From 579b1b15c1f1e9c9e676dc6cf064dce89694ec7b Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Tue, 15 Oct 2024 18:00:31 -0400 Subject: [PATCH 001/149] Add a way to ask Matter.framework for information about device types. (#36084) --- src/darwin/Framework/CHIP/MTRDeviceType.h | 55 +++++++ src/darwin/Framework/CHIP/MTRDeviceType.mm | 59 +++++++ .../Framework/CHIP/MTRDeviceTypeMetadata.h | 21 ++- src/darwin/Framework/CHIP/Matter.h | 1 + .../CHIP/templates/MTRClusterConstants.zapt | 12 ++ .../templates/MTRDeviceTypeMetadata-src.zapt | 22 +-- .../CHIP/templates/availability.yaml | 70 ++++++++ .../CHIP/zap-generated/MTRClusterConstants.h | 71 ++++++++ .../zap-generated/MTRDeviceTypeMetadata.mm | 152 ++++++++---------- .../Framework/CHIPTests/MTRDeviceTypeTests.m | 67 ++++++++ .../Matter.xcodeproj/project.pbxproj | 12 ++ 11 files changed, 442 insertions(+), 100 deletions(-) create mode 100644 src/darwin/Framework/CHIP/MTRDeviceType.h create mode 100644 src/darwin/Framework/CHIP/MTRDeviceType.mm create mode 100644 src/darwin/Framework/CHIPTests/MTRDeviceTypeTests.m diff --git a/src/darwin/Framework/CHIP/MTRDeviceType.h b/src/darwin/Framework/CHIP/MTRDeviceType.h new file mode 100644 index 00000000000000..aded23e7af514a --- /dev/null +++ b/src/darwin/Framework/CHIP/MTRDeviceType.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#import + +#import + +NS_ASSUME_NONNULL_BEGIN + +MTR_NEWLY_AVAILABLE +@interface MTRDeviceType : NSObject + +/** + * Returns an MTRDeviceType for the given ID, if the ID is known. Returns nil + * for unknown IDs. + */ ++ (nullable MTRDeviceType *)deviceTypeForID:(NSNumber *)deviceTypeID; + +/** + * The identifier of the device type (32-bit unsigned integer). + */ +@property (nonatomic, readonly, copy) NSNumber * id; + +/** + * Returns the name of the device type. + */ +@property (nonatomic, readonly, retain) NSString * name; + +/** + * Returns whether this is a utility device type. + */ +@property (nonatomic, readonly, assign) BOOL isUtility; + +- (instancetype)init NS_UNAVAILABLE; ++ (instancetype)new NS_UNAVAILABLE; + +@end + +NS_ASSUME_NONNULL_END diff --git a/src/darwin/Framework/CHIP/MTRDeviceType.mm b/src/darwin/Framework/CHIP/MTRDeviceType.mm new file mode 100644 index 00000000000000..394640d2d72b2a --- /dev/null +++ b/src/darwin/Framework/CHIP/MTRDeviceType.mm @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +#import "MTRDeviceTypeMetadata.h" +#import "MTRLogging_Internal.h" + +#include + +using namespace chip; + +@implementation MTRDeviceType + +- (nullable instancetype)initWithDeviceTypeID:(NSNumber *)id name:(NSString *)name isUtility:(BOOL)isUtility +{ + if (!(self = [super init])) { + return nil; + } + + _id = id; + _name = name; + _isUtility = isUtility; + return self; +} + ++ (nullable MTRDeviceType *)deviceTypeForID:(NSNumber *)deviceTypeID +{ + if (!CanCastTo(deviceTypeID.unsignedLongLongValue)) { + MTR_LOG_ERROR("Invalid device type ID: 0x%llx", deviceTypeID.unsignedLongLongValue); + return nil; + } + + auto * deviceTypeData = MTRDeviceTypeDataForID(static_cast(deviceTypeID.unsignedLongLongValue)); + if (!deviceTypeData) { + return nil; + } + + return [[MTRDeviceType alloc] + initWithDeviceTypeID:deviceTypeID + name:[NSString stringWithUTF8String:deviceTypeData->name] + isUtility:(deviceTypeData->deviceClass != MTRDeviceTypeClass::Simple)]; +} + +@end diff --git a/src/darwin/Framework/CHIP/MTRDeviceTypeMetadata.h b/src/darwin/Framework/CHIP/MTRDeviceTypeMetadata.h index d60f6232a78116..2597f60ec47415 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceTypeMetadata.h +++ b/src/darwin/Framework/CHIP/MTRDeviceTypeMetadata.h @@ -21,4 +21,23 @@ #include -BOOL MTRIsKnownUtilityDeviceType(chip::DeviceTypeId aDeviceTypeId); +NS_ASSUME_NONNULL_BEGIN + +enum class MTRDeviceTypeClass +{ + Utility, + Simple, + Node, // Might not be a real class, but we have it for Root Node for now. +}; + +struct MTRDeviceTypeData +{ + chip::DeviceTypeId id; + MTRDeviceTypeClass deviceClass; + const char * name; +}; + +// Returns null for unknown device types. +const MTRDeviceTypeData * _Nullable MTRDeviceTypeDataForID(chip::DeviceTypeId aDeviceTypeId); + +NS_ASSUME_NONNULL_END diff --git a/src/darwin/Framework/CHIP/Matter.h b/src/darwin/Framework/CHIP/Matter.h index 109f4a20a9a5f1..9f57e4fb4e4285 100644 --- a/src/darwin/Framework/CHIP/Matter.h +++ b/src/darwin/Framework/CHIP/Matter.h @@ -48,6 +48,7 @@ #import #import #import +#import #import #import #import diff --git a/src/darwin/Framework/CHIP/templates/MTRClusterConstants.zapt b/src/darwin/Framework/CHIP/templates/MTRClusterConstants.zapt index c6157548049cce..606732b12a63cd 100644 --- a/src/darwin/Framework/CHIP/templates/MTRClusterConstants.zapt +++ b/src/darwin/Framework/CHIP/templates/MTRClusterConstants.zapt @@ -225,3 +225,15 @@ MTREventIDTypeCluster{{>cluster}}Event{{>event}}ID {{availability (asUpperCamelC {{> eventIDs clusterName=label}} {{/zcl_clusters}} }; + +#pragma mark - Device Type IDs + +typedef NS_ENUM(uint32_t, MTRDeviceTypeIDType) { + {{#zcl_device_types}} + {{! Only include standard device types for now. The template syntax does not get hex numbers, apparently. + ZAP seems to have no is_number_less_than helper, so do is_number_greater_than with the arguments reversed. }} + {{#if (is_number_greater_than 65536 code)}} + MTRDeviceTypeIDType{{asUpperCamelCase caption preserveAcronyms=true}}ID {{availability "" deviceType=(asUpperCamelCase caption preserveAcronyms=true)}} = {{asHex code 8}}, + {{/if}} + {{/zcl_device_types}} +} MTR_NEWLY_AVAILABLE; diff --git a/src/darwin/Framework/CHIP/templates/MTRDeviceTypeMetadata-src.zapt b/src/darwin/Framework/CHIP/templates/MTRDeviceTypeMetadata-src.zapt index 7047fb21acacbe..16322f398e9694 100644 --- a/src/darwin/Framework/CHIP/templates/MTRDeviceTypeMetadata-src.zapt +++ b/src/darwin/Framework/CHIP/templates/MTRDeviceTypeMetadata-src.zapt @@ -5,23 +5,11 @@ using namespace chip; namespace { -enum class DeviceTypeClass { - Utility, - Simple, - Node, // Might not be a real class, but we have it for Root Node for now. - // If new classes get added, plase audit MTRIsKnownUtilityDeviceType below. -}; - -struct DeviceTypeData { - DeviceTypeId id; - DeviceTypeClass deviceClass; - const char * name; -}; -constexpr DeviceTypeData knownDeviceTypes[] = { +constexpr MTRDeviceTypeData knownDeviceTypes[] = { {{#zcl_device_types}} {{#if class}} - { {{asHex code 8}}, DeviceTypeClass::{{class}}, "{{caption}}" }, + { {{asHex code 8}}, MTRDeviceTypeClass::{{class}}, "{{caption}}" }, {{/if}} {{/zcl_device_types}} }; @@ -34,12 +22,12 @@ static_assert(ExtractVendorFromMEI({{asHex code 8}}) != 0, "Must have class defi } // anonymous namespace -BOOL MTRIsKnownUtilityDeviceType(DeviceTypeId aDeviceTypeId) +const MTRDeviceTypeData * _Nullable MTRDeviceTypeDataForID(chip::DeviceTypeId aDeviceTypeId) { for (auto & deviceType : knownDeviceTypes) { if (deviceType.id == aDeviceTypeId) { - return deviceType.deviceClass != DeviceTypeClass::Simple; + return &deviceType; } } - return NO; + return nullptr; } diff --git a/src/darwin/Framework/CHIP/templates/availability.yaml b/src/darwin/Framework/CHIP/templates/availability.yaml index fdf5c00538a3dd..c8beeca6772ee1 100644 --- a/src/darwin/Framework/CHIP/templates/availability.yaml +++ b/src/darwin/Framework/CHIP/templates/availability.yaml @@ -9742,6 +9742,73 @@ - UpdateDirection - UpdateTime - UpdateStartHue + device types: + - AirQualitySensor + - AirPurifier + - Aggregator + - BasicVideoPlayer + - BridgedNode + - CastingVideoClient + - CastingVideoPlayer + - ColorDimmerSwitch + - ColorTemperatureLight + - ContactSensor + - ContentApp + - ControlBridge + - CookSurface + - Cooktop + - DeviceEnergyManagement + - DimmableLight + - DimmablePlugInUnit + - DimmerSwitch + - Dishwasher + - DoorLock + - DoorLockController + - ElectricalSensor + - EVSE + - ExtendedColorLight + - ExtractorHood + - Fan + - FlowSensor + - GenericSwitch + - HeatingCoolingUnit + - HumiditySensor + - LaundryDryer + - LaundryWasher + - LightSensor + - MicrowaveOven + - ModeSelect + - NetworkInfrastructureManager + - OccupancySensor + - OnOffLight + - OnOffLightSwitch + - OnOffPlugInUnit + - OnOffSensor + - OTAProvider + - OTARequestor + - Oven + - PressureSensor + - PowerSource + - Pump + - PumpController + - RainSensor + - Refrigerator + - RoboticVacuumCleaner + - RoomAirConditioner + - RootNode + - SecondaryNetworkInterface + - SmokeCOAlarm + - Speaker + - TemperatureControlledCabinet + - TemperatureSensor + - Thermostat + - ThreadBorderRouter + - VideoRemoteControl + - WaterFreezeDetector + - WaterLeakDetector + - WaterValve + - WindowCovering + - WindowCoveringController provisional: clusters: # Targeting 1.4 @@ -9754,8 +9821,11 @@ - WaterHeaterMode - WiFiNetworkManagement # Targeting Camera enablement + - CameraAVStreamManagement - Chime - WebRTCTransportProvider + - WebRTCTransportRequestor + - ZoneManagement attributes: AccessControl: # Targeting 1.4 diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h b/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h index 9decbec4510c62..76d6ab35d3724a 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h @@ -7688,3 +7688,74 @@ typedef NS_ENUM(uint32_t, MTREventIDType) { MTREventIDTypeClusterSampleMEIEventPingCountEventID MTR_PROVISIONALLY_AVAILABLE = 0x00000000, }; + +#pragma mark - Device Type IDs + +typedef NS_ENUM(uint32_t, MTRDeviceTypeIDType) { + MTRDeviceTypeIDTypeDoorLockID MTR_NEWLY_AVAILABLE = 0x0000000A, + MTRDeviceTypeIDTypeDoorLockControllerID MTR_NEWLY_AVAILABLE = 0x0000000B, + MTRDeviceTypeIDTypeAggregatorID MTR_NEWLY_AVAILABLE = 0x0000000E, + MTRDeviceTypeIDTypeGenericSwitchID MTR_NEWLY_AVAILABLE = 0x0000000F, + MTRDeviceTypeIDTypePowerSourceID MTR_NEWLY_AVAILABLE = 0x00000011, + MTRDeviceTypeIDTypeOTARequestorID MTR_NEWLY_AVAILABLE = 0x00000012, + MTRDeviceTypeIDTypeBridgedNodeID MTR_NEWLY_AVAILABLE = 0x00000013, + MTRDeviceTypeIDTypeOTAProviderID MTR_NEWLY_AVAILABLE = 0x00000014, + MTRDeviceTypeIDTypeContactSensorID MTR_NEWLY_AVAILABLE = 0x00000015, + MTRDeviceTypeIDTypeRootNodeID MTR_NEWLY_AVAILABLE = 0x00000016, + MTRDeviceTypeIDTypeSecondaryNetworkInterfaceID MTR_NEWLY_AVAILABLE = 0x00000019, + MTRDeviceTypeIDTypeSpeakerID MTR_NEWLY_AVAILABLE = 0x00000022, + MTRDeviceTypeIDTypeCastingVideoPlayerID MTR_NEWLY_AVAILABLE = 0x00000023, + MTRDeviceTypeIDTypeContentAppID MTR_NEWLY_AVAILABLE = 0x00000024, + MTRDeviceTypeIDTypeModeSelectID MTR_NEWLY_AVAILABLE = 0x00000027, + MTRDeviceTypeIDTypeBasicVideoPlayerID MTR_NEWLY_AVAILABLE = 0x00000028, + MTRDeviceTypeIDTypeCastingVideoClientID MTR_NEWLY_AVAILABLE = 0x00000029, + MTRDeviceTypeIDTypeVideoRemoteControlID MTR_NEWLY_AVAILABLE = 0x0000002A, + MTRDeviceTypeIDTypeFanID MTR_NEWLY_AVAILABLE = 0x0000002B, + MTRDeviceTypeIDTypeAirQualitySensorID MTR_NEWLY_AVAILABLE = 0x0000002C, + MTRDeviceTypeIDTypeAirPurifierID MTR_NEWLY_AVAILABLE = 0x0000002D, + MTRDeviceTypeIDTypeWaterFreezeDetectorID MTR_NEWLY_AVAILABLE = 0x00000041, + MTRDeviceTypeIDTypeWaterValveID MTR_NEWLY_AVAILABLE = 0x00000042, + MTRDeviceTypeIDTypeWaterLeakDetectorID MTR_NEWLY_AVAILABLE = 0x00000043, + MTRDeviceTypeIDTypeRainSensorID MTR_NEWLY_AVAILABLE = 0x00000044, + MTRDeviceTypeIDTypeRefrigeratorID MTR_NEWLY_AVAILABLE = 0x00000070, + MTRDeviceTypeIDTypeTemperatureControlledCabinetID MTR_NEWLY_AVAILABLE = 0x00000071, + MTRDeviceTypeIDTypeRoomAirConditionerID MTR_NEWLY_AVAILABLE = 0x00000072, + MTRDeviceTypeIDTypeLaundryWasherID MTR_NEWLY_AVAILABLE = 0x00000073, + MTRDeviceTypeIDTypeRoboticVacuumCleanerID MTR_NEWLY_AVAILABLE = 0x00000074, + MTRDeviceTypeIDTypeDishwasherID MTR_NEWLY_AVAILABLE = 0x00000075, + MTRDeviceTypeIDTypeSmokeCOAlarmID MTR_NEWLY_AVAILABLE = 0x00000076, + MTRDeviceTypeIDTypeCookSurfaceID MTR_NEWLY_AVAILABLE = 0x00000077, + MTRDeviceTypeIDTypeCooktopID MTR_NEWLY_AVAILABLE = 0x00000078, + MTRDeviceTypeIDTypeMicrowaveOvenID MTR_NEWLY_AVAILABLE = 0x00000079, + MTRDeviceTypeIDTypeExtractorHoodID MTR_NEWLY_AVAILABLE = 0x0000007A, + MTRDeviceTypeIDTypeOvenID MTR_NEWLY_AVAILABLE = 0x0000007B, + MTRDeviceTypeIDTypeLaundryDryerID MTR_NEWLY_AVAILABLE = 0x0000007C, + MTRDeviceTypeIDTypeNetworkInfrastructureManagerID MTR_NEWLY_AVAILABLE = 0x00000090, + MTRDeviceTypeIDTypeThreadBorderRouterID MTR_NEWLY_AVAILABLE = 0x00000091, + MTRDeviceTypeIDTypeOnOffLightID MTR_NEWLY_AVAILABLE = 0x00000100, + MTRDeviceTypeIDTypeDimmableLightID MTR_NEWLY_AVAILABLE = 0x00000101, + MTRDeviceTypeIDTypeOnOffLightSwitchID MTR_NEWLY_AVAILABLE = 0x00000103, + MTRDeviceTypeIDTypeDimmerSwitchID MTR_NEWLY_AVAILABLE = 0x00000104, + MTRDeviceTypeIDTypeColorDimmerSwitchID MTR_NEWLY_AVAILABLE = 0x00000105, + MTRDeviceTypeIDTypeLightSensorID MTR_NEWLY_AVAILABLE = 0x00000106, + MTRDeviceTypeIDTypeOccupancySensorID MTR_NEWLY_AVAILABLE = 0x00000107, + MTRDeviceTypeIDTypeOnOffPlugInUnitID MTR_NEWLY_AVAILABLE = 0x0000010A, + MTRDeviceTypeIDTypeDimmablePlugInUnitID MTR_NEWLY_AVAILABLE = 0x0000010B, + MTRDeviceTypeIDTypeColorTemperatureLightID MTR_NEWLY_AVAILABLE = 0x0000010C, + MTRDeviceTypeIDTypeExtendedColorLightID MTR_NEWLY_AVAILABLE = 0x0000010D, + MTRDeviceTypeIDTypeWindowCoveringID MTR_NEWLY_AVAILABLE = 0x00000202, + MTRDeviceTypeIDTypeWindowCoveringControllerID MTR_NEWLY_AVAILABLE = 0x00000203, + MTRDeviceTypeIDTypeHeatingCoolingUnitID MTR_NEWLY_AVAILABLE = 0x00000300, + MTRDeviceTypeIDTypeThermostatID MTR_NEWLY_AVAILABLE = 0x00000301, + MTRDeviceTypeIDTypeTemperatureSensorID MTR_NEWLY_AVAILABLE = 0x00000302, + MTRDeviceTypeIDTypePumpID MTR_NEWLY_AVAILABLE = 0x00000303, + MTRDeviceTypeIDTypePumpControllerID MTR_NEWLY_AVAILABLE = 0x00000304, + MTRDeviceTypeIDTypePressureSensorID MTR_NEWLY_AVAILABLE = 0x00000305, + MTRDeviceTypeIDTypeFlowSensorID MTR_NEWLY_AVAILABLE = 0x00000306, + MTRDeviceTypeIDTypeHumiditySensorID MTR_NEWLY_AVAILABLE = 0x00000307, + MTRDeviceTypeIDTypeEVSEID MTR_NEWLY_AVAILABLE = 0x0000050C, + MTRDeviceTypeIDTypeDeviceEnergyManagementID MTR_NEWLY_AVAILABLE = 0x0000050D, + MTRDeviceTypeIDTypeElectricalSensorID MTR_NEWLY_AVAILABLE = 0x00000510, + MTRDeviceTypeIDTypeControlBridgeID MTR_NEWLY_AVAILABLE = 0x00000840, + MTRDeviceTypeIDTypeOnOffSensorID MTR_NEWLY_AVAILABLE = 0x00000850, +} MTR_NEWLY_AVAILABLE; diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRDeviceTypeMetadata.mm b/src/darwin/Framework/CHIP/zap-generated/MTRDeviceTypeMetadata.mm index cadfa6ab337950..f0530c41a54f00 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRDeviceTypeMetadata.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRDeviceTypeMetadata.mm @@ -20,86 +20,74 @@ using namespace chip; namespace { -enum class DeviceTypeClass { - Utility, - Simple, - Node, // Might not be a real class, but we have it for Root Node for now. - // If new classes get added, plase audit MTRIsKnownUtilityDeviceType below. -}; - -struct DeviceTypeData { - DeviceTypeId id; - DeviceTypeClass deviceClass; - const char * name; -}; -constexpr DeviceTypeData knownDeviceTypes[] = { - { 0x0000000A, DeviceTypeClass::Simple, "Door Lock" }, - { 0x0000000B, DeviceTypeClass::Simple, "Door Lock Controller" }, - { 0x0000000E, DeviceTypeClass::Simple, "Aggregator" }, - { 0x0000000F, DeviceTypeClass::Simple, "Generic Switch" }, - { 0x00000011, DeviceTypeClass::Utility, "Power Source" }, - { 0x00000012, DeviceTypeClass::Utility, "OTA Requestor" }, - { 0x00000013, DeviceTypeClass::Utility, "Bridged Node" }, - { 0x00000014, DeviceTypeClass::Utility, "OTA Provider" }, - { 0x00000015, DeviceTypeClass::Simple, "Contact Sensor" }, - { 0x00000016, DeviceTypeClass::Node, "Root Node" }, - { 0x00000019, DeviceTypeClass::Utility, "Secondary Network Interface" }, - { 0x00000022, DeviceTypeClass::Simple, "Speaker" }, - { 0x00000023, DeviceTypeClass::Simple, "Casting Video Player" }, - { 0x00000024, DeviceTypeClass::Simple, "Content App" }, - { 0x00000027, DeviceTypeClass::Simple, "Mode Select" }, - { 0x00000028, DeviceTypeClass::Simple, "Basic Video Player" }, - { 0x00000029, DeviceTypeClass::Simple, "Casting Video Client" }, - { 0x0000002A, DeviceTypeClass::Simple, "Video Remote Control" }, - { 0x0000002B, DeviceTypeClass::Simple, "Fan" }, - { 0x0000002C, DeviceTypeClass::Simple, "Air Quality Sensor" }, - { 0x0000002D, DeviceTypeClass::Simple, "Air Purifier" }, - { 0x00000041, DeviceTypeClass::Simple, "Water Freeze Detector" }, - { 0x00000042, DeviceTypeClass::Simple, "Water Valve" }, - { 0x00000043, DeviceTypeClass::Simple, "Water Leak Detector" }, - { 0x00000044, DeviceTypeClass::Simple, "Rain Sensor" }, - { 0x00000070, DeviceTypeClass::Simple, "Refrigerator" }, - { 0x00000071, DeviceTypeClass::Simple, "Temperature Controlled Cabinet" }, - { 0x00000072, DeviceTypeClass::Simple, "Room Air Conditioner" }, - { 0x00000073, DeviceTypeClass::Simple, "Laundry Washer" }, - { 0x00000074, DeviceTypeClass::Simple, "Robotic Vacuum Cleaner" }, - { 0x00000075, DeviceTypeClass::Simple, "Dishwasher" }, - { 0x00000076, DeviceTypeClass::Simple, "Smoke CO Alarm" }, - { 0x00000077, DeviceTypeClass::Simple, "Cook Surface" }, - { 0x00000078, DeviceTypeClass::Simple, "Cooktop" }, - { 0x00000079, DeviceTypeClass::Simple, "Microwave Oven" }, - { 0x0000007A, DeviceTypeClass::Simple, "Extractor Hood" }, - { 0x0000007B, DeviceTypeClass::Simple, "Oven" }, - { 0x0000007C, DeviceTypeClass::Simple, "Laundry Dryer" }, - { 0x00000090, DeviceTypeClass::Simple, "Network Infrastructure Manager" }, - { 0x00000091, DeviceTypeClass::Simple, "Thread Border Router" }, - { 0x00000100, DeviceTypeClass::Simple, "On/Off Light" }, - { 0x00000101, DeviceTypeClass::Simple, "Dimmable Light" }, - { 0x00000103, DeviceTypeClass::Simple, "On/Off Light Switch" }, - { 0x00000104, DeviceTypeClass::Simple, "Dimmer Switch" }, - { 0x00000105, DeviceTypeClass::Simple, "Color Dimmer Switch" }, - { 0x00000106, DeviceTypeClass::Simple, "Light Sensor" }, - { 0x00000107, DeviceTypeClass::Simple, "Occupancy Sensor" }, - { 0x0000010A, DeviceTypeClass::Simple, "On/Off Plug-in Unit" }, - { 0x0000010B, DeviceTypeClass::Simple, "Dimmable Plug-in Unit" }, - { 0x0000010C, DeviceTypeClass::Simple, "Color Temperature Light" }, - { 0x0000010D, DeviceTypeClass::Simple, "Extended Color Light" }, - { 0x00000202, DeviceTypeClass::Simple, "Window Covering" }, - { 0x00000203, DeviceTypeClass::Simple, "Window Covering Controller" }, - { 0x00000300, DeviceTypeClass::Simple, "Heating/Cooling Unit" }, - { 0x00000301, DeviceTypeClass::Simple, "Thermostat" }, - { 0x00000302, DeviceTypeClass::Simple, "Temperature Sensor" }, - { 0x00000303, DeviceTypeClass::Simple, "Pump" }, - { 0x00000304, DeviceTypeClass::Simple, "Pump Controller" }, - { 0x00000305, DeviceTypeClass::Simple, "Pressure Sensor" }, - { 0x00000306, DeviceTypeClass::Simple, "Flow Sensor" }, - { 0x00000307, DeviceTypeClass::Simple, "Humidity Sensor" }, - { 0x0000050C, DeviceTypeClass::Simple, "EVSE" }, - { 0x0000050D, DeviceTypeClass::Simple, "Device Energy Management" }, - { 0x00000510, DeviceTypeClass::Utility, "Electrical Sensor" }, - { 0x00000840, DeviceTypeClass::Simple, "Control Bridge" }, - { 0x00000850, DeviceTypeClass::Simple, "On/Off Sensor" }, +constexpr MTRDeviceTypeData knownDeviceTypes[] = { + { 0x0000000A, MTRDeviceTypeClass::Simple, "Door Lock" }, + { 0x0000000B, MTRDeviceTypeClass::Simple, "Door Lock Controller" }, + { 0x0000000E, MTRDeviceTypeClass::Simple, "Aggregator" }, + { 0x0000000F, MTRDeviceTypeClass::Simple, "Generic Switch" }, + { 0x00000011, MTRDeviceTypeClass::Utility, "Power Source" }, + { 0x00000012, MTRDeviceTypeClass::Utility, "OTA Requestor" }, + { 0x00000013, MTRDeviceTypeClass::Utility, "Bridged Node" }, + { 0x00000014, MTRDeviceTypeClass::Utility, "OTA Provider" }, + { 0x00000015, MTRDeviceTypeClass::Simple, "Contact Sensor" }, + { 0x00000016, MTRDeviceTypeClass::Node, "Root Node" }, + { 0x00000019, MTRDeviceTypeClass::Utility, "Secondary Network Interface" }, + { 0x00000022, MTRDeviceTypeClass::Simple, "Speaker" }, + { 0x00000023, MTRDeviceTypeClass::Simple, "Casting Video Player" }, + { 0x00000024, MTRDeviceTypeClass::Simple, "Content App" }, + { 0x00000027, MTRDeviceTypeClass::Simple, "Mode Select" }, + { 0x00000028, MTRDeviceTypeClass::Simple, "Basic Video Player" }, + { 0x00000029, MTRDeviceTypeClass::Simple, "Casting Video Client" }, + { 0x0000002A, MTRDeviceTypeClass::Simple, "Video Remote Control" }, + { 0x0000002B, MTRDeviceTypeClass::Simple, "Fan" }, + { 0x0000002C, MTRDeviceTypeClass::Simple, "Air Quality Sensor" }, + { 0x0000002D, MTRDeviceTypeClass::Simple, "Air Purifier" }, + { 0x00000041, MTRDeviceTypeClass::Simple, "Water Freeze Detector" }, + { 0x00000042, MTRDeviceTypeClass::Simple, "Water Valve" }, + { 0x00000043, MTRDeviceTypeClass::Simple, "Water Leak Detector" }, + { 0x00000044, MTRDeviceTypeClass::Simple, "Rain Sensor" }, + { 0x00000070, MTRDeviceTypeClass::Simple, "Refrigerator" }, + { 0x00000071, MTRDeviceTypeClass::Simple, "Temperature Controlled Cabinet" }, + { 0x00000072, MTRDeviceTypeClass::Simple, "Room Air Conditioner" }, + { 0x00000073, MTRDeviceTypeClass::Simple, "Laundry Washer" }, + { 0x00000074, MTRDeviceTypeClass::Simple, "Robotic Vacuum Cleaner" }, + { 0x00000075, MTRDeviceTypeClass::Simple, "Dishwasher" }, + { 0x00000076, MTRDeviceTypeClass::Simple, "Smoke CO Alarm" }, + { 0x00000077, MTRDeviceTypeClass::Simple, "Cook Surface" }, + { 0x00000078, MTRDeviceTypeClass::Simple, "Cooktop" }, + { 0x00000079, MTRDeviceTypeClass::Simple, "Microwave Oven" }, + { 0x0000007A, MTRDeviceTypeClass::Simple, "Extractor Hood" }, + { 0x0000007B, MTRDeviceTypeClass::Simple, "Oven" }, + { 0x0000007C, MTRDeviceTypeClass::Simple, "Laundry Dryer" }, + { 0x00000090, MTRDeviceTypeClass::Simple, "Network Infrastructure Manager" }, + { 0x00000091, MTRDeviceTypeClass::Simple, "Thread Border Router" }, + { 0x00000100, MTRDeviceTypeClass::Simple, "On/Off Light" }, + { 0x00000101, MTRDeviceTypeClass::Simple, "Dimmable Light" }, + { 0x00000103, MTRDeviceTypeClass::Simple, "On/Off Light Switch" }, + { 0x00000104, MTRDeviceTypeClass::Simple, "Dimmer Switch" }, + { 0x00000105, MTRDeviceTypeClass::Simple, "Color Dimmer Switch" }, + { 0x00000106, MTRDeviceTypeClass::Simple, "Light Sensor" }, + { 0x00000107, MTRDeviceTypeClass::Simple, "Occupancy Sensor" }, + { 0x0000010A, MTRDeviceTypeClass::Simple, "On/Off Plug-in Unit" }, + { 0x0000010B, MTRDeviceTypeClass::Simple, "Dimmable Plug-in Unit" }, + { 0x0000010C, MTRDeviceTypeClass::Simple, "Color Temperature Light" }, + { 0x0000010D, MTRDeviceTypeClass::Simple, "Extended Color Light" }, + { 0x00000202, MTRDeviceTypeClass::Simple, "Window Covering" }, + { 0x00000203, MTRDeviceTypeClass::Simple, "Window Covering Controller" }, + { 0x00000300, MTRDeviceTypeClass::Simple, "Heating/Cooling Unit" }, + { 0x00000301, MTRDeviceTypeClass::Simple, "Thermostat" }, + { 0x00000302, MTRDeviceTypeClass::Simple, "Temperature Sensor" }, + { 0x00000303, MTRDeviceTypeClass::Simple, "Pump" }, + { 0x00000304, MTRDeviceTypeClass::Simple, "Pump Controller" }, + { 0x00000305, MTRDeviceTypeClass::Simple, "Pressure Sensor" }, + { 0x00000306, MTRDeviceTypeClass::Simple, "Flow Sensor" }, + { 0x00000307, MTRDeviceTypeClass::Simple, "Humidity Sensor" }, + { 0x0000050C, MTRDeviceTypeClass::Simple, "EVSE" }, + { 0x0000050D, MTRDeviceTypeClass::Simple, "Device Energy Management" }, + { 0x00000510, MTRDeviceTypeClass::Utility, "Electrical Sensor" }, + { 0x00000840, MTRDeviceTypeClass::Simple, "Control Bridge" }, + { 0x00000850, MTRDeviceTypeClass::Simple, "On/Off Sensor" }, }; static_assert(ExtractVendorFromMEI(0xFFF10001) != 0, "Must have class defined for \"Orphan Clusters\" if it's a standard device type"); @@ -107,12 +95,12 @@ } // anonymous namespace -BOOL MTRIsKnownUtilityDeviceType(DeviceTypeId aDeviceTypeId) +const MTRDeviceTypeData * _Nullable MTRDeviceTypeDataForID(chip::DeviceTypeId aDeviceTypeId) { for (auto & deviceType : knownDeviceTypes) { if (deviceType.id == aDeviceTypeId) { - return deviceType.deviceClass != DeviceTypeClass::Simple; + return &deviceType; } } - return NO; + return nullptr; } diff --git a/src/darwin/Framework/CHIPTests/MTRDeviceTypeTests.m b/src/darwin/Framework/CHIPTests/MTRDeviceTypeTests.m new file mode 100644 index 00000000000000..7a41d42b40cb43 --- /dev/null +++ b/src/darwin/Framework/CHIPTests/MTRDeviceTypeTests.m @@ -0,0 +1,67 @@ +/** + * Copyright (c) 2024 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +// system dependencies +#import + +@interface MTRDeviceTypeTests : XCTestCase + +@end + +@implementation MTRDeviceTypeTests + +- (void)testInvalidID +{ + __auto_type * deviceType = [MTRDeviceType deviceTypeForID:@(0x100000000)]; + XCTAssertNil(deviceType); +} + +- (void)testUnknownID +{ + __auto_type * deviceType = [MTRDeviceType deviceTypeForID:@(0xFFF15000)]; + XCTAssertNil(deviceType); +} + +- (void)testKnownNonUtilityID +{ + __auto_type * deviceType = [MTRDeviceType deviceTypeForID:@(MTRDeviceTypeIDTypeMicrowaveOvenID)]; + XCTAssertNotNil(deviceType); + XCTAssertEqualObjects(deviceType.id, @(0x0079)); + XCTAssertEqualObjects(deviceType.name, @"Microwave Oven"); + XCTAssertFalse(deviceType.isUtility); +} + +- (void)testKnownUtilityID +{ + __auto_type * deviceType = [MTRDeviceType deviceTypeForID:@(MTRDeviceTypeIDTypeRootNodeID)]; + XCTAssertNotNil(deviceType); + XCTAssertEqualObjects(deviceType.id, @(0x0016)); + XCTAssertEqualObjects(deviceType.name, @"Root Node"); + XCTAssertTrue(deviceType.isUtility); +} + +- (void)testRootNodeID +{ + __auto_type * deviceType = [MTRDeviceType deviceTypeForID:@(MTRDeviceTypeIDTypePowerSourceID)]; + XCTAssertNotNil(deviceType); + XCTAssertEqualObjects(deviceType.id, @(0x0011)); + XCTAssertEqualObjects(deviceType.name, @"Power Source"); + XCTAssertTrue(deviceType.isUtility); +} + +@end diff --git a/src/darwin/Framework/Matter.xcodeproj/project.pbxproj b/src/darwin/Framework/Matter.xcodeproj/project.pbxproj index e19178531cf914..ea5ef7969a1d4b 100644 --- a/src/darwin/Framework/Matter.xcodeproj/project.pbxproj +++ b/src/darwin/Framework/Matter.xcodeproj/project.pbxproj @@ -129,6 +129,9 @@ 3DFCB32C29678C9500332B35 /* MTRConversion.h in Headers */ = {isa = PBXBuildFile; fileRef = 3DFCB32B29678C9500332B35 /* MTRConversion.h */; }; 51029DF6293AA6100087AFB0 /* MTROperationalCertificateIssuer.mm in Sources */ = {isa = PBXBuildFile; fileRef = 51029DF5293AA6100087AFB0 /* MTROperationalCertificateIssuer.mm */; }; 510470FB2A2F7DF60053EA7E /* MTRBackwardsCompatShims.mm in Sources */ = {isa = PBXBuildFile; fileRef = 510470FA2A2F7DF60053EA7E /* MTRBackwardsCompatShims.mm */; }; + 5109E9B42CB8B5DF0006884B /* MTRDeviceType.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5109E9B32CB8B5DF0006884B /* MTRDeviceType.mm */; }; + 5109E9B52CB8B5DF0006884B /* MTRDeviceType.h in Headers */ = {isa = PBXBuildFile; fileRef = 5109E9B22CB8B5DF0006884B /* MTRDeviceType.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 5109E9B72CB8B83D0006884B /* MTRDeviceTypeTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5109E9B62CB8B83D0006884B /* MTRDeviceTypeTests.m */; }; 510A07492A685D3900A9241C /* Matter.apinotes in Headers */ = {isa = PBXBuildFile; fileRef = 510A07482A685D3900A9241C /* Matter.apinotes */; settings = {ATTRIBUTES = (Public, ); }; }; 510CECA8297F72970064E0B3 /* MTROperationalCertificateIssuerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 510CECA6297F72470064E0B3 /* MTROperationalCertificateIssuerTests.m */; }; 5117DD3829A931AE00FFA1AA /* MTROperationalBrowser.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5117DD3629A931AD00FFA1AA /* MTROperationalBrowser.mm */; }; @@ -578,6 +581,9 @@ 3DFCB32B29678C9500332B35 /* MTRConversion.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MTRConversion.h; sourceTree = ""; }; 51029DF5293AA6100087AFB0 /* MTROperationalCertificateIssuer.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MTROperationalCertificateIssuer.mm; sourceTree = ""; }; 510470FA2A2F7DF60053EA7E /* MTRBackwardsCompatShims.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MTRBackwardsCompatShims.mm; sourceTree = ""; }; + 5109E9B22CB8B5DF0006884B /* MTRDeviceType.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MTRDeviceType.h; sourceTree = ""; }; + 5109E9B32CB8B5DF0006884B /* MTRDeviceType.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MTRDeviceType.mm; sourceTree = ""; }; + 5109E9B62CB8B83D0006884B /* MTRDeviceTypeTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MTRDeviceTypeTests.m; sourceTree = ""; }; 510A07482A685D3900A9241C /* Matter.apinotes */ = {isa = PBXFileReference; lastKnownFileType = text.apinotes; name = Matter.apinotes; path = CHIP/Matter.apinotes; sourceTree = ""; }; 510CECA6297F72470064E0B3 /* MTROperationalCertificateIssuerTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MTROperationalCertificateIssuerTests.m; sourceTree = ""; }; 5117DD3629A931AD00FFA1AA /* MTROperationalBrowser.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MTROperationalBrowser.mm; sourceTree = ""; }; @@ -1417,6 +1423,8 @@ 754784662BFE6B890089C372 /* MTRDeviceStorageBehaviorConfiguration_Internal.h */, 754784642BFE65CB0089C372 /* MTRDeviceStorageBehaviorConfiguration.mm */, 51F522692AE70761000C4050 /* MTRDeviceTypeMetadata.h */, + 5109E9B22CB8B5DF0006884B /* MTRDeviceType.h */, + 5109E9B32CB8B5DF0006884B /* MTRDeviceType.mm */, 5129BCFC26A9EE3300122DDF /* MTRError.h */, B2E0D7AB245B0B5C003C5B48 /* MTRError_Internal.h */, B2E0D7AA245B0B5C003C5B48 /* MTRError.mm */, @@ -1492,6 +1500,7 @@ 51A2F1312A00402A00F03298 /* MTRDataValueParserTests.m */, 5AE6D4E327A99041001F2493 /* MTRDeviceTests.m */, 75B326A12BCF12E900E17C4E /* MTRDeviceConnectivityMonitorTests.m */, + 5109E9B62CB8B83D0006884B /* MTRDeviceTypeTests.m */, 51D9CB0A2BA37DCE0049D6DB /* MTRDSTOffsetTests.m */, 3D0C484A29DA4FA0006D811F /* MTRErrorTests.m */, 5173A47829C0E82300F67F48 /* MTRFabricInfoTests.m */, @@ -1801,6 +1810,7 @@ 991DC08B247704DC00C13860 /* MTRLogging_Internal.h in Headers */, 51FE723F2ACDEF3E00437032 /* MTRCommandPayloadExtensions_Internal.h in Headers */, 51D0B12E2B6177FD006E3511 /* MTRAccessGrant.h in Headers */, + 5109E9B52CB8B5DF0006884B /* MTRDeviceType.h in Headers */, 1E4D655029C208DD00BC3478 /* MTRCommissionableBrowserDelegate.h in Headers */, 7596A84828762783004DAE0E /* MTRAsyncCallbackWorkQueue.h in Headers */, 5A7947E527C0129F00434CF2 /* MTRDeviceController+XPC.h in Headers */, @@ -2117,6 +2127,7 @@ 513DDB8A2761F6F900DAA01A /* MTRAttributeTLVValueDecoder.mm in Sources */, 5117DD3829A931AE00FFA1AA /* MTROperationalBrowser.mm in Sources */, 514C79F02B62ADDA00DD6D7B /* descriptor.cpp in Sources */, + 5109E9B42CB8B5DF0006884B /* MTRDeviceType.mm in Sources */, 3D843757294AD25A0070D20A /* MTRCertificateInfo.mm in Sources */, 5A7947E427C0129600434CF2 /* MTRDeviceController+XPC.mm in Sources */, 5A6FEC9027B563D900F25F42 /* MTRDeviceControllerOverXPC.mm in Sources */, @@ -2184,6 +2195,7 @@ 5142E39829D377F000A206F0 /* MTROTAProviderTests.m in Sources */, 51E0FC102ACBBF230001E197 /* MTRSwiftDeviceTests.swift in Sources */, 3D4733AF2BDF1B80003DC19B /* MTRSetupPayloadTests.m in Sources */, + 5109E9B72CB8B83D0006884B /* MTRDeviceTypeTests.m in Sources */, 51E24E73274E0DAC007CCF6E /* MTRErrorTestUtils.mm in Sources */, 519498322A25581C00B3BABE /* MTRSetupPayloadInitializationTests.m in Sources */, 51A2F1322A00402A00F03298 /* MTRDataValueParserTests.m in Sources */, From c29a25e596cc87f2cace4967e4cf4f44f281c7e7 Mon Sep 17 00:00:00 2001 From: arun-silabs <141724790+arun-silabs@users.noreply.github.com> Date: Wed, 16 Oct 2024 19:00:49 +0530 Subject: [PATCH 002/149] Updated silabs docker image to WiseConnect v3.3.3 (#36093) --- integrations/docker/images/base/chip-build/version | 2 +- .../docker/images/stage-2/chip-build-efr32/Dockerfile | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/integrations/docker/images/base/chip-build/version b/integrations/docker/images/base/chip-build/version index 2b7aeef2b79375..ccb98d6cde3284 100644 --- a/integrations/docker/images/base/chip-build/version +++ b/integrations/docker/images/base/chip-build/version @@ -1 +1 @@ -82 : [Tizen] Enable RTC driver to sync time on boot +83 : [Silabs] Update Silabs docker WiseConnect 3.3.3 diff --git a/integrations/docker/images/stage-2/chip-build-efr32/Dockerfile b/integrations/docker/images/stage-2/chip-build-efr32/Dockerfile index d54bab59f0f59e..e3f4145d8c1950 100644 --- a/integrations/docker/images/stage-2/chip-build-efr32/Dockerfile +++ b/integrations/docker/images/stage-2/chip-build-efr32/Dockerfile @@ -29,8 +29,8 @@ RUN git clone --depth=1 --single-branch --branch=2.10.0 https://github.com/Silic rm -rf .git \ && : # last line -# Clone WiSeConnect SDK v3.3.2 (b5d6422) -RUN git clone --depth=1 --single-branch --branch=v3.3.2 https://github.com/SiliconLabs/wiseconnect.git /tmp/wifi_sdk && \ +# Clone WiSeConnect SDK v3.3.3 (a6390dd) +RUN git clone --depth=1 --single-branch --branch=v3.3.3 https://github.com/SiliconLabs/wiseconnect.git /tmp/wifi_sdk && \ cd /tmp/wifi_sdk && \ rm -rf .git \ && : # last line From c710d089bcf07df52a6351c1da608075c449662b Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Wed, 16 Oct 2024 10:52:50 -0400 Subject: [PATCH 003/149] Update ZAP to a version that removes some unused helpers. (#36089) --- scripts/setup/zap.json | 4 ++-- scripts/setup/zap.version | 2 +- scripts/tools/zap/zap_execution.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/setup/zap.json b/scripts/setup/zap.json index 20cf55478c00dd..8b18116caaa5be 100644 --- a/scripts/setup/zap.json +++ b/scripts/setup/zap.json @@ -8,13 +8,13 @@ "mac-amd64", "windows-amd64" ], - "tags": ["version:2@v2024.10.11-nightly.1"] + "tags": ["version:2@v2024.10.15-nightly.1"] }, { "_comment": "Always get the amd64 version on mac until usable arm64 zap build is available", "path": "fuchsia/third_party/zap/mac-amd64", "platforms": ["mac-arm64"], - "tags": ["version:2@v2024.10.11-nightly.1"] + "tags": ["version:2@v2024.10.15-nightly.1"] } ] } diff --git a/scripts/setup/zap.version b/scripts/setup/zap.version index 044bdcd3d92f21..e58d8c5cac5d73 100644 --- a/scripts/setup/zap.version +++ b/scripts/setup/zap.version @@ -1 +1 @@ -v2024.10.11-nightly +v2024.10.15-nightly diff --git a/scripts/tools/zap/zap_execution.py b/scripts/tools/zap/zap_execution.py index 21257ef1952e75..9ed0b0f222ab38 100644 --- a/scripts/tools/zap/zap_execution.py +++ b/scripts/tools/zap/zap_execution.py @@ -23,7 +23,7 @@ # Use scripts/tools/zap/version_update.py to manage ZAP versioning as many # files may need updating for versions # -MIN_ZAP_VERSION = '2024.10.11' +MIN_ZAP_VERSION = '2024.10.15' class ZapTool: From 22e978351ff3345848a13880b5c6d85c8890095f Mon Sep 17 00:00:00 2001 From: Amine Alami <43780877+Alami-Amine@users.noreply.github.com> Date: Wed, 16 Oct 2024 17:37:49 +0200 Subject: [PATCH 004/149] Making all unit tests binaries build in out/tests folder (#36095) --- .../energy-management-common/tests/BUILD.gn | 1 - src/credentials/tests/BUILD.gn | 1 - 2 files changed, 2 deletions(-) diff --git a/examples/energy-management-app/energy-management-common/tests/BUILD.gn b/examples/energy-management-app/energy-management-common/tests/BUILD.gn index c11d783194229a..3fdc8e9eac4621 100644 --- a/examples/energy-management-app/energy-management-common/tests/BUILD.gn +++ b/examples/energy-management-app/energy-management-common/tests/BUILD.gn @@ -23,7 +23,6 @@ config("tests_config") { chip_test_suite("tests") { output_name = "libEnergyTest" - output_dir = "${root_out_dir}/lib" public_configs = [ ":tests_config" ] diff --git a/src/credentials/tests/BUILD.gn b/src/credentials/tests/BUILD.gn index 46e1f724349102..e83749a4ecd2fd 100644 --- a/src/credentials/tests/BUILD.gn +++ b/src/credentials/tests/BUILD.gn @@ -43,7 +43,6 @@ static_library("cert_test_vectors") { chip_test_suite("tests") { output_name = "libCredentialsTest" - output_dir = "${root_out_dir}/lib" test_sources = [ "TestCertificationDeclaration.cpp", From 4616ac81296b7ac7c209efca940bd6a81e885e23 Mon Sep 17 00:00:00 2001 From: Raul Marquez <130402456+raul-marquez-csa@users.noreply.github.com> Date: Wed, 16 Oct 2024 12:39:29 -0700 Subject: [PATCH 005/149] TC-S-2.5, 2.6 - Updates logs, preconditions (#35054) * Updates logs * Removed ./chip-tool when in interactive mode, added the description about comissioning TH1 * Added ./chiptool to precondition steps --------- Co-authored-by: lpbeliveau-silabs --- .../suites/certification/Test_TC_S_2_5.yaml | 190 +++++++++--------- .../suites/certification/Test_TC_S_2_6.yaml | 33 +-- 2 files changed, 115 insertions(+), 108 deletions(-) diff --git a/src/app/tests/suites/certification/Test_TC_S_2_5.yaml b/src/app/tests/suites/certification/Test_TC_S_2_5.yaml index 8616c15665531e..46cee01c3c36f7 100644 --- a/src/app/tests/suites/certification/Test_TC_S_2_5.yaml +++ b/src/app/tests/suites/certification/Test_TC_S_2_5.yaml @@ -27,8 +27,8 @@ tests: - label: "Precondition" verification: | - Commission DUT to TH - - A given fabric SHALL NOT consume more than half (rounded down towards 0) of the Scene Table entries (as indicated in the SceneTableSize attribute). - - MaxRemainingCapacity is SceneTableSize/2. + - The Scene Table capacity for a given fabric SHALL be less than half (rounded down towards 0) of the Scene Table entries (as indicated in the SceneTableSize attribute). + - MaxRemainingCapacity is (SceneTableSize-1)/2. disabled: true - label: @@ -181,56 +181,56 @@ tests: Set up the subscription between DUT and TH by sending the command mentioned below, and verify that the subscription is activated successfully - scenesmanagement subscribe fabric-scene-info 0 200 1 1 + scenesmanagement subscribe fabric-scene-info 5 100 1 1 Verify the DUT sends a report data for FabricSceneInfo after the MinIntervalFloor time; store the RemainingCapacity field from this fabric’s entry reported in FabricSceneInfo into RemainingCapacity and is equals to (MaxRemainingCapacity) on the TH (Chip-tool) and below is the sample log provided for the raspi platform: - [1706764401.002841][4438:4440] CHIP:DMG: ReportDataMessage = - [1706764401.002862][4438:4440] CHIP:DMG: { - [1706764401.002879][4438:4440] CHIP:DMG: SubscriptionId = 0x679cab48, - [1706764401.002891][4438:4440] CHIP:DMG: AttributeReportIBs = - [1706764401.002916][4438:4440] CHIP:DMG: [ - [1706764401.002926][4438:4440] CHIP:DMG: AttributeReportIB = - [1706764401.002950][4438:4440] CHIP:DMG: { - [1706764401.002960][4438:4440] CHIP:DMG: AttributeDataIB = - [1706764401.002972][4438:4440] CHIP:DMG: { - [1706764401.002985][4438:4440] CHIP:DMG: DataVersion = 0xec4c4ebe, - [1706764401.002996][4438:4440] CHIP:DMG: AttributePathIB = - [1706764401.003008][4438:4440] CHIP:DMG: { - [1706764401.003021][4438:4440] CHIP:DMG: Endpoint = 0x1, - [1706764401.003035][4438:4440] CHIP:DMG: Cluster = 0x62, - [1706764401.003048][4438:4440] CHIP:DMG: Attribute = 0x0000_0002, - [1706764401.003059][4438:4440] CHIP:DMG: } - [1706764401.003076][4438:4440] CHIP:DMG: - [1706764401.003088][4438:4440] CHIP:DMG: Data = [ - [1706764401.003105][4438:4440] CHIP:DMG: - [1706764401.003121][4438:4440] CHIP:DMG: { - [1706764401.003136][4438:4440] CHIP:DMG: 0x0 = 0, - [1706764401.003150][4438:4440] CHIP:DMG: 0x1 = 1, - [1706764401.003162][4438:4440] CHIP:DMG: 0x2 = 1, - [1706764401.003175][4438:4440] CHIP:DMG: 0x3 = false, - [1706764401.003190][4438:4440] CHIP:DMG: 0x4 = 7, - [1706764401.003203][4438:4440] CHIP:DMG: 0xfe = 1, - [1706764401.003216][4438:4440] CHIP:DMG: }, - [1706764401.003229][4438:4440] CHIP:DMG: ], - [1706764401.003239][4438:4440] CHIP:DMG: }, - [1706764401.003260][4438:4440] CHIP:DMG: - [1706764401.003270][4438:4440] CHIP:DMG: }, - [1706764401.003292][4438:4440] CHIP:DMG: - [1706764401.003301][4438:4440] CHIP:DMG: ], - [1706764401.003324][4438:4440] CHIP:DMG: - [1706764401.003334][4438:4440] CHIP:DMG: InteractionModelRevision = 11 - [1706764401.003343][4438:4440] CHIP:DMG: } - [1706764401.003557][4438:4440] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0062 Attribute 0x0000_0002 DataVersion: 3964423870 - [1706764401.003615][4438:4440] CHIP:TOO: FabricSceneInfo: 1 entries - [1706764401.003676][4438:4440] CHIP:TOO: [1]: { - [1706764401.003698][4438:4440] CHIP:TOO: SceneCount: 0 - [1706764401.003708][4438:4440] CHIP:TOO: CurrentScene: 1 - [1706764401.003718][4438:4440] CHIP:TOO: CurrentGroup: 1 - [1706764401.003728][4438:4440] CHIP:TOO: SceneValid: FALSE - [1706764401.003740][4438:4440] CHIP:TOO: RemainingCapacity: 7 - [1706764401.003750][4438:4440] CHIP:TOO: FabricIndex: 1 - [1706764401.003761][4438:4440] CHIP:TOO: } + [1720506229.849] [3777:3779] [DMG] ReportDataMessage = + [1720506229.849] [3777:3779] [DMG] { + [1720506229.849] [3777:3779] [DMG] SubscriptionId = 0x5da2bd16, + [1720506229.849] [3777:3779] [DMG] AttributeReportIBs = + [1720506229.849] [3777:3779] [DMG] [ + [1720506229.849] [3777:3779] [DMG] AttributeReportIB = + [1720506229.849] [3777:3779] [DMG] { + [1720506229.849] [3777:3779] [DMG] AttributeDataIB = + [1720506229.850] [3777:3779] [DMG] { + [1720506229.850] [3777:3779] [DMG] DataVersion = 0xdcafe47f, + [1720506229.850] [3777:3779] [DMG] AttributePathIB = + [1720506229.850] [3777:3779] [DMG] { + [1720506229.850] [3777:3779] [DMG] Endpoint = 0x1, + [1720506229.850] [3777:3779] [DMG] Cluster = 0x62, + [1720506229.850] [3777:3779] [DMG] Attribute = 0x0000_0002, + [1720506229.850] [3777:3779] [DMG] } + [1720506229.850] [3777:3779] [DMG] + [1720506229.850] [3777:3779] [DMG] Data = [ + [1720506229.850] [3777:3779] [DMG] + [1720506229.850] [3777:3779] [DMG] { + [1720506229.850] [3777:3779] [DMG] 0x0 = 0 (unsigned), + [1720506229.850] [3777:3779] [DMG] 0x1 = 0 (unsigned), + [1720506229.850] [3777:3779] [DMG] 0x2 = 0 (unsigned), + [1720506229.850] [3777:3779] [DMG] 0x3 = false, + [1720506229.850] [3777:3779] [DMG] 0x4 = 7 (unsigned), + [1720506229.850] [3777:3779] [DMG] 0xfe = 1 (unsigned), + [1720506229.850] [3777:3779] [DMG] }, + [1720506229.851] [3777:3779] [DMG] ], + [1720506229.851] [3777:3779] [DMG] }, + [1720506229.851] [3777:3779] [DMG] + [1720506229.851] [3777:3779] [DMG] }, + [1720506229.851] [3777:3779] [DMG] + [1720506229.851] [3777:3779] [DMG] ], + [1720506229.851] [3777:3779] [DMG] + [1720506229.851] [3777:3779] [DMG] InteractionModelRevision = 11 + [1720506229.851] [3777:3779] [DMG] } + [1720506229.851] [3777:3779] [TOO] Endpoint: 1 Cluster: 0x0000_0062 Attribute 0x0000_0002 DataVersion: 3702514815 + [1720506229.851] [3777:3779] [TOO] FabricSceneInfo: 1 entries + [1720506229.851] [3777:3779] [TOO] [1]: { + [1720506229.852] [3777:3779] [TOO] SceneCount: 0 + [1720506229.852] [3777:3779] [TOO] CurrentScene: 0 + [1720506229.852] [3777:3779] [TOO] CurrentGroup: 0 + [1720506229.852] [3777:3779] [TOO] SceneValid: FALSE + [1720506229.852] [3777:3779] [TOO] RemainingCapacity: 7 + [1720506229.852] [3777:3779] [TOO] FabricIndex: 1 + [1720506229.852] [3777:3779] [TOO] } disabled: true - label: @@ -275,52 +275,52 @@ tests: verification: | Verify that the DUT sends a report data for FabricSceneInfo after the MinIntervalFloor time; store the RemainingCapacity field from this fabric’s entry reported in FabricSceneInfo into RemainingCapacity and is equals to (MaxRemainingCapacity-1). - [1706764465.493922][4438:4440] CHIP:DMG: ReportDataMessage = - [1706764465.493926][4438:4440] CHIP:DMG: { - [1706764465.493928][4438:4440] CHIP:DMG: SubscriptionId = 0xcd5a528f, - [1706764465.493931][4438:4440] CHIP:DMG: AttributeReportIBs = - [1706764465.493937][4438:4440] CHIP:DMG: [ - [1706764465.493939][4438:4440] CHIP:DMG: AttributeReportIB = - [1706764465.493944][4438:4440] CHIP:DMG: { - [1706764465.493947][4438:4440] CHIP:DMG: AttributeDataIB = - [1706764465.493949][4438:4440] CHIP:DMG: { - [1706764465.493952][4438:4440] CHIP:DMG: DataVersion = 0xec4c4ec0, - [1706764465.493955][4438:4440] CHIP:DMG: AttributePathIB = - [1706764465.493958][4438:4440] CHIP:DMG: { - [1706764465.493961][4438:4440] CHIP:DMG: Endpoint = 0x1, - [1706764465.493963][4438:4440] CHIP:DMG: Cluster = 0x62, - [1706764465.493966][4438:4440] CHIP:DMG: Attribute = 0x0000_0002, - [1706764465.493969][4438:4440] CHIP:DMG: } - [1706764465.493974][4438:4440] CHIP:DMG: - [1706764465.493979][4438:4440] CHIP:DMG: Data = [ - [1706764465.493985][4438:4440] CHIP:DMG: - [1706764465.493990][4438:4440] CHIP:DMG: { - [1706764465.493997][4438:4440] CHIP:DMG: 0x0 = 1, - [1706764465.494002][4438:4440] CHIP:DMG: 0x1 = 1, - [1706764465.494007][4438:4440] CHIP:DMG: 0x2 = 1, - [1706764465.494013][4438:4440] CHIP:DMG: 0x3 = false, - [1706764465.494018][4438:4440] CHIP:DMG: 0x4 = 6, - [1706764465.494023][4438:4440] CHIP:DMG: 0xfe = 1, - [1706764465.494029][4438:4440] CHIP:DMG: }, - [1706764465.494034][4438:4440] CHIP:DMG: ], - [1706764465.494038][4438:4440] CHIP:DMG: }, - [1706764465.494047][4438:4440] CHIP:DMG: - [1706764465.494050][4438:4440] CHIP:DMG: }, - [1706764465.494059][4438:4440] CHIP:DMG: - [1706764465.494062][4438:4440] CHIP:DMG: ], - [1706764465.494070][4438:4440] CHIP:DMG: - [1706764465.494073][4438:4440] CHIP:DMG: InteractionModelRevision = 11 - [1706764465.494077][4438:4440] CHIP:DMG: } - [1706764465.494130][4438:4440] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0062 Attribute 0x0000_0002 DataVersion: 3964423872 - [1706764465.494142][4438:4440] CHIP:TOO: FabricSceneInfo: 1 entries - [1706764465.494152][4438:4440] CHIP:TOO: [1]: { - [1706764465.494155][4438:4440] CHIP:TOO: SceneCount: 1 - [1706764465.494158][4438:4440] CHIP:TOO: CurrentScene: 1 - [1706764465.494161][4438:4440] CHIP:TOO: CurrentGroup: 1 - [1706764465.494164][4438:4440] CHIP:TOO: SceneValid: FALSE - [1706764465.494167][4438:4440] CHIP:TOO: RemainingCapacity: 6 - [1706764465.494170][4438:4440] CHIP:TOO: FabricIndex: 1 - [1706764465.494174][4438:4440] CHIP:TOO: } + [1720506650.012] [3835:3837] [DMG] ReportDataMessage = + [1720506650.012] [3835:3837] [DMG] { + [1720506650.012] [3835:3837] [DMG] SubscriptionId = 0x8e3fb466, + [1720506650.012] [3835:3837] [DMG] AttributeReportIBs = + [1720506650.012] [3835:3837] [DMG] [ + [1720506650.012] [3835:3837] [DMG] AttributeReportIB = + [1720506650.012] [3835:3837] [DMG] { + [1720506650.012] [3835:3837] [DMG] AttributeDataIB = + [1720506650.012] [3835:3837] [DMG] { + [1720506650.013] [3835:3837] [DMG] DataVersion = 0xd2aec24e, + [1720506650.013] [3835:3837] [DMG] AttributePathIB = + [1720506650.013] [3835:3837] [DMG] { + [1720506650.013] [3835:3837] [DMG] Endpoint = 0x1, + [1720506650.013] [3835:3837] [DMG] Cluster = 0x62, + [1720506650.013] [3835:3837] [DMG] Attribute = 0x0000_0002, + [1720506650.013] [3835:3837] [DMG] } + [1720506650.013] [3835:3837] [DMG] + [1720506650.013] [3835:3837] [DMG] Data = [ + [1720506650.014] [3835:3837] [DMG] + [1720506650.014] [3835:3837] [DMG] { + [1720506650.014] [3835:3837] [DMG] 0x0 = 1 (unsigned), + [1720506650.014] [3835:3837] [DMG] 0x1 = 0 (unsigned), + [1720506650.014] [3835:3837] [DMG] 0x2 = 0 (unsigned), + [1720506650.014] [3835:3837] [DMG] 0x3 = false, + [1720506650.014] [3835:3837] [DMG] 0x4 = 6 (unsigned), + [1720506650.014] [3835:3837] [DMG] 0xfe = 1 (unsigned), + [1720506650.014] [3835:3837] [DMG] }, + [1720506650.015] [3835:3837] [DMG] ], + [1720506650.015] [3835:3837] [DMG] }, + [1720506650.015] [3835:3837] [DMG] + [1720506650.015] [3835:3837] [DMG] }, + [1720506650.015] [3835:3837] [DMG] + [1720506650.015] [3835:3837] [DMG] ], + [1720506650.015] [3835:3837] [DMG] + [1720506650.015] [3835:3837] [DMG] InteractionModelRevision = 11 + [1720506650.015] [3835:3837] [DMG] } + [1720506650.016] [3835:3837] [TOO] Endpoint: 1 Cluster: 0x0000_0062 Attribute 0x0000_0002 DataVersion: 3534668366 + [1720506650.016] [3835:3837] [TOO] FabricSceneInfo: 1 entries + [1720506650.016] [3835:3837] [TOO] [1]: { + [1720506650.016] [3835:3837] [TOO] SceneCount: 1 + [1720506650.016] [3835:3837] [TOO] CurrentScene: 0 + [1720506650.016] [3835:3837] [TOO] CurrentGroup: 0 + [1720506650.016] [3835:3837] [TOO] SceneValid: FALSE + [1720506650.016] [3835:3837] [TOO] RemainingCapacity: 6 + [1720506650.016] [3835:3837] [TOO] FabricIndex: 1 + [1720506650.016] [3835:3837] [TOO] } disabled: true - label: diff --git a/src/app/tests/suites/certification/Test_TC_S_2_6.yaml b/src/app/tests/suites/certification/Test_TC_S_2_6.yaml index 5a578eeb8a7866..cff80b796ab11c 100644 --- a/src/app/tests/suites/certification/Test_TC_S_2_6.yaml +++ b/src/app/tests/suites/certification/Test_TC_S_2_6.yaml @@ -28,8 +28,15 @@ config: tests: - label: "Precondition: Commission DUT to TH1" verification: | - Once DUT reach the commissionable state send the following command on TH1: - pairing onnetwork 1 20202021 + - DUT should be commissioned onto TH1, TH2, and TH3. + - The Scene Table capacity for a given fabric SHALL be less than half (rounded down towards 0) of the Scene Table entries (as indicated in the SceneTableSize attribute). + - MaxRemainingCapacity is (SceneTableSize-1)/2. + - TH1, TH2, and TH3 should be on separate, distinct fabrics. + + Send the below command in respective DUT + ./chip-all-clusters-app + + Once DUT reach the commissionable state send the following command ./chip-tool pairing onnetwork 1 20202021 command on TH1. Verify the commissioning completed with success on TH(chip-tool) from DUT [1650455358.501816][4366:4371] CHIP:TOO: Device commissioning completed with success disabled: true @@ -38,7 +45,7 @@ tests: verification: | Open a commissioning window On TH1(Chiptool)using below command - pairing open-commissioning-window 1 1 400 2000 3841 + ./chip-tool pairing open-commissioning-window 1 1 400 2000 3841 Verify the Successfully opened pairing window On TH1(Chiptool)e device @@ -52,7 +59,7 @@ tests: verification: | Now send the below command for commissionin DUT to TH2 with Manual pairing code generated in TH1 using open commission window - pairing code 2 36253605617 --commissioner-name beta + ./chip-tool pairing code 2 36253605617 --commissioner-name beta Verify the commissioning completed with success on TH2(chip-tool) from DUT @@ -64,7 +71,7 @@ tests: verification: | Open a commissioning window On TH1(Chiptool)using below command - pairing open-commissioning-window 1 1 400 2000 3842 + ./chip-tool pairing open-commissioning-window 1 1 400 2000 3842 Verify the Successfully opened pairing window On TH1(Chiptool)e device @@ -78,7 +85,7 @@ tests: verification: | send the below command for commissionin DUT to TH3 with Manual pairing code generated in TH1 using open commission window - pairing code 3 36545248276 --commissioner-name gamma + ./chip-tool pairing code 3 36545248276 --commissioner-name gamma Verify the commissioning completed with success on TH3(chip-tool) from DUT @@ -91,7 +98,7 @@ tests: field set to 0x0000." PICS: S.S.C03.Rsp verification: | - scenesmanagement remove-all-scenes 0x0000 1 1 + ./chip-tool scenesmanagement remove-all-scenes 0x0000 1 1 Verify the RemoveAllScenesResponse with following fields: Status is SUCCESS @@ -107,7 +114,7 @@ tests: - label: "Step 1b: Repeat Step 1a with TH2." PICS: S.S.C03.Rsp verification: | - scenesmanagement remove-all-scenes 0x0000 2 1 --commissioner-name beta + ./chip-tool scenesmanagement remove-all-scenes 0x0000 2 1 --commissioner-name beta Verify the RemoveAllScenesResponse with following fields: Status is SUCCESS @@ -124,7 +131,7 @@ tests: - label: "Step 1C: Repeat Step 1a with TH3." PICS: S.S.C03.Rsp verification: | - scenesmanagement remove-all-scenes 0x0000 3 1 --commissioner-name gamma + ./chip-tool scenesmanagement remove-all-scenes 0x0000 3 1 --commissioner-name gamma Verify the RemoveAllScenesResponse with following fields: Status is SUCCESS @@ -140,7 +147,7 @@ tests: - label: "Step 2a: TH1 reads from the DUT the SceneTableSize attribute" verification: | - scenesmanagement read scene-table-size 1 1 + ./chip-tool scenesmanagement read scene-table-size 1 1 Verify the "SceneTableSize" attribute value is SceneTableSize(minimum=16) which is recorded into SceneTableSize on the TH (Chip-tool) and below is the sample log provided for the raspi platform: @@ -155,7 +162,7 @@ tests: verification: | Please use Interactive mode to Verify the subscription Here the command to enter interactive mode:-- - interactive start + ./chip-tool interactive start Set up the subscription between DUT and TH by sending the command mentioned below, and verify that the subscription is activated successfully @@ -235,7 +242,7 @@ tests: Please use Interactive mode to Verify the subscription of an event Here the command to enter interactive mode:-- - interactive start + ./chip-tool interactive start Set up the subscription between DUT and TH by sending the command mentioned below, and verify that the subscription is activated successfully @@ -295,7 +302,7 @@ tests: verification: | Please use Interactive mode to Verify the subscription of an event Here the command to enter interactive mode:-- - interactive start + ./chip-tool interactive start Set up the subscription between DUT and TH by sending the command mentioned below, and verify that the subscription is activated successfully From 4318c3a0a5bac0dcf55ea2a7f476e9bcb8e5b0fb Mon Sep 17 00:00:00 2001 From: C Freeman Date: Wed, 16 Oct 2024 15:41:21 -0400 Subject: [PATCH 006/149] Remove remaining Global Attributes tests (#36029) --- .../certification/Test_TC_CDOCONC_1_1.yaml | 336 --------- .../certification/Test_TC_CMOCONC_1_1.yaml | 336 --------- .../certification/Test_TC_CNET_1_3.yaml | 219 ------ .../suites/certification/Test_TC_DEM_1_1.yaml | 123 ---- .../certification/Test_TC_FLDCONC_1_1.yaml | 339 ---------- .../certification/Test_TC_ICDM_1_1.yaml | 223 ------ .../certification/Test_TC_LTIME_1_2.yaml | 116 ---- .../certification/Test_TC_MWOCTRL_1_1.yaml | 170 ----- .../certification/Test_TC_NDOCONC_1_1.yaml | 339 ---------- .../certification/Test_TC_OZCONC_1_1.yaml | 339 ---------- .../suites/certification/Test_TC_PCC_1_1.yaml | 555 --------------- .../certification/Test_TC_PMHCONC_1_1.yaml | 336 --------- .../certification/Test_TC_PMICONC_1_1.yaml | 336 --------- .../certification/Test_TC_PMKCONC_1_1.yaml | 336 --------- .../certification/Test_TC_PWRTL_1_1.yaml | 143 ---- .../certification/Test_TC_RNCONC_1_1.yaml | 339 ---------- .../certification/Test_TC_SMOKECO_1_1.yaml | 269 -------- .../certification/Test_TC_SWTCH_1_1.yaml | 184 ----- .../certification/Test_TC_TCTL_1_1.yaml | 158 ----- .../certification/Test_TC_TSTAT_1_1.yaml | 639 ------------------ .../certification/Test_TC_TVOCCONC_1_1.yaml | 339 ---------- .../certification/Test_TC_WNCV_1_1.yaml | 248 ------- 22 files changed, 6422 deletions(-) delete mode 100644 src/app/tests/suites/certification/Test_TC_CDOCONC_1_1.yaml delete mode 100644 src/app/tests/suites/certification/Test_TC_CMOCONC_1_1.yaml delete mode 100644 src/app/tests/suites/certification/Test_TC_CNET_1_3.yaml delete mode 100644 src/app/tests/suites/certification/Test_TC_DEM_1_1.yaml delete mode 100644 src/app/tests/suites/certification/Test_TC_FLDCONC_1_1.yaml delete mode 100755 src/app/tests/suites/certification/Test_TC_ICDM_1_1.yaml delete mode 100644 src/app/tests/suites/certification/Test_TC_LTIME_1_2.yaml delete mode 100644 src/app/tests/suites/certification/Test_TC_MWOCTRL_1_1.yaml delete mode 100644 src/app/tests/suites/certification/Test_TC_NDOCONC_1_1.yaml delete mode 100644 src/app/tests/suites/certification/Test_TC_OZCONC_1_1.yaml delete mode 100644 src/app/tests/suites/certification/Test_TC_PCC_1_1.yaml delete mode 100644 src/app/tests/suites/certification/Test_TC_PMHCONC_1_1.yaml delete mode 100644 src/app/tests/suites/certification/Test_TC_PMICONC_1_1.yaml delete mode 100644 src/app/tests/suites/certification/Test_TC_PMKCONC_1_1.yaml delete mode 100644 src/app/tests/suites/certification/Test_TC_PWRTL_1_1.yaml delete mode 100644 src/app/tests/suites/certification/Test_TC_RNCONC_1_1.yaml delete mode 100644 src/app/tests/suites/certification/Test_TC_SMOKECO_1_1.yaml delete mode 100644 src/app/tests/suites/certification/Test_TC_SWTCH_1_1.yaml delete mode 100644 src/app/tests/suites/certification/Test_TC_TCTL_1_1.yaml delete mode 100644 src/app/tests/suites/certification/Test_TC_TSTAT_1_1.yaml delete mode 100644 src/app/tests/suites/certification/Test_TC_TVOCCONC_1_1.yaml delete mode 100644 src/app/tests/suites/certification/Test_TC_WNCV_1_1.yaml diff --git a/src/app/tests/suites/certification/Test_TC_CDOCONC_1_1.yaml b/src/app/tests/suites/certification/Test_TC_CDOCONC_1_1.yaml deleted file mode 100644 index 963156554c928a..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_CDOCONC_1_1.yaml +++ /dev/null @@ -1,336 +0,0 @@ -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -name: 145.1.1. [TC-CDOCONC-1.1] Global Attributes with DUT as Server - -PICS: - - CDOCONC.S - -config: - nodeId: 0x12344321 - cluster: "Carbon Dioxide Concentration Measurement" - endpoint: 1 - -tests: - - label: "Step 1: Wait for the commissioned device to be retrieved" - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: Read the global attribute: ClusterRevision" - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 3 - constraints: - type: int16u - - - label: - "Step 3a: Read the global attribute: FeatureMap and check for either - bit 0 or 1 set" - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x03] - - - label: - "Step 3b: Given CDOCONC.S.F00(MEA) ensure featuremap has the correct - bit set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: CDOCONC.S.F00 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x1] - - - label: - "Step 3c: Given CDOCONC.S.F00(MEA) is not set, ensure featuremap has - the correct bit clear" - command: "readAttribute" - attribute: "FeatureMap" - PICS: " !CDOCONC.S.F00 " - response: - constraints: - type: bitmap32 - hasMasksClear: [0x1] - - - label: - "Step 3d: Given CDOCONC.S.F01(LEV) ensure featuremap has the correct - bit set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: CDOCONC.S.F01 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x2] - - - label: - "Step 3e: Given CDOCONC.S.F01(LEV) is not set, ensure featuremap has - the correct bit clear" - command: "readAttribute" - attribute: "FeatureMap" - PICS: " !CDOCONC.S.F01 " - response: - constraints: - type: bitmap32 - hasMasksClear: [0x2] - - - label: - "Step 3f: Given CDOCONC.S.F02(MED) ensure featuremap has the correct - bit set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: CDOCONC.S.F02 && CDOCONC.S.F01 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x4, 0x2] - - - label: - "Step 3g: Given CDOCONC.S.F02(MED) is not set, ensure featuremap has - the correct bit clear" - command: "readAttribute" - attribute: "FeatureMap" - PICS: " !CDOCONC.S.F02 && !CDOCONC.S.F01" - response: - constraints: - type: bitmap32 - hasMasksClear: [0x4, 0x2] - - - label: - "Step 3h: Given CDOCONC.S.F03(CRI) ensure featuremap has the correct - bits set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: CDOCONC.S.F03 && CDOCONC.S.F01 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x8, 0x2] - - - label: - "Step 3i: Given CDOCONC.S.F03(CRI) is not set, ensure featuremap has - the correct bit clear" - command: "readAttribute" - attribute: "FeatureMap" - PICS: " !CDOCONC.S.F03 && !CDOCONC.S.F01" - response: - constraints: - type: bitmap32 - hasMasksClear: [0x8, 0x2] - - - label: - "Step 3j: Given CDOCONC.S.F04(PEA) ensure featuremap has the correct - bits set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: CDOCONC.S.F04 && CDOCONC.S.F00 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x10, 0x1] - - - label: - "Step 3k: Given CDOCONC.S.F04(PEA) is not set, ensure featuremap has - the correct bit clear" - command: "readAttribute" - attribute: "FeatureMap" - PICS: " !CDOCONC.S.F04 && !CDOCONC.S.F00" - response: - constraints: - type: bitmap32 - hasMasksClear: [0x10, 0x1] - - - label: - "Step 3l: Given CDOCONC.S.F05(AVG) ensure featuremap has the correct - bits set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: CDOCONC.S.F05 && CDOCONC.S.F00 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x20, 0x1] - - - label: - "Step 3m: Given CDOCONC.S.F05(AVG) is not set, ensure featuremap has - the correct bit clear" - command: "readAttribute" - attribute: "FeatureMap" - PICS: " !CDOCONC.S.F05 && !CDOCONC.S.F00" - response: - constraints: - type: bitmap32 - hasMasksClear: [0x20, 0x1] - - - label: "Step 4a: Read the global attribute: AttributeList" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [9, 65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 4a: Read the global attribute: AttributeList" - PICS: " !PICS_EVENT_LIST_ENABLED " - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [9, 65528, 65529, 65531, 65532, 65533] - - - label: "Step 4b: Read the optional attribute Uncertainty in AttributeList" - command: "readAttribute" - attribute: "AttributeList" - PICS: CDOCONC.S.A0007 && CDOCONC.S.F00 - response: - constraints: - type: list - contains: [7] - - - label: - "Step 4c: Check the optional attribute Uncertainty is excluded from - AttributeList when CDOCONC.S.A0007 is not set" - command: "readAttribute" - attribute: "AttributeList" - PICS: " !CDOCONC.S.A0007 " - response: - constraints: - type: list - excludes: [7] - - - label: - "Step 4d: Read the optional, feature dependent attributes - MeasuredValue, MinMeasuredValue, MaxMeasuredValue and Measurement Unit - in AttributeList" - command: "readAttribute" - attribute: "AttributeList" - PICS: CDOCONC.S.F00 - response: - constraints: - type: list - contains: [0, 1, 2, 8] - - - label: - "Step 4e: Check that MeasuredValue, MinMeasuredValue, - MaxMeasuredValue, Measurement Unit and Uncertainty are excluded from - AttributeList when CDOCONC.S.F00 (MEA) is not set" - command: "readAttribute" - attribute: "AttributeList" - PICS: " !CDOCONC.S.F00 " - response: - constraints: - type: list - excludes: [0, 1, 2, 7, 8] - - - label: - "Step 4f: Read the optional, feature dependent attributes - PeakMeasuredValue & PeakMeasuredValueWindow in AttributeList" - command: "readAttribute" - attribute: "AttributeList" - PICS: CDOCONC.S.F04 - response: - constraints: - type: list - contains: [3, 4] - - - label: - "Step 4g: Check that PeakMeasuredValue & PeakMeasuredValueWindow are - excluded from AttributeList when CDOCONC.S.F04 (PEA) is not set" - command: "readAttribute" - attribute: "AttributeList" - PICS: " !CDOCONC.S.F04 " - response: - constraints: - type: list - excludes: [3, 4] - - - label: - "Step 4h: Read the optional, feature dependent attributes - AverageMeasuredValue AverageMeasuredValueWindow in AttributeList" - command: "readAttribute" - attribute: "AttributeList" - PICS: CDOCONC.S.F05 - response: - constraints: - type: list - contains: [5, 6] - - - label: - "Step 4i: Check that AverageMeasuredValue and - AverageMeasuredValueWindow are excluded from AttributeList when - CDOCONC.S.F05 (AVG) is not set" - command: "readAttribute" - attribute: "AttributeList" - PICS: " !CDOCONC.S.F05 " - response: - constraints: - type: list - excludes: [5, 6] - - - label: - "Step 4j: Read the optional, feature dependent attribute LevelValue in - AttributeList" - command: "readAttribute" - attribute: "AttributeList" - PICS: CDOCONC.S.F01 - response: - constraints: - type: list - contains: [10] - - - label: - "Step 4k: Check that LevelValue is excluded from AttributeList when - CDOCONC.S.F01 (LEV) is not set" - command: "readAttribute" - attribute: "AttributeList" - PICS: " !CDOCONC.S.F01 " - response: - constraints: - type: list - excludes: [10] - - - label: "Step 5: Read the global attribute: EventList" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - value: [] - constraints: - type: list - - - label: "Step 6: Read the global attribute: AcceptedCommandList" - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - value: [] - constraints: - type: list - - - label: "Step 7: Read the global attribute: GeneratedCommandList" - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - value: [] - constraints: - type: list diff --git a/src/app/tests/suites/certification/Test_TC_CMOCONC_1_1.yaml b/src/app/tests/suites/certification/Test_TC_CMOCONC_1_1.yaml deleted file mode 100644 index dfa949e6ffc58c..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_CMOCONC_1_1.yaml +++ /dev/null @@ -1,336 +0,0 @@ -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -name: 145.1.1. [TC-CMOCONC-1.1] Global Attributes with DUT as Server - -PICS: - - CMOCONC.S - -config: - nodeId: 0x12344321 - cluster: "Carbon Monoxide Concentration Measurement" - endpoint: 1 - -tests: - - label: "Step 1: Wait for the commissioned device to be retrieved" - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: Read the global attribute: ClusterRevision" - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 3 - constraints: - type: int16u - - - label: - "Step 3a: Read the global attribute: FeatureMap and check for either - bit 0 or 1 set" - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x03] - - - label: - "Step 3b: Given CMOCONC.S.F00(MEA) ensure featuremap has the correct - bit set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: CMOCONC.S.F00 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x1] - - - label: - "Step 3c: Given CMOCONC.S.F00(MEA) is not set, ensure featuremap has - the correct bit clear" - command: "readAttribute" - attribute: "FeatureMap" - PICS: " !CMOCONC.S.F00 " - response: - constraints: - type: bitmap32 - hasMasksClear: [0x1] - - - label: - "Step 3d: Given CMOCONC.S.F01(LEV) ensure featuremap has the correct - bit set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: CMOCONC.S.F01 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x2] - - - label: - "Step 3e: Given CMOCONC.S.F01(LEV) is not set, ensure featuremap has - the correct bit clear" - command: "readAttribute" - attribute: "FeatureMap" - PICS: " !CMOCONC.S.F01 " - response: - constraints: - type: bitmap32 - hasMasksClear: [0x2] - - - label: - "Step 3f: Given CMOCONC.S.F02(MED) ensure featuremap has the correct - bit set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: CMOCONC.S.F02 && CMOCONC.S.F01 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x4, 0x2] - - - label: - "Step 3g: Given CMOCONC.S.F02(MED) is not set, ensure featuremap has - the correct bit clear" - command: "readAttribute" - attribute: "FeatureMap" - PICS: " !CMOCONC.S.F02 && !CMOCONC.S.F01" - response: - constraints: - type: bitmap32 - hasMasksClear: [0x4] - - - label: - "Step 3h: Given CMOCONC.S.F03(CRI) ensure featuremap has the correct - bits set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: CMOCONC.S.F03 && CMOCONC.S.F01 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x8, 0x2] - - - label: - "Step 3i: Given CMOCONC.S.F03(CRI) is not set, ensure featuremap has - the correct bit clear" - command: "readAttribute" - attribute: "FeatureMap" - PICS: " !CMOCONC.S.F03 && !CMOCONC.S.F01" - response: - constraints: - type: bitmap32 - hasMasksClear: [0x8] - - - label: - "Step 3j: Given CMOCONC.S.F04(PEA) ensure featuremap has the correct - bits set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: CMOCONC.S.F04 && CMOCONC.S.F00 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x10, 0x1] - - - label: - "Step 3k: Given CMOCONC.S.F04(PEA) is not set, ensure featuremap has - the correct bit clear" - command: "readAttribute" - attribute: "FeatureMap" - PICS: " !CMOCONC.S.F04 && !CMOCONC.S.F00" - response: - constraints: - type: bitmap32 - hasMasksClear: [0x10] - - - label: - "Step 3l: Given CMOCONC.S.F05(AVG) ensure featuremap has the correct - bits set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: CMOCONC.S.F05 && CMOCONC.S.F00 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x20, 0x1] - - - label: - "Step 3m: Given CMOCONC.S.F05(AVG) is not set, ensure featuremap has - the correct bit clear" - command: "readAttribute" - attribute: "FeatureMap" - PICS: " !CMOCONC.S.F05 && !CMOCONC.S.F00 " - response: - constraints: - type: bitmap32 - hasMasksClear: [0x20] - - - label: "Step 4a: Read the global attribute: AttributeList" - command: "readAttribute" - attribute: "AttributeList" - PICS: PICS_EVENT_LIST_ENABLED - response: - constraints: - type: list - contains: [9, 65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 4a: Read the global attribute: AttributeList" - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [9, 65528, 65529, 65531, 65532, 65533] - - - label: "Step 4b: Read the optional attribute Uncertainty in AttributeList" - command: "readAttribute" - attribute: "AttributeList" - PICS: CMOCONC.S.A0007 && CMOCONC.S.F00 - response: - constraints: - type: list - contains: [7] - - - label: - "Step 4c: Check the optional attribute Uncertainty is excluded from - AttributeList when CMOCONC.S.A0007 is not set" - command: "readAttribute" - attribute: "AttributeList" - PICS: " !CMOCONC.S.A0007 " - response: - constraints: - type: list - excludes: [7] - - - label: - "Step 4d: Read the optional, feature dependent attributes - MeasuredValue, MinMeasuredValue, MaxMeasuredValue and Measurement Unit - in AttributeList" - command: "readAttribute" - attribute: "AttributeList" - PICS: CMOCONC.S.F00 - response: - constraints: - type: list - contains: [0, 1, 2, 8] - - - label: - "Step 4e: Check that MeasuredValue, MinMeasuredValue, - MaxMeasuredValue, Measurement Unit and Uncertainty are excluded from - AttributeList when CMOCONC.S.F00 (MEA) is not set" - command: "readAttribute" - attribute: "AttributeList" - PICS: " !CMOCONC.S.F00 " - response: - constraints: - type: list - excludes: [0, 1, 2, 7, 8] - - - label: - "Step 4f: Read the optional, feature dependent attributes - PeakMeasuredValue & PeakMeasuredValueWindow in AttributeList" - command: "readAttribute" - attribute: "AttributeList" - PICS: CMOCONC.S.F04 - response: - constraints: - type: list - contains: [3, 4] - - - label: - "Step 4g: Check that PeakMeasuredValue & PeakMeasuredValueWindow are - excluded from AttributeList when CMOCONC.S.F04 (PEA) is not set" - command: "readAttribute" - attribute: "AttributeList" - PICS: " !CMOCONC.S.F04 " - response: - constraints: - type: list - excludes: [3, 4] - - - label: - "Step 4h: Read the optional, feature dependent attributes - AverageMeasuredValue AverageMeasuredValueWindow in AttributeList" - command: "readAttribute" - attribute: "AttributeList" - PICS: CMOCONC.S.F05 - response: - constraints: - type: list - contains: [5, 6] - - - label: - "Step 4i: Check that AverageMeasuredValue and - AverageMeasuredValueWindow are excluded from AttributeList when - CMOCONC.S.F05 (AVG) is not set" - command: "readAttribute" - attribute: "AttributeList" - PICS: " !CMOCONC.S.F05 " - response: - constraints: - type: list - excludes: [5, 6] - - - label: - "Step 4j: Read the optional, feature dependent attribute LevelValue in - AttributeList" - command: "readAttribute" - attribute: "AttributeList" - PICS: CMOCONC.S.F01 - response: - constraints: - type: list - contains: [10] - - - label: - "Step 4k: Check that LevelValue is excluded from AttributeList when - CMOCONC.S.F01 (LEV) is not set" - command: "readAttribute" - attribute: "AttributeList" - PICS: " !CMOCONC.S.F01 " - response: - constraints: - type: list - excludes: [10] - - - label: "Step 5: Read the global attribute: EventList" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - value: [] - constraints: - type: list - - - label: "Step 6: Read the global attribute: AcceptedCommandList" - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - value: [] - constraints: - type: list - - - label: "Step 7: Read the global attribute: GeneratedCommandList" - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - value: [] - constraints: - type: list diff --git a/src/app/tests/suites/certification/Test_TC_CNET_1_3.yaml b/src/app/tests/suites/certification/Test_TC_CNET_1_3.yaml deleted file mode 100644 index afa472af0aa12b..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_CNET_1_3.yaml +++ /dev/null @@ -1,219 +0,0 @@ -# Copyright (c) 2021 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -name: 12.1.3. [TC-CNET-1.3] Global Attributes with DUT as Server - -PICS: - - CNET.S - -config: - nodeId: 0x12344321 - cluster: "Network Commissioning" - endpoint: 0 - -tests: - - label: "Step 1: Wait for the commissioned device to be retrieved" - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: TH reads from the DUT the ClusterRevision attribute" - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 2 - constraints: - type: int16u - - - label: "Step 3a: TH reads from the DUT the FeatureMap attribute" - PICS: " !CNET.S.F00 && !CNET.S.F01 && !CNET.S.F02 " - command: "readAttribute" - attribute: "FeatureMap" - response: - value: 0 - - - label: - "Step 3b: TH reads the global attribute: FeatureMap when CNET.S.F00 is - set" - PICS: CNET.S.F00 - command: "readAttribute" - attribute: "FeatureMap" - response: - value: 1 - - - label: - "Step 3c: TH reads the global attribute: FeatureMap when CNET.S.F01 is - set" - PICS: CNET.S.F01 - command: "readAttribute" - attribute: "FeatureMap" - response: - value: 2 - - - label: - "Step 3d: TH reads the global attribute: FeatureMap when CNET.S.F02 is - set" - PICS: CNET.S.F02 - command: "readAttribute" - attribute: "FeatureMap" - response: - value: 4 - - - label: "Step 4a: TH reads from the DUT the AttributeList attribute" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 4b: TH reads from the DUT the AttributeList attribute." - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [65528, 65529, 65531, 65532, 65533] - - - label: - "Step 4c: TH reads mandatory attributes in AttributeList if - CNET.S.F00(WI)/CNET.S.F01(TH)/CNET.S.F02(ET) is true" - PICS: CNET.S.F00 || CNET.S.F01 || CNET.S.F02 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 1, 4, 5, 6, 7] - - - label: - "Step 4d: TH reads the feature dependent - attribute(ScanMaxTimeSeconds): AttributeList" - PICS: CNET.S.F00 || CNET.S.F01 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [2] - - - label: - "Step 4e: TH reads the feature dependent - attribute(ConnectMaxTimeSeconds) in AttributeList" - PICS: CNET.S.F00 || CNET.S.F01 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [3] - - - label: - "Step 4f: TH reads WIFI related attribute (SupportedWiFiBands) in - AttributeList" - PICS: CNET.S.F00 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [8] - - - label: - "Step 4g: TH reads Thread related attribute (SupportedWiFiBands and - ThreadVersion) in AttributeList" - PICS: CNET.S.F01 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [9, 10] - - - label: "Step 5: TH reads from the DUT the EventList attribute" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - value: [] - constraints: - type: list - - - label: - "Step 6a: TH reads AcceptedCommandList attribute from DUT. If DUT - supports Wi-Fi/Thread related features CNET.S.F00(WI),CNET.S.F01(TH)" - PICS: ( CNET.S.F00 || CNET.S.F01 ) - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [0, 4, 6, 8] - - - label: - "Step 6b: TH reads AcceptedCommandList attribute from DUT. If DUT - supports Wi-Fi related features (CNET.S.F00(WI) is true)" - PICS: CNET.S.F00 - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [2] - - - label: - "Step 6c: TH reads AcceptedCommandList attribute from DUT. If DUT - supports Thread related features(CNET.S.F01(TH) is true)" - PICS: CNET.S.F01 - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [3] - - - label: - "Step 6d: TH reads AcceptedCommandList attribute from DUT. If DUT - supports Ethernet related features(CNET.S.F02(TH) is true)" - PICS: CNET.S.F02 - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - value: [] - - - label: - "Step 7a: TH reads the GeneratedCommandList attribute from DUT. If DUT - supports Wi-Fi/Thread related features(CNET.S.F00(WI) or - CNET.S.F01(TH) is true)" - PICS: ( CNET.S.F00 || CNET.S.F01 ) - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - constraints: - type: list - contains: [1, 5, 7] - - - label: - "Step 7b: Read the GeneratedCommandList attribute from DUT. If DUT - supports Ethernet related features(CNET.S.F02(ET) must be true)" - PICS: CNET.S.F02 - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - value: [] diff --git a/src/app/tests/suites/certification/Test_TC_DEM_1_1.yaml b/src/app/tests/suites/certification/Test_TC_DEM_1_1.yaml deleted file mode 100644 index e69e5a62b0a820..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_DEM_1_1.yaml +++ /dev/null @@ -1,123 +0,0 @@ -# Copyright (c) 2024 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# Auto-generated scripts for harness use only, please review before automation. The endpoints and cluster names are currently set to default - -name: 237.1.1. [TC-DEM-1.1] Global Attributes with DUT as Server - -PICS: - - DEM.S - -config: - nodeId: 0x12344321 - cluster: "Basic Information" - endpoint: 0 - -tests: - - label: - "Step 1: Commission DUT to TH (can be skipped if done in a preceding - test)." - verification: | - - disabled: true - - - label: "Step 2: TH reads from the DUT the ClusterRevision attribute." - verification: | - ./chip-tool deviceenergymanagement read cluster-revision 1 1 - - On TH(chip-tool), Verify the ClusterRevision attribute value as 2: - Below mentioned log is based on the RPI implementation, Value may vary on real DUT - - [1705565332.698601][7061:7063] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0098 Attribute 0x0000_FFFD DataVersion: 1117764527 - [1705565332.698668][7061:7063] CHIP:TOO: ClusterRevision: 3 - disabled: true - - - label: "Step 3: TH reads from the DUT the FeatureMap attribute." - verification: | - ./chip-tool deviceenergymanagement read feature-map 1 1 - - Via the TH (chip-tool), verify that theFeatureMap attribute contains the value. Below mentioned log is based on the RPI implementation, Value may vary on real DUT - - - [1705565302.904580][7054:7056] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0098 Attribute 0x0000_FFFC DataVersion: 1117764527 - [1705565302.904631][7054:7056] CHIP:TOO: FeatureMap: 127 - disabled: true - - - label: "Step 4: TH reads from the DUT the AttributeList attribute." - verification: | - ./chip-tool deviceenergymanagement read attribute-list 1 1 - - Via the TH (chip-tool), verify that the AttributeList attribute contains - - Mandatory entries:0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0xfff8, 0xfff9, 0xfffb, 0xfffc and 0xfffd - - Based on feature support:- 0x0005, 0x0006, 0x0007 - Below mentioned log is based on the RPI implementation, Value may vary on real DUT - - [1723642027.628] [328171:328173] [TOO] Endpoint: 1 Cluster: 0x0000_0098 Attribute 0x0000_FFFB DataVersion: 3122179410 - [1723642027.628] [328171:328173] [TOO] AttributeList: 13 entries - [1723642027.628] [328171:328173] [TOO] [1]: 0 (ESAType) - [1723642027.628] [328171:328173] [TOO] [2]: 1 (ESACanGenerate) - [1723642027.628] [328171:328173] [TOO] [3]: 2 (ESAState) - [1723642027.628] [328171:328173] [TOO] [4]: 3 (AbsMinPower) - [1723642027.628] [328171:328173] [TOO] [5]: 4 (AbsMaxPower) - [1723642027.628] [328171:328173] [TOO] [6]: 5 (PowerAdjustmentCapability) - [1723642027.628] [328171:328173] [TOO] [7]: 6 (Forecast) - [1723642027.628] [328171:328173] [TOO] [8]: 7 (OptOutState) - [1723642027.628] [328171:328173] [TOO] [9]: 65528 (GeneratedCommandList) - [1723642027.628] [328171:328173] [TOO] [10]: 65529 (AcceptedCommandList) - [1723642027.628] [328171:328173] [TOO] [11]: 65531 (AttributeList) - [1723642027.628] [328171:328173] [TOO] [12]: 65532 (FeatureMap) - [1723642027.628] [328171:328173] [TOO] [13]: 65533 (ClusterRevision) - disabled: true - - - label: "Step 5*: TH reads from the DUT the EventList attribute." - verification: | - EventList is currently not supported and SHALL be skipped. - - ./chip-tool deviceenergymanagement read event-list 1 1 - - Via the TH (chip-tool), verify that the EventList attribute. Below mentioned log is based on the RPI implementation, Value may vary on real DUT - - [1703745599.166331][1300:1302] CHIP:DMG: StatusIB = - [1703745599.166364][1300:1302] CHIP:DMG: { - [1703745599.166419][1300:1302] CHIP:DMG: status = 0x86 (UNSUPPORTED_ATTRIBUTE), - [1703745599.166450][1300:1302] CHIP:DMG: }, - disabled: true - - - label: "Step 6: TH reads from the DUT the AcceptedCommandList attribute." - verification: | - ./chip-tool deviceenergymanagement read accepted-command-list 1 1 - - On TH(chip-tool), Verify the AcceptedCommandList attribute that contains 7 entries: - Below mentioned log is based on the RPI implementation, Value may vary on real DUT - - [1705649342.947638][6221:6223] [TOO] Endpoint: 1 Cluster: 0x0000_0098 Attribute 0x0000_FFF9 DataVersion: 633673396 - [1705649342.947712][6221:6223] [TOO] AcceptedCommandList: 8 entries - [1705649342.947754][6221:6223] [TOO] [1]: 0 (PowerAdjustRequest) - [1705649342.947779][6221:6223] [TOO] [2]: 1 (CancelPowerAdjustRequest) - [1705649342.947802][6221:6223] [TOO] [3]: 2 (StartTimeAdjustRequest) - [1705649342.947825][6221:6223] [TOO] [4]: 3 (PauseRequest) - [1705649342.947848][6221:6223] [TOO] [5]: 4 (ResumeRequest) - [1705649342.947871][6221:6223] [TOO] [6]: 5 (ModifyForecastRequest) - [1705649342.947894][6221:6223] [TOO] [7]: 6 (RequestConstraintBasedForecast) - [1705649342.947917][6221:6223] [TOO] [8]: 7 (CancelRequest) - disabled: true - - - label: "Step 7: TH reads from the DUT the GeneratedCommandList attribute." - verification: | - ./chip-tool deviceenergymanagement read generated-command-list 1 1 - - On TH(chip-tool), Verify the GeneratedCommandList attribute that contains 1 entries: - - [1705567897.076935][7141:7143] [TOO] Endpoint: 1 Cluster: 0x0000_0098 Attribute 0x0000_FFF8 DataVersion: 1117764527 - [1705567897.076989][7141:7143] [TOO] GeneratedCommandList: 0 entries - disabled: true diff --git a/src/app/tests/suites/certification/Test_TC_FLDCONC_1_1.yaml b/src/app/tests/suites/certification/Test_TC_FLDCONC_1_1.yaml deleted file mode 100644 index 14f37e7cbb3e29..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_FLDCONC_1_1.yaml +++ /dev/null @@ -1,339 +0,0 @@ -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -name: 145.1.1. [TC-FLDCONC-1.1] Global Attributes with DUT as Server - -PICS: - - FLDCONC.S - -config: - nodeId: 0x12344321 - cluster: "Formaldehyde Concentration Measurement" - endpoint: 1 - -tests: - - label: - "Step 1: Commission DUT to TH (can be skipped if done in a preceding - test)." - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: TH reads from the DUT the ClusterRevision attribute." - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 3 - constraints: - type: int16u - - - label: - "Step 3a: TH reads from the DUT the FeatureMap attribute. and check - for either bit 0 or 1 set" - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x03] - - - label: - "Step 3b: Given FLDCONC.S.F00(MEA) ensure featuremap has the correct - bit set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: FLDCONC.S.F00 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x1] - - - label: - "Step 3c: Given FLDCONC.S.F00(MEA) is not set, ensure featuremap has - the correct bit clear" - command: "readAttribute" - attribute: "FeatureMap" - PICS: " !FLDCONC.S.F00 " - response: - constraints: - type: bitmap32 - hasMasksClear: [0x1] - - - label: - "Step 3d: Given FLDCONC.S.F01(LEV) ensure featuremap has the correct - bit set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: FLDCONC.S.F01 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x2] - - - label: - "Step 3e: Given FLDCONC.S.F01(LEV) is not set, ensure featuremap has - the correct bit clear" - command: "readAttribute" - attribute: "FeatureMap" - PICS: " !FLDCONC.S.F01 " - response: - constraints: - type: bitmap32 - hasMasksClear: [0x2] - - - label: - "Step 3f: Given FLDCONC.S.F02(MED) ensure featuremap has the correct - bit set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: FLDCONC.S.F02 && FLDCONC.S.F01 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x4, 0x2] - - - label: - "Step 3g: Given FLDCONC.S.F02(MED) is not set, ensure featuremap has - the correct bit clear" - command: "readAttribute" - attribute: "FeatureMap" - PICS: " !FLDCONC.S.F02 && !FLDCONC.S.F01" - response: - constraints: - type: bitmap32 - hasMasksClear: [0x4] - - - label: - "Step 3h: Given FLDCONC.S.F03(CRI) ensure featuremap has the correct - bits set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: FLDCONC.S.F03 && FLDCONC.S.F01 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x8, 0x2] - - - label: - "Step 3i: Given FLDCONC.S.F03(CRI) is not set, ensure featuremap has - the correct bit clear" - command: "readAttribute" - attribute: "FeatureMap" - PICS: " !FLDCONC.S.F03 && !FLDCONC.S.F01 " - response: - constraints: - type: bitmap32 - hasMasksClear: [0x8] - - - label: - "Step 3j: Given FLDCONC.S.F04(PEA) ensure featuremap has the correct - bits set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: FLDCONC.S.F04 && FLDCONC.S.F00 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x10, 0x1] - - - label: - "Step 3k: Given FLDCONC.S.F04(PEA) is not set, ensure featuremap has - the correct bit clear" - command: "readAttribute" - attribute: "FeatureMap" - PICS: " !FLDCONC.S.F04 && !FLDCONC.S.F00 " - response: - constraints: - type: bitmap32 - hasMasksClear: [0x10] - - - label: - "Step 3l: Given FLDCONC.S.F05(AVG) ensure featuremap has the correct - bits set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: FLDCONC.S.F05 && FLDCONC.S.F00 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x20, 0x1] - - - label: - "Step 3m: Given FLDCONC.S.F05(AVG) is not set, ensure featuremap has - the correct bit clear" - command: "readAttribute" - attribute: "FeatureMap" - PICS: " !FLDCONC.S.F05 && !FLDCONC.S.F00" - response: - constraints: - type: bitmap32 - hasMasksClear: [0x20] - - - label: "Step 4a: TH reads from the DUT the AttributeList attribute." - command: "readAttribute" - attribute: "AttributeList" - PICS: PICS_EVENT_LIST_ENABLED - response: - constraints: - type: list - contains: [9, 65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 4a: TH reads from the DUT the AttributeList attribute." - command: "readAttribute" - attribute: "AttributeList" - PICS: "!PICS_EVENT_LIST_ENABLED" - response: - constraints: - type: list - contains: [9, 65528, 65529, 65531, 65532, 65533] - - - label: - "Step 4b: TH reads the optional attribute Uncertainty in AttributeList" - command: "readAttribute" - attribute: "AttributeList" - PICS: FLDCONC.S.A0007 && FLDCONC.S.F00 - response: - constraints: - type: list - contains: [7] - - - label: - "Step 4c: Check the optional attribute Uncertainty is excluded from - AttributeList when FLDCONC.S.A0007 is not set" - command: "readAttribute" - attribute: "AttributeList" - PICS: " !FLDCONC.S.A0007 " - response: - constraints: - type: list - excludes: [7] - - - label: - "Step 4d: TH reads the optional, feature dependent attributes - MeasuredValue, MinMeasuredValue, MaxMeasuredValue and Measurement Unit - in AttributeList" - command: "readAttribute" - attribute: "AttributeList" - PICS: FLDCONC.S.F00 - response: - constraints: - type: list - contains: [0, 1, 2, 8] - - - label: - "Step 4e: Check that MeasuredValue, MinMeasuredValue, - MaxMeasuredValue, Measurement Unit and Uncertainty are excluded from - AttributeList when FLDCONC.S.F00 (MEA) is not set" - command: "readAttribute" - attribute: "AttributeList" - PICS: " !FLDCONC.S.F00 " - response: - constraints: - type: list - excludes: [0, 1, 2, 7, 8] - - - label: - "Step 4f: TH reads the optional, feature dependent attributes - PeakMeasuredValue & PeakMeasuredValueWindow in AttributeList" - command: "readAttribute" - attribute: "AttributeList" - PICS: FLDCONC.S.F04 - response: - constraints: - type: list - contains: [3, 4] - - - label: - "Step 4g: Check that PeakMeasuredValue & PeakMeasuredValueWindow are - excluded from AttributeList when FLDCONC.S.F04 (PEA) is not set" - command: "readAttribute" - attribute: "AttributeList" - PICS: " !FLDCONC.S.F04 " - response: - constraints: - type: list - excludes: [3, 4] - - - label: - "Step 4h: TH reads the optional, feature dependent attributes - AverageMeasuredValue AverageMeasuredValueWindow in AttributeList" - command: "readAttribute" - attribute: "AttributeList" - PICS: FLDCONC.S.F05 - response: - constraints: - type: list - contains: [5, 6] - - - label: - "Step 4i: Check that AverageMeasuredValue and - AverageMeasuredValueWindow are excluded from AttributeList when - FLDCONC.S.F05 (AVG) is not set" - command: "readAttribute" - attribute: "AttributeList" - PICS: " !FLDCONC.S.F05 " - response: - constraints: - type: list - excludes: [5, 6] - - - label: - "Step 4j: TH reads the optional, feature dependent attribute - LevelValue in AttributeList" - command: "readAttribute" - attribute: "AttributeList" - PICS: FLDCONC.S.F01 - response: - constraints: - type: list - contains: [10] - - - label: - "Step 4k: Check that LevelValue is excluded from AttributeList when - FLDCONC.S.F01 (LEV) is not set" - command: "readAttribute" - attribute: "AttributeList" - PICS: " !FLDCONC.S.F01 " - response: - constraints: - type: list - excludes: [10] - - - label: "Step 5: TH reads from the DUT the EventList attribute." - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - value: [] - constraints: - type: list - - - label: "Step 6: TH reads from the DUT the AcceptedCommandList attribute." - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - value: [] - constraints: - type: list - - - label: "Step 7: TH reads from the DUT the GeneratedCommandList attribute." - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - value: [] - constraints: - type: list diff --git a/src/app/tests/suites/certification/Test_TC_ICDM_1_1.yaml b/src/app/tests/suites/certification/Test_TC_ICDM_1_1.yaml deleted file mode 100755 index fb507fd7a89663..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_ICDM_1_1.yaml +++ /dev/null @@ -1,223 +0,0 @@ -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -name: 312.1.1. [TC-ICDM-1.1] Global attributes with DUT as Server - -PICS: - - ICDM.S - -config: - nodeId: 0x12344321 - cluster: "ICD Management" - endpoint: 0 - -tests: - - label: "Step 1: Wait for the commissioned device to be retrieved" - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: TH reads ClusterRevision attribute from DUT" - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 3 - constraints: - type: int16u - - - label: "Step 3: TH reads FeatureMap attribute from DUT" - PICS: " !ICDM.S.F00 && !ICDM.S.F01 && !ICDM.S.F02 " - command: "readAttribute" - attribute: "FeatureMap" - response: - value: 0 - constraints: - type: bitmap32 - - - label: - "Step 3: TH reads FeatureMap attribute from DUT, bit 0 is set to 1 if - ICDM.S.F00(UAT) is true," - PICS: ICDM.S.F00 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - hasMasksSet: [0x1] - type: bitmap32 - - - label: - "Step 3: TH reads FeatureMap attribute from DUT, bit 1 is set to 1 if - ICDM.S.F01(CIP) is true" - PICS: ICDM.S.F01 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - hasMasksSet: [0x2] - type: bitmap32 - - - label: - "Step 3: TH reads FeatureMap attribute from DUT, bit 2 is set to 1 if - ICDM.S.F02(UAT) is true," - PICS: ICDM.S.F02 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - hasMasksSet: [0x4] - type: bitmap32 - - - label: "Step 4a: TH reads AttributeList attribute from DUT" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 1, 2, 65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 4a: TH reads AttributeList attribute from DUT" - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 1, 2, 65528, 65529, 65531, 65532, 65533] - - - label: - "Step 4b: Read the optional attribute(RegisteredClients) in - AttributeList" - PICS: ICDM.S.A0003 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [3] - - - label: "Step 4c: Read the optional attribute(IcdCounter) in AttributeList" - PICS: ICDM.S.A0004 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [4] - - - label: - "Step 4d: Read the optional attribute(ClientsSupportedPerFabric) in - AttributeList" - PICS: ICDM.S.A0005 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [5] - - - label: - "Step 4d: Read the optional attribute(UserActiveModeTriggerHint) in - AttributeList" - PICS: ICDM.S.A0006 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [6] - - - label: - "Step 4d: Read the optional - attribute(UserActiveModeTriggerInstruction) in AttributeList" - PICS: ICDM.S.A0007 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [7] - - - label: "Step 5: Read the global attribute: EventList" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - value: [] - constraints: - type: list - - - label: "Step 6a: TH reads AcceptedCommandList attribute from DUT" - PICS: " !ICDM.S.F00 && !ICDM.S.C03.Rsp " - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - value: [] - constraints: - type: list - - - label: - "Step 6b: TH reads AcceptedCommandList attribute from DUT if - ICDM.S.F00 is true" - PICS: ICDM.S.F00 - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [0, 2] - - - label: - "Step 6c: Read the optional command (StayActiveRequest) in - AttributeList" - PICS: ICDM.S.C03.Rsp - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [3] - - - label: "Step 7: TH reads GeneratedCommandList attribute from DUT" - PICS: " !ICDM.S.F00 " - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - value: [] - constraints: - type: list - - - label: "Step 7: TH reads GeneratedCommandList attribute from DUT" - PICS: ICDM.S.F00 - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - constraints: - type: list - contains: [1] - - - label: - "Step 7: TH reads GeneratedCommandList attribute from DUT. The list - MAY include these optional entries: 0x04: SHALL be included if and - only if ICDM.S.C04.Tx(StayActiveResponse) " - PICS: ICDM.S.C04.Tx - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - constraints: - type: list - contains: [4] diff --git a/src/app/tests/suites/certification/Test_TC_LTIME_1_2.yaml b/src/app/tests/suites/certification/Test_TC_LTIME_1_2.yaml deleted file mode 100644 index cb10e8a1d116f2..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_LTIME_1_2.yaml +++ /dev/null @@ -1,116 +0,0 @@ -# Copyright (c) 2021 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -name: 108.1.2. [TC-LTIME-1.2] Global Attributes with DUT as Server - -PICS: - - LTIME.S - -config: - nodeId: 0x12344321 - cluster: "Time Format Localization" - endpoint: 0 - -tests: - - label: - "Step 1: Commission DUT to TH (can be skipped if done in a preceding - test)." - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: TH reads from the DUT the ClusterRevision attribute." - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 1 - constraints: - type: int16u - - - label: "Step 3: TH reads from the DUT the FeatureMap attribute." - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - minValue: 0 - maxValue: 1 - - - label: "Step 4a: TH reads from the DUT the AttributeList attribute." - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 4a: TH reads from the DUT the AttributeList attribute." - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 65528, 65529, 65531, 65532, 65533] - - - label: - "Step 4b: TH reads Feature dependent attribute(ActiveCalendarType) in - AttributeList from DUT" - PICS: LTIME.S.F00 && LTIME.S.A0001 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [1] - - - label: - "Step 4c: TH reads Feature dependent attribute(SupportedCalendarTypes) - in AttributeList from DUT" - PICS: LTIME.S.F00 && LTIME.S.A0002 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [2] - - - label: "Step 5: TH reads from the DUT the EventList attribute." - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - value: [] - constraints: - type: list - - - label: "Step 6: TH reads from the DUT the AcceptedCommandList attribute." - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - value: [] - constraints: - type: list - - - label: "Step 7: TH reads from the DUT the GeneratedCommandList attribute." - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - value: [] - constraints: - type: list diff --git a/src/app/tests/suites/certification/Test_TC_MWOCTRL_1_1.yaml b/src/app/tests/suites/certification/Test_TC_MWOCTRL_1_1.yaml deleted file mode 100644 index d06db8ae77d741..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_MWOCTRL_1_1.yaml +++ /dev/null @@ -1,170 +0,0 @@ -# Copyright (c) 2024 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -name: 263.1.1. [TC-MWOCTRL-1.1] Global attributes with DUT as Server - -PICS: - - MWOCTRL.S - -config: - nodeId: 0x12344321 - cluster: "Microwave Oven Control" - endpoint: 1 - -tests: - - label: "Step 1: Wait for the commissioned device to be retrieved" - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: Read the global attribute: ClusterRevision" - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 1 - constraints: - type: int16u - - - label: "Step 3a: Check for no features selected." - command: "readAttribute" - attribute: "FeatureMap" - PICS: "!MWOCTRL.S.F00 && !MWOCTRL.S.F01 && !MWOCTRL.S.F02" - response: - value: 0 - constraints: - type: bitmap32 - - - label: "Step 3b: Check for PWRNUM feature support" - command: "readAttribute" - attribute: "FeatureMap" - PICS: MWOCTRL.S.F00 - response: - saveAs: powerNumSupported - constraints: - type: bitmap32 - hasMasksSet: [0x1] - hasMasksClear: [0x2] - - - label: "Step 3c: Check for WATTS feature support" - command: "readAttribute" - attribute: "FeatureMap" - PICS: MWOCTRL.S.F01 - response: - saveAs: wattsSupported - constraints: - type: bitmap32 - hasMasksClear: [0x1, 0x4] - hasMasksSet: [0x2] - - - label: "Step 3d: Check for PWRLMTS feature support" - command: "readAttribute" - attribute: "FeatureMap" - PICS: MWOCTRL.S.F02 - response: - saveAs: wattsSupported - constraints: - type: bitmap32 - hasMasksSet: [0x1, 0x4] - hasMasksClear: [0x2] - - - label: "Step 4a: Read the global attribute: AttributeList" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 1, 65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 4b: Read the global attribute: AttributeList" - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 1, 65528, 65529, 65531, 65532, 65533] - - - label: "Step 4c: Check for mandatory attribute support for PWRNUM feature" - PICS: MWOCTRL.S.F00 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [2] - - - label: "Step 4d: Check for optional attribute support for PWRNUM feature" - PICS: MWOCTRL.S.F02 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [3, 4, 5] - - - label: "Step 4e: Check for mandatory attribute support for WATTS feaure" - PICS: MWOCTRL.S.F01 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [6, 7] - - - label: "Step 4f: Check for optional WattRating attribute support" - PICS: MWOCTRL.S.A0008 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [8] - - - label: "Step 5: TH reads EventList attribute from DUT" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - value: [] - constraints: - type: list - - - label: "Step 6a: Check for mandatory commands." - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [0] - - - label: "Step 6b: Check for optional command AddMoreTime." - PICS: MWOCTRL.S.C01.Rsp - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [1] - - - label: "Step 7: TH reads from the DUT the GeneratedCommandList attribute." - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - constraints: - type: list - contains: [] diff --git a/src/app/tests/suites/certification/Test_TC_NDOCONC_1_1.yaml b/src/app/tests/suites/certification/Test_TC_NDOCONC_1_1.yaml deleted file mode 100644 index a28dae650950a7..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_NDOCONC_1_1.yaml +++ /dev/null @@ -1,339 +0,0 @@ -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -name: 145.1.1. [TC-NDOCONC-1.1] Global Attributes with DUT as Server - -PICS: - - NDOCONC.S - -config: - nodeId: 0x12344321 - cluster: "Nitrogen Dioxide Concentration Measurement" - endpoint: 1 - -tests: - - label: - "Step 1: Commission DUT to TH (can be skipped if done in a preceding - test)." - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: TH reads from the DUT the ClusterRevision attribute." - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 3 - constraints: - type: int16u - - - label: - "Step 3a: TH reads from the DUT the FeatureMap attribute. and check - for either bit 0 or 1 set" - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x03] - - - label: - "Step 3b: Given NDOCONC.S.F00(MEA) ensure featuremap has the correct - bit set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: NDOCONC.S.F00 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x1] - - - label: - "Step 3c: Given NDOCONC.S.F00(MEA) is not set, ensure featuremap has - the correct bit clear" - command: "readAttribute" - attribute: "FeatureMap" - PICS: " !NDOCONC.S.F00 " - response: - constraints: - type: bitmap32 - hasMasksClear: [0x1] - - - label: - "Step 3d: Given NDOCONC.S.F01(LEV) ensure featuremap has the correct - bit set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: NDOCONC.S.F01 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x2] - - - label: - "Step 3e: Given NDOCONC.S.F01(LEV) is not set, ensure featuremap has - the correct bit clear" - command: "readAttribute" - attribute: "FeatureMap" - PICS: " !NDOCONC.S.F01 " - response: - constraints: - type: bitmap32 - hasMasksClear: [0x2] - - - label: - "Step 3f: Given NDOCONC.S.F02(MED) ensure featuremap has the correct - bit set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: NDOCONC.S.F02 && NDOCONC.S.F01 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x4, 0x2] - - - label: - "Step 3g: Given NDOCONC.S.F02(MED) is not set, ensure featuremap has - the correct bit clear" - command: "readAttribute" - attribute: "FeatureMap" - PICS: " !NDOCONC.S.F02 && !NDOCONC.S.F01 " - response: - constraints: - type: bitmap32 - hasMasksClear: [0x4] - - - label: - "Step 3h: Given NDOCONC.S.F03(CRI) ensure featuremap has the correct - bits set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: NDOCONC.S.F03 && NDOCONC.S.F01 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x8, 0x2] - - - label: - "Step 3i: Given NDOCONC.S.F03(CRI) is not set, ensure featuremap has - the correct bit clear" - command: "readAttribute" - attribute: "FeatureMap" - PICS: " !NDOCONC.S.F03 && !NDOCONC.S.F01 " - response: - constraints: - type: bitmap32 - hasMasksClear: [0x8] - - - label: - "Step 3j: Given NDOCONC.S.F04(PEA) ensure featuremap has the correct - bits set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: NDOCONC.S.F04 && NDOCONC.S.F00 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x10, 0x1] - - - label: - "Step 3k: Given NDOCONC.S.F04(PEA) is not set, ensure featuremap has - the correct bit clear" - command: "readAttribute" - attribute: "FeatureMap" - PICS: " !NDOCONC.S.F04 && NDOCONC.S.F00 " - response: - constraints: - type: bitmap32 - hasMasksClear: [0x10] - - - label: - "Step 3l: Given NDOCONC.S.F05(AVG) ensure featuremap has the correct - bits set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: NDOCONC.S.F05 && NDOCONC.S.F00 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x20, 0x1] - - - label: - "Step 3m: Given NDOCONC.S.F05(AVG) is not set, ensure featuremap has - the correct bit clear" - command: "readAttribute" - attribute: "FeatureMap" - PICS: " !NDOCONC.S.F05 && !NDOCONC.S.F00" - response: - constraints: - type: bitmap32 - hasMasksClear: [0x20] - - - label: "Step 4a: TH reads from the DUT the AttributeList attribute." - command: "readAttribute" - attribute: "AttributeList" - PICS: PICS_EVENT_LIST_ENABLED - response: - constraints: - type: list - contains: [9, 65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 4a: TH reads from the DUT the AttributeList attribute." - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [9, 65528, 65529, 65531, 65532, 65533] - - - label: - "Step 4b: TH reads the optional attribute Uncertainty in AttributeList" - command: "readAttribute" - attribute: "AttributeList" - PICS: NDOCONC.S.A0007 && NDOCONC.S.F00 - response: - constraints: - type: list - contains: [7] - - - label: - "Step 4c: Check the optional attribute Uncertainty is excluded from - AttributeList when NDOCONC.S.A0007 is not set" - command: "readAttribute" - attribute: "AttributeList" - PICS: " !NDOCONC.S.A0007 " - response: - constraints: - type: list - excludes: [7] - - - label: - "Step 4d: TH reads the optional, feature dependent attributes - MeasuredValue, MinMeasuredValue, MaxMeasuredValue and Measurement Unit - in AttributeList" - command: "readAttribute" - attribute: "AttributeList" - PICS: NDOCONC.S.F00 - response: - constraints: - type: list - contains: [0, 1, 2, 8] - - - label: - "Step 4e: Check that MeasuredValue, MinMeasuredValue, - MaxMeasuredValue, Measurement Unit and Uncertainty are excluded from - AttributeList when NDOCONC.S.F00 (MEA) is not set" - command: "readAttribute" - attribute: "AttributeList" - PICS: " !NDOCONC.S.F00 " - response: - constraints: - type: list - excludes: [0, 1, 2, 7, 8] - - - label: - "Step 4f: TH reads the optional, feature dependent attributes - PeakMeasuredValue & PeakMeasuredValueWindow in AttributeList" - command: "readAttribute" - attribute: "AttributeList" - PICS: NDOCONC.S.F04 - response: - constraints: - type: list - contains: [3, 4] - - - label: - "Step 4g: Check that PeakMeasuredValue & PeakMeasuredValueWindow are - excluded from AttributeList when NDOCONC.S.F04 (PEA) is not set" - command: "readAttribute" - attribute: "AttributeList" - PICS: " !NDOCONC.S.F04 " - response: - constraints: - type: list - excludes: [3, 4] - - - label: - "Step 4h: TH reads the optional, feature dependent attributes - AverageMeasuredValue AverageMeasuredValueWindow in AttributeList" - command: "readAttribute" - attribute: "AttributeList" - PICS: NDOCONC.S.F05 - response: - constraints: - type: list - contains: [5, 6] - - - label: - "Step 4i: TH reads that AverageMeasuredValue and - AverageMeasuredValueWindow are excluded from AttributeList when - NDOCONC.S.F05 (AVG) is not set" - command: "readAttribute" - attribute: "AttributeList" - PICS: " !NDOCONC.S.F05 " - response: - constraints: - type: list - excludes: [5, 6] - - - label: - "Step 4j: TH reads the optional, feature dependent attribute - LevelValue in AttributeList" - command: "readAttribute" - attribute: "AttributeList" - PICS: NDOCONC.S.F01 - response: - constraints: - type: list - contains: [10] - - - label: - "Step 4k: Check that LevelValue is excluded from AttributeList when - NDOCONC.S.F01 (LEV) is not set" - command: "readAttribute" - attribute: "AttributeList" - PICS: " !NDOCONC.S.F01 " - response: - constraints: - type: list - excludes: [10] - - - label: "Step 5: TH reads from the DUT the EventList attribute." - command: "readAttribute" - attribute: "EventList" - PICS: PICS_EVENT_LIST_ENABLED - response: - value: [] - constraints: - type: list - - - label: "Step 6: TH reads from the DUT the AcceptedCommandList attribute." - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - value: [] - constraints: - type: list - - - label: "Step 7: TH reads from the DUT the GeneratedCommandList attribute." - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - value: [] - constraints: - type: list diff --git a/src/app/tests/suites/certification/Test_TC_OZCONC_1_1.yaml b/src/app/tests/suites/certification/Test_TC_OZCONC_1_1.yaml deleted file mode 100644 index 25b6e3af2d0d57..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_OZCONC_1_1.yaml +++ /dev/null @@ -1,339 +0,0 @@ -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -name: 145.1.1. [TC-OZCONC-1.1] Global Attributes with DUT as Server - -PICS: - - OZCONC.S - -config: - nodeId: 0x12344321 - cluster: "Ozone Concentration Measurement" - endpoint: 1 - -tests: - - label: - "Step 1: Commission DUT to TH (can be skipped if done in a preceding - test)." - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: TH reads from the DUT the ClusterRevision attribute." - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 3 - constraints: - type: int16u - - - label: - "Step 3a: TH reads from the DUT the FeatureMap attribute and check for - either bit 0 or 1 set" - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x03] - - - label: - "Step 3b: Given OZCONC.S.F00(MEA) ensure featuremap has the correct - bit set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: OZCONC.S.F00 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x1] - - - label: - "Step 3c: Given OZCONC.S.F00(MEA) is not set, ensure featuremap has - the correct bit clear" - command: "readAttribute" - attribute: "FeatureMap" - PICS: " !OZCONC.S.F00 " - response: - constraints: - type: bitmap32 - hasMasksClear: [0x1] - - - label: - "Step 3d: Given OZCONC.S.F01(LEV) ensure featuremap has the correct - bit set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: OZCONC.S.F01 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x2] - - - label: - "Step 3e: Given OZCONC.S.F01(LEV) is not set, ensure featuremap has - the correct bit clear" - command: "readAttribute" - attribute: "FeatureMap" - PICS: " !OZCONC.S.F01 " - response: - constraints: - type: bitmap32 - hasMasksClear: [0x2] - - - label: - "Step 3f: Given OZCONC.S.F02(MED) ensure featuremap has the correct - bit set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: OZCONC.S.F02 && OZCONC.S.F01 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x4, 0x2] - - - label: - "Step 3g: Given OZCONC.S.F02(MED) is not set, ensure featuremap has - the correct bit clear" - command: "readAttribute" - attribute: "FeatureMap" - PICS: " !OZCONC.S.F02 && !OZCONC.S.F01" - response: - constraints: - type: bitmap32 - hasMasksClear: [0x4] - - - label: - "Step 3h: Given OZCONC.S.F03(CRI) ensure featuremap has the correct - bits set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: OZCONC.S.F03 && OZCONC.S.F01 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x8, 0x2] - - - label: - "Step 3i: Given OZCONC.S.F03(CRI) is not set, ensure featuremap has - the correct bit clear" - command: "readAttribute" - attribute: "FeatureMap" - PICS: " !OZCONC.S.F03 && !OZCONC.S.F01 " - response: - constraints: - type: bitmap32 - hasMasksClear: [0x8] - - - label: - "Step 3j: Given OZCONC.S.F04(PEA) ensure featuremap has the correct - bits set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: OZCONC.S.F04 && OZCONC.S.F00 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x10, 0x1] - - - label: - "Step 3k: Given OZCONC.S.F04(PEA) is not set, ensure featuremap has - the correct bit clear" - command: "readAttribute" - attribute: "FeatureMap" - PICS: " !OZCONC.S.F04 && !OZCONC.S.F00" - response: - constraints: - type: bitmap32 - hasMasksClear: [0x10] - - - label: - "Step 3l: Given OZCONC.S.F05(AVG) ensure featuremap has the correct - bits set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: OZCONC.S.F05 && OZCONC.S.F00 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x20, 0x1] - - - label: - "Step 3m: Given OZCONC.S.F05(AVG) is not set, ensure featuremap has - the correct bit clear" - command: "readAttribute" - attribute: "FeatureMap" - PICS: " !OZCONC.S.F05 && !OZCONC.S.F00 " - response: - constraints: - type: bitmap32 - hasMasksClear: [0x20] - - - label: "Step 4a: TH reads from the DUT the AttributeList attribute." - command: "readAttribute" - attribute: "AttributeList" - PICS: PICS_EVENT_LIST_ENABLED - response: - constraints: - type: list - contains: [9, 65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 4a: TH reads from the DUT the AttributeList attribute." - command: "readAttribute" - attribute: "AttributeList" - PICS: "!PICS_EVENT_LIST_ENABLED" - response: - constraints: - type: list - contains: [9, 65528, 65529, 65531, 65532, 65533] - - - label: - "Step 4b: TH reads the optional attribute Uncertainty in AttributeList" - command: "readAttribute" - attribute: "AttributeList" - PICS: OZCONC.S.A0007 && OZCONC.S.F00 - response: - constraints: - type: list - contains: [7] - - - label: - "Step 4c: Check the optional attribute Uncertainty is excluded from - AttributeList when OZCONC.S.A0007 is not set" - command: "readAttribute" - attribute: "AttributeList" - PICS: " !OZCONC.S.A0007 " - response: - constraints: - type: list - excludes: [7] - - - label: - "Step 4d: TH reads the optional, feature dependent attributes - MeasuredValue, MinMeasuredValue, MaxMeasuredValue and Measurement Unit - in AttributeList" - command: "readAttribute" - attribute: "AttributeList" - PICS: OZCONC.S.F00 - response: - constraints: - type: list - contains: [0, 1, 2, 8] - - - label: - "Step 4e: Check that MeasuredValue, MinMeasuredValue, - MaxMeasuredValue, Measurement Unit and Uncertainty are excluded from - AttributeList when OZCONC.S.F00 (MEA) is not set" - command: "readAttribute" - attribute: "AttributeList" - PICS: " !OZCONC.S.F00 " - response: - constraints: - type: list - excludes: [0, 1, 2, 7, 8] - - - label: - "Step 4f: TH reads the optional, feature dependent attributes - PeakMeasuredValue & PeakMeasuredValueWindow in AttributeList" - command: "readAttribute" - attribute: "AttributeList" - PICS: OZCONC.S.F04 - response: - constraints: - type: list - contains: [3, 4] - - - label: - "Step 4g: Check that PeakMeasuredValue & PeakMeasuredValueWindow are - excluded from AttributeList when OZCONC.S.F04 (PEA) is not set" - command: "readAttribute" - attribute: "AttributeList" - PICS: " !OZCONC.S.F04 " - response: - constraints: - type: list - excludes: [3, 4] - - - label: - "Step 4h: TH reads the optional, feature dependent attributes - AverageMeasuredValue AverageMeasuredValueWindow in AttributeList" - command: "readAttribute" - attribute: "AttributeList" - PICS: OZCONC.S.F05 - response: - constraints: - type: list - contains: [5, 6] - - - label: - "Step 4i: Check that AverageMeasuredValue and - AverageMeasuredValueWindow are excluded from AttributeList when - OZCONC.S.F05 (AVG) is not set" - command: "readAttribute" - attribute: "AttributeList" - PICS: " !OZCONC.S.F05 " - response: - constraints: - type: list - excludes: [5, 6] - - - label: - "Step 4j: TH reads the optional, feature dependent attribute - LevelValue in AttributeList" - command: "readAttribute" - attribute: "AttributeList" - PICS: OZCONC.S.F01 - response: - constraints: - type: list - contains: [10] - - - label: - "Step 4k: Check that LevelValue is excluded from AttributeList when - OZCONC.S.F01 (LEV) is not set" - command: "readAttribute" - attribute: "AttributeList" - PICS: " !OZCONC.S.F01 " - response: - constraints: - type: list - excludes: [10] - - - label: "Step 5: TH reads from the DUT the EventList attribute." - command: "readAttribute" - attribute: "EventList" - PICS: PICS_EVENT_LIST_ENABLED - response: - value: [] - constraints: - type: list - - - label: "Step 6: TH reads from the DUT the AcceptedCommandList attribute." - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - value: [] - constraints: - type: list - - - label: "Step 7: TH reads from the DUT the GeneratedCommandList attribute." - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - value: [] - constraints: - type: list diff --git a/src/app/tests/suites/certification/Test_TC_PCC_1_1.yaml b/src/app/tests/suites/certification/Test_TC_PCC_1_1.yaml deleted file mode 100644 index d6f59700109714..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_PCC_1_1.yaml +++ /dev/null @@ -1,555 +0,0 @@ -# Copyright (c) 2021 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -name: 15.1.1. [TC-PCC-1.1] Global attributes with server as DUT - -PICS: - - PCC.S - -config: - nodeId: 0x12344321 - cluster: "Pump Configuration and Control" - endpoint: 1 - -tests: - - label: "Step 1: Wait for the commissioned device to be retrieved" - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: TH reads the ClusterRevision attribute from the DUT" - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 4 - constraints: - type: int16u - - - label: "Step 3a: TH reads the FeatureMap attribute from the DUT" - PICS: - " !PCC.S.F00 && !PCC.S.F01 && !PCC.S.F02 && !PCC.S.F03 && !PCC.S.F04 - && !PCC.S.F05 && !PCC.S.F06 " - command: "readAttribute" - attribute: "FeatureMap" - response: - value: 0 - constraints: - type: bitmap32 - - - label: - "Step 3b: Given PCC.S.F00(PRSCONST) ensure featuremap has the correct - bit set" - PICS: PCC.S.F00 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x1] - - - label: - "Step 3c: Given PCC.S.F01(PRSCOMP) ensure featuremap has the correct - bit set" - PICS: PCC.S.F01 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x2] - - - label: - "Step 3d: Given PCC.S.F02(FLW) ensure featuremap has the correct bit - set" - PICS: PCC.S.F02 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x4] - - - label: - "Step 3e: Given PCC.S.F03(SPD) ensure featuremap has the correct bit - set" - PICS: PCC.S.F03 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x8] - - - label: - "Step 3f: Given PCC.S.F04(TEMP) ensure featuremap has the correct bit - set" - PICS: PCC.S.F04 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x10] - - - label: - "Step 3g: Given PCC.S.F05(AUTO) ensure featuremap has the correct bit - set" - PICS: PCC.S.F05 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x20] - - - label: - "Step 3h: Given PCC.S.F06(LOCAL) ensure featuremap has the correct bit - set" - PICS: PCC.S.F06 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x40] - - - label: "Step 4a: TH reads the AttributeList attribute from the DUT" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: - [ - 0, - 1, - 2, - 17, - 18, - 19, - 32, - 65528, - 65529, - 65530, - 65531, - 65532, - 65533, - ] - - - label: "Step 4a: TH reads the AttributeList attribute from the DUT" - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: - [0, 1, 2, 17, 18, 19, 32, 65528, 65529, 65531, 65532, 65533] - - - label: - "Step 4b: TH reads optional attribute(MinConstPressure) attribute in - AttributeList from the DUT" - PICS: PCC.S.A0003 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [3] - - - label: - "Step 4c TH reads optional attribute(MaxConstPressure) attribute in - AttributeList from the DUT" - PICS: PCC.S.A0004 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [4] - - - label: - "Step 4d: TH reads optional attribute(MinCompPressure) attribute in - AttributeList from the DUT" - PICS: PCC.S.A0005 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [5] - - - label: - "Step 4e: TH reads optional attribute(MaxCompPressure) attribute in - AttributeList from the DUT" - PICS: PCC.S.A0006 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [6] - - - label: - "Step 4f: TH reads optional attribute(MinConstSpeed) attribute in - AttributeList from the DUT" - PICS: PCC.S.A0007 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [7] - - - label: - "Step 4g: TH reads optional attribute(MaxConstSpeed) attribute in - AttributeList from the DUT" - PICS: PCC.S.A0008 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [8] - - - label: - "Step 4h: TH reads optional attribute(MinConstFlow) attribute in - AttributeList from the DUT" - PICS: PCC.S.A0009 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [9] - - - label: - "Step 4i: TH reads optional attribute(MaxConstFlow) attribute in - AttributeList from the DUT" - PICS: PCC.S.A000a - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [10] - - - label: - "Step 4j: TH reads optional attribute(MinConstTemp) attribute in - AttributeList from the DUT" - PICS: PCC.S.A000b - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [11] - - - label: - "Step 4k: TH reads optional attribute(MaxConstTemp) attribute in - AttributeList from the DUT" - PICS: PCC.S.A000c - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [12] - - - label: - "Step 4l: TH reads optional attribute(PumpStatus) attribute in - AttributeList from the DUT" - PICS: PCC.S.A0010 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [16] - - - label: - "Step 4m: TH reads optional attribute(Speed) attribute in - AttributeList from the DUT" - PICS: PCC.S.A0014 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [20] - - - label: - "Step 4n: TH reads optional attribute(LifetimeRunningHours) attribute - in AttributeList from the DUT" - PICS: PCC.S.A0015 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [21] - - - label: - "Step 4o: TH reads optional attribute(Power) attribute in - AttributeList from the DUT" - PICS: PCC.S.A0016 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [22] - - - label: - "Step 4p: TH reads optional attribute(LifetimeEnergyConsumed) - attribute in AttributeList from the DUT" - PICS: PCC.S.A0017 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [23] - - - label: - "Step 4q: TH reads optional attribute(ControlMode) attribute in - AttributeList from the DUT" - PICS: PCC.S.A0021 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [33] - - - label: "Step 5a: TH reads EventList from DUT" - PICS: - "PICS_EVENT_LIST_ENABLED && !PCC.S.E00 && !PCC.S.E01 && !PCC.S.E02 && - !PCC.S.E03 && !PCC.S.E04 && !PCC.S.E05 && !PCC.S.E06 && !PCC.S.E07 && - !PCC.S.E08 && !PCC.S.E09 && !PCC.S.E0a && !PCC.S.E0b && !PCC.S.E0c && - !PCC.S.E0d && !PCC.S.E0e && !PCC.S.E0f && !PCC.S.E10 " - command: "readAttribute" - attribute: "EventList" - response: - value: [] - constraints: - type: list - - - label: - "Step 5b: TH reads from the DUT the EventList optional - (SupplyVoltageLow)attribute." - PICS: PICS_EVENT_LIST_ENABLED && PCC.S.E00 - command: "readAttribute" - attribute: "EventList" - response: - constraints: - type: list - contains: [0x00] - - - label: - "Step 5c: TH reads from the DUT the EventList optional - (SupplyVoltageHigh)attribute." - PICS: PICS_EVENT_LIST_ENABLED && PCC.S.E01 - command: "readAttribute" - attribute: "EventList" - response: - constraints: - type: list - contains: [0x01] - - - label: - "Step 5d: TH reads from the DUT the EventList optional - (PowerMissingPhase)attribute." - PICS: PICS_EVENT_LIST_ENABLED && PCC.S.E02 - command: "readAttribute" - attribute: "EventList" - response: - constraints: - type: list - contains: [0x02] - - - label: - "Step 5e: TH reads from the DUT the EventList optional - (SystemPressureLow)attribute." - PICS: PICS_EVENT_LIST_ENABLED && PCC.S.E03 - command: "readAttribute" - attribute: "EventList" - response: - constraints: - type: list - contains: [0x03] - - - label: - "Step 5f: TH reads from the DUT the EventList optional - (SystemPressureHigh)attribute." - PICS: PICS_EVENT_LIST_ENABLED && PCC.S.E04 - command: "readAttribute" - attribute: "EventList" - response: - constraints: - type: list - contains: [0x04] - - - label: - "Step 5g: TH reads from the DUT the EventList optional - (DryRunning)attribute." - PICS: PICS_EVENT_LIST_ENABLED && PCC.S.E05 - command: "readAttribute" - attribute: "EventList" - response: - constraints: - type: list - contains: [0x05] - - - label: - "Step 5h: TH reads from the DUT the EventList optional - (MotorTemperatureHigh)attribute." - PICS: PICS_EVENT_LIST_ENABLED && PCC.S.E06 - command: "readAttribute" - attribute: "EventList" - response: - constraints: - type: list - contains: [0x06] - - - label: - "Step 5i: TH reads from the DUT the EventList optional - (PumpMotorFatalFailure)attribute." - PICS: PICS_EVENT_LIST_ENABLED && PCC.S.E07 - command: "readAttribute" - attribute: "EventList" - response: - constraints: - type: list - contains: [0x07] - - - label: - "Step 5j: TH reads from the DUT the EventList optional - (ElectronicTemperatureHigh)attribute." - PICS: PICS_EVENT_LIST_ENABLED && PCC.S.E08 - command: "readAttribute" - attribute: "EventList" - response: - constraints: - type: list - contains: [0x08] - - - label: - "Step 5k: TH reads from the DUT the EventList optional - (PumpBlocked)attribute." - PICS: PICS_EVENT_LIST_ENABLED && PCC.S.E09 - command: "readAttribute" - attribute: "EventList" - response: - constraints: - type: list - contains: [0x09] - - - label: - "Step 5l: TH reads from the DUT the EventList optional - (SensorFailure)attribute." - PICS: PICS_EVENT_LIST_ENABLED && PCC.S.E0a - command: "readAttribute" - attribute: "EventList" - response: - constraints: - type: list - contains: [0x0a] - - - label: - "Step 5m: TH reads from the DUT the EventList optional - (ElectronicNonFatalFailure)attribute." - PICS: PICS_EVENT_LIST_ENABLED && PCC.S.E0b - command: "readAttribute" - attribute: "EventList" - response: - constraints: - type: list - contains: [0x0b] - - - label: - "Step 5n: TH reads from the DUT the EventList optional - (ElectronicFatalFailure)attribute." - PICS: PICS_EVENT_LIST_ENABLED && PCC.S.E0c - command: "readAttribute" - attribute: "EventList" - response: - constraints: - type: list - contains: [0x0c] - - - label: - "Step 5o: TH reads from the DUT the EventList optional - (GeneralFault)attribute." - PICS: PICS_EVENT_LIST_ENABLED && PCC.S.E0d - command: "readAttribute" - attribute: "EventList" - response: - constraints: - type: list - contains: [0x0d] - - - label: - "Step 5p: TH reads from the DUT the EventList optional - (Leakage)attribute." - PICS: PICS_EVENT_LIST_ENABLED && PCC.S.E0e - command: "readAttribute" - attribute: "EventList" - response: - constraints: - type: list - contains: [0x0e] - - - label: - "Step 5q: TH reads from the DUT the EventList optional - (AirDetection)attribute." - PICS: PICS_EVENT_LIST_ENABLED && PCC.S.E0f - command: "readAttribute" - attribute: "EventList" - response: - constraints: - type: list - contains: [0x0f] - - - label: - "Step 5r: TH reads from the DUT the EventList optional - (TurbineOperation)attribute." - PICS: PICS_EVENT_LIST_ENABLED && PCC.S.E10 - command: "readAttribute" - attribute: "EventList" - response: - constraints: - type: list - contains: [0x10] - - - label: "Step 6: TH reads from the DUT the AcceptedCommandList attribute." - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - value: [] - constraints: - type: list - - - label: - "Step 7: TH reads from the DUT the GeneratedCommandList attribute." - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - value: [] - constraints: - type: list diff --git a/src/app/tests/suites/certification/Test_TC_PMHCONC_1_1.yaml b/src/app/tests/suites/certification/Test_TC_PMHCONC_1_1.yaml deleted file mode 100644 index 9bbd216e6b1271..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_PMHCONC_1_1.yaml +++ /dev/null @@ -1,336 +0,0 @@ -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -name: 145.1.1. [TC-PMHCONC-1.1] Global Attributes with DUT as Server - -PICS: - - PMHCONC.S - -config: - nodeId: 0x12344321 - cluster: "PM1 Concentration Measurement" - endpoint: 1 - -tests: - - label: "Step 1: Wait for the commissioned device to be retrieved" - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: Read the global attribute: ClusterRevision" - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 3 - constraints: - type: int16u - - - label: - "Step 3a: Read the global attribute: FeatureMap and check for either - bit 0 or 1 set" - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x03] - - - label: - "Step 3b: Given PMHCONC.S.F00(MEA) ensure featuremap has the correct - bit set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: PMHCONC.S.F00 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x1] - - - label: - "Step 3c: Given PMHCONC.S.F00(MEA) is not set, ensure featuremap has - the correct bit clear" - command: "readAttribute" - attribute: "FeatureMap" - PICS: " !PMHCONC.S.F00 " - response: - constraints: - type: bitmap32 - hasMasksClear: [0x1] - - - label: - "Step 3d: Given PMHCONC.S.F01(LEV) ensure featuremap has the correct - bit set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: PMHCONC.S.F01 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x2] - - - label: - "Step 3e: Given PMHCONC.S.F01(LEV) is not set, ensure featuremap has - the correct bit clear" - command: "readAttribute" - attribute: "FeatureMap" - PICS: " !PMHCONC.S.F01 " - response: - constraints: - type: bitmap32 - hasMasksClear: [0x2] - - - label: - "Step 3f: Given PMHCONC.S.F02(MED) ensure featuremap has the correct - bit set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: PMHCONC.S.F02 && PMHCONC.S.F01 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x4, 0x2] - - - label: - "Step 3g: Given PMHCONC.S.F02(MED) is not set, ensure featuremap has - the correct bit clear" - command: "readAttribute" - attribute: "FeatureMap" - PICS: " !PMHCONC.S.F02 && !PMHCONC.S.F01" - response: - constraints: - type: bitmap32 - hasMasksClear: [0x4] - - - label: - "Step 3h: Given PMHCONC.S.F03(CRI) ensure featuremap has the correct - bits set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: PMHCONC.S.F03 && PMHCONC.S.F01 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x8, 0x2] - - - label: - "Step 3i: Given PMHCONC.S.F03(CRI) is not set, ensure featuremap has - the correct bit clear" - command: "readAttribute" - attribute: "FeatureMap" - PICS: " !PMHCONC.S.F03 && !PMHCONC.S.F01 " - response: - constraints: - type: bitmap32 - hasMasksClear: [0x8] - - - label: - "Step 3j: Given PMHCONC.S.F04(PEA) ensure featuremap has the correct - bits set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: PMHCONC.S.F04 && PMHCONC.S.F00 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x10, 0x1] - - - label: - "Step 3k: Given PMHCONC.S.F04(PEA) is not set, ensure featuremap has - the correct bit clear" - command: "readAttribute" - attribute: "FeatureMap" - PICS: " !PMHCONC.S.F04 && PMHCONC.S.F00 " - response: - constraints: - type: bitmap32 - hasMasksClear: [0x10] - - - label: - "Step 3l: Given PMHCONC.S.F05(AVG) ensure featuremap has the correct - bits set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: PMHCONC.S.F05 && PMHCONC.S.F00 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x20, 0x1] - - - label: - "Step 3m: Given PMHCONC.S.F05(AVG) is not set, ensure featuremap has - the correct bit clear" - command: "readAttribute" - attribute: "FeatureMap" - PICS: " !PMHCONC.S.F05 && !PMHCONC.S.F00" - response: - constraints: - type: bitmap32 - hasMasksClear: [0x20] - - - label: "Step 4a: Read the global attribute: AttributeList" - command: "readAttribute" - attribute: "AttributeList" - PICS: PICS_EVENT_LIST_ENABLED - response: - constraints: - type: list - contains: [9, 65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 4a: Read the global attribute: AttributeList" - command: "readAttribute" - attribute: "AttributeList" - PICS: "!PICS_EVENT_LIST_ENABLED" - response: - constraints: - type: list - contains: [9, 65528, 65529, 65531, 65532, 65533] - - - label: "Step 4b: Read the optional attribute Uncertainty in AttributeList" - command: "readAttribute" - attribute: "AttributeList" - PICS: PMHCONC.S.A0007 && PMHCONC.S.F00 - response: - constraints: - type: list - contains: [7] - - - label: - "Step 4c: Check the optional attribute Uncertainty is excluded from - AttributeList when PMHCONC.S.A0007 is not set" - command: "readAttribute" - attribute: "AttributeList" - PICS: " !PMHCONC.S.A0007 " - response: - constraints: - type: list - excludes: [7] - - - label: - "Step 4d: Read the optional, feature dependent attributes - MeasuredValue, MinMeasuredValue, MaxMeasuredValue and Measurement Unit - in AttributeList" - command: "readAttribute" - attribute: "AttributeList" - PICS: PMHCONC.S.F00 - response: - constraints: - type: list - contains: [0, 1, 2, 8] - - - label: - "Step 4e: Check that MeasuredValue, MinMeasuredValue, - MaxMeasuredValue, Measurement Unit and Uncertainty are excluded from - AttributeList when PMHCONC.S.F00 (MEA) is not set" - command: "readAttribute" - attribute: "AttributeList" - PICS: " !PMHCONC.S.F00 " - response: - constraints: - type: list - excludes: [0, 1, 2, 7, 8] - - - label: - "Step 4f: Read the optional, feature dependent attributes - PeakMeasuredValue & PeakMeasuredValueWindow in AttributeList" - command: "readAttribute" - attribute: "AttributeList" - PICS: PMHCONC.S.F04 - response: - constraints: - type: list - contains: [3, 4] - - - label: - "Step 4g: Check that PeakMeasuredValue & PeakMeasuredValueWindow are - excluded from AttributeList when PMHCONC.S.F04 (PEA) is not set" - command: "readAttribute" - attribute: "AttributeList" - PICS: " !PMHCONC.S.F04 " - response: - constraints: - type: list - excludes: [3, 4] - - - label: - "Step 4h: Read the optional, feature dependent attributes - AverageMeasuredValue AverageMeasuredValueWindow in AttributeList" - command: "readAttribute" - attribute: "AttributeList" - PICS: PMHCONC.S.F05 - response: - constraints: - type: list - contains: [5, 6] - - - label: - "Step 4i: Check that AverageMeasuredValue and - AverageMeasuredValueWindow are excluded from AttributeList when - PMHCONC.S.F05 (AVG) is not set" - command: "readAttribute" - attribute: "AttributeList" - PICS: " !PMHCONC.S.F05 " - response: - constraints: - type: list - excludes: [5, 6] - - - label: - "Step 4j: Read the optional, feature dependent attribute LevelValue in - AttributeList" - command: "readAttribute" - attribute: "AttributeList" - PICS: PMHCONC.S.F01 - response: - constraints: - type: list - contains: [10] - - - label: - "Step 4k: Check that LevelValue is excluded from AttributeList when - PMHCONC.S.F01 (LEV) is not set" - command: "readAttribute" - attribute: "AttributeList" - PICS: " !PMHCONC.S.F01 " - response: - constraints: - type: list - excludes: [10] - - - label: "Step 5: Read the global attribute: EventList" - command: "readAttribute" - attribute: "EventList" - PICS: PICS_EVENT_LIST_ENABLED - response: - value: [] - constraints: - type: list - - - label: "Step 6: Read the global attribute: AcceptedCommandList" - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - value: [] - constraints: - type: list - - - label: "Step 7: Read the global attribute: GeneratedCommandList" - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - value: [] - constraints: - type: list diff --git a/src/app/tests/suites/certification/Test_TC_PMICONC_1_1.yaml b/src/app/tests/suites/certification/Test_TC_PMICONC_1_1.yaml deleted file mode 100644 index 57d14f10ca068e..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_PMICONC_1_1.yaml +++ /dev/null @@ -1,336 +0,0 @@ -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -name: 145.1.1. [TC-PMICONC-1.1] Global Attributes with DUT as Server - -PICS: - - PMICONC.S - -config: - nodeId: 0x12344321 - cluster: "PM2.5 Concentration Measurement" - endpoint: 1 - -tests: - - label: "Step 1: Wait for the commissioned device to be retrieved" - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: Read the global attribute: ClusterRevision" - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 3 - constraints: - type: int16u - - - label: - "Step 3a: Read the global attribute: FeatureMap and check for either - bit 0 or 1 set" - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x03] - - - label: - "Step 3b: Given PMICONC.S.F00(MEA) ensure featuremap has the correct - bit set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: PMICONC.S.F00 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x1] - - - label: - "Step 3c: Given PMICONC.S.F00(MEA) is not set, ensure featuremap has - the correct bit clear" - command: "readAttribute" - attribute: "FeatureMap" - PICS: " !PMICONC.S.F00 " - response: - constraints: - type: bitmap32 - hasMasksClear: [0x1] - - - label: - "Step 3d: Given PMICONC.S.F01(LEV) ensure featuremap has the correct - bit set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: PMICONC.S.F01 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x2] - - - label: - "Step 3e: Given PMICONC.S.F01(LEV) is not set, ensure featuremap has - the correct bit clear" - command: "readAttribute" - attribute: "FeatureMap" - PICS: " !PMICONC.S.F01 " - response: - constraints: - type: bitmap32 - hasMasksClear: [0x2] - - - label: - "Step 3f: Given PMICONC.S.F02(MED) ensure featuremap has the correct - bit set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: PMICONC.S.F02 && PMICONC.S.F01 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x4, 0x2] - - - label: - "Step 3g: Given PMICONC.S.F02(MED) is not set, ensure featuremap has - the correct bit clear" - command: "readAttribute" - attribute: "FeatureMap" - PICS: " !PMICONC.S.F02 && !PMICONC.S.F01" - response: - constraints: - type: bitmap32 - hasMasksClear: [0x4] - - - label: - "Step 3h: Given PMICONC.S.F03(CRI) ensure featuremap has the correct - bits set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: PMICONC.S.F03 && PMICONC.S.F01 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x8, 0x2] - - - label: - "Step 3i: Given PMICONC.S.F03(CRI) is not set, ensure featuremap has - the correct bit clear" - command: "readAttribute" - attribute: "FeatureMap" - PICS: " !PMICONC.S.F03 && !PMICONC.S.F01" - response: - constraints: - type: bitmap32 - hasMasksClear: [0x8] - - - label: - "Step 3j: Given PMICONC.S.F04(PEA) ensure featuremap has the correct - bits set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: PMICONC.S.F04 && PMICONC.S.F00 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x10, 0x1] - - - label: - "Step 3k: Given PMICONC.S.F04(PEA) is not set, ensure featuremap has - the correct bit clear" - command: "readAttribute" - attribute: "FeatureMap" - PICS: " !PMICONC.S.F04 && !PMICONC.S.F00 " - response: - constraints: - type: bitmap32 - hasMasksClear: [0x10] - - - label: - "Step 3l: Given PMICONC.S.F05(AVG) ensure featuremap has the correct - bits set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: PMICONC.S.F05 && PMICONC.S.F00 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x20, 0x1] - - - label: - "Step 3m: Given PMICONC.S.F05(AVG) is not set, ensure featuremap has - the correct bit clear" - command: "readAttribute" - attribute: "FeatureMap" - PICS: " !PMICONC.S.F05 && !PMICONC.S.F00" - response: - constraints: - type: bitmap32 - hasMasksClear: [0x20] - - - label: "Step 4a: Read the global attribute: AttributeList" - command: "readAttribute" - attribute: "AttributeList" - PICS: PICS_EVENT_LIST_ENABLED - response: - constraints: - type: list - contains: [9, 65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 4a: Read the global attribute: AttributeList" - command: "readAttribute" - attribute: "AttributeList" - PICS: "!PICS_EVENT_LIST_ENABLED" - response: - constraints: - type: list - contains: [9, 65528, 65529, 65531, 65532, 65533] - - - label: "Step 4b: Read the optional attribute Uncertainty in AttributeList" - command: "readAttribute" - attribute: "AttributeList" - PICS: PMICONC.S.A0007 && PMICONC.S.F00 - response: - constraints: - type: list - contains: [7] - - - label: - "Step 4c: Check the optional attribute Uncertainty is excluded from - AttributeList when PMICONC.S.A0007 is not set" - command: "readAttribute" - attribute: "AttributeList" - PICS: " !PMICONC.S.A0007 " - response: - constraints: - type: list - excludes: [7] - - - label: - "Step 4d: Read the optional, feature dependent attributes - MeasuredValue, MinMeasuredValue, MaxMeasuredValue and Measurement Unit - in AttributeList" - command: "readAttribute" - attribute: "AttributeList" - PICS: PMICONC.S.F00 - response: - constraints: - type: list - contains: [0, 1, 2, 8] - - - label: - "Step 4e: Check that MeasuredValue, MinMeasuredValue, - MaxMeasuredValue, Measurement Unit and Uncertainty are excluded from - AttributeList when PMICONC.S.F00 (MEA) is not set" - command: "readAttribute" - attribute: "AttributeList" - PICS: " !PMICONC.S.F00 " - response: - constraints: - type: list - excludes: [0, 1, 2, 7, 8] - - - label: - "Step 4f: Read the optional, feature dependent attributes - PeakMeasuredValue & PeakMeasuredValueWindow in AttributeList" - command: "readAttribute" - attribute: "AttributeList" - PICS: PMICONC.S.F04 - response: - constraints: - type: list - contains: [3, 4] - - - label: - "Step 4g: Check that PeakMeasuredValue & PeakMeasuredValueWindow are - excluded from AttributeList when PMICONC.S.F04 (PEA) is not set" - command: "readAttribute" - attribute: "AttributeList" - PICS: " !PMICONC.S.F04 " - response: - constraints: - type: list - excludes: [3, 4] - - - label: - "Step 4h: Read the optional, feature dependent attributes - AverageMeasuredValue AverageMeasuredValueWindow in AttributeList" - command: "readAttribute" - attribute: "AttributeList" - PICS: PMICONC.S.F05 - response: - constraints: - type: list - contains: [5, 6] - - - label: - "Step 4i: Check that AverageMeasuredValue and - AverageMeasuredValueWindow are excluded from AttributeList when - PMICONC.S.F05 (AVG) is not set" - command: "readAttribute" - attribute: "AttributeList" - PICS: " !PMICONC.S.F05 " - response: - constraints: - type: list - excludes: [5, 6] - - - label: - "Step 4j: Read the optional, feature dependent attribute LevelValue in - AttributeList" - command: "readAttribute" - attribute: "AttributeList" - PICS: PMICONC.S.F01 - response: - constraints: - type: list - contains: [10] - - - label: - "Step 4k: Check that LevelValue is excluded from AttributeList when - PMICONC.S.F01 (LEV) is not set" - command: "readAttribute" - attribute: "AttributeList" - PICS: " !PMICONC.S.F01 " - response: - constraints: - type: list - excludes: [10] - - - label: "Step 5: Read the global attribute: EventList" - command: "readAttribute" - attribute: "EventList" - PICS: PICS_EVENT_LIST_ENABLED - response: - value: [] - constraints: - type: list - - - label: "Step 6: Read the global attribute: AcceptedCommandList" - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - value: [] - constraints: - type: list - - - label: "Step 7: Read the global attribute: GeneratedCommandList" - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - value: [] - constraints: - type: list diff --git a/src/app/tests/suites/certification/Test_TC_PMKCONC_1_1.yaml b/src/app/tests/suites/certification/Test_TC_PMKCONC_1_1.yaml deleted file mode 100644 index 26c5797b17288d..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_PMKCONC_1_1.yaml +++ /dev/null @@ -1,336 +0,0 @@ -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -name: 145.1.1. [TC-PMKCONC-1.1] Global Attributes with DUT as Server - -PICS: - - PMKCONC.S - -config: - nodeId: 0x12344321 - cluster: "PM10 Concentration Measurement" - endpoint: 1 - -tests: - - label: "Step 1: Wait for the commissioned device to be retrieved" - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: Read the global attribute: ClusterRevision" - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 3 - constraints: - type: int16u - - - label: - "Step 3a: Read the global attribute: FeatureMap and check for either - bit 0 or 1 set" - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x03] - - - label: - "Step 3b: Given PMKCONC.S.F00(MEA) ensure featuremap has the correct - bit set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: PMKCONC.S.F00 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x1] - - - label: - "Step 3c: Given PMKCONC.S.F00(MEA) is not set, ensure featuremap has - the correct bit clear" - command: "readAttribute" - attribute: "FeatureMap" - PICS: " !PMKCONC.S.F00 " - response: - constraints: - type: bitmap32 - hasMasksClear: [0x1] - - - label: - "Step 3d: Given PMKCONC.S.F01(LEV) ensure featuremap has the correct - bit set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: PMKCONC.S.F01 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x2] - - - label: - "Step 3e: Given PMKCONC.S.F01(LEV) is not set, ensure featuremap has - the correct bit clear" - command: "readAttribute" - attribute: "FeatureMap" - PICS: " !PMKCONC.S.F01 " - response: - constraints: - type: bitmap32 - hasMasksClear: [0x2] - - - label: - "Step 3f: Given PMKCONC.S.F02(MED) ensure featuremap has the correct - bit set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: PMKCONC.S.F02 && PMKCONC.S.F01 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x4, 0x2] - - - label: - "Step 3g: Given PMKCONC.S.F02(MED) is not set, ensure featuremap has - the correct bit clear" - command: "readAttribute" - attribute: "FeatureMap" - PICS: " !PMKCONC.S.F02 && !PMKCONC.S.F01 " - response: - constraints: - type: bitmap32 - hasMasksClear: [0x4] - - - label: - "Step 3h: Given PMKCONC.S.F03(CRI) ensure featuremap has the correct - bits set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: PMKCONC.S.F03 && PMKCONC.S.F01 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x8, 0x2] - - - label: - "Step 3i: Given PMKCONC.S.F03(CRI) is not set, ensure featuremap has - the correct bit clear" - command: "readAttribute" - attribute: "FeatureMap" - PICS: " !PMKCONC.S.F03 && !PMKCONC.S.F01" - response: - constraints: - type: bitmap32 - hasMasksClear: [0x8] - - - label: - "Step 3j: Given PMKCONC.S.F04(PEA) ensure featuremap has the correct - bits set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: PMKCONC.S.F04 && PMKCONC.S.F00 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x10, 0x1] - - - label: - "Step 3k: Given PMKCONC.S.F04(PEA) is not set, ensure featuremap has - the correct bit clear" - command: "readAttribute" - attribute: "FeatureMap" - PICS: " !PMKCONC.S.F04 && !PMKCONC.S.F00 " - response: - constraints: - type: bitmap32 - hasMasksClear: [0x10] - - - label: - "Step 3l: Given PMKCONC.S.F05(AVG) ensure featuremap has the correct - bits set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: PMKCONC.S.F05 && PMKCONC.S.F00 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x20, 0x1] - - - label: - "Step 3m: Given PMKCONC.S.F05(AVG) is not set, ensure featuremap has - the correct bit clear" - command: "readAttribute" - attribute: "FeatureMap" - PICS: " !PMKCONC.S.F05 && !PMKCONC.S.F00" - response: - constraints: - type: bitmap32 - hasMasksClear: [0x20] - - - label: "Step 4a: Read the global attribute: AttributeList" - command: "readAttribute" - attribute: "AttributeList" - PICS: PICS_EVENT_LIST_ENABLED - response: - constraints: - type: list - contains: [9, 65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 4a: Read the global attribute: AttributeList" - command: "readAttribute" - attribute: "AttributeList" - PICS: "!PICS_EVENT_LIST_ENABLED" - response: - constraints: - type: list - contains: [9, 65528, 65529, 65531, 65532, 65533] - - - label: "Step 4b: Read the optional attribute Uncertainty in AttributeList" - command: "readAttribute" - attribute: "AttributeList" - PICS: PMKCONC.S.A0007 && PMKCONC.S.F00 - response: - constraints: - type: list - contains: [7] - - - label: - "Step 4c: Check the optional attribute Uncertainty is excluded from - AttributeList when PMKCONC.S.A0007 is not set" - command: "readAttribute" - attribute: "AttributeList" - PICS: " !PMKCONC.S.A0007 " - response: - constraints: - type: list - excludes: [7] - - - label: - "Step 4d: Read the optional, feature dependent attributes - MeasuredValue, MinMeasuredValue, MaxMeasuredValue and Measurement Unit - in AttributeList" - command: "readAttribute" - attribute: "AttributeList" - PICS: PMKCONC.S.F00 - response: - constraints: - type: list - contains: [0, 1, 2, 8] - - - label: - "Step 4e: Check that MeasuredValue, MinMeasuredValue, - MaxMeasuredValue, Measurement Unit and Uncertainty are excluded from - AttributeList when PMKCONC.S.F00 (MEA) is not set" - command: "readAttribute" - attribute: "AttributeList" - PICS: " !PMKCONC.S.F00 " - response: - constraints: - type: list - excludes: [0, 1, 2, 7, 8] - - - label: - "Step 4f: Read the optional, feature dependent attributes - PeakMeasuredValue & PeakMeasuredValueWindow in AttributeList" - command: "readAttribute" - attribute: "AttributeList" - PICS: PMKCONC.S.F04 - response: - constraints: - type: list - contains: [3, 4] - - - label: - "Step 4g: Check that PeakMeasuredValue & PeakMeasuredValueWindow are - excluded from AttributeList when PMKCONC.S.F04 (PEA) is not set" - command: "readAttribute" - attribute: "AttributeList" - PICS: " !PMKCONC.S.F04 " - response: - constraints: - type: list - excludes: [3, 4] - - - label: - "Step 4h: Read the optional, feature dependent attributes - AverageMeasuredValue AverageMeasuredValueWindow in AttributeList" - command: "readAttribute" - attribute: "AttributeList" - PICS: PMKCONC.S.F05 - response: - constraints: - type: list - contains: [5, 6] - - - label: - "Step 4i: Check that AverageMeasuredValue and - AverageMeasuredValueWindow are excluded from AttributeList when - PMKCONC.S.F05 (AVG) is not set" - command: "readAttribute" - attribute: "AttributeList" - PICS: " !PMKCONC.S.F05 " - response: - constraints: - type: list - excludes: [5, 6] - - - label: - "Step 4j: Read the optional, feature dependent attribute LevelValue in - AttributeList" - command: "readAttribute" - attribute: "AttributeList" - PICS: PMKCONC.S.F01 - response: - constraints: - type: list - contains: [10] - - - label: - "Step 4k: Check that LevelValue is excluded from AttributeList when - PMKCONC.S.F01 (LEV) is not set" - command: "readAttribute" - attribute: "AttributeList" - PICS: " !PMKCONC.S.F01 " - response: - constraints: - type: list - excludes: [10] - - - label: "Step 5: Read the global attribute: EventList" - command: "readAttribute" - attribute: "EventList" - PICS: PICS_EVENT_LIST_ENABLED - response: - value: [] - constraints: - type: list - - - label: "Step 6: Read the global attribute: AcceptedCommandList" - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - value: [] - constraints: - type: list - - - label: "Step 7: Read the global attribute: GeneratedCommandList" - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - value: [] - constraints: - type: list diff --git a/src/app/tests/suites/certification/Test_TC_PWRTL_1_1.yaml b/src/app/tests/suites/certification/Test_TC_PWRTL_1_1.yaml deleted file mode 100644 index 5d64bedf47ebb3..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_PWRTL_1_1.yaml +++ /dev/null @@ -1,143 +0,0 @@ -# Copyright (c) 2021 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -name: 44.1.1. [TC-PWRTL-1.1] Global Attributes with DUT as Server - -PICS: - - PWRTL.S - -config: - nodeId: 0x12344321 - cluster: "Power Topology" - endpoint: 1 - -tests: - - label: "Step 1: Wait for the commissioned device to be retrieved" - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: TH reads the ClusterRevision from DUT" - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 1 - constraints: - type: int16u - - - label: - "Step 3a: Given PWRTL.S.F00(Node) ensure featuremap has the correct - bit set" - PICS: PWRTL.S.F00 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x1] - hasMasksClear: [0x2, 0x4, 0x8] - - - label: - "Step 3b: Given PWRTL.S.F01(Leaf) ensure featuremap has the correct - bit set" - PICS: PWRTL.S.F01 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x2] - hasMasksClear: [0x1, 0x4, 0x8] - - - label: - "Step 3c: Given PWRTL.S.F02(Set) ensure featuremap has the correct bit - set" - PICS: PWRTL.S.F02 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x4] - hasMasksClear: [0x1, 0x2] - - - label: - "Step 3d: Given PWRTL.S.F03(Dynamic Power Flow) ensure featuremap has - the correct bit set" - PICS: PWRTL.S.F03 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x4, 0x8] - - - label: "Step 4a: TH reads AttributeList from DUT" - PICS: " !PWRTL.S.F02 && !PWRTL.S.F03 " - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [] - - - label: - "Step 4b: TH reads feature dependent attribute(AvailableEndpoints) - AttributeList from DUT" - PICS: PWRTL.S.F02 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0] - - - label: - "Step 4c: TH reads feature dependent attribute(ActiveEndpoints) - AttributeList from DUT" - PICS: "PWRTL.S.F02 && PWRTL.S.F03" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 1] - - - label: "Step 5*: TH reads EventList attribute from DUT" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - value: [] - constraints: - type: list - - - label: "Step 6: TH reads the AcceptedCommandList attribute from the DUT" - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - value: [] - constraints: - type: list - - - label: "Step 7: TH reads the GeneratedCommandList attribute from the DUT" - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - value: [] - constraints: - type: list diff --git a/src/app/tests/suites/certification/Test_TC_RNCONC_1_1.yaml b/src/app/tests/suites/certification/Test_TC_RNCONC_1_1.yaml deleted file mode 100644 index 8efffd3ec61792..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_RNCONC_1_1.yaml +++ /dev/null @@ -1,339 +0,0 @@ -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -name: 145.1.1. [TC-RNCONC-1.1] Global Attributes with DUT as Server - -PICS: - - RNCONC.S - -config: - nodeId: 0x12344321 - cluster: "Radon Concentration Measurement" - endpoint: 1 - -tests: - - label: - "Step 1: Commission DUT to TH (can be skipped if done in a preceding - test)." - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: TH reads from the DUT the ClusterRevision attribute." - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 3 - constraints: - type: int16u - - - label: - "Step 3a: TH reads from the DUT the FeatureMap attribute and check for - either bit 0 or 1 set" - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x03] - - - label: - "Step 3b: Given RNCONC.S.F00(MEA) ensure featuremap has the correct - bit set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: RNCONC.S.F00 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x1] - - - label: - "Step 3c: Given RNCONC.S.F00(MEA) is not set, ensure featuremap has - the correct bit clear" - command: "readAttribute" - attribute: "FeatureMap" - PICS: " !RNCONC.S.F00 " - response: - constraints: - type: bitmap32 - hasMasksClear: [0x1] - - - label: - "Step 3d: Given RNCONC.S.F01(LEV) ensure featuremap has the correct - bit set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: RNCONC.S.F01 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x2] - - - label: - "Step 3e: Given RNCONC.S.F01(LEV) is not set, ensure featuremap has - the correct bit clear" - command: "readAttribute" - attribute: "FeatureMap" - PICS: " !RNCONC.S.F01 " - response: - constraints: - type: bitmap32 - hasMasksClear: [0x2] - - - label: - "Step 3f: Given RNCONC.S.F02(MED) ensure featuremap has the correct - bit set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: RNCONC.S.F02 && RNCONC.S.F01 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x4, 0x2] - - - label: - "Step 3g: Given RNCONC.S.F02(MED) is not set, ensure featuremap has - the correct bit clear" - command: "readAttribute" - attribute: "FeatureMap" - PICS: " !RNCONC.S.F02 && !RNCONC.S.F01" - response: - constraints: - type: bitmap32 - hasMasksClear: [0x4] - - - label: - "Step 3h: Given RNCONC.S.F03(CRI) ensure featuremap has the correct - bits set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: RNCONC.S.F03 && RNCONC.S.F01 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x8, 0x2] - - - label: - "Step 3i: Given RNCONC.S.F03(CRI) is not set, ensure featuremap has - the correct bit clear" - command: "readAttribute" - attribute: "FeatureMap" - PICS: " !RNCONC.S.F03 && !RNCONC.S.F01" - response: - constraints: - type: bitmap32 - hasMasksClear: [0x8] - - - label: - "Step 3j: Given RNCONC.S.F04(PEA) ensure featuremap has the correct - bits set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: RNCONC.S.F04 && RNCONC.S.F00 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x10, 0x1] - - - label: - "Step 3k: Given RNCONC.S.F04(PEA) is not set, ensure featuremap has - the correct bit clear" - command: "readAttribute" - attribute: "FeatureMap" - PICS: " !RNCONC.S.F04 && RNCONC.S.F00" - response: - constraints: - type: bitmap32 - hasMasksClear: [0x10] - - - label: - "Step 3l: Given RNCONC.S.F05(AVG) ensure featuremap has the correct - bits set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: RNCONC.S.F05 && RNCONC.S.F00 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x20, 0x1] - - - label: - "Step 3m: Given RNCONC.S.F05(AVG) is not set, ensure featuremap has - the correct bit clear" - command: "readAttribute" - attribute: "FeatureMap" - PICS: " !RNCONC.S.F05 && !RNCONC.S.F00 " - response: - constraints: - type: bitmap32 - hasMasksClear: [0x20] - - - label: "Step 4a: TH reads from the DUT the AttributeList attribute." - command: "readAttribute" - attribute: "AttributeList" - PICS: PICS_EVENT_LIST_ENABLED - response: - constraints: - type: list - contains: [9, 65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 4a: TH reads from the DUT the AttributeList attribute." - command: "readAttribute" - attribute: "AttributeList" - PICS: "!PICS_EVENT_LIST_ENABLED" - response: - constraints: - type: list - contains: [9, 65528, 65529, 65531, 65532, 65533] - - - label: - "Step 4b: TH reads the optional attribute Uncertainty in AttributeList" - command: "readAttribute" - attribute: "AttributeList" - PICS: RNCONC.S.A0007 && RNCONC.S.F00 - response: - constraints: - type: list - contains: [7] - - - label: - "Step 4c: Check the optional attribute Uncertainty is excluded from - AttributeList when RNCONC.S.A0007 is not set" - command: "readAttribute" - attribute: "AttributeList" - PICS: " !RNCONC.S.A0007 " - response: - constraints: - type: list - excludes: [7] - - - label: - "Step 4d: TH reads the optional, feature dependent attributes - MeasuredValue, MinMeasuredValue, MaxMeasuredValue and Measurement Unit - in AttributeList" - command: "readAttribute" - attribute: "AttributeList" - PICS: RNCONC.S.F00 - response: - constraints: - type: list - contains: [0, 1, 2, 8] - - - label: - "Step 4e: Check that MeasuredValue, MinMeasuredValue, - MaxMeasuredValue, Measurement Unit and Uncertainty are excluded from - AttributeList when RNCONC.S.F00 (MEA) is not set" - command: "readAttribute" - attribute: "AttributeList" - PICS: " !RNCONC.S.F00 " - response: - constraints: - type: list - excludes: [0, 1, 2, 7, 8] - - - label: - "Step 4f: TH reads the optional, feature dependent attributes - PeakMeasuredValue & PeakMeasuredValueWindow in AttributeList" - command: "readAttribute" - attribute: "AttributeList" - PICS: RNCONC.S.F04 - response: - constraints: - type: list - contains: [3, 4] - - - label: - "Step 4g: Check that PeakMeasuredValue & PeakMeasuredValueWindow are - excluded from AttributeList when RNCONC.S.F04 (PEA) is not set" - command: "readAttribute" - attribute: "AttributeList" - PICS: " !RNCONC.S.F04 " - response: - constraints: - type: list - excludes: [3, 4] - - - label: - "Step 4h: TH reads the optional, feature dependent attributes - AverageMeasuredValue AverageMeasuredValueWindow in AttributeList" - command: "readAttribute" - attribute: "AttributeList" - PICS: RNCONC.S.F05 - response: - constraints: - type: list - contains: [5, 6] - - - label: - "Step 4i: Check that AverageMeasuredValue and - AverageMeasuredValueWindow are excluded from AttributeList when - RNCONC.S.F05 (AVG) is not set" - command: "readAttribute" - attribute: "AttributeList" - PICS: " !RNCONC.S.F05 " - response: - constraints: - type: list - excludes: [5, 6] - - - label: - "Step 4j: TH reads the optional, feature dependent attribute - LevelValue in AttributeList" - command: "readAttribute" - attribute: "AttributeList" - PICS: RNCONC.S.F01 - response: - constraints: - type: list - contains: [10] - - - label: - "Step 4k: Check that LevelValue is excluded from AttributeList when - RNCONC.S.F01 (LEV) is not set" - command: "readAttribute" - attribute: "AttributeList" - PICS: " !RNCONC.S.F01 " - response: - constraints: - type: list - excludes: [10] - - - label: "Step 5: TH reads from the DUT the EventList attribute." - command: "readAttribute" - attribute: "EventList" - PICS: PICS_EVENT_LIST_ENABLED - response: - value: [] - constraints: - type: list - - - label: "Step 6: TH reads from the DUT the AcceptedCommandList attribute." - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - value: [] - constraints: - type: list - - - label: "Step 7: TH reads from the DUT the GeneratedCommandList attribute." - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - value: [] - constraints: - type: list diff --git a/src/app/tests/suites/certification/Test_TC_SMOKECO_1_1.yaml b/src/app/tests/suites/certification/Test_TC_SMOKECO_1_1.yaml deleted file mode 100644 index c1f997bb3939dc..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_SMOKECO_1_1.yaml +++ /dev/null @@ -1,269 +0,0 @@ -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -name: 4.1.1. [TC-SMOKECO-1.1] Global Attributes with DUT as Server - -PICS: - - SMOKECO.S - -config: - nodeId: 0x12344321 - cluster: "Smoke CO Alarm" - endpoint: 1 - -tests: - - label: "Step 1: Commission DUT to TH" - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: TH reads the ClusterRevision attribute from the DUT" - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 1 - constraints: - type: int16u - - - label: "Step 3a: TH reads from the DUT the FeatureMap attribute" - PICS: "!SMOKECO.S.F00 && !SMOKECO.S.F01" - command: "readAttribute" - attribute: "FeatureMap" - response: - value: 0 - constraints: - type: bitmap32 - - - label: - "Step 3b: TH reads from the DUT the FeatureMap attribute(Smoke Alarm)" - PICS: SMOKECO.S.F00 && !SMOKECO.S.F01 - command: "readAttribute" - attribute: "FeatureMap" - response: - value: 1 - constraints: - type: bitmap32 - - - label: "Step 3c: TH reads from the DUT the FeatureMap attribute(CO Alarm)" - PICS: SMOKECO.S.F01 && !SMOKECO.S.F00 - command: "readAttribute" - attribute: "FeatureMap" - response: - value: 2 - constraints: - type: bitmap32 - - - label: - "Step 3d: TH reads from the DUT the FeatureMap attribute(Smoke Alarm & - CO Alarm)" - PICS: SMOKECO.S.F00 && SMOKECO.S.F01 - command: "readAttribute" - attribute: "FeatureMap" - response: - value: 3 - constraints: - type: bitmap32 - - - label: "Step 4a: TH reads from the DUT the AttributeList attribute" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 3, 5, 6, 7, 65528, 65529, 65531, 65532, 65533] - - - label: - "Step 4b: TH reads from the DUT the AttributeList - attribute(SmokeState)" - PICS: SMOKECO.S.A0001 && SMOKECO.S.F00 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [1] - - - label: - "Step 4c: TH reads from the DUT the AttributeList attribute(COState)" - PICS: SMOKECO.S.A0002 && SMOKECO.S.F01 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [2] - - - label: - "Step 4d: TH reads from the DUT the AttributeList - attribute(DeviceMuted)" - PICS: SMOKECO.S.A0004 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [4] - - - label: - "Step 4e: TH reads from the DUT the AttributeList - attribute(InterconnectSmokeAlarm)" - PICS: SMOKECO.S.A0008 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [8] - - - label: - "Step 4f: TH reads from the DUT the AttributeList - attribute(InterconnectCOAlarm)" - PICS: SMOKECO.S.A0009 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [9] - - - label: - "Step 4g: TH reads from the DUT the AttributeList - attribute(ContaminationState)" - PICS: SMOKECO.S.A000a - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [10] - - - label: - "Step 4h: TH reads from the DUT the AttributeList - attribute(SmokeSensitivityLevel)" - PICS: SMOKECO.S.A000b - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [11] - - - label: - "Step 4i: TH reads from the DUT the AttributeList - attribute(ExpiryDate)" - PICS: SMOKECO.S.A000c - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [12] - - - label: "Step 5a: TH reads from the DUT the EventList attribute" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - constraints: - type: list - contains: [2, 3, 4, 5, 10] - - - label: - "Step 5b: TH reads from the DUT the EventList attribute(SmokeAlarm)" - PICS: PICS_EVENT_LIST_ENABLED && SMOKECO.S.E00 - command: "readAttribute" - attribute: "EventList" - response: - constraints: - type: list - contains: [0] - - - label: "Step 5c: TH reads from the DUT the EventList attribute(COAlarm)" - PICS: PICS_EVENT_LIST_ENABLED && SMOKECO.S.E01 - command: "readAttribute" - attribute: "EventList" - response: - constraints: - type: list - contains: [1] - - - label: - "Step 5d: TH reads from the DUT the EventList attribute(AlarmMuted)" - PICS: PICS_EVENT_LIST_ENABLED && SMOKECO.S.E06 - command: "readAttribute" - attribute: "EventList" - response: - constraints: - type: list - contains: [6] - - - label: "Step 5e: TH reads from the DUT the EventList attribute(MuteEnded)" - PICS: PICS_EVENT_LIST_ENABLED && SMOKECO.S.E07 - command: "readAttribute" - attribute: "EventList" - response: - constraints: - type: list - contains: [7] - - - label: - "Step 5f: TH reads from the DUT the EventList - attribute(InterconnectSmokeAlarm)" - PICS: PICS_EVENT_LIST_ENABLED && SMOKECO.S.E08 - command: "readAttribute" - attribute: "EventList" - response: - constraints: - type: list - contains: [8] - - - label: - "Step 5g: TH reads from the DUT the EventList - attribute(InterconnectCOAlarm)" - PICS: PICS_EVENT_LIST_ENABLED && SMOKECO.S.E09 - command: "readAttribute" - attribute: "EventList" - response: - constraints: - type: list - contains: [9] - - - label: "Step 6a: TH reads from the DUT the AcceptedCommandList attribute" - PICS: "!SMOKECO.S.C00.Rsp" - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - value: [] - constraints: - type: list - - - label: "Step 6b: TH reads from the DUT the AcceptedCommandList attribute" - PICS: SMOKECO.S.C00.Rsp - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [0] - - - label: "Step 7: TH reads from the DUT the GeneratedCommandList attribute" - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - value: [] - constraints: - type: list diff --git a/src/app/tests/suites/certification/Test_TC_SWTCH_1_1.yaml b/src/app/tests/suites/certification/Test_TC_SWTCH_1_1.yaml deleted file mode 100644 index fdb1e4137ce468..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_SWTCH_1_1.yaml +++ /dev/null @@ -1,184 +0,0 @@ -# Copyright (c) 2021 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -name: 74.1.1. [TC-SWTCH-1.1] Global Attributes with DUT as Server - -PICS: - - SWTCH.S - -config: - nodeId: 0x12344321 - cluster: "Switch" - endpoint: 1 - -tests: - - label: - "Step 1: Commission DUT to TH (can be skipped if done in a preceding - test)." - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: TH reads from the DUT the ClusterRevision attribute." - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 2 - constraints: - type: int16u - - - label: - "Step 3: TH reads from the DUT the FeatureMap attribute and ensures no - invalid bits." - PICS: - "!SWTCH.S.F00 && !SWTCH.S.F01 && !SWTCH.S.F02 && !SWTCH.S.F03 && - !SWTCH.S.F04 && !SWTCH.S.F05" - command: "readAttribute" - attribute: "FeatureMap" - response: - value: 0 - constraints: - type: bitmap32 - - - label: - "Step 3a: Given SWTCH.S.F00(LS) ensure featuremap has the correct bits - set" - PICS: SWTCH.S.F00 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x01] - hasMasksClear: [0x02, 0x04, 0x08, 0x10, 0x20] - - - label: - "Step 3b: Given SWTCH.S.F01(MS) ensure featuremap has the correct bits - set: checks on !MSL when MS feature present." - PICS: SWTCH.S.F01 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x2] - hasMasksClear: [0x1] - - - label: - "Step 3b: Given SWTCH.S.F02(MSR) ensure featuremap has the correct - bits set: checks on MS & !AS & MSR." - PICS: SWTCH.S.F02 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x2, 0x4] - hasMasksClear: [0x1, 0x20] - - - label: - "Step 3b: Given SWTCH.S.F03(MSL) ensure featuremap has the correct - bits set: LS cannot be enabled if MSL." - PICS: SWTCH.S.F03 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x2, 0x8] - hasMasksClear: [0x1] - - - label: - "Step 3b: Given SWTCH.S.F04(MSM) ensure featuremap has the correct - bits set: LS cannot be enabled if MSM." - PICS: SWTCH.S.F04 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x2, 0x10] - hasMasksClear: [0x1] - - - label: - "Step 3b: Given SWTCH.S.F05(AS) ensure featuremap has the correct bits - set: LS and MSR cannot be enabled if AS, and MSM is required by AS." - PICS: SWTCH.S.F05 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x2, 0x10, 0x20] - hasMasksClear: [0x1, 0x4] - - - label: "Step 3c: LS and MS are mutually exclusive (1/2)." - PICS: "SWTCH.S.F00" - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x1] - hasMasksClear: [0x2] - - - label: "Step 3c: LS and MS are mutually exclusive (2/2)." - PICS: "SWTCH.S.F01" - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x2] - hasMasksClear: [0x1] - - - label: - "Step 4: TH reads from the DUT the AttributeList attribute, verify - that attribute MultiPressMax is present with MSM feature." - PICS: "SWTCH.S.F04" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [2] - - - label: - "Step 4: TH reads from the DUT the AttributeList attribute, verify - mandatory attributes." - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 1, 65528, 65529, 65531, 65532, 65533] - - - label: "Step 5: TH reads from the DUT the AcceptedCommandList attribute." - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - value: [] - constraints: - type: list - - - label: "Step 6: TH reads from the DUT the GeneratedCommandList attribute." - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - value: [] - constraints: - type: list diff --git a/src/app/tests/suites/certification/Test_TC_TCTL_1_1.yaml b/src/app/tests/suites/certification/Test_TC_TCTL_1_1.yaml deleted file mode 100644 index 680b359d2b7d32..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_TCTL_1_1.yaml +++ /dev/null @@ -1,158 +0,0 @@ -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -name: 178.1.1. [TC-TCTL-1.1] Global attributes with DUT as Server - -PICS: - - TCTL.S - -config: - nodeId: 0x12344321 - cluster: "Temperature Control" - endpoint: 1 - -tests: - - label: "Step 1: Wait for the commissioned device to be retrieved" - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: TH reads from the DUT the ClusterRevision attribute" - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 1 - constraints: - type: int16u - - - label: "Step 3a: TH reads from the DUT the FeatureMap attribute" - command: "readAttribute" - attribute: "FeatureMap" - PICS: "!TCTL.S.F00 && !TCTL.S.F01 && !TCTL.S.F02" - response: - value: 0 - constraints: - type: bitmap32 - - - label: - "Step 3b: TH reads from the DUT the FeatureMap attribute. bit 0: SHALL - be 1 if and only if TCTL.S.F00(TN) & !TCTL.S.F01(TL)" - command: "readAttribute" - attribute: "FeatureMap" - PICS: TCTL.S.F00 && !TCTL.S.F01 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x1] - - - label: - "Step 3c: TH reads from the DUT the FeatureMap attribute. bit 1: SHALL - be 1 if and only if TCTL.S.F01(TL) & !TCTL.S.F00(TN)" - command: "readAttribute" - attribute: "FeatureMap" - PICS: TCTL.S.F01 && !TCTL.S.F00 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x2] - - - label: - "Step 3d: TH reads from the DUT the FeatureMap attribute. bit 2: SHALL - be 1 if and only if TCTL.S.F02(A_STEP) & TCTL.S.F00(TN)" - command: "readAttribute" - attribute: "FeatureMap" - PICS: TCTL.S.F02 && TCTL.S.F00 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x4] - - - label: "Step 4a: TH reads from the DUT the AttributeList attribute." - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 4a: TH reads from the DUT the AttributeList attribute." - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [65528, 65529, 65531, 65532, 65533] - - - label: - "Step 4b: TH reads from the DUT the AttributeList attribute. 0x0000, - 0x0001, 0x0002: SHALL be included if and only if TCTL.S.F00(TN)" - PICS: TCTL.S.F00 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 1, 2] - - - label: - "Step 4c: TH reads from the DUT the AttributeList attribute. 0x0003: - SHALL be included if and only if TCTL.S.F02(A_STEP)" - PICS: TCTL.S.F02 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [3] - - - label: - "Step 4d: TH reads from the DUT the AttributeList attribute. 0x0004 & - 0x0005: SHALL be included if and only if TCTL.S.F01(TL)" - PICS: TCTL.S.F01 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [4, 5] - - - label: "Step 5: TH reads from the DUT the AcceptedCommandList attribute." - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [0] - - - label: "Step 6: TH reads from the DUT the GeneratedCommandList attribute." - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - value: [] - constraints: - type: list - - - label: "Step 7: TH reads from the DUT the EventList attribute." - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - value: [] - constraints: - type: list diff --git a/src/app/tests/suites/certification/Test_TC_TSTAT_1_1.yaml b/src/app/tests/suites/certification/Test_TC_TSTAT_1_1.yaml deleted file mode 100644 index ef8f688bf5e89c..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_TSTAT_1_1.yaml +++ /dev/null @@ -1,639 +0,0 @@ -# Copyright (c) 2021 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -name: 42.1.1. [TC-TSTAT-1.1] Global Attributes with DUT as Server - -PICS: - - TSTAT.S - -config: - nodeId: 0x12344321 - cluster: "Thermostat" - endpoint: 1 - -tests: - - label: - "Step 1: Commission DUT to TH (can be skipped if done in a preceding - test)." - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: TH reads from the DUT the ClusterRevision attribute." - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 7 - constraints: - type: int16u - - - label: "Step 3a: TH reads from the DUT the FeatureMap attribute." - PICS: - "!TSTAT.S.F00 && !TSTAT.S.F01 && !TSTAT.S.F02 && !TSTAT.S.F03 && - !TSTAT.S.F04 && !TSTAT.S.F05" - command: "readAttribute" - attribute: "FeatureMap" - response: - value: 0 - constraints: - type: bitmap32 - - - label: - "Step 3b: Given TSTAT.S.F00(HEAT ensure featuremap has the correct bit - set" - PICS: TSTAT.S.F00 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x1] - - - label: - "Step 3c: Given TSTAT.S.F01(COOL) ensure featuremap has the correct - bit set" - PICS: TSTAT.S.F01 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x2] - - - label: - "Step 3d: Given TSTAT.S.F02(OCC) ensure featuremap has the correct bit - set" - PICS: TSTAT.S.F02 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x4] - - - label: - "Step 3e: Given TSTAT.S.F03(SCH) ensure featuremap has the correct bit - set" - PICS: TSTAT.S.F03 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x8] - - - label: - "Step 3f: Given TSTAT.S.F04(SB) ensure featuremap has the correct bit - set" - PICS: TSTAT.S.F04 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x10] - - - label: - "Step 3g: Given TSTAT.S.F05(AUTO) ensure featuremap has the correct - bit set" - PICS: TSTAT.S.F05 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x20] - - - label: - "Step 3h: Given TSTAT.S.F06(LTNE) ensure featuremap has the correct - bit set" - PICS: TSTAT.S.F06 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x40] - - - label: - "Step 3i: Given TSTAT.S.F08(PRES ensure featuremap has the correct bit - set" - PICS: TSTAT.S.F08 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x100] - - - label: "Step 4a: TH reads from the DUT the AttributeList attribute." - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 27, 28, 65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 4a: TH reads from the DUT the AttributeList attribute." - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 27, 28, 65528, 65529, 65531, 65532, 65533] - - - label: - "Step 4b: TH reads the Feature dependent(TSTAT.S.F00(HEAT)) attribute - in AttributeList" - PICS: TSTAT.S.F00 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [18] - - label: - "Step 4c: TH reads the Feature dependent(TSTAT.S.F01(COOL)) attribute - in AttributeList" - PICS: TSTAT.S.F01 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [17] - - - label: - "Step 4d: TH reads the Feature dependent(TSTAT.S.F02(OCC)) attribute - in AttributeList" - PICS: TSTAT.S.F02 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [2] - - - label: - "Step 4e: TH reads the Feature dependent(TSTAT.S.F00(HEAT) & - TSTAT.S.F02(OCC)) attribute in AttributeList" - PICS: TSTAT.S.F00 && TSTAT.S.F02 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [20] - - - label: - "Step 4f: TH reads the Feature dependent(TSTAT.S.F01(COOL) & - TSTAT.S.F02(OCC)) attribute in AttributeList" - PICS: TSTAT.S.F01 && TSTAT.S.F02 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [19] - - - label: - "Step 4g: TH reads the Feature dependent(TSTAT.S.F05(AUTO)) attribute - in AttributeList" - PICS: TSTAT.S.F05 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [17, 18, 25] - - - label: - "Step 4h: TH reads the Feature dependent(TSTAT.S.F03(SCH)) attribute - in AttributeList" - PICS: TSTAT.S.F03 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [32, 33, 34] - - - label: - "Step 4i: TH reads the Feature dependent(TSTAT.S.F04(SB)) attribute in - AttributeList" - PICS: TSTAT.S.F04 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [52, 53, 54] - - - label: - "Step 4j: TH reads the Feature dependent(TSTAT.S.F04(SB) & - TSTAT.S.F02(OCC)) attribute in AttributeList" - PICS: TSTAT.S.F04 && TSTAT.S.F02 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [55, 56, 57] - - - label: "Step 4k: TH reads the optional attribute in AttributeList" - PICS: TSTAT.S.A0001 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [1] - - - label: "Step 4l: TH reads the optional attribute in AttributeList" - PICS: TSTAT.S.A0009 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [9] - - - label: "Step 4m: TH reads the optional attribute in AttributeList" - PICS: TSTAT.S.A0010 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [16] - - - label: "Step 4n: TH reads the optional attribute in AttributeList" - PICS: TSTAT.S.A001a - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [26] - - - label: "Step 4o: TH reads the optional attribute in AttributeList" - PICS: TSTAT.S.A001d - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [29] - - - label: "Step 4p: TH reads the optional attribute in AttributeList" - PICS: TSTAT.S.A0023 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [35] - - - label: "Step 4q: TH reads the optional attribute in AttributeList" - PICS: TSTAT.S.A0024 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [36] - - - label: "Step 4r: TH reads the optional attribute in AttributeList" - PICS: TSTAT.S.A0025 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [37] - - - label: "Step 4s: TH reads the optional attribute in AttributeList" - PICS: TSTAT.S.A0029 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [41] - - - label: "Step 4t: TH reads the optional attribute in AttributeList" - PICS: TSTAT.S.A0030 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [48] - - - label: "Step 4u: TH reads the optional attribute in AttributeList" - PICS: TSTAT.S.A0031 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [49] - - - label: "Step 4x: TH reads the optional attribute in AttributeList" - PICS: TSTAT.S.A0032 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [50] - - - label: "Step 4y: TH reads the optional attribute: AttributeList" - PICS: TSTAT.S.A003a - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [58] - - - label: "Step 4z: TH reads the optional attribute in AttributeList" - PICS: TSTAT.S.A0040 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [64] - - - label: "Step 4A: TH reads the optional attribute in AttributeList" - PICS: TSTAT.S.A0041 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [65] - - - label: "Step 4B: TH reads the optional attribute in AttributeList" - PICS: TSTAT.S.A0042 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [66] - - - label: "Step 4C: TH reads the optional attribute in AttributeList" - PICS: TSTAT.S.A0043 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [67] - - - label: "Step 4D: TH reads the optional attribute: AttributeList" - PICS: TSTAT.S.A0044 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [68] - - - label: "Step 4E: TH reads the optional attribute in AttributeList" - PICS: TSTAT.S.A0045 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [69] - - - label: "Step 4F: TH reads the optional attribute in AttributeList" - PICS: TSTAT.S.A0046 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [70] - - - label: "Step 4g: TH reads the optional attribute: AttributeList" - PICS: TSTAT.S.A0047 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [71] - - - label: - "Step 4H: TH reads the Feature dependent(TSTAT.S.F00(HEAT)) optional - attribute in AttributeList" - PICS: TSTAT.S.F00 && TSTAT.S.A0003 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [3] - - - label: - "Step 4I: TH reads the Feature dependent(TSTAT.S.F00(HEAT)) optional - attribute in AttributeList" - PICS: TSTAT.S.F00 && TSTAT.S.A0004 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [4] - - - label: - "Step 4J: TH reads the Feature dependent(TSTAT.S.F00(HEAT)) optional - attribute in AttributeList" - PICS: TSTAT.S.F00 && TSTAT.S.A0008 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [8] - - - label: - "Step 4K: TH reads the Feature dependent(TSTAT.S.F00(HEAT)) optional - attribute in AttributeList" - PICS: TSTAT.S.F00 && TSTAT.S.A0015 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [21] - - - label: - "Step 4L: TH reads the Feature dependent(TSTAT.S.F00(HEAT)) optional - attribute in AttributeList" - PICS: TSTAT.S.F00 && TSTAT.S.A0016 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [22] - - - label: - "Step 4M: TH reads the Feature dependent(TSTAT.S.F01(COOL)) optional - attribute in AttributeList" - PICS: TSTAT.S.F01 && TSTAT.S.A0005 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [5] - - - label: - "Step 4N: TH reads the Feature dependent(TSTAT.S.F01(COOL)) optional - attribute in AttributeList" - PICS: TSTAT.S.F01 && TSTAT.S.A0007 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [6] - - - label: - "Step 4O: TH reads the Feature dependent(TSTAT.S.F01(COOL)) optional - attribute in AttributeList" - PICS: TSTAT.S.F01 && TSTAT.S.A0007 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [7] - - - label: - "Step 4P: TH reads the Feature dependent(TSTAT.S.F01(COOL)) optional - attribute in AttributeList" - PICS: TSTAT.S.F01 && TSTAT.S.A0017 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [23] - - - label: - "Step 4Q: TH reads the Feature dependent(TSTAT.S.F01(COOL)) optional - attribute in AttributeList" - PICS: TSTAT.S.F01 && TSTAT.S.A0018 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [24] - - - label: - "Step 4R: TH reads the Feature dependent(TSTAT.S.F05(AUTO)) optional - attribute in AttributeList" - PICS: TSTAT.S.F05 && TSTAT.S.A001e - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [30] - - - label: - "Step 4j: TH reads the Feature dependent(TSTAT.S.F08(PRES) attribute - in AttributeList" - PICS: TSTAT.S.F08 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [72, 74, 78, 80] - - - label: "Step 5: TH reads EventList attribute from the DUT." - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - value: [] - constraints: - type: list - - - label: "Step 6a: TH reads from the DUT the AcceptedCommandList attribute." - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [0] - - - label: - "Step 6b: TH reads Feature dependent(TSTAT.S.F03(SCH)) commands in - AcceptedCommandList" - PICS: TSTAT.S.F03 - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [1, 2, 3] - - - label: - "Step 6c: TH reads Feature dependent(TSTAT.S.F08(PRES)) commands in - AcceptedCommandList" - PICS: TSTAT.S.F08 - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [6, 254] - - - label: - "Step 7a: TH reads Feature dependent(TSTAT.S.F03(SCH)) commands in - GeneratedCommandList" - PICS: TSTAT.S.F03 - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - constraints: - type: list - contains: [0] - - - label: - "Step 7b: TH reads Feature dependent(TSTAT.S.F08(PRES)) commands in - the GeneratedCommandList attribute." - PICS: TSTAT.S.F08 & TSTAT.S.Cfe.Rsp - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - value: [0xFD] # AtomicResponse - constraints: - type: list diff --git a/src/app/tests/suites/certification/Test_TC_TVOCCONC_1_1.yaml b/src/app/tests/suites/certification/Test_TC_TVOCCONC_1_1.yaml deleted file mode 100644 index 8ccf1825791667..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_TVOCCONC_1_1.yaml +++ /dev/null @@ -1,339 +0,0 @@ -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -name: 145.1.1. [TC-TVOCCONC-1.1] Global Attributes with DUT as Server - -PICS: - - TVOCCONC.S - -config: - nodeId: 0x12344321 - cluster: "Total Volatile Organic Compounds Concentration Measurement" - endpoint: 1 - -tests: - - label: - "Step 1: Commission DUT to TH (can be skipped if done in a preceding - test)" - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: TH reads from the DUT the ClusterRevision attribute." - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 3 - constraints: - type: int16u - - - label: - "Step 3a: TH reads from the DUT the FeatureMap attribute and check for - either bit 0 or 1 set" - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x03] - - - label: - "Step 3b: Given TVOCCONC.S.F00(MEA) ensure featuremap has the correct - bit set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: TVOCCONC.S.F00 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x1] - - - label: - "Step 3c: Given TVOCCONC.S.F00(MEA) is not set, ensure featuremap has - the correct bit clear" - command: "readAttribute" - attribute: "FeatureMap" - PICS: " !TVOCCONC.S.F00 " - response: - constraints: - type: bitmap32 - hasMasksClear: [0x1] - - - label: - "Step 3d: Given TVOCCONC.S.F01(LEV) ensure featuremap has the correct - bit set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: TVOCCONC.S.F01 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x2] - - - label: - "Step 3e: Given TVOCCONC.S.F01(LEV) is not set, ensure featuremap has - the correct bit clear" - command: "readAttribute" - attribute: "FeatureMap" - PICS: " !TVOCCONC.S.F01 " - response: - constraints: - type: bitmap32 - hasMasksClear: [0x2] - - - label: - "Step 3f: Given TVOCCONC.S.F02(MED) ensure featuremap has the correct - bit set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: TVOCCONC.S.F02 && TVOCCONC.S.F01 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x4, 0x2] - - - label: - "Step 3g: Given TVOCCONC.S.F02(MED) is not set, ensure featuremap has - the correct bit clear" - command: "readAttribute" - attribute: "FeatureMap" - PICS: " !TVOCCONC.S.F02 && !TVOCCONC.S.F01 " - response: - constraints: - type: bitmap32 - hasMasksClear: [0x4] - - - label: - "Step 3h: Given TVOCCONC.S.F03(CRI) ensure featuremap has the correct - bits set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: TVOCCONC.S.F03 && TVOCCONC.S.F01 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x8, 0x2] - - - label: - "Step 3i: Given TVOCCONC.S.F03(CRI) is not set, ensure featuremap has - the correct bit clear" - command: "readAttribute" - attribute: "FeatureMap" - PICS: " !TVOCCONC.S.F03 && !TVOCCONC.S.F01" - response: - constraints: - type: bitmap32 - hasMasksClear: [0x8] - - - label: - "Step 3j: Given TVOCCONC.S.F04(PEA) ensure featuremap has the correct - bits set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: TVOCCONC.S.F04 && TVOCCONC.S.F00 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x10, 0x1] - - - label: - "Step 3k: Given TVOCCONC.S.F04(PEA) is not set, ensure featuremap has - the correct bit clear" - command: "readAttribute" - attribute: "FeatureMap" - PICS: " !TVOCCONC.S.F04 && !TVOCCONC.S.F00 " - response: - constraints: - type: bitmap32 - hasMasksClear: [0x10] - - - label: - "Step 3l: Given TVOCCONC.S.F05(AVG) ensure featuremap has the correct - bits set" - command: "readAttribute" - attribute: "FeatureMap" - PICS: TVOCCONC.S.F05 && TVOCCONC.S.F00 - response: - constraints: - type: bitmap32 - hasMasksSet: [0x20, 0x1] - - - label: - "Step 3m: Given TVOCCONC.S.F05(AVG) is not set, ensure featuremap has - the correct bit clear" - command: "readAttribute" - attribute: "FeatureMap" - PICS: " !TVOCCONC.S.F05 && !TVOCCONC.S.F00 " - response: - constraints: - type: bitmap32 - hasMasksClear: [0x20] - - - label: "Step 4a: TH reads from the DUT the AttributeList attribute" - command: "readAttribute" - attribute: "AttributeList" - PICS: PICS_EVENT_LIST_ENABLED - response: - constraints: - type: list - contains: [9, 65528, 65529, 65530, 65531, 65532, 65533] - - - label: "Step 4a: TH reads from the DUT the AttributeList attribute." - command: "readAttribute" - attribute: "AttributeList" - PICS: "!PICS_EVENT_LIST_ENABLED" - response: - constraints: - type: list - contains: [9, 65528, 65529, 65531, 65532, 65533] - - - label: - "Step 4b: TH reads the optional attribute Uncertainty in AttributeList" - command: "readAttribute" - attribute: "AttributeList" - PICS: TVOCCONC.S.A0007 && TVOCCONC.S.F00 - response: - constraints: - type: list - contains: [7] - - - label: - "Step 4c: Check the optional attribute Uncertainty is excluded from - AttributeList when TVOCCONC.S.A0007 is not set" - command: "readAttribute" - attribute: "AttributeList" - PICS: " !TVOCCONC.S.A0007 " - response: - constraints: - type: list - excludes: [7] - - - label: - "Step 4d: TH reads the optional, feature dependent attributes - MeasuredValue, MinMeasuredValue, MaxMeasuredValue and Measurement Unit - in AttributeList" - command: "readAttribute" - attribute: "AttributeList" - PICS: TVOCCONC.S.F00 - response: - constraints: - type: list - contains: [0, 1, 2, 8] - - - label: - "Step 4e: Check that MeasuredValue, MinMeasuredValue, - MaxMeasuredValue, Measurement Unit and Uncertainty are excluded from - AttributeList when TVOCCONC.S.F00 (MEA) is not set" - command: "readAttribute" - attribute: "AttributeList" - PICS: " !TVOCCONC.S.F00 " - response: - constraints: - type: list - excludes: [0, 1, 2, 7, 8] - - - label: - "Step 4f: TH reads the optional, feature dependent attributes - PeakMeasuredValue & PeakMeasuredValueWindow in AttributeList" - command: "readAttribute" - attribute: "AttributeList" - PICS: TVOCCONC.S.F04 - response: - constraints: - type: list - contains: [3, 4] - - - label: - "Step 4g: Check that PeakMeasuredValue & PeakMeasuredValueWindow are - excluded from AttributeList when TVOCCONC.S.F04 (PEA) is not set" - command: "readAttribute" - attribute: "AttributeList" - PICS: " !TVOCCONC.S.F04 " - response: - constraints: - type: list - excludes: [3, 4] - - - label: - "Step 4h: TH reads the optional, feature dependent attributes - AverageMeasuredValue AverageMeasuredValueWindow in AttributeList" - command: "readAttribute" - attribute: "AttributeList" - PICS: TVOCCONC.S.F05 - response: - constraints: - type: list - contains: [5, 6] - - - label: - "Step 4i: Check that AverageMeasuredValue and - AverageMeasuredValueWindow are excluded from AttributeList when - TVOCCONC.S.F05 (AVG) is not set" - command: "readAttribute" - attribute: "AttributeList" - PICS: " !TVOCCONC.S.F05 " - response: - constraints: - type: list - excludes: [5, 6] - - - label: - "Step 4j: TH reads the optional, feature dependent attribute - LevelValue in AttributeList" - command: "readAttribute" - attribute: "AttributeList" - PICS: TVOCCONC.S.F01 - response: - constraints: - type: list - contains: [10] - - - label: - "Step 4k: Check that LevelValue is excluded from AttributeList when - TVOCCONC.S.F01 (LEV) is not set" - command: "readAttribute" - attribute: "AttributeList" - PICS: " !TVOCCONC.S.F01 " - response: - constraints: - type: list - excludes: [10] - - - label: "Step 5: TH reads from the DUT the EventList attribute" - command: "readAttribute" - attribute: "EventList" - PICS: PICS_EVENT_LIST_ENABLED - response: - value: [] - constraints: - type: list - - - label: "Step 6: TH reads from the DUT the AcceptedCommandList attribute." - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - value: [] - constraints: - type: list - - - label: "Step 7: TH reads from the DUT the GeneratedCommandList attribute." - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - value: [] - constraints: - type: list diff --git a/src/app/tests/suites/certification/Test_TC_WNCV_1_1.yaml b/src/app/tests/suites/certification/Test_TC_WNCV_1_1.yaml deleted file mode 100644 index cde5ae4934b20d..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_WNCV_1_1.yaml +++ /dev/null @@ -1,248 +0,0 @@ -# Copyright (c) 2021 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -name: Window Covering [TC-WNCV-1.1] Global attributes [DUT as Server] - -PICS: - - WNCV.S - -config: - nodeId: 0x12344321 - cluster: "Window Covering" - endpoint: 1 - -tests: - - label: "Step 1: Commission DUT to TH" - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - ### MANDATORY GLOBAL Attributes - ### Attribute[0xFFFD]: ClusterRevision ======================================= - - label: - "Step 2: TH reads from the DUT the (0xFFFD) ClusterRevision attribute" - command: "readAttribute" - attribute: "ClusterRevision" - response: - value: 5 - constraints: - type: int16u - minValue: 5 - maxValue: 200 - - - label: "Step 3a: TH reads from the DUT the (0xFFFC) FeatureMap attribute" - PICS: - "!WNCV.S.F00 && !WNCV.S.F01 && !WNCV.S.F02 && !WNCV.S.F03 && - !WNCV.S.F04 " - command: "readAttribute" - attribute: "FeatureMap" - response: - value: 0 - constraints: - type: bitmap32 - - - label: - "Step 3b: Given WNCV.S.F00(LF) ensure featuremap has the correct bit - set" - PICS: WNCV.S.F00 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x1] - - - label: - "Step 3c: Given WNCV.S.F01(TL) ensure featuremap has the correct bit - set" - PICS: WNCV.S.F01 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x2] - - - label: - "Step 3d: Given WNCV.S.F02(PA_LF) ensure featuremap has the correct - bit set" - PICS: WNCV.S.F02 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x4] - - - label: - "Step 3e: Given WNCV.S.F03(ABS) ensure featuremap has the correct bit - set" - PICS: WNCV.S.F03 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x8] - - - label: - "Step 3f: Given WNCV.S.F04(PA_TL) ensure featuremap has the correct - bit set" - PICS: WNCV.S.F04 - command: "readAttribute" - attribute: "FeatureMap" - response: - constraints: - type: bitmap32 - hasMasksSet: [0x10] - - - label: - "Step 4a: TH reads from the DUT the (0xFFFB) AttributeList attribute" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: - [0, 7, 10, 13, 23, 65528, 65529, 65530, 65531, 65532, 65533] - - - label: - "Step 4a: TH reads from the DUT the (0xFFFB) AttributeList attribute" - PICS: "!PICS_EVENT_LIST_ENABLED" - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [0, 7, 10, 13, 23, 65528, 65529, 65531, 65532, 65533] - - - label: - "Step 4b: TH reads optional attribute(SafetyStatus) in AttributeList" - PICS: WNCV.S.A001a - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [26] - - - label: - "Step 4c: TH reads the Feature dependent(WNCV.S.F00 & WNCV.S.F02 & - WNCV.S.F03) attribute in AttributeList" - PICS: WNCV.S.F00 && WNCV.S.F02 && WNCV.S.F03 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [16, 17] - - - label: - "Step 4d: TH reads the Feature dependent(WNCV.S.F00 & WNCV.S.F02 ) - attribute in AttributeList" - PICS: WNCV.S.F00 && WNCV.S.F02 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [11, 14] - - - label: - "Step 4e: TH reads the Feature dependent(WNCV.S.F01 & WNCV.S.F04 & - WNCV.S.F03) attribute in AttributeList" - PICS: WNCV.S.F01 && WNCV.S.F04 && WNCV.S.F03 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [18, 19] - - - label: - "Step 4f: TH reads the Feature dependent(WNCV.S.F01 & WNCV.S.F04 ) - attribute in AttributeList" - PICS: WNCV.S.F01 && WNCV.S.F04 - command: "readAttribute" - attribute: "AttributeList" - response: - constraints: - type: list - contains: [12, 15] - - - label: "Step 5: TH reads from the DUT the (0xFFFA) EventList attribute" - PICS: PICS_EVENT_LIST_ENABLED - command: "readAttribute" - attribute: "EventList" - response: - value: [] - constraints: - type: list - - - label: - "Step 6a: TH reads from the DUT the (0xFFF9) AcceptedCommandList - attribute" - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [0, 1, 2] - - - label: - "Step 6b: TH reads Feature dependent(WNCV.S.F00 & WNCV.S.F02) command - in AcceptedCommandList" - PICS: WNCV.S.F00 && WNCV.S.F02 - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [5] - - - label: - "Step 6c: TH reads Feature dependent(WNCV.S.F01 & WNCV.S.F03) command - in AcceptedCommandList" - PICS: WNCV.S.F01 && WNCV.S.F03 - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [7] - - - label: - "Step 6d: TH reads Feature dependent(WNCV.S.F01 & WNCV.S.F04) command - in AcceptedCommandList" - PICS: WNCV.S.F01 && WNCV.S.F04 - command: "readAttribute" - attribute: "AcceptedCommandList" - response: - constraints: - type: list - contains: [8] - - - label: - "Step 7: TH reads from the DUT the (0xFFF8) GeneratedCommandList - attribute" - command: "readAttribute" - attribute: "GeneratedCommandList" - response: - value: [] - constraints: - type: list From 9df818bdd001af2881f3725f5b462924b509bd25 Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Wed, 16 Oct 2024 16:03:11 -0400 Subject: [PATCH 007/149] Decouple PumpConfigurationAndControl from EmberCompat (#36045) This uses the ember internal function instead of the ember compatibility functions override. It is somewhat unclear why we have an override that replaces one method with a single method that is identical except arguments. Co-authored-by: Andrei Litvin --- .../pump-configuration-and-control-server.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/app/clusters/pump-configuration-and-control-server/pump-configuration-and-control-server.cpp b/src/app/clusters/pump-configuration-and-control-server/pump-configuration-and-control-server.cpp index 5996cfe01f9eff..63bd6a29525724 100644 --- a/src/app/clusters/pump-configuration-and-control-server/pump-configuration-and-control-server.cpp +++ b/src/app/clusters/pump-configuration-and-control-server/pump-configuration-and-control-server.cpp @@ -81,8 +81,8 @@ static void setEffectiveModes(EndpointId endpoint) // if this is not suitable, the application should override this value in // the post attribute change callback for the operation mode attribute const EmberAfAttributeMetadata * effectiveControlModeMetaData; - effectiveControlModeMetaData = GetAttributeMetadata( - app::ConcreteAttributePath(endpoint, PumpConfigurationAndControl::Id, Attributes::EffectiveControlMode::Id)); + effectiveControlModeMetaData = + emberAfLocateAttributeMetadata(endpoint, PumpConfigurationAndControl::Id, Attributes::EffectiveControlMode::Id); controlMode = static_cast(effectiveControlModeMetaData->defaultValue.defaultValue); } From 34d633cf7deffe1245c471347616157e7e4d9034 Mon Sep 17 00:00:00 2001 From: lpbeliveau-silabs <112982107+lpbeliveau-silabs@users.noreply.github.com> Date: Wed, 16 Oct 2024 16:37:27 -0400 Subject: [PATCH 008/149] [Scenes] Mode Select Cluster Handler (#30855) * Added scene handler to mode select cluster * Corrected wrong define usage and applied a fix to attribute-storage function * Applied suggestions --- .../mode-select-server/mode-select-server.cpp | 197 +++++++++++++++++- .../suites/TestScenesFabricSceneInfo.yaml | 10 + src/lib/core/CHIPConfig.h | 7 +- 3 files changed, 200 insertions(+), 14 deletions(-) diff --git a/src/app/clusters/mode-select-server/mode-select-server.cpp b/src/app/clusters/mode-select-server/mode-select-server.cpp index 813d16d965148e..9159ad565bdac7 100644 --- a/src/app/clusters/mode-select-server/mode-select-server.cpp +++ b/src/app/clusters/mode-select-server/mode-select-server.cpp @@ -30,9 +30,14 @@ #include #include #include +#include #include #include +#ifdef MATTER_DM_PLUGIN_SCENES_MANAGEMENT +#include +#endif // MATTER_DM_PLUGIN_SCENES_MANAGEMENT + #ifdef MATTER_DM_PLUGIN_ON_OFF #include #endif // MATTER_DM_PLUGIN_ON_OFF @@ -109,35 +114,200 @@ CHIP_ERROR ModeSelectAttrAccess::Read(const ConcreteReadAttributePath & aPath, A return CHIP_NO_ERROR; } -} // anonymous namespace - -bool emberAfModeSelectClusterChangeToModeCallback(CommandHandler * commandHandler, const ConcreteCommandPath & commandPath, - const ModeSelect::Commands::ChangeToMode::DecodableType & commandData) +Status ChangeToMode(EndpointId endpointId, uint8_t newMode) { MATTER_TRACE_SCOPE("ChangeToMode", "ModeSelect"); ChipLogProgress(Zcl, "ModeSelect: Entering emberAfModeSelectClusterChangeToModeCallback"); - EndpointId endpointId = commandPath.mEndpointId; - uint8_t newMode = commandData.newMode; + // Check that the newMode matches one of the supported options const ModeSelect::Structs::ModeOptionStruct::Type * modeOptionPtr; const ModeSelect::SupportedModesManager * gSupportedModeManager = ModeSelect::getSupportedModesManager(); if (gSupportedModeManager == nullptr) { ChipLogError(Zcl, "ModeSelect: SupportedModesManager is NULL"); - commandHandler->AddStatus(commandPath, Status::Failure); - return true; + return Status::Failure; } Status checkSupportedModeStatus = gSupportedModeManager->getModeOptionByMode(endpointId, newMode, &modeOptionPtr); if (Status::Success != checkSupportedModeStatus) { ChipLogProgress(Zcl, "ModeSelect: Failed to find the option with mode %u", newMode); - commandHandler->AddStatus(commandPath, checkSupportedModeStatus); - return true; + return checkSupportedModeStatus; } ModeSelect::Attributes::CurrentMode::Set(endpointId, newMode); + return Status::Success; +} + +} // anonymous namespace + +#if defined(MATTER_DM_PLUGIN_SCENES_MANAGEMENT) && CHIP_CONFIG_SCENES_USE_DEFAULT_HANDLERS +static constexpr size_t kModeSelectMaxEnpointCount = + MATTER_DM_MODE_SELECT_CLUSTER_SERVER_ENDPOINT_COUNT + CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT; + +static void timerCallback(System::Layer *, void * callbackContext); +static void sceneModeSelectCallback(EndpointId endpoint); +using ModeSelectEndPointPair = scenes::DefaultSceneHandlerImpl::EndpointStatePair; +using ModeSelectTransitionTimeInterface = + scenes::DefaultSceneHandlerImpl::TransitionTimeInterface; + +class DefaultModeSelectSceneHandler : public scenes::DefaultSceneHandlerImpl +{ +public: + DefaultSceneHandlerImpl::StatePairBuffer mSceneEndpointStatePairs; + // As per spec, 1 attribute is scenable in the mode select cluster + static constexpr uint8_t kScenableAttributeCount = 1; + + DefaultModeSelectSceneHandler() = default; + ~DefaultModeSelectSceneHandler() override {} + + // Default function for the mode select cluster, only puts the mode select cluster ID in the span if supported on the given + // endpoint + virtual void GetSupportedClusters(EndpointId endpoint, Span & clusterBuffer) override + { + if (emberAfContainsServer(endpoint, ModeSelect::Id) && clusterBuffer.size() >= 1) + { + clusterBuffer[0] = ModeSelect::Id; + clusterBuffer.reduce_size(1); + } + else + { + clusterBuffer.reduce_size(0); + } + } + + // Default function for mode select cluster, only checks if mode select is enabled on the endpoint + bool SupportsCluster(EndpointId endpoint, ClusterId cluster) override + { + return (cluster == ModeSelect::Id) && (emberAfContainsServer(endpoint, ModeSelect::Id)); + } + + /// @brief Serialize the Cluster's EFS value + /// @param [in] endpoint target endpoint + /// @param [in] cluster target cluster + /// @param [out] serializedBytes data to serialize into EFS + /// @return CHIP_NO_ERROR if successfully serialized the data, CHIP_ERROR_INVALID_ARGUMENT otherwise + CHIP_ERROR SerializeSave(EndpointId endpoint, ClusterId cluster, MutableByteSpan & serializedBytes) override + { + using AttributeValuePair = ScenesManagement::Structs::AttributeValuePairStruct::Type; + + uint8_t currentMode; + // read CurrentMode value + Status status = Attributes::CurrentMode::Get(endpoint, ¤tMode); + if (status != Status::Success) + { + ChipLogError(Zcl, "ERR: reading CurrentMode 0x%02x", to_underlying(status)); + return CHIP_ERROR_READ_FAILED; + } + + AttributeValuePair pairs[kScenableAttributeCount]; + + pairs[0].attributeID = Attributes::CurrentMode::Id; + pairs[0].valueUnsigned8.SetValue(currentMode); + + app::DataModel::List attributeValueList(pairs); + + return EncodeAttributeValueList(attributeValueList, serializedBytes); + } + + /// @brief Default EFS interaction when applying scene to the ModeSelect Cluster + /// @param endpoint target endpoint + /// @param cluster target cluster + /// @param serializedBytes Data from nvm + /// @param timeMs transition time in ms + /// @return CHIP_NO_ERROR if value as expected, CHIP_ERROR_INVALID_ARGUMENT otherwise + CHIP_ERROR ApplyScene(EndpointId endpoint, ClusterId cluster, const ByteSpan & serializedBytes, + scenes::TransitionTimeMs timeMs) override + { + app::DataModel::DecodableList attributeValueList; + + VerifyOrReturnError(cluster == ModeSelect::Id, CHIP_ERROR_INVALID_ARGUMENT); + + ReturnErrorOnFailure(DecodeAttributeValueList(serializedBytes, attributeValueList)); + + size_t attributeCount = 0; + ReturnErrorOnFailure(attributeValueList.ComputeSize(&attributeCount)); + VerifyOrReturnError(attributeCount <= kScenableAttributeCount, CHIP_ERROR_BUFFER_TOO_SMALL); + + auto pair_iterator = attributeValueList.begin(); + while (pair_iterator.Next()) + { + auto & decodePair = pair_iterator.GetValue(); + VerifyOrReturnError(decodePair.attributeID == Attributes::CurrentMode::Id, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(decodePair.valueUnsigned8.HasValue(), CHIP_ERROR_INVALID_ARGUMENT); + ReturnErrorOnFailure(mSceneEndpointStatePairs.InsertPair( + ModeSelectEndPointPair(endpoint, static_cast(decodePair.valueUnsigned8.HasValue())))); + } + // Verify that the EFS was completely read + CHIP_ERROR err = pair_iterator.GetStatus(); + if (CHIP_NO_ERROR != err) + { + mSceneEndpointStatePairs.RemovePair(endpoint); + return err; + } + + VerifyOrReturnError(mTransitionTimeInterface.sceneEventControl(endpoint) != nullptr, CHIP_ERROR_INVALID_ARGUMENT); + DeviceLayer::SystemLayer().StartTimer(chip::System::Clock::Milliseconds32(timeMs), timerCallback, + mTransitionTimeInterface.sceneEventControl(endpoint)); + + return CHIP_NO_ERROR; + } + +private: + ModeSelectTransitionTimeInterface mTransitionTimeInterface = + ModeSelectTransitionTimeInterface(ModeSelect::Id, sceneModeSelectCallback); +}; +static DefaultModeSelectSceneHandler sModeSelectSceneHandler; + +static void timerCallback(System::Layer *, void * callbackContext) +{ + auto control = static_cast(callbackContext); + (control->callback)(control->endpoint); +} + +/** + * @brief This function is a callback to apply the mode that was saved when the ApplyScene was called with a transition time greater + * than 0. + * + * @param endpoint The endpoint ID that the scene mode selection is associated with. + * + */ +static void sceneModeSelectCallback(EndpointId endpoint) +{ + ModeSelectEndPointPair savedState; + ReturnOnFailure(sModeSelectSceneHandler.mSceneEndpointStatePairs.GetPair(endpoint, savedState)); + ChangeToMode(endpoint, savedState.mValue); + sModeSelectSceneHandler.mSceneEndpointStatePairs.RemovePair(endpoint); +} + +#endif // defined(MATTER_DM_PLUGIN_SCENES_MANAGEMENT) && CHIP_CONFIG_SCENES_USE_DEFAULT_HANDLERS + +bool emberAfModeSelectClusterChangeToModeCallback(CommandHandler * commandHandler, const ConcreteCommandPath & commandPath, + const ModeSelect::Commands::ChangeToMode::DecodableType & commandData) +{ + ChipLogProgress(Zcl, "ModeSelect: Entering emberAfModeSelectClusterChangeToModeCallback"); + + uint8_t currentMode = 0; + ModeSelect::Attributes::CurrentMode::Get(commandPath.mEndpointId, ¤tMode); +#ifdef MATTER_DM_PLUGIN_SCENES_MANAGEMENT + if (currentMode != commandData.newMode) + { + // the scene has been changed (the value of CurrentMode has changed) so + // the current scene as described in the scene table is invalid + ScenesManagement::ScenesServer::Instance().MakeSceneInvalidForAllFabrics(commandPath.mEndpointId); + } +#endif // MATTER_DM_PLUGIN_SCENES_MANAGEMENT + + Status status = ChangeToMode(commandPath.mEndpointId, commandData.newMode); + + if (Status::Success != status) + { + commandHandler->AddStatus(commandPath, status); + return true; + } + ChipLogProgress(Zcl, "ModeSelect: ChangeToMode successful"); - commandHandler->AddStatus(commandPath, Status::Success); + commandHandler->AddStatus(commandPath, status); return true; } @@ -148,6 +318,10 @@ bool emberAfModeSelectClusterChangeToModeCallback(CommandHandler * commandHandle */ void emberAfModeSelectClusterServerInitCallback(EndpointId endpointId) { +#if defined(MATTER_DM_PLUGIN_SCENES_MANAGEMENT) && CHIP_CONFIG_SCENES_USE_DEFAULT_HANDLERS + ScenesManagement::ScenesServer::Instance().RegisterSceneHandler(endpointId, &sModeSelectSceneHandler); +#endif // defined(MATTER_DM_PLUGIN_SCENES_MANAGEMENT) && CHIP_CONFIG_SCENES_USE_DEFAULT_HANDLERS + // StartUp behavior relies on CurrentMode StartUpMode attributes being non-volatile. if (areStartUpModeAndCurrentModeNonVolatile(endpointId)) { @@ -161,6 +335,7 @@ void emberAfModeSelectClusterServerInitCallback(EndpointId endpointId) Status status = Attributes::StartUpMode::Get(endpointId, startUpMode); if (status == Status::Success && !startUpMode.IsNull()) { + #ifdef MATTER_DM_PLUGIN_ON_OFF // OnMode with Power Up // If the On/Off feature is supported and the On/Off cluster attribute StartUpOnOff is present, with a diff --git a/src/app/tests/suites/TestScenesFabricSceneInfo.yaml b/src/app/tests/suites/TestScenesFabricSceneInfo.yaml index ba83953588bd3b..2d4a09c07eeb6a 100644 --- a/src/app/tests/suites/TestScenesFabricSceneInfo.yaml +++ b/src/app/tests/suites/TestScenesFabricSceneInfo.yaml @@ -253,6 +253,11 @@ tests: }, ], }, + { + ClusterID: 0x0050, + AttributeValueList: + [{ AttributeID: 0x0003, ValueUnsigned8: 0x01 }], + }, ] response: values: @@ -349,6 +354,11 @@ tests: }, ], }, + { + ClusterID: 0x0050, + AttributeValueList: + [{ AttributeID: 0x0003, ValueUnsigned8: 0x01 }], + }, ] - label: "Read the FabricSceneInfo attribute (0x0007) " diff --git a/src/lib/core/CHIPConfig.h b/src/lib/core/CHIPConfig.h index 7827f5a8c335f2..382c63497da51d 100644 --- a/src/lib/core/CHIPConfig.h +++ b/src/lib/core/CHIPConfig.h @@ -1485,11 +1485,12 @@ extern const char CHIP_NON_PRODUCTION_MARKER[]; #endif /** - * @brief The maximum number of clusters per scene, defaults to 3 for a typical usecase (onOff + level control + color control - * cluster). Needs to be changed in case a greater number of clusters is chosen. + * @brief The maximum number of clusters per scene, we recommend using 4 for a typical use case (onOff + level control + color + * control cluster + mode selec cluster). Needs to be changed in case a greater number of clusters is chosen. In the event the + * device does not need to support the mode select cluster, the maximum number of clusters per scene should be set to 3. */ #ifndef CHIP_CONFIG_SCENES_MAX_CLUSTERS_PER_SCENE -#define CHIP_CONFIG_SCENES_MAX_CLUSTERS_PER_SCENE 3 +#define CHIP_CONFIG_SCENES_MAX_CLUSTERS_PER_SCENE 4 #endif /** From b90334a0d01acfd51f90d357210bad91e8d73dd5 Mon Sep 17 00:00:00 2001 From: Terence Hampson Date: Wed, 16 Oct 2024 17:09:20 -0400 Subject: [PATCH 009/149] [Fabric Sync] Update test to run a little faster (#36082) --- src/python_testing/TC_CCTRL_2_2.py | 28 ++++++++++++++++----------- src/python_testing/TC_CCTRL_2_3.py | 25 +++++++++++++++++------- src/python_testing/TC_MCORE_FS_1_1.py | 24 ++++++++++++++++------- 3 files changed, 52 insertions(+), 25 deletions(-) diff --git a/src/python_testing/TC_CCTRL_2_2.py b/src/python_testing/TC_CCTRL_2_2.py index a2e7b15dc2af99..1bc403a7e48031 100644 --- a/src/python_testing/TC_CCTRL_2_2.py +++ b/src/python_testing/TC_CCTRL_2_2.py @@ -138,8 +138,7 @@ def steps_TC_CCTRL_2_2(self) -> list[TestStep]: TestStep(24, "Reading Event CommissioningRequestResult from DUT, confirm one new event"), TestStep(25, "Send CommissionNode command to DUT with CASE session, with valid parameters"), TestStep(26, "Send OpenCommissioningWindow command on Administrator Commissioning Cluster sent to TH_SERVER"), - TestStep(27, "Wait for DUT to successfully commission TH_SERVER, 30 seconds"), - TestStep(28, "Get number of fabrics from TH_SERVER, verify DUT successfully commissioned TH_SERVER")] + TestStep(27, "Get number of fabrics from TH_SERVER, verify DUT successfully commissioned TH_SERVER (up to 30 seconds)")] return steps @@ -317,15 +316,22 @@ async def test_TC_CCTRL_2_2(self): await self.send_single_cmd(cmd, dev_ctrl=self.TH_server_controller, node_id=self.server_nodeid, endpoint=0, timedRequestTimeoutMs=5000) self.step(27) - if not self.is_pics_sdk_ci_only: - time.sleep(30) - - self.step(28) - th_server_fabrics_new = await self.read_single_attribute_check_success(cluster=Clusters.OperationalCredentials, attribute=Clusters.OperationalCredentials.Attributes.Fabrics, dev_ctrl=self.TH_server_controller, node_id=self.server_nodeid, endpoint=0, fabric_filtered=False) - # TODO: this should be mocked too. - if not self.is_pics_sdk_ci_only: - asserts.assert_equal(len(th_server_fabrics) + 1, len(th_server_fabrics_new), - "Unexpected number of fabrics on TH_SERVER") + max_wait_time_sec = 30 + start_time = time.time() + elapsed = 0 + time_remaining = max_wait_time_sec + previous_number_th_server_fabrics = len(th_server_fabrics_new) + + while time_remaining > 0: + time.sleep(2) + th_server_fabrics_new = await self.read_single_attribute_check_success(cluster=Clusters.OperationalCredentials, attribute=Clusters.OperationalCredentials.Attributes.Fabrics, dev_ctrl=self.TH_server_controller, node_id=self.server_nodeid, endpoint=0, fabric_filtered=False) + if previous_number_th_server_fabrics != len(th_server_fabrics_new): + break + elapsed = time.time() - start_time + time_remaining = max_wait_time_sec - elapsed + + asserts.assert_equal(previous_number_th_server_fabrics + 1, len(th_server_fabrics_new), + "Unexpected number of fabrics on TH_SERVER") if __name__ == "__main__": diff --git a/src/python_testing/TC_CCTRL_2_3.py b/src/python_testing/TC_CCTRL_2_3.py index fe7ed3de40702d..83c25290cf6207 100644 --- a/src/python_testing/TC_CCTRL_2_3.py +++ b/src/python_testing/TC_CCTRL_2_3.py @@ -122,8 +122,7 @@ def steps_TC_CCTRL_2_3(self) -> list[TestStep]: TestStep(8, "Send CommissionNode command to DUT with CASE session, with valid parameters"), TestStep(9, "Send another CommissionNode command to DUT with CASE session, with with same RequestId as the previous one"), TestStep(10, "Send OpenCommissioningWindow command on Administrator Commissioning Cluster sent to TH_SERVER"), - TestStep(11, "Wait for DUT to successfully commission TH_SERVER, 30 seconds"), - TestStep(12, "Get number of fabrics from TH_SERVER, verify DUT successfully commissioned TH_SERVER")] + TestStep(11, "Get number of fabrics from TH_SERVER, verify DUT successfully commissioned TH_SERVER (up to 30 seconds)")] return steps @@ -196,11 +195,23 @@ async def test_TC_CCTRL_2_3(self): await self.send_single_cmd(cmd, dev_ctrl=self.TH_server_controller, node_id=self.server_nodeid, endpoint=0, timedRequestTimeoutMs=5000) self.step(11) - time.sleep(5 if self.is_pics_sdk_ci_only else 30) - - self.step(12) - th_server_fabrics_new = await self.read_single_attribute_check_success(cluster=Clusters.OperationalCredentials, attribute=Clusters.OperationalCredentials.Attributes.Fabrics, dev_ctrl=self.TH_server_controller, node_id=self.server_nodeid, endpoint=0, fabric_filtered=False) - asserts.assert_equal(len(th_server_fabrics) + 1, len(th_server_fabrics_new), + max_wait_time_sec = 30 + start_time = time.time() + elapsed = 0 + time_remaining = max_wait_time_sec + previous_number_th_server_fabrics = len(th_server_fabrics) + + th_server_fabrics_new = None + while time_remaining > 0: + time.sleep(2) + th_server_fabrics_new = await self.read_single_attribute_check_success(cluster=Clusters.OperationalCredentials, attribute=Clusters.OperationalCredentials.Attributes.Fabrics, dev_ctrl=self.TH_server_controller, node_id=self.server_nodeid, endpoint=0, fabric_filtered=False) + if previous_number_th_server_fabrics != len(th_server_fabrics_new): + break + elapsed = time.time() - start_time + time_remaining = max_wait_time_sec - elapsed + + asserts.assert_not_equal(th_server_fabrics_new, None, "Failed to read Fabrics attribute") + asserts.assert_equal(previous_number_th_server_fabrics + 1, len(th_server_fabrics_new), "Unexpected number of fabrics on TH_SERVER") diff --git a/src/python_testing/TC_MCORE_FS_1_1.py b/src/python_testing/TC_MCORE_FS_1_1.py index 995a80cd941289..780089b807ecfe 100755 --- a/src/python_testing/TC_MCORE_FS_1_1.py +++ b/src/python_testing/TC_MCORE_FS_1_1.py @@ -199,14 +199,24 @@ async def test_TC_MCORE_FS_1_1(self): await self.send_single_cmd(cmd, dev_ctrl=self.TH_server_controller, node_id=self.server_nodeid, endpoint=0, timedRequestTimeoutMs=5000) self.step("3c") - if not self.is_pics_sdk_ci_only: - time.sleep(30) + max_wait_time_sec = 30 + start_time = time.time() + elapsed = 0 + time_remaining = max_wait_time_sec + previous_number_th_server_fabrics = len(th_fsa_server_fabrics) + + th_fsa_server_fabrics_new = None + while time_remaining > 0: + time.sleep(2) + th_fsa_server_fabrics_new = await self.read_single_attribute_check_success(cluster=Clusters.OperationalCredentials, attribute=Clusters.OperationalCredentials.Attributes.Fabrics, dev_ctrl=self.TH_server_controller, node_id=self.server_nodeid, endpoint=0, fabric_filtered=False) + if previous_number_th_server_fabrics != len(th_fsa_server_fabrics_new): + break + elapsed = time.time() - start_time + time_remaining = max_wait_time_sec - elapsed - th_fsa_server_fabrics_new = await self.read_single_attribute_check_success(cluster=Clusters.OperationalCredentials, attribute=Clusters.OperationalCredentials.Attributes.Fabrics, dev_ctrl=self.TH_server_controller, node_id=self.server_nodeid, endpoint=0, fabric_filtered=False) - # TODO: this should be mocked too. - if not self.is_pics_sdk_ci_only: - asserts.assert_equal(len(th_fsa_server_fabrics) + 1, len(th_fsa_server_fabrics_new), - "Unexpected number of fabrics on TH_SERVER") + asserts.assert_not_equal(th_fsa_server_fabrics_new, None, "Failed to read Fabrics attribute") + asserts.assert_equal(previous_number_th_server_fabrics + 1, len(th_fsa_server_fabrics_new), + "Unexpected number of fabrics on TH_SERVER") if __name__ == "__main__": From 1000d7e6a2547fa3a1bc70021b4c345fa6a69b7e Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Wed, 16 Oct 2024 17:28:03 -0400 Subject: [PATCH 010/149] Update stalebot settings (#36097) Do not close PRs nor Issues Make the stale threshold to about 6 months, to match general release cycle for CHIP. Even if this changes at some point to anually, this still seems to be a more reasonable default if we actively triage and manage issues and PRs. --- .github/workflows/stale.yaml | 22 ++++++---------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/.github/workflows/stale.yaml b/.github/workflows/stale.yaml index a9953e69b08ac1..5adf4f408e768b 100644 --- a/.github/workflows/stale.yaml +++ b/.github/workflows/stale.yaml @@ -16,27 +16,17 @@ jobs: with: stale-issue-message: "This issue has been automatically marked as stale because - it has not had recent activity. It will be closed if no - further activity occurs. Remove stale label or comment or - this will be closed in 30 days." + it has not had recent activity." stale-pr-message: "This pull request has been automatically marked as stale - because it has not had recent activity. It will be closed - if no further activity occurs. Remove stale label or - comment or this will be closed in 10 days." + because it has not had recent activity." close-issue-message: "This stale issue has been automatically closed. Thank you for your contributions." close-pr-message: "This stale pull request has been automatically closed. Thank you for your contributions." - days-before-issue-stale: 30 - days-before-issue-close: -1 # Don't close them for now - days-before-pr-stale: 90 - days-before-pr-close: 10 - exempt-issue-labels: - "security,blocked,cert blocker,build issue,Spec XML - align,CI/CD improvements,memory" - exempt-pr-labels: - "security,blocked,cert blocker,build issue,Spec XML - align,CI/CD improvements,memory" + days-before-issue-stale: 180 + days-before-issue-close: -1 # Don't close stale issues + days-before-pr-stale: 180 + days-before-pr-close: -1 # Don't close stale PRs From 150db874c378d0e167127b1d0c38a3f195c059eb Mon Sep 17 00:00:00 2001 From: Yufeng Wang Date: Wed, 16 Oct 2024 14:42:45 -0700 Subject: [PATCH 011/149] [Fabric-Admin] Refactor to use API methods instead of PushCommand (3/3) (#36033) * [Fabric-Admin] Implement the bridge subscription API * Restyle * Address review comments * Reset the subscription state only in OnDone * Keep subscription --- examples/fabric-admin/BUILD.gn | 2 + .../commands/clusters/ReportCommand.cpp | 2 - .../device_manager/BridgeSubscription.cpp | 159 ++++++++++++++++++ .../device_manager/BridgeSubscription.h | 77 +++++++++ .../device_manager/DeviceManager.cpp | 27 +-- .../device_manager/DeviceManager.h | 3 + 6 files changed, 250 insertions(+), 20 deletions(-) create mode 100644 examples/fabric-admin/device_manager/BridgeSubscription.cpp create mode 100644 examples/fabric-admin/device_manager/BridgeSubscription.h diff --git a/examples/fabric-admin/BUILD.gn b/examples/fabric-admin/BUILD.gn index ab584459582657..38252cd30e7648 100644 --- a/examples/fabric-admin/BUILD.gn +++ b/examples/fabric-admin/BUILD.gn @@ -80,6 +80,8 @@ static_library("fabric-admin-utils") { "commands/pairing/OpenCommissioningWindowCommand.h", "commands/pairing/PairingCommand.cpp", "commands/pairing/ToTLVCert.cpp", + "device_manager/BridgeSubscription.cpp", + "device_manager/BridgeSubscription.h", "device_manager/DeviceManager.cpp", "device_manager/DeviceManager.h", "device_manager/DeviceSubscription.cpp", diff --git a/examples/fabric-admin/commands/clusters/ReportCommand.cpp b/examples/fabric-admin/commands/clusters/ReportCommand.cpp index 2fdb965ddc844c..df6f329896036c 100644 --- a/examples/fabric-admin/commands/clusters/ReportCommand.cpp +++ b/examples/fabric-admin/commands/clusters/ReportCommand.cpp @@ -72,6 +72,4 @@ void ReportCommand::OnEventData(const app::EventHeader & eventHeader, TLV::TLVRe } LogErrorOnFailure(RemoteDataModelLogger::LogEventAsJSON(eventHeader, data)); - - DeviceMgr().HandleEventData(eventHeader, *data); } diff --git a/examples/fabric-admin/device_manager/BridgeSubscription.cpp b/examples/fabric-admin/device_manager/BridgeSubscription.cpp new file mode 100644 index 00000000000000..2efcadaaa63ee5 --- /dev/null +++ b/examples/fabric-admin/device_manager/BridgeSubscription.cpp @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "BridgeSubscription.h" +#include + +using namespace ::chip; +using namespace ::chip::app; +using chip::app::ReadClient; + +namespace { + +constexpr uint16_t kSubscribeMinInterval = 0; +constexpr uint16_t kSubscribeMaxInterval = 60; + +void OnDeviceConnectedWrapper(void * context, Messaging::ExchangeManager & exchangeMgr, const SessionHandle & sessionHandle) +{ + reinterpret_cast(context)->OnDeviceConnected(exchangeMgr, sessionHandle); +} + +void OnDeviceConnectionFailureWrapper(void * context, const ScopedNodeId & peerId, CHIP_ERROR error) +{ + reinterpret_cast(context)->OnDeviceConnectionFailure(peerId, error); +} + +} // namespace + +BridgeSubscription::BridgeSubscription() : + mOnDeviceConnectedCallback(OnDeviceConnectedWrapper, this), + mOnDeviceConnectionFailureCallback(OnDeviceConnectionFailureWrapper, this) +{} + +CHIP_ERROR BridgeSubscription::StartSubscription(Controller::DeviceController & controller, NodeId nodeId, EndpointId endpointId) +{ + assertChipStackLockedByCurrentThread(); + + VerifyOrDie(!subscriptionStarted); // Ensure it's not called multiple times. + + // Mark as started + subscriptionStarted = true; + + mEndpointId = endpointId; + + CHIP_ERROR err = controller.GetConnectedDevice(nodeId, &mOnDeviceConnectedCallback, &mOnDeviceConnectionFailureCallback); + if (err != CHIP_NO_ERROR) + { + ChipLogError(NotSpecified, "Failed to connect to remote fabric sync bridge %" CHIP_ERROR_FORMAT, err.Format()); + } + return err; +} + +void BridgeSubscription::OnAttributeData(const ConcreteDataAttributePath & path, TLV::TLVReader * data, const StatusIB & status) +{ + if (!status.IsSuccess()) + { + ChipLogError(NotSpecified, "Response Failure: %" CHIP_ERROR_FORMAT, status.ToChipError().Format()); + return; + } + + if (data == nullptr) + { + ChipLogError(NotSpecified, "Response Failure: No Data"); + return; + } + + DeviceMgr().HandleAttributeData(path, *data); +} + +void BridgeSubscription::OnEventData(const app::EventHeader & eventHeader, TLV::TLVReader * data, const app::StatusIB * status) +{ + if (status != nullptr) + { + CHIP_ERROR error = status->ToChipError(); + if (CHIP_NO_ERROR != error) + { + ChipLogError(NotSpecified, "Response Failure: %" CHIP_ERROR_FORMAT, error.Format()); + return; + } + } + + if (data == nullptr) + { + ChipLogError(NotSpecified, "Response Failure: No Data"); + return; + } + + DeviceMgr().HandleEventData(eventHeader, *data); +} + +void BridgeSubscription::OnError(CHIP_ERROR error) +{ + ChipLogProgress(NotSpecified, "Error on remote fabric sync bridge subscription: %" CHIP_ERROR_FORMAT, error.Format()); +} + +void BridgeSubscription::OnDone(ReadClient * apReadClient) +{ + mClient.reset(); + ChipLogProgress(NotSpecified, "The remote fabric sync bridge subscription is terminated"); + + // Reset the subscription state to allow retry + subscriptionStarted = false; + + // TODO:(#36092) Fabric-Admin should attempt to re-subscribe when the subscription to the remote bridge is terminated. +} + +void BridgeSubscription::OnDeviceConnected(Messaging::ExchangeManager & exchangeMgr, const SessionHandle & sessionHandle) +{ + mClient = std::make_unique(app::InteractionModelEngine::GetInstance(), &exchangeMgr /* echangeMgr */, + *this /* callback */, ReadClient::InteractionType::Subscribe); + VerifyOrDie(mClient); + + AttributePathParams readPaths[1]; + readPaths[0] = AttributePathParams(mEndpointId, Clusters::Descriptor::Id, Clusters::Descriptor::Attributes::PartsList::Id); + + EventPathParams eventPaths[1]; + eventPaths[0] = EventPathParams(mEndpointId, Clusters::CommissionerControl::Id, + Clusters::CommissionerControl::Events::CommissioningRequestResult::Id); + eventPaths[0].mIsUrgentEvent = true; + + ReadPrepareParams readParams(sessionHandle); + + readParams.mpAttributePathParamsList = readPaths; + readParams.mAttributePathParamsListSize = 1; + readParams.mpEventPathParamsList = eventPaths; + readParams.mEventPathParamsListSize = 1; + readParams.mMinIntervalFloorSeconds = kSubscribeMinInterval; + readParams.mMaxIntervalCeilingSeconds = kSubscribeMaxInterval; + readParams.mKeepSubscriptions = true; + + CHIP_ERROR err = mClient->SendRequest(readParams); + + if (err != CHIP_NO_ERROR) + { + ChipLogError(NotSpecified, "Failed to issue subscription to the Descriptor Cluster of the remote bridged device."); + OnDone(nullptr); + return; + } +} + +void BridgeSubscription::OnDeviceConnectionFailure(const ScopedNodeId & peerId, CHIP_ERROR error) +{ + ChipLogError(NotSpecified, "BridgeSubscription failed to connect to " ChipLogFormatX64, ChipLogValueX64(peerId.GetNodeId())); + OnDone(nullptr); +} diff --git a/examples/fabric-admin/device_manager/BridgeSubscription.h b/examples/fabric-admin/device_manager/BridgeSubscription.h new file mode 100644 index 00000000000000..bd2a70279af065 --- /dev/null +++ b/examples/fabric-admin/device_manager/BridgeSubscription.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#pragma once + +#include +#include + +#include +#include + +/** + * @brief Class used to subscribe to attributes and events from the remote bridged device. + * + * The Descriptor Cluster contains attributes such as the Parts List, which provides a list + * of endpoints or devices that are part of a composite device or bridge. The CommissionerControl + * Cluster generates events related to commissioning requests, which can be monitored to track + * device commissioning status. + * + * When subscribing to attributes and events of a bridged device from another fabric, the class: + * - Establishes a secure session with the device (if needed) via CASE (Chip over + * Authenticated Session Establishment) session. + * - Subscribes to the specified attributes in the Descriptor Cluster (e.g., Parts List) and + * events in the CommissionerControl Cluster (e.g., CommissioningRequestResult) of the remote + * device on the specified node and endpoint. + * - Invokes the provided callback upon successful or unsuccessful subscription, allowing + * further handling of data or errors. + * + * This class also implements the necessary callbacks to handle attribute data reports, event data, + * errors, and session establishment procedures. + */ +class BridgeSubscription : public chip::app::ReadClient::Callback +{ +public: + BridgeSubscription(); + + CHIP_ERROR StartSubscription(chip::Controller::DeviceController & controller, chip::NodeId nodeId, chip::EndpointId endpointId); + + /////////////////////////////////////////////////////////////// + // ReadClient::Callback implementation + /////////////////////////////////////////////////////////////// + void OnAttributeData(const chip::app::ConcreteDataAttributePath & path, chip::TLV::TLVReader * data, + const chip::app::StatusIB & status) override; + void OnEventData(const chip::app::EventHeader & eventHeader, chip::TLV::TLVReader * data, + const chip::app::StatusIB * status) override; + void OnError(CHIP_ERROR error) override; + void OnDone(chip::app::ReadClient * apReadClient) override; + + /////////////////////////////////////////////////////////////// + // callbacks for CASE session establishment + /////////////////////////////////////////////////////////////// + void OnDeviceConnected(chip::Messaging::ExchangeManager & exchangeMgr, const chip::SessionHandle & sessionHandle); + void OnDeviceConnectionFailure(const chip::ScopedNodeId & peerId, CHIP_ERROR error); + +private: + std::unique_ptr mClient; + + chip::Callback::Callback mOnDeviceConnectedCallback; + chip::Callback::Callback mOnDeviceConnectionFailureCallback; + chip::EndpointId mEndpointId; + bool subscriptionStarted = false; +}; diff --git a/examples/fabric-admin/device_manager/DeviceManager.cpp b/examples/fabric-admin/device_manager/DeviceManager.cpp index 3a27c68184c8b0..2968bcf001e9bc 100644 --- a/examples/fabric-admin/device_manager/DeviceManager.cpp +++ b/examples/fabric-admin/device_manager/DeviceManager.cpp @@ -33,9 +33,6 @@ namespace { constexpr EndpointId kAggregatorEndpointId = 1; constexpr uint16_t kWindowTimeout = 300; constexpr uint16_t kIteration = 1000; -constexpr uint16_t kSubscribeMinInterval = 0; -constexpr uint16_t kSubscribeMaxInterval = 60; -constexpr uint16_t kAggragatorEndpointId = 1; constexpr uint16_t kMaxDiscriminatorLength = 4095; } // namespace @@ -193,23 +190,17 @@ void DeviceManager::UnpairLocalFabricBridge() void DeviceManager::SubscribeRemoteFabricBridge() { - // Listen to the state changes of the remote fabric bridge. - StringBuilder commandBuilder; - - // Prepare and push the descriptor subscribe command - commandBuilder.Add("descriptor subscribe parts-list "); - commandBuilder.AddFormat("%d %d %lu %d", kSubscribeMinInterval, kSubscribeMaxInterval, mRemoteBridgeNodeId, - kAggragatorEndpointId); - PushCommand(commandBuilder.c_str()); + ChipLogProgress(NotSpecified, "Start subscription to the remote bridge.") - // Clear the builder for the next command - commandBuilder.Reset(); + CHIP_ERROR error = mBridgeSubscriber.StartSubscription(PairingManager::Instance().CurrentCommissioner(), + mRemoteBridgeNodeId, kAggregatorEndpointId); - // Prepare and push the commissioner control subscribe command - commandBuilder.Add("commissionercontrol subscribe-event commissioning-request-result "); - commandBuilder.AddFormat("%d %d %lu %d --is-urgent true --keepSubscriptions true", kSubscribeMinInterval, kSubscribeMaxInterval, - mRemoteBridgeNodeId, kAggregatorEndpointId); - PushCommand(commandBuilder.c_str()); + if (error != CHIP_NO_ERROR) + { + ChipLogError(NotSpecified, "Failed to subscribe to the remote bridge (NodeId: %lu). Error: %" CHIP_ERROR_FORMAT, + mRemoteBridgeNodeId, error.Format()); + return; + } } void DeviceManager::ReadSupportedDeviceCategories() diff --git a/examples/fabric-admin/device_manager/DeviceManager.h b/examples/fabric-admin/device_manager/DeviceManager.h index 1514c417be4b4d..62d5ae045bb6af 100644 --- a/examples/fabric-admin/device_manager/DeviceManager.h +++ b/examples/fabric-admin/device_manager/DeviceManager.h @@ -19,6 +19,7 @@ #pragma once #include +#include #include #include @@ -209,6 +210,8 @@ class DeviceManager : public PairingDelegate bool mAutoSyncEnabled = false; bool mInitialized = false; uint64_t mRequestId = 0; + + BridgeSubscription mBridgeSubscriber; }; /** From e50084b48e0e68680902c272638521710efe650c Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Thu, 17 Oct 2024 09:18:44 -0400 Subject: [PATCH 012/149] Start an issue triage document to describe issue owners and maintainance (#36096) * Start an issue triage document * Restyle * Restyled by prettier-markdown * Triaged is a word * Move things around, added more notes, removed pyspelling * Update spell check exclude list * Restyled by prettier-markdown * Update docs/issue_triage.md Co-authored-by: jamesharrow <93921463+jamesharrow@users.noreply.github.com> * Cleanup based on review comments * Restyled by prettier-markdown * Add issue triage to the toc tree * Added apple home integration traging notes * Restyle * Fix link * Restyle * attempt to fix links even more ... this doc check is very strict --------- Co-authored-by: Restyled.io Co-authored-by: jamesharrow <93921463+jamesharrow@users.noreply.github.com> --- .github/.wordlist.txt | 2 + .spellcheck.yml | 2 +- docs/README.md | 5 ++ docs/index.md | 3 +- docs/issue_triage.md | 146 ++++++++++++++++++++++++++++++++++++++++++ 5 files changed, 156 insertions(+), 2 deletions(-) create mode 100644 docs/issue_triage.md diff --git a/.github/.wordlist.txt b/.github/.wordlist.txt index f3954d1eb89358..76485a2a013b9a 100644 --- a/.github/.wordlist.txt +++ b/.github/.wordlist.txt @@ -1452,6 +1452,8 @@ trackFree TransferSession transitionTime TransportMgrBase +triaged +triaging TriggerEffect TRNG trustm diff --git a/.spellcheck.yml b/.spellcheck.yml index 7313f64ebd6976..757034586b9bd0 100644 --- a/.spellcheck.yml +++ b/.spellcheck.yml @@ -65,7 +65,7 @@ matrix: # converts markdown to HTML - pyspelling.filters.markdown: sources: - - '**/*.md|!third_party/**|!examples/common/**/repo/**|!docs/ERROR_CODES.md|!docs/clusters.md|!docs/testing/yaml_schema.md|!docs/testing/yaml_pseudocluster.md | !docs/testing/python.md | !docs/testing/ChipDeviceCtrlAPI.md' + - '**/*.md|!third_party/**|!examples/common/**/repo/**|!docs/ERROR_CODES.md|!docs/clusters.md|!docs/testing/yaml_schema.md|!docs/testing/yaml_pseudocluster.md|!docs/testing/python.md|!docs/testing/ChipDeviceCtrlAPI.md|!docs/issue_triage.md' aspell: ignore-case: true camel-case: true diff --git a/docs/README.md b/docs/README.md index e5aad317e6d556..e96ab29f042f56 100644 --- a/docs/README.md +++ b/docs/README.md @@ -15,6 +15,11 @@ [Visual Studio Code](https://code.visualstudio.com/) can be found in [the development guide](./VSCODE_DEVELOPMENT.md) +## Issue triage + +Project issues are triaged and maintained according to the +[issue triage](./issue_triage.md) guide. + ## Platform Guides - Various guides are available [here](./guides/README.md) that cover platform diff --git a/docs/index.md b/docs/index.md index 6b7553f205ae1f..89e4661e2a0e1e 100644 --- a/docs/index.md +++ b/docs/index.md @@ -1,4 +1,4 @@ -# Welcome to Matter's documentation! +# Welcome to Matter's documentation ```{toctree} :maxdepth: 2 @@ -25,6 +25,7 @@ zap_clusters spec_clusters upgrading ERROR_CODES +issue_triage ``` diff --git a/docs/issue_triage.md b/docs/issue_triage.md new file mode 100644 index 00000000000000..891bfca4716a84 --- /dev/null +++ b/docs/issue_triage.md @@ -0,0 +1,146 @@ +# Project issues + +General issues are listed at + . + +In order to be able to effectively follow up on these issues, they are separated +into groups for further review and fixing based on current maintainers on +specific areas of the code. The separation is done via `labels`. + +Issues that still need triaging are labeled as `needs triage`: + + + +## Non-SDK issues + +In some cases the issue is integrating with ecosystems or environments are not +supported. In these cases, issues can be re-directed to specific support pages +rather than the SDK GitHub issues. + +### Google Integration + +- General integration link: +- Support via the communities areas: + - Stack overflow: + + - Google Nest Community: + + +### Apple Integration + +This applies if there is an issue with Home interacting with a device (as +opposed to an issue with Matter.framework or the SDK that is encountered by code +actually running on darwin). + +General instructions available at [here](./guides/darwin.md) in the +`Providing feedback to Apple` section. + +Once a Feedback Assistant ticket is filed, the ticket ID can be sent to Boris +Zbkarsky to ensure it is noticed by the right people + +### Environments not currently supported / not maintained + +Some items are explicitly not maintained currently + +- Windows integration: no official maintainer for this so currently not + supported +- Old compiler support: CHIP requires a C++17 or higher compiler. + +## Platform maintainers + +This level of separation is generally for platform-specific issues (e.g. failure +to commission for one specific platform, failure to run on some specific +operating system). + +Contact is generally done on slack. E-mail addresses are not added here on +purpose in order to avoid spam. + +| Platform | Contact | Label | Note(s) | +| ------------ | --------------------------------------- | -------------------------------------------------------------------------------------------------------- | ------- | +| Android | Andrei Litvin, Yunhan Wang, Yufeng Wang | [android](https://github.com/project-chip/connectedhomeip/issues?q=is%3Aopen+is%3Aissue+label%3Aandroid) | | +| Darwin | Boris Zbarsky, Justin Wood | [darwin](https://github.com/project-chip/connectedhomeip/issues?q=is%3Aopen+is%3Aissue+label%3Adarwin) | | +| Espressif | Hrishikesh Dhayagude | [esp32](https://github.com/project-chip/connectedhomeip/issues?q=is%3Aopen+is%3Aissue+label%3Aesp32) | | +| Linux | Andrei Litvin | [linux](https://github.com/project-chip/connectedhomeip/issues?q=is%3Aopen+is%3Aissue+label%3Alinux) | | +| Nordic | Lucasz Duda | [nrf](https://github.com/project-chip/connectedhomeip/issues?q=is%3Aopen+is%3Aissue+label%3Anrf) | | +| NXP | Doru Gucea | [nxp](https://github.com/project-chip/connectedhomeip/issues?q=is%3Aopen+is%3Aissue+label%3Anxp) | | +| Silabs/EFR32 | Jean Francois Penven, Junior Martinez | [efr32](https://github.com/project-chip/connectedhomeip/issues?q=is%3Aopen+is%3Aissue+label%3Aefr32) | | + +## Code areas + +The following people can be contacted about issues in specific area of code are +affected that are not platform-specific. + +| Code area | Contact | Label | Note(s) | +| ------------------------------------- | -------------------------------- | ------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| ARM cross-compile | Andrei Litvin | N/A | Some support for cross-compiling on x64 linux for arm64 linux (like Raspberry PI) | +| Build system (darwin, xcode) | Boris Zbarsky, Justin Wood | N/A | darwin specific builds, xcode connector | +| Build system (gn, ninja) | Andrei Litvin | N/A | General build system questions and gn support, generally on Linux | +| MatterIDL | Andrei Litvin | N/A | General .matter files and code generation based on it | +| Minimal MDNS | Andrei Litvin | N/A | mdns specfic. Note that platformdns also exists and issues are often "DNSSD" rather than minmdns specific | +| Python testing infrastructure/helpers | Cecille Freeman | N/A | Writing tests cases in python. **NOTE** this is for test infrastrure and NOT for individual test issues. Test case failures are associated with test applications or the test case script. | +| ZAP Code Generation | Boris Zbarsky, Bharat Raju Dandu | [zap](https://github.com/project-chip/connectedhomeip/issues?q=is%3Aopen+is%3Aissue+label%3Azap) | Some issues may be in the zap project itself. This is for generic code generation issues and help, often regarding `.zapt` templates | +| src/crypto, src/credentials | Tennessee Carmel-Veilleux | N/A | | + +## Example maintenance + +Examples often correspond to specific device types. We have split the contact +per device type regardless of example (e.g. all-clusters will contain all device +types or functionality) as well as individual examples. + +### Per device type + +| Device Type(s) | Contact | Label | Note(s) | +| -------------------------- | ---------------------------- | ------------------------------------------------------------------------------------------------------------ | ------- | +| Fabric Bridge, Fabric Sync | Yufeng Wang, Terence Hampson | [fabric-sync](https://github.com/project-chip/connectedhomeip/pulls?q=is%3Aopen+is%3Apr+label%3Afabric-sync) | | + +### Per example + +| Example path | Contact | Note(s) | +| ---------------------------------------------- | ---------------------------- | ------------ | +| `examples/air-purifier-app` | | UNMAINTAINED | +| `examples/air-quality-sensor-app` | | UNMAINTAINED | +| `examples/all-clusters-app` | | UNMAINTAINED | +| `examples/all-clusters-minimal-app` | | UNMAINTAINED | +| `examples/android` | Yunhan Wang | | +| `examples/bridge-app` | | UNMAINTAINED | +| `examples/build_overrides` | | UNMAINTAINED | +| `examples/chef` | Andrei Litvin | | +| `examples/chip-tool` | | UNMAINTAINED | +| `examples/contact-sensor-app` | | UNMAINTAINED | +| `examples/darwin-framework-tool` | Boris Zbarsky | | +| `examples/dishwasher-app` | | UNMAINTAINED | +| `examples/energy-management-app` | James Harrow | | +| `examples/fabric-admin` | Yufeng Wang, Terence Hampson | | +| `examples/fabric-bridge-app` | Yufeng Wang, Terence Hampson | | +| `examples/java-matter-controller` | Yunhan Wang, Yufeng Wang | | +| `examples/kotlin-matter-controller` | Yunhan Wang, Yufeng Wang | | +| `examples/laundry-washer-app` | | UNMAINTAINED | +| `examples/lighting-app` | Junior Martinez | | +| `examples/lighting-app-data-mode-no-unique-id` | | UNMAINTAINED | +| `examples/light-switch-app` | | UNMAINTAINED | +| `examples/lit-icd-app` | Yunhan Wang | | +| `examples/lock-app` | | UNMAINTAINED | +| `examples/log-source-app` | | UNMAINTAINED | +| `examples/microwave-oven-app` | Rob Bultman | | +| `examples/minimal-mdns` | Andrei Litvin | | +| `examples/network-manager-app` | Thomas Lea | | +| `examples/ota-provider-app` | | UNMAINTAINED | +| `examples/ota-requestor-app` | | UNMAINTAINED | +| `examples/persistent-storage` | | UNMAINTAINED | +| `examples/pigweed-app` | | UNMAINTAINED | +| `examples/placeholder` | | UNMAINTAINED | +| `examples/providers` | | UNMAINTAINED | +| `examples/pump-app` | | UNMAINTAINED | +| `examples/pump-controller-app` | | UNMAINTAINED | +| `examples/refrigerator-app` | | UNMAINTAINED | +| `examples/resource-monitoring-app` | | UNMAINTAINED | +| `examples/rvc-app` | | UNMAINTAINED | +| `examples/smoke-co-alarm-app` | | UNMAINTAINED | +| `examples/temperature-measurement-app` | | UNMAINTAINED | +| `examples/thermostat` | | UNMAINTAINED | +| `examples/thread-br-app` | | UNMAINTAINED | +| `examples/tv-app` | Chris DeCenzo, Lazar Kovacic | | +| `examples/tv-casting-app` | Chris DeCenzo, Lazar Kovacic | | +| `examples/virtual-device-app` | | UNMAINTAINED | +| `examples/water-leak-detector-app` | | UNMAINTAINED | +| `examples/window-app` | | UNMAINTAINED | From 1a38286a552f0b41d9f0147bc73fc9e7fa232c6c Mon Sep 17 00:00:00 2001 From: jamesharrow <93921463+jamesharrow@users.noreply.github.com> Date: Thu, 17 Oct 2024 14:25:05 +0100 Subject: [PATCH 013/149] DEMM, WHM, EVSEM to disallow OnMode/StartupMode in All-Clusters-App (#36106) * Fixes #36074, #36073, #36072 - remove OnMode and Startup Mode from all-clusters-app.zap in DEMM, EEVSEM, WHM * Fixes #36074, #36073, #36072 - remove OnMode and Startup Mode from all-clusters-app.zap in DEMM, EEVSEM, WHM --- .../all-clusters-app.matter | 6 - .../all-clusters-common/all-clusters-app.zap | 143 ++++-------------- 2 files changed, 31 insertions(+), 118 deletions(-) diff --git a/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter b/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter index 45e58fffca24ea..aa3ef44b066cdd 100644 --- a/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter +++ b/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter @@ -8774,8 +8774,6 @@ endpoint 1 { server cluster EnergyEvseMode { callback attribute supportedModes; callback attribute currentMode; - ram attribute startUpMode; - ram attribute onMode; callback attribute generatedCommandList; callback attribute acceptedCommandList; callback attribute eventList; @@ -8790,8 +8788,6 @@ endpoint 1 { server cluster WaterHeaterMode { callback attribute supportedModes; callback attribute currentMode; - ram attribute startUpMode; - ram attribute onMode; callback attribute generatedCommandList; callback attribute acceptedCommandList; callback attribute eventList; @@ -8806,8 +8802,6 @@ endpoint 1 { server cluster DeviceEnergyManagementMode { callback attribute supportedModes; callback attribute currentMode; - ram attribute startUpMode; - ram attribute onMode; callback attribute generatedCommandList; callback attribute acceptedCommandList; callback attribute eventList; diff --git a/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap b/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap index f8e3dbd8806c3f..741812bc3c2b26 100644 --- a/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap +++ b/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap @@ -1,6 +1,6 @@ { "fileFormat": 2, - "featureLevel": 103, + "featureLevel": 104, "creator": "zap", "keyValuePairs": [ { @@ -41,20 +41,23 @@ "code": 17, "profileId": 259, "label": "MA-powersource", - "name": "MA-powersource" + "name": "MA-powersource", + "deviceTypeOrder": 0 }, "deviceTypes": [ { "code": 17, "profileId": 259, "label": "MA-powersource", - "name": "MA-powersource" + "name": "MA-powersource", + "deviceTypeOrder": 0 }, { "code": 22, "profileId": 259, "label": "MA-rootdevice", - "name": "MA-rootdevice" + "name": "MA-rootdevice", + "deviceTypeOrder": 1 } ], "deviceVersions": [ @@ -6102,20 +6105,23 @@ "code": 256, "profileId": 259, "label": "MA-onofflight", - "name": "MA-onofflight" + "name": "MA-onofflight", + "deviceTypeOrder": 0 }, "deviceTypes": [ { "code": 256, "profileId": 259, "label": "MA-onofflight", - "name": "MA-onofflight" + "name": "MA-onofflight", + "deviceTypeOrder": 0 }, { "code": 17, "profileId": 259, "label": "MA-powersource", - "name": "MA-powersource" + "name": "MA-powersource", + "deviceTypeOrder": 1 } ], "deviceVersions": [ @@ -14526,38 +14532,6 @@ "maxInterval": 65534, "reportableChange": 0 }, - { - "name": "StartUpMode", - "code": 2, - "mfgCode": null, - "side": "server", - "type": "int8u", - "included": 1, - "storageOption": "RAM", - "singleton": 0, - "bounded": 0, - "defaultValue": "", - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "OnMode", - "code": 3, - "mfgCode": null, - "side": "server", - "type": "int8u", - "included": 1, - "storageOption": "RAM", - "singleton": 0, - "bounded": 0, - "defaultValue": "", - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, { "name": "GeneratedCommandList", "code": 65528, @@ -14714,38 +14688,6 @@ "maxInterval": 65534, "reportableChange": 0 }, - { - "name": "StartUpMode", - "code": 2, - "mfgCode": null, - "side": "server", - "type": "int8u", - "included": 1, - "storageOption": "RAM", - "singleton": 0, - "bounded": 0, - "defaultValue": "", - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "OnMode", - "code": 3, - "mfgCode": null, - "side": "server", - "type": "int8u", - "included": 1, - "storageOption": "RAM", - "singleton": 0, - "bounded": 0, - "defaultValue": "", - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, { "name": "GeneratedCommandList", "code": 65528, @@ -14903,38 +14845,6 @@ "maxInterval": 65534, "reportableChange": 0 }, - { - "name": "StartUpMode", - "code": 2, - "mfgCode": null, - "side": "server", - "type": "int8u", - "included": 1, - "storageOption": "RAM", - "singleton": 0, - "bounded": 0, - "defaultValue": "", - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "OnMode", - "code": 3, - "mfgCode": null, - "side": "server", - "type": "int8u", - "included": 1, - "storageOption": "RAM", - "singleton": 0, - "bounded": 0, - "defaultValue": "", - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, { "name": "GeneratedCommandList", "code": 65528, @@ -23363,20 +23273,23 @@ "code": 256, "profileId": 259, "label": "MA-onofflight", - "name": "MA-onofflight" + "name": "MA-onofflight", + "deviceTypeOrder": 0 }, "deviceTypes": [ { "code": 256, "profileId": 259, "label": "MA-onofflight", - "name": "MA-onofflight" + "name": "MA-onofflight", + "deviceTypeOrder": 0 }, { "code": 17, "profileId": 259, "label": "MA-powersource", - "name": "MA-powersource" + "name": "MA-powersource", + "deviceTypeOrder": 1 } ], "deviceVersions": [ @@ -24815,14 +24728,16 @@ "code": 15, "profileId": 259, "label": "MA-genericswitch", - "name": "MA-genericswitch" + "name": "MA-genericswitch", + "deviceTypeOrder": 0 }, "deviceTypes": [ { "code": 15, "profileId": 259, "label": "MA-genericswitch", - "name": "MA-genericswitch" + "name": "MA-genericswitch", + "deviceTypeOrder": 0 } ], "deviceVersions": [ @@ -25274,14 +25189,16 @@ "code": 15, "profileId": 259, "label": "MA-genericswitch", - "name": "MA-genericswitch" + "name": "MA-genericswitch", + "deviceTypeOrder": 0 }, "deviceTypes": [ { "code": 15, "profileId": 259, "label": "MA-genericswitch", - "name": "MA-genericswitch" + "name": "MA-genericswitch", + "deviceTypeOrder": 0 } ], "deviceVersions": [ @@ -25685,14 +25602,16 @@ "code": 25, "profileId": 259, "label": "MA-secondary-network-interface", - "name": "MA-secondary-network-interface" + "name": "MA-secondary-network-interface", + "deviceTypeOrder": 0 }, "deviceTypes": [ { "code": 25, "profileId": 259, "label": "MA-secondary-network-interface", - "name": "MA-secondary-network-interface" + "name": "MA-secondary-network-interface", + "deviceTypeOrder": 0 } ], "deviceVersions": [ From 97afd9235f154105451174da8e097a0730a0167b Mon Sep 17 00:00:00 2001 From: jby-nxp <113013617+jby-nxp@users.noreply.github.com> Date: Thu, 17 Oct 2024 15:29:18 +0200 Subject: [PATCH 014/149] NXP : Add support of RT1060 and RT1170 boards (#35842) * [NXP][rt1170] Matter enablement on RT1170 It includes: - Matter port files for RT1170 - example files for Laundry-washer, thermostat and all-cluster-app - documentations Signed-off-by: Gatien Chapon [border router][rt1170] RT1170 platform and README updates to support OTBR with new OT stack version (cherry picked from commit f97d5c58c866774c787ec4417bca075ce45eece0) [platform][rt1170] Enable lwip and ephemeral key CLI addons (cherry picked from commit fb3320eabd3c3f6c8c75c4094d6426fcc0cfed57) [2.16][rt1170] SDK 2.16 rt1170 API name changed Signed-off-by: Gatien Chapon (cherry picked from commit 67f183263466267bc1c7da6fd3a05743fd268ea2) Signed-off-by: Gatien Chapon [examples][rt1170] Enable Disgnostic log for thermostat app Signed-off-by: Martin Girardot (cherry picked from commit cce6267446d035e7966c7f5f17d112fb5f1557c5) [platform][rt1170] Rename rt_nvm_component to nxp_nvm_component Signed-off-by: Dina Benamar (cherry picked from commit f5fb5f4e8b2be45fc97c2a7c7a2d5a453adf9b34) [doc][rt1170] update OTA guidelines to generate mcuboot binary (cherry picked from commit 27f58810a07343234d0d884f385eb407998a9220) * [NXP][rt1060] Adding RT1060 Matter support It includes following changes: - Matter port files for RT1060 - examples support for Laundry-washer, thermostat and all-cluster-app - Support for configurations: RT1060 evkb+8801, RT1060 evkb+IW416, RT1060 evkc+IW612 and RT1060 evkb+k32w0 Signed-off-by: Gatien Chapon [platform][rt1060] Rename rt_nvm_component to nxp_nvm_component Signed-off-by: Dina Benamar (cherry picked from commit 316450da02b365aa61bcb53a0dc6b50512fb6435) [border router][rt1060] RT1060 platform and README updates to support OTBR with new OT stack version (cherry picked from commit 231a4c15c4abca40d5759194fb61b9636c8f67e8) [platform][rt1060] Enable lwip and ephemeral key CLI addons (cherry picked from commit 463749a12abcc68fc5f6569f98c27b574b3516bd) [2.16][rt1060] SDK 2.16 rt1060 API name changed Signed-off-by: Gatien Chapon (cherry picked from commit 42f7d8771329172aaeedfde1b2bab86b1799f6d9) [examples][rt1060] Enable Diagnostic log for thermostat app Signed-off-by: Martin Girardot (cherry picked from commit 7c4cbeb41d3a00ec90525bb084f7bc278d5ecb8e) * [NXP][rt1060][doc] Update WiFi build instructions * [NXP][border router][rt1060] Platform updates to support TBR cluster and secondary nwk if A new gn variable was created, chip_enable_secondary_nwk_if, to enable or disable Thread as secondary network commissioning interface when building with BR support. * [NXP][border router][rt1170] Platform updates to support TBR cluster and secondary nwk if A new gn variable was created, chip_enable_secondary_nwk_if, to enable or disable Thread as secondary network commissioning interface when building with BR support. * [NXP] Add targets RT1060 and RT1170 to NXP builds * [NXP][OTA][doc] update OTA doc for RTs boards * [NXP][border router][rt1060] fix compilation issue * [NXP][border router][rt1170] fix compilation issue * [NXP][doc][rt1060] minor changes * [NXP] [rt1060] OTA requestor enablement on RT1060-EVKC+Firecrest * [NXP] Add OTA variant to RT1060 and RT1170 builds * [NXP][doc][rt] changes since workflow feedback * [NXP][examples][rt1060] Update empty button registration path Signed-off-by: marius-alex-tache * [NXP][examples][rt1170] Update empty button registration path Signed-off-by: marius-alex-tache * [NXP] [gn] Restyle gn files * [NXP][doc] Restyle md files * [NXP] Restyle build scripts * [NXP][RT] fix OTBR compile issue * [NXP][RT][doc] rework documentation * [NXP] Reduce and collapse NXP targets list * [NXP] filter which target to be build on PR * [NXP] [rt1170] remove useless flag * [NXP] [rt1060] remove useless flag * [NXP] [doc] fix path to referenced docs since NXP documentation moved --------- Signed-off-by: marius-alex-tache Co-authored-by: Gatien Chapon Co-authored-by: Mihai Ignat Co-authored-by: Marius Preda Co-authored-by: marius-alex-tache Co-authored-by: Restyled.io --- .github/.wordlist.txt | 3 + .github/workflows/examples-nxp.yaml | 241 +++--- docs/platforms/nxp/index.md | 2 +- ...date.md => nxp_RTs_ota_software_update.md} | 144 +++- examples/all-clusters-app/nxp/rt/rt1060/.gn | 35 + .../all-clusters-app/nxp/rt/rt1060/BUILD.gn | 284 +++++++ .../all-clusters-app/nxp/rt/rt1060/README.md | 723 ++++++++++++++++++ .../all-clusters-app/nxp/rt/rt1060/args.gni | 19 + .../nxp/rt/rt1060/build_overrides | 1 + .../rt1060/include/config/CHIPProjectConfig.h | 216 ++++++ .../nxp/rt/rt1060/third_party/connectedhomeip | 1 + examples/all-clusters-app/nxp/rt/rt1170/.gn | 35 + .../all-clusters-app/nxp/rt/rt1170/BUILD.gn | 241 ++++++ .../all-clusters-app/nxp/rt/rt1170/README.md | 505 ++++++++++++ .../all-clusters-app/nxp/rt/rt1170/args.gni | 19 + .../nxp/rt/rt1170/build_overrides | 1 + .../rt1170/include/config/CHIPProjectConfig.h | 216 ++++++ .../nxp/rt/rt1170/third_party/connectedhomeip | 1 + .../all-clusters-app/nxp/rt/rw61x/README.md | 4 +- examples/laundry-washer-app/nxp/rt/rt1060/.gn | 35 + .../laundry-washer-app/nxp/rt/rt1060/BUILD.gn | 291 +++++++ .../nxp/rt/rt1060/README.md | 5 + .../laundry-washer-app/nxp/rt/rt1060/args.gni | 25 + .../nxp/rt/rt1060/build_overrides | 1 + .../rt1060/include/config/CHIPProjectConfig.h | 216 ++++++ .../nxp/rt/rt1060/third_party/connectedhomeip | 1 + examples/laundry-washer-app/nxp/rt/rt1170/.gn | 35 + .../laundry-washer-app/nxp/rt/rt1170/BUILD.gn | 246 ++++++ .../nxp/rt/rt1170/README.md | 5 + .../laundry-washer-app/nxp/rt/rt1170/args.gni | 25 + .../nxp/rt/rt1170/build_overrides | 1 + .../rt1170/include/config/CHIPProjectConfig.h | 216 ++++++ .../nxp/rt/rt1170/third_party/connectedhomeip | 1 + .../rt1060/doc/images/MIMXRT1060-EVKB-TOP.png | Bin 0 -> 314604 bytes .../nxp/rt/rt1060/doc/images/debug0.png | Bin 0 -> 70142 bytes .../nxp/rt/rt1060/doc/images/debug1.png | Bin 0 -> 50913 bytes .../nxp/rt/rt1060/doc/images/flash_driver.png | Bin 0 -> 139127 bytes .../nxp/rt/rt1060/doc/images/gdbdebugger.png | Bin 0 -> 131147 bytes .../doc/images/import-local-repository.png | Bin 0 -> 53399 bytes .../rt/rt1060/doc/images/import-sdk-git.png | Bin 0 -> 26971 bytes .../nxp/rt/rt1060/doc/images/mcu-set.png | Bin 0 -> 133499 bytes .../images/rt1060_evkc_IW612_hw_rework.jpg | Bin 0 -> 68930 bytes .../rt1060_evkc_IW612_hw_rework_detail.jpg | Bin 0 -> 40681 bytes .../images/rt1060_k32w061_pin_settings.jpg | Bin 0 -> 396048 bytes .../nxp/rt/rt1060/doc/images/select-sdk.png | Bin 0 -> 138646 bytes .../nxp/rt/rt1060/doc/images/startup.png | Bin 0 -> 127461 bytes .../nxp/rt/rt1060/doc/images/toolchain.JPG | Bin 0 -> 129143 bytes .../source/AppFactoryDataExample.cpp | 77 ++ examples/platform/nxp/rt/rt1170/BUILD.gn | 24 + .../rt1170/doc/images/IMX-RT1170-EVK-TOP.jpg | Bin 0 -> 438253 bytes .../nxp/rt/rt1170/doc/images/debug0.png | Bin 0 -> 76697 bytes .../nxp/rt/rt1170/doc/images/flash_driver.png | Bin 0 -> 180088 bytes .../nxp/rt/rt1170/doc/images/iwx612_2EL.jpg | Bin 0 -> 30285 bytes .../nxp/rt/rt1170/doc/images/mcu-set.png | Bin 0 -> 158274 bytes .../nxp/rt/rt1170/doc/images/mcuboot_demo.PNG | Bin 0 -> 87011 bytes .../rt1170/doc/images/mcuboot_swap_config.png | Bin 0 -> 238186 bytes .../doc/images/murata_usd-M2_adapter.jpg | Bin 0 -> 35724 bytes .../images/murata_usd-m2_connections_1.jpg | Bin 0 -> 67831 bytes .../images/murata_usd-m2_connections_2.jpg | Bin 0 -> 78898 bytes .../nxp/rt/rt1170/doc/images/select-sdk.png | Bin 0 -> 126030 bytes .../nxp/rt/rt1170/doc/images/startup.png | Bin 0 -> 76388 bytes .../nxp/rt/rt1170/doc/images/toolchain.JPG | Bin 0 -> 129143 bytes examples/thermostat/nxp/rt/rt1060/.gn | 35 + examples/thermostat/nxp/rt/rt1060/BUILD.gn | 304 ++++++++ examples/thermostat/nxp/rt/rt1060/README.md | 5 + examples/thermostat/nxp/rt/rt1060/args.gni | 19 + .../thermostat/nxp/rt/rt1060/build_overrides | 1 + .../rt1060/include/config/CHIPProjectConfig.h | 216 ++++++ .../nxp/rt/rt1060/third_party/connectedhomeip | 1 + examples/thermostat/nxp/rt/rt1170/.gn | 35 + examples/thermostat/nxp/rt/rt1170/BUILD.gn | 257 +++++++ examples/thermostat/nxp/rt/rt1170/README.md | 5 + examples/thermostat/nxp/rt/rt1170/args.gni | 19 + .../thermostat/nxp/rt/rt1170/build_overrides | 1 + .../rt1170/include/config/CHIPProjectConfig.h | 216 ++++++ .../nxp/rt/rt1170/third_party/connectedhomeip | 1 + scripts/build/build/targets.py | 16 +- scripts/build/builders/nxp.py | 47 +- .../build/testdata/all_targets_linux_x64.txt | 2 +- src/platform/nxp/rt/rt1060/BUILD.gn | 187 +++++ .../nxp/rt/rt1060/BlePlatformConfig.h | 36 + .../nxp/rt/rt1060/CHIPDevicePlatformConfig.h | 42 + .../nxp/rt/rt1060/CHIPPlatformConfig.h | 54 ++ .../nxp/rt/rt1060/FactoryDataProviderImpl.cpp | 381 +++++++++ .../nxp/rt/rt1060/FactoryDataProviderImpl.h | 104 +++ .../nxp/rt/rt1060/InetPlatformConfig.h | 40 + .../nxp/rt/rt1060/PlatformManagerImpl.cpp | 548 +++++++++++++ .../nxp/rt/rt1060/SystemPlatformConfig.h | 40 + src/platform/nxp/rt/rt1060/args.gni | 57 ++ src/platform/nxp/rt/rt1170/BUILD.gn | 190 +++++ .../nxp/rt/rt1170/BlePlatformConfig.h | 36 + .../nxp/rt/rt1170/CHIPDevicePlatformConfig.h | 42 + .../nxp/rt/rt1170/CHIPPlatformConfig.h | 54 ++ .../nxp/rt/rt1170/InetPlatformConfig.h | 40 + .../nxp/rt/rt1170/PlatformManagerImpl.cpp | 474 ++++++++++++ .../nxp/rt/rt1170/SystemPlatformConfig.h | 40 + src/platform/nxp/rt/rt1170/args.gni | 62 ++ .../platforms/nxp/rt/rt1060/BUILD.gn | 150 ++++ .../platforms/nxp/rt/rt1170/BUILD.gn | 142 ++++ 99 files changed, 7602 insertions(+), 192 deletions(-) rename docs/platforms/nxp/{nxp_rw61x_ota_software_update.md => nxp_RTs_ota_software_update.md} (68%) create mode 100644 examples/all-clusters-app/nxp/rt/rt1060/.gn create mode 100644 examples/all-clusters-app/nxp/rt/rt1060/BUILD.gn create mode 100644 examples/all-clusters-app/nxp/rt/rt1060/README.md create mode 100644 examples/all-clusters-app/nxp/rt/rt1060/args.gni create mode 120000 examples/all-clusters-app/nxp/rt/rt1060/build_overrides create mode 100644 examples/all-clusters-app/nxp/rt/rt1060/include/config/CHIPProjectConfig.h create mode 120000 examples/all-clusters-app/nxp/rt/rt1060/third_party/connectedhomeip create mode 100644 examples/all-clusters-app/nxp/rt/rt1170/.gn create mode 100644 examples/all-clusters-app/nxp/rt/rt1170/BUILD.gn create mode 100644 examples/all-clusters-app/nxp/rt/rt1170/README.md create mode 100644 examples/all-clusters-app/nxp/rt/rt1170/args.gni create mode 120000 examples/all-clusters-app/nxp/rt/rt1170/build_overrides create mode 100644 examples/all-clusters-app/nxp/rt/rt1170/include/config/CHIPProjectConfig.h create mode 120000 examples/all-clusters-app/nxp/rt/rt1170/third_party/connectedhomeip create mode 100644 examples/laundry-washer-app/nxp/rt/rt1060/.gn create mode 100644 examples/laundry-washer-app/nxp/rt/rt1060/BUILD.gn create mode 100644 examples/laundry-washer-app/nxp/rt/rt1060/README.md create mode 100644 examples/laundry-washer-app/nxp/rt/rt1060/args.gni create mode 120000 examples/laundry-washer-app/nxp/rt/rt1060/build_overrides create mode 100644 examples/laundry-washer-app/nxp/rt/rt1060/include/config/CHIPProjectConfig.h create mode 120000 examples/laundry-washer-app/nxp/rt/rt1060/third_party/connectedhomeip create mode 100644 examples/laundry-washer-app/nxp/rt/rt1170/.gn create mode 100644 examples/laundry-washer-app/nxp/rt/rt1170/BUILD.gn create mode 100644 examples/laundry-washer-app/nxp/rt/rt1170/README.md create mode 100644 examples/laundry-washer-app/nxp/rt/rt1170/args.gni create mode 120000 examples/laundry-washer-app/nxp/rt/rt1170/build_overrides create mode 100644 examples/laundry-washer-app/nxp/rt/rt1170/include/config/CHIPProjectConfig.h create mode 120000 examples/laundry-washer-app/nxp/rt/rt1170/third_party/connectedhomeip create mode 100644 examples/platform/nxp/rt/rt1060/doc/images/MIMXRT1060-EVKB-TOP.png create mode 100644 examples/platform/nxp/rt/rt1060/doc/images/debug0.png create mode 100644 examples/platform/nxp/rt/rt1060/doc/images/debug1.png create mode 100644 examples/platform/nxp/rt/rt1060/doc/images/flash_driver.png create mode 100644 examples/platform/nxp/rt/rt1060/doc/images/gdbdebugger.png create mode 100644 examples/platform/nxp/rt/rt1060/doc/images/import-local-repository.png create mode 100644 examples/platform/nxp/rt/rt1060/doc/images/import-sdk-git.png create mode 100644 examples/platform/nxp/rt/rt1060/doc/images/mcu-set.png create mode 100644 examples/platform/nxp/rt/rt1060/doc/images/rt1060_evkc_IW612_hw_rework.jpg create mode 100644 examples/platform/nxp/rt/rt1060/doc/images/rt1060_evkc_IW612_hw_rework_detail.jpg create mode 100644 examples/platform/nxp/rt/rt1060/doc/images/rt1060_k32w061_pin_settings.jpg create mode 100644 examples/platform/nxp/rt/rt1060/doc/images/select-sdk.png create mode 100644 examples/platform/nxp/rt/rt1060/doc/images/startup.png create mode 100644 examples/platform/nxp/rt/rt1060/doc/images/toolchain.JPG create mode 100644 examples/platform/nxp/rt/rt1060/factory_data/source/AppFactoryDataExample.cpp create mode 100644 examples/platform/nxp/rt/rt1170/BUILD.gn create mode 100644 examples/platform/nxp/rt/rt1170/doc/images/IMX-RT1170-EVK-TOP.jpg create mode 100644 examples/platform/nxp/rt/rt1170/doc/images/debug0.png create mode 100644 examples/platform/nxp/rt/rt1170/doc/images/flash_driver.png create mode 100644 examples/platform/nxp/rt/rt1170/doc/images/iwx612_2EL.jpg create mode 100644 examples/platform/nxp/rt/rt1170/doc/images/mcu-set.png create mode 100644 examples/platform/nxp/rt/rt1170/doc/images/mcuboot_demo.PNG create mode 100644 examples/platform/nxp/rt/rt1170/doc/images/mcuboot_swap_config.png create mode 100644 examples/platform/nxp/rt/rt1170/doc/images/murata_usd-M2_adapter.jpg create mode 100644 examples/platform/nxp/rt/rt1170/doc/images/murata_usd-m2_connections_1.jpg create mode 100644 examples/platform/nxp/rt/rt1170/doc/images/murata_usd-m2_connections_2.jpg create mode 100644 examples/platform/nxp/rt/rt1170/doc/images/select-sdk.png create mode 100644 examples/platform/nxp/rt/rt1170/doc/images/startup.png create mode 100644 examples/platform/nxp/rt/rt1170/doc/images/toolchain.JPG create mode 100644 examples/thermostat/nxp/rt/rt1060/.gn create mode 100644 examples/thermostat/nxp/rt/rt1060/BUILD.gn create mode 100644 examples/thermostat/nxp/rt/rt1060/README.md create mode 100644 examples/thermostat/nxp/rt/rt1060/args.gni create mode 120000 examples/thermostat/nxp/rt/rt1060/build_overrides create mode 100644 examples/thermostat/nxp/rt/rt1060/include/config/CHIPProjectConfig.h create mode 120000 examples/thermostat/nxp/rt/rt1060/third_party/connectedhomeip create mode 100644 examples/thermostat/nxp/rt/rt1170/.gn create mode 100644 examples/thermostat/nxp/rt/rt1170/BUILD.gn create mode 100644 examples/thermostat/nxp/rt/rt1170/README.md create mode 100644 examples/thermostat/nxp/rt/rt1170/args.gni create mode 120000 examples/thermostat/nxp/rt/rt1170/build_overrides create mode 100644 examples/thermostat/nxp/rt/rt1170/include/config/CHIPProjectConfig.h create mode 120000 examples/thermostat/nxp/rt/rt1170/third_party/connectedhomeip create mode 100644 src/platform/nxp/rt/rt1060/BUILD.gn create mode 100644 src/platform/nxp/rt/rt1060/BlePlatformConfig.h create mode 100644 src/platform/nxp/rt/rt1060/CHIPDevicePlatformConfig.h create mode 100644 src/platform/nxp/rt/rt1060/CHIPPlatformConfig.h create mode 100644 src/platform/nxp/rt/rt1060/FactoryDataProviderImpl.cpp create mode 100644 src/platform/nxp/rt/rt1060/FactoryDataProviderImpl.h create mode 100644 src/platform/nxp/rt/rt1060/InetPlatformConfig.h create mode 100644 src/platform/nxp/rt/rt1060/PlatformManagerImpl.cpp create mode 100644 src/platform/nxp/rt/rt1060/SystemPlatformConfig.h create mode 100644 src/platform/nxp/rt/rt1060/args.gni create mode 100644 src/platform/nxp/rt/rt1170/BUILD.gn create mode 100644 src/platform/nxp/rt/rt1170/BlePlatformConfig.h create mode 100644 src/platform/nxp/rt/rt1170/CHIPDevicePlatformConfig.h create mode 100644 src/platform/nxp/rt/rt1170/CHIPPlatformConfig.h create mode 100644 src/platform/nxp/rt/rt1170/InetPlatformConfig.h create mode 100644 src/platform/nxp/rt/rt1170/PlatformManagerImpl.cpp create mode 100644 src/platform/nxp/rt/rt1170/SystemPlatformConfig.h create mode 100644 src/platform/nxp/rt/rt1170/args.gni create mode 100644 third_party/openthread/platforms/nxp/rt/rt1060/BUILD.gn create mode 100644 third_party/openthread/platforms/nxp/rt/rt1170/BUILD.gn diff --git a/.github/.wordlist.txt b/.github/.wordlist.txt index 76485a2a013b9a..a5dee8881fec76 100644 --- a/.github/.wordlist.txt +++ b/.github/.wordlist.txt @@ -735,6 +735,7 @@ isUpperCase itemName iterable itsfoss +IW JDK jinja JLink @@ -893,6 +894,7 @@ microcontroller microcontrollers MicroSD middleware +MIMXRT minApplicableSoftwareVersion Minicom MinInterval @@ -924,6 +926,7 @@ Multicast multilib Multiprotocol multithreaded +Murata mutex mutexes mv diff --git a/.github/workflows/examples-nxp.yaml b/.github/workflows/examples-nxp.yaml index 6354718f25b700..c4b6eb148ae50b 100644 --- a/.github/workflows/examples-nxp.yaml +++ b/.github/workflows/examples-nxp.yaml @@ -30,17 +30,17 @@ env: CHIP_NO_LOG_TIMESTAMPS: true jobs: - k32w0: - name: K32W0 + FreeRTOS: + name: FREERTOS env: - BUILD_TYPE: gn_k32w + BUILD_TYPE: gn_FreeRTOS runs-on: ubuntu-latest if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-nxp:80 + image: ghcr.io/project-chip/chip-build-nxp:81 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" steps: @@ -50,6 +50,15 @@ jobs: uses: ./.github/actions/checkout-submodules-and-bootstrap with: platform: nxp + extra-submodule-parameters: --recursive + + - name: Detect changed paths + uses: dorny/paths-filter@v3 + id: changed_paths + with: + filters: | + nxp: + - '**/nxp/**' - name: Set up environment for size reports uses: ./.github/actions/setup-size-reports @@ -57,222 +66,173 @@ jobs: with: gh-context: ${{ toJson(github) }} - - name: Build examples + - name: Build K32W0 examples run: | scripts/run_in_build_env.sh "\ ./scripts/build/build_examples.py \ - --target nxp-k32w0-freertos-lighting \ --target nxp-k32w0-freertos-lighting-factory \ - --target nxp-k32w0-freertos-lighting-rotating-id \ - --target nxp-k32w0-freertos-contact-sensor \ - --target nxp-k32w0-freertos-contact-sensor-low-power \ --target nxp-k32w0-freertos-contact-sensor-low-power-factory \ build \ --copy-artifacts-to out/artifacts \ " - - name: Get lighting app size stats + - name: Get K32W0 lighting app size stats run: | .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ nxp k32w0+release light \ - out/artifacts/nxp-k32w0-freertos-lighting/chip-k32w0x-light-example.elf \ + out/artifacts/nxp-k32w0-freertos-lighting-factory/chip-k32w0x-light-example.elf \ /tmp/bloat_reports/ - - name: Get contact sensor size stats + - name: Get K32W0 contact sensor size stats run: | .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ nxp k32w0+release contact \ - out/artifacts/nxp-k32w0-freertos-contact-sensor-low-power/chip-k32w0x-contact-example.elf \ + out/artifacts/nxp-k32w0-freertos-contact-sensor-low-power-factory/chip-k32w0x-contact-example.elf \ /tmp/bloat_reports/ - - name: Uploading Size Reports - uses: ./.github/actions/upload-size-reports - if: ${{ !env.ACT }} - with: - platform-name: K32W0 - k32w1: - name: K32W1 - - env: - BUILD_TYPE: gn_k32w - - runs-on: ubuntu-latest - if: github.actor != 'restyled-io[bot]' - - container: - image: ghcr.io/project-chip/chip-build-nxp:81 - volumes: - - "/tmp/bloat_reports:/tmp/bloat_reports" - steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Checkout submodules & Bootstrap - uses: ./.github/actions/checkout-submodules-and-bootstrap - with: - platform: nxp - extra-submodule-parameters: --recursive - - name: Set up environment for size reports - uses: ./.github/actions/setup-size-reports - if: ${{ !env.ACT }} - with: - gh-context: ${{ toJson(github) }} + - name: clean build + run: rm -rf ./out - - name: Build examples + - name: Build K32W1 examples run: | scripts/run_in_build_env.sh "\ ./scripts/build/build_examples.py \ --target nxp-k32w1-freertos-lighting \ - --target nxp-k32w1-freertos-contact-sensor-low-power \ - --target nxp-k32w1-freertos-lock-app \ build \ --copy-artifacts-to out/artifacts \ " - - name: Get lighting app size stats + - name: Get K32W1 lighting app size stats run: | .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ nxp k32w1+release light \ out/artifacts/nxp-k32w1-freertos-lighting/chip-k32w1-light-example.elf \ /tmp/bloat_reports/ - - name: Get contact sensor size stats - run: | - .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ - nxp k32w1+release contact \ - out/artifacts/nxp-k32w1-freertos-contact-sensor-low-power/chip-k32w1-contact-example.elf \ - /tmp/bloat_reports/ - - name: Get lock app size stats - run: | - .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ - nxp k32w1+release lock \ - out/artifacts/nxp-k32w1-freertos-lock-app/chip-k32w1-lock-example.elf \ - /tmp/bloat_reports/ - - name: Uploading Size Reports - uses: ./.github/actions/upload-size-reports - if: ${{ !env.ACT }} - with: - platform-name: K32W1 - mcxw71: - name: MCXW71 - env: - BUILD_TYPE: gn_k32w + - name: clean build + run: rm -rf ./out - runs-on: ubuntu-latest - if: github.actor != 'restyled-io[bot]' - - container: - image: ghcr.io/project-chip/chip-build-nxp:81 - volumes: - - "/tmp/bloat_reports:/tmp/bloat_reports" - steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Checkout submodules & Bootstrap - uses: ./.github/actions/checkout-submodules-and-bootstrap - with: - platform: nxp - extra-submodule-parameters: --recursive - - - name: Set up environment for size reports - uses: ./.github/actions/setup-size-reports - if: ${{ !env.ACT }} - with: - gh-context: ${{ toJson(github) }} - - - name: Build examples + - name: Build MCXW71 examples run: | scripts/run_in_build_env.sh "\ ./scripts/build/build_examples.py \ - --target nxp-mcxw71-freertos-lighting \ --target nxp-mcxw71-freertos-contact-sensor-low-power \ --target nxp-mcxw71-freertos-lock-app \ build \ --copy-artifacts-to out/artifacts \ " - - name: Get lighting app size stats - run: | - .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ - nxp mcxw71+release light \ - out/artifacts/nxp-mcxw71-freertos-lighting/chip-mcxw71-light-example.elf \ - /tmp/bloat_reports/ - - name: Get contact sensor size stats + - name: Get MCXW71 contact sensor size stats run: | .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ nxp mcxw71+release contact \ out/artifacts/nxp-mcxw71-freertos-contact-sensor-low-power/chip-mcxw71-contact-example.elf \ /tmp/bloat_reports/ - - name: Get lock app size stats + - name: Get MCXW71 lock app size stats run: | .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ nxp mcxw71+release lock \ out/artifacts/nxp-mcxw71-freertos-lock-app/chip-mcxw71-lock-example.elf \ /tmp/bloat_reports/ - - name: Uploading Size Reports - uses: ./.github/actions/upload-size-reports - if: ${{ !env.ACT }} - with: - platform-name: MCXW71 - rw61x: - name: RW61X - env: - BUILD_TYPE: gn_rw61x + - name: clean build + run: rm -rf ./out - runs-on: ubuntu-latest - if: github.actor != 'restyled-io[bot]' + - name: Build RT1060 all clusters example app + run: | + scripts/run_in_build_env.sh "\ + ./scripts/build/build_examples.py \ + --target nxp-rt1060-freertos-all-clusters-wifi-iw416 \ + --target nxp-rt1060-freertos-all-clusters-wifi-w8801 \ + --target nxp-rt1060-freertos-all-clusters-wifi-ota-evkc-iwx12 \ + build \ + --copy-artifacts-to out/artifacts \ + " + - name: Build RT1060 thermostat example app + if: github.event_name == 'push' || steps.changed_paths.outputs.nxp == 'true' + run: | + scripts/run_in_build_env.sh "\ + ./scripts/build/build_examples.py \ + --target nxp-rt1060-freertos-thermostat-thread-wifi-evkc-iwx12 \ + build \ + --copy-artifacts-to out/artifacts \ + " + - name: Build RT1060 laundry-washer example app + if: github.event_name == 'push' || steps.changed_paths.outputs.nxp == 'true' + run: | + scripts/run_in_build_env.sh "\ + ./scripts/build/build_examples.py \ + --target nxp-rt1060-freertos-laundry-washer-wifi-evkc-iwx12 \ + --target nxp-rt1060-freertos-laundry-washer-thread-evkc-iwx12 \ + build \ + --copy-artifacts-to out/artifacts \ + " - container: - image: ghcr.io/project-chip/chip-build-nxp:81 - volumes: - - "/tmp/bloat_reports:/tmp/bloat_reports" - steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Checkout submodules & Bootstrap - uses: ./.github/actions/checkout-submodules-and-bootstrap - with: - platform: nxp - extra-submodule-parameters: --recursive + - name: clean build + run: rm -rf ./out - - name: Set up environment for size reports - uses: ./.github/actions/setup-size-reports - if: ${{ !env.ACT }} - with: - gh-context: ${{ toJson(github) }} + - name: Build RT1170 all clusters example app + if: github.event_name == 'push' || steps.changed_paths.outputs.nxp == 'true' + run: | + scripts/run_in_build_env.sh "\ + ./scripts/build/build_examples.py \ + --target nxp-rt1170-freertos-all-clusters-wifi-iwx12 \ + --target nxp-rt1170-freertos-all-clusters-wifi-ota-iwx12 \ + build \ + --copy-artifacts-to out/artifacts \ + " + - name: Build RT1170 thermostat example app + run: | + scripts/run_in_build_env.sh "\ + ./scripts/build/build_examples.py \ + --target nxp-rt1170-freertos-thermostat-thread-wifi-iwx12 \ + build \ + --copy-artifacts-to out/artifacts \ + " + - name: Build RT1170 laundry-washer example app + if: github.event_name == 'push' || steps.changed_paths.outputs.nxp == 'true' + run: | + scripts/run_in_build_env.sh "\ + ./scripts/build/build_examples.py \ + --target nxp-rt1170-freertos-laundry-washer-thread-iwx12 \ + build \ + --copy-artifacts-to out/artifacts \ + " + + - name: clean build + run: rm -rf ./out - name: Build RW61X all clusters example app run: | scripts/run_in_build_env.sh "\ ./scripts/build/build_examples.py \ --target nxp-rw61x-freertos-all-clusters-wifi \ - --target nxp-rw61x-freertos-all-clusters-thread \ --target nxp-rw61x-freertos-all-clusters-wifi-ota-cmake \ build \ --copy-artifacts-to out/artifacts \ " - - name: Build RW61X thermostat example app run: | scripts/run_in_build_env.sh "\ ./scripts/build/build_examples.py \ - --target nxp-rw61x-freertos-thermostat-wifi \ - --target nxp-rw61x-freertos-thermostat-thread \ --target nxp-rw61x-freertos-thermostat-thread-wifi \ build \ --copy-artifacts-to out/artifacts \ " - - name: Build RW61X laundry-washer example app + if: github.event_name == 'push' || steps.changed_paths.outputs.nxp == 'true' run: | scripts/run_in_build_env.sh "\ ./scripts/build/build_examples.py \ --target nxp-rw61x-freertos-laundry-washer-wifi \ - --target nxp-rw61x-freertos-laundry-washer-thread \ build \ --copy-artifacts-to out/artifacts \ " + + - name: clean build + run: rm -rf ./out + - name: Uploading Size Reports uses: ./.github/actions/upload-size-reports if: ${{ !env.ACT }} with: - platform-name: RW61X + platform-name: NXP-FREERTOS zephyr: name: ZEPHYR @@ -289,8 +249,15 @@ jobs: uses: ./.github/actions/checkout-submodules-and-bootstrap with: platform: nxp - + - name: Detect changed paths + uses: dorny/paths-filter@v3 + id: changed_paths + with: + filters: | + nxp: + - '**/nxp/**' - name: Build NXP Zephyr examples + if: github.event_name == 'push' || steps.changed_paths.outputs.nxp == 'true' run: | scripts/run_in_build_env.sh "\ ./scripts/build/build_examples.py \ diff --git a/docs/platforms/nxp/index.md b/docs/platforms/nxp/index.md index be225ac938f7b5..fc11ed78b2baff 100644 --- a/docs/platforms/nxp/index.md +++ b/docs/platforms/nxp/index.md @@ -10,5 +10,5 @@ - [NXP - Android Commissioning](nxp_k32w_android_commissioning.md) - [NXP - Linux Examples](nxp_imx8m_linux_examples.md) - [NXP - Manufacturing Data](nxp_manufacturing_flow.md) -- [NXP - RW61x OTA Software Update Guide](nxp_rw61x_ota_software_update.md) +- [NXP - RTs OTA Software Update Guide](nxp_RTs_ota_software_update.md) - [NXP - Zephyr OTA Software Update Guide](nxp_zephyr_ota_software_update.md) diff --git a/docs/platforms/nxp/nxp_rw61x_ota_software_update.md b/docs/platforms/nxp/nxp_RTs_ota_software_update.md similarity index 68% rename from docs/platforms/nxp/nxp_rw61x_ota_software_update.md rename to docs/platforms/nxp/nxp_RTs_ota_software_update.md index af67b1419d0526..696f5078c1941d 100644 --- a/docs/platforms/nxp/nxp_rw61x_ota_software_update.md +++ b/docs/platforms/nxp/nxp_RTs_ota_software_update.md @@ -1,13 +1,19 @@ -# Matter Over-The-Air Software Update with NXP RW61x example applications +# Matter Over-The-Air Software Update with NXP RTs example applications ## Overview +This document describes OTA feature on NXP devices: + +- RW61x +- RT1060_EVK-C +- RT1170_EVK-B + The OTA Requestor feature enables the device to be informed of, download and apply a software update from an OTA Provider. -This section explains how to perform an OTA Software Update with NXP RW61x -example applications. Throughout this guide, the all-clusters application is -used as an example. +This section explains how to perform an OTA Software Update with NXP RTs example +applications. Throughout this guide, the all-clusters application is used as an +example. In general, the Over-The-Air Software Update process consists of the following steps : @@ -24,10 +30,9 @@ steps : ### Flash Memory Layout -The RW61x Flash is divided into different regions as follow : +The RTs Flash is divided into different regions as follow : -- Bootloader : MCUBoot resides at the base of the flash and occupies 0x20000 - (128 kB). +- Bootloader : MCUBoot resides at the base of the flash. - Primary application partition : The example application which would be run by the bootloader (active application). The size reserved for this partition is 4.4 MB. @@ -36,11 +41,12 @@ The RW61x Flash is divided into different regions as follow : Notes : -- The CPU1/CPU2 firmware are embedded in the CPU3 example application. +- For RW61x: The CPU1/CPU2 firmware are embedded in the CPU3 example + application. - The sizes of the primary and secondary applications are provided as an example (currently 4.4 MB is reserved for each partition). The size can be changed by modifying the `m_app_max_sectors` value in the linker script of - the application (`RW610_flash.ld`). + the application . ### MCUBoot Bootloader @@ -48,11 +54,11 @@ MCUBoot is an open-source secure bootloader used by RW61x to apply the self-upgrade. For more details, please refer to the [MCUBoot documentation](https://github.com/mcu-tools/mcuboot/blob/main/docs/design.md). -For RW61x platform, the bootloader is configured to use the flash remapping +For RTs platform, the bootloader is configured to use the flash remapping mechanism by default, in order to perform the image upgrade. This is achieved by using the `MCUBoot DIRECT-XIP` upgrade mode. -## OTA Software Update process for RW61x example application +## OTA Software Update process for RTs example application ### Flashing the bootloader @@ -71,9 +77,11 @@ $ JLink Run the following commands : -``` +Connect J-Link debugger to device: + +```sh J-Link > connect -Device> ? # you will be presented with a dialog -> select `RW612` +Device> ? # you will be presented with a dialog -> select `RW612` for RW61x, `MIMXRT1062XXX6B` for RT1060, `MIMXRT1176xxxA_M7` for RT1170 Please specify target interface: J) JTAG (Default) S) SWD @@ -81,34 +89,60 @@ T) cJTAG TIF> S Specify target interface speed [kHz]. : 4000 kHz Speed> # +``` + +Erase flash: + +``` J-Link > exec EnableEraseAllFlashBanks +``` + +For RW61x + +``` J-Link > erase 0x8000000, 0x88a0000 ``` -- MCUBoot application can be built with SDK installed, using instructions +For RT1060-EVK-C - below. +``` +J-Link > erase 0x60000000, 0x61000000 +``` -- Retrieve the mcuboot directory with : +For RT1170-EVK-B ``` -user@ubuntu: cd ~/Desktop/connectedhomeip/third_party/nxp/nxp_matter_support/github_sdk/common_sdk/repo/examples//ota_examples/mcuboot_opensource/armgcc +J-Link > erase 0x30000000, 0x34000000 ``` -``: Supported rw612 boards are: `rdrw612bga` or `frdmrw612` +- MCUBoot application can be built with SDK installed, using instructions + below. +- Retrieve the mcuboot directory located at + _'/third_party/nxp/nxp_matter_support/github_sdk/common_sdk/repo/examples/`RTboard`1/ota_examples/`mcuboot_opensource/armgcc`'_ + +_1 `rdrw612bga` or `frdmrw612` for RW61x, +`evkcmimxrt1060` for RT1060-EVK-C, `evkbmimxrt1170` for RT1170-EVK-B_ + +``` +user@ubuntu: cd ~/Desktop/connectedhomeip/third_party/nxp/nxp_matter_support/github_sdk/common_sdk/repo/examples//ota_examples/mcuboot_opensource/armgcc +``` -- Build the mcuboot application : +- Build the mcuboot application with running + `build_script`2 ``` -user@ubuntu: chmod +x build_flash_release.sh +user@ubuntu: chmod +x user@ubuntu: export ARMGCC_DIR=/opt/gcc-arm-none-eabi-10.3-2021.10 # with ARMGCC_DIR referencing the compiler path -user@ubuntu: ./build_flash_release.sh +user@ubuntu: ./ ``` +_2 `build_flash_release.sh` for RW61x, +`build_flexspi_nor_release.sh` for RT1060 and RT1170_ + - Program the generated binary to the target board. ``` -J-Link > loadbin ~/Desktop/connectedhomeip/third_party/nxp/nxp_matter_support/github_sdk/common_sdk/repo/examples//ota_examples/mcuboot_opensource/armgcc/flash_release/mcuboot_opensource.elf +J-Link > loadbin /mcuboot_opensource.elf ``` - If it runs successfully, the following logs will be displayed on the @@ -126,10 +160,11 @@ Unable to find bootable image Note : By default, mcuboot application considers the primary and secondary partitions to be the size of 4.4 MB. If the size is to be changed, the partition -addresses should be modified in the flash_partitioning.h accordingly. For more +addresses should be modified in the `flash_partitioning.h` accordingly. For more information about the flash partitioning with mcuboot, please refer to the -dedicated readme.txt located in -"`/third_party/nxp/nxp_matter_support/github_sdk/common_sdk/repo/examples//ota_examples/mcuboot_opensource/`". +dedicated `readme.txt` located in + +> _/third_party/nxp/nxp_matter_support/github_sdk/common_sdk/repo/examples/`RTboard`1/ota_examples/`mcuboot_opensource`/._ ### Generating and flashing the signed application image @@ -143,15 +178,25 @@ The image must have the following format : signature, the upgrade type, the swap status... The all-clusters application can be generated using the instructions from the -[README.md 'Building'](../../../examples/all-clusters-app/nxp/rt/rw61x/README.md#building) -section. The application is automatically linked to be executed from the primary -image partition, taking into consideration the offset imposed by mcuboot. -The resulting executable file found in out/debug/chip-rw61x-all-cluster-example +README.md3'Building' section. The +application is automatically linked to be executed from the primary image +partition, taking into consideration the offset imposed by mcuboot. + +_3 +[RW61x README.md 'Building'](../../../examples/all-clusters-app/nxp/rt/rw61x/README.md#building), +[RT1060 README.md 'Building'](../../../examples/all-clusters-app/nxp/rt/rt1060/README.md#building), +[RT1170 README.md 'Building'](../../../examples/all-clusters-app/nxp/rt/rt1170/README.md#building)_ + +The resulting executable file found in +out/release/chip-`board`4-all-cluster-example needs to be converted into raw binary format as shown below. -``` -arm-none-eabi-objcopy -R .flash_config -R .NVM -O binary chip-rw61x-all-cluster-example chip-rw61x-all-cluster-example.bin +_4 `rw61x` for RW61x, `rt1060` for +RT1060-EVK-C, `rt1170` for RT1170-EVK-B_ + +```sh +arm-none-eabi-objcopy -R .flash_config -R .NVM -O binary chip-<"board">-all-cluster-example chip-<"board">-all-cluster-example.bin ``` To sign the image and wrap the raw binary of the application with the header and @@ -161,10 +206,10 @@ trailer, "`imgtool`" is provided in the SDK and can be found in The following commands can be run (make sure to replace the /path/to/file/binary with the adequate files): -``` +```sh user@ubuntu: cd ~/Desktop//third_party/nxp/nxp_matter_support/github_sdk/common_sdk/repo/middleware/mcuboot_opensource/scripts/ -user@ubuntu: python3 imgtool.py sign --key ~/Desktop//third_party/nxp/nxp_matter_support/github_sdk/common_sdk/repo/examples//ota_examples/mcuboot_opensource/keys/sign-rsa2048-priv.pem --align 4 --header-size 0x1000 --pad-header --pad --confirm --slot-size 0x440000 --max-sectors 1088 --version "1.0" ~/Desktop/connectedhomeip/examples/all-clusters-app/nxp/rt/rw61x/out/debug/chip-rw61x-all-cluster-example.bin ~/Desktop/connectedhomeip/examples/all-clusters-app/nxp/rt/rw61x/out/debug/chip-rw61x-all-cluster-example_SIGNED.bin +user@ubuntu: python3 imgtool.py sign --key ~/Desktop//third_party/nxp/nxp_matter_support/github_sdk/common_sdk/repo/examples//ota_examples/mcuboot_opensource/keys/sign-rsa2048-priv.pem --align 4 --header-size 0x1000 --pad-header --pad --confirm --slot-size 0x440000 --max-sectors 1088 --version "1.0" ~/Desktop/connectedhomeip/examples/all-clusters-app/nxp/rt/<"rt_board">/out/debug/chip-<"rt_board">-all-cluster-example.bin ~/Desktop/connectedhomeip/examples/all-clusters-app/nxp/rt/<"rt_board">/out/debug/chip-<"rt_board">-all-cluster-example_SIGNED.bin ``` Notes : @@ -176,7 +221,7 @@ Notes : adjusted accordingly. - In this example, the image is signed with the private key provided by the SDK as an example - (`/third_party/nxp/nxp_matter_support/github_sdk/common_sdk/repo/examples//ota_examples/mcuboot_opensource/keys/sign-rsa2048-priv.pem`), + (`/third_party/nxp/nxp_matter_support/github_sdk/common_sdk/repo/examples//ota_examples/mcuboot_opensource/keys/sign-rsa2048-priv.pem`), MCUBoot is built with its corresponding public key which would be used to verify the integrity of the image. It is possible to generate a new pair of keys using the following commands. This procedure should be done prior to @@ -195,18 +240,31 @@ user@ubuntu: python3 imgtool.py getpub -k priv_key.pem ``` - The extracted public key can then be copied to the - `/third_party/nxp/nxp_matter_support/github_sdk/common_sdk/repo/examples//ota_examples/mcuboot_opensource/keys/sign-rsa2048-pub.c`, + `/third_party/nxp/nxp_matter_support/github_sdk/common_sdk/repo/examples//ota_examples/mcuboot_opensource/keys/sign-rsa2048-pub.c`, given as a value to the rsa_pub_key[] array. The resulting output is the signed binary of the application version "1.0". -JLink can be used to flash the application at the address 0x8020000, using the -command : +JLink can be used to flash the application using the command : + +For RW61x ``` J-Link > loadbin chip-rw61x-all-cluster-example_SIGNED.bin 0x8020000 ``` +For RT1060-EVK-C + +``` +J-Link > loadbin chip-rt1060-all-cluster-example_SIGNED.bin 0x60040000 +``` + +For RT1170-EVK-B + +``` +J-Link > loadbin chip-rt1170-all-cluster-example_SIGNED.bin 0x30040000 +``` + The bootloader should then be able to jump directly to the start of the application and run it. @@ -226,8 +284,8 @@ When the signed binary of the update is generated, the file should be converted into OTA format. To do so, the ota_image_tool is provided in the repo and can be used to convert a binary file into an .ota file. -``` -user@ubuntu:~/connectedhomeip$ : ./src/app/ota_image_tool.py create -v 0xDEAD -p 0xBEEF -vn 2 -vs "2.0" -da sha256 chip-rw61x-all-cluster-example_SIGNED.bin chip-rw61x-all-cluster-example.ota +```sh +user@ubuntu:~/connectedhomeip$ : ./src/app/ota_image_tool.py create -v 0xDEAD -p 0xBEEF -vn 2 -vs "2.0" -da sha256 chip-<"rt_board">-all-cluster-example_SIGNED.bin chip-rw61x-all-cluster-example.ota ``` The generated OTA file can be used to perform the OTA Software Update. The @@ -240,7 +298,7 @@ Setup example : - [Chip-tool](../../../examples/chip-tool/README.md) application running on the RPi. - OTA Provider application built on the same RPi (as explained below). -- RW61x board programmed with the example application (with the instructions +- RT board programmed with the example application (with the instructions above). Before starting the OTA process, the Linux OTA Provider application can be built @@ -248,9 +306,11 @@ on the RPi (if not already present in the pre-installed apps) : ``` user@ubuntu:~/connectedhomeip$ : ./scripts/examples/gn_build_example.sh examples/ota-provider-app/linux out/ota-provider-app chip_config_network_layer_ble=false - user@ubuntu:~/connectedhomeip$ : rm -rf /tmp/chip_* -user@ubuntu:~/connectedhomeip$ : ./out/ota-provider-app/chip-ota-provider-app -f chip-rw61x-all-cluster-example.ota +``` + +```sh +user@ubuntu:~/connectedhomeip$ : ./out/ota-provider-app/chip-ota-provider-app -f chip-<"rt_board">-all-cluster-example.ota ``` The OTA Provider should first be provisioned with chip-tool by assigning it the diff --git a/examples/all-clusters-app/nxp/rt/rt1060/.gn b/examples/all-clusters-app/nxp/rt/rt1060/.gn new file mode 100644 index 00000000000000..0985ed955a426f --- /dev/null +++ b/examples/all-clusters-app/nxp/rt/rt1060/.gn @@ -0,0 +1,35 @@ +# Copyright (c) 2020 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/build.gni") +import("//build_overrides/chip.gni") + +# The location of the build configuration file. +buildconfig = "${build_root}/config/BUILDCONFIG.gn" + +# CHIP uses angle bracket includes. +check_system_includes = true + +default_args = { + target_cpu = "arm" + target_os = "freertos" + + import("//args.gni") + + # Import common example GN args + import("${chip_root}/examples/platform/nxp/common/gn/args.gni") + + # Import default platform configs + import("${chip_root}/src/platform/nxp/rt/rt1060/args.gni") +} diff --git a/examples/all-clusters-app/nxp/rt/rt1060/BUILD.gn b/examples/all-clusters-app/nxp/rt/rt1060/BUILD.gn new file mode 100644 index 00000000000000..16e0b03e017c94 --- /dev/null +++ b/examples/all-clusters-app/nxp/rt/rt1060/BUILD.gn @@ -0,0 +1,284 @@ +# Copyright (c) 2021-2023 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/build.gni") +import("//build_overrides/chip.gni") +import("//build_overrides/nxp_sdk.gni") +import("//build_overrides/openthread.gni") +import("${chip_root}/src/platform/device.gni") + +#allows to get common NXP SDK gn options +import("${nxp_sdk_build_root}/nxp_sdk.gni") + +# Allows to get various RT gn options +import("${nxp_sdk_build_root}/${nxp_sdk_name}/rt_sdk.gni") + +import("${chip_root}/src/platform/nxp/${nxp_platform}/args.gni") +import( + "${nxp_sdk_build_root}/${nxp_sdk_name}/${rt_platform}/${rt_platform}.gni") +import("${nxp_sdk_build_root}/${nxp_sdk_name}/nxp_executable.gni") + +assert(current_os == "freertos") +assert(target_os == "freertos") +assert(nxp_platform == "rt/rt1060") + +declare_args() { + # Allows to enable to ota_provider support + enable_ota_provider = false + + # Allows to connect to a predefine Wi-Fi network at boot + wifi_auto_connect_at_boot = false + wifi_auto_connect_at_boot_ssid = "" + wifi_auto_connect_at_boot_password = "" + + # Setup discriminator as argument + setup_discriminator = 3840 +} + +example_platform_dir = + "${nxp_sdk_matter_support_root}/examples/platform/${nxp_platform}" +common_example_dir = "${chip_root}/examples/platform/nxp/common" + +app_common_folder = "all-clusters-app/all-clusters-common" + +# Create here the SDK instance. +# Particular sources/defines/includes could be added/changed depending on the target application. +rt_sdk("sdk") { + defines = [] + + cflags = [] + public_deps = [] + public_configs = [] + sources = [] + include_dirs = [] + + # Indicate paths to default board files + include_dirs += [ "${example_platform_dir}/board/" ] + + # RT1060 rev A use same pin mux as rev B + # If user needs different pin mux files for rev A and rev B boards, the source and include from below needs to be updated accordingly + if (evkname == "evkmimxrt1060") { + include_dirs += [ "${example_platform_dir}/board/evkbmimxrt1060/" ] + sources += [ "${example_platform_dir}/board/evkbmimxrt1060/pin_mux.c" ] + } else { + include_dirs += [ "${example_platform_dir}/board/${evkname}/" ] + sources += [ "${example_platform_dir}/board/${evkname}/pin_mux.c" ] + } + + sources += [ "${example_platform_dir}/board/hardware_init.c" ] + sources += [ "${example_platform_dir}/board/clock_config.c" ] + sources += [ "${example_platform_dir}/board/board.c" ] + sources += [ "${example_platform_dir}/board/peripherals.c" ] + + # Indicate the path to CHIPProjectConfig.h + include_dirs += [ "include/config" ] + + # Indicate the default path to FreeRTOSConfig.h + include_dirs += [ "${example_platform_dir}/app/project_include/freeRTOS" ] + + # Indicate the default path to OpenThreadConfig.h + include_dirs += [ "${example_platform_dir}/app/project_include/openthread" ] + + # For matter with BR feature, increase FreeRTOS heap size + if (chip_enable_wifi && chip_enable_openthread) { + defines += [ "configTOTAL_HEAP_SIZE=(size_t)(170 * 1024)" ] + } + + defines += [ + "CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR=${setup_discriminator}", + ] +} + +# Create the SDK driver instance. +# Particular sources/defines/includes could be added to add other drivers not available in the default sdk driver template +rt1060_sdk_drivers("sdk_driver") { +} + +rt_executable("all_cluster_app") { + output_name = "chip-rt1060-all-cluster-example" + + defines = [ + "CONFIG_RENDEZVOUS_MODE=7", + "CONFIG_APP_FREERTOS_OS=1", + ] + + if (chip_enable_openthread) { + defines += [ "CONFIG_NET_L2_OPENTHREAD=1" ] + } + + include_dirs = [ + "../../common/main/include", + "../../common/main", + "${chip_root}/examples/all-clusters-app/all-clusters-common/include", + "${chip_root}/examples/providers/", + ] + + sources = [ + "${chip_root}/examples/all-clusters-app/all-clusters-common/src/binding-handler.cpp", + "${chip_root}/examples/providers/DeviceInfoProviderImpl.cpp", + "../../common/main/AppTask.cpp", + "../../common/main/DeviceCallbacks.cpp", + "../../common/main/ZclCallbacks.cpp", + "../../common/main/include/AppEvent.h", + "../../common/main/include/AppTask.h", + "../../common/main/include/DeviceCallbacks.h", + "../../common/main/main.cpp", + ] + + # App common files + include_dirs += [ + "${common_example_dir}/icd/include", + "${common_example_dir}/matter_cli/include", + "${common_example_dir}/device_manager/include", + "${common_example_dir}/device_callbacks/include", + "${common_example_dir}/matter_button/include", + "${common_example_dir}/factory_data/include", + "${common_example_dir}/app_task/include", + ] + + sources += [ + "${chip_root}/examples/platform/nxp/${nxp_platform}/factory_data/source/AppFactoryDataExample.cpp", + "${common_example_dir}/app_task/source/AppTaskBase.cpp", + "${common_example_dir}/app_task/source/AppTaskFreeRTOS.cpp", + "${common_example_dir}/device_callbacks/source/CommonDeviceCallbacks.cpp", + "${common_example_dir}/device_manager/source/CHIPDeviceManager.cpp", + "${common_example_dir}/icd/source/ICDUtil.cpp", + "${common_example_dir}/matter_button/source/ButtonDefault.cpp", + "${common_example_dir}/matter_button/source/ButtonManager.cpp", + "${common_example_dir}/matter_button/source/ButtonRegistrationDefault.cpp", + ] + + deps = [ "${chip_root}/examples/${app_common_folder}" ] + + sources += [ + "${chip_root}/examples/${app_common_folder}/src/bridged-actions-stub.cpp", + "${chip_root}/examples/${app_common_folder}/src/smco-stub.cpp", + "${chip_root}/examples/${app_common_folder}/src/static-supported-modes-manager.cpp", + ] + + if (chip_enable_matter_cli) { + defines += [ "ENABLE_CHIP_SHELL" ] + deps += [ + "${chip_root}/examples/shell/shell_common:shell_common", + "${chip_root}/src/lib/shell:shell", + ] + sources += [ + "${common_example_dir}/matter_cli/source/AppCLIBase.cpp", + "${common_example_dir}/matter_cli/source/AppCLIFreeRTOS.cpp", + ] + } + + if (chip_enable_ota_requestor) { + include_dirs += [ "${common_example_dir}/ota_requestor/include" ] + sources += [ + "${common_example_dir}/ota_requestor/source/OTARequestorInitiator.cpp", + "${common_example_dir}/ota_requestor/source/OTARequestorInitiatorCommon.cpp", + ] + } + + if (wifi_auto_connect_at_boot) { + assert(wifi_auto_connect_at_boot_ssid != "" && + wifi_auto_connect_at_boot_password != "", + "WiFi SSID and password must be specified at build time!") + + defines += [ + "CONFIG_CHIP_APP_WIFI_CONNECT_AT_BOOT=1", + "CONFIG_CHIP_APP_WIFI_SSID=\"${wifi_auto_connect_at_boot_ssid}\"", + "CONFIG_CHIP_APP_WIFI_PASSWORD=\"${wifi_auto_connect_at_boot_password}\"", + ] + + include_dirs += [ "${common_example_dir}/wifi_connect/include" ] + sources += [ "${common_example_dir}/wifi_connect/source/WifiConnect.cpp" ] + } + + if (enable_ota_provider) { + defines += [ "CONFIG_CHIP_OTA_PROVIDER=1" ] + + include_dirs += [ + "${common_example_dir}/ota_provider/include", + "${common_example_dir}/ota_provider/ota-provider-common", + ] + + sources += [ + "${common_example_dir}/ota_provider/ota-provider-common/RTBdxOtaSender.cpp", + "${common_example_dir}/ota_provider/ota-provider-common/RTOTAProviderExample.cpp", + "${common_example_dir}/ota_provider/source/OTAProvider.cpp", + ] + + deps += [ + "${chip_root}/src/app/server", + "${chip_root}/src/protocols/bdx", + "${chip_root}/third_party/jsoncpp", + ] + } + + # In case a dedicated assert function needs to be supported the flag sdk_fsl_assert_support should be set to false + # The would add to the build a dedicated application assert implementation. + if (!sdk_fsl_assert_support) { + sources += [ "${common_example_dir}/app_assert/source/AppAssert.cpp" ] + } + + cflags = [ "-Wconversion" ] + + ldscript = + "${example_platform_dir}/app/ldscripts/MIMXRT1062xxxxx_flexspi_nor.ld" + + inputs = [ ldscript ] + + ldflags = [ + "-T" + rebase_path(ldscript, root_build_dir), + "-fno-common", + "-Wl,--defsym=__stack_size__=2048", + "-ffreestanding", + "-fno-builtin", + "-mapcs", + "-u qspiflash_config", + "-u image_vector_table", + "-u boot_data", + "-u dcd_data", + "-Wl,-print-memory-usage", + "-Wl,--no-warn-rwx-segments", + ] + + if (evkname == "evkcmimxrt1060") { + ldflags += [ "-Wl,--defsym=gEVKCFlashSize_d=0x1000000" ] + } + + if (enable_ota_provider) { + # As the OTA file will be stored in the littlefs file system, it is required to increase the size of the file system + # To be able to store an OTA file with a MAX size of 640K, + # it recommended to size the file system with: + # 161 sectors of 4K => reserved for the OTA file + # 32 sectors of 4K => reserved for Matter/OT/BLE settings storage + ldflags += [ "-Wl,--defsym=gNVMSectorCountLink_d=193" ] + } + + if (chip_enable_ota_requestor) { + # If OTA build flag is enabled, + # we would need to reserve enough space for the bootloader (MCUBoot) + # MCUBoot requires 0x11000 Bytes to be reserved at the base of the flash + # Consequently, some sections will need to be shifted + ldflags += [ "-Wl,--defsym=__m_mcuboot_size__=0x40000" ] + } + + output_dir = root_out_dir +} + +group("rt1060") { + deps = [ ":all_cluster_app" ] +} + +group("default") { + deps = [ ":rt1060" ] +} diff --git a/examples/all-clusters-app/nxp/rt/rt1060/README.md b/examples/all-clusters-app/nxp/rt/rt1060/README.md new file mode 100644 index 00000000000000..558ae4127fe72e --- /dev/null +++ b/examples/all-clusters-app/nxp/rt/rt1060/README.md @@ -0,0 +1,723 @@ +# CHIP RT1060 All-clusters Application + +The all-clusters example implements a server which can be accessed by a CHIP +controller and can accept basic cluster commands. + +The example is based on +[Project CHIP](https://github.com/project-chip/connectedhomeip) and the NXP +RT1060 SDK, and provides a prototype application that demonstrates device +commissioning and different cluster control. + +
+ +- [CHIP RT1060 All-clusters Application](#chip-rt1060-all-clusters-application) + - [Introduction](#introduction) + - [Configurations supported](#configurations-supported) + - [Hardware requirements RT1060 + transceiver](#hardware-requirements-rt1060--transceiver) + - [Hardware requirements RT1060+IW416](#hardware-requirements-rt1060iw416) + - [Hardware requirements RT1060+88W8801](#hardware-requirements-rt106088w8801) + - [Hardware requirements RT1060 + K32W0](#hardware-requirements-rt1060--k32w0) + - [Hardware requirements RT1060-EVK-C+IW612](#hardware-requirements-rt1060-evk-ciw612) + - [Hardware requirements RT1060 + 88W8801 + K32W0x1DK6](#hardware-requirements-rt1060--88w8801--k32w0x1dk6) + - [Building](#building) + - [Building with Matter over Wifi configuration on RT1060 + transceiver](#building-with-matter-over-wifi-configuration-on-rt1060--transceiver) + - [Build with Matter over Thread configuration on RT1060 + transceiver](#build-with-matter-over-thread-configuration-on-rt1060--transceiver) + - [Build with Matter over Thread configuration on RT1060 + K32W0](#build-with-matter-over-thread-configuration-on-rt1060--k32w0) + - [Build with Matter over Thread configuration on RT1060-EVK-C + IW612](#build-with-matter-over-thread-configuration-on-rt1060-evk-c--iw612) + - [Build with Matter over Wi-Fi + OpenThread Border Router configuration on RT1060 + 88W8801 + K32W0x1DK6](#build-with-matter-over-wi-fi--openthread-border-router-configuration-on-rt1060--88w8801--k32w0x1dk6) + - [General Information](#general-information) + - [Manufacturing data](#manufacturing-data) + - [Flashing and debugging](#flashing-and-debugging) + - [Testing the example](#testing-the-example) + - [Matter over wifi configuration :](#matter-over-wifi-configuration-) + - [Matter over thread configuration :](#matter-over-thread-configuration-) + - [Matter over wifi with openthread border router configuration :](#matter-over-wifi-with-openthread-border-router-configuration-) + - [Testing the all-clusters application without Matter CLI:](#testing-the-all-clusters-application-without-matter-cli) + - [Testing the all-clusters application with Matter CLI enabled:](#testing-the-all-clusters-application-with-matter-cli-enabled) + - [Thread Border Router overview](#thread-border-router-overview) +
+ + + +## Introduction + +![RT1060 EVK-B](../../../../platform/nxp/rt/rt1060/doc/images/MIMXRT1060-EVKB-TOP.png) + +The RT1060 all-cluster application provides a working demonstration of the +RT1060 board integration, built using the Project CHIP codebase and the NXP +RT1060 SDK. + +The example supports: + +- Matter over Wi-Fi +- Matter over Openthread +- Matter over Wi-Fi with Openthread Border Router support + +The example targets the +[NXP MIMXRT1060-EVK-B](https://www.nxp.com/design/development-boards/i-mx-evaluation-and-development-boards/mimxrt1060-evk-i-mx-rt1060-evaluation-kit:MIMXRT1060-EVK) +board by default. It is also possible to use the older MIMXRT1060-EVK board, +build and board setup instructions differ in some steps. + +### Configurations supported + +Here are listed configurations supported on RT1060. + +Matter over Wi-Fi : + +- RT1060 + IW416 (Wi-Fi + BLE) +- RT1060 + 88W8801 (Wi-Fi) +- **Experimental:** _RT1060-EVK-C + IW612 (Wi-fi +BLE)_ + +Matter over Thread : + +- RT1060 + K32W0 (15.4 + BLE) +- **Experimental:** _RT1060-EVK-C + IW612 (15.4 + BLE)_ + +Matter over Wi-Fi with Openthread Border Router support : + +- RT1060 + 88W8801 + K32W0x1DK6 + +### Hardware requirements RT1060 + transceiver + +#### Hardware requirements RT1060+IW416 + +Host part: + +- 1 MIMXRT1060-EVK-B or MIMXRT1060-EVK board +- external 5V supply + +Transceiver part: + +- 1 AzureWave AW-AM510-uSD evaluation board + +Jumper settings for MIMXRT1060-EVK-B (enables external 5V supply): + +- remove J40 5-6 +- connect J40 1-2 +- connect J45 with external power (controlled by SW6 - position 3) + +Jumper settings for MIMXRT1060-EVK (enables external 5V supply): + +- remove J1 5-6 +- connect J1 1-2 +- connect J2 with external power (enabled by SW1 - position 3) + +The hardware should be reworked according to the chapter _Hardware Rework Guide +for MIMXRT1060-EVK-B and AW-AM510-uSD_ or the chapter _Hardware Rework Guide for +MIMXRT1060-EVK and AW-AM510-uSD_ in the document +_`Hardware Rework Guide for EdgeFast BT PAL`_ which can be found in the NXP +RT1060 SDK (_docs/wireless/bluetooth/`edgefast_bluetooth`/Hardware Rework Guide +for EdgeFast BT PAL.pdf_): + +- Make sure resistors R368/R376/R347/R349/R365/R363/R193/R186 are removed. + +Only the SDK package downloaded from https://mcuxpresso.nxp.com contains the PDF +document mentioned above, it is not present in the SDK downloaded from GitHub +using the west tool. + +Jumper settings for AzureWave AW-AM510-uSD Module: + +- J4 1-2: `VIO` 1.8V (Voltage level of SD-IO pins is 1.8V) +- J2 1-2: 3.3V `VIO_uSD` (Power Supply from uSD connector) +- The pin 1 of J4 is not marked on the board. Please note that pin numbering + of J4 is opposite to J2. + +Plug AW-AM510-uSD into uSD connector J22 on MIMXRT1060-EVK-B or J39 on +MIMXRT1060-EVK. + +Connect the following pins between RT1060 and AW-AM510-uSD to enable Bluetooth +HCI UART: + +| PIN NAME | AW-AM510-uSD | MIMXRT1060-EVK-B | MIMXRT1060-EVK | PIN NAME OF RT1060 | GPIO NAME OF RT1060 | +| :--------: | :-----------: | :--------------: | :------------: | :----------------: | :-----------------: | +| `UART_TXD` | `J10 (pin 4)` | `J16 (pin 1)` | `J22 (pin 1)` | `LPUART3_RXD` | `GPIO_AD_B1_07` | +| `UART_RXD` | `J10 (pin 2)` | `J16 (pin 2)` | `J22 (pin 2)` | `LPUART3_TXD` | `GPIO_AD_B1_06` | +| `UART_RTS` | `J10 (pin 6)` | `J33 (pin 3)` | `J23 (pin 3)` | `LPUART3_CTS` | `GPIO_AD_B1_04` | +| `UART_CTS` | `J10 (pin 8)` | `J33 (pin 4)` | `J23 (pin 4)` | `LPUART3_RTS` | `GPIO_AD_B1_05` | +| `GND` | `J6 (pin 7)` | `J32 (pin 7)` | `J25 (pin 7)` | `GND` | `GND` | + +Attach external antenna into connector on AW-AM510-uSD. + +Additional information about the AW-AM510-uSD can be found in the user manual +_UM11441 - Getting Started with NXP-based Wireless Modules and i.MX RT Platform +Running RTOS_, which can be found in the NXP RT1060 SDK +(docs/wireless/UM11441-Getting-Started-with-NXP-based-Wireless-Modules-and-i.MX-RT-Platform-Running-on-RTOS.pdf). +Only the SDK package downloaded from https://mcuxpresso.nxp.com contains the PDF +document, it is not present in the SDK downloaded from GitHub using the west +tool. + +#### Hardware requirements RT1060+88W8801 + +Host part: + +- 1 MIMXRT1060-EVK-B + +Transceiver part : + +- 1 88W8801 2DS M.2 Module (rev A) +- 1 Murata uSD-M.2 Adapter (rev B1) + +The 88W8801 2DS M.2 Module should be inserted into the Murata uSD-M.2 Adapter +and inserted in the uSD slot J22 of MIMXRT1060-EVK-B. The Murata uSD-M.2 Adapter +can be powered up using uSD pins. For that, set the J1 jumper of Murata uSD-M.2 +to position 2-3 (Position 2-3: `VBAT supply`, typical 3.1 ~ 3.3V, from microSD +connector). + +Note: as the 88W8801 module supports only the 2.4 GHz Wi-Fi band, it is +mandatory to connect it to a Wi-Fi access point on the 2.4 GHz band. + +#### Hardware requirements RT1060 + K32W0 + +Host part: + +- 1 MIMXRT1060-EVK-B or MIMXRT1060-EVK board + +Transceiver part: + +- 1 OM15076-3 Carrier Board (DK6 board) +- 1 K32W0 Module to be plugged on the Carrier Board + +**Board settings** + +The below table explains pin settings (UART settings) to connect the +MIMXRT1060-EVK-B (host) to a k32w061 transceiver (rcp). + +| PIN NAME | DK6 (K32W061) | MIMXRT1060-EVK-B | MIMXRT1060-EVK | PIN NAME OF RT1060 | GPIO NAME OF RT1060 | +| :--------------: | :-----------: | :--------------: | :------------: | :----------------: | :-----------------: | +| `UART_TXD` | `PIO, pin 8` | `J16, pin 1` | `J22, pin 1` | `LPUART3_RXD` | `GPIO_AD_B1_07` | +| `UART_RXD` | `PIO, pin 9` | `J16, pin 2` | `J22, pin 2` | `LPUART3_TXD` | `GPIO_AD_B1_06` | +| `UART_RTS` | `PIO, pin 6` | `J33, pin 3` | `J23, pin 3` | `LPUART3_CTS` | `GPIO_AD_B1_04` | +| `UART_CTS` | `PIO, pin 7` | `J33, pin 4` | `J23, pin 4` | `LPUART3_RTS` | `GPIO_AD_B1_05` | +| `GND` | `J3, pin 1` | `J32, pin 7` | `J25, pin 7` | `XX` | `XX` | +| `RESET` | `RSTN` | `J33, pin 2` | `J23, pin 2` | `GPIO_AD_B1_11` | `GPIO_AD_B1_11` | +| `DIO5/ISP Entry` | `PIO, pin 5` | `J33, pin 1` | `J23, pin 1` | `GPIO_AD_B1_10` | `GPIO_AD_B1_10` | + +The below picture shows pins connections for the MIMXRT1060-EVK. + +![rt1060_k32w061_pin_settings](../../../../platform/nxp/rt/rt1060/doc/images/rt1060_k32w061_pin_settings.jpg) + +#### Hardware requirements RT1060-EVK-C+IW612 + +Host part: + +- 1 MIMXRT1060-EVK-C + + Hardware should be reworked as below: + + - populate R93, R96, R2155, R2156, R2157, R2158, R2159 with 0Ohm resistors + - J76 and J107 jumpers in 2-3 position. + - J109 and J110 jumpers in 1-2 position. + - disconnect pin15 of component U9 + +![rt1060_evkc_IW612_hw_rework](../../../../platform/nxp/rt/rt1060/doc/images/rt1060_evkc_IW612_hw_rework.jpg) + +![rt1060_evkc_IW612_hw_rework_detail](../../../../platform/nxp/rt/rt1060/doc/images/rt1060_evkc_IW612_hw_rework_detail.jpg) + +Transceiver part : + +- 1 + [2EL M2 A1 IW612 Secure Module](https://www.nxp.com/products/wireless/wi-fi-plus-bluetooth-plus-802-15-4/2-4-5-ghz-dual-band-1x1-wi-fi-6-802-11ax-plus-bluetooth-5-2-plus-802-15-4-tri-radio-solution:IW612) + +![](../../../../platform/nxp/rt/rt1170/doc/images/iwx612_2EL.jpg) + +#### Hardware requirements RT1060 + 88W8801 + K32W0x1DK6 + +- i.MX RT1060 EVK-A or EVK-B board +- 88W8801 module (for Wi-Fi connection), for example 88W8801 2DS M.2 Module + (rev A) and Murata uSD-M.2 Adapter (rev B1) +- K32W0x1 mezzanine module (for Thread connection) +- `IOT_ZTB-DK006` carrier board for the K32W0x1 module (referenced as DK6 + carrier board) + + + +## Building + +In order to build the Project CHIP example, we recommend using a Linux +distribution. Supported Operating Systems are listed in +[BUILDING.md](../../../../../docs/guides/BUILDING.md). + +- Make sure that below prerequisites are correctly installed, as described in + [BUILDING.md](../../../../../docs/guides/BUILDING.md). + +``` +sudo apt-get install git gcc g++ pkg-config libssl-dev libdbus-1-dev \ + libglib2.0-dev libavahi-client-dev ninja-build python3-venv python3-dev \ + python3-pip unzip libgirepository1.0-dev libcairo2-dev libreadline-dev +``` + +- Step 1: checkout NXP specific submodules only + +``` +user@ubuntu:~/Desktop/git/connectedhomeip$ scripts/checkout_submodules.py --shallow --platform nxp --recursive +``` + +- Step 2: activate local environment + +``` +user@ubuntu:~/Desktop/git/connectedhomeip$ source scripts/activate.sh +``` + +If the script says the environment is out of date, you can update it by running +the following command: + +``` +user@ubuntu:~/Desktop/git/connectedhomeip$ source scripts/bootstrap.sh +``` + +- Step 3: Init NXP SDK(s) + +``` +user@ubuntu:~/Desktop/git/connectedhomeip$ third_party/nxp/nxp_matter_support/scripts/update_nxp_sdk.py --platform common +``` + +Note: By default update_nxp_sdk.py will try to initialize all NXP SDKs. Arg "-- +help" could be used to view all available options. + +- Start building the application. + +### Building with Matter over Wifi configuration on RT1060 + transceiver + +- Build the Wi-fi configuration for **MIMXRT1060-EVK-B board + IW416 + transceiver** (with BLE for commissioning). + +``` +user@ubuntu:~/Desktop/git/connectedhomeip/examples/all-clusters-app/nxp/rt/rt1060$ gn gen --args="chip_enable_wifi=true iw416_transceiver=true" out/debug +user@ubuntu:~/Desktop/git/connectedhomeip/examples/all-clusters-app/nxp/rt/rt1060$ ninja -C out/debug +``` + +- Build the Wi-fi configuration for **MIMXRT1060-EVK-B board + 88W8801 + transceiver** with Matter-over-Wifi configuration and only onnetwork + commissioning (without BLE, the WiFi network credentials are provided at + build-time which will enable the device to join the Wi-Fi AP at startup): + +``` +user@ubuntu:~/Desktop/git/connectedhomeip/examples/all-clusters-app/nxp/rt/rt1060$ export ssid_name= && export ssid_password= && gn gen --args="chip_enable_wifi=true w8801_transceiver=true chip_config_network_layer_ble=false wifi_auto_connect_at_boot=true wifi_auto_connect_at_boot_ssid=\"${ssid_name}\" wifi_auto_connect_at_boot_password=\"${ssid_password}\"" out/debug +user@ubuntu:~/Desktop/git/connectedhomeip/examples/all-clusters-app/nxp/rt/rt1060$ ninja -C out/debug +``` + +- Build the Wi-fi configuration for **MIMXRT1060-EVK-C board + IW612 + transceiver** (with BLE for commissioning). + +``` +user@ubuntu:~/Desktop/git/connectedhomeip/examples/all-clusters-app/nxp/rt/rt1060$ gn gen --args="chip_enable_wifi=true iwx12_transceiver=true evkname=\"evkcmimxrt1060\" " out/debug +user@ubuntu:~/Desktop/git/connectedhomeip/examples/all-clusters-app/nxp/rt/rt1060$ ninja -C out/debug +``` + +- Build the Wi-fi configuration for **MIMXRT1060-EVK-C board + IW612 + transceiver** with Matter-over-Wifi configuration and only onnetwork + commissioning (without BLE, the WiFi network credentials are provided at + build-time which will enable the device to join the Wi-Fi AP at startup): + +``` +user@ubuntu:~/Desktop/git/connectedhomeip/examples/all-clusters-app/nxp/rt/rt1060$ gn gen --args="chip_enable_wifi=true iwx12_transceiver=true evkname=\"evkcmimxrt1060\" chip_config_network_layer_ble=false tcp_download=true wifi_ssid=\"your_wifi_ssid\" wifi_password=\"your_wifi_password\"" out/debug +user@ubuntu:~/Desktop/git/connectedhomeip/examples/all-clusters-app/nxp/rt/rt1060$ ninja -C out/debug +``` + +### Build with Matter over Thread configuration on RT1060 + transceiver + +#### Build with Matter over Thread configuration on RT1060 + K32W0 + +For this configuration a K32W0 RCP image is required and must support in a +single image the openthread RCP configuration and the BLE HCI BB configuration. +Messages between the host and the K32W0 transceiver are transferred on a single +UART with flow control support. For that the HDLC-Lite framing protocol is used +to transfer spinel and hci frames. In addition, hci and spinel frames can be +distinguished by using the Spinel convention which is line compatible with +BT/BLE HCI. + +Before building the Matter host application, it is required to generate the +K32W0 image supporting features as described above. To build this binary the +target `ot_rcp_ble_hci_bb_single_uart_fc` should be built by following the +[Readme.md][ot_rcp_ble_hci_bb_k32w0_readme]. After a successful build, a `".h"` +file will be generated and would contain the K32W0 RCP binary. As described in +the [Readme.md][ot_rcp_ble_hci_bb_k32w0_readme], the application binaries will +be generated in +`ot_nxp/build_k32w061/ot_rcp_ble_hci_bb_single_uart_fc/bin/ot-rcp-ble-hci-bb-k32w061.elf.bin.h`. + +The generate K32W0 transceiver binary `".h"` file path must be indicated to the +host Matter application build. In fact the Matter host application is in charge +of storing the K32W0 firmware in its flash to be able to use the +`The Over The Wire (OTW) protocol (over UART)` to download (at host startup) the +k32w0 transceiver image from the host to the K32W0 internal flash. For more +information on the k32w0 `OTW` protocol, user can consult the doxygen header of +the file located in +`/third_party/nxp/nxp_matter_support/github_sdk/common_sdk/repo/middleware/wireless/framework/OTW/k32w0_transceiver/fwk_otw.c`. + +Here is a summary of the k32w0 _gn gen_ arguments that are mandatory or +optional: + +- Mandatory: `k32w0_transceiver=true` +- Mandatory: `hci_spinel_single_uart=true` +- Optional: + `k32w0_transceiver_bin_path=\"/home/ot-nxp/build_k32w061/ot_rcp_ble_hci_bb_single_uart_fc/bin/ot-rcp-ble-hci-bb-k32w061.elf.bin.h\"` + This argument is optional, by default, if not set, the binary file located + in + "\${chip_root}/third_party/openthread/ot_nxp/build_k32w061/ot_rcp_ble_hci_bb_single_uart_fc/bin/ot-rcp-ble-hci-bb-k32w061.elf.bin.h" + will be used. If the K32W061 transceiver binary is saved at another location + an absolute path of its location should be given. +- Optional: `otw_logs_enabled=true` This argument is optional, by default + being set to false. If set to true, RT logging will print the `OTW` logs. + +[ot_rcp_ble_hci_bb_k32w0_readme]: + https://github.com/NXP/ot-nxp/blob/v1.0.0.2-tag-nxp/examples/hybrid/ot_rcp_ble_hci_bb/k32w061/README.md#building-the-examples + +Below is presented an example of _gn gen_ argument that could be used to +generate the host matter application with a k32w0 transceiver. + +``` +user@ubuntu:~/Desktop/git/connectedhomeip/examples/all-clusters-app/nxp/rt/rt1060$ gn gen --args="chip_enable_openthread=true k32w0_transceiver=true k32w0_transceiver_bin_path=\"/home/ot-nxp/build_k32w061/ot_rcp_ble_hci_bb_single_uart_fc/bin/ot-rcp-ble-hci-bb-k32w061.elf.bin.h\" hci_spinel_single_uart=true chip_inet_config_enable_ipv4=false chip_config_network_layer_ble=true" out/debug +user@ubuntu:~/Desktop/git/connectedhomeip/examples/all-clusters-app/nxp/rt/rt1060$ ninja -C out/debug +``` + +#### Build with Matter over Thread configuration on RT1060-EVK-C + IW612 + +Build the OpenThread configuration for MIMXRT1060-EVK-C board + IW612 +transceiver (with BLE for commissioning). + +``` +user@ubuntu:~/Desktop/git/connectedhomeip/examples/all-clusters-app/nxp/rt/rt1060$ gn gen --args="chip_enable_openthread=true iwx12_transceiver=true evkname=\"evkcmimxrt1060\" chip_inet_config_enable_ipv4=false chip_config_network_layer_ble=true" " out/debug +user@ubuntu:~/Desktop/git/connectedhomeip/examples/all-clusters-app/nxp/rt/rt1060$ ninja -C out/debug +``` + +### Build with Matter over Wi-Fi + OpenThread Border Router configuration on RT1060 + 88W8801 + K32W0x1DK6 + +This configuration supports the Thread Border Router management cluster to +provision the Thread credentials. Enabling the Matter CLI in order to control +the Thread network on the Border Router is optional but recommended for other +features like the Thread credential sharing. + +Note that the Thread Border Router management cluster is only supported on the +thermostat application for now. + +- Build Matter with Border Router configuration with ble-wifi commissioning: + +``` +user@ubuntu:~/Desktop/git/connectedhomeip/examples/all-clusters-app/nxp/rt/rt1060$ gn gen --args="chip_enable_wifi=true w8801_transceiver=true chip_enable_matter_cli=true chip_config_network_layer_ble=true chip_enable_openthread=true k32w0_transceiver=true k32w0_transceiver_bin_path=\"/path/to/ot-rcp/ot-rcp-ble-hci-bb-k32w061.elf.bin.h\" hci_spinel_single_uart=true" out/debug +user@ubuntu:~/Desktop/git/connectedhomeip/examples/all-clusters-app/nxp/rt/rt1060$ ninja -C out/debug +``` + +- Build Matter with Border Router configuration with onnetwork commissioning: + +``` +user@ubuntu:~/Desktop/git/connectedhomeip/examples/all-clusters-app/nxp/rt/rt1060$ gn gen --args="chip_enable_wifi=true w8801_transceiver=true chip_enable_matter_cli=true chip_config_network_layer_ble=false wifi_auto_connect_at_boot=true wifi_auto_connect_at_boot_ssid=\"your_wifi_ssid\" wifi_auto_connect_at_boot_password=\"your_wifi_password\" chip_enable_openthread=true k32w0_transceiver=true k32w0_transceiver_bin_path=\"/path/to/ot-rcp/ot-rcp-ble-hci-bb-k32w061.elf.bin.h\"" out/debug +user@ubuntu:~/Desktop/git/connectedhomeip/examples/all-clusters-app/nxp/rt/rt1060$ ninja -C out/debug +``` + +### General Information + +The resulting output file can be found in +out/debug/chip-rt1060-all-cluster-example. + +Optional GN options that can be added when building an application: + +- To enable the + [secondary network commissioning interface](../../../../../docs/platforms/nxp/nxp_otbr_guide.md#using-the-secondary-network-commissioning-interface), + the arguments `chip_enable_secondary_nwk_if=true` and + `chip_device_config_thread_network_endpoint_id=3` must be added to the _gn + gen_ command. Note that this is only supported when building the Matter over + Wifi + OpenThread Border Router configuration. Note that is only supported + on the on the thermostat application for now. +- To enable the [matter CLI](README.md#matter-shell), the argument + `chip_enable_matter_cli=true` must be added to the _gn gen_ command. +- To build the application in debug mode, the argument + `is_debug=true optimize_debug=false` must be added to the _gn gen_ command. +- By default, the MIMXRT1060-EVK-B will be chosen. To switch to an + MIMXRT1060-EVK, the argument `evkname=\"evkmimxrt1060\"` must be added to + the _gn gen_ command. +- To build with the option to have Matter certificates/keys pre-loaded in a + specific flash area the argument `chip_with_factory_data=1` must be added to + the _gn gen_ command. For more information, see + [Guide for writing manufacturing data on NXP devices](../../../../../docs/platforms/nxp/nxp_manufacturing_flow.md) + + + +## Manufacturing data + +See +[Guide for writing manufacturing data on NXP devices](../../../../../docs/platforms/nxp/nxp_manufacturing_flow.md) + +Other comments: + +The RT1060 all cluster app demonstrates the usage of encrypted Matter +manufacturing data storage. Matter manufacturing data should be encrypted before +flashing them to the RT1060 flash. + +For development purpose the RT1060 all cluster app code could use the hardcoded +AES 128 software key. This software key should be used only during development +stage. + +For production usage, it is recommended to use the `OTP key` which needs to be +fused in the RT1060 SW_GP2. The application note AN12800 should be followed to +get more information. In this case the all cluster app should be updated to +indicate to the `DCP` module to use the `OTP key` instead of the software key. +For that the call to `FactoryDataPrvdImpl().SetAes128Key()` should be changed to +`FactoryDataPrvdImpl().SetKeySelected(KeySelect::)` with the arg value +specifying where the `OTP key` is stored (`kDCP_OCOTPKeyLow` for [127:0] of +SW_GP2 or `kDCP_OCOTPKeyHigh` for [255:128] of SW_GP2). For more information the +RT1060 `FactoryDataProviderImpl` class description should be checked. + + + +## Flashing and debugging + +In order to flash the application we recommend using +[MCUXpresso IDE (version >= 11.6.0)](https://www.nxp.com/design/software/development-software/mcuxpresso-software-and-tools-/mcuxpresso-integrated-development-environment-ide:MCUXpresso-IDE). + +- Import the previously downloaded NXP SDK into MCUXpresso IDE. + +Right click the empty space in the MCUXpresso IDE "Installed SDKs" tab to show +the menu, select the "Import local SDK Git repository" menu item. + +![Import local SDK Git repository](../../../../platform/nxp/rt/rt1060/doc/images/import-local-repository.png) + +The "Import SDK Git" window will open. The "Repository location" text field +should point to the west workspace +(third_party/nxp/nxp_matter_support/github_sdk/common_sdk/repo subfolder of the +Matter repository). The "Manifest(s) folder" text field should point to its core +subfolder (third_party/nxp/nxp_matter_support/github_sdk/common_sdk/repo/core +subfolder of the Matter repository). Click "OK" and wait for MCUXpresso IDE to +import the SDK. + +![Import SDK Git](../../../../platform/nxp/rt/rt1060/doc/images/import-sdk-git.png) + +Finally select the desired board's SDK manifest in the "Installed SDKs" tab. + +![Select SDK](../../../../platform/nxp/rt/rt1060/doc/images/select-sdk.png) + +- Import the connectedhomeip repo in MCUXpresso IDE as Makefile Project. Use + _none_ as _Toolchain for Indexer Settings_: + +``` +File -> Import -> C/C++ -> Existing Code as Makefile Project +``` + +- Configure MCU Settings: + +``` +Right click on the Project -> Properties -> C/C++ Build -> MCU Settings -> Select MIMXRT1060 -> Apply & Close +``` + +![MCU_Set](../../../../platform/nxp/rt/rt1060/doc/images/mcu-set.png) + +Sometimes when the MCU is selected it will not initialize all the memory regions +(usually the `BOARD_FLASH`, `BOARD_SDRAM` and `NCACHE_REGION`) so it is required +that this regions are added manually like in the image above. In addition to +that on the `BOARD_FLASH` line, in the driver tab: + +``` +click inside the tab and on the right side a button with three horizontal dots will appear +click on the button and an window will show +form the dropdown menu select the MIMXRT1060_SFDP_QSPI driver +``` + +![flash_driver](../../../../platform/nxp/rt/rt1060/doc/images/flash_driver.png) + +- Configure the toolchain editor: + +``` +Right click on the Project -> C/C++ Build-> Tool Chain Editor -> NXP MCU Tools -> Apply & Close +``` + +![toolchain](../../../../platform/nxp/rt/rt1060/doc/images/toolchain.JPG) + +- Create a debug configuration: + +``` +Right click on the Project -> Debug -> As->MCUXpresso IDE LinkServer (inc. CMSIS-DAP) probes -> OK -> Select elf file +``` + +![debug_0](../../../../platform/nxp/rt/rt1060/doc/images/debug0.png) + +![debug_1](../../../../platform/nxp/rt/rt1060/doc/images/debug1.png) + +- Set the _Connect script_ for the debug configuration to _RT1060_connect.scp_ + from the dropdown list: + +``` +Right click on the Project -> Debug As -> Debug configurations... -> LinkServer Debugger +``` + +![connect](../../../../platform/nxp/rt/rt1060/doc/images/gdbdebugger.png) + +- Set the _Initialization Commands_ to: + +``` +Right click on the Project -> Debug As -> Debug configurations... -> Startup + +set non-stop on +set pagination off +set mi-async +set remotetimeout 60000 +##target_extended_remote## +set mem inaccessible-by-default ${mem.access} +mon ondisconnect ${ondisconnect} +set arm force-mode thumb +${load} +``` + +![init](../../../../platform/nxp/rt/rt1060/doc/images/startup.png) + +- Set the _vector.catch_ value to _false_ inside the .launch file: + +``` +Right click on the Project -> Utilities -> Open Directory Browser here -> edit *.launch file: + + + +``` + +- Debug using the newly created configuration file: + + + +## Testing the example + +To know how to commission a device over BLE, follow the instructions from +[chip-tool's README.md 'Commission a device over +BLE'][readme_ble_commissioning_section]. + +[readme_ble_commissioning_section]: + ../../../../chip-tool/README.md#commission-a-device-over-ble + +To know how to commissioning a device over IP, follow the instructions from +[chip-tool's README.md 'Pair a device over +IP'][readme_pair_ip_commissioning_section] + +[readme_pair_ip_commissioning_section]: + ../../../../chip-tool/README.md#pair-a-device-over-ip + +#### Matter over wifi configuration : + +The "ble-wifi" pairing method can be used in order to commission the device. + +#### Matter over thread configuration : + +The "ble-thread" pairing method can be used in order to commission the device. + +#### Matter over wifi with openthread border router configuration : + +In order to create or join a Thread network on the Matter Border Router, the TBR +management cluster or the `otcli` commands from the matter CLI can be used. For +more information about using the TBR management cluster follow instructions from +['Using the TBR management cluster'](../../../../../docs/platforms/nxp/nxp_otbr_guide.md#using-the-thread-border-router-management-cluster). +For more information about using the matter shell, follow instructions from +['Testing the all-clusters application with Matter CLI'](#testing-the-all-clusters-application-with-matter-cli-enabled). + +In this configuration, the device can be commissioned over Wi-Fi with the +'ble-wifi' or 'onnetwork' pairing method. + +### Testing the all-clusters application without Matter CLI: + +1. Prepare the board with the flashed `All-cluster application` (as shown + above). +2. The All-cluster example uses UART1 to print logs while running the server. To + view raw UART output, start a terminal emulator like PuTTY and connect to the + used COM port with the following UART settings: + + - Baud rate: 115200 + - 8 data bits + - 1 stop bit + - No parity + - No flow control + +3. Open a terminal connection on the board and watch the printed logs. + +4. On the client side, start sending commands using the chip-tool application as + it is described + [here](../../../../chip-tool/README.md#using-the-client-to-send-matter-commands). + +### Testing the all-clusters application with Matter CLI enabled: + +The Matter CLI can be enabled with the all-clusters application. + +For more information about the Matter CLI default commands, you can refer to the +dedicated [ReadMe](../../../../shell/README.md). + +The All-clusters application supports additional commands : + +``` +> help +[...] +mattercommissioning Open/close the commissioning window. Usage : mattercommissioning [on|off] +matterfactoryreset Perform a factory reset on the device +matterreset Reset the device +``` + +- `matterfactoryreset` command erases the file system completely (all Matter + settings are erased). +- `matterreset` enables the device to reboot without erasing the settings. + +Here are described steps to use the all-cluster-app with the Matter CLI enabled + +1. Prepare the board with the flashed `All-cluster application` (as shown + above). +2. The matter CLI is accessible in UART1. For that, start a terminal emulator + like PuTTY and connect to the used COM port with the following UART settings: + + - Baud rate: 115200 + - 8 data bits + - 1 stop bit + - No parity + - No flow control + +3. The All-cluster example uses UART2 to print logs while running the server. To + view raw UART output, a pin should be plugged to an USB to UART adapter + (connector J16 pin 7 in case of MIMXRT1060-EVK-B board or connector J22 pin 7 + in case of MIMXRT1060-EVK board), then start a terminal emulator like PuTTY + and connect to the used COM port with the following UART settings: + + - Baud rate: 115200 + - 8 data bits + - 1 stop bit + - No parity + - No flow control + +4. On the client side, start sending commands using the chip-tool application as + it is described + [here](../../../../chip-tool/README.md#using-the-client-to-send-matter-commands). + +For Matter with OpenThread Border Router support, the matter CLI can be used to +start/join the Thread network, using the following ot-cli commands. (Note that +setting channel, panid, and network key is not enough anymore because of an Open +Thread stack update. We first need to initialize a new dataset.) + +``` +> otcli dataset init new +Done +> otcli dataset +Active Timestamp: 1 +Channel: 25 +Channel Mask: 0x07fff800 +Ext PAN ID: 42af793f623aab54 +Mesh Local Prefix: fd6e:c358:7078:5a8d::/64 +Network Key: f824658f79d8ca033fbb85ecc3ca91cc +Network Name: OpenThread-b870 +PAN ID: 0xb870 +PSKc: f438a194a5e968cc43cc4b3a6f560ca4 +Security Policy: 672 onrc 0 +Done +> otcli dataset panid 0xabcd +Done +> otcli dataset channel 25 +Done +> otcli dataset commit active +Done +> otcli ifconfig up +Done +> otcli thread start +Done +> otcli state +leader +Done +``` + + + +## Thread Border Router overview + +To enable Thread Border Router support see the [build](README.md#building) +section. + +The complete Border Router guide is located +[here](../../../../../docs/platforms/nxp/nxp_otbr_guide.md). diff --git a/examples/all-clusters-app/nxp/rt/rt1060/args.gni b/examples/all-clusters-app/nxp/rt/rt1060/args.gni new file mode 100644 index 00000000000000..c2d91a5db7bae7 --- /dev/null +++ b/examples/all-clusters-app/nxp/rt/rt1060/args.gni @@ -0,0 +1,19 @@ +# Copyright (c) 2023 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/chip.gni") + +# SDK target definitions +nxp_sdk_target = get_label_info(":sdk", "label_no_toolchain") +nxp_sdk_driver_target = get_label_info(":sdk_driver", "label_no_toolchain") diff --git a/examples/all-clusters-app/nxp/rt/rt1060/build_overrides b/examples/all-clusters-app/nxp/rt/rt1060/build_overrides new file mode 120000 index 00000000000000..f10867042f4d19 --- /dev/null +++ b/examples/all-clusters-app/nxp/rt/rt1060/build_overrides @@ -0,0 +1 @@ +../../../../build_overrides \ No newline at end of file diff --git a/examples/all-clusters-app/nxp/rt/rt1060/include/config/CHIPProjectConfig.h b/examples/all-clusters-app/nxp/rt/rt1060/include/config/CHIPProjectConfig.h new file mode 100644 index 00000000000000..dd73c6c9eaaedd --- /dev/null +++ b/examples/all-clusters-app/nxp/rt/rt1060/include/config/CHIPProjectConfig.h @@ -0,0 +1,216 @@ +/* + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2020 Google LLC. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Example project configuration file for CHIP. + * + * This is a place to put application or project-specific overrides + * to the default configuration values for general CHIP features. + * + */ + +#pragma once + +/* + * Tells to the platform Factory Data Provider whether to use the example configuration or real/provisioned data. + */ +#ifndef CONFIG_CHIP_PLAT_LOAD_REAL_FACTORY_DATA +#define CONFIG_CHIP_PLAT_LOAD_REAL_FACTORY_DATA 0 +#endif + +/** + * CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID + * + * 0xFFF1: Test vendor. + */ +#define CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID 0xFFF1 + +/** + * CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID + * + */ +#define CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID 0x8005 + +#if !CONFIG_CHIP_PLAT_LOAD_REAL_FACTORY_DATA +// Use a default pairing code if one hasn't been provisioned in flash. +#ifndef CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE +#define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE 20202021 +#endif + +#ifndef CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR +#define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR 0xF00 +#endif + +// Use a default pairing code if one hasn't been provisioned in flash. +#define CHIP_DEVICE_CONFIG_USE_TEST_PAIRING_CODE "CHIPUS" + +/** + * CHIP_DEVICE_CONFIG_USE_TEST_SERIAL_NUMBER + * + * Enables the use of a hard-coded default serial number if none + * is found in CHIP NV storage. + */ +#define CHIP_DEVICE_CONFIG_USE_TEST_SERIAL_NUMBER "DUMMY_SN" + +#endif /* !CONFIG_CHIP_PLAT_LOAD_REAL_FACTORY_DATA */ + +/** + * CHIP_DEVICE_CONFIG_DEVICE_HARDWARE_VERSION + * + * The hardware version number assigned to device or product by the device vendor. This + * number is scoped to the device product id, and typically corresponds to a revision of the + * physical device, a change to its packaging, and/or a change to its marketing presentation. + * This value is generally *not* incremented for device software versions. + */ +#define CHIP_DEVICE_CONFIG_DEVICE_HARDWARE_VERSION 100 + +#ifndef CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION_STRING +#define CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION_STRING "v0.1.0" +#endif + +/** + * CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING + * + * A string identifying the software version running on the device. + * CHIP currently expects the software version to be in the format + * {MAJOR_VERSION}.0d{MINOR_VERSION} + */ +#ifndef CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING +#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING NXP_CONFIG_DEVICE_SOFTWARE_VERSION_STRING +#endif + +#ifndef CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION +#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION NXP_CONFIG_DEVICE_SOFTWARE_VERSION +#endif + +#ifndef CHIP_DEVICE_CONFIG_DEVICE_VENDOR_NAME +#define CHIP_DEVICE_CONFIG_DEVICE_VENDOR_NAME "NXP Semiconductors" +#endif + +#ifndef CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_NAME +#define CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_NAME "NXP Demo App" +#endif + +#ifndef CHIP_DEVICE_CONFIG_CERTIFICATION_DECLARATION +//-> format_version = 1 +//-> vendor_id = 0xFFF1 +//-> product_id_array = [ 0x8000, 0x8001, 0x8002, 0x8003, 0x8004, 0x8005, 0x8006, 0x8007, 0x8008, 0x8009, 0x800A, 0x800B, +// 0x800C, 0x800D, 0x800E, 0x800F, 0x8010, 0x8011, 0x8012, 0x8013, 0x8014, 0x8015, 0x8016, 0x8017, 0x8018, 0x8019, 0x801A, +// 0x801B, 0x801C, 0x801D, 0x801E, 0x801F, 0x8020, 0x8021, 0x8022, 0x8023, 0x8024, 0x8025, 0x8026, 0x8027, 0x8028, 0x8029, +// 0x802A, 0x802B, 0x802C, 0x802D, 0x802E, 0x802F, 0x8030, 0x8031, 0x8032, 0x8033, 0x8034, 0x8035, 0x8036, 0x8037, 0x8038, +// 0x8039, 0x803A, 0x803B, 0x803C, 0x803D, 0x803E, 0x803F, 0x8040, 0x8041, 0x8042, 0x8043, 0x8044, 0x8045, 0x8046, 0x8047, +// 0x8048, 0x8049, 0x804A, 0x804B, 0x804C, 0x804D, 0x804E, 0x804F, 0x8050, 0x8051, 0x8052, 0x8053, 0x8054, 0x8055, 0x8056, +// 0x8057, 0x8058, 0x8059, 0x805A, 0x805B, 0x805C, 0x805D, 0x805E, 0x805F, 0x8060, 0x8061, 0x8062, 0x8063 ] +//-> device_type_id = 0x0016 +//-> certificate_id = "ZIG20142ZB330003-24" +//-> security_level = 0 +//-> security_information = 0 +//-> version_number = 0x2694 +//-> certification_type = 0 +//-> dac_origin_vendor_id is not present +//-> dac_origin_product_id is not present +#define CHIP_DEVICE_CONFIG_CERTIFICATION_DECLARATION \ + { \ + 0x30, 0x82, 0x02, 0x19, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x82, 0x02, 0x0a, 0x30, \ + 0x82, 0x02, 0x06, 0x02, 0x01, 0x03, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, \ + 0x02, 0x01, 0x30, 0x82, 0x01, 0x71, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, \ + 0x01, 0x62, 0x04, 0x82, 0x01, 0x5e, 0x15, 0x24, 0x00, 0x01, 0x25, 0x01, 0xf1, 0xff, 0x36, 0x02, 0x05, 0x00, 0x80, \ + 0x05, 0x01, 0x80, 0x05, 0x02, 0x80, 0x05, 0x03, 0x80, 0x05, 0x04, 0x80, 0x05, 0x05, 0x80, 0x05, 0x06, 0x80, 0x05, \ + 0x07, 0x80, 0x05, 0x08, 0x80, 0x05, 0x09, 0x80, 0x05, 0x0a, 0x80, 0x05, 0x0b, 0x80, 0x05, 0x0c, 0x80, 0x05, 0x0d, \ + 0x80, 0x05, 0x0e, 0x80, 0x05, 0x0f, 0x80, 0x05, 0x10, 0x80, 0x05, 0x11, 0x80, 0x05, 0x12, 0x80, 0x05, 0x13, 0x80, \ + 0x05, 0x14, 0x80, 0x05, 0x15, 0x80, 0x05, 0x16, 0x80, 0x05, 0x17, 0x80, 0x05, 0x18, 0x80, 0x05, 0x19, 0x80, 0x05, \ + 0x1a, 0x80, 0x05, 0x1b, 0x80, 0x05, 0x1c, 0x80, 0x05, 0x1d, 0x80, 0x05, 0x1e, 0x80, 0x05, 0x1f, 0x80, 0x05, 0x20, \ + 0x80, 0x05, 0x21, 0x80, 0x05, 0x22, 0x80, 0x05, 0x23, 0x80, 0x05, 0x24, 0x80, 0x05, 0x25, 0x80, 0x05, 0x26, 0x80, \ + 0x05, 0x27, 0x80, 0x05, 0x28, 0x80, 0x05, 0x29, 0x80, 0x05, 0x2a, 0x80, 0x05, 0x2b, 0x80, 0x05, 0x2c, 0x80, 0x05, \ + 0x2d, 0x80, 0x05, 0x2e, 0x80, 0x05, 0x2f, 0x80, 0x05, 0x30, 0x80, 0x05, 0x31, 0x80, 0x05, 0x32, 0x80, 0x05, 0x33, \ + 0x80, 0x05, 0x34, 0x80, 0x05, 0x35, 0x80, 0x05, 0x36, 0x80, 0x05, 0x37, 0x80, 0x05, 0x38, 0x80, 0x05, 0x39, 0x80, \ + 0x05, 0x3a, 0x80, 0x05, 0x3b, 0x80, 0x05, 0x3c, 0x80, 0x05, 0x3d, 0x80, 0x05, 0x3e, 0x80, 0x05, 0x3f, 0x80, 0x05, \ + 0x40, 0x80, 0x05, 0x41, 0x80, 0x05, 0x42, 0x80, 0x05, 0x43, 0x80, 0x05, 0x44, 0x80, 0x05, 0x45, 0x80, 0x05, 0x46, \ + 0x80, 0x05, 0x47, 0x80, 0x05, 0x48, 0x80, 0x05, 0x49, 0x80, 0x05, 0x4a, 0x80, 0x05, 0x4b, 0x80, 0x05, 0x4c, 0x80, \ + 0x05, 0x4d, 0x80, 0x05, 0x4e, 0x80, 0x05, 0x4f, 0x80, 0x05, 0x50, 0x80, 0x05, 0x51, 0x80, 0x05, 0x52, 0x80, 0x05, \ + 0x53, 0x80, 0x05, 0x54, 0x80, 0x05, 0x55, 0x80, 0x05, 0x56, 0x80, 0x05, 0x57, 0x80, 0x05, 0x58, 0x80, 0x05, 0x59, \ + 0x80, 0x05, 0x5a, 0x80, 0x05, 0x5b, 0x80, 0x05, 0x5c, 0x80, 0x05, 0x5d, 0x80, 0x05, 0x5e, 0x80, 0x05, 0x5f, 0x80, \ + 0x05, 0x60, 0x80, 0x05, 0x61, 0x80, 0x05, 0x62, 0x80, 0x05, 0x63, 0x80, 0x18, 0x24, 0x03, 0x16, 0x2c, 0x04, 0x13, \ + 0x5a, 0x49, 0x47, 0x32, 0x30, 0x31, 0x34, 0x32, 0x5a, 0x42, 0x33, 0x33, 0x30, 0x30, 0x30, 0x33, 0x2d, 0x32, 0x34, \ + 0x24, 0x05, 0x00, 0x24, 0x06, 0x00, 0x25, 0x07, 0x94, 0x26, 0x24, 0x08, 0x00, 0x18, 0x31, 0x7d, 0x30, 0x7b, 0x02, \ + 0x01, 0x03, 0x80, 0x14, 0x62, 0xfa, 0x82, 0x33, 0x59, 0xac, 0xfa, 0xa9, 0x96, 0x3e, 0x1c, 0xfa, 0x14, 0x0a, 0xdd, \ + 0xf5, 0x04, 0xf3, 0x71, 0x60, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x30, \ + 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x04, 0x47, 0x30, 0x45, 0x02, 0x20, 0x24, 0xe5, \ + 0xd1, 0xf4, 0x7a, 0x7d, 0x7b, 0x0d, 0x20, 0x6a, 0x26, 0xef, 0x69, 0x9b, 0x7c, 0x97, 0x57, 0xb7, 0x2d, 0x46, 0x90, \ + 0x89, 0xde, 0x31, 0x92, 0xe6, 0x78, 0xc7, 0x45, 0xe7, 0xf6, 0x0c, 0x02, 0x21, 0x00, 0xf8, 0xaa, 0x2f, 0xa7, 0x11, \ + 0xfc, 0xb7, 0x9b, 0x97, 0xe3, 0x97, 0xce, 0xda, 0x66, 0x7b, 0xae, 0x46, 0x4e, 0x2b, 0xd3, 0xff, 0xdf, 0xc3, 0xcc, \ + 0xed, 0x7a, 0xa8, 0xca, 0x5f, 0x4c, 0x1a, 0x7c \ + } +#endif + +/** + * CHIP_DEVICE_CONFIG_ENABLE_CHIP_TIME_SERVICE_TIME_SYNC + * + * Enables synchronizing the device's real time clock with a remote CHIP Time service + * using the CHIP Time Sync protocol. + */ +// #define CHIP_DEVICE_CONFIG_ENABLE_CHIP_TIME_SERVICE_TIME_SYNC 1 + +/** + * CHIP_CONFIG_MAX_BINDINGS + * + * Maximum number of simultaneously active bindings per ChipExchangeManager + * 1 (Time Sync) + 2 (Two 1-way subscriptions) + 1 (Software Update) = 4 + * in the worst case. Keeping another 4 as buffer. + */ +#define CHIP_CONFIG_MAX_BINDINGS 6 + +/** + * CHIP_CONFIG_EVENT_LOGGING_WDM_OFFLOAD + * + * Select the ability to offload event logs to any interested subscribers using WDM. + */ +#define CHIP_CONFIG_EVENT_LOGGING_WDM_OFFLOAD 1 + +/** + * CHIP_CONFIG_EVENT_LOGGING_UTC_TIMESTAMPS + * + * Enable recording UTC timestamps. + */ +#define CHIP_CONFIG_EVENT_LOGGING_UTC_TIMESTAMPS 1 + +/** + * CHIP_DEVICE_CONFIG_EVENT_LOGGING_DEBUG_BUFFER_SIZE + * + * A size, in bytes, of the individual debug event logging buffer. + */ +#define CHIP_DEVICE_CONFIG_EVENT_LOGGING_DEBUG_BUFFER_SIZE (512) + +/** + * CHIP_CONFIG_EVENT_LOGGING_DEFAULT_IMPORTANCE + * + * For a development build, set the default importance of events to be logged as Debug. + * Since debug is the lowest importance level, this means all standard, critical, info and + * debug importance level vi events get logged. + */ +#if BUILD_RELEASE +#define CHIP_CONFIG_EVENT_LOGGING_DEFAULT_IMPORTANCE chip::Profiles::DataManagement::Production +#else +#define CHIP_CONFIG_EVENT_LOGGING_DEFAULT_IMPORTANCE chip::Profiles::DataManagement::Debug +#endif // BUILD_RELEASE + +/* Increasing the retransmission interval of the MRP messages after subsequent failures */ +#ifndef CHIP_CONFIG_MRP_LOCAL_ACTIVE_RETRY_INTERVAL +#define CHIP_CONFIG_MRP_LOCAL_ACTIVE_RETRY_INTERVAL (2000_ms32) +#endif diff --git a/examples/all-clusters-app/nxp/rt/rt1060/third_party/connectedhomeip b/examples/all-clusters-app/nxp/rt/rt1060/third_party/connectedhomeip new file mode 120000 index 00000000000000..305f2077ffe860 --- /dev/null +++ b/examples/all-clusters-app/nxp/rt/rt1060/third_party/connectedhomeip @@ -0,0 +1 @@ +../../../../../.. \ No newline at end of file diff --git a/examples/all-clusters-app/nxp/rt/rt1170/.gn b/examples/all-clusters-app/nxp/rt/rt1170/.gn new file mode 100644 index 00000000000000..59dcfeb229ae70 --- /dev/null +++ b/examples/all-clusters-app/nxp/rt/rt1170/.gn @@ -0,0 +1,35 @@ +# Copyright (c) 2020 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/build.gni") +import("//build_overrides/chip.gni") + +# The location of the build configuration file. +buildconfig = "${build_root}/config/BUILDCONFIG.gn" + +# CHIP uses angle bracket includes. +check_system_includes = true + +default_args = { + target_cpu = "arm" + target_os = "freertos" + + import("//args.gni") + + # Import common example GN args + import("${chip_root}/examples/platform/nxp/common/gn/args.gni") + + # Import default platform configs + import("${chip_root}/src/platform/nxp/rt/rt1170/args.gni") +} diff --git a/examples/all-clusters-app/nxp/rt/rt1170/BUILD.gn b/examples/all-clusters-app/nxp/rt/rt1170/BUILD.gn new file mode 100644 index 00000000000000..724a6e89ec6558 --- /dev/null +++ b/examples/all-clusters-app/nxp/rt/rt1170/BUILD.gn @@ -0,0 +1,241 @@ +# Copyright (c) 2021-2023 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/build.gni") +import("//build_overrides/chip.gni") +import("//build_overrides/nxp_sdk.gni") +import("//build_overrides/openthread.gni") +import("${chip_root}/src/platform/device.gni") + +#allows to get common NXP SDK gn options +import("${nxp_sdk_build_root}/nxp_sdk.gni") + +# Allows to get various RT gn options +import("${nxp_sdk_build_root}/${nxp_sdk_name}/rt_sdk.gni") + +import("${chip_root}/src/platform/nxp/${nxp_platform}/args.gni") +import( + "${nxp_sdk_build_root}/${nxp_sdk_name}/${rt_platform}/${rt_platform}.gni") +import("${nxp_sdk_build_root}/${nxp_sdk_name}/nxp_executable.gni") + +assert(current_os == "freertos") +assert(target_os == "freertos") +assert(nxp_platform == "rt/rt1170") + +declare_args() { + # Allows to connect to a predefine Wi-Fi network at boot + wifi_auto_connect_at_boot = false + wifi_auto_connect_at_boot_ssid = "" + wifi_auto_connect_at_boot_password = "" + + # Setup discriminator as argument + setup_discriminator = 3840 +} + +example_platform_dir = + "${nxp_sdk_matter_support_root}/examples/platform/${nxp_platform}" +common_example_dir = "${chip_root}/examples/platform/nxp/common" + +app_common_folder = "all-clusters-app/all-clusters-common" + +# Create here the SDK instance. +# Particular sources/defines/includes could be added/changed depending on the target application. +rt_sdk("sdk") { + defines = [] + + cflags = [] + public_deps = [] + public_configs = [] + sources = [] + include_dirs = [] + + # Indicate paths to default board files + include_dirs += [ "${example_platform_dir}/board/" ] + sources += [ "${example_platform_dir}/board/pin_mux.c" ] + sources += [ "${example_platform_dir}/board/hardware_init.c" ] + sources += [ "${example_platform_dir}/board/clock_config.c" ] + sources += [ "${example_platform_dir}/board/board.c" ] + sources += [ "${example_platform_dir}/board/peripherals.c" ] + sources += [ "${example_platform_dir}/board/sdmmc_config.c" ] + + # Indicate the path to CHIPProjectConfig.h + include_dirs += [ "include/config" ] + + # Indicate the default path to FreeRTOSConfig.h + include_dirs += [ "${example_platform_dir}/app/project_include/freeRTOS" ] + + # Indicate the default path to OpenThreadConfig.h + include_dirs += [ "${example_platform_dir}/app/project_include/openthread" ] + + # For matter with BR feature, increase FreeRTOS heap size + if (chip_enable_wifi && chip_enable_openthread) { + defines += [ "configTOTAL_HEAP_SIZE=(size_t)(170 * 1024)" ] + } + + defines += [ + "CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR=${setup_discriminator}", + ] +} + +# Create the SDK driver instance. +# Particular sources/defines/includes could be added to add other drivers not available in the default sdk driver template +rt1170_sdk_drivers("sdk_driver") { +} + +rt_executable("all_cluster_app") { + output_name = "chip-rt1170-all-cluster-example" + + defines = [ + "CONFIG_RENDEZVOUS_MODE=7", + "CONFIG_APP_FREERTOS_OS=1", + ] + + if (chip_enable_openthread) { + defines += [ "CONFIG_NET_L2_OPENTHREAD=1" ] + } + + include_dirs = [ + "../../common/main/include", + "../../common/main", + "${chip_root}/examples/all-clusters-app/all-clusters-common/include", + "${chip_root}/examples/providers/", + ] + + sources = [ + "${chip_root}/examples/all-clusters-app/all-clusters-common/src/binding-handler.cpp", + "${chip_root}/examples/providers/DeviceInfoProviderImpl.cpp", + "../../common/main/AppTask.cpp", + "../../common/main/DeviceCallbacks.cpp", + "../../common/main/ZclCallbacks.cpp", + "../../common/main/include/AppEvent.h", + "../../common/main/include/AppTask.h", + "../../common/main/include/DeviceCallbacks.h", + "../../common/main/main.cpp", + ] + + # App common files + include_dirs += [ + "${common_example_dir}/icd/include", + "${common_example_dir}/matter_button/include", + "${common_example_dir}/matter_cli/include", + "${common_example_dir}/device_manager/include", + "${common_example_dir}/device_callbacks/include", + "${common_example_dir}/factory_data/include", + "${common_example_dir}/app_task/include", + ] + + sources += [ + "${common_example_dir}/app_task/source/AppTaskBase.cpp", + "${common_example_dir}/app_task/source/AppTaskFreeRTOS.cpp", + "${common_example_dir}/device_callbacks/source/CommonDeviceCallbacks.cpp", + "${common_example_dir}/device_manager/source/CHIPDeviceManager.cpp", + "${common_example_dir}/factory_data/source/AppFactoryDataDefaultImpl.cpp", + "${common_example_dir}/icd/source/ICDUtil.cpp", + "${common_example_dir}/matter_button/source/ButtonRegistrationEmpty.cpp", + ] + + deps = [ "${chip_root}/examples/${app_common_folder}" ] + + sources += [ + "${chip_root}/examples/${app_common_folder}/src/bridged-actions-stub.cpp", + "${chip_root}/examples/${app_common_folder}/src/smco-stub.cpp", + "${chip_root}/examples/${app_common_folder}/src/static-supported-modes-manager.cpp", + ] + + if (chip_enable_matter_cli) { + defines += [ "ENABLE_CHIP_SHELL" ] + deps += [ + "${chip_root}/examples/shell/shell_common:shell_common", + "${chip_root}/src/lib/shell:shell", + ] + sources += [ + "${common_example_dir}/matter_cli/source/AppCLIBase.cpp", + "${common_example_dir}/matter_cli/source/AppCLIFreeRTOS.cpp", + ] + } + + if (chip_enable_ota_requestor) { + include_dirs += [ "${common_example_dir}/ota_requestor/include" ] + sources += [ + "${common_example_dir}/ota_requestor/source/OTARequestorInitiator.cpp", + "${common_example_dir}/ota_requestor/source/OTARequestorInitiatorCommon.cpp", + ] + } + + if (wifi_auto_connect_at_boot) { + assert(wifi_auto_connect_at_boot_ssid != "" && + wifi_auto_connect_at_boot_password != "", + "WiFi SSID and password must be specified at build time!") + + defines += [ + "CONFIG_CHIP_APP_WIFI_CONNECT_AT_BOOT=1", + "CONFIG_CHIP_APP_WIFI_SSID=\"${wifi_auto_connect_at_boot_ssid}\"", + "CONFIG_CHIP_APP_WIFI_PASSWORD=\"${wifi_auto_connect_at_boot_password}\"", + ] + + include_dirs += [ "${common_example_dir}/wifi_connect/include" ] + sources += [ "${common_example_dir}/wifi_connect/source/WifiConnect.cpp" ] + } + + # In case a dedicated assert function needs to be supported the flag sdk_fsl_assert_support should be set to false + # The would add to the build a dedicated application assert implementation. + if (!sdk_fsl_assert_support) { + sources += [ "${common_example_dir}/app_assert/source/AppAssert.cpp" ] + } + + cflags = [ "-Wconversion" ] + + ldscript = + "${example_platform_dir}/app/ldscripts/MIMXRT1176xxxxx_cm7_flexspi_nor.ld" + + inputs = [ ldscript ] + + ldflags = [ + "-T" + rebase_path(ldscript, root_build_dir), + "-fno-common", + "-Wl,--defsym=__stack_size__=2048", + "-ffreestanding", + "-fno-builtin", + "-mapcs", + "-u qspiflash_config", + "-u image_vector_table", + "-u boot_data", + "-u dcd_data", + "-Wl,-print-memory-usage", + "-Wl,--no-warn-rwx-segments", + ] + + if (chip_enable_ota_requestor) { + if (no_mcuboot) { + # If "no_mcuboot" is set to true, the application will be linked at the base of the flash. + print( + "Warning : The OTA Requestor is enabled without MCUBoot. This will prevent the application from applying software updates.") + } else { + # we need to reserve enough space for the bootloader (MCUBoot) + # MCUBoot requires 0x40000 Bytes to be reserved at the base of the flash + # Consequently, some sections will need to be shifted + ldflags += [ "-Wl,--defsym=__m_mcuboot_size__=0x40000" ] + } + } + + output_dir = root_out_dir +} + +group("rt1170") { + deps = [ ":all_cluster_app" ] +} + +group("default") { + deps = [ ":rt1170" ] +} diff --git a/examples/all-clusters-app/nxp/rt/rt1170/README.md b/examples/all-clusters-app/nxp/rt/rt1170/README.md new file mode 100644 index 00000000000000..7ff91872a4b1b4 --- /dev/null +++ b/examples/all-clusters-app/nxp/rt/rt1170/README.md @@ -0,0 +1,505 @@ +# CHIP RT1170 All-clusters Application + +The all-clusters example implements a server which can be accessed by a CHIP +controller and can accept basic cluster commands. + +The example is based on +[Project CHIP](https://github.com/project-chip/connectedhomeip) and the NXP +RT1170 SDK, and provides a prototype application that demonstrates device +commissioning and different cluster control. + +
+ +- [CHIP RT1170 All-clusters Application](#chip-rt1170-all-clusters-application) + - [Introduction](#introduction) + - [Configuration(s) supported](#configurations-supported) + - [Hardware requirements for RT1170 + IW612](#hardware-requirements-for-rt1170--iw612) + - [Hardware rework for SPI support on MIMXRT1170-EVK-B](#hardware-rework-for-spi-support-on-mimxrt1170-evk-b) + - [Board settings (Spinel over SPI, I2C, BLE over UART)](#board-settings-spinel-over-spi-i2c-ble-over-uart) + - [Building](#building) + - [Building with Matter over Wifi configuration on RT1170 + IW612](#building-with-matter-over-wifi-configuration-on-rt1170--iw612) + - [Building with Matter over Thread configuration on RT1170 + IW612](#building-with-matter-over-thread-configuration-on-rt1170--iw612) + - [Building with Matter over Wifi + OpenThread Border Router configuration on RT1170 + IW612](#building-with-matter-over-wifi--openthread-border-router-configuration-on-rt1170--iw612) + - [General information](#general-information) + - [Manufacturing data](#manufacturing-data) + - [Flashing and debugging](#flashing-and-debugging) + - [Testing the example](#testing-the-example) + - [Matter over wifi configuration :](#matter-over-wifi-configuration-) + - [Matter over thread configuration :](#matter-over-thread-configuration-) + - [Matter over wifi with openthread border router configuration :](#matter-over-wifi-with-openthread-border-router-configuration-) + - [Testing the all-clusters application without Matter CLI:](#testing-the-all-clusters-application-without-matter-cli) + - [Testing the all-clusters application with Matter CLI enabled:](#testing-the-all-clusters-application-with-matter-cli-enabled) + - [Thread Border Router overview](#thread-border-router-overview) +
+ +## Introduction + +![RT1170 EVK](../../../../platform/nxp/rt/rt1170/doc/images/IMX-RT1170-EVK-TOP.jpg) + +The RT1170 all-cluster application provides a working demonstration of the +RT1170 board integration, built using the Project CHIP codebase and the NXP +RT1170 SDK. + +The example supports: + +- Matter over Wi-Fi +- Matter over Openthread +- Matter over Wi-Fi with Openthread Border Router support + +The example targets the +[NXP MIMXRT1170-EVKB](https://www.nxp.com/part/MIMXRT1170-EVKB#/) board by +default. + +### Configuration(s) supported + +Here are listed configurations that allow to support Matter over Wi-Fi & Matter +over Thread on RT1170 : + +- RT1170 + IW612 (Wi-Fi + BLE + 15.4) + +### Hardware requirements for RT1170 + IW612 + +Host part: + +- 1 MIMXRT1170-EVK-B + +Transceiver part : + +- 1 + [2EL M2 A1 IW612 Secure Module](https://www.nxp.com/products/wireless/wi-fi-plus-bluetooth-plus-802-15-4/2-4-5-ghz-dual-band-1x1-wi-fi-6-802-11ax-plus-bluetooth-5-2-plus-802-15-4-tri-radio-solution:IW612) + +![](../../../../platform/nxp/rt/rt1170/doc/images/iwx612_2EL.jpg) + +- 1 + [Murata uSD to M2 adapter revC](https://www.murata.com/en-eu/products/connectivitymodule/wi-fi-bluetooth/overview/lineup/usd-m2-adapter-2we-2wf) + +![](../../../../platform/nxp/rt/rt1170/doc/images/murata_usd-M2_adapter.jpg) + +- Male to female Burg cables + +#### Hardware rework for SPI support on MIMXRT1170-EVK-B + +To support SPI on the MIMXRT1170-EVK-B board, it is required to remove 0Ω +resistors R404,R406,R2015. + +#### Board settings (Spinel over SPI, I2C, BLE over UART) + +Plug IW612 module to M.2 connector on Murata uSD to M2 adapter + +The Murata uSD-M2 adapter should be plugged to the RT1170 via SD-IO. + +The below tables explain pin settings (SPI settings) to connect the +MIMXRT1170-EVK-B (host) to a IW612 transceiver (rcp). + +- Murata uSD to M2 adapter connections description: + +![](../../../../platform/nxp/rt/rt1170/doc/images/murata_usd-m2_connections_1.jpg) + +![](../../../../platform/nxp/rt/rt1170/doc/images/murata_usd-m2_connections_2.jpg) + +- Jumpers positions on Murata uSD to M2 adapter: + + Use USB-C power supply | Jumper | Position| | :----: | :-----: | | J1 | 1-2 + | | J12 | 1-2 | | J13 | 1-2 | | J14 | 1-2 | | JP1.1 (back side)| ON | + +- Jumpers positions on MIMXRT1170-EVK-B: + + | Jumper | Position | + | :----: | :------: | + | `J56` | `2-3` | + +- I2C connection to program `IO_Expander` on the IW612 module + + | MIMXRT1170-EVK-B | uSD-M2 adapter | + | :----------------: | :------------: | + | `I2C_SDA (J10.18)` | `J5.2` | + | `I2C_SDL (J10.20)` | `J5.4` | + +- SPI connection between RT1170 and uSD-M2 adapter + + | MIMXRT1170-EVK-B | uSD-M2 adapter | + | :-----------------: | :------------: | + | `SPI_MOSI (J10.8)` | `J5.10` | + | `SPI_MISO (J10.10)` | `J9.7` | + | `SPI_CLK (J10.12)` | `J9.8` | + | `SPI_CS (J10.6)` | `J5.8` | + | `SPI_INT (J26.4)` | `J5.6` | + | `GND (J10.14)` | `J5.15` | + +- UART BLE and Reset connections between RT1170 and uSD-M2 adapter + + | MIMXRT1170-EVK-B | uSD-M2 adapter | + | :-----------------: | :------------: | + | `RESET (J26.2)` | `J9.3` | + | `UART_RXD (J25.13)` | `J9.1` | + | `UART_TXD (J25.15)` | `J9.2` | + | `UART_CTS (J25.9)` | `J8.4` | + | `UART_RTS (J25.11)` | `J8.3` | + | `GND (J26.1)` | `J7.6` | + +## Building + +In order to build the Project CHIP example, we recommend using a Linux +distribution. Supported Operating Systems are listed in +[BUILDING.md](../../../../../docs/guides/BUILDING.md). + +- Make sure that below prerequisites are correctly installed, as described in + [BUILDING.md](../../../../../docs/guides/BUILDING.md). + +``` +sudo apt-get install git gcc g++ pkg-config libssl-dev libdbus-1-dev \ + libglib2.0-dev libavahi-client-dev ninja-build python3-venv python3-dev \ + python3-pip unzip libgirepository1.0-dev libcairo2-dev libreadline-dev +``` + +- Step 1: checkout NXP specific submodules only + +``` +user@ubuntu:~/Desktop/git/connectedhomeip$ scripts/checkout_submodules.py --shallow --platform nxp --recursive +``` + +- Step 2: activate local environment + +``` +user@ubuntu:~/Desktop/git/connectedhomeip$ source scripts/activate.sh +``` + +If the script says the environment is out of date, you can update it by running +the following command: + +``` +user@ubuntu:~/Desktop/git/connectedhomeip$ source scripts/bootstrap.sh +``` + +- Step 3: Init NXP SDK(s) + +``` +user@ubuntu:~/Desktop/git/connectedhomeip$ third_party/nxp/nxp_matter_support/scripts/update_nxp_sdk.py --platform common +``` + +Note: By default update_nxp_sdk.py will try to initialize all NXP SDKs. Arg "-- +help" could be used to view all available options. + +``` +user@ubuntu:~/Desktop/git/connectedhomeip$ cd examples/all-cluster-app/nxp/rt/rt1170/ +``` + +### Building with Matter over Wifi configuration on RT1170 + IW612 + +- Build the Wi-fi configuration for MIMXRT1170 board + IW612 transceiver (with + BLE for commissioning). + +``` +user@ubuntu:~/Desktop/git/connectedhomeip/examples/all-clusters-app/nxp/rt/rt1170$ gn gen --args="chip_enable_wifi=true iwx12_transceiver=true chip_config_network_layer_ble=true chip_enable_ble=true " out/debug +user@ubuntu:~/Desktop/git/connectedhomeip/examples/all-clusters-app/nxp/rt/rt1170$ ninja -C out/debug +``` + +### Building with Matter over Thread configuration on RT1170 + IW612 + +- Build the Openthread configuration for MIMXRT1170 board + IW612 transceiver + (with BLE for commissioning). + +``` +user@ubuntu:~/Desktop/git/connectedhomeip/examples/all-cluster/nxp/rt/rt1170$ gn gen --args="chip_enable_openthread=true iwx12_transceiver=true chip_inet_config_enable_ipv4=false chip_config_network_layer_ble=true" out/debug +user@ubuntu:~/Desktop/git/connectedhomeip/examples/all-cluster/nxp/rt/rt1170/$ ninja -C out/debug +``` + +### Building with Matter over Wifi + OpenThread Border Router configuration on RT1170 + IW612 + +This configuration supports the Thread Border Router management cluster to +provision the Thread credentials. Enabling the Matter CLI in order to control +the Thread network on the Border Router is optional but recommended for other +features like the Thread credential sharing. + +Note that the Thread Border Router management cluster is only supported on the +thermostat application for now. + +- Build Matter with Border Router configuration with BLE commissioning + (ble-wifi) : + +``` +user@ubuntu:~/Desktop/git/connectedhomeip/examples/all-clusters-app/nxp/rt/rt11170$ gn gen --args="chip_enable_wifi=true iwx12_transceiver=true chip_config_network_layer_ble=true chip_enable_ble=true chip_enable_openthread=true chip_enable_matter_cli=true" out/debug +user@ubuntu:~/Desktop/git/connectedhomeip/examples/all-clusters-app/nxp/rt/rt1170$ ninja -C out/debug +``` + +### General information + +The resulting output file can be found in +out/debug/chip-rt1170-all-cluster-example. + +Optional GN options that can be added when building an application: + +- To enable the + [secondary network commissioning interface](../../../../../docs/platforms/nxp/nxp_otbr_guide.md#using-the-secondary-network-commissioning-interface), + the arguments `chip_enable_secondary_nwk_if=true` and + `chip_device_config_thread_network_endpoint_id=3` must be added to the _gn + gen_ command. Note that this is only supported when building the Matter over + Wifi + OpenThread Border Router configuration. Note that is only supported + on the on the thermostat application for now. +- To enable the + [matter CLI](#testing-the-all-clusters-application-with-matter-cli-enabled), + the argument `chip_enable_matter_cli=true` must be added to the _gn gen_ + command. +- To build the application in debug mode, the argument + `is_debug=true optimize_debug=false` must be added to the _gn gen_ command. +- To build with the option to have Matter certificates/keys pre-loaded in a + specific flash area the argument `chip_with_factory_data=1` must be added to + the _gn gen_ command. For more information, see + [Guide for writing manufacturing data on NXP devices](../../../../../docs/platforms/nxp/nxp_manufacturing_flow.md) +- To build the application with the OTA Requestor enabled, the arguments + `chip_enable_ota_requestor=true no_mcuboot=false` must be added to the _gn + gen_ command. More information about the OTA Requestor feature in + [OTA Requestor README](../../../../../docs/platforms/nxp/nxp_RTs_ota_software_update.md). + +## Manufacturing data + +See +[Guide for writing manufacturing data on NXP devices](../../../../../docs/platforms/nxp/nxp_manufacturing_flow.md) + +Other comments: + +The all cluster app demonstrates the usage of encrypted Matter manufacturing +data storage. Matter manufacturing data should be encrypted using an AES 128 +software key before flashing them to the device flash. + +## Flashing and debugging + +In order to flash the application we recommend using +[MCUXpresso IDE (version >= 11.5.0)](https://www.nxp.com/design/software/development-software/mcuxpresso-software-and-tools-/mcuxpresso-integrated-development-environment-ide:MCUXpresso-IDE). + +- Import the previously downloaded NXP SDK into MCUXpresso IDE. This can be + done by drag-and-dropping the SDK archive into MCUXpresso IDE "Installed + SDKs" tab; + ![Select SDK](../../../../platform/nxp/rt/rt1170/doc/images/select-sdk.png) +- Import the connectedhomeip repo in MCUXpresso IDE as Makefile Project. Use + _none_ as _Toolchain for Indexer Settings_: + +``` +File -> Import -> C/C++ -> Existing Code as Makefile Project +``` + +- Configure MCU Settings: + +``` +Right click on the Project -> Properties -> C/C++ Build -> MCU Settings -> Select MIMXRT1170 -> Apply & Close +``` + +![MCU_Sett](../../../../platform/nxp/rt/rt1170/doc/images/mcu-set.png) + +Sometimes when the MCU is selected it will not initialize all the memory regions +(usually the `BOARD_FLASH`, `BOARD_SDRAM` and `NCACHE_REGION`) so it is required +that this regions are added manually like in the image above. In addition to +that on the `BOARD_FLASH` line, in the driver tab: + +``` +click inside the tab and on the right side a button with three horizontal dots will appear +click on the button and an window will show +form the dropdown menu select the MIMXRT1170_SFDP_QSPI driver +``` + +![flash_driver](../../../../platform/nxp/rt/rt1170/doc/images/flash_driver.png) + +- Configure the toolchain editor: + +``` +Right click on the Project -> C/C++ Build-> Tool Chain Editor -> NXP MCU Tools -> Apply & Close +``` + +![toolchain](../../../../platform/nxp/rt/rt1170/doc/images/toolchain.JPG) + +- Create a debug configuration: + + MIMXRT1170-EVK-B board supports CMSIS-DAP debug protocol by default. It + should be switched to JLink. + + - download and install + [MCU-LINK_INSTALLER 2.263](https://www.nxp.com/webapp/Download?colCode=MCU-LINK_INSTALLER_2.263_LIN) + - connect jumper JP3 to get board in ISP mode when powered + - connect board and run installed MCU-LINK, follow steps to flash JLINK + firmware + - remove jumper JP3 and reboot board + +``` +Right click on the Project -> Debug -> As->SEGGER J-Link probes -> OK -> Select elf file +``` + +![debug_0](../../../../platform/nxp/rt/rt1170/doc/images/debug0.png) + +- Set the _Initialization Commands_ to: + +``` +Right click on the Project -> Debug As -> Debug configurations... -> Startup + +set non-stop on +set pagination off +set mi-async +set remotetimeout 60000 +##target_extended_remote## +set mem inaccessible-by-default ${mem.access} +mon ondisconnect ${ondisconnect} +set arm force-mode thumb +${load} +``` + +![init](../../../../platform/nxp/rt/rt1170/doc/images/startup.png) + +- Set the _vector.catch_ value to _false_ inside the .launch file: + +``` +Right click on the Project -> Utilities -> Open Directory Browser here -> edit .launch file: + + + +``` + +- Debug using the newly created configuration file: + +## Testing the example + +To know how to commission a device over BLE, follow the instructions from +[chip-tool's README.md 'Commission a device over +BLE'][readme_ble_commissioning_section]. + +[readme_ble_commissioning_section]: + ../../../../chip-tool/README.md#commission-a-device-over-ble + +To know how to commissioning a device over IP, follow the instructions from +[chip-tool's README.md 'Pair a device over +IP'][readme_pair_ip_commissioning_section] + +[readme_pair_ip_commissioning_section]: + ../../../../chip-tool/README.md#pair-a-device-over-ip + +#### Matter over wifi configuration : + +The "ble-wifi" pairing method can be used in order to commission the device. + +#### Matter over thread configuration : + +The "ble-thread" pairing method can be used in order to commission the device. + +#### Matter over wifi with openthread border router configuration : + +In order to create or join a Thread network on the Matter Border Router, the TBR +management cluster or the `otcli` commands from the matter CLI can be used. For +more information about using the TBR management cluster follow instructions from +['Using the TBR management cluster'](../../../../../docs/platforms/nxp/nxp_otbr_guide.md#using-the-thread-border-router-management-cluster). +For more information about using the matter shell, follow instructions from +['Testing the all-clusters application with Matter CLI'](#testing-the-all-clusters-application-with-matter-cli-enabled). + +In this configuration, the device can be commissioned over Wi-Fi with the +'ble-wifi' pairing method. + +### Testing the all-clusters application without Matter CLI: + +1. Prepare the board with the flashed `All-cluster application` (as shown + above). +2. The All-cluster example uses UART1 to print logs while running the server. To + view raw UART output, start a terminal emulator like PuTTY and connect to the + used COM port with the following UART settings: + + - Baud rate: 115200 + - 8 data bits + - 1 stop bit + - No parity + - No flow control + +3. Open a terminal connection on the board and watch the printed logs. + +4. On the client side, start sending commands using the chip-tool application as + it is described + [here](../../../../chip-tool/README.md#using-the-client-to-send-matter-commands). + +### Testing the all-clusters application with Matter CLI enabled: + +Testing the all-clusters application with Matter CLI enabled: + +The Matter CLI can be enabled with the all-clusters application. + +For more information about the Matter CLI default commands, you can refer to the +dedicated [ReadMe](../../../../shell/README.md). + +The All-clusters application supports additional commands : + +``` +> help +[...] +mattercommissioning Open/close the commissioning window. Usage : mattercommissioning [on|off] +matterfactoryreset Perform a factory reset on the device +matterreset Reset the device +``` + +- `matterfactoryreset` command erases the file system completely (all Matter + settings are erased). +- `matterreset` enables the device to reboot without erasing the settings. + +Here are described steps to use the all-cluster-app with the Matter CLI enabled + +1. Prepare the board with the flashed `All-cluster application` (as shown + above). +2. The matter CLI is accessible in UART1. For that, start a terminal emulator + like PuTTY and connect to the used COM port with the following UART settings: + + - Baud rate: 115200 + - 8 data bits + - 1 stop bit + - No parity + - No flow control + +3. The All-cluster example uses UART2 to print logs while running the server. To + view raw UART output, a pin should be plugged to an USB to UART adapter + (connector J9 pin 4), then start a terminal emulator like PuTTY and connect + to the used COM port with the following UART settings: + + - Baud rate: 115200 + - 8 data bits + - 1 stop bit + - No parity + - No flow control + +4. On the client side, start sending commands using the chip-tool application as + it is described + [here](../../../../chip-tool/README.md#using-the-client-to-send-matter-commands). + +For Matter with OpenThread Border Router support, the matter CLI can be used to +start/join the Thread network, using the following ot-cli commands. (Note that +setting channel, panid, and network key is not enough anymore because of an Open +Thread stack update. We first need to initialize a new dataset.) + +``` +> otcli dataset init new +Done +> otcli dataset +Active Timestamp: 1 +Channel: 25 +Channel Mask: 0x07fff800 +Ext PAN ID: 42af793f623aab54 +Mesh Local Prefix: fd6e:c358:7078:5a8d::/64 +Network Key: f824658f79d8ca033fbb85ecc3ca91cc +Network Name: OpenThread-b870 +PAN ID: 0xb870 +PSKc: f438a194a5e968cc43cc4b3a6f560ca4 +Security Policy: 672 onrc 0 +Done +> otcli dataset panid 0xabcd +Done +> otcli dataset channel 25 +Done +> otcli dataset commit active +Done +> otcli ifconfig up +Done +> otcli thread start +Done +> otcli state +leader +Done +``` + +## Thread Border Router overview + +To enable Thread Border Router support see the [build](README.md#building) +section. + +The complete Border Router guide is located +[here](../../../../../docs/platforms/nxp/nxp_otbr_guide.md). diff --git a/examples/all-clusters-app/nxp/rt/rt1170/args.gni b/examples/all-clusters-app/nxp/rt/rt1170/args.gni new file mode 100644 index 00000000000000..c2d91a5db7bae7 --- /dev/null +++ b/examples/all-clusters-app/nxp/rt/rt1170/args.gni @@ -0,0 +1,19 @@ +# Copyright (c) 2023 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/chip.gni") + +# SDK target definitions +nxp_sdk_target = get_label_info(":sdk", "label_no_toolchain") +nxp_sdk_driver_target = get_label_info(":sdk_driver", "label_no_toolchain") diff --git a/examples/all-clusters-app/nxp/rt/rt1170/build_overrides b/examples/all-clusters-app/nxp/rt/rt1170/build_overrides new file mode 120000 index 00000000000000..f10867042f4d19 --- /dev/null +++ b/examples/all-clusters-app/nxp/rt/rt1170/build_overrides @@ -0,0 +1 @@ +../../../../build_overrides \ No newline at end of file diff --git a/examples/all-clusters-app/nxp/rt/rt1170/include/config/CHIPProjectConfig.h b/examples/all-clusters-app/nxp/rt/rt1170/include/config/CHIPProjectConfig.h new file mode 100644 index 00000000000000..dd73c6c9eaaedd --- /dev/null +++ b/examples/all-clusters-app/nxp/rt/rt1170/include/config/CHIPProjectConfig.h @@ -0,0 +1,216 @@ +/* + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2020 Google LLC. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Example project configuration file for CHIP. + * + * This is a place to put application or project-specific overrides + * to the default configuration values for general CHIP features. + * + */ + +#pragma once + +/* + * Tells to the platform Factory Data Provider whether to use the example configuration or real/provisioned data. + */ +#ifndef CONFIG_CHIP_PLAT_LOAD_REAL_FACTORY_DATA +#define CONFIG_CHIP_PLAT_LOAD_REAL_FACTORY_DATA 0 +#endif + +/** + * CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID + * + * 0xFFF1: Test vendor. + */ +#define CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID 0xFFF1 + +/** + * CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID + * + */ +#define CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID 0x8005 + +#if !CONFIG_CHIP_PLAT_LOAD_REAL_FACTORY_DATA +// Use a default pairing code if one hasn't been provisioned in flash. +#ifndef CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE +#define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE 20202021 +#endif + +#ifndef CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR +#define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR 0xF00 +#endif + +// Use a default pairing code if one hasn't been provisioned in flash. +#define CHIP_DEVICE_CONFIG_USE_TEST_PAIRING_CODE "CHIPUS" + +/** + * CHIP_DEVICE_CONFIG_USE_TEST_SERIAL_NUMBER + * + * Enables the use of a hard-coded default serial number if none + * is found in CHIP NV storage. + */ +#define CHIP_DEVICE_CONFIG_USE_TEST_SERIAL_NUMBER "DUMMY_SN" + +#endif /* !CONFIG_CHIP_PLAT_LOAD_REAL_FACTORY_DATA */ + +/** + * CHIP_DEVICE_CONFIG_DEVICE_HARDWARE_VERSION + * + * The hardware version number assigned to device or product by the device vendor. This + * number is scoped to the device product id, and typically corresponds to a revision of the + * physical device, a change to its packaging, and/or a change to its marketing presentation. + * This value is generally *not* incremented for device software versions. + */ +#define CHIP_DEVICE_CONFIG_DEVICE_HARDWARE_VERSION 100 + +#ifndef CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION_STRING +#define CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION_STRING "v0.1.0" +#endif + +/** + * CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING + * + * A string identifying the software version running on the device. + * CHIP currently expects the software version to be in the format + * {MAJOR_VERSION}.0d{MINOR_VERSION} + */ +#ifndef CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING +#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING NXP_CONFIG_DEVICE_SOFTWARE_VERSION_STRING +#endif + +#ifndef CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION +#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION NXP_CONFIG_DEVICE_SOFTWARE_VERSION +#endif + +#ifndef CHIP_DEVICE_CONFIG_DEVICE_VENDOR_NAME +#define CHIP_DEVICE_CONFIG_DEVICE_VENDOR_NAME "NXP Semiconductors" +#endif + +#ifndef CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_NAME +#define CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_NAME "NXP Demo App" +#endif + +#ifndef CHIP_DEVICE_CONFIG_CERTIFICATION_DECLARATION +//-> format_version = 1 +//-> vendor_id = 0xFFF1 +//-> product_id_array = [ 0x8000, 0x8001, 0x8002, 0x8003, 0x8004, 0x8005, 0x8006, 0x8007, 0x8008, 0x8009, 0x800A, 0x800B, +// 0x800C, 0x800D, 0x800E, 0x800F, 0x8010, 0x8011, 0x8012, 0x8013, 0x8014, 0x8015, 0x8016, 0x8017, 0x8018, 0x8019, 0x801A, +// 0x801B, 0x801C, 0x801D, 0x801E, 0x801F, 0x8020, 0x8021, 0x8022, 0x8023, 0x8024, 0x8025, 0x8026, 0x8027, 0x8028, 0x8029, +// 0x802A, 0x802B, 0x802C, 0x802D, 0x802E, 0x802F, 0x8030, 0x8031, 0x8032, 0x8033, 0x8034, 0x8035, 0x8036, 0x8037, 0x8038, +// 0x8039, 0x803A, 0x803B, 0x803C, 0x803D, 0x803E, 0x803F, 0x8040, 0x8041, 0x8042, 0x8043, 0x8044, 0x8045, 0x8046, 0x8047, +// 0x8048, 0x8049, 0x804A, 0x804B, 0x804C, 0x804D, 0x804E, 0x804F, 0x8050, 0x8051, 0x8052, 0x8053, 0x8054, 0x8055, 0x8056, +// 0x8057, 0x8058, 0x8059, 0x805A, 0x805B, 0x805C, 0x805D, 0x805E, 0x805F, 0x8060, 0x8061, 0x8062, 0x8063 ] +//-> device_type_id = 0x0016 +//-> certificate_id = "ZIG20142ZB330003-24" +//-> security_level = 0 +//-> security_information = 0 +//-> version_number = 0x2694 +//-> certification_type = 0 +//-> dac_origin_vendor_id is not present +//-> dac_origin_product_id is not present +#define CHIP_DEVICE_CONFIG_CERTIFICATION_DECLARATION \ + { \ + 0x30, 0x82, 0x02, 0x19, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x82, 0x02, 0x0a, 0x30, \ + 0x82, 0x02, 0x06, 0x02, 0x01, 0x03, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, \ + 0x02, 0x01, 0x30, 0x82, 0x01, 0x71, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, \ + 0x01, 0x62, 0x04, 0x82, 0x01, 0x5e, 0x15, 0x24, 0x00, 0x01, 0x25, 0x01, 0xf1, 0xff, 0x36, 0x02, 0x05, 0x00, 0x80, \ + 0x05, 0x01, 0x80, 0x05, 0x02, 0x80, 0x05, 0x03, 0x80, 0x05, 0x04, 0x80, 0x05, 0x05, 0x80, 0x05, 0x06, 0x80, 0x05, \ + 0x07, 0x80, 0x05, 0x08, 0x80, 0x05, 0x09, 0x80, 0x05, 0x0a, 0x80, 0x05, 0x0b, 0x80, 0x05, 0x0c, 0x80, 0x05, 0x0d, \ + 0x80, 0x05, 0x0e, 0x80, 0x05, 0x0f, 0x80, 0x05, 0x10, 0x80, 0x05, 0x11, 0x80, 0x05, 0x12, 0x80, 0x05, 0x13, 0x80, \ + 0x05, 0x14, 0x80, 0x05, 0x15, 0x80, 0x05, 0x16, 0x80, 0x05, 0x17, 0x80, 0x05, 0x18, 0x80, 0x05, 0x19, 0x80, 0x05, \ + 0x1a, 0x80, 0x05, 0x1b, 0x80, 0x05, 0x1c, 0x80, 0x05, 0x1d, 0x80, 0x05, 0x1e, 0x80, 0x05, 0x1f, 0x80, 0x05, 0x20, \ + 0x80, 0x05, 0x21, 0x80, 0x05, 0x22, 0x80, 0x05, 0x23, 0x80, 0x05, 0x24, 0x80, 0x05, 0x25, 0x80, 0x05, 0x26, 0x80, \ + 0x05, 0x27, 0x80, 0x05, 0x28, 0x80, 0x05, 0x29, 0x80, 0x05, 0x2a, 0x80, 0x05, 0x2b, 0x80, 0x05, 0x2c, 0x80, 0x05, \ + 0x2d, 0x80, 0x05, 0x2e, 0x80, 0x05, 0x2f, 0x80, 0x05, 0x30, 0x80, 0x05, 0x31, 0x80, 0x05, 0x32, 0x80, 0x05, 0x33, \ + 0x80, 0x05, 0x34, 0x80, 0x05, 0x35, 0x80, 0x05, 0x36, 0x80, 0x05, 0x37, 0x80, 0x05, 0x38, 0x80, 0x05, 0x39, 0x80, \ + 0x05, 0x3a, 0x80, 0x05, 0x3b, 0x80, 0x05, 0x3c, 0x80, 0x05, 0x3d, 0x80, 0x05, 0x3e, 0x80, 0x05, 0x3f, 0x80, 0x05, \ + 0x40, 0x80, 0x05, 0x41, 0x80, 0x05, 0x42, 0x80, 0x05, 0x43, 0x80, 0x05, 0x44, 0x80, 0x05, 0x45, 0x80, 0x05, 0x46, \ + 0x80, 0x05, 0x47, 0x80, 0x05, 0x48, 0x80, 0x05, 0x49, 0x80, 0x05, 0x4a, 0x80, 0x05, 0x4b, 0x80, 0x05, 0x4c, 0x80, \ + 0x05, 0x4d, 0x80, 0x05, 0x4e, 0x80, 0x05, 0x4f, 0x80, 0x05, 0x50, 0x80, 0x05, 0x51, 0x80, 0x05, 0x52, 0x80, 0x05, \ + 0x53, 0x80, 0x05, 0x54, 0x80, 0x05, 0x55, 0x80, 0x05, 0x56, 0x80, 0x05, 0x57, 0x80, 0x05, 0x58, 0x80, 0x05, 0x59, \ + 0x80, 0x05, 0x5a, 0x80, 0x05, 0x5b, 0x80, 0x05, 0x5c, 0x80, 0x05, 0x5d, 0x80, 0x05, 0x5e, 0x80, 0x05, 0x5f, 0x80, \ + 0x05, 0x60, 0x80, 0x05, 0x61, 0x80, 0x05, 0x62, 0x80, 0x05, 0x63, 0x80, 0x18, 0x24, 0x03, 0x16, 0x2c, 0x04, 0x13, \ + 0x5a, 0x49, 0x47, 0x32, 0x30, 0x31, 0x34, 0x32, 0x5a, 0x42, 0x33, 0x33, 0x30, 0x30, 0x30, 0x33, 0x2d, 0x32, 0x34, \ + 0x24, 0x05, 0x00, 0x24, 0x06, 0x00, 0x25, 0x07, 0x94, 0x26, 0x24, 0x08, 0x00, 0x18, 0x31, 0x7d, 0x30, 0x7b, 0x02, \ + 0x01, 0x03, 0x80, 0x14, 0x62, 0xfa, 0x82, 0x33, 0x59, 0xac, 0xfa, 0xa9, 0x96, 0x3e, 0x1c, 0xfa, 0x14, 0x0a, 0xdd, \ + 0xf5, 0x04, 0xf3, 0x71, 0x60, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x30, \ + 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x04, 0x47, 0x30, 0x45, 0x02, 0x20, 0x24, 0xe5, \ + 0xd1, 0xf4, 0x7a, 0x7d, 0x7b, 0x0d, 0x20, 0x6a, 0x26, 0xef, 0x69, 0x9b, 0x7c, 0x97, 0x57, 0xb7, 0x2d, 0x46, 0x90, \ + 0x89, 0xde, 0x31, 0x92, 0xe6, 0x78, 0xc7, 0x45, 0xe7, 0xf6, 0x0c, 0x02, 0x21, 0x00, 0xf8, 0xaa, 0x2f, 0xa7, 0x11, \ + 0xfc, 0xb7, 0x9b, 0x97, 0xe3, 0x97, 0xce, 0xda, 0x66, 0x7b, 0xae, 0x46, 0x4e, 0x2b, 0xd3, 0xff, 0xdf, 0xc3, 0xcc, \ + 0xed, 0x7a, 0xa8, 0xca, 0x5f, 0x4c, 0x1a, 0x7c \ + } +#endif + +/** + * CHIP_DEVICE_CONFIG_ENABLE_CHIP_TIME_SERVICE_TIME_SYNC + * + * Enables synchronizing the device's real time clock with a remote CHIP Time service + * using the CHIP Time Sync protocol. + */ +// #define CHIP_DEVICE_CONFIG_ENABLE_CHIP_TIME_SERVICE_TIME_SYNC 1 + +/** + * CHIP_CONFIG_MAX_BINDINGS + * + * Maximum number of simultaneously active bindings per ChipExchangeManager + * 1 (Time Sync) + 2 (Two 1-way subscriptions) + 1 (Software Update) = 4 + * in the worst case. Keeping another 4 as buffer. + */ +#define CHIP_CONFIG_MAX_BINDINGS 6 + +/** + * CHIP_CONFIG_EVENT_LOGGING_WDM_OFFLOAD + * + * Select the ability to offload event logs to any interested subscribers using WDM. + */ +#define CHIP_CONFIG_EVENT_LOGGING_WDM_OFFLOAD 1 + +/** + * CHIP_CONFIG_EVENT_LOGGING_UTC_TIMESTAMPS + * + * Enable recording UTC timestamps. + */ +#define CHIP_CONFIG_EVENT_LOGGING_UTC_TIMESTAMPS 1 + +/** + * CHIP_DEVICE_CONFIG_EVENT_LOGGING_DEBUG_BUFFER_SIZE + * + * A size, in bytes, of the individual debug event logging buffer. + */ +#define CHIP_DEVICE_CONFIG_EVENT_LOGGING_DEBUG_BUFFER_SIZE (512) + +/** + * CHIP_CONFIG_EVENT_LOGGING_DEFAULT_IMPORTANCE + * + * For a development build, set the default importance of events to be logged as Debug. + * Since debug is the lowest importance level, this means all standard, critical, info and + * debug importance level vi events get logged. + */ +#if BUILD_RELEASE +#define CHIP_CONFIG_EVENT_LOGGING_DEFAULT_IMPORTANCE chip::Profiles::DataManagement::Production +#else +#define CHIP_CONFIG_EVENT_LOGGING_DEFAULT_IMPORTANCE chip::Profiles::DataManagement::Debug +#endif // BUILD_RELEASE + +/* Increasing the retransmission interval of the MRP messages after subsequent failures */ +#ifndef CHIP_CONFIG_MRP_LOCAL_ACTIVE_RETRY_INTERVAL +#define CHIP_CONFIG_MRP_LOCAL_ACTIVE_RETRY_INTERVAL (2000_ms32) +#endif diff --git a/examples/all-clusters-app/nxp/rt/rt1170/third_party/connectedhomeip b/examples/all-clusters-app/nxp/rt/rt1170/third_party/connectedhomeip new file mode 120000 index 00000000000000..305f2077ffe860 --- /dev/null +++ b/examples/all-clusters-app/nxp/rt/rt1170/third_party/connectedhomeip @@ -0,0 +1 @@ +../../../../../.. \ No newline at end of file diff --git a/examples/all-clusters-app/nxp/rt/rw61x/README.md b/examples/all-clusters-app/nxp/rt/rw61x/README.md index df760e864e51d1..9b19031c00b44d 100644 --- a/examples/all-clusters-app/nxp/rt/rw61x/README.md +++ b/examples/all-clusters-app/nxp/rt/rw61x/README.md @@ -171,7 +171,7 @@ Optional GN options that can be added when building an application: - To build the application with the OTA Requestor enabled, the arguments `chip_enable_ota_requestor=true no_mcuboot=false` must be added to the _gn gen_ command. (More information about the OTA Requestor feature in - [OTA Requestor README](../../../../../docs/platforms/nxp/nxp_rw61x_ota_software_update.md) + [OTA Requestor README](../../../../../docs/platforms/nxp/nxp_RTs_ota_software_update.md) ## Manufacturing data @@ -407,7 +407,7 @@ Done Over-The-Air software updates are supported with the RW61x all-clusters example. The process to follow in order to perform a software update is described in the dedicated guide -['Matter Over-The-Air Software Update with NXP RW61x example applications'](../../../../../docs/platforms/nxp/nxp_rw61x_ota_software_update.md). +['Matter Over-The-Air Software Update with NXP RW61x example applications'](../../../../../docs/platforms/nxp/nxp_RTs_ota_software_update.md). diff --git a/examples/laundry-washer-app/nxp/rt/rt1060/.gn b/examples/laundry-washer-app/nxp/rt/rt1060/.gn new file mode 100644 index 00000000000000..0985ed955a426f --- /dev/null +++ b/examples/laundry-washer-app/nxp/rt/rt1060/.gn @@ -0,0 +1,35 @@ +# Copyright (c) 2020 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/build.gni") +import("//build_overrides/chip.gni") + +# The location of the build configuration file. +buildconfig = "${build_root}/config/BUILDCONFIG.gn" + +# CHIP uses angle bracket includes. +check_system_includes = true + +default_args = { + target_cpu = "arm" + target_os = "freertos" + + import("//args.gni") + + # Import common example GN args + import("${chip_root}/examples/platform/nxp/common/gn/args.gni") + + # Import default platform configs + import("${chip_root}/src/platform/nxp/rt/rt1060/args.gni") +} diff --git a/examples/laundry-washer-app/nxp/rt/rt1060/BUILD.gn b/examples/laundry-washer-app/nxp/rt/rt1060/BUILD.gn new file mode 100644 index 00000000000000..eb7ea93bbd1d2c --- /dev/null +++ b/examples/laundry-washer-app/nxp/rt/rt1060/BUILD.gn @@ -0,0 +1,291 @@ +# Copyright (c) 2021-2023 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/build.gni") +import("//build_overrides/chip.gni") +import("//build_overrides/nxp_sdk.gni") +import("//build_overrides/openthread.gni") +import("${chip_root}/src/platform/device.gni") + +#allows to get common NXP SDK gn options +import("${nxp_sdk_build_root}/nxp_sdk.gni") + +# Allows to get various RT gn options +import("${nxp_sdk_build_root}/${nxp_sdk_name}/rt_sdk.gni") + +import("${chip_root}/src/platform/nxp/${nxp_platform}/args.gni") +import( + "${nxp_sdk_build_root}/${nxp_sdk_name}/${rt_platform}/${rt_platform}.gni") +import("${nxp_sdk_build_root}/${nxp_sdk_name}/nxp_executable.gni") + +assert(current_os == "freertos") +assert(target_os == "freertos") +assert(nxp_platform == "rt/rt1060") + +declare_args() { + # Allows to enable to ota_provider support + enable_ota_provider = false + + # Allows to connect to a predefine Wi-Fi network at boot + wifi_auto_connect_at_boot = false + wifi_auto_connect_at_boot_ssid = "" + wifi_auto_connect_at_boot_password = "" + + # Setup discriminator as argument + setup_discriminator = 3840 +} + +example_platform_dir = + "${nxp_sdk_matter_support_root}/examples/platform/${nxp_platform}" +common_example_dir = "${chip_root}/examples/platform/nxp/common" + +app_common_folder = "laundry-washer-app/nxp/zap" + +# Create here the SDK instance. +# Particular sources/defines/includes could be added/changed depending on the target application. +rt_sdk("sdk") { + defines = [] + + cflags = [] + public_deps = [] + public_configs = [] + sources = [] + include_dirs = [] + + # Indicate paths to default board files + include_dirs += [ "${example_platform_dir}/board/" ] + + # RT1060 rev A use same pin mux as rev B + # If user needs different pin mux files for rev A and rev B boards, the source and include from below needs to be updated accordingly + if (evkname == "evkmimxrt1060") { + include_dirs += [ "${example_platform_dir}/board/evkbmimxrt1060/" ] + sources += [ "${example_platform_dir}/board/evkbmimxrt1060/pin_mux.c" ] + } else { + include_dirs += [ "${example_platform_dir}/board/${evkname}/" ] + sources += [ "${example_platform_dir}/board/${evkname}/pin_mux.c" ] + } + sources += [ "${example_platform_dir}/board/hardware_init.c" ] + sources += [ "${example_platform_dir}/board/clock_config.c" ] + sources += [ "${example_platform_dir}/board/board.c" ] + sources += [ "${example_platform_dir}/board/peripherals.c" ] + + # Indicate the path to CHIPProjectConfig.h + include_dirs += [ "include/config" ] + + # Indicate the default path to FreeRTOSConfig.h + include_dirs += [ "${example_platform_dir}/app/project_include/freeRTOS" ] + + # Indicate the default path to OpenThreadConfig.h + include_dirs += [ "${example_platform_dir}/app/project_include/openthread" ] + + # For matter with BR feature, increase FreeRTOS heap size + if (chip_enable_wifi && chip_enable_openthread) { + defines += [ "configTOTAL_HEAP_SIZE=(size_t)(170 * 1024)" ] + } + + defines += [ + "CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR=${setup_discriminator}", + ] +} + +# Create the SDK driver instance. +# Particular sources/defines/includes could be added to add other drivers not available in the default sdk driver template +rt1060_sdk_drivers("sdk_driver") { +} + +rt_executable("laundry-washer") { + output_name = "chip-rt1060-laundry-washer-example" + + defines = [ + "CONFIG_RENDEZVOUS_MODE=7", + "CONFIG_APP_FREERTOS_OS=1", + ] + + if (chip_enable_openthread) { + defines += [ "CONFIG_NET_L2_OPENTHREAD=1" ] + } + + include_dirs = [ + "../../common/main/include", + "../../common/main", + "${chip_root}/examples/all-clusters-app/all-clusters-common/include", + "${chip_root}/examples/providers/", + ] + + sources = [ + "${chip_root}/examples/all-clusters-app/all-clusters-common/src/binding-handler.cpp", + "${chip_root}/examples/providers/DeviceInfoProviderImpl.cpp", + "../../common/main/AppTask.cpp", + "../../common/main/DeviceCallbacks.cpp", + "../../common/main/ZclCallbacks.cpp", + "../../common/main/include/AppEvent.h", + "../../common/main/include/AppTask.h", + "../../common/main/include/DeviceCallbacks.h", + "../../common/main/main.cpp", + ] + + # App common files + include_dirs += [ + "${common_example_dir}/icd/include", + "${common_example_dir}/matter_cli/include", + "${common_example_dir}/device_manager/include", + "${common_example_dir}/device_callbacks/include", + "${common_example_dir}/matter_button/include", + "${common_example_dir}/factory_data/include", + "${common_example_dir}/app_task/include", + ] + + sources += [ + "${chip_root}/examples/platform/nxp/${nxp_platform}/factory_data/source/AppFactoryDataExample.cpp", + "${common_example_dir}/app_task/source/AppTaskBase.cpp", + "${common_example_dir}/app_task/source/AppTaskFreeRTOS.cpp", + "${common_example_dir}/device_callbacks/source/CommonDeviceCallbacks.cpp", + "${common_example_dir}/device_manager/source/CHIPDeviceManager.cpp", + "${common_example_dir}/icd/source/ICDUtil.cpp", + "${common_example_dir}/matter_button/source/ButtonDefault.cpp", + "${common_example_dir}/matter_button/source/ButtonManager.cpp", + "${common_example_dir}/matter_button/source/ButtonRegistrationDefault.cpp", + ] + + deps = [ "${chip_root}/examples/${app_common_folder}" ] + + sources += [ + "${chip_root}/examples/all-clusters-app/all-clusters-common/src/bridged-actions-stub.cpp", + "${chip_root}/examples/all-clusters-app/all-clusters-common/src/laundry-washer-controls-delegate-impl.cpp", + "${chip_root}/examples/all-clusters-app/all-clusters-common/src/smco-stub.cpp", + "${chip_root}/examples/all-clusters-app/all-clusters-common/src/static-supported-modes-manager.cpp", + "${chip_root}/examples/all-clusters-app/all-clusters-common/src/static-supported-temperature-levels.cpp", + "../../common/main/laundry-washer-mode.cpp", + "../../common/main/operational-state-delegate-impl.cpp", + ] + + if (chip_enable_matter_cli) { + defines += [ "ENABLE_CHIP_SHELL" ] + deps += [ + "${chip_root}/examples/shell/shell_common:shell_common", + "${chip_root}/src/lib/shell:shell", + ] + sources += [ + "${common_example_dir}/matter_cli/source/AppCLIBase.cpp", + "${common_example_dir}/matter_cli/source/AppCLIFreeRTOS.cpp", + ] + } + + if (chip_enable_ota_requestor) { + sources += [ + "${chip_root}/examples/platform/nxp/common/mcuboot_app_support/flash_partitioning.h", + "${common_example_dir}/ota_requestor/source/OTARequestorInitiator.cpp", + "${common_example_dir}/ota_requestor/source/OTARequestorInitiatorCommon.cpp", + + #Adding mcuboot files + "${chip_root}/examples/platform/nxp/common/mcuboot_app_support/mcuboot_app_support.c", + "${chip_root}/examples/platform/nxp/common/mcuboot_app_support/mcuboot_app_support.h", + ] + include_dirs += [ + "$${common_example_dir}/ota_requestor/include", + "${chip_root}/examples/platform/nxp/common/mcuboot_app_support", + ] + } + + if (wifi_auto_connect_at_boot) { + assert(wifi_auto_connect_at_boot_ssid != "" && + wifi_auto_connect_at_boot_password != "", + "WiFi SSID and password must be specified at build time!") + + defines += [ + "CONFIG_CHIP_APP_WIFI_CONNECT_AT_BOOT=1", + "CONFIG_CHIP_APP_WIFI_SSID=\"${wifi_auto_connect_at_boot_ssid}\"", + "CONFIG_CHIP_APP_WIFI_PASSWORD=\"${wifi_auto_connect_at_boot_password}\"", + ] + + include_dirs += [ "${common_example_dir}/wifi_connect/include" ] + sources += [ "${common_example_dir}/wifi_connect/source/WifiConnect.cpp" ] + } + + if (enable_ota_provider) { + defines += [ "CONFIG_CHIP_OTA_PROVIDER=1" ] + + include_dirs += [ + "${common_example_dir}/ota_provider/include", + "${common_example_dir}/ota_provider/ota-provider-common", + ] + + sources += [ + "${common_example_dir}/ota_provider/ota-provider-common/RTBdxOtaSender.cpp", + "${common_example_dir}/ota_provider/ota-provider-common/RTOTAProviderExample.cpp", + "${common_example_dir}/ota_provider/source/OTAProvider.cpp", + ] + + deps += [ + "${chip_root}/src/app/server", + "${chip_root}/src/protocols/bdx", + "${chip_root}/third_party/jsoncpp", + ] + } + + # In case a dedicated assert function needs to be supported the flag sdk_fsl_assert_support should be set to false + # The would add to the build a dedicated application assert implementation. + if (!sdk_fsl_assert_support) { + sources += [ "${common_example_dir}/app_assert/source/AppAssert.cpp" ] + } + + cflags = [ "-Wconversion" ] + + ldscript = + "${example_platform_dir}/app/ldscripts/MIMXRT1062xxxxx_flexspi_nor.ld" + + inputs = [ ldscript ] + + ldflags = [ + "-T" + rebase_path(ldscript, root_build_dir), + "-fno-common", + "-Wl,--defsym=__stack_size__=2048", + "-ffreestanding", + "-fno-builtin", + "-mapcs", + "-u qspiflash_config", + "-u image_vector_table", + "-u boot_data", + "-u dcd_data", + "-Wl,-print-memory-usage", + "-Wl,--no-warn-rwx-segments", + ] + + if (enable_ota_provider) { + # As the OTA file will be stored in the littlefs file system, it is required to increase the size of the file system + # To be able to store an OTA file with a MAX size of 640K, + # it recommended to size the file system with: + # 161 sectors of 4K => reserved for the OTA file + # 32 sectors of 4K => reserved for Matter/OT/BLE settings storage + ldflags += [ "-Wl,--defsym=gNVMSectorCountLink_d=193" ] + } + + if (chip_enable_ota_requestor) { + # If OTA build flag is enabled, + # we would need to reserve enough space for the bootloader (MCUBoot) + # MCUBoot requires 0x11000 Bytes to be reserved at the base of the flash + # Consequently, some sections will need to be shifted + ldflags += [ "-Wl,--defsym=__mcu_boot_size__=0x11000" ] + } + + output_dir = root_out_dir +} + +group("rt1060") { + deps = [ ":laundry-washer" ] +} + +group("default") { + deps = [ ":rt1060" ] +} diff --git a/examples/laundry-washer-app/nxp/rt/rt1060/README.md b/examples/laundry-washer-app/nxp/rt/rt1060/README.md new file mode 100644 index 00000000000000..62d4847a4a5cef --- /dev/null +++ b/examples/laundry-washer-app/nxp/rt/rt1060/README.md @@ -0,0 +1,5 @@ +# CHIP RT1060 Thermostat Application + +All instructions describing how to use a Matter application on NXP RT1060 can be +found in [README.md](../../../../all-clusters-app/nxp/rt/rt1060/README.md) root +readme diff --git a/examples/laundry-washer-app/nxp/rt/rt1060/args.gni b/examples/laundry-washer-app/nxp/rt/rt1060/args.gni new file mode 100644 index 00000000000000..d65714c9287ce5 --- /dev/null +++ b/examples/laundry-washer-app/nxp/rt/rt1060/args.gni @@ -0,0 +1,25 @@ +# Copyright (c) 2023 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/chip.gni") + +# SDK target definitions +nxp_sdk_target = get_label_info(":sdk", "label_no_toolchain") +nxp_sdk_driver_target = get_label_info(":sdk_driver", "label_no_toolchain") + +# ICDM +chip_enable_icd_server = true +chip_persist_subscriptions = true +chip_subscription_timeout_resumption = true +chip_enable_icd_checkin = true diff --git a/examples/laundry-washer-app/nxp/rt/rt1060/build_overrides b/examples/laundry-washer-app/nxp/rt/rt1060/build_overrides new file mode 120000 index 00000000000000..f10867042f4d19 --- /dev/null +++ b/examples/laundry-washer-app/nxp/rt/rt1060/build_overrides @@ -0,0 +1 @@ +../../../../build_overrides \ No newline at end of file diff --git a/examples/laundry-washer-app/nxp/rt/rt1060/include/config/CHIPProjectConfig.h b/examples/laundry-washer-app/nxp/rt/rt1060/include/config/CHIPProjectConfig.h new file mode 100644 index 00000000000000..dd73c6c9eaaedd --- /dev/null +++ b/examples/laundry-washer-app/nxp/rt/rt1060/include/config/CHIPProjectConfig.h @@ -0,0 +1,216 @@ +/* + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2020 Google LLC. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Example project configuration file for CHIP. + * + * This is a place to put application or project-specific overrides + * to the default configuration values for general CHIP features. + * + */ + +#pragma once + +/* + * Tells to the platform Factory Data Provider whether to use the example configuration or real/provisioned data. + */ +#ifndef CONFIG_CHIP_PLAT_LOAD_REAL_FACTORY_DATA +#define CONFIG_CHIP_PLAT_LOAD_REAL_FACTORY_DATA 0 +#endif + +/** + * CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID + * + * 0xFFF1: Test vendor. + */ +#define CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID 0xFFF1 + +/** + * CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID + * + */ +#define CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID 0x8005 + +#if !CONFIG_CHIP_PLAT_LOAD_REAL_FACTORY_DATA +// Use a default pairing code if one hasn't been provisioned in flash. +#ifndef CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE +#define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE 20202021 +#endif + +#ifndef CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR +#define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR 0xF00 +#endif + +// Use a default pairing code if one hasn't been provisioned in flash. +#define CHIP_DEVICE_CONFIG_USE_TEST_PAIRING_CODE "CHIPUS" + +/** + * CHIP_DEVICE_CONFIG_USE_TEST_SERIAL_NUMBER + * + * Enables the use of a hard-coded default serial number if none + * is found in CHIP NV storage. + */ +#define CHIP_DEVICE_CONFIG_USE_TEST_SERIAL_NUMBER "DUMMY_SN" + +#endif /* !CONFIG_CHIP_PLAT_LOAD_REAL_FACTORY_DATA */ + +/** + * CHIP_DEVICE_CONFIG_DEVICE_HARDWARE_VERSION + * + * The hardware version number assigned to device or product by the device vendor. This + * number is scoped to the device product id, and typically corresponds to a revision of the + * physical device, a change to its packaging, and/or a change to its marketing presentation. + * This value is generally *not* incremented for device software versions. + */ +#define CHIP_DEVICE_CONFIG_DEVICE_HARDWARE_VERSION 100 + +#ifndef CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION_STRING +#define CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION_STRING "v0.1.0" +#endif + +/** + * CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING + * + * A string identifying the software version running on the device. + * CHIP currently expects the software version to be in the format + * {MAJOR_VERSION}.0d{MINOR_VERSION} + */ +#ifndef CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING +#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING NXP_CONFIG_DEVICE_SOFTWARE_VERSION_STRING +#endif + +#ifndef CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION +#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION NXP_CONFIG_DEVICE_SOFTWARE_VERSION +#endif + +#ifndef CHIP_DEVICE_CONFIG_DEVICE_VENDOR_NAME +#define CHIP_DEVICE_CONFIG_DEVICE_VENDOR_NAME "NXP Semiconductors" +#endif + +#ifndef CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_NAME +#define CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_NAME "NXP Demo App" +#endif + +#ifndef CHIP_DEVICE_CONFIG_CERTIFICATION_DECLARATION +//-> format_version = 1 +//-> vendor_id = 0xFFF1 +//-> product_id_array = [ 0x8000, 0x8001, 0x8002, 0x8003, 0x8004, 0x8005, 0x8006, 0x8007, 0x8008, 0x8009, 0x800A, 0x800B, +// 0x800C, 0x800D, 0x800E, 0x800F, 0x8010, 0x8011, 0x8012, 0x8013, 0x8014, 0x8015, 0x8016, 0x8017, 0x8018, 0x8019, 0x801A, +// 0x801B, 0x801C, 0x801D, 0x801E, 0x801F, 0x8020, 0x8021, 0x8022, 0x8023, 0x8024, 0x8025, 0x8026, 0x8027, 0x8028, 0x8029, +// 0x802A, 0x802B, 0x802C, 0x802D, 0x802E, 0x802F, 0x8030, 0x8031, 0x8032, 0x8033, 0x8034, 0x8035, 0x8036, 0x8037, 0x8038, +// 0x8039, 0x803A, 0x803B, 0x803C, 0x803D, 0x803E, 0x803F, 0x8040, 0x8041, 0x8042, 0x8043, 0x8044, 0x8045, 0x8046, 0x8047, +// 0x8048, 0x8049, 0x804A, 0x804B, 0x804C, 0x804D, 0x804E, 0x804F, 0x8050, 0x8051, 0x8052, 0x8053, 0x8054, 0x8055, 0x8056, +// 0x8057, 0x8058, 0x8059, 0x805A, 0x805B, 0x805C, 0x805D, 0x805E, 0x805F, 0x8060, 0x8061, 0x8062, 0x8063 ] +//-> device_type_id = 0x0016 +//-> certificate_id = "ZIG20142ZB330003-24" +//-> security_level = 0 +//-> security_information = 0 +//-> version_number = 0x2694 +//-> certification_type = 0 +//-> dac_origin_vendor_id is not present +//-> dac_origin_product_id is not present +#define CHIP_DEVICE_CONFIG_CERTIFICATION_DECLARATION \ + { \ + 0x30, 0x82, 0x02, 0x19, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x82, 0x02, 0x0a, 0x30, \ + 0x82, 0x02, 0x06, 0x02, 0x01, 0x03, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, \ + 0x02, 0x01, 0x30, 0x82, 0x01, 0x71, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, \ + 0x01, 0x62, 0x04, 0x82, 0x01, 0x5e, 0x15, 0x24, 0x00, 0x01, 0x25, 0x01, 0xf1, 0xff, 0x36, 0x02, 0x05, 0x00, 0x80, \ + 0x05, 0x01, 0x80, 0x05, 0x02, 0x80, 0x05, 0x03, 0x80, 0x05, 0x04, 0x80, 0x05, 0x05, 0x80, 0x05, 0x06, 0x80, 0x05, \ + 0x07, 0x80, 0x05, 0x08, 0x80, 0x05, 0x09, 0x80, 0x05, 0x0a, 0x80, 0x05, 0x0b, 0x80, 0x05, 0x0c, 0x80, 0x05, 0x0d, \ + 0x80, 0x05, 0x0e, 0x80, 0x05, 0x0f, 0x80, 0x05, 0x10, 0x80, 0x05, 0x11, 0x80, 0x05, 0x12, 0x80, 0x05, 0x13, 0x80, \ + 0x05, 0x14, 0x80, 0x05, 0x15, 0x80, 0x05, 0x16, 0x80, 0x05, 0x17, 0x80, 0x05, 0x18, 0x80, 0x05, 0x19, 0x80, 0x05, \ + 0x1a, 0x80, 0x05, 0x1b, 0x80, 0x05, 0x1c, 0x80, 0x05, 0x1d, 0x80, 0x05, 0x1e, 0x80, 0x05, 0x1f, 0x80, 0x05, 0x20, \ + 0x80, 0x05, 0x21, 0x80, 0x05, 0x22, 0x80, 0x05, 0x23, 0x80, 0x05, 0x24, 0x80, 0x05, 0x25, 0x80, 0x05, 0x26, 0x80, \ + 0x05, 0x27, 0x80, 0x05, 0x28, 0x80, 0x05, 0x29, 0x80, 0x05, 0x2a, 0x80, 0x05, 0x2b, 0x80, 0x05, 0x2c, 0x80, 0x05, \ + 0x2d, 0x80, 0x05, 0x2e, 0x80, 0x05, 0x2f, 0x80, 0x05, 0x30, 0x80, 0x05, 0x31, 0x80, 0x05, 0x32, 0x80, 0x05, 0x33, \ + 0x80, 0x05, 0x34, 0x80, 0x05, 0x35, 0x80, 0x05, 0x36, 0x80, 0x05, 0x37, 0x80, 0x05, 0x38, 0x80, 0x05, 0x39, 0x80, \ + 0x05, 0x3a, 0x80, 0x05, 0x3b, 0x80, 0x05, 0x3c, 0x80, 0x05, 0x3d, 0x80, 0x05, 0x3e, 0x80, 0x05, 0x3f, 0x80, 0x05, \ + 0x40, 0x80, 0x05, 0x41, 0x80, 0x05, 0x42, 0x80, 0x05, 0x43, 0x80, 0x05, 0x44, 0x80, 0x05, 0x45, 0x80, 0x05, 0x46, \ + 0x80, 0x05, 0x47, 0x80, 0x05, 0x48, 0x80, 0x05, 0x49, 0x80, 0x05, 0x4a, 0x80, 0x05, 0x4b, 0x80, 0x05, 0x4c, 0x80, \ + 0x05, 0x4d, 0x80, 0x05, 0x4e, 0x80, 0x05, 0x4f, 0x80, 0x05, 0x50, 0x80, 0x05, 0x51, 0x80, 0x05, 0x52, 0x80, 0x05, \ + 0x53, 0x80, 0x05, 0x54, 0x80, 0x05, 0x55, 0x80, 0x05, 0x56, 0x80, 0x05, 0x57, 0x80, 0x05, 0x58, 0x80, 0x05, 0x59, \ + 0x80, 0x05, 0x5a, 0x80, 0x05, 0x5b, 0x80, 0x05, 0x5c, 0x80, 0x05, 0x5d, 0x80, 0x05, 0x5e, 0x80, 0x05, 0x5f, 0x80, \ + 0x05, 0x60, 0x80, 0x05, 0x61, 0x80, 0x05, 0x62, 0x80, 0x05, 0x63, 0x80, 0x18, 0x24, 0x03, 0x16, 0x2c, 0x04, 0x13, \ + 0x5a, 0x49, 0x47, 0x32, 0x30, 0x31, 0x34, 0x32, 0x5a, 0x42, 0x33, 0x33, 0x30, 0x30, 0x30, 0x33, 0x2d, 0x32, 0x34, \ + 0x24, 0x05, 0x00, 0x24, 0x06, 0x00, 0x25, 0x07, 0x94, 0x26, 0x24, 0x08, 0x00, 0x18, 0x31, 0x7d, 0x30, 0x7b, 0x02, \ + 0x01, 0x03, 0x80, 0x14, 0x62, 0xfa, 0x82, 0x33, 0x59, 0xac, 0xfa, 0xa9, 0x96, 0x3e, 0x1c, 0xfa, 0x14, 0x0a, 0xdd, \ + 0xf5, 0x04, 0xf3, 0x71, 0x60, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x30, \ + 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x04, 0x47, 0x30, 0x45, 0x02, 0x20, 0x24, 0xe5, \ + 0xd1, 0xf4, 0x7a, 0x7d, 0x7b, 0x0d, 0x20, 0x6a, 0x26, 0xef, 0x69, 0x9b, 0x7c, 0x97, 0x57, 0xb7, 0x2d, 0x46, 0x90, \ + 0x89, 0xde, 0x31, 0x92, 0xe6, 0x78, 0xc7, 0x45, 0xe7, 0xf6, 0x0c, 0x02, 0x21, 0x00, 0xf8, 0xaa, 0x2f, 0xa7, 0x11, \ + 0xfc, 0xb7, 0x9b, 0x97, 0xe3, 0x97, 0xce, 0xda, 0x66, 0x7b, 0xae, 0x46, 0x4e, 0x2b, 0xd3, 0xff, 0xdf, 0xc3, 0xcc, \ + 0xed, 0x7a, 0xa8, 0xca, 0x5f, 0x4c, 0x1a, 0x7c \ + } +#endif + +/** + * CHIP_DEVICE_CONFIG_ENABLE_CHIP_TIME_SERVICE_TIME_SYNC + * + * Enables synchronizing the device's real time clock with a remote CHIP Time service + * using the CHIP Time Sync protocol. + */ +// #define CHIP_DEVICE_CONFIG_ENABLE_CHIP_TIME_SERVICE_TIME_SYNC 1 + +/** + * CHIP_CONFIG_MAX_BINDINGS + * + * Maximum number of simultaneously active bindings per ChipExchangeManager + * 1 (Time Sync) + 2 (Two 1-way subscriptions) + 1 (Software Update) = 4 + * in the worst case. Keeping another 4 as buffer. + */ +#define CHIP_CONFIG_MAX_BINDINGS 6 + +/** + * CHIP_CONFIG_EVENT_LOGGING_WDM_OFFLOAD + * + * Select the ability to offload event logs to any interested subscribers using WDM. + */ +#define CHIP_CONFIG_EVENT_LOGGING_WDM_OFFLOAD 1 + +/** + * CHIP_CONFIG_EVENT_LOGGING_UTC_TIMESTAMPS + * + * Enable recording UTC timestamps. + */ +#define CHIP_CONFIG_EVENT_LOGGING_UTC_TIMESTAMPS 1 + +/** + * CHIP_DEVICE_CONFIG_EVENT_LOGGING_DEBUG_BUFFER_SIZE + * + * A size, in bytes, of the individual debug event logging buffer. + */ +#define CHIP_DEVICE_CONFIG_EVENT_LOGGING_DEBUG_BUFFER_SIZE (512) + +/** + * CHIP_CONFIG_EVENT_LOGGING_DEFAULT_IMPORTANCE + * + * For a development build, set the default importance of events to be logged as Debug. + * Since debug is the lowest importance level, this means all standard, critical, info and + * debug importance level vi events get logged. + */ +#if BUILD_RELEASE +#define CHIP_CONFIG_EVENT_LOGGING_DEFAULT_IMPORTANCE chip::Profiles::DataManagement::Production +#else +#define CHIP_CONFIG_EVENT_LOGGING_DEFAULT_IMPORTANCE chip::Profiles::DataManagement::Debug +#endif // BUILD_RELEASE + +/* Increasing the retransmission interval of the MRP messages after subsequent failures */ +#ifndef CHIP_CONFIG_MRP_LOCAL_ACTIVE_RETRY_INTERVAL +#define CHIP_CONFIG_MRP_LOCAL_ACTIVE_RETRY_INTERVAL (2000_ms32) +#endif diff --git a/examples/laundry-washer-app/nxp/rt/rt1060/third_party/connectedhomeip b/examples/laundry-washer-app/nxp/rt/rt1060/third_party/connectedhomeip new file mode 120000 index 00000000000000..305f2077ffe860 --- /dev/null +++ b/examples/laundry-washer-app/nxp/rt/rt1060/third_party/connectedhomeip @@ -0,0 +1 @@ +../../../../../.. \ No newline at end of file diff --git a/examples/laundry-washer-app/nxp/rt/rt1170/.gn b/examples/laundry-washer-app/nxp/rt/rt1170/.gn new file mode 100644 index 00000000000000..59dcfeb229ae70 --- /dev/null +++ b/examples/laundry-washer-app/nxp/rt/rt1170/.gn @@ -0,0 +1,35 @@ +# Copyright (c) 2020 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/build.gni") +import("//build_overrides/chip.gni") + +# The location of the build configuration file. +buildconfig = "${build_root}/config/BUILDCONFIG.gn" + +# CHIP uses angle bracket includes. +check_system_includes = true + +default_args = { + target_cpu = "arm" + target_os = "freertos" + + import("//args.gni") + + # Import common example GN args + import("${chip_root}/examples/platform/nxp/common/gn/args.gni") + + # Import default platform configs + import("${chip_root}/src/platform/nxp/rt/rt1170/args.gni") +} diff --git a/examples/laundry-washer-app/nxp/rt/rt1170/BUILD.gn b/examples/laundry-washer-app/nxp/rt/rt1170/BUILD.gn new file mode 100644 index 00000000000000..96b035e8628f5d --- /dev/null +++ b/examples/laundry-washer-app/nxp/rt/rt1170/BUILD.gn @@ -0,0 +1,246 @@ +# Copyright (c) 2021-2023 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/build.gni") +import("//build_overrides/chip.gni") +import("//build_overrides/nxp_sdk.gni") +import("//build_overrides/openthread.gni") +import("${chip_root}/src/platform/device.gni") + +#allows to get common NXP SDK gn options +import("${nxp_sdk_build_root}/nxp_sdk.gni") + +# Allows to get various RT gn options +import("${nxp_sdk_build_root}/${nxp_sdk_name}/rt_sdk.gni") + +import("${chip_root}/src/platform/nxp/${nxp_platform}/args.gni") +import( + "${nxp_sdk_build_root}/${nxp_sdk_name}/${rt_platform}/${rt_platform}.gni") +import("${nxp_sdk_build_root}/${nxp_sdk_name}/nxp_executable.gni") + +assert(current_os == "freertos") +assert(target_os == "freertos") +assert(nxp_platform == "rt/rt1170") + +declare_args() { + # Allows to connect to a predefine Wi-Fi network at boot + wifi_auto_connect_at_boot = false + wifi_auto_connect_at_boot_ssid = "" + wifi_auto_connect_at_boot_password = "" + + # Setup discriminator as argument + setup_discriminator = 3840 +} + +example_platform_dir = + "${nxp_sdk_matter_support_root}/examples/platform/${nxp_platform}" +common_example_dir = "${chip_root}/examples/platform/nxp/common" + +# Use NXP custom zap files for laundry-washer device-type +app_common_folder = "laundry-washer-app/nxp/zap" + +# Create here the SDK instance. +# Particular sources/defines/includes could be added/changed depending on the target application. +rt_sdk("sdk") { + defines = [] + + cflags = [] + public_deps = [] + public_configs = [] + sources = [] + include_dirs = [] + + # Indicate paths to default board files + include_dirs += [ "${example_platform_dir}/board/" ] + sources += [ "${example_platform_dir}/board/pin_mux.c" ] + sources += [ "${example_platform_dir}/board/hardware_init.c" ] + sources += [ "${example_platform_dir}/board/clock_config.c" ] + sources += [ "${example_platform_dir}/board/board.c" ] + sources += [ "${example_platform_dir}/board/peripherals.c" ] + sources += [ "${example_platform_dir}/board/sdmmc_config.c" ] + + # Indicate the path to CHIPProjectConfig.h + include_dirs += [ "include/config" ] + + # Indicate the default path to FreeRTOSConfig.h + include_dirs += [ "${example_platform_dir}/app/project_include/freeRTOS" ] + + # Indicate the default path to OpenThreadConfig.h + include_dirs += [ "${example_platform_dir}/app/project_include/openthread" ] + + # For matter with BR feature, increase FreeRTOS heap size + if (chip_enable_wifi && chip_enable_openthread) { + defines += [ "configTOTAL_HEAP_SIZE=(size_t)(170 * 1024)" ] + } + + defines += [ + "CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR=${setup_discriminator}", + ] +} + +# Create the SDK driver instance. +# Particular sources/defines/includes could be added to add other drivers not available in the default sdk driver template +rt1170_sdk_drivers("sdk_driver") { +} + +rt_executable("laundry-washer-app") { + output_name = "chip-rt1170-laundry-washer-example" + + defines = [ + "CONFIG_RENDEZVOUS_MODE=7", + "CONFIG_APP_FREERTOS_OS=1", + ] + + if (chip_enable_openthread) { + defines += [ "CONFIG_NET_L2_OPENTHREAD=1" ] + } + + include_dirs = [ + "../../common/main/include", + "../../common/main", + "${chip_root}/examples/all-clusters-app/all-clusters-common/include", + "${chip_root}/examples/providers/", + ] + + sources = [ + "${chip_root}/examples/all-clusters-app/all-clusters-common/src/binding-handler.cpp", + "${chip_root}/examples/providers/DeviceInfoProviderImpl.cpp", + "../../common/main/AppTask.cpp", + "../../common/main/DeviceCallbacks.cpp", + "../../common/main/ZclCallbacks.cpp", + "../../common/main/include/AppEvent.h", + "../../common/main/include/AppTask.h", + "../../common/main/include/DeviceCallbacks.h", + "../../common/main/main.cpp", + ] + + # App common files + include_dirs += [ + "${common_example_dir}/icd/include", + "${common_example_dir}/matter_button/include", + "${common_example_dir}/matter_cli/include", + "${common_example_dir}/device_manager/include", + "${common_example_dir}/device_callbacks/include", + "${common_example_dir}/factory_data/include", + "${common_example_dir}/app_task/include", + ] + + sources += [ + "${common_example_dir}/app_task/source/AppTaskBase.cpp", + "${common_example_dir}/app_task/source/AppTaskFreeRTOS.cpp", + "${common_example_dir}/device_callbacks/source/CommonDeviceCallbacks.cpp", + "${common_example_dir}/device_manager/source/CHIPDeviceManager.cpp", + "${common_example_dir}/factory_data/source/AppFactoryDataDefaultImpl.cpp", + "${common_example_dir}/icd/source/ICDUtil.cpp", + "${common_example_dir}/matter_button/source/ButtonRegistrationEmpty.cpp", + ] + + deps = [ "${chip_root}/examples/${app_common_folder}" ] + + sources += [ + "${chip_root}/examples/all-clusters-app/all-clusters-common/src/bridged-actions-stub.cpp", + "${chip_root}/examples/all-clusters-app/all-clusters-common/src/laundry-washer-controls-delegate-impl.cpp", + "${chip_root}/examples/all-clusters-app/all-clusters-common/src/smco-stub.cpp", + "${chip_root}/examples/all-clusters-app/all-clusters-common/src/static-supported-modes-manager.cpp", + "${chip_root}/examples/all-clusters-app/all-clusters-common/src/static-supported-temperature-levels.cpp", + "../../common/main/laundry-washer-mode.cpp", + "../../common/main/operational-state-delegate-impl.cpp", + ] + + if (chip_enable_matter_cli) { + defines += [ "ENABLE_CHIP_SHELL" ] + deps += [ + "${chip_root}/examples/shell/shell_common:shell_common", + "${chip_root}/src/lib/shell:shell", + ] + sources += [ + "${common_example_dir}/matter_cli/source/AppCLIBase.cpp", + "${common_example_dir}/matter_cli/source/AppCLIFreeRTOS.cpp", + ] + } + + if (chip_enable_ota_requestor) { + include_dirs += [ "${common_example_dir}/ota_requestor/include" ] + sources += [ + "${common_example_dir}/ota_requestor/source/OTARequestorInitiator.cpp", + "${common_example_dir}/ota_requestor/source/OTARequestorInitiatorCommon.cpp", + ] + } + + if (wifi_auto_connect_at_boot) { + assert(wifi_auto_connect_at_boot_ssid != "" && + wifi_auto_connect_at_boot_password != "", + "WiFi SSID and password must be specified at build time!") + + defines += [ + "CONFIG_CHIP_APP_WIFI_CONNECT_AT_BOOT=1", + "CONFIG_CHIP_APP_WIFI_SSID=\"${wifi_auto_connect_at_boot_ssid}\"", + "CONFIG_CHIP_APP_WIFI_PASSWORD=\"${wifi_auto_connect_at_boot_password}\"", + ] + + include_dirs += [ "${common_example_dir}/wifi_connect/include" ] + sources += [ "${common_example_dir}/wifi_connect/source/WifiConnect.cpp" ] + } + + # In case a dedicated assert function needs to be supported the flag sdk_fsl_assert_support should be set to false + # The would add to the build a dedicated application assert implementation. + if (!sdk_fsl_assert_support) { + sources += [ "${common_example_dir}/app_assert/source/AppAssert.cpp" ] + } + + cflags = [ "-Wconversion" ] + + ldscript = + "${example_platform_dir}/app/ldscripts/MIMXRT1176xxxxx_cm7_flexspi_nor.ld" + + inputs = [ ldscript ] + + ldflags = [ + "-T" + rebase_path(ldscript, root_build_dir), + "-fno-common", + "-Wl,--defsym=__stack_size__=2048", + "-ffreestanding", + "-fno-builtin", + "-mapcs", + "-u qspiflash_config", + "-u image_vector_table", + "-u boot_data", + "-u dcd_data", + "-Wl,-print-memory-usage", + "-Wl,--no-warn-rwx-segments", + ] + + if (chip_enable_ota_requestor) { + if (no_mcuboot) { + # If "no_mcuboot" is set to true, the application will be linked at the base of the flash. + print( + "Warning : The OTA Requestor is enabled without MCUBoot. This will prevent the application from applying software updates.") + } else { + # we need to reserve enough space for the bootloader (MCUBoot) + # MCUBoot requires 0x40000 Bytes to be reserved at the base of the flash + # Consequently, some sections will need to be shifted + ldflags += [ "-Wl,--defsym=__m_mcuboot_size__=0x40000" ] + } + } + + output_dir = root_out_dir +} + +group("rt1170") { + deps = [ ":laundry-washer-app" ] +} + +group("default") { + deps = [ ":rt1170" ] +} diff --git a/examples/laundry-washer-app/nxp/rt/rt1170/README.md b/examples/laundry-washer-app/nxp/rt/rt1170/README.md new file mode 100644 index 00000000000000..97101758c8e389 --- /dev/null +++ b/examples/laundry-washer-app/nxp/rt/rt1170/README.md @@ -0,0 +1,5 @@ +# CHIP RT1170 Thermostat Application + +All instructions describing how to use a Matter application on NXP RT11170 can +be found in [README.md](../../../../all-clusters-app/nxp/rt/rt1170/README.md) +root readme diff --git a/examples/laundry-washer-app/nxp/rt/rt1170/args.gni b/examples/laundry-washer-app/nxp/rt/rt1170/args.gni new file mode 100644 index 00000000000000..d65714c9287ce5 --- /dev/null +++ b/examples/laundry-washer-app/nxp/rt/rt1170/args.gni @@ -0,0 +1,25 @@ +# Copyright (c) 2023 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/chip.gni") + +# SDK target definitions +nxp_sdk_target = get_label_info(":sdk", "label_no_toolchain") +nxp_sdk_driver_target = get_label_info(":sdk_driver", "label_no_toolchain") + +# ICDM +chip_enable_icd_server = true +chip_persist_subscriptions = true +chip_subscription_timeout_resumption = true +chip_enable_icd_checkin = true diff --git a/examples/laundry-washer-app/nxp/rt/rt1170/build_overrides b/examples/laundry-washer-app/nxp/rt/rt1170/build_overrides new file mode 120000 index 00000000000000..f10867042f4d19 --- /dev/null +++ b/examples/laundry-washer-app/nxp/rt/rt1170/build_overrides @@ -0,0 +1 @@ +../../../../build_overrides \ No newline at end of file diff --git a/examples/laundry-washer-app/nxp/rt/rt1170/include/config/CHIPProjectConfig.h b/examples/laundry-washer-app/nxp/rt/rt1170/include/config/CHIPProjectConfig.h new file mode 100644 index 00000000000000..dd73c6c9eaaedd --- /dev/null +++ b/examples/laundry-washer-app/nxp/rt/rt1170/include/config/CHIPProjectConfig.h @@ -0,0 +1,216 @@ +/* + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2020 Google LLC. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Example project configuration file for CHIP. + * + * This is a place to put application or project-specific overrides + * to the default configuration values for general CHIP features. + * + */ + +#pragma once + +/* + * Tells to the platform Factory Data Provider whether to use the example configuration or real/provisioned data. + */ +#ifndef CONFIG_CHIP_PLAT_LOAD_REAL_FACTORY_DATA +#define CONFIG_CHIP_PLAT_LOAD_REAL_FACTORY_DATA 0 +#endif + +/** + * CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID + * + * 0xFFF1: Test vendor. + */ +#define CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID 0xFFF1 + +/** + * CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID + * + */ +#define CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID 0x8005 + +#if !CONFIG_CHIP_PLAT_LOAD_REAL_FACTORY_DATA +// Use a default pairing code if one hasn't been provisioned in flash. +#ifndef CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE +#define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE 20202021 +#endif + +#ifndef CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR +#define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR 0xF00 +#endif + +// Use a default pairing code if one hasn't been provisioned in flash. +#define CHIP_DEVICE_CONFIG_USE_TEST_PAIRING_CODE "CHIPUS" + +/** + * CHIP_DEVICE_CONFIG_USE_TEST_SERIAL_NUMBER + * + * Enables the use of a hard-coded default serial number if none + * is found in CHIP NV storage. + */ +#define CHIP_DEVICE_CONFIG_USE_TEST_SERIAL_NUMBER "DUMMY_SN" + +#endif /* !CONFIG_CHIP_PLAT_LOAD_REAL_FACTORY_DATA */ + +/** + * CHIP_DEVICE_CONFIG_DEVICE_HARDWARE_VERSION + * + * The hardware version number assigned to device or product by the device vendor. This + * number is scoped to the device product id, and typically corresponds to a revision of the + * physical device, a change to its packaging, and/or a change to its marketing presentation. + * This value is generally *not* incremented for device software versions. + */ +#define CHIP_DEVICE_CONFIG_DEVICE_HARDWARE_VERSION 100 + +#ifndef CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION_STRING +#define CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION_STRING "v0.1.0" +#endif + +/** + * CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING + * + * A string identifying the software version running on the device. + * CHIP currently expects the software version to be in the format + * {MAJOR_VERSION}.0d{MINOR_VERSION} + */ +#ifndef CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING +#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING NXP_CONFIG_DEVICE_SOFTWARE_VERSION_STRING +#endif + +#ifndef CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION +#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION NXP_CONFIG_DEVICE_SOFTWARE_VERSION +#endif + +#ifndef CHIP_DEVICE_CONFIG_DEVICE_VENDOR_NAME +#define CHIP_DEVICE_CONFIG_DEVICE_VENDOR_NAME "NXP Semiconductors" +#endif + +#ifndef CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_NAME +#define CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_NAME "NXP Demo App" +#endif + +#ifndef CHIP_DEVICE_CONFIG_CERTIFICATION_DECLARATION +//-> format_version = 1 +//-> vendor_id = 0xFFF1 +//-> product_id_array = [ 0x8000, 0x8001, 0x8002, 0x8003, 0x8004, 0x8005, 0x8006, 0x8007, 0x8008, 0x8009, 0x800A, 0x800B, +// 0x800C, 0x800D, 0x800E, 0x800F, 0x8010, 0x8011, 0x8012, 0x8013, 0x8014, 0x8015, 0x8016, 0x8017, 0x8018, 0x8019, 0x801A, +// 0x801B, 0x801C, 0x801D, 0x801E, 0x801F, 0x8020, 0x8021, 0x8022, 0x8023, 0x8024, 0x8025, 0x8026, 0x8027, 0x8028, 0x8029, +// 0x802A, 0x802B, 0x802C, 0x802D, 0x802E, 0x802F, 0x8030, 0x8031, 0x8032, 0x8033, 0x8034, 0x8035, 0x8036, 0x8037, 0x8038, +// 0x8039, 0x803A, 0x803B, 0x803C, 0x803D, 0x803E, 0x803F, 0x8040, 0x8041, 0x8042, 0x8043, 0x8044, 0x8045, 0x8046, 0x8047, +// 0x8048, 0x8049, 0x804A, 0x804B, 0x804C, 0x804D, 0x804E, 0x804F, 0x8050, 0x8051, 0x8052, 0x8053, 0x8054, 0x8055, 0x8056, +// 0x8057, 0x8058, 0x8059, 0x805A, 0x805B, 0x805C, 0x805D, 0x805E, 0x805F, 0x8060, 0x8061, 0x8062, 0x8063 ] +//-> device_type_id = 0x0016 +//-> certificate_id = "ZIG20142ZB330003-24" +//-> security_level = 0 +//-> security_information = 0 +//-> version_number = 0x2694 +//-> certification_type = 0 +//-> dac_origin_vendor_id is not present +//-> dac_origin_product_id is not present +#define CHIP_DEVICE_CONFIG_CERTIFICATION_DECLARATION \ + { \ + 0x30, 0x82, 0x02, 0x19, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x82, 0x02, 0x0a, 0x30, \ + 0x82, 0x02, 0x06, 0x02, 0x01, 0x03, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, \ + 0x02, 0x01, 0x30, 0x82, 0x01, 0x71, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, \ + 0x01, 0x62, 0x04, 0x82, 0x01, 0x5e, 0x15, 0x24, 0x00, 0x01, 0x25, 0x01, 0xf1, 0xff, 0x36, 0x02, 0x05, 0x00, 0x80, \ + 0x05, 0x01, 0x80, 0x05, 0x02, 0x80, 0x05, 0x03, 0x80, 0x05, 0x04, 0x80, 0x05, 0x05, 0x80, 0x05, 0x06, 0x80, 0x05, \ + 0x07, 0x80, 0x05, 0x08, 0x80, 0x05, 0x09, 0x80, 0x05, 0x0a, 0x80, 0x05, 0x0b, 0x80, 0x05, 0x0c, 0x80, 0x05, 0x0d, \ + 0x80, 0x05, 0x0e, 0x80, 0x05, 0x0f, 0x80, 0x05, 0x10, 0x80, 0x05, 0x11, 0x80, 0x05, 0x12, 0x80, 0x05, 0x13, 0x80, \ + 0x05, 0x14, 0x80, 0x05, 0x15, 0x80, 0x05, 0x16, 0x80, 0x05, 0x17, 0x80, 0x05, 0x18, 0x80, 0x05, 0x19, 0x80, 0x05, \ + 0x1a, 0x80, 0x05, 0x1b, 0x80, 0x05, 0x1c, 0x80, 0x05, 0x1d, 0x80, 0x05, 0x1e, 0x80, 0x05, 0x1f, 0x80, 0x05, 0x20, \ + 0x80, 0x05, 0x21, 0x80, 0x05, 0x22, 0x80, 0x05, 0x23, 0x80, 0x05, 0x24, 0x80, 0x05, 0x25, 0x80, 0x05, 0x26, 0x80, \ + 0x05, 0x27, 0x80, 0x05, 0x28, 0x80, 0x05, 0x29, 0x80, 0x05, 0x2a, 0x80, 0x05, 0x2b, 0x80, 0x05, 0x2c, 0x80, 0x05, \ + 0x2d, 0x80, 0x05, 0x2e, 0x80, 0x05, 0x2f, 0x80, 0x05, 0x30, 0x80, 0x05, 0x31, 0x80, 0x05, 0x32, 0x80, 0x05, 0x33, \ + 0x80, 0x05, 0x34, 0x80, 0x05, 0x35, 0x80, 0x05, 0x36, 0x80, 0x05, 0x37, 0x80, 0x05, 0x38, 0x80, 0x05, 0x39, 0x80, \ + 0x05, 0x3a, 0x80, 0x05, 0x3b, 0x80, 0x05, 0x3c, 0x80, 0x05, 0x3d, 0x80, 0x05, 0x3e, 0x80, 0x05, 0x3f, 0x80, 0x05, \ + 0x40, 0x80, 0x05, 0x41, 0x80, 0x05, 0x42, 0x80, 0x05, 0x43, 0x80, 0x05, 0x44, 0x80, 0x05, 0x45, 0x80, 0x05, 0x46, \ + 0x80, 0x05, 0x47, 0x80, 0x05, 0x48, 0x80, 0x05, 0x49, 0x80, 0x05, 0x4a, 0x80, 0x05, 0x4b, 0x80, 0x05, 0x4c, 0x80, \ + 0x05, 0x4d, 0x80, 0x05, 0x4e, 0x80, 0x05, 0x4f, 0x80, 0x05, 0x50, 0x80, 0x05, 0x51, 0x80, 0x05, 0x52, 0x80, 0x05, \ + 0x53, 0x80, 0x05, 0x54, 0x80, 0x05, 0x55, 0x80, 0x05, 0x56, 0x80, 0x05, 0x57, 0x80, 0x05, 0x58, 0x80, 0x05, 0x59, \ + 0x80, 0x05, 0x5a, 0x80, 0x05, 0x5b, 0x80, 0x05, 0x5c, 0x80, 0x05, 0x5d, 0x80, 0x05, 0x5e, 0x80, 0x05, 0x5f, 0x80, \ + 0x05, 0x60, 0x80, 0x05, 0x61, 0x80, 0x05, 0x62, 0x80, 0x05, 0x63, 0x80, 0x18, 0x24, 0x03, 0x16, 0x2c, 0x04, 0x13, \ + 0x5a, 0x49, 0x47, 0x32, 0x30, 0x31, 0x34, 0x32, 0x5a, 0x42, 0x33, 0x33, 0x30, 0x30, 0x30, 0x33, 0x2d, 0x32, 0x34, \ + 0x24, 0x05, 0x00, 0x24, 0x06, 0x00, 0x25, 0x07, 0x94, 0x26, 0x24, 0x08, 0x00, 0x18, 0x31, 0x7d, 0x30, 0x7b, 0x02, \ + 0x01, 0x03, 0x80, 0x14, 0x62, 0xfa, 0x82, 0x33, 0x59, 0xac, 0xfa, 0xa9, 0x96, 0x3e, 0x1c, 0xfa, 0x14, 0x0a, 0xdd, \ + 0xf5, 0x04, 0xf3, 0x71, 0x60, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x30, \ + 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x04, 0x47, 0x30, 0x45, 0x02, 0x20, 0x24, 0xe5, \ + 0xd1, 0xf4, 0x7a, 0x7d, 0x7b, 0x0d, 0x20, 0x6a, 0x26, 0xef, 0x69, 0x9b, 0x7c, 0x97, 0x57, 0xb7, 0x2d, 0x46, 0x90, \ + 0x89, 0xde, 0x31, 0x92, 0xe6, 0x78, 0xc7, 0x45, 0xe7, 0xf6, 0x0c, 0x02, 0x21, 0x00, 0xf8, 0xaa, 0x2f, 0xa7, 0x11, \ + 0xfc, 0xb7, 0x9b, 0x97, 0xe3, 0x97, 0xce, 0xda, 0x66, 0x7b, 0xae, 0x46, 0x4e, 0x2b, 0xd3, 0xff, 0xdf, 0xc3, 0xcc, \ + 0xed, 0x7a, 0xa8, 0xca, 0x5f, 0x4c, 0x1a, 0x7c \ + } +#endif + +/** + * CHIP_DEVICE_CONFIG_ENABLE_CHIP_TIME_SERVICE_TIME_SYNC + * + * Enables synchronizing the device's real time clock with a remote CHIP Time service + * using the CHIP Time Sync protocol. + */ +// #define CHIP_DEVICE_CONFIG_ENABLE_CHIP_TIME_SERVICE_TIME_SYNC 1 + +/** + * CHIP_CONFIG_MAX_BINDINGS + * + * Maximum number of simultaneously active bindings per ChipExchangeManager + * 1 (Time Sync) + 2 (Two 1-way subscriptions) + 1 (Software Update) = 4 + * in the worst case. Keeping another 4 as buffer. + */ +#define CHIP_CONFIG_MAX_BINDINGS 6 + +/** + * CHIP_CONFIG_EVENT_LOGGING_WDM_OFFLOAD + * + * Select the ability to offload event logs to any interested subscribers using WDM. + */ +#define CHIP_CONFIG_EVENT_LOGGING_WDM_OFFLOAD 1 + +/** + * CHIP_CONFIG_EVENT_LOGGING_UTC_TIMESTAMPS + * + * Enable recording UTC timestamps. + */ +#define CHIP_CONFIG_EVENT_LOGGING_UTC_TIMESTAMPS 1 + +/** + * CHIP_DEVICE_CONFIG_EVENT_LOGGING_DEBUG_BUFFER_SIZE + * + * A size, in bytes, of the individual debug event logging buffer. + */ +#define CHIP_DEVICE_CONFIG_EVENT_LOGGING_DEBUG_BUFFER_SIZE (512) + +/** + * CHIP_CONFIG_EVENT_LOGGING_DEFAULT_IMPORTANCE + * + * For a development build, set the default importance of events to be logged as Debug. + * Since debug is the lowest importance level, this means all standard, critical, info and + * debug importance level vi events get logged. + */ +#if BUILD_RELEASE +#define CHIP_CONFIG_EVENT_LOGGING_DEFAULT_IMPORTANCE chip::Profiles::DataManagement::Production +#else +#define CHIP_CONFIG_EVENT_LOGGING_DEFAULT_IMPORTANCE chip::Profiles::DataManagement::Debug +#endif // BUILD_RELEASE + +/* Increasing the retransmission interval of the MRP messages after subsequent failures */ +#ifndef CHIP_CONFIG_MRP_LOCAL_ACTIVE_RETRY_INTERVAL +#define CHIP_CONFIG_MRP_LOCAL_ACTIVE_RETRY_INTERVAL (2000_ms32) +#endif diff --git a/examples/laundry-washer-app/nxp/rt/rt1170/third_party/connectedhomeip b/examples/laundry-washer-app/nxp/rt/rt1170/third_party/connectedhomeip new file mode 120000 index 00000000000000..305f2077ffe860 --- /dev/null +++ b/examples/laundry-washer-app/nxp/rt/rt1170/third_party/connectedhomeip @@ -0,0 +1 @@ +../../../../../.. \ No newline at end of file diff --git a/examples/platform/nxp/rt/rt1060/doc/images/MIMXRT1060-EVKB-TOP.png b/examples/platform/nxp/rt/rt1060/doc/images/MIMXRT1060-EVKB-TOP.png new file mode 100644 index 0000000000000000000000000000000000000000..1e9fbff94c977d02c5bf7ab0a501d9f6de17aa4a GIT binary patch literal 314604 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 z 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 nQeodEYD1{;nisXQ=03 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 literal 0 HcmV?d00001 diff --git a/examples/platform/nxp/rt/rt1060/doc/images/debug1.png b/examples/platform/nxp/rt/rt1060/doc/images/debug1.png new file mode 100644 index 0000000000000000000000000000000000000000..b5a9ee59f3a5eb1ebe2252623518e5b326283f86 GIT binary patch literal 50913 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 literal 0 HcmV?d00001 diff --git a/examples/platform/nxp/rt/rt1060/doc/images/gdbdebugger.png b/examples/platform/nxp/rt/rt1060/doc/images/gdbdebugger.png new file mode 100644 index 0000000000000000000000000000000000000000..ace1ff8c9bc910b967e0fe7e2dafe1cbf6a86044 GIT binary patch literal 131147 zcmb5VbySqw7cdMGih!UXol=5yH!3Ak0*Z7u4Ba&X0@9sBNQ-oL!wfJCL&MN8q;xmD z=)L!M@A}ra-nHKI$204h=hWV3_uePugOV)nW3tC6C@8pc@1#^wP|ycaP##P@!o2_I z>qP73{SUg+Te**q?wj``lW!;}G$?XXZ$7%GZO^%RYmeW658y4SwasqN%=cQRKqw4f z#k$x5DS2%piNn%6_ks_-`x0KSP^5u`E6luA)mjNSum`}XsQ39(SKX~Ry$CYP4*_w00T@Yey?RSlb>6koS#S(X!-}Z z`^RCPX?TYN1qCFFjx4V__v>X4=CcqfFb|wtYj(5I*3-jGl57AuJ!thAAO<_KlAgPie!QW6ky{L3lWuC=h3N|H7GsJl*_|J!!xil`u zbQe<^q%L2Lg4#di(`r$R@mw$It(`E)%JDn@rlD8dPZ$roMDYAMMO!LG=X>fm=fFwF z5!jxQB8hZ?lHfqh?+T&J2V9H_COa5W|6;C32}w zT%z_pNm!czrbi`1x#Es_s*7p!$Nz2I#Js7Jw;$``AUyI!I|%wd`{TLJ?oary(^ivO zp)bEFpwwt}$h^~#!VO%wtzBBi{u{wwm7|Z5q`_w7!a@>*eHb&hjU@-Z+)idP50yv+ zN@tXRcdGoOSX95C%yry%Hq^SpWm|vU7JswB z-^x>wz*N>2+9Ynfu=}=tuICBiP>wRzV83*62w-2zLNsaaR9=ZA1+HJ#nkY*w(o`Jv zdyy;V15$RDP{8$f(*Q*0S({?Um6k*J+4Rkr$c)~RjeK(ox>3x#+!>{pzqc*eBv5d3 z$6akn2vX^%nY5S2*=1hzS2M+`KIdAzE7xNDB7;4TjIW&)p5&=XMbd zZ~N3K;}d>YouMKRG=Gr^43 zEik{Vc38XJXzRFLs9i6e2`RArTt-YjPYwC@ZF{$tFcQG_afYfE<6&SdxrBv|(VnQ{ zylESHS=5I7-2)oIO;$&aD~zQp+i4sAY1%A$w@GuCnKOJ0^WQj#%hj-7=+U`^uSU-W zR6u}nd%&%io>4c#64%qt?2S(RSSZR^S7}}h#F>tdB;{?Ui_8zE1AxoB>qH|JO9E6y z-{^qnG!XTV(a-f^<{a}7>bpa3DAHh+5^k5-kb$=2kzV!P1`OQevX!WcuPrEBi`Q4A z!&+oBZ*yW_En=eRE~ldXRyX{iDjWlT69S^nNZN%56+d`#w~Hs(0K_LKT;80qLk^!2 z4=;ZGLBgBZ;oZqXTpmU$aq^g5eCI<@(#3{`7)XGs71WfOCOL(Y@g~jl=2Mzrwt%Vh z#R@vk4xf|zmW113K>;y7*Ozp8y;2NUaoM|N=}633zNo{ULS>%a^D_G(1LE})FAtZ5 zs`0INX53V+c8t0nqy;+yv3@O~SRTu~93E-p>^>+9lR)Sv2yS-vOLDvHz=SG2D8B&0SV5NepwA9Wmn;XXl5URFBxxPF;Y|MEF71rAMX}(q2(Bz z@tC8V+}adY`T2a*rS3o}Y+2}@pv2xZ2uN4B9WkU-Oj4n~3pW4a@N7l*RKD|UuA2Sb z%!i7}yxDbC(00aj{o}!Vxnok`B%;oP90pw|uG-s56cM*X-9DzNpZZ>&LUYORj9JoGB)0CFAKg85B!5V-r{OeYJ zMMY?VJxrNn`MXVU?XSGz(7+!rPY4zi&DcWkW$nasAEmd?y>_0m{$Ui9r6yoAVg!c! z+zYpc)Q5Ij7@){-&no)Sf==cGbY|`B#krq*JK3)u>x`sa2b)%XI>D0gzJhY#%c`mwu}Gvpv)DnZR>s}%$9%nW zTw8Y|q0GARF9mKu&nwnLvYW}W>j%dd+3U4so@ z0v!1Tr;67?_RcrG*}e&$2nZVaK)2nL0E+X>N8s~7&2>51uUWjwoL z#AQPZS}@m;`4T^{9XhJT>CU}Tp(%g_$b0d41c#d>FLVMjz<2W+0cgeUOVVby3%3-h zJn=C;V$Buyam0DQl6mT$xMjAk5EC!@4VZ-h&Rk47qZNb=k{sGsCy!cq7*%6T%i3(2 zK-;Vat1+bgB5n7u&z7LuL4AMZjivR-T%O(a#nc#$u{C;< z$|LC$dGQ%fNoFND4|;Ks2#BR$B+adW|_5Gwg2jW@E_C@y6pSc19e;bbBaRB^+e` z%MEU3^TpZIVj^SG4BHFcW+(?D2#3 zym=&&RYL*KSbdi~)`S*WON>H{%e@27t@Kwr+U8+mZVRv*JPBAF-21ie=PkSv3Yj$S zz^8ilGiz1frvu%wVNZ#-Gr}o8jjR$=m?K^!ieNS^zK+Zs3)_AzZrX#;PLso2oM?l9 zs*ohFde5Q09d41-@_X47Z-u0f$z1Uvl){g!mu%LUa9lf3DS%Q!de_G(-mJ)GB1YAo z=GD0-JTsZem=1SmSpJX7*l65A|Mhc-F~|O)JaxHft2ippf$Ix7G*=ufc$c9a> z$i9_lvsM|mU1AiTkhlTkmXrL~DnHU9gFURw8qqmlI}v7U{a zAC~a)KTyQ-r-UE1VDFg>=9i4OjIkLbDK9_W9ww<_jek;`+$}Kr@=)Px>MyYEjS=fT z8EsK|FZ$`93sKuWan#X!&^CUd?~WXCJPI`6zXMnu*93>O-fqaidm?&rV1BkcalUd) z_oL=mWsZLFRZHozmQlAcNy{ERUTZny1-2}a>zv=nY7*{=j#cjuvMsDkw~4|Bo|okM zU#wgZjB#W@QgbCJk8`b3Zsu`_CaPl}6RE@|WE&1Qi5?ccYS_(U*hGnZG-`V%-Ujr< zEb1f@VhB8sgB5G-W9`8T(=I%=f`znIjg`=NqSXPIGe{JO%tg0#NyCPsY2Z9TD%n zR*&wwpF4-4H` zZ|6y7&pX)PRBU&_9;?KHmf9A7conP6nl>m`HeF9j4 zi$?6%&}%que5>eb{MK(Tb94GR17+IBa)66MrWLOJXCHMi#9Zr0|1Uz{GkETJ9CZsD zH#X+wmo9gde>r&Y24XIH)!8}6WHYT+D*4-1!M+`dhFL+nCPR(4k^r`EIyJ6KXnWO4 z=9;9O*#0s{-OAr~PY#%B%1f|>LiZW9HBN`UM12-?MQfb}LP3A;<$^-F7TvvI4ni8} z@Z<>tGs2_}h6!1lbES^reQ5E1r}@3fUjpl%Z0_~87SV@YC+5?9x?&lKk>bdFmR7-k zJ~xS>jWGhO;`FZ@YKnf#@jvYyF=5)hb^TX!e)Hcb#sB+<<`k-_vDs#xE80IBx_=zz z8KE-9p+)p7H?`6IyU$)*s2pipJnd?}d;~+R8OS^l z5aK#c`1i^&;cP#(JH~)IT_dSh6ihYpm*us#n!LNQ@A4(9YJdyFnr7sxzv=0(MtaeO zede@%leEmJmV8RcrdUEBH%L4koNN4zVZ<+mYmrP+bSd^-X^C(fph^x)RW|gi{X5kz19(aL0QjC43Udb5JrD+Yr6%R z*5y_MO|bIdyXm;9D%CyxW7zzKE)*-RU&(4MU*aItH3%ovvdpNY!Mw%>_M5XWQ6Fp{ z0f(Xhnu3w?EaPI9iTBXN?V4q!aBV``z763JruEq(aoIU4%2~tcc8ll6(-Ae#j_U80 zyGTBgby{m`FeEwMtTJdM2D$M6qjyk^tL^m z>iVJ867L`(6i80hMv2k}mseNE*KZF7Xy@t>S4EtFwTzZr&UDcZa^)tuW}LHAxVqy& z60JNg*7jy(`A!RG1&$m087t-(j}neeR}9UMy4sWr3PqHwpW~&++-5rLA)+aEE zmE+4kww0W`D%5>XG4yNSW<5M28>e!Y75%nBu|2W(tcmn7&P}YxZTuf*LRJSF#{hhT zs`6Be;a#mAapURQ(OTlygOAr*Tl^cGumw-8uNM-6 zw4d7@4H+*Ka4ZV1JN8lIPKo>LzvE~$R$w~Z!cej0H@JE*H}QA;2_dcwb5E$8^>z%% zVxu}*DB4{)*yK1kOgsA~f_1tn@fc;Mw%mpT%%`Egw%)u{C~{uyiW=bKWBJ35v5p3> zZ2^zGdWq~EecSh%6wpRKsrjq=qoSmINgidOQrix0Vx0?qR8ZmVF{y2X#RH6X8Tl&T z!$)l*UJt}1eP!l3dFB+1n3d<;`5)r2(n6_e${bmlbdT_{jjZ9Ly`z&GO{deh8LF(vr7&S?0Qs~^F3z8CB32e zOJZ;PB#xCW7N*!8OdUfmX0-A4XA3yE>paEF20YS}%-aT`RrdS6JBE(Ncwt4pY&lD3pRU&2Z91%y-G=creVD z0!wXQe} zc3fGxvAEnf&A6BoQqYcFu3{R@@#l0}a0gl4p)*o6a3Cnzeq6bi(6iD#Etu&UH ztfI+l7=+al^YKGYhu5^6@v3%=J9bToI=yx`9gsnGKqQ=M^-d|hhw=nlV+qFi)OI=U zPN(N{u=4U~X86~VQ{b|U+?s5gP$mZ2nXyJnlBK-($}O~YFj2>2RlgnGXnPeOBe38SH zuNR>7ED`V~S}T-N$9{M3e2C3xj7v>$%GLytmLhsJtDxoU@qj_QMfH!6j%kr)B}EoS zWg1Rr6)dFH_lBkHHUhinzPd?2KD>l(O?hkT=ETCjkE zwcIQIO?ZBv$@JZcv5E3|VG4*7TrF;pe?AhGe*9Y2Y-gZx7zYClVRkt8N}-=b?e4rG zzq%?ac%j0RDO_GaccGYk0G|_|S9Y#qOc0#hC=2Ij0G+nTXCCpGWeDiw=4Fc9?kx=> z1$CVm;{f2 zxI;n1N^54ac1Fvj=w$~qzlF~5*Dq}aMVA0g-5C=y5M6#Dn_+6F+~`xqOtYm z#E?gkom_F#IA4LCbt-|GqS~c;Qy)NDF)W48O-@FW#GtWdLoI(x<0|cja&Ti6bz~+f zNa8j*5M^L#-T3C(J13{;{CJck-1W!hq^ZtD5#&7AHm;DTre^FxPMv-0!1TiDuMd(+ zVwpE@+xM5^4@CJsI`(78#$tz4Xky)^m zn7)V4)VDB#A=Gfc!mV{A0NT(LJFtJVpbm<%ymAFHHjMy~&a+P`Vt@k5Yz=W;hkJRs z3-;h0Affr~LX8f$!Bv_5UuLiyFYx49M#cr15{sOR6Ifcw`tn`>V&h{+!3Z6$P4FRCw_{Qee&Zot!N#@+#8cZQC$~s5>=E zr6i(T%z=VQnmeU4AOccly_MhwM+D=UlkAhq&3mk}85Jl_TlpP^hDH#hq}GTqYDfxR zOskRB%Ap82zvR4GSGd^)YP@+GtaGBqF7d;ELtenK&&P>2;l+v2I`qfQ&W8`trSm~> zS>aUX{Cf8|C$hMVPxTQua2RZ-dA$RP_zqK;t|%T9_M8A4nh|R^leS0e8~Tn#Tcy0e!;v88gxK~WDVM->jrKGMdT^3&nPzC?G>1BY`L6w^y8H^!&C(B9OeMQn-YXRHL%@z>J+6%A)r*|7b1#noZvt zb+PJu`O&jPcD-;^tqhM)fu=05!F=l#H~JU1^Q}Gc@3<(ETicq&oY4Y?571EEqaaj; zV2tSn4<2;=`hRKxzOH{pLr>u}?2dFZLQ84An-OLNMQ%oV|6!@I%H+JPGJ6>HZQtE| zdQa%Dhk|{0Qu#bSdS;4$xg6Wfo<#937aFE-xX`ejNc7h1r)hI8Y%HI{y^mQnJv4DB z#Dnw_OylD}j^IbAQtJjd%sdjN!i-nwmgnM&2(ySBV4^5}L8dEbIJAZ|9c@@Y0apAp zmi4?hB?1l<@pZn?_6RLtc*H4fKp5?68GmJ6Y=yTOY zX4I`NcVcNHP_)84(SvlkV~*a=qy*Wr3MR)n3A3Tb8b+{QpR)2RG^_fv+$@D;Z*C^4 z8fr<;Q)GMCuBrMnN3fznIYxKJau9aedeE!L)n%Y)ro42 z1r?m4#Cjh?12#w92#te24jB(9yK`WKH^qXK*fFL(c1MZF z)?LoA-yfogAfw1}%J$EWU9tjc;ObZL)#FTek~n3dbOJ_QC^i-iXQV?HxAohGL~x%&!3E&)`t=Fyp{12|UJjiSZ(_Rxg(|Z^%g-NS zq62bypD8qJ@6-N0$b;<>gxL_FgVY_Heqs?Ks zt*-rJaTeGH2iggO(7Z%g-FH0n?wt8fzn9q~lsVR;X*hSUM6U~u5Cy~o9@|tIKg7ee zf$ryKY`9I!QL}=k=&M;z5@FZTcxJ^k_r6iLrJeGgg2r$G-i+RJ>sQ>{z_V(#K>;fF zRPsn_nHYFh7g?w2-31$y8~Y%vzyFtLDfw?6jLOitg)?0&IY_g9wqurA7{t(S{JJ z0TlA@57#A**`sb3c~3WY@=C3kDKWZ|oeu!bx6^QeY353=dkc4OF?oB)yz z3k}tG1BFJPcF3E#uRMJByE#&79K~_j6q}nC>BKd7;~K`XI2T;4Zq&IGYSJ1gA) z_GU3l`58@~R-eenpR@FjazOAf}Q zqef#sm0i1hy$fzB(%8AjVy$LkROhp#iVD9_!y8flVoUkqf|p^9k@UA8d14~@wX#u# z$+kEPjY30Zxvj@l+a=379jA>c(`w*^tsY|-Q?(Htoel#ssN>TV{l!GVV+# ziZ5GaM#E30wLl~SRt7T0HP&^E=anf(n08~qf@`}oXW#5CHd~k+7Jc+i$t9wj&yB?0 zt@%%04?74PlmM_4|9`+@X6jkaXOL1m`T96a(B?dADlv0;TW5M%aqMeR1pwsA^rqdF zc|Y-4L{qUwBO$~e70s*SXJJAsLm&l@=L3e07r(Spzcu2r+G>1lb79!YK#9PuDJ~7+ zEH+|g8>aUOWjQxNi0*pa76+pfZ~d-evwVPWOOlVt)Lu13 z`N>voUaHqu6#=e=>Z6f7A6FOUM(NFNq+qV-Kw6#N;%XFGFEw9C*}^4vruc=6r=7f{ z*HryBTjS0R@n3$_+(dAgxdVJF%6@%8;e1QxN|& zFYer+&+2him}OMArDdH3;7BD=;+ts%?#I)j`xM;!!v}gY>WTP@^c4|!0tu4R9W0l2Bv3>91`!~Z+gZiVe}HOdY3PsJJTCea9dDQ-7W&t9IsXfH2900)}~HN zTzOx!V8}u6#q0o630riD}ST~S|?VOy9(tA z1?o7iq)>3V18+|U(VCk!Fl2Cc;8|!)MhX~L>XC*jM+L<;DYBCFxKJ3_-2dbF021c$ zO3=VU2$vD3?`2+I520z`4_1ozch|Hl4#~~8+nWz~~X?Kk_Q`@jMB`;()wv^5XD=uLlcUBZ8l+VM7v~Dj3`rdF4 z!XVvpxk*;LJgy&Pj5kni`&ZgQw*CLcg%Lfsx5L1Or5y=VL za*)se7eL=Oyge9Tr6O|1s zMCTTfJ+zjiL~fe8b!lrFxI2^)E9>Z3=PlhOgmf%U9zfe<|Ki7oP6YM*$1nStQr-`d z0lHk`iYGB4@hQ2ME(F?J9)HxLEU%E}rQ2w$gzQZMcsUd1@-itF-a zO1r$$7%TT5nSJo!O)!mzyRO9OTB}kgpn#Sl-~0^~E_?WvE~*|i8ualut*3gI_FRx~ zQGW*9BL|&eQa-+9rZCJ65 zh6O7$D2#C=SuVLuw+)X6IFKotWmVs6Q=5w&Q^_9C6Ub#;tOy-GK6(^bnZj8w;q$6r z&~WA5`y=c})A;-DSW{Sx5wDgKnKF&q`qh%_@fKA|cL2D~QpQsgj%(v=Mjl5jIuP2`Mg>w|^b>&MG23RJ6OTS!qP<-H0DD^nh}k1I*`bMaw)c&p1tml_j8Qrw&7OFskS*H=Hp zt`=~LgmoGy$J#P9_{CH^6E1p6vfA2YRsTpnK$90VaOP_BTzq<-<-*|UuETkm6gE#hu#J_k;v%x4JaCkJpoCx?@d+k)OjbC8`%>Rav4+U1zx@D zN3OP`#tFK028OeUeCc|qVAemBL#nDL=i&NoB2qBxLui03vHguCa5Xo}e5uZxRih%* zLUh1?T1HExGk)#iHxbHe0gf&QF~QQzv}V6^pAv5!G4e^dB|&yysB&*6%*Re*u;^&M zC;8Z>N|!SI-_!^KO*2uN2A@VGK5$`AdGCG7dsKrNqQERsEs<%G=^W}(E{*n~P@@OF z)TmJr@KcAghf!+ry4{eXMEv9U!|6`bmEglZ*ee5PQ)Ndd9Ag>6!*$}!Wta(v_h3wrRaX(i3D)Wf3G1a^J;q%kTAO4w^lN%B`EW9#DLFFH%)i0I9qmo~bRqIS3GtUv zbzf+SI#avvIf9yMs>xd|P*t3jdUF+Jc;}0>h$5Npe45Xu_lA??1=CDEJxAxr+I_Io zXzj{i@hp(??Uxp<(hNuDni*^{RSz<*7}2o{88| zf+0z3*C9a@Pb!;(OpGvwlNAjOg%T$jXP1gWfVBq`m@Y8JQ_?Q+8?Z5ge<9Nmmxv#; zw;x6~{}k2u9Rq$HX?_@CPJUcDbyFvn{>3CymqzBzr5SK^#;GTAictaGWi~v5w5fZNg1Qo0`)On<;eAU;stlnjlL{yPV>&yw;qcB(s5~ zF|0e;cDvpu&kc2wzHq#$Z%Mu6ledrP(AB;M&M~6oAC(&FQu3e$9j{^N0a1Xik7hvg z%)G0D2C5=}@c+oDzz2E~dNW`=j}I3(dKKGsuEC{2bDeVZ;xn{!3vUq{vqDs_eX)^U#JURQKm49`!6*L` z#%81kGqRak>mG(gJ4%iT1X`-S^r|*n@2G5u!gEtC_4Qcja=jvLX?&r=jel z56q$|CFog~d6!4=Q@xn+)rRS7YCI0_OMao-VVqJDc?Sn-;m)vwtDCVBy)V}O$7~xX z7wNM!cvTZOmWEf??l-zDY>^Z$GXT=sy za=FK%irMDT#;6h$+?E-W@#MXB&qAhd~x&mtaLT5i#-kzK|=A0Z%W)xI3gYqxO@I>bz?_jVHmS&^b!g zjjN|vhthcS=QwXIUuAw_#@Z)Dj{U_7aDVbue1olj2g_}uha?LLFoYMblD0=lQ zOv>IIGjDfv1TZ>Yw(85l=PPYGhoAiFGF(=oRm5c<)(C&?N>#cwlvDpjsyamT6ShMd zx(0uw^~(X*kRH0~8vfCV`Tk$yMc;bp7MXK%Q7W%@ME6hC!gt*;1u}1N8nSML9L`m~ zBn&ohA8%KrKmP*Y`0qh@EqKQ-&pv2%=-wnj(;ygq|S^!t`I?b*7Zd3&u_9Tff=O!pVP^R4bQ}l#=_y^Y~eI{vOu-3hmzLXs7 z&i%%gMtVeUXu28)B6ojb<-Mv>>{n2jsaG%71vnI^-*SVDuf4nezC(6J~TGfIe99EkvR#$2u}OzFqt%d z=5BLJE|}P#{g~?ZTo@nUN=ubTc53W8%;q(CbilHTq4G5 z%KtMJ5JnY(pX3u`w_uDS0-$Dpod<6uNU*Eqcvl*OOh%S2AwW3Ot2NbF?OvBS_AFUj zX4`&KMQt?d;^aP1n1q4c==%q^j}{GLx+{(9ZA0C;-_7>DNI7&G`*MFDV$m;rlgs(0 zxN`9Oz^Qw=$W~fOiHjLxlLi;s*}1DQ#IMnBIbx`O*^1bxZ~^9LPKU>Bd@rd9@c}>S zx0wA8tzl?sbynBOlmo&HT%)(sY`j}xMeYskf`x=7F`NsxXYh@8QVtPNR3C`LNN>)| zLH2eRU7bk=iiq-R%jfbS^=C>_BOM9Wy{8X1^~Zu$RwYLWz^qM2@WI6aE%Ip1E%Was zbDBNG*MbN#6J5u-`{&N=!f$eSsnr+5+?GA`@o?z?4IlnP@({Gwn-B%01 zOgckm2Mn&9T$=By%VcA!3L`qPO>R2bD2QA3sP%qO#08F@>8|J+aHMhicxAI;Cf7^)#b)=OYWLl z_q)YVUxm3nbgj-E){-(tC^?NlbQc}sl~y0%aG_ZEdhk)Lb9n5vJCj zq|V7p{l|o?B(Nc&*GvqY+`@qF2pbw9jR7-g_30@|J?E`-eSQ5e(r`xcEwfq6(2@DX zmZi8e6X~N5!UIk7Bui>s;1g^!3YjLzeVc$rv!>X8^{`kP!iG`PGd~ehD^U1uqQ;q& zn;h!QZ|1i}#uCQz!`d!8yBx>31TbkM>I4Y5nrK9rS?_6YbqYc&CortR&X^WW?ijgN z|Hc!fC)f(N$24PsMP*gOZVlA{P-Cr3>a@0p^{s5NZHfFO>(SKa%=A@lda0qAo&7?U ztK^p&xXW(2r8fCaw&hM|<9|!qDj&|+kEk~iAx`4;5CN3*tcIzD_`HON0< zOT+min`77}_)4iQP*3`~LHmvlo)zh6gN>7q<((q-*{J5#fDP{?tlwaGgINAw6-hPd z>{L>I=X?6>Dluw#KZAht{;ZK5L4)nA>8YCO9U7l4r)0bUT3Z1%9OVB|ZQot0V2!lA zGu0tH!HQ;g*DBR@fv91{Y528}xC{rg61IIjZKW>$jF3~)JhFd1hvXW~v3zn==cIe- zz!Lht0>BaCp61RPwACoGq|lW3pQD5|dK!ro47Ki5^fC9+B~zk9JLQB0L(uhqZ5q$~ zTPN8|)ji}RPb0zMdUWA!vikKAI@&!G%Ei3TbG^>hfAQ1dpL)VdrcJP%zP5G$`kA37 zQJ>T^&iX>aT7a>p7g*=7n$SPA>GjQaUeu|Gwf+7gr6y6~M;2W*7@tP1p*b7D&5M8i z;TRY|@{zfhsK&%ymD|FS%12$4U|!+%E(>1q?X|xr=%$m*8D8Aj_*PKBG%+!OSFHCNrf#}+ z15W$H6**Bcv4fM7p8Hgdp@7`qL#RlF(<8|RZ0#?PEq{J03JUBAz_RQsNxjG1qk8Af zXH-;F?j9a;LkfTQ-!(Qh4XmpZxc^_L)%(J4{HoV9tw(x~f!&iMa<@aU@nMpuPl227 zo7cVHj1ppEe{@Yx#2yV-=!8Z}ntymFH?9I!3M;B&8)s?ARxb*jn?TMKtO_X_8!F~~ z7q{5a3DbqQ#K)T$odF=NT8hOwvyKV^-H=%OZImZ(T*_Y}KW4i~yl>S%6$s7#{_-(6 zJX5ocJVHosbn8UHJ!h}Ww)PzFH&!Mm&kO}5|AEoc*48%4ZE<@s-{C@ukW1@-1vCHw~H5W8%+kcK@nQU5%2Rb34e}xR%rND zS6e3uoekfWS68fqEB6kyL67rJb%0*@x!n`M45`3e?r|bv|wDK7f^$87=Z4Zq*A% zc-kWGjxOf-Nfpzk_~Wb$%Thl;d zNw&+IK6M;N)3FtkrO%t#|HlfV-gvb3`ER&Zy>FHe^dJ4C^tVO?B|8haH@bP+?@amO zo`XmQ)d-*GU;R=oS{zz~|Cn3RL{VrYvHE(9{+wb~IG`Z4MLk#87EPm)Pp%##a-wYid?tt|J_j~SU#cRo)N!Mm2xzQZ%m&wo62K4Hd-|@E(CSaH|4PJ_ip*fs?iIgs-YraskxxC_3B$tr(C`+p= zHVbVagB6wlM+@YuUQGTE7vE%|Xn1L)gnXf~M=s`PjoZ`51Xyl^BaKLuTP-o-hr|-1 z*IFRmBqLQPVE7>Vn9YH(*XTJ6eDZ^kfNPS#-hM2* zMzL+Ke+Cj57qi~*U0D97cu2ekZbGw`aUPf5)JJKRoMeS#oU#x(E(hDY!FvRJ?ItXh zf$WcWi(3@il=pn);!4bEYR&V7R!En^k1pP%WuEhs+WDCAs;#(t6hT=6 ze!#$no6a8bN}z06Xc@O^qA0g|dpxIopsEvn$`PsA%F5RHv+7_^@+*I-oJZNA&{~5F zTPhvsE=%6s=lYdb>ZgB|0Tm_Qs=6Z5$I^g^?0M;@)TQmwcZS7I#se2 zzf=i7Mbe~aCzlWX_%Y+j>vfwPB>{Wk5QeUd; z%Bin!)ZDj0_qwP0+hUTF?N2^B9CJA8g2TTfLr;R4jm;yX0$H?a6uDA3$s%4d60H7; z#QZK=ZawE^RssUNrb(F3=)J(QLoVr1k(aO${V3d6z84U0@6Ug@HTuT(f6-0I2pr0c3E^;zii7 zZ3<01*r{7s6H&gqz1du71I9p!mfL7k6X@tPcF#zmL7#zB5gz_JOY2-^mHhUPk1&aD z>goRojc(*_7W&{Wp4lcLfyqix0`oe&@2GA_c*RFV$B>!vlR6mT=Cp3VH32KOG>ib@ zPnZ#kOaNtigx4N!*c7wwADnf+&3Uoosx`6oIc~6OZ5#7gh9GfTBsUL{#joigB9!o) z$=6h)<;|3KVqd{ZT6q3(cvUGN<84GJPm_Qd#)z{pnx(K$ZRP=1pSN)7Lm6qn=_TS* znIGJX+Wt1(pF!i?%u+M2^j*LO{&ByyheyVyZk70h!-{polD_Y z%v_$7a2wtVG(TU3EWDGK>-q80*>VO&A~X9T48`;07e=)CzJkBma@#t7T)<34{mHW@ z%9cU-?H9&Em4;$h)qQy10e32WkmS2ddvUFnDC`O{ohxtX=3b+rTJc-EO0RMF^~}{= zcpHIG6M#TPiOqsw<-;{U_8%@hpf>lF>QTUy4j4A+KgoQL>pJ-9hiVpFjdk<- z_m?+o-guRI8*T##tqDQfypiJW$<2IDWo((okj`w*#fspwesp`?P zBC%cDc_W#7mnTM7X-%yUXUlhupv_hQ``w%ElrBZ0D+w1E|8E0tf=snbI-4#9W3FIX zhfmX>^M}%*qOaFVSKdS#pvk(?6C>HnyOt+?_`VCFX}eF#2n`_?8E|V2^aLThbg+px z^nNiN*HZ?MRYZSRXb)IXDslD9oUXVKi3v}MD@uCifeB`!w3#{B#pbw3SvUIUV#7L+ z`ngIQ(KXYg*5HZ|CRW%QzYfM)rP#o9_0&Ic%p0vWn0OcB_RIA}V}L^wW-_k!Gz)tM z%0j3eNXTfFTNh!`jvf$d@sM_N*xdgO}X;opSXPf`{mzas}ZP3->NV1}bD z?2_`kQSr&Dmy-NFGz4`C2fUW&MK9j)Q&zM!&;#HMJh)$INm0qaNl3cHcHp%e8X7XN zdO2S8B|ix9JLZkEGn%Yw*$GvB+ppjC#rAU57S@8C+U8lEyVSoHZ&)x~-&rZf6`^$} z#aM&>KAP{nY7BvSQcJ3dT`n+X2pscbOC4m66B#EmW{810lBz*oyp!vnGee-MD>9wX zt|NS5mRtTn9+Ku@s#MzhYQ3hx9PHGQn=`7n{#m|r{@;fF?i#PLbqafkGDrj28(7DN zS7q@#-)|wRsj1aAG?e~~XOBt*WsYyg_H<-S@ip%GZpQJ*LqK`+WsD7hKqNJ7H}iQx}~nsRlsC&g3j zuKk^ESy?uJJ$~bj%zwUCpr65|ZBtc;ux5MKD&oXdrXj#*W36RCx4-slIJqJGNFP^F z4!~W_W6Is>eJfEqi}+=#^7|a3Te+vD5H6wS9vFtWcgxs*{q$->$1^?s6|&X@e%ZP` zN8i&zFIwR0Gk9NyWy2*b%jv2}B^;f%547;N|GY6v(D9tWdljAMm_J-~^8V*Ii$?2k z_3H+m-}~J>Ak$JY9lP(XUI?~B#9O}r*f9# zaE#59zA?Lgav+1v z=$yuMRQ>m+XmFCupgM11I;l}((eq1(wu=iDIgb=8_`~Sq;dNP%a}baHnn0(KUSsK^ z{Cgf-y(AN8#FWT2Aza>}4C>M1g39Jc5q=E5p+50*4evCA3V_|d3Ms6Oq@?rMidIbT z6f39Sy1UHi)rEZ>Y24acaycbCOX}L%2Zd_f2X2iwr_YN(s+w&S%r%J7me84*&& zJIRCgZF9Kd=tf$BzLqoj^$wx{QD=P4VVsHD?=qD_u8d2!YsSaN^f@BMsU{uFIVOAt z_vbA9FQd%6ryu3PJbB1Dhpl3ka1VwW7#Fu0sP0 z{o}}^57w|J-$MvZ4Sy|4qCmjWJI<5{j_L}^k|mnTM{7VH*>!0j#`_qrjqp`r0xsaf zQw!=iFpxbkp-k$6)1(TyGooWirCIWhHG6pILU-$7{oOA!2~H-WXdk@>C+4eUjUm)J|6YN;nP~u|0^xZ z)sJ@@%or{j@qSK~RdsZC>YHbUrl#LiRE1b3R1~E|*zNRGN zgYK0g&7sUrPDQkW=6dkuR&-{yTa%ru5A?KKVVHw?<5Z38XAey@BWCpJXjEvWV(6jNKP;JBZe{VtS9!d1vq3>n z-gbYWbZ4)T*sW$QLsiimNQk|t4+!8v_FboXa3El5{{l@I^(>I`{#3C-y0|=lA;U*b zDRHZdN!)qbyi>C_Z$=g!cIi`Hih~yVjpi^1aOZ#s+L?wZcNAK&ZqS9>zM^UwJ0rZe>{sLF$nRflx9^KeT)Y^xO< z*E1c;$CB{Yr>K```LqF_DR6csu8M;WogM$FDn&=&2rw%Q z>d3yDz>~_sCu^v!?JxVdX4J@N25|XZdGXm*fjZ!#JFwB*n?78+s>GIj~TTxNnBQLtU=NPa{a?MLf9&h*H|_8n$3|KK;al6pCEaB+plmT6#>eS&)_ia z0ePb*&(W;mzkWSsiGGz~FBB9|8V)2KpJ_26i```1%8Ir{a#~Vm)9-ABpM8pbBcu-1Vs_znqm}pmHn*>9!lA)#UZN|DJL7JaVb*zsNvo40 z=B^(Rs|eI0w1j*%nlbwEXnNNhaA6nCm(8}F+HpU6K`SW|;XZ2(`(iUbc6VoNpAlBF zMy@w-+J?tg_4K2TlI`Ha?CY1gHe+0DIemS!-^%~4|6IMZpJ&k@)N!J)%p0~;Gsnc5 za_D&%SlNA%H>vNpy6_3e;Rw}Ii?hgL(1%tMTx?@cwGhYOiM%#g27dGntCYss=i+nk> z@GB4SWXr?$jc>|gz&&={C;r{oy76zrSF2EgPp?rHDB7seMgi%28Ts_L80X!R{L*#ndX$dKH;Gfx;emF^iMF_Em^; z#>nGLtqBx0!11rK!I_lSn5{(3AoOT$G-BNbMOAPStFc&Vh`>`Ra{%-u-wM-Od#L_J z5(hT9$UO7DNFfc;wfU?!n9{%J7AR`aeUbrC3C(*jC;01_%5IqVhj>Uy;rJYd?_j=| zY-zyI?~RckM_}p%LiH1gTI^e$1Rt7GM)^fJ)sta8c_*DV1d zPUjIGMQBsM^!)GrjQGPTpgjAAtx8^>LtK%(0lV#Ov!I6~bAsl^P6Nz5x|K`H6-<=H zXZx3c#TC<9oD~}!J*RQp*Q;6j#)c~xC{{Un=V4vA%p2R~l4QBiM$xtZ`^cW+uz9k3 z+cbmVcNyxE8*q(u-s(mcyG^%aJdhq>iOcT7Gm&S4-20bbOkp+k4^-3=aL!vfA~Lk1 zL_Dd;tds$1_sV9~Ysz1sbA*oBFZl9j(G7Kac|DxoyyxYtVRMVsol^;P|Mb#U;;5(cls_i%)!SAr-!y?X~@nd90`%ZY&1&FADAH)8{`^|68wX4t;1>2hg?_9 zo~|UMWFwF7wluSUb7LaD&%4UlwLO6I24qHOYh4`&gk2G;`iAL7ONrLn8!Rt2LpxvI zZ;q4pjZ|C_RppdxcOoixXFhJB#;*gyF8S2!JLk5aUM)!C)o5pJLGGP;g{-@Ue<-(| z9cbEoT{G3<^qV`>kCE-GuSE5~&D%ZEN%EY)>-H2m%e%&Yd#X@CALXJ*YG<) ze#FiX{E!w-|JkTukkG-5NHm5(Ct-Xi*{k_2@B&?cHA5ncKz+)R+_6F<2c>H8dbPg5 z^|E0+bF#ASSJ%W2B^#&db(U+6U$h2>kN#Rn*`Wvj+1N{LN@W`qr?9m1@2^*wSQGZ1 zy#AR&=Lq&Uc{~Z5C;@*+!EMv_)^7|-#(@2S{10UgKs9pa+3R(S}5&eouV<{$cGdDqItx?_RvvJ1!*(4x!r-lyY@+|HX4C82uHaUipo22adEn70;gHzb5vO;2 z9Fv*3B4UmDKNVw7*CSUU`?Z!o^A%sw-oEuUz8xw17u-|Z)Kmg5{=i|KjL|f9GaeF3 z_oRQdJ@nm9Lcz49qpK?|2ghX)J;|3XI2=Uro`8Vh{{CL%)Z#yF3jO;b1o^-3;m`NK zLTb@!t(x4ty!e{BT!S>LD)xpbA=Ny;-b*~E>1Y?YgQX3ssFqU2E9L>G1pgD5TTWIQ z)Un11uVSVW#7dFVWYT;?1zXi%!lxZDdG_Efq8I(2=vU}F!DP9?3};(ZrYcNpJ=Dr9 zS8;PQBa(Ue6@3bfkws_g-;q8Jd3>@Q!eQ1copsvoef{(2PZhl4{t^5g)t#-az^p9N z!-QBnw-oN zQ`Xids;;iaZr9o21cN8VT()|GWOlx3imdDr-E2~=j`+@agwa4X9&`HvagmWGlewaj zQc|M7T@uyMvQ4JUkmj1Oiq$&a?Of&8*9{dZGbhx$3Xv1C8}2saJisjR2jp^kKn(fySTD-vYtIZCFV;S5ylDMtTPEJ%JA|fZA8qM|wf)t`Z zzv*QtKUO;y<;iU(Ee)};vHiAN<+I7rWWvX1*7D6iq=uUSSK>SBM{Y~^^R-rnovnoO zd}ND;@42=)-8)pj6_Ufp@|TwzfM{rFh_S3@fYlz#7s-UgU+fyhe0-@lmgIl`!Z4kj ze;^7<{?Ruu0IjuhJMw?Ox=**#07x(#230e_;UJ z3PPErXzkINEm3@Uy6C2K=Z24Cs%D2xdM+-mMTLe~Be9%|`YJHd#L6-Fv}uM2VDxi!D`n-q5;0q&TW(701I#@|Aur(SlDX<5)7O~HO3RmcrBY)`dwa(=ok?3i&o7zv;!u43%9I+zP?Ji2Astp zQrna97&J#6`mXpR6H^p?RO*)!D=^_Dp(UXy(9eo?hot0Sq*Tm(3Q$xWSW8N|(+O&TXCbN$ki#>-A*9do)Z6wRm4(<9d3HGH$k z3kwT#f<1e&8FqYEDrI(WCFOT0Qa@A@SQ4ytIaH#~js8&N^hRkv+tJyXx>owbEKrd> zh}ZMSjzFs)>CjJg`TR;@GVO*$R-l}PO3u!x-+FLJNCSnTT^C+8`RX4S7;^EMq7m>B zjn1u->CvZ(WA)dGvcr_uzRiHGp7{03M!cMt;Qpe=RiqV}fEPsmSL=oQ$Rng^xF%02 zJIZu(`^z1fz`z8QLBQ!iL>NN8dqIx6+-4`11zYb6uWEmA0b?!Ltqrb-y$sH%IR~77 z<$79sNriVyCE_;4E3ZW~Di|0~Y8XsP5TXjNuv0FQeNZfAU>y%saxmTlE7sP_8x5Aq zz3UEGj>GDM{cVr4qntL`dB36vjr)4C_G0@HH!U^J_|k&}g*`)jQNnN8OuiKz|I)qj zvu4Zu*q|lPf%ahz_$wl4*z zFtc1|zu0KNxA_IAq!hzXZNV+AI+9zVo5SK#zdGu$?o!MhFe|_8OvvC0flPDMs|72C z)#{u#S0kqtcrfTGzJ+b4ltdI_$^ro@g9nl|e}UfxMX2{iUb)(mbKYC}B(%cmbUzLR ze9v~_cNAK$11J5LGVC%4Fn#as)nvkz42QzWflluACfgA?)1>%Kr-FI%taW2n2B}nc z7}GD;`fLnuusmO*;AsCT@9%Px7wGr_8T1>RY@cwX86fbW3^=|an&ijLEzw7tSG~s3 zdH=qDt2phuA~Hr6SBqAqQlFLqv4ArXIn<8Q9htIh?6e_Acy=>jpw-P~GuO`*v=p|| zXfsjsP*H~FjQ96T9K}4|+p-bv)*N`Z>%8jvbxp6UGz zdo2Er!}C6Ks;(&sbEUjnTh+~o9ppg(Z+*0-l* z&Q3(nmD-Fdad)))$1B;>{7=G?l5n+)Uf$kd(DHGnCNU`goVR{(KW~0Z#=~)egwcr2 zEYACQH5`3g|2p-o6Wn#rY;eaz42Wfl1O?>iK>5pO`4*dq!x-hFZJPjWsrB>TGs+|rN zZ_rCq*^JZFUw5e4J0J4>xLP}A?pEH)35$r7E)mtjEEZ+MeE(ry2s_XI?_Z+rsbAuR8 z84`*YeS<(ixmpd{lin+DtTBwBh~0&fl%i)3G`S9sJ}&FDh=V3 zyw&+TMzKFj*wPsF^@)wzcttLJ5$Ox{F{E`&7lsYA2h}<|4vsf)orNpqHyBZs9Ig&} z-m%I_6Jb3UusS4x$c<7r}NTl$re^_sm$f~FsH zkk22UGjRm2zy`DmC|?1wX7+Q5 zm~uc8%xBjr;L;E*aU<>oX+6Aa5L*c1bBHgHsTw2H`;jYR`EBSoMU2>NtV1_QIV`69 zkPyq_lF}``u7$9<>-qbDPqiaATQ1&+N`ZyII!VS-r#m<5#JYroUXV0&kmH!x=zQJ! zfwE$3nc{VK8hWBF*SnfoWNQT`WTpYh=3gnbJ;9{`WGGRQVo!uW5H*bRHd0)CY|!sJ z_8LXOOc$1jL(jstS)wU)KI~4S^r_zpSOG_lt&cUB1gv?}Oz|`)tv; zt1&KDEJNC4htRAGb*YPXq)pP-IVXFN)-O9ZH4Pb!rlhLPv6iEnB~MF}AU#EcGMCzC zqF8Bbtr};D!+_)`eC1PHFl^?}w~>=)UYG6*@fy%9F_C9;%+vwo6oPSD5#w@A?H4|- zQ}V`+aqu?iBk_Mimo%?*VI%?Ovnpb%pNzSN0z7DK`Vx>5qNW&`wm`TBq4yY2Qi!~m zPTXdHFK-Yj}VpvRHfx58|3S5*Yx+*dYH5EMn40)KikTG=lvC3~Kn=R)0 zJzb6+d{EIA<(GPS{-x%mfH4y!aTQ{Q~51A0Gtk^Kx_1&+UVFT9_-0bb8wYb}ToxyZT~(GEhAV z*zl8m-k(m)+#hFM%>6$@u)uG1pv0>3X&Zs{oSE+{wcn+72aU6N)82IVuDM$7?9|tF z2)$t4K6Uj9i|?y!!m?T^U;adrPA%8ug9edSh=zs(nw`p@qdNdRZ}j|FGSLSxG7&4E zPiVR_}~Vk0HWv^v1;suD>5=zcDs{oL6h?POeeMaKB&Z)Uh;? z`U?oe@xGwv|9`=7hkASd$mSezErz}L-QjXGtshKA_IY*{(sh+uyt8(T&S4HXNS=)F z73O}6x{k^6%X_M)92slV!E`qEO2ZBLi^=Zb*;1pPBr`KI>JVY$n0~ND>-0Ux-fY5H zC2xkq*Nq~`s5ypZz@sVSl{=4@4S_?l@^{)PAXLCkBdpPb=3S07XHGv7@&5}3z)UGDm3m=K2#!kb_x9zBUxw*qXr zQ8SebKo%js+{dgpE*3L|!EHalcnMb@0_;1)Gqh@ERv}%{0C|VDuBF@*nt=UDgW=F7 zg@9H$NIVf~ZtjTPp|{6t@OcQ%(qWs=u3f_4uGrNURnfQ2w#3sU$FCL#o%^V;2JRUA zrfK8I+XD^OgEZ(OJ0q~(t9!lKZF@9{67Bs}a{wNu3J~ge_b2_(uBFqA%Eh8H-e<}e zWsUobEo_L1yGe#>L;f`<2yZ9xHhnGws6wJb%1Ipi`?fqr7IU2Nt+*Xey;Tpt7h$pk zJf5uHO}zLr)tq@zOTC0*s$$?;&N;lA z)btp1J>hewu+Gn))cw75XV_Eqn<)Y{Of(dpJNdaLV;a(OF+Zm{3})oEw9vAg zjjA;R*>fN50Agon!)3E7`=a)jNHv2M!Jpyl5f1mo2P6-r-TF;L-n~Z+q zqilbR=?ktLZt7L%DZ@pWqhGoe@{zGU*yR3PPN9A8w$bW}IlsauQJnr=u`R54FzV5; zQKt?_toSQDv82d^N8(e3v_Q+sey$gROAuIArQ90ffWE21_xY+(L%{nA=Le_tRukiI zJ7GE~((Eg3&7UXz{;%+N_Lvr(lN{=em!*#5^#?KFxtMm@-JqNM?Nfr{P=t!;Zq~AM z?9)`Y9sGzhiRUS7|HwT571@`%g4e)^Bab@IVa7Ed-(eppbhi6JIm&`A0MFk0dNa(r zFh|*dWFG6IuMD2?XfDQEuK@CkuC;Wg4JFUyhElzgPub*l4~`q%bXxJBjk#AE(NT19 z47ZU^NZ3r~yD~!g#?r-Gd!xSRcKBB_SHPfw;Tez=&;J9i?>m}V8w{89nz}o&q`y_{ zp2B#zL+bvTJ+^bk{l+dApqD{ncQkjM8^k5jHZ^gl<8R~>LG|8Tyg7(BKz!9<{deZn71sIm%*Bv1rk4c)p1xPdUR$9_n5< zhW@!foT80S1p)i3y^8E%Fb;mt68_^zPqtwAW)c^8)kH!<;)|jp-8^;5(vtRX0+4v> zl3rc^;2;h;IVM4^D@aW#S0tmM2WKe)e>u*|)sp}0d^5K*T{PfB>)91p6wp8DsOOZg z<%n#p)ffyvJE@)Q`Lopq2SVBBb?50*lCC<-p{O}K7H#ivxz6tG@pC{~;Fk9WZMR6e z6h+9 ztlvPshDgKG4ZTwyFg#}b6$Ip{ZmO1RxwO=icXC3fKL8+;+A5nVTR>hJ zv15;V&nrfz8(4Vr)BU#q5lN~^hwDP3*kpDOen-Du3l{r{xTTeYB*m0PmntsElRwPM zp^*9}MKEuhnpHiyDY*xpKv4X%*@ePJsE{NC$;1unoMTT7^#Zo}a!=sM#-Iv+6?QCF zzTm^~au~>a>-kHBS<9#ZmT!OmYj(*773~VG2z3JQf5Vbsab4Bi*zj~_fZk0~*Z*#^ z(Di)dS8~2}^4_0FQJUl{rup{4{%`xKS5m5116jClu(276JifZKbzTSpqtI}T3x>VY zzw17eygZe%QBL>=t@-dKF&=&|a5FTWVE&VTB-`bZL32Xbu+^DRR_Z%2s*KOK|D5a0 zE`?LRh|AqcNM5p;W8WV*dz&nhTJu+(cck{{UhpT{Kt=v>wKPt~>6cCvSgRObcRt9X zvF^UD35%9fR;D72V7gQBL(N^4vJ|$A_3O6xdwTb)u2B;ITUrL6UL(n~_oRu@Ve@j6 zHPz;LhQbpl$x6^1zrqk(+Ghs=b;ebn{50rpf6N^3=EzAjZ}RX9sZyGwyy5e{2M%@a z=XNXJfTBhV3m+d2_z)d^^Cl$2O|#G{$ys5=Kh(wbPj~(?HKal8PfF?P{3x{Z>(q_f zF}6zxkgb|6h76FHP$)Cg;pJkzSgm+dW%*l|wYXPmsjJ!J|YuZ({gwlES?) z()sy$C@@|5wj%s*frFEt!r%CgOV1XuJ> zXEZs=EL^Bd|E4~FG*86x&!OOfANbh$9_vC-%J_xdS*I1GnqOr;p>3Q6Zol4A6Y`AUBy7DmhE{osGPpw06N?C@V`2?_~$9&9I-l-Zp z^x+@C(z6nT&l`m#jD3*fbm!a5@m9{iGy#p4Hn=lK)L6DN*PvX$kq&&2Y}PP8t6&9s zMQdz^9GSu3yr>0+-O~}RU>=TBAtrMg>_XxhE|pbD9IV3drQce-O*FGgf{o|>?Aant zP$1s>lKHbx6H3pb-%L_?t*}s)DHv>lz?SQ2wcXR&Kvb4?W^AGmNyEoR?1yN_kt6&$ z*-&vH3ZgHxlG-;k#ITDU@M{sgH{n8~-G2UoT?}8X%xzSwI*cxLY1(#AA-DZPkDv6g z1FV22g_wgyjzFNT9mvMY3du-H`Xc=~_t50EB7Z~d0B@}g>jDgSU?pJUvhTQ0KVEjH zqItD|NU;b622imQR1vVE+(0@6v$JlCVcV^~fJ@O8`&@;xKEKf=jSrO<0=|@O$qQ|D4NhCLfV|rYgl^?qIM-JK8q0vI@3;1Pyaq!N=@jK!SNH!g#S2TDVuuY(6hDuKnFlX zURI7VGc)_M5ho!wKDt5v5*QfVpp78}uwJc0U<^#tIQx|odCcW1uD26{~Yjq^_$+sKxXJ8{`_mns7^ z>*$?KS79t|dWcgcZ5PMuod(Q|Jz<0L?H zzpHZ`kT+7;5ghm6rBX3Z{51A+_>36n^?LmI$v-Yu9Z(23nD+?tc1UmD_=qlNXr9&s z9Jl02Oi#|d^|1bxTeSCEBx&S>U(uERdc!8a8au?VF5`*U1-&GL zO$Q{QnO*^l78(k#zh%=UB)?h6nAE#G{u2LVKmiIR(L{~?Swa^`KuY>WNdf6oq|hI$ z&mU;0d&|!dwn8CL#1J(coaq!l`9%ar`hP(RMBEHy8pOL%nL@a{HWIKf?YRP-bmXiT z-JW0eyda&r@BH*cHCLnAn)-DZ+hOz|?9}lTKnf3X8E@D#>L}vQ&SF#7e4RIyud}7O7nPGlGVGE8b33(y&8auIle_+e&n0`f{jY?9+5> z8g~2Q+n>(WImYriajciwJkhfWpJqwsYU9jbB59xVCU;*6V4JtS&2P6OBzV3=t`<81 zJsM2jM0|P5FtP}G3w+qQCC+v_?JqjFH#UqgzOvg+%k!t=;CKfw8imIaNzY|` zY;!&B4MoHK9vf>u!k|th=u6uLYpv8PfS4$0{Mrkww_|@&*PZ#mEiMs|xQ>cbTehR_ zsAWxMZg_%!exESpR(Dj0N+$`ri$O5Wfg76KjXPQSu2^YgFDq-gy_A9(QDbntN~Ue>nqAA3ZBt}uC5B5bV#`138p9f(4k|j2(0WOJXfOy9W>vCx6(9# z4UfDWuO}rDe320ohcu6-%*4gAOaeE{jh44?Z~QyCZZp#$!S)2D_KlNUFPtM#{qXO6 z3#AZ!;ML11Ac1DKa*{ii%br-(A zz}A|$E&Ypgo;we58-;_tR(&nnJERCKatXUH2NNmkr}_|5J+{=szSWuya#h?9=QuL) z6a(MB&;f)J4Z3TL4JuLBSN5(x#2}5@DQr@tc;1%ED$L#NgGxutGQ6WPA`M;9u}9E( zXpKbr&qElsX^l)?YNGGy=)Zq`jQI9VxMj9T2LVhtw!dpGl#As!xU(R*!@X*}8N5O6 zzc)T`0S;S7$n;{?U+zq3_yHS>3NEq1SRDMxm9e$gsyC+Rg@7QB!JE=KGfR$>=*j}! zB~nd0SLqICSkNL^TGi%sy4$SWB#>I>dYJS6H&4zT>6BzHSa+a>`u{_o9Hrd<%99iP zJirL{=Z|kNA0?P;dsUscJf3-B(XiLT&(5Bg1NccFR>8d8Z?Rx6*UtreOWKwFcdWw1 z7f_%+D5YrbEuxp_vEh?MSW$nfODjFE!YHRyYAeG?{iWc zNsjQt)lQU^K9BMTR&q^UW6e9>xLo5XtCY`v9!ZIzKy1~y+8d{Tiwg9lY$Wn8- z=76r+g!trq4zrF&gTT62Mb@Dhhe-DBsnXV0ZBIM~Im!sx(w&{FhU8IttJJf`(P27qcrE8mHS zVG?7-x#hu}55z1J${$8Y`F7tro{i_yy_bbC^XaRS^I{dli%mw7&27xyQCH+)7%iNq z$Ijcy>E#so$m>T@_3PpCB_g1f%VdP!DfN>tl4WCjz-tvBI5%+HN?u1hvk$6miWt4) z?+c&~m8wYNxPp9iWx}u}lT&M2;y!jyjgq!Wi4N6aio+yswWPogFdS`S-K>X*v!KM{ z-%SjZ8FVAXA$+WJa~`yY2mvVTu!=M2?xaMo$`_(#&4g5jpxeCarbcu4?V>isFp!*z zRb8#ip9Xzyl*x0&AvsWh=wGW&rV*_4A(8e0-*zj;*#KEdv)vdOXtU)q%2?fCg*ATE z^X}xBlWKn!i&Mo^vWZc*6m#vG@PW7iQ%asn$uxyPA)F5eG(-9hxjf-;YS(2%9JbE z*^L*o=m|u$U2Y2-&*F#gS5=mfKuW9DAMxrF^u|UGYo|;CGHXBXQrg~oqjJ(?=*uk@ zz07%lbm(eorshtq=DR5)y4J=ZdZcPkISc^+BAV)kfI=~`jp)Jr#tQ#q`u}nP1{xJ; z0MJT300f}2GjBr=W+7;>gpv(P1^bmhcJK#qC{G?3 zURAQzVHlWzkykwmCbkGrY-rgezkd8D4p3IW13^-T4z06u-(qDqVe~?$kb}b0cYvU7 zq_B(BDQm0S@w@6`{b_Cd-Saa&5drsv5x@Eit5j&?=&%b-`=(p{&!4t0tz(TkW6fFJ z=EswfmZ#Cvmrx;|j|O`nBb!KXe|^Yd;Sfs5`(m}A9kkuwm?$)=(@sm;z!~Oos`)3_ z0^KP_Y+qU3pXJ$zOas?+XV0qK*h5Bwgq(;?%7&EXXA(q2#QTQ_^CgM~e?)|Zb+Hk* zPqC!@^c)-8w-IowZsX@DYJO%2jS4Cdg>+XS!X5PhP@;bM~s-#mLIKV)z${vtm5nt~QWBIakj^Wb7Zz3;a;eKMvqXr5~P*FFFd0}X9^ zs^BwRJVmq)k|AAO;L<#S&@p|6374uV(`MX6VTuBND9ux6=h^ilfKbX_u2v9jo-V(b zuyl9eK$wQ?>#jS4o(+Ihqo@|$Gj8_P>oZm~94jlcMRKa=c_NBu05fM!5%56jyjz=} z7#;)aszTh~m5|GiQTVKhPg0VG&NVwH0_>ZZlu_~V3@j{f9WJt2acM>W38jsk>ds=> zTjtcV4bM)jmxL3liKbGO98!kB%@xHp=Jk~D0hgxk4>A7Dh;qfjg{2obdFc(qFxKBp znG4sZj*}#>3DZ4Gl%QPEpQGfGotg*kw|HQ)gpS2446dwc4bVwlC7(PHruRaPo{@k! z`jw>6xj~miHe)V0tJ|dA4f}xK%PGlXXZcN+cWN|Yjasojn!X71Lc&Gem4vUtvLeD6zpFOnH=Z`M=6G14c$zZm5mI;dbdwc6-t$I-oQHuPVm)l zb44pw%Q$klv2iT}X{Y-!`lA8S0fovY z5me}3oF3t<96t=N3ffH1 zy5YmQ=+Ebx8^evG#H~uNm8+fpB=l#z+X?f4oEum#RO&35yiwh<-{{a;qIz?s0N(;w z1#cgmhu-gUdNf@)S;;C3uZkL?OGWMZJFEUzG-O8>o!+U0?{k5QaZI$d6=TKN8!9ef zRJ?e>G*U@v^(b5-2!xFDUpBiM;}2frWHySAELGFwtC5U=k`I~hBs#Vft~hBapcrAr znCJ}gy;w5;rGEd-|Ky#`=x1%V^ujFt!TyO!;jus1Qu@smlDg$@_)R$J`U|R;+iLsX z|MwfXKK`HpYA+Yq&tO)b4aZYyOMFjDE+#(?H{cllVgKJ&PZl77oGk3^u?`MYx<89+ zu>Xgh4!?_J5OX>OoF)6;e}%UW-9i(tx8$i58alvb^B~@I-YMZ543HVp*0wxan2Csg zTKKau*bzvB_n)h-IuideY%$;dlV2s4KvIR-Pg6IR<$HEG8+eO8Bek`|`5n#k1+q## zMB>1MJ=Lle*`=M!C-417*-eLo-NV!h6=$!G$R*OJhT7hVY5e$lO{=vwOw5s`!Vxp5vX3&{ss4EmcC3H( zoOSnES9+ndTrrXhH}4}Y%_A+cP-hVG%Ld!l(RCW^nF&C7GI>^{L0Z`RJszFr=)j9D zbJ3d)2WSOXBe|jNm;CV#SA1$5O!jnw-SmhF)YxQNB5?Qo_d|a_%={;}3S)v3vZtn0 z-~v$?MX*pwWJQ~lZ}~==2!re^hGz2Fr#&9h*Iw-?x191+N(ba^FZOzdeKkIo9p@W`(?eynNl?S0{q#{Ht5P z!_~w7310lKJzG|$O2iov4ypu_Ej$`l=ydqXkwZ%DcWXkvI{j`o-v6z1gemP#*$SH* z&s*nV?W^sY`waC~K8|pDvW5YiLOwRq(EVyM+iE9gw8?SHiTujXZMB9z@jv)_%cwZk zpj#M8Ah^3FxVvi-+}$0*;O;sQ++}cg*AU!2xVyW%`#0x3@_uXGb?-kG1Krb4KV8*T zd)MCmKf5bw&t(WjThKQ@z!r^c0#q}iRtXd-D9BVQm1ObjkK)XAYvx^Q?YCXtcpO0+ zW<<1Ux$%`NzVqt`Vnke{c@8DUXKW@AK@37Q+Z|~EJWgA$7JgpO;-5A|ic;3uvQK(c zR6eB%d1hfH$r$J*Z4Qe~b&?7#os1+QJjZ}k$^x}Nmd;8Li!GO1!)jHM42R6(NRs+p zAJ1LN9~;iFjIY*7jAD9cjvo7vZ~WmPm2rtLUQBFQJN*7p`y;AoXYw08541wy7a{rV z0*b?W^=*HSZ8IC>m_LyjbPt9-f@4Ax#=7OK49_<`?#l}8JTMB04M|`bN75!RKdh?h zpM8h%Kl{!D9#iv<_Goqtr%o$Ws^n{hn#21y#E!Fe5!I~R$2e}!Uo8*vX)-_c{9y#1 z8b33_y#2uhA*_3A;e^XXP3XS+mtZKx0irnY*e}_%+|3}UbaYhgRv~Iy9z7yr0nW6F z^$}bqZ35NPKU$#_2Re4I50{&gK2VR=)HaZ^Y$2OM0XIh`K{r{PDPt5iP7V{YRdEa6XfLe(KZ%Ph&FP#+yqY+gckx<&tn?AxZ6f zcrn}K%B~V4XHF}0SmM0MTWu7seLYyzwc>7}Gf5&dIj$>EUuRTtmZGuc9$2zfilY(5 zXSG@iW_Oy5adTt?32JvOHeQ#%UD~F~n)&OdQX7S;sO7ykLbBidBIo7yBc)*fP2HB6 zpe_?|hO%?Aj8$A5z~|?u^Rd&9lA$z@C4GC~#e%IWNoO}u9qu#K=gf@_Gv<}S?YfXJ z{W)yLl&<}0WiPxy>@-G-?2h`-SwAA&X?|x-iZG{pHl!YN&PtEuPmYC~uz7Ap^#b=U zKBG4z!dbaif@}Nfx`uy;V?A0Xk*)Gio4X{<{ihP70fke;IMTqb+EN5sV1;6JmR`AY|LW@6krm;p?7^Ck&r*OCt&|tcLa# z`L28w_%!`)-#-!bWX|ZHdekPA~0+*(`)Aoh%X;sFz(8<@b=w;14cok{|17ek1|A zYk5@Zz^+-G1riy|*N{}yXBcd^@h6V%KhytD&gw1O3zSI5+ADS2d`_y~h=GL;t}A#@ zo{h(me0g5gxKkw=oY1X^TCVo9I4{UvWJpG6HRL3Mn+fi zoS6xijB)Pw6pqmzH@I5S#FPTD4NMMuy~LcA%U!eF%xi0dXW_3Gl@KCgSIqZDh#g~t z7c#VLA{a!l`R?#M%FRyw`|-lt*ecJLm;*P8gbUA1=S#W<=M_8N1zNv5!(VLKzQJ zM~Rl)Jb98|D)wA5*7wH@*C+0;zu05<%)at98LdaCVIe#rl!PrfcCa`&;m(fJ7nZ0( za@|86PfZ0UYY;K4X^PIP33@HGU}xI6s9f6T7@6-w+31EIDZWYjZH1BvgNH692b+|? zi4Z;pUFvJIp7wZf3-VHiPCUmhG-H2*&Ymz(Zza7ASMR;L`$l;d0+|~U!3+ssUE4$a z36lLb`1(2o=7%6yCs6D6k_@NzY@TSwIZr)P)PcXJrmZ^*4=|5jei(2zXmZsusx$5A zy)E_T^KfaX>aT@`X-8LOABcf&1TntjT9h9H%ReHWvbdBh3Zlg;6|RCFft>dK`F%>& z#L}Mu6&9D6|1*@to1-LZSC_nE{ltG^y`E~c@#;mQj#e)Xrl7i3j?Z+lNA=QY-8&Se z(0cot>Ag_-`d908oz~uMU#4l#1DE;9c37QSctRePs@9$HP?qadqGxq%9UsHNN-e|E z3Skmcw}yZVCl~LCks5*a=byIPwAGb-q1%^-!*5+_d+@1@ttel&CRrXV=*`*Bq55Zv zh#t@i5?p@2Zc?K5JV8>}F{|e)P){yl^_6{x_V8+t_rITZ4V1w4cA&^|Di(t?wWKfC zy|}XWT@Mg)SAa0h8VNEI6nwyJ0Dj9XUgQ}nm&?Fy;b4Exm6sKcWYNE@_klA`)EWO3 zKiR>B9|-IJ7B&2%D)f5VGEZ@4zpUlZMc}f|E`>%FYoVi-K{)a~>hjwrZ~V`*fdm5R z7L^Tho`H5DKb>b=Ym z1s85fAR10uj{nI0gFT_%gWx%GTGv!0ANS3=JEN}Pc<3tKqTRzL=9Nt&j`ZMf_t|`a zlsd)hroM(feZY>K4dqSjJWss|oN-ctuHVhzNb%~gFZB@i&kLwAE2omm6(1vsT|$TM zIcsr%=k!!jL`L&!z(lzx-|;yenI@*a`147S)>2U@U6i+_y2Fhe?xt&0%~29GIe8XG zLRq}H-^Z~rlqB)C{+c|)`ga3(9m$1_V25rK`7LadXxeLc7V!J@-FBTkchAga)FN68r*GAfPm}c( z$gbrYe_GUD5a?VgWekNoRZ5b!^2Fk^CgNpf+z5Om7oX+)*tnoY15>^<=nGZ$PGPzh z5&fnf8-{@GaI?)bGm`)3b-6)u3t2j7bhih?m?rCq=hgrzYn1ytdch}nC?#Gb6EM&b zv*=yPr8SJ^!R0NYEf@JqKyAeVyW zgKJJ9IiLX0U%h$isJ2EViez|vf4i~H83u!)pRLLEBRwQDs{1Xob|o=DnlgBK?o2EV zod!h(>wu>iiwbbE(Y{HkUD!IFrRK6wj2;pp)d`_c1A40K^a}W=(MLHUm}@n3rTnIxudZ*<+6xAFmPrN;duel4TenGTb@?BDSEL{1gXsnlsH z`rLay$nrl0Y;&l*8ew73y$>Y6)$-VeP}$9B(}$h>;gWvdPHZj)p&%X4=Y5;zbRuB~ zRnWn1I=zY~+Q@TtO$~ND&^3N~-K#QiTaN*J(~pNNCgr1lJhd34hpe9_cxiU)H+a5_zdKf;sZ@HBEo69dK3jp=6WjIf8Y z5w$jnGf4zbnQ>jRmYcr84`IC^_#hF4sa-AD#DgfUSpj zNi(Y4EKaV-Mjw!)!Sm<}*$UJL^_(=pH9`i<50&g!43di4j=$^AZglVv54dX`m`8`O z`j$oz3DikE-kpvo6|r7kE}Gt8f$5aWuIFokTP8H#hQy#3GUZd2i}4XSD;ljR)}id3 zUc8u=`HAbUA3v|>iL0Hq;Sz25{lqGI%aR53`c5vL>P$}O*j`$9+3UPk-P_DH`E{&P z8o6UMhmm87ht~y-AG^yjSH+@p+lpW&>}P?r%A7isXqHDE0&({qzYAR+;~M#vjdIj- zr?j?pe!(+5d3BXGHCZ0IYl+K z*sr}_7V04xEQ?ORq@P;@NHF0GU>q$y!#ti8YE75~Q(ig1p3aiBVL#TkXur3NQ?h1D zYNj)A6pw~)tX4B&P_}+6iEprx?Q4&~n@WX0yGyoY*JxJD8xDbMRirew9%Be%b2roW zS}mU}9<`^|Ogqa9nw;C+ELkux&UpSc{`PMGymA8wjB(nm{0YON%hV`TuhP3Ynx(sU z-gi>v?_o@=XbdvWT2EFO;5~+iJbUY2@~(gIo`jdRi5kZ7xI24>Rc*U3$?#Dxxz`XH z496#W!PU9u9_HmXQG+ZVzFr(Ud{ML}fAx45UI?Q0c)Jo1s7)!9HZk_6;N98=eZH09 z)-$0ggEJnW1=`Hr_ptS>a7n)K9Xj(e(R3HP6KE)qMhHJ`rlK@1Nua?&t7@`qJv%Xe!LFLj5@_vgx0cYPaAy4%@|-b z@)F>Ra6L2BmimaxBT&H+S=4*cA5W6JRkpDcHi>AvkQx9A#?_O9BOkD9=qB{h(m@jK z<>8cn|JkstrF3?rKBIoT_^zqUOV7DI8Y;v*pgz3nFT_F?qjOX0sT46ti?Td64jtEG zyNIQ}&wK|^!9H4+YV`K-W&eJppl$M=v+ zE=eF1a?P4fnv#EuPgjwiA!xK`LU*jdPf+rk`~=rbjtE1>7?r3wcf9J#lJ*2x_jxrW zSY)SvwuV3wS{CUcB#f?OI;VdKbe*!EODvUMR&q8^3vW<7R+2sBE2mk^kWynQQqP@- z;xw7|@o7lWlRKAf?^AW5%=krbEjO6xpSTj)+#-T`+FrE%j^ct%Q$I+`{+XU&qq=SgS-;@5p=z zuh|6kt-8xc(UDz8f8;vmW%dSeZyAv_db;4O1KX1=u}2?T&6^Wf*GvxO-=`cUT!%iW zsY_Mw*T4Xp4#fj6@SIcY^i^c|oVez);HIM$ z4QI@K@Dp3BWGzW@<)2v1yD5Vz4~Keum^cMx&6aa1C(=3lY^y8A@HvT|!=Bm+QrZsS zIjD4ZiqO^u1DBf}0gF{US)gM{mcnW~hVUxeLH<6Qb_YLCvh&y)c)lAB| z(J$Vms+)e|ET39EaU`<1r_s>S1Lta}D}ti)FS(3UYP~;5FC{yAY+BW0lXQpL6lik6 zM8ST9EP&svySU-yU>X3o`qAD40>8^phJ?#64^Qco721!YYZ87Df&8>K&XxD#o?X*B zHU_0E^Fa{~Mg{`g#BDo+lY6(I{O>jj>3HU$!f2&#%Tx#O9dS8}(i~>6Yzr@vQmeH# zY}4_5Yp+crUP`oI^)f;%BBmZktI(##<@8&6^Id)lZ}0#Sew6so1z#0fu;FvdLO%ap zh8^$otGNg&8f1Nay(W8M!P5fA$jxfc23N;k7)`j52j zWv0|Y+IKp8KuQ+El5DuI7L;oJ#AfrR(wx9KtgZQXgF+-z;JOcT>Ym?oDIbr#Dh#Lk z9v;$@sb*^)^dYeSYV@EUPrc8PNf?jr;dw_g&TjN+r>er_R7lP#ZH?dktumcZ{ZaXi z|B{k-<4pe54A_VOi|yP6Rc&_*vut%&WEkBh0H(8=n(d(#aFJB%bj}S4<38N7v%2t3 zI~qypQ>It+wF0qGp8&dIw`sCz-ei}O8P{g~e%`f9h9=t~%8Fbo;TnQGX%>p%Kgi@5cMpD~gB~kPonaqT(k!IXQt~s1WxOanEx1db4Ly zvxKeAi$*{VtK$$6D;xnP=FKZO{9@!~#}qJ!c|j*6gmQ5)-%FI@Sw0!(h}Ov{*JS?X z>^I9K(r#b=Eenm~0JLuMPygFpjXE6K>2&Ec}kW-Nn>@pCry8@79Pf5pjSqrTX zwZ_Nxh?>|A1FJ-pS$s*4ZSG1DPMatJzt53J5chM#Cyz)U<^R%++g8~C_Q0Dm12bt+kU4f z603^}uE`a^;G7bTSj6jGf?pbKU;jl;s71zG2Ns2!B$EsDuu$B7(-MDmDvzqu9=F?7 z;|9MHPNtUB)H54zZGEjj@A&C&eUu+hL1gMJU9~FkSnk3g=X1xBQHIl_MABaeytiwb zk=VQCs0N(cue6Nk#nN&On6Of*XQoUR8(Jf>p*RF^ncoD&+1N4y&Qjr9iDEpCIogSN zLBn-L)#eg3n7&J{AEd=AbLR4MUM7xh*BCNeLL!1qr#&UZ?|)JGy~|C4(=fNq>N!D`8jh@MpuZ|*=M+A zT(+){5Lm8$VeBnn+!1XcuES+JV|yBx$p^}+vo|o)KsEf!1(3fqvpd8vrWdZzav9O# z31zZG=@xg5WWFc9seH$*(SP;-2qY-hT7;HfwSE&M@aygi6o-xo0GWN(_R6sRr36)RXme(F-eIsZ#`Y>T zqLw&6-Av(aFkJGOt--1!S2L4EeEq$u%RpD&V~G^9P=LAH+&*a42O|3JwB+Wn!HV|+ zEAmLlT#$xq?Fqmuq)K>G+@Lg3DxYjuP2Lmj6L6om3A8AUd`fjq;xd^jIzDJ_9|b{6 zQ0W~k+*%Luz+WHAyBj;u0~k#XcpC(COPiF-_yi1x*)D6mL>70;l@n8sbI|RW>iZ9RDvY699?vKHl)-M#XsYS_=l8 ziyk}4a`M{k=`~@?mjleSJ)gmYGDC7r?oHL{Xc9H#BCDY{gfve3v07*%T2mJ%M3x!@ z^T&rXv(k=nSD``%6JukfdD0Mw@-L=UAJ63Sj zU4jYO{j-+m_Po3Czxr3>F+U0A7~>by<^G5Hfc4U_ic)B6+LN^}!TN)>=@lc{au)HX zY$)Jcq@&l!;bptZQ_e?N8-{GXC{tIaPdP6OYan_0Bzt4;ahbgUbW(y)Pu!i=pYMWA zfBfX7v0T_S!y+Ro*x51V<;M}9UtV9$=POt92EZpXCoWohqhAaE7i7h3zgfp389L%K zwz#~!3eZqPM2%Cg2kHF zl^Ya500>bx$1CQ&IijvV9ZQ$i(rMku60Hhx+$^_biL~p0WzTWjseg@T0^BmeSWB&G zJ?&bDrKW2Rw}9GA-o!P)x9~~BCzV7#TXrli@H>B@`0;9L$#DNfcXPGze|WN<3>a}Z zNh#qC94@2@Bod{?FGWd_z3oO8ZuJGT;cc<8{sP*m85yG%78bz2{U`c~KuQV7-`B=W zYfk@@g#PM7yA?=8g9izvyQZeDQr>s}(}EkW_=;}Ywb}-ss|Eg)y2gwqm!8nzE~p#% zUy-%|3E?0M`2R5JPqA=+L2Lgm=%?6Fb&IH41rSy^`cVzrSonuLTJeG8vPdW9j!sYP zcLQlJNO9`_{`yNMPL;~m$#A3C!$ADtEXyRXM!|jGhluJ0WoEzsJ!;7Q7#)X-qo>yx zHiH5!mPV@OL@~&-;80d7in0;whuJuq>2KSL&a=7|3f#VF2hn9$7S2&=Y?se}x7@+k zD{(1x%Prj-QCPcSC*Bg|y43jh!s1pElU~ki_P*f+ z_cgv(OFjf_Xr@gQ&uIN&vk)YH-hVx=`^G_JM$D|Dt~U zT`uItv}%R2ef5J9#eVjvyB4ib%T=OPC`(uYqV`m^Fe%O!Q3DH@tP~NBC5LNnJ_+Mg z#~dIuu$b#8Bw0puvu@Ims^rmcMQsgzCsjM`&aW5KEEmM~QMNZzNC}Y_&l^^~<&u0T z<&wux#NQjO#^Xb=ZWO8+-Zu_u_NflMW67015yo^5DLnJML}D*_wB+b z1u}86B{b~R>`T9wRopc|U%tR#;9~+TK68cE-dHK9mj_?nvF9eHL(97yKCb=k_JDJ>)HS6>!A zzo~m~D-Un~+qx%_j6a^hj{Nm!v^qZOrVLo{flxw2L(SOnBOtTF$2vfLO;RA^-= zG2lhjwxJP{$j6ixy?0>zDQ%5Uo{?yF4WrXQ96k)*cE4+XOa-JxBk;zHntTi@GyRpd zT)Ib}u0B5WL!1-imJYmz*akM?Q+dSL-fJQSd=e`uFL+Mo&5oZ|OO!hyolwFIIorsV zlrSdrrD(F9MEQ0I%EN7_97c3*P|}d}rDx``sy$87qGrdl5p={~?qm;sDx-&BpVl1h z$Zp-&g{m;+JCcW~(YRmCkZTj;bZxX`>EVqNibA4;_-%E=cEnq%CzQS!wChW= zg)hlvyZ`7G8>{xr9ZQ6ct`rjc&)y2Kb8+#p0RcXT*0MMMzWG9_CLZppHd&W|LULCb zSd>Pj>ZMbxv4rqpJ% ziBf5DIH!e4S6mWW%eUge;R`n~5+d+t9BqbzL3|d+aQX2ib;(ELH*uKmbIyT!oA?e% z5i?dr-0 z{82}3DHT;%-#Fy>U(rL9|1`PGy3%ioA5~kQpGF_w;u}}ap+y;0Vpw}N#_d$2TYj~Eu%b8c3xNZ zrXA#7vy3vAvAAUZEMog!vjaNQ6i~Dh9Qg}Qcj`_Q9)>&z7)}^_+4AeHXT(q5;S=ZD zLCyPGgwLa$TN<8QaZX<`;nttf(rhfal^;MJ!+jt(I~-17J#ouh*#0N$jU5&AZ9o3` z6yePF;#sjc8~tHVZBbZ*=SNgbU^JPt>g&!m)V2=lp_I>{FUkck7 zk+asR(7#IMi#sQX&;Kv*id&0|YtwEd%`0G+BsjDsZ}@$~$TqvfiS_+>^vm?A zeu$3Chn7Koqx(VY?xL!`7;{Fd%zR^57N_IjB`j`FKk_yPd=zO!PX{imshe>a^z~Qb zYf4>~xyhIZ*{=>y2YPGABZ)&8;cvEiVb5s`!a3Q)#@c$Slf`nVZ2*C0Twi9y$r6MQ zhM%CXjn=3e(>t9Y#_KXeb3IR$U%Wlb_)u7x| zUTBUGA0vww3+$5l(fB$*0oMEoCTl(Q1r$%9B4!b)+-e4Y&1b#hEfjQ5EQuAVmGdOK zg9jv+pg{8UmdL>sq`F<_EmtCM2O-*5;;s7++Y_Grg%6`5#Ih+|r{+g8)t8K>zOyb6i55n|J6{M27geDKz=!_y?^e~eauV#&q zsdy%qj&~)}Q*K!J8*%)mX8lP^aL8qwyZ2HM9{Hv~Hd#J081wtCK2ZNe&_9vtwDyHv zotKXHJl-_iJ%S)O^jjF4mGEAjGO+>`1NQGf8R7i9Lh>}5<0X65a>edM)~%Vb8N_m& ze?xkI=wE)%L6`s(cXTEY1iUVMGv_?SRwV~d>!?~bUtuYBuy<`nrf3kK$+QY0f}9EH zVG%{ljbT{2a4W4SpMu@VMWApes!k={ZZyi5y`!v65klIBAdi2eIGOh{Cz?&e3ccP@xy?B!3| z&Odvzf-!{LFcV3bzM;7ytOfze?bWisFTUPd`Lv;aD<2E_ULs~`9$YJKPCI8MH4L-1 zAlN}iZp!$E9Nb__aq-}8BM?F%Y3v_v%45N9Eq#oCwsVw0d&!I-^x~&XiSkkyvCWaB z@=RK3_asIin!bO7L?o+&uqmMMPo#$T{Ykh-w6)DPR)d9#>YJ6NA9MET->3SFRe-?R}i=LC9A3B5^f?)Tb zfpgbyIrW`Nc~p#ohm!>Pswrb$FNSa}LyG9`RHI!^!2RZ(sle8#}0>!8K~hqo94w>qip`1?Af`7R6f3XlWu1y^7dT+NzQ7V+~Z4 z+^5UdixckD$toTYCQf%?+p*^EJ4sHG&u%aSR`P*5E6=S>*v?8lk`*$4UxnGnyUK!+ z$$A1J%f?(uWo<-p^@#0Ge^~NltQ?)5vzucTJXow0$~?w$;<1%gMGf|skdLpllm{A&o;@@1DfvFIH=yPkxU=ve&FH**f89|4NAcf)$`>EsCa1 zfz}}R>$QcT*NZ#!tsT4MXc7Y()2|`{udw*@n3Z-fzo2Pu77mZ}I+eZotJB^KR)nOv zUtSt4K+&}kcn#Hs+=Z*{7Hjyy`~(gvdH_nQRS!HyAx5*>b3!}eu<nnM{cJuvP_Ch4~{giU9RXvighF~GIoxCSI8;k1)bZNj&tqAH*D1*u~18*DsP zIVPjo!IIJb#-=qo%i69YDRf{1@b_pnW`B;CrW$i(10QD!hR&K$u?uIR#exO9uV`Xa z`s3w$wZ~-DOPR9at`efUGooRRWb&YAqu2qUKsqm`8xB> zXBjU*Q8SKl8^Gq>Z&i3x;+rag{Nf!Sz&@}%b+i2l7ST=`Y#RbIh9<^3c+CHlSI7jw zZgsHXVsOs**uqZ_MDGD*bu+zWCUnp6AayQoW!2SG)58P@%jziC+N3p7Gw#^m?KmCV z(|axw&!{CfZu*6|vnbWnwSfGgk|0VJbAvYVaHJx%rYxl8bA#SgeCVPYgRUf*lQS^? z76X3`2RwV`EBH=V`FOMczPenXOsL;1(+ zwU_N$3TYPed&o-o_RS&PU}!q2%^=2l*=(^Nc>y1XewkFNpl+f`^| zB(3UDnjQMn$le9)gjw9O6178nd1x7(4SWcDpxvI+r>d5sRI_QfG`4+^x+#aFV;@Ty zFFSz7v93g+#8>5XpMl2I;|8diAs9_+{2CuKPxfCBXt>;OF?*gn& zGj7zN0EldL#ZI}i?m_uPz%EOPqrx3EHl{|$LT%Pu!5w=4J$(P@JY3UcHF&PQ(rnwt z{^UOE@mSE8qweUj@EMgE>@x+4ff7ZyjqjU6P#NVrgm20A6=&#F`*Op`Z_?mvj*^K? zfO|r}wsXui9Mz&LclwpH)hA^BUQq~Zn%0#p!nbWZqfpkS>Fnjt_)g6|dw3Xdjn4kY zMZ_0cHC91o|Ma;;1i_;mVD100QGF`r9WLmn{NT3ycy5)$(H83!5J&_W>2T%;?6s@V z#!T~|SMwq~LS0m&2F0!5OW0d`iLxZx$&&?naO9*&KNX}Ft&4edG<;_oejVXrEnmd7 zrPwvttEg9`2&umY()!rO^s-ALih*RHW|xNtn$F_>Y~WB^nupLOt#g+RPNr60cCsJ( z;HXU2RR^=B{Uu;q4c>@!n>o9)&Rv?e3_?n|=4Ybtd%xq4LkY$gqaZouB>5sIY2vAr zRBPzw-)n;-6|OvYJvixl72k2HdIIpP=J}Ln>8bW1R#t|7*kF;!MoR0|*9%59g&OO^&a`D5RvJ{fMwA`bRDYQo%k4FvQ0Q3+3%VxzkaZs@B zcsOt??60f$`d>ev1*CzaY@$ab?_^#oWiZD-$*6Z)F{bCxVrzSw%?jbur_S+lrVeBD z@2%gBjE&)tkou;l*?I(lKp({TT10@ancWu<<)fT>YBlG1-_qYy#|7niYi1=_<7I>Go^ z*Zvvs+2IfndX|^@#I4(y1;(@@bx?ejayrdeb5y7mXt0WBX=i9D@C#TUfeGl~83?hI zR^0-ni`|&QKmxEy*p4Q>cv7_CtqDT8HN8TwD0+e!gtfaC`=99ie~fs(hm^N6hq9fE zIYUfPV;w|N{-*tiZ9y>y7<{)HjbBJEAr`1tpqnhkq`wuqQaKGe*YEx*OpHi4m$>z4 zPdZ+}_YnOM1CfPCPoz;;?T_|7A1%7ck!MBt?BX*ky8jZsD~Ue7^NEyq%8~Rx>k2=E z0OD?Gy=RUo9Y|5~lgg2p9hOO0IhM(|(kK91l4h$>XXVZ^bIRa%d+qDvCI}T>ro(S$ z$-bR<8e0u*zb9+eGL&goZtg@-YL4Z^v$5!`c7W*aM$J?wDQE9qtb{|7QZSsKkn`lg zAaIJ`y4QFol=a`ubMQDjA4>G02Y8%4Bjv>N4M%FFvb0o7 z)uKerTootY#wfgA#hjrI!$Q)C4m}{|^LO-ElfAdMa$5#KFN;QuMO^=N~_Z4kfj4H_F%MnY^~45PILE>=+%MJvO?E>i61n6 zCpd7^3CqG+hTP+`(pyanMEtiG{5_;a-2~lqsnrvxwX+*JmLb2FHp};D{QeQ5evBYc z4U)sX0dBNKzgSIicUc;FnTo$JBAK_f&6rBrzuYG2hVaHJhm5j@-Uy+-4VafFiM+hd z`kP2c?;UO23U@GjY)u1;hN0!9{zP^p)iYvD*=72406QWLZ!n7ibU0ZCOeN(Z}%pJjctQuCgeb=A7LA;+%9m2r%W)5`}+ROIB3|H4HAvc$*;B? zD~ovBQO^Zo>7?EOMsRA~X(kwLnQ$~NuP|gZfj=E3lbRAu!YrqKWYUGwHro>mZu3z^ z7{VH_KQMk0!d}{}H@&#!2#v32 zR;5VY1a)w019=gIY=bCo_1{vtLJb*^9ZoOQ^hzsOtK~E?qh!uS4tg;?WRr)Vzf>NK z>30@J35FjMz91^&w22`R1O`O1x$UmLMIdkw|GeNMyTtFP$;=9Bf;7;sZ6x6%sv&XC z9o=z)k=5(`A%ryc8%dLrHH6QvcR)WRR08maueG2oa?JsxC;~o3j*@ezM%+1bL$WEVI zO(B|Lx@3|YgG_N;2l5G>rQ+*S2SIrkcsSC%eC?QWb&KqW-`88;VPRYB$h(8H8c6&v z3LB1-TV@8v$7^?te~7T!9|^G&;tb#09z;(zfl$mRePmJ_!;%tj`cCGW9)44_3Ojy| z7~>ePW;BBes1w-{ts^;W>E#`-lez38ZYwxnOt48`B1F-Brd0?8I>E8H|%M4 zoslaSj67jBq(w#V7ZRe&eM2PSNd~=q>Vx5$0G}WwddlKy@XDsKFL0lRtL@@$Sc8z# zQN%(f_TeC_%-{VD4`_rvW*S{-cDpR|^I)ngb7r-L$A`)JimxW?^>FMr3SBBYG!fh} z<+Vs!&`h~axOb#oyC4#n!N>Mv+?8-~crD`lfWjmC+*rFIT)@9vfRx|G)KQ5OGO8Vd zdOAB>eOE+s|Ag!S)LeR1K(A)KTGsEONi0H#L>EE7h2HB{)^`YkJwcR%B1hT=v8>&! z(nGaqkHl&g-c%hODZ$5wPo%ko2V5M8kvXUM9b;LrndAf#FFw?|_cwt3m9=E(Jw`nP zWifY1-um(PDB~f`evcAd?QD9#N1!ZKvE$%&FFQUGm;$6{gw%7i0w*4fj8(b?aPA+? z0Y*pv!Q)Blt4-a`PTwlaX$x)D%?WS`q=A=WamEs*X@6q?0Fq;+<)R=5{<|#!)WNhM z?%^S6-$Tq-eACmP-+jU3`@dm)v6O>XwfI-5!eG>aQ&aSt9PDJl5ah<`yVic zF0X!we0a`yzB1R2+&raUF*~Tz?-{o7|EMvaAKL+J4}2M>9j7vdMgU5E{?WbewK%}3 z|BZGy6KOjxd^ zdx&4t`rq5st(w!DA_(b1XO6LPEaGb`uLo>4TYU-5D1TArsL39PsCrmmhjuR${XA*g zCROE&ud$Pl3baF@I*!<#{-TvAaxzfyUi5n|zDV~Jo^PJO61$d^BEBSVY3p38dc?*6 zRe1n7FcklWI4Z4>5uHAi?;$_cO%X0Eeq^d#+#s7_ z8kpQ`${@B0B9aeVhJb0HcS0O)mm$RY+8Hm1SeM$3Dior}o{2}5dc7GY7!(=txBc2* zv9|atIL@jWRQz)I!?-e5z$A3GEOij9tjP^Tq{FDnIZ$U-vhVBnA<`Xmo=DDmBl^nec#K%@ zbwx@tP++8Z&(dGRA@i)(fd=Djru{c7`R|Y&@OH3KX%kJ zoe0KD=AO+vr_w!q?U;Xbw})bqcMo5?W^|nX6L!Sd&VJp@aWWF8H;sLHb2-KLRkJkO^^SA7?aE~dB21o z`nMSfu+*v5jyPUU;NY~G}Ssi}B{Rvj}}(&ah$yY}|vUYPc2OFfMw z>jMCkG&D4B?pS)Z?QY-@v)D3?B=57@rjbZ55Ha9u`^o131OWffSy5b^017CW<m%W~;sVUeOjG2?ur!y8_u|7SWkWsf;#L9|ZHkG}rH-9IM z?JtyNtD|Iye2h56AB|o>4+IGohKR5Nk9)Qxjn&+iaholNe(M@bAc}a1ZcK1BQxLh7)|`!mvY*yOri(p43U%wPxxcF})`}-qZP8EV3zsA> zc3)0yU=kenXc$)(;07glQdLR^CAzVZ8|*n&qL|k&3}T07W?|`CT_u8rg#}-mic#Cl zj0zzkA+f=a?<)f0;^LKhZCZ>rQ0~`JUP%uDD^ zSdC&~qFh@@?2+3r(J`TR06E5G`-}WT!ca=}JSCdiq9OkW;=5i@O$|$!(Zp-;-*3Tg zW|CXr7RQj$wwyl<(gXy%jaXTf;Y`{M?Yh?;md|zn(I-*l zge>MYdP0M*vlrD%b)LX^97Kck%r7k8Vzu?AH}ngIGKS9)S$>A)N0VfrV=M;Vvm-6! zYvx`B%&emRYFF+e0k==+&rmj9L;@})f)qbA4@|Rd9LH2@vb+XIJc-2aVJbg@bQYuzP z(u{1#ah8c?Vv1eby)oCPp4$EAR%|sS2n5(sZ(bDWX8pf&-=)M~x)|SAJ|>9kS`g3? z3b+!pGGWvl5z2~t549S3iw7o4uHx7VP5 z&w5bzd1z#H=dI@oi^}ed2h;#NI~%PuEU~4|iCK~6kXVbSP%B3iA-%Ldsw+~?FFNW| z>t0Xf}wfFeUy&?xYN~3YlEI&+olqfpXPrdyMBpklp%P5K1yt(ZqLnzuyCe1Y;>gJai5OL z7JEcjqea1gT&l5pheQ9A(`d4nqbk<1(2M3e9aR_^CZCG8BlzF$ z`HCf#?o8N12vH{$D5t1UreZcj8xg^dYd(WpHv0tRu!x8N|8%>|fsd8dwovKdj{~+M zr8bpAODgMLT}6tBWa*DnW0EobnlmX4xT9d|1rOhS<_orhh?p?@%*WUAFqFdeN5sEB z#yoIV$DYIgV7h2>OaH~JzI7+HRH0w0qYjgj5;spY&GM_e=4)JeHXS9502YkN^x3?7 z2<-_>XmGS$-&~T|*`A3y4mj9=10N?V2O8U2Qq7x&^bkh1!=m0h#yy`gOgLz3%;URrmt1E-yp z4vvsAy^x1L4D*5N{Y)+_)U9GE?C{=1On}D}O@cMMor=!R&{X)wmi%J}yOb%GWp6`g zVoggSQ@c4Pt6r@!f19KaDJ9RF{=xzQ(fl-u+jI7@L$^)qA?~>T{0MKma$$xoMg1H= z&OIivld)g^J3~XmIPVBJJK~(M;f<9|)!&|NX4@#gda`E;LR>6_0LF|(L!|r5%tLZZA+zL5 z5ld)o?D8$tgGgGjlBr^eXYLr=qnwF|8-N|34IfK{Hb9^!;bS0HthQmo7R!Lrn3-ag zBgokj6sP6E^QcZx1=c37wp*j3Kj0Yh?OOzMy#&~X7AeJ8lCY7UJ&+c#q3-PsCZO?` zTP<41#+T#?6b~7MJngzeS65dTK`4=STYoQtxoU=Np7cS!%FbL$(rZW@aCPUHZb|`( z9&-BUX1BmvJnNq>=bLj$wPOy|&lnCExdb>|*MstNdH3hnSzT>7`X=f@?iaw{{bNyM z+3kr$A}SNVoatao=dMrc;_ecB#^$kQCP$=1K`#txu+QOdEycqNGYXxKC9$LNdJooC z;Y$>d6|8u~E`po)S5h}mzTwU^qS(-9PFU7bneM$Q2NIgKM@l<; zA&65=SG|9G_{QsCZQ)lZGo|X%lD>i2??lb!Z({|KdG|N0e0I*(aDvuN-?loU_3Etf zJ$`+7;^h5M_Wu2$Z*3p~nS_O`ny!IKaJ-pOLB4p4c3@@cpP8c%EC)e$aaG5F2 zL6Hz^4KXkIm_f9=03|0l`bJ?EyKm&?1`d|#E5-9os9Wnug~>)HzVMMjK3xQq>ouN>RF)GpUE`y~7;Ly$cjDGKJr=Bmle&xI z9MAP3S~SV~5#_dJYN)T)+|)%yvu7{`NesF#m6@zN_zSZr`U^AYj>U3vBtoNyILO)o zRIL5(q=@sLgH)r|`i4g$L+8eC=Zi%qC#M|2p3HP6Uf-hvStDWZv8B@Ze_c&VgunRR ztv$pI@l*YnsO##lC6;<>hh!h}+S%ohL>6%93P0LECd7mft1-VHeX*0|#ppjGKAo2u-wpDLXoyJ<-_56)ql*t1)MyhkoE%tmhsMD91 zvbk2pOe(ExYHw}J&mI~_PrE4*C&{S&qrc5r0)KYIhc!yQ?pX84Pt+hOtgYg&v6!M1 zGKgppisK3BTD>(3oGay4YLZ{#7-)bu89*0pi692dXJ@Fcwsmc$A2oZHZ>Up?jgl?s z&&ICvq$ZSVxsTa=CwFHpt97X+(o}Zy7VS(MR<}?|;{a^ewgZ^?&!-4u6}iE(!Fqz$ z`l|7QK}|T>xt$b_b#Jhg=I*au0}uGa=<3J}x5>YWBvhkD!Y~AN$b@H8#HBV(o8NoX z;b+`EAIodIQ()|Uu;wYQxgmW{zW6DqAU~$;>f#d^-I|Cgiwrxi-JkWG8nJwNTG9ZU zpdiw@LX#;c*}TLY5)T|vuo(b1T)Y+qh3czWk;W@wesy7)am!Uw zcBILN*T3|@xoWzrIm1*Y7YyA>RzL%9yM~AF|-1yGzKJ%;^JFeR12IyP; z^QEzcuoc0bsHz-DC~Zl1L1$0o`FXOhl_?dW_kpV74{Rz{KG}71Kk1 z;`i_3-h~`|1*oo z$4X~&%uLa=okhNIEUMXVovULL%{3MgPbQvf!#{T%f1Kq(rtFg<5gO@yS|IWYqT{T? zO-|O+(~5j#=rNTAe`@_S7XzA)uJBfN3+C@R8_g+xx&P>|Wo>`DA+0a1v*|t{Rr9%@ ztcmyJFvS6UPsu?j4jPbR5W#L}nn5Hl3PpTa*TQPoHtW}%_c(!r%y8dAa!STN;#jTm z0I>1FWIOsSzz%R=L+KpELuclM-qX**By@$~#>Rp3r$MHx z@0F(z^qT%`Ol`OjeARg(rLWe9ZRvrUlPl)7)V*^b#{0t;UgCutA-hV^K=a^$vp7gHh-h^%*w16`T6$b8puR-&B6e+()+j zQ86*87VhTo1GVLbaBPUP;9{1J)D%kU3sfX`{|k8DhEwjAezR06c;R{$aNO)w>5qg$ z%;#64#+tIb-Wh-jK?HKFf*FxKtv`jkob7}w?>)E=QGa3-Yyy_KJCdJ01t13lZO;+& zwNlaWdCZ15HVRO0y@?KHOL5xWZ$1@?^mh=A@OZ^>9fC9(@wGeZ<zF>&<&Z|m9KE&30#8zFS6nG7y{Di&V&@YF^lt%>*xA-vX0YAr~=#`u5dWCvf zyprEOmXov*R%kbUDXIc<}I4l!Kvi$yuKa(L!=l-&-h%MvYHcnbm9dj!%EKB zDwI|xm5wKJ0j-TUL9QkI7X%mqW#WRmAeK)J%aeQQQMiePTJKs~o*lgP-i>fCfkiVX6WxH%PE!^$RdPQTxB^txP5@25we;^f;r=I{U?P1= z%XrNz`Ptl~WG`cTK6>ENvFY8Kor9^`n2h|?)=>z!2*Zl9kk#}On)0bQM4K;z6OwOY zd~LmU&G-@^u?YV4|H@B@pJh%zHC$Ub1(SL?MlOt}idk~Sp6#&<$GgYr6m%#Y)}y_? z<81P@C+V~b-=40gkFZQHI#`Z%$vln}jekJMLnzhCd>o*8zA+#-(YWo-Js+1})tKy2 z(mUwz(RKBJx~13Yu3wXx_5vd$oTLcbN?=uGwtG0;^WproG8+WCvK+>$Bm)f*5S6v{ zCn13n_V`D06|aAG8LEBE}61i>uL{2Y6{*DZYU!oSL&=kVy_x zUMH%36fSNX1I85PYr7}9yU#iGmfoTW>kKr=F)gt-(5WVPB)~AMR9Vf0b9g`2;Imr} zgLiOHh`1yI8tScOz-%=R-K*noZ2MPP(j6>7Tpkqf3)@JTB9pP4ogZ#}$ky!~A92f` zTQGKYv;=dQc+<(!s8!Bzmzy_F4`p>z#n@e}rQSO^)_r6b_}#R9wBfxMKFm_7^6oa^ zPciu2TWOcfIZ8TnVUqS;Bi#QpTSNVvTv+upAN{!ItQU?bVsy3wlxDPvQ))*-ESv;C z>4YhyC3Jte+{^cxVdIyw%Xo8fbwytj3~E^ZAJ~{*|CO=nXKb)oFT)9F;eg|rtQO(3 zfcDX!6?8DgQ>?R&*)sXBY|Y*Je`9NiAG=%ha94Q_4G_=pd@H_w#-Oa&TCy=*^3JCM1y1_H+Z`~ zKEM2!ZVT6z3a)Wke(#AQXA7NZz4S@OCQ7A47CM+?4it*xy|rg6pm`h^yROc0c;Hl?EN zo62cZV>+g|r+p2>R`74|Y7){^woWh8t3;Ybph_-Iq+=J}nOO4DzHsMb=g zDUssD<}?dwNPD_-Q&W<|`HE46T%jw`RsXy1OEXW>Ugiar@uuhP%8euR|Hy6uaWWSGFODWl!C0AWbUmYpOpNvy zIex){HHqzbfwz^H6lLkGW^!_b3>D+6w*g{kT09G}EgqbMXZh0J`L{B7UKT~I2V`HA zI=vq%0?~5P*j$kx!+a*vje%5NRg3(AjB5fveOj1omfC5omg;pz1!}PWy2+7V#=4OZ5+rN0o1Inf2fDIv-QZn+!$~ zMc^_+`&M?owAe%X4hNJMR7yqaHBdbe!R~rI4C z&n}^Sma5zy!7JLQIz@^NrW2q>=!~!mn6eA-=rl;py zbUBpkRQv*xIh!A?1C>{MepJJ-A390I=lR~)+mji{wUDjwv} z=Iw1j9ZGk_?RH!kTNjqD;Pl#nU$3_!{^0~$N6{&BCUMb3?{Lr8o{Pl z^%c+8pUxATDc5N1iPp-tB(nV+w)6ZzM?Db~^^>K$54Xl1iDb%g>(QxBRafqLqm9=w zG%aMbYxvd9pa1gJYh?F&!ikXIE&-c;rFctEBIHbIdJok;pqN5+XoQ@V+u?IEQ+U90=dY{m?B4g`n z#frSVtf)oimR)+C+-^v{S$(b|aI``qVOd=tI5X1|euUGh z<)VxFWbglAe`(uO@`g)Z@U`t-r3f2K>rg>tu-rFfLMP?251>nA@=1^ZhZUdyhb7rg zpPkRCjpPPcxFG?2B@Akug#16XAwCz z+sPbpqnOV5nOGL_#%!eZ&AQ&=;jpF#!s}Chtv5oG5^B(`TND+Jboc50yA;$Tad^&e z?PQ!$0G-Tn_~lc{Lk;7TR^>)(t=;j|!3=&6)izgVsNP^yD(ZdG)T{LPk^XQTM3h+0 znx5`#>^G4__a_@79H8jNaAbTdmU#)HYr}wm0C;99RQtYeI07x6#ode9R^9Ka#AX&i+5V%S_pB}2u3TDzI=X6n|99|GvQp@9x zp%IxXHxJ=0o`aK)P}r=_Tf%?grgip3pqya>l6YQtl?$#-OzYj> z!Y;9ZgT*}O^f3h%FY=m@b!|sKG(53)%kU?^Bk`0;@Al@x)%nQyD)}vZEyANWaU;3~ zsFK_@iH15h4H_zA{kbMZ6Z{)=INE3T=B?yGuWTs|(nY|&@K&;24mU}~zJlRQ;wCt2 z-C4k%HujKT3^9=&1$_Mm80~(wd$)@C{3}s=5Q~$OtJMzP2dPxZwf)3m;*Y;vrY`gi;i?fZu7~?GH#Gftd@Wsi{o0&y3^7Ih>@g6sNZqS6o=q~e6w&_h6 zHYVovImPIuMAR<8Y3g0$;sdZXQP4S(cWU;S3R2{lC~NtjSgol=Ysh-6899k!@1h{ zK2R87Lf&5yKYtZx4@+1sZUtBxm$*EykVZd_MbH=|Ug;((v6zuh__FzqVr)>Ynq`h! zWVa#A!Ad88v`on5wz9R%^3^b8Iwv7rzl2%2OpAcF*IS^HdPHu=ODC?y;BKur^&wyy zE6#5;JV;GmGwd|1#$gUEzqz$uUthm`#*+E_10U@U@zYn5RIe{46lH#;`bOpzTX&^A3)no!w zqrrY>k&z=Txw=^YWV@K{>OTwdbaR(RgTtegA!x zn2d}HhvkB-ej4OERBCE#cjV$phUG@4Z4zkZhEc!Lqi$SOy-xfg@S}fE3lLy8^1qT% zPzZCoUFLml{`^HwudAgPDmgh>xS?FDH9^4ZaYbQnLN<0VC>yhu@w9wHDX^jV68v;p zCk0DFb?YUF&#>P$@pJL#5Kf#@A2a16`^KQP2RC>51OE(qJSiDj0G&$3#^$D69z6@o zZwS}E;@tr$!=V9JHa@bI!l0=tgF%#ULPB)B5%T=U%*KX>RUUWNV`F1skq(fWuFiBS z=ffuqm!rc2Tt>a<$Uu1UIi-p3XL~wUFz$|bgQw`O08A{b8`*yksV5W5hUS3Pz#DQ1 zd3kvoJ4&wY4LKPQC}HJAJj9>(9h69i;c@t}uUjE$Ag#PBUe0*=o|`aXQGQ zs_E}d|3VqZ=l>uE;SC{i4=p8Q5n^gbvu$;;!YW>G3;!jx^{m0(^FM#*Y59*-* zar2_fj13=hA?bLLNRc4Yi2#w@;^WVM{!b2`+>R3RLh&oA2Z)A>3NF56+e2}AanbJK zat97K2F>McI$vU8aZ$+`_sqvWH8h6d!5Am{vpR=YbEB4YT5QH$9UVR`uv zkbdgz?QOoUp`V{MrKM3Io8%M}n+FGKi<^Jwteg+HO3qM0hg{CwQ0DOn={Z@-ki2vy zTs*VS(?!h6r8lqUGq`xg%*scN7HqTv9@Sbqu#nJ(oDqojrRW$#pYal5(S;?8}??d|kK~nblj43&LvZr^ZWf6%R5fKq02a+ha(AW2GY`lXB`@0n+L+N<5MyQ+mS0 zm{>;b@V01o*@!kV@`FBf7Nzw8C zgofnfnwgo!6G6Pu|6GK-GKla-q;(?ebm%ggn3r7;je3T03zyDV(s*JT`8c{WO#dK4 z)s$J6%BsyHxC5vR^?f#U_YW^_Ng}I&m~xw3S@0OClT%i|g;&)L=bnt=b+AWc!i;xaq4%do1SJtZj5NXdG#tYgY+PHZJQ zE)=gKid+O0AJ%47;^{H`f5fIscS=+HYC;$mZi&B(#$MJ1j2;PslGT=*)OwoZl)O{_ zV6Z`GOBJkOQK`LX5|K^YN8a5^KrN&E{Qy#i7pLu>Q-^#ysCdGCMo1w-Oh&z}e7hPj1P+Lr z&+g~lL5Ta-i7(?uE{N{u|b1=xxXr4q3m?GO5$ zemnUCs_yImwrr#2xc*rRmCgpcTO4fJD4%UdgK?7hYiMdkIr7Jg+@O-oy5?{tm2^vj z{x`8UjU*DS!I1LbNUVvjXv8S+RA5?F!{94Na&oh8)Iv1R)b0tjr?y&`O{e#ugwx$Q zL_0mkmyuY*&7GRvo1n*YFX6r3koRFJm3zQ*F!=>^^}{?ZU5k*&6E35 z-Y-`Co#Q0Jk?kZb&$EI>x1FeJZRQl2Hypc(iH{dkei|OkAF&y0J&ec)`7;e(n0#uy z7YVhkcNE15n+elq(zVyM^RM!-ELESl1K3J&mrjVBjU5v0@TZ3}A|AJu+A7P9yGJBo z`?3?=R)5b``gBk4tg|fLaVhXN?zMx1)<~r{_phVgb~X_Qlh&%fJehl^yx=x3E7v}i zk?t7v|F?5#Tw)9X521kAEoQ2^x}Ry^IkTfua#qswCNAfCS=YmSy!Z_9Qq}tcWyFx1 zR>kJ8b?bGX6=2uAq(rTSqQ+@sOGXyoN0$1qd*arY+PHV(y!)%#KUCp0d$UQk!>1Pq zYw~|b{OBK`aU7lNj%MN;7{+|Dg;DfQsz@_vq%4F)3>T}nPv!?I$yR$)5{X2Y?AJ2A;|4oBhVr^^q24la^_~$c z+`H{rsyDQTb0OzlT8Stq5G_X$2iLs~02NJ{5S~R(W~#V0Le)IuUk(?RCf^%W*7yw9 z{BatkHt%eX9ts`5UOb+070~n3+kw4>u-^Yk2nvBr`sgPAfM*USD1;)u>iIs~+wnWp z2;41g!5r%}hmQMDkp*S_Hy9xy3xPuGes!EIRja3*c7RlKRgW=Z)mNlBHvpJ&AVEtz zZC1v>$U3xK2pPW)Zvb?3a&LPB;M+p^qyI*NU}OgvN>D|f@D_WL>WY}6Z`An)e=;VI z!Cw`CS%Io{`{Er30YO*S*FWpXf3sY1;Cg`6U@A15b9}6S(C;{1L&4S5JZ!0{KCRRzYP84Q3kmRp}5!!J^=|2FxSfNb%tt2&S*vc zlplX4hHr8CBN1GqbBD3Y+%5h>6Vnq^XsNClD!U}Qy(@cfz>d;8bNjUr@$%}S9N+_o zh-hrM#4r^J$=C03FyMlqZ00(xt@($mu2@5u&~?=Oql~rVv}FQ^u9bd7%MofO>C{lm z%&B)0N9J5ytsv!9kTmGKoUClNJeFk+^~2-fP^w(#t3+WZHmk|5WDpxTshO4YYVRnL znX$l13^JAZN!B%*5U1#yBQ!TR2Mx;Sd;ooB@5khY^==J^4}=|2YsU5&9A(*J`}N@p z6|QEM%~bZa0t7W_UT=G4yvE}^fJ-1`Y;1fHU#YXlBZ3=$4Wp*~pf&Ix!>o{LrQ|*} zWo>B5!hIaD4Gt#saZYa@J5*T`&$e?7y-y1zFXuWg(bgdD%%C5|x=&Zx{4&cx;eBW# z71^hSvz0`dWpgAOlT8sJA5N%a4pm<#Dg1{g2NU7Cnvrlloy4rHE)dgin~#3jB(-K+ z=y8xlkr?d}Jq{bO0ou=KnafxV#mg7(j9mz&J5}(fcDHOo-N6pus{dAvyHGGvuKrFOp`up>f z;UgKG@>Cxv1?89G6xB(C0hQ;oGrzXkPrvpXwewZJAk*8+hX^(W#ySmL9-uKue7fD5 zdsR@k7y(Y4v)9r7G}57rLj0&JP71~m8CBNzL1;8fKx z(_kw`QBhi&3tBe1>x)Lg>*r8_dPENuZw6-L8zgJDOnn+TF}v%XbWZ#aEVU%*;ziP`%v8n0EF5vLA(;QTh8(fhcpx3Lte9LYa~>%3|Ph^YzZ4mj*o8mKJd@TF(gN zR97&2Zo1$vookarsL?%bs`3c1(z4|*u3569(%XC3wT|PIh$=3#?=3Q8dtqu&Zy(v0 z2?FxtrGY(|9iA+;FQ-H+q{8%OsWO=b7y~sO;LJJCdi_b(@&up~u2UL95+QognQs1O zGmX?Lc&k%JJL50(6m&EwB+yhgMy0(LZ2~6r0fp;bb?#Da9+JjGwzMDd48ODAr7SQc ziwxcZCzI5+6iZ1Nc-qDf^O+`RM?uc*(_2-!a;hGh^WFo$h!e$ti}Hm#U$8~I`X+f? z1|=oR-DwD_FH{G#N&T ziCDS+S)ZH+h554*NGPs6N?OcUp+k0qC+^eUiqeF}r4-5?*UVX>#&j6S6&9q(}#u}t5y9o$ujJr-|?i?GF zl$V!3zogY`fB0517EV%P-1&# zG0prD->V&&4kri_eb=+FfLq@(vZAQ^*C_g)^raTkD-)KJ#d3`jgsKW@2;@hDBU5#6 zqlCc@#>88s>;pSQ)_Tl;rqky!`E8>MQbk;Eu&FXW)VMcCqQTk8?tCg)%a=%`W&ZH* zvl$f?g=#g81n~~}_3sk#VyHU*Xi($e@nSV0yp{Ct)h1*Iiaa5wqGxKVx~7*pW=!cn zPM(lu6fVmjW%g-mDdBocYVY23(Ucz4SBT0!`k$*5a`_7#B2v~1Sy6aq*m{Tr!d24qzq)Hq7 z-o7-4X)1YdvGxVE;Z#thX9vkXvfS?Syg;qhmWSOTSCc=nKA1^_>7$5UAz=HC+E(op z$o`LwV~9q{ejy8l`0673hWBiU@1ekNx?JY}fvvev?Pk%WOk(Wa7f5}ar}OD$1O2y$ z(p2JJ9j4Z+SlqtT-K~N*sy1^;T3t^hId>49^!WarR!LT zwwcegaDlKogTMLK6#w0H<*i$TcWYd^No;dU!ayWF*6yqYuuj1Tw(f%3TQQy^S*lj> z6KDZh(&A26vJ%Oeau+)4XZs5Z*lTQ9sIwLWiMJ6c=Uh0Qt^xhb&8qcYkun*kz6ecCw?b=A z6mOJP-;Cit;WoImzpl+N*v{`0Jl7g#3z!)niX6QOI9OOf21e9A*Y28pg2Xv__qu%N z$mod`80d0qn9vz%U=`Esa8FO=!LVHQG+itg)OsdD0Q>QXZnpwHz{|Qou?`9ZNyS(| zQ{$zr;SXO5-eLH#6F9&z`M03tnM{_)SO;k}&g6F1I?g&rQD~Db4}I|1Ge*MY4;e_f zyHz0n`#~&HhhQRQTMIi-MM|`eVgBm*-*T1p4D-5wWgVqKRJJmj;}&yg$#! zBv#Ld9x-?~cn;F|?foU{Q#SN>B*Byq%RA?1m&s#mzkW^({XXO{m&eFad%eM%7L@_f z2s&&)vItK$RT)hs%d6Q&DSL+qJ>t11UT)+D2}!}{=pRgd;mip6?NOir1uqM0z!$`H z{ed?PrvRv#nbQ|&A@#lS(mJal1G0>*$7WPD7v^~WWdpozASPLbt^OcY%N->K}|2WRV_@c}T(BEA7e@Q9A)+~6b0f^z<76y$~31FyC4f-(GOvb=RFZV`sz27GF_hd2u0eDU0XKRtz zB2Tc34`0tjU%J$hFX$t2Nq=zFhM)S_L zu(%UObKTwM3BW`XgUAC#_56%bj$T+CS{aRe#HdY0#~g#1VqX|Uq?cO=1h5A9B>Id| z5qt>MY7R2!7CLX%8Vr=K#8%%btFqu#t$yL-DKq8JhX%Y=i+!Fa6wvgJ@PQbk>~jDn z`xbnUoY_Oe7kvwe+Xvgk2{hQll*3oN|F*pj5&hF!p1#rmH^d2&EdQ1(ze8YDFcrc3*cCz?t z#WHX&$f&O{6Es6{Ud`0HXjLeKUifYdA4oey%)T*A`SWo!+V0+%kP0A#0r+MW)@nTg zX|&K9Z9yEozeu+`Hd_lC>>6^7y@-oRj?NE);#A9N{^%de64j^w^NGu zff^JH9&I`%9g#(Ui}}VOXM?!;jyPXA#aMlJZicYAUJ^K_X;#oQX|I$*CN-Ykn(5(B z@YYa^t5cA1-$)0O_3+8N{S@)kZNM!9VgzvG>6YOzB+GcqcT^x_IB`fs*n0VXcIjPa znA84eON3kkY_Ei~7x!;2>eD=B5T_!}fdmgd<}xoj-?ePc5J}l7)di5|O6G(e}$v ztrtT8uMq#9G0E5XlpG1lcSz6$*j(Jnm*;x)gL7Vka_a($_CF+mx;iXBu_=U1*B&@p zamEd2hpD41S0%z}8SGdgi<`;hCWU4@w`r-SnoEj1nQZp>ZzCVvPv6c*5$QH=;W<*r zAyoKdbRo{$bj@OMzRQ{MNaOa3#y$d%QMrUQbJoN*##h=oJCgSRwLy3l0au2-kB!T7sy>hlrvgHOx1 z;{XVZ&tc{`9W-i|B2;T_s+vn`XDOQ?HIRXI=0l(x#*>`I6ZFk02F z_5r!69VVi0eUZPC`r&mv{T34!f1`LxA~1pl<-n<#4i$;avHJxCW4#s<@F^jWoGRCp zEg42nd+pv7#a7^j{OQH@dvZy`3i#yXD@+x2Xrjje^x}`Go$5pBn_I8qwL@%z!YGrY zNDD%Kr_2Fi2X#8yzvs;RMw-t)JTlVhY`XbVox~z5Mu$C-GpD?nOI~}qdArPCJNd-r zeyke1n#K2ZF!LvQmynZr^Y$m;k(`ShVb>k5q(<+R?OmY+Iea{=qI5*Pwc-JG@iFae zyZ~a|T;{aF!Zz6U57 z*@A@r(`)9}M?uuE1+(fZT7R7Y)caFMN8&3(#|%3^1Oc)rT+49KP+KGXt>YI9y~tV@ zc1ofjup2%89C7w8Jxe_)J=*aHTxOgu4n)!Pw=qWx1;n-T{WOr>ZJzV{K-#XF0>lkV z1T6*0xSqA&WwZ;ZjuhjRLnII!?HXG~2=IvuO}*!#LT`OUXPdBoup$= zVA8A&%@=mC7Z#DlWJv=nLUo!tm?l7ga45?UybrO{Pi4aAh8r!TcPin2!{f+PRjeK? zZpPUHhlfjcyr zy`8U8{;w7w0I&9tP>i~1&Le%E4QlP}y#^E{N02Rzv^V&CY5`eu)cnqQ)(kjFgrU#X za&G{ObRSY}0f_wxp-k1~*A@i1G}i~VyGfW0XSgV(Qvn$oP}of^+cXjXfFSoc)SvxW zwQ4$w%@Xa_Etdcd2AgB2N`8y&5Nqi(PpCTlDoz;0cl4595-riVB-Z+W8>!g38+_O* zS=w&vUAB0?Y9hKUjr@63qB(IWN0!v`2RZ4RFN2}*45sbp=#i9V27_}<2W5+2?siFP z1<^l-0b8BXwVmJ7`8+3+;N0ZzZ_2nmJiiRAUk}ww;yz_NIV4mzR_4{vgDJBoxf0yFBogj*(H^+R-BNw_;Ew}L_Os} zOyIrLS91X_Qj!;Z8mG9|D)4NL(YdqSDb;2?CRp{0Sq9nTMMp&7X@HqqPhQbSdmGNT z?qW@U*Cn{5L>P85hSTlG)Q_;J zoBaj@Q6p^yT(s6A7{HS^{)4@@a&!>sNE2rL6Gzfv23n$Nlu-3=OqS8z-gq~FYv-Ep zZ~QNIh1xK^csdVqudHDP6l-{_zlkGhw@&nf1B+o5%89J={Y{sy3855c$@=TCnzWSDv` z#Z1ai5ur2o0^ueh%kbYok0$c25;nz?Guv8r|wRDVU`J(q5XkFSro1Y zBTuhdzW7le8u9@F&|I??J#KSa$fpxi4VVz^(FLUkcgIr7aXvz(2xuqj>|qpX11xhK9AY;TJS&zHk?j~DC$#jx5wazxlEM1ce^*+${u zvY;aIAJM&7e!*{XO!_Fb7Rt=mIx-0BX6@A)<1c2IRMZ-tQiipAg}Cp2sqJudLEJ12 zG;uwP^>yU70v}DaeKpDwkWyD7&zJmcFkn@1SA(6jM=I0sfrHr&MEWd}L3zF9D~U7j zypuA`cyqU*t1=PvSZ%-VW-7mFmLa(nBS$ zp)(D{V{dh23!`vrKOGXd3wVeE9M8Jj`?)&ARK5=IA)H2vUMd*`(C5=m@-!CEaJbGN zO-#D4)>^0)G#G*uGtsY(I@=zROKWel+*{WaZ4y1S`3Y$6lD>FUmMKUbk51OSx~k&? z8T;|i=GTq4j}}ixL$-ETlcERMCRG2i3cVmv)HP0{$e$pTkn|%D7?vsU4bAbP$SpXENMIrk>tx7nQ=>l*ow5kM2MK{9jj?K9h2XM}iD$M^=f0&X1~p|9Kp;lW znJtx7OKKEH?Z zOeZJ&ZoA8)w73SUlaRpPw1EVIQrnU0FPKb* z(FRkL^i2qIa&iMR&tnczEchbz4j#+#2Q%*bX)q5+cWO91hpC)wRDXxF9o)pdi1+f50_Laz> z#4VfO?^m?f(v5xU^j_OIRG||p1auQ6+?5X{A?l`rqyZ8G`&Mns#_Pfqox_0l^z>C- ze$t4jp9{nv^*OAS)s#*2vO8sDFM$-&*s7|&(upl7vPyDtvMk@D6=!Y7SPS>s`Duf){ror0dIkz^8`1B90gxhD&@A2@T@v!trAf+Hy3wa9 z;hEfg&~dR5S^y#~#*GdYRge2Chhr0oiHRHw{R``$J(P64o%kRRqf1lrQt;|j5(EWT zB&f#U4nn1~}J#JxKm1+cJ)U^3Z> z@^J%`EfYGc`dQhHBrw_7GG(qz*Xo{qZNA)L&gYX*&dirj_iMXQW4MKws`OF)`V#&l zDm}cv(Szc0M=kEn*SBipx_gx-a-~m4CL+Zq3-x=99ACfQ9}omW;<7}HU3I@`FU8gc zP^_|Z2{jQpkB*dhFcPL4eq-uoY$Bsfm z&C+}47kAit_eV7on!(qNAM&4dq&!pIrJ(|8;!oAk79&JOL?X-4UfJC=p#Lez(0m%9 zF}Z+nUDN*fSTJF-%vo3gYr|>tpU-1-n-nqV)TLij7+ZOn%f!*Bg1x>Ug$Y-SyAQ=< zcr>Znb7i_n7%S~FukdTGaK=LLP(`FJ*Ib!#*-&1uG^~97 zQEcof_}qObRnkOxzIV5k>|DVnl+gIY<#IP|5ZT40>E(#FpY&0*_0czV&S;qTbdI?}@xeq5=64&1A>4Qrpe$%${CX_Ye_bA<|14&bO7?P1mU zg9*Qbi&YwGhwUW*DctcQK2onaKA)}65l#)nC;Qg#t<0rPD{!UfcNzAlZCH*_)*SQ0kmUXQ23aopa1VO!Qh#PX`ksSGapb+CJ47OBEw zset4imC*v+2d5De{8;S2S@bdBARSm~6>s~#hlisYgf))pU}wIAGeq_>3~@_zJKuOi zOiY|S4bh{RF4Y|X?=&F!r*~_%PwO{Y|G;x-pxF`E@+8Vu3lSkZJ3Btldo+?v%TvzG zuYPJJ-0mqC-IaSTDN3b)jj0O)e+tt-BBH;q?L{V~MITc7d!rkj{(}V?a^M)m8uvec zT$hK;FJOidne7~&3#G|pK-w*Bu7B}oNQcYXaKvA-sekU3nvZ_}UpI%oe)|Ru z5gt{x;Qg~#a=PSHRGo*E+XQYU1!&(4$w*1xK=k60lG`>&|GY(yK2jv0q=Y)`vLyAg z2SIY9toytkDv26_rX(yhCyQC`GyAM=33K;Y-}hGq1OMV;cw@@P6a2^?9PnY=(f}eU z0y#tmRoJ=S>T-tF@co~?M~LbPM0}<5HhZ(|K2XsPv>#C6DeXU4$oCokOjxg#Y` zk>}ALlmEELl14zXd-)M?7@td0W0)X2ehgX@gbKhjp+vwJW=?{jQUD%SDX&ThDn*?{ z`+7s6tg?8$D0zExcEyC6wyO8EVpe9l_JRdF@nR^yLs{nOg+*03Cvp|0{+|mM@+_wd zZ9>u_HQ1`MW)iKXj``M*8pk8U2}s3aa)T13;^7 z9NV)KW)EZU zUv%mx?D#fO`gI^wGz-<~z}5DOCnjFB+QQr*?&silO}@T4VW8Q=(g*j-#o>8|6)2*+ z3awr3{EKISdQx*w%tpYO@xcsy-NON8r}kq?3pO6X$7xpQGDQEsk&5<1FPpb;ACA#=lP>jP)fMD!l^5 zbA9+Dnnq^=35r);1nQqAM8(Dpps9UxezlCBgD6A24BS71<8XTK()33oQ1_QwuufWT z^cL#Q)VQlWAJciB` z?JKag5QMAX_wiw(Hx;6Bp(BQ9_3+TBxsyAaoGH%htlbO@pS`Kj5>=cXcW^0#n6WD}vtp=BxaLfjg z8zRhPlt@f0kHbMauU;Lz7^z;tk$4tlhn`IaY?W}B{S(s&^IZuM>*&%Wz?s#yy)rbu ztHWAo&d!gjb_K7eb;!}&FH$zQ zHkuhX(9?IAK`rg>f-O=I__EqSqU1FjIU3NHDJy91%VR_+t{7BT6k9Z(`|??!f z+QKby0yGdDf`#Dj?iSqL2?Td{OM+W)cXxMpcXtak?%LS&efQos_2#{qs_B2Hx=x)_ zXMcO|Z?Cn!ZykR)zI)V|<@}xMH2ihkEkncTOK^{kqyAL)el7iIsPJ!O| zldT{H`H9jRYnrEWtYkq$6@Az1TaGA?C*(X=huJe^qjSk&q&Q@sBrh$UOP2e_& z>FxToFE_I5@+OtrTQTp$@BWLv(NcpAKvXVGoGx?ZC$ES?@m?L zxBa%_x+MRatT?|PhdxXV_|_Xip3e-2&cz5y_Is$0H-4DK@JGe1X79t_Rg1}`lWeKv zD6>`TUv$#Q|6T>$T@c5WC-O007c?A$!c()e4KcA$R8hVrr6v~d9nt00J3_1r^rc9C z_<*?U!RQt5FRfZF`R$^m%U|equ$q&J-3No6JOvYL8g#RRnpcv!Q9CPlVQBm$kB!if z^=7J3Nqwg5hl=95Z(U4G`;ZY#ft9(BU@a8xnUIAQtv40nkyOmL<3~q)oVT^upTR2Q zYiMAJT?RrfE(91oWQutq=-!ZLOaVn<7ruM4JGy42!t+|EY2+#=^4)2+Ia8G9YC&E|WEqeHzuo!-br z=*;ju#PK^I#ZeIUS`DN14yw&cB#>5J;)O@bOa)aK*rd)^0p|0RuB={EU9j+@CUdj{ zfn^FW;cNyd$l@Wo`cs@knhTGTV$D2MMjiDG!a%Ldn!^l}w zu>)Ikq4}DTO>GrlN#n8Eg`ml-zY=mmUW((r^JBufxEL?rd@P;#>cL9pVxV-nraQ0K zwj&JC%vR5pv-4U(yFcEmx_L+qU zF+tRVL-ub)38hVr&EMMoS1<17Q`l>&efAe8Fl$Q zMVqqv3A?^{^7mHecRle6hf`jAe`vTWpR7f>rs)6S*on7;r3sNsz=<*JB z`US7s@hQ$}#ThUNYB>fQho(;UXYveS8N0e&;SS{@%~eYklndgv6yOU}t05A92?-g_ z0`-^W*=iLVSf&hw(<9v|#zCnM)&nuJFMxT zmQgL7e?CB|>`;f3%jX#z8k^8;sQm%rRXVNy`Izhz!-Dg}z!IV_zeg;YE;AsDTzqS9 za$~5a^0%@A;l6t=g2`ySXX8vIZa_du-IRWrSVPd}I<-;)tc)v5o%+pq0+*)>I~Uih z3VRg~WC`a@D_<}QJ!Ray715Zf+MrfP|I)_V$3&SmNy*OvWU;Z1qpA_=^t4R3X%hsm zbYT^|(B^z?_=!5fA3<|+n;a|SSFshEn2%6r)z#fl@I3T<-N`gZan|b*e$u9`HNKNP zadB}Z0z|KtYOLeqpTX(>$#^vJ4X%o8-LvYSL|Z@wHa*WP^Jp}vpEi%pOQWllQS`U0 z#XSR?*8{iZyhsVeau@s;J0bLsO|UKxE=*SvPwphmsok5=h6}{iR`4+OEK~*`1ePO| zr33k)6*Y*1HgbyT1qO;2Vxu{7&pRQxa&G~Fh*8xAtjCFCD@iR*@5{7e2ipF22IwO$sZr1?h=h>6C&^WzHQJIiaO8}a2k||@- zL0V6wPI0$RQ+NFw_e6ob;< zmP$TB5oEvpnt&)zn?19r9%rggEM`p}Ggi-%w?V40eB$cF)lADVxqcj$*)ZuOU`s=~ zr%#@){O~bF&e%9q4hkcZ!tSm}n)?l2BKF6VPW>trcL=3$($9NU2xeQIGKv$tPChLK zKsDbb$~RZMpJr3UY%&Ffaz%1Jts@O8CE%zl#wabC^5Wc!ykw&?Ey;=)z590eO|m`g z`a?Cl(H7@qcD{dUMI~w~9x1uaV!YJ-O;T0Hyx^sf4m5djh_B9sY4zKO{w%Q$*f6so z777L`{mNn-+gyRxG?#70GVp|2S}@Lr9=FPwm(x?WFhV{M`r)tvZu|6)I_M=2GrK$G zt(5LeB+p0)jRvmXND;dUk+mIHib=OLl)a*mF?%di9#Ezos6q-qQ>m;}?yU6UaO`jp zcAjDKaK4dD_SFg4OTxjJGF4hPa9C$5kdc9WlVNtz=~En9v)<(yL62lw`^Q!a?!Nd& z*N6STqXbC{F%Zl3z&U1N)yI4+dR&>TR)J+QqCZs;v|oLA=GYI7zbd?B#`d9NKumW+ zV||VKZW+c&YNp{?fu2aF&_v_?&Dt%odxm5A8UC z;?GgS5pUmd`3uRX^J-~LITfxxS0G2};m&wL-BG%3`#eiI(U zwLSlaohWSI41^OqYc^m>$G7rOXQ+?q2Z2GmzupimAPAd@+k zftA?U=p-V|j9>d{4e!rQzC_g$-Ug6DuPt9+*3-4nD&ZS}-0{eoMOkoW8(|@g+)LzE zIy{T{q7+bqI5_{7ZO`vWOw8_cBfXxYxvz15IA*PqK`bmGRXxx$h z^$J$`#rB=G`*Ju5>*hDndN`e;FPIfGzY!}T66c?-d2?1#pPWU^68US2R82VROJw+* z6sF2vDizvkMv*31WPS{X7q^-A%uoqIFX$Z3t$W`=Cdb1Y>YyIS&vr$(Mp^E}$XQc- zaqN49JD~`-Ymw;L5YO9v!o@tWng`*cPkd^u*e)LMT<(HSaRzDr*ZO;OUU{4Puvt?-%8jhm zClm{#L^iG|Uc9xo1S|0RhoDWTUCBpJ$N?Zl7?VTOR}9*@^QwDiFm1_f+P-UO0zdEL zcIQ!lpUnq(5kqyc^i^+~;4K0=5^GuOhlO$c6?E-#7s_4m%VE;rxYN6QAQI4dZW|}= zN}E~EbtxifcX!wQ@sdP9fSXTqMkpY~fx|NurmKI<&2qvSg~sH{rHOR^&7!w({6IM{ zpq|!7*VFex;RW9!ry8HH87VXrw4I`dh8Zngtj3eAN@H@F1c4MEHI_ZBJJ0X6-D9k1 zldWmN6b?@Z$w{SwR;eFQ4DSz%i4;IVoU3XtRWXEFa7LhLnoYzF%N*TP`hm++Xr!KR zk;;xCICpH@FGT5#-f zrcStTf}=3&qhAr#VF*xUl&AQ!+>a*p z692r8f*KQ)S)n5RaCoB}&Bv2JM%wE*2cPg<#q zs$-A{>7h_(XkC8%k!Ru{rpk(?GTVq@&Z~89zt|6DwedIAY(~#&i^wV6cKdKQ;!XZt z4+rrGODiqTBq#69{T-SZr@6(jv~|BMQZD*av3Z*+sEcd2rl+x_+ zzN0nXwNBLPNb<_9_jb$!DW2Cli#HN0n5ey%1M}An@B+upg;RzCCD$#Q!TEIdrvUU< z7W!M5=tvr$805I3>TAux8~(PlL@q4)uS#ZC@!l34SCv5%-_OyIjvwBV5io*ogju`1 z5mSZlU$J191TP5wCa`zKF(bNDsQU+Q*!;1H&_)(J%tE8Ru;D`IguVGr*S(_d(xPg7 z*R*;sBux2>{?e8Wc1qC;YFN{c*ErhuRcYf3yxhZFLG)MOSDe8iK+=C(IN~xwga0xM zcDV6=ZT*q^-B&Hs6U{%qx-yx1;PCk*j_y9k(N`L4Jl=A=C8KfTA1w3{AJyGbP`j$T zd3hhLu*q^D+2#r7GswwO!qc{KH={+c)=2_aMxZ>(dv<9dsd`UBz<=6a}=gn%% zu}17ZdwUiDz+aBLzk8`^s_8!{IGqmkgr)?8(7-JM=a4_QCHR=7o0*Ly0gq1!1?fr5 zto6T!57jdI{+>?l$v-ar#$ihfMex0c7CQUg_iS$>8ar7k?~RN?vgYzq{@#iB~E)y$amWAz#TTb zov}R7L;@d5kd^lGntgmZWs2mpClolJ?q-+f8zi@4itgn9k(jNG^ip3aIo+Z83f!^Z z%~iHqMSXkt6J!pMUh~9;{=9o2=e%yTvpw~A`G`A;s~@;-Fi>3*JfjrL>jvTG|2Lky zKQ%)I7EgICX@$A!4qv)1==Z!u@&_aSc;9`B3ooO5VjWFv{VAC5vSOBok9#21GBq^YKy~Na4hUStKmwY6~eg)Ak)({>fZ-N{mviE0c7m$z-*s;;{C@*uBfc2&(>=W zi*~#+DMFkCg!N)ykCUu|wxWX{Bam)lmpKdJ=M+4cy{D)f#~=MGD|BWmb%=xHo--4m z$BL%TPbDHhu@~!gQD=Z6j8}U4#w#4cVK+eNo?A=?)TOZSDjo8qJnfu;E*NRO6|V%% ziE@7FufhrkIKVO)ty`zrIzIV=V*NZgc7XnV*wM4!^Sup~KH^1}fSHJ9 zyzsyXK`KWSJww42drKZ_I;8!-8n!=?|6Rj&elxf1IuE$*ACM0Z%;3%FY%62T75LMA zdJf~UY@E}OC$>N|&QFlCp)~e6-Gz8QPo!iQv$3gP_e3c4w>}*|MjFEsv1mu;WVID> zDvt*J6P(UqeNkyNSW+c^RrM~g#ZRB4=S6&Vh_;@r#y=O)frPZGIJ$vgg=B^3rB=9? zzp*a26m~jD(bV|8C)sH@gopSXcj5$6yr!C>F9236!1yKEt;E9d_ez|){iY#ep;=kYcqV_^N}bt_ytrKDT9!xe-CU8o zW;-l&Q1rL?ZqAbA_NGXB%+M> z=-C@o+58CkhAVm_4>=v_jDzoUwNl1~>(W71>TJI_;UbL2f1j(WBR`w1KNb>(-;511 z9SyZTHXcn~_FT-i*TXu5dI;(xD9~NnJu!#|-Q{Ur>68--1|=k^u$(jDw-CeuJnVi& z8vmJf!n9ouM$3vY5=tt3Y)i)FzHiAO24e;sMBELGKx510A)JeUdeSo*fRk42p*lRX zL~VLrH^RMVcKBk&#qi7x(PEtPE(g%A+7P(1hCqg%FYJTDR^J~zIxSb&=cp4r{1*bS zC3NQP>nZ6$d|LnR-NWJf5S@>wG!$ypDKPEg-dMSowt+vgd~p$*7Cn^pI>;J)I{4Xr zG=7)%bx#4vRJnmG4ZUtK@>q2~ZF|(j)v=YR<7Na_R#+->^Hz{74DsjRC3{35JCN?H zbGeeUcl)4JqV6$HjnHL+OLP0%k`o!A^6fnxMJ?qba&GzuWC5yNE!LQ#mTY8ie}seL zC+Xqv2afdGn$HB|_HSsj#WIce;-fu^La_=Mr*gE99X!EOKkxTMUWoevIY>fEiu&xk zUXh3wZ^AkmzCTGBJ{07!%Z#?O4v<)EtEc^Qs>wP=;an$Zt zPo{RvmaVk6+I|rGX+3&P;V>vo^{_3Tq2YFmy#TbeKiqcmc;?Oc0(G}CPPl$`NflcH zI&C!ju0`h`R`mp7LVe+#WZZXuJyf9on7}u>>Vji$!5)W}(Q(I`Yjkl5&3g-*M|36G zKvC^&0_8mcu|@D;YzYht4j!sQzIsN`^9$WQGh@w8fJao!@mAWcL^hN=6i!7(Avs%{ zDHY@XF$(&l>F4^|a8)TCDJ{@#74OtK7L((3`$}uO{&>9R>5shjXSTlA1LX{xnX}hPx6MSDVdPguh*%E{=&Ej83vwVAW`QqMwtC^>j;tNtM9?GV<+Yb$n5 zh5n&ye4mSVRO5CMfWeZBCC3ul=@w4$+(rsKL;1gOu4j&p(zeVvHR)mF{q8W z?6}wtkr{8g!_&l1e4)BaH_keL8K&oNx@s89@fq}#dj0zh_oWLQURn$oHM3Bb5ZWr; znBa~mC>)7LS-HuvB8Y~jiQfuwFM;_VKULUuFB)SEdx*$}32>Pn-dUtSwln9GU2^UE zo$B$#)X9~1TL^yhgHnbB~00UIKqWhKD_b; z2lIJL!^XGgUS&~pP zM1#nYJ)%1kyBD?;v^b6HwG^FxbEI!ixXQW8N$m%094(Cl%UTg|z-gzuDnNrJ59_yg z>dI-Jq!y9x0b_!22H8G}gj)Ty44qcAS;8^z;;L>Yx4|lPuNTXP?4!~d!1FyV2dt00 z4lC<;b>ZOi++p%J^@zn8D8*q=U($xF@v2c2-U!)=e=}u&j&R%t8$|9`|o%$bRK8!SKinp5CGhI zNyrEtq?T1^&h|SwIoai4JxZ!IOig*1ue19mx?|^YKQVL7eSHEv%0zQX3;$$=*IGRv z(ji%K&c9!+8grSGu;{lZR%RF&Dm#Ndr42U-Io!8jbRAecp zlecPgzf(R)Sf>-nsr4S%|``O#LF}>;}hpxj@D$w$Z}1gEwz97`}Qv^u4svr?`lxVXba>EP84og-y%6GV>*b&1uB}+Eh zF({dUL@d*wmye;%Vpi&>is(!l&`w|O0G2MKW*M+BXy4g?W^`qWSDa^g#yAD(d7T?! zV18d8aE&^xX$l^Wu(?MdoBk4O3^ckr(;sPGVd9qjZ~Ro>>pm05(@bIn@b|vce2Q~O zma9N-r?%Q_$C>@m24Q6;uLPe73u6lXS#%dgy3aF%F#E;$9e7TF*@-Q|-=MBY?@s)pg5Y18UytLS`rxAm$V7;}79fqb=*$rP2d2=4{bFC};+${RWEp?uNWQC2rco)dt0c=8H5sK!brM*BJ((Gv zZ3N5MYsa@cI$?jja7QTshh4R9q!{=AAi@Z@c*o8++L)yx4kiOdt@T;5)Xc(X%qF~f zc<~Q-r#5|_6)}uk{O)jdu*biTY{UY_<9S5S=@qQ& zIQ~@n+CmC@rTFnc0nQmO95X2H+ih~9Q1obJ@&@0)&w36n*KcAM2=iIX0S{-CGbO4l zIE@wCWZRaqp8ET4KJP*Zrmo8p#NX$3<<`UHd*=tyII~u7&o%;A?;$>Ux5^vEo}nk& zYE1&aAtbNxsML?*&zGQLo0qJTkE3~e9mA?CR95d(~1H)39)6mI!1HskAciG<$orR3|4=Mr~* zSH|RWSKF_k=C{yhV^qEHgj`O}WRlGE9L^7A?6*jSjBP1{t|=i+W}UGet~B^ZX1g zCWpwJ-YHl{ToGhA829VguaZ~WFs@z6f5`Cc&n_u7l{%7!dmois1H#f^x z-JL9z`2`~)o0dLD2bWpKmI`=c7Wopp$`bN@3+K5>dp)j#XDHKg)mNwVeJcZrt@ z#pujuiY}E!pAVG$braU7@o`my>x`|1me;g0EE%qn#KKPt!+v?iL7Ap!F zb->2dbc?Cz`KLQ2i@S`}cpE#Fo9`|JP=lqw`8!K^jQOA~zHx_fU*9FAf@8p45col! z@`U*Q$NVpsbpYyz1)nSzm9ltyMS3>V(u%Y$(Bi0$7SKogAfVMxowLD_S!ZE=U7cRP zAPuyibGjN+Q>8VJ|B$f?n3uP@vvbklEGC}6Qw!JBDRn)6vpjhMW;WhEOtqD$@n@)3 zq^LKz-Kmw`>Q@ArY1l=rVa&5`byO|hI4RkTvz3+i&>F5CPyioSl z&6-=!f3{k3+qo@_tm?AY(Um7wZW-vg9y@?|Vk^r80anEz?AcP&gT>OgvLx-suQ)DB z#~(`--im@ytjpn=*Gkk;1{SWXG?c>g)V5ZwWjzOL#$PoLS_Pq*nVF9ptd>|Pi%VO5 zUqP~4+*Q|Y#X@b^rT11F26{fPYMf$xUoe z^9GIy3$JmFwj0uGjW$`FhGuN+ZnRVWBASz|2<0+(cFF12MB`UmRk@6Ei;Natr{e(vacUl=% zrK6*ZD3nVR@ab|nS#-WYZh9x&5{DgW*y6ktEP%0F^qpzgzQH5BdR!80 z*vXQL3jI3~e5)|$vxlM&1#p=z1t#y zD9w&K`)`FCdC5p5Iez66GWPcL;tI3;o4IG4^Jfvijz& zL;&TcE?)n$ZV2`#-N%0!CNNm}1qq$&e>>v-|6aoGmZXMV8||yH`>p5Ugm zNYU|X!S?I34gbrIf%i9{;==Lqz%69!$vp9!~rnxJ-(c_cd}EO(bDinz|vZbT#c0d+B{S-d$dOgTxvAuhkk2 zn9$SpEn+FQ=gp5_ytk?}^w*s-T_$hRy)K?Mf$4F?;`Xmu?=^e9W9zin3$Tgz#er>+ z)Y8yM1U&F)30?(Vl&CArUg)&Z{1bf~=_b13I?^aB5+X#6|B!JczlLR=c7zcAK( z6XUgX*EG(p3eIUkCKB+y)$$B7hxnqoRr3K`njRC8-WhqK=I*kmY6-JZ-y@+k`vZq7 zbx=a6z$*B!NV;kU?aUy(q1q=)=R&nEzNR0(kz-2zv$)X4wCVh1vqpcm_#i*08whA* zD}H||kL1~fiA!TQe!O2t z`k0Y{E0k0by#h{iA(!Y|dkQ4UKWi$9HMZ^e(pbZ!LvLh_`Qa9q08m z#80b7mZw~D#L{=vq;I16o0 z=8dJZgCq(LA--rkJ)lFN(hF-1QRyLYy{$fp97AI70Z8bo_Z+AVDmji?{#w-{h;sKXn}l2sQ&ofEjq+mrNKPkt!9>G{)B=M5<-#^cIv07Lq5Ggjbe| zsrqML$~VUs_0;jPlgPw&7y0i??YNq18Ql6k_Y_Ibf>Q4+EZ;*!CV+Lf+hR0JlbY*(=XE=2jCc=A zSm%7+y*Ic%)}syI|MaFf(^%Z{EX)W`Qo)hGZoM~gan#QQ{91cqt|iX%TN?`;0&%HZ z4^C^Tm>bM~aPQ3`?KD~+jC;Wc`P(B-dr#smHu??Lnb~`Js$tH>jg~R(AW{Z3+naO} zM}9rqJDTiF3#k zPWi^`w|x@}GVt7aBMNpiDaR`j zE`Q8*q5Mgc!sqs&MEv=KgR42da4kaamZ8e_mHewGwwcM^o^FPwQeUU4MwTSFx@EP& zYQ4)ZD>)fA^7`=P1niA0T4OXYJsbPvcaeG<2DrSyq8Z?Lnu{ zv%fWz1p>H}{wbU(BtBjYMRGog4W+02bE1~XV2$~n@v3)0nyZfy;2S5()k&DBIhM_s znf%c;Z`)2G{$Nys@Gnq(w^CO6O#Q1J*pl!Nhc1M&VgF_{=L71_ z1H#ta%F@S&le$YOBA){Imx0o#Mu=qYLx`(%yp3N6NQf-AMabiH=!08%o@mRONk&O# zyLk`4Nb!F*pR#3&*OeNfKYt)}qx}qk2xhQa2Ajt~0Llp=sZKW{5oDgfnU(I|SB~7i z=3t4A1=kKQK`1&nDD#&_0rH+Mxg&~=M0Yoyld%^Tv*|ybRs;41MeP!upNdNnHt+&@9!Y9zkFBLYxi^azobo*lz5B2mnK@dAxF_~S6)I@BJTdx z0zj+H!K+!f*4RJcX+Ky7o-{hL*=!{c@vo^2ac_(lOq|WA)xTdfXyLg2V*KMIx0W?` zHeTAv7K$Dk={>mdn}3|RH6334t-iQWYR7Q*3a`_J2CAXt!aiKE!`FCjMC;L=yn?gZ zwQp|js0+Zj#A>Ac0r^1C(0MICT(bjbV;6PEpMU>Vfv!p@$V1U2By~| zW+Zm?KwN{0FiCH#{djer^;eU}T$3Bd3V$tiyP^qIRq(}HH+4%23-gDu z6a8Z7ka~I>fU?P`vL7x_#M}j)zw@^>EwdDM!PX<`{7ygo-n1wB516{7)Zoq){6yVt zbXQ+`M|e3`_$y!wB?f1vH=wt&k`&o*onX%eLTDt~hKsMu~s z40{xiIX+L-cx&aspukR4SKpYt$+^G1c+4Kt7I9%IC2Kd#!A>|f(3cEO;3sIMe_B97 z^LXRqWGgv8rk3xh&(E|A97lC@Ibr`@$mo>Qt{^Nc3y>~Q_UUzwmo6Ag@-|^e4Ni)3 z;9z@YHLcTrbjq==%uBu(^=PkEW44n?Qyw9ckp3hjGh|=&6TO>KtZj}xZI-|-L%R*iRia? zwU2NmJqUvb!H&{kf=i_&_Q&_5_bjzkfVG|j`!7ABk|4U3{rzZyed$^ zkw-mzcR*#MeSH3{3s1g)c3Y(i7d70S+3(7>aM3)y<|8zGY2#~VsZCeGLrAJB(Q;&p zoIESnzJw{O#ArNyT8$H%jh}oIYZ*v+o?s~S2ze${V8H#o@|1}xAbJRYaz%wk30*;# z!2iol=j@UMv6D6<*ZAeAg$CXl?m_$HNuBwEGoOPVu-e*F9I>SGN+z3FnEC_*L&|%| zMvB#TvwHm3FPM-hd6e4Y+%hC3B`t3R@2ej;huLvzMWs4bq4Pc|`1_$v7&TcA8--4T z4ZK}Z_j1qOXqB}VFEFlhO`T0Y5Mmk2QqH1*ENO!R;Jbpo{?n@Xe8 zEYyiLTgXwLxj+oT92I-fev=Nb-(YA8xH-i6udb{l%4%V^>~tJYMR_=sqe-S0S-agXwkdi}{8KRKOh{~_YOEyNE~e0s8EF%H=U73cb@LGf0)NNY27PY*QN=f?oKwfDxgl+BZFZ7uAo4#~jO z*GETfWE2#dtHiqSaVFNEmzU1ZGXoe3ulDkRV!NL-A?3~w6EgbeB)HLl6YDh@#d;9k z=uJ>1C$!?!`_Qfzt^TE!ty*R+Gl{o*gWJfX5xj$0ZCT$A_5yh!8kbjlCw_m-rIrtB zK|Uv^%JIqi311bUP!q9VqLZc4qL(>b!@K4O%%6p-yGdJdY!C=wV0pOc``tZO6dg*p z7|TpZlZ){lR=sAn+<2}Ll;Jb}n6Y9|<4hvpKq-#1u&)JTo>sVToG7;CiI?3X^z z#F&QNQ_Ag#6nhZVSYC+NK;5$jSA!GA-t&3>W;XL}@pnkfLf5XD@6Y2zF`@Q9rnU+V z7pg3j21u*$N#|o77{II2>sXV)k_!AFCgOx?UI5wz#S}2yr{Za{j0G5cKh*VuFz9NE z+w)C)@J}>jt=oluy^+E7(1%Bg$Fd*{%>lIiu@f;Yn`na;PV?|phdiwmM$!9f8#kC%#>#4^Nh;HgveDZZ zxmZ6~w?Y#ka^J@*ULM)798qyA=Zkcpg)}~0r=jG-%sk#&Sk=Vf%qo2V?V5%oO7-G* zANhS(k1uAsQ#V~UZd6OQELac7M*9~MA8-%jNU}i}wN;loiMQ`G&>WX~4dsbePVZHr z5n5gW)kzMAIMqXSwi2yPxBaIs7FEryK4?fBggb+EF!8V%=Bsvm^l@L>_|^n}X7Uo< zaA^laO$yYXF9h;LrRa7RhHYOHhif)J;c{k`Roh<|dOR?&IZL%X?6IQICr<{=J-CBj zU}GFwSK^bpue1Upx)$SCSapn(+S#0K3_#~p6NQ0#oA&TPC>5_TuV%`QDbK__Ui&!gvCe2FuMpFZ6UBHs7`m^V3IXesO`yK zt;qd8nxt_`nfj!EWq1%BKGw2sRZGUkpqSk}>$*!QTNoSQVKMha0?BxfrJx7(bV=T3^V@1OO@n*Fx+jhNJaFAs8)bcAq*FXY1 z+TmJ!jxaD2Ccb9avoIRYm|2Rc3kC)FHT+4|GV{gzq(}#M-GzT(kgli=xEB4iG#^zb z`Q^*b$a~Q4Lsvfe!0MEVW%&Gq4H9rT7tfl{CrRSllt+T0(9Z6H`AQ2RyTO#9XV1~r zLCxDR`#C=fCAx8YtAd%KTwN1xur_gzLvA5s9UbqN@K?MT+jOg0&eVDp@U}m!-HDuT zLh19F9vRAncz7$9~%628J zj*Qtc8ba%|&^ z!9WXsGZbXUyHCNWEL_myx4?hSd{PuVyG!L_#~1F(w@AXpo}F}UN%7KKeXtM_7Ik;D z#X!=K`zAgE3qAwE7dI2K#pYOjxkP*nTRg`u?#=wB_}C@XTB(QCX|0SH_v@KpqdI-X z__pS`fR@N&QbqNbEx|~&%Z%!CEshN#*7|B)Sb?YnIAboJzMd%^V>7sqQj)_qfH9bZ+09A9Rtky|1|5a%!Bq#@LFAYHjE3cZ()>$8u9%%?npF=Or6$rlj~&BkITk1&F&ZDWnv3 z7g?KRm$D^oGkM31*MvHc)BzR4Ug@t+^mT9>+Y99mY;@%i`i@V-Xy@9Ed2Sl0fZeP- z8>>QLFE9`eo-wgD2BsRW>d&mN9fs^j_{ghZVKum`!WQggZAWlQP<^@g;oS|k=WDte zqA^rr5PG$$p48wYV{24b5Go2A&036B8jopQZ#ogL+O48W6zJY6Ro=&kD5YZQ!4$M0 zR#-+q^)sf2=4+vRuJw?*TH6w1LpYn+;`zb2v_X9CXMxv5r+kCLicwA5#<4r98C#UL z)rpbv>ZLoiv##{KS5|{07aip}=k;RRxliv}ZC6v(Dzh^V*+=BGiQ0M$nenxa0SPIrFIYvT@2& z>(~+!WdQQ;jqB4TP-?O77YC-3XV4uh#E$TzIDyT3P|;k>=EM?JE(4?sXC$ElfAAxv6E<7YGbYB12|tBe7mNgrCu#g8({**EhpqQV{zKV)ul zPi@iOquZ(n(hLL?iuPNuY1$euy$D#p2(DHXA??XASE`Lj0~%#$Rk|tG*{v@`?^!>r!3*tZ0?hQVNZih$ z3N17QrcBqf4{#OKtHT5<1l=IBy$5pp?_Pu6Z3N`geD(3{ShIJ)f#>>H;Bn)c@f0p{ z@f7+@$xe0WU}BAtbyOu(>BjeO{?zKYhq(i(dcFp(R!id1Bsk8rcdSJAMelHpR5G$Z z(v4IL)@4g=c^?kdf&Gq9H98T~3s8~^I%Qeg`~n|UGYmLWNW+xD9B1q!S#mZ4Ym0g% z@!NT7#nc(7pBKF~oKOR--!QlysqBq}bIDj~HKu%TJdRky@4zW_cl3m&GV2C)sf9b(t4d`vzKHbhm?VukLX**YZ_0@x7_>*$);WG;7Fx)5 zhW{77Ec*1tK5;)ughUKG6T{P+c5X>_cQH@nPzyWfj~Vnb&knD&rB$s!(+S2!P}pz6 zww5x_@#{=qI)%D(1l}o_U3GbQ#otd_QrKg}wkD&^$o)%a@>`P($;CvMOXHygQd(KX zUt$PegmQ|484$?&i|l-r{mJ|K^b~Ijv(!8waCi0A!eQr79Jz8)2IL8Vp-%LpDJF^c z{MRqBB^k8Ygl-wgaR>J5Q;=@Ye`I!@U1kPCEDaRCe0~M+Ao)x;=JlY0+v~Za>iBJq zN4%viZ#n=-(|B?!80->#vZQSvL?Q95&W0|@8#aOGQpJ~-p$wI+p-^GR7}}YYqP$pY&!ec zE>UiV{;E4&eTRAQukqf`07ZGlys$n!XRFzo^zSj$lQdhz5C}hf@AWQ$UQAUkj@BnfG%r( z?%%tLCb1z|xe+>8s9r;tsb1dS8o{VHHs53R%^=8TwI`u)<5Dq=v#e8rTmwXcb;hE4 z!?EAJ*MNMgA|!-T^ogcHI`vgcIAEBoo_CCKKDXZ9AFR6Wg|JPi)(^ zeLHjZ-ru>m&VTFvRb5@x)#*;Ze%`g#vz{FkG!!zRsPk0 zYvBA?q9v`@2bP`7Tz09N!;#fzs-bV58@qlxs(?}q5R#wiL($UxI2*m$iFkF^GDrsw z@W6B>`@;i@t!y}3{M7o`8X7Q=%Z-uL6|hxN-hW1b6^pl``|X5{aZpc|nvLKC%u%`( z4lv>6wY&2#0=yZ8!L2bS3=}ENTGVsU?|vusFkg)iIZ6*x)LqdI``pDQ6~D%$MB3Ot zP_V4oXP-GM)@1fysZB#Z?$|@HDXyekvjk@CN#%m~AJ)5~MfIea+@@Q?VcngRhc)JA zeyD<1W{ja#hA`C^{~R%bgL(I4K(1GpYxPHUo05i%sOxWxgm{LRuDa7892bPj!T*S} zcP5lgN+n*K5-TR5RlRGMEdk#X;>|0N-h<;V!sCiJ^aHn@sf5%LgwD!D=t|OHZC3G<7Ic}vrGEWE3(J0z%tnjQay`~~jPRFCDsdBf%UJ4BQu>0((iIGJ%PcGZQ0CH5B7%V)eWZKG&xOdOYDxEhwlJ}=yY?j0%Xptzj zqRBBi5#lS=;f$)I+vVa(4K!G|jOry0CBJ)Palr)DBK6Yj5TRK=Mwp3N1n*Zz%^rkE-Jpqq&WUyeMJ*yvDTgQ`-*fcSw*ogS=lir z3I$`%}7On`esahu8!xqZS?V?QVd7bF;6WFDUHM`?&XnC*t{Xq08O zVZa($%V9K|X>#z6F+I?vLl6!JN^j?apwXORMHB+`eI@czyyoKr_n$C9ga zRfAG5GvieMmZEkZ$>`~a@r(6ixF9I{P(88RTR<9^!L!H2%$gPM=EXLrgVuhhRzP#Z z0P54=)jT)05Kex5)XeHGXwUDl|{h5?2^g;Al=qmw_;?V@Eyn*9*lA3}7imtA1 zQVzqu>U!O^wu(oz4z^%&|O9kZ!Kutfx<|xQ&yz3Ki zM!Y7;NZw>&ir|MdlIn~6g@ktqKW)ieq~pYh$H&JPS5|VTFKxS_0)RC&HE(b2_N-X& zo83=S--u2wD66TT*g=BobAnq+i>9M_kgUZAet)vzeS?CZo7NTH(b3V+&=se=zfa~o z!ev7K=RYFWKh)P3PEAfViCq{&NdDacV3e=U_bwY<{u>L-1N#Ky`~`len>r|f=43l|GVmX&?&mJ$6N!zHLKm>#biQ32>GA55^K8oNHvJ$Am~GXV z4eX3CfWBSRV5}5eiy^tFGyD%Li-6zafy^dvLLLkUH*T9@@wSAjzk&Q}vj@Y!{(xN8 zt2EVDjq9zP(L1)Lt$&kIIIs ziSMzNgLpI8f`pzaauL0t;&$nf!ZnD-3VyuHXFdm=%o%S*bQyabqLYb0L; zrCNRozm2GJs1WIDYUd*KJ=28BCSwjADW2v@QO6EYb$<^YqtIs2b7u4$Cq9l^8NXC> zelj#eKr}_-`gXYDrf_Z3H>?oSk&TMy*r_XcIf7F#B+z5|j?8lVn7JLV*IKUg$HgIr&Sn{e9x$_#80@4LJlVE*$WNX^>m3PH=`%7V&gp`GEFT zdR`#_-a0*#Cz*X_YyY8`wNo!9U}s7nGN&^R|L6;`<3m0Rv?sJDECaQP z+B@Fb(0dD0WpLUNme)<*p!f&%shzvKl&!RtW4ke!68|as# zv$9D#Nw@zC$rf8DPR_katK?V*)-_770fYFTSr@DkZ=FL(&R13G?FQEsS2>Eo^wBKj z%4DckK=3~F@o?X;zl{a2gx}`Be!2gM1%5f$V0?RO@}-({sRab2WMY_`C5E%XPjM`}E2brWl^uvPv`4atx$ z|JZcfy&X3ZNx-DeJBUzYy@=UGj{55sTjX4j(Y8Dzd9rUkc1DI2`?B+Yo4~2B_QghN zq4^Nfof)bLNKE4GRJB|w;=A{m`cE}NkT_5&y1EA=uc?=>PxdnNg|42OPH*oJw7yMi zsY`e_>|@wi#+kH?-C?RObxfKqanf$(dy-LBhU}d#1j5L*rWqONuqP@AUb`YG;zIUu zB)d$7`g%+2YvB2E$+rg_NyuD#`(weQcK=LXkDBX=@LGij$`J|~r>l7)D;}4?{ASre zuH?`tQatLqI-mcML;%8=E>h%2!Ck0gZ(|0Vwrhx)4 zRCP`b;3U~nWP84#r(r*3kX*M|Gi{r54@VNa#%o!!U*2 z{|zETM`0ehkgAc)GbQgwl308jz6RITEc}6j$oC3g)IX0n(w{13uDt=lZM~3Q9e};9?eGI90TVVtFD; zu=b)M?OC5+^JQ&iMds$E<1o2FUp+SOGGW=HxNW&599CB`dGdyFcsWngczrnxvNxfM zz6{lO$hWbT4;kZZIdXWOK24K3RFvQxMq~ZEWT9c^0JysP*R?zB6;8DNg}KZNh`6lb z*@VX-gDp5(BW{R!jdbl;Z5o~$*4k7%wFVVsV?#8ir`1a$tU+J4Hi5&i<#=_(yO zPhXJbC`!?kCxJgx@Vvl%`Ra;s1>!C%&gxpd>_M)DP-lT0tw=ges5uGKMV`g1VxNR@-$-1x>^_Qca7Gh_ZLo>u(ex>I3?&fGo(WD{uqpYZ_Ah2X!& z{>oIuyCR9O)P7(Vpq~E<4c*({FPPhMJ@(ftl#sQ*ug_*@0Jf*MS5!pg&&mGhO53J3 zH86r`gQannfgSoc=Ri@FXPeLj*W`D-hhnYOs7GM>&E1SlLV7=|V&O?yI$ z^;xKd(D?o70KcuheZ#%Iy1JUn>osX}Q)f7i9Hgt+{-CO%p+F>>@Y?m`%Ws}x{OO08 z!gX3CwwG_NbPOu}e;TC#9+ZTP3zgac=`J`YXKR~P=;wiN7m|^&ell^7&1#h;S4^hS zMAy*J;JV5X{qvd3TVzA}{QTT?HK#2{uFa- zYfD8Z$F6 zP85F+zW4>u0iRLOzq%KIcKiP|R`~Z0_5bgsK!mf(nm@Y{#Hv`Gk9(;^vJ&F zsLvx8#eO+5fn$3*o)viSx`uIu_=lBoJRC|zrpPD)=M59J>d%SMLG>Wc3QAu$cJxr? z1Vcp*HF41C&KW)#cK4n4`(PwA?F{wA7{@0?{4Z+yn0wwe78Zna#<(90iFrI0{p@cw z-#^fZt8A`ml+t?FEd=<{=4Fp1#OY{hlJDe9 zn{a!5sRb6VFE;hQ{J_*E?m~Qz53tkyA}YhroAQw`C#cU|x@*iZ{jjd&Yi>hCUSLY? z&ZB4U6|QTPmAMx|*5!+7CQ$IEH%JQIo5BEdJh+vv9T5l>F0M@#(|Gs8L|J>wJF7Ta z*};!LxEcLq1~L6n*?*0vx52TK;q+90;A0kV!Q+Oethi_PoHb?Hbq(gTVP9d{T3WL4oqbCi zvxKVS@|9JVypalr;SJO{qZYc8QWq)^t<}I;Ayf7u8-Y~*j$ z&0!{>H`0IS(2CFHs2F|d9cus*dKOaQQ2ws7s)ZNbbx#u@12E{>Q!vFJE05?YTLMGba6fuH~!R3ag zU_A551=~32UR+#C|p zScj|c0G4m)1Ub{j?#`g&1oIENw$oNB{y{A(lcAX_SGM~BW1F&Yhsjb5Eyvw{A-D89 zCFe?;=)2}Usu#db_vwlLN#{ANXfAGovcl>kxqGeidzK&u1r0ba>(O$&C=eO1~*~tzj&xXfROc0rWF`Me}!fc-L5Wl-3>UWZ=dO<&=Hm2q%eleQwGuo%I%-gqYU%5~+8o&9eo@BhrbRckb zO2!!uzhMKoH6Ew5l!z?tGhiSLG%?oJJ1?ib(*J=bRDpIG+9MKfGGB^Z*W{)P_Ks{Q z$IN@d1R`v9J*SGY1bHe@r>`Ttu)UwCAH{O;Q?4DDs=D;PP+V&GJH7GC=Sr1pb-I69 z%s3oQ`bOe%?tASe^pk7J^k;Zi`dF(1{k%UXs&Uiwh`cbq=+}xPD+a2td9ovnloZnu zAY@gB%b6H9F>}TgKsN?kcvtIdvj#_MwV^4;jUBiBd5^o<;HV6KM;@TN%2<)eU% zi*#P)y8G~2v6hl4#MCVX-P9U=6??Cx7WxVji1!I~kcqAGSVj6r$fNVhJ zCE)ktsorbG9fR)^mEwkE^PITE-Omh3PPL6XkNm={YR z{h>OXmP}NAr6HR5;0awKEzkiey36$Sp2SsRgsG4B>0^C;UPEK2``9mW5_=s-yBFwv z@jg5Qm-?F%sk-wIKW*$R&^XoI-bM|QdjA@id$dzd+}sAd$s$r;7R992O<-;>s$`OU z(U4`P3U$OHKkM4-?`RK3kAKP?wC6$Faq@=bM$rZ$xdR6$b>=;^8G7$FRnMYkR}6K| z0J=x{c}D?odb=J`F&J2*C!aiy? z5t5|FTRZty{QiI775apQFK@?P-?gd}ZE7hL$l(NV^~MS~<4&6WY0WS|Hs@auNn0#+ zKJqJE4!L%chrdqLppqYzKWZB}A{b5{LRP!1}8}Bx4o#%q6z>kg>U~UPw0$1Pse;W(MQ5}I!L8#O` zYlqfp_DlkiqWs7YjTF#4>ANDcq$PUs${dZBQ(}jJ=MY#3K(0ooH3&dL zTb-YGoo}ve?g85dsWx9D!C59=>T?#>ZCq%b84exGP{1#W6mp27lO#Nze-T!zG&l%Y zkE43IcYi6zNfBwEAbo#WuAqiia^gQ@ol3J%?jC@_a*LN`6rO$$hUU4$nyNG99$xvL zUQa=(oS!z10*C9xHxpR!8)Nh-Y&i~J2E6=I-t0xH(}!D1YM$LHHJhKDBF+{H_#iG0ys|I#%fSTDy>NxJ@LW*;Z`~VbX@Bbg4n@i@M3|~~`gC^bk!!HqcC403!`HVi3u{7KE{)qv(Eh#`)e8$l5DQ`h-{q|5PAsHIo?l$Pi z#SoQl;U-5H7ux8Yv&S$+=2&tj&uI^(kPvDn%V{7>HL{VC5u;dO|rtq5@V20(DR{H{IrfBc4<$|v55IYf)1f?_SwN$;yb2UMYP;HJT)YtM;H zM@!64c=cW9nGB1kRQN}L9~I7e*a7wOJ2y>h*u9R6Hhk{r{bP z9IN@f`$p3mqH?)6@-YHwiX~q8xORgI`_0XzpSr5XTepvrA)oZ;HFL5p%pgZWcWcbt z_f_Vht+tHrnLwAsOQX8TvB_4HfsI6I62@Vf`LRnkO6aVX{;JcQj2hlAR&rq~XkWnd zI!FK0>6kjbT1h__mTcr1MZC7{lE|vNvxIQI>Bktt#nBL|t$e<{T23l(l$?VP8G<;Z z47S?d6Hf+B5$`olNEBE`b{NPKH#HaJ?UFK0&Ay; zP1M(cBUT2LY z=U6JYy12#Th}h0%3yG%qC+2C6j!lYVqiT~rlGa^q25CWgIV?E%QirB#%zo$o_n2T{ zK_lZnvqs7=kE3FRA_mb?x#A=2e1^Gvi=Vsp8QKi>_F#286}7t4IOE6cn^u_~Whciu zVTf}b83I1)%NAn)S00uYYF4PNhLTrSkkG`b?BKu1Q{oS-Qog@VepgfC_+0J}e6`;b z*0oU5+avAKx2qN#!;+3SWJTc}Jk55v4Y9oOPQcJ?-iYDDUoR#&SYHeXf-_Sj_mX5PAxg*&iz5zAC zadufYgVdS7F};&mY;mdjL*1RIgtchAjJ|d0qX)gQH^_BYE=mjyXz5P#{LCJ}349Ce zTbPiX6;wt?+TO$Kz7PWdZH5g00BxrG3)jV|woWg@sCrf116W9n_Z?%p->w|)pQeLXhPD+Oiy1s$DusTtcWs@$K(#~1#t zL|T8fAs!=$r@y>|6%9!0yoqwb=6F|9A!CTKQGu1+a~~7@{2XiS*R=h$;Vx@F#+)%u zuMoP?`s2W2+dD&HU&T**H|5K{+9l1yS|`dxV1Tcusc0jc^Eta1x^bCrUnzk`B<*-( zx+l3Ylun@M@gUza$4(h~Lc>|*gCFB~3!(;O#6U-f`nzk44!EfL-80i;d4qU}c>Fbr zT0;oH)!dz~Y(L7n+j{Z-fjk2Tsz2Wd)+i4(al2>-hz%2etBAB7(6_kd4GNk78Mas{>f`9zruMHvGp}c zS!H4h?8)|aSmw@)unbeq24+zx>*BG*;nMPvMFgdINN(O-ix$kd{qpuCItxhbUNyud zoU9gXCf})wvmy)J-X+D{B$Vy(u06?V2eo@si>ms7NzKmcc70h7&6)X-YpjPu(1t3prJ`Fra$8^`myOY;(_zS;& z?AX>l_}hyI(Lad^4p^8(FT{EVxLm~buS`vRQ28lO7=tZ2yakaiy3rsW5Q0rbc@H;pMw5+>(Sga7428kc&;){>sSlzpfG-a6 z?i%`*%wCG1W=vFgc+$S6vNO2!x{#Er$&Io|()y%3ae2V*S;7B4ma?pwYRHVOn4Gl&#jK1SL=>X_6R9#o{Sq&3EfeTEAv& z{z+7f=_MM*axgm)Ym6sK(gFA*3T`cDhCQBDaHb0@3ePmFs?9q-dX3_`JtX%RDdLS< zUHlqv@3r8H4;H5vkGqOucf28nvcF-1A9io^MjbglmTUWgqwGwh?^r}+*#V#}we}QX zjLZ2g)Zft?97FXAZsJ~w^_ho{J(iY3DwRDazACyOyP^qQ%yH{koXD=_gP*B!UfnGt z!Yo(``%TXu3UcoY`E!qXa?1+g8;Wg`jn89@#H{a4DLy<~w(dosX6f*`xY(f!pR8;e zRvNX+?Mc9>_AZvw#}#jerYG~*Zn3hrc|pTR49l_XLBW?JJu*8I+pG!TaghgZ6z$5G zHh3CGwYDOberSz@M;WmVtnC8Yxz{M!kh%R5*2qi=grJVVRuzWCLzEW^~`GLC4pWDTcNlu4{gJ`mOG6>ea6 zVroXZ5QB|6Es18lNZslQ%;yDQ0g^rqplvbM=1trb#e{`oZ2W) zu;(dnCGX|%5P^wd)DP2$%a@;PPMA|3+j1R8x46j5EJVwr$;-Xw1~6&ag2lR=i`K8y zo&}CMLqud64eavp<9UrieKY-qB0+lPZqt`t2=g>c;$s))ThmTBI}&KMyHR_uC@6jv zq6DWD-lAh1S=e4-M5&Ec$9$lW&m=0SHwDTY`$L^(rk}Jwv6io=$?XjTixj?eny#)G zSeyj%Z!rb+ca={C!PPvmggSaeWHPlPhay0*E3xq{aC5A)=1BMZ^St3D{#2|_4*A8G zw8SWcR93;zaik1W1I@(kbNTpR|D(!{g zBv<;{Ea$F{wSMlLh0ZY#Zug_HjH^!cqE{a#q4dqS)4X+_3226WOfNCt7hZ>6;oMkA za<}FghHNd}rN@}91y1TsdniR=3YAsE?ky)~ONkCf8Dx5|qWB0oPez3fyXd$4qe|FB zBH|9Kt+}$TkScpbGxdMG6ciG=zCDu1!Np}PgNB02(d`Ya)V5w}pdLG!9ocI?XA^Ti;X z9$vbJjS?BN$rHOLJYq1quK*A^nywU;l+Z2f{18n zfni}r2c(}!^ndVrf%V|M_4rbO;+!UoTgH{}6}r~>L0l$e(f`K5e2p$|Jx$~CiFbyn zqFninKiJr-dd_nz`nzihV(72Dw!;w%fc%>~)g?EFu>1>&4fdFbh7-TP?7&a|CdY={ zq{Hb8c;{+e)I;Il7`uE$NH?MXElaiBljf@6%2BU6T*a?xRg`fDv zcs-B*ws$*LK2HP@;Jq@K&gs0X{24)P6Cnaj3)WhlKg-?S-`_7TEnRJPgPgCoQ)WKk ze?7{5CGZ4%+~KMa+$iSYhLSd8f#Ot~RX8C0n1z9XAyaRlVzpY`oGq6B{{8!| zW9;AS@NhJd@Va~Y^71m^7i}FMhek&u0s)Ad&pg{&fPBwzF}h6FZae8VQ>u%5Z);J*@*#=ocR!j<}0_<;zzRXR0uU$`#Uo55?E$sJ)X# z*^z{I)ryrW-5qxeQ9Kt{pKfN4WRIzsK+iz>&Jv<$T6`O77hdBG0=`eG=wE}_7*~l8 zC(||hZKRXc5s=kv)c{5}&Dt~FO!#Hz{(8fH;eI;zH}FL<>&J+VG5C7u&)aoqn@re^ z*@CoGkOU*}L-H|lxqM1-8i9h6t^X75zVu$O-OygcOZ*wAx+{q|*u90DEX<^qw`pVvud7L4I!lIaCZ6&}bqg<1E10EOqe=|Ap z<2_h+sP2eUI%(9BO;fr-T6C?9u7&o{@6QMP^WUl%6>Z%Y4Bi1=J;H*v^9c6l@X7>_7IxO^aH-CS&WYXx9jp)uXK zuu#UEAo?OH{g`naz2AN$PqQlH7AwQBFSes^`6SEL-nEVcUt4B51T`M<+?0QV2ovK5V%|B;(&7&|!{ z<|eCwAv+L{EDj(ZCUWN-say$F`;RDXr62u8vcfhnF#1O_#&*xgN_7SJxGBwFU`-7i z;~me#rcc}q$Q?M-E>&!toP}c@GK$5C)E=9-wSPCIY|;ay`7rw3UAJs0Oith5!=Z_O zElj$HbPg1{rLa9sw#fpZYidnd<@@hsF1XzLjX#uoSpW+!JvuKLVHMIA1wE@LKu!o0-Z3=r1!RV4o%zC{ch)w(R=gqk|l2nqVWwu3WSH;>X(b!Q4 zzPu@gkhPO{S*E=?{^vY>U}`dZj>~`7DcP>sLWSle!B^R=`-_dJ!oma24J$i4Ksw?E zDZrV#uyMwEx<$A`8FP5GHM+>L$5tD<#9zDn|b^p zQKUO?=1?!Sh?)I;-QsIBqUqSd#8Hyox z1r(3~2m|7%RBN(&5!rtO`j}zxsIx+5oNYu@%#0!tuOL&dm_b2yE}yKBFz0L19TECK z*{If|7aM1TB0B|FU)?et@P9A z7;w6}amYNAORo|roWp><1N3YBHx75zTzu~UQdAI=JFx>HtSP%!37)03jBdPoHf*+S z_r05cYXN{hQj{x? z0}-9liwv*gX2Jp)X?lG5pw&=1&=daagxJ>RQ&xUhs;_xJDNJgwGzf=ljg{<;qZ$9I@nkf5sk$ZL-+0wuapq zcg1~iz(@|ZBIkT1Wp?lH!_+yN=+SpC;N zKcznx-VoI^wS^Z`e$e0Uka6SWktQ{pRtAX`aFRam_ouAJPW46Q?;{p}D5zVwLZFxq9bOl2(}EMnRJz?LY+f(4jdd{c0ryEX9I=v~bOW^`Pr7 zO^Vv8Cs~>Z$C1t^gl0hMz;_M~EOYad#QAcq_LNWOB=-(LG-)wWOXID*9@gi6z8A)c zCV}%a*c;u|8j&#dR}1?Or64$5V6sa#f%DH^<`05vPh@R(y=v7fSnXgmx&tglJw3gu z`uaH&^#H2@RVz6;`H+@u!OZ7OB$*XuB%^;?u#Nw;@O>OlVnYtFXZ&;4dq;aqZcDV8 zM}h{CgQ7cN{PO|p5T$p)f5!x0uO|AdjE{8!E1Q)jeP6@Yj4vvA>2!O`f58d7ii>Om zWZMFGF-`98Ukk0HK5p^-%+>X`DXJ<`lm3+R^SWNQ`Qup~}7GwD=`b+g)SQH+bP&$fwYD zC5Di_%7CHQ&3P}j!SV><670Y+NTLd(8%&sV+X!gDm;SP0J;k1{itho8 zZ4qq9DpUDff_L>Y#R@1>to=RX$emt{Y_C7Q#6J|iybvr|e13`eehZ{P;Bj>{ z!p$)Ql{TkIt%J%9bkvv79FI@aeT}G@4rgQVH&KWWQEKg7)4IJ$_K#E8!7^>;b`hVw zkeZRE-(3}5)@&*^wr_cOqyqI87qrUe9rHNo28O%lUc$ulCcG&>sry^(wj8^!1y=vy z(dh6y@3zw;T0z9IV0-z(lDi$KrPq?^U3hL$t^CULgAS1q^)cUbM0wb@4$SdlZCMgd zUscFS)4f2pSA!*)f7DIxUXsdk0FAy~^4Ee}ykFKYIcY2RsCz&n`=biHJWwr>2M24I z4Eh)>dpOmzO&y=Rg`K{oag>%ATVe%&yI8U~ZH-MAn^Y5=o*e0*@lcX^B5kah8tlt7 z7|N-)X8ic;Yk+#g5-*7%>=%6=ESBV`^*)vi91@2~jC(Zm9%F6i{^dhR`e@~*EX&}b zR1<9!u^51(R&XOpL~y^nihVm%`CvG4m)6Hpikc%9FKxkh8{Ib?qe||cdbWTZmW;={ z$Fzb5AxtnlJDqt0rHnQ}r3WG;c?UA3?$rBsp2F<<4)BvNcOa3p=_57mx~m>}{2^lX zmlyAtcZ>@+N#fWCbmn6O6+9CBolUU#5BQSULAUkZ6CW{3H!~miSWPkAj&-%SjPcm5 zfU9*sAI+L15Hj>CCj?^_Ux>%D)aGssW*M79^2&q0XdgxtUM!{puW$awtx@9&s1fKQ za5YZK4P&X4kR2^az4tBwL%_4#!%EJet4KN+fwb!W7QJv^p#XE>|uJ7H!3OSi-Ghq%hCrr$7@-tj`gus zt-Hx=u=Qc`vRBf}lcCD5#b1UX0;eg+0(6BVXGWy(wW__=x7k?A@!Ltuwr0~&!bg;H zKYH3>Zl=MB1O4Qmr<|wN##iO5isnPD3j?QD*0^%dah2|$;(m{zH#DE;!Fx>m`k&ys%deCFPlpCXs-o8oO>tOrR zLVCj|uL>>&GNodgvzNPqct2aA5nG%mOC)G#?cMoy6C}F)d)C^=>MQ6kTs(uL9dAo2 zIjl26ja_1t0p{ujh%Gko2N!+04CHpU^GxOcbwZ?;Dx(+vyuCqMOKC=}9* z8pF~5;e!q)vN({k;*>P#4#z6eBYM;ym1%jx+O{!-S{J-l&m1mBq`pj5OzX;2LQ>-i zr0#W}YHo&$r}5t|PgV9fDuG)a&7m;_qN7agB^b+>;c!-!8p1cKS#QKyW|c( z=paPr`SjHH`yDd!W-NbsdmPPY z8-6nhr>gg1qM^nZemIeMs#~ymj*C1vwB}_bsrsq}?Y2|K-z_&=G&7ySt6V%eKfQY_ zUpYw|Rue~!G*Mmd-h85wIKA{-7E#(t$)PS~drY8$4kof`vFI3X<`ts9OVKgxcsi|U z!Rq^M;}$;=R@}@SL7i|xDub{^kM`H=nJiw0(cWxxIH#d>nAO^2MJd75i?_a-30(pW z^wa9Sqf^ICJD-R_b!uFU%$CSG&)wRN8LA zMj-7ObIfEX;pU3!Sx|H0t2=$0?KmB)xWX?U^NE~Y)69)UQ}%e7v*I79vmFoIk)G8t z+y|{YhcUo~$SRMZoPbzu=6eg}mj(#);dG|c$kZs^YB?`|~c zKAANs4}Hk5XKA3WmMj4)+LkLKI$jV^X*q=tc&=r7ChcJ!@aB-PUlBwjawcOo`4q{$ z*Hz@|DpHrP(vo4J3Zf8KSN)0EWvuBL#&Ozc23a*e82?Vebk@_T?JlqNLDNclyFcRg zB}qe-|Hb3vAeznn89i4Bx0{|WJfAT zz}vFZB!$h($C{tDD~M#TqIO6h(mYbSdxa?TPKxr;Rs$4&EL=}u@K&JoAnl~A5l;8Y zSEjA~I+)haH-MXlhNb!8Y905yXsmdn2@`*I8p6zU{$sR*9RMvv11d*vBvcepx+9^q zMdID4XQjR<0fY=~IRL#E@NNp1ySXSM(5bE6wC-KAy?`t(G);WbiHg3S#(j86V*pz!Ji1&3yW&x z1XK7}l?JMrl08s~-0?mh9BsJ(_eWsUmsuHGBlB;Ak!xG_>LbdF*+1oD*xaqT3@+*r z8seT)qAe-W9O$fNDGH6it0x>q5@tLF-g6dtT#*KGAn5xR!f(QaYPyd(!DkcY1J}(% ze*v4A?$O^I%@flQC-2A-i_3``N}?LuCuBDLk!<^Ogv+N`0F%&nO~(=xPg|j^xg{n> zK|j+vWhG<;$y}VL>qZMHQE5Xwl!m2fCuOlWQbB)acCPOvLt8QX@pYph;2yLt1SnDx&fC%fM9lD6P6S*pZMt_3yyfG%mXlK70+a{D-wP%d%g1Lpt~QD81}OpPCn5rFVda2=aXq+|p6Y@`F)LO)aZ5^(w3a z+_t0QnE)qsHI7h}6yt0oy&PQ1g|j0YL>L;HstLfHnErl(a`i}Esn*fe{Q^FKf$r-* zHTC0}JS0ge>!bPG%w)bzIJOlV6>OFBBT z!%A2{Tv>Ui2bhASW7F}sw^`e>dufo;*@x$6T;-e?&YF`~_uckA-&t^vz_t!V?9WB0 ziR|9eJWxsIc>1n}Ih4XPh0BLBchX!#7%a`zBHwTucT!bq9oTa_RRU*}W0NN<^eVL1 zYjKg+v?MR91oK#40=w2DlgOiA*-3)AlLKy^UuUNHAoQ_d(u59%my|J4yy30P3@t+1 z{rJZRXI)*>y^i90@^wiyuo|-Gtlu7w0ksKlGXw`~gl6B0Xyk>?btZ_kPvP-)Gc5I2 z!+>|0ovf`gPYw@(q-9GpsriHsFM;~<$5ni^nrDU;k=nZp{s(iVdV~MMi{&~%p zxaFx#Y0`B5bnmg(CAS^TWBS$xT#x(axF$nn_xMm3cXb~pLyDE2>a|wa`wEu>roxMp z?MDYS%>asL+0#Y5_v=Nr)*UO1{>Za~nl_r=rREpBf%9|rG?z;(3r(A;uss0* zLZ`?`HY3+K=9ytmo=-c$#YK$*4I_Pld?9V*7WOo1&(Iq49;(P6JZA^r|3QFn0b1`q z%A>_5qn zzc*xOp~gc>YiGAO2!oBygb7+~VIXmH$hV1Cqpu3_q$&2S>nDC`iq~xhT~tW9BwM`& z?t#7K5r^@3U$%BOFq+S^94NXR+iDj%UCB=Q87X(8sev((HYrp_wF0K$B8@*S`~3JR*0C%9eq`iydC}0Rk|aPa5zoA zmhEoIyw))+}A+yG4{ujI7eVcj2kvNW>d)zBGqUHcKIT1NXRzXB^L#XP>v$du~44=FSr? zpXkW3S`^s#exY7atMAIyqraU-YI0{zE1E7pRNDxHdq>4=(!;w)f^EH;9feictAj@(W*FaGh8h z4}Xuz#3-%GZs8ZTOIzGD-o0~Dtm>MX`99qkcOJJS94*-_?pD4qWjn+$eR@PclOijh z;bwgym&tBRi5OFlkptme^I)@F7=d zRwI~9c`gS;B6emoO@%pIly3-iVR>?`1?!rO;l&AXc37Hd5=Vw7DvbKZB5QY+9HBeW z*cq7HVhL&yD)xLaL1M(?(#@kmrl)yB!}No4$B(IkL$xLXn>ys`3oL2ftVO$YQ=AX+ zeK{Xcs^H7C+YJVoiUL(4jgIt&r*~#IC$CuCnvKYKDPAx+kcSbxw>%% zBq^`SvZQ(F=jVqj59HZP=PORaQ!;YP>6BVqb!#m$7f4+WF|t-A8(o&;q{KxK?|mj# zg&P%#*v+KVZHl&Xk@}xm9jlG!`nqDw`)49}%N~OPu>Y?uU@s zo;)s(JD+L5S(SZR=5q3AK5HR}ce$rKp}34z9+r@sP)yM(Q=^aOh+C~Oq*N^LB-!cE z*-wpkJ)h$9u?B>r@_cUq=G7*dv4K}f3;Sks10yZhK5QUcxa59tZW#NWi%@jlhGbv+ zwmii#6?|KbuQrW6V|E$s4r5PRaohJLLlxc(1e^!eHM|pIpI&Mm>!+bYES|5E5sy>$ zH zy+ZCc+*E@aI-2k6J#ccxtJ3Y4&{}Mwt+J$2INZj{$PZg#4IVQxC5n;yhrCj$+`r3` z9Fpw&Ed0_|d#TGvnT+W%d^~y;MpC{}PJ3p?c}zbDzWi}?Qi}rE`|}hi7N{hr&612G z&2C!QW5h9Zz8VO|2=SKf`)TY?H86+I&Xm(o&1%prLv3kZq@nXgKoZy2U$T1OB6Y;~ z+urOuF_Ej1ljV`E7_i~La1eOBg~7*fE#nyor_uEos>|F;N)I#deb4tYIS|zBl_umz zXS^i_e~&X9WwUWZEiUoyxF8KtdK@Ce<+ z+fK>=@MfObwbR<(P&6B#A5qRSI-L7dAJNSQSG9|8^B&krW}vk@CrVQvR5faPkMA)K z+BfN`PfJ#UoJ9{+TFy!Lc1#p`9R;nh>XVi-_usQyLf|CcO_Yp|-aGR^j{WwUVaSJ^ zM>S6T6jaJlFX`@bSG$=xmBisdZg-!;y$UTJZ1&^dnQMBJc7ZuOz#qvqz{*2--}5Mx zCZ-*_JNM&i#kXQ@Xb??NywNq5Im%_MsD#u$$+Mfm-gN7p=PlR`1cc!H(RU=;Y_z`; zmL>&4taBzMR9_icQUz3MDn9 z86^M;YQYe!KFcVwc5x=-?TJ1*FsQ%F_DI^G_ZV-u6noqXe(RIT_-+r3qIHSUJ(9~Z zr}G}K%Q2227O zo5x~eG{kFC#Y&16%f;ASb>b>K1^GIn@3KMuy%?sB6k4dlr}0*o&VETzC0^6_zJxx7X3lIR*Ghm1pWLZ!99cQLiXT!(!%IoG0h1O)x25N+4j}az(^Qn zbh8pr-9&U{rU`}M1x~aSk`h@GOR++a=UV#CZUZIKNN%&LmRhL%<3fexe3@IrMC&)d zpZYSwx0}Hn0m?sOh#xtEuX$NyaK@!%4^uUM>lIpI12 zKG7svu2viP(c&?n1Vgi>#l*W?d6mZN+b4TxD3pya48!qWR=LkLkJPsbE8ts2-Gt$HcbBpZ;%r`_gYqS1XGSmu#w) z#U-s7-BH^VWX`P;lAmS<#}~%k{6tdncSMD0XJphtzR^w}CVq&BNDGnHzen3*CR4vB&|UH%~0uwi7q^LK3|gZO@UdT9Jr7V zt~>A1G*vOg&8XrNP40Sr3Z*#H_XYwtkrRh{aASeQAGy2-{#KzzB^u&=^)9L9dXZWn z=kR&c7R@uzR<>0~T5N`9^Sys6q}0RDkgT$lJskD1TjCi=97X2$Whubg{+06Sf4RCnmiy?H~9 zw$)tIX+U016ZblfYi*p6j+J$^H2u9_G71jg>{v#6Cz+XqD&u(;7JKWyiG0%pXLzoR zH4&QxeqDO!^L$j4Z&f;TI?vWhy-%PRbDk060KgP$DU=F9l~q+t7xtfEP@u`vCk#yI zbQPclU^Qi7ib`Hxt7?clJm$P3BW61i<#$M{5Qyw!qS_hxS5zNi39=xVWA%a zJdO_%%^kF_`09;jyb&L>+uGisH7iRA5b4a;lO$@yvX?4Xlnv(|a`jL>&4yqY7`(>< zcf1)m2jxUzSwJGqHJrXSw%0h{u_TJD&5%f7s0UC%_W{OenR1spw{idEx7sL>As&(Y zF&)2`Cre48h%Nm|{0&;G+W8*b5`tlGjrshDJoWzu_EgmPUtv#njsC@Nv3EkZcTjIA zKigeZ2=P8bOH)9OiJgn*y%4Ix=8ckes5LATrXGQWZ)?p#@z1x$<^hZN>^;7QYFNXZ zNF3?Ge_hv>u;Neu_!Emzsb(ZTBU?p_P$@#&SA*0j^RQ9GayL`1= zRO5Acn`o)2;fB3Oc89|SKSdiZM_OF%r9})XcBNR_xY2a}cMzWb@OB-hI#{YG7(%lR zEIXu&1XLs8ni{6MHv{E*D`?I&DYNmLV3%?L?;C2}8u4pemD^gPMNA^W!R}(jFsa8J z9b-c(3{Q2!8}GK_8+A{AK;6lj`4@t#O5Ps$Cl}OP_~+Oye=s|m8X02A8o0pC>rAy5 zCM5_O;5#@Rbnz%5-AZZ`7TQ#M4ahR5N69;1*qrH5C?XX4oH{>7X7jWs9n1fUsp8LE z6hvGUIx=u9e}s)^@Pa2q8mHC|c*-&;jc0pB^`PQphEOdWu6;E0q9`0m(a)KQdjs6)|e37~Y3EXOhn) z?4ywspdySfkoN^YX)(kzA$7-RSThuyNllpV!&_tBB^g0O(aMO6 z!iU<@LC;sVsvtyc>nV~IKYj$ClOk#1r za_jVmn@=^=cn)ktNUOD2{&fx5MU8)s|CLreY3b3IVXI>q{19(&1Nu@zWmm0s#_)e5 zKDC=Rx{resY``P&(@~_-fk8p5K-?lHXXnjE>Ut<&r-0x|Eg^@$L#X% zKeT2NrQVT&E=RsF!$M+kB!CNp;XwUEiOaMA)U_}lPr_|29>qiaO0@EO151#2WFQswB?^WB|~$-;y=EzSZWZ=m&+cTo(7tD2AZ8B z5R;PHK0Uevk)86?>luQ7S^@cLAjD#+$kVQmUtnZ*tae-9l}2>|*B=6(in_W4q>|Y_ z19t7t0R+BeU7Ag2gO3kj7$SK5WzvM%QkOVjeDsWrog*XggoK0;0EV>Ab{ifDG8H=t zzV-s<^!p^+L!9U{c&*Db*2jk*00jHqpt<1D{-o;i{Ia#{we~=)OSJ6x8*}xqEok!_ zi1xpIlrbu?o-yhRR-$ONR|nN11NjaEJ>h`NbcFwW($otrxi*xiEDKwpIG%S9#b~%< z!}N#zHYAP;fXntj=_Y4pdKMRx&o&2jzkZb&TSczpi(->E&KH4(nXD_ip$*i#taYFN z#TGlC212o;`~9`o;upXyDXybi0+}qS#WgD+QR1tNGvQ6nB001ALZYv&$s#vZowICn8}T`BY(JNuP|T+bG+8) z;*|_cq7C6y??@=eOMi%17%}Hs-T(mA$H_nYb`$>TK7b32tI!{OX?3~x}A^f%7=1D<(tadGgdG&|bwsUV+m02IcsHUxzgDwOZd5V4sHGbDvBn%5ni~ICN zpAD@dx|wweDn(U*f zE5RV0_A<-HL;&XAfIF){FvbjY0)taEJ63-y15fm->-iFeV*#wrXqgT;fW2a^`ZT02`hfNnF-utDgLWR5A%+>lgJHE|2QS-j)N<4Y!asAHQ^#{0q(t$eT>8P)^pU^EvO9m}rt1nfrqffz+0rqzL3P^{NUN+huChq)7*vk5Sj-|bzp5>?u?t` ze`?fGr7C~V_;__u^=na181nc8XBeLIyc@YR2@8Ov6;>Cmd-l`g5 zK=I<&qp4Oh(B)g6hEJ8Lb~P6|cSTk$ckS$IqDZ88iL5rSFxNm6DE9i&-rlq0x*jlg zS{V{0sgM7@MzS3zRXk+wsdqRlzJB^s30)1T7vaQw2l8etYtf#?nM!;3l-$X6WA@)+ zOp$#7*6RA>r@`Pw#QYfvrrQ74XD{JJNXmZ8lmOzU8h>J_^iD*UBXg$4@7*#pGyC{R z{VsqdH7B)8FpS07gbh2#G@WFiq??BJA1ZK zNLzr!;mQ)wnieW-VT*0gZM0BEmeGh{{S8&Yd5J+qgR4ErcfxJs+-Bk+1{{+#i>(&Z z%v~dZh;nI?gv7T&l*oT>XuDXz*vwNkwE9=FY)S=Y0S31f$Lm!7DgE1nzQdzNP{2R6ttCdJM9{o=w7*Pty$mxUJZr6qPVgDpm_bn=m(gK{& zu0K4RFK|}g2oNg?cz7aD0z;f;3Q}!fFq#&8DV0JjV04^kH<>ve&5hbCKUO2H`nLly z#q{R`$x9oD-X*J-oHc3u`G?UwjH2%hw~t)W8ynZ-agqP1P;jpvKXb9tYHpCnDyw?A ztZRp7J2AK`D7gi{i0*2cJFm#`&^Tqi&~3lJjaEi+H#}xM&mB)tx zeJ;(c@wwoq5+Zo1!`@PGW{|WPzxe2Tr1J@dqBYT|8IP%oDQ6#0Ls#OsZry^*7K~^v z5xm6i;DtMah=eSV#iXrDfc?OfrLEN*=|Hmb-jHZ%tt~OeY|b-r&~aTBD>}WY5=!zO z^h?+D?7&lm{Q}9nH)XwZb@Ha5U>U}mOrQjFh!v(9@MBU9+qkwmW%K;QwglSArh+N~ zs_VPrvV~LyZp;iSS^Vl)QM#?-hY3dRZ%z`j7pf$)!b;_JlgeB1xC7lX+NC3DB7w#V z`sf;Fsz39tqH0?^TzMztXUVGnO=5fB#bb*N|l=y61RUB&C|+P-?}0 z)4^t#Qkmc*jJmse;cn+LUqU)wGw2V!faOh;MB*Q_$@dSLA=`r0`qUjx6FpYn8B=6P zyyqzp0U^GJ@BpbXDFp;HNL?PN)kKY$9X8aLFz>mz_u8XP#?fD1_Mz|GDyPVyPGM{j z5iY^)eA_5BRpB(SE7*yFw%V5dhPtAe?3_kdG=afN7yN<6AwRHm3FZYx4S`iUV``?_ zuhQ4!^MjZVH52h!hbCL+D{)Ed7-pQ>USu zU<_*l=OD5F%?_AI(WJ9)bdl`GU3`2}?p)cuCoHFX+BolIXz(JcsK^0eAeCFPw+_T4j3QLLL8oPHZ^{f=NvE?7UNwQyq}H}$z&=o zZ=)ps8#r|BLCy%t5bl7swW?@ztbg>8Ws1CGml1KX6>m8Gap~Mh6o`iZBz8=^{2D=B zq%AGQ8m~HloA{3L>%e=CaMw`HQyVrnu3)c{Ce1Zi>H=8M0PecSMaonR>UFxEJuk@- zOm?mAmSAh>2^JX3y#d}pqBoW(;Y%B79xhHZ4s+->d4r<9Gcrf2X4G+{+1GF4op{QO z*_7E3*#A`*AIhUrPS+{4ZF$VVG;pCG;{%6StHMg^K zXPU(T3VjITZ!r7YbgqYpCEeu6)u&yhz1vLH!wkIgQ4DP>=dD@O_ZO|rkR^InDMRQ3 za`WT(?lT4AaEl?m4EEoQX1(vy;rr*O!~ZS1Mv}Of0>o zD{pJIrF(@L-Is~5usF{Z8#&k!6eRt*R9QtG(>_BO3vI||;qOJECVW2z>zeapF?O0K zeY?BR%J=~5P)x=!Xq178V%sDt;-OoUqz)xo#i?_>Gh*h^35$X?r)#aYj7N6!?#N$s ze!q%B7O059^WHUXo?@%uq7a4dlf7E6%mt)$yl&m$nnW{i+Qy$zf5CLa1j zyf@#d(L9{4?z78fQF5=m-eBXN*eu=OJ@2rlu=^gCfZ0$F(i!slBkEJj?5yur*Ia52 zKwyssT$*f%{}awV#$SJ8zUn^mad#U}SDD~Cs?lCTB2~+f_K=FxVWqd~G44jmX?03G zg`sL^%D469Y~}eJ64xHa3E2^%vSW_$JTt6TOE|pdVcAQkssMeg^^?6xsHlYXz;H=# z!|Rw~D?^+N`77O-7Sff*Sg*PyE^-wnwaDbVuUlh*UMM!p7s*x`jjt8xZLaCD}w!SsY>BVdvft#soCRH6o`DJ5QssS@pv9VCw;E=2KdnC@?_|#OXhICRYCZXb zutQGHi|-K7=>*4W{W+!5AMtTR#n3;~E8XwY>R#Y+?(C=s^Rg`WRNKOsDfB1PdEeYP zrQ2Nz9bitDZ1EUCU9O2eM4Xr}yrsp8a;qsi`L!YDp;aGnf<;fXo0twpkM8Qdy;S|@ zEPRag)CX?k9ow+kpH>gNl@&pcZCe0B4T%zC7plFV)ul_SP0J1`{gGPbf^Qq$!gL-4 zsV@_0c-6ltPvTG*Au7@pK)ykx@`JG<_zo`(zR{-g5X z=&PBs@<9=A-kQ&xwLFU&y}sXLvRL-oS(nV{Wq;0LbHwsH+bR7sjOEwt5wbwo>gs5s zA99n@l)3-Lk751`KNkIFc;IVbBt8+z*7u^9bW}l-e$aDstXbFT5%ip#0sW?o3zH=s zQ1&6`M%y|w>f$4swA8_uAvGs$d8l}GSTBQ!NW5D#d&uKsC5?6;zvHNNx(2fki;!0GIu0d8E8$4#idQeYqD3R{UfEv%GO|8W63%bo|leTaC_(Zua7TzVC(F# z_uXOG4vT#F_YzMpm{!Rs*5X%RIMA+xnWa9gss56U?MzG&M1T3}r1S_~2Pu%*t^Hth z>pc%0yyv;51DU7h- z`?X^25Kl~Ee-h(q#gqOgzw-d)(GOCmfphm|@D_9G0@Sy6?&#M;_MvP{syP{`=3Kjs zR}LfYhq^5;yT%90t9F=6-+-9>F(rGORu2EwgynP5f)s+UY`4zEFGd{+RIk*XHIM6+vWcJs@j$ zZ3^*?^HB%_8AgWCu%bARV zf`F7Xw}Z0{K8aozl28a3D!1uO5n&GH$ZWGncrTEFW_P8vwXyR(B2bLSF!xrHA|8vK zWWKawP*Tv)kg&4Gg@(f3UG6Kbw_JoXKEL%`j1{GLA1+j@<<}$x{wawux931W!jun& zznA0rSIpQih`$dLMQkZj$x_?&=f#SY`uh3-IZ5gfm88cUolE$?hXVW(d1b(aN%^24 zk@y)&BDtF=Ra5`0$Zo#VuFA>wF62puK3AE^@?}sDgnw%qALkMi!Q&rwM{G` zzTU@BmwU7;i0{2>hM08fYKbf?c28__{g*rjBE1kSp zsAt^@NKXxCiV&$zH)6Q1HXL}(r|6ulv|J>{iX(ipP`M{v2usd4dqK&KMlV$m)H}1> z2@|fCrv+XXB@7=Fp@u#j=pNzPST$3kYw-pEEnj}5p$V@xoqhQp2=p^;0tEH{(;J^* z142s5kc$gD4#%T|Bdfik_KBgycmx)c9ns2Qi~CUlP0!mGGnPOMzWndeiz&US$gr}3p7v$KX0&#WaD)fMH0dxrU3EfR0D?5}ZF_=pK=a^42tNXCXjAGnN$J{z+LPeE z$`ZQsw39`{ErmbH&D3-TKxbIW#fm`0zx^Y+-?ZBWXQEbM%r#e55HY`KWow!X#}xe-hdX*i&cJznfNrVZ`z?3WKU zN*X#ri<6aO4FCx5Pr1x1kY%R4Rai;Sh_za_I@Y*2nh$6^a!N+cIHgi+4vxrel3szQ zXC@jwC~`Zaz|~p_2@>BvwF0#|eLWCh!PUrKpZ@Wv#MK8rf7I@O6*<%bcF~+yj}s>P z+X9^Eu;pjdPs<5+?`BsV5uSgJ?^j>~ws@^(JAM6o%j||JVoN~q3QOljX4CSa?k0o} zX%B&FAjkEL{)kD7?#xhE?N>35W9K;_XZ}DNbDhapc~6PI)yuV-6trrRs_wlO{NuQo?%GuX8s!t}wYg zT(c~<-m{j7r}d#6qtfpT;S%{f=?rR)I?^`tCqBLRzsM`gKd`^&alJxJ=pBRS-}zw7 zAt+4ww+HsCb;8p{#=2pG)1r)X+?(*YTG*pYgCyVe*w|(zYN0gO?;;@2+fpVm9%ab1 z*%_U0!{bB-$-6%wi^`SKH$B{WVjwAM>xQK2>!mOt3?QvCv3x7gdL|7}6874s8qfFeUq z@=whG--=5A{g7WhF#&{MknbNH1olfECpIEGJV{g#z+TqY)=tjOY#iApe0NpwC!Cmb z4gG#swh>)1Z&svI=^q&Q7I>*lwfG2LR3Q9$$8&NfwLU#2(P%X6JZa}6xhMuQSq$&0 z$b#e~*W3M>-GQ-WIg5*m;&X8&=jG**Jj9Vj<_wrrf55?!baGCou)hH<^d_dYXg|()BdPO-w6;7X z3W9=7jcUVak6U6vyeh(z52P_494zmnrj4iF(MZAWX@QxetaLn{zeUY7LW9-g#yLo81)gVekhlFjFiKh9I!@tJ` zw~^2gelWMWKcKaUxNs=0Z-$y4RUW^`O;O4ZNdtxy5PRl4z3&Ql8>N3BE^GiBp|QauGz7{OJjz{ zhsL1UysqL7DYW2CLtQR29F|y4;)s-1Z5}jVD*k@TUE0*}-AmkZYxM}f%o3_Qh_T1vypjrlX0Xe$h0laDDPsJF2j#Mx4!bUm?Zg*b8e}- z?4L5$jB)@P)Qm&GX}rqfH-#Cyi@$V70@I}ne;7-kX;-0YG^7!)4JWOa^b;ZuNx0P| z35t`}>F|r(Ja2%Cx&oz{v2mo<(Om3BD{N*YG+yO2_MTIzY4))j-tf(v#1{Ko)Y|pR zH3g0u9A$xq@oa9}&eAZ=Ee3VwFSQsf*PVWF&RF2Z)Z`n3woFyuv4l=Ft1krGucDZyf?!B4S#S=qk9hb#;@|@NB*A>GY=WW}w!*TBrS6=0V=A1E<3P8K=wRyVG>xCtP&R zl+iT7S0@^Ez7sUFW0P2A%4NSgz0^{5?UD#*&tT8k>X&A!4)ikJ^|c~@k#@hl`v{EB&Evs!)G7E=*K9bU8Ov?;@J`||aB`=LPvuAm);WZ0)+dF;x+jWA~L_KwJ zmskw=>}y>$_ym_n!IUL!nvXx}OIq&s8bFbbWT)@m#f$u^X>_!@?mRx9U_Er+>WD?R zLwFvKao^sd%6MNsASq?F!w|5cSIiC>c4HvgMM!>}IeAmbo5X+9#&$pKI(mA10DjRJCq@-$?%UXtYf)O*OzUZ&!WB$*r1QSXhI%S50=ql>;q}J4LuPz7Mpl z#PD%I^e(vG>{SEqc8)-n$Mki?$598}y7jf`#p~UDx7lqKA)!6oB4FP!*@?xca6Gdp z>m&$BEf03j=F?Yrj|&k;y23WwzT8dVZoSk8a=gZVq}Fuh4}^nH35);LP+-3ZW`6H_ zio~_ent;%n+5w|=+`F?WEu&28((9DgW{qyl>xOP!nX^{+l`RE6CM8~^VU0ZX4D5yA z89x-lC{}*s_kIa128pn_@xhSU3?v8Sl9pFby})qg+-|v|*J{3CayYi)2s^S;=UoUa zc~qY%V%gr=+23Ycd(|eEYnu9tX1~$x^cH4_{E~!%{4FJLmHo& zxQYksVHJ4P-T)O6$mH@Yip`nTV1m(THJbo*gDW1R=S-1GC?@k>7XdP2MiVk2DQN%@ zt5r94IG)}Ikx&RbF_qbL25}N)dtZ~t20BY}yXGAX`puqcsD<;vnjZ|>M6Kn@U4*!R zR6VhH>=+Pc(J=rYW!ehCg6g8^y)g&oS>@W!N-)%y%cSz3Yil|-wzmC!ed$`Q9@8~% zo;hD2lNtzZL@x?Iyzi@}`YlN1e)?Lkh9j*d1_4Y#K#=?WS^f+2;dlv{S(wDZ^OgD- zDQNeB5lY4$*6DOy-j0 zy|JDd3l{LLo`Jzci3X=*0HI_wAc}{n*}5o3$HZvYf=tZ}OC&P^BZfR;6fjUGotBoC zDsxaQU>#B{)eQTiz1v_*kRSogR#_}z;^E=_k804vdQ@XF6HO;YxJLlRqRWWs!~6GR z8;yq{fW>mMl1~5==09diE{Fkyi|YAEuVOx;>jdQq`=yFgy;bBM^3Evl^? zHIc)vgu2(ahk3Od*CiUNlu<*V#UTe*dX+)XjaqXayPfGs^kcaR;4Ir)G=fZ9i8C71 zWEn{j98Kk3a(`Bp*9@|=fe@EDKjPwYBPRqfF{1hfzJC2^ZEX!;ChIw|jXR#{vMF)0 z@~4}EB(3UIV|@7o1yx{Brlg;ZL}mZRXT4(>j7jjx(AbGn19l>G#_;a;lzSIY^+fu- z86c0T@CyjM2I>P8CC30Fg5Gw6%E*+I;T6v($v7H~i>I=wch7oQ?bbz6o_T)G>DSIg zp69Qdva_<@sPA=g@=;>Dji^W`5!AZqyhj7mco}TdNqIaYccZb z>?I>#fezVFM<$RT4WqMN(BAE~J&hPl5x`I{Kgqp^KAe|aV3(7CA7#o|Jt zxe(j*paen0Bd`Xij}j~4EPFee`fJW(dUc1?PDxJ@5Rj6QlJ)||LMCS*P&G0#avfmO zV}BDI9DH#Q&5>c~Co(xcm4<@(MP48=44~>*YPBuEz?0~=IT+W-`5KX35O}ZQ=kNDq z(om>XtJrqUqazB8OUqO0S;7XMi33i#R1;9Ly#HwGOaz;mCW$7`gimN5@4l% z7rA%D&zs|S$x=z+bfi(4Z@fJ?C!elioR#PL`x*gU2N2)SWLoO?R{HZgMFwC1|EGu$ zNB^t8i21(%X_A%sx5YN=gIIFV-%tLpx&+uH{kq#HC3oo#DxmbX+H{vpTKyEmMwmxuW>z+^X%3^CIMJ z1_U5sVC3tGztS&P4h#+^00E#HJlsnMclFI&Gf>|hai12 z6tU$0ZMR^0W4k?)4IE9(HH;v$8ZoquL(t%{t;c4?xUQ7F*}s&T7ezj-`es9>C50fAI zUuBsu9v!X!<%WptfZySuknW3rF`Z9S^s85hLljTa9A7mZ*Y_c^u#Hq-9+Z^rd3rpe zrp?*zv8ew2F4D!OOu_alIjz8bHlaQT4o6+(_+PYUJaiRRWA={orOQNXb!(%Kbz$SS zRCoQYxLim@VEvt4=)3lleGY6xyN_h_$cDaf@~R3%!~clZTl z)EnvJPkgE*6ZN(X8L5Ck8&KW)BxKPm9?iyykxhPo)y?JLceVLLyWgpiGu0q#K~B=A zU8XQB@2|bDD@8r}h_++qC(QOmXwObnB`BZu4D4xkk6J_emXWVIUX@RZG5RFUlZKhG04(F@?P}y4u+!wxne%h}C19P&a>C+yr z5Y!y5KN5YgIyCGp$S#rsGWF%ZNJF)@JDQB@`h>)ZCS~a0z>rCEFwoAbj$(PAuuIv5 z?lS*L6|+Ef7B;%fcA8+uVi3PI&sUBs@X(dV2WhZ2s`)^iM^*80yY90t#*cI=&0=;& zSlsxOp6|=hgFjR?+p*(3M&-Cv2Zd7=vTzZ-k{^Laf4uxU8%Pw!EfLCpzM|<-_^BbSHHGOv1O?77rh=(9_~lC}mI0OiXbscVt-ax=G`gX1IoNNSZ9EX(9I4&u zM0gNI%VLQ*5fkQEBKVORLG8XS#ARpKVOa+exrZ4plAQIsyU4fK>7Fa7=w`Qi_m%!{ zR$~h?!OcfCL_Kr`MetJGFY&L{K`g}{|sa|@v zm_C;&D72A^575_UhPT1R2iL)bEZAk1hMNmqKV4ySObg%gb?WSLq`$)VBhS+NM$Zs# zWQ*G95EE#35eC$@bh^mkvB2t<}X{G*($^Ww1p$Y+WnaaZb_V|sIGgQv zLsVCY{9{2?r-8&gF7zQa$89ql@Agxd^cFgIu;<+%o!OMl+3yd|t?Si$saTa*&W)ZW zgx@9WTj0*fZL=;Nn~m~0n2$l?o9`R!9W-4g?G7=%C)-^ch2oU%L0I%aslcAHk1;qk zPDP*zvXCRe&}x?bf&6Wq>zv_(%)m`8_pUR-*h52G7iqrCLK;_Qbl9&fUqF-vcPxr) zKXg<$SYxUth`b$-zIuiT=rl=fC}YM|R4|-f>FF|HwnNb5!oWf%hcgVJQlgfgaj4h= zr&$;l1;tQtMEpO_fGiSJEpKlh`VT{1?ckfMT;7CQn&efSSM)bfhrit4nxNGCsx|4*8O3A_+mF<`CEX1%XQV`30}IrJ%6LCQTPxou zDRC8dT>Pv|j6Pf(xSFtXsS5fy2kz6KxsjPETI{%*aQeVKuzk4F;{WAQ)Ypk)E~z58 z8hpR&!Lu*h`8;O#w$HpS>!4lE6P565wk{>$Hk!y)o^y*(#y#+}QQ;lyFof z#&H|3|8}yW_j0zhZMqyMvZoVN;Jh>tA9Tp>M%5x<2dA`FggU{JD~mdl zqI|3ycUvR&(QaPLOp2O>zTPc$e(me^iny|pQRe~L=iExEOz{vxFr?y2Pe@mZ#(cRE zp{IE`VU92vgopV8Ql$$nXD8>xLMc2#-3xLmDk9qB6A0Lm2|2PFUAU7r3(8I-x?eAc z{Oae~u%$wwgvRXHQ*QkHUwy5eC$o*#rZYlU`R6>pu9&zwu&&~EsUeSEM*Cm2eRnim z-`BU2AOw*RCW0h-gy=mZh%joJ-s?mey)y{Wf|2N5ghcc*dKWE>-n%f&U@$r($}``T z@AG@!^*(>S>%D7P&fI(MJ@@Q$_CDwC&*$tDoqd!A$aw1}p6(*`3eJ7eZ@^#d!cLK| zFBVWt56iY?SGfu-+XviK$xNY=g$>%QGU#bm4%R{1uXDuEFzg=Xx`KHz6N0)IE zaS$PVD$vla=l6hr@19y%(6=-@XP03dxRpp$UuuxIwQWvzEVb4JZ3dr$9a~spQSgD> z+e5`Y#TKj~QSCOBW|evXN!Qm*p{achV$7&o7WeTTzgsax=X5D^D5xGk=-##nb|!)@cC_<5(# zJNc<^%b15|8#4utMDM#oaCobT;yS>h%}aFCbh+>xw7 z!6P!r=pxExA0E(37n;*?B^b@W-%Dd~x*?s<(sp2R8>%K!WvleZF5O?TET`Aj|Du~J zN_Tn4ZJD7HRvSkV>dx6&?`7FXLW%d)w&}RBz{m9J6AzfMUsD!l1>Vyqut+r@HNx?G zSvkm=n}<{G6`6U?MERby5ZeLvBp%(k?(G*Yv~YakXM%Hm7fR=Kb{e3>wme%T-K zb}s{L+0i+qy?b84XbmO$IVE@?kfDFO^}s_~KGB40Co(r*J(H7VWN6|QQj+se^9*ml zdc@V4H;A(_YRsCTIr!+u+el~}BC|{0hH*tZ3xiF`{e91wv3^xwqdyi95U{9&p2)rm zi+n*p2eW_n>IqG_!TGnKG=Qf`hDg%njp-R9t)khd-{1SxIzQ|34&zpyi2G|-E>ZZI zW_c!Bz@-+bbofa-*{9w;H(3c9ut)>!_{&gJ{s#uuHh zNt&LYqh+J}7X9Vbe)O8{ke2KWIq-n`;MeEf3CuZWzm;CnFkw-VN&3#|B35SZK^1%~ z^aDoiX{PfmxCph~g}7LW{VdhpGt=cq6t*cDI7Dpl0B0|XsJ1fS3%6_;qjttB6zxct zj`usTEX`AEmvJt@6eGmzGCe3R05ee^QLtD0@Rp;31B zgT^45XYd?eA>Qe$s1zSg{(FlpMg@s58(94%+Xnk67yrrN5lL+Jz?0oVBSm z)Uib(GV2rjjvlG>4^i&!b#tcW@D*7bzEpgo4a78gM`;7~TksoJ1;&y%7)N&$Lk-W7_Dw)`3DpFCB8TEm<(=epcQklC9LiD-J)6RLf)) zA(dgH@jO$p#}3T(Ih4hX1-PZLBTp+!{iiUNfuITRSojZlBcHYB_oUR3C&UKak&jA^Vtm}D3vV?=DAt}UzJ*8tiDVyxMj>ku-Kf!U`pcn3DY@MVObF1 zqQw4^xVykbteDp!vxZr&#>ecuFXp`Fo2k_<3llf{n+}2YYNh4iISo}qN^pO?SRBa0KCtjksAD^2e}@}u9);m zpl<}ijGD!GvNl@C$yE+lM#7S+B}cB`+Gc_kJyg8J zqMi0vsrd2U66O;)Zu>2uxx11IE$O3r3>FR5_sVHT=Kb{?l^Y7}JbV~yN2L8n#BfK|C;SnUIx@CVt%G|j8U4@+2nC?3}oa6T{&eJOBZQP?MIDa`q+j9V3uN$ zreHMnms9!Eq-d|z;a%kV98bcTehDg@8ZES5CVPA1w$+u$dw1_sin7dAHne|4(a}TD> zm6W^X)Bwm#98K55~MOZOn9K9fo&nBZ&jTEB}Lr!5%?hv!?ym+6%)eJqSj zi5BUDr3>EI`j#Qc!Sbozu;mP?z1x-T&+k8>1M?I~Mg(I#VFf@l$|YMH^Y zf9A05RJ57n4PLh*eBBoBMvfSAH( zQ#)aeq6Q(?$sy{e@7&9w18-W1u4Wtuj~@I?=@GhJERU09@r7oUmJ)n@W<@{pPAfr9 z6!MS*l~#2yp50aJ^@tHM?Sek0aXlg>%lYizaZ|IMaqgYgxPjIKjgGOrgvNfV{52h9 zEa)()(^y4xabxz2dJ_ewNjq_L_8#a;H=B>TdB-lKMzSN3C6OnduHbMfKF!y;kz7Og zi}~o0$TG-vAfl!bO-9lz37h!>B~3g>$3YB#O*3W(Mn+-}H)r7HT~vaCf{vpg4H5|e zUSDKnWMX1tcfKx#X7`)7X{YXamcNUL$nvDWD4caOQ725*vb;T(f6Zk*MN_et%fMs5 zCM1~l=0;xZ9co)yC9(}8U@CiC_A28@%(4Z`m-ABrLN$mzW-L1^>1!mv2S{dPcm*H()VtKj|fB}dGN~)yMNTn#U^e(M*JM0cl{47mw*rrzh2*rongf@)PEfNu`1Uqh+^}3C|TcxJHILFh(6c4#H0z z4rvdeQpHIytv(5fj*0g!4&-}Z{9C2gaN^QLVRlksKbf00E>-;{A|A9N5CvMq)C|5* zsG*36v-s_06pHzOAbokQkpLkE0kih3HC?zBlK}7UA+KOFN&(X z+W&*&^`iJq+&_rj?_)F?4|%0Pp-@}992$;4pK4EX^0@f;iZ!KvL3_V5zWNU@{cvH0 z-5kk4;8j6{T$sa}%3?pnf}VvzW`y>!Yr(VI0DaB>hUoebu)b8P)4YI6ADEHecNrcJ z!vEm-<-H1ip~eb)4zXskV)OSP@gaxQL^i$cP%vAlE$*T0O%ljv{zgl~EoM9Zz$5g| z@A^d@uPa(eSJq)jf!cQ=$|WieC8V6e^-3E;IBUsPrSSS)PwXtvT^_4L4yCo zBmcj+{f7(NLp{yJ#ZAdM%51f-6Hzkwnyn5N5f1@ZR44-|T*yG_pSV>F+p46sKQrQi zi{iwVe`$#8a!yVHwY9Zu?CfKM!*WV56eH)RpDbcEd$xGFm&JW|_V(H)X7sXnQV0j$ zA4^i|{o5#urEoApxtB-m^TgnwLU#t_fab&Bc2o+=^7wxPAO4rB-i!YiVfaUgc%}R! z#9`V=J5l$INm*H0LMps3aq;_eJXq=H=l4WW5l=JLHUDYo1&}_Si#;u~CJg=@d~hx6 zHnlOeF-hgtKsM{vXH6yF^vy1U8k>>Qnwpyaz+a4cJQKe6zhR8`@2?eV75suR>_q>8 zF&cfuy1Tn|9wgkK`GQ5{%(TB@xc7iTPlsQJ@_-?4Gz5YAR@oI|>jB`wCM&*r{G@1{ z=Qrm*Cnra*Qu{AR@ExSAqQd%%gvrI;cZ;iFOc@{SWpQy4kGNz{S5f=_l)1WS75PEy zpNm0b0Rlb5@-@kdO+MxQhuMDt8+?csF0MPm!lQGhO1y7FLSiyAjUlNEVtrlL@-MwM zHz6w%1djwt&NTgt7IAhjI)2U7Wi_qTv-Kr4d~Quc65*X9LPApTCNSoIR8vxwx~@DOFVt9Bn22m|v&rgR{4oW>fBG-x%Y%ftuUC@--$6FKZcFI#L#oK?>>{hKEs`-HH26)rewU<FYqjlrM2RdxuI zMPrPkWco4A(`l>&%)gl`u|;P5$FFc@va9p*9!?70KKDi`o!r!MW+#&B3ckds7=2}t z#KKu6%v&zKr@>3kwFHx;5|jbsSDqVqpFbw}CPxGiX^Tg4LFP*u;OaOabrhvoJPvNk`rJ}7qG%SE;s>m>mU zBw&q`An)d$?kVq`Qk@cy&!mXkE~K^xrSTfWlkpv)O*e~euModKf~Y{qkH-tFDD)w z1gk{kJa4w#bGb$p_!j4eDs0Cb@6SH>mG-~wvDM@5@m?)M|2ml4Iyv&^L~^KiDj{2k zVhk@sD}Ng@CG+Q<)6^NJddh6t4Zv{B zj2DyM@I~Yv^(i-Ia?Ai%hzBXPWsH@2jObg#b6wW_?UA3Vnn-U=P8}lHjFJVTqX3r~ zPCtonc7{t!KPdDq6N+GGQCmVTXqWL0D0`-!8#w(`OJl<7<|@wQ#D6Jg^O3M5NZw1T zwd6ny9EXITv6#1tRSRU(@;`BON0ZiwHHmdIi@KvuJ5>-If>7g~tiDSMswOBe$m$|S z!)ehBsB_40LkP}|%@|Fke~3#`$Mi23Qj*SdVjm?KKdeiRhyQfK+7lQ{a?T-KnEJmI zRFigmp4zxS*}l9|y<>0x$e;7zJ17v|ZG=pJz9uC${+aA19Fps#VVBy%F79Kqt-#*2gxvf~ttRLnjt4 zNLl<+o?`2pmQu3(2r8PzV%ZbbO%Lm4RtFDgS`AZr8} zQwh{9+2{yxo`p)lxAm z9i;Dn#eAZW2m9G7YEg@?xIo^He>O&ZuT+nVyAmJV_tf7wbObb>Ax%)+;CQV&TtG4I zHFKQyvnLUEnkAz&|Jaowr#eT%r{)kJTEdx&#mtyHB(4uNQV31La`h+fa9q@W5GIL< z^JUgPNN%(Bh_oEhWv$)*v?u;(sJS7H7eb-G;eOcQC;)DDbR_1x9Y>R-dv&x5ojTg< zSo3zUnJGQ$=Dm|%&g_BK9)6o^X5A}C`@|r) zRXcAuJn8#QySWTmXEW8$h$9peU$bgt#Mg3dT^l`)A)32x*R%h$Qa0Un`AE(}B~Ys@ zf2DF}tw9aH3ID5+PFlp}0YABc6&Zm&_<+~R$y!D88aoHfK6uKkHSnSQR!aM%yJ9hF zOfHBfO*y26%2iNuDz2F_O;nlN1T~CEszHBuSLo1;ZmP1j>QRLzLMYQSqV`=$YZ>&&mraP zQ;+WsMDLo9?PI6NuBAT?{QSPpn!UXpzoqozjdf(gzWj*A>u$Qyo|Pt3 zs>{?J`+SJW{DvaWboHS-Yl}>m5c-yRnkHgLcqgLQEbPER;WKytY0)W?{IkPryL2Wk z`4zloK=PqD8g%9qg+qzC#taGqSYE;A%Fonzhw1#O zmcY((1tZpCHJ{V-CyEhNyK$YQ;z~#MgUraj0#I~antngk7X^yR##6Bbs)!to-p9qY zpF}1!yduF3#mEgUyw~k0xvGG70_f!JCC3gGFfMY8iDP&N))nQcqB9}8%0|%Qa>tx6 z3Z1YPy%T1A73~UZ(MwaaF}+Gpg$?T*la^%;->1e#Ay(zT8gquQ8})Y(Ci@CsgzwUb z;DYHV999w!OSZ!?yuiL`g>Z>L_wmh!YPZXzU1R$P*fw37`AJ@Q2g*3knyCd`-EseYg)@I%t%?!tV311-vbhYtH0joc=?Q{MM@3-5j-ZX8mrXgs7d zI>>C#0bsY6E3Q8{#}gp^nZVSF;cz6%1beP}*kL@-D^$|8$YrK6q?G_}Laa~#R}uqb znR`@AX5BX%Dc=$rF_p!JI@%E_#L#) zMqw?t-YcvUTQ&2}+O*Ijc&IGCb^OIsvGKAf!>jJ`LzE=u^$fz1Q38`Dl%Iw9vZlUW zKf2fbI)+_kRvcFJw9HPz??bdNTRJ>qv;f{c4r0``IXw%o&q1$Be&tZD-lY!OE zT3!N12IbZ0&}iGEAjX5&1Gx@TR{cHegP99jg+(BZBcShu4-o z%y)2fWZMN}itwA?-u1?@Ie3IT96x| zuAVl!>c*m$Q~44P8NLozXKaq?cMYs2hRzS7D0!!wY7L9jD9K;p*g;mE!!3hu=@K$u z3s^yq_C~=6gNJG>c8tGD`k3SAj6$#2o4yH4nE-x5>o;d5m^{-$K@D$1HI2{F4sJWl zUc)FxMJmjYBJd$dSuK($v5))O)gG{J!l~bdKLun)OEgszn5li|+WQI2SojT2<>^^- zY6tCse!hdurmxi+884+jys+wz*%T+AxHL9@eXJkCxc^N%Gj73nypa0$Yb+bpA6nJw z>zL?4bDKXkjjU{CyJj5E#$H}H($v(fJs}zqj-ZEL6&WMk#7upGKAK?zdCj0YFMi!k zz?J$=?F(7o?;p>|@s0LUGF^)=F%~Hv(c}wz=__QDS8emFg$W1{me~2m;&tB;)0+Da z4z$#M-}N!ZF&FwP3FIi5;6aox9|D)SSn&T3yb}wrkbdj2U;_AgL_|FU!dAGhN6zjz zDMmAEdU$vYNg7M0^XZK)Ecka({(3^`i??m2?6Dvb5s~vRPvzBE@$)3N7MF_9!myR^0QfSS^T}dj)64QbhM0FU zOph;tf4$Cw&MHV>Z!cG}s*Sg|9?rLEmUq$LQ<_=f9*u~wFxU0)@5r48dbTrF#T+GT zxloyrGQ`E8tCcrEDwy$uiH?uiqm%O{2U~M?%Gu^(#Ov!?-)7#C%Ox+<8%^XLxQ)~~uhm(B z?0Z6fTqPj*C~{g=eL7l2$nN#qnjb3|$?;7aYKI3Ct7Lob^&ag^4ngaZqR6*s=R)vmxIW^FpyG z?}G}KJ2|=e6+;ughXhaq$cti>e0ne9<=Q_Erv{^D$uDD_ zg`KhHDQT4!h=OPG5nCl0CWj;ef_KD;1KuGu`=+0Y%vURCebiu<;&Jgdz(%tPTS~;t zEb7NBQWpSkjZJIby?kZ_P&d-GRY#3}eY$ib1^JJB2ncQ};AQ&jp#8z^@u%}VX1^!? gCrOSk;`ep(W9phr!ILvA*{>Tw3hGaa=W#llIQwjQfz?RTA-u0_&z%W@{L*^!W1lRU;Yn=D>2DAB8R=T&_ zm@X*^iSWSC&|JN-c*Fi#mI!gY#COzi5hv=IO*_cH&i=ZPurcyY^(GgN=ojo)EhV1ZDx#&jI0;s z99)a}`0!-1+q<1AC#;9QImT$mHoZ)WuC;o^xpi_%bYLR2haliJ*sizmV6oY4jOe;= zl7g#9{tSzXI;iQmaynK1r*&Hea7akvs*5~WDyqq#6-5dnVq)zNlz$HZs(n0O>A$1l zj?W~K{7(lr9RHsqLlmg;Px;ZWq3}wi|EPAy4++?+v%Lj3`M%e&A>ztn>l{6KZQ!Me7p|v};}aOV3NHLf$u4Y608T zQ`MwADvKqLg(ztoy*Ji%O#T}HoJ#Zj8{1nCP4yEWT5e?sAHXr+B*%O)RllL@Od9@F zK?+gzc(1?qsL&F(q9niE>gY3lI3uLO?7db`zEs)8hqawwC~Up@gC91uUrr=4wLDLH zxQ5aKcLlPnA^`lSuyPo8l1MX^;P>x3hk!%>*%nvh0;$kVf?!cp;Ky_Hrr@P#XL4o> zDP5!C8G4H-Z~qQ-p$QO}+5j|xy`JI;I1wO(LsahIhM$*})v#vZPH0GKb82c#XH zmgaU#wr&4JpS$8_mmLSRuO3K8hr||8G(b};#AWzt7MpcV>8w1HB6gr;PC{ocigdw9 zP(6O{I1)?rVmt;if=iuR&g@&%Q)NTP_l3(^b7F2}0Ii|(J-l<>(yM!>&3yr%#5!NG zpdKM2`G83X^nCr+U!^eA#`rM_2}wY^z2Kq1p}Kx1vB2f`f~HN9J)|GQhfJKO=R(%| zZ`n0R62|uqf_rmZ>!*fbyxBch8S~FWb@#uDeePFcog25WdQrfVIWv6M*}qfQPejFw z%y%*k*!D#-R`IlXvVMMjQ69Sp)m^Ojy&hf1F48kS?rW>En#&s2YO~bVA`WGhx$ZY%Rfe>{uquVf5`cT*wDh~juMGbZZ1t8#N0YPt4Q>l0z-L`V zIqx`@-S=lQ=bafw7p|{dqJp!hGpFb-5qmtP^Z6&}E>cG?6E0$fcNlH@iV{x$z{j7A73t?gTFM2iH1;{^~`Ox<>UY3|2T%*uaqCCgV{5 zi8dDPZcC9N%cbe}^p{F^#|I%)#9W0jHEV&)oatMU#4zsXbmcc}V;$&waxCBLS18By z7h&&v)vW&L-$R|R^Aub`8(`F1B_FKph_bP>=oe33UmBC)C{tIOP1z7K_(HY}T(T8( zNZg*4eN1utvfQux0c5AzHs~7q;=O;Y;Sk@eyXg%yVR{3bQ&qzJa}0?>zW@$|9N;G> zgOhA~d>F_2BP>_ACk9+YEuWpF8&|ZNA^KTZd!+)2OavMRI{fwvM@G+J!mKT$cH%Dw z6S(?$z5?w+OCEM(O0?{!DKfx`QYYrt6 z<5OZr4@w##KH?u86Q7Nj2JnZsqWYd+Asy{YKM%O5ZLeTuoAW8AoY-OR-_qt)0D=_~ zoBd7fTV_vf5?U@kS*cdZ1IupF%Fu2JMwB-#G5!!SU-i9nHNF%t{-{@xS_DZ(>+v5r z=tsbQ)`Bi@`9T-w)H)_^ul$*T7g{1dZ?KfWYocLeqG7AS^yg>;f4z*@HJduujiV#Q zJsdOXY&m!LWm@PnJZu~iPDynU=hXyxC>hdJg0FDyVRq_d%uPggEA;V9?&+;1XPzcc zr9*U~>VxsD!~;JA3$ZNQbgOcjiOP+Bcv_Dr8f1*kBTb$EJs>qBI4=y{%@>FpI6Pr| ze#+uQTse2zFZ%W@GdSV;&5aEqT8tn4w+uiZH4T^+-oMQwmFk}2Oxzp5SO5j!<4=*i zcFU`3Rm^%vj}%8RK9KiEb(bp^kx>uveWiTIh34+z)kb6n`q$oU#aeS@?1>k5oEdkM z>By0+?5j1>)#J-gXAZf|vEsqB#jxCnmzan&N48=~1?1S&j>b)>K?umFkU5sXNIy*sBRI1l@`*kyvRg4{d zWf$9z$!?d>@`5r;1X3d8AAZ6tLnarhRclSzn?B;rS0!Y3*U}oDPGMPWP-R!o_Z*Zq z135hzaWWaBQo#AmJ=Pu2X@7og>^5B6qs8wjK~`&{M0)g$7sm_YwEbRFXLv_G@pjH( zPET$)52@5{2FC^POPOj8Xq27RH@csoeCu>#Cr4Egs%R-P=RY24C9Y|o`qTq~29g7g zdPhO{ng|$UTeWh{hko}~Suy2MPOG~6t&XVsK@ERAXM{H{Ii55?3Oi_K0B}anZKb{N zH&OP)B7UUMayEOjzvdYdN0FkLrA6!yTVPl_j|C2A@0x_7}8fo15@@*}>b@*rx*RjWMyeZh<@!1I~ z!XDd{Y9X)x2m7fO>1fwQ->a?T%Cceq@X5u2K4C}D!UBuZ{G5cWEIBJ}bTL0dTh7vO znRsIdoKp2g<}Ic3l*+-WBjH@-Sv37T?bT%(t?;yO`24h-)2FHe@t0+kbcfj6G9dIjTyvdajk`wBax* z+o#5Fz6a3W*MJt?OOdIMMdhwMN4Hyvt@Q5f$Wb@=-ovu(4^KU>_Ae-+*xt@%Tr5N< zGwobLFhOK9K>{$xpD2&e0mwkApFmXq-` z9AOGPVvbfT{Myb(mVR9P-O?)}J(dNQC8X<-!XA~Kp4^Y2R7G`7J}=~29;T!SV95*- zL%3j6JM^!)=g^K)lPyfa=2qgUhkw?&0~s$_)i`nOUIIo3-dNPDaSZ0g$sAb9%B zj&FCSdx{=-BN!L8xSvl*&O7_uP2}N(N6Xry&tg~3MKb@N_q5?u7AGgz;st0$C5oE8 zf@-o?Gu1Z762u}^YVY>+yF>*t^tK7BNo;;&!j)}GLeF;AQnbM zKyn~|)K2ybtZj~W_AxcA98K<2Q|m{l?S?sz?&fgYlIOBrjfzLeGPL^Ouv7eIq`%Q! z=CB0b=a;U6=pVsd^B=<_{L(iTpYGV`@qJI}`b?*rqe-t%su^jUhyG9u3dP4A@YZ)MCHDHf#hr>DsyLm&Se-k6+)oc~ zSff&$ZE|>%M+s$!&N|e?+tT#YyX^7UZ*~BFbas^AG(oLqDNP8e3+9`y=$vD~V{ zR4>N!)dIc|3pkiA_;zw1|vRw%^;BdeNpUPx2|gA2F;cU-m&TUZckX) z_X*`TkdI-Yr-I(e4=!)|Fas^J4tH&xb74=llcAEo#h|uSX5}%gN%7N^F=R?8OE09| zg%H}7bC|_O4^NY*Ziu(3r{@dQRk7@9B8@#`;L2CGt7ST8(V)4f9B<2|8A6MsW4mpo z#WLkmsTcv8Usr)H<>zl5j{OQxQ!%^19>l$qt%>&$X*JKYU5N@Qa^kVJIZn ztX3-VU@9OT6;2lm!RNzR`?ZEFXSb{!u`8Qnt)*e!2K))c!hJOziz+J4ApR`~`&hDvhh_`z*++Mm*-zS8912`+N&YXY4 zS@FXBQO!LCYVbfUszOQ6CcC-tI)k!W04?9-zP0|#P}HVW-(;zemPhw9XM$yGeOi+r zwp+2;Ql*y5%L>iYk2ljiwRBLpI-C)t`J3G$_r<0+Xtf+?(?Q=lPozm^Oh_-rT?Qg} z1lUJNr#`u|&5O@qrzV^Hdf&zidAQeuw4Q$_6O_RBoMU!V)s_j}5xRhF%urv}Pz1t2 zU%VuH2>2l`@2z5=tpw1mKAN`trxGv<{3tM2}V3(n{YPFQxj znp$jGQC%?g8Y^t>?h*g%&*=Qivxdv??gzq|P;p!_FNz<@`*31+L*mY>E+=58B@8l@ zi13rNdWY8>osqwq(B+=O`v5QJ#l42}yWT`Nz<6H#y5#+M%)>7Hd=};XQ~TAWeOtE4 z+}HXQshnTc4;P!s}_>n&2=mXba{eh8}@MFa@4;!Xp zC8~6rKx8;UDkqN~?s38}Mw{4Dk$(N8p_}IMOyp)ir9VqmTX}Pl9XgkarG{{9LpPMO zv?XtE)i|rJ$l20|p5WsmS<`8nPB(FN2o{BE)-eMY-&Hitw^~Pu_+4i z$x7C#eNp0)%(U#t`ZrP5Z8=G$@x+_|`%)u|rAkU5@Cjw-dSm7&Tw9B#fuS17S9J zMX=rEy%>=8g;zHlZe0lp)q20Df}{CwH!oZ-_`NYI8Ig_KBf8Z-@Gg0FXR_ws{me*4 z%TFO7e-YR^9e(wE@8e+l=rL|$UV!4&sx1;HBjb1wa#=%Vd zXjD(H!RygVEE;$4`F0 zLccKm_f0|)JfrtxaekdF|1h{T%uKNJ_RK7g9&1M~^>YYhfdea{;1{4;1N>~z=F@GGh=wUvPjb@24OY!{pbFeU)jbNA?Fx9-8PSSD@NB&h3BQ^ zP-NV^Uu@Y`JApSYE(^=jS?-C8miVg_imFR1-~1F`RgsF zwdnMu3)IphIu}a#%U|H(H)t~9WJQHz_4I#-PZm7eGOl3d?>tNM3fS|+IeG$*mCbw&54<0|uSdKtlL{zo*4;=Hd~XM_ zbW8pOZoGT-`BjtnSg;7zYp_geu`UmE#C(5&=!Sm4<0(Wd9MVMc6HE>TBuztV&c7Fu zzfI)gxy?05e%<=|3ZI>e(;GgI6%M@TMom=maN4n8qB&J5bNZ1I4cEN@%dvk&@op_5CFJQ>5Q4pNC}A}i`g0V>k^^>?XlZprXW$p+xi z-3EUy4Tz!t=0kLtiM&|{?&lnc~*}p3eq3c*{k6XZdt*&b0VZmf<=i#pc|+Ro$&)>lc&%62d&*w(K| zO1Bq?~Ge~U76M@*hZU*L`EnfEh`S*S|~zr2u{(RWVsOT7fq1& zc+d;4T^IDuTQNH$d_L7pw&-R=ni5U&rD8UzXl3i9V*|Pcx<0tVH>%O<7g6jlk#})zyT89H+yZ?9=clPSR2hU2luSH&cf9&iLba2=DMbW@h zvxlnLAQ}jmHYGHDH3}i{js!$L)6E_ynVS$TJ;uES?oh%b@&X~l4E$Z$Y!btj+{xx;cS|dhF2*$M%C%7 z`sEn4FJDpraO`c7A;feGO)TXlJg`PBAK;&XhQ1bT7-;3Vop!}D#r@FL!BesjjW6eV zS+~?PH0!Q~J9%v@a)|0@@da9g$B-%XEra>jZuFFVzCa!7^<@u4B2kx987FS*02_WeoJt3MIyhfye#I z(yIvH+A3w@Uvj=t!# z$-Zfy$MiI1v*A*EsFJ;tZKYy#yu2gq`YRKAyto+DqDF25jX)JD2q@F5wTWDp^Jsf& z9K2y<9A!M?I7Ay$$<>c9O$6TWUJ@1@x9T-03f)c1Y;-VN%c0-i9|&45TMS$DOqL4> z)4l6qyFyqUp)A_J34uYTy49Mlw>7ZPYLC2*LSOp)<$gcOJKDRRa@*(?JA5c}Dga!- znkp!u5M7G2@#5g(!@-u2#RYDy4Z&PO==DcDz#n(~`!;!72fofqL&!cA%ZR)i%3BM^ z1$Toy+|Wl8WOl-$dl>#^Ny59n=K`AlBp=hx$W_-rXea@a^aV1WJU#={C1hJs(GPsi z+sGhp)zQM?k%)O%;);?UGL;2*QWbA!pgpR3h`XfIjs~Xi{ zj?>Gn(qHZ_$MPGm)I(GaDNqf%>?M{9TN;4Cln$qbS6%XExqH2Z@KR(vU9%UPe;Ues z-to{!`zBAJB`ElU!BDGam#7M5#}rkLB-(ck^?fAbuoc5y@>!*v|KbGrbw<6Q)ZTA3 zsh`~HF+rpj>cuj;cvo-=M$o%=wFdF`Z691p*3Ml9T9+L$6jW?YlCTCk%eH>8DRB^@ zpWaVYA97^k1J^a6tYAGIdmbb?)mDV=6L1jWcug+!eD0n-kxi$+_up~#15&P!zv&v5 zji4p^n~0CQb#4KTGonZdy*5u#>43*JK)Qce0ps!@JKJbUs~zx9=-A9 zKGj}=XX_uC1&jYB zkI3p={Bo&cBo_Ud@RuT?F0LTEjL9-~Wrq`RO4UNhY5!+@-2&#G14`1i>rn!mjJh<+ z`pIz5KTFOtazcF3I#0}Is#I6+$+J3?lYN~+UG4$|(s!#pWRe%dms=r=Ov0@do-ngO zvAYOQrh7m9!98>|Q|qMPc_$mNuPT%NCubHr1*lNuiHg(R(uS)&*DAjGdAA(NKA;3rn434T7d&NdXW!m4|LD>?-PiBQwG5Yc zTYK!Z@tAk499cCb-M)G7z^HMp2h`ndf^W0Oco-3v)v24v?2i}ieBO&RF+tx>`s9y) zd%Mph#G1K`ukpEiq*1e7k-Jahit;$L)bp^V>3I5DEO=?b=jZ-yy6cVT6z5dN0}!0a zwyBS8XG*AGaXR&lCCIbz^_WBd*bXO8YU6$??oR*`3gaY)dO6`<7x5b<&%T%stUy@( z@uM^1q(H?P9QQCdGSGU;TPhW%!1A4{RR%r`SL0t6VAvlo`)q5tqW}Ea?;bvdP;2mT zp>lwH9cTHlemyUGtlYJyQC~!nj2OiCjFN5YBU-t5jj?Vl8)z*J)fKb7b?wlx_`IHg zk!L0gASWfQ|C7==mj)@3Nq6c{ebe4o$i^$x^Sotz<=ceh*JsZ7VL#N9L$bM1Uikcy zx^3tD!^<1^gZNMZFe-A!r>RpR@qr+c4BJBrkl^{#vtbwnM>?X>*GJ0ueS6aTY~R(X zFOZFG2G<%%=uxfffMYE$Vl=gnh=L!hJHx55h$X7YAq4CwnB2tCk7eN{MkP(@DP#%NdIpMikmBQMf>6DTgiWxw7P)T4o$^K6dFp1ga{#A6vaX?-6U-V&+DWTn0Q=AF)f^+I61TWk& z6_8r>uNYMx-E)88$rLF*-k{X9R9!KkB2RN)k(sXE^LE)re*_R-Vh==wqDXI6^r zbheInP*G?uk_b*@T@B8MlDzYe zKH^9sia9*ZRw5~k(G??qH>k2#re_zt2>t9k3S!8| zKE4a?6hnYw!)C5-41w=?>lX`xa0#wx<6|DC76Q>Q6MX+pF{d5*AeWjeF8fFLrBPpr zEtesjJhgN2o460`cc){bzd4_TRN`7m46UjBCh2j)Z!Z(k@yfw2PqlA9?nv7~9GtF? z2a*(5-Sm#dYDO^n!zNtVs?ajc<+7K1{YOAF0IVsSp$g64;9b2@W`K}Uy>h+-FQi4& zK$P=d5{q(72FSvoq#=cT*6uE-Jv677C?o>1M~5XXExeZU>hN4xiu| zNqiZSnan$AF^1RVC3Sy6hzDR4%fL-+Lg!(<93~@NqMl(?-e2b}J@YLP7@Jk&6mRkE|XriMg$e16LBA}Q!OLx)lMhPxF4Eh}8k&Lo-tEz#N z1L}<3zJp3(d24YCU0=-?bopB|fd8404^m5?a>mV9U@u6sj1AO_-$f8K>;P?rU1p%$ z8t$XNr?)l$M?rBJp5(NH)goOmkE1!@VcNYA&cP!!8#RP(0EFY4BVW0(ZJJSrQI!ss zaIw@$6y)q?)b0mpTBO`5ObRXZbCo0x; z=r~;61$LDD_)gZVDTeSb4)b-XS0v{wP%9JjfGrPb&)C{)Y;*oEU+?R3 zPA)P>pKZIC1s2tRzxA0vv%?Fn-+)RotF_g|QwuS;dL%`?^Y7JZDk8m!z5d(=f%K6w zuzBO~L|zW(R&OEJ zhrRYcPTd#;)pv@$x!qDvE6E&^WeSW}>4xi`K>!Jw1Kw)RPiJ7}3$5uMS zwx3|TbfhM9KYg<@V(QBmG(v^_7KHKG$N6mpPBZ;ju6EE(6%yS6pUn77fCj`Q57r#l z(FDy+8%gGv-B@};hfA>;>w~tUKv}?j8)U-2hUopZA>wVhovJwm_0G+9?lUdYb=q!0 zC6gJZNw=@t5lnKp7Wu9>6MOPyl^>4QTrMK=b#(8{ib?IVx73+8=>oh(Z#njFq|u*R z^g~mHRXgsiu0vnEY}L8jOVasdV+5lOYF5Oo-G85C&`@T|3< zIj)H2W~|%Decuk2PkZBk>Fh(Dc6UHpbDT_i#gamwL+W~L%FdW5uu|>$IG*o5<*eld zmT~l!X$@Vk?@Y85ACyu(#2nux!al>jU->T2i682aHL5dQ`J5jKGdjUf{S#4l5sHG`t$-_` zZW>P@!46drX|WBZ%uAR5??uQ*HTnyN3Ta{DYNs0-<7P)5*9LSsBI_~hVm`pGZsPD; z_7u(y49K9U7g~t-Fv{8;Qw$nVkv>a|w;Of*HQQpDEuq^2;Ry6H%l(Mm!o!FTr-Lp~ zL80P_)MDozTX-@oyT9%ArSH5Fxf2(8il-DJC|_9sgDdGM7j@~ndxP{>Z!!hPejZKQzD@?TMl6Bvg9wB!DTTb7tT;|RltxuMAq8#9oP52-QbJ5(!uG67~o?F zk-%_z>d_Ny_F}~uvd*e|{=F^sJ~PAJaSJolb4txdBXEP7`kHt5^vJ3;*H&_|Q2 zazA$0@2K^%mqK1%%rdfC##I_$bbo+48X}yo*K*9C6wIW~bi|P$r@9%eJ440$Kn>Sy z*V%AqaAusx-tKm%y%E`Oc|FK(lS;V8y02Ez%6&~vdKOvF7ZDl6*%=*Ua`v^hF?0_W{o{^m1Y589kK?v+&Nm(VX?tyATy9h zzrcio3?d0{V!Nc@CEYd8o~!RUl$DLY#?`?yG?DGx(=(`B{A6_CTQWhgoy7Y-xGbF7 z1Pv^1n)uD8opbdt?mLAYxUIZdC!ZB+wJJUI3%VX6s4y-hB?D0?kHs=6z2!@{u9gwd z?`wuBp5=8*Kk9BIrawl*@Y{=R7AjZ}!sUS!lU&Vr5_zz%?XS}YbfwOUh#0Q#!0)xw zu92ugyS=jzeAt(JIaNN7Cz)OHaTN(Xt~eDLKWxqXm0Y%wSNedje=j-iu8TDE#mc!h zJ`YO!^Ua4VXlb%s;>Qqbm1_HA_9nQ?X6ca zz8dID^n@V$ofP64dKoZ${4w>cv!(nVZyLdAzKD7ghKLaX3Jiw#W4Je~SC4dE4!&4_ z5rI^KXO+qrJ|6VJJm_2lm%|L>t6QAjcdo>a6ZR{0f$P9M!k>Hp9eq zl#GMqI$t=d|L+dIxg(3}3G5%RS>nSJ-BZ@e&B~qgi;Brs*$3y;avL}2eMVN#zwEO| z$w&v#S-In0(#oAK1O8v~xhK=;tK`3BBq9QhRyXPY0lnkV$p_mz^#38di762y-WtpP z*(#w*I+BzE|BFmJ?f>DU|8w6#OyP>YAnE_;z^DyS8N7&`V&5@4|5sH!h#pk=S#aV? ztzP?R#lL;{F4qaG6rFr7aLC23jrC6h!y)3X|EGN$KmV`z?f*0Iy+G46|MoPr|B&g0 zy|`F^aHO2Ywmj8n)#t$Xu}`e!c;ePUVZr%9dDwkfRBt<{?bCd?cKO-cMcfS6yBNLA zbk|6lMHeCLQ7Byhtj7gy);<0U<4f!I73%0VievC&;?_=A+wdn!{dhJ?(Hc8rf!=r4 z&?>URvIY@YayB}%!R~_qSEn`8mJhz%M{=cXz#-oUyK>fJBH^H=^WV60n|H#;)}#82 z)0^^`Z)UyCdmNvzc|E`8D8C_N6GD7vw&Zk6ky05>*How&3BYjkooG^8Wp{8;GOVBp z&N2LjMBlj24KBYu%M(XdQ03wtPjYMIRxH%$miOyYVSOi{&mo0O3W<)*3214Uo9GVf zuH*^3292Itb9G>WrNR2*Y-UFvLhsdb*r_olvabk?hUZIiS;PA2YO&IctY=3Iy47>mPTFsXpPBud6)u$Dd=}=T+(Z8d|I8^ z%dJoNj28{Dx#g!*L}0Mh@tH3>IR}v*odzbYRPCv*m(e~>N#2_Kaha3Y_A7Brd4@0V zmrEChsoKQz>)8$CAIu?6`jh6n-r4mcz1*RodcsvMeW_jn6h~O*Ghv8LS1x_Gcg~rY z0G8O}446yx>l%DoM-FJP($RJF|1S!dewp(pE_pPWNzTN?DgwUHUA4yPzsHkoS$A(1wNGw6d{U6d&|k=`otpFCtv>BLltVX$IWea6 zQ^?;N4Ru%blNi;|>1&(Y*lOJrededWPw4uiQgTlC>AcN!MKOr*5c~1e9!i;`4g32^ zi2zfvHoLhgXs)Q~wfSCF7IfcLC@BLbpbQy8!>y1IG0=JlhzP6+Xo=q@i1S>0XN@no z;^R~e9;==oo1sPbD~d(pM!!Y*k%~kE^^o;#!rYJIhmS0c6t5+A=XZQj+&3-piLc(F z`c(YtG_u!qa6$*Fh`x$cqx$s?vkR%%JNJ|k8llP#!Di@@snt&enB%URD2Fj#&XpLpy%38U*ZhzVC9U(X9}fid)O6j zEoeHX@+Yn@)8X&Utd#WW+?v)eWt5LMbQdJW*!aSN`9j{#;bum*C<N&OGHxEiacwg=K{BpZ$KA%1^$dri7leyuhxrqF8}^M=JKvVqf;+MqtBq(xxu7^U66z2 z{~d03zLEPo|)EMx&maPHtfE60J0mg(!#&6+naX zCr^T`-CBcnKkSBq;Y&P#=FA+enfGlmkOt}1T%7kc+~V+@#Hx!!Kg(qiuI+py2sy^L zP$X*h`F3@oaU0;E7O1 z1XfQPbxMs6aY@gTP!Kj%q40hNTAO4P@>1%3_9(qk!PN;euuuKezC>x z4~yM{F1dX1D=|?sXQYK>AWD>apkh#YFs_57;icOBJyhBWcuO0$XeSj{q5CfS0K*vG zF@!(zBgw2J}Qba@+3bqNHz=%s+_>YbB3QBXYV(XuSg+7AVaDhu@^j0iiSJGX&+CP zFFUjDgXmQRS7hP0YF|pa9HFLE62ogartw}UqCzn8%ld-xJIBCoY{nPm0p~p=Yqk26 zuw&^Ak^Ncd21sd6TVke`F!pn7(E;Uq(FSBsn;P8=G6KX0tgqc2Cr#pOLbozOJr?|j zLNWF}T5m`N%0D!lUJq8Hxmv5SYSoyIVV9f^uOl{G(>cU>FwaPEI~%1yzC8z+(0(Es?Jaax-?2!+N~WOq zJ(gRCKULtnYpgKUax*POs8gkjCe8wbSkHBihASWF?p!$V`v^W8PYC|JA;qt|h?Y^w z`N9~(XT;6JA>08aAEaAlw&*DGA5=AmbL7**xa3>*2fi=PTe(zEa^7+*@XRpIr$Yt6 z8T!El;qbm3*Udkl^H^D<9?|hf3~aoV&|^-E{u#_47{nyZx@sL3d|s^*90q0%7V5>C4M&ILy;*ZN_)Yir+tR2G+SkssLf(F z7?`2LEA;YMx`6?rsf2WTt)Z6#=6iO^K_^`dw8|l}_%B7tH?;SiVX{;F|5)yGjyUh; z$^L?C&vRY4ri!1bZH^a3)Aa}V`=XaY)UR<1R9o`wj`-B^hC?dpSEt$9C`lIJ$xQU? z{T%y!^|I)xQ1d0~wb#jcS2zmngN)Pt27n6F@!sa<=|y?wxmcpzY*@EypX&3HMC5Yf ztvLv1FFwy;_Hp?6{7^w&9vP5EJkS`)D}q25xR8lgxtU}N6(hX9nynYJ1W;+K_Zw13 z_SQ-zwOwXI#4?Ib?lxk?|w8UI*`X(S&(|Pb%X#i_JPxFuzLlvEXEAQiVL@7);mJ)O@;N$k1fp=q&sr3DN zV+aK+oiZNj_Qcm~XX69kykY$Ibm5QvmCQlCEHXo3W7b7-+u;6t=Dd7z&f6R5qK zjydRSYrX4fnU!pOzg=J+nUNF;Pg)>EPDbElASpX!RBuqP;RrK>zcgVC_oQ@4Su4FW zH|U}SxHRdhrja$0G8pf)t6y<|K}KAE^lsqWDxS_P9W)|hwS()J8=vdc)V$C<{;J4g zuNTskow=HMcBEG^U!p3R;BI54UqPBGCyAfN9gst7t(Y%@9go3%yJ&blo~w+ha>4nt z8G2uX=Zpxf)kg-<&g!w##ov~;n`F8SG8wa&ppArAkzxvN&ZV1fwxK^9TAd5O^G;eS zIqfWeL{1W)t=F6+2wH@Zey=r922vWOqf+JY`!HjQ_DyU!o2~z2_Wr z-p!=VKhW{wu5n0Hl8CuyM8EsJ&j;v-RdXSzQ1fwn%2*0OTd{ss+s45X3Gg04zWtz5 ztCsmy7DPxGX1AdhKqf}9#yl#iXoO;)%fGer@uJVu?v>~tJn{B5)Ey-?rLTZb@i}8M zZPM(m0@1LGHW&^o;=?UyFJ=+8)p3lZV8uO?5{d+hMFoLj(e!3d*hPaeJ3QBC%vpAb zaW{~Z#=DWR`v*0W5+LTdp1fP&^Ud7n)6-arD)glUfJQ?RL>C;NEbOno{602cu~T91A}HBQ=q#&^>8_tV%0upfx@#;$y@uBKG-MSWzph9YHkhK z>2+$8Dx~-!U;zo>l6R$4fu@3jhnn6@AhE-beS8Jey^h5Onu#t*Yo{~c>3(o^WG9c) zo-`}t%PUIq*9T*a*K(cHydy8GaF=(eH88!g;AnA?v)3AU8kt2`Kyzm2C%Bk^Q>Wxk zD8`-{($95_p(!Bce%Bq}Sy)P@k#F})2`rtTos(}c9dxRps<~2Kbzh1|@rs(HPC?7H z#R_%vqN_y$BIvI3JzS#5hB@UFqYX74PO#OE^=vFps^!c;xp=z5Kl;D_*e%RGZl1a2 zQDh7T|AK2}gK*>T(T(?n@MSV&hSP$OI`w*7Cbv?C?(%ZW%=2n`?0Sv} zm6h7uy~?ER@;mt)%Uq1T+2EZAhf4yykR|VpZM*s?olGx&LpH{^s|D5(vuy{z>$|uv~N~>jyZr7LkQ4d)t0fZwd>2SuKJ1gwwMqxdSU?B zJAG4Zv1^%hpb`hctiuT%C7?p}@Y%IBA9v4-jwh`FElu17GxY+P!dSslEE6--1DO zExlxQ`!X3JzjgsrnhvMBFEx%nO=(gDQ&T^`pUz2Y>pRLg+>#^UMFGzHb;D9Lbh9!US4xf z-@fF@`IJb%!#9!2*wiq_$#;>7GGEUnGp_eZaTYIoz$2xneJPN4vDnQq!s6N*vzouF zKI!+OOHYX<@$GO;pN$p$*1K~@8nbzfMx$BsuZ*~FHf))1Be8EI)BGRKk7ug&W|LC0 zwXO(?x2rgR2p`pzOSk-0!12jB96pJM7g?LY=Ha2siZrN!AApMj$jTnYhv%-#Qsv~LWqG>Wzi zI!-6uv2EK<$F^e#ul*|BYP$48F1QRAH~2}AndMtR<8lV=|* zQeHv7;rjs2@p<~oLG7mULwc_I>lb%^dNI#H6aHoSs^d&cWsa=Dw}<{dx$ZN#;QS7X z^O4D2=SE~~M@(W!Vruk-)oMYNa&8*mCaFoavBZ+HtO<)%%W|&BGBE--991ax8_5qO zO!ncC)KWV4z} zT09X~wC+vD=)=FL)b4MmU*LBypc9C?SDD3AJskL^a0N$+z+S$3*ovskcTB^$yWYpk zaPytL0G(KuyiiM$KX;i^a^d^8xQNfUWq}$7<%&)e5$b28tPj`yPj>`jy-cjBb`8f?Ki^3uFhJic>uQ3j$B+#1a~qJwO{<_;$5 z!#vXBj{J95YM%BZY<@5LMpk!Eve`q5Q@0vZ?>_CvTQ_!mcGd49>$KwZj~ox#NNZ6W z81T-O*Eb)2GHr>$UqZx?6|ZTvUuEhxe2*`zS~WfBecz3|IDdx@T1EhEM@L@;Vx$hG?*}3xu)9i8rBu zC;P>v0}eA1W%ubOGoq}*qcA}(7S@y{y&>?9P4D{bm)y~<4N@xi)`|rYt|yvJtR_lr zdSY@incY%da5AkHU-BdH|L|{~@Klm2g{xx^(=s<=|1&^}#@yo8l6fJ7xyclSI{jj2 z_Thc<;f&%9BuC9gZgyd-;z*(Cua7CLl$R@5V;TLgsdHxOvP#k7nYg$(K}ScXcDIWn zje1iIZ2q0mKmuqX%9O;!u^1h{nF0l3X&ITRnHk|c3QX!+{uHG9SC5&F0-*GdM3Ubj zbtXnfMEr$=`vCc?DO(tBR^$$3T>lX(GiM1kpg53pq`i3Qa%VEr z^`w{Hm$S|2(An6;1o(bJFlE7S>+YteMaIU)u}Mk6vTA=lOeG`YuV26ah<%1+wC2gG zH_#}NJoOCYG#06;@cU-eJKF-$H5tGks?^DmES8Aeic^oxN08 zMR8>fXGdw21jXkY(i>7#6RtOI8{5Cb1rT)nh*-GGR#(jC?|~chp@R+}`25kQK`R2E z{6+9v5R%xJ(*L+96iytVEJ(43lrPM|(8v>dFiUm*D^b>wsQ5j7GTx^)%)kj)P^5TB zbZWKT4FFWSJHEeqF!nr=!azfBUT*dF>%ecpaAn1ejY*%cwTrpCbF8(y(Vr9XCSu_B z9I^g+bjcdsg2;+!=b%r?9EoN&&}P3cOfR1*&!7|S>J1;adK%=9#q)QS>&|frfxwS8 z^owR3!<0vTQ&XW6q%a+f!6hap21iClp0&I?;gld&aHrIzwXH5vs{ytX;e`?Ce`cfExSO~94zYX;@@e?)1=? zQb1S7VX<0%LqQ2DEF^`5grrE?rWbJM3x-v6f-E7j_w>NQ#dUCY{*gare>6=>L`1~l zbzcFk9?Y}Wi6pdmtY7Aq5nLF_4`OMg2Xu2N_IlGx#dK zvP~CC0NrD?9~`LsJ-5sA`T1G7OgUUKiHaAkM)b#zut@=TiY-a#JijkW^)K}5ZOY)B za6faa5%$}BPD^bvmv{o60})VokU3*~>V1tp#8DP@68`E3>CB-ymsFEkzu?JgM-lh- z!Fnp|&FFRxs9TX`jc;l207PMQZy`h5hsBr7S%%x8I zQ9c4&yVrnhI2z1W!!LJtwn%l}bfa#;j+DBg!D_s1@HpZbumgtu*uXhVL61|g-sz?G zMXdi&@b~fgxva7>3Ob#(Ks?Fn>S~|a6{J+e*Mr9q{nvIMKvF)sG3kCgK&PJzNB8;a z#)M>JM^c>w1`q%8PM%(Q_+XLYMa?(uLZp1tH_Ck@HYm1mOr0UFa6J<9FdvLFt>mx# zwoV}CdpNr15j*r+OCqP9?(TYn#qF&!IMxIm)CBOm zAmZ*1A_P2=`FGwftkb|!Hq79BQY1A{)a;9xy-`z>Sb2TL`{8qRq~s*6DZ3wL)=?(g z!fK3GTR-+aX$*ek!YF22ScR!G1;km^xtBj2d`V#^-H|0Ca|PJuK~DJJ9&Ls;I!DHC z959-lYGoou1b@<8mYm zvPs}*F=nM1?aSM49ehd5)rJ3DVOHRvN+l#DKvFX@QZjSJ-I830yY#)DYRA00c}B?f zy5-Xsp3DZ|V?4g@-=OVDt~x^lhjvSAE8!^9!9>>1YO7QA0Xo#0%>8)IxWQl-yv1JP zhet9p%tlK(GFs&!rg_TC{bYtIWo)4YsD_Z7+*b_=h;_MQuQ(M0k|>;V`A$oSMCCvC z%iTe*TS9O1{{CrelmYv zp=WVC$J2JHn#w)R(PL7~8Yqvn$$fakHl(xI;2tWwOK~`11Q=vx;diGT);%!N>H$I; z>mROa+a}^Z&UXI>)4clN(fh~g*?6n)I~|%6T{P4PNFwgYr=neK9;dEz|2~$vnte5< z>IAE|O6lZl9gfqLTEgZ_{i#{qn?CTlFz*ECtRPw{*jQUf)bT9s8vlA<8QUmMaIX?8 zK1UOK*PMJW@mhM}eR>u#&tGJ*q4EnM?Q+MWUkcQmL!;G{uQe1QA|?)xh!D!3LUEhA zPIgIu@>%}tv=74q;s|zd{~_gWt@&r7-aEqx+t+Mx$;_MXv;Fn=G_fz{`7bYe@<;}= zL&o~N{kDmP85rDXj3;0#M$`!l*Y<3m-}EReYiffMy(m3${CE*9RU1i2uXz?4a-;bs z`<=DCz0dI1G7}LVpBH0Y83R&#;NQUr5*EQDF}OKWtIjs^bQZo_hfM)P^Pk2#>#DL3 zgfv}SVXsZp6ej%ZB1n)Da`+sFd459r!uBBI5lTSHJo@3xJpRp%VQo7U|23@ylQtWS zHl8ul;o+otn=b6GO4WS9v%>=$K#(Xzubn_O%4BM43a~uc%^0&f?;#h33)fn}P3TFa zx`9sMawBmbvcOVfqyF<&V|sU{Zy+usuDwWuVb5%iWHk$&+EbPz1OW8hrd*r&)Z!nG=0a=@lysBBMfE$ zJHy@V=QlFtPq+`3J0cz4J|9;lLDTuYF%{-%4 zW!S&@LiWZMluqi1S7d$9XCn~8D-|-8yYOwy`c%9FQzn$sEu!5VFr#yDd$e-c-ey$& zrBKO(=XT*c9$MtYi!b`uGuED-9mY!vKz_VgU*z-QiLj(2EZ5MT9T_oI07VvJPS--z zaS_tc07vTn2dl)$TvK-)KPtPYeh_5zbpm z791EwLw#a1S_I(&E=9dOlGNKU=DnvAk9A$uG0GIMHMcd3(fLDH$E&F05@51EKydN(Kj>>e$l#Meld?B+qu1|z*>$UF^QgHrxNZrHF_i`d|1vJyX1ZKS_ofP zGQIJbY-%uH%3ja$nWPW2N~q74G0^dEyE{R~n2n&r_ZhW&5q@m+0E6Sh=o?ui2Qs{t zdoL^}AN0Q6)@Dau*@viy-n`cY@^{zQ+daW>!B)?5{1eOFh9&p!?$656W}`V!;_;x< zoE){ZfxR{hG=YhC!o0B2@ravQbVzi{oED}xyc(&h`Dw9M#e@h20% zLUDRr^Uup*PL7PyHC$-F`1;NAP~cuUF6=DxQ)~D!B<_6Jm_4NJ4)SR=)?*`FTd>iu z4A<79hjrM;Wl%mXtV{0S9WGAC3>9uLIPCG`@Oi}VK)Kp)Zo|FnV9w==2s_ErWsmya zX*HCX1bh+SzdKs&$u9Sc+G#i8=0x#~-y!s?cOAr3G>JuiU@jHo4lu(bPkPn+bPXnS z*U?=#{byd@_e_(nXfl+*0~5vB-Z(PzvO*QM#=O&Yvn4Nc$2p=jdb0QL4{b$b4-=h0 zqOiL2P9D#A$x$d6+$O4;sI;2-kyCtP0)xjI{m5>P4%gvt+J9fiph1|!N*R2FC3n2E z!|6%u48jj`pJrb2^V#sDEX>?k7^Dxy5Yiqs_GGT_Bwy7xr&~dxF>b|Xo=`DTq0_Ib zz%90V!>NHSZ!7*Ck!-}~9q=7 zTzKNeWWwdKon~PF1KMM89pCb1*po zri6MSO&`9&)TV8=oN(^h_xY2mvvZOm-6gq_ zyJwhcIe~WA#+Ym}e)!-CO#M1IAh)wX zyNWYykDZypp-ePG0UufW?$1FX!0qzO0OpwKpAi^u4|Ez{%PE^zkT%t^gXN?#^UFWv zL2sATk=;vx`9;tVK2(cMo99bUB~RC_@;}XKS1&Z8l`?|GY<;uS;Su*wItil6Z<}HR zY2$m%GW^V@3S3lhX6w&2ST1Y2hcxnqDsZbGnnL?4l~-Qw=Aw^2kHkA;2erm4(p@_7 zumdLch_64J(>;x#hj`X~h`JYmMo4ve%4#}^fo3h}c;KtTR9FZ?%94f~rdEs@QbD^& zhqc5EWORwnI7Z3)?0U%Fh*Dw1ppk!S>*Pv9C%rJ z(rIqdrpyo5F67uGxyxhJ);CzA$8XH$cs2f*Qq|uXT%nwxTFnly&4-8kwH(jti!L#K zzj78IU1^Y0y{kme^9CM$7|^G?@8Snh@|N$I<(a&+iZ{4}$9m|08D}To;ynLr1XM=R z@qOIf6$n9HL!`%0kXyU#qD{;7!#JN_|#7zss zz|1MO>V1_ag$ecoxm&v^R#{J!YJaJ{yG3pIN`=1JlfW?H<_FPq*FIIQB9bT|@YRi} z>Px+~542A?t7qA~jO=rY3ii(B$0_b3HcBaZ@VqR*pjZ{fwIY{<@t<`&Ki- zC~(If{vCa9I%W#TpepP$L5@krq=RR9LizO?aOcncKs5Kmx;6t?J%ZKov1lDhucYI@p1{ojJ(gLZO(`6u}vrTC@Uh3~@P z;PCM94A;+@Zgt{VzX!<`76vQaPKu{Om#u zWE1eYuft^9>V(9KF3MH>GHec?4%&NW4Ep+*RK)tftZXf zM5>A`*kstC=`D$v5K$0+XFyA4dZO;uEDEw@MIkOwAnZ^if;FIl-ZHn-zkQgtsN;^B_CK8 zGV^41puu$f$am-a9#y(Z^R0M_--%EX&I6(p6J3MJ6K!jsR%3Pw6atWLNEtK9)b zU0>vUK88-ac@*=nB_}e_3hNq0kdbTU2Uh*(k?^q+ zRuKFrSO=5!JR=eOj$OS}eqTxioice*m*~-OPB6t_R+9?js#D$ZdpO;OTleiowf{4a zpJt*J@-~?U%E(R#~TdEbsX z&(+mWyD^eGrovz+{w&erG^Uj)273}qgf`8{0FpiCV#_{?_#I+dk8DqpB2>eqXPR289Oa zO-Pa-&5OiX>y8(#AT-$R2WFQBRN-nr8b5Iqm3nU4rS(l!o*b<^+5h23`G?Lrs#ptJ z{(lo2y-e*z3R{wZDd9y9eZ1cN=E5aFV~)E{sAz&~&HBDnm(DF^R+kKz6S+6HOo8wu zSE@wF?6WJjR%PhT-Ra~Z1086kKWdDwe?ztL`wxDVGZ3_oRpBB2AsXO zm8+Tkt6MjfpA|i;16X@iFb%dmpoQ;m!><|M!)<$fV6^#Ez3k$9yg0!4`|~nDgDJVQao%lWcB^r%I*9Q z$15NHMuVIkm+3<=g z>Wj&}yE!KCxD6PIo){X5{e_0$eD9@DXRmeW3e~F*P-G=$3H1HqDdW7=0X}7!5f`Wo_aG|+!isZGJvta%D^{d5x3rts6 zSEP<>E@D3nSG3k%ykU8<)*f&E_dxkv`cTmOiq z0s#cf0n6k~ng94r_3zeND&<&9TU%Y_y>F7SW)KxUGr%m=X=y-{)eUfYX+K4-^6d*K zhwCW@CMITTYHF@(xdMgm(X*fsrF;p&-0W;a$p~ShJSVs+p&KWZ?9mbL$7vhzb%hGi zSgd`&Df8s}7O?(}WFSHKU9gNG(J_3A5GPeLyVuDQ)lEUy?wa;~5`S>ElJW3*b)SuV zo^BJ+>(&?F3VaA>L2)tv10Rt%YLFrgBUjLjRlwB=R|<&9TgQLJ0wg{TZPQJRk`_De zI71K87xOU-Bq~kbEC2$JrkXg%*KLI#hF>Ho#h=^05WRE%F2%O+D6WnsH6G77ZBHZu zvK`-ogpl%IAo3F1{%1O1S%`#;yymFfc5D`ZV7XQh15JZ6GWLI<11u8R{~j;pzVJ=O7OWZ4576P!(97#&vZXNNMkK6_nK@e<{7oaXf{}&i) zfM&zd!*`uB4YLQi_zU~T<|CRFuaJ_(A562Vv-m853eli-9L&Y&GW#Hh-#I*ajj;Ap zSJWm167qJIj|DqAu>?f=5qmi8BaAh5=gn_9BIcv+9U7|*Af&CR>@At z2uBaAq?2C-<_7$qiITpL2!y^A}UJ|js`$X{YlKF2r(_RjbAT^lCS^_$;cCq+bFk8Ei8Q<%kN4rT+kqSkbh ztH1}DhRDK=fC=xM#&AYxUo$}hJ7PpW$+^!7L!^<85=(k}I~$v%y!qzbhK{*UY_O{y ze5^v9TL9a%@J_mmh<@CRP*4P00&mbR>O}R*#f5+H(in#%I^jE8rT|JRKeGXDv8g{_ z#U~xQb;lshH&oVLwY_eHC%kNOv2(B^zPyL1(MT0Ekq^!YDd1nL_0>{sRF?c@v;JeM z-m!0d{2kLjJ7~EFPmR4f^kroD1upf1*l`+k{vxW_Fb5xVdYz7&Uk{nimbPk~9;}>6Roud@^+iAVdm$=Ya;)P8Ch^)GPl?7{eB#iJ_DlfVGY|TV z&DB+-pRnZ25ir(n@y!_gO$iDr!kYmHHpUVLEElK z63R_`_M`S0pL(cbx8kHF;N88V|TidR&2Wa0i zh{=1Qd9h@rpYw4@Z=Rj44JPOK2d>uYvT$H|hp%G0HQIOJOFdAeWmhK)@XnyKJu+v( zI?#ZNW2LT)Oj)MDp&mAeuUK%U9`kyY>5KiX)qcND#iAEPmI7&dw-yxlcQ!boIEPD{ zK$_m7qYEQ_#iEu-@SoXSzjp%2b`NWfKoiW@jrTC`>{@fq`QdQ}K2mO1jM@Qrj-)i6h zk%W`kmG%8#$IAKzuc)b+-eEF|rrBiuv?!|8WDT?=5Io50fH_;tx;|2&1dnZS<9nb} zo+~YOEdqj|6@wRYRLe5fJ?ntPB)aw*m3Y{`(nK~ttq(7I34=D%kTB|>gV z$@Z7E_}N-Xt@3KMZBYughD(HiL%6L9He8CuOHxGOs=Qneug1rB#g4Jp5{ zfDj0!LeZvNmBTd>9%jC+6u zeke|}8XHR-rX~Jqjo=4Gt>|}BZ;>OTCB5^NihC`4DWGCtVH8b6ogDTNYbhG8{397o zbc099MG84Ea5#KK(wAxSk)6T-bp;m>QlPH=jgzsZQ_F${K`MAYUwK^e?ry85& znK3%(hU_Tf#6K==i?cQ{VHCG2nZ&@Pnvmw4#r)z{^P#v*&ExwyecYM*L__Kyq=oKN zg*k(@)QrOABuT+}Z|9hfBo@LsS|W)Tm?PUugu?SkX?elr_06q;VNA*}P8R}}+}K3q zqBZ=xj&y-gD2bJG;dnY+*RrF@4Hid$EG%aU_SQ5fqv1qJnTkMw-JeiwZ`0e8 z`hS(`eOrg7Y9RTMNlZpONPofK4m2$VY`9tD>4FcbuMB^|5oTn{dU6ektE*Kg!Yj#B zN?%pz<+KEKbNW#ReH%yKaoIyLjCqq9T2enZ*~h@i9U`HoPPx6cu4$CFXGCLSu8$=p zuCR%Ut6C!!&KHCdciV2MOp4pn!qIub7IQ))Crv}ajOynK`e%R|kCDXIBZbLLD{Kvy za-xVPQW`}$ztJ68936g}`3m#1f>4Jzus~>|r`~;EBIyp2SzR>VYGErq?Uwg>H)_mBf%SOU~`#tGRU(u$&SI_u@Xe~!tTTx?c|18KN z=BF|f1@&j74zS<)@p#MotxLl+`MA4`6p)f8 z5C--vCzP$@VI0AS@p|%$`v}6qQPZFzvAZ0Z%dB2i>W6EB**x>INFql8jp|Q3T7*g> z#E}ZFV*Cegsl0$AWI8+uDwRrY6-QxFg`N(T_S(QwA5^CTNmOMeqw*>d>pgS^yY7HA zePBE0q%?(Id>VNdp4pNMVH!2mLj86LsHY-XIy`E&OuPJs!fh;agsil*v;+F*{8%)} z`#oJwBgBngjg!-RHP&Lx_@=bk75j?X}#Y`f*mFMN6!tRE{Ex^1lF8+!weB0yYV|$i zUo(?z41W5U@ zCWLk$zedEf#q*231FBWCiNRrAeWmKAU3o-K1?|gbfT!v>6Un1W1{r1oeVU*Y%CmhK z!w*c!J3OZv`+G69)TQ~|ANSIDJxp)DV;I_@2iQ4J5$5!@CIik@Y#(@bP`%r9GN3~R zqGu*|Iouq09tpcNsATg9?sFD$7p{D%PJmt~F{TfDqBJh~lCO-7uD|mgzk+434OFkb zaXvY|S=Y6++M#XGM-RLNRv)74zbQutW%_0rX|dPc{I#GPTqBk;iE0ca@A|qjL-`jI zeE8d_<6ccY)5!WmBX_qPh0UN+pRtB$`JAD?zJR4Am1H4Ou+Wvc3WXpA z>Ww)uop)dVXdCh8NC~{zftrt{marAQwH0FTP}h7p-9EOAEML!dj_*$5xK@KlH8R2g z(=a=ogM>k1Cv0{FDeDs+*JKm?nKGt}Dwdm__V#YKR_gm*_ZMG|sC8BvCkuobB)3a7 zGTP371uwlzUt3ViW6t+i2P`dHb%jm`>}PlNeA({N@l-f%sRRXZ3LI!GmWW(6dph0l z&z?9Gq_s3PCCkpv)^2l#i53ma*1e~B1$IkBBrqN=FHxe?A>gn(6zQ)MSu)+6z(h7y z>+of)c5^pgR}%9I`PS6YWPlmb#@6Ar-qVROd^6H{oIj`u736e9NP5^?D2LM>LYk=S zBg=`1{pdA@)X&V{wHxR)SA8nBt6gFtJs4V($1F#G!wKk>@Tz1h+DDJZsh^x4B&x^) zf}K>bT+T(M>>^L~rDRF0*O1=1a3rL)nbIub${wE6{To3Ve!TNV@pXfjlycgm1zPUa zugds7fgU1pw!4s)e{c@ZwQIsxteP+TVc2w{tS<5ta^C8^?^55t z(OwYEAtjoN@LXHZ7YTm35mT)c>?ChWkRI96=<;^`TI!}^$yy?}r?I0^V@|op3#qX1 zTB{rm_mm_NIk7Wsg@Hd$pD`-K7kG1mUU%2VYZK}x$laWIw;k=2nSwD7cnbNp5$CSG@XwhZ*YN11y~LQP$?N-jWD2eh>1J)POHn6==4AsI zG*yg*{9W+ZO}qE%0;zRN86)h=XmW!fO*WVmy6E*NL&NX?nK8O39uN9fzNweRHJqAS}jO`uHoH_=!& zdF8~|4j8X>hQ`^r_8FYd#k%oZ#}s}i$y^$_ZoGM1+Y{p}v$&;b83~>)!f6`u$>ej7 zcLy9VqTJe6&56)WRCZEP{>Zj~|?@&x}>WWkz{@gZ6Zp{vm(&Tg@Wx!nQlITkpP*CS0a7y*9x!E_w3&`$o2V)<4H1;=sfhxJA z5QjKiZltDGt=N3NJNcYyNuN^7s6?Sb$zfRC51ohysC`XNl@t@#O%TxjIl9bd8y%grX*i% zJK>VOh$3&1xaUh6Ng?Ikw`#KeTKFX32Y*p)w5y(0wr&eZ)*h>35S{G6iHT{Ng#U&g z3m30vNulLBu=zOQ{@hgKWf?9eEQVjkZThh>-XE6QYqW@u8Cg{{$ea?GXpMd2n`1Sm z!53I9%dw-z9vc#Uthh8!uu(@n(zb0#f{f>djC&7aK3Q$*XpUvV9W%@=0O1U?5H6## zxqCDcS;3O^@#OPdAEy*kZ!?MO?TJ`i>E}9LB6Z>36Kb=0`LzD{Y5tn<$0iO6eej}}f93-}8)%zW<_m45LN2#%&3*d=|vs^$@`ca zifuam)pasw{OW+hzrZY7EsG7f>x(AH0M9{K-dNmXPrjG+xX5pJ2p=s)YH~Hfhg5{k zz`Diz8%`BjRBOHrC_umwmFq6fXhTIaq0A?D+OmY#P$oJ+EuUK@rsO;mEOe#|_K5)> zm4GCHvwXmo%otqmB)z4LiW}j>cmmy+fm&>|;fCv48kvX@#++Y{*7hPh z!0SKAk<%qXem#DyG5kX)OEUN8<`xqP=k=WQ$7gqJE`G6@$eC?o_42WM=%KT@yc zNUu^gzq%UW?+*$LTLu~r*%>9x=s}7@)AcYh{=|=FR{)ZJ9dHe?=}HVsU#$CCxjDp- z{xa{IZOW2!G<2eiU#|AQDv(h2v>g;T_Fr4I0A$?@>jc~0V4kv7iC(5Jt$5F#vB~M_ zAAL^`JFx+~#S|w&fmB`@;;<+Whdc6xVDo)W z#OIjY#%tTZmv#CuR0;)UMhACjTsV(?88SaQAzn;nP4`N7i|gkfidn%BRbBc@Z55D{Rdx|7U zVB!tDi9#x9`i#Q_D(J$*LN(Xu<0=tkXjnYSVfUiL7AHeE?9usw8CXN%`Fh4Scz+$A z`j;n6wPF)wFEZQAe#19}S(l*0H>*YWasOtom#eWQ8q_^|2gUlGP1AQ*yC~!_(#w}{H@j{n2NwQJqeZ>8)ndxwV1$ z1$}iUUvjLrs=uyP%Dd(yIXE{7@t+`=RTusYhiUb(8+vhvb@&Q)s8V2%OKa3jyQ^9T zF7smgV3m{rsNGzF`0?yB#?DKfpEG%~ZJpySpYSZ8u8#5c@?f^!;bF*-bSe4I;9#V# zCL3b1PUnN?B|h1vLm|3lt5(M|0&f5+YtHZ;?4Y>?omwaF4NdcG8 zKi5uT%W=ss^x{*JkRW^Pe!=^GqgHP_z}OJd^yq9)PGI(pbVdKa_Ric^i z($+8OPgr2_J*iSe#r&NGF>Nk+;Vzbw~J-{N6733>n8k*`P zQ~Bbl@1o73?!N91$4csSZz|33t2f(mGS3$W=Ap{IUnu6&Awm(M-Y@?p6LoSvarNzX z0nijOnrN3#Rq9D)CS5Au*<}yzTy8Ju-wzMA8ZcAY>GfegB+oXDe(&R5av|wn=qG75 zeM%sgyPgumXEd9@VdPD^91*v$u($@we9V{X_KfVTfyy5QT&~^Lo#jTWoTn~=4oW=u zOi6KZ{e>!>FOZOEZgG-D+6Sd5UnDmg<2?M6@_osw*4*IB5(Yti^P6{pHjH_r=I!mRJXI3l&ca6@c*w{X2nYiU3(DsLSo$B{Z{LBA zXOPe+!Mi2Ol-fj{+pyt1HrpQVM?8M+KABn0EV*A#Z!ac``8VLCK0G?go3orcavmZr zKvSpC`Qg<4>B6EUvn79^$r}4K#519SAH8(Xw{)4xEkgO5PVkk&27_rN14Tz)CnhEU zHg<-FLck==Kz6LUA+slAhxG*+>C0AQp?$$xi=KtrDv(yop0>B4&~ZP=Xzfs1-E$Y@ zv=YK+8Ev+lgKg9t2i8XeNDazlu$chSI`R0R(o#xWTieCOMV`|PDrgaz{}ku&6eyNn zUR@b1)))Y(#AsmoT9*@5zQ;{)Zy%peos*m#qOh>=tR-ta$=)*1!-bW)l|cRU!M6y# zyu8SyQ-2RcW7pQyB_-wQdS?budBkivO98C(gV50@mJqbC3{09N z@)Ovo1xAB0<}B%hz7KP1dJdbvL4noEV6#DzdFye)JSq(Im1>Gxw ztzFp?31l@zt*uX$x@V4@tru(ZFeHf+(Ugj$|9z-kcD@*3|Je&196TyIS^?;$+c*Hn zVTw3Vs|Kv7q$Dg*dnDJHv*5$U58QEqbxB?!pj1*)ii(O7mzD;Kgu?bE{@oBya(j2j z$jmHUshW_P`MUTb*F{I6& z6xk>f@I8HlgGR>2LH_=NaRt<$lCJ(wNmnNsMt7ByL^y!ve7gf_U|@iRjO^FUQA9fh z5TCI_$&wW_G$aCE7KzXP=Zt?cqL(Uv9=o{z38em$5gpxcc=SZK5K-+(0e&GrE0@M6 zw8qMU_0_VmO?(>3=hL}p^CAtZnfs%B!3HOV?guhE&~%Dp^fuc>)`VL6*APtg{Hv}D zqaJLq5MlZw5cG}+rx_JtQ&$0wb@>qzZ5YB^fWD>c2ZU6LC4m{}x7)ct+RXso#%SgY zF?qkg{y+#|u-0xKK!X^*?dgq#6;)Hd9Dr~)7i6>18y@LkoXWAa;lLogUKvpOW$5ZO zhdB)uiXO>_Iu1UV@_zl!9D6mTDQVoJ<+=HsZO|`gJRmx>C6&NnPa%@+jqjHf>&a;m z{{JXuqUlQm!d>4anWk3hp$o+otvLqOAeHh*AJjQL1yv2Z_tn<$5f7b%7J$h~% z`(iBNHXpLSGJRl>3BF-mt*P@_82`S4K-Tc2I(g?C{t+C4bg>-1wIQ?H9_Le9%+-@g zFIK|?JV&ADKZHO@Q!Or-6Mf-&(@T3y)S@xQ5kIZZM|lyzu$)#ir@}hRRe3 zo$+wRUERF@O9}&*sP#DraKqApV@;$&+iGX+8R}h!BXM_eCN?egLeAS58gf4-cud1z z1(Uj08Q6j{$H^GEQg#ZO4!^WP2*UCj@q|MD<{}m z+bemOiYwyrST z69*Mw!j9xVNj{)P6Bx2Evd-Qv>hfUMYks@_O>$uMo@@JEs~n$h;`@lNZs2`uE7OKh0n3;4_N4 z0sazcKobYV^Oz*2GIQ)Y12dIFC4amG08?e@{-NX35lGH3q0a`VD!Vz_u79KuX}bgU zxAB*6ZSudKYW#$)3p4+(14i5UlVic0K73zi>Ajr&s!-Tw4;j<3c&|M_jyix94w@E= zI!FK9Y=E-_=X=4YtcDEMY+3F#i}NC7vc2iqWvH6qi0agW#~rL!GZ7h)8Q9u=8;!sY z9e6W+?w_aVn=PFH60YKS^bKxumHo{4$3CG)UTO1vJHV=DjiQv@nZQk+~V zp>Gf3jFCRT8C1S)>Un1JaM$YHGNzFNWtVv@x(#6?xZmNvI0R$A`|ie0FP+EZl-_ef zDguZ{pgU;SYMc}1}Uq^Erw=E9Cls>=e=*( z_E3HrkGFrAU3Be~(_DN2y3d&t5_pFR2uVnSFxd>~1%GQ)G-}#d&D}5L-D!06On}R<<}8D2Ko=5eq;PM+pd_E!~{HJio<(z!)RTK<6Cn#0>^!I;}0dwVpdo zjB_vWPWVNdJD(i3p{pseii9>@-*4b;E+?u!9GX8cn-M-?mvgK+N1@xr*gYU>j{Bjo zzrB*O;ZfyHYz=7WiLT$fJ&v-Iu{=0!Ez-A7jzd7MxO)oFWg-bdUoA1f8%<;ypmceV z%XPNny7?_Qao+4-1L!CA@pDvO@ct6n?jJ?@)$Go~y&iM(@9QV|hsDjL9#c;^bY+31S!TBm3! ziALiA=vDdvpc3Fb9&)<(S61Nczx+sGu|+ciXT{06T72o($Cg7Jk}mru)G)}9nDO3` zJZ4llyS&zNmW1 zkastE*_pOwY82Fzg4oeJCVfG!0`N95l0wd0_g0Y7w(_s(&n&|yINM8 z^i`=y!<578Ek}`D^0-0MS};1Y^Z^;5K;wDTYdTOfa$}MAwI=4zvVe#x@IIkMNSfcW zZ!e)A-tHVs`M#3n#Kxj$-6bl@Q}Z=Nkz&vA0H7)Ra40K-el4*jC1)C|H6K=An%QgR z`==)sZa;pkw`KpJy8g|a^Q(+X=HsnL7jNO7^H14kE4L;Q_G7-6E>2CM=(Xq--SOcw z`m49wP1Sncv(6A5YqK2=yfw3fOS>YrNjjIt?Cd5e26%&WMBU99qohS0IxK3rxW*@! z^Nd+nzEK`qKBoY)b-tFus^gUiT_Md7PFx+dfa} zc|2vgd7Km$du;#Vemqusxolv+M`-q-&gx|6@{zlnGSh|A@8O-iKDwg9u_bru=j;Gx z!`kQbWXje((~57o-!QX3f1xy*WMyHxFMhGle1^LjL+|{SgAG$E1U-dE8^q{z!0_K# zdkd(zo^MMSNs!>~5In)%EqH>vySr;Op<*xf4;wKC@ZD72W-6Qj9W5v!ujNp1~nAz#&!O&Gdi~DJ|vZD_Gb|}F+ zN|2DSoBXtLXQEhu{#lgiy2$rnc;2qeCPCXY%X) z_-e0EQ?-Cs^1~i%%WK>@;qwx|w%hf!*E99&dK`wWP@(k_E1&bDqUo4=$1#9sv=R2T z`_vBcWG7oZ{b|?Mr0Z`@v09l!{Y&L33|{>H>KFZpx=r8VmV7*T=d|6Z+ZW^`D(hXa ze1>0KU@F(P$0SeyejW(zqpUM(=hI7aHEdO-$DTglU0UdyE*I-t>>OV@j^`K*7U)qf zqTTT1+RndMAagZG-{^J|+wR(y7g8U4CqL983V89QZvwm%2@0CsDX^GyO$TafL)<+$CD-t^HK;y%KK;>jmIOxo3-Yor3^v;+SY9w z@Un_GqBOd%lz`=_@c=B5#LQIWH3FU1!iODJJHki7r^m`U`Nzsi7QiB6f)7aT$xZGn zwO-ZSs=H^i9d~a6d#XbogTAfvP-#w3oPZU@O*z5BQf7$Ik!!Q(VL32<#n$ffa#qW( zc+~m21y$`sOn)vuKEASnLAK{c5KjEi_Rq|*b6E3B@Jazr6Gkf!6TwAxK1cF5Ks%+E zET(9sn3LMl?)Kyo>8y^TpMXXk?!inYDSG;$JMHoedY7UVltLP#=Ao>! zo;-JqoMORA1>>F6L4C;%M?pnHoI~BiIdL=3!=tl_t(mvYQiEW$?TqsVS66$29JH?`lOkfM)@_ z)%#dF4v_DdUO26{liYlZ-vCT!JOY+pU)6b!F%ss!a-SWlT-A#FSsVN}y=BB%ql=W>W)9ZedP0V^C59Ruv zH?H(e0q-4*o1@EbBS8{7I!gOZ%%3v)_}s~CTBMn_JU%a8ykiO+-kO1HfuHlP&VNCz zXk>D`e86~4S#oDM==`>c6m$77D}t#yEw53Pa$1m7_2A3|T99DZsgu5N7uWc(&{m$+ zy+Eln_^$8%z5TIMVKpxy7a?*=^o!p@0z^)3vm2$e*-{R$GW~XoS@ysnFvRsn?*S4UCvU(4&mTfv1&;kaxE`rG;L1ub&hu}oD zeR{97ZR15~z%F$}u(MaF+SE9N%Y++WYSI~q9`oqwz0%{u<4)OT5FU?);*=1h!8T_BlR;NtLgslS5r4+_)v|-tfU2g;Ig~{!aSU-jcfJ)sKyd+7L-`Z?Egj)dStgOuLGJ7NOWkPh zFJ=>(IR6$xUauqV9~T*(si&i|yQ49|XC2K}_e1p)$H5qO=gb$Wk&!7(2?%2>OphU~ z6l4%m5{&Y8ajJ}KO8hUwytVg-?BsZtLDbw#R}2|z-l0e+a{G5T2FDe5=r{Bw{wS(G zfmWUL+MGSogE?Y|BhNo#5E!p(eJm*QK9Kg94J7pp<4w#v)pDIcj>WbTR`oNR>2BUf z;7Jb*rxQs{`L%B8@cr`0sF^Yj$@-DS;I?Ykt?f3u%kAl_ZAR#{L#e~|9mHz;!3asq z{b84}#zzjB`|-xU?qKt^kq0RTXK#SRoHyDXn}IkeKi4P5)L|U&t7c6sMhJ@2-Lf2U zp;faRdBJEyFJ-H%nadfzs~aysm9HPgVVYnp67Ref4kl`=VnI5aBW-IVUHifG>t<;T zAjF{_kMCAhAr;SI`wysHFLMk>Z@lrcKIX1_^DF{d4Mg2?Vav@76zI_*=k>&?%Z1HM zMYulTpII7fv0R^D1e^&DQPo@(vr0d%>I_@kB@spLPOfH#m&}Y^h+p%y`8*0&v{L;F zuxppnU0Z7}li0#m7Di-|sNu-YX383u&q{v=BBvOd4{A#%(4O3^W|EVORKDsFb3f4V zejvS`mGGdT&)g*$&ce=m;Lmt^G!XFEQh8Z8`}8_8gL^yE@8LfDCF5cBV26X~d@DA2 zd%aDIWb-@kYmBuGF533#`QnW#D~~7TwhDeX_VVz|fW!dTV$`)tOLykWH519}75z)@ z^Up+AOc1hc2jeS}09V?G!m;kj{QwbWYl6sc>V&{7)$@&<>lqhri~OcqB!+`q9iLZV zfY-&iR?8rxyQveT>}zt~U1p^ixKgDt{^1Zouc$=+_RTdd1p9|xW~wVL#+JJDCfgRz zk~o|56F({U<0f~cwF66DK;LvS@VA=+Qox`=Q1O+qqlbi1z z`J(N6Rf3+M@ox3{`8QJC4Yr2}Q=RAmg3AXbL@M0}Bx_@(PP&`LG6czI(}Ei58j=B| z@mCJ%X^vCrV=@v;`C6yNQm?}VaTVKImq=U2Sd->qMlXA)MI~7)?Mgg^W0Y-zsT}9S z?J>2_uwy@Qy?(T>xNNaD_S>Qi1Stt?r}(*UDDT`Ls%Yxuk4`HWAMsnMjApRYxQ+E6 zjIYKhpH#TbY_yUTwX~MbObp-tYHe#=J8bo0NE6nu^ORxd7LeCNnbBl0$IT~RFjA8M z2-uU|sbqFvRc1S6y2LIG3SgngowSasQXnID_ zN9_1drK&4XX$Ff#{qQ${Zo31 zB1k&ZQ{^@jLvsv!uGbZf`3BB951%5V9A`3JZ_FSU_4F5WK3F*2vA#NEj6l zu2xBFZ4V(KBlRx)BW8-yj{dyUNb9@+a}0c<3V6yaFCD~p&Tcn z)>J_YY!$~MSuI$-UxGdW2W~hpF7|%Eu({OulaJ+*c!?D(W+U`SKtD7NmH<9-#{-qh zQ4Byw4&@^MfTbB&K${pP{t}557+;O966mxQGCZ@MvR%?A_4FDFyL7?6=Rj z6~eH$SAJ*7keUZV45EHde8`$DJt8<&f)Ca`lHgrHxeYc2E~$u%!we-d+F|IjvaqOw zR|5&zaGfbpNf%)3`PFrJy=l)?R8e92{BXVOx@7aLDL0!TCn=d40m+qIADcAojHr3J zuYj*_4PKXNYuz))Q1}dqC}IMAvXWizLqz`Zc~w#pZg@n*VrDhyp5-m{0bgCcuu|3E|x;#a(2d7q}Ftz3cV^;=Rms*?Rsi8%o}Zt^<;&mh83; zZ1|AE;1Q9t*UMmHs$mo%CeaDtLdZ;wvoV>2ksuF@b0xy}>n~m+;%E7UHzuH_%qCR$6cWi+Bw{ll-f3gC_>yHUUCi-vk?s2 zK9=-^)9BXzZn|?syep9To#hMIi)P+yuIOo8h@V1R>izsd)AKRcsAI0bYkW`NQWmeM z*e0hcZ%5m=PF*@uDq5WN!M>m?YyoknN!#$JncHf0Y5Xwz;XuVDxqu1Ze(XyUzpLe- zl)WcUdsFKew``5~ifj0jgja?Ymf_i?zoevICrTS%!rdPTL?p2->n9xG$}`szkq#pR zgHb{3^2@L%G0`a%;PP_$x_9lz!nOAw0UUJ2AY5Z-#CakH*~D4>Zb^M##$pbu((dPx zxq!Z?WY{Ly%AqeBKBhRWo}ZT5qtX^pspxd1HRtb72O{L8x!0uG71CN$hsg_zUCr-; z5lyzXiX)?LY>=xeMu)Q;(k_bdxMEu_#Cc9=lj7b-1Y3N}G2YqxI z=+PPG9cFjVeSt1lVxzi)x8+99q>^cDiJwWs4~!oFXtyJeO>Rpgaze?LNPV+F%=oi> z#T1$0`7N4Ie{7LPdnkdK#uTpa34Ji74`Z_s5_xcJ+K}+4xOyo%`zr)g9aXqo+Q|$D zm=a+=`zncL_(K8Lyr%i{r{cc$ZK-X=xZt$Zul(O-4;C(!Is;b4BvoYUr<>UPyG3|c zEgC=k;n$YhyE{zgF1dGQQi%0yv|6R62L52aL?2yQn?%PHvzF$9$q5TX64OfW%w8rF zmy04FtP1Edge@LuTQ6Rh&KK{=lhl+jqW}0Snbm5(#R`;fO+y-p3Y`?F{C5PraL{&x zx<2u0Aa`tlj>qye>8biC0$uszJZ&eU$M|NfXp1lI&`7ZC+kTP$C?e&!$*jnemHXJz z+8dSKBYOW+N%3pC2`2mmKJSNcdy1G2MV&r8H{4=o93S?)*sMGaZBA<_uj3Qj8HPaA z%?mP8mC!HZ{k~J%8`37-zwstV%@kX8M)NEigrKCuYfA82L?;H^2Cu#iaXLZ^Aj(Ac zRuOIjcj|7$jvOtbA-tTMN*3|>hR*AK@0HiN1pgLPXb z$zKGX$=AgE1AKxUmut&A2?P4h^YeE;6+mQE@Y6$;e0zEm%sGc2nunq+;WI73H@QMx ze-HDDPn?J`vyGHThnUV5wUM8?@Vp_R93^XDUPMB*otJ%pcnz7GoQB&!KmAc)aIuHu zQuL>P_Jcds0{fRp*%+&9@5AuEF2WjUjIgtS#iwUumG?jRC>wr9eGZQ$hr0XdMsQuB zuV|+C|3MQOM8c)LY)Um_$-yi@*_6+( zLwo`|ZVf-&)+a8i${}%i^J8sG9FKn9pA460FrrJer>9iicu~gm#&njagWC8L2wTQT z+kGinEw}Tl!;NYUev7()4lcJH4@T~&F22b}<1OD&WxTGjr~j&9pG zw&dWgKXA{$Aes43USWE>-F`H*htMNy@vg;6yZs>N&*}XL$@EnPXaZ)?E*fjwl#x5-1bI6ECRZ8Mk;F-_Eyr`rzD&#_hm)jJt_vgDc;@g}>7k);US3|~Y`+1&P=&n`*kro<`$NF*M;^KI$`;nj zJ^V^mChaj985@fM3uqiMGjnqw*XHxfOL8tQ+<-4H#5iDk!Yd9NS8OeShgx%Yib7?Xvp>2suP#R0>Nt6jFaM{&TCQYynOnYGVB<;PvrY#~*B-EZvWp{lx z{AOLrP*r0paDe$XX1Q46z|&pfVR&3nzIzKX#4r^ryo1QrOE%a97`EiE;1Nd4P~NkD zV^}?3rEblYM*MBC00AkDL?D zdyR-v$@E}jPK;qSTW~3fr<=erckcL9h=Iq7(8o9DQ$!{h@#k*ih zrhi$|xhi=zBXqsw4>{}Q$HKuwd(SBK=YTNjG$Bt-x;D*2W^?e>UQYq=F~s5*d$B$5 zGggQe2edA!cx7tuF1kch$ZKU+CZfFRa#QxWrIORv=MM3~{na_<%{7xF(fPbc;}yFt z4(E9kG0>ifhww0jVDOVgQO1QBPU_4b4ss>bhOmp((=~CVt4poLuUbXNS?dAQ$zIX& z^5w|pKSVD&(ja2fExtEO!VFMwn^IOA-OpXHc0c_z;FS1-*v^XD>wqn7zH2dEMRZiX ziw?dB%-jF|J8hawvw4;8+TA-o^)RyuiS%dfa|+XA`C zp|(YRNCWTE-W)fRqVGkW$DfT^JOLkK7#XX3Kcz>(k6h~gE6V;0*ejqJb1GIUXFgpb zrVWhbt}Sk(DvhjSwh*1<%o=Lv_f8=i@-wgtHMOW(i-ZZt_1Q=Djn7_MBj51hh?;+J zf8`MB-n4__i#Mq-GHN3+DrES$GA8CQi|lGMFVYdk8fN42P_jcJR9yY}m*biD; z(PF`W`kIzB*m;X=e`QP_mOI)f&v@MrtTK4S>nhM2N!t?IVu%4hko#CLj?vF=UV14> z5j=50LcTztP3ANGlroVRZi%wf6wnj1FD|LVqg#nHa+p)x5NVVgQp|yDu=Qi7&Ky3B zQXntiW}d?GVr^I5gZ`lk&VJE>hL%}jLNqYNw<@BE^8p5(5Zzv&kq6-q|D>q&gCZ5h z9RzC1s?bCUbQ)c%?9upTwE}{q$<8o7$LZpqrT5uAlu;i|jM14Pb@W2>-v^^vDqzmd z=E7O7>YA}=I4#Po_gGP6eIOMTeCtYCc?>CEuN!*k0I5L}K%;{X`DNG4f&JBea#x1Tbjh=!Tra?B6}_PU zt324rk43z>iO=~!!MFpnTJ-hZ?r~B-TsEZ2A&-;a73K*LU1VJrrw~oRCVxw^WM+eR z6RJWQaCO?a`@`@0@>uAp!U9)H@Au9WMkA4^@iD|P8q*mt(-8cFedYZlLy9Vt-ci6@ zpXE?ubTW&aExCn0z`Q34Qf|#KdPG(-3NumlM?&hq-;MO67|{)%X$c1J`KGV#&OT-6 z<*5vIVxg;V-8Rele8Z=eQj>#?+rr#gQB@;m#@f(X7+2S2-%K0dUj$A$t!oQi>jwxK&AuD1zWn3Xk<`Z5L&i z)nVqI^yz{fp^-;g**U3)El*h6@o=1F8)AAxhbMf~zvlvkCXb>l)OfJ^4ONh_OIDn} z&A%yc4PF|7e9O6}HLzw%IX)JWE#eOj7>N@R>`0D2AZ8mS$Jv^h-7w6OIA z0+%kZ7V+~)9aWz#Z)u>?Z0#As^eiad1ijl{p*2x&g; zvMjaf&^<-In|+mbcD5UL+=0~KPhQFWx~Syw_+&b%Jwg)LD<9opIv=dTCS55c)F2%ty-LvE!CZG$pO#gUnM_!l_Xle!R$Lk*CZv}Pf#9{>k z3%dsvUculX5Y?~)+@ru40t^%g-^9EBKa0*a6wT%@jzCZQ-BWwdIuT&dDE@|J;kZj8 z=3kFijyw+{{{8`OYzb$?o^@t@3sWxKPs1MX29cyR9IsuLZ?>@U8S9l=Q^=PZekxf? zuvZ37E)yANSX;h$XYCgWjD5*y{{G(WWeqazStS*9Gu-gt6e2DVL1$V3@a2a}41E`{(rQn}8-`%R!J$X&&ftmf5KUOS`Y){C zdbuTzJV8G)!7B=-oR_+tP;QA?{}=`Rsy$JXAN)Gb_OrsHPV2d(N&4l!Tf(E1F5x}r zYNyM90q&t}&0)6+pUbOi4ap0+U>da_v6inyyQUaS+zR)I#Y$*w!82o&ej(b)3%nhP9h1#S%qw&9Ore(xX5 zv~3|1J27((=yB~)zImVTDBYPgmqwS5zwfK9AQmGdx7rnzRchZz5VaZtu_iaW z6Bi3M$Fx6f<4scY4KMqCYv6mPpaqf?o=MX)h(IvsnmKf*yE$|xsn(Wfu(-B7$?590 zXJTOSbPm)uZu72fG{yRum!yrny89=(W#r|xV8gZr#z^i)thFUFM&8(Q!Vy4$a9Lfg zFUvrA&O3}+gFSjH{c(UhT96`ORK-9O=g@h>c^|XYfl;j;QlIQP18_da*ss{~!0hwT zrTgtbJIQ}Dsp=_p`L*66kN{##;KggHo3Q!bvRwdn#5ifaG% zg+_iJNHjG1_Rm$C5K4Vg$KG_HszTI-6En7U)9c`r~n8K)l2h$OzbFK0&H9Ivs33yUpa6 znZ86}8Y%Qs(pXTY_6m?Vk?Y+2WcX{ z1y{(n@bKMusOAj@ar0+LXncX}3EXiwJSQYKK}XgNpYZVK%FCEtz>r|vOE*X~?(Mzr^^ zEEBCZBE?G^8|e}_z^4KSkdf8mu~Oxyb>}$0o>=n5sOEwV@~<_G+&(3kLcD=q6UR^__8*k~UgldKW~Cb;uf@W#Zhb!|Z{0^b*%*bi=OgH5 zZ`}g9csnTQ=*1ifRH-@GRq2BD~Y|*~bjNTfcnm|#I7j*XU z!WZ6Bi>vD%=_P@Y-`*Z%BA1~zdpJ?0%-*mRK}wVGNrb5Wn!kmrE&n$V=g@km!1xg0 zaZ^7+NLSWlfZSntYlwS%qCw={qm|U}AVE>v*PkX>XBTPm)M&4}>=8J%`kMl4%VBzT zd1o^s?ZK39rP#=r7rte#G8gQv$=_nfzA1FYAvv7O{bsyj4F?Rga|ik{OL|BZ-rLiQ zE~p!ys_=!iJCP7?{H|d1!&0Y@r??gQagAq3U&jV=)9jN&qawP5T$;VjVW5j@J4O9S zBgIf&613v9`aeOp8TgqWUuEOT;419#H!c+Ex+mpE!5D5DG2a-bLwLRr@V%4*ndx2` zP<%LpP>~{gNNYLY3?F>MwO{&< zRpK-GItxqZSa*X>L`C2Gl_t1CAMBHHlxxa7sQHLJ1(x!hOq-EO?MPG^Jbznl_o361 zHg_3cQ|elLHI>I?3aHG7ttYv;GIVsJt)`+tH+pAeP1ZeZ=k!!3JDjtDa~k?U*5Mwm zad~?C=QedTz^RKl*%K(M_JVeC?ErRRl+qu@h3?S^#t(EMgFgxfV41w{Z452UCD8r+ zY+Y1qSTAhkP0n+5=PKLRi21Y3E-qcgUx25=1A9tKRMqvpz}L@+?EcIgVef``jm@w? zL@PJ;fJD%~srO2;NL#BAoWtjTIVK$*f;FA)r^6i#G>b!~tc=ezMvwhVO~^$M^GVLT z&&xj^oigq_p9x>PT!tm#yVX<2Dk6b*dsQfxBoEk50rd&`IZAEEE~`T2rZGN{A^VGDEr>*>l9ZYJHVe&ejyB65P~>hU!i3&Xp%JC36{MhaHe~CsZX7 z$kiYa%Dg*Gl1a?+P!|(Y)N1(@pPahUSnr(bfz=A_pfh|zuE zZdU=;x;x_*1hX6|TuPo=^7SDfNZDwmVl&kq@_;#7^uIhOd^m|jZ`iX}N;TeyzA!89 zIGac+L>^w0XiQq~BuRM}CsT{ov*j11`_atTzCAU)o%HLm^PZvWJ%J61$khH;z|)5z z30UB7oZ?>X{#CV%t!);Z7YB^rC)8`(qjj~wd?53NmfV^9IP24HZu@1#E1RF*yD+Cy z1KAjn613MWp~z&~`*Ubo<|LbUD0t!rd5o9y4fZW(p&?y*~Zs->SjX)YJxi!;)GJ#B^1YVjLVJxkb~4eCW@v`&m&_h66)BP5sAf9aP26 z!99k0eAhAn&UwtS!wYum7ZluzeyITOwcBGNV+!Uq!RLE? z!QSl+PlNfnH>&erMPO!cqW{~sZx7Ayz^68AsKJgz0Go(tWsUOfw~74R%Z&e@;P~$* zy--@oi43!eR@SG~WhCQyOZN+fCm~9!5ouUJ8sf%{G``fbBKP`%&h|r0AqI2gGG&ejC z1r1-L@nDe(Zjo&{Fh?37-JL9=oIW4eui!S}1XGIy@%jf10`n9QwFeK>-}@ZM_u3k)(eLIiZ02l60_*3 zuJjG-NjC(ah#+1=MdK$wFW%x;V>Ev#A^vu22a*@TjZ36AwGOS`KIcOJi5_}K5kSOy zi;BaaXplhl;l`S>v?_d2oLYB8SV)ww7=t<%f5Ear<)0|DWvG%^rRE05tfG`)acW}e zd0`MPzYR|=IUWDf$C9wkqZMOfZkc+KZcgJ*di_`b!Qc$G_j^h}7(W{Eb?T_B;6tWTFJn*}~taqL;o!GEQ= z9!>|U+|l>b*ug^L(vno1Ak_X3M2J$3iaLtljLt-N3PKF7rj;DGAimG4ZfG_{*2$Bv zXVWi|r6GPdieJvXhlhMG7UJn~iMvIfb+VJz6lQ*y~H~ zaeYi`OT6$tR0qJJQ;(Q@3(a|$7hsvI?5=g@#^{dnO$>iNRCkj%n-5HuMy$_(M z^bM9X{t&kt*=g!mFiGfY;xm{rjx|i=%E9%&(12^Jw)MO&S2IaLsD}3ck|5&`RE7A5 z%vrMIqc1#pPHKx2c!1)P>Yw^tGdKeSF)XKxOKgPfEDYeo$vCJ8p(lEJf^*78*X3=| za(8=-T(N(A&kIYs%9oZrgZ#+W>X)Me%ca4QK0m+XGx9~DM?A#nWB4a6=w1@SUFUpR zYh}*LduOa4-y0Lg&*xa3lu_|fvG78hcf1`P5%5?UAtOqEq=~QxMz&{Y82K|arA(uv zOL<8SF&e}b4FEEYw(Ix0$wuqh|I&ivmZl9jF5?nL*utS-gx`illxf$3JxnQm)lh*9 z`*zysin#RRhv9}F3`@5u%<)N|^c=s@6i?rEo6b5(5WEF*s*2m^)W-Xu#L(w(~NuJ34CV; zbtBqnCVQ2S>yo5EA_cAPdX$5ZRa_WSIf#U%lKYM<4DQTbwrmzezvv~7$BtPK|A(dv zPs9;4ZlJX2eKOwP4xRsIz(+Su5o%W=c}OO)xOjc?S5fQ`C2~BBWtxJ6YeK;v60Ihm zFgCr+IrU3CN8>pSJ|I(eK>RP%o32-AYuxfYd2kk!uyn{L+HwgoHWE{b|Bx-|>)#Qe zD5+}35KlB<+qt}-5oIyzg3BrQtwA-n;NQ0BGKT_A1^FYNT92pmJXpS&st%smH$UWH zvdyY0{-{lD{JMfz1d$Y$%oQ-rN-+O85uzN0|J5rAX+%M0Vj_UBoGF&+I}N-*T_C-f zkpc38Uzq6K7n>KKni43<4D=3mZeXAf{j>1Nt2VS3Pd7_E-+|p1hiM?<#J+wmr*Cc#=XZeWq0wJW`3_`c zo|ApO02eIOB^*gOIJRRiN<+%Feimlre)qmtW3%aPA`>M5Pg;%sxFZ}Fw|3+P2Z`TN z<+bj5SZwauMUBlI?nJ4yYSQ+o2uNe$rS*6+;zJuaFFEnkFwN{JOFJVdKZVC$7O*lO zSU<7-GyT?zQ2dZgH(NPisRQXyYiBU=Pnzi+7!OccUZ7)Z-d4T-K^9op1*;u~^V8;= z=>06z;N`%Mbjk$xgz<*ey`kYzxCm&=DWqi!t%r1PY(5DA-=Xr7rUfF1&`^;zmA&1P zRmzI38u*=1I=!}*5e)D_nR<0j_j|Q+&6)j6VeQW?x{Syn0S5<`vz2;dHo%qHHOgy7 z74LI?;eP@Mf`3HE{=Aa>7tV~ES_N(bScf`U(H>Cu{{#yD0Vn*QiX2%1q!kdba>@=h zjTbrn7=~TA>9~t1SYWXjH9hVvKf~=z6s!NkV56t%2MA3NJe%43l)`BC`wv3?mLY`k zM5FmV)IoKD5OpsM5@5>b;~SZ{brC_+XerLpk6^{^(?kdnB~OS9z)!XOM90^?*R$}f zO_`M#cmLuk+dI7bP^^Ia*h~yzQpk4t@xHnncTHE4D3l%SJU;$)9`wv92Q2@p4N_MpJKplrU09I^g8e-Kw}%%s{MV_+>?YNJg8_ijz2u>4Q_{dj z={J~NrSzdv%??9xWpxL7>eTyZx4#01zs08dDzSK;^zR-Qc1O!ORb)(+sqwv@0C+8P z!rVd`Gv~nft?mSNWh33IJd9Q^k(y2Z`?2-^bK12>{BP219_m<~ii>z_Vy_<~EbKj* z)dNDmC3i)_SI@HvEqq>V4}hi~lV1U=H)oUr&-go(3*-NU1I$l==RJij-gU9!!0Zus z`I&M{Bk01~8~b(9&ofax0vp}nNt&j3 zBSC8E1niOE{wBmIHFbehaDtS9YSmt=>hUls{y$rW1=Ld`QfgQTJ28@3$-%cBJ+<(C zp>{%Y9IU2ArFBdah-cFZ&BWgBn?_r9e}%I-<%6W2q0DE4ku$dS#1)t0r<6dhGPA*| zFd33WXgx!eN6P$zNi~KSFajl$&wVub6wjYco5VW|#Z~l)E>FN7%4sr0UxlGgNRO>W z`ADz7DS)S&YS`E?32Wt~2i?AnN@<*lDmuDP96IRD5C^$S_r;?xGNOIr20RMF8dL7V zPi!4x8eb`c|LlvV@W&r(^!IrQ_Q~o9HDyL@mJuB-R)zQyn4vF4)xIUdeEXZXAuF*l z;bM-VDAU*)?xN)g*=RY7tDVudM3fYe6B>owFNCSk0240AHM;*Tef|@{mrjljk={0X zLL2<9t!)fE!-D&kKv!^rMrag#zYrU9b+&maD_6W$&mQ+VPP&ZMU-54{vFhveR{L1> zh31t38vX8srMkZnEpD9Ps87#7i2cpuEeFt1(YL_rm z9X*H56%%_yQnpK3RkGR*4g+LU)I?*+XN%v^)+x0#%8)hwS03D2g#f=T5d4Nlx$`kI z5E#-f_Qa8i2Ai`?%t!}(C*X8}yE*W3F-y?mM*UJ&;BCn-Nqr#P;FFh-L9$5_5B6Fy zmEm*a=5~uJD!VlnQ>1nA7Q-3X!7-{5s|hlg&I?AcN{vL=S@lG61OkXe!~qS@6k^ft zUb5JmQ7O`CjN@5CmnL^dy^(ft73|V&vl%lV15wo=z={T<<2S$l(zq1NZY`^tG5!(uyV2m6pmG-AkZacIKNk%1M<&(wFSO2J{$evg{6N(q#CegCTJy~N=MvfM zW!l}#lP~GtA;r4Ch1~xJ4)%GV2%v=FIfx6&>WKNt_I|e0F5+|g->sx_`y6oz6k=6R zfzIE-Zulu7;U%$hjNt`wqVvf38;Rg;ELRAK#5cKGt*F3 z$UKTjAmIJNT#Cww5{<$aGk<{;&?#iLHKv0MrWz$2+R-l;{5%!xLTi7Z0=wYS7*^#F zcDGbo+yHH^{^WmVb=yVy4>)5eXs(;!e-{c*Y%#Yn#{MgI-~#wq$t4*{5}$PUKi=wB zQB~U)Z7+NNH)7$+Z!NIGq^tllNPBdx6i=ik3yp?=_$9o*YPjk5ZWDQGt zVU~zQV=7W~#wWbeHw}DggOPgbbQTd*tQ<|eXi^jM%98bSQEdRE(-Xlt)^n%!;jRs$ zvbpsSD#uWH61ewWT}@97pTFP?>h~QGNV*HD0o_3>x6(~Vjt3w$A70B{!dWi ze-ab_mtW!L#V^TB6@%PU@t3@H-FT{Sc5-=%GM)ZfHTU+g;XDowi_{;9Z^&Vbm(NI} zH@i5-noDVl)PX4lBHYSlT2aj`?2QfuK(`5FI)ivNMGQa98jj!R5ZanJGF;0-0S`jx1~5zkqIuo2^@;%WP@f zG7eGAW)YuxvEILrXK&OJK6u{_7D;hYrJr?tQFBf|7h=f3ZqG35f1Jk_9T`1tl$afl zcS{n|f}k1+yf`p#68_x;=UMWf;7O&{e}X3!FGn-~MrDjMxcu;Z&rQH7&%Gm_6EKpv zst2o$fgHIe$S2iVKEvdm6cksaO-a-)oUJPS++`r;U!9e`n+9k51l9AFhNe{q zYM{%5VHnw8BZdt&0!OtZXQ&V1s_udBRHF2?KAPhXmV&N5i>%71&HL!Qg8QyV!d1u% zU2V376xflXWciY+g8G;}7oEi=)P+=>*7ZN7xj;am!h99|qWnCQ7OK;S6xYq{JVVT> z;?ca2?EN!b90kVeqeEP!;V9f|f_$M;+ata1GLpXWe2bO_)3W4BY*g8ro^-%eL?^ze z@*t+EbZGBvH$~BZDqwP? zC-jq85!^R43g0q+AwMA|Uc8^l9w#KE%y1M2tWz78Jk+pM?Ys9QZg(JV5}zgc)E{5+ z$^$r4VvTjCQ)LhY%$6#6Y9847~}ViBT*OC&>Up|J0u z)q~q-PM>7jfum!pq!P{__KV?@@_uYqn5^;g&VT0;^1RsB$^6DIL62kcxtOAF!S4>^ zq&`Rj4dam8wrLqJRaX3{8s{8G>G!2g14#+lIQ@B@I6ab_T`+RF@qHl)i=7*x&iAW4 zHCdENzUZ6NsBr30i|Wb}muXa_ z$V6sKA(lc;283YVWsRCUl$&|ljVZ>nm(AmjDNjkBNHOCp}gDh9Uz}y~m>hW~0e{h(eSXOR8 zLwO~zce3#8o6niub7<*OUpR30eD&diBc`&3hNH%M0cW~*m$}8B5A*?Mg1;u<)SKo8 z?q|&dtMf9-r>0Ng7h`JG=Z8Y6Ky{UELR+RYQ2^_pm8dCG-kxJ{{`Z9{W9H1G;<;+I zHU34-#;fM1TEPXUUYBUxS2PGg}H7D z*2UD!7OLFS-tE4S&*vDOr2z}W0*dNZ5gF1X4Qz2kIP5_B5FODYvQuW<6?u*{l4R8F z)Wz`CJ$;m@+k6A=+rTM=Z)Q9TEA92oYuI8j8z9^n zj0Q%n;REl7K1Q_IxC!TWNjMg10?15~AvXATP}80Sp?Lh^XBirSE?;-gv`*JuxvLhe z*Kb9Z0{nfW;sv}zm+rX%uN@y5sfl7d0t1$$7L>8RR(7ty@uFmQmn?KAK%){6`0>m4 z`wha_2W>zx<%Y)8pZAU`a!}t;C1|!7=eky{_0~e~JRcme|%9R(;_c3l|Xn-xh;)%F?>Bl9# zuSsug*9I#FnQA1ENok)bAQ#{Yht{EjiM)y(7@*^{BPv?v zsIR}@m6Q#Dd?FccTJ3BmSmr5r=aWx&7~w8E zheu`F=FJ{<+XrI&`q7y+fip#0W8qRsJ{(l-#7{z}8DrtJ86HW+%pRjau0^r~KsTk( z5Rq_fG-iIiGl%{PdcY`5S0*E)k9>IWEX~Uc1nWoLS9TpIv8n>!JKvadC5kBn2hn{l}MF>jBL_D^WEG2@MK>k zNL56^AOC3K67U8-q3^&MduZSfJkN*XxAW-Eb4GO`OsIZ~A^LMa)U z<0EwNbuZf%O?v;A3LL&s1eSZeu5v8FVhh|5ser3>^u$yY6IK^r#Z;VxUB85tHD7Aj zct(-DLA(cJ`?kjO+&f)o=iZ2DqoYs7 ztKkq%)oc!2WuX|U3Weyiwg(F$z!k~9?dJ34#u9#Ci~HF!U0e=M*KuH!LAZ%p$ez?ykA7{b8=*r2V~aM$VTd8MSK64gE?mvmp- z8F+tCG+!I-w)4c;uC3K~n$Z&5R&jajAu77nmHXy}#9uv05DM~{&hgzJe*u|&X>HR7 z{R@fBI_3@A_;2FX!H;!Zu}zF%i42CQ(O>w-FPeD z(qoTB?Xf;QRI*S}5({2IZJ4hk)r}I8Y5z9F161Me8QuPV2&(<{4l5-JatW_BgnUqh zOE=n+zGEmD=ftRQ(%8pq2+>xm$aEx)+WjEgOwz-FCSXNkf#uPM_^vbtO{w4_vz3p{ zOGnJOgs6!0Le5_J<|1&E%cbzFLM=u1&@ZkeW<&;k7IUW9kZ}3 z$a0}RUpI9r!P@91O$I|1J1~ko?aA?a0q$-LpYp;3vs@wy;{;84pii~Gii&p< zL4+3tX}qS;cVP88Tr;_Zx9mn)IkqOY!#?J4tAa;}69ElDg_aDB=cphnm8w#kb1cB< zfEvpkYLF~5w`=@;{(1v&zKYX)9y4s?(ZLOB`jMPG%OboO>mw$b=kytDX%g5{rP>n@ zT-Nl~N}WMn{XdMiQ*O@8SS|v~3>byE77SkZ!^+~z&6$xcpNS5d4SLD7b3~k$MH1+$Zh{D zeuRJ5VPf~8h-6r@!2Upr4nX&7RcZB5el7Zmz~gC0%HD(X@}OJpESWdrCHch2Zxo6( z!~eVK1<69WQPEd-FU&qQGsh1?;Q!C7mw)#^_ONn>>;4Dx;=d?eyK(wZA(R%6^+EO*;ANW^=)&AMbyEFZykJ-thI=I-9yuwQXN?c3D2#n4I6RrRj{Y zoL*QJ|1Rt2!Mp0@|J~`~>s_|(`ttJUVr6Wfc6{Dt81u&PK$pVZ%T>ZNxTkZ!%6i4& zaJqWi_4OScC3d#6U7dXX&3L(nSxm&Aky~$nni6+>q{G8}{=yZfj<0$ovTjzD`4L`* z3`_6Qmy2U1E;cT>b>zU@a@+Fwz0-Eb{bT;T@4rQOD$n!w$Nvv)x!zTIqm1|QFV%-1 z5@Sh8*R2y6H|?*42Pjz?=(;Psg9h zv&{VVR)!1J*M8JhJEQeHA@s7<*~ap9Pu8lpKkPHmobyY_TmCGgMQ_8cGp^_Q^HU#f zTDj-b9rhkAIq!ex(*tGx%4`<5J(`~;-`L@@$?e{ejzckbc1RXn*6CV2@2Nlc{{znT zUy}MyCLB4hpY%f0No&XLcblJI_1XQ`z<=K_ll`-z-46)%sc+NXd%5rJ8}mgwzAUqj z_aFBbBus;c_TGI=@0{M=mY z?Ptp-a<|@pfBf~=puoU`lT^KD*i;s!PrtIL}z@uHwZqJl0RTtOm1?IjDd**COuAisVaPQ2gNZ;T; z%KL6_0#aG4b+JpfbK0%R2Aosq5YE!9 znQw2)T?{-!UqxO0afy}bTm5t&P~C3eE4=)2=k2#@*4EP7Z=aoKTYUp~xuD&AeumSV ztaf?<^Wu8ThFfpTfGw93Cr>Kc+R6eq!CiiN#bebRLtrCr^OZevS05G#$jSAkMwYz3 z*1Kehij=hU$KQXsRwxNwnw36f*8JwP_I&M&Q)5@1cnPdVEZJwtU(lPrIyJ=9#ztoT zd3ObY01wfL6R!Q4U%LBl-{qG_UX}p2f}32`PY2fVPh>LrR<$K2Y`+cMMF%vp=wJrl zDzn+VmrYEYw9y4T#09__8W_<;w2{ya_*wtIqAh>h`;aCEAn%kTQHVS$FjqM<+?x19C;^6$%&KO{7Wo>CpYj0?0Y;0w3X6YDkEPXX^BPULNuS0-_CKc_`p3GJh$P6-B@$ z(00qy)1`tVab3xonVDgJQ3AkM5qrS_w?};g6Xj@lF9MlE;B`yz60rgzUc+1;9MqS{ zph0K9u{v$NqXUBr+W0&qbEAbKKM-zUE5Jroy1S(zC9GN=(qH0C!+W9-K= zJUJsAVWPo+yOJggNTODo!2$xEPnR2L0n;h~P(OcvZZT0YzUY{gA?IIz5$<4h#OJP`^Y02k|3JUvDs-c%cI1d~0YShWh$0B9>ua zR7kdJSsqA03E;q3WB!p_>F@0~^oN=xT?hf%5vD4Iu8)VP3SAk}H$Vd9CQUym>;(b9 ziUb8&OC6Q1p!{yqFxYi5d5D^%e)gr0wPUqD#V-sVsEr3S`eFoFz|x;O>L`D;Xv7Gc zzG;EopW0p+>j3`!0 z1M?}4-EeIikOFg!%8Cw=OGkN78bne@iVkw!{p`RW%BJcfqES!b{czSpEbW{B+P`P=yxB0 z%0rNuE;+pKZd$ge2ca^4VgjS89b`N+dL}AaG4SqA8*2rr%}~qm$rsw)-6}_4njZM* zZle~y|E@?$C_#t@&CS@LpnjLTI!Y{c88~0)S{h+IRS1OTb^i=|lU?h4VY5Jr0379L znWaIdGJW_TVy7kv@~!4yZcf;s-ag&qDc0i2bkF68b^b_xcJTxk->=zwQM=sDln#z6 zDI;F~dNO)H*&5VECJ!g}kov=nzyXrFLnmUp$a~<%+}Di27T5cGGt9J`ylTJt4`e_+ zVm;a`>Cm9mD;^OEIT#MD-NHB+0Be~){C7-TG^Z(#K;XGg146C-9cx~00WAm6@T5~5 zFKpd9T&N0?Re_QU%@+rij$l1JA+3t2Q5bU-^%G)#fx*5tGo#}fUH;I#=VRLgvDkK2(sW zS)YCcYtDWd8%BnnPL6i+U|jdyEqC;m(c!s1R^)g3Gtzi3(jB{)jNL*$p#PS&b4oiX9Zgp9vB^Wj4F5@qFGF8Df6(S=ZYR3O~yc z5J=yOqkQy?Q5bIJ%b-1=m(>v(6-(E%Dc}zbdiv5Cq{|AQ9gaqm%m)V7L@?l32NJ`I z5{+ex;eG`$`;>itEj-2g8`Nw7a+FIaI{vAasb5l7v?3fDswdP{0uJyCCme)uDm*$S zE{4md)D?>Q_!)AS#=Yk23mHwGMMH6pC~Td$bjzkn(Cf*0U<{mhcz-(W(+)pa2Ut zE7%OwyblJkUELUTr5n;?+cdy7XX5wI^Qi9J${@D(l{^VT{UHfqw?4*BK`aJSZRh6rfDil9U|7py-bbMj_Hw5I2Ssf*i&LB7vhXy47w)joMVvK-aa z0aovBcIS*W|E|PCi~sPQ?z!l^8h1z-;rdmcY)MDbZ)PN_scvs|5Mw@rXa8%WnbrjB3~gTy4w()Ub=)T*EXPhA9fC_P5W7b`^_oj2kz`w^G0hW9n9^*Q*{Zz*aquwF8-||4 zKgTm)U2anD8B8DO(wT!vI(iIU4DYn1-KuL>;L@@ccPI9V(Y$&-bs04JhzAyr=P?v2 z887re`q{YaCZF1}++H5U(_iksjdh2Za7_&NV_m0xioGriK25I=h{IDeng-+enM%+{lJ?heQY8pL;q?p@T=aU8 zwz<|Dy(5DK*54heZ&qeO;7Gh4e;LkEdmRH#C@v8p2NUoxjGa!)qM_G)>3VLkTsRWl zpfa^vVeV2Q(>w!L;IRo$Ck|d*M$E`4`2aDu{o!^W=imZfTj}8B>!y%>_f;&0x_`~r zZ9GWB1yOW5YOF-?_W%~|Dvb~!2FModb2W|xMfvVsx;+<)7TGKk{+Fq z()1Z!vKHE?J;t;6L27D_?oGct^cc=KQB0M+VM=Z5of`6cQ2qb{*;I|TOHacmy&Z#} z?o)^uSZVHdfT-C^DE4wTz$_-%8}l`wLIZ$1z~bYA)q205tyIR~kX{WgBbKH=s1cDw zkQV6g)D_zzOVIXwW>{QF7EL4Qhx07~;A^D4-huuW`s;MXAMCJ#{j zlp7MrICx?ZzhTkOdmqj~YVkD{Uq^VfX#s@<`|zCKX#fQs5S_+C@beP}#$(zKaGIOn z8F9}L;f#CO!#xSt=92;7pxCB0_Fe8Sj`LPK0D$q=g>VHI$Ga>J7fK|}JRHvb`>%bb zh73;QUz@eJ^Zn6kB-@l#UB4shX_OKXt~d$L+>p6$p+^Zg`;`y!a1 zYF?k37#`zJ2Z;d;M5kNE`TN5_7OsO?6g#W*t{ltG?KJ1$%}X`R&E_!psj<$>hk&0P z-#{H2Ah#PfBanaVb6>97wefyOD;(Ph7v7(VAqNH3i1s|CL40e#@Xm4qYPf!!#6vA) zr59_Ct!la)(B0`Trz;ka!98i?&;U(xHmkNde;%g(*RXoa%e&#IkF&cTT_Wcv0`r^T?|W4q}_2OAH|&_~*6vOiKLrd?lrVI-ovsfN#~PX=ON ziGA@Tvnw16@!<>~xum{%3%*uuJr>YJXoYYDuk1_@Q)Mx>ps(A3*UE(f*E}qk4Euv} z6$ntC91a=O^L%SD(#g%GD7(9u{QNPJ3<`eCWhkkuwFBezE%qZJ9F_a`>DQ8KzmbT50obRfpEHm?2y5PO5dis_T)X?<89sim>4cQSb%mk`#=_LX zhs1`LpJ;2hIw3?HFYGwWFnv%wz#{9%K!007%h0e3$f9Nxz(&WMu3;4*J@&7Ai8{v@85b*}G2gp3p5KkO@7>&Qt{=n~l z1ePWOB@6|xqY$=3(N7V@HmQU60|*Rmj4=K?d6lphkylg1PdZYVI@VV^3_dmkO84$R zEqCMifSAMx?C|`mT}@4|;(-SHZ)A`dMVk0$dyjGBAkf%ik_?)Ty&de|1f7irrOT*> zZ}$KeIodQv-%}yR)VUkhhVWy#jPHTRmnRHfq6?Rv(Yu1-SC5vy(;uBUpunGkbSl%2pJ;3l+fY@7xc*)QENU~ z%V<;zbw^cNH@eQskl-pmH1hJ|M6aAKn-�O7+ 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 US^v^~vVZfq^b=4{ssEP$4>Hfq+yDRo literal 0 HcmV?d00001 diff --git a/examples/platform/nxp/rt/rt1060/doc/images/rt1060_evkc_IW612_hw_rework_detail.jpg b/examples/platform/nxp/rt/rt1060/doc/images/rt1060_evkc_IW612_hw_rework_detail.jpg new file mode 100644 index 0000000000000000000000000000000000000000..c5a43e6f4ac7503c91c47b4651e2feb998e33349 GIT binary patch literal 40681 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

sxXJvRWJMW~ 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≤;CgWH<)3C)^9y6j__`Q#s&`JUcu-!edXA8 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 Uc_5(0)kRc8$v^-800RL3+2h9%wg3PC literal 0 HcmV?d00001 diff --git a/examples/platform/nxp/rt/rt1060/doc/images/select-sdk.png b/examples/platform/nxp/rt/rt1060/doc/images/select-sdk.png new file mode 100644 index 0000000000000000000000000000000000000000..335a05035e18294999fd64258aa8f4af30a77501 GIT binary patch literal 138646 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 literal 0 HcmV?d00001 diff --git a/examples/platform/nxp/rt/rt1060/doc/images/startup.png b/examples/platform/nxp/rt/rt1060/doc/images/startup.png new file mode 100644 index 0000000000000000000000000000000000000000..cd9a8ad90fd8052723151629ec1890d7501d0a7b GIT binary patch literal 127461 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 literal 0 HcmV?d00001 diff --git a/examples/platform/nxp/rt/rt1060/doc/images/toolchain.JPG b/examples/platform/nxp/rt/rt1060/doc/images/toolchain.JPG new file mode 100644 index 0000000000000000000000000000000000000000..068ebfb35e1efa9a35bc4df79c94adb5f9a16aa9 GIT binary patch literal 129143 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

cq2UV^&S?gCK|IE0a)aaC&#s zFP_IQG}bl;`ehM&+YzOa(cbji;+-{Vq`lkSSyFwi+KK(ssw+|LycUQ%fzfUFCbb`W z-(L`8n?n3bW)bx+-Rv+vA|$T}j7|j!i61sq0rH;6n?lqa`1IZ{1OM``p@lR6?zC&B z|AFn)2PL1sqBR}=4OhYA9~$?oNd1NN^#3d0|J%GhGx!b$dMJzns*!bvK#am09kLgV z{$s1&^`-JETCR)O$Jvw>C=1j?@~at3MyZOWI{vyJ@Y2s3r<3vf_ zowO@ip4ZMA`TKM4E)qdS_qaMOWED86S7J4LSMu;Of_Y&p(6%ZFscze$WgytlJvP_> zs#C}N>w2?7ug@=Z45rG~b*>3gFk^M%Oy}8du~AfY2aZV?V6xO^TT!q+(@l96E@goa zRt`GmQE-PG_xMWle{${->r5h*J-^Hld&3ZAyALd>B(}}4DLsmp0b5FnnJ40f_dd?u zN~}z|I2KPnD_bH&hMYS?M$b&5y!biLkUcY`1iz=4fe=v39Z&3`qM$trG3GeR zooXts-@LxbOS_HjmG={7JU^%BbG+4}MHg1IGp*A631bOjg<)#;=tzDF;U1@i3lw9H4+w7{mSKlB9j{vb;*YkHJB^7_ zn^KJ~U0=GX!4-rbh6h~#yB%-PM_LBdo(s)My|lj%?txIk+zeP{%RniBTHd`_m4S&Y zR73Rb_=GMxC!O*W+9}4|1N04}gCea<5+DuB=$$hE1a|t#FQpsYoz}hsZ4>#n?7PQo z)lOJm0m`i7N+$lO52#088=lIj-L0wm`^Q!wE8sy-K@kD;5@z16iu5N|nv`lmyAVdM zwL9ui;!fHCzj}&XfxXf|RW;Vy_sOX2AoDZd{MUm?v%%o*`}Ml%p-oTEkRA<5JuQGb zGq^tZ+^`P-*A6q~WR0HxA*F@>RZ45(|C~;or~ePSg8tXJ4k}0Y4DVJv`0J8}&Dy(H zk&Q(jf>)f`7h;e*DYM6ICz0b%6jMMxtm0!aw%1GZjB?=;qo`4h`7y|20$* z+uQprrJNXvSH@wG%aW(1MzyoEg7zxP4P{VFMkB6b5+o6e@7B+`T?4wlPwlN;Cv^k* z9-P9p8VC6y@98QhQr&*dN9ZD>2hgP5oFCq4>VD#GuGbVT68c#I)(tCLzz<_ns$MxR zXH~Nl^YnkLt2FcnOr-Rb(bH{Mm+R)SB@M^}KR?_-3DZSGZ_vzR=o~hWl|KlQ$U#$6logu zm{^hthX=dUm5G3uIlf{J8eYz|CK#HL<6oXV9(<&m4M2R-1H*tToW_#=crJ zaZ7V?9(_j310}YGGtF6T#q>eRS@B2+F{$(i$y?kuatC>}^Vmb8d^ee$Qd{m0IAfo~kma?H`x=7)NPB;4>;$QeXpGgclU0eqkswZ8F@=C>L z5|jsT%5~=^(WriNt{y8a+x66&Gp?r!pT+24&cEL$cIakaCKxjAH|<#iN=+nZ zKqsGS>JE(cE#8F?Lf%r^^14(N+2a`~bj*HN64QWHaqM93*^r)O9ZIZ@~g{TTuQAneum> z#%R<%IkPA5T-${9fyj|gRH zP7cF!!FRkY>gzw(sjOK4>*tA@rKxQN^iWnF$o}5}Opvd7dEq^a1Xn#U?xy~Y#e3Yy zUgY{5hN8$ojL^4Rh{*%f40~i4Tx#JkgX0%MUQTW#E-dyGXdi(o&Y)&WyMkeYPlEWVAL9LbZ~|=jCBc@r z!z*exzSjvft{m3+CNw{t1?WhwOw;PlHtABg_`kWjOUIT2JI3(bTK%F)j9#DMQ!twTHHj`hnxA zQ^2wc9uz5ABTCj9^PE9#0lsY9rbYl<(d(t&F~7*cD8pXmPO1W{swA2c9EjDhXK00S zqqVQCCM#b{mkNF=~-$)j8Sqg;H4K= zN?2cCv4BXfb6M#!Sl?5CtyU+3X>wuViODm19uChD6E7bgX4XgfSu7w~l7`$5nv1mX zGthJc{lKP7SsXaNZ=SXv+D2L;$UxQ;LBxCO7`G#6i9a|#}Sq-f3dU=qin zN#bbFqF$^Fbb+dZ90%`p3gp-AP}Sr%FckztF&0(w1Z!D(0OY|Xw2xCJB4`?rUeBHe z4IzGj2U3*}nl`ukUJ0XXYum55*Hr64O$#LvmeurJ_Ki& z42ZLzff9*se{Q~$EO_7!*b)M;0R&Gy#$Th}eG6SAcn42Q&JP=u`Vc0FRzUH$2m*gJ zGCFO^HpqG9U&nR{HNJ~uvdZ5jrr-DQTTX#8isRLtU~NeSD#Eu)7&E?K8||UGH!lPr zDm*8Uku1)I5LG%5?@b-Utp(ZicVHQA=7Y4^O!oduKj1q^dq8&H69Y;wz#wXd#0uf~ zA^lWv2WA2uLCNK#yI1|!pCjcg39H0RuWSUJsbCTjGUW{%g5G4}(WM{+ptMz~ETGI{ zRzP1ItiUok0Pk@QSHV%3lXIQtDuhtHgUXTbL-{@{-)-gl4*J{k>HE3z&ra?CsabjU z#S7eQ?6swD=!p$b4ztYEBJWk1um=QUbX}p|rR-^-1iGm(UlQ_q9!w+E@xL-=1++kI zvEm*6*u4TQ#n^vZ&LfEz!C02EN$r?Li~9SUZDyw{DzuB;Z!T%F2*0k_qLp`raJ@%0 zo@<0(p<#{T$2$xi^S_A2HEv{#4eLg;dnf%w(5N?K|Ai4XvKj9zmI6q_SCQaBMT<*}^9Pu5j}xvY;3) z?=eYY_igw1)dR!7XX7PF3zpn9NG-0NZErUJCiNz-CLwHUnT8ON1kj$TWqS84hwDMq zqe-$9*xj1$s!eY%R%)xww9k9pD2bRjr)(*%AsE;;PKonLepNfaN%`RPbuRfk%)0RL zw~Ehk?*=mV-p=!icw1uBQsuUWsG zdJnB65x(HG2v04uM%qkI^ysu4w{AW)aC9}j*vIdnvbf=x$m^{=U2GB(rGoFs2U*au_Nu7f5@@ME5=J!4D6h^`+y(((r7G}x3I*fhP7fE zbK6O!upP0dtJ7Ppji- zOgH;f78My1$#d5Wg=05Ydc`9MmV(GpOs0MxA;!jO$@#j#n6}+vR?2$n+ic zRaNSU;jmh!o5>@6?AqYi-Dq_5R;b}1Sb7C*82G8uZLluCj)OSizaR>#@!?NOs7K#o zm})U@a~D60rY7`#L>qU+<uDd9v)2^dktY+?l=nyk~F z2U@F~#rEPVb=%O87YxZ0Kd-^gGfs8Eo|uU~+fv7hA|7SAs3PY2(q{O**bMgLSVf)_ zTx<`U?sl%4(+Yd(I%hee%$Qv#Ke>Ofi?LKQ#%gn@rkLv|MJh#qJKVf`moZiM{l}A% z3FlsXhXX2ml15r4$uxo@n6n|hgoUT!;}!Xd%PDN$GXEk6fpIa_J?PiTA6k`+vTyF} z?TCAqJ*IWejK7U|&R^W?cN?@1am%%~wB^PX3uG!pSy!g@p7?GLzG*$4B1^5aS|aB7 zSq{jII`*)SI8mop)4#fR{nk+BCI2roxJ7K5NcCUPnH@UhRvNvbkR#N(byxC?TFP-3K4SLJ83#Yi> zq|#^kC$9EfGwK^?lj%X1!!&+#4OJ5WmfH^r9A}?!y%u&bojjQ5-2<U|-BzSKRO zdd^S7j6hriTh3YuYHpAXkmLNjC7&{?Y0<=-(id4C?U5*vX}%x##CsB0T*@!Og=VK2 zd@E_+X+Y{eg)Y_O>mX`CJ2#F&e8cyuls7w+&F@QDNPnAHai+=Z+zsuR?r}}&h_C~a z!LMt*dIFm=>g#A#AhN3I7Sok?k*kN zuMR+5dK%fjULdR}BqEAMXC<+H1uY8Wid%%G@?jsKpFtZ{(2KkPM+3zjSKay!>WT?- zG;Fen_7>lp<)qQF1yvzw3QjN$GB{pK5JNcjnSX4xy65fR;+t>@(pNK>q+4|jaZ|<0 zV`V@L2Q<93p6F?W1D+Cv5O}v35YJkrlk2H@3gE{~)|nO~00bK)8_`Rf^-~K|G!NAg z8<*X~e~i)Xat>h-W}Bh566Ztw!(p#GMQwh8c`arMCi}Cx3omX50jr~v2^-UuQ;vV< z6_yvQJ9`z*- zZi*hvnd*4C;93K;GB)_3!fUY%`z#Gn6tZd6v`}i!>m3+nEJ@!h?XK17ApMQ3^7z6X zG!LW1sy>QQ6Cr53`F0ts`VwuC&K+JXkDfsONX=tZ5MkZ;N1@4!NJ)ga_o`WEOiegz35u&W_3 zm5;;2JDzxRx(WN5vry@VV>8$dZ-Wg?Zci&DFzfb5S(vhuhc#KgYh_W7INP11ryZv7(PyhCRn?!u3=kfiu;QVR?- z4E%!#qwE3vK~x)UR>xP2GUPJbL&(~vsmdf9LMT7k`9$HHDIFhhbLIXlnNIOd6=8J0 zPFWO*d*O@eRFT_jsFwqr=4iYAYTD~Am{9fwjym?JbEs5Hl8eonF%zwqR3|SNhnv@2 z6)Jy@F#=OytH2~{jSigrO6sicyLyd6c!F`Fh zuGx66vhgyb#o^yKm5v+_%g{XkthD7ssl@sYZL^i=0#^vK>&TB16EyHIpZWkQr!_-^ z>3>;I#|^6ce`EbuzoW9C9*{Qu=?|^`{5KDqj_zLb{d4|0vES$CZ*1(l{rvkq_ zFoo+ulVdC{%?WtycF)=+t=`;C$NS?HL8CauAr&3hVUISNUlin&(U<2*%&Y`5QOLH( z9_nS=hG*5IUo1|m8kAhM3I-RL)MGjNpC6Tqs-`3X;qN>OqR|b64k}3IFc7Vd!tFrp z`E6s?a#zME#h=m5x{7yA*}{{B*m?O6^OMAj;L42q$Lw*F+4ym|0x>CLM)$rWD zNgYb*2xNF(cVhGn;A}i-#JC;jw1uA%_L_9GdFBA&t?sR?EmumLVxYPUF>dS|&8*Ll zPYiI4fH0I{3!(vL4JtnYBo`(XIsrM(ToY;rUz@75(~=d?ZxO`D%qFRKJ=G6)@$Q$Hc#xaLe0`=s9P5tbcf7#Nd^LS08s@iKL*@TPc6iYL_T2xQ)PL&4 z{oab9@R_O#8*;2FiSTBHac?$lA;}Ql&yDiDdXS%)CmD=3P8j!`?w&h4l<+S46L7iks-Fo^Lm@nbvFy(Q^wG1CZZrTIH5De`{-eTH(F>DKT+_~ z-n)5Dm|8Ew#6ha4Ih;UNBDuo#y43^?P)AcoG05Q}J}azvu|l|(zIJWcvFNrsn_vxz zV|$mrqs~;f7J(%SAI^!cm~D}~0$T7IIg&hMg=KKaiTos>)pzsqYn_7D)%wV0k0AL% zr*6vuong;O8y$*{H$9$W=sY&a8@HRi2w%-2oyixB4_+@;_T|>8C^F$l&!tRT`|fRb zHZ&4;$uy2$mpsBdmjEKKaGWk^zjOLA8xG@8qU`u*J+5xNnRqEB?u)&ZoBXqD>23{W z>YDw1!TqAN!k|vq( z)k1tEB&f2XeII`&^OkzNOhU}6FV?~il4vB@1HWGq0Xnc;*lpQtc@VsU?yqvPb`qm? z+Qv)nbXA7?uMin%zZo15{$i_?^N=H0D9D>dQd@Dx6A=icsfkyAAm4J zrdQG+j{HIklf!RpGHvXr_U}t5;zO;gYJJUPtPN*GeSW)Cd!aSsq&;F?atkpBI|f=A ztzV34DTHxK;)?j~P6aHZsI(eqXw95OGvICsvepf&1Mx|lLoG&7Ju`QZzR-L*eQEoL zC?FO9l`BhcmL_YVpF+f&wXJ%xB}p#vZ+3RyEnpa@aTUS})uLx?)kjY^8kN|OR{US= zy?s2>eg8kKTS;07Ay&Doq;(^TwRJB^ODaX|C>4@+C^F1GN2!pTg`pafudwjpw<9Ge8>v#Tf{oz4+Fx%cYuh;YWd_AAj z=}s*s>;n64$I?aO8PNj(2bk6ySZCr{I}2R5BVxR89n`m4*EKa_8t60s?@ZntJ@1Yho`L!m*}#_4||$<0mjPuD;F;v;IvY?v#$_t4<*#m%%g2b8s*WrQ|> z;HKjlq#8_ojOPU{Ig2-Y$OVtZ^A97<^Q2eV&EvRLosQ2=!HRAAc+@G1*IR~L>m*@x zl$(yyEPtirW8+R$sLEyd>ylB!3t>R>Fdv5N0N_g_=9`66?D?lDr#Hr0YP!~9onPS6 zU+uNjte@ZX#a$Q*d_`y{!NjjZcC1S9bpz@nW-y*}S~Bsm1rzVkhj+GwBFmQM z3BsH!rL*JlLH%mly{b8Ohwn;vU@os_e3 zt&rGp}y}7D2R(BmwV6H{SssK{W9{ zPpg#}TR1{?598=TUhkA53FpN~A|&d54w_`X z;Pe$N{K)GgReYD9Ev0Ipqe3(&2PG0IdNiiKV2n38A{FM%(7ndR({RSgllRl*O*CY_ zHaKwSf@7WV0*9iup_f43S;8l9m{|WE)h6{Y*ap=i0Ag8evnnt{LV`7L+}c!exU>Lv zk>Q4mwQ)H3ejjQ+@zQUKyS!?{)rBp_0G7%1v5X{&Uf{IcxL8LA}QCTfdae=Airv42>8piL9Jp=ygOi)`yRYWaOiw za&bm-JF&Ig5?_^LcU*iWtslRvG3(T}QJcWD3HPolv+*&AJYo7C`$k?eTxNlMf`QmqtYxHfx-Vky+aO{_QTM#{TY#@KnH0%HWZZdZIo!0^oeaZz6Hl~ z9vOY``N|P$hM@a+?)XuT%=$YopZE^Mfnr5ty_sQ8;43?fijt0z2g<@E_M10~pPB}h ze!t1tDR&o}ofKnnT4iF>awu!>6Qt8x@4~aLw8=!1+b_djZeMkPRH{e%95rn|kI##P zyqR5Y(o}Kn+o$BW2R~u=_A#Rqz0Yx-;G&>RSD#tOoQVULL)a}Tlm`+;Zp)zk0OLbY znz6m6!rg1n8L^9uD38Il) z>tw%Clx22QF3z^&tm3KM{E0WRp)9d_8QIObg{jeIOsm$m+T2|ixa3+{Fe*rvjQ2O2 z<&FnmJ$aHT+vY(z3S-2!9w1I}BTAhd?i{|aux*l{4Ik*J_dXWyF-SU8Ecd_Eue;w2V{*WQRUoxkb+$`m(dt_PCwu zdvjypPMZJ~Sn!cB6*@9ZiZC=O5!c-;>^as#Xe-PPZTNM_E6Zo%lzRmt$4D||H1`F| zftnFFuL-9HXCF~SBbxOuV6$qy#)zAU5ziOINOPs3<%*u9?jpQJbJt;3@0r93d=eNF z!wif$ic2a`%PHr;5iB_)V%(7LegX`sY@UY)dGg(4=+RWJhDmgt=~E!}PxOkHzG-={ z_{QDZFoP(<6hB3qiC_yvbPpnBKS{2t5aw@Fm^hHlo7GR4C*LWyzBvi3^-gr$HtatB zY2edf$CSM)Yte&`MnN*{g`a)#^RJpuwl$J7W!EYm;O2>wZU8f-HKe;5WQ<)?E^FsY zcBj-Ce-Z^yYl_ zFb201Uq7J-*AsT`mzJsBSgP0ThGfMwFq%UIV)qlv=X`{D$R0XCCSHRsWoW~c3js7M z(b>>v8&IC?eVgrJ4Y*#;9YD5%ojmKX^91;f15bx}(xrJ|By9ZqymP5RKa>oE&{H4N z9Kqd1v!%@r?m`>G^TtQe(iN@v$^4MDBITZT{OINv(9rqGqsm!GEi`c)3;o0OW={u~ z_l%t5Q45@wMm0o2Ne6PIi zYfg4|MLCYtd(ga_qAzea>({wm*b};^_0?3Y{;3j&xB4>sgwW78?m_9bLshGlX=gg# zU58LOj2v{DH`AzXUBoK9A=&7imCi{+&7!v4BBlyAcX%E(75_l`1mo9tm@2`Yvwsw~ z(A<_!0FmE(<}FatKgBOaG)KDBIB{58QAA%H9YOnDU;ZZ4_x)6`=Ggm(oh#+2v;|%& z=CxbFQ5&7~eSPm}@DoL76ESO+@F-}doGP;-t75BDrIw5{q zUF8^_PtOtIs~9T^-S_sd@hN6pYTm#PHGhLu?8lEhdm!s2z=qyg`e0|>#m`u#D@+NU zpeHGxL1*C6)SWOvN`&{mf+ck}>E3KD(ZD)fI=MKpCpEz9V8z4}yLcpM_rz+f!Z%Jq z=a4YB!Hd!ni^1CR@#>e*qQq06tnzkz>g%eV{&@IY_jT@0zraPSlKXl0C0dK;)n2Qi z07P~H_N{3Dw0v1dt)qyBsK3W9>B7bo4v%k`7~m;@4`=Db z$1`BtgWA*c!*=Iyw}?|LLJP-$T;&M+_cao$U27^&4cTZt>bgBu6>xLWQC1u^vXqHc z+=nh{D_*hm5TimE63?r!*;c*D-N(gnU2)-WBM(|k;lZ2RH(rcimb*R82zo?G^PPaC z7vW&O4_ldXRIC$DwV%->DS^%*b zFQ37O&npS@%!)8=cs_dw~a$i#ZmJPfqCrdVTLbb%-&DxzUQN@8(+O> zt&mN?C_K1~^$uuP)98ii%7N#tVdFZhefol+$lpsJ1?c zfg)|xv_-xfx-?8OvH88}dHT{B1AbcH1Tb#pK(fHEoH=qxB7a5&Wye?WBNV;Rq zSXh|OHy7&ITc#|iWhXgjNIncsld^(U&N&UtNP|;%Y&iiDXNf@51BVL%Aefp2xbAt< z8%f`md+9b(&8gjVtrqH9q#Lho$&Dl~$7#vU^IJCr5a8n>9nq{EFMB;sfi~$ET0@y= ztkvfBvt?X^PR56W0+7Kd0pmSoQv`h;Y}SX7YX$9XEwXUtXVx(zd)JDWMrD9y5BoPiE(ezd zP&9=s{x8!R|5EAnw^`K{2xx}>X^`avbun3IzleKhtjN!LfAeIIbM?swE_yXz%b(i$ zXT5)rSEqk?*!unV$VgTCvU53PH)Jo}2;6-!(5%A(s+TWbClJ$_iY&GlYYHa2ioQT7 z#L&l3O=KPS>P8P~VSHF7cId_E2tY;1XuPDdKjh=F7%w4kXw1trD;-C_$fsbNyu=f5 za-sVM_^!ECi}MNJeX^^rZ=>|SI8Mt8)})Whl9gl~Xg`_0e03iDiV}vZq}>t0(~UAa zxv@Wdu4WswRR;Ry33*SiY(zrjV`}hG3>4c63}xwM$U?~@{T=Uu*~T!muZ;Eqsk-^c zu);EX7emryVO$ujiGKa^|oJx^>#tm253Fc{qr9MKO)IFa!>)8UNFA~7A0{B)QCQaA59Zg3i>DHyA%1G z-`whk7jiYNBXX9$<~ZcggAlxXM5LuYUgP_;4fToF!Y60RG_{&S(W`q$Xw&gcZ+@XZ z+&1Is_o50V*W)mEN$l7=l~3fI=W!W|5-inDhIrK%h?uYOeJ{|3<-E}v8EV*C4?7#n zh{paR?OiUCboq4XblmgkMT8&Yx|Syd(--Y)nek6AmF*Ce+jJeM*$-~g_6R1$K=C_H zoBA;*X&R5B>cPtIN?hsM<3to3(&7-xg1CF<`*6fB5DfC3w-}t_?jChcKt6?zU|Y3X zPOkI0#)Pl5IMX{6b#&`>uuBC;bc7gfO|lWWf(5(j@?xTSkcSl?UbiPcD_M zOj_3SPBzxFZPBWDLHIEj#o#PwvQU3kkSj79nV8p8;vSFHi2G%*`-<;FGdd(ZYd%$y(PZfA0tcfphyAeX>xcvQ5LR>jq#91>5{uZ~Rt>a2cakXkV3;KIn(o5>4Sk!ab}_M4hlJdN1t6=cvI< zXEC!X$DxL|B7nKbyVtxufV8x}-!?~MxY;f!rM+#u@bh3CxySle)$^*aHyte$ypdjT z7aHqB#0Ci2CzII2CIHq)G4FV`uq^ngXn4<9Kr*#eWE@^W;i!VkY^dTM)Br_U9t=mCdBiyE3zuQGQ|Oac6|4a2#R`G z_N972cjRV1c6?f8?DBTJ81in^jj5IB3VtY^nn?`tD)x1&LFY58fJ2CLzPPtQBzPB6 z5<6LJmoL^Dj2QE3yDaCF<_{%)a7=qGcd1C>jU{J+$=kX}HqP$xm39kI40ey{iB{zd=!XG8q6IYBB67AhMW}PS{j2lnpM_Xq;{ac2VE~a!rh36 z=Nbnz;*moeK^yYR$WI^EVsrGLJJH8#cmEzJ9%v;*u;ciVG$l%6AL{KZ=(8s{&YJ7L zr~f%;e3xOS3^XwHN5wys6u~~kSp!9wDsd@if97sxGOmQu1*g)@r3AOYNmVVP<+oWNsX)&A@sLQIN_TLQ+WQM#v;w>Wfe>O>-6UDJ6OAQ#=f7? zo!OUJ)nm4s)xidG?xxEWr^`tpCN-ev8TAviuYyWV-qu?S?|}%KE#`P>qvFLy#Ur-z z=aF86yw_q>6wB$=5LI7P6W$mZXxlyVrZ0v>n7J6wN=!g~i5k`_qu+2dB+XKHz+VyC$0~QSSP> z)6Q?>R^n#)5%7RC7~cntG0;^EeK`FcTUC_9yYX1;NPnB-``V{}V%T@c;#jX$aua&m zUnnpwe=k2Gl7~nmGK$Ne=4SLqnv^yBQ9IF$mwPqR--}l7NU^kER`7h+(&XCx+TUoK z!g8Ho)(&sJ;c=}W(-jJuSe9y7exB9djDDtv4mD-U<)!wNz2JWwH`WRpnmLGGjg(HQm8g^GHLpO4@vb8 z@%t#VaozydKL2IrcnAA%nDCaAU~c&oJEx0%tOM$M&6^iM3uiA7e=Ui_n!O}@)*7yE zVOc|2r(hc4K}ThY%k>2JIWHUsFGn;SJff&uQ;wfGHRKYd|4-N?2o{xV~8(IUE6*Yr&Aj7|87fQ$x(AM`%X56|4&Ioots!V6~;LZVG!g^vlpO#O@#%#lBix8y8|Jr8-fGJOXP6v@I(@fX#!&U%_~MBcjrTwapn(_tq|PVQ3c0RIo=j zCXfHpzC?R-R~=i|KyZA*=%94XoVd~vcfy}}zrl~mvNLc?Uyyt`*HyeQuRps&q`$YB zV$|mtbfoM}q6}Zv(G~l9(#bL=ehmu$z9@m<@Mc<3VK0X|ro^XkbvtI~S-+z#ZWKR7 zMXEic!47_tJFr`l7~YA$w9vf=$=I}B;_UlR!cI<%*GiWMay-~sr{!v}lXy)Fh*uEB zJ>idxsO=gqF4lvh0^P#&dPlDRP}*!+U8=qI+K>`67C}*YAgI?8ia{6J)mogJc5Y*t zy^^nH^b@L>D(-|;g|Ax*K^bB3=-qaEj8U9w7Fsy^CKmtoA@kYK`s}mdcpKKB4}F)u z5$+Tx)v&GGURi8YICw>8hF1mAuygHh?zF%+X|xQ^C=oU(;e!vQJqpX55<5&C;bY>Q z5H@(BQ*6ySu!-3_eQu0}z=v&EWm@|4ic^{Y04yyR-sg#7+Yb!Cu&rE~>X~2${^2h? z&fv#j=1DOJXwH^U?8UrrmQ${eMOZEcU;3uiQrC4nFs?SZFQM0N!m0WyKHli@7Nb$g z(hqv@!VW=QET>=Jk5uO;z-wXRR*S~dH&9n09jP)W6USrZCU(oWVEQk+veJ;YNgere za5uz&2f-N-XS^RIR$(QL3q?cHh`4zxFDnck6Ft4U>!&lhsiVD!*1MYgH+A7VrrvD4)_$4O_lUQk51#XavMupl@ibMvJrFaN4PTj3ecLcI zg-KNG5I##DM_R2+%_OXv&$y5hKI$`upL7dr#_!SSuxls1qG0+@$%)T#S^a*_$4g7v zGz09mnK&qsPjqvVb{ybIr!mO<YP>z2E5!V%;k=4-v47p%eJN!u0W zfx-o_i(RU~JvYj*NQRXMH)*<-i^5`CAB2=Aes8(7iLjuMYy2KL(`|^~3@|C(8F9<@ z)+6hEWtnl$%OOqE6r>-pTSoVU{g{B6rQ3SImui~CY{P_k~^gn_#-_QET`-* zKH?z>^s1z|IN@u5;ocugM}`b20x=0$%n;l1r*9(aonKDD7)P;JEgXo^9BT2QYq!h2 zJo#Y@=ilhFf81>Ft@R3H?5L2ge5VHoItr}3fr z;6<>PGzS=%c8`X5M0;u7{@wHdv}V!0HKyNY-t3?Eh;AN)?Jo#0VL57aZZj=Om^rum zYWwg>9STKuV&XdWP0pH4*Y+V6dl;1#z=Uh}&${#9;p3kv(EIH!X5uQuJ}zS_;)jx* ziPBm5MgX$;O)CP5ekipBW&~b_#(L6-hd%HsK8 zFYYkwo#{J)ztxo_-!fQ(jzDlN)J1adCaS(KV}1@r)%U3neR*qO4zV)j_U*}uum{pE z%TQWxurPn1?rZ(mBwo}UW=mqjQGFB=wtgq0EL}m_h|lt9$()iBzf*}o0=NTzKK5cm z4NolqC`1@)Q~R0$|L&!VLJ{k7ysrjpPjk8w>rJAC1Ppg#V1C`S*ckvHEKEP@t|11% zLI&jYBkh)4*b99p56-T(xsv5)QeN}CC?vtB>x?FdINM=V=rCi2pB6A%g6bjZRr5#@ z@f~-Gd~dv0@?{BK8ntX%Qf3;}dV|MazRb68Jv*|(5<4^q7xI|vn-u; zS6@Ta$khB7jcZ9Gt}=TQ(#UD++2j|#K*h3|_+)0a2;$d8 zv9tuJ+mJTP3j_sPM*736>?Qz z+kJ)L3E!D4yiokQ?eRaIyCi%5^w_@ zpnY`LtVCeO|kC78@PJ2O%=&g21X8dB~{iZbx@S)lG__7Nwg4mPtO_U>4)*SLkjI* zRL|X+7kFGDlZ0g>o4;;-Ub-Wg$^|ZF8$Bn4g1XT_K`e0}ywz7USg99rNACU#;d-nW zJ;;3NHk5PDZ=0^A!fe#4q+nE0HPbI>knHF+o@C#vu-IX@B;=lchHE>gi$g)Rv7ddNwYHrg-fYuE*P0V%o6el(+2L@9h##3N#e=8OHq|k$Rqq|`SLc3YVH}=k_z-F zW+~YT-EbmIr#h*9D{q%@BM_3%w^L&5P3PZ12_?1;Ni*U62D%b%WrJvG<3!nlm~ltrS0+Ew~CiapG!uEKJAs}JaXYei#UDRy&GC_SZWi_s-umBTLQcAWpD>y znl#_3&i}=!p$=ULZXTlR(7io+i1Dcq^E|*HiCT zC2xzhdza#JD`4Q$*e~=={eRdd#qe}!Av7#kB2c(5A1K}V6e%B~mMkyt^=6Lr(1y+# zI3SC@ipHmpm9=nVaO*KuZjC{RhAvw#w=BGp6yPOurVhRbj(q+yVZjVymkcBcGM6_< z3siu<#qlNG>cFXqZ|4k@T~4eD^9%G0kS5K#x1zr74)Vo9SZnn+UlPn#-JO}+E&T$g zVdTrur{K@Mrt|v4a&JIkhD8d7?*!K{eZ!*O16-rXPo`Gq$~n?Wc)Fh(u7`d%L)n@Q zU9|5PMwKZ?1fJCX^bxb+%3(SMZG!`x+egOs(My*+)`POY9JHH#uBaq}FJPFHP8)DW z2f;uHQK=|(M6tJjx)v4X7kI_uT#1;P;c2Puz0yFOk(0wF7SC9-&5J>PQA8DQE=v;? zfi=%G!0auee;YQ3aQ4Oa*a^Z`VSJCoIMH@$Jj5jt>47wL__a*YkuAtt8lr)UnmtMT zp`_vGUzjHAE5i@%^;Ep<_&U=!gXQ+53A}KG7f{71%IT+Yrbiowy0jbUd!C6n)n`S# zW8!@t7IBV8dcX7R&L!C$maRwnxR&z}+!6*$cIPFAE<(zn6ct;@gEPR*W-kLNC_mTN zg1vms;-SWj@7D{?^wf|B>#gd|==R_ICTvT28$K#R>1pN_6l<`ln}Hl~~7%a4ed z><}m2#q)n9C!P@RYq^BKP$0SzH8|>!HL$r93{kIJz?2tG4A=_dc1}H!S%I4_7^@@O zO9>F+BQ9U2XtUAq{j46~)bchDzHuRo9M^k3&SzEF-uPB91D5zdPf0#4h5qFmzzzH9fBsR|0`98+Q?NF2?*F-GRS&fi4A#j##b*7Qr|Ls` z9pmCzUrsf8Q-LhUN8NmAct#ab$ut>Ys8dbDUit>(KNW`2595gP!d6aq$gK2le<*I7 zA{~&*s5r&~ybnfMj&GsPBdb;)1?p`~fKYXKE9EG?)}g4VFtpUTG(xt9U^MMb-EI7+ z1DG305fP!H2dXmEg){sE`$)RJPM?9k)AeFj*yB??cZ0lc=(6IjE$;jutK$V2Ma5|_ zG-XzSUryNryl*cuw1#Zlh~Bt4?M2x+)WNZ3bqact-p(2pD(|zcFs%t6#F>{ES2RJA zFDFR%C?4azi9jlC$$$?~P2d(g@j_-gw=c92)o+lS$Pb%$yxa702 z+%+SL^P$-C-(Sd`ZdF2!nqv*z?o@snb8HDu)!DTz5Tm=-Un`@HoyG_8o7^Mx;}WAg z!_q~D?QOmIhsG1D*RV>YCluwsv<1?%hVbf?-B-4aaHG3~Hz-D)KAHB$)4z7v%y?_e zzuvhrIM|G09IO}!zuV7VFV}{%o*_Ib+XS}jL+it)2G?rz0+8+EmA&hl2SiYG;TwLG zX@cKI`)6+*`17fI?B_4Tc{)yD11qT?(XU-m_WsdQG4>K3xBhKULU2pHPe!c>YS=BQE0~6$6yWt~ z-3Ja?Zy{{fQG=QXTOaoGsxe&CjBCg|9Ub|LWI&QmAtg6&lSL%`x;=LuvRDh4K?$R& zt0~sNoyo46rbV%C8O1yin?=ay3AR(ra?f~_{^oinENeU`sA8oL4hFdwX`keRr_)dW z_#RS6!}mQ#FGBR>h9U;72)*+37qV9!l_)nlHdJhFlkt&Lj;)Zo`5sRQ<^UPRc z{DGHi`S!WO=6l4;4L7!Jb0BJ-A-WE=UpLfh$857dpXYDzISi-o@|N~KKHk`8wfn7! z{gfP$m(&-2BGaU7SNu+K3+wA9s*|Jn)QEl}YJ|G9RP2%FoAoRtM*K19WRkUW#H}m9eY^Cox_*_*o;9z^A`C?OGw3j>WSNi$!_wu)O>Obn>PYa0ub0$x_)P7!sY1LK!;ej-SC(%UlviAPaAcyQI=jwBhAMw_&EK6etu2B zuTftUV_cdHwg058BAQb+fCip6qGu;xex;%BNZ#X9-SAR^s<+68x*FVIKA>8-6S`v~ zQf2+ob7G+2jvZ~rpKzPL{Cr`4(-btX%Jj`F z1v0*#f62ec*e`!))VHuis9xw12t0Zhg9b%~HfAo{W0&J&RR&cE!x5dtYFF)|#q}n= z9E0DduXkm-ZQY`00u%ZBc1) zD+#+lb4X&AY$y}%wCED}I1Wj}lF`(ckA6=F-9BNebZh4O8HjlYFC(q10KI0#YOI|Z zup7G-FTc!=mIkrgpS5O)yhSX0m$<83*v&ZNNc{M|Xlo+KtN*rJcilIaVrmZ~->^h> znmn&!mULTw;cVZ|(07P=i`@PBC6^E#Y2zFEhth++-Q4iCK~ow_?+ZXRS8;&lZzfmw zJg!KG^5p=TRVjK96_%Aj>wJzhVAMumuj(8OPPH$D9QoBcHQ# zkXoW9Zj%pv0Tjj40`vSk?ZDkl0~NHc>zVKLMPYh7_(gZfvFWw5x9c`u#0-*VHq$n= z2Lbc#WT=}{0Al%Qb3qO3Hvm>p8ax-4c*Pb z>MhV7a}Y-=*U~4z;UcqsgSaFV`a{M5{aL4)P<>Uc+ zkG!;bhw?*)iDuSlM-dI?Fy-?^Q|mVm`p0mXBMh+x*%whU@$Dl;2Qk#KI|Yj-AvBLH zaTZ&QKTk3BYzuHdK-@C2t2~;kkOTZMnznIw`LYX5v!qT{sfsvhG&su}(Qih~d~Af3 zXf?&tokmsDy-RoJcJ1kIEPp#(A26>@Ir$d;0xwSqa~l7;M82Hb-7k$5aVw~sM6?>z z0=S{ZLnGpNGe++6ykbE~Otto>^413hdo9C1=*zhq{pY8msUKYY`%pBg?fD6r|FcxDm?#peg99Tb8h}W%aPX3L-B*; z;UvyT1`|omF@KRu{PVy6I?nQ6s^-tHz?Je(a-H9-)|EiwLI0nY5dRdLEHb?zzU02u zO>FWKP{QA5$Dc7QZjAv!TnBp8>CAw}Fhi6`PH%XVcM8m@tZuU!FOKJYorR>|AETb) z`%*X)PE=#4;{j-o)3>dk?Pr76{pO{g^Z^|Ib9w}i#I$CQfL4Z?!ruJzEW}!fP|~lT zsLSAYRnJ_>*;Vaj&y!yr{Gs&5p>$(z--H=(^|*xW2`04!ubQQ0c+a&OX~|LLUYe=u zD;W!YNkp3QhS)h`m4Kbv1c1+8=$LftK2LT&D(Yz~o-9kE(301@xjDYWz{>1BV-?dD zCIPws4)OIHGDEU&|1=E;T-;6oO6x*se{wEX|G8^Di65){F@DT&W+U@h5MwmdG;vhS z5hG)p@7~7;rOqNHvhbwduR!rB!8LD2B;xez#&zWsYjKj4+4c$#o+_H>W4N{BG7Hd~ zSWawVd&`(7YZ*cMHrz0M!K-c!pIhs67lAB=zSTna_9x)4(QlS3KbG(O6aeT!`BAuB zz)>gLbk`)E?A33&+&=NKrp-teIBbvIwELU=w{wenzLaf0_{GG;OP@L70;Y}fscoDb z(3jL34U4Yrr`XGuQoB6BOB->HvReEtrw>R+S5WNx!*D)R=+Q+R&bJ!jC_j`~58d5& zMd;7H9K%YktG5>$A&XOAoB`d&qd@c>+!C=}HFJU7t9jel5qFGzL19S;^vScZ6Fj++ zldl0;vh`Wy8Af8c@7jrm-_wUtF^mFI6{ib-xF{cv>ccO9Cq7olWxkO5_XlNs5KMI8{-XHT)l6JYLM! z1I}+mpqyd?IDB%>@gk#tin9&+OU27?`ha>|i2t)Jr9J`dqpee@xLH!IZ>(>%1OGE( z*1&gksdVj)-fEu>pBp*U(iaQT3ijD!C$Gs$eifJ2>x+q};Xi5VedX)V$hV4wif{|g z^~$7;8|@84$ryf(nuO<X2JfE9e)@w+c@wHM$Sa0ndWb&Qcde*BR=z;xv#3I;vxeF!vHpvqkRP_g42YXt1JFNd+?< zN6Qn!Qmkd;@mxIC<@;~8;(h1U_m!TxfR+VG04kFFECc7w`T957qy}G5GU_5uIt^!v zJWs);{-SRCCY;ju4!!H)XZhwMJ%_@sj{6$tS-Uv9ySdG5er9-fSuIWSUL|p0?i_uEcZUI_3;v%`e_}R4D3;5)$ zl(5Wa*8O>ER)zlX13IB|v^cmPR33%+qw{g@e{0$mw)6DCARwoSm zL_GKyIruek<>LYBwsEg<$swDQ^yb5_F6{I;=&JylmcZs{YPY)IA*v2$-jUI$XCQBX#J^c*_ z=-I07BZlP5vk{ffenyw9 zj=j8{rPA-XwQ}nv?Q5`k-NczBUN(GWocyiq=G;gyj_YHLe#^_->~D3(WdS&XmVm$Y z6#1<*2F}R7WVjO0iFgAt@u*0Tymx;y*8fHC=ej=gTh{YrdygEnxRM_1Zc4+yjjikS z1U5Ohi+d;65kD44{Yx-Yic82uX+~qC0&>N?feEz`Xvrgw+3QGgd41if?u0&7`KmTt zr+?u52PO4O==)o3S0{eBF_4Jjc-AtuOYm*&_nD*a;>13kYRn?Cgnyo+7T6d@)gLlc z5}%CfcRwJlBD}E)zTa0~RDQE7c#APTV4d-bfX?Yf%wqel{cEoJ)Vr4`!kCC-@`PPd z(yR67^OD|?EC}*>!t1)k zEU&iq@3yz8pL6g!DSS{L8H7GrUDnge_mKo3oSZ{AG@Ju=cpDhs8KKciQX(QLTOSYe zG%;8+CLGe===C<*p)KH`A8%S*wwi1>j_M0TPIKQ+f=cZ*uNK{M>l?+zesu`p3frGQ}eaFTgLYc5r!Qc-i-0w%! z6TTvBL*n~&e>gQk?$Fk+yhYSn9PmS`1tCzJ>cmTW`k&>;;YB!$~gIM}7RW zD`a`>O_!f>A3DFJB=?2wrKQk!H7YHBneh7sYkTYlpGnl?P&RBV?-I@bj7m%T6jdi;S|K*J;$?swXS_CUZAn{Z|Y z|BtzRfO$L~8RUNEA%}u!_`fB8vG5f{5x*>SD*i1#xp&^{Cy&RDX_5L((yxS zU&ep4^d2w$$Fl$X^8a`J{LkI`e>XfdY@YNl<3z)M9eDaL{rdmC@fvE_cd#VTVlzcV zAV#tA&C^&kvKKK1XWe)PsE9h2A63@>p|r3{eiX#cF_q+=9I;E}6i?H`ZRF(9z5XvR zX?ob}U1kiRj8;A#Bfjhuj1bcpqTTqXa-$KEO^9zf1T z&ns9UTW0d`%EeO!!@p$oT z;{P{afJN9He1k*66XGRJ-Q#h7*N$DVZ9$++P{`2~arl8uvgB`mpt=xocRy!6)b}O0 zFclxoDEtWc$7}D(I&NJSVy$t>W;gwe3q_LzlMEjH!E2Ue24WG?)DgsY%Jn~Ik^i;E z{`(Zl@c*K;@i{a;X=W*zhE#6;X~UwG2S^NiMg%mf>-$6L>9PN#y)O@I>e|a2Pp<<P{-VdnJL{0-LpW^I>4Rqh$;KNll3${ADBpXQ_#j7F5UsjFse@V?$7*9?d>Gkr$#!E}$UxjXe<&DccTW z(m=f2A&I5H*s9zo{;68P|J}rc zT}261tV0F`J5xA{!Fy-6+ct|1f&xKCDSdn~=t8R9^ts0GzLmd+`uOkq`-j5j56~tX z>GPd5C1f7o{~KSWj%QP_owF&CQp%PuWRFQ?@u$CaNag!CfO=Pgl0 z$^b}lZZNB$j&&u#JyjCPQX1(uTk2>0gg>(UzIFoTwl`Qq7PwzOp}r9?Wg!y45`_gc z)gL9Kphd|bNs8MHSKTB(kqW%$=-3+tXZhCHO<`zTsd>GXED}Vm$1)N^ON+(F} z@VMF(z@wYq_cf49wNeRYi_q@6uWOo(r*mpsVa~>AGBJfQAx}={?z&*#x&E7Vs;9R0 zdi*A&MCy{Nxo^v3ts;3ZK8V$(wp=owMCr;#!fdRa$!40g(CTlU*nhOWroR7mW6f@{ z|LJ!A>us?v+>Oz;3k)vhron*BgaaTyMr?o7ZZdU#_u}G_eIWP7we&LZ%P4cOxjnfu- zZu+JlPl)iTZ0;WKm2+=ddTKoQqmB7*-;}oGB|;5ept)9jGlN}yj8{MK;7Xe&v#LG# z2|}z<@U`?r3m#{{J&sI>Ux-H_tZcI$RkCV~AsqtIRZ5KlZuW@T^_blsvv0$!bojrL zh10^MhSLRd!5WjH#AGQ)MSGyGmZKE&_9smI|q0i3=a z>jKWi9(Va+Ct3iqt{0yEe!S`bDOW_I2*&F}J$T{BZU+$9u(2fVHjIGRBPx z0{S_4ig^-hJ*!NL{|K41K_2HheRnN%%9tgnu;=%+?2P zPothD7>CNQI^6+%8@0fpUEzH$y_9K8&#aRhEvu_NGpmCWAC z?5fP}mDx9FR<6uS+y5OMM7{4~5)oD2D3^CVZZFQA8k=@6Dl zV*jZk+JAL&|F4+mn1jVPo~%czmOR34XnFv(bg+=jAuFAUNz_x9QTSWYb;Mr{*b|^U zmOHip^z3Qr2EYTr5CIf0-bQoYfU><051Dz!l@3;G9-CT5Syg#ov0cGz-Y0q4E#*hE@VnzHibk4+8(8P1I{-=63lMzDpNTo;i zp`Hn!l1d%zFGi~88ERzSeGKBpb=)G z1K|P0R;C_!7Fa1&!;Qz|+I>9~?t+YCk4ghG#*IE~C9^@0ERZo8+BlcY`ck-|Jo_tV zlm!Kp>2D^NZ>RuqvbiH+@kp^yRldLoSg)19!0mtd@bV7U0D3v-_?a?Bk5GZNI(=C1 z$;P=c)6eReKJ2RqHTQf7Xr{*AWN|c{ZECyC+HMdaaZ}1jUYrVhJ z=MSGw7Dih%T*{`D4tkbFMaIaf>^6+wK3=8G@WNx1*M9yzxA!G&_Vwp}JpC4C-VyU^ zk-a;YwaE2S7v=7_#dojNd(0bKbR*Y$;N%PK%5CFZF9eo((wnEel>0BHZ1;RfBuCE} zd)eAvnfWS>IWhLtE7BK>Awgmg*tyadoh03J!vzv2T^JX#!xsvGiYp~ewuem zw@{^Vl&qTTXaBOG;OZ-1O-1~AlOK>Fqu$ZXLi0^h3xdK=PFowytsfB7OH84lT#N1r z+sC!{^NIko-Nc*VZiwS5QT+)&kAOScl&fJ_42W#J(JS;4Gkx9Ti|4;cM)So(!BVgW zd6v*+Ov|ucJ{LqbuF|%PQrYl4*&ZSGy3Fj9AZns~#gRS-SybbTE03_xKlUo{8`h1D zW*vjY$DW%;Rf+18MR6V2fh&SooDw0koOzJ6uPKLMZuyAd|6-!XF9vw^yMmKVaXQqs zBk``Z?USgkB!PW1O+_>p^zyVTHyCLsf}5)uwfHux!ANdqb+zsd|H5f_%k~;AUeX&q z$FD^`5Bh0K!b^Qxb#D3Iul`#rEzVeRu(8C-Xg} zXq_!Ab$$sQGh8Z~C;`yl-qcXzP{=k5VY2R*#OhJYO-zqy?r}Q4)rm20g_X2=SoiM8 zzOZM250=mPjs z*1Bn`2@Im+W#$3HYsl3)R}vlGR-7_RWLSK>sH-qhnV)3#sXLFq04_Gv5uN8$8uOJ% zyK-yBDmB{1G)&m^Yw3oHbe4SBRod4_WaHkMo4jz+7jcC|4*#aPDNQ?1zzZo_9`Dkd zAW!0KM%GYpF{3>^V(;d->{yF0b{MpA;Vm}Q!j@q;E%T&EL%`AS81EFda2U(noU{V% z1+NH~TnBUfE=rgPL4UYV}t9@l36OAt|Q?{Ugv< zT}dxZBp2iEQBIQdr24Y6Lfz|-8$RID_#Km=%_JqE=T}XJD@tue*P!6z&sr9H{xs}R z;CspI76_;qN@Z%_Z$y8Vz#?cfUB;>!gis(zLFsj)d7yz%j0K^g@w~DaRhPzHP6f^Z7B#uXjiqo}xih z?DMT0?O2060oq?*c2v)olAdwhE$TXbLMD$r39C_kIuP1=W-DfnNSE!Wz)`qHKW=8> zd9=~U#;7-Tb6yyKuW+$Mzsxi41%ho&ciN#m1XXt1KM_^n8!$`A&88P~IgI6m)G|#) z;nKW>9-3;jr7&Ljw#Tz*`HP5xn|Ghjud`am;vsSbrhc25P_$dRO=c#<1)QuI!v!Ks z8gg9u)PqFz7_}y%ufaXp$beT%H=H-oYs7B>q_MZSKbr4%?LaSZ5XH9bU)S_q?HT*8 zLzi#U<&XPPJv(0zRN~2)ZzF&5G3GgB%EDk}n4SjrNJB;)M$+vOD=3)GYJx`n%D>dS z{`Zud!V9|K>m{yaW7!2j$emAG#GwacRB8uwh3F8kbX2qW#)x)A!6mEl)E|{k-5n1W zg_ETO;gQ9##u#HYQbGTSw3Ty|ScWWOjzYoPoaP8`R02TJ<8HBg&NI5i;h>FEJ93#{ z1g;HOGWr;~-)CG(3tS$>Dz_k(wX2C9JR)e?`08^Dp4Q8ZN_1+*w3IyUTH*{SB`0_60%`PN?%Riu!#{JW?;+Y_iN(Sst<4TrR9u^8jSc zWovD*Z4~))v|JBpokdcH1i>R;3h}{ol`(+PNnZfF@Rz!vmlxsE2p+|%1@kW9g1VbJ zpV8|z#|fCX-x)9F!}>~+O6?J?k^X}ft^NcBdr>WrETx!jLRAV$^}HZ(KXWMj5c4?m ztdaFQtF}|KalL+=Dl%`S(-}Dcmn>79<_` zWG}#S*W6zpxj9`zQd-g7Ap?WXJqw4;=x>H(_o9Z| zJjbzlLWMHwB8I2${T7*-2u{YP^=K}yE7~3be@DByW5tekkF86ChRuU+6{8sq&xyCR zgy|a$+^fX&Oy=;`8@|5BKu;XmIr(8oSV{hw-3S&G>J_h|OSTLZM0MpViP50+YTi^o zQ&j;<>^Yro1bZ1X1nlEup;O6dT~PaJKW+l54r90s$#5Ng^n~1R?&j2$#ONVrH9ebk zkE|{;y-+98ldOO836U_A zBhAF1&E!X@06hV?qG!i+$0vg5JxXyPp;?DRK05&az6it0pK}Z)b3uop$S53ObMK!q zwxzZlgll#I0gFS{QwCD#J?lVgDhWjRmVdq+AZHS;BbOx*vIMjva#zCBhAO(_wye=* zQxaSmXwf+7Cmxc8PB3c`z#jX09{iRz6_vq&sEofABq~SG7+cBjn8@b=eenI1^haJr zBUe?a6D6>40zf2|Dv;PpE29%<9{++Ctw^?OA}mN0j6dguxfKYQO7ItiamSn z5Bi2VX(Pm>3El{(*d8@~{`*U|k9A0>pPQ{6VQSHED~a)0gSP+cNz`RuLpvz12!wt= z_XDBd1!1r-B>cn2w13(!{tX)BgAgKmDuftMm3>EVXF%_)+@7euZ zX8S10J5*fIV62ZFK)gE_{cZPIDK}L4H3Es$8$s9ihws!kL!$*xNu z)4Q%=H-cE4Ha=?FZ}sfiBr3zzD_9G__?Qm5i2hW&!vC}Y_W$JgG_)e&JM=1oTZJtx zzfqIB|BAu*?quA&^L+96daVRk(3bzC9_Bp-tLRV6L<}zL*M0-B5BJhX-h!BK@pBLv zQpL*jEKCrhJ6dD{a4|SNe``}Yh^WLy1Lq)@B2#aJgUMFmC7w)h$R5YLS=f-Ba%IM67{w~voye^)>EW}4^xD|-dD5%T__ZL ze}vA4!%hK_Sms&<@fxOZ6C`sU(y4rrD*(kD{RRWPced*zSl9=#6A)dv)>f1WI8PE& zK!_Lsm7fB|)EEIXz@IvkM(6(dtM7k*anQ)NJasdO`hpv(#Puu)L16knx>P`< zC}t96d5}X#Rz)QN8oW3;Tmk|crHGat2yA1(pTej$OH^c&sDCii{QyPIP-upPB$dN5 zePbMAft7%HAXb60FVdbMemKw^0^L{B6C)rv@tZ3lYIu&1Tm=^bRJ?;5Rd$IoCRLP$ zgJ9j^Q!)t^*$aPeWIqBz*E6pnGoqLAC7)1LfYi=ughXTL{&7{Y4qB*|%@B`4vfIez zoz=gv29ZI5RWZN~aARo@m|R+Z2c%30KO(fFm;~~g22V8dVl=JK7X&mLz*(#SMexu|;%tMY%MFSmI-MDQC-0E?TL$)BTbyBowag zq57G~MV(S1U6QZo=GisTVTmJ&spFoiCith65Zcnr8!{^)k?lvj#p?@qXW~7=cQ@=u zY$EZ++81Dk1r-=niMN=|)F*ktxf=KqhltQLC#&RsO{GTN+OwHx`3cT?thO>;ZWOkt z!v`E2-CqhhTPrD%UsJR1DIax_R9qcA9!o5Y7b->Sq?{YJ8upD==7r&IY2gfkQDApx z2zmlv8`C!|mPBNwwNxhdYku0O+mw;UlAnk&#m)m-b+m5#$5RGGV(f`CA=GV&t37K# zu!d{;AA|7mK_B!-0ErGKbIeqN-{Y8kzV}@k6rhXfGXv@G`~L55IQw(^my?MQ9rT8LP$Sj5yd8L~1RS5JFWK9+g zHfZA6Hh!CPb3|To3%NuoM{CFcfRp>)`dr2uf<3mOXy@bJi_F%dRTF9flPGb=O))S| zn5BRTN8x+#%**KldO09FQWJ5@TCGHQXLjL+T){g@E-%3FenAW`fVi=i7sv?hkasi0 zKFwoF74*wdlZ|wz{5kcpWXPqU1V=`Se~VD&CY_ zjal4?(EwSY)oEi(%<#x-roNYY_0~iAx#0tnt2>=F(x~)Fls!)zjAVifX!xmq`5G8I zOaAtltOLKy10dn2;n7F!d8rDVQ?l#l0jSOw6@cO?y=QJWU9`DE78h56ACo_XdpRX^ zHTQ8xMDbIYdsNdDWR(YjcZFM}BC5xSpC5nLY&b-HjTpl(n*f3Dc(3M_4s=Uu8N33s zf)M`V(z$G;O3+T~Iq^gM1Od#mGxLjKu9yX#*HZ-1-i0K4p;{A%TiUKFT#&aU|E+cb zIoi1492MJ4-Qc%@ok@Y0AancSB_!zl(%kgSYiX+i=dRrow^o~h)*FN(?EbTePXwh? zKFUFDH*bhQe{>ck!CL4}wMDvI>XP0cT<9xe(sF%^ESKC+J?D4(wAYVN1h48ddgNH9 zTH@iIRTJuAWj5)grd@n5O7)G#I zDV0pS(U7Z-4;7MYRh^WXIiVQ!#F~RrhimpwA6%8%D z^clGIP^}->#|{{HPWaLXTZr$9=+g7UIRJxlr)C}|s#Wu8)U}wrw@EofU8!Y}nThxf z^N*v?0+tF%IPEKy23ki-y5S>rrlV^qH;p#5n| zqC$>EOj)~zATQYXr9S13Ua#adbAO2+`a9AcC4cfN0+q8M$`-9I7+WsDnBH z{AN?qP56W!BjBQHRXU;cr)>q@RMlwD2e6w_)NS-AqZ6kKG@dhA(uXl6eOH&`A=+qD z5vqUoTc%OEN!coUhH(yZ>8Lgad$)@&l)ri-;tBRL4+>#mNW_Uoe!BD~F!@Mz>f5>L zrJ4z*Um~X>#wk*M4v^pP(wfvLhM*ctRbD732OO*t(B3ZV-AxT64?y{R;tPcr)RwxD z5_FDEZimOB7El!sZqs}$MDbJ<$Vi-D8%7GE4l=cpWS zW)$r_ZGubOeat-aJO!_NQu4CNOP#UQUAfuK&S#ZLlSdchjOW~n4TWHywf+52AaJ!V zlT^}WM+7(h(+EC?{M@Bm{I>DR)MQOfk-=!b!I>8i6ieyO^r5$xv}19(1l*uKw~!x% zR!uBySTA^OV)xXp$+w2zKHg*-veLG?s!&{a+RTIxk9n7e79Wh;WxRs{ZK-@LI<1>` za6&vqy4Z(*FvJqL3NtjIKpg;7T(kDM76JPt#Sjc=^YD&@sAr)6X25hVM~H;`Mk? z^G!oN4wf>B>aVf}DGz>s&nuMP9np2cZs16$04OC-tDElqMlJ5}V!o^IS?ar+1kD}F z2x9+@CF-2!3i)00H64TGC3Y;EqJ~^YV9ggb8C$12a2Uuli~7nZK*Pe8D~bEg{i)i_ znLtc`fw7+KGe~&0$l_-x!#R2v^7ZfwtrL>&97}g!wXINaOZS#GP^&E04OVjh6u71` z4Q5@(BcFY)VWUz7f7^#2-Qtd(-~itq#6bTO5BOHL7bL4Mu#l2fkmQ^Bwn%XUz2|rn z#4pbT5jWuPvX>L1pXtyVy=|-q_|Mlxzq|<+OE7OQO8gd4)TN4i@He+kqM#@pNZ{d& z56zV?Bz-HwJ(QghokYGD#=s|A@ryG0PhI8ewc z3CXmvbBjaoCw8w|+ux|G6XC6Q(UsShn^Xc%nl@I&?DLUr*JD%UN>mlPz!1E$ou5GL zV*FyLhd2dpdL_ypV2K?_Dc*69H>gvY!ZuvqNX@wiG}sk%gpvKvXTx$O7@WNoJlLPl z221|o=?AB#juGf0>z4YqqeaWb&X(_IMNYAbB!{QUGHZ_M*`_!R%-x)^324togVPoZ0i*yjkHiA#uD~z~?`fb9ST?|;>_ldN0!!xm z4rZDPsLgz25w`=~{Lt^fMCn%dOBqj6_xu2A$DY^O?6`tCuXcJ*s4|kDK+OI78FKWx zD&Cdil55Tr8H+0QPOP#0^bqxi*pSV8*F+yMPKJArH`vmb4nnoL9zR327^@6Y4|z|b zvKL!93$-fLsZ}GJbLjFlu#;T=KuI=E0dn(YD?e~uqlaZ3Bc+*fE@g43bMiaKvxgA= zyYuz0J>ERSEq9Hy<90HO4$&vjz$fS4o->g&{yj9(3Q5J-Uq0YtO!oIdqgx48lc zS;&rWik@SU0FN~=dp8m25SO{5uyhw%JcyRd;(qy%`9{fbKcHofet{Q#-3~g(TFqxq znq7!#JEBc^HpbVTeYg91nbW5?apB$gWlkV^h!oT)^r-%_`~G_yMyyhc$TtXO`>Mat zG;Je30R_(?VH3cr$Nm639Gt@_b=4uK=6;&$O~Vz0a=VEGgp=TifC(P{$-A|1+E^(3 z2}-^IsR=};P-5VXzkbr|U=3WSNR$XbqAN^LWfv&ZhnF$KzaBe#*6eD0xK(CXV|F!W z<;Ijeot2`qIz@J2RvymE!&!OwFO-Mz*Rju_5e?xfM2QcH1_9#hFYcYKiT&5|n>ZGB z0;1zr^^(h3qrS+f^>21y6l|LvgOrgN?Yu1WgpibE{obYce3Tb08n5)oB#j- literal 0 HcmV?d00001 diff --git a/examples/platform/nxp/rt/rt1060/factory_data/source/AppFactoryDataExample.cpp b/examples/platform/nxp/rt/rt1060/factory_data/source/AppFactoryDataExample.cpp new file mode 100644 index 00000000000000..a37ff1b5c47feb --- /dev/null +++ b/examples/platform/nxp/rt/rt1060/factory_data/source/AppFactoryDataExample.cpp @@ -0,0 +1,77 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "AppFactoryData.h" + +#include +#include +#include + +#if CONFIG_CHIP_PLAT_LOAD_REAL_FACTORY_DATA +#include "FactoryDataProvider.h" +/* + * Test key used to encrypt factory data before storing it to the flash. + * The software key should be used only during development stage. + * For production usage, it is recommended to use the OTP key which needs to be fused in the RT1060 SW_GP2. + */ +static const uint8_t aes128TestKey[] + __attribute__((aligned)) = { 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c }; +#else +#include +#endif + +using namespace chip; +using namespace ::chip::Credentials; +using namespace ::chip::DeviceLayer; + +/** + * Allows to register Matter factory data before initializing the Matter stack + * Load factory data from the flash to the RAM. + * Needs to be done before starting other Matter modules to avoid concurrent access issues with DCP hardware module. + * + * This example demonstrates the usage of the ecb with a software key, to use other encryption mode, + * or to use hardware keys, check available methodes from the FactoryDataProviderImpl class. + */ +CHIP_ERROR NXP::App::AppFactoryData_PreMatterStackInit(void) +{ +#if CONFIG_CHIP_PLAT_LOAD_REAL_FACTORY_DATA + + FactoryDataPrvdImpl().SetEncryptionMode(FactoryDataProvider::encrypt_ecb); + FactoryDataPrvdImpl().SetAes128Key(&aes128TestKey[0]); + + return FactoryDataPrvdImpl().Init(); +#else + return CHIP_NO_ERROR; +#endif +} + +/** + * Allows to register Matter factory data after initializing the Matter stack + */ +CHIP_ERROR NXP::App::AppFactoryData_PostMatterStackInit(void) +{ +#if CONFIG_CHIP_PLAT_LOAD_REAL_FACTORY_DATA + SetDeviceInstanceInfoProvider(&FactoryDataPrvd()); + SetDeviceAttestationCredentialsProvider(&FactoryDataPrvd()); + SetCommissionableDataProvider(&FactoryDataPrvd()); +#else + // Initialize device attestation with example one (only for debug purpose) + SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider()); +#endif + return CHIP_NO_ERROR; +} diff --git a/examples/platform/nxp/rt/rt1170/BUILD.gn b/examples/platform/nxp/rt/rt1170/BUILD.gn new file mode 100644 index 00000000000000..6585e31750db6c --- /dev/null +++ b/examples/platform/nxp/rt/rt1170/BUILD.gn @@ -0,0 +1,24 @@ +# Copyright (c) 2020-2022 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/chip.gni") +import("//build_overrides/nxp_sdk.gni") + +config("chip_app_project_config") { + include_dirs = [ + "app/project_include", + "../../common/util/include", + "../../common/mbedtls", + ] +} diff --git a/examples/platform/nxp/rt/rt1170/doc/images/IMX-RT1170-EVK-TOP.jpg b/examples/platform/nxp/rt/rt1170/doc/images/IMX-RT1170-EVK-TOP.jpg new file mode 100644 index 0000000000000000000000000000000000000000..a5dc1619edca9f9ea79b38497e3229da517c9529 GIT binary patch literal 438253 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 o7^#-Q}GkSW#wy9c3f2 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 ylh1i@@y^6?@I-I%zZWYD-86y8#QTFKV_+{S_ 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 Jm5(gL{slxe9j*WX literal 0 HcmV?d00001 diff --git a/examples/platform/nxp/rt/rt1170/doc/images/flash_driver.png b/examples/platform/nxp/rt/rt1170/doc/images/flash_driver.png new file mode 100644 index 0000000000000000000000000000000000000000..610acab9043f3716734d267981330f2d2b2ae7b5 GIT binary patch literal 180088 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 z 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 HSDF9WtdV#M literal 0 HcmV?d00001 diff --git a/examples/platform/nxp/rt/rt1170/doc/images/mcu-set.png b/examples/platform/nxp/rt/rt1170/doc/images/mcu-set.png new file mode 100644 index 0000000000000000000000000000000000000000..27bc4d910a3653150b769b78a8c6225a5a5c4674 GIT binary patch literal 158274 zcmeFYRa9Ne5-tpZ06~MhTLgD^*Wm83aCe8`Zow@fNC@uk?(XivW#O{8YwvwF+2_hX z{_}7j?ii;ZV9nXxHLJg_uK9IU&#+H&;z;m#@DLCXNRkpFiVzSm5)cqj%WyE@JMiM{ z!{C1r9?I%YiUzJEb`G`xb1M@PCwDs&5)(Ib00e~FqDu4vQkMXn$a5hXr5&v}=R|MP zvi}f!lO^T(0}f0ej6Qb^p)QorYipt;fV!E*MU%|B(A%&$F}zS zlac({#L1GEOkMU9iLkAM2?+}w3mpTksGGS96B!>o36Fy@fJ;$C>|Y|lSG;6qPEK}Q z^z^Q-u5_-QwMU$uXT;*zvBFf~y#H+C}nN59`S z5+>%RX5g{>TOWA`a}zKMe~cI0iH!aaEb0FRCU|b>Unb`dg#PcB|32hD!uY>%{THtP z2!a2o@qexBzi|CW2>eHl|7%_UZ@~rso8Fn&fH|Ejn7mc_8-4{7KWIlGNo6>2@q#lB zg@7P|kQ5PAc3V7JadpC+0fEkMGU6R4B_;eZJl?#C9VcZGgnVz<5jt)Cf{HH+De7_B0xJafRtRsuVE8l!BAkM>Lqs5JPLrl9BbC?ldN|B-q-&M9 zi$xYat}XTQ(n&~InDs5$OW7;W$swz(s!C-tftQq&oVQ{-a^ZGqB8&(Y7x`UAS>Yvq zUx{pIeE0jurN}7fe^zZ&^ebR<(@>iZ+uYoIdv|y9+>J%^BDqSl1R53=9TPLCYomSN z$>P)RXKc$CF_73dXj?5-hyD6xmd0is9upHICJl1P%gZx1HZC_A!qTj<$or>S79v5? zR^Vz>OiWQHr|M2rPHQhOuh6hC(hncPTRd+p1b)lU6;sBE1#5zaiuw&To>@pl1RBhK z@!(KjN+BvH349OIYXz*U4zEAc);u!>0e;<`tZ+Z1fIt6(2 z_Wp*reVh?!pXt;T`giGHOO_QTQ6x$b2Ig0u^+spt^+7liSLM?de9bV&IH}IY0run5 z^xGL3>Z>2mBQQzmxcW_BLM+}`OU7SWJs!X9lRcH+^`KX`azW(9cp20MyMqlZ1%NKy zCv_mY(Hm#Fv^0OJ9~DM59n-eMA%ApHd~GP_%qn{{CS6H_$ZG28eWAjvh<`W$;s&)df=&p+hp$ZU6- z-3LqG*72pJCj|hxuf>*-rlk4sR2o$~7HbdUhChgv(JF|L{AIS=EjVOZ*WbX8*jd8n_5qMDLvLv{Q*spR0j1Omuz%3QpF0$Vx1KTh1lK> z7n!30+-0%V%|4r_+OdkEs-L`_?n(;Vx*ekmXe8zPvU{X|?O6s~v7vXnxp+btJ6p(E z*>0fWXl_cqzu||(cm=SlV=d0)4JdRZ@6YsvBcn64OV(B$ zep*pV${N%~(Z5B_o_>|Bc@X33%k{uZl?3y2w}(z{er)QeA*CwD2f_kdZ>R6BiJ@k? z!^r%(_S!J)>1x^Q;hY?dS?l4g@XdW0UA<6q=*gXITj2Ir31oV&AkVB+Nqg2( z$-iCFw$tFifWb%_D+Lu*rPKao)dk)K5GW}nW!Mvr>GW$H(%1Kyxv>olEyU%?N;<7p zZES4pr=q=w2f7NA-S|fCio>#g}dH$K$BFiGLt z=W^}QZVda};0X83dGgCi(Irt}Dvc)4kg`@u4e!>^AdG@(+>b1wvr{NsQHf(6^2q-3 z7f~2eK&)Jg#N~5pYDkfXtOvB{zs9+JIWRg3_+yxql&ENEpUtx}rL$7`2a2W&;(d(xxVE(JCK(P!bfuAZ@qFIVDRzW#)Z`e1Uq~nl7QI!#tNQ z6>#==Qy>fb`3FZlEaF$AFTmTmp?rkoCF$856n7g`zo1{h)AioKW3T(`SDhhiL$SRo z`!~Yc3yZpU?jv5cBU!!8QJ($%bluhn6gKN4h|-9UT^~;mYLCC#O}Wb40*Fh*mxbD3 z_|`f5bH@1e724m5>2B)Tr(YD@b)y&xObvKdmcV5krQzi#)17YU#MDJlTxR~P!344uJ_>tohyu%Yk8sXe9eIMZ3y=EWy9MyOQP zR#{9S^Pu;RKm78kg`v<}j7r%8=&Of?mE66@MK0Lt2U>SHRNoDP_zhI|(sb8zBrr+; zUZ-(wx-KqkMQUaFI!!Ktfq@X~TU%Z7{7+7ut^WT0-90@Dbv7$gvujTeH&yOHKzKxi z{O$0@JI_7!GF@JXBw8)8zG%WXaBv)3y-!)5CkC^{8Z^4iDSKI-(c|Oen*64;Fceq^ zlzKgsVI4R)9G|`IQ;;f3)_P7Jbw!|Y^|9h>snI>H=yPa9X`~iJb=`>R2$hM`KZfXh z+-2GVLSd}gLA4w#`6()zJ|&mU!6xvme}I9(tZ-aq$@k?<;BwU!0iv(c<4>EjM;0}T z=|dhtlHyR#9J^wUTGEqvAF5UgdpZt$g}L>JU_7`_W+q<8Sd2a#3pz)?1srH^+MEQO z4w?^-SoE$Nyn)7R`e3GHv5RUW@Z2Hk#p&~!PY2dfw;oapR4;8y7y1xSco-p>%@eKm zomk)aSv62Id_YR4tE{R@qS5E=NU^zYdmb51O&)fN1U!{n8#sSxbXy#n0M`gs(K#7^r-sibcyS(&pnlpu?8T8U$c1 z9e|4SNP1atWr>-YBR^G&q7lR)?yrxvPCySgr>0xIQI|&xRZ_>c^X2}DAJtSF+EkLB^+O&6)5OtEM*I=#>2b}e;~P{j8xHKQqzN&UQZ+}bMwHnq3m(FF zwFX7=GpRI|ZNX5U{Vj$yU?Q9+4Y|>O_1vUN>HuZX;33^{A%!b;cjVcP6Grv<5BeId z@||5;?%NtQx9wD=BPUtfc#b_wQkqp$1Hb(f?6^gzt4yk5=xMDm3!xY88-EzLL0ct@ zaKZT?`HO5KN}N%FM5$t4U8dY~5V<4^LG3r|(Ba zSnRioi!#srvlvzzzTZo?rJ-cX!ovJ%8~KwdU{%~uT09Fbrk|ATS*>KOLfZhgE%bOlOI_2}Y<7=U7y;V$;)RcnvL`cB75@i}8z{)W^Fd}_DSLxbt zI64q0a$_|8Jz#JRq+g|k$7)#xiD>==by_-LGEqd1drr&`kFv8>fzwB8>00^wwR-n) zXJ@CvVMi)HJ{}Gkxp(V4<1*#!%ucmfU17(OprlYiVcqV7pfH%+CqCe#qWYVs(P&f# zo~$%&IdRELXAd#kEOY33or`|{{27PehX=gysouXYR6V`ZyO*ye1MxBGg7s$Ygn+4k^a6}}GuCaHvXOeHMzuAWs&1XX5qK9_Hh+d# z`CG7oU9p?L`Davt^lx($ZGrfyP z#ho7+?QWR`17<8J>FLV`pTIAg{8%=9&s#U6 zTIIt11tWQ+^p>`s;mmp>3wjT`SR-9%qgJMKYx9TYMtz=Z^f{o)RGzQ)OhSl8zYt%t z-ulf$RdZl<)Yo3D4bG&q#I@6etU1pEBZmu1ruWNi35ADG`_4})^8l~m;=+$+4%XB{ z9|=t3rUs<%tEq9X5(KLN3eXN~}9ps!Y)H)r_&N!{68BM;lt#weomY^UoS|>h zFv$G1=FUnyk~%Vb8}ShrY*jrZ&3)F9`}XO<;PApb0s0-YjtXS?9pC|(!*OHBI z8UsEq!F*{Mz9G^deRu}wRN>bHAI+2vgh9j1saaV*V!jK169AFz;pD8W(aAjN^Ye3q z@vnlWI?n~N>A`(lq@0|ojn0Qz6W-pp8zFx@9Rj#JLe9(EA_h3dz{HFL6NfMFl_aF3 z?hyd7Uxq|SL5Nbriq~`xVKdRAkrHs@GO&M>NK{l#a#2xH`vJ=2jG8C@bfL`dZV~WQ zaW2+c4|Rv3yFXpcSw3a>>IiI(7$0xTr#iMvNp!g&w&YM>mE3<0``fFAhGra=Htgcn zS}h1kNx|DTpTmG5sqqnqt+DZ0ShE#Mx~QVYI&$MFkUHeSH#AQc`g6%Zd$OwMeCA`~@u$k?m!}3iS`j z65#IOU=kiBC;6A8B*U7YW>LQ%HysHN6~Df&&&0&UBIF>}-``Kd!J!UC`nSE4k+J4< z`cZ)6PT&aK)WD`Ly(ZwIZSf*RKBS_I#}p-6Uv$I@=Cxk!sHZz_)r)W#R*g^}I z*74nbO=$hXGMLGXpXvk$CjY6wLr+f+wbjQ#PJuerE4WKnf+d$h$bnqR1PD1&3i|}d zv$rRuF~BKlsB`*}t@c?xci&-tPTyG@A6=GUWBwI^f9O?+Tc1NcRj7^M5 zo7$UJCv4kuM-y(zx@Ts!GA>_PzIVF;ZlQPmTKy2NUw{(59;|(3?y=CC_4LSf&DF?? z+%bnM;8q26b1@hgc%b>m+!Tnea8ZvAmp?6t$$L``oD+Qe2K`CG;M*GvhUW@F?K@Fn zB9CLO)$jqs-IS(=n@L!+>J9JvQ=cgO(^RR;glwjV&UekQwXyhG&k~DD-SN~gjF++j z8%BIvJDf0<$4q057-Z8)tXsUAsDgjMXIG$vZnBJV^1SKrxoDalp`(Oe-)>E=4M}m-Sl8VVszkhOw@bmk z4=F44N+-{oh@<~of$WRri)8uCcqsT5QPOZ5Jc7@c`?( z&1ufBLl&GJ5nJmBcsnDSrazyy@>tES^a}6!4naLFm3!TmEZgsmXfM(c;IFS%er64- z&|YqO-#6H@ls465$|5hXHL7~E13@t`tx&T?K6knNlD_(0tJEa*wUKV$%df= za&kF0Eo}0Vqeok}Dgu(x!6)i*$xIT=H0&4K<-{$U(_)4kINRvL<@0i@iMGGQ?J8D- z-B2t4l3dylksYu&S>^mmBUC?4zi^C|7}Wip&}U5)0rEIkO=OMdz%wrYA*6ZDzatg3EnAv@*Z`n0( ztE19qMqI28)&J#Ad%IVYd3FPwh>Y8{2$(9p&mdjAgAmm=szLde2xwj~B0HHqV|CYl8$# z?^~}R5yYKyZHJI4?pp_%Il0fBtTosox?7?efH#}T^ZrAeE!4 z5_hsU(RC^8rm!caee@M3MN-*2#j2mwrLxoc$SHZTr&#Q{j!l)%YG_#_?6c`Me5csX zww`rlopRyVetUTc5izmxazPrlbi$^U;1!!^N63M~VDdg@xPv=HVjhl&)v=YHbnFpB zvVe8HMjejhMc1S?Zup;I!R zBzu*a60E@H`J-~Lm%*-q*BJYYp)!#33|O(T_v6trP46gYey4+D(#-?F_ap`i;Uw0R zcl(iTll6jw1g9J)Nnxtp_B%Z;UY;y&s;se;5dOV`Q=6}2L(I2yM+RA-U%GU@TqvK7 z%suZSv|V)Ay^xD{(v$V}ItWAFRfLS!cZoLNZ$MEjKs^4sA69O?!SDH%T)NeX7%D^1 z{hhygP&m^&M#p7S_<8HQuq$vHNPbJU6u_Lz7u9%~r;}R~?*lXWkhkxpcSD-xbt*^q zphkLq#u41&z=uuQtGsCXn!>a$nNPhx%V-0xo`pf%lAL4bC2nbs+mDUzA?!4+hH-NA z-oZHUk;mUaL9j?{T+zp&Mv{m=NS=?i#j+(Y>vx{aYtXi#$9A@oaVsaz!^H4s_bbD; zp)UKeJ%1Eul#L6cC%e{9&Q6W4P2t*oka=3d83tC&~H3d#?`GufMdNq#LwvQ*sZ`e&A#)+NmG& z7j6)xQEv#5e&|tgaMr!1Ng0!?dlT#rnUWvUg0Ne0{4>9M!Qy64emM_?v9S(z>Wn(S zRCg!)!_;xFrBcQVc~K+;=St-a_wSv&KxY>VfSR+m*ILm_fVA-v6K{`R@vRTk^9-_P zSeTt1U7|FLl_;K^($=X0z6`?Ef1Fh(|D~<0%3j8zGmKORM(rEA46hsTrTIL(?`~#pSsZ0cAO`- z+dE^5=6BDVIq~ldCii5tl7y1jQ^W{i9iF0+V?PyCGW6z>n9!~HFlYAQyClTzbzfr!AzV9Ql}8N0eKzX-xw0L2 zWm>-G)Vg-WS9_ZF+!QwiLSgvK@vKK|=gN&w>50v7-ln8p&6pSvBF&KD4?XvW{HMKV z@Uk5%A*SNrytJRQJBRdbp|)T}#Kr9UiwcdHhplogjfyRZB5+O)-v`32S+}wJhq#xM zL<6LRUzgk|TLmVTBRgV1WX7u`s}H1mg$h+a$AhHh)f(D;7r z2|bQ;O0WDfvG%UWX5rnK)p>joO3C{?r?4yZn_$rc)C zPLR(A*)+G@Vz+?jp$tVs$xIc9>?U8r;Xs)4_gMhhQy(9XD^5O;GXm^|v^^$~@zU~` z+sPgMysF|vgN%ck%=(0QFS9v_Y7*Fd`})CvNY1otnI7litja4{Q8TKv;G*l}R!Var zMEc6-re87M95a?nebs7u+r9|32^zn0q{uZJ{l~Jr6K%0<0D7ee;+da5ALkhtoa&F{ zh*}Mt9}Lm`?I?V;LYRxwwBv$2O+d4@s|o zJ6Ws6ErkBK|Mn4~Z9B!7KC^ETe`#U>yBNuHs%f9yt9C|qck;DWE1y4`3%w^cEsa*z z5Sri(U)Zf7X)*AMXQB@CO@*LIn||}16=*Es@o*`#9_4Yc+GK9L)>VMj!YIQq9RS%A zmkjJq`NqQR!gLo^A+!8R;5>T3i_@3n`xyNmsGg1K{0aByJ!^$XR-d>0nqZ6sak!H2 zdQTr8Ko%s{`e?<*`#h8VLAI7*<<|Ayx7p5?zH`7BbSv&=z4~qKiu4wvtR%LJPpAGo z74q-)N<5@hZUE$0@!Gt zt&q{Jg#t&aUtQYHg_e`7IUFY72!sudd@9YL?m69-uM5X(cZapu6 zgIbxd`a7>$pD2T#7G7gCwSY)@Y`#LsiJGpUVlJWCP`Sat z@H|HXK~>7gVeKYg+sYf$i`-&;6@bR0vHdZimwSx4%Bq~h>{ZGaE6uK?cn}45(YUj; zPNVL8rrk#Y9GwSODyNPZV~?2YZ@~Au>GXtUEdiv~pBemOxlFu=imWgK4$v&v=M|0s zTXRP4CY}g}IXR)$1mfx2eA5+&O&|ZZ-90SuCXscRVO?JrbxQ5TQ2l1NetBn(JPaA( ztEm?YvueR)o+xkHG(u^)ThkniMzaYqEHK=HiU2ZvcGO5iRm0g`tBWeo
    Z_A@?P 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

    _IAFPD{n7FhgX!NUw{&hX?q9w_@a z_3g1gv_hg0cEyaTcCK~3N$Bt!m_W*&oG}O8YSD0I7@D5&!j*oC3n$IOi6G&vYVt6k zV-J+YeFkwD0Y43L-vYNQyM;~)$z+QDU2F_9=31_)!`-FirbWzV!Hwo-EY?`h_w-ay z2dtB=cUYolYi^zvUlD_X7#?9W7g5|@)G7@AR{9y;{1v5X0&mIIs;ymgZ9TiXX@mBOVhKypBc>oDpdxORJFmE;2v%^ur53}4gVfNoT%9{a6g|xo%>$ocM=GHmO0itXoSOZ~fv`X^w)&MAHl7M{PGAC5 zG^G^qSM|H%XDLg*!-|r~p(4FJ_t(T3ge!2xvstJS(Q#R7{(vmQ9<3Ggw&d1m@2csPoa@K*!VcI~@ zU6w=!0Brd$(Ys?NL!7!G+I;T`oU&r|NKEht2Rr#uJ5@wlFcPvi-+G>@7(Yx8`fHq? ziN(0&mMn}?qinM@Q>Dt1FHL&Ond_#OhmHvw-kKjpAfE6Nyot2L~K&1zDm5wDmKH?onj-jatVKaSv{KVIa61Lb$(UvgpTK>Vtd zm^NPVB6^>lsM6MVBo`4%#mK(tcj9EJdG^VGn*1Qk!3ExtMT`?wH81aw%gvUZ- z;wqSG!84%bjHbco&6&*lYd%p%FHPcmfrr8bT;H20emNGG5ve zzrv5*9+5j{>in_O-c1~7T^WWNA+D9woN+te!gekWodW}JlFz}R>S}0*_Mx;5Ff9|XjN*dbK)CZ{b`hrV2&{1zH9AY(2Is`_lb zxZP3Le1QmAD-RQ^eOU1lOI4XIv%Newvk5%v)SpB9xdJ`0z1T4mTDy8dR`5~Ev1kZCsZ)Y8dyi{vqha|!b%_Akql z>jB|X%>IJ1TCIK)5@~EWdIA7{DR6rt}q@)p<>2YioolZ;3F%wk#fl$l5oK(bY(UY;XOEI=cN~I zth$+aO4LsIK;9=c12>1BdO7O!nK-I_%qcqI{5Ah(jV*6lAXHoBZnCnrl6*Pna3Yc) zb>K%K%0`xv4>x1|sVC3n#&;e7Ue8n%_yJzQ-i$kLKV6};W9awNkyOckhHR$U2O~Wg zbu3}q2Cz{4^*)8x=Y?8B79r+A!No%a*a1TnZ@#5n28XU|Y56YOaG)d1woMcyC`Z8x@U+qP{qIk9<8aMQl;_g(((A8^*$d+k{> z^E~s+tZ&vnA#o>|S>|f|ugu z3CcA=wD;H*+0k3I1bGHvCRf!Ezj@^<@%--D@7{w2(^&2_BFc7kLE1}fcNPJ}y-;30 zqKnRPK>Cj(5vpH}{YiY{DL84!;X+NF9S4z|g6Bm-{<(`jQisJKklqF1AWoH$+HalJUs!%U7D z5zkJtD}AKdDni(AGa>Te6ZVOZpr=U%(v5siohkim2+R2`B}~^lGXY=3@ZL_ai@=YQ zq}wsKwek&TP482AZ6&KU?DxXUThnwkW~r^f#nX{b7F+v4>d~!-&8s06zs^AXqOv$r z%d@a@UlUHWhObBV5p7#q(uw$A0(Xb2Vyz$YEYBZ2UtSr_(+Wsn|MMZh=130n=s5J9 zq3bcwru(*7j$ZM0uBl3ZenC2&J`_rihK@oUWh!ABvQfY^&Q1XJY-U+G!F@QaMpI6na3YyRi9KY~)lp&oZG1zmnj@I!GAI6>iv0OPq`t z=ufhrP5s<2jO1u$s=E-ErW2+7gD03YZ}$T~V_+EGGnLl9M_Lmv9V(F|DvnJA$>F4jdVKGB+7o*p+u@pl8? zUs@jA&CHgqKmU}L{>H|Z#A>mGf`b$GKMB`wkN2SeIL$r&hSM`Q=giKLuG{36xRgkh zoJLWqpgEX?IoI}9Io297)&R&7LfotDV)^P6C>rvE7rk~9`SYwsA0un!Ty<>xE$Hi6 zUCywr4x~9SF$P<4$N)TS1>I}OBd6isKd{=-w%5ohd?;3Fer5Z&mrfef`7Smg-=Sr+ zcT%8|oBGdGXSN*V619lEp@AT(SZj!FMn(!jO&AU;@oDWCd#FpWb$s}(3tz~B%n(|N zD|^4Eh#DV4t|e&Jn`elG0s^y_NvO|AJiIpQ`_B#EEewls3(%u{lz-i_G6Xe-zLKo=0rg*Nl9&2FaljiX z(OYYFJ=HM>9{#NNw`&?R5sM%}jauv;Um=Si6-*>GsWTq;-#ze52;J3VK4~(G7r)l) zdu@>7zI^A0m|aI+*Y<$c#AD6%-yL)-VI(#DMXX2Vz7NZ&EFAR&2O(YK_St<2 zbESdM+-01!SMaKjM=8}bWd+jf2<>bQIq_6rWA%)x+dLme7L0*Zt*&RJ5iBeh|0F0q zOK|R9OlcWGJTf5g{^&Ye=ng5g-oLZnW3Y0HUv}1F2DIOc0>>aFsQln-B|OXjk_2*h z!Y8v>r}By));$+lVIxup^#?oU2<`L&Yg`G*2K_NY`H(OXgX>BpexNvxmuvnrk?@b{ zO8)}Q2W;}$`E#I_B%(Dm+zXbZgdl;wcjlj-58D79zoa&!IVMg@P6t`Olwjwy*DM*< z5EY$Umi_3Hw&er;6YdNCsQ=*ROhmQExExwqGkAY*dNUL`dd4bbD()TOUCIzUJ(|aq z^KX9s;5fMorUm z%y4p{4}XsP$90640TVgcsAIw(3wjSD-=^bI(Xi#>|es z3AhV6uVP$}ME529gGB=bqW=pBuZf-xX6&Mi3T!zB;bv#C>%U`Cr~;Qt{1sGY(!NMy zmOl{m$EEuBE=Eu*_cO+hvU?!i{<;OeyQRIu#u>hA`P%sRB9MQwh4-Cvl9%=ngytXN zO1V{abSCb@N1DXjcIDl!EIQ}J$Ml%8pJcC^&LuY=S-zV8ewQ>^bFOh09d&i%LfKu8 z*GdJf13BEu`uIw+9xY%TIAZhKU>ZU|yM-6?y0rm|zKy@#tH%>72iQZJu$$g6T4q9Y zS3@0uORxKntFMk7i5KfbeFap)$TWN{uceqe!=EuydeV?Lobp+A1FJ4~0`ESr`<(W0~d-X47K zVvY=!(remsa6RD8Rw@%}{8OIlCA7m2?5l5O{-EypTC30QYvhbSa77&>~s! z&zR6A9j{MrmxSW7#y8jKJOr5G3gm}p+;FL-y7oCHuAGtBvuZ2&7`N|97yi(qRm?&m zsZING9?&Xa`{p$ReyWlSuLo9GPw`U$R5@3W#I&$E)ItDcx%22g3fUZ4!k|}^+@N$i z>{xG9FFqWM9i$|LP(BOzz`!P9R`=-iI2ld)3L#N0kr&4UYQIy@1jHw`^c!nVdXuzdz+OjD2%A}nwFL~++- zA`c1tb0ar^@Z^;65w<@EQ}B&(a`*uHRBQX@@*&vaU8EELl{g=*f; zj=NIs)MOO;VCqU0zVZ2A6^;DZY{{9PFBpion@ZYlXEpM4FZPeVeG@1YDnmz5i!M_i zk%uiV&ZD4(s@Am~^S#AfAA#4gVQkGGYt4Ba>`Rb23PRdh!CWl-iv7@+J3T}6f z)_!vaRhUZYCpu8%>&p!MIU|uWYsll*vypgNZl%uWqwVS539(tpP7;=EUp3J>D|PyV zP-YrA@R>4-l2^H6ycFn9J|sZk?$tw54fOffHtmEe{y1XBR&M0MR@~V@%89l*0W0qe z((~(#pBYc;eO9x*3iQP+0cgXpe{=fr_wfdkyV2c zNFi?gJ!UMf93O|o{v!&NLESyU9o&9%A6E$tgUP3P3K1^6$`G3>&_Yb%G|XP4DS6>3 zyKx%F#_ug5roox3Xu1uJ)h>BY3}SVd0X+(Pe#O@8Wxy|6fGTgQq}jt*@YTILIk4p# zQ?c$!%(1pniV$7(Oa8xoogd=WDURnPN$lgNxk*#2$Oa3lJ3BI;JBc!cbIkerPYED* z{g<K{MSM0o_XiA06eHB4#W6;9h&kHA%iQ=yK9GxEERAus@qvTx1zSx1+XNJ}nl) zoMpqyt5EL3!zPnZ4Pg@hOCjLLP}jO+%)cabR-wsJ)$9aecSF3sei3K)v%yY@C#EM& z{>}6c*$swZz^jprgTZ`JiTG{OH+H2Zfg7A)*wE|ya93351ExD@d;j1aAWCC#JyMX% z6Zyh>xmqLjm_KAQ{>)+k*5D1lxVCk9SX1T9B7a`xp>;vEFj8zU8{?w505ARi`UYu} zLpVZ8L_#1h%ysy#?d{gqCY9bSZ*@j%a(PiQ-3D-I+J?HfLpnH{2Xki~F&Sb;SMo+v zejeSx8m<0sl<(gy|Kf-8L#)vQ(;m+M4+cK?=aX=AT%>{iliefK^V#_B!1!8c%SF__ z@-_djuqO3@uU%shA(CVHZZ&;KRCZn=_b?Z z_!f8=XkHs^9our4%2Yc`@JtsKR@Md%Rtq~sa@BOAQH12Xnt$E?mv@67Mn4RC3ZhJ{ z1aU}4gh8>Wk$WhJaxI1 z=yb%lLbYF5fwt5MUQo)b>rGL2foEp*;jV^ay26ylU^weD`P}(FPe}AdKL`K9b&+cm z*4%_4bLhfI-NgxBH>9|EEA{|W$bmto=R3Cs!CXg7l>qR}LIIJ9>OP6>AENZdF!1s7->S7M3|3gU(WsA3ZCA&DJ67Ddx-)H0j`2#HiY3YlRq9J z6MB?td28w;(p$lgr6BIep|k$6P#Q1Vv4w8(ig?on11be8(f-@>%Xo$WKiV%U1~9sM zy{+&l9ypP|lxXpSHB58PhmuO_@k1pA%ox=L@#@8%{!4R*KVWNx6Mst8z*gRj853rY zb!R`6rLf<7#CYjo0H^Z+HOWK6MypNtKTM*e6L2uP`KHI8U*7%EgdoF3i|Gqjoz=(} zR7*?U z1C<0Nhmm{xsl>%wAdyLMNPfjfg*x$H(!*-Q&H_h6e%|x8LKZibC8ojp^gKV(4z(Eo z(KGxBGMr8<+Ma4tBB==srjIA15bQswiBf;?k&Vpjx6OJ&(fit6Iv=B=%LbwMyUw7G z7DZEfZ@>;5Mk)5*uP3LCQReqQ{nlD5oQ6b`M0+4q5XZoj z@z(tb-$m+aYd(g+!ND6Et!}9rhhm4CD>DJ^)BAUhoAqAgTCUiEARGC9ZLs0=q;c^k zURe>&ya_lZu!a*@bN+>67-IqMRnb^A#hGK=LjT-#hpSbS*aqaH`*xg z5KODx6*LZ3$X8&b#W*GD!Udu?3PNUaJhV=N@5 z_>{QG>8ydN(csRm@b+A;Ar+$fe7zK9{k#G(XX3XIB;R~^!@_IB14b%=zt;4TNvhQn z6`#-ikxuGf_qTXd#Ia@2I9YF;2-cAY-L_(MUE!)Zy{sk2+-kJI0-YK zXY`Pu5xau*l?0HGLN-9Qd=e}bSK73eYZuyzfwZd(aliR_H@q#lKzkQ1S|Vn?)gq;S zvzU~)$xZqH3?sg%LLa()Rm`Oc!OLyr>o8s0#)Di5X^oms(5TfpFi`ob3?cLKx=aB! z-%8f;7W3qtcLpILcy{*e)&X0nGd28WO~ni7|IUWR2mF1yU4h<^mbt6cf-INUt1+cD zolwtB92)#1kX@F@WEvzN@B?SX{#%l>k&v}U+Xt_02>6GXLOtT<)Ul?2CDn<=BG^A? z9sTIEZGUz+{e{`}^8K=EWBj^4`R7p7P8#yb6u55kVgn9k%&dbe^QFlLOo6a8Y+vb|b0i!v5$m8#J@b%fB`*g$h0FNQe zC+Uf2Z6%*eW|IJ0c+*#heoe&ES;to*TCbjigwdJpLU4qEtmpkXQ_+?$di1Bxncpf! zeykz9W!MC>4}ngguO<{LTwORWCtiYh0kjDfn_;^j6NWT1(UzA|*V$N>SaK{SyTaSJ zY~sYdz`854{B__NjxN@TSs4uyC8r!f$(ZR-R;IiT$>htcDj# zSRc3Xt!8ImS}i$;$GZm_5>KDZ-b7&7u7?Gv*SAb1L+n0xIy)Yl&d)NOC@M!Tl`)!cY z5J`W;ygmh%-rWLIdox37xq73mAasikYZA}a>O*)v-t_x~nT!7=)`2L^>sMULu8&<~ zfo<5Fctrg~Cet;~6F-|WxdxM1idXF)pfqH&_cblQ7iuDUF1Co~29OGUd3AICu2CEV zICYY58YbI%X_GsR)SC{+p?%}NxbPA^?2Hxru;9ED>IX&3LOO2*m-`j|YQ(qcx|6%+ z24)D#4I0+M$$&?_JRD@G>_5f9ENag#2%38AKf?T3%Ail$u7R775Gu_yV?H|G(Fj1ZF-$P{)qbbPqo86*yE3jQ7Qvqg3f z01VvOykoBvQ<0Al@Pt0!+XH@O*Ha>U8!*pz zgh8g3>&5EO2AC0|4yd1mX}aV7q(uBRZ$k_J+kXQ8-W2*SVA5prR6_6zc&2?MYkarC zY?FcJPxjqSN8;=bHKOEprurn|34E?3I@aLZ>v>d;4Tau9`|BBR`WB@kcPcDUwxn4U z;D~6QV?0h`QK1Z2_YvHDYJNx%9{9Cnz`$};t@-0k$mj0m z$6Ay4WW1_x^*!gpsA?5=rgO|;)S8e3zR@V?DnQiry~aE!oUw5cdNxT4^z}jf@ylHX1fs zs6;q97ql&y6gU*9f2hUvd#sZyg-0AZ=PElCz~qf{?<-Be@9lFSKC;y9R?&aXijZb} ztrL%|mtzWfwd_tSE_($>$WGQ47EP*-#qcUL_lpAOk3yegL2^^+HNr+ z1^(K@LiR#mli)U8_rugVj0#a)y!pFn(}py-roxOz<%)yXEPo484{AulTDR*(_Ctd>dj|Wp{!+EdpGQYW6+ZucXOuiO{N}c{ zHq0vxl|6&K9txE0l0@2-rC<`o&HBsQu|Fd>&@bn>BD(5duVGbfa3lde8w_fmRbP0A zI(|0WFJIhOyZDr!Et0P_yJe1rWfwD=?P5l2%k=+29q{TDV`}*|ig$TChhu1{#@THM zrIieZ4SV@Ywa?XF=P<=SvF#Z;pNuxb=%IL-YKLHT7*#h^b2>~lp$THA*#GFVvRb?I z{vcR8ECD}&a2n*YhP^t)EwhN2)jAjT2Ex7MT_-qAINi*IOsq~xmqbqm&}b6yl&q7AJy#dzn_$nKn~^Y(Qbd{Qv)lrna=k2zZ1Ul$*MR*jQ>jN zdgf1Z<((E2#@#QpZbYWl<&U-Dr4e~MKNhZkxRQQn$~d~hxpYDh00-_di*_~yGFSUZ zcZa%i0~tMTT+;s%MjJ4Ld;?d^ziDdKJr#V-~fqe>5;hI!FIFctwRV1tRt`XB)D z#ojljf_exMPIPcoCDDe6WxwFyXYmHt(tLU3=L_A+wRP{eH0}Z+9bZP~o4BzYkxiX# z%W9@>A$Tw$DDI)E$fWib9P2flET$(DIefJS@pPp>Q{7T~%VbltXDXbM$y~0EC(dMj ztdA6O7jgEBH@h@nHtyx3-4UK8AbR?nml=KvQ!uj6ZN5V`>fNoh;j;fvDMI$dxNO9n zrO82e*2+Tn>l=py#$qj9P~NfB>&_>C3Z$H&!k4jGkyRN|?3D>DNH{E=^-7nlMD^=| zooLr~p^2&Y^?HbJ-ML1-wQsYG2XBfF+F z=Y7n#rC84e!<^mji5gx~FD_hwXuUIL_pE zP0yQOmsCJD{IS4lfa3eBcFXGv-R;!!UTbcYHC*(UI%HbYe^zYz2EQJn5Xv`^^|Bf5 z^-*tZ7W>eh7+SiAG)-=`?(#ZJ&b~BO))Q}iAd6Dmg({V|>_?|LBHCY0(ac&Dj5$_}Fgfap0t&LoMx$~3#~cm2{L@X2 zNM%y@Wd}?OINR_VPZsi&_v)-UMX)7MAoi|dKS-=v71${|kuFJbR`cZ=t9E0QSGw zCC_lLX?zHpYH9`Uzb@Y;Gyy>GRWa{r?mW-3nAJSO zrB&#zwFb6TPQ6(-P2F^du~iirr`BBuO6^ehSr?M8x!E_1s<17uUeP0O4D%zBdOu}J zcxgP~oQ(QL2NibsYIa_IdG9CQUbZEOByxc@9m#fWh#Fmejt;$lq))!G>kQbq^)4_T~cFY&psB->UA9Lg{Z1`)W&IWBqBrn2`e zlNj!)pD~YrOi%Fh?T=n$8|lz6?rN7I@oFE7jmN>|!Kt&uYr`xjw>SE_HDvIPU4JJ! zSwNV)hLF}f8ALp$@^^>U<#b8dH*0!`HzBCYXQ0&7=xA&!X3CdX031_z8_ZCgwy52@ z@!9+d`Wm0P{Q%g!Z|XvD5DuPpE$i{p^#g(LS2i}jHy}3_Be$ES&Nb^1!IKP}f0ZTu z4=@q>Y!@X%!U>&`kqJ&w)@UOHlKAxPD6B-e_6Y|=n&i-nE zs;(sIR!L|qa1|l7^!UAvlb4PaL&|vlaiY-daSdx>?G?T}iPm86YLNEw9>&IrYWjVc zj7Bsb^#{31B{=k0;OJ*{3y^Bw0zX!?1A`0VSUNdFr(m-Evd)+ihg)lI=%f#eD7t8c zS|h7DXg4WJRFMhY7q)Uf(h zSQi`q7YPonc1jD`&5l9lmfQ_x@LSVH-NDdVImi3G;JYt^oj?i#XT~oz9q>OeiZZ}5 zC&FGS#9f?&Ni|lyuLadVrIb94P!4?`A0rf0@K+f6qJmZP*ALrDTG4g)2x(jCP$9t7 zsL`5ot0?Ducw{4MqrV$!^>rG6`Oh={+t6>E(D<1I^1dV`(C6kux9h;8zICI&AlKEZoPIvG@H2zHhiNw)mnoG2gyt7F;1t!TPg`Q3lr#l~(E! zZ<>6kCzV7{BI(HMwkov^5|WlzrVgPch&XMteJWNt@JGc4#OG=hndiFPCmkaE+GcCa zJcOGnlLx>o3W`t;Nt$p7J%9)I59a9)`9&IGT^ymwrU!#j3qkHNP|}({y%YPpr#agD zo1cw0jo>5G<&9cu|HP9!BA^nkc}GGiD)eKTfq!UOuB%)qUybjpKa z+%P_mtjN5xerxqZ=Q9J6z!oh-sQ-~ohgvvNmzwSTF>U7vy~z=59_BpC66wSgT*bL5PtiIlqu*nl6 zJB008AT13cRg16rPC7pIJYOcuyMdv`U}-X`O;b4bw3pzN+G!HkGYQ$O(UGs#x+zxN z)Z5Wz%cH~jSYTFixDdQb%Y!Zf@^-SNs)J~-KbRh*MKG6w*5PLNw+9$MYK3R4Jle?nch9EUwz)D=N_IaBLja|fw|Q8Q;sJtvuy@@BIe7;G{3abe4cStQZcnDp>6+QQC04v> z7V+KwaTZW0lhAp9N*Jwl^o&bNP|UnPEc?Vt$TPl>H$KAWh{P~9+Wy5@@oPJ#cdx%> zY730mjPVi6U8L<8z=K}N1naAS{%Ae^rrDE-&w~$J z04I?p>G(Hab>4onl_Hh^;NZ<>%=YcY&6f&tij7WxSY+GrDfORe&X+w8HcQM-R$AtK zzjlk3F>Xf#ATiv#dQUG{QaXViLz9wy=Fa^TC2;q`nhu>$sZO@w2HWbko7~1H2rpT` zkyl#9&Pvi%%afUCvzbR!!EZ}8S}#|ZUAOG0B>~YUR&kJiyIm;>eL3NI+Fz7A?Tb#( zZEngy$P>SA5%-M?4Q@W?_9`y6R!8n5K96;G*yPfcX`WaQ&hXs)%90!}s?9p=SR$EV zJ6F9D=2>(m$UmIgorYnMe*}KEBmwpK-$4ddnY13ht6vdcHrW(N0Z2L$7{fT>`ScXy zFzVB>zR@V%2+WCK+P|47>h`Wd#2 zjEsVu|Ej}+On3)7^!it^Ig?~Pl7}h3eT7qunxfxHBsnd8m=ejVAZ`=~`f<~q&rQRU zgopkAFttYi>s~%|MDNJ(#myCau}EKM))9qo%-+-*GUneV-I^*i-T(T1Yj!vBb`&A7 zBhw}sqUq(+JWFK%_GhQuC7k{&3>LK)7kr>LRdYM<%nIsY>fdUyKN*)x0!_bVRX%eKJ+a>7yQ9i)rt zT46T2(1wv=I2}p2+|bfB&;6`kS_hvWzbX! z0#L6%Zyl{8MK<0W-($aMy76q+wj^$}OT$o4Ye^RWNkn_ulny_eHSpc4WJp7YS6I0{ zMv4~y7o*?hW8jR%PP)={pkoM1#=DLzT*fsL+}D-i`=$J*q@3DPh=oJZWu+F<(nZRI{R>(9(2HJ5Sn*xplY>jM2LnW z1?9(>d9LV2o5y|bVXRcPJlH0edX8>uo@yVDxRZdb!@*$hAR1LKMO-PF7Emw>;c7y( z)|%WRh@KOlehf$vUi5d5R~jtjD>lvUD{79Zki615tzM$XC7GVi|C?%j3H@j$qU?)5 ze4?o}RL}dx?*)zg!!iHPX*tH}jNF)xPbe7aD_bwzH!Gr(KVB1_7PJw0o~7$$G_N$k z-2|NBRACQsiFQP3B^~|uH_0b9&#(t4nk^g`Pi%?n8Jf%MnNB4QG;hEu({@e0p+nn) zPox|>%{3s}cHt9J}Z++5sJqfqffQQKuhka8PgLYaPf9@cP}g` z0*`{(eU6Emk39{%+0pMCHzG#c^$>ca?U)3~#f!K1ukTUK&KX93LS921+u)stc-7u7 zp6rvnz7A||7O$ocanmvk?l)`v2P4R%d^ASoji`migh6Htc;>6r>1yBwe|H>alOc;I z9ml$Awm|VS3mc%&%xoaZgmmcEy>3;w!@eco9MfuF)4Y6BSuK}txUJw#MCX^)o9m;) z@5~4uB@G3+$LQPE$CcnEjT4jhk3D}QJ!*sM5qG_m#aUiW%yj6|dpi`)=t>X>UQKtO zjx;c3u}NSJ*5a4ZJ6!AL#QBtEWIkW?IPX|?XvFQeth&PN_7(n(YcPl=tYAOVM+Ba* z%0&O2A$`^Bh8c&xcfou+2EeU6B)zHWSe(Lc$$>{Yd}DTbgI!&9d8w$`k|E9|} z$G@8VDa$)LTDh)Ysqu9Ftmq)YgE5g>wP{mJy^}3U<9qSi({In~0~e*LD>!Lho3@^t zbrDe?C*Qj1uF)Oij|F*edXF<-2F7zEo)`T`k1dJ;XCm13Z&mMw&|3 z91ro4ymJ-*Tw%&&Z^8$NJ7QJ|qJFKJrj;la5%A75~x6n8sVp4xxnZsz;i&JUugzVm$jT>LSLJ`+$|?XX6{*<>+%>H_m| zNzDGHupPdnI0ZC|o>4!x(%{GtLGdpazM$_EE^FT_`q>{ryIzf86=pAWW}iskL-kGa zFxZi8V4N+6PJ3q&o=hRR@fr;j4cHNUSszfO`8fsdDY&nU*Vs-bq7G*HDxYc^U}<4L z1nTNT?aM|UF8obZTSF@WwfNDp6v~_m^xspk)R%MxsD{sOqzo3@&O7QKnLP~Vf3k4R zmU_{ARPzjK$m;d`WwutGe)Gbn#R-xi*r-MT{3j_hN2kuYUCs7!-Xh2QdKWVvD$|%d zlW2lF_#kVFZf=JNB7rR7T0c=xPzD?-NpT1dGaPDO%u@-Y_gy`?MpIys5cUq78*#8t z1n%DGnpI#p-#(BqzXZ;WtdHJl52Agk$#Y|je-nkrx{sdsG#oHp0vtr=;eC3eF|@_D zbtQ!KTAw*g)_SwEJbD;+AUP8s zs&d;W*&tfLKGCvmk+!M?j^MDB{_Yyo$($*W3Z1Uct@bJN^fg|yjz!*AkiF=i zf4HSXptCC>yu9d6NtvVN5>I0&s$bvhx~91 zp03#WxgK!@`L{)!=~4#%*eOyyuY#F#7T4T@m^|xdgN!?2=GhlSCVHJ{IVv0wVzFN# zuGxobEcSIoLY4=ox2S@n-oBqdqtIw)4Nq%S&HTwNH%k4v5G?zAl^zhtdy5%Bga9;Y zhc3r^X5rx47r?|xUGh(kj~H{{KjN8B+it6t6@wA`f76t@)6-d*+mk%QYp_IhV^@sT z$YxH8won4A@__F+sTT{bf1uld>YVL%eD%ZK!b9mqv+RAaH)cKrq~&`xcE})uHu*JG z@Y1twuP+7%CMA0bLw;rt$*OPXJbcM~d(>jofK);bts_2~M`y3f?GfGWQAtgNiqQ?R z4qNf4-H1ePH?t`A>86U_i6nA*!j18s>?Yl&oSG;_B}9rFZhQo@4{sLIL7BYYH1|yl{gb5`KNjDyJXw$FvF}wyHwC%P^s+ zG$?VwM4g$7ECgkAk@>#5H!@nA!-%Z*rCAFhy)!;M;AHMlWqe2HW{t?Xpj*zVC(GSf z43y)0K3eslBhqd1{8A*!g_W~C=lrsC?Egx*wmEcuQGPRCO?`JQVE6VvNx&axas|uk zA3A^5*$Q#~-0;puxbHsb*lh0z+6ILyAzUYfD1`aQtf8YRGPOU;)q8!Se&@+PXkTN> zNrEh1qBkjaq1m#+9w3U?74iJ4vO#=E3y4EZfMba0uVf1g7{%i|Lj1RR{Ryxhkfj>=F2{t^uOy)bVWwQ?c?a!|*ekGSrzv4IJj zlTB{?WOsK^WLGa$G-Feo4u=z|EcdBG_teT^Rk~2rf4XiwpwTc1y({0jSQsK(LR5=Y z8ZC%46zAD)K-tAq%MK8b+`&2EWy(l>o_nm`?_TIyIu;{|rxjJbiJ_HfVM!8C*&4%1 zt$GU<>%O>L#4rz4FQHzbsr?H4xN23gmSClC^lWH!izVvRegrmEy5sVnYNt8?i-Qy? zb-RA-n&P%Jcw(D%zxb(n#==;uYtMGfG7$4_HDeYVq9)!?(O7{#J;I2ca=vh{3^h(W z3>BM?w081%YIm34@_-%VzA{G4#TtVF2IEaN4CyxsJxCo_FF%KTxYMxMl8R;ORT`|8 zGgbr)vatBS3!)~txYV65{K^Of-&uKtytHCNzZ*Hiqp$f=WV69_i&Vje7fzQspy;9Y z(4U>bs8rB0tm*4|tz`VC@9?fz&WJW~LMVv3tOuRY3dzG>EvBun2kJmSr z=A{oM5l}VQ97O4__AhP9Q1hWhh`GP5)4ZQPSFVTREv=e!E)OgIq?u!*DZU3DvOV5C z7CSvF98pTI6voqP9{*_O(rZ|R*sZZ2mQW#*?U$c|uRQo}u&h;Nev9O}zH&MgkkxtNBaUJ+(gBz zb37qeF-SqRxH3(a$vZ!+NlTrnqYNB6^fYd2@4Ef@Ud>AVlulDg%T%!o;Xc60_pOyn)`b!41(1OROp9FH2j8A*)l98rc zd1G95+HgDNBj5fAfD<-)F`pzBy8fG~{${v=`l)AD&Un?lh>(zkqB?Cj|5NhQvO<;V ztHJS-AzMD6x!|pO&B+L1*=UDXN|$c1(j0caBym@I8lvv|K)vCfCCz_V zk!axcW$t2x?X+zT<&Tv}t+8z{j45~&4GCe*oW3x$B^KJMu~V^yTZ|9^3e|;Pq?JpC zc{d>mUl~29yzQ`qb@_R&s^hnv7&_-4ghFGa)ibR46{C6w%PAgBfHwOEcvUHzBkNZ; z(!DR$K93aX2Bg?>4E`6rFpj=_Jb>?@K@sN_X288Uo&}GY%2d?vPiUM+2>CL6&Og+3 zkjJQ0=+h!{5v|8k)^A2sU*TszgJ^za5SBxkV6jbGt>xqF>gtF3c-cBIjR=HMk>bYtiD4**nqd4XDB;K>d zlwC|#i;MtS$lUR85mpgfiT~7)qWU;2PMY<%HAH?njc&mj>m)D^yu+Gulgqqcb z9x%QAt~(a%M(b+GarqERdoxcJl)GpqU$d*EECBu^L@8D&GIg!I=7m5hA<^OFUU%X2icDlR;_g;^-kVX-nC^c zx4>y9;>z#->85?TF)@#H4II0WxW4C9hW;_S9rR-`UOlS(b`r~CHBNyjyD@#VWR0E0 zG+wSVlu7@8v;ZHbOW(Q(I5eg+?WPq8x>rYpbH@Mhf4x7-ca#<#My{&4~%hcsNG699XQsX&kUE4{|Z{g%EteNH$ zMtgNoc|gRRaPS`Aa&X$?RF^q}(88a*HcM4${o9%PN7!-Fp(59$v;zdEQ|D(a%f-ON zX57{2S}WDBZ8NqI)fr|qqW)zrJEbRdrW{_M`!VT^e3r%aBW60k_o5~^{2JNX1lWq2 zbmETN1@n5KGbKb2tBuoD_q34Or>PD?2f(MyNoo4%RNOzIMwchLcDcao^L~-jf_>2{XGvDK?9vr$==t~C0-KGlSd>$lE#VBv z6O0!$tYF)y47@=bh?duu+wp-Gt)KlHo`1c6*)VU;i5`biq1B0gH2%bzT^Z60@ui?M z+=^HAYNC|S9DHd%oz#}IV)+N(=bOjE@C)Mdz4@Au&AV{AL4h1@{O*)+Xoih?ocFoj zbA$~&!xa{3MtWdKZZ}cU{l2`2F*}n9u7zxx9pV*1@B071T{vP2LOe3 z4iyJyFmUAN?!^I?Zkb5W%79#&2XukJ#~rKs+v1-6-3ClCIa*x>hC z4%oPGayAglNhd*=e|#AzkAFHZeaau5cRmeAT3yHbys~TtSI<8I;L^rlFY6;jPH6CY zJg+gH#O2(=`e(+?Kk`MR-s;V^<5dq93!WoiE%|GOn_12WQzjmj*u%a$xkwL1YxL~= z;=S(bh_zF6M&~soefOy6qW4X+4Gc?5O%3{!m^B}in_}Exqx^}0&XmwTvK#NMC$Exi zZJAQaEzi)2hs78k8!@;dUY!B=?quA1`uj;E(o~y&eU(lU9j2xc!9dXw9 zl#ykjGXQM$hRyL;_HWqdSgT&lh&&xvlzXh`gZW6CT)~W%4;*|h=fd@jiTm$w184Di zJTu)7h?iR3iuReR(u^2mC%s-wke#d&h zDr3oZ@F>xrsgFO@3oamZ9J|Qzay4g7f^LVH1=r(~m`D8C+mr-2jXRzr|640tz`t5t^{bH$TWl&y8^)yZH}Do_lvNH@N}`T20R z6&0~5b+Z~^sr`UuA@e)~Of)gwOP|zw4o7axA{^^ka7p3uh7io(%FT4vh(0eYsxUdh zQ(V;nISuhB5-j`EBS`nIjm8e!k65izYrD|~oC4eSlw;_vj9G4$Wm7~L(!@Zy(z3+) zQo<)mouyMo*5-X1Lx|l;vKmEH3<#Y4SG(Ixb~0p_k7c&~gO*;}Ui1;i3)W4SV?Dak zy329d&##`)?uccnt+Y4wZ>>u?$_5Og6KQ@^<(xK)W55wx!L@RZ<=c!C#n}6&B=4kG z_stUh*{neM4I$UYrcdWd)rU-taIbw@v+46c9}$Z!VzDx5+-~2-2zZG86zJr@lYMhw zvdC1V17J7paCk>)-2NYQy=7QjO|veH6Fk8kg1fthkl^m_?(P-{ZowUb6P(}<8QcbU z9o*gRnKAXp5Dqsh9V1aJC3$B8(78%8xhfr7D^S z-hh{^Ry^0)pyEaN-Lr~VdRN5lq($%jYAcjjtI{(QO>Sg04DS(Q0Yw1GZNZd}CuS*J z%f<=IxqTp(4$2+vy2J>ttRu?y^@CpBlRG1@StZ{dZ@%7^nk4IXCkg)J8Jx-#ZT5=| z^q~=cO^x$<#oC)@&qnngt|n8jW~SJ-Lwyt8o7%t%5?IX~C*4=1R$=XEGovX(|pL zMa3*!-eVhJDP;eN#hi?uDM-FK{mSE!wnhAzyL}<ZL72XpqOd*w<);REifFaoAew|HYLK$1Jl^G2U1X?(eM_`*PXW#OwGq#ioA zEb5b#x${TvONl0%&zlF*4l07#KD&yGa5Ueo94{|E)jD&Lpyou2?MA47z*Ve4yVxl^ zE+NVsz9d|PNJsWa%eRl-dK`2PKM=3<6=fVcEU~j}6j=Q6@nrb@t?6NMKU-5ay(%$5 zw{|vrYWWm(q~cW3P#HoLoM-e|>k+-YxWQ8T}>wndV2g?sB( zRomdUhfH`wRl1E@OD5wrX+Y66DN74+Z0w$NKjH&axxW`(y`^k(Z*6s>h4@Ta#`nNF zb;rtG-kD;E!}C%10D7?1!HRq+Wf2@*tY3F;JdT>LOM_2YoM`o)$QQ*Ue&dwyH5KAx zzWA$kc#d^A&xoT%iK!gfk(iEu&d!_2l~UlMc=Hj)Rbwfh5{v3t-l4kMvD=2 zemv3LU5a5Bpx&dZjS0wCZ?P8WX}5&e?206qve30BXESpkpaHEj8J|{r03nKAVPc_6 zLqhoL4xV076dJF&;7jsDMfzo{AHAr0Wxg+8A_DSGg`Z>FyV7>M!^Aaia^A>76uV5l zlVNhuM@v5 zBmH&wE3;xsD6jXl1c7xork)GO+Ds$9TOqMzi?e9CPPLvc+BGSx*Htq0*oKfMnp3A~`G$`J7~W|E=82oDec8WOTY|C+{bes+0DKh6;)md{ZKzJ|b&?cc07H>bA&Ux|AH7X5je;Rh=_Ce>U89TVW^Y2#mO-(#5d_-RD z#O-?i_SsbjbhCLahnQ*=JQ4YRv%2~>qUAci_>BkkVY6SD^3W9*ff|h`Fk@a=cK7QJ zdi$`I%B(4WutTgHGUeL5>GHvO;zdT1vWAD2h4US0N_mOjxJs}<)bz3c)EX@JOZf!! zcp9P&r!cjjthC}wsqYUQGWU!-sn};?Fzan|BoRedmWJ#+Qt} zeY_~`XYuNzA=JHN=RY2YQn-*{E&(yg|Gt%)tGlV1!Ic@MlqxwY6t;b_TW2=1Q1GsESY_Q0uK73)<(N1c2C8~DgJ`*aRQ z2>VO9XwPMY@|jcBN`t%3w~=2`?px(VO@_vqj$iJ)%|MHyh|s;$A^bBnj)@ry;#u=m9S{M^sVf6angcu&aOMY&P$B^^4ay^tO zZzPM9{Y@@ND8)E{B3IqhlF0Ek(+*Z`{bw0-ZoYp)-(OY$F%?*FSk$Mzs%4>O(tWoW zw_<~ShadgRA3t6pE6w#UycJobfC#w$wGQkaTEhGx!%>^VYI={UG#cq0<0Cp`KoADK zKPZQs%Vj(LQsVNbNuR7u=E?*0AsTg@UBkvS{y8Fzcs*Zz*xAgN^p8(F6-UCpUkX$( zxKu+YxI=cbtQ13BzzNYqV?o7Dsb;WQ@3`gd!L3$`Bu!sOF0!b`P8LRHp{biqlpN2I zzw68_PDfmb`unP8;ViJ3^JzoK8VGtdR7JH4$o#>WbkvUr*ZSYi{A*2d5=RIe>u6?O zWKfC3+y%Lu`6P>PfAZS(M zK%q-92pM6`vMm}NaGC5g)`O%|2Tf6JdU9*i%p@x*O{u%B^$)ye7{hkJP=KHs+%_TwTI#umFy&|`Jh zl}J0QZqo^?jWIh0(KN8soIkaVAt*_Qk>^cud+ph4#S}yH4 z8%s7sgUlU~qlz-@xfL->);al)`HZs(mY!(pQx4g@fzL`2S9*Wt_>&~BH(;d`vvLS_ z5@=_(LDGNbRui8X=kD?GJnFmDLVJ0b{O;b+8cz#bhJapNkJypLc=td}h@6d?jB)5#sj9GdZRC7`MzH+ zjpo*-3@Sw7+V1jZ8;DI<{nU#zpeQ$l*YdVC-Q7^uks0kOZCc;aMs%-$9uEYGnFJLT zlrR0tb*9x|Sl_AaeINS|MqZj#*V*aIjP@)H$nUL&I zXYtQ5n2!$o=UgYU_}?$5)&(ALiuO;9h2p(jS@%dDQv&)S*alMH_HRe?BI}dHJW_WW zFTcD^@mofaA`PML1L?8j+tTV|%J6_v46|9Grn<|EWib7(vQ~TYed%3Zhz;br9G&=g z_JdgZ37o6I8Bu?X2WD9ES&^^j&;3z=E{*OFRwDXs4n16165sfug#rymL`YQvbZjIZ zrTJDDq5kppjeW=C834ZfN283l=o!wV9K;*bb{KNDni7A83q*f`2?uQ>QB!?$dys5v z5st7^o>it0%5tLJomz;zH?dHiIcT3?%=IeZ!$AU*C0qXb|5> z9pDa|D2<>QZnsBrk9sOr%qn{-Z;9#9~x>Ik2KGw2t3G;yW-dNN5K&4ju?pbtg<1&C?b}hvDe*81d3SR7P zYu@dgQNym9`(N(=dRLVet}mG4y6f81a?ow{%fvNMD4^tx@O|~)dPtf&FxRqvKX(bL zbJoD|iLTg|ZtC+BKj1=YnU&v&zrv6_++=lu%}QZ*zlD=u!1l!rCg%ZRc_+W{wbPniw9Q^v?(l$v?qpmS)vrpK%bv1qfB+zf~f-B zT)tLoM>nO4Z0`G-7L-HVn4iyXcgak;*Mnuz$feBxSKF338wi7aDv&;(y(yolI(rhR zk0%n8=bZQ8v7Ft|>_Aw25CqEo^6g*`#e8tyljiZef}QI>ZbVq?`ZDuRMR>A8%D>TZ zR{Cy8ba@WD?^=_P7_*;+4PLh-mq}W`b_>N0TaQ5(Dl#HQc<*>y&h!}bFyLQp)8$n& zJqCQS60QGYu5|$dUvYsVj15xxl&mJO$CW?R($h`2seGOOSV7u8N*)a6q;e&D|##F-cH zf7cq{&EJ5rVs)S2taST{Mz@t9tJE_evnf+46>ZnOgN>)oikE+^z-X*`<3rHcdW`#z z4?}9@V%rYPE*iXTF4$#qd`>n_fBmjtR%>03tku3wdiS{R(Ye0B2bfg{a-*Al^%6GR>;Lgt-+#ShPFmiL!;;73hMln) zd-C1E8CjAxv{8h9)Mu|YgD6GdgvN9SjtI=wo7l8`Z5V`z>SkIfJ1OWD2yB413ZC~~R>v-fzx*e~XiHipz zOJQdaBSLp&x3^i^zK;?0Z6J%05XC!ZXC5$}Fw98(irFsb%S;w^km?r96LJOUDo!KI z*)9wyCLrP!&$rMLgHy@bTOjK{>OjCJ*IkXQht0y`WWj|}1|w0URa@?Vd>M7ar`xyO zPXiF)EVLeC&V@qDp7Zm3JA%nfRhk;O=PeIRR{nPXGa)A^2k9Egu zU>K9N79S2y9pbvo#@@mGh;CbquDD!+31mjW-|Gd>|^jscU5Pe=*K+4cGP5N5DOX*Os)9>U?Z}&q>R! zf1sb5g3{AETbxJK?eR&foQVdP^E#w6 z{j|Scvk}VbUJ&h<_<<|^X}IH)iQJd}eHNI@&Qw&MufHJS(s#(4u$tf@+87i~{*eK_#?Rd@S03uUbmFv1$zievoLkh})pI36oUW~bx7v0e~SC)Js#kviB z1l{=9b4cOG++n2(;mJN!)@hf4lo3SdiqB{^gFsDDn|s0qzCtLi(4;7bx6e(P7gQ&V zA)711&@$#VRj*&8lD?Npnmq9kULuJ)_*XEd#u{hULl1Y0E}$`61bmVu+gvJ^s6p*L z&ZWg&VdO#05mC)r|E(QS-K}&4m#d3(4f=;<6Hjz<0&H6Scn@X;$L_JtQ)4O(gY)vN z1b)na$9~Vmn^MV|T=X#&Z3#&AJzX|c)ei9+4@*Wx2~ATA-XIHQwf`Ed(E;4LKzmBi zARUvPT?rLN46?JD0eLGeR%Pa|(Uid1y_nYb^hdd+_x_xjAjwZQu52=e;V%4rAXE4n zOp0f(2KJ+QFQ~}Ud>I?vJOM10{#s{$bkyFk*w8F?Z*J#v6U$%u^h&ehvGz$~(>%=q zvb(o6cIKK|4=09~l1S-FoEAFd?6{7N+y4dS57JX|s`6aGPMB;o0%MW;X@(+kqjj|5 zUAhAeUYLr{GkI?1sa>~Rlr9yquDev?^|RBR;rcbpYxVp1_(RWuW8~Lao{ci}#T)yg zMiQM`Gtl604a?}}1^H#=GuJ8LLRFtZ-}D*P6S9-F-Jys_5p74&-4UMFL)Gfz);(6a zpkn~%VUPt$y01{<#dV4I5d(dUrh+Q$?SR+x7$sj`DJt9Vv)#m}OmLGPqT7rhf>PMX z&#)Ycr7Bo%cA%@c_RJ_(YU4FlnF#8nvab$SmqJR6*lbRj8ivEP13tWxi?xZKq1{$e z0I+LgM9NZ1xGMFsw8Yp3R}ZNXKG_{&{m*%xex^?XbVa z$^_{U1%QuLYPS`)g1b{_HYB9RvDsQa@z*E-c9maKS1K~Rs1rL+ESq}%vF(3fO`#SA z2q&&uF4s9d^&-wXbbYy1_bkNEIiE7BQ=>duIe@y2VqWMAO{^2yi2LVWkJM!4 z;hEBPdcM&~+e%P_4M%Kz&DEZ$>_z@SdFNL{;Aeh|Wm;`YD4;eJg&M=`$Y@|Ub-dK} za+gzlyLQ9R({dEseO#lDIurEY7ul+JuHMDxB_^ESL$&e-Z*3)(uZK~;ljWOgiRT{5 z(la|SjUg0>C1Qk3Dg}$Ms(S(g{P*+N{NeoA%e(v)3*3_kqt>2|_Tp+t{2VEcD5OuP zbp~VO>m*C5R)uy^V#~JwYr5(Z0b6>-9=YLGv4@)&XMVRhK6+m7d=D6ugt7xhsYadE znb<^WT=CWW#95tpt_p30LhLqr`sxWK9P=D6e<`EI^sJOGI_-qS=IS%b=YKA9?%vyw zHfW}swx0_x+FtpIK%r5irK+Ig;OO|iNeOcmpMMvPm`alKtr{&9GY-y`rYCzj@2JS1 z9k-;>eH0-+UHJAk2+9h77g)G;v2nK~E-TbmLqWX<70z&)HdBeHRl#++RvM^QC9(;U zzIS@DfbiDBH^U+g8V6jRkTnt7^wMz?cW&Af*_xs#%3+Gw!)GjCc>!CAL@+pVo zvt%Axxd>pWSfh>qJ~{Fw8G}I6p9e*C^RrCCm`X=mrtoYI<#rce!&l)CLFGQaqoE_iXHEVHaag)w0>vXf7ew$LUbbK>^U}a(R>?$| zb6i^!n!bcM7Z9xu#FTtEfLR_KO_w^@pQ7Lw(WZ*}cDM*w-wkbb3Q62bAe1hZLJ=k~ zmotTHyUNaPqN6LiLn-Hv4*?O#HF>3DP;>wE(uX)My)*e-b=n~C`vlXJqsf5%Z%9f0 zclQr>N+swbY07W`DWP?0|JJ;fp>R8M92TJVo0n!G(r9^4KWF%U` z~?m;7n%N zDlqtli@`ho1m;@*VG%lT{AiBI8<-p&xr^bL*G)|dF?U#0c3vg1-4$fR`e3XJCanApDR#bhEW2%({k&$opLO{%|lBL{}VkS;#1xgm219XCT}e zDrkPX-nyCjgQAcJ5|-H>NWfhZfs>?FSE%Pgs^>+pkL_^HEI+Dd8%}?`HPSHJlhIY- zBWnchvIk}KgJ>hhh#wduE6(zxp_L)FJpS*Q^*809)x45Yx|H@FU7!hDTxzO>g@r}O zMGmhsoUm{wlt24HMarI?E+aVvglW@Lu+q-dKq`) z`Jbi6#w9DuZzT3o{28q>ztw(MN0!oWMJmRFJ69EpIk7EdX_mE44QHqBKB;0eeUr{t z{LiG{ysu0b^yY$y6@KyPmIubGv((Arh>;-XTfa8mm5cBSFzn8^+Tn#48DytkanB@V z1!UvX-lDyrUW12*i2ltW_j0z`nWIO7u*6f zU9mZJ9|C^w$|p%BBWQ|)V13Vy%@1ajGrRRbKf{-0yeQ)FOaoziAG>~?zlnh(-t}-y zllK2mN~R5q8lRecK8kh@b45J1u0{Mgy@Bb0_l3J1Z7`o?qws!L(S9)Z?YJ!ihBw%# z1fXf8*ll*1GoQU|+(hM!N0Q1aPMO~Sxg<)Ypu9O7Z8+3dqYOQtzXN(!*sJro9E}-Q z`Sm1N8BXkLCOK8LnBe;b4Xc2$%j&mixhSXGeU|+~^I>^XMnoJbJ(O_sG(@=CqAdD`6PwL$ z$SyC`X3O7RtsgvS42vQ=2E=YJ3{z=Go#kxcgX75u+5PBSn#f+VXwpB-dP48}aFr{c zBXmDhh7z6^*c!ySAWfgXoJ4-AN44cZHwwAJT?d%dDiT@!fWl$=0hr=Y9$E zkKZM)>rMIHmEz5NDHz?sik7(4{th!|;6{1IE%chNVEReIYVm5d{v9~nAb@ITuI@$G zpN-mkokqXOQ=`q%K5n8-v6so?es6pixI?Sj==LqxQBsq4|?hYC2vF87oA;0`Ci5l?)2yR8~)con6{({g6+ zwwMdM&hs;X`PEg4lMC7XQ1WFZ1IF*=ZZPHfA0HQMZZXVZ)KzegoSLZ3Bp6NI zli)avpn>NG42j4#-&dZ`pLqAz+kx67j7KF!3C|I_b(b_17^<3pYiXW}nz zL#|DIyx|%oGmh*ppXT=anu1BdIM8rsdA+Hfsk^WKQBNmWUNJI|rz}R^ej`D?1nY&g zpMkN(KQF=?@g|&^xT+);JJnP4Q0UBs+X5ib6O{y5Od<7K+Q+`SdtaKy(<{0HCg}0& z@T;@d1~XYP@SL{L@x1hh=DY&V*E-}-?%({2vGCW@J1)_dmJYFZxrhDFRr4)dQHLIW z0mT0`LBOuRe|oN5Qxu$4X9D?$AHvXmGim$l|2SEB6h!7)49R7$Tp6Pjl$13lgXka- zXnfyg@7fFOCSA1svNbjb9{nhH7Q?^;MRIwfb;f4*WM9a$6o$Zv|FhzM-L)}foYxAD^N0~`P%@9if|Fp|x(ZZeYe5I?0QgY|VsEHgo{oYLl=5y(_x69Y~ z9QY_+`P{$Vke7p$a%qQvOPGWVJOxb3M`2^{4!Ncq2kpf%;6Cw*Tm~~RZiU=_p^zUn zw(yIz+ji^ZrMa?N(G&ymMD#oR#sI({z&&eo1UY#u4be$BYHr^ zD!_Lse3p&=aU6m!%^YmO`*EJ8{Cd()nvX-k1HVL5)g zAHH_`i{s+=Ue|oH6|EPI5hU;qs{jt=^Du{RDc*T*ep_|kKBU4b2~8pYP~*WOo;!Ai_c{f0RQ3At&Tq9Q}5W+ zz29-G&qNFDdx-h*XS+`e7{8snAHJ?-TkB`;RV-UT1-*xR_J&)6o_m6W6H=i@7vs08 z2XML>Q+Ld`=Tp2|(Ygcd@3aOqx_6Zu-#$G#b$Haghx?xED9nl`XR?@Fd|wh{L;PQH z)~1v}tPk&Bpli*6W_?k3%{%*3#b{uQIY=3rAdQeRu0k-_lqz|3e}{DALLj9|RI=;0 zlV8O&>G{hcJ8Z2VYvLHRA#lH^rG!&7>Dy=G6}t7JklqbMLz79B zx%Z4tN*+*8MiT3xrM$Ggh;tUTy_3auu!_in`CPZ21X~{;}ZMT>%#SSUA$(Gep z*1sh`(@K9tG$V!eiDCy{;ReiatLfDJt;sh^H;7a)S~kZ z=F}^9Is@~$y6`8gD+c?ksJ=CLCJLP%#Szmz`u3h(do{z`OktiSCyGsP*zIZ&MMsTz z-ezAR64d7y@e&MQp-`k3RFNf=m*DpMB} zvZh3-Ukfl>jN1P#5lg?($o(mbNhMzb$phHadMM5=&OhSJrp!HB+?zhd63XlSDzH4S zBYcA5jMnq;7P%-auo1S?D_~=2O}l&~<~TVqDbMbX^{!~dv`@RG$&P@_Dr4T@^gjFi z5aiRm$KLWt?_OPaY?JfCNdQe^Xn^BiDXaPUb6gC~f0(t$R|*Wc@Dyr?8o$NQ1NB{x ziWgQuKv2PkbAmX=y!~mPf&;!oEb#neVSm%-7@J@n@bRhN>uS%DlO_Ii{Y?OS@YXP$ z9q|cGKm$k_*(#;0{FF;!|31ZH2ae{%qe;X{4l@2@vf=90J75g2RM2hbdNBUAhw-99 z>B-BtmrZx4XJ?8CcTFQ}m141c^Sg`C6oiLclx)IIq(dSb{r;EUCs&35E~3qGeQq7? zT%qfsf@-sSuF4+QNi}BE_6mXPL)gJS#lME*x4$0do#|7c8`k>a3lzC}iDf}iP;0C9 z4hEi-B{3miM7>|Qi!WdL2(xw5`blMfT%t@mVjqYG&=DEV9K9=15jWx^gh=$gOepn7 z)w5WBtlrkt$uO?Y`3?fD2d8JOeF#JT0z5Oz_7~GOwS74oKNWQDO5@H-uB!f(s}&4U z47fIhgi~SMF6lUuN&daJ`e~`Ynl;C2QNuBy=W}p3fV}MH1 zG#2C)H84b#L4E>$q?8H@7`b$}5^-|%xz&n~Tc9b&EuskPH!=DWH7`aC1fa_j&6gH-zu z;bBl2tj1y+Vk$uPimZ2YC+w2LT+is8S18@ORU-Kl-?_cs;exZBnPm-o@gAc!r*2pu zS2{S#Fu$gV#7^)hT2&Bl2K5%(^YlwD-Se&hRxB^Kn{7I0QjA+RIU>bf$hiif)qx6D z*TkbkNa{`|Z#x|@pYg>(r*=Jpr0F|ApS~g!Rld;Q4q1<`lwHDDH2W9X%iWrmege#c zZ?m4src+es%8$gz$C|n8oBun2;MKZ2_YN2sj-he6yor4B*5mMMMg=riu@&Zyp{05r z57d60i$c3lPN$5OVXC{oAe?hb%6&ygdX7};Q}+LMr^2-$pv7`uoiwN^Y@a%YbrOx& z$QzfQL;_CBL%a!g!ARd}ydo&ysC~MpIwp zw>@z6@AaV9jG_pgTeju#@Wrw|x4zq~^6jQ>`EzH4XNu?Lm2C#@R2lpd{Aq6C|D9bn@P+;5$s#k!qgUQzK(&f^|h;fj>Q=RNp@#|G^>pMKfbGfbCyUvft>oXpo6MSDx(`q1t^0A zgs>+V+&u>?ZigTA-=;M6@JA!`coqW_kJ-KtCA zrgbLQ)0X*&8qMkMXWDnV?J2$Vc@wEtj7+hX&1Jl?gam~oFK|BVf!o4wh-r5Ga9N!Okk&$)LY8dNvB- zJbTY2)V`uto=9>**?GLw-{C9F-rlU;cQEOhO)_V{t})@q@OVMcp~s%_;_96HMdeRN z^H*6WCML~v{pFVIEf;41xwajYwaezpWj$`Y8*MvcTGxIL0&ZXXks*(xnMGEBhMzxk zDwSx=gxP`>T$1C&Fc@u*?Bd&lyxrtUlurM&XDAK7KvXbuN*6Lm35LYznnoMSY$pTG5dLh&F$s(DHxFq_!pRb!z z3=7U-1*kJMt8Bv1Rp{3ivn7bw_zJ@7JoMZ_z3Tpq1?Ne? zwAv>M)qXoOkxez; zy`^&1z%^VgSO+24WX%%ZCU&A&yCG`7-`~?irP?ai9ffjVF#t;V zs(XGdPRu#HN_{E(J-@hePJ>=iZ_8UU9w>tgMyVt#)#mLd-`fzF#%uG@p>T!+^@Nnj zRx{80onJFQk`EErd>-k~N6R)5byn(w1;b+}+O?cWDXjV(7SZ@VU1F`VNq7GlH+0qC zg|rjHJee>-Z1WCPoCePf37c@9$YAXiRUQ`D_whYHIuPQlBlU9S4v#!AT`=S6jhJ~z@bPTHVm%Q9^K2O-zGG<81vWYx>Lbnq)3^{rc z(b+S{E9o}AJdEKyUz!;w%$%_kSwoDsov|c-;qTd;-ne#1t=!Y~5_tP9VNW>{n>X*Kd+@7?(wr{LF;OrbqCLn6lYvc_#EwWka(A& z>PaVm;?c-c7x_Io{Y_!Muf16Z#+~cVx82A&(@AE#r0UJs$lBb|>SZmaPq@nOTcU7# z9y*Zl9`p#(Whxy3efxNLxrt`m>bOHcd5iaiElDfPb^A_0;rb^a6-JP>n(abdwY2~v zepKfMyY)Tm)6YU#-waLCmj~?MJpK3a^uU!XR$dYx5M>58_YDhsbFn>~lDjFN#TT5DqhB;s zy$+O5p{dV6&r1;IUT z2L>d#Y!^QTBVvIOWx;J8%GKzp1fl-@r{GV|X_^mYWVkbCan3VxZ9`tGWHV8P$JAR- zd&bMoMNbKaTV2PafGxtsokb^yv{Aqt!l<>-$1_`1j_V`?m}rW}A^m|H4?h+k$K%e> z%(9q`*K^h<^%L^`a{06Udk!@cc3e+K0%w?4&W*+w&1OvQoI|8pJlIyy<;kgubtV{w zz@hAFx&2Jnwd@IPLwV{r#G3=lGE}@1>u&ThICJyCV79aR_iX<>XpE7iAGQ?De{Joe z?LgS*dZBw8pi2JW9zXYmik;nNiE@w;g3AP^3uKD#I&4q1+zH)topcJyj=Z9GSKt!^ z-Milq$W3#_s(H&iz{5d2?! z3s9tMo9|pkWI^0zVR|gkkHHu`gkG(G82a~%SPg%T;bMTD<$n8XWWVFq{ughoH5E%H z4ehqC(lR`5p(Iqy%Gf*a^|2S{*^a0F#&M}a0=buaxmK1nG z3Ws-l+i8lPf>YU>Rz=L@1Vc@|C|Z?dK#E%MoKVvLNeUE~m?Pa=GczXnE7bn2Hy1CWNh0o7cWr)F zz>?E;{&vsn4TdB&aI>dN#TB1d&F)w2S8plD&yFOuDTL74hHS(xEvtV2@|dR!?FX_v ze>j#l-;JtXoo6b3FC_#%jXdpBY@dd@zwUc* zpOgBXTY$(Wv%NOjyb!4EaGCJ#N&NV4m|L72=Shujvf6{LRFFw@_}indpV;ymbENJ^ z(B`UE2~Y{2ca`FfzA6G0v9&B2l32~JS6`I ztrr8%y<6L;>cDT+hVR0gTi4ZQp;?SQpEPyIgvq?*d15T$Q(A`(1mu|BA54*_mT~^7 zvxif6&uNv#gVShd#qlDHU6)I(@)3R7=!sg%n{ssD_rE+1@J69O&tYiq_?lWMz|_0q zK=>S$8r*du`bfo?1^=Uwe^OogiU2=TRpeP&J%%CMwV*e^UJD(0MWAV7<7j;@zf z2wTdnD;f9zJSrO_-Ay;Xt9pt)O4!}pX^Er95PM7FDqQ>_wT8n3akvl|{!DxE(0{_q zx^P7CTo-Y-b{pqngHv+~B<)r~nj314k8N&?E2D2PEPbX(&Yyb4gYg>Q|Cc(lSW;Mt zPsFYvI8^QqeV?IODSVm(3qZj2iFUL~$((l>Uf5yXc;*Hk9!4gX#9R!=)EmTa#je7b zdNLWJ`;pqKmodp5PjWtPjbnd`!WCQoOnUP+{I%7~|8P(TUpx9EPlvv|(Lp%9WH=A2 zp@*0LE5ixL4GqhE!ALTzPjw<)@H=m;h=#72H6P_?!F88^nJ`ZL8x#duEFS;~u+oJ` zknwc;BQ_ibylf(#@m$Q5?};7y)}!D70D9?5mWYlp_d_U(N_@GIa~31)5y~H3(jN76 zj>e=^I~0=rXz?x2#Rr)s^;Ro+qX(*Vld&**-<4x77<{szM42DEw`57!Bt4#39-RlQRv+h_6o^QQ{okir#> zWhgt&;qLIub&fnCwEjuMW!so$>ZGqfEIyCKv{Qtv)t!bvL)2*hVkvEpP@mG$K%4`# zy9<}A&%S%Sq;#kX?yr?!*Wr$zHx3Q+wCB3%67k?1N%46JlEe9T6+J&aBSBHfk#%VI z+~E=2OM4@lXKpeJ`L?q&`#8X~T8T~?H5t!$;o*2cYrES}DxQv!Z!8j%jBUAapDr=f zBrOQYq#m?Ki05MTFv!(!@FGxDWPDgoLTrK;{<5DO+#7edfNMlPw7FWpVjDAPWi|pC zE7F5-bk1G8P~(5kmLiI3WZ4O^c3$gvc^6U=z9|vLWo&uR$2IHZ3V_UnpiXgg-Q+FL zf?Gc@^zGUYS@j1KKFB5wF2w{et$}+u)o;w&QG#KCW<29!TjACXIStv;su$Y^i8P{T zpUrBYRVJfD^#mmb_A008)8OsZ>A7-z5-q2*&I#n>TlhU)Pkk1#&c2@qvM*byw`v#n zW4!djw9GI`p`sBGzx0;8J_-1>ZA}Ayuh)GFTc+GDU?tr-dm|{h*F*4;?L}u5n^~|n zO7bC`duY~7H}v!kf%?1Q&L=k`@C9gC7^!|oRJ50{>j9>ppI;gsz^vBv-ZeBN1f3_p zY*qaC9tb(#yJGnio5@Gx!~ZMOmGz*E41W--Yq;vwqH&k6u+D*a<^Zcq4{dQjOVx3 zo)qR)n>yJ|BEF^f(Jabr`s$i6nrq5n)sgFV(AW0uH^GXllF_S*8^qV!Pr@y8jA57S z;!$|@5hZr|j%O=<9((n_{q$z);}QOMI5_UdxAXHFWaQ)vb(R=dbShm&H3s!sHCh$! zLP1+G;_%NaeWU9G#Jg$NK5bLcJ6ZS}N#U12rJOuhO7z*#R=Maa^_pqa@)@6n-)xqy z>i=GYcX8GqKYl!Esq)}2BBU(Qtc9yT;4bv7Ixp9JVGE9_GB{7hB@NLv_F~<3c$?q3 zAUd%1;$l0O-q79dX*^3;f&WcTjaly6ON&T%Ua(0(iGUU-FxfyP#$#|6b#wNs}i`W8%%C(X)vPvEz2 zZv#eRQ3Er?Zjg=j4&nqSW>uu`czCYw!El=vW2GT_X*@v5=@%3qr=L7o8Q6g99QAK< z4~&(yK!TAfMF{O_%a>)Gp%;2N8!!LAUc%4vs#H8PH2LMIPez;Zq-NBoRd4z`FKysd zFWOe{Fo~*z&qSzX5cDr>il({`jM`s9$pfd%G0tevB?1OXy_bHB>}iBo`u0!x0ePOV z+k2XX)6Y*z<+dhHa(*jow8B;`&;2p{jvrz-KCR*0%A9&jaJL=j3jLBo`jRV|FZoFVlz@8ljIt@um};`lRo#B=3$P(2wD&Jt2uoIO$O#M+JdE;VZXSs#kw zhX^p*5IPP{DD4YdF{-WkAi?GQsahzGmA9d==QlvgD2ys?thSbCs*ELb{x`h`P6R^F zSIWLurSJ`YzW5c0v*Hzgb_@L<{Jsx5UAMykj;z=BS(rq>dCb#d#Z{VdO1Z?ip(yGI zFRgDNJMrf9Rmgahm_*CXDnOiSY#5zY+ta_7)k)x+3z{)^|eM^mNv_@W-}#bK=ii-b}_;*eQoUAaE2 zk8Y_&MZTNyPfTU`tjlMJqfj<&YmHw0%=EQCN#p14TS=l)426ZDz`q62c958@o{KI+QLB* zL>PN~HIZSDhbI8dT9f1jnHh5e^S2p@3r(UdV;ef#`yLf@<`kKmhh22dL zVQ?F4 z(03qvpS}0@oaemf$NSZfY38DPy1S~@s(al_%7qXxdw*xb%_~0y`=T%8E@2@gPMJF7 zG)*F=QSTKX&b+R+fwFBePjS~NZSAe;T7bxXFS? zC-Z7doJovFs?HA_)%kC!no~7llbfk8`PdJgPbo`+j_&oLcwY}*5=O2`JXg7pt~zaIYOH$wc@^2EV@%EQ4{i9cY>d-zpi@nx(gHq%!5sq1*{;g1^2Z?#|lXI z)i;`{S5W4^-%^yTy@k<*b-rOtK~a}rvq9Xge__z2`Ze?M4#Hq+7_06 z!~aI$6yh6@n{U@e15$S4YB^xp+0NN5mEn)q~=`FS!QX;wTDe?Q)!>^nSX-i+j&aXi1 zuf2_$)49Ns7e6A>U@>f;+}_QsJM&dgJly-+w|Ng2en-kzpPm#FDN3CM(ig@io9SKz zr`V!wbwn<>NEr~aj(eDcVjkpJR{)!!l$2kFdnlS zA}D;k9x$cR#_q|Q^P~udO3!Eq7?jIz#zDl#lvP>$GwxBKUpcD7M)F(2m_tkXgIwQE z-bfU2Mdg?RJKS9O$+rS_`z7+L&4%5~xe>?n6{kN7RpiB!DN4e7oa;7KoyJ6@Gs2~M zByFms{t7bX85*biY;}6i^GxYW>VoBRiXN+rYtz3WeH3ufSWRiN)1q*eiVVj_-e|$Q zr*GE$et&uwVq#W@5f2sO#xWks#?$5m$BAEu{Z6MT34=aNjF-!Atv5$?waX~mS|jID zRJQSqBo^$RsM73F*!V7@KT7Zf36j(SR7JT{cwl3Ax6R(VePAy{EK1-xy!!SMM;s9# zIlernC&IT)E4kqjNmUOQ3Djo!7DH1UzP>72^u&k5`xl{`9Lyp|d|ASfLqk`5C)^g# zCd%b{wsm)4#bKiN=XHgl>i7Si^+_Ur%8L67_)VnXus;0fVdc->b;8*i-G{#Z-6;K6 zKJk&2amMfMk*Eab$r2r%{oEe69}&fV*iHhv>x?Jl#B}RYC0k(y1d7XLv*yx{)pz;u z;dQ0u#3JxDHuyOMovb+zc0l!!>y1RCwf_3_tRe-sUd7f=F6E&uG* zJPnftnUyF;MDa(-JX)TAnP1R9E?PwKUP{l_$A(itEapn-zK1=I!0(TqMgzAkrkqt* zjE<10sE1qq(IPy$GUy%v&7a>TL!cJZU+ttv>GPkj`fw!WMG61=?@~y@V*hz9^ys$! zKr8*#!ib?};a_b%A|2+pV0@de%#@8=oCzF+Zm3|{UbrArw8(Z#PUeE%(hkjDW;3jG zi{dXKEW92tyUxuZ!fbR84Dsj^20>wOG{*0@O=-yO=5?G+Sz#L(|jvdz9k ztOXkOYvZ=%xkzH`@cGD&sG+rx*2aZNR%XlW-xUa3+)GMB)d_Lu;o*=;lq}P{%b>}@ z#j*S4LkHa}V=}yn6e!CkI+NXOoipp4pvUX9tjN4aGVDzckXwX*POot6Il}@+dDj!I zK!RU;-0x+_; zVyWw-J9&|la!T@b1wX>PFMb`psgT^NNY(^U;tgmb**PPw$mL;N*S*UGzP(L}t731k zx1uH+P)riCWoedxwN}c8IO@N?F6JqPjh6+l&gwSgnE#$uC&gIU*iYVskqRDI@cx%L z7dAQh{ziB5h>||7NTG6mpJ2&UDF4oKC3nlrAVj0am8?-RPWGUh@UFtc9C4rCDO)iO_0rodJ_{_IF}5@k zb~-Bl(5p?g_pp)ig$>QC_`IpfgFpIG69i^tAg|KODkQz-;*V&TvuGZvVDgh^4)*rF zqc^LQXO!96L+iq5cx6bHMyIp9r*tO16bi|o4d>@xijLlGFhFXb3%*e6Kv~ubF?WwP zJ6O%!Bj5^|EuxJBEv4p03H_3*#(Zj97A~4{GXKm~n)y-39fVykBFd7^82_|B>vNrN zh1k>vVLg8?_U;|+i3gFp?{7)ROjuqv@b&X6=TMAuH=eEod3fKP!2nVNm-iN*Em|id zu^V7K%_#Yr;%9hW>!O|2U2fj%aNd2>vP;E?AK+uC@zfn`zS^cBozaU z`&H76v^gGlfR1dlJCqxPqxtEQ)L-gXv+4GZ%6pk`6^JtJbIUfqM*n`gf83S@L#{3Wny1FA2%?HGIMCVKunP@UQC z-19lI!m?VFD2L(W<3N4DPTZ|n-4Hm>dQ;gvK{2^?2HiM^T6Vj#6;a?Z`&L6EJ>2dj zXzH%)?De^bib>#eCrC@% z6;qshA<m*m-&d81_YPL^0G+;Me_)eddKPn)f#z!3^&i6wC-G zhaZE{xaSv^9o9{W-EICDy_otG-pFTsK9eCtW0$jvsEhN&{_N=~a}SQE#u&{M$CJ5V zKR?;dMRF-#nDE7pj?lfw(tTd|BI=si$hRO0&EHiO|;iQpUy+!cTa63VfW)fPbdnUC; zlNSL}18W8EeM;tuBN1FOc;Brkeaa+LUaGqNzWuPP()>Z7|7@d%ZtoD1{scg7^%Q+9 zCsP^{SyvrYC8&o1&MUft+z*fUN2^7hy_f&6N(90paJb6JL5w+AP7;E(V-h7fA!>D$?Af z?q@GwrPnJLn~*l>7EXJfC}kZh%d4UZt$VE*KBwD zTSj3RH#<9Hg8*8C-wr}(^ev)zCKUOTe#al?cz_yxP3x&fPi?ZL~m=Zb)TUZz6ev ztc{`7gf|GVuv3(fe78_5=Ixq~3fFuF>ZD47*jzZr3J`tkWM}s23{q*~uBC{471|uH zI&}7eq702ry-02


    $n5d*n>Td04D9PbeQ1Dbj`p0^Zz-q=-c1_3_jYx3>XHu{Y3 z9J1XR-7XS*XNLJI>UykF*J>8=VlzZDKYq5A432*#2#MvCUNKc$Fl?}i`{MnmtYR%j zv(b2tZqn?Ox1};u3;O4HT?$wCGJmX}OXWL-c-!L{TrsliUFb9*p?w9|>X!irG6^(M zuHhDEWmv;*oY^GqE)U~I3J<(x9&Lq0Wd|zqwXPbLyO!Q1MVIO+I;HA$CaHM8oKy;C z2a&vc%^R@RP?53{qRkHZ;5~av+SNele-zB$epp|Pjg@kI|HY;FoH|HvNp4}JF=6JE zC?ML|hklL#vRW_3h0iDl#Ou}gJ zNX)$DXJj#626{QxvtD*f^n2gC$<)RN22GXFKL}LBS6wM7DTgp9J?o(rI@6BBO%X9& zL-}o{_nN-#_)s88Bu2p21yLNy`juxmvPxT=K+^W z94cmoC^*v43lVxF__8+ z2YJ#9Fu}kPYL2%=&T{pR=k*Dh`K~nX>EnoZM=B8&G4h7MG=0@7$hExRHh5n!#p_so zS}2eCP|w|W+p%7y1)fLYWP91{J#8!!SrRT@m`=3ycoOfDZjI1xn|(mBg!2!z-iFI* z9lJBy9u=ShRW?oPa?psPG6f4w>Vfz3A}|9OAfsv7M<71!(U_ysftfUcd)OfINfWxY za6`o?%wG01+pBm>1h0~rGNqi^F}Zp7D=v0DHVyObjqOX}w|W+GohV<=fq|9aZhlUC>B>7Bqf4}%>62m5ZZt$7w0tjqGKx>Ud~I{pSMuC9y6~E^ z+*`WQtb`tRV^_J^+iPd4Skm8<3+>{``#kkDnHV~yGBH>$<43)Ghj7p7C&7bYi z5dxAe0s3=bAL+!+e*(J!(h}Nz1v~fcH}mGYM>3pq3(57|NjRUskWCX3ir!i35?med zRoOtoVG&%|_X0^9?&ILl0JDwke&=y!W7&%O?qR%gV-{oE8CwtH-vbAJV-~I>;DV)+ zz}lcY#2nJ>IPw{_!+N0Q!w)$-M&Poz@wA39 z<*#@gi#JcFd04tE0aFxPi;*&+-}Vb&tMGl;D?vFxQ4QMW(|wwpk;4jWWcIo!FB zi};^>z&ELbQW$&Fy)!?K3tXWOv?V;v;)XBEhn{(PcsSBe($Zl(@;Jt3Bv}b^W%^PAXY&koHtm zvW;NWJ&R5c>G<~%E6{L$I5a@W{z-uSp&xn?I(3PYmgBt29aq5&tu+D&GM3zAne}NG zWTDSoi>YQa_@U~>Uhmgkg_AuXgcVY4zLOF5dTbxAEs0_MUADk1{`-fU!Mel1M)EM} zG<*-zhY3N#_;rr7mH=@AELt6OHTknoCuigF^SxLD_a5!mqD~+C2Zti|!CUou_XE5* zaThhhWWg8l=V1Z4J}$k86(4jEP=_-tc!TLG<9R<)6f@ZR;lWUQ`jTdww$n|~jS?Ia zjJ-(B=$+pW-iwEW%VD{ICxYuPGn*nNb>Z(u$Yu`N<^17}fcay!5}O3iCT;US2iDO{ zOqiR%t9F4oj_8!a%tG=Ee!`x?g@T<1a6KWiH zju68=@H>~SXT!>9XHT?g@Z zhXYSwXdMbuQH|a;Lu}fjcPR4Lyp!`mWS#A?Z>&SjqER2)U+=nK%W}(6+wqOn3e&`& z9GxN&5vb8Roh3f7!7GVT-ulE@kXY0H6s{EWd^yv}nhiPhuKj?TXO#!=*|yqRniFnOY;e?xHjbYn z<@x`OCANzVe)dU+r)TivoK1YL?TKfwObq>Kx;p13)O#McX=-d&DOMFqFywr1Amq`8 z$z*HTL7#s_)DY!^3p7d<_EpRa{c(@PI1SY!v9k}1mKzLd3tA+-PTgL|!WbMJ3mzc$ zPJXD=^7ta!^C#KaJZw9hqRTfK_|Ch4h!DjCn$H@t5mEM_8B7{06C68w0$?^0WG-|JGZxTaROSLtcfiLDWfXAP0xOwozuZdVvl$_r{=e<0-f| z(vmZ!yOakTbV_@hR()?$O!wCJB>%*H$e~WJJ|FrmGRz!3k zLk<5Ii?1gykPx}PYwVW@9AUxc=*&R0t0`w%gJ!5G&a6_pn)#-#Wv8#xm_;gM zU?aPpG4c?L={p1+SlPh1_$voJX!j2UNM-9iSRD~a%dq_~Yh~VZxVqLD!{GB;2zx$R zf`|`q)*8`{W#}Fql^BIJbg0ryv+)q-tN@u+yw5c1Dp`)*m$IHi_W`b_!b$MHWOY}x zmBfIPn(q$w9=j|b#aC;3_6?yVny6#G)hhSw9N2GB9V6lc<9uhk@SYmpIm_Lf=X6Aa z`sN&eNWsRwU5|{L-J!y?#nE=mvrpwyDH0sSuR^8;+daE+ss!%eLs}anijUE%y$TD9^m>h{?k_$Kn<_41E9d{lWj@1~sO~{0i_HhO)s^i~a0gWp&#SM;7ax8!j3=`MUf`jdPV~}G>v|!- z)(m-Z8z~7_tA;;_m*j~rzcff10gnAu$Z!^ZMcT8 z1|bdG_v0S*D$a!BSS&#cRG43!^hOh)-Ga%F)$~d8PvOUe@ZY+jc4S8&9=s>JMo6p2 zG`q|w;^0TB?W;7HuCr*+I-8s;$<{Yd7y=LS3Cy?|og==e!8E+u8f5tPiK4_3wjco6 zF>8~hc87@majHLlXtqJAhD4wT`?XM)T2Wu08UOUXa}3fmad-H<%VqdHRUJ7$TY$NY zlT}@JcSi@54i{LF#Z)*o={dBF}3&T8x!Ov_7F-qYbneq0BQ43 zpaS+sbK{ABkMP$e}*KhgP*&;J*t5K&+CX?v8Pf5a`;U;blFrFQRxc9#D7S`n

    Li*w_XhnKtOi@l#Gp@Q=JnUkKQuISATDrD95y+8u-%L9^| zZI!PQnT@OmXO&BbCy&dFSQ*qndkQ1ye%iB|998q_j$C?T$z&~K)0I+ZWp5;fA?1cp zo{Q9EA5cqN1Z@f*i^Cd3JCshQDGlln*$GfQi|}-TWTmf8jR_`&1UTLw28_tKsHQ&lbB`$9 z1B+oEnK3m1RPs&aw0f8CtulK-IFz`-tg>~9^1?O{)@YhD3r__DiS;T;@Qd7m;*@it z1<`yGw^^Z)B@zH_?+Y_&%W$!Po6VU3-}RyZC1c}h^zIS8M96GquGfAx^~RHVn7^Cl zsDC%hw=;KdAEsFC5@`#zcCN(z9*XH)7bmpr3~N`{)Cc8a;UuO7(+@2=iFi{7tK~i$ z_O-Sb>+5}(I9sRv%Ar)-nU7wh2+65Nw8;74Gw@NzfD|Pc6S7g&$=!Fm8~!kpcT_`j zDIz1V+E4Ed2}B7I=6^NE>$$t5-OMSNN^}GJ_xV#7MgoabFR<6{K6F)Vr}P-hFzf!- zgtzA{i3S#-clOCE`4J>Js%*?cTzEQOC@14(D!t__|IP-zaxXrI@{G$8fri2kjA{|C zzRVKB(jhI$u65T+HG}2-_uD6DnuO={ZJyi zX2jm9pYae{gaGb|%UL$~@-VPzUw4kT><1i`qla;M-EvGeL!qQ+XD`u<{6=v%WNkOr z7Ks6uy9O?tPAnlmJ{ySZ_S~0>UHU=~7YVF$J?5R~$L(fLo&2`XbYn>+;U1m5V(T{Z zQ7;22BB0wG7%`=7gdGZ-jemadM~H%F^`;d`*N;ruMO6E;8~e+8qn&AZ8b7@}C}(ob zob~H?G+ULi(f^%odg^jY(fAlUSzAn+C@5uvf4e3y6t>H4SFrUVcAzlCR+)0ssFnrm zcUn`G$kCS#Ifi|c`?3f$z%Sg=xwix=ozSu%=`&{%sHr-t;p*9dzGP1uNvJPJZ23 zLmA6i8#~RvBsr`ebP9SP(eq}K0_hQP!UuYL3sneMe({R}$u`Ce`3&v1#cEv~4XYwKV@Qx-t=N32N zY7h~zaOc~Qd?ycuknwC=6h}gRN(70c0SxYDs)6yc#^he2C^&I9f$thdq`m#pz%G!8 zp3?Mrxb}e&JOZwC_K0O$bLS_urp3L003UoXrqpJ!M@PUdZ1 zF(*fS*?&sW1tjv;0A3xLyZ-#fyY?6)?64$I;zQS)4wygciA`!DTyVYcWRxh@O%%8S zaYg>lgUWr#g9<2l%!B%daUDoeJ$+BHEroymD}DM%M`+%f%bJVmz{hVU=2_?Vn7S0t zDNeHl4an_cgxrM=Q@c+)(}iWL7DBAhz$=()oEEm+t3}nDMnN=#T48h$LAkoNdLT`b z?Q$5K=;c~DLS@E9E84DyqY2)1tMLE+s95JiJg|siSs*VmWh(RDGwFYC%Z1h|_?rWX z=MHwUF)B#EsV|5O!fv#Su}F6<*nZ8ljOigU_UOCwb~j*`8YRAsk}zf;)2`wFTi8ss zRU3O4S=V7`1(<_PGqn<)nJKYtGtX~J&;#F1g=*&C2GFGHxdkAX6GUR;utTHc7wWAP zuDtByH??C~U1mR}7P7@?u5p#QX_(HRE+`mgCKQBdb^g85XAUk zmz2-c-r}F{bVk9^{bic;Kbhw^>3TGC${)=fUEdlvTpe=*UYYtqL(sXfbe{JZw)Vd= zq}YTOx^!}Az)Lf4Ht=YUtcc$$Km`70h86AYi5zcl%2;opDBzhSvH+Ww{`S0wLqh8F zk2mCFL@wED;dva%V4)@SA~^~?FWyHCK)H6{yeai|3to#mHGBt0U5k--pzeTR&lvHO zQSZUO#mK8AQJk``Dfb8!gAmtjFZ;E;(S+|g(7J>Fm#CbK<${V)ys_D-;h+cKw*#5x zojjh^WtCZvEY$~|pX^=&-J_KiQC>iaqjMi+wD_?dvgWo)|I+9BX+r(R=zL-oMW=w)`Q@uI*-w0x^;MDUJ zrX}aUpk+OT!S{HbF<%$kx#Wf2`VQ$c4lYXTT1*xYsbEGMP1iBwtDbd<|13gcX?V0E z(DQrl8A;!CQ-^`Yh9U}X4gfm#Ph6F3N2!I#)MAZM^)kHHs4D>WglQz-S`1CH*E(ti zlCC`@oUGe$hU8b*O4xbW-j_qRxr~X!%5eC~`Cy>2ci<(qwh;|Hs}T;N$059GwAM#e zZOe+h@vGcI#@W0)rHNQN)o8VWX|3-S5(AUeSSC^jm$z7zbV1XHptY6b--!D6=fPI5bhw5K8*c$DnSQ@) z2rN6kTDQEU`rpoZJSAQ<{u58AG+)-^YV-Re5+yz00Ve<1Qn_UQ5ox3%iTsa9qn+0x zf4iDok%a0Wkw&@c@P9-aJ!*CVr|5rpJF`Qve@|X=hat0}R4*3>k>`^lcrQ z%9Qi5c2y?=dM6G3&f@EhihC(N-~U5-hIZ10(f&d!ZjDWni_uuMBa>f`!<@1^Qy+5a zZ-C;i$x?5U^=3+3Z1?6Nhzu*DyQ9q?^-xGUlAIoINVi1`LZbG?)@1)Xf+xohrT|=9 zW#)BGH9fhjs?D03P!Uf0vGZG96Dz*(uqM5psWh~ox`FUaUGc0iRXGd&fNEUayv8m} zn!BVzseMRA(AotpW6rP%ITEtrvRw}91!aIA#%f*ZWEqEYyXG2n;2uqoMlMdf zljQHwbS^hPSTp$(P1BwU0^bX`T9Ym!SN$+!PM9>5b>_<#@$ueDF^!XVi+7i%ZHm!! zbGOxG6hiwrqG1u&ag?yeRWNyKg>UUbt}1qfA`$dYf3=L%_UquHc3=w?@UNXCv7N>- zG7w)Al4x?8Gg4iwF#uW>+J|cX&)(zv`tWk3lw*FjCt3A? zE{+bt6>M`18-w#{?%e8C#aQb!nOg=Iz^m^n$nM@m3PWFK(%`J(g?2bCi-o%K2GVnO zVr6j8jjgBcf*TCkw-*{v%u?bW-|r+|tH$mXObVY%~*v z)Rcar4S`5{AN@mBVz>5htcJY0qqm-fyo057^X9~?kYmj#Uo@T+smYeEQ)0o;DZlcF z^iJ1BOnS+$agw8!z^4tu9{yMW&gH0L?I`Uag9j}u@D6kTgub&Lu$K+7mwMgWd9rL_ z-_^-3{1KEar^P<$9I2W{kuu|&} zM0uCy-R%QOZzt-HjzhPSCL;w05=%*Pl!sB(gOFx!Em@4lCIG1AwP|Duh;WF0^oC0v zS&M0;=@4fv^M?EQ&SZJy-0tOX6kLN{`Z#&3)+`1rJSrCbcNs#N@0l{~WlHCT89W=A zOm7{dIwyi>CW4-*@}0EC23ZhAJ->EH&>gE+X)NJ>QI47bh9C7lSNcQ|{UF~xV{1+Q zl%+J-WMqogrv!Jid}%HofDXN>9gc!n;Kh@l?g2FCPmQ z@nsifNVe{KvDJ#NA{Qat>?Ia7X2jKguaFpN8Wi(`qTG%<EO7ft7f_#T_g^Ly*0_`H?t`83ZgTFbXlHhe)Fe(iCnL2 z_9X&TOXh!W;&k@b zWdr}$O7s&0;qtVthT4(Lrr%xKIWxm6x*McFny^=t5_M;2M{Q+*6X4D7e}E8d*Wv@m zf=_zKjVXCbtDtNDORU_c0!2D;K-saIbVmiGq@h8^rB7$H`wHKZ97mdIc%qvON`1juHHY_E4y zR@Uv-q;52{2i3je%q3pOh@PmId(?}xV@10Bvz1nHKb`o#q8WF_BbqoIx9}@^pMdO| zOAj-`g#G6~TF+O;<&Sqb2=kfRb#)@F7Izrb?|T^ZZ_qFA`Jx)wId@r?II^CQI}1cM zN!DFQGSlw~d%*I$vGVmVebLEmqe$(C6_t+%=?gfKmZQ&Ny#E$EgO=MB zK96{WS(dBSdZ&X}L1-}z`iE5t&puRbg57S>5=$oLi zXL=!Jh_kE|-0}p&*>=7!(~7w?Ey&=IfZhKVy!yot6^Jwp&L>9GYfQb5neF=#mwg;3 z5BklKpAVabXSiM{mJ#<-BSbQjUACDU?pDuK!`fQ+4vs3R)?|r85XO%9riQ8+avld2IA28hM zkp7g*l8Px=u$&Dgz9z08W4P7>otb;Fu4|u87HBz*T_94-$O?#V>sY+DKFT=mxo~sV zMY0;JQjofmG6|L?CR61?M$XOSWwB?pe^U&$rl2+Du0w^fy^8HOz0T#S=C1lf#H(mV z|FLdANYSc+-gN_(Y(3tvvi8HGggGoK8-C+)5hm&G%cvDPS`;-?a==p6Cmw}OH|bY^ zDeR-Y?eLtn^`m17DI)^+gyl4H_>z|gqSj{9}i&jCWu;4ar`s|e^73|H+q@C?=Od0Gaqu&8z!CS1cxth zls^|G?UY7Spf7GIpU|4sw2`}Cz@7Z4j-qz-%tI-yiN(w7(rw&3{He_WRkQ#4G5j>m1;8dQXhgkd2b`fppQK0E`exwC!f=?*?PCWttfTSv8Q z38y+7X+EzcTDK!#KC``KI(J$moQR|Yg+O<}>#m?$vxx8PJ8WMxdBI$=7xGdE=82x6 zXK{i6yY*|?cC*ob;EyQj2k-;SDyYy(*pN7K7z1M&;vS197%=wpi=Ut)B3Mt%-d)k+ zB<)rb25m-bxPI4zgLo?TJWHhESu$o^d~@J8202iuYEN<@f>&Lm$}ePDJmw#@5$*mKiJaZPYDbGMmn7@%v<+tfn4uTit(qatI}*xn4h_MVeV%8c8(X z?NYW>QrZT}O3?jAG<$s9H+w&^KVt!eHQIn=87FT+5}w{d2TZBlkrbDlS@$PebUy1p z5BO1Yt_J~Wbhih#9Zeo!3a0nOm0vHF{(wyt-FxO%+;o`wT^DfQ%RJ68V#&@a|~9t(k&FtZH34(x;jo(%ObewoM@9UByluimz0;)P+uVl$&!!er=Nu@JOS zttKsWS1_>`qjVNkYm-pSlr1W3AW{p<((PseOj+#Zc5Tb}a|Elzzkvn`H;L}w&iQ=`hT-T65A}BZZ~E#%PQFRe1rz?G(#P!o*HDW3 z)6P=HAtK5bd7zCVXukhx4@Krdi-(~5KKzt`64Yp_9pbW?&-r~;_hPAWH^fRL z z7(5f47Pi833kT+|87*=8$hI(Ag)?ZQcljJO%d{AoLGT&)DH$~qo{OiR=3~$U2Q1!~``1M18>>n-l-Nh;R>cL8Mrw(M*hEdH|dsQRhrFDisP(8-C zcH7OcX)W{l%f#tv={u*kS9d8d4TVpHCUm{rOy!?U-y5#%I??W?B{3A4^%vYW_7j9v_#j0Hnx8k{- zNj;n1-aG_o_-I96yl|3k)~W>2Fde82mYoa2tBw_NnL~kliHj*a{*9&ax;@D>;pgRH zMpM^{e|8qs_KWmL1=ul5M<&&}daQ{sl$KgdPqbr+cU++-Bkuv{Glh@WxQ#7VPAP7+ zF3dMJh?vXo8{-kQ1uW+4s1Il-%$cOFSBl^9x%0BWxbsW-jr$4IKO8NRPZp+%V-~AE z;C|e=A|z-{mV$9NN4_9Hd}q?e-DbKu5qNW!-eS+5crMmHW+Gb&YIT{EAxItX+o?SPJU7Wyn8w4w0{ei7{%8Vuas*1f3(VCUEicFhdcAfbp2Kn&rnYT4 zd4m=VRxefFJVm!uZxNHXyd>TLD_Yqr5!2&X4NvsGpDuOb*~WAc*d+^gTz9$MyXBT10p;!~eb2qxo@!u=MPV=x zuXTow)9(4e+KDkK@GkO6pVe&Ay)`gcA%bovZbDj}>DU0wn8&+@lqb8mDsg8}$N0_r zl(~cc;)QxdV+^^E`T6;?ch8Q4=AwEHI@Wi@o63HAVvl{d01E#y=-7u8`D5an#hGf0-{-|nK z=H_dzgZa+EBSkl^Vpyw9<@cEV!LTg`9lgi}fq@ox_DcqA#%-bdTHYPbAFxop2PDQO zhn5oqPO9MMAdIuf%`n2r#274_o3%qOC00{KRsiSni?9VbOfYrr^U!u1BtKSpFT3f2 zX%<7aOu<(sc0kDq(4yJZPNOyPX7~AupxeC*eFoLydSY$8=Q!h9ilx4e%*jsKtr)|O z*80pFK*w?BdSitYx7b`_#><#=!8b1z!o*WlkNbk8(EE_JQd4ip02hr*}qzxYX7 z$14X-{efMVX4M?RvQ-kVjE-80p(f95O%!gUW68%pG%l(w^xw%>k7Iz@Ex0e@P~97$ zP0*v`#lwD8Ol`7GFK1Ji*wp!bG{X&9BG@e`u1_b^*us{l>?_#f7I(?{vp=dgjX9VV ze(9C4k?;l5?o?4{q+J3#Qgxa2WVR>R9HVY9MXr8c0lxI3NhK2H0ZZW6;Yn)Y}*%5Ngj+H}Y*v>QVB4i)PgTv>|AHK_p06w%&j)onF@YxiDJjP<&tyt$M%8iTl%< z7M0AKGm$n%FDqjWA5_Mj{&B;Ev^ai{B3?${`fDuP$HJ5rWjA}p%cM$xn2!rrL#6C> zRI7dJkzyBE_MEfg=zU{(j#2< z`VF(Wd%n>c8@RViHwY@3TJRfkw;=VoG*pPQtxaNekuQ*O2%2>si<`}u{y{na#aWU| z#^L&ePVOmnkoR044Wnn#ZB0@_;+nV7aZA|^dpWn^+0JkU_}S*it0Y;BmSyq4aLe_1 z!GJ1sOQm8bz@~ogz;q1IwY~s&R;9e>_ljPghS^k0+eHo2E4J>8pWR!Q!^{sWTRZf- zAADSaYl?1b$KudPhK-ljC$a%PSyXC+%+a_G_Iiko4mY71qhe;AZoE@1EROJ@Btg{TXM#Ta1d62CQo7Z z2YE&19NgfG-+^A!K_S8bCxE4>400@lLNFiqyAI3o*_r&WekfDvy?nibC1po}w-*j!oo-J0hU|RczLRmndx{03O*`8N% z8z4J#hWs*TKj`MUfIq~mZ`o6L)l`IKuO?%_~u$Gs=c%hO#{&$&tY zZUv~guOnlT0gTszpg{}2e*My@b)XUv5rKvRK^+TbhN1HjD=tRGBBr(bDNK(P*m1eHtd()LK0Tl`9)GvW^O5YWm7z` zPO$KL2OhtXcE@y>W_Tc3W*9tY=Wa>)plsF+^h(Caobfbaqb(s z9FG~xia%)%B&>E1Y&Bh9GBdW(ok)QsiARVRPDpT;w%$Y~4!vt$lbST&?`oiG&oOfA zN4%BZk#DH=f;k^L zghsnc*YJg6L<%n5+v=D1o-+}j_YP`m+?9UFND56mu+lQkkp>{uVzb!sPmZt36#{6x z?7s5hsEv(vznwt-TEt9Z{x9J7w(nN{)r)S3_$S(R`O+zMd(HcY#PXgshRj|1Icc>J zOUcZeR1F5r*YCD@C5nYQo8v-h^<*=z-G~0-*42v|&lRZyOjYg`v}&ECor++Q_^wklW~!2GDKJ1NVv* zR6I^O>To9&+#l4hVmgftVqor`6#1&8(3KBi*{JJ0A7PlslgHr+V2LcZ#FQA?4^n)A zM56|k$z{;C{^m>l0JGL*p6+w9Schrb*N$0g?Lb0*m55~gK;!EY2@Ya1(Wq7xO&wmE zP~#<*AJ+m^q}3ub`CpnBzH#Y;%v&Qm$CUCv%(p20F!xUH!=Ve$KT1wa0x_jcJl#>xl!o8v}Og@-QT)&P~zOjzfK ztp9qo3242@h;B_8Xy^YYZaKq_vGVYs=t3(PbX(%^$<>XruqwFax?COqSRGCXQpZ_q z+gv&H8^6*DCfb@sck((AsVw35+Fayj*9Q)xYzc&W;>)Y_Eo1V;>-X`570cd9}?L5*M_s})eF;Af2V74OnFa|05> zsXB|H&@EHB_=Y(0+v?*^?M!<_Vsp&nCVRb6mzthVxtmk?v#cUxDGe^PH^bw`1xI9q zzDKki1yS!qtcu9t5vi*u!Ma_}$4Fg@p)c)*nS>6B>~@j9GUf)m)NWRMOn#r`UL;zO zbAs?l#a8l%jqclL%{J%Jc7%t^E#ZthG~CTCy*IXa-j}@glWzk0=_x?DpV(?=Jp+{gmyvJz2kstd3sq|D;!gqKT znv5sZzP;B|Z(~Ck6@o~AjyodewOuhM;gEXcYoBEZ-2lB^xz;vmMvc^%Q!7+`9{Q1T zA8K9q+Nty2+)6DHUNa_Lq>)c{62$@4 zXQhLo&WVp2T2}^ID&V&H#KU^jaS8{O8t^vnn#CG|fuYf!6F!Lgi$m9V<3r~qtG-g% z8i+Xeg7#Vq)YYTv?V0&f-dvno7p$dKzTCDvSNx`TKZ&S4#xXevAsJSM$xoH9_G+OZk7g)-LOd|P3< zx{#z}ozGS9!=j-np{CBFzvBq0eAG)!omK)!7Zvea3p$6eJpY3wpH85&Wiph{wwn6X zMI6mCcez%zGcag|7Mef37n%WsHpr8NKD}RkHdYq}LA@gfY@yLv**ZV;U3MarA|YV# z9>O@E%|AXKRv16$`YgzPx0qXOX-%ht2FMPZZh-Kd%lO}wi^cXfKkw8PTEFn)LaD^O zIb?_ugYI$lijR(vf8IW@us(F)Z=5OI!Mr6VR*x4N#`kvwm&7-sej|-^DP_*Ws{u5qS1;w_R~rt&Uh+&d#{{Jh*ld z4hb(7^9M+s7r$YXpTSEM|MY}o=VltG`Ln^>CpPZ6ABS`==BjKFgh>WO79>PII6X%3 zWZxueh`x+0)p;VbdKlk-8lk^D#udJog+m;oaC^ru8XDU$Z-)Pqf^WFnn8gql5rg?U zU_mVh8NaOZe}}0v@4u8~GI(B2e8_t5o)8&ooD5tHu2Qw>cdgl-hF+*xeUT$f9t|Qn z94>Vr?Z*qlRw>~efE&BcjnYZZJ!Q_sm!VQOS4!kyZvDn;d#s$0|A}EAUGm&+G1VQQ z@||kTU;I-GrsUOY4Zmp{8s=fEMYr=vV5*OmW;*_6CbLXwl zLr)T2GBA6h6p11scx|I>w}h`>vZsAp~8Ek2ZO^H=0HFm4|Uxw0bpCrF1#o zBQ;W~utIH6hMll#!ud?8u-3)wa?Gq)tBrl5Ud)J#z<~|MxNy56S6!fj;Td=!r{2QH zaVQY%k@>WpKw0cPyHo5uP@C-5wKra~Pq2N=7b8e%NQq5hqFk|QHCzmc%S2=XS*8kASKi0d0%p)5f#zr9A7rs5;F-z7xGFu3XUY! zOWXDRuN3I3%r4Pr%wSjQ>7)O*12RwmJSrcX&^I2~RECYE$g=A-Pv-cgH*?di0VoR1*soaUBm0-V3mZwa3GogEIC%6wMZ9_BhY zWIf#Qc<0~tAPsX zX5T;N!E;&$V{BS=tfs^{Qg9}ac@^RShPlvWkqgwzfa<^z<3XKB(;&ai;6qK^|At<* ziCV?(*e^5XrZ37BRti%DZ9rAz8a#H7s9X<4mQ=GJX`CzXrE_`TWOC{_{0lMe54uD= z5;3GQn<9(OS-{U_K$9;eQ#kGz1+@W1T2Y1reU7Pg-CYQUjz-)-u($#-4JA;*he9ubD=!;RGkIJFkha(PN>PwzKz;4K(`ZcZ$JT|eY>RPbP7i`)3hFS(nao0+< z*mA}mxI=c864X);X$?OLOFy#*G2upjJZ~ZG*6|Anu%6Ncja|P=^g=W1`q1YS(PaSf z2@D=c0v;r(Z2TeVflT?379X}1FY~$kc&ne{?#eaww3r==n-9K^~YRP;8q6P>A7zbD|DUKzGFF0xQ3|T z*Y#C=!WCo6pdlVJbrOO<=Uc#~(ZrZpI^I^KUypYhs(4m(ard8kqCfirdh#!hhXaMM z>+0X@WDVGa07E0Ai0J6Vh8BT40-Rd*@S};s12!>v$|Gw;{~o zamE$a)BP3_VK2g_Fm#9!BLrcN1Do8WkFc-nrVqhblns_c~HI* z;uQy4`^~b&qZGb~=ofXpI?#YP1*P*knVvB_YU}$VkS`94M~hRM%9uLds(qU)Nz`zg z_#u+SA!)quJP$IHL-QQDi;&BlVJ(Rgril}{!Do~fVrCBw!<+w`hoO;-PCunnO8VBS zF;*t<`&lK7*L0`!i#qR&Q9!os>z}JOqtj`0epz1Qc)AEzn!IArlNQ=QtGy2FKn0TB z(_E@P3?v*X7w7hTfll6>i>ox~Vm%8T&UZV1yEsc%jP1nb?8#x|`c`Dru4}hA?{5_L zI>7XE_@V^F%BfJTT(`Ts`vDAyA?8*pR-%^A6&fB)rl-@Yv);3twT4#tsTs0LbZIf= zLxtSB^C2M5DIM?@@4ra0y3s!W->ZIYEu{g6|4RWip6^(k++vg&ran(i%Ouh@XLMhW zg+MD@9Aq_p#n6}~oy}eS+|@a=uQbh!pYw~l(V(0EB1|sl6=qg)m$_EY_As~R#`n|`AXr}GZ6|5Ntmixt1^(8sky>TMiN4)<^}BmG#z4~f>+vjJr!+p7 zw-5|xb+TA_hFq^gAKGPak^-`c0=e%^0K_k1>C>b95m^Hf#Qv*3aD!yQPkqp!O%1ZA z48E@}OZrUCKt%li%I&n*xnVIkH=>N%I;l6=u+s~Xi-ny5%6)k9wXa5O@VA2K`Sz3vdd*gw(dxM{x-a;_I9QWUhld8$e=b^3!F#Sr2*D=q zOu@Alw3T@bmc1h3_!F1W5xLps1Rg4<2^!@VJ+Egb;+YO!XpJ0uT~(Nkmdjf1c!t5V zS(5x2Wg(xx#o?)e8AclWs zzQ?M1gKj2rgR}P^ny$sPfdtLD(91*%Pz%y%npf2W`26A^0ag^~nNnV@WFltM{7tF2 zI)2C|o9lD2B#X=YxB9Qsn*A7!=VsSyb}*#{&Az-XeXinNTMMiFgx;Q3m>*E4L;GHk_^cb&-EJ}hONL<8_;{P_BYbQ}%C7vyis#oxB6 z;a+DpdHe?~G89%#IebXmkAv|(Xdaj4V^)`kCSJgClUh3f;iP z>-k*bLS{sHHJ?)%zQm;|+-nBFN%=&)!U!Du#loC3^XCVxIZu6jFGHs4niA$RJY>8m zIPT}xU|Q|%$zqwbAODjCD`PfG(wy5&VPG@1lHAXb4`$XFfJ5lERqq^im@;2tK)-4# zWskrH_&6CgIL10v&XBQfb<)ymH>TADtKJ#Oi)Q~LgEOkOPZXw@@(G`-4T7D<83{Ou zu}~h0IO(D10sD6^?a$#Tr`)+XE>_WbuD6mNL`zw2Tmdha>i#ALYl?Os{^9jvokCl& z|9h^PTc$}i$@4oA>IaFiONt$_)6&wmKAg!wb|+SEbl$zpmohguZ`^l8BkYZ2MeW~Q z4{*zQ*c@H+-3VLX+1tDSI)!*9KDR}2S!SUu0ZxvB!%)>VyQ1TZtc5Y z`Vy&=DO;NG`hdAm=gcpxb+U9d+s~XB2Tl*!46UNSX)wW($o(8iO3xl9AW^HFBlU;= z3-`FP^0LVn-d5S~cDTM*Bd8j`0l;7E-k}O-dBhI3J#-3FcYe>kuFFs9%6U)hHq+W+ z+#5`)MRX2>mWfMDBU@-38`u$^h^>x|4Z@AHIesx;ml>^Gf1Q3Q;^9by#`4pNzqPI4 zh~vY}yIzss!#W2o4vd0z?||0=S*ZK?LTP0TWf@fp)mrJjNgl0Wv;QzVG9m zY&KtVnNHL467lp<+{@&*O0BXEFAJ!7VbUJ{Z|2YACwvfsuZtJkZeMokPIi!uvS|e! zMU2UD|GR0LZ1e596oAt$mM8m-BDw781GL5B{hg~3BB*6MDER-tvdvA%drp=}@s zE;}J#@Tk<^Ku*5dk;Fp|=|Qd9M#0zY?>a)C+rOOMc&%Kl#C70utA)o#%AcO!ip2bK zbNZtRkdlq&CLWm0wHmXoeT7XpqLGJ`1vn1hlpVqNW-12p+Z;w6BFe1fcK71*pNe;B z7uT;f0ON=Ec{eq(=c(CN8UVbEHW7;f)z$0}f3_ZD&k8$!(K@_~qdPLxzS@Eo3k>EL z;4bQIyVtLgK>#D%#s4N3BUWb4imYo_v9lwGH^_te8&69S2cYiw!^_3@JE!jre#jn-tVQ+ga^~&$ zC1{0OGwy&61^40*w>{x^x$VN zvZ53cfa4R}(J~n!iQNCHZ~JqJGZPc~X-K))7T;9Iw!M4w{$p>F=UkEo;?Z)5(zMu1 zH{bXSTZ<^L@AdUj!$*%BwpMb*q$MN1u`ePLy%IQPs|hB}TC9u~O6&z*&GLt7*kY;& zl1<;-?k@Vp`qPrVg)4BviZ1g%EqT`L@y7RH#?KxD9y!>I3wAdPWUcl`_P&lP)%%+D z+C}tQv#cAxVENx*B=%bcF=a)+ZCRuq3n}spIJJDk%UEEON)lU0OF{w!7YUBZkxtdt z^58BdlWU4Kcq-!`zVdqa&l6UF3+h^HD9J_1X+9r?t(32YKaRms4A4eHOq)YkTn^ZVcf^7|F!mBJY;S(F;xg)0yHlmtlFHFZL z6N!;Zb~P$6o0h|0HQN~+nm&K-`QJ*OD%`n8bVoxd!QZD!$jIi{3Lq=2^VD0DLFp>| zL8&Ql$^I8%i*@dadS{tfl)0|XD_&Ls8iW4;uDJGjenTexl+2JSDVWp$S|xSf!dO{r zzxLkWnOaIDfC~>Sh%2<0i(tdgq1E*Fz+SY6pEy;*7R?b_u3#qY=D! z!?s2@?&hN2M@e%PhX(GqkwB}8oR;HHl6xu-(A#aGOar~rjq)K|oKh7cnIza$;*g0k z@jpnwN%Z#jJ2Utz1b4>I~dM`pU74;p_7J;^?M&gb!ADMb_#b zsH@nNDS1t=8#Ws{>*&ha`OixpChtDV$EruD^CS;ny}r41Uvp*+Jnr*-C)P0{%aphI zdnOAP&^Yp74|b-N60kh?w$j^Xx(VgP-XHH5++Az9T&cK;CeP+m?SP}?ExFRaSZuv9 zcCa_RboWH}&3Q6GJ2NpS!g?8N?(3O{NecEjdk6=3D=q>fV%Q05FSlPvY0k4K7p}ZE zbsLPrq|CWJstJ}M(F)`EHfIcbDDKm-gN1fALfHAGP%d1nDc%5=VKw}<;UoOWi&*0$ z+O3N2hn|T_*xlbmoGc$^E(adB+S{5E+4Ks>e3yij4*hm(u8o6(QfO}_^=tNe37gPk zF6EPSCg6?hD-%fN`F{BJPReoG&82Q^ZcFr1R~V$YIqiB*|A)Hs-yqTEKmtY6hazSv z!>^j)E1cU+`AtcJe`a4;TS3jU{B0!Fbq8HUn(32A zMy}d7IdpniU)E1@)2=MP=5JNzoUUJM49&SeehTHNUCSsz3<%(6tTbu*`SUw<^s_m6 z0sP@QNEez1nzQ8I$-_>gS3!M{ST9UxfoJwzp+5%EWSM_N#^ed_;OHlC)kD1)QSi>l z0d0JBb#(%%!XvFU#<6u%H-DT=^Pjk9?}qcv?|{8IkZPc1l@AWnSKgI(X7Wof&|}zY zh9&tpbZaoWUG| zwyZ@wvoQZm-`2NX;3>IAe4ml_fK+@W3M?ZfsaOX5Q%z7-{pTJSe_X>R^w8%QQV`9P z`AnJ4JTlMi_*V(i8wew0A5WINGtKvl{djKK$KhA+!~&+o+6n0Y5K{e}MK+-TbWu z18+VfOnhH$(G)Hj^9)WpO3XGh1h2y>$grig^dfH0A@nX+q(v&$C55235e+9vGb>Lx zL_5u8j@PXp+Hn3qawoqR(U7laZvgu*1_Y@kpjfak)=MUDzR+szw}{ub6Msz$ykj>T zl+q;zg_)9z8#!II^Q(P)i+3fhc{!-=e-*T{8kQVGSp2O4|Q9 z?taWt42LUwtSXIGy#2E#@gIR^@NUHJ+;;Xg7W@6UzWWDFwdNLbTNSd_=;Nh3 zHgky1JS!xtfSA>OKnz~Rd5Z8V$&rVIgx@vV2|N-HSr-|tXi9}# zblGNqo3^(0L^D;YG1NU_9rIm8o{)>V2Jf|??<*R|TOb`1FBr1t^DRY=H~7}*oW_-0 za5VV^!t$2ZxWEc)3e!rMn}f?3$F@%S)`I~xakTqu4po}?_C06E4YEZa^=m0`;I=9G$^t~3+RprWa$_mWG&TZ zFw(ZX(aWO%Xvd@p2(W4{od6Ty&{M*Eim#L{*SfeE7&w@hpUQD7uS4O+ zOAML6znR5=6H&pzD3&h&I`i&Lz>5hl$B|~gV0lC-vEZTOYSn3JN7Ji=M_>-`fbYn% zsAXA%mm&(PW^JKu1+rpyJfn<8Ggm-T)@uga)^3htsiKT!>fAGCD?Rr5BqQAqF|fj? z_wkJ=1Y^PedCG8(+|PsgxJS-_R`yRnO{Tz9rf5y6jK(&GZwcpaafr)qg1Z&#HJtWB z8eGjwTx2vVJ(!C>4Y_!u?ESvog%T8m3_t|<9`T$m`HuO1lHft=(UUE4R65?S(Wz_2A%V8uvbTo1H@81!|#u(_7RvmDLT?8{M}cw}57k z%SRp309c^Y&3zznMfZLX{XW&mehGtiHdD{etK^5_LwutTWjYP-n@*zeuAHIelw@DBpSAf0gdzehV#=)jr}W$|J~ zNKO8@O}DWCmro}7y04rrdmi3^apbkdIZ?`^Yj9_)j|GW2WA)Miy&0PqrHa*Z1m4r< zIv;9!)8WqXB67K)p9NwUB!@0^G$xk}ra#@V7V=?-19coWw>S2Dtjj_}+ToXWRY1tF z_NO)3AD`x~nH7AHC1v;|b>Fe`)gyOmW=X9#;xc4bqpWls78}B{oRm$499_azKyg8U zmT#bamc(?(zJT1eGI5G-z)~Fsy_%pTYiyX2sr?Z=JJ{||h1tE?I7uZ)7I$ZayTEk_cHsLkf@pg?^gk&O;Ur=F!xQxb~W z@8Jh<*tgzml`9!Mr0{i%uNkKH$5W&E-`*Y;|QmFu}a!9sE+qm^pMlK0xdAw6DK z@p>ijb@^gf{GH}R8xbBOY(Gs9I*24yg85Gol=|&^F^sc*F45)Vd0}DuPUtuHq@J*# zt5O$!UW=xl{jOe`wM$1r_m-}jP4vX%P%r%sM!nhll{!vz8S{4PHS5!2 z&vNsR25KrLlI1J{^jG`ZCMiJ%NmkV_(UWsaS}eeCKs;`@+qb36{yl+kEJIDzyWQP^ zJv?5ND6m=bWvDv*ZM(luWyJmrI%Q#-6?jH>RihHZXG8n_J{;#je7~-_YbtE@ zvwk4#<0+GZwxSlKGY8n|vxy6I49=_GtfQNzMeu1FIx-c((;yt{Rw?rlSr9< z5?RIp%>r(DvJ^8?kUf4_islJgcQ$*DM3Vl68u#L0Wx0$-U#-MP_K_GpHO8)W)gZFI zoL1d6HaW+u?&|3xA`0Eltwx+yaqh|`CdpNC$3&t*jlMwjdxWS1x#BhS;swl zn>?A7Yi$>&66wczt6Q5(lI_fxV$8jOf>%+7$2^8GK1e7PRR(>0TyQfTxz=Y(hTri# zCrZ=UuFJ)I=(}3px~!|Rn_UW|%oAbnBcyw|#qR|pLUpC?5co}(YK?q*hrkJ=O+lah z-~1Gwza;?#-QWz3EwdSC27E6`T z0Vz($TCQ?GgQvhCSWQzbs8>>&>VTtH=QQJ%$0z@m0gsKp=c#mSa;&#}_atcBU9&62zrZ$Ko-?!!Lod{!tB$g< zGiZVbL+n~$)S*|Z$)2kNCtq4d<{l!3vEzG1D3sC;?`)YlwC*C4R{IqLWZ5^hl&Vjj zy3xnTDMXPh3_3m5lO*&#X!&pSv9iCx>?c3s|UG8-jx zbaec#`je=vY|E=mTtoz#-}RtCN8u&1R^Xm&~eeo;&|x3{-_ZKFd&l#Glq8r7!b4Gu;S zGcVUB(x#;{2zl@vyt8ADg^djn1Qk_ORA}EfG&EpfVZC>Du7SCUqo>-pCrTe6mg;w< zWShN*XnlC3WM;c5K=^tJYSEn>SEUQ@GTh|mU%ci0eaEj;(II{?Ptc(T7}(f(>96qV z!I)gY+nC`H-C*v6ccA{ET~&2S)ic}aV_9nca>Rq2o3NR0GGR2qnp2#=FMIRsD|Ovw zf_*V#CH3D2e*GMK##C8w`O6~wciXJ`Pq!IuS4eL1Pm3S=+im8L!#K`CYA65InE3zG z>c-?ht!@AZ|5?GA`ai60ew|#B8V3hQQCT{@5az&@ zA1~@G>R)$4RWcQ6kwFmZusoz1D3%|nt)mm?mz$9A&HrCV5ry#e&+(gx<`InX(#rqx z``OIBREX{Rx3=K*>p!k-liXmNs?y|A5BO+BoW30*AFElF3|f?b2} z2v_LFn?a93x}*5-8`H+R`0N^g{>E+KUVx7x$54v_Hpe4Nca3)IRTNel-yWwab$alX zXCN3s^;75>hv|`$khitKJ_#!d$?c1l&Ov+%vw3+g8q@gW#opd-Z@#dcxWW92lQ7{~ zHEZfd8wAS+)%6Fy>+_+Zyc-MVZZwjCjh4;|m4@8z&#jx3x;Ygo3<4JRplTF5V*dcC z?H{A=yNO%IL>-X;-UUNMPWY@~sSnV;LP|y`=tZ?Tw;xbj;plV#nTC+w z&ty#mfre&RLP>^{r}ZFRK5Ha$^rj-X7JRqwHU4w-*+C9lVWe-&)1eb)`|u6aHN5jN zLBM5m_DW=m5yse_Cp`C62aA)s@S#^qQDz!1@r}cvG+PD6r0*NpJ$L;yxcs9P1!-}n z5Av{4YhPZ`r!Vc}vtD+o-I|NA$)hl+(sN~^W)6o=DPb{oIj*~LmB7I!25zE02tDEI zx?gkGndSQG4tg%N+h5YKu$<&G+i9c1ve=)Vw4*6z0nd=~+@F5hr2(9=@2gM*9tA6O z9qBU&8)kOJ@85FuYj=^$pc}#9*leUK(43h;EUjIM<3&C&%)@VtDoG%p8*qQB0->jHi|K*tX=DL!Q@@!4Jlc- zRZQ&|8bJisFD^K?@T-e`oy>(5<}=V}MP`X$dx|fXqVrs5CdY$Y*7K=I%b1ggJmJKi zGut-^$JvC|k48kojOu+ylZK0d>*f=+!jJsj>lRQW#;Wp<@o|#%8vD zrSx=0x$9AvAvdnxpU1f;dqWd_gyRe+NAD|j9Vp8eXV7v%RT!p6kX`c7@PBIo@Z{5h z2b@h(^k=WA+Pk5PXy`|#rj1CN((e{^WZ|qiLs|CX>!=j`a;0Rh9jMsJ!-g}*Eai51 z&7pq2*6FBBycGr-T8LnXFVUdH(mg)pmp!LTfu0SA0vJe`bYBE>8;uFhOq@i|y+p%O zE8nUBwdd&~6S))m=dFXUn=i5bG|>RDH`yEN>6M}6g$%vxyoo)E+9k=3aU&^>xX)>thtP?gX76S!6Be$&ZRs3OVEG$P`#fQgGcmRo>>f6|cqL-n zy&Mq*-aUvG9y#jQE>xry4f8nAu(w6eEM+bNW#nS7(I!%2O(t(RaXhEY#=e-k6NMZ+ z>{8M&@P;#1an9&1giY55#$5#&UX6Mtsudk|V@}6}N}NLcZGNkZAhlt-W+NVw0n3kki_HI_qE%mf>u6KGh4AHCp^8 z9Ue-4C4S9xH1zD~6{{QIsE^Hwx94t3D4TX!L*E|d7azPGINQ^+r3Mg=&gZVW7Ml5O z=$hCVZtj}m{mj|VTiwH$)l5^O-T31wj1En&sLT}2FS|ji?eU~CX+kD6R#;9I08Khs z1>?&Lgtf1LidfXxd>O$4aJlMHp-ZpSau0O;MY`@GZ zG`EM!rzbT!GdJ4e#klPb)ShRS%}8{>5MgL<>i;h zk*&Ui#Vf$*-TnT~q5rm41!3@NMjS?*Mw zdK~P@u>F>#&LWS~8<~i;l5-X(xzT2#Y>8o?GinjpWl19VrQSekUHS@KblbyEp7*ZV zuU?djwt3~Ojt96Tk^D{<0Ep)B5&gG@rt!%(hK3Z4%5G`5u*9iABb{R?$L%sI5aL&v z>&DV&12Vcf4P*Wepn7jKoD`3>1B&~df#(NxDV+T4c5OeJvwQHKb8qTvzTa_PNz~SxNox(YQZI{-g=TETEXthD#f?z#9W z?{q!i5_&*%f3%$QT-2qD77nm&;%clIZ%P4By)uMO6;2g|$ zU%_Alt*=V8ddQ$uE1kz3%e+r8%VMLx?8o?MTo2;7K0HyB156W5;=ZoPsVQBmuhi;j zFQ^BKBGnNc&$eYlj7gRXs?;iOvVXnwc)x6jh%k%U zlxdDvp2gZ-yr$4eS+8HCk6gKk-Oh@lt|8XBbVIo+SkadWfM$OH@gI7PU2Tr9oJ&4J z>bBT}t!MLUg~OqcjHWgz?w**8wL3(sgM+T0`9%~tD=Rhn;mFVcWDDmjn$POihVD8d z3pCK`mDuw?sHbe;O_#~A&{DYK+S^U(2k;1>W6V{DL)R7+9`3qutXKMD-($-p_i~^J zo!6}iG~`l+MXV`@(QwLOz3dz0D`c|~bnxfkdbmMTSP~8lBl8NRmGBwehCDKumoEpe zfmkx`f_q`}U-YrDbG;&Ggq}mD5Rhg3bR#s}YqZt0bz-D*SI(ytVvjTG<7~W~;vU6R z*Ig4{$_OHc5DrjLQzz!AMOz>hZZRs@+kq>P{XlLsl^3IjIEF=<;Ic_)#$r8JO}-u) z^^&WN^m^gVu6hZ!(s*VZDmJ$f_%moLcQxAsHCQzXymSDUq34R&sQEozkDkhc`jUNh z>P7Cudnh%-`RhEVjjM|TP*@HrF{si`;s=1RQSbM(tNr5FwCnA#9iM3yxE2uB#P7mi zOW{3GesJT2M3BRAxEP5Mhuc7`p8?q1&eYG~f$k#vP+f+~!+WjoKGnVg!!y!s{ZqmT zUA~&CM8B5w`NM$HCqK7`sgojyp$yrjx`^&6dUd?Y5E5$@o5k?Y)zKBiP_gUP!dcA% zHk`4a7B@G|YQg21gEtzP1E=A6Ab)ukr-h+FDW_T87fILYM@*aqH~o3Rqd5cQQ8U#} zy9x)|)v-cx0`e5y(585&D}FuSaA-sI5Jf!b@(=E_ zk(8~@H$Uf%zTzE`K4^~@n0F>7kA4b`0Z7bN3Wltwd~MKPg=}pX@Tqhj4CQ5`$%)Rl z%z1c~*Wo}kyJ$Vj5YJ(!lzcp0mdA35m@aS6Ud7vRjTi!D$|~VX{dqf@ui#i;S8RbN z>J0-t3O|!XrWv|zH>Vrt+uODICiCz71;4YU526r7)JUd)<2jVJy-TfrjIBan1`~ll zbp>@ck%vJ;<0_2)c4DfTA!_;i{Hb%V=7qDOS1yPr0# zg)&7eE~egE?Wb5!3aOh}9Cpgf{iaunTdhyN&qbActBn>V9Pot4!p`e>v-1R*r+!5y zsp-Z6@1_gHLQL5{t(?u)fLi-Lk+Z;vhX(5MNr8Ck2GW`9;s|1SC49fp=un+z7- zW(!J$Z20L}NaSFRy=ET${sx9&RW{OWIN&u)^=yp+cMm}WJlvWQ>wx+#=?a5f57BtI zI3`yWx9oNlK#Fz?g}KZotC)_&A&o%Q59aaW>g`|aK*vfDVr;*MA>MZ4F^ht?=OW@4 zlXBb1a^=)%HP>&Uq$o|uuCOfU1H%ZE4Y)0u@P?cq4gS*)WS*-AWWKAqM?RY-g~#?P zjZC3_$Ys{#k;AekJ!T5$tFY*&o%u1F>+h491kHCo#6BYlmoR- zuyctkT6xx^bxPA%wUG>T#R+wQR=RT&-q5LO*?cP2S;FlC8um04xj#fmc%1a)_J{un zEQce}@?D)$Ti!gpE~*l$FXh*IWAIfKg*|m@LvM5c28P7TccWH&T27juE}B~N`=HkrHqeu^)!pe*;_V717|W<;`*h@5PK`=1;4ut4~f)pcIF>8 zvW~8{v;#;fC+dca&I-TTKfvrS0KOGcV$4S4>+C^;BCvM_UPd5a-FB78ebjg8=&|%q zSMY7cMzJG8^9sg<)l{aOM7A$;IS^fFTZA5GJ=`|v>=9;M^U`F)~ zEvKj!tCOTP-tTZ&zp=4;v0>oSHPjai+Le+_qwU$1qB@f4xri(1nQ~*xPgkR(PnZk0 zQX$vtqGI=j(|Y;V!*^6hc)+YLdVoR7$Y3n7K3>4g ziG##DW3r(YW$S~B@b{lakWv0?zn(u)q<;W12)ssJC-#<(he!PnAF@CH4IpL#|676l zD}?<254!yoxc)z#oGav41?68Y|Ka7!mykVaUI_}4hIM`Q&kC8c>=_-6g8;7(X#sQN z9b`WErzy!p(C$*L`q+~bdqYD*dk2S)ii6=(Yh7U)5FvaF5$BznQF0A4rZBUcHP=D} zbM|WpQlqj9BKke!3niQNc0qKsi0J5$GM4wy{0R8?sT&T`l9FFke`-E!>cEJ;kNA!i zG;G>uTW?UmkPHDc<7Jc$3@A=dPa&6#fsbFLVD;DC_phj`t4lgMvJrDxe=+C^Er{jL zFDg>5wfqEE0t2xRSFg8S`k==AtAC0yN%aZ+#3Upv{#zWDh0nyq1o0ZjBqNi5|NedP z0)%rsaBT|w)X|_DUE=o#@R^!_ap4U4B@W_W{e|}!@|~oNjPk3eK8pxQ=`w(dmjrG2 z_Yx}Jue*nDL*(tTJ`o4`BRvU&cAxgLb1n*YN=K-vDR;b2kou5G7)UI zmrse`FsOA^NolvmW``lu`vGOfcPpQ@vMFOOtNl#JM@s#KLU9G#UMtFHNMV z`*9zX38}Q$5D~uo>t-bjAP>*+YdS=IIBkPM$nhC6MX~KP8Z5dVCpO;=IIEKNm%kH1 zt5fiZ8lAbHxNnV*_Pw3fq1uRxT-Z;z9*q?Er9%|3mD6{7oX?rB2P90+b0A{TZ@18!Ia|*H`Y{t; zxZQ7h2)BXNmM8a5EBhR;j|(o>47ncbImyaM-OaAY0bJV@Lc6=6_x=&aYE{vTCZl8B zU8%8lwuL+SzL~to(3VYb4pT))JU~isVFoOPCb+1cz@_2Tij1FxC#!u7Qm+2&@oxN$ zh6LifdbTYDsovjajQjk${mm5`{k$tCTUF-wV@d7C<_l`hmIyDF#+^%ygxMvoibNXl zkCs1jke(4CD+3*MigxLR*K)`%!%rM~j`l>=ho`mA9~jX16uNJLMor`Q)i^-qb)%l1 zuH1e;8$$bI0^hk5rwIf3xIAMZ@K~a50}Ns+@V63DYGS7R zWH+Y5z!Qf7;D$VtRRBW9urZg7G|l&6#JjrhA(w`>Rn!^FaV_tU&o7@60BM!XKEV0U zOel@#@ITyn2WH!{NmUgDVq{i(y?R^(oJ2*nW1oB5*%z@llnxWYw+}gb@=8~<9~GO! zP8C{*1haF#wm#;!CUHcV>FUYnRMQ|RXDLoO>JFZm-=b{fq{)SWk5{vE{7(9DnLY#j z!AFELn&p+=&RPtrXz@9Y!RxA{Eaz=4rwqW&u{sZLzB{4Dk)^IIYD&O%_KL;lqZg4H z&mA!W&EM#ceXhtYHK1jnY9CNZEKVOzuFj*q_s#0S>bu@|bBr4jc*2rl-xo5@;Z9O8s!o()<{?+)b+hZ;Vn(8&=YcplBP7#_d z6l%sqnHK(DoJSLZt=YoMLsfw8*2>*Wv#oB4_ZPda;{*mfd-FWNy?g4z zlnl2Af`z5aT^(H-IIH6Ctl96DT=~_e1lT|7Z`*EXf_2x?+cF6+#T4FOTk9*!V`SR` zqDuD3PseD{Ck6|?nY0deWy6k`$F1Rt{4@eTCGq8A@}MQTFbxY}ZAXJaa&l*lXF%e-N{S!P{r(FCa_3U?++%e}E0vO>PTB^6hX{2rGu-IZC{ zaiR!l?^RHLSbOD;gN{wtzqIF>;8r|jj{`4Cq%IG-sK{M&`q&oD&u(~f(x+nakKLnk zoQ`Q+HkYF1j)%bHi((g2NH8*rHuE(WG5GI_axS8!@>Fw?ya6{Jy{`N3sGvT~7B(4J zM;BW3$#Ya^?{M(<3b*IAePCU0Lf7!x@FC&*sZ5=8*{H>%R)Z)!J`r3Q{c!b4XCq$Od84(JDT|Cjw81mvaD^_n82&-FI^Y9;g^H5_SUFPFNxOHWs0)7(uj^=4kty$eA z)ytVoZDlw*YxRk2$9M!631xK5=f7_Lmf^6HTJ2tELI&_abB(qL8cIvJcZgEkxUJka z*F@79c4=eYx^&f5tV!o?sx_6p=_}20Ctb^6X82xCgLmt%;=U8 z*2c?8$!GKwR$F&2cysz;BS{hB%)y#_J%1bxew{^WFH%<%T0dw8aNhqcXJ4cB+l~qJ|?MHL~X;)*ry<&u+9# z#xjmVu5FTD@BW{lsgVf%knFear0GrA%|{n>6Tpp$<|Jjnd3By4)7NfX{BnUn7Y9L&j{;PsCQt z8T?E1-r%7;SYEFdB9zgzV=K)(_nTp_tVPYDdsMiX*jaNK-V1m5WCvB~uVQYVUC&#Z zR=a^{Ci240R&}N-z~shTHRWk1^Y~(|Zs;)zBP}?GW>;F}=a~iQqe7EGlEi5pYr&ez z8uj+Lbex(P-o1U_&*!vF57=fa4XF{j!t9^3T~3^hjbacf=C@vIe3cuZP?7ju+y71W7fyr%5_8H*yAG)RQs)a_6^9o4+nY)ofjF-qs z83nD^JoLH0N}@yu7Utx2>f+)VgON$W9jue2dw*cTiJI-tlYQFjAr8}Kp2(2#E)8#^ z0l}V1E4m@H+p#(;E@M@ply4~or!D{I>GZ0W|^(p2-l}NCaBHI^`4TQdsR$W3Ex4PVVF0Pe9?M~ zmBiU0vkR>z^RSl{hO3x(67H+S&4Sk%<+5*XM@)J9)4ge(afZq@w>_1uzLO~{U1r@!cNdH@oJyMw)$cy+Y9tw*pkpTL zoo!l=rVkjVny=?5`h;%MNADcs&L0+8%E+Ivt`W>C&obR^R_EdnGfxm11)r`Jq97sw zd`ua4PD8=$(z(=NO8%H!Q}VClqG3f9ZZjkVGe4EpgX;&n*k%wQYK=A2Xo`Qzq z5M?1Nqhah5#{XgKt>fBiwy5E@P@u(%6qh1xio0726e%vnonpm{6QmR`4#lmwLveR^ z3GOZd5`s$zZ~Dl6@BO}a{zy2#gp)aY=A7BH_S$Q^p@jO1j4a#UIo6eHALKRY!D&N6 zafB+8O|J$#x$TrGnJ$WmlSY~VM8Cfz`uDj++O5kQ!=w#iy`8(l*HahMmv04{@Mcpt z+>Uof#|=%dPqk9qjy^_Zq+7n&)!?Li1N0Cuu~;WviO#<$p^geYmZl*=C zF=|_>9nbeJ0)SvII-{4{lm?ZC$Jv*y21xnfnA`qP?U^zRtal_lm3IeA z@HW)%mAjgWWp!8ja_MrFPTMbRk7(0V+~<*RoCs^-=Y&kIFQmVn2mtL8?a)P}RM?(2u9_zY_AZX>gQB)SnU zA21C!hsxRftTwq7uxSN zGmjuss}CYq-s-WGoXwO++^~;Qy9cKV-kLn(frt&98XHy_-QU;P+_bkhRR5Xu410d4 zm)mt_);M; zA9i8EG)WYQd+${yjQod^dJz1l1;%{nk#HK{qTcYV8D^4@1zAPpbq3j-=#Z&Dc->%d zo^(~gN^PyHV0bQiCXb*zRr7bUto3}fCx==KOhQ>))s_#V}NoeBIh8u-KXhBen& z71RM3Lf4JA6aIS7gynfgo?)dQ=q4)rYdEaiYBOQji&{o3R^t}-ph$W{o+Ri^N2H|m z90C7s&%2^^DjXZfcLPIfi6DS33+fk%BKBoK%J3!Dq628A|2bo&GERKUrq=crTbC0$MYr3p06(N)zPKasfIX9Du`w;HEtx@NCEYV(4k?V~uR{G5pisQPo z=Xi3_dG2-JBeooAf-*-ZkaT@N&Q_g=L?u4-co+#ae`OAk4m9OZV1KgDz9~>%B4+(>5xs}+GafAG`U7>nr!*!k`U8Bq-ke*oFJ}=Z)y^B zAq$ABJTUM{YmID93CKLoY^i$S;}*A?WK3}6N~~lNO57o*v+@BF3(xxWQkURNt<QxO_`=#9>(kKzJ%s~48L8|xtODbS$e7Oo5oBSIsv1Wm z*g60Gg=O|uG2Vvv)bYqk=UP9#nIXQ}C`zo%!r9KLz}Z_;%)txx!dN*hco z#r7Ie*_Scw=TmhvfpIb3-V2CBiaNpvF7GP1{SRVkipLJ-u^Gmj8=p?$l-6asjTIK0 zaeZt#WBPRa`;SR7+&$jSF5uJ0Gt=4kGA$!+S#{dE6E-4rPUitiYWCg3%P?~|!(7G& zxrDzIw$=2dm>2xwK49E8Tz6G(JTUESXPz@|p;=P{TxL zlhUrrOqWC4EuFGApGt{}YwVS5P7UE4W{<7mDO1d}NxLjt^RT@Nc$EVt&9R{B{rovb zclv<2CKtRt^K|i*Z=L*Id_=ENM6p!3NP7BRnxv#Ofj6A#htc>joy#BXkOzD&Q#Nuw zn~psGsPkOg(lnve_RE{eW50)q)wPaauf3b@JLJULI(28?I~P%gx304TtGo7>i-;_M zQn4bODHvy(KAFOq9d#VnT2awnr|1tXG2GUqqgQI}CN?&B>BXM!PpLSg^72?#uicY# zOASXBk!q;{A6^if?j?Q@JFy-$=t*Mud|UU+mZgFV4RbWSwbZa4lDmLO6^a1uvCUDFp_Kx=)HI9 zkd6uCwT*4^dZueL>YfX;a*EPha=JQs<0SyLlT!ChrrB5`z1o*N6>J?mRv0eV?VRFk zF!jPI6XK&`?Lpa#869!IBB=AMF_+vrtuO}5FZ6WXoH;U$Y))L7jU=5sTeHR4sH<4p zx;=4X({{02J$FAqvD0Ty3Kn!RzL#(VRal|U{=68W;0vn6Txr-nd}i zTAtnHO*p^L*nv8C3l)mtBKBT-wmD<-C67CpmS7wmG!KSSj?7$)xgL*gEZhO`PEKg4 zY^EL^N{@5a_Es-n-NeJc0zY|^N&U41ZySEjhZ=X^Ud)G`4azSJ4w0%Q#gNH9KrVhe z{+{;6g4XHHiKPU$`NVKQ>L*$mk5cYQ2?&Zg_Yt%1Pb6J(og&z-kCq6tgIc6ZXF8_x zMJh8RwtyCd5)f9>CM|?N++Hp+9ra$gKcG-Y@{}`xLA1ME8m!ec4Rx zc+i~IqTQ*|ukplq$rTJ!`7%i5k`N0~^cI9Bj#q$eDLFfjT{O=ClK9A#O2N5<)rev) zfXZ?s;3ATZ@7!&Oxd3GHa5-w0DTh>UPe5FA8B&a74}d>d*6uC~W{Xv7FeZ$=b;~Rb z@#TmFIPFHKqfi-8_1~4~#v#2aklK@|f<*M)4CL;Ke`}KZC2O}VLQ@HLy9i!>m}^ZN zaBP^`j^S&#Kg?)3J$KU+Yt&_U=~{5J1$DUEE)VyCTL;0feI*fFIZM4q%Po}BJ&%e# zGCZgbML3h8PC;k$)&4h}{fSMQ5uX=#XGV#^C#HPdv5zJZ=FdaW{`xFs?^Pw?OHo{Yx=AqQtyqSo+TgRk)~$n+t}{5NrSLr*`>zQvxh-D3L5}}p zuf^W|2*K6?{vK?P!BH#p_3BWfu_;TMbc?Tiy7l6dRHOHR#ai2lsnxn+*-HuOweE}B zD4Z%S+JnUs8iKm~$x5}_SX>9GngX>lM;oW}-2O?k#4wO+rNb1Vs9>~g%xKt2ifzMQ z3sm34=^*vaQnLjh9f2Pm$#dP*p~0C(}PzL$H>;6$ndw0X}i^}rj0o^orA z7W7vTZ@>&}V~Xp0e?eTPQ>*%o(ehv_kJyG8ASU*3edXcdk(-wX>)wVIX|_|jB01nI zkt^n)2lyXE5HN3fGU2`ou1ek0{XnqP!q<%uisJT0E=YerDSZFV(@-@wKjrsqBqezm zU-b^|S6TL@@P+cEg9oeVb2e8U-y4P7Vxf_PQV#+WCh$MvW6;CjI*MaH7FQ~y$#V0T z;Oa9{0191FM^z?pBf)7Sd~7PaX3eFM5oI zSH=P;%6)+}*2KO;IdhSpjmDW{xj)AL9ki4w$#MHr3t6UGn_=&CL`hn;wi>3&LVVoZ zsC(@yC<_tzeg=%3i28>wF!iy>|IhVY{z8ipulHkE{8#PMs*<}W;qO!a^;#nU{u9|H z8a!~u$3lz8`#bDJTQ&aF|9zTb0cUo+8agtr*v}1(uLHNl{;=P4ln5c4ay%8bQ(op9L^y>c$dhk@7fd&I-n5-rkN*OzcON?FyBo9r~9Bv%sWS5VyVk84ZUbWbSa~fKxOxDmE6M zlZz|fScQ>+p>ywy(s?Nl2Pv3fRVhq`+X}qWkoxEH1|G-7$M;U<$#L{WCnN;*Z>i)T ziL;aB=H>=uXVczZ9s?(AGX?*%4xl&eT{GR$r*I9YMr_2Hxild*tp!V!n$l%A2k2pauRj_-ybgg zYoh$y^+k%-|31!r`3&{R_RfxqipqO>e1TVo&VuRm005}b$pWdEsw*k__cZ(GzjNa; z(ELYI`J%$Zu>{>9;r&|zMu#g6j&ztr%&!1|y>Df1_Ld=kbjJT_F&ZW_#h*TZ{v4g0 zj3o9jAV)AcIr-0VV&WX_>Bs-EQ5ljW@DxdV5nH-dQ&VGLW3$Ke_-o|<@7ZYaL)TrK zed{iO!Wk%+t8uOWd@gVzFY?+$PMaM_RZos+Nbxp z+d=pTi6Y-vLx}=@BwgIhF&9~n|00kE)u%&t@C1^QLNZf^JSk+4L)MyJ7tP1lz3Xob z*;JC$X~FL86_Q6zkb(Drfg!dv^Pwhvv7p@%(I8BvqfpJ{*Hd2kX^qt0J!xNw4}#MN zWP=N;53)eYkk6~Pb}X)X)QW9JB&5Y|VMmR(dT)H$18d)hK)q@ADAGTu;ku_Tnmqq_ zA8r(9$=Tk$&$m*xdF&(|Hvy8ONj zJuhKk8Zo^YqL9i=l4#O(k;Geg*xcN5P0Gi?kMWNThUBp308Kxb9J|?b2=E1z48!!k zdRe4hYr}ScEjLr@o408rH{F~LCThHUbfOu$k?}lfm{J9mu3#l*wxVB6V@d-JAqt`a z<@Y#%0^m@Bko&RVbK=p@msKu5XGw)a51bEt>HR(P*Jp8QZ2gK%N6+n(_Jjh{YSLeZ z(mc2D9XyZUnVt>)oo*02)y!^m@~Wxc$xnZ*$_h!`a+fRZt%piRjXD0@+le)Vpxbk5 zx1w{|7@--+RRU}!3%|V{9;!?~9{gC5^Xqps@?hUX@@}R55u0k)RPxy%_G@u-i^z{r zN1|wzMf!Y+2TmHwT9AHMk5DB@mkIzYD~GE3C$CQVOO}+;G&5_4qKI`xnS$XgX$Q$n z?m9ii=f53qD9qUmBpmaow`52NgTefPXburr1EhEewjsq{o#CDW7kB?2~ zCeQ2UcbL;}>4xQs3opDNWByMaprLa$xHp&J|Fl-YO=yn{&1et`2wlm`r5RPfzEK1?~QE-^I-w<7O*SF)Ri}9vsX3veZ z#b%E(#{+?AS}opTG))?CD2tx^rGK-|+=2i8uNYLx#rXwUNu4B;sw$9!$qDgGWn+~5 z4D1h|=J{oZ$9k;4%>OR`7V+sKAl;yaHMMD~mO1T|)R49K*G606ix1VJdtu3qgmVHR zVNL|)BNl@-vhu?vn!Ix4MtG?&qPWz%TA=39)bk6rm5QZCEG~G&tJnO?`5CA1Uio`- zQF7ak>EFh-rlkTVC;VON#1)^%!f#4hF*lvH1FYq=MfS*j^aw2F)hYpHhW9CErR7`= zxCh<8)9mQAcwaIls*u>(eN^Z%(q|R(5{jzL^PzY)NZ&8?Y<7WP7P^NzQoAd8Y=1~ zO5Jvyq%Z78+FO@IhP=mAbv{XB@EO$8C~FT?K>=LVuW~cha2yDR{rkUIYQ_`U{9?3p zaL1P&SEREe#ud|n@W*;ZR7R65xnC6pGKo?}fq}Hm_Mwdg{JGFdENFU2paSxN{&W7D z{$SIN2Vwl&iz<_oChYga5=Xp_`>(6j1k3xZY0V<$B!4^~s&tHwO;>1n`2kC+mNll% zcqmsoWM1+auu&qC0DOfb-I5a&yx@8Gr7 zp?0$kPp$qfe#H;Jnp3ThU?8&yuh;OEbs~qYCtAU0`}S~u9Eq{5*c@8a`^VxJCCR)S zfak?O=9MjEBFyAU)7@F6Z)RaD*A;_hZqYnPUW#B+;{{^s6K|hyUGRu`{i@$zUIM3v zk{LBvh5;eLtRg~jNvj!lZLdd4222-H=mx;6Y0^Tj)cy#kBB@4Ic*L0>Jz*&b{zmt!fEnGWW{%fu$}pDq&IG_`)X_Jh70e>yW!B=xb_$)*>uk5!Zv zpAA+}Nb1-;KID_?n9NY5B*=2r2HCQ@R{<`5KD6PQQ%^y7k- z?LZ-eu_?)~B<(Fjv)S2$IdwH_wdRQ(j)eNljFW_v*~)Xn)_0erRLTWz)E zw%q8H6AdQ{<1V3Qg4MW>DdV*Dt1oZ@IW#DamjLSn6|YDzOi(nEO_X%_nuQZzlGACe zvO14PJ`N5pN0Q>$3&P2aAeoVCl@|8({l{yv5BQL77mJY!WztmvXB&7-rZ3Pa7uis$St?j zh5Yi)9T+?(Z!whpl@{WR7D4fGk3VccaOO%fyBKV{a=rLL9?7jFqxN5}veW}KQE~cz zhd-aKsK{1=>+lA2#LULCiedu22{{@{TtaK!cZP(8U{`0}Tc3){8Z@sE@0>rvrU^H}xg1!{`k(iPpo;u`D z)Ef5NwpsK#D+lT?D)RS!=DJRjSU9;6e|~ycUz8d=J7xmzdh#U0`Ic%S*jbZQ&R1_B z2*b#g%#xq%Ng2)9qXJN6&V8N2eqbza5CF)nY=~+vxPxpgN&jNhCc@y}$=2=Gd0epV_tH#mwgxZH+C>k+I

    bAenyRCVwL5E|nkuH7`@%>3 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

    tgpvtv&0*Z=XKGsNMe3dco6n|PSl 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 X6TRHb!)~s%Fq}Sh?qtP@AAb4|F<|({ literal 0 HcmV?d00001 diff --git a/examples/platform/nxp/rt/rt1170/doc/images/mcuboot_swap_config.png b/examples/platform/nxp/rt/rt1170/doc/images/mcuboot_swap_config.png new file mode 100644 index 0000000000000000000000000000000000000000..83c4fdb433494bfeeb63367adfcf1934811515da GIT binary patch literal 238186 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�}myk5#aZvr2Ri08MO~iQ64dGo~v} z)57+W`hb`bJed^SNqkt`KPkk!8+GXc8Qxs}uD?E_B_j8vzjyfum9M}=m2>9Oe|LWW zYw6Zqxb10#ugq$n>EW5%1R<` zWSV@^%06*P9+;=X+VD+!d~s^A=GDSLuQ`C`@~cbvIH0evrKU8cJ0@KZUaI^#bdZ{* zPo!P8&56)aCPG}tuV@3x$$s}<_ErZq6-Go=p^Jh$@?1sH4gN8=V1y7>qbjp3^cAOV zM8WC;%76?~(a7$U*lo)>=kyOnkrGwV&}&1CCn955l;erb)AuUHC0<@zQ6g$U^~t&E z#ydKUhYy#MZr)dwK;uXJpO?Int(nwCWu0kZeA7~!;vv=g<{rint_Rq!G3z}QhVt(7 zJ@hM(BpV`PykO;4LDD@xsn4-bE| z`(=~9A~~JR67Akv$}K2L+tSi<*qWRICB}Y#bF)gn?SAz(;O0<#Pw=1I&CsEC9+z7F zDL?nx8`1Hx!PYqaPA~Wu&&ciw!Tz&<^V-Vrn=Y7^7Wa$DlFt8O^ZIv|d}QbS=gsUr z5iWs${AFdeNRvEEt>eoy{{B^7LS`pNpBza{!7Ej%;nWE|((PW+H=i;WdlX|cX?@=m zEdN`9&aO(n+qZ;@YNvd9jE?3?zH8k>?zg`YZ)e6qgm3nrUwLr@k3hjmip>6}ER+wI zha)QjAr!_1worza^tKrU=7%phDw6*FxWzkaw*CSB_ZDcuaasjKuUt1n_Rr5hdHr86 z3G&wQ53jo4@T&<3%_tB-6(DRonetW3&6*@zYn@V>S!COU`8D~M>72chIB*Qa(`P&+ z@sO;vP?vduh`Z9(ftf==4EJ+?hc4Ri@ae-BPtZLWclWjc3Ts0O1OK$S&bD6$N5<3+ z&o^tyz%RjBm10FNS&m26K#dszL)t-Atv34b^Bmr$5`H&cpwq8sj9d$kXE>nqb=my} zE}<6h$WNrPeEDjI!%a=W`Rsm)JN0bq+5Z+o-w*05(4Nz;8IJ)Zv-tT=1n_M@0fAeipfrLdWc=-ovg67I+%qMg=Hx{K4 zHJH$|jfh%lYkt01Sz%jUIA8A6y}F)>n`{19{WMI5T#TT@A=8#VIJ&rI4h*?m6uJ|IV4vl(6_A(;CM`|iQ*SIc ziF0H@+Vk74>#qDgBVPpfJa}YgV(PhiqX3}P=348xx5;xRn@~i&#izFTbIoBKwNdJDrO;y z#l8egN7y^;Oo+Fwj+I{dOf@p?POP;}gtO*r$tzypC7e<@7fWxbw0cCh<@0#-xkxs9f*w8$8LKu040^6CxS4 zQqw#s7{EMAzZaIv$HQCDfZ3-0S2Cw z^zr-h)8vp0iVlsb)vZ;QmzUF|8P5IFaz5rx^`;<8t*mkjHTq>3>acMEE<6FYf7hxZ z0&MrgV+?m^OFKJwQpl7RWY0Sv8IK4!o;*;mi^LC$BU4e`f$q!k@#9?P9w{*G(I zPx$K0?1AX{KUzzXhK*7~m}%MBCLAc_>`qY|@V9#@gZ8g(0X|mQ;Q3YXIfH7_Jr0vw6l+toa>!Gj)`?VR@SX@Kls4Qm2QB-@KyCMOJxKO+S9Q(h&R zXmu>LF(vBb2ZHEE)d=LJ64H+kCjc2!qu^o{<(YjtcoTj+4@;!}{g_&7UEW5cue3Qv zZn>e(htRN`2SNpT(8TGi$w&&Q>={^<>qk!Yn&6-nzxDJQ4Y2>Z{VZ1^SY=RbzG zonBx1vk!Li1jd?di~#bm3@N{UV)3o@^GkBOyzva~bEF%wax#w$2K+F_$XKZ>!b_op zfY4Fqj#8c;zURL1v^PnJh+&>_PThQe0BrbNQbiz6*PX!@561oXwA7yi@wxt*yV~^b zSn_&Fnq0Sw#dUXrM;hvS<`Ov=6t2A3i^fY>SUwTO?P8v~+1bPgD%*W{fkB6IT+&e1 zu3%;B8WC9=`VL6NCp@@W;J$m2wD>Mn5-GW)F)J8y7$C^93Dkk#-_S zvsb2;iCtngx(0dN7}^F>TKG|%3N{q>8SoY&WWDeuI=gFd-Y4?zP(OKs1RmU_P6oCp~-DuMnlyQwufhz5<-$5CK2o4iiU`V zw_UCxD^l^u(;rHfX zRg$B53*zy(`@Os0xS=IUD&DsZZ|>5+f&37e+j}az^3R@A{0~NG8PTZWZ`CriVCvo4 zrSw*&SG(Dn=FL5wT*)8rR!a%`Ffu%DRwONGZ*P?UsWQfHX_(LIpBnzb`$}Nn{Xo#E z0v+>SZtm&g$xhrHnIs=4cNp8D%y;t6Lk0uhI&A#1Tj-7D^>@~`e`nfM@00?F#cn2$ zvJVHk9=SVzs*+8h7*3d^QIxh4d-*-W8}PA+4w?w=rQxr$r93l}MYxbCNKljDHE_}U zJg~Ov&IzrO#6;rhPoaU&qJTo4=Xt)vj?c8u+e0jH7#tMZMk{rHc5u%b&9tRGSam5l znXj+zp*Au&)Z+H0zv1I5*!@)94cZZWW?9JVRmdR8Cl5zY=N;kTMf@QA8mimvjU`zRz=Ue%m#raj~JD+AH+!xSK6sqtguI zNLI$96P+Ax<>nI6qcs+H4689VDYSQbo}m85s$SvUf$w|4bLlrDyHszh_A+1S;1|(B zk5*zhJU8v1a!@0~z#$GM&`x~b*6;c_c(9kRo`j1HdT$`4sR0MY;ABUb++XN71REn4 zJF!{CI24E%ub7WZ*_z5@(#%%d^$g=y_2{LbX%9BF7yvaO6#Yk@p~`ogRv zdfP_%)QiM(ZH*c{g4!B8o4dBzVv(VJ@cO;}@^?Ohj8WN%RcfrbdGpSH;omFDzLX2$ zPc|S3EF%O12_Y4K*K>)cjwDWwF~4Xb2d+S!{1MRul+bY1K$%UDqqm*1S@pU~NWwrD z7ps%Ip;%slG8>X?VLk;}NwWJ%i|q&u*VCU3;MIzu>ax#Zg!>Sn`!nx1MzLX*2dA*R zg1ku8mY!nI|0o(dLJEs70mxWor`Vng+OvE$Nkg)x6BNxyfjkT`(Jn}xSK(C2f8LbK zRz=V?7nymv#~N8fpRSG^qe03jmXs+|MzjLpG;2u&I-gF{x}0RQh_-dmF9ApY@nI}o zJD9Q%ngCm!)KY}wil`%Zqa!#HhtL?QYgN7ae=3+lYi3wh<1G1!LqAwnyBw(M<8lD?_NK{Li!NG zy9n1H2lLA7o0&ygA1chU(kb5#B=9wMW)$W6rMw+Yv%YAP?NGBwu;U{V#TahcO#h>+ zEBbW9il8qrT-rq@jz8{bh)j^9O-=$L_~a`U`(b zLs)Lx)$3Pu49mSebPa(}>Q)C_I3T;s=5fLueUQb+M#9;>KOMLZf3CRFw*5EKu45UZo`O)K4+-u}Pa%=J;?7 zE#K3w#qx*scj~or_rDaO0-fd}5vGk>PpM$PIhe$?x(3Lm*vB#I4?nsmGdI0rxDj%X zE!esydfDUV5D{71y#nd8&lm};X4PN_EB8=DYiOKyQbuOaRzjM zRCJ7mT@g;nvDvgaSeK2M;5U3?HN#O2xvr)yTt-H^7Uckh$2yx{muo<|iQ-a8HLnZWbSUAl=I= z1NnqqwtJU$o1s>lMy8OMnOLC7tt~4`iAsDI`_0TTQ`1^T9mXV`Wue)>WGUX2{Mz}h zveFqiW|(<6->5q=6$)Qp5PZD$0=b|HRx+6v_G>Oiovu>3ao>xjdsmoba(Oy@D-ISF z>%a*t$q#Dtcz|9#E>pflKe|>9v5!Wc8#^*+ie#CV{Dz6US~qg&lqyA478%yl*~MT( zt4I<@lAl=PBa60CD~oWKxwDoGa51Z%aXx@+_OV`WYE8}P|5~sE3r-|mAAhNeF^93& z5f^0(ll|zQ5)?`$bnt?(WnaXjx_jGls;ceT01)FeqIY%ee0$nI1?XEGuilP

    $9;hs#=Bl+)$%dN&Rp=cMSsL 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�keqxi#&jgz-O`x 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 literal 0 HcmV?d00001 diff --git a/examples/platform/nxp/rt/rt1170/doc/images/murata_usd-m2_connections_1.jpg b/examples/platform/nxp/rt/rt1170/doc/images/murata_usd-m2_connections_1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..01febd90b557735a50ebda9f7b5fe6eca0d779c3 GIT binary patch literal 67831 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

    uNPDNG~r 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 z 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 literal 0 HcmV?d00001 diff --git a/examples/platform/nxp/rt/rt1170/doc/images/murata_usd-m2_connections_2.jpg b/examples/platform/nxp/rt/rt1170/doc/images/murata_usd-m2_connections_2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..91bae4b5f55beebbcf1d35663211e634c6f99856 GIT binary patch literal 78898 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�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 literal 0 HcmV?d00001 diff --git a/examples/platform/nxp/rt/rt1170/doc/images/select-sdk.png b/examples/platform/nxp/rt/rt1170/doc/images/select-sdk.png new file mode 100644 index 0000000000000000000000000000000000000000..412731cc988531fde8b80e9ee232237e9bf76d80 GIT binary patch literal 126030 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%0Dk|0fqj0o;8P!-YPqh9 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

    T590t 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 UbfqO=X8-^I07*qoM6N<$g2biu{Qv*} literal 0 HcmV?d00001 diff --git a/examples/platform/nxp/rt/rt1170/doc/images/startup.png b/examples/platform/nxp/rt/rt1170/doc/images/startup.png new file mode 100644 index 0000000000000000000000000000000000000000..c805bc53b05049bef769ca8b0ce94b3d428e46d6 GIT binary patch literal 76388 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

    co-Z%r^=tFB_aiazzIXrfYGKlaZW(NF!T(d; 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

    cq2UV^&S?gCK|IE0a)aaC&#s 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 literal 0 HcmV?d00001 diff --git a/examples/thermostat/nxp/rt/rt1060/.gn b/examples/thermostat/nxp/rt/rt1060/.gn new file mode 100644 index 00000000000000..0985ed955a426f --- /dev/null +++ b/examples/thermostat/nxp/rt/rt1060/.gn @@ -0,0 +1,35 @@ +# Copyright (c) 2020 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/build.gni") +import("//build_overrides/chip.gni") + +# The location of the build configuration file. +buildconfig = "${build_root}/config/BUILDCONFIG.gn" + +# CHIP uses angle bracket includes. +check_system_includes = true + +default_args = { + target_cpu = "arm" + target_os = "freertos" + + import("//args.gni") + + # Import common example GN args + import("${chip_root}/examples/platform/nxp/common/gn/args.gni") + + # Import default platform configs + import("${chip_root}/src/platform/nxp/rt/rt1060/args.gni") +} diff --git a/examples/thermostat/nxp/rt/rt1060/BUILD.gn b/examples/thermostat/nxp/rt/rt1060/BUILD.gn new file mode 100644 index 00000000000000..5eba1a328f799f --- /dev/null +++ b/examples/thermostat/nxp/rt/rt1060/BUILD.gn @@ -0,0 +1,304 @@ +# Copyright (c) 2021-2023 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/build.gni") +import("//build_overrides/chip.gni") +import("//build_overrides/nxp_sdk.gni") +import("//build_overrides/openthread.gni") +import("${chip_root}/src/platform/device.gni") + +#allows to get common NXP SDK gn options +import("${nxp_sdk_build_root}/nxp_sdk.gni") + +# Allows to get various RT gn options +import("${nxp_sdk_build_root}/${nxp_sdk_name}/rt_sdk.gni") + +import("${chip_root}/src/platform/nxp/${nxp_platform}/args.gni") +import( + "${nxp_sdk_build_root}/${nxp_sdk_name}/${rt_platform}/${rt_platform}.gni") +import("${nxp_sdk_build_root}/${nxp_sdk_name}/nxp_executable.gni") + +assert(current_os == "freertos") +assert(target_os == "freertos") +assert(nxp_platform == "rt/rt1060") + +declare_args() { + # Allows to enable to ota_provider support + enable_ota_provider = false + + # Allows to connect to a predefine Wi-Fi network at boot + wifi_auto_connect_at_boot = false + wifi_auto_connect_at_boot_ssid = "" + wifi_auto_connect_at_boot_password = "" + + # Setup discriminator as argument + setup_discriminator = 3840 + + chip_with_diag_logs_demo = true +} + +example_platform_dir = + "${nxp_sdk_matter_support_root}/examples/platform/${nxp_platform}" +common_example_dir = "${chip_root}/examples/platform/nxp/common" + +app_common_folder = "thermostat/nxp/zap" + +# Create here the SDK instance. +# Particular sources/defines/includes could be added/changed depending on the target application. +rt_sdk("sdk") { + defines = [] + + cflags = [] + public_deps = [] + public_configs = [] + sources = [] + include_dirs = [] + + # Indicate paths to default board files + include_dirs += [ "${example_platform_dir}/board/" ] + + # RT1060 rev A use same pin mux as rev B + # If user needs different pin mux files for rev A and rev B boards, the source and include from below needs to be updated accordingly + if (evkname == "evkmimxrt1060") { + include_dirs += [ "${example_platform_dir}/board/evkbmimxrt1060/" ] + sources += [ "${example_platform_dir}/board/evkbmimxrt1060/pin_mux.c" ] + } else { + include_dirs += [ "${example_platform_dir}/board/${evkname}/" ] + sources += [ "${example_platform_dir}/board/${evkname}/pin_mux.c" ] + } + sources += [ "${example_platform_dir}/board/hardware_init.c" ] + sources += [ "${example_platform_dir}/board/clock_config.c" ] + sources += [ "${example_platform_dir}/board/board.c" ] + sources += [ "${example_platform_dir}/board/peripherals.c" ] + + # Indicate the path to CHIPProjectConfig.h + include_dirs += [ "include/config" ] + + # Indicate the default path to FreeRTOSConfig.h + include_dirs += [ "${example_platform_dir}/app/project_include/freeRTOS" ] + + # Indicate the default path to OpenThreadConfig.h + include_dirs += [ "${example_platform_dir}/app/project_include/openthread" ] + + # For matter with BR feature, increase FreeRTOS heap size and enable TBR cluster + if (chip_enable_wifi && chip_enable_openthread) { + defines += [ + "configTOTAL_HEAP_SIZE=(size_t)(170 * 1024)", + "CHIP_DEVICE_CONFIG_ENABLE_TBR=1", + ] + } + + defines += [ + "CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR=${setup_discriminator}", + ] +} + +# Create the SDK driver instance. +# Particular sources/defines/includes could be added to add other drivers not available in the default sdk driver template +rt1060_sdk_drivers("sdk_driver") { +} + +rt_executable("thermostat") { + output_name = "chip-rt1060-thermostat-example" + + defines = [ + "CONFIG_RENDEZVOUS_MODE=7", + "CONFIG_APP_FREERTOS_OS=1", + ] + + if (chip_enable_openthread) { + defines += [ "CONFIG_NET_L2_OPENTHREAD=1" ] + } + + if (chip_with_diag_logs_demo) { + defines += [ + "CONFIG_DIAG_LOGS_DEMO=1", + "CHIP_DEVICE_CONFIG_MAX_DIAG_LOG_SIZE=1024", + ] + } + + include_dirs = [ + "../../common/main/include", + "../../common/main", + "${chip_root}/examples/all-clusters-app/all-clusters-common/include", + "${chip_root}/examples/providers/", + ] + + sources = [ + "${chip_root}/examples/all-clusters-app/all-clusters-common/src/binding-handler.cpp", + "${chip_root}/examples/providers/DeviceInfoProviderImpl.cpp", + "../../common/main/AppTask.cpp", + "../../common/main/DeviceCallbacks.cpp", + "../../common/main/ZclCallbacks.cpp", + "../../common/main/include/AppEvent.h", + "../../common/main/include/AppTask.h", + "../../common/main/include/DeviceCallbacks.h", + "../../common/main/main.cpp", + ] + + if (chip_with_diag_logs_demo) { + include_dirs += [ + "${common_example_dir}/diagnostic_logs/include", + "${chip_root}", + ] + sources += [ + "${common_example_dir}/diagnostic_logs/source/DiagnosticLogsDemo.cpp", + "${common_example_dir}/diagnostic_logs/source/DiagnosticLogsProviderDelegateImpl.cpp", + ] + } + + # App common files + include_dirs += [ + "${common_example_dir}/icd/include", + "${common_example_dir}/matter_cli/include", + "${common_example_dir}/device_manager/include", + "${common_example_dir}/device_callbacks/include", + "${common_example_dir}/matter_button/include", + "${common_example_dir}/factory_data/include", + "${common_example_dir}/app_task/include", + ] + + sources += [ + "${chip_root}/examples/platform/nxp/${nxp_platform}/factory_data/source/AppFactoryDataExample.cpp", + "${common_example_dir}/app_task/source/AppTaskBase.cpp", + "${common_example_dir}/app_task/source/AppTaskFreeRTOS.cpp", + "${common_example_dir}/device_callbacks/source/CommonDeviceCallbacks.cpp", + "${common_example_dir}/device_manager/source/CHIPDeviceManager.cpp", + "${common_example_dir}/icd/source/ICDUtil.cpp", + "${common_example_dir}/matter_button/source/ButtonDefault.cpp", + "${common_example_dir}/matter_button/source/ButtonManager.cpp", + "${common_example_dir}/matter_button/source/ButtonRegistrationDefault.cpp", + ] + + deps = [ "${chip_root}/examples/${app_common_folder}" ] + + if (chip_enable_matter_cli) { + defines += [ "ENABLE_CHIP_SHELL" ] + deps += [ + "${chip_root}/examples/shell/shell_common:shell_common", + "${chip_root}/src/lib/shell:shell", + ] + sources += [ + "${common_example_dir}/matter_cli/source/AppCLIBase.cpp", + "${common_example_dir}/matter_cli/source/AppCLIFreeRTOS.cpp", + ] + } + + if (chip_enable_ota_requestor) { + sources += [ + "${chip_root}/examples/platform/nxp/common/mcuboot_app_support/flash_partitioning.h", + "${common_example_dir}/ota_requestor/source/OTARequestorInitiator.cpp", + "${common_example_dir}/ota_requestor/source/OTARequestorInitiatorCommon.cpp", + + #Adding mcuboot files + "${chip_root}/examples/platform/nxp/common/mcuboot_app_support/mcuboot_app_support.c", + "${chip_root}/examples/platform/nxp/common/mcuboot_app_support/mcuboot_app_support.h", + ] + include_dirs += [ + "$${common_example_dir}/ota_requestor/include", + "${chip_root}/examples/platform/nxp/common/mcuboot_app_support", + ] + } + + if (wifi_auto_connect_at_boot) { + assert(wifi_auto_connect_at_boot_ssid != "" && + wifi_auto_connect_at_boot_password != "", + "WiFi SSID and password must be specified at build time!") + + defines += [ + "CONFIG_CHIP_APP_WIFI_CONNECT_AT_BOOT=1", + "CONFIG_CHIP_APP_WIFI_SSID=\"${wifi_auto_connect_at_boot_ssid}\"", + "CONFIG_CHIP_APP_WIFI_PASSWORD=\"${wifi_auto_connect_at_boot_password}\"", + ] + + include_dirs += [ "${common_example_dir}/wifi_connect/include" ] + sources += [ "${common_example_dir}/wifi_connect/source/WifiConnect.cpp" ] + } + + if (enable_ota_provider) { + defines += [ "CONFIG_CHIP_OTA_PROVIDER=1" ] + + include_dirs += [ + "${common_example_dir}/ota_provider/include", + "${common_example_dir}/ota_provider/ota-provider-common", + ] + + sources += [ + "${common_example_dir}/ota_provider/ota-provider-common/RTBdxOtaSender.cpp", + "${common_example_dir}/ota_provider/ota-provider-common/RTOTAProviderExample.cpp", + "${common_example_dir}/ota_provider/source/OTAProvider.cpp", + ] + + deps += [ + "${chip_root}/src/app/server", + "${chip_root}/src/protocols/bdx", + "${chip_root}/third_party/jsoncpp", + ] + } + + # In case a dedicated assert function needs to be supported the flag sdk_fsl_assert_support should be set to false + # The would add to the build a dedicated application assert implementation. + if (!sdk_fsl_assert_support) { + sources += [ "${common_example_dir}/app_assert/source/AppAssert.cpp" ] + } + + cflags = [ "-Wconversion" ] + + ldscript = + "${example_platform_dir}/app/ldscripts/MIMXRT1062xxxxx_flexspi_nor.ld" + + inputs = [ ldscript ] + + ldflags = [ + "-T" + rebase_path(ldscript, root_build_dir), + "-fno-common", + "-Wl,--defsym=__stack_size__=2048", + "-ffreestanding", + "-fno-builtin", + "-mapcs", + "-u qspiflash_config", + "-u image_vector_table", + "-u boot_data", + "-u dcd_data", + "-Wl,-print-memory-usage", + "-Wl,--no-warn-rwx-segments", + ] + + if (enable_ota_provider) { + # As the OTA file will be stored in the littlefs file system, it is required to increase the size of the file system + # To be able to store an OTA file with a MAX size of 640K, + # it recommended to size the file system with: + # 161 sectors of 4K => reserved for the OTA file + # 32 sectors of 4K => reserved for Matter/OT/BLE settings storage + ldflags += [ "-Wl,--defsym=gNVMSectorCountLink_d=193" ] + } + + if (chip_enable_ota_requestor) { + # If OTA build flag is enabled, + # we would need to reserve enough space for the bootloader (MCUBoot) + # MCUBoot requires 0x11000 Bytes to be reserved at the base of the flash + # Consequently, some sections will need to be shifted + ldflags += [ "-Wl,--defsym=__mcu_boot_size__=0x11000" ] + } + + output_dir = root_out_dir +} + +group("rt1060") { + deps = [ ":thermostat" ] +} + +group("default") { + deps = [ ":rt1060" ] +} diff --git a/examples/thermostat/nxp/rt/rt1060/README.md b/examples/thermostat/nxp/rt/rt1060/README.md new file mode 100644 index 00000000000000..62d4847a4a5cef --- /dev/null +++ b/examples/thermostat/nxp/rt/rt1060/README.md @@ -0,0 +1,5 @@ +# CHIP RT1060 Thermostat Application + +All instructions describing how to use a Matter application on NXP RT1060 can be +found in [README.md](../../../../all-clusters-app/nxp/rt/rt1060/README.md) root +readme diff --git a/examples/thermostat/nxp/rt/rt1060/args.gni b/examples/thermostat/nxp/rt/rt1060/args.gni new file mode 100644 index 00000000000000..c2d91a5db7bae7 --- /dev/null +++ b/examples/thermostat/nxp/rt/rt1060/args.gni @@ -0,0 +1,19 @@ +# Copyright (c) 2023 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/chip.gni") + +# SDK target definitions +nxp_sdk_target = get_label_info(":sdk", "label_no_toolchain") +nxp_sdk_driver_target = get_label_info(":sdk_driver", "label_no_toolchain") diff --git a/examples/thermostat/nxp/rt/rt1060/build_overrides b/examples/thermostat/nxp/rt/rt1060/build_overrides new file mode 120000 index 00000000000000..f10867042f4d19 --- /dev/null +++ b/examples/thermostat/nxp/rt/rt1060/build_overrides @@ -0,0 +1 @@ +../../../../build_overrides \ No newline at end of file diff --git a/examples/thermostat/nxp/rt/rt1060/include/config/CHIPProjectConfig.h b/examples/thermostat/nxp/rt/rt1060/include/config/CHIPProjectConfig.h new file mode 100644 index 00000000000000..dd73c6c9eaaedd --- /dev/null +++ b/examples/thermostat/nxp/rt/rt1060/include/config/CHIPProjectConfig.h @@ -0,0 +1,216 @@ +/* + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2020 Google LLC. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Example project configuration file for CHIP. + * + * This is a place to put application or project-specific overrides + * to the default configuration values for general CHIP features. + * + */ + +#pragma once + +/* + * Tells to the platform Factory Data Provider whether to use the example configuration or real/provisioned data. + */ +#ifndef CONFIG_CHIP_PLAT_LOAD_REAL_FACTORY_DATA +#define CONFIG_CHIP_PLAT_LOAD_REAL_FACTORY_DATA 0 +#endif + +/** + * CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID + * + * 0xFFF1: Test vendor. + */ +#define CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID 0xFFF1 + +/** + * CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID + * + */ +#define CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID 0x8005 + +#if !CONFIG_CHIP_PLAT_LOAD_REAL_FACTORY_DATA +// Use a default pairing code if one hasn't been provisioned in flash. +#ifndef CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE +#define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE 20202021 +#endif + +#ifndef CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR +#define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR 0xF00 +#endif + +// Use a default pairing code if one hasn't been provisioned in flash. +#define CHIP_DEVICE_CONFIG_USE_TEST_PAIRING_CODE "CHIPUS" + +/** + * CHIP_DEVICE_CONFIG_USE_TEST_SERIAL_NUMBER + * + * Enables the use of a hard-coded default serial number if none + * is found in CHIP NV storage. + */ +#define CHIP_DEVICE_CONFIG_USE_TEST_SERIAL_NUMBER "DUMMY_SN" + +#endif /* !CONFIG_CHIP_PLAT_LOAD_REAL_FACTORY_DATA */ + +/** + * CHIP_DEVICE_CONFIG_DEVICE_HARDWARE_VERSION + * + * The hardware version number assigned to device or product by the device vendor. This + * number is scoped to the device product id, and typically corresponds to a revision of the + * physical device, a change to its packaging, and/or a change to its marketing presentation. + * This value is generally *not* incremented for device software versions. + */ +#define CHIP_DEVICE_CONFIG_DEVICE_HARDWARE_VERSION 100 + +#ifndef CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION_STRING +#define CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION_STRING "v0.1.0" +#endif + +/** + * CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING + * + * A string identifying the software version running on the device. + * CHIP currently expects the software version to be in the format + * {MAJOR_VERSION}.0d{MINOR_VERSION} + */ +#ifndef CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING +#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING NXP_CONFIG_DEVICE_SOFTWARE_VERSION_STRING +#endif + +#ifndef CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION +#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION NXP_CONFIG_DEVICE_SOFTWARE_VERSION +#endif + +#ifndef CHIP_DEVICE_CONFIG_DEVICE_VENDOR_NAME +#define CHIP_DEVICE_CONFIG_DEVICE_VENDOR_NAME "NXP Semiconductors" +#endif + +#ifndef CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_NAME +#define CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_NAME "NXP Demo App" +#endif + +#ifndef CHIP_DEVICE_CONFIG_CERTIFICATION_DECLARATION +//-> format_version = 1 +//-> vendor_id = 0xFFF1 +//-> product_id_array = [ 0x8000, 0x8001, 0x8002, 0x8003, 0x8004, 0x8005, 0x8006, 0x8007, 0x8008, 0x8009, 0x800A, 0x800B, +// 0x800C, 0x800D, 0x800E, 0x800F, 0x8010, 0x8011, 0x8012, 0x8013, 0x8014, 0x8015, 0x8016, 0x8017, 0x8018, 0x8019, 0x801A, +// 0x801B, 0x801C, 0x801D, 0x801E, 0x801F, 0x8020, 0x8021, 0x8022, 0x8023, 0x8024, 0x8025, 0x8026, 0x8027, 0x8028, 0x8029, +// 0x802A, 0x802B, 0x802C, 0x802D, 0x802E, 0x802F, 0x8030, 0x8031, 0x8032, 0x8033, 0x8034, 0x8035, 0x8036, 0x8037, 0x8038, +// 0x8039, 0x803A, 0x803B, 0x803C, 0x803D, 0x803E, 0x803F, 0x8040, 0x8041, 0x8042, 0x8043, 0x8044, 0x8045, 0x8046, 0x8047, +// 0x8048, 0x8049, 0x804A, 0x804B, 0x804C, 0x804D, 0x804E, 0x804F, 0x8050, 0x8051, 0x8052, 0x8053, 0x8054, 0x8055, 0x8056, +// 0x8057, 0x8058, 0x8059, 0x805A, 0x805B, 0x805C, 0x805D, 0x805E, 0x805F, 0x8060, 0x8061, 0x8062, 0x8063 ] +//-> device_type_id = 0x0016 +//-> certificate_id = "ZIG20142ZB330003-24" +//-> security_level = 0 +//-> security_information = 0 +//-> version_number = 0x2694 +//-> certification_type = 0 +//-> dac_origin_vendor_id is not present +//-> dac_origin_product_id is not present +#define CHIP_DEVICE_CONFIG_CERTIFICATION_DECLARATION \ + { \ + 0x30, 0x82, 0x02, 0x19, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x82, 0x02, 0x0a, 0x30, \ + 0x82, 0x02, 0x06, 0x02, 0x01, 0x03, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, \ + 0x02, 0x01, 0x30, 0x82, 0x01, 0x71, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, \ + 0x01, 0x62, 0x04, 0x82, 0x01, 0x5e, 0x15, 0x24, 0x00, 0x01, 0x25, 0x01, 0xf1, 0xff, 0x36, 0x02, 0x05, 0x00, 0x80, \ + 0x05, 0x01, 0x80, 0x05, 0x02, 0x80, 0x05, 0x03, 0x80, 0x05, 0x04, 0x80, 0x05, 0x05, 0x80, 0x05, 0x06, 0x80, 0x05, \ + 0x07, 0x80, 0x05, 0x08, 0x80, 0x05, 0x09, 0x80, 0x05, 0x0a, 0x80, 0x05, 0x0b, 0x80, 0x05, 0x0c, 0x80, 0x05, 0x0d, \ + 0x80, 0x05, 0x0e, 0x80, 0x05, 0x0f, 0x80, 0x05, 0x10, 0x80, 0x05, 0x11, 0x80, 0x05, 0x12, 0x80, 0x05, 0x13, 0x80, \ + 0x05, 0x14, 0x80, 0x05, 0x15, 0x80, 0x05, 0x16, 0x80, 0x05, 0x17, 0x80, 0x05, 0x18, 0x80, 0x05, 0x19, 0x80, 0x05, \ + 0x1a, 0x80, 0x05, 0x1b, 0x80, 0x05, 0x1c, 0x80, 0x05, 0x1d, 0x80, 0x05, 0x1e, 0x80, 0x05, 0x1f, 0x80, 0x05, 0x20, \ + 0x80, 0x05, 0x21, 0x80, 0x05, 0x22, 0x80, 0x05, 0x23, 0x80, 0x05, 0x24, 0x80, 0x05, 0x25, 0x80, 0x05, 0x26, 0x80, \ + 0x05, 0x27, 0x80, 0x05, 0x28, 0x80, 0x05, 0x29, 0x80, 0x05, 0x2a, 0x80, 0x05, 0x2b, 0x80, 0x05, 0x2c, 0x80, 0x05, \ + 0x2d, 0x80, 0x05, 0x2e, 0x80, 0x05, 0x2f, 0x80, 0x05, 0x30, 0x80, 0x05, 0x31, 0x80, 0x05, 0x32, 0x80, 0x05, 0x33, \ + 0x80, 0x05, 0x34, 0x80, 0x05, 0x35, 0x80, 0x05, 0x36, 0x80, 0x05, 0x37, 0x80, 0x05, 0x38, 0x80, 0x05, 0x39, 0x80, \ + 0x05, 0x3a, 0x80, 0x05, 0x3b, 0x80, 0x05, 0x3c, 0x80, 0x05, 0x3d, 0x80, 0x05, 0x3e, 0x80, 0x05, 0x3f, 0x80, 0x05, \ + 0x40, 0x80, 0x05, 0x41, 0x80, 0x05, 0x42, 0x80, 0x05, 0x43, 0x80, 0x05, 0x44, 0x80, 0x05, 0x45, 0x80, 0x05, 0x46, \ + 0x80, 0x05, 0x47, 0x80, 0x05, 0x48, 0x80, 0x05, 0x49, 0x80, 0x05, 0x4a, 0x80, 0x05, 0x4b, 0x80, 0x05, 0x4c, 0x80, \ + 0x05, 0x4d, 0x80, 0x05, 0x4e, 0x80, 0x05, 0x4f, 0x80, 0x05, 0x50, 0x80, 0x05, 0x51, 0x80, 0x05, 0x52, 0x80, 0x05, \ + 0x53, 0x80, 0x05, 0x54, 0x80, 0x05, 0x55, 0x80, 0x05, 0x56, 0x80, 0x05, 0x57, 0x80, 0x05, 0x58, 0x80, 0x05, 0x59, \ + 0x80, 0x05, 0x5a, 0x80, 0x05, 0x5b, 0x80, 0x05, 0x5c, 0x80, 0x05, 0x5d, 0x80, 0x05, 0x5e, 0x80, 0x05, 0x5f, 0x80, \ + 0x05, 0x60, 0x80, 0x05, 0x61, 0x80, 0x05, 0x62, 0x80, 0x05, 0x63, 0x80, 0x18, 0x24, 0x03, 0x16, 0x2c, 0x04, 0x13, \ + 0x5a, 0x49, 0x47, 0x32, 0x30, 0x31, 0x34, 0x32, 0x5a, 0x42, 0x33, 0x33, 0x30, 0x30, 0x30, 0x33, 0x2d, 0x32, 0x34, \ + 0x24, 0x05, 0x00, 0x24, 0x06, 0x00, 0x25, 0x07, 0x94, 0x26, 0x24, 0x08, 0x00, 0x18, 0x31, 0x7d, 0x30, 0x7b, 0x02, \ + 0x01, 0x03, 0x80, 0x14, 0x62, 0xfa, 0x82, 0x33, 0x59, 0xac, 0xfa, 0xa9, 0x96, 0x3e, 0x1c, 0xfa, 0x14, 0x0a, 0xdd, \ + 0xf5, 0x04, 0xf3, 0x71, 0x60, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x30, \ + 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x04, 0x47, 0x30, 0x45, 0x02, 0x20, 0x24, 0xe5, \ + 0xd1, 0xf4, 0x7a, 0x7d, 0x7b, 0x0d, 0x20, 0x6a, 0x26, 0xef, 0x69, 0x9b, 0x7c, 0x97, 0x57, 0xb7, 0x2d, 0x46, 0x90, \ + 0x89, 0xde, 0x31, 0x92, 0xe6, 0x78, 0xc7, 0x45, 0xe7, 0xf6, 0x0c, 0x02, 0x21, 0x00, 0xf8, 0xaa, 0x2f, 0xa7, 0x11, \ + 0xfc, 0xb7, 0x9b, 0x97, 0xe3, 0x97, 0xce, 0xda, 0x66, 0x7b, 0xae, 0x46, 0x4e, 0x2b, 0xd3, 0xff, 0xdf, 0xc3, 0xcc, \ + 0xed, 0x7a, 0xa8, 0xca, 0x5f, 0x4c, 0x1a, 0x7c \ + } +#endif + +/** + * CHIP_DEVICE_CONFIG_ENABLE_CHIP_TIME_SERVICE_TIME_SYNC + * + * Enables synchronizing the device's real time clock with a remote CHIP Time service + * using the CHIP Time Sync protocol. + */ +// #define CHIP_DEVICE_CONFIG_ENABLE_CHIP_TIME_SERVICE_TIME_SYNC 1 + +/** + * CHIP_CONFIG_MAX_BINDINGS + * + * Maximum number of simultaneously active bindings per ChipExchangeManager + * 1 (Time Sync) + 2 (Two 1-way subscriptions) + 1 (Software Update) = 4 + * in the worst case. Keeping another 4 as buffer. + */ +#define CHIP_CONFIG_MAX_BINDINGS 6 + +/** + * CHIP_CONFIG_EVENT_LOGGING_WDM_OFFLOAD + * + * Select the ability to offload event logs to any interested subscribers using WDM. + */ +#define CHIP_CONFIG_EVENT_LOGGING_WDM_OFFLOAD 1 + +/** + * CHIP_CONFIG_EVENT_LOGGING_UTC_TIMESTAMPS + * + * Enable recording UTC timestamps. + */ +#define CHIP_CONFIG_EVENT_LOGGING_UTC_TIMESTAMPS 1 + +/** + * CHIP_DEVICE_CONFIG_EVENT_LOGGING_DEBUG_BUFFER_SIZE + * + * A size, in bytes, of the individual debug event logging buffer. + */ +#define CHIP_DEVICE_CONFIG_EVENT_LOGGING_DEBUG_BUFFER_SIZE (512) + +/** + * CHIP_CONFIG_EVENT_LOGGING_DEFAULT_IMPORTANCE + * + * For a development build, set the default importance of events to be logged as Debug. + * Since debug is the lowest importance level, this means all standard, critical, info and + * debug importance level vi events get logged. + */ +#if BUILD_RELEASE +#define CHIP_CONFIG_EVENT_LOGGING_DEFAULT_IMPORTANCE chip::Profiles::DataManagement::Production +#else +#define CHIP_CONFIG_EVENT_LOGGING_DEFAULT_IMPORTANCE chip::Profiles::DataManagement::Debug +#endif // BUILD_RELEASE + +/* Increasing the retransmission interval of the MRP messages after subsequent failures */ +#ifndef CHIP_CONFIG_MRP_LOCAL_ACTIVE_RETRY_INTERVAL +#define CHIP_CONFIG_MRP_LOCAL_ACTIVE_RETRY_INTERVAL (2000_ms32) +#endif diff --git a/examples/thermostat/nxp/rt/rt1060/third_party/connectedhomeip b/examples/thermostat/nxp/rt/rt1060/third_party/connectedhomeip new file mode 120000 index 00000000000000..305f2077ffe860 --- /dev/null +++ b/examples/thermostat/nxp/rt/rt1060/third_party/connectedhomeip @@ -0,0 +1 @@ +../../../../../.. \ No newline at end of file diff --git a/examples/thermostat/nxp/rt/rt1170/.gn b/examples/thermostat/nxp/rt/rt1170/.gn new file mode 100644 index 00000000000000..59dcfeb229ae70 --- /dev/null +++ b/examples/thermostat/nxp/rt/rt1170/.gn @@ -0,0 +1,35 @@ +# Copyright (c) 2020 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/build.gni") +import("//build_overrides/chip.gni") + +# The location of the build configuration file. +buildconfig = "${build_root}/config/BUILDCONFIG.gn" + +# CHIP uses angle bracket includes. +check_system_includes = true + +default_args = { + target_cpu = "arm" + target_os = "freertos" + + import("//args.gni") + + # Import common example GN args + import("${chip_root}/examples/platform/nxp/common/gn/args.gni") + + # Import default platform configs + import("${chip_root}/src/platform/nxp/rt/rt1170/args.gni") +} diff --git a/examples/thermostat/nxp/rt/rt1170/BUILD.gn b/examples/thermostat/nxp/rt/rt1170/BUILD.gn new file mode 100644 index 00000000000000..c89df14eb5fc01 --- /dev/null +++ b/examples/thermostat/nxp/rt/rt1170/BUILD.gn @@ -0,0 +1,257 @@ +# Copyright (c) 2021-2023 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/build.gni") +import("//build_overrides/chip.gni") +import("//build_overrides/nxp_sdk.gni") +import("//build_overrides/openthread.gni") +import("${chip_root}/src/platform/device.gni") + +#allows to get common NXP SDK gn options +import("${nxp_sdk_build_root}/nxp_sdk.gni") + +# Allows to get various RT gn options +import("${nxp_sdk_build_root}/${nxp_sdk_name}/rt_sdk.gni") + +import("${chip_root}/src/platform/nxp/${nxp_platform}/args.gni") +import( + "${nxp_sdk_build_root}/${nxp_sdk_name}/${rt_platform}/${rt_platform}.gni") +import("${nxp_sdk_build_root}/${nxp_sdk_name}/nxp_executable.gni") + +assert(current_os == "freertos") +assert(target_os == "freertos") +assert(nxp_platform == "rt/rt1170") + +declare_args() { + # Allows to connect to a predefine Wi-Fi network at boot + wifi_auto_connect_at_boot = false + wifi_auto_connect_at_boot_ssid = "" + wifi_auto_connect_at_boot_password = "" + + # Setup discriminator as argument + setup_discriminator = 3840 + + chip_with_diag_logs_demo = true +} + +example_platform_dir = + "${nxp_sdk_matter_support_root}/examples/platform/${nxp_platform}" +common_example_dir = "${chip_root}/examples/platform/nxp/common" + +app_common_folder = "thermostat/nxp/zap" + +# Create here the SDK instance. +# Particular sources/defines/includes could be added/changed depending on the target application. +rt_sdk("sdk") { + defines = [] + + cflags = [] + public_deps = [] + public_configs = [] + sources = [] + include_dirs = [] + + # Indicate paths to default board files + include_dirs += [ "${example_platform_dir}/board/" ] + sources += [ "${example_platform_dir}/board/pin_mux.c" ] + sources += [ "${example_platform_dir}/board/hardware_init.c" ] + sources += [ "${example_platform_dir}/board/clock_config.c" ] + sources += [ "${example_platform_dir}/board/board.c" ] + sources += [ "${example_platform_dir}/board/peripherals.c" ] + sources += [ "${example_platform_dir}/board/sdmmc_config.c" ] + + # Indicate the path to CHIPProjectConfig.h + include_dirs += [ "include/config" ] + + # Indicate the default path to FreeRTOSConfig.h + include_dirs += [ "${example_platform_dir}/app/project_include/freeRTOS" ] + + # Indicate the default path to OpenThreadConfig.h + include_dirs += [ "${example_platform_dir}/app/project_include/openthread" ] + + # For matter with BR feature, increase FreeRTOS heap size and enable TBR cluster + if (chip_enable_wifi && chip_enable_openthread) { + defines += [ + "configTOTAL_HEAP_SIZE=(size_t)(170 * 1024)", + "CHIP_DEVICE_CONFIG_ENABLE_TBR=1", + ] + } + defines += [ + "CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR=${setup_discriminator}", + ] +} + +# Create the SDK driver instance. +# Particular sources/defines/includes could be added to add other drivers not available in the default sdk driver template +rt1170_sdk_drivers("sdk_driver") { +} + +rt_executable("thermostat") { + output_name = "chip-rt1170-thermostat-example" + + defines = [ + "CONFIG_RENDEZVOUS_MODE=7", + "CONFIG_APP_FREERTOS_OS=1", + ] + + if (chip_enable_openthread) { + defines += [ "CONFIG_NET_L2_OPENTHREAD=1" ] + } + + if (chip_with_diag_logs_demo) { + defines += [ + "CONFIG_DIAG_LOGS_DEMO=1", + "CHIP_DEVICE_CONFIG_MAX_DIAG_LOG_SIZE=1024", + ] + } + + include_dirs = [ + "../../common/main/include", + "../../common/main", + "${chip_root}/examples/all-clusters-app/all-clusters-common/include", + "${chip_root}/examples/providers/", + ] + + sources = [ + "${chip_root}/examples/all-clusters-app/all-clusters-common/src/binding-handler.cpp", + "${chip_root}/examples/providers/DeviceInfoProviderImpl.cpp", + "../../common/main/AppTask.cpp", + "../../common/main/DeviceCallbacks.cpp", + "../../common/main/ZclCallbacks.cpp", + "../../common/main/include/AppEvent.h", + "../../common/main/include/AppTask.h", + "../../common/main/include/DeviceCallbacks.h", + "../../common/main/main.cpp", + ] + + if (chip_with_diag_logs_demo) { + include_dirs += [ + "${common_example_dir}/diagnostic_logs/include", + "${chip_root}", + ] + sources += [ + "${common_example_dir}/diagnostic_logs/source/DiagnosticLogsDemo.cpp", + "${common_example_dir}/diagnostic_logs/source/DiagnosticLogsProviderDelegateImpl.cpp", + ] + } + + # App common files + include_dirs += [ + "${common_example_dir}/icd/include", + "${common_example_dir}/matter_button/include", + "${common_example_dir}/matter_cli/include", + "${common_example_dir}/device_manager/include", + "${common_example_dir}/device_callbacks/include", + "${common_example_dir}/factory_data/include", + "${common_example_dir}/app_task/include", + ] + + sources += [ + "${common_example_dir}/app_task/source/AppTaskBase.cpp", + "${common_example_dir}/app_task/source/AppTaskFreeRTOS.cpp", + "${common_example_dir}/device_callbacks/source/CommonDeviceCallbacks.cpp", + "${common_example_dir}/device_manager/source/CHIPDeviceManager.cpp", + "${common_example_dir}/factory_data/source/AppFactoryDataDefaultImpl.cpp", + "${common_example_dir}/icd/source/ICDUtil.cpp", + "${common_example_dir}/matter_button/source/ButtonRegistrationEmpty.cpp", + ] + + deps = [ "${chip_root}/examples/${app_common_folder}" ] + + if (chip_enable_matter_cli) { + defines += [ "ENABLE_CHIP_SHELL" ] + deps += [ + "${chip_root}/examples/shell/shell_common:shell_common", + "${chip_root}/src/lib/shell:shell", + ] + sources += [ + "${common_example_dir}/matter_cli/source/AppCLIBase.cpp", + "${common_example_dir}/matter_cli/source/AppCLIFreeRTOS.cpp", + ] + } + + if (chip_enable_ota_requestor) { + include_dirs += [ "${common_example_dir}/ota_requestor/include" ] + sources += [ + "${common_example_dir}/ota_requestor/source/OTARequestorInitiator.cpp", + "${common_example_dir}/ota_requestor/source/OTARequestorInitiatorCommon.cpp", + ] + } + + if (wifi_auto_connect_at_boot) { + assert(wifi_auto_connect_at_boot_ssid != "" && + wifi_auto_connect_at_boot_password != "", + "WiFi SSID and password must be specified at build time!") + + defines += [ + "CONFIG_CHIP_APP_WIFI_CONNECT_AT_BOOT=1", + "CONFIG_CHIP_APP_WIFI_SSID=\"${wifi_auto_connect_at_boot_ssid}\"", + "CONFIG_CHIP_APP_WIFI_PASSWORD=\"${wifi_auto_connect_at_boot_password}\"", + ] + + include_dirs += [ "${common_example_dir}/wifi_connect/include" ] + sources += [ "${common_example_dir}/wifi_connect/source/WifiConnect.cpp" ] + } + + # In case a dedicated assert function needs to be supported the flag sdk_fsl_assert_support should be set to false + # The would add to the build a dedicated application assert implementation. + if (!sdk_fsl_assert_support) { + sources += [ "${common_example_dir}/app_assert/source/AppAssert.cpp" ] + } + + cflags = [ "-Wconversion" ] + + ldscript = + "${example_platform_dir}/app/ldscripts/MIMXRT1176xxxxx_cm7_flexspi_nor.ld" + + inputs = [ ldscript ] + + ldflags = [ + "-T" + rebase_path(ldscript, root_build_dir), + "-fno-common", + "-Wl,--defsym=__stack_size__=2048", + "-ffreestanding", + "-fno-builtin", + "-mapcs", + "-u qspiflash_config", + "-u image_vector_table", + "-u boot_data", + "-u dcd_data", + "-Wl,-print-memory-usage", + "-Wl,--no-warn-rwx-segments", + ] + + if (chip_enable_ota_requestor) { + if (no_mcuboot) { + # If "no_mcuboot" is set to true, the application will be linked at the base of the flash. + print( + "Warning : The OTA Requestor is enabled without MCUBoot. This will prevent the application from applying software updates.") + } else { + # we need to reserve enough space for the bootloader (MCUBoot) + # MCUBoot requires 0x40000 Bytes to be reserved at the base of the flash + # Consequently, some sections will need to be shifted + ldflags += [ "-Wl,--defsym=__m_mcuboot_size__=0x40000" ] + } + } + + output_dir = root_out_dir +} + +group("rt1170") { + deps = [ ":thermostat" ] +} + +group("default") { + deps = [ ":rt1170" ] +} diff --git a/examples/thermostat/nxp/rt/rt1170/README.md b/examples/thermostat/nxp/rt/rt1170/README.md new file mode 100644 index 00000000000000..97101758c8e389 --- /dev/null +++ b/examples/thermostat/nxp/rt/rt1170/README.md @@ -0,0 +1,5 @@ +# CHIP RT1170 Thermostat Application + +All instructions describing how to use a Matter application on NXP RT11170 can +be found in [README.md](../../../../all-clusters-app/nxp/rt/rt1170/README.md) +root readme diff --git a/examples/thermostat/nxp/rt/rt1170/args.gni b/examples/thermostat/nxp/rt/rt1170/args.gni new file mode 100644 index 00000000000000..c2d91a5db7bae7 --- /dev/null +++ b/examples/thermostat/nxp/rt/rt1170/args.gni @@ -0,0 +1,19 @@ +# Copyright (c) 2023 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/chip.gni") + +# SDK target definitions +nxp_sdk_target = get_label_info(":sdk", "label_no_toolchain") +nxp_sdk_driver_target = get_label_info(":sdk_driver", "label_no_toolchain") diff --git a/examples/thermostat/nxp/rt/rt1170/build_overrides b/examples/thermostat/nxp/rt/rt1170/build_overrides new file mode 120000 index 00000000000000..f10867042f4d19 --- /dev/null +++ b/examples/thermostat/nxp/rt/rt1170/build_overrides @@ -0,0 +1 @@ +../../../../build_overrides \ No newline at end of file diff --git a/examples/thermostat/nxp/rt/rt1170/include/config/CHIPProjectConfig.h b/examples/thermostat/nxp/rt/rt1170/include/config/CHIPProjectConfig.h new file mode 100644 index 00000000000000..dd73c6c9eaaedd --- /dev/null +++ b/examples/thermostat/nxp/rt/rt1170/include/config/CHIPProjectConfig.h @@ -0,0 +1,216 @@ +/* + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2020 Google LLC. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Example project configuration file for CHIP. + * + * This is a place to put application or project-specific overrides + * to the default configuration values for general CHIP features. + * + */ + +#pragma once + +/* + * Tells to the platform Factory Data Provider whether to use the example configuration or real/provisioned data. + */ +#ifndef CONFIG_CHIP_PLAT_LOAD_REAL_FACTORY_DATA +#define CONFIG_CHIP_PLAT_LOAD_REAL_FACTORY_DATA 0 +#endif + +/** + * CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID + * + * 0xFFF1: Test vendor. + */ +#define CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID 0xFFF1 + +/** + * CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID + * + */ +#define CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID 0x8005 + +#if !CONFIG_CHIP_PLAT_LOAD_REAL_FACTORY_DATA +// Use a default pairing code if one hasn't been provisioned in flash. +#ifndef CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE +#define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_PIN_CODE 20202021 +#endif + +#ifndef CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR +#define CHIP_DEVICE_CONFIG_USE_TEST_SETUP_DISCRIMINATOR 0xF00 +#endif + +// Use a default pairing code if one hasn't been provisioned in flash. +#define CHIP_DEVICE_CONFIG_USE_TEST_PAIRING_CODE "CHIPUS" + +/** + * CHIP_DEVICE_CONFIG_USE_TEST_SERIAL_NUMBER + * + * Enables the use of a hard-coded default serial number if none + * is found in CHIP NV storage. + */ +#define CHIP_DEVICE_CONFIG_USE_TEST_SERIAL_NUMBER "DUMMY_SN" + +#endif /* !CONFIG_CHIP_PLAT_LOAD_REAL_FACTORY_DATA */ + +/** + * CHIP_DEVICE_CONFIG_DEVICE_HARDWARE_VERSION + * + * The hardware version number assigned to device or product by the device vendor. This + * number is scoped to the device product id, and typically corresponds to a revision of the + * physical device, a change to its packaging, and/or a change to its marketing presentation. + * This value is generally *not* incremented for device software versions. + */ +#define CHIP_DEVICE_CONFIG_DEVICE_HARDWARE_VERSION 100 + +#ifndef CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION_STRING +#define CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION_STRING "v0.1.0" +#endif + +/** + * CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING + * + * A string identifying the software version running on the device. + * CHIP currently expects the software version to be in the format + * {MAJOR_VERSION}.0d{MINOR_VERSION} + */ +#ifndef CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING +#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING NXP_CONFIG_DEVICE_SOFTWARE_VERSION_STRING +#endif + +#ifndef CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION +#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION NXP_CONFIG_DEVICE_SOFTWARE_VERSION +#endif + +#ifndef CHIP_DEVICE_CONFIG_DEVICE_VENDOR_NAME +#define CHIP_DEVICE_CONFIG_DEVICE_VENDOR_NAME "NXP Semiconductors" +#endif + +#ifndef CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_NAME +#define CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_NAME "NXP Demo App" +#endif + +#ifndef CHIP_DEVICE_CONFIG_CERTIFICATION_DECLARATION +//-> format_version = 1 +//-> vendor_id = 0xFFF1 +//-> product_id_array = [ 0x8000, 0x8001, 0x8002, 0x8003, 0x8004, 0x8005, 0x8006, 0x8007, 0x8008, 0x8009, 0x800A, 0x800B, +// 0x800C, 0x800D, 0x800E, 0x800F, 0x8010, 0x8011, 0x8012, 0x8013, 0x8014, 0x8015, 0x8016, 0x8017, 0x8018, 0x8019, 0x801A, +// 0x801B, 0x801C, 0x801D, 0x801E, 0x801F, 0x8020, 0x8021, 0x8022, 0x8023, 0x8024, 0x8025, 0x8026, 0x8027, 0x8028, 0x8029, +// 0x802A, 0x802B, 0x802C, 0x802D, 0x802E, 0x802F, 0x8030, 0x8031, 0x8032, 0x8033, 0x8034, 0x8035, 0x8036, 0x8037, 0x8038, +// 0x8039, 0x803A, 0x803B, 0x803C, 0x803D, 0x803E, 0x803F, 0x8040, 0x8041, 0x8042, 0x8043, 0x8044, 0x8045, 0x8046, 0x8047, +// 0x8048, 0x8049, 0x804A, 0x804B, 0x804C, 0x804D, 0x804E, 0x804F, 0x8050, 0x8051, 0x8052, 0x8053, 0x8054, 0x8055, 0x8056, +// 0x8057, 0x8058, 0x8059, 0x805A, 0x805B, 0x805C, 0x805D, 0x805E, 0x805F, 0x8060, 0x8061, 0x8062, 0x8063 ] +//-> device_type_id = 0x0016 +//-> certificate_id = "ZIG20142ZB330003-24" +//-> security_level = 0 +//-> security_information = 0 +//-> version_number = 0x2694 +//-> certification_type = 0 +//-> dac_origin_vendor_id is not present +//-> dac_origin_product_id is not present +#define CHIP_DEVICE_CONFIG_CERTIFICATION_DECLARATION \ + { \ + 0x30, 0x82, 0x02, 0x19, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x82, 0x02, 0x0a, 0x30, \ + 0x82, 0x02, 0x06, 0x02, 0x01, 0x03, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, \ + 0x02, 0x01, 0x30, 0x82, 0x01, 0x71, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, \ + 0x01, 0x62, 0x04, 0x82, 0x01, 0x5e, 0x15, 0x24, 0x00, 0x01, 0x25, 0x01, 0xf1, 0xff, 0x36, 0x02, 0x05, 0x00, 0x80, \ + 0x05, 0x01, 0x80, 0x05, 0x02, 0x80, 0x05, 0x03, 0x80, 0x05, 0x04, 0x80, 0x05, 0x05, 0x80, 0x05, 0x06, 0x80, 0x05, \ + 0x07, 0x80, 0x05, 0x08, 0x80, 0x05, 0x09, 0x80, 0x05, 0x0a, 0x80, 0x05, 0x0b, 0x80, 0x05, 0x0c, 0x80, 0x05, 0x0d, \ + 0x80, 0x05, 0x0e, 0x80, 0x05, 0x0f, 0x80, 0x05, 0x10, 0x80, 0x05, 0x11, 0x80, 0x05, 0x12, 0x80, 0x05, 0x13, 0x80, \ + 0x05, 0x14, 0x80, 0x05, 0x15, 0x80, 0x05, 0x16, 0x80, 0x05, 0x17, 0x80, 0x05, 0x18, 0x80, 0x05, 0x19, 0x80, 0x05, \ + 0x1a, 0x80, 0x05, 0x1b, 0x80, 0x05, 0x1c, 0x80, 0x05, 0x1d, 0x80, 0x05, 0x1e, 0x80, 0x05, 0x1f, 0x80, 0x05, 0x20, \ + 0x80, 0x05, 0x21, 0x80, 0x05, 0x22, 0x80, 0x05, 0x23, 0x80, 0x05, 0x24, 0x80, 0x05, 0x25, 0x80, 0x05, 0x26, 0x80, \ + 0x05, 0x27, 0x80, 0x05, 0x28, 0x80, 0x05, 0x29, 0x80, 0x05, 0x2a, 0x80, 0x05, 0x2b, 0x80, 0x05, 0x2c, 0x80, 0x05, \ + 0x2d, 0x80, 0x05, 0x2e, 0x80, 0x05, 0x2f, 0x80, 0x05, 0x30, 0x80, 0x05, 0x31, 0x80, 0x05, 0x32, 0x80, 0x05, 0x33, \ + 0x80, 0x05, 0x34, 0x80, 0x05, 0x35, 0x80, 0x05, 0x36, 0x80, 0x05, 0x37, 0x80, 0x05, 0x38, 0x80, 0x05, 0x39, 0x80, \ + 0x05, 0x3a, 0x80, 0x05, 0x3b, 0x80, 0x05, 0x3c, 0x80, 0x05, 0x3d, 0x80, 0x05, 0x3e, 0x80, 0x05, 0x3f, 0x80, 0x05, \ + 0x40, 0x80, 0x05, 0x41, 0x80, 0x05, 0x42, 0x80, 0x05, 0x43, 0x80, 0x05, 0x44, 0x80, 0x05, 0x45, 0x80, 0x05, 0x46, \ + 0x80, 0x05, 0x47, 0x80, 0x05, 0x48, 0x80, 0x05, 0x49, 0x80, 0x05, 0x4a, 0x80, 0x05, 0x4b, 0x80, 0x05, 0x4c, 0x80, \ + 0x05, 0x4d, 0x80, 0x05, 0x4e, 0x80, 0x05, 0x4f, 0x80, 0x05, 0x50, 0x80, 0x05, 0x51, 0x80, 0x05, 0x52, 0x80, 0x05, \ + 0x53, 0x80, 0x05, 0x54, 0x80, 0x05, 0x55, 0x80, 0x05, 0x56, 0x80, 0x05, 0x57, 0x80, 0x05, 0x58, 0x80, 0x05, 0x59, \ + 0x80, 0x05, 0x5a, 0x80, 0x05, 0x5b, 0x80, 0x05, 0x5c, 0x80, 0x05, 0x5d, 0x80, 0x05, 0x5e, 0x80, 0x05, 0x5f, 0x80, \ + 0x05, 0x60, 0x80, 0x05, 0x61, 0x80, 0x05, 0x62, 0x80, 0x05, 0x63, 0x80, 0x18, 0x24, 0x03, 0x16, 0x2c, 0x04, 0x13, \ + 0x5a, 0x49, 0x47, 0x32, 0x30, 0x31, 0x34, 0x32, 0x5a, 0x42, 0x33, 0x33, 0x30, 0x30, 0x30, 0x33, 0x2d, 0x32, 0x34, \ + 0x24, 0x05, 0x00, 0x24, 0x06, 0x00, 0x25, 0x07, 0x94, 0x26, 0x24, 0x08, 0x00, 0x18, 0x31, 0x7d, 0x30, 0x7b, 0x02, \ + 0x01, 0x03, 0x80, 0x14, 0x62, 0xfa, 0x82, 0x33, 0x59, 0xac, 0xfa, 0xa9, 0x96, 0x3e, 0x1c, 0xfa, 0x14, 0x0a, 0xdd, \ + 0xf5, 0x04, 0xf3, 0x71, 0x60, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x30, \ + 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x04, 0x47, 0x30, 0x45, 0x02, 0x20, 0x24, 0xe5, \ + 0xd1, 0xf4, 0x7a, 0x7d, 0x7b, 0x0d, 0x20, 0x6a, 0x26, 0xef, 0x69, 0x9b, 0x7c, 0x97, 0x57, 0xb7, 0x2d, 0x46, 0x90, \ + 0x89, 0xde, 0x31, 0x92, 0xe6, 0x78, 0xc7, 0x45, 0xe7, 0xf6, 0x0c, 0x02, 0x21, 0x00, 0xf8, 0xaa, 0x2f, 0xa7, 0x11, \ + 0xfc, 0xb7, 0x9b, 0x97, 0xe3, 0x97, 0xce, 0xda, 0x66, 0x7b, 0xae, 0x46, 0x4e, 0x2b, 0xd3, 0xff, 0xdf, 0xc3, 0xcc, \ + 0xed, 0x7a, 0xa8, 0xca, 0x5f, 0x4c, 0x1a, 0x7c \ + } +#endif + +/** + * CHIP_DEVICE_CONFIG_ENABLE_CHIP_TIME_SERVICE_TIME_SYNC + * + * Enables synchronizing the device's real time clock with a remote CHIP Time service + * using the CHIP Time Sync protocol. + */ +// #define CHIP_DEVICE_CONFIG_ENABLE_CHIP_TIME_SERVICE_TIME_SYNC 1 + +/** + * CHIP_CONFIG_MAX_BINDINGS + * + * Maximum number of simultaneously active bindings per ChipExchangeManager + * 1 (Time Sync) + 2 (Two 1-way subscriptions) + 1 (Software Update) = 4 + * in the worst case. Keeping another 4 as buffer. + */ +#define CHIP_CONFIG_MAX_BINDINGS 6 + +/** + * CHIP_CONFIG_EVENT_LOGGING_WDM_OFFLOAD + * + * Select the ability to offload event logs to any interested subscribers using WDM. + */ +#define CHIP_CONFIG_EVENT_LOGGING_WDM_OFFLOAD 1 + +/** + * CHIP_CONFIG_EVENT_LOGGING_UTC_TIMESTAMPS + * + * Enable recording UTC timestamps. + */ +#define CHIP_CONFIG_EVENT_LOGGING_UTC_TIMESTAMPS 1 + +/** + * CHIP_DEVICE_CONFIG_EVENT_LOGGING_DEBUG_BUFFER_SIZE + * + * A size, in bytes, of the individual debug event logging buffer. + */ +#define CHIP_DEVICE_CONFIG_EVENT_LOGGING_DEBUG_BUFFER_SIZE (512) + +/** + * CHIP_CONFIG_EVENT_LOGGING_DEFAULT_IMPORTANCE + * + * For a development build, set the default importance of events to be logged as Debug. + * Since debug is the lowest importance level, this means all standard, critical, info and + * debug importance level vi events get logged. + */ +#if BUILD_RELEASE +#define CHIP_CONFIG_EVENT_LOGGING_DEFAULT_IMPORTANCE chip::Profiles::DataManagement::Production +#else +#define CHIP_CONFIG_EVENT_LOGGING_DEFAULT_IMPORTANCE chip::Profiles::DataManagement::Debug +#endif // BUILD_RELEASE + +/* Increasing the retransmission interval of the MRP messages after subsequent failures */ +#ifndef CHIP_CONFIG_MRP_LOCAL_ACTIVE_RETRY_INTERVAL +#define CHIP_CONFIG_MRP_LOCAL_ACTIVE_RETRY_INTERVAL (2000_ms32) +#endif diff --git a/examples/thermostat/nxp/rt/rt1170/third_party/connectedhomeip b/examples/thermostat/nxp/rt/rt1170/third_party/connectedhomeip new file mode 120000 index 00000000000000..305f2077ffe860 --- /dev/null +++ b/examples/thermostat/nxp/rt/rt1170/third_party/connectedhomeip @@ -0,0 +1 @@ +../../../../../.. \ No newline at end of file diff --git a/scripts/build/build/targets.py b/scripts/build/build/targets.py index 42738adce7c0c8..c49d6201b6fb54 100755 --- a/scripts/build/build/targets.py +++ b/scripts/build/build/targets.py @@ -517,6 +517,8 @@ def BuildNxpTarget(): target.AppendFixedTargets([ TargetPart('k32w0', board=NxpBoard.K32W0), TargetPart('k32w1', board=NxpBoard.K32W1), + TargetPart('rt1060', board=NxpBoard.RT1060), + TargetPart('rt1170', board=NxpBoard.RT1170), TargetPart('rw61x', board=NxpBoard.RW61X), TargetPart('rw61x_eth', board=NxpBoard.RW61X_ETH), TargetPart('mcxw71', board=NxpBoard.MCXW71) @@ -533,9 +535,9 @@ def BuildNxpTarget(): TargetPart('lighting', app=NxpApp.LIGHTING).OnlyIfRe('(k32w0|k32w1|mcxw71)'), TargetPart('contact-sensor', app=NxpApp.CONTACT).OnlyIfRe('(k32w0|k32w1|mcxw71)'), TargetPart('lock-app', app=NxpApp.LOCK_APP).OnlyIfRe('(k32w1|mcxw71)'), - TargetPart('all-clusters', app=NxpApp.ALLCLUSTERS).OnlyIfRe('rw61x'), - TargetPart('laundry-washer', app=NxpApp.LAUNDRYWASHER).OnlyIfRe('rw61x'), - TargetPart('thermostat', app=NxpApp.THERMOSTAT).OnlyIfRe('rw61x') + TargetPart('all-clusters', app=NxpApp.ALLCLUSTERS).OnlyIfRe('rt1060|rt1170|rw61x'), + TargetPart('laundry-washer', app=NxpApp.LAUNDRYWASHER).OnlyIfRe('rt1060|rt1170|rw61x'), + TargetPart('thermostat', app=NxpApp.THERMOSTAT).OnlyIfRe('rt1060|rt1170|rw61x') ]) target.AppendModifier(name="factory", enable_factory_data=True) @@ -547,15 +549,19 @@ def BuildNxpTarget(): target.AppendModifier(name="rotating-id", enable_rotating_id=True).ExceptIfRe('rw61x') target.AppendModifier(name="sw-v2", has_sw_version_2=True) target.AppendModifier(name="ota", enable_ota=True).ExceptIfRe('zephyr') - target.AppendModifier(name="wifi", enable_wifi=True).OnlyIfRe('rw61x') + target.AppendModifier(name="wifi", enable_wifi=True).OnlyIfRe('rt1060|rt1170|rw61x') target.AppendModifier(name="ethernet", enable_ethernet=True).OnlyIfRe('rw61x_eth-zephyr') target.AppendModifier(name="thread", enable_thread=True).ExceptIfRe('zephyr') target.AppendModifier(name="matter-shell", enable_shell=True).ExceptIfRe('k32w0|k32w1') target.AppendModifier('data-model-disabled', data_model_interface="disabled").ExceptIfRe('-data-model-enabled') target.AppendModifier('data-model-enabled', data_model_interface="enabled").ExceptIfRe('-data-model-disabled') - target.AppendModifier(name="factory-build", enable_factory_data_build=True).OnlyIfRe('rw61x') + target.AppendModifier(name="factory-build", enable_factory_data_build=True).OnlyIfRe('rt1060|rt1170|rw61x') target.AppendModifier(name="frdm", board_variant=NxpBoardVariant.FRDM).OnlyIfRe('rw61x') target.AppendModifier(name="cmake", build_system=NxpBuildSystem.CMAKE).OnlyIfRe('rw61x') + target.AppendModifier(name="evkc", board_variant=NxpBoardVariant.EVKC).OnlyIfRe('rt1060') + target.AppendModifier(name="iw416", iw416_transceiver=True).OnlyIfRe('rt1060') + target.AppendModifier(name="w8801", w8801_transceiver=True).OnlyIfRe('rt1060') + target.AppendModifier(name="iwx12", iwx12_transceiver=True).OnlyIfRe('rt1060|rt1170') return target diff --git a/scripts/build/builders/nxp.py b/scripts/build/builders/nxp.py index c78ea1ca58fee6..6070a18fd0ba60 100644 --- a/scripts/build/builders/nxp.py +++ b/scripts/build/builders/nxp.py @@ -51,6 +51,8 @@ def BuildSystem(self): class NxpBoard(Enum): K32W0 = auto() K32W1 = auto() + RT1060 = auto() + RT1170 = auto() RW61X = auto() RW61X_ETH = auto() MCXW71 = auto() @@ -60,6 +62,10 @@ def Name(self, os_env): return 'k32w0x' elif self == NxpBoard.K32W1: return 'k32w1' + elif self == NxpBoard.RT1060: + return 'rt1060' + elif self == NxpBoard.RT1170: + return 'rt1170' elif (self == NxpBoard.RW61X) or (self == NxpBoard.RW61X_ETH): if os_env == NxpOsUsed.ZEPHYR: if self == NxpBoard.RW61X_ETH: @@ -78,6 +84,10 @@ def FolderName(self, os_env): return 'k32w0' elif self == NxpBoard.K32W1: return 'k32w1' + elif self == NxpBoard.RT1060: + return 'rt/rt1060' + elif self == NxpBoard.RT1170: + return 'rt/rt1170' elif (self == NxpBoard.RW61X) or (self == NxpBoard.RW61X_ETH): if os_env == NxpOsUsed.ZEPHYR: return 'zephyr' @@ -92,15 +102,16 @@ def FolderName(self, os_env): class NxpBoardVariant(Enum): RD = auto() FRDM = auto() + EVKC = auto() + EVKB = auto() def BoardVariantName(self, board): - if board != NxpBoard.RW61X: - raise Exception('Board variants only supported for RW61X') - if self == NxpBoardVariant.RD: return "rdrw612bga" elif self == NxpBoardVariant.FRDM: return "frdm" + elif self == NxpBoardVariant.EVKC: + return "evkcmimxrt1060" class NxpApp(Enum): @@ -173,7 +184,10 @@ def __init__(self, enable_ota: bool = False, data_model_interface: Optional[str] = None, enable_factory_data_build: bool = False, - disable_pairing_autostart: bool = False): + disable_pairing_autostart: bool = False, + iw416_transceiver: bool = False, + w8801_transceiver: bool = False, + iwx12_transceiver: bool = False): super(NxpBuilder, self).__init__( root=app.BuildRoot(root, board, os_env), runner=runner) @@ -200,6 +214,9 @@ def __init__(self, self.enable_factory_data_build = enable_factory_data_build self.disable_pairing_autostart = disable_pairing_autostart self.board_variant = board_variant + self.iw416_transceiver = iw416_transceiver + self.w8801_transceiver = w8801_transceiver + self.iwx12_transceiver = iwx12_transceiver def GnBuildArgs(self): args = [] @@ -248,10 +265,32 @@ def GnBuildArgs(self): # thread is enabled by default on kw32 if self.board == NxpBoard.RW61X: args.append('chip_enable_openthread=true chip_inet_config_enable_ipv4=false') + if self.board == NxpBoard.RT1060: + args.append('chip_enable_openthread=true chip_inet_config_enable_ipv4=false') + if self.board == NxpBoard.RT1170: + args.append('chip_enable_openthread=true chip_inet_config_enable_ipv4=false') if self.data_model_interface is not None: args.append(f'chip_use_data_model_interface="{self.data_model_interface}"') + if self.board_variant: + if self.board == NxpBoard.RT1060: + flag_board_variant = "evkname=\\\"%s\\\"" % self.board_variant.BoardVariantName(self.board) + args.append(flag_board_variant) + if self.board == NxpBoard.RW61X: + flag_board_variant = "board_version=\\\"%s\\\"" % self.board_variant.BoardVariantName(self.board) + args.append(flag_board_variant) + + if self.iw416_transceiver: + args.append('iw416_transceiver=true') + + if self.w8801_transceiver: + # BLE not supported on this transceiver + args.append('w8801_transceiver=true chip_enable_ble=false') + + if self.iwx12_transceiver: + args.append('iwx12_transceiver=true') + return args def CmakeBuildFlags(self): diff --git a/scripts/build/testdata/all_targets_linux_x64.txt b/scripts/build/testdata/all_targets_linux_x64.txt index c9a9a40eedf5f6..3a1c592d2ae609 100644 --- a/scripts/build/testdata/all_targets_linux_x64.txt +++ b/scripts/build/testdata/all_targets_linux_x64.txt @@ -13,7 +13,7 @@ linux-{x64,arm64}-{rpc-console,all-clusters,all-clusters-minimal,chip-tool,therm linux-x64-efr32-test-runner[-clang] imx-{chip-tool,lighting-app,thermostat,all-clusters-app,all-clusters-minimal-app,ota-provider-app}[-release] infineon-psoc6-{lock,light,all-clusters,all-clusters-minimal}[-ota][-updateimage][-trustm] -nxp-{k32w0,k32w1,rw61x,rw61x_eth,mcxw71}-{zephyr,freertos}-{lighting,contact-sensor,lock-app,all-clusters,laundry-washer,thermostat}[-factory][-low-power][-lit][-fro32k][-smu2][-dac-conversion][-rotating-id][-sw-v2][-ota][-wifi][-ethernet][-thread][-matter-shell][-data-model-disabled][-data-model-enabled][-factory-build][-frdm][-cmake] +nxp-{k32w0,k32w1,rt1060,rt1170,rw61x,rw61x_eth,mcxw71}-{zephyr,freertos}-{lighting,contact-sensor,lock-app,all-clusters,laundry-washer,thermostat}[-factory][-low-power][-lit][-fro32k][-smu2][-dac-conversion][-rotating-id][-sw-v2][-ota][-wifi][-ethernet][-thread][-matter-shell][-data-model-disabled][-data-model-enabled][-factory-build][-frdm][-cmake][-evkc][-iw416][-w8801][-iwx12] mbed-cy8cproto_062_4343w-{lock,light,all-clusters,all-clusters-minimal,pigweed,ota-requestor,shell}[-release][-develop][-debug][-data-model-disabled][-data-model-enabled] mw320-all-clusters-app nrf-{nrf5340dk,nrf52840dk,nrf52840dongle}-{all-clusters,all-clusters-minimal,lock,light,light-switch,shell,pump,pump-controller,window-covering}[-rpc][-data-model-disabled][-data-model-enabled] diff --git a/src/platform/nxp/rt/rt1060/BUILD.gn b/src/platform/nxp/rt/rt1060/BUILD.gn new file mode 100644 index 00000000000000..1e3d8f1e1e6ba9 --- /dev/null +++ b/src/platform/nxp/rt/rt1060/BUILD.gn @@ -0,0 +1,187 @@ +# Copyright (c) 2021 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/build.gni") +import("//build_overrides/chip.gni") +import("//build_overrides/nxp_sdk.gni") +import("//build_overrides/openthread.gni") +import("${chip_root}/src/platform/device.gni") + +# If external SDK is used, do not import ${nxp_sdk_name}.gni +if (!nxp_external_sdk) { + import("${nxp_sdk_build_root}/${nxp_sdk_name}/${nxp_sdk_name}.gni") +} + +import("${nxp_sdk_build_root}/nxp_sdk.gni") + +assert(chip_device_platform == "nxp") + +source_set("nxp_factory_data") { +} +source_set("nxp_ota") { +} + +config("nxp_platform_config") { + defines = [ "EXTERNAL_BLEMANAGERIMPL_HEADER=\"platform/nxp/common/ble_zephyr/BLEManagerImpl.h\"" ] + include_dirs = [ + ".", + "../../common", + ] + if (chip_with_factory_data == 1) { + include_dirs += [ + ".", + "../../common/factory_data", + ] + defines += [ "CONFIG_CHIP_PLAT_LOAD_REAL_FACTORY_DATA=1" ] + defines += [ "EXTERNAL_FACTORY_DATA_PROVIDER_IMPL_HEADER=\"platform/nxp/rt/rt1060/FactoryDataProviderImpl.h\"" ] + } + + # When OTBR is enabled Thread network commissioning cluster is enabled using chip_enable_secondary_nwk_if + if (chip_enable_wifi && chip_enable_openthread && + !chip_enable_secondary_nwk_if) { + defines += [ "_NO_GENERIC_THREAD_NETWORK_COMMISSIONING_DRIVER_" ] + } +} + +static_library("nxp_platform") { + output_name = "libCHIP_NXP_Port_RT1060" + cflags = [ + "-Wno-conversion", + "-Wno-sign-compare", + ] + deps = [] + defines = [] + sources = [ + "../../../FreeRTOS/SystemTimeSupport.cpp", + "../../../SingletonConfigurationManager.cpp", + "../../common/CHIPDevicePlatformEvent.h", + "../../common/ConfigurationManagerImpl.cpp", + "../../common/ConfigurationManagerImpl.h", + "../../common/ConnectivityManagerImpl.cpp", + "../../common/ConnectivityManagerImpl.h", + "../../common/DiagnosticDataProviderImpl.cpp", + "../../common/DiagnosticDataProviderImpl.h", + "../../common/KeyValueStoreManagerImpl.cpp", + "../../common/KeyValueStoreManagerImpl.h", + "../../common/Logging.cpp", + "../../common/NXPConfig.cpp", + "../../common/NXPConfig.h", + "../../common/NetworkProvisioningServerImpl.h", + "../../common/PlatformManagerImpl.h", + "../../common/SoftwareUpdateManagerImpl.h", + "../../common/ram_storage.c", + "../../common/ram_storage.h", + "CHIPDevicePlatformConfig.h", + "PlatformManagerImpl.cpp", + ] + + if (chip_enable_ble) { + sources += [ + # Adding random file which defines the function sys_csrand_get which is called by BLEManagerImpl from Zephyr + "${nxp_sdk_build_root}/rt_sdk/sdk_hook/zephyr/random/random.cpp", + "../../common/ble_zephyr/BLEAdvertisingArbiter.cpp", + "../../common/ble_zephyr/BLEManagerImpl.cpp", + "../../common/ble_zephyr/BLEManagerImpl.h", + ] + } + + public_deps = [ "${chip_root}/src/platform:platform_base" ] + + deps += [ + "${chip_root}/src/lib/dnssd:constants", + "${chip_root}/src/platform/logging:headers", + ] + + # define CHIP_PLAT_NVM_SUPPORT - See NXPConfig.cpp for definition + if (nxp_nvm_component == "nvm_fwk") { + defines += [ "CHIP_PLAT_NVM_SUPPORT=1" ] + } else if (nxp_nvm_component == "littlefs") { + defines += [ "CHIP_PLAT_NVM_SUPPORT=2" ] + } + + if (chip_enable_wifi) { + sources += [ + "../../common/NetworkCommissioningDriver.h", + "../../common/NetworkCommissioningWiFiDriver.cpp", + ] + } + if (chip_enable_ota_requestor) { + sources += [ + "../../common/OTAImageProcessorImpl.cpp", + "../../common/OTAImageProcessorImpl.h", + ] + } + + if (chip_enable_openthread) { + sources += [ + # Temporary fix, to be revert once PR #34662 is merged, build issue when using GN check argument + "${chip_root}/src/app/clusters/thread-border-router-management-server/thread-br-delegate.h", + "../../../OpenThread/GenericThreadBorderRouterDelegate.cpp", + "../../../OpenThread/GenericThreadBorderRouterDelegate.h", + "../../../OpenThread/OpenThreadUtils.cpp", + "../../common/ThreadStackManagerImpl.cpp", + "../../common/ThreadStackManagerImpl.h", + ] + + deps += [ "${chip_root}/src/app/common:ids" ] + + if (!nxp_build_matter_standalone_lib) { + deps += [ "${chip_root}/third_party/openthread:openthread" ] + public_deps += + [ "${chip_root}/third_party/openthread:openthread-platform" ] + } + + # dep required to include 'lib/spinel/spinel.h' in PlatformManagerImpl.cpp + deps += [ "${openthread_root}:libopenthread-spinel-rcp" ] + + if (chip_mdns == "platform") { + if (chip_enable_wifi) { + sources += [ + "../../../OpenThread/OpenThreadDnssdImpl.cpp", + "../../../OpenThread/OpenThreadDnssdImpl.h", + "../../common/DnssdImpl.cpp", + "../../common/DnssdImplBr.cpp", + "../../common/DnssdImplBr.h", + ] + } else { + sources += [ + "../../../OpenThread/DnssdImpl.cpp", + "../../../OpenThread/OpenThreadDnssdImpl.cpp", + "../../../OpenThread/OpenThreadDnssdImpl.h", + ] + } + deps += [ "${chip_root}/src/lib/dnssd:platform_header" ] + } + } + + if (chip_with_factory_data == 1) { + sources += [ + "../../common/factory_data/FactoryDataProvider.cpp", + "../../common/factory_data/FactoryDataProvider.h", + "FactoryDataProviderImpl.cpp", + "FactoryDataProviderImpl.h", + ] + + deps += [ "${chip_root}/src/credentials:credentials_header" ] + } + + deps += [ "${nxp_sdk_build_root}:nxp_sdk" ] + + public_deps += [ + "${chip_root}/examples/platform/nxp/common/app/support:freertos_memory_utils", + "${chip_root}/src/crypto", + "${chip_root}/src/platform:syscalls_stub", + ] + public_configs = [ ":nxp_platform_config" ] +} diff --git a/src/platform/nxp/rt/rt1060/BlePlatformConfig.h b/src/platform/nxp/rt/rt1060/BlePlatformConfig.h new file mode 100644 index 00000000000000..61ad3de197edef --- /dev/null +++ b/src/platform/nxp/rt/rt1060/BlePlatformConfig.h @@ -0,0 +1,36 @@ +/* + * + * Copyright (c) 2021-2022 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Platform-specific configuration overrides for the CHIP BLE + * Layer on RT1060 platforms using the NXP SDK. + * + */ + +#pragma once + +// ==================== Platform Adaptations ==================== + +/* Default NXP Platform adaptations are used */ + +// ========== Platform-specific Configuration Overrides ========= + +/* Default NXP Platform configuration overrides are used */ + +// Include default nxp platform configurations +#include "platform/nxp/common/ble_zephyr/BleNXPPlatformDefaultConfig.h" diff --git a/src/platform/nxp/rt/rt1060/CHIPDevicePlatformConfig.h b/src/platform/nxp/rt/rt1060/CHIPDevicePlatformConfig.h new file mode 100644 index 00000000000000..0e45bd41086c89 --- /dev/null +++ b/src/platform/nxp/rt/rt1060/CHIPDevicePlatformConfig.h @@ -0,0 +1,42 @@ +/* + * + * Copyright (c) 2020-2022 Project CHIP Authors + * Copyright (c) 2020 Google LLC. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Platform-specific configuration overrides for the chip Device Layer + * on NXP platforms using the NXP SDK. + */ + +#pragma once + +// ==================== Platform Adaptations ==================== + +/* Default NXP Platform adaptations are used */ + +// ========== Platform-specific Configuration ========= + +// These are configuration options that are unique to the NXP platform. +// These can be overridden by the application as needed. + +// ========== Platform-specific Configuration Overrides ========= + +/* Default NXP Platform configuration overrides are used */ + +// Include default nxp platform configurations +#include "platform/nxp/common/CHIPDeviceNXPPlatformDefaultConfig.h" diff --git a/src/platform/nxp/rt/rt1060/CHIPPlatformConfig.h b/src/platform/nxp/rt/rt1060/CHIPPlatformConfig.h new file mode 100644 index 00000000000000..7b08c5c17f7a94 --- /dev/null +++ b/src/platform/nxp/rt/rt1060/CHIPPlatformConfig.h @@ -0,0 +1,54 @@ +/* + * + * Copyright (c) 2020-2022 Project CHIP Authors + * Copyright (c) 2020 Google LLC. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Platform-specific configuration overrides for CHIP on + * NXP RT1060 platforms. + */ + +#pragma once + +#include + +// ==================== General Platform Adaptations ==================== + +/* Default NXP platform adaptations are used */ + +// ==================== Security Adaptations ==================== + +/* Default NXP Platform security adaptations are used */ + +// ==================== General Configuration Overrides ==================== + +/* Default NXP Platform general configuration overrides are used */ + +/* For now on RT1060, due to the current file system implementation only 5 fabrics are supported */ +#define CHIP_CONFIG_MAX_FABRICS 5 + +// ==================== Security Configuration Overrides ==================== + +/* Default NXP Platform security configuration overrides are used */ + +// ==================== WDM Configuration Overrides ==================== + +/* Default NXP Platform WDM Configuration overrides are used */ + +// Include default nxp platform configurations +#include "platform/nxp/common/CHIPNXPPlatformDefaultConfig.h" diff --git a/src/platform/nxp/rt/rt1060/FactoryDataProviderImpl.cpp b/src/platform/nxp/rt/rt1060/FactoryDataProviderImpl.cpp new file mode 100644 index 00000000000000..3fac3c7385f862 --- /dev/null +++ b/src/platform/nxp/rt/rt1060/FactoryDataProviderImpl.cpp @@ -0,0 +1,381 @@ +/* + * + * Copyright (c) 2022-2024 Project CHIP Authors + * Copyright 2023-2024 NXP + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "FactoryDataProviderImpl.h" + +#if defined(__cplusplus) +extern "C" { +#endif /* __cplusplus */ + +#include "fsl_dcp.h" +#include "mflash_drv.h" + +#if defined(__cplusplus) +} +#endif /* __cplusplus */ + +#ifndef FACTORY_DATA_PROVIDER_LOG +#define FACTORY_DATA_PROVIDER_LOG 0 +#endif + +#if FACTORY_DATA_PROVIDER_LOG +#include "fsl_debug_console.h" +#define FACTORY_DATA_PROVIDER_PRINTF(...) \ + PRINTF("[%s] ", __FUNCTION__); \ + PRINTF(__VA_ARGS__); \ + PRINTF("\n\r"); +#else +#define FACTORY_DATA_PROVIDER_PRINTF(...) +#endif + +#define BLOCK_SIZE_16_BYTES 16 +#define SHA256_OUTPUT_SIZE 32 +#define HASH_ID 0xCE47BA5E +#define HASH_LEN 4 +#define CBC_INITIAL_VECTOR_SIZE 16 + +/* Grab symbol for the base address from the linker file. */ +extern uint32_t __FACTORY_DATA_START_OFFSET[]; +extern uint32_t __FACTORY_DATA_SIZE[]; + +namespace chip { +namespace DeviceLayer { + +FactoryDataProviderImpl FactoryDataProviderImpl::sInstance; + +CHIP_ERROR FactoryDataProviderImpl::SearchForId(uint8_t searchedType, uint8_t * pBuf, size_t bufLength, uint16_t & length, + uint32_t * contentAddr) +{ + CHIP_ERROR err = CHIP_ERROR_NOT_FOUND; + uint8_t type = 0; + uint32_t index = 0; + uint8_t * addrContent = NULL; + uint8_t * factoryDataAddress = &factoryDataRamBuffer[0]; + uint32_t factoryDataSize = sizeof(factoryDataRamBuffer); + uint16_t currentLen = 0; + + while (index < factoryDataSize) + { + /* Read the type */ + memcpy((uint8_t *) &type, factoryDataAddress + index, sizeof(type)); + index += sizeof(type); + + /* Read the len */ + memcpy((uint8_t *) ¤tLen, factoryDataAddress + index, sizeof(currentLen)); + index += sizeof(currentLen); + + /* Check if the type gotten is the expected one */ + if (searchedType == type) + { + FACTORY_DATA_PROVIDER_PRINTF("type = %d, currentLen = %d, bufLength =%d", type, currentLen, bufLength); + /* If pBuf is null it means that we only want to know if the Type has been found */ + if (pBuf != NULL) + { + /* If the buffer given is too small, fill only the available space */ + if (bufLength < currentLen) + { + currentLen = bufLength; + } + memcpy((uint8_t *) pBuf, factoryDataAddress + index, currentLen); + } + length = currentLen; + if (contentAddr != NULL) + { + *contentAddr = (uint32_t) factoryDataAddress + index; + } + err = CHIP_NO_ERROR; + break; + } + else if (type == 0) + { + /* No more type available , break the loop */ + break; + } + else + { + /* Jump to next data */ + index += currentLen; + } + } + + return err; +} + +CHIP_ERROR FactoryDataProviderImpl::SignWithDacKey(const ByteSpan & digestToSign, MutableByteSpan & outSignBuffer) +{ + Crypto::P256ECDSASignature signature; + Crypto::P256Keypair keypair; + + VerifyOrReturnError(IsSpanUsable(outSignBuffer), CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(IsSpanUsable(digestToSign), CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(outSignBuffer.size() >= signature.Capacity(), CHIP_ERROR_BUFFER_TOO_SMALL); + + // In a non-exemplary implementation, the public key is not needed here. It is used here merely because + // Crypto::P256Keypair is only (currently) constructable from raw keys if both private/public keys are present. + Crypto::P256PublicKey dacPublicKey; + uint16_t certificateSize = 0; + uint32_t certificateAddr; + ReturnErrorOnFailure(SearchForId(FactoryDataId::kDacCertificateId, NULL, 0, certificateSize, &certificateAddr)); + MutableByteSpan dacCertSpan((uint8_t *) certificateAddr, certificateSize); + + /* Extract Public Key of DAC certificate from itself */ + ReturnErrorOnFailure(Crypto::ExtractPubkeyFromX509Cert(dacCertSpan, dacPublicKey)); + + /* Get private key of DAC certificate from reserved section */ + uint16_t keySize = 0; + uint32_t keyAddr; + ReturnErrorOnFailure(SearchForId(FactoryDataId::kDacPrivateKeyId, NULL, 0, keySize, &keyAddr)); + MutableByteSpan dacPrivateKeySpan((uint8_t *) keyAddr, keySize); + + ReturnErrorOnFailure(LoadKeypairFromRaw(ByteSpan(dacPrivateKeySpan.data(), dacPrivateKeySpan.size()), + ByteSpan(dacPublicKey.Bytes(), dacPublicKey.Length()), keypair)); + + ReturnErrorOnFailure(keypair.ECDSA_sign_msg(digestToSign.data(), digestToSign.size(), signature)); + + return CopySpanToMutableSpan(ByteSpan{ signature.ConstBytes(), signature.Length() }, outSignBuffer); +} + +CHIP_ERROR FactoryDataProviderImpl::LoadKeypairFromRaw(ByteSpan privateKey, ByteSpan publicKey, Crypto::P256Keypair & keypair) +{ + Crypto::P256SerializedKeypair serialized_keypair; + ReturnErrorOnFailure(serialized_keypair.SetLength(privateKey.size() + publicKey.size())); + memcpy(serialized_keypair.Bytes(), publicKey.data(), publicKey.size()); + memcpy(serialized_keypair.Bytes() + publicKey.size(), privateKey.data(), privateKey.size()); + return keypair.Deserialize(serialized_keypair); +} + +CHIP_ERROR FactoryDataProviderImpl::Init(void) +{ + uint16_t len; + status_t status; + uint32_t factoryDataAddress = (uint32_t) __FACTORY_DATA_START_OFFSET; + uint32_t factoryDataSize = (uint32_t) __FACTORY_DATA_SIZE; + uint32_t hashId; + uint8_t currentBlock[BLOCK_SIZE_16_BYTES]; + uint8_t calculatedHash[SHA256_OUTPUT_SIZE]; + size_t outputHashSize = sizeof(calculatedHash); + uint16_t i; + CHIP_ERROR res; + + /* Init mflash */ + status = mflash_drv_init(); + + if (status != kStatus_Success || factoryDataSize > sizeof(factoryDataRamBuffer)) + return CHIP_ERROR_INTERNAL; + + /* Read hash id saved in flash */ + if (mflash_drv_read(factoryDataAddress, (uint32_t *) &mHeader, sizeof(mHeader)) != kStatus_Success) + { + return CHIP_ERROR_INTERNAL; + } + + if (mHeader.hashId != HASH_ID) + { + return CHIP_ERROR_NOT_FOUND; + } + + /* Update address to start after hash id to read size of factory data */ + factoryDataAddress += sizeof(mHeader); + + /* Load the buffer into RAM by reading each 16 bytes blocks */ + for (i = 0; i < (factoryDataSize / BLOCK_SIZE_16_BYTES); i++) + { + if (mflash_drv_read(factoryDataAddress + i * BLOCK_SIZE_16_BYTES, (uint32_t *) ¤tBlock[0], sizeof(currentBlock)) != + kStatus_Success) + { + return CHIP_ERROR_INTERNAL; + } + + /* Decrypt data if an encryptMode is set */ + if (encryptMode != encrypt_none) + { + res = ReadEncryptedData(&factoryDataRamBuffer[i * BLOCK_SIZE_16_BYTES], ¤tBlock[0], sizeof(currentBlock)); + if (res != CHIP_NO_ERROR) + return res; + } + else + { + /* Store the block unencrypted */ + memcpy(&factoryDataRamBuffer[i * BLOCK_SIZE_16_BYTES], ¤tBlock[0], sizeof(currentBlock)); + } + } + + /* Calculate SHA256 value over the factory data and compare with stored value */ + res = Hash256(&factoryDataRamBuffer[0], mHeader.size, &calculatedHash[0], &outputHashSize); + + if (res != CHIP_NO_ERROR) + return res; + + if (memcmp(&calculatedHash[0], &mHeader.hash[0], HASH_LEN) != 0) + { + return CHIP_ERROR_NOT_FOUND; + } + + ReturnErrorOnFailure(SearchForId(FactoryDataId::kVerifierId, NULL, 0, len)); + FACTORY_DATA_PROVIDER_PRINTF("[%d] len = %d", FactoryDataId::kVerifierId, len); + ReturnErrorOnFailure(SearchForId(FactoryDataId::kSaltId, NULL, 0, len)); + FACTORY_DATA_PROVIDER_PRINTF("[%d] len = %d", FactoryDataId::kSaltId, len); + ReturnErrorOnFailure(SearchForId(FactoryDataId::kIcId, NULL, 0, len)); + FACTORY_DATA_PROVIDER_PRINTF("[%d] len = %d", FactoryDataId::kIcId, len); + ReturnErrorOnFailure(SearchForId(FactoryDataId::kDacPrivateKeyId, NULL, 0, len)); + FACTORY_DATA_PROVIDER_PRINTF("[%d] len = %d", FactoryDataId::kDacPrivateKeyId, len); + ReturnErrorOnFailure(SearchForId(FactoryDataId::kDacCertificateId, NULL, 0, len)); + FACTORY_DATA_PROVIDER_PRINTF("[%d] len = %d", FactoryDataId::kDacCertificateId, len); + ReturnErrorOnFailure(SearchForId(FactoryDataId::kPaiCertificateId, NULL, 0, len)); + FACTORY_DATA_PROVIDER_PRINTF("[%d] len = %d", FactoryDataId::kPaiCertificateId, len); + ReturnErrorOnFailure(SearchForId(FactoryDataId::kDiscriminatorId, NULL, 0, len)); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR FactoryDataProviderImpl::SetAes128Key(const uint8_t * keyAes128) +{ + CHIP_ERROR error = CHIP_ERROR_INVALID_ARGUMENT; + if (keyAes128 != nullptr) + { + pAesKey = keyAes128; + error = CHIP_NO_ERROR; + } + return error; +} + +CHIP_ERROR FactoryDataProviderImpl::SetKeySelected(KeySelect key) +{ + CHIP_ERROR error = CHIP_ERROR_INVALID_ARGUMENT; + if (key <= kDCP_OCOTPKeyHigh) + { + selectedKey = key; + error = CHIP_NO_ERROR; + } + return error; +} + +void FactoryDataProviderImpl::SetDCP_OTPKeySelect(void) +{ + switch (selectedKey) + { + case kDCP_OTPMKKeyLow: + IOMUXC_GPR->GPR3 &= ~(1 << IOMUXC_GPR_GPR3_DCP_KEY_SEL_SHIFT); + IOMUXC_GPR->GPR10 &= ~(1 << IOMUXC_GPR_GPR10_DCPKEY_OCOTP_OR_KEYMUX_SHIFT); + break; + case kDCP_OTPMKKeyHigh: + IOMUXC_GPR->GPR3 |= (1 << IOMUXC_GPR_GPR3_DCP_KEY_SEL_SHIFT); + IOMUXC_GPR->GPR10 &= ~(1 << IOMUXC_GPR_GPR10_DCPKEY_OCOTP_OR_KEYMUX_SHIFT); + break; + case kDCP_OCOTPKeyLow: + IOMUXC_GPR->GPR3 &= ~(1 << IOMUXC_GPR_GPR3_DCP_KEY_SEL_SHIFT); + IOMUXC_GPR->GPR10 |= (1 << IOMUXC_GPR_GPR10_DCPKEY_OCOTP_OR_KEYMUX_SHIFT); + break; + case kDCP_OCOTPKeyHigh: + IOMUXC_GPR->GPR3 |= (1 << IOMUXC_GPR_GPR3_DCP_KEY_SEL_SHIFT); + IOMUXC_GPR->GPR10 |= (1 << IOMUXC_GPR_GPR10_DCPKEY_OCOTP_OR_KEYMUX_SHIFT); + break; + default: + break; + } +} + +CHIP_ERROR FactoryDataProviderImpl::SetCbcInitialVector(const uint8_t * iv, uint16_t ivSize) +{ + CHIP_ERROR error = CHIP_ERROR_INVALID_ARGUMENT; + if (ivSize == CBC_INITIAL_VECTOR_SIZE) + { + cbcInitialVector = iv; + error = CHIP_NO_ERROR; + } + return error; +} + +CHIP_ERROR FactoryDataProviderImpl::SetEncryptionMode(EncryptionMode mode) +{ + CHIP_ERROR error = CHIP_ERROR_INVALID_ARGUMENT; + if (mode <= encrypt_cbc) + { + encryptMode = mode; + error = CHIP_NO_ERROR; + } + return error; +} + +CHIP_ERROR FactoryDataProviderImpl::ReadEncryptedData(uint8_t * desBuff, uint8_t * sourceAddr, uint16_t sizeToRead) +{ + status_t status; + dcp_handle_t m_handle; + dcp_config_t dcpConfig; + + /* Check that the length is aligned on 16 bytes */ + if ((sizeToRead % 16) != 0) + return CHIP_ERROR_INVALID_ARGUMENT; + + /* Check that the soft key has been correclty provisioned */ + if (selectedKey == kDCP_UseSoftKey && pAesKey == nullptr) + return CHIP_ERROR_INVALID_ARGUMENT; + + /* Check if the initial vector has been provisioned if CBC mode is chosen */ + if (encryptMode == encrypt_cbc && cbcInitialVector == nullptr) + return CHIP_ERROR_INVALID_ARGUMENT; + + if (!dcpDriverIsInitialized) + { + /* Initialize DCP */ + DCP_GetDefaultConfig(&dcpConfig); + SetDCP_OTPKeySelect(); + /* Reset and initialize DCP */ + DCP_Init(DCP, &dcpConfig); + dcpDriverIsInitialized = true; + } + + m_handle.channel = kDCP_Channel0; + m_handle.swapConfig = kDCP_NoSwap; + + if (selectedKey == kDCP_UseSoftKey) + m_handle.keySlot = kDCP_KeySlot0; + else + m_handle.keySlot = kDCP_OtpKey; + + status = DCP_AES_SetKey(DCP, &m_handle, pAesKey, 16); + if (status != kStatus_Success) + return CHIP_ERROR_INTERNAL; + + if (encryptMode == encrypt_ecb) + DCP_AES_DecryptEcb(DCP, &m_handle, sourceAddr, desBuff, sizeToRead); + else + DCP_AES_DecryptCbc(DCP, &m_handle, sourceAddr, desBuff, sizeToRead, cbcInitialVector); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR FactoryDataProviderImpl::Hash256(const uint8_t * input, size_t inputSize, uint8_t * output, size_t * outputSize) +{ + status_t status; + dcp_handle_t m_handle; + + m_handle.channel = kDCP_Channel0; + m_handle.swapConfig = kDCP_NoSwap; + m_handle.keySlot = kDCP_KeySlot0; + + status = DCP_HASH(DCP, &m_handle, kDCP_Sha256, input, inputSize, output, outputSize); + + if (status != kStatus_Success) + return CHIP_ERROR_INTERNAL; + + return CHIP_NO_ERROR; +} + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/nxp/rt/rt1060/FactoryDataProviderImpl.h b/src/platform/nxp/rt/rt1060/FactoryDataProviderImpl.h new file mode 100644 index 00000000000000..6eb65fab7207bd --- /dev/null +++ b/src/platform/nxp/rt/rt1060/FactoryDataProviderImpl.h @@ -0,0 +1,104 @@ +/* + * + * Copyright (c) 2022-2024 Project CHIP Authors + * Copyright 2023-2024 NXP + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#pragma once + +#include + +#define FACTORY_DATA_MAX_SIZE 4096 + +namespace chip { +namespace DeviceLayer { + +/** + * @brief This class provides Commissionable data and Device Attestation Credentials. + * + * This implementation allows to use the DCP RT1060 hardware module to load the Matter factory + * dataset in RAM at the boot. + * + * Depending on how the dataset have been encrypted, specific AES hardware of software keys can be + * used. + * + * Example of calls for loading the dataset using a software key: + * + * FactoryDataPrvdImpl().SetEncryptionMode(FactoryDataProvider::encrypt_ecb); + * FactoryDataPrvdImpl().SetAes128Key(&aes128TestKey[0]); + * FactoryDataPrvdImpl().Init(); + * + * Example of calls for loading the dataset using a OTP key: + * + * FactoryDataPrvdImpl().SetEncryptionMode(FactoryDataProvider::encrypt_ecb); + * FactoryDataPrvdImpl().SetKeySelected(KeySelect::); + * FactoryDataPrvdImpl().Init(); + */ + +class FactoryDataProviderImpl : public FactoryDataProvider +{ +public: + enum KeySelect + { + kDCP_UseSoftKey = 0U, + kDCP_OTPMKKeyLow = 1U, /* Use [127:0] from snvs key as dcp key */ + kDCP_OTPMKKeyHigh = 2U, /* Use [255:128] from snvs key as dcp key */ + kDCP_OCOTPKeyLow = 3U, /* Use [127:0] from ocotp key as dcp key */ + kDCP_OCOTPKeyHigh = 4U /* Use [255:128] from ocotp key as dcp key */ + }; + + static FactoryDataProviderImpl sInstance; + + CHIP_ERROR Init(void); + CHIP_ERROR SearchForId(uint8_t searchedType, uint8_t * pBuf, size_t bufLength, uint16_t & length, + uint32_t * contentAddr = NULL); + CHIP_ERROR SignWithDacKey(const ByteSpan & digestToSign, MutableByteSpan & outSignBuffer); + + CHIP_ERROR SetAes128Key(const uint8_t * keyAes128); + CHIP_ERROR SetKeySelected(KeySelect key); + CHIP_ERROR SetEncryptionMode(EncryptionMode mode); + CHIP_ERROR SetCbcInitialVector(const uint8_t * iv, uint16_t ivSize); + +private: + struct Header + { + uint32_t hashId; + uint32_t size; + uint8_t hash[4]; + }; + uint8_t factoryDataRamBuffer[FACTORY_DATA_MAX_SIZE]; + Header mHeader; + const uint8_t * pAesKey = nullptr; + const uint8_t * cbcInitialVector = nullptr; + EncryptionMode encryptMode = encrypt_none; + KeySelect selectedKey; + bool dcpDriverIsInitialized; + void SetDCP_OTPKeySelect(void); + CHIP_ERROR ReadEncryptedData(uint8_t * desBuff, uint8_t * sourceAddr, uint16_t sizeToRead); + CHIP_ERROR Hash256(const uint8_t * input, size_t inputSize, uint8_t * output, size_t * outputSize); + CHIP_ERROR LoadKeypairFromRaw(ByteSpan privateKey, ByteSpan publicKey, Crypto::P256Keypair & keypair); +}; + +inline FactoryDataProvider & FactoryDataPrvd() +{ + return FactoryDataProviderImpl::sInstance; +} + +inline FactoryDataProviderImpl & FactoryDataPrvdImpl() +{ + return FactoryDataProviderImpl::sInstance; +} + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/nxp/rt/rt1060/InetPlatformConfig.h b/src/platform/nxp/rt/rt1060/InetPlatformConfig.h new file mode 100644 index 00000000000000..b9153fd9f19741 --- /dev/null +++ b/src/platform/nxp/rt/rt1060/InetPlatformConfig.h @@ -0,0 +1,40 @@ +/* + * + * Copyright (c) 2020-2022 Project CHIP Authors + * Copyright (c) 2020 Google LLC. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Platform-specific configuration overrides for the CHIP Inet + * Layer on RT1060 platforms using the NXP SDK. + * + */ + +#pragma once + +#include + +// ==================== Platform Adaptations ==================== + +/* Default NXP Platform adaptations are used */ + +// ========== Platform-specific Configuration Overrides ========= + +/* Default NXP Platform configuration overrides are used */ + +// Include default nxp platform configurations +#include "platform/nxp/common/InetNXPPlatformDefaultConfig.h" diff --git a/src/platform/nxp/rt/rt1060/PlatformManagerImpl.cpp b/src/platform/nxp/rt/rt1060/PlatformManagerImpl.cpp new file mode 100644 index 00000000000000..8ecdf01e9c1c6d --- /dev/null +++ b/src/platform/nxp/rt/rt1060/PlatformManagerImpl.cpp @@ -0,0 +1,548 @@ +/* + * + * Copyright (c) 2020-2024 Project CHIP Authors + * Copyright (c) 2020 Nest Labs, Inc. + * Copyright 2023-2024 NXP + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Provides an implementation of the PlatformManager object + * for RT1060 platforms using the NXP RT1060 SDK. + */ +/* this file behaves like a config.h, comes first */ +#include + +#include "DiagnosticDataProviderImpl.h" +#include "fsl_adapter_rng.h" +#include "fsl_os_abstraction.h" +#include "fwk_platform_coex.h" +#include "ksdk_mbedtls.h" +#include +#include +#include +#include +#include + +#ifdef WATCHDOG_ALLOWED +#include "fsl_wdog.h" +#endif + +#include + +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR +#include "OtaSupport.h" +#endif + +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD +#include "fwk_platform_ot.h" +#include "ot_platform_common.h" +#if CHIP_DEVICE_CONFIG_CHIPOBLE_DISABLE_ADVERTISING_WHEN_PROVISIONED +#include "lib/spinel/spinel.h" +#define OT_NXP_SPINEL_PROP_VENDOR_BLE_STATE SPINEL_PROP_VENDOR__BEGIN +#endif /* CHIP_DEVICE_CONFIG_CHIPOBLE_DISABLE_ADVERTISING_WHEN_PROVISIONED */ +#endif + +#if !CHIP_DEVICE_CONFIG_ENABLE_THREAD && !CHIP_DEVICE_CONFIG_ENABLE_WPA + +#include "board.h" +#include "clock_config.h" +#include "fsl_phy.h" +#include "fsl_silicon_id.h" +#include "pin_mux.h" + +#include "fsl_enet_mdio.h" +#include "fsl_phyksz8081.h" + +#include "enet_ethernetif.h" +#include "fsl_debug_console.h" +#include "lwip/netif.h" +#include "lwip/netifapi.h" +#include "lwip/opt.h" +#include "lwip/tcpip.h" +#include "netif/ethernet.h" + +//----LWIP defines----// + +/* Address of PHY interface. */ +#define EXAMPLE_PHY_ADDRESS BOARD_ENET0_PHY_ADDRESS + +/* MDIO operations. */ +#define EXAMPLE_MDIO_OPS enet_ops + +/* PHY operations. */ +#define EXAMPLE_PHY_OPS phyksz8081_ops + +/* ENET clock frequency. */ +#define EXAMPLE_CLOCK_FREQ CLOCK_GetFreq(kCLOCK_IpgClk) + +#ifndef EXAMPLE_NETIF_INIT_FN +/*! @brief Network interface initialization function. */ +#define EXAMPLE_NETIF_INIT_FN ethernetif0_init +#endif /* EXAMPLE_NETIF_INIT_FN */ + +/*! @brief Stack size of the temporary lwIP initialization thread. */ +#define INIT_THREAD_STACKSIZE 1024 + +/*! @brief Priority of the temporary lwIP initialization thread. */ +#define INIT_THREAD_PRIO DEFAULT_THREAD_PRIO + +static mdio_handle_t mdioHandle = { .ops = &EXAMPLE_MDIO_OPS }; +static phy_handle_t phyHandle = { .phyAddr = EXAMPLE_PHY_ADDRESS, .mdioHandle = &mdioHandle, .ops = &EXAMPLE_PHY_OPS }; + +#endif + +extern "C" void BOARD_InitHardware(void); +extern "C" void otPlatSetResetFunction(void (*fp)(void)); +extern "C" void initiateResetInIdle(void); + +#if CHIP_DEVICE_CONFIG_ENABLE_WPA + +/* +Currently only IW612 and K32W0 support controller initialization in the connectivity framework +* Include should be removed otherwise it will introduce double firmware definition +*/ +#ifndef WIFI_IW612_BOARD_MURATA_2EL_M2 +#include "wlan_bt_fw.h" +#endif + +extern "C" { +#include "wlan.h" +#include "wm_net.h" +} + +#endif /* CHIP_DEVICE_CONFIG_ENABLE_WPA */ + +extern "C" void vApplicationMallocFailedHook(void) +{ + ChipLogError(DeviceLayer, "Malloc Failure"); +} + +#if WIFI_PTA_ENABLED && (CHIP_DEVICE_CONFIG_ENABLE_WPA && CHIP_ENABLE_OPENTHREAD) +#ifdef SD8801 +#define HOSTCMD_RESP_BUFF_SIZE 1024 +/* 8801 command buffer to enable External Coexistence. + * Source: SDK 2.11.1, wifi_cli demo, wlan_tests.c file. */ +const uint8_t ext_coex_8801_cmd_buf[] = { 0xe0, 0, 0x1d, 0, 0x17, 0, 0, 0, 0x01, 0, 0, 0, 0x2f, 0x02, 0x0d, + 0x00, 0x01, 0, 0, 0x03, 0x01, 0x02, 0x01, 0x01, 0x00, 0x28, 0x00, 0x3c, 0x00 }; +#endif + +static CHIP_ERROR EnableWiFiCoexistence(void) +{ + CHIP_ERROR ret = CHIP_NO_ERROR; + +#ifdef SD8801 + int status = WM_FAIL; + uint8_t * rspBuff = NULL; + uint32_t reqd_len = 0; + + rspBuff = (uint8_t *) pvPortMalloc(HOSTCMD_RESP_BUFF_SIZE); + if (rspBuff != NULL) + { + status = wlan_send_hostcmd((void *) ext_coex_8801_cmd_buf, sizeof(ext_coex_8801_cmd_buf) / sizeof(u8_t), rspBuff, + HOSTCMD_RESP_BUFF_SIZE, &reqd_len); + + if (status == WM_SUCCESS) + { + ChipLogProgress(DeviceLayer, "8801 Coexistence enabled"); + } + else + { + ChipLogError(DeviceLayer, "8801 Coexistence enabling failed = %d", status); + ret = CHIP_ERROR_INTERNAL; + } + + vPortFree(rspBuff); + } + else + { + ChipLogError(DeviceLayer, "Failed to allocate memory for Wi-Fi coexistence response buffer"); + } +#else + ChipLogError(DeviceLayer, "This chip does not support Wi-Fi and OpenThread coexistence"); + ret = CHIP_ERROR_INTERNAL; +#endif + + return ret; +} +#endif + +#if !CHIP_DEVICE_CONFIG_ENABLE_WPA +extern "C" void vApplicationIdleHook(void) +{ + chip::DeviceLayer::PlatformManagerImpl::IdleHook(); +} +#endif + +extern "C" void __wrap_exit(int __status) +{ + ChipLogError(DeviceLayer, "======> error exit function !!!"); + assert(0); +} + +namespace chip { +namespace DeviceLayer { + +PlatformManagerImpl PlatformManagerImpl::sInstance; + +void PlatformManagerImpl::HardwareInit(void) +{ + BOARD_InitHardware(); + SysTick_Config(SystemCoreClock / configTICK_RATE_HZ); +} + +CHIP_ERROR PlatformManagerImpl::ServiceInit(void) +{ + status_t status; + CHIP_ERROR chipRes = CHIP_NO_ERROR; + + status = CRYPTO_InitHardware(); + + if (status != 0) + { + chipRes = CHIP_ERROR_INTERNAL; + ChipLogError(DeviceLayer, "Crypto hardware init error"); + } + + return chipRes; +} + +/* For IW612 transceiver firmware initialization is done by PLATFORM_InitControllers */ +#ifndef WIFI_IW612_BOARD_MURATA_2EL_M2 +#if CHIP_DEVICE_CONFIG_ENABLE_WPA +CHIP_ERROR PlatformManagerImpl::WiFiInterfaceInit(void) +{ + CHIP_ERROR result = CHIP_NO_ERROR; + int wifi_status = WM_SUCCESS; + + ChipLogProgress(DeviceLayer, "Initialize WLAN"); + +#if defined(SD8801) && CHIP_ENABLE_OPENTHREAD + /* + * The 88W8801 is quirky with the REQ & PRIO lines + * at boot: they need to be held HIGH while booting. + * So disable the coexistence mechanism on the RCP, + * since internally this puts the lines HIGH. + */ + otPlatRadioSetCoexEnabled(NULL, false); +#endif + + wifi_status = wlan_init(wlan_fw_bin, wlan_fw_bin_len); + if (wifi_status != WM_SUCCESS) + { + ChipLogError(DeviceLayer, "WLAN initialization failed"); + result = CHIP_ERROR_INTERNAL; + } + else + { + ChipLogProgress(DeviceLayer, "WLAN initialized"); + } + +#if WIFI_PTA_ENABLED && (CHIP_ENABLE_OPENTHREAD) + if (result == CHIP_NO_ERROR) + { + /* In case we have both Wi-Fi and OpenThread active, enable coexistence on Wi-Fi side */ + if (EnableWiFiCoexistence() != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "Failed to initialize Wi-Fi and OpenThread coexistence"); + } + } +#endif +#if defined(SD8801) && CHIP_ENABLE_OPENTHREAD + /* + * Re-enabling the coexistence is done here because enabling it too fast + * can lead to unexpected hangs of the coexistence mechanism. Up to this point, + * all the 15.4 requests will be 'pass-through' i.e. will always be granted + * access. + */ + otPlatRadioSetCoexEnabled(NULL, true); +#endif + + return result; +} +#endif +#endif + +#if !CHIP_DEVICE_CONFIG_ENABLE_THREAD && !CHIP_DEVICE_CONFIG_ENABLE_WPA +CHIP_ERROR PlatformManagerImpl::EthernetInterfaceInit() +{ + + static struct netif netif; + ethernetif_config_t enet_config = { + .phyHandle = &phyHandle, +#ifdef configMAC_ADDR + .macAddress = configMAC_ADDR, +#endif + }; + + mdioHandle.resource.csrClock_Hz = EXAMPLE_CLOCK_FREQ; + +#ifndef configMAC_ADDR + /* Set special address for each chip. */ + (void) SILICONID_ConvertToMacAddr(&enet_config.macAddress); +#endif + + netifapi_netif_add(&netif, &enet_config, EXAMPLE_NETIF_INIT_FN, tcpip_input); + + netifapi_netif_set_default(&netif); + netifapi_netif_set_up(netif_default); + LOCK_TCPIP_CORE(); + netif_create_ip6_linklocal_address(netif_default, 1); + UNLOCK_TCPIP_CORE(); + + vTaskDelay(pdMS_TO_TICKS(1500)); + + for (uint8_t i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) + { + const char * str_ip = "-"; + if (ip6_addr_isvalid(netif_ip6_addr_state(netif_default, i))) + { + str_ip = ip6addr_ntoa(netif_ip6_addr(netif_default, i)); + } + PRINTF(" IPv6 Address%d : %s\r\n", i, str_ip); + } + PRINTF("************************************************\r\n"); + + if (netif_is_up(&netif)) + { + return CHIP_NO_ERROR; + } + + return CHIP_ERROR_NOT_CONNECTED; +} +#endif + +CHIP_ERROR PlatformManagerImpl::_InitChipStack(void) +{ + CHIP_ERROR err = CHIP_ERROR_INTERNAL; + int osError; + + /* Initialize platform services */ + err = ServiceInit(); + SuccessOrExit(err); + + // Initialize the configuration system. + err = Internal::NXPConfig::Init(); + SuccessOrExit(err); + + SetConfigurationMgr(&ConfigurationManagerImpl::GetDefaultInstance()); + SetDiagnosticDataProvider(&DiagnosticDataProviderImpl::GetDefaultInstance()); + +#if CHIP_DEVICE_CONFIG_ENABLE_WPA + /* Initialize LwIP via Wi-Fi layer. */ + net_ipv4stack_init(); +#else + /* Initialize LwIP directly. */ + tcpip_init(NULL, NULL); +#endif + +/* Currently only IW612 and K32W0 support controller initialization in the connectivity framework */ +#ifdef WIFI_IW612_BOARD_MURATA_2EL_M2 + /* Init the controller by giving as an arg the connectivity supported */ + PLATFORM_InitControllers(connBle_c +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD + | conn802_15_4_c +#endif +#if CHIP_DEVICE_CONFIG_ENABLE_WPA + | connWlan_c +#endif + ); +#endif + +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD + PLATFORM_InitOt(); + /* + * Initialize the RCP here: the WiFi initialization requires to enable/disable + * coexistence through the Spinel interface; as such, the otPlatRadioInit() call + * will fail if done afterwards + */ + otPlatLogInit(); + otPlatRadioInit(); + otPlatSetResetFunction(initiateResetInIdle); + otPlatRandomInit(); +#endif + +#if CHIP_DEVICE_CONFIG_ENABLE_WPA + osError = OSA_SetupIdleFunction(chip::DeviceLayer::PlatformManagerImpl::IdleHook); + if (osError != WM_SUCCESS) + { + ChipLogError(DeviceLayer, "Failed to setup idle function"); + err = CHIP_ERROR_NO_MEMORY; + goto exit; + } + +/* For IW612 transceiver firmware initialization is done by PLATFORM_InitControllers */ +#ifndef WIFI_IW612_BOARD_MURATA_2EL_M2 + err = WiFiInterfaceInit(); +#endif + + if (err != CHIP_NO_ERROR) + { + ChipLogProgress(DeviceLayer, + "Wi-Fi module initialization failed. Make sure the Wi-Fi/BLE module is properly configured and connected " + "with the board and start again!"); + chipDie(); + } + ChipLogProgress(DeviceLayer, "Wi-Fi module initialization done."); +#elif !CHIP_DEVICE_CONFIG_ENABLE_THREAD + err = EthernetInterfaceInit(); + + if (err != CHIP_NO_ERROR) + { + ChipLogProgress(DeviceLayer, + "LWIP interface initialization failed. Make sure there is internet conectivity on the board and reset!"); + chipDie(); + } + ChipLogProgress(DeviceLayer, "LWIP interface initialization done"); +#endif + + // Call _InitChipStack() on the generic implementation base class + // to finish the initialization process. + err = Internal::GenericPlatformManagerImpl_FreeRTOS::_InitChipStack(); + SuccessOrExit(err); + + err = System::Clock::InitClock_RealTime(); + SuccessOrExit(err); + + mStartTime = System::SystemClock().GetMonotonicTimestamp(); + +exit: + return err; +} + +void PlatformManagerImpl::SaveSettings(void) +{ +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD + otPlatSaveSettingsIdle(); +#endif +} + +void PlatformManagerImpl::IdleHook(void) +{ + +#ifdef WATCHDOG_ALLOWED + WDOG_Refresh(WDOG1); +#endif + + bool isResetScheduled = PlatformMgrImpl().GetResetInIdleValue(); + if (isResetScheduled) + { + /* + * In case a reset in IDLE has been scheduled + * Disable IRQs so that the idle task won't be preempted until the reset + */ + OSA_InterruptDisable(); + } + + chip::DeviceLayer::Internal::NXPConfig::RunSystemIdleTask(); + +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD + SaveSettings(); +#endif + +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR + /* Resume OTA Transactions in Idle task */ + OTA_TransactionResume(); +#endif + + /* + * In case a reset in idle operation has been posted, + * reset the device after having run the idle function + */ + if (isResetScheduled) + { + PlatformMgrImpl().Reset(); + } +} + +void PlatformManagerImpl::Reset(void) +{ + ChipLogProgress(DeviceLayer, "System restarting"); + // Restart the system. + NVIC_SystemReset(); + while (1) + { + } +} + +void PlatformManagerImpl::ScheduleResetInIdle(void) +{ + resetInIdle = true; +} + +bool PlatformManagerImpl::GetResetInIdleValue(void) +{ + return resetInIdle; +} + +extern "C" void initiateResetInIdle(void) +{ + PlatformMgr().Shutdown(); + PlatformMgrImpl().ScheduleResetInIdle(); +} + +extern "C" void scheduleResetInIdle(void) +{ + PlatformMgrImpl().ScheduleResetInIdle(); +} + +extern "C" bool getResetInIdleValue(void) +{ + return PlatformMgrImpl().GetResetInIdleValue(); +} + +void PlatformManagerImpl::StopBLEConnectivity(void) +{ +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD + otPlatRadioSendSetPropVendorUint8Cmd(OT_NXP_SPINEL_PROP_VENDOR_BLE_STATE, 0); +#endif /* #if CHIP_DEVICE_CONFIG_ENABLE_THREAD */ +} + +void PlatformManagerImpl::_Shutdown() +{ + uint64_t upTime = 0; + + if (GetDiagnosticDataProvider().GetUpTime(upTime) == CHIP_NO_ERROR) + { + uint32_t totalOperationalHours = 0; + + if (ConfigurationMgr().GetTotalOperationalHours(totalOperationalHours) == CHIP_NO_ERROR) + { + ConfigurationMgr().StoreTotalOperationalHours(totalOperationalHours + static_cast(upTime / 3600)); + } + else + { + ChipLogError(DeviceLayer, "Failed to get total operational hours of the Node"); + } + } + else + { + ChipLogError(DeviceLayer, "Failed to get current uptime since the Node’s last reboot"); + } + + /* Handle the server shutting down & emit the ShutDown event*/ + PlatformMgr().HandleServerShuttingDown(); + /* Shutdown all layers */ + Internal::GenericPlatformManagerImpl_FreeRTOS::_Shutdown(); +} + +} // namespace DeviceLayer +} // namespace chip + +extern "C" void mt_wipe(void) +{ + chip::DeviceLayer::Internal::NXPConfig::FactoryResetConfig(); +} diff --git a/src/platform/nxp/rt/rt1060/SystemPlatformConfig.h b/src/platform/nxp/rt/rt1060/SystemPlatformConfig.h new file mode 100644 index 00000000000000..17f3c18dd39ee9 --- /dev/null +++ b/src/platform/nxp/rt/rt1060/SystemPlatformConfig.h @@ -0,0 +1,40 @@ +/* + * + * Copyright (c) 2020-2022 Project CHIP Authors + * Copyright (c) 2020 Google LLC. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Platform-specific configuration overrides for the CHIP System + * Layer on NXP RT1060 Platforms. + * + */ + +#pragma once + +#include + +// ==================== Platform Adaptations ==================== + +/* Default NXP Platform adaptations are used */ + +// ========== Platform-specific Configuration Overrides ========= + +/* Default NXP Platform configuration overrides are used */ + +// Include default nxp platform configurations +#include "platform/nxp/common/SystemNXPPlatformDefaultConfig.h" diff --git a/src/platform/nxp/rt/rt1060/args.gni b/src/platform/nxp/rt/rt1060/args.gni new file mode 100644 index 00000000000000..b5fe5340f8ff38 --- /dev/null +++ b/src/platform/nxp/rt/rt1060/args.gni @@ -0,0 +1,57 @@ +# Copyright (c) 2020-2023 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/chip.gni") +import("//build_overrides/nxp_sdk.gni") + +rt_platform = "rt1060" +nxp_platform = "rt/${rt_platform}" +nxp_sdk_name = "rt_sdk" +chip_device_platform = "nxp" +lwip_platform = "nxp" + +# ARM architecture flags will be set based on NXP board. +arm_platform_config = "${nxp_sdk_build_root}/${nxp_sdk_name}/nxp_arm.gni" + +chip_device_project_config_include = "" +chip_project_config_include = "" +chip_inet_project_config_include = "" +chip_system_project_config_include = "" +chip_ble_project_config_include = "" + +chip_build_tests = false + +#This enables the EventList global attribute +enable_eventlist_attribute = true + +# TODO : Enable the OTA Requestor by default. +# This requires the mcuboot bootloader to be used, which reserves the first 256 kB of the flash. +# If mcuboot is not used, "no_mcuboot" must be set to true in the gn gen build command +# in order for the application to be linked at the base of the flash. +#chip_enable_ota_requestor = true +declare_args() { + # TODO : set no_mcuboot to false by default when enabling ota requestor by default + no_mcuboot = true + + chip_enable_secondary_nwk_if = false +} + +mbedtls_target = "${nxp_sdk_build_root}:nxp_mbedtls" + +openthread_external_mbedtls = mbedtls_target +openthread_project_core_config_file = "OpenThreadConfig.h" +openthread_core_config_deps = [ "${chip_root}/third_party/openthread/platforms/nxp/${nxp_platform}:openthread_core_config_rt1060" ] +openthread_core_config_platform_check_file = + "openthread-core-rt1060-config-check.h" +openthread_external_platform = "${chip_root}/third_party/openthread/platforms/nxp/${nxp_platform}:libopenthread-rt1060" diff --git a/src/platform/nxp/rt/rt1170/BUILD.gn b/src/platform/nxp/rt/rt1170/BUILD.gn new file mode 100644 index 00000000000000..4bfd1034a78f21 --- /dev/null +++ b/src/platform/nxp/rt/rt1170/BUILD.gn @@ -0,0 +1,190 @@ +# Copyright (c) 2021 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/build.gni") +import("//build_overrides/chip.gni") +import("//build_overrides/nxp_sdk.gni") +import("//build_overrides/openthread.gni") +import("${chip_root}/src/platform/device.gni") + +# If external SDK is used, do not import ${nxp_sdk_name}.gni +if (!nxp_external_sdk) { + import("${nxp_sdk_build_root}/${nxp_sdk_name}/${nxp_sdk_name}.gni") +} + +import("${nxp_sdk_build_root}/nxp_sdk.gni") + +assert(chip_device_platform == "nxp") + +source_set("nxp_factory_data") { +} +source_set("nxp_ota") { +} + +config("nxp_platform_config") { + defines = [ "EXTERNAL_BLEMANAGERIMPL_HEADER=\"platform/nxp/common/ble_zephyr/BLEManagerImpl.h\"" ] + include_dirs = [ + ".", + "../../common", + ] + if (chip_with_factory_data == 1) { + include_dirs += [ + ".", + "../../common/factory_data", + ] + defines += [ + "CONFIG_CHIP_PLAT_LOAD_REAL_FACTORY_DATA=1", + "CONFIG_CHIP_ENCRYPTED_FACTORY_DATA=1", + ] + defines += [ "EXTERNAL_FACTORY_DATA_PROVIDER_IMPL_HEADER=\"platform/nxp/common/factory_data/FactoryDataProviderFwkImpl.h\"" ] + } + + # When OTBR is enabled Thread network commissioning cluster is enabled using chip_enable_secondary_nwk_if + if (chip_enable_wifi && chip_enable_openthread && + !chip_enable_secondary_nwk_if) { + defines += [ "_NO_GENERIC_THREAD_NETWORK_COMMISSIONING_DRIVER_" ] + } +} + +static_library("nxp_platform") { + output_name = "libCHIP_NXP_Port_RT1170" + cflags = [ + "-Wno-conversion", + "-Wno-sign-compare", + ] + deps = [] + defines = [] + sources = [ + "../../../FreeRTOS/SystemTimeSupport.cpp", + "../../../SingletonConfigurationManager.cpp", + "../../common/CHIPDevicePlatformEvent.h", + "../../common/ConfigurationManagerImpl.cpp", + "../../common/ConfigurationManagerImpl.h", + "../../common/ConnectivityManagerImpl.cpp", + "../../common/ConnectivityManagerImpl.h", + "../../common/DiagnosticDataProviderImpl.cpp", + "../../common/DiagnosticDataProviderImpl.h", + "../../common/KeyValueStoreManagerImpl.cpp", + "../../common/KeyValueStoreManagerImpl.h", + "../../common/Logging.cpp", + "../../common/NXPConfig.cpp", + "../../common/NXPConfig.h", + "../../common/NetworkProvisioningServerImpl.h", + "../../common/PlatformManagerImpl.h", + "../../common/SoftwareUpdateManagerImpl.h", + "../../common/ram_storage.c", + "../../common/ram_storage.h", + "CHIPDevicePlatformConfig.h", + "PlatformManagerImpl.cpp", + ] + + if (chip_enable_ble) { + sources += [ + # Adding random file which defines the function sys_csrand_get which is called by BLEManagerImpl from Zephyr + "${nxp_sdk_build_root}/rt_sdk/sdk_hook/zephyr/random/random.cpp", + "../../common/ble_zephyr/BLEAdvertisingArbiter.cpp", + "../../common/ble_zephyr/BLEManagerImpl.cpp", + "../../common/ble_zephyr/BLEManagerImpl.h", + ] + } + + public_deps = [ "${chip_root}/src/platform:platform_base" ] + + deps += [ + "${chip_root}/src/lib/dnssd:constants", + "${chip_root}/src/platform/logging:headers", + ] + + # define CHIP_PLAT_NVM_SUPPORT - See NXPConfig.cpp for definition + if (nxp_nvm_component == "nvm_fwk") { + defines += [ "CHIP_PLAT_NVM_SUPPORT=1" ] + } else if (nxp_nvm_component == "littlefs") { + defines += [ "CHIP_PLAT_NVM_SUPPORT=2" ] + } + + if (chip_enable_wifi) { + sources += [ + "../../common/NetworkCommissioningDriver.h", + "../../common/NetworkCommissioningWiFiDriver.cpp", + ] + } + if (chip_enable_ota_requestor) { + sources += [ + "../../common/OTAImageProcessorImpl.cpp", + "../../common/OTAImageProcessorImpl.h", + ] + } + + if (chip_enable_openthread) { + sources += [ + # Temporary fix, to be revert once PR #34662 is merged, build issue when using GN check argument + "${chip_root}/src/app/clusters/thread-border-router-management-server/thread-br-delegate.h", + "../../../OpenThread/GenericThreadBorderRouterDelegate.cpp", + "../../../OpenThread/GenericThreadBorderRouterDelegate.h", + "../../../OpenThread/OpenThreadUtils.cpp", + "../../common/ThreadStackManagerImpl.cpp", + "../../common/ThreadStackManagerImpl.h", + ] + + deps += [ "${chip_root}/src/app/common:ids" ] + + if (!nxp_build_matter_standalone_lib) { + deps += [ "${chip_root}/third_party/openthread:openthread" ] + public_deps += + [ "${chip_root}/third_party/openthread:openthread-platform" ] + } + + # dep required to include 'lib/spinel/spinel.h' in PlatformManagerImpl.cpp + deps += [ "${openthread_root}:libopenthread-spinel-rcp" ] + + if (chip_mdns == "platform") { + if (chip_enable_wifi) { + sources += [ + "../../../OpenThread/OpenThreadDnssdImpl.cpp", + "../../../OpenThread/OpenThreadDnssdImpl.h", + "../../common/DnssdImpl.cpp", + "../../common/DnssdImplBr.cpp", + "../../common/DnssdImplBr.h", + ] + } else { + sources += [ + "../../../OpenThread/DnssdImpl.cpp", + "../../../OpenThread/OpenThreadDnssdImpl.cpp", + "../../../OpenThread/OpenThreadDnssdImpl.h", + ] + } + deps += [ "${chip_root}/src/lib/dnssd:platform_header" ] + } + } + + if (chip_with_factory_data == 1) { + sources += [ + "../../common/factory_data/FactoryDataProvider.cpp", + "../../common/factory_data/FactoryDataProvider.h", + "../../common/factory_data/FactoryDataProviderFwkImpl.cpp", + "../../common/factory_data/FactoryDataProviderFwkImpl.h", + ] + + deps += [ "${chip_root}/src/credentials:credentials_header" ] + } + + deps += [ "${nxp_sdk_build_root}:nxp_sdk" ] + + public_deps += [ + "${chip_root}/examples/platform/nxp/common/app/support:freertos_memory_utils", + "${chip_root}/src/crypto", + "${chip_root}/src/platform:syscalls_stub", + ] + public_configs = [ ":nxp_platform_config" ] +} diff --git a/src/platform/nxp/rt/rt1170/BlePlatformConfig.h b/src/platform/nxp/rt/rt1170/BlePlatformConfig.h new file mode 100644 index 00000000000000..bd4d80390bb244 --- /dev/null +++ b/src/platform/nxp/rt/rt1170/BlePlatformConfig.h @@ -0,0 +1,36 @@ +/* + * + * Copyright (c) 2021 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Platform-specific configuration overrides for the CHIP BLE + * Layer on RT1170 platforms using the NXP SDK. + * + */ + +#pragma once + +// ==================== Platform Adaptations ==================== + +/* Default NXP Platform adaptations are used */ + +// ========== Platform-specific Configuration Overrides ========= + +/* Default NXP Platform configuration overrides are used */ + +// Include default nxp platform configurations +#include "platform/nxp/common/ble_zephyr/BleNXPPlatformDefaultConfig.h" diff --git a/src/platform/nxp/rt/rt1170/CHIPDevicePlatformConfig.h b/src/platform/nxp/rt/rt1170/CHIPDevicePlatformConfig.h new file mode 100644 index 00000000000000..cfb589209e9de2 --- /dev/null +++ b/src/platform/nxp/rt/rt1170/CHIPDevicePlatformConfig.h @@ -0,0 +1,42 @@ +/* + * + * Copyright (c) 2020-2022 Project CHIP Authors + * Copyright (c) 2020 Google LLC. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Platform-specific configuration overrides for the chip Device Layer + * on RT1170 platforms using the NXP SDK. + */ + +#pragma once + +// ==================== Platform Adaptations ==================== + +/* Default NXP Platform adaptations are used */ + +// ========== Platform-specific Configuration ========= + +// These are configuration options that are unique to the NXP platform. +// These can be overridden by the application as needed. + +// ========== Platform-specific Configuration Overrides ========= + +/* Default NXP Platform configuration overrides are used */ + +// Include default nxp platform configurations +#include "platform/nxp/common/CHIPDeviceNXPPlatformDefaultConfig.h" diff --git a/src/platform/nxp/rt/rt1170/CHIPPlatformConfig.h b/src/platform/nxp/rt/rt1170/CHIPPlatformConfig.h new file mode 100644 index 00000000000000..6485baca53edb9 --- /dev/null +++ b/src/platform/nxp/rt/rt1170/CHIPPlatformConfig.h @@ -0,0 +1,54 @@ +/* + * + * Copyright (c) 2020-2022 Project CHIP Authors + * Copyright (c) 2020 Google LLC. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Platform-specific configuration overrides for CHIP on + * NXP RT1060 platforms. + */ + +#pragma once + +#include + +// ==================== General Platform Adaptations ==================== + +/* Default NXP platform adaptations are used */ + +// ==================== Security Adaptations ==================== + +/* Default NXP Platform security adaptations are used */ + +// ==================== General Configuration Overrides ==================== + +/* Default NXP Platform general configuration overrides are used */ + +/* For now on RT1170, due to the current file system implementation only 5 fabrics are supported */ +#define CHIP_CONFIG_MAX_FABRICS 5 + +// ==================== Security Configuration Overrides ==================== + +/* Default NXP Platform security configuration overrides are used */ + +// ==================== WDM Configuration Overrides ==================== + +/* Default NXP Platform WDM Configuration overrides are used */ + +// Include default nxp platform configurations +#include "platform/nxp/common/CHIPNXPPlatformDefaultConfig.h" diff --git a/src/platform/nxp/rt/rt1170/InetPlatformConfig.h b/src/platform/nxp/rt/rt1170/InetPlatformConfig.h new file mode 100644 index 00000000000000..dee850a5596139 --- /dev/null +++ b/src/platform/nxp/rt/rt1170/InetPlatformConfig.h @@ -0,0 +1,40 @@ +/* + * + * Copyright (c) 2020-2022 Project CHIP Authors + * Copyright (c) 2020 Google LLC. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Platform-specific configuration overrides for the CHIP Inet + * Layer on RT1170 platforms using the NXP SDK. + * + */ + +#pragma once + +#include + +// ==================== Platform Adaptations ==================== + +/* Default NXP Platform adaptations are used */ + +// ========== Platform-specific Configuration Overrides ========= + +/* Default NXP Platform configuration overrides are used */ + +// Include default nxp platform configurations +#include "platform/nxp/common/InetNXPPlatformDefaultConfig.h" diff --git a/src/platform/nxp/rt/rt1170/PlatformManagerImpl.cpp b/src/platform/nxp/rt/rt1170/PlatformManagerImpl.cpp new file mode 100644 index 00000000000000..24212cee4ccf7f --- /dev/null +++ b/src/platform/nxp/rt/rt1170/PlatformManagerImpl.cpp @@ -0,0 +1,474 @@ +/* + * + * Copyright (c) 2020-2024 Project CHIP Authors + * Copyright (c) 2020 Nest Labs, Inc. + * Copyright 2023-2024 NXP + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Provides an implementation of the PlatformManager object + * for RT1170 platforms using the NXP RT1170 SDK. + */ +/* this file behaves like a config.h, comes first */ +#include + +#include "DiagnosticDataProviderImpl.h" +#include "fsl_os_abstraction.h" +#include "fwk_platform_coex.h" +#include "ksdk_mbedtls.h" +#include +#include +#include +#include +#include + +#include + +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR +#include "OtaSupport.h" +#endif + +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD +#include "ot_platform_common.h" +#include +#if CHIP_DEVICE_CONFIG_CHIPOBLE_DISABLE_ADVERTISING_WHEN_PROVISIONED +#include "lib/spinel/spinel.h" +#define OT_NXP_SPINEL_PROP_VENDOR_BLE_STATE SPINEL_PROP_VENDOR__BEGIN +#endif /* CHIP_DEVICE_CONFIG_CHIPOBLE_DISABLE_ADVERTISING_WHEN_PROVISIONED */ +#endif + +#if !CHIP_DEVICE_CONFIG_ENABLE_THREAD && !CHIP_DEVICE_CONFIG_ENABLE_WPA + +#include "board.h" +#include "clock_config.h" +#include "fsl_phy.h" +#include "pin_mux.h" + +#include "fsl_enet_mdio.h" +#include "fsl_phyksz8081.h" + +#include "enet_ethernetif.h" +#include "fsl_debug_console.h" +#include "lwip/netif.h" +#include "lwip/netifapi.h" +#include "lwip/opt.h" +#include "lwip/tcpip.h" +#include "netif/ethernet.h" + +//----LWIP defines----// +/* MAC address configuration. */ +#define configMAC_ADDR \ + { \ + 0x02, 0x12, 0x13, 0x10, 0x15, 0x11 \ + } + +/* Address of PHY interface. */ +#define EXAMPLE_PHY_ADDRESS BOARD_ENET0_PHY_ADDRESS + +/* MDIO operations. */ +#define EXAMPLE_MDIO_OPS enet_ops + +/* PHY operations. */ +#define EXAMPLE_PHY_OPS phyksz8081_ops + +/* ENET clock frequency. */ +#define EXAMPLE_CLOCK_FREQ CLOCK_GetFreq(kCLOCK_IpgClk) + +#ifndef EXAMPLE_NETIF_INIT_FN +/*! @brief Network interface initialization function. */ +#define EXAMPLE_NETIF_INIT_FN ethernetif0_init +#endif /* EXAMPLE_NETIF_INIT_FN */ + +/*! @brief Stack size of the temporary lwIP initialization thread. */ +#define INIT_THREAD_STACKSIZE 1024 + +/*! @brief Priority of the temporary lwIP initialization thread. */ +#define INIT_THREAD_PRIO DEFAULT_THREAD_PRIO + +static mdio_handle_t mdioHandle = { .ops = &EXAMPLE_MDIO_OPS }; +static phy_handle_t phyHandle = { .phyAddr = EXAMPLE_PHY_ADDRESS, .mdioHandle = &mdioHandle, .ops = &EXAMPLE_PHY_OPS }; + +#endif + +extern "C" void BOARD_InitHardware(void); +extern "C" void otPlatSetResetFunction(void (*fp)(void)); +extern "C" void initiateResetInIdle(void); + +#include "fwk_platform_ot.h" + +#if CHIP_DEVICE_CONFIG_ENABLE_WPA + +#include "fsl_adapter_gpio.h" +#include "fsl_os_abstraction.h" + +extern "C" { +#include "wlan.h" +#include "wm_net.h" +} + +#endif /* CHIP_DEVICE_CONFIG_ENABLE_WPA */ + +extern "C" void vApplicationMallocFailedHook(void) +{ + ChipLogError(DeviceLayer, "Malloc Failure"); +} + +#if WIFI_PTA_ENABLED && (CHIP_DEVICE_CONFIG_ENABLE_WPA && CHIP_ENABLE_OPENTHREAD) +#ifdef SD8801 +#define HOSTCMD_RESP_BUFF_SIZE 1024 +/* 8801 command buffer to enable External Coexistence. + * Source: SDK 2.11.1, wifi_cli demo, wlan_tests.c file. */ +const uint8_t ext_coex_8801_cmd_buf[] = { 0xe0, 0, 0x1d, 0, 0x17, 0, 0, 0, 0x01, 0, 0, 0, 0x2f, 0x02, 0x0d, + 0x00, 0x01, 0, 0, 0x03, 0x01, 0x02, 0x01, 0x01, 0x00, 0x28, 0x00, 0x3c, 0x00 }; +#endif + +static CHIP_ERROR EnableWiFiCoexistence(void) +{ + CHIP_ERROR ret = CHIP_NO_ERROR; + +#ifdef SD8801 + int status = WM_FAIL; + uint8_t * rspBuff = NULL; + uint32_t reqd_len = 0; + + rspBuff = (uint8_t *) pvPortMalloc(HOSTCMD_RESP_BUFF_SIZE); + if (rspBuff != NULL) + { + status = wlan_send_hostcmd((void *) ext_coex_8801_cmd_buf, sizeof(ext_coex_8801_cmd_buf) / sizeof(u8_t), rspBuff, + HOSTCMD_RESP_BUFF_SIZE, &reqd_len); + + if (status == WM_SUCCESS) + { + ChipLogProgress(DeviceLayer, "8801 Coexistence enabled"); + } + else + { + ChipLogError(DeviceLayer, "8801 Coexistence enabling failed = %d", status); + ret = CHIP_ERROR_INTERNAL; + } + + vPortFree(rspBuff); + } + else + { + ChipLogError(DeviceLayer, "Failed to allocate memory for Wi-Fi coexistence response buffer"); + } +#else + ChipLogError(DeviceLayer, "This chip does not support Wi-Fi and OpenThread coexistence"); + ret = CHIP_ERROR_INTERNAL; +#endif + + return ret; +} +#endif + +#if !CHIP_DEVICE_CONFIG_ENABLE_WPA +extern "C" void vApplicationIdleHook(void) +{ + chip::DeviceLayer::PlatformManagerImpl::IdleHook(); +} +#endif + +extern "C" void __wrap_exit(int __status) +{ + ChipLogError(DeviceLayer, "======> error exit function !!!"); + assert(0); +} + +namespace chip { +namespace DeviceLayer { + +PlatformManagerImpl PlatformManagerImpl::sInstance; + +void PlatformManagerImpl::HardwareInit(void) +{ + BOARD_InitHardware(); + SysTick_Config(SystemCoreClock / configTICK_RATE_HZ); +} + +CHIP_ERROR PlatformManagerImpl::ServiceInit(void) +{ + status_t status; + CHIP_ERROR chipRes = CHIP_NO_ERROR; + + status = CRYPTO_InitHardware(); + + if (status != 0) + { + chipRes = CHIP_ERROR_INTERNAL; + ChipLogError(DeviceLayer, "Crypto hardware init error"); + } + + return chipRes; +} + +#if !CHIP_DEVICE_CONFIG_ENABLE_THREAD && !CHIP_DEVICE_CONFIG_ENABLE_WPA +CHIP_ERROR PlatformManagerImpl::EthernetInterfaceInit() +{ + + static struct netif netif; + ethernetif_config_t enet_config = { + .phyHandle = &phyHandle, + .macAddress = configMAC_ADDR, + }; + + mdioHandle.resource.csrClock_Hz = EXAMPLE_CLOCK_FREQ; + + netifapi_netif_add(&netif, &enet_config, EXAMPLE_NETIF_INIT_FN, tcpip_input); + + netifapi_netif_set_default(&netif); + netifapi_netif_set_up(netif_default); + LOCK_TCPIP_CORE(); + netif_create_ip6_linklocal_address(netif_default, 1); + UNLOCK_TCPIP_CORE(); + + vTaskDelay(pdMS_TO_TICKS(1500)); + + for (uint8_t i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) + { + const char * str_ip = "-"; + if (ip6_addr_isvalid(netif_ip6_addr_state(netif_default, i))) + { + str_ip = ip6addr_ntoa(netif_ip6_addr(netif_default, i)); + } + PRINTF(" IPv6 Address%d : %s\r\n", i, str_ip); + } + PRINTF("************************************************\r\n"); + + if (netif_is_up(&netif)) + { + return CHIP_NO_ERROR; + } + + return CHIP_ERROR_NOT_CONNECTED; +} +#endif + +CHIP_ERROR PlatformManagerImpl::_InitChipStack(void) +{ +#if CHIP_DEVICE_CONFIG_ENABLE_WPA + hal_gpio_status_t status_gpio; + hal_gpio_pin_config_t resetPinConfig = { + .direction = kHAL_GpioDirectionOut, + .level = 0U, + .port = 3, + .pin = 9, + }; + + GPIO_HANDLE_DEFINE(otGpioResetHandle); + +#endif /* CHIP_DEVICE_CONFIG_ENABLE_WPA */ + + CHIP_ERROR err = CHIP_ERROR_INTERNAL; + int osError; + + /* Initialize platform services */ + err = ServiceInit(); + SuccessOrExit(err); + + // Initialize the configuration system. + err = Internal::NXPConfig::Init(); + SuccessOrExit(err); + + SetConfigurationMgr(&ConfigurationManagerImpl::GetDefaultInstance()); + SetDiagnosticDataProvider(&DiagnosticDataProviderImpl::GetDefaultInstance()); + +#if CHIP_DEVICE_CONFIG_ENABLE_WPA + /* Initialize LwIP via Wi-Fi layer. */ + net_ipv4stack_init(); +#else + /* Initialize LwIP directly. */ + tcpip_init(NULL, NULL); +#endif + + /* Init the controller by giving as an arg the connectivity supported */ + PLATFORM_InitControllers(connBle_c +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD + | conn802_15_4_c +#endif +#if CHIP_DEVICE_CONFIG_ENABLE_WPA + | connWlan_c +#endif + ); +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD + PLATFORM_InitOt(); + /* + * Initialize the RCP here: the WiFi initialization requires to enable/disable + * coexistence through the Spinel interface; as such, the otPlatRadioInit() call + * will fail if done afterwards + */ + otPlatLogInit(); + otPlatRadioInit(); + otPlatSetResetFunction(initiateResetInIdle); + otPlatRandomInit(); +#endif + +#if CHIP_DEVICE_CONFIG_ENABLE_WPA + + osError = OSA_SetupIdleFunction(chip::DeviceLayer::PlatformManagerImpl::IdleHook); + if (osError != WM_SUCCESS) + { + ChipLogError(DeviceLayer, "Failed to setup idle function"); + err = CHIP_ERROR_NO_MEMORY; + goto exit; + } + + ChipLogProgress(DeviceLayer, "Wi-Fi module initialization done."); +#elif !CHIP_DEVICE_CONFIG_ENABLE_THREAD + err = EthernetInterfaceInit(); + + if (err != CHIP_NO_ERROR) + { + ChipLogProgress(DeviceLayer, + "LWIP interface initialization failed. Make sure there is internet conectivity on the board and reset!"); + chipDie(); + } + ChipLogProgress(DeviceLayer, "LWIP interface initialization done"); +#endif + + // Call _InitChipStack() on the generic implementation base class + // to finish the initialization process. + err = Internal::GenericPlatformManagerImpl_FreeRTOS::_InitChipStack(); + SuccessOrExit(err); + + err = System::Clock::InitClock_RealTime(); + SuccessOrExit(err); + + mStartTime = System::SystemClock().GetMonotonicTimestamp(); + +exit: + return err; +} + +void PlatformManagerImpl::SaveSettings(void) +{ +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD + otPlatSaveSettingsIdle(); +#endif +} + +void PlatformManagerImpl::IdleHook(void) +{ + bool isResetScheduled = PlatformMgrImpl().GetResetInIdleValue(); + if (isResetScheduled) + { + /* + * In case a reset in IDLE has been scheduled + * Disable IRQs so that the idle task won't be preempted until the reset + */ + OSA_InterruptDisable(); + } + + chip::DeviceLayer::Internal::NXPConfig::RunSystemIdleTask(); + +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD + SaveSettings(); +#endif + +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR + /* Resume OTA Transactions in Idle task */ + OTA_TransactionResume(); +#endif + + /* + * In case a reset in idle operation has been posted, + * reset the device after having run the idle function + */ + if (isResetScheduled) + { + PlatformMgrImpl().Reset(); + } +} + +void PlatformManagerImpl::Reset(void) +{ + ChipLogProgress(DeviceLayer, "System restarting"); + // Restart the system. + NVIC_SystemReset(); + while (1) + { + } +} + +void PlatformManagerImpl::ScheduleResetInIdle(void) +{ + resetInIdle = true; +} + +bool PlatformManagerImpl::GetResetInIdleValue(void) +{ + return resetInIdle; +} + +extern "C" void initiateResetInIdle(void) +{ + PlatformMgr().Shutdown(); + PlatformMgrImpl().ScheduleResetInIdle(); +} + +extern "C" void scheduleResetInIdle(void) +{ + PlatformMgrImpl().ScheduleResetInIdle(); +} + +extern "C" bool getResetInIdleValue(void) +{ + return PlatformMgrImpl().GetResetInIdleValue(); +} + +void PlatformManagerImpl::StopBLEConnectivity(void) +{ +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD + otPlatRadioSendSetPropVendorUint8Cmd(OT_NXP_SPINEL_PROP_VENDOR_BLE_STATE, 0); +#endif /* CHIP_DEVICE_CONFIG_ENABLE_THREAD */ +} + +void PlatformManagerImpl::_Shutdown() +{ + uint64_t upTime = 0; + + if (GetDiagnosticDataProvider().GetUpTime(upTime) == CHIP_NO_ERROR) + { + uint32_t totalOperationalHours = 0; + + if (ConfigurationMgr().GetTotalOperationalHours(totalOperationalHours) == CHIP_NO_ERROR) + { + ConfigurationMgr().StoreTotalOperationalHours(totalOperationalHours + static_cast(upTime / 3600)); + } + else + { + ChipLogError(DeviceLayer, "Failed to get total operational hours of the Node"); + } + } + else + { + ChipLogError(DeviceLayer, "Failed to get current uptime since the Node’s last reboot"); + } + + /* Handle the server shutting down & emit the ShutDown event*/ + PlatformMgr().HandleServerShuttingDown(); + /* Shutdown all layers */ + Internal::GenericPlatformManagerImpl_FreeRTOS::_Shutdown(); +} + +} // namespace DeviceLayer +} // namespace chip + +extern "C" void mt_wipe(void) +{ + chip::DeviceLayer::Internal::NXPConfig::FactoryResetConfig(); +} diff --git a/src/platform/nxp/rt/rt1170/SystemPlatformConfig.h b/src/platform/nxp/rt/rt1170/SystemPlatformConfig.h new file mode 100644 index 00000000000000..3838fc869baeb3 --- /dev/null +++ b/src/platform/nxp/rt/rt1170/SystemPlatformConfig.h @@ -0,0 +1,40 @@ +/* + * + * Copyright (c) 2020-2022 Project CHIP Authors + * Copyright (c) 2020 Google LLC. + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Platform-specific configuration overrides for the CHIP System + * Layer on NXP RT1170 Platforms. + * + */ + +#pragma once + +#include + +// ==================== Platform Adaptations ==================== + +/* Default NXP Platform adaptations are used */ + +// ========== Platform-specific Configuration Overrides ========= + +/* Default NXP Platform configuration overrides are used */ + +// Include default nxp platform configurations +#include "platform/nxp/common/SystemNXPPlatformDefaultConfig.h" diff --git a/src/platform/nxp/rt/rt1170/args.gni b/src/platform/nxp/rt/rt1170/args.gni new file mode 100644 index 00000000000000..aaadc3081a5b4a --- /dev/null +++ b/src/platform/nxp/rt/rt1170/args.gni @@ -0,0 +1,62 @@ +# Copyright (c) 2020 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/chip.gni") +import("//build_overrides/nxp_sdk.gni") + +rt_platform = "rt1170" +nxp_platform = "rt/${rt_platform}" +nxp_sdk_name = "rt_sdk" +chip_device_platform = "nxp" +lwip_platform = "nxp" + +# ARM architecture flags will be set based on NXP board. +arm_platform_config = "${nxp_sdk_build_root}/${nxp_sdk_name}/nxp_arm.gni" + +chip_device_project_config_include = "" +chip_project_config_include = "" +chip_inet_project_config_include = "" +chip_system_project_config_include = "" +chip_ble_project_config_include = "" + +chip_build_tests = false + +#This enables the EventList global attribute +enable_eventlist_attribute = true + +# TODO : Enable the OTA Requestor by default. +# This requires the mcuboot bootloader to be used, which reserves the first 256 kB of the flash. +# If mcuboot is not used, "no_mcuboot" must be set to true in the gn gen build command +# in order for the application to be linked at the base of the flash. +#chip_enable_ota_requestor = true +declare_args() { + # TODO : set no_mcuboot to false by default when enabling ota requestor by default + no_mcuboot = true + + chip_enable_secondary_nwk_if = false +} + +# As a temporary workaround, we are disabling the session resumption because currently +# the mbedtls port does not support this. +# If not disabled, reconnecting to the OTA Provider node will fail. +chip_enable_session_resumption = false + +mbedtls_target = "${nxp_sdk_build_root}:nxp_mbedtls" + +openthread_external_mbedtls = mbedtls_target +openthread_project_core_config_file = "OpenThreadConfig.h" +openthread_core_config_deps = [ "${chip_root}/third_party/openthread/platforms/nxp/${nxp_platform}:openthread_core_config_rt1170" ] +openthread_core_config_platform_check_file = + "openthread-core-rt1170-config-check.h" +openthread_external_platform = "${chip_root}/third_party/openthread/platforms/nxp/${nxp_platform}:libopenthread-rt1170" diff --git a/third_party/openthread/platforms/nxp/rt/rt1060/BUILD.gn b/third_party/openthread/platforms/nxp/rt/rt1060/BUILD.gn new file mode 100644 index 00000000000000..ef44f9048e2d25 --- /dev/null +++ b/third_party/openthread/platforms/nxp/rt/rt1060/BUILD.gn @@ -0,0 +1,150 @@ +# Copyright (c) 2020-2022 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/chip.gni") +import("//build_overrides/mbedtls.gni") +import("//build_overrides/nxp_sdk.gni") +import("//build_overrides/openthread.gni") + +#allows to get common NXP SDK gn options +import("${nxp_sdk_build_root}/nxp_sdk.gni") + +# Allows to get various RT gn options +import("${nxp_sdk_build_root}/${nxp_sdk_name}/${nxp_sdk_name}.gni") +openthread_nxp_root = "${chip_root}/third_party/openthread/ot-nxp" + +config("openthread_rt1060_config") { + defines = [] + include_dirs = [ + "${openthread_nxp_root}/src/common", + "${openthread_nxp_root}/src/common/br", + "${openthread_nxp_root}/src/common/spinel", + "${openthread_nxp_root}/src/imx_rt/rt1060", + "${openthread_nxp_root}/third_party/mbedtls/configs", + "${openthread_root}/third_party/mbedtls", + "${openthread_root}/examples/platforms", + "${openthread_nxp_root}/examples/utils/cli_addons", + "${openthread_nxp_root}/examples/utils/cli_addons/ephemeral_key", + "${openthread_nxp_root}/examples/utils/cli_addons/lwip", + ] + + if (chip_enable_wifi && chip_enable_openthread) { + defines += [ + "OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE=1", + "OPENTHREAD_CONFIG_COMMISSIONER_ENABLE=1", + "OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE=1", + "OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE=1", + "OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE=1", + "OPENTHREAD_CONFIG_MAX_STATECHANGE_HANDLERS=3", + "OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE=1", + "OPENTHREAD_CONFIG_BORDER_AGENT_ID_ENABLE=1", + "OPENTHREAD_CONFIG_BORDER_ROUTING_DHCP6_PD_ENABLE=1", + "OPENTHREAD_CONFIG_SRP_SERVER_ADVERTISING_PROXY_ENABLE=1", + "OPENTHREAD_CONFIG_DNSSD_DISCOVERY_PROXY_ENABLE=1", + "OPENTHREAD_CONFIG_MULTICAST_DNS_ENABLE=1", + "OPENTHREAD_CONFIG_MULTICAST_DNS_PUBLIC_API_ENABLE=1", + "OT_APP_BR_LWIP_HOOKS_EN=1", + ] + + if (chip_enable_matter_cli) { + defines += [ + "OPENTHREAD_CONFIG_BORDER_AGENT_EPHEMERAL_KEY_ENABLE=1", + "OT_APP_CLI_EPHEMERAL_KEY_ADDON=1", + "OT_APP_CLI_LWIP_ADDON=1", + ] + } + } + + # ot cli configs + defines += [ "OPENTHREAD_CONFIG_PING_SENDER_ENABLE=1" ] +} + +#Config used by the openthread stack to get the path to OpenthreadConfig.h +source_set("openthread_core_config_rt1060") { + public_configs = [ ":openthread_rt1060_config" ] + public_deps = [ nxp_sdk_target ] +} + +source_set("libopenthread-rt1060") { + deps = [] + sources = [ + "${openthread_nxp_root}/src/common/alarm_freertos.c", + "${openthread_nxp_root}/src/common/diag.c", + "${openthread_nxp_root}/src/common/entropy.c", + "${openthread_nxp_root}/src/common/logging.c", + "${openthread_nxp_root}/src/common/spinel/misc.c", + "${openthread_nxp_root}/src/common/spinel/radio.cpp", + "${openthread_nxp_root}/src/common/spinel/spinel_hdlc.cpp", + "${openthread_nxp_root}/src/common/spinel/system.c", + "${openthread_root}/src/lib/hdlc/hdlc.cpp", + "${openthread_root}/src/lib/url/url.cpp", + ] + + if (chip_enable_wifi && chip_enable_openthread) { + sources += [ + "${openthread_nxp_root}/src/common/br/border_agent.c", + "${openthread_nxp_root}/src/common/br/br_rtos_manager.c", + "${openthread_nxp_root}/src/common/br/infra_if.c", + "${openthread_nxp_root}/src/common/br/lwip_hooks.c", + "${openthread_nxp_root}/src/common/br/lwip_mcast.c", + "${openthread_nxp_root}/src/common/br/mdns_socket.c", + "${openthread_nxp_root}/src/common/br/udp_plat.c", + "${openthread_nxp_root}/src/common/br/utils.c", + ] + + if (chip_enable_matter_cli) { + sources += [ + "${openthread_nxp_root}/examples/utils/cli_addons/addons_cli.c", + "${openthread_nxp_root}/examples/utils/cli_addons/ephemeral_key/ephemeral_key_cli.c", + "${openthread_nxp_root}/examples/utils/cli_addons/lwip/lwip_cli.c", + ] + } + + deps += [ "${nxp_sdk_build_root}:nxp_lwip" ] + } + + if (nxp_nvm_component == "nvm_fwk") { + sources += [ "${openthread_nxp_root}/src/common/flash_nvm.c" ] + } else { + sources += [ "${openthread_nxp_root}/src/common/flash_littlefs.c" ] + } + + defines = [ "OPENTHREAD_FTD" ] + + if (hci_spinel_single_uart) { + defines += [ "OT_PLAT_SPINEL_HCI_OVER_HDLC" ] + sources += + [ "${openthread_nxp_root}/src/common/spinel/spinel_hci_hdlc.cpp" ] + } else if (spinel_over_spi == true) { + defines += [ + "OT_PLAT_SPINEL_OVER_SPI", + "OT_PLATFORM_CONFIG_SPI_INSTANCE=4", + "OT_PLATFORM_CONFIG_SPI_INT_PORT=2", + "OT_PLATFORM_CONFIG_SPI_INT_PIN=4", + "LPSPI_MASTER_CLK_FREQ=CLOCK_GetClockRootFreq(kCLOCK_LpspiClkRoot)", + ] + sources += [ "${openthread_nxp_root}/src/common/spinel/spi_interface.cpp" ] + } else { + defines += [ "OT_PLAT_SPINEL_OVER_HDLC" ] + } + + public_configs = [ ":openthread_rt1060_config" ] + + deps += [ + "${nxp_sdk_build_root}:nxp_mbedtls", + "${openthread_root}:libopenthread-spinel-rcp", + "../../..:libopenthread-platform-utils", + nxp_sdk_target, + ] +} diff --git a/third_party/openthread/platforms/nxp/rt/rt1170/BUILD.gn b/third_party/openthread/platforms/nxp/rt/rt1170/BUILD.gn new file mode 100644 index 00000000000000..039c911e51fa60 --- /dev/null +++ b/third_party/openthread/platforms/nxp/rt/rt1170/BUILD.gn @@ -0,0 +1,142 @@ +# Copyright (c) 2020-2022 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/chip.gni") +import("//build_overrides/mbedtls.gni") +import("//build_overrides/nxp_sdk.gni") +import("//build_overrides/openthread.gni") + +#allows to get common NXP SDK gn options +import("${nxp_sdk_build_root}/nxp_sdk.gni") + +# Allows to get various RT gn options +import("${nxp_sdk_build_root}/${nxp_sdk_name}/${nxp_sdk_name}.gni") +openthread_nxp_root = "${chip_root}/third_party/openthread/ot-nxp" + +config("openthread_rt1170_config") { + include_dirs = [ + "${openthread_nxp_root}/src/common", + "${openthread_nxp_root}/src/common/br", + "${openthread_nxp_root}/src/imx_rt/rt1170", + "${openthread_nxp_root}/third_party/mbedtls/configs", + "${openthread_root}/third_party/mbedtls", + "${openthread_root}/examples/platforms", + "${openthread_nxp_root}/examples/utils/cli_addons", + "${openthread_nxp_root}/examples/utils/cli_addons/ephemeral_key", + "${openthread_nxp_root}/examples/utils/cli_addons/lwip", + ] + defines = [ "OT_PLAT_SPINEL_OVER_SPI" ] + + if (chip_enable_wifi && chip_enable_openthread) { + defines += [ + "OPENTHREAD_CONFIG_BORDER_ROUTER_ENABLE=1", + "OPENTHREAD_CONFIG_COMMISSIONER_ENABLE=1", + "OPENTHREAD_CONFIG_BORDER_ROUTING_ENABLE=1", + "OPENTHREAD_CONFIG_PLATFORM_UDP_ENABLE=1", + "OPENTHREAD_CONFIG_BACKBONE_ROUTER_ENABLE=1", + "OPENTHREAD_CONFIG_MAX_STATECHANGE_HANDLERS=3", + "OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE=1", + "OPENTHREAD_CONFIG_BORDER_AGENT_ID_ENABLE=1", + "OPENTHREAD_CONFIG_BORDER_ROUTING_DHCP6_PD_ENABLE=1", + "OPENTHREAD_CONFIG_SRP_SERVER_ADVERTISING_PROXY_ENABLE=1", + "OPENTHREAD_CONFIG_DNSSD_DISCOVERY_PROXY_ENABLE=1", + "OPENTHREAD_CONFIG_MULTICAST_DNS_ENABLE=1", + "OPENTHREAD_CONFIG_MULTICAST_DNS_PUBLIC_API_ENABLE=1", + "OT_APP_BR_LWIP_HOOKS_EN=1", + ] + + if (chip_enable_matter_cli) { + defines += [ + "OPENTHREAD_CONFIG_BORDER_AGENT_EPHEMERAL_KEY_ENABLE=1", + "OT_APP_CLI_EPHEMERAL_KEY_ADDON=1", + "OT_APP_CLI_LWIP_ADDON=1", + ] + } + } + + # ot cli configs + defines += [ "OPENTHREAD_CONFIG_PING_SENDER_ENABLE=1" ] +} + +#Config used by the openthread stack to get the path to OpenthreadConfig.h +source_set("openthread_core_config_rt1170") { + public_configs = [ ":openthread_rt1170_config" ] + public_deps = [ nxp_sdk_target ] +} + +source_set("libopenthread-rt1170") { + deps = [] + sources = [ + "${openthread_nxp_root}/src/common/alarm_freertos.c", + "${openthread_nxp_root}/src/common/diag.c", + "${openthread_nxp_root}/src/common/entropy.c", + "${openthread_nxp_root}/src/common/logging.c", + "${openthread_nxp_root}/src/common/spinel/misc.c", + "${openthread_nxp_root}/src/common/spinel/radio.cpp", + "${openthread_nxp_root}/src/common/spinel/system.c", + "${openthread_root}/src/lib/hdlc/hdlc.cpp", + "${openthread_root}/src/lib/url/url.cpp", + ] + + if (chip_enable_wifi && chip_enable_openthread) { + sources += [ + "${openthread_nxp_root}/src/common/br/border_agent.c", + "${openthread_nxp_root}/src/common/br/br_rtos_manager.c", + "${openthread_nxp_root}/src/common/br/infra_if.c", + "${openthread_nxp_root}/src/common/br/lwip_hooks.c", + "${openthread_nxp_root}/src/common/br/lwip_mcast.c", + "${openthread_nxp_root}/src/common/br/mdns_socket.c", + "${openthread_nxp_root}/src/common/br/udp_plat.c", + "${openthread_nxp_root}/src/common/br/utils.c", + ] + + if (chip_enable_matter_cli) { + sources += [ + "${openthread_nxp_root}/examples/utils/cli_addons/addons_cli.c", + "${openthread_nxp_root}/examples/utils/cli_addons/ephemeral_key/ephemeral_key_cli.c", + "${openthread_nxp_root}/examples/utils/cli_addons/lwip/lwip_cli.c", + ] + } + + deps += [ "${nxp_sdk_build_root}:nxp_lwip" ] + } + + if (nxp_nvm_component == "nvm_fwk") { + sources += [ "${openthread_nxp_root}/src/common/flash_nvm.c" ] + } else { + sources += [ "${openthread_nxp_root}/src/common/flash_littlefs.c" ] + } + + defines = [ "OPENTHREAD_FTD" ] + + if (hci_spinel_single_uart) { + defines += [ "OT_PLAT_SPINEL_HCI_OVER_HDLC" ] + sources += [ + "${openthread_nxp_root}/src/common/spinel/spinel_hci_hdlc.cpp", + "${openthread_nxp_root}/src/common/spinel/spinel_hdlc.cpp", + ] + } else { + defines += [ "OT_PLAT_SPINEL_OVER_SPI" ] + sources += [ "${openthread_nxp_root}/src/common/spinel/spi_interface.cpp" ] + } + + public_configs = [ ":openthread_rt1170_config" ] + + deps += [ + "${nxp_sdk_build_root}:nxp_mbedtls", + "${openthread_root}:libopenthread-spinel-rcp", + "../../..:libopenthread-platform-utils", + nxp_sdk_target, + ] +} From c03ffef75ffdb3e48cb841b1c814d91e17f03da1 Mon Sep 17 00:00:00 2001 From: Stefan Agner Date: Thu, 17 Oct 2024 15:34:14 +0200 Subject: [PATCH 015/149] [Python] Improve type hints of cluster objects (#29966) * Use default value for initialization The default value returns a valid value for the initialization according to the type hints. This lowers the type hints errors using mypy from 838 to 354. * Make response_type an optional string if initialized to None This reduced mypy type errors from 354 to 163. * Use non-string type annotations Python 3.7 and newer don't need strings for type annotations anymore. This makes type annotations more readable in most editors. * regen --- .../python/chip/clusters/Objects.py | 10173 ++++++++-------- .../templates/python-cluster-Objects-py.zapt | 15 +- 2 files changed, 5095 insertions(+), 5093 deletions(-) diff --git a/src/controller/python/chip/clusters/Objects.py b/src/controller/python/chip/clusters/Objects.py index 11674124680fc0..076dc946e39898 100644 --- a/src/controller/python/chip/clusters/Objects.py +++ b/src/controller/python/chip/clusters/Objects.py @@ -23,6 +23,7 @@ # Users are not expected to import this file, instead, users can use import chip.clusters, # which will import all symbols from this file and can get a readable, pretty naming like # clusters.OnOff.commands.OnCommand +from __future__ import annotations import typing from dataclasses import dataclass, field @@ -490,14 +491,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - identifyTime: 'uint' = None - identifyType: 'Identify.Enums.IdentifyTypeEnum' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + identifyTime: uint = 0 + identifyType: Identify.Enums.IdentifyTypeEnum = 0 + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class EffectIdentifierEnum(MatterIntEnum): @@ -540,7 +541,7 @@ class Identify(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000003 command_id: typing.ClassVar[int] = 0x00000000 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -549,14 +550,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="identifyTime", Tag=0, Type=uint), ]) - identifyTime: 'uint' = 0 + identifyTime: uint = 0 @dataclass class TriggerEffect(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000003 command_id: typing.ClassVar[int] = 0x00000040 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -566,8 +567,8 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="effectVariant", Tag=1, Type=Identify.Enums.EffectVariantEnum), ]) - effectIdentifier: 'Identify.Enums.EffectIdentifierEnum' = 0 - effectVariant: 'Identify.Enums.EffectVariantEnum' = 0 + effectIdentifier: Identify.Enums.EffectIdentifierEnum = 0 + effectVariant: Identify.Enums.EffectVariantEnum = 0 class Attributes: @dataclass @@ -584,7 +585,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class IdentifyType(ClusterAttributeDescriptor): @@ -600,7 +601,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=Identify.Enums.IdentifyTypeEnum) - value: 'Identify.Enums.IdentifyTypeEnum' = 0 + value: Identify.Enums.IdentifyTypeEnum = 0 @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -616,7 +617,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -632,7 +633,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -648,7 +649,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -664,7 +665,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -680,7 +681,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -696,7 +697,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -716,13 +717,13 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - nameSupport: 'uint' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + nameSupport: uint = 0 + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Bitmaps: class Feature(IntFlag): @@ -747,15 +748,15 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="groupName", Tag=1, Type=str), ]) - groupID: 'uint' = 0 - groupName: 'str' = "" + groupID: uint = 0 + groupName: str = "" @dataclass class AddGroupResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000004 command_id: typing.ClassVar[int] = 0x00000000 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -765,8 +766,8 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="groupID", Tag=1, Type=uint), ]) - status: 'uint' = 0 - groupID: 'uint' = 0 + status: uint = 0 + groupID: uint = 0 @dataclass class ViewGroup(ClusterCommand): @@ -782,14 +783,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="groupID", Tag=0, Type=uint), ]) - groupID: 'uint' = 0 + groupID: uint = 0 @dataclass class ViewGroupResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000004 command_id: typing.ClassVar[int] = 0x00000001 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -800,9 +801,9 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="groupName", Tag=2, Type=str), ]) - status: 'uint' = 0 - groupID: 'uint' = 0 - groupName: 'str' = "" + status: uint = 0 + groupID: uint = 0 + groupName: str = "" @dataclass class GetGroupMembership(ClusterCommand): @@ -818,14 +819,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="groupList", Tag=0, Type=typing.List[uint]), ]) - groupList: 'typing.List[uint]' = field(default_factory=lambda: []) + groupList: typing.List[uint] = field(default_factory=lambda: []) @dataclass class GetGroupMembershipResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000004 command_id: typing.ClassVar[int] = 0x00000002 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -835,8 +836,8 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="groupList", Tag=1, Type=typing.List[uint]), ]) - capacity: 'typing.Union[Nullable, uint]' = NullValue - groupList: 'typing.List[uint]' = field(default_factory=lambda: []) + capacity: typing.Union[Nullable, uint] = NullValue + groupList: typing.List[uint] = field(default_factory=lambda: []) @dataclass class RemoveGroup(ClusterCommand): @@ -852,14 +853,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="groupID", Tag=0, Type=uint), ]) - groupID: 'uint' = 0 + groupID: uint = 0 @dataclass class RemoveGroupResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000004 command_id: typing.ClassVar[int] = 0x00000003 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -869,15 +870,15 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="groupID", Tag=1, Type=uint), ]) - status: 'uint' = 0 - groupID: 'uint' = 0 + status: uint = 0 + groupID: uint = 0 @dataclass class RemoveAllGroups(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000004 command_id: typing.ClassVar[int] = 0x00000004 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -890,7 +891,7 @@ class AddGroupIfIdentifying(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000004 command_id: typing.ClassVar[int] = 0x00000005 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -900,8 +901,8 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="groupName", Tag=1, Type=str), ]) - groupID: 'uint' = 0 - groupName: 'str' = "" + groupID: uint = 0 + groupName: str = "" class Attributes: @dataclass @@ -918,7 +919,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -934,7 +935,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -950,7 +951,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -966,7 +967,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -982,7 +983,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -998,7 +999,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -1014,7 +1015,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -1038,17 +1039,17 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - onOff: 'bool' = None - globalSceneControl: 'typing.Optional[bool]' = None - onTime: 'typing.Optional[uint]' = None - offWaitTime: 'typing.Optional[uint]' = None - startUpOnOff: 'typing.Union[None, Nullable, OnOff.Enums.StartUpOnOffEnum]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + onOff: bool = False + globalSceneControl: typing.Optional[bool] = None + onTime: typing.Optional[uint] = None + offWaitTime: typing.Optional[uint] = None + startUpOnOff: typing.Union[None, Nullable, OnOff.Enums.StartUpOnOffEnum] = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class DelayedAllOffEffectVariantEnum(MatterIntEnum): @@ -1103,7 +1104,7 @@ class Off(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000006 command_id: typing.ClassVar[int] = 0x00000000 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -1116,7 +1117,7 @@ class On(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000006 command_id: typing.ClassVar[int] = 0x00000001 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -1129,7 +1130,7 @@ class Toggle(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000006 command_id: typing.ClassVar[int] = 0x00000002 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -1142,7 +1143,7 @@ class OffWithEffect(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000006 command_id: typing.ClassVar[int] = 0x00000040 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -1152,15 +1153,15 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="effectVariant", Tag=1, Type=uint), ]) - effectIdentifier: 'OnOff.Enums.EffectIdentifierEnum' = 0 - effectVariant: 'uint' = 0 + effectIdentifier: OnOff.Enums.EffectIdentifierEnum = 0 + effectVariant: uint = 0 @dataclass class OnWithRecallGlobalScene(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000006 command_id: typing.ClassVar[int] = 0x00000041 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -1173,7 +1174,7 @@ class OnWithTimedOff(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000006 command_id: typing.ClassVar[int] = 0x00000042 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -1184,9 +1185,9 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="offWaitTime", Tag=2, Type=uint), ]) - onOffControl: 'uint' = 0 - onTime: 'uint' = 0 - offWaitTime: 'uint' = 0 + onOffControl: uint = 0 + onTime: uint = 0 + offWaitTime: uint = 0 class Attributes: @dataclass @@ -1203,7 +1204,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=bool) - value: 'bool' = False + value: bool = False @dataclass class GlobalSceneControl(ClusterAttributeDescriptor): @@ -1219,7 +1220,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[bool]) - value: 'typing.Optional[bool]' = None + value: typing.Optional[bool] = None @dataclass class OnTime(ClusterAttributeDescriptor): @@ -1235,7 +1236,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class OffWaitTime(ClusterAttributeDescriptor): @@ -1251,7 +1252,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class StartUpOnOff(ClusterAttributeDescriptor): @@ -1267,7 +1268,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, OnOff.Enums.StartUpOnOffEnum]) - value: 'typing.Union[None, Nullable, OnOff.Enums.StartUpOnOffEnum]' = None + value: typing.Union[None, Nullable, OnOff.Enums.StartUpOnOffEnum] = None @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -1283,7 +1284,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -1299,7 +1300,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -1315,7 +1316,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -1331,7 +1332,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -1347,7 +1348,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -1363,7 +1364,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -1396,26 +1397,26 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - currentLevel: 'typing.Union[Nullable, uint]' = None - remainingTime: 'typing.Optional[uint]' = None - minLevel: 'typing.Optional[uint]' = None - maxLevel: 'typing.Optional[uint]' = None - currentFrequency: 'typing.Optional[uint]' = None - minFrequency: 'typing.Optional[uint]' = None - maxFrequency: 'typing.Optional[uint]' = None - options: 'uint' = None - onOffTransitionTime: 'typing.Optional[uint]' = None - onLevel: 'typing.Union[Nullable, uint]' = None - onTransitionTime: 'typing.Union[None, Nullable, uint]' = None - offTransitionTime: 'typing.Union[None, Nullable, uint]' = None - defaultMoveRate: 'typing.Union[None, Nullable, uint]' = None - startUpCurrentLevel: 'typing.Union[None, Nullable, uint]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + currentLevel: typing.Union[Nullable, uint] = NullValue + remainingTime: typing.Optional[uint] = None + minLevel: typing.Optional[uint] = None + maxLevel: typing.Optional[uint] = None + currentFrequency: typing.Optional[uint] = None + minFrequency: typing.Optional[uint] = None + maxFrequency: typing.Optional[uint] = None + options: uint = 0 + onOffTransitionTime: typing.Optional[uint] = None + onLevel: typing.Union[Nullable, uint] = NullValue + onTransitionTime: typing.Union[None, Nullable, uint] = None + offTransitionTime: typing.Union[None, Nullable, uint] = None + defaultMoveRate: typing.Union[None, Nullable, uint] = None + startUpCurrentLevel: typing.Union[None, Nullable, uint] = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class MoveModeEnum(MatterIntEnum): @@ -1452,7 +1453,7 @@ class MoveToLevel(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000008 command_id: typing.ClassVar[int] = 0x00000000 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -1464,17 +1465,17 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="optionsOverride", Tag=3, Type=uint), ]) - level: 'uint' = 0 - transitionTime: 'typing.Union[Nullable, uint]' = NullValue - optionsMask: 'uint' = 0 - optionsOverride: 'uint' = 0 + level: uint = 0 + transitionTime: typing.Union[Nullable, uint] = NullValue + optionsMask: uint = 0 + optionsOverride: uint = 0 @dataclass class Move(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000008 command_id: typing.ClassVar[int] = 0x00000001 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -1486,17 +1487,17 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="optionsOverride", Tag=3, Type=uint), ]) - moveMode: 'LevelControl.Enums.MoveModeEnum' = 0 - rate: 'typing.Union[Nullable, uint]' = NullValue - optionsMask: 'uint' = 0 - optionsOverride: 'uint' = 0 + moveMode: LevelControl.Enums.MoveModeEnum = 0 + rate: typing.Union[Nullable, uint] = NullValue + optionsMask: uint = 0 + optionsOverride: uint = 0 @dataclass class Step(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000008 command_id: typing.ClassVar[int] = 0x00000002 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -1509,18 +1510,18 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="optionsOverride", Tag=4, Type=uint), ]) - stepMode: 'LevelControl.Enums.StepModeEnum' = 0 - stepSize: 'uint' = 0 - transitionTime: 'typing.Union[Nullable, uint]' = NullValue - optionsMask: 'uint' = 0 - optionsOverride: 'uint' = 0 + stepMode: LevelControl.Enums.StepModeEnum = 0 + stepSize: uint = 0 + transitionTime: typing.Union[Nullable, uint] = NullValue + optionsMask: uint = 0 + optionsOverride: uint = 0 @dataclass class Stop(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000008 command_id: typing.ClassVar[int] = 0x00000003 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -1530,15 +1531,15 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="optionsOverride", Tag=1, Type=uint), ]) - optionsMask: 'uint' = 0 - optionsOverride: 'uint' = 0 + optionsMask: uint = 0 + optionsOverride: uint = 0 @dataclass class MoveToLevelWithOnOff(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000008 command_id: typing.ClassVar[int] = 0x00000004 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -1550,17 +1551,17 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="optionsOverride", Tag=3, Type=uint), ]) - level: 'uint' = 0 - transitionTime: 'typing.Union[Nullable, uint]' = NullValue - optionsMask: 'uint' = 0 - optionsOverride: 'uint' = 0 + level: uint = 0 + transitionTime: typing.Union[Nullable, uint] = NullValue + optionsMask: uint = 0 + optionsOverride: uint = 0 @dataclass class MoveWithOnOff(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000008 command_id: typing.ClassVar[int] = 0x00000005 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -1572,17 +1573,17 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="optionsOverride", Tag=3, Type=uint), ]) - moveMode: 'LevelControl.Enums.MoveModeEnum' = 0 - rate: 'typing.Union[Nullable, uint]' = NullValue - optionsMask: 'uint' = 0 - optionsOverride: 'uint' = 0 + moveMode: LevelControl.Enums.MoveModeEnum = 0 + rate: typing.Union[Nullable, uint] = NullValue + optionsMask: uint = 0 + optionsOverride: uint = 0 @dataclass class StepWithOnOff(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000008 command_id: typing.ClassVar[int] = 0x00000006 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -1595,18 +1596,18 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="optionsOverride", Tag=4, Type=uint), ]) - stepMode: 'LevelControl.Enums.StepModeEnum' = 0 - stepSize: 'uint' = 0 - transitionTime: 'typing.Union[Nullable, uint]' = NullValue - optionsMask: 'uint' = 0 - optionsOverride: 'uint' = 0 + stepMode: LevelControl.Enums.StepModeEnum = 0 + stepSize: uint = 0 + transitionTime: typing.Union[Nullable, uint] = NullValue + optionsMask: uint = 0 + optionsOverride: uint = 0 @dataclass class StopWithOnOff(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000008 command_id: typing.ClassVar[int] = 0x00000007 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -1616,15 +1617,15 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="optionsOverride", Tag=1, Type=uint), ]) - optionsMask: 'uint' = 0 - optionsOverride: 'uint' = 0 + optionsMask: uint = 0 + optionsOverride: uint = 0 @dataclass class MoveToClosestFrequency(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000008 command_id: typing.ClassVar[int] = 0x00000008 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -1633,7 +1634,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="frequency", Tag=0, Type=uint), ]) - frequency: 'uint' = 0 + frequency: uint = 0 class Attributes: @dataclass @@ -1650,7 +1651,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, uint]) - value: 'typing.Union[Nullable, uint]' = NullValue + value: typing.Union[Nullable, uint] = NullValue @dataclass class RemainingTime(ClusterAttributeDescriptor): @@ -1666,7 +1667,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class MinLevel(ClusterAttributeDescriptor): @@ -1682,7 +1683,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class MaxLevel(ClusterAttributeDescriptor): @@ -1698,7 +1699,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class CurrentFrequency(ClusterAttributeDescriptor): @@ -1714,7 +1715,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class MinFrequency(ClusterAttributeDescriptor): @@ -1730,7 +1731,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class MaxFrequency(ClusterAttributeDescriptor): @@ -1746,7 +1747,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class Options(ClusterAttributeDescriptor): @@ -1762,7 +1763,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class OnOffTransitionTime(ClusterAttributeDescriptor): @@ -1778,7 +1779,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class OnLevel(ClusterAttributeDescriptor): @@ -1794,7 +1795,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, uint]) - value: 'typing.Union[Nullable, uint]' = NullValue + value: typing.Union[Nullable, uint] = NullValue @dataclass class OnTransitionTime(ClusterAttributeDescriptor): @@ -1810,7 +1811,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class OffTransitionTime(ClusterAttributeDescriptor): @@ -1826,7 +1827,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class DefaultMoveRate(ClusterAttributeDescriptor): @@ -1842,7 +1843,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class StartUpCurrentLevel(ClusterAttributeDescriptor): @@ -1858,7 +1859,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -1874,7 +1875,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -1890,7 +1891,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -1906,7 +1907,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -1922,7 +1923,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -1938,7 +1939,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -1954,7 +1955,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -1973,12 +1974,12 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Attributes: @dataclass @@ -1995,7 +1996,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -2011,7 +2012,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -2027,7 +2028,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -2043,7 +2044,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -2059,7 +2060,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -2075,7 +2076,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -2099,17 +2100,17 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - deviceTypeList: 'typing.List[Descriptor.Structs.DeviceTypeStruct]' = None - serverList: 'typing.List[uint]' = None - clientList: 'typing.List[uint]' = None - partsList: 'typing.List[uint]' = None - tagList: 'typing.Optional[typing.List[Descriptor.Structs.SemanticTagStruct]]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + deviceTypeList: typing.List[Descriptor.Structs.DeviceTypeStruct] = field(default_factory=lambda: []) + serverList: typing.List[uint] = field(default_factory=lambda: []) + clientList: typing.List[uint] = field(default_factory=lambda: []) + partsList: typing.List[uint] = field(default_factory=lambda: []) + tagList: typing.Optional[typing.List[Descriptor.Structs.SemanticTagStruct]] = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Bitmaps: class Feature(IntFlag): @@ -2161,7 +2162,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[Descriptor.Structs.DeviceTypeStruct]) - value: 'typing.List[Descriptor.Structs.DeviceTypeStruct]' = field(default_factory=lambda: []) + value: typing.List[Descriptor.Structs.DeviceTypeStruct] = field(default_factory=lambda: []) @dataclass class ServerList(ClusterAttributeDescriptor): @@ -2177,7 +2178,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class ClientList(ClusterAttributeDescriptor): @@ -2193,7 +2194,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class PartsList(ClusterAttributeDescriptor): @@ -2209,7 +2210,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class TagList(ClusterAttributeDescriptor): @@ -2225,7 +2226,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[typing.List[Descriptor.Structs.SemanticTagStruct]]) - value: 'typing.Optional[typing.List[Descriptor.Structs.SemanticTagStruct]]' = None + value: typing.Optional[typing.List[Descriptor.Structs.SemanticTagStruct]] = None @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -2241,7 +2242,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -2257,7 +2258,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -2273,7 +2274,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -2289,7 +2290,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -2305,7 +2306,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -2321,7 +2322,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -2341,13 +2342,13 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - binding: 'typing.List[Binding.Structs.TargetStruct]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + binding: typing.List[Binding.Structs.TargetStruct] = field(default_factory=lambda: []) + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Structs: @dataclass @@ -2384,7 +2385,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[Binding.Structs.TargetStruct]) - value: 'typing.List[Binding.Structs.TargetStruct]' = field(default_factory=lambda: []) + value: typing.List[Binding.Structs.TargetStruct] = field(default_factory=lambda: []) @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -2400,7 +2401,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -2416,7 +2417,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -2432,7 +2433,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -2448,7 +2449,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -2464,7 +2465,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -2480,7 +2481,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -2506,19 +2507,19 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - acl: 'typing.List[AccessControl.Structs.AccessControlEntryStruct]' = None - extension: 'typing.Optional[typing.List[AccessControl.Structs.AccessControlExtensionStruct]]' = None - subjectsPerAccessControlEntry: 'uint' = None - targetsPerAccessControlEntry: 'uint' = None - accessControlEntriesPerFabric: 'uint' = None - commissioningARL: 'typing.Optional[typing.List[AccessControl.Structs.CommissioningAccessRestrictionEntryStruct]]' = None - arl: 'typing.Optional[typing.List[AccessControl.Structs.AccessRestrictionEntryStruct]]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + acl: typing.List[AccessControl.Structs.AccessControlEntryStruct] = field(default_factory=lambda: []) + extension: typing.Optional[typing.List[AccessControl.Structs.AccessControlExtensionStruct]] = None + subjectsPerAccessControlEntry: uint = 0 + targetsPerAccessControlEntry: uint = 0 + accessControlEntriesPerFabric: uint = 0 + commissioningARL: typing.Optional[typing.List[AccessControl.Structs.CommissioningAccessRestrictionEntryStruct]] = None + arl: typing.Optional[typing.List[AccessControl.Structs.AccessRestrictionEntryStruct]] = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class AccessControlEntryAuthModeEnum(MatterIntEnum): @@ -2677,14 +2678,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="arl", Tag=0, Type=typing.List[AccessControl.Structs.CommissioningAccessRestrictionEntryStruct]), ]) - arl: 'typing.List[AccessControl.Structs.CommissioningAccessRestrictionEntryStruct]' = field(default_factory=lambda: []) + arl: typing.List[AccessControl.Structs.CommissioningAccessRestrictionEntryStruct] = field(default_factory=lambda: []) @dataclass class ReviewFabricRestrictionsResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x0000001F command_id: typing.ClassVar[int] = 0x00000001 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -2693,7 +2694,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="token", Tag=0, Type=uint), ]) - token: 'uint' = 0 + token: uint = 0 class Attributes: @dataclass @@ -2710,7 +2711,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[AccessControl.Structs.AccessControlEntryStruct]) - value: 'typing.List[AccessControl.Structs.AccessControlEntryStruct]' = field(default_factory=lambda: []) + value: typing.List[AccessControl.Structs.AccessControlEntryStruct] = field(default_factory=lambda: []) @dataclass class Extension(ClusterAttributeDescriptor): @@ -2726,7 +2727,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[typing.List[AccessControl.Structs.AccessControlExtensionStruct]]) - value: 'typing.Optional[typing.List[AccessControl.Structs.AccessControlExtensionStruct]]' = None + value: typing.Optional[typing.List[AccessControl.Structs.AccessControlExtensionStruct]] = None @dataclass class SubjectsPerAccessControlEntry(ClusterAttributeDescriptor): @@ -2742,7 +2743,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class TargetsPerAccessControlEntry(ClusterAttributeDescriptor): @@ -2758,7 +2759,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class AccessControlEntriesPerFabric(ClusterAttributeDescriptor): @@ -2774,7 +2775,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class CommissioningARL(ClusterAttributeDescriptor): @@ -2790,7 +2791,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[typing.List[AccessControl.Structs.CommissioningAccessRestrictionEntryStruct]]) - value: 'typing.Optional[typing.List[AccessControl.Structs.CommissioningAccessRestrictionEntryStruct]]' = None + value: typing.Optional[typing.List[AccessControl.Structs.CommissioningAccessRestrictionEntryStruct]] = None @dataclass class Arl(ClusterAttributeDescriptor): @@ -2806,7 +2807,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[typing.List[AccessControl.Structs.AccessRestrictionEntryStruct]]) - value: 'typing.Optional[typing.List[AccessControl.Structs.AccessRestrictionEntryStruct]]' = None + value: typing.Optional[typing.List[AccessControl.Structs.AccessRestrictionEntryStruct]] = None @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -2822,7 +2823,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -2838,7 +2839,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -2854,7 +2855,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -2870,7 +2871,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -2886,7 +2887,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -2902,7 +2903,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 class Events: @dataclass @@ -2926,11 +2927,11 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="fabricIndex", Tag=254, Type=uint), ]) - adminNodeID: 'typing.Union[Nullable, uint]' = NullValue - adminPasscodeID: 'typing.Union[Nullable, uint]' = NullValue - changeType: 'AccessControl.Enums.ChangeTypeEnum' = 0 - latestValue: 'typing.Union[Nullable, AccessControl.Structs.AccessControlEntryStruct]' = NullValue - fabricIndex: 'uint' = 0 + adminNodeID: typing.Union[Nullable, uint] = NullValue + adminPasscodeID: typing.Union[Nullable, uint] = NullValue + changeType: AccessControl.Enums.ChangeTypeEnum = 0 + latestValue: typing.Union[Nullable, AccessControl.Structs.AccessControlEntryStruct] = NullValue + fabricIndex: uint = 0 @dataclass class AccessControlExtensionChanged(ClusterEvent): @@ -2953,11 +2954,11 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="fabricIndex", Tag=254, Type=uint), ]) - adminNodeID: 'typing.Union[Nullable, uint]' = NullValue - adminPasscodeID: 'typing.Union[Nullable, uint]' = NullValue - changeType: 'AccessControl.Enums.ChangeTypeEnum' = 0 - latestValue: 'typing.Union[Nullable, AccessControl.Structs.AccessControlExtensionStruct]' = NullValue - fabricIndex: 'uint' = 0 + adminNodeID: typing.Union[Nullable, uint] = NullValue + adminPasscodeID: typing.Union[Nullable, uint] = NullValue + changeType: AccessControl.Enums.ChangeTypeEnum = 0 + latestValue: typing.Union[Nullable, AccessControl.Structs.AccessControlExtensionStruct] = NullValue + fabricIndex: uint = 0 @dataclass class FabricRestrictionReviewUpdate(ClusterEvent): @@ -2979,10 +2980,10 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="fabricIndex", Tag=254, Type=uint), ]) - token: 'uint' = 0 - instruction: 'typing.Optional[str]' = None - ARLRequestFlowUrl: 'typing.Optional[str]' = None - fabricIndex: 'uint' = 0 + token: uint = 0 + instruction: typing.Optional[str] = None + ARLRequestFlowUrl: typing.Optional[str] = None + fabricIndex: uint = 0 @dataclass @@ -3004,15 +3005,15 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - actionList: 'typing.List[Actions.Structs.ActionStruct]' = None - endpointLists: 'typing.List[Actions.Structs.EndpointListStruct]' = None - setupURL: 'typing.Optional[str]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + actionList: typing.List[Actions.Structs.ActionStruct] = field(default_factory=lambda: []) + endpointLists: typing.List[Actions.Structs.EndpointListStruct] = field(default_factory=lambda: []) + setupURL: typing.Optional[str] = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class ActionErrorEnum(MatterIntEnum): @@ -3119,7 +3120,7 @@ class InstantAction(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000025 command_id: typing.ClassVar[int] = 0x00000000 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -3129,15 +3130,15 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="invokeID", Tag=1, Type=typing.Optional[uint]), ]) - actionID: 'uint' = 0 - invokeID: 'typing.Optional[uint]' = None + actionID: uint = 0 + invokeID: typing.Optional[uint] = None @dataclass class InstantActionWithTransition(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000025 command_id: typing.ClassVar[int] = 0x00000001 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -3148,16 +3149,16 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="transitionTime", Tag=2, Type=uint), ]) - actionID: 'uint' = 0 - invokeID: 'typing.Optional[uint]' = None - transitionTime: 'uint' = 0 + actionID: uint = 0 + invokeID: typing.Optional[uint] = None + transitionTime: uint = 0 @dataclass class StartAction(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000025 command_id: typing.ClassVar[int] = 0x00000002 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -3167,15 +3168,15 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="invokeID", Tag=1, Type=typing.Optional[uint]), ]) - actionID: 'uint' = 0 - invokeID: 'typing.Optional[uint]' = None + actionID: uint = 0 + invokeID: typing.Optional[uint] = None @dataclass class StartActionWithDuration(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000025 command_id: typing.ClassVar[int] = 0x00000003 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -3186,16 +3187,16 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="duration", Tag=2, Type=uint), ]) - actionID: 'uint' = 0 - invokeID: 'typing.Optional[uint]' = None - duration: 'uint' = 0 + actionID: uint = 0 + invokeID: typing.Optional[uint] = None + duration: uint = 0 @dataclass class StopAction(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000025 command_id: typing.ClassVar[int] = 0x00000004 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -3205,15 +3206,15 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="invokeID", Tag=1, Type=typing.Optional[uint]), ]) - actionID: 'uint' = 0 - invokeID: 'typing.Optional[uint]' = None + actionID: uint = 0 + invokeID: typing.Optional[uint] = None @dataclass class PauseAction(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000025 command_id: typing.ClassVar[int] = 0x00000005 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -3223,15 +3224,15 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="invokeID", Tag=1, Type=typing.Optional[uint]), ]) - actionID: 'uint' = 0 - invokeID: 'typing.Optional[uint]' = None + actionID: uint = 0 + invokeID: typing.Optional[uint] = None @dataclass class PauseActionWithDuration(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000025 command_id: typing.ClassVar[int] = 0x00000006 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -3242,16 +3243,16 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="duration", Tag=2, Type=uint), ]) - actionID: 'uint' = 0 - invokeID: 'typing.Optional[uint]' = None - duration: 'uint' = 0 + actionID: uint = 0 + invokeID: typing.Optional[uint] = None + duration: uint = 0 @dataclass class ResumeAction(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000025 command_id: typing.ClassVar[int] = 0x00000007 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -3261,15 +3262,15 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="invokeID", Tag=1, Type=typing.Optional[uint]), ]) - actionID: 'uint' = 0 - invokeID: 'typing.Optional[uint]' = None + actionID: uint = 0 + invokeID: typing.Optional[uint] = None @dataclass class EnableAction(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000025 command_id: typing.ClassVar[int] = 0x00000008 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -3279,15 +3280,15 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="invokeID", Tag=1, Type=typing.Optional[uint]), ]) - actionID: 'uint' = 0 - invokeID: 'typing.Optional[uint]' = None + actionID: uint = 0 + invokeID: typing.Optional[uint] = None @dataclass class EnableActionWithDuration(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000025 command_id: typing.ClassVar[int] = 0x00000009 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -3298,16 +3299,16 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="duration", Tag=2, Type=uint), ]) - actionID: 'uint' = 0 - invokeID: 'typing.Optional[uint]' = None - duration: 'uint' = 0 + actionID: uint = 0 + invokeID: typing.Optional[uint] = None + duration: uint = 0 @dataclass class DisableAction(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000025 command_id: typing.ClassVar[int] = 0x0000000A is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -3317,15 +3318,15 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="invokeID", Tag=1, Type=typing.Optional[uint]), ]) - actionID: 'uint' = 0 - invokeID: 'typing.Optional[uint]' = None + actionID: uint = 0 + invokeID: typing.Optional[uint] = None @dataclass class DisableActionWithDuration(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000025 command_id: typing.ClassVar[int] = 0x0000000B is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -3336,9 +3337,9 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="duration", Tag=2, Type=uint), ]) - actionID: 'uint' = 0 - invokeID: 'typing.Optional[uint]' = None - duration: 'uint' = 0 + actionID: uint = 0 + invokeID: typing.Optional[uint] = None + duration: uint = 0 class Attributes: @dataclass @@ -3355,7 +3356,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[Actions.Structs.ActionStruct]) - value: 'typing.List[Actions.Structs.ActionStruct]' = field(default_factory=lambda: []) + value: typing.List[Actions.Structs.ActionStruct] = field(default_factory=lambda: []) @dataclass class EndpointLists(ClusterAttributeDescriptor): @@ -3371,7 +3372,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[Actions.Structs.EndpointListStruct]) - value: 'typing.List[Actions.Structs.EndpointListStruct]' = field(default_factory=lambda: []) + value: typing.List[Actions.Structs.EndpointListStruct] = field(default_factory=lambda: []) @dataclass class SetupURL(ClusterAttributeDescriptor): @@ -3387,7 +3388,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[str]) - value: 'typing.Optional[str]' = None + value: typing.Optional[str] = None @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -3403,7 +3404,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -3419,7 +3420,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -3435,7 +3436,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -3451,7 +3452,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -3467,7 +3468,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -3483,7 +3484,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 class Events: @dataclass @@ -3505,9 +3506,9 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="newState", Tag=2, Type=Actions.Enums.ActionStateEnum), ]) - actionID: 'uint' = 0 - invokeID: 'uint' = 0 - newState: 'Actions.Enums.ActionStateEnum' = 0 + actionID: uint = 0 + invokeID: uint = 0 + newState: Actions.Enums.ActionStateEnum = 0 @dataclass class ActionFailed(ClusterEvent): @@ -3529,10 +3530,10 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="error", Tag=3, Type=Actions.Enums.ActionErrorEnum), ]) - actionID: 'uint' = 0 - invokeID: 'uint' = 0 - newState: 'Actions.Enums.ActionStateEnum' = 0 - error: 'Actions.Enums.ActionErrorEnum' = 0 + actionID: uint = 0 + invokeID: uint = 0 + newState: Actions.Enums.ActionStateEnum = 0 + error: Actions.Enums.ActionErrorEnum = 0 @dataclass @@ -3574,35 +3575,35 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - dataModelRevision: 'uint' = None - vendorName: 'str' = None - vendorID: 'uint' = None - productName: 'str' = None - productID: 'uint' = None - nodeLabel: 'str' = None - location: 'str' = None - hardwareVersion: 'uint' = None - hardwareVersionString: 'str' = None - softwareVersion: 'uint' = None - softwareVersionString: 'str' = None - manufacturingDate: 'typing.Optional[str]' = None - partNumber: 'typing.Optional[str]' = None - productURL: 'typing.Optional[str]' = None - productLabel: 'typing.Optional[str]' = None - serialNumber: 'typing.Optional[str]' = None - localConfigDisabled: 'typing.Optional[bool]' = None - reachable: 'typing.Optional[bool]' = None - uniqueID: 'str' = None - capabilityMinima: 'BasicInformation.Structs.CapabilityMinimaStruct' = None - productAppearance: 'typing.Optional[BasicInformation.Structs.ProductAppearanceStruct]' = None - specificationVersion: 'uint' = None - maxPathsPerInvoke: 'uint' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + dataModelRevision: uint = 0 + vendorName: str = "" + vendorID: uint = 0 + productName: str = "" + productID: uint = 0 + nodeLabel: str = "" + location: str = "" + hardwareVersion: uint = 0 + hardwareVersionString: str = "" + softwareVersion: uint = 0 + softwareVersionString: str = "" + manufacturingDate: typing.Optional[str] = None + partNumber: typing.Optional[str] = None + productURL: typing.Optional[str] = None + productLabel: typing.Optional[str] = None + serialNumber: typing.Optional[str] = None + localConfigDisabled: typing.Optional[bool] = None + reachable: typing.Optional[bool] = None + uniqueID: str = "" + capabilityMinima: BasicInformation.Structs.CapabilityMinimaStruct = field(default_factory=lambda: BasicInformation.Structs.CapabilityMinimaStruct()) + productAppearance: typing.Optional[BasicInformation.Structs.ProductAppearanceStruct] = None + specificationVersion: uint = 0 + maxPathsPerInvoke: uint = 0 + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class ColorEnum(MatterIntEnum): @@ -3679,7 +3680,7 @@ class MfgSpecificPing(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000028 command_id: typing.ClassVar[int] = 0x10020000 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -3702,7 +3703,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class VendorName(ClusterAttributeDescriptor): @@ -3718,7 +3719,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=str) - value: 'str' = "" + value: str = "" @dataclass class VendorID(ClusterAttributeDescriptor): @@ -3734,7 +3735,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ProductName(ClusterAttributeDescriptor): @@ -3750,7 +3751,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=str) - value: 'str' = "" + value: str = "" @dataclass class ProductID(ClusterAttributeDescriptor): @@ -3766,7 +3767,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class NodeLabel(ClusterAttributeDescriptor): @@ -3782,7 +3783,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=str) - value: 'str' = "" + value: str = "" @dataclass class Location(ClusterAttributeDescriptor): @@ -3798,7 +3799,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=str) - value: 'str' = "" + value: str = "" @dataclass class HardwareVersion(ClusterAttributeDescriptor): @@ -3814,7 +3815,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class HardwareVersionString(ClusterAttributeDescriptor): @@ -3830,7 +3831,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=str) - value: 'str' = "" + value: str = "" @dataclass class SoftwareVersion(ClusterAttributeDescriptor): @@ -3846,7 +3847,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class SoftwareVersionString(ClusterAttributeDescriptor): @@ -3862,7 +3863,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=str) - value: 'str' = "" + value: str = "" @dataclass class ManufacturingDate(ClusterAttributeDescriptor): @@ -3878,7 +3879,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[str]) - value: 'typing.Optional[str]' = None + value: typing.Optional[str] = None @dataclass class PartNumber(ClusterAttributeDescriptor): @@ -3894,7 +3895,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[str]) - value: 'typing.Optional[str]' = None + value: typing.Optional[str] = None @dataclass class ProductURL(ClusterAttributeDescriptor): @@ -3910,7 +3911,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[str]) - value: 'typing.Optional[str]' = None + value: typing.Optional[str] = None @dataclass class ProductLabel(ClusterAttributeDescriptor): @@ -3926,7 +3927,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[str]) - value: 'typing.Optional[str]' = None + value: typing.Optional[str] = None @dataclass class SerialNumber(ClusterAttributeDescriptor): @@ -3942,7 +3943,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[str]) - value: 'typing.Optional[str]' = None + value: typing.Optional[str] = None @dataclass class LocalConfigDisabled(ClusterAttributeDescriptor): @@ -3958,7 +3959,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[bool]) - value: 'typing.Optional[bool]' = None + value: typing.Optional[bool] = None @dataclass class Reachable(ClusterAttributeDescriptor): @@ -3974,7 +3975,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[bool]) - value: 'typing.Optional[bool]' = None + value: typing.Optional[bool] = None @dataclass class UniqueID(ClusterAttributeDescriptor): @@ -3990,7 +3991,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=str) - value: 'str' = "" + value: str = "" @dataclass class CapabilityMinima(ClusterAttributeDescriptor): @@ -4006,7 +4007,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=BasicInformation.Structs.CapabilityMinimaStruct) - value: 'BasicInformation.Structs.CapabilityMinimaStruct' = field(default_factory=lambda: BasicInformation.Structs.CapabilityMinimaStruct()) + value: BasicInformation.Structs.CapabilityMinimaStruct = field(default_factory=lambda: BasicInformation.Structs.CapabilityMinimaStruct()) @dataclass class ProductAppearance(ClusterAttributeDescriptor): @@ -4022,7 +4023,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[BasicInformation.Structs.ProductAppearanceStruct]) - value: 'typing.Optional[BasicInformation.Structs.ProductAppearanceStruct]' = None + value: typing.Optional[BasicInformation.Structs.ProductAppearanceStruct] = None @dataclass class SpecificationVersion(ClusterAttributeDescriptor): @@ -4038,7 +4039,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class MaxPathsPerInvoke(ClusterAttributeDescriptor): @@ -4054,7 +4055,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -4070,7 +4071,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -4086,7 +4087,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -4102,7 +4103,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -4118,7 +4119,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -4134,7 +4135,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -4150,7 +4151,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 class Events: @dataclass @@ -4170,7 +4171,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="softwareVersion", Tag=0, Type=uint), ]) - softwareVersion: 'uint' = 0 + softwareVersion: uint = 0 @dataclass class ShutDown(ClusterEvent): @@ -4205,7 +4206,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="fabricIndex", Tag=0, Type=uint), ]) - fabricIndex: 'uint' = 0 + fabricIndex: uint = 0 @dataclass class ReachableChanged(ClusterEvent): @@ -4224,7 +4225,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="reachableNewValue", Tag=0, Type=bool), ]) - reachableNewValue: 'bool' = False + reachableNewValue: bool = False @dataclass @@ -4243,12 +4244,12 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class ApplyUpdateActionEnum(MatterIntEnum): @@ -4305,21 +4306,21 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="metadataForProvider", Tag=7, Type=typing.Optional[bytes]), ]) - vendorID: 'uint' = 0 - productID: 'uint' = 0 - softwareVersion: 'uint' = 0 - protocolsSupported: 'typing.List[OtaSoftwareUpdateProvider.Enums.DownloadProtocolEnum]' = field(default_factory=lambda: []) - hardwareVersion: 'typing.Optional[uint]' = None - location: 'typing.Optional[str]' = None - requestorCanConsent: 'typing.Optional[bool]' = None - metadataForProvider: 'typing.Optional[bytes]' = None + vendorID: uint = 0 + productID: uint = 0 + softwareVersion: uint = 0 + protocolsSupported: typing.List[OtaSoftwareUpdateProvider.Enums.DownloadProtocolEnum] = field(default_factory=lambda: []) + hardwareVersion: typing.Optional[uint] = None + location: typing.Optional[str] = None + requestorCanConsent: typing.Optional[bool] = None + metadataForProvider: typing.Optional[bytes] = None @dataclass class QueryImageResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000029 command_id: typing.ClassVar[int] = 0x00000001 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -4335,14 +4336,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="metadataForRequestor", Tag=7, Type=typing.Optional[bytes]), ]) - status: 'OtaSoftwareUpdateProvider.Enums.StatusEnum' = 0 - delayedActionTime: 'typing.Optional[uint]' = None - imageURI: 'typing.Optional[str]' = None - softwareVersion: 'typing.Optional[uint]' = None - softwareVersionString: 'typing.Optional[str]' = None - updateToken: 'typing.Optional[bytes]' = None - userConsentNeeded: 'typing.Optional[bool]' = None - metadataForRequestor: 'typing.Optional[bytes]' = None + status: OtaSoftwareUpdateProvider.Enums.StatusEnum = 0 + delayedActionTime: typing.Optional[uint] = None + imageURI: typing.Optional[str] = None + softwareVersion: typing.Optional[uint] = None + softwareVersionString: typing.Optional[str] = None + updateToken: typing.Optional[bytes] = None + userConsentNeeded: typing.Optional[bool] = None + metadataForRequestor: typing.Optional[bytes] = None @dataclass class ApplyUpdateRequest(ClusterCommand): @@ -4359,15 +4360,15 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="newVersion", Tag=1, Type=uint), ]) - updateToken: 'bytes' = b"" - newVersion: 'uint' = 0 + updateToken: bytes = b"" + newVersion: uint = 0 @dataclass class ApplyUpdateResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000029 command_id: typing.ClassVar[int] = 0x00000003 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -4377,15 +4378,15 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="delayedActionTime", Tag=1, Type=uint), ]) - action: 'OtaSoftwareUpdateProvider.Enums.ApplyUpdateActionEnum' = 0 - delayedActionTime: 'uint' = 0 + action: OtaSoftwareUpdateProvider.Enums.ApplyUpdateActionEnum = 0 + delayedActionTime: uint = 0 @dataclass class NotifyUpdateApplied(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000029 command_id: typing.ClassVar[int] = 0x00000004 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -4395,8 +4396,8 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="softwareVersion", Tag=1, Type=uint), ]) - updateToken: 'bytes' = b"" - softwareVersion: 'uint' = 0 + updateToken: bytes = b"" + softwareVersion: uint = 0 class Attributes: @dataclass @@ -4413,7 +4414,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -4429,7 +4430,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -4445,7 +4446,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -4461,7 +4462,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -4477,7 +4478,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -4493,7 +4494,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -4516,16 +4517,16 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - defaultOTAProviders: 'typing.List[OtaSoftwareUpdateRequestor.Structs.ProviderLocation]' = None - updatePossible: 'bool' = None - updateState: 'OtaSoftwareUpdateRequestor.Enums.UpdateStateEnum' = None - updateStateProgress: 'typing.Union[Nullable, uint]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + defaultOTAProviders: typing.List[OtaSoftwareUpdateRequestor.Structs.ProviderLocation] = field(default_factory=lambda: []) + updatePossible: bool = False + updateState: OtaSoftwareUpdateRequestor.Enums.UpdateStateEnum = 0 + updateStateProgress: typing.Union[Nullable, uint] = NullValue + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class AnnouncementReasonEnum(MatterIntEnum): @@ -4588,7 +4589,7 @@ class AnnounceOTAProvider(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x0000002A command_id: typing.ClassVar[int] = 0x00000000 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -4601,11 +4602,11 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="endpoint", Tag=4, Type=uint), ]) - providerNodeID: 'uint' = 0 - vendorID: 'uint' = 0 - announcementReason: 'OtaSoftwareUpdateRequestor.Enums.AnnouncementReasonEnum' = 0 - metadataForNode: 'typing.Optional[bytes]' = None - endpoint: 'uint' = 0 + providerNodeID: uint = 0 + vendorID: uint = 0 + announcementReason: OtaSoftwareUpdateRequestor.Enums.AnnouncementReasonEnum = 0 + metadataForNode: typing.Optional[bytes] = None + endpoint: uint = 0 class Attributes: @dataclass @@ -4622,7 +4623,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[OtaSoftwareUpdateRequestor.Structs.ProviderLocation]) - value: 'typing.List[OtaSoftwareUpdateRequestor.Structs.ProviderLocation]' = field(default_factory=lambda: []) + value: typing.List[OtaSoftwareUpdateRequestor.Structs.ProviderLocation] = field(default_factory=lambda: []) @dataclass class UpdatePossible(ClusterAttributeDescriptor): @@ -4638,7 +4639,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=bool) - value: 'bool' = False + value: bool = False @dataclass class UpdateState(ClusterAttributeDescriptor): @@ -4654,7 +4655,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=OtaSoftwareUpdateRequestor.Enums.UpdateStateEnum) - value: 'OtaSoftwareUpdateRequestor.Enums.UpdateStateEnum' = 0 + value: OtaSoftwareUpdateRequestor.Enums.UpdateStateEnum = 0 @dataclass class UpdateStateProgress(ClusterAttributeDescriptor): @@ -4670,7 +4671,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, uint]) - value: 'typing.Union[Nullable, uint]' = NullValue + value: typing.Union[Nullable, uint] = NullValue @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -4686,7 +4687,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -4702,7 +4703,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -4718,7 +4719,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -4734,7 +4735,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -4750,7 +4751,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -4766,7 +4767,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 class Events: @dataclass @@ -4789,10 +4790,10 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="targetSoftwareVersion", Tag=3, Type=typing.Union[Nullable, uint]), ]) - previousState: 'OtaSoftwareUpdateRequestor.Enums.UpdateStateEnum' = 0 - newState: 'OtaSoftwareUpdateRequestor.Enums.UpdateStateEnum' = 0 - reason: 'OtaSoftwareUpdateRequestor.Enums.ChangeReasonEnum' = 0 - targetSoftwareVersion: 'typing.Union[Nullable, uint]' = NullValue + previousState: OtaSoftwareUpdateRequestor.Enums.UpdateStateEnum = 0 + newState: OtaSoftwareUpdateRequestor.Enums.UpdateStateEnum = 0 + reason: OtaSoftwareUpdateRequestor.Enums.ChangeReasonEnum = 0 + targetSoftwareVersion: typing.Union[Nullable, uint] = NullValue @dataclass class VersionApplied(ClusterEvent): @@ -4812,8 +4813,8 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="productID", Tag=1, Type=uint), ]) - softwareVersion: 'uint' = 0 - productID: 'uint' = 0 + softwareVersion: uint = 0 + productID: uint = 0 @dataclass class DownloadError(ClusterEvent): @@ -4835,10 +4836,10 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="platformCode", Tag=3, Type=typing.Union[Nullable, int]), ]) - softwareVersion: 'uint' = 0 - bytesDownloaded: 'uint' = 0 - progressPercent: 'typing.Union[Nullable, uint]' = NullValue - platformCode: 'typing.Union[Nullable, int]' = NullValue + softwareVersion: uint = 0 + bytesDownloaded: uint = 0 + progressPercent: typing.Union[Nullable, uint] = NullValue + platformCode: typing.Union[Nullable, int] = NullValue @dataclass @@ -4859,14 +4860,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - activeLocale: 'str' = None - supportedLocales: 'typing.List[str]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + activeLocale: str = "" + supportedLocales: typing.List[str] = field(default_factory=lambda: []) + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Attributes: @dataclass @@ -4883,7 +4884,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=str) - value: 'str' = "" + value: str = "" @dataclass class SupportedLocales(ClusterAttributeDescriptor): @@ -4899,7 +4900,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[str]) - value: 'typing.List[str]' = field(default_factory=lambda: []) + value: typing.List[str] = field(default_factory=lambda: []) @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -4915,7 +4916,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -4931,7 +4932,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -4947,7 +4948,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -4963,7 +4964,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -4979,7 +4980,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -4995,7 +4996,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -5017,15 +5018,15 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - hourFormat: 'TimeFormatLocalization.Enums.HourFormatEnum' = None - activeCalendarType: 'typing.Optional[TimeFormatLocalization.Enums.CalendarTypeEnum]' = None - supportedCalendarTypes: 'typing.Optional[typing.List[TimeFormatLocalization.Enums.CalendarTypeEnum]]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + hourFormat: TimeFormatLocalization.Enums.HourFormatEnum = 0 + activeCalendarType: typing.Optional[TimeFormatLocalization.Enums.CalendarTypeEnum] = None + supportedCalendarTypes: typing.Optional[typing.List[TimeFormatLocalization.Enums.CalendarTypeEnum]] = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class CalendarTypeEnum(MatterIntEnum): @@ -5077,7 +5078,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=TimeFormatLocalization.Enums.HourFormatEnum) - value: 'TimeFormatLocalization.Enums.HourFormatEnum' = 0 + value: TimeFormatLocalization.Enums.HourFormatEnum = 0 @dataclass class ActiveCalendarType(ClusterAttributeDescriptor): @@ -5093,7 +5094,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[TimeFormatLocalization.Enums.CalendarTypeEnum]) - value: 'typing.Optional[TimeFormatLocalization.Enums.CalendarTypeEnum]' = None + value: typing.Optional[TimeFormatLocalization.Enums.CalendarTypeEnum] = None @dataclass class SupportedCalendarTypes(ClusterAttributeDescriptor): @@ -5109,7 +5110,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[typing.List[TimeFormatLocalization.Enums.CalendarTypeEnum]]) - value: 'typing.Optional[typing.List[TimeFormatLocalization.Enums.CalendarTypeEnum]]' = None + value: typing.Optional[typing.List[TimeFormatLocalization.Enums.CalendarTypeEnum]] = None @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -5125,7 +5126,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -5141,7 +5142,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -5157,7 +5158,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -5173,7 +5174,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -5189,7 +5190,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -5205,7 +5206,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -5225,13 +5226,13 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - temperatureUnit: 'typing.Optional[UnitLocalization.Enums.TempUnitEnum]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + temperatureUnit: typing.Optional[UnitLocalization.Enums.TempUnitEnum] = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class TempUnitEnum(MatterIntEnum): @@ -5263,7 +5264,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[UnitLocalization.Enums.TempUnitEnum]) - value: 'typing.Optional[UnitLocalization.Enums.TempUnitEnum]' = None + value: typing.Optional[UnitLocalization.Enums.TempUnitEnum] = None @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -5279,7 +5280,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -5295,7 +5296,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -5311,7 +5312,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -5327,7 +5328,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -5343,7 +5344,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -5359,7 +5360,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -5379,13 +5380,13 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - sources: 'typing.List[uint]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + sources: typing.List[uint] = field(default_factory=lambda: []) + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Attributes: @dataclass @@ -5402,7 +5403,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -5418,7 +5419,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -5434,7 +5435,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -5450,7 +5451,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -5466,7 +5467,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -5482,7 +5483,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -5498,7 +5499,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -5549,44 +5550,44 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - status: 'PowerSource.Enums.PowerSourceStatusEnum' = None - order: 'uint' = None - description: 'str' = None - wiredAssessedInputVoltage: 'typing.Union[None, Nullable, uint]' = None - wiredAssessedInputFrequency: 'typing.Union[None, Nullable, uint]' = None - wiredCurrentType: 'typing.Optional[PowerSource.Enums.WiredCurrentTypeEnum]' = None - wiredAssessedCurrent: 'typing.Union[None, Nullable, uint]' = None - wiredNominalVoltage: 'typing.Optional[uint]' = None - wiredMaximumCurrent: 'typing.Optional[uint]' = None - wiredPresent: 'typing.Optional[bool]' = None - activeWiredFaults: 'typing.Optional[typing.List[PowerSource.Enums.WiredFaultEnum]]' = None - batVoltage: 'typing.Union[None, Nullable, uint]' = None - batPercentRemaining: 'typing.Union[None, Nullable, uint]' = None - batTimeRemaining: 'typing.Union[None, Nullable, uint]' = None - batChargeLevel: 'typing.Optional[PowerSource.Enums.BatChargeLevelEnum]' = None - batReplacementNeeded: 'typing.Optional[bool]' = None - batReplaceability: 'typing.Optional[PowerSource.Enums.BatReplaceabilityEnum]' = None - batPresent: 'typing.Optional[bool]' = None - activeBatFaults: 'typing.Optional[typing.List[PowerSource.Enums.BatFaultEnum]]' = None - batReplacementDescription: 'typing.Optional[str]' = None - batCommonDesignation: 'typing.Optional[PowerSource.Enums.BatCommonDesignationEnum]' = None - batANSIDesignation: 'typing.Optional[str]' = None - batIECDesignation: 'typing.Optional[str]' = None - batApprovedChemistry: 'typing.Optional[PowerSource.Enums.BatApprovedChemistryEnum]' = None - batCapacity: 'typing.Optional[uint]' = None - batQuantity: 'typing.Optional[uint]' = None - batChargeState: 'typing.Optional[PowerSource.Enums.BatChargeStateEnum]' = None - batTimeToFullCharge: 'typing.Union[None, Nullable, uint]' = None - batFunctionalWhileCharging: 'typing.Optional[bool]' = None - batChargingCurrent: 'typing.Union[None, Nullable, uint]' = None - activeBatChargeFaults: 'typing.Optional[typing.List[PowerSource.Enums.BatChargeFaultEnum]]' = None - endpointList: 'typing.List[uint]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + status: PowerSource.Enums.PowerSourceStatusEnum = 0 + order: uint = 0 + description: str = "" + wiredAssessedInputVoltage: typing.Union[None, Nullable, uint] = None + wiredAssessedInputFrequency: typing.Union[None, Nullable, uint] = None + wiredCurrentType: typing.Optional[PowerSource.Enums.WiredCurrentTypeEnum] = None + wiredAssessedCurrent: typing.Union[None, Nullable, uint] = None + wiredNominalVoltage: typing.Optional[uint] = None + wiredMaximumCurrent: typing.Optional[uint] = None + wiredPresent: typing.Optional[bool] = None + activeWiredFaults: typing.Optional[typing.List[PowerSource.Enums.WiredFaultEnum]] = None + batVoltage: typing.Union[None, Nullable, uint] = None + batPercentRemaining: typing.Union[None, Nullable, uint] = None + batTimeRemaining: typing.Union[None, Nullable, uint] = None + batChargeLevel: typing.Optional[PowerSource.Enums.BatChargeLevelEnum] = None + batReplacementNeeded: typing.Optional[bool] = None + batReplaceability: typing.Optional[PowerSource.Enums.BatReplaceabilityEnum] = None + batPresent: typing.Optional[bool] = None + activeBatFaults: typing.Optional[typing.List[PowerSource.Enums.BatFaultEnum]] = None + batReplacementDescription: typing.Optional[str] = None + batCommonDesignation: typing.Optional[PowerSource.Enums.BatCommonDesignationEnum] = None + batANSIDesignation: typing.Optional[str] = None + batIECDesignation: typing.Optional[str] = None + batApprovedChemistry: typing.Optional[PowerSource.Enums.BatApprovedChemistryEnum] = None + batCapacity: typing.Optional[uint] = None + batQuantity: typing.Optional[uint] = None + batChargeState: typing.Optional[PowerSource.Enums.BatChargeStateEnum] = None + batTimeToFullCharge: typing.Union[None, Nullable, uint] = None + batFunctionalWhileCharging: typing.Optional[bool] = None + batChargingCurrent: typing.Union[None, Nullable, uint] = None + activeBatChargeFaults: typing.Optional[typing.List[PowerSource.Enums.BatChargeFaultEnum]] = None + endpointList: typing.List[uint] = field(default_factory=lambda: []) + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class BatApprovedChemistryEnum(MatterIntEnum): @@ -5869,7 +5870,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=PowerSource.Enums.PowerSourceStatusEnum) - value: 'PowerSource.Enums.PowerSourceStatusEnum' = 0 + value: PowerSource.Enums.PowerSourceStatusEnum = 0 @dataclass class Order(ClusterAttributeDescriptor): @@ -5885,7 +5886,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class Description(ClusterAttributeDescriptor): @@ -5901,7 +5902,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=str) - value: 'str' = "" + value: str = "" @dataclass class WiredAssessedInputVoltage(ClusterAttributeDescriptor): @@ -5917,7 +5918,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class WiredAssessedInputFrequency(ClusterAttributeDescriptor): @@ -5933,7 +5934,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class WiredCurrentType(ClusterAttributeDescriptor): @@ -5949,7 +5950,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[PowerSource.Enums.WiredCurrentTypeEnum]) - value: 'typing.Optional[PowerSource.Enums.WiredCurrentTypeEnum]' = None + value: typing.Optional[PowerSource.Enums.WiredCurrentTypeEnum] = None @dataclass class WiredAssessedCurrent(ClusterAttributeDescriptor): @@ -5965,7 +5966,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class WiredNominalVoltage(ClusterAttributeDescriptor): @@ -5981,7 +5982,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class WiredMaximumCurrent(ClusterAttributeDescriptor): @@ -5997,7 +5998,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class WiredPresent(ClusterAttributeDescriptor): @@ -6013,7 +6014,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[bool]) - value: 'typing.Optional[bool]' = None + value: typing.Optional[bool] = None @dataclass class ActiveWiredFaults(ClusterAttributeDescriptor): @@ -6029,7 +6030,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[typing.List[PowerSource.Enums.WiredFaultEnum]]) - value: 'typing.Optional[typing.List[PowerSource.Enums.WiredFaultEnum]]' = None + value: typing.Optional[typing.List[PowerSource.Enums.WiredFaultEnum]] = None @dataclass class BatVoltage(ClusterAttributeDescriptor): @@ -6045,7 +6046,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class BatPercentRemaining(ClusterAttributeDescriptor): @@ -6061,7 +6062,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class BatTimeRemaining(ClusterAttributeDescriptor): @@ -6077,7 +6078,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class BatChargeLevel(ClusterAttributeDescriptor): @@ -6093,7 +6094,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[PowerSource.Enums.BatChargeLevelEnum]) - value: 'typing.Optional[PowerSource.Enums.BatChargeLevelEnum]' = None + value: typing.Optional[PowerSource.Enums.BatChargeLevelEnum] = None @dataclass class BatReplacementNeeded(ClusterAttributeDescriptor): @@ -6109,7 +6110,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[bool]) - value: 'typing.Optional[bool]' = None + value: typing.Optional[bool] = None @dataclass class BatReplaceability(ClusterAttributeDescriptor): @@ -6125,7 +6126,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[PowerSource.Enums.BatReplaceabilityEnum]) - value: 'typing.Optional[PowerSource.Enums.BatReplaceabilityEnum]' = None + value: typing.Optional[PowerSource.Enums.BatReplaceabilityEnum] = None @dataclass class BatPresent(ClusterAttributeDescriptor): @@ -6141,7 +6142,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[bool]) - value: 'typing.Optional[bool]' = None + value: typing.Optional[bool] = None @dataclass class ActiveBatFaults(ClusterAttributeDescriptor): @@ -6157,7 +6158,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[typing.List[PowerSource.Enums.BatFaultEnum]]) - value: 'typing.Optional[typing.List[PowerSource.Enums.BatFaultEnum]]' = None + value: typing.Optional[typing.List[PowerSource.Enums.BatFaultEnum]] = None @dataclass class BatReplacementDescription(ClusterAttributeDescriptor): @@ -6173,7 +6174,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[str]) - value: 'typing.Optional[str]' = None + value: typing.Optional[str] = None @dataclass class BatCommonDesignation(ClusterAttributeDescriptor): @@ -6189,7 +6190,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[PowerSource.Enums.BatCommonDesignationEnum]) - value: 'typing.Optional[PowerSource.Enums.BatCommonDesignationEnum]' = None + value: typing.Optional[PowerSource.Enums.BatCommonDesignationEnum] = None @dataclass class BatANSIDesignation(ClusterAttributeDescriptor): @@ -6205,7 +6206,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[str]) - value: 'typing.Optional[str]' = None + value: typing.Optional[str] = None @dataclass class BatIECDesignation(ClusterAttributeDescriptor): @@ -6221,7 +6222,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[str]) - value: 'typing.Optional[str]' = None + value: typing.Optional[str] = None @dataclass class BatApprovedChemistry(ClusterAttributeDescriptor): @@ -6237,7 +6238,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[PowerSource.Enums.BatApprovedChemistryEnum]) - value: 'typing.Optional[PowerSource.Enums.BatApprovedChemistryEnum]' = None + value: typing.Optional[PowerSource.Enums.BatApprovedChemistryEnum] = None @dataclass class BatCapacity(ClusterAttributeDescriptor): @@ -6253,7 +6254,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class BatQuantity(ClusterAttributeDescriptor): @@ -6269,7 +6270,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class BatChargeState(ClusterAttributeDescriptor): @@ -6285,7 +6286,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[PowerSource.Enums.BatChargeStateEnum]) - value: 'typing.Optional[PowerSource.Enums.BatChargeStateEnum]' = None + value: typing.Optional[PowerSource.Enums.BatChargeStateEnum] = None @dataclass class BatTimeToFullCharge(ClusterAttributeDescriptor): @@ -6301,7 +6302,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class BatFunctionalWhileCharging(ClusterAttributeDescriptor): @@ -6317,7 +6318,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[bool]) - value: 'typing.Optional[bool]' = None + value: typing.Optional[bool] = None @dataclass class BatChargingCurrent(ClusterAttributeDescriptor): @@ -6333,7 +6334,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class ActiveBatChargeFaults(ClusterAttributeDescriptor): @@ -6349,7 +6350,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[typing.List[PowerSource.Enums.BatChargeFaultEnum]]) - value: 'typing.Optional[typing.List[PowerSource.Enums.BatChargeFaultEnum]]' = None + value: typing.Optional[typing.List[PowerSource.Enums.BatChargeFaultEnum]] = None @dataclass class EndpointList(ClusterAttributeDescriptor): @@ -6365,7 +6366,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -6381,7 +6382,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -6397,7 +6398,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -6413,7 +6414,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -6429,7 +6430,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -6445,7 +6446,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -6461,7 +6462,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 class Events: @dataclass @@ -6482,8 +6483,8 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="previous", Tag=1, Type=typing.List[PowerSource.Enums.WiredFaultEnum]), ]) - current: 'typing.List[PowerSource.Enums.WiredFaultEnum]' = field(default_factory=lambda: []) - previous: 'typing.List[PowerSource.Enums.WiredFaultEnum]' = field(default_factory=lambda: []) + current: typing.List[PowerSource.Enums.WiredFaultEnum] = field(default_factory=lambda: []) + previous: typing.List[PowerSource.Enums.WiredFaultEnum] = field(default_factory=lambda: []) @dataclass class BatFaultChange(ClusterEvent): @@ -6503,8 +6504,8 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="previous", Tag=1, Type=typing.List[PowerSource.Enums.BatFaultEnum]), ]) - current: 'typing.List[PowerSource.Enums.BatFaultEnum]' = field(default_factory=lambda: []) - previous: 'typing.List[PowerSource.Enums.BatFaultEnum]' = field(default_factory=lambda: []) + current: typing.List[PowerSource.Enums.BatFaultEnum] = field(default_factory=lambda: []) + previous: typing.List[PowerSource.Enums.BatFaultEnum] = field(default_factory=lambda: []) @dataclass class BatChargeFaultChange(ClusterEvent): @@ -6524,8 +6525,8 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="previous", Tag=1, Type=typing.List[PowerSource.Enums.BatChargeFaultEnum]), ]) - current: 'typing.List[PowerSource.Enums.BatChargeFaultEnum]' = field(default_factory=lambda: []) - previous: 'typing.List[PowerSource.Enums.BatChargeFaultEnum]' = field(default_factory=lambda: []) + current: typing.List[PowerSource.Enums.BatChargeFaultEnum] = field(default_factory=lambda: []) + previous: typing.List[PowerSource.Enums.BatChargeFaultEnum] = field(default_factory=lambda: []) @dataclass @@ -6554,22 +6555,22 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - breadcrumb: 'uint' = None - basicCommissioningInfo: 'GeneralCommissioning.Structs.BasicCommissioningInfo' = None - regulatoryConfig: 'GeneralCommissioning.Enums.RegulatoryLocationTypeEnum' = None - locationCapability: 'GeneralCommissioning.Enums.RegulatoryLocationTypeEnum' = None - supportsConcurrentConnection: 'bool' = None - TCAcceptedVersion: 'typing.Optional[uint]' = None - TCMinRequiredVersion: 'typing.Optional[uint]' = None - TCAcknowledgements: 'typing.Optional[uint]' = None - TCAcknowledgementsRequired: 'typing.Optional[bool]' = None - TCUpdateDeadline: 'typing.Optional[uint]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + breadcrumb: uint = 0 + basicCommissioningInfo: GeneralCommissioning.Structs.BasicCommissioningInfo = field(default_factory=lambda: GeneralCommissioning.Structs.BasicCommissioningInfo()) + regulatoryConfig: GeneralCommissioning.Enums.RegulatoryLocationTypeEnum = 0 + locationCapability: GeneralCommissioning.Enums.RegulatoryLocationTypeEnum = 0 + supportsConcurrentConnection: bool = False + TCAcceptedVersion: typing.Optional[uint] = None + TCMinRequiredVersion: typing.Optional[uint] = None + TCAcknowledgements: typing.Optional[uint] = None + TCAcknowledgementsRequired: typing.Optional[bool] = None + TCUpdateDeadline: typing.Optional[uint] = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class CommissioningErrorEnum(MatterIntEnum): @@ -6631,15 +6632,15 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="breadcrumb", Tag=1, Type=uint), ]) - expiryLengthSeconds: 'uint' = 0 - breadcrumb: 'uint' = 0 + expiryLengthSeconds: uint = 0 + breadcrumb: uint = 0 @dataclass class ArmFailSafeResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000030 command_id: typing.ClassVar[int] = 0x00000001 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -6649,8 +6650,8 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="debugText", Tag=1, Type=str), ]) - errorCode: 'GeneralCommissioning.Enums.CommissioningErrorEnum' = 0 - debugText: 'str' = "" + errorCode: GeneralCommissioning.Enums.CommissioningErrorEnum = 0 + debugText: str = "" @dataclass class SetRegulatoryConfig(ClusterCommand): @@ -6668,16 +6669,16 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="breadcrumb", Tag=2, Type=uint), ]) - newRegulatoryConfig: 'GeneralCommissioning.Enums.RegulatoryLocationTypeEnum' = 0 - countryCode: 'str' = "" - breadcrumb: 'uint' = 0 + newRegulatoryConfig: GeneralCommissioning.Enums.RegulatoryLocationTypeEnum = 0 + countryCode: str = "" + breadcrumb: uint = 0 @dataclass class SetRegulatoryConfigResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000030 command_id: typing.ClassVar[int] = 0x00000003 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -6687,8 +6688,8 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="debugText", Tag=1, Type=str), ]) - errorCode: 'GeneralCommissioning.Enums.CommissioningErrorEnum' = 0 - debugText: 'str' = "" + errorCode: GeneralCommissioning.Enums.CommissioningErrorEnum = 0 + debugText: str = "" @dataclass class CommissioningComplete(ClusterCommand): @@ -6708,7 +6709,7 @@ class CommissioningCompleteResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000030 command_id: typing.ClassVar[int] = 0x00000005 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -6718,8 +6719,8 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="debugText", Tag=1, Type=str), ]) - errorCode: 'GeneralCommissioning.Enums.CommissioningErrorEnum' = 0 - debugText: 'str' = "" + errorCode: GeneralCommissioning.Enums.CommissioningErrorEnum = 0 + debugText: str = "" @dataclass class SetTCAcknowledgements(ClusterCommand): @@ -6736,15 +6737,15 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="TCUserResponse", Tag=1, Type=uint), ]) - TCVersion: 'uint' = 0 - TCUserResponse: 'uint' = 0 + TCVersion: uint = 0 + TCUserResponse: uint = 0 @dataclass class SetTCAcknowledgementsResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000030 command_id: typing.ClassVar[int] = 0x00000007 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -6753,7 +6754,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="errorCode", Tag=0, Type=GeneralCommissioning.Enums.CommissioningErrorEnum), ]) - errorCode: 'GeneralCommissioning.Enums.CommissioningErrorEnum' = 0 + errorCode: GeneralCommissioning.Enums.CommissioningErrorEnum = 0 class Attributes: @dataclass @@ -6770,7 +6771,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class BasicCommissioningInfo(ClusterAttributeDescriptor): @@ -6786,7 +6787,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=GeneralCommissioning.Structs.BasicCommissioningInfo) - value: 'GeneralCommissioning.Structs.BasicCommissioningInfo' = field(default_factory=lambda: GeneralCommissioning.Structs.BasicCommissioningInfo()) + value: GeneralCommissioning.Structs.BasicCommissioningInfo = field(default_factory=lambda: GeneralCommissioning.Structs.BasicCommissioningInfo()) @dataclass class RegulatoryConfig(ClusterAttributeDescriptor): @@ -6802,7 +6803,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=GeneralCommissioning.Enums.RegulatoryLocationTypeEnum) - value: 'GeneralCommissioning.Enums.RegulatoryLocationTypeEnum' = 0 + value: GeneralCommissioning.Enums.RegulatoryLocationTypeEnum = 0 @dataclass class LocationCapability(ClusterAttributeDescriptor): @@ -6818,7 +6819,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=GeneralCommissioning.Enums.RegulatoryLocationTypeEnum) - value: 'GeneralCommissioning.Enums.RegulatoryLocationTypeEnum' = 0 + value: GeneralCommissioning.Enums.RegulatoryLocationTypeEnum = 0 @dataclass class SupportsConcurrentConnection(ClusterAttributeDescriptor): @@ -6834,7 +6835,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=bool) - value: 'bool' = False + value: bool = False @dataclass class TCAcceptedVersion(ClusterAttributeDescriptor): @@ -6850,7 +6851,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class TCMinRequiredVersion(ClusterAttributeDescriptor): @@ -6866,7 +6867,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class TCAcknowledgements(ClusterAttributeDescriptor): @@ -6882,7 +6883,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class TCAcknowledgementsRequired(ClusterAttributeDescriptor): @@ -6898,7 +6899,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[bool]) - value: 'typing.Optional[bool]' = None + value: typing.Optional[bool] = None @dataclass class TCUpdateDeadline(ClusterAttributeDescriptor): @@ -6914,7 +6915,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -6930,7 +6931,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -6946,7 +6947,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -6962,7 +6963,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -6978,7 +6979,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -6994,7 +6995,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -7010,7 +7011,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -7040,23 +7041,23 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - maxNetworks: 'uint' = None - networks: 'typing.List[NetworkCommissioning.Structs.NetworkInfoStruct]' = None - scanMaxTimeSeconds: 'typing.Optional[uint]' = None - connectMaxTimeSeconds: 'typing.Optional[uint]' = None - interfaceEnabled: 'bool' = None - lastNetworkingStatus: 'typing.Union[Nullable, NetworkCommissioning.Enums.NetworkCommissioningStatusEnum]' = None - lastNetworkID: 'typing.Union[Nullable, bytes]' = None - lastConnectErrorValue: 'typing.Union[Nullable, int]' = None - supportedWiFiBands: 'typing.Optional[typing.List[NetworkCommissioning.Enums.WiFiBandEnum]]' = None - supportedThreadFeatures: 'typing.Optional[uint]' = None - threadVersion: 'typing.Optional[uint]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + maxNetworks: uint = 0 + networks: typing.List[NetworkCommissioning.Structs.NetworkInfoStruct] = field(default_factory=lambda: []) + scanMaxTimeSeconds: typing.Optional[uint] = None + connectMaxTimeSeconds: typing.Optional[uint] = None + interfaceEnabled: bool = False + lastNetworkingStatus: typing.Union[Nullable, NetworkCommissioning.Enums.NetworkCommissioningStatusEnum] = NullValue + lastNetworkID: typing.Union[Nullable, bytes] = NullValue + lastConnectErrorValue: typing.Union[Nullable, int] = NullValue + supportedWiFiBands: typing.Optional[typing.List[NetworkCommissioning.Enums.WiFiBandEnum]] = None + supportedThreadFeatures: typing.Optional[uint] = None + threadVersion: typing.Optional[uint] = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class NetworkCommissioningStatusEnum(MatterIntEnum): @@ -7194,15 +7195,15 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="breadcrumb", Tag=1, Type=typing.Optional[uint]), ]) - ssid: 'typing.Union[None, Nullable, bytes]' = None - breadcrumb: 'typing.Optional[uint]' = None + ssid: typing.Union[None, Nullable, bytes] = None + breadcrumb: typing.Optional[uint] = None @dataclass class ScanNetworksResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000031 command_id: typing.ClassVar[int] = 0x00000001 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -7214,10 +7215,10 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="threadScanResults", Tag=3, Type=typing.Optional[typing.List[NetworkCommissioning.Structs.ThreadInterfaceScanResultStruct]]), ]) - networkingStatus: 'NetworkCommissioning.Enums.NetworkCommissioningStatusEnum' = 0 - debugText: 'typing.Optional[str]' = None - wiFiScanResults: 'typing.Optional[typing.List[NetworkCommissioning.Structs.WiFiInterfaceScanResultStruct]]' = None - threadScanResults: 'typing.Optional[typing.List[NetworkCommissioning.Structs.ThreadInterfaceScanResultStruct]]' = None + networkingStatus: NetworkCommissioning.Enums.NetworkCommissioningStatusEnum = 0 + debugText: typing.Optional[str] = None + wiFiScanResults: typing.Optional[typing.List[NetworkCommissioning.Structs.WiFiInterfaceScanResultStruct]] = None + threadScanResults: typing.Optional[typing.List[NetworkCommissioning.Structs.ThreadInterfaceScanResultStruct]] = None @dataclass class AddOrUpdateWiFiNetwork(ClusterCommand): @@ -7238,12 +7239,12 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="possessionNonce", Tag=5, Type=typing.Optional[bytes]), ]) - ssid: 'bytes' = b"" - credentials: 'bytes' = b"" - breadcrumb: 'typing.Optional[uint]' = None - networkIdentity: 'typing.Optional[bytes]' = None - clientIdentifier: 'typing.Optional[bytes]' = None - possessionNonce: 'typing.Optional[bytes]' = None + ssid: bytes = b"" + credentials: bytes = b"" + breadcrumb: typing.Optional[uint] = None + networkIdentity: typing.Optional[bytes] = None + clientIdentifier: typing.Optional[bytes] = None + possessionNonce: typing.Optional[bytes] = None @dataclass class AddOrUpdateThreadNetwork(ClusterCommand): @@ -7260,8 +7261,8 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="breadcrumb", Tag=1, Type=typing.Optional[uint]), ]) - operationalDataset: 'bytes' = b"" - breadcrumb: 'typing.Optional[uint]' = None + operationalDataset: bytes = b"" + breadcrumb: typing.Optional[uint] = None @dataclass class RemoveNetwork(ClusterCommand): @@ -7278,15 +7279,15 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="breadcrumb", Tag=1, Type=typing.Optional[uint]), ]) - networkID: 'bytes' = b"" - breadcrumb: 'typing.Optional[uint]' = None + networkID: bytes = b"" + breadcrumb: typing.Optional[uint] = None @dataclass class NetworkConfigResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000031 command_id: typing.ClassVar[int] = 0x00000005 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -7299,11 +7300,11 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="possessionSignature", Tag=4, Type=typing.Optional[bytes]), ]) - networkingStatus: 'NetworkCommissioning.Enums.NetworkCommissioningStatusEnum' = 0 - debugText: 'typing.Optional[str]' = None - networkIndex: 'typing.Optional[uint]' = None - clientIdentity: 'typing.Optional[bytes]' = None - possessionSignature: 'typing.Optional[bytes]' = None + networkingStatus: NetworkCommissioning.Enums.NetworkCommissioningStatusEnum = 0 + debugText: typing.Optional[str] = None + networkIndex: typing.Optional[uint] = None + clientIdentity: typing.Optional[bytes] = None + possessionSignature: typing.Optional[bytes] = None @dataclass class ConnectNetwork(ClusterCommand): @@ -7320,15 +7321,15 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="breadcrumb", Tag=1, Type=typing.Optional[uint]), ]) - networkID: 'bytes' = b"" - breadcrumb: 'typing.Optional[uint]' = None + networkID: bytes = b"" + breadcrumb: typing.Optional[uint] = None @dataclass class ConnectNetworkResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000031 command_id: typing.ClassVar[int] = 0x00000007 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -7339,9 +7340,9 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="errorValue", Tag=2, Type=typing.Union[Nullable, int]), ]) - networkingStatus: 'NetworkCommissioning.Enums.NetworkCommissioningStatusEnum' = 0 - debugText: 'typing.Optional[str]' = None - errorValue: 'typing.Union[Nullable, int]' = NullValue + networkingStatus: NetworkCommissioning.Enums.NetworkCommissioningStatusEnum = 0 + debugText: typing.Optional[str] = None + errorValue: typing.Union[Nullable, int] = NullValue @dataclass class ReorderNetwork(ClusterCommand): @@ -7359,9 +7360,9 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="breadcrumb", Tag=2, Type=typing.Optional[uint]), ]) - networkID: 'bytes' = b"" - networkIndex: 'uint' = 0 - breadcrumb: 'typing.Optional[uint]' = None + networkID: bytes = b"" + networkIndex: uint = 0 + breadcrumb: typing.Optional[uint] = None @dataclass class QueryIdentity(ClusterCommand): @@ -7378,15 +7379,15 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="possessionNonce", Tag=1, Type=typing.Optional[bytes]), ]) - keyIdentifier: 'bytes' = b"" - possessionNonce: 'typing.Optional[bytes]' = None + keyIdentifier: bytes = b"" + possessionNonce: typing.Optional[bytes] = None @dataclass class QueryIdentityResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000031 command_id: typing.ClassVar[int] = 0x0000000A is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -7396,8 +7397,8 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="possessionSignature", Tag=1, Type=typing.Optional[bytes]), ]) - identity: 'bytes' = b"" - possessionSignature: 'typing.Optional[bytes]' = None + identity: bytes = b"" + possessionSignature: typing.Optional[bytes] = None class Attributes: @dataclass @@ -7414,7 +7415,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class Networks(ClusterAttributeDescriptor): @@ -7430,7 +7431,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[NetworkCommissioning.Structs.NetworkInfoStruct]) - value: 'typing.List[NetworkCommissioning.Structs.NetworkInfoStruct]' = field(default_factory=lambda: []) + value: typing.List[NetworkCommissioning.Structs.NetworkInfoStruct] = field(default_factory=lambda: []) @dataclass class ScanMaxTimeSeconds(ClusterAttributeDescriptor): @@ -7446,7 +7447,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class ConnectMaxTimeSeconds(ClusterAttributeDescriptor): @@ -7462,7 +7463,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class InterfaceEnabled(ClusterAttributeDescriptor): @@ -7478,7 +7479,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=bool) - value: 'bool' = False + value: bool = False @dataclass class LastNetworkingStatus(ClusterAttributeDescriptor): @@ -7494,7 +7495,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, NetworkCommissioning.Enums.NetworkCommissioningStatusEnum]) - value: 'typing.Union[Nullable, NetworkCommissioning.Enums.NetworkCommissioningStatusEnum]' = NullValue + value: typing.Union[Nullable, NetworkCommissioning.Enums.NetworkCommissioningStatusEnum] = NullValue @dataclass class LastNetworkID(ClusterAttributeDescriptor): @@ -7510,7 +7511,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, bytes]) - value: 'typing.Union[Nullable, bytes]' = NullValue + value: typing.Union[Nullable, bytes] = NullValue @dataclass class LastConnectErrorValue(ClusterAttributeDescriptor): @@ -7526,7 +7527,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, int]) - value: 'typing.Union[Nullable, int]' = NullValue + value: typing.Union[Nullable, int] = NullValue @dataclass class SupportedWiFiBands(ClusterAttributeDescriptor): @@ -7542,7 +7543,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[typing.List[NetworkCommissioning.Enums.WiFiBandEnum]]) - value: 'typing.Optional[typing.List[NetworkCommissioning.Enums.WiFiBandEnum]]' = None + value: typing.Optional[typing.List[NetworkCommissioning.Enums.WiFiBandEnum]] = None @dataclass class SupportedThreadFeatures(ClusterAttributeDescriptor): @@ -7558,7 +7559,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class ThreadVersion(ClusterAttributeDescriptor): @@ -7574,7 +7575,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -7590,7 +7591,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -7606,7 +7607,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -7622,7 +7623,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -7638,7 +7639,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -7654,7 +7655,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -7670,7 +7671,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -7689,12 +7690,12 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class IntentEnum(MatterIntEnum): @@ -7745,16 +7746,16 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="transferFileDesignator", Tag=2, Type=typing.Optional[str]), ]) - intent: 'DiagnosticLogs.Enums.IntentEnum' = 0 - requestedProtocol: 'DiagnosticLogs.Enums.TransferProtocolEnum' = 0 - transferFileDesignator: 'typing.Optional[str]' = None + intent: DiagnosticLogs.Enums.IntentEnum = 0 + requestedProtocol: DiagnosticLogs.Enums.TransferProtocolEnum = 0 + transferFileDesignator: typing.Optional[str] = None @dataclass class RetrieveLogsResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000032 command_id: typing.ClassVar[int] = 0x00000001 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -7766,10 +7767,10 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="timeSinceBoot", Tag=3, Type=typing.Optional[uint]), ]) - status: 'DiagnosticLogs.Enums.StatusEnum' = 0 - logContent: 'bytes' = b"" - UTCTimeStamp: 'typing.Optional[uint]' = None - timeSinceBoot: 'typing.Optional[uint]' = None + status: DiagnosticLogs.Enums.StatusEnum = 0 + logContent: bytes = b"" + UTCTimeStamp: typing.Optional[uint] = None + timeSinceBoot: typing.Optional[uint] = None class Attributes: @dataclass @@ -7786,7 +7787,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -7802,7 +7803,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -7818,7 +7819,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -7834,7 +7835,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -7850,7 +7851,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -7866,7 +7867,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -7894,21 +7895,21 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - networkInterfaces: 'typing.List[GeneralDiagnostics.Structs.NetworkInterface]' = None - rebootCount: 'uint' = None - upTime: 'typing.Optional[uint]' = None - totalOperationalHours: 'typing.Optional[uint]' = None - bootReason: 'typing.Optional[GeneralDiagnostics.Enums.BootReasonEnum]' = None - activeHardwareFaults: 'typing.Optional[typing.List[GeneralDiagnostics.Enums.HardwareFaultEnum]]' = None - activeRadioFaults: 'typing.Optional[typing.List[GeneralDiagnostics.Enums.RadioFaultEnum]]' = None - activeNetworkFaults: 'typing.Optional[typing.List[GeneralDiagnostics.Enums.NetworkFaultEnum]]' = None - testEventTriggersEnabled: 'bool' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + networkInterfaces: typing.List[GeneralDiagnostics.Structs.NetworkInterface] = field(default_factory=lambda: []) + rebootCount: uint = 0 + upTime: typing.Optional[uint] = None + totalOperationalHours: typing.Optional[uint] = None + bootReason: typing.Optional[GeneralDiagnostics.Enums.BootReasonEnum] = None + activeHardwareFaults: typing.Optional[typing.List[GeneralDiagnostics.Enums.HardwareFaultEnum]] = None + activeRadioFaults: typing.Optional[typing.List[GeneralDiagnostics.Enums.RadioFaultEnum]] = None + activeNetworkFaults: typing.Optional[typing.List[GeneralDiagnostics.Enums.NetworkFaultEnum]] = None + testEventTriggersEnabled: bool = False + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class BootReasonEnum(MatterIntEnum): @@ -8016,7 +8017,7 @@ class TestEventTrigger(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000033 command_id: typing.ClassVar[int] = 0x00000000 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -8026,8 +8027,8 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="eventTrigger", Tag=1, Type=uint), ]) - enableKey: 'bytes' = b"" - eventTrigger: 'uint' = 0 + enableKey: bytes = b"" + eventTrigger: uint = 0 @dataclass class TimeSnapshot(ClusterCommand): @@ -8047,7 +8048,7 @@ class TimeSnapshotResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000033 command_id: typing.ClassVar[int] = 0x00000002 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -8057,8 +8058,8 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="posixTimeMs", Tag=1, Type=typing.Union[Nullable, uint]), ]) - systemTimeMs: 'uint' = 0 - posixTimeMs: 'typing.Union[Nullable, uint]' = NullValue + systemTimeMs: uint = 0 + posixTimeMs: typing.Union[Nullable, uint] = NullValue @dataclass class PayloadTestRequest(ClusterCommand): @@ -8076,16 +8077,16 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="count", Tag=2, Type=uint), ]) - enableKey: 'bytes' = b"" - value: 'uint' = 0 - count: 'uint' = 0 + enableKey: bytes = b"" + value: uint = 0 + count: uint = 0 @dataclass class PayloadTestResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000033 command_id: typing.ClassVar[int] = 0x00000004 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -8094,7 +8095,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="payload", Tag=0, Type=bytes), ]) - payload: 'bytes' = b"" + payload: bytes = b"" class Attributes: @dataclass @@ -8111,7 +8112,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[GeneralDiagnostics.Structs.NetworkInterface]) - value: 'typing.List[GeneralDiagnostics.Structs.NetworkInterface]' = field(default_factory=lambda: []) + value: typing.List[GeneralDiagnostics.Structs.NetworkInterface] = field(default_factory=lambda: []) @dataclass class RebootCount(ClusterAttributeDescriptor): @@ -8127,7 +8128,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class UpTime(ClusterAttributeDescriptor): @@ -8143,7 +8144,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class TotalOperationalHours(ClusterAttributeDescriptor): @@ -8159,7 +8160,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class BootReason(ClusterAttributeDescriptor): @@ -8175,7 +8176,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[GeneralDiagnostics.Enums.BootReasonEnum]) - value: 'typing.Optional[GeneralDiagnostics.Enums.BootReasonEnum]' = None + value: typing.Optional[GeneralDiagnostics.Enums.BootReasonEnum] = None @dataclass class ActiveHardwareFaults(ClusterAttributeDescriptor): @@ -8191,7 +8192,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[typing.List[GeneralDiagnostics.Enums.HardwareFaultEnum]]) - value: 'typing.Optional[typing.List[GeneralDiagnostics.Enums.HardwareFaultEnum]]' = None + value: typing.Optional[typing.List[GeneralDiagnostics.Enums.HardwareFaultEnum]] = None @dataclass class ActiveRadioFaults(ClusterAttributeDescriptor): @@ -8207,7 +8208,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[typing.List[GeneralDiagnostics.Enums.RadioFaultEnum]]) - value: 'typing.Optional[typing.List[GeneralDiagnostics.Enums.RadioFaultEnum]]' = None + value: typing.Optional[typing.List[GeneralDiagnostics.Enums.RadioFaultEnum]] = None @dataclass class ActiveNetworkFaults(ClusterAttributeDescriptor): @@ -8223,7 +8224,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[typing.List[GeneralDiagnostics.Enums.NetworkFaultEnum]]) - value: 'typing.Optional[typing.List[GeneralDiagnostics.Enums.NetworkFaultEnum]]' = None + value: typing.Optional[typing.List[GeneralDiagnostics.Enums.NetworkFaultEnum]] = None @dataclass class TestEventTriggersEnabled(ClusterAttributeDescriptor): @@ -8239,7 +8240,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=bool) - value: 'bool' = False + value: bool = False @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -8255,7 +8256,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -8271,7 +8272,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -8287,7 +8288,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -8303,7 +8304,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -8319,7 +8320,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -8335,7 +8336,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 class Events: @dataclass @@ -8356,8 +8357,8 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="previous", Tag=1, Type=typing.List[GeneralDiagnostics.Enums.HardwareFaultEnum]), ]) - current: 'typing.List[GeneralDiagnostics.Enums.HardwareFaultEnum]' = field(default_factory=lambda: []) - previous: 'typing.List[GeneralDiagnostics.Enums.HardwareFaultEnum]' = field(default_factory=lambda: []) + current: typing.List[GeneralDiagnostics.Enums.HardwareFaultEnum] = field(default_factory=lambda: []) + previous: typing.List[GeneralDiagnostics.Enums.HardwareFaultEnum] = field(default_factory=lambda: []) @dataclass class RadioFaultChange(ClusterEvent): @@ -8377,8 +8378,8 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="previous", Tag=1, Type=typing.List[GeneralDiagnostics.Enums.RadioFaultEnum]), ]) - current: 'typing.List[GeneralDiagnostics.Enums.RadioFaultEnum]' = field(default_factory=lambda: []) - previous: 'typing.List[GeneralDiagnostics.Enums.RadioFaultEnum]' = field(default_factory=lambda: []) + current: typing.List[GeneralDiagnostics.Enums.RadioFaultEnum] = field(default_factory=lambda: []) + previous: typing.List[GeneralDiagnostics.Enums.RadioFaultEnum] = field(default_factory=lambda: []) @dataclass class NetworkFaultChange(ClusterEvent): @@ -8398,8 +8399,8 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="previous", Tag=1, Type=typing.List[GeneralDiagnostics.Enums.NetworkFaultEnum]), ]) - current: 'typing.List[GeneralDiagnostics.Enums.NetworkFaultEnum]' = field(default_factory=lambda: []) - previous: 'typing.List[GeneralDiagnostics.Enums.NetworkFaultEnum]' = field(default_factory=lambda: []) + current: typing.List[GeneralDiagnostics.Enums.NetworkFaultEnum] = field(default_factory=lambda: []) + previous: typing.List[GeneralDiagnostics.Enums.NetworkFaultEnum] = field(default_factory=lambda: []) @dataclass class BootReason(ClusterEvent): @@ -8418,7 +8419,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="bootReason", Tag=0, Type=GeneralDiagnostics.Enums.BootReasonEnum), ]) - bootReason: 'GeneralDiagnostics.Enums.BootReasonEnum' = 0 + bootReason: GeneralDiagnostics.Enums.BootReasonEnum = 0 @dataclass @@ -8441,16 +8442,16 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - threadMetrics: 'typing.Optional[typing.List[SoftwareDiagnostics.Structs.ThreadMetricsStruct]]' = None - currentHeapFree: 'typing.Optional[uint]' = None - currentHeapUsed: 'typing.Optional[uint]' = None - currentHeapHighWatermark: 'typing.Optional[uint]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + threadMetrics: typing.Optional[typing.List[SoftwareDiagnostics.Structs.ThreadMetricsStruct]] = None + currentHeapFree: typing.Optional[uint] = None + currentHeapUsed: typing.Optional[uint] = None + currentHeapHighWatermark: typing.Optional[uint] = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Bitmaps: class Feature(IntFlag): @@ -8482,7 +8483,7 @@ class ResetWatermarks(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000034 command_id: typing.ClassVar[int] = 0x00000000 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -8505,7 +8506,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[typing.List[SoftwareDiagnostics.Structs.ThreadMetricsStruct]]) - value: 'typing.Optional[typing.List[SoftwareDiagnostics.Structs.ThreadMetricsStruct]]' = None + value: typing.Optional[typing.List[SoftwareDiagnostics.Structs.ThreadMetricsStruct]] = None @dataclass class CurrentHeapFree(ClusterAttributeDescriptor): @@ -8521,7 +8522,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class CurrentHeapUsed(ClusterAttributeDescriptor): @@ -8537,7 +8538,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class CurrentHeapHighWatermark(ClusterAttributeDescriptor): @@ -8553,7 +8554,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -8569,7 +8570,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -8585,7 +8586,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -8601,7 +8602,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -8617,7 +8618,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -8633,7 +8634,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -8649,7 +8650,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 class Events: @dataclass @@ -8671,9 +8672,9 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="faultRecording", Tag=2, Type=typing.Optional[bytes]), ]) - id: 'uint' = 0 - name: 'typing.Optional[str]' = None - faultRecording: 'typing.Optional[bytes]' = None + id: uint = 0 + name: typing.Optional[str] = None + faultRecording: typing.Optional[bytes] = None @dataclass @@ -8755,75 +8756,75 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - channel: 'typing.Union[Nullable, uint]' = None - routingRole: 'typing.Union[Nullable, ThreadNetworkDiagnostics.Enums.RoutingRoleEnum]' = None - networkName: 'typing.Union[Nullable, str]' = None - panId: 'typing.Union[Nullable, uint]' = None - extendedPanId: 'typing.Union[Nullable, uint]' = None - meshLocalPrefix: 'typing.Union[Nullable, bytes]' = None - overrunCount: 'typing.Optional[uint]' = None - neighborTable: 'typing.List[ThreadNetworkDiagnostics.Structs.NeighborTableStruct]' = None - routeTable: 'typing.List[ThreadNetworkDiagnostics.Structs.RouteTableStruct]' = None - partitionId: 'typing.Union[Nullable, uint]' = None - weighting: 'typing.Union[Nullable, uint]' = None - dataVersion: 'typing.Union[Nullable, uint]' = None - stableDataVersion: 'typing.Union[Nullable, uint]' = None - leaderRouterId: 'typing.Union[Nullable, uint]' = None - detachedRoleCount: 'typing.Optional[uint]' = None - childRoleCount: 'typing.Optional[uint]' = None - routerRoleCount: 'typing.Optional[uint]' = None - leaderRoleCount: 'typing.Optional[uint]' = None - attachAttemptCount: 'typing.Optional[uint]' = None - partitionIdChangeCount: 'typing.Optional[uint]' = None - betterPartitionAttachAttemptCount: 'typing.Optional[uint]' = None - parentChangeCount: 'typing.Optional[uint]' = None - txTotalCount: 'typing.Optional[uint]' = None - txUnicastCount: 'typing.Optional[uint]' = None - txBroadcastCount: 'typing.Optional[uint]' = None - txAckRequestedCount: 'typing.Optional[uint]' = None - txAckedCount: 'typing.Optional[uint]' = None - txNoAckRequestedCount: 'typing.Optional[uint]' = None - txDataCount: 'typing.Optional[uint]' = None - txDataPollCount: 'typing.Optional[uint]' = None - txBeaconCount: 'typing.Optional[uint]' = None - txBeaconRequestCount: 'typing.Optional[uint]' = None - txOtherCount: 'typing.Optional[uint]' = None - txRetryCount: 'typing.Optional[uint]' = None - txDirectMaxRetryExpiryCount: 'typing.Optional[uint]' = None - txIndirectMaxRetryExpiryCount: 'typing.Optional[uint]' = None - txErrCcaCount: 'typing.Optional[uint]' = None - txErrAbortCount: 'typing.Optional[uint]' = None - txErrBusyChannelCount: 'typing.Optional[uint]' = None - rxTotalCount: 'typing.Optional[uint]' = None - rxUnicastCount: 'typing.Optional[uint]' = None - rxBroadcastCount: 'typing.Optional[uint]' = None - rxDataCount: 'typing.Optional[uint]' = None - rxDataPollCount: 'typing.Optional[uint]' = None - rxBeaconCount: 'typing.Optional[uint]' = None - rxBeaconRequestCount: 'typing.Optional[uint]' = None - rxOtherCount: 'typing.Optional[uint]' = None - rxAddressFilteredCount: 'typing.Optional[uint]' = None - rxDestAddrFilteredCount: 'typing.Optional[uint]' = None - rxDuplicatedCount: 'typing.Optional[uint]' = None - rxErrNoFrameCount: 'typing.Optional[uint]' = None - rxErrUnknownNeighborCount: 'typing.Optional[uint]' = None - rxErrInvalidSrcAddrCount: 'typing.Optional[uint]' = None - rxErrSecCount: 'typing.Optional[uint]' = None - rxErrFcsCount: 'typing.Optional[uint]' = None - rxErrOtherCount: 'typing.Optional[uint]' = None - activeTimestamp: 'typing.Union[None, Nullable, uint]' = None - pendingTimestamp: 'typing.Union[None, Nullable, uint]' = None - delay: 'typing.Union[None, Nullable, uint]' = None - securityPolicy: 'typing.Union[Nullable, ThreadNetworkDiagnostics.Structs.SecurityPolicy]' = None - channelPage0Mask: 'typing.Union[Nullable, bytes]' = None - operationalDatasetComponents: 'typing.Union[Nullable, ThreadNetworkDiagnostics.Structs.OperationalDatasetComponents]' = None - activeNetworkFaultsList: 'typing.List[ThreadNetworkDiagnostics.Enums.NetworkFaultEnum]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + channel: typing.Union[Nullable, uint] = NullValue + routingRole: typing.Union[Nullable, ThreadNetworkDiagnostics.Enums.RoutingRoleEnum] = NullValue + networkName: typing.Union[Nullable, str] = NullValue + panId: typing.Union[Nullable, uint] = NullValue + extendedPanId: typing.Union[Nullable, uint] = NullValue + meshLocalPrefix: typing.Union[Nullable, bytes] = NullValue + overrunCount: typing.Optional[uint] = None + neighborTable: typing.List[ThreadNetworkDiagnostics.Structs.NeighborTableStruct] = field(default_factory=lambda: []) + routeTable: typing.List[ThreadNetworkDiagnostics.Structs.RouteTableStruct] = field(default_factory=lambda: []) + partitionId: typing.Union[Nullable, uint] = NullValue + weighting: typing.Union[Nullable, uint] = NullValue + dataVersion: typing.Union[Nullable, uint] = NullValue + stableDataVersion: typing.Union[Nullable, uint] = NullValue + leaderRouterId: typing.Union[Nullable, uint] = NullValue + detachedRoleCount: typing.Optional[uint] = None + childRoleCount: typing.Optional[uint] = None + routerRoleCount: typing.Optional[uint] = None + leaderRoleCount: typing.Optional[uint] = None + attachAttemptCount: typing.Optional[uint] = None + partitionIdChangeCount: typing.Optional[uint] = None + betterPartitionAttachAttemptCount: typing.Optional[uint] = None + parentChangeCount: typing.Optional[uint] = None + txTotalCount: typing.Optional[uint] = None + txUnicastCount: typing.Optional[uint] = None + txBroadcastCount: typing.Optional[uint] = None + txAckRequestedCount: typing.Optional[uint] = None + txAckedCount: typing.Optional[uint] = None + txNoAckRequestedCount: typing.Optional[uint] = None + txDataCount: typing.Optional[uint] = None + txDataPollCount: typing.Optional[uint] = None + txBeaconCount: typing.Optional[uint] = None + txBeaconRequestCount: typing.Optional[uint] = None + txOtherCount: typing.Optional[uint] = None + txRetryCount: typing.Optional[uint] = None + txDirectMaxRetryExpiryCount: typing.Optional[uint] = None + txIndirectMaxRetryExpiryCount: typing.Optional[uint] = None + txErrCcaCount: typing.Optional[uint] = None + txErrAbortCount: typing.Optional[uint] = None + txErrBusyChannelCount: typing.Optional[uint] = None + rxTotalCount: typing.Optional[uint] = None + rxUnicastCount: typing.Optional[uint] = None + rxBroadcastCount: typing.Optional[uint] = None + rxDataCount: typing.Optional[uint] = None + rxDataPollCount: typing.Optional[uint] = None + rxBeaconCount: typing.Optional[uint] = None + rxBeaconRequestCount: typing.Optional[uint] = None + rxOtherCount: typing.Optional[uint] = None + rxAddressFilteredCount: typing.Optional[uint] = None + rxDestAddrFilteredCount: typing.Optional[uint] = None + rxDuplicatedCount: typing.Optional[uint] = None + rxErrNoFrameCount: typing.Optional[uint] = None + rxErrUnknownNeighborCount: typing.Optional[uint] = None + rxErrInvalidSrcAddrCount: typing.Optional[uint] = None + rxErrSecCount: typing.Optional[uint] = None + rxErrFcsCount: typing.Optional[uint] = None + rxErrOtherCount: typing.Optional[uint] = None + activeTimestamp: typing.Union[None, Nullable, uint] = None + pendingTimestamp: typing.Union[None, Nullable, uint] = None + delay: typing.Union[None, Nullable, uint] = None + securityPolicy: typing.Union[Nullable, ThreadNetworkDiagnostics.Structs.SecurityPolicy] = NullValue + channelPage0Mask: typing.Union[Nullable, bytes] = NullValue + operationalDatasetComponents: typing.Union[Nullable, ThreadNetworkDiagnostics.Structs.OperationalDatasetComponents] = NullValue + activeNetworkFaultsList: typing.List[ThreadNetworkDiagnostics.Enums.NetworkFaultEnum] = field(default_factory=lambda: []) + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class ConnectionStatusEnum(MatterIntEnum): @@ -8986,7 +8987,7 @@ class ResetCounts(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000035 command_id: typing.ClassVar[int] = 0x00000000 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -9009,7 +9010,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, uint]) - value: 'typing.Union[Nullable, uint]' = NullValue + value: typing.Union[Nullable, uint] = NullValue @dataclass class RoutingRole(ClusterAttributeDescriptor): @@ -9025,7 +9026,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, ThreadNetworkDiagnostics.Enums.RoutingRoleEnum]) - value: 'typing.Union[Nullable, ThreadNetworkDiagnostics.Enums.RoutingRoleEnum]' = NullValue + value: typing.Union[Nullable, ThreadNetworkDiagnostics.Enums.RoutingRoleEnum] = NullValue @dataclass class NetworkName(ClusterAttributeDescriptor): @@ -9041,7 +9042,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, str]) - value: 'typing.Union[Nullable, str]' = NullValue + value: typing.Union[Nullable, str] = NullValue @dataclass class PanId(ClusterAttributeDescriptor): @@ -9057,7 +9058,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, uint]) - value: 'typing.Union[Nullable, uint]' = NullValue + value: typing.Union[Nullable, uint] = NullValue @dataclass class ExtendedPanId(ClusterAttributeDescriptor): @@ -9073,7 +9074,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, uint]) - value: 'typing.Union[Nullable, uint]' = NullValue + value: typing.Union[Nullable, uint] = NullValue @dataclass class MeshLocalPrefix(ClusterAttributeDescriptor): @@ -9089,7 +9090,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, bytes]) - value: 'typing.Union[Nullable, bytes]' = NullValue + value: typing.Union[Nullable, bytes] = NullValue @dataclass class OverrunCount(ClusterAttributeDescriptor): @@ -9105,7 +9106,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class NeighborTable(ClusterAttributeDescriptor): @@ -9121,7 +9122,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[ThreadNetworkDiagnostics.Structs.NeighborTableStruct]) - value: 'typing.List[ThreadNetworkDiagnostics.Structs.NeighborTableStruct]' = field(default_factory=lambda: []) + value: typing.List[ThreadNetworkDiagnostics.Structs.NeighborTableStruct] = field(default_factory=lambda: []) @dataclass class RouteTable(ClusterAttributeDescriptor): @@ -9137,7 +9138,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[ThreadNetworkDiagnostics.Structs.RouteTableStruct]) - value: 'typing.List[ThreadNetworkDiagnostics.Structs.RouteTableStruct]' = field(default_factory=lambda: []) + value: typing.List[ThreadNetworkDiagnostics.Structs.RouteTableStruct] = field(default_factory=lambda: []) @dataclass class PartitionId(ClusterAttributeDescriptor): @@ -9153,7 +9154,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, uint]) - value: 'typing.Union[Nullable, uint]' = NullValue + value: typing.Union[Nullable, uint] = NullValue @dataclass class Weighting(ClusterAttributeDescriptor): @@ -9169,7 +9170,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, uint]) - value: 'typing.Union[Nullable, uint]' = NullValue + value: typing.Union[Nullable, uint] = NullValue @dataclass class DataVersion(ClusterAttributeDescriptor): @@ -9185,7 +9186,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, uint]) - value: 'typing.Union[Nullable, uint]' = NullValue + value: typing.Union[Nullable, uint] = NullValue @dataclass class StableDataVersion(ClusterAttributeDescriptor): @@ -9201,7 +9202,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, uint]) - value: 'typing.Union[Nullable, uint]' = NullValue + value: typing.Union[Nullable, uint] = NullValue @dataclass class LeaderRouterId(ClusterAttributeDescriptor): @@ -9217,7 +9218,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, uint]) - value: 'typing.Union[Nullable, uint]' = NullValue + value: typing.Union[Nullable, uint] = NullValue @dataclass class DetachedRoleCount(ClusterAttributeDescriptor): @@ -9233,7 +9234,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class ChildRoleCount(ClusterAttributeDescriptor): @@ -9249,7 +9250,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class RouterRoleCount(ClusterAttributeDescriptor): @@ -9265,7 +9266,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class LeaderRoleCount(ClusterAttributeDescriptor): @@ -9281,7 +9282,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class AttachAttemptCount(ClusterAttributeDescriptor): @@ -9297,7 +9298,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class PartitionIdChangeCount(ClusterAttributeDescriptor): @@ -9313,7 +9314,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class BetterPartitionAttachAttemptCount(ClusterAttributeDescriptor): @@ -9329,7 +9330,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class ParentChangeCount(ClusterAttributeDescriptor): @@ -9345,7 +9346,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class TxTotalCount(ClusterAttributeDescriptor): @@ -9361,7 +9362,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class TxUnicastCount(ClusterAttributeDescriptor): @@ -9377,7 +9378,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class TxBroadcastCount(ClusterAttributeDescriptor): @@ -9393,7 +9394,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class TxAckRequestedCount(ClusterAttributeDescriptor): @@ -9409,7 +9410,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class TxAckedCount(ClusterAttributeDescriptor): @@ -9425,7 +9426,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class TxNoAckRequestedCount(ClusterAttributeDescriptor): @@ -9441,7 +9442,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class TxDataCount(ClusterAttributeDescriptor): @@ -9457,7 +9458,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class TxDataPollCount(ClusterAttributeDescriptor): @@ -9473,7 +9474,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class TxBeaconCount(ClusterAttributeDescriptor): @@ -9489,7 +9490,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class TxBeaconRequestCount(ClusterAttributeDescriptor): @@ -9505,7 +9506,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class TxOtherCount(ClusterAttributeDescriptor): @@ -9521,7 +9522,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class TxRetryCount(ClusterAttributeDescriptor): @@ -9537,7 +9538,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class TxDirectMaxRetryExpiryCount(ClusterAttributeDescriptor): @@ -9553,7 +9554,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class TxIndirectMaxRetryExpiryCount(ClusterAttributeDescriptor): @@ -9569,7 +9570,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class TxErrCcaCount(ClusterAttributeDescriptor): @@ -9585,7 +9586,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class TxErrAbortCount(ClusterAttributeDescriptor): @@ -9601,7 +9602,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class TxErrBusyChannelCount(ClusterAttributeDescriptor): @@ -9617,7 +9618,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class RxTotalCount(ClusterAttributeDescriptor): @@ -9633,7 +9634,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class RxUnicastCount(ClusterAttributeDescriptor): @@ -9649,7 +9650,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class RxBroadcastCount(ClusterAttributeDescriptor): @@ -9665,7 +9666,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class RxDataCount(ClusterAttributeDescriptor): @@ -9681,7 +9682,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class RxDataPollCount(ClusterAttributeDescriptor): @@ -9697,7 +9698,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class RxBeaconCount(ClusterAttributeDescriptor): @@ -9713,7 +9714,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class RxBeaconRequestCount(ClusterAttributeDescriptor): @@ -9729,7 +9730,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class RxOtherCount(ClusterAttributeDescriptor): @@ -9745,7 +9746,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class RxAddressFilteredCount(ClusterAttributeDescriptor): @@ -9761,7 +9762,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class RxDestAddrFilteredCount(ClusterAttributeDescriptor): @@ -9777,7 +9778,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class RxDuplicatedCount(ClusterAttributeDescriptor): @@ -9793,7 +9794,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class RxErrNoFrameCount(ClusterAttributeDescriptor): @@ -9809,7 +9810,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class RxErrUnknownNeighborCount(ClusterAttributeDescriptor): @@ -9825,7 +9826,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class RxErrInvalidSrcAddrCount(ClusterAttributeDescriptor): @@ -9841,7 +9842,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class RxErrSecCount(ClusterAttributeDescriptor): @@ -9857,7 +9858,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class RxErrFcsCount(ClusterAttributeDescriptor): @@ -9873,7 +9874,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class RxErrOtherCount(ClusterAttributeDescriptor): @@ -9889,7 +9890,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class ActiveTimestamp(ClusterAttributeDescriptor): @@ -9905,7 +9906,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class PendingTimestamp(ClusterAttributeDescriptor): @@ -9921,7 +9922,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class Delay(ClusterAttributeDescriptor): @@ -9937,7 +9938,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class SecurityPolicy(ClusterAttributeDescriptor): @@ -9953,7 +9954,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, ThreadNetworkDiagnostics.Structs.SecurityPolicy]) - value: 'typing.Union[Nullable, ThreadNetworkDiagnostics.Structs.SecurityPolicy]' = NullValue + value: typing.Union[Nullable, ThreadNetworkDiagnostics.Structs.SecurityPolicy] = NullValue @dataclass class ChannelPage0Mask(ClusterAttributeDescriptor): @@ -9969,7 +9970,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, bytes]) - value: 'typing.Union[Nullable, bytes]' = NullValue + value: typing.Union[Nullable, bytes] = NullValue @dataclass class OperationalDatasetComponents(ClusterAttributeDescriptor): @@ -9985,7 +9986,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, ThreadNetworkDiagnostics.Structs.OperationalDatasetComponents]) - value: 'typing.Union[Nullable, ThreadNetworkDiagnostics.Structs.OperationalDatasetComponents]' = NullValue + value: typing.Union[Nullable, ThreadNetworkDiagnostics.Structs.OperationalDatasetComponents] = NullValue @dataclass class ActiveNetworkFaultsList(ClusterAttributeDescriptor): @@ -10001,7 +10002,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[ThreadNetworkDiagnostics.Enums.NetworkFaultEnum]) - value: 'typing.List[ThreadNetworkDiagnostics.Enums.NetworkFaultEnum]' = field(default_factory=lambda: []) + value: typing.List[ThreadNetworkDiagnostics.Enums.NetworkFaultEnum] = field(default_factory=lambda: []) @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -10017,7 +10018,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -10033,7 +10034,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -10049,7 +10050,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -10065,7 +10066,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -10081,7 +10082,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -10097,7 +10098,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 class Events: @dataclass @@ -10117,7 +10118,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="connectionStatus", Tag=0, Type=ThreadNetworkDiagnostics.Enums.ConnectionStatusEnum), ]) - connectionStatus: 'ThreadNetworkDiagnostics.Enums.ConnectionStatusEnum' = 0 + connectionStatus: ThreadNetworkDiagnostics.Enums.ConnectionStatusEnum = 0 @dataclass class NetworkFaultChange(ClusterEvent): @@ -10137,8 +10138,8 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="previous", Tag=1, Type=typing.List[ThreadNetworkDiagnostics.Enums.NetworkFaultEnum]), ]) - current: 'typing.List[ThreadNetworkDiagnostics.Enums.NetworkFaultEnum]' = field(default_factory=lambda: []) - previous: 'typing.List[ThreadNetworkDiagnostics.Enums.NetworkFaultEnum]' = field(default_factory=lambda: []) + current: typing.List[ThreadNetworkDiagnostics.Enums.NetworkFaultEnum] = field(default_factory=lambda: []) + previous: typing.List[ThreadNetworkDiagnostics.Enums.NetworkFaultEnum] = field(default_factory=lambda: []) @dataclass @@ -10170,25 +10171,25 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - bssid: 'typing.Union[Nullable, bytes]' = None - securityType: 'typing.Union[Nullable, WiFiNetworkDiagnostics.Enums.SecurityTypeEnum]' = None - wiFiVersion: 'typing.Union[Nullable, WiFiNetworkDiagnostics.Enums.WiFiVersionEnum]' = None - channelNumber: 'typing.Union[Nullable, uint]' = None - rssi: 'typing.Union[Nullable, int]' = None - beaconLostCount: 'typing.Union[None, Nullable, uint]' = None - beaconRxCount: 'typing.Union[None, Nullable, uint]' = None - packetMulticastRxCount: 'typing.Union[None, Nullable, uint]' = None - packetMulticastTxCount: 'typing.Union[None, Nullable, uint]' = None - packetUnicastRxCount: 'typing.Union[None, Nullable, uint]' = None - packetUnicastTxCount: 'typing.Union[None, Nullable, uint]' = None - currentMaxRate: 'typing.Union[None, Nullable, uint]' = None - overrunCount: 'typing.Union[None, Nullable, uint]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + bssid: typing.Union[Nullable, bytes] = NullValue + securityType: typing.Union[Nullable, WiFiNetworkDiagnostics.Enums.SecurityTypeEnum] = NullValue + wiFiVersion: typing.Union[Nullable, WiFiNetworkDiagnostics.Enums.WiFiVersionEnum] = NullValue + channelNumber: typing.Union[Nullable, uint] = NullValue + rssi: typing.Union[Nullable, int] = NullValue + beaconLostCount: typing.Union[None, Nullable, uint] = None + beaconRxCount: typing.Union[None, Nullable, uint] = None + packetMulticastRxCount: typing.Union[None, Nullable, uint] = None + packetMulticastTxCount: typing.Union[None, Nullable, uint] = None + packetUnicastRxCount: typing.Union[None, Nullable, uint] = None + packetUnicastTxCount: typing.Union[None, Nullable, uint] = None + currentMaxRate: typing.Union[None, Nullable, uint] = None + overrunCount: typing.Union[None, Nullable, uint] = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class AssociationFailureCauseEnum(MatterIntEnum): @@ -10249,7 +10250,7 @@ class ResetCounts(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000036 command_id: typing.ClassVar[int] = 0x00000000 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -10272,7 +10273,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, bytes]) - value: 'typing.Union[Nullable, bytes]' = NullValue + value: typing.Union[Nullable, bytes] = NullValue @dataclass class SecurityType(ClusterAttributeDescriptor): @@ -10288,7 +10289,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, WiFiNetworkDiagnostics.Enums.SecurityTypeEnum]) - value: 'typing.Union[Nullable, WiFiNetworkDiagnostics.Enums.SecurityTypeEnum]' = NullValue + value: typing.Union[Nullable, WiFiNetworkDiagnostics.Enums.SecurityTypeEnum] = NullValue @dataclass class WiFiVersion(ClusterAttributeDescriptor): @@ -10304,7 +10305,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, WiFiNetworkDiagnostics.Enums.WiFiVersionEnum]) - value: 'typing.Union[Nullable, WiFiNetworkDiagnostics.Enums.WiFiVersionEnum]' = NullValue + value: typing.Union[Nullable, WiFiNetworkDiagnostics.Enums.WiFiVersionEnum] = NullValue @dataclass class ChannelNumber(ClusterAttributeDescriptor): @@ -10320,7 +10321,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, uint]) - value: 'typing.Union[Nullable, uint]' = NullValue + value: typing.Union[Nullable, uint] = NullValue @dataclass class Rssi(ClusterAttributeDescriptor): @@ -10336,7 +10337,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, int]) - value: 'typing.Union[Nullable, int]' = NullValue + value: typing.Union[Nullable, int] = NullValue @dataclass class BeaconLostCount(ClusterAttributeDescriptor): @@ -10352,7 +10353,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class BeaconRxCount(ClusterAttributeDescriptor): @@ -10368,7 +10369,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class PacketMulticastRxCount(ClusterAttributeDescriptor): @@ -10384,7 +10385,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class PacketMulticastTxCount(ClusterAttributeDescriptor): @@ -10400,7 +10401,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class PacketUnicastRxCount(ClusterAttributeDescriptor): @@ -10416,7 +10417,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class PacketUnicastTxCount(ClusterAttributeDescriptor): @@ -10432,7 +10433,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class CurrentMaxRate(ClusterAttributeDescriptor): @@ -10448,7 +10449,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class OverrunCount(ClusterAttributeDescriptor): @@ -10464,7 +10465,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -10480,7 +10481,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -10496,7 +10497,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -10512,7 +10513,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -10528,7 +10529,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -10544,7 +10545,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -10560,7 +10561,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 class Events: @dataclass @@ -10580,7 +10581,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="reasonCode", Tag=0, Type=uint), ]) - reasonCode: 'uint' = 0 + reasonCode: uint = 0 @dataclass class AssociationFailure(ClusterEvent): @@ -10600,8 +10601,8 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="status", Tag=1, Type=uint), ]) - associationFailureCause: 'WiFiNetworkDiagnostics.Enums.AssociationFailureCauseEnum' = 0 - status: 'uint' = 0 + associationFailureCause: WiFiNetworkDiagnostics.Enums.AssociationFailureCauseEnum = 0 + status: uint = 0 @dataclass class ConnectionStatus(ClusterEvent): @@ -10620,7 +10621,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="connectionStatus", Tag=0, Type=WiFiNetworkDiagnostics.Enums.ConnectionStatusEnum), ]) - connectionStatus: 'WiFiNetworkDiagnostics.Enums.ConnectionStatusEnum' = 0 + connectionStatus: WiFiNetworkDiagnostics.Enums.ConnectionStatusEnum = 0 @dataclass @@ -10648,21 +10649,21 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - PHYRate: 'typing.Union[None, Nullable, EthernetNetworkDiagnostics.Enums.PHYRateEnum]' = None - fullDuplex: 'typing.Union[None, Nullable, bool]' = None - packetRxCount: 'typing.Optional[uint]' = None - packetTxCount: 'typing.Optional[uint]' = None - txErrCount: 'typing.Optional[uint]' = None - collisionCount: 'typing.Optional[uint]' = None - overrunCount: 'typing.Optional[uint]' = None - carrierDetect: 'typing.Union[None, Nullable, bool]' = None - timeSinceReset: 'typing.Optional[uint]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + PHYRate: typing.Union[None, Nullable, EthernetNetworkDiagnostics.Enums.PHYRateEnum] = None + fullDuplex: typing.Union[None, Nullable, bool] = None + packetRxCount: typing.Optional[uint] = None + packetTxCount: typing.Optional[uint] = None + txErrCount: typing.Optional[uint] = None + collisionCount: typing.Optional[uint] = None + overrunCount: typing.Optional[uint] = None + carrierDetect: typing.Union[None, Nullable, bool] = None + timeSinceReset: typing.Optional[uint] = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class PHYRateEnum(MatterIntEnum): @@ -10693,7 +10694,7 @@ class ResetCounts(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000037 command_id: typing.ClassVar[int] = 0x00000000 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -10716,7 +10717,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, EthernetNetworkDiagnostics.Enums.PHYRateEnum]) - value: 'typing.Union[None, Nullable, EthernetNetworkDiagnostics.Enums.PHYRateEnum]' = None + value: typing.Union[None, Nullable, EthernetNetworkDiagnostics.Enums.PHYRateEnum] = None @dataclass class FullDuplex(ClusterAttributeDescriptor): @@ -10732,7 +10733,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, bool]) - value: 'typing.Union[None, Nullable, bool]' = None + value: typing.Union[None, Nullable, bool] = None @dataclass class PacketRxCount(ClusterAttributeDescriptor): @@ -10748,7 +10749,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class PacketTxCount(ClusterAttributeDescriptor): @@ -10764,7 +10765,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class TxErrCount(ClusterAttributeDescriptor): @@ -10780,7 +10781,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class CollisionCount(ClusterAttributeDescriptor): @@ -10796,7 +10797,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class OverrunCount(ClusterAttributeDescriptor): @@ -10812,7 +10813,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class CarrierDetect(ClusterAttributeDescriptor): @@ -10828,7 +10829,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, bool]) - value: 'typing.Union[None, Nullable, bool]' = None + value: typing.Union[None, Nullable, bool] = None @dataclass class TimeSinceReset(ClusterAttributeDescriptor): @@ -10844,7 +10845,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -10860,7 +10861,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -10876,7 +10877,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -10892,7 +10893,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -10908,7 +10909,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -10924,7 +10925,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -10940,7 +10941,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -10972,25 +10973,25 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - UTCTime: 'typing.Union[Nullable, uint]' = None - granularity: 'TimeSynchronization.Enums.GranularityEnum' = None - timeSource: 'typing.Optional[TimeSynchronization.Enums.TimeSourceEnum]' = None - trustedTimeSource: 'typing.Union[None, Nullable, TimeSynchronization.Structs.TrustedTimeSourceStruct]' = None - defaultNTP: 'typing.Union[None, Nullable, str]' = None - timeZone: 'typing.Optional[typing.List[TimeSynchronization.Structs.TimeZoneStruct]]' = None - DSTOffset: 'typing.Optional[typing.List[TimeSynchronization.Structs.DSTOffsetStruct]]' = None - localTime: 'typing.Union[None, Nullable, uint]' = None - timeZoneDatabase: 'typing.Optional[TimeSynchronization.Enums.TimeZoneDatabaseEnum]' = None - NTPServerAvailable: 'typing.Optional[bool]' = None - timeZoneListMaxSize: 'typing.Optional[uint]' = None - DSTOffsetListMaxSize: 'typing.Optional[uint]' = None - supportsDNSResolve: 'typing.Optional[bool]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + UTCTime: typing.Union[Nullable, uint] = NullValue + granularity: TimeSynchronization.Enums.GranularityEnum = 0 + timeSource: typing.Optional[TimeSynchronization.Enums.TimeSourceEnum] = None + trustedTimeSource: typing.Union[None, Nullable, TimeSynchronization.Structs.TrustedTimeSourceStruct] = None + defaultNTP: typing.Union[None, Nullable, str] = None + timeZone: typing.Optional[typing.List[TimeSynchronization.Structs.TimeZoneStruct]] = None + DSTOffset: typing.Optional[typing.List[TimeSynchronization.Structs.DSTOffsetStruct]] = None + localTime: typing.Union[None, Nullable, uint] = None + timeZoneDatabase: typing.Optional[TimeSynchronization.Enums.TimeZoneDatabaseEnum] = None + NTPServerAvailable: typing.Optional[bool] = None + timeZoneListMaxSize: typing.Optional[uint] = None + DSTOffsetListMaxSize: typing.Optional[uint] = None + supportsDNSResolve: typing.Optional[bool] = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class GranularityEnum(MatterIntEnum): @@ -11119,7 +11120,7 @@ class SetUTCTime(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000038 command_id: typing.ClassVar[int] = 0x00000000 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -11130,16 +11131,16 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="timeSource", Tag=2, Type=typing.Optional[TimeSynchronization.Enums.TimeSourceEnum]), ]) - UTCTime: 'uint' = 0 - granularity: 'TimeSynchronization.Enums.GranularityEnum' = 0 - timeSource: 'typing.Optional[TimeSynchronization.Enums.TimeSourceEnum]' = None + UTCTime: uint = 0 + granularity: TimeSynchronization.Enums.GranularityEnum = 0 + timeSource: typing.Optional[TimeSynchronization.Enums.TimeSourceEnum] = None @dataclass class SetTrustedTimeSource(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000038 command_id: typing.ClassVar[int] = 0x00000001 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -11148,7 +11149,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="trustedTimeSource", Tag=0, Type=typing.Union[Nullable, TimeSynchronization.Structs.FabricScopedTrustedTimeSourceStruct]), ]) - trustedTimeSource: 'typing.Union[Nullable, TimeSynchronization.Structs.FabricScopedTrustedTimeSourceStruct]' = NullValue + trustedTimeSource: typing.Union[Nullable, TimeSynchronization.Structs.FabricScopedTrustedTimeSourceStruct] = NullValue @dataclass class SetTimeZone(ClusterCommand): @@ -11164,14 +11165,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="timeZone", Tag=0, Type=typing.List[TimeSynchronization.Structs.TimeZoneStruct]), ]) - timeZone: 'typing.List[TimeSynchronization.Structs.TimeZoneStruct]' = field(default_factory=lambda: []) + timeZone: typing.List[TimeSynchronization.Structs.TimeZoneStruct] = field(default_factory=lambda: []) @dataclass class SetTimeZoneResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000038 command_id: typing.ClassVar[int] = 0x00000003 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -11180,14 +11181,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="DSTOffsetRequired", Tag=0, Type=bool), ]) - DSTOffsetRequired: 'bool' = False + DSTOffsetRequired: bool = False @dataclass class SetDSTOffset(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000038 command_id: typing.ClassVar[int] = 0x00000004 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -11196,14 +11197,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="DSTOffset", Tag=0, Type=typing.List[TimeSynchronization.Structs.DSTOffsetStruct]), ]) - DSTOffset: 'typing.List[TimeSynchronization.Structs.DSTOffsetStruct]' = field(default_factory=lambda: []) + DSTOffset: typing.List[TimeSynchronization.Structs.DSTOffsetStruct] = field(default_factory=lambda: []) @dataclass class SetDefaultNTP(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000038 command_id: typing.ClassVar[int] = 0x00000005 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -11212,7 +11213,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="defaultNTP", Tag=0, Type=typing.Union[Nullable, str]), ]) - defaultNTP: 'typing.Union[Nullable, str]' = NullValue + defaultNTP: typing.Union[Nullable, str] = NullValue class Attributes: @dataclass @@ -11229,7 +11230,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, uint]) - value: 'typing.Union[Nullable, uint]' = NullValue + value: typing.Union[Nullable, uint] = NullValue @dataclass class Granularity(ClusterAttributeDescriptor): @@ -11245,7 +11246,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=TimeSynchronization.Enums.GranularityEnum) - value: 'TimeSynchronization.Enums.GranularityEnum' = 0 + value: TimeSynchronization.Enums.GranularityEnum = 0 @dataclass class TimeSource(ClusterAttributeDescriptor): @@ -11261,7 +11262,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[TimeSynchronization.Enums.TimeSourceEnum]) - value: 'typing.Optional[TimeSynchronization.Enums.TimeSourceEnum]' = None + value: typing.Optional[TimeSynchronization.Enums.TimeSourceEnum] = None @dataclass class TrustedTimeSource(ClusterAttributeDescriptor): @@ -11277,7 +11278,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, TimeSynchronization.Structs.TrustedTimeSourceStruct]) - value: 'typing.Union[None, Nullable, TimeSynchronization.Structs.TrustedTimeSourceStruct]' = None + value: typing.Union[None, Nullable, TimeSynchronization.Structs.TrustedTimeSourceStruct] = None @dataclass class DefaultNTP(ClusterAttributeDescriptor): @@ -11293,7 +11294,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, str]) - value: 'typing.Union[None, Nullable, str]' = None + value: typing.Union[None, Nullable, str] = None @dataclass class TimeZone(ClusterAttributeDescriptor): @@ -11309,7 +11310,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[typing.List[TimeSynchronization.Structs.TimeZoneStruct]]) - value: 'typing.Optional[typing.List[TimeSynchronization.Structs.TimeZoneStruct]]' = None + value: typing.Optional[typing.List[TimeSynchronization.Structs.TimeZoneStruct]] = None @dataclass class DSTOffset(ClusterAttributeDescriptor): @@ -11325,7 +11326,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[typing.List[TimeSynchronization.Structs.DSTOffsetStruct]]) - value: 'typing.Optional[typing.List[TimeSynchronization.Structs.DSTOffsetStruct]]' = None + value: typing.Optional[typing.List[TimeSynchronization.Structs.DSTOffsetStruct]] = None @dataclass class LocalTime(ClusterAttributeDescriptor): @@ -11341,7 +11342,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class TimeZoneDatabase(ClusterAttributeDescriptor): @@ -11357,7 +11358,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[TimeSynchronization.Enums.TimeZoneDatabaseEnum]) - value: 'typing.Optional[TimeSynchronization.Enums.TimeZoneDatabaseEnum]' = None + value: typing.Optional[TimeSynchronization.Enums.TimeZoneDatabaseEnum] = None @dataclass class NTPServerAvailable(ClusterAttributeDescriptor): @@ -11373,7 +11374,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[bool]) - value: 'typing.Optional[bool]' = None + value: typing.Optional[bool] = None @dataclass class TimeZoneListMaxSize(ClusterAttributeDescriptor): @@ -11389,7 +11390,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class DSTOffsetListMaxSize(ClusterAttributeDescriptor): @@ -11405,7 +11406,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class SupportsDNSResolve(ClusterAttributeDescriptor): @@ -11421,7 +11422,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[bool]) - value: 'typing.Optional[bool]' = None + value: typing.Optional[bool] = None @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -11437,7 +11438,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -11453,7 +11454,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -11469,7 +11470,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -11485,7 +11486,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -11501,7 +11502,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -11517,7 +11518,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 class Events: @dataclass @@ -11553,7 +11554,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="DSTOffsetActive", Tag=0, Type=bool), ]) - DSTOffsetActive: 'bool' = False + DSTOffsetActive: bool = False @dataclass class TimeZoneStatus(ClusterEvent): @@ -11573,8 +11574,8 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="name", Tag=1, Type=typing.Optional[str]), ]) - offset: 'int' = 0 - name: 'typing.Optional[str]' = None + offset: int = 0 + name: typing.Optional[str] = None @dataclass class TimeFailure(ClusterEvent): @@ -11642,29 +11643,29 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - vendorName: 'typing.Optional[str]' = None - vendorID: 'typing.Optional[uint]' = None - productName: 'typing.Optional[str]' = None - productID: 'typing.Optional[uint]' = None - nodeLabel: 'typing.Optional[str]' = None - hardwareVersion: 'typing.Optional[uint]' = None - hardwareVersionString: 'typing.Optional[str]' = None - softwareVersion: 'typing.Optional[uint]' = None - softwareVersionString: 'typing.Optional[str]' = None - manufacturingDate: 'typing.Optional[str]' = None - partNumber: 'typing.Optional[str]' = None - productURL: 'typing.Optional[str]' = None - productLabel: 'typing.Optional[str]' = None - serialNumber: 'typing.Optional[str]' = None - reachable: 'bool' = None - uniqueID: 'str' = None - productAppearance: 'typing.Optional[BridgedDeviceBasicInformation.Structs.ProductAppearanceStruct]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + vendorName: typing.Optional[str] = None + vendorID: typing.Optional[uint] = None + productName: typing.Optional[str] = None + productID: typing.Optional[uint] = None + nodeLabel: typing.Optional[str] = None + hardwareVersion: typing.Optional[uint] = None + hardwareVersionString: typing.Optional[str] = None + softwareVersion: typing.Optional[uint] = None + softwareVersionString: typing.Optional[str] = None + manufacturingDate: typing.Optional[str] = None + partNumber: typing.Optional[str] = None + productURL: typing.Optional[str] = None + productLabel: typing.Optional[str] = None + serialNumber: typing.Optional[str] = None + reachable: bool = False + uniqueID: str = "" + productAppearance: typing.Optional[BridgedDeviceBasicInformation.Structs.ProductAppearanceStruct] = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class ColorEnum(MatterIntEnum): @@ -11732,7 +11733,7 @@ class KeepActive(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000039 command_id: typing.ClassVar[int] = 0x00000080 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -11742,8 +11743,8 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="timeoutMs", Tag=1, Type=uint), ]) - stayActiveDuration: 'uint' = 0 - timeoutMs: 'uint' = 0 + stayActiveDuration: uint = 0 + timeoutMs: uint = 0 class Attributes: @dataclass @@ -11760,7 +11761,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[str]) - value: 'typing.Optional[str]' = None + value: typing.Optional[str] = None @dataclass class VendorID(ClusterAttributeDescriptor): @@ -11776,7 +11777,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class ProductName(ClusterAttributeDescriptor): @@ -11792,7 +11793,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[str]) - value: 'typing.Optional[str]' = None + value: typing.Optional[str] = None @dataclass class ProductID(ClusterAttributeDescriptor): @@ -11808,7 +11809,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class NodeLabel(ClusterAttributeDescriptor): @@ -11824,7 +11825,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[str]) - value: 'typing.Optional[str]' = None + value: typing.Optional[str] = None @dataclass class HardwareVersion(ClusterAttributeDescriptor): @@ -11840,7 +11841,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class HardwareVersionString(ClusterAttributeDescriptor): @@ -11856,7 +11857,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[str]) - value: 'typing.Optional[str]' = None + value: typing.Optional[str] = None @dataclass class SoftwareVersion(ClusterAttributeDescriptor): @@ -11872,7 +11873,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class SoftwareVersionString(ClusterAttributeDescriptor): @@ -11888,7 +11889,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[str]) - value: 'typing.Optional[str]' = None + value: typing.Optional[str] = None @dataclass class ManufacturingDate(ClusterAttributeDescriptor): @@ -11904,7 +11905,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[str]) - value: 'typing.Optional[str]' = None + value: typing.Optional[str] = None @dataclass class PartNumber(ClusterAttributeDescriptor): @@ -11920,7 +11921,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[str]) - value: 'typing.Optional[str]' = None + value: typing.Optional[str] = None @dataclass class ProductURL(ClusterAttributeDescriptor): @@ -11936,7 +11937,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[str]) - value: 'typing.Optional[str]' = None + value: typing.Optional[str] = None @dataclass class ProductLabel(ClusterAttributeDescriptor): @@ -11952,7 +11953,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[str]) - value: 'typing.Optional[str]' = None + value: typing.Optional[str] = None @dataclass class SerialNumber(ClusterAttributeDescriptor): @@ -11968,7 +11969,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[str]) - value: 'typing.Optional[str]' = None + value: typing.Optional[str] = None @dataclass class Reachable(ClusterAttributeDescriptor): @@ -11984,7 +11985,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=bool) - value: 'bool' = False + value: bool = False @dataclass class UniqueID(ClusterAttributeDescriptor): @@ -12000,7 +12001,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=str) - value: 'str' = "" + value: str = "" @dataclass class ProductAppearance(ClusterAttributeDescriptor): @@ -12016,7 +12017,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[BridgedDeviceBasicInformation.Structs.ProductAppearanceStruct]) - value: 'typing.Optional[BridgedDeviceBasicInformation.Structs.ProductAppearanceStruct]' = None + value: typing.Optional[BridgedDeviceBasicInformation.Structs.ProductAppearanceStruct] = None @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -12032,7 +12033,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -12048,7 +12049,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -12064,7 +12065,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -12080,7 +12081,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -12096,7 +12097,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -12112,7 +12113,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 class Events: @dataclass @@ -12132,7 +12133,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="softwareVersion", Tag=0, Type=uint), ]) - softwareVersion: 'uint' = 0 + softwareVersion: uint = 0 @dataclass class ShutDown(ClusterEvent): @@ -12183,7 +12184,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="reachableNewValue", Tag=0, Type=bool), ]) - reachableNewValue: 'bool' = False + reachableNewValue: bool = False @dataclass class ActiveChanged(ClusterEvent): @@ -12202,7 +12203,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="promisedActiveDuration", Tag=0, Type=uint), ]) - promisedActiveDuration: 'uint' = 0 + promisedActiveDuration: uint = 0 @dataclass @@ -12224,15 +12225,15 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - numberOfPositions: 'uint' = None - currentPosition: 'uint' = None - multiPressMax: 'typing.Optional[uint]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + numberOfPositions: uint = 0 + currentPosition: uint = 0 + multiPressMax: typing.Optional[uint] = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Bitmaps: class Feature(IntFlag): @@ -12258,7 +12259,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class CurrentPosition(ClusterAttributeDescriptor): @@ -12274,7 +12275,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class MultiPressMax(ClusterAttributeDescriptor): @@ -12290,7 +12291,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -12306,7 +12307,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -12322,7 +12323,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -12338,7 +12339,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -12354,7 +12355,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -12370,7 +12371,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -12386,7 +12387,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 class Events: @dataclass @@ -12406,7 +12407,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="newPosition", Tag=0, Type=uint), ]) - newPosition: 'uint' = 0 + newPosition: uint = 0 @dataclass class InitialPress(ClusterEvent): @@ -12425,7 +12426,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="newPosition", Tag=0, Type=uint), ]) - newPosition: 'uint' = 0 + newPosition: uint = 0 @dataclass class LongPress(ClusterEvent): @@ -12444,7 +12445,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="newPosition", Tag=0, Type=uint), ]) - newPosition: 'uint' = 0 + newPosition: uint = 0 @dataclass class ShortRelease(ClusterEvent): @@ -12463,7 +12464,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="previousPosition", Tag=0, Type=uint), ]) - previousPosition: 'uint' = 0 + previousPosition: uint = 0 @dataclass class LongRelease(ClusterEvent): @@ -12482,7 +12483,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="previousPosition", Tag=0, Type=uint), ]) - previousPosition: 'uint' = 0 + previousPosition: uint = 0 @dataclass class MultiPressOngoing(ClusterEvent): @@ -12502,8 +12503,8 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="currentNumberOfPressesCounted", Tag=1, Type=uint), ]) - newPosition: 'uint' = 0 - currentNumberOfPressesCounted: 'uint' = 0 + newPosition: uint = 0 + currentNumberOfPressesCounted: uint = 0 @dataclass class MultiPressComplete(ClusterEvent): @@ -12523,8 +12524,8 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="totalNumberOfPressesCounted", Tag=1, Type=uint), ]) - previousPosition: 'uint' = 0 - totalNumberOfPressesCounted: 'uint' = 0 + previousPosition: uint = 0 + totalNumberOfPressesCounted: uint = 0 @dataclass @@ -12546,15 +12547,15 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - windowStatus: 'AdministratorCommissioning.Enums.CommissioningWindowStatusEnum' = None - adminFabricIndex: 'typing.Union[Nullable, uint]' = None - adminVendorId: 'typing.Union[Nullable, uint]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + windowStatus: AdministratorCommissioning.Enums.CommissioningWindowStatusEnum = 0 + adminFabricIndex: typing.Union[Nullable, uint] = NullValue + adminVendorId: typing.Union[Nullable, uint] = NullValue + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class CommissioningWindowStatusEnum(MatterIntEnum): @@ -12587,7 +12588,7 @@ class OpenCommissioningWindow(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x0000003C command_id: typing.ClassVar[int] = 0x00000000 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -12604,18 +12605,18 @@ def descriptor(cls) -> ClusterObjectDescriptor: def must_use_timed_invoke(cls) -> bool: return True - commissioningTimeout: 'uint' = 0 - PAKEPasscodeVerifier: 'bytes' = b"" - discriminator: 'uint' = 0 - iterations: 'uint' = 0 - salt: 'bytes' = b"" + commissioningTimeout: uint = 0 + PAKEPasscodeVerifier: bytes = b"" + discriminator: uint = 0 + iterations: uint = 0 + salt: bytes = b"" @dataclass class OpenBasicCommissioningWindow(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x0000003C command_id: typing.ClassVar[int] = 0x00000001 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -12628,14 +12629,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: def must_use_timed_invoke(cls) -> bool: return True - commissioningTimeout: 'uint' = 0 + commissioningTimeout: uint = 0 @dataclass class RevokeCommissioning(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x0000003C command_id: typing.ClassVar[int] = 0x00000002 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -12662,7 +12663,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=AdministratorCommissioning.Enums.CommissioningWindowStatusEnum) - value: 'AdministratorCommissioning.Enums.CommissioningWindowStatusEnum' = 0 + value: AdministratorCommissioning.Enums.CommissioningWindowStatusEnum = 0 @dataclass class AdminFabricIndex(ClusterAttributeDescriptor): @@ -12678,7 +12679,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, uint]) - value: 'typing.Union[Nullable, uint]' = NullValue + value: typing.Union[Nullable, uint] = NullValue @dataclass class AdminVendorId(ClusterAttributeDescriptor): @@ -12694,7 +12695,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, uint]) - value: 'typing.Union[Nullable, uint]' = NullValue + value: typing.Union[Nullable, uint] = NullValue @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -12710,7 +12711,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -12726,7 +12727,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -12742,7 +12743,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -12758,7 +12759,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -12774,7 +12775,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -12790,7 +12791,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -12815,18 +12816,18 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - NOCs: 'typing.List[OperationalCredentials.Structs.NOCStruct]' = None - fabrics: 'typing.List[OperationalCredentials.Structs.FabricDescriptorStruct]' = None - supportedFabrics: 'uint' = None - commissionedFabrics: 'uint' = None - trustedRootCertificates: 'typing.List[bytes]' = None - currentFabricIndex: 'uint' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + NOCs: typing.List[OperationalCredentials.Structs.NOCStruct] = field(default_factory=lambda: []) + fabrics: typing.List[OperationalCredentials.Structs.FabricDescriptorStruct] = field(default_factory=lambda: []) + supportedFabrics: uint = 0 + commissionedFabrics: uint = 0 + trustedRootCertificates: typing.List[bytes] = field(default_factory=lambda: []) + currentFabricIndex: uint = 0 + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class CertificateChainTypeEnum(MatterIntEnum): @@ -12907,14 +12908,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="attestationNonce", Tag=0, Type=bytes), ]) - attestationNonce: 'bytes' = b"" + attestationNonce: bytes = b"" @dataclass class AttestationResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x0000003E command_id: typing.ClassVar[int] = 0x00000001 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -12924,8 +12925,8 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="attestationSignature", Tag=1, Type=bytes), ]) - attestationElements: 'bytes' = b"" - attestationSignature: 'bytes' = b"" + attestationElements: bytes = b"" + attestationSignature: bytes = b"" @dataclass class CertificateChainRequest(ClusterCommand): @@ -12941,14 +12942,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="certificateType", Tag=0, Type=OperationalCredentials.Enums.CertificateChainTypeEnum), ]) - certificateType: 'OperationalCredentials.Enums.CertificateChainTypeEnum' = 0 + certificateType: OperationalCredentials.Enums.CertificateChainTypeEnum = 0 @dataclass class CertificateChainResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x0000003E command_id: typing.ClassVar[int] = 0x00000003 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -12957,7 +12958,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="certificate", Tag=0, Type=bytes), ]) - certificate: 'bytes' = b"" + certificate: bytes = b"" @dataclass class CSRRequest(ClusterCommand): @@ -12974,15 +12975,15 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="isForUpdateNOC", Tag=1, Type=typing.Optional[bool]), ]) - CSRNonce: 'bytes' = b"" - isForUpdateNOC: 'typing.Optional[bool]' = None + CSRNonce: bytes = b"" + isForUpdateNOC: typing.Optional[bool] = None @dataclass class CSRResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x0000003E command_id: typing.ClassVar[int] = 0x00000005 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -12992,8 +12993,8 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="attestationSignature", Tag=1, Type=bytes), ]) - NOCSRElements: 'bytes' = b"" - attestationSignature: 'bytes' = b"" + NOCSRElements: bytes = b"" + attestationSignature: bytes = b"" @dataclass class AddNOC(ClusterCommand): @@ -13013,11 +13014,11 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="adminVendorId", Tag=4, Type=uint), ]) - NOCValue: 'bytes' = b"" - ICACValue: 'typing.Optional[bytes]' = None - IPKValue: 'bytes' = b"" - caseAdminSubject: 'uint' = 0 - adminVendorId: 'uint' = 0 + NOCValue: bytes = b"" + ICACValue: typing.Optional[bytes] = None + IPKValue: bytes = b"" + caseAdminSubject: uint = 0 + adminVendorId: uint = 0 @dataclass class UpdateNOC(ClusterCommand): @@ -13034,15 +13035,15 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="ICACValue", Tag=1, Type=typing.Optional[bytes]), ]) - NOCValue: 'bytes' = b"" - ICACValue: 'typing.Optional[bytes]' = None + NOCValue: bytes = b"" + ICACValue: typing.Optional[bytes] = None @dataclass class NOCResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x0000003E command_id: typing.ClassVar[int] = 0x00000008 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -13053,9 +13054,9 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="debugText", Tag=2, Type=typing.Optional[str]), ]) - statusCode: 'OperationalCredentials.Enums.NodeOperationalCertStatusEnum' = 0 - fabricIndex: 'typing.Optional[uint]' = None - debugText: 'typing.Optional[str]' = None + statusCode: OperationalCredentials.Enums.NodeOperationalCertStatusEnum = 0 + fabricIndex: typing.Optional[uint] = None + debugText: typing.Optional[str] = None @dataclass class UpdateFabricLabel(ClusterCommand): @@ -13071,7 +13072,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="label", Tag=0, Type=str), ]) - label: 'str' = "" + label: str = "" @dataclass class RemoveFabric(ClusterCommand): @@ -13087,14 +13088,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="fabricIndex", Tag=0, Type=uint), ]) - fabricIndex: 'uint' = 0 + fabricIndex: uint = 0 @dataclass class AddTrustedRootCertificate(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x0000003E command_id: typing.ClassVar[int] = 0x0000000B is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -13103,7 +13104,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="rootCACertificate", Tag=0, Type=bytes), ]) - rootCACertificate: 'bytes' = b"" + rootCACertificate: bytes = b"" class Attributes: @dataclass @@ -13120,7 +13121,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[OperationalCredentials.Structs.NOCStruct]) - value: 'typing.List[OperationalCredentials.Structs.NOCStruct]' = field(default_factory=lambda: []) + value: typing.List[OperationalCredentials.Structs.NOCStruct] = field(default_factory=lambda: []) @dataclass class Fabrics(ClusterAttributeDescriptor): @@ -13136,7 +13137,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[OperationalCredentials.Structs.FabricDescriptorStruct]) - value: 'typing.List[OperationalCredentials.Structs.FabricDescriptorStruct]' = field(default_factory=lambda: []) + value: typing.List[OperationalCredentials.Structs.FabricDescriptorStruct] = field(default_factory=lambda: []) @dataclass class SupportedFabrics(ClusterAttributeDescriptor): @@ -13152,7 +13153,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class CommissionedFabrics(ClusterAttributeDescriptor): @@ -13168,7 +13169,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class TrustedRootCertificates(ClusterAttributeDescriptor): @@ -13184,7 +13185,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[bytes]) - value: 'typing.List[bytes]' = field(default_factory=lambda: []) + value: typing.List[bytes] = field(default_factory=lambda: []) @dataclass class CurrentFabricIndex(ClusterAttributeDescriptor): @@ -13200,7 +13201,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -13216,7 +13217,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -13232,7 +13233,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -13248,7 +13249,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -13264,7 +13265,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -13280,7 +13281,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -13296,7 +13297,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -13319,16 +13320,16 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - groupKeyMap: 'typing.List[GroupKeyManagement.Structs.GroupKeyMapStruct]' = None - groupTable: 'typing.List[GroupKeyManagement.Structs.GroupInfoMapStruct]' = None - maxGroupsPerFabric: 'uint' = None - maxGroupKeysPerFabric: 'uint' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + groupKeyMap: typing.List[GroupKeyManagement.Structs.GroupKeyMapStruct] = field(default_factory=lambda: []) + groupTable: typing.List[GroupKeyManagement.Structs.GroupInfoMapStruct] = field(default_factory=lambda: []) + maxGroupsPerFabric: uint = 0 + maxGroupKeysPerFabric: uint = 0 + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class GroupKeySecurityPolicyEnum(MatterIntEnum): @@ -13408,7 +13409,7 @@ class KeySetWrite(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x0000003F command_id: typing.ClassVar[int] = 0x00000000 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -13417,7 +13418,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="groupKeySet", Tag=0, Type=GroupKeyManagement.Structs.GroupKeySetStruct), ]) - groupKeySet: 'GroupKeyManagement.Structs.GroupKeySetStruct' = field(default_factory=lambda: GroupKeyManagement.Structs.GroupKeySetStruct()) + groupKeySet: GroupKeyManagement.Structs.GroupKeySetStruct = field(default_factory=lambda: GroupKeyManagement.Structs.GroupKeySetStruct()) @dataclass class KeySetRead(ClusterCommand): @@ -13433,14 +13434,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="groupKeySetID", Tag=0, Type=uint), ]) - groupKeySetID: 'uint' = 0 + groupKeySetID: uint = 0 @dataclass class KeySetReadResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x0000003F command_id: typing.ClassVar[int] = 0x00000002 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -13449,14 +13450,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="groupKeySet", Tag=0, Type=GroupKeyManagement.Structs.GroupKeySetStruct), ]) - groupKeySet: 'GroupKeyManagement.Structs.GroupKeySetStruct' = field(default_factory=lambda: GroupKeyManagement.Structs.GroupKeySetStruct()) + groupKeySet: GroupKeyManagement.Structs.GroupKeySetStruct = field(default_factory=lambda: GroupKeyManagement.Structs.GroupKeySetStruct()) @dataclass class KeySetRemove(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x0000003F command_id: typing.ClassVar[int] = 0x00000003 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -13465,7 +13466,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="groupKeySetID", Tag=0, Type=uint), ]) - groupKeySetID: 'uint' = 0 + groupKeySetID: uint = 0 @dataclass class KeySetReadAllIndices(ClusterCommand): @@ -13485,7 +13486,7 @@ class KeySetReadAllIndicesResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x0000003F command_id: typing.ClassVar[int] = 0x00000005 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -13494,7 +13495,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="groupKeySetIDs", Tag=0, Type=typing.List[uint]), ]) - groupKeySetIDs: 'typing.List[uint]' = field(default_factory=lambda: []) + groupKeySetIDs: typing.List[uint] = field(default_factory=lambda: []) class Attributes: @dataclass @@ -13511,7 +13512,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[GroupKeyManagement.Structs.GroupKeyMapStruct]) - value: 'typing.List[GroupKeyManagement.Structs.GroupKeyMapStruct]' = field(default_factory=lambda: []) + value: typing.List[GroupKeyManagement.Structs.GroupKeyMapStruct] = field(default_factory=lambda: []) @dataclass class GroupTable(ClusterAttributeDescriptor): @@ -13527,7 +13528,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[GroupKeyManagement.Structs.GroupInfoMapStruct]) - value: 'typing.List[GroupKeyManagement.Structs.GroupInfoMapStruct]' = field(default_factory=lambda: []) + value: typing.List[GroupKeyManagement.Structs.GroupInfoMapStruct] = field(default_factory=lambda: []) @dataclass class MaxGroupsPerFabric(ClusterAttributeDescriptor): @@ -13543,7 +13544,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class MaxGroupKeysPerFabric(ClusterAttributeDescriptor): @@ -13559,7 +13560,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -13575,7 +13576,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -13591,7 +13592,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -13607,7 +13608,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -13623,7 +13624,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -13639,7 +13640,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -13655,7 +13656,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -13675,13 +13676,13 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - labelList: 'typing.List[FixedLabel.Structs.LabelStruct]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + labelList: typing.List[FixedLabel.Structs.LabelStruct] = field(default_factory=lambda: []) + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Structs: @dataclass @@ -13712,7 +13713,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[FixedLabel.Structs.LabelStruct]) - value: 'typing.List[FixedLabel.Structs.LabelStruct]' = field(default_factory=lambda: []) + value: typing.List[FixedLabel.Structs.LabelStruct] = field(default_factory=lambda: []) @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -13728,7 +13729,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -13744,7 +13745,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -13760,7 +13761,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -13776,7 +13777,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -13792,7 +13793,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -13808,7 +13809,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -13828,13 +13829,13 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - labelList: 'typing.List[UserLabel.Structs.LabelStruct]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + labelList: typing.List[UserLabel.Structs.LabelStruct] = field(default_factory=lambda: []) + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Structs: @dataclass @@ -13865,7 +13866,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[UserLabel.Structs.LabelStruct]) - value: 'typing.List[UserLabel.Structs.LabelStruct]' = field(default_factory=lambda: []) + value: typing.List[UserLabel.Structs.LabelStruct] = field(default_factory=lambda: []) @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -13881,7 +13882,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -13897,7 +13898,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -13913,7 +13914,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -13929,7 +13930,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -13945,7 +13946,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -13961,7 +13962,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -13980,12 +13981,12 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Attributes: @dataclass @@ -14002,7 +14003,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -14018,7 +14019,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -14034,7 +14035,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -14050,7 +14051,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -14066,7 +14067,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -14082,7 +14083,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -14101,12 +14102,12 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Attributes: @dataclass @@ -14123,7 +14124,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -14139,7 +14140,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -14155,7 +14156,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -14171,7 +14172,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -14187,7 +14188,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -14203,7 +14204,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -14222,12 +14223,12 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Attributes: @dataclass @@ -14244,7 +14245,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -14260,7 +14261,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -14276,7 +14277,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -14292,7 +14293,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -14308,7 +14309,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -14324,7 +14325,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -14344,13 +14345,13 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - stateValue: 'bool' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + stateValue: bool = False + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Attributes: @dataclass @@ -14367,7 +14368,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=bool) - value: 'bool' = False + value: bool = False @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -14383,7 +14384,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -14399,7 +14400,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -14415,7 +14416,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -14431,7 +14432,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -14447,7 +14448,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -14463,7 +14464,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 class Events: @dataclass @@ -14483,7 +14484,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="stateValue", Tag=0, Type=bool), ]) - stateValue: 'bool' = False + stateValue: bool = False @dataclass @@ -14512,22 +14513,22 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - idleModeDuration: 'uint' = None - activeModeDuration: 'uint' = None - activeModeThreshold: 'uint' = None - registeredClients: 'typing.Optional[typing.List[IcdManagement.Structs.MonitoringRegistrationStruct]]' = None - ICDCounter: 'typing.Optional[uint]' = None - clientsSupportedPerFabric: 'typing.Optional[uint]' = None - userActiveModeTriggerHint: 'typing.Optional[uint]' = None - userActiveModeTriggerInstruction: 'typing.Optional[str]' = None - operatingMode: 'typing.Optional[IcdManagement.Enums.OperatingModeEnum]' = None - maximumCheckInBackOff: 'typing.Optional[uint]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + idleModeDuration: uint = 0 + activeModeDuration: uint = 0 + activeModeThreshold: uint = 0 + registeredClients: typing.Optional[typing.List[IcdManagement.Structs.MonitoringRegistrationStruct]] = None + ICDCounter: typing.Optional[uint] = None + clientsSupportedPerFabric: typing.Optional[uint] = None + userActiveModeTriggerHint: typing.Optional[uint] = None + userActiveModeTriggerInstruction: typing.Optional[str] = None + operatingMode: typing.Optional[IcdManagement.Enums.OperatingModeEnum] = None + maximumCheckInBackOff: typing.Optional[uint] = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class ClientTypeEnum(MatterIntEnum): @@ -14611,18 +14612,18 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clientType", Tag=4, Type=IcdManagement.Enums.ClientTypeEnum), ]) - checkInNodeID: 'uint' = 0 - monitoredSubject: 'uint' = 0 - key: 'bytes' = b"" - verificationKey: 'typing.Optional[bytes]' = None - clientType: 'IcdManagement.Enums.ClientTypeEnum' = 0 + checkInNodeID: uint = 0 + monitoredSubject: uint = 0 + key: bytes = b"" + verificationKey: typing.Optional[bytes] = None + clientType: IcdManagement.Enums.ClientTypeEnum = 0 @dataclass class RegisterClientResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000046 command_id: typing.ClassVar[int] = 0x00000001 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -14631,14 +14632,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="ICDCounter", Tag=0, Type=uint), ]) - ICDCounter: 'uint' = 0 + ICDCounter: uint = 0 @dataclass class UnregisterClient(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000046 command_id: typing.ClassVar[int] = 0x00000002 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -14648,8 +14649,8 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="verificationKey", Tag=1, Type=typing.Optional[bytes]), ]) - checkInNodeID: 'uint' = 0 - verificationKey: 'typing.Optional[bytes]' = None + checkInNodeID: uint = 0 + verificationKey: typing.Optional[bytes] = None @dataclass class StayActiveRequest(ClusterCommand): @@ -14665,14 +14666,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="stayActiveDuration", Tag=0, Type=uint), ]) - stayActiveDuration: 'uint' = 0 + stayActiveDuration: uint = 0 @dataclass class StayActiveResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000046 command_id: typing.ClassVar[int] = 0x00000004 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -14681,7 +14682,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="promisedActiveDuration", Tag=0, Type=uint), ]) - promisedActiveDuration: 'uint' = 0 + promisedActiveDuration: uint = 0 class Attributes: @dataclass @@ -14698,7 +14699,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ActiveModeDuration(ClusterAttributeDescriptor): @@ -14714,7 +14715,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ActiveModeThreshold(ClusterAttributeDescriptor): @@ -14730,7 +14731,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class RegisteredClients(ClusterAttributeDescriptor): @@ -14746,7 +14747,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[typing.List[IcdManagement.Structs.MonitoringRegistrationStruct]]) - value: 'typing.Optional[typing.List[IcdManagement.Structs.MonitoringRegistrationStruct]]' = None + value: typing.Optional[typing.List[IcdManagement.Structs.MonitoringRegistrationStruct]] = None @dataclass class ICDCounter(ClusterAttributeDescriptor): @@ -14762,7 +14763,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class ClientsSupportedPerFabric(ClusterAttributeDescriptor): @@ -14778,7 +14779,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class UserActiveModeTriggerHint(ClusterAttributeDescriptor): @@ -14794,7 +14795,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class UserActiveModeTriggerInstruction(ClusterAttributeDescriptor): @@ -14810,7 +14811,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[str]) - value: 'typing.Optional[str]' = None + value: typing.Optional[str] = None @dataclass class OperatingMode(ClusterAttributeDescriptor): @@ -14826,7 +14827,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[IcdManagement.Enums.OperatingModeEnum]) - value: 'typing.Optional[IcdManagement.Enums.OperatingModeEnum]' = None + value: typing.Optional[IcdManagement.Enums.OperatingModeEnum] = None @dataclass class MaximumCheckInBackOff(ClusterAttributeDescriptor): @@ -14842,7 +14843,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -14858,7 +14859,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -14874,7 +14875,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -14890,7 +14891,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -14906,7 +14907,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -14922,7 +14923,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -14938,7 +14939,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -14960,15 +14961,15 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - setTime: 'uint' = None - timeRemaining: 'uint' = None - timerState: 'Timer.Enums.TimerStatusEnum' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + setTime: uint = 0 + timeRemaining: uint = 0 + timerState: Timer.Enums.TimerStatusEnum = 0 + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class TimerStatusEnum(MatterIntEnum): @@ -14992,7 +14993,7 @@ class SetTimer(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000047 command_id: typing.ClassVar[int] = 0x00000000 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -15001,14 +15002,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="newTime", Tag=0, Type=uint), ]) - newTime: 'uint' = 0 + newTime: uint = 0 @dataclass class ResetTimer(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000047 command_id: typing.ClassVar[int] = 0x00000001 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -15021,7 +15022,7 @@ class AddTime(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000047 command_id: typing.ClassVar[int] = 0x00000002 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -15030,14 +15031,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="additionalTime", Tag=0, Type=uint), ]) - additionalTime: 'uint' = 0 + additionalTime: uint = 0 @dataclass class ReduceTime(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000047 command_id: typing.ClassVar[int] = 0x00000003 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -15046,7 +15047,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="timeReduction", Tag=0, Type=uint), ]) - timeReduction: 'uint' = 0 + timeReduction: uint = 0 class Attributes: @dataclass @@ -15063,7 +15064,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class TimeRemaining(ClusterAttributeDescriptor): @@ -15079,7 +15080,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class TimerState(ClusterAttributeDescriptor): @@ -15095,7 +15096,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=Timer.Enums.TimerStatusEnum) - value: 'Timer.Enums.TimerStatusEnum' = 0 + value: Timer.Enums.TimerStatusEnum = 0 @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -15111,7 +15112,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -15127,7 +15128,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -15143,7 +15144,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -15159,7 +15160,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -15175,7 +15176,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -15191,7 +15192,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -15216,18 +15217,18 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - phaseList: 'typing.Union[Nullable, typing.List[str]]' = None - currentPhase: 'typing.Union[Nullable, uint]' = None - countdownTime: 'typing.Union[None, Nullable, uint]' = None - operationalStateList: 'typing.List[OvenCavityOperationalState.Structs.OperationalStateStruct]' = None - operationalState: 'OvenCavityOperationalState.Enums.OperationalStateEnum' = None - operationalError: 'OvenCavityOperationalState.Structs.ErrorStateStruct' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + phaseList: typing.Union[Nullable, typing.List[str]] = NullValue + currentPhase: typing.Union[Nullable, uint] = NullValue + countdownTime: typing.Union[None, Nullable, uint] = None + operationalStateList: typing.List[OvenCavityOperationalState.Structs.OperationalStateStruct] = field(default_factory=lambda: []) + operationalState: OvenCavityOperationalState.Enums.OperationalStateEnum = 0 + operationalError: OvenCavityOperationalState.Structs.ErrorStateStruct = field(default_factory=lambda: OvenCavityOperationalState.Structs.ErrorStateStruct()) + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class ErrorStateEnum(MatterIntEnum): @@ -15339,7 +15340,7 @@ class OperationalCommandResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000048 command_id: typing.ClassVar[int] = 0x00000004 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -15348,7 +15349,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="commandResponseState", Tag=0, Type=OvenCavityOperationalState.Structs.ErrorStateStruct), ]) - commandResponseState: 'OvenCavityOperationalState.Structs.ErrorStateStruct' = field(default_factory=lambda: OvenCavityOperationalState.Structs.ErrorStateStruct()) + commandResponseState: OvenCavityOperationalState.Structs.ErrorStateStruct = field(default_factory=lambda: OvenCavityOperationalState.Structs.ErrorStateStruct()) class Attributes: @dataclass @@ -15365,7 +15366,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, typing.List[str]]) - value: 'typing.Union[Nullable, typing.List[str]]' = NullValue + value: typing.Union[Nullable, typing.List[str]] = NullValue @dataclass class CurrentPhase(ClusterAttributeDescriptor): @@ -15381,7 +15382,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, uint]) - value: 'typing.Union[Nullable, uint]' = NullValue + value: typing.Union[Nullable, uint] = NullValue @dataclass class CountdownTime(ClusterAttributeDescriptor): @@ -15397,7 +15398,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class OperationalStateList(ClusterAttributeDescriptor): @@ -15413,7 +15414,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[OvenCavityOperationalState.Structs.OperationalStateStruct]) - value: 'typing.List[OvenCavityOperationalState.Structs.OperationalStateStruct]' = field(default_factory=lambda: []) + value: typing.List[OvenCavityOperationalState.Structs.OperationalStateStruct] = field(default_factory=lambda: []) @dataclass class OperationalState(ClusterAttributeDescriptor): @@ -15429,7 +15430,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=OvenCavityOperationalState.Enums.OperationalStateEnum) - value: 'OvenCavityOperationalState.Enums.OperationalStateEnum' = 0 + value: OvenCavityOperationalState.Enums.OperationalStateEnum = 0 @dataclass class OperationalError(ClusterAttributeDescriptor): @@ -15445,7 +15446,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=OvenCavityOperationalState.Structs.ErrorStateStruct) - value: 'OvenCavityOperationalState.Structs.ErrorStateStruct' = field(default_factory=lambda: OvenCavityOperationalState.Structs.ErrorStateStruct()) + value: OvenCavityOperationalState.Structs.ErrorStateStruct = field(default_factory=lambda: OvenCavityOperationalState.Structs.ErrorStateStruct()) @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -15461,7 +15462,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -15477,7 +15478,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -15493,7 +15494,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -15509,7 +15510,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -15525,7 +15526,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -15541,7 +15542,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 class Events: @dataclass @@ -15561,7 +15562,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="errorState", Tag=0, Type=OvenCavityOperationalState.Structs.ErrorStateStruct), ]) - errorState: 'OvenCavityOperationalState.Structs.ErrorStateStruct' = field(default_factory=lambda: OvenCavityOperationalState.Structs.ErrorStateStruct()) + errorState: OvenCavityOperationalState.Structs.ErrorStateStruct = field(default_factory=lambda: OvenCavityOperationalState.Structs.ErrorStateStruct()) @dataclass class OperationCompletion(ClusterEvent): @@ -15582,9 +15583,9 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="pausedTime", Tag=2, Type=typing.Union[None, Nullable, uint]), ]) - completionErrorCode: 'uint' = 0 - totalOperationalTime: 'typing.Union[None, Nullable, uint]' = None - pausedTime: 'typing.Union[None, Nullable, uint]' = None + completionErrorCode: uint = 0 + totalOperationalTime: typing.Union[None, Nullable, uint] = None + pausedTime: typing.Union[None, Nullable, uint] = None @dataclass @@ -15607,16 +15608,16 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - supportedModes: 'typing.List[OvenMode.Structs.ModeOptionStruct]' = None - currentMode: 'uint' = None - startUpMode: 'typing.Union[None, Nullable, uint]' = None - onMode: 'typing.Union[None, Nullable, uint]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + supportedModes: typing.List[OvenMode.Structs.ModeOptionStruct] = field(default_factory=lambda: []) + currentMode: uint = 0 + startUpMode: typing.Union[None, Nullable, uint] = None + onMode: typing.Union[None, Nullable, uint] = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class ModeTag(MatterIntEnum): @@ -15693,14 +15694,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="newMode", Tag=0, Type=uint), ]) - newMode: 'uint' = 0 + newMode: uint = 0 @dataclass class ChangeToModeResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000049 command_id: typing.ClassVar[int] = 0x00000001 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -15710,8 +15711,8 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="statusText", Tag=1, Type=typing.Optional[str]), ]) - status: 'uint' = 0 - statusText: 'typing.Optional[str]' = None + status: uint = 0 + statusText: typing.Optional[str] = None class Attributes: @dataclass @@ -15728,7 +15729,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[OvenMode.Structs.ModeOptionStruct]) - value: 'typing.List[OvenMode.Structs.ModeOptionStruct]' = field(default_factory=lambda: []) + value: typing.List[OvenMode.Structs.ModeOptionStruct] = field(default_factory=lambda: []) @dataclass class CurrentMode(ClusterAttributeDescriptor): @@ -15744,7 +15745,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class StartUpMode(ClusterAttributeDescriptor): @@ -15760,7 +15761,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class OnMode(ClusterAttributeDescriptor): @@ -15776,7 +15777,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -15792,7 +15793,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -15808,7 +15809,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -15824,7 +15825,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -15840,7 +15841,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -15856,7 +15857,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -15872,7 +15873,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -15893,14 +15894,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - supportedDrynessLevels: 'typing.List[LaundryDryerControls.Enums.DrynessLevelEnum]' = None - selectedDrynessLevel: 'typing.Union[Nullable, LaundryDryerControls.Enums.DrynessLevelEnum]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + supportedDrynessLevels: typing.List[LaundryDryerControls.Enums.DrynessLevelEnum] = field(default_factory=lambda: []) + selectedDrynessLevel: typing.Union[Nullable, LaundryDryerControls.Enums.DrynessLevelEnum] = NullValue + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class DrynessLevelEnum(MatterIntEnum): @@ -15929,7 +15930,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[LaundryDryerControls.Enums.DrynessLevelEnum]) - value: 'typing.List[LaundryDryerControls.Enums.DrynessLevelEnum]' = field(default_factory=lambda: []) + value: typing.List[LaundryDryerControls.Enums.DrynessLevelEnum] = field(default_factory=lambda: []) @dataclass class SelectedDrynessLevel(ClusterAttributeDescriptor): @@ -15945,7 +15946,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, LaundryDryerControls.Enums.DrynessLevelEnum]) - value: 'typing.Union[Nullable, LaundryDryerControls.Enums.DrynessLevelEnum]' = NullValue + value: typing.Union[Nullable, LaundryDryerControls.Enums.DrynessLevelEnum] = NullValue @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -15961,7 +15962,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -15977,7 +15978,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -15993,7 +15994,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -16009,7 +16010,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -16025,7 +16026,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -16041,7 +16042,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -16066,18 +16067,18 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - description: 'str' = None - standardNamespace: 'typing.Union[Nullable, uint]' = None - supportedModes: 'typing.List[ModeSelect.Structs.ModeOptionStruct]' = None - currentMode: 'uint' = None - startUpMode: 'typing.Union[None, Nullable, uint]' = None - onMode: 'typing.Union[None, Nullable, uint]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + description: str = "" + standardNamespace: typing.Union[Nullable, uint] = NullValue + supportedModes: typing.List[ModeSelect.Structs.ModeOptionStruct] = field(default_factory=lambda: []) + currentMode: uint = 0 + startUpMode: typing.Union[None, Nullable, uint] = None + onMode: typing.Union[None, Nullable, uint] = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Bitmaps: class Feature(IntFlag): @@ -16118,7 +16119,7 @@ class ChangeToMode(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000050 command_id: typing.ClassVar[int] = 0x00000000 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -16127,7 +16128,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="newMode", Tag=0, Type=uint), ]) - newMode: 'uint' = 0 + newMode: uint = 0 class Attributes: @dataclass @@ -16144,7 +16145,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=str) - value: 'str' = "" + value: str = "" @dataclass class StandardNamespace(ClusterAttributeDescriptor): @@ -16160,7 +16161,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, uint]) - value: 'typing.Union[Nullable, uint]' = NullValue + value: typing.Union[Nullable, uint] = NullValue @dataclass class SupportedModes(ClusterAttributeDescriptor): @@ -16176,7 +16177,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[ModeSelect.Structs.ModeOptionStruct]) - value: 'typing.List[ModeSelect.Structs.ModeOptionStruct]' = field(default_factory=lambda: []) + value: typing.List[ModeSelect.Structs.ModeOptionStruct] = field(default_factory=lambda: []) @dataclass class CurrentMode(ClusterAttributeDescriptor): @@ -16192,7 +16193,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class StartUpMode(ClusterAttributeDescriptor): @@ -16208,7 +16209,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class OnMode(ClusterAttributeDescriptor): @@ -16224,7 +16225,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -16240,7 +16241,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -16256,7 +16257,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -16272,7 +16273,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -16288,7 +16289,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -16304,7 +16305,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -16320,7 +16321,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -16343,16 +16344,16 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - supportedModes: 'typing.List[LaundryWasherMode.Structs.ModeOptionStruct]' = None - currentMode: 'uint' = None - startUpMode: 'typing.Union[None, Nullable, uint]' = None - onMode: 'typing.Union[None, Nullable, uint]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + supportedModes: typing.List[LaundryWasherMode.Structs.ModeOptionStruct] = field(default_factory=lambda: []) + currentMode: uint = 0 + startUpMode: typing.Union[None, Nullable, uint] = None + onMode: typing.Union[None, Nullable, uint] = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class ModeTag(MatterIntEnum): @@ -16424,14 +16425,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="newMode", Tag=0, Type=uint), ]) - newMode: 'uint' = 0 + newMode: uint = 0 @dataclass class ChangeToModeResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000051 command_id: typing.ClassVar[int] = 0x00000001 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -16441,8 +16442,8 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="statusText", Tag=1, Type=typing.Optional[str]), ]) - status: 'uint' = 0 - statusText: 'typing.Optional[str]' = None + status: uint = 0 + statusText: typing.Optional[str] = None class Attributes: @dataclass @@ -16459,7 +16460,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[LaundryWasherMode.Structs.ModeOptionStruct]) - value: 'typing.List[LaundryWasherMode.Structs.ModeOptionStruct]' = field(default_factory=lambda: []) + value: typing.List[LaundryWasherMode.Structs.ModeOptionStruct] = field(default_factory=lambda: []) @dataclass class CurrentMode(ClusterAttributeDescriptor): @@ -16475,7 +16476,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class StartUpMode(ClusterAttributeDescriptor): @@ -16491,7 +16492,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class OnMode(ClusterAttributeDescriptor): @@ -16507,7 +16508,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -16523,7 +16524,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -16539,7 +16540,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -16555,7 +16556,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -16571,7 +16572,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -16587,7 +16588,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -16603,7 +16604,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -16626,16 +16627,16 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - supportedModes: 'typing.List[RefrigeratorAndTemperatureControlledCabinetMode.Structs.ModeOptionStruct]' = None - currentMode: 'uint' = None - startUpMode: 'typing.Union[None, Nullable, uint]' = None - onMode: 'typing.Union[None, Nullable, uint]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + supportedModes: typing.List[RefrigeratorAndTemperatureControlledCabinetMode.Structs.ModeOptionStruct] = field(default_factory=lambda: []) + currentMode: uint = 0 + startUpMode: typing.Union[None, Nullable, uint] = None + onMode: typing.Union[None, Nullable, uint] = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class ModeTag(MatterIntEnum): @@ -16705,14 +16706,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="newMode", Tag=0, Type=uint), ]) - newMode: 'uint' = 0 + newMode: uint = 0 @dataclass class ChangeToModeResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000052 command_id: typing.ClassVar[int] = 0x00000001 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -16722,8 +16723,8 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="statusText", Tag=1, Type=typing.Optional[str]), ]) - status: 'uint' = 0 - statusText: 'typing.Optional[str]' = None + status: uint = 0 + statusText: typing.Optional[str] = None class Attributes: @dataclass @@ -16740,7 +16741,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[RefrigeratorAndTemperatureControlledCabinetMode.Structs.ModeOptionStruct]) - value: 'typing.List[RefrigeratorAndTemperatureControlledCabinetMode.Structs.ModeOptionStruct]' = field(default_factory=lambda: []) + value: typing.List[RefrigeratorAndTemperatureControlledCabinetMode.Structs.ModeOptionStruct] = field(default_factory=lambda: []) @dataclass class CurrentMode(ClusterAttributeDescriptor): @@ -16756,7 +16757,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class StartUpMode(ClusterAttributeDescriptor): @@ -16772,7 +16773,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class OnMode(ClusterAttributeDescriptor): @@ -16788,7 +16789,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -16804,7 +16805,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -16820,7 +16821,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -16836,7 +16837,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -16852,7 +16853,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -16868,7 +16869,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -16884,7 +16885,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -16907,16 +16908,16 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - spinSpeeds: 'typing.Optional[typing.List[str]]' = None - spinSpeedCurrent: 'typing.Union[None, Nullable, uint]' = None - numberOfRinses: 'typing.Optional[LaundryWasherControls.Enums.NumberOfRinsesEnum]' = None - supportedRinses: 'typing.Optional[typing.List[LaundryWasherControls.Enums.NumberOfRinsesEnum]]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + spinSpeeds: typing.Optional[typing.List[str]] = None + spinSpeedCurrent: typing.Union[None, Nullable, uint] = None + numberOfRinses: typing.Optional[LaundryWasherControls.Enums.NumberOfRinsesEnum] = None + supportedRinses: typing.Optional[typing.List[LaundryWasherControls.Enums.NumberOfRinsesEnum]] = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class NumberOfRinsesEnum(MatterIntEnum): @@ -16950,7 +16951,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[typing.List[str]]) - value: 'typing.Optional[typing.List[str]]' = None + value: typing.Optional[typing.List[str]] = None @dataclass class SpinSpeedCurrent(ClusterAttributeDescriptor): @@ -16966,7 +16967,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class NumberOfRinses(ClusterAttributeDescriptor): @@ -16982,7 +16983,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[LaundryWasherControls.Enums.NumberOfRinsesEnum]) - value: 'typing.Optional[LaundryWasherControls.Enums.NumberOfRinsesEnum]' = None + value: typing.Optional[LaundryWasherControls.Enums.NumberOfRinsesEnum] = None @dataclass class SupportedRinses(ClusterAttributeDescriptor): @@ -16998,7 +16999,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[typing.List[LaundryWasherControls.Enums.NumberOfRinsesEnum]]) - value: 'typing.Optional[typing.List[LaundryWasherControls.Enums.NumberOfRinsesEnum]]' = None + value: typing.Optional[typing.List[LaundryWasherControls.Enums.NumberOfRinsesEnum]] = None @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -17014,7 +17015,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -17030,7 +17031,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -17046,7 +17047,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -17062,7 +17063,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -17078,7 +17079,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -17094,7 +17095,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -17115,14 +17116,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - supportedModes: 'typing.List[RvcRunMode.Structs.ModeOptionStruct]' = None - currentMode: 'uint' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + supportedModes: typing.List[RvcRunMode.Structs.ModeOptionStruct] = field(default_factory=lambda: []) + currentMode: uint = 0 + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class ModeTag(MatterIntEnum): @@ -17208,14 +17209,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="newMode", Tag=0, Type=uint), ]) - newMode: 'uint' = 0 + newMode: uint = 0 @dataclass class ChangeToModeResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000054 command_id: typing.ClassVar[int] = 0x00000001 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -17225,8 +17226,8 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="statusText", Tag=1, Type=typing.Optional[str]), ]) - status: 'uint' = 0 - statusText: 'typing.Optional[str]' = None + status: uint = 0 + statusText: typing.Optional[str] = None class Attributes: @dataclass @@ -17243,7 +17244,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[RvcRunMode.Structs.ModeOptionStruct]) - value: 'typing.List[RvcRunMode.Structs.ModeOptionStruct]' = field(default_factory=lambda: []) + value: typing.List[RvcRunMode.Structs.ModeOptionStruct] = field(default_factory=lambda: []) @dataclass class CurrentMode(ClusterAttributeDescriptor): @@ -17259,7 +17260,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -17275,7 +17276,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -17291,7 +17292,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -17307,7 +17308,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -17323,7 +17324,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -17339,7 +17340,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -17355,7 +17356,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -17376,14 +17377,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - supportedModes: 'typing.List[RvcCleanMode.Structs.ModeOptionStruct]' = None - currentMode: 'uint' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + supportedModes: typing.List[RvcCleanMode.Structs.ModeOptionStruct] = field(default_factory=lambda: []) + currentMode: uint = 0 + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class ModeTag(MatterIntEnum): @@ -17462,14 +17463,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="newMode", Tag=0, Type=uint), ]) - newMode: 'uint' = 0 + newMode: uint = 0 @dataclass class ChangeToModeResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000055 command_id: typing.ClassVar[int] = 0x00000001 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -17479,8 +17480,8 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="statusText", Tag=1, Type=typing.Optional[str]), ]) - status: 'uint' = 0 - statusText: 'typing.Optional[str]' = None + status: uint = 0 + statusText: typing.Optional[str] = None class Attributes: @dataclass @@ -17497,7 +17498,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[RvcCleanMode.Structs.ModeOptionStruct]) - value: 'typing.List[RvcCleanMode.Structs.ModeOptionStruct]' = field(default_factory=lambda: []) + value: typing.List[RvcCleanMode.Structs.ModeOptionStruct] = field(default_factory=lambda: []) @dataclass class CurrentMode(ClusterAttributeDescriptor): @@ -17513,7 +17514,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -17529,7 +17530,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -17545,7 +17546,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -17561,7 +17562,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -17577,7 +17578,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -17593,7 +17594,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -17609,7 +17610,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -17634,18 +17635,18 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - temperatureSetpoint: 'typing.Optional[int]' = None - minTemperature: 'typing.Optional[int]' = None - maxTemperature: 'typing.Optional[int]' = None - step: 'typing.Optional[int]' = None - selectedTemperatureLevel: 'typing.Optional[uint]' = None - supportedTemperatureLevels: 'typing.Optional[typing.List[str]]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + temperatureSetpoint: typing.Optional[int] = None + minTemperature: typing.Optional[int] = None + maxTemperature: typing.Optional[int] = None + step: typing.Optional[int] = None + selectedTemperatureLevel: typing.Optional[uint] = None + supportedTemperatureLevels: typing.Optional[typing.List[str]] = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Bitmaps: class Feature(IntFlag): @@ -17659,7 +17660,7 @@ class SetTemperature(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000056 command_id: typing.ClassVar[int] = 0x00000000 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -17669,8 +17670,8 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="targetTemperatureLevel", Tag=1, Type=typing.Optional[uint]), ]) - targetTemperature: 'typing.Optional[int]' = None - targetTemperatureLevel: 'typing.Optional[uint]' = None + targetTemperature: typing.Optional[int] = None + targetTemperatureLevel: typing.Optional[uint] = None class Attributes: @dataclass @@ -17687,7 +17688,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[int]) - value: 'typing.Optional[int]' = None + value: typing.Optional[int] = None @dataclass class MinTemperature(ClusterAttributeDescriptor): @@ -17703,7 +17704,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[int]) - value: 'typing.Optional[int]' = None + value: typing.Optional[int] = None @dataclass class MaxTemperature(ClusterAttributeDescriptor): @@ -17719,7 +17720,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[int]) - value: 'typing.Optional[int]' = None + value: typing.Optional[int] = None @dataclass class Step(ClusterAttributeDescriptor): @@ -17735,7 +17736,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[int]) - value: 'typing.Optional[int]' = None + value: typing.Optional[int] = None @dataclass class SelectedTemperatureLevel(ClusterAttributeDescriptor): @@ -17751,7 +17752,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class SupportedTemperatureLevels(ClusterAttributeDescriptor): @@ -17767,7 +17768,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[typing.List[str]]) - value: 'typing.Optional[typing.List[str]]' = None + value: typing.Optional[typing.List[str]] = None @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -17783,7 +17784,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -17799,7 +17800,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -17815,7 +17816,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -17831,7 +17832,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -17847,7 +17848,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -17863,7 +17864,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -17885,15 +17886,15 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - mask: 'uint' = None - state: 'uint' = None - supported: 'uint' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + mask: uint = 0 + state: uint = 0 + supported: uint = 0 + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Bitmaps: class AlarmBitmap(IntFlag): @@ -17914,7 +17915,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class State(ClusterAttributeDescriptor): @@ -17930,7 +17931,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class Supported(ClusterAttributeDescriptor): @@ -17946,7 +17947,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -17962,7 +17963,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -17978,7 +17979,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -17994,7 +17995,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -18010,7 +18011,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -18026,7 +18027,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -18042,7 +18043,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 class Events: @dataclass @@ -18065,10 +18066,10 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="mask", Tag=3, Type=uint), ]) - active: 'uint' = 0 - inactive: 'uint' = 0 - state: 'uint' = 0 - mask: 'uint' = 0 + active: uint = 0 + inactive: uint = 0 + state: uint = 0 + mask: uint = 0 @dataclass @@ -18091,16 +18092,16 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - supportedModes: 'typing.List[DishwasherMode.Structs.ModeOptionStruct]' = None - currentMode: 'uint' = None - startUpMode: 'typing.Union[None, Nullable, uint]' = None - onMode: 'typing.Union[None, Nullable, uint]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + supportedModes: typing.List[DishwasherMode.Structs.ModeOptionStruct] = field(default_factory=lambda: []) + currentMode: uint = 0 + startUpMode: typing.Union[None, Nullable, uint] = None + onMode: typing.Union[None, Nullable, uint] = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class ModeTag(MatterIntEnum): @@ -18171,14 +18172,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="newMode", Tag=0, Type=uint), ]) - newMode: 'uint' = 0 + newMode: uint = 0 @dataclass class ChangeToModeResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000059 command_id: typing.ClassVar[int] = 0x00000001 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -18188,8 +18189,8 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="statusText", Tag=1, Type=typing.Optional[str]), ]) - status: 'uint' = 0 - statusText: 'typing.Optional[str]' = None + status: uint = 0 + statusText: typing.Optional[str] = None class Attributes: @dataclass @@ -18206,7 +18207,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[DishwasherMode.Structs.ModeOptionStruct]) - value: 'typing.List[DishwasherMode.Structs.ModeOptionStruct]' = field(default_factory=lambda: []) + value: typing.List[DishwasherMode.Structs.ModeOptionStruct] = field(default_factory=lambda: []) @dataclass class CurrentMode(ClusterAttributeDescriptor): @@ -18222,7 +18223,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class StartUpMode(ClusterAttributeDescriptor): @@ -18238,7 +18239,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class OnMode(ClusterAttributeDescriptor): @@ -18254,7 +18255,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -18270,7 +18271,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -18286,7 +18287,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -18302,7 +18303,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -18318,7 +18319,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -18334,7 +18335,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -18350,7 +18351,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -18370,13 +18371,13 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - airQuality: 'AirQuality.Enums.AirQualityEnum' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + airQuality: AirQuality.Enums.AirQualityEnum = 0 + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class AirQualityEnum(MatterIntEnum): @@ -18415,7 +18416,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=AirQuality.Enums.AirQualityEnum) - value: 'AirQuality.Enums.AirQualityEnum' = 0 + value: AirQuality.Enums.AirQualityEnum = 0 @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -18431,7 +18432,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -18447,7 +18448,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -18463,7 +18464,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -18479,7 +18480,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -18495,7 +18496,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -18511,7 +18512,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -18543,25 +18544,25 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - expressedState: 'SmokeCoAlarm.Enums.ExpressedStateEnum' = None - smokeState: 'typing.Optional[SmokeCoAlarm.Enums.AlarmStateEnum]' = None - COState: 'typing.Optional[SmokeCoAlarm.Enums.AlarmStateEnum]' = None - batteryAlert: 'SmokeCoAlarm.Enums.AlarmStateEnum' = None - deviceMuted: 'typing.Optional[SmokeCoAlarm.Enums.MuteStateEnum]' = None - testInProgress: 'bool' = None - hardwareFaultAlert: 'bool' = None - endOfServiceAlert: 'SmokeCoAlarm.Enums.EndOfServiceEnum' = None - interconnectSmokeAlarm: 'typing.Optional[SmokeCoAlarm.Enums.AlarmStateEnum]' = None - interconnectCOAlarm: 'typing.Optional[SmokeCoAlarm.Enums.AlarmStateEnum]' = None - contaminationState: 'typing.Optional[SmokeCoAlarm.Enums.ContaminationStateEnum]' = None - smokeSensitivityLevel: 'typing.Optional[SmokeCoAlarm.Enums.SensitivityEnum]' = None - expiryDate: 'typing.Optional[uint]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + expressedState: SmokeCoAlarm.Enums.ExpressedStateEnum = 0 + smokeState: typing.Optional[SmokeCoAlarm.Enums.AlarmStateEnum] = None + COState: typing.Optional[SmokeCoAlarm.Enums.AlarmStateEnum] = None + batteryAlert: SmokeCoAlarm.Enums.AlarmStateEnum = 0 + deviceMuted: typing.Optional[SmokeCoAlarm.Enums.MuteStateEnum] = None + testInProgress: bool = False + hardwareFaultAlert: bool = False + endOfServiceAlert: SmokeCoAlarm.Enums.EndOfServiceEnum = 0 + interconnectSmokeAlarm: typing.Optional[SmokeCoAlarm.Enums.AlarmStateEnum] = None + interconnectCOAlarm: typing.Optional[SmokeCoAlarm.Enums.AlarmStateEnum] = None + contaminationState: typing.Optional[SmokeCoAlarm.Enums.ContaminationStateEnum] = None + smokeSensitivityLevel: typing.Optional[SmokeCoAlarm.Enums.SensitivityEnum] = None + expiryDate: typing.Optional[uint] = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class AlarmStateEnum(MatterIntEnum): @@ -18640,7 +18641,7 @@ class SelfTestRequest(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x0000005C command_id: typing.ClassVar[int] = 0x00000000 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -18663,7 +18664,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=SmokeCoAlarm.Enums.ExpressedStateEnum) - value: 'SmokeCoAlarm.Enums.ExpressedStateEnum' = 0 + value: SmokeCoAlarm.Enums.ExpressedStateEnum = 0 @dataclass class SmokeState(ClusterAttributeDescriptor): @@ -18679,7 +18680,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[SmokeCoAlarm.Enums.AlarmStateEnum]) - value: 'typing.Optional[SmokeCoAlarm.Enums.AlarmStateEnum]' = None + value: typing.Optional[SmokeCoAlarm.Enums.AlarmStateEnum] = None @dataclass class COState(ClusterAttributeDescriptor): @@ -18695,7 +18696,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[SmokeCoAlarm.Enums.AlarmStateEnum]) - value: 'typing.Optional[SmokeCoAlarm.Enums.AlarmStateEnum]' = None + value: typing.Optional[SmokeCoAlarm.Enums.AlarmStateEnum] = None @dataclass class BatteryAlert(ClusterAttributeDescriptor): @@ -18711,7 +18712,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=SmokeCoAlarm.Enums.AlarmStateEnum) - value: 'SmokeCoAlarm.Enums.AlarmStateEnum' = 0 + value: SmokeCoAlarm.Enums.AlarmStateEnum = 0 @dataclass class DeviceMuted(ClusterAttributeDescriptor): @@ -18727,7 +18728,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[SmokeCoAlarm.Enums.MuteStateEnum]) - value: 'typing.Optional[SmokeCoAlarm.Enums.MuteStateEnum]' = None + value: typing.Optional[SmokeCoAlarm.Enums.MuteStateEnum] = None @dataclass class TestInProgress(ClusterAttributeDescriptor): @@ -18743,7 +18744,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=bool) - value: 'bool' = False + value: bool = False @dataclass class HardwareFaultAlert(ClusterAttributeDescriptor): @@ -18759,7 +18760,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=bool) - value: 'bool' = False + value: bool = False @dataclass class EndOfServiceAlert(ClusterAttributeDescriptor): @@ -18775,7 +18776,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=SmokeCoAlarm.Enums.EndOfServiceEnum) - value: 'SmokeCoAlarm.Enums.EndOfServiceEnum' = 0 + value: SmokeCoAlarm.Enums.EndOfServiceEnum = 0 @dataclass class InterconnectSmokeAlarm(ClusterAttributeDescriptor): @@ -18791,7 +18792,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[SmokeCoAlarm.Enums.AlarmStateEnum]) - value: 'typing.Optional[SmokeCoAlarm.Enums.AlarmStateEnum]' = None + value: typing.Optional[SmokeCoAlarm.Enums.AlarmStateEnum] = None @dataclass class InterconnectCOAlarm(ClusterAttributeDescriptor): @@ -18807,7 +18808,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[SmokeCoAlarm.Enums.AlarmStateEnum]) - value: 'typing.Optional[SmokeCoAlarm.Enums.AlarmStateEnum]' = None + value: typing.Optional[SmokeCoAlarm.Enums.AlarmStateEnum] = None @dataclass class ContaminationState(ClusterAttributeDescriptor): @@ -18823,7 +18824,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[SmokeCoAlarm.Enums.ContaminationStateEnum]) - value: 'typing.Optional[SmokeCoAlarm.Enums.ContaminationStateEnum]' = None + value: typing.Optional[SmokeCoAlarm.Enums.ContaminationStateEnum] = None @dataclass class SmokeSensitivityLevel(ClusterAttributeDescriptor): @@ -18839,7 +18840,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[SmokeCoAlarm.Enums.SensitivityEnum]) - value: 'typing.Optional[SmokeCoAlarm.Enums.SensitivityEnum]' = None + value: typing.Optional[SmokeCoAlarm.Enums.SensitivityEnum] = None @dataclass class ExpiryDate(ClusterAttributeDescriptor): @@ -18855,7 +18856,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -18871,7 +18872,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -18887,7 +18888,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -18903,7 +18904,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -18919,7 +18920,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -18935,7 +18936,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -18951,7 +18952,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 class Events: @dataclass @@ -18971,7 +18972,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="alarmSeverityLevel", Tag=0, Type=SmokeCoAlarm.Enums.AlarmStateEnum), ]) - alarmSeverityLevel: 'SmokeCoAlarm.Enums.AlarmStateEnum' = 0 + alarmSeverityLevel: SmokeCoAlarm.Enums.AlarmStateEnum = 0 @dataclass class COAlarm(ClusterEvent): @@ -18990,7 +18991,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="alarmSeverityLevel", Tag=0, Type=SmokeCoAlarm.Enums.AlarmStateEnum), ]) - alarmSeverityLevel: 'SmokeCoAlarm.Enums.AlarmStateEnum' = 0 + alarmSeverityLevel: SmokeCoAlarm.Enums.AlarmStateEnum = 0 @dataclass class LowBattery(ClusterEvent): @@ -19009,7 +19010,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="alarmSeverityLevel", Tag=0, Type=SmokeCoAlarm.Enums.AlarmStateEnum), ]) - alarmSeverityLevel: 'SmokeCoAlarm.Enums.AlarmStateEnum' = 0 + alarmSeverityLevel: SmokeCoAlarm.Enums.AlarmStateEnum = 0 @dataclass class HardwareFault(ClusterEvent): @@ -19108,7 +19109,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="alarmSeverityLevel", Tag=0, Type=SmokeCoAlarm.Enums.AlarmStateEnum), ]) - alarmSeverityLevel: 'SmokeCoAlarm.Enums.AlarmStateEnum' = 0 + alarmSeverityLevel: SmokeCoAlarm.Enums.AlarmStateEnum = 0 @dataclass class InterconnectCOAlarm(ClusterEvent): @@ -19127,7 +19128,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="alarmSeverityLevel", Tag=0, Type=SmokeCoAlarm.Enums.AlarmStateEnum), ]) - alarmSeverityLevel: 'SmokeCoAlarm.Enums.AlarmStateEnum' = 0 + alarmSeverityLevel: SmokeCoAlarm.Enums.AlarmStateEnum = 0 @dataclass class AllClear(ClusterEvent): @@ -19166,16 +19167,16 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - mask: 'uint' = None - latch: 'typing.Optional[uint]' = None - state: 'uint' = None - supported: 'uint' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + mask: uint = 0 + latch: typing.Optional[uint] = None + state: uint = 0 + supported: uint = 0 + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Bitmaps: class AlarmBitmap(IntFlag): @@ -19195,7 +19196,7 @@ class Reset(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x0000005D command_id: typing.ClassVar[int] = 0x00000000 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -19204,14 +19205,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="alarms", Tag=0, Type=uint), ]) - alarms: 'uint' = 0 + alarms: uint = 0 @dataclass class ModifyEnabledAlarms(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x0000005D command_id: typing.ClassVar[int] = 0x00000001 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -19220,7 +19221,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="mask", Tag=0, Type=uint), ]) - mask: 'uint' = 0 + mask: uint = 0 class Attributes: @dataclass @@ -19237,7 +19238,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class Latch(ClusterAttributeDescriptor): @@ -19253,7 +19254,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class State(ClusterAttributeDescriptor): @@ -19269,7 +19270,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class Supported(ClusterAttributeDescriptor): @@ -19285,7 +19286,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -19301,7 +19302,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -19317,7 +19318,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -19333,7 +19334,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -19349,7 +19350,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -19365,7 +19366,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -19381,7 +19382,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 class Events: @dataclass @@ -19404,10 +19405,10 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="mask", Tag=3, Type=uint), ]) - active: 'uint' = 0 - inactive: 'uint' = 0 - state: 'uint' = 0 - mask: 'uint' = 0 + active: uint = 0 + inactive: uint = 0 + state: uint = 0 + mask: uint = 0 @dataclass @@ -19428,14 +19429,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - supportedModes: 'typing.List[MicrowaveOvenMode.Structs.ModeOptionStruct]' = None - currentMode: 'uint' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + supportedModes: typing.List[MicrowaveOvenMode.Structs.ModeOptionStruct] = field(default_factory=lambda: []) + currentMode: uint = 0 + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class ModeTag(MatterIntEnum): @@ -19505,7 +19506,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[MicrowaveOvenMode.Structs.ModeOptionStruct]) - value: 'typing.List[MicrowaveOvenMode.Structs.ModeOptionStruct]' = field(default_factory=lambda: []) + value: typing.List[MicrowaveOvenMode.Structs.ModeOptionStruct] = field(default_factory=lambda: []) @dataclass class CurrentMode(ClusterAttributeDescriptor): @@ -19521,7 +19522,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -19537,7 +19538,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -19553,7 +19554,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -19569,7 +19570,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -19585,7 +19586,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -19601,7 +19602,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -19617,7 +19618,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -19645,21 +19646,21 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - cookTime: 'uint' = None - maxCookTime: 'uint' = None - powerSetting: 'typing.Optional[uint]' = None - minPower: 'typing.Optional[uint]' = None - maxPower: 'typing.Optional[uint]' = None - powerStep: 'typing.Optional[uint]' = None - supportedWatts: 'typing.Optional[typing.List[uint]]' = None - selectedWattIndex: 'typing.Optional[uint]' = None - wattRating: 'typing.Optional[uint]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + cookTime: uint = 0 + maxCookTime: uint = 0 + powerSetting: typing.Optional[uint] = None + minPower: typing.Optional[uint] = None + maxPower: typing.Optional[uint] = None + powerStep: typing.Optional[uint] = None + supportedWatts: typing.Optional[typing.List[uint]] = None + selectedWattIndex: typing.Optional[uint] = None + wattRating: typing.Optional[uint] = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Bitmaps: class Feature(IntFlag): @@ -19673,7 +19674,7 @@ class SetCookingParameters(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x0000005F command_id: typing.ClassVar[int] = 0x00000000 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -19686,18 +19687,18 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="startAfterSetting", Tag=4, Type=typing.Optional[bool]), ]) - cookMode: 'typing.Optional[uint]' = None - cookTime: 'typing.Optional[uint]' = None - powerSetting: 'typing.Optional[uint]' = None - wattSettingIndex: 'typing.Optional[uint]' = None - startAfterSetting: 'typing.Optional[bool]' = None + cookMode: typing.Optional[uint] = None + cookTime: typing.Optional[uint] = None + powerSetting: typing.Optional[uint] = None + wattSettingIndex: typing.Optional[uint] = None + startAfterSetting: typing.Optional[bool] = None @dataclass class AddMoreTime(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x0000005F command_id: typing.ClassVar[int] = 0x00000001 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -19706,7 +19707,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="timeToAdd", Tag=0, Type=uint), ]) - timeToAdd: 'uint' = 0 + timeToAdd: uint = 0 class Attributes: @dataclass @@ -19723,7 +19724,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class MaxCookTime(ClusterAttributeDescriptor): @@ -19739,7 +19740,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class PowerSetting(ClusterAttributeDescriptor): @@ -19755,7 +19756,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class MinPower(ClusterAttributeDescriptor): @@ -19771,7 +19772,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class MaxPower(ClusterAttributeDescriptor): @@ -19787,7 +19788,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class PowerStep(ClusterAttributeDescriptor): @@ -19803,7 +19804,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class SupportedWatts(ClusterAttributeDescriptor): @@ -19819,7 +19820,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[typing.List[uint]]) - value: 'typing.Optional[typing.List[uint]]' = None + value: typing.Optional[typing.List[uint]] = None @dataclass class SelectedWattIndex(ClusterAttributeDescriptor): @@ -19835,7 +19836,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class WattRating(ClusterAttributeDescriptor): @@ -19851,7 +19852,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -19867,7 +19868,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -19883,7 +19884,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -19899,7 +19900,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -19915,7 +19916,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -19931,7 +19932,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -19947,7 +19948,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -19972,18 +19973,18 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - phaseList: 'typing.Union[Nullable, typing.List[str]]' = None - currentPhase: 'typing.Union[Nullable, uint]' = None - countdownTime: 'typing.Union[None, Nullable, uint]' = None - operationalStateList: 'typing.List[OperationalState.Structs.OperationalStateStruct]' = None - operationalState: 'OperationalState.Enums.OperationalStateEnum' = None - operationalError: 'OperationalState.Structs.ErrorStateStruct' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + phaseList: typing.Union[Nullable, typing.List[str]] = NullValue + currentPhase: typing.Union[Nullable, uint] = NullValue + countdownTime: typing.Union[None, Nullable, uint] = None + operationalStateList: typing.List[OperationalState.Structs.OperationalStateStruct] = field(default_factory=lambda: []) + operationalState: OperationalState.Enums.OperationalStateEnum = 0 + operationalError: OperationalState.Structs.ErrorStateStruct = field(default_factory=lambda: OperationalState.Structs.ErrorStateStruct()) + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class ErrorStateEnum(MatterIntEnum): @@ -20095,7 +20096,7 @@ class OperationalCommandResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000060 command_id: typing.ClassVar[int] = 0x00000004 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -20104,7 +20105,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="commandResponseState", Tag=0, Type=OperationalState.Structs.ErrorStateStruct), ]) - commandResponseState: 'OperationalState.Structs.ErrorStateStruct' = field(default_factory=lambda: OperationalState.Structs.ErrorStateStruct()) + commandResponseState: OperationalState.Structs.ErrorStateStruct = field(default_factory=lambda: OperationalState.Structs.ErrorStateStruct()) class Attributes: @dataclass @@ -20121,7 +20122,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, typing.List[str]]) - value: 'typing.Union[Nullable, typing.List[str]]' = NullValue + value: typing.Union[Nullable, typing.List[str]] = NullValue @dataclass class CurrentPhase(ClusterAttributeDescriptor): @@ -20137,7 +20138,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, uint]) - value: 'typing.Union[Nullable, uint]' = NullValue + value: typing.Union[Nullable, uint] = NullValue @dataclass class CountdownTime(ClusterAttributeDescriptor): @@ -20153,7 +20154,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class OperationalStateList(ClusterAttributeDescriptor): @@ -20169,7 +20170,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[OperationalState.Structs.OperationalStateStruct]) - value: 'typing.List[OperationalState.Structs.OperationalStateStruct]' = field(default_factory=lambda: []) + value: typing.List[OperationalState.Structs.OperationalStateStruct] = field(default_factory=lambda: []) @dataclass class OperationalState(ClusterAttributeDescriptor): @@ -20185,7 +20186,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=OperationalState.Enums.OperationalStateEnum) - value: 'OperationalState.Enums.OperationalStateEnum' = 0 + value: OperationalState.Enums.OperationalStateEnum = 0 @dataclass class OperationalError(ClusterAttributeDescriptor): @@ -20201,7 +20202,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=OperationalState.Structs.ErrorStateStruct) - value: 'OperationalState.Structs.ErrorStateStruct' = field(default_factory=lambda: OperationalState.Structs.ErrorStateStruct()) + value: OperationalState.Structs.ErrorStateStruct = field(default_factory=lambda: OperationalState.Structs.ErrorStateStruct()) @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -20217,7 +20218,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -20233,7 +20234,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -20249,7 +20250,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -20265,7 +20266,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -20281,7 +20282,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -20297,7 +20298,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 class Events: @dataclass @@ -20317,7 +20318,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="errorState", Tag=0, Type=OperationalState.Structs.ErrorStateStruct), ]) - errorState: 'OperationalState.Structs.ErrorStateStruct' = field(default_factory=lambda: OperationalState.Structs.ErrorStateStruct()) + errorState: OperationalState.Structs.ErrorStateStruct = field(default_factory=lambda: OperationalState.Structs.ErrorStateStruct()) @dataclass class OperationCompletion(ClusterEvent): @@ -20338,9 +20339,9 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="pausedTime", Tag=2, Type=typing.Union[None, Nullable, uint]), ]) - completionErrorCode: 'uint' = 0 - totalOperationalTime: 'typing.Union[None, Nullable, uint]' = None - pausedTime: 'typing.Union[None, Nullable, uint]' = None + completionErrorCode: uint = 0 + totalOperationalTime: typing.Union[None, Nullable, uint] = None + pausedTime: typing.Union[None, Nullable, uint] = None @dataclass @@ -20365,18 +20366,18 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - phaseList: 'typing.Union[Nullable, typing.List[str]]' = None - currentPhase: 'typing.Union[Nullable, uint]' = None - countdownTime: 'typing.Union[None, Nullable, uint]' = None - operationalStateList: 'typing.List[RvcOperationalState.Structs.OperationalStateStruct]' = None - operationalState: 'uint' = None - operationalError: 'RvcOperationalState.Structs.ErrorStateStruct' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + phaseList: typing.Union[Nullable, typing.List[str]] = NullValue + currentPhase: typing.Union[Nullable, uint] = NullValue + countdownTime: typing.Union[None, Nullable, uint] = None + operationalStateList: typing.List[RvcOperationalState.Structs.OperationalStateStruct] = field(default_factory=lambda: []) + operationalState: uint = 0 + operationalError: RvcOperationalState.Structs.ErrorStateStruct = field(default_factory=lambda: RvcOperationalState.Structs.ErrorStateStruct()) + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class ErrorStateEnum(MatterIntEnum): @@ -20473,7 +20474,7 @@ class OperationalCommandResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000061 command_id: typing.ClassVar[int] = 0x00000004 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -20482,7 +20483,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="commandResponseState", Tag=0, Type=RvcOperationalState.Structs.ErrorStateStruct), ]) - commandResponseState: 'RvcOperationalState.Structs.ErrorStateStruct' = field(default_factory=lambda: RvcOperationalState.Structs.ErrorStateStruct()) + commandResponseState: RvcOperationalState.Structs.ErrorStateStruct = field(default_factory=lambda: RvcOperationalState.Structs.ErrorStateStruct()) @dataclass class GoHome(ClusterCommand): @@ -20512,7 +20513,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, typing.List[str]]) - value: 'typing.Union[Nullable, typing.List[str]]' = NullValue + value: typing.Union[Nullable, typing.List[str]] = NullValue @dataclass class CurrentPhase(ClusterAttributeDescriptor): @@ -20528,7 +20529,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, uint]) - value: 'typing.Union[Nullable, uint]' = NullValue + value: typing.Union[Nullable, uint] = NullValue @dataclass class CountdownTime(ClusterAttributeDescriptor): @@ -20544,7 +20545,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class OperationalStateList(ClusterAttributeDescriptor): @@ -20560,7 +20561,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[RvcOperationalState.Structs.OperationalStateStruct]) - value: 'typing.List[RvcOperationalState.Structs.OperationalStateStruct]' = field(default_factory=lambda: []) + value: typing.List[RvcOperationalState.Structs.OperationalStateStruct] = field(default_factory=lambda: []) @dataclass class OperationalState(ClusterAttributeDescriptor): @@ -20576,7 +20577,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class OperationalError(ClusterAttributeDescriptor): @@ -20592,7 +20593,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=RvcOperationalState.Structs.ErrorStateStruct) - value: 'RvcOperationalState.Structs.ErrorStateStruct' = field(default_factory=lambda: RvcOperationalState.Structs.ErrorStateStruct()) + value: RvcOperationalState.Structs.ErrorStateStruct = field(default_factory=lambda: RvcOperationalState.Structs.ErrorStateStruct()) @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -20608,7 +20609,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -20624,7 +20625,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -20640,7 +20641,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -20656,7 +20657,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -20672,7 +20673,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -20688,7 +20689,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 class Events: @dataclass @@ -20708,7 +20709,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="errorState", Tag=0, Type=RvcOperationalState.Structs.ErrorStateStruct), ]) - errorState: 'RvcOperationalState.Structs.ErrorStateStruct' = field(default_factory=lambda: RvcOperationalState.Structs.ErrorStateStruct()) + errorState: RvcOperationalState.Structs.ErrorStateStruct = field(default_factory=lambda: RvcOperationalState.Structs.ErrorStateStruct()) @dataclass class OperationCompletion(ClusterEvent): @@ -20729,9 +20730,9 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="pausedTime", Tag=2, Type=typing.Union[None, Nullable, uint]), ]) - completionErrorCode: 'uint' = 0 - totalOperationalTime: 'typing.Union[None, Nullable, uint]' = None - pausedTime: 'typing.Union[None, Nullable, uint]' = None + completionErrorCode: uint = 0 + totalOperationalTime: typing.Union[None, Nullable, uint] = None + pausedTime: typing.Union[None, Nullable, uint] = None @dataclass @@ -20753,15 +20754,15 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - lastConfiguredBy: 'typing.Union[None, Nullable, uint]' = None - sceneTableSize: 'uint' = None - fabricSceneInfo: 'typing.List[ScenesManagement.Structs.SceneInfoStruct]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + lastConfiguredBy: typing.Union[None, Nullable, uint] = None + sceneTableSize: uint = 0 + fabricSceneInfo: typing.List[ScenesManagement.Structs.SceneInfoStruct] = field(default_factory=lambda: []) + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Bitmaps: class CopyModeBitmap(IntFlag): @@ -20851,18 +20852,18 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="extensionFieldSets", Tag=4, Type=typing.List[ScenesManagement.Structs.ExtensionFieldSet]), ]) - groupID: 'uint' = 0 - sceneID: 'uint' = 0 - transitionTime: 'uint' = 0 - sceneName: 'str' = "" - extensionFieldSets: 'typing.List[ScenesManagement.Structs.ExtensionFieldSet]' = field(default_factory=lambda: []) + groupID: uint = 0 + sceneID: uint = 0 + transitionTime: uint = 0 + sceneName: str = "" + extensionFieldSets: typing.List[ScenesManagement.Structs.ExtensionFieldSet] = field(default_factory=lambda: []) @dataclass class AddSceneResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000062 command_id: typing.ClassVar[int] = 0x00000000 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -20873,9 +20874,9 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="sceneID", Tag=2, Type=uint), ]) - status: 'uint' = 0 - groupID: 'uint' = 0 - sceneID: 'uint' = 0 + status: uint = 0 + groupID: uint = 0 + sceneID: uint = 0 @dataclass class ViewScene(ClusterCommand): @@ -20892,15 +20893,15 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="sceneID", Tag=1, Type=uint), ]) - groupID: 'uint' = 0 - sceneID: 'uint' = 0 + groupID: uint = 0 + sceneID: uint = 0 @dataclass class ViewSceneResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000062 command_id: typing.ClassVar[int] = 0x00000001 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -20914,12 +20915,12 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="extensionFieldSets", Tag=5, Type=typing.Optional[typing.List[ScenesManagement.Structs.ExtensionFieldSet]]), ]) - status: 'uint' = 0 - groupID: 'uint' = 0 - sceneID: 'uint' = 0 - transitionTime: 'typing.Optional[uint]' = None - sceneName: 'typing.Optional[str]' = None - extensionFieldSets: 'typing.Optional[typing.List[ScenesManagement.Structs.ExtensionFieldSet]]' = None + status: uint = 0 + groupID: uint = 0 + sceneID: uint = 0 + transitionTime: typing.Optional[uint] = None + sceneName: typing.Optional[str] = None + extensionFieldSets: typing.Optional[typing.List[ScenesManagement.Structs.ExtensionFieldSet]] = None @dataclass class RemoveScene(ClusterCommand): @@ -20936,15 +20937,15 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="sceneID", Tag=1, Type=uint), ]) - groupID: 'uint' = 0 - sceneID: 'uint' = 0 + groupID: uint = 0 + sceneID: uint = 0 @dataclass class RemoveSceneResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000062 command_id: typing.ClassVar[int] = 0x00000002 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -20955,9 +20956,9 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="sceneID", Tag=2, Type=uint), ]) - status: 'uint' = 0 - groupID: 'uint' = 0 - sceneID: 'uint' = 0 + status: uint = 0 + groupID: uint = 0 + sceneID: uint = 0 @dataclass class RemoveAllScenes(ClusterCommand): @@ -20973,14 +20974,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="groupID", Tag=0, Type=uint), ]) - groupID: 'uint' = 0 + groupID: uint = 0 @dataclass class RemoveAllScenesResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000062 command_id: typing.ClassVar[int] = 0x00000003 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -20990,8 +20991,8 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="groupID", Tag=1, Type=uint), ]) - status: 'uint' = 0 - groupID: 'uint' = 0 + status: uint = 0 + groupID: uint = 0 @dataclass class StoreScene(ClusterCommand): @@ -21008,15 +21009,15 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="sceneID", Tag=1, Type=uint), ]) - groupID: 'uint' = 0 - sceneID: 'uint' = 0 + groupID: uint = 0 + sceneID: uint = 0 @dataclass class StoreSceneResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000062 command_id: typing.ClassVar[int] = 0x00000004 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -21027,16 +21028,16 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="sceneID", Tag=2, Type=uint), ]) - status: 'uint' = 0 - groupID: 'uint' = 0 - sceneID: 'uint' = 0 + status: uint = 0 + groupID: uint = 0 + sceneID: uint = 0 @dataclass class RecallScene(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000062 command_id: typing.ClassVar[int] = 0x00000005 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -21047,9 +21048,9 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="transitionTime", Tag=2, Type=typing.Union[None, Nullable, uint]), ]) - groupID: 'uint' = 0 - sceneID: 'uint' = 0 - transitionTime: 'typing.Union[None, Nullable, uint]' = None + groupID: uint = 0 + sceneID: uint = 0 + transitionTime: typing.Union[None, Nullable, uint] = None @dataclass class GetSceneMembership(ClusterCommand): @@ -21065,14 +21066,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="groupID", Tag=0, Type=uint), ]) - groupID: 'uint' = 0 + groupID: uint = 0 @dataclass class GetSceneMembershipResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000062 command_id: typing.ClassVar[int] = 0x00000006 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -21084,10 +21085,10 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="sceneList", Tag=3, Type=typing.Optional[typing.List[uint]]), ]) - status: 'uint' = 0 - capacity: 'typing.Union[Nullable, uint]' = NullValue - groupID: 'uint' = 0 - sceneList: 'typing.Optional[typing.List[uint]]' = None + status: uint = 0 + capacity: typing.Union[Nullable, uint] = NullValue + groupID: uint = 0 + sceneList: typing.Optional[typing.List[uint]] = None @dataclass class CopyScene(ClusterCommand): @@ -21107,18 +21108,18 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="sceneIdentifierTo", Tag=4, Type=uint), ]) - mode: 'uint' = 0 - groupIdentifierFrom: 'uint' = 0 - sceneIdentifierFrom: 'uint' = 0 - groupIdentifierTo: 'uint' = 0 - sceneIdentifierTo: 'uint' = 0 + mode: uint = 0 + groupIdentifierFrom: uint = 0 + sceneIdentifierFrom: uint = 0 + groupIdentifierTo: uint = 0 + sceneIdentifierTo: uint = 0 @dataclass class CopySceneResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000062 command_id: typing.ClassVar[int] = 0x00000040 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -21129,9 +21130,9 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="sceneIdentifierFrom", Tag=2, Type=uint), ]) - status: 'uint' = 0 - groupIdentifierFrom: 'uint' = 0 - sceneIdentifierFrom: 'uint' = 0 + status: uint = 0 + groupIdentifierFrom: uint = 0 + sceneIdentifierFrom: uint = 0 class Attributes: @dataclass @@ -21148,7 +21149,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class SceneTableSize(ClusterAttributeDescriptor): @@ -21164,7 +21165,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class FabricSceneInfo(ClusterAttributeDescriptor): @@ -21180,7 +21181,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[ScenesManagement.Structs.SceneInfoStruct]) - value: 'typing.List[ScenesManagement.Structs.SceneInfoStruct]' = field(default_factory=lambda: []) + value: typing.List[ScenesManagement.Structs.SceneInfoStruct] = field(default_factory=lambda: []) @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -21196,7 +21197,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -21212,7 +21213,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -21228,7 +21229,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -21244,7 +21245,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -21260,7 +21261,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -21276,7 +21277,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -21301,18 +21302,18 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - condition: 'typing.Optional[uint]' = None - degradationDirection: 'typing.Optional[HepaFilterMonitoring.Enums.DegradationDirectionEnum]' = None - changeIndication: 'HepaFilterMonitoring.Enums.ChangeIndicationEnum' = None - inPlaceIndicator: 'typing.Optional[bool]' = None - lastChangedTime: 'typing.Union[None, Nullable, uint]' = None - replacementProductList: 'typing.Optional[typing.List[HepaFilterMonitoring.Structs.ReplacementProductStruct]]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + condition: typing.Optional[uint] = None + degradationDirection: typing.Optional[HepaFilterMonitoring.Enums.DegradationDirectionEnum] = None + changeIndication: HepaFilterMonitoring.Enums.ChangeIndicationEnum = 0 + inPlaceIndicator: typing.Optional[bool] = None + lastChangedTime: typing.Union[None, Nullable, uint] = None + replacementProductList: typing.Optional[typing.List[HepaFilterMonitoring.Structs.ReplacementProductStruct]] = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class ChangeIndicationEnum(MatterIntEnum): @@ -21372,7 +21373,7 @@ class ResetCondition(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000071 command_id: typing.ClassVar[int] = 0x00000000 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -21395,7 +21396,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class DegradationDirection(ClusterAttributeDescriptor): @@ -21411,7 +21412,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[HepaFilterMonitoring.Enums.DegradationDirectionEnum]) - value: 'typing.Optional[HepaFilterMonitoring.Enums.DegradationDirectionEnum]' = None + value: typing.Optional[HepaFilterMonitoring.Enums.DegradationDirectionEnum] = None @dataclass class ChangeIndication(ClusterAttributeDescriptor): @@ -21427,7 +21428,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=HepaFilterMonitoring.Enums.ChangeIndicationEnum) - value: 'HepaFilterMonitoring.Enums.ChangeIndicationEnum' = 0 + value: HepaFilterMonitoring.Enums.ChangeIndicationEnum = 0 @dataclass class InPlaceIndicator(ClusterAttributeDescriptor): @@ -21443,7 +21444,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[bool]) - value: 'typing.Optional[bool]' = None + value: typing.Optional[bool] = None @dataclass class LastChangedTime(ClusterAttributeDescriptor): @@ -21459,7 +21460,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class ReplacementProductList(ClusterAttributeDescriptor): @@ -21475,7 +21476,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[typing.List[HepaFilterMonitoring.Structs.ReplacementProductStruct]]) - value: 'typing.Optional[typing.List[HepaFilterMonitoring.Structs.ReplacementProductStruct]]' = None + value: typing.Optional[typing.List[HepaFilterMonitoring.Structs.ReplacementProductStruct]] = None @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -21491,7 +21492,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -21507,7 +21508,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -21523,7 +21524,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -21539,7 +21540,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -21555,7 +21556,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -21571,7 +21572,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -21596,18 +21597,18 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - condition: 'typing.Optional[uint]' = None - degradationDirection: 'typing.Optional[ActivatedCarbonFilterMonitoring.Enums.DegradationDirectionEnum]' = None - changeIndication: 'ActivatedCarbonFilterMonitoring.Enums.ChangeIndicationEnum' = None - inPlaceIndicator: 'typing.Optional[bool]' = None - lastChangedTime: 'typing.Union[None, Nullable, uint]' = None - replacementProductList: 'typing.Optional[typing.List[ActivatedCarbonFilterMonitoring.Structs.ReplacementProductStruct]]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + condition: typing.Optional[uint] = None + degradationDirection: typing.Optional[ActivatedCarbonFilterMonitoring.Enums.DegradationDirectionEnum] = None + changeIndication: ActivatedCarbonFilterMonitoring.Enums.ChangeIndicationEnum = 0 + inPlaceIndicator: typing.Optional[bool] = None + lastChangedTime: typing.Union[None, Nullable, uint] = None + replacementProductList: typing.Optional[typing.List[ActivatedCarbonFilterMonitoring.Structs.ReplacementProductStruct]] = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class ChangeIndicationEnum(MatterIntEnum): @@ -21667,7 +21668,7 @@ class ResetCondition(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000072 command_id: typing.ClassVar[int] = 0x00000000 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -21690,7 +21691,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class DegradationDirection(ClusterAttributeDescriptor): @@ -21706,7 +21707,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[ActivatedCarbonFilterMonitoring.Enums.DegradationDirectionEnum]) - value: 'typing.Optional[ActivatedCarbonFilterMonitoring.Enums.DegradationDirectionEnum]' = None + value: typing.Optional[ActivatedCarbonFilterMonitoring.Enums.DegradationDirectionEnum] = None @dataclass class ChangeIndication(ClusterAttributeDescriptor): @@ -21722,7 +21723,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=ActivatedCarbonFilterMonitoring.Enums.ChangeIndicationEnum) - value: 'ActivatedCarbonFilterMonitoring.Enums.ChangeIndicationEnum' = 0 + value: ActivatedCarbonFilterMonitoring.Enums.ChangeIndicationEnum = 0 @dataclass class InPlaceIndicator(ClusterAttributeDescriptor): @@ -21738,7 +21739,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[bool]) - value: 'typing.Optional[bool]' = None + value: typing.Optional[bool] = None @dataclass class LastChangedTime(ClusterAttributeDescriptor): @@ -21754,7 +21755,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class ReplacementProductList(ClusterAttributeDescriptor): @@ -21770,7 +21771,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[typing.List[ActivatedCarbonFilterMonitoring.Structs.ReplacementProductStruct]]) - value: 'typing.Optional[typing.List[ActivatedCarbonFilterMonitoring.Structs.ReplacementProductStruct]]' = None + value: typing.Optional[typing.List[ActivatedCarbonFilterMonitoring.Structs.ReplacementProductStruct]] = None @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -21786,7 +21787,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -21802,7 +21803,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -21818,7 +21819,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -21834,7 +21835,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -21850,7 +21851,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -21866,7 +21867,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -21893,20 +21894,20 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - currentSensitivityLevel: 'typing.Optional[uint]' = None - supportedSensitivityLevels: 'typing.Optional[uint]' = None - defaultSensitivityLevel: 'typing.Optional[uint]' = None - alarmsActive: 'typing.Optional[uint]' = None - alarmsSuppressed: 'typing.Optional[uint]' = None - alarmsEnabled: 'typing.Optional[uint]' = None - alarmsSupported: 'typing.Optional[uint]' = None - sensorFault: 'typing.Optional[uint]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + currentSensitivityLevel: typing.Optional[uint] = None + supportedSensitivityLevels: typing.Optional[uint] = None + defaultSensitivityLevel: typing.Optional[uint] = None + alarmsActive: typing.Optional[uint] = None + alarmsSuppressed: typing.Optional[uint] = None + alarmsEnabled: typing.Optional[uint] = None + alarmsSupported: typing.Optional[uint] = None + sensorFault: typing.Optional[uint] = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Bitmaps: class AlarmModeBitmap(IntFlag): @@ -21928,7 +21929,7 @@ class SuppressAlarm(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000080 command_id: typing.ClassVar[int] = 0x00000000 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -21937,14 +21938,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="alarmsToSuppress", Tag=0, Type=uint), ]) - alarmsToSuppress: 'uint' = 0 + alarmsToSuppress: uint = 0 @dataclass class EnableDisableAlarm(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000080 command_id: typing.ClassVar[int] = 0x00000001 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -21953,7 +21954,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="alarmsToEnableDisable", Tag=0, Type=uint), ]) - alarmsToEnableDisable: 'uint' = 0 + alarmsToEnableDisable: uint = 0 class Attributes: @dataclass @@ -21970,7 +21971,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class SupportedSensitivityLevels(ClusterAttributeDescriptor): @@ -21986,7 +21987,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class DefaultSensitivityLevel(ClusterAttributeDescriptor): @@ -22002,7 +22003,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class AlarmsActive(ClusterAttributeDescriptor): @@ -22018,7 +22019,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class AlarmsSuppressed(ClusterAttributeDescriptor): @@ -22034,7 +22035,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class AlarmsEnabled(ClusterAttributeDescriptor): @@ -22050,7 +22051,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class AlarmsSupported(ClusterAttributeDescriptor): @@ -22066,7 +22067,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class SensorFault(ClusterAttributeDescriptor): @@ -22082,7 +22083,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -22098,7 +22099,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -22114,7 +22115,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -22130,7 +22131,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -22146,7 +22147,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -22162,7 +22163,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -22178,7 +22179,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 class Events: @dataclass @@ -22199,8 +22200,8 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="alarmsSuppressed", Tag=1, Type=typing.Optional[uint]), ]) - alarmsActive: 'uint' = 0 - alarmsSuppressed: 'typing.Optional[uint]' = None + alarmsActive: uint = 0 + alarmsSuppressed: typing.Optional[uint] = None @dataclass class SensorFault(ClusterEvent): @@ -22219,7 +22220,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="sensorFault", Tag=0, Type=uint), ]) - sensorFault: 'uint' = 0 + sensorFault: uint = 0 @dataclass @@ -22249,23 +22250,23 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - openDuration: 'typing.Union[Nullable, uint]' = None - defaultOpenDuration: 'typing.Union[Nullable, uint]' = None - autoCloseTime: 'typing.Union[None, Nullable, uint]' = None - remainingDuration: 'typing.Union[Nullable, uint]' = None - currentState: 'typing.Union[Nullable, ValveConfigurationAndControl.Enums.ValveStateEnum]' = None - targetState: 'typing.Union[Nullable, ValveConfigurationAndControl.Enums.ValveStateEnum]' = None - currentLevel: 'typing.Union[None, Nullable, uint]' = None - targetLevel: 'typing.Union[None, Nullable, uint]' = None - defaultOpenLevel: 'typing.Optional[uint]' = None - valveFault: 'typing.Optional[uint]' = None - levelStep: 'typing.Optional[uint]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + openDuration: typing.Union[Nullable, uint] = NullValue + defaultOpenDuration: typing.Union[Nullable, uint] = NullValue + autoCloseTime: typing.Union[None, Nullable, uint] = None + remainingDuration: typing.Union[Nullable, uint] = NullValue + currentState: typing.Union[Nullable, ValveConfigurationAndControl.Enums.ValveStateEnum] = NullValue + targetState: typing.Union[Nullable, ValveConfigurationAndControl.Enums.ValveStateEnum] = NullValue + currentLevel: typing.Union[None, Nullable, uint] = None + targetLevel: typing.Union[None, Nullable, uint] = None + defaultOpenLevel: typing.Optional[uint] = None + valveFault: typing.Optional[uint] = None + levelStep: typing.Optional[uint] = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class StatusCodeEnum(MatterIntEnum): @@ -22305,7 +22306,7 @@ class Open(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000081 command_id: typing.ClassVar[int] = 0x00000000 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -22315,15 +22316,15 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="targetLevel", Tag=1, Type=typing.Optional[uint]), ]) - openDuration: 'typing.Union[None, Nullable, uint]' = None - targetLevel: 'typing.Optional[uint]' = None + openDuration: typing.Union[None, Nullable, uint] = None + targetLevel: typing.Optional[uint] = None @dataclass class Close(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000081 command_id: typing.ClassVar[int] = 0x00000001 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -22346,7 +22347,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, uint]) - value: 'typing.Union[Nullable, uint]' = NullValue + value: typing.Union[Nullable, uint] = NullValue @dataclass class DefaultOpenDuration(ClusterAttributeDescriptor): @@ -22362,7 +22363,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, uint]) - value: 'typing.Union[Nullable, uint]' = NullValue + value: typing.Union[Nullable, uint] = NullValue @dataclass class AutoCloseTime(ClusterAttributeDescriptor): @@ -22378,7 +22379,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class RemainingDuration(ClusterAttributeDescriptor): @@ -22394,7 +22395,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, uint]) - value: 'typing.Union[Nullable, uint]' = NullValue + value: typing.Union[Nullable, uint] = NullValue @dataclass class CurrentState(ClusterAttributeDescriptor): @@ -22410,7 +22411,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, ValveConfigurationAndControl.Enums.ValveStateEnum]) - value: 'typing.Union[Nullable, ValveConfigurationAndControl.Enums.ValveStateEnum]' = NullValue + value: typing.Union[Nullable, ValveConfigurationAndControl.Enums.ValveStateEnum] = NullValue @dataclass class TargetState(ClusterAttributeDescriptor): @@ -22426,7 +22427,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, ValveConfigurationAndControl.Enums.ValveStateEnum]) - value: 'typing.Union[Nullable, ValveConfigurationAndControl.Enums.ValveStateEnum]' = NullValue + value: typing.Union[Nullable, ValveConfigurationAndControl.Enums.ValveStateEnum] = NullValue @dataclass class CurrentLevel(ClusterAttributeDescriptor): @@ -22442,7 +22443,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class TargetLevel(ClusterAttributeDescriptor): @@ -22458,7 +22459,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class DefaultOpenLevel(ClusterAttributeDescriptor): @@ -22474,7 +22475,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class ValveFault(ClusterAttributeDescriptor): @@ -22490,7 +22491,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class LevelStep(ClusterAttributeDescriptor): @@ -22506,7 +22507,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -22522,7 +22523,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -22538,7 +22539,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -22554,7 +22555,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -22570,7 +22571,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -22586,7 +22587,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -22602,7 +22603,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 class Events: @dataclass @@ -22623,8 +22624,8 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="valveLevel", Tag=1, Type=typing.Optional[uint]), ]) - valveState: 'ValveConfigurationAndControl.Enums.ValveStateEnum' = 0 - valveLevel: 'typing.Optional[uint]' = None + valveState: ValveConfigurationAndControl.Enums.ValveStateEnum = 0 + valveLevel: typing.Optional[uint] = None @dataclass class ValveFault(ClusterEvent): @@ -22643,7 +22644,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="valveFault", Tag=0, Type=uint), ]) - valveFault: 'uint' = 0 + valveFault: uint = 0 @dataclass @@ -22681,31 +22682,31 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - powerMode: 'ElectricalPowerMeasurement.Enums.PowerModeEnum' = None - numberOfMeasurementTypes: 'uint' = None - accuracy: 'typing.List[ElectricalPowerMeasurement.Structs.MeasurementAccuracyStruct]' = None - ranges: 'typing.Optional[typing.List[ElectricalPowerMeasurement.Structs.MeasurementRangeStruct]]' = None - voltage: 'typing.Union[None, Nullable, int]' = None - activeCurrent: 'typing.Union[None, Nullable, int]' = None - reactiveCurrent: 'typing.Union[None, Nullable, int]' = None - apparentCurrent: 'typing.Union[None, Nullable, int]' = None - activePower: 'typing.Union[Nullable, int]' = None - reactivePower: 'typing.Union[None, Nullable, int]' = None - apparentPower: 'typing.Union[None, Nullable, int]' = None - RMSVoltage: 'typing.Union[None, Nullable, int]' = None - RMSCurrent: 'typing.Union[None, Nullable, int]' = None - RMSPower: 'typing.Union[None, Nullable, int]' = None - frequency: 'typing.Union[None, Nullable, int]' = None - harmonicCurrents: 'typing.Union[None, Nullable, typing.List[ElectricalPowerMeasurement.Structs.HarmonicMeasurementStruct]]' = None - harmonicPhases: 'typing.Union[None, Nullable, typing.List[ElectricalPowerMeasurement.Structs.HarmonicMeasurementStruct]]' = None - powerFactor: 'typing.Union[None, Nullable, int]' = None - neutralCurrent: 'typing.Union[None, Nullable, int]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + powerMode: ElectricalPowerMeasurement.Enums.PowerModeEnum = 0 + numberOfMeasurementTypes: uint = 0 + accuracy: typing.List[ElectricalPowerMeasurement.Structs.MeasurementAccuracyStruct] = field(default_factory=lambda: []) + ranges: typing.Optional[typing.List[ElectricalPowerMeasurement.Structs.MeasurementRangeStruct]] = None + voltage: typing.Union[None, Nullable, int] = None + activeCurrent: typing.Union[None, Nullable, int] = None + reactiveCurrent: typing.Union[None, Nullable, int] = None + apparentCurrent: typing.Union[None, Nullable, int] = None + activePower: typing.Union[Nullable, int] = NullValue + reactivePower: typing.Union[None, Nullable, int] = None + apparentPower: typing.Union[None, Nullable, int] = None + RMSVoltage: typing.Union[None, Nullable, int] = None + RMSCurrent: typing.Union[None, Nullable, int] = None + RMSPower: typing.Union[None, Nullable, int] = None + frequency: typing.Union[None, Nullable, int] = None + harmonicCurrents: typing.Union[None, Nullable, typing.List[ElectricalPowerMeasurement.Structs.HarmonicMeasurementStruct]] = None + harmonicPhases: typing.Union[None, Nullable, typing.List[ElectricalPowerMeasurement.Structs.HarmonicMeasurementStruct]] = None + powerFactor: typing.Union[None, Nullable, int] = None + neutralCurrent: typing.Union[None, Nullable, int] = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class MeasurementTypeEnum(MatterIntEnum): @@ -22852,7 +22853,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=ElectricalPowerMeasurement.Enums.PowerModeEnum) - value: 'ElectricalPowerMeasurement.Enums.PowerModeEnum' = 0 + value: ElectricalPowerMeasurement.Enums.PowerModeEnum = 0 @dataclass class NumberOfMeasurementTypes(ClusterAttributeDescriptor): @@ -22868,7 +22869,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class Accuracy(ClusterAttributeDescriptor): @@ -22884,7 +22885,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[ElectricalPowerMeasurement.Structs.MeasurementAccuracyStruct]) - value: 'typing.List[ElectricalPowerMeasurement.Structs.MeasurementAccuracyStruct]' = field(default_factory=lambda: []) + value: typing.List[ElectricalPowerMeasurement.Structs.MeasurementAccuracyStruct] = field(default_factory=lambda: []) @dataclass class Ranges(ClusterAttributeDescriptor): @@ -22900,7 +22901,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[typing.List[ElectricalPowerMeasurement.Structs.MeasurementRangeStruct]]) - value: 'typing.Optional[typing.List[ElectricalPowerMeasurement.Structs.MeasurementRangeStruct]]' = None + value: typing.Optional[typing.List[ElectricalPowerMeasurement.Structs.MeasurementRangeStruct]] = None @dataclass class Voltage(ClusterAttributeDescriptor): @@ -22916,7 +22917,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, int]) - value: 'typing.Union[None, Nullable, int]' = None + value: typing.Union[None, Nullable, int] = None @dataclass class ActiveCurrent(ClusterAttributeDescriptor): @@ -22932,7 +22933,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, int]) - value: 'typing.Union[None, Nullable, int]' = None + value: typing.Union[None, Nullable, int] = None @dataclass class ReactiveCurrent(ClusterAttributeDescriptor): @@ -22948,7 +22949,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, int]) - value: 'typing.Union[None, Nullable, int]' = None + value: typing.Union[None, Nullable, int] = None @dataclass class ApparentCurrent(ClusterAttributeDescriptor): @@ -22964,7 +22965,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, int]) - value: 'typing.Union[None, Nullable, int]' = None + value: typing.Union[None, Nullable, int] = None @dataclass class ActivePower(ClusterAttributeDescriptor): @@ -22980,7 +22981,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, int]) - value: 'typing.Union[Nullable, int]' = NullValue + value: typing.Union[Nullable, int] = NullValue @dataclass class ReactivePower(ClusterAttributeDescriptor): @@ -22996,7 +22997,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, int]) - value: 'typing.Union[None, Nullable, int]' = None + value: typing.Union[None, Nullable, int] = None @dataclass class ApparentPower(ClusterAttributeDescriptor): @@ -23012,7 +23013,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, int]) - value: 'typing.Union[None, Nullable, int]' = None + value: typing.Union[None, Nullable, int] = None @dataclass class RMSVoltage(ClusterAttributeDescriptor): @@ -23028,7 +23029,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, int]) - value: 'typing.Union[None, Nullable, int]' = None + value: typing.Union[None, Nullable, int] = None @dataclass class RMSCurrent(ClusterAttributeDescriptor): @@ -23044,7 +23045,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, int]) - value: 'typing.Union[None, Nullable, int]' = None + value: typing.Union[None, Nullable, int] = None @dataclass class RMSPower(ClusterAttributeDescriptor): @@ -23060,7 +23061,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, int]) - value: 'typing.Union[None, Nullable, int]' = None + value: typing.Union[None, Nullable, int] = None @dataclass class Frequency(ClusterAttributeDescriptor): @@ -23076,7 +23077,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, int]) - value: 'typing.Union[None, Nullable, int]' = None + value: typing.Union[None, Nullable, int] = None @dataclass class HarmonicCurrents(ClusterAttributeDescriptor): @@ -23092,7 +23093,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, typing.List[ElectricalPowerMeasurement.Structs.HarmonicMeasurementStruct]]) - value: 'typing.Union[None, Nullable, typing.List[ElectricalPowerMeasurement.Structs.HarmonicMeasurementStruct]]' = None + value: typing.Union[None, Nullable, typing.List[ElectricalPowerMeasurement.Structs.HarmonicMeasurementStruct]] = None @dataclass class HarmonicPhases(ClusterAttributeDescriptor): @@ -23108,7 +23109,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, typing.List[ElectricalPowerMeasurement.Structs.HarmonicMeasurementStruct]]) - value: 'typing.Union[None, Nullable, typing.List[ElectricalPowerMeasurement.Structs.HarmonicMeasurementStruct]]' = None + value: typing.Union[None, Nullable, typing.List[ElectricalPowerMeasurement.Structs.HarmonicMeasurementStruct]] = None @dataclass class PowerFactor(ClusterAttributeDescriptor): @@ -23124,7 +23125,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, int]) - value: 'typing.Union[None, Nullable, int]' = None + value: typing.Union[None, Nullable, int] = None @dataclass class NeutralCurrent(ClusterAttributeDescriptor): @@ -23140,7 +23141,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, int]) - value: 'typing.Union[None, Nullable, int]' = None + value: typing.Union[None, Nullable, int] = None @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -23156,7 +23157,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -23172,7 +23173,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -23188,7 +23189,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -23204,7 +23205,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -23220,7 +23221,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -23236,7 +23237,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 class Events: @dataclass @@ -23256,7 +23257,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="ranges", Tag=0, Type=typing.List[ElectricalPowerMeasurement.Structs.MeasurementRangeStruct]), ]) - ranges: 'typing.List[ElectricalPowerMeasurement.Structs.MeasurementRangeStruct]' = field(default_factory=lambda: []) + ranges: typing.List[ElectricalPowerMeasurement.Structs.MeasurementRangeStruct] = field(default_factory=lambda: []) @dataclass @@ -23281,18 +23282,18 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - accuracy: 'ElectricalEnergyMeasurement.Structs.MeasurementAccuracyStruct' = None - cumulativeEnergyImported: 'typing.Union[None, Nullable, ElectricalEnergyMeasurement.Structs.EnergyMeasurementStruct]' = None - cumulativeEnergyExported: 'typing.Union[None, Nullable, ElectricalEnergyMeasurement.Structs.EnergyMeasurementStruct]' = None - periodicEnergyImported: 'typing.Union[None, Nullable, ElectricalEnergyMeasurement.Structs.EnergyMeasurementStruct]' = None - periodicEnergyExported: 'typing.Union[None, Nullable, ElectricalEnergyMeasurement.Structs.EnergyMeasurementStruct]' = None - cumulativeEnergyReset: 'typing.Union[None, Nullable, ElectricalEnergyMeasurement.Structs.CumulativeEnergyResetStruct]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + accuracy: ElectricalEnergyMeasurement.Structs.MeasurementAccuracyStruct = field(default_factory=lambda: ElectricalEnergyMeasurement.Structs.MeasurementAccuracyStruct()) + cumulativeEnergyImported: typing.Union[None, Nullable, ElectricalEnergyMeasurement.Structs.EnergyMeasurementStruct] = None + cumulativeEnergyExported: typing.Union[None, Nullable, ElectricalEnergyMeasurement.Structs.EnergyMeasurementStruct] = None + periodicEnergyImported: typing.Union[None, Nullable, ElectricalEnergyMeasurement.Structs.EnergyMeasurementStruct] = None + periodicEnergyExported: typing.Union[None, Nullable, ElectricalEnergyMeasurement.Structs.EnergyMeasurementStruct] = None + cumulativeEnergyReset: typing.Union[None, Nullable, ElectricalEnergyMeasurement.Structs.CumulativeEnergyResetStruct] = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class MeasurementTypeEnum(MatterIntEnum): @@ -23420,7 +23421,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=ElectricalEnergyMeasurement.Structs.MeasurementAccuracyStruct) - value: 'ElectricalEnergyMeasurement.Structs.MeasurementAccuracyStruct' = field(default_factory=lambda: ElectricalEnergyMeasurement.Structs.MeasurementAccuracyStruct()) + value: ElectricalEnergyMeasurement.Structs.MeasurementAccuracyStruct = field(default_factory=lambda: ElectricalEnergyMeasurement.Structs.MeasurementAccuracyStruct()) @dataclass class CumulativeEnergyImported(ClusterAttributeDescriptor): @@ -23436,7 +23437,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, ElectricalEnergyMeasurement.Structs.EnergyMeasurementStruct]) - value: 'typing.Union[None, Nullable, ElectricalEnergyMeasurement.Structs.EnergyMeasurementStruct]' = None + value: typing.Union[None, Nullable, ElectricalEnergyMeasurement.Structs.EnergyMeasurementStruct] = None @dataclass class CumulativeEnergyExported(ClusterAttributeDescriptor): @@ -23452,7 +23453,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, ElectricalEnergyMeasurement.Structs.EnergyMeasurementStruct]) - value: 'typing.Union[None, Nullable, ElectricalEnergyMeasurement.Structs.EnergyMeasurementStruct]' = None + value: typing.Union[None, Nullable, ElectricalEnergyMeasurement.Structs.EnergyMeasurementStruct] = None @dataclass class PeriodicEnergyImported(ClusterAttributeDescriptor): @@ -23468,7 +23469,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, ElectricalEnergyMeasurement.Structs.EnergyMeasurementStruct]) - value: 'typing.Union[None, Nullable, ElectricalEnergyMeasurement.Structs.EnergyMeasurementStruct]' = None + value: typing.Union[None, Nullable, ElectricalEnergyMeasurement.Structs.EnergyMeasurementStruct] = None @dataclass class PeriodicEnergyExported(ClusterAttributeDescriptor): @@ -23484,7 +23485,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, ElectricalEnergyMeasurement.Structs.EnergyMeasurementStruct]) - value: 'typing.Union[None, Nullable, ElectricalEnergyMeasurement.Structs.EnergyMeasurementStruct]' = None + value: typing.Union[None, Nullable, ElectricalEnergyMeasurement.Structs.EnergyMeasurementStruct] = None @dataclass class CumulativeEnergyReset(ClusterAttributeDescriptor): @@ -23500,7 +23501,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, ElectricalEnergyMeasurement.Structs.CumulativeEnergyResetStruct]) - value: 'typing.Union[None, Nullable, ElectricalEnergyMeasurement.Structs.CumulativeEnergyResetStruct]' = None + value: typing.Union[None, Nullable, ElectricalEnergyMeasurement.Structs.CumulativeEnergyResetStruct] = None @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -23516,7 +23517,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -23532,7 +23533,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -23548,7 +23549,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -23564,7 +23565,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -23580,7 +23581,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -23596,7 +23597,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 class Events: @dataclass @@ -23617,8 +23618,8 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="energyExported", Tag=1, Type=typing.Optional[ElectricalEnergyMeasurement.Structs.EnergyMeasurementStruct]), ]) - energyImported: 'typing.Optional[ElectricalEnergyMeasurement.Structs.EnergyMeasurementStruct]' = None - energyExported: 'typing.Optional[ElectricalEnergyMeasurement.Structs.EnergyMeasurementStruct]' = None + energyImported: typing.Optional[ElectricalEnergyMeasurement.Structs.EnergyMeasurementStruct] = None + energyExported: typing.Optional[ElectricalEnergyMeasurement.Structs.EnergyMeasurementStruct] = None @dataclass class PeriodicEnergyMeasured(ClusterEvent): @@ -23638,8 +23639,8 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="energyExported", Tag=1, Type=typing.Optional[ElectricalEnergyMeasurement.Structs.EnergyMeasurementStruct]), ]) - energyImported: 'typing.Optional[ElectricalEnergyMeasurement.Structs.EnergyMeasurementStruct]' = None - energyExported: 'typing.Optional[ElectricalEnergyMeasurement.Structs.EnergyMeasurementStruct]' = None + energyImported: typing.Optional[ElectricalEnergyMeasurement.Structs.EnergyMeasurementStruct] = None + energyExported: typing.Optional[ElectricalEnergyMeasurement.Structs.EnergyMeasurementStruct] = None @dataclass @@ -23664,18 +23665,18 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - heaterTypes: 'uint' = None - heatDemand: 'uint' = None - tankVolume: 'typing.Optional[uint]' = None - estimatedHeatRequired: 'typing.Optional[int]' = None - tankPercentage: 'typing.Optional[uint]' = None - boostState: 'WaterHeaterManagement.Enums.BoostStateEnum' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + heaterTypes: uint = 0 + heatDemand: uint = 0 + tankVolume: typing.Optional[uint] = None + estimatedHeatRequired: typing.Optional[int] = None + tankPercentage: typing.Optional[uint] = None + boostState: WaterHeaterManagement.Enums.BoostStateEnum = 0 + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class BoostStateEnum(MatterIntEnum): @@ -23727,7 +23728,7 @@ class Boost(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000094 command_id: typing.ClassVar[int] = 0x00000000 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -23736,14 +23737,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="boostInfo", Tag=0, Type=WaterHeaterManagement.Structs.WaterHeaterBoostInfoStruct), ]) - boostInfo: 'WaterHeaterManagement.Structs.WaterHeaterBoostInfoStruct' = field(default_factory=lambda: WaterHeaterManagement.Structs.WaterHeaterBoostInfoStruct()) + boostInfo: WaterHeaterManagement.Structs.WaterHeaterBoostInfoStruct = field(default_factory=lambda: WaterHeaterManagement.Structs.WaterHeaterBoostInfoStruct()) @dataclass class CancelBoost(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000094 command_id: typing.ClassVar[int] = 0x00000001 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -23766,7 +23767,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class HeatDemand(ClusterAttributeDescriptor): @@ -23782,7 +23783,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class TankVolume(ClusterAttributeDescriptor): @@ -23798,7 +23799,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class EstimatedHeatRequired(ClusterAttributeDescriptor): @@ -23814,7 +23815,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[int]) - value: 'typing.Optional[int]' = None + value: typing.Optional[int] = None @dataclass class TankPercentage(ClusterAttributeDescriptor): @@ -23830,7 +23831,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class BoostState(ClusterAttributeDescriptor): @@ -23846,7 +23847,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=WaterHeaterManagement.Enums.BoostStateEnum) - value: 'WaterHeaterManagement.Enums.BoostStateEnum' = 0 + value: WaterHeaterManagement.Enums.BoostStateEnum = 0 @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -23862,7 +23863,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -23878,7 +23879,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -23894,7 +23895,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -23910,7 +23911,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -23926,7 +23927,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -23942,7 +23943,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 class Events: @dataclass @@ -23962,7 +23963,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="boostInfo", Tag=0, Type=WaterHeaterManagement.Structs.WaterHeaterBoostInfoStruct), ]) - boostInfo: 'WaterHeaterManagement.Structs.WaterHeaterBoostInfoStruct' = field(default_factory=lambda: WaterHeaterManagement.Structs.WaterHeaterBoostInfoStruct()) + boostInfo: WaterHeaterManagement.Structs.WaterHeaterBoostInfoStruct = field(default_factory=lambda: WaterHeaterManagement.Structs.WaterHeaterBoostInfoStruct()) @dataclass class BoostEnded(ClusterEvent): @@ -24005,20 +24006,20 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - loadControlPrograms: 'typing.List[DemandResponseLoadControl.Structs.LoadControlProgramStruct]' = None - numberOfLoadControlPrograms: 'uint' = None - events: 'typing.List[DemandResponseLoadControl.Structs.LoadControlEventStruct]' = None - activeEvents: 'typing.List[DemandResponseLoadControl.Structs.LoadControlEventStruct]' = None - numberOfEventsPerProgram: 'uint' = None - numberOfTransitions: 'uint' = None - defaultRandomStart: 'uint' = None - defaultRandomDuration: 'uint' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + loadControlPrograms: typing.List[DemandResponseLoadControl.Structs.LoadControlProgramStruct] = field(default_factory=lambda: []) + numberOfLoadControlPrograms: uint = 0 + events: typing.List[DemandResponseLoadControl.Structs.LoadControlEventStruct] = field(default_factory=lambda: []) + activeEvents: typing.List[DemandResponseLoadControl.Structs.LoadControlEventStruct] = field(default_factory=lambda: []) + numberOfEventsPerProgram: uint = 0 + numberOfTransitions: uint = 0 + defaultRandomStart: uint = 0 + defaultRandomDuration: uint = 0 + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class CriticalityLevelEnum(MatterIntEnum): @@ -24251,7 +24252,7 @@ class RegisterLoadControlProgramRequest(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000096 command_id: typing.ClassVar[int] = 0x00000000 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -24260,14 +24261,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="loadControlProgram", Tag=0, Type=DemandResponseLoadControl.Structs.LoadControlProgramStruct), ]) - loadControlProgram: 'DemandResponseLoadControl.Structs.LoadControlProgramStruct' = field(default_factory=lambda: DemandResponseLoadControl.Structs.LoadControlProgramStruct()) + loadControlProgram: DemandResponseLoadControl.Structs.LoadControlProgramStruct = field(default_factory=lambda: DemandResponseLoadControl.Structs.LoadControlProgramStruct()) @dataclass class UnregisterLoadControlProgramRequest(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000096 command_id: typing.ClassVar[int] = 0x00000001 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -24276,14 +24277,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="loadControlProgramID", Tag=0, Type=bytes), ]) - loadControlProgramID: 'bytes' = b"" + loadControlProgramID: bytes = b"" @dataclass class AddLoadControlEventRequest(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000096 command_id: typing.ClassVar[int] = 0x00000002 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -24292,14 +24293,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="event", Tag=0, Type=DemandResponseLoadControl.Structs.LoadControlEventStruct), ]) - event: 'DemandResponseLoadControl.Structs.LoadControlEventStruct' = field(default_factory=lambda: DemandResponseLoadControl.Structs.LoadControlEventStruct()) + event: DemandResponseLoadControl.Structs.LoadControlEventStruct = field(default_factory=lambda: DemandResponseLoadControl.Structs.LoadControlEventStruct()) @dataclass class RemoveLoadControlEventRequest(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000096 command_id: typing.ClassVar[int] = 0x00000003 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -24309,15 +24310,15 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="cancelControl", Tag=1, Type=uint), ]) - eventID: 'bytes' = b"" - cancelControl: 'uint' = 0 + eventID: bytes = b"" + cancelControl: uint = 0 @dataclass class ClearLoadControlEventsRequest(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000096 command_id: typing.ClassVar[int] = 0x00000004 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -24340,7 +24341,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[DemandResponseLoadControl.Structs.LoadControlProgramStruct]) - value: 'typing.List[DemandResponseLoadControl.Structs.LoadControlProgramStruct]' = field(default_factory=lambda: []) + value: typing.List[DemandResponseLoadControl.Structs.LoadControlProgramStruct] = field(default_factory=lambda: []) @dataclass class NumberOfLoadControlPrograms(ClusterAttributeDescriptor): @@ -24356,7 +24357,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class Events(ClusterAttributeDescriptor): @@ -24372,7 +24373,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[DemandResponseLoadControl.Structs.LoadControlEventStruct]) - value: 'typing.List[DemandResponseLoadControl.Structs.LoadControlEventStruct]' = field(default_factory=lambda: []) + value: typing.List[DemandResponseLoadControl.Structs.LoadControlEventStruct] = field(default_factory=lambda: []) @dataclass class ActiveEvents(ClusterAttributeDescriptor): @@ -24388,7 +24389,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[DemandResponseLoadControl.Structs.LoadControlEventStruct]) - value: 'typing.List[DemandResponseLoadControl.Structs.LoadControlEventStruct]' = field(default_factory=lambda: []) + value: typing.List[DemandResponseLoadControl.Structs.LoadControlEventStruct] = field(default_factory=lambda: []) @dataclass class NumberOfEventsPerProgram(ClusterAttributeDescriptor): @@ -24404,7 +24405,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class NumberOfTransitions(ClusterAttributeDescriptor): @@ -24420,7 +24421,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class DefaultRandomStart(ClusterAttributeDescriptor): @@ -24436,7 +24437,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class DefaultRandomDuration(ClusterAttributeDescriptor): @@ -24452,7 +24453,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -24468,7 +24469,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -24484,7 +24485,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -24500,7 +24501,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -24516,7 +24517,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -24532,7 +24533,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -24548,7 +24549,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 class Events: @dataclass @@ -24577,16 +24578,16 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="heatingSourceControl", Tag=9, Type=typing.Union[None, Nullable, DemandResponseLoadControl.Structs.HeatingSourceControlStruct]), ]) - eventID: 'bytes' = b"" - transitionIndex: 'typing.Union[Nullable, uint]' = NullValue - status: 'DemandResponseLoadControl.Enums.LoadControlEventStatusEnum' = 0 - criticality: 'DemandResponseLoadControl.Enums.CriticalityLevelEnum' = 0 - control: 'uint' = 0 - temperatureControl: 'typing.Union[None, Nullable, DemandResponseLoadControl.Structs.TemperatureControlStruct]' = None - averageLoadControl: 'typing.Union[None, Nullable, DemandResponseLoadControl.Structs.AverageLoadControlStruct]' = None - dutyCycleControl: 'typing.Union[None, Nullable, DemandResponseLoadControl.Structs.DutyCycleControlStruct]' = None - powerSavingsControl: 'typing.Union[None, Nullable, DemandResponseLoadControl.Structs.PowerSavingsControlStruct]' = None - heatingSourceControl: 'typing.Union[None, Nullable, DemandResponseLoadControl.Structs.HeatingSourceControlStruct]' = None + eventID: bytes = b"" + transitionIndex: typing.Union[Nullable, uint] = NullValue + status: DemandResponseLoadControl.Enums.LoadControlEventStatusEnum = 0 + criticality: DemandResponseLoadControl.Enums.CriticalityLevelEnum = 0 + control: uint = 0 + temperatureControl: typing.Union[None, Nullable, DemandResponseLoadControl.Structs.TemperatureControlStruct] = None + averageLoadControl: typing.Union[None, Nullable, DemandResponseLoadControl.Structs.AverageLoadControlStruct] = None + dutyCycleControl: typing.Union[None, Nullable, DemandResponseLoadControl.Structs.DutyCycleControlStruct] = None + powerSavingsControl: typing.Union[None, Nullable, DemandResponseLoadControl.Structs.PowerSavingsControlStruct] = None + heatingSourceControl: typing.Union[None, Nullable, DemandResponseLoadControl.Structs.HeatingSourceControlStruct] = None @dataclass @@ -24607,14 +24608,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - messages: 'typing.List[Messages.Structs.MessageStruct]' = None - activeMessageIDs: 'typing.List[bytes]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + messages: typing.List[Messages.Structs.MessageStruct] = field(default_factory=lambda: []) + activeMessageIDs: typing.List[bytes] = field(default_factory=lambda: []) + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class FutureMessagePreferenceEnum(MatterIntEnum): @@ -24697,7 +24698,7 @@ class PresentMessagesRequest(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000097 command_id: typing.ClassVar[int] = 0x00000000 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -24712,20 +24713,20 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="responses", Tag=6, Type=typing.Optional[typing.List[Messages.Structs.MessageResponseOptionStruct]]), ]) - messageID: 'bytes' = b"" - priority: 'Messages.Enums.MessagePriorityEnum' = 0 - messageControl: 'uint' = 0 - startTime: 'typing.Union[Nullable, uint]' = NullValue - duration: 'typing.Union[Nullable, uint]' = NullValue - messageText: 'str' = "" - responses: 'typing.Optional[typing.List[Messages.Structs.MessageResponseOptionStruct]]' = None + messageID: bytes = b"" + priority: Messages.Enums.MessagePriorityEnum = 0 + messageControl: uint = 0 + startTime: typing.Union[Nullable, uint] = NullValue + duration: typing.Union[Nullable, uint] = NullValue + messageText: str = "" + responses: typing.Optional[typing.List[Messages.Structs.MessageResponseOptionStruct]] = None @dataclass class CancelMessagesRequest(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000097 command_id: typing.ClassVar[int] = 0x00000001 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -24734,7 +24735,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="messageIDs", Tag=0, Type=typing.List[bytes]), ]) - messageIDs: 'typing.List[bytes]' = field(default_factory=lambda: []) + messageIDs: typing.List[bytes] = field(default_factory=lambda: []) class Attributes: @dataclass @@ -24751,7 +24752,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[Messages.Structs.MessageStruct]) - value: 'typing.List[Messages.Structs.MessageStruct]' = field(default_factory=lambda: []) + value: typing.List[Messages.Structs.MessageStruct] = field(default_factory=lambda: []) @dataclass class ActiveMessageIDs(ClusterAttributeDescriptor): @@ -24767,7 +24768,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[bytes]) - value: 'typing.List[bytes]' = field(default_factory=lambda: []) + value: typing.List[bytes] = field(default_factory=lambda: []) @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -24783,7 +24784,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -24799,7 +24800,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -24815,7 +24816,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -24831,7 +24832,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -24847,7 +24848,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -24863,7 +24864,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 class Events: @dataclass @@ -24883,7 +24884,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="messageID", Tag=0, Type=bytes), ]) - messageID: 'bytes' = b"" + messageID: bytes = b"" @dataclass class MessagePresented(ClusterEvent): @@ -24902,7 +24903,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="messageID", Tag=0, Type=bytes), ]) - messageID: 'bytes' = b"" + messageID: bytes = b"" @dataclass class MessageComplete(ClusterEvent): @@ -24924,10 +24925,10 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="futureMessagesPreference", Tag=3, Type=typing.Union[Nullable, Messages.Enums.FutureMessagePreferenceEnum]), ]) - messageID: 'bytes' = b"" - responseID: 'typing.Union[None, Nullable, uint]' = None - reply: 'typing.Union[None, Nullable, str]' = None - futureMessagesPreference: 'typing.Union[Nullable, Messages.Enums.FutureMessagePreferenceEnum]' = NullValue + messageID: bytes = b"" + responseID: typing.Union[None, Nullable, uint] = None + reply: typing.Union[None, Nullable, str] = None + futureMessagesPreference: typing.Union[Nullable, Messages.Enums.FutureMessagePreferenceEnum] = NullValue @dataclass @@ -24954,20 +24955,20 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - ESAType: 'DeviceEnergyManagement.Enums.ESATypeEnum' = None - ESACanGenerate: 'bool' = None - ESAState: 'DeviceEnergyManagement.Enums.ESAStateEnum' = None - absMinPower: 'int' = None - absMaxPower: 'int' = None - powerAdjustmentCapability: 'typing.Union[None, Nullable, DeviceEnergyManagement.Structs.PowerAdjustCapabilityStruct]' = None - forecast: 'typing.Union[None, Nullable, DeviceEnergyManagement.Structs.ForecastStruct]' = None - optOutState: 'typing.Optional[DeviceEnergyManagement.Enums.OptOutStateEnum]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + ESAType: DeviceEnergyManagement.Enums.ESATypeEnum = 0 + ESACanGenerate: bool = False + ESAState: DeviceEnergyManagement.Enums.ESAStateEnum = 0 + absMinPower: int = 0 + absMaxPower: int = 0 + powerAdjustmentCapability: typing.Union[None, Nullable, DeviceEnergyManagement.Structs.PowerAdjustCapabilityStruct] = None + forecast: typing.Union[None, Nullable, DeviceEnergyManagement.Structs.ForecastStruct] = None + optOutState: typing.Optional[DeviceEnergyManagement.Enums.OptOutStateEnum] = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class AdjustmentCauseEnum(MatterIntEnum): @@ -25237,7 +25238,7 @@ class PowerAdjustRequest(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000098 command_id: typing.ClassVar[int] = 0x00000000 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -25248,16 +25249,16 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="cause", Tag=2, Type=DeviceEnergyManagement.Enums.AdjustmentCauseEnum), ]) - power: 'int' = 0 - duration: 'uint' = 0 - cause: 'DeviceEnergyManagement.Enums.AdjustmentCauseEnum' = 0 + power: int = 0 + duration: uint = 0 + cause: DeviceEnergyManagement.Enums.AdjustmentCauseEnum = 0 @dataclass class CancelPowerAdjustRequest(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000098 command_id: typing.ClassVar[int] = 0x00000001 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -25270,7 +25271,7 @@ class StartTimeAdjustRequest(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000098 command_id: typing.ClassVar[int] = 0x00000002 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -25280,15 +25281,15 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="cause", Tag=1, Type=DeviceEnergyManagement.Enums.AdjustmentCauseEnum), ]) - requestedStartTime: 'uint' = 0 - cause: 'DeviceEnergyManagement.Enums.AdjustmentCauseEnum' = 0 + requestedStartTime: uint = 0 + cause: DeviceEnergyManagement.Enums.AdjustmentCauseEnum = 0 @dataclass class PauseRequest(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000098 command_id: typing.ClassVar[int] = 0x00000003 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -25298,15 +25299,15 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="cause", Tag=1, Type=DeviceEnergyManagement.Enums.AdjustmentCauseEnum), ]) - duration: 'uint' = 0 - cause: 'DeviceEnergyManagement.Enums.AdjustmentCauseEnum' = 0 + duration: uint = 0 + cause: DeviceEnergyManagement.Enums.AdjustmentCauseEnum = 0 @dataclass class ResumeRequest(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000098 command_id: typing.ClassVar[int] = 0x00000004 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -25319,7 +25320,7 @@ class ModifyForecastRequest(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000098 command_id: typing.ClassVar[int] = 0x00000005 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -25330,16 +25331,16 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="cause", Tag=2, Type=DeviceEnergyManagement.Enums.AdjustmentCauseEnum), ]) - forecastID: 'uint' = 0 - slotAdjustments: 'typing.List[DeviceEnergyManagement.Structs.SlotAdjustmentStruct]' = field(default_factory=lambda: []) - cause: 'DeviceEnergyManagement.Enums.AdjustmentCauseEnum' = 0 + forecastID: uint = 0 + slotAdjustments: typing.List[DeviceEnergyManagement.Structs.SlotAdjustmentStruct] = field(default_factory=lambda: []) + cause: DeviceEnergyManagement.Enums.AdjustmentCauseEnum = 0 @dataclass class RequestConstraintBasedForecast(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000098 command_id: typing.ClassVar[int] = 0x00000006 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -25349,15 +25350,15 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="cause", Tag=1, Type=DeviceEnergyManagement.Enums.AdjustmentCauseEnum), ]) - constraints: 'typing.List[DeviceEnergyManagement.Structs.ConstraintsStruct]' = field(default_factory=lambda: []) - cause: 'DeviceEnergyManagement.Enums.AdjustmentCauseEnum' = 0 + constraints: typing.List[DeviceEnergyManagement.Structs.ConstraintsStruct] = field(default_factory=lambda: []) + cause: DeviceEnergyManagement.Enums.AdjustmentCauseEnum = 0 @dataclass class CancelRequest(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000098 command_id: typing.ClassVar[int] = 0x00000007 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -25380,7 +25381,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=DeviceEnergyManagement.Enums.ESATypeEnum) - value: 'DeviceEnergyManagement.Enums.ESATypeEnum' = 0 + value: DeviceEnergyManagement.Enums.ESATypeEnum = 0 @dataclass class ESACanGenerate(ClusterAttributeDescriptor): @@ -25396,7 +25397,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=bool) - value: 'bool' = False + value: bool = False @dataclass class ESAState(ClusterAttributeDescriptor): @@ -25412,7 +25413,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=DeviceEnergyManagement.Enums.ESAStateEnum) - value: 'DeviceEnergyManagement.Enums.ESAStateEnum' = 0 + value: DeviceEnergyManagement.Enums.ESAStateEnum = 0 @dataclass class AbsMinPower(ClusterAttributeDescriptor): @@ -25428,7 +25429,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=int) - value: 'int' = 0 + value: int = 0 @dataclass class AbsMaxPower(ClusterAttributeDescriptor): @@ -25444,7 +25445,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=int) - value: 'int' = 0 + value: int = 0 @dataclass class PowerAdjustmentCapability(ClusterAttributeDescriptor): @@ -25460,7 +25461,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, DeviceEnergyManagement.Structs.PowerAdjustCapabilityStruct]) - value: 'typing.Union[None, Nullable, DeviceEnergyManagement.Structs.PowerAdjustCapabilityStruct]' = None + value: typing.Union[None, Nullable, DeviceEnergyManagement.Structs.PowerAdjustCapabilityStruct] = None @dataclass class Forecast(ClusterAttributeDescriptor): @@ -25476,7 +25477,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, DeviceEnergyManagement.Structs.ForecastStruct]) - value: 'typing.Union[None, Nullable, DeviceEnergyManagement.Structs.ForecastStruct]' = None + value: typing.Union[None, Nullable, DeviceEnergyManagement.Structs.ForecastStruct] = None @dataclass class OptOutState(ClusterAttributeDescriptor): @@ -25492,7 +25493,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[DeviceEnergyManagement.Enums.OptOutStateEnum]) - value: 'typing.Optional[DeviceEnergyManagement.Enums.OptOutStateEnum]' = None + value: typing.Optional[DeviceEnergyManagement.Enums.OptOutStateEnum] = None @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -25508,7 +25509,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -25524,7 +25525,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -25540,7 +25541,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -25556,7 +25557,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -25572,7 +25573,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -25588,7 +25589,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 class Events: @dataclass @@ -25626,9 +25627,9 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="energyUse", Tag=2, Type=int), ]) - cause: 'DeviceEnergyManagement.Enums.CauseEnum' = 0 - duration: 'uint' = 0 - energyUse: 'int' = 0 + cause: DeviceEnergyManagement.Enums.CauseEnum = 0 + duration: uint = 0 + energyUse: int = 0 @dataclass class Paused(ClusterEvent): @@ -25663,7 +25664,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="cause", Tag=0, Type=DeviceEnergyManagement.Enums.CauseEnum), ]) - cause: 'DeviceEnergyManagement.Enums.CauseEnum' = 0 + cause: DeviceEnergyManagement.Enums.CauseEnum = 0 @dataclass @@ -25705,35 +25706,35 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - state: 'typing.Union[Nullable, EnergyEvse.Enums.StateEnum]' = None - supplyState: 'EnergyEvse.Enums.SupplyStateEnum' = None - faultState: 'EnergyEvse.Enums.FaultStateEnum' = None - chargingEnabledUntil: 'typing.Union[Nullable, uint]' = None - dischargingEnabledUntil: 'typing.Union[None, Nullable, uint]' = None - circuitCapacity: 'int' = None - minimumChargeCurrent: 'int' = None - maximumChargeCurrent: 'int' = None - maximumDischargeCurrent: 'typing.Optional[int]' = None - userMaximumChargeCurrent: 'typing.Optional[int]' = None - randomizationDelayWindow: 'typing.Optional[uint]' = None - nextChargeStartTime: 'typing.Union[None, Nullable, uint]' = None - nextChargeTargetTime: 'typing.Union[None, Nullable, uint]' = None - nextChargeRequiredEnergy: 'typing.Union[None, Nullable, int]' = None - nextChargeTargetSoC: 'typing.Union[None, Nullable, uint]' = None - approximateEVEfficiency: 'typing.Union[None, Nullable, uint]' = None - stateOfCharge: 'typing.Union[None, Nullable, uint]' = None - batteryCapacity: 'typing.Union[None, Nullable, int]' = None - vehicleID: 'typing.Union[None, Nullable, str]' = None - sessionID: 'typing.Union[Nullable, uint]' = None - sessionDuration: 'typing.Union[Nullable, uint]' = None - sessionEnergyCharged: 'typing.Union[Nullable, int]' = None - sessionEnergyDischarged: 'typing.Union[None, Nullable, int]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + state: typing.Union[Nullable, EnergyEvse.Enums.StateEnum] = NullValue + supplyState: EnergyEvse.Enums.SupplyStateEnum = 0 + faultState: EnergyEvse.Enums.FaultStateEnum = 0 + chargingEnabledUntil: typing.Union[Nullable, uint] = NullValue + dischargingEnabledUntil: typing.Union[None, Nullable, uint] = None + circuitCapacity: int = 0 + minimumChargeCurrent: int = 0 + maximumChargeCurrent: int = 0 + maximumDischargeCurrent: typing.Optional[int] = None + userMaximumChargeCurrent: typing.Optional[int] = None + randomizationDelayWindow: typing.Optional[uint] = None + nextChargeStartTime: typing.Union[None, Nullable, uint] = None + nextChargeTargetTime: typing.Union[None, Nullable, uint] = None + nextChargeRequiredEnergy: typing.Union[None, Nullable, int] = None + nextChargeTargetSoC: typing.Union[None, Nullable, uint] = None + approximateEVEfficiency: typing.Union[None, Nullable, uint] = None + stateOfCharge: typing.Union[None, Nullable, uint] = None + batteryCapacity: typing.Union[None, Nullable, int] = None + vehicleID: typing.Union[None, Nullable, str] = None + sessionID: typing.Union[Nullable, uint] = NullValue + sessionDuration: typing.Union[Nullable, uint] = NullValue + sessionEnergyCharged: typing.Union[Nullable, int] = NullValue + sessionEnergyDischarged: typing.Union[None, Nullable, int] = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class EnergyTransferStoppedReasonEnum(MatterIntEnum): @@ -25849,7 +25850,7 @@ class GetTargetsResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000099 command_id: typing.ClassVar[int] = 0x00000000 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -25858,14 +25859,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="chargingTargetSchedules", Tag=0, Type=typing.List[EnergyEvse.Structs.ChargingTargetScheduleStruct]), ]) - chargingTargetSchedules: 'typing.List[EnergyEvse.Structs.ChargingTargetScheduleStruct]' = field(default_factory=lambda: []) + chargingTargetSchedules: typing.List[EnergyEvse.Structs.ChargingTargetScheduleStruct] = field(default_factory=lambda: []) @dataclass class Disable(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000099 command_id: typing.ClassVar[int] = 0x00000001 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -25882,7 +25883,7 @@ class EnableCharging(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000099 command_id: typing.ClassVar[int] = 0x00000002 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -25897,16 +25898,16 @@ def descriptor(cls) -> ClusterObjectDescriptor: def must_use_timed_invoke(cls) -> bool: return True - chargingEnabledUntil: 'typing.Union[Nullable, uint]' = NullValue - minimumChargeCurrent: 'int' = 0 - maximumChargeCurrent: 'int' = 0 + chargingEnabledUntil: typing.Union[Nullable, uint] = NullValue + minimumChargeCurrent: int = 0 + maximumChargeCurrent: int = 0 @dataclass class EnableDischarging(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000099 command_id: typing.ClassVar[int] = 0x00000003 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -25920,15 +25921,15 @@ def descriptor(cls) -> ClusterObjectDescriptor: def must_use_timed_invoke(cls) -> bool: return True - dischargingEnabledUntil: 'typing.Union[Nullable, uint]' = NullValue - maximumDischargeCurrent: 'int' = 0 + dischargingEnabledUntil: typing.Union[Nullable, uint] = NullValue + maximumDischargeCurrent: int = 0 @dataclass class StartDiagnostics(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000099 command_id: typing.ClassVar[int] = 0x00000004 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -25945,7 +25946,7 @@ class SetTargets(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000099 command_id: typing.ClassVar[int] = 0x00000005 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -25958,7 +25959,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: def must_use_timed_invoke(cls) -> bool: return True - chargingTargetSchedules: 'typing.List[EnergyEvse.Structs.ChargingTargetScheduleStruct]' = field(default_factory=lambda: []) + chargingTargetSchedules: typing.List[EnergyEvse.Structs.ChargingTargetScheduleStruct] = field(default_factory=lambda: []) @dataclass class GetTargets(ClusterCommand): @@ -25982,7 +25983,7 @@ class ClearTargets(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000099 command_id: typing.ClassVar[int] = 0x00000007 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -26009,7 +26010,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, EnergyEvse.Enums.StateEnum]) - value: 'typing.Union[Nullable, EnergyEvse.Enums.StateEnum]' = NullValue + value: typing.Union[Nullable, EnergyEvse.Enums.StateEnum] = NullValue @dataclass class SupplyState(ClusterAttributeDescriptor): @@ -26025,7 +26026,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=EnergyEvse.Enums.SupplyStateEnum) - value: 'EnergyEvse.Enums.SupplyStateEnum' = 0 + value: EnergyEvse.Enums.SupplyStateEnum = 0 @dataclass class FaultState(ClusterAttributeDescriptor): @@ -26041,7 +26042,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=EnergyEvse.Enums.FaultStateEnum) - value: 'EnergyEvse.Enums.FaultStateEnum' = 0 + value: EnergyEvse.Enums.FaultStateEnum = 0 @dataclass class ChargingEnabledUntil(ClusterAttributeDescriptor): @@ -26057,7 +26058,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, uint]) - value: 'typing.Union[Nullable, uint]' = NullValue + value: typing.Union[Nullable, uint] = NullValue @dataclass class DischargingEnabledUntil(ClusterAttributeDescriptor): @@ -26073,7 +26074,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class CircuitCapacity(ClusterAttributeDescriptor): @@ -26089,7 +26090,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=int) - value: 'int' = 0 + value: int = 0 @dataclass class MinimumChargeCurrent(ClusterAttributeDescriptor): @@ -26105,7 +26106,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=int) - value: 'int' = 0 + value: int = 0 @dataclass class MaximumChargeCurrent(ClusterAttributeDescriptor): @@ -26121,7 +26122,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=int) - value: 'int' = 0 + value: int = 0 @dataclass class MaximumDischargeCurrent(ClusterAttributeDescriptor): @@ -26137,7 +26138,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[int]) - value: 'typing.Optional[int]' = None + value: typing.Optional[int] = None @dataclass class UserMaximumChargeCurrent(ClusterAttributeDescriptor): @@ -26153,7 +26154,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[int]) - value: 'typing.Optional[int]' = None + value: typing.Optional[int] = None @dataclass class RandomizationDelayWindow(ClusterAttributeDescriptor): @@ -26169,7 +26170,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class NextChargeStartTime(ClusterAttributeDescriptor): @@ -26185,7 +26186,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class NextChargeTargetTime(ClusterAttributeDescriptor): @@ -26201,7 +26202,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class NextChargeRequiredEnergy(ClusterAttributeDescriptor): @@ -26217,7 +26218,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, int]) - value: 'typing.Union[None, Nullable, int]' = None + value: typing.Union[None, Nullable, int] = None @dataclass class NextChargeTargetSoC(ClusterAttributeDescriptor): @@ -26233,7 +26234,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class ApproximateEVEfficiency(ClusterAttributeDescriptor): @@ -26249,7 +26250,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class StateOfCharge(ClusterAttributeDescriptor): @@ -26265,7 +26266,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class BatteryCapacity(ClusterAttributeDescriptor): @@ -26281,7 +26282,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, int]) - value: 'typing.Union[None, Nullable, int]' = None + value: typing.Union[None, Nullable, int] = None @dataclass class VehicleID(ClusterAttributeDescriptor): @@ -26297,7 +26298,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, str]) - value: 'typing.Union[None, Nullable, str]' = None + value: typing.Union[None, Nullable, str] = None @dataclass class SessionID(ClusterAttributeDescriptor): @@ -26313,7 +26314,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, uint]) - value: 'typing.Union[Nullable, uint]' = NullValue + value: typing.Union[Nullable, uint] = NullValue @dataclass class SessionDuration(ClusterAttributeDescriptor): @@ -26329,7 +26330,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, uint]) - value: 'typing.Union[Nullable, uint]' = NullValue + value: typing.Union[Nullable, uint] = NullValue @dataclass class SessionEnergyCharged(ClusterAttributeDescriptor): @@ -26345,7 +26346,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, int]) - value: 'typing.Union[Nullable, int]' = NullValue + value: typing.Union[Nullable, int] = NullValue @dataclass class SessionEnergyDischarged(ClusterAttributeDescriptor): @@ -26361,7 +26362,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, int]) - value: 'typing.Union[None, Nullable, int]' = None + value: typing.Union[None, Nullable, int] = None @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -26377,7 +26378,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -26393,7 +26394,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -26409,7 +26410,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -26425,7 +26426,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -26441,7 +26442,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -26457,7 +26458,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 class Events: @dataclass @@ -26477,7 +26478,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="sessionID", Tag=0, Type=uint), ]) - sessionID: 'uint' = 0 + sessionID: uint = 0 @dataclass class EVNotDetected(ClusterEvent): @@ -26500,11 +26501,11 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="sessionEnergyDischarged", Tag=4, Type=typing.Optional[int]), ]) - sessionID: 'uint' = 0 - state: 'EnergyEvse.Enums.StateEnum' = 0 - sessionDuration: 'uint' = 0 - sessionEnergyCharged: 'int' = 0 - sessionEnergyDischarged: 'typing.Optional[int]' = None + sessionID: uint = 0 + state: EnergyEvse.Enums.StateEnum = 0 + sessionDuration: uint = 0 + sessionEnergyCharged: int = 0 + sessionEnergyDischarged: typing.Optional[int] = None @dataclass class EnergyTransferStarted(ClusterEvent): @@ -26526,10 +26527,10 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="maximumDischargeCurrent", Tag=3, Type=typing.Optional[int]), ]) - sessionID: 'uint' = 0 - state: 'EnergyEvse.Enums.StateEnum' = 0 - maximumCurrent: 'int' = 0 - maximumDischargeCurrent: 'typing.Optional[int]' = None + sessionID: uint = 0 + state: EnergyEvse.Enums.StateEnum = 0 + maximumCurrent: int = 0 + maximumDischargeCurrent: typing.Optional[int] = None @dataclass class EnergyTransferStopped(ClusterEvent): @@ -26552,11 +26553,11 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="energyDischarged", Tag=5, Type=typing.Optional[int]), ]) - sessionID: 'uint' = 0 - state: 'EnergyEvse.Enums.StateEnum' = 0 - reason: 'EnergyEvse.Enums.EnergyTransferStoppedReasonEnum' = 0 - energyTransferred: 'int' = 0 - energyDischarged: 'typing.Optional[int]' = None + sessionID: uint = 0 + state: EnergyEvse.Enums.StateEnum = 0 + reason: EnergyEvse.Enums.EnergyTransferStoppedReasonEnum = 0 + energyTransferred: int = 0 + energyDischarged: typing.Optional[int] = None @dataclass class Fault(ClusterEvent): @@ -26578,10 +26579,10 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="faultStateCurrentState", Tag=4, Type=EnergyEvse.Enums.FaultStateEnum), ]) - sessionID: 'typing.Union[Nullable, uint]' = NullValue - state: 'EnergyEvse.Enums.StateEnum' = 0 - faultStatePreviousState: 'EnergyEvse.Enums.FaultStateEnum' = 0 - faultStateCurrentState: 'EnergyEvse.Enums.FaultStateEnum' = 0 + sessionID: typing.Union[Nullable, uint] = NullValue + state: EnergyEvse.Enums.StateEnum = 0 + faultStatePreviousState: EnergyEvse.Enums.FaultStateEnum = 0 + faultStateCurrentState: EnergyEvse.Enums.FaultStateEnum = 0 @dataclass class Rfid(ClusterEvent): @@ -26600,7 +26601,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="uid", Tag=0, Type=bytes), ]) - uid: 'bytes' = b"" + uid: bytes = b"" @dataclass @@ -26624,17 +26625,17 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - energyBalances: 'typing.Optional[typing.List[EnergyPreference.Structs.BalanceStruct]]' = None - currentEnergyBalance: 'typing.Optional[uint]' = None - energyPriorities: 'typing.Optional[typing.List[EnergyPreference.Enums.EnergyPriorityEnum]]' = None - lowPowerModeSensitivities: 'typing.Optional[typing.List[EnergyPreference.Structs.BalanceStruct]]' = None - currentLowPowerModeSensitivity: 'typing.Optional[uint]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + energyBalances: typing.Optional[typing.List[EnergyPreference.Structs.BalanceStruct]] = None + currentEnergyBalance: typing.Optional[uint] = None + energyPriorities: typing.Optional[typing.List[EnergyPreference.Enums.EnergyPriorityEnum]] = None + lowPowerModeSensitivities: typing.Optional[typing.List[EnergyPreference.Structs.BalanceStruct]] = None + currentLowPowerModeSensitivity: typing.Optional[uint] = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class EnergyPriorityEnum(MatterIntEnum): @@ -26682,7 +26683,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[typing.List[EnergyPreference.Structs.BalanceStruct]]) - value: 'typing.Optional[typing.List[EnergyPreference.Structs.BalanceStruct]]' = None + value: typing.Optional[typing.List[EnergyPreference.Structs.BalanceStruct]] = None @dataclass class CurrentEnergyBalance(ClusterAttributeDescriptor): @@ -26698,7 +26699,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class EnergyPriorities(ClusterAttributeDescriptor): @@ -26714,7 +26715,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[typing.List[EnergyPreference.Enums.EnergyPriorityEnum]]) - value: 'typing.Optional[typing.List[EnergyPreference.Enums.EnergyPriorityEnum]]' = None + value: typing.Optional[typing.List[EnergyPreference.Enums.EnergyPriorityEnum]] = None @dataclass class LowPowerModeSensitivities(ClusterAttributeDescriptor): @@ -26730,7 +26731,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[typing.List[EnergyPreference.Structs.BalanceStruct]]) - value: 'typing.Optional[typing.List[EnergyPreference.Structs.BalanceStruct]]' = None + value: typing.Optional[typing.List[EnergyPreference.Structs.BalanceStruct]] = None @dataclass class CurrentLowPowerModeSensitivity(ClusterAttributeDescriptor): @@ -26746,7 +26747,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -26762,7 +26763,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -26778,7 +26779,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -26794,7 +26795,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -26810,7 +26811,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -26826,7 +26827,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -26842,7 +26843,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -26863,14 +26864,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - availableEndpoints: 'typing.Optional[typing.List[uint]]' = None - activeEndpoints: 'typing.Optional[typing.List[uint]]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + availableEndpoints: typing.Optional[typing.List[uint]] = None + activeEndpoints: typing.Optional[typing.List[uint]] = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Bitmaps: class Feature(IntFlag): @@ -26894,7 +26895,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[typing.List[uint]]) - value: 'typing.Optional[typing.List[uint]]' = None + value: typing.Optional[typing.List[uint]] = None @dataclass class ActiveEndpoints(ClusterAttributeDescriptor): @@ -26910,7 +26911,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[typing.List[uint]]) - value: 'typing.Optional[typing.List[uint]]' = None + value: typing.Optional[typing.List[uint]] = None @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -26926,7 +26927,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -26942,7 +26943,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -26958,7 +26959,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -26974,7 +26975,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -26990,7 +26991,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -27006,7 +27007,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -27029,16 +27030,16 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - supportedModes: 'typing.List[EnergyEvseMode.Structs.ModeOptionStruct]' = None - currentMode: 'uint' = None - startUpMode: 'typing.Union[None, Nullable, uint]' = None - onMode: 'typing.Union[None, Nullable, uint]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + supportedModes: typing.List[EnergyEvseMode.Structs.ModeOptionStruct] = field(default_factory=lambda: []) + currentMode: uint = 0 + startUpMode: typing.Union[None, Nullable, uint] = None + onMode: typing.Union[None, Nullable, uint] = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class ModeTag(MatterIntEnum): @@ -27109,14 +27110,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="newMode", Tag=0, Type=uint), ]) - newMode: 'uint' = 0 + newMode: uint = 0 @dataclass class ChangeToModeResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x0000009D command_id: typing.ClassVar[int] = 0x00000001 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -27126,8 +27127,8 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="statusText", Tag=1, Type=typing.Optional[str]), ]) - status: 'uint' = 0 - statusText: 'typing.Optional[str]' = None + status: uint = 0 + statusText: typing.Optional[str] = None class Attributes: @dataclass @@ -27144,7 +27145,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[EnergyEvseMode.Structs.ModeOptionStruct]) - value: 'typing.List[EnergyEvseMode.Structs.ModeOptionStruct]' = field(default_factory=lambda: []) + value: typing.List[EnergyEvseMode.Structs.ModeOptionStruct] = field(default_factory=lambda: []) @dataclass class CurrentMode(ClusterAttributeDescriptor): @@ -27160,7 +27161,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class StartUpMode(ClusterAttributeDescriptor): @@ -27176,7 +27177,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class OnMode(ClusterAttributeDescriptor): @@ -27192,7 +27193,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -27208,7 +27209,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -27224,7 +27225,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -27240,7 +27241,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -27256,7 +27257,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -27272,7 +27273,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -27288,7 +27289,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -27311,16 +27312,16 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - supportedModes: 'typing.List[WaterHeaterMode.Structs.ModeOptionStruct]' = None - currentMode: 'uint' = None - startUpMode: 'typing.Union[None, Nullable, uint]' = None - onMode: 'typing.Union[None, Nullable, uint]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + supportedModes: typing.List[WaterHeaterMode.Structs.ModeOptionStruct] = field(default_factory=lambda: []) + currentMode: uint = 0 + startUpMode: typing.Union[None, Nullable, uint] = None + onMode: typing.Union[None, Nullable, uint] = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class ModeTag(MatterIntEnum): @@ -27391,14 +27392,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="newMode", Tag=0, Type=uint), ]) - newMode: 'uint' = 0 + newMode: uint = 0 @dataclass class ChangeToModeResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x0000009E command_id: typing.ClassVar[int] = 0x00000001 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -27408,8 +27409,8 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="statusText", Tag=1, Type=typing.Optional[str]), ]) - status: 'uint' = 0 - statusText: 'typing.Optional[str]' = None + status: uint = 0 + statusText: typing.Optional[str] = None class Attributes: @dataclass @@ -27426,7 +27427,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[WaterHeaterMode.Structs.ModeOptionStruct]) - value: 'typing.List[WaterHeaterMode.Structs.ModeOptionStruct]' = field(default_factory=lambda: []) + value: typing.List[WaterHeaterMode.Structs.ModeOptionStruct] = field(default_factory=lambda: []) @dataclass class CurrentMode(ClusterAttributeDescriptor): @@ -27442,7 +27443,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class StartUpMode(ClusterAttributeDescriptor): @@ -27458,7 +27459,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class OnMode(ClusterAttributeDescriptor): @@ -27474,7 +27475,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -27490,7 +27491,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -27506,7 +27507,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -27522,7 +27523,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -27538,7 +27539,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -27554,7 +27555,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -27570,7 +27571,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -27593,16 +27594,16 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - supportedModes: 'typing.List[DeviceEnergyManagementMode.Structs.ModeOptionStruct]' = None - currentMode: 'uint' = None - startUpMode: 'typing.Union[None, Nullable, uint]' = None - onMode: 'typing.Union[None, Nullable, uint]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + supportedModes: typing.List[DeviceEnergyManagementMode.Structs.ModeOptionStruct] = field(default_factory=lambda: []) + currentMode: uint = 0 + startUpMode: typing.Union[None, Nullable, uint] = None + onMode: typing.Union[None, Nullable, uint] = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class ModeTag(MatterIntEnum): @@ -27674,14 +27675,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="newMode", Tag=0, Type=uint), ]) - newMode: 'uint' = 0 + newMode: uint = 0 @dataclass class ChangeToModeResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x0000009F command_id: typing.ClassVar[int] = 0x00000001 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -27691,8 +27692,8 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="statusText", Tag=1, Type=typing.Optional[str]), ]) - status: 'uint' = 0 - statusText: 'typing.Optional[str]' = None + status: uint = 0 + statusText: typing.Optional[str] = None class Attributes: @dataclass @@ -27709,7 +27710,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[DeviceEnergyManagementMode.Structs.ModeOptionStruct]) - value: 'typing.List[DeviceEnergyManagementMode.Structs.ModeOptionStruct]' = field(default_factory=lambda: []) + value: typing.List[DeviceEnergyManagementMode.Structs.ModeOptionStruct] = field(default_factory=lambda: []) @dataclass class CurrentMode(ClusterAttributeDescriptor): @@ -27725,7 +27726,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class StartUpMode(ClusterAttributeDescriptor): @@ -27741,7 +27742,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class OnMode(ClusterAttributeDescriptor): @@ -27757,7 +27758,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -27773,7 +27774,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -27789,7 +27790,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -27805,7 +27806,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -27821,7 +27822,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -27837,7 +27838,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -27853,7 +27854,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -27917,57 +27918,57 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - lockState: 'typing.Union[Nullable, DoorLock.Enums.DlLockState]' = None - lockType: 'DoorLock.Enums.DlLockType' = None - actuatorEnabled: 'bool' = None - doorState: 'typing.Union[None, Nullable, DoorLock.Enums.DoorStateEnum]' = None - doorOpenEvents: 'typing.Optional[uint]' = None - doorClosedEvents: 'typing.Optional[uint]' = None - openPeriod: 'typing.Optional[uint]' = None - numberOfTotalUsersSupported: 'typing.Optional[uint]' = None - numberOfPINUsersSupported: 'typing.Optional[uint]' = None - numberOfRFIDUsersSupported: 'typing.Optional[uint]' = None - numberOfWeekDaySchedulesSupportedPerUser: 'typing.Optional[uint]' = None - numberOfYearDaySchedulesSupportedPerUser: 'typing.Optional[uint]' = None - numberOfHolidaySchedulesSupported: 'typing.Optional[uint]' = None - maxPINCodeLength: 'typing.Optional[uint]' = None - minPINCodeLength: 'typing.Optional[uint]' = None - maxRFIDCodeLength: 'typing.Optional[uint]' = None - minRFIDCodeLength: 'typing.Optional[uint]' = None - credentialRulesSupport: 'typing.Optional[uint]' = None - numberOfCredentialsSupportedPerUser: 'typing.Optional[uint]' = None - language: 'typing.Optional[str]' = None - LEDSettings: 'typing.Optional[uint]' = None - autoRelockTime: 'typing.Optional[uint]' = None - soundVolume: 'typing.Optional[uint]' = None - operatingMode: 'DoorLock.Enums.OperatingModeEnum' = None - supportedOperatingModes: 'uint' = None - defaultConfigurationRegister: 'typing.Optional[uint]' = None - enableLocalProgramming: 'typing.Optional[bool]' = None - enableOneTouchLocking: 'typing.Optional[bool]' = None - enableInsideStatusLED: 'typing.Optional[bool]' = None - enablePrivacyModeButton: 'typing.Optional[bool]' = None - localProgrammingFeatures: 'typing.Optional[uint]' = None - wrongCodeEntryLimit: 'typing.Optional[uint]' = None - userCodeTemporaryDisableTime: 'typing.Optional[uint]' = None - sendPINOverTheAir: 'typing.Optional[bool]' = None - requirePINforRemoteOperation: 'typing.Optional[bool]' = None - expiringUserTimeout: 'typing.Optional[uint]' = None - aliroReaderVerificationKey: 'typing.Union[None, Nullable, bytes]' = None - aliroReaderGroupIdentifier: 'typing.Union[None, Nullable, bytes]' = None - aliroReaderGroupSubIdentifier: 'typing.Optional[bytes]' = None - aliroExpeditedTransactionSupportedProtocolVersions: 'typing.Optional[typing.List[bytes]]' = None - aliroGroupResolvingKey: 'typing.Union[None, Nullable, bytes]' = None - aliroSupportedBLEUWBProtocolVersions: 'typing.Optional[typing.List[bytes]]' = None - aliroBLEAdvertisingVersion: 'typing.Optional[uint]' = None - numberOfAliroCredentialIssuerKeysSupported: 'typing.Optional[uint]' = None - numberOfAliroEndpointKeysSupported: 'typing.Optional[uint]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + lockState: typing.Union[Nullable, DoorLock.Enums.DlLockState] = NullValue + lockType: DoorLock.Enums.DlLockType = 0 + actuatorEnabled: bool = False + doorState: typing.Union[None, Nullable, DoorLock.Enums.DoorStateEnum] = None + doorOpenEvents: typing.Optional[uint] = None + doorClosedEvents: typing.Optional[uint] = None + openPeriod: typing.Optional[uint] = None + numberOfTotalUsersSupported: typing.Optional[uint] = None + numberOfPINUsersSupported: typing.Optional[uint] = None + numberOfRFIDUsersSupported: typing.Optional[uint] = None + numberOfWeekDaySchedulesSupportedPerUser: typing.Optional[uint] = None + numberOfYearDaySchedulesSupportedPerUser: typing.Optional[uint] = None + numberOfHolidaySchedulesSupported: typing.Optional[uint] = None + maxPINCodeLength: typing.Optional[uint] = None + minPINCodeLength: typing.Optional[uint] = None + maxRFIDCodeLength: typing.Optional[uint] = None + minRFIDCodeLength: typing.Optional[uint] = None + credentialRulesSupport: typing.Optional[uint] = None + numberOfCredentialsSupportedPerUser: typing.Optional[uint] = None + language: typing.Optional[str] = None + LEDSettings: typing.Optional[uint] = None + autoRelockTime: typing.Optional[uint] = None + soundVolume: typing.Optional[uint] = None + operatingMode: DoorLock.Enums.OperatingModeEnum = 0 + supportedOperatingModes: uint = 0 + defaultConfigurationRegister: typing.Optional[uint] = None + enableLocalProgramming: typing.Optional[bool] = None + enableOneTouchLocking: typing.Optional[bool] = None + enableInsideStatusLED: typing.Optional[bool] = None + enablePrivacyModeButton: typing.Optional[bool] = None + localProgrammingFeatures: typing.Optional[uint] = None + wrongCodeEntryLimit: typing.Optional[uint] = None + userCodeTemporaryDisableTime: typing.Optional[uint] = None + sendPINOverTheAir: typing.Optional[bool] = None + requirePINforRemoteOperation: typing.Optional[bool] = None + expiringUserTimeout: typing.Optional[uint] = None + aliroReaderVerificationKey: typing.Union[None, Nullable, bytes] = None + aliroReaderGroupIdentifier: typing.Union[None, Nullable, bytes] = None + aliroReaderGroupSubIdentifier: typing.Optional[bytes] = None + aliroExpeditedTransactionSupportedProtocolVersions: typing.Optional[typing.List[bytes]] = None + aliroGroupResolvingKey: typing.Union[None, Nullable, bytes] = None + aliroSupportedBLEUWBProtocolVersions: typing.Optional[typing.List[bytes]] = None + aliroBLEAdvertisingVersion: typing.Optional[uint] = None + numberOfAliroCredentialIssuerKeysSupported: typing.Optional[uint] = None + numberOfAliroEndpointKeysSupported: typing.Optional[uint] = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class AlarmCodeEnum(MatterIntEnum): @@ -28400,7 +28401,7 @@ class LockDoor(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000101 command_id: typing.ClassVar[int] = 0x00000000 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -28413,14 +28414,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: def must_use_timed_invoke(cls) -> bool: return True - PINCode: 'typing.Optional[bytes]' = None + PINCode: typing.Optional[bytes] = None @dataclass class UnlockDoor(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000101 command_id: typing.ClassVar[int] = 0x00000001 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -28433,14 +28434,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: def must_use_timed_invoke(cls) -> bool: return True - PINCode: 'typing.Optional[bytes]' = None + PINCode: typing.Optional[bytes] = None @dataclass class UnlockWithTimeout(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000101 command_id: typing.ClassVar[int] = 0x00000003 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -28454,15 +28455,15 @@ def descriptor(cls) -> ClusterObjectDescriptor: def must_use_timed_invoke(cls) -> bool: return True - timeout: 'uint' = 0 - PINCode: 'typing.Optional[bytes]' = None + timeout: uint = 0 + PINCode: typing.Optional[bytes] = None @dataclass class SetWeekDaySchedule(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000101 command_id: typing.ClassVar[int] = 0x0000000B is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -28477,13 +28478,13 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="endMinute", Tag=6, Type=uint), ]) - weekDayIndex: 'uint' = 0 - userIndex: 'uint' = 0 - daysMask: 'uint' = 0 - startHour: 'uint' = 0 - startMinute: 'uint' = 0 - endHour: 'uint' = 0 - endMinute: 'uint' = 0 + weekDayIndex: uint = 0 + userIndex: uint = 0 + daysMask: uint = 0 + startHour: uint = 0 + startMinute: uint = 0 + endHour: uint = 0 + endMinute: uint = 0 @dataclass class GetWeekDaySchedule(ClusterCommand): @@ -28500,15 +28501,15 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="userIndex", Tag=1, Type=uint), ]) - weekDayIndex: 'uint' = 0 - userIndex: 'uint' = 0 + weekDayIndex: uint = 0 + userIndex: uint = 0 @dataclass class GetWeekDayScheduleResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000101 command_id: typing.ClassVar[int] = 0x0000000C is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -28524,21 +28525,21 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="endMinute", Tag=7, Type=typing.Optional[uint]), ]) - weekDayIndex: 'uint' = 0 - userIndex: 'uint' = 0 - status: 'DoorLock.Enums.DlStatus' = 0 - daysMask: 'typing.Optional[uint]' = None - startHour: 'typing.Optional[uint]' = None - startMinute: 'typing.Optional[uint]' = None - endHour: 'typing.Optional[uint]' = None - endMinute: 'typing.Optional[uint]' = None + weekDayIndex: uint = 0 + userIndex: uint = 0 + status: DoorLock.Enums.DlStatus = 0 + daysMask: typing.Optional[uint] = None + startHour: typing.Optional[uint] = None + startMinute: typing.Optional[uint] = None + endHour: typing.Optional[uint] = None + endMinute: typing.Optional[uint] = None @dataclass class ClearWeekDaySchedule(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000101 command_id: typing.ClassVar[int] = 0x0000000D is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -28548,15 +28549,15 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="userIndex", Tag=1, Type=uint), ]) - weekDayIndex: 'uint' = 0 - userIndex: 'uint' = 0 + weekDayIndex: uint = 0 + userIndex: uint = 0 @dataclass class SetYearDaySchedule(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000101 command_id: typing.ClassVar[int] = 0x0000000E is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -28568,10 +28569,10 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="localEndTime", Tag=3, Type=uint), ]) - yearDayIndex: 'uint' = 0 - userIndex: 'uint' = 0 - localStartTime: 'uint' = 0 - localEndTime: 'uint' = 0 + yearDayIndex: uint = 0 + userIndex: uint = 0 + localStartTime: uint = 0 + localEndTime: uint = 0 @dataclass class GetYearDaySchedule(ClusterCommand): @@ -28588,15 +28589,15 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="userIndex", Tag=1, Type=uint), ]) - yearDayIndex: 'uint' = 0 - userIndex: 'uint' = 0 + yearDayIndex: uint = 0 + userIndex: uint = 0 @dataclass class GetYearDayScheduleResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000101 command_id: typing.ClassVar[int] = 0x0000000F is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -28609,18 +28610,18 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="localEndTime", Tag=4, Type=typing.Optional[uint]), ]) - yearDayIndex: 'uint' = 0 - userIndex: 'uint' = 0 - status: 'DoorLock.Enums.DlStatus' = 0 - localStartTime: 'typing.Optional[uint]' = None - localEndTime: 'typing.Optional[uint]' = None + yearDayIndex: uint = 0 + userIndex: uint = 0 + status: DoorLock.Enums.DlStatus = 0 + localStartTime: typing.Optional[uint] = None + localEndTime: typing.Optional[uint] = None @dataclass class ClearYearDaySchedule(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000101 command_id: typing.ClassVar[int] = 0x00000010 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -28630,15 +28631,15 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="userIndex", Tag=1, Type=uint), ]) - yearDayIndex: 'uint' = 0 - userIndex: 'uint' = 0 + yearDayIndex: uint = 0 + userIndex: uint = 0 @dataclass class SetHolidaySchedule(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000101 command_id: typing.ClassVar[int] = 0x00000011 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -28650,10 +28651,10 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="operatingMode", Tag=3, Type=DoorLock.Enums.OperatingModeEnum), ]) - holidayIndex: 'uint' = 0 - localStartTime: 'uint' = 0 - localEndTime: 'uint' = 0 - operatingMode: 'DoorLock.Enums.OperatingModeEnum' = 0 + holidayIndex: uint = 0 + localStartTime: uint = 0 + localEndTime: uint = 0 + operatingMode: DoorLock.Enums.OperatingModeEnum = 0 @dataclass class GetHolidaySchedule(ClusterCommand): @@ -28669,14 +28670,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="holidayIndex", Tag=0, Type=uint), ]) - holidayIndex: 'uint' = 0 + holidayIndex: uint = 0 @dataclass class GetHolidayScheduleResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000101 command_id: typing.ClassVar[int] = 0x00000012 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -28689,18 +28690,18 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="operatingMode", Tag=4, Type=typing.Optional[DoorLock.Enums.OperatingModeEnum]), ]) - holidayIndex: 'uint' = 0 - status: 'DoorLock.Enums.DlStatus' = 0 - localStartTime: 'typing.Optional[uint]' = None - localEndTime: 'typing.Optional[uint]' = None - operatingMode: 'typing.Optional[DoorLock.Enums.OperatingModeEnum]' = None + holidayIndex: uint = 0 + status: DoorLock.Enums.DlStatus = 0 + localStartTime: typing.Optional[uint] = None + localEndTime: typing.Optional[uint] = None + operatingMode: typing.Optional[DoorLock.Enums.OperatingModeEnum] = None @dataclass class ClearHolidaySchedule(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000101 command_id: typing.ClassVar[int] = 0x00000013 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -28709,14 +28710,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="holidayIndex", Tag=0, Type=uint), ]) - holidayIndex: 'uint' = 0 + holidayIndex: uint = 0 @dataclass class SetUser(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000101 command_id: typing.ClassVar[int] = 0x0000001A is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -28735,13 +28736,13 @@ def descriptor(cls) -> ClusterObjectDescriptor: def must_use_timed_invoke(cls) -> bool: return True - operationType: 'DoorLock.Enums.DataOperationTypeEnum' = 0 - userIndex: 'uint' = 0 - userName: 'typing.Union[Nullable, str]' = NullValue - userUniqueID: 'typing.Union[Nullable, uint]' = NullValue - userStatus: 'typing.Union[Nullable, DoorLock.Enums.UserStatusEnum]' = NullValue - userType: 'typing.Union[Nullable, DoorLock.Enums.UserTypeEnum]' = NullValue - credentialRule: 'typing.Union[Nullable, DoorLock.Enums.CredentialRuleEnum]' = NullValue + operationType: DoorLock.Enums.DataOperationTypeEnum = 0 + userIndex: uint = 0 + userName: typing.Union[Nullable, str] = NullValue + userUniqueID: typing.Union[Nullable, uint] = NullValue + userStatus: typing.Union[Nullable, DoorLock.Enums.UserStatusEnum] = NullValue + userType: typing.Union[Nullable, DoorLock.Enums.UserTypeEnum] = NullValue + credentialRule: typing.Union[Nullable, DoorLock.Enums.CredentialRuleEnum] = NullValue @dataclass class GetUser(ClusterCommand): @@ -28757,14 +28758,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="userIndex", Tag=0, Type=uint), ]) - userIndex: 'uint' = 0 + userIndex: uint = 0 @dataclass class GetUserResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000101 command_id: typing.ClassVar[int] = 0x0000001C is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -28782,23 +28783,23 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="nextUserIndex", Tag=9, Type=typing.Union[Nullable, uint]), ]) - userIndex: 'uint' = 0 - userName: 'typing.Union[Nullable, str]' = NullValue - userUniqueID: 'typing.Union[Nullable, uint]' = NullValue - userStatus: 'typing.Union[Nullable, DoorLock.Enums.UserStatusEnum]' = NullValue - userType: 'typing.Union[Nullable, DoorLock.Enums.UserTypeEnum]' = NullValue - credentialRule: 'typing.Union[Nullable, DoorLock.Enums.CredentialRuleEnum]' = NullValue - credentials: 'typing.Union[Nullable, typing.List[DoorLock.Structs.CredentialStruct]]' = NullValue - creatorFabricIndex: 'typing.Union[Nullable, uint]' = NullValue - lastModifiedFabricIndex: 'typing.Union[Nullable, uint]' = NullValue - nextUserIndex: 'typing.Union[Nullable, uint]' = NullValue + userIndex: uint = 0 + userName: typing.Union[Nullable, str] = NullValue + userUniqueID: typing.Union[Nullable, uint] = NullValue + userStatus: typing.Union[Nullable, DoorLock.Enums.UserStatusEnum] = NullValue + userType: typing.Union[Nullable, DoorLock.Enums.UserTypeEnum] = NullValue + credentialRule: typing.Union[Nullable, DoorLock.Enums.CredentialRuleEnum] = NullValue + credentials: typing.Union[Nullable, typing.List[DoorLock.Structs.CredentialStruct]] = NullValue + creatorFabricIndex: typing.Union[Nullable, uint] = NullValue + lastModifiedFabricIndex: typing.Union[Nullable, uint] = NullValue + nextUserIndex: typing.Union[Nullable, uint] = NullValue @dataclass class ClearUser(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000101 command_id: typing.ClassVar[int] = 0x0000001D is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -28811,7 +28812,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: def must_use_timed_invoke(cls) -> bool: return True - userIndex: 'uint' = 0 + userIndex: uint = 0 @dataclass class SetCredential(ClusterCommand): @@ -28836,19 +28837,19 @@ def descriptor(cls) -> ClusterObjectDescriptor: def must_use_timed_invoke(cls) -> bool: return True - operationType: 'DoorLock.Enums.DataOperationTypeEnum' = 0 - credential: 'DoorLock.Structs.CredentialStruct' = field(default_factory=lambda: DoorLock.Structs.CredentialStruct()) - credentialData: 'bytes' = b"" - userIndex: 'typing.Union[Nullable, uint]' = NullValue - userStatus: 'typing.Union[Nullable, DoorLock.Enums.UserStatusEnum]' = NullValue - userType: 'typing.Union[Nullable, DoorLock.Enums.UserTypeEnum]' = NullValue + operationType: DoorLock.Enums.DataOperationTypeEnum = 0 + credential: DoorLock.Structs.CredentialStruct = field(default_factory=lambda: DoorLock.Structs.CredentialStruct()) + credentialData: bytes = b"" + userIndex: typing.Union[Nullable, uint] = NullValue + userStatus: typing.Union[Nullable, DoorLock.Enums.UserStatusEnum] = NullValue + userType: typing.Union[Nullable, DoorLock.Enums.UserTypeEnum] = NullValue @dataclass class SetCredentialResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000101 command_id: typing.ClassVar[int] = 0x00000023 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -28859,9 +28860,9 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="nextCredentialIndex", Tag=2, Type=typing.Union[Nullable, uint]), ]) - status: 'DoorLock.Enums.DlStatus' = 0 - userIndex: 'typing.Union[Nullable, uint]' = NullValue - nextCredentialIndex: 'typing.Union[Nullable, uint]' = NullValue + status: DoorLock.Enums.DlStatus = 0 + userIndex: typing.Union[Nullable, uint] = NullValue + nextCredentialIndex: typing.Union[Nullable, uint] = NullValue @dataclass class GetCredentialStatus(ClusterCommand): @@ -28877,14 +28878,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="credential", Tag=0, Type=DoorLock.Structs.CredentialStruct), ]) - credential: 'DoorLock.Structs.CredentialStruct' = field(default_factory=lambda: DoorLock.Structs.CredentialStruct()) + credential: DoorLock.Structs.CredentialStruct = field(default_factory=lambda: DoorLock.Structs.CredentialStruct()) @dataclass class GetCredentialStatusResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000101 command_id: typing.ClassVar[int] = 0x00000025 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -28898,19 +28899,19 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="credentialData", Tag=5, Type=typing.Union[None, Nullable, bytes]), ]) - credentialExists: 'bool' = False - userIndex: 'typing.Union[Nullable, uint]' = NullValue - creatorFabricIndex: 'typing.Union[Nullable, uint]' = NullValue - lastModifiedFabricIndex: 'typing.Union[Nullable, uint]' = NullValue - nextCredentialIndex: 'typing.Union[Nullable, uint]' = NullValue - credentialData: 'typing.Union[None, Nullable, bytes]' = None + credentialExists: bool = False + userIndex: typing.Union[Nullable, uint] = NullValue + creatorFabricIndex: typing.Union[Nullable, uint] = NullValue + lastModifiedFabricIndex: typing.Union[Nullable, uint] = NullValue + nextCredentialIndex: typing.Union[Nullable, uint] = NullValue + credentialData: typing.Union[None, Nullable, bytes] = None @dataclass class ClearCredential(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000101 command_id: typing.ClassVar[int] = 0x00000026 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -28923,14 +28924,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: def must_use_timed_invoke(cls) -> bool: return True - credential: 'typing.Union[Nullable, DoorLock.Structs.CredentialStruct]' = NullValue + credential: typing.Union[Nullable, DoorLock.Structs.CredentialStruct] = NullValue @dataclass class UnboltDoor(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000101 command_id: typing.ClassVar[int] = 0x00000027 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -28943,14 +28944,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: def must_use_timed_invoke(cls) -> bool: return True - PINCode: 'typing.Optional[bytes]' = None + PINCode: typing.Optional[bytes] = None @dataclass class SetAliroReaderConfig(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000101 command_id: typing.ClassVar[int] = 0x00000028 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -28966,17 +28967,17 @@ def descriptor(cls) -> ClusterObjectDescriptor: def must_use_timed_invoke(cls) -> bool: return True - signingKey: 'bytes' = b"" - verificationKey: 'bytes' = b"" - groupIdentifier: 'bytes' = b"" - groupResolvingKey: 'typing.Optional[bytes]' = None + signingKey: bytes = b"" + verificationKey: bytes = b"" + groupIdentifier: bytes = b"" + groupResolvingKey: typing.Optional[bytes] = None @dataclass class ClearAliroReaderConfig(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000101 command_id: typing.ClassVar[int] = 0x00000029 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -29003,7 +29004,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, DoorLock.Enums.DlLockState]) - value: 'typing.Union[Nullable, DoorLock.Enums.DlLockState]' = NullValue + value: typing.Union[Nullable, DoorLock.Enums.DlLockState] = NullValue @dataclass class LockType(ClusterAttributeDescriptor): @@ -29019,7 +29020,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=DoorLock.Enums.DlLockType) - value: 'DoorLock.Enums.DlLockType' = 0 + value: DoorLock.Enums.DlLockType = 0 @dataclass class ActuatorEnabled(ClusterAttributeDescriptor): @@ -29035,7 +29036,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=bool) - value: 'bool' = False + value: bool = False @dataclass class DoorState(ClusterAttributeDescriptor): @@ -29051,7 +29052,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, DoorLock.Enums.DoorStateEnum]) - value: 'typing.Union[None, Nullable, DoorLock.Enums.DoorStateEnum]' = None + value: typing.Union[None, Nullable, DoorLock.Enums.DoorStateEnum] = None @dataclass class DoorOpenEvents(ClusterAttributeDescriptor): @@ -29067,7 +29068,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class DoorClosedEvents(ClusterAttributeDescriptor): @@ -29083,7 +29084,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class OpenPeriod(ClusterAttributeDescriptor): @@ -29099,7 +29100,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class NumberOfTotalUsersSupported(ClusterAttributeDescriptor): @@ -29115,7 +29116,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class NumberOfPINUsersSupported(ClusterAttributeDescriptor): @@ -29131,7 +29132,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class NumberOfRFIDUsersSupported(ClusterAttributeDescriptor): @@ -29147,7 +29148,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class NumberOfWeekDaySchedulesSupportedPerUser(ClusterAttributeDescriptor): @@ -29163,7 +29164,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class NumberOfYearDaySchedulesSupportedPerUser(ClusterAttributeDescriptor): @@ -29179,7 +29180,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class NumberOfHolidaySchedulesSupported(ClusterAttributeDescriptor): @@ -29195,7 +29196,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class MaxPINCodeLength(ClusterAttributeDescriptor): @@ -29211,7 +29212,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class MinPINCodeLength(ClusterAttributeDescriptor): @@ -29227,7 +29228,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class MaxRFIDCodeLength(ClusterAttributeDescriptor): @@ -29243,7 +29244,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class MinRFIDCodeLength(ClusterAttributeDescriptor): @@ -29259,7 +29260,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class CredentialRulesSupport(ClusterAttributeDescriptor): @@ -29275,7 +29276,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class NumberOfCredentialsSupportedPerUser(ClusterAttributeDescriptor): @@ -29291,7 +29292,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class Language(ClusterAttributeDescriptor): @@ -29307,7 +29308,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[str]) - value: 'typing.Optional[str]' = None + value: typing.Optional[str] = None @dataclass class LEDSettings(ClusterAttributeDescriptor): @@ -29323,7 +29324,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class AutoRelockTime(ClusterAttributeDescriptor): @@ -29339,7 +29340,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class SoundVolume(ClusterAttributeDescriptor): @@ -29355,7 +29356,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class OperatingMode(ClusterAttributeDescriptor): @@ -29371,7 +29372,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=DoorLock.Enums.OperatingModeEnum) - value: 'DoorLock.Enums.OperatingModeEnum' = 0 + value: DoorLock.Enums.OperatingModeEnum = 0 @dataclass class SupportedOperatingModes(ClusterAttributeDescriptor): @@ -29387,7 +29388,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class DefaultConfigurationRegister(ClusterAttributeDescriptor): @@ -29403,7 +29404,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class EnableLocalProgramming(ClusterAttributeDescriptor): @@ -29419,7 +29420,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[bool]) - value: 'typing.Optional[bool]' = None + value: typing.Optional[bool] = None @dataclass class EnableOneTouchLocking(ClusterAttributeDescriptor): @@ -29435,7 +29436,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[bool]) - value: 'typing.Optional[bool]' = None + value: typing.Optional[bool] = None @dataclass class EnableInsideStatusLED(ClusterAttributeDescriptor): @@ -29451,7 +29452,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[bool]) - value: 'typing.Optional[bool]' = None + value: typing.Optional[bool] = None @dataclass class EnablePrivacyModeButton(ClusterAttributeDescriptor): @@ -29467,7 +29468,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[bool]) - value: 'typing.Optional[bool]' = None + value: typing.Optional[bool] = None @dataclass class LocalProgrammingFeatures(ClusterAttributeDescriptor): @@ -29483,7 +29484,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class WrongCodeEntryLimit(ClusterAttributeDescriptor): @@ -29499,7 +29500,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class UserCodeTemporaryDisableTime(ClusterAttributeDescriptor): @@ -29515,7 +29516,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class SendPINOverTheAir(ClusterAttributeDescriptor): @@ -29531,7 +29532,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[bool]) - value: 'typing.Optional[bool]' = None + value: typing.Optional[bool] = None @dataclass class RequirePINforRemoteOperation(ClusterAttributeDescriptor): @@ -29547,7 +29548,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[bool]) - value: 'typing.Optional[bool]' = None + value: typing.Optional[bool] = None @dataclass class ExpiringUserTimeout(ClusterAttributeDescriptor): @@ -29563,7 +29564,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class AliroReaderVerificationKey(ClusterAttributeDescriptor): @@ -29579,7 +29580,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, bytes]) - value: 'typing.Union[None, Nullable, bytes]' = None + value: typing.Union[None, Nullable, bytes] = None @dataclass class AliroReaderGroupIdentifier(ClusterAttributeDescriptor): @@ -29595,7 +29596,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, bytes]) - value: 'typing.Union[None, Nullable, bytes]' = None + value: typing.Union[None, Nullable, bytes] = None @dataclass class AliroReaderGroupSubIdentifier(ClusterAttributeDescriptor): @@ -29611,7 +29612,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[bytes]) - value: 'typing.Optional[bytes]' = None + value: typing.Optional[bytes] = None @dataclass class AliroExpeditedTransactionSupportedProtocolVersions(ClusterAttributeDescriptor): @@ -29627,7 +29628,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[typing.List[bytes]]) - value: 'typing.Optional[typing.List[bytes]]' = None + value: typing.Optional[typing.List[bytes]] = None @dataclass class AliroGroupResolvingKey(ClusterAttributeDescriptor): @@ -29643,7 +29644,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, bytes]) - value: 'typing.Union[None, Nullable, bytes]' = None + value: typing.Union[None, Nullable, bytes] = None @dataclass class AliroSupportedBLEUWBProtocolVersions(ClusterAttributeDescriptor): @@ -29659,7 +29660,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[typing.List[bytes]]) - value: 'typing.Optional[typing.List[bytes]]' = None + value: typing.Optional[typing.List[bytes]] = None @dataclass class AliroBLEAdvertisingVersion(ClusterAttributeDescriptor): @@ -29675,7 +29676,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class NumberOfAliroCredentialIssuerKeysSupported(ClusterAttributeDescriptor): @@ -29691,7 +29692,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class NumberOfAliroEndpointKeysSupported(ClusterAttributeDescriptor): @@ -29707,7 +29708,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -29723,7 +29724,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -29739,7 +29740,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -29755,7 +29756,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -29771,7 +29772,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -29787,7 +29788,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -29803,7 +29804,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 class Events: @dataclass @@ -29823,7 +29824,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="alarmCode", Tag=0, Type=DoorLock.Enums.AlarmCodeEnum), ]) - alarmCode: 'DoorLock.Enums.AlarmCodeEnum' = 0 + alarmCode: DoorLock.Enums.AlarmCodeEnum = 0 @dataclass class DoorStateChange(ClusterEvent): @@ -29842,7 +29843,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="doorState", Tag=0, Type=DoorLock.Enums.DoorStateEnum), ]) - doorState: 'DoorLock.Enums.DoorStateEnum' = 0 + doorState: DoorLock.Enums.DoorStateEnum = 0 @dataclass class LockOperation(ClusterEvent): @@ -29866,12 +29867,12 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="credentials", Tag=5, Type=typing.Union[None, Nullable, typing.List[DoorLock.Structs.CredentialStruct]]), ]) - lockOperationType: 'DoorLock.Enums.LockOperationTypeEnum' = 0 - operationSource: 'DoorLock.Enums.OperationSourceEnum' = 0 - userIndex: 'typing.Union[Nullable, uint]' = NullValue - fabricIndex: 'typing.Union[Nullable, uint]' = NullValue - sourceNode: 'typing.Union[Nullable, uint]' = NullValue - credentials: 'typing.Union[None, Nullable, typing.List[DoorLock.Structs.CredentialStruct]]' = None + lockOperationType: DoorLock.Enums.LockOperationTypeEnum = 0 + operationSource: DoorLock.Enums.OperationSourceEnum = 0 + userIndex: typing.Union[Nullable, uint] = NullValue + fabricIndex: typing.Union[Nullable, uint] = NullValue + sourceNode: typing.Union[Nullable, uint] = NullValue + credentials: typing.Union[None, Nullable, typing.List[DoorLock.Structs.CredentialStruct]] = None @dataclass class LockOperationError(ClusterEvent): @@ -29896,13 +29897,13 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="credentials", Tag=6, Type=typing.Union[None, Nullable, typing.List[DoorLock.Structs.CredentialStruct]]), ]) - lockOperationType: 'DoorLock.Enums.LockOperationTypeEnum' = 0 - operationSource: 'DoorLock.Enums.OperationSourceEnum' = 0 - operationError: 'DoorLock.Enums.OperationErrorEnum' = 0 - userIndex: 'typing.Union[Nullable, uint]' = NullValue - fabricIndex: 'typing.Union[Nullable, uint]' = NullValue - sourceNode: 'typing.Union[Nullable, uint]' = NullValue - credentials: 'typing.Union[None, Nullable, typing.List[DoorLock.Structs.CredentialStruct]]' = None + lockOperationType: DoorLock.Enums.LockOperationTypeEnum = 0 + operationSource: DoorLock.Enums.OperationSourceEnum = 0 + operationError: DoorLock.Enums.OperationErrorEnum = 0 + userIndex: typing.Union[Nullable, uint] = NullValue + fabricIndex: typing.Union[Nullable, uint] = NullValue + sourceNode: typing.Union[Nullable, uint] = NullValue + credentials: typing.Union[None, Nullable, typing.List[DoorLock.Structs.CredentialStruct]] = None @dataclass class LockUserChange(ClusterEvent): @@ -29927,13 +29928,13 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="dataIndex", Tag=6, Type=typing.Union[Nullable, uint]), ]) - lockDataType: 'DoorLock.Enums.LockDataTypeEnum' = 0 - dataOperationType: 'DoorLock.Enums.DataOperationTypeEnum' = 0 - operationSource: 'DoorLock.Enums.OperationSourceEnum' = 0 - userIndex: 'typing.Union[Nullable, uint]' = NullValue - fabricIndex: 'typing.Union[Nullable, uint]' = NullValue - sourceNode: 'typing.Union[Nullable, uint]' = NullValue - dataIndex: 'typing.Union[Nullable, uint]' = NullValue + lockDataType: DoorLock.Enums.LockDataTypeEnum = 0 + dataOperationType: DoorLock.Enums.DataOperationTypeEnum = 0 + operationSource: DoorLock.Enums.OperationSourceEnum = 0 + userIndex: typing.Union[Nullable, uint] = NullValue + fabricIndex: typing.Union[Nullable, uint] = NullValue + sourceNode: typing.Union[Nullable, uint] = NullValue + dataIndex: typing.Union[Nullable, uint] = NullValue @dataclass @@ -29974,34 +29975,34 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - type: 'WindowCovering.Enums.Type' = None - physicalClosedLimitLift: 'typing.Optional[uint]' = None - physicalClosedLimitTilt: 'typing.Optional[uint]' = None - currentPositionLift: 'typing.Union[None, Nullable, uint]' = None - currentPositionTilt: 'typing.Union[None, Nullable, uint]' = None - numberOfActuationsLift: 'typing.Optional[uint]' = None - numberOfActuationsTilt: 'typing.Optional[uint]' = None - configStatus: 'uint' = None - currentPositionLiftPercentage: 'typing.Union[None, Nullable, uint]' = None - currentPositionTiltPercentage: 'typing.Union[None, Nullable, uint]' = None - operationalStatus: 'uint' = None - targetPositionLiftPercent100ths: 'typing.Union[None, Nullable, uint]' = None - targetPositionTiltPercent100ths: 'typing.Union[None, Nullable, uint]' = None - endProductType: 'WindowCovering.Enums.EndProductType' = None - currentPositionLiftPercent100ths: 'typing.Union[None, Nullable, uint]' = None - currentPositionTiltPercent100ths: 'typing.Union[None, Nullable, uint]' = None - installedOpenLimitLift: 'typing.Optional[uint]' = None - installedClosedLimitLift: 'typing.Optional[uint]' = None - installedOpenLimitTilt: 'typing.Optional[uint]' = None - installedClosedLimitTilt: 'typing.Optional[uint]' = None - mode: 'uint' = None - safetyStatus: 'typing.Optional[uint]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + type: WindowCovering.Enums.Type = 0 + physicalClosedLimitLift: typing.Optional[uint] = None + physicalClosedLimitTilt: typing.Optional[uint] = None + currentPositionLift: typing.Union[None, Nullable, uint] = None + currentPositionTilt: typing.Union[None, Nullable, uint] = None + numberOfActuationsLift: typing.Optional[uint] = None + numberOfActuationsTilt: typing.Optional[uint] = None + configStatus: uint = 0 + currentPositionLiftPercentage: typing.Union[None, Nullable, uint] = None + currentPositionTiltPercentage: typing.Union[None, Nullable, uint] = None + operationalStatus: uint = 0 + targetPositionLiftPercent100ths: typing.Union[None, Nullable, uint] = None + targetPositionTiltPercent100ths: typing.Union[None, Nullable, uint] = None + endProductType: WindowCovering.Enums.EndProductType = 0 + currentPositionLiftPercent100ths: typing.Union[None, Nullable, uint] = None + currentPositionTiltPercent100ths: typing.Union[None, Nullable, uint] = None + installedOpenLimitLift: typing.Optional[uint] = None + installedClosedLimitLift: typing.Optional[uint] = None + installedOpenLimitTilt: typing.Optional[uint] = None + installedClosedLimitTilt: typing.Optional[uint] = None + mode: uint = 0 + safetyStatus: typing.Optional[uint] = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class EndProductType(MatterIntEnum): @@ -30102,7 +30103,7 @@ class UpOrOpen(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000102 command_id: typing.ClassVar[int] = 0x00000000 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -30115,7 +30116,7 @@ class DownOrClose(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000102 command_id: typing.ClassVar[int] = 0x00000001 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -30128,7 +30129,7 @@ class StopMotion(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000102 command_id: typing.ClassVar[int] = 0x00000002 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -30141,7 +30142,7 @@ class GoToLiftValue(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000102 command_id: typing.ClassVar[int] = 0x00000004 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -30150,14 +30151,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="liftValue", Tag=0, Type=uint), ]) - liftValue: 'uint' = 0 + liftValue: uint = 0 @dataclass class GoToLiftPercentage(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000102 command_id: typing.ClassVar[int] = 0x00000005 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -30166,14 +30167,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="liftPercent100thsValue", Tag=0, Type=uint), ]) - liftPercent100thsValue: 'uint' = 0 + liftPercent100thsValue: uint = 0 @dataclass class GoToTiltValue(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000102 command_id: typing.ClassVar[int] = 0x00000007 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -30182,14 +30183,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="tiltValue", Tag=0, Type=uint), ]) - tiltValue: 'uint' = 0 + tiltValue: uint = 0 @dataclass class GoToTiltPercentage(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000102 command_id: typing.ClassVar[int] = 0x00000008 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -30198,7 +30199,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="tiltPercent100thsValue", Tag=0, Type=uint), ]) - tiltPercent100thsValue: 'uint' = 0 + tiltPercent100thsValue: uint = 0 class Attributes: @dataclass @@ -30215,7 +30216,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=WindowCovering.Enums.Type) - value: 'WindowCovering.Enums.Type' = 0 + value: WindowCovering.Enums.Type = 0 @dataclass class PhysicalClosedLimitLift(ClusterAttributeDescriptor): @@ -30231,7 +30232,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class PhysicalClosedLimitTilt(ClusterAttributeDescriptor): @@ -30247,7 +30248,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class CurrentPositionLift(ClusterAttributeDescriptor): @@ -30263,7 +30264,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class CurrentPositionTilt(ClusterAttributeDescriptor): @@ -30279,7 +30280,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class NumberOfActuationsLift(ClusterAttributeDescriptor): @@ -30295,7 +30296,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class NumberOfActuationsTilt(ClusterAttributeDescriptor): @@ -30311,7 +30312,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class ConfigStatus(ClusterAttributeDescriptor): @@ -30327,7 +30328,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class CurrentPositionLiftPercentage(ClusterAttributeDescriptor): @@ -30343,7 +30344,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class CurrentPositionTiltPercentage(ClusterAttributeDescriptor): @@ -30359,7 +30360,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class OperationalStatus(ClusterAttributeDescriptor): @@ -30375,7 +30376,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class TargetPositionLiftPercent100ths(ClusterAttributeDescriptor): @@ -30391,7 +30392,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class TargetPositionTiltPercent100ths(ClusterAttributeDescriptor): @@ -30407,7 +30408,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class EndProductType(ClusterAttributeDescriptor): @@ -30423,7 +30424,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=WindowCovering.Enums.EndProductType) - value: 'WindowCovering.Enums.EndProductType' = 0 + value: WindowCovering.Enums.EndProductType = 0 @dataclass class CurrentPositionLiftPercent100ths(ClusterAttributeDescriptor): @@ -30439,7 +30440,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class CurrentPositionTiltPercent100ths(ClusterAttributeDescriptor): @@ -30455,7 +30456,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class InstalledOpenLimitLift(ClusterAttributeDescriptor): @@ -30471,7 +30472,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class InstalledClosedLimitLift(ClusterAttributeDescriptor): @@ -30487,7 +30488,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class InstalledOpenLimitTilt(ClusterAttributeDescriptor): @@ -30503,7 +30504,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class InstalledClosedLimitTilt(ClusterAttributeDescriptor): @@ -30519,7 +30520,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class Mode(ClusterAttributeDescriptor): @@ -30535,7 +30536,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class SafetyStatus(ClusterAttributeDescriptor): @@ -30551,7 +30552,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -30567,7 +30568,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -30583,7 +30584,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -30599,7 +30600,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -30615,7 +30616,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -30631,7 +30632,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -30647,7 +30648,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -30672,18 +30673,18 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - supportedAreas: 'typing.List[ServiceArea.Structs.AreaStruct]' = None - supportedMaps: 'typing.Optional[typing.List[ServiceArea.Structs.MapStruct]]' = None - selectedAreas: 'typing.List[uint]' = None - currentArea: 'typing.Union[None, Nullable, uint]' = None - estimatedEndTime: 'typing.Union[None, Nullable, uint]' = None - progress: 'typing.Optional[typing.List[ServiceArea.Structs.ProgressStruct]]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + supportedAreas: typing.List[ServiceArea.Structs.AreaStruct] = field(default_factory=lambda: []) + supportedMaps: typing.Optional[typing.List[ServiceArea.Structs.MapStruct]] = None + selectedAreas: typing.List[uint] = field(default_factory=lambda: []) + currentArea: typing.Union[None, Nullable, uint] = None + estimatedEndTime: typing.Union[None, Nullable, uint] = None + progress: typing.Optional[typing.List[ServiceArea.Structs.ProgressStruct]] = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class OperationalStatusEnum(MatterIntEnum): @@ -30812,14 +30813,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="newAreas", Tag=0, Type=typing.List[uint]), ]) - newAreas: 'typing.List[uint]' = field(default_factory=lambda: []) + newAreas: typing.List[uint] = field(default_factory=lambda: []) @dataclass class SelectAreasResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000150 command_id: typing.ClassVar[int] = 0x00000001 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -30829,8 +30830,8 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="statusText", Tag=1, Type=str), ]) - status: 'ServiceArea.Enums.SelectAreasStatus' = 0 - statusText: 'str' = "" + status: ServiceArea.Enums.SelectAreasStatus = 0 + statusText: str = "" @dataclass class SkipArea(ClusterCommand): @@ -30846,14 +30847,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="skippedArea", Tag=0, Type=uint), ]) - skippedArea: 'uint' = 0 + skippedArea: uint = 0 @dataclass class SkipAreaResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000150 command_id: typing.ClassVar[int] = 0x00000003 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -30863,8 +30864,8 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="statusText", Tag=1, Type=str), ]) - status: 'ServiceArea.Enums.SkipAreaStatus' = 0 - statusText: 'str' = "" + status: ServiceArea.Enums.SkipAreaStatus = 0 + statusText: str = "" class Attributes: @dataclass @@ -30881,7 +30882,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[ServiceArea.Structs.AreaStruct]) - value: 'typing.List[ServiceArea.Structs.AreaStruct]' = field(default_factory=lambda: []) + value: typing.List[ServiceArea.Structs.AreaStruct] = field(default_factory=lambda: []) @dataclass class SupportedMaps(ClusterAttributeDescriptor): @@ -30897,7 +30898,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[typing.List[ServiceArea.Structs.MapStruct]]) - value: 'typing.Optional[typing.List[ServiceArea.Structs.MapStruct]]' = None + value: typing.Optional[typing.List[ServiceArea.Structs.MapStruct]] = None @dataclass class SelectedAreas(ClusterAttributeDescriptor): @@ -30913,7 +30914,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class CurrentArea(ClusterAttributeDescriptor): @@ -30929,7 +30930,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class EstimatedEndTime(ClusterAttributeDescriptor): @@ -30945,7 +30946,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class Progress(ClusterAttributeDescriptor): @@ -30961,7 +30962,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[typing.List[ServiceArea.Structs.ProgressStruct]]) - value: 'typing.Optional[typing.List[ServiceArea.Structs.ProgressStruct]]' = None + value: typing.Optional[typing.List[ServiceArea.Structs.ProgressStruct]] = None @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -30977,7 +30978,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -30993,7 +30994,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -31009,7 +31010,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -31025,7 +31026,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -31041,7 +31042,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -31057,7 +31058,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -31099,35 +31100,35 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - maxPressure: 'typing.Union[Nullable, int]' = None - maxSpeed: 'typing.Union[Nullable, uint]' = None - maxFlow: 'typing.Union[Nullable, uint]' = None - minConstPressure: 'typing.Union[None, Nullable, int]' = None - maxConstPressure: 'typing.Union[None, Nullable, int]' = None - minCompPressure: 'typing.Union[None, Nullable, int]' = None - maxCompPressure: 'typing.Union[None, Nullable, int]' = None - minConstSpeed: 'typing.Union[None, Nullable, uint]' = None - maxConstSpeed: 'typing.Union[None, Nullable, uint]' = None - minConstFlow: 'typing.Union[None, Nullable, uint]' = None - maxConstFlow: 'typing.Union[None, Nullable, uint]' = None - minConstTemp: 'typing.Union[None, Nullable, int]' = None - maxConstTemp: 'typing.Union[None, Nullable, int]' = None - pumpStatus: 'typing.Optional[uint]' = None - effectiveOperationMode: 'PumpConfigurationAndControl.Enums.OperationModeEnum' = None - effectiveControlMode: 'PumpConfigurationAndControl.Enums.ControlModeEnum' = None - capacity: 'typing.Union[Nullable, int]' = None - speed: 'typing.Union[None, Nullable, uint]' = None - lifetimeRunningHours: 'typing.Union[None, Nullable, uint]' = None - power: 'typing.Union[None, Nullable, uint]' = None - lifetimeEnergyConsumed: 'typing.Union[None, Nullable, uint]' = None - operationMode: 'PumpConfigurationAndControl.Enums.OperationModeEnum' = None - controlMode: 'typing.Optional[PumpConfigurationAndControl.Enums.ControlModeEnum]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + maxPressure: typing.Union[Nullable, int] = NullValue + maxSpeed: typing.Union[Nullable, uint] = NullValue + maxFlow: typing.Union[Nullable, uint] = NullValue + minConstPressure: typing.Union[None, Nullable, int] = None + maxConstPressure: typing.Union[None, Nullable, int] = None + minCompPressure: typing.Union[None, Nullable, int] = None + maxCompPressure: typing.Union[None, Nullable, int] = None + minConstSpeed: typing.Union[None, Nullable, uint] = None + maxConstSpeed: typing.Union[None, Nullable, uint] = None + minConstFlow: typing.Union[None, Nullable, uint] = None + maxConstFlow: typing.Union[None, Nullable, uint] = None + minConstTemp: typing.Union[None, Nullable, int] = None + maxConstTemp: typing.Union[None, Nullable, int] = None + pumpStatus: typing.Optional[uint] = None + effectiveOperationMode: PumpConfigurationAndControl.Enums.OperationModeEnum = 0 + effectiveControlMode: PumpConfigurationAndControl.Enums.ControlModeEnum = 0 + capacity: typing.Union[Nullable, int] = NullValue + speed: typing.Union[None, Nullable, uint] = None + lifetimeRunningHours: typing.Union[None, Nullable, uint] = None + power: typing.Union[None, Nullable, uint] = None + lifetimeEnergyConsumed: typing.Union[None, Nullable, uint] = None + operationMode: PumpConfigurationAndControl.Enums.OperationModeEnum = 0 + controlMode: typing.Optional[PumpConfigurationAndControl.Enums.ControlModeEnum] = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class ControlModeEnum(MatterIntEnum): @@ -31190,7 +31191,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, int]) - value: 'typing.Union[Nullable, int]' = NullValue + value: typing.Union[Nullable, int] = NullValue @dataclass class MaxSpeed(ClusterAttributeDescriptor): @@ -31206,7 +31207,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, uint]) - value: 'typing.Union[Nullable, uint]' = NullValue + value: typing.Union[Nullable, uint] = NullValue @dataclass class MaxFlow(ClusterAttributeDescriptor): @@ -31222,7 +31223,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, uint]) - value: 'typing.Union[Nullable, uint]' = NullValue + value: typing.Union[Nullable, uint] = NullValue @dataclass class MinConstPressure(ClusterAttributeDescriptor): @@ -31238,7 +31239,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, int]) - value: 'typing.Union[None, Nullable, int]' = None + value: typing.Union[None, Nullable, int] = None @dataclass class MaxConstPressure(ClusterAttributeDescriptor): @@ -31254,7 +31255,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, int]) - value: 'typing.Union[None, Nullable, int]' = None + value: typing.Union[None, Nullable, int] = None @dataclass class MinCompPressure(ClusterAttributeDescriptor): @@ -31270,7 +31271,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, int]) - value: 'typing.Union[None, Nullable, int]' = None + value: typing.Union[None, Nullable, int] = None @dataclass class MaxCompPressure(ClusterAttributeDescriptor): @@ -31286,7 +31287,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, int]) - value: 'typing.Union[None, Nullable, int]' = None + value: typing.Union[None, Nullable, int] = None @dataclass class MinConstSpeed(ClusterAttributeDescriptor): @@ -31302,7 +31303,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class MaxConstSpeed(ClusterAttributeDescriptor): @@ -31318,7 +31319,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class MinConstFlow(ClusterAttributeDescriptor): @@ -31334,7 +31335,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class MaxConstFlow(ClusterAttributeDescriptor): @@ -31350,7 +31351,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class MinConstTemp(ClusterAttributeDescriptor): @@ -31366,7 +31367,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, int]) - value: 'typing.Union[None, Nullable, int]' = None + value: typing.Union[None, Nullable, int] = None @dataclass class MaxConstTemp(ClusterAttributeDescriptor): @@ -31382,7 +31383,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, int]) - value: 'typing.Union[None, Nullable, int]' = None + value: typing.Union[None, Nullable, int] = None @dataclass class PumpStatus(ClusterAttributeDescriptor): @@ -31398,7 +31399,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class EffectiveOperationMode(ClusterAttributeDescriptor): @@ -31414,7 +31415,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=PumpConfigurationAndControl.Enums.OperationModeEnum) - value: 'PumpConfigurationAndControl.Enums.OperationModeEnum' = 0 + value: PumpConfigurationAndControl.Enums.OperationModeEnum = 0 @dataclass class EffectiveControlMode(ClusterAttributeDescriptor): @@ -31430,7 +31431,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=PumpConfigurationAndControl.Enums.ControlModeEnum) - value: 'PumpConfigurationAndControl.Enums.ControlModeEnum' = 0 + value: PumpConfigurationAndControl.Enums.ControlModeEnum = 0 @dataclass class Capacity(ClusterAttributeDescriptor): @@ -31446,7 +31447,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, int]) - value: 'typing.Union[Nullable, int]' = NullValue + value: typing.Union[Nullable, int] = NullValue @dataclass class Speed(ClusterAttributeDescriptor): @@ -31462,7 +31463,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class LifetimeRunningHours(ClusterAttributeDescriptor): @@ -31478,7 +31479,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class Power(ClusterAttributeDescriptor): @@ -31494,7 +31495,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class LifetimeEnergyConsumed(ClusterAttributeDescriptor): @@ -31510,7 +31511,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class OperationMode(ClusterAttributeDescriptor): @@ -31526,7 +31527,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=PumpConfigurationAndControl.Enums.OperationModeEnum) - value: 'PumpConfigurationAndControl.Enums.OperationModeEnum' = 0 + value: PumpConfigurationAndControl.Enums.OperationModeEnum = 0 @dataclass class ControlMode(ClusterAttributeDescriptor): @@ -31542,7 +31543,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[PumpConfigurationAndControl.Enums.ControlModeEnum]) - value: 'typing.Optional[PumpConfigurationAndControl.Enums.ControlModeEnum]' = None + value: typing.Optional[PumpConfigurationAndControl.Enums.ControlModeEnum] = None @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -31558,7 +31559,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -31574,7 +31575,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -31590,7 +31591,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -31606,7 +31607,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -31622,7 +31623,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -31638,7 +31639,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 class Events: @dataclass @@ -31990,72 +31991,72 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - localTemperature: 'typing.Union[Nullable, int]' = None - outdoorTemperature: 'typing.Union[None, Nullable, int]' = None - occupancy: 'typing.Optional[uint]' = None - absMinHeatSetpointLimit: 'typing.Optional[int]' = None - absMaxHeatSetpointLimit: 'typing.Optional[int]' = None - absMinCoolSetpointLimit: 'typing.Optional[int]' = None - absMaxCoolSetpointLimit: 'typing.Optional[int]' = None - PICoolingDemand: 'typing.Optional[uint]' = None - PIHeatingDemand: 'typing.Optional[uint]' = None - HVACSystemTypeConfiguration: 'typing.Optional[uint]' = None - localTemperatureCalibration: 'typing.Optional[int]' = None - occupiedCoolingSetpoint: 'typing.Optional[int]' = None - occupiedHeatingSetpoint: 'typing.Optional[int]' = None - unoccupiedCoolingSetpoint: 'typing.Optional[int]' = None - unoccupiedHeatingSetpoint: 'typing.Optional[int]' = None - minHeatSetpointLimit: 'typing.Optional[int]' = None - maxHeatSetpointLimit: 'typing.Optional[int]' = None - minCoolSetpointLimit: 'typing.Optional[int]' = None - maxCoolSetpointLimit: 'typing.Optional[int]' = None - minSetpointDeadBand: 'typing.Optional[int]' = None - remoteSensing: 'typing.Optional[uint]' = None - controlSequenceOfOperation: 'Thermostat.Enums.ControlSequenceOfOperationEnum' = None - systemMode: 'Thermostat.Enums.SystemModeEnum' = None - thermostatRunningMode: 'typing.Optional[Thermostat.Enums.ThermostatRunningModeEnum]' = None - startOfWeek: 'typing.Optional[Thermostat.Enums.StartOfWeekEnum]' = None - numberOfWeeklyTransitions: 'typing.Optional[uint]' = None - numberOfDailyTransitions: 'typing.Optional[uint]' = None - temperatureSetpointHold: 'typing.Optional[Thermostat.Enums.TemperatureSetpointHoldEnum]' = None - temperatureSetpointHoldDuration: 'typing.Union[None, Nullable, uint]' = None - thermostatProgrammingOperationMode: 'typing.Optional[uint]' = None - thermostatRunningState: 'typing.Optional[uint]' = None - setpointChangeSource: 'typing.Optional[Thermostat.Enums.SetpointChangeSourceEnum]' = None - setpointChangeAmount: 'typing.Union[None, Nullable, int]' = None - setpointChangeSourceTimestamp: 'typing.Optional[uint]' = None - occupiedSetback: 'typing.Union[None, Nullable, uint]' = None - occupiedSetbackMin: 'typing.Union[None, Nullable, uint]' = None - occupiedSetbackMax: 'typing.Union[None, Nullable, uint]' = None - unoccupiedSetback: 'typing.Union[None, Nullable, uint]' = None - unoccupiedSetbackMin: 'typing.Union[None, Nullable, uint]' = None - unoccupiedSetbackMax: 'typing.Union[None, Nullable, uint]' = None - emergencyHeatDelta: 'typing.Optional[uint]' = None - ACType: 'typing.Optional[Thermostat.Enums.ACTypeEnum]' = None - ACCapacity: 'typing.Optional[uint]' = None - ACRefrigerantType: 'typing.Optional[Thermostat.Enums.ACRefrigerantTypeEnum]' = None - ACCompressorType: 'typing.Optional[Thermostat.Enums.ACCompressorTypeEnum]' = None - ACErrorCode: 'typing.Optional[uint]' = None - ACLouverPosition: 'typing.Optional[Thermostat.Enums.ACLouverPositionEnum]' = None - ACCoilTemperature: 'typing.Union[None, Nullable, int]' = None - ACCapacityformat: 'typing.Optional[Thermostat.Enums.ACCapacityFormatEnum]' = None - presetTypes: 'typing.Optional[typing.List[Thermostat.Structs.PresetTypeStruct]]' = None - scheduleTypes: 'typing.Optional[typing.List[Thermostat.Structs.ScheduleTypeStruct]]' = None - numberOfPresets: 'typing.Optional[uint]' = None - numberOfSchedules: 'typing.Optional[uint]' = None - numberOfScheduleTransitions: 'typing.Optional[uint]' = None - numberOfScheduleTransitionPerDay: 'typing.Union[None, Nullable, uint]' = None - activePresetHandle: 'typing.Union[None, Nullable, bytes]' = None - activeScheduleHandle: 'typing.Union[None, Nullable, bytes]' = None - presets: 'typing.Optional[typing.List[Thermostat.Structs.PresetStruct]]' = None - schedules: 'typing.Optional[typing.List[Thermostat.Structs.ScheduleStruct]]' = None - setpointHoldExpiryTimestamp: 'typing.Union[None, Nullable, uint]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + localTemperature: typing.Union[Nullable, int] = NullValue + outdoorTemperature: typing.Union[None, Nullable, int] = None + occupancy: typing.Optional[uint] = None + absMinHeatSetpointLimit: typing.Optional[int] = None + absMaxHeatSetpointLimit: typing.Optional[int] = None + absMinCoolSetpointLimit: typing.Optional[int] = None + absMaxCoolSetpointLimit: typing.Optional[int] = None + PICoolingDemand: typing.Optional[uint] = None + PIHeatingDemand: typing.Optional[uint] = None + HVACSystemTypeConfiguration: typing.Optional[uint] = None + localTemperatureCalibration: typing.Optional[int] = None + occupiedCoolingSetpoint: typing.Optional[int] = None + occupiedHeatingSetpoint: typing.Optional[int] = None + unoccupiedCoolingSetpoint: typing.Optional[int] = None + unoccupiedHeatingSetpoint: typing.Optional[int] = None + minHeatSetpointLimit: typing.Optional[int] = None + maxHeatSetpointLimit: typing.Optional[int] = None + minCoolSetpointLimit: typing.Optional[int] = None + maxCoolSetpointLimit: typing.Optional[int] = None + minSetpointDeadBand: typing.Optional[int] = None + remoteSensing: typing.Optional[uint] = None + controlSequenceOfOperation: Thermostat.Enums.ControlSequenceOfOperationEnum = 0 + systemMode: Thermostat.Enums.SystemModeEnum = 0 + thermostatRunningMode: typing.Optional[Thermostat.Enums.ThermostatRunningModeEnum] = None + startOfWeek: typing.Optional[Thermostat.Enums.StartOfWeekEnum] = None + numberOfWeeklyTransitions: typing.Optional[uint] = None + numberOfDailyTransitions: typing.Optional[uint] = None + temperatureSetpointHold: typing.Optional[Thermostat.Enums.TemperatureSetpointHoldEnum] = None + temperatureSetpointHoldDuration: typing.Union[None, Nullable, uint] = None + thermostatProgrammingOperationMode: typing.Optional[uint] = None + thermostatRunningState: typing.Optional[uint] = None + setpointChangeSource: typing.Optional[Thermostat.Enums.SetpointChangeSourceEnum] = None + setpointChangeAmount: typing.Union[None, Nullable, int] = None + setpointChangeSourceTimestamp: typing.Optional[uint] = None + occupiedSetback: typing.Union[None, Nullable, uint] = None + occupiedSetbackMin: typing.Union[None, Nullable, uint] = None + occupiedSetbackMax: typing.Union[None, Nullable, uint] = None + unoccupiedSetback: typing.Union[None, Nullable, uint] = None + unoccupiedSetbackMin: typing.Union[None, Nullable, uint] = None + unoccupiedSetbackMax: typing.Union[None, Nullable, uint] = None + emergencyHeatDelta: typing.Optional[uint] = None + ACType: typing.Optional[Thermostat.Enums.ACTypeEnum] = None + ACCapacity: typing.Optional[uint] = None + ACRefrigerantType: typing.Optional[Thermostat.Enums.ACRefrigerantTypeEnum] = None + ACCompressorType: typing.Optional[Thermostat.Enums.ACCompressorTypeEnum] = None + ACErrorCode: typing.Optional[uint] = None + ACLouverPosition: typing.Optional[Thermostat.Enums.ACLouverPositionEnum] = None + ACCoilTemperature: typing.Union[None, Nullable, int] = None + ACCapacityformat: typing.Optional[Thermostat.Enums.ACCapacityFormatEnum] = None + presetTypes: typing.Optional[typing.List[Thermostat.Structs.PresetTypeStruct]] = None + scheduleTypes: typing.Optional[typing.List[Thermostat.Structs.ScheduleTypeStruct]] = None + numberOfPresets: typing.Optional[uint] = None + numberOfSchedules: typing.Optional[uint] = None + numberOfScheduleTransitions: typing.Optional[uint] = None + numberOfScheduleTransitionPerDay: typing.Union[None, Nullable, uint] = None + activePresetHandle: typing.Union[None, Nullable, bytes] = None + activeScheduleHandle: typing.Union[None, Nullable, bytes] = None + presets: typing.Optional[typing.List[Thermostat.Structs.PresetStruct]] = None + schedules: typing.Optional[typing.List[Thermostat.Structs.ScheduleStruct]] = None + setpointHoldExpiryTimestamp: typing.Union[None, Nullable, uint] = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class ACCapacityFormatEnum(MatterIntEnum): @@ -32394,7 +32395,7 @@ class SetpointRaiseLower(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000201 command_id: typing.ClassVar[int] = 0x00000000 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -32404,15 +32405,15 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="amount", Tag=1, Type=int), ]) - mode: 'Thermostat.Enums.SetpointRaiseLowerModeEnum' = 0 - amount: 'int' = 0 + mode: Thermostat.Enums.SetpointRaiseLowerModeEnum = 0 + amount: int = 0 @dataclass class GetWeeklyScheduleResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000201 command_id: typing.ClassVar[int] = 0x00000000 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -32424,17 +32425,17 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="transitions", Tag=3, Type=typing.List[Thermostat.Structs.WeeklyScheduleTransitionStruct]), ]) - numberOfTransitionsForSequence: 'uint' = 0 - dayOfWeekForSequence: 'uint' = 0 - modeForSequence: 'uint' = 0 - transitions: 'typing.List[Thermostat.Structs.WeeklyScheduleTransitionStruct]' = field(default_factory=lambda: []) + numberOfTransitionsForSequence: uint = 0 + dayOfWeekForSequence: uint = 0 + modeForSequence: uint = 0 + transitions: typing.List[Thermostat.Structs.WeeklyScheduleTransitionStruct] = field(default_factory=lambda: []) @dataclass class SetWeeklySchedule(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000201 command_id: typing.ClassVar[int] = 0x00000001 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -32446,10 +32447,10 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="transitions", Tag=3, Type=typing.List[Thermostat.Structs.WeeklyScheduleTransitionStruct]), ]) - numberOfTransitionsForSequence: 'uint' = 0 - dayOfWeekForSequence: 'uint' = 0 - modeForSequence: 'uint' = 0 - transitions: 'typing.List[Thermostat.Structs.WeeklyScheduleTransitionStruct]' = field(default_factory=lambda: []) + numberOfTransitionsForSequence: uint = 0 + dayOfWeekForSequence: uint = 0 + modeForSequence: uint = 0 + transitions: typing.List[Thermostat.Structs.WeeklyScheduleTransitionStruct] = field(default_factory=lambda: []) @dataclass class GetWeeklySchedule(ClusterCommand): @@ -32466,15 +32467,15 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="modeToReturn", Tag=1, Type=uint), ]) - daysToReturn: 'uint' = 0 - modeToReturn: 'uint' = 0 + daysToReturn: uint = 0 + modeToReturn: uint = 0 @dataclass class ClearWeeklySchedule(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000201 command_id: typing.ClassVar[int] = 0x00000003 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -32487,7 +32488,7 @@ class SetActiveScheduleRequest(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000201 command_id: typing.ClassVar[int] = 0x00000005 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -32496,14 +32497,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="scheduleHandle", Tag=0, Type=bytes), ]) - scheduleHandle: 'bytes' = b"" + scheduleHandle: bytes = b"" @dataclass class SetActivePresetRequest(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000201 command_id: typing.ClassVar[int] = 0x00000006 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -32512,14 +32513,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="presetHandle", Tag=0, Type=typing.Union[Nullable, bytes]), ]) - presetHandle: 'typing.Union[Nullable, bytes]' = NullValue + presetHandle: typing.Union[Nullable, bytes] = NullValue @dataclass class AtomicResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000201 command_id: typing.ClassVar[int] = 0x000000FD is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -32530,9 +32531,9 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="timeout", Tag=2, Type=typing.Optional[uint]), ]) - statusCode: 'uint' = 0 - attributeStatus: 'typing.List[Globals.Structs.AtomicAttributeStatusStruct]' = field(default_factory=lambda: []) - timeout: 'typing.Optional[uint]' = None + statusCode: uint = 0 + attributeStatus: typing.List[Globals.Structs.AtomicAttributeStatusStruct] = field(default_factory=lambda: []) + timeout: typing.Optional[uint] = None @dataclass class AtomicRequest(ClusterCommand): @@ -32550,9 +32551,9 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="timeout", Tag=2, Type=typing.Optional[uint]), ]) - requestType: 'Globals.Enums.AtomicRequestTypeEnum' = 0 - attributeRequests: 'typing.List[uint]' = field(default_factory=lambda: []) - timeout: 'typing.Optional[uint]' = None + requestType: Globals.Enums.AtomicRequestTypeEnum = 0 + attributeRequests: typing.List[uint] = field(default_factory=lambda: []) + timeout: typing.Optional[uint] = None class Attributes: @dataclass @@ -32569,7 +32570,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, int]) - value: 'typing.Union[Nullable, int]' = NullValue + value: typing.Union[Nullable, int] = NullValue @dataclass class OutdoorTemperature(ClusterAttributeDescriptor): @@ -32585,7 +32586,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, int]) - value: 'typing.Union[None, Nullable, int]' = None + value: typing.Union[None, Nullable, int] = None @dataclass class Occupancy(ClusterAttributeDescriptor): @@ -32601,7 +32602,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class AbsMinHeatSetpointLimit(ClusterAttributeDescriptor): @@ -32617,7 +32618,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[int]) - value: 'typing.Optional[int]' = None + value: typing.Optional[int] = None @dataclass class AbsMaxHeatSetpointLimit(ClusterAttributeDescriptor): @@ -32633,7 +32634,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[int]) - value: 'typing.Optional[int]' = None + value: typing.Optional[int] = None @dataclass class AbsMinCoolSetpointLimit(ClusterAttributeDescriptor): @@ -32649,7 +32650,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[int]) - value: 'typing.Optional[int]' = None + value: typing.Optional[int] = None @dataclass class AbsMaxCoolSetpointLimit(ClusterAttributeDescriptor): @@ -32665,7 +32666,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[int]) - value: 'typing.Optional[int]' = None + value: typing.Optional[int] = None @dataclass class PICoolingDemand(ClusterAttributeDescriptor): @@ -32681,7 +32682,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class PIHeatingDemand(ClusterAttributeDescriptor): @@ -32697,7 +32698,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class HVACSystemTypeConfiguration(ClusterAttributeDescriptor): @@ -32713,7 +32714,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class LocalTemperatureCalibration(ClusterAttributeDescriptor): @@ -32729,7 +32730,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[int]) - value: 'typing.Optional[int]' = None + value: typing.Optional[int] = None @dataclass class OccupiedCoolingSetpoint(ClusterAttributeDescriptor): @@ -32745,7 +32746,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[int]) - value: 'typing.Optional[int]' = None + value: typing.Optional[int] = None @dataclass class OccupiedHeatingSetpoint(ClusterAttributeDescriptor): @@ -32761,7 +32762,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[int]) - value: 'typing.Optional[int]' = None + value: typing.Optional[int] = None @dataclass class UnoccupiedCoolingSetpoint(ClusterAttributeDescriptor): @@ -32777,7 +32778,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[int]) - value: 'typing.Optional[int]' = None + value: typing.Optional[int] = None @dataclass class UnoccupiedHeatingSetpoint(ClusterAttributeDescriptor): @@ -32793,7 +32794,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[int]) - value: 'typing.Optional[int]' = None + value: typing.Optional[int] = None @dataclass class MinHeatSetpointLimit(ClusterAttributeDescriptor): @@ -32809,7 +32810,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[int]) - value: 'typing.Optional[int]' = None + value: typing.Optional[int] = None @dataclass class MaxHeatSetpointLimit(ClusterAttributeDescriptor): @@ -32825,7 +32826,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[int]) - value: 'typing.Optional[int]' = None + value: typing.Optional[int] = None @dataclass class MinCoolSetpointLimit(ClusterAttributeDescriptor): @@ -32841,7 +32842,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[int]) - value: 'typing.Optional[int]' = None + value: typing.Optional[int] = None @dataclass class MaxCoolSetpointLimit(ClusterAttributeDescriptor): @@ -32857,7 +32858,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[int]) - value: 'typing.Optional[int]' = None + value: typing.Optional[int] = None @dataclass class MinSetpointDeadBand(ClusterAttributeDescriptor): @@ -32873,7 +32874,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[int]) - value: 'typing.Optional[int]' = None + value: typing.Optional[int] = None @dataclass class RemoteSensing(ClusterAttributeDescriptor): @@ -32889,7 +32890,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class ControlSequenceOfOperation(ClusterAttributeDescriptor): @@ -32905,7 +32906,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=Thermostat.Enums.ControlSequenceOfOperationEnum) - value: 'Thermostat.Enums.ControlSequenceOfOperationEnum' = 0 + value: Thermostat.Enums.ControlSequenceOfOperationEnum = 0 @dataclass class SystemMode(ClusterAttributeDescriptor): @@ -32921,7 +32922,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=Thermostat.Enums.SystemModeEnum) - value: 'Thermostat.Enums.SystemModeEnum' = 0 + value: Thermostat.Enums.SystemModeEnum = 0 @dataclass class ThermostatRunningMode(ClusterAttributeDescriptor): @@ -32937,7 +32938,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[Thermostat.Enums.ThermostatRunningModeEnum]) - value: 'typing.Optional[Thermostat.Enums.ThermostatRunningModeEnum]' = None + value: typing.Optional[Thermostat.Enums.ThermostatRunningModeEnum] = None @dataclass class StartOfWeek(ClusterAttributeDescriptor): @@ -32953,7 +32954,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[Thermostat.Enums.StartOfWeekEnum]) - value: 'typing.Optional[Thermostat.Enums.StartOfWeekEnum]' = None + value: typing.Optional[Thermostat.Enums.StartOfWeekEnum] = None @dataclass class NumberOfWeeklyTransitions(ClusterAttributeDescriptor): @@ -32969,7 +32970,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class NumberOfDailyTransitions(ClusterAttributeDescriptor): @@ -32985,7 +32986,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class TemperatureSetpointHold(ClusterAttributeDescriptor): @@ -33001,7 +33002,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[Thermostat.Enums.TemperatureSetpointHoldEnum]) - value: 'typing.Optional[Thermostat.Enums.TemperatureSetpointHoldEnum]' = None + value: typing.Optional[Thermostat.Enums.TemperatureSetpointHoldEnum] = None @dataclass class TemperatureSetpointHoldDuration(ClusterAttributeDescriptor): @@ -33017,7 +33018,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class ThermostatProgrammingOperationMode(ClusterAttributeDescriptor): @@ -33033,7 +33034,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class ThermostatRunningState(ClusterAttributeDescriptor): @@ -33049,7 +33050,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class SetpointChangeSource(ClusterAttributeDescriptor): @@ -33065,7 +33066,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[Thermostat.Enums.SetpointChangeSourceEnum]) - value: 'typing.Optional[Thermostat.Enums.SetpointChangeSourceEnum]' = None + value: typing.Optional[Thermostat.Enums.SetpointChangeSourceEnum] = None @dataclass class SetpointChangeAmount(ClusterAttributeDescriptor): @@ -33081,7 +33082,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, int]) - value: 'typing.Union[None, Nullable, int]' = None + value: typing.Union[None, Nullable, int] = None @dataclass class SetpointChangeSourceTimestamp(ClusterAttributeDescriptor): @@ -33097,7 +33098,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class OccupiedSetback(ClusterAttributeDescriptor): @@ -33113,7 +33114,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class OccupiedSetbackMin(ClusterAttributeDescriptor): @@ -33129,7 +33130,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class OccupiedSetbackMax(ClusterAttributeDescriptor): @@ -33145,7 +33146,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class UnoccupiedSetback(ClusterAttributeDescriptor): @@ -33161,7 +33162,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class UnoccupiedSetbackMin(ClusterAttributeDescriptor): @@ -33177,7 +33178,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class UnoccupiedSetbackMax(ClusterAttributeDescriptor): @@ -33193,7 +33194,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class EmergencyHeatDelta(ClusterAttributeDescriptor): @@ -33209,7 +33210,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class ACType(ClusterAttributeDescriptor): @@ -33225,7 +33226,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[Thermostat.Enums.ACTypeEnum]) - value: 'typing.Optional[Thermostat.Enums.ACTypeEnum]' = None + value: typing.Optional[Thermostat.Enums.ACTypeEnum] = None @dataclass class ACCapacity(ClusterAttributeDescriptor): @@ -33241,7 +33242,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class ACRefrigerantType(ClusterAttributeDescriptor): @@ -33257,7 +33258,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[Thermostat.Enums.ACRefrigerantTypeEnum]) - value: 'typing.Optional[Thermostat.Enums.ACRefrigerantTypeEnum]' = None + value: typing.Optional[Thermostat.Enums.ACRefrigerantTypeEnum] = None @dataclass class ACCompressorType(ClusterAttributeDescriptor): @@ -33273,7 +33274,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[Thermostat.Enums.ACCompressorTypeEnum]) - value: 'typing.Optional[Thermostat.Enums.ACCompressorTypeEnum]' = None + value: typing.Optional[Thermostat.Enums.ACCompressorTypeEnum] = None @dataclass class ACErrorCode(ClusterAttributeDescriptor): @@ -33289,7 +33290,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class ACLouverPosition(ClusterAttributeDescriptor): @@ -33305,7 +33306,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[Thermostat.Enums.ACLouverPositionEnum]) - value: 'typing.Optional[Thermostat.Enums.ACLouverPositionEnum]' = None + value: typing.Optional[Thermostat.Enums.ACLouverPositionEnum] = None @dataclass class ACCoilTemperature(ClusterAttributeDescriptor): @@ -33321,7 +33322,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, int]) - value: 'typing.Union[None, Nullable, int]' = None + value: typing.Union[None, Nullable, int] = None @dataclass class ACCapacityformat(ClusterAttributeDescriptor): @@ -33337,7 +33338,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[Thermostat.Enums.ACCapacityFormatEnum]) - value: 'typing.Optional[Thermostat.Enums.ACCapacityFormatEnum]' = None + value: typing.Optional[Thermostat.Enums.ACCapacityFormatEnum] = None @dataclass class PresetTypes(ClusterAttributeDescriptor): @@ -33353,7 +33354,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[typing.List[Thermostat.Structs.PresetTypeStruct]]) - value: 'typing.Optional[typing.List[Thermostat.Structs.PresetTypeStruct]]' = None + value: typing.Optional[typing.List[Thermostat.Structs.PresetTypeStruct]] = None @dataclass class ScheduleTypes(ClusterAttributeDescriptor): @@ -33369,7 +33370,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[typing.List[Thermostat.Structs.ScheduleTypeStruct]]) - value: 'typing.Optional[typing.List[Thermostat.Structs.ScheduleTypeStruct]]' = None + value: typing.Optional[typing.List[Thermostat.Structs.ScheduleTypeStruct]] = None @dataclass class NumberOfPresets(ClusterAttributeDescriptor): @@ -33385,7 +33386,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class NumberOfSchedules(ClusterAttributeDescriptor): @@ -33401,7 +33402,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class NumberOfScheduleTransitions(ClusterAttributeDescriptor): @@ -33417,7 +33418,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class NumberOfScheduleTransitionPerDay(ClusterAttributeDescriptor): @@ -33433,7 +33434,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class ActivePresetHandle(ClusterAttributeDescriptor): @@ -33449,7 +33450,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, bytes]) - value: 'typing.Union[None, Nullable, bytes]' = None + value: typing.Union[None, Nullable, bytes] = None @dataclass class ActiveScheduleHandle(ClusterAttributeDescriptor): @@ -33465,7 +33466,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, bytes]) - value: 'typing.Union[None, Nullable, bytes]' = None + value: typing.Union[None, Nullable, bytes] = None @dataclass class Presets(ClusterAttributeDescriptor): @@ -33481,7 +33482,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[typing.List[Thermostat.Structs.PresetStruct]]) - value: 'typing.Optional[typing.List[Thermostat.Structs.PresetStruct]]' = None + value: typing.Optional[typing.List[Thermostat.Structs.PresetStruct]] = None @dataclass class Schedules(ClusterAttributeDescriptor): @@ -33497,7 +33498,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[typing.List[Thermostat.Structs.ScheduleStruct]]) - value: 'typing.Optional[typing.List[Thermostat.Structs.ScheduleStruct]]' = None + value: typing.Optional[typing.List[Thermostat.Structs.ScheduleStruct]] = None @dataclass class SetpointHoldExpiryTimestamp(ClusterAttributeDescriptor): @@ -33513,7 +33514,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -33529,7 +33530,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -33545,7 +33546,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -33561,7 +33562,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -33577,7 +33578,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -33593,7 +33594,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -33609,7 +33610,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -33640,24 +33641,24 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - fanMode: 'FanControl.Enums.FanModeEnum' = None - fanModeSequence: 'FanControl.Enums.FanModeSequenceEnum' = None - percentSetting: 'typing.Union[Nullable, uint]' = None - percentCurrent: 'uint' = None - speedMax: 'typing.Optional[uint]' = None - speedSetting: 'typing.Union[None, Nullable, uint]' = None - speedCurrent: 'typing.Optional[uint]' = None - rockSupport: 'typing.Optional[uint]' = None - rockSetting: 'typing.Optional[uint]' = None - windSupport: 'typing.Optional[uint]' = None - windSetting: 'typing.Optional[uint]' = None - airflowDirection: 'typing.Optional[FanControl.Enums.AirflowDirectionEnum]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + fanMode: FanControl.Enums.FanModeEnum = 0 + fanModeSequence: FanControl.Enums.FanModeSequenceEnum = 0 + percentSetting: typing.Union[Nullable, uint] = NullValue + percentCurrent: uint = 0 + speedMax: typing.Optional[uint] = None + speedSetting: typing.Union[None, Nullable, uint] = None + speedCurrent: typing.Optional[uint] = None + rockSupport: typing.Optional[uint] = None + rockSetting: typing.Optional[uint] = None + windSupport: typing.Optional[uint] = None + windSetting: typing.Optional[uint] = None + airflowDirection: typing.Optional[FanControl.Enums.AirflowDirectionEnum] = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class AirflowDirectionEnum(MatterIntEnum): @@ -33729,7 +33730,7 @@ class Step(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000202 command_id: typing.ClassVar[int] = 0x00000000 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -33740,9 +33741,9 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="lowestOff", Tag=2, Type=typing.Optional[bool]), ]) - direction: 'FanControl.Enums.StepDirectionEnum' = 0 - wrap: 'typing.Optional[bool]' = None - lowestOff: 'typing.Optional[bool]' = None + direction: FanControl.Enums.StepDirectionEnum = 0 + wrap: typing.Optional[bool] = None + lowestOff: typing.Optional[bool] = None class Attributes: @dataclass @@ -33759,7 +33760,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=FanControl.Enums.FanModeEnum) - value: 'FanControl.Enums.FanModeEnum' = 0 + value: FanControl.Enums.FanModeEnum = 0 @dataclass class FanModeSequence(ClusterAttributeDescriptor): @@ -33775,7 +33776,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=FanControl.Enums.FanModeSequenceEnum) - value: 'FanControl.Enums.FanModeSequenceEnum' = 0 + value: FanControl.Enums.FanModeSequenceEnum = 0 @dataclass class PercentSetting(ClusterAttributeDescriptor): @@ -33791,7 +33792,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, uint]) - value: 'typing.Union[Nullable, uint]' = NullValue + value: typing.Union[Nullable, uint] = NullValue @dataclass class PercentCurrent(ClusterAttributeDescriptor): @@ -33807,7 +33808,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class SpeedMax(ClusterAttributeDescriptor): @@ -33823,7 +33824,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class SpeedSetting(ClusterAttributeDescriptor): @@ -33839,7 +33840,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class SpeedCurrent(ClusterAttributeDescriptor): @@ -33855,7 +33856,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class RockSupport(ClusterAttributeDescriptor): @@ -33871,7 +33872,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class RockSetting(ClusterAttributeDescriptor): @@ -33887,7 +33888,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class WindSupport(ClusterAttributeDescriptor): @@ -33903,7 +33904,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class WindSetting(ClusterAttributeDescriptor): @@ -33919,7 +33920,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class AirflowDirection(ClusterAttributeDescriptor): @@ -33935,7 +33936,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[FanControl.Enums.AirflowDirectionEnum]) - value: 'typing.Optional[FanControl.Enums.AirflowDirectionEnum]' = None + value: typing.Optional[FanControl.Enums.AirflowDirectionEnum] = None @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -33951,7 +33952,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -33967,7 +33968,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -33983,7 +33984,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -33999,7 +34000,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -34015,7 +34016,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -34031,7 +34032,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -34053,15 +34054,15 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - temperatureDisplayMode: 'ThermostatUserInterfaceConfiguration.Enums.TemperatureDisplayModeEnum' = None - keypadLockout: 'ThermostatUserInterfaceConfiguration.Enums.KeypadLockoutEnum' = None - scheduleProgrammingVisibility: 'typing.Optional[ThermostatUserInterfaceConfiguration.Enums.ScheduleProgrammingVisibilityEnum]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + temperatureDisplayMode: ThermostatUserInterfaceConfiguration.Enums.TemperatureDisplayModeEnum = 0 + keypadLockout: ThermostatUserInterfaceConfiguration.Enums.KeypadLockoutEnum = 0 + scheduleProgrammingVisibility: typing.Optional[ThermostatUserInterfaceConfiguration.Enums.ScheduleProgrammingVisibilityEnum] = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class KeypadLockoutEnum(MatterIntEnum): @@ -34110,7 +34111,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=ThermostatUserInterfaceConfiguration.Enums.TemperatureDisplayModeEnum) - value: 'ThermostatUserInterfaceConfiguration.Enums.TemperatureDisplayModeEnum' = 0 + value: ThermostatUserInterfaceConfiguration.Enums.TemperatureDisplayModeEnum = 0 @dataclass class KeypadLockout(ClusterAttributeDescriptor): @@ -34126,7 +34127,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=ThermostatUserInterfaceConfiguration.Enums.KeypadLockoutEnum) - value: 'ThermostatUserInterfaceConfiguration.Enums.KeypadLockoutEnum' = 0 + value: ThermostatUserInterfaceConfiguration.Enums.KeypadLockoutEnum = 0 @dataclass class ScheduleProgrammingVisibility(ClusterAttributeDescriptor): @@ -34142,7 +34143,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[ThermostatUserInterfaceConfiguration.Enums.ScheduleProgrammingVisibilityEnum]) - value: 'typing.Optional[ThermostatUserInterfaceConfiguration.Enums.ScheduleProgrammingVisibilityEnum]' = None + value: typing.Optional[ThermostatUserInterfaceConfiguration.Enums.ScheduleProgrammingVisibilityEnum] = None @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -34158,7 +34159,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -34174,7 +34175,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -34190,7 +34191,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -34206,7 +34207,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -34222,7 +34223,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -34238,7 +34239,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -34309,64 +34310,64 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - currentHue: 'typing.Optional[uint]' = None - currentSaturation: 'typing.Optional[uint]' = None - remainingTime: 'typing.Optional[uint]' = None - currentX: 'typing.Optional[uint]' = None - currentY: 'typing.Optional[uint]' = None - driftCompensation: 'typing.Optional[ColorControl.Enums.DriftCompensationEnum]' = None - compensationText: 'typing.Optional[str]' = None - colorTemperatureMireds: 'typing.Optional[uint]' = None - colorMode: 'ColorControl.Enums.ColorModeEnum' = None - options: 'uint' = None - numberOfPrimaries: 'typing.Union[Nullable, uint]' = None - primary1X: 'typing.Optional[uint]' = None - primary1Y: 'typing.Optional[uint]' = None - primary1Intensity: 'typing.Union[None, Nullable, uint]' = None - primary2X: 'typing.Optional[uint]' = None - primary2Y: 'typing.Optional[uint]' = None - primary2Intensity: 'typing.Union[None, Nullable, uint]' = None - primary3X: 'typing.Optional[uint]' = None - primary3Y: 'typing.Optional[uint]' = None - primary3Intensity: 'typing.Union[None, Nullable, uint]' = None - primary4X: 'typing.Optional[uint]' = None - primary4Y: 'typing.Optional[uint]' = None - primary4Intensity: 'typing.Union[None, Nullable, uint]' = None - primary5X: 'typing.Optional[uint]' = None - primary5Y: 'typing.Optional[uint]' = None - primary5Intensity: 'typing.Union[None, Nullable, uint]' = None - primary6X: 'typing.Optional[uint]' = None - primary6Y: 'typing.Optional[uint]' = None - primary6Intensity: 'typing.Union[None, Nullable, uint]' = None - whitePointX: 'typing.Optional[uint]' = None - whitePointY: 'typing.Optional[uint]' = None - colorPointRX: 'typing.Optional[uint]' = None - colorPointRY: 'typing.Optional[uint]' = None - colorPointRIntensity: 'typing.Union[None, Nullable, uint]' = None - colorPointGX: 'typing.Optional[uint]' = None - colorPointGY: 'typing.Optional[uint]' = None - colorPointGIntensity: 'typing.Union[None, Nullable, uint]' = None - colorPointBX: 'typing.Optional[uint]' = None - colorPointBY: 'typing.Optional[uint]' = None - colorPointBIntensity: 'typing.Union[None, Nullable, uint]' = None - enhancedCurrentHue: 'typing.Optional[uint]' = None - enhancedColorMode: 'ColorControl.Enums.EnhancedColorModeEnum' = None - colorLoopActive: 'typing.Optional[uint]' = None - colorLoopDirection: 'typing.Optional[uint]' = None - colorLoopTime: 'typing.Optional[uint]' = None - colorLoopStartEnhancedHue: 'typing.Optional[uint]' = None - colorLoopStoredEnhancedHue: 'typing.Optional[uint]' = None - colorCapabilities: 'uint' = None - colorTempPhysicalMinMireds: 'typing.Optional[uint]' = None - colorTempPhysicalMaxMireds: 'typing.Optional[uint]' = None - coupleColorTempToLevelMinMireds: 'typing.Optional[uint]' = None - startUpColorTemperatureMireds: 'typing.Union[None, Nullable, uint]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + currentHue: typing.Optional[uint] = None + currentSaturation: typing.Optional[uint] = None + remainingTime: typing.Optional[uint] = None + currentX: typing.Optional[uint] = None + currentY: typing.Optional[uint] = None + driftCompensation: typing.Optional[ColorControl.Enums.DriftCompensationEnum] = None + compensationText: typing.Optional[str] = None + colorTemperatureMireds: typing.Optional[uint] = None + colorMode: ColorControl.Enums.ColorModeEnum = 0 + options: uint = 0 + numberOfPrimaries: typing.Union[Nullable, uint] = NullValue + primary1X: typing.Optional[uint] = None + primary1Y: typing.Optional[uint] = None + primary1Intensity: typing.Union[None, Nullable, uint] = None + primary2X: typing.Optional[uint] = None + primary2Y: typing.Optional[uint] = None + primary2Intensity: typing.Union[None, Nullable, uint] = None + primary3X: typing.Optional[uint] = None + primary3Y: typing.Optional[uint] = None + primary3Intensity: typing.Union[None, Nullable, uint] = None + primary4X: typing.Optional[uint] = None + primary4Y: typing.Optional[uint] = None + primary4Intensity: typing.Union[None, Nullable, uint] = None + primary5X: typing.Optional[uint] = None + primary5Y: typing.Optional[uint] = None + primary5Intensity: typing.Union[None, Nullable, uint] = None + primary6X: typing.Optional[uint] = None + primary6Y: typing.Optional[uint] = None + primary6Intensity: typing.Union[None, Nullable, uint] = None + whitePointX: typing.Optional[uint] = None + whitePointY: typing.Optional[uint] = None + colorPointRX: typing.Optional[uint] = None + colorPointRY: typing.Optional[uint] = None + colorPointRIntensity: typing.Union[None, Nullable, uint] = None + colorPointGX: typing.Optional[uint] = None + colorPointGY: typing.Optional[uint] = None + colorPointGIntensity: typing.Union[None, Nullable, uint] = None + colorPointBX: typing.Optional[uint] = None + colorPointBY: typing.Optional[uint] = None + colorPointBIntensity: typing.Union[None, Nullable, uint] = None + enhancedCurrentHue: typing.Optional[uint] = None + enhancedColorMode: ColorControl.Enums.EnhancedColorModeEnum = 0 + colorLoopActive: typing.Optional[uint] = None + colorLoopDirection: typing.Optional[uint] = None + colorLoopTime: typing.Optional[uint] = None + colorLoopStartEnhancedHue: typing.Optional[uint] = None + colorLoopStoredEnhancedHue: typing.Optional[uint] = None + colorCapabilities: uint = 0 + colorTempPhysicalMinMireds: typing.Optional[uint] = None + colorTempPhysicalMaxMireds: typing.Optional[uint] = None + coupleColorTempToLevelMinMireds: typing.Optional[uint] = None + startUpColorTemperatureMireds: typing.Union[None, Nullable, uint] = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class ColorLoopActionEnum(MatterIntEnum): @@ -34481,7 +34482,7 @@ class MoveToHue(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000300 command_id: typing.ClassVar[int] = 0x00000000 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -34494,18 +34495,18 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="optionsOverride", Tag=4, Type=uint), ]) - hue: 'uint' = 0 - direction: 'ColorControl.Enums.DirectionEnum' = 0 - transitionTime: 'uint' = 0 - optionsMask: 'uint' = 0 - optionsOverride: 'uint' = 0 + hue: uint = 0 + direction: ColorControl.Enums.DirectionEnum = 0 + transitionTime: uint = 0 + optionsMask: uint = 0 + optionsOverride: uint = 0 @dataclass class MoveHue(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000300 command_id: typing.ClassVar[int] = 0x00000001 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -34517,17 +34518,17 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="optionsOverride", Tag=3, Type=uint), ]) - moveMode: 'ColorControl.Enums.MoveModeEnum' = 0 - rate: 'uint' = 0 - optionsMask: 'uint' = 0 - optionsOverride: 'uint' = 0 + moveMode: ColorControl.Enums.MoveModeEnum = 0 + rate: uint = 0 + optionsMask: uint = 0 + optionsOverride: uint = 0 @dataclass class StepHue(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000300 command_id: typing.ClassVar[int] = 0x00000002 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -34540,18 +34541,18 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="optionsOverride", Tag=4, Type=uint), ]) - stepMode: 'ColorControl.Enums.StepModeEnum' = 0 - stepSize: 'uint' = 0 - transitionTime: 'uint' = 0 - optionsMask: 'uint' = 0 - optionsOverride: 'uint' = 0 + stepMode: ColorControl.Enums.StepModeEnum = 0 + stepSize: uint = 0 + transitionTime: uint = 0 + optionsMask: uint = 0 + optionsOverride: uint = 0 @dataclass class MoveToSaturation(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000300 command_id: typing.ClassVar[int] = 0x00000003 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -34563,17 +34564,17 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="optionsOverride", Tag=3, Type=uint), ]) - saturation: 'uint' = 0 - transitionTime: 'uint' = 0 - optionsMask: 'uint' = 0 - optionsOverride: 'uint' = 0 + saturation: uint = 0 + transitionTime: uint = 0 + optionsMask: uint = 0 + optionsOverride: uint = 0 @dataclass class MoveSaturation(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000300 command_id: typing.ClassVar[int] = 0x00000004 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -34585,17 +34586,17 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="optionsOverride", Tag=3, Type=uint), ]) - moveMode: 'ColorControl.Enums.MoveModeEnum' = 0 - rate: 'uint' = 0 - optionsMask: 'uint' = 0 - optionsOverride: 'uint' = 0 + moveMode: ColorControl.Enums.MoveModeEnum = 0 + rate: uint = 0 + optionsMask: uint = 0 + optionsOverride: uint = 0 @dataclass class StepSaturation(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000300 command_id: typing.ClassVar[int] = 0x00000005 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -34608,18 +34609,18 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="optionsOverride", Tag=4, Type=uint), ]) - stepMode: 'ColorControl.Enums.StepModeEnum' = 0 - stepSize: 'uint' = 0 - transitionTime: 'uint' = 0 - optionsMask: 'uint' = 0 - optionsOverride: 'uint' = 0 + stepMode: ColorControl.Enums.StepModeEnum = 0 + stepSize: uint = 0 + transitionTime: uint = 0 + optionsMask: uint = 0 + optionsOverride: uint = 0 @dataclass class MoveToHueAndSaturation(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000300 command_id: typing.ClassVar[int] = 0x00000006 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -34632,18 +34633,18 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="optionsOverride", Tag=4, Type=uint), ]) - hue: 'uint' = 0 - saturation: 'uint' = 0 - transitionTime: 'uint' = 0 - optionsMask: 'uint' = 0 - optionsOverride: 'uint' = 0 + hue: uint = 0 + saturation: uint = 0 + transitionTime: uint = 0 + optionsMask: uint = 0 + optionsOverride: uint = 0 @dataclass class MoveToColor(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000300 command_id: typing.ClassVar[int] = 0x00000007 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -34656,18 +34657,18 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="optionsOverride", Tag=4, Type=uint), ]) - colorX: 'uint' = 0 - colorY: 'uint' = 0 - transitionTime: 'uint' = 0 - optionsMask: 'uint' = 0 - optionsOverride: 'uint' = 0 + colorX: uint = 0 + colorY: uint = 0 + transitionTime: uint = 0 + optionsMask: uint = 0 + optionsOverride: uint = 0 @dataclass class MoveColor(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000300 command_id: typing.ClassVar[int] = 0x00000008 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -34679,17 +34680,17 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="optionsOverride", Tag=3, Type=uint), ]) - rateX: 'int' = 0 - rateY: 'int' = 0 - optionsMask: 'uint' = 0 - optionsOverride: 'uint' = 0 + rateX: int = 0 + rateY: int = 0 + optionsMask: uint = 0 + optionsOverride: uint = 0 @dataclass class StepColor(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000300 command_id: typing.ClassVar[int] = 0x00000009 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -34702,18 +34703,18 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="optionsOverride", Tag=4, Type=uint), ]) - stepX: 'int' = 0 - stepY: 'int' = 0 - transitionTime: 'uint' = 0 - optionsMask: 'uint' = 0 - optionsOverride: 'uint' = 0 + stepX: int = 0 + stepY: int = 0 + transitionTime: uint = 0 + optionsMask: uint = 0 + optionsOverride: uint = 0 @dataclass class MoveToColorTemperature(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000300 command_id: typing.ClassVar[int] = 0x0000000A is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -34725,17 +34726,17 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="optionsOverride", Tag=3, Type=uint), ]) - colorTemperatureMireds: 'uint' = 0 - transitionTime: 'uint' = 0 - optionsMask: 'uint' = 0 - optionsOverride: 'uint' = 0 + colorTemperatureMireds: uint = 0 + transitionTime: uint = 0 + optionsMask: uint = 0 + optionsOverride: uint = 0 @dataclass class EnhancedMoveToHue(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000300 command_id: typing.ClassVar[int] = 0x00000040 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -34748,18 +34749,18 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="optionsOverride", Tag=4, Type=uint), ]) - enhancedHue: 'uint' = 0 - direction: 'ColorControl.Enums.DirectionEnum' = 0 - transitionTime: 'uint' = 0 - optionsMask: 'uint' = 0 - optionsOverride: 'uint' = 0 + enhancedHue: uint = 0 + direction: ColorControl.Enums.DirectionEnum = 0 + transitionTime: uint = 0 + optionsMask: uint = 0 + optionsOverride: uint = 0 @dataclass class EnhancedMoveHue(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000300 command_id: typing.ClassVar[int] = 0x00000041 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -34771,17 +34772,17 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="optionsOverride", Tag=3, Type=uint), ]) - moveMode: 'ColorControl.Enums.MoveModeEnum' = 0 - rate: 'uint' = 0 - optionsMask: 'uint' = 0 - optionsOverride: 'uint' = 0 + moveMode: ColorControl.Enums.MoveModeEnum = 0 + rate: uint = 0 + optionsMask: uint = 0 + optionsOverride: uint = 0 @dataclass class EnhancedStepHue(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000300 command_id: typing.ClassVar[int] = 0x00000042 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -34794,18 +34795,18 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="optionsOverride", Tag=4, Type=uint), ]) - stepMode: 'ColorControl.Enums.StepModeEnum' = 0 - stepSize: 'uint' = 0 - transitionTime: 'uint' = 0 - optionsMask: 'uint' = 0 - optionsOverride: 'uint' = 0 + stepMode: ColorControl.Enums.StepModeEnum = 0 + stepSize: uint = 0 + transitionTime: uint = 0 + optionsMask: uint = 0 + optionsOverride: uint = 0 @dataclass class EnhancedMoveToHueAndSaturation(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000300 command_id: typing.ClassVar[int] = 0x00000043 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -34818,18 +34819,18 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="optionsOverride", Tag=4, Type=uint), ]) - enhancedHue: 'uint' = 0 - saturation: 'uint' = 0 - transitionTime: 'uint' = 0 - optionsMask: 'uint' = 0 - optionsOverride: 'uint' = 0 + enhancedHue: uint = 0 + saturation: uint = 0 + transitionTime: uint = 0 + optionsMask: uint = 0 + optionsOverride: uint = 0 @dataclass class ColorLoopSet(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000300 command_id: typing.ClassVar[int] = 0x00000044 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -34844,20 +34845,20 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="optionsOverride", Tag=6, Type=uint), ]) - updateFlags: 'uint' = 0 - action: 'ColorControl.Enums.ColorLoopActionEnum' = 0 - direction: 'ColorControl.Enums.ColorLoopDirectionEnum' = 0 - time: 'uint' = 0 - startHue: 'uint' = 0 - optionsMask: 'uint' = 0 - optionsOverride: 'uint' = 0 + updateFlags: uint = 0 + action: ColorControl.Enums.ColorLoopActionEnum = 0 + direction: ColorControl.Enums.ColorLoopDirectionEnum = 0 + time: uint = 0 + startHue: uint = 0 + optionsMask: uint = 0 + optionsOverride: uint = 0 @dataclass class StopMoveStep(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000300 command_id: typing.ClassVar[int] = 0x00000047 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -34867,15 +34868,15 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="optionsOverride", Tag=1, Type=uint), ]) - optionsMask: 'uint' = 0 - optionsOverride: 'uint' = 0 + optionsMask: uint = 0 + optionsOverride: uint = 0 @dataclass class MoveColorTemperature(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000300 command_id: typing.ClassVar[int] = 0x0000004B is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -34889,19 +34890,19 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="optionsOverride", Tag=5, Type=uint), ]) - moveMode: 'ColorControl.Enums.MoveModeEnum' = 0 - rate: 'uint' = 0 - colorTemperatureMinimumMireds: 'uint' = 0 - colorTemperatureMaximumMireds: 'uint' = 0 - optionsMask: 'uint' = 0 - optionsOverride: 'uint' = 0 + moveMode: ColorControl.Enums.MoveModeEnum = 0 + rate: uint = 0 + colorTemperatureMinimumMireds: uint = 0 + colorTemperatureMaximumMireds: uint = 0 + optionsMask: uint = 0 + optionsOverride: uint = 0 @dataclass class StepColorTemperature(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000300 command_id: typing.ClassVar[int] = 0x0000004C is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -34916,13 +34917,13 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="optionsOverride", Tag=6, Type=uint), ]) - stepMode: 'ColorControl.Enums.StepModeEnum' = 0 - stepSize: 'uint' = 0 - transitionTime: 'uint' = 0 - colorTemperatureMinimumMireds: 'uint' = 0 - colorTemperatureMaximumMireds: 'uint' = 0 - optionsMask: 'uint' = 0 - optionsOverride: 'uint' = 0 + stepMode: ColorControl.Enums.StepModeEnum = 0 + stepSize: uint = 0 + transitionTime: uint = 0 + colorTemperatureMinimumMireds: uint = 0 + colorTemperatureMaximumMireds: uint = 0 + optionsMask: uint = 0 + optionsOverride: uint = 0 class Attributes: @dataclass @@ -34939,7 +34940,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class CurrentSaturation(ClusterAttributeDescriptor): @@ -34955,7 +34956,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class RemainingTime(ClusterAttributeDescriptor): @@ -34971,7 +34972,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class CurrentX(ClusterAttributeDescriptor): @@ -34987,7 +34988,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class CurrentY(ClusterAttributeDescriptor): @@ -35003,7 +35004,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class DriftCompensation(ClusterAttributeDescriptor): @@ -35019,7 +35020,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[ColorControl.Enums.DriftCompensationEnum]) - value: 'typing.Optional[ColorControl.Enums.DriftCompensationEnum]' = None + value: typing.Optional[ColorControl.Enums.DriftCompensationEnum] = None @dataclass class CompensationText(ClusterAttributeDescriptor): @@ -35035,7 +35036,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[str]) - value: 'typing.Optional[str]' = None + value: typing.Optional[str] = None @dataclass class ColorTemperatureMireds(ClusterAttributeDescriptor): @@ -35051,7 +35052,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class ColorMode(ClusterAttributeDescriptor): @@ -35067,7 +35068,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=ColorControl.Enums.ColorModeEnum) - value: 'ColorControl.Enums.ColorModeEnum' = 0 + value: ColorControl.Enums.ColorModeEnum = 0 @dataclass class Options(ClusterAttributeDescriptor): @@ -35083,7 +35084,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class NumberOfPrimaries(ClusterAttributeDescriptor): @@ -35099,7 +35100,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, uint]) - value: 'typing.Union[Nullable, uint]' = NullValue + value: typing.Union[Nullable, uint] = NullValue @dataclass class Primary1X(ClusterAttributeDescriptor): @@ -35115,7 +35116,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class Primary1Y(ClusterAttributeDescriptor): @@ -35131,7 +35132,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class Primary1Intensity(ClusterAttributeDescriptor): @@ -35147,7 +35148,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class Primary2X(ClusterAttributeDescriptor): @@ -35163,7 +35164,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class Primary2Y(ClusterAttributeDescriptor): @@ -35179,7 +35180,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class Primary2Intensity(ClusterAttributeDescriptor): @@ -35195,7 +35196,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class Primary3X(ClusterAttributeDescriptor): @@ -35211,7 +35212,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class Primary3Y(ClusterAttributeDescriptor): @@ -35227,7 +35228,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class Primary3Intensity(ClusterAttributeDescriptor): @@ -35243,7 +35244,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class Primary4X(ClusterAttributeDescriptor): @@ -35259,7 +35260,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class Primary4Y(ClusterAttributeDescriptor): @@ -35275,7 +35276,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class Primary4Intensity(ClusterAttributeDescriptor): @@ -35291,7 +35292,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class Primary5X(ClusterAttributeDescriptor): @@ -35307,7 +35308,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class Primary5Y(ClusterAttributeDescriptor): @@ -35323,7 +35324,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class Primary5Intensity(ClusterAttributeDescriptor): @@ -35339,7 +35340,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class Primary6X(ClusterAttributeDescriptor): @@ -35355,7 +35356,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class Primary6Y(ClusterAttributeDescriptor): @@ -35371,7 +35372,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class Primary6Intensity(ClusterAttributeDescriptor): @@ -35387,7 +35388,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class WhitePointX(ClusterAttributeDescriptor): @@ -35403,7 +35404,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class WhitePointY(ClusterAttributeDescriptor): @@ -35419,7 +35420,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class ColorPointRX(ClusterAttributeDescriptor): @@ -35435,7 +35436,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class ColorPointRY(ClusterAttributeDescriptor): @@ -35451,7 +35452,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class ColorPointRIntensity(ClusterAttributeDescriptor): @@ -35467,7 +35468,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class ColorPointGX(ClusterAttributeDescriptor): @@ -35483,7 +35484,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class ColorPointGY(ClusterAttributeDescriptor): @@ -35499,7 +35500,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class ColorPointGIntensity(ClusterAttributeDescriptor): @@ -35515,7 +35516,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class ColorPointBX(ClusterAttributeDescriptor): @@ -35531,7 +35532,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class ColorPointBY(ClusterAttributeDescriptor): @@ -35547,7 +35548,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class ColorPointBIntensity(ClusterAttributeDescriptor): @@ -35563,7 +35564,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class EnhancedCurrentHue(ClusterAttributeDescriptor): @@ -35579,7 +35580,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class EnhancedColorMode(ClusterAttributeDescriptor): @@ -35595,7 +35596,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=ColorControl.Enums.EnhancedColorModeEnum) - value: 'ColorControl.Enums.EnhancedColorModeEnum' = 0 + value: ColorControl.Enums.EnhancedColorModeEnum = 0 @dataclass class ColorLoopActive(ClusterAttributeDescriptor): @@ -35611,7 +35612,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class ColorLoopDirection(ClusterAttributeDescriptor): @@ -35627,7 +35628,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class ColorLoopTime(ClusterAttributeDescriptor): @@ -35643,7 +35644,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class ColorLoopStartEnhancedHue(ClusterAttributeDescriptor): @@ -35659,7 +35660,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class ColorLoopStoredEnhancedHue(ClusterAttributeDescriptor): @@ -35675,7 +35676,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class ColorCapabilities(ClusterAttributeDescriptor): @@ -35691,7 +35692,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ColorTempPhysicalMinMireds(ClusterAttributeDescriptor): @@ -35707,7 +35708,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class ColorTempPhysicalMaxMireds(ClusterAttributeDescriptor): @@ -35723,7 +35724,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class CoupleColorTempToLevelMinMireds(ClusterAttributeDescriptor): @@ -35739,7 +35740,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class StartUpColorTemperatureMireds(ClusterAttributeDescriptor): @@ -35755,7 +35756,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -35771,7 +35772,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -35787,7 +35788,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -35803,7 +35804,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -35819,7 +35820,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -35835,7 +35836,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -35851,7 +35852,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -35884,26 +35885,26 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - physicalMinLevel: 'uint' = None - physicalMaxLevel: 'uint' = None - ballastStatus: 'typing.Optional[uint]' = None - minLevel: 'uint' = None - maxLevel: 'uint' = None - intrinsicBallastFactor: 'typing.Union[None, Nullable, uint]' = None - ballastFactorAdjustment: 'typing.Union[None, Nullable, uint]' = None - lampQuantity: 'uint' = None - lampType: 'typing.Optional[str]' = None - lampManufacturer: 'typing.Optional[str]' = None - lampRatedHours: 'typing.Union[None, Nullable, uint]' = None - lampBurnHours: 'typing.Union[None, Nullable, uint]' = None - lampAlarmMode: 'typing.Optional[uint]' = None - lampBurnHoursTripPoint: 'typing.Union[None, Nullable, uint]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + physicalMinLevel: uint = 0 + physicalMaxLevel: uint = 0 + ballastStatus: typing.Optional[uint] = None + minLevel: uint = 0 + maxLevel: uint = 0 + intrinsicBallastFactor: typing.Union[None, Nullable, uint] = None + ballastFactorAdjustment: typing.Union[None, Nullable, uint] = None + lampQuantity: uint = 0 + lampType: typing.Optional[str] = None + lampManufacturer: typing.Optional[str] = None + lampRatedHours: typing.Union[None, Nullable, uint] = None + lampBurnHours: typing.Union[None, Nullable, uint] = None + lampAlarmMode: typing.Optional[uint] = None + lampBurnHoursTripPoint: typing.Union[None, Nullable, uint] = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Bitmaps: class BallastStatusBitmap(IntFlag): @@ -35928,7 +35929,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class PhysicalMaxLevel(ClusterAttributeDescriptor): @@ -35944,7 +35945,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class BallastStatus(ClusterAttributeDescriptor): @@ -35960,7 +35961,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class MinLevel(ClusterAttributeDescriptor): @@ -35976,7 +35977,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class MaxLevel(ClusterAttributeDescriptor): @@ -35992,7 +35993,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class IntrinsicBallastFactor(ClusterAttributeDescriptor): @@ -36008,7 +36009,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class BallastFactorAdjustment(ClusterAttributeDescriptor): @@ -36024,7 +36025,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class LampQuantity(ClusterAttributeDescriptor): @@ -36040,7 +36041,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class LampType(ClusterAttributeDescriptor): @@ -36056,7 +36057,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[str]) - value: 'typing.Optional[str]' = None + value: typing.Optional[str] = None @dataclass class LampManufacturer(ClusterAttributeDescriptor): @@ -36072,7 +36073,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[str]) - value: 'typing.Optional[str]' = None + value: typing.Optional[str] = None @dataclass class LampRatedHours(ClusterAttributeDescriptor): @@ -36088,7 +36089,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class LampBurnHours(ClusterAttributeDescriptor): @@ -36104,7 +36105,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class LampAlarmMode(ClusterAttributeDescriptor): @@ -36120,7 +36121,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class LampBurnHoursTripPoint(ClusterAttributeDescriptor): @@ -36136,7 +36137,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -36152,7 +36153,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -36168,7 +36169,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -36184,7 +36185,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -36200,7 +36201,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -36216,7 +36217,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -36232,7 +36233,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -36256,17 +36257,17 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - measuredValue: 'typing.Union[Nullable, uint]' = None - minMeasuredValue: 'typing.Union[Nullable, uint]' = None - maxMeasuredValue: 'typing.Union[Nullable, uint]' = None - tolerance: 'typing.Optional[uint]' = None - lightSensorType: 'typing.Union[None, Nullable, IlluminanceMeasurement.Enums.LightSensorTypeEnum]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + measuredValue: typing.Union[Nullable, uint] = NullValue + minMeasuredValue: typing.Union[Nullable, uint] = NullValue + maxMeasuredValue: typing.Union[Nullable, uint] = NullValue + tolerance: typing.Optional[uint] = None + lightSensorType: typing.Union[None, Nullable, IlluminanceMeasurement.Enums.LightSensorTypeEnum] = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class LightSensorTypeEnum(MatterIntEnum): @@ -36293,7 +36294,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, uint]) - value: 'typing.Union[Nullable, uint]' = NullValue + value: typing.Union[Nullable, uint] = NullValue @dataclass class MinMeasuredValue(ClusterAttributeDescriptor): @@ -36309,7 +36310,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, uint]) - value: 'typing.Union[Nullable, uint]' = NullValue + value: typing.Union[Nullable, uint] = NullValue @dataclass class MaxMeasuredValue(ClusterAttributeDescriptor): @@ -36325,7 +36326,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, uint]) - value: 'typing.Union[Nullable, uint]' = NullValue + value: typing.Union[Nullable, uint] = NullValue @dataclass class Tolerance(ClusterAttributeDescriptor): @@ -36341,7 +36342,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class LightSensorType(ClusterAttributeDescriptor): @@ -36357,7 +36358,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, IlluminanceMeasurement.Enums.LightSensorTypeEnum]) - value: 'typing.Union[None, Nullable, IlluminanceMeasurement.Enums.LightSensorTypeEnum]' = None + value: typing.Union[None, Nullable, IlluminanceMeasurement.Enums.LightSensorTypeEnum] = None @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -36373,7 +36374,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -36389,7 +36390,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -36405,7 +36406,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -36421,7 +36422,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -36437,7 +36438,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -36453,7 +36454,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -36476,16 +36477,16 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - measuredValue: 'typing.Union[Nullable, int]' = None - minMeasuredValue: 'typing.Union[Nullable, int]' = None - maxMeasuredValue: 'typing.Union[Nullable, int]' = None - tolerance: 'typing.Optional[uint]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + measuredValue: typing.Union[Nullable, int] = NullValue + minMeasuredValue: typing.Union[Nullable, int] = NullValue + maxMeasuredValue: typing.Union[Nullable, int] = NullValue + tolerance: typing.Optional[uint] = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Attributes: @dataclass @@ -36502,7 +36503,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, int]) - value: 'typing.Union[Nullable, int]' = NullValue + value: typing.Union[Nullable, int] = NullValue @dataclass class MinMeasuredValue(ClusterAttributeDescriptor): @@ -36518,7 +36519,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, int]) - value: 'typing.Union[Nullable, int]' = NullValue + value: typing.Union[Nullable, int] = NullValue @dataclass class MaxMeasuredValue(ClusterAttributeDescriptor): @@ -36534,7 +36535,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, int]) - value: 'typing.Union[Nullable, int]' = NullValue + value: typing.Union[Nullable, int] = NullValue @dataclass class Tolerance(ClusterAttributeDescriptor): @@ -36550,7 +36551,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -36566,7 +36567,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -36582,7 +36583,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -36598,7 +36599,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -36614,7 +36615,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -36630,7 +36631,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -36646,7 +36647,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -36674,21 +36675,21 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - measuredValue: 'typing.Union[Nullable, int]' = None - minMeasuredValue: 'typing.Union[Nullable, int]' = None - maxMeasuredValue: 'typing.Union[Nullable, int]' = None - tolerance: 'typing.Optional[uint]' = None - scaledValue: 'typing.Union[None, Nullable, int]' = None - minScaledValue: 'typing.Union[None, Nullable, int]' = None - maxScaledValue: 'typing.Union[None, Nullable, int]' = None - scaledTolerance: 'typing.Optional[uint]' = None - scale: 'typing.Optional[int]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + measuredValue: typing.Union[Nullable, int] = NullValue + minMeasuredValue: typing.Union[Nullable, int] = NullValue + maxMeasuredValue: typing.Union[Nullable, int] = NullValue + tolerance: typing.Optional[uint] = None + scaledValue: typing.Union[None, Nullable, int] = None + minScaledValue: typing.Union[None, Nullable, int] = None + maxScaledValue: typing.Union[None, Nullable, int] = None + scaledTolerance: typing.Optional[uint] = None + scale: typing.Optional[int] = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Bitmaps: class Feature(IntFlag): @@ -36709,7 +36710,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, int]) - value: 'typing.Union[Nullable, int]' = NullValue + value: typing.Union[Nullable, int] = NullValue @dataclass class MinMeasuredValue(ClusterAttributeDescriptor): @@ -36725,7 +36726,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, int]) - value: 'typing.Union[Nullable, int]' = NullValue + value: typing.Union[Nullable, int] = NullValue @dataclass class MaxMeasuredValue(ClusterAttributeDescriptor): @@ -36741,7 +36742,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, int]) - value: 'typing.Union[Nullable, int]' = NullValue + value: typing.Union[Nullable, int] = NullValue @dataclass class Tolerance(ClusterAttributeDescriptor): @@ -36757,7 +36758,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class ScaledValue(ClusterAttributeDescriptor): @@ -36773,7 +36774,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, int]) - value: 'typing.Union[None, Nullable, int]' = None + value: typing.Union[None, Nullable, int] = None @dataclass class MinScaledValue(ClusterAttributeDescriptor): @@ -36789,7 +36790,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, int]) - value: 'typing.Union[None, Nullable, int]' = None + value: typing.Union[None, Nullable, int] = None @dataclass class MaxScaledValue(ClusterAttributeDescriptor): @@ -36805,7 +36806,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, int]) - value: 'typing.Union[None, Nullable, int]' = None + value: typing.Union[None, Nullable, int] = None @dataclass class ScaledTolerance(ClusterAttributeDescriptor): @@ -36821,7 +36822,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class Scale(ClusterAttributeDescriptor): @@ -36837,7 +36838,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[int]) - value: 'typing.Optional[int]' = None + value: typing.Optional[int] = None @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -36853,7 +36854,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -36869,7 +36870,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -36885,7 +36886,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -36901,7 +36902,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -36917,7 +36918,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -36933,7 +36934,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -36956,16 +36957,16 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - measuredValue: 'typing.Union[Nullable, uint]' = None - minMeasuredValue: 'typing.Union[Nullable, uint]' = None - maxMeasuredValue: 'typing.Union[Nullable, uint]' = None - tolerance: 'typing.Optional[uint]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + measuredValue: typing.Union[Nullable, uint] = NullValue + minMeasuredValue: typing.Union[Nullable, uint] = NullValue + maxMeasuredValue: typing.Union[Nullable, uint] = NullValue + tolerance: typing.Optional[uint] = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Attributes: @dataclass @@ -36982,7 +36983,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, uint]) - value: 'typing.Union[Nullable, uint]' = NullValue + value: typing.Union[Nullable, uint] = NullValue @dataclass class MinMeasuredValue(ClusterAttributeDescriptor): @@ -36998,7 +36999,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, uint]) - value: 'typing.Union[Nullable, uint]' = NullValue + value: typing.Union[Nullable, uint] = NullValue @dataclass class MaxMeasuredValue(ClusterAttributeDescriptor): @@ -37014,7 +37015,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, uint]) - value: 'typing.Union[Nullable, uint]' = NullValue + value: typing.Union[Nullable, uint] = NullValue @dataclass class Tolerance(ClusterAttributeDescriptor): @@ -37030,7 +37031,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -37046,7 +37047,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -37062,7 +37063,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -37078,7 +37079,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -37094,7 +37095,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -37110,7 +37111,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -37126,7 +37127,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -37149,16 +37150,16 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - measuredValue: 'typing.Union[Nullable, uint]' = None - minMeasuredValue: 'typing.Union[Nullable, uint]' = None - maxMeasuredValue: 'typing.Union[Nullable, uint]' = None - tolerance: 'typing.Optional[uint]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + measuredValue: typing.Union[Nullable, uint] = NullValue + minMeasuredValue: typing.Union[Nullable, uint] = NullValue + maxMeasuredValue: typing.Union[Nullable, uint] = NullValue + tolerance: typing.Optional[uint] = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Attributes: @dataclass @@ -37175,7 +37176,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, uint]) - value: 'typing.Union[Nullable, uint]' = NullValue + value: typing.Union[Nullable, uint] = NullValue @dataclass class MinMeasuredValue(ClusterAttributeDescriptor): @@ -37191,7 +37192,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, uint]) - value: 'typing.Union[Nullable, uint]' = NullValue + value: typing.Union[Nullable, uint] = NullValue @dataclass class MaxMeasuredValue(ClusterAttributeDescriptor): @@ -37207,7 +37208,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, uint]) - value: 'typing.Union[Nullable, uint]' = NullValue + value: typing.Union[Nullable, uint] = NullValue @dataclass class Tolerance(ClusterAttributeDescriptor): @@ -37223,7 +37224,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -37239,7 +37240,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -37255,7 +37256,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -37271,7 +37272,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -37287,7 +37288,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -37303,7 +37304,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -37319,7 +37320,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -37352,26 +37353,26 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - occupancy: 'uint' = None - occupancySensorType: 'OccupancySensing.Enums.OccupancySensorTypeEnum' = None - occupancySensorTypeBitmap: 'uint' = None - holdTime: 'typing.Optional[uint]' = None - holdTimeLimits: 'typing.Optional[OccupancySensing.Structs.HoldTimeLimitsStruct]' = None - PIROccupiedToUnoccupiedDelay: 'typing.Optional[uint]' = None - PIRUnoccupiedToOccupiedDelay: 'typing.Optional[uint]' = None - PIRUnoccupiedToOccupiedThreshold: 'typing.Optional[uint]' = None - ultrasonicOccupiedToUnoccupiedDelay: 'typing.Optional[uint]' = None - ultrasonicUnoccupiedToOccupiedDelay: 'typing.Optional[uint]' = None - ultrasonicUnoccupiedToOccupiedThreshold: 'typing.Optional[uint]' = None - physicalContactOccupiedToUnoccupiedDelay: 'typing.Optional[uint]' = None - physicalContactUnoccupiedToOccupiedDelay: 'typing.Optional[uint]' = None - physicalContactUnoccupiedToOccupiedThreshold: 'typing.Optional[uint]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + occupancy: uint = 0 + occupancySensorType: OccupancySensing.Enums.OccupancySensorTypeEnum = 0 + occupancySensorTypeBitmap: uint = 0 + holdTime: typing.Optional[uint] = None + holdTimeLimits: typing.Optional[OccupancySensing.Structs.HoldTimeLimitsStruct] = None + PIROccupiedToUnoccupiedDelay: typing.Optional[uint] = None + PIRUnoccupiedToOccupiedDelay: typing.Optional[uint] = None + PIRUnoccupiedToOccupiedThreshold: typing.Optional[uint] = None + ultrasonicOccupiedToUnoccupiedDelay: typing.Optional[uint] = None + ultrasonicUnoccupiedToOccupiedDelay: typing.Optional[uint] = None + ultrasonicUnoccupiedToOccupiedThreshold: typing.Optional[uint] = None + physicalContactOccupiedToUnoccupiedDelay: typing.Optional[uint] = None + physicalContactUnoccupiedToOccupiedDelay: typing.Optional[uint] = None + physicalContactUnoccupiedToOccupiedThreshold: typing.Optional[uint] = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class OccupancySensorTypeEnum(MatterIntEnum): @@ -37435,7 +37436,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class OccupancySensorType(ClusterAttributeDescriptor): @@ -37451,7 +37452,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=OccupancySensing.Enums.OccupancySensorTypeEnum) - value: 'OccupancySensing.Enums.OccupancySensorTypeEnum' = 0 + value: OccupancySensing.Enums.OccupancySensorTypeEnum = 0 @dataclass class OccupancySensorTypeBitmap(ClusterAttributeDescriptor): @@ -37467,7 +37468,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class HoldTime(ClusterAttributeDescriptor): @@ -37483,7 +37484,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class HoldTimeLimits(ClusterAttributeDescriptor): @@ -37499,7 +37500,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[OccupancySensing.Structs.HoldTimeLimitsStruct]) - value: 'typing.Optional[OccupancySensing.Structs.HoldTimeLimitsStruct]' = None + value: typing.Optional[OccupancySensing.Structs.HoldTimeLimitsStruct] = None @dataclass class PIROccupiedToUnoccupiedDelay(ClusterAttributeDescriptor): @@ -37515,7 +37516,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class PIRUnoccupiedToOccupiedDelay(ClusterAttributeDescriptor): @@ -37531,7 +37532,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class PIRUnoccupiedToOccupiedThreshold(ClusterAttributeDescriptor): @@ -37547,7 +37548,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class UltrasonicOccupiedToUnoccupiedDelay(ClusterAttributeDescriptor): @@ -37563,7 +37564,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class UltrasonicUnoccupiedToOccupiedDelay(ClusterAttributeDescriptor): @@ -37579,7 +37580,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class UltrasonicUnoccupiedToOccupiedThreshold(ClusterAttributeDescriptor): @@ -37595,7 +37596,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class PhysicalContactOccupiedToUnoccupiedDelay(ClusterAttributeDescriptor): @@ -37611,7 +37612,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class PhysicalContactUnoccupiedToOccupiedDelay(ClusterAttributeDescriptor): @@ -37627,7 +37628,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class PhysicalContactUnoccupiedToOccupiedThreshold(ClusterAttributeDescriptor): @@ -37643,7 +37644,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -37659,7 +37660,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -37675,7 +37676,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -37691,7 +37692,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -37707,7 +37708,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -37723,7 +37724,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -37739,7 +37740,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 class Events: @dataclass @@ -37759,7 +37760,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="occupancy", Tag=0, Type=uint), ]) - occupancy: 'uint' = 0 + occupancy: uint = 0 @dataclass @@ -37789,23 +37790,23 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - measuredValue: 'typing.Union[None, Nullable, float32]' = None - minMeasuredValue: 'typing.Union[None, Nullable, float32]' = None - maxMeasuredValue: 'typing.Union[None, Nullable, float32]' = None - peakMeasuredValue: 'typing.Union[None, Nullable, float32]' = None - peakMeasuredValueWindow: 'typing.Optional[uint]' = None - averageMeasuredValue: 'typing.Union[None, Nullable, float32]' = None - averageMeasuredValueWindow: 'typing.Optional[uint]' = None - uncertainty: 'typing.Optional[float32]' = None - measurementUnit: 'typing.Optional[CarbonMonoxideConcentrationMeasurement.Enums.MeasurementUnitEnum]' = None - measurementMedium: 'typing.Optional[CarbonMonoxideConcentrationMeasurement.Enums.MeasurementMediumEnum]' = None - levelValue: 'typing.Optional[CarbonMonoxideConcentrationMeasurement.Enums.LevelValueEnum]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + measuredValue: typing.Union[None, Nullable, float32] = None + minMeasuredValue: typing.Union[None, Nullable, float32] = None + maxMeasuredValue: typing.Union[None, Nullable, float32] = None + peakMeasuredValue: typing.Union[None, Nullable, float32] = None + peakMeasuredValueWindow: typing.Optional[uint] = None + averageMeasuredValue: typing.Union[None, Nullable, float32] = None + averageMeasuredValueWindow: typing.Optional[uint] = None + uncertainty: typing.Optional[float32] = None + measurementUnit: typing.Optional[CarbonMonoxideConcentrationMeasurement.Enums.MeasurementUnitEnum] = None + measurementMedium: typing.Optional[CarbonMonoxideConcentrationMeasurement.Enums.MeasurementMediumEnum] = None + levelValue: typing.Optional[CarbonMonoxideConcentrationMeasurement.Enums.LevelValueEnum] = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class LevelValueEnum(MatterIntEnum): @@ -37869,7 +37870,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, float32]) - value: 'typing.Union[None, Nullable, float32]' = None + value: typing.Union[None, Nullable, float32] = None @dataclass class MinMeasuredValue(ClusterAttributeDescriptor): @@ -37885,7 +37886,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, float32]) - value: 'typing.Union[None, Nullable, float32]' = None + value: typing.Union[None, Nullable, float32] = None @dataclass class MaxMeasuredValue(ClusterAttributeDescriptor): @@ -37901,7 +37902,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, float32]) - value: 'typing.Union[None, Nullable, float32]' = None + value: typing.Union[None, Nullable, float32] = None @dataclass class PeakMeasuredValue(ClusterAttributeDescriptor): @@ -37917,7 +37918,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, float32]) - value: 'typing.Union[None, Nullable, float32]' = None + value: typing.Union[None, Nullable, float32] = None @dataclass class PeakMeasuredValueWindow(ClusterAttributeDescriptor): @@ -37933,7 +37934,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class AverageMeasuredValue(ClusterAttributeDescriptor): @@ -37949,7 +37950,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, float32]) - value: 'typing.Union[None, Nullable, float32]' = None + value: typing.Union[None, Nullable, float32] = None @dataclass class AverageMeasuredValueWindow(ClusterAttributeDescriptor): @@ -37965,7 +37966,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class Uncertainty(ClusterAttributeDescriptor): @@ -37981,7 +37982,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[float32]) - value: 'typing.Optional[float32]' = None + value: typing.Optional[float32] = None @dataclass class MeasurementUnit(ClusterAttributeDescriptor): @@ -37997,7 +37998,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[CarbonMonoxideConcentrationMeasurement.Enums.MeasurementUnitEnum]) - value: 'typing.Optional[CarbonMonoxideConcentrationMeasurement.Enums.MeasurementUnitEnum]' = None + value: typing.Optional[CarbonMonoxideConcentrationMeasurement.Enums.MeasurementUnitEnum] = None @dataclass class MeasurementMedium(ClusterAttributeDescriptor): @@ -38013,7 +38014,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[CarbonMonoxideConcentrationMeasurement.Enums.MeasurementMediumEnum]) - value: 'typing.Optional[CarbonMonoxideConcentrationMeasurement.Enums.MeasurementMediumEnum]' = None + value: typing.Optional[CarbonMonoxideConcentrationMeasurement.Enums.MeasurementMediumEnum] = None @dataclass class LevelValue(ClusterAttributeDescriptor): @@ -38029,7 +38030,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[CarbonMonoxideConcentrationMeasurement.Enums.LevelValueEnum]) - value: 'typing.Optional[CarbonMonoxideConcentrationMeasurement.Enums.LevelValueEnum]' = None + value: typing.Optional[CarbonMonoxideConcentrationMeasurement.Enums.LevelValueEnum] = None @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -38045,7 +38046,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -38061,7 +38062,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -38077,7 +38078,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -38093,7 +38094,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -38109,7 +38110,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -38125,7 +38126,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -38155,23 +38156,23 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - measuredValue: 'typing.Union[None, Nullable, float32]' = None - minMeasuredValue: 'typing.Union[None, Nullable, float32]' = None - maxMeasuredValue: 'typing.Union[None, Nullable, float32]' = None - peakMeasuredValue: 'typing.Union[None, Nullable, float32]' = None - peakMeasuredValueWindow: 'typing.Optional[uint]' = None - averageMeasuredValue: 'typing.Union[None, Nullable, float32]' = None - averageMeasuredValueWindow: 'typing.Optional[uint]' = None - uncertainty: 'typing.Optional[float32]' = None - measurementUnit: 'typing.Optional[CarbonDioxideConcentrationMeasurement.Enums.MeasurementUnitEnum]' = None - measurementMedium: 'typing.Optional[CarbonDioxideConcentrationMeasurement.Enums.MeasurementMediumEnum]' = None - levelValue: 'typing.Optional[CarbonDioxideConcentrationMeasurement.Enums.LevelValueEnum]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + measuredValue: typing.Union[None, Nullable, float32] = None + minMeasuredValue: typing.Union[None, Nullable, float32] = None + maxMeasuredValue: typing.Union[None, Nullable, float32] = None + peakMeasuredValue: typing.Union[None, Nullable, float32] = None + peakMeasuredValueWindow: typing.Optional[uint] = None + averageMeasuredValue: typing.Union[None, Nullable, float32] = None + averageMeasuredValueWindow: typing.Optional[uint] = None + uncertainty: typing.Optional[float32] = None + measurementUnit: typing.Optional[CarbonDioxideConcentrationMeasurement.Enums.MeasurementUnitEnum] = None + measurementMedium: typing.Optional[CarbonDioxideConcentrationMeasurement.Enums.MeasurementMediumEnum] = None + levelValue: typing.Optional[CarbonDioxideConcentrationMeasurement.Enums.LevelValueEnum] = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class LevelValueEnum(MatterIntEnum): @@ -38235,7 +38236,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, float32]) - value: 'typing.Union[None, Nullable, float32]' = None + value: typing.Union[None, Nullable, float32] = None @dataclass class MinMeasuredValue(ClusterAttributeDescriptor): @@ -38251,7 +38252,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, float32]) - value: 'typing.Union[None, Nullable, float32]' = None + value: typing.Union[None, Nullable, float32] = None @dataclass class MaxMeasuredValue(ClusterAttributeDescriptor): @@ -38267,7 +38268,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, float32]) - value: 'typing.Union[None, Nullable, float32]' = None + value: typing.Union[None, Nullable, float32] = None @dataclass class PeakMeasuredValue(ClusterAttributeDescriptor): @@ -38283,7 +38284,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, float32]) - value: 'typing.Union[None, Nullable, float32]' = None + value: typing.Union[None, Nullable, float32] = None @dataclass class PeakMeasuredValueWindow(ClusterAttributeDescriptor): @@ -38299,7 +38300,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class AverageMeasuredValue(ClusterAttributeDescriptor): @@ -38315,7 +38316,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, float32]) - value: 'typing.Union[None, Nullable, float32]' = None + value: typing.Union[None, Nullable, float32] = None @dataclass class AverageMeasuredValueWindow(ClusterAttributeDescriptor): @@ -38331,7 +38332,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class Uncertainty(ClusterAttributeDescriptor): @@ -38347,7 +38348,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[float32]) - value: 'typing.Optional[float32]' = None + value: typing.Optional[float32] = None @dataclass class MeasurementUnit(ClusterAttributeDescriptor): @@ -38363,7 +38364,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[CarbonDioxideConcentrationMeasurement.Enums.MeasurementUnitEnum]) - value: 'typing.Optional[CarbonDioxideConcentrationMeasurement.Enums.MeasurementUnitEnum]' = None + value: typing.Optional[CarbonDioxideConcentrationMeasurement.Enums.MeasurementUnitEnum] = None @dataclass class MeasurementMedium(ClusterAttributeDescriptor): @@ -38379,7 +38380,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[CarbonDioxideConcentrationMeasurement.Enums.MeasurementMediumEnum]) - value: 'typing.Optional[CarbonDioxideConcentrationMeasurement.Enums.MeasurementMediumEnum]' = None + value: typing.Optional[CarbonDioxideConcentrationMeasurement.Enums.MeasurementMediumEnum] = None @dataclass class LevelValue(ClusterAttributeDescriptor): @@ -38395,7 +38396,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[CarbonDioxideConcentrationMeasurement.Enums.LevelValueEnum]) - value: 'typing.Optional[CarbonDioxideConcentrationMeasurement.Enums.LevelValueEnum]' = None + value: typing.Optional[CarbonDioxideConcentrationMeasurement.Enums.LevelValueEnum] = None @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -38411,7 +38412,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -38427,7 +38428,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -38443,7 +38444,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -38459,7 +38460,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -38475,7 +38476,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -38491,7 +38492,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -38521,23 +38522,23 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - measuredValue: 'typing.Union[None, Nullable, float32]' = None - minMeasuredValue: 'typing.Union[None, Nullable, float32]' = None - maxMeasuredValue: 'typing.Union[None, Nullable, float32]' = None - peakMeasuredValue: 'typing.Union[None, Nullable, float32]' = None - peakMeasuredValueWindow: 'typing.Optional[uint]' = None - averageMeasuredValue: 'typing.Union[None, Nullable, float32]' = None - averageMeasuredValueWindow: 'typing.Optional[uint]' = None - uncertainty: 'typing.Optional[float32]' = None - measurementUnit: 'typing.Optional[NitrogenDioxideConcentrationMeasurement.Enums.MeasurementUnitEnum]' = None - measurementMedium: 'typing.Optional[NitrogenDioxideConcentrationMeasurement.Enums.MeasurementMediumEnum]' = None - levelValue: 'typing.Optional[NitrogenDioxideConcentrationMeasurement.Enums.LevelValueEnum]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + measuredValue: typing.Union[None, Nullable, float32] = None + minMeasuredValue: typing.Union[None, Nullable, float32] = None + maxMeasuredValue: typing.Union[None, Nullable, float32] = None + peakMeasuredValue: typing.Union[None, Nullable, float32] = None + peakMeasuredValueWindow: typing.Optional[uint] = None + averageMeasuredValue: typing.Union[None, Nullable, float32] = None + averageMeasuredValueWindow: typing.Optional[uint] = None + uncertainty: typing.Optional[float32] = None + measurementUnit: typing.Optional[NitrogenDioxideConcentrationMeasurement.Enums.MeasurementUnitEnum] = None + measurementMedium: typing.Optional[NitrogenDioxideConcentrationMeasurement.Enums.MeasurementMediumEnum] = None + levelValue: typing.Optional[NitrogenDioxideConcentrationMeasurement.Enums.LevelValueEnum] = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class LevelValueEnum(MatterIntEnum): @@ -38601,7 +38602,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, float32]) - value: 'typing.Union[None, Nullable, float32]' = None + value: typing.Union[None, Nullable, float32] = None @dataclass class MinMeasuredValue(ClusterAttributeDescriptor): @@ -38617,7 +38618,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, float32]) - value: 'typing.Union[None, Nullable, float32]' = None + value: typing.Union[None, Nullable, float32] = None @dataclass class MaxMeasuredValue(ClusterAttributeDescriptor): @@ -38633,7 +38634,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, float32]) - value: 'typing.Union[None, Nullable, float32]' = None + value: typing.Union[None, Nullable, float32] = None @dataclass class PeakMeasuredValue(ClusterAttributeDescriptor): @@ -38649,7 +38650,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, float32]) - value: 'typing.Union[None, Nullable, float32]' = None + value: typing.Union[None, Nullable, float32] = None @dataclass class PeakMeasuredValueWindow(ClusterAttributeDescriptor): @@ -38665,7 +38666,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class AverageMeasuredValue(ClusterAttributeDescriptor): @@ -38681,7 +38682,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, float32]) - value: 'typing.Union[None, Nullable, float32]' = None + value: typing.Union[None, Nullable, float32] = None @dataclass class AverageMeasuredValueWindow(ClusterAttributeDescriptor): @@ -38697,7 +38698,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class Uncertainty(ClusterAttributeDescriptor): @@ -38713,7 +38714,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[float32]) - value: 'typing.Optional[float32]' = None + value: typing.Optional[float32] = None @dataclass class MeasurementUnit(ClusterAttributeDescriptor): @@ -38729,7 +38730,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[NitrogenDioxideConcentrationMeasurement.Enums.MeasurementUnitEnum]) - value: 'typing.Optional[NitrogenDioxideConcentrationMeasurement.Enums.MeasurementUnitEnum]' = None + value: typing.Optional[NitrogenDioxideConcentrationMeasurement.Enums.MeasurementUnitEnum] = None @dataclass class MeasurementMedium(ClusterAttributeDescriptor): @@ -38745,7 +38746,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[NitrogenDioxideConcentrationMeasurement.Enums.MeasurementMediumEnum]) - value: 'typing.Optional[NitrogenDioxideConcentrationMeasurement.Enums.MeasurementMediumEnum]' = None + value: typing.Optional[NitrogenDioxideConcentrationMeasurement.Enums.MeasurementMediumEnum] = None @dataclass class LevelValue(ClusterAttributeDescriptor): @@ -38761,7 +38762,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[NitrogenDioxideConcentrationMeasurement.Enums.LevelValueEnum]) - value: 'typing.Optional[NitrogenDioxideConcentrationMeasurement.Enums.LevelValueEnum]' = None + value: typing.Optional[NitrogenDioxideConcentrationMeasurement.Enums.LevelValueEnum] = None @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -38777,7 +38778,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -38793,7 +38794,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -38809,7 +38810,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -38825,7 +38826,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -38841,7 +38842,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -38857,7 +38858,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -38887,23 +38888,23 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - measuredValue: 'typing.Union[None, Nullable, float32]' = None - minMeasuredValue: 'typing.Union[None, Nullable, float32]' = None - maxMeasuredValue: 'typing.Union[None, Nullable, float32]' = None - peakMeasuredValue: 'typing.Union[None, Nullable, float32]' = None - peakMeasuredValueWindow: 'typing.Optional[uint]' = None - averageMeasuredValue: 'typing.Union[None, Nullable, float32]' = None - averageMeasuredValueWindow: 'typing.Optional[uint]' = None - uncertainty: 'typing.Optional[float32]' = None - measurementUnit: 'typing.Optional[OzoneConcentrationMeasurement.Enums.MeasurementUnitEnum]' = None - measurementMedium: 'typing.Optional[OzoneConcentrationMeasurement.Enums.MeasurementMediumEnum]' = None - levelValue: 'typing.Optional[OzoneConcentrationMeasurement.Enums.LevelValueEnum]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + measuredValue: typing.Union[None, Nullable, float32] = None + minMeasuredValue: typing.Union[None, Nullable, float32] = None + maxMeasuredValue: typing.Union[None, Nullable, float32] = None + peakMeasuredValue: typing.Union[None, Nullable, float32] = None + peakMeasuredValueWindow: typing.Optional[uint] = None + averageMeasuredValue: typing.Union[None, Nullable, float32] = None + averageMeasuredValueWindow: typing.Optional[uint] = None + uncertainty: typing.Optional[float32] = None + measurementUnit: typing.Optional[OzoneConcentrationMeasurement.Enums.MeasurementUnitEnum] = None + measurementMedium: typing.Optional[OzoneConcentrationMeasurement.Enums.MeasurementMediumEnum] = None + levelValue: typing.Optional[OzoneConcentrationMeasurement.Enums.LevelValueEnum] = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class LevelValueEnum(MatterIntEnum): @@ -38967,7 +38968,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, float32]) - value: 'typing.Union[None, Nullable, float32]' = None + value: typing.Union[None, Nullable, float32] = None @dataclass class MinMeasuredValue(ClusterAttributeDescriptor): @@ -38983,7 +38984,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, float32]) - value: 'typing.Union[None, Nullable, float32]' = None + value: typing.Union[None, Nullable, float32] = None @dataclass class MaxMeasuredValue(ClusterAttributeDescriptor): @@ -38999,7 +39000,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, float32]) - value: 'typing.Union[None, Nullable, float32]' = None + value: typing.Union[None, Nullable, float32] = None @dataclass class PeakMeasuredValue(ClusterAttributeDescriptor): @@ -39015,7 +39016,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, float32]) - value: 'typing.Union[None, Nullable, float32]' = None + value: typing.Union[None, Nullable, float32] = None @dataclass class PeakMeasuredValueWindow(ClusterAttributeDescriptor): @@ -39031,7 +39032,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class AverageMeasuredValue(ClusterAttributeDescriptor): @@ -39047,7 +39048,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, float32]) - value: 'typing.Union[None, Nullable, float32]' = None + value: typing.Union[None, Nullable, float32] = None @dataclass class AverageMeasuredValueWindow(ClusterAttributeDescriptor): @@ -39063,7 +39064,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class Uncertainty(ClusterAttributeDescriptor): @@ -39079,7 +39080,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[float32]) - value: 'typing.Optional[float32]' = None + value: typing.Optional[float32] = None @dataclass class MeasurementUnit(ClusterAttributeDescriptor): @@ -39095,7 +39096,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[OzoneConcentrationMeasurement.Enums.MeasurementUnitEnum]) - value: 'typing.Optional[OzoneConcentrationMeasurement.Enums.MeasurementUnitEnum]' = None + value: typing.Optional[OzoneConcentrationMeasurement.Enums.MeasurementUnitEnum] = None @dataclass class MeasurementMedium(ClusterAttributeDescriptor): @@ -39111,7 +39112,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[OzoneConcentrationMeasurement.Enums.MeasurementMediumEnum]) - value: 'typing.Optional[OzoneConcentrationMeasurement.Enums.MeasurementMediumEnum]' = None + value: typing.Optional[OzoneConcentrationMeasurement.Enums.MeasurementMediumEnum] = None @dataclass class LevelValue(ClusterAttributeDescriptor): @@ -39127,7 +39128,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[OzoneConcentrationMeasurement.Enums.LevelValueEnum]) - value: 'typing.Optional[OzoneConcentrationMeasurement.Enums.LevelValueEnum]' = None + value: typing.Optional[OzoneConcentrationMeasurement.Enums.LevelValueEnum] = None @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -39143,7 +39144,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -39159,7 +39160,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -39175,7 +39176,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -39191,7 +39192,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -39207,7 +39208,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -39223,7 +39224,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -39253,23 +39254,23 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - measuredValue: 'typing.Union[None, Nullable, float32]' = None - minMeasuredValue: 'typing.Union[None, Nullable, float32]' = None - maxMeasuredValue: 'typing.Union[None, Nullable, float32]' = None - peakMeasuredValue: 'typing.Union[None, Nullable, float32]' = None - peakMeasuredValueWindow: 'typing.Optional[uint]' = None - averageMeasuredValue: 'typing.Union[None, Nullable, float32]' = None - averageMeasuredValueWindow: 'typing.Optional[uint]' = None - uncertainty: 'typing.Optional[float32]' = None - measurementUnit: 'typing.Optional[Pm25ConcentrationMeasurement.Enums.MeasurementUnitEnum]' = None - measurementMedium: 'typing.Optional[Pm25ConcentrationMeasurement.Enums.MeasurementMediumEnum]' = None - levelValue: 'typing.Optional[Pm25ConcentrationMeasurement.Enums.LevelValueEnum]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + measuredValue: typing.Union[None, Nullable, float32] = None + minMeasuredValue: typing.Union[None, Nullable, float32] = None + maxMeasuredValue: typing.Union[None, Nullable, float32] = None + peakMeasuredValue: typing.Union[None, Nullable, float32] = None + peakMeasuredValueWindow: typing.Optional[uint] = None + averageMeasuredValue: typing.Union[None, Nullable, float32] = None + averageMeasuredValueWindow: typing.Optional[uint] = None + uncertainty: typing.Optional[float32] = None + measurementUnit: typing.Optional[Pm25ConcentrationMeasurement.Enums.MeasurementUnitEnum] = None + measurementMedium: typing.Optional[Pm25ConcentrationMeasurement.Enums.MeasurementMediumEnum] = None + levelValue: typing.Optional[Pm25ConcentrationMeasurement.Enums.LevelValueEnum] = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class LevelValueEnum(MatterIntEnum): @@ -39333,7 +39334,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, float32]) - value: 'typing.Union[None, Nullable, float32]' = None + value: typing.Union[None, Nullable, float32] = None @dataclass class MinMeasuredValue(ClusterAttributeDescriptor): @@ -39349,7 +39350,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, float32]) - value: 'typing.Union[None, Nullable, float32]' = None + value: typing.Union[None, Nullable, float32] = None @dataclass class MaxMeasuredValue(ClusterAttributeDescriptor): @@ -39365,7 +39366,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, float32]) - value: 'typing.Union[None, Nullable, float32]' = None + value: typing.Union[None, Nullable, float32] = None @dataclass class PeakMeasuredValue(ClusterAttributeDescriptor): @@ -39381,7 +39382,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, float32]) - value: 'typing.Union[None, Nullable, float32]' = None + value: typing.Union[None, Nullable, float32] = None @dataclass class PeakMeasuredValueWindow(ClusterAttributeDescriptor): @@ -39397,7 +39398,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class AverageMeasuredValue(ClusterAttributeDescriptor): @@ -39413,7 +39414,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, float32]) - value: 'typing.Union[None, Nullable, float32]' = None + value: typing.Union[None, Nullable, float32] = None @dataclass class AverageMeasuredValueWindow(ClusterAttributeDescriptor): @@ -39429,7 +39430,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class Uncertainty(ClusterAttributeDescriptor): @@ -39445,7 +39446,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[float32]) - value: 'typing.Optional[float32]' = None + value: typing.Optional[float32] = None @dataclass class MeasurementUnit(ClusterAttributeDescriptor): @@ -39461,7 +39462,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[Pm25ConcentrationMeasurement.Enums.MeasurementUnitEnum]) - value: 'typing.Optional[Pm25ConcentrationMeasurement.Enums.MeasurementUnitEnum]' = None + value: typing.Optional[Pm25ConcentrationMeasurement.Enums.MeasurementUnitEnum] = None @dataclass class MeasurementMedium(ClusterAttributeDescriptor): @@ -39477,7 +39478,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[Pm25ConcentrationMeasurement.Enums.MeasurementMediumEnum]) - value: 'typing.Optional[Pm25ConcentrationMeasurement.Enums.MeasurementMediumEnum]' = None + value: typing.Optional[Pm25ConcentrationMeasurement.Enums.MeasurementMediumEnum] = None @dataclass class LevelValue(ClusterAttributeDescriptor): @@ -39493,7 +39494,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[Pm25ConcentrationMeasurement.Enums.LevelValueEnum]) - value: 'typing.Optional[Pm25ConcentrationMeasurement.Enums.LevelValueEnum]' = None + value: typing.Optional[Pm25ConcentrationMeasurement.Enums.LevelValueEnum] = None @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -39509,7 +39510,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -39525,7 +39526,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -39541,7 +39542,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -39557,7 +39558,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -39573,7 +39574,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -39589,7 +39590,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -39619,23 +39620,23 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - measuredValue: 'typing.Union[None, Nullable, float32]' = None - minMeasuredValue: 'typing.Union[None, Nullable, float32]' = None - maxMeasuredValue: 'typing.Union[None, Nullable, float32]' = None - peakMeasuredValue: 'typing.Union[None, Nullable, float32]' = None - peakMeasuredValueWindow: 'typing.Optional[uint]' = None - averageMeasuredValue: 'typing.Union[None, Nullable, float32]' = None - averageMeasuredValueWindow: 'typing.Optional[uint]' = None - uncertainty: 'typing.Optional[float32]' = None - measurementUnit: 'typing.Optional[FormaldehydeConcentrationMeasurement.Enums.MeasurementUnitEnum]' = None - measurementMedium: 'typing.Optional[FormaldehydeConcentrationMeasurement.Enums.MeasurementMediumEnum]' = None - levelValue: 'typing.Optional[FormaldehydeConcentrationMeasurement.Enums.LevelValueEnum]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + measuredValue: typing.Union[None, Nullable, float32] = None + minMeasuredValue: typing.Union[None, Nullable, float32] = None + maxMeasuredValue: typing.Union[None, Nullable, float32] = None + peakMeasuredValue: typing.Union[None, Nullable, float32] = None + peakMeasuredValueWindow: typing.Optional[uint] = None + averageMeasuredValue: typing.Union[None, Nullable, float32] = None + averageMeasuredValueWindow: typing.Optional[uint] = None + uncertainty: typing.Optional[float32] = None + measurementUnit: typing.Optional[FormaldehydeConcentrationMeasurement.Enums.MeasurementUnitEnum] = None + measurementMedium: typing.Optional[FormaldehydeConcentrationMeasurement.Enums.MeasurementMediumEnum] = None + levelValue: typing.Optional[FormaldehydeConcentrationMeasurement.Enums.LevelValueEnum] = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class LevelValueEnum(MatterIntEnum): @@ -39699,7 +39700,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, float32]) - value: 'typing.Union[None, Nullable, float32]' = None + value: typing.Union[None, Nullable, float32] = None @dataclass class MinMeasuredValue(ClusterAttributeDescriptor): @@ -39715,7 +39716,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, float32]) - value: 'typing.Union[None, Nullable, float32]' = None + value: typing.Union[None, Nullable, float32] = None @dataclass class MaxMeasuredValue(ClusterAttributeDescriptor): @@ -39731,7 +39732,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, float32]) - value: 'typing.Union[None, Nullable, float32]' = None + value: typing.Union[None, Nullable, float32] = None @dataclass class PeakMeasuredValue(ClusterAttributeDescriptor): @@ -39747,7 +39748,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, float32]) - value: 'typing.Union[None, Nullable, float32]' = None + value: typing.Union[None, Nullable, float32] = None @dataclass class PeakMeasuredValueWindow(ClusterAttributeDescriptor): @@ -39763,7 +39764,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class AverageMeasuredValue(ClusterAttributeDescriptor): @@ -39779,7 +39780,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, float32]) - value: 'typing.Union[None, Nullable, float32]' = None + value: typing.Union[None, Nullable, float32] = None @dataclass class AverageMeasuredValueWindow(ClusterAttributeDescriptor): @@ -39795,7 +39796,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class Uncertainty(ClusterAttributeDescriptor): @@ -39811,7 +39812,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[float32]) - value: 'typing.Optional[float32]' = None + value: typing.Optional[float32] = None @dataclass class MeasurementUnit(ClusterAttributeDescriptor): @@ -39827,7 +39828,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[FormaldehydeConcentrationMeasurement.Enums.MeasurementUnitEnum]) - value: 'typing.Optional[FormaldehydeConcentrationMeasurement.Enums.MeasurementUnitEnum]' = None + value: typing.Optional[FormaldehydeConcentrationMeasurement.Enums.MeasurementUnitEnum] = None @dataclass class MeasurementMedium(ClusterAttributeDescriptor): @@ -39843,7 +39844,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[FormaldehydeConcentrationMeasurement.Enums.MeasurementMediumEnum]) - value: 'typing.Optional[FormaldehydeConcentrationMeasurement.Enums.MeasurementMediumEnum]' = None + value: typing.Optional[FormaldehydeConcentrationMeasurement.Enums.MeasurementMediumEnum] = None @dataclass class LevelValue(ClusterAttributeDescriptor): @@ -39859,7 +39860,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[FormaldehydeConcentrationMeasurement.Enums.LevelValueEnum]) - value: 'typing.Optional[FormaldehydeConcentrationMeasurement.Enums.LevelValueEnum]' = None + value: typing.Optional[FormaldehydeConcentrationMeasurement.Enums.LevelValueEnum] = None @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -39875,7 +39876,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -39891,7 +39892,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -39907,7 +39908,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -39923,7 +39924,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -39939,7 +39940,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -39955,7 +39956,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -39985,23 +39986,23 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - measuredValue: 'typing.Union[None, Nullable, float32]' = None - minMeasuredValue: 'typing.Union[None, Nullable, float32]' = None - maxMeasuredValue: 'typing.Union[None, Nullable, float32]' = None - peakMeasuredValue: 'typing.Union[None, Nullable, float32]' = None - peakMeasuredValueWindow: 'typing.Optional[uint]' = None - averageMeasuredValue: 'typing.Union[None, Nullable, float32]' = None - averageMeasuredValueWindow: 'typing.Optional[uint]' = None - uncertainty: 'typing.Optional[float32]' = None - measurementUnit: 'typing.Optional[Pm1ConcentrationMeasurement.Enums.MeasurementUnitEnum]' = None - measurementMedium: 'typing.Optional[Pm1ConcentrationMeasurement.Enums.MeasurementMediumEnum]' = None - levelValue: 'typing.Optional[Pm1ConcentrationMeasurement.Enums.LevelValueEnum]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + measuredValue: typing.Union[None, Nullable, float32] = None + minMeasuredValue: typing.Union[None, Nullable, float32] = None + maxMeasuredValue: typing.Union[None, Nullable, float32] = None + peakMeasuredValue: typing.Union[None, Nullable, float32] = None + peakMeasuredValueWindow: typing.Optional[uint] = None + averageMeasuredValue: typing.Union[None, Nullable, float32] = None + averageMeasuredValueWindow: typing.Optional[uint] = None + uncertainty: typing.Optional[float32] = None + measurementUnit: typing.Optional[Pm1ConcentrationMeasurement.Enums.MeasurementUnitEnum] = None + measurementMedium: typing.Optional[Pm1ConcentrationMeasurement.Enums.MeasurementMediumEnum] = None + levelValue: typing.Optional[Pm1ConcentrationMeasurement.Enums.LevelValueEnum] = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class LevelValueEnum(MatterIntEnum): @@ -40065,7 +40066,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, float32]) - value: 'typing.Union[None, Nullable, float32]' = None + value: typing.Union[None, Nullable, float32] = None @dataclass class MinMeasuredValue(ClusterAttributeDescriptor): @@ -40081,7 +40082,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, float32]) - value: 'typing.Union[None, Nullable, float32]' = None + value: typing.Union[None, Nullable, float32] = None @dataclass class MaxMeasuredValue(ClusterAttributeDescriptor): @@ -40097,7 +40098,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, float32]) - value: 'typing.Union[None, Nullable, float32]' = None + value: typing.Union[None, Nullable, float32] = None @dataclass class PeakMeasuredValue(ClusterAttributeDescriptor): @@ -40113,7 +40114,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, float32]) - value: 'typing.Union[None, Nullable, float32]' = None + value: typing.Union[None, Nullable, float32] = None @dataclass class PeakMeasuredValueWindow(ClusterAttributeDescriptor): @@ -40129,7 +40130,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class AverageMeasuredValue(ClusterAttributeDescriptor): @@ -40145,7 +40146,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, float32]) - value: 'typing.Union[None, Nullable, float32]' = None + value: typing.Union[None, Nullable, float32] = None @dataclass class AverageMeasuredValueWindow(ClusterAttributeDescriptor): @@ -40161,7 +40162,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class Uncertainty(ClusterAttributeDescriptor): @@ -40177,7 +40178,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[float32]) - value: 'typing.Optional[float32]' = None + value: typing.Optional[float32] = None @dataclass class MeasurementUnit(ClusterAttributeDescriptor): @@ -40193,7 +40194,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[Pm1ConcentrationMeasurement.Enums.MeasurementUnitEnum]) - value: 'typing.Optional[Pm1ConcentrationMeasurement.Enums.MeasurementUnitEnum]' = None + value: typing.Optional[Pm1ConcentrationMeasurement.Enums.MeasurementUnitEnum] = None @dataclass class MeasurementMedium(ClusterAttributeDescriptor): @@ -40209,7 +40210,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[Pm1ConcentrationMeasurement.Enums.MeasurementMediumEnum]) - value: 'typing.Optional[Pm1ConcentrationMeasurement.Enums.MeasurementMediumEnum]' = None + value: typing.Optional[Pm1ConcentrationMeasurement.Enums.MeasurementMediumEnum] = None @dataclass class LevelValue(ClusterAttributeDescriptor): @@ -40225,7 +40226,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[Pm1ConcentrationMeasurement.Enums.LevelValueEnum]) - value: 'typing.Optional[Pm1ConcentrationMeasurement.Enums.LevelValueEnum]' = None + value: typing.Optional[Pm1ConcentrationMeasurement.Enums.LevelValueEnum] = None @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -40241,7 +40242,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -40257,7 +40258,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -40273,7 +40274,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -40289,7 +40290,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -40305,7 +40306,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -40321,7 +40322,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -40351,23 +40352,23 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - measuredValue: 'typing.Union[None, Nullable, float32]' = None - minMeasuredValue: 'typing.Union[None, Nullable, float32]' = None - maxMeasuredValue: 'typing.Union[None, Nullable, float32]' = None - peakMeasuredValue: 'typing.Union[None, Nullable, float32]' = None - peakMeasuredValueWindow: 'typing.Optional[uint]' = None - averageMeasuredValue: 'typing.Union[None, Nullable, float32]' = None - averageMeasuredValueWindow: 'typing.Optional[uint]' = None - uncertainty: 'typing.Optional[float32]' = None - measurementUnit: 'typing.Optional[Pm10ConcentrationMeasurement.Enums.MeasurementUnitEnum]' = None - measurementMedium: 'typing.Optional[Pm10ConcentrationMeasurement.Enums.MeasurementMediumEnum]' = None - levelValue: 'typing.Optional[Pm10ConcentrationMeasurement.Enums.LevelValueEnum]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + measuredValue: typing.Union[None, Nullable, float32] = None + minMeasuredValue: typing.Union[None, Nullable, float32] = None + maxMeasuredValue: typing.Union[None, Nullable, float32] = None + peakMeasuredValue: typing.Union[None, Nullable, float32] = None + peakMeasuredValueWindow: typing.Optional[uint] = None + averageMeasuredValue: typing.Union[None, Nullable, float32] = None + averageMeasuredValueWindow: typing.Optional[uint] = None + uncertainty: typing.Optional[float32] = None + measurementUnit: typing.Optional[Pm10ConcentrationMeasurement.Enums.MeasurementUnitEnum] = None + measurementMedium: typing.Optional[Pm10ConcentrationMeasurement.Enums.MeasurementMediumEnum] = None + levelValue: typing.Optional[Pm10ConcentrationMeasurement.Enums.LevelValueEnum] = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class LevelValueEnum(MatterIntEnum): @@ -40431,7 +40432,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, float32]) - value: 'typing.Union[None, Nullable, float32]' = None + value: typing.Union[None, Nullable, float32] = None @dataclass class MinMeasuredValue(ClusterAttributeDescriptor): @@ -40447,7 +40448,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, float32]) - value: 'typing.Union[None, Nullable, float32]' = None + value: typing.Union[None, Nullable, float32] = None @dataclass class MaxMeasuredValue(ClusterAttributeDescriptor): @@ -40463,7 +40464,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, float32]) - value: 'typing.Union[None, Nullable, float32]' = None + value: typing.Union[None, Nullable, float32] = None @dataclass class PeakMeasuredValue(ClusterAttributeDescriptor): @@ -40479,7 +40480,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, float32]) - value: 'typing.Union[None, Nullable, float32]' = None + value: typing.Union[None, Nullable, float32] = None @dataclass class PeakMeasuredValueWindow(ClusterAttributeDescriptor): @@ -40495,7 +40496,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class AverageMeasuredValue(ClusterAttributeDescriptor): @@ -40511,7 +40512,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, float32]) - value: 'typing.Union[None, Nullable, float32]' = None + value: typing.Union[None, Nullable, float32] = None @dataclass class AverageMeasuredValueWindow(ClusterAttributeDescriptor): @@ -40527,7 +40528,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class Uncertainty(ClusterAttributeDescriptor): @@ -40543,7 +40544,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[float32]) - value: 'typing.Optional[float32]' = None + value: typing.Optional[float32] = None @dataclass class MeasurementUnit(ClusterAttributeDescriptor): @@ -40559,7 +40560,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[Pm10ConcentrationMeasurement.Enums.MeasurementUnitEnum]) - value: 'typing.Optional[Pm10ConcentrationMeasurement.Enums.MeasurementUnitEnum]' = None + value: typing.Optional[Pm10ConcentrationMeasurement.Enums.MeasurementUnitEnum] = None @dataclass class MeasurementMedium(ClusterAttributeDescriptor): @@ -40575,7 +40576,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[Pm10ConcentrationMeasurement.Enums.MeasurementMediumEnum]) - value: 'typing.Optional[Pm10ConcentrationMeasurement.Enums.MeasurementMediumEnum]' = None + value: typing.Optional[Pm10ConcentrationMeasurement.Enums.MeasurementMediumEnum] = None @dataclass class LevelValue(ClusterAttributeDescriptor): @@ -40591,7 +40592,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[Pm10ConcentrationMeasurement.Enums.LevelValueEnum]) - value: 'typing.Optional[Pm10ConcentrationMeasurement.Enums.LevelValueEnum]' = None + value: typing.Optional[Pm10ConcentrationMeasurement.Enums.LevelValueEnum] = None @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -40607,7 +40608,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -40623,7 +40624,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -40639,7 +40640,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -40655,7 +40656,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -40671,7 +40672,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -40687,7 +40688,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -40717,23 +40718,23 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - measuredValue: 'typing.Union[None, Nullable, float32]' = None - minMeasuredValue: 'typing.Union[None, Nullable, float32]' = None - maxMeasuredValue: 'typing.Union[None, Nullable, float32]' = None - peakMeasuredValue: 'typing.Union[None, Nullable, float32]' = None - peakMeasuredValueWindow: 'typing.Optional[uint]' = None - averageMeasuredValue: 'typing.Union[None, Nullable, float32]' = None - averageMeasuredValueWindow: 'typing.Optional[uint]' = None - uncertainty: 'typing.Optional[float32]' = None - measurementUnit: 'typing.Optional[TotalVolatileOrganicCompoundsConcentrationMeasurement.Enums.MeasurementUnitEnum]' = None - measurementMedium: 'typing.Optional[TotalVolatileOrganicCompoundsConcentrationMeasurement.Enums.MeasurementMediumEnum]' = None - levelValue: 'typing.Optional[TotalVolatileOrganicCompoundsConcentrationMeasurement.Enums.LevelValueEnum]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + measuredValue: typing.Union[None, Nullable, float32] = None + minMeasuredValue: typing.Union[None, Nullable, float32] = None + maxMeasuredValue: typing.Union[None, Nullable, float32] = None + peakMeasuredValue: typing.Union[None, Nullable, float32] = None + peakMeasuredValueWindow: typing.Optional[uint] = None + averageMeasuredValue: typing.Union[None, Nullable, float32] = None + averageMeasuredValueWindow: typing.Optional[uint] = None + uncertainty: typing.Optional[float32] = None + measurementUnit: typing.Optional[TotalVolatileOrganicCompoundsConcentrationMeasurement.Enums.MeasurementUnitEnum] = None + measurementMedium: typing.Optional[TotalVolatileOrganicCompoundsConcentrationMeasurement.Enums.MeasurementMediumEnum] = None + levelValue: typing.Optional[TotalVolatileOrganicCompoundsConcentrationMeasurement.Enums.LevelValueEnum] = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class LevelValueEnum(MatterIntEnum): @@ -40797,7 +40798,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, float32]) - value: 'typing.Union[None, Nullable, float32]' = None + value: typing.Union[None, Nullable, float32] = None @dataclass class MinMeasuredValue(ClusterAttributeDescriptor): @@ -40813,7 +40814,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, float32]) - value: 'typing.Union[None, Nullable, float32]' = None + value: typing.Union[None, Nullable, float32] = None @dataclass class MaxMeasuredValue(ClusterAttributeDescriptor): @@ -40829,7 +40830,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, float32]) - value: 'typing.Union[None, Nullable, float32]' = None + value: typing.Union[None, Nullable, float32] = None @dataclass class PeakMeasuredValue(ClusterAttributeDescriptor): @@ -40845,7 +40846,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, float32]) - value: 'typing.Union[None, Nullable, float32]' = None + value: typing.Union[None, Nullable, float32] = None @dataclass class PeakMeasuredValueWindow(ClusterAttributeDescriptor): @@ -40861,7 +40862,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class AverageMeasuredValue(ClusterAttributeDescriptor): @@ -40877,7 +40878,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, float32]) - value: 'typing.Union[None, Nullable, float32]' = None + value: typing.Union[None, Nullable, float32] = None @dataclass class AverageMeasuredValueWindow(ClusterAttributeDescriptor): @@ -40893,7 +40894,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class Uncertainty(ClusterAttributeDescriptor): @@ -40909,7 +40910,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[float32]) - value: 'typing.Optional[float32]' = None + value: typing.Optional[float32] = None @dataclass class MeasurementUnit(ClusterAttributeDescriptor): @@ -40925,7 +40926,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[TotalVolatileOrganicCompoundsConcentrationMeasurement.Enums.MeasurementUnitEnum]) - value: 'typing.Optional[TotalVolatileOrganicCompoundsConcentrationMeasurement.Enums.MeasurementUnitEnum]' = None + value: typing.Optional[TotalVolatileOrganicCompoundsConcentrationMeasurement.Enums.MeasurementUnitEnum] = None @dataclass class MeasurementMedium(ClusterAttributeDescriptor): @@ -40941,7 +40942,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[TotalVolatileOrganicCompoundsConcentrationMeasurement.Enums.MeasurementMediumEnum]) - value: 'typing.Optional[TotalVolatileOrganicCompoundsConcentrationMeasurement.Enums.MeasurementMediumEnum]' = None + value: typing.Optional[TotalVolatileOrganicCompoundsConcentrationMeasurement.Enums.MeasurementMediumEnum] = None @dataclass class LevelValue(ClusterAttributeDescriptor): @@ -40957,7 +40958,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[TotalVolatileOrganicCompoundsConcentrationMeasurement.Enums.LevelValueEnum]) - value: 'typing.Optional[TotalVolatileOrganicCompoundsConcentrationMeasurement.Enums.LevelValueEnum]' = None + value: typing.Optional[TotalVolatileOrganicCompoundsConcentrationMeasurement.Enums.LevelValueEnum] = None @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -40973,7 +40974,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -40989,7 +40990,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -41005,7 +41006,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -41021,7 +41022,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -41037,7 +41038,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -41053,7 +41054,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -41083,23 +41084,23 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - measuredValue: 'typing.Union[None, Nullable, float32]' = None - minMeasuredValue: 'typing.Union[None, Nullable, float32]' = None - maxMeasuredValue: 'typing.Union[None, Nullable, float32]' = None - peakMeasuredValue: 'typing.Union[None, Nullable, float32]' = None - peakMeasuredValueWindow: 'typing.Optional[uint]' = None - averageMeasuredValue: 'typing.Union[None, Nullable, float32]' = None - averageMeasuredValueWindow: 'typing.Optional[uint]' = None - uncertainty: 'typing.Optional[float32]' = None - measurementUnit: 'typing.Optional[RadonConcentrationMeasurement.Enums.MeasurementUnitEnum]' = None - measurementMedium: 'typing.Optional[RadonConcentrationMeasurement.Enums.MeasurementMediumEnum]' = None - levelValue: 'typing.Optional[RadonConcentrationMeasurement.Enums.LevelValueEnum]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + measuredValue: typing.Union[None, Nullable, float32] = None + minMeasuredValue: typing.Union[None, Nullable, float32] = None + maxMeasuredValue: typing.Union[None, Nullable, float32] = None + peakMeasuredValue: typing.Union[None, Nullable, float32] = None + peakMeasuredValueWindow: typing.Optional[uint] = None + averageMeasuredValue: typing.Union[None, Nullable, float32] = None + averageMeasuredValueWindow: typing.Optional[uint] = None + uncertainty: typing.Optional[float32] = None + measurementUnit: typing.Optional[RadonConcentrationMeasurement.Enums.MeasurementUnitEnum] = None + measurementMedium: typing.Optional[RadonConcentrationMeasurement.Enums.MeasurementMediumEnum] = None + levelValue: typing.Optional[RadonConcentrationMeasurement.Enums.LevelValueEnum] = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class LevelValueEnum(MatterIntEnum): @@ -41163,7 +41164,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, float32]) - value: 'typing.Union[None, Nullable, float32]' = None + value: typing.Union[None, Nullable, float32] = None @dataclass class MinMeasuredValue(ClusterAttributeDescriptor): @@ -41179,7 +41180,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, float32]) - value: 'typing.Union[None, Nullable, float32]' = None + value: typing.Union[None, Nullable, float32] = None @dataclass class MaxMeasuredValue(ClusterAttributeDescriptor): @@ -41195,7 +41196,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, float32]) - value: 'typing.Union[None, Nullable, float32]' = None + value: typing.Union[None, Nullable, float32] = None @dataclass class PeakMeasuredValue(ClusterAttributeDescriptor): @@ -41211,7 +41212,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, float32]) - value: 'typing.Union[None, Nullable, float32]' = None + value: typing.Union[None, Nullable, float32] = None @dataclass class PeakMeasuredValueWindow(ClusterAttributeDescriptor): @@ -41227,7 +41228,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class AverageMeasuredValue(ClusterAttributeDescriptor): @@ -41243,7 +41244,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, float32]) - value: 'typing.Union[None, Nullable, float32]' = None + value: typing.Union[None, Nullable, float32] = None @dataclass class AverageMeasuredValueWindow(ClusterAttributeDescriptor): @@ -41259,7 +41260,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class Uncertainty(ClusterAttributeDescriptor): @@ -41275,7 +41276,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[float32]) - value: 'typing.Optional[float32]' = None + value: typing.Optional[float32] = None @dataclass class MeasurementUnit(ClusterAttributeDescriptor): @@ -41291,7 +41292,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[RadonConcentrationMeasurement.Enums.MeasurementUnitEnum]) - value: 'typing.Optional[RadonConcentrationMeasurement.Enums.MeasurementUnitEnum]' = None + value: typing.Optional[RadonConcentrationMeasurement.Enums.MeasurementUnitEnum] = None @dataclass class MeasurementMedium(ClusterAttributeDescriptor): @@ -41307,7 +41308,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[RadonConcentrationMeasurement.Enums.MeasurementMediumEnum]) - value: 'typing.Optional[RadonConcentrationMeasurement.Enums.MeasurementMediumEnum]' = None + value: typing.Optional[RadonConcentrationMeasurement.Enums.MeasurementMediumEnum] = None @dataclass class LevelValue(ClusterAttributeDescriptor): @@ -41323,7 +41324,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[RadonConcentrationMeasurement.Enums.LevelValueEnum]) - value: 'typing.Optional[RadonConcentrationMeasurement.Enums.LevelValueEnum]' = None + value: typing.Optional[RadonConcentrationMeasurement.Enums.LevelValueEnum] = None @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -41339,7 +41340,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -41355,7 +41356,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -41371,7 +41372,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -41387,7 +41388,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -41403,7 +41404,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -41419,7 +41420,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -41440,14 +41441,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - ssid: 'typing.Union[Nullable, bytes]' = None - passphraseSurrogate: 'typing.Union[Nullable, uint]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + ssid: typing.Union[Nullable, bytes] = NullValue + passphraseSurrogate: typing.Union[Nullable, uint] = NullValue + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Commands: @dataclass @@ -41468,7 +41469,7 @@ class NetworkPassphraseResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000451 command_id: typing.ClassVar[int] = 0x00000001 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -41477,7 +41478,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="passphrase", Tag=0, Type=bytes), ]) - passphrase: 'bytes' = b"" + passphrase: bytes = b"" class Attributes: @dataclass @@ -41494,7 +41495,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, bytes]) - value: 'typing.Union[Nullable, bytes]' = NullValue + value: typing.Union[Nullable, bytes] = NullValue @dataclass class PassphraseSurrogate(ClusterAttributeDescriptor): @@ -41510,7 +41511,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, uint]) - value: 'typing.Union[Nullable, uint]' = NullValue + value: typing.Union[Nullable, uint] = NullValue @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -41526,7 +41527,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -41542,7 +41543,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -41558,7 +41559,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -41574,7 +41575,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -41590,7 +41591,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -41606,7 +41607,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -41631,18 +41632,18 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - borderRouterName: 'str' = None - borderAgentID: 'bytes' = None - threadVersion: 'uint' = None - interfaceEnabled: 'bool' = None - activeDatasetTimestamp: 'typing.Union[Nullable, uint]' = None - pendingDatasetTimestamp: 'typing.Union[Nullable, uint]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + borderRouterName: str = "" + borderAgentID: bytes = b"" + threadVersion: uint = 0 + interfaceEnabled: bool = False + activeDatasetTimestamp: typing.Union[Nullable, uint] = NullValue + pendingDatasetTimestamp: typing.Union[Nullable, uint] = NullValue + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Bitmaps: class Feature(IntFlag): @@ -41680,7 +41681,7 @@ class DatasetResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000452 command_id: typing.ClassVar[int] = 0x00000002 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -41689,14 +41690,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="dataset", Tag=0, Type=bytes), ]) - dataset: 'bytes' = b"" + dataset: bytes = b"" @dataclass class SetActiveDatasetRequest(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000452 command_id: typing.ClassVar[int] = 0x00000003 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -41706,15 +41707,15 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="breadcrumb", Tag=1, Type=typing.Optional[uint]), ]) - activeDataset: 'bytes' = b"" - breadcrumb: 'typing.Optional[uint]' = None + activeDataset: bytes = b"" + breadcrumb: typing.Optional[uint] = None @dataclass class SetPendingDatasetRequest(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000452 command_id: typing.ClassVar[int] = 0x00000004 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -41723,7 +41724,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="pendingDataset", Tag=0, Type=bytes), ]) - pendingDataset: 'bytes' = b"" + pendingDataset: bytes = b"" class Attributes: @dataclass @@ -41740,7 +41741,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=str) - value: 'str' = "" + value: str = "" @dataclass class BorderAgentID(ClusterAttributeDescriptor): @@ -41756,7 +41757,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=bytes) - value: 'bytes' = b"" + value: bytes = b"" @dataclass class ThreadVersion(ClusterAttributeDescriptor): @@ -41772,7 +41773,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class InterfaceEnabled(ClusterAttributeDescriptor): @@ -41788,7 +41789,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=bool) - value: 'bool' = False + value: bool = False @dataclass class ActiveDatasetTimestamp(ClusterAttributeDescriptor): @@ -41804,7 +41805,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, uint]) - value: 'typing.Union[Nullable, uint]' = NullValue + value: typing.Union[Nullable, uint] = NullValue @dataclass class PendingDatasetTimestamp(ClusterAttributeDescriptor): @@ -41820,7 +41821,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, uint]) - value: 'typing.Union[Nullable, uint]' = NullValue + value: typing.Union[Nullable, uint] = NullValue @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -41836,7 +41837,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -41852,7 +41853,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -41868,7 +41869,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -41884,7 +41885,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -41900,7 +41901,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -41916,7 +41917,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -41938,15 +41939,15 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - preferredExtendedPanID: 'typing.Union[Nullable, bytes]' = None - threadNetworks: 'typing.List[ThreadNetworkDirectory.Structs.ThreadNetworkStruct]' = None - threadNetworkTableSize: 'uint' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + preferredExtendedPanID: typing.Union[Nullable, bytes] = NullValue + threadNetworks: typing.List[ThreadNetworkDirectory.Structs.ThreadNetworkStruct] = field(default_factory=lambda: []) + threadNetworkTableSize: uint = 0 + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Structs: @dataclass @@ -41972,7 +41973,7 @@ class AddNetwork(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000453 command_id: typing.ClassVar[int] = 0x00000000 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -41985,14 +41986,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: def must_use_timed_invoke(cls) -> bool: return True - operationalDataset: 'bytes' = b"" + operationalDataset: bytes = b"" @dataclass class RemoveNetwork(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000453 command_id: typing.ClassVar[int] = 0x00000001 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -42005,7 +42006,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: def must_use_timed_invoke(cls) -> bool: return True - extendedPanID: 'bytes' = b"" + extendedPanID: bytes = b"" @dataclass class GetOperationalDataset(ClusterCommand): @@ -42021,14 +42022,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="extendedPanID", Tag=0, Type=bytes), ]) - extendedPanID: 'bytes' = b"" + extendedPanID: bytes = b"" @dataclass class OperationalDatasetResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000453 command_id: typing.ClassVar[int] = 0x00000003 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -42037,7 +42038,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="operationalDataset", Tag=0, Type=bytes), ]) - operationalDataset: 'bytes' = b"" + operationalDataset: bytes = b"" class Attributes: @dataclass @@ -42054,7 +42055,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, bytes]) - value: 'typing.Union[Nullable, bytes]' = NullValue + value: typing.Union[Nullable, bytes] = NullValue @dataclass class ThreadNetworks(ClusterAttributeDescriptor): @@ -42070,7 +42071,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[ThreadNetworkDirectory.Structs.ThreadNetworkStruct]) - value: 'typing.List[ThreadNetworkDirectory.Structs.ThreadNetworkStruct]' = field(default_factory=lambda: []) + value: typing.List[ThreadNetworkDirectory.Structs.ThreadNetworkStruct] = field(default_factory=lambda: []) @dataclass class ThreadNetworkTableSize(ClusterAttributeDescriptor): @@ -42086,7 +42087,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -42102,7 +42103,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -42118,7 +42119,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -42134,7 +42135,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -42150,7 +42151,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -42166,7 +42167,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -42182,7 +42183,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -42203,14 +42204,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - MACAddress: 'typing.Optional[str]' = None - linkLocalAddress: 'typing.Optional[bytes]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + MACAddress: typing.Optional[str] = None + linkLocalAddress: typing.Optional[bytes] = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Attributes: @dataclass @@ -42227,7 +42228,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[str]) - value: 'typing.Optional[str]' = None + value: typing.Optional[str] = None @dataclass class LinkLocalAddress(ClusterAttributeDescriptor): @@ -42243,7 +42244,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[bytes]) - value: 'typing.Optional[bytes]' = None + value: typing.Optional[bytes] = None @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -42259,7 +42260,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -42275,7 +42276,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -42291,7 +42292,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -42307,7 +42308,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -42323,7 +42324,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -42339,7 +42340,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -42361,15 +42362,15 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - channelList: 'typing.Optional[typing.List[Channel.Structs.ChannelInfoStruct]]' = None - lineup: 'typing.Union[None, Nullable, Channel.Structs.LineupInfoStruct]' = None - currentChannel: 'typing.Union[None, Nullable, Channel.Structs.ChannelInfoStruct]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + channelList: typing.Optional[typing.List[Channel.Structs.ChannelInfoStruct]] = None + lineup: typing.Union[None, Nullable, Channel.Structs.LineupInfoStruct] = None + currentChannel: typing.Union[None, Nullable, Channel.Structs.ChannelInfoStruct] = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class ChannelTypeEnum(MatterIntEnum): @@ -42596,14 +42597,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="match", Tag=0, Type=str), ]) - match: 'str' = "" + match: str = "" @dataclass class ChangeChannelResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000504 command_id: typing.ClassVar[int] = 0x00000001 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -42613,15 +42614,15 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="data", Tag=1, Type=typing.Optional[str]), ]) - status: 'Channel.Enums.StatusEnum' = 0 - data: 'typing.Optional[str]' = None + status: Channel.Enums.StatusEnum = 0 + data: typing.Optional[str] = None @dataclass class ChangeChannelByNumber(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000504 command_id: typing.ClassVar[int] = 0x00000002 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -42631,15 +42632,15 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="minorNumber", Tag=1, Type=uint), ]) - majorNumber: 'uint' = 0 - minorNumber: 'uint' = 0 + majorNumber: uint = 0 + minorNumber: uint = 0 @dataclass class SkipChannel(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000504 command_id: typing.ClassVar[int] = 0x00000003 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -42648,7 +42649,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="count", Tag=0, Type=int), ]) - count: 'int' = 0 + count: int = 0 @dataclass class GetProgramGuide(ClusterCommand): @@ -42670,20 +42671,20 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="data", Tag=6, Type=typing.Optional[bytes]), ]) - startTime: 'typing.Optional[uint]' = None - endTime: 'typing.Optional[uint]' = None - channelList: 'typing.Optional[typing.List[Channel.Structs.ChannelInfoStruct]]' = None - pageToken: 'typing.Optional[Channel.Structs.PageTokenStruct]' = None - recordingFlag: 'typing.Optional[uint]' = None - externalIDList: 'typing.Optional[typing.List[Channel.Structs.AdditionalInfoStruct]]' = None - data: 'typing.Optional[bytes]' = None + startTime: typing.Optional[uint] = None + endTime: typing.Optional[uint] = None + channelList: typing.Optional[typing.List[Channel.Structs.ChannelInfoStruct]] = None + pageToken: typing.Optional[Channel.Structs.PageTokenStruct] = None + recordingFlag: typing.Optional[uint] = None + externalIDList: typing.Optional[typing.List[Channel.Structs.AdditionalInfoStruct]] = None + data: typing.Optional[bytes] = None @dataclass class ProgramGuideResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000504 command_id: typing.ClassVar[int] = 0x00000005 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -42693,15 +42694,15 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="programList", Tag=1, Type=typing.List[Channel.Structs.ProgramStruct]), ]) - paging: 'Channel.Structs.ChannelPagingStruct' = field(default_factory=lambda: Channel.Structs.ChannelPagingStruct()) - programList: 'typing.List[Channel.Structs.ProgramStruct]' = field(default_factory=lambda: []) + paging: Channel.Structs.ChannelPagingStruct = field(default_factory=lambda: Channel.Structs.ChannelPagingStruct()) + programList: typing.List[Channel.Structs.ProgramStruct] = field(default_factory=lambda: []) @dataclass class RecordProgram(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000504 command_id: typing.ClassVar[int] = 0x00000006 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -42713,17 +42714,17 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="data", Tag=3, Type=bytes), ]) - programIdentifier: 'str' = "" - shouldRecordSeries: 'bool' = False - externalIDList: 'typing.List[Channel.Structs.AdditionalInfoStruct]' = field(default_factory=lambda: []) - data: 'bytes' = b"" + programIdentifier: str = "" + shouldRecordSeries: bool = False + externalIDList: typing.List[Channel.Structs.AdditionalInfoStruct] = field(default_factory=lambda: []) + data: bytes = b"" @dataclass class CancelRecordProgram(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000504 command_id: typing.ClassVar[int] = 0x00000007 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -42735,10 +42736,10 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="data", Tag=3, Type=bytes), ]) - programIdentifier: 'str' = "" - shouldRecordSeries: 'bool' = False - externalIDList: 'typing.List[Channel.Structs.AdditionalInfoStruct]' = field(default_factory=lambda: []) - data: 'bytes' = b"" + programIdentifier: str = "" + shouldRecordSeries: bool = False + externalIDList: typing.List[Channel.Structs.AdditionalInfoStruct] = field(default_factory=lambda: []) + data: bytes = b"" class Attributes: @dataclass @@ -42755,7 +42756,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[typing.List[Channel.Structs.ChannelInfoStruct]]) - value: 'typing.Optional[typing.List[Channel.Structs.ChannelInfoStruct]]' = None + value: typing.Optional[typing.List[Channel.Structs.ChannelInfoStruct]] = None @dataclass class Lineup(ClusterAttributeDescriptor): @@ -42771,7 +42772,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, Channel.Structs.LineupInfoStruct]) - value: 'typing.Union[None, Nullable, Channel.Structs.LineupInfoStruct]' = None + value: typing.Union[None, Nullable, Channel.Structs.LineupInfoStruct] = None @dataclass class CurrentChannel(ClusterAttributeDescriptor): @@ -42787,7 +42788,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, Channel.Structs.ChannelInfoStruct]) - value: 'typing.Union[None, Nullable, Channel.Structs.ChannelInfoStruct]' = None + value: typing.Union[None, Nullable, Channel.Structs.ChannelInfoStruct] = None @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -42803,7 +42804,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -42819,7 +42820,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -42835,7 +42836,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -42851,7 +42852,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -42867,7 +42868,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -42883,7 +42884,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -42904,14 +42905,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - targetList: 'typing.List[TargetNavigator.Structs.TargetInfoStruct]' = None - currentTarget: 'typing.Optional[uint]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + targetList: typing.List[TargetNavigator.Structs.TargetInfoStruct] = field(default_factory=lambda: []) + currentTarget: typing.Optional[uint] = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class StatusEnum(MatterIntEnum): @@ -42954,15 +42955,15 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="data", Tag=1, Type=typing.Optional[str]), ]) - target: 'uint' = 0 - data: 'typing.Optional[str]' = None + target: uint = 0 + data: typing.Optional[str] = None @dataclass class NavigateTargetResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000505 command_id: typing.ClassVar[int] = 0x00000001 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -42972,8 +42973,8 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="data", Tag=1, Type=typing.Optional[str]), ]) - status: 'TargetNavigator.Enums.StatusEnum' = 0 - data: 'typing.Optional[str]' = None + status: TargetNavigator.Enums.StatusEnum = 0 + data: typing.Optional[str] = None class Attributes: @dataclass @@ -42990,7 +42991,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[TargetNavigator.Structs.TargetInfoStruct]) - value: 'typing.List[TargetNavigator.Structs.TargetInfoStruct]' = field(default_factory=lambda: []) + value: typing.List[TargetNavigator.Structs.TargetInfoStruct] = field(default_factory=lambda: []) @dataclass class CurrentTarget(ClusterAttributeDescriptor): @@ -43006,7 +43007,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -43022,7 +43023,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -43038,7 +43039,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -43054,7 +43055,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -43070,7 +43071,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -43086,7 +43087,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -43102,7 +43103,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 class Events: @dataclass @@ -43124,9 +43125,9 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="data", Tag=2, Type=bytes), ]) - targetList: 'typing.List[TargetNavigator.Structs.TargetInfoStruct]' = field(default_factory=lambda: []) - currentTarget: 'uint' = 0 - data: 'bytes' = b"" + targetList: typing.List[TargetNavigator.Structs.TargetInfoStruct] = field(default_factory=lambda: []) + currentTarget: uint = 0 + data: bytes = b"" @dataclass @@ -43156,23 +43157,23 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - currentState: 'MediaPlayback.Enums.PlaybackStateEnum' = None - startTime: 'typing.Union[None, Nullable, uint]' = None - duration: 'typing.Union[None, Nullable, uint]' = None - sampledPosition: 'typing.Union[None, Nullable, MediaPlayback.Structs.PlaybackPositionStruct]' = None - playbackSpeed: 'typing.Optional[float32]' = None - seekRangeEnd: 'typing.Union[None, Nullable, uint]' = None - seekRangeStart: 'typing.Union[None, Nullable, uint]' = None - activeAudioTrack: 'typing.Union[None, Nullable, MediaPlayback.Structs.TrackStruct]' = None - availableAudioTracks: 'typing.Union[None, Nullable, typing.List[MediaPlayback.Structs.TrackStruct]]' = None - activeTextTrack: 'typing.Union[None, Nullable, MediaPlayback.Structs.TrackStruct]' = None - availableTextTracks: 'typing.Union[None, Nullable, typing.List[MediaPlayback.Structs.TrackStruct]]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + currentState: MediaPlayback.Enums.PlaybackStateEnum = 0 + startTime: typing.Union[None, Nullable, uint] = None + duration: typing.Union[None, Nullable, uint] = None + sampledPosition: typing.Union[None, Nullable, MediaPlayback.Structs.PlaybackPositionStruct] = None + playbackSpeed: typing.Optional[float32] = None + seekRangeEnd: typing.Union[None, Nullable, uint] = None + seekRangeStart: typing.Union[None, Nullable, uint] = None + activeAudioTrack: typing.Union[None, Nullable, MediaPlayback.Structs.TrackStruct] = None + availableAudioTracks: typing.Union[None, Nullable, typing.List[MediaPlayback.Structs.TrackStruct]] = None + activeTextTrack: typing.Union[None, Nullable, MediaPlayback.Structs.TrackStruct] = None + availableTextTracks: typing.Union[None, Nullable, typing.List[MediaPlayback.Structs.TrackStruct]] = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class CharacteristicEnum(MatterIntEnum): @@ -43365,7 +43366,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="audioAdvanceUnmuted", Tag=0, Type=typing.Optional[bool]), ]) - audioAdvanceUnmuted: 'typing.Optional[bool]' = None + audioAdvanceUnmuted: typing.Optional[bool] = None @dataclass class FastForward(ClusterCommand): @@ -43381,7 +43382,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="audioAdvanceUnmuted", Tag=0, Type=typing.Optional[bool]), ]) - audioAdvanceUnmuted: 'typing.Optional[bool]' = None + audioAdvanceUnmuted: typing.Optional[bool] = None @dataclass class SkipForward(ClusterCommand): @@ -43397,7 +43398,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="deltaPositionMilliseconds", Tag=0, Type=uint), ]) - deltaPositionMilliseconds: 'uint' = 0 + deltaPositionMilliseconds: uint = 0 @dataclass class SkipBackward(ClusterCommand): @@ -43413,14 +43414,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="deltaPositionMilliseconds", Tag=0, Type=uint), ]) - deltaPositionMilliseconds: 'uint' = 0 + deltaPositionMilliseconds: uint = 0 @dataclass class PlaybackResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000506 command_id: typing.ClassVar[int] = 0x0000000A is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -43430,8 +43431,8 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="data", Tag=1, Type=typing.Optional[str]), ]) - status: 'MediaPlayback.Enums.StatusEnum' = 0 - data: 'typing.Optional[str]' = None + status: MediaPlayback.Enums.StatusEnum = 0 + data: typing.Optional[str] = None @dataclass class Seek(ClusterCommand): @@ -43447,14 +43448,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="position", Tag=0, Type=uint), ]) - position: 'uint' = 0 + position: uint = 0 @dataclass class ActivateAudioTrack(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000506 command_id: typing.ClassVar[int] = 0x0000000C is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -43464,15 +43465,15 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="audioOutputIndex", Tag=1, Type=uint), ]) - trackID: 'str' = "" - audioOutputIndex: 'uint' = 0 + trackID: str = "" + audioOutputIndex: uint = 0 @dataclass class ActivateTextTrack(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000506 command_id: typing.ClassVar[int] = 0x0000000D is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -43481,14 +43482,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="trackID", Tag=0, Type=str), ]) - trackID: 'str' = "" + trackID: str = "" @dataclass class DeactivateTextTrack(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000506 command_id: typing.ClassVar[int] = 0x0000000E is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -43511,7 +43512,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=MediaPlayback.Enums.PlaybackStateEnum) - value: 'MediaPlayback.Enums.PlaybackStateEnum' = 0 + value: MediaPlayback.Enums.PlaybackStateEnum = 0 @dataclass class StartTime(ClusterAttributeDescriptor): @@ -43527,7 +43528,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class Duration(ClusterAttributeDescriptor): @@ -43543,7 +43544,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class SampledPosition(ClusterAttributeDescriptor): @@ -43559,7 +43560,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, MediaPlayback.Structs.PlaybackPositionStruct]) - value: 'typing.Union[None, Nullable, MediaPlayback.Structs.PlaybackPositionStruct]' = None + value: typing.Union[None, Nullable, MediaPlayback.Structs.PlaybackPositionStruct] = None @dataclass class PlaybackSpeed(ClusterAttributeDescriptor): @@ -43575,7 +43576,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[float32]) - value: 'typing.Optional[float32]' = None + value: typing.Optional[float32] = None @dataclass class SeekRangeEnd(ClusterAttributeDescriptor): @@ -43591,7 +43592,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class SeekRangeStart(ClusterAttributeDescriptor): @@ -43607,7 +43608,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - value: 'typing.Union[None, Nullable, uint]' = None + value: typing.Union[None, Nullable, uint] = None @dataclass class ActiveAudioTrack(ClusterAttributeDescriptor): @@ -43623,7 +43624,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, MediaPlayback.Structs.TrackStruct]) - value: 'typing.Union[None, Nullable, MediaPlayback.Structs.TrackStruct]' = None + value: typing.Union[None, Nullable, MediaPlayback.Structs.TrackStruct] = None @dataclass class AvailableAudioTracks(ClusterAttributeDescriptor): @@ -43639,7 +43640,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, typing.List[MediaPlayback.Structs.TrackStruct]]) - value: 'typing.Union[None, Nullable, typing.List[MediaPlayback.Structs.TrackStruct]]' = None + value: typing.Union[None, Nullable, typing.List[MediaPlayback.Structs.TrackStruct]] = None @dataclass class ActiveTextTrack(ClusterAttributeDescriptor): @@ -43655,7 +43656,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, MediaPlayback.Structs.TrackStruct]) - value: 'typing.Union[None, Nullable, MediaPlayback.Structs.TrackStruct]' = None + value: typing.Union[None, Nullable, MediaPlayback.Structs.TrackStruct] = None @dataclass class AvailableTextTracks(ClusterAttributeDescriptor): @@ -43671,7 +43672,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, typing.List[MediaPlayback.Structs.TrackStruct]]) - value: 'typing.Union[None, Nullable, typing.List[MediaPlayback.Structs.TrackStruct]]' = None + value: typing.Union[None, Nullable, typing.List[MediaPlayback.Structs.TrackStruct]] = None @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -43687,7 +43688,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -43703,7 +43704,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -43719,7 +43720,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -43735,7 +43736,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -43751,7 +43752,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -43767,7 +43768,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 class Events: @dataclass @@ -43795,15 +43796,15 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="audioAdvanceUnmuted", Tag=8, Type=bool), ]) - currentState: 'MediaPlayback.Enums.PlaybackStateEnum' = 0 - startTime: 'uint' = 0 - duration: 'uint' = 0 - sampledPosition: 'MediaPlayback.Structs.PlaybackPositionStruct' = field(default_factory=lambda: MediaPlayback.Structs.PlaybackPositionStruct()) - playbackSpeed: 'float32' = 0.0 - seekRangeEnd: 'uint' = 0 - seekRangeStart: 'uint' = 0 - data: 'typing.Optional[bytes]' = None - audioAdvanceUnmuted: 'bool' = False + currentState: MediaPlayback.Enums.PlaybackStateEnum = 0 + startTime: uint = 0 + duration: uint = 0 + sampledPosition: MediaPlayback.Structs.PlaybackPositionStruct = field(default_factory=lambda: MediaPlayback.Structs.PlaybackPositionStruct()) + playbackSpeed: float32 = 0.0 + seekRangeEnd: uint = 0 + seekRangeStart: uint = 0 + data: typing.Optional[bytes] = None + audioAdvanceUnmuted: bool = False @dataclass @@ -43824,14 +43825,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - inputList: 'typing.List[MediaInput.Structs.InputInfoStruct]' = None - currentInput: 'uint' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + inputList: typing.List[MediaInput.Structs.InputInfoStruct] = field(default_factory=lambda: []) + currentInput: uint = 0 + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class InputTypeEnum(MatterIntEnum): @@ -43881,7 +43882,7 @@ class SelectInput(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000507 command_id: typing.ClassVar[int] = 0x00000000 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -43890,14 +43891,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="index", Tag=0, Type=uint), ]) - index: 'uint' = 0 + index: uint = 0 @dataclass class ShowInputStatus(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000507 command_id: typing.ClassVar[int] = 0x00000001 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -43910,7 +43911,7 @@ class HideInputStatus(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000507 command_id: typing.ClassVar[int] = 0x00000002 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -43923,7 +43924,7 @@ class RenameInput(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000507 command_id: typing.ClassVar[int] = 0x00000003 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -43933,8 +43934,8 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="name", Tag=1, Type=str), ]) - index: 'uint' = 0 - name: 'str' = "" + index: uint = 0 + name: str = "" class Attributes: @dataclass @@ -43951,7 +43952,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[MediaInput.Structs.InputInfoStruct]) - value: 'typing.List[MediaInput.Structs.InputInfoStruct]' = field(default_factory=lambda: []) + value: typing.List[MediaInput.Structs.InputInfoStruct] = field(default_factory=lambda: []) @dataclass class CurrentInput(ClusterAttributeDescriptor): @@ -43967,7 +43968,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -43983,7 +43984,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -43999,7 +44000,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -44015,7 +44016,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -44031,7 +44032,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -44047,7 +44048,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -44063,7 +44064,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -44082,12 +44083,12 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Commands: @dataclass @@ -44095,7 +44096,7 @@ class Sleep(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000508 command_id: typing.ClassVar[int] = 0x00000000 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -44118,7 +44119,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -44134,7 +44135,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -44150,7 +44151,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -44166,7 +44167,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -44182,7 +44183,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -44198,7 +44199,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -44217,12 +44218,12 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class CECKeyCodeEnum(MatterIntEnum): @@ -44349,14 +44350,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="keyCode", Tag=0, Type=KeypadInput.Enums.CECKeyCodeEnum), ]) - keyCode: 'KeypadInput.Enums.CECKeyCodeEnum' = 0 + keyCode: KeypadInput.Enums.CECKeyCodeEnum = 0 @dataclass class SendKeyResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000509 command_id: typing.ClassVar[int] = 0x00000001 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -44365,7 +44366,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="status", Tag=0, Type=KeypadInput.Enums.StatusEnum), ]) - status: 'KeypadInput.Enums.StatusEnum' = 0 + status: KeypadInput.Enums.StatusEnum = 0 class Attributes: @dataclass @@ -44382,7 +44383,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -44398,7 +44399,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -44414,7 +44415,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -44430,7 +44431,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -44446,7 +44447,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -44462,7 +44463,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -44483,14 +44484,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - acceptHeader: 'typing.Optional[typing.List[str]]' = None - supportedStreamingProtocols: 'typing.Optional[uint]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + acceptHeader: typing.Optional[typing.List[str]] = None + supportedStreamingProtocols: typing.Optional[uint] = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class CharacteristicEnum(MatterIntEnum): @@ -44715,11 +44716,11 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="useCurrentContext", Tag=4, Type=typing.Optional[bool]), ]) - search: 'ContentLauncher.Structs.ContentSearchStruct' = field(default_factory=lambda: ContentLauncher.Structs.ContentSearchStruct()) - autoPlay: 'bool' = False - data: 'typing.Optional[str]' = None - playbackPreferences: 'typing.Optional[ContentLauncher.Structs.PlaybackPreferencesStruct]' = None - useCurrentContext: 'typing.Optional[bool]' = None + search: ContentLauncher.Structs.ContentSearchStruct = field(default_factory=lambda: ContentLauncher.Structs.ContentSearchStruct()) + autoPlay: bool = False + data: typing.Optional[str] = None + playbackPreferences: typing.Optional[ContentLauncher.Structs.PlaybackPreferencesStruct] = None + useCurrentContext: typing.Optional[bool] = None @dataclass class LaunchURL(ClusterCommand): @@ -44737,16 +44738,16 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="brandingInformation", Tag=2, Type=typing.Optional[ContentLauncher.Structs.BrandingInformationStruct]), ]) - contentURL: 'str' = "" - displayString: 'typing.Optional[str]' = None - brandingInformation: 'typing.Optional[ContentLauncher.Structs.BrandingInformationStruct]' = None + contentURL: str = "" + displayString: typing.Optional[str] = None + brandingInformation: typing.Optional[ContentLauncher.Structs.BrandingInformationStruct] = None @dataclass class LauncherResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x0000050A command_id: typing.ClassVar[int] = 0x00000002 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -44756,8 +44757,8 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="data", Tag=1, Type=typing.Optional[str]), ]) - status: 'ContentLauncher.Enums.StatusEnum' = 0 - data: 'typing.Optional[str]' = None + status: ContentLauncher.Enums.StatusEnum = 0 + data: typing.Optional[str] = None class Attributes: @dataclass @@ -44774,7 +44775,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[typing.List[str]]) - value: 'typing.Optional[typing.List[str]]' = None + value: typing.Optional[typing.List[str]] = None @dataclass class SupportedStreamingProtocols(ClusterAttributeDescriptor): @@ -44790,7 +44791,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -44806,7 +44807,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -44822,7 +44823,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -44838,7 +44839,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -44854,7 +44855,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -44870,7 +44871,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -44886,7 +44887,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -44907,14 +44908,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - outputList: 'typing.List[AudioOutput.Structs.OutputInfoStruct]' = None - currentOutput: 'uint' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + outputList: typing.List[AudioOutput.Structs.OutputInfoStruct] = field(default_factory=lambda: []) + currentOutput: uint = 0 + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class OutputTypeEnum(MatterIntEnum): @@ -44956,7 +44957,7 @@ class SelectOutput(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x0000050B command_id: typing.ClassVar[int] = 0x00000000 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -44965,14 +44966,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="index", Tag=0, Type=uint), ]) - index: 'uint' = 0 + index: uint = 0 @dataclass class RenameOutput(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x0000050B command_id: typing.ClassVar[int] = 0x00000001 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -44982,8 +44983,8 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="name", Tag=1, Type=str), ]) - index: 'uint' = 0 - name: 'str' = "" + index: uint = 0 + name: str = "" class Attributes: @dataclass @@ -45000,7 +45001,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[AudioOutput.Structs.OutputInfoStruct]) - value: 'typing.List[AudioOutput.Structs.OutputInfoStruct]' = field(default_factory=lambda: []) + value: typing.List[AudioOutput.Structs.OutputInfoStruct] = field(default_factory=lambda: []) @dataclass class CurrentOutput(ClusterAttributeDescriptor): @@ -45016,7 +45017,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -45032,7 +45033,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -45048,7 +45049,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -45064,7 +45065,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -45080,7 +45081,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -45096,7 +45097,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -45112,7 +45113,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -45133,14 +45134,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - catalogList: 'typing.Optional[typing.List[uint]]' = None - currentApp: 'typing.Union[None, Nullable, ApplicationLauncher.Structs.ApplicationEPStruct]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + catalogList: typing.Optional[typing.List[uint]] = None + currentApp: typing.Union[None, Nullable, ApplicationLauncher.Structs.ApplicationEPStruct] = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class StatusEnum(MatterIntEnum): @@ -45203,8 +45204,8 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="data", Tag=1, Type=typing.Optional[bytes]), ]) - application: 'typing.Optional[ApplicationLauncher.Structs.ApplicationStruct]' = None - data: 'typing.Optional[bytes]' = None + application: typing.Optional[ApplicationLauncher.Structs.ApplicationStruct] = None + data: typing.Optional[bytes] = None @dataclass class StopApp(ClusterCommand): @@ -45220,7 +45221,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="application", Tag=0, Type=typing.Optional[ApplicationLauncher.Structs.ApplicationStruct]), ]) - application: 'typing.Optional[ApplicationLauncher.Structs.ApplicationStruct]' = None + application: typing.Optional[ApplicationLauncher.Structs.ApplicationStruct] = None @dataclass class HideApp(ClusterCommand): @@ -45236,14 +45237,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="application", Tag=0, Type=typing.Optional[ApplicationLauncher.Structs.ApplicationStruct]), ]) - application: 'typing.Optional[ApplicationLauncher.Structs.ApplicationStruct]' = None + application: typing.Optional[ApplicationLauncher.Structs.ApplicationStruct] = None @dataclass class LauncherResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x0000050C command_id: typing.ClassVar[int] = 0x00000003 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -45253,8 +45254,8 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="data", Tag=1, Type=typing.Optional[bytes]), ]) - status: 'ApplicationLauncher.Enums.StatusEnum' = 0 - data: 'typing.Optional[bytes]' = None + status: ApplicationLauncher.Enums.StatusEnum = 0 + data: typing.Optional[bytes] = None class Attributes: @dataclass @@ -45271,7 +45272,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[typing.List[uint]]) - value: 'typing.Optional[typing.List[uint]]' = None + value: typing.Optional[typing.List[uint]] = None @dataclass class CurrentApp(ClusterAttributeDescriptor): @@ -45287,7 +45288,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, ApplicationLauncher.Structs.ApplicationEPStruct]) - value: 'typing.Union[None, Nullable, ApplicationLauncher.Structs.ApplicationEPStruct]' = None + value: typing.Union[None, Nullable, ApplicationLauncher.Structs.ApplicationEPStruct] = None @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -45303,7 +45304,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -45319,7 +45320,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -45335,7 +45336,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -45351,7 +45352,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -45367,7 +45368,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -45383,7 +45384,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -45410,20 +45411,20 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - vendorName: 'typing.Optional[str]' = None - vendorID: 'typing.Optional[uint]' = None - applicationName: 'str' = None - productID: 'typing.Optional[uint]' = None - application: 'ApplicationBasic.Structs.ApplicationStruct' = None - status: 'ApplicationBasic.Enums.ApplicationStatusEnum' = None - applicationVersion: 'str' = None - allowedVendorList: 'typing.List[uint]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + vendorName: typing.Optional[str] = None + vendorID: typing.Optional[uint] = None + applicationName: str = "" + productID: typing.Optional[uint] = None + application: ApplicationBasic.Structs.ApplicationStruct = field(default_factory=lambda: ApplicationBasic.Structs.ApplicationStruct()) + status: ApplicationBasic.Enums.ApplicationStatusEnum = 0 + applicationVersion: str = "" + allowedVendorList: typing.List[uint] = field(default_factory=lambda: []) + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class ApplicationStatusEnum(MatterIntEnum): @@ -45466,7 +45467,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[str]) - value: 'typing.Optional[str]' = None + value: typing.Optional[str] = None @dataclass class VendorID(ClusterAttributeDescriptor): @@ -45482,7 +45483,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class ApplicationName(ClusterAttributeDescriptor): @@ -45498,7 +45499,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=str) - value: 'str' = "" + value: str = "" @dataclass class ProductID(ClusterAttributeDescriptor): @@ -45514,7 +45515,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class Application(ClusterAttributeDescriptor): @@ -45530,7 +45531,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=ApplicationBasic.Structs.ApplicationStruct) - value: 'ApplicationBasic.Structs.ApplicationStruct' = field(default_factory=lambda: ApplicationBasic.Structs.ApplicationStruct()) + value: ApplicationBasic.Structs.ApplicationStruct = field(default_factory=lambda: ApplicationBasic.Structs.ApplicationStruct()) @dataclass class Status(ClusterAttributeDescriptor): @@ -45546,7 +45547,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=ApplicationBasic.Enums.ApplicationStatusEnum) - value: 'ApplicationBasic.Enums.ApplicationStatusEnum' = 0 + value: ApplicationBasic.Enums.ApplicationStatusEnum = 0 @dataclass class ApplicationVersion(ClusterAttributeDescriptor): @@ -45562,7 +45563,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=str) - value: 'str' = "" + value: str = "" @dataclass class AllowedVendorList(ClusterAttributeDescriptor): @@ -45578,7 +45579,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -45594,7 +45595,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -45610,7 +45611,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -45626,7 +45627,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -45642,7 +45643,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -45658,7 +45659,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -45674,7 +45675,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -45693,12 +45694,12 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Commands: @dataclass @@ -45719,14 +45720,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: def must_use_timed_invoke(cls) -> bool: return True - tempAccountIdentifier: 'str' = "" + tempAccountIdentifier: str = "" @dataclass class GetSetupPINResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x0000050E command_id: typing.ClassVar[int] = 0x00000001 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -45735,14 +45736,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="setupPIN", Tag=0, Type=str), ]) - setupPIN: 'str' = "" + setupPIN: str = "" @dataclass class Login(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x0000050E command_id: typing.ClassVar[int] = 0x00000002 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -45757,16 +45758,16 @@ def descriptor(cls) -> ClusterObjectDescriptor: def must_use_timed_invoke(cls) -> bool: return True - tempAccountIdentifier: 'str' = "" - setupPIN: 'str' = "" - node: 'typing.Optional[uint]' = None + tempAccountIdentifier: str = "" + setupPIN: str = "" + node: typing.Optional[uint] = None @dataclass class Logout(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x0000050E command_id: typing.ClassVar[int] = 0x00000003 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -45779,7 +45780,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: def must_use_timed_invoke(cls) -> bool: return True - node: 'typing.Optional[uint]' = None + node: typing.Optional[uint] = None class Attributes: @dataclass @@ -45796,7 +45797,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -45812,7 +45813,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -45828,7 +45829,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -45844,7 +45845,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -45860,7 +45861,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -45876,7 +45877,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 class Events: @dataclass @@ -45896,7 +45897,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="node", Tag=0, Type=typing.Optional[uint]), ]) - node: 'typing.Optional[uint]' = None + node: typing.Optional[uint] = None @dataclass @@ -45923,20 +45924,20 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - enabled: 'bool' = None - onDemandRatings: 'typing.Optional[typing.List[ContentControl.Structs.RatingNameStruct]]' = None - onDemandRatingThreshold: 'typing.Optional[str]' = None - scheduledContentRatings: 'typing.Optional[typing.List[ContentControl.Structs.RatingNameStruct]]' = None - scheduledContentRatingThreshold: 'typing.Optional[str]' = None - screenDailyTime: 'typing.Optional[uint]' = None - remainingScreenTime: 'typing.Optional[uint]' = None - blockUnrated: 'bool' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + enabled: bool = False + onDemandRatings: typing.Optional[typing.List[ContentControl.Structs.RatingNameStruct]] = None + onDemandRatingThreshold: typing.Optional[str] = None + scheduledContentRatings: typing.Optional[typing.List[ContentControl.Structs.RatingNameStruct]] = None + scheduledContentRatingThreshold: typing.Optional[str] = None + screenDailyTime: typing.Optional[uint] = None + remainingScreenTime: typing.Optional[uint] = None + blockUnrated: bool = False + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Bitmaps: class Feature(IntFlag): @@ -45966,7 +45967,7 @@ class UpdatePIN(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x0000050F command_id: typing.ClassVar[int] = 0x00000000 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -45976,8 +45977,8 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="newPIN", Tag=1, Type=str), ]) - oldPIN: 'typing.Optional[str]' = None - newPIN: 'str' = "" + oldPIN: typing.Optional[str] = None + newPIN: str = "" @dataclass class ResetPIN(ClusterCommand): @@ -45997,7 +45998,7 @@ class ResetPINResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x0000050F command_id: typing.ClassVar[int] = 0x00000002 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -46006,14 +46007,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="PINCode", Tag=0, Type=str), ]) - PINCode: 'str' = "" + PINCode: str = "" @dataclass class Enable(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x0000050F command_id: typing.ClassVar[int] = 0x00000003 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -46026,7 +46027,7 @@ class Disable(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x0000050F command_id: typing.ClassVar[int] = 0x00000004 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -46039,7 +46040,7 @@ class AddBonusTime(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x0000050F command_id: typing.ClassVar[int] = 0x00000005 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -46049,15 +46050,15 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="bonusTime", Tag=1, Type=typing.Optional[uint]), ]) - PINCode: 'typing.Optional[str]' = None - bonusTime: 'typing.Optional[uint]' = None + PINCode: typing.Optional[str] = None + bonusTime: typing.Optional[uint] = None @dataclass class SetScreenDailyTime(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x0000050F command_id: typing.ClassVar[int] = 0x00000006 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -46066,14 +46067,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="screenTime", Tag=0, Type=uint), ]) - screenTime: 'uint' = 0 + screenTime: uint = 0 @dataclass class BlockUnratedContent(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x0000050F command_id: typing.ClassVar[int] = 0x00000007 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -46086,7 +46087,7 @@ class UnblockUnratedContent(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x0000050F command_id: typing.ClassVar[int] = 0x00000008 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -46099,7 +46100,7 @@ class SetOnDemandRatingThreshold(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x0000050F command_id: typing.ClassVar[int] = 0x00000009 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -46108,14 +46109,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="rating", Tag=0, Type=str), ]) - rating: 'str' = "" + rating: str = "" @dataclass class SetScheduledContentRatingThreshold(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x0000050F command_id: typing.ClassVar[int] = 0x0000000A is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -46124,7 +46125,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="rating", Tag=0, Type=str), ]) - rating: 'str' = "" + rating: str = "" class Attributes: @dataclass @@ -46141,7 +46142,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=bool) - value: 'bool' = False + value: bool = False @dataclass class OnDemandRatings(ClusterAttributeDescriptor): @@ -46157,7 +46158,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[typing.List[ContentControl.Structs.RatingNameStruct]]) - value: 'typing.Optional[typing.List[ContentControl.Structs.RatingNameStruct]]' = None + value: typing.Optional[typing.List[ContentControl.Structs.RatingNameStruct]] = None @dataclass class OnDemandRatingThreshold(ClusterAttributeDescriptor): @@ -46173,7 +46174,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[str]) - value: 'typing.Optional[str]' = None + value: typing.Optional[str] = None @dataclass class ScheduledContentRatings(ClusterAttributeDescriptor): @@ -46189,7 +46190,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[typing.List[ContentControl.Structs.RatingNameStruct]]) - value: 'typing.Optional[typing.List[ContentControl.Structs.RatingNameStruct]]' = None + value: typing.Optional[typing.List[ContentControl.Structs.RatingNameStruct]] = None @dataclass class ScheduledContentRatingThreshold(ClusterAttributeDescriptor): @@ -46205,7 +46206,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[str]) - value: 'typing.Optional[str]' = None + value: typing.Optional[str] = None @dataclass class ScreenDailyTime(ClusterAttributeDescriptor): @@ -46221,7 +46222,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class RemainingScreenTime(ClusterAttributeDescriptor): @@ -46237,7 +46238,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class BlockUnrated(ClusterAttributeDescriptor): @@ -46253,7 +46254,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=bool) - value: 'bool' = False + value: bool = False @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -46269,7 +46270,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -46285,7 +46286,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -46301,7 +46302,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -46317,7 +46318,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -46333,7 +46334,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -46349,7 +46350,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 class Events: @dataclass @@ -46385,12 +46386,12 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class StatusEnum(MatterIntEnum): @@ -46418,15 +46419,15 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="encodingHint", Tag=1, Type=str), ]) - data: 'typing.Optional[str]' = None - encodingHint: 'str' = "" + data: typing.Optional[str] = None + encodingHint: str = "" @dataclass class ContentAppMessageResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000510 command_id: typing.ClassVar[int] = 0x00000001 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -46437,9 +46438,9 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="encodingHint", Tag=2, Type=typing.Optional[str]), ]) - status: 'ContentAppObserver.Enums.StatusEnum' = 0 - data: 'typing.Optional[str]' = None - encodingHint: 'typing.Optional[str]' = None + status: ContentAppObserver.Enums.StatusEnum = 0 + data: typing.Optional[str] = None + encodingHint: typing.Optional[str] = None class Attributes: @dataclass @@ -46456,7 +46457,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -46472,7 +46473,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -46488,7 +46489,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -46504,7 +46505,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -46520,7 +46521,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -46536,7 +46537,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -46559,16 +46560,16 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - supportedZoneSources: 'typing.List[ZoneManagement.Enums.ZoneSourceEnum]' = None - zones: 'typing.Optional[typing.List[ZoneManagement.Structs.ZoneInformationStruct]]' = None - timeControl: 'typing.List[ZoneManagement.Structs.ZoneTriggeringTimeControlStruct]' = None - sensitivity: 'uint' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + supportedZoneSources: typing.List[ZoneManagement.Enums.ZoneSourceEnum] = field(default_factory=lambda: []) + zones: typing.Optional[typing.List[ZoneManagement.Structs.ZoneInformationStruct]] = None + timeControl: typing.List[ZoneManagement.Structs.ZoneTriggeringTimeControlStruct] = field(default_factory=lambda: []) + sensitivity: uint = 0 + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class StatusCodeEnum(MatterIntEnum): @@ -46706,14 +46707,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="zone", Tag=0, Type=ZoneManagement.Structs.TwoDCartesianZoneStruct), ]) - zone: 'ZoneManagement.Structs.TwoDCartesianZoneStruct' = field(default_factory=lambda: ZoneManagement.Structs.TwoDCartesianZoneStruct()) + zone: ZoneManagement.Structs.TwoDCartesianZoneStruct = field(default_factory=lambda: ZoneManagement.Structs.TwoDCartesianZoneStruct()) @dataclass class CreateTwoDCartesianZoneResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000550 command_id: typing.ClassVar[int] = 0x00000001 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -46722,14 +46723,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="zoneID", Tag=0, Type=uint), ]) - zoneID: 'uint' = 0 + zoneID: uint = 0 @dataclass class UpdateTwoDCartesianZone(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000550 command_id: typing.ClassVar[int] = 0x00000002 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -46739,8 +46740,8 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="zone", Tag=1, Type=ZoneManagement.Structs.TwoDCartesianZoneStruct), ]) - zoneID: 'uint' = 0 - zone: 'ZoneManagement.Structs.TwoDCartesianZoneStruct' = field(default_factory=lambda: ZoneManagement.Structs.TwoDCartesianZoneStruct()) + zoneID: uint = 0 + zone: ZoneManagement.Structs.TwoDCartesianZoneStruct = field(default_factory=lambda: ZoneManagement.Structs.TwoDCartesianZoneStruct()) @dataclass class GetTwoDCartesianZone(ClusterCommand): @@ -46756,14 +46757,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="zoneID", Tag=0, Type=typing.Union[None, Nullable, uint]), ]) - zoneID: 'typing.Union[None, Nullable, uint]' = None + zoneID: typing.Union[None, Nullable, uint] = None @dataclass class GetTwoDCartesianZoneResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000550 command_id: typing.ClassVar[int] = 0x00000004 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -46772,14 +46773,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="zones", Tag=0, Type=typing.List[ZoneManagement.Structs.TwoDCartesianZoneStruct]), ]) - zones: 'typing.List[ZoneManagement.Structs.TwoDCartesianZoneStruct]' = field(default_factory=lambda: []) + zones: typing.List[ZoneManagement.Structs.TwoDCartesianZoneStruct] = field(default_factory=lambda: []) @dataclass class RemoveZone(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000550 command_id: typing.ClassVar[int] = 0x00000005 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -46788,7 +46789,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="zoneID", Tag=0, Type=uint), ]) - zoneID: 'uint' = 0 + zoneID: uint = 0 class Attributes: @dataclass @@ -46805,7 +46806,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[ZoneManagement.Enums.ZoneSourceEnum]) - value: 'typing.List[ZoneManagement.Enums.ZoneSourceEnum]' = field(default_factory=lambda: []) + value: typing.List[ZoneManagement.Enums.ZoneSourceEnum] = field(default_factory=lambda: []) @dataclass class Zones(ClusterAttributeDescriptor): @@ -46821,7 +46822,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[typing.List[ZoneManagement.Structs.ZoneInformationStruct]]) - value: 'typing.Optional[typing.List[ZoneManagement.Structs.ZoneInformationStruct]]' = None + value: typing.Optional[typing.List[ZoneManagement.Structs.ZoneInformationStruct]] = None @dataclass class TimeControl(ClusterAttributeDescriptor): @@ -46837,7 +46838,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[ZoneManagement.Structs.ZoneTriggeringTimeControlStruct]) - value: 'typing.List[ZoneManagement.Structs.ZoneTriggeringTimeControlStruct]' = field(default_factory=lambda: []) + value: typing.List[ZoneManagement.Structs.ZoneTriggeringTimeControlStruct] = field(default_factory=lambda: []) @dataclass class Sensitivity(ClusterAttributeDescriptor): @@ -46853,7 +46854,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -46869,7 +46870,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -46885,7 +46886,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -46901,7 +46902,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -46917,7 +46918,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -46933,7 +46934,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -46949,7 +46950,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 class Events: @dataclass @@ -46970,8 +46971,8 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="reason", Tag=1, Type=ZoneManagement.Enums.ZoneEventTriggeredReasonEnum), ]) - zones: 'typing.List[uint]' = field(default_factory=lambda: []) - reason: 'ZoneManagement.Enums.ZoneEventTriggeredReasonEnum' = 0 + zones: typing.List[uint] = field(default_factory=lambda: []) + reason: ZoneManagement.Enums.ZoneEventTriggeredReasonEnum = 0 @dataclass class ZoneStopped(ClusterEvent): @@ -46991,8 +46992,8 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="reason", Tag=1, Type=ZoneManagement.Enums.ZoneEventStoppedReasonEnum), ]) - zones: 'typing.List[uint]' = field(default_factory=lambda: []) - reason: 'ZoneManagement.Enums.ZoneEventStoppedReasonEnum' = 0 + zones: typing.List[uint] = field(default_factory=lambda: []) + reason: ZoneManagement.Enums.ZoneEventStoppedReasonEnum = 0 @dataclass @@ -47058,59 +47059,59 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - maxConcurrentVideoEncoders: 'typing.Optional[uint]' = None - maxEncodedPixelRate: 'typing.Optional[uint]' = None - videoSensorParams: 'typing.Optional[CameraAvStreamManagement.Structs.VideoSensorParamsStruct]' = None - nightVisionCapable: 'typing.Optional[bool]' = None - minViewport: 'typing.Optional[CameraAvStreamManagement.Structs.VideoResolutionStruct]' = None - rateDistortionTradeOffPoints: 'typing.Optional[typing.List[CameraAvStreamManagement.Structs.RateDistortionTradeOffPointsStruct]]' = None - maxPreRollBufferSize: 'typing.Optional[uint]' = None - microphoneCapabilities: 'typing.Optional[CameraAvStreamManagement.Structs.AudioCapabilitiesStruct]' = None - speakerCapabilities: 'typing.Optional[CameraAvStreamManagement.Structs.AudioCapabilitiesStruct]' = None - twoWayTalkSupport: 'typing.Optional[CameraAvStreamManagement.Enums.TwoWayTalkSupportTypeEnum]' = None - supportedSnapshotParams: 'typing.Optional[typing.List[CameraAvStreamManagement.Structs.SnapshotParamsStruct]]' = None - maxNetworkBandwidth: 'uint' = None - currentFrameRate: 'typing.Optional[uint]' = None - HDRModeEnabled: 'typing.Optional[bool]' = None - currentVideoCodecs: 'typing.Optional[typing.List[CameraAvStreamManagement.Enums.VideoCodecEnum]]' = None - currentSnapshotConfig: 'typing.Optional[CameraAvStreamManagement.Structs.SnapshotParamsStruct]' = None - fabricsUsingCamera: 'typing.List[uint]' = None - allocatedVideoStreams: 'typing.Optional[typing.List[CameraAvStreamManagement.Structs.VideoStreamStruct]]' = None - allocatedAudioStreams: 'typing.Optional[typing.List[CameraAvStreamManagement.Structs.AudioStreamStruct]]' = None - allocatedSnapshotStreams: 'typing.Optional[typing.List[CameraAvStreamManagement.Structs.SnapshotStreamStruct]]' = None - rankedVideoStreamPrioritiesList: 'typing.Optional[typing.List[CameraAvStreamManagement.Enums.StreamTypeEnum]]' = None - softRecordingPrivacyModeEnabled: 'typing.Optional[bool]' = None - softLivestreamPrivacyModeEnabled: 'typing.Optional[bool]' = None - hardPrivacyModeOn: 'typing.Optional[bool]' = None - nightVision: 'typing.Optional[CameraAvStreamManagement.Enums.TriStateAutoEnum]' = None - nightVisionIllum: 'typing.Optional[CameraAvStreamManagement.Enums.TriStateAutoEnum]' = None - AWBEnabled: 'typing.Optional[bool]' = None - autoShutterSpeedEnabled: 'typing.Optional[bool]' = None - autoISOEnabled: 'typing.Optional[bool]' = None - viewport: 'typing.Optional[CameraAvStreamManagement.Structs.ViewportStruct]' = None - speakerMuted: 'typing.Optional[bool]' = None - speakerVolumeLevel: 'typing.Optional[uint]' = None - speakerMaxLevel: 'typing.Optional[uint]' = None - speakerMinLevel: 'typing.Optional[uint]' = None - microphoneMuted: 'typing.Optional[bool]' = None - microphoneVolumeLevel: 'typing.Optional[uint]' = None - microphoneMaxLevel: 'typing.Optional[uint]' = None - microphoneMinLevel: 'typing.Optional[uint]' = None - microphoneAGCEnabled: 'typing.Optional[bool]' = None - imageRotation: 'typing.Optional[uint]' = None - imageFlipHorizontal: 'typing.Optional[bool]' = None - imageFlipVertical: 'typing.Optional[bool]' = None - localVideoRecordingEnabled: 'typing.Optional[bool]' = None - localSnapshotRecordingEnabled: 'typing.Optional[bool]' = None - statusLightEnabled: 'typing.Optional[bool]' = None - statusLightBrightness: 'typing.Optional[Globals.Enums.ThreeLevelAutoEnum]' = None - depthSensorStatus: 'typing.Optional[CameraAvStreamManagement.Enums.TriStateAutoEnum]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + maxConcurrentVideoEncoders: typing.Optional[uint] = None + maxEncodedPixelRate: typing.Optional[uint] = None + videoSensorParams: typing.Optional[CameraAvStreamManagement.Structs.VideoSensorParamsStruct] = None + nightVisionCapable: typing.Optional[bool] = None + minViewport: typing.Optional[CameraAvStreamManagement.Structs.VideoResolutionStruct] = None + rateDistortionTradeOffPoints: typing.Optional[typing.List[CameraAvStreamManagement.Structs.RateDistortionTradeOffPointsStruct]] = None + maxPreRollBufferSize: typing.Optional[uint] = None + microphoneCapabilities: typing.Optional[CameraAvStreamManagement.Structs.AudioCapabilitiesStruct] = None + speakerCapabilities: typing.Optional[CameraAvStreamManagement.Structs.AudioCapabilitiesStruct] = None + twoWayTalkSupport: typing.Optional[CameraAvStreamManagement.Enums.TwoWayTalkSupportTypeEnum] = None + supportedSnapshotParams: typing.Optional[typing.List[CameraAvStreamManagement.Structs.SnapshotParamsStruct]] = None + maxNetworkBandwidth: uint = 0 + currentFrameRate: typing.Optional[uint] = None + HDRModeEnabled: typing.Optional[bool] = None + currentVideoCodecs: typing.Optional[typing.List[CameraAvStreamManagement.Enums.VideoCodecEnum]] = None + currentSnapshotConfig: typing.Optional[CameraAvStreamManagement.Structs.SnapshotParamsStruct] = None + fabricsUsingCamera: typing.List[uint] = field(default_factory=lambda: []) + allocatedVideoStreams: typing.Optional[typing.List[CameraAvStreamManagement.Structs.VideoStreamStruct]] = None + allocatedAudioStreams: typing.Optional[typing.List[CameraAvStreamManagement.Structs.AudioStreamStruct]] = None + allocatedSnapshotStreams: typing.Optional[typing.List[CameraAvStreamManagement.Structs.SnapshotStreamStruct]] = None + rankedVideoStreamPrioritiesList: typing.Optional[typing.List[CameraAvStreamManagement.Enums.StreamTypeEnum]] = None + softRecordingPrivacyModeEnabled: typing.Optional[bool] = None + softLivestreamPrivacyModeEnabled: typing.Optional[bool] = None + hardPrivacyModeOn: typing.Optional[bool] = None + nightVision: typing.Optional[CameraAvStreamManagement.Enums.TriStateAutoEnum] = None + nightVisionIllum: typing.Optional[CameraAvStreamManagement.Enums.TriStateAutoEnum] = None + AWBEnabled: typing.Optional[bool] = None + autoShutterSpeedEnabled: typing.Optional[bool] = None + autoISOEnabled: typing.Optional[bool] = None + viewport: typing.Optional[CameraAvStreamManagement.Structs.ViewportStruct] = None + speakerMuted: typing.Optional[bool] = None + speakerVolumeLevel: typing.Optional[uint] = None + speakerMaxLevel: typing.Optional[uint] = None + speakerMinLevel: typing.Optional[uint] = None + microphoneMuted: typing.Optional[bool] = None + microphoneVolumeLevel: typing.Optional[uint] = None + microphoneMaxLevel: typing.Optional[uint] = None + microphoneMinLevel: typing.Optional[uint] = None + microphoneAGCEnabled: typing.Optional[bool] = None + imageRotation: typing.Optional[uint] = None + imageFlipHorizontal: typing.Optional[bool] = None + imageFlipVertical: typing.Optional[bool] = None + localVideoRecordingEnabled: typing.Optional[bool] = None + localSnapshotRecordingEnabled: typing.Optional[bool] = None + statusLightEnabled: typing.Optional[bool] = None + statusLightBrightness: typing.Optional[Globals.Enums.ThreeLevelAutoEnum] = None + depthSensorStatus: typing.Optional[CameraAvStreamManagement.Enums.TriStateAutoEnum] = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class AudioCodecEnum(MatterIntEnum): @@ -47388,19 +47389,19 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="bitDepth", Tag=5, Type=uint), ]) - streamType: 'CameraAvStreamManagement.Enums.StreamTypeEnum' = 0 - audioCodec: 'CameraAvStreamManagement.Enums.AudioCodecEnum' = 0 - channelCount: 'uint' = 0 - sampleRate: 'uint' = 0 - bitRate: 'uint' = 0 - bitDepth: 'uint' = 0 + streamType: CameraAvStreamManagement.Enums.StreamTypeEnum = 0 + audioCodec: CameraAvStreamManagement.Enums.AudioCodecEnum = 0 + channelCount: uint = 0 + sampleRate: uint = 0 + bitRate: uint = 0 + bitDepth: uint = 0 @dataclass class AudioStreamAllocateResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000551 command_id: typing.ClassVar[int] = 0x00000001 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -47409,14 +47410,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="audioStreamID", Tag=0, Type=uint), ]) - audioStreamID: 'uint' = 0 + audioStreamID: uint = 0 @dataclass class AudioStreamDeallocate(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000551 command_id: typing.ClassVar[int] = 0x00000002 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -47425,7 +47426,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="audioStreamID", Tag=0, Type=uint), ]) - audioStreamID: 'uint' = 0 + audioStreamID: uint = 0 @dataclass class VideoStreamAllocate(ClusterCommand): @@ -47452,25 +47453,25 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="OSDEnabled", Tag=11, Type=typing.Optional[bool]), ]) - streamType: 'CameraAvStreamManagement.Enums.StreamTypeEnum' = 0 - videoCodec: 'CameraAvStreamManagement.Enums.VideoCodecEnum' = 0 - minFrameRate: 'uint' = 0 - maxFrameRate: 'uint' = 0 - minResolution: 'CameraAvStreamManagement.Structs.VideoResolutionStruct' = field(default_factory=lambda: CameraAvStreamManagement.Structs.VideoResolutionStruct()) - maxResolution: 'CameraAvStreamManagement.Structs.VideoResolutionStruct' = field(default_factory=lambda: CameraAvStreamManagement.Structs.VideoResolutionStruct()) - minBitRate: 'uint' = 0 - maxBitRate: 'uint' = 0 - minFragmentLen: 'uint' = 0 - maxFragmentLen: 'uint' = 0 - watermarkEnabled: 'typing.Optional[bool]' = None - OSDEnabled: 'typing.Optional[bool]' = None + streamType: CameraAvStreamManagement.Enums.StreamTypeEnum = 0 + videoCodec: CameraAvStreamManagement.Enums.VideoCodecEnum = 0 + minFrameRate: uint = 0 + maxFrameRate: uint = 0 + minResolution: CameraAvStreamManagement.Structs.VideoResolutionStruct = field(default_factory=lambda: CameraAvStreamManagement.Structs.VideoResolutionStruct()) + maxResolution: CameraAvStreamManagement.Structs.VideoResolutionStruct = field(default_factory=lambda: CameraAvStreamManagement.Structs.VideoResolutionStruct()) + minBitRate: uint = 0 + maxBitRate: uint = 0 + minFragmentLen: uint = 0 + maxFragmentLen: uint = 0 + watermarkEnabled: typing.Optional[bool] = None + OSDEnabled: typing.Optional[bool] = None @dataclass class VideoStreamAllocateResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000551 command_id: typing.ClassVar[int] = 0x00000004 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -47479,14 +47480,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="videoStreamID", Tag=0, Type=uint), ]) - videoStreamID: 'uint' = 0 + videoStreamID: uint = 0 @dataclass class VideoStreamModify(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000551 command_id: typing.ClassVar[int] = 0x00000005 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -47498,17 +47499,17 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="OSDEnabled", Tag=3, Type=typing.Optional[bool]), ]) - videoStreamID: 'uint' = 0 - resolution: 'typing.Optional[CameraAvStreamManagement.Structs.VideoResolutionStruct]' = None - watermarkEnabled: 'typing.Optional[bool]' = None - OSDEnabled: 'typing.Optional[bool]' = None + videoStreamID: uint = 0 + resolution: typing.Optional[CameraAvStreamManagement.Structs.VideoResolutionStruct] = None + watermarkEnabled: typing.Optional[bool] = None + OSDEnabled: typing.Optional[bool] = None @dataclass class VideoStreamDeallocate(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000551 command_id: typing.ClassVar[int] = 0x00000006 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -47517,7 +47518,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="videoStreamID", Tag=0, Type=uint), ]) - videoStreamID: 'uint' = 0 + videoStreamID: uint = 0 @dataclass class SnapshotStreamAllocate(ClusterCommand): @@ -47538,19 +47539,19 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="quality", Tag=5, Type=uint), ]) - imageCodec: 'CameraAvStreamManagement.Enums.ImageCodecEnum' = 0 - frameRate: 'uint' = 0 - bitRate: 'uint' = 0 - minResolution: 'CameraAvStreamManagement.Structs.VideoResolutionStruct' = field(default_factory=lambda: CameraAvStreamManagement.Structs.VideoResolutionStruct()) - maxResolution: 'CameraAvStreamManagement.Structs.VideoResolutionStruct' = field(default_factory=lambda: CameraAvStreamManagement.Structs.VideoResolutionStruct()) - quality: 'uint' = 0 + imageCodec: CameraAvStreamManagement.Enums.ImageCodecEnum = 0 + frameRate: uint = 0 + bitRate: uint = 0 + minResolution: CameraAvStreamManagement.Structs.VideoResolutionStruct = field(default_factory=lambda: CameraAvStreamManagement.Structs.VideoResolutionStruct()) + maxResolution: CameraAvStreamManagement.Structs.VideoResolutionStruct = field(default_factory=lambda: CameraAvStreamManagement.Structs.VideoResolutionStruct()) + quality: uint = 0 @dataclass class SnapshotStreamAllocateResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000551 command_id: typing.ClassVar[int] = 0x00000008 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -47559,14 +47560,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="snapshotStreamID", Tag=0, Type=uint), ]) - snapshotStreamID: 'uint' = 0 + snapshotStreamID: uint = 0 @dataclass class SnapshotStreamDeallocate(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000551 command_id: typing.ClassVar[int] = 0x00000009 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -47575,14 +47576,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="snapshotStreamID", Tag=0, Type=uint), ]) - snapshotStreamID: 'uint' = 0 + snapshotStreamID: uint = 0 @dataclass class SetStreamPriorities(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000551 command_id: typing.ClassVar[int] = 0x0000000A is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -47591,14 +47592,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="streamPriorities", Tag=0, Type=typing.List[CameraAvStreamManagement.Enums.StreamTypeEnum]), ]) - streamPriorities: 'typing.List[CameraAvStreamManagement.Enums.StreamTypeEnum]' = field(default_factory=lambda: []) + streamPriorities: typing.List[CameraAvStreamManagement.Enums.StreamTypeEnum] = field(default_factory=lambda: []) @dataclass class CaptureSnapshot(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000551 command_id: typing.ClassVar[int] = 0x0000000B is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -47608,15 +47609,15 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="requestedResolution", Tag=1, Type=CameraAvStreamManagement.Structs.VideoResolutionStruct), ]) - snapshotStreamID: 'uint' = 0 - requestedResolution: 'CameraAvStreamManagement.Structs.VideoResolutionStruct' = field(default_factory=lambda: CameraAvStreamManagement.Structs.VideoResolutionStruct()) + snapshotStreamID: uint = 0 + requestedResolution: CameraAvStreamManagement.Structs.VideoResolutionStruct = field(default_factory=lambda: CameraAvStreamManagement.Structs.VideoResolutionStruct()) @dataclass class CaptureSnapshotResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000551 command_id: typing.ClassVar[int] = 0x0000000C is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -47627,16 +47628,16 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="resolution", Tag=2, Type=CameraAvStreamManagement.Structs.VideoResolutionStruct), ]) - data: 'bytes' = b"" - imageCodec: 'CameraAvStreamManagement.Enums.ImageCodecEnum' = 0 - resolution: 'CameraAvStreamManagement.Structs.VideoResolutionStruct' = field(default_factory=lambda: CameraAvStreamManagement.Structs.VideoResolutionStruct()) + data: bytes = b"" + imageCodec: CameraAvStreamManagement.Enums.ImageCodecEnum = 0 + resolution: CameraAvStreamManagement.Structs.VideoResolutionStruct = field(default_factory=lambda: CameraAvStreamManagement.Structs.VideoResolutionStruct()) @dataclass class SetViewport(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000551 command_id: typing.ClassVar[int] = 0x0000000D is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -47645,14 +47646,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="viewport", Tag=0, Type=CameraAvStreamManagement.Structs.ViewportStruct), ]) - viewport: 'CameraAvStreamManagement.Structs.ViewportStruct' = field(default_factory=lambda: CameraAvStreamManagement.Structs.ViewportStruct()) + viewport: CameraAvStreamManagement.Structs.ViewportStruct = field(default_factory=lambda: CameraAvStreamManagement.Structs.ViewportStruct()) @dataclass class SetImageRotation(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000551 command_id: typing.ClassVar[int] = 0x0000000E is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -47661,14 +47662,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="angle", Tag=0, Type=uint), ]) - angle: 'uint' = 0 + angle: uint = 0 @dataclass class SetImageFlipHorizontal(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000551 command_id: typing.ClassVar[int] = 0x0000000F is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -47677,14 +47678,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="enabled", Tag=0, Type=bool), ]) - enabled: 'bool' = False + enabled: bool = False @dataclass class SetImageFlipVertical(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000551 command_id: typing.ClassVar[int] = 0x00000010 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -47693,7 +47694,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="enabled", Tag=0, Type=bool), ]) - enabled: 'bool' = False + enabled: bool = False class Attributes: @dataclass @@ -47710,7 +47711,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class MaxEncodedPixelRate(ClusterAttributeDescriptor): @@ -47726,7 +47727,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class VideoSensorParams(ClusterAttributeDescriptor): @@ -47742,7 +47743,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[CameraAvStreamManagement.Structs.VideoSensorParamsStruct]) - value: 'typing.Optional[CameraAvStreamManagement.Structs.VideoSensorParamsStruct]' = None + value: typing.Optional[CameraAvStreamManagement.Structs.VideoSensorParamsStruct] = None @dataclass class NightVisionCapable(ClusterAttributeDescriptor): @@ -47758,7 +47759,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[bool]) - value: 'typing.Optional[bool]' = None + value: typing.Optional[bool] = None @dataclass class MinViewport(ClusterAttributeDescriptor): @@ -47774,7 +47775,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[CameraAvStreamManagement.Structs.VideoResolutionStruct]) - value: 'typing.Optional[CameraAvStreamManagement.Structs.VideoResolutionStruct]' = None + value: typing.Optional[CameraAvStreamManagement.Structs.VideoResolutionStruct] = None @dataclass class RateDistortionTradeOffPoints(ClusterAttributeDescriptor): @@ -47790,7 +47791,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[typing.List[CameraAvStreamManagement.Structs.RateDistortionTradeOffPointsStruct]]) - value: 'typing.Optional[typing.List[CameraAvStreamManagement.Structs.RateDistortionTradeOffPointsStruct]]' = None + value: typing.Optional[typing.List[CameraAvStreamManagement.Structs.RateDistortionTradeOffPointsStruct]] = None @dataclass class MaxPreRollBufferSize(ClusterAttributeDescriptor): @@ -47806,7 +47807,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class MicrophoneCapabilities(ClusterAttributeDescriptor): @@ -47822,7 +47823,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[CameraAvStreamManagement.Structs.AudioCapabilitiesStruct]) - value: 'typing.Optional[CameraAvStreamManagement.Structs.AudioCapabilitiesStruct]' = None + value: typing.Optional[CameraAvStreamManagement.Structs.AudioCapabilitiesStruct] = None @dataclass class SpeakerCapabilities(ClusterAttributeDescriptor): @@ -47838,7 +47839,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[CameraAvStreamManagement.Structs.AudioCapabilitiesStruct]) - value: 'typing.Optional[CameraAvStreamManagement.Structs.AudioCapabilitiesStruct]' = None + value: typing.Optional[CameraAvStreamManagement.Structs.AudioCapabilitiesStruct] = None @dataclass class TwoWayTalkSupport(ClusterAttributeDescriptor): @@ -47854,7 +47855,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[CameraAvStreamManagement.Enums.TwoWayTalkSupportTypeEnum]) - value: 'typing.Optional[CameraAvStreamManagement.Enums.TwoWayTalkSupportTypeEnum]' = None + value: typing.Optional[CameraAvStreamManagement.Enums.TwoWayTalkSupportTypeEnum] = None @dataclass class SupportedSnapshotParams(ClusterAttributeDescriptor): @@ -47870,7 +47871,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[typing.List[CameraAvStreamManagement.Structs.SnapshotParamsStruct]]) - value: 'typing.Optional[typing.List[CameraAvStreamManagement.Structs.SnapshotParamsStruct]]' = None + value: typing.Optional[typing.List[CameraAvStreamManagement.Structs.SnapshotParamsStruct]] = None @dataclass class MaxNetworkBandwidth(ClusterAttributeDescriptor): @@ -47886,7 +47887,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class CurrentFrameRate(ClusterAttributeDescriptor): @@ -47902,7 +47903,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class HDRModeEnabled(ClusterAttributeDescriptor): @@ -47918,7 +47919,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[bool]) - value: 'typing.Optional[bool]' = None + value: typing.Optional[bool] = None @dataclass class CurrentVideoCodecs(ClusterAttributeDescriptor): @@ -47934,7 +47935,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[typing.List[CameraAvStreamManagement.Enums.VideoCodecEnum]]) - value: 'typing.Optional[typing.List[CameraAvStreamManagement.Enums.VideoCodecEnum]]' = None + value: typing.Optional[typing.List[CameraAvStreamManagement.Enums.VideoCodecEnum]] = None @dataclass class CurrentSnapshotConfig(ClusterAttributeDescriptor): @@ -47950,7 +47951,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[CameraAvStreamManagement.Structs.SnapshotParamsStruct]) - value: 'typing.Optional[CameraAvStreamManagement.Structs.SnapshotParamsStruct]' = None + value: typing.Optional[CameraAvStreamManagement.Structs.SnapshotParamsStruct] = None @dataclass class FabricsUsingCamera(ClusterAttributeDescriptor): @@ -47966,7 +47967,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AllocatedVideoStreams(ClusterAttributeDescriptor): @@ -47982,7 +47983,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[typing.List[CameraAvStreamManagement.Structs.VideoStreamStruct]]) - value: 'typing.Optional[typing.List[CameraAvStreamManagement.Structs.VideoStreamStruct]]' = None + value: typing.Optional[typing.List[CameraAvStreamManagement.Structs.VideoStreamStruct]] = None @dataclass class AllocatedAudioStreams(ClusterAttributeDescriptor): @@ -47998,7 +47999,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[typing.List[CameraAvStreamManagement.Structs.AudioStreamStruct]]) - value: 'typing.Optional[typing.List[CameraAvStreamManagement.Structs.AudioStreamStruct]]' = None + value: typing.Optional[typing.List[CameraAvStreamManagement.Structs.AudioStreamStruct]] = None @dataclass class AllocatedSnapshotStreams(ClusterAttributeDescriptor): @@ -48014,7 +48015,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[typing.List[CameraAvStreamManagement.Structs.SnapshotStreamStruct]]) - value: 'typing.Optional[typing.List[CameraAvStreamManagement.Structs.SnapshotStreamStruct]]' = None + value: typing.Optional[typing.List[CameraAvStreamManagement.Structs.SnapshotStreamStruct]] = None @dataclass class RankedVideoStreamPrioritiesList(ClusterAttributeDescriptor): @@ -48030,7 +48031,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[typing.List[CameraAvStreamManagement.Enums.StreamTypeEnum]]) - value: 'typing.Optional[typing.List[CameraAvStreamManagement.Enums.StreamTypeEnum]]' = None + value: typing.Optional[typing.List[CameraAvStreamManagement.Enums.StreamTypeEnum]] = None @dataclass class SoftRecordingPrivacyModeEnabled(ClusterAttributeDescriptor): @@ -48046,7 +48047,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[bool]) - value: 'typing.Optional[bool]' = None + value: typing.Optional[bool] = None @dataclass class SoftLivestreamPrivacyModeEnabled(ClusterAttributeDescriptor): @@ -48062,7 +48063,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[bool]) - value: 'typing.Optional[bool]' = None + value: typing.Optional[bool] = None @dataclass class HardPrivacyModeOn(ClusterAttributeDescriptor): @@ -48078,7 +48079,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[bool]) - value: 'typing.Optional[bool]' = None + value: typing.Optional[bool] = None @dataclass class NightVision(ClusterAttributeDescriptor): @@ -48094,7 +48095,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[CameraAvStreamManagement.Enums.TriStateAutoEnum]) - value: 'typing.Optional[CameraAvStreamManagement.Enums.TriStateAutoEnum]' = None + value: typing.Optional[CameraAvStreamManagement.Enums.TriStateAutoEnum] = None @dataclass class NightVisionIllum(ClusterAttributeDescriptor): @@ -48110,7 +48111,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[CameraAvStreamManagement.Enums.TriStateAutoEnum]) - value: 'typing.Optional[CameraAvStreamManagement.Enums.TriStateAutoEnum]' = None + value: typing.Optional[CameraAvStreamManagement.Enums.TriStateAutoEnum] = None @dataclass class AWBEnabled(ClusterAttributeDescriptor): @@ -48126,7 +48127,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[bool]) - value: 'typing.Optional[bool]' = None + value: typing.Optional[bool] = None @dataclass class AutoShutterSpeedEnabled(ClusterAttributeDescriptor): @@ -48142,7 +48143,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[bool]) - value: 'typing.Optional[bool]' = None + value: typing.Optional[bool] = None @dataclass class AutoISOEnabled(ClusterAttributeDescriptor): @@ -48158,7 +48159,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[bool]) - value: 'typing.Optional[bool]' = None + value: typing.Optional[bool] = None @dataclass class Viewport(ClusterAttributeDescriptor): @@ -48174,7 +48175,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[CameraAvStreamManagement.Structs.ViewportStruct]) - value: 'typing.Optional[CameraAvStreamManagement.Structs.ViewportStruct]' = None + value: typing.Optional[CameraAvStreamManagement.Structs.ViewportStruct] = None @dataclass class SpeakerMuted(ClusterAttributeDescriptor): @@ -48190,7 +48191,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[bool]) - value: 'typing.Optional[bool]' = None + value: typing.Optional[bool] = None @dataclass class SpeakerVolumeLevel(ClusterAttributeDescriptor): @@ -48206,7 +48207,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class SpeakerMaxLevel(ClusterAttributeDescriptor): @@ -48222,7 +48223,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class SpeakerMinLevel(ClusterAttributeDescriptor): @@ -48238,7 +48239,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class MicrophoneMuted(ClusterAttributeDescriptor): @@ -48254,7 +48255,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[bool]) - value: 'typing.Optional[bool]' = None + value: typing.Optional[bool] = None @dataclass class MicrophoneVolumeLevel(ClusterAttributeDescriptor): @@ -48270,7 +48271,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class MicrophoneMaxLevel(ClusterAttributeDescriptor): @@ -48286,7 +48287,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class MicrophoneMinLevel(ClusterAttributeDescriptor): @@ -48302,7 +48303,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class MicrophoneAGCEnabled(ClusterAttributeDescriptor): @@ -48318,7 +48319,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[bool]) - value: 'typing.Optional[bool]' = None + value: typing.Optional[bool] = None @dataclass class ImageRotation(ClusterAttributeDescriptor): @@ -48334,7 +48335,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class ImageFlipHorizontal(ClusterAttributeDescriptor): @@ -48350,7 +48351,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[bool]) - value: 'typing.Optional[bool]' = None + value: typing.Optional[bool] = None @dataclass class ImageFlipVertical(ClusterAttributeDescriptor): @@ -48366,7 +48367,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[bool]) - value: 'typing.Optional[bool]' = None + value: typing.Optional[bool] = None @dataclass class LocalVideoRecordingEnabled(ClusterAttributeDescriptor): @@ -48382,7 +48383,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[bool]) - value: 'typing.Optional[bool]' = None + value: typing.Optional[bool] = None @dataclass class LocalSnapshotRecordingEnabled(ClusterAttributeDescriptor): @@ -48398,7 +48399,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[bool]) - value: 'typing.Optional[bool]' = None + value: typing.Optional[bool] = None @dataclass class StatusLightEnabled(ClusterAttributeDescriptor): @@ -48414,7 +48415,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[bool]) - value: 'typing.Optional[bool]' = None + value: typing.Optional[bool] = None @dataclass class StatusLightBrightness(ClusterAttributeDescriptor): @@ -48430,7 +48431,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[Globals.Enums.ThreeLevelAutoEnum]) - value: 'typing.Optional[Globals.Enums.ThreeLevelAutoEnum]' = None + value: typing.Optional[Globals.Enums.ThreeLevelAutoEnum] = None @dataclass class DepthSensorStatus(ClusterAttributeDescriptor): @@ -48446,7 +48447,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[CameraAvStreamManagement.Enums.TriStateAutoEnum]) - value: 'typing.Optional[CameraAvStreamManagement.Enums.TriStateAutoEnum]' = None + value: typing.Optional[CameraAvStreamManagement.Enums.TriStateAutoEnum] = None @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -48462,7 +48463,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -48478,7 +48479,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -48494,7 +48495,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -48510,7 +48511,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -48526,7 +48527,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -48542,7 +48543,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 class Events: @dataclass @@ -48572,17 +48573,17 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="maxFragmentLen", Tag=10, Type=typing.Optional[uint]), ]) - videoStreamID: 'uint' = 0 - streamType: 'typing.Optional[CameraAvStreamManagement.Enums.StreamTypeEnum]' = None - videoCodec: 'typing.Optional[CameraAvStreamManagement.Enums.VideoCodecEnum]' = None - minFrameRate: 'typing.Optional[uint]' = None - maxFrameRate: 'typing.Optional[uint]' = None - minResolution: 'typing.Optional[CameraAvStreamManagement.Structs.VideoResolutionStruct]' = None - maxResolution: 'typing.Optional[CameraAvStreamManagement.Structs.VideoResolutionStruct]' = None - minBitRate: 'typing.Optional[uint]' = None - maxBitRate: 'typing.Optional[uint]' = None - minFragmentLen: 'typing.Optional[uint]' = None - maxFragmentLen: 'typing.Optional[uint]' = None + videoStreamID: uint = 0 + streamType: typing.Optional[CameraAvStreamManagement.Enums.StreamTypeEnum] = None + videoCodec: typing.Optional[CameraAvStreamManagement.Enums.VideoCodecEnum] = None + minFrameRate: typing.Optional[uint] = None + maxFrameRate: typing.Optional[uint] = None + minResolution: typing.Optional[CameraAvStreamManagement.Structs.VideoResolutionStruct] = None + maxResolution: typing.Optional[CameraAvStreamManagement.Structs.VideoResolutionStruct] = None + minBitRate: typing.Optional[uint] = None + maxBitRate: typing.Optional[uint] = None + minFragmentLen: typing.Optional[uint] = None + maxFragmentLen: typing.Optional[uint] = None @dataclass class AudioStreamChanged(ClusterEvent): @@ -48607,13 +48608,13 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="bitDepth", Tag=6, Type=typing.Optional[uint]), ]) - audioStreamID: 'uint' = 0 - streamType: 'typing.Optional[CameraAvStreamManagement.Enums.StreamTypeEnum]' = None - audioCodec: 'typing.Optional[CameraAvStreamManagement.Enums.AudioCodecEnum]' = None - channelCount: 'typing.Optional[uint]' = None - sampleRate: 'typing.Optional[uint]' = None - bitRate: 'typing.Optional[uint]' = None - bitDepth: 'typing.Optional[uint]' = None + audioStreamID: uint = 0 + streamType: typing.Optional[CameraAvStreamManagement.Enums.StreamTypeEnum] = None + audioCodec: typing.Optional[CameraAvStreamManagement.Enums.AudioCodecEnum] = None + channelCount: typing.Optional[uint] = None + sampleRate: typing.Optional[uint] = None + bitRate: typing.Optional[uint] = None + bitDepth: typing.Optional[uint] = None @dataclass class SnapshotStreamChanged(ClusterEvent): @@ -48638,13 +48639,13 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="quality", Tag=6, Type=typing.Optional[uint]), ]) - snapshotStreamID: 'uint' = 0 - imageCodec: 'typing.Optional[CameraAvStreamManagement.Enums.ImageCodecEnum]' = None - frameRate: 'typing.Optional[uint]' = None - bitRate: 'typing.Optional[uint]' = None - minResolution: 'typing.Optional[CameraAvStreamManagement.Structs.VideoResolutionStruct]' = None - maxResolution: 'typing.Optional[CameraAvStreamManagement.Structs.VideoResolutionStruct]' = None - quality: 'typing.Optional[uint]' = None + snapshotStreamID: uint = 0 + imageCodec: typing.Optional[CameraAvStreamManagement.Enums.ImageCodecEnum] = None + frameRate: typing.Optional[uint] = None + bitRate: typing.Optional[uint] = None + minResolution: typing.Optional[CameraAvStreamManagement.Structs.VideoResolutionStruct] = None + maxResolution: typing.Optional[CameraAvStreamManagement.Structs.VideoResolutionStruct] = None + quality: typing.Optional[uint] = None @dataclass @@ -48664,13 +48665,13 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - currentSessions: 'typing.List[WebRTCTransportProvider.Structs.WebRTCSessionStruct]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + currentSessions: typing.List[WebRTCTransportProvider.Structs.WebRTCSessionStruct] = field(default_factory=lambda: []) + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class StreamTypeEnum(MatterIntEnum): @@ -48768,19 +48769,19 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="metadataOptions", Tag=5, Type=typing.Optional[uint]), ]) - streamType: 'WebRTCTransportProvider.Enums.StreamTypeEnum' = 0 - videoStreamID: 'typing.Union[None, Nullable, uint]' = None - audioStreamID: 'typing.Union[None, Nullable, uint]' = None - ICEServers: 'typing.Optional[typing.List[WebRTCTransportProvider.Structs.ICEServerStruct]]' = None - ICETransportPolicy: 'typing.Optional[str]' = None - metadataOptions: 'typing.Optional[uint]' = None + streamType: WebRTCTransportProvider.Enums.StreamTypeEnum = 0 + videoStreamID: typing.Union[None, Nullable, uint] = None + audioStreamID: typing.Union[None, Nullable, uint] = None + ICEServers: typing.Optional[typing.List[WebRTCTransportProvider.Structs.ICEServerStruct]] = None + ICETransportPolicy: typing.Optional[str] = None + metadataOptions: typing.Optional[uint] = None @dataclass class SolicitOfferResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000553 command_id: typing.ClassVar[int] = 0x00000002 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -48792,10 +48793,10 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="audioStreamID", Tag=3, Type=typing.Union[None, Nullable, uint]), ]) - webRTCSessionID: 'uint' = 0 - deferredOffer: 'bool' = False - videoStreamID: 'typing.Union[None, Nullable, uint]' = None - audioStreamID: 'typing.Union[None, Nullable, uint]' = None + webRTCSessionID: uint = 0 + deferredOffer: bool = False + videoStreamID: typing.Union[None, Nullable, uint] = None + audioStreamID: typing.Union[None, Nullable, uint] = None @dataclass class ProvideOffer(ClusterCommand): @@ -48818,21 +48819,21 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="metadataOptions", Tag=7, Type=typing.Optional[uint]), ]) - webRTCSessionID: 'typing.Union[Nullable, uint]' = NullValue - sdp: 'str' = "" - streamType: 'WebRTCTransportProvider.Enums.StreamTypeEnum' = 0 - videoStreamID: 'typing.Union[None, Nullable, uint]' = None - audioStreamID: 'typing.Union[None, Nullable, uint]' = None - ICEServers: 'typing.Optional[typing.List[WebRTCTransportProvider.Structs.ICEServerStruct]]' = None - ICETransportPolicy: 'typing.Optional[str]' = None - metadataOptions: 'typing.Optional[uint]' = None + webRTCSessionID: typing.Union[Nullable, uint] = NullValue + sdp: str = "" + streamType: WebRTCTransportProvider.Enums.StreamTypeEnum = 0 + videoStreamID: typing.Union[None, Nullable, uint] = None + audioStreamID: typing.Union[None, Nullable, uint] = None + ICEServers: typing.Optional[typing.List[WebRTCTransportProvider.Structs.ICEServerStruct]] = None + ICETransportPolicy: typing.Optional[str] = None + metadataOptions: typing.Optional[uint] = None @dataclass class ProvideOfferResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000553 command_id: typing.ClassVar[int] = 0x00000004 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -48843,16 +48844,16 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="audioStreamID", Tag=2, Type=uint), ]) - webRTCSessionID: 'uint' = 0 - videoStreamID: 'uint' = 0 - audioStreamID: 'uint' = 0 + webRTCSessionID: uint = 0 + videoStreamID: uint = 0 + audioStreamID: uint = 0 @dataclass class ProvideAnswer(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000553 command_id: typing.ClassVar[int] = 0x00000005 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -48862,15 +48863,15 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="sdp", Tag=1, Type=str), ]) - webRTCSessionID: 'uint' = 0 - sdp: 'str' = "" + webRTCSessionID: uint = 0 + sdp: str = "" @dataclass class ProvideICECandidate(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000553 command_id: typing.ClassVar[int] = 0x00000006 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -48880,15 +48881,15 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="ICECandidate", Tag=1, Type=str), ]) - webRTCSessionID: 'uint' = 0 - ICECandidate: 'str' = "" + webRTCSessionID: uint = 0 + ICECandidate: str = "" @dataclass class EndSession(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000553 command_id: typing.ClassVar[int] = 0x00000007 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -48898,8 +48899,8 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="reason", Tag=1, Type=WebRTCTransportProvider.Enums.WebRTCEndReasonEnum), ]) - webRTCSessionID: 'uint' = 0 - reason: 'WebRTCTransportProvider.Enums.WebRTCEndReasonEnum' = 0 + webRTCSessionID: uint = 0 + reason: WebRTCTransportProvider.Enums.WebRTCEndReasonEnum = 0 class Attributes: @dataclass @@ -48916,7 +48917,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[WebRTCTransportProvider.Structs.WebRTCSessionStruct]) - value: 'typing.List[WebRTCTransportProvider.Structs.WebRTCSessionStruct]' = field(default_factory=lambda: []) + value: typing.List[WebRTCTransportProvider.Structs.WebRTCSessionStruct] = field(default_factory=lambda: []) @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -48932,7 +48933,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -48948,7 +48949,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -48964,7 +48965,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -48980,7 +48981,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -48996,7 +48997,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -49012,7 +49013,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -49032,13 +49033,13 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - currentSessions: 'typing.List[WebRTCTransportRequestor.Structs.WebRTCSessionStruct]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + currentSessions: typing.List[WebRTCTransportRequestor.Structs.WebRTCSessionStruct] = field(default_factory=lambda: []) + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class StreamTypeEnum(MatterIntEnum): @@ -49122,7 +49123,7 @@ class Offer(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000554 command_id: typing.ClassVar[int] = 0x00000001 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -49134,17 +49135,17 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="ICETransportPolicy", Tag=3, Type=typing.Optional[str]), ]) - webRTCSessionID: 'uint' = 0 - sdp: 'str' = "" - ICEServers: 'typing.Optional[typing.List[WebRTCTransportRequestor.Structs.ICEServerStruct]]' = None - ICETransportPolicy: 'typing.Optional[str]' = None + webRTCSessionID: uint = 0 + sdp: str = "" + ICEServers: typing.Optional[typing.List[WebRTCTransportRequestor.Structs.ICEServerStruct]] = None + ICETransportPolicy: typing.Optional[str] = None @dataclass class Answer(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000554 command_id: typing.ClassVar[int] = 0x00000002 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -49154,15 +49155,15 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="sdp", Tag=1, Type=str), ]) - webRTCSessionID: 'uint' = 0 - sdp: 'str' = "" + webRTCSessionID: uint = 0 + sdp: str = "" @dataclass class ICECandidate(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000554 command_id: typing.ClassVar[int] = 0x00000003 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -49172,15 +49173,15 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="ICECandidate", Tag=1, Type=str), ]) - webRTCSessionID: 'uint' = 0 - ICECandidate: 'str' = "" + webRTCSessionID: uint = 0 + ICECandidate: str = "" @dataclass class End(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000554 command_id: typing.ClassVar[int] = 0x00000004 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -49190,8 +49191,8 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="reason", Tag=1, Type=WebRTCTransportRequestor.Enums.WebRTCEndReasonEnum), ]) - webRTCSessionID: 'uint' = 0 - reason: 'WebRTCTransportRequestor.Enums.WebRTCEndReasonEnum' = 0 + webRTCSessionID: uint = 0 + reason: WebRTCTransportRequestor.Enums.WebRTCEndReasonEnum = 0 class Attributes: @dataclass @@ -49208,7 +49209,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[WebRTCTransportRequestor.Structs.WebRTCSessionStruct]) - value: 'typing.List[WebRTCTransportRequestor.Structs.WebRTCSessionStruct]' = field(default_factory=lambda: []) + value: typing.List[WebRTCTransportRequestor.Structs.WebRTCSessionStruct] = field(default_factory=lambda: []) @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -49224,7 +49225,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -49240,7 +49241,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -49256,7 +49257,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -49272,7 +49273,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -49288,7 +49289,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -49304,7 +49305,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -49326,15 +49327,15 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - installedChimeSounds: 'typing.List[Chime.Structs.ChimeSoundStruct]' = None - activeChimeID: 'uint' = None - enabled: 'bool' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + installedChimeSounds: typing.List[Chime.Structs.ChimeSoundStruct] = field(default_factory=lambda: []) + activeChimeID: uint = 0 + enabled: bool = False + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Structs: @dataclass @@ -49356,7 +49357,7 @@ class PlayChimeSound(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000556 command_id: typing.ClassVar[int] = 0x00000000 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -49379,7 +49380,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[Chime.Structs.ChimeSoundStruct]) - value: 'typing.List[Chime.Structs.ChimeSoundStruct]' = field(default_factory=lambda: []) + value: typing.List[Chime.Structs.ChimeSoundStruct] = field(default_factory=lambda: []) @dataclass class ActiveChimeID(ClusterAttributeDescriptor): @@ -49395,7 +49396,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class Enabled(ClusterAttributeDescriptor): @@ -49411,7 +49412,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=bool) - value: 'bool' = False + value: bool = False @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -49427,7 +49428,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -49443,7 +49444,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -49459,7 +49460,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -49475,7 +49476,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -49491,7 +49492,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -49507,7 +49508,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -49528,14 +49529,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - deviceDirectory: 'typing.List[EcosystemInformation.Structs.EcosystemDeviceStruct]' = None - locationDirectory: 'typing.List[EcosystemInformation.Structs.EcosystemLocationStruct]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + deviceDirectory: typing.List[EcosystemInformation.Structs.EcosystemDeviceStruct] = field(default_factory=lambda: []) + locationDirectory: typing.List[EcosystemInformation.Structs.EcosystemLocationStruct] = field(default_factory=lambda: []) + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Structs: @dataclass @@ -49608,7 +49609,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[EcosystemInformation.Structs.EcosystemDeviceStruct]) - value: 'typing.List[EcosystemInformation.Structs.EcosystemDeviceStruct]' = field(default_factory=lambda: []) + value: typing.List[EcosystemInformation.Structs.EcosystemDeviceStruct] = field(default_factory=lambda: []) @dataclass class LocationDirectory(ClusterAttributeDescriptor): @@ -49624,7 +49625,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[EcosystemInformation.Structs.EcosystemLocationStruct]) - value: 'typing.List[EcosystemInformation.Structs.EcosystemLocationStruct]' = field(default_factory=lambda: []) + value: typing.List[EcosystemInformation.Structs.EcosystemLocationStruct] = field(default_factory=lambda: []) @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -49640,7 +49641,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -49656,7 +49657,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -49672,7 +49673,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -49688,7 +49689,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -49704,7 +49705,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -49720,7 +49721,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -49740,13 +49741,13 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - supportedDeviceCategories: 'uint' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + supportedDeviceCategories: uint = 0 + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Bitmaps: class SupportedDeviceCategoryBitmap(IntFlag): @@ -49758,7 +49759,7 @@ class RequestCommissioningApproval(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000751 command_id: typing.ClassVar[int] = 0x00000000 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -49770,10 +49771,10 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="label", Tag=3, Type=typing.Optional[str]), ]) - requestID: 'uint' = 0 - vendorID: 'uint' = 0 - productID: 'uint' = 0 - label: 'typing.Optional[str]' = None + requestID: uint = 0 + vendorID: uint = 0 + productID: uint = 0 + label: typing.Optional[str] = None @dataclass class CommissionNode(ClusterCommand): @@ -49790,15 +49791,15 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="responseTimeoutSeconds", Tag=1, Type=uint), ]) - requestID: 'uint' = 0 - responseTimeoutSeconds: 'uint' = 0 + requestID: uint = 0 + responseTimeoutSeconds: uint = 0 @dataclass class ReverseOpenCommissioningWindow(ClusterCommand): cluster_id: typing.ClassVar[int] = 0x00000751 command_id: typing.ClassVar[int] = 0x00000002 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -49811,11 +49812,11 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="salt", Tag=4, Type=bytes), ]) - commissioningTimeout: 'uint' = 0 - PAKEPasscodeVerifier: 'bytes' = b"" - discriminator: 'uint' = 0 - iterations: 'uint' = 0 - salt: 'bytes' = b"" + commissioningTimeout: uint = 0 + PAKEPasscodeVerifier: bytes = b"" + discriminator: uint = 0 + iterations: uint = 0 + salt: bytes = b"" class Attributes: @dataclass @@ -49832,7 +49833,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -49848,7 +49849,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -49864,7 +49865,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -49880,7 +49881,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -49896,7 +49897,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -49912,7 +49913,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -49928,7 +49929,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 class Events: @dataclass @@ -49951,10 +49952,10 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="fabricIndex", Tag=254, Type=uint), ]) - requestID: 'uint' = 0 - clientNodeID: 'uint' = 0 - statusCode: 'uint' = 0 - fabricIndex: 'uint' = 0 + requestID: uint = 0 + clientNodeID: uint = 0 + statusCode: uint = 0 + fabricIndex: uint = 0 @dataclass @@ -50062,101 +50063,101 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="meiInt8u", Tag=0xFFF24F01, Type=uint), ]) - boolean: 'bool' = None - bitmap8: 'uint' = None - bitmap16: 'uint' = None - bitmap32: 'uint' = None - bitmap64: 'uint' = None - int8u: 'uint' = None - int16u: 'uint' = None - int24u: 'uint' = None - int32u: 'uint' = None - int40u: 'uint' = None - int48u: 'uint' = None - int56u: 'uint' = None - int64u: 'uint' = None - int8s: 'int' = None - int16s: 'int' = None - int24s: 'int' = None - int32s: 'int' = None - int40s: 'int' = None - int48s: 'int' = None - int56s: 'int' = None - int64s: 'int' = None - enum8: 'uint' = None - enum16: 'uint' = None - floatSingle: 'float32' = None - floatDouble: 'float' = None - octetString: 'bytes' = None - listInt8u: 'typing.List[uint]' = None - listOctetString: 'typing.List[bytes]' = None - listStructOctetString: 'typing.List[UnitTesting.Structs.TestListStructOctet]' = None - longOctetString: 'bytes' = None - charString: 'str' = None - longCharString: 'str' = None - epochUs: 'uint' = None - epochS: 'uint' = None - vendorId: 'uint' = None - listNullablesAndOptionalsStruct: 'typing.List[UnitTesting.Structs.NullablesAndOptionalsStruct]' = None - enumAttr: 'UnitTesting.Enums.SimpleEnum' = None - structAttr: 'UnitTesting.Structs.SimpleStruct' = None - rangeRestrictedInt8u: 'uint' = None - rangeRestrictedInt8s: 'int' = None - rangeRestrictedInt16u: 'uint' = None - rangeRestrictedInt16s: 'int' = None - listLongOctetString: 'typing.List[bytes]' = None - listFabricScoped: 'typing.List[UnitTesting.Structs.TestFabricScoped]' = None - timedWriteBoolean: 'bool' = None - generalErrorBoolean: 'bool' = None - clusterErrorBoolean: 'bool' = None - globalEnum: 'Globals.Enums.TestGlobalEnum' = None - globalStruct: 'Globals.Structs.TestGlobalStruct' = None - unsupported: 'typing.Optional[bool]' = None - readFailureCode: 'typing.Optional[uint]' = None - failureInt32U: 'typing.Optional[uint]' = None - nullableBoolean: 'typing.Union[Nullable, bool]' = None - nullableBitmap8: 'typing.Union[Nullable, uint]' = None - nullableBitmap16: 'typing.Union[Nullable, uint]' = None - nullableBitmap32: 'typing.Union[Nullable, uint]' = None - nullableBitmap64: 'typing.Union[Nullable, uint]' = None - nullableInt8u: 'typing.Union[Nullable, uint]' = None - nullableInt16u: 'typing.Union[Nullable, uint]' = None - nullableInt24u: 'typing.Union[Nullable, uint]' = None - nullableInt32u: 'typing.Union[Nullable, uint]' = None - nullableInt40u: 'typing.Union[Nullable, uint]' = None - nullableInt48u: 'typing.Union[Nullable, uint]' = None - nullableInt56u: 'typing.Union[Nullable, uint]' = None - nullableInt64u: 'typing.Union[Nullable, uint]' = None - nullableInt8s: 'typing.Union[Nullable, int]' = None - nullableInt16s: 'typing.Union[Nullable, int]' = None - nullableInt24s: 'typing.Union[Nullable, int]' = None - nullableInt32s: 'typing.Union[Nullable, int]' = None - nullableInt40s: 'typing.Union[Nullable, int]' = None - nullableInt48s: 'typing.Union[Nullable, int]' = None - nullableInt56s: 'typing.Union[Nullable, int]' = None - nullableInt64s: 'typing.Union[Nullable, int]' = None - nullableEnum8: 'typing.Union[Nullable, uint]' = None - nullableEnum16: 'typing.Union[Nullable, uint]' = None - nullableFloatSingle: 'typing.Union[Nullable, float32]' = None - nullableFloatDouble: 'typing.Union[Nullable, float]' = None - nullableOctetString: 'typing.Union[Nullable, bytes]' = None - nullableCharString: 'typing.Union[Nullable, str]' = None - nullableEnumAttr: 'typing.Union[Nullable, UnitTesting.Enums.SimpleEnum]' = None - nullableStruct: 'typing.Union[Nullable, UnitTesting.Structs.SimpleStruct]' = None - nullableRangeRestrictedInt8u: 'typing.Union[Nullable, uint]' = None - nullableRangeRestrictedInt8s: 'typing.Union[Nullable, int]' = None - nullableRangeRestrictedInt16u: 'typing.Union[Nullable, uint]' = None - nullableRangeRestrictedInt16s: 'typing.Union[Nullable, int]' = None - writeOnlyInt8u: 'typing.Optional[uint]' = None - nullableGlobalEnum: 'typing.Union[Nullable, Globals.Enums.TestGlobalEnum]' = None - nullableGlobalStruct: 'typing.Union[Nullable, Globals.Structs.TestGlobalStruct]' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None - meiInt8u: 'uint' = None + boolean: bool = False + bitmap8: uint = 0 + bitmap16: uint = 0 + bitmap32: uint = 0 + bitmap64: uint = 0 + int8u: uint = 0 + int16u: uint = 0 + int24u: uint = 0 + int32u: uint = 0 + int40u: uint = 0 + int48u: uint = 0 + int56u: uint = 0 + int64u: uint = 0 + int8s: int = 0 + int16s: int = 0 + int24s: int = 0 + int32s: int = 0 + int40s: int = 0 + int48s: int = 0 + int56s: int = 0 + int64s: int = 0 + enum8: uint = 0 + enum16: uint = 0 + floatSingle: float32 = 0.0 + floatDouble: float = 0.0 + octetString: bytes = b"" + listInt8u: typing.List[uint] = field(default_factory=lambda: []) + listOctetString: typing.List[bytes] = field(default_factory=lambda: []) + listStructOctetString: typing.List[UnitTesting.Structs.TestListStructOctet] = field(default_factory=lambda: []) + longOctetString: bytes = b"" + charString: str = "" + longCharString: str = "" + epochUs: uint = 0 + epochS: uint = 0 + vendorId: uint = 0 + listNullablesAndOptionalsStruct: typing.List[UnitTesting.Structs.NullablesAndOptionalsStruct] = field(default_factory=lambda: []) + enumAttr: UnitTesting.Enums.SimpleEnum = 0 + structAttr: UnitTesting.Structs.SimpleStruct = field(default_factory=lambda: UnitTesting.Structs.SimpleStruct()) + rangeRestrictedInt8u: uint = 0 + rangeRestrictedInt8s: int = 0 + rangeRestrictedInt16u: uint = 0 + rangeRestrictedInt16s: int = 0 + listLongOctetString: typing.List[bytes] = field(default_factory=lambda: []) + listFabricScoped: typing.List[UnitTesting.Structs.TestFabricScoped] = field(default_factory=lambda: []) + timedWriteBoolean: bool = False + generalErrorBoolean: bool = False + clusterErrorBoolean: bool = False + globalEnum: Globals.Enums.TestGlobalEnum = 0 + globalStruct: Globals.Structs.TestGlobalStruct = field(default_factory=lambda: Globals.Structs.TestGlobalStruct()) + unsupported: typing.Optional[bool] = None + readFailureCode: typing.Optional[uint] = None + failureInt32U: typing.Optional[uint] = None + nullableBoolean: typing.Union[Nullable, bool] = NullValue + nullableBitmap8: typing.Union[Nullable, uint] = NullValue + nullableBitmap16: typing.Union[Nullable, uint] = NullValue + nullableBitmap32: typing.Union[Nullable, uint] = NullValue + nullableBitmap64: typing.Union[Nullable, uint] = NullValue + nullableInt8u: typing.Union[Nullable, uint] = NullValue + nullableInt16u: typing.Union[Nullable, uint] = NullValue + nullableInt24u: typing.Union[Nullable, uint] = NullValue + nullableInt32u: typing.Union[Nullable, uint] = NullValue + nullableInt40u: typing.Union[Nullable, uint] = NullValue + nullableInt48u: typing.Union[Nullable, uint] = NullValue + nullableInt56u: typing.Union[Nullable, uint] = NullValue + nullableInt64u: typing.Union[Nullable, uint] = NullValue + nullableInt8s: typing.Union[Nullable, int] = NullValue + nullableInt16s: typing.Union[Nullable, int] = NullValue + nullableInt24s: typing.Union[Nullable, int] = NullValue + nullableInt32s: typing.Union[Nullable, int] = NullValue + nullableInt40s: typing.Union[Nullable, int] = NullValue + nullableInt48s: typing.Union[Nullable, int] = NullValue + nullableInt56s: typing.Union[Nullable, int] = NullValue + nullableInt64s: typing.Union[Nullable, int] = NullValue + nullableEnum8: typing.Union[Nullable, uint] = NullValue + nullableEnum16: typing.Union[Nullable, uint] = NullValue + nullableFloatSingle: typing.Union[Nullable, float32] = NullValue + nullableFloatDouble: typing.Union[Nullable, float] = NullValue + nullableOctetString: typing.Union[Nullable, bytes] = NullValue + nullableCharString: typing.Union[Nullable, str] = NullValue + nullableEnumAttr: typing.Union[Nullable, UnitTesting.Enums.SimpleEnum] = NullValue + nullableStruct: typing.Union[Nullable, UnitTesting.Structs.SimpleStruct] = NullValue + nullableRangeRestrictedInt8u: typing.Union[Nullable, uint] = NullValue + nullableRangeRestrictedInt8s: typing.Union[Nullable, int] = NullValue + nullableRangeRestrictedInt16u: typing.Union[Nullable, uint] = NullValue + nullableRangeRestrictedInt16s: typing.Union[Nullable, int] = NullValue + writeOnlyInt8u: typing.Optional[uint] = None + nullableGlobalEnum: typing.Union[Nullable, Globals.Enums.TestGlobalEnum] = NullValue + nullableGlobalStruct: typing.Union[Nullable, Globals.Structs.TestGlobalStruct] = NullValue + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 + meiInt8u: uint = 0 class Enums: class SimpleEnum(MatterIntEnum): @@ -50356,7 +50357,7 @@ class Test(ClusterCommand): cluster_id: typing.ClassVar[int] = 0xFFF1FC05 command_id: typing.ClassVar[int] = 0x00000000 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -50369,7 +50370,7 @@ class TestSpecificResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0xFFF1FC05 command_id: typing.ClassVar[int] = 0x00000000 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -50378,14 +50379,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="returnValue", Tag=0, Type=uint), ]) - returnValue: 'uint' = 0 + returnValue: uint = 0 @dataclass class TestNotHandled(ClusterCommand): cluster_id: typing.ClassVar[int] = 0xFFF1FC05 command_id: typing.ClassVar[int] = 0x00000001 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -50398,7 +50399,7 @@ class TestAddArgumentsResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0xFFF1FC05 command_id: typing.ClassVar[int] = 0x00000001 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -50407,7 +50408,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="returnValue", Tag=0, Type=uint), ]) - returnValue: 'uint' = 0 + returnValue: uint = 0 @dataclass class TestSpecific(ClusterCommand): @@ -50427,7 +50428,7 @@ class TestSimpleArgumentResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0xFFF1FC05 command_id: typing.ClassVar[int] = 0x00000002 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -50436,14 +50437,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="returnValue", Tag=0, Type=bool), ]) - returnValue: 'bool' = False + returnValue: bool = False @dataclass class TestUnknownCommand(ClusterCommand): cluster_id: typing.ClassVar[int] = 0xFFF1FC05 command_id: typing.ClassVar[int] = 0x00000003 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -50456,7 +50457,7 @@ class TestStructArrayArgumentResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0xFFF1FC05 command_id: typing.ClassVar[int] = 0x00000003 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -50470,12 +50471,12 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="arg6", Tag=5, Type=bool), ]) - arg1: 'typing.List[UnitTesting.Structs.NestedStructList]' = field(default_factory=lambda: []) - arg2: 'typing.List[UnitTesting.Structs.SimpleStruct]' = field(default_factory=lambda: []) - arg3: 'typing.List[UnitTesting.Enums.SimpleEnum]' = field(default_factory=lambda: []) - arg4: 'typing.List[bool]' = field(default_factory=lambda: []) - arg5: 'UnitTesting.Enums.SimpleEnum' = 0 - arg6: 'bool' = False + arg1: typing.List[UnitTesting.Structs.NestedStructList] = field(default_factory=lambda: []) + arg2: typing.List[UnitTesting.Structs.SimpleStruct] = field(default_factory=lambda: []) + arg3: typing.List[UnitTesting.Enums.SimpleEnum] = field(default_factory=lambda: []) + arg4: typing.List[bool] = field(default_factory=lambda: []) + arg5: UnitTesting.Enums.SimpleEnum = 0 + arg6: bool = False @dataclass class TestAddArguments(ClusterCommand): @@ -50492,15 +50493,15 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="arg2", Tag=1, Type=uint), ]) - arg1: 'uint' = 0 - arg2: 'uint' = 0 + arg1: uint = 0 + arg2: uint = 0 @dataclass class TestListInt8UReverseResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0xFFF1FC05 command_id: typing.ClassVar[int] = 0x00000004 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -50509,7 +50510,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="arg1", Tag=0, Type=typing.List[uint]), ]) - arg1: 'typing.List[uint]' = field(default_factory=lambda: []) + arg1: typing.List[uint] = field(default_factory=lambda: []) @dataclass class TestSimpleArgumentRequest(ClusterCommand): @@ -50525,14 +50526,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="arg1", Tag=0, Type=bool), ]) - arg1: 'bool' = False + arg1: bool = False @dataclass class TestEnumsResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0xFFF1FC05 command_id: typing.ClassVar[int] = 0x00000005 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -50542,8 +50543,8 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="arg2", Tag=1, Type=UnitTesting.Enums.SimpleEnum), ]) - arg1: 'uint' = 0 - arg2: 'UnitTesting.Enums.SimpleEnum' = 0 + arg1: uint = 0 + arg2: UnitTesting.Enums.SimpleEnum = 0 @dataclass class TestStructArrayArgumentRequest(ClusterCommand): @@ -50564,19 +50565,19 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="arg6", Tag=5, Type=bool), ]) - arg1: 'typing.List[UnitTesting.Structs.NestedStructList]' = field(default_factory=lambda: []) - arg2: 'typing.List[UnitTesting.Structs.SimpleStruct]' = field(default_factory=lambda: []) - arg3: 'typing.List[UnitTesting.Enums.SimpleEnum]' = field(default_factory=lambda: []) - arg4: 'typing.List[bool]' = field(default_factory=lambda: []) - arg5: 'UnitTesting.Enums.SimpleEnum' = 0 - arg6: 'bool' = False + arg1: typing.List[UnitTesting.Structs.NestedStructList] = field(default_factory=lambda: []) + arg2: typing.List[UnitTesting.Structs.SimpleStruct] = field(default_factory=lambda: []) + arg3: typing.List[UnitTesting.Enums.SimpleEnum] = field(default_factory=lambda: []) + arg4: typing.List[bool] = field(default_factory=lambda: []) + arg5: UnitTesting.Enums.SimpleEnum = 0 + arg6: bool = False @dataclass class TestNullableOptionalResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0xFFF1FC05 command_id: typing.ClassVar[int] = 0x00000006 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -50588,10 +50589,10 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="originalValue", Tag=3, Type=typing.Union[None, Nullable, uint]), ]) - wasPresent: 'bool' = False - wasNull: 'typing.Optional[bool]' = None - value: 'typing.Optional[uint]' = None - originalValue: 'typing.Union[None, Nullable, uint]' = None + wasPresent: bool = False + wasNull: typing.Optional[bool] = None + value: typing.Optional[uint] = None + originalValue: typing.Union[None, Nullable, uint] = None @dataclass class TestStructArgumentRequest(ClusterCommand): @@ -50607,14 +50608,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="arg1", Tag=0, Type=UnitTesting.Structs.SimpleStruct), ]) - arg1: 'UnitTesting.Structs.SimpleStruct' = field(default_factory=lambda: UnitTesting.Structs.SimpleStruct()) + arg1: UnitTesting.Structs.SimpleStruct = field(default_factory=lambda: UnitTesting.Structs.SimpleStruct()) @dataclass class TestComplexNullableOptionalResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0xFFF1FC05 command_id: typing.ClassVar[int] = 0x00000007 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -50650,34 +50651,34 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="nullableOptionalListValue", Tag=27, Type=typing.Optional[typing.List[UnitTesting.Enums.SimpleEnum]]), ]) - nullableIntWasNull: 'bool' = False - nullableIntValue: 'typing.Optional[uint]' = None - optionalIntWasPresent: 'bool' = False - optionalIntValue: 'typing.Optional[uint]' = None - nullableOptionalIntWasPresent: 'bool' = False - nullableOptionalIntWasNull: 'typing.Optional[bool]' = None - nullableOptionalIntValue: 'typing.Optional[uint]' = None - nullableStringWasNull: 'bool' = False - nullableStringValue: 'typing.Optional[str]' = None - optionalStringWasPresent: 'bool' = False - optionalStringValue: 'typing.Optional[str]' = None - nullableOptionalStringWasPresent: 'bool' = False - nullableOptionalStringWasNull: 'typing.Optional[bool]' = None - nullableOptionalStringValue: 'typing.Optional[str]' = None - nullableStructWasNull: 'bool' = False - nullableStructValue: 'typing.Optional[UnitTesting.Structs.SimpleStruct]' = None - optionalStructWasPresent: 'bool' = False - optionalStructValue: 'typing.Optional[UnitTesting.Structs.SimpleStruct]' = None - nullableOptionalStructWasPresent: 'bool' = False - nullableOptionalStructWasNull: 'typing.Optional[bool]' = None - nullableOptionalStructValue: 'typing.Optional[UnitTesting.Structs.SimpleStruct]' = None - nullableListWasNull: 'bool' = False - nullableListValue: 'typing.Optional[typing.List[UnitTesting.Enums.SimpleEnum]]' = None - optionalListWasPresent: 'bool' = False - optionalListValue: 'typing.Optional[typing.List[UnitTesting.Enums.SimpleEnum]]' = None - nullableOptionalListWasPresent: 'bool' = False - nullableOptionalListWasNull: 'typing.Optional[bool]' = None - nullableOptionalListValue: 'typing.Optional[typing.List[UnitTesting.Enums.SimpleEnum]]' = None + nullableIntWasNull: bool = False + nullableIntValue: typing.Optional[uint] = None + optionalIntWasPresent: bool = False + optionalIntValue: typing.Optional[uint] = None + nullableOptionalIntWasPresent: bool = False + nullableOptionalIntWasNull: typing.Optional[bool] = None + nullableOptionalIntValue: typing.Optional[uint] = None + nullableStringWasNull: bool = False + nullableStringValue: typing.Optional[str] = None + optionalStringWasPresent: bool = False + optionalStringValue: typing.Optional[str] = None + nullableOptionalStringWasPresent: bool = False + nullableOptionalStringWasNull: typing.Optional[bool] = None + nullableOptionalStringValue: typing.Optional[str] = None + nullableStructWasNull: bool = False + nullableStructValue: typing.Optional[UnitTesting.Structs.SimpleStruct] = None + optionalStructWasPresent: bool = False + optionalStructValue: typing.Optional[UnitTesting.Structs.SimpleStruct] = None + nullableOptionalStructWasPresent: bool = False + nullableOptionalStructWasNull: typing.Optional[bool] = None + nullableOptionalStructValue: typing.Optional[UnitTesting.Structs.SimpleStruct] = None + nullableListWasNull: bool = False + nullableListValue: typing.Optional[typing.List[UnitTesting.Enums.SimpleEnum]] = None + optionalListWasPresent: bool = False + optionalListValue: typing.Optional[typing.List[UnitTesting.Enums.SimpleEnum]] = None + nullableOptionalListWasPresent: bool = False + nullableOptionalListWasNull: typing.Optional[bool] = None + nullableOptionalListValue: typing.Optional[typing.List[UnitTesting.Enums.SimpleEnum]] = None @dataclass class TestNestedStructArgumentRequest(ClusterCommand): @@ -50693,14 +50694,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="arg1", Tag=0, Type=UnitTesting.Structs.NestedStruct), ]) - arg1: 'UnitTesting.Structs.NestedStruct' = field(default_factory=lambda: UnitTesting.Structs.NestedStruct()) + arg1: UnitTesting.Structs.NestedStruct = field(default_factory=lambda: UnitTesting.Structs.NestedStruct()) @dataclass class BooleanResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0xFFF1FC05 command_id: typing.ClassVar[int] = 0x00000008 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -50709,7 +50710,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="value", Tag=0, Type=bool), ]) - value: 'bool' = False + value: bool = False @dataclass class TestListStructArgumentRequest(ClusterCommand): @@ -50725,14 +50726,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="arg1", Tag=0, Type=typing.List[UnitTesting.Structs.SimpleStruct]), ]) - arg1: 'typing.List[UnitTesting.Structs.SimpleStruct]' = field(default_factory=lambda: []) + arg1: typing.List[UnitTesting.Structs.SimpleStruct] = field(default_factory=lambda: []) @dataclass class SimpleStructResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0xFFF1FC05 command_id: typing.ClassVar[int] = 0x00000009 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -50741,7 +50742,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="arg1", Tag=0, Type=UnitTesting.Structs.SimpleStruct), ]) - arg1: 'UnitTesting.Structs.SimpleStruct' = field(default_factory=lambda: UnitTesting.Structs.SimpleStruct()) + arg1: UnitTesting.Structs.SimpleStruct = field(default_factory=lambda: UnitTesting.Structs.SimpleStruct()) @dataclass class TestListInt8UArgumentRequest(ClusterCommand): @@ -50757,14 +50758,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="arg1", Tag=0, Type=typing.List[uint]), ]) - arg1: 'typing.List[uint]' = field(default_factory=lambda: []) + arg1: typing.List[uint] = field(default_factory=lambda: []) @dataclass class TestEmitTestEventResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0xFFF1FC05 command_id: typing.ClassVar[int] = 0x0000000A is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -50773,7 +50774,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="value", Tag=0, Type=uint), ]) - value: 'uint' = 0 + value: uint = 0 @dataclass class TestNestedStructListArgumentRequest(ClusterCommand): @@ -50789,14 +50790,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="arg1", Tag=0, Type=UnitTesting.Structs.NestedStructList), ]) - arg1: 'UnitTesting.Structs.NestedStructList' = field(default_factory=lambda: UnitTesting.Structs.NestedStructList()) + arg1: UnitTesting.Structs.NestedStructList = field(default_factory=lambda: UnitTesting.Structs.NestedStructList()) @dataclass class TestEmitTestFabricScopedEventResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0xFFF1FC05 command_id: typing.ClassVar[int] = 0x0000000B is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -50805,7 +50806,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="value", Tag=0, Type=uint), ]) - value: 'uint' = 0 + value: uint = 0 @dataclass class TestListNestedStructListArgumentRequest(ClusterCommand): @@ -50821,14 +50822,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="arg1", Tag=0, Type=typing.List[UnitTesting.Structs.NestedStructList]), ]) - arg1: 'typing.List[UnitTesting.Structs.NestedStructList]' = field(default_factory=lambda: []) + arg1: typing.List[UnitTesting.Structs.NestedStructList] = field(default_factory=lambda: []) @dataclass class TestBatchHelperResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0xFFF1FC05 command_id: typing.ClassVar[int] = 0x0000000C is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -50837,7 +50838,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="buffer", Tag=0, Type=bytes), ]) - buffer: 'bytes' = b"" + buffer: bytes = b"" @dataclass class TestListInt8UReverseRequest(ClusterCommand): @@ -50853,14 +50854,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="arg1", Tag=0, Type=typing.List[uint]), ]) - arg1: 'typing.List[uint]' = field(default_factory=lambda: []) + arg1: typing.List[uint] = field(default_factory=lambda: []) @dataclass class StringEchoResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0xFFF1FC05 command_id: typing.ClassVar[int] = 0x0000000D is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -50869,7 +50870,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="payload", Tag=0, Type=bytes), ]) - payload: 'bytes' = b"" + payload: bytes = b"" @dataclass class TestEnumsRequest(ClusterCommand): @@ -50886,15 +50887,15 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="arg2", Tag=1, Type=UnitTesting.Enums.SimpleEnum), ]) - arg1: 'uint' = 0 - arg2: 'UnitTesting.Enums.SimpleEnum' = 0 + arg1: uint = 0 + arg2: UnitTesting.Enums.SimpleEnum = 0 @dataclass class GlobalEchoResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0xFFF1FC05 command_id: typing.ClassVar[int] = 0x0000000E is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -50904,8 +50905,8 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="field2", Tag=1, Type=Globals.Enums.TestGlobalEnum), ]) - field1: 'Globals.Structs.TestGlobalStruct' = field(default_factory=lambda: Globals.Structs.TestGlobalStruct()) - field2: 'Globals.Enums.TestGlobalEnum' = 0 + field1: Globals.Structs.TestGlobalStruct = field(default_factory=lambda: Globals.Structs.TestGlobalStruct()) + field2: Globals.Enums.TestGlobalEnum = 0 @dataclass class TestNullableOptionalRequest(ClusterCommand): @@ -50921,7 +50922,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="arg1", Tag=0, Type=typing.Union[None, Nullable, uint]), ]) - arg1: 'typing.Union[None, Nullable, uint]' = None + arg1: typing.Union[None, Nullable, uint] = None @dataclass class TestComplexNullableOptionalRequest(ClusterCommand): @@ -50948,18 +50949,18 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="nullableOptionalList", Tag=11, Type=typing.Union[None, Nullable, typing.List[UnitTesting.Enums.SimpleEnum]]), ]) - nullableInt: 'typing.Union[Nullable, uint]' = NullValue - optionalInt: 'typing.Optional[uint]' = None - nullableOptionalInt: 'typing.Union[None, Nullable, uint]' = None - nullableString: 'typing.Union[Nullable, str]' = NullValue - optionalString: 'typing.Optional[str]' = None - nullableOptionalString: 'typing.Union[None, Nullable, str]' = None - nullableStruct: 'typing.Union[Nullable, UnitTesting.Structs.SimpleStruct]' = NullValue - optionalStruct: 'typing.Optional[UnitTesting.Structs.SimpleStruct]' = None - nullableOptionalStruct: 'typing.Union[None, Nullable, UnitTesting.Structs.SimpleStruct]' = None - nullableList: 'typing.Union[Nullable, typing.List[UnitTesting.Enums.SimpleEnum]]' = NullValue - optionalList: 'typing.Optional[typing.List[UnitTesting.Enums.SimpleEnum]]' = None - nullableOptionalList: 'typing.Union[None, Nullable, typing.List[UnitTesting.Enums.SimpleEnum]]' = None + nullableInt: typing.Union[Nullable, uint] = NullValue + optionalInt: typing.Optional[uint] = None + nullableOptionalInt: typing.Union[None, Nullable, uint] = None + nullableString: typing.Union[Nullable, str] = NullValue + optionalString: typing.Optional[str] = None + nullableOptionalString: typing.Union[None, Nullable, str] = None + nullableStruct: typing.Union[Nullable, UnitTesting.Structs.SimpleStruct] = NullValue + optionalStruct: typing.Optional[UnitTesting.Structs.SimpleStruct] = None + nullableOptionalStruct: typing.Union[None, Nullable, UnitTesting.Structs.SimpleStruct] = None + nullableList: typing.Union[Nullable, typing.List[UnitTesting.Enums.SimpleEnum]] = NullValue + optionalList: typing.Optional[typing.List[UnitTesting.Enums.SimpleEnum]] = None + nullableOptionalList: typing.Union[None, Nullable, typing.List[UnitTesting.Enums.SimpleEnum]] = None @dataclass class SimpleStructEchoRequest(ClusterCommand): @@ -50975,14 +50976,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="arg1", Tag=0, Type=UnitTesting.Structs.SimpleStruct), ]) - arg1: 'UnitTesting.Structs.SimpleStruct' = field(default_factory=lambda: UnitTesting.Structs.SimpleStruct()) + arg1: UnitTesting.Structs.SimpleStruct = field(default_factory=lambda: UnitTesting.Structs.SimpleStruct()) @dataclass class TimedInvokeRequest(ClusterCommand): cluster_id: typing.ClassVar[int] = 0xFFF1FC05 command_id: typing.ClassVar[int] = 0x00000012 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -50999,7 +51000,7 @@ class TestSimpleOptionalArgumentRequest(ClusterCommand): cluster_id: typing.ClassVar[int] = 0xFFF1FC05 command_id: typing.ClassVar[int] = 0x00000013 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -51008,7 +51009,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="arg1", Tag=0, Type=typing.Optional[bool]), ]) - arg1: 'typing.Optional[bool]' = None + arg1: typing.Optional[bool] = None @dataclass class TestEmitTestEventRequest(ClusterCommand): @@ -51026,9 +51027,9 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="arg3", Tag=2, Type=bool), ]) - arg1: 'uint' = 0 - arg2: 'UnitTesting.Enums.SimpleEnum' = 0 - arg3: 'bool' = False + arg1: uint = 0 + arg2: UnitTesting.Enums.SimpleEnum = 0 + arg3: bool = False @dataclass class TestEmitTestFabricScopedEventRequest(ClusterCommand): @@ -51044,7 +51045,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="arg1", Tag=0, Type=uint), ]) - arg1: 'uint' = 0 + arg1: uint = 0 @dataclass class TestBatchHelperRequest(ClusterCommand): @@ -51062,9 +51063,9 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="fillCharacter", Tag=2, Type=uint), ]) - sleepBeforeResponseTimeMs: 'uint' = 0 - sizeOfResponseBuffer: 'uint' = 0 - fillCharacter: 'uint' = 0 + sleepBeforeResponseTimeMs: uint = 0 + sizeOfResponseBuffer: uint = 0 + fillCharacter: uint = 0 @dataclass class TestSecondBatchHelperRequest(ClusterCommand): @@ -51082,9 +51083,9 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="fillCharacter", Tag=2, Type=uint), ]) - sleepBeforeResponseTimeMs: 'uint' = 0 - sizeOfResponseBuffer: 'uint' = 0 - fillCharacter: 'uint' = 0 + sleepBeforeResponseTimeMs: uint = 0 + sizeOfResponseBuffer: uint = 0 + fillCharacter: uint = 0 @dataclass class StringEchoRequest(ClusterCommand): @@ -51100,7 +51101,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="payload", Tag=0, Type=bytes), ]) - payload: 'bytes' = b"" + payload: bytes = b"" @dataclass class GlobalEchoRequest(ClusterCommand): @@ -51117,8 +51118,8 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="field2", Tag=1, Type=Globals.Enums.TestGlobalEnum), ]) - field1: 'Globals.Structs.TestGlobalStruct' = field(default_factory=lambda: Globals.Structs.TestGlobalStruct()) - field2: 'Globals.Enums.TestGlobalEnum' = 0 + field1: Globals.Structs.TestGlobalStruct = field(default_factory=lambda: Globals.Structs.TestGlobalStruct()) + field2: Globals.Enums.TestGlobalEnum = 0 @dataclass class TestDifferentVendorMeiRequest(ClusterCommand): @@ -51134,14 +51135,14 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="arg1", Tag=0, Type=uint), ]) - arg1: 'uint' = 0 + arg1: uint = 0 @dataclass class TestDifferentVendorMeiResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0xFFF1FC05 command_id: typing.ClassVar[int] = 0xFFF200BB is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -51151,8 +51152,8 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="eventNumber", Tag=1, Type=uint), ]) - arg1: 'uint' = 0 - eventNumber: 'uint' = 0 + arg1: uint = 0 + eventNumber: uint = 0 class Attributes: @dataclass @@ -51169,7 +51170,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=bool) - value: 'bool' = False + value: bool = False @dataclass class Bitmap8(ClusterAttributeDescriptor): @@ -51185,7 +51186,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class Bitmap16(ClusterAttributeDescriptor): @@ -51201,7 +51202,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class Bitmap32(ClusterAttributeDescriptor): @@ -51217,7 +51218,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class Bitmap64(ClusterAttributeDescriptor): @@ -51233,7 +51234,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class Int8u(ClusterAttributeDescriptor): @@ -51249,7 +51250,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class Int16u(ClusterAttributeDescriptor): @@ -51265,7 +51266,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class Int24u(ClusterAttributeDescriptor): @@ -51281,7 +51282,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class Int32u(ClusterAttributeDescriptor): @@ -51297,7 +51298,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class Int40u(ClusterAttributeDescriptor): @@ -51313,7 +51314,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class Int48u(ClusterAttributeDescriptor): @@ -51329,7 +51330,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class Int56u(ClusterAttributeDescriptor): @@ -51345,7 +51346,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class Int64u(ClusterAttributeDescriptor): @@ -51361,7 +51362,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class Int8s(ClusterAttributeDescriptor): @@ -51377,7 +51378,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=int) - value: 'int' = 0 + value: int = 0 @dataclass class Int16s(ClusterAttributeDescriptor): @@ -51393,7 +51394,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=int) - value: 'int' = 0 + value: int = 0 @dataclass class Int24s(ClusterAttributeDescriptor): @@ -51409,7 +51410,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=int) - value: 'int' = 0 + value: int = 0 @dataclass class Int32s(ClusterAttributeDescriptor): @@ -51425,7 +51426,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=int) - value: 'int' = 0 + value: int = 0 @dataclass class Int40s(ClusterAttributeDescriptor): @@ -51441,7 +51442,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=int) - value: 'int' = 0 + value: int = 0 @dataclass class Int48s(ClusterAttributeDescriptor): @@ -51457,7 +51458,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=int) - value: 'int' = 0 + value: int = 0 @dataclass class Int56s(ClusterAttributeDescriptor): @@ -51473,7 +51474,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=int) - value: 'int' = 0 + value: int = 0 @dataclass class Int64s(ClusterAttributeDescriptor): @@ -51489,7 +51490,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=int) - value: 'int' = 0 + value: int = 0 @dataclass class Enum8(ClusterAttributeDescriptor): @@ -51505,7 +51506,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class Enum16(ClusterAttributeDescriptor): @@ -51521,7 +51522,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class FloatSingle(ClusterAttributeDescriptor): @@ -51537,7 +51538,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=float32) - value: 'float32' = 0.0 + value: float32 = 0.0 @dataclass class FloatDouble(ClusterAttributeDescriptor): @@ -51553,7 +51554,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=float) - value: 'float' = 0.0 + value: float = 0.0 @dataclass class OctetString(ClusterAttributeDescriptor): @@ -51569,7 +51570,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=bytes) - value: 'bytes' = b"" + value: bytes = b"" @dataclass class ListInt8u(ClusterAttributeDescriptor): @@ -51585,7 +51586,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class ListOctetString(ClusterAttributeDescriptor): @@ -51601,7 +51602,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[bytes]) - value: 'typing.List[bytes]' = field(default_factory=lambda: []) + value: typing.List[bytes] = field(default_factory=lambda: []) @dataclass class ListStructOctetString(ClusterAttributeDescriptor): @@ -51617,7 +51618,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[UnitTesting.Structs.TestListStructOctet]) - value: 'typing.List[UnitTesting.Structs.TestListStructOctet]' = field(default_factory=lambda: []) + value: typing.List[UnitTesting.Structs.TestListStructOctet] = field(default_factory=lambda: []) @dataclass class LongOctetString(ClusterAttributeDescriptor): @@ -51633,7 +51634,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=bytes) - value: 'bytes' = b"" + value: bytes = b"" @dataclass class CharString(ClusterAttributeDescriptor): @@ -51649,7 +51650,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=str) - value: 'str' = "" + value: str = "" @dataclass class LongCharString(ClusterAttributeDescriptor): @@ -51665,7 +51666,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=str) - value: 'str' = "" + value: str = "" @dataclass class EpochUs(ClusterAttributeDescriptor): @@ -51681,7 +51682,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class EpochS(ClusterAttributeDescriptor): @@ -51697,7 +51698,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class VendorId(ClusterAttributeDescriptor): @@ -51713,7 +51714,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ListNullablesAndOptionalsStruct(ClusterAttributeDescriptor): @@ -51729,7 +51730,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[UnitTesting.Structs.NullablesAndOptionalsStruct]) - value: 'typing.List[UnitTesting.Structs.NullablesAndOptionalsStruct]' = field(default_factory=lambda: []) + value: typing.List[UnitTesting.Structs.NullablesAndOptionalsStruct] = field(default_factory=lambda: []) @dataclass class EnumAttr(ClusterAttributeDescriptor): @@ -51745,7 +51746,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=UnitTesting.Enums.SimpleEnum) - value: 'UnitTesting.Enums.SimpleEnum' = 0 + value: UnitTesting.Enums.SimpleEnum = 0 @dataclass class StructAttr(ClusterAttributeDescriptor): @@ -51761,7 +51762,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=UnitTesting.Structs.SimpleStruct) - value: 'UnitTesting.Structs.SimpleStruct' = field(default_factory=lambda: UnitTesting.Structs.SimpleStruct()) + value: UnitTesting.Structs.SimpleStruct = field(default_factory=lambda: UnitTesting.Structs.SimpleStruct()) @dataclass class RangeRestrictedInt8u(ClusterAttributeDescriptor): @@ -51777,7 +51778,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class RangeRestrictedInt8s(ClusterAttributeDescriptor): @@ -51793,7 +51794,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=int) - value: 'int' = 0 + value: int = 0 @dataclass class RangeRestrictedInt16u(ClusterAttributeDescriptor): @@ -51809,7 +51810,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class RangeRestrictedInt16s(ClusterAttributeDescriptor): @@ -51825,7 +51826,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=int) - value: 'int' = 0 + value: int = 0 @dataclass class ListLongOctetString(ClusterAttributeDescriptor): @@ -51841,7 +51842,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[bytes]) - value: 'typing.List[bytes]' = field(default_factory=lambda: []) + value: typing.List[bytes] = field(default_factory=lambda: []) @dataclass class ListFabricScoped(ClusterAttributeDescriptor): @@ -51857,7 +51858,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[UnitTesting.Structs.TestFabricScoped]) - value: 'typing.List[UnitTesting.Structs.TestFabricScoped]' = field(default_factory=lambda: []) + value: typing.List[UnitTesting.Structs.TestFabricScoped] = field(default_factory=lambda: []) @dataclass class TimedWriteBoolean(ClusterAttributeDescriptor): @@ -51877,7 +51878,7 @@ def must_use_timed_write(cls) -> bool: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=bool) - value: 'bool' = False + value: bool = False @dataclass class GeneralErrorBoolean(ClusterAttributeDescriptor): @@ -51893,7 +51894,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=bool) - value: 'bool' = False + value: bool = False @dataclass class ClusterErrorBoolean(ClusterAttributeDescriptor): @@ -51909,7 +51910,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=bool) - value: 'bool' = False + value: bool = False @dataclass class GlobalEnum(ClusterAttributeDescriptor): @@ -51925,7 +51926,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=Globals.Enums.TestGlobalEnum) - value: 'Globals.Enums.TestGlobalEnum' = 0 + value: Globals.Enums.TestGlobalEnum = 0 @dataclass class GlobalStruct(ClusterAttributeDescriptor): @@ -51941,7 +51942,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=Globals.Structs.TestGlobalStruct) - value: 'Globals.Structs.TestGlobalStruct' = field(default_factory=lambda: Globals.Structs.TestGlobalStruct()) + value: Globals.Structs.TestGlobalStruct = field(default_factory=lambda: Globals.Structs.TestGlobalStruct()) @dataclass class Unsupported(ClusterAttributeDescriptor): @@ -51957,7 +51958,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[bool]) - value: 'typing.Optional[bool]' = None + value: typing.Optional[bool] = None @dataclass class ReadFailureCode(ClusterAttributeDescriptor): @@ -51973,7 +51974,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class FailureInt32U(ClusterAttributeDescriptor): @@ -51989,7 +51990,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class NullableBoolean(ClusterAttributeDescriptor): @@ -52005,7 +52006,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, bool]) - value: 'typing.Union[Nullable, bool]' = NullValue + value: typing.Union[Nullable, bool] = NullValue @dataclass class NullableBitmap8(ClusterAttributeDescriptor): @@ -52021,7 +52022,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, uint]) - value: 'typing.Union[Nullable, uint]' = NullValue + value: typing.Union[Nullable, uint] = NullValue @dataclass class NullableBitmap16(ClusterAttributeDescriptor): @@ -52037,7 +52038,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, uint]) - value: 'typing.Union[Nullable, uint]' = NullValue + value: typing.Union[Nullable, uint] = NullValue @dataclass class NullableBitmap32(ClusterAttributeDescriptor): @@ -52053,7 +52054,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, uint]) - value: 'typing.Union[Nullable, uint]' = NullValue + value: typing.Union[Nullable, uint] = NullValue @dataclass class NullableBitmap64(ClusterAttributeDescriptor): @@ -52069,7 +52070,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, uint]) - value: 'typing.Union[Nullable, uint]' = NullValue + value: typing.Union[Nullable, uint] = NullValue @dataclass class NullableInt8u(ClusterAttributeDescriptor): @@ -52085,7 +52086,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, uint]) - value: 'typing.Union[Nullable, uint]' = NullValue + value: typing.Union[Nullable, uint] = NullValue @dataclass class NullableInt16u(ClusterAttributeDescriptor): @@ -52101,7 +52102,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, uint]) - value: 'typing.Union[Nullable, uint]' = NullValue + value: typing.Union[Nullable, uint] = NullValue @dataclass class NullableInt24u(ClusterAttributeDescriptor): @@ -52117,7 +52118,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, uint]) - value: 'typing.Union[Nullable, uint]' = NullValue + value: typing.Union[Nullable, uint] = NullValue @dataclass class NullableInt32u(ClusterAttributeDescriptor): @@ -52133,7 +52134,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, uint]) - value: 'typing.Union[Nullable, uint]' = NullValue + value: typing.Union[Nullable, uint] = NullValue @dataclass class NullableInt40u(ClusterAttributeDescriptor): @@ -52149,7 +52150,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, uint]) - value: 'typing.Union[Nullable, uint]' = NullValue + value: typing.Union[Nullable, uint] = NullValue @dataclass class NullableInt48u(ClusterAttributeDescriptor): @@ -52165,7 +52166,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, uint]) - value: 'typing.Union[Nullable, uint]' = NullValue + value: typing.Union[Nullable, uint] = NullValue @dataclass class NullableInt56u(ClusterAttributeDescriptor): @@ -52181,7 +52182,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, uint]) - value: 'typing.Union[Nullable, uint]' = NullValue + value: typing.Union[Nullable, uint] = NullValue @dataclass class NullableInt64u(ClusterAttributeDescriptor): @@ -52197,7 +52198,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, uint]) - value: 'typing.Union[Nullable, uint]' = NullValue + value: typing.Union[Nullable, uint] = NullValue @dataclass class NullableInt8s(ClusterAttributeDescriptor): @@ -52213,7 +52214,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, int]) - value: 'typing.Union[Nullable, int]' = NullValue + value: typing.Union[Nullable, int] = NullValue @dataclass class NullableInt16s(ClusterAttributeDescriptor): @@ -52229,7 +52230,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, int]) - value: 'typing.Union[Nullable, int]' = NullValue + value: typing.Union[Nullable, int] = NullValue @dataclass class NullableInt24s(ClusterAttributeDescriptor): @@ -52245,7 +52246,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, int]) - value: 'typing.Union[Nullable, int]' = NullValue + value: typing.Union[Nullable, int] = NullValue @dataclass class NullableInt32s(ClusterAttributeDescriptor): @@ -52261,7 +52262,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, int]) - value: 'typing.Union[Nullable, int]' = NullValue + value: typing.Union[Nullable, int] = NullValue @dataclass class NullableInt40s(ClusterAttributeDescriptor): @@ -52277,7 +52278,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, int]) - value: 'typing.Union[Nullable, int]' = NullValue + value: typing.Union[Nullable, int] = NullValue @dataclass class NullableInt48s(ClusterAttributeDescriptor): @@ -52293,7 +52294,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, int]) - value: 'typing.Union[Nullable, int]' = NullValue + value: typing.Union[Nullable, int] = NullValue @dataclass class NullableInt56s(ClusterAttributeDescriptor): @@ -52309,7 +52310,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, int]) - value: 'typing.Union[Nullable, int]' = NullValue + value: typing.Union[Nullable, int] = NullValue @dataclass class NullableInt64s(ClusterAttributeDescriptor): @@ -52325,7 +52326,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, int]) - value: 'typing.Union[Nullable, int]' = NullValue + value: typing.Union[Nullable, int] = NullValue @dataclass class NullableEnum8(ClusterAttributeDescriptor): @@ -52341,7 +52342,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, uint]) - value: 'typing.Union[Nullable, uint]' = NullValue + value: typing.Union[Nullable, uint] = NullValue @dataclass class NullableEnum16(ClusterAttributeDescriptor): @@ -52357,7 +52358,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, uint]) - value: 'typing.Union[Nullable, uint]' = NullValue + value: typing.Union[Nullable, uint] = NullValue @dataclass class NullableFloatSingle(ClusterAttributeDescriptor): @@ -52373,7 +52374,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, float32]) - value: 'typing.Union[Nullable, float32]' = NullValue + value: typing.Union[Nullable, float32] = NullValue @dataclass class NullableFloatDouble(ClusterAttributeDescriptor): @@ -52389,7 +52390,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, float]) - value: 'typing.Union[Nullable, float]' = NullValue + value: typing.Union[Nullable, float] = NullValue @dataclass class NullableOctetString(ClusterAttributeDescriptor): @@ -52405,7 +52406,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, bytes]) - value: 'typing.Union[Nullable, bytes]' = NullValue + value: typing.Union[Nullable, bytes] = NullValue @dataclass class NullableCharString(ClusterAttributeDescriptor): @@ -52421,7 +52422,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, str]) - value: 'typing.Union[Nullable, str]' = NullValue + value: typing.Union[Nullable, str] = NullValue @dataclass class NullableEnumAttr(ClusterAttributeDescriptor): @@ -52437,7 +52438,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, UnitTesting.Enums.SimpleEnum]) - value: 'typing.Union[Nullable, UnitTesting.Enums.SimpleEnum]' = NullValue + value: typing.Union[Nullable, UnitTesting.Enums.SimpleEnum] = NullValue @dataclass class NullableStruct(ClusterAttributeDescriptor): @@ -52453,7 +52454,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, UnitTesting.Structs.SimpleStruct]) - value: 'typing.Union[Nullable, UnitTesting.Structs.SimpleStruct]' = NullValue + value: typing.Union[Nullable, UnitTesting.Structs.SimpleStruct] = NullValue @dataclass class NullableRangeRestrictedInt8u(ClusterAttributeDescriptor): @@ -52469,7 +52470,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, uint]) - value: 'typing.Union[Nullable, uint]' = NullValue + value: typing.Union[Nullable, uint] = NullValue @dataclass class NullableRangeRestrictedInt8s(ClusterAttributeDescriptor): @@ -52485,7 +52486,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, int]) - value: 'typing.Union[Nullable, int]' = NullValue + value: typing.Union[Nullable, int] = NullValue @dataclass class NullableRangeRestrictedInt16u(ClusterAttributeDescriptor): @@ -52501,7 +52502,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, uint]) - value: 'typing.Union[Nullable, uint]' = NullValue + value: typing.Union[Nullable, uint] = NullValue @dataclass class NullableRangeRestrictedInt16s(ClusterAttributeDescriptor): @@ -52517,7 +52518,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, int]) - value: 'typing.Union[Nullable, int]' = NullValue + value: typing.Union[Nullable, int] = NullValue @dataclass class WriteOnlyInt8u(ClusterAttributeDescriptor): @@ -52533,7 +52534,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Optional[uint]) - value: 'typing.Optional[uint]' = None + value: typing.Optional[uint] = None @dataclass class NullableGlobalEnum(ClusterAttributeDescriptor): @@ -52549,7 +52550,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, Globals.Enums.TestGlobalEnum]) - value: 'typing.Union[Nullable, Globals.Enums.TestGlobalEnum]' = NullValue + value: typing.Union[Nullable, Globals.Enums.TestGlobalEnum] = NullValue @dataclass class NullableGlobalStruct(ClusterAttributeDescriptor): @@ -52565,7 +52566,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.Union[Nullable, Globals.Structs.TestGlobalStruct]) - value: 'typing.Union[Nullable, Globals.Structs.TestGlobalStruct]' = NullValue + value: typing.Union[Nullable, Globals.Structs.TestGlobalStruct] = NullValue @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -52581,7 +52582,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -52597,7 +52598,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -52613,7 +52614,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -52629,7 +52630,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -52645,7 +52646,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -52661,7 +52662,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class MeiInt8u(ClusterAttributeDescriptor): @@ -52677,7 +52678,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 class Events: @dataclass @@ -52702,12 +52703,12 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="arg6", Tag=6, Type=typing.List[UnitTesting.Enums.SimpleEnum]), ]) - arg1: 'uint' = 0 - arg2: 'UnitTesting.Enums.SimpleEnum' = 0 - arg3: 'bool' = False - arg4: 'UnitTesting.Structs.SimpleStruct' = field(default_factory=lambda: UnitTesting.Structs.SimpleStruct()) - arg5: 'typing.List[UnitTesting.Structs.SimpleStruct]' = field(default_factory=lambda: []) - arg6: 'typing.List[UnitTesting.Enums.SimpleEnum]' = field(default_factory=lambda: []) + arg1: uint = 0 + arg2: UnitTesting.Enums.SimpleEnum = 0 + arg3: bool = False + arg4: UnitTesting.Structs.SimpleStruct = field(default_factory=lambda: UnitTesting.Structs.SimpleStruct()) + arg5: typing.List[UnitTesting.Structs.SimpleStruct] = field(default_factory=lambda: []) + arg6: typing.List[UnitTesting.Enums.SimpleEnum] = field(default_factory=lambda: []) @dataclass class TestFabricScopedEvent(ClusterEvent): @@ -52726,7 +52727,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="fabricIndex", Tag=254, Type=uint), ]) - fabricIndex: 'uint' = 0 + fabricIndex: uint = 0 @dataclass class TestDifferentVendorMeiEvent(ClusterEvent): @@ -52745,7 +52746,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="arg1", Tag=1, Type=uint), ]) - arg1: 'uint' = 0 + arg1: uint = 0 @dataclass @@ -52764,12 +52765,12 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Enums: class FaultType(MatterIntEnum): @@ -52790,7 +52791,7 @@ class FailAtFault(ClusterCommand): cluster_id: typing.ClassVar[int] = 0xFFF1FC06 command_id: typing.ClassVar[int] = 0x00000000 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -52803,18 +52804,18 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="takeMutex", Tag=4, Type=bool), ]) - type: 'FaultInjection.Enums.FaultType' = 0 - id: 'uint' = 0 - numCallsToSkip: 'uint' = 0 - numCallsToFail: 'uint' = 0 - takeMutex: 'bool' = False + type: FaultInjection.Enums.FaultType = 0 + id: uint = 0 + numCallsToSkip: uint = 0 + numCallsToFail: uint = 0 + takeMutex: bool = False @dataclass class FailRandomlyAtFault(ClusterCommand): cluster_id: typing.ClassVar[int] = 0xFFF1FC06 command_id: typing.ClassVar[int] = 0x00000001 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -52825,9 +52826,9 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="percentage", Tag=2, Type=uint), ]) - type: 'FaultInjection.Enums.FaultType' = 0 - id: 'uint' = 0 - percentage: 'uint' = 0 + type: FaultInjection.Enums.FaultType = 0 + id: uint = 0 + percentage: uint = 0 class Attributes: @dataclass @@ -52844,7 +52845,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -52860,7 +52861,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -52876,7 +52877,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -52892,7 +52893,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -52908,7 +52909,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -52924,7 +52925,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass @@ -52944,13 +52945,13 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), ]) - flipFlop: 'bool' = None - generatedCommandList: 'typing.List[uint]' = None - acceptedCommandList: 'typing.List[uint]' = None - eventList: 'typing.List[uint]' = None - attributeList: 'typing.List[uint]' = None - featureMap: 'uint' = None - clusterRevision: 'uint' = None + flipFlop: bool = False + generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) + acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) + eventList: typing.List[uint] = field(default_factory=lambda: []) + attributeList: typing.List[uint] = field(default_factory=lambda: []) + featureMap: uint = 0 + clusterRevision: uint = 0 class Commands: @dataclass @@ -52958,7 +52959,7 @@ class Ping(ClusterCommand): cluster_id: typing.ClassVar[int] = 0xFFF1FC20 command_id: typing.ClassVar[int] = 0x00000000 is_client: typing.ClassVar[bool] = True - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -52971,7 +52972,7 @@ class AddArgumentsResponse(ClusterCommand): cluster_id: typing.ClassVar[int] = 0xFFF1FC20 command_id: typing.ClassVar[int] = 0x00000001 is_client: typing.ClassVar[bool] = False - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None @ChipUtility.classproperty def descriptor(cls) -> ClusterObjectDescriptor: @@ -52980,7 +52981,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="returnValue", Tag=0, Type=uint), ]) - returnValue: 'uint' = 0 + returnValue: uint = 0 @dataclass class AddArguments(ClusterCommand): @@ -52997,8 +52998,8 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="arg2", Tag=1, Type=uint), ]) - arg1: 'uint' = 0 - arg2: 'uint' = 0 + arg1: uint = 0 + arg2: uint = 0 class Attributes: @dataclass @@ -53015,7 +53016,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=bool) - value: 'bool' = False + value: bool = False @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @@ -53031,7 +53032,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AcceptedCommandList(ClusterAttributeDescriptor): @@ -53047,7 +53048,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class EventList(ClusterAttributeDescriptor): @@ -53063,7 +53064,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class AttributeList(ClusterAttributeDescriptor): @@ -53079,7 +53080,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - value: 'typing.List[uint]' = field(default_factory=lambda: []) + value: typing.List[uint] = field(default_factory=lambda: []) @dataclass class FeatureMap(ClusterAttributeDescriptor): @@ -53095,7 +53096,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 @dataclass class ClusterRevision(ClusterAttributeDescriptor): @@ -53111,7 +53112,7 @@ def attribute_id(cls) -> int: def attribute_type(cls) -> ClusterObjectFieldDescriptor: return ClusterObjectFieldDescriptor(Type=uint) - value: 'uint' = 0 + value: uint = 0 class Events: @dataclass @@ -53132,6 +53133,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="fabricIndex", Tag=254, Type=uint), ]) - count: 'uint' = 0 - fabricIndex: 'uint' = 0 + count: uint = 0 + fabricIndex: uint = 0 diff --git a/src/controller/python/templates/python-cluster-Objects-py.zapt b/src/controller/python/templates/python-cluster-Objects-py.zapt index 3cb973d86dd356..381d266668082a 100644 --- a/src/controller/python/templates/python-cluster-Objects-py.zapt +++ b/src/controller/python/templates/python-cluster-Objects-py.zapt @@ -6,6 +6,7 @@ # Users are not expected to import this file, instead, users can use import chip.clusters, # which will import all symbols from this file and can get a readable, pretty naming like # clusters.OnOff.commands.OnCommand +from __future__ import annotations import typing from dataclasses import dataclass, field @@ -76,9 +77,9 @@ class {{asUpperCamelCase name}}(Cluster): {{#zcl_attributes_server}} {{#if entryType}} - {{ asLowerCamelCase label }}: '{{zapTypeToPythonClusterObjectType entryType ns=(asUpperCamelCase parent.name)}}' = None + {{ asLowerCamelCase label }}: {{zapTypeToPythonClusterObjectType entryType ns=(asUpperCamelCase parent.name)}} = {{getPythonFieldDefault entryType ns=(asUpperCamelCase parent.name)}} {{else}} - {{ asLowerCamelCase label }}: '{{zapTypeToPythonClusterObjectType type ns=(asUpperCamelCase parent.name)}}' = None + {{ asLowerCamelCase label }}: {{zapTypeToPythonClusterObjectType type ns=(asUpperCamelCase parent.name)}} = {{getPythonFieldDefault type ns=(asUpperCamelCase parent.name)}} {{/if}} {{/zcl_attributes_server}} @@ -121,7 +122,7 @@ class {{asUpperCamelCase name}}(Cluster): {{~#if responseName}} response_type: typing.ClassVar[str] = '{{asUpperCamelCase responseName}}' {{else}} - response_type: typing.ClassVar[str] = None + response_type: typing.ClassVar[typing.Optional[str]] = None {{/if}} @ChipUtility.classproperty @@ -142,7 +143,7 @@ class {{asUpperCamelCase name}}(Cluster): {{#first}} {{/first}} - {{ asLowerCamelCase label }}: '{{zapTypeToPythonClusterObjectType type ns=(asUpperCamelCase parent.parent.name)}}' = {{getPythonFieldDefault type ns=(asUpperCamelCase parent.parent.name)}} + {{ asLowerCamelCase label }}: {{zapTypeToPythonClusterObjectType type ns=(asUpperCamelCase parent.parent.name)}} = {{getPythonFieldDefault type ns=(asUpperCamelCase parent.parent.name)}} {{/zcl_command_arguments}} {{/zcl_commands}} @@ -175,9 +176,9 @@ class {{asUpperCamelCase name}}(Cluster): {{/if}} {{#if entryType}} - value: '{{zapTypeToPythonClusterObjectType entryType ns=(asUpperCamelCase parent.name)}}' = {{getPythonFieldDefault entryType ns=(asUpperCamelCase parent.name)}} + value: {{zapTypeToPythonClusterObjectType entryType ns=(asUpperCamelCase parent.name)}} = {{getPythonFieldDefault entryType ns=(asUpperCamelCase parent.name)}} {{else}} - value: '{{zapTypeToPythonClusterObjectType type ns=(asUpperCamelCase parent.name)}}' = {{getPythonFieldDefault type ns=(asUpperCamelCase parent.name)}} + value: {{zapTypeToPythonClusterObjectType type ns=(asUpperCamelCase parent.name)}} = {{getPythonFieldDefault type ns=(asUpperCamelCase parent.name)}} {{/if}} {{/zcl_attributes_server}} @@ -207,7 +208,7 @@ class {{asUpperCamelCase name}}(Cluster): {{#first}} {{/first}} - {{ asLowerCamelCase name }}: '{{zapTypeToPythonClusterObjectType type ns=(asUpperCamelCase parent.parent.name)}}' = {{getPythonFieldDefault type ns=(asUpperCamelCase parent.parent.name)}} + {{ asLowerCamelCase name }}: {{zapTypeToPythonClusterObjectType type ns=(asUpperCamelCase parent.parent.name)}} = {{getPythonFieldDefault type ns=(asUpperCamelCase parent.parent.name)}} {{/zcl_event_fields}} {{/zcl_events}} From d5886bc32eaba2c4cba350de17c2069dcd3a3fa6 Mon Sep 17 00:00:00 2001 From: Romulo Quidute Filho <116586593+rquidute@users.noreply.github.com> Date: Thu, 17 Oct 2024 10:41:04 -0300 Subject: [PATCH 016/149] Handle logging.info at matter_testing_support.py (#36070) * Handle logging.info at matter_testing_support.py * Move self.print_step instruction * restyled --- .../chip/testing/matter_testing.py | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/python_testing/matter_testing_infrastructure/chip/testing/matter_testing.py b/src/python_testing/matter_testing_infrastructure/chip/testing/matter_testing.py index 2d23a9f84b0192..b16d1b42a08b45 100644 --- a/src/python_testing/matter_testing_infrastructure/chip/testing/matter_testing.py +++ b/src/python_testing/matter_testing_infrastructure/chip/testing/matter_testing.py @@ -1429,8 +1429,7 @@ def mark_current_step_skipped(self): # TODO: I very much do not want to have people passing in strings here. Do we really need the expression # as a string? Does it get used by the TH? self.runner_hook.step_skipped(name=str(num), expression="") - else: - logging.info(f'**** Skipping: {num}') + logging.info(f'**** Skipping: {num}') self.step_skipped = True def skip_step(self, step): @@ -1465,6 +1464,8 @@ def step(self, step: typing.Union[int, str], endpoint: Optional[int] = None): asserts.fail(f'Unexpected test step: {step} - steps not called in order, or step does not exist') current_step = steps[self.current_step_index] + self.print_step(step, current_step.description, endpoint) + if self.runner_hook: # If we've reached the next step with no assertion and the step wasn't skipped, it passed if not self.step_skipped and self.current_step_index != 0: @@ -1477,11 +1478,7 @@ def step(self, step: typing.Union[int, str], endpoint: Optional[int] = None): # TODO: it seems like the step start should take a number and a name name = f'{step} : {current_step.description}' - self.print_step(step, current_step.description, endpoint) self.runner_hook.step_start(name=name, endpoint=current_step.endpoint) - else: - self.print_step(step, current_step.description) - self.step_start_time = datetime.now(tz=timezone.utc) self.current_step_index += 1 self.step_skipped = False From 190c5c8eb90a3b806d1c2e60c5622047b1706dec Mon Sep 17 00:00:00 2001 From: Marius Preda Date: Thu, 17 Oct 2024 17:21:59 +0300 Subject: [PATCH 017/149] [NXP][third_party] Border router updates and fixes (#36118) * [NXP][third_party] Border router updates and fixes Fixed selecting correct DnsSd implementation when Border Router is enabled. Fix an issue with the SRP client starting even when the device is running in Border Router mode. Removed ChipDnssdShutdown function, there is no use for it. Removed unused OpenThread define. Signed-off-by: Marius Preda * Restyled by clang-format --------- Signed-off-by: Marius Preda Co-authored-by: Restyled.io --- .../source/CommonDeviceCallbacks.cpp | 20 ++++++++++--------- src/platform/nxp/common/DnssdImpl.cpp | 16 ++++++++++++--- src/platform/nxp/common/DnssdImplBr.cpp | 14 ++++--------- src/platform/nxp/rt/rw61x/BUILD.gn | 1 - .../platforms/nxp/rt/rw61x/BUILD.gn | 1 - 5 files changed, 28 insertions(+), 24 deletions(-) diff --git a/examples/platform/nxp/common/device_callbacks/source/CommonDeviceCallbacks.cpp b/examples/platform/nxp/common/device_callbacks/source/CommonDeviceCallbacks.cpp index 1bab4b09f58eda..5d877aad9bed7a 100644 --- a/examples/platform/nxp/common/device_callbacks/source/CommonDeviceCallbacks.cpp +++ b/examples/platform/nxp/common/device_callbacks/source/CommonDeviceCallbacks.cpp @@ -79,7 +79,16 @@ void chip::NXP::App::CommonDeviceCallbacks::DeviceEventCallback(const ChipDevice case DeviceEventType::kCommissioningComplete: CommonDeviceCallbacks::OnComissioningComplete(event); break; -#endif +#if CHIP_DEVICE_CONFIG_ENABLE_WPA + case DeviceEventType::kThreadConnectivityChange: + if (!ConnectivityMgr().IsWiFiStationConnected() && (event->ThreadConnectivityChange.Result == kConnectivity_Established)) + { + // Restart DnsSd service when operating as Matter over Thread + chip::app::DnssdServer::Instance().StartServer(); + } + break; +#endif // CHIP_DEVICE_CONFIG_ENABLE_WPA +#endif // CHIP_ENABLE_OPENTHREAD case DeviceLayer::DeviceEventType::kDnssdInitialized: ChipLogProgress(DeviceLayer, "kDnssdInitialized"); #if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR @@ -158,20 +167,13 @@ void chip::NXP::App::CommonDeviceCallbacks::OnSessionEstablished(chip::DeviceLay #if CHIP_ENABLE_OPENTHREAD void chip::NXP::App::CommonDeviceCallbacks::OnComissioningComplete(const chip::DeviceLayer::ChipDeviceEvent * event) { -#ifndef _NO_GENERIC_THREAD_NETWORK_COMMISSIONING_DRIVER_ #if CHIP_DEVICE_CONFIG_ENABLE_WPA - if (ConnectivityMgr().IsWiFiStationConnected()) - { - // Disable thr nwk commissioining cluster - app::Clusters::NetworkCommissioning::Attributes::InterfaceEnabled::Set(CHIP_DEVICE_CONFIG_THREAD_NETWORK_ENDPOINT_ID, 0); - } - else if (ConnectivityMgr().IsThreadProvisioned()) + if (!ConnectivityMgr().IsWiFiStationConnected() && ConnectivityMgr().IsThreadProvisioned()) { // Set WIFI cluster interface attribute to disable. app::Clusters::NetworkCommissioning::Attributes::InterfaceEnabled::Set(0, 0); } #endif // CHIP_DEVICE_CONFIG_ENABLE_WPA -#endif // _NO_GENERIC_THREAD_NETWORK_COMMISSIONING_DRIVER_ #if CHIP_DEVICE_CONFIG_CHIPOBLE_DISABLE_ADVERTISING_WHEN_PROVISIONED /* diff --git a/src/platform/nxp/common/DnssdImpl.cpp b/src/platform/nxp/common/DnssdImpl.cpp index 439327017897b2..5b35693534059f 100644 --- a/src/platform/nxp/common/DnssdImpl.cpp +++ b/src/platform/nxp/common/DnssdImpl.cpp @@ -33,15 +33,25 @@ namespace Dnssd { CHIP_ERROR ChipDnssdInit(DnssdAsyncReturnCallback initCallback, DnssdAsyncReturnCallback errorCallback, void * context) { - NxpChipDnssdInit(initCallback, errorCallback, context); - OpenThreadDnssdInit(initCallback, errorCallback, context); + if (ConnectivityMgr().IsWiFiStationConnected()) + { + ReturnErrorOnFailure(NxpChipDnssdInit(initCallback, errorCallback, context)); + } + else if (ConnectivityMgr().IsThreadProvisioned()) + { + ReturnErrorOnFailure(OpenThreadDnssdInit(initCallback, errorCallback, context)); + } + else + { + initCallback(context, CHIP_ERROR_INCORRECT_STATE); + } return CHIP_NO_ERROR; } void ChipDnssdShutdown() { - NxpChipDnssdShutdown(); + // Empty implementation. Intentionally left blank } CHIP_ERROR ChipDnssdPublishService(const DnssdService * service, DnssdPublishCallback callback, void * context) diff --git a/src/platform/nxp/common/DnssdImplBr.cpp b/src/platform/nxp/common/DnssdImplBr.cpp index 6b84f1f258d8be..56ccb6f13ade52 100644 --- a/src/platform/nxp/common/DnssdImplBr.cpp +++ b/src/platform/nxp/common/DnssdImplBr.cpp @@ -144,23 +144,17 @@ static uint32_t mServiceListFreeIndex; CHIP_ERROR NxpChipDnssdInit(DnssdAsyncReturnCallback initCallback, DnssdAsyncReturnCallback errorCallback, void * context) { - CHIP_ERROR error = CHIP_NO_ERROR; - otInstance * thrInstancePtr = ThreadStackMgrImpl().OTInstance(); - struct netif * extNetif = (ConnectivityManagerImpl().GetExternalInterface()).GetPlatformInterface(); - - // Don't try to do anything until the mDNS server is started - VerifyOrExit(otMdnsIsEnabled(thrInstancePtr), error = CHIP_ERROR_INCORRECT_STATE); + struct netif * extNetif = (ConnectivityManagerImpl().GetExternalInterface()).GetPlatformInterface(); mNetifIndex = netif_get_index(extNetif); + initCallback(context, CHIP_NO_ERROR); -exit: - initCallback(context, error); - return error; + return CHIP_NO_ERROR; } void NxpChipDnssdShutdown() { - otMdnsSetEnabled(ThreadStackMgrImpl().OTInstance(), false, 0); + // Empty implementation. Intentionally left blank } #if USE_MDNS_NEXT_SERVICE_API CHIP_ERROR NxpChipDnssdRemoveServices() diff --git a/src/platform/nxp/rt/rw61x/BUILD.gn b/src/platform/nxp/rt/rw61x/BUILD.gn index e80dd3cbd823f4..7ac204e92c55e9 100644 --- a/src/platform/nxp/rt/rw61x/BUILD.gn +++ b/src/platform/nxp/rt/rw61x/BUILD.gn @@ -179,7 +179,6 @@ static_library("nxp_platform") { if (chip_mdns == "platform") { if (chip_enable_wifi) { sources += [ - "../../../OpenThread/DnssdImpl.cpp", "../../../OpenThread/OpenThreadDnssdImpl.cpp", "../../../OpenThread/OpenThreadDnssdImpl.h", "../../common/DnssdImpl.cpp", diff --git a/third_party/openthread/platforms/nxp/rt/rw61x/BUILD.gn b/third_party/openthread/platforms/nxp/rt/rw61x/BUILD.gn index 978c45f8a6da8d..6c00f94b3a077e 100644 --- a/third_party/openthread/platforms/nxp/rt/rw61x/BUILD.gn +++ b/third_party/openthread/platforms/nxp/rt/rw61x/BUILD.gn @@ -52,7 +52,6 @@ config("openthread_rw61x_config") { "OPENTHREAD_CONFIG_BORDER_AGENT_ENABLE=1", "OPENTHREAD_CONFIG_BORDER_AGENT_ID_ENABLE=1", "OPENTHREAD_CONFIG_BORDER_ROUTING_DHCP6_PD_ENABLE=1", - "OPENTHREAD_CONFIG_GENERIC_TASKLET_ENABLE=1", "OPENTHREAD_CONFIG_SRP_SERVER_ADVERTISING_PROXY_ENABLE=1", "OPENTHREAD_CONFIG_DNSSD_DISCOVERY_PROXY_ENABLE=1", "OPENTHREAD_CONFIG_MULTICAST_DNS_ENABLE=1", From d7f99c7b17ab42148528f82695e72c8e950cbc8d Mon Sep 17 00:00:00 2001 From: Yufeng Wang Date: Thu, 17 Oct 2024 08:02:17 -0700 Subject: [PATCH 018/149] [Fabric-Admin] Cleanup extra override method (#36109) --- .../device_manager/DeviceSynchronization.cpp | 30 +++++++++---------- .../device_manager/UniqueIdGetter.cpp | 5 ---- .../device_manager/UniqueIdGetter.h | 1 - 3 files changed, 15 insertions(+), 21 deletions(-) diff --git a/examples/fabric-admin/device_manager/DeviceSynchronization.cpp b/examples/fabric-admin/device_manager/DeviceSynchronization.cpp index ec350239d7be38..26f4d7e91bc479 100644 --- a/examples/fabric-admin/device_manager/DeviceSynchronization.cpp +++ b/examples/fabric-admin/device_manager/DeviceSynchronization.cpp @@ -239,23 +239,23 @@ void DeviceSynchronizer::GetUniqueId() auto remoteBridgeNodeId = DeviceMgr().GetRemoteBridgeNodeId(); EndpointId remoteEndpointIdOfInterest = device->GetEndpointId(); - ChipLogDetail(NotSpecified, "Attempting to get UniqueId from remote Fabric Sync Aggregator") CHIP_ERROR err = - mUniqueIdGetter.GetUniqueId( - [this](std::optional aUniqueId) { - if (aUniqueId.has_value()) - { + ChipLogDetail(NotSpecified, "Attempting to get UniqueId from remote Fabric Sync Aggregator"); + CHIP_ERROR err = mUniqueIdGetter.GetUniqueId( + [this](std::optional aUniqueId) { + if (aUniqueId.has_value()) + { #if defined(PW_RPC_ENABLED) - this->mCurrentDeviceData.has_unique_id = true; - memcpy(this->mCurrentDeviceData.unique_id, aUniqueId.value().data(), aUniqueId.value().size()); + this->mCurrentDeviceData.has_unique_id = true; + memcpy(this->mCurrentDeviceData.unique_id, aUniqueId.value().data(), aUniqueId.value().size()); #endif - } - else - { - ChipLogError(NotSpecified, "We expected to get UniqueId from remote Fabric Sync Aggregator, but failed"); - } - this->SynchronizationCompleteAddDevice(); - }, - *mController, remoteBridgeNodeId, remoteEndpointIdOfInterest); + } + else + { + ChipLogError(NotSpecified, "We expected to get UniqueId from remote Fabric Sync Aggregator, but failed"); + } + this->SynchronizationCompleteAddDevice(); + }, + *mController, remoteBridgeNodeId, remoteEndpointIdOfInterest); if (err == CHIP_NO_ERROR) { diff --git a/examples/fabric-admin/device_manager/UniqueIdGetter.cpp b/examples/fabric-admin/device_manager/UniqueIdGetter.cpp index 49ce9b663c27af..3a6d6af69d032b 100644 --- a/examples/fabric-admin/device_manager/UniqueIdGetter.cpp +++ b/examples/fabric-admin/device_manager/UniqueIdGetter.cpp @@ -95,11 +95,6 @@ void UniqueIdGetter::OnAttributeData(const ConcreteDataAttributePath & path, TLV } } -void UniqueIdGetter::OnReportEnd() -{ - // We will call mOnDoneCallback in OnDone. -} - void UniqueIdGetter::OnError(CHIP_ERROR error) { ChipLogProgress(NotSpecified, "Error Getting UID: %" CHIP_ERROR_FORMAT, error.Format()); diff --git a/examples/fabric-admin/device_manager/UniqueIdGetter.h b/examples/fabric-admin/device_manager/UniqueIdGetter.h index 6680adf5bdfc97..86d5d82f656bd5 100644 --- a/examples/fabric-admin/device_manager/UniqueIdGetter.h +++ b/examples/fabric-admin/device_manager/UniqueIdGetter.h @@ -51,7 +51,6 @@ class UniqueIdGetter : public chip::app::ReadClient::Callback /////////////////////////////////////////////////////////////// void OnAttributeData(const chip::app::ConcreteDataAttributePath & path, chip::TLV::TLVReader * data, const chip::app::StatusIB & status) override; - void OnReportEnd() override; void OnError(CHIP_ERROR error) override; void OnDone(chip::app::ReadClient * apReadClient) override; From e150e067de18e0a07cef604162ce9f424452de27 Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Thu, 17 Oct 2024 11:11:51 -0400 Subject: [PATCH 019/149] Add `emberAfMetadataStructureGeneration` for codegen data model. (#36104) CodegenDataModel is using caching to speed up queries on clusters. However dynamic endpoints can be created/removed at will and in those cases old cluster pointers should not be re-used. --- .../CodegenDataModelProvider.cpp | 8 +++++--- .../CodegenDataModelProvider.h | 1 + src/app/util/attribute-storage.cpp | 13 +++++++++++++ src/app/util/attribute-storage.h | 8 ++++++++ src/app/util/mock/attribute-storage.cpp | 12 ++++++++++-- 5 files changed, 37 insertions(+), 5 deletions(-) diff --git a/src/app/codegen-data-model-provider/CodegenDataModelProvider.cpp b/src/app/codegen-data-model-provider/CodegenDataModelProvider.cpp index 7f7b7e14b8b752..2fb542c768aac0 100644 --- a/src/app/codegen-data-model-provider/CodegenDataModelProvider.cpp +++ b/src/app/codegen-data-model-provider/CodegenDataModelProvider.cpp @@ -619,8 +619,9 @@ std::optional CodegenDataModelProvider::TryFindAttributeIndex(const Em const EmberAfCluster * CodegenDataModelProvider::FindServerCluster(const ConcreteClusterPath & path) { - // cache things - if (mPreviouslyFoundCluster.has_value() && (mPreviouslyFoundCluster->path == path)) + if (mPreviouslyFoundCluster.has_value() && (mPreviouslyFoundCluster->path == path) && + (mEmberMetadataStructureGeneration == emberAfMetadataStructureGeneration())) + { return mPreviouslyFoundCluster->cluster; } @@ -628,7 +629,8 @@ const EmberAfCluster * CodegenDataModelProvider::FindServerCluster(const Concret const EmberAfCluster * cluster = emberAfFindServerCluster(path.mEndpointId, path.mClusterId); if (cluster != nullptr) { - mPreviouslyFoundCluster = std::make_optional(path, cluster); + mPreviouslyFoundCluster = std::make_optional(path, cluster); + mEmberMetadataStructureGeneration = emberAfMetadataStructureGeneration(); } return cluster; } diff --git a/src/app/codegen-data-model-provider/CodegenDataModelProvider.h b/src/app/codegen-data-model-provider/CodegenDataModelProvider.h index f6d6e4e4ed4be3..085ae67ec392ab 100644 --- a/src/app/codegen-data-model-provider/CodegenDataModelProvider.h +++ b/src/app/codegen-data-model-provider/CodegenDataModelProvider.h @@ -137,6 +137,7 @@ class CodegenDataModelProvider : public chip::app::DataModel::Provider ClusterReference(const ConcreteClusterPath p, const EmberAfCluster * c) : path(p), cluster(c) {} }; std::optional mPreviouslyFoundCluster; + unsigned mEmberMetadataStructureGeneration = 0; /// Finds the specified ember cluster /// diff --git a/src/app/util/attribute-storage.cpp b/src/app/util/attribute-storage.cpp index adc728157c3a1e..51c01c7e43fa80 100644 --- a/src/app/util/attribute-storage.cpp +++ b/src/app/util/attribute-storage.cpp @@ -93,6 +93,11 @@ uint8_t singletonAttributeData[ACTUAL_SINGLETONS_SIZE]; uint16_t emberEndpointCount = 0; +/// Determines a incremental unique index for ember +/// metadata that is increased whenever a structural change is made to the +/// ember metadata (e.g. changing dynamic endpoints or enabling/disabling endpoints) +unsigned emberMetadataStructureGeneration = 0; + // If we have attributes that are more than 4 bytes, then // we need this data block for the defaults #if (defined(GENERATED_DEFAULTS) && GENERATED_DEFAULTS_COUNT) @@ -315,6 +320,7 @@ CHIP_ERROR emberAfSetDynamicEndpoint(uint16_t index, EndpointId id, const EmberA // Now enable the endpoint. emberAfEndpointEnableDisable(id, true); + emberMetadataStructureGeneration++; return CHIP_NO_ERROR; } @@ -332,6 +338,7 @@ EndpointId emberAfClearDynamicEndpoint(uint16_t index) emAfEndpoints[index].endpoint = kInvalidEndpointId; } + emberMetadataStructureGeneration++; return ep; } @@ -944,9 +951,15 @@ bool emberAfEndpointEnableDisable(EndpointId endpoint, bool enable) emberAfGlobalInteractionModelAttributesChangedListener()); } + emberMetadataStructureGeneration++; return true; } +unsigned emberAfMetadataStructureGeneration() +{ + return emberMetadataStructureGeneration; +} + // Returns the index of a given endpoint. Does not consider disabled endpoints. uint16_t emberAfIndexFromEndpoint(EndpointId endpoint) { diff --git a/src/app/util/attribute-storage.h b/src/app/util/attribute-storage.h index 9d2dcc60bb3f05..711f6a7cff768d 100644 --- a/src/app/util/attribute-storage.h +++ b/src/app/util/attribute-storage.h @@ -312,6 +312,14 @@ void emberAfAttributeChanged(chip::EndpointId endpoint, chip::ClusterId clusterI /// any cluster data versions. void emberAfEndpointChanged(chip::EndpointId endpoint, chip::app::AttributesChangedListener * listener); +/// Maintains a increasing index of structural changes within ember +/// that determine if existing "indexes" and metadata pointers within ember +/// are still valid or not. +/// +/// Changes to metadata structure (e.g. endpoint enable/disable and dynamic endpoint changes) +/// are reflected in this generation count changing. +unsigned emberAfMetadataStructureGeneration(); + namespace chip { namespace app { diff --git a/src/app/util/mock/attribute-storage.cpp b/src/app/util/mock/attribute-storage.cpp index 256d0a3a880886..57f3d1e5216264 100644 --- a/src/app/util/mock/attribute-storage.cpp +++ b/src/app/util/mock/attribute-storage.cpp @@ -61,8 +61,9 @@ using namespace Clusters::Globals::Attributes; namespace { -DataVersion dataVersion = 0; -const MockNodeConfig * mockConfig = nullptr; +unsigned metadataStructureGeneration = 0; +DataVersion dataVersion = 0; +const MockNodeConfig * mockConfig = nullptr; const MockNodeConfig & DefaultMockNodeConfig() { @@ -342,6 +343,11 @@ void emberAfAttributeChanged(EndpointId endpoint, ClusterId clusterId, Attribute listener->MarkDirty(AttributePathParams(endpoint, clusterId, attributeId)); } +unsigned emberAfMetadataStructureGeneration() +{ + return metadataStructureGeneration; +} + namespace chip { namespace app { @@ -494,12 +500,14 @@ CHIP_ERROR ReadSingleMockClusterData(FabricIndex aAccessingFabricIndex, const Co void SetMockNodeConfig(const MockNodeConfig & config) { + metadataStructureGeneration++; mockConfig = &config; } /// Resets the mock attribute storage to the default configuration. void ResetMockNodeConfig() { + metadataStructureGeneration++; mockConfig = nullptr; } From dead378d8d2dca64aa610f9c9447ef24523e469a Mon Sep 17 00:00:00 2001 From: Terence Hampson Date: Thu, 17 Oct 2024 11:39:33 -0400 Subject: [PATCH 020/149] Add plumbing for BRBINFO reachability change (#36101) --- .../protos/fabric_bridge_service.proto | 6 +++++ .../pigweed/rpc_services/FabricBridge.h | 5 ++++ .../include/BridgedDevice.h | 3 +++ .../src/BridgedDevice.cpp | 23 +++++++++++++++++++ .../fabric-bridge-app/linux/RpcServer.cpp | 21 +++++++++++++++++ 5 files changed, 58 insertions(+) diff --git a/examples/common/pigweed/protos/fabric_bridge_service.proto b/examples/common/pigweed/protos/fabric_bridge_service.proto index 4e01d4ec5c7e78..f1312f22ea0e75 100644 --- a/examples/common/pigweed/protos/fabric_bridge_service.proto +++ b/examples/common/pigweed/protos/fabric_bridge_service.proto @@ -34,9 +34,15 @@ message AdministratorCommissioningChanged { optional uint32 opener_vendor_id = 4; } +message ReachabilityChanged { + ScopedNode id = 1; + bool reachability = 2; +} + service FabricBridge { rpc AddSynchronizedDevice(SynchronizedDevice) returns (pw.protobuf.Empty){} rpc RemoveSynchronizedDevice(SynchronizedDevice) returns (pw.protobuf.Empty){} rpc ActiveChanged(KeepActiveChanged) returns (pw.protobuf.Empty){} rpc AdminCommissioningAttributeChanged(AdministratorCommissioningChanged) returns (pw.protobuf.Empty){} + rpc DeviceReachableChanged(ReachabilityChanged) returns (pw.protobuf.Empty){} } diff --git a/examples/common/pigweed/rpc_services/FabricBridge.h b/examples/common/pigweed/rpc_services/FabricBridge.h index 9bd520278c13b4..9a1dee017e3be6 100644 --- a/examples/common/pigweed/rpc_services/FabricBridge.h +++ b/examples/common/pigweed/rpc_services/FabricBridge.h @@ -54,6 +54,11 @@ class FabricBridge : public pw_rpc::nanopb::FabricBridge::Service { return pw::Status::Unimplemented(); } + + virtual pw::Status DeviceReachableChanged(const chip_rpc_ReachabilityChanged & request, pw_protobuf_Empty & response) + { + return pw::Status::Unimplemented(); + } }; } // namespace rpc diff --git a/examples/fabric-bridge-app/fabric-bridge-common/include/BridgedDevice.h b/examples/fabric-bridge-app/fabric-bridge-common/include/BridgedDevice.h index 526ecfff2157f2..d2c5a64b9ef4b7 100644 --- a/examples/fabric-bridge-app/fabric-bridge-common/include/BridgedDevice.h +++ b/examples/fabric-bridge-app/fabric-bridge-common/include/BridgedDevice.h @@ -54,6 +54,9 @@ class BridgedDevice [[nodiscard]] bool IsReachable() const { return mReachable; } void SetReachable(bool reachable); + // Reachability attribute changed and requires marking attribute as dirty and sending + // event. + void ReachableChanged(bool reachable); void LogActiveChangeEvent(uint32_t promisedActiveDurationMs); diff --git a/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDevice.cpp b/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDevice.cpp index 7d588112997570..f462d1cce6efd5 100644 --- a/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDevice.cpp +++ b/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDevice.cpp @@ -65,6 +65,29 @@ void BridgedDevice::SetReachable(bool reachable) } } +void BridgedDevice::ReachableChanged(bool reachable) +{ + EndpointId endpointId = mEndpointId; + bool reachableChanged = (mReachable != reachable); + if (reachableChanged) + { + SetReachable(reachable); + DeviceLayer::SystemLayer().ScheduleLambda([endpointId]() { + MatterReportingAttributeChangeCallback(endpointId, app::Clusters::BridgedDeviceBasicInformation::Id, + app::Clusters::BridgedDeviceBasicInformation::Attributes::Reachable::Id); + + app::Clusters::BridgedDeviceBasicInformation::Events::ReachableChanged::Type event{}; + EventNumber eventNumber = 0; + + CHIP_ERROR err = app::LogEvent(event, endpointId, eventNumber); + if (err != CHIP_NO_ERROR) + { + ChipLogProgress(NotSpecified, "LogEvent for ActiveChanged failed %s", err.AsString()); + } + }); + } +} + void BridgedDevice::SetAdminCommissioningAttributes(const AdminCommissioningAttributes & aAdminCommissioningAttributes) { EndpointId endpointId = mEndpointId; diff --git a/examples/fabric-bridge-app/linux/RpcServer.cpp b/examples/fabric-bridge-app/linux/RpcServer.cpp index 8271cc3c49f041..5fea43c6ef2953 100644 --- a/examples/fabric-bridge-app/linux/RpcServer.cpp +++ b/examples/fabric-bridge-app/linux/RpcServer.cpp @@ -48,6 +48,7 @@ class FabricBridge final : public chip::rpc::FabricBridge pw::Status ActiveChanged(const chip_rpc_KeepActiveChanged & request, pw_protobuf_Empty & response) override; pw::Status AdminCommissioningAttributeChanged(const chip_rpc_AdministratorCommissioningChanged & request, pw_protobuf_Empty & response) override; + pw::Status DeviceReachableChanged(const chip_rpc_ReachabilityChanged & request, pw_protobuf_Empty & response) override; }; pw::Status FabricBridge::AddSynchronizedDevice(const chip_rpc_SynchronizedDevice & request, pw_protobuf_Empty & response) @@ -210,6 +211,26 @@ pw::Status FabricBridge::AdminCommissioningAttributeChanged(const chip_rpc_Admin return pw::OkStatus(); } +pw::Status FabricBridge::DeviceReachableChanged(const chip_rpc_ReachabilityChanged & request, pw_protobuf_Empty & response) +{ + VerifyOrReturnValue(request.has_id, pw::Status::InvalidArgument()); + ScopedNodeId scopedNodeId(request.id.node_id, request.id.fabric_index); + ChipLogProgress(NotSpecified, "Received device reachable changed: Id=[%d:" ChipLogFormatX64 "]", scopedNodeId.GetFabricIndex(), + ChipLogValueX64(scopedNodeId.GetNodeId())); + + auto * device = BridgeDeviceMgr().GetDeviceByScopedNodeId(scopedNodeId); + if (device == nullptr) + { + ChipLogError(NotSpecified, "Could not find bridged device associated with Id=[%d:0x" ChipLogFormatX64 "]", + scopedNodeId.GetFabricIndex(), ChipLogValueX64(scopedNodeId.GetNodeId())); + return pw::Status::NotFound(); + } + + device->ReachableChanged(request.reachability); + + return pw::OkStatus(); +} + FabricBridge fabric_bridge_service; #endif // defined(PW_RPC_FABRIC_BRIDGE_SERVICE) && PW_RPC_FABRIC_BRIDGE_SERVICE From 8f4fd1dbb6ad6f3ad3e67745618225904ab77ee1 Mon Sep 17 00:00:00 2001 From: bhmanda-silabs <107180296+bhmanda-silabs@users.noreply.github.com> Date: Thu, 17 Oct 2024 22:06:02 +0530 Subject: [PATCH 021/149] Updated docker file for wiseconnect-wifi-bt-sdk to 2.10.3 (#36126) --- integrations/docker/images/base/chip-build/version | 2 +- .../docker/images/stage-2/chip-build-efr32/Dockerfile | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/integrations/docker/images/base/chip-build/version b/integrations/docker/images/base/chip-build/version index ccb98d6cde3284..9ce87dc9432ce1 100644 --- a/integrations/docker/images/base/chip-build/version +++ b/integrations/docker/images/base/chip-build/version @@ -1 +1 @@ -83 : [Silabs] Update Silabs docker WiseConnect 3.3.3 +84 : [Silabs] Update Silabs docker WiseConnect-wifi-bt-sdk 2.10.3 \ No newline at end of file diff --git a/integrations/docker/images/stage-2/chip-build-efr32/Dockerfile b/integrations/docker/images/stage-2/chip-build-efr32/Dockerfile index e3f4145d8c1950..230a5bbb1fd1d0 100644 --- a/integrations/docker/images/stage-2/chip-build-efr32/Dockerfile +++ b/integrations/docker/images/stage-2/chip-build-efr32/Dockerfile @@ -23,8 +23,8 @@ RUN wget https://github.com/SiliconLabs/simplicity_sdk/releases/download/v2024.6 && find /tmp/simplicity_sdk/protocol/openthread -name "*efr32mg21*" -delete \ && : # last line -# Clone WiSeConnect Wi-Fi and Bluetooth Software 2.10.0 (f94b83d) -RUN git clone --depth=1 --single-branch --branch=2.10.0 https://github.com/SiliconLabs/wiseconnect-wifi-bt-sdk.git /tmp/wiseconnect-wifi-bt-sdk && \ +# Clone WiSeConnect Wi-Fi and Bluetooth Software 2.10.3 (b6d6cb5) +RUN git clone --depth=1 --single-branch --branch=2.10.3 https://github.com/SiliconLabs/wiseconnect-wifi-bt-sdk.git /tmp/wiseconnect-wifi-bt-sdk && \ cd /tmp/wiseconnect-wifi-bt-sdk && \ rm -rf .git \ && : # last line From 7cab1aab819185d71f7c968dd52ef7e7993adbf9 Mon Sep 17 00:00:00 2001 From: Terence Hampson Date: Thu, 17 Oct 2024 14:22:10 -0400 Subject: [PATCH 022/149] Use ScopedNodeId for fabric sync CADMIN subscription (#36121) * Use ScopedNodeId for fabric sync CADMIN subscription * Restyled by clang-format --------- Co-authored-by: Restyled.io --- .../device_manager/DeviceSubscription.cpp | 22 ++++++++++--------- .../device_manager/DeviceSubscription.h | 6 ++--- .../DeviceSubscriptionManager.cpp | 18 +++++++-------- .../DeviceSubscriptionManager.h | 21 +++++++++++++----- .../device_manager/DeviceSynchronization.cpp | 3 ++- 5 files changed, 42 insertions(+), 28 deletions(-) diff --git a/examples/fabric-admin/device_manager/DeviceSubscription.cpp b/examples/fabric-admin/device_manager/DeviceSubscription.cpp index a5625707a5363b..0da2bdddd4fbf5 100644 --- a/examples/fabric-admin/device_manager/DeviceSubscription.cpp +++ b/examples/fabric-admin/device_manager/DeviceSubscription.cpp @@ -120,7 +120,7 @@ void DeviceSubscription::OnDone(ReadClient * apReadClient) // After calling mOnDoneCallback we are indicating that `this` is deleted and we shouldn't do anything else with // DeviceSubscription. MoveToState(State::AwaitingDestruction); - mOnDoneCallback(mNodeId); + mOnDoneCallback(mScopedNodeId); } void DeviceSubscription::OnError(CHIP_ERROR error) @@ -135,7 +135,7 @@ void DeviceSubscription::OnDeviceConnected(Messaging::ExchangeManager & exchange // After calling mOnDoneCallback we are indicating that `this` is deleted and we shouldn't do anything else with // DeviceSubscription. MoveToState(State::AwaitingDestruction); - mOnDoneCallback(mNodeId); + mOnDoneCallback(mScopedNodeId); return; } VerifyOrDie(mState == State::Connecting); @@ -160,7 +160,7 @@ void DeviceSubscription::OnDeviceConnected(Messaging::ExchangeManager & exchange // After calling mOnDoneCallback we are indicating that `this` is deleted and we shouldn't do anything else with // DeviceSubscription. MoveToState(State::AwaitingDestruction); - mOnDoneCallback(mNodeId); + mOnDoneCallback(mScopedNodeId); return; } MoveToState(State::SubscriptionStarted); @@ -203,29 +203,31 @@ void DeviceSubscription::OnDeviceConnectionFailure(const ScopedNodeId & peerId, // After calling mOnDoneCallback we are indicating that `this` is deleted and we shouldn't do anything else with // DeviceSubscription. MoveToState(State::AwaitingDestruction); - mOnDoneCallback(mNodeId); + mOnDoneCallback(mScopedNodeId); } CHIP_ERROR DeviceSubscription::StartSubscription(OnDoneCallback onDoneCallback, Controller::DeviceController & controller, - NodeId nodeId) + ScopedNodeId scopedNodeId) { assertChipStackLockedByCurrentThread(); VerifyOrDie(mState == State::Idle); + VerifyOrReturnError(controller.GetFabricIndex() == scopedNodeId.GetFabricIndex(), CHIP_ERROR_INVALID_ARGUMENT); - mNodeId = nodeId; + mScopedNodeId = scopedNodeId; #if defined(PW_RPC_ENABLED) mCurrentAdministratorCommissioningAttributes = chip_rpc_AdministratorCommissioningChanged_init_default; mCurrentAdministratorCommissioningAttributes.has_id = true; - mCurrentAdministratorCommissioningAttributes.id.node_id = nodeId; - mCurrentAdministratorCommissioningAttributes.id.fabric_index = controller.GetFabricIndex(); + mCurrentAdministratorCommissioningAttributes.id.node_id = scopedNodeId.GetNodeId(); + mCurrentAdministratorCommissioningAttributes.id.fabric_index = scopedNodeId.GetFabricIndex(); mCurrentAdministratorCommissioningAttributes.window_status = static_cast(Clusters::AdministratorCommissioning::CommissioningWindowStatusEnum::kWindowNotOpen); #endif mOnDoneCallback = onDoneCallback; MoveToState(State::Connecting); - CHIP_ERROR err = controller.GetConnectedDevice(nodeId, &mOnDeviceConnectedCallback, &mOnDeviceConnectionFailureCallback); + CHIP_ERROR err = + controller.GetConnectedDevice(scopedNodeId.GetNodeId(), &mOnDeviceConnectedCallback, &mOnDeviceConnectionFailureCallback); if (err != CHIP_NO_ERROR) { MoveToState(State::Idle); @@ -258,5 +260,5 @@ void DeviceSubscription::StopSubscription() // After calling mOnDoneCallback we are indicating that `this` is deleted and we shouldn't do anything else with // DeviceSubscription. MoveToState(State::AwaitingDestruction); - mOnDoneCallback(mNodeId); + mOnDoneCallback(mScopedNodeId); } diff --git a/examples/fabric-admin/device_manager/DeviceSubscription.h b/examples/fabric-admin/device_manager/DeviceSubscription.h index 5d8403777364b7..8db31d6e9037fc 100644 --- a/examples/fabric-admin/device_manager/DeviceSubscription.h +++ b/examples/fabric-admin/device_manager/DeviceSubscription.h @@ -39,12 +39,12 @@ class DeviceSubscriptionManager; class DeviceSubscription : public chip::app::ReadClient::Callback { public: - using OnDoneCallback = std::function; + using OnDoneCallback = std::function; DeviceSubscription(); CHIP_ERROR StartSubscription(OnDoneCallback onDoneCallback, chip::Controller::DeviceController & controller, - chip::NodeId nodeId); + chip::ScopedNodeId nodeId); /// This will trigger stopping the subscription. Once subscription is stopped the OnDoneCallback /// provided in StartSubscription will be called to indicate that subscription have been terminated. @@ -80,7 +80,7 @@ class DeviceSubscription : public chip::app::ReadClient::Callback void MoveToState(const State aTargetState); const char * GetStateStr() const; - chip::NodeId mNodeId = chip::kUndefinedNodeId; + chip::ScopedNodeId mScopedNodeId; OnDoneCallback mOnDoneCallback; std::unique_ptr mClient; diff --git a/examples/fabric-admin/device_manager/DeviceSubscriptionManager.cpp b/examples/fabric-admin/device_manager/DeviceSubscriptionManager.cpp index 8dd43f28751591..0410c162a8e43a 100644 --- a/examples/fabric-admin/device_manager/DeviceSubscriptionManager.cpp +++ b/examples/fabric-admin/device_manager/DeviceSubscriptionManager.cpp @@ -38,25 +38,25 @@ DeviceSubscriptionManager & DeviceSubscriptionManager::Instance() return instance; } -CHIP_ERROR DeviceSubscriptionManager::StartSubscription(Controller::DeviceController & controller, NodeId nodeId) +CHIP_ERROR DeviceSubscriptionManager::StartSubscription(Controller::DeviceController & controller, ScopedNodeId scopedNodeId) { assertChipStackLockedByCurrentThread(); - auto it = mDeviceSubscriptionMap.find(nodeId); + auto it = mDeviceSubscriptionMap.find(scopedNodeId); VerifyOrReturnError((it == mDeviceSubscriptionMap.end()), CHIP_ERROR_INCORRECT_STATE); auto deviceSubscription = std::make_unique(); VerifyOrReturnError(deviceSubscription, CHIP_ERROR_NO_MEMORY); ReturnErrorOnFailure(deviceSubscription->StartSubscription( - [this](NodeId aNodeId) { this->DeviceSubscriptionTerminated(aNodeId); }, controller, nodeId)); + [this](ScopedNodeId aNodeId) { this->DeviceSubscriptionTerminated(aNodeId); }, controller, scopedNodeId)); - mDeviceSubscriptionMap[nodeId] = std::move(deviceSubscription); + mDeviceSubscriptionMap[scopedNodeId] = std::move(deviceSubscription); return CHIP_NO_ERROR; } -CHIP_ERROR DeviceSubscriptionManager::RemoveSubscription(NodeId nodeId) +CHIP_ERROR DeviceSubscriptionManager::RemoveSubscription(ScopedNodeId scopedNodeId) { assertChipStackLockedByCurrentThread(); - auto it = mDeviceSubscriptionMap.find(nodeId); + auto it = mDeviceSubscriptionMap.find(scopedNodeId); VerifyOrReturnError((it != mDeviceSubscriptionMap.end()), CHIP_ERROR_NOT_FOUND); // We cannot safely erase the DeviceSubscription from mDeviceSubscriptionMap. // After calling StopSubscription we expect DeviceSubscription to eventually @@ -67,14 +67,14 @@ CHIP_ERROR DeviceSubscriptionManager::RemoveSubscription(NodeId nodeId) return CHIP_NO_ERROR; } -void DeviceSubscriptionManager::DeviceSubscriptionTerminated(NodeId nodeId) +void DeviceSubscriptionManager::DeviceSubscriptionTerminated(ScopedNodeId scopedNodeId) { assertChipStackLockedByCurrentThread(); - auto it = mDeviceSubscriptionMap.find(nodeId); + auto it = mDeviceSubscriptionMap.find(scopedNodeId); // DeviceSubscriptionTerminated is a private method that is expected to only // be called by DeviceSubscription when it is terminal and is ready to be // cleaned up and removed. If it is not mapped that means something has gone // really wrong and there is likely a memory leak somewhere. VerifyOrDie(it != mDeviceSubscriptionMap.end()); - mDeviceSubscriptionMap.erase(nodeId); + mDeviceSubscriptionMap.erase(scopedNodeId); } diff --git a/examples/fabric-admin/device_manager/DeviceSubscriptionManager.h b/examples/fabric-admin/device_manager/DeviceSubscriptionManager.h index 5f4e1158634a29..1b5c45fd05ae16 100644 --- a/examples/fabric-admin/device_manager/DeviceSubscriptionManager.h +++ b/examples/fabric-admin/device_manager/DeviceSubscriptionManager.h @@ -32,12 +32,23 @@ class DeviceSubscriptionManager /// Usually called after we have added a synchronized device to fabric-bridge to monitor /// for any changes that need to be propagated to fabric-bridge. - CHIP_ERROR StartSubscription(chip::Controller::DeviceController & controller, chip::NodeId nodeId); + CHIP_ERROR StartSubscription(chip::Controller::DeviceController & controller, chip::ScopedNodeId scopedNodeId); - CHIP_ERROR RemoveSubscription(chip::NodeId nodeId); + CHIP_ERROR RemoveSubscription(chip::ScopedNodeId scopedNodeId); private: - void DeviceSubscriptionTerminated(chip::NodeId nodeId); - - std::unordered_map> mDeviceSubscriptionMap; + struct ScopedNodeIdHasher + { + std::size_t operator()(const chip::ScopedNodeId & scopedNodeId) const + { + std::size_t h1 = std::hash{}(scopedNodeId.GetFabricIndex()); + std::size_t h2 = std::hash{}(scopedNodeId.GetNodeId()); + // Bitshifting h2 reduces collisions when fabricIndex == nodeId. + return h1 ^ (h2 << 1); + } + }; + + void DeviceSubscriptionTerminated(chip::ScopedNodeId scopedNodeId); + + std::unordered_map, ScopedNodeIdHasher> mDeviceSubscriptionMap; }; diff --git a/examples/fabric-admin/device_manager/DeviceSynchronization.cpp b/examples/fabric-admin/device_manager/DeviceSynchronization.cpp index 26f4d7e91bc479..6c2284018e0d19 100644 --- a/examples/fabric-admin/device_manager/DeviceSynchronization.cpp +++ b/examples/fabric-admin/device_manager/DeviceSynchronization.cpp @@ -278,7 +278,8 @@ void DeviceSynchronizer::SynchronizationCompleteAddDevice() { VerifyOrDie(mController); // TODO(#35333) Figure out how we should recover in this circumstance. - CHIP_ERROR err = DeviceSubscriptionManager::Instance().StartSubscription(*mController, mNodeId); + ScopedNodeId scopedNodeId(mNodeId, mController->GetFabricIndex()); + CHIP_ERROR err = DeviceSubscriptionManager::Instance().StartSubscription(*mController, scopedNodeId); if (err != CHIP_NO_ERROR) { ChipLogError(NotSpecified, "Failed start subscription to NodeId:" ChipLogFormatX64, ChipLogValueX64(mNodeId)); From 79168089da89160cfad1acca15bcc3bec21d7720 Mon Sep 17 00:00:00 2001 From: yeaissa <133245269+yeaissa@users.noreply.github.com> Date: Thu, 17 Oct 2024 20:26:37 +0200 Subject: [PATCH 023/149] [NXP] Fix mDNS issue with RW61x ethernet board (#36123) Noticing that mDNS resolution from the controller is failing some time after the board is commissioned. This is due to the board not responding to the mDNS queries. --- config/nxp/chip-module/Kconfig.defaults | 3 +++ config/nxp/chip-module/Kconfig.features | 2 ++ 2 files changed, 5 insertions(+) diff --git a/config/nxp/chip-module/Kconfig.defaults b/config/nxp/chip-module/Kconfig.defaults index 3d0fcf08d75eac..cd2dd74b91f788 100644 --- a/config/nxp/chip-module/Kconfig.defaults +++ b/config/nxp/chip-module/Kconfig.defaults @@ -336,6 +336,9 @@ choice NXP_ENET_DRIVER default ETH_NXP_ENET endchoice +config NET_SOCKETS_POLL_MAX + default 7 + endif # Configure MBEDTLS lib diff --git a/config/nxp/chip-module/Kconfig.features b/config/nxp/chip-module/Kconfig.features index 9c388a20f9db72..50f72eb0164f14 100644 --- a/config/nxp/chip-module/Kconfig.features +++ b/config/nxp/chip-module/Kconfig.features @@ -95,6 +95,8 @@ config CHIP_ETHERNET select NET_TCP select DNS_RESOLVER select MDNS_RESOLVER + select MDNS_RESPONDER + select DNS_SD select MBEDTLS_PKCS5_C select MBEDTLS_HKDF_C select MBEDTLS_ECDSA_C From 162b599a9f7c30dec1e4b8ead66ac0820ff054b8 Mon Sep 17 00:00:00 2001 From: Arkadiusz Bokowy Date: Thu, 17 Oct 2024 20:31:07 +0200 Subject: [PATCH 024/149] Fix unmatched Register/UnregisterReadHandlerAppCallback calls (#36119) * Fix unmatched Register/UnregisterReadHandlerAppCallback calls By moving register/unregister calls to SetUp/TearDown we will ensure that tests will not reuse stale global state from previous test case. * Cleanup * Restyled by clang-format --------- Co-authored-by: Restyled.io --- src/controller/tests/data_model/TestRead.cpp | 133 +------------------ 1 file changed, 4 insertions(+), 129 deletions(-) diff --git a/src/controller/tests/data_model/TestRead.cpp b/src/controller/tests/data_model/TestRead.cpp index 6724e0d589457f..136fbc243db340 100644 --- a/src/controller/tests/data_model/TestRead.cpp +++ b/src/controller/tests/data_model/TestRead.cpp @@ -118,6 +118,9 @@ class TestRead : public chip::Test::AppContext, public app::ReadHandler::Applica void SetUp() override { chip::Test::AppContext::SetUp(); + // Register app callback, so we can test it as well to ensure we get the right + // number of SubscriptionEstablishment/Termination callbacks. + InteractionModelEngine::GetInstance()->RegisterReadHandlerAppCallback(this); mOldProvider = InteractionModelEngine::GetInstance()->SetDataModelProvider(&CustomDataModel::Instance()); chip::Test::SetMockNodeConfig(TestMockNodeConfig()); } @@ -127,6 +130,7 @@ class TestRead : public chip::Test::AppContext, public app::ReadHandler::Applica { chip::Test::ResetMockNodeConfig(); InteractionModelEngine::GetInstance()->SetDataModelProvider(mOldProvider); + InteractionModelEngine::GetInstance()->UnregisterReadHandlerAppCallback(); chip::Test::AppContext::TearDown(); } @@ -270,11 +274,6 @@ TEST_F(TestRead, TestReadSubscribeAttributeResponseWithVersionOnlyCache) chip::app::ClusterStateCache cache(delegate, Optional::Missing(), false /*cachedData*/); chip::app::ReadPrepareParams readPrepareParams(GetSessionBobToAlice()); - // - // Test the application callback as well to ensure we get the right number of SubscriptionEstablishment/Termination - // callbacks. - // - app::InteractionModelEngine::GetInstance()->RegisterReadHandlerAppCallback(this); // read of E2C2A* and E3C2A2. Expect cache E2C2 version { @@ -352,11 +351,6 @@ TEST_F(TestRead, TestReadSubscribeAttributeResponseWithCache) chip::app::ReadPrepareParams readPrepareParams(GetSessionBobToAlice()); readPrepareParams.mMinIntervalFloorSeconds = 0; readPrepareParams.mMaxIntervalCeilingSeconds = 4; - // - // Test the application callback as well to ensure we get the right number of SubscriptionEstablishment/Termination - // callbacks. - // - app::InteractionModelEngine::GetInstance()->RegisterReadHandlerAppCallback(this); [[maybe_unused]] int testId = 0; @@ -1691,12 +1685,6 @@ TEST_F(TestRead, TestReadHandler_MultipleSubscriptions) numSubscriptionEstablishedCalls++; }; - // - // Test the application callback as well to ensure we get the right number of SubscriptionEstablishment/Termination - // callbacks. - // - app::InteractionModelEngine::GetInstance()->RegisterReadHandlerAppCallback(this); - // // Try to issue parallel subscriptions that will exceed the value for app::InteractionModelEngine::kReadHandlerPoolSize. // If heap allocation is correctly setup, this should result in it successfully servicing more than the number @@ -1727,7 +1715,6 @@ TEST_F(TestRead, TestReadHandler_MultipleSubscriptions) EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); SetMRPMode(chip::Test::MessagingContext::MRPMode::kDefault); - app::InteractionModelEngine::GetInstance()->UnregisterReadHandlerAppCallback(); } TEST_F(TestRead, TestReadHandler_SubscriptionAppRejection) @@ -1756,12 +1743,6 @@ TEST_F(TestRead, TestReadHandler_SubscriptionAppRejection) numSubscriptionEstablishedCalls++; }; - // - // Test the application callback as well to ensure we get the right number of SubscriptionEstablishment/Termination - // callbacks. - // - app::InteractionModelEngine::GetInstance()->RegisterReadHandlerAppCallback(this); - // // Test the application rejecting subscriptions. // @@ -1788,7 +1769,6 @@ TEST_F(TestRead, TestReadHandler_SubscriptionAppRejection) EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); - app::InteractionModelEngine::GetInstance()->UnregisterReadHandlerAppCallback(); mEmitSubscriptionError = false; } @@ -1831,17 +1811,6 @@ TEST_F(TestRead, TestReadHandler_SubscriptionReportingIntervalsTest1) numSubscriptionEstablishedCalls++; }; - // - // Test the application callback as well to ensure we get the right number of SubscriptionEstablishment/Termination - // callbacks. - // - app::InteractionModelEngine::GetInstance()->RegisterReadHandlerAppCallback(this); - - // - // Test the server-side application altering the subscription intervals. - // - mAlterSubscriptionIntervals = false; - EXPECT_EQ(Controller::SubscribeAttribute( &GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb, 5, 5, onSubscriptionEstablishedCb, nullptr, true), @@ -1863,9 +1832,6 @@ TEST_F(TestRead, TestReadHandler_SubscriptionReportingIntervalsTest1) EXPECT_EQ(mNumActiveSubscriptions, 0); EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); - - app::InteractionModelEngine::GetInstance()->UnregisterReadHandlerAppCallback(); - mAlterSubscriptionIntervals = false; } // Subscriber sends the request with particular max-interval value: @@ -1906,17 +1872,6 @@ TEST_F(TestRead, TestReadHandler_SubscriptionReportingIntervalsTest2) numSubscriptionEstablishedCalls++; }; - // - // Test the application callback as well to ensure we get the right number of SubscriptionEstablishment/Termination - // callbacks. - // - app::InteractionModelEngine::GetInstance()->RegisterReadHandlerAppCallback(this); - - // - // Test the server-side application altering the subscription intervals. - // - mAlterSubscriptionIntervals = false; - EXPECT_EQ(Controller::SubscribeAttribute( &GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb, 0, 10, onSubscriptionEstablishedCb, nullptr, true), @@ -1938,9 +1893,6 @@ TEST_F(TestRead, TestReadHandler_SubscriptionReportingIntervalsTest2) EXPECT_EQ(mNumActiveSubscriptions, 0); EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); - - app::InteractionModelEngine::GetInstance()->UnregisterReadHandlerAppCallback(); - mAlterSubscriptionIntervals = false; } // Subscriber sends the request with particular max-interval value: @@ -1981,12 +1933,6 @@ TEST_F(TestRead, TestReadHandler_SubscriptionReportingIntervalsTest3) numSubscriptionEstablishedCalls++; }; - // - // Test the application callback as well to ensure we get the right number of SubscriptionEstablishment/Termination - // callbacks. - // - app::InteractionModelEngine::GetInstance()->RegisterReadHandlerAppCallback(this); - // // Test the server-side application altering the subscription intervals. // @@ -2013,9 +1959,6 @@ TEST_F(TestRead, TestReadHandler_SubscriptionReportingIntervalsTest3) EXPECT_EQ(mNumActiveSubscriptions, 0); EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); - - app::InteractionModelEngine::GetInstance()->UnregisterReadHandlerAppCallback(); - mAlterSubscriptionIntervals = false; } #endif // CHIP_CONFIG_ENABLE_ICD_SERVER @@ -2049,12 +1992,6 @@ TEST_F(TestRead, TestReadHandler_SubscriptionReportingIntervalsTest4) numSubscriptionEstablishedCalls++; }; - // - // Test the application callback as well to ensure we get the right number of SubscriptionEstablishment/Termination - // callbacks. - // - app::InteractionModelEngine::GetInstance()->RegisterReadHandlerAppCallback(this); - // // Test the server-side application altering the subscription intervals. // @@ -2080,9 +2017,6 @@ TEST_F(TestRead, TestReadHandler_SubscriptionReportingIntervalsTest4) EXPECT_EQ(mNumActiveSubscriptions, 0); EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); - - app::InteractionModelEngine::GetInstance()->UnregisterReadHandlerAppCallback(); - mAlterSubscriptionIntervals = false; } #if CHIP_CONFIG_ENABLE_ICD_SERVER != 1 @@ -2125,17 +2059,6 @@ TEST_F(TestRead, TestReadHandler_SubscriptionReportingIntervalsTest5) numSubscriptionEstablishedCalls++; }; - // - // Test the application callback as well to ensure we get the right number of SubscriptionEstablishment/Termination - // callbacks. - // - app::InteractionModelEngine::GetInstance()->RegisterReadHandlerAppCallback(this); - - // - // Test the server-side application altering the subscription intervals. - // - mAlterSubscriptionIntervals = false; - EXPECT_EQ(Controller::SubscribeAttribute( &GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb, 0, 4000, onSubscriptionEstablishedCb, nullptr, true), @@ -2157,9 +2080,6 @@ TEST_F(TestRead, TestReadHandler_SubscriptionReportingIntervalsTest5) EXPECT_EQ(mNumActiveSubscriptions, 0); EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); - - app::InteractionModelEngine::GetInstance()->UnregisterReadHandlerAppCallback(); - mAlterSubscriptionIntervals = false; } // Subscriber sends the request with particular max-interval value: @@ -2200,12 +2120,6 @@ TEST_F(TestRead, TestReadHandler_SubscriptionReportingIntervalsTest6) numSubscriptionEstablishedCalls++; }; - // - // Test the application callback as well to ensure we get the right number of SubscriptionEstablishment/Termination - // callbacks. - // - app::InteractionModelEngine::GetInstance()->RegisterReadHandlerAppCallback(this); - // // Test the server-side application altering the subscription intervals. // @@ -2232,9 +2146,6 @@ TEST_F(TestRead, TestReadHandler_SubscriptionReportingIntervalsTest6) EXPECT_EQ(mNumActiveSubscriptions, 0); EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); - - app::InteractionModelEngine::GetInstance()->UnregisterReadHandlerAppCallback(); - mAlterSubscriptionIntervals = false; } // Subscriber sends the request with particular max-interval value: @@ -2274,11 +2185,6 @@ TEST_F(TestRead, TestReadHandler_SubscriptionReportingIntervalsTest7) numSubscriptionEstablishedCalls++; }; - // - // Test the application callback as well to ensure we get the right number of SubscriptionEstablishment/Termination - // callbacks. - // - app::InteractionModelEngine::GetInstance()->RegisterReadHandlerAppCallback(this); // // Test the server-side application altering the subscription intervals. @@ -2306,9 +2212,6 @@ TEST_F(TestRead, TestReadHandler_SubscriptionReportingIntervalsTest7) EXPECT_EQ(mNumActiveSubscriptions, 0); EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); - - app::InteractionModelEngine::GetInstance()->UnregisterReadHandlerAppCallback(); - mAlterSubscriptionIntervals = false; } #endif // CHIP_CONFIG_ENABLE_ICD_SERVER @@ -2341,11 +2244,6 @@ TEST_F(TestRead, TestReadHandler_SubscriptionReportingIntervalsTest8) chip::SubscriptionId aSubscriptionId) { numSubscriptionEstablishedCalls++; }; - // - // Test the application callback as well to ensure we get the right number of SubscriptionEstablishment/Termination - // callbacks. - // - app::InteractionModelEngine::GetInstance()->RegisterReadHandlerAppCallback(this); // // Test the server-side application altering the subscription intervals. @@ -2372,9 +2270,6 @@ TEST_F(TestRead, TestReadHandler_SubscriptionReportingIntervalsTest8) EXPECT_EQ(mNumActiveSubscriptions, 0); EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); - - app::InteractionModelEngine::GetInstance()->UnregisterReadHandlerAppCallback(); - mAlterSubscriptionIntervals = false; } // Subscriber sends the request with particular max-interval value: @@ -2405,17 +2300,6 @@ TEST_F(TestRead, TestReadHandler_SubscriptionReportingIntervalsTest9) numSubscriptionEstablishedCalls++; }; - // - // Test the application callback as well to ensure we get the right number of SubscriptionEstablishment/Termination - // callbacks. - // - app::InteractionModelEngine::GetInstance()->RegisterReadHandlerAppCallback(this); - - // - // Test the server-side application altering the subscription intervals. - // - mAlterSubscriptionIntervals = false; - EXPECT_EQ(Controller::SubscribeAttribute( &GetExchangeManager(), sessionHandle, kTestEndpointId, onSuccessCb, onFailureCb, 5, 4, onSubscriptionEstablishedCb, nullptr, true), @@ -2434,9 +2318,6 @@ TEST_F(TestRead, TestReadHandler_SubscriptionReportingIntervalsTest9) EXPECT_EQ(mNumActiveSubscriptions, 0); EXPECT_EQ(GetExchangeManager().GetNumActiveExchanges(), 0u); - - app::InteractionModelEngine::GetInstance()->UnregisterReadHandlerAppCallback(); - mAlterSubscriptionIntervals = false; } /** @@ -3291,8 +3172,6 @@ TEST_F(TestRead, TestReadHandler_KillOverQuotaSubscriptions) app::InteractionModelEngine::kMinSupportedSubscriptionsPerFabric * GetFabricTable().FabricCount(); const auto kExpectedParallelPaths = kExpectedParallelSubs * app::InteractionModelEngine::kMinSupportedPathsPerSubscription; - app::InteractionModelEngine::GetInstance()->RegisterReadHandlerAppCallback(this); - // Here, we set up two background perpetual read requests to simulate parallel Read + Subscriptions. // We don't care about the data read, we only care about the existence of such read transactions. TestReadCallback readCallback; @@ -3502,8 +3381,6 @@ TEST_F(TestRead, TestReadHandler_KillOldestSubscriptions) app::InteractionModelEngine::kMinSupportedSubscriptionsPerFabric * GetFabricTable().FabricCount(); const auto kExpectedParallelPaths = kExpectedParallelSubs * app::InteractionModelEngine::kMinSupportedPathsPerSubscription; - app::InteractionModelEngine::GetInstance()->RegisterReadHandlerAppCallback(this); - TestReadCallback readCallback; std::vector> readClients; @@ -3621,8 +3498,6 @@ TEST_F(TestRead, TestReadHandler_ParallelReads) auto sessionHandle = GetSessionBobToAlice(); - app::InteractionModelEngine::GetInstance()->RegisterReadHandlerAppCallback(this); - auto TestCase = [&](const TestReadHandler_ParallelReads_TestCase_Parameters & params, std::function body) { TestReadHandler_ParallelReads_TestCase(this, params, body); }; From d9c6de56df8ea92b5bda3eff12f1e8d4589222f3 Mon Sep 17 00:00:00 2001 From: Jake Ororke Date: Thu, 17 Oct 2024 11:32:05 -0700 Subject: [PATCH 025/149] [ Test ] Creating test module TC_CADMIN_1_11 (#34760) * Creating test module TC_CADMIN_1_11: - Test module created following matter-test-scripts task (https://github.com/project-chip/matter-test-scripts/issues/286): -- Open commissioning window on DUT twice using ECM then BCM [DUT - Commissionee] -- Commission DUT to TH_CR1 (can be skipped if done in a preceding test) -- TH_CR1 reads the BasicCommissioningInfo attribute from the General Commissioning cluster on EP0 and saves the MaxCumulativeFailsafeSeconds as timeout -- TH_CR1 sends an OpenCommissioningWindow command to the DUT with the CommissioningTimeout set to timeout -- TH_CR2 fully commissions the DUT -- TH_CR1 sends an OpenCommissioningWindow command to the DUT with the CommissioningTimeout set to timeout -- TH_CR1 sends an OpenCommissioningWindow command to the DUT with the CommissioningTimeout set to timeout -- TH_CR2 sends an OpenCommissioningWindow command to the DUT with the CommissioningTimeout set to timeout -- TH_CR1 sends an RevokeCommissioning command to the DUT -- TH_CR1 reads the FeatureMap from the Administrator Commissioning Cluster. If the feature map includes the BC feature bit, repeat steps 5-8 using the OpenBasicCommissioningWindow command -- TH_CR2 reads the CurrentFabricIndex attribute from the Node Operational Credentials cluster and saves as th2_idx -- TH_CR1 sends the RemoveFabric command to the DUT with the FabricIndex set to th2_idx * Restyled by autopep8 * Update tests.yaml * Update TC_CADMIN_1_11.py Updated OpenbasicCommissioningWindow to update to using correct variables. * Updated TC_CADMIN_1_11 test module: - Removed unneccessary count variable due to no longer being needed - Added expectations to TestSteps - Replaced elif with else statements in OpenCommissioningWindow and OpenBasicCommissioningWindow functions - Set busy_enum var using Clusters.AdministratorCommissioning.Enums.StatusCode.kBusy enum value - Changed method to check features for administrator commissioning cluster to check if BC bit value is contained in features * Restyled by autopep8 * Updated TC_CADMIN_1_11: - Removed unneeded prints from the code output * Restyled by autopep8 * Apply suggestions from code review Co-authored-by: C Freeman * Update TC_CADMIN_1_11.py -Added Optional function from typing library to resolve issue with latest code change * Update TC_CADMIN_1_11.py - Due to recent changes, had to update to using PyChipError for ctx.exception.err in order to handle error raised during commissioning properly * Updating TC_CADMIN_1_11: - Updated method for OpenBasicCommissiongWindow with BC feature enabled * Restyled by autopep8 * Update src/python_testing/TC_CADMIN_1_11.py Co-authored-by: C Freeman * Updated TC_CADMIN_1_11 test module: - Removed useTestCommissioner when creating self.th2 - Changed to using None instead of 0 as variable value for OpenCommissioningWindow() - Removed generate_unique_randow_value() as not needed in this test module * Updating TC_CADMIN_1_11 test module: - Resolved linting error * Updated TC_CADMIN_1_11: - Updated due to latest changes to matter_testing support module * Restyled by autopep8 * Removed TC_CADMIN_1_11.yaml and updated TC_CADMIN_1_11: - Removed Test_TC_CADMIN_1_11.yaml - Updated TC_CADMIN_1_11 python test module to enable verbose output in CI/CD pipeline. * Updated TC_CADMIN_1_11 test module: - Updated CI/CD nominclature for this test to match latest version * Updated src/app/tests/suites/manualTests.json: - Removed Test_TC_CADMIN_1_11 from MultipleFabrics section --------- Co-authored-by: Restyled.io Co-authored-by: C Freeman --- .../certification/Test_TC_CADMIN_1_11.yaml | 377 ------------------ src/app/tests/suites/manualTests.json | 1 - src/python_testing/TC_CADMIN_1_11.py | 222 +++++++++++ 3 files changed, 222 insertions(+), 378 deletions(-) delete mode 100644 src/app/tests/suites/certification/Test_TC_CADMIN_1_11.yaml create mode 100644 src/python_testing/TC_CADMIN_1_11.py diff --git a/src/app/tests/suites/certification/Test_TC_CADMIN_1_11.yaml b/src/app/tests/suites/certification/Test_TC_CADMIN_1_11.yaml deleted file mode 100644 index 26503486dd059a..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_CADMIN_1_11.yaml +++ /dev/null @@ -1,377 +0,0 @@ -# Copyright (c) 2021 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# Auto-generated scripts for harness use only, please review before automation. The endpoints and cluster names are currently set to default - -name: - 4.1.11. [TC-CADMIN-1.11] Open commissioning window on DUT twice using ECM - then BCM [DUT - Commissionee] - -PICS: - - CADMIN.S - - CADMIN.S.F00 - -config: - nodeId: 0x12344321 - cluster: "Basic Information" - endpoint: 0 - -tests: - - label: "Precondition" - verification: | - Reset Devices to factory defaults - disabled: true - - - label: "Step 1: TH_CR1 starts a commissioning process with DUT_CE" - PICS: CADMIN.S - verification: | - "1. Provision the DUT_CE (all-cluster-app) device using TH_CR1 (chip-tool ) on the raspi" - disabled: true - - - label: - "Step 2: TH_CR1 opens a commissioning window on DUT_CE using a - commissioning timeout of PIXIT.CADMIN.CwDuration seconds using ECM" - PICS: CADMIN.S.C00.Rsp - verification: | - On TH_CR1 send the below command - - ./chip-tool pairing open-commissioning-window 1 1 180 1000 3840 - - Verify the Open commisioning window on the DUT_CE(all-cluster-app) Log: - - [1660904553.796857][3537:3537] CHIP:DMG: Received command for Endpoint=0 Cluster=0x0000_003C Command=0x0000_0000 - [1660904553.796951][3537:3537] CHIP:ZCL: Received command to open commissioning window - [1660904553.797255][3537:3537] CHIP:IN: SecureSession[0xaaab142ef7f0]: Allocated Type:1 LSID:34523 - - Verify the Manual pairing code on the TH_CR1(chip-tool) Log: - - [1635864513.699433][3850:3855] CHIP:DMG: ICR moving to [CommandSen] - [1635864513.699489][3850:3855] CHIP:CTL: Manual pairing code: [36177160937] - [1635864513.699566][3850:3855] CHIP:CTL: SetupQRCode: [MT:00000CQM00YZN476420] - [1635864513.699636][3850:3855] CHIP:EM: Sending Standalone Ack for MessageCounter:2599714227 on exchange 60688i - [1635864513.699685][3850:3855] CHIP:IN: Prepared plaintext message 0xffff8a7cd960 to 0x0000000000000000 of type - disabled: true - - - label: "Step 3: DNS-SD records shows DUT_CE advertising" - verification: | - On TH_CR1 send the below command - - avahi-browse -rt _matterc._udp - + wlp5s0 IPv6 C326228BDB082BF4 _matterc._udp local - + wlp5s0 IPv6 7B6545A75C5330BE _matterc._udp local - = wlp5s0 IPv6 7B6545A75C5330BE _matterc._udp local - hostname = [E45F010F27530000.local] - address = [fe80::e65f:1ff:fe0f:2755] - port = [5540] - txt = ["PI=" "PH=33" "CM=1" "D=3841" "T=1" "CRA=300" "CRI=5000" "VP=65521+32769"] - = wlp5s0 IPv6 C326228BDB082BF4 _matterc._udp local - hostname = [E45F010F27530000.local] - address = [fe80::e65f:1ff:fe0f:2755] - port = [5540] - txt = ["PI=" "PH=36" "CM=2" "D=3840" "T=1" "CRA=300" "CRI=5000" "VP=65521+32769"] - grl@grl-ThinkPad-L480:~/2nd_cntrl/connectedhomeip/examples/chip-tool/out/debug$ On TH_CR1 send the below command - disabled: true - - - label: "Step 4: TH_CR3 Commissions with DUT_CE" - PICS: CADMIN.S - verification: | - On TH_CR3 send the below command - - ./chip-tool pairing code 3 35484132896 --commissioner-name gamma - - Verify you got below message TH_CR3(chip-tool) log - Device commissioning completed with success - disabled: true - - - label: - "Step 5: TH_CR1 opens a commissioning window on DUT_CE using a - commissioning timeout of PIXIT.CADMIN.CwDuration seconds using ECM and - TH_CR2 Commissions with DUT_CE" - PICS: CADMIN.S.C00.Rsp - verification: | - On TH_CR1 send the below command - - ./chip-tool pairing open-commissioning-window 1 1 180 1000 3840 - - Verify Manual pairing code on TH1(chip-tool) Log - - 0x0000000000000001 at monotonic time: 16129075 msec - [1635874557.417449][4549:4554] CHIP:DMG: ICR moving to [CommandSen] - [1635874557.417505][4549:4554] CHIP:CTL: Manual pairing code: [35484132896] - [1635874557.417577][4549:4554] CHIP:CTL: SetupQRCode: [MT:00000CQM00AT-F5A510] - - On TH_CR2 send the below command - - ./chip-tool pairing code 2 35484132896 --commissioner-name beta - - Verify you got below message on TH_CR2(chip-tool) log - Device commissioning completed with success - disabled: true - - - label: - "Step 6: TH_CR1 opens a commissioning window on DUT_CE using a - commissioning timeout of PIXIT.CADMIN.CwDuration seconds using ECM" - PICS: CADMIN.S.C00.Rsp - verification: | - On TH_CR1 send the below command - - ./chip-tool pairing open-commissioning-window 1 1 180 1000 3840 - - Verify the Open commisioning window on the DUT_CE(all-cluster-app) Log: - - [1660904553.796857][3537:3537] CHIP:DMG: Received command for Endpoint=0 Cluster=0x0000_003C Command=0x0000_0000 - [1660904553.796951][3537:3537] CHIP:ZCL: Received command to open commissioning window - [1660904553.797255][3537:3537] CHIP:IN: SecureSession[0xaaab142ef7f0]: Allocated Type:1 LSID:34523 - - Verify the Manual pairing code on the TH_CR1(chip-tool) Log: - - [1635874557.417271][4549:4554] CHIP:IN: Sending encrypted msg 0xaaaac5947d10 with MessageCounter:0 to 0x0000000000000001 at monotonic time: 16129075 msec - [1635874557.417449][4549:4554] CHIP:DMG: ICR moving to [CommandSen] - [1635874557.417505][4549:4554] CHIP:CTL: Manual pairing code: [35484132896] - [1635874557.417577][4549:4554] CHIP:CTL: SetupQRCode: [MT:00000CQM00AT-F5A510] - disabled: true - - - label: - "Step 7: Before the expiration of PIXIT.CADMIN.CwDuration seconds - which was set in step 5, TH_CR1 opens a 2nd commissioning window on - DUT_CE using a commissioning timeout of PIXIT.CADMIN.CwDuration - seconds using ECM" - PICS: CADMIN.S.C00.Rsp - verification: | - On TH_CR1 send the below command - - Verify that the DUT_CE is rejecting the opening of second commissioning session with the response status 0x01 failure - - - ./chip-tool pairing open-commissioning-window 1 1 180 1000 3840 - - Verify cluster status 1 on TH_CR1(chip-tool) Log - - - [1650527291.952431][8566:8571] CHIP:DMG: - [1650527291.952458][8566:8571] CHIP:DMG: StatusIB = - [1650527291.952488][8566:8571] CHIP:DMG: { - [1650527291.952519][8566:8571] CHIP:DMG: status = 0x01 (FAILURE), - [1650527291.952555][8566:8571] CHIP:DMG: cluster-status = 0x2, - [1650527291.952578][8566:8571] CHIP:DMG: }, - [1650527291.952612][8566:8571] CHIP:DMG: - [1650527291.952634][8566:8571] CHIP:DMG: }, - disabled: true - - - label: "Step 8: TH_CR1 reads the list of Fabrics on DUT_CE" - PICS: OPCREDS.S.A0001 - verification: | - On TH_CR1 send the below command - - ./chip-tool operationalcredentials read fabrics 1 0 --fabric-filtered 0 - - Verify the list of Fabrics consists of FabricIndex 1, FabricIndex 2, FabricIndex 3 on TH_CR1(chip-tool) log - - CHIP:TOO: Endpoint: 0 Cluster: 0x0000_003E Attribute 0x0000_0001 DataVersion: 268962768 - [1650527361.425870][15792:15797] CHIP:TOO: Fabrics: 3 entries - [1650527361.426777][15792:15797] CHIP:TOO: [1]: { - [1650527361.426859][15792:15797] CHIP:TOO: RootPublicKey: 0429A71383F336D80918C9EC655112513E428C073AF7FB44820EC793535302C6E3825C56EE6DD1A683EAA7B59E3F261B46FFA24A6D911E8D88839F4C1B3C84BA01 - [1650527361.426923][15792:15797] CHIP:TOO: VendorId: 65521 - [1650527361.426979][15792:15797] CHIP:TOO: FabricId: 1 - [1650527361.427033][15792:15797] CHIP:TOO: NodeId: 1 - [1650527361.427088][15792:15797] CHIP:TOO: Label: - [1650527361.427166][15792:15797] CHIP:TOO: FabricIndex: 1 - [1650527361.427376][15792:15797] CHIP:TOO: } - [1650527361.427464][15792:15797] CHIP:TOO: [2]: { - [1650527361.427532][15792:15797] CHIP:TOO: RootPublicKey: 04781BCEE70118049ED61DD5B4E401CF1A09D2F78AE7F5770BE5506AD24238E5E0777277DABAFD062659651C95CC2CA7DEAACE40DB579A946CC07CADB141BE05D7 - [1650527361.427595][15792:15797] CHIP:TOO: VendorId: 65521 - [1650527361.427649][15792:15797] CHIP:TOO: FabricId: 1 - [1650527361.427703][15792:15797] CHIP:TOO: NodeId: 3 - [1650527361.427756][15792:15797] CHIP:TOO: Label: - [1650527361.427811][15792:15797] CHIP:TOO: FabricIndex: 2 - [1650527361.427868][15792:15797] CHIP:TOO: } - [1650527361.427943][15792:15797] CHIP:TOO: [3]: { - [1650527361.428008][15792:15797] CHIP:TOO: RootPublicKey: 0403EDB5B461030A34EF7EA2F9DB0D46A36185E4755C365AF9344C4959F049EF21D55EAB903A2C7FBFC305EEFA42989250D7517A73E6156062390A60C0D4C41EBD - [1650527361.428067][15792:15797] CHIP:TOO: VendorId: 65521 - [1650527361.428122][15792:15797] CHIP:TOO: FabricId: 1 - [1650527361.428176][15792:15797] CHIP:TOO: NodeId: 2 - [1650527361.428229][15792:15797] CHIP:TOO: Label: - [1650527361.428282][15792:15797] CHIP:TOO: FabricIndex: 3 - [1650527361.428335][15792:15797] CHIP:TOO: } - disabled: true - - - label: - "Step 9: Wait for the expiration of PIXIT.CADMIN.CwDuration seconds - that was set in step 6" - verification: | - Wait for the expiration of PIXIT.CADMIN.CwDuration seconds that was set in step 6 - disabled: true - - - label: - "Step 10: TH_CR1 re-opens a commissioning window on DUT_CE using a - commissioning timeout of PIXIT.CADMIN.CwDuration seconds using BCM" - PICS: CADMIN.S.C01.Rsp - verification: | - On TH_CR1 send the below command - - ./chip-tool administratorcommissioning open-basic-commissioning-window 500 1 0 --timedInteractionTimeoutMs 1000 - - Verify the Open commisioning window on the DUT_CE(all-cluster-app) Log: - - [1660904553.796857][3537:3537] CHIP:DMG: Received command for Endpoint=0 Cluster=0x0000_003C Command=0x0000_0000 - [1660904553.796951][3537:3537] CHIP:ZCL: Received command to open commissioning window - [1660904553.797255][3537:3537] CHIP:IN: SecureSession[0xaaab142ef7f0]: Allocated Type:1 LSID:34523 - - Verify the Manual pairing code on the TH_CR1(chip-tool) Log: - - [1650278416.249347][11064:11069] CHIP:DMG: }, - [1650278416.249430][11064:11069] CHIP:DMG: - [1650278416.249501][11064:11069] CHIP:DMG: StatusIB = - [1650278416.249581][11064:11069] CHIP:DMG: { - [1650278416.249664][11064:11069] CHIP:DMG: status = 0x00 (SUCCESS), - [1650278416.249738][11064:11069] CHIP:DMG: }, - [1650278416.249823][11064:11069] CHIP:DMG: - disabled: true - - - label: "Step 11: DNS-SD records shows DUT_CE advertising" - verification: | - On TH_CR1 send the below command - avahi-browse -rt _matterc._udp - + eth0 IPv6 2664ED6939FC373C _matterc._udp local - = eth0 IPv6 2664ED6939FC373C _matterc._udp local - hostname = [E45F010F27530000.local] - address = [fe80::e65f:1ff:fe0f:2753] - port = [5540] - txt = ["PI=" "PH=36" "CM=1" "D=3840" "T=1" "SAI=300" "SII=5000" "VP=65521+32769"] - ubuntu@ubuntu:~/may16_cntrl/connectedhomeip/examples/chip-tool/out/debug$ - disabled: true - - - label: - "Step 12: Before the expiration of PIXIT.CADMIN.CwDuration seconds - that was set in step 10, TH_CR3 opens a 2nd commissioning window on - DUT_CE using a commissioning timeout of PIXIT.CADMIN.CwDuration - seconds using BCM" - PICS: CADMIN.S.C01.Rsp - verification: | - On TH_CR3 send the below command - - ./chip-tool administratorcommissioning open-basic-commissioning-window 500 3 0 --timedInteractionTimeoutMs 1000 --commissioner-name gamma - - Verify that the DUT_CE is rejecting the opening of second commissioning session with the response status 0x01 failure - - - - [1650527565.991042][24618:24623] CHIP:DMG: { - [1650527565.991112][24618:24623] CHIP:DMG: EndpointId = 0x0, - [1650527565.991186][24618:24623] CHIP:DMG: ClusterId = 0x3c, - [1650527565.991257][24618:24623] CHIP:DMG: CommandId = 0x1, - [1650527565.991332][24618:24623] CHIP:DMG: }, - [1650527565.991441][24618:24623] CHIP:DMG: - [1650527565.991505][24618:24623] CHIP:DMG: StatusIB = - [1650527565.991574][24618:24623] CHIP:DMG: { - [1650527565.991645][24618:24623] CHIP:DMG: status = 0x01 (FAILURE), - [1650527565.991743][24618:24623] CHIP:DMG: cluster-status = 0x2, - [1650527565.991830][24618:24623] CHIP:DMG: }, - [1650527565.991918][24618:24623] CHIP:DMG: - [1650527565.991976][24618:24623] CHIP:DMG: }, - [1650527565.992061][24618:24623] CHIP:DMG: - [1650527565.992116][24618:24623] CHIP:DMG: }, - disabled: true - - - label: - "Step 13: Wait for the expiration of PIXIT.CADMIN.CwDuration seconds - that was set in step 11" - verification: | - Wait for the expiration of PIXIT.CADMIN.CwDuration seconds that was set in step 10 - disabled: true - - - label: "Step 14: TH_CR1 reads the list of Fabrics on DUT_CE" - PICS: OPCREDS.S.A0001 - verification: | - On TH_CR1 send the below command - - ./chip-tool operationalcredentials read fabrics 1 0 --fabric-filtered 0 - - Verify the list of Fabrics consists of FabricIndex 1, FabricIndex 2, FabricIndex 3 on TH_CR1(chip-tool) log - - CHIP:TOO: Endpoint: 0 Cluster: 0x0000_003E Attribute 0x0000_0001 DataVersion: 268962768 - [1678866402.096093][704851:704853] CHIP:TOO: Fabrics: 3 entries - [1678866402.096119][704851:704853] CHIP:TOO: [1]: { - [1678866402.096131][704851:704853] CHIP:TOO: RootPublicKey: 045F808373B5CED7FC2AFF99D98C2DEE6CA3889A9B078E87DAD9E263C9DEDB47AD7D31703024B72F4CB68A3017963128748FC7E97C6CBB419AF8AA914CE67D7457 - [1678866402.096141][704851:704853] CHIP:TOO: VendorID: 65521 - [1678866402.096147][704851:704853] CHIP:TOO: FabricID: 1 - [1678866402.096154][704851:704853] CHIP:TOO: NodeID: 1 - [1678866402.096160][704851:704853] CHIP:TOO: Label: - [1678866402.096167][704851:704853] CHIP:TOO: FabricIndex: 1 - [1678866402.096173][704851:704853] CHIP:TOO: } - [1678866402.096185][704851:704853] CHIP:TOO: [2]: { - [1678866402.096194][704851:704853] CHIP:TOO: RootPublicKey: 0458F2B4AD99F579EC01AA271EFDDF14526CE5222BADE218C703902544430F32FA9B951963C6C03713AC63E2D95785CFCD997946098957C4F5844BD2B3916B7148 - [1678866402.096201][704851:704853] CHIP:TOO: VendorID: 65521 - [1678866402.096207][704851:704853] CHIP:TOO: FabricID: 3 - [1678866402.096213][704851:704853] CHIP:TOO: NodeID: 3 - [1678866402.096219][704851:704853] CHIP:TOO: Label: - [1678866402.096224][704851:704853] CHIP:TOO: FabricIndex: 2 - [1678866402.096230][704851:704853] CHIP:TOO: } - [1678866402.096241][704851:704853] CHIP:TOO: [3]: { - [1678866402.096250][704851:704853] CHIP:TOO: RootPublicKey: 04CE10BA136D610089C4810BF963C354CE93BA61D267E8B9594977E3CC5FF30741941CE3D2A0A9E62A66AEF02CAA9F25A614F033D304D9F2ACF4204FAB68E8F773 - [1678866402.096257][704851:704853] CHIP:TOO: VendorID: 65521 - [1678866402.096263][704851:704853] CHIP:TOO: FabricID: 2 - [1678866402.096269][704851:704853] CHIP:TOO: NodeID: 2 - [1678866402.096274][704851:704853] CHIP:TOO: Label: - [1678866402.096280][704851:704853] CHIP:TOO: FabricIndex: 3 - [1678866402.096286][704851:704853] CHIP:TOO: } - disabled: true - - - label: - "Step 15: TH_CR1 opens a commissioning window on DUT_CE using a - commissioning timeout of PIXIT.CADMIN.CwDuration seconds using BCM" - PICS: CADMIN.S.C01.Rsp - verification: | - On TH_CR1 send the below command - - ./chip-tool administratorcommissioning open-basic-commissioning-window 500 1 0 --timedInteractionTimeoutMs 1000 - - Verify success response On TH_CR1(chip-tool) Log - - [1650278416.249268][11064:11069] CHIP:DMG: CommandId = 0x1, - [1650278416.249347][11064:11069] CHIP:DMG: }, - [1650278416.249430][11064:11069] CHIP:DMG: - [1650278416.249501][11064:11069] CHIP:DMG: StatusIB = - [1650278416.249581][11064:11069] CHIP:DMG: { - [1650278416.249664][11064:11069] CHIP:DMG: status = 0x00 (SUCCESS), - [1650278416.249738][11064:11069] CHIP:DMG: }, - [1650278416.249823][11064:11069] CHIP:DMG: - disabled: true - - - label: - "Step 16: Before the expiration of PIXIT.CADMIN.CwDuration seconds - that was set in step 14, TH_CR2 opens a second commissioning window on - DUT_CE using a commissioning timeout of PIXIT.CADMIN.CwDuration - seconds using BCM" - PICS: CADMIN.S.C01.Rsp - verification: | - On TH_CR2 send the below command - - ./chip-tool administratorcommissioning open-basic-commissioning-window 500 2 0 --timedInteractionTimeoutMs 1000 --commissioner-name beta - - - Verify that the DUT_CE is rejecting the opening of second commissioning session with the response status 0x01 failure - - - - [1650527622.374682][15824:15829] CHIP:DMG: }, - [1650527622.374799][15824:15829] CHIP:DMG: - [1650527622.374896][15824:15829] CHIP:DMG: StatusIB = - [1650527622.374979][15824:15829] CHIP:DMG: { - [1650527622.375086][15824:15829] CHIP:DMG: status = 0x01 (FAILURE), - [1650527622.375236][15824:15829] CHIP:DMG: cluster-status = 0x2, - [1650527622.375320][15824:15829] CHIP:DMG: }, - [1650527622.375426][15824:15829] CHIP:DMG: - [1650527622.375527][15824:15829] CHIP:DMG: }, - [1650527622.375616][15824:15829] CHIP:DMG: - disabled: true diff --git a/src/app/tests/suites/manualTests.json b/src/app/tests/suites/manualTests.json index 3b0b354840e1c6..01d98213b3e279 100644 --- a/src/app/tests/suites/manualTests.json +++ b/src/app/tests/suites/manualTests.json @@ -171,7 +171,6 @@ "Test_TC_CADMIN_1_2", "Test_TC_CADMIN_1_7", "Test_TC_CADMIN_1_8", - "Test_TC_CADMIN_1_11", "Test_TC_CADMIN_1_12", "Test_TC_CADMIN_1_14", "Test_TC_CADMIN_1_15", diff --git a/src/python_testing/TC_CADMIN_1_11.py b/src/python_testing/TC_CADMIN_1_11.py new file mode 100644 index 00000000000000..cefd8b44a785f4 --- /dev/null +++ b/src/python_testing/TC_CADMIN_1_11.py @@ -0,0 +1,222 @@ +# +# Copyright (c) 2024 Project CHIP Authors +# All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# === BEGIN CI TEST ARGUMENTS === +# test-runner-runs: +# run1: +# app: ${ALL_CLUSTERS_APP} +# app-args: --discriminator 1234 --KVS kvs1 --trace-to json:${TRACE_APP}.json +# script-args: > +# --storage-path admin_storage.json +# --commissioning-method on-network +# --discriminator 1234 +# --passcode 20202021 +# --trace-to json:${TRACE_TEST_JSON}.json +# --trace-to perfetto:${TRACE_TEST_PERFETTO}.perfetto +# --PICS src/app/tests/suites/certification/ci-pics-values +# factory-reset: true +# quiet: false +# === END CI TEST ARGUMENTS === + + +import logging +import random +from time import sleep +from typing import Optional + +import chip.clusters as Clusters +from chip import ChipDeviceCtrl +from chip.ChipDeviceCtrl import CommissioningParameters +from chip.exceptions import ChipStackError +from chip.native import PyChipError +from matter_testing_infrastructure.chip.testing.matter_testing import (MatterBaseTest, TestStep, async_test_body, + default_matter_test_main) +from mobly import asserts + + +class TC_CADMIN_1_11(MatterBaseTest): + async def OpenCommissioningWindow(self, th, expectedErrCode) -> CommissioningParameters: + if expectedErrCode is None: + params = await th.OpenCommissioningWindow( + nodeid=self.dut_node_id, timeout=self.timeout, iteration=10000, discriminator=self.discriminator, option=1) + return params + + else: + ctx = asserts.assert_raises(ChipStackError) + with ctx: + await th.OpenCommissioningWindow( + nodeid=self.dut_node_id, timeout=self.timeout, iteration=10000, discriminator=self.discriminator, option=1) + errcode = PyChipError.from_code(ctx.exception.err) + logging.info('Commissioning complete done. Successful? {}, errorcode = {}'.format(errcode.is_success, errcode)) + asserts.assert_false(errcode.is_success, 'Commissioning complete did not error as expected') + asserts.assert_true(errcode.sdk_code == expectedErrCode, + 'Unexpected error code returned from CommissioningComplete') + + async def OpenBasicCommissioningWindow(self, th: ChipDeviceCtrl, expectedErrCode: Optional[Clusters.AdministratorCommissioning.Enums.StatusCode] = None) -> CommissioningParameters: + if not expectedErrCode: + params = await th.OpenBasicCommissioningWindow( + nodeid=self.dut_node_id, timeout=self.timeout) + return params + + else: + ctx = asserts.assert_raises(ChipStackError) + with ctx: + await th.OpenBasicCommissioningWindow( + nodeid=self.dut_node_id, timeout=self.timeout) + errcode = ctx.exception.chip_error + logging.info('Commissioning complete done. Successful? {}, errorcode = {}'.format(errcode.is_success, errcode)) + asserts.assert_false(errcode.is_success, 'Commissioning complete did not error as expected') + asserts.assert_true(errcode.sdk_code == expectedErrCode, + 'Unexpected error code returned from CommissioningComplete') + + async def read_currentfabricindex(self, th: ChipDeviceCtrl) -> int: + cluster = Clusters.OperationalCredentials + attribute = Clusters.OperationalCredentials.Attributes.CurrentFabricIndex + current_fabric_index = await self.read_single_attribute_check_success(dev_ctrl=th, endpoint=0, cluster=cluster, attribute=attribute) + return current_fabric_index + + def steps_TC_CADMIN_1_11(self) -> list[TestStep]: + return [ + TestStep(1, "Commissioning, already done", is_commissioning=True), + TestStep( + 2, "TH_CR1 gets the MaxCumulativeFailsafeSeconds value from BasicCommissioningInfo attribute in GeneralCommissioning Cluster", "Should set the MaxCumulativeFailsafeSeconds value from BasicCommissioningInfo attribute to timeout"), + TestStep( + 3, "TH_CR1 opens commissioning window on DUT with duration set to value for MaxCumulativeFailsafeSeconds", "Commissioning window should open with timeout set to MaxCumulativeFailsafeSeconds"), + TestStep(4, "TH_CR2 fully commissions the DUT", "DUT should fully commission"), + TestStep( + 5, "TH_CR1 opens commissioning window on DUT with duration set to value from BasicCommissioningInfo", "New commissioning window should open and be set to timeout"), + TestStep(6, "TH_CR1 sends an OpenCommissioningWindow command to the DUT and attempts to open another commissioning window", + "Commissioning window should fail to be opened due to being busy"), + TestStep(7, "TH_CR2 sends an OpenCommissioningWindow command to the DUT and attempts to open another commissioning window", + "Commissioning window should fail to be opened due to being busy"), + TestStep(8, "TH_CR1 sends an RevokeCommissioning command to the DUT", "Commissioning window should be closed"), + TestStep(9, "TH_CR1 reads the FeatureMap from the Administrator Commissioning Cluster to check to see if BC is supported on DUT", + "FeatureMap should be checked to see if BC enum is available feature, if not then test steps 9a-9d will be skipped"), + TestStep("9a", "TH_CR1 opens commissioning window on DUT with duration set to value from BasicCommissioningInfo", + "Opens basic commissioning window on the DUT for timeout set to value of MaxCumulativeFailsafeSeconds"), + TestStep("9b", "TH_CR1 sends an OpenBasicCommissioningWindow command to the DUT and attempts to open another commissioning window", + "Commissioning window should fail to be opened due to being busy"), + TestStep("9c", "TH_CR2 sends an OpenBasicCommissioningWindow command to the DUT and attempts to open another commissioning window", + "Commissioning window should fail to be opened due to being busy"), + TestStep("9d", "TH_CR1 sends a RevokeCommissioning command to the DUT", "Commissioning window should be closed"), + TestStep(10, "TH_CR2 reads the CurrentFabricIndex attribute from the Operational Credentials cluster and saves as th2_idx", + "th2_idx set to value for CurrentFabricIndex attribute from TH_CR2"), + TestStep(11, "TH_CR1 sends the RemoveFabric command to the DUT with the FabricIndex set to th2_idx", + "TH_CR1 removes TH_CR2 fabric using th2_idx"), + ] + + async def CommissionAttempt( + self, setupPinCode: int): + + logging.info("-----------------Commissioning with TH_CR2-------------------------") + await self.th2.CommissionOnNetwork( + nodeId=self.dut_node_id, setupPinCode=setupPinCode, + filterType=ChipDeviceCtrl.DiscoveryFilterType.LONG_DISCRIMINATOR, filter=self.discriminator) + + def pics_TC_CADMIN_1_11(self) -> list[str]: + return ["CADMIN.S"] + + @async_test_body + async def test_TC_CADMIN_1_11(self): + self.step(1) + + # Establishing TH1 and TH2 controllers + self.th1 = self.default_controller + self.discriminator = random.randint(0, 4095) + th2_certificate_authority = self.certificate_authority_manager.NewCertificateAuthority() + th2_fabric_admin = th2_certificate_authority.NewFabricAdmin(vendorId=0xFFF1, fabricId=self.th1.fabricId + 1) + self.th2 = th2_fabric_admin.NewController(nodeId=2) + + self.step(2) + GC_cluster = Clusters.GeneralCommissioning + attribute = GC_cluster.Attributes.BasicCommissioningInfo + duration = await self.read_single_attribute_check_success(endpoint=0, cluster=GC_cluster, attribute=attribute) + self.timeout = duration.maxCumulativeFailsafeSeconds + + self.step(3) + params = await self.OpenCommissioningWindow(self.th1, None) + setupPinCode = params.setupPinCode + busy_enum = Clusters.AdministratorCommissioning.Enums.StatusCode.kBusy + + self.step(4) + await self.CommissionAttempt(setupPinCode) + + self.step(5) + await self.OpenCommissioningWindow(self.th1, None) + + self.step(6) + await self.OpenCommissioningWindow(self.th1, busy_enum) + + self.step(7) + await self.OpenCommissioningWindow(self.th2, busy_enum) + + self.step(8) + revokeCmd = Clusters.AdministratorCommissioning.Commands.RevokeCommissioning() + await self.th1.SendCommand(nodeid=self.dut_node_id, endpoint=0, payload=revokeCmd, timedRequestTimeoutMs=6000) + # The failsafe cleanup is scheduled after the command completes, so give it a bit of time to do that + sleep(1) + + self.step(9) + + AC_cluster = Clusters.AdministratorCommissioning + fm_attribute = Clusters.AdministratorCommissioning.Attributes + features = await self.read_single_attribute_check_success(cluster=AC_cluster, attribute=fm_attribute.FeatureMap) + + self.supports_bc = bool(features & AC_cluster.Bitmaps.Feature.kBasic) != 0 + + if self.supports_bc: + self.count = 0 + self.step("9a") + obcCmd = Clusters.AdministratorCommissioning.Commands.OpenBasicCommissioningWindow(180) + await self.th1.SendCommand(nodeid=self.dut_node_id, endpoint=0, payload=obcCmd, timedRequestTimeoutMs=6000) + + self.step("9b") + try: + await self.th1.SendCommand(nodeid=self.dut_node_id, endpoint=0, payload=obcCmd, timedRequestTimeoutMs=6000) + except Exception as e: + asserts.assert_true(e.clusterStatus == busy_enum, + 'Unexpected error code returned from CommissioningComplete') + + self.step("9c") + try: + await self.th2.SendCommand(nodeid=self.dut_node_id, endpoint=0, payload=obcCmd, timedRequestTimeoutMs=6000) + except Exception as e: + asserts.assert_true(e.clusterStatus == busy_enum, + 'Unexpected error code returned from CommissioningComplete') + + self.step("9d") + revokeCmd = Clusters.AdministratorCommissioning.Commands.RevokeCommissioning() + await self.th1.SendCommand(nodeid=self.dut_node_id, endpoint=0, payload=revokeCmd, timedRequestTimeoutMs=6000) + # The failsafe cleanup is scheduled after the command completes, so give it a bit of time to do that + sleep(1) + + else: + self.skip_step("9a") + self.skip_step("9b") + self.skip_step("9c") + self.skip_step("9d") + + # Read CurrentFabricIndex attribute from the Operational Credentials cluster + self.step(10) + th2_idx = await self.read_currentfabricindex(self.th2) + + self.step(11) + removeFabricCmd = Clusters.OperationalCredentials.Commands.RemoveFabric(th2_idx) + await self.th1.SendCommand(nodeid=self.dut_node_id, endpoint=0, payload=removeFabricCmd) + + +if __name__ == "__main__": + default_matter_test_main() From c0c674c56fe13af0552ff8aed28deac3699e4535 Mon Sep 17 00:00:00 2001 From: Yufeng Wang Date: Thu, 17 Oct 2024 12:34:16 -0700 Subject: [PATCH 026/149] [Fabric-Admin] Implement FabricSyncGetter APIs (#36108) * [Fabric-Admin] Implement FabricSyncGetter APIs * Update examples/fabric-admin/device_manager/FabricSyncGetter.h Co-authored-by: Terence Hampson --------- Co-authored-by: Terence Hampson --- examples/fabric-admin/BUILD.gn | 2 + .../commands/clusters/ReportCommand.cpp | 2 - .../device_manager/DeviceManager.cpp | 22 ++-- .../device_manager/DeviceManager.h | 2 + .../device_manager/FabricSyncGetter.cpp | 121 ++++++++++++++++++ .../device_manager/FabricSyncGetter.h | 75 +++++++++++ 6 files changed, 210 insertions(+), 14 deletions(-) create mode 100644 examples/fabric-admin/device_manager/FabricSyncGetter.cpp create mode 100644 examples/fabric-admin/device_manager/FabricSyncGetter.h diff --git a/examples/fabric-admin/BUILD.gn b/examples/fabric-admin/BUILD.gn index 38252cd30e7648..58d9cee914e410 100644 --- a/examples/fabric-admin/BUILD.gn +++ b/examples/fabric-admin/BUILD.gn @@ -90,6 +90,8 @@ static_library("fabric-admin-utils") { "device_manager/DeviceSubscriptionManager.h", "device_manager/DeviceSynchronization.cpp", "device_manager/DeviceSynchronization.h", + "device_manager/FabricSyncGetter.cpp", + "device_manager/FabricSyncGetter.h", "device_manager/PairingManager.cpp", "device_manager/PairingManager.h", "device_manager/UniqueIdGetter.cpp", diff --git a/examples/fabric-admin/commands/clusters/ReportCommand.cpp b/examples/fabric-admin/commands/clusters/ReportCommand.cpp index df6f329896036c..7f3decd78a83f0 100644 --- a/examples/fabric-admin/commands/clusters/ReportCommand.cpp +++ b/examples/fabric-admin/commands/clusters/ReportCommand.cpp @@ -45,8 +45,6 @@ void ReportCommand::OnAttributeData(const app::ConcreteDataAttributePath & path, } LogErrorOnFailure(RemoteDataModelLogger::LogAttributeAsJSON(path, data)); - - DeviceMgr().HandleAttributeData(path, *data); } void ReportCommand::OnEventData(const app::EventHeader & eventHeader, TLV::TLVReader * data, const app::StatusIB * status) diff --git a/examples/fabric-admin/device_manager/DeviceManager.cpp b/examples/fabric-admin/device_manager/DeviceManager.cpp index 2968bcf001e9bc..3bfd677d962435 100644 --- a/examples/fabric-admin/device_manager/DeviceManager.cpp +++ b/examples/fabric-admin/device_manager/DeviceManager.cpp @@ -212,13 +212,18 @@ void DeviceManager::ReadSupportedDeviceCategories() return; } - StringBuilder commandBuilder; + ChipLogProgress(NotSpecified, "Read SupportedDeviceCategories from the remote bridge."); - commandBuilder.Add("commissionercontrol read supported-device-categories "); - commandBuilder.AddFormat("%ld ", mRemoteBridgeNodeId); - commandBuilder.AddFormat("%d", kAggregatorEndpointId); + CHIP_ERROR error = mFabricSyncGetter.GetFabricSynchronizationData( + [this](TLV::TLVReader & data) { this->HandleReadSupportedDeviceCategories(data); }, + PairingManager::Instance().CurrentCommissioner(), this->GetRemoteBridgeNodeId(), kAggregatorEndpointId); - PushCommand(commandBuilder.c_str()); + if (error != CHIP_NO_ERROR) + { + ChipLogError(NotSpecified, + "Failed to read SupportedDeviceCategories from the remote bridge (NodeId: %lu). Error: %" CHIP_ERROR_FORMAT, + mRemoteBridgeNodeId, error.Format()); + } } void DeviceManager::HandleReadSupportedDeviceCategories(TLV::TLVReader & data) @@ -421,13 +426,6 @@ void DeviceManager::HandleReverseOpenCommissioningWindow(TLV::TLVReader & data) void DeviceManager::HandleAttributeData(const app::ConcreteDataAttributePath & path, TLV::TLVReader & data) { - if (path.mClusterId == CommissionerControl::Id && - path.mAttributeId == CommissionerControl::Attributes::SupportedDeviceCategories::Id) - { - HandleReadSupportedDeviceCategories(data); - return; - } - if (path.mClusterId == Descriptor::Id && path.mAttributeId == Descriptor::Attributes::PartsList::Id) { HandleAttributePartsListUpdate(data); diff --git a/examples/fabric-admin/device_manager/DeviceManager.h b/examples/fabric-admin/device_manager/DeviceManager.h index 62d5ae045bb6af..43461f41c17229 100644 --- a/examples/fabric-admin/device_manager/DeviceManager.h +++ b/examples/fabric-admin/device_manager/DeviceManager.h @@ -20,6 +20,7 @@ #include #include +#include #include #include @@ -212,6 +213,7 @@ class DeviceManager : public PairingDelegate uint64_t mRequestId = 0; BridgeSubscription mBridgeSubscriber; + FabricSyncGetter mFabricSyncGetter; }; /** diff --git a/examples/fabric-admin/device_manager/FabricSyncGetter.cpp b/examples/fabric-admin/device_manager/FabricSyncGetter.cpp new file mode 100644 index 00000000000000..5201048c3faea6 --- /dev/null +++ b/examples/fabric-admin/device_manager/FabricSyncGetter.cpp @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "FabricSyncGetter.h" + +using namespace ::chip; +using namespace ::chip::app; +using chip::app::ReadClient; + +namespace { + +void OnDeviceConnectedWrapper(void * context, Messaging::ExchangeManager & exchangeMgr, const SessionHandle & sessionHandle) +{ + reinterpret_cast(context)->OnDeviceConnected(exchangeMgr, sessionHandle); +} + +void OnDeviceConnectionFailureWrapper(void * context, const ScopedNodeId & peerId, CHIP_ERROR error) +{ + reinterpret_cast(context)->OnDeviceConnectionFailure(peerId, error); +} + +} // namespace + +FabricSyncGetter::FabricSyncGetter() : + mOnDeviceConnectedCallback(OnDeviceConnectedWrapper, this), + mOnDeviceConnectionFailureCallback(OnDeviceConnectionFailureWrapper, this) +{} + +CHIP_ERROR FabricSyncGetter::GetFabricSynchronizationData(OnDoneCallback onDoneCallback, Controller::DeviceController & controller, + NodeId nodeId, EndpointId endpointId) +{ + assertChipStackLockedByCurrentThread(); + + mEndpointId = endpointId; + mOnDoneCallback = onDoneCallback; + + CHIP_ERROR err = controller.GetConnectedDevice(nodeId, &mOnDeviceConnectedCallback, &mOnDeviceConnectionFailureCallback); + if (err != CHIP_NO_ERROR) + { + ChipLogError(NotSpecified, "Failed to connect to remote fabric bridge %" CHIP_ERROR_FORMAT, err.Format()); + } + return err; +} + +void FabricSyncGetter::OnAttributeData(const ConcreteDataAttributePath & path, TLV::TLVReader * data, const StatusIB & status) +{ + VerifyOrDie(path.mClusterId == Clusters::CommissionerControl::Id); + + if (!status.IsSuccess()) + { + ChipLogError(NotSpecified, "Response Failure: %" CHIP_ERROR_FORMAT, status.ToChipError().Format()); + return; + } + + switch (path.mAttributeId) + { + case Clusters::CommissionerControl::Attributes::SupportedDeviceCategories::Id: { + mOnDoneCallback(*data); + break; + } + default: + break; + } +} + +void FabricSyncGetter::OnError(CHIP_ERROR error) +{ + ChipLogProgress(NotSpecified, "Error Getting SupportedDeviceCategories: %" CHIP_ERROR_FORMAT, error.Format()); +} + +void FabricSyncGetter::OnDone(ReadClient * apReadClient) +{ + ChipLogProgress(NotSpecified, "Reading SupportedDeviceCategories is done."); +} + +void FabricSyncGetter::OnDeviceConnected(Messaging::ExchangeManager & exchangeMgr, const SessionHandle & sessionHandle) +{ + mClient = std::make_unique(app::InteractionModelEngine::GetInstance(), &exchangeMgr, *this /* callback */, + ReadClient::InteractionType::Read); + VerifyOrDie(mClient); + + AttributePathParams readPaths[1]; + readPaths[0] = AttributePathParams(mEndpointId, Clusters::CommissionerControl::Id, + Clusters::CommissionerControl::Attributes::SupportedDeviceCategories::Id); + + ReadPrepareParams readParams(sessionHandle); + + readParams.mpAttributePathParamsList = readPaths; + readParams.mAttributePathParamsListSize = 1; + + CHIP_ERROR err = mClient->SendRequest(readParams); + + if (err != CHIP_NO_ERROR) + { + ChipLogError(NotSpecified, "Failed to read SupportedDeviceCategories from the bridged device."); + OnDone(nullptr); + return; + } +} + +void FabricSyncGetter::OnDeviceConnectionFailure(const ScopedNodeId & peerId, CHIP_ERROR error) +{ + ChipLogError(NotSpecified, "FabricSyncGetter failed to connect to " ChipLogFormatX64, ChipLogValueX64(peerId.GetNodeId())); + + OnDone(nullptr); +} diff --git a/examples/fabric-admin/device_manager/FabricSyncGetter.h b/examples/fabric-admin/device_manager/FabricSyncGetter.h new file mode 100644 index 00000000000000..d6d3a5bce8c9f5 --- /dev/null +++ b/examples/fabric-admin/device_manager/FabricSyncGetter.h @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#pragma once + +#include +#include + +#include +#include + +/** + * @brief Class used to get FabricSynchronization from SupportedDeviceCategories attribute of Commissioner Control Cluster. + * + * Functionality: + * - Establishes a CASE session to communicate with the remote bridge. + * - Retrieves the attribute data from the endpoint which host Aggregator. + * - Provides callbacks for success, error, and completion when retrieving data. + */ +class FabricSyncGetter : public chip::app::ReadClient::Callback +{ +public: + using OnDoneCallback = std::function; + + FabricSyncGetter(); + + /** + * @brief Initiates the process of retrieving fabric synchronization data from the target device. + * + * @param onDoneCallback A callback function to be invoked when the data retrieval is complete. + * @param controller The device controller used to establish a session with the target device. + * @param nodeId The Node ID of the target device. + * @param endpointId The Endpoint ID from which to retrieve the fabric synchronization data. + * @return CHIP_ERROR Returns an error if the process fails, CHIP_NO_ERROR on success. + */ + CHIP_ERROR GetFabricSynchronizationData(OnDoneCallback onDoneCallback, chip::Controller::DeviceController & controller, + chip::NodeId nodeId, chip::EndpointId endpointId); + + /////////////////////////////////////////////////////////////// + // ReadClient::Callback implementation + /////////////////////////////////////////////////////////////// + void OnAttributeData(const chip::app::ConcreteDataAttributePath & path, chip::TLV::TLVReader * data, + const chip::app::StatusIB & status) override; + void OnError(CHIP_ERROR error) override; + void OnDone(chip::app::ReadClient * apReadClient) override; + + /////////////////////////////////////////////////////////////// + // callbacks for CASE session establishment + /////////////////////////////////////////////////////////////// + void OnDeviceConnected(chip::Messaging::ExchangeManager & exchangeMgr, const chip::SessionHandle & sessionHandle); + void OnDeviceConnectionFailure(const chip::ScopedNodeId & peerId, CHIP_ERROR error); + +private: + std::unique_ptr mClient; + + OnDoneCallback mOnDoneCallback; + chip::EndpointId mEndpointId; + chip::Callback::Callback mOnDeviceConnectedCallback; + chip::Callback::Callback mOnDeviceConnectionFailureCallback; +}; From ed7ef1bcb7eb9c01af329e54cdc50962a1478a36 Mon Sep 17 00:00:00 2001 From: Yufeng Wang Date: Thu, 17 Oct 2024 12:40:29 -0700 Subject: [PATCH 027/149] Cleanup AutoSync command (#36128) --- .../commands/fabric-sync/Commands.h | 1 - .../fabric-sync/FabricSyncCommand.cpp | 12 ----------- .../commands/fabric-sync/FabricSyncCommand.h | 19 ----------------- .../device_manager/DeviceManager.cpp | 21 ------------------- .../device_manager/DeviceManager.h | 9 ++------ 5 files changed, 2 insertions(+), 60 deletions(-) diff --git a/examples/fabric-admin/commands/fabric-sync/Commands.h b/examples/fabric-admin/commands/fabric-sync/Commands.h index a6bf1c258f9475..47f7207922beae 100644 --- a/examples/fabric-admin/commands/fabric-sync/Commands.h +++ b/examples/fabric-admin/commands/fabric-sync/Commands.h @@ -31,7 +31,6 @@ void registerCommandsFabricSync(Commands & commands, CredentialIssuerCommands * make_unique(credsIssuerConfig), make_unique(credsIssuerConfig), make_unique(credsIssuerConfig), - make_unique(credsIssuerConfig), }; commands.RegisterCommandSet(clusterName, clusterCommands, "Commands for fabric synchronization."); diff --git a/examples/fabric-admin/commands/fabric-sync/FabricSyncCommand.cpp b/examples/fabric-admin/commands/fabric-sync/FabricSyncCommand.cpp index 879d28cd156956..f10db13e939acd 100644 --- a/examples/fabric-admin/commands/fabric-sync/FabricSyncCommand.cpp +++ b/examples/fabric-admin/commands/fabric-sync/FabricSyncCommand.cpp @@ -305,15 +305,3 @@ CHIP_ERROR FabricSyncDeviceCommand::RunCommand(EndpointId remoteId) return CHIP_NO_ERROR; } - -CHIP_ERROR FabricAutoSyncCommand::RunCommand(bool enableAutoSync) -{ - DeviceMgr().EnableAutoSync(enableAutoSync); - - // print to console - fprintf(stderr, "Auto Fabric Sync is %s.\n", enableAutoSync ? "enabled" : "disabled"); - fprintf(stderr, - "WARNING: The auto-sync command is currently under development and may contain bugs. Use it at your own risk.\n"); - - return CHIP_NO_ERROR; -} diff --git a/examples/fabric-admin/commands/fabric-sync/FabricSyncCommand.h b/examples/fabric-admin/commands/fabric-sync/FabricSyncCommand.h index 16ee40e5b40f3e..8d14529155cab4 100644 --- a/examples/fabric-admin/commands/fabric-sync/FabricSyncCommand.h +++ b/examples/fabric-admin/commands/fabric-sync/FabricSyncCommand.h @@ -136,22 +136,3 @@ class FabricSyncDeviceCommand : public CHIPCommand, public CommissioningWindowDe CHIP_ERROR RunCommand(chip::EndpointId remoteId); }; - -class FabricAutoSyncCommand : public CHIPCommand -{ -public: - FabricAutoSyncCommand(CredentialIssuerCommands * credIssuerCommands) : CHIPCommand("enable-auto-sync", credIssuerCommands) - { - AddArgument("state", 0, 1, &mEnableAutoSync, "Set to true to enable auto Fabric Sync, false to disable."); - } - - /////////// CHIPCommand Interface ///////// - CHIP_ERROR RunCommand() override { return RunCommand(mEnableAutoSync); } - - chip::System::Clock::Timeout GetWaitDuration() const override { return chip::System::Clock::Seconds16(1); } - -private: - bool mEnableAutoSync; - - CHIP_ERROR RunCommand(bool enableAutoSync); -}; diff --git a/examples/fabric-admin/device_manager/DeviceManager.cpp b/examples/fabric-admin/device_manager/DeviceManager.cpp index 3bfd677d962435..45a40942a27be9 100644 --- a/examples/fabric-admin/device_manager/DeviceManager.cpp +++ b/examples/fabric-admin/device_manager/DeviceManager.cpp @@ -351,14 +351,6 @@ void DeviceManager::HandleAttributePartsListUpdate(TLV::TLVReader & data) { // print to console fprintf(stderr, "A new device is added on Endpoint: %u\n", endpoint); - - if (mAutoSyncEnabled) - { - StringBuilder commandBuilder; - commandBuilder.Add("fabricsync sync-device "); - commandBuilder.AddFormat("%d", endpoint); - PushCommand(commandBuilder.c_str()); - } } // Process removed endpoints @@ -373,19 +365,6 @@ void DeviceManager::HandleAttributePartsListUpdate(TLV::TLVReader & data) ChipLogProgress(NotSpecified, "No device on Endpoint: %u", endpoint); continue; } - - if (mAutoSyncEnabled) - { - NodeId nodeId = device->GetNodeId(); - if (PairingManager::Instance().UnpairDevice(nodeId) != CHIP_NO_ERROR) - { - ChipLogError(NotSpecified, "Failed to unpair device " ChipLogFormatX64, ChipLogValueX64(nodeId)); - } - else - { - PairingManager::Instance().SetPairingDelegate(this); - } - } } } diff --git a/examples/fabric-admin/device_manager/DeviceManager.h b/examples/fabric-admin/device_manager/DeviceManager.h index 43461f41c17229..54d3bf97864820 100644 --- a/examples/fabric-admin/device_manager/DeviceManager.h +++ b/examples/fabric-admin/device_manager/DeviceManager.h @@ -69,14 +69,10 @@ class DeviceManager : public PairingDelegate void SetLocalBridgeSetupPinCode(uint32_t pinCode) { mLocalBridgeSetupPinCode = pinCode; } void SetLocalBridgeNodeId(chip::NodeId nodeId) { mLocalBridgeNodeId = nodeId; } - bool IsAutoSyncEnabled() const { return mAutoSyncEnabled; } - bool IsFabricSyncReady() const { return mRemoteBridgeNodeId != chip::kUndefinedNodeId; } bool IsLocalBridgeReady() const { return mLocalBridgeNodeId != chip::kUndefinedNodeId; } - void EnableAutoSync(bool state) { mAutoSyncEnabled = state; } - void AddSyncedDevice(const Device & device); void RemoveSyncedDevice(chip::NodeId nodeId); @@ -208,9 +204,8 @@ class DeviceManager : public PairingDelegate chip::NodeId mLocalBridgeNodeId = chip::kUndefinedNodeId; std::set mSyncedDevices; - bool mAutoSyncEnabled = false; - bool mInitialized = false; - uint64_t mRequestId = 0; + bool mInitialized = false; + uint64_t mRequestId = 0; BridgeSubscription mBridgeSubscriber; FabricSyncGetter mFabricSyncGetter; From 5fe4409398cc5029ecb4c8b5090b4cf9a488fa11 Mon Sep 17 00:00:00 2001 From: Terence Hampson Date: Thu, 17 Oct 2024 15:43:47 -0400 Subject: [PATCH 028/149] =?UTF-8?q?[Fabric=20Sync]=20Have=20ECOINFO=20mark?= =?UTF-8?q?=20attribute=20dirty=20when=20new=20entry=20added=20=E2=80=A6?= =?UTF-8?q?=20(#36088)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ecosystem-information-server.cpp | 2 + .../ecosystem-information-server.h | 22 ++++++++- .../tests/TestEcosystemInformationCluster.cpp | 49 +++++++++++++++++++ 3 files changed, 72 insertions(+), 1 deletion(-) diff --git a/src/app/clusters/ecosystem-information-server/ecosystem-information-server.cpp b/src/app/clusters/ecosystem-information-server/ecosystem-information-server.cpp index 5793ebfd1a4726..ec2f4f852b5147 100644 --- a/src/app/clusters/ecosystem-information-server/ecosystem-information-server.cpp +++ b/src/app/clusters/ecosystem-information-server/ecosystem-information-server.cpp @@ -264,6 +264,7 @@ CHIP_ERROR EcosystemInformationServer::AddDeviceInfo(EndpointId aEndpoint, std:: auto & deviceInfo = mDevicesMap[aEndpoint]; deviceInfo.mDeviceDirectory.push_back(std::move(aDevice)); + mMatterContext.MarkDirty(aEndpoint, Attributes::DeviceDirectory::Id); return CHIP_NO_ERROR; } @@ -282,6 +283,7 @@ CHIP_ERROR EcosystemInformationServer::AddLocationInfo(EndpointId aEndpoint, con VerifyOrReturnError((deviceInfo.mLocationDirectory.find(key) == deviceInfo.mLocationDirectory.end()), CHIP_ERROR_INVALID_ARGUMENT); deviceInfo.mLocationDirectory[key] = std::move(aLocation); + mMatterContext.MarkDirty(aEndpoint, Attributes::LocationDirectory::Id); return CHIP_NO_ERROR; } diff --git a/src/app/clusters/ecosystem-information-server/ecosystem-information-server.h b/src/app/clusters/ecosystem-information-server/ecosystem-information-server.h index 13d2bc8a6da850..81cfcfab9c8d53 100644 --- a/src/app/clusters/ecosystem-information-server/ecosystem-information-server.h +++ b/src/app/clusters/ecosystem-information-server/ecosystem-information-server.h @@ -27,6 +27,7 @@ #include #include +#include #include @@ -35,6 +36,21 @@ namespace app { namespace Clusters { namespace EcosystemInformation { +class MatterContext +{ +public: + virtual ~MatterContext() = default; + // MarkDirty + virtual void MarkDirty(EndpointId endpointId, AttributeId attributeId) + { + MatterReportingAttributeChangeCallback(endpointId, Id, attributeId); + } +}; + +class TestOnlyParameter +{ +}; + // This intentionally mirrors Structs::EcosystemDeviceStruct::Type but has ownership // of underlying types. class EcosystemDeviceStruct @@ -144,11 +160,14 @@ class EcosystemLocationStruct uint64_t mLocationDescriptorLastEditEpochUs; }; -class EcosystemInformationServer +class EcosystemInformationServer : public MatterContext { public: static EcosystemInformationServer & Instance(); + EcosystemInformationServer() : mMatterContext(*this){}; + EcosystemInformationServer(TestOnlyParameter _, MatterContext & aMatterContext) : mMatterContext(aMatterContext){}; + /** * @brief Add EcosystemInformation Cluster to endpoint so we respond appropriately on endpoint * @@ -212,6 +231,7 @@ class EcosystemInformationServer CHIP_ERROR EncodeDeviceDirectoryAttribute(EndpointId aEndpoint, AttributeValueEncoder & aEncoder); CHIP_ERROR EncodeLocationStructAttribute(EndpointId aEndpoint, AttributeValueEncoder & aEncoder); + MatterContext & mMatterContext; std::map mDevicesMap; static EcosystemInformationServer mInstance; diff --git a/src/app/tests/TestEcosystemInformationCluster.cpp b/src/app/tests/TestEcosystemInformationCluster.cpp index f8d9f34642f1cc..8d7a2c217fe6d2 100644 --- a/src/app/tests/TestEcosystemInformationCluster.cpp +++ b/src/app/tests/TestEcosystemInformationCluster.cpp @@ -49,11 +49,28 @@ const ClusterId kEcosystemInfoClusterId = EcosystemInformation::Id; const AttributeId kDeviceDirectoryAttributeId = EcosystemInformation::Attributes::DeviceDirectory::Id; const AttributeId kLocationDirectoryAttributeId = EcosystemInformation::Attributes::LocationDirectory::Id; +class MockMatterContext : public MatterContext +{ +public: + virtual void MarkDirty(EndpointId endpointId, AttributeId attributeId) override + { + ConcreteAttributePath path(endpointId, kEcosystemInfoClusterId, attributeId); + mDirtyMarkedList.push_back(path); + } + + std::vector & GetDirtyList() { return mDirtyMarkedList; } + +private: + std::vector mDirtyMarkedList; +}; + } // namespace class TestEcosystemInformationCluster : public ::testing::Test { public: + TestEcosystemInformationCluster() : mClusterServer(TestOnlyParameter(), mMockMatterContext) {} + static void SetUpTestSuite() { ASSERT_EQ(chip::Platform::MemoryInit(), CHIP_NO_ERROR); } static void TearDownTestSuite() { chip::Platform::MemoryShutdown(); } @@ -80,7 +97,10 @@ class TestEcosystemInformationCluster : public ::testing::Test return locationInfo; } + MockMatterContext & GetMockMatterContext() { return mMockMatterContext; } + private: + MockMatterContext mMockMatterContext; Clusters::EcosystemInformation::EcosystemInformationServer mClusterServer; }; @@ -265,6 +285,19 @@ TEST_F(TestEcosystemInformationCluster, AddDeviceInfo) ASSERT_FALSE(iterator.Next()); } +TEST_F(TestEcosystemInformationCluster, AddDeviceInfoResultInMarkDirty) +{ + std::unique_ptr deviceInfo = CreateSimplestValidDeviceStruct(); + ASSERT_EQ(EcoInfoCluster().AddDeviceInfo(kValidEndpointId, std::move(deviceInfo)), CHIP_NO_ERROR); + + auto markedDirtyList = GetMockMatterContext().GetDirtyList(); + ASSERT_EQ(markedDirtyList.size(), 1u); + ConcreteAttributePath path = markedDirtyList[0]; + ASSERT_EQ(path.mEndpointId, kValidEndpointId); + ASSERT_EQ(path.mClusterId, kEcosystemInfoClusterId); + ASSERT_EQ(path.mAttributeId, kDeviceDirectoryAttributeId); +} + TEST_F(TestEcosystemInformationCluster, BuildingEcosystemLocationStruct) { EcosystemLocationStruct::Builder locationInfoBuilder; @@ -388,5 +421,21 @@ TEST_F(TestEcosystemInformationCluster, AddLocationInfo) ASSERT_FALSE(iterator.Next()); } +TEST_F(TestEcosystemInformationCluster, AddLocationInfoResultInMarkDirty) +{ + std::unique_ptr locationInfo = CreateValidLocationStruct(); + const char * kValidLocationIdStr = "SomeLocationIdString"; + ASSERT_EQ(EcoInfoCluster().AddLocationInfo(kValidEndpointId, kValidLocationIdStr, Testing::kAdminSubjectDescriptor.fabricIndex, + std::move(locationInfo)), + CHIP_NO_ERROR); + + auto markedDirtyList = GetMockMatterContext().GetDirtyList(); + ASSERT_EQ(markedDirtyList.size(), 1u); + ConcreteAttributePath path = markedDirtyList[0]; + ASSERT_EQ(path.mEndpointId, kValidEndpointId); + ASSERT_EQ(path.mClusterId, kEcosystemInfoClusterId); + ASSERT_EQ(path.mAttributeId, kLocationDirectoryAttributeId); +} + } // namespace app } // namespace chip From 1ae2e6eb78555d249e3c63870e93c55dbbded067 Mon Sep 17 00:00:00 2001 From: Justin Wood Date: Thu, 17 Oct 2024 13:23:05 -0700 Subject: [PATCH 029/149] Adding accessory for publicKeyData (#36129) * Adding accessory for publicKeyData * Update src/darwin/Framework/CHIP/MTRCertificateInfo.mm * Restyled by whitespace * Restyled by clang-format * braces for multi-line conditional statement --------- Co-authored-by: Restyled.io Co-authored-by: Kiel Oleson --- src/darwin/Framework/CHIP/MTRCertificateInfo.h | 13 +++++++++---- .../Framework/CHIP/MTRCertificateInfo.mm | 18 ++++++++++++++++++ .../CHIPTests/MTRCertificateInfoTests.m | 1 + 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/src/darwin/Framework/CHIP/MTRCertificateInfo.h b/src/darwin/Framework/CHIP/MTRCertificateInfo.h index 20e907466c74f2..eba7aec83073e1 100644 --- a/src/darwin/Framework/CHIP/MTRCertificateInfo.h +++ b/src/darwin/Framework/CHIP/MTRCertificateInfo.h @@ -55,15 +55,20 @@ MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) * Matter root certificates are self-signed, i.e. the issuer and the subject are * the same. */ -@property (readonly) MTRDistinguishedNameInfo * issuer; +@property (readonly, retain) MTRDistinguishedNameInfo * issuer; /** * The Distinguished Name of the entity represented by the certificate. */ -@property (readonly) MTRDistinguishedNameInfo * subject; +@property (readonly, retain) MTRDistinguishedNameInfo * subject; -@property (readonly) NSDate * notBefore; -@property (readonly) NSDate * notAfter; +@property (readonly, retain) NSDate * notBefore; +@property (readonly, retain) NSDate * notAfter; + +/** + * Public key data for this certificate + */ +@property (nullable, readonly, retain) NSData * publicKeyData; @end diff --git a/src/darwin/Framework/CHIP/MTRCertificateInfo.mm b/src/darwin/Framework/CHIP/MTRCertificateInfo.mm index f3aacb9dd51f24..43c4117231a2e9 100644 --- a/src/darwin/Framework/CHIP/MTRCertificateInfo.mm +++ b/src/darwin/Framework/CHIP/MTRCertificateInfo.mm @@ -21,9 +21,15 @@ #include +#import "NSDataSpanConversion.h" + +#include +#include + NS_ASSUME_NONNULL_BEGIN using namespace chip; +using namespace chip::Crypto; using namespace chip::Credentials; using namespace chip::ASN1; @@ -65,6 +71,18 @@ - (NSDate *)notBefore return MatterEpochSecondsAsDate(_data.mNotBeforeTime); } +- (nullable NSData *)publicKeyData +{ + P256PublicKeySpan publicKeySpan; + CHIP_ERROR err = ExtractPublicKeyFromChipCert(AsByteSpan(_bytes), publicKeySpan); + + if (err != CHIP_NO_ERROR) { + return nil; + } + + return AsData(publicKeySpan); +} + - (NSDate *)notAfter { // "no expiry" is encoded as kNullCertTime (see ChipEpochToASN1Time) diff --git a/src/darwin/Framework/CHIPTests/MTRCertificateInfoTests.m b/src/darwin/Framework/CHIPTests/MTRCertificateInfoTests.m index bdf52e33d37b43..8a532a8e3300dc 100644 --- a/src/darwin/Framework/CHIPTests/MTRCertificateInfoTests.m +++ b/src/darwin/Framework/CHIPTests/MTRCertificateInfoTests.m @@ -117,6 +117,7 @@ - (void)testParseOperationalCertificateTLV { MTRCertificateInfo * info = [[MTRCertificateInfo alloc] initWithTLVBytes:self.exampleNOCertTLV]; XCTAssertNotNil(info); + XCTAssertNotNil(info.publicKeyData); XCTAssertEqual([NSDate.now compare:info.notBefore], NSOrderedDescending); XCTAssertEqual([NSDate.now compare:info.notAfter], NSOrderedAscending); From bdfc0d104d7feb4c2ea697af54282a5a3f5ef6f9 Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Thu, 17 Oct 2024 18:23:44 -0400 Subject: [PATCH 030/149] Auto-release group iterators (#36127) * Fix up group iterator releasing * Add missing bracket * Renames and comments * Restyled by clang-format * Update src/app/WriteHandler.cpp Co-authored-by: Arkadiusz Bokowy --------- Co-authored-by: Restyled.io Co-authored-by: Arkadiusz Bokowy --- src/app/WriteHandler.cpp | 37 +++++++++++++++++++++++++++++-------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/src/app/WriteHandler.cpp b/src/app/WriteHandler.cpp index d2fde339304f8f..011fd2e46b48ab 100644 --- a/src/app/WriteHandler.cpp +++ b/src/app/WriteHandler.cpp @@ -42,6 +42,31 @@ namespace chip { namespace app { +namespace { + +/// Wraps a EndpointIterator and ensures that `::Release()` is called +/// for the iterator (assuming it is non-null) +class AutoReleaseGroupEndpointIterator +{ +public: + explicit AutoReleaseGroupEndpointIterator(Credentials::GroupDataProvider::EndpointIterator * iterator) : mIterator(iterator) {} + ~AutoReleaseGroupEndpointIterator() + { + if (mIterator != nullptr) + { + mIterator->Release(); + } + } + + bool IsNull() const { return mIterator == nullptr; } + bool Next(Credentials::GroupDataProvider::GroupEndpoint & item) { return mIterator->Next(item); } + +private: + Credentials::GroupDataProvider::EndpointIterator * mIterator; +}; + +} // namespace + using namespace Protocols::InteractionModel; using Status = Protocols::InteractionModel::Status; @@ -436,10 +461,6 @@ CHIP_ERROR WriteHandler::ProcessGroupAttributeDataIBs(TLV::TLVReader & aAttribut ConcreteDataAttributePath dataAttributePath; TLV::TLVReader reader = aAttributeDataIBsReader; - Credentials::GroupDataProvider::GroupEndpoint mapping; - Credentials::GroupDataProvider * groupDataProvider = Credentials::GetGroupDataProvider(); - Credentials::GroupDataProvider::EndpointIterator * iterator; - err = element.Init(reader); SuccessOrExit(err); @@ -461,8 +482,8 @@ CHIP_ERROR WriteHandler::ProcessGroupAttributeDataIBs(TLV::TLVReader & aAttribut "Received group attribute write for Group=%u Cluster=" ChipLogFormatMEI " attribute=" ChipLogFormatMEI, groupId, ChipLogValueMEI(dataAttributePath.mClusterId), ChipLogValueMEI(dataAttributePath.mAttributeId)); - iterator = groupDataProvider->IterateEndpoints(fabric); - VerifyOrExit(iterator != nullptr, err = CHIP_ERROR_NO_MEMORY); + AutoReleaseGroupEndpointIterator iterator(Credentials::GetGroupDataProvider()->IterateEndpoints(fabric)); + VerifyOrExit(!iterator.IsNull(), err = CHIP_ERROR_NO_MEMORY); bool shouldReportListWriteEnd = ShouldReportListWriteEnd( mProcessingAttributePath, mStateFlags.Has(StateBits::kProcessingAttributeIsList), dataAttributePath); @@ -470,7 +491,8 @@ CHIP_ERROR WriteHandler::ProcessGroupAttributeDataIBs(TLV::TLVReader & aAttribut std::optional isListAttribute = std::nullopt; - while (iterator->Next(mapping)) + Credentials::GroupDataProvider::GroupEndpoint mapping; + while (iterator.Next(mapping)) { if (groupId != mapping.group_id) { @@ -552,7 +574,6 @@ CHIP_ERROR WriteHandler::ProcessGroupAttributeDataIBs(TLV::TLVReader & aAttribut dataAttributePath.mEndpointId = kInvalidEndpointId; mStateFlags.Set(StateBits::kProcessingAttributeIsList, dataAttributePath.IsListOperation()); mProcessingAttributePath.SetValue(dataAttributePath); - iterator->Release(); } if (CHIP_END_OF_TLV == err) From 9b252030ee6c8caf961c43cf1268e08afdeb0bea Mon Sep 17 00:00:00 2001 From: Yufeng Wang Date: Thu, 17 Oct 2024 15:34:24 -0700 Subject: [PATCH 031/149] [Fabric-Admin] Implement CommissionerControl command APIs (#36057) * Implement CommissionerControl command APIs * Address review comment * Add missing change * Init mCommissionerControl in SetRemoteBridgeNodeId * Remove redundant optimization * Fix merge conflict * Call OnDone on failure * Fix build error after merge --- examples/fabric-admin/BUILD.gn | 2 + .../commands/clusters/ClusterCommand.h | 1 - .../device_manager/CommissionerControl.cpp | 141 ++++++++++++++++++ .../device_manager/CommissionerControl.h | 125 ++++++++++++++++ .../device_manager/DeviceManager.cpp | 51 ++++--- .../device_manager/DeviceManager.h | 5 +- 6 files changed, 304 insertions(+), 21 deletions(-) create mode 100644 examples/fabric-admin/device_manager/CommissionerControl.cpp create mode 100644 examples/fabric-admin/device_manager/CommissionerControl.h diff --git a/examples/fabric-admin/BUILD.gn b/examples/fabric-admin/BUILD.gn index 58d9cee914e410..e95d6cb7c8f555 100644 --- a/examples/fabric-admin/BUILD.gn +++ b/examples/fabric-admin/BUILD.gn @@ -82,6 +82,8 @@ static_library("fabric-admin-utils") { "commands/pairing/ToTLVCert.cpp", "device_manager/BridgeSubscription.cpp", "device_manager/BridgeSubscription.h", + "device_manager/CommissionerControl.cpp", + "device_manager/CommissionerControl.h", "device_manager/DeviceManager.cpp", "device_manager/DeviceManager.h", "device_manager/DeviceSubscription.cpp", diff --git a/examples/fabric-admin/commands/clusters/ClusterCommand.h b/examples/fabric-admin/commands/clusters/ClusterCommand.h index edf2302219fa1c..7c66bebcecfbea 100644 --- a/examples/fabric-admin/commands/clusters/ClusterCommand.h +++ b/examples/fabric-admin/commands/clusters/ClusterCommand.h @@ -84,7 +84,6 @@ class ClusterCommand : public InteractionModelCommands, public ModelCommand, pub if (data != nullptr) { LogErrorOnFailure(RemoteDataModelLogger::LogCommandAsJSON(path, data)); - DeviceMgr().HandleCommandResponse(path, *data); } } diff --git a/examples/fabric-admin/device_manager/CommissionerControl.cpp b/examples/fabric-admin/device_manager/CommissionerControl.cpp new file mode 100644 index 00000000000000..b919ceb0683192 --- /dev/null +++ b/examples/fabric-admin/device_manager/CommissionerControl.cpp @@ -0,0 +1,141 @@ +#include "CommissionerControl.h" +#include + +using namespace ::chip; + +void CommissionerControl::Init(Controller::DeviceCommissioner & commissioner, NodeId nodeId, EndpointId endpointId) +{ + // Ensure that mCommissioner is not already initialized + VerifyOrDie(mCommissioner == nullptr); + + ChipLogProgress(NotSpecified, "Initilize CommissionerControl"); + mCommissioner = &commissioner; + mDestinationId = nodeId; + mEndpointId = endpointId; +} + +CHIP_ERROR CommissionerControl::RequestCommissioningApproval(uint64_t requestId, uint16_t vendorId, uint16_t productId, + Optional label) +{ + VerifyOrReturnError(mCommissioner != nullptr, CHIP_ERROR_INCORRECT_STATE); + + ChipLogProgress(NotSpecified, "Sending RequestCommissioningApproval to node " ChipLogFormatX64, + ChipLogValueX64(mDestinationId)); + + mRequestCommissioningApproval.requestID = requestId; + mRequestCommissioningApproval.vendorID = static_cast(vendorId); + mRequestCommissioningApproval.productID = productId; + + if (label.HasValue()) + { + VerifyOrReturnError(label.Value().size() <= kMaxDeviceLabelLength, CHIP_ERROR_BUFFER_TOO_SMALL); + memcpy(mLabelBuffer, label.Value().data(), label.Value().size()); + mRequestCommissioningApproval.label = Optional>(CharSpan(mLabelBuffer, label.Value().size())); + } + + mCommandType = CommandType::kRequestCommissioningApproval; + return mCommissioner->GetConnectedDevice(mDestinationId, &mOnDeviceConnectedCallback, &mOnDeviceConnectionFailureCallback); +} + +CHIP_ERROR CommissionerControl::CommissionNode(uint64_t requestId, uint16_t responseTimeoutSeconds) +{ + VerifyOrReturnError(mCommissioner != nullptr, CHIP_ERROR_INCORRECT_STATE); + + ChipLogProgress(NotSpecified, "Sending CommissionNode to node " ChipLogFormatX64, ChipLogValueX64(mDestinationId)); + + mCommissionNode.requestID = requestId; + mCommissionNode.responseTimeoutSeconds = responseTimeoutSeconds; + + mCommandType = CommandType::kCommissionNode; + return mCommissioner->GetConnectedDevice(mDestinationId, &mOnDeviceConnectedCallback, &mOnDeviceConnectionFailureCallback); +} + +void CommissionerControl::OnResponse(app::CommandSender * client, const app::ConcreteCommandPath & path, + const app::StatusIB & status, TLV::TLVReader * data) +{ + ChipLogProgress(NotSpecified, "CommissionerControl: OnResponse."); + + CHIP_ERROR error = status.ToChipError(); + if (CHIP_NO_ERROR != error) + { + ChipLogError(NotSpecified, "Response Failure: %s", ErrorStr(error)); + return; + } + + if (data != nullptr) + { + DeviceMgr().HandleCommandResponse(path, *data); + } +} + +void CommissionerControl::OnError(const app::CommandSender * client, CHIP_ERROR error) +{ + // Handle the error, then reset mCommandSender + ChipLogProgress(NotSpecified, "CommissionerControl: OnError: Error: %s", ErrorStr(error)); +} + +void CommissionerControl::OnDone(app::CommandSender * client) +{ + ChipLogProgress(NotSpecified, "CommissionerControl: OnDone."); + + switch (mCommandType) + { + case CommandType::kRequestCommissioningApproval: + ChipLogProgress(NotSpecified, "CommissionerControl: Command RequestCommissioningApproval has been successfully processed."); + break; + + case CommandType::kCommissionNode: + ChipLogProgress(NotSpecified, "CommissionerControl: Command CommissionNode has been successfully processed."); + break; + + default: + ChipLogError(NotSpecified, "CommissionerControl: Unknown or unhandled command type in OnDone."); + break; + } + + // Reset command type to undefined after processing is done + mCommandType = CommandType::kUndefined; + + // Ensure that mCommandSender is cleaned up after it is done + mCommandSender.reset(); +} + +CHIP_ERROR CommissionerControl::SendCommandForType(CommandType commandType, DeviceProxy * device) +{ + switch (commandType) + { + case CommandType::kRequestCommissioningApproval: + return SendCommand(device, mEndpointId, app::Clusters::CommissionerControl::Id, + app::Clusters::CommissionerControl::Commands::RequestCommissioningApproval::Id, + mRequestCommissioningApproval); + case CommandType::kCommissionNode: + return SendCommand(device, mEndpointId, app::Clusters::CommissionerControl::Id, + app::Clusters::CommissionerControl::Commands::CommissionNode::Id, mCommissionNode); + default: + return CHIP_ERROR_INVALID_ARGUMENT; + } +} + +void CommissionerControl::OnDeviceConnectedFn(void * context, Messaging::ExchangeManager & exchangeMgr, + const SessionHandle & sessionHandle) +{ + CommissionerControl * self = reinterpret_cast(context); + VerifyOrReturn(self != nullptr, ChipLogError(NotSpecified, "OnDeviceConnectedFn: context is null")); + + OperationalDeviceProxy device(&exchangeMgr, sessionHandle); + + CHIP_ERROR err = self->SendCommandForType(self->mCommandType, &device); + if (err != CHIP_NO_ERROR) + { + ChipLogError(NotSpecified, "Failed to send CommissionerControl command."); + self->OnDone(nullptr); + } +} + +void CommissionerControl::OnDeviceConnectionFailureFn(void * context, const ScopedNodeId & peerId, CHIP_ERROR err) +{ + LogErrorOnFailure(err); + CommissionerControl * self = reinterpret_cast(context); + VerifyOrReturn(self != nullptr, ChipLogError(NotSpecified, "OnDeviceConnectedFn: context is null")); + self->OnDone(nullptr); +} diff --git a/examples/fabric-admin/device_manager/CommissionerControl.h b/examples/fabric-admin/device_manager/CommissionerControl.h new file mode 100644 index 00000000000000..1fad323e125c2a --- /dev/null +++ b/examples/fabric-admin/device_manager/CommissionerControl.h @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#pragma once + +#include +#include + +/** + * @class CommissionerControl + * @brief This class handles sending CHIP commands related to commissioning, including sending + * commissioning approval requests and commissioning nodes. + * + * The class acts as a command sender and implements the `chip::app::CommandSender::Callback` interface + * to handle responses, errors, and completion events for the commands it sends. It relies on external + * CCTRL delegate and server mechanisms to manage the overall protocol and state transitions, including + * processing the CommissioningRequestResult and invoking CommissionNode. + */ +class CommissionerControl : public chip::app::CommandSender::Callback +{ +public: + CommissionerControl() : + mOnDeviceConnectedCallback(OnDeviceConnectedFn, this), mOnDeviceConnectionFailureCallback(OnDeviceConnectionFailureFn, this) + {} + + /** + * @brief Initializes the CommissionerControl with a DeviceCommissioner, NodeId, and EndpointId. + * + * @param commissioner The DeviceCommissioner to use for the commissioning process. + * @param nodeId The node ID of the remote fabric bridge. + * @param endpointId The endpoint on which to send CommissionerControl commands. + */ + void Init(chip::Controller::DeviceCommissioner & commissioner, chip::NodeId nodeId, chip::EndpointId endpointId); + + /** + * @brief Sends a RequestCommissioningApproval command to the device. + * + * @param requestId The unique request ID. + * @param vendorId The vendor ID of the device. + * @param productId The product ID of the device. + * @param label Optional label for the device. + * @return CHIP_ERROR CHIP_NO_ERROR on success, or an appropriate error code on failure. + */ + CHIP_ERROR RequestCommissioningApproval(uint64_t requestId, uint16_t vendorId, uint16_t productId, + chip::Optional label); + /** + * @brief Sends a CommissionNode command to the device. + * + * @param requestId The unique request ID. + * @param responseTimeoutSeconds Timeout for the response in seconds. + * @return CHIP_ERROR CHIP_NO_ERROR on success, or an appropriate error code on failure. + */ + CHIP_ERROR CommissionNode(uint64_t requestId, uint16_t responseTimeoutSeconds); + + /////////// CommandSender Callback Interface ///////// + virtual void OnResponse(chip::app::CommandSender * client, const chip::app::ConcreteCommandPath & path, + const chip::app::StatusIB & status, chip::TLV::TLVReader * data) override; + + virtual void OnError(const chip::app::CommandSender * client, CHIP_ERROR error) override; + + virtual void OnDone(chip::app::CommandSender * client) override; + +private: + static constexpr uint16_t kMaxDeviceLabelLength = 64; + + enum class CommandType : uint8_t + { + kUndefined = 0, + kRequestCommissioningApproval = 1, + kCommissionNode = 2, + }; + + template + CHIP_ERROR SendCommand(chip::DeviceProxy * device, chip::EndpointId endpointId, chip::ClusterId clusterId, + chip::CommandId commandId, const T & value) + { + chip::app::CommandPathParams commandPath = { endpointId, clusterId, commandId, + (chip::app::CommandPathFlags::kEndpointIdValid) }; + mCommandSender = std::make_unique(this, device->GetExchangeManager(), false, false, + device->GetSecureSession().Value()->AllowsLargePayload()); + + VerifyOrReturnError(mCommandSender != nullptr, CHIP_ERROR_NO_MEMORY); + + chip::app::CommandSender::AddRequestDataParameters addRequestDataParams(chip::NullOptional); + ReturnErrorOnFailure(mCommandSender->AddRequestData(commandPath, value, addRequestDataParams)); + ReturnErrorOnFailure(mCommandSender->SendCommandRequest(device->GetSecureSession().Value())); + + return CHIP_NO_ERROR; + } + + CHIP_ERROR SendCommandForType(CommandType commandType, chip::DeviceProxy * device); + + static void OnDeviceConnectedFn(void * context, chip::Messaging::ExchangeManager & exchangeMgr, + const chip::SessionHandle & sessionHandle); + static void OnDeviceConnectionFailureFn(void * context, const chip::ScopedNodeId & peerId, CHIP_ERROR error); + + // Private data members + chip::Controller::DeviceCommissioner * mCommissioner = nullptr; + std::unique_ptr mCommandSender; + chip::NodeId mDestinationId = chip::kUndefinedNodeId; + chip::EndpointId mEndpointId = chip::kRootEndpointId; + CommandType mCommandType = CommandType::kUndefined; + char mLabelBuffer[kMaxDeviceLabelLength]; + + chip::Callback::Callback mOnDeviceConnectedCallback; + chip::Callback::Callback mOnDeviceConnectionFailureCallback; + + chip::app::Clusters::CommissionerControl::Commands::RequestCommissioningApproval::Type mRequestCommissioningApproval; + chip::app::Clusters::CommissionerControl::Commands::CommissionNode::Type mCommissionNode; +}; diff --git a/examples/fabric-admin/device_manager/DeviceManager.cpp b/examples/fabric-admin/device_manager/DeviceManager.cpp index 45a40942a27be9..0d7d656a4e685e 100644 --- a/examples/fabric-admin/device_manager/DeviceManager.cpp +++ b/examples/fabric-admin/device_manager/DeviceManager.cpp @@ -26,7 +26,6 @@ #include using namespace chip; -using namespace chip::app::Clusters; namespace { @@ -67,6 +66,12 @@ void DeviceManager::UpdateLastUsedNodeId(NodeId nodeId) } } +void DeviceManager::SetRemoteBridgeNodeId(chip::NodeId nodeId) +{ + mRemoteBridgeNodeId = nodeId; + mCommissionerControl.Init(PairingManager::Instance().CurrentCommissioner(), mRemoteBridgeNodeId, kAggregatorEndpointId); +} + void DeviceManager::AddSyncedDevice(const Device & device) { mSyncedDevices.insert(device); @@ -230,7 +235,7 @@ void DeviceManager::HandleReadSupportedDeviceCategories(TLV::TLVReader & data) { ChipLogProgress(NotSpecified, "Attribute SupportedDeviceCategories detected."); - BitMask value; + BitMask value; CHIP_ERROR error = app::DataModel::Decode(data, value); if (error != CHIP_NO_ERROR) { @@ -238,7 +243,7 @@ void DeviceManager::HandleReadSupportedDeviceCategories(TLV::TLVReader & data) return; } - if (value.Has(CommissionerControl::SupportedDeviceCategoryBitmap::kFabricSynchronization)) + if (value.Has(app::Clusters::CommissionerControl::SupportedDeviceCategoryBitmap::kFabricSynchronization)) { ChipLogProgress(NotSpecified, "Remote Fabric-Bridge supports Fabric Synchronization, start reverse commissioning."); RequestCommissioningApproval(); @@ -254,19 +259,24 @@ void DeviceManager::RequestCommissioningApproval() uint16_t vendorId = static_cast(CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID); uint16_t productId = static_cast(CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID); - StringBuilder commandBuilder; - commandBuilder.Add("commissionercontrol request-commissioning-approval "); - commandBuilder.AddFormat("%lu %u %u %lu %d", requestId, vendorId, productId, mRemoteBridgeNodeId, kAggregatorEndpointId); + CHIP_ERROR error = mCommissionerControl.RequestCommissioningApproval(requestId, vendorId, productId, NullOptional); + + if (error != CHIP_NO_ERROR) + { + ChipLogError(NotSpecified, + "Failed to request commissioning-approval to the remote bridge (NodeId: %lu). Error: %" CHIP_ERROR_FORMAT, + mRemoteBridgeNodeId, error.Format()); + return; + } mRequestId = requestId; - PushCommand(commandBuilder.c_str()); } void DeviceManager::HandleCommissioningRequestResult(TLV::TLVReader & data) { ChipLogProgress(NotSpecified, "CommissioningRequestResult event received."); - CommissionerControl::Events::CommissioningRequestResult::DecodableType value; + app::Clusters::CommissionerControl::Events::CommissioningRequestResult::DecodableType value; CHIP_ERROR error = app::DataModel::Decode(data, value); if (error != CHIP_NO_ERROR) { @@ -372,16 +382,20 @@ void DeviceManager::SendCommissionNodeRequest(uint64_t requestId, uint16_t respo { ChipLogProgress(NotSpecified, "Request the Commissioner Control Server to begin commissioning a previously approved request."); - StringBuilder commandBuilder; - commandBuilder.Add("commissionercontrol commission-node "); - commandBuilder.AddFormat("%lu %u %lu %d", requestId, responseTimeoutSeconds, mRemoteBridgeNodeId, kAggregatorEndpointId); + CHIP_ERROR error = mCommissionerControl.CommissionNode(requestId, responseTimeoutSeconds); - PushCommand(commandBuilder.c_str()); + if (error != CHIP_NO_ERROR) + { + ChipLogError(NotSpecified, + "Failed to send CommissionNode command to the remote bridge (NodeId: %lu). Error: %" CHIP_ERROR_FORMAT, + mRemoteBridgeNodeId, error.Format()); + return; + } } void DeviceManager::HandleReverseOpenCommissioningWindow(TLV::TLVReader & data) { - CommissionerControl::Commands::ReverseOpenCommissioningWindow::DecodableType value; + app::Clusters::CommissionerControl::Commands::ReverseOpenCommissioningWindow::DecodableType value; CHIP_ERROR error = app::DataModel::Decode(data, value); if (error != CHIP_NO_ERROR) @@ -405,7 +419,8 @@ void DeviceManager::HandleReverseOpenCommissioningWindow(TLV::TLVReader & data) void DeviceManager::HandleAttributeData(const app::ConcreteDataAttributePath & path, TLV::TLVReader & data) { - if (path.mClusterId == Descriptor::Id && path.mAttributeId == Descriptor::Attributes::PartsList::Id) + if (path.mClusterId == app::Clusters::Descriptor::Id && + path.mAttributeId == app::Clusters::Descriptor::Attributes::PartsList::Id) { HandleAttributePartsListUpdate(data); return; @@ -414,8 +429,8 @@ void DeviceManager::HandleAttributeData(const app::ConcreteDataAttributePath & p void DeviceManager::HandleEventData(const app::EventHeader & header, TLV::TLVReader & data) { - if (header.mPath.mClusterId == CommissionerControl::Id && - header.mPath.mEventId == CommissionerControl::Events::CommissioningRequestResult::Id) + if (header.mPath.mClusterId == app::Clusters::CommissionerControl::Id && + header.mPath.mEventId == app::Clusters::CommissionerControl::Events::CommissioningRequestResult::Id) { HandleCommissioningRequestResult(data); } @@ -425,8 +440,8 @@ void DeviceManager::HandleCommandResponse(const app::ConcreteCommandPath & path, { ChipLogProgress(NotSpecified, "Command Response received."); - if (path.mClusterId == CommissionerControl::Id && - path.mCommandId == CommissionerControl::Commands::ReverseOpenCommissioningWindow::Id) + if (path.mClusterId == app::Clusters::CommissionerControl::Id && + path.mCommandId == app::Clusters::CommissionerControl::Commands::ReverseOpenCommissioningWindow::Id) { HandleReverseOpenCommissioningWindow(data); } diff --git a/examples/fabric-admin/device_manager/DeviceManager.h b/examples/fabric-admin/device_manager/DeviceManager.h index 54d3bf97864820..d405bd358d5fdb 100644 --- a/examples/fabric-admin/device_manager/DeviceManager.h +++ b/examples/fabric-admin/device_manager/DeviceManager.h @@ -20,10 +20,10 @@ #include #include +#include #include #include #include - #include constexpr uint32_t kDefaultSetupPinCode = 20202021; @@ -63,7 +63,7 @@ class DeviceManager : public PairingDelegate void UpdateLastUsedNodeId(chip::NodeId nodeId); - void SetRemoteBridgeNodeId(chip::NodeId nodeId) { mRemoteBridgeNodeId = nodeId; } + void SetRemoteBridgeNodeId(chip::NodeId nodeId); void SetLocalBridgePort(uint16_t port) { mLocalBridgePort = port; } void SetLocalBridgeSetupPinCode(uint32_t pinCode) { mLocalBridgeSetupPinCode = pinCode; } @@ -208,6 +208,7 @@ class DeviceManager : public PairingDelegate uint64_t mRequestId = 0; BridgeSubscription mBridgeSubscriber; + CommissionerControl mCommissionerControl; FabricSyncGetter mFabricSyncGetter; }; From 3a6c54500b1cf9ef38b5e304c78399c933903d82 Mon Sep 17 00:00:00 2001 From: yunhanw-google Date: Thu, 17 Oct 2024 15:47:13 -0700 Subject: [PATCH 032/149] [ICD] Add logs to improve debuggability for storeEntry/removeEntry/removeAllEntries (#36053) * [ICD] Add log for storeEntry/removeEntry/removeAllEntires * Restyled by clang-format --------- Co-authored-by: Restyled.io --- src/app/icd/client/DefaultICDClientStorage.cpp | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/app/icd/client/DefaultICDClientStorage.cpp b/src/app/icd/client/DefaultICDClientStorage.cpp index 0c6a0f7e134bb4..c50bb621a2dc3a 100644 --- a/src/app/icd/client/DefaultICDClientStorage.cpp +++ b/src/app/icd/client/DefaultICDClientStorage.cpp @@ -394,7 +394,12 @@ CHIP_ERROR DefaultICDClientStorage::StoreEntry(const ICDClientInfo & clientInfo) DefaultStorageKeyAllocator::ICDClientInfoKey(clientInfo.peer_node.GetFabricIndex()).KeyName(), backingBuffer.Get(), static_cast(len))); - return IncreaseEntryCountForFabric(clientInfo.peer_node.GetFabricIndex()); + ReturnErrorOnFailure(IncreaseEntryCountForFabric(clientInfo.peer_node.GetFabricIndex())); + ChipLogProgress(ICD, + "Store ICD entry successfully with peer nodeId " ChipLogFormatScopedNodeId + " and checkin nodeId " ChipLogFormatScopedNodeId, + ChipLogValueScopedNodeId(clientInfo.peer_node), ChipLogValueScopedNodeId(clientInfo.check_in_node)); + return CHIP_NO_ERROR; } CHIP_ERROR DefaultICDClientStorage::IncreaseEntryCountForFabric(FabricIndex fabricIndex) @@ -475,7 +480,10 @@ CHIP_ERROR DefaultICDClientStorage::DeleteEntry(const ScopedNodeId & peerNode) mpClientInfoStore->SyncSetKeyValue(DefaultStorageKeyAllocator::ICDClientInfoKey(peerNode.GetFabricIndex()).KeyName(), backingBuffer.Get(), static_cast(len))); - return DecreaseEntryCountForFabric(peerNode.GetFabricIndex()); + ReturnErrorOnFailure(DecreaseEntryCountForFabric(peerNode.GetFabricIndex())); + ChipLogProgress(ICD, "Remove ICD entry successfully with peer nodeId " ChipLogFormatScopedNodeId, + ChipLogValueScopedNodeId(peerNode)); + return CHIP_NO_ERROR; } CHIP_ERROR DefaultICDClientStorage::DeleteAllEntries(FabricIndex fabricIndex) @@ -508,7 +516,10 @@ CHIP_ERROR DefaultICDClientStorage::DeleteAllEntries(FabricIndex fabricIndex) { return mpClientInfoStore->SyncDeleteKeyValue(DefaultStorageKeyAllocator::ICDFabricList().KeyName()); } - return StoreFabricList(); + + ReturnErrorOnFailure(StoreFabricList()); + ChipLogProgress(ICD, "Remove all ICD entries successfully for fabric index %u", fabricIndex); + return CHIP_NO_ERROR; } CHIP_ERROR DefaultICDClientStorage::ProcessCheckInPayload(const ByteSpan & payload, ICDClientInfo & clientInfo, From 915fb2c2e37db143e3f5e62e59e94a008c0ffdbd Mon Sep 17 00:00:00 2001 From: Jeff Tung <100387939+jtung-apple@users.noreply.github.com> Date: Thu, 17 Oct 2024 18:13:21 -0700 Subject: [PATCH 033/149] [Darwin] Some MTRDevice mtr_strongify sites need to guard against nil self (#36131) * [Darwin] Some MTRDevice mtr_strongify sites need to guard against nil self * Took ksperling-apple's suggestion to use VerifyOrReturn instead for cleaner code --- .../Framework/CHIP/MTRDevice_Concrete.mm | 26 +++++++++++++------ 1 file changed, 18 insertions(+), 8 deletions(-) diff --git a/src/darwin/Framework/CHIP/MTRDevice_Concrete.mm b/src/darwin/Framework/CHIP/MTRDevice_Concrete.mm index 68b610cb25c7d7..2342cadfb253f5 100644 --- a/src/darwin/Framework/CHIP/MTRDevice_Concrete.mm +++ b/src/darwin/Framework/CHIP/MTRDevice_Concrete.mm @@ -389,6 +389,8 @@ - (instancetype)initWithNodeID:(NSNumber *)nodeID controller:(MTRDeviceControlle mtr_weakify(self); _systemTimeChangeObserverToken = [[NSNotificationCenter defaultCenter] addObserverForName:NSSystemClockDidChangeNotification object:nil queue:nil usingBlock:^(NSNotification * _Nonnull notification) { mtr_strongify(self); + VerifyOrReturn(self); + std::lock_guard lock(self->_lock); [self _resetStorageBehaviorState]; }]; @@ -760,6 +762,8 @@ - (void)_ensureSubscriptionForExistingDelegates:(NSString *)reason mtr_weakify(self); [self _scheduleSubscriptionPoolWork:^{ mtr_strongify(self); + VerifyOrReturn(self); + [self->_deviceController asyncDispatchToMatterQueue:^{ std::lock_guard lock(self->_lock); [self _setupSubscriptionWithReason:[NSString stringWithFormat:@"%@ and scheduled subscription is happening", reason]]; @@ -1168,16 +1172,16 @@ - (void)_scheduleSubscriptionPoolWork:(dispatch_block_t)workBlock inNanoseconds: mtr_weakify(self); dispatch_block_t workBlockToQueue = ^{ mtr_strongify(self); - if (nil == self) { - // This block may be delayed by a specified number of nanoseconds, potentially running after the device is deallocated. - // If so, MTRAsyncWorkItem::initWithQueue will assert on a nil queue, which will cause a crash. - return; - } + // This block may be delayed by a specified number of nanoseconds, potentially running after the device is deallocated. + // If so, MTRAsyncWorkItem::initWithQueue will assert on a nil queue, which will cause a crash. + VerifyOrReturn(self); // In the case where a resubscription triggering event happened and already established, running the work block should result in a no-op MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:self.queue]; [workItem setReadyHandler:^(id _Nonnull context, NSInteger retryCount, MTRAsyncWorkCompletionBlock _Nonnull completion) { mtr_strongify(self); + VerifyOrReturn(self); + MTR_LOG("%@ - work item is ready to attempt pooled subscription", self); os_unfair_lock_lock(&self->_lock); #ifdef DEBUG @@ -1257,6 +1261,8 @@ - (void)_handleResubscriptionNeededWithDelayOnDeviceQueue:(NSNumber *)resubscrip mtr_weakify(self); auto resubscriptionBlock = ^{ mtr_strongify(self); + VerifyOrReturn(self); + [self->_deviceController asyncDispatchToMatterQueue:^{ [self _triggerResubscribeWithReason:@"ResubscriptionNeeded timer fired" nodeLikelyReachable:NO]; } errorHandler:^(NSError * _Nonnull error) { @@ -1369,6 +1375,8 @@ - (void)_doHandleSubscriptionReset:(NSNumber * _Nullable)retryDelay mtr_weakify(self); auto resubscriptionBlock = ^{ mtr_strongify(self); + VerifyOrReturn(self); + [self->_deviceController asyncDispatchToMatterQueue:^{ std::lock_guard lock(self->_lock); [self _reattemptSubscriptionNowIfNeededWithReason:@"got subscription reset"]; @@ -2386,9 +2394,9 @@ - (void)_setupSubscriptionWithReason:(NSString *)reason mtr_weakify(self); dispatch_after(dispatch_time(DISPATCH_TIME_NOW, static_cast(kSecondsToWaitBeforeMarkingUnreachableAfterSettingUpSubscription) * static_cast(NSEC_PER_SEC)), self.queue, ^{ mtr_strongify(self); - if (self != nil) { - [self _markDeviceAsUnreachableIfNeverSubscribed]; - } + VerifyOrReturn(self); + + [self _markDeviceAsUnreachableIfNeverSubscribed]; }); } @@ -3242,6 +3250,8 @@ - (void)_checkExpiredExpectedValues mtr_weakify(self); dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t) (waitTime * NSEC_PER_SEC)), self.queue, ^{ mtr_strongify(self); + VerifyOrReturn(self); + [self _performScheduledExpirationCheck]; }); } From 76e9e14a19674edd1932bcf5577d623ac21b065d Mon Sep 17 00:00:00 2001 From: Vivien Nicolas Date: Fri, 18 Oct 2024 04:16:19 +0200 Subject: [PATCH 034/149] [Logging] Log the duration for successfully establishing a subscription (#36115) --- src/app/ReadClient.cpp | 12 ++++++++++-- src/app/ReadClient.h | 6 ++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/app/ReadClient.cpp b/src/app/ReadClient.cpp index 1e9c7e727f409c..2d609eb1afa05a 100644 --- a/src/app/ReadClient.cpp +++ b/src/app/ReadClient.cpp @@ -1081,10 +1081,14 @@ CHIP_ERROR ReadClient::ProcessSubscribeResponse(System::PacketBufferHandle && aP VerifyOrReturnError(IsMatchingSubscriptionId(subscriptionId), CHIP_ERROR_INVALID_SUBSCRIPTION); ReturnErrorOnFailure(subscribeResponse.GetMaxInterval(&mMaxInterval)); +#if CHIP_PROGRESS_LOGGING + auto duration = System::Clock::Milliseconds32(System::SystemClock().GetMonotonicTimestamp() - mSubscribeRequestTime); +#endif ChipLogProgress(DataManagement, - "Subscription established with SubscriptionID = 0x%08" PRIx32 " MinInterval = %u" + "Subscription established in %" PRIu32 "ms with SubscriptionID = 0x%08" PRIx32 " MinInterval = %u" "s MaxInterval = %us Peer = %02x:" ChipLogFormatX64, - mSubscriptionId, mMinIntervalFloorSeconds, mMaxInterval, GetFabricIndex(), ChipLogValueX64(GetPeerNodeId())); + duration.count(), mSubscriptionId, mMinIntervalFloorSeconds, mMaxInterval, GetFabricIndex(), + ChipLogValueX64(GetPeerNodeId())); ReturnErrorOnFailure(subscribeResponse.ExitContainer()); @@ -1144,6 +1148,10 @@ CHIP_ERROR ReadClient::SendSubscribeRequestImpl(const ReadPrepareParams & aReadP { MATTER_LOG_METRIC_BEGIN(Tracing::kMetricDeviceSubscriptionSetup); +#if CHIP_PROGRESS_LOGGING + mSubscribeRequestTime = System::SystemClock().GetMonotonicTimestamp(); +#endif + VerifyOrReturnError(ClientState::Idle == mState, CHIP_ERROR_INCORRECT_STATE); if (&aReadPrepareParams != &mReadPrepareParams) diff --git a/src/app/ReadClient.h b/src/app/ReadClient.h index fd27f0afc9e959..d8b8a971db8c28 100644 --- a/src/app/ReadClient.h +++ b/src/app/ReadClient.h @@ -676,6 +676,12 @@ class ReadClient : public Messaging::ExchangeDelegate // of RequestMessage (another end of container)). static constexpr uint16_t kReservedSizeForTLVEncodingOverhead = kReservedSizeForEndOfContainer + kReservedSizeForIMRevision + kReservedSizeForEndOfContainer; + +#if CHIP_PROGRESS_LOGGING + // Tracks the time when a subscribe request is successfully sent. + // This timestamp allows for logging the duration taken to established the subscription. + System::Clock::Timestamp mSubscribeRequestTime = System::Clock::kZero; +#endif }; }; // namespace app From 2574847dad7c1042e649241c3c39dd48a5d5f5b5 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Fri, 18 Oct 2024 02:49:27 -0400 Subject: [PATCH 035/149] Remove various un-necessary code from MTRDevice. (#36132) * Remove various un-necessary code from MTRDevice. The _deviceInternalStateChanged declaration was duplicated in MTRDevice_Concrete and only needed there. MTRDeviceClusterData implementation can move into its own file. setPersistedClusterData: is only used on MTRDevice_Concrete instances, so its declaration can move to MTRDevice_Concrete and the unused implementation in MTRDevice can be removed. setPersistedDeviceData: is only used on MTRDevice_Concrete instances, so its declaration can move to MTRDevice_Concrete and the unused implementation in MTRDevice can be removed. Now _setLastInitialSubscribeLatency and _updateAttributeDependentDescriptionData on MTRDevice are unused and can be removed. At this point, _informationalVendorID, _informationalProductID, _networkFeatures, _vid, _pid, _allNetworkFeatures, and _descriptionLock are all unused on MTRDevice and can be removed. Now _informationalNumberAtAttributePath is unused on MTRDevice and can be removed. _endpointList is also unused on MTRDevice and can be removed. deviceCachePrimed is implemented by both MTRDevice_XPC and MTRDevice_Concrete, so the implementation on MTRDevice can be removed. unitTestGetClusterDataForPath, unitTestGetPersistedClusters, unitTestClusterHasBeenPersisted, unitTestResetSubscription, unitTestAttributesReportedSinceLastCheck, unitTestClearClusterData, unitTestInjectEventReport, unitTestInjectAttributeReport, and unitTestAttributeCount are only used on MTRDevice_Concrete, so the duplicate implementations on MTRDevice can be removed. At this point, _cachedAttributeValueForPath is unused on MTRDevice and can be removed. Now _getCachedDataVersions is unused on MTRDevice and can be removed. deviceUsesThread is only used by MTRDeviceController_Concrete on MTRDevice_Concrete instances and so can move to MTRDevice_Concrete entirely. Then _deviceUsesThread becomes unused on MTRDevice and can be removed. Then _clusterDataForPath is unused on MTRDevice and can be removed. Now _reconcilePersistedClustersWithStorage is unused on MTRDevice and can be removed. Also, _knownClusters is unused on MTRDevice and can be removed. setStorageBehaviorConfiguration is only used from MTRDeviceController_Concrete (which has an MTRDevice_Concrete) and from unit tests (which have an MTRDevice_Concrete, though they don't know it), so it can be removed from MTRDevice. Then _resetStorageBehaviorState also becomes unused and can be removed. At this point, _scheduleClusterDataPersistence is not used on MTRDevice and can be removed. This makes _persistClusterDataAsNeeded and _deviceCachePrimed unused, and they can also be removed. At this point, _persistClusterData, _deviceIsReportingExcessively, _reportToPersistenceDelayTimeAfterMutiplier, _reportToPersistenceDelayTimeMaxAfterMutiplier, _mostRecentReportTimes, and _clusterDataPersistenceFirstScheduledTime are not used on MTRDevice and can be removed. Now _dataStoreExists, _clusterDataToPersistSnapshot, _storageBehaviorConfiguration, _reportToPersistenceDelayCurrentMultiplier, _deviceReportingExcessivelyStartTime, and _persistedClusters are unused on MTRDevice and can be removed. At this point _clusterDataToPersist and _persistedClusterData are unused on MTRDevice and can be removed. _systemTimeChangeObserverToken was never actually used on MTRDevice (it's only used on MTRDevice_Concrete) and can be removed. The MTRDeviceAttributeReportHandler typedef is unused on MTRDevice and can be removed. kSecondsToWaitBeforeMarkingUnreachableAfterSettingUpSubscription and ENABLE_CONNECTIVITY_MONITORING are unused on MTRDevice and can be removed. assertChipStackLockedByCurrentThread is not used in MTRDevice, so the LockTracker.h include can be removed. MTRAsyncWorkQueue, MTRAttributeIsSpecified, MTRCommandNeedsTimedInvoke, MTRDeviceConnectivityMonitor, MTRDeviceControllerOverXPC, MTRDecodeEventPayload, are all unused in MTRDevice, so the imports of the corresponding headers can be removed. arrayOfNumbersFromAttributeValue is now unused on MTRDevice and can be removed. The fabricIndex property is write-only on both MTRDevice and MTRDevice_Concrete and can be removed on both. _dataValueWithoutDataVersion is unused on MTRDevice and can be removed. * Move MTRDeviceClusterData into a separate header/implementation file. --- src/darwin/Framework/CHIP/MTRDevice.mm | 871 +----------------- .../Framework/CHIP/MTRDeviceClusterData.h | 38 + .../Framework/CHIP/MTRDeviceClusterData.mm | 122 +++ .../CHIP/MTRDeviceControllerDataStore.h | 4 +- .../CHIP/MTRDeviceController_Concrete.mm | 25 +- .../CHIP/MTRDeviceController_Internal.h | 1 + .../CHIP/MTRDeviceDataValueDictionary.h | 23 + .../Framework/CHIP/MTRDevice_Concrete.h | 18 + .../Framework/CHIP/MTRDevice_Concrete.mm | 5 +- .../Framework/CHIP/MTRDevice_Internal.h | 37 - src/darwin/Framework/CHIP/MTRDevice_XPC.mm | 1 + .../Framework/CHIPTests/MTRDeviceTests.m | 1 + .../CHIPTests/MTRPerControllerStorageTests.m | 2 + .../TestHelpers/MTRTestDeclarations.h | 6 +- .../Matter.xcodeproj/project.pbxproj | 12 + 15 files changed, 261 insertions(+), 905 deletions(-) create mode 100644 src/darwin/Framework/CHIP/MTRDeviceClusterData.h create mode 100644 src/darwin/Framework/CHIP/MTRDeviceClusterData.mm create mode 100644 src/darwin/Framework/CHIP/MTRDeviceDataValueDictionary.h diff --git a/src/darwin/Framework/CHIP/MTRDevice.mm b/src/darwin/Framework/CHIP/MTRDevice.mm index a584bd68e06f9f..0bfdf44efb0d9a 100644 --- a/src/darwin/Framework/CHIP/MTRDevice.mm +++ b/src/darwin/Framework/CHIP/MTRDevice.mm @@ -18,21 +18,16 @@ #import #import -#import "MTRAsyncWorkQueue.h" -#import "MTRAttributeSpecifiedCheck.h" #import "MTRBaseClusters.h" #import "MTRBaseDevice_Internal.h" #import "MTRCluster.h" #import "MTRClusterConstants.h" -#import "MTRCommandTimedCheck.h" #import "MTRConversion.h" #import "MTRDefines_Internal.h" -#import "MTRDeviceConnectivityMonitor.h" -#import "MTRDeviceControllerOverXPC.h" #import "MTRDeviceController_Internal.h" +#import "MTRDeviceDataValueDictionary.h" #import "MTRDevice_Internal.h" #import "MTRError_Internal.h" -#import "MTREventTLVValueDecoder_Internal.h" #import "MTRLogging_Internal.h" #import "MTRMetricKeys.h" #import "MTRMetricsCollector.h" @@ -43,18 +38,11 @@ #import "lib/core/CHIPError.h" -#import - -typedef void (^MTRDeviceAttributeReportHandler)(NSArray * _Nonnull); - +// TODO Should these string definitions just move to MTRDevice_Concrete, since +// that's the only place they are used? NSString * const MTRPreviousDataKey = @"previousData"; NSString * const MTRDataVersionKey = @"dataVersion"; -#define kSecondsToWaitBeforeMarkingUnreachableAfterSettingUpSubscription 10 - -// Disabling pending crashes -#define ENABLE_CONNECTIVITY_MONITORING 0 - @implementation MTRDeviceDelegateInfo - (instancetype)initWithDelegate:(id)delegate queue:(dispatch_queue_t)queue interestedPathsForAttributes:(NSArray * _Nullable)interestedPathsForAttributes interestedPathsForEvents:(NSArray * _Nullable)interestedPathsForEvents { @@ -96,127 +84,8 @@ - (BOOL)callDelegateSynchronouslyWithBlock:(void (^)(id))bloc #endif @end -/* BEGIN DRAGONS: Note methods here cannot be renamed, and are used by private callers, do not rename, remove or modify behavior here */ - -@interface NSObject (MatterPrivateForInternalDragonsDoNotFeed) -- (void)_deviceInternalStateChanged:(MTRDevice *)device; -@end - -/* END DRAGONS */ - -using namespace chip; -using namespace chip::app; -using namespace chip::Protocols::InteractionModel; -using namespace chip::Tracing::DarwinFramework; - #pragma mark - MTRDevice -@implementation MTRDeviceClusterData { - NSMutableDictionary * _attributes; -} - -- (void)storeValue:(MTRDeviceDataValueDictionary _Nullable)value forAttribute:(NSNumber *)attribute -{ - _attributes[attribute] = value; -} - -- (void)removeValueForAttribute:(NSNumber *)attribute -{ - [_attributes removeObjectForKey:attribute]; -} - -- (NSDictionary *)attributes -{ - return _attributes; -} - -+ (BOOL)supportsSecureCoding -{ - return YES; -} - -- (NSString *)description -{ - return [NSString stringWithFormat:@"", _dataVersion, static_cast(_attributes.count)]; -} - -- (nullable instancetype)init -{ - return [self initWithDataVersion:nil attributes:nil]; -} - -// Attributes dictionary is: attributeID => data-value dictionary -- (nullable instancetype)initWithDataVersion:(NSNumber * _Nullable)dataVersion attributes:(NSDictionary * _Nullable)attributes -{ - self = [super init]; - if (self == nil) { - return nil; - } - - _dataVersion = [dataVersion copy]; - _attributes = [NSMutableDictionary dictionaryWithCapacity:attributes.count]; - [_attributes addEntriesFromDictionary:attributes]; - - return self; -} - -- (nullable instancetype)initWithCoder:(NSCoder *)decoder -{ - self = [super init]; - if (self == nil) { - return nil; - } - - _dataVersion = [decoder decodeObjectOfClass:[NSNumber class] forKey:sDataVersionKey]; - if (_dataVersion != nil && ![_dataVersion isKindOfClass:[NSNumber class]]) { - MTR_LOG_ERROR("MTRDeviceClusterData got %@ for data version, not NSNumber.", _dataVersion); - return nil; - } - - static NSSet * const sAttributeValueClasses = [NSSet setWithObjects:[NSDictionary class], [NSArray class], [NSData class], [NSString class], [NSNumber class], nil]; - _attributes = [decoder decodeObjectOfClasses:sAttributeValueClasses forKey:sAttributesKey]; - if (_attributes != nil && ![_attributes isKindOfClass:[NSDictionary class]]) { - MTR_LOG_ERROR("MTRDeviceClusterData got %@ for attributes, not NSDictionary.", _attributes); - return nil; - } - - return self; -} - -- (void)encodeWithCoder:(NSCoder *)coder -{ - [coder encodeObject:self.dataVersion forKey:sDataVersionKey]; - [coder encodeObject:self.attributes forKey:sAttributesKey]; -} - -- (id)copyWithZone:(NSZone *)zone -{ - return [[MTRDeviceClusterData alloc] initWithDataVersion:_dataVersion attributes:_attributes]; -} - -- (BOOL)isEqualToClusterData:(MTRDeviceClusterData *)otherClusterData -{ - return MTREqualObjects(_dataVersion, otherClusterData.dataVersion) - && MTREqualObjects(_attributes, otherClusterData.attributes); -} - -- (BOOL)isEqual:(id)object -{ - if ([object class] != [self class]) { - return NO; - } - - return [self isEqualToClusterData:object]; -} - -@end - -@interface MTRDevice () - -@property (nonatomic) chip::FabricIndex fabricIndex; - -@end - // Declaring selector so compiler won't complain about testing and calling it in _handleReportEnd #ifdef DEBUG @protocol MTRDeviceUnitTestDelegate @@ -233,54 +102,7 @@ - (BOOL)unitTestSuppressTimeBasedReachabilityChanges:(MTRDevice *)device; @end #endif -@implementation MTRDevice { - // _deviceCachePrimed is true if we have the data that comes from an initial - // subscription priming report (whether it came from storage or from our - // subscription). - BOOL _deviceCachePrimed; - - // _persistedClusterData stores data that we have already persisted (when we have - // cluster data persistence enabled). Nil when we have no persistence enabled. - NSCache * _Nullable _persistedClusterData; - // _clusterDataToPersist stores data that needs to be persisted. If we - // don't have persistence enabled, this is our only data store. Nil if we - // currently have nothing that could need persisting. - NSMutableDictionary * _Nullable _clusterDataToPersist; - // _persistedClusters stores the set of "valid" keys into _persistedClusterData. - // These are keys that could have values in _persistedClusterData even if they don't - // right now (because they have been evicted). - NSMutableSet * _persistedClusters; - - // Storage behavior configuration and variables to keep track of the logic - // _clusterDataPersistenceFirstScheduledTime is used to track the start time of the delay between - // report and persistence. - // _mostRecentReportTimes is a list of the most recent report timestamps used for calculating - // the running average time between reports. - // _deviceReportingExcessivelyStartTime tracks when a device starts reporting excessively. - // _reportToPersistenceDelayCurrentMultiplier is the current multiplier that is calculated when a - // report comes in. - MTRDeviceStorageBehaviorConfiguration * _storageBehaviorConfiguration; - NSDate * _Nullable _clusterDataPersistenceFirstScheduledTime; - NSMutableArray * _mostRecentReportTimes; - NSDate * _Nullable _deviceReportingExcessivelyStartTime; - double _reportToPersistenceDelayCurrentMultiplier; - - // System time change observer reference - id _systemTimeChangeObserverToken; - - // Protects mutable state used by our description getter. This is a separate lock from "lock" - // so that we don't need to worry about getting our description while holding "lock" (e.g due to - // logging self). This lock _must_ be held narrowly, with no other lock acquisitions allowed - // while it's held, to avoid deadlock. - os_unfair_lock _descriptionLock; - - // State used by our description getter: access to these must be protected by descriptionLock. - NSNumber * _Nullable _vid; // nil if unknown - NSNumber * _Nullable _pid; // nil if unknown - // _allNetworkFeatures is a bitwise or of the feature maps of all network commissioning clusters - // present on the device, or nil if there aren't any. - NSNumber * _Nullable _allNetworkFeatures; -} +@implementation MTRDevice - (instancetype)initForSubclassesWithNodeID:(NSNumber *)nodeID controller:(MTRDeviceController *)controller { @@ -306,8 +128,6 @@ - (instancetype)initWithNodeID:(NSNumber *)nodeID controller:(MTRDeviceControlle - (void)dealloc { - [[NSNotificationCenter defaultCenter] removeObserver:_systemTimeChangeObserverToken]; - // TODO: retain cycle and clean up https://github.com/project-chip/connectedhomeip/issues/34267 MTR_LOG("MTRDevice dealloc: %p", self); } @@ -328,42 +148,6 @@ + (MTRDevice *)deviceWithNodeID:(NSNumber *)nodeID controller:(MTRDeviceControll return [controller deviceForNodeID:nodeID]; } -- (NSMutableArray *)arrayOfNumbersFromAttributeValue:(MTRDeviceDataValueDictionary)dataDictionary -{ - if (![MTRArrayValueType isEqual:dataDictionary[MTRTypeKey]]) { - return nil; - } - - id value = dataDictionary[MTRValueKey]; - if (![value isKindOfClass:NSArray.class]) { - return nil; - } - - NSArray * valueArray = value; - __auto_type outputArray = [NSMutableArray arrayWithCapacity:valueArray.count]; - - for (id item in valueArray) { - if (![item isKindOfClass:NSDictionary.class]) { - return nil; - } - - NSDictionary * itemDictionary = item; - id data = itemDictionary[MTRDataKey]; - if (![data isKindOfClass:NSDictionary.class]) { - return nil; - } - - NSDictionary * dataDictionary = data; - id dataType = dataDictionary[MTRTypeKey]; - id dataValue = dataDictionary[MTRValueKey]; - if (![dataType isKindOfClass:NSString.class] || ![dataValue isKindOfClass:NSNumber.class]) { - return nil; - } - [outputArray addObject:dataValue]; - } - return outputArray; -} - #pragma mark Delegate handling - (void)setDelegate:(id)delegate queue:(dispatch_queue_t)queue @@ -529,449 +313,7 @@ - (void)_callFirstDelegateSynchronouslyWithBlock:(void (^)(id } #endif -- (BOOL)deviceUsesThread -{ - std::lock_guard lock(_lock); - return [self _deviceUsesThread]; -} - -// This method is used for signaling whether to use the subscription pool. This functions as -// a heuristic for whether to throttle subscriptions to the device via a pool of subscriptions. -// If products appear that have both Thread and Wifi enabled but are primarily on wifi, this -// method will need to be updated to reflect that. -- (BOOL)_deviceUsesThread -{ - os_unfair_lock_assert_owner(&self->_lock); - #ifdef DEBUG - // Note: This is a hack to allow our unit tests to test the subscription pooling behavior we have implemented for thread, so we mock devices to be a thread device - __block BOOL pretendThreadEnabled = NO; - [self _callFirstDelegateSynchronouslyWithBlock:^(id testDelegate) { - if ([testDelegate respondsToSelector:@selector(unitTestPretendThreadEnabled:)]) { - pretendThreadEnabled = [testDelegate unitTestPretendThreadEnabled:self]; - } - }]; - if (pretendThreadEnabled) { - return YES; - } -#endif - - MTRClusterPath * networkCommissioningClusterPath = [MTRClusterPath clusterPathWithEndpointID:@(kRootEndpointId) clusterID:@(MTRClusterIDTypeNetworkCommissioningID)]; - MTRDeviceClusterData * networkCommissioningClusterData = [self _clusterDataForPath:networkCommissioningClusterPath]; - NSNumber * networkCommissioningClusterFeatureMapValueNumber = networkCommissioningClusterData.attributes[@(MTRClusterGlobalAttributeFeatureMapID)][MTRValueKey]; - - if (networkCommissioningClusterFeatureMapValueNumber == nil) - return NO; - if (![networkCommissioningClusterFeatureMapValueNumber isKindOfClass:[NSNumber class]]) { - MTR_LOG_ERROR("%@ Unexpected NetworkCommissioning FeatureMap value %@", self, networkCommissioningClusterFeatureMapValueNumber); - return NO; - } - - uint32_t networkCommissioningClusterFeatureMapValue = static_cast(networkCommissioningClusterFeatureMapValueNumber.unsignedLongValue); - - return (networkCommissioningClusterFeatureMapValue & MTRNetworkCommissioningFeatureThreadNetworkInterface) != 0 ? YES : NO; -} - -- (NSDictionary *)_clusterDataToPersistSnapshot -{ - os_unfair_lock_assert_owner(&self->_lock); - NSMutableDictionary * clusterDataToReturn = [NSMutableDictionary dictionary]; - for (MTRClusterPath * clusterPath in _clusterDataToPersist) { - clusterDataToReturn[clusterPath] = [_clusterDataToPersist[clusterPath] copy]; - } - - return clusterDataToReturn; -} - -- (NSTimeInterval)_reportToPersistenceDelayTimeAfterMutiplier -{ - return _storageBehaviorConfiguration.reportToPersistenceDelayTime * _reportToPersistenceDelayCurrentMultiplier; -} - -- (NSTimeInterval)_reportToPersistenceDelayTimeMaxAfterMutiplier -{ - return _storageBehaviorConfiguration.reportToPersistenceDelayTimeMax * _reportToPersistenceDelayCurrentMultiplier; -} - -- (BOOL)_dataStoreExists -{ - os_unfair_lock_assert_owner(&self->_lock); - return _persistedClusterData != nil; -} - -- (void)_persistClusterData -{ - os_unfair_lock_assert_owner(&self->_lock); - - // Sanity check - if (![self _dataStoreExists]) { - MTR_LOG_ERROR("%@ storage behavior: no data store in _persistClusterData!", self); - return; - } - - // Nothing to persist - if (!_clusterDataToPersist.count) { - return; - } - - MTR_LOG("%@ Storing cluster information (data version and attributes) count: %lu", self, static_cast(_clusterDataToPersist.count)); - // We're going to hand out these MTRDeviceClusterData objects to our - // storage implementation, which will try to read them later. Make sure - // we snapshot the state here instead of handing out live copies. - NSDictionary * clusterData = [self _clusterDataToPersistSnapshot]; - [_deviceController.controllerDataStore storeClusterData:clusterData forNodeID:_nodeID]; - for (MTRClusterPath * clusterPath in _clusterDataToPersist) { - [_persistedClusterData setObject:_clusterDataToPersist[clusterPath] forKey:clusterPath]; - [_persistedClusters addObject:clusterPath]; - } - - // TODO: There is one edge case not handled well here: if the - // storeClusterData call above fails somehow, and then the data gets - // evicted from _persistedClusterData, we could end up in a situation - // where when we page things in from storage we have stale values and - // hence effectively lose the delta that we failed to persist. - // - // The only way to handle this would be to detect it when it happens, - // then re-subscribe at that point, which would cause the relevant data - // to be sent to us via the priming read. - _clusterDataToPersist = nil; - -#ifdef DEBUG - [self _callDelegatesWithBlock:^(id testDelegate) { - if ([testDelegate respondsToSelector:@selector(unitTestClusterDataPersisted:)]) { - [testDelegate unitTestClusterDataPersisted:self]; - } - }]; -#endif -} - -- (BOOL)_deviceIsReportingExcessively -{ - os_unfair_lock_assert_owner(&self->_lock); - - if (!_deviceReportingExcessivelyStartTime) { - return NO; - } - - NSTimeInterval intervalSinceDeviceReportingExcessively = -[_deviceReportingExcessivelyStartTime timeIntervalSinceNow]; - BOOL deviceIsReportingExcessively = intervalSinceDeviceReportingExcessively > _storageBehaviorConfiguration.deviceReportingExcessivelyIntervalThreshold; - if (deviceIsReportingExcessively) { - MTR_LOG("%@ storage behavior: device has been reporting excessively for %.3lf seconds", self, intervalSinceDeviceReportingExcessively); - } - return deviceIsReportingExcessively; -} - -- (void)_persistClusterDataAsNeeded -{ - std::lock_guard lock(_lock); - - // Nothing to persist - if (!_clusterDataToPersist.count) { - return; - } - - // This is run with a dispatch_after, and need to check again if this device is reporting excessively - if ([self _deviceIsReportingExcessively]) { - return; - } - - NSDate * lastReportTime = [_mostRecentReportTimes lastObject]; - NSTimeInterval intervalSinceLastReport = -[lastReportTime timeIntervalSinceNow]; - if (intervalSinceLastReport < [self _reportToPersistenceDelayTimeAfterMutiplier]) { - // A report came in after this call was scheduled - - if (!_clusterDataPersistenceFirstScheduledTime) { - MTR_LOG_ERROR("%@ storage behavior: expects _clusterDataPersistenceFirstScheduledTime if _clusterDataToPersist exists", self); - return; - } - - NSTimeInterval intervalSinceFirstScheduledPersistence = -[_clusterDataPersistenceFirstScheduledTime timeIntervalSinceNow]; - if (intervalSinceFirstScheduledPersistence < [self _reportToPersistenceDelayTimeMaxAfterMutiplier]) { - MTR_LOG("%@ storage behavior: not persisting: intervalSinceLastReport %lf intervalSinceFirstScheduledPersistence %lf", self, intervalSinceLastReport, intervalSinceFirstScheduledPersistence); - // The max delay is also not reached - do not persist yet - return; - } - } - - // At this point, there is data to persist, and either _reportToPersistenceDelayTime was - // reached, or _reportToPersistenceDelayTimeMax was reached. Time to persist: - [self _persistClusterData]; - - _clusterDataPersistenceFirstScheduledTime = nil; -} - -- (void)_scheduleClusterDataPersistence -{ - os_unfair_lock_assert_owner(&self->_lock); - - // No persisted data / lack of controller data store - if (![self _dataStoreExists]) { - MTR_LOG_DEBUG("%@ storage behavior: no data store", self); - return; - } - - // Nothing to persist - if (!_clusterDataToPersist.count) { - MTR_LOG_DEBUG("%@ storage behavior: nothing to persist", self); - return; - } - - // If there is no storage behavior configuration, make a default one - if (!_storageBehaviorConfiguration) { - _storageBehaviorConfiguration = [[MTRDeviceStorageBehaviorConfiguration alloc] init]; - [_storageBehaviorConfiguration checkValuesAndResetToDefaultIfNecessary]; - } - - // Directly store if the storage behavior optimization is disabled - if (_storageBehaviorConfiguration.disableStorageBehaviorOptimization) { - [self _persistClusterData]; - return; - } - - // If we have nothing stored at all yet, store directly, so we move into a - // primed state. - if (!_deviceCachePrimed) { - [self _persistClusterData]; - return; - } - - // Ensure there is an array to keep the most recent report times - if (!_mostRecentReportTimes) { - _mostRecentReportTimes = [NSMutableArray array]; - } - - // Mark when first report comes in to know when _reportToPersistenceDelayTimeMax is hit - if (!_clusterDataPersistenceFirstScheduledTime) { - _clusterDataPersistenceFirstScheduledTime = [NSDate now]; - } - - // Make sure there is space in the array, and note report time - while (_mostRecentReportTimes.count >= _storageBehaviorConfiguration.recentReportTimesMaxCount) { - [_mostRecentReportTimes removeObjectAtIndex:0]; - } - [_mostRecentReportTimes addObject:[NSDate now]]; - - // Calculate running average and update multiplier - need at least 2 items to calculate intervals - if (_mostRecentReportTimes.count > 2) { - NSTimeInterval cumulativeIntervals = 0; - for (int i = 1; i < _mostRecentReportTimes.count; i++) { - NSDate * lastDate = [_mostRecentReportTimes objectAtIndex:i - 1]; - NSDate * currentDate = [_mostRecentReportTimes objectAtIndex:i]; - NSTimeInterval intervalSinceLastReport = [currentDate timeIntervalSinceDate:lastDate]; - // Check to guard against clock change - if (intervalSinceLastReport > 0) { - cumulativeIntervals += intervalSinceLastReport; - } - } - NSTimeInterval averageTimeBetweenReports = cumulativeIntervals / (_mostRecentReportTimes.count - 1); - - if (averageTimeBetweenReports < _storageBehaviorConfiguration.timeBetweenReportsTooShortThreshold) { - // Multiplier goes from 1 to _reportToPersistenceDelayMaxMultiplier uniformly, as - // averageTimeBetweenReports go from timeBetweenReportsTooShortThreshold to - // timeBetweenReportsTooShortMinThreshold - - double intervalAmountBelowThreshold = _storageBehaviorConfiguration.timeBetweenReportsTooShortThreshold - averageTimeBetweenReports; - double intervalAmountBetweenThresholdAndMinThreshold = _storageBehaviorConfiguration.timeBetweenReportsTooShortThreshold - _storageBehaviorConfiguration.timeBetweenReportsTooShortMinThreshold; - double proportionTowardMinThreshold = intervalAmountBelowThreshold / intervalAmountBetweenThresholdAndMinThreshold; - if (proportionTowardMinThreshold > 1) { - // Clamp to 100% - proportionTowardMinThreshold = 1; - } - - // Set current multiplier to [1, MaxMultiplier] - _reportToPersistenceDelayCurrentMultiplier = 1 + (proportionTowardMinThreshold * (_storageBehaviorConfiguration.reportToPersistenceDelayMaxMultiplier - 1)); - MTR_LOG("%@ storage behavior: device reporting frequently - setting delay multiplier to %lf", self, _reportToPersistenceDelayCurrentMultiplier); - } else { - _reportToPersistenceDelayCurrentMultiplier = 1; - } - - // Also note when the running average first dips below the min threshold - if (averageTimeBetweenReports < _storageBehaviorConfiguration.timeBetweenReportsTooShortMinThreshold) { - if (!_deviceReportingExcessivelyStartTime) { - _deviceReportingExcessivelyStartTime = [NSDate now]; - MTR_LOG_DEBUG("%@ storage behavior: device is reporting excessively @%@", self, _deviceReportingExcessivelyStartTime); - } - } else { - _deviceReportingExcessivelyStartTime = nil; - } - } - - // Do not schedule persistence if device is reporting excessively - if ([self _deviceIsReportingExcessively]) { - return; - } - - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t) ([self _reportToPersistenceDelayTimeAfterMutiplier] * NSEC_PER_SEC)), self.queue, ^{ - [self _persistClusterDataAsNeeded]; - }); -} - -// Used to clear the storage behavior state when needed (system time change, or when new -// configuration is set. -// -// Also flushes unwritten cluster data to storage, if data store exists. -- (void)_resetStorageBehaviorState -{ - os_unfair_lock_assert_owner(&self->_lock); - - _clusterDataPersistenceFirstScheduledTime = nil; - _mostRecentReportTimes = nil; - _deviceReportingExcessivelyStartTime = nil; - _reportToPersistenceDelayCurrentMultiplier = 1; - - // Sanity check that there is a data - if ([self _dataStoreExists]) { - [self _persistClusterData]; - } -} - -- (void)setStorageBehaviorConfiguration:(MTRDeviceStorageBehaviorConfiguration *)storageBehaviorConfiguration -{ - MTR_LOG("%@ storage behavior: setStorageBehaviorConfiguration %@", self, storageBehaviorConfiguration); - std::lock_guard lock(_lock); - _storageBehaviorConfiguration = storageBehaviorConfiguration; - // Make sure the values are sane - [_storageBehaviorConfiguration checkValuesAndResetToDefaultIfNecessary]; - [self _resetStorageBehaviorState]; -} - -#ifdef DEBUG -- (void)unitTestInjectEventReport:(NSArray *> *)eventReport -{ - NSAssert(NO, @"Unit test injection of reports needs to be handled by subclasses"); -} - -- (void)unitTestInjectAttributeReport:(NSArray *> *)attributeReport fromSubscription:(BOOL)isFromSubscription -{ - NSAssert(NO, @"Unit test injection of reports needs to be handled by subclasses"); -} -#endif - -#ifdef DEBUG -- (void)unitTestClearClusterData -{ - std::lock_guard lock(_lock); - NSAssert([self _dataStoreExists], @"Test is not going to test what it thinks is testing!"); - [_persistedClusterData removeAllObjects]; -} -#endif - -- (void)_reconcilePersistedClustersWithStorage -{ - os_unfair_lock_assert_owner(&self->_lock); - - NSMutableSet * clusterPathsToRemove = [NSMutableSet set]; - for (MTRClusterPath * clusterPath in _persistedClusters) { - MTRDeviceClusterData * data = [_deviceController.controllerDataStore getStoredClusterDataForNodeID:_nodeID endpointID:clusterPath.endpoint clusterID:clusterPath.cluster]; - if (!data) { - [clusterPathsToRemove addObject:clusterPath]; - } - } - - MTR_LOG_ERROR("%@ Storage missing %lu / %lu clusters - reconciling in-memory records", self, static_cast(clusterPathsToRemove.count), static_cast(_persistedClusters.count)); - [_persistedClusters minusSet:clusterPathsToRemove]; -} - -- (nullable MTRDeviceClusterData *)_clusterDataForPath:(MTRClusterPath *)clusterPath -{ - os_unfair_lock_assert_owner(&self->_lock); - - if (_clusterDataToPersist != nil) { - // Use the "dirty" values, if we have them. - MTRDeviceClusterData * data = _clusterDataToPersist[clusterPath]; - if (data != nil) { - return data; - } - } - - if ([self _dataStoreExists]) { - MTRDeviceClusterData * data = [_persistedClusterData objectForKey:clusterPath]; - if (data != nil) { - return data; - } - } - - if (![_persistedClusters containsObject:clusterPath]) { - // We are not expected to have this cluster, so no point in paging it in - // loading it from storage. - return nil; - } - - NSAssert(_deviceController.controllerDataStore != nil, - @"How can _persistedClusters have an entry if we have no persistence?"); - NSAssert(_persistedClusterData != nil, - @"How can _persistedClusterData not exist if we have persisted clusters?"); - - // Page in the stored value for the data. - MTRDeviceClusterData * data = [_deviceController.controllerDataStore getStoredClusterDataForNodeID:_nodeID endpointID:clusterPath.endpoint clusterID:clusterPath.cluster]; - MTR_LOG("%@ cluster path %@ cache miss - load from storage success %@", self, clusterPath, MTR_YES_NO(data)); - if (data != nil) { - [_persistedClusterData setObject:data forKey:clusterPath]; - } else { - // If clusterPath is in _persistedClusters and the data store returns nil for it, then the in-memory cache is now not dependable, and subscription should be reset and reestablished to reload cache from device - - // First make sure _persistedClusters is consistent with storage, so repeated calls don't immediately re-trigger this - [self _reconcilePersistedClustersWithStorage]; - } - - return data; -} - -- (NSSet *)_knownClusters -{ - os_unfair_lock_assert_owner(&self->_lock); - - // We might have some clusters that have not been persisted at all yet, and - // some that have been persisted but are still present in - // _clusterDataToPersist because they have been modified since then. - NSMutableSet * clusterPaths = [_persistedClusters mutableCopy]; - if (_clusterDataToPersist != nil) { - [clusterPaths unionSet:[NSSet setWithArray:[_clusterDataToPersist allKeys]]]; - } - return clusterPaths; -} - -- (NSDictionary *)_getCachedDataVersions -{ - NSMutableDictionary * dataVersions = [NSMutableDictionary dictionary]; - std::lock_guard lock(_lock); - - for (MTRClusterPath * path in [self _knownClusters]) { - dataVersions[path] = [self _clusterDataForPath:path].dataVersion; - } - - MTR_LOG_DEBUG("%@ _getCachedDataVersions dataVersions count: %lu", self, static_cast(dataVersions.count)); - - return dataVersions; -} - -- (MTRDeviceDataValueDictionary _Nullable)_cachedAttributeValueForPath:(MTRAttributePath *)path -{ - os_unfair_lock_assert_owner(&self->_lock); - - // We need an actual MTRClusterPath, not a subsclass, to do _clusterDataForPath. - auto * clusterPath = [MTRClusterPath clusterPathWithEndpointID:path.endpoint clusterID:path.cluster]; - - MTRDeviceClusterData * clusterData = [self _clusterDataForPath:clusterPath]; - if (clusterData == nil) { - return nil; - } - - return clusterData.attributes[path.attribute]; -} - -#ifdef DEBUG -- (void)unitTestResetSubscription -{ -} -#endif - -#ifdef DEBUG -- (NSUInteger)unitTestAttributesReportedSinceLastCheck -{ - return 0; -} - - (NSUInteger)unitTestNonnullDelegateCount { std::lock_guard lock(self->_lock); @@ -1182,215 +524,24 @@ - (void)downloadLogOfType:(MTRDiagnosticLogType)type }); } -#pragma mark - Cache management - -// Utility to return data value dictionary without data version -- (NSDictionary *)_dataValueWithoutDataVersion:(NSDictionary *)attributeValue -{ - // Sanity check for nil - return the same input to fail gracefully - if (!attributeValue || !attributeValue[MTRTypeKey]) { - return attributeValue; - } - - if (attributeValue[MTRValueKey]) { - return @{ MTRTypeKey : attributeValue[MTRTypeKey], MTRValueKey : attributeValue[MTRValueKey] }; - } else { - return @{ MTRTypeKey : attributeValue[MTRTypeKey] }; - } -} - -- (NSArray *> *)getAllAttributesReport +- (nullable NSNumber *)estimatedSubscriptionLatency { MTR_ABSTRACT_METHOD(); return nil; } -#ifdef DEBUG -- (NSUInteger)unitTestAttributeCount -{ - std::lock_guard lock(_lock); - NSUInteger count = 0; - for (MTRClusterPath * path in [self _knownClusters]) { - count += [self _clusterDataForPath:path].attributes.count; - } - return count; -} -#endif - -- (void)setPersistedClusterData:(NSDictionary *)clusterData -{ - MTR_LOG("%@ setPersistedClusterData count: %lu", self, static_cast(clusterData.count)); - if (!clusterData.count) { - return; - } - - std::lock_guard lock(_lock); - - NSAssert([self _dataStoreExists], @"Why is controller setting persisted data when we shouldn't have it?"); - - for (MTRClusterPath * clusterPath in clusterData) { - // The caller has mutable references to MTRDeviceClusterData and - // MTRClusterPath, but that should be OK, since we control all the - // callers. If that stops being OK, we'll need to copy the key and - // value here. - [_persistedClusters addObject:clusterPath]; - [_persistedClusterData setObject:clusterData[clusterPath] forKey:clusterPath]; - } - - [self _updateAttributeDependentDescriptionData]; - - // We have some stored data. Since we don't store data until the end of the - // initial priming report, our device cache must be primed. - _deviceCachePrimed = YES; -} - -- (void)_setLastInitialSubscribeLatency:(id)latency -{ - os_unfair_lock_assert_owner(&self->_lock); - - if (![latency isKindOfClass:NSNumber.class]) { - // Unexpected value of some sort; just ignore it. - return; - } - - _estimatedSubscriptionLatency = latency; -} - -- (void)setPersistedDeviceData:(NSDictionary *)data -{ - MTR_LOG_DEBUG("%@ setPersistedDeviceData: %@", self, data); - - std::lock_guard lock(_lock); - - // For now the only data we care about is our initial subscribe latency. - id initialSubscribeLatency = data[sLastInitialSubscribeLatencyKey]; - if (initialSubscribeLatency != nil) { - [self _setLastInitialSubscribeLatency:initialSubscribeLatency]; - } -} - -#ifdef DEBUG -- (MTRDeviceClusterData *)unitTestGetClusterDataForPath:(MTRClusterPath *)path -{ - std::lock_guard lock(_lock); - - return [[self _clusterDataForPath:path] copy]; -} - -- (NSSet *)unitTestGetPersistedClusters -{ - std::lock_guard lock(_lock); - - return [_persistedClusters copy]; -} +#pragma mark - Cache management -- (BOOL)unitTestClusterHasBeenPersisted:(MTRClusterPath *)path +- (NSArray *> *)getAllAttributesReport { - std::lock_guard lock(_lock); - - return [_persistedClusters containsObject:path]; + MTR_ABSTRACT_METHOD(); + return nil; } -#endif - (BOOL)deviceCachePrimed { - std::lock_guard lock(_lock); - return _deviceCachePrimed; -} - -#pragma mark Log Help - -- (nullable NSNumber *)_informationalNumberAtAttributePath:(MTRAttributePath *)attributePath -{ - auto * cachedData = [self _cachedAttributeValueForPath:attributePath]; - - if (cachedData == nil) { - return nil; - } - - auto * attrReport = [[MTRAttributeReport alloc] initWithResponseValue:@{ - MTRAttributePathKey : attributePath, - MTRDataKey : cachedData, - } - error:nil]; - - return attrReport.value; -} - -- (nullable NSNumber *)_informationalVendorID -{ - auto * vendorIDPath = [MTRAttributePath attributePathWithEndpointID:@(kRootEndpointId) - clusterID:@(MTRClusterIDTypeBasicInformationID) - attributeID:@(MTRClusterBasicAttributeVendorIDID)]; - - return [self _informationalNumberAtAttributePath:vendorIDPath]; -} - -- (nullable NSNumber *)_informationalProductID -{ - auto * productIDPath = [MTRAttributePath attributePathWithEndpointID:@(kRootEndpointId) - clusterID:@(MTRClusterIDTypeBasicInformationID) - attributeID:@(MTRClusterBasicAttributeProductIDID)]; - - return [self _informationalNumberAtAttributePath:productIDPath]; -} - -#pragma mark - Description handling - -- (void)_updateAttributeDependentDescriptionData -{ - os_unfair_lock_assert_owner(&_lock); - - NSNumber * _Nullable vid = [self _informationalVendorID]; - NSNumber * _Nullable pid = [self _informationalProductID]; - NSNumber * _Nullable networkFeatures = [self _networkFeatures]; - - std::lock_guard lock(_descriptionLock); - _vid = vid; - _pid = pid; - _allNetworkFeatures = networkFeatures; -} - -- (NSArray *)_endpointList -{ - os_unfair_lock_assert_owner(&_lock); - - auto * partsListPath = [MTRAttributePath attributePathWithEndpointID:@(kRootEndpointId) - clusterID:@(MTRClusterIDTypeDescriptorID) - attributeID:@(MTRAttributeIDTypeClusterDescriptorAttributePartsListID)]; - auto * partsList = [self _cachedAttributeValueForPath:partsListPath]; - NSMutableArray * endpointsOnDevice = [self arrayOfNumbersFromAttributeValue:partsList]; - if (!endpointsOnDevice) { - endpointsOnDevice = [[NSMutableArray alloc] init]; - } - // Add Root node! - [endpointsOnDevice addObject:@(0)]; - return endpointsOnDevice; -} - -- (NSNumber * _Nullable)_networkFeatures -{ - NSNumber * _Nullable result = nil; - auto * endpoints = [self _endpointList]; - for (NSNumber * endpoint in endpoints) { - auto * featureMapPath = [MTRAttributePath attributePathWithEndpointID:endpoint - clusterID:@(MTRClusterIDTypeNetworkCommissioningID) - attributeID:@(MTRAttributeIDTypeGlobalAttributeFeatureMapID)]; - auto * featureMap = [self _informationalNumberAtAttributePath:featureMapPath]; - if (featureMap == nil) { - // No network commissioning cluster on this endpoint, or no known - // FeatureMap attribute value for it yet. - continue; - } - - if (result == nil) { - result = featureMap; - } else { - result = @(featureMap.unsignedLongLongValue | result.unsignedLongLongValue); - } - } - - return result; + MTR_ABSTRACT_METHOD(); + return NO; } - (void)controllerSuspended diff --git a/src/darwin/Framework/CHIP/MTRDeviceClusterData.h b/src/darwin/Framework/CHIP/MTRDeviceClusterData.h new file mode 100644 index 00000000000000..d34ada90e9a7f2 --- /dev/null +++ b/src/darwin/Framework/CHIP/MTRDeviceClusterData.h @@ -0,0 +1,38 @@ +/** + * Copyright (c) 2024 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +#import "MTRDefines_Internal.h" +#import "MTRDeviceDataValueDictionary.h" + +NS_ASSUME_NONNULL_BEGIN + +/** + * Information about a cluster: data version and known attribute values. + */ +MTR_TESTABLE +@interface MTRDeviceClusterData : NSObject +@property (nonatomic, nullable) NSNumber * dataVersion; +@property (nonatomic, readonly) NSDictionary * attributes; // attributeID => data-value dictionary + +- (void)storeValue:(MTRDeviceDataValueDictionary _Nullable)value forAttribute:(NSNumber *)attribute; +- (void)removeValueForAttribute:(NSNumber *)attribute; + +- (nullable instancetype)initWithDataVersion:(NSNumber * _Nullable)dataVersion attributes:(NSDictionary * _Nullable)attributes; +@end + +NS_ASSUME_NONNULL_END diff --git a/src/darwin/Framework/CHIP/MTRDeviceClusterData.mm b/src/darwin/Framework/CHIP/MTRDeviceClusterData.mm new file mode 100644 index 00000000000000..fb3d8b38ae027d --- /dev/null +++ b/src/darwin/Framework/CHIP/MTRDeviceClusterData.mm @@ -0,0 +1,122 @@ +/** + * Copyright (c) 2024 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "MTRDeviceClusterData.h" +#import "MTRLogging_Internal.h" +#import "MTRUtilities.h" + +static NSString * const sDataVersionKey = @"dataVersion"; +static NSString * const sAttributesKey = @"attributes"; + +@implementation MTRDeviceClusterData { + NSMutableDictionary * _attributes; +} + +- (void)storeValue:(MTRDeviceDataValueDictionary _Nullable)value forAttribute:(NSNumber *)attribute +{ + _attributes[attribute] = value; +} + +- (void)removeValueForAttribute:(NSNumber *)attribute +{ + [_attributes removeObjectForKey:attribute]; +} + +- (NSDictionary *)attributes +{ + return _attributes; +} + ++ (BOOL)supportsSecureCoding +{ + return YES; +} + +- (NSString *)description +{ + return [NSString stringWithFormat:@"", _dataVersion, static_cast(_attributes.count)]; +} + +- (nullable instancetype)init +{ + return [self initWithDataVersion:nil attributes:nil]; +} + +// Attributes dictionary is: attributeID => data-value dictionary +- (nullable instancetype)initWithDataVersion:(NSNumber * _Nullable)dataVersion attributes:(NSDictionary * _Nullable)attributes +{ + self = [super init]; + if (self == nil) { + return nil; + } + + _dataVersion = [dataVersion copy]; + _attributes = [NSMutableDictionary dictionaryWithCapacity:attributes.count]; + [_attributes addEntriesFromDictionary:attributes]; + + return self; +} + +- (nullable instancetype)initWithCoder:(NSCoder *)decoder +{ + self = [super init]; + if (self == nil) { + return nil; + } + + _dataVersion = [decoder decodeObjectOfClass:[NSNumber class] forKey:sDataVersionKey]; + if (_dataVersion != nil && ![_dataVersion isKindOfClass:[NSNumber class]]) { + MTR_LOG_ERROR("MTRDeviceClusterData got %@ for data version, not NSNumber.", _dataVersion); + return nil; + } + + static NSSet * const sAttributeValueClasses = [NSSet setWithObjects:[NSDictionary class], [NSArray class], [NSData class], [NSString class], [NSNumber class], nil]; + _attributes = [decoder decodeObjectOfClasses:sAttributeValueClasses forKey:sAttributesKey]; + if (_attributes != nil && ![_attributes isKindOfClass:[NSDictionary class]]) { + MTR_LOG_ERROR("MTRDeviceClusterData got %@ for attributes, not NSDictionary.", _attributes); + return nil; + } + + return self; +} + +- (void)encodeWithCoder:(NSCoder *)coder +{ + [coder encodeObject:self.dataVersion forKey:sDataVersionKey]; + [coder encodeObject:self.attributes forKey:sAttributesKey]; +} + +- (id)copyWithZone:(NSZone *)zone +{ + return [[MTRDeviceClusterData alloc] initWithDataVersion:_dataVersion attributes:_attributes]; +} + +- (BOOL)isEqualToClusterData:(MTRDeviceClusterData *)otherClusterData +{ + return MTREqualObjects(_dataVersion, otherClusterData.dataVersion) + && MTREqualObjects(_attributes, otherClusterData.attributes); +} + +- (BOOL)isEqual:(id)object +{ + if ([object class] != [self class]) { + return NO; + } + + return [self isEqualToClusterData:object]; +} + +@end diff --git a/src/darwin/Framework/CHIP/MTRDeviceControllerDataStore.h b/src/darwin/Framework/CHIP/MTRDeviceControllerDataStore.h index 826fd1821f7640..508092b40fa613 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceControllerDataStore.h +++ b/src/darwin/Framework/CHIP/MTRDeviceControllerDataStore.h @@ -18,7 +18,9 @@ #import #import #import -#import + +#import "MTRDeviceClusterData.h" +#import "MTRDevice_Internal.h" #include diff --git a/src/darwin/Framework/CHIP/MTRDeviceController_Concrete.mm b/src/darwin/Framework/CHIP/MTRDeviceController_Concrete.mm index eb7881bfd11d21..1a164e50b14b5c 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceController_Concrete.mm +++ b/src/darwin/Framework/CHIP/MTRDeviceController_Concrete.mm @@ -1149,7 +1149,7 @@ - (MTRDevice *)_setupDeviceForNodeID:(NSNumber *)nodeID prefetchedClusterData:(N { os_unfair_lock_assert_owner(self.deviceMapLock); - MTRDevice * deviceToReturn = [[MTRDevice_Concrete alloc] initWithNodeID:nodeID controller:self]; + MTRDevice_Concrete * deviceToReturn = [[MTRDevice_Concrete alloc] initWithNodeID:nodeID controller:self]; // If we're not running, don't add the device to our map. That would // create a cycle that nothing would break. Just return the device, // which will be in exactly the state it would be in if it were created @@ -1190,7 +1190,16 @@ - (MTRDevice *)_setupDeviceForNodeID:(NSNumber *)nodeID prefetchedClusterData:(N std::lock_guard lock(*self.deviceMapLock); NSMutableDictionary * deviceAttributeCounts = [NSMutableDictionary dictionary]; for (NSNumber * nodeID in self.nodeIDToDeviceMap) { - deviceAttributeCounts[nodeID] = @([[self.nodeIDToDeviceMap objectForKey:nodeID] unitTestAttributeCount]); + MTRDevice * device = [self.nodeIDToDeviceMap objectForKey:nodeID]; + + // TODO: Can we not just assume this isKindOfClass test is true? Would be + // really nice if we had compile-time checking for this somehow... + if (![device isKindOfClass:MTRDevice_Concrete.class]) { + continue; + } + + auto * concreteDevice = static_cast(device); + deviceAttributeCounts[nodeID] = @([concreteDevice unitTestAttributeCount]); } return deviceAttributeCounts; } @@ -1389,9 +1398,19 @@ - (void)getSessionForNode:(chip::NodeId)nodeID completion:(MTRInternalDeviceConn // Get the corresponding MTRDevice object to determine if the case/subscription pool is to be used MTRDevice * device = [self deviceForNodeID:@(nodeID)]; + // TODO: Can we not just assume this isKindOfClass test is true? Would be + // really nice if we had compile-time checking for this somehow... + if (![device isKindOfClass:MTRDevice_Concrete.class]) { + MTR_LOG_ERROR("%@ somehow has %@ instead of MTRDevice_Concrete for node ID 0x%016llX (%llu)", self, device, nodeID, nodeID); + completion(nullptr, chip::NullOptional, [MTRError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE], nil); + return; + } + + auto * concreteDevice = static_cast(device); + // In the case that this device is known to use thread, queue this with subscription attempts as well, to // help with throttling Thread traffic. - if ([device deviceUsesThread]) { + if ([concreteDevice deviceUsesThread]) { MTRAsyncWorkItem * workItem = [[MTRAsyncWorkItem alloc] initWithQueue:dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0)]; [workItem setReadyHandler:^(id _Nonnull context, NSInteger retryCount, MTRAsyncWorkCompletionBlock _Nonnull workItemCompletion) { MTRInternalDeviceConnectionCallback completionWrapper = ^(chip::Messaging::ExchangeManager * _Nullable exchangeManager, diff --git a/src/darwin/Framework/CHIP/MTRDeviceController_Internal.h b/src/darwin/Framework/CHIP/MTRDeviceController_Internal.h index 8fd6e4cb4bfccc..c26518d532e2ea 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceController_Internal.h +++ b/src/darwin/Framework/CHIP/MTRDeviceController_Internal.h @@ -31,6 +31,7 @@ #import #import "MTRBaseDevice.h" +#import "MTRDeviceClusterData.h" #import "MTRDeviceController.h" #import "MTRDeviceControllerDataStore.h" #import "MTRDeviceControllerDelegate.h" diff --git a/src/darwin/Framework/CHIP/MTRDeviceDataValueDictionary.h b/src/darwin/Framework/CHIP/MTRDeviceDataValueDictionary.h new file mode 100644 index 00000000000000..34e46b7ccd7ef3 --- /dev/null +++ b/src/darwin/Framework/CHIP/MTRDeviceDataValueDictionary.h @@ -0,0 +1,23 @@ +/** + * Copyright (c) 2024 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +NS_ASSUME_NONNULL_BEGIN + +typedef NSDictionary * MTRDeviceDataValueDictionary; + +NS_ASSUME_NONNULL_END diff --git a/src/darwin/Framework/CHIP/MTRDevice_Concrete.h b/src/darwin/Framework/CHIP/MTRDevice_Concrete.h index 70dac9a362b10d..f2596b8ca4afc7 100644 --- a/src/darwin/Framework/CHIP/MTRDevice_Concrete.h +++ b/src/darwin/Framework/CHIP/MTRDevice_Concrete.h @@ -18,6 +18,7 @@ #import #import +#import "MTRDeviceClusterData.h" #import "MTRDeviceController_Concrete.h" NS_ASSUME_NONNULL_BEGIN @@ -31,6 +32,23 @@ NS_ASSUME_NONNULL_BEGIN // false-positives, for example due to compressed fabric id collisions. - (void)nodeMayBeAdvertisingOperational; +// Method to insert persisted cluster data +// Contains data version information and attribute values. +- (void)setPersistedClusterData:(NSDictionary *)clusterData; + +// Method to insert persisted data that pertains to the whole device. +- (void)setPersistedDeviceData:(NSDictionary *)data; + +// Returns whether this MTRDevice_Concrete uses Thread for communication +- (BOOL)deviceUsesThread; + +// For use from MTRDeviceController_Concrete when setting up a device instance. +- (void)setStorageBehaviorConfiguration:(MTRDeviceStorageBehaviorConfiguration *)storageBehaviorConfiguration; + +#ifdef DEBUG +- (NSUInteger)unitTestAttributeCount; +#endif + @end NS_ASSUME_NONNULL_END diff --git a/src/darwin/Framework/CHIP/MTRDevice_Concrete.mm b/src/darwin/Framework/CHIP/MTRDevice_Concrete.mm index 2342cadfb253f5..48d7f7f99d0fe7 100644 --- a/src/darwin/Framework/CHIP/MTRDevice_Concrete.mm +++ b/src/darwin/Framework/CHIP/MTRDevice_Concrete.mm @@ -31,6 +31,7 @@ #import "MTRDeviceConnectivityMonitor.h" #import "MTRDeviceControllerOverXPC.h" #import "MTRDeviceController_Internal.h" +#import "MTRDeviceDataValueDictionary.h" #import "MTRDevice_Concrete.h" #import "MTRDevice_Internal.h" #import "MTRError_Internal.h" @@ -55,6 +56,8 @@ #import #import +static NSString * const sLastInitialSubscribeLatencyKey = @"lastInitialSubscribeLatency"; + // allow readwrite access to superclass properties @interface MTRDevice_Concrete () @@ -208,7 +211,6 @@ @interface MTRDevice_Concrete () // whatever lock protects the time sync bits. @property (nonatomic, readonly) os_unfair_lock timeSyncLock; -@property (nonatomic) chip::FabricIndex fabricIndex; @property (nonatomic) NSMutableArray *> * unreportedEvents; @property (nonatomic) BOOL receivingReport; @property (nonatomic) BOOL receivingPrimingReport; @@ -367,7 +369,6 @@ - (instancetype)initWithNodeID:(NSNumber *)nodeID controller:(MTRDeviceControlle if (self = [super initForSubclassesWithNodeID:nodeID controller:controller]) { _timeSyncLock = OS_UNFAIR_LOCK_INIT; _descriptionLock = OS_UNFAIR_LOCK_INIT; - _fabricIndex = controller.fabricIndex; _queue = dispatch_queue_create("org.csa-iot.matter.framework.device.workqueue", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); _expectedValueCache = [NSMutableDictionary dictionary]; diff --git a/src/darwin/Framework/CHIP/MTRDevice_Internal.h b/src/darwin/Framework/CHIP/MTRDevice_Internal.h index 2cdcd66976099a..f954979f131084 100644 --- a/src/darwin/Framework/CHIP/MTRDevice_Internal.h +++ b/src/darwin/Framework/CHIP/MTRDevice_Internal.h @@ -28,8 +28,6 @@ NS_ASSUME_NONNULL_BEGIN @class MTRAsyncWorkQueue; -typedef NSDictionary * MTRDeviceDataValueDictionary; - typedef void (^MTRDevicePerformAsyncBlock)(MTRBaseDevice * baseDevice); typedef NS_ENUM(NSUInteger, MTRInternalDeviceState) { @@ -52,20 +50,6 @@ typedef NS_ENUM(NSUInteger, MTRInternalDeviceState) { MTRInternalDeviceStateLaterSubscriptionEstablished = 4, }; -/** - * Information about a cluster: data version and known attribute values. - */ -MTR_TESTABLE -@interface MTRDeviceClusterData : NSObject -@property (nonatomic, nullable) NSNumber * dataVersion; -@property (nonatomic, readonly) NSDictionary * attributes; // attributeID => data-value dictionary - -- (void)storeValue:(MTRDeviceDataValueDictionary _Nullable)value forAttribute:(NSNumber *)attribute; -- (void)removeValueForAttribute:(NSNumber *)attribute; - -- (nullable instancetype)initWithDataVersion:(NSNumber * _Nullable)dataVersion attributes:(NSDictionary * _Nullable)attributes; -@end - // Consider moving utility classes to their own file #pragma mark - Utility Classes @@ -157,22 +141,6 @@ MTR_DIRECT_MEMBERS @property (nonatomic) dispatch_queue_t queue; @property (nonatomic, readonly) MTRAsyncWorkQueue * asyncWorkQueue; -// Method to insert persisted cluster data -// Contains data version information and attribute values. -- (void)setPersistedClusterData:(NSDictionary *)clusterData; - -// Method to insert persisted data that pertains to the whole device. -- (void)setPersistedDeviceData:(NSDictionary *)data; - -#ifdef DEBUG -- (NSUInteger)unitTestAttributeCount; -#endif - -- (void)setStorageBehaviorConfiguration:(MTRDeviceStorageBehaviorConfiguration *)storageBehaviorConfiguration; - -// Returns whether this MTRDevice uses Thread for communication -- (BOOL)deviceUsesThread; - #pragma mark - MTRDevice functionality to deal with delegates. // Returns YES if any non-null delegates were found @@ -208,11 +176,6 @@ MTR_DIRECT_MEMBERS static NSString * const kDefaultSubscriptionPoolSizeOverrideKey = @"subscriptionPoolSizeOverride"; static NSString * const kTestStorageUserDefaultEnabledKey = @"enableTestStorage"; -// ex-MTRDeviceClusterData constants -static NSString * const sDataVersionKey = @"dataVersion"; -static NSString * const sAttributesKey = @"attributes"; -static NSString * const sLastInitialSubscribeLatencyKey = @"lastInitialSubscribeLatency"; - // Declared inside platform, but noting here for reference // static NSString * const kSRPTimeoutInMsecsUserDefaultKey = @"SRPTimeoutInMSecsOverride"; diff --git a/src/darwin/Framework/CHIP/MTRDevice_XPC.mm b/src/darwin/Framework/CHIP/MTRDevice_XPC.mm index aefa2fffc1eeb7..7782509fb79bcd 100644 --- a/src/darwin/Framework/CHIP/MTRDevice_XPC.mm +++ b/src/darwin/Framework/CHIP/MTRDevice_XPC.mm @@ -41,6 +41,7 @@ #import "MTRDeviceControllerStartupParams_Internal.h" #import "MTRDeviceController_Concrete.h" #import "MTRDeviceController_XPC.h" +#import "MTRDeviceDataValueDictionary.h" #import "MTRDevice_Concrete.h" #import "MTRDevice_Internal.h" #import "MTRDevice_XPC_Internal.h" diff --git a/src/darwin/Framework/CHIPTests/MTRDeviceTests.m b/src/darwin/Framework/CHIPTests/MTRDeviceTests.m index 8a3188cbeb7db1..5fb3549a49216a 100644 --- a/src/darwin/Framework/CHIPTests/MTRDeviceTests.m +++ b/src/darwin/Framework/CHIPTests/MTRDeviceTests.m @@ -25,6 +25,7 @@ #import #import "MTRCommandPayloadExtensions_Internal.h" +#import "MTRDeviceClusterData.h" #import "MTRDeviceControllerLocalTestStorage.h" #import "MTRDeviceStorageBehaviorConfiguration.h" #import "MTRDeviceTestDelegate.h" diff --git a/src/darwin/Framework/CHIPTests/MTRPerControllerStorageTests.m b/src/darwin/Framework/CHIPTests/MTRPerControllerStorageTests.m index 6b193c7b55dbb5..721cb09b994e25 100644 --- a/src/darwin/Framework/CHIPTests/MTRPerControllerStorageTests.m +++ b/src/darwin/Framework/CHIPTests/MTRPerControllerStorageTests.m @@ -19,7 +19,9 @@ #import #import +#import "MTRDeviceClusterData.h" #import "MTRDeviceControllerLocalTestStorage.h" +#import "MTRDeviceDataValueDictionary.h" #import "MTRDeviceStorageBehaviorConfiguration.h" #import "MTRDeviceTestDelegate.h" #import "MTRDevice_Internal.h" diff --git a/src/darwin/Framework/CHIPTests/TestHelpers/MTRTestDeclarations.h b/src/darwin/Framework/CHIPTests/TestHelpers/MTRTestDeclarations.h index 22998eb4496216..74a7dc280b1216 100644 --- a/src/darwin/Framework/CHIPTests/TestHelpers/MTRTestDeclarations.h +++ b/src/darwin/Framework/CHIPTests/TestHelpers/MTRTestDeclarations.h @@ -18,14 +18,14 @@ #import #import -// For MTRDeviceDataValueDictionary: +#import "MTRDeviceClusterData.h" +#import "MTRDeviceDataValueDictionary.h" #import "MTRDevice_Internal.h" NS_ASSUME_NONNULL_BEGIN #pragma mark - Declarations for internal methods -@class MTRDeviceClusterData; // MTRDeviceControllerDataStore.h includes C++ header, and so we need to declare the methods separately @protocol MTRDeviceControllerDataStoreAttributeStoreMethods - (nullable NSDictionary *)getStoredClusterDataForNodeID:(NSNumber *)nodeID; @@ -51,6 +51,7 @@ NS_ASSUME_NONNULL_BEGIN @interface MTRDevice (Test) - (BOOL)_attributeDataValue:(NSDictionary *)one isEqualToDataValue:(NSDictionary *)theOther; - (NSMutableArray *)arrayOfNumbersFromAttributeValue:(MTRDeviceDataValueDictionary)dataDictionary; +- (void)setStorageBehaviorConfiguration:(MTRDeviceStorageBehaviorConfiguration *)storageBehaviorConfiguration; @end #pragma mark - Declarations for items compiled only for DEBUG configuration @@ -85,6 +86,7 @@ NS_ASSUME_NONNULL_BEGIN - (MTRDeviceClusterData *)unitTestGetClusterDataForPath:(MTRClusterPath *)path; - (NSSet *)unitTestGetPersistedClusters; - (BOOL)unitTestClusterHasBeenPersisted:(MTRClusterPath *)path; +- (NSUInteger)unitTestAttributeCount; @end #endif diff --git a/src/darwin/Framework/Matter.xcodeproj/project.pbxproj b/src/darwin/Framework/Matter.xcodeproj/project.pbxproj index ea5ef7969a1d4b..bd05397c05c67e 100644 --- a/src/darwin/Framework/Matter.xcodeproj/project.pbxproj +++ b/src/darwin/Framework/Matter.xcodeproj/project.pbxproj @@ -132,6 +132,9 @@ 5109E9B42CB8B5DF0006884B /* MTRDeviceType.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5109E9B32CB8B5DF0006884B /* MTRDeviceType.mm */; }; 5109E9B52CB8B5DF0006884B /* MTRDeviceType.h in Headers */ = {isa = PBXBuildFile; fileRef = 5109E9B22CB8B5DF0006884B /* MTRDeviceType.h */; settings = {ATTRIBUTES = (Public, ); }; }; 5109E9B72CB8B83D0006884B /* MTRDeviceTypeTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5109E9B62CB8B83D0006884B /* MTRDeviceTypeTests.m */; }; + 5109E9BA2CC1F23E0006884B /* MTRDeviceClusterData.h in Headers */ = {isa = PBXBuildFile; fileRef = 5109E9B82CC1F23E0006884B /* MTRDeviceClusterData.h */; }; + 5109E9BB2CC1F23E0006884B /* MTRDeviceClusterData.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5109E9B92CC1F23E0006884B /* MTRDeviceClusterData.mm */; }; + 5109E9BD2CC1F25C0006884B /* MTRDeviceDataValueDictionary.h in Headers */ = {isa = PBXBuildFile; fileRef = 5109E9BC2CC1F25C0006884B /* MTRDeviceDataValueDictionary.h */; }; 510A07492A685D3900A9241C /* Matter.apinotes in Headers */ = {isa = PBXBuildFile; fileRef = 510A07482A685D3900A9241C /* Matter.apinotes */; settings = {ATTRIBUTES = (Public, ); }; }; 510CECA8297F72970064E0B3 /* MTROperationalCertificateIssuerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 510CECA6297F72470064E0B3 /* MTROperationalCertificateIssuerTests.m */; }; 5117DD3829A931AE00FFA1AA /* MTROperationalBrowser.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5117DD3629A931AD00FFA1AA /* MTROperationalBrowser.mm */; }; @@ -584,6 +587,9 @@ 5109E9B22CB8B5DF0006884B /* MTRDeviceType.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MTRDeviceType.h; sourceTree = ""; }; 5109E9B32CB8B5DF0006884B /* MTRDeviceType.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MTRDeviceType.mm; sourceTree = ""; }; 5109E9B62CB8B83D0006884B /* MTRDeviceTypeTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MTRDeviceTypeTests.m; sourceTree = ""; }; + 5109E9B82CC1F23E0006884B /* MTRDeviceClusterData.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MTRDeviceClusterData.h; sourceTree = ""; }; + 5109E9B92CC1F23E0006884B /* MTRDeviceClusterData.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MTRDeviceClusterData.mm; sourceTree = ""; }; + 5109E9BC2CC1F25C0006884B /* MTRDeviceDataValueDictionary.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MTRDeviceDataValueDictionary.h; sourceTree = ""; }; 510A07482A685D3900A9241C /* Matter.apinotes */ = {isa = PBXFileReference; lastKnownFileType = text.apinotes; name = Matter.apinotes; path = CHIP/Matter.apinotes; sourceTree = ""; }; 510CECA6297F72470064E0B3 /* MTROperationalCertificateIssuerTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MTROperationalCertificateIssuerTests.m; sourceTree = ""; }; 5117DD3629A931AD00FFA1AA /* MTROperationalBrowser.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MTROperationalBrowser.mm; sourceTree = ""; }; @@ -1383,6 +1389,8 @@ 7534F12628BFF20300390851 /* MTRDeviceAttestationDelegate.mm */, 88EBF8CD27FABDD500686BC1 /* MTRDeviceAttestationDelegateBridge.h */, 88EBF8CC27FABDD500686BC1 /* MTRDeviceAttestationDelegateBridge.mm */, + 5109E9B82CC1F23E0006884B /* MTRDeviceClusterData.h */, + 5109E9B92CC1F23E0006884B /* MTRDeviceClusterData.mm */, 2C5EEEF4268A85C400CAE3D3 /* MTRDeviceConnectionBridge.h */, 2C5EEEF5268A85C400CAE3D3 /* MTRDeviceConnectionBridge.mm */, 75B3269B2BCDB9D600E17C4E /* MTRDeviceConnectivityMonitor.h */, @@ -1417,6 +1425,7 @@ 51565CB32A7AD78D00469F18 /* MTRDeviceControllerStorageDelegate.h */, 5A6FEC9427B5976200F25F42 /* MTRDeviceControllerXPCConnection.h */, 5A6FEC9527B5983000F25F42 /* MTRDeviceControllerXPCConnection.mm */, + 5109E9BC2CC1F25C0006884B /* MTRDeviceDataValueDictionary.h */, 5A6FEC8B27B5609C00F25F42 /* MTRDeviceOverXPC.h */, 5A6FEC9727B5C6AF00F25F42 /* MTRDeviceOverXPC.mm */, 754784632BFE65B70089C372 /* MTRDeviceStorageBehaviorConfiguration.h */, @@ -1698,6 +1707,7 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( + 5109E9BD2CC1F25C0006884B /* MTRDeviceDataValueDictionary.h in Headers */, 51D0B1282B617246006E3511 /* MTRServerEndpoint.h in Headers */, 51565CB62A7B0D6600469F18 /* MTRDeviceControllerParameters.h in Headers */, 51565CB42A7AD78D00469F18 /* MTRDeviceControllerStorageDelegate.h in Headers */, @@ -1744,6 +1754,7 @@ 2C222AD0255C620600E446B9 /* MTRBaseDevice.h in Headers */, 7596A84F2877E6A9004DAE0E /* MTRCluster_Internal.h in Headers */, 9B5CCB612C6EE29E009DD99B /* MTRDeviceControllerXPCParameters.h in Headers */, + 5109E9BA2CC1F23E0006884B /* MTRDeviceClusterData.h in Headers */, 991DC0842475F45400C13860 /* MTRDeviceController.h in Headers */, 88FA798D2B7B257100CD4B6F /* MTRMetricsCollector.h in Headers */, 9BFE5D502C6D3075007D4319 /* MTRDeviceController_XPC.h in Headers */, @@ -2120,6 +2131,7 @@ 511913FB28C100EF009235E9 /* MTRBaseSubscriptionCallback.mm in Sources */, 510470FB2A2F7DF60053EA7E /* MTRBackwardsCompatShims.mm in Sources */, 5173A47629C0E2ED00F67F48 /* MTRFabricInfo.mm in Sources */, + 5109E9BB2CC1F23E0006884B /* MTRDeviceClusterData.mm in Sources */, 9B231B052C62EF650030EB37 /* MTRDeviceController_Concrete.mm in Sources */, 5ACDDD7D27CD16D200EFD68A /* MTRClusterStateCacheContainer.mm in Sources */, 75B3269E2BCDB9EA00E17C4E /* MTRDeviceConnectivityMonitor.mm in Sources */, From edf3b8b2fac223b1a9625ecc13ffbd0d3a95a5ba Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Fri, 18 Oct 2024 08:47:28 -0400 Subject: [PATCH 036/149] Add missing availability annotation on publicKeyData. (#36135) --- src/darwin/Framework/CHIP/MTRCertificateInfo.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/darwin/Framework/CHIP/MTRCertificateInfo.h b/src/darwin/Framework/CHIP/MTRCertificateInfo.h index eba7aec83073e1..88b64730f1260a 100644 --- a/src/darwin/Framework/CHIP/MTRCertificateInfo.h +++ b/src/darwin/Framework/CHIP/MTRCertificateInfo.h @@ -68,7 +68,7 @@ MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) /** * Public key data for this certificate */ -@property (nullable, readonly, retain) NSData * publicKeyData; +@property (nullable, readonly, retain) NSData * publicKeyData MTR_NEWLY_AVAILABLE; @end From 0060e0e63c8d1105ed5a9f421f8b56544cf0924b Mon Sep 17 00:00:00 2001 From: Arkadiusz Bokowy Date: Fri, 18 Oct 2024 15:46:54 +0200 Subject: [PATCH 037/149] Replace ReturnErrorCodeIf with VerifyOrReturnError (#36083) * 'ReturnErrorCodeIf(!$A, $B);' -> 'VerifyOrReturnError($A, $B);' * 'ReturnErrorCodeIf($A == $B, $C);' -> 'VerifyOrReturnError($A != $B, $C);' * 'ReturnErrorCodeIf($A != $B, $C);' -> 'VerifyOrReturnError($A == $B, $C);' * 'ReturnErrorCodeIf($A < $B, $C);' -> 'VerifyOrReturnError($A >= $B, $C);' * 'ReturnErrorCodeIf($A <= $B, $C);' -> 'VerifyOrReturnError($A > $B, $C);' * 'ReturnErrorCodeIf($A > $B, $C);' -> 'VerifyOrReturnError($A <= $B, $C);' * 'ReturnErrorCodeIf($A >= $B, $C);' -> 'VerifyOrReturnError($A < $B, $C);' * 'ReturnErrorCodeIf($A($$$B), $C);' -> 'VerifyOrReturnError(!$A($$$B), $C);' * 'ReturnErrorCodeIf($A, $B);' -> 'VerifyOrReturnError(!$A, $B);' * Replace ReturnErrorCodeWithMetricIf with VerifyOrReturnErrorWithMetric * Restyled by clang-format * 'ReturnErrorCodeIf($A != $B && $C != $D, $Z);' --rewrite 'VerifyOrReturnError($A == $B || $C == $D, $Z);' * 'ReturnErrorCodeIf($A == $B && $C == $D, $Z);' --rewrite 'VerifyOrReturnError($A != $B || $C != $D, $Z);' * 'ReturnErrorCodeIf($A == $B || $C == $D, $Z);' --rewrite 'VerifyOrReturnError($A != $B && $C != $D, $Z);' * 'ReturnErrorCodeIf($A || $B, $Z);' --rewrite 'VerifyOrReturnError(!($A) && !($B), $Z);' This commit was manually optimized. * 'ReturnErrorCodeIf($A && $B, $Z);' --rewrite 'VerifyOrReturnError(!($A) || !($B), $Z);' This commit was manually optimized. * Drop support for ReturnErrorCodeIf * Restyled by clang-format --------- Co-authored-by: Restyled.io --- .../asr/subdevice/SubDeviceManager.cpp | 4 +- examples/bridge-app/esp32/main/main.cpp | 4 +- examples/bridge-app/telink/src/AppTask.cpp | 4 +- .../delay/WaitForCommissioneeCommand.cpp | 2 +- .../src/EnergyEvseTargetsStore.cpp | 4 +- .../KeyValueStorageTest.cpp | 24 +++---- .../CC13X4_26X4DeviceAttestationCreds.cpp | 8 +-- .../cc32xx/CC32XXDeviceAttestationCreds.cpp | 8 +-- .../silabs/SiWx917/SiWx917/sl_wifi_if.cpp | 4 +- .../provision/ProvisionStorageFlash.cpp | 6 +- .../include/MediaCommandBase.h | 2 +- .../tv-casting-common/include/MediaReadBase.h | 2 +- .../include/MediaSubscriptionBase.h | 2 +- src/access/AccessControl.cpp | 4 +- src/access/AccessControl.h | 4 +- .../examples/ExampleAccessControlDelegate.cpp | 4 +- src/access/tests/TestAccessControl.cpp | 16 ++--- src/app/CASEClient.h | 8 +-- src/app/CASESessionManager.cpp | 2 +- .../DeferredAttributePersistenceProvider.cpp | 2 +- src/app/EventManagement.cpp | 6 +- src/app/InteractionModelEngine.cpp | 12 ++-- src/app/OperationalSessionSetup.cpp | 2 +- .../SimpleSubscriptionResumptionStorage.cpp | 8 +-- src/app/SubscriptionResumptionStorage.h | 8 +-- src/app/WriteClient.cpp | 2 +- src/app/WriteHandler.cpp | 4 +- .../access-control-server.cpp | 16 ++--- src/app/clusters/bindings/bindings.cpp | 4 +- .../ota-requestor/DefaultOTARequestor.cpp | 2 +- ...thread-border-router-management-server.cpp | 4 +- .../user-label-server/user-label-server.cpp | 4 +- .../CodegenDataModelProvider_Read.cpp | 6 +- .../CodegenDataModelProvider_Write.cpp | 2 +- .../icd/client/DefaultICDClientStorage.cpp | 14 ++-- src/app/reporting/Engine.cpp | 4 +- src/app/server/AclStorage.cpp | 4 +- src/app/util/binding-table.cpp | 2 +- .../util/ember-compatibility-functions.cpp | 6 +- src/controller/CHIPDeviceController.cpp | 10 +-- .../CHIPDeviceControllerFactory.cpp | 6 +- .../ExampleOperationalCredentialsIssuer.cpp | 16 ++--- src/controller/ExamplePersistentStorage.cpp | 14 ++-- .../AndroidOperationalCredentialsIssuer.cpp | 8 +-- .../ChipDeviceController-ScriptBinding.cpp | 10 +-- .../ChipDeviceController-StorageDelegate.cpp | 8 +-- src/controller/python/OpCredsBinding.cpp | 12 ++-- src/credentials/CHIPCert.cpp | 6 +- src/credentials/CHIPCertToX509.cpp | 2 +- src/credentials/FabricTable.cpp | 26 +++---- src/credentials/FabricTable.h | 2 +- .../PersistentStorageOpCertStore.cpp | 68 +++++++++--------- .../TestOnlyLocalCertificateAuthority.h | 12 ++-- .../DefaultDeviceAttestationVerifier.cpp | 6 +- src/crypto/CHIPCryptoPAL.cpp | 18 ++--- src/crypto/CHIPCryptoPALOpenSSL.cpp | 4 +- src/crypto/CHIPCryptoPALmbedTLSCert.cpp | 4 +- src/crypto/PSAOperationalKeystore.cpp | 2 +- .../GenericConfigurationManagerImpl.ipp | 26 +++---- .../GenericDeviceInstanceInfoProvider.ipp | 16 ++--- src/lib/asn1/ASN1OID.cpp | 6 +- src/lib/asn1/ASN1Reader.cpp | 60 ++++++++-------- src/lib/asn1/ASN1Writer.cpp | 24 +++---- src/lib/core/OTAImageHeader.cpp | 14 ++-- src/lib/dnssd/Advertiser_ImplMinimalMdns.cpp | 12 ++-- src/lib/dnssd/Resolver_ImplMinimalMdns.cpp | 8 +-- src/lib/dnssd/ServiceNaming.cpp | 20 +++--- src/lib/dnssd/minimal_mdns/ResponseSender.cpp | 4 +- src/lib/support/CHIPMem-Simple.cpp | 4 +- src/lib/support/CodeUtils.h | 25 ------- .../support/TestPersistentStorageDelegate.h | 6 +- src/messaging/ExchangeMessageDispatch.cpp | 2 +- src/platform/ASR/ASRFactoryDataProvider.cpp | 38 +++++----- src/platform/ASR/ASROTAImageProcessor.cpp | 2 +- src/platform/Ameba/AmebaOTAImageProcessor.cpp | 2 +- src/platform/Ameba/FactoryDataProvider.cpp | 71 ++++++++++--------- src/platform/Beken/OTAImageProcessorImpl.cpp | 2 +- .../Darwin/KeyValueStoreManagerImpl.mm | 28 ++++---- .../ESP32/ConfigurationManagerImpl.cpp | 5 +- src/platform/ESP32/ESP32Config.cpp | 2 +- src/platform/ESP32/ESP32EndpointQueueFilter.h | 4 +- .../ESP32/ESP32FactoryDataProvider.cpp | 8 +-- .../ESP32/KeyValueStoreManagerImpl.cpp | 4 +- .../ESP32/NetworkCommissioningDriver.cpp | 2 +- src/platform/ESP32/OTAImageProcessorImpl.cpp | 2 +- .../ESP32/bluedroid/ChipDeviceScanner.cpp | 4 +- .../ESP32/nimble/ChipDeviceScanner.cpp | 4 +- .../Infineon/CYW30739/FactoryDataProvider.cpp | 4 +- .../CYW30739/KeyValueStoreManagerImpl.cpp | 6 +- .../CYW30739/OTAImageProcessorImpl.cpp | 2 +- .../Infineon/PSOC6/OTAImageProcessorImpl.cpp | 6 +- src/platform/Linux/OTAImageProcessorImpl.cpp | 2 +- src/platform/NuttX/OTAImageProcessorImpl.cpp | 2 +- ...enericNetworkCommissioningThreadDriver.cpp | 2 +- .../GenericThreadBorderRouterDelegate.cpp | 2 +- ...nericThreadStackManagerImpl_OpenThread.hpp | 2 +- .../OpenThread/OpenThreadDnssdImpl.cpp | 2 +- .../Tizen/ConnectivityManagerImpl.cpp | 4 +- src/platform/Zephyr/BLEAdvertisingArbiter.cpp | 2 +- .../Zephyr/KeyValueStoreManagerImpl.cpp | 6 +- src/platform/Zephyr/SystemTimeSupport.cpp | 2 +- src/platform/android/AndroidConfig.cpp | 48 ++++++------- .../android/ConfigurationManagerImpl.cpp | 4 +- .../DeviceInstanceInfoProviderImpl.cpp | 5 +- src/platform/android/DnssdImpl.cpp | 6 +- .../android/KeyValueStoreManagerImpl.cpp | 22 +++--- .../cc13xx_26xx/FactoryDataProvider.cpp | 68 +++++++++--------- src/platform/mt793x/OTAImageProcessorImpl.cpp | 2 +- .../DeviceInstanceInfoProviderImpl.cpp | 4 +- .../DiagnosticDataProviderImplNrf.cpp | 2 +- .../nrfconnect/FactoryDataProvider.cpp | 50 ++++++------- .../nrfconnect/OTAImageProcessorImpl.cpp | 6 +- .../nxp/common/ConfigurationManagerImpl.cpp | 4 +- src/platform/nxp/common/DnssdImplBr.cpp | 4 +- src/platform/nxp/common/NXPConfigNVS.cpp | 24 +++---- .../nxp/common/OTAImageProcessorImpl.cpp | 2 +- .../ble_zephyr/BLEAdvertisingArbiter.cpp | 2 +- .../common/crypto/CHIPCryptoPALTinyCrypt.cpp | 4 +- .../factory_data/FactoryDataProvider.cpp | 10 +-- .../legacy/FactoryDataDriverImpl.cpp | 6 +- .../legacy/FactoryDataProvider.cpp | 16 ++--- .../legacy/FactoryDataProviderImpl.cpp | 2 +- .../nxp/common/ota/OTAFirmwareProcessor.cpp | 8 +-- .../nxp/common/ota/OTAImageProcessorImpl.cpp | 4 +- .../nxp/k32w0/ConfigurationManagerImpl.cpp | 4 +- .../nxp/k32w0/FactoryDataProvider.cpp | 16 ++--- .../nxp/k32w0/FactoryDataProviderImpl.cpp | 8 +-- .../nxp/k32w0/KeyValueStoreManagerImpl.cpp | 2 +- .../nxp/k32w0/OTAFactoryDataProcessor.cpp | 10 +-- .../nxp/k32w0/OTAFirmwareProcessor.cpp | 8 +-- .../nxp/mw320/FactoryDataProvider.cpp | 4 +- .../nxp/mw320/OTAImageProcessorImpl.cpp | 2 +- .../zephyr/DeviceInstanceInfoProviderImpl.cpp | 4 +- .../zephyr/DiagnosticDataProviderImplNxp.cpp | 2 +- .../nxp/zephyr/ota/OTAImageProcessorImpl.cpp | 6 +- .../openiotsdk/OTAImageProcessorImpl.cpp | 2 +- src/platform/qpg/OTAImageProcessorImpl.cpp | 2 +- .../silabs/SiWx917/CHIPCryptoPALTinyCrypt.cpp | 4 +- .../silabs/SiWx917/OTAImageProcessorImpl.cpp | 4 +- .../silabs/efr32/CHIPCryptoPALPsaEfr32.cpp | 4 +- .../silabs/efr32/OTAImageProcessorImpl.cpp | 4 +- .../silabs/multi-ota/OTACustomProcessor.cpp | 2 +- .../silabs/multi-ota/OTAFirmwareProcessor.cpp | 2 +- .../multi-ota/OTAMultiImageProcessorImpl.cpp | 4 +- src/platform/stm32/FactoryDataProvider.cpp | 6 +- src/platform/stm32/OTAImageProcessorImpl.cpp | 2 +- src/platform/telink/FactoryDataProvider.cpp | 40 +++++------ src/platform/telink/OTAImageProcessorImpl.cpp | 6 +- src/platform/webos/ChipDeviceScanner.cpp | 4 +- src/protocols/secure_channel/CASEServer.cpp | 2 +- src/protocols/secure_channel/CASESession.cpp | 12 ++-- src/protocols/secure_channel/PASESession.cpp | 12 ++-- src/protocols/secure_channel/StatusReport.cpp | 2 +- .../QRCodeSetupPayloadParser.cpp | 4 +- src/system/SystemLayerImplSelect.cpp | 4 +- src/tracing/metric_macros.h | 34 +-------- src/tracing/tests/TestMetricEvents.cpp | 33 --------- src/transport/SecureMessageCodec.cpp | 2 +- src/transport/raw/BLE.cpp | 6 +- src/transport/raw/WiFiPAF.cpp | 4 +- 160 files changed, 695 insertions(+), 782 deletions(-) diff --git a/examples/bridge-app/asr/subdevice/SubDeviceManager.cpp b/examples/bridge-app/asr/subdevice/SubDeviceManager.cpp index 3508068c4832c6..776c4e43490e04 100644 --- a/examples/bridge-app/asr/subdevice/SubDeviceManager.cpp +++ b/examples/bridge-app/asr/subdevice/SubDeviceManager.cpp @@ -156,8 +156,8 @@ Protocols::InteractionModel::Status HandleWriteOnOffAttribute(SubDevice * dev, c { ChipLogProgress(DeviceLayer, "HandleWriteOnOffAttribute: attrId=%" PRIu32, attributeId); - ReturnErrorCodeIf((attributeId != OnOff::Attributes::OnOff::Id) || (!dev->IsReachable()), - Protocols::InteractionModel::Status::Failure); + VerifyOrReturnError((attributeId == OnOff::Attributes::OnOff::Id) && dev->IsReachable(), + Protocols::InteractionModel::Status::Failure); dev->SetOnOff(*buffer == 1); return Protocols::InteractionModel::Status::Success; } diff --git a/examples/bridge-app/esp32/main/main.cpp b/examples/bridge-app/esp32/main/main.cpp index 016b75803cd69b..d1075385cec8c9 100644 --- a/examples/bridge-app/esp32/main/main.cpp +++ b/examples/bridge-app/esp32/main/main.cpp @@ -268,8 +268,8 @@ Protocols::InteractionModel::Status HandleWriteOnOffAttribute(Device * dev, chip { ChipLogProgress(DeviceLayer, "HandleWriteOnOffAttribute: attrId=%" PRIu32, attributeId); - ReturnErrorCodeIf((attributeId != OnOff::Attributes::OnOff::Id) || (!dev->IsReachable()), - Protocols::InteractionModel::Status::Failure); + VerifyOrReturnError((attributeId == OnOff::Attributes::OnOff::Id) && dev->IsReachable(), + Protocols::InteractionModel::Status::Failure); dev->SetOnOff(*buffer == 1); return Protocols::InteractionModel::Status::Success; } diff --git a/examples/bridge-app/telink/src/AppTask.cpp b/examples/bridge-app/telink/src/AppTask.cpp index e080e40eb5dda9..79644c2860ae21 100644 --- a/examples/bridge-app/telink/src/AppTask.cpp +++ b/examples/bridge-app/telink/src/AppTask.cpp @@ -298,8 +298,8 @@ Protocols::InteractionModel::Status HandleWriteOnOffAttribute(Device * dev, chip { ChipLogProgress(DeviceLayer, "HandleWriteOnOffAttribute: attrId=%" PRIu32, attributeId); - ReturnErrorCodeIf((attributeId != Clusters::OnOff::Attributes::OnOff::Id) || (!dev->IsReachable()), - Protocols::InteractionModel::Status::Failure); + VerifyOrReturnError((attributeId == Clusters::OnOff::Attributes::OnOff::Id) && dev->IsReachable(), + Protocols::InteractionModel::Status::Failure); dev->SetOnOff(*buffer == 1); return Protocols::InteractionModel::Status::Success; } diff --git a/examples/chip-tool/commands/delay/WaitForCommissioneeCommand.cpp b/examples/chip-tool/commands/delay/WaitForCommissioneeCommand.cpp index 486e9f1204f2b5..2634c78e99a503 100644 --- a/examples/chip-tool/commands/delay/WaitForCommissioneeCommand.cpp +++ b/examples/chip-tool/commands/delay/WaitForCommissioneeCommand.cpp @@ -23,7 +23,7 @@ using namespace chip; CHIP_ERROR WaitForCommissioneeCommand::RunCommand() { chip::FabricIndex fabricIndex = CurrentCommissioner().GetFabricIndex(); - ReturnErrorCodeIf(fabricIndex == chip::kUndefinedFabricIndex, CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(fabricIndex != chip::kUndefinedFabricIndex, CHIP_ERROR_INCORRECT_STATE); if (mExpireExistingSession.ValueOr(true)) { diff --git a/examples/energy-management-app/energy-management-common/energy-evse/src/EnergyEvseTargetsStore.cpp b/examples/energy-management-app/energy-management-common/energy-evse/src/EnergyEvseTargetsStore.cpp index f15e0b7a109817..2144219409bc5f 100644 --- a/examples/energy-management-app/energy-management-common/energy-evse/src/EnergyEvseTargetsStore.cpp +++ b/examples/energy-management-app/energy-management-common/energy-evse/src/EnergyEvseTargetsStore.cpp @@ -75,7 +75,7 @@ CHIP_ERROR EvseTargetsDelegate::LoadTargets() Platform::ScopedMemoryBuffer backingBuffer; uint16_t length = GetTlvSizeUpperBound(); - ReturnErrorCodeIf(!backingBuffer.Calloc(length), CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(backingBuffer.Calloc(length), CHIP_ERROR_NO_MEMORY); CHIP_ERROR err = mpTargetStore->SyncGetKeyValue(spEvseTargetsKeyName, backingBuffer.Get(), length); if (err == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND) @@ -390,7 +390,7 @@ EvseTargetsDelegate::SaveTargets(DataModel::List backingBuffer; - ReturnErrorCodeIf(!backingBuffer.Calloc(total), CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(backingBuffer.Calloc(total), CHIP_ERROR_NO_MEMORY); TLV::ScopedBufferTLVWriter writer(std::move(backingBuffer), total); TLV::TLVType arrayType; diff --git a/examples/persistent-storage/KeyValueStorageTest.cpp b/examples/persistent-storage/KeyValueStorageTest.cpp index 5aab299dc014ac..0f688c4f07f6ac 100644 --- a/examples/persistent-storage/KeyValueStorageTest.cpp +++ b/examples/persistent-storage/KeyValueStorageTest.cpp @@ -55,8 +55,8 @@ CHIP_ERROR TestEmptyString() size_t read_size; ReturnErrorOnFailure(KeyValueStoreMgr().Put(kTestKey, kTestValue)); ReturnErrorOnFailure(KeyValueStoreMgr().Get(kTestKey, read_value, sizeof(read_value), &read_size)); - ReturnErrorCodeIf(strcmp(kTestValue, read_value) != 0, CHIP_ERROR_INTERNAL); - ReturnErrorCodeIf(read_size != sizeof(kTestValue), CHIP_ERROR_INTERNAL); + VerifyOrReturnError(strcmp(kTestValue, read_value) == 0, CHIP_ERROR_INTERNAL); + VerifyOrReturnError(read_size == sizeof(kTestValue), CHIP_ERROR_INTERNAL); ReturnErrorOnFailure(KeyValueStoreMgr().Delete(kTestKey)); return CHIP_NO_ERROR; } @@ -69,8 +69,8 @@ CHIP_ERROR TestString() size_t read_size; ReturnErrorOnFailure(KeyValueStoreMgr().Put(kTestKey, kTestValue)); ReturnErrorOnFailure(KeyValueStoreMgr().Get(kTestKey, read_value, sizeof(read_value), &read_size)); - ReturnErrorCodeIf(strcmp(kTestValue, read_value) != 0, CHIP_ERROR_INTERNAL); - ReturnErrorCodeIf(read_size != sizeof(kTestValue), CHIP_ERROR_INTERNAL); + VerifyOrReturnError(strcmp(kTestValue, read_value) == 0, CHIP_ERROR_INTERNAL); + VerifyOrReturnError(read_size == sizeof(kTestValue), CHIP_ERROR_INTERNAL); ReturnErrorOnFailure(KeyValueStoreMgr().Delete(kTestKey)); return CHIP_NO_ERROR; } @@ -82,7 +82,7 @@ CHIP_ERROR TestUint32() uint32_t read_value; ReturnErrorOnFailure(KeyValueStoreMgr().Put(kTestKey, kTestValue)); ReturnErrorOnFailure(KeyValueStoreMgr().Get(kTestKey, &read_value)); - ReturnErrorCodeIf(kTestValue != read_value, CHIP_ERROR_INTERNAL); + VerifyOrReturnError(kTestValue == read_value, CHIP_ERROR_INTERNAL); ReturnErrorOnFailure(KeyValueStoreMgr().Delete(kTestKey)); return CHIP_NO_ERROR; } @@ -94,7 +94,7 @@ CHIP_ERROR TestArray() uint32_t read_value[5]; ReturnErrorOnFailure(KeyValueStoreMgr().Put(kTestKey, kTestValue)); ReturnErrorOnFailure(KeyValueStoreMgr().Get(kTestKey, &read_value)); - ReturnErrorCodeIf(memcmp(kTestValue, read_value, sizeof(kTestValue)) != 0, CHIP_ERROR_INTERNAL); + VerifyOrReturnError(memcmp(kTestValue, read_value, sizeof(kTestValue)) == 0, CHIP_ERROR_INTERNAL); ReturnErrorOnFailure(KeyValueStoreMgr().Delete(kTestKey)); return CHIP_NO_ERROR; } @@ -111,8 +111,8 @@ CHIP_ERROR TestStruct() SomeStruct read_value; ReturnErrorOnFailure(KeyValueStoreMgr().Put(kTestKey, kTestValue)); ReturnErrorOnFailure(KeyValueStoreMgr().Get(kTestKey, &read_value)); - ReturnErrorCodeIf(kTestValue.value1 != read_value.value1, CHIP_ERROR_INTERNAL); - ReturnErrorCodeIf(kTestValue.value2 != read_value.value2, CHIP_ERROR_INTERNAL); + VerifyOrReturnError(kTestValue.value1 == read_value.value1, CHIP_ERROR_INTERNAL); + VerifyOrReturnError(kTestValue.value2 == read_value.value2, CHIP_ERROR_INTERNAL); ReturnErrorOnFailure(KeyValueStoreMgr().Delete(kTestKey)); return CHIP_NO_ERROR; } @@ -125,7 +125,7 @@ CHIP_ERROR TestUpdateValue() { ReturnErrorOnFailure(KeyValueStoreMgr().Put(kTestKey, i)); ReturnErrorOnFailure(KeyValueStoreMgr().Get(kTestKey, &read_value)); - ReturnErrorCodeIf(i != read_value, CHIP_ERROR_INTERNAL); + VerifyOrReturnError(i == read_value, CHIP_ERROR_INTERNAL); } ReturnErrorOnFailure(KeyValueStoreMgr().Delete(kTestKey)); return CHIP_NO_ERROR; @@ -142,9 +142,9 @@ CHIP_ERROR TestMultiRead() size_t read_size; // Returns buffer too small for all but the last read. CHIP_ERROR error = KeyValueStoreMgr().Get(kTestKey, &read_value, sizeof(read_value), &read_size, i * sizeof(uint32_t)); - ReturnErrorCodeIf(error != (i < 4 ? CHIP_ERROR_BUFFER_TOO_SMALL : CHIP_NO_ERROR), error); - ReturnErrorCodeIf(read_size != sizeof(read_value), CHIP_ERROR_INTERNAL); - ReturnErrorCodeIf(kTestValue[i] != read_value, CHIP_ERROR_INTERNAL); + VerifyOrReturnError(error == (i < 4 ? CHIP_ERROR_BUFFER_TOO_SMALL : CHIP_NO_ERROR), error); + VerifyOrReturnError(read_size == sizeof(read_value), CHIP_ERROR_INTERNAL); + VerifyOrReturnError(kTestValue[i] == read_value, CHIP_ERROR_INTERNAL); } ReturnErrorOnFailure(KeyValueStoreMgr().Delete(kTestKey)); return CHIP_NO_ERROR; diff --git a/examples/platform/cc13x4_26x4/CC13X4_26X4DeviceAttestationCreds.cpp b/examples/platform/cc13x4_26x4/CC13X4_26X4DeviceAttestationCreds.cpp index 2cd36b6a14e93f..18b5890e9d156e 100644 --- a/examples/platform/cc13x4_26x4/CC13X4_26X4DeviceAttestationCreds.cpp +++ b/examples/platform/cc13x4_26x4/CC13X4_26X4DeviceAttestationCreds.cpp @@ -218,8 +218,8 @@ CHIP_ERROR DeviceAttestationCredsCC13X4_26X4::GetFirmwareInformation(MutableByte CHIP_ERROR DeviceAttestationCredsCC13X4_26X4::GetDeviceAttestationCert(MutableByteSpan & out_buffer) { - ReturnErrorCodeIf(out_buffer.size() < mFactoryData->dac_cert.len, CHIP_ERROR_BUFFER_TOO_SMALL); - ReturnErrorCodeIf(!mFactoryData->dac_cert.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + VerifyOrReturnError(out_buffer.size() >= mFactoryData->dac_cert.len, CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(mFactoryData->dac_cert.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); return CopySpanToMutableSpan(ByteSpan{ mFactoryData->dac_cert.data, mFactoryData->dac_cert.len }, out_buffer); return CHIP_NO_ERROR; @@ -227,8 +227,8 @@ CHIP_ERROR DeviceAttestationCredsCC13X4_26X4::GetDeviceAttestationCert(MutableBy CHIP_ERROR DeviceAttestationCredsCC13X4_26X4::GetProductAttestationIntermediateCert(MutableByteSpan & out_buffer) { - ReturnErrorCodeIf(out_buffer.size() < mFactoryData->pai_cert.len, CHIP_ERROR_BUFFER_TOO_SMALL); - ReturnErrorCodeIf(!mFactoryData->pai_cert.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + VerifyOrReturnError(out_buffer.size() >= mFactoryData->pai_cert.len, CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(mFactoryData->pai_cert.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); return CopySpanToMutableSpan(ByteSpan{ mFactoryData->pai_cert.data, mFactoryData->pai_cert.len }, out_buffer); } diff --git a/examples/platform/cc32xx/CC32XXDeviceAttestationCreds.cpp b/examples/platform/cc32xx/CC32XXDeviceAttestationCreds.cpp index 0323e3b7ed39b1..2e85c0b69a3b25 100644 --- a/examples/platform/cc32xx/CC32XXDeviceAttestationCreds.cpp +++ b/examples/platform/cc32xx/CC32XXDeviceAttestationCreds.cpp @@ -349,8 +349,8 @@ CHIP_ERROR DeviceAttestationCredsCC32XX::GetFirmwareInformation(MutableByteSpan CHIP_ERROR DeviceAttestationCredsCC32XX::GetDeviceAttestationCert(MutableByteSpan & out_buffer) { - ReturnErrorCodeIf(out_buffer.size() < mFactoryData->dac_cert.len, CHIP_ERROR_BUFFER_TOO_SMALL); - ReturnErrorCodeIf(!mFactoryData->dac_cert.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + VerifyOrReturnError(out_buffer.size() >= mFactoryData->dac_cert.len, CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(mFactoryData->dac_cert.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); return CopySpanToMutableSpan(ByteSpan{ mFactoryData->dac_cert.data, mFactoryData->dac_cert.len }, out_buffer); return CHIP_NO_ERROR; @@ -358,8 +358,8 @@ CHIP_ERROR DeviceAttestationCredsCC32XX::GetDeviceAttestationCert(MutableByteSpa CHIP_ERROR DeviceAttestationCredsCC32XX::GetProductAttestationIntermediateCert(MutableByteSpan & out_buffer) { - ReturnErrorCodeIf(out_buffer.size() < mFactoryData->pai_cert.len, CHIP_ERROR_BUFFER_TOO_SMALL); - ReturnErrorCodeIf(!mFactoryData->pai_cert.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + VerifyOrReturnError(out_buffer.size() >= mFactoryData->pai_cert.len, CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(mFactoryData->pai_cert.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); return CopySpanToMutableSpan(ByteSpan{ mFactoryData->pai_cert.data, mFactoryData->pai_cert.len }, out_buffer); } diff --git a/examples/platform/silabs/SiWx917/SiWx917/sl_wifi_if.cpp b/examples/platform/silabs/SiWx917/SiWx917/sl_wifi_if.cpp index 9dd91a44061799..d3572289eb7f30 100644 --- a/examples/platform/silabs/SiWx917/SiWx917/sl_wifi_if.cpp +++ b/examples/platform/silabs/SiWx917/SiWx917/sl_wifi_if.cpp @@ -619,7 +619,7 @@ static void wfx_rsi_save_ap_info(void) // translation **********************************************************************************************/ static sl_status_t wfx_rsi_do_join(void) { - ReturnErrorCodeIf((wfx_rsi.dev_state & (WFX_RSI_ST_STA_CONNECTING | WFX_RSI_ST_STA_CONNECTED)), SL_STATUS_IN_PROGRESS); + VerifyOrReturnError(!(wfx_rsi.dev_state & (WFX_RSI_ST_STA_CONNECTING | WFX_RSI_ST_STA_CONNECTED)), SL_STATUS_IN_PROGRESS); sl_status_t status = SL_STATUS_OK; sl_wifi_client_configuration_t ap; memset(&ap, 0, sizeof(ap)); @@ -680,7 +680,7 @@ static sl_status_t wfx_rsi_do_join(void) status = sl_wifi_connect(SL_WIFI_CLIENT_INTERFACE, &ap, timeout_ms); // sl_wifi_connect returns SL_STATUS_IN_PROGRESS if join is in progress // after the initial scan is done, the scan does not check for SSID - ReturnErrorCodeIf((status == SL_STATUS_OK || status == SL_STATUS_IN_PROGRESS), status); + VerifyOrReturnError(status != SL_STATUS_OK && status != SL_STATUS_IN_PROGRESS, status); // failure only happens when the firmware returns an error ChipLogError(DeviceLayer, "wfx_rsi_do_join: sl_wifi_connect failed: 0x%lx", static_cast(status)); diff --git a/examples/platform/silabs/provision/ProvisionStorageFlash.cpp b/examples/platform/silabs/provision/ProvisionStorageFlash.cpp index af59d6560cd0fc..abca012e361b13 100644 --- a/examples/platform/silabs/provision/ProvisionStorageFlash.cpp +++ b/examples/platform/silabs/provision/ProvisionStorageFlash.cpp @@ -78,7 +78,7 @@ CHIP_ERROR DecodeTotal(Encoding::Buffer & reader, uint16_t & total) ReturnErrorOnFailure(reader.Get(sz)); total = (0xffff == sz) ? sizeof(uint16_t) : sz; reader.in = reader.begin + total; - ReturnErrorCodeIf(reader.in > reader.end, CHIP_ERROR_INTERNAL); + VerifyOrReturnError(reader.in <= reader.end, CHIP_ERROR_INTERNAL); return CHIP_NO_ERROR; } @@ -118,7 +118,7 @@ CHIP_ERROR Set(uint16_t id, Encoding::Buffer & in) { // New entry size_t temp_total = found.offset; - ReturnErrorCodeIf(temp_total + in.Size() > kPageSize, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(temp_total + in.Size() <= kPageSize, CHIP_ERROR_INVALID_ARGUMENT); // Copy entry ReturnErrorOnFailure(in.Get(page + temp_total, in.Size())); // Update total @@ -138,7 +138,7 @@ CHIP_ERROR Set(uint16_t id, Encoding::Buffer & in) { // Size change, move to the end uint16_t temp_total = total - found.encoded_size; - ReturnErrorCodeIf(temp_total + in.Size() > kPageSize, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(temp_total + in.Size() <= kPageSize, CHIP_ERROR_INVALID_ARGUMENT); // Remove the entry memmove(page + found.offset, page + found.offset + found.encoded_size, temp_total); // Add the entry diff --git a/examples/tv-casting-app/tv-casting-common/include/MediaCommandBase.h b/examples/tv-casting-app/tv-casting-common/include/MediaCommandBase.h index 87ddf70ef2effd..d3d03b1a2402fb 100644 --- a/examples/tv-casting-app/tv-casting-common/include/MediaCommandBase.h +++ b/examples/tv-casting-app/tv-casting-common/include/MediaCommandBase.h @@ -32,7 +32,7 @@ class MediaCommandBase : public MediaBase VerifyOrDieWithMsg(mTargetVideoPlayerInfo != nullptr, AppServer, "Target unknown"); auto deviceProxy = mTargetVideoPlayerInfo->GetOperationalDeviceProxy(); - ReturnErrorCodeIf(deviceProxy == nullptr || !deviceProxy->ConnectionReady(), CHIP_ERROR_PEER_NODE_NOT_FOUND); + VerifyOrReturnError(deviceProxy != nullptr && deviceProxy->ConnectionReady(), CHIP_ERROR_PEER_NODE_NOT_FOUND); sResponseCallback = responseCallback; diff --git a/examples/tv-casting-app/tv-casting-common/include/MediaReadBase.h b/examples/tv-casting-app/tv-casting-common/include/MediaReadBase.h index e7e99e3d7ec662..ba896739d6d5b0 100644 --- a/examples/tv-casting-app/tv-casting-common/include/MediaReadBase.h +++ b/examples/tv-casting-app/tv-casting-common/include/MediaReadBase.h @@ -32,7 +32,7 @@ class MediaReadBase : public MediaBase VerifyOrDieWithMsg(mTargetVideoPlayerInfo != nullptr, AppServer, "Target unknown"); auto deviceProxy = mTargetVideoPlayerInfo->GetOperationalDeviceProxy(); - ReturnErrorCodeIf(deviceProxy == nullptr || !deviceProxy->ConnectionReady(), CHIP_ERROR_PEER_NODE_NOT_FOUND); + VerifyOrReturnError(deviceProxy != nullptr && deviceProxy->ConnectionReady(), CHIP_ERROR_PEER_NODE_NOT_FOUND); MediaClusterBase cluster(*deviceProxy->GetExchangeManager(), deviceProxy->GetSecureSession().Value(), mTvEndpoint); diff --git a/examples/tv-casting-app/tv-casting-common/include/MediaSubscriptionBase.h b/examples/tv-casting-app/tv-casting-common/include/MediaSubscriptionBase.h index 65b91b175f7b9d..caf6e5da71b39f 100644 --- a/examples/tv-casting-app/tv-casting-common/include/MediaSubscriptionBase.h +++ b/examples/tv-casting-app/tv-casting-common/include/MediaSubscriptionBase.h @@ -33,7 +33,7 @@ class MediaSubscriptionBase : public MediaBase VerifyOrDieWithMsg(mTargetVideoPlayerInfo != nullptr, AppServer, "Target unknown"); auto deviceProxy = mTargetVideoPlayerInfo->GetOperationalDeviceProxy(); - ReturnErrorCodeIf(deviceProxy == nullptr || !deviceProxy->ConnectionReady(), CHIP_ERROR_PEER_NODE_NOT_FOUND); + VerifyOrReturnError(deviceProxy != nullptr && deviceProxy->ConnectionReady(), CHIP_ERROR_PEER_NODE_NOT_FOUND); MediaClusterBase cluster(*deviceProxy->GetExchangeManager(), deviceProxy->GetSecureSession().Value(), mTvEndpoint); diff --git a/src/access/AccessControl.cpp b/src/access/AccessControl.cpp index c9da05e51038cc..ba149a6a225b54 100644 --- a/src/access/AccessControl.cpp +++ b/src/access/AccessControl.cpp @@ -232,7 +232,7 @@ CHIP_ERROR AccessControl::CreateEntry(const SubjectDescriptor * subjectDescripto VerifyOrReturnError((count + 1) <= maxCount, CHIP_ERROR_BUFFER_TOO_SMALL); - ReturnErrorCodeIf(!IsValid(entry), CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(IsValid(entry), CHIP_ERROR_INVALID_ARGUMENT); size_t i = 0; ReturnErrorOnFailure(mDelegate->CreateEntry(&i, entry, &fabric)); @@ -250,7 +250,7 @@ CHIP_ERROR AccessControl::UpdateEntry(const SubjectDescriptor * subjectDescripto const Entry & entry) { VerifyOrReturnError(IsInitialized(), CHIP_ERROR_INCORRECT_STATE); - ReturnErrorCodeIf(!IsValid(entry), CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(IsValid(entry), CHIP_ERROR_INVALID_ARGUMENT); ReturnErrorOnFailure(mDelegate->UpdateEntry(index, entry, &fabric)); NotifyEntryChanged(subjectDescriptor, fabric, index, &entry, EntryListener::ChangeType::kUpdated); return CHIP_NO_ERROR; diff --git a/src/access/AccessControl.h b/src/access/AccessControl.h index df986864b8ff4c..638c8d71f8f50a 100644 --- a/src/access/AccessControl.h +++ b/src/access/AccessControl.h @@ -501,7 +501,7 @@ class AccessControl */ CHIP_ERROR CreateEntry(size_t * index, const Entry & entry, FabricIndex * fabricIndex = nullptr) { - ReturnErrorCodeIf(!IsValid(entry), CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(IsValid(entry), CHIP_ERROR_INVALID_ARGUMENT); VerifyOrReturnError(IsInitialized(), CHIP_ERROR_INCORRECT_STATE); return mDelegate->CreateEntry(index, entry, fabricIndex); } @@ -551,7 +551,7 @@ class AccessControl */ CHIP_ERROR UpdateEntry(size_t index, const Entry & entry, const FabricIndex * fabricIndex = nullptr) { - ReturnErrorCodeIf(!IsValid(entry), CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(IsValid(entry), CHIP_ERROR_INVALID_ARGUMENT); VerifyOrReturnError(IsInitialized(), CHIP_ERROR_INCORRECT_STATE); return mDelegate->UpdateEntry(index, entry, fabricIndex); } diff --git a/src/access/examples/ExampleAccessControlDelegate.cpp b/src/access/examples/ExampleAccessControlDelegate.cpp index fc1c1b710deba4..9297740bf889ee 100644 --- a/src/access/examples/ExampleAccessControlDelegate.cpp +++ b/src/access/examples/ExampleAccessControlDelegate.cpp @@ -909,7 +909,7 @@ CHIP_ERROR CopyViaInterface(const Entry & entry, EntryStorage & storage) size_t subjectCount = 0; ReturnErrorOnFailure(entry.GetSubjectCount(subjectCount)); - ReturnErrorCodeIf(subjectCount > EntryStorage::kMaxSubjects, CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(subjectCount <= EntryStorage::kMaxSubjects, CHIP_ERROR_BUFFER_TOO_SMALL); for (size_t i = 0; i < subjectCount; ++i) { NodeId subject = kUndefinedNodeId; @@ -919,7 +919,7 @@ CHIP_ERROR CopyViaInterface(const Entry & entry, EntryStorage & storage) size_t targetCount = 0; ReturnErrorOnFailure(entry.GetTargetCount(targetCount)); - ReturnErrorCodeIf(targetCount > EntryStorage::kMaxTargets, CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(targetCount <= EntryStorage::kMaxTargets, CHIP_ERROR_BUFFER_TOO_SMALL); for (size_t i = 0; i < targetCount; ++i) { Target target; diff --git a/src/access/tests/TestAccessControl.cpp b/src/access/tests/TestAccessControl.cpp index 00b95baf39164b..b528d4a3bc3b79 100644 --- a/src/access/tests/TestAccessControl.cpp +++ b/src/access/tests/TestAccessControl.cpp @@ -662,30 +662,30 @@ CHIP_ERROR CompareEntry(const Entry & entry, const EntryData & entryData) { AuthMode authMode = AuthMode::kNone; ReturnErrorOnFailure(entry.GetAuthMode(authMode)); - ReturnErrorCodeIf(authMode != entryData.authMode, CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(authMode == entryData.authMode, CHIP_ERROR_INCORRECT_STATE); FabricIndex fabricIndex = kUndefinedFabricIndex; ReturnErrorOnFailure(entry.GetFabricIndex(fabricIndex)); - ReturnErrorCodeIf(fabricIndex != entryData.fabricIndex, CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(fabricIndex == entryData.fabricIndex, CHIP_ERROR_INCORRECT_STATE); Privilege privilege = Privilege::kView; ReturnErrorOnFailure(entry.GetPrivilege(privilege)); - ReturnErrorCodeIf(privilege != entryData.privilege, CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(privilege == entryData.privilege, CHIP_ERROR_INCORRECT_STATE); size_t subjectCount = 0; ReturnErrorOnFailure(entry.GetSubjectCount(subjectCount)); - ReturnErrorCodeIf(subjectCount != entryData.GetSubjectCount(), CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(subjectCount == entryData.GetSubjectCount(), CHIP_ERROR_INCORRECT_STATE); for (size_t i = 0; i < subjectCount; ++i) { NodeId subject = kUndefinedNodeId; ReturnErrorOnFailure(entry.GetSubject(i, subject)); - ReturnErrorCodeIf(subject != entryData.subjects[i], CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(subject == entryData.subjects[i], CHIP_ERROR_INCORRECT_STATE); } size_t targetCount = 0; ReturnErrorOnFailure(entry.GetTargetCount(targetCount)); - ReturnErrorCodeIf(targetCount != entryData.GetTargetCount(), CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(targetCount == entryData.GetTargetCount(), CHIP_ERROR_INCORRECT_STATE); for (size_t i = 0; i < targetCount; ++i) { Target target; ReturnErrorOnFailure(entry.GetTarget(i, target)); - ReturnErrorCodeIf(target != entryData.targets[i], CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(target == entryData.targets[i], CHIP_ERROR_INCORRECT_STATE); } return CHIP_NO_ERROR; } @@ -724,7 +724,7 @@ CHIP_ERROR CompareAccessControl(AccessControl & ac, const EntryData * entryData, ReturnErrorOnFailure(ac.ReadEntry(i, entry)); ReturnErrorOnFailure(CompareEntry(entry, *entryData)); } - ReturnErrorCodeIf(ac.ReadEntry(count, entry) == CHIP_NO_ERROR, CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(ac.ReadEntry(count, entry) != CHIP_NO_ERROR, CHIP_ERROR_INCORRECT_STATE); return CHIP_NO_ERROR; } diff --git a/src/app/CASEClient.h b/src/app/CASEClient.h index 7ef968d544165f..2cb43498f6de22 100644 --- a/src/app/CASEClient.h +++ b/src/app/CASEClient.h @@ -44,10 +44,10 @@ struct CASEClientInitParams { // sessionResumptionStorage can be nullptr when resumption is disabled. // certificateValidityPolicy is optional, too. - ReturnErrorCodeIf(sessionManager == nullptr, CHIP_ERROR_INCORRECT_STATE); - ReturnErrorCodeIf(exchangeMgr == nullptr, CHIP_ERROR_INCORRECT_STATE); - ReturnErrorCodeIf(fabricTable == nullptr, CHIP_ERROR_INCORRECT_STATE); - ReturnErrorCodeIf(groupDataProvider == nullptr, CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(sessionManager != nullptr, CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(exchangeMgr != nullptr, CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(fabricTable != nullptr, CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(groupDataProvider != nullptr, CHIP_ERROR_INCORRECT_STATE); return CHIP_NO_ERROR; } diff --git a/src/app/CASESessionManager.cpp b/src/app/CASESessionManager.cpp index fa22748a50feff..766e60115df829 100644 --- a/src/app/CASESessionManager.cpp +++ b/src/app/CASESessionManager.cpp @@ -146,7 +146,7 @@ CHIP_ERROR CASESessionManager::GetPeerAddress(const ScopedNodeId & peerId, Trans { ReturnErrorOnFailure(mConfig.sessionInitParams.Validate()); auto optionalSessionHandle = FindExistingSession(peerId, transportPayloadCapability); - ReturnErrorCodeIf(!optionalSessionHandle.HasValue(), CHIP_ERROR_NOT_CONNECTED); + VerifyOrReturnError(optionalSessionHandle.HasValue(), CHIP_ERROR_NOT_CONNECTED); addr = optionalSessionHandle.Value()->AsSecureSession()->GetPeerAddress(); return CHIP_NO_ERROR; } diff --git a/src/app/DeferredAttributePersistenceProvider.cpp b/src/app/DeferredAttributePersistenceProvider.cpp index 9480fba14e9c8e..26adcb18c8dcf7 100644 --- a/src/app/DeferredAttributePersistenceProvider.cpp +++ b/src/app/DeferredAttributePersistenceProvider.cpp @@ -28,7 +28,7 @@ CHIP_ERROR DeferredAttribute::PrepareWrite(System::Clock::Timestamp flushTime, c if (mValue.AllocatedSize() != value.size()) { mValue.Alloc(value.size()); - ReturnErrorCodeIf(!mValue, CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(mValue, CHIP_ERROR_NO_MEMORY); } memcpy(mValue.Get(), value.data(), value.size()); diff --git a/src/app/EventManagement.cpp b/src/app/EventManagement.cpp index 271f72ec107f3b..4c01bedf4b9a5b 100644 --- a/src/app/EventManagement.cpp +++ b/src/app/EventManagement.cpp @@ -563,9 +563,9 @@ CHIP_ERROR EventManagement::CheckEventContext(EventLoadOutContext * eventLoadOut Access::GetAccessControl().Check(eventLoadOutContext->mSubjectDescriptor, requestPath, requestPrivilege); if (accessControlError != CHIP_NO_ERROR) { - ReturnErrorCodeIf((accessControlError != CHIP_ERROR_ACCESS_DENIED) && - (accessControlError != CHIP_ERROR_ACCESS_RESTRICTED_BY_ARL), - accessControlError); + VerifyOrReturnError((accessControlError == CHIP_ERROR_ACCESS_DENIED) || + (accessControlError == CHIP_ERROR_ACCESS_RESTRICTED_BY_ARL), + accessControlError); ret = CHIP_ERROR_UNEXPECTED_EVENT; } diff --git a/src/app/InteractionModelEngine.cpp b/src/app/InteractionModelEngine.cpp index 6f326b5fdb4842..269cc7f9158ee3 100644 --- a/src/app/InteractionModelEngine.cpp +++ b/src/app/InteractionModelEngine.cpp @@ -756,8 +756,8 @@ Protocols::InteractionModel::Status InteractionModelEngine::OnReadInitialRequest { TLV::TLVReader pathReader; attributePathListParser.GetReader(&pathReader); - ReturnErrorCodeIf(TLV::Utilities::Count(pathReader, requestedAttributePathCount, false) != CHIP_NO_ERROR, - Status::InvalidAction); + VerifyOrReturnError(TLV::Utilities::Count(pathReader, requestedAttributePathCount, false) == CHIP_NO_ERROR, + Status::InvalidAction); } else if (err != CHIP_ERROR_END_OF_TLV) { @@ -769,8 +769,8 @@ Protocols::InteractionModel::Status InteractionModelEngine::OnReadInitialRequest { TLV::TLVReader pathReader; eventpathListParser.GetReader(&pathReader); - ReturnErrorCodeIf(TLV::Utilities::Count(pathReader, requestedEventPathCount, false) != CHIP_NO_ERROR, - Status::InvalidAction); + VerifyOrReturnError(TLV::Utilities::Count(pathReader, requestedEventPathCount, false) == CHIP_NO_ERROR, + Status::InvalidAction); } else if (err != CHIP_ERROR_END_OF_TLV) { @@ -1988,9 +1988,9 @@ void InteractionModelEngine::OnFabricRemoved(const FabricTable & fabricTable, Fa CHIP_ERROR InteractionModelEngine::ResumeSubscriptions() { #if CHIP_CONFIG_PERSIST_SUBSCRIPTIONS - ReturnErrorCodeIf(!mpSubscriptionResumptionStorage, CHIP_NO_ERROR); + VerifyOrReturnError(mpSubscriptionResumptionStorage, CHIP_NO_ERROR); #if CHIP_CONFIG_SUBSCRIPTION_TIMEOUT_RESUMPTION - ReturnErrorCodeIf(mSubscriptionResumptionScheduled, CHIP_NO_ERROR); + VerifyOrReturnError(!mSubscriptionResumptionScheduled, CHIP_NO_ERROR); #endif // To avoid the case of a reboot loop causing rapid traffic generation / power consumption, subscription resumption should make diff --git a/src/app/OperationalSessionSetup.cpp b/src/app/OperationalSessionSetup.cpp index a0af8fa3d00ecf..6b9b894314bd81 100644 --- a/src/app/OperationalSessionSetup.cpp +++ b/src/app/OperationalSessionSetup.cpp @@ -318,7 +318,7 @@ CHIP_ERROR OperationalSessionSetup::EstablishConnection(const ResolveResult & re #endif mCASEClient = mClientPool->Allocate(); - ReturnErrorCodeIf(mCASEClient == nullptr, CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(mCASEClient != nullptr, CHIP_ERROR_NO_MEMORY); MATTER_LOG_METRIC_BEGIN(kMetricDeviceCASESession); CHIP_ERROR err = mCASEClient->EstablishSession(mInitParams, mPeerId, mDeviceAddress, config, this); diff --git a/src/app/SimpleSubscriptionResumptionStorage.cpp b/src/app/SimpleSubscriptionResumptionStorage.cpp index e233c18af9218a..0818a758236b3d 100644 --- a/src/app/SimpleSubscriptionResumptionStorage.cpp +++ b/src/app/SimpleSubscriptionResumptionStorage.cpp @@ -143,7 +143,7 @@ CHIP_ERROR SimpleSubscriptionResumptionStorage::Load(uint16_t subscriptionIndex, { Platform::ScopedMemoryBuffer backingBuffer; backingBuffer.Calloc(MaxSubscriptionSize()); - ReturnErrorCodeIf(backingBuffer.Get() == nullptr, CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(backingBuffer.Get() != nullptr, CHIP_ERROR_NO_MEMORY); uint16_t len = static_cast(MaxSubscriptionSize()); ReturnErrorOnFailure(mStorage->SyncGetKeyValue(DefaultStorageKeyAllocator::SubscriptionResumption(subscriptionIndex).KeyName(), @@ -193,7 +193,7 @@ CHIP_ERROR SimpleSubscriptionResumptionStorage::Load(uint16_t subscriptionIndex, if (pathCount) { subscriptionInfo.mAttributePaths.Calloc(pathCount); - ReturnErrorCodeIf(subscriptionInfo.mAttributePaths.Get() == nullptr, CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(subscriptionInfo.mAttributePaths.Get() != nullptr, CHIP_ERROR_NO_MEMORY); for (size_t pathIndex = 0; pathIndex < pathCount; pathIndex++) { ReturnErrorOnFailure(reader.Next(TLV::kTLVType_Structure, kAttributePathTag)); @@ -226,7 +226,7 @@ CHIP_ERROR SimpleSubscriptionResumptionStorage::Load(uint16_t subscriptionIndex, if (pathCount) { subscriptionInfo.mEventPaths.Calloc(pathCount); - ReturnErrorCodeIf(subscriptionInfo.mEventPaths.Get() == nullptr, CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(subscriptionInfo.mEventPaths.Get() != nullptr, CHIP_ERROR_NO_MEMORY); for (size_t pathIndex = 0; pathIndex < pathCount; pathIndex++) { ReturnErrorOnFailure(reader.Next(TLV::kTLVType_Structure, kEventPathTag)); @@ -371,7 +371,7 @@ CHIP_ERROR SimpleSubscriptionResumptionStorage::Save(SubscriptionInfo & subscrip // Now construct subscription state and save Platform::ScopedMemoryBuffer backingBuffer; backingBuffer.Calloc(MaxSubscriptionSize()); - ReturnErrorCodeIf(backingBuffer.Get() == nullptr, CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(backingBuffer.Get() != nullptr, CHIP_ERROR_NO_MEMORY); TLV::ScopedBufferTLVWriter writer(std::move(backingBuffer), MaxSubscriptionSize()); diff --git a/src/app/SubscriptionResumptionStorage.h b/src/app/SubscriptionResumptionStorage.h index 74158ecfd395f8..23a06c91e3bced 100644 --- a/src/app/SubscriptionResumptionStorage.h +++ b/src/app/SubscriptionResumptionStorage.h @@ -95,9 +95,9 @@ class SubscriptionResumptionStorage attributePathCount++; attributePath = attributePath->mpNext; } - ReturnErrorCodeIf((attributePathCount * sizeof(AttributePathParamsValues)) > UINT16_MAX, CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError((attributePathCount * sizeof(AttributePathParamsValues)) <= UINT16_MAX, CHIP_ERROR_NO_MEMORY); mAttributePaths.Calloc(attributePathCount); - ReturnErrorCodeIf(mAttributePaths.Get() == nullptr, CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(mAttributePaths.Get() != nullptr, CHIP_ERROR_NO_MEMORY); attributePath = pAttributePathList; for (size_t i = 0; i < attributePathCount; i++) { @@ -120,9 +120,9 @@ class SubscriptionResumptionStorage eventPathCount++; eventPath = eventPath->mpNext; } - ReturnErrorCodeIf((eventPathCount * sizeof(EventPathParamsValues)) > UINT16_MAX, CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError((eventPathCount * sizeof(EventPathParamsValues)) <= UINT16_MAX, CHIP_ERROR_NO_MEMORY); mEventPaths.Calloc(eventPathCount); - ReturnErrorCodeIf(mEventPaths.Get() == nullptr, CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(mEventPaths.Get() != nullptr, CHIP_ERROR_NO_MEMORY); eventPath = pEventPathList; for (size_t i = 0; i < eventPathCount; i++) { diff --git a/src/app/WriteClient.cpp b/src/app/WriteClient.cpp index da24d058f1c40a..0f1aef9f748885 100644 --- a/src/app/WriteClient.cpp +++ b/src/app/WriteClient.cpp @@ -142,7 +142,7 @@ CHIP_ERROR WriteClient::FinalizeMessage(bool aHasMoreChunks) VerifyOrReturnError(mState == State::AddAttribute, CHIP_ERROR_INCORRECT_STATE); TLV::TLVWriter * writer = mWriteRequestBuilder.GetWriter(); - ReturnErrorCodeIf(writer == nullptr, CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(writer != nullptr, CHIP_ERROR_INCORRECT_STATE); ReturnErrorOnFailure(writer->UnreserveBuffer(kReservedSizeForTLVEncodingOverhead)); ReturnErrorOnFailure(mWriteRequestBuilder.GetWriteRequests().EndOfAttributeDataIBs()); diff --git a/src/app/WriteHandler.cpp b/src/app/WriteHandler.cpp index 011fd2e46b48ab..67a5c7a3ac99d9 100644 --- a/src/app/WriteHandler.cpp +++ b/src/app/WriteHandler.cpp @@ -344,7 +344,7 @@ CHIP_ERROR WriteHandler::ProcessAttributeDataIBs(TLV::TLVReader & aAttributeData { CHIP_ERROR err = CHIP_NO_ERROR; - ReturnErrorCodeIf(!mExchangeCtx, CHIP_ERROR_INTERNAL); + VerifyOrReturnError(mExchangeCtx, CHIP_ERROR_INTERNAL); const Access::SubjectDescriptor subjectDescriptor = mExchangeCtx->GetSessionHandle()->GetSubjectDescriptor(); while (CHIP_NO_ERROR == (err = aAttributeDataIBsReader.Next())) @@ -446,7 +446,7 @@ CHIP_ERROR WriteHandler::ProcessGroupAttributeDataIBs(TLV::TLVReader & aAttribut { CHIP_ERROR err = CHIP_NO_ERROR; - ReturnErrorCodeIf(!mExchangeCtx, CHIP_ERROR_INTERNAL); + VerifyOrReturnError(mExchangeCtx, CHIP_ERROR_INTERNAL); const Access::SubjectDescriptor subjectDescriptor = mExchangeCtx->GetSessionHandle()->AsIncomingGroupSession()->GetSubjectDescriptor(); diff --git a/src/app/clusters/access-control-server/access-control-server.cpp b/src/app/clusters/access-control-server/access-control-server.cpp index f6a47fb96dca12..e4c5688e6a9805 100644 --- a/src/app/clusters/access-control-server/access-control-server.cpp +++ b/src/app/clusters/access-control-server/access-control-server.cpp @@ -215,7 +215,7 @@ CHIP_ERROR AccessControlAttribute::ReadAcl(AttributeValueEncoder & aEncoder) { ReturnErrorOnFailure(encoder.Encode(encodableEntry)); } - ReturnErrorCodeIf(err != CHIP_NO_ERROR && err != CHIP_ERROR_SENTINEL, err); + VerifyOrReturnError(err == CHIP_NO_ERROR || err == CHIP_ERROR_SENTINEL, err); } return CHIP_NO_ERROR; }); @@ -233,7 +233,7 @@ CHIP_ERROR AccessControlAttribute::ReadExtension(AttributeValueEncoder & aEncode uint16_t size = static_cast(sizeof(buffer)); CHIP_ERROR errStorage = storage.SyncGetKeyValue( DefaultStorageKeyAllocator::AccessControlExtensionEntry(fabric.GetFabricIndex()).KeyName(), buffer, size); - ReturnErrorCodeIf(errStorage == CHIP_ERROR_BUFFER_TOO_SMALL, CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(errStorage != CHIP_ERROR_BUFFER_TOO_SMALL, CHIP_ERROR_INCORRECT_STATE); if (errStorage == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND) { continue; @@ -333,8 +333,8 @@ CHIP_ERROR AccessControlAttribute::WriteExtension(const ConcreteDataAttributePat uint16_t size = static_cast(sizeof(buffer)); CHIP_ERROR errStorage = storage.SyncGetKeyValue( DefaultStorageKeyAllocator::AccessControlExtensionEntry(accessingFabricIndex).KeyName(), buffer, size); - ReturnErrorCodeIf(errStorage == CHIP_ERROR_BUFFER_TOO_SMALL, CHIP_ERROR_INCORRECT_STATE); - ReturnErrorCodeIf(errStorage != CHIP_NO_ERROR && errStorage != CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND, errStorage); + VerifyOrReturnError(errStorage != CHIP_ERROR_BUFFER_TOO_SMALL, CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(errStorage == CHIP_NO_ERROR || errStorage == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND, errStorage); if (!aPath.IsListItemOperation()) { @@ -346,7 +346,7 @@ CHIP_ERROR AccessControlAttribute::WriteExtension(const ConcreteDataAttributePat if (count == 0) { - ReturnErrorCodeIf(errStorage == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND, CHIP_NO_ERROR); + VerifyOrReturnError(errStorage != CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND, CHIP_NO_ERROR); ReturnErrorOnFailure(storage.SyncDeleteKeyValue( DefaultStorageKeyAllocator::AccessControlExtensionEntry(accessingFabricIndex).KeyName())); AccessControlCluster::Structs::AccessControlExtensionStruct::Type item = { @@ -367,7 +367,7 @@ CHIP_ERROR AccessControlAttribute::WriteExtension(const ConcreteDataAttributePat } auto & item = iterator.GetValue(); // TODO(#13590): generated code doesn't automatically handle max length so do it manually - ReturnErrorCodeIf(item.data.size() > kExtensionDataMaxLength, CHIP_IM_GLOBAL_STATUS(ConstraintError)); + VerifyOrReturnError(item.data.size() <= kExtensionDataMaxLength, CHIP_IM_GLOBAL_STATUS(ConstraintError)); ReturnErrorOnFailure(CheckExtensionEntryDataFormat(item.data)); @@ -386,11 +386,11 @@ CHIP_ERROR AccessControlAttribute::WriteExtension(const ConcreteDataAttributePat } else if (aPath.mListOp == ConcreteDataAttributePath::ListOperation::AppendItem) { - ReturnErrorCodeIf(errStorage != CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND, CHIP_IM_GLOBAL_STATUS(ConstraintError)); + VerifyOrReturnError(errStorage == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND, CHIP_IM_GLOBAL_STATUS(ConstraintError)); AccessControlCluster::Structs::AccessControlExtensionStruct::DecodableType item; ReturnErrorOnFailure(aDecoder.Decode(item)); // TODO(#13590): generated code doesn't automatically handle max length so do it manually - ReturnErrorCodeIf(item.data.size() > kExtensionDataMaxLength, CHIP_IM_GLOBAL_STATUS(ConstraintError)); + VerifyOrReturnError(item.data.size() <= kExtensionDataMaxLength, CHIP_IM_GLOBAL_STATUS(ConstraintError)); ReturnErrorOnFailure(CheckExtensionEntryDataFormat(item.data)); diff --git a/src/app/clusters/bindings/bindings.cpp b/src/app/clusters/bindings/bindings.cpp index 409e667278b081..47e4d4571562f3 100644 --- a/src/app/clusters/bindings/bindings.cpp +++ b/src/app/clusters/bindings/bindings.cpp @@ -114,8 +114,8 @@ CHIP_ERROR CheckValidBindingList(const EndpointId localEndpoint, const Decodable oldListSize++; } } - ReturnErrorCodeIf(BindingTable::GetInstance().Size() - oldListSize + listSize > MATTER_BINDING_TABLE_SIZE, - CHIP_IM_GLOBAL_STATUS(ResourceExhausted)); + VerifyOrReturnError(BindingTable::GetInstance().Size() - oldListSize + listSize <= MATTER_BINDING_TABLE_SIZE, + CHIP_IM_GLOBAL_STATUS(ResourceExhausted)); return CHIP_NO_ERROR; } diff --git a/src/app/clusters/ota-requestor/DefaultOTARequestor.cpp b/src/app/clusters/ota-requestor/DefaultOTARequestor.cpp index edd0b5729c2708..e8352d890d7f21 100644 --- a/src/app/clusters/ota-requestor/DefaultOTARequestor.cpp +++ b/src/app/clusters/ota-requestor/DefaultOTARequestor.cpp @@ -593,7 +593,7 @@ CHIP_ERROR DefaultOTARequestor::ClearDefaultOtaProviderList(FabricIndex fabricIn CHIP_ERROR error = mDefaultOtaProviderList.Delete(fabricIndex); // Ignore the error if no entry for the associated fabric index has been found. - ReturnErrorCodeIf(error == CHIP_ERROR_NOT_FOUND, CHIP_NO_ERROR); + VerifyOrReturnError(error != CHIP_ERROR_NOT_FOUND, CHIP_NO_ERROR); ReturnErrorOnFailure(error); return mStorage->StoreDefaultProviders(mDefaultOtaProviderList); diff --git a/src/app/clusters/thread-border-router-management-server/thread-border-router-management-server.cpp b/src/app/clusters/thread-border-router-management-server/thread-border-router-management-server.cpp index 6988b83b46ba72..81dc2125e146a5 100644 --- a/src/app/clusters/thread-border-router-management-server/thread-border-router-management-server.cpp +++ b/src/app/clusters/thread-border-router-management-server/thread-border-router-management-server.cpp @@ -126,7 +126,7 @@ Status ServerInstance::HandleSetPendingDatasetRequest(CommandHandlerInterface::H Thread::OperationalDataset pendingDataset; // If any of the parameters in the PendingDataset is invalid, the command SHALL fail with a status code // of INVALID_COMMAND. - ReturnErrorCodeIf(pendingDataset.Init(req.pendingDataset) != CHIP_NO_ERROR, Status::InvalidCommand); + VerifyOrReturnError(pendingDataset.Init(req.pendingDataset) == CHIP_NO_ERROR, Status::InvalidCommand); CHIP_ERROR err = mDelegate->SetPendingDataset(pendingDataset); return StatusIB(err).mStatus; } @@ -363,7 +363,7 @@ void ServerInstance::OnPlatformEventHandler(const DeviceLayer::ChipDeviceEvent * CHIP_ERROR ServerInstance::Init() { - ReturnErrorCodeIf(!mDelegate, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(mDelegate, CHIP_ERROR_INVALID_ARGUMENT); ReturnErrorOnFailure(CommandHandlerInterfaceRegistry::Instance().RegisterCommandHandler(this)); VerifyOrReturnError(chip::app::AttributeAccessInterfaceRegistry::Instance().Register(this), CHIP_ERROR_INCORRECT_STATE); ReturnErrorOnFailure(DeviceLayer::PlatformMgrImpl().AddEventHandler(OnPlatformEventHandler, reinterpret_cast(this))); diff --git a/src/app/clusters/user-label-server/user-label-server.cpp b/src/app/clusters/user-label-server/user-label-server.cpp index 5daae5ab179ac3..e1ea85cf01a78a 100644 --- a/src/app/clusters/user-label-server/user-label-server.cpp +++ b/src/app/clusters/user-label-server/user-label-server.cpp @@ -131,7 +131,7 @@ CHIP_ERROR UserLabelAttrAccess::WriteLabelList(const ConcreteDataAttributePath & LabelList::TypeInfo::DecodableType decodablelist; ReturnErrorOnFailure(aDecoder.Decode(decodablelist)); - ReturnErrorCodeIf(!IsValidLabelEntryList(decodablelist), CHIP_IM_GLOBAL_STATUS(ConstraintError)); + VerifyOrReturnError(IsValidLabelEntryList(decodablelist), CHIP_IM_GLOBAL_STATUS(ConstraintError)); auto iter = decodablelist.begin(); while (iter.Next()) @@ -148,7 +148,7 @@ CHIP_ERROR UserLabelAttrAccess::WriteLabelList(const ConcreteDataAttributePath & Structs::LabelStruct::DecodableType entry; ReturnErrorOnFailure(aDecoder.Decode(entry)); - ReturnErrorCodeIf(!IsValidLabelEntry(entry), CHIP_IM_GLOBAL_STATUS(ConstraintError)); + VerifyOrReturnError(IsValidLabelEntry(entry), CHIP_IM_GLOBAL_STATUS(ConstraintError)); return provider->AppendUserLabel(endpoint, entry); } diff --git a/src/app/codegen-data-model-provider/CodegenDataModelProvider_Read.cpp b/src/app/codegen-data-model-provider/CodegenDataModelProvider_Read.cpp index 82baba4835c8b5..6ce5d282f89d30 100644 --- a/src/app/codegen-data-model-provider/CodegenDataModelProvider_Read.cpp +++ b/src/app/codegen-data-model-provider/CodegenDataModelProvider_Read.cpp @@ -271,7 +271,7 @@ DataModel::ActionReturnStatus CodegenDataModelProvider::ReadAttribute(const Data // ACL check for non-internal requests if (!request.operationFlags.Has(DataModel::OperationFlags::kInternal)) { - ReturnErrorCodeIf(!request.subjectDescriptor.has_value(), CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(request.subjectDescriptor.has_value(), CHIP_ERROR_INVALID_ARGUMENT); Access::RequestPath requestPath{ .cluster = request.path.mClusterId, .endpoint = request.path.mEndpointId, @@ -281,7 +281,7 @@ DataModel::ActionReturnStatus CodegenDataModelProvider::ReadAttribute(const Data RequiredPrivilege::ForReadAttribute(request.path)); if (err != CHIP_NO_ERROR) { - ReturnErrorCodeIf((err != CHIP_ERROR_ACCESS_DENIED) && (err != CHIP_ERROR_ACCESS_RESTRICTED_BY_ARL), err); + VerifyOrReturnError((err == CHIP_ERROR_ACCESS_DENIED) || (err == CHIP_ERROR_ACCESS_RESTRICTED_BY_ARL), err); // Implementation of 8.4.3.2 of the spec for path expansion if (request.path.mExpanded) @@ -319,7 +319,7 @@ DataModel::ActionReturnStatus CodegenDataModelProvider::ReadAttribute(const Data request.path, AttributeAccessInterfaceRegistry::Instance().Get(request.path.mEndpointId, request.path.mClusterId), encoder); } - ReturnErrorCodeIf(aai_result.has_value(), *aai_result); + VerifyOrReturnError(!aai_result.has_value(), *aai_result); if (!std::holds_alternative(metadata)) { diff --git a/src/app/codegen-data-model-provider/CodegenDataModelProvider_Write.cpp b/src/app/codegen-data-model-provider/CodegenDataModelProvider_Write.cpp index 76c283ae04108a..4c46a2a364d16b 100644 --- a/src/app/codegen-data-model-provider/CodegenDataModelProvider_Write.cpp +++ b/src/app/codegen-data-model-provider/CodegenDataModelProvider_Write.cpp @@ -350,7 +350,7 @@ DataModel::ActionReturnStatus CodegenDataModelProvider::WriteAttribute(const Dat if (checkAcl) { - ReturnErrorCodeIf(!request.subjectDescriptor.has_value(), Status::UnsupportedAccess); + VerifyOrReturnError(request.subjectDescriptor.has_value(), Status::UnsupportedAccess); Access::RequestPath requestPath{ .cluster = request.path.mClusterId, .endpoint = request.path.mEndpointId, diff --git a/src/app/icd/client/DefaultICDClientStorage.cpp b/src/app/icd/client/DefaultICDClientStorage.cpp index c50bb621a2dc3a..2a1bc6a5d4fb86 100644 --- a/src/app/icd/client/DefaultICDClientStorage.cpp +++ b/src/app/icd/client/DefaultICDClientStorage.cpp @@ -59,7 +59,7 @@ CHIP_ERROR DefaultICDClientStorage::StoreFabricList() Platform::ScopedMemoryBuffer backingBuffer; size_t counter = mFabricList.size(); size_t total = kFabricIndexTlvSize * counter + kArrayOverHead; - ReturnErrorCodeIf(!backingBuffer.Calloc(total), CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(backingBuffer.Calloc(total), CHIP_ERROR_NO_MEMORY); TLV::ScopedBufferTLVWriter writer(std::move(backingBuffer), total); TLV::TLVType arrayType; @@ -81,7 +81,7 @@ CHIP_ERROR DefaultICDClientStorage::StoreFabricList() CHIP_ERROR DefaultICDClientStorage::LoadFabricList() { Platform::ScopedMemoryBuffer backingBuffer; - ReturnErrorCodeIf(!backingBuffer.Calloc(kMaxFabricListTlvLength), CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(backingBuffer.Calloc(kMaxFabricListTlvLength), CHIP_ERROR_NO_MEMORY); uint16_t length = kMaxFabricListTlvLength; ReturnErrorOnFailure( mpClientInfoStore->SyncGetKeyValue(DefaultStorageKeyAllocator::ICDFabricList().KeyName(), backingBuffer.Get(), length)); @@ -182,7 +182,7 @@ CHIP_ERROR DefaultICDClientStorage::LoadCounter(FabricIndex fabricIndex, size_t Platform::ScopedMemoryBuffer backingBuffer; size_t len = MaxICDCounterSize(); VerifyOrReturnError(CanCastTo(len), CHIP_ERROR_BUFFER_TOO_SMALL); - ReturnErrorCodeIf(!backingBuffer.Calloc(len), CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(backingBuffer.Calloc(len), CHIP_ERROR_NO_MEMORY); uint16_t length = static_cast(len); CHIP_ERROR err = mpClientInfoStore->SyncGetKeyValue( @@ -220,7 +220,7 @@ CHIP_ERROR DefaultICDClientStorage::Load(FabricIndex fabricIndex, std::vector backingBuffer; VerifyOrReturnError(CanCastTo(len), CHIP_ERROR_BUFFER_TOO_SMALL); - ReturnErrorCodeIf(!backingBuffer.Calloc(len), CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(backingBuffer.Calloc(len), CHIP_ERROR_NO_MEMORY); uint16_t length = static_cast(len); CHIP_ERROR err = mpClientInfoStore->SyncGetKeyValue(DefaultStorageKeyAllocator::ICDClientInfoKey(fabricIndex).KeyName(), backingBuffer.Get(), length); @@ -381,7 +381,7 @@ CHIP_ERROR DefaultICDClientStorage::StoreEntry(const ICDClientInfo & clientInfo) clientInfoVector.push_back(clientInfo); size_t total = clientInfoSize * clientInfoVector.size() + kArrayOverHead; Platform::ScopedMemoryBuffer backingBuffer; - ReturnErrorCodeIf(!backingBuffer.Calloc(total), CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(backingBuffer.Calloc(total), CHIP_ERROR_NO_MEMORY); TLV::ScopedBufferTLVWriter writer(std::move(backingBuffer), total); ReturnErrorOnFailure(SerializeToTlv(writer, clientInfoVector)); @@ -428,7 +428,7 @@ CHIP_ERROR DefaultICDClientStorage::UpdateEntryCountForFabric(FabricIndex fabric size_t total = MaxICDCounterSize(); Platform::ScopedMemoryBuffer backingBuffer; - ReturnErrorCodeIf(!backingBuffer.Calloc(total), CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(backingBuffer.Calloc(total), CHIP_ERROR_NO_MEMORY); TLV::ScopedBufferTLVWriter writer(std::move(backingBuffer), total); TLV::TLVType structType; @@ -467,7 +467,7 @@ CHIP_ERROR DefaultICDClientStorage::DeleteEntry(const ScopedNodeId & peerNode) mpClientInfoStore->SyncDeleteKeyValue(DefaultStorageKeyAllocator::ICDClientInfoKey(peerNode.GetFabricIndex()).KeyName())); size_t total = clientInfoSize * clientInfoVector.size() + kArrayOverHead; Platform::ScopedMemoryBuffer backingBuffer; - ReturnErrorCodeIf(!backingBuffer.Calloc(total), CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(backingBuffer.Calloc(total), CHIP_ERROR_NO_MEMORY); TLV::ScopedBufferTLVWriter writer(std::move(backingBuffer), total); ReturnErrorOnFailure(SerializeToTlv(writer, clientInfoVector)); diff --git a/src/app/reporting/Engine.cpp b/src/app/reporting/Engine.cpp index 2dd08739ad8959..45ebdeb7f64c02 100644 --- a/src/app/reporting/Engine.cpp +++ b/src/app/reporting/Engine.cpp @@ -852,7 +852,7 @@ bool Engine::MergeDirtyPathsUnderSameEndpoint() CHIP_ERROR Engine::InsertPathIntoDirtySet(const AttributePathParams & aAttributePath) { - ReturnErrorCodeIf(MergeOverlappedAttributePath(aAttributePath), CHIP_NO_ERROR); + VerifyOrReturnError(!MergeOverlappedAttributePath(aAttributePath), CHIP_NO_ERROR); if (mGlobalDirtySet.Exhausted() && !MergeDirtyPathsUnderSameCluster() && !MergeDirtyPathsUnderSameEndpoint()) { @@ -862,7 +862,7 @@ CHIP_ERROR Engine::InsertPathIntoDirtySet(const AttributePathParams & aAttribute object->mGeneration = GetDirtySetGeneration(); } - ReturnErrorCodeIf(MergeOverlappedAttributePath(aAttributePath), CHIP_NO_ERROR); + VerifyOrReturnError(!MergeOverlappedAttributePath(aAttributePath), CHIP_NO_ERROR); ChipLogDetail(DataManagement, "Cannot merge the new path into any existing path, create one."); auto object = mGlobalDirtySet.CreateObject(); diff --git a/src/app/server/AclStorage.cpp b/src/app/server/AclStorage.cpp index 03ebc7a1341906..913589ef828fb7 100644 --- a/src/app/server/AclStorage.cpp +++ b/src/app/server/AclStorage.cpp @@ -152,14 +152,14 @@ CHIP_ERROR Convert(StagingSubject from, NodeId & to) switch (from.authMode) { case StagingAuthMode::kPase: - ReturnErrorCodeIf((from.nodeId & ~kMaskPAKEKeyId) != 0, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError((from.nodeId & ~kMaskPAKEKeyId) == 0, CHIP_ERROR_INVALID_ARGUMENT); to = NodeIdFromPAKEKeyId(static_cast(from.nodeId)); break; case StagingAuthMode::kCase: to = from.nodeId; break; case StagingAuthMode::kGroup: - ReturnErrorCodeIf((from.nodeId & ~kMaskGroupId) != 0, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError((from.nodeId & ~kMaskGroupId) == 0, CHIP_ERROR_INVALID_ARGUMENT); to = NodeIdFromGroupId(static_cast(from.nodeId)); break; default: diff --git a/src/app/util/binding-table.cpp b/src/app/util/binding-table.cpp index ce3c45f196b3c9..7ca3c4ba18aace 100644 --- a/src/app/util/binding-table.cpp +++ b/src/app/util/binding-table.cpp @@ -219,7 +219,7 @@ CHIP_ERROR BindingTable::LoadEntryFromStorage(uint8_t index, uint8_t & nextIndex else { entry.type = MATTER_MULTICAST_BINDING; - ReturnErrorCodeIf(reader.GetTag() != TLV::ContextTag(kTagGroupId), CHIP_ERROR_INVALID_TLV_TAG); + VerifyOrReturnError(reader.GetTag() == TLV::ContextTag(kTagGroupId), CHIP_ERROR_INVALID_TLV_TAG); ReturnErrorOnFailure(reader.Get(entry.groupId)); } ReturnErrorOnFailure(reader.Next(TLV::ContextTag(kTagNextEntry))); diff --git a/src/app/util/ember-compatibility-functions.cpp b/src/app/util/ember-compatibility-functions.cpp index 0ea63cba30d1db..e50b55975f9de8 100644 --- a/src/app/util/ember-compatibility-functions.cpp +++ b/src/app/util/ember-compatibility-functions.cpp @@ -302,7 +302,7 @@ CHIP_ERROR ReadSingleClusterData(const SubjectDescriptor & aSubjectDescriptor, b CHIP_ERROR err = Access::GetAccessControl().Check(aSubjectDescriptor, requestPath, requestPrivilege); if (err != CHIP_NO_ERROR) { - ReturnErrorCodeIf((err != CHIP_ERROR_ACCESS_DENIED) && (err != CHIP_ERROR_ACCESS_RESTRICTED_BY_ARL), err); + VerifyOrReturnError((err == CHIP_ERROR_ACCESS_DENIED) || (err == CHIP_ERROR_ACCESS_RESTRICTED_BY_ARL), err); if (aPath.mExpanded) { return CHIP_NO_ERROR; @@ -324,7 +324,7 @@ CHIP_ERROR ReadSingleClusterData(const SubjectDescriptor & aSubjectDescriptor, b bool triedEncode = false; ReturnErrorOnFailure(ReadViaAccessInterface(aSubjectDescriptor, aIsFabricFiltered, aPath, aAttributeReports, apEncoderState, attributeOverride, &triedEncode)); - ReturnErrorCodeIf(triedEncode, CHIP_NO_ERROR); + VerifyOrReturnError(!triedEncode, CHIP_NO_ERROR); } } @@ -704,7 +704,7 @@ CHIP_ERROR WriteSingleClusterData(const SubjectDescriptor & aSubjectDescriptor, } if (err != CHIP_NO_ERROR) { - ReturnErrorCodeIf((err != CHIP_ERROR_ACCESS_DENIED) && (err != CHIP_ERROR_ACCESS_RESTRICTED_BY_ARL), err); + VerifyOrReturnError((err == CHIP_ERROR_ACCESS_DENIED) || (err == CHIP_ERROR_ACCESS_RESTRICTED_BY_ARL), err); // TODO: when wildcard/group writes are supported, handle them to discard rather than fail with status return apWriteHandler->AddStatus(aPath, err == CHIP_ERROR_ACCESS_DENIED diff --git a/src/controller/CHIPDeviceController.cpp b/src/controller/CHIPDeviceController.cpp index 346867226e4261..0c4f7ac9969b03 100644 --- a/src/controller/CHIPDeviceController.cpp +++ b/src/controller/CHIPDeviceController.cpp @@ -182,9 +182,9 @@ CHIP_ERROR DeviceController::InitControllerNOCChain(const ControllerInitParams & externalOperationalKeypair = params.operationalKeypair; } - ReturnErrorCodeIf(!rcacBuf.Alloc(chipCertAllocatedLen), CHIP_ERROR_NO_MEMORY); - ReturnErrorCodeIf(!icacBuf.Alloc(chipCertAllocatedLen), CHIP_ERROR_NO_MEMORY); - ReturnErrorCodeIf(!nocBuf.Alloc(chipCertAllocatedLen), CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(rcacBuf.Alloc(chipCertAllocatedLen), CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(icacBuf.Alloc(chipCertAllocatedLen), CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(nocBuf.Alloc(chipCertAllocatedLen), CHIP_ERROR_NO_MEMORY); MutableByteSpan rcacSpan(rcacBuf.Get(), chipCertAllocatedLen); @@ -2745,7 +2745,7 @@ void DeviceCommissioner::OnScanNetworksResponse(void * context, CHIP_ERROR DeviceCommissioner::NetworkCredentialsReady() { - ReturnErrorCodeIf(mCommissioningStage != CommissioningStage::kNeedsNetworkCreds, CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(mCommissioningStage == CommissioningStage::kNeedsNetworkCreds, CHIP_ERROR_INCORRECT_STATE); // need to advance to next step CommissioningStageComplete(CHIP_NO_ERROR); @@ -2755,7 +2755,7 @@ CHIP_ERROR DeviceCommissioner::NetworkCredentialsReady() CHIP_ERROR DeviceCommissioner::ICDRegistrationInfoReady() { - ReturnErrorCodeIf(mCommissioningStage != CommissioningStage::kICDGetRegistrationInfo, CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(mCommissioningStage == CommissioningStage::kICDGetRegistrationInfo, CHIP_ERROR_INCORRECT_STATE); // need to advance to next step CommissioningStageComplete(CHIP_NO_ERROR); diff --git a/src/controller/CHIPDeviceControllerFactory.cpp b/src/controller/CHIPDeviceControllerFactory.cpp index dbc55dd7b7327e..e7e718964d3745 100644 --- a/src/controller/CHIPDeviceControllerFactory.cpp +++ b/src/controller/CHIPDeviceControllerFactory.cpp @@ -132,8 +132,8 @@ CHIP_ERROR DeviceControllerFactory::InitSystemState(FactoryInitParams params) // OperationalCertificateStore needs to be provided to init the fabric table if fabric table is // not provided wholesale. - ReturnErrorCodeIf((params.fabricTable == nullptr) && (params.opCertStore == nullptr), CHIP_ERROR_INVALID_ARGUMENT); - ReturnErrorCodeIf(params.sessionKeystore == nullptr, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError((params.fabricTable != nullptr) || (params.opCertStore != nullptr), CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(params.sessionKeystore != nullptr, CHIP_ERROR_INVALID_ARGUMENT); #if CONFIG_NETWORK_LAYER_BLE #if CONFIG_DEVICE_LAYER @@ -197,7 +197,7 @@ CHIP_ERROR DeviceControllerFactory::InitSystemState(FactoryInitParams params) { // TODO(#16231): Previously (and still) the objects new-ed in this entire method seem expected to last forever... auto newFabricTable = Platform::MakeUnique(); - ReturnErrorCodeIf(!newFabricTable, CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(newFabricTable, CHIP_ERROR_NO_MEMORY); FabricTable::InitParams fabricTableInitParams; fabricTableInitParams.storage = params.fabricIndependentStorage; diff --git a/src/controller/ExampleOperationalCredentialsIssuer.cpp b/src/controller/ExampleOperationalCredentialsIssuer.cpp index 516b3ece2b4357..346b9012c1b8e5 100644 --- a/src/controller/ExampleOperationalCredentialsIssuer.cpp +++ b/src/controller/ExampleOperationalCredentialsIssuer.cpp @@ -59,7 +59,7 @@ CHIP_ERROR IssueX509Cert(uint32_t now, uint32_t validity, ChipDN issuerDn, ChipD constexpr uint8_t sOID_Extension_SubjectAltName[] = { 0x55, 0x1d, 0x11 }; Platform::ScopedMemoryBuffer derBuf; - ReturnErrorCodeIf(!derBuf.Alloc(kMaxDERCertLength), CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(derBuf.Alloc(kMaxDERCertLength), CHIP_ERROR_NO_MEMORY); MutableByteSpan derSpan{ derBuf.Get(), kMaxDERCertLength }; int64_t serialNumber = 1; @@ -88,16 +88,16 @@ CHIP_ERROR IssueX509Cert(uint32_t now, uint32_t validity, ChipDN issuerDn, ChipD if (maximizeSize) { Platform::ScopedMemoryBuffer paddedTlvBuf; - ReturnErrorCodeIf(!paddedTlvBuf.Alloc(kMaxCHIPCertLength + kMaxCertPaddingLength), CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(paddedTlvBuf.Alloc(kMaxCHIPCertLength + kMaxCertPaddingLength), CHIP_ERROR_NO_MEMORY); MutableByteSpan paddedTlvSpan{ paddedTlvBuf.Get(), kMaxCHIPCertLength + kMaxCertPaddingLength }; ReturnErrorOnFailure(ConvertX509CertToChipCert(derSpan, paddedTlvSpan)); Platform::ScopedMemoryBuffer paddedDerBuf; - ReturnErrorCodeIf(!paddedDerBuf.Alloc(kMaxDERCertLength + kMaxCertPaddingLength), CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(paddedDerBuf.Alloc(kMaxDERCertLength + kMaxCertPaddingLength), CHIP_ERROR_NO_MEMORY); MutableByteSpan paddedDerSpan{ paddedDerBuf.Get(), kMaxDERCertLength + kMaxCertPaddingLength }; Platform::ScopedMemoryBuffer fillerBuf; - ReturnErrorCodeIf(!fillerBuf.Alloc(kMaxCertPaddingLength), CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(fillerBuf.Alloc(kMaxCertPaddingLength), CHIP_ERROR_NO_MEMORY); memset(fillerBuf.Get(), 'A', kMaxCertPaddingLength); int derPaddingLen = static_cast(kMaxDERCertLength - kDERCertFutureExtEncodingOverhead - derSpan.size()); @@ -361,15 +361,15 @@ CHIP_ERROR ExampleOperationalCredentialsIssuer::GenerateNOCChain(const ByteSpan ReturnErrorOnFailure(VerifyCertificateSigningRequest(csr.data(), csr.size(), pubkey)); chip::Platform::ScopedMemoryBuffer noc; - ReturnErrorCodeIf(!noc.Alloc(kMaxDERCertLength), CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(noc.Alloc(kMaxDERCertLength), CHIP_ERROR_NO_MEMORY); MutableByteSpan nocSpan(noc.Get(), kMaxDERCertLength); chip::Platform::ScopedMemoryBuffer icac; - ReturnErrorCodeIf(!icac.Alloc(kMaxDERCertLength), CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(icac.Alloc(kMaxDERCertLength), CHIP_ERROR_NO_MEMORY); MutableByteSpan icacSpan(icac.Get(), kMaxDERCertLength); chip::Platform::ScopedMemoryBuffer rcac; - ReturnErrorCodeIf(!rcac.Alloc(kMaxDERCertLength), CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(rcac.Alloc(kMaxDERCertLength), CHIP_ERROR_NO_MEMORY); MutableByteSpan rcacSpan(rcac.Get(), kMaxDERCertLength); ReturnErrorOnFailure( @@ -387,7 +387,7 @@ CHIP_ERROR ExampleOperationalCredentialsIssuer::GenerateNOCChain(const ByteSpan uint8_t ipkValue[CHIP_CRYPTO_SYMMETRIC_KEY_LENGTH_BYTES]; Crypto::IdentityProtectionKeySpan ipkSpan(ipkValue); - ReturnErrorCodeIf(defaultIpkSpan.size() != sizeof(ipkValue), CHIP_ERROR_INTERNAL); + VerifyOrReturnError(defaultIpkSpan.size() == sizeof(ipkValue), CHIP_ERROR_INTERNAL); memcpy(&ipkValue[0], defaultIpkSpan.data(), defaultIpkSpan.size()); // Callback onto commissioner. diff --git a/src/controller/ExamplePersistentStorage.cpp b/src/controller/ExamplePersistentStorage.cpp index 27ea886a77dd7f..599f0980db99b3 100644 --- a/src/controller/ExamplePersistentStorage.cpp +++ b/src/controller/ExamplePersistentStorage.cpp @@ -102,20 +102,20 @@ CHIP_ERROR PersistentStorage::SyncGetKeyValue(const char * key, void * value, ui { std::string iniValue; - ReturnErrorCodeIf(((value == nullptr) && (size != 0)), CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError((value != nullptr) || (size == 0), CHIP_ERROR_INVALID_ARGUMENT); auto section = mConfig.sections[kDefaultSectionName]; - ReturnErrorCodeIf(!SyncDoesKeyExist(key), CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + VerifyOrReturnError(SyncDoesKeyExist(key), CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); std::string escapedKey = EscapeKey(key); - ReturnErrorCodeIf(!inipp::extract(section[escapedKey], iniValue), CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(inipp::extract(section[escapedKey], iniValue), CHIP_ERROR_INVALID_ARGUMENT); iniValue = Base64ToString(iniValue); uint16_t dataSize = static_cast(iniValue.size()); - ReturnErrorCodeIf(size == 0 && dataSize == 0, CHIP_NO_ERROR); - ReturnErrorCodeIf(value == nullptr, CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(size != 0 || dataSize != 0, CHIP_NO_ERROR); + VerifyOrReturnError(value != nullptr, CHIP_ERROR_BUFFER_TOO_SMALL); uint16_t sizeToCopy = std::min(size, dataSize); @@ -126,7 +126,7 @@ CHIP_ERROR PersistentStorage::SyncGetKeyValue(const char * key, void * value, ui CHIP_ERROR PersistentStorage::SyncSetKeyValue(const char * key, const void * value, uint16_t size) { - ReturnErrorCodeIf((value == nullptr) && (size != 0), CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError((value != nullptr) || (size == 0), CHIP_ERROR_INVALID_ARGUMENT); auto section = mConfig.sections[kDefaultSectionName]; @@ -148,7 +148,7 @@ CHIP_ERROR PersistentStorage::SyncDeleteKeyValue(const char * key) { auto section = mConfig.sections[kDefaultSectionName]; - ReturnErrorCodeIf(!SyncDoesKeyExist(key), CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + VerifyOrReturnError(SyncDoesKeyExist(key), CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); std::string escapedKey = EscapeKey(key); section.erase(escapedKey); diff --git a/src/controller/java/AndroidOperationalCredentialsIssuer.cpp b/src/controller/java/AndroidOperationalCredentialsIssuer.cpp index d87e4f94825c9f..4873f21c1a26b8 100644 --- a/src/controller/java/AndroidOperationalCredentialsIssuer.cpp +++ b/src/controller/java/AndroidOperationalCredentialsIssuer.cpp @@ -295,7 +295,7 @@ CHIP_ERROR AndroidOperationalCredentialsIssuer::NOCChainGenerated(CHIP_ERROR sta Optional ipk, Optional adminSubject) { - ReturnErrorCodeIf(mOnNOCCompletionCallback == nullptr, CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(mOnNOCCompletionCallback != nullptr, CHIP_ERROR_INCORRECT_STATE); Callback::Callback * onCompletion = mOnNOCCompletionCallback; mOnNOCCompletionCallback = nullptr; @@ -357,11 +357,11 @@ CHIP_ERROR AndroidOperationalCredentialsIssuer::LocalGenerateNOCChain(const Byte ChipLogProgress(chipTool, "VerifyCertificateSigningRequest"); Platform::ScopedMemoryBuffer noc; - ReturnErrorCodeIf(!noc.Alloc(kMaxCHIPDERCertLength), CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(noc.Alloc(kMaxCHIPDERCertLength), CHIP_ERROR_NO_MEMORY); MutableByteSpan nocSpan(noc.Get(), kMaxCHIPDERCertLength); Platform::ScopedMemoryBuffer rcac; - ReturnErrorCodeIf(!rcac.Alloc(kMaxCHIPDERCertLength), CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(rcac.Alloc(kMaxCHIPDERCertLength), CHIP_ERROR_NO_MEMORY); MutableByteSpan rcacSpan(rcac.Get(), kMaxCHIPDERCertLength); MutableByteSpan icacSpan; @@ -380,7 +380,7 @@ CHIP_ERROR AndroidOperationalCredentialsIssuer::LocalGenerateNOCChain(const Byte uint8_t ipkValue[CHIP_CRYPTO_SYMMETRIC_KEY_LENGTH_BYTES]; Crypto::IdentityProtectionKeySpan ipkSpan(ipkValue); - ReturnErrorCodeIf(defaultIpkSpan.size() != sizeof(ipkValue), CHIP_ERROR_INTERNAL); + VerifyOrReturnError(defaultIpkSpan.size() == sizeof(ipkValue), CHIP_ERROR_INTERNAL); memcpy(&ipkValue[0], defaultIpkSpan.data(), defaultIpkSpan.size()); diff --git a/src/controller/python/ChipDeviceController-ScriptBinding.cpp b/src/controller/python/ChipDeviceController-ScriptBinding.cpp index b31cb5b7b8a4e6..11fdf763da558d 100644 --- a/src/controller/python/ChipDeviceController-ScriptBinding.cpp +++ b/src/controller/python/ChipDeviceController-ScriptBinding.cpp @@ -512,7 +512,7 @@ PyChipError pychip_DeviceController_OnNetworkCommission(chip::Controller::Device PyChipError pychip_DeviceController_SetThreadOperationalDataset(const char * threadOperationalDataset, uint32_t size) { - ReturnErrorCodeIf(!sThreadBuf.Alloc(size), ToPyChipError(CHIP_ERROR_NO_MEMORY)); + VerifyOrReturnError(sThreadBuf.Alloc(size), ToPyChipError(CHIP_ERROR_NO_MEMORY)); memcpy(sThreadBuf.Get(), threadOperationalDataset, size); sCommissioningParameters.SetThreadOperationalDataset(ByteSpan(sThreadBuf.Get(), size)); return ToPyChipError(CHIP_NO_ERROR); @@ -520,11 +520,11 @@ PyChipError pychip_DeviceController_SetThreadOperationalDataset(const char * thr PyChipError pychip_DeviceController_SetWiFiCredentials(const char * ssid, const char * credentials) { size_t ssidSize = strlen(ssid); - ReturnErrorCodeIf(!sSsidBuf.Alloc(ssidSize), ToPyChipError(CHIP_ERROR_NO_MEMORY)); + VerifyOrReturnError(sSsidBuf.Alloc(ssidSize), ToPyChipError(CHIP_ERROR_NO_MEMORY)); memcpy(sSsidBuf.Get(), ssid, ssidSize); size_t credsSize = strlen(credentials); - ReturnErrorCodeIf(!sCredsBuf.Alloc(credsSize), ToPyChipError(CHIP_ERROR_NO_MEMORY)); + VerifyOrReturnError(sCredsBuf.Alloc(credsSize), ToPyChipError(CHIP_ERROR_NO_MEMORY)); memcpy(sCredsBuf.Get(), credentials, credsSize); sCommissioningParameters.SetWiFiCredentials( @@ -544,7 +544,7 @@ PyChipError pychip_DeviceController_SetTimeZone(int32_t offset, uint64_t validAt else { size_t len = strlen(name); - ReturnErrorCodeIf(!sTimeZoneNameBuf.Alloc(len), ToPyChipError(CHIP_ERROR_NO_MEMORY)); + VerifyOrReturnError(sTimeZoneNameBuf.Alloc(len), ToPyChipError(CHIP_ERROR_NO_MEMORY)); memcpy(sTimeZoneNameBuf.Get(), name, len); sTimeZoneBuf.name.SetValue(CharSpan(sTimeZoneNameBuf.Get(), len)); } @@ -564,7 +564,7 @@ PyChipError pychip_DeviceController_SetDSTOffset(int32_t offset, uint64_t validS PyChipError pychip_DeviceController_SetDefaultNtp(const char * defaultNTP) { size_t len = strlen(defaultNTP); - ReturnErrorCodeIf(!sDefaultNTPBuf.Alloc(len), ToPyChipError(CHIP_ERROR_NO_MEMORY)); + VerifyOrReturnError(sDefaultNTPBuf.Alloc(len), ToPyChipError(CHIP_ERROR_NO_MEMORY)); memcpy(sDefaultNTPBuf.Get(), defaultNTP, len); sCommissioningParameters.SetDefaultNTP(chip::app::DataModel::MakeNullable(CharSpan(sDefaultNTPBuf.Get(), len))); return ToPyChipError(CHIP_NO_ERROR); diff --git a/src/controller/python/ChipDeviceController-StorageDelegate.cpp b/src/controller/python/ChipDeviceController-StorageDelegate.cpp index 9fb19efccdd2db..68e1531b7d8907 100644 --- a/src/controller/python/ChipDeviceController-StorageDelegate.cpp +++ b/src/controller/python/ChipDeviceController-StorageDelegate.cpp @@ -32,7 +32,7 @@ namespace Controller { CHIP_ERROR PythonPersistentStorageDelegate::SyncGetKeyValue(const char * key, void * value, uint16_t & size) { - ReturnErrorCodeIf(((value == nullptr) && (size != 0)), CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError((value != nullptr) || (size == 0), CHIP_ERROR_INVALID_ARGUMENT); auto val = mStorage.find(key); if (val == mStorage.end()) @@ -47,8 +47,8 @@ CHIP_ERROR PythonPersistentStorageDelegate::SyncGetKeyValue(const char * key, vo } uint16_t neededSize = static_cast(val->second.size()); - ReturnErrorCodeIf(size == 0 && neededSize == 0, CHIP_NO_ERROR); - ReturnErrorCodeIf(value == nullptr, CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(size != 0 || neededSize != 0, CHIP_NO_ERROR); + VerifyOrReturnError(value != nullptr, CHIP_ERROR_BUFFER_TOO_SMALL); if (size < neededSize) { @@ -114,7 +114,7 @@ CHIP_ERROR StorageAdapter::SyncGetKeyValue(const char * key, void * value, uint1 CHIP_ERROR StorageAdapter::SyncSetKeyValue(const char * key, const void * value, uint16_t size) { - ReturnErrorCodeIf(((value == nullptr) && (size != 0)), CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError((value != nullptr) || (size == 0), CHIP_ERROR_INVALID_ARGUMENT); ChipLogDetail(Controller, "StorageAdapter::SetKeyValue: Key = %s, Value = %p (%u)", StringOrNullMarker(key), value, size); mSetKeyCb(mContext, key, value, size); return CHIP_NO_ERROR; diff --git a/src/controller/python/OpCredsBinding.cpp b/src/controller/python/OpCredsBinding.cpp index f5815922cc14eb..37b1e9a9d1a267 100644 --- a/src/controller/python/OpCredsBinding.cpp +++ b/src/controller/python/OpCredsBinding.cpp @@ -413,9 +413,9 @@ PyChipError pychip_OpCreds_AllocateControllerForPythonCommissioningFLow( uint8_t * rcac, uint32_t rcacLen, const uint8_t * ipk, uint32_t ipkLen, chip::VendorId adminVendorId, bool enableServerInteractions) { - ReturnErrorCodeIf(nocLen > Controller::kMaxCHIPDERCertLength, ToPyChipError(CHIP_ERROR_NO_MEMORY)); - ReturnErrorCodeIf(icacLen > Controller::kMaxCHIPDERCertLength, ToPyChipError(CHIP_ERROR_NO_MEMORY)); - ReturnErrorCodeIf(rcacLen > Controller::kMaxCHIPDERCertLength, ToPyChipError(CHIP_ERROR_NO_MEMORY)); + VerifyOrReturnError(nocLen <= Controller::kMaxCHIPDERCertLength, ToPyChipError(CHIP_ERROR_NO_MEMORY)); + VerifyOrReturnError(icacLen <= Controller::kMaxCHIPDERCertLength, ToPyChipError(CHIP_ERROR_NO_MEMORY)); + VerifyOrReturnError(rcacLen <= Controller::kMaxCHIPDERCertLength, ToPyChipError(CHIP_ERROR_NO_MEMORY)); ChipLogDetail(Controller, "Creating New Device Controller"); @@ -507,15 +507,15 @@ PyChipError pychip_OpCreds_AllocateController(OpCredsContext * context, chip::Co } chip::Platform::ScopedMemoryBuffer noc; - ReturnErrorCodeIf(!noc.Alloc(Controller::kMaxCHIPDERCertLength), ToPyChipError(CHIP_ERROR_NO_MEMORY)); + VerifyOrReturnError(noc.Alloc(Controller::kMaxCHIPDERCertLength), ToPyChipError(CHIP_ERROR_NO_MEMORY)); MutableByteSpan nocSpan(noc.Get(), Controller::kMaxCHIPDERCertLength); chip::Platform::ScopedMemoryBuffer icac; - ReturnErrorCodeIf(!icac.Alloc(Controller::kMaxCHIPDERCertLength), ToPyChipError(CHIP_ERROR_NO_MEMORY)); + VerifyOrReturnError(icac.Alloc(Controller::kMaxCHIPDERCertLength), ToPyChipError(CHIP_ERROR_NO_MEMORY)); MutableByteSpan icacSpan(icac.Get(), Controller::kMaxCHIPDERCertLength); chip::Platform::ScopedMemoryBuffer rcac; - ReturnErrorCodeIf(!rcac.Alloc(Controller::kMaxCHIPDERCertLength), ToPyChipError(CHIP_ERROR_NO_MEMORY)); + VerifyOrReturnError(rcac.Alloc(Controller::kMaxCHIPDERCertLength), ToPyChipError(CHIP_ERROR_NO_MEMORY)); MutableByteSpan rcacSpan(rcac.Get(), Controller::kMaxCHIPDERCertLength); CATValues catValues; diff --git a/src/credentials/CHIPCert.cpp b/src/credentials/CHIPCert.cpp index 5bad0ab75076a9..034b2873971405 100644 --- a/src/credentials/CHIPCert.cpp +++ b/src/credentials/CHIPCert.cpp @@ -989,7 +989,7 @@ CHIP_ERROR ChipDN::DecodeFromASN1(ASN1Reader & reader) // Only one AttributeTypeAndValue allowed per RDN. err = reader.Next(); - ReturnErrorCodeIf(err == CHIP_NO_ERROR, ASN1_ERROR_UNSUPPORTED_ENCODING); + VerifyOrReturnError(err != CHIP_NO_ERROR, ASN1_ERROR_UNSUPPORTED_ENCODING); VerifyOrReturnError(err == ASN1_END, err); } ASN1_EXIT_SET; @@ -1245,7 +1245,7 @@ CHIP_ERROR ExtractNodeIdFabricIdFromOpCert(const ChipCertificateData & opcert, N { // Since we assume the cert is pre-validated, we are going to assume that // its subject in fact has both a node id and a fabric id. - ReturnErrorCodeIf(outNodeId == nullptr || outFabricId == nullptr, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(outNodeId != nullptr && outFabricId != nullptr, CHIP_ERROR_INVALID_ARGUMENT); NodeId nodeId = 0; FabricId fabricId = kUndefinedFabricId; bool foundNodeId = false; @@ -1341,7 +1341,7 @@ CHIP_ERROR ExtractCATsFromOpCert(const ChipCertificateData & opcert, CATValues & // This error should never happen in practice because valid NOC cannot have more // than kMaxSubjectCATAttributeCount CATs in its subject. The check that it is // valid NOC was done above. - ReturnErrorCodeIf(catCount == cats.size(), CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(catCount != cats.size(), CHIP_ERROR_BUFFER_TOO_SMALL); VerifyOrReturnError(CanCastTo(rdn.mChipVal), CHIP_ERROR_INVALID_ARGUMENT); cats.values[catCount++] = static_cast(rdn.mChipVal); } diff --git a/src/credentials/CHIPCertToX509.cpp b/src/credentials/CHIPCertToX509.cpp index 9e0549d13f4921..b5447780ce76f1 100644 --- a/src/credentials/CHIPCertToX509.cpp +++ b/src/credentials/CHIPCertToX509.cpp @@ -453,7 +453,7 @@ static CHIP_ERROR DecodeConvertECDSASignature(TLVReader & reader, ASN1Writer & w ReturnErrorOnFailure(DecodeECDSASignature(reader, certData)); // Converting the signature is a bit of work, so explicitly check if we have a null writer - ReturnErrorCodeIf(writer.IsNullWriter(), CHIP_NO_ERROR); + VerifyOrReturnError(!writer.IsNullWriter(), CHIP_NO_ERROR); // signatureValue BIT STRING // Per RFC3279, the ECDSA signature value is encoded in DER encapsulated in the signatureValue BIT STRING. diff --git a/src/credentials/FabricTable.cpp b/src/credentials/FabricTable.cpp index 8ed838243df4ab..1c4001cefecebd 100644 --- a/src/credentials/FabricTable.cpp +++ b/src/credentials/FabricTable.cpp @@ -436,7 +436,7 @@ CHIP_ERROR FabricTable::VerifyCredentials(const ByteSpan & noc, const ByteSpan & err = ExtractFabricIdFromCert(certificates.GetCertSet()[1], &icacFabricId); if (err == CHIP_NO_ERROR) { - ReturnErrorCodeIf(icacFabricId != outFabricId, CHIP_ERROR_FABRIC_MISMATCH_ON_ICA); + VerifyOrReturnError(icacFabricId == outFabricId, CHIP_ERROR_FABRIC_MISMATCH_ON_ICA); } // FabricId is optional field in ICAC and "not found" code is not treated as error. else if (err != CHIP_ERROR_NOT_FOUND) @@ -449,7 +449,7 @@ CHIP_ERROR FabricTable::VerifyCredentials(const ByteSpan & noc, const ByteSpan & err = ExtractFabricIdFromCert(certificates.GetCertSet()[0], &rcacFabricId); if (err == CHIP_NO_ERROR) { - ReturnErrorCodeIf(rcacFabricId != outFabricId, CHIP_ERROR_WRONG_CERT_DN); + VerifyOrReturnError(rcacFabricId == outFabricId, CHIP_ERROR_WRONG_CERT_DN); } // FabricId is optional field in RCAC and "not found" code is not treated as error. else if (err != CHIP_ERROR_NOT_FOUND) @@ -660,7 +660,7 @@ CHIP_ERROR FabricTable::FetchRootPubkey(FabricIndex fabricIndex, Crypto::P256Pub { MATTER_TRACE_SCOPE("FetchRootPubkey", "Fabric"); const FabricInfo * fabricInfo = FindFabricWithIndex(fabricIndex); - ReturnErrorCodeIf(fabricInfo == nullptr, CHIP_ERROR_INVALID_FABRIC_INDEX); + VerifyOrReturnError(fabricInfo != nullptr, CHIP_ERROR_INVALID_FABRIC_INDEX); return fabricInfo->FetchRootPubkey(outPublicKey); } @@ -861,9 +861,9 @@ FabricTable::AddOrUpdateInner(FabricIndex fabricIndex, bool isAddition, Crypto:: Platform::ScopedMemoryBuffer icacBuf; Platform::ScopedMemoryBuffer rcacBuf; - ReturnErrorCodeIf(!nocBuf.Alloc(kMaxCHIPCertLength), CHIP_ERROR_NO_MEMORY); - ReturnErrorCodeIf(!icacBuf.Alloc(kMaxCHIPCertLength), CHIP_ERROR_NO_MEMORY); - ReturnErrorCodeIf(!rcacBuf.Alloc(kMaxCHIPCertLength), CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(nocBuf.Alloc(kMaxCHIPCertLength), CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(icacBuf.Alloc(kMaxCHIPCertLength), CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(rcacBuf.Alloc(kMaxCHIPCertLength), CHIP_ERROR_NO_MEMORY); MutableByteSpan nocSpan{ nocBuf.Get(), kMaxCHIPCertLength }; MutableByteSpan icacSpan{ icacBuf.Get(), kMaxCHIPCertLength }; @@ -1590,7 +1590,7 @@ CHIP_ERROR FabricTable::AllocatePendingOperationalKey(Optional fabr if (fabricIndex.HasValue()) { // Check we not are trying to do an update but also change the root: forbidden - ReturnErrorCodeIf(mStateFlags.Has(StateFlags::kIsTrustedRootPending), CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(!mStateFlags.Has(StateFlags::kIsTrustedRootPending), CHIP_ERROR_INCORRECT_STATE); // Fabric update case (e.g. UpdateNOC): we already know the fabric index fabricIndexToUse = fabricIndex.Value(); @@ -1621,8 +1621,8 @@ CHIP_ERROR FabricTable::AddNewPendingTrustedRootCert(const ByteSpan & rcac) VerifyOrReturnError(mOpCertStore != nullptr, CHIP_ERROR_INCORRECT_STATE); // We should not already have pending NOC chain elements when we get here - ReturnErrorCodeIf( - mStateFlags.HasAny(StateFlags::kIsTrustedRootPending, StateFlags::kIsUpdatePending, StateFlags::kIsAddPending), + VerifyOrReturnError( + !mStateFlags.HasAny(StateFlags::kIsTrustedRootPending, StateFlags::kIsUpdatePending, StateFlags::kIsAddPending), CHIP_ERROR_INCORRECT_STATE); EnsureNextAvailableFabricIndexUpdated(); @@ -1738,7 +1738,7 @@ CHIP_ERROR FabricTable::AddNewPendingFabricCommon(const ByteSpan & noc, const By { FabricIndex collidingFabricIndex = kUndefinedFabricIndex; ReturnErrorOnFailure(FindExistingFabricByNocChaining(fabricIndexToUse, noc, collidingFabricIndex)); - ReturnErrorCodeIf(collidingFabricIndex != kUndefinedFabricIndex, CHIP_ERROR_FABRIC_EXISTS); + VerifyOrReturnError(collidingFabricIndex == kUndefinedFabricIndex, CHIP_ERROR_FABRIC_EXISTS); } // We don't have a collision, handle the temp insert of NOC/ICAC @@ -1790,7 +1790,7 @@ CHIP_ERROR FabricTable::UpdatePendingFabricCommon(FabricIndex fabricIndex, const // Make sure we are updating at least an existing FabricIndex const auto * fabricInfo = FindFabricWithIndex(fabricIndex); - ReturnErrorCodeIf(fabricInfo == nullptr, CHIP_ERROR_INVALID_FABRIC_INDEX); + VerifyOrReturnError(fabricInfo != nullptr, CHIP_ERROR_INVALID_FABRIC_INDEX); // Check for an existing fabric matching RCAC and FabricID. We must find a correct // existing fabric that chains to same root. We assume the stored root is correct. @@ -1798,7 +1798,7 @@ CHIP_ERROR FabricTable::UpdatePendingFabricCommon(FabricIndex fabricIndex, const { FabricIndex collidingFabricIndex = kUndefinedFabricIndex; ReturnErrorOnFailure(FindExistingFabricByNocChaining(fabricIndex, noc, collidingFabricIndex)); - ReturnErrorCodeIf(collidingFabricIndex != fabricIndex, CHIP_ERROR_INVALID_FABRIC_INDEX); + VerifyOrReturnError(collidingFabricIndex == fabricIndex, CHIP_ERROR_INVALID_FABRIC_INDEX); } // Handle the temp insert of NOC/ICAC @@ -2110,7 +2110,7 @@ CHIP_ERROR FabricTable::SetFabricLabel(FabricIndex fabricIndex, const CharSpan & VerifyOrReturnError(mStorage != nullptr, CHIP_ERROR_INCORRECT_STATE); VerifyOrReturnError(IsValidFabricIndex(fabricIndex), CHIP_ERROR_INVALID_FABRIC_INDEX); - ReturnErrorCodeIf(fabricLabel.size() > kFabricLabelMaxLengthInBytes, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(fabricLabel.size() <= kFabricLabelMaxLengthInBytes, CHIP_ERROR_INVALID_ARGUMENT); FabricInfo * fabricInfo = GetMutableFabricByIndex(fabricIndex); bool fabricIsInitialized = (fabricInfo != nullptr) && fabricInfo->IsInitialized(); diff --git a/src/credentials/FabricTable.h b/src/credentials/FabricTable.h index 9515ffb8889c06..2bf8af51af4a48 100644 --- a/src/credentials/FabricTable.h +++ b/src/credentials/FabricTable.h @@ -96,7 +96,7 @@ class DLL_EXPORT FabricInfo CompressedFabricId GetCompressedFabricId() const { return mCompressedFabricId; } CHIP_ERROR GetCompressedFabricIdBytes(MutableByteSpan & compressedFabricId) const { - ReturnErrorCodeIf(compressedFabricId.size() != sizeof(uint64_t), CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(compressedFabricId.size() == sizeof(uint64_t), CHIP_ERROR_INVALID_ARGUMENT); Encoding::BigEndian::Put64(compressedFabricId.data(), GetCompressedFabricId()); return CHIP_NO_ERROR; } diff --git a/src/credentials/PersistentStorageOpCertStore.cpp b/src/credentials/PersistentStorageOpCertStore.cpp index a2c0eb8bfb09d3..bda1e06d9a0baa 100644 --- a/src/credentials/PersistentStorageOpCertStore.cpp +++ b/src/credentials/PersistentStorageOpCertStore.cpp @@ -210,17 +210,17 @@ bool PersistentStorageOpCertStore::HasCertificateForFabric(FabricIndex fabricInd CHIP_ERROR PersistentStorageOpCertStore::AddNewTrustedRootCertForFabric(FabricIndex fabricIndex, const ByteSpan & rcac) { - ReturnErrorCodeIf(mStorage == nullptr, CHIP_ERROR_INCORRECT_STATE); - ReturnErrorCodeIf(!IsValidFabricIndex(fabricIndex), CHIP_ERROR_INVALID_FABRIC_INDEX); - ReturnErrorCodeIf(rcac.empty() || (rcac.size() > Credentials::kMaxCHIPCertLength), CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(mStorage != nullptr, CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(IsValidFabricIndex(fabricIndex), CHIP_ERROR_INVALID_FABRIC_INDEX); + VerifyOrReturnError(!rcac.empty() && (rcac.size() <= Credentials::kMaxCHIPCertLength), CHIP_ERROR_INVALID_ARGUMENT); - ReturnErrorCodeIf(mStateFlags.HasAny(StateFlags::kUpdateOpCertsCalled, StateFlags::kAddNewTrustedRootCalled, - StateFlags::kAddNewOpCertsCalled), - CHIP_ERROR_INCORRECT_STATE); - ReturnErrorCodeIf(StorageHasCertificate(mStorage, fabricIndex, CertChainElement::kRcac), CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(!mStateFlags.HasAny(StateFlags::kUpdateOpCertsCalled, StateFlags::kAddNewTrustedRootCalled, + StateFlags::kAddNewOpCertsCalled), + CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(!StorageHasCertificate(mStorage, fabricIndex, CertChainElement::kRcac), CHIP_ERROR_INCORRECT_STATE); Platform::ScopedMemoryBufferWithSize rcacBuf; - ReturnErrorCodeIf(!rcacBuf.Alloc(rcac.size()), CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(rcacBuf.Alloc(rcac.size()), CHIP_ERROR_NO_MEMORY); memcpy(rcacBuf.Get(), rcac.data(), rcac.size()); mPendingRcac = std::move(rcacBuf); @@ -234,33 +234,33 @@ CHIP_ERROR PersistentStorageOpCertStore::AddNewTrustedRootCertForFabric(FabricIn CHIP_ERROR PersistentStorageOpCertStore::AddNewOpCertsForFabric(FabricIndex fabricIndex, const ByteSpan & noc, const ByteSpan & icac) { - ReturnErrorCodeIf(mStorage == nullptr, CHIP_ERROR_INCORRECT_STATE); - ReturnErrorCodeIf(!IsValidFabricIndex(fabricIndex), CHIP_ERROR_INVALID_FABRIC_INDEX); - ReturnErrorCodeIf(noc.empty() || (noc.size() > Credentials::kMaxCHIPCertLength), CHIP_ERROR_INVALID_ARGUMENT); - ReturnErrorCodeIf(icac.size() > Credentials::kMaxCHIPCertLength, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(mStorage != nullptr, CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(IsValidFabricIndex(fabricIndex), CHIP_ERROR_INVALID_FABRIC_INDEX); + VerifyOrReturnError(!noc.empty() && (noc.size() <= Credentials::kMaxCHIPCertLength), CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(icac.size() <= Credentials::kMaxCHIPCertLength, CHIP_ERROR_INVALID_ARGUMENT); // Can't have called UpdateOpCertsForFabric first, or called with pending certs - ReturnErrorCodeIf(mStateFlags.HasAny(StateFlags::kUpdateOpCertsCalled, StateFlags::kAddNewOpCertsCalled), - CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(!mStateFlags.HasAny(StateFlags::kUpdateOpCertsCalled, StateFlags::kAddNewOpCertsCalled), + CHIP_ERROR_INCORRECT_STATE); // Need to have trusted roots installed to make the chain valid - ReturnErrorCodeIf(!mStateFlags.Has(StateFlags::kAddNewTrustedRootCalled), CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(mStateFlags.Has(StateFlags::kAddNewTrustedRootCalled), CHIP_ERROR_INCORRECT_STATE); // fabricIndex must match the current pending fabric - ReturnErrorCodeIf(fabricIndex != mPendingFabricIndex, CHIP_ERROR_INVALID_FABRIC_INDEX); + VerifyOrReturnError(fabricIndex == mPendingFabricIndex, CHIP_ERROR_INVALID_FABRIC_INDEX); // Can't have persisted NOC/ICAC for same fabric if adding - ReturnErrorCodeIf(StorageHasCertificate(mStorage, fabricIndex, CertChainElement::kNoc), CHIP_ERROR_INCORRECT_STATE); - ReturnErrorCodeIf(StorageHasCertificate(mStorage, fabricIndex, CertChainElement::kIcac), CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(!StorageHasCertificate(mStorage, fabricIndex, CertChainElement::kNoc), CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(!StorageHasCertificate(mStorage, fabricIndex, CertChainElement::kIcac), CHIP_ERROR_INCORRECT_STATE); Platform::ScopedMemoryBufferWithSize nocBuf; - ReturnErrorCodeIf(!nocBuf.Alloc(noc.size()), CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(nocBuf.Alloc(noc.size()), CHIP_ERROR_NO_MEMORY); memcpy(nocBuf.Get(), noc.data(), noc.size()); Platform::ScopedMemoryBufferWithSize icacBuf; if (icac.size() > 0) { - ReturnErrorCodeIf(!icacBuf.Alloc(icac.size()), CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(icacBuf.Alloc(icac.size()), CHIP_ERROR_NO_MEMORY); memcpy(icacBuf.Get(), icac.data(), icac.size()); } @@ -275,35 +275,35 @@ CHIP_ERROR PersistentStorageOpCertStore::AddNewOpCertsForFabric(FabricIndex fabr CHIP_ERROR PersistentStorageOpCertStore::UpdateOpCertsForFabric(FabricIndex fabricIndex, const ByteSpan & noc, const ByteSpan & icac) { - ReturnErrorCodeIf(mStorage == nullptr, CHIP_ERROR_INCORRECT_STATE); - ReturnErrorCodeIf(!IsValidFabricIndex(fabricIndex), CHIP_ERROR_INVALID_FABRIC_INDEX); - ReturnErrorCodeIf(noc.empty() || (noc.size() > Credentials::kMaxCHIPCertLength), CHIP_ERROR_INVALID_ARGUMENT); - ReturnErrorCodeIf(icac.size() > Credentials::kMaxCHIPCertLength, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(mStorage != nullptr, CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(IsValidFabricIndex(fabricIndex), CHIP_ERROR_INVALID_FABRIC_INDEX); + VerifyOrReturnError(!noc.empty() && (noc.size() <= Credentials::kMaxCHIPCertLength), CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(icac.size() <= Credentials::kMaxCHIPCertLength, CHIP_ERROR_INVALID_ARGUMENT); // Can't have called AddNewOpCertsForFabric first, and should never get here after AddNewTrustedRootCertForFabric. - ReturnErrorCodeIf(mStateFlags.HasAny(StateFlags::kAddNewOpCertsCalled, StateFlags::kAddNewTrustedRootCalled), - CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(!mStateFlags.HasAny(StateFlags::kAddNewOpCertsCalled, StateFlags::kAddNewTrustedRootCalled), + CHIP_ERROR_INCORRECT_STATE); // Can't have already pending NOC from UpdateOpCerts not yet committed - ReturnErrorCodeIf(mStateFlags.Has(StateFlags::kUpdateOpCertsCalled), CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(!mStateFlags.Has(StateFlags::kUpdateOpCertsCalled), CHIP_ERROR_INCORRECT_STATE); // Need to have trusted roots installed to make the chain valid - ReturnErrorCodeIf(!StorageHasCertificate(mStorage, fabricIndex, CertChainElement::kRcac), CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(StorageHasCertificate(mStorage, fabricIndex, CertChainElement::kRcac), CHIP_ERROR_INCORRECT_STATE); // Must have persisted NOC for same fabric if updating - ReturnErrorCodeIf(!StorageHasCertificate(mStorage, fabricIndex, CertChainElement::kNoc), CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(StorageHasCertificate(mStorage, fabricIndex, CertChainElement::kNoc), CHIP_ERROR_INCORRECT_STATE); // Don't check for ICAC, we may not have had one before, but assume that if NOC is there, a // previous chain was at least partially there Platform::ScopedMemoryBufferWithSize nocBuf; - ReturnErrorCodeIf(!nocBuf.Alloc(noc.size()), CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(nocBuf.Alloc(noc.size()), CHIP_ERROR_NO_MEMORY); memcpy(nocBuf.Get(), noc.data(), noc.size()); Platform::ScopedMemoryBufferWithSize icacBuf; if (icac.size() > 0) { - ReturnErrorCodeIf(!icacBuf.Alloc(icac.size()), CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(icacBuf.Alloc(icac.size()), CHIP_ERROR_NO_MEMORY); memcpy(icacBuf.Get(), icac.data(), icac.size()); } @@ -329,8 +329,8 @@ CHIP_ERROR PersistentStorageOpCertStore::CommitOpCertsForFabric(FabricIndex fabr { // Neither of these conditions should have occurred based on other interlocks, but since // committing certificates is a dangerous operation, we absolutely validate our assumptions. - ReturnErrorCodeIf(mStateFlags.Has(StateFlags::kUpdateOpCertsCalled), CHIP_ERROR_INCORRECT_STATE); - ReturnErrorCodeIf(!mStateFlags.Has(StateFlags::kAddNewTrustedRootCalled), CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(!mStateFlags.Has(StateFlags::kUpdateOpCertsCalled), CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(mStateFlags.Has(StateFlags::kAddNewTrustedRootCalled), CHIP_ERROR_INCORRECT_STATE); } // TODO: Handle transaction marking to revert partial certs at next boot if we get interrupted by reboot. @@ -405,7 +405,7 @@ CHIP_ERROR PersistentStorageOpCertStore::RemoveOpCertsForFabric(FabricIndex fabr VerifyOrReturnError(IsValidFabricIndex(fabricIndex), CHIP_ERROR_INVALID_FABRIC_INDEX); // If there was *no* state, pending or persisted, we have an error - ReturnErrorCodeIf(!HasAnyCertificateForFabric(fabricIndex), CHIP_ERROR_INVALID_FABRIC_INDEX); + VerifyOrReturnError(HasAnyCertificateForFabric(fabricIndex), CHIP_ERROR_INVALID_FABRIC_INDEX); // Clear any pending state RevertPendingOpCerts(); diff --git a/src/credentials/TestOnlyLocalCertificateAuthority.h b/src/credentials/TestOnlyLocalCertificateAuthority.h index fb731f9fc98b2e..719b6495a0db24 100644 --- a/src/credentials/TestOnlyLocalCertificateAuthority.h +++ b/src/credentials/TestOnlyLocalCertificateAuthority.h @@ -161,9 +161,9 @@ class TestOnlyLocalCertificateAuthority if (mIncludeIcac) { Platform::ScopedMemoryBufferWithSize icacDerBuf; - ReturnErrorCodeIf(!icacDerBuf.Alloc(Credentials::kMaxDERCertLength), CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(icacDerBuf.Alloc(Credentials::kMaxDERCertLength), CHIP_ERROR_NO_MEMORY); Platform::ScopedMemoryBufferWithSize icacChipBuf; - ReturnErrorCodeIf(!icacChipBuf.Alloc(Credentials::kMaxCHIPCertLength), CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(icacChipBuf.Alloc(Credentials::kMaxCHIPCertLength), CHIP_ERROR_NO_MEMORY); ReturnErrorOnFailure(icac_dn.AddAttribute_MatterFabricId(fabricId)); ReturnErrorOnFailure(icac_dn.AddAttribute_MatterICACId(1234)); @@ -176,7 +176,7 @@ class TestOnlyLocalCertificateAuthority MutableByteSpan icacChipSpan{ icacChipBuf.Get(), icacChipBuf.AllocatedSize() }; ReturnErrorOnFailure(Credentials::ConvertX509CertToChipCert(icacDerSpan, icacChipSpan)); - ReturnErrorCodeIf(!mLastIcac.Alloc(icacChipSpan.size()), CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(mLastIcac.Alloc(icacChipSpan.size()), CHIP_ERROR_NO_MEMORY); memcpy(mLastIcac.Get(), icacChipSpan.data(), icacChipSpan.size()); @@ -187,9 +187,9 @@ class TestOnlyLocalCertificateAuthority // Generate NOC always, either issued from ICAC if present or from RCAC { Platform::ScopedMemoryBufferWithSize nocDerBuf; - ReturnErrorCodeIf(!nocDerBuf.Alloc(Credentials::kMaxDERCertLength), CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(nocDerBuf.Alloc(Credentials::kMaxDERCertLength), CHIP_ERROR_NO_MEMORY); Platform::ScopedMemoryBufferWithSize nocChipBuf; - ReturnErrorCodeIf(!nocChipBuf.Alloc(Credentials::kMaxCHIPCertLength), CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(nocChipBuf.Alloc(Credentials::kMaxCHIPCertLength), CHIP_ERROR_NO_MEMORY); ReturnErrorOnFailure(noc_dn.AddAttribute_MatterFabricId(fabricId)); ReturnErrorOnFailure(noc_dn.AddAttribute_MatterNodeId(nodeId)); @@ -202,7 +202,7 @@ class TestOnlyLocalCertificateAuthority MutableByteSpan nocChipSpan{ nocChipBuf.Get(), nocChipBuf.AllocatedSize() }; ReturnErrorOnFailure(Credentials::ConvertX509CertToChipCert(nocDerSpan, nocChipSpan)); - ReturnErrorCodeIf(!mLastNoc.Alloc(nocChipSpan.size()), CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(mLastNoc.Alloc(nocChipSpan.size()), CHIP_ERROR_NO_MEMORY); memcpy(mLastNoc.Get(), nocChipSpan.data(), nocChipSpan.size()); } diff --git a/src/credentials/attestation_verifier/DefaultDeviceAttestationVerifier.cpp b/src/credentials/attestation_verifier/DefaultDeviceAttestationVerifier.cpp index 14759d850ffc40..f9cf68e6cf24bd 100644 --- a/src/credentials/attestation_verifier/DefaultDeviceAttestationVerifier.cpp +++ b/src/credentials/attestation_verifier/DefaultDeviceAttestationVerifier.cpp @@ -627,9 +627,9 @@ bool CsaCdKeysTrustStore::IsCdTestKey(const ByteSpan & kid) const CHIP_ERROR CsaCdKeysTrustStore::AddTrustedKey(const ByteSpan & kid, const Crypto::P256PublicKey & pubKey) { - ReturnErrorCodeIf(kid.size() > SingleKeyEntry::kMaxKidSize, CHIP_ERROR_INVALID_ARGUMENT); - ReturnErrorCodeIf(kid.empty(), CHIP_ERROR_INVALID_ARGUMENT); - ReturnErrorCodeIf(mNumTrustedKeys == kMaxNumTrustedKeys, CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(kid.size() <= SingleKeyEntry::kMaxKidSize, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(!kid.empty(), CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(mNumTrustedKeys != kMaxNumTrustedKeys, CHIP_ERROR_NO_MEMORY); auto & entry = mTrustedKeys[mNumTrustedKeys]; diff --git a/src/crypto/CHIPCryptoPAL.cpp b/src/crypto/CHIPCryptoPAL.cpp index fa84d786b8eabb..2caecbcb156779 100644 --- a/src/crypto/CHIPCryptoPAL.cpp +++ b/src/crypto/CHIPCryptoPAL.cpp @@ -75,7 +75,7 @@ CHIP_ERROR ReadDerUnsignedIntegerIntoRaw(Reader & reader, MutableByteSpan raw_in // Check for pseudo-zero to mark unsigned value // This means we have too large an integer (should be at most 1 byte too large), it's invalid - ReturnErrorCodeIf(integer_len > (raw_integer_out.size() + 1), CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(integer_len <= (raw_integer_out.size() + 1), CHIP_ERROR_INVALID_ARGUMENT); if (integer_len == (raw_integer_out.size() + 1u)) { @@ -603,10 +603,10 @@ CHIP_ERROR Spake2pVerifier::ComputeWS(uint32_t pbkdf2IterCount, const ByteSpan & uint8_t littleEndianSetupPINCode[sizeof(uint32_t)]; Encoding::LittleEndian::Put32(littleEndianSetupPINCode, setupPin); - ReturnErrorCodeIf(salt.size() < kSpake2p_Min_PBKDF_Salt_Length || salt.size() > kSpake2p_Max_PBKDF_Salt_Length, - CHIP_ERROR_INVALID_ARGUMENT); - ReturnErrorCodeIf(pbkdf2IterCount < kSpake2p_Min_PBKDF_Iterations || pbkdf2IterCount > kSpake2p_Max_PBKDF_Iterations, - CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(salt.size() >= kSpake2p_Min_PBKDF_Salt_Length && salt.size() <= kSpake2p_Max_PBKDF_Salt_Length, + CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(pbkdf2IterCount >= kSpake2p_Min_PBKDF_Iterations && pbkdf2IterCount <= kSpake2p_Max_PBKDF_Iterations, + CHIP_ERROR_INVALID_ARGUMENT); return pbkdf2.pbkdf2_sha256(littleEndianSetupPINCode, sizeof(littleEndianSetupPINCode), salt.data(), salt.size(), pbkdf2IterCount, ws_len, ws); @@ -925,8 +925,8 @@ CHIP_ERROR DeriveGroupOperationalCredentials(const ByteSpan & epoch_key, const B CHIP_ERROR ExtractVIDPIDFromAttributeString(DNAttrType attrType, const ByteSpan & attr, AttestationCertVidPid & vidpidFromMatterAttr, AttestationCertVidPid & vidpidFromCNAttr) { - ReturnErrorCodeIf(attrType == DNAttrType::kUnspecified, CHIP_NO_ERROR); - ReturnErrorCodeIf(attr.empty(), CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(attrType != DNAttrType::kUnspecified, CHIP_NO_ERROR); + VerifyOrReturnError(!attr.empty(), CHIP_ERROR_INVALID_ARGUMENT); if (attrType == DNAttrType::kMatterVID || attrType == DNAttrType::kMatterPID) { @@ -939,13 +939,13 @@ CHIP_ERROR ExtractVIDPIDFromAttributeString(DNAttrType attrType, const ByteSpan if (attrType == DNAttrType::kMatterVID) { // Not more than one VID attribute can be present. - ReturnErrorCodeIf(vidpidFromMatterAttr.mVendorId.HasValue(), CHIP_ERROR_WRONG_CERT_DN); + VerifyOrReturnError(!vidpidFromMatterAttr.mVendorId.HasValue(), CHIP_ERROR_WRONG_CERT_DN); vidpidFromMatterAttr.mVendorId.SetValue(static_cast(matterAttr)); } else { // Not more than one PID attribute can be present. - ReturnErrorCodeIf(vidpidFromMatterAttr.mProductId.HasValue(), CHIP_ERROR_WRONG_CERT_DN); + VerifyOrReturnError(!vidpidFromMatterAttr.mProductId.HasValue(), CHIP_ERROR_WRONG_CERT_DN); vidpidFromMatterAttr.mProductId.SetValue(matterAttr); } } diff --git a/src/crypto/CHIPCryptoPALOpenSSL.cpp b/src/crypto/CHIPCryptoPALOpenSSL.cpp index 6b4b17daf005d0..c1182ac8ebe03c 100644 --- a/src/crypto/CHIPCryptoPALOpenSSL.cpp +++ b/src/crypto/CHIPCryptoPALOpenSSL.cpp @@ -2297,11 +2297,11 @@ CHIP_ERROR ReplaceCertIfResignedCertFound(const ByteSpan & referenceCertificate, MutableByteSpan referenceSKID(referenceSKIDBuf); MutableByteSpan candidateSKID(candidateSKIDBuf); - ReturnErrorCodeIf(referenceCertificate.empty(), CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(!referenceCertificate.empty(), CHIP_ERROR_INVALID_ARGUMENT); outCertificate = referenceCertificate; - ReturnErrorCodeIf(candidateCertificates == nullptr || candidateCertificatesCount == 0, CHIP_NO_ERROR); + VerifyOrReturnError(candidateCertificates != nullptr && candidateCertificatesCount != 0, CHIP_NO_ERROR); ReturnErrorOnFailure(ExtractSKIDFromX509Cert(referenceCertificate, referenceSKID)); diff --git a/src/crypto/CHIPCryptoPALmbedTLSCert.cpp b/src/crypto/CHIPCryptoPALmbedTLSCert.cpp index 11eab025193135..00053ee5b7ea9c 100644 --- a/src/crypto/CHIPCryptoPALmbedTLSCert.cpp +++ b/src/crypto/CHIPCryptoPALmbedTLSCert.cpp @@ -982,7 +982,7 @@ CHIP_ERROR ExtractRawDNFromX509Cert(bool extractSubject, const ByteSpan & certif size_t len = 0; mbedtls_x509_crt mbedCertificate; - ReturnErrorCodeIf(certificate.empty(), CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(!certificate.empty(), CHIP_ERROR_INVALID_ARGUMENT); mbedtls_x509_crt_init(&mbedCertificate); result = mbedtls_x509_crt_parse(&mbedCertificate, Uint8::to_const_uchar(certificate.data()), certificate.size()); @@ -1038,7 +1038,7 @@ CHIP_ERROR ReplaceCertIfResignedCertFound(const ByteSpan & referenceCertificate, outCertificate = referenceCertificate; - ReturnErrorCodeIf(candidateCertificates == nullptr || candidateCertificatesCount == 0, CHIP_NO_ERROR); + VerifyOrReturnError(candidateCertificates != nullptr && candidateCertificatesCount != 0, CHIP_NO_ERROR); ReturnErrorOnFailure(ExtractSubjectFromX509Cert(referenceCertificate, referenceSubject)); ReturnErrorOnFailure(ExtractSKIDFromX509Cert(referenceCertificate, referenceSKID)); diff --git a/src/crypto/PSAOperationalKeystore.cpp b/src/crypto/PSAOperationalKeystore.cpp index 09e00bc9b581f9..b0d0e133e41c21 100644 --- a/src/crypto/PSAOperationalKeystore.cpp +++ b/src/crypto/PSAOperationalKeystore.cpp @@ -88,7 +88,7 @@ CHIP_ERROR PSAOperationalKeystore::PersistentP256Keypair::Destroy() { psa_status_t status = psa_destroy_key(GetKeyId()); - ReturnErrorCodeIf(status == PSA_ERROR_INVALID_HANDLE, CHIP_ERROR_INVALID_FABRIC_INDEX); + VerifyOrReturnError(status != PSA_ERROR_INVALID_HANDLE, CHIP_ERROR_INVALID_FABRIC_INDEX); VerifyOrReturnError(status == PSA_SUCCESS, CHIP_ERROR_INTERNAL); return CHIP_NO_ERROR; diff --git a/src/include/platform/internal/GenericConfigurationManagerImpl.ipp b/src/include/platform/internal/GenericConfigurationManagerImpl.ipp index 9b36f341042aa9..d9769576c90f7b 100644 --- a/src/include/platform/internal/GenericConfigurationManagerImpl.ipp +++ b/src/include/platform/internal/GenericConfigurationManagerImpl.ipp @@ -177,7 +177,7 @@ CHIP_ERROR LegacyTemporaryCommissionableDataProvider::GetSpake2pSal if (err == CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND) { saltB64Len = strlen(CHIP_DEVICE_CONFIG_USE_TEST_SPAKE2P_SALT); - ReturnErrorCodeIf(saltB64Len > sizeof(saltB64), CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(saltB64Len <= sizeof(saltB64), CHIP_ERROR_BUFFER_TOO_SMALL); memcpy(saltB64, CHIP_DEVICE_CONFIG_USE_TEST_SPAKE2P_SALT, saltB64Len); err = CHIP_NO_ERROR; } @@ -189,7 +189,7 @@ CHIP_ERROR LegacyTemporaryCommissionableDataProvider::GetSpake2pSal size_t saltLen = chip::Base64Decode32(saltB64, static_cast(saltB64Len), reinterpret_cast(saltB64)); - ReturnErrorCodeIf(saltLen > saltBuf.size(), CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(saltLen <= saltBuf.size(), CHIP_ERROR_BUFFER_TOO_SMALL); memcpy(saltBuf.data(), saltB64, saltLen); saltBuf.reduce_size(saltLen); @@ -214,7 +214,7 @@ CHIP_ERROR LegacyTemporaryCommissionableDataProvider::GetSpake2pVer if (err == CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND) { verifierB64Len = strlen(CHIP_DEVICE_CONFIG_USE_TEST_SPAKE2P_VERIFIER); - ReturnErrorCodeIf(verifierB64Len > sizeof(verifierB64), CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(verifierB64Len <= sizeof(verifierB64), CHIP_ERROR_BUFFER_TOO_SMALL); memcpy(verifierB64, CHIP_DEVICE_CONFIG_USE_TEST_SPAKE2P_VERIFIER, verifierB64Len); err = CHIP_NO_ERROR; } @@ -226,7 +226,7 @@ CHIP_ERROR LegacyTemporaryCommissionableDataProvider::GetSpake2pVer verifierLen = chip::Base64Decode32(verifierB64, static_cast(verifierB64Len), reinterpret_cast(verifierB64)); - ReturnErrorCodeIf(verifierLen > verifierBuf.size(), CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(verifierLen <= verifierBuf.size(), CHIP_ERROR_BUFFER_TOO_SMALL); memcpy(verifierBuf.data(), verifierB64, verifierLen); verifierBuf.reduce_size(verifierLen); @@ -351,7 +351,7 @@ CHIP_ERROR GenericConfigurationManagerImpl::GetSecondaryPairingHint template CHIP_ERROR GenericConfigurationManagerImpl::GetSoftwareVersionString(char * buf, size_t bufSize) { - ReturnErrorCodeIf(bufSize < sizeof(CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING), CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(bufSize >= sizeof(CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING), CHIP_ERROR_BUFFER_TOO_SMALL); strcpy(buf, CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING); return CHIP_NO_ERROR; } @@ -516,8 +516,8 @@ CHIP_ERROR GenericConfigurationManagerImpl::GetUniqueId(char * buf, ReturnErrorOnFailure(err); - ReturnErrorCodeIf(uniqueIdLen >= bufSize, CHIP_ERROR_BUFFER_TOO_SMALL); - ReturnErrorCodeIf(buf[uniqueIdLen] != 0, CHIP_ERROR_INVALID_STRING_LENGTH); + VerifyOrReturnError(uniqueIdLen < bufSize, CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(buf[uniqueIdLen] == 0, CHIP_ERROR_INVALID_STRING_LENGTH); return err; } @@ -552,8 +552,8 @@ CHIP_ERROR GenericConfigurationManagerImpl::IncrementLifetimeCounte template CHIP_ERROR GenericConfigurationManagerImpl::SetRotatingDeviceIdUniqueId(const ByteSpan & uniqueIdSpan) { - ReturnErrorCodeIf(uniqueIdSpan.size() < kMinRotatingDeviceIDUniqueIDLength, CHIP_ERROR_INVALID_ARGUMENT); - ReturnErrorCodeIf(uniqueIdSpan.size() > CHIP_DEVICE_CONFIG_ROTATING_DEVICE_ID_UNIQUE_ID_LENGTH, CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(uniqueIdSpan.size() >= kMinRotatingDeviceIDUniqueIDLength, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(uniqueIdSpan.size() <= CHIP_DEVICE_CONFIG_ROTATING_DEVICE_ID_UNIQUE_ID_LENGTH, CHIP_ERROR_BUFFER_TOO_SMALL); memcpy(mRotatingDeviceIdUniqueId, uniqueIdSpan.data(), uniqueIdSpan.size()); mRotatingDeviceIdUniqueIdLength = uniqueIdSpan.size(); return CHIP_NO_ERROR; @@ -562,7 +562,7 @@ CHIP_ERROR GenericConfigurationManagerImpl::SetRotatingDeviceIdUniq template CHIP_ERROR GenericConfigurationManagerImpl::GetRotatingDeviceIdUniqueId(MutableByteSpan & uniqueIdSpan) { - ReturnErrorCodeIf(mRotatingDeviceIdUniqueIdLength > uniqueIdSpan.size(), CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(mRotatingDeviceIdUniqueIdLength <= uniqueIdSpan.size(), CHIP_ERROR_BUFFER_TOO_SMALL); memcpy(uniqueIdSpan.data(), mRotatingDeviceIdUniqueId, mRotatingDeviceIdUniqueIdLength); uniqueIdSpan.reduce_size(mRotatingDeviceIdUniqueIdLength); return CHIP_NO_ERROR; @@ -646,7 +646,7 @@ bool GenericConfigurationManagerImpl::IsCommissionableDeviceNameEna template CHIP_ERROR GenericConfigurationManagerImpl::GetCommissionableDeviceName(char * buf, size_t bufSize) { - ReturnErrorCodeIf(bufSize < sizeof(CHIP_DEVICE_CONFIG_DEVICE_NAME), CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(bufSize >= sizeof(CHIP_DEVICE_CONFIG_DEVICE_NAME), CHIP_ERROR_BUFFER_TOO_SMALL); strcpy(buf, CHIP_DEVICE_CONFIG_DEVICE_NAME); return CHIP_NO_ERROR; } @@ -654,7 +654,7 @@ CHIP_ERROR GenericConfigurationManagerImpl::GetCommissionableDevice template CHIP_ERROR GenericConfigurationManagerImpl::GetInitialPairingInstruction(char * buf, size_t bufSize) { - ReturnErrorCodeIf(bufSize < sizeof(CHIP_DEVICE_CONFIG_PAIRING_INITIAL_INSTRUCTION), CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(bufSize >= sizeof(CHIP_DEVICE_CONFIG_PAIRING_INITIAL_INSTRUCTION), CHIP_ERROR_BUFFER_TOO_SMALL); strcpy(buf, CHIP_DEVICE_CONFIG_PAIRING_INITIAL_INSTRUCTION); return CHIP_NO_ERROR; } @@ -662,7 +662,7 @@ CHIP_ERROR GenericConfigurationManagerImpl::GetInitialPairingInstru template CHIP_ERROR GenericConfigurationManagerImpl::GetSecondaryPairingInstruction(char * buf, size_t bufSize) { - ReturnErrorCodeIf(bufSize < sizeof(CHIP_DEVICE_CONFIG_PAIRING_SECONDARY_INSTRUCTION), CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(bufSize >= sizeof(CHIP_DEVICE_CONFIG_PAIRING_SECONDARY_INSTRUCTION), CHIP_ERROR_BUFFER_TOO_SMALL); strcpy(buf, CHIP_DEVICE_CONFIG_PAIRING_SECONDARY_INSTRUCTION); return CHIP_NO_ERROR; } diff --git a/src/include/platform/internal/GenericDeviceInstanceInfoProvider.ipp b/src/include/platform/internal/GenericDeviceInstanceInfoProvider.ipp index 549c3eb360aa95..4febf883850277 100644 --- a/src/include/platform/internal/GenericDeviceInstanceInfoProvider.ipp +++ b/src/include/platform/internal/GenericDeviceInstanceInfoProvider.ipp @@ -38,7 +38,7 @@ CHIP_ERROR GenericDeviceInstanceInfoProvider::GetProductId(uint16_t template CHIP_ERROR GenericDeviceInstanceInfoProvider::GetVendorName(char * buf, size_t bufSize) { - ReturnErrorCodeIf(bufSize < sizeof(CHIP_DEVICE_CONFIG_DEVICE_VENDOR_NAME), CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(bufSize >= sizeof(CHIP_DEVICE_CONFIG_DEVICE_VENDOR_NAME), CHIP_ERROR_BUFFER_TOO_SMALL); strcpy(buf, CHIP_DEVICE_CONFIG_DEVICE_VENDOR_NAME); return CHIP_NO_ERROR; } @@ -46,7 +46,7 @@ CHIP_ERROR GenericDeviceInstanceInfoProvider::GetVendorName(char * template CHIP_ERROR GenericDeviceInstanceInfoProvider::GetProductName(char * buf, size_t bufSize) { - ReturnErrorCodeIf(bufSize < sizeof(CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_NAME), CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(bufSize >= sizeof(CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_NAME), CHIP_ERROR_BUFFER_TOO_SMALL); strcpy(buf, CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_NAME); return CHIP_NO_ERROR; @@ -99,7 +99,7 @@ CHIP_ERROR GenericDeviceInstanceInfoProvider::GetSerialNumber(char #ifdef CHIP_DEVICE_CONFIG_TEST_SERIAL_NUMBER if (CHIP_DEVICE_CONFIG_TEST_SERIAL_NUMBER[0] != 0 && err == CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND) { - ReturnErrorCodeIf(sizeof(CHIP_DEVICE_CONFIG_TEST_SERIAL_NUMBER) > bufSize, CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(sizeof(CHIP_DEVICE_CONFIG_TEST_SERIAL_NUMBER) <= bufSize, CHIP_ERROR_BUFFER_TOO_SMALL); memcpy(buf, CHIP_DEVICE_CONFIG_TEST_SERIAL_NUMBER, sizeof(CHIP_DEVICE_CONFIG_TEST_SERIAL_NUMBER)); serialNumLen = sizeof(CHIP_DEVICE_CONFIG_TEST_SERIAL_NUMBER) - 1; err = CHIP_NO_ERROR; @@ -107,8 +107,8 @@ CHIP_ERROR GenericDeviceInstanceInfoProvider::GetSerialNumber(char #endif // CHIP_DEVICE_CONFIG_TEST_SERIAL_NUMBER ReturnErrorOnFailure(err); - ReturnErrorCodeIf(serialNumLen >= bufSize, CHIP_ERROR_BUFFER_TOO_SMALL); - ReturnErrorCodeIf(buf[serialNumLen] != 0, CHIP_ERROR_INVALID_STRING_LENGTH); + VerifyOrReturnError(serialNumLen < bufSize, CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(buf[serialNumLen] == 0, CHIP_ERROR_INVALID_STRING_LENGTH); return err; } @@ -176,7 +176,7 @@ CHIP_ERROR GenericDeviceInstanceInfoProvider::GetHardwareVersion(ui template CHIP_ERROR GenericDeviceInstanceInfoProvider::GetHardwareVersionString(char * buf, size_t bufSize) { - ReturnErrorCodeIf(bufSize < sizeof(CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION_STRING), CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(bufSize >= sizeof(CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION_STRING), CHIP_ERROR_BUFFER_TOO_SMALL); strcpy(buf, CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION_STRING); return CHIP_NO_ERROR; } @@ -194,8 +194,8 @@ CHIP_ERROR GenericDeviceInstanceInfoProvider::GetRotatingDeviceIdUn constexpr uint8_t uniqueId[] = CHIP_DEVICE_CONFIG_ROTATING_DEVICE_ID_UNIQUE_ID; - ReturnErrorCodeIf(sizeof(uniqueId) > uniqueIdSpan.size(), CHIP_ERROR_BUFFER_TOO_SMALL); - ReturnErrorCodeIf(sizeof(uniqueId) != ConfigurationManager::kRotatingDeviceIDUniqueIDLength, CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(sizeof(uniqueId) <= uniqueIdSpan.size(), CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(sizeof(uniqueId) == ConfigurationManager::kRotatingDeviceIDUniqueIDLength, CHIP_ERROR_BUFFER_TOO_SMALL); memcpy(uniqueIdSpan.data(), uniqueId, sizeof(uniqueId)); uniqueIdSpan.reduce_size(sizeof(uniqueId)); } diff --git a/src/lib/asn1/ASN1OID.cpp b/src/lib/asn1/ASN1OID.cpp index 4734a4aa7ad527..70ac838ccf5e8e 100644 --- a/src/lib/asn1/ASN1OID.cpp +++ b/src/lib/asn1/ASN1OID.cpp @@ -107,9 +107,9 @@ const char * GetOIDName(OID oid) CHIP_ERROR ASN1Reader::GetObjectId(OID & oid) { - ReturnErrorCodeIf(Value == nullptr, ASN1_ERROR_INVALID_STATE); - ReturnErrorCodeIf(ValueLen < 1, ASN1_ERROR_INVALID_ENCODING); - ReturnErrorCodeIf(mElemStart + mHeadLen + ValueLen > mContainerEnd, ASN1_ERROR_UNDERRUN); + VerifyOrReturnError(Value != nullptr, ASN1_ERROR_INVALID_STATE); + VerifyOrReturnError(ValueLen >= 1, ASN1_ERROR_INVALID_ENCODING); + VerifyOrReturnError(mElemStart + mHeadLen + ValueLen <= mContainerEnd, ASN1_ERROR_UNDERRUN); VerifyOrReturnError(CanCastTo(ValueLen), ASN1_ERROR_INVALID_ENCODING); oid = ParseObjectID(Value, static_cast(ValueLen)); return CHIP_NO_ERROR; diff --git a/src/lib/asn1/ASN1Reader.cpp b/src/lib/asn1/ASN1Reader.cpp index 6039e1ae084561..1a053f307f101d 100644 --- a/src/lib/asn1/ASN1Reader.cpp +++ b/src/lib/asn1/ASN1Reader.cpp @@ -50,8 +50,8 @@ void ASN1Reader::Init(const uint8_t * buf, size_t len) CHIP_ERROR ASN1Reader::Next() { - ReturnErrorCodeIf(EndOfContents, ASN1_END); - ReturnErrorCodeIf(IndefiniteLen, ASN1_ERROR_UNSUPPORTED_ENCODING); + VerifyOrReturnError(!EndOfContents, ASN1_END); + VerifyOrReturnError(!IndefiniteLen, ASN1_ERROR_UNSUPPORTED_ENCODING); // Note: avoid using addition assignment operator (+=), which may result in integer overflow // in the right hand side of an assignment (mHeadLen + ValueLen). @@ -59,14 +59,14 @@ CHIP_ERROR ASN1Reader::Next() ResetElementState(); - ReturnErrorCodeIf(mElemStart == mContainerEnd, ASN1_END); + VerifyOrReturnError(mElemStart != mContainerEnd, ASN1_END); return DecodeHead(); } CHIP_ERROR ASN1Reader::EnterConstructedType() { - ReturnErrorCodeIf(!Constructed, ASN1_ERROR_INVALID_STATE); + VerifyOrReturnError(Constructed, ASN1_ERROR_INVALID_STATE); return EnterContainer(0); } @@ -78,7 +78,7 @@ CHIP_ERROR ASN1Reader::ExitConstructedType() CHIP_ERROR ASN1Reader::GetConstructedType(const uint8_t *& val, uint32_t & valLen) { - ReturnErrorCodeIf(!Constructed, ASN1_ERROR_INVALID_STATE); + VerifyOrReturnError(Constructed, ASN1_ERROR_INVALID_STATE); val = mElemStart; valLen = mHeadLen + ValueLen; @@ -91,7 +91,7 @@ CHIP_ERROR ASN1Reader::EnterEncapsulatedType() (Tag == kASN1UniversalTag_OctetString || Tag == kASN1UniversalTag_BitString), ASN1_ERROR_INVALID_STATE); - ReturnErrorCodeIf(Constructed, ASN1_ERROR_UNSUPPORTED_ENCODING); + VerifyOrReturnError(!Constructed, ASN1_ERROR_UNSUPPORTED_ENCODING); return EnterContainer((Tag == kASN1UniversalTag_BitString) ? 1 : 0); } @@ -103,7 +103,7 @@ CHIP_ERROR ASN1Reader::ExitEncapsulatedType() CHIP_ERROR ASN1Reader::EnterContainer(uint32_t offset) { - ReturnErrorCodeIf(mNumSavedContexts == kMaxContextDepth, ASN1_ERROR_MAX_DEPTH_EXCEEDED); + VerifyOrReturnError(mNumSavedContexts != kMaxContextDepth, ASN1_ERROR_MAX_DEPTH_EXCEEDED); mSavedContexts[mNumSavedContexts].ElemStart = mElemStart; mSavedContexts[mNumSavedContexts].HeadLen = mHeadLen; @@ -127,11 +127,11 @@ CHIP_ERROR ASN1Reader::EnterContainer(uint32_t offset) CHIP_ERROR ASN1Reader::ExitContainer() { - ReturnErrorCodeIf(mNumSavedContexts == 0, ASN1_ERROR_INVALID_STATE); + VerifyOrReturnError(mNumSavedContexts != 0, ASN1_ERROR_INVALID_STATE); ASN1ParseContext & prevContext = mSavedContexts[--mNumSavedContexts]; - ReturnErrorCodeIf(prevContext.IndefiniteLen, ASN1_ERROR_UNSUPPORTED_ENCODING); + VerifyOrReturnError(!prevContext.IndefiniteLen, ASN1_ERROR_UNSUPPORTED_ENCODING); mElemStart = prevContext.ElemStart + prevContext.HeadLen + prevContext.ValueLen; @@ -152,10 +152,10 @@ CHIP_ERROR ASN1Reader::GetInteger(int64_t & val) uint8_t encodedVal[sizeof(int64_t)] = { 0 }; size_t valPaddingLen = sizeof(int64_t) - ValueLen; - ReturnErrorCodeIf(Value == nullptr, ASN1_ERROR_INVALID_STATE); - ReturnErrorCodeIf(ValueLen < 1, ASN1_ERROR_INVALID_ENCODING); - ReturnErrorCodeIf(ValueLen > sizeof(int64_t), ASN1_ERROR_VALUE_OVERFLOW); - ReturnErrorCodeIf(mElemStart + mHeadLen + ValueLen > mContainerEnd, ASN1_ERROR_UNDERRUN); + VerifyOrReturnError(Value != nullptr, ASN1_ERROR_INVALID_STATE); + VerifyOrReturnError(ValueLen >= 1, ASN1_ERROR_INVALID_ENCODING); + VerifyOrReturnError(ValueLen <= sizeof(int64_t), ASN1_ERROR_VALUE_OVERFLOW); + VerifyOrReturnError(mElemStart + mHeadLen + ValueLen <= mContainerEnd, ASN1_ERROR_UNDERRUN); if ((*Value & 0x80) == 0x80) { @@ -173,9 +173,9 @@ CHIP_ERROR ASN1Reader::GetInteger(int64_t & val) CHIP_ERROR ASN1Reader::GetBoolean(bool & val) { - ReturnErrorCodeIf(Value == nullptr, ASN1_ERROR_INVALID_STATE); - ReturnErrorCodeIf(ValueLen != 1, ASN1_ERROR_INVALID_ENCODING); - ReturnErrorCodeIf(mElemStart + mHeadLen + ValueLen > mContainerEnd, ASN1_ERROR_UNDERRUN); + VerifyOrReturnError(Value != nullptr, ASN1_ERROR_INVALID_STATE); + VerifyOrReturnError(ValueLen == 1, ASN1_ERROR_INVALID_ENCODING); + VerifyOrReturnError(mElemStart + mHeadLen + ValueLen <= mContainerEnd, ASN1_ERROR_UNDERRUN); VerifyOrReturnError(Value[0] == 0 || Value[0] == 0xFF, ASN1_ERROR_INVALID_ENCODING); val = (Value[0] != 0); @@ -186,9 +186,9 @@ CHIP_ERROR ASN1Reader::GetBoolean(bool & val) CHIP_ERROR ASN1Reader::GetUTCTime(ASN1UniversalTime & outTime) { // Supported Encoding: YYMMDDHHMMSSZ - ReturnErrorCodeIf(Value == nullptr, ASN1_ERROR_INVALID_STATE); - ReturnErrorCodeIf(ValueLen < 1, ASN1_ERROR_INVALID_ENCODING); - ReturnErrorCodeIf(mElemStart + mHeadLen + ValueLen > mContainerEnd, ASN1_ERROR_UNDERRUN); + VerifyOrReturnError(Value != nullptr, ASN1_ERROR_INVALID_STATE); + VerifyOrReturnError(ValueLen >= 1, ASN1_ERROR_INVALID_ENCODING); + VerifyOrReturnError(mElemStart + mHeadLen + ValueLen <= mContainerEnd, ASN1_ERROR_UNDERRUN); VerifyOrReturnError(ValueLen == 13 && Value[12] == 'Z', ASN1_ERROR_UNSUPPORTED_ENCODING); return outTime.ImportFrom_ASN1_TIME_string(CharSpan(reinterpret_cast(Value), ValueLen)); @@ -197,9 +197,9 @@ CHIP_ERROR ASN1Reader::GetUTCTime(ASN1UniversalTime & outTime) CHIP_ERROR ASN1Reader::GetGeneralizedTime(ASN1UniversalTime & outTime) { // Supported Encoding: YYYYMMDDHHMMSSZ - ReturnErrorCodeIf(Value == nullptr, ASN1_ERROR_INVALID_STATE); - ReturnErrorCodeIf(ValueLen < 1, ASN1_ERROR_INVALID_ENCODING); - ReturnErrorCodeIf(mElemStart + mHeadLen + ValueLen > mContainerEnd, ASN1_ERROR_UNDERRUN); + VerifyOrReturnError(Value != nullptr, ASN1_ERROR_INVALID_STATE); + VerifyOrReturnError(ValueLen >= 1, ASN1_ERROR_INVALID_ENCODING); + VerifyOrReturnError(mElemStart + mHeadLen + ValueLen <= mContainerEnd, ASN1_ERROR_UNDERRUN); VerifyOrReturnError(ValueLen == 15 && Value[14] == 'Z', ASN1_ERROR_UNSUPPORTED_ENCODING); return outTime.ImportFrom_ASN1_TIME_string(CharSpan(reinterpret_cast(Value), ValueLen)); @@ -219,10 +219,10 @@ static uint8_t ReverseBits(uint8_t v) CHIP_ERROR ASN1Reader::GetBitString(uint32_t & outVal) { // NOTE: only supports DER encoding. - ReturnErrorCodeIf(Value == nullptr, ASN1_ERROR_INVALID_STATE); - ReturnErrorCodeIf(ValueLen < 1, ASN1_ERROR_INVALID_ENCODING); - ReturnErrorCodeIf(ValueLen > 5, ASN1_ERROR_UNSUPPORTED_ENCODING); - ReturnErrorCodeIf(mElemStart + mHeadLen + ValueLen > mContainerEnd, ASN1_ERROR_UNDERRUN); + VerifyOrReturnError(Value != nullptr, ASN1_ERROR_INVALID_STATE); + VerifyOrReturnError(ValueLen >= 1, ASN1_ERROR_INVALID_ENCODING); + VerifyOrReturnError(ValueLen <= 5, ASN1_ERROR_UNSUPPORTED_ENCODING); + VerifyOrReturnError(mElemStart + mHeadLen + ValueLen <= mContainerEnd, ASN1_ERROR_UNDERRUN); if (ValueLen == 1) { @@ -244,7 +244,7 @@ CHIP_ERROR ASN1Reader::GetBitString(uint32_t & outVal) CHIP_ERROR ASN1Reader::DecodeHead() { const uint8_t * p = mElemStart; - ReturnErrorCodeIf(p >= mBufEnd, ASN1_ERROR_UNDERRUN); + VerifyOrReturnError(p < mBufEnd, ASN1_ERROR_UNDERRUN); Class = *p & 0xC0; Constructed = (*p & 0x20) != 0; @@ -254,7 +254,7 @@ CHIP_ERROR ASN1Reader::DecodeHead() VerifyOrReturnError(Tag < 0x1F, ASN1_ERROR_UNSUPPORTED_ENCODING); p++; - ReturnErrorCodeIf(p >= mBufEnd, ASN1_ERROR_UNDERRUN); + VerifyOrReturnError(p < mBufEnd, ASN1_ERROR_UNDERRUN); if ((*p & 0x80) == 0) { @@ -275,8 +275,8 @@ CHIP_ERROR ASN1Reader::DecodeHead() p++; for (; lenLen > 0; lenLen--, p++) { - ReturnErrorCodeIf(p >= mBufEnd, ASN1_ERROR_UNDERRUN); - ReturnErrorCodeIf((ValueLen & 0xFF000000) != 0, ASN1_ERROR_LENGTH_OVERFLOW); + VerifyOrReturnError(p < mBufEnd, ASN1_ERROR_UNDERRUN); + VerifyOrReturnError((ValueLen & 0xFF000000) == 0, ASN1_ERROR_LENGTH_OVERFLOW); ValueLen = (ValueLen << 8) | *p; } IndefiniteLen = false; diff --git a/src/lib/asn1/ASN1Writer.cpp b/src/lib/asn1/ASN1Writer.cpp index f916d138ae3c4d..4bdb8eaa04a091 100644 --- a/src/lib/asn1/ASN1Writer.cpp +++ b/src/lib/asn1/ASN1Writer.cpp @@ -72,7 +72,7 @@ size_t ASN1Writer::GetLengthWritten() const CHIP_ERROR ASN1Writer::PutInteger(int64_t val) { - ReturnErrorCodeIf(IsNullWriter(), CHIP_NO_ERROR); + VerifyOrReturnError(!IsNullWriter(), CHIP_NO_ERROR); uint8_t encodedVal[sizeof(int64_t)]; uint8_t valStart, valLen; @@ -94,7 +94,7 @@ CHIP_ERROR ASN1Writer::PutInteger(int64_t val) CHIP_ERROR ASN1Writer::PutBoolean(bool val) { - ReturnErrorCodeIf(IsNullWriter(), CHIP_NO_ERROR); + VerifyOrReturnError(!IsNullWriter(), CHIP_NO_ERROR); ReturnErrorOnFailure(EncodeHead(kASN1TagClass_Universal, kASN1UniversalTag_Boolean, false, 1)); @@ -170,7 +170,7 @@ static uint8_t HighestBit(uint32_t v) CHIP_ERROR ASN1Writer::PutBitString(uint32_t val) { - ReturnErrorCodeIf(IsNullWriter(), CHIP_NO_ERROR); + VerifyOrReturnError(!IsNullWriter(), CHIP_NO_ERROR); uint8_t len; if (val == 0) @@ -218,7 +218,7 @@ CHIP_ERROR ASN1Writer::PutBitString(uint32_t val) CHIP_ERROR ASN1Writer::PutBitString(uint8_t unusedBitCount, const uint8_t * encodedBits, uint16_t encodedBitsLen) { - ReturnErrorCodeIf(IsNullWriter(), CHIP_NO_ERROR); + VerifyOrReturnError(!IsNullWriter(), CHIP_NO_ERROR); ReturnErrorOnFailure(EncodeHead(kASN1TagClass_Universal, kASN1UniversalTag_BitString, false, encodedBitsLen + 1)); @@ -236,7 +236,7 @@ CHIP_ERROR ASN1Writer::PutBitString(uint8_t unusedBitCount, chip::TLV::TLVReader VerifyOrReturnError(CanCastTo(encodedBits.size() + 1), ASN1_ERROR_LENGTH_OVERFLOW); - ReturnErrorCodeIf(IsNullWriter(), CHIP_NO_ERROR); + VerifyOrReturnError(!IsNullWriter(), CHIP_NO_ERROR); ReturnErrorOnFailure( EncodeHead(kASN1TagClass_Universal, kASN1UniversalTag_BitString, false, static_cast(encodedBits.size() + 1))); @@ -250,7 +250,7 @@ CHIP_ERROR ASN1Writer::PutBitString(uint8_t unusedBitCount, chip::TLV::TLVReader CHIP_ERROR ASN1Writer::PutTime(const ASN1UniversalTime & val) { - ReturnErrorCodeIf(IsNullWriter(), CHIP_NO_ERROR); + VerifyOrReturnError(!IsNullWriter(), CHIP_NO_ERROR); char buf[ASN1UniversalTime::kASN1TimeStringMaxLength]; MutableCharSpan bufSpan(buf); @@ -276,7 +276,7 @@ CHIP_ERROR ASN1Writer::PutNull() CHIP_ERROR ASN1Writer::PutConstructedType(const uint8_t * val, uint16_t valLen) { - ReturnErrorCodeIf(IsNullWriter(), CHIP_NO_ERROR); + VerifyOrReturnError(!IsNullWriter(), CHIP_NO_ERROR); // Make sure we have enough space to write VerifyOrReturnError((mWritePoint + valLen) <= mBufEnd, ASN1_ERROR_OVERFLOW); @@ -298,7 +298,7 @@ CHIP_ERROR ASN1Writer::EndConstructedType() CHIP_ERROR ASN1Writer::StartEncapsulatedType(uint8_t cls, uint8_t tag, bool bitStringEncoding) { - ReturnErrorCodeIf(IsNullWriter(), CHIP_NO_ERROR); + VerifyOrReturnError(!IsNullWriter(), CHIP_NO_ERROR); ReturnErrorOnFailure(EncodeHead(cls, tag, false, kUnknownLength)); @@ -321,7 +321,7 @@ CHIP_ERROR ASN1Writer::EndEncapsulatedType() CHIP_ERROR ASN1Writer::PutValue(uint8_t cls, uint8_t tag, bool isConstructed, const uint8_t * val, uint16_t valLen) { - ReturnErrorCodeIf(IsNullWriter(), CHIP_NO_ERROR); + VerifyOrReturnError(!IsNullWriter(), CHIP_NO_ERROR); ReturnErrorOnFailure(EncodeHead(cls, tag, isConstructed, valLen)); @@ -337,7 +337,7 @@ CHIP_ERROR ASN1Writer::PutValue(uint8_t cls, uint8_t tag, bool isConstructed, ch VerifyOrReturnError(CanCastTo(val.size()), ASN1_ERROR_LENGTH_OVERFLOW); - ReturnErrorCodeIf(IsNullWriter(), CHIP_NO_ERROR); + VerifyOrReturnError(!IsNullWriter(), CHIP_NO_ERROR); ReturnErrorOnFailure(EncodeHead(cls, tag, isConstructed, static_cast(val.size()))); @@ -348,7 +348,7 @@ CHIP_ERROR ASN1Writer::PutValue(uint8_t cls, uint8_t tag, bool isConstructed, ch CHIP_ERROR ASN1Writer::EncodeHead(uint8_t cls, uint8_t tag, bool isConstructed, int32_t len) { - ReturnErrorCodeIf(IsNullWriter(), CHIP_NO_ERROR); + VerifyOrReturnError(!IsNullWriter(), CHIP_NO_ERROR); uint8_t bytesForLen; uint32_t totalLen; @@ -399,7 +399,7 @@ CHIP_ERROR ASN1Writer::EncodeHead(uint8_t cls, uint8_t tag, bool isConstructed, CHIP_ERROR ASN1Writer::WriteDeferredLength() { - ReturnErrorCodeIf(IsNullWriter(), CHIP_NO_ERROR); + VerifyOrReturnError(!IsNullWriter(), CHIP_NO_ERROR); VerifyOrReturnError(mDeferredLengthCount > 0, ASN1_ERROR_INVALID_STATE); diff --git a/src/lib/core/OTAImageHeader.cpp b/src/lib/core/OTAImageHeader.cpp index ab4b65635bc5f4..a4f535f50e6a9a 100644 --- a/src/lib/core/OTAImageHeader.cpp +++ b/src/lib/core/OTAImageHeader.cpp @@ -110,16 +110,16 @@ void OTAImageHeaderParser::Append(ByteSpan & buffer, uint32_t numBytes) CHIP_ERROR OTAImageHeaderParser::DecodeFixed() { - ReturnErrorCodeIf(mBufferOffset < kFixedHeaderSize, CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(mBufferOffset >= kFixedHeaderSize, CHIP_ERROR_BUFFER_TOO_SMALL); Encoding::LittleEndian::Reader reader(mBuffer.Get(), mBufferOffset); uint32_t fileIdentifier; uint64_t totalSize; ReturnErrorOnFailure(reader.Read32(&fileIdentifier).Read64(&totalSize).Read32(&mHeaderTlvSize).StatusCode()); - ReturnErrorCodeIf(fileIdentifier != kOTAImageFileIdentifier, CHIP_ERROR_INVALID_FILE_IDENTIFIER); + VerifyOrReturnError(fileIdentifier == kOTAImageFileIdentifier, CHIP_ERROR_INVALID_FILE_IDENTIFIER); // Safety check against malicious headers. - ReturnErrorCodeIf(mHeaderTlvSize > kMaxHeaderSize, CHIP_ERROR_NO_MEMORY); - ReturnErrorCodeIf(!mBuffer.Alloc(mHeaderTlvSize), CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(mHeaderTlvSize <= kMaxHeaderSize, CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(mBuffer.Alloc(mHeaderTlvSize), CHIP_ERROR_NO_MEMORY); mState = State::kTlv; mBufferOffset = 0; @@ -129,7 +129,7 @@ CHIP_ERROR OTAImageHeaderParser::DecodeFixed() CHIP_ERROR OTAImageHeaderParser::DecodeTlv(OTAImageHeader & header) { - ReturnErrorCodeIf(mBufferOffset < mHeaderTlvSize, CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(mBufferOffset >= mHeaderTlvSize, CHIP_ERROR_BUFFER_TOO_SMALL); TLV::TLVReader tlvReader; tlvReader.Init(mBuffer.Get(), mBufferOffset); @@ -146,7 +146,7 @@ CHIP_ERROR OTAImageHeaderParser::DecodeTlv(OTAImageHeader & header) ReturnErrorOnFailure(tlvReader.Get(header.mSoftwareVersion)); ReturnErrorOnFailure(tlvReader.Next(TLV::ContextTag(Tag::kSoftwareVersionString))); ReturnErrorOnFailure(tlvReader.Get(header.mSoftwareVersionString)); - ReturnErrorCodeIf(header.mSoftwareVersionString.size() > kMaxSoftwareVersionStringSize, CHIP_ERROR_INVALID_STRING_LENGTH); + VerifyOrReturnError(header.mSoftwareVersionString.size() <= kMaxSoftwareVersionStringSize, CHIP_ERROR_INVALID_STRING_LENGTH); ReturnErrorOnFailure(tlvReader.Next(TLV::ContextTag(Tag::kPayloadSize))); ReturnErrorOnFailure(tlvReader.Get(header.mPayloadSize)); ReturnErrorOnFailure(tlvReader.Next()); @@ -166,7 +166,7 @@ CHIP_ERROR OTAImageHeaderParser::DecodeTlv(OTAImageHeader & header) if (tlvReader.GetTag() == TLV::ContextTag(Tag::kReleaseNotesURL)) { ReturnErrorOnFailure(tlvReader.Get(header.mReleaseNotesURL)); - ReturnErrorCodeIf(header.mReleaseNotesURL.size() > kMaxReleaseNotesURLSize, CHIP_ERROR_INVALID_STRING_LENGTH); + VerifyOrReturnError(header.mReleaseNotesURL.size() <= kMaxReleaseNotesURLSize, CHIP_ERROR_INVALID_STRING_LENGTH); ReturnErrorOnFailure(tlvReader.Next()); } diff --git a/src/lib/dnssd/Advertiser_ImplMinimalMdns.cpp b/src/lib/dnssd/Advertiser_ImplMinimalMdns.cpp index ce46137c9a00e2..de8e8422027866 100644 --- a/src/lib/dnssd/Advertiser_ImplMinimalMdns.cpp +++ b/src/lib/dnssd/Advertiser_ImplMinimalMdns.cpp @@ -558,7 +558,7 @@ CHIP_ERROR AdvertiserMinMdns::Advertise(const OperationalAdvertisingParameters & DiscoveryFilter(DiscoveryFilterType::kCompressedFabricId, params.GetPeerId().GetCompressedFabricId())); FullQName compressedFabricIdSubtype = operationalAllocator->AllocateQName( nameBuffer, kSubtypeServiceNamePart, kOperationalServiceName, kOperationalProtocol, kLocalDomain); - ReturnErrorCodeIf(compressedFabricIdSubtype.nameCount == 0, CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(compressedFabricIdSubtype.nameCount != 0, CHIP_ERROR_NO_MEMORY); if (!operationalAllocator->AddResponder(compressedFabricIdSubtype, instanceName) .SetReportAdditional(instanceName) @@ -676,7 +676,7 @@ CHIP_ERROR AdvertiserMinMdns::Advertise(const CommissionAdvertisingParameters & MakeServiceSubtype(nameBuffer, sizeof(nameBuffer), DiscoveryFilter(DiscoveryFilterType::kVendorId, *vendorId)); FullQName vendorServiceName = allocator->AllocateQName(nameBuffer, kSubtypeServiceNamePart, serviceType, kCommissionProtocol, kLocalDomain); - ReturnErrorCodeIf(vendorServiceName.nameCount == 0, CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(vendorServiceName.nameCount != 0, CHIP_ERROR_NO_MEMORY); if (!allocator->AddResponder(vendorServiceName, instanceName) .SetReportAdditional(instanceName) @@ -693,7 +693,7 @@ CHIP_ERROR AdvertiserMinMdns::Advertise(const CommissionAdvertisingParameters & MakeServiceSubtype(nameBuffer, sizeof(nameBuffer), DiscoveryFilter(DiscoveryFilterType::kDeviceType, *deviceType)); FullQName vendorServiceName = allocator->AllocateQName(nameBuffer, kSubtypeServiceNamePart, serviceType, kCommissionProtocol, kLocalDomain); - ReturnErrorCodeIf(vendorServiceName.nameCount == 0, CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(vendorServiceName.nameCount != 0, CHIP_ERROR_NO_MEMORY); if (!allocator->AddResponder(vendorServiceName, instanceName) .SetReportAdditional(instanceName) @@ -713,7 +713,7 @@ CHIP_ERROR AdvertiserMinMdns::Advertise(const CommissionAdvertisingParameters & DiscoveryFilter(DiscoveryFilterType::kShortDiscriminator, params.GetShortDiscriminator())); FullQName shortServiceName = allocator->AllocateQName(nameBuffer, kSubtypeServiceNamePart, serviceType, kCommissionProtocol, kLocalDomain); - ReturnErrorCodeIf(shortServiceName.nameCount == 0, CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(shortServiceName.nameCount != 0, CHIP_ERROR_NO_MEMORY); if (!allocator->AddResponder(shortServiceName, instanceName) .SetReportAdditional(instanceName) @@ -730,7 +730,7 @@ CHIP_ERROR AdvertiserMinMdns::Advertise(const CommissionAdvertisingParameters & DiscoveryFilter(DiscoveryFilterType::kLongDiscriminator, params.GetLongDiscriminator())); FullQName longServiceName = allocator->AllocateQName(nameBuffer, kSubtypeServiceNamePart, serviceType, kCommissionProtocol, kLocalDomain); - ReturnErrorCodeIf(longServiceName.nameCount == 0, CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(longServiceName.nameCount != 0, CHIP_ERROR_NO_MEMORY); if (!allocator->AddResponder(longServiceName, instanceName) .SetReportAdditional(instanceName) .SetReportInServiceListing(true) @@ -746,7 +746,7 @@ CHIP_ERROR AdvertiserMinMdns::Advertise(const CommissionAdvertisingParameters & MakeServiceSubtype(nameBuffer, sizeof(nameBuffer), DiscoveryFilter(DiscoveryFilterType::kCommissioningMode)); FullQName longServiceName = allocator->AllocateQName(nameBuffer, kSubtypeServiceNamePart, serviceType, kCommissionProtocol, kLocalDomain); - ReturnErrorCodeIf(longServiceName.nameCount == 0, CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(longServiceName.nameCount != 0, CHIP_ERROR_NO_MEMORY); if (!allocator->AddResponder(longServiceName, instanceName) .SetReportAdditional(instanceName) .SetReportInServiceListing(true) diff --git a/src/lib/dnssd/Resolver_ImplMinimalMdns.cpp b/src/lib/dnssd/Resolver_ImplMinimalMdns.cpp index 8e913f2addb1c1..0a615fef4d62fb 100644 --- a/src/lib/dnssd/Resolver_ImplMinimalMdns.cpp +++ b/src/lib/dnssd/Resolver_ImplMinimalMdns.cpp @@ -590,7 +590,7 @@ CHIP_ERROR MinMdnsResolver::BuildQuery(QueryBuilder & builder, const ActiveResol break; } - ReturnErrorCodeIf(!qname.nameCount, CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(qname.nameCount, CHIP_ERROR_NO_MEMORY); mdns::Minimal::Query query(qname); query @@ -665,7 +665,7 @@ CHIP_ERROR MinMdnsResolver::BuildQuery(QueryBuilder & builder, const ActiveResol return CHIP_ERROR_INVALID_ARGUMENT; } - ReturnErrorCodeIf(!builder.Ok(), CHIP_ERROR_INTERNAL); + VerifyOrReturnError(builder.Ok(), CHIP_ERROR_INTERNAL); return CHIP_NO_ERROR; } @@ -681,7 +681,7 @@ CHIP_ERROR MinMdnsResolver::SendAllPendingQueries() } System::PacketBufferHandle buffer = System::PacketBufferHandle::New(kMdnsMaxPacketSize); - ReturnErrorCodeIf(buffer.IsNull(), CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(!buffer.IsNull(), CHIP_ERROR_NO_MEMORY); QueryBuilder builder(std::move(buffer)); builder.Header().SetMessageId(0); @@ -770,7 +770,7 @@ CHIP_ERROR MinMdnsResolver::ScheduleRetries() { MATTER_TRACE_SCOPE("Schedule retries", "MinMdnsResolver"); - ReturnErrorCodeIf(mSystemLayer == nullptr, CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(mSystemLayer != nullptr, CHIP_ERROR_INCORRECT_STATE); mSystemLayer->CancelTimer(&RetryCallback, this); std::optional delay = mActiveResolves.GetTimeUntilNextExpectedResponse(); diff --git a/src/lib/dnssd/ServiceNaming.cpp b/src/lib/dnssd/ServiceNaming.cpp index 405e10a69c6de9..d463a3ae8ebebd 100644 --- a/src/lib/dnssd/ServiceNaming.cpp +++ b/src/lib/dnssd/ServiceNaming.cpp @@ -30,7 +30,7 @@ namespace Dnssd { CHIP_ERROR MakeInstanceName(char * buffer, size_t bufferLen, const PeerId & peerId) { - ReturnErrorCodeIf(bufferLen <= Operational::kInstanceNameMaxLength, CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(bufferLen > Operational::kInstanceNameMaxLength, CHIP_ERROR_BUFFER_TOO_SMALL); NodeId nodeId = peerId.GetNodeId(); CompressedFabricId fabricId = peerId.GetCompressedFabricId(); @@ -43,8 +43,8 @@ CHIP_ERROR MakeInstanceName(char * buffer, size_t bufferLen, const PeerId & peer CHIP_ERROR ExtractIdFromInstanceName(const char * name, PeerId * peerId) { - ReturnErrorCodeIf(name == nullptr, CHIP_ERROR_INVALID_ARGUMENT); - ReturnErrorCodeIf(peerId == nullptr, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(name != nullptr, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(peerId != nullptr, CHIP_ERROR_INVALID_ARGUMENT); // Make sure the string is long enough. static constexpr size_t fabricIdByteLength = 8; @@ -55,24 +55,24 @@ CHIP_ERROR ExtractIdFromInstanceName(const char * name, PeerId * peerId) // Ensure we have at least totalLength chars. size_t len = strnlen(name, totalLength); - ReturnErrorCodeIf(len < totalLength, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(len >= totalLength, CHIP_ERROR_INVALID_ARGUMENT); // Check that we have a proper terminator. - ReturnErrorCodeIf(name[totalLength] != '\0' && name[totalLength] != '.', CHIP_ERROR_WRONG_NODE_ID); + VerifyOrReturnError(name[totalLength] == '\0' || name[totalLength] == '.', CHIP_ERROR_WRONG_NODE_ID); // Check what we have a separator where we expect. - ReturnErrorCodeIf(name[fabricIdStringLength] != '-', CHIP_ERROR_WRONG_NODE_ID); + VerifyOrReturnError(name[fabricIdStringLength] == '-', CHIP_ERROR_WRONG_NODE_ID); static constexpr size_t bufferSize = std::max(fabricIdByteLength, nodeIdByteLength); uint8_t buf[bufferSize]; - ReturnErrorCodeIf(Encoding::HexToBytes(name, fabricIdStringLength, buf, bufferSize) == 0, CHIP_ERROR_WRONG_NODE_ID); + VerifyOrReturnError(Encoding::HexToBytes(name, fabricIdStringLength, buf, bufferSize) != 0, CHIP_ERROR_WRONG_NODE_ID); // Buf now stores the fabric id, as big-endian bytes. static_assert(fabricIdByteLength == sizeof(uint64_t), "Wrong number of bytes"); peerId->SetCompressedFabricId(Encoding::BigEndian::Get64(buf)); - ReturnErrorCodeIf(Encoding::HexToBytes(name + fabricIdStringLength + 1, nodeIdStringLength, buf, bufferSize) == 0, - CHIP_ERROR_WRONG_NODE_ID); + VerifyOrReturnError(Encoding::HexToBytes(name + fabricIdStringLength + 1, nodeIdStringLength, buf, bufferSize) != 0, + CHIP_ERROR_WRONG_NODE_ID); // Buf now stores the node id id, as big-endian bytes. static_assert(nodeIdByteLength == sizeof(uint64_t), "Wrong number of bytes"); peerId->SetNodeId(Encoding::BigEndian::Get64(buf)); @@ -82,7 +82,7 @@ CHIP_ERROR ExtractIdFromInstanceName(const char * name, PeerId * peerId) CHIP_ERROR MakeHostName(char * buffer, size_t bufferLen, const chip::ByteSpan & macOrEui64) { - ReturnErrorCodeIf(bufferLen < macOrEui64.size() * 2 + 1, CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(bufferLen >= macOrEui64.size() * 2 + 1, CHIP_ERROR_BUFFER_TOO_SMALL); int idx = 0; for (size_t i = 0; i < macOrEui64.size(); ++i) diff --git a/src/lib/dnssd/minimal_mdns/ResponseSender.cpp b/src/lib/dnssd/minimal_mdns/ResponseSender.cpp index 7aec6142f0b555..0128824542c681 100644 --- a/src/lib/dnssd/minimal_mdns/ResponseSender.cpp +++ b/src/lib/dnssd/minimal_mdns/ResponseSender.cpp @@ -200,7 +200,7 @@ CHIP_ERROR ResponseSender::Respond(uint16_t messageId, const QueryData & query, CHIP_ERROR ResponseSender::FlushReply() { - ReturnErrorCodeIf(!mResponseBuilder.HasPacketBuffer(), CHIP_NO_ERROR); // nothing to flush + VerifyOrReturnError(mResponseBuilder.HasPacketBuffer(), CHIP_NO_ERROR); // nothing to flush if (mResponseBuilder.HasResponseRecords()) { @@ -232,7 +232,7 @@ CHIP_ERROR ResponseSender::FlushReply() CHIP_ERROR ResponseSender::PrepareNewReplyPacket() { chip::System::PacketBufferHandle buffer = chip::System::PacketBufferHandle::New(kPacketSizeBytes); - ReturnErrorCodeIf(buffer.IsNull(), CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(!buffer.IsNull(), CHIP_ERROR_NO_MEMORY); mResponseBuilder.Reset(std::move(buffer)); mResponseBuilder.Header().SetMessageId(mSendState.GetMessageId()); diff --git a/src/lib/support/CHIPMem-Simple.cpp b/src/lib/support/CHIPMem-Simple.cpp index 8816afeaed21c5..dbbaa9634d7ba1 100644 --- a/src/lib/support/CHIPMem-Simple.cpp +++ b/src/lib/support/CHIPMem-Simple.cpp @@ -55,8 +55,8 @@ class HeapLocked CHIP_ERROR MemoryAllocatorInit(void * buf, size_t bufSize) { - ReturnErrorCodeIf(buf == nullptr, CHIP_ERROR_INVALID_ARGUMENT); - ReturnErrorCodeIf(gPrivateHeap != nullptr, CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(buf != nullptr, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(gPrivateHeap == nullptr, CHIP_ERROR_INCORRECT_STATE); PrivateHeapInit(buf, bufSize); gPrivateHeap = buf; diff --git a/src/lib/support/CodeUtils.h b/src/lib/support/CodeUtils.h index 0142bc8544ecb2..01cc80bffcbe6c 100644 --- a/src/lib/support/CodeUtils.h +++ b/src/lib/support/CodeUtils.h @@ -313,31 +313,6 @@ } while (false) #endif // CHIP_CONFIG_ERROR_SOURCE -/** - * @def ReturnErrorCodeIf(expr, code) - * - * @brief - * Returns a specified error code if expression evaluates to true - * - * Example usage: - * - * @code - * ReturnErrorCodeIf(state == kInitialized, CHIP_NO_ERROR); - * ReturnErrorCodeIf(state == kInitialized, CHIP_ERROR_INCORRECT_STATE); - * @endcode - * - * @param[in] expr A Boolean expression to be evaluated. - * @param[in] code A value to return if @a expr is false. - */ -#define ReturnErrorCodeIf(expr, code) \ - do \ - { \ - if (expr) \ - { \ - return code; \ - } \ - } while (false) - /** * @def SuccessOrExit(error) * diff --git a/src/lib/support/TestPersistentStorageDelegate.h b/src/lib/support/TestPersistentStorageDelegate.h index 7dc1c06008c77c..997448c03d017b 100644 --- a/src/lib/support/TestPersistentStorageDelegate.h +++ b/src/lib/support/TestPersistentStorageDelegate.h @@ -207,7 +207,7 @@ class TestPersistentStorageDelegate : public PersistentStorageDelegate protected: virtual CHIP_ERROR SyncGetKeyValueInternal(const char * key, void * buffer, uint16_t & size) { - ReturnErrorCodeIf(((buffer == nullptr) && (size != 0)), CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError((buffer != nullptr) || (size == 0), CHIP_ERROR_INVALID_ARGUMENT); // Making sure poison keys are not accessed if (mPoisonKeys.find(std::string(key)) != mPoisonKeys.end()) @@ -226,8 +226,8 @@ class TestPersistentStorageDelegate : public PersistentStorageDelegate } uint16_t valueSizeUint16 = static_cast(valueSize); - ReturnErrorCodeIf(size == 0 && valueSizeUint16 == 0, CHIP_NO_ERROR); - ReturnErrorCodeIf(buffer == nullptr, CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(size != 0 || valueSizeUint16 != 0, CHIP_NO_ERROR); + VerifyOrReturnError(buffer != nullptr, CHIP_ERROR_BUFFER_TOO_SMALL); uint16_t sizeToCopy = std::min(size, valueSizeUint16); diff --git a/src/messaging/ExchangeMessageDispatch.cpp b/src/messaging/ExchangeMessageDispatch.cpp index a94f1310549eb4..662a2e4d02d0d2 100644 --- a/src/messaging/ExchangeMessageDispatch.cpp +++ b/src/messaging/ExchangeMessageDispatch.cpp @@ -38,7 +38,7 @@ CHIP_ERROR ExchangeMessageDispatch::SendMessage(SessionManager * sessionManager, bool isReliableTransmission, Protocols::Id protocol, uint8_t type, System::PacketBufferHandle && message) { - ReturnErrorCodeIf(!MessagePermitted(protocol, type), CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(MessagePermitted(protocol, type), CHIP_ERROR_INVALID_ARGUMENT); PayloadHeader payloadHeader; payloadHeader.SetExchangeID(exchangeId).SetMessageType(protocol, type).SetInitiator(isInitiator); diff --git a/src/platform/ASR/ASRFactoryDataProvider.cpp b/src/platform/ASR/ASRFactoryDataProvider.cpp index c1a436168f6246..204a2497739010 100755 --- a/src/platform/ASR/ASRFactoryDataProvider.cpp +++ b/src/platform/ASR/ASRFactoryDataProvider.cpp @@ -97,7 +97,7 @@ CHIP_ERROR ASRFactoryDataProvider::GetSpake2pSalt(MutableByteSpan & saltBuf) #if !CONFIG_ENABLE_ASR_FACTORY_DATA_PROVIDER #if defined(CHIP_DEVICE_CONFIG_USE_TEST_SPAKE2P_SALT) saltB64Len = strlen(CHIP_DEVICE_CONFIG_USE_TEST_SPAKE2P_SALT); - ReturnErrorCodeIf(saltB64Len > sizeof(saltB64), CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(saltB64Len <= sizeof(saltB64), CHIP_ERROR_BUFFER_TOO_SMALL); memcpy(saltB64, CHIP_DEVICE_CONFIG_USE_TEST_SPAKE2P_SALT, saltB64Len); #else return CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND; @@ -109,7 +109,7 @@ CHIP_ERROR ASRFactoryDataProvider::GetSpake2pSalt(MutableByteSpan & saltBuf) ReturnErrorOnFailure(err); size_t saltLen = chip::Base64Decode32(saltB64, saltB64Len, reinterpret_cast(saltB64)); - ReturnErrorCodeIf(saltLen > saltBuf.size(), CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(saltLen <= saltBuf.size(), CHIP_ERROR_BUFFER_TOO_SMALL); memcpy(saltBuf.data(), saltB64, saltLen); saltBuf.reduce_size(saltLen); @@ -128,7 +128,7 @@ CHIP_ERROR ASRFactoryDataProvider::GetSpake2pVerifier(MutableByteSpan & verifier #if !CONFIG_ENABLE_ASR_FACTORY_DATA_PROVIDER #if defined(CHIP_DEVICE_CONFIG_USE_TEST_SPAKE2P_VERIFIER) verifierB64Len = strlen(CHIP_DEVICE_CONFIG_USE_TEST_SPAKE2P_VERIFIER); - ReturnErrorCodeIf(verifierB64Len > sizeof(verifierB64), CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(verifierB64Len <= sizeof(verifierB64), CHIP_ERROR_BUFFER_TOO_SMALL); memcpy(verifierB64, CHIP_DEVICE_CONFIG_USE_TEST_SPAKE2P_VERIFIER, verifierB64Len); #else return CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND; @@ -140,7 +140,7 @@ CHIP_ERROR ASRFactoryDataProvider::GetSpake2pVerifier(MutableByteSpan & verifier ReturnErrorOnFailure(err); verifierLen = chip::Base64Decode32(verifierB64, verifierB64Len, reinterpret_cast(verifierB64)); - ReturnErrorCodeIf(verifierLen > verifierBuf.size(), CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(verifierLen <= verifierBuf.size(), CHIP_ERROR_BUFFER_TOO_SMALL); memcpy(verifierBuf.data(), verifierB64, verifierLen); verifierBuf.reduce_size(verifierLen); @@ -352,13 +352,13 @@ CHIP_ERROR ASRFactoryDataProvider::SignWithDeviceAttestationKey(const ByteSpan & CHIP_ERROR ASRFactoryDataProvider::GetVendorName(char * buf, size_t bufSize) { #if !CONFIG_ENABLE_ASR_FACTORY_DEVICE_INFO_PROVIDER - ReturnErrorCodeIf(bufSize < sizeof(CHIP_DEVICE_CONFIG_DEVICE_VENDOR_NAME), CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(bufSize >= sizeof(CHIP_DEVICE_CONFIG_DEVICE_VENDOR_NAME), CHIP_ERROR_BUFFER_TOO_SMALL); strcpy(buf, CHIP_DEVICE_CONFIG_DEVICE_VENDOR_NAME); #else size_t buffer_len = ConfigurationManager::kMaxVendorNameLength + 1; uint8_t buffer[ConfigurationManager::kMaxVendorNameLength + 1] = { 0 }; ReturnErrorOnFailure(ASRConfig::ReadFactoryConfigValue(ASR_VENDOR_NAME_PARTITION, buffer, buffer_len, buffer_len)); - ReturnErrorCodeIf(bufSize < buffer_len, CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(bufSize >= buffer_len, CHIP_ERROR_BUFFER_TOO_SMALL); memcpy(buf, buffer, buffer_len); buf[buffer_len] = 0; #endif @@ -380,13 +380,13 @@ CHIP_ERROR ASRFactoryDataProvider::GetVendorId(uint16_t & vendorId) CHIP_ERROR ASRFactoryDataProvider::GetProductName(char * buf, size_t bufSize) { #if !CONFIG_ENABLE_ASR_FACTORY_DEVICE_INFO_PROVIDER - ReturnErrorCodeIf(bufSize < sizeof(CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_NAME), CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(bufSize >= sizeof(CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_NAME), CHIP_ERROR_BUFFER_TOO_SMALL); strcpy(buf, CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_NAME); #else size_t buffer_len = ConfigurationManager::kMaxProductNameLength + 1; uint8_t buffer[ConfigurationManager::kMaxProductNameLength + 1] = { 0 }; ReturnErrorOnFailure(ASRConfig::ReadFactoryConfigValue(ASR_PRODUCT_NAME_PARTITION, buffer, buffer_len, buffer_len)); - ReturnErrorCodeIf(bufSize < buffer_len, CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(bufSize >= buffer_len, CHIP_ERROR_BUFFER_TOO_SMALL); memcpy(buf, buffer, buffer_len); buf[buffer_len] = 0; #endif @@ -413,7 +413,7 @@ CHIP_ERROR ASRFactoryDataProvider::GetPartNumber(char * buf, size_t bufSize) size_t buffer_len = ConfigurationManager::kMaxPartNumberLength + 1; uint8_t buffer[ConfigurationManager::kMaxPartNumberLength + 1] = { 0 }; ReturnErrorOnFailure(ASRConfig::ReadFactoryConfigValue(ASR_PART_NUMBER_PARTITION, buffer, buffer_len, buffer_len)); - ReturnErrorCodeIf(bufSize < buffer_len, CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(bufSize >= buffer_len, CHIP_ERROR_BUFFER_TOO_SMALL); memcpy(buf, buffer, buffer_len); buf[buffer_len] = 0; #endif @@ -428,7 +428,7 @@ CHIP_ERROR ASRFactoryDataProvider::GetProductURL(char * buf, size_t bufSize) size_t buffer_len = ConfigurationManager::kMaxProductURLLength + 1; uint8_t buffer[ConfigurationManager::kMaxProductURLLength + 1] = { 0 }; ReturnErrorOnFailure(ASRConfig::ReadFactoryConfigValue(ASR_PRODUCT_URL_PARTITION, buffer, buffer_len, buffer_len)); - ReturnErrorCodeIf(bufSize < buffer_len, CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(bufSize >= buffer_len, CHIP_ERROR_BUFFER_TOO_SMALL); memcpy(buf, buffer, buffer_len); buf[buffer_len] = 0; #endif @@ -443,7 +443,7 @@ CHIP_ERROR ASRFactoryDataProvider::GetProductLabel(char * buf, size_t bufSize) size_t buffer_len = ConfigurationManager::kMaxProductLabelLength + 1; uint8_t buffer[ConfigurationManager::kMaxProductLabelLength + 1] = { 0 }; ReturnErrorOnFailure(ASRConfig::ReadFactoryConfigValue(ASR_PRODUCT_LABEL_PARTITION, buffer, buffer_len, buffer_len)); - ReturnErrorCodeIf(bufSize < buffer_len, CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(bufSize >= buffer_len, CHIP_ERROR_BUFFER_TOO_SMALL); memcpy(buf, buffer, buffer_len); buf[buffer_len] = 0; #endif @@ -453,13 +453,13 @@ CHIP_ERROR ASRFactoryDataProvider::GetProductLabel(char * buf, size_t bufSize) CHIP_ERROR ASRFactoryDataProvider::GetSerialNumber(char * buf, size_t bufSize) { #if !CONFIG_ENABLE_ASR_FACTORY_DEVICE_INFO_PROVIDER - ReturnErrorCodeIf(bufSize < sizeof(CHIP_DEVICE_CONFIG_TEST_SERIAL_NUMBER), CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(bufSize >= sizeof(CHIP_DEVICE_CONFIG_TEST_SERIAL_NUMBER), CHIP_ERROR_BUFFER_TOO_SMALL); strcpy(buf, CHIP_DEVICE_CONFIG_TEST_SERIAL_NUMBER); #else size_t buffer_len = ConfigurationManager::kMaxSerialNumberLength + 1; uint8_t buffer[ConfigurationManager::kMaxSerialNumberLength + 1] = { 0 }; ReturnErrorOnFailure(ASRConfig::ReadFactoryConfigValue(ASR_SERIAL_NUMBER_PARTITION, buffer, buffer_len, buffer_len)); - ReturnErrorCodeIf(bufSize < buffer_len, CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(bufSize >= buffer_len, CHIP_ERROR_BUFFER_TOO_SMALL); memcpy(buf, buffer, buffer_len); buf[buffer_len] = 0; #endif @@ -522,13 +522,13 @@ CHIP_ERROR ASRFactoryDataProvider::GetHardwareVersion(uint16_t & hardwareVersion CHIP_ERROR ASRFactoryDataProvider::GetHardwareVersionString(char * buf, size_t bufSize) { #if !CONFIG_ENABLE_ASR_FACTORY_DEVICE_INFO_PROVIDER - ReturnErrorCodeIf(bufSize < sizeof(CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION_STRING), CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(bufSize >= sizeof(CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION_STRING), CHIP_ERROR_BUFFER_TOO_SMALL); strcpy(buf, CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION_STRING); #else size_t buffer_len = ConfigurationManager::kMaxHardwareVersionStringLength + 1; uint8_t buffer[ConfigurationManager::kMaxHardwareVersionStringLength + 1] = { 0 }; ReturnErrorOnFailure(ASRConfig::ReadFactoryConfigValue(ASR_HARDWARE_VERSION_STR_PARTITION, buffer, buffer_len, buffer_len)); - ReturnErrorCodeIf(bufSize < buffer_len, CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(bufSize >= buffer_len, CHIP_ERROR_BUFFER_TOO_SMALL); memcpy(buf, buffer, buffer_len); buf[buffer_len] = 0; #endif @@ -545,8 +545,8 @@ CHIP_ERROR ASRFactoryDataProvider::GetRotatingDeviceIdUniqueId(MutableByteSpan & #ifdef CHIP_DEVICE_CONFIG_ROTATING_DEVICE_ID_UNIQUE_ID constexpr uint8_t uniqueId[] = CHIP_DEVICE_CONFIG_ROTATING_DEVICE_ID_UNIQUE_ID; - ReturnErrorCodeIf(sizeof(uniqueId) > uniqueIdSpan.size(), CHIP_ERROR_BUFFER_TOO_SMALL); - ReturnErrorCodeIf(sizeof(uniqueId) != ConfigurationManager::kRotatingDeviceIDUniqueIDLength, CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(sizeof(uniqueId) <= uniqueIdSpan.size(), CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(sizeof(uniqueId) == ConfigurationManager::kRotatingDeviceIDUniqueIDLength, CHIP_ERROR_BUFFER_TOO_SMALL); memcpy(uniqueIdSpan.data(), uniqueId, sizeof(uniqueId)); uniqueIdSpan.reduce_size(sizeof(uniqueId)); return CHIP_NO_ERROR; @@ -555,11 +555,11 @@ CHIP_ERROR ASRFactoryDataProvider::GetRotatingDeviceIdUniqueId(MutableByteSpan & #define ROTATING_UNIQUE_ID_STRING_LEN ConfigurationManager::kRotatingDeviceIDUniqueIDLength * 2 uint8_t buffer[ROTATING_UNIQUE_ID_STRING_LEN] = { 0 }; size_t buffer_len = ROTATING_UNIQUE_ID_STRING_LEN; - ReturnErrorCodeIf(ConfigurationManager::kRotatingDeviceIDUniqueIDLength > uniqueIdSpan.size(), CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(ConfigurationManager::kRotatingDeviceIDUniqueIDLength <= uniqueIdSpan.size(), CHIP_ERROR_BUFFER_TOO_SMALL); ReturnErrorOnFailure(ASRConfig::ReadFactoryConfigValue(ASR_ROTATING_UNIQUE_ID_PARTITION, buffer, buffer_len, buffer_len)); size_t bytesLen = chip::Encoding::HexToBytes(Uint8::to_char(buffer), ROTATING_UNIQUE_ID_STRING_LEN, uniqueIdSpan.data(), uniqueIdSpan.size()); - ReturnErrorCodeIf(bytesLen != ConfigurationManager::kRotatingDeviceIDUniqueIDLength, CHIP_ERROR_INVALID_STRING_LENGTH); + VerifyOrReturnError(bytesLen == ConfigurationManager::kRotatingDeviceIDUniqueIDLength, CHIP_ERROR_INVALID_STRING_LENGTH); uniqueIdSpan.reduce_size(bytesLen); return CHIP_NO_ERROR; #endif // CONFIG_ENABLE_ASR_FACTORY_DEVICE_INFO_PROVIDER diff --git a/src/platform/ASR/ASROTAImageProcessor.cpp b/src/platform/ASR/ASROTAImageProcessor.cpp index d83ba75362cb69..ca853ab5b50faf 100644 --- a/src/platform/ASR/ASROTAImageProcessor.cpp +++ b/src/platform/ASR/ASROTAImageProcessor.cpp @@ -211,7 +211,7 @@ CHIP_ERROR ASROTAImageProcessor::ProcessHeader(ByteSpan & block) CHIP_ERROR error = mHeaderParser.AccumulateAndDecode(block, header); // Needs more data to decode the header - ReturnErrorCodeIf(error == CHIP_ERROR_BUFFER_TOO_SMALL, CHIP_NO_ERROR); + VerifyOrReturnError(error != CHIP_ERROR_BUFFER_TOO_SMALL, CHIP_NO_ERROR); ReturnErrorOnFailure(error); ChipLogProgress(SoftwareUpdate, "Image Header software version: %ld payload size: %lu", header.mSoftwareVersion, diff --git a/src/platform/Ameba/AmebaOTAImageProcessor.cpp b/src/platform/Ameba/AmebaOTAImageProcessor.cpp index 78c1a8bdd2665c..f2752a6e0daaed 100644 --- a/src/platform/Ameba/AmebaOTAImageProcessor.cpp +++ b/src/platform/Ameba/AmebaOTAImageProcessor.cpp @@ -262,7 +262,7 @@ CHIP_ERROR AmebaOTAImageProcessor::ProcessHeader(ByteSpan & block) CHIP_ERROR error = mHeaderParser.AccumulateAndDecode(block, header); // Needs more data to decode the header - ReturnErrorCodeIf(error == CHIP_ERROR_BUFFER_TOO_SMALL, CHIP_NO_ERROR); + VerifyOrReturnError(error != CHIP_ERROR_BUFFER_TOO_SMALL, CHIP_NO_ERROR); ReturnErrorOnFailure(error); mParams.totalFileBytes = header.mPayloadSize; diff --git a/src/platform/Ameba/FactoryDataProvider.cpp b/src/platform/Ameba/FactoryDataProvider.cpp index d41f85669014b8..e7251a6f8084fd 100644 --- a/src/platform/Ameba/FactoryDataProvider.cpp +++ b/src/platform/Ameba/FactoryDataProvider.cpp @@ -174,8 +174,8 @@ CHIP_ERROR FactoryDataProvider::GetCertificationDeclaration(MutableByteSpan & ou if (kReadFromFlash) { - ReturnErrorCodeIf(outBuffer.size() < mFactoryData.dac.cd.len, CHIP_ERROR_BUFFER_TOO_SMALL); - ReturnErrorCodeIf(!mFactoryData.dac.cd.value, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + VerifyOrReturnError(outBuffer.size() >= mFactoryData.dac.cd.len, CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(mFactoryData.dac.cd.value, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); memcpy(outBuffer.data(), mFactoryData.dac.cd.value, mFactoryData.dac.cd.len); @@ -204,8 +204,8 @@ CHIP_ERROR FactoryDataProvider::GetDeviceAttestationCert(MutableByteSpan & outBu if (kReadFromFlash) { - ReturnErrorCodeIf(outBuffer.size() < mFactoryData.dac.dac_cert.len, CHIP_ERROR_BUFFER_TOO_SMALL); - ReturnErrorCodeIf(!mFactoryData.dac.dac_cert.value, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + VerifyOrReturnError(outBuffer.size() >= mFactoryData.dac.dac_cert.len, CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(mFactoryData.dac.dac_cert.value, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); memcpy(outBuffer.data(), mFactoryData.dac.dac_cert.value, mFactoryData.dac.dac_cert.len); @@ -226,8 +226,8 @@ CHIP_ERROR FactoryDataProvider::GetProductAttestationIntermediateCert(MutableByt if (kReadFromFlash) { - ReturnErrorCodeIf(outBuffer.size() < mFactoryData.dac.pai_cert.len, CHIP_ERROR_BUFFER_TOO_SMALL); - ReturnErrorCodeIf(!mFactoryData.dac.pai_cert.value, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + VerifyOrReturnError(outBuffer.size() >= mFactoryData.dac.pai_cert.len, CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(mFactoryData.dac.pai_cert.value, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); memcpy(outBuffer.data(), mFactoryData.dac.pai_cert.value, mFactoryData.dac.pai_cert.len); @@ -254,7 +254,7 @@ CHIP_ERROR FactoryDataProvider::SignWithDeviceAttestationKey(const ByteSpan & me if (kReadFromFlash) { #if CONFIG_ENABLE_AMEBA_CRYPTO - ReturnErrorCodeIf(!mFactoryData.dac.dac_cert.value, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + VerifyOrReturnError(mFactoryData.dac.dac_cert.value, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); // Extract public key from DAC cert. ByteSpan dacCertSpan{ reinterpret_cast(mFactoryData.dac.dac_cert.value), mFactoryData.dac.dac_cert.len }; chip::Crypto::P256PublicKey dacPublicKey; @@ -266,8 +266,8 @@ CHIP_ERROR FactoryDataProvider::SignWithDeviceAttestationKey(const ByteSpan & me err = decoder.GetSign(dacPublicKey.Bytes(), dacPublicKey.Length(), messageToSign.data(), messageToSign.size(), signature.Bytes()); #else - ReturnErrorCodeIf(!mFactoryData.dac.dac_cert.value, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); - ReturnErrorCodeIf(!mFactoryData.dac.dac_key.value, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + VerifyOrReturnError(mFactoryData.dac.dac_cert.value, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + VerifyOrReturnError(mFactoryData.dac.dac_key.value, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); // Extract public key from DAC cert. ByteSpan dacCertSpan{ reinterpret_cast(mFactoryData.dac.dac_cert.value), mFactoryData.dac.dac_cert.len }; chip::Crypto::P256PublicKey dacPublicKey; @@ -325,7 +325,7 @@ CHIP_ERROR FactoryDataProvider::GetSpake2pIterationCount(uint32_t & iterationCou if (kReadFromFlash) { - ReturnErrorCodeIf(mFactoryData.cdata.spake2_it == 0, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + VerifyOrReturnError(mFactoryData.cdata.spake2_it != 0, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); iterationCount = mFactoryData.cdata.spake2_it; err = CHIP_NO_ERROR; } @@ -351,7 +351,7 @@ CHIP_ERROR FactoryDataProvider::GetSpake2pSalt(MutableByteSpan & saltBuf) if (kReadFromFlash) { saltB64Len = mFactoryData.cdata.spake2_salt.len; - ReturnErrorCodeIf(saltB64Len > sizeof(saltB64), CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(saltB64Len <= sizeof(saltB64), CHIP_ERROR_BUFFER_TOO_SMALL); memcpy(saltB64, mFactoryData.cdata.spake2_salt.value, saltB64Len); err = CHIP_NO_ERROR; } @@ -359,7 +359,7 @@ CHIP_ERROR FactoryDataProvider::GetSpake2pSalt(MutableByteSpan & saltBuf) { #if defined(CHIP_DEVICE_CONFIG_USE_TEST_SPAKE2P_SALT) saltB64Len = strlen(CHIP_DEVICE_CONFIG_USE_TEST_SPAKE2P_SALT); - ReturnErrorCodeIf(saltB64Len > sizeof(saltB64), CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(saltB64Len <= sizeof(saltB64), CHIP_ERROR_BUFFER_TOO_SMALL); memcpy(saltB64, CHIP_DEVICE_CONFIG_USE_TEST_SPAKE2P_SALT, saltB64Len); err = CHIP_NO_ERROR; #endif // defined(CHIP_DEVICE_CONFIG_USE_TEST_SPAKE2P_SALT) @@ -368,7 +368,7 @@ CHIP_ERROR FactoryDataProvider::GetSpake2pSalt(MutableByteSpan & saltBuf) ReturnErrorOnFailure(err); size_t saltLen = chip::Base64Decode32(saltB64, saltB64Len, reinterpret_cast(saltB64)); - ReturnErrorCodeIf(saltLen > saltBuf.size(), CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(saltLen <= saltBuf.size(), CHIP_ERROR_BUFFER_TOO_SMALL); memcpy(saltBuf.data(), saltB64, saltLen); saltBuf.reduce_size(saltLen); @@ -387,7 +387,7 @@ CHIP_ERROR FactoryDataProvider::GetSpake2pVerifier(MutableByteSpan & verifierBuf if (kReadFromFlash) { verifierB64Len = mFactoryData.cdata.spake2_verifier.len; - ReturnErrorCodeIf(verifierB64Len > sizeof(verifierB64), CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(verifierB64Len <= sizeof(verifierB64), CHIP_ERROR_BUFFER_TOO_SMALL); memcpy(verifierB64, mFactoryData.cdata.spake2_verifier.value, verifierB64Len); err = CHIP_NO_ERROR; } @@ -395,7 +395,7 @@ CHIP_ERROR FactoryDataProvider::GetSpake2pVerifier(MutableByteSpan & verifierBuf { #if defined(CHIP_DEVICE_CONFIG_USE_TEST_SPAKE2P_VERIFIER) verifierB64Len = strlen(CHIP_DEVICE_CONFIG_USE_TEST_SPAKE2P_VERIFIER); - ReturnErrorCodeIf(verifierB64Len > sizeof(verifierB64), CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(verifierB64Len <= sizeof(verifierB64), CHIP_ERROR_BUFFER_TOO_SMALL); memcpy(verifierB64, CHIP_DEVICE_CONFIG_USE_TEST_SPAKE2P_VERIFIER, verifierB64Len); err = CHIP_NO_ERROR; #endif // defined(CHIP_DEVICE_CONFIG_USE_TEST_SPAKE2P_VERIFIER) @@ -403,7 +403,7 @@ CHIP_ERROR FactoryDataProvider::GetSpake2pVerifier(MutableByteSpan & verifierBuf ReturnErrorOnFailure(err); verifierLen = chip::Base64Decode32(verifierB64, verifierB64Len, reinterpret_cast(verifierB64)); - ReturnErrorCodeIf(verifierLen > verifierBuf.size(), CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(verifierLen <= verifierBuf.size(), CHIP_ERROR_BUFFER_TOO_SMALL); memcpy(verifierBuf.data(), verifierB64, verifierLen); verifierBuf.reduce_size(verifierLen); @@ -416,7 +416,7 @@ CHIP_ERROR FactoryDataProvider::GetSetupPasscode(uint32_t & setupPasscode) if (kReadFromFlash) { - ReturnErrorCodeIf(mFactoryData.cdata.passcode == 0, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + VerifyOrReturnError(mFactoryData.cdata.passcode != 0, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); setupPasscode = mFactoryData.cdata.passcode; err = CHIP_NO_ERROR; } @@ -442,15 +442,15 @@ CHIP_ERROR FactoryDataProvider::GetVendorName(char * buf, size_t bufSize) if (kReadFromFlash) { - ReturnErrorCodeIf(bufSize < mFactoryData.dii.vendor_name.len + 1, CHIP_ERROR_BUFFER_TOO_SMALL); - ReturnErrorCodeIf(!mFactoryData.dii.vendor_name.value, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + VerifyOrReturnError(bufSize >= mFactoryData.dii.vendor_name.len + 1, CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(mFactoryData.dii.vendor_name.value, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); memcpy(buf, mFactoryData.dii.vendor_name.value, mFactoryData.dii.vendor_name.len); buf[mFactoryData.dii.vendor_name.len] = 0; err = CHIP_NO_ERROR; } else { - ReturnErrorCodeIf(bufSize < sizeof(CHIP_DEVICE_CONFIG_DEVICE_VENDOR_NAME), CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(bufSize >= sizeof(CHIP_DEVICE_CONFIG_DEVICE_VENDOR_NAME), CHIP_ERROR_BUFFER_TOO_SMALL); strcpy(buf, CHIP_DEVICE_CONFIG_DEVICE_VENDOR_NAME); err = CHIP_NO_ERROR; } @@ -482,15 +482,15 @@ CHIP_ERROR FactoryDataProvider::GetProductName(char * buf, size_t bufSize) if (kReadFromFlash) { - ReturnErrorCodeIf(bufSize < mFactoryData.dii.product_name.len + 1, CHIP_ERROR_BUFFER_TOO_SMALL); - ReturnErrorCodeIf(!mFactoryData.dii.product_name.value, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + VerifyOrReturnError(bufSize >= mFactoryData.dii.product_name.len + 1, CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(mFactoryData.dii.product_name.value, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); memcpy(buf, mFactoryData.dii.product_name.value, mFactoryData.dii.product_name.len); buf[mFactoryData.dii.product_name.len] = 0; err = CHIP_NO_ERROR; } else { - ReturnErrorCodeIf(bufSize < sizeof(CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_NAME), CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(bufSize >= sizeof(CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_NAME), CHIP_ERROR_BUFFER_TOO_SMALL); strcpy(buf, CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_NAME); err = CHIP_NO_ERROR; } @@ -539,8 +539,8 @@ CHIP_ERROR FactoryDataProvider::GetSerialNumber(char * buf, size_t bufSize) if (kReadFromFlash) { - ReturnErrorCodeIf(bufSize < mFactoryData.dii.serial_num.len + 1, CHIP_ERROR_BUFFER_TOO_SMALL); - ReturnErrorCodeIf(!mFactoryData.dii.serial_num.value, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + VerifyOrReturnError(bufSize >= mFactoryData.dii.serial_num.len + 1, CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(mFactoryData.dii.serial_num.value, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); memcpy(buf, mFactoryData.dii.serial_num.value, mFactoryData.dii.serial_num.len); buf[mFactoryData.dii.serial_num.len] = 0; err = CHIP_NO_ERROR; @@ -550,15 +550,15 @@ CHIP_ERROR FactoryDataProvider::GetSerialNumber(char * buf, size_t bufSize) #ifdef CHIP_DEVICE_CONFIG_TEST_SERIAL_NUMBER if (CHIP_DEVICE_CONFIG_TEST_SERIAL_NUMBER[0] != 0) { - ReturnErrorCodeIf(sizeof(CHIP_DEVICE_CONFIG_TEST_SERIAL_NUMBER) > bufSize, CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(sizeof(CHIP_DEVICE_CONFIG_TEST_SERIAL_NUMBER) <= bufSize, CHIP_ERROR_BUFFER_TOO_SMALL); memcpy(buf, CHIP_DEVICE_CONFIG_TEST_SERIAL_NUMBER, sizeof(CHIP_DEVICE_CONFIG_TEST_SERIAL_NUMBER)); serialNumLen = sizeof(CHIP_DEVICE_CONFIG_TEST_SERIAL_NUMBER) - 1; err = CHIP_NO_ERROR; } #endif // CHIP_DEVICE_CONFIG_TEST_SERIAL_NUMBER - ReturnErrorCodeIf(serialNumLen >= bufSize, CHIP_ERROR_BUFFER_TOO_SMALL); - ReturnErrorCodeIf(buf[serialNumLen] != 0, CHIP_ERROR_INVALID_STRING_LENGTH); + VerifyOrReturnError(serialNumLen < bufSize, CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(buf[serialNumLen] == 0, CHIP_ERROR_INVALID_STRING_LENGTH); err = CHIP_NO_ERROR; } @@ -635,15 +635,16 @@ CHIP_ERROR FactoryDataProvider::GetHardwareVersionString(char * buf, size_t bufS if (kReadFromFlash) { - ReturnErrorCodeIf(bufSize < mFactoryData.dii.hw_ver_string.len + 1, CHIP_ERROR_BUFFER_TOO_SMALL); - ReturnErrorCodeIf(!mFactoryData.dii.hw_ver_string.value, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + VerifyOrReturnError(bufSize >= mFactoryData.dii.hw_ver_string.len + 1, CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(mFactoryData.dii.hw_ver_string.value, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); memcpy(buf, mFactoryData.dii.hw_ver_string.value, mFactoryData.dii.hw_ver_string.len); buf[mFactoryData.dii.hw_ver_string.len] = 0; err = CHIP_NO_ERROR; } else { - ReturnErrorCodeIf(bufSize < sizeof(CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION_STRING), CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(bufSize >= sizeof(CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION_STRING), + CHIP_ERROR_BUFFER_TOO_SMALL); strcpy(buf, CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION_STRING); err = CHIP_NO_ERROR; } @@ -657,8 +658,8 @@ CHIP_ERROR FactoryDataProvider::GetRotatingDeviceIdUniqueId(MutableByteSpan & un if (kReadFromFlash) { - ReturnErrorCodeIf(uniqueIdSpan.size() < mFactoryData.dii.rd_id_uid.len, CHIP_ERROR_BUFFER_TOO_SMALL); - ReturnErrorCodeIf(!mFactoryData.dii.rd_id_uid.value, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + VerifyOrReturnError(uniqueIdSpan.size() >= mFactoryData.dii.rd_id_uid.len, CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(mFactoryData.dii.rd_id_uid.value, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); memcpy(uniqueIdSpan.data(), mFactoryData.dii.rd_id_uid.value, mFactoryData.dii.rd_id_uid.len); err = CHIP_NO_ERROR; } @@ -671,8 +672,8 @@ CHIP_ERROR FactoryDataProvider::GetRotatingDeviceIdUniqueId(MutableByteSpan & un "Length of unique ID for rotating device ID is smaller than minimum."); constexpr uint8_t uniqueId[] = CHIP_DEVICE_CONFIG_ROTATING_DEVICE_ID_UNIQUE_ID; - ReturnErrorCodeIf(sizeof(uniqueId) > uniqueIdSpan.size(), CHIP_ERROR_BUFFER_TOO_SMALL); - ReturnErrorCodeIf(sizeof(uniqueId) != ConfigurationManager::kRotatingDeviceIDUniqueIDLength, CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(sizeof(uniqueId) <= uniqueIdSpan.size(), CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(sizeof(uniqueId) == ConfigurationManager::kRotatingDeviceIDUniqueIDLength, CHIP_ERROR_BUFFER_TOO_SMALL); memcpy(uniqueIdSpan.data(), uniqueId, sizeof(uniqueId)); uniqueIdSpan.reduce_size(sizeof(uniqueId)); err = CHIP_NO_ERROR; diff --git a/src/platform/Beken/OTAImageProcessorImpl.cpp b/src/platform/Beken/OTAImageProcessorImpl.cpp index 770dfc223225a3..9fd7dda7ca7fff 100644 --- a/src/platform/Beken/OTAImageProcessorImpl.cpp +++ b/src/platform/Beken/OTAImageProcessorImpl.cpp @@ -346,7 +346,7 @@ CHIP_ERROR OTAImageProcessorImpl::ProcessHeader(ByteSpan & block) CHIP_ERROR error = mHeaderParser.AccumulateAndDecode(block, header); // Needs more data to decode the header - ReturnErrorCodeIf(error == CHIP_ERROR_BUFFER_TOO_SMALL, CHIP_NO_ERROR); + VerifyOrReturnError(error != CHIP_ERROR_BUFFER_TOO_SMALL, CHIP_NO_ERROR); ReturnErrorOnFailure(error); mParams.totalFileBytes = header.mPayloadSize; diff --git a/src/platform/Darwin/KeyValueStoreManagerImpl.mm b/src/platform/Darwin/KeyValueStoreManagerImpl.mm index ffb28435f642af..d59610eaf7a731 100644 --- a/src/platform/Darwin/KeyValueStoreManagerImpl.mm +++ b/src/platform/Darwin/KeyValueStoreManagerImpl.mm @@ -152,13 +152,13 @@ - (instancetype)initWithContext:(nonnull NSManagedObjectContext *)context key:(n return CHIP_NO_ERROR; } - ReturnErrorCodeIf(gContext != nullptr, CHIP_ERROR_INCORRECT_STATE); - ReturnErrorCodeIf(fileName == nullptr, CHIP_ERROR_INVALID_ARGUMENT); - ReturnErrorCodeIf(fileName[0] == '\0', CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(gContext == nullptr, CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(fileName != nullptr, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(fileName[0] != '\0', CHIP_ERROR_INVALID_ARGUMENT); NSURL * url = nullptr; NSString * filepath = [NSString stringWithUTF8String:fileName]; - ReturnErrorCodeIf(filepath == nil, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(filepath != nil, CHIP_ERROR_INVALID_ARGUMENT); // relative paths are relative to Documents folder if (![filepath hasPrefix:@"/"]) { @@ -178,12 +178,12 @@ - (instancetype)initWithContext:(nonnull NSManagedObjectContext *)context key:(n } else { url = [NSURL fileURLWithPath:filepath]; } - ReturnErrorCodeIf(url == nullptr, CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(url != nullptr, CHIP_ERROR_NO_MEMORY); ChipLogProgress(DeviceLayer, "KVS will be written to: %s", [[url absoluteString] UTF8String]); NSManagedObjectModel * model = CreateManagedObjectModel(); - ReturnErrorCodeIf(model == nullptr, CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(model != nullptr, CHIP_ERROR_NO_MEMORY); // setup persistent store coordinator @@ -220,9 +220,9 @@ - (instancetype)initWithContext:(nonnull NSManagedObjectContext *)context key:(n const char * key, void * value, size_t value_size, size_t * read_bytes_size, size_t offset) { @autoreleasepool { - ReturnErrorCodeIf(key == nullptr, CHIP_ERROR_INVALID_ARGUMENT); - ReturnErrorCodeIf(offset != 0, CHIP_ERROR_INVALID_ARGUMENT); - ReturnErrorCodeIf(gContext == nullptr, CHIP_ERROR_UNINITIALIZED); + VerifyOrReturnError(key != nullptr, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(offset == 0, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(gContext != nullptr, CHIP_ERROR_UNINITIALIZED); KeyValueItem * item = FindItemForKey([[NSString alloc] initWithUTF8String:key], nil, true); if (!item) { @@ -261,8 +261,8 @@ - (instancetype)initWithContext:(nonnull NSManagedObjectContext *)context key:(n CHIP_ERROR KeyValueStoreManagerImpl::_Delete(const char * key) { @autoreleasepool { - ReturnErrorCodeIf(key == nullptr, CHIP_ERROR_INVALID_ARGUMENT); - ReturnErrorCodeIf(gContext == nullptr, CHIP_ERROR_UNINITIALIZED); + VerifyOrReturnError(key != nullptr, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(gContext != nullptr, CHIP_ERROR_UNINITIALIZED); KeyValueItem * item = FindItemForKey([[NSString alloc] initWithUTF8String:key], nil); if (!item) { @@ -288,13 +288,13 @@ - (instancetype)initWithContext:(nonnull NSManagedObjectContext *)context key:(n CHIP_ERROR KeyValueStoreManagerImpl::_Put(const char * key, const void * value, size_t value_size) { @autoreleasepool { - ReturnErrorCodeIf(key == nullptr, CHIP_ERROR_INVALID_ARGUMENT); - ReturnErrorCodeIf(gContext == nullptr, CHIP_ERROR_UNINITIALIZED); + VerifyOrReturnError(key != nullptr, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(gContext != nullptr, CHIP_ERROR_UNINITIALIZED); NSData * data = [[NSData alloc] initWithBytes:value length:value_size]; NSString * itemKey = [[NSString alloc] initWithUTF8String:key]; - ReturnErrorCodeIf(itemKey == nil, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(itemKey != nil, CHIP_ERROR_INVALID_ARGUMENT); KeyValueItem * item = FindItemForKey(itemKey, nil); if (!item) { diff --git a/src/platform/ESP32/ConfigurationManagerImpl.cpp b/src/platform/ESP32/ConfigurationManagerImpl.cpp index 78446432c58b0a..a12750c6a45e57 100644 --- a/src/platform/ESP32/ConfigurationManagerImpl.cpp +++ b/src/platform/ESP32/ConfigurationManagerImpl.cpp @@ -238,8 +238,9 @@ CHIP_ERROR ConfigurationManagerImpl::GetSoftwareVersionString(char * buf, size_t appDescription = esp_ota_get_app_description(); #endif - ReturnErrorCodeIf(bufSize < sizeof(appDescription->version), CHIP_ERROR_BUFFER_TOO_SMALL); - ReturnErrorCodeIf(sizeof(appDescription->version) > ConfigurationManager::kMaxSoftwareVersionStringLength, CHIP_ERROR_INTERNAL); + VerifyOrReturnError(bufSize >= sizeof(appDescription->version), CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(sizeof(appDescription->version) <= ConfigurationManager::kMaxSoftwareVersionStringLength, + CHIP_ERROR_INTERNAL); strcpy(buf, appDescription->version); return CHIP_NO_ERROR; } diff --git a/src/platform/ESP32/ESP32Config.cpp b/src/platform/ESP32/ESP32Config.cpp index df48f5f2955793..3fd7d9ea777927 100644 --- a/src/platform/ESP32/ESP32Config.cpp +++ b/src/platform/ESP32/ESP32Config.cpp @@ -217,7 +217,7 @@ CHIP_ERROR ESP32Config::ReadConfigValueStr(Key key, char * buf, size_t bufSize, { return CHIP_ERROR_BUFFER_TOO_SMALL; } - ReturnErrorCodeIf(buf[outLen - 1] != 0, CHIP_ERROR_INVALID_STRING_LENGTH); + VerifyOrReturnError(buf[outLen - 1] == 0, CHIP_ERROR_INVALID_STRING_LENGTH); ReturnMappedErrorOnFailure(err); } diff --git a/src/platform/ESP32/ESP32EndpointQueueFilter.h b/src/platform/ESP32/ESP32EndpointQueueFilter.h index aa283d9b7fd770..cbf3304d97e573 100644 --- a/src/platform/ESP32/ESP32EndpointQueueFilter.h +++ b/src/platform/ESP32/ESP32EndpointQueueFilter.h @@ -29,8 +29,8 @@ class ESP32EndpointQueueFilter : public EndpointQueueFilter public: CHIP_ERROR SetMdnsHostName(const chip::CharSpan & hostName) { - ReturnErrorCodeIf(hostName.size() != sizeof(mHostNameBuffer), CHIP_ERROR_INVALID_ARGUMENT); - ReturnErrorCodeIf(!IsValidMdnsHostName(hostName), CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(hostName.size() == sizeof(mHostNameBuffer), CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(IsValidMdnsHostName(hostName), CHIP_ERROR_INVALID_ARGUMENT); memcpy(mHostNameBuffer, hostName.data(), hostName.size()); return CHIP_NO_ERROR; } diff --git a/src/platform/ESP32/ESP32FactoryDataProvider.cpp b/src/platform/ESP32/ESP32FactoryDataProvider.cpp index ace2a087de144b..03936c96c7421e 100644 --- a/src/platform/ESP32/ESP32FactoryDataProvider.cpp +++ b/src/platform/ESP32/ESP32FactoryDataProvider.cpp @@ -66,7 +66,7 @@ CHIP_ERROR ESP32FactoryDataProvider::GetSpake2pSalt(MutableByteSpan & saltBuf) ReturnErrorOnFailure(err); size_t saltLen = chip::Base64Decode32(saltB64, saltB64Len, reinterpret_cast(saltB64)); - ReturnErrorCodeIf(saltLen > saltBuf.size(), CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(saltLen <= saltBuf.size(), CHIP_ERROR_BUFFER_TOO_SMALL); memcpy(saltBuf.data(), saltB64, saltLen); saltBuf.reduce_size(saltLen); @@ -88,7 +88,7 @@ CHIP_ERROR ESP32FactoryDataProvider::GetSpake2pVerifier(MutableByteSpan & verifi ReturnErrorOnFailure(err); verifierLen = chip::Base64Decode32(verifierB64, verifierB64Len, reinterpret_cast(verifierB64)); - ReturnErrorCodeIf(verifierLen > verifierBuf.size(), CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(verifierLen <= verifierBuf.size(), CHIP_ERROR_BUFFER_TOO_SMALL); memcpy(verifierBuf.data(), verifierB64, verifierLen); verifierBuf.reduce_size(verifierLen); @@ -251,7 +251,7 @@ CHIP_ERROR ESP32FactoryDataProvider::GetProductFinish(app::Clusters::BasicInform uint32_t productFinish = 0; err = ESP32Config::ReadConfigValue(ESP32Config::kConfigKey_ProductFinish, productFinish); - ReturnErrorCodeIf(err != CHIP_NO_ERROR, CHIP_ERROR_NOT_IMPLEMENTED); + VerifyOrReturnError(err == CHIP_NO_ERROR, CHIP_ERROR_NOT_IMPLEMENTED); *finish = static_cast(productFinish); @@ -264,7 +264,7 @@ CHIP_ERROR ESP32FactoryDataProvider::GetProductPrimaryColor(app::Clusters::Basic uint32_t color = 0; err = ESP32Config::ReadConfigValue(ESP32Config::kConfigKey_ProductColor, color); - ReturnErrorCodeIf(err != CHIP_NO_ERROR, CHIP_ERROR_NOT_IMPLEMENTED); + VerifyOrReturnError(err == CHIP_NO_ERROR, CHIP_ERROR_NOT_IMPLEMENTED); *primaryColor = static_cast(color); diff --git a/src/platform/ESP32/KeyValueStoreManagerImpl.cpp b/src/platform/ESP32/KeyValueStoreManagerImpl.cpp index 3c587167334de2..96e68a6c2f8e5f 100644 --- a/src/platform/ESP32/KeyValueStoreManagerImpl.cpp +++ b/src/platform/ESP32/KeyValueStoreManagerImpl.cpp @@ -49,10 +49,10 @@ namespace { // Returns true if key is hashed, false otherwise. bool HashIfLongKey(const char * key, char * keyHash) { - ReturnErrorCodeIf(strlen(key) < NVS_KEY_NAME_MAX_SIZE, false); + VerifyOrReturnError(strlen(key) >= NVS_KEY_NAME_MAX_SIZE, false); uint8_t hashBuffer[chip::Crypto::kSHA1_Hash_Length]; - ReturnErrorCodeIf(Crypto::Hash_SHA1(Uint8::from_const_char(key), strlen(key), hashBuffer) != CHIP_NO_ERROR, false); + VerifyOrReturnError(Crypto::Hash_SHA1(Uint8::from_const_char(key), strlen(key), hashBuffer) == CHIP_NO_ERROR, false); BitFlags flags(Encoding::HexFlags::kNone); Encoding::BytesToHex(hashBuffer, NVS_KEY_NAME_MAX_SIZE / 2, keyHash, NVS_KEY_NAME_MAX_SIZE, flags); diff --git a/src/platform/ESP32/NetworkCommissioningDriver.cpp b/src/platform/ESP32/NetworkCommissioningDriver.cpp index 3845287cfdb919..9b1280f83d72b6 100644 --- a/src/platform/ESP32/NetworkCommissioningDriver.cpp +++ b/src/platform/ESP32/NetworkCommissioningDriver.cpp @@ -143,7 +143,7 @@ CHIP_ERROR ESPWiFiDriver::RevertConfiguration() size_t credentialsLen = 0; CHIP_ERROR error = PersistedStorage::KeyValueStoreMgr().Get(kWiFiSSIDKeyName, network.ssid, sizeof(network.ssid), &ssidLen); - ReturnErrorCodeIf(error == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND, CHIP_NO_ERROR); + VerifyOrReturnError(error != CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND, CHIP_NO_ERROR); VerifyOrExit(CanCastTo(ssidLen), error = CHIP_ERROR_INTERNAL); VerifyOrExit(PersistedStorage::KeyValueStoreMgr().Get(kWiFiCredentialsKeyName, network.credentials, sizeof(network.credentials), &credentialsLen) == CHIP_NO_ERROR, diff --git a/src/platform/ESP32/OTAImageProcessorImpl.cpp b/src/platform/ESP32/OTAImageProcessorImpl.cpp index ab27b9c50df0cb..284f21c0639eec 100644 --- a/src/platform/ESP32/OTAImageProcessorImpl.cpp +++ b/src/platform/ESP32/OTAImageProcessorImpl.cpp @@ -573,7 +573,7 @@ CHIP_ERROR OTAImageProcessorImpl::ProcessHeader(ByteSpan & block) CHIP_ERROR error = mHeaderParser.AccumulateAndDecode(block, header); // Need more data to decode the header - ReturnErrorCodeIf(error == CHIP_ERROR_BUFFER_TOO_SMALL, CHIP_NO_ERROR); + VerifyOrReturnError(error != CHIP_ERROR_BUFFER_TOO_SMALL, CHIP_NO_ERROR); ReturnErrorOnFailure(error); mParams.totalFileBytes = header.mPayloadSize; diff --git a/src/platform/ESP32/bluedroid/ChipDeviceScanner.cpp b/src/platform/ESP32/bluedroid/ChipDeviceScanner.cpp index 81421cf8d5f79a..fc8ac74384982b 100644 --- a/src/platform/ESP32/bluedroid/ChipDeviceScanner.cpp +++ b/src/platform/ESP32/bluedroid/ChipDeviceScanner.cpp @@ -70,7 +70,7 @@ void ChipDeviceScanner::RemoveDevice() CHIP_ERROR ChipDeviceScanner::StartScan(uint16_t timeout) { - ReturnErrorCodeIf(mIsScanning, CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(!mIsScanning, CHIP_ERROR_INCORRECT_STATE); static esp_ble_scan_params_t ble_scan_params = { .scan_type = BLE_SCAN_TYPE_PASSIVE, .own_addr_type = BLE_ADDR_TYPE_RANDOM, @@ -98,7 +98,7 @@ CHIP_ERROR ChipDeviceScanner::StartScan(uint16_t timeout) CHIP_ERROR ChipDeviceScanner::StopScan() { - ReturnErrorCodeIf(!mIsScanning, CHIP_NO_ERROR); + VerifyOrReturnError(mIsScanning, CHIP_NO_ERROR); int rc = esp_ble_gap_stop_scanning(); if (rc != 0) diff --git a/src/platform/ESP32/nimble/ChipDeviceScanner.cpp b/src/platform/ESP32/nimble/ChipDeviceScanner.cpp index 4e01340558503f..89dbbd91f06594 100644 --- a/src/platform/ESP32/nimble/ChipDeviceScanner.cpp +++ b/src/platform/ESP32/nimble/ChipDeviceScanner.cpp @@ -95,7 +95,7 @@ int ChipDeviceScanner::OnBleCentralEvent(struct ble_gap_event * event, void * ar CHIP_ERROR ChipDeviceScanner::StartScan(uint16_t timeout) { - ReturnErrorCodeIf(mIsScanning, CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(!mIsScanning, CHIP_ERROR_INCORRECT_STATE); uint8_t ownAddrType; struct ble_gap_disc_params discParams; @@ -135,7 +135,7 @@ CHIP_ERROR ChipDeviceScanner::StartScan(uint16_t timeout) CHIP_ERROR ChipDeviceScanner::StopScan() { - ReturnErrorCodeIf(!mIsScanning, CHIP_NO_ERROR); + VerifyOrReturnError(mIsScanning, CHIP_NO_ERROR); int rc = ble_gap_disc_cancel(); if (rc != 0) diff --git a/src/platform/Infineon/CYW30739/FactoryDataProvider.cpp b/src/platform/Infineon/CYW30739/FactoryDataProvider.cpp index 412259bda75013..6ed897bfd4859b 100644 --- a/src/platform/Infineon/CYW30739/FactoryDataProvider.cpp +++ b/src/platform/Infineon/CYW30739/FactoryDataProvider.cpp @@ -204,8 +204,8 @@ CHIP_ERROR FactoryDataProvider::GetRotatingDeviceIdUniqueId(MutableByteSpan & un constexpr uint8_t uniqueId[] = CHIP_DEVICE_CONFIG_ROTATING_DEVICE_ID_UNIQUE_ID; - ReturnErrorCodeIf(sizeof(uniqueId) > uniqueIdSpan.size(), CHIP_ERROR_BUFFER_TOO_SMALL); - ReturnErrorCodeIf(sizeof(uniqueId) != ConfigurationManager::kRotatingDeviceIDUniqueIDLength, CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(sizeof(uniqueId) <= uniqueIdSpan.size(), CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(sizeof(uniqueId) == ConfigurationManager::kRotatingDeviceIDUniqueIDLength, CHIP_ERROR_BUFFER_TOO_SMALL); memcpy(uniqueIdSpan.data(), uniqueId, sizeof(uniqueId)); uniqueIdSpan.reduce_size(sizeof(uniqueId)); } diff --git a/src/platform/Infineon/CYW30739/KeyValueStoreManagerImpl.cpp b/src/platform/Infineon/CYW30739/KeyValueStoreManagerImpl.cpp index 079acbe90682d6..a77fc2c549be79 100644 --- a/src/platform/Infineon/CYW30739/KeyValueStoreManagerImpl.cpp +++ b/src/platform/Infineon/CYW30739/KeyValueStoreManagerImpl.cpp @@ -195,11 +195,11 @@ KeyValueStoreManagerImpl::KeyConfigIdEntry * KeyValueStoreManagerImpl::AllocateE { Optional freeConfigID; KeyConfigIdEntry * newEntry = FindEntry(key, &freeConfigID); - ReturnErrorCodeIf(newEntry != nullptr, newEntry); - ReturnErrorCodeIf(!freeConfigID.HasValue(), nullptr); + VerifyOrReturnError(newEntry == nullptr, newEntry); + VerifyOrReturnError(freeConfigID.HasValue(), nullptr); newEntry = Platform::New(freeConfigID.Value(), KeyStorage(key)); - ReturnErrorCodeIf(newEntry == nullptr, nullptr); + VerifyOrReturnError(newEntry != nullptr, nullptr); KeyConfigIdEntry * entry = static_cast(slist_tail(&mKeyConfigIdList)); if (entry == nullptr) diff --git a/src/platform/Infineon/CYW30739/OTAImageProcessorImpl.cpp b/src/platform/Infineon/CYW30739/OTAImageProcessorImpl.cpp index 087295247278b1..02c654d9294f16 100644 --- a/src/platform/Infineon/CYW30739/OTAImageProcessorImpl.cpp +++ b/src/platform/Infineon/CYW30739/OTAImageProcessorImpl.cpp @@ -228,7 +228,7 @@ CHIP_ERROR OTAImageProcessorImpl::ProcessHeader(ByteSpan & block) CHIP_ERROR error = mHeaderParser.AccumulateAndDecode(block, header); // Needs more data to decode the header - ReturnErrorCodeIf(error == CHIP_ERROR_BUFFER_TOO_SMALL, CHIP_NO_ERROR); + VerifyOrReturnError(error != CHIP_ERROR_BUFFER_TOO_SMALL, CHIP_NO_ERROR); ReturnErrorOnFailure(error); mParams.totalFileBytes = header.mPayloadSize; diff --git a/src/platform/Infineon/PSOC6/OTAImageProcessorImpl.cpp b/src/platform/Infineon/PSOC6/OTAImageProcessorImpl.cpp index d47434a80d4fb0..b6b3dfb9ed528c 100644 --- a/src/platform/Infineon/PSOC6/OTAImageProcessorImpl.cpp +++ b/src/platform/Infineon/PSOC6/OTAImageProcessorImpl.cpp @@ -68,7 +68,7 @@ CHIP_ERROR OTAImageProcessorImpl::ProcessHeader(ByteSpan & block) // If we have not received all the bytes of the OTAImageHeader yet, that is OK. // Return CHIP_NO_ERROR and expect that future blocks will contain the rest. - ReturnErrorCodeIf(error == CHIP_ERROR_BUFFER_TOO_SMALL, CHIP_NO_ERROR); + VerifyOrReturnError(error != CHIP_ERROR_BUFFER_TOO_SMALL, CHIP_NO_ERROR); // If there is some error other than "too small", return that so future // processing will be aborted. @@ -107,10 +107,10 @@ CHIP_ERROR OTAImageProcessorImpl::ProcessBlock(ByteSpan & block) bool OTAImageProcessorImpl::IsFirstImageRun() { OTARequestorInterface * requestor = GetRequestorInstance(); - ReturnErrorCodeIf(requestor == nullptr, false); + VerifyOrReturnError(requestor != nullptr, false); uint32_t currentVersion; - ReturnErrorCodeIf(ConfigurationMgr().GetSoftwareVersion(currentVersion) != CHIP_NO_ERROR, false); + VerifyOrReturnError(ConfigurationMgr().GetSoftwareVersion(currentVersion) == CHIP_NO_ERROR, false); ChipLogProgress(SoftwareUpdate, "%ld", currentVersion); ChipLogProgress(SoftwareUpdate, "%ld", requestor->GetTargetVersion()); diff --git a/src/platform/Linux/OTAImageProcessorImpl.cpp b/src/platform/Linux/OTAImageProcessorImpl.cpp index b6fe393e01e19d..207de208ee0188 100644 --- a/src/platform/Linux/OTAImageProcessorImpl.cpp +++ b/src/platform/Linux/OTAImageProcessorImpl.cpp @@ -226,7 +226,7 @@ CHIP_ERROR OTAImageProcessorImpl::ProcessHeader(ByteSpan & block) CHIP_ERROR error = mHeaderParser.AccumulateAndDecode(block, header); // Needs more data to decode the header - ReturnErrorCodeIf(error == CHIP_ERROR_BUFFER_TOO_SMALL, CHIP_NO_ERROR); + VerifyOrReturnError(error != CHIP_ERROR_BUFFER_TOO_SMALL, CHIP_NO_ERROR); ReturnErrorOnFailure(error); mParams.totalFileBytes = header.mPayloadSize; diff --git a/src/platform/NuttX/OTAImageProcessorImpl.cpp b/src/platform/NuttX/OTAImageProcessorImpl.cpp index b6fe393e01e19d..207de208ee0188 100644 --- a/src/platform/NuttX/OTAImageProcessorImpl.cpp +++ b/src/platform/NuttX/OTAImageProcessorImpl.cpp @@ -226,7 +226,7 @@ CHIP_ERROR OTAImageProcessorImpl::ProcessHeader(ByteSpan & block) CHIP_ERROR error = mHeaderParser.AccumulateAndDecode(block, header); // Needs more data to decode the header - ReturnErrorCodeIf(error == CHIP_ERROR_BUFFER_TOO_SMALL, CHIP_NO_ERROR); + VerifyOrReturnError(error != CHIP_ERROR_BUFFER_TOO_SMALL, CHIP_NO_ERROR); ReturnErrorOnFailure(error); mParams.totalFileBytes = header.mPayloadSize; diff --git a/src/platform/OpenThread/GenericNetworkCommissioningThreadDriver.cpp b/src/platform/OpenThread/GenericNetworkCommissioningThreadDriver.cpp index cb0b05a57e3510..0c1d482f84c751 100644 --- a/src/platform/OpenThread/GenericNetworkCommissioningThreadDriver.cpp +++ b/src/platform/OpenThread/GenericNetworkCommissioningThreadDriver.cpp @@ -95,7 +95,7 @@ CHIP_ERROR GenericThreadDriver::RevertConfiguration() // If no backup could be found, it means that the network configuration has not been modified // since the fail-safe was armed, so return with no error. - ReturnErrorCodeIf(error == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND, CHIP_NO_ERROR); + VerifyOrReturnError(error != CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND, CHIP_NO_ERROR); if (!GetEnabled()) { diff --git a/src/platform/OpenThread/GenericThreadBorderRouterDelegate.cpp b/src/platform/OpenThread/GenericThreadBorderRouterDelegate.cpp index b08b0ab47321b3..69676488adf219 100644 --- a/src/platform/OpenThread/GenericThreadBorderRouterDelegate.cpp +++ b/src/platform/OpenThread/GenericThreadBorderRouterDelegate.cpp @@ -219,7 +219,7 @@ CHIP_ERROR GenericOpenThreadBorderRouterDelegate::SetPendingDataset(const Thread datasetTlvs.mLength = pendingDataset.AsByteSpan().size(); { ScopedThreadLock threadLock; - ReturnErrorCodeIf(otDatasetSetPendingTlvs(otInst, &datasetTlvs) != OT_ERROR_NONE, CHIP_ERROR_INTERNAL); + VerifyOrReturnError(otDatasetSetPendingTlvs(otInst, &datasetTlvs) == OT_ERROR_NONE, CHIP_ERROR_INTERNAL); } return CHIP_NO_ERROR; } diff --git a/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.hpp b/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.hpp index 6916c096c9ce50..f15e22252d6ab9 100644 --- a/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.hpp +++ b/src/platform/OpenThread/GenericThreadStackManagerImpl_OpenThread.hpp @@ -1798,7 +1798,7 @@ CHIP_ERROR GenericThreadStackManagerImpl_OpenThread::FromOtDnsRespons entryIndex++; } - ReturnErrorCodeIf(alloc.AnyAllocFailed(), CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(!alloc.AnyAllocFailed(), CHIP_ERROR_BUFFER_TOO_SMALL); mdnsService.mTextEntries = serviceTxtEntries.mTxtEntries; mdnsService.mTextEntrySize = entryIndex; diff --git a/src/platform/OpenThread/OpenThreadDnssdImpl.cpp b/src/platform/OpenThread/OpenThreadDnssdImpl.cpp index f5b0a85f2d0d83..79a8608091b909 100644 --- a/src/platform/OpenThread/OpenThreadDnssdImpl.cpp +++ b/src/platform/OpenThread/OpenThreadDnssdImpl.cpp @@ -47,7 +47,7 @@ const char * GetProtocolString(DnssdServiceProtocol protocol) CHIP_ERROR OpenThreadDnssdPublishService(const DnssdService * service, DnssdPublishCallback callback, void * context) { #if CHIP_DEVICE_CONFIG_ENABLE_THREAD_SRP_CLIENT - ReturnErrorCodeIf(service == nullptr, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(service != nullptr, CHIP_ERROR_INVALID_ARGUMENT); if (strcmp(service->mHostName, "") != 0) { ReturnErrorOnFailure(ThreadStackMgr().SetupSrpHost(service->mHostName)); diff --git a/src/platform/Tizen/ConnectivityManagerImpl.cpp b/src/platform/Tizen/ConnectivityManagerImpl.cpp index 37a15bb9546c75..063765687b4071 100644 --- a/src/platform/Tizen/ConnectivityManagerImpl.cpp +++ b/src/platform/Tizen/ConnectivityManagerImpl.cpp @@ -115,7 +115,7 @@ ConnectivityManager::WiFiStationMode ConnectivityManagerImpl::_GetWiFiStationMod CHIP_ERROR err = CHIP_NO_ERROR; wifi_manager_device_state_e deviceState = WIFI_MANAGER_DEVICE_STATE_DEACTIVATED; - ReturnErrorCodeIf(mWiFiStationMode == kWiFiStationMode_ApplicationControlled, mWiFiStationMode); + VerifyOrReturnError(mWiFiStationMode != kWiFiStationMode_ApplicationControlled, mWiFiStationMode); err = Internal::WiFiMgr().GetDeviceState(&deviceState); VerifyOrReturnError(err == CHIP_NO_ERROR, mWiFiStationMode); @@ -130,7 +130,7 @@ CHIP_ERROR ConnectivityManagerImpl::_SetWiFiStationMode(ConnectivityManager::WiF CHIP_ERROR err = CHIP_NO_ERROR; wifi_manager_device_state_e deviceState = WIFI_MANAGER_DEVICE_STATE_DEACTIVATED; - ReturnErrorCodeIf(val == kWiFiStationMode_NotSupported, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(val != kWiFiStationMode_NotSupported, CHIP_ERROR_INVALID_ARGUMENT); if (val != kWiFiStationMode_ApplicationControlled) { diff --git a/src/platform/Zephyr/BLEAdvertisingArbiter.cpp b/src/platform/Zephyr/BLEAdvertisingArbiter.cpp index 4356ba9aa146ea..0fafdba94402b8 100644 --- a/src/platform/Zephyr/BLEAdvertisingArbiter.cpp +++ b/src/platform/Zephyr/BLEAdvertisingArbiter.cpp @@ -56,7 +56,7 @@ CHIP_ERROR RestartAdvertising() { // Note: bt_le_adv_stop() returns success when the advertising was not started ReturnErrorOnFailure(System::MapErrorZephyr(bt_le_adv_stop())); - ReturnErrorCodeIf(sys_slist_is_empty(&sRequests), CHIP_NO_ERROR); + VerifyOrReturnError(!sys_slist_is_empty(&sRequests), CHIP_NO_ERROR); const Request & top = ToRequest(sys_slist_peek_head(&sRequests)); bt_le_adv_param params = BT_LE_ADV_PARAM_INIT(top.options, top.minInterval, top.maxInterval, nullptr); diff --git a/src/platform/Zephyr/KeyValueStoreManagerImpl.cpp b/src/platform/Zephyr/KeyValueStoreManagerImpl.cpp index 03c82341a8fc31..95c004e7f7a8d8 100644 --- a/src/platform/Zephyr/KeyValueStoreManagerImpl.cpp +++ b/src/platform/Zephyr/KeyValueStoreManagerImpl.cpp @@ -195,9 +195,9 @@ CHIP_ERROR KeyValueStoreManagerImpl::_Delete(const char * key) char fullKey[SETTINGS_MAX_NAME_LEN + 1]; ReturnErrorOnFailure(MakeFullKey(fullKey, key)); - ReturnErrorCodeIf(Get(key, nullptr, 0) == CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND, - CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); - ReturnErrorCodeIf(settings_delete(fullKey) != 0, CHIP_ERROR_PERSISTED_STORAGE_FAILED); + VerifyOrReturnError(Get(key, nullptr, 0) != CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND, + CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + VerifyOrReturnError(settings_delete(fullKey) == 0, CHIP_ERROR_PERSISTED_STORAGE_FAILED); return CHIP_NO_ERROR; } diff --git a/src/platform/Zephyr/SystemTimeSupport.cpp b/src/platform/Zephyr/SystemTimeSupport.cpp index c9ebdf7da2c31d..fc9485556abaa7 100644 --- a/src/platform/Zephyr/SystemTimeSupport.cpp +++ b/src/platform/Zephyr/SystemTimeSupport.cpp @@ -63,7 +63,7 @@ CHIP_ERROR ClockImpl::GetClock_RealTime(Microseconds64 & aCurTime) { // The real time can be configured by an application if it has access to a reliable time source. // Otherwise, just return an error so that Matter stack can fallback to Last Known UTC Time. - ReturnErrorCodeIf(gBootRealTime == kUnknownRealTime, CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(gBootRealTime != kUnknownRealTime, CHIP_ERROR_INCORRECT_STATE); aCurTime = gBootRealTime + GetMonotonicMicroseconds64(); diff --git a/src/platform/android/AndroidConfig.cpp b/src/platform/android/AndroidConfig.cpp index 510008f4411947..e3e7f3a58bc064 100644 --- a/src/platform/android/AndroidConfig.cpp +++ b/src/platform/android/AndroidConfig.cpp @@ -196,11 +196,11 @@ CHIP_ERROR AndroidConfig::ReadConfigValue(Key key, uint32_t & val) CHIP_ERROR AndroidConfig::ReadConfigValue(Key key, uint64_t & val) { chip::DeviceLayer::StackUnlock unlock; - ReturnErrorCodeIf(!gAndroidConfigObject.HasValidObjectRef(), CHIP_ERROR_INCORRECT_STATE); - ReturnErrorCodeIf(gReadConfigValueLongMethod == nullptr, CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(gAndroidConfigObject.HasValidObjectRef(), CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(gReadConfigValueLongMethod != nullptr, CHIP_ERROR_INCORRECT_STATE); JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); - ReturnErrorCodeIf(env == nullptr, CHIP_ERROR_INTERNAL); + VerifyOrReturnError(env != nullptr, CHIP_ERROR_INTERNAL); UtfString space(env, key.Namespace); UtfString name(env, key.Name); @@ -223,11 +223,11 @@ CHIP_ERROR AndroidConfig::ReadConfigValue(Key key, uint64_t & val) CHIP_ERROR AndroidConfig::ReadConfigValueStr(Key key, char * buf, size_t bufSize, size_t & outLen) { chip::DeviceLayer::StackUnlock unlock; - ReturnErrorCodeIf(!gAndroidConfigObject.HasValidObjectRef(), CHIP_ERROR_INCORRECT_STATE); - ReturnErrorCodeIf(gReadConfigValueStrMethod == nullptr, CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(gAndroidConfigObject.HasValidObjectRef(), CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(gReadConfigValueStrMethod != nullptr, CHIP_ERROR_INCORRECT_STATE); JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); - ReturnErrorCodeIf(env == nullptr, CHIP_ERROR_INTERNAL); + VerifyOrReturnError(env != nullptr, CHIP_ERROR_INTERNAL); UtfString space(env, key.Namespace); UtfString name(env, key.Name); @@ -253,11 +253,11 @@ CHIP_ERROR AndroidConfig::ReadConfigValueStr(Key key, char * buf, size_t bufSize CHIP_ERROR AndroidConfig::ReadConfigValueBin(Key key, uint8_t * buf, size_t bufSize, size_t & outLen) { chip::DeviceLayer::StackUnlock unlock; - ReturnErrorCodeIf(!gAndroidConfigObject.HasValidObjectRef(), CHIP_ERROR_INCORRECT_STATE); - ReturnErrorCodeIf(gReadConfigValueBinMethod == nullptr, CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(gAndroidConfigObject.HasValidObjectRef(), CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(gReadConfigValueBinMethod != nullptr, CHIP_ERROR_INCORRECT_STATE); JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); - ReturnErrorCodeIf(env == nullptr, CHIP_ERROR_INTERNAL); + VerifyOrReturnError(env != nullptr, CHIP_ERROR_INTERNAL); UtfString space(env, key.Namespace); UtfString name(env, key.Name); @@ -300,11 +300,11 @@ CHIP_ERROR AndroidConfig::WriteConfigValue(Key key, uint32_t val) CHIP_ERROR AndroidConfig::WriteConfigValue(Key key, uint64_t val) { chip::DeviceLayer::StackUnlock unlock; - ReturnErrorCodeIf(!gAndroidConfigObject.HasValidObjectRef(), CHIP_ERROR_INCORRECT_STATE); - ReturnErrorCodeIf(gWriteConfigValueLongMethod == nullptr, CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(gAndroidConfigObject.HasValidObjectRef(), CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(gWriteConfigValueLongMethod != nullptr, CHIP_ERROR_INCORRECT_STATE); JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); - ReturnErrorCodeIf(env == nullptr, CHIP_ERROR_INTERNAL); + VerifyOrReturnError(env != nullptr, CHIP_ERROR_INTERNAL); UtfString space(env, key.Namespace); UtfString name(env, key.Name); @@ -325,11 +325,11 @@ CHIP_ERROR AndroidConfig::WriteConfigValue(Key key, uint64_t val) CHIP_ERROR AndroidConfig::WriteConfigValueStr(Key key, const char * str) { chip::DeviceLayer::StackUnlock unlock; - ReturnErrorCodeIf(!gAndroidConfigObject.HasValidObjectRef(), CHIP_ERROR_INCORRECT_STATE); - ReturnErrorCodeIf(gWriteConfigValueStrMethod == nullptr, CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(gAndroidConfigObject.HasValidObjectRef(), CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(gWriteConfigValueStrMethod != nullptr, CHIP_ERROR_INCORRECT_STATE); JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); - ReturnErrorCodeIf(env == nullptr, CHIP_ERROR_INTERNAL); + VerifyOrReturnError(env != nullptr, CHIP_ERROR_INTERNAL); UtfString space(env, key.Namespace); UtfString name(env, key.Name); @@ -376,12 +376,12 @@ CHIP_ERROR AndroidConfig::WriteConfigValueStr(Key key, const char * str, size_t CHIP_ERROR AndroidConfig::WriteConfigValueBin(Key key, const uint8_t * data, size_t dataLen) { chip::DeviceLayer::StackUnlock unlock; - ReturnErrorCodeIf(!gAndroidConfigObject.HasValidObjectRef(), CHIP_ERROR_INCORRECT_STATE); - ReturnErrorCodeIf(gWriteConfigValueBinMethod == nullptr, CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(gAndroidConfigObject.HasValidObjectRef(), CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(gWriteConfigValueBinMethod != nullptr, CHIP_ERROR_INCORRECT_STATE); VerifyOrReturnError(chip::CanCastTo(dataLen), CHIP_ERROR_INVALID_ARGUMENT); JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); - ReturnErrorCodeIf(env == nullptr, CHIP_ERROR_INTERNAL); + VerifyOrReturnError(env != nullptr, CHIP_ERROR_INTERNAL); UtfString space(env, key.Namespace); UtfString name(env, key.Name); @@ -403,11 +403,11 @@ CHIP_ERROR AndroidConfig::WriteConfigValueBin(Key key, const uint8_t * data, siz CHIP_ERROR AndroidConfig::ClearConfigValue(Key key) { chip::DeviceLayer::StackUnlock unlock; - ReturnErrorCodeIf(!gAndroidConfigObject.HasValidObjectRef(), CHIP_ERROR_INCORRECT_STATE); - ReturnErrorCodeIf(gClearConfigValueMethod == nullptr, CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(gAndroidConfigObject.HasValidObjectRef(), CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(gClearConfigValueMethod != nullptr, CHIP_ERROR_INCORRECT_STATE); JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); - ReturnErrorCodeIf(env == nullptr, CHIP_ERROR_INTERNAL); + VerifyOrReturnError(env != nullptr, CHIP_ERROR_INTERNAL); UtfString space(env, key.Namespace); UtfString name(env, key.Name); @@ -427,11 +427,11 @@ CHIP_ERROR AndroidConfig::ClearConfigValue(Key key) bool AndroidConfig::ConfigValueExists(Key key) { chip::DeviceLayer::StackUnlock unlock; - ReturnErrorCodeIf(!gAndroidConfigObject.HasValidObjectRef(), false); - ReturnErrorCodeIf(gConfigValueExistsMethod == nullptr, false); + VerifyOrReturnError(gAndroidConfigObject.HasValidObjectRef(), false); + VerifyOrReturnError(gConfigValueExistsMethod != nullptr, false); JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); - ReturnErrorCodeIf(env == nullptr, false); + VerifyOrReturnError(env != nullptr, false); UtfString space(env, key.Namespace); UtfString name(env, key.Name); diff --git a/src/platform/android/ConfigurationManagerImpl.cpp b/src/platform/android/ConfigurationManagerImpl.cpp index defbb77f89b6f6..762e70f6079707 100644 --- a/src/platform/android/ConfigurationManagerImpl.cpp +++ b/src/platform/android/ConfigurationManagerImpl.cpp @@ -169,7 +169,7 @@ CHIP_ERROR ConfigurationManagerImpl::GetSoftwareVersionString(char * buf, size_t if (err == CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND) { - ReturnErrorCodeIf(bufSize < sizeof(CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING), CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(bufSize >= sizeof(CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING), CHIP_ERROR_BUFFER_TOO_SMALL); strcpy(buf, CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING); } @@ -208,7 +208,7 @@ CHIP_ERROR ConfigurationManagerImpl::GetCommissionableDeviceName(char * buf, siz if (err == CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND) { - ReturnErrorCodeIf(bufSize < sizeof(CHIP_DEVICE_CONFIG_DEVICE_NAME), CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(bufSize >= sizeof(CHIP_DEVICE_CONFIG_DEVICE_NAME), CHIP_ERROR_BUFFER_TOO_SMALL); strcpy(buf, CHIP_DEVICE_CONFIG_DEVICE_NAME); } diff --git a/src/platform/android/DeviceInstanceInfoProviderImpl.cpp b/src/platform/android/DeviceInstanceInfoProviderImpl.cpp index cd07215c378e74..3faac5ba05fd22 100644 --- a/src/platform/android/DeviceInstanceInfoProviderImpl.cpp +++ b/src/platform/android/DeviceInstanceInfoProviderImpl.cpp @@ -32,7 +32,8 @@ CHIP_ERROR DeviceInstanceInfoProviderImpl::GetHardwareVersionString(char * buf, hardwareVersionLen); if (err == CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND) { - ReturnErrorCodeIf(bufSize < sizeof(CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION_STRING), CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(bufSize >= sizeof(CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION_STRING), + CHIP_ERROR_BUFFER_TOO_SMALL); strcpy(buf, CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION_STRING); } @@ -81,7 +82,7 @@ CHIP_ERROR DeviceInstanceInfoProviderImpl::GetProductName(char * buf, size_t buf Internal::AndroidConfig::ReadConfigValueStr(Internal::AndroidConfig::kConfigKey_ProductName, buf, bufSize, productNameSize); if (err == CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND) { - ReturnErrorCodeIf(bufSize < sizeof(CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_NAME), CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(bufSize >= sizeof(CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_NAME), CHIP_ERROR_BUFFER_TOO_SMALL); strcpy(buf, CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_NAME); } return CHIP_NO_ERROR; diff --git a/src/platform/android/DnssdImpl.cpp b/src/platform/android/DnssdImpl.cpp index 290b3497ea11d4..d93ec2c52d22a6 100644 --- a/src/platform/android/DnssdImpl.cpp +++ b/src/platform/android/DnssdImpl.cpp @@ -244,10 +244,10 @@ template CHIP_ERROR extractProtocol(const char * serviceType, char (&outServiceName)[N], DnssdServiceProtocol & outProtocol) { const char * dotPos = strrchr(serviceType, '.'); - ReturnErrorCodeIf(dotPos == nullptr, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(dotPos != nullptr, CHIP_ERROR_INVALID_ARGUMENT); size_t lengthWithoutProtocol = static_cast(dotPos - serviceType); - ReturnErrorCodeIf(lengthWithoutProtocol + 1 > N, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(lengthWithoutProtocol + 1 <= N, CHIP_ERROR_INVALID_ARGUMENT); memcpy(outServiceName, serviceType, lengthWithoutProtocol); outServiceName[lengthWithoutProtocol] = '\0'; // Set a null terminator @@ -267,7 +267,7 @@ CHIP_ERROR extractProtocol(const char * serviceType, char (&outServiceName)[N], return CHIP_ERROR_INVALID_ARGUMENT; } - ReturnErrorCodeIf(outProtocol == DnssdServiceProtocol::kDnssdProtocolUnknown, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(outProtocol != DnssdServiceProtocol::kDnssdProtocolUnknown, CHIP_ERROR_INVALID_ARGUMENT); return CHIP_NO_ERROR; } diff --git a/src/platform/android/KeyValueStoreManagerImpl.cpp b/src/platform/android/KeyValueStoreManagerImpl.cpp index 658532f6524137..9d382150ca3c91 100644 --- a/src/platform/android/KeyValueStoreManagerImpl.cpp +++ b/src/platform/android/KeyValueStoreManagerImpl.cpp @@ -80,11 +80,11 @@ CHIP_ERROR KeyValueStoreManagerImpl::_Get(const char * key, void * value, size_t size_t offset_bytes) { CHIP_ERROR err = CHIP_NO_ERROR; - ReturnErrorCodeIf(!mKeyValueStoreManagerObject.HasValidObjectRef(), CHIP_ERROR_INCORRECT_STATE); - ReturnErrorCodeIf(mGetMethod == nullptr, CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(mKeyValueStoreManagerObject.HasValidObjectRef(), CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(mGetMethod != nullptr, CHIP_ERROR_INCORRECT_STATE); JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); - ReturnErrorCodeIf(env == nullptr, CHIP_JNI_ERROR_NO_ENV); + VerifyOrReturnError(env != nullptr, CHIP_JNI_ERROR_NO_ENV); chip::UtfString javaKey(env, key); @@ -118,7 +118,7 @@ CHIP_ERROR KeyValueStoreManagerImpl::_Get(const char * key, void * value, size_t ChipLogError(DeviceLayer, "KeyValueStoreManager base64 decoding failed"); return CHIP_ERROR_INTEGRITY_CHECK_FAILED; } - ReturnErrorCodeIf(offset_bytes != 0 && offset_bytes >= decodedLength, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(offset_bytes == 0 || offset_bytes < decodedLength, CHIP_ERROR_INVALID_ARGUMENT); size_t read_size = std::min(value_size, decodedLength - offset_bytes); if (value_size + offset_bytes < decodedLength) { @@ -140,12 +140,12 @@ CHIP_ERROR KeyValueStoreManagerImpl::_Get(const char * key, void * value, size_t CHIP_ERROR KeyValueStoreManagerImpl::_Put(const char * key, const void * value, size_t value_size) { - ReturnErrorCodeIf(!mKeyValueStoreManagerObject.HasValidObjectRef(), CHIP_ERROR_INCORRECT_STATE); - ReturnErrorCodeIf(mSetMethod == nullptr, CHIP_ERROR_INCORRECT_STATE); - ReturnErrorCodeIf(value_size > kMaxKvsValueBytes, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(mKeyValueStoreManagerObject.HasValidObjectRef(), CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(mSetMethod != nullptr, CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(value_size <= kMaxKvsValueBytes, CHIP_ERROR_INVALID_ARGUMENT); JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); - ReturnErrorCodeIf(env == nullptr, CHIP_ERROR_INTERNAL); + VerifyOrReturnError(env != nullptr, CHIP_ERROR_INTERNAL); std::unique_ptr buffer(new char[BASE64_ENCODED_LEN(value_size) + 1]); @@ -170,11 +170,11 @@ CHIP_ERROR KeyValueStoreManagerImpl::_Put(const char * key, const void * value, CHIP_ERROR KeyValueStoreManagerImpl::_Delete(const char * key) { - ReturnErrorCodeIf(!mKeyValueStoreManagerObject.HasValidObjectRef(), CHIP_ERROR_INCORRECT_STATE); - ReturnErrorCodeIf(mDeleteMethod == nullptr, CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(mKeyValueStoreManagerObject.HasValidObjectRef(), CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(mDeleteMethod != nullptr, CHIP_ERROR_INCORRECT_STATE); JNIEnv * env = JniReferences::GetInstance().GetEnvForCurrentThread(); - ReturnErrorCodeIf(env == nullptr, CHIP_ERROR_INTERNAL); + VerifyOrReturnError(env != nullptr, CHIP_ERROR_INTERNAL); UtfString javaKey(env, key); diff --git a/src/platform/cc13xx_26xx/FactoryDataProvider.cpp b/src/platform/cc13xx_26xx/FactoryDataProvider.cpp index 695d7e5f757f39..4244fd48b2a34d 100644 --- a/src/platform/cc13xx_26xx/FactoryDataProvider.cpp +++ b/src/platform/cc13xx_26xx/FactoryDataProvider.cpp @@ -135,8 +135,8 @@ CHIP_ERROR FactoryDataProvider::GetFirmwareInformation(MutableByteSpan & out_fir } CHIP_ERROR FactoryDataProvider::GetDeviceAttestationCert(MutableByteSpan & outBuffer) { - ReturnErrorCodeIf(outBuffer.size() < mFactoryData.dac_cert.len, CHIP_ERROR_BUFFER_TOO_SMALL); - ReturnErrorCodeIf(!mFactoryData.dac_cert.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + VerifyOrReturnError(outBuffer.size() >= mFactoryData.dac_cert.len, CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(mFactoryData.dac_cert.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); memcpy(outBuffer.data(), mFactoryData.dac_cert.data, mFactoryData.dac_cert.len); outBuffer.reduce_size(mFactoryData.dac_cert.len); @@ -145,8 +145,8 @@ CHIP_ERROR FactoryDataProvider::GetDeviceAttestationCert(MutableByteSpan & outBu CHIP_ERROR FactoryDataProvider::GetProductAttestationIntermediateCert(MutableByteSpan & outBuffer) { - ReturnErrorCodeIf(outBuffer.size() < mFactoryData.pai_cert.len, CHIP_ERROR_BUFFER_TOO_SMALL); - ReturnErrorCodeIf(!mFactoryData.pai_cert.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + VerifyOrReturnError(outBuffer.size() >= mFactoryData.pai_cert.len, CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(mFactoryData.pai_cert.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); memcpy(outBuffer.data(), mFactoryData.pai_cert.data, mFactoryData.pai_cert.len); outBuffer.reduce_size(mFactoryData.pai_cert.len); @@ -165,7 +165,7 @@ CHIP_ERROR FactoryDataProvider::SignWithDeviceAttestationKey(const ByteSpan & me // Extract public key from DAC cert. uint8_t dacBuf[600] = { 0 }; MutableByteSpan dacCertSpan(dacBuf); - ReturnErrorCodeIf(dacCertSpan.size() < mFactoryData.dac_cert.len, CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(dacCertSpan.size() >= mFactoryData.dac_cert.len, CHIP_ERROR_BUFFER_TOO_SMALL); memcpy(dacCertSpan.data(), mFactoryData.dac_cert.data, mFactoryData.dac_cert.len); dacCertSpan.reduce_size(mFactoryData.dac_cert.len); chip::Crypto::P256PublicKey dacPublicKey; @@ -174,13 +174,13 @@ CHIP_ERROR FactoryDataProvider::SignWithDeviceAttestationKey(const ByteSpan & me uint8_t privKeyBuf[600] = { 0 }; MutableByteSpan privKeySpan(privKeyBuf); - ReturnErrorCodeIf(privKeySpan.size() < mFactoryData.dac_priv_key.len, CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(privKeySpan.size() >= mFactoryData.dac_priv_key.len, CHIP_ERROR_BUFFER_TOO_SMALL); memcpy(privKeySpan.data(), mFactoryData.dac_priv_key.data, mFactoryData.dac_priv_key.len); privKeySpan.reduce_size(mFactoryData.dac_priv_key.len); uint8_t pubKeyBuf[600] = { 0 }; MutableByteSpan pubKeySpan(pubKeyBuf); - ReturnErrorCodeIf(pubKeySpan.size() < dacPublicKey.Length(), CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(pubKeySpan.size() >= dacPublicKey.Length(), CHIP_ERROR_BUFFER_TOO_SMALL); memcpy(pubKeySpan.data(), dacPublicKey.Bytes(), dacPublicKey.Length()); pubKeySpan.reduce_size(dacPublicKey.Length()); @@ -191,8 +191,8 @@ CHIP_ERROR FactoryDataProvider::SignWithDeviceAttestationKey(const ByteSpan & me } CHIP_ERROR FactoryDataProvider::GetSetupDiscriminator(uint16_t & setupDiscriminator) { - ReturnErrorCodeIf(sizeof(setupDiscriminator) < mFactoryData.discriminator.len, CHIP_ERROR_BUFFER_TOO_SMALL); - ReturnErrorCodeIf(!mFactoryData.discriminator.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + VerifyOrReturnError(sizeof(setupDiscriminator) >= mFactoryData.discriminator.len, CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(mFactoryData.discriminator.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); memcpy(&setupDiscriminator, mFactoryData.discriminator.data, mFactoryData.discriminator.len); return CHIP_NO_ERROR; } @@ -202,24 +202,24 @@ CHIP_ERROR FactoryDataProvider::SetSetupDiscriminator(uint16_t setupDiscriminato } CHIP_ERROR FactoryDataProvider::GetSpake2pIterationCount(uint32_t & iterationCount) { - ReturnErrorCodeIf(sizeof(iterationCount) < mFactoryData.spake2p_it.len, CHIP_ERROR_BUFFER_TOO_SMALL); - ReturnErrorCodeIf(!mFactoryData.spake2p_it.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + VerifyOrReturnError(sizeof(iterationCount) >= mFactoryData.spake2p_it.len, CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(mFactoryData.spake2p_it.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); memset(&iterationCount, 0, sizeof(iterationCount)); memcpy(&iterationCount, mFactoryData.spake2p_it.data, mFactoryData.spake2p_it.len); return CHIP_NO_ERROR; } CHIP_ERROR FactoryDataProvider::GetSpake2pSalt(MutableByteSpan & saltBuf) { - ReturnErrorCodeIf(saltBuf.size() < mFactoryData.spake2p_salt.len, CHIP_ERROR_BUFFER_TOO_SMALL); - ReturnErrorCodeIf(!mFactoryData.spake2p_salt.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + VerifyOrReturnError(saltBuf.size() >= mFactoryData.spake2p_salt.len, CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(mFactoryData.spake2p_salt.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); memcpy(saltBuf.data(), mFactoryData.spake2p_salt.data, mFactoryData.spake2p_salt.len); saltBuf.reduce_size(mFactoryData.spake2p_salt.len); return CHIP_NO_ERROR; } CHIP_ERROR FactoryDataProvider::GetSpake2pVerifier(MutableByteSpan & verifierBuf, size_t & verifierLen) { - ReturnErrorCodeIf(verifierBuf.size() < mFactoryData.spake2p_verifier.len, CHIP_ERROR_BUFFER_TOO_SMALL); - ReturnErrorCodeIf(!mFactoryData.spake2p_verifier.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + VerifyOrReturnError(verifierBuf.size() >= mFactoryData.spake2p_verifier.len, CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(mFactoryData.spake2p_verifier.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); memcpy(verifierBuf.data(), mFactoryData.spake2p_verifier.data, mFactoryData.spake2p_verifier.len); verifierLen = mFactoryData.spake2p_verifier.len; verifierBuf.reduce_size(verifierLen); @@ -227,8 +227,8 @@ CHIP_ERROR FactoryDataProvider::GetSpake2pVerifier(MutableByteSpan & verifierBuf } CHIP_ERROR FactoryDataProvider::GetSetupPasscode(uint32_t & setupPasscode) { - ReturnErrorCodeIf(sizeof(setupPasscode) < mFactoryData.passcode.len, CHIP_ERROR_BUFFER_TOO_SMALL); - ReturnErrorCodeIf(!mFactoryData.passcode.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + VerifyOrReturnError(sizeof(setupPasscode) >= mFactoryData.passcode.len, CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(mFactoryData.passcode.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); memcpy(&setupPasscode, mFactoryData.passcode.data, mFactoryData.passcode.len); return CHIP_NO_ERROR; } @@ -238,23 +238,23 @@ CHIP_ERROR FactoryDataProvider::SetSetupPasscode(uint32_t setupPasscode) } CHIP_ERROR FactoryDataProvider::GetVendorName(char * buf, size_t bufSize) { - ReturnErrorCodeIf(bufSize < mFactoryData.vendor_name.len + 1, CHIP_ERROR_BUFFER_TOO_SMALL); - ReturnErrorCodeIf(!mFactoryData.vendor_name.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + VerifyOrReturnError(bufSize >= mFactoryData.vendor_name.len + 1, CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(mFactoryData.vendor_name.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); memcpy(buf, mFactoryData.vendor_name.data, mFactoryData.vendor_name.len); buf[mFactoryData.vendor_name.len] = '\0'; return CHIP_NO_ERROR; } CHIP_ERROR FactoryDataProvider::GetVendorId(uint16_t & vendorId) { - ReturnErrorCodeIf(sizeof(vendorId) < mFactoryData.vendor_id.len, CHIP_ERROR_BUFFER_TOO_SMALL); - ReturnErrorCodeIf(!mFactoryData.vendor_id.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + VerifyOrReturnError(sizeof(vendorId) >= mFactoryData.vendor_id.len, CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(mFactoryData.vendor_id.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); memcpy(&vendorId, mFactoryData.vendor_id.data, mFactoryData.vendor_id.len); return CHIP_NO_ERROR; } CHIP_ERROR FactoryDataProvider::GetProductName(char * buf, size_t bufSize) { - ReturnErrorCodeIf(bufSize < mFactoryData.product_name.len + 1, CHIP_ERROR_BUFFER_TOO_SMALL); - ReturnErrorCodeIf(!mFactoryData.product_name.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + VerifyOrReturnError(bufSize >= mFactoryData.product_name.len + 1, CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(mFactoryData.product_name.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); memset(buf, 0, bufSize); memcpy(buf, mFactoryData.product_name.data, mFactoryData.product_name.len); buf[mFactoryData.product_name.len] = '\0'; @@ -262,8 +262,8 @@ CHIP_ERROR FactoryDataProvider::GetProductName(char * buf, size_t bufSize) } CHIP_ERROR FactoryDataProvider::GetProductId(uint16_t & productId) { - ReturnErrorCodeIf(sizeof(productId) < mFactoryData.product_id.len, CHIP_ERROR_BUFFER_TOO_SMALL); - ReturnErrorCodeIf(!mFactoryData.product_id.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + VerifyOrReturnError(sizeof(productId) >= mFactoryData.product_id.len, CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(mFactoryData.product_id.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); memcpy(&productId, mFactoryData.product_id.data, mFactoryData.product_id.len); return CHIP_NO_ERROR; } @@ -282,8 +282,8 @@ CHIP_ERROR FactoryDataProvider::GetProductLabel(char * buf, size_t bufSize) CHIP_ERROR FactoryDataProvider::GetSerialNumber(char * buf, size_t bufSize) { - ReturnErrorCodeIf(bufSize < mFactoryData.serial_number.len + 1, CHIP_ERROR_BUFFER_TOO_SMALL); - ReturnErrorCodeIf(!mFactoryData.serial_number.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + VerifyOrReturnError(bufSize >= mFactoryData.serial_number.len + 1, CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(mFactoryData.serial_number.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); memset(buf, 0, bufSize); memcpy(buf, mFactoryData.serial_number.data, mFactoryData.serial_number.len); buf[mFactoryData.serial_number.len] = '\0'; @@ -292,7 +292,7 @@ CHIP_ERROR FactoryDataProvider::GetSerialNumber(char * buf, size_t bufSize) CHIP_ERROR FactoryDataProvider::GetManufacturingDate(uint16_t & year, uint8_t & month, uint8_t & day) { - ReturnErrorCodeIf(!mFactoryData.manufacturing_date.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + VerifyOrReturnError(mFactoryData.manufacturing_date.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); uint8_t tmp[10] = { 0 }; memcpy(tmp, mFactoryData.manufacturing_date.data, 10); year = ((tmp[0] - 0x30) * 1000) + ((tmp[1] - 0x30) * 100) + ((tmp[2] - 0x30) * 10) + (tmp[3] - 0x30); @@ -303,15 +303,15 @@ CHIP_ERROR FactoryDataProvider::GetManufacturingDate(uint16_t & year, uint8_t & CHIP_ERROR FactoryDataProvider::GetHardwareVersion(uint16_t & hardwareVersion) { - ReturnErrorCodeIf(sizeof(hardwareVersion) < mFactoryData.hw_ver.len, CHIP_ERROR_BUFFER_TOO_SMALL); - ReturnErrorCodeIf(!mFactoryData.hw_ver.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + VerifyOrReturnError(sizeof(hardwareVersion) >= mFactoryData.hw_ver.len, CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(mFactoryData.hw_ver.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); memcpy(&hardwareVersion, mFactoryData.hw_ver.data, mFactoryData.hw_ver.len); return CHIP_NO_ERROR; } CHIP_ERROR FactoryDataProvider::GetHardwareVersionString(char * buf, size_t bufSize) { - ReturnErrorCodeIf(bufSize < mFactoryData.hw_ver_str.len + 1, CHIP_ERROR_BUFFER_TOO_SMALL); - ReturnErrorCodeIf(!mFactoryData.hw_ver_str.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + VerifyOrReturnError(bufSize >= mFactoryData.hw_ver_str.len + 1, CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(mFactoryData.hw_ver_str.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); memset(buf, 0, bufSize); memcpy(buf, mFactoryData.hw_ver_str.data, mFactoryData.hw_ver_str.len); buf[mFactoryData.hw_ver_str.len] = '\0'; @@ -321,8 +321,8 @@ CHIP_ERROR FactoryDataProvider::GetHardwareVersionString(char * buf, size_t bufS CHIP_ERROR FactoryDataProvider::GetRotatingDeviceIdUniqueId(MutableByteSpan & uniqueIdSpan) { - ReturnErrorCodeIf(uniqueIdSpan.size() < mFactoryData.rd_uniqueid.len, CHIP_ERROR_BUFFER_TOO_SMALL); - ReturnErrorCodeIf(!mFactoryData.rd_uniqueid.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + VerifyOrReturnError(uniqueIdSpan.size() >= mFactoryData.rd_uniqueid.len, CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(mFactoryData.rd_uniqueid.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); memcpy(uniqueIdSpan.data(), mFactoryData.rd_uniqueid.data, mFactoryData.rd_uniqueid.len); uniqueIdSpan.reduce_size(mFactoryData.rd_uniqueid.len); diff --git a/src/platform/mt793x/OTAImageProcessorImpl.cpp b/src/platform/mt793x/OTAImageProcessorImpl.cpp index 98685242aa4347..03a1d87dccacf5 100644 --- a/src/platform/mt793x/OTAImageProcessorImpl.cpp +++ b/src/platform/mt793x/OTAImageProcessorImpl.cpp @@ -255,7 +255,7 @@ CHIP_ERROR OTAImageProcessorImpl::ProcessHeader(ByteSpan & block) CHIP_ERROR error = mHeaderParser.AccumulateAndDecode(block, header); // Needs more data to decode the header - ReturnErrorCodeIf(error == CHIP_ERROR_BUFFER_TOO_SMALL, CHIP_NO_ERROR); + VerifyOrReturnError(error != CHIP_ERROR_BUFFER_TOO_SMALL, CHIP_NO_ERROR); ReturnErrorOnFailure(error); ChipLogProgress(SoftwareUpdate, "Image Header software version: %ld payload size: %lu", header.mSoftwareVersion, (long unsigned int) header.mPayloadSize); diff --git a/src/platform/nrfconnect/DeviceInstanceInfoProviderImpl.cpp b/src/platform/nrfconnect/DeviceInstanceInfoProviderImpl.cpp index ed4f2124edf754..1d30d5a9d38f5a 100644 --- a/src/platform/nrfconnect/DeviceInstanceInfoProviderImpl.cpp +++ b/src/platform/nrfconnect/DeviceInstanceInfoProviderImpl.cpp @@ -28,13 +28,13 @@ CHIP_ERROR DeviceInstanceInfoProviderImpl::GetRotatingDeviceIdUniqueId(MutableBy static_assert(ConfigurationManager::kRotatingDeviceIDUniqueIDLength >= ConfigurationManager::kMinRotatingDeviceIDUniqueIDLength, "Length of unique ID for rotating device ID is smaller than minimum."); - ReturnErrorCodeIf(ConfigurationManager::kRotatingDeviceIDUniqueIDLength > uniqueIdSpan.size(), CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(ConfigurationManager::kRotatingDeviceIDUniqueIDLength <= uniqueIdSpan.size(), CHIP_ERROR_BUFFER_TOO_SMALL); size_t bytesLen = chip::Encoding::HexToBytes(CONFIG_CHIP_DEVICE_ROTATING_DEVICE_UID, ConfigurationManager::kRotatingDeviceIDUniqueIDLength * 2, uniqueIdSpan.data(), uniqueIdSpan.size()); - ReturnErrorCodeIf(bytesLen != ConfigurationManager::kRotatingDeviceIDUniqueIDLength, CHIP_ERROR_INVALID_STRING_LENGTH); + VerifyOrReturnError(bytesLen == ConfigurationManager::kRotatingDeviceIDUniqueIDLength, CHIP_ERROR_INVALID_STRING_LENGTH); uniqueIdSpan.reduce_size(bytesLen); return CHIP_NO_ERROR; diff --git a/src/platform/nrfconnect/DiagnosticDataProviderImplNrf.cpp b/src/platform/nrfconnect/DiagnosticDataProviderImplNrf.cpp index e71e6e392c9edd..2c4b3b4ff934f4 100644 --- a/src/platform/nrfconnect/DiagnosticDataProviderImplNrf.cpp +++ b/src/platform/nrfconnect/DiagnosticDataProviderImplNrf.cpp @@ -46,7 +46,7 @@ CHIP_ERROR DiagnosticDataProviderImplNrf::GetWiFiBssId(MutableByteSpan & value) { WiFiManager::WiFiInfo info; ReturnErrorOnFailure(WiFiManager::Instance().GetWiFiInfo(info)); - ReturnErrorCodeIf(sizeof(info.mBssId) >= value.size(), CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(sizeof(info.mBssId) < value.size(), CHIP_ERROR_BUFFER_TOO_SMALL); memcpy(value.data(), info.mBssId, sizeof(info.mBssId)); value.reduce_size(sizeof(info.mBssId)); diff --git a/src/platform/nrfconnect/FactoryDataProvider.cpp b/src/platform/nrfconnect/FactoryDataProvider.cpp index aaa6f4b93e12bb..a93239ac98884a 100644 --- a/src/platform/nrfconnect/FactoryDataProvider.cpp +++ b/src/platform/nrfconnect/FactoryDataProvider.cpp @@ -40,8 +40,8 @@ CHIP_ERROR LoadKeypairFromRaw(ByteSpan privateKey, ByteSpan publicKey, Crypto::P CHIP_ERROR GetFactoryDataString(const FactoryDataString & str, char * buf, size_t bufSize) { - ReturnErrorCodeIf(bufSize < str.len + 1, CHIP_ERROR_BUFFER_TOO_SMALL); - ReturnErrorCodeIf(!str.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + VerifyOrReturnError(bufSize >= str.len + 1, CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(str.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); memcpy(buf, str.data, str.len); buf[str.len] = 0; @@ -128,8 +128,8 @@ CHIP_ERROR FactoryDataProvider::GetFirmwareInformation(Mutable template CHIP_ERROR FactoryDataProvider::GetDeviceAttestationCert(MutableByteSpan & outBuffer) { - ReturnErrorCodeIf(outBuffer.size() < mFactoryData.dac_cert.len, CHIP_ERROR_BUFFER_TOO_SMALL); - ReturnErrorCodeIf(!mFactoryData.dac_cert.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + VerifyOrReturnError(outBuffer.size() >= mFactoryData.dac_cert.len, CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(mFactoryData.dac_cert.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); memcpy(outBuffer.data(), mFactoryData.dac_cert.data, mFactoryData.dac_cert.len); @@ -141,8 +141,8 @@ CHIP_ERROR FactoryDataProvider::GetDeviceAttestationCert(Mutab template CHIP_ERROR FactoryDataProvider::GetProductAttestationIntermediateCert(MutableByteSpan & outBuffer) { - ReturnErrorCodeIf(outBuffer.size() < mFactoryData.pai_cert.len, CHIP_ERROR_BUFFER_TOO_SMALL); - ReturnErrorCodeIf(!mFactoryData.pai_cert.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + VerifyOrReturnError(outBuffer.size() >= mFactoryData.pai_cert.len, CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(mFactoryData.pai_cert.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); memcpy(outBuffer.data(), mFactoryData.pai_cert.data, mFactoryData.pai_cert.len); @@ -234,7 +234,7 @@ CHIP_ERROR FactoryDataProvider::SetSetupDiscriminator(uint16_t template CHIP_ERROR FactoryDataProvider::GetSpake2pIterationCount(uint32_t & iterationCount) { - ReturnErrorCodeIf(mFactoryData.spake2_it == 0, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + VerifyOrReturnError(mFactoryData.spake2_it != 0, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); iterationCount = mFactoryData.spake2_it; return CHIP_NO_ERROR; } @@ -242,8 +242,8 @@ CHIP_ERROR FactoryDataProvider::GetSpake2pIterationCount(uint3 template CHIP_ERROR FactoryDataProvider::GetSpake2pSalt(MutableByteSpan & saltBuf) { - ReturnErrorCodeIf(saltBuf.size() < mFactoryData.spake2_salt.len, CHIP_ERROR_BUFFER_TOO_SMALL); - ReturnErrorCodeIf(!mFactoryData.spake2_salt.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + VerifyOrReturnError(saltBuf.size() >= mFactoryData.spake2_salt.len, CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(mFactoryData.spake2_salt.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); memcpy(saltBuf.data(), mFactoryData.spake2_salt.data, mFactoryData.spake2_salt.len); @@ -255,8 +255,8 @@ CHIP_ERROR FactoryDataProvider::GetSpake2pSalt(MutableByteSpan template CHIP_ERROR FactoryDataProvider::GetSpake2pVerifier(MutableByteSpan & verifierBuf, size_t & verifierLen) { - ReturnErrorCodeIf(verifierBuf.size() < mFactoryData.spake2_verifier.len, CHIP_ERROR_BUFFER_TOO_SMALL); - ReturnErrorCodeIf(!mFactoryData.spake2_verifier.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + VerifyOrReturnError(verifierBuf.size() >= mFactoryData.spake2_verifier.len, CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(mFactoryData.spake2_verifier.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); memcpy(verifierBuf.data(), mFactoryData.spake2_verifier.data, mFactoryData.spake2_verifier.len); @@ -270,7 +270,7 @@ CHIP_ERROR FactoryDataProvider::GetSpake2pVerifier(MutableByte template CHIP_ERROR FactoryDataProvider::GetSetupPasscode(uint32_t & setupPasscode) { - ReturnErrorCodeIf(mFactoryData.passcode == 0, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + VerifyOrReturnError(mFactoryData.passcode != 0, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); setupPasscode = mFactoryData.passcode; return CHIP_NO_ERROR; } @@ -360,8 +360,8 @@ CHIP_ERROR FactoryDataProvider::GetHardwareVersionString(char template CHIP_ERROR FactoryDataProvider::GetRotatingDeviceIdUniqueId(MutableByteSpan & uniqueIdSpan) { - ReturnErrorCodeIf(uniqueIdSpan.size() < mFactoryData.rd_uid.len, CHIP_ERROR_BUFFER_TOO_SMALL); - ReturnErrorCodeIf(!mFactoryData.rd_uid.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + VerifyOrReturnError(uniqueIdSpan.size() >= mFactoryData.rd_uid.len, CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(mFactoryData.rd_uid.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); memcpy(uniqueIdSpan.data(), mFactoryData.rd_uid.data, mFactoryData.rd_uid.len); @@ -373,8 +373,8 @@ CHIP_ERROR FactoryDataProvider::GetRotatingDeviceIdUniqueId(Mu template CHIP_ERROR FactoryDataProvider::GetEnableKey(MutableByteSpan & enableKey) { - ReturnErrorCodeIf(!mFactoryData.enable_key.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); - ReturnErrorCodeIf(enableKey.size() < mFactoryData.enable_key.len, CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(mFactoryData.enable_key.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + VerifyOrReturnError(enableKey.size() >= mFactoryData.enable_key.len, CHIP_ERROR_BUFFER_TOO_SMALL); memcpy(enableKey.data(), mFactoryData.enable_key.data, mFactoryData.enable_key.len); @@ -386,8 +386,8 @@ CHIP_ERROR FactoryDataProvider::GetEnableKey(MutableByteSpan & template CHIP_ERROR FactoryDataProvider::GetProductFinish(app::Clusters::BasicInformation::ProductFinishEnum * finish) { - ReturnErrorCodeIf(!finish, CHIP_ERROR_INVALID_ARGUMENT); - ReturnErrorCodeIf(!mFactoryData.productFinishPresent, CHIP_ERROR_NOT_IMPLEMENTED); + VerifyOrReturnError(finish, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(mFactoryData.productFinishPresent, CHIP_ERROR_NOT_IMPLEMENTED); *finish = static_cast(mFactoryData.product_finish); return CHIP_NO_ERROR; @@ -396,8 +396,8 @@ CHIP_ERROR FactoryDataProvider::GetProductFinish(app::Clusters template CHIP_ERROR FactoryDataProvider::GetProductPrimaryColor(app::Clusters::BasicInformation::ColorEnum * primaryColor) { - ReturnErrorCodeIf(!primaryColor, CHIP_ERROR_INVALID_ARGUMENT); - ReturnErrorCodeIf(!mFactoryData.primaryColorPresent, CHIP_ERROR_NOT_IMPLEMENTED); + VerifyOrReturnError(primaryColor, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(mFactoryData.primaryColorPresent, CHIP_ERROR_NOT_IMPLEMENTED); *primaryColor = static_cast(mFactoryData.primary_color); @@ -407,8 +407,8 @@ CHIP_ERROR FactoryDataProvider::GetProductPrimaryColor(app::Cl template CHIP_ERROR FactoryDataProvider::GetUserData(MutableByteSpan & userData) { - ReturnErrorCodeIf(!mFactoryData.user.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); - ReturnErrorCodeIf(userData.size() < mFactoryData.user.len, CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(mFactoryData.user.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + VerifyOrReturnError(userData.size() >= mFactoryData.user.len, CHIP_ERROR_BUFFER_TOO_SMALL); memcpy(userData.data(), mFactoryData.user.data, mFactoryData.user.len); @@ -420,12 +420,12 @@ CHIP_ERROR FactoryDataProvider::GetUserData(MutableByteSpan & template CHIP_ERROR FactoryDataProvider::GetUserKey(const char * userKey, void * buf, size_t & len) { - ReturnErrorCodeIf(!mFactoryData.user.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); - ReturnErrorCodeIf(!buf, CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(mFactoryData.user.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + VerifyOrReturnError(buf, CHIP_ERROR_BUFFER_TOO_SMALL); bool success = FindUserDataEntry(&mFactoryData, userKey, buf, len, &len); - ReturnErrorCodeIf(!success, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + VerifyOrReturnError(success, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); return CHIP_NO_ERROR; } diff --git a/src/platform/nrfconnect/OTAImageProcessorImpl.cpp b/src/platform/nrfconnect/OTAImageProcessorImpl.cpp index 357a2aeb8a4f99..f0baf084b0ead3 100644 --- a/src/platform/nrfconnect/OTAImageProcessorImpl.cpp +++ b/src/platform/nrfconnect/OTAImageProcessorImpl.cpp @@ -195,10 +195,10 @@ CHIP_ERROR OTAImageProcessorImpl::ProcessBlock(ByteSpan & aBlock) bool OTAImageProcessorImpl::IsFirstImageRun() { OTARequestorInterface * requestor = GetRequestorInstance(); - ReturnErrorCodeIf(requestor == nullptr, false); + VerifyOrReturnError(requestor != nullptr, false); uint32_t currentVersion; - ReturnErrorCodeIf(ConfigurationMgr().GetSoftwareVersion(currentVersion) != CHIP_NO_ERROR, false); + VerifyOrReturnError(ConfigurationMgr().GetSoftwareVersion(currentVersion) == CHIP_NO_ERROR, false); return requestor->GetCurrentUpdateState() == OTARequestorInterface::OTAUpdateStateEnum::kApplying && requestor->GetTargetVersion() == currentVersion; @@ -218,7 +218,7 @@ CHIP_ERROR OTAImageProcessorImpl::ProcessHeader(ByteSpan & aBlock) CHIP_ERROR error = mHeaderParser.AccumulateAndDecode(aBlock, header); // Needs more data to decode the header - ReturnErrorCodeIf(error == CHIP_ERROR_BUFFER_TOO_SMALL, CHIP_NO_ERROR); + VerifyOrReturnError(error != CHIP_ERROR_BUFFER_TOO_SMALL, CHIP_NO_ERROR); ReturnErrorOnFailure(error); mParams.totalFileBytes = header.mPayloadSize; diff --git a/src/platform/nxp/common/ConfigurationManagerImpl.cpp b/src/platform/nxp/common/ConfigurationManagerImpl.cpp index 09fb98abac6a3f..70912a4d6ebaa9 100644 --- a/src/platform/nxp/common/ConfigurationManagerImpl.cpp +++ b/src/platform/nxp/common/ConfigurationManagerImpl.cpp @@ -177,8 +177,8 @@ CHIP_ERROR ConfigurationManagerImpl::GetUniqueId(char * buf, size_t bufSize) ReturnErrorOnFailure(err); - ReturnErrorCodeIf(uniqueIdLen >= bufSize, CHIP_ERROR_BUFFER_TOO_SMALL); - ReturnErrorCodeIf(buf[uniqueIdLen] != 0, CHIP_ERROR_INVALID_STRING_LENGTH); + VerifyOrReturnError(uniqueIdLen < bufSize, CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(buf[uniqueIdLen] == 0, CHIP_ERROR_INVALID_STRING_LENGTH); return err; } diff --git a/src/platform/nxp/common/DnssdImplBr.cpp b/src/platform/nxp/common/DnssdImplBr.cpp index 56ccb6f13ade52..5eab86fe197963 100644 --- a/src/platform/nxp/common/DnssdImplBr.cpp +++ b/src/platform/nxp/common/DnssdImplBr.cpp @@ -224,7 +224,7 @@ CHIP_ERROR NxpChipDnssdRemoveServices() CHIP_ERROR NxpChipDnssdPublishService(const DnssdService * service, DnssdPublishCallback callback, void * context) { - ReturnErrorCodeIf(service == nullptr, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(service != nullptr, CHIP_ERROR_INVALID_ARGUMENT); otInstance * thrInstancePtr = ThreadStackMgrImpl().OTInstance(); uint32_t txtBufferOffset = 0; @@ -634,7 +634,7 @@ CHIP_ERROR FromSrpCacheToMdnsData(const otSrpServerService * service, const otSr entryIndex++; } - ReturnErrorCodeIf(alloc.AnyAllocFailed(), CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(!alloc.AnyAllocFailed(), CHIP_ERROR_BUFFER_TOO_SMALL); mdnsService.mTextEntries = serviceTxtEntries.mTxtEntries; mdnsService.mTextEntrySize = entryIndex; diff --git a/src/platform/nxp/common/NXPConfigNVS.cpp b/src/platform/nxp/common/NXPConfigNVS.cpp index 4cd997b218d473..1aa1320383b662 100644 --- a/src/platform/nxp/common/NXPConfigNVS.cpp +++ b/src/platform/nxp/common/NXPConfigNVS.cpp @@ -160,11 +160,11 @@ CHIP_ERROR NXPConfig::Init() /* Initialize flash components */ const struct flash_area * fa; - ReturnErrorCodeIf(flash_area_open(SETTINGS_PARTITION, &fa), CHIP_ERROR_PERSISTED_STORAGE_FAILED); - ReturnErrorCodeIf(flash_init(fa->fa_dev), CHIP_ERROR_PERSISTED_STORAGE_FAILED); + VerifyOrReturnError(!flash_area_open(SETTINGS_PARTITION, &fa), CHIP_ERROR_PERSISTED_STORAGE_FAILED); + VerifyOrReturnError(!flash_init(fa->fa_dev), CHIP_ERROR_PERSISTED_STORAGE_FAILED); /* End flash init */ - ReturnErrorCodeIf(settings_subsys_init(), CHIP_ERROR_PERSISTED_STORAGE_FAILED); + VerifyOrReturnError(!settings_subsys_init(), CHIP_ERROR_PERSISTED_STORAGE_FAILED); #if (CHIP_DEVICE_CONFIG_KVS_WEAR_STATS == 1) ReturnErrorOnFailure(InitStorageWearStats()); @@ -183,7 +183,7 @@ CHIP_ERROR NXPConfig::InitStorageWearStats(void) /* Create an empty flash wear profile */ flash_wear_profile = (nvs_storage_wear_profile_t *) calloc(1, flash_wear_profile_size); - ReturnErrorCodeIf(flash_wear_profile == NULL, CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(flash_wear_profile != NULL, CHIP_ERROR_NO_MEMORY); /* Try to read the flash wear profile from the User Support diagnostic log key */ CHIP_ERROR err = ReadConfigValueBin((const char *) keyUser, (uint8_t *) flash_wear_profile, flash_wear_profile_size, size); @@ -213,26 +213,26 @@ CHIP_ERROR NXPConfig::InitStorageWearStats(void) CHIP_ERROR NXPConfig::ReadConfigValue(Key key, bool & val) { - ReturnErrorCodeIf(!ValidConfigKey(key), CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id. + VerifyOrReturnError(ValidConfigKey(key), CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id. return ReadSimpleConfigValue(key, val); } CHIP_ERROR NXPConfig::ReadConfigValue(Key key, uint32_t & val) { - ReturnErrorCodeIf(!ValidConfigKey(key), CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id. + VerifyOrReturnError(ValidConfigKey(key), CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id. return ReadSimpleConfigValue(key, val); } CHIP_ERROR NXPConfig::ReadConfigValue(Key key, uint64_t & val) { - ReturnErrorCodeIf(!ValidConfigKey(key), CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id. + VerifyOrReturnError(ValidConfigKey(key), CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id. return ReadSimpleConfigValue(key, val); } CHIP_ERROR NXPConfig::ReadConfigValueStr(Key key, char * buf, size_t bufSize, size_t & outLen) { CHIP_ERROR err = CHIP_NO_ERROR; - ReturnErrorCodeIf(!ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id. + VerifyOrReturnError(ValidConfigKey(key), err = CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id. // Pretend that the buffer is smaller by 1 to secure space for null-character err = ReadConfigValueImpl(key, buf, bufSize ? bufSize - 1 : 0, outLen); @@ -259,7 +259,7 @@ CHIP_ERROR NXPConfig::ReadConfigValueBin(const char * keyString, uint8_t * buf, // to be able to concat CHIP_DEVICE_STRING_SETTINGS_KEY"/" and keyString, + 1 for end char key_name_len = strlen(keyString) + strlen(CHIP_DEVICE_STRING_SETTINGS_KEY) + 1; - ReturnErrorCodeIf(key_name_len > (SETTINGS_MAX_NAME_LEN + 1), CHIP_ERROR_PERSISTED_STORAGE_FAILED); + VerifyOrReturnError(key_name_len <= (SETTINGS_MAX_NAME_LEN + 1), CHIP_ERROR_PERSISTED_STORAGE_FAILED); sprintf(key_name, CHIP_DEVICE_STRING_SETTINGS_KEY "/%s", keyString); settings_load_subtree_direct(key_name, ConfigValueCallback, &request); @@ -295,7 +295,7 @@ CHIP_ERROR NXPConfig::WriteConfigValueStr(Key key, const char * str) CHIP_ERROR NXPConfig::WriteConfigValueStr(Key key, const char * str, size_t strLen) { - ReturnErrorCodeIf(!ValidConfigKey(key), CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id. + VerifyOrReturnError(ValidConfigKey(key), CHIP_DEVICE_ERROR_CONFIG_NOT_FOUND); // Verify key id. return WriteConfigValueImpl(key, str, strLen); } @@ -311,7 +311,7 @@ CHIP_ERROR NXPConfig::WriteConfigValueBin(const char * keyString, const uint8_t // to be able to concat CHIP_DEVICE_STRING_SETTINGS_KEY"/" and keyString, + 1 for end char key_name_len = strlen(keyString) + strlen(CHIP_DEVICE_STRING_SETTINGS_KEY) + 1; - ReturnErrorCodeIf(key_name_len > (SETTINGS_MAX_NAME_LEN + 1), CHIP_ERROR_PERSISTED_STORAGE_FAILED); + VerifyOrReturnError(key_name_len <= (SETTINGS_MAX_NAME_LEN + 1), CHIP_ERROR_PERSISTED_STORAGE_FAILED); sprintf(key_name, CHIP_DEVICE_STRING_SETTINGS_KEY "/%s", keyString); if (settings_save_one(key_name, data, dataLen) != 0) @@ -340,7 +340,7 @@ CHIP_ERROR NXPConfig::ClearConfigValue(const char * keyString) // to be able to concat CHIP_DEVICE_STRING_SETTINGS_KEY"/" and keyString, + 1 for end char key_name_len = strlen(keyString) + strlen(CHIP_DEVICE_STRING_SETTINGS_KEY) + 1; - ReturnErrorCodeIf(key_name_len > (SETTINGS_MAX_NAME_LEN + 1), CHIP_ERROR_PERSISTED_STORAGE_FAILED); + VerifyOrReturnError(key_name_len <= (SETTINGS_MAX_NAME_LEN + 1), CHIP_ERROR_PERSISTED_STORAGE_FAILED); sprintf(key_name, CHIP_DEVICE_STRING_SETTINGS_KEY "/%s", keyString); if (settings_delete(key_name) != 0) diff --git a/src/platform/nxp/common/OTAImageProcessorImpl.cpp b/src/platform/nxp/common/OTAImageProcessorImpl.cpp index a471b57f512105..1d8dfa02e6a1ce 100644 --- a/src/platform/nxp/common/OTAImageProcessorImpl.cpp +++ b/src/platform/nxp/common/OTAImageProcessorImpl.cpp @@ -229,7 +229,7 @@ CHIP_ERROR OTAImageProcessorImpl::ProcessHeader(ByteSpan & block) CHIP_ERROR error = mHeaderParser.AccumulateAndDecode(block, header); /* Needs more data to decode the header */ - ReturnErrorCodeIf(error == CHIP_ERROR_BUFFER_TOO_SMALL, CHIP_NO_ERROR); + VerifyOrReturnError(error != CHIP_ERROR_BUFFER_TOO_SMALL, CHIP_NO_ERROR); ReturnErrorOnFailure(error); mParams.totalFileBytes = header.mPayloadSize; diff --git a/src/platform/nxp/common/ble_zephyr/BLEAdvertisingArbiter.cpp b/src/platform/nxp/common/ble_zephyr/BLEAdvertisingArbiter.cpp index e977708fe4862a..ee6b91da3f9c7e 100644 --- a/src/platform/nxp/common/ble_zephyr/BLEAdvertisingArbiter.cpp +++ b/src/platform/nxp/common/ble_zephyr/BLEAdvertisingArbiter.cpp @@ -53,7 +53,7 @@ CHIP_ERROR RestartAdvertising() { // Note: bt_le_adv_stop() returns success when the advertising was not started ReturnErrorOnFailure(MapErrorZephyr(bt_le_adv_stop())); - ReturnErrorCodeIf(sys_slist_is_empty(&sRequests), CHIP_NO_ERROR); + VerifyOrReturnError(!sys_slist_is_empty(&sRequests), CHIP_NO_ERROR); const Request & top = ToRequest(sys_slist_peek_head(&sRequests)); const bt_le_adv_param params = BT_LE_ADV_PARAM_INIT(top.options, top.minInterval, top.maxInterval, nullptr); diff --git a/src/platform/nxp/common/crypto/CHIPCryptoPALTinyCrypt.cpp b/src/platform/nxp/common/crypto/CHIPCryptoPALTinyCrypt.cpp index b0ed35595fa602..9c6334bded2da6 100644 --- a/src/platform/nxp/common/crypto/CHIPCryptoPALTinyCrypt.cpp +++ b/src/platform/nxp/common/crypto/CHIPCryptoPALTinyCrypt.cpp @@ -1965,7 +1965,7 @@ CHIP_ERROR ExtractRawDNFromX509Cert(bool extractSubject, const ByteSpan & certif size_t len = 0; mbedtls_x509_crt mbedCertificate; - ReturnErrorCodeIf(certificate.empty(), CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(!certificate.empty(), CHIP_ERROR_INVALID_ARGUMENT); mbedtls_x509_crt_init(&mbedCertificate); result = mbedtls_x509_crt_parse(&mbedCertificate, Uint8::to_const_uchar(certificate.data()), certificate.size()); @@ -2021,7 +2021,7 @@ CHIP_ERROR ReplaceCertIfResignedCertFound(const ByteSpan & referenceCertificate, outCertificate = referenceCertificate; - ReturnErrorCodeIf(candidateCertificates == nullptr || candidateCertificatesCount == 0, CHIP_NO_ERROR); + VerifyOrReturnError(candidateCertificates != nullptr && candidateCertificatesCount != 0, CHIP_NO_ERROR); ReturnErrorOnFailure(ExtractSubjectFromX509Cert(referenceCertificate, referenceSubject)); ReturnErrorOnFailure(ExtractSKIDFromX509Cert(referenceCertificate, referenceSKID)); diff --git a/src/platform/nxp/common/factory_data/FactoryDataProvider.cpp b/src/platform/nxp/common/factory_data/FactoryDataProvider.cpp index b60d7e49c0ad81..43c78a02428a08 100644 --- a/src/platform/nxp/common/factory_data/FactoryDataProvider.cpp +++ b/src/platform/nxp/common/factory_data/FactoryDataProvider.cpp @@ -125,7 +125,7 @@ CHIP_ERROR FactoryDataProvider::GetSpake2pSalt(MutableByteSpan & saltBuf) size_t saltLen = chip::Base64Decode32((char *) saltB64, saltB64Len, reinterpret_cast(saltB64)); - ReturnErrorCodeIf(saltLen > saltBuf.size(), CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(saltLen <= saltBuf.size(), CHIP_ERROR_BUFFER_TOO_SMALL); memcpy(saltBuf.data(), saltB64, saltLen); saltBuf.reduce_size(saltLen); @@ -142,7 +142,7 @@ CHIP_ERROR FactoryDataProvider::GetSpake2pVerifier(MutableByteSpan & verifierBuf ReturnErrorOnFailure(SearchForId(FactoryDataId::kVerifierId, &verifierB64[0], sizeof(verifierB64), verifierB64Len)); verifierLen = chip::Base64Decode32((char *) verifierB64, verifierB64Len, reinterpret_cast(verifierB64)); - ReturnErrorCodeIf(verifierLen > verifierBuf.size(), CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(verifierLen <= verifierBuf.size(), CHIP_ERROR_BUFFER_TOO_SMALL); memcpy(verifierBuf.data(), verifierB64, verifierLen); verifierBuf.reduce_size(verifierLen); @@ -288,7 +288,7 @@ CHIP_ERROR FactoryDataProvider::GetRotatingDeviceIdUniqueId(MutableByteSpan & un { constexpr uint8_t uniqueId[] = CHIP_DEVICE_CONFIG_ROTATING_DEVICE_ID_UNIQUE_ID; - ReturnErrorCodeIf(sizeof(uniqueId) > uniqueIdSpan.size(), CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(sizeof(uniqueId) <= uniqueIdSpan.size(), CHIP_ERROR_BUFFER_TOO_SMALL); memcpy(uniqueIdSpan.data(), uniqueId, sizeof(uniqueId)); uniqueIdLen = sizeof(uniqueId); err = CHIP_NO_ERROR; @@ -306,7 +306,7 @@ CHIP_ERROR FactoryDataProvider::GetProductFinish(app::Clusters::BasicInformation uint8_t productFinish; uint16_t length = 0; auto err = SearchForId(FactoryDataId::kProductFinish, &productFinish, sizeof(productFinish), length); - ReturnErrorCodeIf(err != CHIP_NO_ERROR, CHIP_ERROR_NOT_IMPLEMENTED); + VerifyOrReturnError(err == CHIP_NO_ERROR, CHIP_ERROR_NOT_IMPLEMENTED); *finish = static_cast(productFinish); @@ -318,7 +318,7 @@ CHIP_ERROR FactoryDataProvider::GetProductPrimaryColor(app::Clusters::BasicInfor uint8_t color; uint16_t length = 0; auto err = SearchForId(FactoryDataId::kProductPrimaryColor, &color, sizeof(color), length); - ReturnErrorCodeIf(err != CHIP_NO_ERROR, CHIP_ERROR_NOT_IMPLEMENTED); + VerifyOrReturnError(err == CHIP_NO_ERROR, CHIP_ERROR_NOT_IMPLEMENTED); *primaryColor = static_cast(color); diff --git a/src/platform/nxp/common/factory_data/legacy/FactoryDataDriverImpl.cpp b/src/platform/nxp/common/factory_data/legacy/FactoryDataDriverImpl.cpp index 18ea65cdf18e26..cb7f7c110924e6 100644 --- a/src/platform/nxp/common/factory_data/legacy/FactoryDataDriverImpl.cpp +++ b/src/platform/nxp/common/factory_data/legacy/FactoryDataDriverImpl.cpp @@ -70,7 +70,7 @@ CHIP_ERROR FactoryDataDriverImpl::InitRamBackup(void) VerifyOrReturnError(mFactoryDataRamBuff == nullptr, CHIP_ERROR_INTERNAL); mFactoryDataRamBuff = static_cast(chip::Platform::MemoryAlloc(mMaxSize)); - ReturnErrorCodeIf(mFactoryDataRamBuff == nullptr, CHIP_ERROR_INTERNAL); + VerifyOrReturnError(mFactoryDataRamBuff != nullptr, CHIP_ERROR_INTERNAL); memset(mFactoryDataRamBuff, 0, mMaxSize); memcpy(mFactoryDataRamBuff, (void *) &mFactoryData->app_factory_data[0], mSize); @@ -97,7 +97,7 @@ CHIP_ERROR FactoryDataDriverImpl::ReadBackupInRam() if (mFactoryDataRamBuff == nullptr) { mFactoryDataRamBuff = static_cast(chip::Platform::MemoryAlloc(mMaxSize)); - ReturnErrorCodeIf(mFactoryDataRamBuff == nullptr, CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(mFactoryDataRamBuff != nullptr, CHIP_ERROR_NO_MEMORY); memset(mFactoryDataRamBuff, 0, mMaxSize); } @@ -111,7 +111,7 @@ CHIP_ERROR FactoryDataDriverImpl::ReadBackupInRam() CHIP_ERROR FactoryDataDriverImpl::BackupFactoryData() { CHIP_ERROR error = CHIP_NO_ERROR; - ReturnErrorCodeIf(mFactoryData == nullptr, CHIP_ERROR_INTERNAL); + VerifyOrReturnError(mFactoryData != nullptr, CHIP_ERROR_INTERNAL); error = KeyValueStoreMgr().Put(FactoryDataDriverImpl::GetFactoryBackupKey().KeyName(), &mFactoryData->app_factory_data[0], mMaxSize); diff --git a/src/platform/nxp/common/factory_data/legacy/FactoryDataProvider.cpp b/src/platform/nxp/common/factory_data/legacy/FactoryDataProvider.cpp index 38998ed3c5bde6..d7cac2e8f12835 100644 --- a/src/platform/nxp/common/factory_data/legacy/FactoryDataProvider.cpp +++ b/src/platform/nxp/common/factory_data/legacy/FactoryDataProvider.cpp @@ -129,10 +129,10 @@ CHIP_ERROR FactoryDataProvider::Validate() uint8_t output[Crypto::kSHA256_Hash_Length] = { 0 }; memcpy(&mHeader, (void *) mConfig.start, sizeof(Header)); - ReturnErrorCodeIf(mHeader.hashId != kHashId, CHIP_FACTORY_DATA_HASH_ID); + VerifyOrReturnError(mHeader.hashId == kHashId, CHIP_FACTORY_DATA_HASH_ID); ReturnErrorOnFailure(Crypto::Hash_SHA256((uint8_t *) mConfig.payload, mHeader.size, output)); - ReturnErrorCodeIf(memcmp(output, mHeader.hash, kHashLen) != 0, CHIP_FACTORY_DATA_SHA_CHECK); + VerifyOrReturnError(memcmp(output, mHeader.hash, kHashLen) == 0, CHIP_FACTORY_DATA_SHA_CHECK); return CHIP_NO_ERROR; } @@ -150,7 +150,7 @@ CHIP_ERROR FactoryDataProvider::SearchForId(uint8_t searchedType, uint8_t * pBuf if (searchedType == type) { - ReturnErrorCodeIf(bufLength < length, CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(bufLength >= length, CHIP_ERROR_BUFFER_TOO_SMALL); memcpy(pBuf, (void *) (addr + kValueOffset), length); if (offset) @@ -241,7 +241,7 @@ CHIP_ERROR FactoryDataProvider::GetSpake2pSalt(MutableByteSpan & saltBuf) ReturnErrorOnFailure(SearchForId(FactoryDataId::kSaltId, (uint8_t *) (&saltB64[0]), sizeof(saltB64), saltB64Len)); size_t saltLen = chip::Base64Decode32(saltB64, saltB64Len, reinterpret_cast(saltB64)); - ReturnErrorCodeIf(saltLen > saltBuf.size(), CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(saltLen <= saltBuf.size(), CHIP_ERROR_BUFFER_TOO_SMALL); memcpy(saltBuf.data(), saltB64, saltLen); saltBuf.reduce_size(saltLen); @@ -255,7 +255,7 @@ CHIP_ERROR FactoryDataProvider::GetSpake2pVerifier(MutableByteSpan & verifierBuf ReturnErrorOnFailure(SearchForId(FactoryDataId::kVerifierId, (uint8_t *) &verifierB64[0], sizeof(verifierB64), verifierB64Len)); verifierLen = chip::Base64Decode32(verifierB64, verifierB64Len, reinterpret_cast(verifierB64)); - ReturnErrorCodeIf(verifierLen > verifierBuf.size(), CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(verifierLen <= verifierBuf.size(), CHIP_ERROR_BUFFER_TOO_SMALL); memcpy(verifierBuf.data(), verifierB64, verifierLen); verifierBuf.reduce_size(verifierLen); @@ -401,7 +401,7 @@ CHIP_ERROR FactoryDataProvider::GetRotatingDeviceIdUniqueId(MutableByteSpan & un { constexpr uint8_t uniqueId[] = CHIP_DEVICE_CONFIG_ROTATING_DEVICE_ID_UNIQUE_ID; - ReturnErrorCodeIf(sizeof(uniqueId) > uniqueIdSpan.size(), CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(sizeof(uniqueId) <= uniqueIdSpan.size(), CHIP_ERROR_BUFFER_TOO_SMALL); memcpy(uniqueIdSpan.data(), uniqueId, sizeof(uniqueId)); uniqueIdLen = sizeof(uniqueId); err = CHIP_NO_ERROR; @@ -419,7 +419,7 @@ CHIP_ERROR FactoryDataProvider::GetProductFinish(app::Clusters::BasicInformation uint8_t productFinish; uint16_t length = 0; auto err = SearchForId(FactoryDataId::kProductFinish, &productFinish, sizeof(productFinish), length); - ReturnErrorCodeIf(err != CHIP_NO_ERROR, CHIP_ERROR_NOT_IMPLEMENTED); + VerifyOrReturnError(err == CHIP_NO_ERROR, CHIP_ERROR_NOT_IMPLEMENTED); *finish = static_cast(productFinish); @@ -431,7 +431,7 @@ CHIP_ERROR FactoryDataProvider::GetProductPrimaryColor(app::Clusters::BasicInfor uint8_t color; uint16_t length = 0; auto err = SearchForId(FactoryDataId::kProductPrimaryColor, &color, sizeof(color), length); - ReturnErrorCodeIf(err != CHIP_NO_ERROR, CHIP_ERROR_NOT_IMPLEMENTED); + VerifyOrReturnError(err == CHIP_NO_ERROR, CHIP_ERROR_NOT_IMPLEMENTED); *primaryColor = static_cast(color); diff --git a/src/platform/nxp/common/factory_data/legacy/FactoryDataProviderImpl.cpp b/src/platform/nxp/common/factory_data/legacy/FactoryDataProviderImpl.cpp index abb189685bdc7f..1ee2340602a6cc 100644 --- a/src/platform/nxp/common/factory_data/legacy/FactoryDataProviderImpl.cpp +++ b/src/platform/nxp/common/factory_data/legacy/FactoryDataProviderImpl.cpp @@ -273,7 +273,7 @@ extern "C" WEAK CHIP_ERROR FactoryDataDefaultRestoreMechanism() CHIP_ERROR error = CHIP_NO_ERROR; FactoryDataDriver * driver = &FactoryDataDrv(); - ReturnErrorCodeIf(driver == nullptr, CHIP_ERROR_INTERNAL); + VerifyOrReturnError(driver != nullptr, CHIP_ERROR_INTERNAL); // Check if key related to factory data backup exists. // If it does, it means an external event (such as a power loss) diff --git a/src/platform/nxp/common/ota/OTAFirmwareProcessor.cpp b/src/platform/nxp/common/ota/OTAFirmwareProcessor.cpp index 15aa5f271c3ccc..a9015d8e1822d8 100644 --- a/src/platform/nxp/common/ota/OTAFirmwareProcessor.cpp +++ b/src/platform/nxp/common/ota/OTAFirmwareProcessor.cpp @@ -26,16 +26,16 @@ namespace chip { CHIP_ERROR OTAFirmwareProcessor::Init() { - ReturnErrorCodeIf(mCallbackProcessDescriptor == nullptr, CHIP_ERROR_OTA_PROCESSOR_CB_NOT_REGISTERED); + VerifyOrReturnError(mCallbackProcessDescriptor != nullptr, CHIP_ERROR_OTA_PROCESSOR_CB_NOT_REGISTERED); mAccumulator.Init(sizeof(Descriptor)); - ReturnErrorCodeIf(gOtaSuccess_c != OTA_SelectExternalStoragePartition(), CHIP_ERROR_OTA_PROCESSOR_EXTERNAL_STORAGE); + VerifyOrReturnError(gOtaSuccess_c == OTA_SelectExternalStoragePartition(), CHIP_ERROR_OTA_PROCESSOR_EXTERNAL_STORAGE); otaResult_t ota_status; ota_status = OTA_ServiceInit(&mPostedOperationsStorage[0], NB_PENDING_TRANSACTIONS * TRANSACTION_SZ); - ReturnErrorCodeIf(ota_status != gOtaSuccess_c, CHIP_ERROR_OTA_PROCESSOR_CLIENT_INIT); - ReturnErrorCodeIf(gOtaSuccess_c != OTA_StartImage(mLength - sizeof(Descriptor)), CHIP_ERROR_OTA_PROCESSOR_START_IMAGE); + VerifyOrReturnError(ota_status == gOtaSuccess_c, CHIP_ERROR_OTA_PROCESSOR_CLIENT_INIT); + VerifyOrReturnError(gOtaSuccess_c == OTA_StartImage(mLength - sizeof(Descriptor)), CHIP_ERROR_OTA_PROCESSOR_START_IMAGE); return CHIP_NO_ERROR; } diff --git a/src/platform/nxp/common/ota/OTAImageProcessorImpl.cpp b/src/platform/nxp/common/ota/OTAImageProcessorImpl.cpp index f6f42367329e54..59af9449b9af76 100644 --- a/src/platform/nxp/common/ota/OTAImageProcessorImpl.cpp +++ b/src/platform/nxp/common/ota/OTAImageProcessorImpl.cpp @@ -39,7 +39,7 @@ namespace chip { CHIP_ERROR OTAImageProcessorImpl::Init(OTADownloader * downloader) { - ReturnErrorCodeIf(downloader == nullptr, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(downloader != nullptr, CHIP_ERROR_INVALID_ARGUMENT); mDownloader = downloader; OtaHookInit(); @@ -297,7 +297,7 @@ CHIP_ERROR OTAImageProcessorImpl::ConfirmCurrentImage() uint32_t targetVersion; OTARequestorInterface * requestor = chip::GetRequestorInstance(); - ReturnErrorCodeIf(requestor == nullptr, CHIP_ERROR_INTERNAL); + VerifyOrReturnError(requestor != nullptr, CHIP_ERROR_INTERNAL); targetVersion = requestor->GetTargetVersion(); ReturnErrorOnFailure(DeviceLayer::ConfigurationMgr().GetSoftwareVersion(currentVersion)); diff --git a/src/platform/nxp/k32w0/ConfigurationManagerImpl.cpp b/src/platform/nxp/k32w0/ConfigurationManagerImpl.cpp index 7343c75b5d5865..4e24fa71996290 100644 --- a/src/platform/nxp/k32w0/ConfigurationManagerImpl.cpp +++ b/src/platform/nxp/k32w0/ConfigurationManagerImpl.cpp @@ -121,8 +121,8 @@ CHIP_ERROR ConfigurationManagerImpl::GetUniqueId(char * buf, size_t bufSize) ReturnErrorOnFailure(err); - ReturnErrorCodeIf(uniqueIdLen >= bufSize, CHIP_ERROR_BUFFER_TOO_SMALL); - ReturnErrorCodeIf(buf[uniqueIdLen] != 0, CHIP_ERROR_INVALID_STRING_LENGTH); + VerifyOrReturnError(uniqueIdLen < bufSize, CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(buf[uniqueIdLen] == 0, CHIP_ERROR_INVALID_STRING_LENGTH); return err; } diff --git a/src/platform/nxp/k32w0/FactoryDataProvider.cpp b/src/platform/nxp/k32w0/FactoryDataProvider.cpp index 23f8ffe7c0586b..28d8c9f3889b76 100644 --- a/src/platform/nxp/k32w0/FactoryDataProvider.cpp +++ b/src/platform/nxp/k32w0/FactoryDataProvider.cpp @@ -55,10 +55,10 @@ CHIP_ERROR FactoryDataProvider::Validate() uint8_t output[Crypto::kSHA256_Hash_Length] = { 0 }; memcpy(&mHeader, (void *) kFactoryDataStart, sizeof(Header)); - ReturnErrorCodeIf(mHeader.hashId != kHashId, CHIP_FACTORY_DATA_HASH_ID); + VerifyOrReturnError(mHeader.hashId == kHashId, CHIP_FACTORY_DATA_HASH_ID); ReturnErrorOnFailure(Crypto::Hash_SHA256((uint8_t *) kFactoryDataPayloadStart, mHeader.size, output)); - ReturnErrorCodeIf(memcmp(output, mHeader.hash, kHashLen) != 0, CHIP_FACTORY_DATA_SHA_CHECK); + VerifyOrReturnError(memcmp(output, mHeader.hash, kHashLen) == 0, CHIP_FACTORY_DATA_SHA_CHECK); return CHIP_NO_ERROR; } @@ -76,7 +76,7 @@ CHIP_ERROR FactoryDataProvider::SearchForId(uint8_t searchedType, uint8_t * pBuf if (searchedType == type) { - ReturnErrorCodeIf(bufLength < length, CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(bufLength >= length, CHIP_ERROR_BUFFER_TOO_SMALL); memcpy(pBuf, (void *) (addr + kValueOffset), length); if (offset) @@ -167,7 +167,7 @@ CHIP_ERROR FactoryDataProvider::GetSpake2pSalt(MutableByteSpan & saltBuf) ReturnErrorOnFailure(SearchForId(FactoryDataId::kSaltId, (uint8_t *) (&saltB64[0]), sizeof(saltB64), saltB64Len)); size_t saltLen = chip::Base64Decode32(saltB64, saltB64Len, reinterpret_cast(saltB64)); - ReturnErrorCodeIf(saltLen > saltBuf.size(), CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(saltLen <= saltBuf.size(), CHIP_ERROR_BUFFER_TOO_SMALL); memcpy(saltBuf.data(), saltB64, saltLen); saltBuf.reduce_size(saltLen); @@ -181,7 +181,7 @@ CHIP_ERROR FactoryDataProvider::GetSpake2pVerifier(MutableByteSpan & verifierBuf ReturnErrorOnFailure(SearchForId(FactoryDataId::kVerifierId, (uint8_t *) &verifierB64[0], sizeof(verifierB64), verifierB64Len)); verifierLen = chip::Base64Decode32(verifierB64, verifierB64Len, reinterpret_cast(verifierB64)); - ReturnErrorCodeIf(verifierLen > verifierBuf.size(), CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(verifierLen <= verifierBuf.size(), CHIP_ERROR_BUFFER_TOO_SMALL); memcpy(verifierBuf.data(), verifierB64, verifierLen); verifierBuf.reduce_size(verifierLen); @@ -327,7 +327,7 @@ CHIP_ERROR FactoryDataProvider::GetRotatingDeviceIdUniqueId(MutableByteSpan & un { constexpr uint8_t uniqueId[] = CHIP_DEVICE_CONFIG_ROTATING_DEVICE_ID_UNIQUE_ID; - ReturnErrorCodeIf(sizeof(uniqueId) > uniqueIdSpan.size(), CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(sizeof(uniqueId) <= uniqueIdSpan.size(), CHIP_ERROR_BUFFER_TOO_SMALL); memcpy(uniqueIdSpan.data(), uniqueId, sizeof(uniqueId)); uniqueIdLen = sizeof(uniqueId); err = CHIP_NO_ERROR; @@ -345,7 +345,7 @@ CHIP_ERROR FactoryDataProvider::GetProductFinish(app::Clusters::BasicInformation uint8_t productFinish; uint16_t length = 0; auto err = SearchForId(FactoryDataId::kProductFinish, &productFinish, sizeof(productFinish), length); - ReturnErrorCodeIf(err != CHIP_NO_ERROR, CHIP_ERROR_NOT_IMPLEMENTED); + VerifyOrReturnError(err == CHIP_NO_ERROR, CHIP_ERROR_NOT_IMPLEMENTED); *finish = static_cast(productFinish); @@ -357,7 +357,7 @@ CHIP_ERROR FactoryDataProvider::GetProductPrimaryColor(app::Clusters::BasicInfor uint8_t color; uint16_t length = 0; auto err = SearchForId(FactoryDataId::kProductPrimaryColor, &color, sizeof(color), length); - ReturnErrorCodeIf(err != CHIP_NO_ERROR, CHIP_ERROR_NOT_IMPLEMENTED); + VerifyOrReturnError(err == CHIP_NO_ERROR, CHIP_ERROR_NOT_IMPLEMENTED); *primaryColor = static_cast(color); diff --git a/src/platform/nxp/k32w0/FactoryDataProviderImpl.cpp b/src/platform/nxp/k32w0/FactoryDataProviderImpl.cpp index 93c09adf5c749d..e2d5f1db8b9606 100644 --- a/src/platform/nxp/k32w0/FactoryDataProviderImpl.cpp +++ b/src/platform/nxp/k32w0/FactoryDataProviderImpl.cpp @@ -105,11 +105,11 @@ extern "C" WEAK CHIP_ERROR FactoryDataDefaultRestoreMechanism() { chip::Platform::ScopedMemoryBuffer buffer; buffer.Calloc(FactoryDataProvider::kFactoryDataSize); - ReturnErrorCodeIf(buffer.Get() == nullptr, CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(buffer.Get() != nullptr, CHIP_ERROR_NO_MEMORY); auto status = PDM_eReadDataFromRecord(kNvmId_FactoryDataBackup, (void *) buffer.Get(), FactoryDataProvider::kFactoryDataSize, &backupLength); - ReturnErrorCodeIf(PDM_E_STATUS_OK != status, CHIP_FACTORY_DATA_PDM_RESTORE); + VerifyOrReturnError(PDM_E_STATUS_OK == status, CHIP_FACTORY_DATA_PDM_RESTORE); error = FactoryDataProviderImpl::UpdateData(buffer.Get()); if (error == CHIP_NO_ERROR) @@ -157,11 +157,11 @@ CHIP_ERROR FactoryDataProviderImpl::UpdateData(uint8_t * pBuf) NV_Init(); auto status = NV_FlashEraseSector(kFactoryDataStart, kFactoryDataSize); - ReturnErrorCodeIf(status != kStatus_FLASH_Success, CHIP_FACTORY_DATA_FLASH_ERASE); + VerifyOrReturnError(status == kStatus_FLASH_Success, CHIP_FACTORY_DATA_FLASH_ERASE); Header * header = (Header *) pBuf; status = NV_FlashProgramUnaligned(kFactoryDataStart, sizeof(Header) + header->size, pBuf); - ReturnErrorCodeIf(status != kStatus_FLASH_Success, CHIP_FACTORY_DATA_FLASH_PROGRAM); + VerifyOrReturnError(status == kStatus_FLASH_Success, CHIP_FACTORY_DATA_FLASH_PROGRAM); return CHIP_NO_ERROR; } diff --git a/src/platform/nxp/k32w0/KeyValueStoreManagerImpl.cpp b/src/platform/nxp/k32w0/KeyValueStoreManagerImpl.cpp index 50f900583769f7..34666e491ab43e 100644 --- a/src/platform/nxp/k32w0/KeyValueStoreManagerImpl.cpp +++ b/src/platform/nxp/k32w0/KeyValueStoreManagerImpl.cpp @@ -326,7 +326,7 @@ static CHIP_ERROR MoveKeysAndValues() Platform::ScopedMemoryBuffer buffer; buffer.Calloc(len); - ReturnErrorCodeIf(buffer.Get() == nullptr, CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(buffer.Get() != nullptr, CHIP_ERROR_NO_MEMORY); for (uint8_t id = 0; id < kMaxNumberOfKeys; id++) { diff --git a/src/platform/nxp/k32w0/OTAFactoryDataProcessor.cpp b/src/platform/nxp/k32w0/OTAFactoryDataProcessor.cpp index 9114906787a7b6..b3ffdd156313e4 100644 --- a/src/platform/nxp/k32w0/OTAFactoryDataProcessor.cpp +++ b/src/platform/nxp/k32w0/OTAFactoryDataProcessor.cpp @@ -174,7 +174,7 @@ CHIP_ERROR OTAFactoryDataProcessor::Read() memcpy(&header, (void *) FactoryProvider::kFactoryDataStart, sizeof(FactoryProvider::Header)); mFactoryData = static_cast(chip::Platform::MemoryAlloc(FactoryProvider::kFactoryDataSize)); - ReturnErrorCodeIf(mFactoryData == nullptr, CHIP_FACTORY_DATA_NULL); + VerifyOrReturnError(mFactoryData != nullptr, CHIP_FACTORY_DATA_NULL); memset(mFactoryData, 0, FactoryProvider::kFactoryDataSize); memcpy(mFactoryData, (void *) FactoryProvider::kFactoryDataStart, sizeof(FactoryProvider::Header) + header.size); @@ -183,10 +183,10 @@ CHIP_ERROR OTAFactoryDataProcessor::Read() CHIP_ERROR OTAFactoryDataProcessor::Backup() { - ReturnErrorCodeIf(mFactoryData == nullptr, CHIP_FACTORY_DATA_NULL); + VerifyOrReturnError(mFactoryData != nullptr, CHIP_FACTORY_DATA_NULL); auto status = PDM_eSaveRecordData(kNvmId_FactoryDataBackup, (void *) mFactoryData, FactoryProvider::kFactoryDataSize); - ReturnErrorCodeIf(status != PDM_E_STATUS_OK, CHIP_FACTORY_DATA_PDM_SAVE_RECORD); + VerifyOrReturnError(status == PDM_E_STATUS_OK, CHIP_FACTORY_DATA_PDM_SAVE_RECORD); // PDM save will do an encryption in place, so a restore is neeeded in order // to have the decrypted data back in the mFactoryData buffer. ReturnErrorOnFailure(Restore()); @@ -196,13 +196,13 @@ CHIP_ERROR OTAFactoryDataProcessor::Backup() CHIP_ERROR OTAFactoryDataProcessor::Restore() { - ReturnErrorCodeIf(mFactoryData == nullptr, CHIP_FACTORY_DATA_NULL); + VerifyOrReturnError(mFactoryData != nullptr, CHIP_FACTORY_DATA_NULL); uint16_t bytesRead = 0; auto status = PDM_eReadDataFromRecord(kNvmId_FactoryDataBackup, (void *) mFactoryData, FactoryProvider::kFactoryDataSize, &bytesRead); - ReturnErrorCodeIf(status != PDM_E_STATUS_OK, CHIP_FACTORY_DATA_PDM_READ_RECORD); + VerifyOrReturnError(status == PDM_E_STATUS_OK, CHIP_FACTORY_DATA_PDM_READ_RECORD); return CHIP_NO_ERROR; } diff --git a/src/platform/nxp/k32w0/OTAFirmwareProcessor.cpp b/src/platform/nxp/k32w0/OTAFirmwareProcessor.cpp index 3fcb2fd43bf1d9..1ea200313178b6 100644 --- a/src/platform/nxp/k32w0/OTAFirmwareProcessor.cpp +++ b/src/platform/nxp/k32w0/OTAFirmwareProcessor.cpp @@ -28,12 +28,12 @@ namespace chip { CHIP_ERROR OTAFirmwareProcessor::Init() { - ReturnErrorCodeIf(mCallbackProcessDescriptor == nullptr, CHIP_ERROR_OTA_PROCESSOR_CB_NOT_REGISTERED); + VerifyOrReturnError(mCallbackProcessDescriptor != nullptr, CHIP_ERROR_OTA_PROCESSOR_CB_NOT_REGISTERED); mAccumulator.Init(sizeof(Descriptor)); #if OTA_ENCRYPTION_ENABLE mUnalignmentNum = 0; #endif - ReturnErrorCodeIf(gOtaSuccess_c != OTA_ClientInit(), CHIP_ERROR_OTA_PROCESSOR_CLIENT_INIT); + VerifyOrReturnError(gOtaSuccess_c == OTA_ClientInit(), CHIP_ERROR_OTA_PROCESSOR_CLIENT_INIT); auto offset = OTA_GetCurrentEepromAddressOffset(); if (offset != 0) @@ -41,8 +41,8 @@ CHIP_ERROR OTAFirmwareProcessor::Init() offset += 1; } - ReturnErrorCodeIf(OTA_UTILS_IMAGE_INVALID_ADDR == OTA_SetStartEepromOffset(offset), CHIP_ERROR_OTA_PROCESSOR_EEPROM_OFFSET); - ReturnErrorCodeIf(gOtaSuccess_c != OTA_StartImage(mLength - sizeof(Descriptor)), CHIP_ERROR_OTA_PROCESSOR_START_IMAGE); + VerifyOrReturnError(OTA_UTILS_IMAGE_INVALID_ADDR != OTA_SetStartEepromOffset(offset), CHIP_ERROR_OTA_PROCESSOR_EEPROM_OFFSET); + VerifyOrReturnError(gOtaSuccess_c == OTA_StartImage(mLength - sizeof(Descriptor)), CHIP_ERROR_OTA_PROCESSOR_START_IMAGE); return CHIP_NO_ERROR; } diff --git a/src/platform/nxp/mw320/FactoryDataProvider.cpp b/src/platform/nxp/mw320/FactoryDataProvider.cpp index 5b36958f306d5b..5d02bcf9e48ee0 100644 --- a/src/platform/nxp/mw320/FactoryDataProvider.cpp +++ b/src/platform/nxp/mw320/FactoryDataProvider.cpp @@ -234,7 +234,7 @@ CHIP_ERROR FactoryDataProvider::GetSpake2pSalt(MutableByteSpan & saltBuf) ReturnErrorOnFailure(SearchForId(kSaltId, (uint8_t *) (&saltB64[0]), sizeof(saltB64), saltB64Len)); size_t saltLen = chip::Base64Decode32(saltB64, saltB64Len, reinterpret_cast(saltB64)); - ReturnErrorCodeIf(saltLen > saltBuf.size(), CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(saltLen <= saltBuf.size(), CHIP_ERROR_BUFFER_TOO_SMALL); memcpy(saltBuf.data(), saltB64, saltLen); saltBuf.reduce_size(saltLen); @@ -249,7 +249,7 @@ CHIP_ERROR FactoryDataProvider::GetSpake2pVerifier(MutableByteSpan & verifierBuf ReturnErrorOnFailure(SearchForId(kVerifierId, (uint8_t *) &verifierB64[0], sizeof(verifierB64), verifierB64Len)); verifierLen = chip::Base64Decode32(verifierB64, verifierB64Len, reinterpret_cast(verifierB64)); - ReturnErrorCodeIf(verifierLen > verifierBuf.size(), CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(verifierLen <= verifierBuf.size(), CHIP_ERROR_BUFFER_TOO_SMALL); memcpy(verifierBuf.data(), verifierB64, verifierLen); verifierBuf.reduce_size(verifierLen); diff --git a/src/platform/nxp/mw320/OTAImageProcessorImpl.cpp b/src/platform/nxp/mw320/OTAImageProcessorImpl.cpp index 1fac68beb2e360..18dc019ba33bc0 100644 --- a/src/platform/nxp/mw320/OTAImageProcessorImpl.cpp +++ b/src/platform/nxp/mw320/OTAImageProcessorImpl.cpp @@ -280,7 +280,7 @@ CHIP_ERROR OTAImageProcessorImpl::ProcessHeader(ByteSpan & block) CHIP_ERROR error = mHeaderParser.AccumulateAndDecode(block, header); // Needs more data to decode the header - ReturnErrorCodeIf(error == CHIP_ERROR_BUFFER_TOO_SMALL, CHIP_NO_ERROR); + VerifyOrReturnError(error != CHIP_ERROR_BUFFER_TOO_SMALL, CHIP_NO_ERROR); ReturnErrorOnFailure(error); // mParams.totalFileBytes = header.mPayloadSize; diff --git a/src/platform/nxp/zephyr/DeviceInstanceInfoProviderImpl.cpp b/src/platform/nxp/zephyr/DeviceInstanceInfoProviderImpl.cpp index 92029ebd617386..52d0fc65ad19f8 100644 --- a/src/platform/nxp/zephyr/DeviceInstanceInfoProviderImpl.cpp +++ b/src/platform/nxp/zephyr/DeviceInstanceInfoProviderImpl.cpp @@ -28,13 +28,13 @@ CHIP_ERROR DeviceInstanceInfoProviderImpl::GetRotatingDeviceIdUniqueId(MutableBy static_assert(ConfigurationManager::kRotatingDeviceIDUniqueIDLength >= ConfigurationManager::kMinRotatingDeviceIDUniqueIDLength, "Length of unique ID for rotating device ID is smaller than minimum."); - ReturnErrorCodeIf(ConfigurationManager::kRotatingDeviceIDUniqueIDLength > uniqueIdSpan.size(), CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(ConfigurationManager::kRotatingDeviceIDUniqueIDLength <= uniqueIdSpan.size(), CHIP_ERROR_BUFFER_TOO_SMALL); size_t bytesLen = chip::Encoding::HexToBytes(CONFIG_CHIP_DEVICE_ROTATING_DEVICE_UID, ConfigurationManager::kRotatingDeviceIDUniqueIDLength * 2, uniqueIdSpan.data(), uniqueIdSpan.size()); - ReturnErrorCodeIf(bytesLen != ConfigurationManager::kRotatingDeviceIDUniqueIDLength, CHIP_ERROR_INVALID_STRING_LENGTH); + VerifyOrReturnError(bytesLen == ConfigurationManager::kRotatingDeviceIDUniqueIDLength, CHIP_ERROR_INVALID_STRING_LENGTH); uniqueIdSpan.reduce_size(bytesLen); return CHIP_NO_ERROR; diff --git a/src/platform/nxp/zephyr/DiagnosticDataProviderImplNxp.cpp b/src/platform/nxp/zephyr/DiagnosticDataProviderImplNxp.cpp index 6c3481da234719..9c7b3c789a72c0 100644 --- a/src/platform/nxp/zephyr/DiagnosticDataProviderImplNxp.cpp +++ b/src/platform/nxp/zephyr/DiagnosticDataProviderImplNxp.cpp @@ -46,7 +46,7 @@ CHIP_ERROR DiagnosticDataProviderImplNxp::GetWiFiBssId(MutableByteSpan & value) { WiFiManager::WiFiInfo info; ReturnErrorOnFailure(WiFiManager::Instance().GetWiFiInfo(info)); - ReturnErrorCodeIf(sizeof(info.mBssId) >= value.size(), CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(sizeof(info.mBssId) < value.size(), CHIP_ERROR_BUFFER_TOO_SMALL); memcpy(value.data(), info.mBssId, sizeof(info.mBssId)); value.reduce_size(sizeof(info.mBssId)); diff --git a/src/platform/nxp/zephyr/ota/OTAImageProcessorImpl.cpp b/src/platform/nxp/zephyr/ota/OTAImageProcessorImpl.cpp index 89907c0fff3bdd..d86e662ccc05c8 100644 --- a/src/platform/nxp/zephyr/ota/OTAImageProcessorImpl.cpp +++ b/src/platform/nxp/zephyr/ota/OTAImageProcessorImpl.cpp @@ -151,10 +151,10 @@ CHIP_ERROR OTAImageProcessorImpl::ProcessBlock(ByteSpan & aBlock) bool OTAImageProcessorImpl::IsFirstImageRun() { OTARequestorInterface * requestor = GetRequestorInstance(); - ReturnErrorCodeIf(requestor == nullptr, false); + VerifyOrReturnError(requestor != nullptr, false); uint32_t currentVersion; - ReturnErrorCodeIf(ConfigurationMgr().GetSoftwareVersion(currentVersion) != CHIP_NO_ERROR, false); + VerifyOrReturnError(ConfigurationMgr().GetSoftwareVersion(currentVersion) == CHIP_NO_ERROR, false); return requestor->GetCurrentUpdateState() == OTARequestorInterface::OTAUpdateStateEnum::kApplying && requestor->GetTargetVersion() == currentVersion; @@ -173,7 +173,7 @@ CHIP_ERROR OTAImageProcessorImpl::ProcessHeader(ByteSpan & aBlock) CHIP_ERROR error = mHeaderParser.AccumulateAndDecode(aBlock, header); // Needs more data to decode the header - ReturnErrorCodeIf(error == CHIP_ERROR_BUFFER_TOO_SMALL, CHIP_NO_ERROR); + VerifyOrReturnError(error != CHIP_ERROR_BUFFER_TOO_SMALL, CHIP_NO_ERROR); ReturnErrorOnFailure(error); mParams.totalFileBytes = header.mPayloadSize; diff --git a/src/platform/openiotsdk/OTAImageProcessorImpl.cpp b/src/platform/openiotsdk/OTAImageProcessorImpl.cpp index 81b3973ff2c0a6..a92a9b1020885a 100644 --- a/src/platform/openiotsdk/OTAImageProcessorImpl.cpp +++ b/src/platform/openiotsdk/OTAImageProcessorImpl.cpp @@ -255,7 +255,7 @@ CHIP_ERROR OTAImageProcessorImpl::ProcessHeader(ByteSpan & block) CHIP_ERROR error = mHeaderParser.AccumulateAndDecode(block, header); // Needs more data to decode the header - ReturnErrorCodeIf(error == CHIP_ERROR_BUFFER_TOO_SMALL, CHIP_NO_ERROR); + VerifyOrReturnError(error != CHIP_ERROR_BUFFER_TOO_SMALL, CHIP_NO_ERROR); ReturnErrorOnFailure(error); mParams.totalFileBytes = header.mPayloadSize; diff --git a/src/platform/qpg/OTAImageProcessorImpl.cpp b/src/platform/qpg/OTAImageProcessorImpl.cpp index 6293f310bf28d9..e0e2cf4a8029f5 100644 --- a/src/platform/qpg/OTAImageProcessorImpl.cpp +++ b/src/platform/qpg/OTAImageProcessorImpl.cpp @@ -77,7 +77,7 @@ CHIP_ERROR OTAImageProcessorImpl::ProcessHeader(ByteSpan & block) CHIP_ERROR error = mHeaderParser.AccumulateAndDecode(block, header); // Needs more data to decode the header - ReturnErrorCodeIf(error == CHIP_ERROR_BUFFER_TOO_SMALL, CHIP_NO_ERROR); + VerifyOrReturnError(error != CHIP_ERROR_BUFFER_TOO_SMALL, CHIP_NO_ERROR); ReturnErrorOnFailure(error); mParams.totalFileBytes = header.mPayloadSize; diff --git a/src/platform/silabs/SiWx917/CHIPCryptoPALTinyCrypt.cpp b/src/platform/silabs/SiWx917/CHIPCryptoPALTinyCrypt.cpp index 52f2cb74b9fe86..05fa10c5832ac2 100644 --- a/src/platform/silabs/SiWx917/CHIPCryptoPALTinyCrypt.cpp +++ b/src/platform/silabs/SiWx917/CHIPCryptoPALTinyCrypt.cpp @@ -1983,7 +1983,7 @@ CHIP_ERROR ExtractRawDNFromX509Cert(bool extractSubject, const ByteSpan & certif size_t len = 0; mbedtls_x509_crt mbedCertificate; - ReturnErrorCodeIf(certificate.empty(), CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(!certificate.empty(), CHIP_ERROR_INVALID_ARGUMENT); mbedtls_x509_crt_init(&mbedCertificate); result = mbedtls_x509_crt_parse(&mbedCertificate, Uint8::to_const_uchar(certificate.data()), certificate.size()); @@ -2039,7 +2039,7 @@ CHIP_ERROR ReplaceCertIfResignedCertFound(const ByteSpan & referenceCertificate, outCertificate = referenceCertificate; - ReturnErrorCodeIf(candidateCertificates == nullptr || candidateCertificatesCount == 0, CHIP_NO_ERROR); + VerifyOrReturnError(candidateCertificates != nullptr && candidateCertificatesCount != 0, CHIP_NO_ERROR); ReturnErrorOnFailure(ExtractSubjectFromX509Cert(referenceCertificate, referenceSubject)); ReturnErrorOnFailure(ExtractSKIDFromX509Cert(referenceCertificate, referenceSKID)); diff --git a/src/platform/silabs/SiWx917/OTAImageProcessorImpl.cpp b/src/platform/silabs/SiWx917/OTAImageProcessorImpl.cpp index d641bfa61f9888..bccb704ad18cab 100644 --- a/src/platform/silabs/SiWx917/OTAImageProcessorImpl.cpp +++ b/src/platform/silabs/SiWx917/OTAImageProcessorImpl.cpp @@ -51,7 +51,7 @@ uint8_t OTAImageProcessorImpl::writeBuffer[kAlignmentBytes] __attribute__((align CHIP_ERROR OTAImageProcessorImpl::Init(OTADownloader * downloader) { - ReturnErrorCodeIf(downloader == nullptr, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(downloader != nullptr, CHIP_ERROR_INVALID_ARGUMENT); gImageProcessor.SetOTADownloader(downloader); @@ -342,7 +342,7 @@ CHIP_ERROR OTAImageProcessorImpl::ProcessHeader(ByteSpan & block) CHIP_ERROR error = mHeaderParser.AccumulateAndDecode(block, header); // Needs more data to decode the header - ReturnErrorCodeIf(error == CHIP_ERROR_BUFFER_TOO_SMALL, CHIP_NO_ERROR); + VerifyOrReturnError(error != CHIP_ERROR_BUFFER_TOO_SMALL, CHIP_NO_ERROR); ReturnErrorOnFailure(error); // SL TODO -- store version somewhere diff --git a/src/platform/silabs/efr32/CHIPCryptoPALPsaEfr32.cpp b/src/platform/silabs/efr32/CHIPCryptoPALPsaEfr32.cpp index 6989e3a2c67945..8028d84d92c40c 100644 --- a/src/platform/silabs/efr32/CHIPCryptoPALPsaEfr32.cpp +++ b/src/platform/silabs/efr32/CHIPCryptoPALPsaEfr32.cpp @@ -2330,7 +2330,7 @@ CHIP_ERROR ExtractRawDNFromX509Cert(bool extractSubject, const ByteSpan & certif size_t len = 0; mbedtls_x509_crt mbedCertificate; - ReturnErrorCodeIf(certificate.empty(), CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(!certificate.empty(), CHIP_ERROR_INVALID_ARGUMENT); mbedtls_x509_crt_init(&mbedCertificate); result = mbedtls_x509_crt_parse(&mbedCertificate, Uint8::to_const_uchar(certificate.data()), certificate.size()); @@ -2386,7 +2386,7 @@ CHIP_ERROR ReplaceCertIfResignedCertFound(const ByteSpan & referenceCertificate, outCertificate = referenceCertificate; - ReturnErrorCodeIf(candidateCertificates == nullptr || candidateCertificatesCount == 0, CHIP_NO_ERROR); + VerifyOrReturnError(candidateCertificates != nullptr && candidateCertificatesCount != 0, CHIP_NO_ERROR); ReturnErrorOnFailure(ExtractSubjectFromX509Cert(referenceCertificate, referenceSubject)); ReturnErrorOnFailure(ExtractSKIDFromX509Cert(referenceCertificate, referenceSKID)); diff --git a/src/platform/silabs/efr32/OTAImageProcessorImpl.cpp b/src/platform/silabs/efr32/OTAImageProcessorImpl.cpp index 846d4f720ac930..4fc7f8d7424cdd 100644 --- a/src/platform/silabs/efr32/OTAImageProcessorImpl.cpp +++ b/src/platform/silabs/efr32/OTAImageProcessorImpl.cpp @@ -45,7 +45,7 @@ uint8_t OTAImageProcessorImpl::writeBuffer[kAlignmentBytes] __attribute__((align CHIP_ERROR OTAImageProcessorImpl::Init(OTADownloader * downloader) { - ReturnErrorCodeIf(downloader == nullptr, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(downloader != nullptr, CHIP_ERROR_INVALID_ARGUMENT); gImageProcessor.SetOTADownloader(downloader); @@ -357,7 +357,7 @@ CHIP_ERROR OTAImageProcessorImpl::ProcessHeader(ByteSpan & block) CHIP_ERROR error = mHeaderParser.AccumulateAndDecode(block, header); // Needs more data to decode the header - ReturnErrorCodeIf(error == CHIP_ERROR_BUFFER_TOO_SMALL, CHIP_NO_ERROR); + VerifyOrReturnError(error != CHIP_ERROR_BUFFER_TOO_SMALL, CHIP_NO_ERROR); ReturnErrorOnFailure(error); // SL TODO -- store version somewhere diff --git a/src/platform/silabs/multi-ota/OTACustomProcessor.cpp b/src/platform/silabs/multi-ota/OTACustomProcessor.cpp index ef761d003e0499..6b87638adb9639 100644 --- a/src/platform/silabs/multi-ota/OTACustomProcessor.cpp +++ b/src/platform/silabs/multi-ota/OTACustomProcessor.cpp @@ -43,7 +43,7 @@ uint8_t OTACustomProcessor::writeBuffer[kAlignmentBytes] __attribute__((aligned( CHIP_ERROR OTACustomProcessor::Init() { - ReturnErrorCodeIf(mCallbackProcessDescriptor == nullptr, CHIP_OTA_PROCESSOR_CB_NOT_REGISTERED); + VerifyOrReturnError(mCallbackProcessDescriptor != nullptr, CHIP_OTA_PROCESSOR_CB_NOT_REGISTERED); mAccumulator.Init(sizeof(Descriptor)); return CHIP_NO_ERROR; diff --git a/src/platform/silabs/multi-ota/OTAFirmwareProcessor.cpp b/src/platform/silabs/multi-ota/OTAFirmwareProcessor.cpp index d8545d01f40996..07dc974dd7b54d 100644 --- a/src/platform/silabs/multi-ota/OTAFirmwareProcessor.cpp +++ b/src/platform/silabs/multi-ota/OTAFirmwareProcessor.cpp @@ -43,7 +43,7 @@ uint8_t OTAFirmwareProcessor::writeBuffer[kAlignmentBytes] __attribute__((aligne CHIP_ERROR OTAFirmwareProcessor::Init() { - ReturnErrorCodeIf(mCallbackProcessDescriptor == nullptr, CHIP_OTA_PROCESSOR_CB_NOT_REGISTERED); + VerifyOrReturnError(mCallbackProcessDescriptor != nullptr, CHIP_OTA_PROCESSOR_CB_NOT_REGISTERED); mAccumulator.Init(sizeof(Descriptor)); #if OTA_ENCRYPTION_ENABLE mUnalignmentNum = 0; diff --git a/src/platform/silabs/multi-ota/OTAMultiImageProcessorImpl.cpp b/src/platform/silabs/multi-ota/OTAMultiImageProcessorImpl.cpp index a95cb4e1ada4b4..42a9788c2868eb 100644 --- a/src/platform/silabs/multi-ota/OTAMultiImageProcessorImpl.cpp +++ b/src/platform/silabs/multi-ota/OTAMultiImageProcessorImpl.cpp @@ -42,7 +42,7 @@ namespace chip { CHIP_ERROR OTAMultiImageProcessorImpl::Init(OTADownloader * downloader) { - ReturnErrorCodeIf(downloader == nullptr, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(downloader != nullptr, CHIP_ERROR_INVALID_ARGUMENT); gImageProcessor.SetOTADownloader(downloader); @@ -297,7 +297,7 @@ CHIP_ERROR OTAMultiImageProcessorImpl::ConfirmCurrentImage() uint32_t targetVersion; OTARequestorInterface * requestor = chip::GetRequestorInstance(); - ReturnErrorCodeIf(requestor == nullptr, CHIP_ERROR_INTERNAL); + VerifyOrReturnError(requestor != nullptr, CHIP_ERROR_INTERNAL); targetVersion = requestor->GetTargetVersion(); ReturnErrorOnFailure(DeviceLayer::ConfigurationMgr().GetSoftwareVersion(currentVersion)); diff --git a/src/platform/stm32/FactoryDataProvider.cpp b/src/platform/stm32/FactoryDataProvider.cpp index 8b3d0af05a6ec7..c5a82393df3cd0 100644 --- a/src/platform/stm32/FactoryDataProvider.cpp +++ b/src/platform/stm32/FactoryDataProvider.cpp @@ -268,7 +268,7 @@ CHIP_ERROR FactoryDataProvider::GetVendorName(char * buf, size_t bufSize) { #if (CONFIG_STM32_FACTORY_DATA_ENABLE == 0) - ReturnErrorCodeIf(bufSize < sizeof(CHIP_DEVICE_CONFIG_DEVICE_VENDOR_NAME), CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(bufSize >= sizeof(CHIP_DEVICE_CONFIG_DEVICE_VENDOR_NAME), CHIP_ERROR_BUFFER_TOO_SMALL); memcpy(buf, CHIP_DEVICE_CONFIG_DEVICE_VENDOR_NAME, sizeof(CHIP_DEVICE_CONFIG_DEVICE_VENDOR_NAME)); #else @@ -287,7 +287,7 @@ CHIP_ERROR FactoryDataProvider::GetProductName(char * buf, size_t bufSize) { #if (CONFIG_STM32_FACTORY_DATA_ENABLE == 0) - ReturnErrorCodeIf(bufSize < sizeof(CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_NAME), CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(bufSize >= sizeof(CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_NAME), CHIP_ERROR_BUFFER_TOO_SMALL); memcpy(buf, CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_NAME, sizeof(CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_NAME)); #else FACTORYDATA_StatusTypeDef err; @@ -319,7 +319,7 @@ CHIP_ERROR FactoryDataProvider::GetSerialNumber(char * buf, size_t bufSize) CHIP_ERROR FactoryDataProvider::GetHardwareVersionString(char * buf, size_t bufSize) { - ReturnErrorCodeIf(bufSize < sizeof(CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION_STRING), CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(bufSize >= sizeof(CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION_STRING), CHIP_ERROR_BUFFER_TOO_SMALL); memcpy(buf, CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION_STRING, sizeof(CHIP_DEVICE_CONFIG_DEFAULT_DEVICE_HARDWARE_VERSION_STRING)); return CHIP_NO_ERROR; diff --git a/src/platform/stm32/OTAImageProcessorImpl.cpp b/src/platform/stm32/OTAImageProcessorImpl.cpp index 76363befebb005..30967cd6146729 100644 --- a/src/platform/stm32/OTAImageProcessorImpl.cpp +++ b/src/platform/stm32/OTAImageProcessorImpl.cpp @@ -96,7 +96,7 @@ CHIP_ERROR OTAImageProcessorImpl::ProcessHeader(ByteSpan & block) CHIP_ERROR error = mHeaderParser.AccumulateAndDecode(block, header); // Needs more data to decode the header - ReturnErrorCodeIf(error == CHIP_ERROR_BUFFER_TOO_SMALL, CHIP_NO_ERROR); + VerifyOrReturnError(error != CHIP_ERROR_BUFFER_TOO_SMALL, CHIP_NO_ERROR); ReturnErrorOnFailure(error); mParams.totalFileBytes = header.mPayloadSize; diff --git a/src/platform/telink/FactoryDataProvider.cpp b/src/platform/telink/FactoryDataProvider.cpp index ba02131911370f..b2d58313f6178e 100644 --- a/src/platform/telink/FactoryDataProvider.cpp +++ b/src/platform/telink/FactoryDataProvider.cpp @@ -40,8 +40,8 @@ CHIP_ERROR LoadKeypairFromRaw(ByteSpan privateKey, ByteSpan publicKey, Crypto::P CHIP_ERROR GetFactoryDataString(const FactoryDataString & str, char * buf, size_t bufSize) { - ReturnErrorCodeIf(bufSize < str.len + 1, CHIP_ERROR_BUFFER_TOO_SMALL); - ReturnErrorCodeIf(!str.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + VerifyOrReturnError(bufSize >= str.len + 1, CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(str.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); memcpy(buf, str.data, str.len); buf[str.len] = 0; @@ -102,8 +102,8 @@ template CHIP_ERROR FactoryDataProvider::GetCertificationDeclaration(MutableByteSpan & outBuffer) { #if CONFIG_CHIP_CERTIFICATION_DECLARATION_STORAGE - ReturnErrorCodeIf(outBuffer.size() < mFactoryData.certificate_declaration.len, CHIP_ERROR_BUFFER_TOO_SMALL); - ReturnErrorCodeIf(!mFactoryData.certificate_declaration.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + VerifyOrReturnError(outBuffer.size() >= mFactoryData.certificate_declaration.len, CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(mFactoryData.certificate_declaration.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); memcpy(outBuffer.data(), mFactoryData.certificate_declaration.data, mFactoryData.certificate_declaration.len); @@ -127,8 +127,8 @@ CHIP_ERROR FactoryDataProvider::GetFirmwareInformation(Mutable template CHIP_ERROR FactoryDataProvider::GetDeviceAttestationCert(MutableByteSpan & outBuffer) { - ReturnErrorCodeIf(outBuffer.size() < mFactoryData.dac_cert.len, CHIP_ERROR_BUFFER_TOO_SMALL); - ReturnErrorCodeIf(!mFactoryData.dac_cert.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + VerifyOrReturnError(outBuffer.size() >= mFactoryData.dac_cert.len, CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(mFactoryData.dac_cert.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); memcpy(outBuffer.data(), mFactoryData.dac_cert.data, mFactoryData.dac_cert.len); @@ -140,8 +140,8 @@ CHIP_ERROR FactoryDataProvider::GetDeviceAttestationCert(Mutab template CHIP_ERROR FactoryDataProvider::GetProductAttestationIntermediateCert(MutableByteSpan & outBuffer) { - ReturnErrorCodeIf(outBuffer.size() < mFactoryData.pai_cert.len, CHIP_ERROR_BUFFER_TOO_SMALL); - ReturnErrorCodeIf(!mFactoryData.pai_cert.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + VerifyOrReturnError(outBuffer.size() >= mFactoryData.pai_cert.len, CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(mFactoryData.pai_cert.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); memcpy(outBuffer.data(), mFactoryData.pai_cert.data, mFactoryData.pai_cert.len); @@ -158,8 +158,8 @@ CHIP_ERROR FactoryDataProvider::SignWithDeviceAttestationKey(c Crypto::P256Keypair keypair; VerifyOrReturnError(outSignBuffer.size() >= signature.Capacity(), CHIP_ERROR_BUFFER_TOO_SMALL); - ReturnErrorCodeIf(!mFactoryData.dac_cert.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); - ReturnErrorCodeIf(!mFactoryData.dac_priv_key.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + VerifyOrReturnError(mFactoryData.dac_cert.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + VerifyOrReturnError(mFactoryData.dac_priv_key.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); // Extract public key from DAC cert. ByteSpan dacCertSpan{ reinterpret_cast(mFactoryData.dac_cert.data), mFactoryData.dac_cert.len }; @@ -191,7 +191,7 @@ CHIP_ERROR FactoryDataProvider::SetSetupDiscriminator(uint16_t template CHIP_ERROR FactoryDataProvider::GetSpake2pIterationCount(uint32_t & iterationCount) { - ReturnErrorCodeIf(mFactoryData.spake2_it == 0, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + VerifyOrReturnError(mFactoryData.spake2_it != 0, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); iterationCount = mFactoryData.spake2_it; return CHIP_NO_ERROR; } @@ -199,8 +199,8 @@ CHIP_ERROR FactoryDataProvider::GetSpake2pIterationCount(uint3 template CHIP_ERROR FactoryDataProvider::GetSpake2pSalt(MutableByteSpan & saltBuf) { - ReturnErrorCodeIf(saltBuf.size() < mFactoryData.spake2_salt.len, CHIP_ERROR_BUFFER_TOO_SMALL); - ReturnErrorCodeIf(!mFactoryData.spake2_salt.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + VerifyOrReturnError(saltBuf.size() >= mFactoryData.spake2_salt.len, CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(mFactoryData.spake2_salt.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); memcpy(saltBuf.data(), mFactoryData.spake2_salt.data, mFactoryData.spake2_salt.len); @@ -212,8 +212,8 @@ CHIP_ERROR FactoryDataProvider::GetSpake2pSalt(MutableByteSpan template CHIP_ERROR FactoryDataProvider::GetSpake2pVerifier(MutableByteSpan & verifierBuf, size_t & verifierLen) { - ReturnErrorCodeIf(verifierBuf.size() < mFactoryData.spake2_verifier.len, CHIP_ERROR_BUFFER_TOO_SMALL); - ReturnErrorCodeIf(!mFactoryData.spake2_verifier.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + VerifyOrReturnError(verifierBuf.size() >= mFactoryData.spake2_verifier.len, CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(mFactoryData.spake2_verifier.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); memcpy(verifierBuf.data(), mFactoryData.spake2_verifier.data, mFactoryData.spake2_verifier.len); @@ -227,7 +227,7 @@ CHIP_ERROR FactoryDataProvider::GetSpake2pVerifier(MutableByte template CHIP_ERROR FactoryDataProvider::GetSetupPasscode(uint32_t & setupPasscode) { - ReturnErrorCodeIf(mFactoryData.passcode == 0, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + VerifyOrReturnError(mFactoryData.passcode != 0, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); setupPasscode = mFactoryData.passcode; return CHIP_NO_ERROR; } @@ -317,8 +317,8 @@ CHIP_ERROR FactoryDataProvider::GetHardwareVersionString(char template CHIP_ERROR FactoryDataProvider::GetRotatingDeviceIdUniqueId(MutableByteSpan & uniqueIdSpan) { - ReturnErrorCodeIf(uniqueIdSpan.size() < mFactoryData.rd_uid.len, CHIP_ERROR_BUFFER_TOO_SMALL); - ReturnErrorCodeIf(!mFactoryData.rd_uid.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + VerifyOrReturnError(uniqueIdSpan.size() >= mFactoryData.rd_uid.len, CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(mFactoryData.rd_uid.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); memcpy(uniqueIdSpan.data(), mFactoryData.rd_uid.data, mFactoryData.rd_uid.len); @@ -328,8 +328,8 @@ CHIP_ERROR FactoryDataProvider::GetRotatingDeviceIdUniqueId(Mu template CHIP_ERROR FactoryDataProvider::GetEnableKey(MutableByteSpan & enableKey) { - ReturnErrorCodeIf(!mFactoryData.enable_key.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); - ReturnErrorCodeIf(enableKey.size() < mFactoryData.enable_key.len / 2, CHIP_ERROR_BUFFER_TOO_SMALL); + VerifyOrReturnError(mFactoryData.enable_key.data, CHIP_ERROR_PERSISTED_STORAGE_VALUE_NOT_FOUND); + VerifyOrReturnError(enableKey.size() >= mFactoryData.enable_key.len / 2, CHIP_ERROR_BUFFER_TOO_SMALL); Encoding::HexToBytes((const char *) mFactoryData.enable_key.data, mFactoryData.enable_key.len, enableKey.data(), enableKey.size()); diff --git a/src/platform/telink/OTAImageProcessorImpl.cpp b/src/platform/telink/OTAImageProcessorImpl.cpp index b1ce54748e268e..a47a59fadfdb38 100644 --- a/src/platform/telink/OTAImageProcessorImpl.cpp +++ b/src/platform/telink/OTAImageProcessorImpl.cpp @@ -159,10 +159,10 @@ CHIP_ERROR OTAImageProcessorImpl::ProcessBlock(ByteSpan & aBlock) bool OTAImageProcessorImpl::IsFirstImageRun() { OTARequestorInterface * requestor = GetRequestorInstance(); - ReturnErrorCodeIf(requestor == nullptr, false); + VerifyOrReturnError(requestor != nullptr, false); uint32_t currentVersion; - ReturnErrorCodeIf(ConfigurationMgr().GetSoftwareVersion(currentVersion) != CHIP_NO_ERROR, false); + VerifyOrReturnError(ConfigurationMgr().GetSoftwareVersion(currentVersion) == CHIP_NO_ERROR, false); return requestor->GetCurrentUpdateState() == OTARequestorInterface::OTAUpdateStateEnum::kApplying && requestor->GetTargetVersion() == currentVersion; @@ -182,7 +182,7 @@ CHIP_ERROR OTAImageProcessorImpl::ProcessHeader(ByteSpan & aBlock) CHIP_ERROR error = mHeaderParser.AccumulateAndDecode(aBlock, header); // Needs more data to decode the header - ReturnErrorCodeIf(error == CHIP_ERROR_BUFFER_TOO_SMALL, CHIP_NO_ERROR); + VerifyOrReturnError(error != CHIP_ERROR_BUFFER_TOO_SMALL, CHIP_NO_ERROR); ReturnErrorOnFailure(error); mParams.totalFileBytes = header.mPayloadSize; diff --git a/src/platform/webos/ChipDeviceScanner.cpp b/src/platform/webos/ChipDeviceScanner.cpp index 5a312281d6d8b9..5808b4bf482b61 100644 --- a/src/platform/webos/ChipDeviceScanner.cpp +++ b/src/platform/webos/ChipDeviceScanner.cpp @@ -294,7 +294,7 @@ gboolean ChipDeviceScanner::TriggerScan(GMainLoop * mainLoop, gpointer userData) CHIP_ERROR ChipDeviceScanner::StartChipScan(unsigned timeoutMs) { CHIP_ERROR err = CHIP_NO_ERROR; - ReturnErrorCodeIf(mIsScanning, CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(!mIsScanning, CHIP_ERROR_INCORRECT_STATE); kScanTimeout = timeoutMs; @@ -327,7 +327,7 @@ bool ChipDeviceScanner::cancelDiscoveryCb(LSHandle * sh, LSMessage * message, vo CHIP_ERROR ChipDeviceScanner::StopChipScan() { int ret = 0; - ReturnErrorCodeIf(!mIsScanning, CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(mIsScanning, CHIP_ERROR_INCORRECT_STATE); ret = LSCall(mLSHandle, "luna://com.webos.service.bluetooth2/dadapter/cancelDiscovery", "{}", cancelDiscoveryCb, this, NULL, NULL); diff --git a/src/protocols/secure_channel/CASEServer.cpp b/src/protocols/secure_channel/CASEServer.cpp index fc6b4970ce0829..95d3a9c7714ec3 100644 --- a/src/protocols/secure_channel/CASEServer.cpp +++ b/src/protocols/secure_channel/CASEServer.cpp @@ -61,7 +61,7 @@ CHIP_ERROR CASEServer::ListenForSessionEstablishment(Messaging::ExchangeManager CHIP_ERROR CASEServer::InitCASEHandshake(Messaging::ExchangeContext * ec) { MATTER_TRACE_SCOPE("InitCASEHandshake", "CASEServer"); - ReturnErrorCodeIf(ec == nullptr, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(ec != nullptr, CHIP_ERROR_INVALID_ARGUMENT); // Hand over the exchange context to the CASE session. ec->SetDelegate(&GetSession()); diff --git a/src/protocols/secure_channel/CASESession.cpp b/src/protocols/secure_channel/CASESession.cpp index e0a0fa744e4cc3..007a58659f45cd 100644 --- a/src/protocols/secure_channel/CASESession.cpp +++ b/src/protocols/secure_channel/CASESession.cpp @@ -523,15 +523,15 @@ CHIP_ERROR CASESession::EstablishSession(SessionManager & sessionManager, Fabric CHIP_ERROR err = CHIP_NO_ERROR; // Return early on error here, as we have not initialized any state yet - ReturnErrorCodeWithMetricIf(kMetricDeviceCASESession, exchangeCtxt == nullptr, CHIP_ERROR_INVALID_ARGUMENT); - ReturnErrorCodeWithMetricIf(kMetricDeviceCASESession, fabricTable == nullptr, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnErrorWithMetric(kMetricDeviceCASESession, exchangeCtxt != nullptr, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnErrorWithMetric(kMetricDeviceCASESession, fabricTable != nullptr, CHIP_ERROR_INVALID_ARGUMENT); // Use FabricTable directly to avoid situation of dangling index from stale FabricInfo // until we factor-out any FabricInfo direct usage. - ReturnErrorCodeWithMetricIf(kMetricDeviceCASESession, peerScopedNodeId.GetFabricIndex() == kUndefinedFabricIndex, - CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnErrorWithMetric(kMetricDeviceCASESession, peerScopedNodeId.GetFabricIndex() != kUndefinedFabricIndex, + CHIP_ERROR_INVALID_ARGUMENT); const auto * fabricInfo = fabricTable->FindFabricWithIndex(peerScopedNodeId.GetFabricIndex()); - ReturnErrorCodeWithMetricIf(kMetricDeviceCASESession, fabricInfo == nullptr, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnErrorWithMetric(kMetricDeviceCASESession, fabricInfo != nullptr, CHIP_ERROR_INVALID_ARGUMENT); err = Init(sessionManager, policy, delegate, peerScopedNodeId); @@ -784,7 +784,7 @@ CHIP_ERROR CASESession::SendSigma1() // Lookup fabric info. const auto * fabricInfo = mFabricsTable->FindFabricWithIndex(mFabricIndex); - ReturnErrorCodeIf(fabricInfo == nullptr, CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(fabricInfo != nullptr, CHIP_ERROR_INCORRECT_STATE); // Validate that we have a session ID allocated. VerifyOrReturnError(GetLocalSessionId().HasValue(), CHIP_ERROR_INCORRECT_STATE); diff --git a/src/protocols/secure_channel/PASESession.cpp b/src/protocols/secure_channel/PASESession.cpp index 345b307f26c24d..638b99624bae6c 100644 --- a/src/protocols/secure_channel/PASESession.cpp +++ b/src/protocols/secure_channel/PASESession.cpp @@ -126,7 +126,7 @@ CHIP_ERROR PASESession::Init(SessionManager & sessionManager, uint32_t setupCode VerifyOrReturnError(GetLocalSessionId().HasValue(), CHIP_ERROR_INCORRECT_STATE); ChipLogDetail(SecureChannel, "Assigned local session key ID %u", GetLocalSessionId().Value()); - ReturnErrorCodeIf(setupCode >= (1 << kSetupPINCodeFieldLengthInBits), CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(setupCode < (1 << kSetupPINCodeFieldLengthInBits), CHIP_ERROR_INVALID_ARGUMENT); mSetupPINCode = setupCode; return CHIP_NO_ERROR; @@ -162,10 +162,10 @@ CHIP_ERROR PASESession::WaitForPairing(SessionManager & sessionManager, const Sp SessionEstablishmentDelegate * delegate) { // Return early on error here, as we have not initialized any state yet - ReturnErrorCodeIf(salt.empty(), CHIP_ERROR_INVALID_ARGUMENT); - ReturnErrorCodeIf(salt.data() == nullptr, CHIP_ERROR_INVALID_ARGUMENT); - ReturnErrorCodeIf(salt.size() < kSpake2p_Min_PBKDF_Salt_Length || salt.size() > kSpake2p_Max_PBKDF_Salt_Length, - CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(!salt.empty(), CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(salt.data() != nullptr, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(salt.size() >= kSpake2p_Min_PBKDF_Salt_Length && salt.size() <= kSpake2p_Max_PBKDF_Salt_Length, + CHIP_ERROR_INVALID_ARGUMENT); CHIP_ERROR err = Init(sessionManager, kSetupPINCodeUndefinedValue, delegate); // From here onwards, let's go to exit on error, as some state might have already @@ -209,7 +209,7 @@ CHIP_ERROR PASESession::Pair(SessionManager & sessionManager, uint32_t peerSetUp SessionEstablishmentDelegate * delegate) { MATTER_TRACE_SCOPE("Pair", "PASESession"); - ReturnErrorCodeIf(exchangeCtxt == nullptr, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(exchangeCtxt != nullptr, CHIP_ERROR_INVALID_ARGUMENT); CHIP_ERROR err = Init(sessionManager, peerSetUpPINCode, delegate); SuccessOrExit(err); diff --git a/src/protocols/secure_channel/StatusReport.cpp b/src/protocols/secure_channel/StatusReport.cpp index e31c832b469f51..5ce7656c9ef224 100644 --- a/src/protocols/secure_channel/StatusReport.cpp +++ b/src/protocols/secure_channel/StatusReport.cpp @@ -50,7 +50,7 @@ CHIP_ERROR StatusReport::Parse(System::PacketBufferHandle buf) { uint16_t tempGeneralCode = 0; - ReturnErrorCodeIf(buf.IsNull(), CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(!buf.IsNull(), CHIP_ERROR_INVALID_ARGUMENT); uint8_t * bufStart = buf->Start(); LittleEndian::Reader bufReader(bufStart, buf->DataLength()); diff --git a/src/setup_payload/QRCodeSetupPayloadParser.cpp b/src/setup_payload/QRCodeSetupPayloadParser.cpp index 99bf0e4983040b..102de4af69581b 100644 --- a/src/setup_payload/QRCodeSetupPayloadParser.cpp +++ b/src/setup_payload/QRCodeSetupPayloadParser.cpp @@ -267,10 +267,10 @@ CHIP_ERROR QRCodeSetupPayloadParser::populateTLV(SetupPayload & outPayload, cons size_t tlvBytesLength = (bitsLeftToRead + 7) / 8; // ceil(bitsLeftToRead/8) chip::Platform::ScopedMemoryBuffer tlvArray; - ReturnErrorCodeIf(tlvBytesLength == 0, CHIP_NO_ERROR); + VerifyOrReturnError(tlvBytesLength != 0, CHIP_NO_ERROR); tlvArray.Alloc(tlvBytesLength); - ReturnErrorCodeIf(!tlvArray, CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(tlvArray, CHIP_ERROR_NO_MEMORY); for (size_t i = 0; i < tlvBytesLength; i++) { diff --git a/src/system/SystemLayerImplSelect.cpp b/src/system/SystemLayerImplSelect.cpp index 3e8a79f7b6e44f..fe025a5765e659 100644 --- a/src/system/SystemLayerImplSelect.cpp +++ b/src/system/SystemLayerImplSelect.cpp @@ -427,7 +427,7 @@ CHIP_ERROR LayerImplSelect::RequestCallbackOnPendingRead(SocketWatchToken token) { watch->mRdSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_READ, static_cast(watch->mFD), 0, dispatchQueue); - ReturnErrorCodeIf(watch->mRdSource == nullptr, CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(watch->mRdSource != nullptr, CHIP_ERROR_NO_MEMORY); dispatch_source_set_event_handler(watch->mRdSource, ^{ if (watch->mPendingIO.Has(SocketEventFlags::kRead) && watch->mCallback != nullptr) { @@ -487,7 +487,7 @@ CHIP_ERROR LayerImplSelect::RequestCallbackOnPendingWrite(SocketWatchToken token { watch->mWrSource = dispatch_source_create(DISPATCH_SOURCE_TYPE_WRITE, static_cast(watch->mFD), 0, dispatchQueue); - ReturnErrorCodeIf(watch->mWrSource == nullptr, CHIP_ERROR_NO_MEMORY); + VerifyOrReturnError(watch->mWrSource != nullptr, CHIP_ERROR_NO_MEMORY); dispatch_source_set_event_handler(watch->mWrSource, ^{ if (watch->mPendingIO.Has(SocketEventFlags::kWrite) && watch->mCallback != nullptr) { diff --git a/src/tracing/metric_macros.h b/src/tracing/metric_macros.h index 3d00e7d9d9677b..1a2596ec2c93e5 100644 --- a/src/tracing/metric_macros.h +++ b/src/tracing/metric_macros.h @@ -241,36 +241,6 @@ } while (false) #endif // CHIP_CONFIG_ERROR_SOURCE -/** - * @def ReturnErrorCodeWithMetricIf(kMetricKey, expr, code) - * - * @brief - * Returns a specified error code if expression evaluates to true - * If the expression evaluates to true, a metric with the specified key is emitted - * with the value set to code. - * - * Example usage: - * - * @code - * ReturnErrorCodeWithMetricIf(kMetricKey, state == kInitialized, CHIP_NO_ERROR); - * ReturnErrorCodeWithMetricIf(kMetricKey, state == kInitialized, CHIP_ERROR_INCORRECT_STATE); - * @endcode - * - * @param[in] kMetricKey Metric key for the metric event to be emitted if the expr evaluates - * to true. Value of the metric is to code. - * @param[in] expr A Boolean expression to be evaluated. - * @param[in] code A value to return if @a expr is false. - */ -#define ReturnErrorCodeWithMetricIf(kMetricKey, expr, code) \ - do \ - { \ - if (expr) \ - { \ - MATTER_LOG_METRIC(kMetricKey, code); \ - return code; \ - } \ - } while (false) - /** * @def SuccessOrExitWithMetric(kMetricKey, error) * @@ -577,14 +547,12 @@ #define VerifyOrReturnWithMetric(kMetricKey, expr, ...) VerifyOrReturn(expr, ##__VA_ARGS__) -#define VerifyOrReturnErrorWithMetric(kMetricKey, expr, code, ...) VerifyOrReturnValue(expr, code, ##__VA_ARGS__) +#define VerifyOrReturnErrorWithMetric(kMetricKey, expr, code, ...) VerifyOrReturnError(expr, code, ##__VA_ARGS__) #define VerifyOrReturnValueWithMetric(kMetricKey, expr, value, ...) VerifyOrReturnValue(expr, value, ##__VA_ARGS__) #define VerifyOrReturnLogErrorWithMetric(kMetricKey, expr, code) VerifyOrReturnLogError(expr, code) -#define ReturnErrorCodeWithMetricIf(kMetricKey, expr, code) ReturnErrorCodeIf(expr, code) - #define SuccessOrExitWithMetric(kMetricKey, aStatus) SuccessOrExit(aStatus) #define VerifyOrExitWithMetric(kMetricKey, aCondition, anAction) VerifyOrExit(aCondition, anAction) diff --git a/src/tracing/tests/TestMetricEvents.cpp b/src/tracing/tests/TestMetricEvents.cpp index 20c6f7788ad69e..d3796477c09f89 100644 --- a/src/tracing/tests/TestMetricEvents.cpp +++ b/src/tracing/tests/TestMetricEvents.cpp @@ -523,39 +523,6 @@ TEST(TestMetricEvents, TestVerifyOrReturnLogErrorWithMetric) EXPECT_TRUE(std::equal(backend.GetMetricEvents().begin(), backend.GetMetricEvents().end(), expected.begin(), expected.end())); } -template -static return_code_type InvokeReturnErrorCodeWithMetricIf(MetricKey key, bool expr, const return_code_type & code) -{ - ReturnErrorCodeWithMetricIf(key, expr, code); - return return_code_type(); -} - -TEST(TestMetricEvents, TestReturnErrorCodeWithMetricIf) -{ - MetricEventBackend backend; - ScopedRegistration scope(backend); - - auto err = InvokeReturnErrorCodeWithMetricIf("event0", DoubleOf(2) == 4, CHIP_ERROR_DUPLICATE_KEY_ID); - EXPECT_EQ(err, CHIP_ERROR_DUPLICATE_KEY_ID); - - auto retval = InvokeReturnErrorCodeWithMetricIf("event1", DoubleOf(3) == 9, 11); - EXPECT_EQ(retval, 0); - - retval = InvokeReturnErrorCodeWithMetricIf("event2", DoubleOf(4) == 8, 22); - EXPECT_EQ(retval, 22); - - err = InvokeReturnErrorCodeWithMetricIf("event3", DoubleOf(5) == 11, CHIP_ERROR_ACCESS_DENIED); - EXPECT_EQ(err, CHIP_NO_ERROR); - - std::vector expected = { - MetricEvent(MetricEvent::Type::kInstantEvent, "event0", CHIP_ERROR_DUPLICATE_KEY_ID), - MetricEvent(MetricEvent::Type::kInstantEvent, "event2", 22), - }; - - EXPECT_EQ(backend.GetMetricEvents().size(), expected.size()); - EXPECT_TRUE(std::equal(backend.GetMetricEvents().begin(), backend.GetMetricEvents().end(), expected.begin(), expected.end())); -} - TEST(TestMetricEvents, TestExitNowWithMetric) { MetricEventBackend backend; diff --git a/src/transport/SecureMessageCodec.cpp b/src/transport/SecureMessageCodec.cpp index 263b4e5e127a5a..4e8cef59beb12b 100644 --- a/src/transport/SecureMessageCodec.cpp +++ b/src/transport/SecureMessageCodec.cpp @@ -61,7 +61,7 @@ CHIP_ERROR Encrypt(const CryptoContext & context, CryptoContext::ConstNonceView CHIP_ERROR Decrypt(const CryptoContext & context, CryptoContext::ConstNonceView nonce, PayloadHeader & payloadHeader, const PacketHeader & packetHeader, System::PacketBufferHandle & msg) { - ReturnErrorCodeIf(msg.IsNull(), CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(!msg.IsNull(), CHIP_ERROR_INVALID_ARGUMENT); uint8_t * data = msg->Start(); size_t len = msg->DataLength(); diff --git a/src/transport/raw/BLE.cpp b/src/transport/raw/BLE.cpp index 811969ef0966ea..2872db5bf3ae0b 100644 --- a/src/transport/raw/BLE.cpp +++ b/src/transport/raw/BLE.cpp @@ -96,9 +96,9 @@ CHIP_ERROR BLEBase::SetEndPoint(Ble::BLEEndPoint * endPoint) CHIP_ERROR BLEBase::SendMessage(const Transport::PeerAddress & address, System::PacketBufferHandle && msgBuf) { - ReturnErrorCodeIf(address.GetTransportType() != Type::kBle, CHIP_ERROR_INVALID_ARGUMENT); - ReturnErrorCodeIf(mBleEndPoint == nullptr, CHIP_ERROR_INCORRECT_STATE); - ReturnErrorCodeIf(mState == State::kNotReady, CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(address.GetTransportType() == Type::kBle, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(mBleEndPoint != nullptr, CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(mState != State::kNotReady, CHIP_ERROR_INCORRECT_STATE); if (mState == State::kConnected) { diff --git a/src/transport/raw/WiFiPAF.cpp b/src/transport/raw/WiFiPAF.cpp index 97b465dd261e9b..56c16b3342200c 100644 --- a/src/transport/raw/WiFiPAF.cpp +++ b/src/transport/raw/WiFiPAF.cpp @@ -79,8 +79,8 @@ CHIP_ERROR WiFiPAFBase::Init(const WiFiPAFListenParameters & param) CHIP_ERROR WiFiPAFBase::SendMessage(const Transport::PeerAddress & address, System::PacketBufferHandle && msgBuf) { - ReturnErrorCodeIf(address.GetTransportType() != Type::kWiFiPAF, CHIP_ERROR_INVALID_ARGUMENT); - ReturnErrorCodeIf(mState == State::kNotReady, CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(address.GetTransportType() == Type::kWiFiPAF, CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(mState != State::kNotReady, CHIP_ERROR_INCORRECT_STATE); DeviceLayer::ConnectivityMgr().WiFiPAFSend(std::move(msgBuf)); return CHIP_NO_ERROR; From 8fa33f045350e72ab086b1c796913b5d5b4e7ef2 Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Fri, 18 Oct 2024 10:39:15 -0400 Subject: [PATCH 038/149] Add support for log control variants to NXP build targets (#36122) * Add support for controlling logging amount in NXP builds * Remove the many reformat issues * Restyled by isort * Update scripts/build/builders/nxp.py Co-authored-by: Arkadiusz Bokowy --------- Co-authored-by: Restyled.io Co-authored-by: Arkadiusz Bokowy --- scripts/build/build/targets.py | 6 ++- scripts/build/builders/nxp.py | 43 ++++++++++++++++++- .../build/testdata/all_targets_linux_x64.txt | 2 +- 3 files changed, 47 insertions(+), 4 deletions(-) diff --git a/scripts/build/build/targets.py b/scripts/build/build/targets.py index c49d6201b6fb54..fb68a3276c705a 100755 --- a/scripts/build/build/targets.py +++ b/scripts/build/build/targets.py @@ -28,7 +28,7 @@ from builders.mw320 import MW320App, MW320Builder from builders.nrf import NrfApp, NrfBoard, NrfConnectBuilder from builders.nuttx import NuttXApp, NuttXBoard, NuttXBuilder -from builders.nxp import NxpApp, NxpBoard, NxpBoardVariant, NxpBuilder, NxpBuildSystem, NxpOsUsed +from builders.nxp import NxpApp, NxpBoard, NxpBoardVariant, NxpBuilder, NxpBuildSystem, NxpLogLevel, NxpOsUsed from builders.openiotsdk import OpenIotSdkApp, OpenIotSdkBuilder, OpenIotSdkCryptoBackend from builders.qpg import QpgApp, QpgBoard, QpgBuilder from builders.stm32 import stm32App, stm32Board, stm32Builder @@ -562,6 +562,10 @@ def BuildNxpTarget(): target.AppendModifier(name="iw416", iw416_transceiver=True).OnlyIfRe('rt1060') target.AppendModifier(name="w8801", w8801_transceiver=True).OnlyIfRe('rt1060') target.AppendModifier(name="iwx12", iwx12_transceiver=True).OnlyIfRe('rt1060|rt1170') + target.AppendModifier(name="log-all", log_level=NxpLogLevel.ALL).ExceptIfRe("-log-(progress|error|none)") + target.AppendModifier(name="log-progress", log_level=NxpLogLevel.PROGRESS).ExceptIfRe("-log-(all|error|none)") + target.AppendModifier(name="log-error", log_level=NxpLogLevel.ERROR).ExceptIfRe("-log-(progress|all|none)") + target.AppendModifier(name="log-none", log_level=NxpLogLevel.NONE).ExceptIfRe("-log-(progress|error|all)") return target diff --git a/scripts/build/builders/nxp.py b/scripts/build/builders/nxp.py index 6070a18fd0ba60..91155f20c96f7b 100644 --- a/scripts/build/builders/nxp.py +++ b/scripts/build/builders/nxp.py @@ -158,6 +158,14 @@ def BuildRoot(self, root, board, os_env): return os.path.join(root, 'examples', self.ExampleName(), 'nxp', board.FolderName(os_env)) +class NxpLogLevel(Enum): + DEFAULT = auto() # default everything + ALL = auto() # enable all logging + PROGRESS = auto() # progress and above + ERROR = auto() # error and above + NONE = auto() # no chip_logging at all + + class NxpBuilder(GnBuilder): def __init__(self, @@ -187,7 +195,9 @@ def __init__(self, disable_pairing_autostart: bool = False, iw416_transceiver: bool = False, w8801_transceiver: bool = False, - iwx12_transceiver: bool = False): + iwx12_transceiver: bool = False, + log_level: NxpLogLevel = NxpLogLevel.DEFAULT, + ): super(NxpBuilder, self).__init__( root=app.BuildRoot(root, board, os_env), runner=runner) @@ -217,12 +227,16 @@ def __init__(self, self.iw416_transceiver = iw416_transceiver self.w8801_transceiver = w8801_transceiver self.iwx12_transceiver = iwx12_transceiver + if self.low_power and log_level != NxpLogLevel.NONE: + logging.warning("Switching log level to 'NONE' for low power build") + log_level = NxpLogLevel.NONE + self.log_level = log_level def GnBuildArgs(self): args = [] if self.low_power: - args.append('chip_with_low_power=1 chip_logging=false') + args.append('chip_with_low_power=1') if self.board == NxpBoard.K32W0: args.append('chip_pw_tokenizer_logging=false chip_with_OM15082=0') @@ -244,6 +258,31 @@ def GnBuildArgs(self): if self.enable_rotating_id: args.append('chip_enable_rotating_device_id=1 chip_enable_additional_data_advertising=1') + if self.log_level == NxpLogLevel.DEFAULT: + pass + elif self.log_level == NxpLogLevel.ALL: + args.append("chip_logging=true") + args.append("chip_error_logging=true") + args.append("chip_progress_logging=true") + args.append("chip_detail_logging=true") + args.append("chip_automation_logging=true") + elif self.log_level == NxpLogLevel.PROGRESS: + args.append("chip_logging=true") + args.append("chip_error_logging=true") + args.append("chip_progress_logging=true") + args.append("chip_detail_logging=false") + args.append("chip_automation_logging=false") + elif self.log_level == NxpLogLevel.ERROR: + args.append("chip_logging=true") + args.append("chip_error_logging=true") + args.append("chip_progress_logging=false") + args.append("chip_detail_logging=false") + args.append("chip_automation_logging=false") + elif self.log_level == NxpLogLevel.NONE: + args.append("chip_logging=false") + else: + raise Exception("Unknown log level: %r", self.log_level) + if self.has_sw_version_2: args.append('nxp_software_version=2') diff --git a/scripts/build/testdata/all_targets_linux_x64.txt b/scripts/build/testdata/all_targets_linux_x64.txt index 3a1c592d2ae609..65755878191856 100644 --- a/scripts/build/testdata/all_targets_linux_x64.txt +++ b/scripts/build/testdata/all_targets_linux_x64.txt @@ -13,7 +13,7 @@ linux-{x64,arm64}-{rpc-console,all-clusters,all-clusters-minimal,chip-tool,therm linux-x64-efr32-test-runner[-clang] imx-{chip-tool,lighting-app,thermostat,all-clusters-app,all-clusters-minimal-app,ota-provider-app}[-release] infineon-psoc6-{lock,light,all-clusters,all-clusters-minimal}[-ota][-updateimage][-trustm] -nxp-{k32w0,k32w1,rt1060,rt1170,rw61x,rw61x_eth,mcxw71}-{zephyr,freertos}-{lighting,contact-sensor,lock-app,all-clusters,laundry-washer,thermostat}[-factory][-low-power][-lit][-fro32k][-smu2][-dac-conversion][-rotating-id][-sw-v2][-ota][-wifi][-ethernet][-thread][-matter-shell][-data-model-disabled][-data-model-enabled][-factory-build][-frdm][-cmake][-evkc][-iw416][-w8801][-iwx12] +nxp-{k32w0,k32w1,rt1060,rt1170,rw61x,rw61x_eth,mcxw71}-{zephyr,freertos}-{lighting,contact-sensor,lock-app,all-clusters,laundry-washer,thermostat}[-factory][-low-power][-lit][-fro32k][-smu2][-dac-conversion][-rotating-id][-sw-v2][-ota][-wifi][-ethernet][-thread][-matter-shell][-data-model-disabled][-data-model-enabled][-factory-build][-frdm][-cmake][-evkc][-iw416][-w8801][-iwx12][-log-all][-log-progress][-log-error][-log-none] mbed-cy8cproto_062_4343w-{lock,light,all-clusters,all-clusters-minimal,pigweed,ota-requestor,shell}[-release][-develop][-debug][-data-model-disabled][-data-model-enabled] mw320-all-clusters-app nrf-{nrf5340dk,nrf52840dk,nrf52840dongle}-{all-clusters,all-clusters-minimal,lock,light,light-switch,shell,pump,pump-controller,window-covering}[-rpc][-data-model-disabled][-data-model-enabled] From 728d1385e2a540963e9bead633e97d6fe7b6956b Mon Sep 17 00:00:00 2001 From: Alex Tsitsiura Date: Fri, 18 Oct 2024 18:11:55 +0300 Subject: [PATCH 039/149] [Telink] Reduce CI time (#36144) * [Telink] check affect of Checkout fetch-depth * [Telink] Skip some build in PRs --- .github/workflows/examples-telink.yaml | 30 ++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/.github/workflows/examples-telink.yaml b/.github/workflows/examples-telink.yaml index 64b3d6bb7c93ce..a1d7244ab8f02f 100644 --- a/.github/workflows/examples-telink.yaml +++ b/.github/workflows/examples-telink.yaml @@ -61,6 +61,8 @@ jobs: # run: scripts/run_in_build_env.sh "python3 scripts/tools/telink/update_zephyr.py 3ed7686a9378de6be1368c912f9a42f998bbfb18" - name: Build example Telink (B92 retention) Air Quality Sensor App + # Run test for master and s07641069 PRs + if: github.event.pull_request.number == null || github.event.pull_request.head.repo.full_name == 's07641069/connectedhomeip' run: | ./scripts/run_in_build_env.sh \ "./scripts/build/build_examples.py --target 'telink-tlsr9528a_retention-air-quality-sensor' build" @@ -73,6 +75,8 @@ jobs: run: rm -rf ./out - name: Build example Telink (W91) All Clusters App + # Run test for master and s07641069 PRs + if: github.event.pull_request.number == null || github.event.pull_request.head.repo.full_name == 's07641069/connectedhomeip' continue-on-error: true run: | ./scripts/run_in_build_env.sh \ @@ -86,6 +90,8 @@ jobs: run: rm -rf ./out - name: Build example Telink (B92) All Clusters Minimal App + # Run test for master and s07641069 PRs + if: github.event.pull_request.number == null || github.event.pull_request.head.repo.full_name == 's07641069/connectedhomeip' run: | ./scripts/run_in_build_env.sh \ "./scripts/build/build_examples.py --target 'telink-tlsr9528a-all-clusters-minimal' build" @@ -98,6 +104,7 @@ jobs: run: rm -rf ./out - name: Build example Telink (B95) Bridge App + # Run test for master and all PRs run: | ./scripts/run_in_build_env.sh \ "./scripts/build/build_examples.py --target 'telink-tlsr9258a-bridge' build" @@ -110,6 +117,7 @@ jobs: run: rm -rf ./out - name: Build example Telink (B92 retention) Contact Sensor App + # Run test for master and all PRs run: | ./scripts/run_in_build_env.sh \ "./scripts/build/build_examples.py --target 'telink-tlsr9528a_retention-contact-sensor' build" @@ -122,6 +130,7 @@ jobs: run: rm -rf ./out - name: Build tools required for Factory Data + # Run test for master and all PRs run: | ./scripts/checkout_submodules.py --allow-changing-global-git-config --shallow --platform linux ./scripts/build/gn_gen.sh @@ -132,6 +141,7 @@ jobs: run: rm -rf ./out/telink* - name: Build example Telink (W91) Lighting App with OTA, Factory Data + # Run test for master and all PRs continue-on-error: true run: | ./scripts/run_in_build_env.sh \ @@ -145,6 +155,7 @@ jobs: run: rm -rf ./out/telink* - name: Build example Telink (B91) Lighting App with OTA, RPC, Factory Data and 4Mb flash + # Run test for master and all PRs run: | ./scripts/run_in_build_env.sh \ "./scripts/build/build_examples.py --target 'telink-tlsr9518adk80d-light-ota-rpc-factory-data-4mb' build" @@ -157,6 +168,7 @@ jobs: run: rm -rf ./out/telink* - name: Build example Telink (B92) Light Switch App with OTA, Shell, Factory Data + # Run test for master and all PRs run: | ./scripts/run_in_build_env.sh \ "./scripts/build/build_examples.py --target 'telink-tlsr9528a-light-switch-ota-shell-factory-data' build" @@ -169,6 +181,8 @@ jobs: run: rm -rf ./out - name: Build example Telink (B92) Lock App with DFU + # Run test for master and s07641069 PRs + if: github.event.pull_request.number == null || github.event.pull_request.head.repo.full_name == 's07641069/connectedhomeip' run: | ./scripts/run_in_build_env.sh \ "./scripts/build/build_examples.py --target 'telink-tlsr9528a-lock-dfu' build" @@ -181,6 +195,8 @@ jobs: run: rm -rf ./out - name: Build example Telink (B95) OTA Requestor App + # Run test for master and s07641069 PRs + if: github.event.pull_request.number == null || github.event.pull_request.head.repo.full_name == 's07641069/connectedhomeip' run: | ./scripts/run_in_build_env.sh \ "./scripts/build/build_examples.py --target 'telink-tlsr9258a-ota-requestor' build" @@ -193,6 +209,8 @@ jobs: run: rm -rf ./out - name: Build example Telink (B91 USB) Pump App + # Run test for master and s07641069 PRs + if: github.event.pull_request.number == null || github.event.pull_request.head.repo.full_name == 's07641069/connectedhomeip' run: | ./scripts/run_in_build_env.sh \ "./scripts/build/build_examples.py --target 'telink-tlsr9518adk80d-pump-usb' build" @@ -205,6 +223,8 @@ jobs: run: rm -rf ./out - name: Build example Telink (B91) Pump Controller App + # Run test for master and s07641069 PRs + if: github.event.pull_request.number == null || github.event.pull_request.head.repo.full_name == 's07641069/connectedhomeip' run: | ./scripts/run_in_build_env.sh \ "./scripts/build/build_examples.py --target 'telink-tlsr9518adk80d-pump-controller' build" @@ -217,6 +237,8 @@ jobs: run: rm -rf ./out - name: Build example Telink (B91) Shell App + # Run test for master and s07641069 PRs + if: github.event.pull_request.number == null || github.event.pull_request.head.repo.full_name == 's07641069/connectedhomeip' run: | ./scripts/run_in_build_env.sh \ "./scripts/build/build_examples.py --target 'telink-tlsr9518adk80d-shell' build" @@ -229,6 +251,8 @@ jobs: run: rm -rf ./out - name: Build example Telink (B92 retention) Smoke CO Alarm App + # Run test for master and s07641069 PRs + if: github.event.pull_request.number == null || github.event.pull_request.head.repo.full_name == 's07641069/connectedhomeip' run: | ./scripts/run_in_build_env.sh \ "./scripts/build/build_examples.py --target 'telink-tlsr9528a_retention-smoke-co-alarm' build" @@ -241,6 +265,8 @@ jobs: run: rm -rf ./out - name: Build example Telink (B91 Mars) Temperature Measurement App with OTA + # Run test for master and s07641069 PRs + if: github.event.pull_request.number == null || github.event.pull_request.head.repo.full_name == 's07641069/connectedhomeip' run: | ./scripts/run_in_build_env.sh \ "./scripts/build/build_examples.py --target 'telink-tlsr9518adk80d-temperature-measurement-mars-ota' build" @@ -253,6 +279,8 @@ jobs: run: rm -rf ./out - name: Build example Telink (B91) Thermostat App + # Run test for master and s07641069 PRs + if: github.event.pull_request.number == null || github.event.pull_request.head.repo.full_name == 's07641069/connectedhomeip' run: | ./scripts/run_in_build_env.sh \ "./scripts/build/build_examples.py --target 'telink-tlsr9518adk80d-thermostat' build" @@ -265,6 +293,8 @@ jobs: run: rm -rf ./out - name: Build example Telink (W91) Window Covering App + # Run test for master and s07641069 PRs + if: github.event.pull_request.number == null || github.event.pull_request.head.repo.full_name == 's07641069/connectedhomeip' continue-on-error: true run: | ./scripts/run_in_build_env.sh \ From b79c6c6ff1ee6221570890c81593d3407cb96019 Mon Sep 17 00:00:00 2001 From: C Freeman Date: Fri, 18 Oct 2024 14:22:48 -0400 Subject: [PATCH 040/149] Documentation: more reorganization (#36100) * Documentation: Fix NXP index * Documentation: Fix up getting started ordering, names * Documentation: Fix up new cluster section names * Documentation: fix examples - group into sub-tables - un-smurf-name --- .../cluster_and_device_type_dev.md | 2 +- .../how_to_add_new_dts_and_clusters.md | 2 +- docs/cluster_and_device_type_dev/index.md | 2 +- docs/examples/air_purifier.md | 8 + docs/examples/air_quality.md | 8 + docs/examples/all_clusters.md | 8 + docs/examples/all_clusters_minimal.md | 8 + docs/examples/bridge.md | 8 + docs/examples/chef.md | 9 + docs/examples/chip_tool.md | 8 + docs/examples/contact_sensor.md | 8 + docs/examples/darwin.md | 8 + docs/examples/dishwasher.md | 8 + docs/examples/energy_management.md | 8 + docs/examples/fabric_admin.md | 8 + docs/examples/fabric_bridge.md | 8 + docs/examples/index.md | 387 +----------------- docs/examples/java_matter_controller.md | 8 + docs/examples/kotlin_matter_controller.md | 8 + docs/examples/laundry_washer.md | 8 + docs/examples/light_switch.md | 9 + docs/examples/lighting.md | 9 + docs/examples/lighting_no_unique_id.md | 8 + docs/examples/lit_icd.md | 8 + docs/examples/lock.md | 9 + docs/examples/log_source.md | 8 + docs/examples/microwave.md | 8 + docs/examples/minimal_mdns.md | 8 + .../network_infrastructure_manager.md | 8 + docs/examples/ota_provider.md | 8 + docs/examples/ota_requestor.md | 8 + docs/examples/persistent_storage.md | 9 + docs/examples/pigweed.md | 8 + docs/examples/pump.md | 8 + docs/examples/pump_controler.md | 8 + docs/examples/refrigerator.md | 8 + docs/examples/rvc.md | 8 + docs/examples/shell.md | 9 + docs/examples/smoke_co.md | 8 + docs/examples/tbr.md | 8 + docs/examples/temperature_measurement.md | 8 + docs/examples/thermostat.md | 9 + docs/examples/tv.md | 8 + docs/examples/tv_casting.md | 9 + docs/examples/virtual_device.md | 8 + docs/examples/window.md | 8 + docs/getting_started/SDKBasics.md | 2 +- docs/getting_started/first_example.md | 2 +- docs/getting_started/index.md | 7 +- docs/platforms/nxp/index.md | 15 +- 50 files changed, 366 insertions(+), 397 deletions(-) create mode 100644 docs/examples/air_purifier.md create mode 100644 docs/examples/air_quality.md create mode 100644 docs/examples/all_clusters.md create mode 100644 docs/examples/all_clusters_minimal.md create mode 100644 docs/examples/bridge.md create mode 100644 docs/examples/chef.md create mode 100644 docs/examples/chip_tool.md create mode 100644 docs/examples/contact_sensor.md create mode 100644 docs/examples/darwin.md create mode 100644 docs/examples/dishwasher.md create mode 100644 docs/examples/energy_management.md create mode 100644 docs/examples/fabric_admin.md create mode 100644 docs/examples/fabric_bridge.md create mode 100644 docs/examples/java_matter_controller.md create mode 100644 docs/examples/kotlin_matter_controller.md create mode 100644 docs/examples/laundry_washer.md create mode 100644 docs/examples/light_switch.md create mode 100644 docs/examples/lighting.md create mode 100644 docs/examples/lighting_no_unique_id.md create mode 100644 docs/examples/lit_icd.md create mode 100644 docs/examples/lock.md create mode 100644 docs/examples/log_source.md create mode 100644 docs/examples/microwave.md create mode 100644 docs/examples/minimal_mdns.md create mode 100644 docs/examples/network_infrastructure_manager.md create mode 100644 docs/examples/ota_provider.md create mode 100644 docs/examples/ota_requestor.md create mode 100644 docs/examples/persistent_storage.md create mode 100644 docs/examples/pigweed.md create mode 100644 docs/examples/pump.md create mode 100644 docs/examples/pump_controler.md create mode 100644 docs/examples/refrigerator.md create mode 100644 docs/examples/rvc.md create mode 100644 docs/examples/shell.md create mode 100644 docs/examples/smoke_co.md create mode 100644 docs/examples/tbr.md create mode 100644 docs/examples/temperature_measurement.md create mode 100644 docs/examples/thermostat.md create mode 100644 docs/examples/tv.md create mode 100644 docs/examples/tv_casting.md create mode 100644 docs/examples/virtual_device.md create mode 100644 docs/examples/window.md diff --git a/docs/cluster_and_device_type_dev/cluster_and_device_type_dev.md b/docs/cluster_and_device_type_dev/cluster_and_device_type_dev.md index e2460ff5a0a2b2..a19336a5939b73 100644 --- a/docs/cluster_and_device_type_dev/cluster_and_device_type_dev.md +++ b/docs/cluster_and_device_type_dev/cluster_and_device_type_dev.md @@ -1,4 +1,4 @@ -# New Clusters & Device Types +# Implementing New Clusters & Device Types The goal of new cluster and device type development is to diff --git a/docs/cluster_and_device_type_dev/how_to_add_new_dts_and_clusters.md b/docs/cluster_and_device_type_dev/how_to_add_new_dts_and_clusters.md index 90d82c60310a90..3e3704699d10f5 100644 --- a/docs/cluster_and_device_type_dev/how_to_add_new_dts_and_clusters.md +++ b/docs/cluster_and_device_type_dev/how_to_add_new_dts_and_clusters.md @@ -1,4 +1,4 @@ -# How to Add New Device Types & Clusters +# Adding new clusters and device types to the codegen This document outlines the process needed to add a new Matter device type and related clusters. Obviously, the steps below assume that the related Matter diff --git a/docs/cluster_and_device_type_dev/index.md b/docs/cluster_and_device_type_dev/index.md index cf43d02651378c..0ec65df347f9cd 100644 --- a/docs/cluster_and_device_type_dev/index.md +++ b/docs/cluster_and_device_type_dev/index.md @@ -13,5 +13,5 @@ types in the SDK. ``` - [Cluster and device type development](./cluster_and_device_type_dev.md) -- [How To Add New Device Types & Clusters](how_to_add_new_dts_and_clusters.md) +- [How To Add New Device Types & Clusters](./how_to_add_new_dts_and_clusters.md) - [Cluster Server design](./unit_testing_clusters.md) diff --git a/docs/examples/air_purifier.md b/docs/examples/air_purifier.md new file mode 100644 index 00000000000000..fbac74357fadd2 --- /dev/null +++ b/docs/examples/air_purifier.md @@ -0,0 +1,8 @@ +## Air Purifier + +```{toctree} +:glob: +:maxdepth: 1 + +air-purifier-app/**/README +``` diff --git a/docs/examples/air_quality.md b/docs/examples/air_quality.md new file mode 100644 index 00000000000000..2f6e43a7783709 --- /dev/null +++ b/docs/examples/air_quality.md @@ -0,0 +1,8 @@ +## Air Quality + +```{toctree} +:glob: +:maxdepth: 1 + +air-quality-sensor-app/**/README +``` diff --git a/docs/examples/all_clusters.md b/docs/examples/all_clusters.md new file mode 100644 index 00000000000000..f16a2723e88c05 --- /dev/null +++ b/docs/examples/all_clusters.md @@ -0,0 +1,8 @@ +## All clusters + +```{toctree} +:glob: +:maxdepth: 1 + +all-clusters-app/**/README +``` diff --git a/docs/examples/all_clusters_minimal.md b/docs/examples/all_clusters_minimal.md new file mode 100644 index 00000000000000..0000772c763dd5 --- /dev/null +++ b/docs/examples/all_clusters_minimal.md @@ -0,0 +1,8 @@ +## All clusters minimal + +```{toctree} +:glob: +:maxdepth: 1 + +all-clusters-minimal-app/**/README +``` diff --git a/docs/examples/bridge.md b/docs/examples/bridge.md new file mode 100644 index 00000000000000..fe4655da580ed0 --- /dev/null +++ b/docs/examples/bridge.md @@ -0,0 +1,8 @@ +## Bridge + +```{toctree} +:glob: +:maxdepth: 1 + +bridge-app/**/README +``` diff --git a/docs/examples/chef.md b/docs/examples/chef.md new file mode 100644 index 00000000000000..e17ea88b64d51e --- /dev/null +++ b/docs/examples/chef.md @@ -0,0 +1,9 @@ +## CHEF + +```{toctree} +:glob: +:maxdepth: 1 + +chef/README* +chef/**/README +``` diff --git a/docs/examples/chip_tool.md b/docs/examples/chip_tool.md new file mode 100644 index 00000000000000..8c9b74deabbdff --- /dev/null +++ b/docs/examples/chip_tool.md @@ -0,0 +1,8 @@ +## CHIP Tool example + +```{toctree} +:glob: +:maxdepth: 1 + +chip-tool/README +``` diff --git a/docs/examples/contact_sensor.md b/docs/examples/contact_sensor.md new file mode 100644 index 00000000000000..1daca03f007083 --- /dev/null +++ b/docs/examples/contact_sensor.md @@ -0,0 +1,8 @@ +## Contact Sensor + +```{toctree} +:glob: +:maxdepth: 1 + +contact-sensor-app/**/README +``` diff --git a/docs/examples/darwin.md b/docs/examples/darwin.md new file mode 100644 index 00000000000000..f16fca866a5376 --- /dev/null +++ b/docs/examples/darwin.md @@ -0,0 +1,8 @@ +## CHIP Tool Darwin + +```{toctree} +:glob: +:maxdepth: 1 + +darwin-framework-tool/README +``` diff --git a/docs/examples/dishwasher.md b/docs/examples/dishwasher.md new file mode 100644 index 00000000000000..7ceaa98791cff3 --- /dev/null +++ b/docs/examples/dishwasher.md @@ -0,0 +1,8 @@ +## Dishwasher + +```{toctree} +:glob: +:maxdepth: 1 + +dishwasher-app/**/README +``` diff --git a/docs/examples/energy_management.md b/docs/examples/energy_management.md new file mode 100644 index 00000000000000..dfec14dd68c651 --- /dev/null +++ b/docs/examples/energy_management.md @@ -0,0 +1,8 @@ +## Energy Management + +```{toctree} +:glob: +:maxdepth: 1 + +energy-management-app/**/README +``` diff --git a/docs/examples/fabric_admin.md b/docs/examples/fabric_admin.md new file mode 100644 index 00000000000000..fa47159c50a091 --- /dev/null +++ b/docs/examples/fabric_admin.md @@ -0,0 +1,8 @@ +## Fabric Admin + +```{toctree} +:glob: +:maxdepth: 1 + +fabric-admin/README +``` diff --git a/docs/examples/fabric_bridge.md b/docs/examples/fabric_bridge.md new file mode 100644 index 00000000000000..de08b59318662b --- /dev/null +++ b/docs/examples/fabric_bridge.md @@ -0,0 +1,8 @@ +## Fabric Bridge + +```{toctree} +:glob: +:maxdepth: 1 + +fabric-bridge-app/**/README +``` diff --git a/docs/examples/index.md b/docs/examples/index.md index 67dcfcf36b0e55..75118fa9335aad 100644 --- a/docs/examples/index.md +++ b/docs/examples/index.md @@ -1,390 +1,11 @@ # Examples -The Matter SDK provides examples of Matter devices for different development -platforms. - -## Air Quality Sensor example - -```{toctree} -:glob: -:maxdepth: 1 - -air-quality-sensor-app/**/README -``` - -## All clusters example - -```{toctree} -:glob: -:maxdepth: 1 - -all-clusters-app/**/README -``` - -## All clusters minimal example - -```{toctree} -:glob: -:maxdepth: 1 - -all-clusters-minimal-app/**/README -``` - -## Bridge example - -```{toctree} -:glob: -:maxdepth: 1 - -bridge-app/**/README -``` - -## Contact Sensor Example - -```{toctree} -:glob: -:maxdepth: 1 - -contact-sensor-app/**/README -``` - -## CHEF example - -```{toctree} -:glob: -:maxdepth: 1 - -chef/README* -chef/**/README -``` - -## CHIP Tool example - -```{toctree} -:glob: -:maxdepth: 1 - -chip-tool/README -``` - -## CHIP Tool Darwin example - -```{toctree} -:glob: -:maxdepth: 1 - -darwin-framework-tool/README -``` - -## Energy Management example - -```{toctree} -:glob: -:maxdepth: 1 - -energy-management-app/**/README -``` - -## Fabric Admin example - -```{toctree} -:glob: -:maxdepth: 1 - -fabric-admin/README -``` - -## Fabric Bridge example - -```{toctree} -:glob: -:maxdepth: 1 - -fabric-bridge-app/**/README -``` - -## Java matter controller example - -```{toctree} -:glob: -:maxdepth: 1 - -java-matter-controller/README -``` - -## Kotlin matter controller example - -```{toctree} -:glob: -:maxdepth: 1 - -kotlin-matter-controller/README -``` - -## Virtual Device App example - -```{toctree} -:glob: -:maxdepth: 1 - -virtual-device-app/**/README -``` - -## Laundry washer example - -```{toctree} -:glob: -:maxdepth: 1 - -laundry-washer-app/**/README -``` - -## Lighting example - ```{toctree} :glob: -:maxdepth: 1 +:maxdepth: 2 -lighting-app/**/README -lighting-app/qpg/APPLICATION +* ``` -## Lighting example without unique id - -```{toctree} -:glob: -:maxdepth: 1 - -lighting-app-data-mode-no-unique-id/**/README -``` - -## Light switch example - -```{toctree} -:glob: -:maxdepth: 1 - -light-switch-app/**/README -light-switch-app/qpg/APPLICATION -``` - -## Lock example - -```{toctree} -:glob: -:maxdepth: 1 - -lock-app/**/README -lock-app/qpg/APPLICATION -``` - -## Log source example - -```{toctree} -:glob: -:maxdepth: 1 - -log-source-app/**/README -``` - -## Minimal MDNS example - -```{toctree} -:glob: -:maxdepth: 1 - -minimal-mdns/README -``` - -## OTA Provider example - -```{toctree} -:glob: -:maxdepth: 1 - -ota-provider-app/**/README -``` - -## OTA Requestor example - -```{toctree} -:glob: -:maxdepth: 1 - -ota-requestor-app/**/README -``` - -## Persistent storage example - -```{toctree} -:glob: -:maxdepth: 1 - -persistent-storage/**/README -persistent-storage/**/APPLICATION -``` - -## Pigweed example - -```{toctree} -:glob: -:maxdepth: 1 - -pigweed-app/**/README -``` - -## Pump example - -```{toctree} -:glob: -:maxdepth: 1 - -pump-app/**/README -``` - -## Pump controller example - -```{toctree} -:glob: -:maxdepth: 1 - -pump-controller-app/**/README -``` - -## Refrigerator example - -```{toctree} -:glob: -:maxdepth: 1 - -refrigerator-app/**/README -``` - -## Shell example - -```{toctree} -:glob: -:maxdepth: 1 - -shell/README* -shell/**/README -``` - -## Smoke CO Alarm example - -```{toctree} -:glob: -:maxdepth: 1 - -smoke-co-alarm-app/**/README -``` - -## Dishwasher example - -```{toctree} -:glob: -:maxdepth: 1 - -dishwasher-app/**/README -``` - -## Microwave oven example - -```{toctree} -:glob: -:maxdepth: 1 - -microwave-oven-app/**/README -``` - -## Temperature measurement example - -```{toctree} -:glob: -:maxdepth: 1 - -temperature-measurement-app/**/README -``` - -## Thermostat example - -```{toctree} -:glob: -:maxdepth: 1 - -thermostat/**/README -thermostat/qpg/APPLICATION -``` - -## TV example - -```{toctree} -:glob: -:maxdepth: 1 - -tv-app/**/README -``` - -## TV casting example - -```{toctree} -:glob: -:maxdepth: 1 - -tv-casting-app/**/README -tv-casting-app/APIs.md -``` - -## Window example - -```{toctree} -:glob: -:maxdepth: 1 - -window-app/**/README -``` - -## RVC example - -```{toctree} -:glob: -:maxdepth: 1 - -rvc-app/README -``` - -## Air Purifier Example - -```{toctree} -:glob: -:maxdepth: 1 - -air-purifier-app/**/README -``` - -## Network Infrastructure Manager example - -```{toctree} -:glob: -:maxdepth: 1 - -network-manager-app/README -``` - -## Lit ICD example - -```{toctree} -:glob: -:maxdepth: 1 - -lit-icd-app/**/README -``` - -## Thread Border Router example - -```{toctree} -:glob: -:maxdepth: 1 - -thread-br-app/**/README -``` +The Matter SDK provides examples of Matter devices for different development +platforms. diff --git a/docs/examples/java_matter_controller.md b/docs/examples/java_matter_controller.md new file mode 100644 index 00000000000000..58af7cbf26729d --- /dev/null +++ b/docs/examples/java_matter_controller.md @@ -0,0 +1,8 @@ +## Java matter controller + +```{toctree} +:glob: +:maxdepth: 1 + +java-matter-controller/README +``` diff --git a/docs/examples/kotlin_matter_controller.md b/docs/examples/kotlin_matter_controller.md new file mode 100644 index 00000000000000..9241a1ef182131 --- /dev/null +++ b/docs/examples/kotlin_matter_controller.md @@ -0,0 +1,8 @@ +## Kotlin matter controller + +```{toctree} +:glob: +:maxdepth: 1 + +kotlin-matter-controller/README +``` diff --git a/docs/examples/laundry_washer.md b/docs/examples/laundry_washer.md new file mode 100644 index 00000000000000..3a522c8f821819 --- /dev/null +++ b/docs/examples/laundry_washer.md @@ -0,0 +1,8 @@ +## Laundry washer + +```{toctree} +:glob: +:maxdepth: 1 + +laundry-washer-app/**/README +``` diff --git a/docs/examples/light_switch.md b/docs/examples/light_switch.md new file mode 100644 index 00000000000000..1a887fc6b4ef6a --- /dev/null +++ b/docs/examples/light_switch.md @@ -0,0 +1,9 @@ +## Light switch + +```{toctree} +:glob: +:maxdepth: 1 + +light-switch-app/**/README +light-switch-app/qpg/APPLICATION +``` diff --git a/docs/examples/lighting.md b/docs/examples/lighting.md new file mode 100644 index 00000000000000..8870e50372c742 --- /dev/null +++ b/docs/examples/lighting.md @@ -0,0 +1,9 @@ +## Lighting + +```{toctree} +:glob: +:maxdepth: 1 + +lighting-app/**/README +lighting-app/qpg/APPLICATION +``` diff --git a/docs/examples/lighting_no_unique_id.md b/docs/examples/lighting_no_unique_id.md new file mode 100644 index 00000000000000..a71f9df5225b07 --- /dev/null +++ b/docs/examples/lighting_no_unique_id.md @@ -0,0 +1,8 @@ +## Lighting without unique id + +```{toctree} +:glob: +:maxdepth: 1 + +lighting-app-data-mode-no-unique-id/**/README +``` diff --git a/docs/examples/lit_icd.md b/docs/examples/lit_icd.md new file mode 100644 index 00000000000000..8678c44fcd743f --- /dev/null +++ b/docs/examples/lit_icd.md @@ -0,0 +1,8 @@ +## Lit ICD + +```{toctree} +:glob: +:maxdepth: 1 + +lit-icd-app/**/README +``` diff --git a/docs/examples/lock.md b/docs/examples/lock.md new file mode 100644 index 00000000000000..16ab19dc64b3d7 --- /dev/null +++ b/docs/examples/lock.md @@ -0,0 +1,9 @@ +## Lock + +```{toctree} +:glob: +:maxdepth: 1 + +lock-app/**/README +lock-app/qpg/APPLICATION +``` diff --git a/docs/examples/log_source.md b/docs/examples/log_source.md new file mode 100644 index 00000000000000..caec22654d0d60 --- /dev/null +++ b/docs/examples/log_source.md @@ -0,0 +1,8 @@ +## Log source + +```{toctree} +:glob: +:maxdepth: 1 + +log-source-app/**/README +``` diff --git a/docs/examples/microwave.md b/docs/examples/microwave.md new file mode 100644 index 00000000000000..c5f659f8733b79 --- /dev/null +++ b/docs/examples/microwave.md @@ -0,0 +1,8 @@ +## Microwave ovens + +```{toctree} +:glob: +:maxdepth: 1 + +microwave-oven-app/**/README +``` diff --git a/docs/examples/minimal_mdns.md b/docs/examples/minimal_mdns.md new file mode 100644 index 00000000000000..9d65b4dab23440 --- /dev/null +++ b/docs/examples/minimal_mdns.md @@ -0,0 +1,8 @@ +## Minimal MDNS + +```{toctree} +:glob: +:maxdepth: 1 + +minimal-mdns/README +``` diff --git a/docs/examples/network_infrastructure_manager.md b/docs/examples/network_infrastructure_manager.md new file mode 100644 index 00000000000000..bcc0591037e87f --- /dev/null +++ b/docs/examples/network_infrastructure_manager.md @@ -0,0 +1,8 @@ +## Network Infrastructure Manager + +```{toctree} +:glob: +:maxdepth: 1 + +network-manager-app/README +``` diff --git a/docs/examples/ota_provider.md b/docs/examples/ota_provider.md new file mode 100644 index 00000000000000..3470d9fe078bf8 --- /dev/null +++ b/docs/examples/ota_provider.md @@ -0,0 +1,8 @@ +## OTA Provider + +```{toctree} +:glob: +:maxdepth: 1 + +ota-provider-app/**/README +``` diff --git a/docs/examples/ota_requestor.md b/docs/examples/ota_requestor.md new file mode 100644 index 00000000000000..9cf5a75feafa4d --- /dev/null +++ b/docs/examples/ota_requestor.md @@ -0,0 +1,8 @@ +## OTA Requestor + +```{toctree} +:glob: +:maxdepth: 1 + +ota-requestor-app/**/README +``` diff --git a/docs/examples/persistent_storage.md b/docs/examples/persistent_storage.md new file mode 100644 index 00000000000000..5f5f5d17581282 --- /dev/null +++ b/docs/examples/persistent_storage.md @@ -0,0 +1,9 @@ +## Persistent storage + +```{toctree} +:glob: +:maxdepth: 1 + +persistent-storage/**/README +persistent-storage/**/APPLICATION +``` diff --git a/docs/examples/pigweed.md b/docs/examples/pigweed.md new file mode 100644 index 00000000000000..bf670bebd0cfa1 --- /dev/null +++ b/docs/examples/pigweed.md @@ -0,0 +1,8 @@ +## Pigweed + +```{toctree} +:glob: +:maxdepth: 1 + +pigweed-app/**/README +``` diff --git a/docs/examples/pump.md b/docs/examples/pump.md new file mode 100644 index 00000000000000..001a7df3fcf287 --- /dev/null +++ b/docs/examples/pump.md @@ -0,0 +1,8 @@ +## Pump + +```{toctree} +:glob: +:maxdepth: 1 + +pump-app/**/README +``` diff --git a/docs/examples/pump_controler.md b/docs/examples/pump_controler.md new file mode 100644 index 00000000000000..ff7f51f5ecb4ec --- /dev/null +++ b/docs/examples/pump_controler.md @@ -0,0 +1,8 @@ +## Pump controller + +```{toctree} +:glob: +:maxdepth: 1 + +pump-controller-app/**/README +``` diff --git a/docs/examples/refrigerator.md b/docs/examples/refrigerator.md new file mode 100644 index 00000000000000..455e8fe703b7cd --- /dev/null +++ b/docs/examples/refrigerator.md @@ -0,0 +1,8 @@ +## Refrigerator + +```{toctree} +:glob: +:maxdepth: 1 + +refrigerator-app/**/README +``` diff --git a/docs/examples/rvc.md b/docs/examples/rvc.md new file mode 100644 index 00000000000000..e0d033c4474eab --- /dev/null +++ b/docs/examples/rvc.md @@ -0,0 +1,8 @@ +## RVC + +```{toctree} +:glob: +:maxdepth: 1 + +rvc-app/README +``` diff --git a/docs/examples/shell.md b/docs/examples/shell.md new file mode 100644 index 00000000000000..3a0536a3dc8dfa --- /dev/null +++ b/docs/examples/shell.md @@ -0,0 +1,9 @@ +## Shell + +```{toctree} +:glob: +:maxdepth: 1 + +shell/README* +shell/**/README +``` diff --git a/docs/examples/smoke_co.md b/docs/examples/smoke_co.md new file mode 100644 index 00000000000000..9144276c7ac7e1 --- /dev/null +++ b/docs/examples/smoke_co.md @@ -0,0 +1,8 @@ +## Smoke CO Alarm example + +```{toctree} +:glob: +:maxdepth: 1 + +smoke-co-alarm-app/**/README +``` diff --git a/docs/examples/tbr.md b/docs/examples/tbr.md new file mode 100644 index 00000000000000..512a1132228b1d --- /dev/null +++ b/docs/examples/tbr.md @@ -0,0 +1,8 @@ +## Thread Border Router + +```{toctree} +:glob: +:maxdepth: 1 + +thread-br-app/**/README +``` diff --git a/docs/examples/temperature_measurement.md b/docs/examples/temperature_measurement.md new file mode 100644 index 00000000000000..cf8235b1d49611 --- /dev/null +++ b/docs/examples/temperature_measurement.md @@ -0,0 +1,8 @@ +## Temperature measurement + +```{toctree} +:glob: +:maxdepth: 1 + +temperature-measurement-app/**/README +``` diff --git a/docs/examples/thermostat.md b/docs/examples/thermostat.md new file mode 100644 index 00000000000000..8eb87892be665d --- /dev/null +++ b/docs/examples/thermostat.md @@ -0,0 +1,9 @@ +## Thermostat + +```{toctree} +:glob: +:maxdepth: 1 + +thermostat/**/README +thermostat/qpg/APPLICATION +``` diff --git a/docs/examples/tv.md b/docs/examples/tv.md new file mode 100644 index 00000000000000..ee97387402eadb --- /dev/null +++ b/docs/examples/tv.md @@ -0,0 +1,8 @@ +## TV + +```{toctree} +:glob: +:maxdepth: 1 + +tv-app/**/README +``` diff --git a/docs/examples/tv_casting.md b/docs/examples/tv_casting.md new file mode 100644 index 00000000000000..caeedf9e6dcaca --- /dev/null +++ b/docs/examples/tv_casting.md @@ -0,0 +1,9 @@ +## TV casting + +```{toctree} +:glob: +:maxdepth: 1 + +tv-casting-app/**/README +tv-casting-app/APIs.md +``` diff --git a/docs/examples/virtual_device.md b/docs/examples/virtual_device.md new file mode 100644 index 00000000000000..0b50f145033da1 --- /dev/null +++ b/docs/examples/virtual_device.md @@ -0,0 +1,8 @@ +## Virtual Device App + +```{toctree} +:glob: +:maxdepth: 1 + +virtual-device-app/**/README +``` diff --git a/docs/examples/window.md b/docs/examples/window.md new file mode 100644 index 00000000000000..2b4993641c9dbd --- /dev/null +++ b/docs/examples/window.md @@ -0,0 +1,8 @@ +## Window + +```{toctree} +:glob: +:maxdepth: 1 + +window-app/**/README +``` diff --git a/docs/getting_started/SDKBasics.md b/docs/getting_started/SDKBasics.md index 7f2c81f285fceb..eaad3baac81e8f 100644 --- a/docs/getting_started/SDKBasics.md +++ b/docs/getting_started/SDKBasics.md @@ -1,4 +1,4 @@ -# SDK Basics +# SDK Architecture Overview ## Getting Started diff --git a/docs/getting_started/first_example.md b/docs/getting_started/first_example.md index 14fe239749ab17..d75d9e7b1a4fee 100644 --- a/docs/getting_started/first_example.md +++ b/docs/getting_started/first_example.md @@ -1,4 +1,4 @@ -# An SDK example +# Compiling, Running, and Controlling Matter examples The SDK provides a number of example devices and controllers that can be used to familiarize yourself with the SDK and the Matter ecosystem. diff --git a/docs/getting_started/index.md b/docs/getting_started/index.md index 098f047ed75393..1bfbe3f57cc333 100644 --- a/docs/getting_started/index.md +++ b/docs/getting_started/index.md @@ -7,11 +7,14 @@ The following docs are a brief introduction to SDK development. :maxdepth: 1 :hidden: -* +first_example +changing_examples +SDKBasics +zap ``` - [Running your first example](./first_example.md) - [Changing examples](./changing_examples.md) -- [SDK Architecture Introduction](./SDKBasics.md) +- [SDK Architecture Overview](./SDKBasics.md) - [ZAP Introduction](./zap.md) diff --git a/docs/platforms/nxp/index.md b/docs/platforms/nxp/index.md index fc11ed78b2baff..844dc40194cebb 100644 --- a/docs/platforms/nxp/index.md +++ b/docs/platforms/nxp/index.md @@ -1,14 +1,15 @@ +# NXP + ```{toctree} :glob: :maxdepth: 1 +:hidden: * ``` -# NXP Getting Started Guide - -- [NXP - Android Commissioning](nxp_k32w_android_commissioning.md) -- [NXP - Linux Examples](nxp_imx8m_linux_examples.md) -- [NXP - Manufacturing Data](nxp_manufacturing_flow.md) -- [NXP - RTs OTA Software Update Guide](nxp_RTs_ota_software_update.md) -- [NXP - Zephyr OTA Software Update Guide](nxp_zephyr_ota_software_update.md) +- [NXP - Android Commissioning](./nxp_k32w_android_commissioning.md) +- [NXP - Linux Examples](./nxp_imx8m_linux_examples.md) +- [NXP - Manufacturing Data](./nxp_manufacturing_flow.md) +- [NXP - RTs OTA Software Update Guide](./nxp_RTs_ota_software_update.md) +- [NXP - Zephyr OTA Software Update Guide](./nxp_zephyr_ota_software_update.md From 1f4e81eeb63c00d4442bf383e35c0f8d703f3911 Mon Sep 17 00:00:00 2001 From: Mathieu Kardous <84793247+mkardous-silabs@users.noreply.github.com> Date: Fri, 18 Oct 2024 14:52:53 -0400 Subject: [PATCH 041/149] Update docker image to pull latest simplicity sdk (#36148) --- integrations/docker/images/base/chip-build/version | 2 +- .../docker/images/stage-2/chip-build-efr32/Dockerfile | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/integrations/docker/images/base/chip-build/version b/integrations/docker/images/base/chip-build/version index 9ce87dc9432ce1..c79147db54915d 100644 --- a/integrations/docker/images/base/chip-build/version +++ b/integrations/docker/images/base/chip-build/version @@ -1 +1 @@ -84 : [Silabs] Update Silabs docker WiseConnect-wifi-bt-sdk 2.10.3 \ No newline at end of file +85 : [Silabs] Update Silabs docker Simplicity SDK v2024.6.2 \ No newline at end of file diff --git a/integrations/docker/images/stage-2/chip-build-efr32/Dockerfile b/integrations/docker/images/stage-2/chip-build-efr32/Dockerfile index 230a5bbb1fd1d0..3d65e2c52fa606 100644 --- a/integrations/docker/images/stage-2/chip-build-efr32/Dockerfile +++ b/integrations/docker/images/stage-2/chip-build-efr32/Dockerfile @@ -13,8 +13,8 @@ RUN set -x \ && : # last line -# Download Simplicity SDK v2024.6.1 (a1a37fa) -RUN wget https://github.com/SiliconLabs/simplicity_sdk/releases/download/v2024.6.1-0/sisdk-sdk.zip -O /tmp/simplicity_sdk.zip \ +# Download Simplicity SDK v2024.6.2 (36e12f0) +RUN wget https://github.com/SiliconLabs/simplicity_sdk/releases/download/v2024.6.2/gecko-sdk.zip -O /tmp/simplicity_sdk.zip \ && unzip /tmp/simplicity_sdk.zip -d /tmp/simplicity_sdk \ && rm -rf /tmp/simplicity_sdk.zip \ # Deleting files that are not needed to save space From 00bd8285490ea94c9d647f3a4a6b520473dc94b9 Mon Sep 17 00:00:00 2001 From: C Freeman Date: Fri, 18 Oct 2024 15:36:42 -0400 Subject: [PATCH 042/149] TC-DESC-2.2: Fix comparison when mfg label is in the list (#35849) * TC-DESC-2.2: Fix comparison when mfg label is in the list Unit tests included, also tested on an example app with mfg tags * linter * Restyled by isort --------- Co-authored-by: Restyled.io --- src/python_testing/TestMatterTestingSupport.py | 8 ++++++++ .../chip/testing/taglist_and_topology_test.py | 5 +++++ 2 files changed, 13 insertions(+) diff --git a/src/python_testing/TestMatterTestingSupport.py b/src/python_testing/TestMatterTestingSupport.py index 811349b3a96f6c..d39c869456e8f9 100644 --- a/src/python_testing/TestMatterTestingSupport.py +++ b/src/python_testing/TestMatterTestingSupport.py @@ -549,6 +549,14 @@ def test_tag_list_problems(self): problems = find_tag_list_problems(roots, device_types, simple) asserts.assert_equal(len(problems), 0, "Unexpected problems found in list") + # Tags with mfg tags + tag_mfg = Clusters.Descriptor.Structs.SemanticTagStruct(mfgCode=0xFFF1, label="test") + tag_label = Clusters.Descriptor.Structs.SemanticTagStruct(tag=1, label="test") + simple[1][Clusters.Descriptor][Clusters.Descriptor.Attributes.TagList] = [tag1, tag_mfg] + simple[2][Clusters.Descriptor][Clusters.Descriptor.Attributes.TagList] = [tag1, tag_label] + problems = find_tag_list_problems(roots, device_types, simple) + asserts.assert_equal(len(problems), 0, "Unexpected problems found in list") + def test_root_node_tag_list_functions(self): # Example topology - see comment above for the layout. # There are 4 direct children of root 0 diff --git a/src/python_testing/matter_testing_infrastructure/chip/testing/taglist_and_topology_test.py b/src/python_testing/matter_testing_infrastructure/chip/testing/taglist_and_topology_test.py index bf5c085bf84d12..eb0ab1289ee183 100644 --- a/src/python_testing/matter_testing_infrastructure/chip/testing/taglist_and_topology_test.py +++ b/src/python_testing/matter_testing_infrastructure/chip/testing/taglist_and_topology_test.py @@ -21,6 +21,7 @@ from typing import Any import chip.clusters as Clusters +from chip.clusters.Types import Nullable @dataclass @@ -143,12 +144,16 @@ def create_device_type_list_for_root(direct_children, endpoint_dict: dict[int, A def cmp_tag_list(a: Clusters.Descriptor.Structs.SemanticTagStruct, b: Clusters.Descriptor.Structs.SemanticTagStruct): + if type(a.mfgCode) != type(b.mfgCode): + return -1 if type(a.mfgCode) is Nullable else 1 if a.mfgCode != b.mfgCode: return -1 if a.mfgCode < b.mfgCode else 1 if a.namespaceID != b.namespaceID: return -1 if a.namespaceID < b.namespaceID else 1 if a.tag != b.tag: return -1 if a.tag < b.tag else 1 + if type(a.label) != type(b.label): + return -1 if type(a.label) is Nullable or a.label is None else 1 if a.label != b.label: return -1 if a.label < b.label else 1 return 0 From 29a567eaf5e0cbbcbb05b5b4c43c57b7efe9c559 Mon Sep 17 00:00:00 2001 From: feasel <120589145+feasel0@users.noreply.github.com> Date: Fri, 18 Oct 2024 17:04:27 -0400 Subject: [PATCH 043/149] Re-enabling unit tests for EFR32 which had been disabled due to flash limitations (#35456) * Removed as many efr32 checks as possible without having to make code modifications * Updated comments to show error message * Restyled by clang-format * Comment updates * ci testing 1 * Re-added suites * . * . * comment icd tests * removed 5 tests from line 112 * re-enable app/tests in the main tests group * reverted to original (with inconsequential mods) * (addendum) Now actually reverted back to original state (with inconsequential mods) * moved 4 dirs up into the main tests lists * enabled 3-test-set for efr32 * moved tracing tests out of the if * enable platform tests for efr32 * enabled controller and datamodel tests but not the stuff in controller * enabled all tests in controller * add transport tests back in * enabled data_model Test[Commands,Read,Write] * commands is in, read/write is out * added TestRead * Added TestWrite, removed TestRead * src/app/tests remains disabled * changed c-style cast to static_cast * Added TestTLVVectorWriter.cpp back in * comment update * restyle fixes * restyle fixes --------- Co-authored-by: Restyled.io --- src/BUILD.gn | 43 ++++++++++------------ src/controller/tests/BUILD.gn | 32 ++++++++++------ src/controller/tests/TestReadChunking.cpp | 2 +- src/controller/tests/TestWriteChunking.cpp | 2 +- src/controller/tests/data_model/BUILD.gn | 8 ++-- src/lib/core/tests/BUILD.gn | 7 +--- src/transport/tests/BUILD.gn | 5 +-- 7 files changed, 51 insertions(+), 48 deletions(-) diff --git a/src/BUILD.gn b/src/BUILD.gn index e70025151c852b..722e0c8278582a 100644 --- a/src/BUILD.gn +++ b/src/BUILD.gn @@ -50,21 +50,25 @@ if (chip_build_tests) { chip_test_group("tests") { deps = [] tests = [ + "${chip_root}/src/access/tests", "${chip_root}/src/app/data-model/tests", "${chip_root}/src/app/cluster-building-blocks/tests", "${chip_root}/src/app/data-model-provider/tests", - "${chip_root}/src/access/tests", + "${chip_root}/src/app/icd/server/tests", "${chip_root}/src/crypto/tests", "${chip_root}/src/inet/tests", "${chip_root}/src/lib/address_resolve/tests", "${chip_root}/src/lib/asn1/tests", "${chip_root}/src/lib/core/tests", + "${chip_root}/src/lib/format/tests", "${chip_root}/src/messaging/tests", "${chip_root}/src/protocols/bdx/tests", "${chip_root}/src/protocols/interaction_model/tests", + "${chip_root}/src/protocols/secure_channel/tests", "${chip_root}/src/protocols/user_directed_commissioning/tests", + "${chip_root}/src/system/tests", "${chip_root}/src/transport/retransmit/tests", - "${chip_root}/src/app/icd/server/tests", + "${chip_root}/src/transport/tests", ] # Skip DNSSD tests for Mbed platform due to flash memory size limitations @@ -81,14 +85,12 @@ if (chip_build_tests) { tests += [ "${chip_root}/src/lib/dnssd/minimal_mdns/records/tests" ] } - if (current_os != "zephyr" && current_os != "mbed" && - chip_device_platform != "efr32") { + if (current_os != "zephyr" && current_os != "mbed") { # Avoid these items from "one single binary" test executions. Once tests - # are split, we can re-visit this (and likely many others) + # are split, we can re-visit this (and likely many others). # - # In particular: - # "app/codegen-data-model-provider/tests" contains symbols for ember mocks which - # are used by other tests + # In particular: "app/codegen-data-model-provider/tests" contains + # symbols for ember mocks which are used by other tests. tests += [ "${chip_root}/src/app/codegen-data-model-provider/tests", @@ -97,30 +99,27 @@ if (chip_build_tests) { ] } - # Skip on efr32 due to flash and/or ram limitations. if (chip_device_platform != "efr32") { + tests += [ "${chip_root}/src/app/tests" ] + + # Disabled for EFR32 because _open is not implemented. + # https://github.com/project-chip/connectedhomeip/issues/35624 tests += [ - "${chip_root}/src/app/tests", "${chip_root}/src/credentials/tests", - "${chip_root}/src/lib/format/tests", "${chip_root}/src/lib/support/tests", - "${chip_root}/src/protocols/secure_channel/tests", - "${chip_root}/src/system/tests", - "${chip_root}/src/transport/tests", ] + } - if (matter_enable_tracing_support && - matter_trace_config == "${chip_root}/src/tracing/multiplexed") { - tests += [ "${chip_root}/src/tracing/tests" ] - } + if (matter_enable_tracing_support && + matter_trace_config == "${chip_root}/src/tracing/multiplexed") { + tests += [ "${chip_root}/src/tracing/tests" ] } if (chip_device_platform != "none") { tests += [ "${chip_root}/src/lib/dnssd/minimal_mdns/tests" ] } - if (chip_device_platform != "esp32" && chip_device_platform != "efr32" && - chip_device_platform != "ameba") { + if (chip_device_platform != "esp32" && chip_device_platform != "ameba") { tests += [ "${chip_root}/src/platform/tests" ] } @@ -130,9 +129,7 @@ if (chip_build_tests) { # On nrfconnect, the controller tests run into # https://github.com/project-chip/connectedhomeip/issues/9630 - if (chip_device_platform != "nrfconnect" && - chip_device_platform != "efr32") { - # Doesn't compile on ef32. Multiple definitions issues with attribute storage and overflows flash memory. + if (chip_device_platform != "nrfconnect") { tests += [ "${chip_root}/src/controller/tests/data_model" ] # Skip controller test for Open IoT SDK diff --git a/src/controller/tests/BUILD.gn b/src/controller/tests/BUILD.gn index a1d7b9433075b7..a7389c59ae569e 100644 --- a/src/controller/tests/BUILD.gn +++ b/src/controller/tests/BUILD.gn @@ -21,17 +21,27 @@ import("${chip_root}/build/chip/chip_test_suite.gni") chip_test_suite("tests") { output_name = "libControllerTests" - test_sources = [ "TestCommissionableNodeController.cpp" ] - - if (chip_device_platform != "mbed" && chip_device_platform != "efr32" && - chip_device_platform != "esp32") { - test_sources += [ "TestServerCommandDispatch.cpp" ] - test_sources += [ "TestEventChunking.cpp" ] - test_sources += [ "TestEventCaching.cpp" ] - test_sources += [ "TestReadChunking.cpp" ] - test_sources += [ "TestWriteChunking.cpp" ] - test_sources += [ "TestEventNumberCaching.cpp" ] - test_sources += [ "TestCommissioningWindowOpener.cpp" ] + test_sources = [] + + # Not supported on efr32. + if (chip_device_platform != "efr32") { + test_sources += [ "TestCommissionableNodeController.cpp" ] + } + + if (chip_device_platform != "mbed" && chip_device_platform != "esp32") { + test_sources += [ + "TestEventCaching.cpp", + "TestEventChunking.cpp", + "TestEventNumberCaching.cpp", + "TestReadChunking.cpp", + "TestServerCommandDispatch.cpp", + "TestWriteChunking.cpp", + ] + + # Not supported on efr32. + if (chip_device_platform != "efr32") { + test_sources += [ "TestCommissioningWindowOpener.cpp" ] + } } cflags = [ "-Wconversion" ] diff --git a/src/controller/tests/TestReadChunking.cpp b/src/controller/tests/TestReadChunking.cpp index 4f2251b857b259..989d91005290fe 100644 --- a/src/controller/tests/TestReadChunking.cpp +++ b/src/controller/tests/TestReadChunking.cpp @@ -576,7 +576,7 @@ TEST_F(TestReadChunking, TestListChunking) { TestReadCallback readCallback; - ChipLogDetail(DataManagement, "Running iteration %d\n", packetSize); + ChipLogDetail(DataManagement, "Running iteration %d\n", static_cast(packetSize)); gIterationCount = packetSize; diff --git a/src/controller/tests/TestWriteChunking.cpp b/src/controller/tests/TestWriteChunking.cpp index 5bb7ef95214ce9..4efc09818694e2 100644 --- a/src/controller/tests/TestWriteChunking.cpp +++ b/src/controller/tests/TestWriteChunking.cpp @@ -231,7 +231,7 @@ TEST_F(TestWriteChunking, TestListChunking) CHIP_ERROR err = CHIP_NO_ERROR; TestWriteCallback writeCallback; - ChipLogDetail(DataManagement, "Running iteration %d\n", i); + ChipLogDetail(DataManagement, "Running iteration %d\n", static_cast(i)); gIterationCount = i; diff --git a/src/controller/tests/data_model/BUILD.gn b/src/controller/tests/data_model/BUILD.gn index 9bf2eac9391bac..ca0f8a30afede3 100644 --- a/src/controller/tests/data_model/BUILD.gn +++ b/src/controller/tests/data_model/BUILD.gn @@ -29,13 +29,15 @@ chip_test_suite("data_model") { ] test_sources = [] - if (chip_device_platform != "mbed" && chip_device_platform != "efr32" && - chip_device_platform != "esp32" && chip_device_platform != "fake") { + if (chip_device_platform != "mbed" && chip_device_platform != "esp32" && + chip_device_platform != "fake") { test_sources += [ "TestCommands.cpp", - "TestRead.cpp", "TestWrite.cpp", ] + if (chip_device_platform != "efr32") { + test_sources += [ "TestRead.cpp" ] + } } public_deps = [ diff --git a/src/lib/core/tests/BUILD.gn b/src/lib/core/tests/BUILD.gn index 264de2c8aafe6b..fd00915c595427 100644 --- a/src/lib/core/tests/BUILD.gn +++ b/src/lib/core/tests/BUILD.gn @@ -31,14 +31,9 @@ chip_test_suite("tests") { "TestOptional.cpp", "TestReferenceCounted.cpp", "TestTLV.cpp", + "TestTLVVectorWriter.cpp", ] - # requires large amount of heap for multiple unfragmented 10k buffers - # skip for efr32 to allow flash space for other tests - if (chip_device_platform != "efr32") { - test_sources += [ "TestTLVVectorWriter.cpp" ] - } - cflags = [ "-Wconversion" ] public_deps = [ diff --git a/src/transport/tests/BUILD.gn b/src/transport/tests/BUILD.gn index f0be95ff5ac8dd..3736f8b69cef3e 100644 --- a/src/transport/tests/BUILD.gn +++ b/src/transport/tests/BUILD.gn @@ -44,9 +44,8 @@ chip_test_suite("tests") { "TestSessionManagerDispatch.cpp", ] - if (chip_device_platform != "mbed" && chip_device_platform != "efr32" && - chip_device_platform != "esp32" && chip_device_platform != "nrfconnect" && - chip_device_platform != "nxp") { + if (chip_device_platform != "mbed" && chip_device_platform != "esp32" && + chip_device_platform != "nrfconnect" && chip_device_platform != "nxp") { test_sources += [ "TestSecureSessionTable.cpp" ] } From 909960876ad3ae461c63b185f34cd64220ac0322 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Fri, 18 Oct 2024 18:14:05 -0400 Subject: [PATCH 044/149] Improve the unit tests for MTRCertificateInfo.publicKeyData. (#36150) Checks the value, not just that there is a value. --- .../CHIPTests/MTRCertificateInfoTests.m | 25 ++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/darwin/Framework/CHIPTests/MTRCertificateInfoTests.m b/src/darwin/Framework/CHIPTests/MTRCertificateInfoTests.m index 8a532a8e3300dc..29af62d9a63798 100644 --- a/src/darwin/Framework/CHIPTests/MTRCertificateInfoTests.m +++ b/src/darwin/Framework/CHIPTests/MTRCertificateInfoTests.m @@ -58,10 +58,22 @@ - (MTRCertificateTLVBytes)exampleRCACertTLV options:0]; } +- (NSData *)exampleRCACertPublicKey +{ + // Needs to match the "Public Key" listed above. + const unsigned char publicKeyBytes[] = "\x04\x61\xE7\x5C\xFE\x03\xEC\x90\x5E\xF4\x53\x77\xE5\xF4\xB5\x1D" + "\xE4\x3D\x55\xF4\xD4\xE7\xEA\x7B\x22\x76\x5E\x59\xCA\x0A\x9B\xDB" + "\x59\x8F\x69\xDB\x12\x8B\xFB\x35\xBF\x03\x1F\xE9\x51\xED\x53\x37" + "\x5D\x35\xB0\x53\x22\xF4\xDF\x7E\xBA\xEC\x02\xAC\x52\xF3\x1B\x9A" + "\xD7"; + return [NSData dataWithBytes:publicKeyBytes length:sizeof(publicKeyBytes) - 1]; +} + - (void)testParseRootCertificateTLV { MTRCertificateInfo * info = [[MTRCertificateInfo alloc] initWithTLVBytes:self.exampleRCACertTLV]; XCTAssertNotNil(info); + XCTAssertEqualObjects(info.publicKeyData, self.exampleRCACertPublicKey); XCTAssertEqual([NSDate.now compare:info.notBefore], NSOrderedDescending); XCTAssertEqual([NSDate.now compare:info.notAfter], NSOrderedAscending); @@ -113,11 +125,22 @@ - (MTRCertificateTLVBytes)exampleNOCertTLV options:0]; } +- (NSData *)exampleNOCertPublicKey +{ + // Needs to match the "Public Key" listed above. + const unsigned char publicKeyBytes[] = "\x04\xFD\x7F\x7A\x19\x37\xE0\x6D\xA4\xC2\xC9\x95\xC5\x5F\x01\x10" + "\xD2\xB0\xFC\x93\x50\x4C\x4A\x2A\xD5\x65\x90\x8B\x42\x7C\xAF\x60" + "\x4A\x1C\x24\xF9\xC1\x75\x61\x4C\x45\xDC\x87\x34\x0F\xB4\x1C\x24" + "\xD2\x40\x11\x3F\x82\x6D\x8B\x2A\x24\x0E\xE4\xA5\x9B\x30\xC6\xA9" + "\x51"; + return [NSData dataWithBytes:publicKeyBytes length:sizeof(publicKeyBytes) - 1]; +} + - (void)testParseOperationalCertificateTLV { MTRCertificateInfo * info = [[MTRCertificateInfo alloc] initWithTLVBytes:self.exampleNOCertTLV]; XCTAssertNotNil(info); - XCTAssertNotNil(info.publicKeyData); + XCTAssertEqualObjects(info.publicKeyData, self.exampleNOCertPublicKey); XCTAssertEqual([NSDate.now compare:info.notBefore], NSOrderedDescending); XCTAssertEqual([NSDate.now compare:info.notAfter], NSOrderedAscending); From 14a98e9ab9d28e73367a9ce0ac574dc9dd6ce5e7 Mon Sep 17 00:00:00 2001 From: Yufeng Wang Date: Fri, 18 Oct 2024 16:11:53 -0700 Subject: [PATCH 045/149] [Fabric-Sync] Initial version of fabric-sync example (#36136) * [Fabric-Sync] Initial version of fabric-sync example * Add Readme.txt * Remove unused define flag --- docs/examples/fabric_sync.md | 8 + examples/fabric-sync/.gn | 25 + examples/fabric-sync/BUILD.gn | 45 + examples/fabric-sync/README.md | 104 + examples/fabric-sync/args.gni | 40 + examples/fabric-sync/bridge/BUILD.gn | 50 + .../fabric-sync/bridge/fabric-bridge.matter | 2108 ++++++++ examples/fabric-sync/bridge/fabric-bridge.zap | 4474 +++++++++++++++++ .../bridge/include/CHIPProjectAppConfig.h | 80 + examples/fabric-sync/build_overrides | 1 + examples/fabric-sync/main.cpp | 41 + .../fabric-sync/third_party/connectedhomeip | 1 + 12 files changed, 6977 insertions(+) create mode 100644 docs/examples/fabric_sync.md create mode 100644 examples/fabric-sync/.gn create mode 100644 examples/fabric-sync/BUILD.gn create mode 100644 examples/fabric-sync/README.md create mode 100644 examples/fabric-sync/args.gni create mode 100644 examples/fabric-sync/bridge/BUILD.gn create mode 100644 examples/fabric-sync/bridge/fabric-bridge.matter create mode 100644 examples/fabric-sync/bridge/fabric-bridge.zap create mode 100644 examples/fabric-sync/bridge/include/CHIPProjectAppConfig.h create mode 120000 examples/fabric-sync/build_overrides create mode 100644 examples/fabric-sync/main.cpp create mode 120000 examples/fabric-sync/third_party/connectedhomeip diff --git a/docs/examples/fabric_sync.md b/docs/examples/fabric_sync.md new file mode 100644 index 00000000000000..269448f8cf661e --- /dev/null +++ b/docs/examples/fabric_sync.md @@ -0,0 +1,8 @@ +## Fabric Sync + +```{toctree} +:glob: +:maxdepth: 1 + +fabric-sync/README +``` diff --git a/examples/fabric-sync/.gn b/examples/fabric-sync/.gn new file mode 100644 index 00000000000000..3b11e2ba2e62ee --- /dev/null +++ b/examples/fabric-sync/.gn @@ -0,0 +1,25 @@ +# Copyright (c) 2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/build.gni") + +# The location of the build configuration file. +buildconfig = "${build_root}/config/BUILDCONFIG.gn" + +# CHIP uses angle bracket includes. +check_system_includes = true + +default_args = { + import("//args.gni") +} diff --git a/examples/fabric-sync/BUILD.gn b/examples/fabric-sync/BUILD.gn new file mode 100644 index 00000000000000..de193bd5f6207a --- /dev/null +++ b/examples/fabric-sync/BUILD.gn @@ -0,0 +1,45 @@ +# Copyright (c) 2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/build.gni") +import("//build_overrides/chip.gni") +import("${chip_root}/build/chip/tools.gni") +import("${chip_root}/src/lib/lib.gni") + +assert(chip_build_tools) + +executable("fabric-sync") { + cflags = [ "-Wconversion" ] + + include_dirs = [ + ".", + "${chip_root}/src/lib", + ] + + sources = [ "main.cpp" ] + + deps = [ + "${chip_root}/examples/fabric-sync/bridge:fabric-bridge-lib", + "${chip_root}/examples/fabric-sync/bridge:fabric-bridge-zap", + "${chip_root}/examples/platform/linux:app-main", + "${chip_root}/src/lib", + "${chip_root}/third_party/inipp", + ] + + output_dir = root_out_dir +} + +group("default") { + deps = [ ":fabric-sync" ] +} diff --git a/examples/fabric-sync/README.md b/examples/fabric-sync/README.md new file mode 100644 index 00000000000000..dd24d3794457c2 --- /dev/null +++ b/examples/fabric-sync/README.md @@ -0,0 +1,104 @@ +# Matter Linux Fabric Sync Example + +An example application to implement the Fabric Synchronization feature and +demonstrates the end-to-end Fabric Synchronization feature using dynamic +endpoints. + +Fabric Synchronization feature will facilitate the commissioning of end devices +from one fabric to another without requiring user intervention for every end +device. It defines mechanisms that can be used by multiple +ecosystems/controllers to communicate with one another to simplify the +experience for users. + +This doc is tested on **Ubuntu 22.04 LTS (aarch64)** + +


    + +- [Matter Linux Fabric Sync Example](#matter-linux-fabric-sync-example) + - [Theory of Operation](#theory-of-operation) + - [Building](#building) + - [Running the Complete Example on Ubuntu](#running-the-complete-example-on-ubuntu) + +
    + +## Theory of Operation + +### Dynamic Endpoints + +The Fabric-Sync Example makes use of Dynamic Endpoints. Current SDK support is +limited for dynamic endpoints, since endpoints are typically defined (along with +the clusters and attributes they contain) in a .zap file which then generates +code and static structures to define the endpoints. + +To support endpoints that are not statically defined, the ZCL attribute storage +mechanisms will hold additional endpoint information for `NUM_DYNAMIC_ENDPOINTS` +additional endpoints. These additional endpoint structures must be defined by +the application and can change at runtime. + +To facilitate the creation of these endpoint structures, several macros are +defined: + +`DECLARE_DYNAMIC_ATTRIBUTE_LIST_BEGIN(attrListName)` +`DECLARE_DYNAMIC_ATTRIBUTE(attId, attType, attSizeBytes, attrMask)` +`DECLARE_DYNAMIC_ATTRIBUTE_LIST_END(clusterRevision)` + +- These three macros are used to declare a list of attributes for use within a + cluster. The declaration must begin with the + `DECLARE_DYNAMIC_ATTRIBUTE_LIST_BEGIN` macro which will define the name of + the allocated attribute structure. Each attribute is then added by the + `DECLARE_DYNAMIC_ATTRIBUTE` macro. Finally, + `DECLARE_DYNAMIC_ATTRIBUTE_LIST_END` macro should be used to close the + definition. + +- All attributes defined with these macros will be configured as + `ATTRIBUTE_MASK_EXTERNAL_STORAGE` in the ZCL database and therefore will + rely on the application to maintain storage for the attribute. Consequently, + reads or writes to these attributes must be handled within the application + by the `emberAfExternalAttributeWriteCallback` and + `emberAfExternalAttributeReadCallback` functions. See the bridge + application's `main.cpp` for an example of this implementation. + +`DECLARE_DYNAMIC_CLUSTER_LIST_BEGIN(clusterListName)` +`DECLARE_DYNAMIC_CLUSTER(clusterId, clusterAttrs, role, incomingCommands, outgoingCommands)` +`DECLARE_DYNAMIC_CLUSTER_LIST_END` + +- These three macros are used to declare a list of clusters for use within a + endpoint. The declaration must begin with the + `DECLARE_DYNAMIC_CLUSTER_LIST_BEGIN` macro which will define the name of the + allocated cluster structure. Each cluster is then added by the + `DECLARE_DYNAMIC_CLUSTER` macro referencing attribute list previously + defined by the `DECLARE_DYNAMIC_ATTRIBUTE...` macros and the lists of + incoming/outgoing commands terminated by kInvalidCommandId (or nullptr if + there aren't any commands in the list). Finally, + `DECLARE_DYNAMIC_CLUSTER_LIST_END` macro should be used to close the + definition. + +`DECLARE_DYNAMIC_ENDPOINT(endpointName, clusterList)` + +- This macro is used to declare an endpoint and its associated cluster list, + which must be previously defined by the `DECLARE_DYNAMIC_CLUSTER...` macros. + +## Building + + ### For Linux host example: + + ``` + ./scripts/examples/gn_build_example.sh examples/fabric-sync out/debug/standalone + ``` + + ### For Raspberry Pi 4 example: + + TODO + +## Running the Complete Example on Ubuntu + +- Building + + Follow [Building](#building) section of this document. + +- Run Linux Fabric Sync Example App + + ```sh + cd ~/connectedhomeip/ + sudo out/debug/fabric-sync + ``` diff --git a/examples/fabric-sync/args.gni b/examples/fabric-sync/args.gni new file mode 100644 index 00000000000000..d5e45ed869dd25 --- /dev/null +++ b/examples/fabric-sync/args.gni @@ -0,0 +1,40 @@ +# Copyright (c) 2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/chip.gni") + +import("${chip_root}/config/standalone/args.gni") + +chip_device_project_config_include = "" +chip_project_config_include = "" +chip_system_project_config_include = "" + +chip_project_config_include_dirs = + [ "${chip_root}/examples/fabric-sync/bridge/include" ] +chip_project_config_include_dirs += [ "${chip_root}/config/standalone" ] + +chip_build_libshell = true + +chip_enable_additional_data_advertising = true + +chip_enable_rotating_device_id = true + +chip_config_network_layer_ble = false + +matter_enable_tracing_support = true +matter_log_json_payload_hex = true +matter_log_json_payload_decode_full = true + +# Thread devices do not support WakeOnLan because their mac address is >48bit +chip_enable_openthread = false diff --git a/examples/fabric-sync/bridge/BUILD.gn b/examples/fabric-sync/bridge/BUILD.gn new file mode 100644 index 00000000000000..cdf3671b7d1cc5 --- /dev/null +++ b/examples/fabric-sync/bridge/BUILD.gn @@ -0,0 +1,50 @@ +# Copyright (c) 2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/chip.gni") +import("${chip_root}/src/app/chip_data_model.gni") +import("${chip_root}/src/lib/lib.gni") + +config("config") { + include_dirs = [ "include" ] +} + +chip_data_model("fabric-bridge-zap") { + zap_file = "fabric-bridge.zap" + is_server = true +} + +# This includes all the clusters that only exist on the dynamic endpoint. +source_set("fabric-bridge-common") { + public_configs = [ ":config" ] + + sources = [ + "${chip_root}/src/app/clusters/ecosystem-information-server/ecosystem-information-server.cpp", + "${chip_root}/src/app/clusters/ecosystem-information-server/ecosystem-information-server.h", + ] + + public_deps = [ ":fabric-bridge-zap" ] +} + +source_set("fabric-bridge-lib") { + public_configs = [ ":config" ] + + sources = [ "include/CHIPProjectAppConfig.h" ] + + deps = [ + "${chip_root}/examples/fabric-sync/bridge:fabric-bridge-common", + "${chip_root}/examples/platform/linux:app-main", + "${chip_root}/src/lib", + ] +} diff --git a/examples/fabric-sync/bridge/fabric-bridge.matter b/examples/fabric-sync/bridge/fabric-bridge.matter new file mode 100644 index 00000000000000..11dcf2f03db88e --- /dev/null +++ b/examples/fabric-sync/bridge/fabric-bridge.matter @@ -0,0 +1,2108 @@ +// This IDL was generated automatically by ZAP. +// It is for view/code review purposes only. + +enum AreaTypeTag : enum8 { + kAisle = 0; + kAttic = 1; + kBackDoor = 2; + kBackYard = 3; + kBalcony = 4; + kBallroom = 5; + kBathroom = 6; + kBedroom = 7; + kBorder = 8; + kBoxroom = 9; + kBreakfastRoom = 10; + kCarport = 11; + kCellar = 12; + kCloakroom = 13; + kCloset = 14; + kConservatory = 15; + kCorridor = 16; + kCraftRoom = 17; + kCupboard = 18; + kDeck = 19; + kDen = 20; + kDining = 21; + kDrawingRoom = 22; + kDressingRoom = 23; + kDriveway = 24; + kElevator = 25; + kEnsuite = 26; + kEntrance = 27; + kEntryway = 28; + kFamilyRoom = 29; + kFoyer = 30; + kFrontDoor = 31; + kFrontYard = 32; + kGameRoom = 33; + kGarage = 34; + kGarageDoor = 35; + kGarden = 36; + kGardenDoor = 37; + kGuestBathroom = 38; + kGuestBedroom = 39; + kGuestRestroom = 40; + kGuestRoom = 41; + kGym = 42; + kHallway = 43; + kHearthRoom = 44; + kKidsRoom = 45; + kKidsBedroom = 46; + kKitchen = 47; + kLarder = 48; + kLaundryRoom = 49; + kLawn = 50; + kLibrary = 51; + kLivingRoom = 52; + kLounge = 53; + kMediaTVRoom = 54; + kMudRoom = 55; + kMusicRoom = 56; + kNursery = 57; + kOffice = 58; + kOutdoorKitchen = 59; + kOutside = 60; + kPantry = 61; + kParkingLot = 62; + kParlor = 63; + kPatio = 64; + kPlayRoom = 65; + kPoolRoom = 66; + kPorch = 67; + kPrimaryBathroom = 68; + kPrimaryBedroom = 69; + kRamp = 70; + kReceptionRoom = 71; + kRecreationRoom = 72; + kRestroom = 73; + kRoof = 74; + kSauna = 75; + kScullery = 76; + kSewingRoom = 77; + kShed = 78; + kSideDoor = 79; + kSideYard = 80; + kSittingRoom = 81; + kSnug = 82; + kSpa = 83; + kStaircase = 84; + kSteamRoom = 85; + kStorageRoom = 86; + kStudio = 87; + kStudy = 88; + kSunRoom = 89; + kSwimmingPool = 90; + kTerrace = 91; + kUtilityRoom = 92; + kWard = 93; + kWorkshop = 94; +} + +enum AtomicRequestTypeEnum : enum8 { + kBeginWrite = 0; + kCommitWrite = 1; + kRollbackWrite = 2; +} + +enum FloorSurfaceTag : enum8 { + kCarpet = 0; + kCeramic = 1; + kConcrete = 2; + kCork = 3; + kDeepCarpet = 4; + kDirt = 5; + kEngineeredWood = 6; + kGlass = 7; + kGrass = 8; + kHardwood = 9; + kLaminate = 10; + kLinoleum = 11; + kMat = 12; + kMetal = 13; + kPlastic = 14; + kPolishedConcrete = 15; + kRubber = 16; + kRug = 17; + kSand = 18; + kStone = 19; + kTatami = 20; + kTerrazzo = 21; + kTile = 22; + kVinyl = 23; +} + +enum LandmarkTag : enum8 { + kAirConditioner = 0; + kAirPurifier = 1; + kBackDoor = 2; + kBarStool = 3; + kBathMat = 4; + kBathtub = 5; + kBed = 6; + kBookshelf = 7; + kChair = 8; + kChristmasTree = 9; + kCoatRack = 10; + kCoffeeTable = 11; + kCookingRange = 12; + kCouch = 13; + kCountertop = 14; + kCradle = 15; + kCrib = 16; + kDesk = 17; + kDiningTable = 18; + kDishwasher = 19; + kDoor = 20; + kDresser = 21; + kLaundryDryer = 22; + kFan = 23; + kFireplace = 24; + kFreezer = 25; + kFrontDoor = 26; + kHighChair = 27; + kKitchenIsland = 28; + kLamp = 29; + kLitterBox = 30; + kMirror = 31; + kNightstand = 32; + kOven = 33; + kPetBed = 34; + kPetBowl = 35; + kPetCrate = 36; + kRefrigerator = 37; + kScratchingPost = 38; + kShoeRack = 39; + kShower = 40; + kSideDoor = 41; + kSink = 42; + kSofa = 43; + kStove = 44; + kTable = 45; + kToilet = 46; + kTrashCan = 47; + kLaundryWasher = 48; + kWindow = 49; + kWineCooler = 50; +} + +enum PositionTag : enum8 { + kLeft = 0; + kRight = 1; + kTop = 2; + kBottom = 3; + kMiddle = 4; + kRow = 5; + kColumn = 6; +} + +enum RelativePositionTag : enum8 { + kUnder = 0; + kNextTo = 1; + kAround = 2; + kOn = 3; + kAbove = 4; + kFrontOf = 5; + kBehind = 6; +} + +enum TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +enum ThreeLevelAutoEnum : enum8 { + kLow = 0; + kMedium = 1; + kHigh = 2; + kAutomatic = 3; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + +struct AtomicAttributeStatusStruct { + attrib_id attributeID = 0; + status statusCode = 1; +} + +/** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ +cluster Identify = 3 { + revision 4; + + enum EffectIdentifierEnum : enum8 { + kBlink = 0; + kBreathe = 1; + kOkay = 2; + kChannelChange = 11; + kFinishEffect = 254; + kStopEffect = 255; + } + + enum EffectVariantEnum : enum8 { + kDefault = 0; + } + + enum IdentifyTypeEnum : enum8 { + kNone = 0; + kLightOutput = 1; + kVisibleIndicator = 2; + kAudibleBeep = 3; + kDisplay = 4; + kActuator = 5; + } + + attribute int16u identifyTime = 0; + readonly attribute IdentifyTypeEnum identifyType = 1; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct IdentifyRequest { + int16u identifyTime = 0; + } + + request struct TriggerEffectRequest { + EffectIdentifierEnum effectIdentifier = 0; + EffectVariantEnum effectVariant = 1; + } + + /** Command description for Identify */ + command access(invoke: manage) Identify(IdentifyRequest): DefaultSuccess = 0; + /** Command description for TriggerEffect */ + command access(invoke: manage) TriggerEffect(TriggerEffectRequest): DefaultSuccess = 64; +} + +/** The Descriptor Cluster is meant to replace the support from the Zigbee Device Object (ZDO) for describing a node, its endpoints and clusters. */ +cluster Descriptor = 29 { + revision 2; + + bitmap Feature : bitmap32 { + kTagList = 0x1; + } + + struct DeviceTypeStruct { + devtype_id deviceType = 0; + int16u revision = 1; + } + + struct SemanticTagStruct { + nullable vendor_id mfgCode = 0; + enum8 namespaceID = 1; + enum8 tag = 2; + optional nullable char_string label = 3; + } + + readonly attribute DeviceTypeStruct deviceTypeList[] = 0; + readonly attribute cluster_id serverList[] = 1; + readonly attribute cluster_id clientList[] = 2; + readonly attribute endpoint_no partsList[] = 3; + readonly attribute optional SemanticTagStruct tagList[] = 4; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; +} + +/** The Access Control Cluster exposes a data model view of a + Node's Access Control List (ACL), which codifies the rules used to manage + and enforce Access Control for the Node's endpoints and their associated + cluster instances. */ +cluster AccessControl = 31 { + revision 2; + + enum AccessControlEntryAuthModeEnum : enum8 { + kPASE = 1; + kCASE = 2; + kGroup = 3; + } + + enum AccessControlEntryPrivilegeEnum : enum8 { + kView = 1; + kProxyView = 2; + kOperate = 3; + kManage = 4; + kAdminister = 5; + } + + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + + enum ChangeTypeEnum : enum8 { + kChanged = 0; + kAdded = 1; + kRemoved = 2; + } + + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + + struct AccessControlTargetStruct { + nullable cluster_id cluster = 0; + nullable endpoint_no endpoint = 1; + nullable devtype_id deviceType = 2; + } + + fabric_scoped struct AccessControlEntryStruct { + fabric_sensitive AccessControlEntryPrivilegeEnum privilege = 1; + fabric_sensitive AccessControlEntryAuthModeEnum authMode = 2; + nullable fabric_sensitive int64u subjects[] = 3; + nullable fabric_sensitive AccessControlTargetStruct targets[] = 4; + fabric_idx fabricIndex = 254; + } + + fabric_scoped struct AccessControlExtensionStruct { + fabric_sensitive octet_string<128> data = 1; + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) AccessControlEntryChanged = 0 { + nullable node_id adminNodeID = 1; + nullable int16u adminPasscodeID = 2; + ChangeTypeEnum changeType = 3; + nullable AccessControlEntryStruct latestValue = 4; + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) AccessControlExtensionChanged = 1 { + nullable node_id adminNodeID = 1; + nullable int16u adminPasscodeID = 2; + ChangeTypeEnum changeType = 3; + nullable AccessControlExtensionStruct latestValue = 4; + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { + int64u token = 0; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; + fabric_idx fabricIndex = 254; + } + + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; + attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; + readonly attribute int16u subjectsPerAccessControlEntry = 2; + readonly attribute int16u targetsPerAccessControlEntry = 3; + readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; +} + +/** The Access Control Cluster exposes a data model view of a + Node's Access Control List (ACL), which codifies the rules used to manage + and enforce Access Control for the Node's endpoints and their associated + cluster instances. */ +cluster AccessControl = 31 { + revision 2; + + enum AccessControlEntryAuthModeEnum : enum8 { + kPASE = 1; + kCASE = 2; + kGroup = 3; + } + + enum AccessControlEntryPrivilegeEnum : enum8 { + kView = 1; + kProxyView = 2; + kOperate = 3; + kManage = 4; + kAdminister = 5; + } + + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + + enum ChangeTypeEnum : enum8 { + kChanged = 0; + kAdded = 1; + kRemoved = 2; + } + + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + + struct AccessControlTargetStruct { + nullable cluster_id cluster = 0; + nullable endpoint_no endpoint = 1; + nullable devtype_id deviceType = 2; + } + + fabric_scoped struct AccessControlEntryStruct { + fabric_sensitive AccessControlEntryPrivilegeEnum privilege = 1; + fabric_sensitive AccessControlEntryAuthModeEnum authMode = 2; + nullable fabric_sensitive int64u subjects[] = 3; + nullable fabric_sensitive AccessControlTargetStruct targets[] = 4; + fabric_idx fabricIndex = 254; + } + + fabric_scoped struct AccessControlExtensionStruct { + fabric_sensitive octet_string<128> data = 1; + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) AccessControlEntryChanged = 0 { + nullable node_id adminNodeID = 1; + nullable int16u adminPasscodeID = 2; + ChangeTypeEnum changeType = 3; + nullable AccessControlEntryStruct latestValue = 4; + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) AccessControlExtensionChanged = 1 { + nullable node_id adminNodeID = 1; + nullable int16u adminPasscodeID = 2; + ChangeTypeEnum changeType = 3; + nullable AccessControlExtensionStruct latestValue = 4; + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { + int64u token = 0; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; + fabric_idx fabricIndex = 254; + } + + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; + attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; + readonly attribute int16u subjectsPerAccessControlEntry = 2; + readonly attribute int16u targetsPerAccessControlEntry = 3; + readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; +} + +/** This cluster provides attributes and events for determining basic information about Nodes, which supports both + Commissioning and operational determination of Node characteristics, such as Vendor ID, Product ID and serial number, + which apply to the whole Node. Also allows setting user device information such as location. */ +cluster BasicInformation = 40 { + revision 3; + + enum ColorEnum : enum8 { + kBlack = 0; + kNavy = 1; + kGreen = 2; + kTeal = 3; + kMaroon = 4; + kPurple = 5; + kOlive = 6; + kGray = 7; + kBlue = 8; + kLime = 9; + kAqua = 10; + kRed = 11; + kFuchsia = 12; + kYellow = 13; + kWhite = 14; + kNickel = 15; + kChrome = 16; + kBrass = 17; + kCopper = 18; + kSilver = 19; + kGold = 20; + } + + enum ProductFinishEnum : enum8 { + kOther = 0; + kMatte = 1; + kSatin = 2; + kPolished = 3; + kRugged = 4; + kFabric = 5; + } + + struct CapabilityMinimaStruct { + int16u caseSessionsPerFabric = 0; + int16u subscriptionsPerFabric = 1; + } + + struct ProductAppearanceStruct { + ProductFinishEnum finish = 0; + nullable ColorEnum primaryColor = 1; + } + + critical event StartUp = 0 { + int32u softwareVersion = 0; + } + + critical event ShutDown = 1 { + } + + info event Leave = 2 { + fabric_idx fabricIndex = 0; + } + + info event ReachableChanged = 3 { + boolean reachableNewValue = 0; + } + + readonly attribute int16u dataModelRevision = 0; + readonly attribute char_string<32> vendorName = 1; + readonly attribute vendor_id vendorID = 2; + readonly attribute char_string<32> productName = 3; + readonly attribute int16u productID = 4; + attribute access(write: manage) char_string<32> nodeLabel = 5; + attribute access(write: administer) char_string<2> location = 6; + readonly attribute int16u hardwareVersion = 7; + readonly attribute char_string<64> hardwareVersionString = 8; + readonly attribute int32u softwareVersion = 9; + readonly attribute char_string<64> softwareVersionString = 10; + readonly attribute optional char_string<16> manufacturingDate = 11; + readonly attribute optional char_string<32> partNumber = 12; + readonly attribute optional long_char_string<256> productURL = 13; + readonly attribute optional char_string<64> productLabel = 14; + readonly attribute optional char_string<32> serialNumber = 15; + attribute access(write: manage) optional boolean localConfigDisabled = 16; + readonly attribute optional boolean reachable = 17; + readonly attribute char_string<32> uniqueID = 18; + readonly attribute CapabilityMinimaStruct capabilityMinima = 19; + readonly attribute optional ProductAppearanceStruct productAppearance = 20; + readonly attribute int32u specificationVersion = 21; + readonly attribute int16u maxPathsPerInvoke = 22; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + command MfgSpecificPing(): DefaultSuccess = 0; +} + +/** This cluster is used to manage global aspects of the Commissioning flow. */ +cluster GeneralCommissioning = 48 { + revision 1; // NOTE: Default/not specifically set + + enum CommissioningErrorEnum : enum8 { + kOK = 0; + kValueOutsideRange = 1; + kInvalidAuthentication = 2; + kNoFailSafe = 3; + kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; + } + + enum RegulatoryLocationTypeEnum : enum8 { + kIndoor = 0; + kOutdoor = 1; + kIndoorOutdoor = 2; + } + + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + + struct BasicCommissioningInfo { + int16u failSafeExpiryLengthSeconds = 0; + int16u maxCumulativeFailsafeSeconds = 1; + } + + attribute access(write: administer) int64u breadcrumb = 0; + readonly attribute BasicCommissioningInfo basicCommissioningInfo = 1; + readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; + readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; + readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; + provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct ArmFailSafeRequest { + int16u expiryLengthSeconds = 0; + int64u breadcrumb = 1; + } + + response struct ArmFailSafeResponse = 1 { + CommissioningErrorEnum errorCode = 0; + char_string<128> debugText = 1; + } + + request struct SetRegulatoryConfigRequest { + RegulatoryLocationTypeEnum newRegulatoryConfig = 0; + char_string<2> countryCode = 1; + int64u breadcrumb = 2; + } + + response struct SetRegulatoryConfigResponse = 3 { + CommissioningErrorEnum errorCode = 0; + char_string debugText = 1; + } + + response struct CommissioningCompleteResponse = 5 { + CommissioningErrorEnum errorCode = 0; + char_string debugText = 1; + } + + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ + command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; + /** Set the regulatory configuration to be used during commissioning */ + command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; + /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ + fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; +} + +/** Functionality to configure, enable, disable network credentials and access on a Matter device. */ +cluster NetworkCommissioning = 49 { + revision 1; // NOTE: Default/not specifically set + + enum NetworkCommissioningStatusEnum : enum8 { + kSuccess = 0; + kOutOfRange = 1; + kBoundsExceeded = 2; + kNetworkIDNotFound = 3; + kDuplicateNetworkID = 4; + kNetworkNotFound = 5; + kRegulatoryError = 6; + kAuthFailure = 7; + kUnsupportedSecurity = 8; + kOtherConnectionFailure = 9; + kIPV6Failed = 10; + kIPBindFailed = 11; + kUnknownError = 12; + } + + enum WiFiBandEnum : enum8 { + k2G4 = 0; + k3G65 = 1; + k5G = 2; + k6G = 3; + k60G = 4; + k1G = 5; + } + + bitmap Feature : bitmap32 { + kWiFiNetworkInterface = 0x1; + kThreadNetworkInterface = 0x2; + kEthernetNetworkInterface = 0x4; + kPerDeviceCredentials = 0x8; + } + + bitmap ThreadCapabilitiesBitmap : bitmap16 { + kIsBorderRouterCapable = 0x1; + kIsRouterCapable = 0x2; + kIsSleepyEndDeviceCapable = 0x4; + kIsFullThreadDevice = 0x8; + kIsSynchronizedSleepyEndDeviceCapable = 0x10; + } + + bitmap WiFiSecurityBitmap : bitmap8 { + kUnencrypted = 0x1; + kWEP = 0x2; + kWPAPersonal = 0x4; + kWPA2Personal = 0x8; + kWPA3Personal = 0x10; + kWPA3MatterPDC = 0x20; + } + + struct NetworkInfoStruct { + octet_string<32> networkID = 0; + boolean connected = 1; + optional nullable octet_string<20> networkIdentifier = 2; + optional nullable octet_string<20> clientIdentifier = 3; + } + + struct ThreadInterfaceScanResultStruct { + int16u panId = 0; + int64u extendedPanId = 1; + char_string<16> networkName = 2; + int16u channel = 3; + int8u version = 4; + octet_string<8> extendedAddress = 5; + int8s rssi = 6; + int8u lqi = 7; + } + + struct WiFiInterfaceScanResultStruct { + WiFiSecurityBitmap security = 0; + octet_string<32> ssid = 1; + octet_string<6> bssid = 2; + int16u channel = 3; + WiFiBandEnum wiFiBand = 4; + int8s rssi = 5; + } + + readonly attribute access(read: administer) int8u maxNetworks = 0; + readonly attribute access(read: administer) NetworkInfoStruct networks[] = 1; + readonly attribute optional int8u scanMaxTimeSeconds = 2; + readonly attribute optional int8u connectMaxTimeSeconds = 3; + attribute access(write: administer) boolean interfaceEnabled = 4; + readonly attribute access(read: administer) nullable NetworkCommissioningStatusEnum lastNetworkingStatus = 5; + readonly attribute access(read: administer) nullable octet_string<32> lastNetworkID = 6; + readonly attribute access(read: administer) nullable int32s lastConnectErrorValue = 7; + provisional readonly attribute optional WiFiBandEnum supportedWiFiBands[] = 8; + provisional readonly attribute optional ThreadCapabilitiesBitmap supportedThreadFeatures = 9; + provisional readonly attribute optional int16u threadVersion = 10; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct ScanNetworksRequest { + optional nullable octet_string<32> ssid = 0; + optional int64u breadcrumb = 1; + } + + response struct ScanNetworksResponse = 1 { + NetworkCommissioningStatusEnum networkingStatus = 0; + optional char_string debugText = 1; + optional WiFiInterfaceScanResultStruct wiFiScanResults[] = 2; + optional ThreadInterfaceScanResultStruct threadScanResults[] = 3; + } + + request struct AddOrUpdateWiFiNetworkRequest { + octet_string<32> ssid = 0; + octet_string<64> credentials = 1; + optional int64u breadcrumb = 2; + optional octet_string<140> networkIdentity = 3; + optional octet_string<20> clientIdentifier = 4; + optional octet_string<32> possessionNonce = 5; + } + + request struct AddOrUpdateThreadNetworkRequest { + octet_string<254> operationalDataset = 0; + optional int64u breadcrumb = 1; + } + + request struct RemoveNetworkRequest { + octet_string<32> networkID = 0; + optional int64u breadcrumb = 1; + } + + response struct NetworkConfigResponse = 5 { + NetworkCommissioningStatusEnum networkingStatus = 0; + optional char_string<512> debugText = 1; + optional int8u networkIndex = 2; + optional octet_string<140> clientIdentity = 3; + optional octet_string<64> possessionSignature = 4; + } + + request struct ConnectNetworkRequest { + octet_string<32> networkID = 0; + optional int64u breadcrumb = 1; + } + + response struct ConnectNetworkResponse = 7 { + NetworkCommissioningStatusEnum networkingStatus = 0; + optional char_string debugText = 1; + nullable int32s errorValue = 2; + } + + request struct ReorderNetworkRequest { + octet_string<32> networkID = 0; + int8u networkIndex = 1; + optional int64u breadcrumb = 2; + } + + request struct QueryIdentityRequest { + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; + } + + response struct QueryIdentityResponse = 10 { + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; + } + + /** Detemine the set of networks the device sees as available. */ + command access(invoke: administer) ScanNetworks(ScanNetworksRequest): ScanNetworksResponse = 0; + /** Add or update the credentials for a given Wi-Fi network. */ + command access(invoke: administer) AddOrUpdateWiFiNetwork(AddOrUpdateWiFiNetworkRequest): NetworkConfigResponse = 2; + /** Add or update the credentials for a given Thread network. */ + command access(invoke: administer) AddOrUpdateThreadNetwork(AddOrUpdateThreadNetworkRequest): NetworkConfigResponse = 3; + /** Remove the definition of a given network (including its credentials). */ + command access(invoke: administer) RemoveNetwork(RemoveNetworkRequest): NetworkConfigResponse = 4; + /** Connect to the specified network, using previously-defined credentials. */ + command access(invoke: administer) ConnectNetwork(ConnectNetworkRequest): ConnectNetworkResponse = 6; + /** Modify the order in which networks will be presented in the Networks attribute. */ + command access(invoke: administer) ReorderNetwork(ReorderNetworkRequest): NetworkConfigResponse = 8; + /** Retrieve details about and optionally proof of possession of a network client identity. */ + command access(invoke: administer) QueryIdentity(QueryIdentityRequest): QueryIdentityResponse = 9; +} + +/** The cluster provides commands for retrieving unstructured diagnostic logs from a Node that may be used to aid in diagnostics. */ +cluster DiagnosticLogs = 50 { + revision 1; // NOTE: Default/not specifically set + + enum IntentEnum : enum8 { + kEndUserSupport = 0; + kNetworkDiag = 1; + kCrashLogs = 2; + } + + enum StatusEnum : enum8 { + kSuccess = 0; + kExhausted = 1; + kNoLogs = 2; + kBusy = 3; + kDenied = 4; + } + + enum TransferProtocolEnum : enum8 { + kResponsePayload = 0; + kBDX = 1; + } + + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct RetrieveLogsRequestRequest { + IntentEnum intent = 0; + TransferProtocolEnum requestedProtocol = 1; + optional char_string<32> transferFileDesignator = 2; + } + + response struct RetrieveLogsResponse = 1 { + StatusEnum status = 0; + long_octet_string logContent = 1; + optional epoch_us UTCTimeStamp = 2; + optional systime_us timeSinceBoot = 3; + } + + /** Retrieving diagnostic logs from a Node */ + command RetrieveLogsRequest(RetrieveLogsRequestRequest): RetrieveLogsResponse = 0; +} + +/** The General Diagnostics Cluster, along with other diagnostics clusters, provide a means to acquire standardized diagnostics metrics that MAY be used by a Node to assist a user or Administrative Node in diagnosing potential problems. */ +cluster GeneralDiagnostics = 51 { + revision 2; + + enum BootReasonEnum : enum8 { + kUnspecified = 0; + kPowerOnReboot = 1; + kBrownOutReset = 2; + kSoftwareWatchdogReset = 3; + kHardwareWatchdogReset = 4; + kSoftwareUpdateCompleted = 5; + kSoftwareReset = 6; + } + + enum HardwareFaultEnum : enum8 { + kUnspecified = 0; + kRadio = 1; + kSensor = 2; + kResettableOverTemp = 3; + kNonResettableOverTemp = 4; + kPowerSource = 5; + kVisualDisplayFault = 6; + kAudioOutputFault = 7; + kUserInterfaceFault = 8; + kNonVolatileMemoryError = 9; + kTamperDetected = 10; + } + + enum InterfaceTypeEnum : enum8 { + kUnspecified = 0; + kWiFi = 1; + kEthernet = 2; + kCellular = 3; + kThread = 4; + } + + enum NetworkFaultEnum : enum8 { + kUnspecified = 0; + kHardwareFailure = 1; + kNetworkJammed = 2; + kConnectionFailed = 3; + } + + enum RadioFaultEnum : enum8 { + kUnspecified = 0; + kWiFiFault = 1; + kCellularFault = 2; + kThreadFault = 3; + kNFCFault = 4; + kBLEFault = 5; + kEthernetFault = 6; + } + + bitmap Feature : bitmap32 { + kDataModelTest = 0x1; + } + + struct NetworkInterface { + char_string<32> name = 0; + boolean isOperational = 1; + nullable boolean offPremiseServicesReachableIPv4 = 2; + nullable boolean offPremiseServicesReachableIPv6 = 3; + octet_string<8> hardwareAddress = 4; + octet_string IPv4Addresses[] = 5; + octet_string IPv6Addresses[] = 6; + InterfaceTypeEnum type = 7; + } + + critical event HardwareFaultChange = 0 { + HardwareFaultEnum current[] = 0; + HardwareFaultEnum previous[] = 1; + } + + critical event RadioFaultChange = 1 { + RadioFaultEnum current[] = 0; + RadioFaultEnum previous[] = 1; + } + + critical event NetworkFaultChange = 2 { + NetworkFaultEnum current[] = 0; + NetworkFaultEnum previous[] = 1; + } + + critical event BootReason = 3 { + BootReasonEnum bootReason = 0; + } + + readonly attribute NetworkInterface networkInterfaces[] = 0; + readonly attribute int16u rebootCount = 1; + readonly attribute optional int64u upTime = 2; + readonly attribute optional int32u totalOperationalHours = 3; + readonly attribute optional BootReasonEnum bootReason = 4; + readonly attribute optional HardwareFaultEnum activeHardwareFaults[] = 5; + readonly attribute optional RadioFaultEnum activeRadioFaults[] = 6; + readonly attribute optional NetworkFaultEnum activeNetworkFaults[] = 7; + readonly attribute boolean testEventTriggersEnabled = 8; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct TestEventTriggerRequest { + octet_string<16> enableKey = 0; + int64u eventTrigger = 1; + } + + response struct TimeSnapshotResponse = 2 { + systime_ms systemTimeMs = 0; + nullable posix_ms posixTimeMs = 1; + } + + request struct PayloadTestRequestRequest { + octet_string<16> enableKey = 0; + int8u value = 1; + int16u count = 2; + } + + response struct PayloadTestResponse = 4 { + octet_string payload = 0; + } + + /** Provide a means for certification tests to trigger some test-plan-specific events */ + command access(invoke: manage) TestEventTrigger(TestEventTriggerRequest): DefaultSuccess = 0; + /** Take a snapshot of system time and epoch time. */ + command TimeSnapshot(): TimeSnapshotResponse = 1; + /** Request a variable length payload response. */ + command PayloadTestRequest(PayloadTestRequestRequest): PayloadTestResponse = 3; +} + +/** The Software Diagnostics Cluster provides a means to acquire standardized diagnostics metrics that MAY be used by a Node to assist a user or Administrative Node in diagnosing potential problems. */ +cluster SoftwareDiagnostics = 52 { + revision 1; // NOTE: Default/not specifically set + + bitmap Feature : bitmap32 { + kWatermarks = 0x1; + } + + struct ThreadMetricsStruct { + int64u id = 0; + optional char_string<8> name = 1; + optional int32u stackFreeCurrent = 2; + optional int32u stackFreeMinimum = 3; + optional int32u stackSize = 4; + } + + info event SoftwareFault = 0 { + int64u id = 0; + optional char_string name = 1; + optional octet_string faultRecording = 2; + } + + readonly attribute optional ThreadMetricsStruct threadMetrics[] = 0; + readonly attribute optional int64u currentHeapFree = 1; + readonly attribute optional int64u currentHeapUsed = 2; + readonly attribute optional int64u currentHeapHighWatermark = 3; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + /** Reception of this command SHALL reset the values: The StackFreeMinimum field of the ThreadMetrics attribute, CurrentHeapHighWaterMark attribute. */ + command access(invoke: manage) ResetWatermarks(): DefaultSuccess = 0; +} + +/** The Thread Network Diagnostics Cluster provides a means to acquire standardized diagnostics metrics that MAY be used by a Node to assist a user or Administrative Node in diagnosing potential problems */ +cluster ThreadNetworkDiagnostics = 53 { + revision 2; + + enum ConnectionStatusEnum : enum8 { + kConnected = 0; + kNotConnected = 1; + } + + enum NetworkFaultEnum : enum8 { + kUnspecified = 0; + kLinkDown = 1; + kHardwareFailure = 2; + kNetworkJammed = 3; + } + + enum RoutingRoleEnum : enum8 { + kUnspecified = 0; + kUnassigned = 1; + kSleepyEndDevice = 2; + kEndDevice = 3; + kREED = 4; + kRouter = 5; + kLeader = 6; + } + + bitmap Feature : bitmap32 { + kPacketCounts = 0x1; + kErrorCounts = 0x2; + kMLECounts = 0x4; + kMACCounts = 0x8; + } + + struct NeighborTableStruct { + int64u extAddress = 0; + int32u age = 1; + int16u rloc16 = 2; + int32u linkFrameCounter = 3; + int32u mleFrameCounter = 4; + int8u lqi = 5; + nullable int8s averageRssi = 6; + nullable int8s lastRssi = 7; + int8u frameErrorRate = 8; + int8u messageErrorRate = 9; + boolean rxOnWhenIdle = 10; + boolean fullThreadDevice = 11; + boolean fullNetworkData = 12; + boolean isChild = 13; + } + + struct OperationalDatasetComponents { + boolean activeTimestampPresent = 0; + boolean pendingTimestampPresent = 1; + boolean masterKeyPresent = 2; + boolean networkNamePresent = 3; + boolean extendedPanIdPresent = 4; + boolean meshLocalPrefixPresent = 5; + boolean delayPresent = 6; + boolean panIdPresent = 7; + boolean channelPresent = 8; + boolean pskcPresent = 9; + boolean securityPolicyPresent = 10; + boolean channelMaskPresent = 11; + } + + struct RouteTableStruct { + int64u extAddress = 0; + int16u rloc16 = 1; + int8u routerId = 2; + int8u nextHop = 3; + int8u pathCost = 4; + int8u LQIIn = 5; + int8u LQIOut = 6; + int8u age = 7; + boolean allocated = 8; + boolean linkEstablished = 9; + } + + struct SecurityPolicy { + int16u rotationTime = 0; + int16u flags = 1; + } + + info event ConnectionStatus = 0 { + ConnectionStatusEnum connectionStatus = 0; + } + + info event NetworkFaultChange = 1 { + NetworkFaultEnum current[] = 0; + NetworkFaultEnum previous[] = 1; + } + + readonly attribute nullable int16u channel = 0; + readonly attribute nullable RoutingRoleEnum routingRole = 1; + readonly attribute nullable char_string<16> networkName = 2; + readonly attribute nullable int16u panId = 3; + readonly attribute nullable int64u extendedPanId = 4; + readonly attribute nullable octet_string<17> meshLocalPrefix = 5; + readonly attribute optional int64u overrunCount = 6; + readonly attribute NeighborTableStruct neighborTable[] = 7; + readonly attribute RouteTableStruct routeTable[] = 8; + readonly attribute nullable int32u partitionId = 9; + readonly attribute nullable int16u weighting = 10; + readonly attribute nullable int16u dataVersion = 11; + readonly attribute nullable int16u stableDataVersion = 12; + readonly attribute nullable int8u leaderRouterId = 13; + readonly attribute optional int16u detachedRoleCount = 14; + readonly attribute optional int16u childRoleCount = 15; + readonly attribute optional int16u routerRoleCount = 16; + readonly attribute optional int16u leaderRoleCount = 17; + readonly attribute optional int16u attachAttemptCount = 18; + readonly attribute optional int16u partitionIdChangeCount = 19; + readonly attribute optional int16u betterPartitionAttachAttemptCount = 20; + readonly attribute optional int16u parentChangeCount = 21; + readonly attribute optional int32u txTotalCount = 22; + readonly attribute optional int32u txUnicastCount = 23; + readonly attribute optional int32u txBroadcastCount = 24; + readonly attribute optional int32u txAckRequestedCount = 25; + readonly attribute optional int32u txAckedCount = 26; + readonly attribute optional int32u txNoAckRequestedCount = 27; + readonly attribute optional int32u txDataCount = 28; + readonly attribute optional int32u txDataPollCount = 29; + readonly attribute optional int32u txBeaconCount = 30; + readonly attribute optional int32u txBeaconRequestCount = 31; + readonly attribute optional int32u txOtherCount = 32; + readonly attribute optional int32u txRetryCount = 33; + readonly attribute optional int32u txDirectMaxRetryExpiryCount = 34; + readonly attribute optional int32u txIndirectMaxRetryExpiryCount = 35; + readonly attribute optional int32u txErrCcaCount = 36; + readonly attribute optional int32u txErrAbortCount = 37; + readonly attribute optional int32u txErrBusyChannelCount = 38; + readonly attribute optional int32u rxTotalCount = 39; + readonly attribute optional int32u rxUnicastCount = 40; + readonly attribute optional int32u rxBroadcastCount = 41; + readonly attribute optional int32u rxDataCount = 42; + readonly attribute optional int32u rxDataPollCount = 43; + readonly attribute optional int32u rxBeaconCount = 44; + readonly attribute optional int32u rxBeaconRequestCount = 45; + readonly attribute optional int32u rxOtherCount = 46; + readonly attribute optional int32u rxAddressFilteredCount = 47; + readonly attribute optional int32u rxDestAddrFilteredCount = 48; + readonly attribute optional int32u rxDuplicatedCount = 49; + readonly attribute optional int32u rxErrNoFrameCount = 50; + readonly attribute optional int32u rxErrUnknownNeighborCount = 51; + readonly attribute optional int32u rxErrInvalidSrcAddrCount = 52; + readonly attribute optional int32u rxErrSecCount = 53; + readonly attribute optional int32u rxErrFcsCount = 54; + readonly attribute optional int32u rxErrOtherCount = 55; + readonly attribute optional nullable int64u activeTimestamp = 56; + readonly attribute optional nullable int64u pendingTimestamp = 57; + readonly attribute optional nullable int32u delay = 58; + readonly attribute nullable SecurityPolicy securityPolicy = 59; + readonly attribute nullable octet_string<4> channelPage0Mask = 60; + readonly attribute nullable OperationalDatasetComponents operationalDatasetComponents = 61; + readonly attribute NetworkFaultEnum activeNetworkFaultsList[] = 62; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + /** Reception of this command SHALL reset the OverrunCount attributes to 0 */ + command access(invoke: manage) ResetCounts(): DefaultSuccess = 0; +} + +/** The Wi-Fi Network Diagnostics Cluster provides a means to acquire standardized diagnostics metrics that MAY be used by a Node to assist a user or Administrative Node in diagnosing potential problems. */ +cluster WiFiNetworkDiagnostics = 54 { + revision 1; // NOTE: Default/not specifically set + + enum AssociationFailureCauseEnum : enum8 { + kUnknown = 0; + kAssociationFailed = 1; + kAuthenticationFailed = 2; + kSsidNotFound = 3; + } + + enum ConnectionStatusEnum : enum8 { + kConnected = 0; + kNotConnected = 1; + } + + enum SecurityTypeEnum : enum8 { + kUnspecified = 0; + kNone = 1; + kWEP = 2; + kWPA = 3; + kWPA2 = 4; + kWPA3 = 5; + } + + enum WiFiVersionEnum : enum8 { + kA = 0; + kB = 1; + kG = 2; + kN = 3; + kAc = 4; + kAx = 5; + kAh = 6; + } + + bitmap Feature : bitmap32 { + kPacketCounts = 0x1; + kErrorCounts = 0x2; + } + + info event Disconnection = 0 { + int16u reasonCode = 0; + } + + info event AssociationFailure = 1 { + AssociationFailureCauseEnum associationFailureCause = 0; + int16u status = 1; + } + + info event ConnectionStatus = 2 { + ConnectionStatusEnum connectionStatus = 0; + } + + readonly attribute nullable octet_string<6> bssid = 0; + readonly attribute nullable SecurityTypeEnum securityType = 1; + readonly attribute nullable WiFiVersionEnum wiFiVersion = 2; + readonly attribute nullable int16u channelNumber = 3; + readonly attribute nullable int8s rssi = 4; + readonly attribute optional nullable int32u beaconLostCount = 5; + readonly attribute optional nullable int32u beaconRxCount = 6; + readonly attribute optional nullable int32u packetMulticastRxCount = 7; + readonly attribute optional nullable int32u packetMulticastTxCount = 8; + readonly attribute optional nullable int32u packetUnicastRxCount = 9; + readonly attribute optional nullable int32u packetUnicastTxCount = 10; + readonly attribute optional nullable int64u currentMaxRate = 11; + readonly attribute optional nullable int64u overrunCount = 12; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + /** Reception of this command SHALL reset the Breacon and Packet related count attributes to 0 */ + command ResetCounts(): DefaultSuccess = 0; +} + +/** The Ethernet Network Diagnostics Cluster provides a means to acquire standardized diagnostics metrics that MAY be used by a Node to assist a user or Administrative Node in diagnosing potential problems. */ +cluster EthernetNetworkDiagnostics = 55 { + revision 1; // NOTE: Default/not specifically set + + enum PHYRateEnum : enum8 { + kRate10M = 0; + kRate100M = 1; + kRate1G = 2; + kRate25G = 3; + kRate5G = 4; + kRate10G = 5; + kRate40G = 6; + kRate100G = 7; + kRate200G = 8; + kRate400G = 9; + } + + bitmap Feature : bitmap32 { + kPacketCounts = 0x1; + kErrorCounts = 0x2; + } + + readonly attribute optional nullable PHYRateEnum PHYRate = 0; + readonly attribute optional nullable boolean fullDuplex = 1; + readonly attribute optional int64u packetRxCount = 2; + readonly attribute optional int64u packetTxCount = 3; + readonly attribute optional int64u txErrCount = 4; + readonly attribute optional int64u collisionCount = 5; + readonly attribute optional int64u overrunCount = 6; + readonly attribute optional nullable boolean carrierDetect = 7; + readonly attribute optional int64u timeSinceReset = 8; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + /** Reception of this command SHALL reset the attributes: PacketRxCount, PacketTxCount, TxErrCount, CollisionCount, OverrunCount to 0 */ + command access(invoke: manage) ResetCounts(): DefaultSuccess = 0; +} + +/** Commands to trigger a Node to allow a new Administrator to commission it. */ +cluster AdministratorCommissioning = 60 { + revision 1; // NOTE: Default/not specifically set + + enum CommissioningWindowStatusEnum : enum8 { + kWindowNotOpen = 0; + kEnhancedWindowOpen = 1; + kBasicWindowOpen = 2; + } + + enum StatusCode : enum8 { + kBusy = 2; + kPAKEParameterError = 3; + kWindowNotOpen = 4; + } + + bitmap Feature : bitmap32 { + kBasic = 0x1; + } + + readonly attribute CommissioningWindowStatusEnum windowStatus = 0; + readonly attribute nullable fabric_idx adminFabricIndex = 1; + readonly attribute nullable vendor_id adminVendorId = 2; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct OpenCommissioningWindowRequest { + int16u commissioningTimeout = 0; + octet_string PAKEPasscodeVerifier = 1; + int16u discriminator = 2; + int32u iterations = 3; + octet_string<32> salt = 4; + } + + request struct OpenBasicCommissioningWindowRequest { + int16u commissioningTimeout = 0; + } + + /** This command is used by a current Administrator to instruct a Node to go into commissioning mode using enhanced commissioning method. */ + timed command access(invoke: administer) OpenCommissioningWindow(OpenCommissioningWindowRequest): DefaultSuccess = 0; + /** This command is used by a current Administrator to instruct a Node to go into commissioning mode using basic commissioning method, if the node supports it. */ + timed command access(invoke: administer) OpenBasicCommissioningWindow(OpenBasicCommissioningWindowRequest): DefaultSuccess = 1; + /** This command is used by a current Administrator to instruct a Node to revoke any active Open Commissioning Window or Open Basic Commissioning Window command. */ + timed command access(invoke: administer) RevokeCommissioning(): DefaultSuccess = 2; +} + +/** This cluster is used to add or remove Operational Credentials on a Commissionee or Node, as well as manage the associated Fabrics. */ +cluster OperationalCredentials = 62 { + revision 1; // NOTE: Default/not specifically set + + enum CertificateChainTypeEnum : enum8 { + kDACCertificate = 1; + kPAICertificate = 2; + } + + enum NodeOperationalCertStatusEnum : enum8 { + kOK = 0; + kInvalidPublicKey = 1; + kInvalidNodeOpId = 2; + kInvalidNOC = 3; + kMissingCsr = 4; + kTableFull = 5; + kInvalidAdminSubject = 6; + kFabricConflict = 9; + kLabelConflict = 10; + kInvalidFabricIndex = 11; + } + + fabric_scoped struct FabricDescriptorStruct { + octet_string<65> rootPublicKey = 1; + vendor_id vendorID = 2; + fabric_id fabricID = 3; + node_id nodeID = 4; + char_string<32> label = 5; + fabric_idx fabricIndex = 254; + } + + fabric_scoped struct NOCStruct { + fabric_sensitive octet_string noc = 1; + nullable fabric_sensitive octet_string icac = 2; + fabric_idx fabricIndex = 254; + } + + readonly attribute access(read: administer) NOCStruct NOCs[] = 0; + readonly attribute FabricDescriptorStruct fabrics[] = 1; + readonly attribute int8u supportedFabrics = 2; + readonly attribute int8u commissionedFabrics = 3; + readonly attribute octet_string trustedRootCertificates[] = 4; + readonly attribute int8u currentFabricIndex = 5; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct AttestationRequestRequest { + octet_string<32> attestationNonce = 0; + } + + response struct AttestationResponse = 1 { + octet_string<900> attestationElements = 0; + octet_string<64> attestationSignature = 1; + } + + request struct CertificateChainRequestRequest { + CertificateChainTypeEnum certificateType = 0; + } + + response struct CertificateChainResponse = 3 { + octet_string<600> certificate = 0; + } + + request struct CSRRequestRequest { + octet_string<32> CSRNonce = 0; + optional boolean isForUpdateNOC = 1; + } + + response struct CSRResponse = 5 { + octet_string NOCSRElements = 0; + octet_string attestationSignature = 1; + } + + request struct AddNOCRequest { + octet_string<400> NOCValue = 0; + optional octet_string<400> ICACValue = 1; + octet_string<16> IPKValue = 2; + int64u caseAdminSubject = 3; + vendor_id adminVendorId = 4; + } + + request struct UpdateNOCRequest { + octet_string NOCValue = 0; + optional octet_string ICACValue = 1; + } + + response struct NOCResponse = 8 { + NodeOperationalCertStatusEnum statusCode = 0; + optional fabric_idx fabricIndex = 1; + optional char_string<128> debugText = 2; + } + + request struct UpdateFabricLabelRequest { + char_string<32> label = 0; + } + + request struct RemoveFabricRequest { + fabric_idx fabricIndex = 0; + } + + request struct AddTrustedRootCertificateRequest { + octet_string rootCACertificate = 0; + } + + /** Sender is requesting attestation information from the receiver. */ + command access(invoke: administer) AttestationRequest(AttestationRequestRequest): AttestationResponse = 0; + /** Sender is requesting a device attestation certificate from the receiver. */ + command access(invoke: administer) CertificateChainRequest(CertificateChainRequestRequest): CertificateChainResponse = 2; + /** Sender is requesting a certificate signing request (CSR) from the receiver. */ + command access(invoke: administer) CSRRequest(CSRRequestRequest): CSRResponse = 4; + /** Sender is requesting to add the new node operational certificates. */ + command access(invoke: administer) AddNOC(AddNOCRequest): NOCResponse = 6; + /** Sender is requesting to update the node operational certificates. */ + fabric command access(invoke: administer) UpdateNOC(UpdateNOCRequest): NOCResponse = 7; + /** This command SHALL be used by an Administrative Node to set the user-visible Label field for a given Fabric, as reflected by entries in the Fabrics attribute. */ + fabric command access(invoke: administer) UpdateFabricLabel(UpdateFabricLabelRequest): NOCResponse = 9; + /** This command is used by Administrative Nodes to remove a given fabric index and delete all associated fabric-scoped data. */ + command access(invoke: administer) RemoveFabric(RemoveFabricRequest): NOCResponse = 10; + /** This command SHALL add a Trusted Root CA Certificate, provided as its CHIP Certificate representation. */ + command access(invoke: administer) AddTrustedRootCertificate(AddTrustedRootCertificateRequest): DefaultSuccess = 11; +} + +/** The Group Key Management Cluster is the mechanism by which group keys are managed. */ +cluster GroupKeyManagement = 63 { + revision 1; // NOTE: Default/not specifically set + + enum GroupKeySecurityPolicyEnum : enum8 { + kTrustFirst = 0; + kCacheAndSync = 1; + } + + bitmap Feature : bitmap32 { + kCacheAndSync = 0x1; + } + + fabric_scoped struct GroupInfoMapStruct { + group_id groupId = 1; + endpoint_no endpoints[] = 2; + optional char_string<16> groupName = 3; + fabric_idx fabricIndex = 254; + } + + fabric_scoped struct GroupKeyMapStruct { + group_id groupId = 1; + int16u groupKeySetID = 2; + fabric_idx fabricIndex = 254; + } + + struct GroupKeySetStruct { + int16u groupKeySetID = 0; + GroupKeySecurityPolicyEnum groupKeySecurityPolicy = 1; + nullable octet_string<16> epochKey0 = 2; + nullable epoch_us epochStartTime0 = 3; + nullable octet_string<16> epochKey1 = 4; + nullable epoch_us epochStartTime1 = 5; + nullable octet_string<16> epochKey2 = 6; + nullable epoch_us epochStartTime2 = 7; + } + + attribute access(write: manage) GroupKeyMapStruct groupKeyMap[] = 0; + readonly attribute GroupInfoMapStruct groupTable[] = 1; + readonly attribute int16u maxGroupsPerFabric = 2; + readonly attribute int16u maxGroupKeysPerFabric = 3; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct KeySetWriteRequest { + GroupKeySetStruct groupKeySet = 0; + } + + request struct KeySetReadRequest { + int16u groupKeySetID = 0; + } + + response struct KeySetReadResponse = 2 { + GroupKeySetStruct groupKeySet = 0; + } + + request struct KeySetRemoveRequest { + int16u groupKeySetID = 0; + } + + response struct KeySetReadAllIndicesResponse = 5 { + int16u groupKeySetIDs[] = 0; + } + + /** Write a new set of keys for the given key set id. */ + fabric command access(invoke: administer) KeySetWrite(KeySetWriteRequest): DefaultSuccess = 0; + /** Read the keys for a given key set id. */ + fabric command access(invoke: administer) KeySetRead(KeySetReadRequest): KeySetReadResponse = 1; + /** Revoke a Root Key from a Group */ + fabric command access(invoke: administer) KeySetRemove(KeySetRemoveRequest): DefaultSuccess = 3; + /** Return the list of Group Key Sets associated with the accessing fabric */ + fabric command access(invoke: administer) KeySetReadAllIndices(): KeySetReadAllIndicesResponse = 4; +} + +/** Supports the ability for clients to request the commissioning of themselves or other nodes onto a fabric which the cluster server can commission onto. */ +cluster CommissionerControl = 1873 { + revision 1; + + bitmap SupportedDeviceCategoryBitmap : bitmap32 { + kFabricSynchronization = 0x1; + } + + fabric_sensitive info event access(read: manage) CommissioningRequestResult = 0 { + int64u requestID = 0; + node_id clientNodeID = 1; + status statusCode = 2; + fabric_idx fabricIndex = 254; + } + + readonly attribute access(read: manage) SupportedDeviceCategoryBitmap supportedDeviceCategories = 0; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct RequestCommissioningApprovalRequest { + int64u requestID = 0; + vendor_id vendorID = 1; + int16u productID = 2; + optional char_string<64> label = 3; + } + + request struct CommissionNodeRequest { + int64u requestID = 0; + int16u responseTimeoutSeconds = 1; + } + + response struct ReverseOpenCommissioningWindow = 2 { + int16u commissioningTimeout = 0; + octet_string PAKEPasscodeVerifier = 1; + int16u discriminator = 2; + int32u iterations = 3; + octet_string<32> salt = 4; + } + + /** This command is sent by a client to request approval for a future CommissionNode call. */ + command access(invoke: manage) RequestCommissioningApproval(RequestCommissioningApprovalRequest): DefaultSuccess = 0; + /** This command is sent by a client to request that the server begins commissioning a previously approved request. */ + command access(invoke: manage) CommissionNode(CommissionNodeRequest): ReverseOpenCommissioningWindow = 1; +} + +endpoint 0 { + device type ma_rootdevice = 22, version 1; + + binding cluster AccessControl; + + server cluster Descriptor { + callback attribute deviceTypeList; + callback attribute serverList; + callback attribute clientList; + callback attribute partsList; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute attributeList; + callback attribute featureMap; + callback attribute clusterRevision; + } + + server cluster AccessControl { + emits event AccessControlEntryChanged; + callback attribute acl; + callback attribute extension; + callback attribute subjectsPerAccessControlEntry; + callback attribute targetsPerAccessControlEntry; + callback attribute accessControlEntriesPerFabric; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute attributeList; + ram attribute featureMap default = 0; + callback attribute clusterRevision; + } + + server cluster BasicInformation { + emits event StartUp; + emits event ShutDown; + emits event Leave; + callback attribute dataModelRevision; + callback attribute vendorName; + callback attribute vendorID; + callback attribute productName; + callback attribute productID; + persist attribute nodeLabel; + callback attribute location; + callback attribute hardwareVersion; + callback attribute hardwareVersionString; + callback attribute softwareVersion; + callback attribute softwareVersionString; + callback attribute manufacturingDate; + callback attribute partNumber; + callback attribute productURL; + callback attribute productLabel; + callback attribute serialNumber; + persist attribute localConfigDisabled default = 0; + callback attribute uniqueID; + callback attribute capabilityMinima; + callback attribute specificationVersion; + callback attribute maxPathsPerInvoke; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute attributeList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 3; + } + + server cluster GeneralCommissioning { + ram attribute breadcrumb default = 0x0000000000000000; + callback attribute basicCommissioningInfo; + callback attribute regulatoryConfig; + callback attribute locationCapability; + callback attribute supportsConcurrentConnection; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute attributeList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + + handle command ArmFailSafe; + handle command ArmFailSafeResponse; + handle command SetRegulatoryConfig; + handle command SetRegulatoryConfigResponse; + handle command CommissioningComplete; + handle command CommissioningCompleteResponse; + } + + server cluster NetworkCommissioning { + ram attribute maxNetworks; + callback attribute networks; + ram attribute scanMaxTimeSeconds; + ram attribute connectMaxTimeSeconds; + ram attribute interfaceEnabled; + ram attribute lastNetworkingStatus; + ram attribute lastNetworkID; + ram attribute lastConnectErrorValue; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute attributeList; + ram attribute featureMap default = 2; + ram attribute clusterRevision default = 1; + + handle command ScanNetworks; + handle command ScanNetworksResponse; + handle command AddOrUpdateWiFiNetwork; + handle command AddOrUpdateThreadNetwork; + handle command RemoveNetwork; + handle command NetworkConfigResponse; + handle command ConnectNetwork; + handle command ConnectNetworkResponse; + handle command ReorderNetwork; + } + + server cluster DiagnosticLogs { + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + + handle command RetrieveLogsRequest; + } + + server cluster GeneralDiagnostics { + emits event BootReason; + callback attribute networkInterfaces; + callback attribute rebootCount; + callback attribute upTime; + callback attribute totalOperationalHours; + callback attribute bootReason; + callback attribute activeHardwareFaults; + callback attribute activeRadioFaults; + callback attribute activeNetworkFaults; + callback attribute testEventTriggersEnabled default = false; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute attributeList; + callback attribute featureMap; + callback attribute clusterRevision; + + handle command TestEventTrigger; + handle command TimeSnapshot; + handle command TimeSnapshotResponse; + } + + server cluster SoftwareDiagnostics { + emits event SoftwareFault; + callback attribute threadMetrics; + callback attribute currentHeapFree; + callback attribute currentHeapUsed; + callback attribute currentHeapHighWatermark; + callback attribute featureMap; + ram attribute clusterRevision default = 1; + } + + server cluster ThreadNetworkDiagnostics { + callback attribute channel; + callback attribute routingRole; + callback attribute networkName; + callback attribute panId; + callback attribute extendedPanId; + callback attribute meshLocalPrefix; + callback attribute overrunCount; + callback attribute neighborTable; + callback attribute routeTable; + callback attribute partitionId; + callback attribute weighting; + callback attribute dataVersion; + callback attribute stableDataVersion; + callback attribute leaderRouterId; + callback attribute detachedRoleCount; + callback attribute childRoleCount; + callback attribute routerRoleCount; + callback attribute leaderRoleCount; + callback attribute attachAttemptCount; + callback attribute partitionIdChangeCount; + callback attribute betterPartitionAttachAttemptCount; + callback attribute parentChangeCount; + callback attribute txTotalCount; + callback attribute txUnicastCount; + callback attribute txBroadcastCount; + callback attribute txAckRequestedCount; + callback attribute txAckedCount; + callback attribute txNoAckRequestedCount; + callback attribute txDataCount; + callback attribute txDataPollCount; + callback attribute txBeaconCount; + callback attribute txBeaconRequestCount; + callback attribute txOtherCount; + callback attribute txRetryCount; + callback attribute txDirectMaxRetryExpiryCount; + callback attribute txIndirectMaxRetryExpiryCount; + callback attribute txErrCcaCount; + callback attribute txErrAbortCount; + callback attribute txErrBusyChannelCount; + callback attribute rxTotalCount; + callback attribute rxUnicastCount; + callback attribute rxBroadcastCount; + callback attribute rxDataCount; + callback attribute rxDataPollCount; + callback attribute rxBeaconCount; + callback attribute rxBeaconRequestCount; + callback attribute rxOtherCount; + callback attribute rxAddressFilteredCount; + callback attribute rxDestAddrFilteredCount; + callback attribute rxDuplicatedCount; + callback attribute rxErrNoFrameCount; + callback attribute rxErrUnknownNeighborCount; + callback attribute rxErrInvalidSrcAddrCount; + callback attribute rxErrSecCount; + callback attribute rxErrFcsCount; + callback attribute rxErrOtherCount; + callback attribute activeTimestamp; + callback attribute pendingTimestamp; + callback attribute delay; + callback attribute securityPolicy; + callback attribute channelPage0Mask; + callback attribute operationalDatasetComponents; + callback attribute activeNetworkFaultsList; + ram attribute featureMap default = 15; + ram attribute clusterRevision default = 2; + } + + server cluster WiFiNetworkDiagnostics { + emits event Disconnection; + emits event AssociationFailure; + emits event ConnectionStatus; + callback attribute bssid; + callback attribute securityType; + callback attribute wiFiVersion; + callback attribute channelNumber; + callback attribute rssi; + callback attribute beaconLostCount; + callback attribute beaconRxCount; + callback attribute packetMulticastRxCount; + callback attribute packetMulticastTxCount; + callback attribute packetUnicastRxCount; + callback attribute packetUnicastTxCount; + callback attribute currentMaxRate; + callback attribute overrunCount; + ram attribute featureMap default = 3; + ram attribute clusterRevision default = 1; + } + + server cluster EthernetNetworkDiagnostics { + callback attribute PHYRate; + callback attribute fullDuplex; + callback attribute packetRxCount; + callback attribute packetTxCount; + callback attribute txErrCount; + callback attribute collisionCount; + callback attribute overrunCount; + callback attribute carrierDetect; + callback attribute timeSinceReset; + ram attribute featureMap default = 3; + ram attribute clusterRevision default = 1; + + handle command ResetCounts; + } + + server cluster AdministratorCommissioning { + callback attribute windowStatus; + callback attribute adminFabricIndex; + callback attribute adminVendorId; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute attributeList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + + handle command OpenCommissioningWindow; + handle command OpenBasicCommissioningWindow; + handle command RevokeCommissioning; + } + + server cluster OperationalCredentials { + callback attribute NOCs; + callback attribute fabrics; + callback attribute supportedFabrics; + callback attribute commissionedFabrics; + callback attribute trustedRootCertificates; + callback attribute currentFabricIndex; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute attributeList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + + handle command AttestationRequest; + handle command AttestationResponse; + handle command CertificateChainRequest; + handle command CertificateChainResponse; + handle command CSRRequest; + handle command CSRResponse; + handle command AddNOC; + handle command UpdateNOC; + handle command NOCResponse; + handle command UpdateFabricLabel; + handle command RemoveFabric; + handle command AddTrustedRootCertificate; + } + + server cluster GroupKeyManagement { + callback attribute groupKeyMap; + callback attribute groupTable; + callback attribute maxGroupsPerFabric; + callback attribute maxGroupKeysPerFabric; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute attributeList; + callback attribute featureMap; + callback attribute clusterRevision; + + handle command KeySetWrite; + handle command KeySetRead; + handle command KeySetReadResponse; + handle command KeySetRemove; + handle command KeySetReadAllIndices; + handle command KeySetReadAllIndicesResponse; + } +} +endpoint 1 { + device type ma_aggregator = 14, version 1; + + + server cluster Identify { + ram attribute identifyTime default = 0x0; + ram attribute identifyType default = 0x0; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute attributeList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 2; + + handle command Identify; + handle command TriggerEffect; + } + + server cluster Descriptor { + callback attribute deviceTypeList; + callback attribute serverList; + callback attribute clientList; + callback attribute partsList; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute attributeList; + callback attribute featureMap; + callback attribute clusterRevision; + } + + server cluster CommissionerControl { + emits event CommissioningRequestResult; + ram attribute supportedDeviceCategories default = 0; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + + handle command RequestCommissioningApproval; + handle command CommissionNode; + handle command ReverseOpenCommissioningWindow; + } +} + + diff --git a/examples/fabric-sync/bridge/fabric-bridge.zap b/examples/fabric-sync/bridge/fabric-bridge.zap new file mode 100644 index 00000000000000..653742177876cd --- /dev/null +++ b/examples/fabric-sync/bridge/fabric-bridge.zap @@ -0,0 +1,4474 @@ +{ + "fileFormat": 2, + "featureLevel": 103, + "creator": "zap", + "keyValuePairs": [ + { + "key": "commandDiscovery", + "value": "1" + }, + { + "key": "defaultResponsePolicy", + "value": "always" + }, + { + "key": "manufacturerCodes", + "value": "0x1002" + } + ], + "package": [ + { + "pathRelativity": "relativeToZap", + "path": "../../../src/app/zap-templates/zcl/zcl.json", + "type": "zcl-properties", + "category": "matter", + "version": 1, + "description": "Matter SDK ZCL data" + }, + { + "pathRelativity": "relativeToZap", + "path": "../../../src/app/zap-templates/app-templates.json", + "type": "gen-templates-json", + "category": "matter", + "version": "chip-v1" + } + ], + "endpointTypes": [ + { + "id": 1, + "name": "MA-bridge", + "deviceTypeRef": { + "code": 22, + "profileId": 259, + "label": "MA-rootdevice", + "name": "MA-rootdevice" + }, + "deviceTypes": [ + { + "code": 22, + "profileId": 259, + "label": "MA-rootdevice", + "name": "MA-rootdevice" + } + ], + "deviceVersions": [ + 1 + ], + "deviceIdentifiers": [ + 22 + ], + "deviceTypeName": "MA-rootdevice", + "deviceTypeCode": 22, + "deviceTypeProfileId": 259, + "clusters": [ + { + "name": "Descriptor", + "code": 29, + "mfgCode": null, + "define": "DESCRIPTOR_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "DeviceTypeList", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ServerList", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ClientList", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "PartsList", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Access Control", + "code": 31, + "mfgCode": null, + "define": "ACCESS_CONTROL_CLUSTER", + "side": "client", + "enabled": 1 + }, + { + "name": "Access Control", + "code": 31, + "mfgCode": null, + "define": "ACCESS_CONTROL_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "ACL", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "Extension", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "SubjectsPerAccessControlEntry", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "TargetsPerAccessControlEntry", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AccessControlEntriesPerFabric", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ], + "events": [ + { + "name": "AccessControlEntryChanged", + "code": 0, + "mfgCode": null, + "side": "server", + "included": 1 + } + ] + }, + { + "name": "Basic Information", + "code": 40, + "mfgCode": null, + "define": "BASIC_INFORMATION_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "DataModelRevision", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "VendorName", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "VendorID", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "vendor_id", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ProductName", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ProductID", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "NodeLabel", + "code": 5, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "NVM", + "singleton": 1, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "Location", + "code": 6, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "HardwareVersion", + "code": 7, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "HardwareVersionString", + "code": 8, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "SoftwareVersion", + "code": 9, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "SoftwareVersionString", + "code": 10, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ManufacturingDate", + "code": 11, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "PartNumber", + "code": 12, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ProductURL", + "code": 13, + "mfgCode": null, + "side": "server", + "type": "long_char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ProductLabel", + "code": 14, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "SerialNumber", + "code": 15, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "LocalConfigDisabled", + "code": 16, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "NVM", + "singleton": 1, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "UniqueID", + "code": 18, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "CapabilityMinima", + "code": 19, + "mfgCode": null, + "side": "server", + "type": "CapabilityMinimaStruct", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "SpecificationVersion", + "code": 21, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "MaxPathsPerInvoke", + "code": 22, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 1, + "bounded": 0, + "defaultValue": "3", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ], + "events": [ + { + "name": "StartUp", + "code": 0, + "mfgCode": null, + "side": "server", + "included": 1 + }, + { + "name": "ShutDown", + "code": 1, + "mfgCode": null, + "side": "server", + "included": 1 + }, + { + "name": "Leave", + "code": 2, + "mfgCode": null, + "side": "server", + "included": 1 + } + ] + }, + { + "name": "General Commissioning", + "code": 48, + "mfgCode": null, + "define": "GENERAL_COMMISSIONING_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "ArmFailSafe", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "ArmFailSafeResponse", + "code": 1, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "SetRegulatoryConfig", + "code": 2, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "SetRegulatoryConfigResponse", + "code": 3, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "CommissioningComplete", + "code": 4, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "CommissioningCompleteResponse", + "code": 5, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "Breadcrumb", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000000000000000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "BasicCommissioningInfo", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "BasicCommissioningInfo", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RegulatoryConfig", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "RegulatoryLocationTypeEnum", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "LocationCapability", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "RegulatoryLocationTypeEnum", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "SupportsConcurrentConnection", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Network Commissioning", + "code": 49, + "mfgCode": null, + "define": "NETWORK_COMMISSIONING_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "ScanNetworks", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "ScanNetworksResponse", + "code": 1, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "AddOrUpdateWiFiNetwork", + "code": 2, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "AddOrUpdateThreadNetwork", + "code": 3, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "RemoveNetwork", + "code": 4, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "NetworkConfigResponse", + "code": 5, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "ConnectNetwork", + "code": 6, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "ConnectNetworkResponse", + "code": 7, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "ReorderNetwork", + "code": 8, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "MaxNetworks", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "Networks", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ScanMaxTimeSeconds", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ConnectMaxTimeSeconds", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "InterfaceEnabled", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "LastNetworkingStatus", + "code": 5, + "mfgCode": null, + "side": "server", + "type": "NetworkCommissioningStatusEnum", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "LastNetworkID", + "code": 6, + "mfgCode": null, + "side": "server", + "type": "octet_string", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "LastConnectErrorValue", + "code": 7, + "mfgCode": null, + "side": "server", + "type": "int32s", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "2", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Diagnostic Logs", + "code": 50, + "mfgCode": null, + "define": "DIAGNOSTIC_LOGS_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "RetrieveLogsRequest", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "General Diagnostics", + "code": 51, + "mfgCode": null, + "define": "GENERAL_DIAGNOSTICS_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "TestEventTrigger", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "TimeSnapshot", + "code": 1, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "TimeSnapshotResponse", + "code": 2, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "NetworkInterfaces", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RebootCount", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "UpTime", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "TotalOperationalHours", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "BootReason", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "BootReasonEnum", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ActiveHardwareFaults", + "code": 5, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ActiveRadioFaults", + "code": 6, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ActiveNetworkFaults", + "code": 7, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "TestEventTriggersEnabled", + "code": 8, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "false", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ], + "events": [ + { + "name": "BootReason", + "code": 3, + "mfgCode": null, + "side": "server", + "included": 1 + } + ] + }, + { + "name": "Software Diagnostics", + "code": 52, + "mfgCode": null, + "define": "SOFTWARE_DIAGNOSTICS_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "ThreadMetrics", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "CurrentHeapFree", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "CurrentHeapUsed", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "CurrentHeapHighWatermark", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ], + "events": [ + { + "name": "SoftwareFault", + "code": 0, + "mfgCode": null, + "side": "server", + "included": 1 + } + ] + }, + { + "name": "Thread Network Diagnostics", + "code": 53, + "mfgCode": null, + "define": "THREAD_NETWORK_DIAGNOSTICS_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "Channel", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RoutingRole", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "RoutingRoleEnum", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "NetworkName", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "PanId", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ExtendedPanId", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "MeshLocalPrefix", + "code": 5, + "mfgCode": null, + "side": "server", + "type": "octet_string", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "OverrunCount", + "code": 6, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "NeighborTable", + "code": 7, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RouteTable", + "code": 8, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "PartitionId", + "code": 9, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "Weighting", + "code": 10, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "DataVersion", + "code": 11, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "StableDataVersion", + "code": 12, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "LeaderRouterId", + "code": 13, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "DetachedRoleCount", + "code": 14, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ChildRoleCount", + "code": 15, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RouterRoleCount", + "code": 16, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "LeaderRoleCount", + "code": 17, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "AttachAttemptCount", + "code": 18, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "PartitionIdChangeCount", + "code": 19, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "BetterPartitionAttachAttemptCount", + "code": 20, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ParentChangeCount", + "code": 21, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxTotalCount", + "code": 22, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxUnicastCount", + "code": 23, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxBroadcastCount", + "code": 24, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxAckRequestedCount", + "code": 25, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxAckedCount", + "code": 26, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxNoAckRequestedCount", + "code": 27, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxDataCount", + "code": 28, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxDataPollCount", + "code": 29, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxBeaconCount", + "code": 30, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxBeaconRequestCount", + "code": 31, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxOtherCount", + "code": 32, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxRetryCount", + "code": 33, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxDirectMaxRetryExpiryCount", + "code": 34, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxIndirectMaxRetryExpiryCount", + "code": 35, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxErrCcaCount", + "code": 36, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxErrAbortCount", + "code": 37, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxErrBusyChannelCount", + "code": 38, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxTotalCount", + "code": 39, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxUnicastCount", + "code": 40, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxBroadcastCount", + "code": 41, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxDataCount", + "code": 42, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxDataPollCount", + "code": 43, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxBeaconCount", + "code": 44, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxBeaconRequestCount", + "code": 45, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxOtherCount", + "code": 46, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxAddressFilteredCount", + "code": 47, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxDestAddrFilteredCount", + "code": 48, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxDuplicatedCount", + "code": 49, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxErrNoFrameCount", + "code": 50, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxErrUnknownNeighborCount", + "code": 51, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxErrInvalidSrcAddrCount", + "code": 52, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxErrSecCount", + "code": 53, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxErrFcsCount", + "code": 54, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxErrOtherCount", + "code": 55, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ActiveTimestamp", + "code": 56, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "PendingTimestamp", + "code": 57, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "Delay", + "code": 58, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "SecurityPolicy", + "code": 59, + "mfgCode": null, + "side": "server", + "type": "SecurityPolicy", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ChannelPage0Mask", + "code": 60, + "mfgCode": null, + "side": "server", + "type": "octet_string", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "OperationalDatasetComponents", + "code": 61, + "mfgCode": null, + "side": "server", + "type": "OperationalDatasetComponents", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ActiveNetworkFaultsList", + "code": 62, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "15", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "2", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Wi-Fi Network Diagnostics", + "code": 54, + "mfgCode": null, + "define": "WIFI_NETWORK_DIAGNOSTICS_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "BSSID", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "octet_string", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "SecurityType", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "SecurityTypeEnum", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "WiFiVersion", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "WiFiVersionEnum", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ChannelNumber", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RSSI", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "int8s", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "BeaconLostCount", + "code": 5, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "BeaconRxCount", + "code": 6, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "PacketMulticastRxCount", + "code": 7, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "PacketMulticastTxCount", + "code": 8, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "PacketUnicastRxCount", + "code": 9, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "PacketUnicastTxCount", + "code": 10, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "CurrentMaxRate", + "code": 11, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "OverrunCount", + "code": 12, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "3", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ], + "events": [ + { + "name": "Disconnection", + "code": 0, + "mfgCode": null, + "side": "server", + "included": 1 + }, + { + "name": "AssociationFailure", + "code": 1, + "mfgCode": null, + "side": "server", + "included": 1 + }, + { + "name": "ConnectionStatus", + "code": 2, + "mfgCode": null, + "side": "server", + "included": 1 + } + ] + }, + { + "name": "Ethernet Network Diagnostics", + "code": 55, + "mfgCode": null, + "define": "ETHERNET_NETWORK_DIAGNOSTICS_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "ResetCounts", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "PHYRate", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "PHYRateEnum", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FullDuplex", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "PacketRxCount", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "PacketTxCount", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxErrCount", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "CollisionCount", + "code": 5, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "OverrunCount", + "code": 6, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "CarrierDetect", + "code": 7, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "TimeSinceReset", + "code": 8, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "3", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Administrator Commissioning", + "code": 60, + "mfgCode": null, + "define": "ADMINISTRATOR_COMMISSIONING_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "OpenCommissioningWindow", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "OpenBasicCommissioningWindow", + "code": 1, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "RevokeCommissioning", + "code": 2, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "WindowStatus", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "CommissioningWindowStatusEnum", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AdminFabricIndex", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "fabric_idx", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AdminVendorId", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "vendor_id", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Operational Credentials", + "code": 62, + "mfgCode": null, + "define": "OPERATIONAL_CREDENTIALS_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "AttestationRequest", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "AttestationResponse", + "code": 1, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "CertificateChainRequest", + "code": 2, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "CertificateChainResponse", + "code": 3, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "CSRRequest", + "code": 4, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "CSRResponse", + "code": 5, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "AddNOC", + "code": 6, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "UpdateNOC", + "code": 7, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "NOCResponse", + "code": 8, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "UpdateFabricLabel", + "code": 9, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "RemoveFabric", + "code": 10, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "AddTrustedRootCertificate", + "code": 11, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "NOCs", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "Fabrics", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "SupportedFabrics", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "CommissionedFabrics", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TrustedRootCertificates", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "CurrentFabricIndex", + "code": 5, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Group Key Management", + "code": 63, + "mfgCode": null, + "define": "GROUP_KEY_MANAGEMENT_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "KeySetWrite", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "KeySetRead", + "code": 1, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "KeySetReadResponse", + "code": 2, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "KeySetRemove", + "code": 3, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "KeySetReadAllIndices", + "code": 4, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "KeySetReadAllIndicesResponse", + "code": 5, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "GroupKeyMap", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GroupTable", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "MaxGroupsPerFabric", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "MaxGroupKeysPerFabric", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + } + ] + }, + { + "id": 2, + "name": "Anonymous Endpoint Type", + "deviceTypeRef": { + "code": 14, + "profileId": 259, + "label": "MA-aggregator", + "name": "MA-aggregator" + }, + "deviceTypes": [ + { + "code": 14, + "profileId": 259, + "label": "MA-aggregator", + "name": "MA-aggregator" + } + ], + "deviceVersions": [ + 1 + ], + "deviceIdentifiers": [ + 14 + ], + "deviceTypeName": "MA-aggregator", + "deviceTypeCode": 14, + "deviceTypeProfileId": 259, + "clusters": [ + { + "name": "Identify", + "code": 3, + "mfgCode": null, + "define": "IDENTIFY_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "Identify", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "TriggerEffect", + "code": 64, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "IdentifyTime", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "IdentifyType", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "IdentifyTypeEnum", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "2", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "Descriptor", + "code": 29, + "mfgCode": null, + "define": "DESCRIPTOR_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "DeviceTypeList", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ServerList", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClientList", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "PartsList", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "Commissioner Control", + "code": 1873, + "mfgCode": null, + "define": "COMMISSIONER_CONTROL_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "RequestCommissioningApproval", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "CommissionNode", + "code": 1, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "ReverseOpenCommissioningWindow", + "code": 2, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "SupportedDeviceCategories", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "SupportedDeviceCategoryBitmap", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ], + "events": [ + { + "name": "CommissioningRequestResult", + "code": 0, + "mfgCode": null, + "side": "server", + "included": 1 + } + ] + } + ] + } + ], + "endpoints": [ + { + "endpointTypeName": "MA-bridge", + "endpointTypeIndex": 0, + "profileId": 259, + "endpointId": 0, + "networkId": 0, + "parentEndpointIdentifier": null + }, + { + "endpointTypeName": "Anonymous Endpoint Type", + "endpointTypeIndex": 1, + "profileId": 259, + "endpointId": 1, + "networkId": 0, + "parentEndpointIdentifier": null + } + ] +} \ No newline at end of file diff --git a/examples/fabric-sync/bridge/include/CHIPProjectAppConfig.h b/examples/fabric-sync/bridge/include/CHIPProjectAppConfig.h new file mode 100644 index 00000000000000..b2a999da741088 --- /dev/null +++ b/examples/fabric-sync/bridge/include/CHIPProjectAppConfig.h @@ -0,0 +1,80 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * @file + * Example project configuration file for CHIP. + * + * This is a place to put application or project-specific overrides + * to the default configuration values for general CHIP features. + * + */ + +#pragma once + +// FabricSync needs to be commissioners and likely want to be discoverable +#define CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY 1 + +// FabricSync can handle the memory impact of supporting a larger list +#define CHIP_DEVICE_CONFIG_UDC_MAX_TARGET_APPS 10 + +// FabricSync will often enable this feature +#define CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_PASSCODE 1 + +// FabricSync needs to be both commissioners and commissionees +#define CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE 1 + +// See issue 23625. +#define CHIP_CONFIG_UNSAFE_SUBSCRIPTION_EXCHANGE_MANAGER_USE 1 + +// FabricSync that are not commissionees, +// or that don't automatically enter commissioning mode should set this to 0 +#define CHIP_DEVICE_CONFIG_ENABLE_PAIRING_AUTOSTART 1 + +// FabricSync do not typically need this - enable for debugging +// #define CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT 1 + +// Enable extended discovery, set timeout to 24 hours +#define CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY 1 +#define CHIP_DEVICE_CONFIG_EXTENDED_DISCOVERY_TIMEOUT_SECS (24 * 60 * 60) + +// Advertise TV device type in DNS-SD +#define CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONABLE_DEVICE_TYPE 1 + +#define CHIP_DEVICE_CONFIG_DEVICE_TYPE 35 // 0x0023 = 35 = Video Player + +// Include device name in discovery for casting use case +#define CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONABLE_DEVICE_NAME 1 +#define CHIP_DEVICE_CONFIG_DEVICE_NAME "Test TV" + +// Enable app platform +#define CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED 1 + +// overrides CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT in CHIPProjectConfig +#define CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT 16 + +// For casting, we need to allow more ACL entries, and more complex entries +#define CHIP_CONFIG_EXAMPLE_ACCESS_CONTROL_MAX_TARGETS_PER_ENTRY 20 +#define CHIP_CONFIG_EXAMPLE_ACCESS_CONTROL_MAX_SUBJECTS_PER_ENTRY 20 +#define CHIP_CONFIG_EXAMPLE_ACCESS_CONTROL_MAX_ENTRIES_PER_FABRIC 20 + +// Allows app options (ports) to be configured on launch of app +#define CHIP_DEVICE_ENABLE_PORT_PARAMS 1 + +// Include the CHIPProjectConfig from platform implementation config +#include diff --git a/examples/fabric-sync/build_overrides b/examples/fabric-sync/build_overrides new file mode 120000 index 00000000000000..b430cf6a2e6391 --- /dev/null +++ b/examples/fabric-sync/build_overrides @@ -0,0 +1 @@ +../build_overrides \ No newline at end of file diff --git a/examples/fabric-sync/main.cpp b/examples/fabric-sync/main.cpp new file mode 100644 index 00000000000000..84c014dfcbf010 --- /dev/null +++ b/examples/fabric-sync/main.cpp @@ -0,0 +1,41 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +using namespace chip; + +void ApplicationInit() +{ + ChipLogProgress(NotSpecified, "Fabric-Sync: ApplicationInit()"); +} + +void ApplicationShutdown() +{ + ChipLogDetail(NotSpecified, "Fabric-Sync: ApplicationShutdown()"); +} + +int main(int argc, char * argv[]) +{ + + VerifyOrDie(ChipLinuxAppInit(argc, argv) == 0); + + ChipLinuxAppMainLoop(); + + return 0; +} diff --git a/examples/fabric-sync/third_party/connectedhomeip b/examples/fabric-sync/third_party/connectedhomeip new file mode 120000 index 00000000000000..1b20c9fb816b63 --- /dev/null +++ b/examples/fabric-sync/third_party/connectedhomeip @@ -0,0 +1 @@ +../../../ \ No newline at end of file From 7d6373f33600b3d7ef670867b649557b44d43e09 Mon Sep 17 00:00:00 2001 From: C Freeman Date: Fri, 18 Oct 2024 19:19:49 -0400 Subject: [PATCH 046/149] Add an ALL_EVENTS maps in symmetry to ALL_ATTRIBUTES (#35661) * add an ALL_EVENTS * But do it correctly * Remove try: except: and let badly subclassed items fail * Fix unit tests to instantiate the classes properly --- .../python/chip/clusters/ClusterObjects.py | 32 +++++++++---------- .../test/unit_tests/test_cluster_objects.py | 24 ++++++++++++++ 2 files changed, 40 insertions(+), 16 deletions(-) diff --git a/src/controller/python/chip/clusters/ClusterObjects.py b/src/controller/python/chip/clusters/ClusterObjects.py index ddafe87bf2c89d..beb490c631ab50 100644 --- a/src/controller/python/chip/clusters/ClusterObjects.py +++ b/src/controller/python/chip/clusters/ClusterObjects.py @@ -214,6 +214,7 @@ def descriptor(cls): # These need to be separate because there can be overlap in command ids for commands and responses. ALL_ACCEPTED_COMMANDS: typing.Dict = {} ALL_GENERATED_COMMANDS: typing.Dict = {} +ALL_EVENTS: typing.Dict = {} class ClusterCommand(ClusterObject): @@ -261,12 +262,7 @@ def __init_subclass__(cls, *args, **kwargs) -> None: """Register a subclass.""" super().__init_subclass__(*args, **kwargs) # register this cluster in the ALL_CLUSTERS dict for quick lookups - try: - ALL_CLUSTERS[cls.id] = cls - except NotImplementedError: - # handle case where the Cluster class is not (fully) subclassed - # and accessing the id property throws a NotImplementedError. - pass + ALL_CLUSTERS[cls.id] = cls @property def data_version(self) -> int: @@ -300,16 +296,11 @@ class ClusterAttributeDescriptor: def __init_subclass__(cls, *args, **kwargs) -> None: """Register a subclass.""" super().__init_subclass__(*args, **kwargs) - try: - if cls.standard_attribute: - if cls.cluster_id not in ALL_ATTRIBUTES: - ALL_ATTRIBUTES[cls.cluster_id] = {} - # register this clusterattribute in the ALL_ATTRIBUTES dict for quick lookups - ALL_ATTRIBUTES[cls.cluster_id][cls.attribute_id] = cls - except NotImplementedError: - # handle case where the ClusterAttribute class is not (fully) subclassed - # and accessing the id property throws a NotImplementedError. - pass + if cls.standard_attribute: + if cls.cluster_id not in ALL_ATTRIBUTES: + ALL_ATTRIBUTES[cls.cluster_id] = {} + # register this clusterattribute in the ALL_ATTRIBUTES dict for quick lookups + ALL_ATTRIBUTES[cls.cluster_id][cls.attribute_id] = cls @classmethod def ToTLV(cls, tag: Union[int, None], value): @@ -369,6 +360,15 @@ def _cluster_object(cls) -> ClusterObject: class ClusterEvent(ClusterObject): + def __init_subclass__(cls, *args, **kwargs) -> None: + """Register a subclass.""" + super().__init_subclass__(*args, **kwargs) + + if cls.cluster_id not in ALL_EVENTS: + ALL_EVENTS[cls.cluster_id] = {} + # register this clusterattribute in the ALL_ATTRIBUTES dict for quick lookups + ALL_EVENTS[cls.cluster_id][cls.event_id] = cls + @ChipUtility.classproperty def cluster_id(self) -> int: raise NotImplementedError() diff --git a/src/controller/python/test/unit_tests/test_cluster_objects.py b/src/controller/python/test/unit_tests/test_cluster_objects.py index 13b12db185270e..beca5ff39863d9 100644 --- a/src/controller/python/test/unit_tests/test_cluster_objects.py +++ b/src/controller/python/test/unit_tests/test_cluster_objects.py @@ -193,6 +193,14 @@ class IntAttribute(ClusterObjects.ClusterAttributeDescriptor): def attribute_type(cls) -> ClusterObjects.ClusterObjectFieldDescriptor: return ClusterObjects.ClusterObjectFieldDescriptor(Type=int) + @chip.ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000000 + + @chip.ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x00000000 + def test_basic_encode(self): res = _encode_attribute_and_then_decode_to_native( 42, TestAttributeDescriptor.IntAttribute) @@ -208,6 +216,14 @@ class StructAttribute(ClusterObjects.ClusterAttributeDescriptor): def attribute_type(cls) -> ClusterObjects.ClusterObjectFieldDescriptor: return ClusterObjects.ClusterObjectFieldDescriptor(Type=TestClusterObjects.C) + @chip.ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000000 + + @chip.ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x00000000 + def test_struct_encode(self): res = _encode_attribute_and_then_decode_to_native( TestClusterObjects.C(X=42, Y=24), TestAttributeDescriptor.StructAttribute) @@ -223,6 +239,14 @@ class ArrayAttribute(ClusterObjects.ClusterAttributeDescriptor): def attribute_type(cls) -> ClusterObjects.ClusterObjectFieldDescriptor: return ClusterObjects.ClusterObjectFieldDescriptor(Type=typing.List[int]) + @chip.ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000000 + + @chip.ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x00000000 + def test_array_encode(self): res = _encode_attribute_and_then_decode_to_native( [1, 2, 3, 4, 5], TestAttributeDescriptor.ArrayAttribute) From 3d755733fa935d973e8d5d5d31af08cb9ba7078a Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Fri, 18 Oct 2024 22:20:20 -0400 Subject: [PATCH 047/149] Move some MTRDevice_Concrete-specific constants to MTRDevice_Concrete. (#36152) --- src/darwin/Framework/CHIP/MTRDevice.mm | 5 ----- src/darwin/Framework/CHIP/MTRDevice_Concrete.mm | 4 ++++ 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/darwin/Framework/CHIP/MTRDevice.mm b/src/darwin/Framework/CHIP/MTRDevice.mm index 0bfdf44efb0d9a..e0154fdb8934e6 100644 --- a/src/darwin/Framework/CHIP/MTRDevice.mm +++ b/src/darwin/Framework/CHIP/MTRDevice.mm @@ -38,11 +38,6 @@ #import "lib/core/CHIPError.h" -// TODO Should these string definitions just move to MTRDevice_Concrete, since -// that's the only place they are used? -NSString * const MTRPreviousDataKey = @"previousData"; -NSString * const MTRDataVersionKey = @"dataVersion"; - @implementation MTRDeviceDelegateInfo - (instancetype)initWithDelegate:(id)delegate queue:(dispatch_queue_t)queue interestedPathsForAttributes:(NSArray * _Nullable)interestedPathsForAttributes interestedPathsForEvents:(NSArray * _Nullable)interestedPathsForEvents { diff --git a/src/darwin/Framework/CHIP/MTRDevice_Concrete.mm b/src/darwin/Framework/CHIP/MTRDevice_Concrete.mm index 48d7f7f99d0fe7..7276a5b5342eb1 100644 --- a/src/darwin/Framework/CHIP/MTRDevice_Concrete.mm +++ b/src/darwin/Framework/CHIP/MTRDevice_Concrete.mm @@ -58,6 +58,10 @@ static NSString * const sLastInitialSubscribeLatencyKey = @"lastInitialSubscribeLatency"; +// Not static, because these are public API. +NSString * const MTRPreviousDataKey = @"previousData"; +NSString * const MTRDataVersionKey = @"dataVersion"; + // allow readwrite access to superclass properties @interface MTRDevice_Concrete () From 79c1cf5cb093448d1eb6ee9b5f31c68b75c241c8 Mon Sep 17 00:00:00 2001 From: Vivien Nicolas Date: Sat, 19 Oct 2024 10:57:43 +0200 Subject: [PATCH 048/149] =?UTF-8?q?[Matter.framework]=20Backtrace=20loggin?= =?UTF-8?q?g=20for=20MTRDeviceControllerFactory::=E2=80=A6=20(#36113)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [Matter.framework] Backtrace logging for MTRDeviceControllerFactory::startControllerFactory/stopControllerFactory * Update src/darwin/Framework/CHIP/MTRDeviceControllerFactory.mm --------- Co-authored-by: Justin Wood --- src/darwin/Framework/CHIP/MTRDeviceControllerFactory.mm | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/darwin/Framework/CHIP/MTRDeviceControllerFactory.mm b/src/darwin/Framework/CHIP/MTRDeviceControllerFactory.mm index 750ab648cb7bfa..8ab6a7dc365f2a 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceControllerFactory.mm +++ b/src/darwin/Framework/CHIP/MTRDeviceControllerFactory.mm @@ -327,6 +327,7 @@ - (BOOL)_startControllerFactory:(MTRDeviceControllerFactoryParams *)startupParam error:(NSError * __autoreleasing *)error { [self _assertCurrentQueueIsNotMatterQueue]; + [self _maybeLogBacktrace:@"Controller Factory Start"]; __block CHIP_ERROR err = CHIP_ERROR_INTERNAL; dispatch_sync(_chipWorkQueue, ^{ @@ -418,6 +419,7 @@ - (BOOL)_startControllerFactory:(MTRDeviceControllerFactoryParams *)startupParam - (void)stopControllerFactory { [self _assertCurrentQueueIsNotMatterQueue]; + [self _maybeLogBacktrace:@"Controller Factory Stop"]; for (MTRDeviceController * controller in [_controllers copy]) { [controller shutdown]; @@ -1245,6 +1247,13 @@ - (FabricTable * _Nullable)fabricTable return systemState->Fabrics(); } +- (void)_maybeLogBacktrace:(NSString *)message +{ + @autoreleasepool { + MTR_LOG("[%@]: %@", message, [NSThread callStackSymbols]); + } +} + @end @interface MTRDummyStorage : NSObject From d7abcbfc3a0b7782df950ec49a830c0579dfd9ad Mon Sep 17 00:00:00 2001 From: C Freeman Date: Sun, 20 Oct 2024 14:58:39 -0400 Subject: [PATCH 049/149] DM XMLs 1.4 tag (#36153) * DM XMLs 1.4 tag * Update to master --- .../1.4/clusters/DeviceEnergyManagement.xml | 8 +---- .../1.4/clusters/DiagnosticsGeneral.xml | 1 - data_model/1.4/clusters/DiagnosticsThread.xml | 10 ++++-- data_model/1.4/clusters/DoorLock.xml | 5 +-- ...er.xml => EcosystemInformationCluster.xml} | 0 data_model/1.4/clusters/EnergyEVSE.xml | 6 +--- data_model/1.4/clusters/ICDManagement.xml | 34 ++++++------------- data_model/1.4/clusters/LevelControl.xml | 1 - .../clusters/Mode_DeviceEnergyManagement.xml | 4 +-- data_model/1.4/clusters/Mode_Dishwasher.xml | 3 +- data_model/1.4/clusters/Mode_EVSE.xml | 2 +- .../1.4/clusters/Mode_LaundryWasher.xml | 3 +- .../1.4/clusters/Mode_MicrowaveOven.xml | 3 +- data_model/1.4/clusters/Mode_Oven.xml | 3 +- data_model/1.4/clusters/Mode_Refrigerator.xml | 3 +- data_model/1.4/clusters/OccupancySensing.xml | 2 +- data_model/1.4/clusters/OperationalState.xml | 5 +-- .../1.4/clusters/OperationalState_Oven.xml | 3 +- .../1.4/clusters/OperationalState_RVC.xml | 5 +-- .../1.4/clusters/PumpConfigurationControl.xml | 5 +-- data_model/1.4/clusters/Scenes.xml | 6 ++-- .../ThermostatUserInterfaceConfiguration.xml | 3 -- .../1.4/clusters/WaterHeaterManagement.xml | 2 -- .../device_types/DeviceEnergyManagement.xml | 6 +--- data_model/1.4/device_types/HeatPump.xml | 2 +- .../1.4/device_types/RootNodeDeviceType.xml | 14 ++++---- data_model/1.4/spec_sha | 2 +- 27 files changed, 53 insertions(+), 88 deletions(-) rename data_model/1.4/clusters/{bridge-clusters-EcosystemInformationCluster.xml => EcosystemInformationCluster.xml} (100%) diff --git a/data_model/1.4/clusters/DeviceEnergyManagement.xml b/data_model/1.4/clusters/DeviceEnergyManagement.xml index 776a06f20b3fd4..3b95a7b8d449dc 100644 --- a/data_model/1.4/clusters/DeviceEnergyManagement.xml +++ b/data_model/1.4/clusters/DeviceEnergyManagement.xml @@ -65,9 +65,7 @@ Davis, CA 95616, USA - - - + @@ -566,7 +564,6 @@ Davis, CA 95616, USA - @@ -580,7 +577,6 @@ Davis, CA 95616, USA - @@ -604,7 +600,6 @@ Davis, CA 95616, USA - @@ -619,7 +614,6 @@ Davis, CA 95616, USA - diff --git a/data_model/1.4/clusters/DiagnosticsGeneral.xml b/data_model/1.4/clusters/DiagnosticsGeneral.xml index 44b891fbcd6ea4..1266705ba6d0dc 100644 --- a/data_model/1.4/clusters/DiagnosticsGeneral.xml +++ b/data_model/1.4/clusters/DiagnosticsGeneral.xml @@ -263,7 +263,6 @@ Davis, CA 95616, USA - diff --git a/data_model/1.4/clusters/DiagnosticsThread.xml b/data_model/1.4/clusters/DiagnosticsThread.xml index a55412d7fd3eff..a712cebc8f1bf0 100644 --- a/data_model/1.4/clusters/DiagnosticsThread.xml +++ b/data_model/1.4/clusters/DiagnosticsThread.xml @@ -669,12 +669,18 @@ Davis, CA 95616, USA - + + + + - + + + + diff --git a/data_model/1.4/clusters/DoorLock.xml b/data_model/1.4/clusters/DoorLock.xml index 46d659da94a690..932532c768d423 100644 --- a/data_model/1.4/clusters/DoorLock.xml +++ b/data_model/1.4/clusters/DoorLock.xml @@ -66,7 +66,7 @@ Davis, CA 95616, USA - @@ -600,9 +600,6 @@ Davis, CA 95616, USA - - - diff --git a/data_model/1.4/clusters/bridge-clusters-EcosystemInformationCluster.xml b/data_model/1.4/clusters/EcosystemInformationCluster.xml similarity index 100% rename from data_model/1.4/clusters/bridge-clusters-EcosystemInformationCluster.xml rename to data_model/1.4/clusters/EcosystemInformationCluster.xml diff --git a/data_model/1.4/clusters/EnergyEVSE.xml b/data_model/1.4/clusters/EnergyEVSE.xml index a4c865c3096a60..352ac7e24ad205 100644 --- a/data_model/1.4/clusters/EnergyEVSE.xml +++ b/data_model/1.4/clusters/EnergyEVSE.xml @@ -69,10 +69,7 @@ Davis, CA 95616, USA - - - - + @@ -240,7 +237,6 @@ Davis, CA 95616, USA - diff --git a/data_model/1.4/clusters/ICDManagement.xml b/data_model/1.4/clusters/ICDManagement.xml index b6f76f48e2b137..d9cb7397da7256 100644 --- a/data_model/1.4/clusters/ICDManagement.xml +++ b/data_model/1.4/clusters/ICDManagement.xml @@ -70,7 +70,6 @@ Davis, CA 95616, USA - @@ -79,7 +78,6 @@ Davis, CA 95616, USA - @@ -87,18 +85,12 @@ Davis, CA 95616, USA - - - - + - - - - - - + + + @@ -227,12 +219,9 @@ Davis, CA 95616, USA - - - - - - + + + @@ -242,12 +231,9 @@ Davis, CA 95616, USA - - - - - - + + + diff --git a/data_model/1.4/clusters/LevelControl.xml b/data_model/1.4/clusters/LevelControl.xml index 404b1250e90acc..1a034d5802bb73 100644 --- a/data_model/1.4/clusters/LevelControl.xml +++ b/data_model/1.4/clusters/LevelControl.xml @@ -165,7 +165,6 @@ Davis, CA 95616, USA - diff --git a/data_model/1.4/clusters/Mode_DeviceEnergyManagement.xml b/data_model/1.4/clusters/Mode_DeviceEnergyManagement.xml index 48cf6df4955a15..9fca7f31ca00e7 100644 --- a/data_model/1.4/clusters/Mode_DeviceEnergyManagement.xml +++ b/data_model/1.4/clusters/Mode_DeviceEnergyManagement.xml @@ -63,9 +63,7 @@ Davis, CA 95616, USA - - - + diff --git a/data_model/1.4/clusters/Mode_Dishwasher.xml b/data_model/1.4/clusters/Mode_Dishwasher.xml index 1c3a99b9e3d245..ca14d02672dd2c 100644 --- a/data_model/1.4/clusters/Mode_Dishwasher.xml +++ b/data_model/1.4/clusters/Mode_Dishwasher.xml @@ -57,10 +57,11 @@ Davis, CA 95616, USA :xrefstyle: basic --> - + + diff --git a/data_model/1.4/clusters/Mode_EVSE.xml b/data_model/1.4/clusters/Mode_EVSE.xml index 025e9de9884c89..863a2b7d6446c1 100644 --- a/data_model/1.4/clusters/Mode_EVSE.xml +++ b/data_model/1.4/clusters/Mode_EVSE.xml @@ -60,7 +60,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.4/clusters/Mode_LaundryWasher.xml b/data_model/1.4/clusters/Mode_LaundryWasher.xml index b5f557a4b46a4b..a13253304d2ef3 100644 --- a/data_model/1.4/clusters/Mode_LaundryWasher.xml +++ b/data_model/1.4/clusters/Mode_LaundryWasher.xml @@ -57,10 +57,11 @@ Davis, CA 95616, USA :xrefstyle: basic --> - + + diff --git a/data_model/1.4/clusters/Mode_MicrowaveOven.xml b/data_model/1.4/clusters/Mode_MicrowaveOven.xml index 24d682fecac68b..371b294849143d 100644 --- a/data_model/1.4/clusters/Mode_MicrowaveOven.xml +++ b/data_model/1.4/clusters/Mode_MicrowaveOven.xml @@ -57,9 +57,10 @@ Davis, CA 95616, USA :xrefstyle: basic --> - + + diff --git a/data_model/1.4/clusters/Mode_Oven.xml b/data_model/1.4/clusters/Mode_Oven.xml index a3e3323fe98777..071f70d277a0e6 100644 --- a/data_model/1.4/clusters/Mode_Oven.xml +++ b/data_model/1.4/clusters/Mode_Oven.xml @@ -57,9 +57,10 @@ Davis, CA 95616, USA :xrefstyle: basic --> - + + diff --git a/data_model/1.4/clusters/Mode_Refrigerator.xml b/data_model/1.4/clusters/Mode_Refrigerator.xml index 2728ac0f42b8fb..692740e090f198 100644 --- a/data_model/1.4/clusters/Mode_Refrigerator.xml +++ b/data_model/1.4/clusters/Mode_Refrigerator.xml @@ -57,10 +57,11 @@ Davis, CA 95616, USA :xrefstyle: basic --> - + + diff --git a/data_model/1.4/clusters/OccupancySensing.xml b/data_model/1.4/clusters/OccupancySensing.xml index 7ca0d3631dbe05..7400dde084f7d0 100644 --- a/data_model/1.4/clusters/OccupancySensing.xml +++ b/data_model/1.4/clusters/OccupancySensing.xml @@ -173,7 +173,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.4/clusters/OperationalState.xml b/data_model/1.4/clusters/OperationalState.xml index 354efa2400bda7..d02635cf65fabd 100644 --- a/data_model/1.4/clusters/OperationalState.xml +++ b/data_model/1.4/clusters/OperationalState.xml @@ -203,10 +203,7 @@ Davis, CA 95616, USA - - - - + diff --git a/data_model/1.4/clusters/OperationalState_Oven.xml b/data_model/1.4/clusters/OperationalState_Oven.xml index 710dea9806bf57..e743fbf1d7752c 100644 --- a/data_model/1.4/clusters/OperationalState_Oven.xml +++ b/data_model/1.4/clusters/OperationalState_Oven.xml @@ -57,9 +57,10 @@ Davis, CA 95616, USA :xrefstyle: basic --> - + + diff --git a/data_model/1.4/clusters/OperationalState_RVC.xml b/data_model/1.4/clusters/OperationalState_RVC.xml index 9b83bc4dfde257..fb9fea9d5d4e27 100644 --- a/data_model/1.4/clusters/OperationalState_RVC.xml +++ b/data_model/1.4/clusters/OperationalState_RVC.xml @@ -117,10 +117,7 @@ Davis, CA 95616, USA - - - - + \ No newline at end of file diff --git a/data_model/1.4/clusters/PumpConfigurationControl.xml b/data_model/1.4/clusters/PumpConfigurationControl.xml index 9b7e4ab56dc5c2..2be5a4437184c7 100644 --- a/data_model/1.4/clusters/PumpConfigurationControl.xml +++ b/data_model/1.4/clusters/PumpConfigurationControl.xml @@ -373,11 +373,8 @@ Davis, CA 95616, USA - - - + - diff --git a/data_model/1.4/clusters/Scenes.xml b/data_model/1.4/clusters/Scenes.xml index 1479d3ffd7de86..3de80abbc56ef8 100644 --- a/data_model/1.4/clusters/Scenes.xml +++ b/data_model/1.4/clusters/Scenes.xml @@ -373,14 +373,16 @@ Davis, CA 95616, USA - + + - + + diff --git a/data_model/1.4/clusters/ThermostatUserInterfaceConfiguration.xml b/data_model/1.4/clusters/ThermostatUserInterfaceConfiguration.xml index d6a52248282321..8b33ccedbd2200 100644 --- a/data_model/1.4/clusters/ThermostatUserInterfaceConfiguration.xml +++ b/data_model/1.4/clusters/ThermostatUserInterfaceConfiguration.xml @@ -106,17 +106,14 @@ Davis, CA 95616, USA - - - \ No newline at end of file diff --git a/data_model/1.4/clusters/WaterHeaterManagement.xml b/data_model/1.4/clusters/WaterHeaterManagement.xml index 96dcc2b112461b..49cdf1eeb25b57 100644 --- a/data_model/1.4/clusters/WaterHeaterManagement.xml +++ b/data_model/1.4/clusters/WaterHeaterManagement.xml @@ -168,7 +168,6 @@ Davis, CA 95616, USA - @@ -182,7 +181,6 @@ Davis, CA 95616, USA - diff --git a/data_model/1.4/device_types/DeviceEnergyManagement.xml b/data_model/1.4/device_types/DeviceEnergyManagement.xml index 86efccc02f6b2d..0a90a21edb868c 100644 --- a/data_model/1.4/device_types/DeviceEnergyManagement.xml +++ b/data_model/1.4/device_types/DeviceEnergyManagement.xml @@ -63,10 +63,7 @@ Davis, CA 95616, USA - - - - + @@ -77,7 +74,6 @@ Davis, CA 95616, USA - diff --git a/data_model/1.4/device_types/HeatPump.xml b/data_model/1.4/device_types/HeatPump.xml index 61f556c6ed2a9b..012060e034b84c 100644 --- a/data_model/1.4/device_types/HeatPump.xml +++ b/data_model/1.4/device_types/HeatPump.xml @@ -65,7 +65,7 @@ Davis, CA 95616, USA - + diff --git a/data_model/1.4/device_types/RootNodeDeviceType.xml b/data_model/1.4/device_types/RootNodeDeviceType.xml index 13473e44cacb60..99ce8fc319af47 100644 --- a/data_model/1.4/device_types/RootNodeDeviceType.xml +++ b/data_model/1.4/device_types/RootNodeDeviceType.xml @@ -160,16 +160,16 @@ Davis, CA 95616, USA - + + + + - - - - - - + + + diff --git a/data_model/1.4/spec_sha b/data_model/1.4/spec_sha index 094141d3c099c6..b48b447d733e71 100644 --- a/data_model/1.4/spec_sha +++ b/data_model/1.4/spec_sha @@ -1 +1 @@ -2760ea4338a4b612ac025bfa5677e6918041c1d4 +3d8fc9ae05045a53fdaffd7e3593f92a48b10e30 From ccaa43edd0e22e0f34094c99d811d0feaa9e157a Mon Sep 17 00:00:00 2001 From: Yufeng Wang Date: Mon, 21 Oct 2024 05:58:01 -0700 Subject: [PATCH 050/149] [Fabric-Bridge] Cleanup unused flag (#36156) --- examples/fabric-bridge-app/fabric-bridge-common/BUILD.gn | 1 - .../fabric-bridge-common/include/CHIPProjectAppConfig.h | 6 +++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/examples/fabric-bridge-app/fabric-bridge-common/BUILD.gn b/examples/fabric-bridge-app/fabric-bridge-common/BUILD.gn index 3db4f1ebb13425..18615a0d195a50 100644 --- a/examples/fabric-bridge-app/fabric-bridge-common/BUILD.gn +++ b/examples/fabric-bridge-app/fabric-bridge-common/BUILD.gn @@ -22,7 +22,6 @@ config("config") { chip_data_model("fabric-bridge-common-zap") { zap_file = "fabric-bridge-app.zap" is_server = true - cflags = [ "-DDYNAMIC_ENDPOINT_COUNT=16" ] } # This includes all the clusters that only exist on the dynamic endpoint. diff --git a/examples/fabric-bridge-app/fabric-bridge-common/include/CHIPProjectAppConfig.h b/examples/fabric-bridge-app/fabric-bridge-common/include/CHIPProjectAppConfig.h index 534079821043a8..f61f9f469fa2b4 100644 --- a/examples/fabric-bridge-app/fabric-bridge-common/include/CHIPProjectAppConfig.h +++ b/examples/fabric-bridge-app/fabric-bridge-common/include/CHIPProjectAppConfig.h @@ -30,8 +30,8 @@ // overrides CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT in CHIPProjectConfig #define CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT 16 -// include the CHIPProjectConfig from config/standalone -#include - // Allows app options (ports) to be configured on launch of app #define CHIP_DEVICE_ENABLE_PORT_PARAMS 1 + +// Include the CHIPProjectConfig from platform implementation config +#include From d0e9166f93f2dccb038e87aa39c6b865b9225cf0 Mon Sep 17 00:00:00 2001 From: Yufeng Wang Date: Mon, 21 Oct 2024 05:58:56 -0700 Subject: [PATCH 051/149] [Fabric-Sync] Add build target for Raspberry Pi (#36158) --- examples/fabric-sync/README.md | 36 +++++++++++++++++-- scripts/build/build/targets.py | 1 + scripts/build/builders/host.py | 6 ++++ .../build/testdata/all_targets_linux_x64.txt | 2 +- 4 files changed, 42 insertions(+), 3 deletions(-) diff --git a/examples/fabric-sync/README.md b/examples/fabric-sync/README.md index dd24d3794457c2..6cbe9da9e9428d 100644 --- a/examples/fabric-sync/README.md +++ b/examples/fabric-sync/README.md @@ -83,12 +83,44 @@ defined: ### For Linux host example: ``` - ./scripts/examples/gn_build_example.sh examples/fabric-sync out/debug/standalone + source scripts/activate.sh + ./scripts/build/build_examples.py --target linux-x64-fabric-sync-no-ble build ``` ### For Raspberry Pi 4 example: - TODO + Pull Docker Images + + ``` + docker pull connectedhomeip/chip-build-vscode:latest + ``` + + Run docker + + ``` + docker run -it -v ~/connectedhomeip:/var/connectedhomeip connectedhomeip/chip-build-vscode:latest /bin/bash + ``` + + Build + + ``` + cd /var/connectedhomeip + + git config --global --add safe.directory /var/connectedhomeip + git config --global --add safe.directory /var/connectedhomeip/third_party/pigweed/repo + git config --global --add safe.directory /var/connectedhomeip/examples/common/QRCode/repo + + ./scripts/run_in_build_env.sh \ + "./scripts/build/build_examples.py \ + --target linux-arm64-fabric-sync-no-ble-clang \ + build" + ``` + + Transfer the fabric-bridge-app binary to a Raspberry Pi + + ``` + scp ./fabric-sync ubuntu@xxx.xxx.xxx.xxx:/home/ubuntu + ``` ## Running the Complete Example on Ubuntu diff --git a/scripts/build/build/targets.py b/scripts/build/build/targets.py index fb68a3276c705a..9ddb7801530ae1 100755 --- a/scripts/build/build/targets.py +++ b/scripts/build/build/targets.py @@ -133,6 +133,7 @@ def BuildHostTarget(): TargetPart('bridge', app=HostApp.BRIDGE), TargetPart('fabric-admin', app=HostApp.FABRIC_ADMIN).OnlyIfRe("-rpc"), TargetPart('fabric-bridge', app=HostApp.FABRIC_BRIDGE).OnlyIfRe("-rpc"), + TargetPart('fabric-sync', app=HostApp.FABRIC_SYNC), TargetPart('tests', app=HostApp.TESTS), TargetPart('chip-cert', app=HostApp.CERT_TOOL), TargetPart('address-resolve-tool', app=HostApp.ADDRESS_RESOLVE), diff --git a/scripts/build/builders/host.py b/scripts/build/builders/host.py index 8d209d6d29bf3f..3b81f5d94423fa 100644 --- a/scripts/build/builders/host.py +++ b/scripts/build/builders/host.py @@ -72,6 +72,7 @@ class HostApp(Enum): BRIDGE = auto() FABRIC_ADMIN = auto() FABRIC_BRIDGE = auto() + FABRIC_SYNC = auto() JAVA_MATTER_CONTROLLER = auto() KOTLIN_MATTER_CONTROLLER = auto() CONTACT_SENSOR = auto() @@ -131,6 +132,8 @@ def ExamplePath(self): return 'fabric-admin' elif self == HostApp.FABRIC_BRIDGE: return 'fabric-bridge-app/linux' + elif self == HostApp.FABRIC_SYNC: + return 'fabric-sync' elif self == HostApp.JAVA_MATTER_CONTROLLER: return 'java-matter-controller' elif self == HostApp.KOTLIN_MATTER_CONTROLLER: @@ -236,6 +239,9 @@ def OutputNames(self): elif self == HostApp.FABRIC_BRIDGE: yield 'fabric-bridge-app' yield 'fabric-bridge-app.map' + elif self == HostApp.FABRIC_SYNC: + yield 'fabric-sync' + yield 'fabric-sync.map' elif self == HostApp.JAVA_MATTER_CONTROLLER: yield 'java-matter-controller' yield 'java-matter-controller.map' diff --git a/scripts/build/testdata/all_targets_linux_x64.txt b/scripts/build/testdata/all_targets_linux_x64.txt index 65755878191856..59466f91e6ec42 100644 --- a/scripts/build/testdata/all_targets_linux_x64.txt +++ b/scripts/build/testdata/all_targets_linux_x64.txt @@ -9,7 +9,7 @@ efr32-{brd2704b,brd4316a,brd4317a,brd4318a,brd4319a,brd4186a,brd4187a,brd2601b,b esp32-{m5stack,c3devkit,devkitc,qemu}-{all-clusters,all-clusters-minimal,energy-management,ota-provider,ota-requestor,shell,light,lock,bridge,temperature-measurement,ota-requestor,tests}[-rpc][-ipv6only][-tracing][-data-model-disabled][-data-model-enabled] genio-lighting-app linux-fake-tests[-mbedtls][-boringssl][-asan][-tsan][-ubsan][-libfuzzer][-ossfuzz][-pw-fuzztest][-coverage][-dmalloc][-clang] -linux-{x64,arm64}-{rpc-console,all-clusters,all-clusters-minimal,chip-tool,thermostat,java-matter-controller,kotlin-matter-controller,minmdns,light,light-data-model-no-unique-id,lock,shell,ota-provider,ota-requestor,simulated-app1,simulated-app2,python-bindings,tv-app,tv-casting-app,bridge,fabric-admin,fabric-bridge,tests,chip-cert,address-resolve-tool,contact-sensor,dishwasher,microwave-oven,refrigerator,rvc,air-purifier,lit-icd,air-quality-sensor,network-manager,energy-management,water-leak-detector}[-nodeps][-nlfaultinject][-platform-mdns][-minmdns-verbose][-libnl][-same-event-loop][-no-interactive][-ipv6only][-no-ble][-no-wifi][-no-thread][-no-shell][-mbedtls][-boringssl][-asan][-tsan][-ubsan][-libfuzzer][-ossfuzz][-pw-fuzztest][-coverage][-dmalloc][-clang][-test][-rpc][-with-ui][-evse-test-event][-enable-dnssd-tests][-disable-dnssd-tests][-chip-casting-simplified][-data-model-check][-data-model-disabled][-data-model-enabled][-check-failure-die] +linux-{x64,arm64}-{rpc-console,all-clusters,all-clusters-minimal,chip-tool,thermostat,java-matter-controller,kotlin-matter-controller,minmdns,light,light-data-model-no-unique-id,lock,shell,ota-provider,ota-requestor,simulated-app1,simulated-app2,python-bindings,tv-app,tv-casting-app,bridge,fabric-admin,fabric-bridge,fabric-sync,tests,chip-cert,address-resolve-tool,contact-sensor,dishwasher,microwave-oven,refrigerator,rvc,air-purifier,lit-icd,air-quality-sensor,network-manager,energy-management,water-leak-detector}[-nodeps][-nlfaultinject][-platform-mdns][-minmdns-verbose][-libnl][-same-event-loop][-no-interactive][-ipv6only][-no-ble][-no-wifi][-no-thread][-no-shell][-mbedtls][-boringssl][-asan][-tsan][-ubsan][-libfuzzer][-ossfuzz][-pw-fuzztest][-coverage][-dmalloc][-clang][-test][-rpc][-with-ui][-evse-test-event][-enable-dnssd-tests][-disable-dnssd-tests][-chip-casting-simplified][-data-model-check][-data-model-disabled][-data-model-enabled][-check-failure-die] linux-x64-efr32-test-runner[-clang] imx-{chip-tool,lighting-app,thermostat,all-clusters-app,all-clusters-minimal-app,ota-provider-app}[-release] infineon-psoc6-{lock,light,all-clusters,all-clusters-minimal}[-ota][-updateimage][-trustm] From 562acf2077f6130bae23bae45ae6701eb9bca363 Mon Sep 17 00:00:00 2001 From: Alex Tsitsiura Date: Mon, 21 Oct 2024 16:01:50 +0300 Subject: [PATCH 052/149] riscv:telink: fix alexa auto connect. (#36143) - enlarge the rx stack size to avoid crash. Signed-off-by: Haiwen Xia Co-authored-by: Haiwen Xia --- config/telink/chip-module/Kconfig.defaults | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/telink/chip-module/Kconfig.defaults b/config/telink/chip-module/Kconfig.defaults index ed8172b1824584..835b14c1811be0 100644 --- a/config/telink/chip-module/Kconfig.defaults +++ b/config/telink/chip-module/Kconfig.defaults @@ -137,7 +137,7 @@ config BT_BUF_ACL_TX_SIZE default 251 config BT_RX_STACK_SIZE - default 810 if BT_B9X + default 1352 if BT_B9X default 2048 if BT_W91 config BT_HCI_TX_STACK_SIZE From 8c31c3f92f5be28d224eba7d3dc428cb16394dfa Mon Sep 17 00:00:00 2001 From: Arkadiusz Bokowy Date: Mon, 21 Oct 2024 15:03:49 +0200 Subject: [PATCH 053/149] Label platform changes in examples and test drivers (#36140) --- .github/labeler.yml | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/.github/labeler.yml b/.github/labeler.yml index 7e02fe6d368df3..68d976ecd5b0df 100644 --- a/.github/labeler.yml +++ b/.github/labeler.yml @@ -275,14 +275,22 @@ darwin: silabs: - changed-files: - any-glob-to-any-file: + - examples/platform/silabs/* + - examples/platform/silabs/**/* - src/platform/silabs/* - src/platform/silabs/**/* + - src/test_driver/efr32/* + - src/test_driver/efr32/**/* esp32: - changed-files: - any-glob-to-any-file: + - examples/platform/esp32/* + - examples/platform/esp32/**/* - src/platform/ESP32/* - src/platform/ESP32/**/* + - src/test_driver/esp32/* + - src/test_driver/esp32/**/* freeRTOS: - changed-files: @@ -290,23 +298,31 @@ freeRTOS: - src/platform/FreeRTOS/* - src/platform/FreeRTOS/**/* -k32w: +nxp: - changed-files: - any-glob-to-any-file: - - src/platform/K32W/* - - src/platform/K32W/**/* + - examples/platform/nxp/* + - examples/platform/nxp/**/* + - src/platform/nxp/* + - src/platform/nxp/**/* linux: - changed-files: - any-glob-to-any-file: + - examples/platform/linux/* + - examples/platform/linux/**/* - src/platform/Linux/* - src/platform/Linux/**/* nrf connect: - changed-files: - any-glob-to-any-file: + - examples/platform/nrfconnect/* + - examples/platform/nrfconnect/**/* - src/platform/nrfconnect/* - src/platform/nrfconnect/**/* + - src/test_driver/nrfconnect/* + - src/test_driver/nrfconnect/**/* openthread: - changed-files: @@ -323,11 +339,17 @@ zephyr: telink: - changed-files: - any-glob-to-any-file: + - examples/platform/telink/* + - examples/platform/telink/**/* - src/platform/telink/* - src/platform/telink/**/* tizen: - changed-files: - any-glob-to-any-file: + - examples/platform/tizen/* + - examples/platform/tizen/**/* - src/platform/Tizen/* - src/platform/Tizen/**/* + - src/test_driver/tizen/* + - src/test_driver/tizen/**/* From db7c54a53c094988840de612692c5af0552c8993 Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Mon, 21 Oct 2024 10:29:46 -0400 Subject: [PATCH 054/149] Minor update: avoid extra constructor on IsExistentAttributePath (#36130) --- src/app/InteractionModelEngine.cpp | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/app/InteractionModelEngine.cpp b/src/app/InteractionModelEngine.cpp index 269cc7f9158ee3..d88299c29da412 100644 --- a/src/app/InteractionModelEngine.cpp +++ b/src/app/InteractionModelEngine.cpp @@ -1507,20 +1507,14 @@ bool InteractionModelEngine::IsExistentAttributePath(const ConcreteAttributePath { #if CHIP_CONFIG_USE_DATA_MODEL_INTERFACE #if CHIP_CONFIG_USE_EMBER_DATA_MODEL - - bool providerResult = GetDataModelProvider() - ->GetAttributeInfo(ConcreteAttributePath(path.mEndpointId, path.mClusterId, path.mAttributeId)) - .has_value(); + bool providerResult = GetDataModelProvider()->GetAttributeInfo(path).has_value(); bool emberResult = emberAfContainsAttribute(path.mEndpointId, path.mClusterId, path.mAttributeId); // Ensure that Provider interface and ember are IDENTICAL in attribute location (i.e. "check" mode) VerifyOrDie(providerResult == emberResult); #endif - - return GetDataModelProvider() - ->GetAttributeInfo(ConcreteAttributePath(path.mEndpointId, path.mClusterId, path.mAttributeId)) - .has_value(); + return GetDataModelProvider()->GetAttributeInfo(path).has_value(); #else return emberAfContainsAttribute(path.mEndpointId, path.mClusterId, path.mAttributeId); #endif From 605e3f5250852a4068350a6b479501665ab0a906 Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Mon, 21 Oct 2024 12:11:11 -0400 Subject: [PATCH 055/149] Remove the linux auto-label. (#36177) It tends to mark a lot of issues as 'linux' even though they are not. --- .github/issue-labeler.yml | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/.github/issue-labeler.yml b/.github/issue-labeler.yml index 909ef045c039e4..f47ce859328801 100644 --- a/.github/issue-labeler.yml +++ b/.github/issue-labeler.yml @@ -12,8 +12,18 @@ darwin: # (?![a-z]) means "there is no next char in the range a-z". - "/(\\b[Ii][Oo][Ss](?![a-zA-Z])|[Hh][Oo][Mm][Ee][Pp][Oo][Dd]|[Dd][Aa][Rr][Ww][Ii][Nn]|\\bm[Aa][Cc]\\b|\\bMa[Cc]\\b|\\bM[Aa]c\\b|[Mm][Aa][Cc][Oo][Ss])/" -linux: - - "/(linux)/i" + +# NOTE: +# Linux intentionally disabled: most people compile either on linux or darwin and +# as a result a lot of issues get tagged as such even though they are not platform specific +# (e.g. we get test case failures reported as linux even though they are just normal +# test runs) +# +# Linux label should be reserved to platform-specific problems (usually bootstrap/packages +# or integration with wifi/ethernet/bluetootn/etc.) +# +# linux: +# - "/(linux)/i" # Special Keywords for Cert Blockers air purifiers: From 6f0a70c6c0c4ec0fc14bcbab1493dd1b8de40f27 Mon Sep 17 00:00:00 2001 From: andrei-menzopol <96489227+andrei-menzopol@users.noreply.github.com> Date: Mon, 21 Oct 2024 19:59:46 +0300 Subject: [PATCH 056/149] [nxp][examples][common][lock-app] Add DiagnosticLog and Update zap file (#36120) * [nxp][examples][common] Update zap files to support Aliro Signed-off-by: Andrei Menzopol * [nxp][examples][common][lock-app] Add DiagnosticLog and Update zap file * Add DiagnosticLogs in lock-app ZclCallbacks.cpp * Update zap file: enable door-lock attributes Signed-off-by: Andrei Menzopol Signed-off-by: Ethan Tan --------- Signed-off-by: Andrei Menzopol Signed-off-by: Ethan Tan --- .../lock-app/nxp/common/main/ZclCallbacks.cpp | 17 + examples/lock-app/nxp/zap/lock-app.matter | 64 +- examples/lock-app/nxp/zap/lock-app.zap | 834 +++++++++++++++++- 3 files changed, 863 insertions(+), 52 deletions(-) diff --git a/examples/lock-app/nxp/common/main/ZclCallbacks.cpp b/examples/lock-app/nxp/common/main/ZclCallbacks.cpp index 98fb0f8c2bc20f..8806a2c058d6a2 100644 --- a/examples/lock-app/nxp/common/main/ZclCallbacks.cpp +++ b/examples/lock-app/nxp/common/main/ZclCallbacks.cpp @@ -35,11 +35,20 @@ #include "UserInterfaceFeedback.h" #endif +#if CONFIG_DIAG_LOGS_DEMO +#include +#include +#endif + using namespace ::chip; using namespace chip::app::Clusters; using namespace chip::app::Clusters::DoorLock; using chip::app::DataModel::Nullable; +#if CONFIG_DIAG_LOGS_DEMO +using namespace ::chip::app::Clusters::DiagnosticLogs; +#endif + void MatterPostAttributeChangeCallback(const chip::app::ConcreteAttributePath & path, uint8_t type, uint16_t size, uint8_t * value) { chip::DeviceManager::CHIPDeviceManagerCallbacks * cb = @@ -158,3 +167,11 @@ void emberAfPluginDoorLockOnAutoRelock(chip::EndpointId endpointId) DoorLockServer::Instance().SetLockState(1, DlLockState::kLocked, OperationSourceEnum::kAuto, NullNullable, NullNullable, NullNullable, NullNullable); } + +#if CONFIG_DIAG_LOGS_DEMO +void emberAfDiagnosticLogsClusterInitCallback(chip::EndpointId endpoint) +{ + auto & logProvider = LogProvider::GetInstance(); + DiagnosticLogsServer::Instance().SetDiagnosticLogsProviderDelegate(endpoint, &logProvider); +} +#endif diff --git a/examples/lock-app/nxp/zap/lock-app.matter b/examples/lock-app/nxp/zap/lock-app.matter index fc3a8917b2a3a0..8cf448449a5d76 100644 --- a/examples/lock-app/nxp/zap/lock-app.matter +++ b/examples/lock-app/nxp/zap/lock-app.matter @@ -2384,6 +2384,10 @@ endpoint 0 { callback attribute serverList; callback attribute clientList; callback attribute partsList; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; } @@ -2400,7 +2404,7 @@ endpoint 0 { callback attribute acceptedCommandList; callback attribute eventList; callback attribute attributeList; - ram attribute featureMap default = 0; + ram attribute featureMap default = 1; callback attribute clusterRevision; } @@ -2439,6 +2443,10 @@ endpoint 0 { ram attribute updatePossible default = 1; ram attribute updateState default = 0; ram attribute updateStateProgress default = 0; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -2622,6 +2630,10 @@ endpoint 0 { callback attribute windowStatus; callback attribute adminFabricIndex; callback attribute adminVendorId; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -2636,6 +2648,10 @@ endpoint 0 { callback attribute commissionedFabrics; callback attribute trustedRootCertificates; callback attribute currentFabricIndex; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -2658,6 +2674,10 @@ endpoint 0 { callback attribute groupTable; callback attribute maxGroupsPerFabric; callback attribute maxGroupKeysPerFabric; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute eventList; + callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -2725,13 +2745,18 @@ endpoint 1 { ram attribute numberOfTotalUsersSupported default = 10; ram attribute numberOfPINUsersSupported default = 10; ram attribute numberOfRFIDUsersSupported default = 10; + ram attribute numberOfWeekDaySchedulesSupportedPerUser default = 10; + ram attribute numberOfYearDaySchedulesSupportedPerUser default = 10; + ram attribute numberOfHolidaySchedulesSupported default = 10; ram attribute maxPINCodeLength default = 8; ram attribute minPINCodeLength default = 6; ram attribute maxRFIDCodeLength default = 20; ram attribute minRFIDCodeLength default = 10; ram attribute credentialRulesSupport default = 1; ram attribute numberOfCredentialsSupportedPerUser default = 5; - ram attribute autoRelockTime; + ram attribute language default = "en"; + ram attribute autoRelockTime default = 60; + ram attribute soundVolume default = 0; ram attribute operatingMode default = 0x00; ram attribute supportedOperatingModes default = 0xFFF6; ram attribute enableOneTouchLocking default = 0x00; @@ -2739,16 +2764,49 @@ endpoint 1 { ram attribute wrongCodeEntryLimit default = 3; ram attribute userCodeTemporaryDisableTime default = 10; ram attribute requirePINforRemoteOperation default = 0; + callback attribute aliroReaderVerificationKey; + callback attribute aliroReaderGroupIdentifier; + callback attribute aliroReaderGroupSubIdentifier; + callback attribute aliroExpeditedTransactionSupportedProtocolVersions; + callback attribute aliroGroupResolvingKey; + callback attribute aliroSupportedBLEUWBProtocolVersions; + callback attribute aliroBLEAdvertisingVersion; + callback attribute numberOfAliroCredentialIssuerKeysSupported; + callback attribute numberOfAliroEndpointKeysSupported; callback attribute generatedCommandList; callback attribute acceptedCommandList; callback attribute eventList; callback attribute attributeList; - ram attribute featureMap default = 0x0001; + ram attribute featureMap default = 0x7DB3; ram attribute clusterRevision default = 7; handle command LockDoor; handle command UnlockDoor; handle command UnlockWithTimeout; + handle command SetWeekDaySchedule; + handle command GetWeekDaySchedule; + handle command GetWeekDayScheduleResponse; + handle command ClearWeekDaySchedule; + handle command SetYearDaySchedule; + handle command GetYearDaySchedule; + handle command GetYearDayScheduleResponse; + handle command ClearYearDaySchedule; + handle command SetHolidaySchedule; + handle command GetHolidaySchedule; + handle command GetHolidayScheduleResponse; + handle command ClearHolidaySchedule; + handle command SetUser; + handle command GetUser; + handle command GetUserResponse; + handle command ClearUser; + handle command SetCredential; + handle command SetCredentialResponse; + handle command GetCredentialStatus; + handle command GetCredentialStatusResponse; + handle command ClearCredential; + handle command UnboltDoor; + handle command SetAliroReaderConfig; + handle command ClearAliroReaderConfig; } } diff --git a/examples/lock-app/nxp/zap/lock-app.zap b/examples/lock-app/nxp/zap/lock-app.zap index 67da76956d2e1d..e888db45055184 100644 --- a/examples/lock-app/nxp/zap/lock-app.zap +++ b/examples/lock-app/nxp/zap/lock-app.zap @@ -96,7 +96,7 @@ "singleton": 0, "bounded": 0, "defaultValue": null, - "reportable": 1, + "reportable": 0, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 @@ -112,7 +112,7 @@ "singleton": 0, "bounded": 0, "defaultValue": null, - "reportable": 1, + "reportable": 0, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 @@ -128,6 +128,70 @@ "singleton": 0, "bounded": 0, "defaultValue": null, + "reportable": 0, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -186,7 +250,7 @@ "singleton": 0, "bounded": 0, "defaultValue": null, - "reportable": 1, + "reportable": 0, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 @@ -202,7 +266,7 @@ "singleton": 0, "bounded": 0, "defaultValue": null, - "reportable": 1, + "reportable": 0, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 @@ -329,7 +393,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "0", + "defaultValue": "1", "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -388,7 +452,7 @@ "singleton": 1, "bounded": 0, "defaultValue": null, - "reportable": 1, + "reportable": 0, "minInterval": 0, "maxInterval": 65344, "reportableChange": 0 @@ -404,7 +468,7 @@ "singleton": 1, "bounded": 0, "defaultValue": null, - "reportable": 1, + "reportable": 0, "minInterval": 0, "maxInterval": 65344, "reportableChange": 0 @@ -420,7 +484,7 @@ "singleton": 1, "bounded": 0, "defaultValue": null, - "reportable": 1, + "reportable": 0, "minInterval": 0, "maxInterval": 65344, "reportableChange": 0 @@ -436,7 +500,7 @@ "singleton": 1, "bounded": 0, "defaultValue": null, - "reportable": 1, + "reportable": 0, "minInterval": 0, "maxInterval": 65344, "reportableChange": 0 @@ -452,7 +516,7 @@ "singleton": 1, "bounded": 0, "defaultValue": null, - "reportable": 1, + "reportable": 0, "minInterval": 0, "maxInterval": 65344, "reportableChange": 0 @@ -468,7 +532,7 @@ "singleton": 1, "bounded": 0, "defaultValue": "", - "reportable": 1, + "reportable": 0, "minInterval": 0, "maxInterval": 65344, "reportableChange": 0 @@ -484,7 +548,7 @@ "singleton": 1, "bounded": 0, "defaultValue": null, - "reportable": 1, + "reportable": 0, "minInterval": 0, "maxInterval": 65344, "reportableChange": 0 @@ -500,7 +564,7 @@ "singleton": 1, "bounded": 0, "defaultValue": null, - "reportable": 1, + "reportable": 0, "minInterval": 0, "maxInterval": 65344, "reportableChange": 0 @@ -516,7 +580,7 @@ "singleton": 1, "bounded": 0, "defaultValue": null, - "reportable": 1, + "reportable": 0, "minInterval": 0, "maxInterval": 65344, "reportableChange": 0 @@ -532,7 +596,7 @@ "singleton": 1, "bounded": 0, "defaultValue": null, - "reportable": 1, + "reportable": 0, "minInterval": 0, "maxInterval": 65344, "reportableChange": 0 @@ -548,7 +612,7 @@ "singleton": 1, "bounded": 0, "defaultValue": null, - "reportable": 1, + "reportable": 0, "minInterval": 0, "maxInterval": 65344, "reportableChange": 0 @@ -870,6 +934,70 @@ "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "FeatureMap", "code": 65532, @@ -946,7 +1074,7 @@ "singleton": 0, "bounded": 0, "defaultValue": "", - "reportable": 1, + "reportable": 0, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 @@ -962,7 +1090,7 @@ "singleton": 0, "bounded": 0, "defaultValue": null, - "reportable": 1, + "reportable": 0, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 @@ -1834,7 +1962,7 @@ "singleton": 0, "bounded": 0, "defaultValue": null, - "reportable": 1, + "reportable": 0, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 @@ -2056,8 +2184,8 @@ "bounded": 0, "defaultValue": null, "reportable": 1, - "minInterval": 0, - "maxInterval": 65344, + "minInterval": 1, + "maxInterval": 65534, "reportableChange": 0 }, { @@ -3244,6 +3372,70 @@ "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "FeatureMap", "code": 65532, @@ -3481,52 +3673,116 @@ "reportableChange": 0 }, { - "name": "FeatureMap", - "code": 65532, + "name": "GeneratedCommandList", + "code": 65528, "mfgCode": null, "side": "server", - "type": "bitmap32", + "type": "array", "included": 1, - "storageOption": "RAM", + "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "0", + "defaultValue": null, "reportable": 1, "minInterval": 1, "maxInterval": 65534, "reportableChange": 0 }, { - "name": "ClusterRevision", - "code": 65533, + "name": "AcceptedCommandList", + "code": 65529, "mfgCode": null, "side": "server", - "type": "int16u", + "type": "array", "included": 1, - "storageOption": "RAM", + "storageOption": "External", "singleton": 0, "bounded": 0, - "defaultValue": "1", + "defaultValue": null, "reportable": 1, - "minInterval": 0, - "maxInterval": 65344, + "minInterval": 1, + "maxInterval": 65534, "reportableChange": 0 - } - ] - }, - { - "name": "Group Key Management", - "code": 63, - "mfgCode": null, - "define": "GROUP_KEY_MANAGEMENT_CLUSTER", - "side": "server", - "enabled": 1, - "commands": [ + }, { - "name": "KeySetWrite", - "code": 0, + "name": "EventList", + "code": 65530, "mfgCode": null, - "source": "client", + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Group Key Management", + "code": 63, + "mfgCode": null, + "define": "GROUP_KEY_MANAGEMENT_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "KeySetWrite", + "code": 0, + "mfgCode": null, + "source": "client", "isIncoming": 1, "isEnabled": 1 }, @@ -3636,6 +3892,70 @@ "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "EventList", + "code": 65530, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "FeatureMap", "code": 65532, @@ -4210,6 +4530,198 @@ "source": "client", "isIncoming": 1, "isEnabled": 1 + }, + { + "name": "SetWeekDaySchedule", + "code": 11, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "GetWeekDaySchedule", + "code": 12, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "GetWeekDayScheduleResponse", + "code": 12, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "ClearWeekDaySchedule", + "code": 13, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "SetYearDaySchedule", + "code": 14, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "GetYearDaySchedule", + "code": 15, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "GetYearDayScheduleResponse", + "code": 15, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "ClearYearDaySchedule", + "code": 16, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "SetHolidaySchedule", + "code": 17, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "GetHolidaySchedule", + "code": 18, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "GetHolidayScheduleResponse", + "code": 18, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "ClearHolidaySchedule", + "code": 19, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "SetUser", + "code": 26, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "GetUser", + "code": 27, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "GetUserResponse", + "code": 28, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "ClearUser", + "code": 29, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "SetCredential", + "code": 34, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "SetCredentialResponse", + "code": 35, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "GetCredentialStatus", + "code": 36, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "GetCredentialStatusResponse", + "code": 37, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "ClearCredential", + "code": 38, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "UnboltDoor", + "code": 39, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "SetAliroReaderConfig", + "code": 40, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "ClearAliroReaderConfig", + "code": 41, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 } ], "attributes": [ @@ -4325,6 +4837,54 @@ "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "NumberOfWeekDaySchedulesSupportedPerUser", + "code": 20, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "10", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "NumberOfYearDaySchedulesSupportedPerUser", + "code": 21, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "10", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "NumberOfHolidaySchedulesSupported", + "code": 22, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "10", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "MaxPINCodeLength", "code": 23, @@ -4421,6 +4981,22 @@ "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "Language", + "code": 33, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "en", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "AutoRelockTime", "code": 35, @@ -4431,7 +5007,23 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "", + "defaultValue": "60", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "SoundVolume", + "code": 36, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -4549,6 +5141,150 @@ "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "AliroReaderVerificationKey", + "code": 128, + "mfgCode": null, + "side": "server", + "type": "octet_string", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AliroReaderGroupIdentifier", + "code": 129, + "mfgCode": null, + "side": "server", + "type": "octet_string", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AliroReaderGroupSubIdentifier", + "code": 130, + "mfgCode": null, + "side": "server", + "type": "octet_string", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AliroExpeditedTransactionSupportedProtocolVersions", + "code": 131, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AliroGroupResolvingKey", + "code": 132, + "mfgCode": null, + "side": "server", + "type": "octet_string", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AliroSupportedBLEUWBProtocolVersions", + "code": 133, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AliroBLEAdvertisingVersion", + "code": 134, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "NumberOfAliroCredentialIssuerKeysSupported", + "code": 135, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "NumberOfAliroEndpointKeysSupported", + "code": 136, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "GeneratedCommandList", "code": 65528, @@ -4623,7 +5359,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "0x0001", + "defaultValue": "0x7DB3", "reportable": 1, "minInterval": 1, "maxInterval": 65534, From 9ee0499d591039e75ab20cad845d384e3d957688 Mon Sep 17 00:00:00 2001 From: jamesharrow <93921463+jamesharrow@users.noreply.github.com> Date: Mon, 21 Oct 2024 21:25:48 +0100 Subject: [PATCH 057/149] DEMM, EVSEM, WHM, EEVSE, DEM, EWATERHTR zap XML out of date with 1.4 specs (#36155) * Fixes #36059 * regen_all after change to mode cluster ZCL XML * Checking on EEVSE the cluster revision was wrong (looks like the rev 4 was backed out after it was felt to still be a draft). Taken in the DEM and WHM latest descriptions based on Alchemy autogen. * revert description in DEM which was truncated by Alchemy * regen_all * Removed src/app/tests/suites/certification/Test_TC_EEVSEM_3_1.yaml, Test_TC_EEVSEM_3_2.yaml, Test_TC_EEVSEM_3_3.yaml which were removed in test plan PR: https://github.com/CHIP-Specifications/chip-test-plans/pull/4553 * Reverted change to domain since ZAP does not show the clusters if the element text is empty --- .../all-clusters-app.matter | 30 +- .../data_model/dishwasher-thread-app.matter | 11 +- .../data_model/dishwasher-wifi-app.matter | 11 +- .../energy-management-app.matter | 30 +- .../certification/Test_TC_EEVSEM_3_1.yaml | 134 --- .../certification/Test_TC_EEVSEM_3_2.yaml | 172 ---- .../certification/Test_TC_EEVSEM_3_3.yaml | 189 ---- .../chip/device-energy-management-cluster.xml | 41 +- .../device-energy-management-mode-cluster.xml | 49 +- .../data-model/chip/energy-evse-cluster.xml | 48 +- .../chip/energy-evse-mode-cluster.xml | 42 +- .../chip/water-heater-management-cluster.xml | 12 +- .../chip/water-heater-mode-cluster.xml | 40 +- .../data_model/controller-clusters.matter | 30 +- .../chip/devicecontroller/ChipClusters.java | 240 ------ .../devicecontroller/ClusterIDMapping.java | 6 - .../devicecontroller/ClusterInfoMapping.java | 126 --- .../devicecontroller/ClusterReadMapping.java | 66 -- .../devicecontroller/ClusterWriteMapping.java | 132 --- .../DeviceEnergyManagementModeCluster.kt | 305 ------- .../cluster/clusters/EnergyEvseModeCluster.kt | 305 ------- .../clusters/WaterHeaterModeCluster.kt | 305 ------- .../CHIPAttributeTLVValueDecoder.cpp | 138 --- .../python/chip/clusters/CHIPClusters.py | 42 - .../python/chip/clusters/Objects.py | 109 +-- .../MTRAttributeSpecifiedCheck.mm | 18 - .../MTRAttributeTLVValueDecoder.mm | 90 -- .../CHIP/zap-generated/MTRBaseClusters.h | 58 +- .../CHIP/zap-generated/MTRBaseClusters.mm | 414 --------- .../CHIP/zap-generated/MTRClusterConstants.h | 6 - .../CHIP/zap-generated/MTRClusterNames.mm | 24 - .../CHIP/zap-generated/MTRClusters.h | 24 - .../CHIP/zap-generated/MTRClusters.mm | 96 --- .../zap-generated/attributes/Accessors.cpp | 574 +------------ .../zap-generated/attributes/Accessors.h | 66 -- .../app-common/zap-generated/cluster-enums.h | 1 + .../zap-generated/cluster-objects.cpp | 12 - .../zap-generated/cluster-objects.h | 78 -- .../app-common/zap-generated/ids/Attributes.h | 24 - .../zap-generated/cluster/Commands.h | 30 - .../cluster/logging/DataModelLogger.cpp | 30 - .../cluster/logging/EntryToText.cpp | 12 - .../zap-generated/cluster/Commands.h | 810 ------------------ 43 files changed, 179 insertions(+), 4801 deletions(-) delete mode 100644 src/app/tests/suites/certification/Test_TC_EEVSEM_3_1.yaml delete mode 100644 src/app/tests/suites/certification/Test_TC_EEVSEM_3_2.yaml delete mode 100644 src/app/tests/suites/certification/Test_TC_EEVSEM_3_3.yaml diff --git a/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter b/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter index aa3ef44b066cdd..4888bf464cf85d 100644 --- a/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter +++ b/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter @@ -4709,13 +4709,13 @@ provisional cluster DeviceEnergyManagement = 152 { command ModifyForecastRequest(ModifyForecastRequestRequest): DefaultSuccess = 5; /** Allows a client to ask the ESA to recompute its Forecast based on power and time constraints. */ command RequestConstraintBasedForecast(RequestConstraintBasedForecastRequest): DefaultSuccess = 6; - /** Allows a client to request cancellation of a previous adjustment request in a StartTimeAdjustRequest, ModifyForecastRequest or RequestConstraintBasedForecast command */ + /** Allows a client to request cancellation of a previous adjustment request in a StartTimeAdjustRequest, ModifyForecastRequest or RequestConstraintBasedForecast command. */ command CancelRequest(): DefaultSuccess = 7; } /** Electric Vehicle Supply Equipment (EVSE) is equipment used to charge an Electric Vehicle (EV) or Plug-In Hybrid Electric Vehicle. This cluster provides an interface to the functionality of Electric Vehicle Supply Equipment (EVSE) management. */ cluster EnergyEvse = 153 { - revision 4; + revision 3; enum EnergyTransferStoppedReasonEnum : enum8 { kEVStopped = 0; @@ -4880,9 +4880,9 @@ cluster EnergyEvse = 153 { /** Allows a client to disable the EVSE from charging and discharging. */ timed command Disable(): DefaultSuccess = 1; - /** This command allows a client to enable the EVSE to charge an EV, */ + /** This command allows a client to enable the EVSE to charge an EV, and to provide or update the maximum and minimum charge current. */ timed command EnableCharging(EnableChargingRequest): DefaultSuccess = 2; - /** Upon receipt, this SHALL allow a client to enable the discharge of an EV, */ + /** Upon receipt, this SHALL allow a client to enable the discharge of an EV, and to provide or update the maximum discharge current. */ timed command EnableDischarging(EnableDischargingRequest): DefaultSuccess = 3; /** Allows a client to put the EVSE into a self-diagnostics mode. */ timed command StartDiagnostics(): DefaultSuccess = 4; @@ -4951,7 +4951,7 @@ cluster PowerTopology = 156 { /** Attributes and commands for selecting a mode from a list of supported options. */ cluster EnergyEvseMode = 157 { - revision 1; + revision 2; enum ModeTag : enum16 { kAuto = 0; @@ -4967,6 +4967,7 @@ cluster EnergyEvseMode = 157 { kManual = 16384; kTimeOfUse = 16385; kSolarCharging = 16386; + kV2X = 16387; } bitmap Feature : bitmap32 { @@ -4986,8 +4987,6 @@ cluster EnergyEvseMode = 157 { readonly attribute ModeOptionStruct supportedModes[] = 0; readonly attribute int8u currentMode = 1; - attribute optional nullable int8u startUpMode = 2; - attribute optional nullable int8u onMode = 3; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -5004,8 +5003,7 @@ cluster EnergyEvseMode = 157 { optional char_string<64> statusText = 1; } - /** This command is used to change device modes. - On receipt of this command the device SHALL respond with a ChangeToModeResponse command. */ + /** This command is used to change device modes. */ command ChangeToMode(ChangeToModeRequest): ChangeToModeResponse = 0; } @@ -5046,8 +5044,6 @@ cluster WaterHeaterMode = 158 { readonly attribute ModeOptionStruct supportedModes[] = 0; readonly attribute int8u currentMode = 1; - attribute optional nullable int8u startUpMode = 2; - attribute optional nullable int8u onMode = 3; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -5061,17 +5057,16 @@ cluster WaterHeaterMode = 158 { response struct ChangeToModeResponse = 1 { enum8 status = 0; - optional char_string statusText = 1; + optional char_string<64> statusText = 1; } - /** This command is used to change device modes. - On receipt of this command the device SHALL respond with a ChangeToModeResponse command. */ + /** This command is used to change device modes. */ command ChangeToMode(ChangeToModeRequest): ChangeToModeResponse = 0; } /** Attributes and commands for selecting a mode from a list of supported options. */ provisional cluster DeviceEnergyManagementMode = 159 { - revision 1; + revision 2; enum ModeTag : enum16 { kAuto = 0; @@ -5107,8 +5102,6 @@ provisional cluster DeviceEnergyManagementMode = 159 { readonly attribute ModeOptionStruct supportedModes[] = 0; readonly attribute int8u currentMode = 1; - attribute optional nullable int8u startUpMode = 2; - attribute optional nullable int8u onMode = 3; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -5125,8 +5118,7 @@ provisional cluster DeviceEnergyManagementMode = 159 { optional char_string<64> statusText = 1; } - /** This command is used to change device modes. - On receipt of this command the device SHALL respond with a ChangeToModeResponse command. */ + /** This command is used to change device modes. */ command ChangeToMode(ChangeToModeRequest): ChangeToModeResponse = 0; } diff --git a/examples/dishwasher-app/silabs/data_model/dishwasher-thread-app.matter b/examples/dishwasher-app/silabs/data_model/dishwasher-thread-app.matter index 0d217ab47b4256..43ac95d4ba4b7c 100644 --- a/examples/dishwasher-app/silabs/data_model/dishwasher-thread-app.matter +++ b/examples/dishwasher-app/silabs/data_model/dishwasher-thread-app.matter @@ -2227,7 +2227,7 @@ provisional cluster DeviceEnergyManagement = 152 { command ModifyForecastRequest(ModifyForecastRequestRequest): DefaultSuccess = 5; /** Allows a client to ask the ESA to recompute its Forecast based on power and time constraints. */ command RequestConstraintBasedForecast(RequestConstraintBasedForecastRequest): DefaultSuccess = 6; - /** Allows a client to request cancellation of a previous adjustment request in a StartTimeAdjustRequest, ModifyForecastRequest or RequestConstraintBasedForecast command */ + /** Allows a client to request cancellation of a previous adjustment request in a StartTimeAdjustRequest, ModifyForecastRequest or RequestConstraintBasedForecast command. */ command CancelRequest(): DefaultSuccess = 7; } @@ -2254,7 +2254,7 @@ cluster PowerTopology = 156 { /** Attributes and commands for selecting a mode from a list of supported options. */ provisional cluster DeviceEnergyManagementMode = 159 { - revision 1; + revision 2; enum ModeTag : enum16 { kAuto = 0; @@ -2290,8 +2290,6 @@ provisional cluster DeviceEnergyManagementMode = 159 { readonly attribute ModeOptionStruct supportedModes[] = 0; readonly attribute int8u currentMode = 1; - attribute optional nullable int8u startUpMode = 2; - attribute optional nullable int8u onMode = 3; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -2308,8 +2306,7 @@ provisional cluster DeviceEnergyManagementMode = 159 { optional char_string<64> statusText = 1; } - /** This command is used to change device modes. - On receipt of this command the device SHALL respond with a ChangeToModeResponse command. */ + /** This command is used to change device modes. */ command ChangeToMode(ChangeToModeRequest): ChangeToModeResponse = 0; } @@ -2792,8 +2789,6 @@ endpoint 3 { server cluster DeviceEnergyManagementMode { callback attribute supportedModes; callback attribute currentMode; - ram attribute startUpMode; - ram attribute onMode; callback attribute generatedCommandList; callback attribute acceptedCommandList; callback attribute eventList; diff --git a/examples/dishwasher-app/silabs/data_model/dishwasher-wifi-app.matter b/examples/dishwasher-app/silabs/data_model/dishwasher-wifi-app.matter index 3c8601d09bee9b..4d1106449ad2fd 100644 --- a/examples/dishwasher-app/silabs/data_model/dishwasher-wifi-app.matter +++ b/examples/dishwasher-app/silabs/data_model/dishwasher-wifi-app.matter @@ -2138,7 +2138,7 @@ provisional cluster DeviceEnergyManagement = 152 { command ModifyForecastRequest(ModifyForecastRequestRequest): DefaultSuccess = 5; /** Allows a client to ask the ESA to recompute its Forecast based on power and time constraints. */ command RequestConstraintBasedForecast(RequestConstraintBasedForecastRequest): DefaultSuccess = 6; - /** Allows a client to request cancellation of a previous adjustment request in a StartTimeAdjustRequest, ModifyForecastRequest or RequestConstraintBasedForecast command */ + /** Allows a client to request cancellation of a previous adjustment request in a StartTimeAdjustRequest, ModifyForecastRequest or RequestConstraintBasedForecast command. */ command CancelRequest(): DefaultSuccess = 7; } @@ -2165,7 +2165,7 @@ cluster PowerTopology = 156 { /** Attributes and commands for selecting a mode from a list of supported options. */ provisional cluster DeviceEnergyManagementMode = 159 { - revision 1; + revision 2; enum ModeTag : enum16 { kAuto = 0; @@ -2201,8 +2201,6 @@ provisional cluster DeviceEnergyManagementMode = 159 { readonly attribute ModeOptionStruct supportedModes[] = 0; readonly attribute int8u currentMode = 1; - attribute optional nullable int8u startUpMode = 2; - attribute optional nullable int8u onMode = 3; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -2219,8 +2217,7 @@ provisional cluster DeviceEnergyManagementMode = 159 { optional char_string<64> statusText = 1; } - /** This command is used to change device modes. - On receipt of this command the device SHALL respond with a ChangeToModeResponse command. */ + /** This command is used to change device modes. */ command ChangeToMode(ChangeToModeRequest): ChangeToModeResponse = 0; } @@ -2652,8 +2649,6 @@ endpoint 3 { server cluster DeviceEnergyManagementMode { callback attribute supportedModes; callback attribute currentMode; - ram attribute startUpMode; - ram attribute onMode; callback attribute generatedCommandList; callback attribute acceptedCommandList; callback attribute eventList; diff --git a/examples/energy-management-app/energy-management-common/energy-management-app.matter b/examples/energy-management-app/energy-management-common/energy-management-app.matter index a8a10075efec17..5da8448194d2f8 100644 --- a/examples/energy-management-app/energy-management-common/energy-management-app.matter +++ b/examples/energy-management-app/energy-management-common/energy-management-app.matter @@ -2019,13 +2019,13 @@ provisional cluster DeviceEnergyManagement = 152 { command ModifyForecastRequest(ModifyForecastRequestRequest): DefaultSuccess = 5; /** Allows a client to ask the ESA to recompute its Forecast based on power and time constraints. */ command RequestConstraintBasedForecast(RequestConstraintBasedForecastRequest): DefaultSuccess = 6; - /** Allows a client to request cancellation of a previous adjustment request in a StartTimeAdjustRequest, ModifyForecastRequest or RequestConstraintBasedForecast command */ + /** Allows a client to request cancellation of a previous adjustment request in a StartTimeAdjustRequest, ModifyForecastRequest or RequestConstraintBasedForecast command. */ command CancelRequest(): DefaultSuccess = 7; } /** Electric Vehicle Supply Equipment (EVSE) is equipment used to charge an Electric Vehicle (EV) or Plug-In Hybrid Electric Vehicle. This cluster provides an interface to the functionality of Electric Vehicle Supply Equipment (EVSE) management. */ cluster EnergyEvse = 153 { - revision 4; + revision 3; enum EnergyTransferStoppedReasonEnum : enum8 { kEVStopped = 0; @@ -2190,9 +2190,9 @@ cluster EnergyEvse = 153 { /** Allows a client to disable the EVSE from charging and discharging. */ timed command Disable(): DefaultSuccess = 1; - /** This command allows a client to enable the EVSE to charge an EV, */ + /** This command allows a client to enable the EVSE to charge an EV, and to provide or update the maximum and minimum charge current. */ timed command EnableCharging(EnableChargingRequest): DefaultSuccess = 2; - /** Upon receipt, this SHALL allow a client to enable the discharge of an EV, */ + /** Upon receipt, this SHALL allow a client to enable the discharge of an EV, and to provide or update the maximum discharge current. */ timed command EnableDischarging(EnableDischargingRequest): DefaultSuccess = 3; /** Allows a client to put the EVSE into a self-diagnostics mode. */ timed command StartDiagnostics(): DefaultSuccess = 4; @@ -2227,7 +2227,7 @@ cluster PowerTopology = 156 { /** Attributes and commands for selecting a mode from a list of supported options. */ cluster EnergyEvseMode = 157 { - revision 1; + revision 2; enum ModeTag : enum16 { kAuto = 0; @@ -2243,6 +2243,7 @@ cluster EnergyEvseMode = 157 { kManual = 16384; kTimeOfUse = 16385; kSolarCharging = 16386; + kV2X = 16387; } bitmap Feature : bitmap32 { @@ -2262,8 +2263,6 @@ cluster EnergyEvseMode = 157 { readonly attribute ModeOptionStruct supportedModes[] = 0; readonly attribute int8u currentMode = 1; - attribute optional nullable int8u startUpMode = 2; - attribute optional nullable int8u onMode = 3; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -2280,8 +2279,7 @@ cluster EnergyEvseMode = 157 { optional char_string<64> statusText = 1; } - /** This command is used to change device modes. - On receipt of this command the device SHALL respond with a ChangeToModeResponse command. */ + /** This command is used to change device modes. */ command ChangeToMode(ChangeToModeRequest): ChangeToModeResponse = 0; } @@ -2322,8 +2320,6 @@ cluster WaterHeaterMode = 158 { readonly attribute ModeOptionStruct supportedModes[] = 0; readonly attribute int8u currentMode = 1; - attribute optional nullable int8u startUpMode = 2; - attribute optional nullable int8u onMode = 3; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -2337,17 +2333,16 @@ cluster WaterHeaterMode = 158 { response struct ChangeToModeResponse = 1 { enum8 status = 0; - optional char_string statusText = 1; + optional char_string<64> statusText = 1; } - /** This command is used to change device modes. - On receipt of this command the device SHALL respond with a ChangeToModeResponse command. */ + /** This command is used to change device modes. */ command ChangeToMode(ChangeToModeRequest): ChangeToModeResponse = 0; } /** Attributes and commands for selecting a mode from a list of supported options. */ provisional cluster DeviceEnergyManagementMode = 159 { - revision 1; + revision 2; enum ModeTag : enum16 { kAuto = 0; @@ -2383,8 +2378,6 @@ provisional cluster DeviceEnergyManagementMode = 159 { readonly attribute ModeOptionStruct supportedModes[] = 0; readonly attribute int8u currentMode = 1; - attribute optional nullable int8u startUpMode = 2; - attribute optional nullable int8u onMode = 3; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -2401,8 +2394,7 @@ provisional cluster DeviceEnergyManagementMode = 159 { optional char_string<64> statusText = 1; } - /** This command is used to change device modes. - On receipt of this command the device SHALL respond with a ChangeToModeResponse command. */ + /** This command is used to change device modes. */ command ChangeToMode(ChangeToModeRequest): ChangeToModeResponse = 0; } diff --git a/src/app/tests/suites/certification/Test_TC_EEVSEM_3_1.yaml b/src/app/tests/suites/certification/Test_TC_EEVSEM_3_1.yaml deleted file mode 100644 index 2d38a6c1465236..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_EEVSEM_3_1.yaml +++ /dev/null @@ -1,134 +0,0 @@ -# Copyright (c) 2024 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -name: 183.3.1. [TC-EEVSEM-3.1] On Mode functionality with DUT as Server - -PICS: - - EEVSEM.S.A0003 - - MOD.S.F00 - - OO.S.C00.Rsp - - OO.S.C01.Rsp - -config: - nodeId: 0x12344321 - cluster: "Energy EVSE Mode" - endpoint: 1 - - ConfigureOnMode: - type: int8u - defaultValue: 0 - new_mode_th: - type: int8u - defaultValue: 2 - -tests: - - label: - "Step 1: Commission DUT to TH (can be skipped if done in a preceding - test)." - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: - "Precondition: TH writes from the DUT the OnMode attribute.NOTE: To - execute this test case set onmode to any integer value because as - default it value has null." - PICS: EEVSEM.S.A0003 && MOD.S.F00 - command: "writeAttribute" - attribute: "OnMode" - arguments: - value: ConfigureOnMode - - - label: "Step 2: TH reads from the DUT the OnMode attribute." - PICS: EEVSEM.S.A0003 && MOD.S.F00 - command: "readAttribute" - attribute: "OnMode" - response: - saveAs: on_mode_dut - constraints: - type: int8u - minValue: 0 - maxValue: 254 - - - label: "Step 3: TH reads from the DUT the CurrentMode attribute." - PICS: EEVSEM.S.A0001 && MOD.S.F00 - command: "readAttribute" - attribute: "CurrentMode" - response: - saveAs: old_current_mode_dut - constraints: - type: int8u - minValue: 0 - maxValue: 254 - - - label: - "If on_mode_dut is equal to old_current_mode_dut proceed to step 4. - Else proceed to step 6." - cluster: "EqualityCommands" - command: "UnsignedNumberEquals" - arguments: - values: - - name: "Value1" - value: on_mode_dut - - name: "Value2" - value: old_current_mode_dut - response: - - values: - - name: "Equals" - saveAs: IsExpectedValue - - - label: "Step 4: TH reads from the DUT the SupportedModes attribute." - runIf: IsExpectedValue - PICS: EEVSEM.S.A0000 && MOD.S.F00 - command: "readAttribute" - attribute: "SupportedModes" - response: - constraints: - type: list - minLength: 2 - - - label: - "Step 5: TH sends a ChangeToMode command to the DUT with NewMode set - to new_mode_th" - runIf: IsExpectedValue - PICS: EEVSEM.S.C00.Rsp && MOD.S.F00 - command: "ChangeToMode" - arguments: - values: - - name: "NewMode" - value: new_mode_th - response: - values: - - name: "Status" - value: 0x00 - - - label: "Step 6:TH sends a Off command to the DUT" - PICS: OO.S.C00.Rsp - cluster: "On/Off" - command: "Off" - - - label: "Step 7:TH sends a On command to the DUT" - PICS: OO.S.C01.Rsp - cluster: "On/Off" - command: "On" - - - label: "Step 8: TH reads from the DUT the CurrentMode attribute." - PICS: EEVSEM.S.A0001 && EEVSEM.S.A0003 && MOD.S.F00 - command: "readAttribute" - attribute: "CurrentMode" - response: - value: on_mode_dut diff --git a/src/app/tests/suites/certification/Test_TC_EEVSEM_3_2.yaml b/src/app/tests/suites/certification/Test_TC_EEVSEM_3_2.yaml deleted file mode 100644 index 0251528f9ffe94..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_EEVSEM_3_2.yaml +++ /dev/null @@ -1,172 +0,0 @@ -# Copyright (c) 2024 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -name: 269.3.2. [TC-EEVSEM-3.2] Startup Mode functionality with DUT as Server - -PICS: - - EEVSEM.S.A0002 - -config: - nodeId: 0x12344321 - cluster: "Energy EVSE Mode" - endpoint: 1 - - new_start_up_mode_th: - type: int8u - defaultValue: 0 - new_mode_th: - type: int8u - defaultValue: 1 - -tests: - - label: - "Step 1: Commission DUT to TH (can be skipped if done in a preceding - test)." - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: TH reads from the DUT the StartUpMode attribute." - PICS: EEVSEM.S.A0002 - command: "readAttribute" - attribute: "StartUpMode" - response: - saveAs: startup_mode_dut - - - label: - "Step 2: If startup_mode_dut is null proceed to step 3. Else save - startup_mode_dut as new_start_up_mode_th and proceed to step 5." - PICS: EEVSEM.S.A0002 - cluster: "EqualityCommands" - command: "UnsignedNumberEquals" - arguments: - values: - - name: "Value1" - value: startup_mode_dut - - name: "Value2" - value: null - response: - - values: - - name: "Equals" - saveAs: IsExpectedValue - - - label: "Step 3: TH reads from the DUT the SupportedModes attribute." - runIf: IsExpectedValue - PICS: EEVSEM.S.A0000 - command: "readAttribute" - attribute: "SupportedModes" - response: - saveAs: supported_modes_dut - constraints: - type: list - minLength: 2 - - label: - "Step 4: TH writes to the DUT the StartUpMode attribute with the - new_start_up_mode_th value" - PICS: EEVSEM.S.A0002 - runIf: IsExpectedValue - command: "writeAttribute" - attribute: "StartUpMode" - arguments: - value: new_start_up_mode_th - - - label: "Step 5: TH reads from the DUT the CurrentMode attribute." - PICS: EEVSEM.S.A0001 - command: "readAttribute" - attribute: "CurrentMode" - response: - saveAs: old_current_mode_dut - - - label: - "Step 5: If startup_mode_dut is equal to old_current_mode_dut proceed - to step 6. Else proceed to step 8." - PICS: EEVSEM.S.A0001 && EEVSEM.S.A0002 - cluster: "EqualityCommands" - command: "UnsignedNumberEquals" - arguments: - values: - - name: "Value1" - value: startup_mode_dut - - name: "Value2" - value: old_current_mode_dut - response: - - values: - - name: "Equals" - saveAs: Step5_IsExpectedValue - - - label: "Step 6: TH reads from the DUT the SupportedModes attribute." - PICS: EEVSEM.S.A0000 - runIf: Step5_IsExpectedValue - command: "readAttribute" - attribute: "SupportedModes" - response: - saveAs: Step6_supported_modes_dut - constraints: - type: list - minLength: 2 - - - label: - "Step 7: TH sends a ChangeToMode command to the DUT with NewMode set - to new_mode_th" - PICS: EEVSEM.S.C00.Rsp - runIf: Step5_IsExpectedValue - command: "ChangeToMode" - arguments: - values: - - name: "NewMode" - value: new_mode_th - response: - values: - - name: "Status" - value: 0x00 - - - label: "Step 8: Physically power cycle the device" - verification: | - Physically power cycle the device. - cluster: "LogCommands" - command: "UserPrompt" - PICS: PICS_USER_PROMPT - arguments: - values: - - name: "message" - value: "Please enter 'y' for success" - - name: "expectedValue" - value: "y" - - - label: "Wait for the commissioned device to be retrieved" - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 9: TH reads from the DUT the StartUpMode attribute." - PICS: EEVSEM.S.A0002 && PICS_USER_PROMPT - command: "readAttribute" - attribute: "StartUpMode" - response: - saveAs: new_start_up_mode_dut - constraints: - anyOf: [startup_mode_dut, new_start_up_mode_th] - - - label: "Step 10: TH reads from the DUT the CurrentMode attribute." - PICS: EEVSEM.S.A0001 && PICS_USER_PROMPT - command: "readAttribute" - attribute: "CurrentMode" - response: - value: new_start_up_mode_dut diff --git a/src/app/tests/suites/certification/Test_TC_EEVSEM_3_3.yaml b/src/app/tests/suites/certification/Test_TC_EEVSEM_3_3.yaml deleted file mode 100644 index e60aa1ca60c740..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_EEVSEM_3_3.yaml +++ /dev/null @@ -1,189 +0,0 @@ -# Copyright (c) 2024 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -name: - 269.3.3. [TC-EEVSEM-3.3] On Mode and Startup Mode functionality with DUT as - Server - -PICS: - - EEVSEM.S.A0002 - - EEVSEM.S.A0003 - - MOD.S.F00 - - OO.S.A4003 - -config: - nodeId: 0x12344321 - cluster: "Energy EVSE Mode" - endpoint: 1 - - new_start_up_mode_th: - type: int8u - defaultValue: 0 - new_mode_th: - type: int8u - defaultValue: 1 - -tests: - - label: - "Step 1: Commission DUT to TH (can be skipped if done in a preceding - test)." - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: TH reads from the DUT the StartUpMode attribute." - PICS: EEVSEM.S.A0002 - command: "readAttribute" - attribute: "StartUpMode" - response: - saveAs: startup_mode_dut - - - label: - "Step 2: If startup_mode_dut is null proceed to step 3. Else save - startup_mode_dut as new_start_up_mode_th and proceed to step 5." - PICS: EEVSEM.S.A0002 - cluster: "EqualityCommands" - command: "UnsignedNumberEquals" - arguments: - values: - - name: "Value1" - value: startup_mode_dut - - name: "Value2" - value: null - response: - - values: - - name: "Equals" - saveAs: IsExpectedValue - - - label: "Step 3: TH reads from the DUT the SupportedModes attribute." - runIf: IsExpectedValue - PICS: EEVSEM.S.A0000 - command: "readAttribute" - attribute: "SupportedModes" - response: - saveAs: supported_modes_dut - constraints: - type: list - minLength: 2 - - - label: - "Step 4: TH writes to the DUT the StartUpMode attribute with the - new_start_up_mode_th value" - PICS: EEVSEM.S.A0002 - runIf: IsExpectedValue - command: "writeAttribute" - attribute: "StartUpMode" - arguments: - value: new_start_up_mode_th - - - label: "Step 5: TH reads from the DUT the OnMode attribute." - PICS: EEVSEM.S.A0003 && EEVSEM.S.A0002 - command: "readAttribute" - attribute: "OnMode" - response: - saveAs: old_on_mode_dut - - - label: - "Step 5: If startup_mode_dut is equal to old_on_mode_dut proceed to - step 6. Else proceed to step 8." - PICS: EEVSEM.S.A0002 - cluster: "EqualityCommands" - command: "UnsignedNumberEquals" - arguments: - values: - - name: "Value1" - value: old_on_mode_dut - - name: "Value2" - value: startup_mode_dut - response: - - values: - - name: "Equals" - saveAs: Step5_IsExpectedValue - - - label: "Step 6: TH reads from the DUT the SupportedModes attribute." - PICS: EEVSEM.S.A0000 && EEVSEM.S.A0002 - runIf: Step5_IsExpectedValue - command: "readAttribute" - attribute: "SupportedModes" - response: - saveAs: Step6_supported_modes_dut - constraints: - type: list - minLength: 2 - - - label: - "Step 7: TH writes to the DUT the OnMode attribute with the - new_mode_th value" - PICS: EEVSEM.S.A0003 - runIf: Step5_IsExpectedValue - command: "writeAttribute" - attribute: "OnMode" - arguments: - value: new_mode_th - - - label: "Step 8: TH reads from the DUT the OnMode attribute." - PICS: EEVSEM.S.A0003 && MOD.S.F00 - command: "readAttribute" - attribute: "OnMode" - response: - saveAs: new_on_mode_dut - - - label: - "Step 9: TH writes to the DUT the StartUpOnOff attribute with the - value 1." - PICS: OO.S.A4003 - cluster: "On/Off" - command: "writeAttribute" - attribute: "StartUpOnOff" - arguments: - value: 1 - - - label: "Step 10: Physically power cycle the device" - verification: | - Physically power cycle the device. - cluster: "LogCommands" - command: "UserPrompt" - PICS: PICS_USER_PROMPT - arguments: - values: - - name: "message" - value: "Please enter 'y' for success" - - name: "expectedValue" - value: "y" - - - label: "Wait for the commissioned device to be retrieved" - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 11: TH reads from the DUT the StartUpMode attribute." - PICS: EEVSEM.S.A0002 && PICS_USER_PROMPT - command: "readAttribute" - attribute: "StartUpMode" - response: - constraints: - anyOf: [new_start_up_mode_th, startup_mode_dut] - - - label: "Step 12: TH reads from the DUT the CurrentMode attribute." - PICS: EEVSEM.S.A0001 && PICS_USER_PROMPT - command: "readAttribute" - attribute: "CurrentMode" - response: - value: new_on_mode_dut diff --git a/src/app/zap-templates/zcl/data-model/chip/device-energy-management-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/device-energy-management-cluster.xml index b087f3c162ab8d..3550dd0301be99 100644 --- a/src/app/zap-templates/zcl/data-model/chip/device-energy-management-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/device-energy-management-cluster.xml @@ -1,6 +1,6 @@ - + + Device Energy Management @@ -26,12 +32,10 @@ limitations under the License. This cluster allows a client to manage the power draw of a device. An example of such a client could be an Energy Management System (EMS) which controls an Energy Smart Appliance (ESA). - + - + @@ -49,28 +53,23 @@ future power consumption vs time."> - + - + - + - + - + @@ -126,26 +125,26 @@ planned operation."> - Allows a client to request cancellation of a previous adjustment request in a StartTimeAdjustRequest, ModifyForecastRequest or RequestConstraintBasedForecast command + Allows a client to request cancellation of a previous adjustment request in a StartTimeAdjustRequest, ModifyForecastRequest or RequestConstraintBasedForecast command. - PowerAdjustStart + This event SHALL be generated when the Power Adjustment session is started. - PowerAdjustEnd + This event SHALL be generated when the Power Adjustment session ends. - Paused + This event SHALL be generated when the ESA enters the Paused state. - Resumed + This event SHALL be generated when the ESA leaves the Paused state and resumes operation. diff --git a/src/app/zap-templates/zcl/data-model/chip/device-energy-management-mode-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/device-energy-management-mode-cluster.xml index 3ee32897b4df06..c3440adebef3f6 100644 --- a/src/app/zap-templates/zcl/data-model/chip/device-energy-management-mode-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/device-energy-management-mode-cluster.xml @@ -14,9 +14,14 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --> - + + - - - - - + + + + - General + Energy Management Device Energy Management Mode 0x009F DEVICE_ENERGY_MANAGEMENT_MODE_CLUSTER true true Attributes and commands for selecting a mode from a list of supported options. - - + - + - - SupportedModes - CurrentMode - StartUpMode - OnMode - + SupportedModes + CurrentMode - - This command is used to change device modes. - On receipt of this command the device SHALL respond with a ChangeToModeResponse command. - - + This command is used to change device modes. + - - This command is sent by the device on receipt of the ChangeToModeWithStatus command. - - - + This command is sent by the device on receipt of the ChangeToMode command. + + + diff --git a/src/app/zap-templates/zcl/data-model/chip/energy-evse-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/energy-evse-cluster.xml index 94774774d53a10..7a4a40d2e39966 100644 --- a/src/app/zap-templates/zcl/data-model/chip/energy-evse-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/energy-evse-cluster.xml @@ -1,6 +1,6 @@ - + + @@ -94,25 +100,31 @@ limitations under the License. true true Electric Vehicle Supply Equipment (EVSE) is equipment used to charge an Electric Vehicle (EV) or Plug-In Hybrid Electric Vehicle. This cluster provides an interface to the functionality of Electric Vehicle Supply Equipment (EVSE) management. - + + + + - + - - - - + + + + - + + + + @@ -146,7 +158,7 @@ limitations under the License. NextChargeTargetSoC - + ApproximateEVEfficiency @@ -169,13 +181,13 @@ limitations under the License. - This command allows a client to enable the EVSE to charge an EV, + This command allows a client to enable the EVSE to charge an EV, and to provide or update the maximum and minimum charge current. - Upon receipt, this SHALL allow a client to enable the discharge of an EV, + Upon receipt, this SHALL allow a client to enable the discharge of an EV, and to provide or update the maximum discharge current. @@ -201,12 +213,12 @@ limitations under the License. - EVConnected + This event SHALL be generated when the EV is plugged in. - EVNotDetected + This event SHALL be generated when the EV is unplugged or not detected (having been previously plugged in). @@ -215,7 +227,7 @@ limitations under the License. - EnergyTransferStarted + This event SHALL be generated whenever the EV starts charging or discharging, except when an EV has switched between charging and discharging under the control of the PowerAdjustment feature of the Device Energy Management cluster of the associated Device Energy Management device. @@ -223,7 +235,7 @@ limitations under the License. - EnergyTransferStopped + This event SHALL be generated whenever the EV stops charging or discharging, except when an EV has switched between charging and discharging under the control of the PowerAdjustment feature of the Device Energy Management cluster of the associated Device Energy Management device. @@ -232,7 +244,7 @@ limitations under the License. - Fault + If the EVSE detects a fault it SHALL generate a Fault Event. @@ -240,7 +252,7 @@ limitations under the License. - RFID + This event SHALL be generated when a RFID card has been read. diff --git a/src/app/zap-templates/zcl/data-model/chip/energy-evse-mode-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/energy-evse-mode-cluster.xml index b5dc56682132a5..b28daf8899636c 100644 --- a/src/app/zap-templates/zcl/data-model/chip/energy-evse-mode-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/energy-evse-mode-cluster.xml @@ -14,9 +14,14 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --> - + + - + - General + Energy Management Energy EVSE Mode 0x009D ENERGY_EVSE_MODE_CLUSTER true true Attributes and commands for selecting a mode from a list of supported options. - - + - + - - SupportedModes - CurrentMode - StartUpMode - OnMode - + SupportedModes + CurrentMode - - This command is used to change device modes. - On receipt of this command the device SHALL respond with a ChangeToModeResponse command. - - + This command is used to change device modes. + - - This command is sent by the device on receipt of the ChangeToModeWithStatus command. - - - + This command is sent by the device on receipt of the ChangeToMode command. + + + diff --git a/src/app/zap-templates/zcl/data-model/chip/water-heater-management-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/water-heater-management-cluster.xml index 8246930e5b4dab..beeaf277b77d2e 100644 --- a/src/app/zap-templates/zcl/data-model/chip/water-heater-management-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/water-heater-management-cluster.xml @@ -14,7 +14,13 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --> - + + @@ -76,12 +82,12 @@ limitations under the License. - BoostStarted + This event SHALL be generated whenever a Boost command is accepted. - BoostEnded + This event SHALL be generated whenever the BoostState transitions from Active to Inactive. diff --git a/src/app/zap-templates/zcl/data-model/chip/water-heater-mode-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/water-heater-mode-cluster.xml index 502f9e3f032b54..d9211e808467fb 100644 --- a/src/app/zap-templates/zcl/data-model/chip/water-heater-mode-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/water-heater-mode-cluster.xml @@ -14,12 +14,16 @@ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --> - + + - - @@ -33,7 +37,6 @@ limitations under the License. - @@ -41,7 +44,7 @@ limitations under the License. - General + Energy Management Water Heater Mode 0x009E WATER_HEATER_MODE_CLUSTER @@ -49,34 +52,25 @@ limitations under the License. true Attributes and commands for selecting a mode from a list of supported options. - - + - - SupportedModes - CurrentMode - StartUpMode - OnMode - + SupportedModes + CurrentMode - - This command is used to change device modes. - On receipt of this command the device SHALL respond with a ChangeToModeResponse command. - - + This command is used to change device modes. + - - This command is sent by the device on receipt of the ChangeToModeWithStatus command. - - - + This command is sent by the device on receipt of the ChangeToMode command. + + + diff --git a/src/controller/data_model/controller-clusters.matter b/src/controller/data_model/controller-clusters.matter index 3b777477b217d6..d663a5f018a217 100644 --- a/src/controller/data_model/controller-clusters.matter +++ b/src/controller/data_model/controller-clusters.matter @@ -5260,13 +5260,13 @@ provisional cluster DeviceEnergyManagement = 152 { command ModifyForecastRequest(ModifyForecastRequestRequest): DefaultSuccess = 5; /** Allows a client to ask the ESA to recompute its Forecast based on power and time constraints. */ command RequestConstraintBasedForecast(RequestConstraintBasedForecastRequest): DefaultSuccess = 6; - /** Allows a client to request cancellation of a previous adjustment request in a StartTimeAdjustRequest, ModifyForecastRequest or RequestConstraintBasedForecast command */ + /** Allows a client to request cancellation of a previous adjustment request in a StartTimeAdjustRequest, ModifyForecastRequest or RequestConstraintBasedForecast command. */ command CancelRequest(): DefaultSuccess = 7; } /** Electric Vehicle Supply Equipment (EVSE) is equipment used to charge an Electric Vehicle (EV) or Plug-In Hybrid Electric Vehicle. This cluster provides an interface to the functionality of Electric Vehicle Supply Equipment (EVSE) management. */ cluster EnergyEvse = 153 { - revision 4; + revision 3; enum EnergyTransferStoppedReasonEnum : enum8 { kEVStopped = 0; @@ -5431,9 +5431,9 @@ cluster EnergyEvse = 153 { /** Allows a client to disable the EVSE from charging and discharging. */ timed command Disable(): DefaultSuccess = 1; - /** This command allows a client to enable the EVSE to charge an EV, */ + /** This command allows a client to enable the EVSE to charge an EV, and to provide or update the maximum and minimum charge current. */ timed command EnableCharging(EnableChargingRequest): DefaultSuccess = 2; - /** Upon receipt, this SHALL allow a client to enable the discharge of an EV, */ + /** Upon receipt, this SHALL allow a client to enable the discharge of an EV, and to provide or update the maximum discharge current. */ timed command EnableDischarging(EnableDischargingRequest): DefaultSuccess = 3; /** Allows a client to put the EVSE into a self-diagnostics mode. */ timed command StartDiagnostics(): DefaultSuccess = 4; @@ -5502,7 +5502,7 @@ cluster PowerTopology = 156 { /** Attributes and commands for selecting a mode from a list of supported options. */ cluster EnergyEvseMode = 157 { - revision 1; + revision 2; enum ModeTag : enum16 { kAuto = 0; @@ -5518,6 +5518,7 @@ cluster EnergyEvseMode = 157 { kManual = 16384; kTimeOfUse = 16385; kSolarCharging = 16386; + kV2X = 16387; } bitmap Feature : bitmap32 { @@ -5537,8 +5538,6 @@ cluster EnergyEvseMode = 157 { readonly attribute ModeOptionStruct supportedModes[] = 0; readonly attribute int8u currentMode = 1; - attribute optional nullable int8u startUpMode = 2; - attribute optional nullable int8u onMode = 3; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -5555,8 +5554,7 @@ cluster EnergyEvseMode = 157 { optional char_string<64> statusText = 1; } - /** This command is used to change device modes. - On receipt of this command the device SHALL respond with a ChangeToModeResponse command. */ + /** This command is used to change device modes. */ command ChangeToMode(ChangeToModeRequest): ChangeToModeResponse = 0; } @@ -5597,8 +5595,6 @@ cluster WaterHeaterMode = 158 { readonly attribute ModeOptionStruct supportedModes[] = 0; readonly attribute int8u currentMode = 1; - attribute optional nullable int8u startUpMode = 2; - attribute optional nullable int8u onMode = 3; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -5612,17 +5608,16 @@ cluster WaterHeaterMode = 158 { response struct ChangeToModeResponse = 1 { enum8 status = 0; - optional char_string statusText = 1; + optional char_string<64> statusText = 1; } - /** This command is used to change device modes. - On receipt of this command the device SHALL respond with a ChangeToModeResponse command. */ + /** This command is used to change device modes. */ command ChangeToMode(ChangeToModeRequest): ChangeToModeResponse = 0; } /** Attributes and commands for selecting a mode from a list of supported options. */ provisional cluster DeviceEnergyManagementMode = 159 { - revision 1; + revision 2; enum ModeTag : enum16 { kAuto = 0; @@ -5658,8 +5653,6 @@ provisional cluster DeviceEnergyManagementMode = 159 { readonly attribute ModeOptionStruct supportedModes[] = 0; readonly attribute int8u currentMode = 1; - attribute optional nullable int8u startUpMode = 2; - attribute optional nullable int8u onMode = 3; readonly attribute command_id generatedCommandList[] = 65528; readonly attribute command_id acceptedCommandList[] = 65529; readonly attribute event_id eventList[] = 65530; @@ -5676,8 +5669,7 @@ provisional cluster DeviceEnergyManagementMode = 159 { optional char_string<64> statusText = 1; } - /** This command is used to change device modes. - On receipt of this command the device SHALL respond with a ChangeToModeResponse command. */ + /** This command is used to change device modes. */ command ChangeToMode(ChangeToModeRequest): ChangeToModeResponse = 0; } diff --git a/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java b/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java index 5560704fd36ced..dff134bddd1a18 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java @@ -33304,8 +33304,6 @@ public static class EnergyEvseModeCluster extends BaseChipCluster { private static final long SUPPORTED_MODES_ATTRIBUTE_ID = 0L; private static final long CURRENT_MODE_ATTRIBUTE_ID = 1L; - private static final long START_UP_MODE_ATTRIBUTE_ID = 2L; - private static final long ON_MODE_ATTRIBUTE_ID = 3L; private static final long GENERATED_COMMAND_LIST_ATTRIBUTE_ID = 65528L; private static final long ACCEPTED_COMMAND_LIST_ATTRIBUTE_ID = 65529L; private static final long EVENT_LIST_ATTRIBUTE_ID = 65530L; @@ -33368,14 +33366,6 @@ public interface SupportedModesAttributeCallback extends BaseAttributeCallback { void onSuccess(List value); } - public interface StartUpModeAttributeCallback extends BaseAttributeCallback { - void onSuccess(@Nullable Integer value); - } - - public interface OnModeAttributeCallback extends BaseAttributeCallback { - void onSuccess(@Nullable Integer value); - } - public interface GeneratedCommandListAttributeCallback extends BaseAttributeCallback { void onSuccess(List value); } @@ -33444,76 +33434,6 @@ public void onSuccess(byte[] tlv) { }, CURRENT_MODE_ATTRIBUTE_ID, minInterval, maxInterval); } - public void readStartUpModeAttribute( - StartUpModeAttributeCallback callback) { - ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, START_UP_MODE_ATTRIBUTE_ID); - - readAttribute(new ReportCallbackImpl(callback, path) { - @Override - public void onSuccess(byte[] tlv) { - @Nullable Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); - callback.onSuccess(value); - } - }, START_UP_MODE_ATTRIBUTE_ID, true); - } - - public void writeStartUpModeAttribute(DefaultClusterCallback callback, Integer value) { - writeStartUpModeAttribute(callback, value, 0); - } - - public void writeStartUpModeAttribute(DefaultClusterCallback callback, Integer value, int timedWriteTimeoutMs) { - BaseTLVType tlvValue = value != null ? new UIntType(value) : new NullType(); - writeAttribute(new WriteAttributesCallbackImpl(callback), START_UP_MODE_ATTRIBUTE_ID, tlvValue, timedWriteTimeoutMs); - } - - public void subscribeStartUpModeAttribute( - StartUpModeAttributeCallback callback, int minInterval, int maxInterval) { - ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, START_UP_MODE_ATTRIBUTE_ID); - - subscribeAttribute(new ReportCallbackImpl(callback, path) { - @Override - public void onSuccess(byte[] tlv) { - @Nullable Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); - callback.onSuccess(value); - } - }, START_UP_MODE_ATTRIBUTE_ID, minInterval, maxInterval); - } - - public void readOnModeAttribute( - OnModeAttributeCallback callback) { - ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ON_MODE_ATTRIBUTE_ID); - - readAttribute(new ReportCallbackImpl(callback, path) { - @Override - public void onSuccess(byte[] tlv) { - @Nullable Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); - callback.onSuccess(value); - } - }, ON_MODE_ATTRIBUTE_ID, true); - } - - public void writeOnModeAttribute(DefaultClusterCallback callback, Integer value) { - writeOnModeAttribute(callback, value, 0); - } - - public void writeOnModeAttribute(DefaultClusterCallback callback, Integer value, int timedWriteTimeoutMs) { - BaseTLVType tlvValue = value != null ? new UIntType(value) : new NullType(); - writeAttribute(new WriteAttributesCallbackImpl(callback), ON_MODE_ATTRIBUTE_ID, tlvValue, timedWriteTimeoutMs); - } - - public void subscribeOnModeAttribute( - OnModeAttributeCallback callback, int minInterval, int maxInterval) { - ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ON_MODE_ATTRIBUTE_ID); - - subscribeAttribute(new ReportCallbackImpl(callback, path) { - @Override - public void onSuccess(byte[] tlv) { - @Nullable Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); - callback.onSuccess(value); - } - }, ON_MODE_ATTRIBUTE_ID, minInterval, maxInterval); - } - public void readGeneratedCommandListAttribute( GeneratedCommandListAttributeCallback callback) { ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, GENERATED_COMMAND_LIST_ATTRIBUTE_ID); @@ -33676,8 +33596,6 @@ public static class WaterHeaterModeCluster extends BaseChipCluster { private static final long SUPPORTED_MODES_ATTRIBUTE_ID = 0L; private static final long CURRENT_MODE_ATTRIBUTE_ID = 1L; - private static final long START_UP_MODE_ATTRIBUTE_ID = 2L; - private static final long ON_MODE_ATTRIBUTE_ID = 3L; private static final long GENERATED_COMMAND_LIST_ATTRIBUTE_ID = 65528L; private static final long ACCEPTED_COMMAND_LIST_ATTRIBUTE_ID = 65529L; private static final long EVENT_LIST_ATTRIBUTE_ID = 65530L; @@ -33740,14 +33658,6 @@ public interface SupportedModesAttributeCallback extends BaseAttributeCallback { void onSuccess(List value); } - public interface StartUpModeAttributeCallback extends BaseAttributeCallback { - void onSuccess(@Nullable Integer value); - } - - public interface OnModeAttributeCallback extends BaseAttributeCallback { - void onSuccess(@Nullable Integer value); - } - public interface GeneratedCommandListAttributeCallback extends BaseAttributeCallback { void onSuccess(List value); } @@ -33816,76 +33726,6 @@ public void onSuccess(byte[] tlv) { }, CURRENT_MODE_ATTRIBUTE_ID, minInterval, maxInterval); } - public void readStartUpModeAttribute( - StartUpModeAttributeCallback callback) { - ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, START_UP_MODE_ATTRIBUTE_ID); - - readAttribute(new ReportCallbackImpl(callback, path) { - @Override - public void onSuccess(byte[] tlv) { - @Nullable Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); - callback.onSuccess(value); - } - }, START_UP_MODE_ATTRIBUTE_ID, true); - } - - public void writeStartUpModeAttribute(DefaultClusterCallback callback, Integer value) { - writeStartUpModeAttribute(callback, value, 0); - } - - public void writeStartUpModeAttribute(DefaultClusterCallback callback, Integer value, int timedWriteTimeoutMs) { - BaseTLVType tlvValue = value != null ? new UIntType(value) : new NullType(); - writeAttribute(new WriteAttributesCallbackImpl(callback), START_UP_MODE_ATTRIBUTE_ID, tlvValue, timedWriteTimeoutMs); - } - - public void subscribeStartUpModeAttribute( - StartUpModeAttributeCallback callback, int minInterval, int maxInterval) { - ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, START_UP_MODE_ATTRIBUTE_ID); - - subscribeAttribute(new ReportCallbackImpl(callback, path) { - @Override - public void onSuccess(byte[] tlv) { - @Nullable Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); - callback.onSuccess(value); - } - }, START_UP_MODE_ATTRIBUTE_ID, minInterval, maxInterval); - } - - public void readOnModeAttribute( - OnModeAttributeCallback callback) { - ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ON_MODE_ATTRIBUTE_ID); - - readAttribute(new ReportCallbackImpl(callback, path) { - @Override - public void onSuccess(byte[] tlv) { - @Nullable Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); - callback.onSuccess(value); - } - }, ON_MODE_ATTRIBUTE_ID, true); - } - - public void writeOnModeAttribute(DefaultClusterCallback callback, Integer value) { - writeOnModeAttribute(callback, value, 0); - } - - public void writeOnModeAttribute(DefaultClusterCallback callback, Integer value, int timedWriteTimeoutMs) { - BaseTLVType tlvValue = value != null ? new UIntType(value) : new NullType(); - writeAttribute(new WriteAttributesCallbackImpl(callback), ON_MODE_ATTRIBUTE_ID, tlvValue, timedWriteTimeoutMs); - } - - public void subscribeOnModeAttribute( - OnModeAttributeCallback callback, int minInterval, int maxInterval) { - ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ON_MODE_ATTRIBUTE_ID); - - subscribeAttribute(new ReportCallbackImpl(callback, path) { - @Override - public void onSuccess(byte[] tlv) { - @Nullable Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); - callback.onSuccess(value); - } - }, ON_MODE_ATTRIBUTE_ID, minInterval, maxInterval); - } - public void readGeneratedCommandListAttribute( GeneratedCommandListAttributeCallback callback) { ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, GENERATED_COMMAND_LIST_ATTRIBUTE_ID); @@ -34048,8 +33888,6 @@ public static class DeviceEnergyManagementModeCluster extends BaseChipCluster { private static final long SUPPORTED_MODES_ATTRIBUTE_ID = 0L; private static final long CURRENT_MODE_ATTRIBUTE_ID = 1L; - private static final long START_UP_MODE_ATTRIBUTE_ID = 2L; - private static final long ON_MODE_ATTRIBUTE_ID = 3L; private static final long GENERATED_COMMAND_LIST_ATTRIBUTE_ID = 65528L; private static final long ACCEPTED_COMMAND_LIST_ATTRIBUTE_ID = 65529L; private static final long EVENT_LIST_ATTRIBUTE_ID = 65530L; @@ -34112,14 +33950,6 @@ public interface SupportedModesAttributeCallback extends BaseAttributeCallback { void onSuccess(List value); } - public interface StartUpModeAttributeCallback extends BaseAttributeCallback { - void onSuccess(@Nullable Integer value); - } - - public interface OnModeAttributeCallback extends BaseAttributeCallback { - void onSuccess(@Nullable Integer value); - } - public interface GeneratedCommandListAttributeCallback extends BaseAttributeCallback { void onSuccess(List value); } @@ -34188,76 +34018,6 @@ public void onSuccess(byte[] tlv) { }, CURRENT_MODE_ATTRIBUTE_ID, minInterval, maxInterval); } - public void readStartUpModeAttribute( - StartUpModeAttributeCallback callback) { - ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, START_UP_MODE_ATTRIBUTE_ID); - - readAttribute(new ReportCallbackImpl(callback, path) { - @Override - public void onSuccess(byte[] tlv) { - @Nullable Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); - callback.onSuccess(value); - } - }, START_UP_MODE_ATTRIBUTE_ID, true); - } - - public void writeStartUpModeAttribute(DefaultClusterCallback callback, Integer value) { - writeStartUpModeAttribute(callback, value, 0); - } - - public void writeStartUpModeAttribute(DefaultClusterCallback callback, Integer value, int timedWriteTimeoutMs) { - BaseTLVType tlvValue = value != null ? new UIntType(value) : new NullType(); - writeAttribute(new WriteAttributesCallbackImpl(callback), START_UP_MODE_ATTRIBUTE_ID, tlvValue, timedWriteTimeoutMs); - } - - public void subscribeStartUpModeAttribute( - StartUpModeAttributeCallback callback, int minInterval, int maxInterval) { - ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, START_UP_MODE_ATTRIBUTE_ID); - - subscribeAttribute(new ReportCallbackImpl(callback, path) { - @Override - public void onSuccess(byte[] tlv) { - @Nullable Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); - callback.onSuccess(value); - } - }, START_UP_MODE_ATTRIBUTE_ID, minInterval, maxInterval); - } - - public void readOnModeAttribute( - OnModeAttributeCallback callback) { - ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ON_MODE_ATTRIBUTE_ID); - - readAttribute(new ReportCallbackImpl(callback, path) { - @Override - public void onSuccess(byte[] tlv) { - @Nullable Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); - callback.onSuccess(value); - } - }, ON_MODE_ATTRIBUTE_ID, true); - } - - public void writeOnModeAttribute(DefaultClusterCallback callback, Integer value) { - writeOnModeAttribute(callback, value, 0); - } - - public void writeOnModeAttribute(DefaultClusterCallback callback, Integer value, int timedWriteTimeoutMs) { - BaseTLVType tlvValue = value != null ? new UIntType(value) : new NullType(); - writeAttribute(new WriteAttributesCallbackImpl(callback), ON_MODE_ATTRIBUTE_ID, tlvValue, timedWriteTimeoutMs); - } - - public void subscribeOnModeAttribute( - OnModeAttributeCallback callback, int minInterval, int maxInterval) { - ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ON_MODE_ATTRIBUTE_ID); - - subscribeAttribute(new ReportCallbackImpl(callback, path) { - @Override - public void onSuccess(byte[] tlv) { - @Nullable Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); - callback.onSuccess(value); - } - }, ON_MODE_ATTRIBUTE_ID, minInterval, maxInterval); - } - public void readGeneratedCommandListAttribute( GeneratedCommandListAttributeCallback callback) { ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, GENERATED_COMMAND_LIST_ATTRIBUTE_ID); diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java index 9ab44a7257397a..a43df66e40bf0a 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java @@ -10227,8 +10227,6 @@ public long getID() { public enum Attribute { SupportedModes(0L), CurrentMode(1L), - StartUpMode(2L), - OnMode(3L), GeneratedCommandList(65528L), AcceptedCommandList(65529L), EventList(65530L), @@ -10349,8 +10347,6 @@ public long getID() { public enum Attribute { SupportedModes(0L), CurrentMode(1L), - StartUpMode(2L), - OnMode(3L), GeneratedCommandList(65528L), AcceptedCommandList(65529L), EventList(65530L), @@ -10471,8 +10467,6 @@ public long getID() { public enum Attribute { SupportedModes(0L), CurrentMode(1L), - StartUpMode(2L), - OnMode(3L), GeneratedCommandList(65528L), AcceptedCommandList(65529L), EventList(65530L), diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java index 6e89ac926fd9a3..d0e83258a32ae5 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java @@ -11742,48 +11742,6 @@ public void onError(Exception ex) { } } - public static class DelegatedEnergyEvseModeClusterStartUpModeAttributeCallback implements ChipClusters.EnergyEvseModeCluster.StartUpModeAttributeCallback, DelegatedClusterCallback { - private ClusterCommandCallback callback; - @Override - public void setCallbackDelegate(ClusterCommandCallback callback) { - this.callback = callback; - } - - @Override - public void onSuccess(@Nullable Integer value) { - Map responseValues = new LinkedHashMap<>(); - CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer"); - responseValues.put(commandResponseInfo, value); - callback.onSuccess(responseValues); - } - - @Override - public void onError(Exception ex) { - callback.onFailure(ex); - } - } - - public static class DelegatedEnergyEvseModeClusterOnModeAttributeCallback implements ChipClusters.EnergyEvseModeCluster.OnModeAttributeCallback, DelegatedClusterCallback { - private ClusterCommandCallback callback; - @Override - public void setCallbackDelegate(ClusterCommandCallback callback) { - this.callback = callback; - } - - @Override - public void onSuccess(@Nullable Integer value) { - Map responseValues = new LinkedHashMap<>(); - CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer"); - responseValues.put(commandResponseInfo, value); - callback.onSuccess(responseValues); - } - - @Override - public void onError(Exception ex) { - callback.onFailure(ex); - } - } - public static class DelegatedEnergyEvseModeClusterGeneratedCommandListAttributeCallback implements ChipClusters.EnergyEvseModeCluster.GeneratedCommandListAttributeCallback, DelegatedClusterCallback { private ClusterCommandCallback callback; @Override @@ -11913,48 +11871,6 @@ public void onError(Exception ex) { } } - public static class DelegatedWaterHeaterModeClusterStartUpModeAttributeCallback implements ChipClusters.WaterHeaterModeCluster.StartUpModeAttributeCallback, DelegatedClusterCallback { - private ClusterCommandCallback callback; - @Override - public void setCallbackDelegate(ClusterCommandCallback callback) { - this.callback = callback; - } - - @Override - public void onSuccess(@Nullable Integer value) { - Map responseValues = new LinkedHashMap<>(); - CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer"); - responseValues.put(commandResponseInfo, value); - callback.onSuccess(responseValues); - } - - @Override - public void onError(Exception ex) { - callback.onFailure(ex); - } - } - - public static class DelegatedWaterHeaterModeClusterOnModeAttributeCallback implements ChipClusters.WaterHeaterModeCluster.OnModeAttributeCallback, DelegatedClusterCallback { - private ClusterCommandCallback callback; - @Override - public void setCallbackDelegate(ClusterCommandCallback callback) { - this.callback = callback; - } - - @Override - public void onSuccess(@Nullable Integer value) { - Map responseValues = new LinkedHashMap<>(); - CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer"); - responseValues.put(commandResponseInfo, value); - callback.onSuccess(responseValues); - } - - @Override - public void onError(Exception ex) { - callback.onFailure(ex); - } - } - public static class DelegatedWaterHeaterModeClusterGeneratedCommandListAttributeCallback implements ChipClusters.WaterHeaterModeCluster.GeneratedCommandListAttributeCallback, DelegatedClusterCallback { private ClusterCommandCallback callback; @Override @@ -12084,48 +12000,6 @@ public void onError(Exception ex) { } } - public static class DelegatedDeviceEnergyManagementModeClusterStartUpModeAttributeCallback implements ChipClusters.DeviceEnergyManagementModeCluster.StartUpModeAttributeCallback, DelegatedClusterCallback { - private ClusterCommandCallback callback; - @Override - public void setCallbackDelegate(ClusterCommandCallback callback) { - this.callback = callback; - } - - @Override - public void onSuccess(@Nullable Integer value) { - Map responseValues = new LinkedHashMap<>(); - CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer"); - responseValues.put(commandResponseInfo, value); - callback.onSuccess(responseValues); - } - - @Override - public void onError(Exception ex) { - callback.onFailure(ex); - } - } - - public static class DelegatedDeviceEnergyManagementModeClusterOnModeAttributeCallback implements ChipClusters.DeviceEnergyManagementModeCluster.OnModeAttributeCallback, DelegatedClusterCallback { - private ClusterCommandCallback callback; - @Override - public void setCallbackDelegate(ClusterCommandCallback callback) { - this.callback = callback; - } - - @Override - public void onSuccess(@Nullable Integer value) { - Map responseValues = new LinkedHashMap<>(); - CommandResponseInfo commandResponseInfo = new CommandResponseInfo("value", "Integer"); - responseValues.put(commandResponseInfo, value); - callback.onSuccess(responseValues); - } - - @Override - public void onError(Exception ex) { - callback.onFailure(ex); - } - } - public static class DelegatedDeviceEnergyManagementModeClusterGeneratedCommandListAttributeCallback implements ChipClusters.DeviceEnergyManagementModeCluster.GeneratedCommandListAttributeCallback, DelegatedClusterCallback { private ClusterCommandCallback callback; @Override diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java index 616f9f299bee1a..9abbcd879c5503 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java @@ -10236,28 +10236,6 @@ private static Map readEnergyEvseModeInteractionInfo() readEnergyEvseModeCurrentModeCommandParams ); result.put("readCurrentModeAttribute", readEnergyEvseModeCurrentModeAttributeInteractionInfo); - Map readEnergyEvseModeStartUpModeCommandParams = new LinkedHashMap(); - InteractionInfo readEnergyEvseModeStartUpModeAttributeInteractionInfo = new InteractionInfo( - (cluster, callback, commandArguments) -> { - ((ChipClusters.EnergyEvseModeCluster) cluster).readStartUpModeAttribute( - (ChipClusters.EnergyEvseModeCluster.StartUpModeAttributeCallback) callback - ); - }, - () -> new ClusterInfoMapping.DelegatedEnergyEvseModeClusterStartUpModeAttributeCallback(), - readEnergyEvseModeStartUpModeCommandParams - ); - result.put("readStartUpModeAttribute", readEnergyEvseModeStartUpModeAttributeInteractionInfo); - Map readEnergyEvseModeOnModeCommandParams = new LinkedHashMap(); - InteractionInfo readEnergyEvseModeOnModeAttributeInteractionInfo = new InteractionInfo( - (cluster, callback, commandArguments) -> { - ((ChipClusters.EnergyEvseModeCluster) cluster).readOnModeAttribute( - (ChipClusters.EnergyEvseModeCluster.OnModeAttributeCallback) callback - ); - }, - () -> new ClusterInfoMapping.DelegatedEnergyEvseModeClusterOnModeAttributeCallback(), - readEnergyEvseModeOnModeCommandParams - ); - result.put("readOnModeAttribute", readEnergyEvseModeOnModeAttributeInteractionInfo); Map readEnergyEvseModeGeneratedCommandListCommandParams = new LinkedHashMap(); InteractionInfo readEnergyEvseModeGeneratedCommandListAttributeInteractionInfo = new InteractionInfo( (cluster, callback, commandArguments) -> { @@ -10350,28 +10328,6 @@ private static Map readWaterHeaterModeInteractionInfo() readWaterHeaterModeCurrentModeCommandParams ); result.put("readCurrentModeAttribute", readWaterHeaterModeCurrentModeAttributeInteractionInfo); - Map readWaterHeaterModeStartUpModeCommandParams = new LinkedHashMap(); - InteractionInfo readWaterHeaterModeStartUpModeAttributeInteractionInfo = new InteractionInfo( - (cluster, callback, commandArguments) -> { - ((ChipClusters.WaterHeaterModeCluster) cluster).readStartUpModeAttribute( - (ChipClusters.WaterHeaterModeCluster.StartUpModeAttributeCallback) callback - ); - }, - () -> new ClusterInfoMapping.DelegatedWaterHeaterModeClusterStartUpModeAttributeCallback(), - readWaterHeaterModeStartUpModeCommandParams - ); - result.put("readStartUpModeAttribute", readWaterHeaterModeStartUpModeAttributeInteractionInfo); - Map readWaterHeaterModeOnModeCommandParams = new LinkedHashMap(); - InteractionInfo readWaterHeaterModeOnModeAttributeInteractionInfo = new InteractionInfo( - (cluster, callback, commandArguments) -> { - ((ChipClusters.WaterHeaterModeCluster) cluster).readOnModeAttribute( - (ChipClusters.WaterHeaterModeCluster.OnModeAttributeCallback) callback - ); - }, - () -> new ClusterInfoMapping.DelegatedWaterHeaterModeClusterOnModeAttributeCallback(), - readWaterHeaterModeOnModeCommandParams - ); - result.put("readOnModeAttribute", readWaterHeaterModeOnModeAttributeInteractionInfo); Map readWaterHeaterModeGeneratedCommandListCommandParams = new LinkedHashMap(); InteractionInfo readWaterHeaterModeGeneratedCommandListAttributeInteractionInfo = new InteractionInfo( (cluster, callback, commandArguments) -> { @@ -10464,28 +10420,6 @@ private static Map readDeviceEnergyManagementModeIntera readDeviceEnergyManagementModeCurrentModeCommandParams ); result.put("readCurrentModeAttribute", readDeviceEnergyManagementModeCurrentModeAttributeInteractionInfo); - Map readDeviceEnergyManagementModeStartUpModeCommandParams = new LinkedHashMap(); - InteractionInfo readDeviceEnergyManagementModeStartUpModeAttributeInteractionInfo = new InteractionInfo( - (cluster, callback, commandArguments) -> { - ((ChipClusters.DeviceEnergyManagementModeCluster) cluster).readStartUpModeAttribute( - (ChipClusters.DeviceEnergyManagementModeCluster.StartUpModeAttributeCallback) callback - ); - }, - () -> new ClusterInfoMapping.DelegatedDeviceEnergyManagementModeClusterStartUpModeAttributeCallback(), - readDeviceEnergyManagementModeStartUpModeCommandParams - ); - result.put("readStartUpModeAttribute", readDeviceEnergyManagementModeStartUpModeAttributeInteractionInfo); - Map readDeviceEnergyManagementModeOnModeCommandParams = new LinkedHashMap(); - InteractionInfo readDeviceEnergyManagementModeOnModeAttributeInteractionInfo = new InteractionInfo( - (cluster, callback, commandArguments) -> { - ((ChipClusters.DeviceEnergyManagementModeCluster) cluster).readOnModeAttribute( - (ChipClusters.DeviceEnergyManagementModeCluster.OnModeAttributeCallback) callback - ); - }, - () -> new ClusterInfoMapping.DelegatedDeviceEnergyManagementModeClusterOnModeAttributeCallback(), - readDeviceEnergyManagementModeOnModeCommandParams - ); - result.put("readOnModeAttribute", readDeviceEnergyManagementModeOnModeAttributeInteractionInfo); Map readDeviceEnergyManagementModeGeneratedCommandListCommandParams = new LinkedHashMap(); InteractionInfo readDeviceEnergyManagementModeGeneratedCommandListAttributeInteractionInfo = new InteractionInfo( (cluster, callback, commandArguments) -> { diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterWriteMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterWriteMapping.java index cfc302460fbcf6..725fd0baeccf65 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ClusterWriteMapping.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterWriteMapping.java @@ -1205,142 +1205,10 @@ public Map> getWriteAttributeMap() { Map writePowerTopologyInteractionInfo = new LinkedHashMap<>(); writeAttributeMap.put("powerTopology", writePowerTopologyInteractionInfo); Map writeEnergyEvseModeInteractionInfo = new LinkedHashMap<>(); - Map writeEnergyEvseModeStartUpModeCommandParams = new LinkedHashMap(); - CommandParameterInfo energyEvseModestartUpModeCommandParameterInfo = - new CommandParameterInfo( - "value", - Integer.class, - Integer.class - ); - writeEnergyEvseModeStartUpModeCommandParams.put( - "value", - energyEvseModestartUpModeCommandParameterInfo - ); - InteractionInfo writeEnergyEvseModeStartUpModeAttributeInteractionInfo = new InteractionInfo( - (cluster, callback, commandArguments) -> { - ((ChipClusters.EnergyEvseModeCluster) cluster).writeStartUpModeAttribute( - (DefaultClusterCallback) callback, - (Integer) commandArguments.get("value") - ); - }, - () -> new ClusterInfoMapping.DelegatedDefaultClusterCallback(), - writeEnergyEvseModeStartUpModeCommandParams - ); - writeEnergyEvseModeInteractionInfo.put("writeStartUpModeAttribute", writeEnergyEvseModeStartUpModeAttributeInteractionInfo); - Map writeEnergyEvseModeOnModeCommandParams = new LinkedHashMap(); - CommandParameterInfo energyEvseModeonModeCommandParameterInfo = - new CommandParameterInfo( - "value", - Integer.class, - Integer.class - ); - writeEnergyEvseModeOnModeCommandParams.put( - "value", - energyEvseModeonModeCommandParameterInfo - ); - InteractionInfo writeEnergyEvseModeOnModeAttributeInteractionInfo = new InteractionInfo( - (cluster, callback, commandArguments) -> { - ((ChipClusters.EnergyEvseModeCluster) cluster).writeOnModeAttribute( - (DefaultClusterCallback) callback, - (Integer) commandArguments.get("value") - ); - }, - () -> new ClusterInfoMapping.DelegatedDefaultClusterCallback(), - writeEnergyEvseModeOnModeCommandParams - ); - writeEnergyEvseModeInteractionInfo.put("writeOnModeAttribute", writeEnergyEvseModeOnModeAttributeInteractionInfo); writeAttributeMap.put("energyEvseMode", writeEnergyEvseModeInteractionInfo); Map writeWaterHeaterModeInteractionInfo = new LinkedHashMap<>(); - Map writeWaterHeaterModeStartUpModeCommandParams = new LinkedHashMap(); - CommandParameterInfo waterHeaterModestartUpModeCommandParameterInfo = - new CommandParameterInfo( - "value", - Integer.class, - Integer.class - ); - writeWaterHeaterModeStartUpModeCommandParams.put( - "value", - waterHeaterModestartUpModeCommandParameterInfo - ); - InteractionInfo writeWaterHeaterModeStartUpModeAttributeInteractionInfo = new InteractionInfo( - (cluster, callback, commandArguments) -> { - ((ChipClusters.WaterHeaterModeCluster) cluster).writeStartUpModeAttribute( - (DefaultClusterCallback) callback, - (Integer) commandArguments.get("value") - ); - }, - () -> new ClusterInfoMapping.DelegatedDefaultClusterCallback(), - writeWaterHeaterModeStartUpModeCommandParams - ); - writeWaterHeaterModeInteractionInfo.put("writeStartUpModeAttribute", writeWaterHeaterModeStartUpModeAttributeInteractionInfo); - Map writeWaterHeaterModeOnModeCommandParams = new LinkedHashMap(); - CommandParameterInfo waterHeaterModeonModeCommandParameterInfo = - new CommandParameterInfo( - "value", - Integer.class, - Integer.class - ); - writeWaterHeaterModeOnModeCommandParams.put( - "value", - waterHeaterModeonModeCommandParameterInfo - ); - InteractionInfo writeWaterHeaterModeOnModeAttributeInteractionInfo = new InteractionInfo( - (cluster, callback, commandArguments) -> { - ((ChipClusters.WaterHeaterModeCluster) cluster).writeOnModeAttribute( - (DefaultClusterCallback) callback, - (Integer) commandArguments.get("value") - ); - }, - () -> new ClusterInfoMapping.DelegatedDefaultClusterCallback(), - writeWaterHeaterModeOnModeCommandParams - ); - writeWaterHeaterModeInteractionInfo.put("writeOnModeAttribute", writeWaterHeaterModeOnModeAttributeInteractionInfo); writeAttributeMap.put("waterHeaterMode", writeWaterHeaterModeInteractionInfo); Map writeDeviceEnergyManagementModeInteractionInfo = new LinkedHashMap<>(); - Map writeDeviceEnergyManagementModeStartUpModeCommandParams = new LinkedHashMap(); - CommandParameterInfo deviceEnergyManagementModestartUpModeCommandParameterInfo = - new CommandParameterInfo( - "value", - Integer.class, - Integer.class - ); - writeDeviceEnergyManagementModeStartUpModeCommandParams.put( - "value", - deviceEnergyManagementModestartUpModeCommandParameterInfo - ); - InteractionInfo writeDeviceEnergyManagementModeStartUpModeAttributeInteractionInfo = new InteractionInfo( - (cluster, callback, commandArguments) -> { - ((ChipClusters.DeviceEnergyManagementModeCluster) cluster).writeStartUpModeAttribute( - (DefaultClusterCallback) callback, - (Integer) commandArguments.get("value") - ); - }, - () -> new ClusterInfoMapping.DelegatedDefaultClusterCallback(), - writeDeviceEnergyManagementModeStartUpModeCommandParams - ); - writeDeviceEnergyManagementModeInteractionInfo.put("writeStartUpModeAttribute", writeDeviceEnergyManagementModeStartUpModeAttributeInteractionInfo); - Map writeDeviceEnergyManagementModeOnModeCommandParams = new LinkedHashMap(); - CommandParameterInfo deviceEnergyManagementModeonModeCommandParameterInfo = - new CommandParameterInfo( - "value", - Integer.class, - Integer.class - ); - writeDeviceEnergyManagementModeOnModeCommandParams.put( - "value", - deviceEnergyManagementModeonModeCommandParameterInfo - ); - InteractionInfo writeDeviceEnergyManagementModeOnModeAttributeInteractionInfo = new InteractionInfo( - (cluster, callback, commandArguments) -> { - ((ChipClusters.DeviceEnergyManagementModeCluster) cluster).writeOnModeAttribute( - (DefaultClusterCallback) callback, - (Integer) commandArguments.get("value") - ); - }, - () -> new ClusterInfoMapping.DelegatedDefaultClusterCallback(), - writeDeviceEnergyManagementModeOnModeCommandParams - ); - writeDeviceEnergyManagementModeInteractionInfo.put("writeOnModeAttribute", writeDeviceEnergyManagementModeOnModeAttributeInteractionInfo); writeAttributeMap.put("deviceEnergyManagementMode", writeDeviceEnergyManagementModeInteractionInfo); Map writeDoorLockInteractionInfo = new LinkedHashMap<>(); Map writeDoorLockDoorOpenEventsCommandParams = new LinkedHashMap(); diff --git a/src/controller/java/generated/java/matter/controller/cluster/clusters/DeviceEnergyManagementModeCluster.kt b/src/controller/java/generated/java/matter/controller/cluster/clusters/DeviceEnergyManagementModeCluster.kt index 657941cb3f0964..95ccc5a67287d9 100644 --- a/src/controller/java/generated/java/matter/controller/cluster/clusters/DeviceEnergyManagementModeCluster.kt +++ b/src/controller/java/generated/java/matter/controller/cluster/clusters/DeviceEnergyManagementModeCluster.kt @@ -32,9 +32,6 @@ import matter.controller.SubscriptionState import matter.controller.UByteSubscriptionState import matter.controller.UIntSubscriptionState import matter.controller.UShortSubscriptionState -import matter.controller.WriteRequest -import matter.controller.WriteRequests -import matter.controller.WriteResponse import matter.controller.cluster.structs.* import matter.controller.model.AttributePath import matter.controller.model.CommandPath @@ -60,26 +57,6 @@ class DeviceEnergyManagementModeCluster( object SubscriptionEstablished : SupportedModesAttributeSubscriptionState() } - class StartUpModeAttribute(val value: UByte?) - - sealed class StartUpModeAttributeSubscriptionState { - data class Success(val value: UByte?) : StartUpModeAttributeSubscriptionState() - - data class Error(val exception: Exception) : StartUpModeAttributeSubscriptionState() - - object SubscriptionEstablished : StartUpModeAttributeSubscriptionState() - } - - class OnModeAttribute(val value: UByte?) - - sealed class OnModeAttributeSubscriptionState { - data class Success(val value: UByte?) : OnModeAttributeSubscriptionState() - - data class Error(val exception: Exception) : OnModeAttributeSubscriptionState() - - object SubscriptionEstablished : OnModeAttributeSubscriptionState() - } - class GeneratedCommandListAttribute(val value: List) sealed class GeneratedCommandListAttributeSubscriptionState { @@ -364,288 +341,6 @@ class DeviceEnergyManagementModeCluster( } } - suspend fun readStartUpModeAttribute(): StartUpModeAttribute { - val ATTRIBUTE_ID: UInt = 2u - - val attributePath = - AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - - val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - - val response = controller.read(readRequest) - - if (response.successes.isEmpty()) { - logger.log(Level.WARNING, "Read command failed") - throw IllegalStateException("Read command failed with failures: ${response.failures}") - } - - logger.log(Level.FINE, "Read command succeeded") - - val attributeData = - response.successes.filterIsInstance().firstOrNull { - it.path.attributeId == ATTRIBUTE_ID - } - - requireNotNull(attributeData) { "Startupmode attribute not found in response" } - - // Decode the TLV data into the appropriate type - val tlvReader = TlvReader(attributeData.data) - val decodedValue: UByte? = - if (!tlvReader.isNull()) { - if (tlvReader.isNextTag(AnonymousTag)) { - tlvReader.getUByte(AnonymousTag) - } else { - null - } - } else { - tlvReader.getNull(AnonymousTag) - null - } - - return StartUpModeAttribute(decodedValue) - } - - suspend fun writeStartUpModeAttribute(value: UByte, timedWriteTimeout: Duration? = null) { - val ATTRIBUTE_ID: UInt = 2u - - val tlvWriter = TlvWriter() - tlvWriter.put(AnonymousTag, value) - - val writeRequests: WriteRequests = - WriteRequests( - requests = - listOf( - WriteRequest( - attributePath = - AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), - tlvPayload = tlvWriter.getEncoded(), - ) - ), - timedRequest = timedWriteTimeout, - ) - - val response: WriteResponse = controller.write(writeRequests) - - when (response) { - is WriteResponse.Success -> { - logger.log(Level.FINE, "Write command succeeded") - } - is WriteResponse.PartialWriteFailure -> { - val aggregatedErrorMessage = - response.failures.joinToString("\n") { failure -> - "Error at ${failure.attributePath}: ${failure.ex.message}" - } - - response.failures.forEach { failure -> - logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") - } - - throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") - } - } - } - - suspend fun subscribeStartUpModeAttribute( - minInterval: Int, - maxInterval: Int, - ): Flow { - val ATTRIBUTE_ID: UInt = 2u - val attributePaths = - listOf( - AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - ) - - val subscribeRequest: SubscribeRequest = - SubscribeRequest( - eventPaths = emptyList(), - attributePaths = attributePaths, - minInterval = Duration.ofSeconds(minInterval.toLong()), - maxInterval = Duration.ofSeconds(maxInterval.toLong()), - ) - - return controller.subscribe(subscribeRequest).transform { subscriptionState -> - when (subscriptionState) { - is SubscriptionState.SubscriptionErrorNotification -> { - emit( - StartUpModeAttributeSubscriptionState.Error( - Exception( - "Subscription terminated with error code: ${subscriptionState.terminationCause}" - ) - ) - ) - } - is SubscriptionState.NodeStateUpdate -> { - val attributeData = - subscriptionState.updateState.successes - .filterIsInstance() - .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } - - requireNotNull(attributeData) { "Startupmode attribute not found in Node State update" } - - // Decode the TLV data into the appropriate type - val tlvReader = TlvReader(attributeData.data) - val decodedValue: UByte? = - if (!tlvReader.isNull()) { - if (tlvReader.isNextTag(AnonymousTag)) { - tlvReader.getUByte(AnonymousTag) - } else { - null - } - } else { - tlvReader.getNull(AnonymousTag) - null - } - - decodedValue?.let { emit(StartUpModeAttributeSubscriptionState.Success(it)) } - } - SubscriptionState.SubscriptionEstablished -> { - emit(StartUpModeAttributeSubscriptionState.SubscriptionEstablished) - } - } - } - } - - suspend fun readOnModeAttribute(): OnModeAttribute { - val ATTRIBUTE_ID: UInt = 3u - - val attributePath = - AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - - val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - - val response = controller.read(readRequest) - - if (response.successes.isEmpty()) { - logger.log(Level.WARNING, "Read command failed") - throw IllegalStateException("Read command failed with failures: ${response.failures}") - } - - logger.log(Level.FINE, "Read command succeeded") - - val attributeData = - response.successes.filterIsInstance().firstOrNull { - it.path.attributeId == ATTRIBUTE_ID - } - - requireNotNull(attributeData) { "Onmode attribute not found in response" } - - // Decode the TLV data into the appropriate type - val tlvReader = TlvReader(attributeData.data) - val decodedValue: UByte? = - if (!tlvReader.isNull()) { - if (tlvReader.isNextTag(AnonymousTag)) { - tlvReader.getUByte(AnonymousTag) - } else { - null - } - } else { - tlvReader.getNull(AnonymousTag) - null - } - - return OnModeAttribute(decodedValue) - } - - suspend fun writeOnModeAttribute(value: UByte, timedWriteTimeout: Duration? = null) { - val ATTRIBUTE_ID: UInt = 3u - - val tlvWriter = TlvWriter() - tlvWriter.put(AnonymousTag, value) - - val writeRequests: WriteRequests = - WriteRequests( - requests = - listOf( - WriteRequest( - attributePath = - AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), - tlvPayload = tlvWriter.getEncoded(), - ) - ), - timedRequest = timedWriteTimeout, - ) - - val response: WriteResponse = controller.write(writeRequests) - - when (response) { - is WriteResponse.Success -> { - logger.log(Level.FINE, "Write command succeeded") - } - is WriteResponse.PartialWriteFailure -> { - val aggregatedErrorMessage = - response.failures.joinToString("\n") { failure -> - "Error at ${failure.attributePath}: ${failure.ex.message}" - } - - response.failures.forEach { failure -> - logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") - } - - throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") - } - } - } - - suspend fun subscribeOnModeAttribute( - minInterval: Int, - maxInterval: Int, - ): Flow { - val ATTRIBUTE_ID: UInt = 3u - val attributePaths = - listOf( - AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - ) - - val subscribeRequest: SubscribeRequest = - SubscribeRequest( - eventPaths = emptyList(), - attributePaths = attributePaths, - minInterval = Duration.ofSeconds(minInterval.toLong()), - maxInterval = Duration.ofSeconds(maxInterval.toLong()), - ) - - return controller.subscribe(subscribeRequest).transform { subscriptionState -> - when (subscriptionState) { - is SubscriptionState.SubscriptionErrorNotification -> { - emit( - OnModeAttributeSubscriptionState.Error( - Exception( - "Subscription terminated with error code: ${subscriptionState.terminationCause}" - ) - ) - ) - } - is SubscriptionState.NodeStateUpdate -> { - val attributeData = - subscriptionState.updateState.successes - .filterIsInstance() - .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } - - requireNotNull(attributeData) { "Onmode attribute not found in Node State update" } - - // Decode the TLV data into the appropriate type - val tlvReader = TlvReader(attributeData.data) - val decodedValue: UByte? = - if (!tlvReader.isNull()) { - if (tlvReader.isNextTag(AnonymousTag)) { - tlvReader.getUByte(AnonymousTag) - } else { - null - } - } else { - tlvReader.getNull(AnonymousTag) - null - } - - decodedValue?.let { emit(OnModeAttributeSubscriptionState.Success(it)) } - } - SubscriptionState.SubscriptionEstablished -> { - emit(OnModeAttributeSubscriptionState.SubscriptionEstablished) - } - } - } - } - suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { val ATTRIBUTE_ID: UInt = 65528u diff --git a/src/controller/java/generated/java/matter/controller/cluster/clusters/EnergyEvseModeCluster.kt b/src/controller/java/generated/java/matter/controller/cluster/clusters/EnergyEvseModeCluster.kt index a854ec8d1f71b4..00baf3ce4a4173 100644 --- a/src/controller/java/generated/java/matter/controller/cluster/clusters/EnergyEvseModeCluster.kt +++ b/src/controller/java/generated/java/matter/controller/cluster/clusters/EnergyEvseModeCluster.kt @@ -32,9 +32,6 @@ import matter.controller.SubscriptionState import matter.controller.UByteSubscriptionState import matter.controller.UIntSubscriptionState import matter.controller.UShortSubscriptionState -import matter.controller.WriteRequest -import matter.controller.WriteRequests -import matter.controller.WriteResponse import matter.controller.cluster.structs.* import matter.controller.model.AttributePath import matter.controller.model.CommandPath @@ -60,26 +57,6 @@ class EnergyEvseModeCluster( object SubscriptionEstablished : SupportedModesAttributeSubscriptionState() } - class StartUpModeAttribute(val value: UByte?) - - sealed class StartUpModeAttributeSubscriptionState { - data class Success(val value: UByte?) : StartUpModeAttributeSubscriptionState() - - data class Error(val exception: Exception) : StartUpModeAttributeSubscriptionState() - - object SubscriptionEstablished : StartUpModeAttributeSubscriptionState() - } - - class OnModeAttribute(val value: UByte?) - - sealed class OnModeAttributeSubscriptionState { - data class Success(val value: UByte?) : OnModeAttributeSubscriptionState() - - data class Error(val exception: Exception) : OnModeAttributeSubscriptionState() - - object SubscriptionEstablished : OnModeAttributeSubscriptionState() - } - class GeneratedCommandListAttribute(val value: List) sealed class GeneratedCommandListAttributeSubscriptionState { @@ -362,288 +339,6 @@ class EnergyEvseModeCluster( } } - suspend fun readStartUpModeAttribute(): StartUpModeAttribute { - val ATTRIBUTE_ID: UInt = 2u - - val attributePath = - AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - - val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - - val response = controller.read(readRequest) - - if (response.successes.isEmpty()) { - logger.log(Level.WARNING, "Read command failed") - throw IllegalStateException("Read command failed with failures: ${response.failures}") - } - - logger.log(Level.FINE, "Read command succeeded") - - val attributeData = - response.successes.filterIsInstance().firstOrNull { - it.path.attributeId == ATTRIBUTE_ID - } - - requireNotNull(attributeData) { "Startupmode attribute not found in response" } - - // Decode the TLV data into the appropriate type - val tlvReader = TlvReader(attributeData.data) - val decodedValue: UByte? = - if (!tlvReader.isNull()) { - if (tlvReader.isNextTag(AnonymousTag)) { - tlvReader.getUByte(AnonymousTag) - } else { - null - } - } else { - tlvReader.getNull(AnonymousTag) - null - } - - return StartUpModeAttribute(decodedValue) - } - - suspend fun writeStartUpModeAttribute(value: UByte, timedWriteTimeout: Duration? = null) { - val ATTRIBUTE_ID: UInt = 2u - - val tlvWriter = TlvWriter() - tlvWriter.put(AnonymousTag, value) - - val writeRequests: WriteRequests = - WriteRequests( - requests = - listOf( - WriteRequest( - attributePath = - AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), - tlvPayload = tlvWriter.getEncoded(), - ) - ), - timedRequest = timedWriteTimeout, - ) - - val response: WriteResponse = controller.write(writeRequests) - - when (response) { - is WriteResponse.Success -> { - logger.log(Level.FINE, "Write command succeeded") - } - is WriteResponse.PartialWriteFailure -> { - val aggregatedErrorMessage = - response.failures.joinToString("\n") { failure -> - "Error at ${failure.attributePath}: ${failure.ex.message}" - } - - response.failures.forEach { failure -> - logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") - } - - throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") - } - } - } - - suspend fun subscribeStartUpModeAttribute( - minInterval: Int, - maxInterval: Int, - ): Flow { - val ATTRIBUTE_ID: UInt = 2u - val attributePaths = - listOf( - AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - ) - - val subscribeRequest: SubscribeRequest = - SubscribeRequest( - eventPaths = emptyList(), - attributePaths = attributePaths, - minInterval = Duration.ofSeconds(minInterval.toLong()), - maxInterval = Duration.ofSeconds(maxInterval.toLong()), - ) - - return controller.subscribe(subscribeRequest).transform { subscriptionState -> - when (subscriptionState) { - is SubscriptionState.SubscriptionErrorNotification -> { - emit( - StartUpModeAttributeSubscriptionState.Error( - Exception( - "Subscription terminated with error code: ${subscriptionState.terminationCause}" - ) - ) - ) - } - is SubscriptionState.NodeStateUpdate -> { - val attributeData = - subscriptionState.updateState.successes - .filterIsInstance() - .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } - - requireNotNull(attributeData) { "Startupmode attribute not found in Node State update" } - - // Decode the TLV data into the appropriate type - val tlvReader = TlvReader(attributeData.data) - val decodedValue: UByte? = - if (!tlvReader.isNull()) { - if (tlvReader.isNextTag(AnonymousTag)) { - tlvReader.getUByte(AnonymousTag) - } else { - null - } - } else { - tlvReader.getNull(AnonymousTag) - null - } - - decodedValue?.let { emit(StartUpModeAttributeSubscriptionState.Success(it)) } - } - SubscriptionState.SubscriptionEstablished -> { - emit(StartUpModeAttributeSubscriptionState.SubscriptionEstablished) - } - } - } - } - - suspend fun readOnModeAttribute(): OnModeAttribute { - val ATTRIBUTE_ID: UInt = 3u - - val attributePath = - AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - - val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - - val response = controller.read(readRequest) - - if (response.successes.isEmpty()) { - logger.log(Level.WARNING, "Read command failed") - throw IllegalStateException("Read command failed with failures: ${response.failures}") - } - - logger.log(Level.FINE, "Read command succeeded") - - val attributeData = - response.successes.filterIsInstance().firstOrNull { - it.path.attributeId == ATTRIBUTE_ID - } - - requireNotNull(attributeData) { "Onmode attribute not found in response" } - - // Decode the TLV data into the appropriate type - val tlvReader = TlvReader(attributeData.data) - val decodedValue: UByte? = - if (!tlvReader.isNull()) { - if (tlvReader.isNextTag(AnonymousTag)) { - tlvReader.getUByte(AnonymousTag) - } else { - null - } - } else { - tlvReader.getNull(AnonymousTag) - null - } - - return OnModeAttribute(decodedValue) - } - - suspend fun writeOnModeAttribute(value: UByte, timedWriteTimeout: Duration? = null) { - val ATTRIBUTE_ID: UInt = 3u - - val tlvWriter = TlvWriter() - tlvWriter.put(AnonymousTag, value) - - val writeRequests: WriteRequests = - WriteRequests( - requests = - listOf( - WriteRequest( - attributePath = - AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), - tlvPayload = tlvWriter.getEncoded(), - ) - ), - timedRequest = timedWriteTimeout, - ) - - val response: WriteResponse = controller.write(writeRequests) - - when (response) { - is WriteResponse.Success -> { - logger.log(Level.FINE, "Write command succeeded") - } - is WriteResponse.PartialWriteFailure -> { - val aggregatedErrorMessage = - response.failures.joinToString("\n") { failure -> - "Error at ${failure.attributePath}: ${failure.ex.message}" - } - - response.failures.forEach { failure -> - logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") - } - - throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") - } - } - } - - suspend fun subscribeOnModeAttribute( - minInterval: Int, - maxInterval: Int, - ): Flow { - val ATTRIBUTE_ID: UInt = 3u - val attributePaths = - listOf( - AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - ) - - val subscribeRequest: SubscribeRequest = - SubscribeRequest( - eventPaths = emptyList(), - attributePaths = attributePaths, - minInterval = Duration.ofSeconds(minInterval.toLong()), - maxInterval = Duration.ofSeconds(maxInterval.toLong()), - ) - - return controller.subscribe(subscribeRequest).transform { subscriptionState -> - when (subscriptionState) { - is SubscriptionState.SubscriptionErrorNotification -> { - emit( - OnModeAttributeSubscriptionState.Error( - Exception( - "Subscription terminated with error code: ${subscriptionState.terminationCause}" - ) - ) - ) - } - is SubscriptionState.NodeStateUpdate -> { - val attributeData = - subscriptionState.updateState.successes - .filterIsInstance() - .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } - - requireNotNull(attributeData) { "Onmode attribute not found in Node State update" } - - // Decode the TLV data into the appropriate type - val tlvReader = TlvReader(attributeData.data) - val decodedValue: UByte? = - if (!tlvReader.isNull()) { - if (tlvReader.isNextTag(AnonymousTag)) { - tlvReader.getUByte(AnonymousTag) - } else { - null - } - } else { - tlvReader.getNull(AnonymousTag) - null - } - - decodedValue?.let { emit(OnModeAttributeSubscriptionState.Success(it)) } - } - SubscriptionState.SubscriptionEstablished -> { - emit(OnModeAttributeSubscriptionState.SubscriptionEstablished) - } - } - } - } - suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { val ATTRIBUTE_ID: UInt = 65528u diff --git a/src/controller/java/generated/java/matter/controller/cluster/clusters/WaterHeaterModeCluster.kt b/src/controller/java/generated/java/matter/controller/cluster/clusters/WaterHeaterModeCluster.kt index 27352644935c8a..d2bc5094fe12a9 100644 --- a/src/controller/java/generated/java/matter/controller/cluster/clusters/WaterHeaterModeCluster.kt +++ b/src/controller/java/generated/java/matter/controller/cluster/clusters/WaterHeaterModeCluster.kt @@ -32,9 +32,6 @@ import matter.controller.SubscriptionState import matter.controller.UByteSubscriptionState import matter.controller.UIntSubscriptionState import matter.controller.UShortSubscriptionState -import matter.controller.WriteRequest -import matter.controller.WriteRequests -import matter.controller.WriteResponse import matter.controller.cluster.structs.* import matter.controller.model.AttributePath import matter.controller.model.CommandPath @@ -60,26 +57,6 @@ class WaterHeaterModeCluster( object SubscriptionEstablished : SupportedModesAttributeSubscriptionState() } - class StartUpModeAttribute(val value: UByte?) - - sealed class StartUpModeAttributeSubscriptionState { - data class Success(val value: UByte?) : StartUpModeAttributeSubscriptionState() - - data class Error(val exception: Exception) : StartUpModeAttributeSubscriptionState() - - object SubscriptionEstablished : StartUpModeAttributeSubscriptionState() - } - - class OnModeAttribute(val value: UByte?) - - sealed class OnModeAttributeSubscriptionState { - data class Success(val value: UByte?) : OnModeAttributeSubscriptionState() - - data class Error(val exception: Exception) : OnModeAttributeSubscriptionState() - - object SubscriptionEstablished : OnModeAttributeSubscriptionState() - } - class GeneratedCommandListAttribute(val value: List) sealed class GeneratedCommandListAttributeSubscriptionState { @@ -362,288 +339,6 @@ class WaterHeaterModeCluster( } } - suspend fun readStartUpModeAttribute(): StartUpModeAttribute { - val ATTRIBUTE_ID: UInt = 2u - - val attributePath = - AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - - val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - - val response = controller.read(readRequest) - - if (response.successes.isEmpty()) { - logger.log(Level.WARNING, "Read command failed") - throw IllegalStateException("Read command failed with failures: ${response.failures}") - } - - logger.log(Level.FINE, "Read command succeeded") - - val attributeData = - response.successes.filterIsInstance().firstOrNull { - it.path.attributeId == ATTRIBUTE_ID - } - - requireNotNull(attributeData) { "Startupmode attribute not found in response" } - - // Decode the TLV data into the appropriate type - val tlvReader = TlvReader(attributeData.data) - val decodedValue: UByte? = - if (!tlvReader.isNull()) { - if (tlvReader.isNextTag(AnonymousTag)) { - tlvReader.getUByte(AnonymousTag) - } else { - null - } - } else { - tlvReader.getNull(AnonymousTag) - null - } - - return StartUpModeAttribute(decodedValue) - } - - suspend fun writeStartUpModeAttribute(value: UByte, timedWriteTimeout: Duration? = null) { - val ATTRIBUTE_ID: UInt = 2u - - val tlvWriter = TlvWriter() - tlvWriter.put(AnonymousTag, value) - - val writeRequests: WriteRequests = - WriteRequests( - requests = - listOf( - WriteRequest( - attributePath = - AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), - tlvPayload = tlvWriter.getEncoded(), - ) - ), - timedRequest = timedWriteTimeout, - ) - - val response: WriteResponse = controller.write(writeRequests) - - when (response) { - is WriteResponse.Success -> { - logger.log(Level.FINE, "Write command succeeded") - } - is WriteResponse.PartialWriteFailure -> { - val aggregatedErrorMessage = - response.failures.joinToString("\n") { failure -> - "Error at ${failure.attributePath}: ${failure.ex.message}" - } - - response.failures.forEach { failure -> - logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") - } - - throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") - } - } - } - - suspend fun subscribeStartUpModeAttribute( - minInterval: Int, - maxInterval: Int, - ): Flow { - val ATTRIBUTE_ID: UInt = 2u - val attributePaths = - listOf( - AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - ) - - val subscribeRequest: SubscribeRequest = - SubscribeRequest( - eventPaths = emptyList(), - attributePaths = attributePaths, - minInterval = Duration.ofSeconds(minInterval.toLong()), - maxInterval = Duration.ofSeconds(maxInterval.toLong()), - ) - - return controller.subscribe(subscribeRequest).transform { subscriptionState -> - when (subscriptionState) { - is SubscriptionState.SubscriptionErrorNotification -> { - emit( - StartUpModeAttributeSubscriptionState.Error( - Exception( - "Subscription terminated with error code: ${subscriptionState.terminationCause}" - ) - ) - ) - } - is SubscriptionState.NodeStateUpdate -> { - val attributeData = - subscriptionState.updateState.successes - .filterIsInstance() - .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } - - requireNotNull(attributeData) { "Startupmode attribute not found in Node State update" } - - // Decode the TLV data into the appropriate type - val tlvReader = TlvReader(attributeData.data) - val decodedValue: UByte? = - if (!tlvReader.isNull()) { - if (tlvReader.isNextTag(AnonymousTag)) { - tlvReader.getUByte(AnonymousTag) - } else { - null - } - } else { - tlvReader.getNull(AnonymousTag) - null - } - - decodedValue?.let { emit(StartUpModeAttributeSubscriptionState.Success(it)) } - } - SubscriptionState.SubscriptionEstablished -> { - emit(StartUpModeAttributeSubscriptionState.SubscriptionEstablished) - } - } - } - } - - suspend fun readOnModeAttribute(): OnModeAttribute { - val ATTRIBUTE_ID: UInt = 3u - - val attributePath = - AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - - val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) - - val response = controller.read(readRequest) - - if (response.successes.isEmpty()) { - logger.log(Level.WARNING, "Read command failed") - throw IllegalStateException("Read command failed with failures: ${response.failures}") - } - - logger.log(Level.FINE, "Read command succeeded") - - val attributeData = - response.successes.filterIsInstance().firstOrNull { - it.path.attributeId == ATTRIBUTE_ID - } - - requireNotNull(attributeData) { "Onmode attribute not found in response" } - - // Decode the TLV data into the appropriate type - val tlvReader = TlvReader(attributeData.data) - val decodedValue: UByte? = - if (!tlvReader.isNull()) { - if (tlvReader.isNextTag(AnonymousTag)) { - tlvReader.getUByte(AnonymousTag) - } else { - null - } - } else { - tlvReader.getNull(AnonymousTag) - null - } - - return OnModeAttribute(decodedValue) - } - - suspend fun writeOnModeAttribute(value: UByte, timedWriteTimeout: Duration? = null) { - val ATTRIBUTE_ID: UInt = 3u - - val tlvWriter = TlvWriter() - tlvWriter.put(AnonymousTag, value) - - val writeRequests: WriteRequests = - WriteRequests( - requests = - listOf( - WriteRequest( - attributePath = - AttributePath(endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID), - tlvPayload = tlvWriter.getEncoded(), - ) - ), - timedRequest = timedWriteTimeout, - ) - - val response: WriteResponse = controller.write(writeRequests) - - when (response) { - is WriteResponse.Success -> { - logger.log(Level.FINE, "Write command succeeded") - } - is WriteResponse.PartialWriteFailure -> { - val aggregatedErrorMessage = - response.failures.joinToString("\n") { failure -> - "Error at ${failure.attributePath}: ${failure.ex.message}" - } - - response.failures.forEach { failure -> - logger.log(Level.WARNING, "Error at ${failure.attributePath}: ${failure.ex.message}") - } - - throw IllegalStateException("Write command failed with errors: \n$aggregatedErrorMessage") - } - } - } - - suspend fun subscribeOnModeAttribute( - minInterval: Int, - maxInterval: Int, - ): Flow { - val ATTRIBUTE_ID: UInt = 3u - val attributePaths = - listOf( - AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) - ) - - val subscribeRequest: SubscribeRequest = - SubscribeRequest( - eventPaths = emptyList(), - attributePaths = attributePaths, - minInterval = Duration.ofSeconds(minInterval.toLong()), - maxInterval = Duration.ofSeconds(maxInterval.toLong()), - ) - - return controller.subscribe(subscribeRequest).transform { subscriptionState -> - when (subscriptionState) { - is SubscriptionState.SubscriptionErrorNotification -> { - emit( - OnModeAttributeSubscriptionState.Error( - Exception( - "Subscription terminated with error code: ${subscriptionState.terminationCause}" - ) - ) - ) - } - is SubscriptionState.NodeStateUpdate -> { - val attributeData = - subscriptionState.updateState.successes - .filterIsInstance() - .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } - - requireNotNull(attributeData) { "Onmode attribute not found in Node State update" } - - // Decode the TLV data into the appropriate type - val tlvReader = TlvReader(attributeData.data) - val decodedValue: UByte? = - if (!tlvReader.isNull()) { - if (tlvReader.isNextTag(AnonymousTag)) { - tlvReader.getUByte(AnonymousTag) - } else { - null - } - } else { - tlvReader.getNull(AnonymousTag) - null - } - - decodedValue?.let { emit(OnModeAttributeSubscriptionState.Success(it)) } - } - SubscriptionState.SubscriptionEstablished -> { - emit(OnModeAttributeSubscriptionState.SubscriptionEstablished) - } - } - } - } - suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { val ATTRIBUTE_ID: UInt = 65528u diff --git a/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp b/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp index 905347e73f92d8..972cc32e536787 100644 --- a/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp +++ b/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp @@ -25877,52 +25877,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR value); return value; } - case Attributes::StartUpMode::Id: { - using TypeInfo = Attributes::StartUpMode::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - if (cppValue.IsNull()) - { - value = nullptr; - } - else - { - std::string valueClassName = "java/lang/Integer"; - std::string valueCtorSignature = "(I)V"; - jint jnivalue = static_cast(cppValue.Value()); - chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), - jnivalue, value); - } - return value; - } - case Attributes::OnMode::Id: { - using TypeInfo = Attributes::OnMode::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - if (cppValue.IsNull()) - { - value = nullptr; - } - else - { - std::string valueClassName = "java/lang/Integer"; - std::string valueCtorSignature = "(I)V"; - jint jnivalue = static_cast(cppValue.Value()); - chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), - jnivalue, value); - } - return value; - } case Attributes::GeneratedCommandList::Id: { using TypeInfo = Attributes::GeneratedCommandList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -26194,52 +26148,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR value); return value; } - case Attributes::StartUpMode::Id: { - using TypeInfo = Attributes::StartUpMode::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - if (cppValue.IsNull()) - { - value = nullptr; - } - else - { - std::string valueClassName = "java/lang/Integer"; - std::string valueCtorSignature = "(I)V"; - jint jnivalue = static_cast(cppValue.Value()); - chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), - jnivalue, value); - } - return value; - } - case Attributes::OnMode::Id: { - using TypeInfo = Attributes::OnMode::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - if (cppValue.IsNull()) - { - value = nullptr; - } - else - { - std::string valueClassName = "java/lang/Integer"; - std::string valueCtorSignature = "(I)V"; - jint jnivalue = static_cast(cppValue.Value()); - chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), - jnivalue, value); - } - return value; - } case Attributes::GeneratedCommandList::Id: { using TypeInfo = Attributes::GeneratedCommandList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -26513,52 +26421,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR value); return value; } - case Attributes::StartUpMode::Id: { - using TypeInfo = Attributes::StartUpMode::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - if (cppValue.IsNull()) - { - value = nullptr; - } - else - { - std::string valueClassName = "java/lang/Integer"; - std::string valueCtorSignature = "(I)V"; - jint jnivalue = static_cast(cppValue.Value()); - chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), - jnivalue, value); - } - return value; - } - case Attributes::OnMode::Id: { - using TypeInfo = Attributes::OnMode::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - if (cppValue.IsNull()) - { - value = nullptr; - } - else - { - std::string valueClassName = "java/lang/Integer"; - std::string valueCtorSignature = "(I)V"; - jint jnivalue = static_cast(cppValue.Value()); - chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), - jnivalue, value); - } - return value; - } case Attributes::GeneratedCommandList::Id: { using TypeInfo = Attributes::GeneratedCommandList::TypeInfo; TypeInfo::DecodableType cppValue; diff --git a/src/controller/python/chip/clusters/CHIPClusters.py b/src/controller/python/chip/clusters/CHIPClusters.py index a3b2a05cb67553..7bc1cb66b4a9c4 100644 --- a/src/controller/python/chip/clusters/CHIPClusters.py +++ b/src/controller/python/chip/clusters/CHIPClusters.py @@ -7336,20 +7336,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x00000002: { - "attributeName": "StartUpMode", - "attributeId": 0x00000002, - "type": "int", - "reportable": True, - "writable": True, - }, - 0x00000003: { - "attributeName": "OnMode", - "attributeId": 0x00000003, - "type": "int", - "reportable": True, - "writable": True, - }, 0x0000FFF8: { "attributeName": "GeneratedCommandList", "attributeId": 0x0000FFF8, @@ -7413,20 +7399,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x00000002: { - "attributeName": "StartUpMode", - "attributeId": 0x00000002, - "type": "int", - "reportable": True, - "writable": True, - }, - 0x00000003: { - "attributeName": "OnMode", - "attributeId": 0x00000003, - "type": "int", - "reportable": True, - "writable": True, - }, 0x0000FFF8: { "attributeName": "GeneratedCommandList", "attributeId": 0x0000FFF8, @@ -7490,20 +7462,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x00000002: { - "attributeName": "StartUpMode", - "attributeId": 0x00000002, - "type": "int", - "reportable": True, - "writable": True, - }, - 0x00000003: { - "attributeName": "OnMode", - "attributeId": 0x00000003, - "type": "int", - "reportable": True, - "writable": True, - }, 0x0000FFF8: { "attributeName": "GeneratedCommandList", "attributeId": 0x0000FFF8, diff --git a/src/controller/python/chip/clusters/Objects.py b/src/controller/python/chip/clusters/Objects.py index 076dc946e39898..e6e74717dc739a 100644 --- a/src/controller/python/chip/clusters/Objects.py +++ b/src/controller/python/chip/clusters/Objects.py @@ -27020,8 +27020,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: Fields=[ ClusterObjectFieldDescriptor(Label="supportedModes", Tag=0x00000000, Type=typing.List[EnergyEvseMode.Structs.ModeOptionStruct]), ClusterObjectFieldDescriptor(Label="currentMode", Tag=0x00000001, Type=uint), - ClusterObjectFieldDescriptor(Label="startUpMode", Tag=0x00000002, Type=typing.Union[None, Nullable, uint]), - ClusterObjectFieldDescriptor(Label="onMode", Tag=0x00000003, Type=typing.Union[None, Nullable, uint]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), @@ -27032,8 +27030,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: supportedModes: typing.List[EnergyEvseMode.Structs.ModeOptionStruct] = field(default_factory=lambda: []) currentMode: uint = 0 - startUpMode: typing.Union[None, Nullable, uint] = None - onMode: typing.Union[None, Nullable, uint] = None generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) eventList: typing.List[uint] = field(default_factory=lambda: []) @@ -27056,6 +27052,7 @@ class ModeTag(MatterIntEnum): kManual = 0x4000 kTimeOfUse = 0x4001 kSolarCharging = 0x4002 + kV2x = 0x4003 # kUnknownEnumValue intentionally not defined. This enum never goes # through DataModel::Decode, likely because it is a part of a derived # cluster. As a result having kUnknownEnumValue in this enum is error @@ -27163,38 +27160,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: uint = 0 - @dataclass - class StartUpMode(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x0000009D - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x00000002 - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - - value: typing.Union[None, Nullable, uint] = None - - @dataclass - class OnMode(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x0000009D - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x00000003 - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - - value: typing.Union[None, Nullable, uint] = None - @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -27302,8 +27267,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: Fields=[ ClusterObjectFieldDescriptor(Label="supportedModes", Tag=0x00000000, Type=typing.List[WaterHeaterMode.Structs.ModeOptionStruct]), ClusterObjectFieldDescriptor(Label="currentMode", Tag=0x00000001, Type=uint), - ClusterObjectFieldDescriptor(Label="startUpMode", Tag=0x00000002, Type=typing.Union[None, Nullable, uint]), - ClusterObjectFieldDescriptor(Label="onMode", Tag=0x00000003, Type=typing.Union[None, Nullable, uint]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), @@ -27314,8 +27277,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: supportedModes: typing.List[WaterHeaterMode.Structs.ModeOptionStruct] = field(default_factory=lambda: []) currentMode: uint = 0 - startUpMode: typing.Union[None, Nullable, uint] = None - onMode: typing.Union[None, Nullable, uint] = None generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) eventList: typing.List[uint] = field(default_factory=lambda: []) @@ -27445,38 +27406,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: uint = 0 - @dataclass - class StartUpMode(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x0000009E - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x00000002 - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - - value: typing.Union[None, Nullable, uint] = None - - @dataclass - class OnMode(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x0000009E - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x00000003 - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - - value: typing.Union[None, Nullable, uint] = None - @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -27584,8 +27513,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: Fields=[ ClusterObjectFieldDescriptor(Label="supportedModes", Tag=0x00000000, Type=typing.List[DeviceEnergyManagementMode.Structs.ModeOptionStruct]), ClusterObjectFieldDescriptor(Label="currentMode", Tag=0x00000001, Type=uint), - ClusterObjectFieldDescriptor(Label="startUpMode", Tag=0x00000002, Type=typing.Union[None, Nullable, uint]), - ClusterObjectFieldDescriptor(Label="onMode", Tag=0x00000003, Type=typing.Union[None, Nullable, uint]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), @@ -27596,8 +27523,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: supportedModes: typing.List[DeviceEnergyManagementMode.Structs.ModeOptionStruct] = field(default_factory=lambda: []) currentMode: uint = 0 - startUpMode: typing.Union[None, Nullable, uint] = None - onMode: typing.Union[None, Nullable, uint] = None generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) eventList: typing.List[uint] = field(default_factory=lambda: []) @@ -27728,38 +27653,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: uint = 0 - @dataclass - class StartUpMode(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x0000009F - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x00000002 - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - - value: typing.Union[None, Nullable, uint] = None - - @dataclass - class OnMode(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x0000009F - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x00000003 - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.Union[None, Nullable, uint]) - - value: typing.Union[None, Nullable, uint] = None - @dataclass class GeneratedCommandList(ClusterAttributeDescriptor): @ChipUtility.classproperty diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm index 31a1d57e3bc2c3..4f75da11d76b1a 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm @@ -3354,12 +3354,6 @@ static BOOL AttributeIsSpecifiedInEnergyEVSEModeCluster(AttributeId aAttributeId case Attributes::CurrentMode::Id: { return YES; } - case Attributes::StartUpMode::Id: { - return YES; - } - case Attributes::OnMode::Id: { - return YES; - } case Attributes::GeneratedCommandList::Id: { return YES; } @@ -3393,12 +3387,6 @@ static BOOL AttributeIsSpecifiedInWaterHeaterModeCluster(AttributeId aAttributeI case Attributes::CurrentMode::Id: { return YES; } - case Attributes::StartUpMode::Id: { - return YES; - } - case Attributes::OnMode::Id: { - return YES; - } case Attributes::GeneratedCommandList::Id: { return YES; } @@ -3432,12 +3420,6 @@ static BOOL AttributeIsSpecifiedInDeviceEnergyManagementModeCluster(AttributeId case Attributes::CurrentMode::Id: { return YES; } - case Attributes::StartUpMode::Id: { - return YES; - } - case Attributes::OnMode::Id: { - return YES; - } case Attributes::GeneratedCommandList::Id: { return YES; } diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm index 5e6e0486606e6b..b735c0f56c1ea1 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm @@ -9799,36 +9799,6 @@ static id _Nullable DecodeAttributeValueForEnergyEVSEModeCluster(AttributeId aAt value = [NSNumber numberWithUnsignedChar:cppValue]; return value; } - case Attributes::StartUpMode::Id: { - using TypeInfo = Attributes::StartUpMode::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) { - return nil; - } - NSNumber * _Nullable value; - if (cppValue.IsNull()) { - value = nil; - } else { - value = [NSNumber numberWithUnsignedChar:cppValue.Value()]; - } - return value; - } - case Attributes::OnMode::Id: { - using TypeInfo = Attributes::OnMode::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) { - return nil; - } - NSNumber * _Nullable value; - if (cppValue.IsNull()) { - value = nil; - } else { - value = [NSNumber numberWithUnsignedChar:cppValue.Value()]; - } - return value; - } default: { break; } @@ -9907,36 +9877,6 @@ static id _Nullable DecodeAttributeValueForWaterHeaterModeCluster(AttributeId aA value = [NSNumber numberWithUnsignedChar:cppValue]; return value; } - case Attributes::StartUpMode::Id: { - using TypeInfo = Attributes::StartUpMode::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) { - return nil; - } - NSNumber * _Nullable value; - if (cppValue.IsNull()) { - value = nil; - } else { - value = [NSNumber numberWithUnsignedChar:cppValue.Value()]; - } - return value; - } - case Attributes::OnMode::Id: { - using TypeInfo = Attributes::OnMode::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) { - return nil; - } - NSNumber * _Nullable value; - if (cppValue.IsNull()) { - value = nil; - } else { - value = [NSNumber numberWithUnsignedChar:cppValue.Value()]; - } - return value; - } default: { break; } @@ -10015,36 +9955,6 @@ static id _Nullable DecodeAttributeValueForDeviceEnergyManagementModeCluster(Att value = [NSNumber numberWithUnsignedChar:cppValue]; return value; } - case Attributes::StartUpMode::Id: { - using TypeInfo = Attributes::StartUpMode::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) { - return nil; - } - NSNumber * _Nullable value; - if (cppValue.IsNull()) { - value = nil; - } else { - value = [NSNumber numberWithUnsignedChar:cppValue.Value()]; - } - return value; - } - case Attributes::OnMode::Id: { - using TypeInfo = Attributes::OnMode::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) { - return nil; - } - NSNumber * _Nullable value; - if (cppValue.IsNull()) { - value = nil; - } else { - value = [NSNumber numberWithUnsignedChar:cppValue.Value()]; - } - return value; - } default: { break; } diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h index bba11808021618..eda0c7b5a06431 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h @@ -7775,7 +7775,7 @@ MTR_PROVISIONALLY_AVAILABLE /** * Command CancelRequest * - * Allows a client to request cancellation of a previous adjustment request in a StartTimeAdjustRequest, ModifyForecastRequest or RequestConstraintBasedForecast command + * Allows a client to request cancellation of a previous adjustment request in a StartTimeAdjustRequest, ModifyForecastRequest or RequestConstraintBasedForecast command. */ - (void)cancelRequestWithParams:(MTRDeviceEnergyManagementClusterCancelRequestParams * _Nullable)params completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; - (void)cancelRequestWithCompletion:(MTRStatusCompletion)completion @@ -7901,13 +7901,13 @@ MTR_PROVISIONALLY_AVAILABLE /** * Command EnableCharging * - * This command allows a client to enable the EVSE to charge an EV, + * This command allows a client to enable the EVSE to charge an EV, and to provide or update the maximum and minimum charge current. */ - (void)enableChargingWithParams:(MTREnergyEVSEClusterEnableChargingParams *)params completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; /** * Command EnableDischarging * - * Upon receipt, this SHALL allow a client to enable the discharge of an EV, + * Upon receipt, this SHALL allow a client to enable the discharge of an EV, and to provide or update the maximum discharge current. */ - (void)enableDischargingWithParams:(MTREnergyEVSEClusterEnableDischargingParams *)params completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; /** @@ -8318,7 +8318,6 @@ MTR_PROVISIONALLY_AVAILABLE * Command ChangeToMode * * This command is used to change device modes. - On receipt of this command the device SHALL respond with a ChangeToModeResponse command. */ - (void)changeToModeWithParams:(MTREnergyEVSEModeClusterChangeToModeParams *)params completion:(void (^)(MTREnergyEVSEModeClusterChangeToModeResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; @@ -8334,22 +8333,6 @@ MTR_PROVISIONALLY_AVAILABLE reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; + (void)readAttributeCurrentModeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)readAttributeStartUpModeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)writeAttributeStartUpModeWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; -- (void)writeAttributeStartUpModeWithValue:(NSNumber * _Nullable)value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeStartUpModeWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeStartUpModeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - -- (void)readAttributeOnModeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)writeAttributeOnModeWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; -- (void)writeAttributeOnModeWithValue:(NSNumber * _Nullable)value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeOnModeWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeOnModeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -8415,7 +8398,6 @@ MTR_PROVISIONALLY_AVAILABLE * Command ChangeToMode * * This command is used to change device modes. - On receipt of this command the device SHALL respond with a ChangeToModeResponse command. */ - (void)changeToModeWithParams:(MTRWaterHeaterModeClusterChangeToModeParams *)params completion:(void (^)(MTRWaterHeaterModeClusterChangeToModeResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; @@ -8431,22 +8413,6 @@ MTR_PROVISIONALLY_AVAILABLE reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; + (void)readAttributeCurrentModeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)readAttributeStartUpModeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)writeAttributeStartUpModeWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; -- (void)writeAttributeStartUpModeWithValue:(NSNumber * _Nullable)value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeStartUpModeWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeStartUpModeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - -- (void)readAttributeOnModeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)writeAttributeOnModeWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; -- (void)writeAttributeOnModeWithValue:(NSNumber * _Nullable)value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeOnModeWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeOnModeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -8512,7 +8478,6 @@ MTR_PROVISIONALLY_AVAILABLE * Command ChangeToMode * * This command is used to change device modes. - On receipt of this command the device SHALL respond with a ChangeToModeResponse command. */ - (void)changeToModeWithParams:(MTRDeviceEnergyManagementModeClusterChangeToModeParams *)params completion:(void (^)(MTRDeviceEnergyManagementModeClusterChangeToModeResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; @@ -8528,22 +8493,6 @@ MTR_PROVISIONALLY_AVAILABLE reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; + (void)readAttributeCurrentModeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)readAttributeStartUpModeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)writeAttributeStartUpModeWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; -- (void)writeAttributeStartUpModeWithValue:(NSNumber * _Nullable)value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeStartUpModeWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeStartUpModeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - -- (void)readAttributeOnModeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)writeAttributeOnModeWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; -- (void)writeAttributeOnModeWithValue:(NSNumber * _Nullable)value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeOnModeWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeOnModeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -18962,6 +18911,7 @@ typedef NS_ENUM(uint16_t, MTREnergyEVSEModeModeTag) { MTREnergyEVSEModeModeTagManual MTR_PROVISIONALLY_AVAILABLE = 0x4000, MTREnergyEVSEModeModeTagTimeOfUse MTR_PROVISIONALLY_AVAILABLE = 0x4001, MTREnergyEVSEModeModeTagSolarCharging MTR_PROVISIONALLY_AVAILABLE = 0x4002, + MTREnergyEVSEModeModeTagV2X MTR_PROVISIONALLY_AVAILABLE = 0x4003, } MTR_PROVISIONALLY_AVAILABLE; typedef NS_OPTIONS(uint32_t, MTREnergyEVSEModeFeature) { diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm index cda854f0c80c91..6e2ea748a37766 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm @@ -54060,144 +54060,6 @@ + (void)readAttributeCurrentModeWithClusterStateCache:(MTRClusterStateCacheConta completion:completion]; } -- (void)readAttributeStartUpModeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = EnergyEvseMode::Attributes::StartUpMode::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)writeAttributeStartUpModeWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion -{ - [self writeAttributeStartUpModeWithValue:(NSNumber * _Nullable) value params:nil completion:completion]; -} -- (void)writeAttributeStartUpModeWithValue:(NSNumber * _Nullable)value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion -{ - // Make a copy of params before we go async. - params = [params copy]; - value = [value copy]; - - auto * bridge = new MTRDefaultSuccessCallbackBridge(self.callbackQueue, ^(id _Nullable ignored, NSError * _Nullable error) { completion(error); }, ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb, MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) { - chip::Optional timedWriteTimeout; - if (params != nil) { - if (params.timedWriteTimeout != nil){ - timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue); - } - } - - ListFreer listFreer; - using TypeInfo = EnergyEvseMode::Attributes::StartUpMode::TypeInfo; - TypeInfo::Type cppValue; - if (value == nil) { - cppValue.SetNull(); - } else { - auto & nonNullValue_0 = cppValue.SetNonNull(); - nonNullValue_0 = value.unsignedCharValue; - } - - chip::Controller::ClusterBase cppCluster(exchangeManager, session, self.endpointID.unsignedShortValue); - return cppCluster.WriteAttribute(cppValue, bridge, successCb, failureCb, timedWriteTimeout); }); - std::move(*bridge).DispatchAction(self.device); -} - -- (void)subscribeAttributeStartUpModeWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = EnergyEvseMode::Attributes::StartUpMode::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeStartUpModeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = EnergyEvseMode::Attributes::StartUpMode::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - -- (void)readAttributeOnModeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = EnergyEvseMode::Attributes::OnMode::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)writeAttributeOnModeWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion -{ - [self writeAttributeOnModeWithValue:(NSNumber * _Nullable) value params:nil completion:completion]; -} -- (void)writeAttributeOnModeWithValue:(NSNumber * _Nullable)value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion -{ - // Make a copy of params before we go async. - params = [params copy]; - value = [value copy]; - - auto * bridge = new MTRDefaultSuccessCallbackBridge(self.callbackQueue, ^(id _Nullable ignored, NSError * _Nullable error) { completion(error); }, ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb, MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) { - chip::Optional timedWriteTimeout; - if (params != nil) { - if (params.timedWriteTimeout != nil){ - timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue); - } - } - - ListFreer listFreer; - using TypeInfo = EnergyEvseMode::Attributes::OnMode::TypeInfo; - TypeInfo::Type cppValue; - if (value == nil) { - cppValue.SetNull(); - } else { - auto & nonNullValue_0 = cppValue.SetNonNull(); - nonNullValue_0 = value.unsignedCharValue; - } - - chip::Controller::ClusterBase cppCluster(exchangeManager, session, self.endpointID.unsignedShortValue); - return cppCluster.WriteAttribute(cppValue, bridge, successCb, failureCb, timedWriteTimeout); }); - std::move(*bridge).DispatchAction(self.device); -} - -- (void)subscribeAttributeOnModeWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = EnergyEvseMode::Attributes::OnMode::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeOnModeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = EnergyEvseMode::Attributes::OnMode::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = EnergyEvseMode::Attributes::GeneratedCommandList::TypeInfo; @@ -54515,144 +54377,6 @@ + (void)readAttributeCurrentModeWithClusterStateCache:(MTRClusterStateCacheConta completion:completion]; } -- (void)readAttributeStartUpModeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = WaterHeaterMode::Attributes::StartUpMode::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)writeAttributeStartUpModeWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion -{ - [self writeAttributeStartUpModeWithValue:(NSNumber * _Nullable) value params:nil completion:completion]; -} -- (void)writeAttributeStartUpModeWithValue:(NSNumber * _Nullable)value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion -{ - // Make a copy of params before we go async. - params = [params copy]; - value = [value copy]; - - auto * bridge = new MTRDefaultSuccessCallbackBridge(self.callbackQueue, ^(id _Nullable ignored, NSError * _Nullable error) { completion(error); }, ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb, MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) { - chip::Optional timedWriteTimeout; - if (params != nil) { - if (params.timedWriteTimeout != nil){ - timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue); - } - } - - ListFreer listFreer; - using TypeInfo = WaterHeaterMode::Attributes::StartUpMode::TypeInfo; - TypeInfo::Type cppValue; - if (value == nil) { - cppValue.SetNull(); - } else { - auto & nonNullValue_0 = cppValue.SetNonNull(); - nonNullValue_0 = value.unsignedCharValue; - } - - chip::Controller::ClusterBase cppCluster(exchangeManager, session, self.endpointID.unsignedShortValue); - return cppCluster.WriteAttribute(cppValue, bridge, successCb, failureCb, timedWriteTimeout); }); - std::move(*bridge).DispatchAction(self.device); -} - -- (void)subscribeAttributeStartUpModeWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = WaterHeaterMode::Attributes::StartUpMode::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeStartUpModeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = WaterHeaterMode::Attributes::StartUpMode::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - -- (void)readAttributeOnModeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = WaterHeaterMode::Attributes::OnMode::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)writeAttributeOnModeWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion -{ - [self writeAttributeOnModeWithValue:(NSNumber * _Nullable) value params:nil completion:completion]; -} -- (void)writeAttributeOnModeWithValue:(NSNumber * _Nullable)value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion -{ - // Make a copy of params before we go async. - params = [params copy]; - value = [value copy]; - - auto * bridge = new MTRDefaultSuccessCallbackBridge(self.callbackQueue, ^(id _Nullable ignored, NSError * _Nullable error) { completion(error); }, ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb, MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) { - chip::Optional timedWriteTimeout; - if (params != nil) { - if (params.timedWriteTimeout != nil){ - timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue); - } - } - - ListFreer listFreer; - using TypeInfo = WaterHeaterMode::Attributes::OnMode::TypeInfo; - TypeInfo::Type cppValue; - if (value == nil) { - cppValue.SetNull(); - } else { - auto & nonNullValue_0 = cppValue.SetNonNull(); - nonNullValue_0 = value.unsignedCharValue; - } - - chip::Controller::ClusterBase cppCluster(exchangeManager, session, self.endpointID.unsignedShortValue); - return cppCluster.WriteAttribute(cppValue, bridge, successCb, failureCb, timedWriteTimeout); }); - std::move(*bridge).DispatchAction(self.device); -} - -- (void)subscribeAttributeOnModeWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = WaterHeaterMode::Attributes::OnMode::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeOnModeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = WaterHeaterMode::Attributes::OnMode::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = WaterHeaterMode::Attributes::GeneratedCommandList::TypeInfo; @@ -54970,144 +54694,6 @@ + (void)readAttributeCurrentModeWithClusterStateCache:(MTRClusterStateCacheConta completion:completion]; } -- (void)readAttributeStartUpModeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = DeviceEnergyManagementMode::Attributes::StartUpMode::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)writeAttributeStartUpModeWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion -{ - [self writeAttributeStartUpModeWithValue:(NSNumber * _Nullable) value params:nil completion:completion]; -} -- (void)writeAttributeStartUpModeWithValue:(NSNumber * _Nullable)value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion -{ - // Make a copy of params before we go async. - params = [params copy]; - value = [value copy]; - - auto * bridge = new MTRDefaultSuccessCallbackBridge(self.callbackQueue, ^(id _Nullable ignored, NSError * _Nullable error) { completion(error); }, ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb, MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) { - chip::Optional timedWriteTimeout; - if (params != nil) { - if (params.timedWriteTimeout != nil){ - timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue); - } - } - - ListFreer listFreer; - using TypeInfo = DeviceEnergyManagementMode::Attributes::StartUpMode::TypeInfo; - TypeInfo::Type cppValue; - if (value == nil) { - cppValue.SetNull(); - } else { - auto & nonNullValue_0 = cppValue.SetNonNull(); - nonNullValue_0 = value.unsignedCharValue; - } - - chip::Controller::ClusterBase cppCluster(exchangeManager, session, self.endpointID.unsignedShortValue); - return cppCluster.WriteAttribute(cppValue, bridge, successCb, failureCb, timedWriteTimeout); }); - std::move(*bridge).DispatchAction(self.device); -} - -- (void)subscribeAttributeStartUpModeWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = DeviceEnergyManagementMode::Attributes::StartUpMode::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeStartUpModeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = DeviceEnergyManagementMode::Attributes::StartUpMode::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - -- (void)readAttributeOnModeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = DeviceEnergyManagementMode::Attributes::OnMode::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)writeAttributeOnModeWithValue:(NSNumber * _Nullable)value completion:(MTRStatusCompletion)completion -{ - [self writeAttributeOnModeWithValue:(NSNumber * _Nullable) value params:nil completion:completion]; -} -- (void)writeAttributeOnModeWithValue:(NSNumber * _Nullable)value params:(MTRWriteParams * _Nullable)params completion:(MTRStatusCompletion)completion -{ - // Make a copy of params before we go async. - params = [params copy]; - value = [value copy]; - - auto * bridge = new MTRDefaultSuccessCallbackBridge(self.callbackQueue, ^(id _Nullable ignored, NSError * _Nullable error) { completion(error); }, ^(ExchangeManager & exchangeManager, const SessionHandle & session, DefaultSuccessCallbackType successCb, MTRErrorCallback failureCb, MTRCallbackBridgeBase * bridge) { - chip::Optional timedWriteTimeout; - if (params != nil) { - if (params.timedWriteTimeout != nil){ - timedWriteTimeout.SetValue(params.timedWriteTimeout.unsignedShortValue); - } - } - - ListFreer listFreer; - using TypeInfo = DeviceEnergyManagementMode::Attributes::OnMode::TypeInfo; - TypeInfo::Type cppValue; - if (value == nil) { - cppValue.SetNull(); - } else { - auto & nonNullValue_0 = cppValue.SetNonNull(); - nonNullValue_0 = value.unsignedCharValue; - } - - chip::Controller::ClusterBase cppCluster(exchangeManager, session, self.endpointID.unsignedShortValue); - return cppCluster.WriteAttribute(cppValue, bridge, successCb, failureCb, timedWriteTimeout); }); - std::move(*bridge).DispatchAction(self.device); -} - -- (void)subscribeAttributeOnModeWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = DeviceEnergyManagementMode::Attributes::OnMode::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeOnModeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = DeviceEnergyManagementMode::Attributes::OnMode::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = DeviceEnergyManagementMode::Attributes::GeneratedCommandList::TypeInfo; diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h b/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h index 76d6ab35d3724a..6f9901c3c8dc9a 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h @@ -2662,8 +2662,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { // Cluster EnergyEVSEMode attributes MTRAttributeIDTypeClusterEnergyEVSEModeAttributeSupportedModesID MTR_PROVISIONALLY_AVAILABLE = 0x00000000, MTRAttributeIDTypeClusterEnergyEVSEModeAttributeCurrentModeID MTR_PROVISIONALLY_AVAILABLE = 0x00000001, - MTRAttributeIDTypeClusterEnergyEVSEModeAttributeStartUpModeID MTR_PROVISIONALLY_AVAILABLE = 0x00000002, - MTRAttributeIDTypeClusterEnergyEVSEModeAttributeOnModeID MTR_PROVISIONALLY_AVAILABLE = 0x00000003, MTRAttributeIDTypeClusterEnergyEVSEModeAttributeGeneratedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterEnergyEVSEModeAttributeAcceptedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, MTRAttributeIDTypeClusterEnergyEVSEModeAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, @@ -2674,8 +2672,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { // Cluster WaterHeaterMode attributes MTRAttributeIDTypeClusterWaterHeaterModeAttributeSupportedModesID MTR_PROVISIONALLY_AVAILABLE = 0x00000000, MTRAttributeIDTypeClusterWaterHeaterModeAttributeCurrentModeID MTR_PROVISIONALLY_AVAILABLE = 0x00000001, - MTRAttributeIDTypeClusterWaterHeaterModeAttributeStartUpModeID MTR_PROVISIONALLY_AVAILABLE = 0x00000002, - MTRAttributeIDTypeClusterWaterHeaterModeAttributeOnModeID MTR_PROVISIONALLY_AVAILABLE = 0x00000003, MTRAttributeIDTypeClusterWaterHeaterModeAttributeGeneratedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterWaterHeaterModeAttributeAcceptedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, MTRAttributeIDTypeClusterWaterHeaterModeAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, @@ -2686,8 +2682,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { // Cluster DeviceEnergyManagementMode attributes MTRAttributeIDTypeClusterDeviceEnergyManagementModeAttributeSupportedModesID MTR_PROVISIONALLY_AVAILABLE = 0x00000000, MTRAttributeIDTypeClusterDeviceEnergyManagementModeAttributeCurrentModeID MTR_PROVISIONALLY_AVAILABLE = 0x00000001, - MTRAttributeIDTypeClusterDeviceEnergyManagementModeAttributeStartUpModeID MTR_PROVISIONALLY_AVAILABLE = 0x00000002, - MTRAttributeIDTypeClusterDeviceEnergyManagementModeAttributeOnModeID MTR_PROVISIONALLY_AVAILABLE = 0x00000003, MTRAttributeIDTypeClusterDeviceEnergyManagementModeAttributeGeneratedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterDeviceEnergyManagementModeAttributeAcceptedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, MTRAttributeIDTypeClusterDeviceEnergyManagementModeAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm b/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm index 04f3350f752d8a..1d7ffd3925f51f 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm @@ -4785,14 +4785,6 @@ result = @"CurrentMode"; break; - case MTRAttributeIDTypeClusterEnergyEVSEModeAttributeStartUpModeID: - result = @"StartUpMode"; - break; - - case MTRAttributeIDTypeClusterEnergyEVSEModeAttributeOnModeID: - result = @"OnMode"; - break; - case MTRAttributeIDTypeClusterEnergyEVSEModeAttributeGeneratedCommandListID: result = @"GeneratedCommandList"; break; @@ -4836,14 +4828,6 @@ result = @"CurrentMode"; break; - case MTRAttributeIDTypeClusterWaterHeaterModeAttributeStartUpModeID: - result = @"StartUpMode"; - break; - - case MTRAttributeIDTypeClusterWaterHeaterModeAttributeOnModeID: - result = @"OnMode"; - break; - case MTRAttributeIDTypeClusterWaterHeaterModeAttributeGeneratedCommandListID: result = @"GeneratedCommandList"; break; @@ -4887,14 +4871,6 @@ result = @"CurrentMode"; break; - case MTRAttributeIDTypeClusterDeviceEnergyManagementModeAttributeStartUpModeID: - result = @"StartUpMode"; - break; - - case MTRAttributeIDTypeClusterDeviceEnergyManagementModeAttributeOnModeID: - result = @"OnMode"; - break; - case MTRAttributeIDTypeClusterDeviceEnergyManagementModeAttributeGeneratedCommandListID: result = @"GeneratedCommandList"; break; diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h index 217fe6c026533f..6ee9d3d3943db0 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h @@ -3899,14 +3899,6 @@ MTR_PROVISIONALLY_AVAILABLE - (NSDictionary * _Nullable)readAttributeCurrentModeWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; -- (NSDictionary * _Nullable)readAttributeStartUpModeWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; -- (void)writeAttributeStartUpModeWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs MTR_PROVISIONALLY_AVAILABLE; -- (void)writeAttributeStartUpModeWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - -- (NSDictionary * _Nullable)readAttributeOnModeWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; -- (void)writeAttributeOnModeWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs MTR_PROVISIONALLY_AVAILABLE; -- (void)writeAttributeOnModeWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeGeneratedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; @@ -3949,14 +3941,6 @@ MTR_PROVISIONALLY_AVAILABLE - (NSDictionary * _Nullable)readAttributeCurrentModeWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; -- (NSDictionary * _Nullable)readAttributeStartUpModeWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; -- (void)writeAttributeStartUpModeWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs MTR_PROVISIONALLY_AVAILABLE; -- (void)writeAttributeStartUpModeWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - -- (NSDictionary * _Nullable)readAttributeOnModeWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; -- (void)writeAttributeOnModeWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs MTR_PROVISIONALLY_AVAILABLE; -- (void)writeAttributeOnModeWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeGeneratedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; @@ -3999,14 +3983,6 @@ MTR_PROVISIONALLY_AVAILABLE - (NSDictionary * _Nullable)readAttributeCurrentModeWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; -- (NSDictionary * _Nullable)readAttributeStartUpModeWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; -- (void)writeAttributeStartUpModeWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs MTR_PROVISIONALLY_AVAILABLE; -- (void)writeAttributeStartUpModeWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - -- (NSDictionary * _Nullable)readAttributeOnModeWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; -- (void)writeAttributeOnModeWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs MTR_PROVISIONALLY_AVAILABLE; -- (void)writeAttributeOnModeWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeGeneratedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm index 53d9aecae90970..fbdc9bd48613a3 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm @@ -10522,38 +10522,6 @@ - (void)changeToModeWithParams:(MTREnergyEVSEModeClusterChangeToModeParams *)par return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeEnergyEVSEModeID) attributeID:@(MTRAttributeIDTypeClusterEnergyEVSEModeAttributeCurrentModeID) params:params]; } -- (NSDictionary * _Nullable)readAttributeStartUpModeWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeEnergyEVSEModeID) attributeID:@(MTRAttributeIDTypeClusterEnergyEVSEModeAttributeStartUpModeID) params:params]; -} - -- (void)writeAttributeStartUpModeWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs -{ - [self writeAttributeStartUpModeWithValue:dataValueDictionary expectedValueInterval:expectedValueIntervalMs params:nil]; -} -- (void)writeAttributeStartUpModeWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params -{ - NSNumber * timedWriteTimeout = params.timedWriteTimeout; - - [self.device writeAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeEnergyEVSEModeID) attributeID:@(MTRAttributeIDTypeClusterEnergyEVSEModeAttributeStartUpModeID) value:dataValueDictionary expectedValueInterval:expectedValueIntervalMs timedWriteTimeout:timedWriteTimeout]; -} - -- (NSDictionary * _Nullable)readAttributeOnModeWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeEnergyEVSEModeID) attributeID:@(MTRAttributeIDTypeClusterEnergyEVSEModeAttributeOnModeID) params:params]; -} - -- (void)writeAttributeOnModeWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs -{ - [self writeAttributeOnModeWithValue:dataValueDictionary expectedValueInterval:expectedValueIntervalMs params:nil]; -} -- (void)writeAttributeOnModeWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params -{ - NSNumber * timedWriteTimeout = params.timedWriteTimeout; - - [self.device writeAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeEnergyEVSEModeID) attributeID:@(MTRAttributeIDTypeClusterEnergyEVSEModeAttributeOnModeID) value:dataValueDictionary expectedValueInterval:expectedValueIntervalMs timedWriteTimeout:timedWriteTimeout]; -} - - (NSDictionary * _Nullable)readAttributeGeneratedCommandListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeEnergyEVSEModeID) attributeID:@(MTRAttributeIDTypeClusterEnergyEVSEModeAttributeGeneratedCommandListID) params:params]; @@ -10625,38 +10593,6 @@ - (void)changeToModeWithParams:(MTRWaterHeaterModeClusterChangeToModeParams *)pa return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWaterHeaterModeID) attributeID:@(MTRAttributeIDTypeClusterWaterHeaterModeAttributeCurrentModeID) params:params]; } -- (NSDictionary * _Nullable)readAttributeStartUpModeWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWaterHeaterModeID) attributeID:@(MTRAttributeIDTypeClusterWaterHeaterModeAttributeStartUpModeID) params:params]; -} - -- (void)writeAttributeStartUpModeWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs -{ - [self writeAttributeStartUpModeWithValue:dataValueDictionary expectedValueInterval:expectedValueIntervalMs params:nil]; -} -- (void)writeAttributeStartUpModeWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params -{ - NSNumber * timedWriteTimeout = params.timedWriteTimeout; - - [self.device writeAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWaterHeaterModeID) attributeID:@(MTRAttributeIDTypeClusterWaterHeaterModeAttributeStartUpModeID) value:dataValueDictionary expectedValueInterval:expectedValueIntervalMs timedWriteTimeout:timedWriteTimeout]; -} - -- (NSDictionary * _Nullable)readAttributeOnModeWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWaterHeaterModeID) attributeID:@(MTRAttributeIDTypeClusterWaterHeaterModeAttributeOnModeID) params:params]; -} - -- (void)writeAttributeOnModeWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs -{ - [self writeAttributeOnModeWithValue:dataValueDictionary expectedValueInterval:expectedValueIntervalMs params:nil]; -} -- (void)writeAttributeOnModeWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params -{ - NSNumber * timedWriteTimeout = params.timedWriteTimeout; - - [self.device writeAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWaterHeaterModeID) attributeID:@(MTRAttributeIDTypeClusterWaterHeaterModeAttributeOnModeID) value:dataValueDictionary expectedValueInterval:expectedValueIntervalMs timedWriteTimeout:timedWriteTimeout]; -} - - (NSDictionary * _Nullable)readAttributeGeneratedCommandListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWaterHeaterModeID) attributeID:@(MTRAttributeIDTypeClusterWaterHeaterModeAttributeGeneratedCommandListID) params:params]; @@ -10728,38 +10664,6 @@ - (void)changeToModeWithParams:(MTRDeviceEnergyManagementModeClusterChangeToMode return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeDeviceEnergyManagementModeID) attributeID:@(MTRAttributeIDTypeClusterDeviceEnergyManagementModeAttributeCurrentModeID) params:params]; } -- (NSDictionary * _Nullable)readAttributeStartUpModeWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeDeviceEnergyManagementModeID) attributeID:@(MTRAttributeIDTypeClusterDeviceEnergyManagementModeAttributeStartUpModeID) params:params]; -} - -- (void)writeAttributeStartUpModeWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs -{ - [self writeAttributeStartUpModeWithValue:dataValueDictionary expectedValueInterval:expectedValueIntervalMs params:nil]; -} -- (void)writeAttributeStartUpModeWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params -{ - NSNumber * timedWriteTimeout = params.timedWriteTimeout; - - [self.device writeAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeDeviceEnergyManagementModeID) attributeID:@(MTRAttributeIDTypeClusterDeviceEnergyManagementModeAttributeStartUpModeID) value:dataValueDictionary expectedValueInterval:expectedValueIntervalMs timedWriteTimeout:timedWriteTimeout]; -} - -- (NSDictionary * _Nullable)readAttributeOnModeWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeDeviceEnergyManagementModeID) attributeID:@(MTRAttributeIDTypeClusterDeviceEnergyManagementModeAttributeOnModeID) params:params]; -} - -- (void)writeAttributeOnModeWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs -{ - [self writeAttributeOnModeWithValue:dataValueDictionary expectedValueInterval:expectedValueIntervalMs params:nil]; -} -- (void)writeAttributeOnModeWithValue:(NSDictionary *)dataValueDictionary expectedValueInterval:(NSNumber *)expectedValueIntervalMs params:(MTRWriteParams * _Nullable)params -{ - NSNumber * timedWriteTimeout = params.timedWriteTimeout; - - [self.device writeAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeDeviceEnergyManagementModeID) attributeID:@(MTRAttributeIDTypeClusterDeviceEnergyManagementModeAttributeOnModeID) value:dataValueDictionary expectedValueInterval:expectedValueIntervalMs timedWriteTimeout:timedWriteTimeout]; -} - - (NSDictionary * _Nullable)readAttributeGeneratedCommandListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeDeviceEnergyManagementModeID) attributeID:@(MTRAttributeIDTypeClusterDeviceEnergyManagementModeAttributeGeneratedCommandListID) params:params]; diff --git a/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp b/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp index 2caf4f3764cac4..382c808a78cc62 100644 --- a/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp +++ b/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp @@ -16141,186 +16141,6 @@ Protocols::InteractionModel::Status Set(EndpointId endpoint, uint16_t value) namespace EnergyEvseMode { namespace Attributes { -namespace StartUpMode { - -Protocols::InteractionModel::Status Get(EndpointId endpoint, DataModel::Nullable & value) -{ - using Traits = NumericAttributeTraits; - Traits::StorageType temp; - uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); - Protocols::InteractionModel::Status status = - emberAfReadAttribute(endpoint, Clusters::EnergyEvseMode::Id, Id, readable, sizeof(temp)); - VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); - if (Traits::IsNullValue(temp)) - { - value.SetNull(); - } - else - { - value.SetNonNull() = Traits::StorageToWorking(temp); - } - return status; -} - -Protocols::InteractionModel::Status Set(EndpointId endpoint, uint8_t value, MarkAttributeDirty markDirty) -{ - using Traits = NumericAttributeTraits; - if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - Traits::StorageType storageValue; - Traits::WorkingToStorage(value, storageValue); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(ConcreteAttributePath(endpoint, Clusters::EnergyEvseMode::Id, Id), - EmberAfWriteDataInput(writable, ZCL_INT8U_ATTRIBUTE_TYPE).SetMarkDirty(markDirty)); -} - -Protocols::InteractionModel::Status Set(EndpointId endpoint, uint8_t value) -{ - using Traits = NumericAttributeTraits; - if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - Traits::StorageType storageValue; - Traits::WorkingToStorage(value, storageValue); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::EnergyEvseMode::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); -} - -Protocols::InteractionModel::Status SetNull(EndpointId endpoint, MarkAttributeDirty markDirty) -{ - using Traits = NumericAttributeTraits; - Traits::StorageType value; - Traits::SetNull(value); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); - return emberAfWriteAttribute(ConcreteAttributePath(endpoint, Clusters::EnergyEvseMode::Id, Id), - EmberAfWriteDataInput(writable, ZCL_INT8U_ATTRIBUTE_TYPE).SetMarkDirty(markDirty)); -} - -Protocols::InteractionModel::Status SetNull(EndpointId endpoint) -{ - using Traits = NumericAttributeTraits; - Traits::StorageType value; - Traits::SetNull(value); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); - return emberAfWriteAttribute(endpoint, Clusters::EnergyEvseMode::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); -} - -Protocols::InteractionModel::Status Set(EndpointId endpoint, const chip::app::DataModel::Nullable & value, - MarkAttributeDirty markDirty) -{ - if (value.IsNull()) - { - return SetNull(endpoint, markDirty); - } - - return Set(endpoint, value.Value(), markDirty); -} - -Protocols::InteractionModel::Status Set(EndpointId endpoint, const chip::app::DataModel::Nullable & value) -{ - if (value.IsNull()) - { - return SetNull(endpoint); - } - - return Set(endpoint, value.Value()); -} - -} // namespace StartUpMode - -namespace OnMode { - -Protocols::InteractionModel::Status Get(EndpointId endpoint, DataModel::Nullable & value) -{ - using Traits = NumericAttributeTraits; - Traits::StorageType temp; - uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); - Protocols::InteractionModel::Status status = - emberAfReadAttribute(endpoint, Clusters::EnergyEvseMode::Id, Id, readable, sizeof(temp)); - VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); - if (Traits::IsNullValue(temp)) - { - value.SetNull(); - } - else - { - value.SetNonNull() = Traits::StorageToWorking(temp); - } - return status; -} - -Protocols::InteractionModel::Status Set(EndpointId endpoint, uint8_t value, MarkAttributeDirty markDirty) -{ - using Traits = NumericAttributeTraits; - if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - Traits::StorageType storageValue; - Traits::WorkingToStorage(value, storageValue); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(ConcreteAttributePath(endpoint, Clusters::EnergyEvseMode::Id, Id), - EmberAfWriteDataInput(writable, ZCL_INT8U_ATTRIBUTE_TYPE).SetMarkDirty(markDirty)); -} - -Protocols::InteractionModel::Status Set(EndpointId endpoint, uint8_t value) -{ - using Traits = NumericAttributeTraits; - if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - Traits::StorageType storageValue; - Traits::WorkingToStorage(value, storageValue); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::EnergyEvseMode::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); -} - -Protocols::InteractionModel::Status SetNull(EndpointId endpoint, MarkAttributeDirty markDirty) -{ - using Traits = NumericAttributeTraits; - Traits::StorageType value; - Traits::SetNull(value); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); - return emberAfWriteAttribute(ConcreteAttributePath(endpoint, Clusters::EnergyEvseMode::Id, Id), - EmberAfWriteDataInput(writable, ZCL_INT8U_ATTRIBUTE_TYPE).SetMarkDirty(markDirty)); -} - -Protocols::InteractionModel::Status SetNull(EndpointId endpoint) -{ - using Traits = NumericAttributeTraits; - Traits::StorageType value; - Traits::SetNull(value); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); - return emberAfWriteAttribute(endpoint, Clusters::EnergyEvseMode::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); -} - -Protocols::InteractionModel::Status Set(EndpointId endpoint, const chip::app::DataModel::Nullable & value, - MarkAttributeDirty markDirty) -{ - if (value.IsNull()) - { - return SetNull(endpoint, markDirty); - } - - return Set(endpoint, value.Value(), markDirty); -} - -Protocols::InteractionModel::Status Set(EndpointId endpoint, const chip::app::DataModel::Nullable & value) -{ - if (value.IsNull()) - { - return SetNull(endpoint); - } - - return Set(endpoint, value.Value()); -} - -} // namespace OnMode - namespace ClusterRevision { Protocols::InteractionModel::Status Get(EndpointId endpoint, uint16_t * value) @@ -16374,31 +16194,28 @@ Protocols::InteractionModel::Status Set(EndpointId endpoint, uint16_t value) namespace WaterHeaterMode { namespace Attributes { -namespace StartUpMode { +namespace ClusterRevision { -Protocols::InteractionModel::Status Get(EndpointId endpoint, DataModel::Nullable & value) +Protocols::InteractionModel::Status Get(EndpointId endpoint, uint16_t * value) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; Traits::StorageType temp; uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); Protocols::InteractionModel::Status status = emberAfReadAttribute(endpoint, Clusters::WaterHeaterMode::Id, Id, readable, sizeof(temp)); VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); - if (Traits::IsNullValue(temp)) - { - value.SetNull(); - } - else + if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) { - value.SetNonNull() = Traits::StorageToWorking(temp); + return Protocols::InteractionModel::Status::ConstraintError; } + *value = Traits::StorageToWorking(temp); return status; } -Protocols::InteractionModel::Status Set(EndpointId endpoint, uint8_t value, MarkAttributeDirty markDirty) +Protocols::InteractionModel::Status Set(EndpointId endpoint, uint16_t value, MarkAttributeDirty markDirty) { - using Traits = NumericAttributeTraits; - if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) { return Protocols::InteractionModel::Status::ConstraintError; } @@ -16406,387 +16223,30 @@ Protocols::InteractionModel::Status Set(EndpointId endpoint, uint8_t value, Mark Traits::WorkingToStorage(value, storageValue); uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); return emberAfWriteAttribute(ConcreteAttributePath(endpoint, Clusters::WaterHeaterMode::Id, Id), - EmberAfWriteDataInput(writable, ZCL_INT8U_ATTRIBUTE_TYPE).SetMarkDirty(markDirty)); + EmberAfWriteDataInput(writable, ZCL_INT16U_ATTRIBUTE_TYPE).SetMarkDirty(markDirty)); } -Protocols::InteractionModel::Status Set(EndpointId endpoint, uint8_t value) +Protocols::InteractionModel::Status Set(EndpointId endpoint, uint16_t value) { - using Traits = NumericAttributeTraits; - if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) { return Protocols::InteractionModel::Status::ConstraintError; } Traits::StorageType storageValue; Traits::WorkingToStorage(value, storageValue); uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::WaterHeaterMode::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); -} - -Protocols::InteractionModel::Status SetNull(EndpointId endpoint, MarkAttributeDirty markDirty) -{ - using Traits = NumericAttributeTraits; - Traits::StorageType value; - Traits::SetNull(value); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); - return emberAfWriteAttribute(ConcreteAttributePath(endpoint, Clusters::WaterHeaterMode::Id, Id), - EmberAfWriteDataInput(writable, ZCL_INT8U_ATTRIBUTE_TYPE).SetMarkDirty(markDirty)); -} - -Protocols::InteractionModel::Status SetNull(EndpointId endpoint) -{ - using Traits = NumericAttributeTraits; - Traits::StorageType value; - Traits::SetNull(value); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); - return emberAfWriteAttribute(endpoint, Clusters::WaterHeaterMode::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); -} - -Protocols::InteractionModel::Status Set(EndpointId endpoint, const chip::app::DataModel::Nullable & value, - MarkAttributeDirty markDirty) -{ - if (value.IsNull()) - { - return SetNull(endpoint, markDirty); - } - - return Set(endpoint, value.Value(), markDirty); -} - -Protocols::InteractionModel::Status Set(EndpointId endpoint, const chip::app::DataModel::Nullable & value) -{ - if (value.IsNull()) - { - return SetNull(endpoint); - } - - return Set(endpoint, value.Value()); + return emberAfWriteAttribute(endpoint, Clusters::WaterHeaterMode::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); } -} // namespace StartUpMode +} // namespace ClusterRevision -namespace OnMode { - -Protocols::InteractionModel::Status Get(EndpointId endpoint, DataModel::Nullable & value) -{ - using Traits = NumericAttributeTraits; - Traits::StorageType temp; - uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); - Protocols::InteractionModel::Status status = - emberAfReadAttribute(endpoint, Clusters::WaterHeaterMode::Id, Id, readable, sizeof(temp)); - VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); - if (Traits::IsNullValue(temp)) - { - value.SetNull(); - } - else - { - value.SetNonNull() = Traits::StorageToWorking(temp); - } - return status; -} - -Protocols::InteractionModel::Status Set(EndpointId endpoint, uint8_t value, MarkAttributeDirty markDirty) -{ - using Traits = NumericAttributeTraits; - if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - Traits::StorageType storageValue; - Traits::WorkingToStorage(value, storageValue); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(ConcreteAttributePath(endpoint, Clusters::WaterHeaterMode::Id, Id), - EmberAfWriteDataInput(writable, ZCL_INT8U_ATTRIBUTE_TYPE).SetMarkDirty(markDirty)); -} - -Protocols::InteractionModel::Status Set(EndpointId endpoint, uint8_t value) -{ - using Traits = NumericAttributeTraits; - if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - Traits::StorageType storageValue; - Traits::WorkingToStorage(value, storageValue); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::WaterHeaterMode::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); -} - -Protocols::InteractionModel::Status SetNull(EndpointId endpoint, MarkAttributeDirty markDirty) -{ - using Traits = NumericAttributeTraits; - Traits::StorageType value; - Traits::SetNull(value); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); - return emberAfWriteAttribute(ConcreteAttributePath(endpoint, Clusters::WaterHeaterMode::Id, Id), - EmberAfWriteDataInput(writable, ZCL_INT8U_ATTRIBUTE_TYPE).SetMarkDirty(markDirty)); -} - -Protocols::InteractionModel::Status SetNull(EndpointId endpoint) -{ - using Traits = NumericAttributeTraits; - Traits::StorageType value; - Traits::SetNull(value); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); - return emberAfWriteAttribute(endpoint, Clusters::WaterHeaterMode::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); -} - -Protocols::InteractionModel::Status Set(EndpointId endpoint, const chip::app::DataModel::Nullable & value, - MarkAttributeDirty markDirty) -{ - if (value.IsNull()) - { - return SetNull(endpoint, markDirty); - } - - return Set(endpoint, value.Value(), markDirty); -} - -Protocols::InteractionModel::Status Set(EndpointId endpoint, const chip::app::DataModel::Nullable & value) -{ - if (value.IsNull()) - { - return SetNull(endpoint); - } - - return Set(endpoint, value.Value()); -} - -} // namespace OnMode - -namespace ClusterRevision { - -Protocols::InteractionModel::Status Get(EndpointId endpoint, uint16_t * value) -{ - using Traits = NumericAttributeTraits; - Traits::StorageType temp; - uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); - Protocols::InteractionModel::Status status = - emberAfReadAttribute(endpoint, Clusters::WaterHeaterMode::Id, Id, readable, sizeof(temp)); - VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); - if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - *value = Traits::StorageToWorking(temp); - return status; -} - -Protocols::InteractionModel::Status Set(EndpointId endpoint, uint16_t value, MarkAttributeDirty markDirty) -{ - using Traits = NumericAttributeTraits; - if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - Traits::StorageType storageValue; - Traits::WorkingToStorage(value, storageValue); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(ConcreteAttributePath(endpoint, Clusters::WaterHeaterMode::Id, Id), - EmberAfWriteDataInput(writable, ZCL_INT16U_ATTRIBUTE_TYPE).SetMarkDirty(markDirty)); -} - -Protocols::InteractionModel::Status Set(EndpointId endpoint, uint16_t value) -{ - using Traits = NumericAttributeTraits; - if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - Traits::StorageType storageValue; - Traits::WorkingToStorage(value, storageValue); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::WaterHeaterMode::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); -} - -} // namespace ClusterRevision - -} // namespace Attributes -} // namespace WaterHeaterMode +} // namespace Attributes +} // namespace WaterHeaterMode namespace DeviceEnergyManagementMode { namespace Attributes { -namespace StartUpMode { - -Protocols::InteractionModel::Status Get(EndpointId endpoint, DataModel::Nullable & value) -{ - using Traits = NumericAttributeTraits; - Traits::StorageType temp; - uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); - Protocols::InteractionModel::Status status = - emberAfReadAttribute(endpoint, Clusters::DeviceEnergyManagementMode::Id, Id, readable, sizeof(temp)); - VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); - if (Traits::IsNullValue(temp)) - { - value.SetNull(); - } - else - { - value.SetNonNull() = Traits::StorageToWorking(temp); - } - return status; -} - -Protocols::InteractionModel::Status Set(EndpointId endpoint, uint8_t value, MarkAttributeDirty markDirty) -{ - using Traits = NumericAttributeTraits; - if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - Traits::StorageType storageValue; - Traits::WorkingToStorage(value, storageValue); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(ConcreteAttributePath(endpoint, Clusters::DeviceEnergyManagementMode::Id, Id), - EmberAfWriteDataInput(writable, ZCL_INT8U_ATTRIBUTE_TYPE).SetMarkDirty(markDirty)); -} - -Protocols::InteractionModel::Status Set(EndpointId endpoint, uint8_t value) -{ - using Traits = NumericAttributeTraits; - if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - Traits::StorageType storageValue; - Traits::WorkingToStorage(value, storageValue); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::DeviceEnergyManagementMode::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); -} - -Protocols::InteractionModel::Status SetNull(EndpointId endpoint, MarkAttributeDirty markDirty) -{ - using Traits = NumericAttributeTraits; - Traits::StorageType value; - Traits::SetNull(value); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); - return emberAfWriteAttribute(ConcreteAttributePath(endpoint, Clusters::DeviceEnergyManagementMode::Id, Id), - EmberAfWriteDataInput(writable, ZCL_INT8U_ATTRIBUTE_TYPE).SetMarkDirty(markDirty)); -} - -Protocols::InteractionModel::Status SetNull(EndpointId endpoint) -{ - using Traits = NumericAttributeTraits; - Traits::StorageType value; - Traits::SetNull(value); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); - return emberAfWriteAttribute(endpoint, Clusters::DeviceEnergyManagementMode::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); -} - -Protocols::InteractionModel::Status Set(EndpointId endpoint, const chip::app::DataModel::Nullable & value, - MarkAttributeDirty markDirty) -{ - if (value.IsNull()) - { - return SetNull(endpoint, markDirty); - } - - return Set(endpoint, value.Value(), markDirty); -} - -Protocols::InteractionModel::Status Set(EndpointId endpoint, const chip::app::DataModel::Nullable & value) -{ - if (value.IsNull()) - { - return SetNull(endpoint); - } - - return Set(endpoint, value.Value()); -} - -} // namespace StartUpMode - -namespace OnMode { - -Protocols::InteractionModel::Status Get(EndpointId endpoint, DataModel::Nullable & value) -{ - using Traits = NumericAttributeTraits; - Traits::StorageType temp; - uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); - Protocols::InteractionModel::Status status = - emberAfReadAttribute(endpoint, Clusters::DeviceEnergyManagementMode::Id, Id, readable, sizeof(temp)); - VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); - if (Traits::IsNullValue(temp)) - { - value.SetNull(); - } - else - { - value.SetNonNull() = Traits::StorageToWorking(temp); - } - return status; -} - -Protocols::InteractionModel::Status Set(EndpointId endpoint, uint8_t value, MarkAttributeDirty markDirty) -{ - using Traits = NumericAttributeTraits; - if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - Traits::StorageType storageValue; - Traits::WorkingToStorage(value, storageValue); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(ConcreteAttributePath(endpoint, Clusters::DeviceEnergyManagementMode::Id, Id), - EmberAfWriteDataInput(writable, ZCL_INT8U_ATTRIBUTE_TYPE).SetMarkDirty(markDirty)); -} - -Protocols::InteractionModel::Status Set(EndpointId endpoint, uint8_t value) -{ - using Traits = NumericAttributeTraits; - if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - Traits::StorageType storageValue; - Traits::WorkingToStorage(value, storageValue); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::DeviceEnergyManagementMode::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); -} - -Protocols::InteractionModel::Status SetNull(EndpointId endpoint, MarkAttributeDirty markDirty) -{ - using Traits = NumericAttributeTraits; - Traits::StorageType value; - Traits::SetNull(value); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); - return emberAfWriteAttribute(ConcreteAttributePath(endpoint, Clusters::DeviceEnergyManagementMode::Id, Id), - EmberAfWriteDataInput(writable, ZCL_INT8U_ATTRIBUTE_TYPE).SetMarkDirty(markDirty)); -} - -Protocols::InteractionModel::Status SetNull(EndpointId endpoint) -{ - using Traits = NumericAttributeTraits; - Traits::StorageType value; - Traits::SetNull(value); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); - return emberAfWriteAttribute(endpoint, Clusters::DeviceEnergyManagementMode::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); -} - -Protocols::InteractionModel::Status Set(EndpointId endpoint, const chip::app::DataModel::Nullable & value, - MarkAttributeDirty markDirty) -{ - if (value.IsNull()) - { - return SetNull(endpoint, markDirty); - } - - return Set(endpoint, value.Value(), markDirty); -} - -Protocols::InteractionModel::Status Set(EndpointId endpoint, const chip::app::DataModel::Nullable & value) -{ - if (value.IsNull()) - { - return SetNull(endpoint); - } - - return Set(endpoint, value.Value()); -} - -} // namespace OnMode - namespace ClusterRevision { Protocols::InteractionModel::Status Get(EndpointId endpoint, uint16_t * value) diff --git a/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.h b/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.h index 50d01dbe713163..e0a965b732a743 100644 --- a/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.h +++ b/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.h @@ -2586,28 +2586,6 @@ Protocols::InteractionModel::Status Set(EndpointId endpoint, uint16_t value, Mar namespace EnergyEvseMode { namespace Attributes { -namespace StartUpMode { -Protocols::InteractionModel::Status Get(EndpointId endpoint, DataModel::Nullable & value); // int8u -Protocols::InteractionModel::Status Set(EndpointId endpoint, uint8_t value); -Protocols::InteractionModel::Status Set(EndpointId endpoint, uint8_t value, MarkAttributeDirty markDirty); -Protocols::InteractionModel::Status SetNull(EndpointId endpoint); -Protocols::InteractionModel::Status SetNull(EndpointId endpoint, MarkAttributeDirty markDirty); -Protocols::InteractionModel::Status Set(EndpointId endpoint, const chip::app::DataModel::Nullable & value); -Protocols::InteractionModel::Status Set(EndpointId endpoint, const chip::app::DataModel::Nullable & value, - MarkAttributeDirty markDirty); -} // namespace StartUpMode - -namespace OnMode { -Protocols::InteractionModel::Status Get(EndpointId endpoint, DataModel::Nullable & value); // int8u -Protocols::InteractionModel::Status Set(EndpointId endpoint, uint8_t value); -Protocols::InteractionModel::Status Set(EndpointId endpoint, uint8_t value, MarkAttributeDirty markDirty); -Protocols::InteractionModel::Status SetNull(EndpointId endpoint); -Protocols::InteractionModel::Status SetNull(EndpointId endpoint, MarkAttributeDirty markDirty); -Protocols::InteractionModel::Status Set(EndpointId endpoint, const chip::app::DataModel::Nullable & value); -Protocols::InteractionModel::Status Set(EndpointId endpoint, const chip::app::DataModel::Nullable & value, - MarkAttributeDirty markDirty); -} // namespace OnMode - namespace ClusterRevision { Protocols::InteractionModel::Status Get(EndpointId endpoint, uint16_t * value); // int16u Protocols::InteractionModel::Status Set(EndpointId endpoint, uint16_t value); @@ -2620,28 +2598,6 @@ Protocols::InteractionModel::Status Set(EndpointId endpoint, uint16_t value, Mar namespace WaterHeaterMode { namespace Attributes { -namespace StartUpMode { -Protocols::InteractionModel::Status Get(EndpointId endpoint, DataModel::Nullable & value); // int8u -Protocols::InteractionModel::Status Set(EndpointId endpoint, uint8_t value); -Protocols::InteractionModel::Status Set(EndpointId endpoint, uint8_t value, MarkAttributeDirty markDirty); -Protocols::InteractionModel::Status SetNull(EndpointId endpoint); -Protocols::InteractionModel::Status SetNull(EndpointId endpoint, MarkAttributeDirty markDirty); -Protocols::InteractionModel::Status Set(EndpointId endpoint, const chip::app::DataModel::Nullable & value); -Protocols::InteractionModel::Status Set(EndpointId endpoint, const chip::app::DataModel::Nullable & value, - MarkAttributeDirty markDirty); -} // namespace StartUpMode - -namespace OnMode { -Protocols::InteractionModel::Status Get(EndpointId endpoint, DataModel::Nullable & value); // int8u -Protocols::InteractionModel::Status Set(EndpointId endpoint, uint8_t value); -Protocols::InteractionModel::Status Set(EndpointId endpoint, uint8_t value, MarkAttributeDirty markDirty); -Protocols::InteractionModel::Status SetNull(EndpointId endpoint); -Protocols::InteractionModel::Status SetNull(EndpointId endpoint, MarkAttributeDirty markDirty); -Protocols::InteractionModel::Status Set(EndpointId endpoint, const chip::app::DataModel::Nullable & value); -Protocols::InteractionModel::Status Set(EndpointId endpoint, const chip::app::DataModel::Nullable & value, - MarkAttributeDirty markDirty); -} // namespace OnMode - namespace ClusterRevision { Protocols::InteractionModel::Status Get(EndpointId endpoint, uint16_t * value); // int16u Protocols::InteractionModel::Status Set(EndpointId endpoint, uint16_t value); @@ -2654,28 +2610,6 @@ Protocols::InteractionModel::Status Set(EndpointId endpoint, uint16_t value, Mar namespace DeviceEnergyManagementMode { namespace Attributes { -namespace StartUpMode { -Protocols::InteractionModel::Status Get(EndpointId endpoint, DataModel::Nullable & value); // int8u -Protocols::InteractionModel::Status Set(EndpointId endpoint, uint8_t value); -Protocols::InteractionModel::Status Set(EndpointId endpoint, uint8_t value, MarkAttributeDirty markDirty); -Protocols::InteractionModel::Status SetNull(EndpointId endpoint); -Protocols::InteractionModel::Status SetNull(EndpointId endpoint, MarkAttributeDirty markDirty); -Protocols::InteractionModel::Status Set(EndpointId endpoint, const chip::app::DataModel::Nullable & value); -Protocols::InteractionModel::Status Set(EndpointId endpoint, const chip::app::DataModel::Nullable & value, - MarkAttributeDirty markDirty); -} // namespace StartUpMode - -namespace OnMode { -Protocols::InteractionModel::Status Get(EndpointId endpoint, DataModel::Nullable & value); // int8u -Protocols::InteractionModel::Status Set(EndpointId endpoint, uint8_t value); -Protocols::InteractionModel::Status Set(EndpointId endpoint, uint8_t value, MarkAttributeDirty markDirty); -Protocols::InteractionModel::Status SetNull(EndpointId endpoint); -Protocols::InteractionModel::Status SetNull(EndpointId endpoint, MarkAttributeDirty markDirty); -Protocols::InteractionModel::Status Set(EndpointId endpoint, const chip::app::DataModel::Nullable & value); -Protocols::InteractionModel::Status Set(EndpointId endpoint, const chip::app::DataModel::Nullable & value, - MarkAttributeDirty markDirty); -} // namespace OnMode - namespace ClusterRevision { Protocols::InteractionModel::Status Get(EndpointId endpoint, uint16_t * value); // int16u Protocols::InteractionModel::Status Set(EndpointId endpoint, uint16_t value); diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-enums.h b/zzz_generated/app-common/app-common/zap-generated/cluster-enums.h index dd7986eaee6627..586eeb91aff695 100644 --- a/zzz_generated/app-common/app-common/zap-generated/cluster-enums.h +++ b/zzz_generated/app-common/app-common/zap-generated/cluster-enums.h @@ -3255,6 +3255,7 @@ enum class ModeTag : uint16_t kManual = 0x4000, kTimeOfUse = 0x4001, kSolarCharging = 0x4002, + kV2x = 0x4003, // kUnknownEnumValue intentionally not defined. This enum never goes // through DataModel::Decode, likely because it is a part of a derived // cluster. As a result having kUnknownEnumValue in this enum is error diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp index c944864eec4cee..6884315a0737e0 100644 --- a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp +++ b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp @@ -18246,10 +18246,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, supportedModes); case Attributes::CurrentMode::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, currentMode); - case Attributes::StartUpMode::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, startUpMode); - case Attributes::OnMode::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, onMode); case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): @@ -18359,10 +18355,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, supportedModes); case Attributes::CurrentMode::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, currentMode); - case Attributes::StartUpMode::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, startUpMode); - case Attributes::OnMode::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, onMode); case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): @@ -18472,10 +18464,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, supportedModes); case Attributes::CurrentMode::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, currentMode); - case Attributes::StartUpMode::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, startUpMode); - case Attributes::OnMode::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, onMode); case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h index dd701f82100980..f2671adf0f2a03 100644 --- a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h +++ b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h @@ -24788,30 +24788,6 @@ struct TypeInfo static constexpr bool MustUseTimedWrite() { return false; } }; } // namespace CurrentMode -namespace StartUpMode { -struct TypeInfo -{ - using Type = chip::app::DataModel::Nullable; - using DecodableType = chip::app::DataModel::Nullable; - using DecodableArgType = const chip::app::DataModel::Nullable &; - - static constexpr ClusterId GetClusterId() { return Clusters::EnergyEvseMode::Id; } - static constexpr AttributeId GetAttributeId() { return Attributes::StartUpMode::Id; } - static constexpr bool MustUseTimedWrite() { return false; } -}; -} // namespace StartUpMode -namespace OnMode { -struct TypeInfo -{ - using Type = chip::app::DataModel::Nullable; - using DecodableType = chip::app::DataModel::Nullable; - using DecodableArgType = const chip::app::DataModel::Nullable &; - - static constexpr ClusterId GetClusterId() { return Clusters::EnergyEvseMode::Id; } - static constexpr AttributeId GetAttributeId() { return Attributes::OnMode::Id; } - static constexpr bool MustUseTimedWrite() { return false; } -}; -} // namespace OnMode namespace GeneratedCommandList { struct TypeInfo : public Clusters::Globals::Attributes::GeneratedCommandList::TypeInfo { @@ -24859,8 +24835,6 @@ struct TypeInfo Attributes::SupportedModes::TypeInfo::DecodableType supportedModes; Attributes::CurrentMode::TypeInfo::DecodableType currentMode = static_cast(0); - Attributes::StartUpMode::TypeInfo::DecodableType startUpMode; - Attributes::OnMode::TypeInfo::DecodableType onMode; Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; Attributes::EventList::TypeInfo::DecodableType eventList; @@ -24990,30 +24964,6 @@ struct TypeInfo static constexpr bool MustUseTimedWrite() { return false; } }; } // namespace CurrentMode -namespace StartUpMode { -struct TypeInfo -{ - using Type = chip::app::DataModel::Nullable; - using DecodableType = chip::app::DataModel::Nullable; - using DecodableArgType = const chip::app::DataModel::Nullable &; - - static constexpr ClusterId GetClusterId() { return Clusters::WaterHeaterMode::Id; } - static constexpr AttributeId GetAttributeId() { return Attributes::StartUpMode::Id; } - static constexpr bool MustUseTimedWrite() { return false; } -}; -} // namespace StartUpMode -namespace OnMode { -struct TypeInfo -{ - using Type = chip::app::DataModel::Nullable; - using DecodableType = chip::app::DataModel::Nullable; - using DecodableArgType = const chip::app::DataModel::Nullable &; - - static constexpr ClusterId GetClusterId() { return Clusters::WaterHeaterMode::Id; } - static constexpr AttributeId GetAttributeId() { return Attributes::OnMode::Id; } - static constexpr bool MustUseTimedWrite() { return false; } -}; -} // namespace OnMode namespace GeneratedCommandList { struct TypeInfo : public Clusters::Globals::Attributes::GeneratedCommandList::TypeInfo { @@ -25061,8 +25011,6 @@ struct TypeInfo Attributes::SupportedModes::TypeInfo::DecodableType supportedModes; Attributes::CurrentMode::TypeInfo::DecodableType currentMode = static_cast(0); - Attributes::StartUpMode::TypeInfo::DecodableType startUpMode; - Attributes::OnMode::TypeInfo::DecodableType onMode; Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; Attributes::EventList::TypeInfo::DecodableType eventList; @@ -25192,30 +25140,6 @@ struct TypeInfo static constexpr bool MustUseTimedWrite() { return false; } }; } // namespace CurrentMode -namespace StartUpMode { -struct TypeInfo -{ - using Type = chip::app::DataModel::Nullable; - using DecodableType = chip::app::DataModel::Nullable; - using DecodableArgType = const chip::app::DataModel::Nullable &; - - static constexpr ClusterId GetClusterId() { return Clusters::DeviceEnergyManagementMode::Id; } - static constexpr AttributeId GetAttributeId() { return Attributes::StartUpMode::Id; } - static constexpr bool MustUseTimedWrite() { return false; } -}; -} // namespace StartUpMode -namespace OnMode { -struct TypeInfo -{ - using Type = chip::app::DataModel::Nullable; - using DecodableType = chip::app::DataModel::Nullable; - using DecodableArgType = const chip::app::DataModel::Nullable &; - - static constexpr ClusterId GetClusterId() { return Clusters::DeviceEnergyManagementMode::Id; } - static constexpr AttributeId GetAttributeId() { return Attributes::OnMode::Id; } - static constexpr bool MustUseTimedWrite() { return false; } -}; -} // namespace OnMode namespace GeneratedCommandList { struct TypeInfo : public Clusters::Globals::Attributes::GeneratedCommandList::TypeInfo { @@ -25263,8 +25187,6 @@ struct TypeInfo Attributes::SupportedModes::TypeInfo::DecodableType supportedModes; Attributes::CurrentMode::TypeInfo::DecodableType currentMode = static_cast(0); - Attributes::StartUpMode::TypeInfo::DecodableType startUpMode; - Attributes::OnMode::TypeInfo::DecodableType onMode; Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; Attributes::EventList::TypeInfo::DecodableType eventList; diff --git a/zzz_generated/app-common/app-common/zap-generated/ids/Attributes.h b/zzz_generated/app-common/app-common/zap-generated/ids/Attributes.h index d3cd9efcc673e1..030d38c2a5d779 100644 --- a/zzz_generated/app-common/app-common/zap-generated/ids/Attributes.h +++ b/zzz_generated/app-common/app-common/zap-generated/ids/Attributes.h @@ -4170,14 +4170,6 @@ namespace CurrentMode { static constexpr AttributeId Id = 0x00000001; } // namespace CurrentMode -namespace StartUpMode { -static constexpr AttributeId Id = 0x00000002; -} // namespace StartUpMode - -namespace OnMode { -static constexpr AttributeId Id = 0x00000003; -} // namespace OnMode - namespace GeneratedCommandList { static constexpr AttributeId Id = Globals::Attributes::GeneratedCommandList::Id; } // namespace GeneratedCommandList @@ -4216,14 +4208,6 @@ namespace CurrentMode { static constexpr AttributeId Id = 0x00000001; } // namespace CurrentMode -namespace StartUpMode { -static constexpr AttributeId Id = 0x00000002; -} // namespace StartUpMode - -namespace OnMode { -static constexpr AttributeId Id = 0x00000003; -} // namespace OnMode - namespace GeneratedCommandList { static constexpr AttributeId Id = Globals::Attributes::GeneratedCommandList::Id; } // namespace GeneratedCommandList @@ -4262,14 +4246,6 @@ namespace CurrentMode { static constexpr AttributeId Id = 0x00000001; } // namespace CurrentMode -namespace StartUpMode { -static constexpr AttributeId Id = 0x00000002; -} // namespace StartUpMode - -namespace OnMode { -static constexpr AttributeId Id = 0x00000003; -} // namespace OnMode - namespace GeneratedCommandList { static constexpr AttributeId Id = Globals::Attributes::GeneratedCommandList::Id; } // namespace GeneratedCommandList diff --git a/zzz_generated/chip-tool/zap-generated/cluster/Commands.h b/zzz_generated/chip-tool/zap-generated/cluster/Commands.h index ddb336fa7d3c01..244bc725ea5c8b 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/Commands.h +++ b/zzz_generated/chip-tool/zap-generated/cluster/Commands.h @@ -7829,8 +7829,6 @@ class EnergyEvseClearTargets : public ClusterCommand | Attributes: | | | * SupportedModes | 0x0000 | | * CurrentMode | 0x0001 | -| * StartUpMode | 0x0002 | -| * OnMode | 0x0003 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | | * EventList | 0xFFFA | @@ -7887,8 +7885,6 @@ class EnergyEvseModeChangeToMode : public ClusterCommand | Attributes: | | | * SupportedModes | 0x0000 | | * CurrentMode | 0x0001 | -| * StartUpMode | 0x0002 | -| * OnMode | 0x0003 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | | * EventList | 0xFFFA | @@ -7945,8 +7941,6 @@ class WaterHeaterModeChangeToMode : public ClusterCommand | Attributes: | | | * SupportedModes | 0x0000 | | * CurrentMode | 0x0001 | -| * StartUpMode | 0x0002 | -| * OnMode | 0x0003 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | | * EventList | 0xFFFA | @@ -22712,8 +22706,6 @@ void registerClusterEnergyEvseMode(Commands & commands, CredentialIssuerCommands make_unique(Id, credsIssuerConfig), // make_unique(Id, "supported-modes", Attributes::SupportedModes::Id, credsIssuerConfig), // make_unique(Id, "current-mode", Attributes::CurrentMode::Id, credsIssuerConfig), // - make_unique(Id, "start-up-mode", Attributes::StartUpMode::Id, credsIssuerConfig), // - make_unique(Id, "on-mode", Attributes::OnMode::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // @@ -22726,10 +22718,6 @@ void registerClusterEnergyEvseMode(Commands & commands, CredentialIssuerCommands Id, "supported-modes", Attributes::SupportedModes::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "current-mode", 0, UINT8_MAX, Attributes::CurrentMode::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "start-up-mode", 0, UINT8_MAX, Attributes::StartUpMode::Id, WriteCommandType::kWrite, credsIssuerConfig), // - make_unique>>(Id, "on-mode", 0, UINT8_MAX, Attributes::OnMode::Id, - WriteCommandType::kWrite, credsIssuerConfig), // make_unique>>( Id, "generated-command-list", Attributes::GeneratedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // @@ -22746,8 +22734,6 @@ void registerClusterEnergyEvseMode(Commands & commands, CredentialIssuerCommands make_unique(Id, credsIssuerConfig), // make_unique(Id, "supported-modes", Attributes::SupportedModes::Id, credsIssuerConfig), // make_unique(Id, "current-mode", Attributes::CurrentMode::Id, credsIssuerConfig), // - make_unique(Id, "start-up-mode", Attributes::StartUpMode::Id, credsIssuerConfig), // - make_unique(Id, "on-mode", Attributes::OnMode::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // @@ -22781,8 +22767,6 @@ void registerClusterWaterHeaterMode(Commands & commands, CredentialIssuerCommand make_unique(Id, credsIssuerConfig), // make_unique(Id, "supported-modes", Attributes::SupportedModes::Id, credsIssuerConfig), // make_unique(Id, "current-mode", Attributes::CurrentMode::Id, credsIssuerConfig), // - make_unique(Id, "start-up-mode", Attributes::StartUpMode::Id, credsIssuerConfig), // - make_unique(Id, "on-mode", Attributes::OnMode::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // @@ -22795,10 +22779,6 @@ void registerClusterWaterHeaterMode(Commands & commands, CredentialIssuerCommand Id, "supported-modes", Attributes::SupportedModes::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "current-mode", 0, UINT8_MAX, Attributes::CurrentMode::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "start-up-mode", 0, UINT8_MAX, Attributes::StartUpMode::Id, WriteCommandType::kWrite, credsIssuerConfig), // - make_unique>>(Id, "on-mode", 0, UINT8_MAX, Attributes::OnMode::Id, - WriteCommandType::kWrite, credsIssuerConfig), // make_unique>>( Id, "generated-command-list", Attributes::GeneratedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // @@ -22815,8 +22795,6 @@ void registerClusterWaterHeaterMode(Commands & commands, CredentialIssuerCommand make_unique(Id, credsIssuerConfig), // make_unique(Id, "supported-modes", Attributes::SupportedModes::Id, credsIssuerConfig), // make_unique(Id, "current-mode", Attributes::CurrentMode::Id, credsIssuerConfig), // - make_unique(Id, "start-up-mode", Attributes::StartUpMode::Id, credsIssuerConfig), // - make_unique(Id, "on-mode", Attributes::OnMode::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // @@ -22850,8 +22828,6 @@ void registerClusterDeviceEnergyManagementMode(Commands & commands, CredentialIs make_unique(Id, credsIssuerConfig), // make_unique(Id, "supported-modes", Attributes::SupportedModes::Id, credsIssuerConfig), // make_unique(Id, "current-mode", Attributes::CurrentMode::Id, credsIssuerConfig), // - make_unique(Id, "start-up-mode", Attributes::StartUpMode::Id, credsIssuerConfig), // - make_unique(Id, "on-mode", Attributes::OnMode::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // @@ -22864,10 +22840,6 @@ void registerClusterDeviceEnergyManagementMode(Commands & commands, CredentialIs Id, "supported-modes", Attributes::SupportedModes::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "current-mode", 0, UINT8_MAX, Attributes::CurrentMode::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "start-up-mode", 0, UINT8_MAX, Attributes::StartUpMode::Id, WriteCommandType::kWrite, credsIssuerConfig), // - make_unique>>(Id, "on-mode", 0, UINT8_MAX, Attributes::OnMode::Id, - WriteCommandType::kWrite, credsIssuerConfig), // make_unique>>( Id, "generated-command-list", Attributes::GeneratedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // @@ -22884,8 +22856,6 @@ void registerClusterDeviceEnergyManagementMode(Commands & commands, CredentialIs make_unique(Id, credsIssuerConfig), // make_unique(Id, "supported-modes", Attributes::SupportedModes::Id, credsIssuerConfig), // make_unique(Id, "current-mode", Attributes::CurrentMode::Id, credsIssuerConfig), // - make_unique(Id, "start-up-mode", Attributes::StartUpMode::Id, credsIssuerConfig), // - make_unique(Id, "on-mode", Attributes::OnMode::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // diff --git a/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp b/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp index d49df9e342986f..afd4cc609368ef 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp +++ b/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp @@ -15147,16 +15147,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogValue("CurrentMode", 1, value); } - case EnergyEvseMode::Attributes::StartUpMode::Id: { - chip::app::DataModel::Nullable value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("StartUpMode", 1, value); - } - case EnergyEvseMode::Attributes::OnMode::Id: { - chip::app::DataModel::Nullable value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("OnMode", 1, value); - } case EnergyEvseMode::Attributes::GeneratedCommandList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -15204,16 +15194,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogValue("CurrentMode", 1, value); } - case WaterHeaterMode::Attributes::StartUpMode::Id: { - chip::app::DataModel::Nullable value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("StartUpMode", 1, value); - } - case WaterHeaterMode::Attributes::OnMode::Id: { - chip::app::DataModel::Nullable value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("OnMode", 1, value); - } case WaterHeaterMode::Attributes::GeneratedCommandList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -15262,16 +15242,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogValue("CurrentMode", 1, value); } - case DeviceEnergyManagementMode::Attributes::StartUpMode::Id: { - chip::app::DataModel::Nullable value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("StartUpMode", 1, value); - } - case DeviceEnergyManagementMode::Attributes::OnMode::Id: { - chip::app::DataModel::Nullable value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("OnMode", 1, value); - } case DeviceEnergyManagementMode::Attributes::GeneratedCommandList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); diff --git a/zzz_generated/chip-tool/zap-generated/cluster/logging/EntryToText.cpp b/zzz_generated/chip-tool/zap-generated/cluster/logging/EntryToText.cpp index 5aa0a783f8bfac..faafa6df9dd627 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/logging/EntryToText.cpp +++ b/zzz_generated/chip-tool/zap-generated/cluster/logging/EntryToText.cpp @@ -2635,10 +2635,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "SupportedModes"; case chip::app::Clusters::EnergyEvseMode::Attributes::CurrentMode::Id: return "CurrentMode"; - case chip::app::Clusters::EnergyEvseMode::Attributes::StartUpMode::Id: - return "StartUpMode"; - case chip::app::Clusters::EnergyEvseMode::Attributes::OnMode::Id: - return "OnMode"; case chip::app::Clusters::EnergyEvseMode::Attributes::GeneratedCommandList::Id: return "GeneratedCommandList"; case chip::app::Clusters::EnergyEvseMode::Attributes::AcceptedCommandList::Id: @@ -2662,10 +2658,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "SupportedModes"; case chip::app::Clusters::WaterHeaterMode::Attributes::CurrentMode::Id: return "CurrentMode"; - case chip::app::Clusters::WaterHeaterMode::Attributes::StartUpMode::Id: - return "StartUpMode"; - case chip::app::Clusters::WaterHeaterMode::Attributes::OnMode::Id: - return "OnMode"; case chip::app::Clusters::WaterHeaterMode::Attributes::GeneratedCommandList::Id: return "GeneratedCommandList"; case chip::app::Clusters::WaterHeaterMode::Attributes::AcceptedCommandList::Id: @@ -2689,10 +2681,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "SupportedModes"; case chip::app::Clusters::DeviceEnergyManagementMode::Attributes::CurrentMode::Id: return "CurrentMode"; - case chip::app::Clusters::DeviceEnergyManagementMode::Attributes::StartUpMode::Id: - return "StartUpMode"; - case chip::app::Clusters::DeviceEnergyManagementMode::Attributes::OnMode::Id: - return "OnMode"; case chip::app::Clusters::DeviceEnergyManagementMode::Attributes::GeneratedCommandList::Id: return "GeneratedCommandList"; case chip::app::Clusters::DeviceEnergyManagementMode::Attributes::AcceptedCommandList::Id: diff --git a/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h b/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h index ac56d68687951d..cecd156144f022 100644 --- a/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h +++ b/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h @@ -88045,8 +88045,6 @@ class SubscribeAttributePowerTopologyClusterRevision : public SubscribeAttribute | Attributes: | | | * SupportedModes | 0x0000 | | * CurrentMode | 0x0001 | -| * StartUpMode | 0x0002 | -| * OnMode | 0x0003 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | | * EventList | 0xFFFA | @@ -88289,264 +88287,6 @@ class SubscribeAttributeEnergyEvseModeCurrentMode : public SubscribeAttribute { #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL -/* - * Attribute StartUpMode - */ -class ReadEnergyEvseModeStartUpMode : public ReadAttribute { -public: - ReadEnergyEvseModeStartUpMode() - : ReadAttribute("start-up-mode") - { - } - - ~ReadEnergyEvseModeStartUpMode() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::EnergyEvseMode::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::EnergyEvseMode::Attributes::StartUpMode::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterEnergyEVSEMode alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeStartUpModeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { - NSLog(@"EnergyEVSEMode.StartUpMode response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("EnergyEVSEMode StartUpMode read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class WriteEnergyEvseModeStartUpMode : public WriteAttribute { -public: - WriteEnergyEvseModeStartUpMode() - : WriteAttribute("start-up-mode") - { - AddArgument("attr-name", "start-up-mode"); - AddArgument("attr-value", 0, UINT8_MAX, &mValue); - WriteAttribute::AddArguments(); - } - - ~WriteEnergyEvseModeStartUpMode() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::EnergyEvseMode::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::EnergyEvseMode::Attributes::StartUpMode::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") WriteAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterEnergyEVSEMode alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRWriteParams alloc] init]; - params.timedWriteTimeout = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil; - params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil; - NSNumber * _Nullable value = nil; - if (!mValue.IsNull()) { - value = [NSNumber numberWithUnsignedChar:mValue.Value()]; - } - - [cluster writeAttributeStartUpModeWithValue:value params:params completion:^(NSError * _Nullable error) { - if (error != nil) { - LogNSError("EnergyEVSEMode StartUpMode write Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } - -private: - chip::app::DataModel::Nullable mValue; -}; - -class SubscribeAttributeEnergyEvseModeStartUpMode : public SubscribeAttribute { -public: - SubscribeAttributeEnergyEvseModeStartUpMode() - : SubscribeAttribute("start-up-mode") - { - } - - ~SubscribeAttributeEnergyEvseModeStartUpMode() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::EnergyEvseMode::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::EnergyEvseMode::Attributes::StartUpMode::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterEnergyEVSEMode alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeStartUpModeWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) { - NSLog(@"EnergyEVSEMode.StartUpMode response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute OnMode - */ -class ReadEnergyEvseModeOnMode : public ReadAttribute { -public: - ReadEnergyEvseModeOnMode() - : ReadAttribute("on-mode") - { - } - - ~ReadEnergyEvseModeOnMode() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::EnergyEvseMode::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::EnergyEvseMode::Attributes::OnMode::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterEnergyEVSEMode alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeOnModeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { - NSLog(@"EnergyEVSEMode.OnMode response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("EnergyEVSEMode OnMode read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class WriteEnergyEvseModeOnMode : public WriteAttribute { -public: - WriteEnergyEvseModeOnMode() - : WriteAttribute("on-mode") - { - AddArgument("attr-name", "on-mode"); - AddArgument("attr-value", 0, UINT8_MAX, &mValue); - WriteAttribute::AddArguments(); - } - - ~WriteEnergyEvseModeOnMode() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::EnergyEvseMode::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::EnergyEvseMode::Attributes::OnMode::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") WriteAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterEnergyEVSEMode alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRWriteParams alloc] init]; - params.timedWriteTimeout = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil; - params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil; - NSNumber * _Nullable value = nil; - if (!mValue.IsNull()) { - value = [NSNumber numberWithUnsignedChar:mValue.Value()]; - } - - [cluster writeAttributeOnModeWithValue:value params:params completion:^(NSError * _Nullable error) { - if (error != nil) { - LogNSError("EnergyEVSEMode OnMode write Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } - -private: - chip::app::DataModel::Nullable mValue; -}; - -class SubscribeAttributeEnergyEvseModeOnMode : public SubscribeAttribute { -public: - SubscribeAttributeEnergyEvseModeOnMode() - : SubscribeAttribute("on-mode") - { - } - - ~SubscribeAttributeEnergyEvseModeOnMode() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::EnergyEvseMode::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::EnergyEvseMode::Attributes::OnMode::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterEnergyEVSEMode alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeOnModeWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) { - NSLog(@"EnergyEVSEMode.OnMode response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - /* * Attribute GeneratedCommandList */ @@ -89066,8 +88806,6 @@ class SubscribeAttributeEnergyEvseModeClusterRevision : public SubscribeAttribut | Attributes: | | | * SupportedModes | 0x0000 | | * CurrentMode | 0x0001 | -| * StartUpMode | 0x0002 | -| * OnMode | 0x0003 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | | * EventList | 0xFFFA | @@ -89310,264 +89048,6 @@ class SubscribeAttributeWaterHeaterModeCurrentMode : public SubscribeAttribute { #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL -/* - * Attribute StartUpMode - */ -class ReadWaterHeaterModeStartUpMode : public ReadAttribute { -public: - ReadWaterHeaterModeStartUpMode() - : ReadAttribute("start-up-mode") - { - } - - ~ReadWaterHeaterModeStartUpMode() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterMode::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::WaterHeaterMode::Attributes::StartUpMode::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterWaterHeaterMode alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeStartUpModeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { - NSLog(@"WaterHeaterMode.StartUpMode response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("WaterHeaterMode StartUpMode read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class WriteWaterHeaterModeStartUpMode : public WriteAttribute { -public: - WriteWaterHeaterModeStartUpMode() - : WriteAttribute("start-up-mode") - { - AddArgument("attr-name", "start-up-mode"); - AddArgument("attr-value", 0, UINT8_MAX, &mValue); - WriteAttribute::AddArguments(); - } - - ~WriteWaterHeaterModeStartUpMode() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterMode::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::WaterHeaterMode::Attributes::StartUpMode::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") WriteAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterWaterHeaterMode alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRWriteParams alloc] init]; - params.timedWriteTimeout = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil; - params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil; - NSNumber * _Nullable value = nil; - if (!mValue.IsNull()) { - value = [NSNumber numberWithUnsignedChar:mValue.Value()]; - } - - [cluster writeAttributeStartUpModeWithValue:value params:params completion:^(NSError * _Nullable error) { - if (error != nil) { - LogNSError("WaterHeaterMode StartUpMode write Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } - -private: - chip::app::DataModel::Nullable mValue; -}; - -class SubscribeAttributeWaterHeaterModeStartUpMode : public SubscribeAttribute { -public: - SubscribeAttributeWaterHeaterModeStartUpMode() - : SubscribeAttribute("start-up-mode") - { - } - - ~SubscribeAttributeWaterHeaterModeStartUpMode() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterMode::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::WaterHeaterMode::Attributes::StartUpMode::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterWaterHeaterMode alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeStartUpModeWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) { - NSLog(@"WaterHeaterMode.StartUpMode response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute OnMode - */ -class ReadWaterHeaterModeOnMode : public ReadAttribute { -public: - ReadWaterHeaterModeOnMode() - : ReadAttribute("on-mode") - { - } - - ~ReadWaterHeaterModeOnMode() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterMode::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::WaterHeaterMode::Attributes::OnMode::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterWaterHeaterMode alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeOnModeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { - NSLog(@"WaterHeaterMode.OnMode response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("WaterHeaterMode OnMode read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class WriteWaterHeaterModeOnMode : public WriteAttribute { -public: - WriteWaterHeaterModeOnMode() - : WriteAttribute("on-mode") - { - AddArgument("attr-name", "on-mode"); - AddArgument("attr-value", 0, UINT8_MAX, &mValue); - WriteAttribute::AddArguments(); - } - - ~WriteWaterHeaterModeOnMode() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterMode::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::WaterHeaterMode::Attributes::OnMode::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") WriteAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterWaterHeaterMode alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRWriteParams alloc] init]; - params.timedWriteTimeout = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil; - params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil; - NSNumber * _Nullable value = nil; - if (!mValue.IsNull()) { - value = [NSNumber numberWithUnsignedChar:mValue.Value()]; - } - - [cluster writeAttributeOnModeWithValue:value params:params completion:^(NSError * _Nullable error) { - if (error != nil) { - LogNSError("WaterHeaterMode OnMode write Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } - -private: - chip::app::DataModel::Nullable mValue; -}; - -class SubscribeAttributeWaterHeaterModeOnMode : public SubscribeAttribute { -public: - SubscribeAttributeWaterHeaterModeOnMode() - : SubscribeAttribute("on-mode") - { - } - - ~SubscribeAttributeWaterHeaterModeOnMode() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterMode::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::WaterHeaterMode::Attributes::OnMode::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterWaterHeaterMode alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeOnModeWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) { - NSLog(@"WaterHeaterMode.OnMode response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - /* * Attribute GeneratedCommandList */ @@ -90087,8 +89567,6 @@ class SubscribeAttributeWaterHeaterModeClusterRevision : public SubscribeAttribu | Attributes: | | | * SupportedModes | 0x0000 | | * CurrentMode | 0x0001 | -| * StartUpMode | 0x0002 | -| * OnMode | 0x0003 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | | * EventList | 0xFFFA | @@ -90331,264 +89809,6 @@ class SubscribeAttributeDeviceEnergyManagementModeCurrentMode : public Subscribe #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL -/* - * Attribute StartUpMode - */ -class ReadDeviceEnergyManagementModeStartUpMode : public ReadAttribute { -public: - ReadDeviceEnergyManagementModeStartUpMode() - : ReadAttribute("start-up-mode") - { - } - - ~ReadDeviceEnergyManagementModeStartUpMode() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::DeviceEnergyManagementMode::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::DeviceEnergyManagementMode::Attributes::StartUpMode::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterDeviceEnergyManagementMode alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeStartUpModeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { - NSLog(@"DeviceEnergyManagementMode.StartUpMode response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("DeviceEnergyManagementMode StartUpMode read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class WriteDeviceEnergyManagementModeStartUpMode : public WriteAttribute { -public: - WriteDeviceEnergyManagementModeStartUpMode() - : WriteAttribute("start-up-mode") - { - AddArgument("attr-name", "start-up-mode"); - AddArgument("attr-value", 0, UINT8_MAX, &mValue); - WriteAttribute::AddArguments(); - } - - ~WriteDeviceEnergyManagementModeStartUpMode() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::DeviceEnergyManagementMode::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::DeviceEnergyManagementMode::Attributes::StartUpMode::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") WriteAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterDeviceEnergyManagementMode alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRWriteParams alloc] init]; - params.timedWriteTimeout = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil; - params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil; - NSNumber * _Nullable value = nil; - if (!mValue.IsNull()) { - value = [NSNumber numberWithUnsignedChar:mValue.Value()]; - } - - [cluster writeAttributeStartUpModeWithValue:value params:params completion:^(NSError * _Nullable error) { - if (error != nil) { - LogNSError("DeviceEnergyManagementMode StartUpMode write Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } - -private: - chip::app::DataModel::Nullable mValue; -}; - -class SubscribeAttributeDeviceEnergyManagementModeStartUpMode : public SubscribeAttribute { -public: - SubscribeAttributeDeviceEnergyManagementModeStartUpMode() - : SubscribeAttribute("start-up-mode") - { - } - - ~SubscribeAttributeDeviceEnergyManagementModeStartUpMode() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::DeviceEnergyManagementMode::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::DeviceEnergyManagementMode::Attributes::StartUpMode::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterDeviceEnergyManagementMode alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeStartUpModeWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) { - NSLog(@"DeviceEnergyManagementMode.StartUpMode response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute OnMode - */ -class ReadDeviceEnergyManagementModeOnMode : public ReadAttribute { -public: - ReadDeviceEnergyManagementModeOnMode() - : ReadAttribute("on-mode") - { - } - - ~ReadDeviceEnergyManagementModeOnMode() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::DeviceEnergyManagementMode::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::DeviceEnergyManagementMode::Attributes::OnMode::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterDeviceEnergyManagementMode alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeOnModeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { - NSLog(@"DeviceEnergyManagementMode.OnMode response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("DeviceEnergyManagementMode OnMode read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class WriteDeviceEnergyManagementModeOnMode : public WriteAttribute { -public: - WriteDeviceEnergyManagementModeOnMode() - : WriteAttribute("on-mode") - { - AddArgument("attr-name", "on-mode"); - AddArgument("attr-value", 0, UINT8_MAX, &mValue); - WriteAttribute::AddArguments(); - } - - ~WriteDeviceEnergyManagementModeOnMode() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::DeviceEnergyManagementMode::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::DeviceEnergyManagementMode::Attributes::OnMode::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") WriteAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterDeviceEnergyManagementMode alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRWriteParams alloc] init]; - params.timedWriteTimeout = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil; - params.dataVersion = mDataVersion.HasValue() ? [NSNumber numberWithUnsignedInt:mDataVersion.Value()] : nil; - NSNumber * _Nullable value = nil; - if (!mValue.IsNull()) { - value = [NSNumber numberWithUnsignedChar:mValue.Value()]; - } - - [cluster writeAttributeOnModeWithValue:value params:params completion:^(NSError * _Nullable error) { - if (error != nil) { - LogNSError("DeviceEnergyManagementMode OnMode write Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } - -private: - chip::app::DataModel::Nullable mValue; -}; - -class SubscribeAttributeDeviceEnergyManagementModeOnMode : public SubscribeAttribute { -public: - SubscribeAttributeDeviceEnergyManagementModeOnMode() - : SubscribeAttribute("on-mode") - { - } - - ~SubscribeAttributeDeviceEnergyManagementModeOnMode() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::DeviceEnergyManagementMode::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::DeviceEnergyManagementMode::Attributes::OnMode::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterDeviceEnergyManagementMode alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeOnModeWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) { - NSLog(@"DeviceEnergyManagementMode.OnMode response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - /* * Attribute GeneratedCommandList */ @@ -191040,16 +190260,6 @@ void registerClusterEnergyEvseMode(Commands & commands) make_unique(), // make_unique(), // #endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // @@ -191102,16 +190312,6 @@ void registerClusterWaterHeaterMode(Commands & commands) make_unique(), // make_unique(), // #endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // @@ -191164,16 +190364,6 @@ void registerClusterDeviceEnergyManagementMode(Commands & commands) make_unique(), // make_unique(), // #endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // From 6054fe155655d1d19b62ccd3276eff1a99b95180 Mon Sep 17 00:00:00 2001 From: Yufeng Wang Date: Mon, 21 Oct 2024 19:31:54 -0700 Subject: [PATCH 058/149] [Fabric-Sync] Integrate fabric bridge functionalities into fabric-sync (#36166) --- examples/fabric-sync/bridge/BUILD.gn | 12 +- .../BridgedAdministratorCommissioning.h | 58 +++ .../bridge/include/BridgedDevice.h | 92 +++++ .../BridgedDeviceBasicInformationImpl.h | 32 ++ .../bridge/include/BridgedDeviceManager.h | 136 +++++++ .../src/BridgedAdministratorCommissioning.cpp | 81 ++++ .../fabric-sync/bridge/src/BridgedDevice.cpp | 118 ++++++ .../src/BridgedDeviceBasicInformationImpl.cpp | 107 ++++++ .../bridge/src/BridgedDeviceManager.cpp | 345 ++++++++++++++++++ 9 files changed, 980 insertions(+), 1 deletion(-) create mode 100644 examples/fabric-sync/bridge/include/BridgedAdministratorCommissioning.h create mode 100644 examples/fabric-sync/bridge/include/BridgedDevice.h create mode 100644 examples/fabric-sync/bridge/include/BridgedDeviceBasicInformationImpl.h create mode 100644 examples/fabric-sync/bridge/include/BridgedDeviceManager.h create mode 100644 examples/fabric-sync/bridge/src/BridgedAdministratorCommissioning.cpp create mode 100644 examples/fabric-sync/bridge/src/BridgedDevice.cpp create mode 100644 examples/fabric-sync/bridge/src/BridgedDeviceBasicInformationImpl.cpp create mode 100644 examples/fabric-sync/bridge/src/BridgedDeviceManager.cpp diff --git a/examples/fabric-sync/bridge/BUILD.gn b/examples/fabric-sync/bridge/BUILD.gn index cdf3671b7d1cc5..310496bc54d06a 100644 --- a/examples/fabric-sync/bridge/BUILD.gn +++ b/examples/fabric-sync/bridge/BUILD.gn @@ -40,7 +40,17 @@ source_set("fabric-bridge-common") { source_set("fabric-bridge-lib") { public_configs = [ ":config" ] - sources = [ "include/CHIPProjectAppConfig.h" ] + sources = [ + "include/BridgedAdministratorCommissioning.h", + "include/BridgedDevice.h", + "include/BridgedDeviceBasicInformationImpl.h", + "include/BridgedDeviceManager.h", + "include/CHIPProjectAppConfig.h", + "src/BridgedAdministratorCommissioning.cpp", + "src/BridgedDevice.cpp", + "src/BridgedDeviceBasicInformationImpl.cpp", + "src/BridgedDeviceManager.cpp", + ] deps = [ "${chip_root}/examples/fabric-sync/bridge:fabric-bridge-common", diff --git a/examples/fabric-sync/bridge/include/BridgedAdministratorCommissioning.h b/examples/fabric-sync/bridge/include/BridgedAdministratorCommissioning.h new file mode 100644 index 00000000000000..06fd9026d44225 --- /dev/null +++ b/examples/fabric-sync/bridge/include/BridgedAdministratorCommissioning.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include + +/** + * @brief CADMIN cluster implementation for handling attribute interactions of bridged device endpoints. + * + * The current Administrator Commissioning Cluster server's zap generated code will automatically + * register an Attribute Access Interface for the root node endpoint implementation. In order to + * properly respond to a read attribute for bridged devices we are representing, we override the + * currently registered Attribute Interface such that we are first to receive any read attribute + * request on Administrator Commissioning Cluster, and if it is not an endpoint for a device we + * are a bridge for we redirect to the default cluster server implementation of Administrator + * Commissioning Cluster. + */ +class BridgedAdministratorCommissioning : public chip::app::AttributeAccessInterface +{ +public: + // Register for the AdministratorCommissioning cluster on all endpoints. + BridgedAdministratorCommissioning() : + AttributeAccessInterface(chip::NullOptional, chip::app::Clusters::AdministratorCommissioning::Id) + {} + + CHIP_ERROR Init(); + + CHIP_ERROR Read(const chip::app::ConcreteReadAttributePath & aPath, chip::app::AttributeValueEncoder & aEncoder) override; + + // We do not allow writing to CADMIN attributes of a bridged device endpoint. We simply redirect + // write requests to the original attribute interface. + CHIP_ERROR Write(const chip::app::ConcreteDataAttributePath & aPath, chip::app::AttributeValueDecoder & aDecoder) override + { + VerifyOrDie(mOriginalAttributeInterface); + return mOriginalAttributeInterface->Write(aPath, aDecoder); + } + +private: + // If mOriginalAttributeInterface is removed from here, the class description needs to be updated + // to reflect this change. + chip::app::AttributeAccessInterface * mOriginalAttributeInterface = nullptr; +}; diff --git a/examples/fabric-sync/bridge/include/BridgedDevice.h b/examples/fabric-sync/bridge/include/BridgedDevice.h new file mode 100644 index 00000000000000..d2c5a64b9ef4b7 --- /dev/null +++ b/examples/fabric-sync/bridge/include/BridgedDevice.h @@ -0,0 +1,92 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include + +#include + +class BridgedDevice +{ +public: + /// Defines all attributes that we keep track of for a bridged device + struct BridgedAttributes + { + std::string uniqueId; + std::string vendorName; + uint16_t vendorId = 0; + std::string productName; + uint16_t productId = 0; + std::string nodeLabel; + uint16_t hardwareVersion = 0; + std::string hardwareVersionString; + uint32_t softwareVersion = 0; + std::string softwareVersionString; + }; + + struct AdminCommissioningAttributes + { + chip::app::Clusters::AdministratorCommissioning::CommissioningWindowStatusEnum commissioningWindowStatus = + chip::app::Clusters::AdministratorCommissioning::CommissioningWindowStatusEnum::kWindowNotOpen; + std::optional openerFabricIndex = std::nullopt; + std::optional openerVendorId = std::nullopt; + }; + + BridgedDevice(chip::ScopedNodeId scopedNodeId); + virtual ~BridgedDevice() = default; + + [[nodiscard]] bool IsReachable() const { return mReachable; } + void SetReachable(bool reachable); + // Reachability attribute changed and requires marking attribute as dirty and sending + // event. + void ReachableChanged(bool reachable); + + void LogActiveChangeEvent(uint32_t promisedActiveDurationMs); + + [[nodiscard]] bool IsIcd() const { return mIsIcd; } + void SetIcd(bool icd) { mIsIcd = icd; } + + inline void SetEndpointId(chip::EndpointId id) { mEndpointId = id; }; + inline chip::EndpointId GetEndpointId() { return mEndpointId; }; + inline chip::ScopedNodeId GetScopedNodeId() { return mScopedNodeId; }; + inline void SetParentEndpointId(chip::EndpointId id) { mParentEndpointId = id; }; + inline chip::EndpointId GetParentEndpointId() { return mParentEndpointId; }; + + [[nodiscard]] const BridgedAttributes & GetBridgedAttributes() const { return mAttributes; } + void SetBridgedAttributes(const BridgedAttributes & value) { mAttributes = value; } + + void SetAdminCommissioningAttributes(const AdminCommissioningAttributes & aAdminCommissioningAttributes); + const AdminCommissioningAttributes & GetAdminCommissioningAttributes() const { return mAdminCommissioningAttributes; } + + /// Convenience method to set just the unique id of a bridged device as it + /// is one of the few attributes that is not always bulk-set + void SetUniqueId(const std::string & value) { mAttributes.uniqueId = value; } + +protected: + bool mReachable = false; + bool mIsIcd = false; + + chip::ScopedNodeId mScopedNodeId; + chip::EndpointId mEndpointId = 0; + chip::EndpointId mParentEndpointId = 0; + + BridgedAttributes mAttributes; + AdminCommissioningAttributes mAdminCommissioningAttributes; +}; diff --git a/examples/fabric-sync/bridge/include/BridgedDeviceBasicInformationImpl.h b/examples/fabric-sync/bridge/include/BridgedDeviceBasicInformationImpl.h new file mode 100644 index 00000000000000..23403438ab2be8 --- /dev/null +++ b/examples/fabric-sync/bridge/include/BridgedDeviceBasicInformationImpl.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#pragma once + +#include +#include + +class BridgedDeviceBasicInformationImpl : public chip::app::AttributeAccessInterface +{ +public: + BridgedDeviceBasicInformationImpl() : + chip::app::AttributeAccessInterface(chip::NullOptional /* endpointId */, + chip::app::Clusters::BridgedDeviceBasicInformation::Id) + {} + + // AttributeAccessInterface implementation + CHIP_ERROR Read(const chip::app::ConcreteReadAttributePath & path, chip::app::AttributeValueEncoder & encoder) override; + CHIP_ERROR Write(const chip::app::ConcreteDataAttributePath & path, chip::app::AttributeValueDecoder & decoder) override; +}; diff --git a/examples/fabric-sync/bridge/include/BridgedDeviceManager.h b/examples/fabric-sync/bridge/include/BridgedDeviceManager.h new file mode 100644 index 00000000000000..127898fc5b2fab --- /dev/null +++ b/examples/fabric-sync/bridge/include/BridgedDeviceManager.h @@ -0,0 +1,136 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include + +#include "BridgedDevice.h" + +#include + +class BridgedDeviceManager +{ +public: + BridgedDeviceManager() = default; + + /** + * @brief Initializes the BridgedDeviceManager. + * + * This function sets up the initial state of the BridgedDeviceManager, clearing + * any existing devices and setting the starting dynamic endpoint ID. + */ + void Init(); + + /** + * @brief Adds a device to a dynamic endpoint. + * + * This function attempts to add a device to a dynamic endpoint. It tries to find an available + * endpoint slot and retries the addition process up to a specified maximum number of times if + * the endpoint already exists. If the addition is successful, it returns the index of the + * dynamic endpoint; + * + * Ensures that the device has a unique id: + * - device MUST set its unique id if any BEFORE calling this method + * - if no unique id (i.e. empty string), a new unique id will be generated + * - Add will fail if the unique id is not unique + * + * @param dev A pointer to the device to be added. + * @param parentEndpointId The parent endpoint ID. Defaults to an invalid endpoint ID. + * @return int The index of the dynamic endpoint if successful, nullopt otherwise + */ + std::optional AddDeviceEndpoint(std::unique_ptr dev, + chip::EndpointId parentEndpointId = chip::kInvalidEndpointId); + + /** + * @brief Removes a device from a dynamic endpoint. + * + * This function attempts to remove a device from a dynamic endpoint by iterating through the + * available endpoints and checking if the device matches. If the device is found, it clears the + * dynamic endpoint, logs the removal, and returns the index of the removed endpoint. + * If the device is not found, it returns -1. + * + * @param dev A pointer to the device to be removed. + * @return int The index of the removed dynamic endpoint if successful, -1 otherwise. + */ + int RemoveDeviceEndpoint(BridgedDevice * dev); + + /** + * @brief Gets a device from its endpoint ID. + * + * This function iterates through the available devices and returns the device that matches the + * specified endpoint ID. If no device matches the endpoint ID, it returns nullptr. + * + * @param endpointId The endpoint ID of the device to be retrieved. + * @return BridgedDevice* A pointer to the device if found, nullptr otherwise. + */ + BridgedDevice * GetDevice(chip::EndpointId endpointId) const; + + /** + * @brief Gets a device from its ScopedNodeId. + * + * This function iterates through the available devices and returns the device that matches the + * specified ScopedNodeId. If no device matches the ScopedNodeId, it returns nullptr. + * + * @param scopedNodeId The ScopedNodeId of the device to be retrieved. + * @return BridgedDevice* A pointer to the device if found, nullptr otherwise. + */ + BridgedDevice * GetDeviceByScopedNodeId(chip::ScopedNodeId scopedNodeId) const; + + /** + * @brief Removes a device from a dynamic endpoint by its ScopedNodeId. + * + * This function attempts to remove a device and the associated dynamic endpoint by iterating through + * the available device and checking if the device matches the specified ScopedNodeId. If the device is + * found, it removes the dynamic endpoint. + * + * @param scopedNodeId The ScopedNodeId of the device to be removed. + * @return unsigned of the index of the removed dynamic endpoint if successful, nullopt otherwise. + */ + std::optional RemoveDeviceByScopedNodeId(chip::ScopedNodeId scopedNodeId); + + /** + * Finds the device with the given unique id (if any) + */ + BridgedDevice * GetDeviceByUniqueId(const std::string & id); + +private: + friend BridgedDeviceManager & BridgeDeviceMgr(); + + /** + * Creates a new unique ID that is not used by any other mDevice + */ + std::string GenerateUniqueId(); + + static BridgedDeviceManager sInstance; + + chip::EndpointId mCurrentEndpointId; + chip::EndpointId mFirstDynamicEndpointId; + std::unique_ptr mDevices[CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT + 1]; +}; + +/** + * Returns the public interface of the BridgedDeviceManager singleton object. + * + * Applications should use this to access features of the BridgedDeviceManager + * object. + */ +inline BridgedDeviceManager & BridgeDeviceMgr() +{ + return BridgedDeviceManager::sInstance; +} diff --git a/examples/fabric-sync/bridge/src/BridgedAdministratorCommissioning.cpp b/examples/fabric-sync/bridge/src/BridgedAdministratorCommissioning.cpp new file mode 100644 index 00000000000000..a0d87cbb3b81ef --- /dev/null +++ b/examples/fabric-sync/bridge/src/BridgedAdministratorCommissioning.cpp @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "BridgedAdministratorCommissioning.h" + +#include "BridgedDevice.h" +#include "BridgedDeviceManager.h" +#include + +using namespace chip; +using namespace chip::app; +using namespace chip::app::Clusters; +using namespace chip::app::Clusters::AdministratorCommissioning; + +CHIP_ERROR BridgedAdministratorCommissioning::Init() +{ + // We expect initialization after emberAfInit(). This allows us to unregister the existing + // AccessAttributeInterface for AdministratorCommissioning and register ourselves, ensuring we + // get the callback for reading attribute. If the read is not intended for a bridged device we will + // forward it to the original attribute interface that we are unregistering. + mOriginalAttributeInterface = AttributeAccessInterfaceRegistry::Instance().Get(kRootEndpointId, AdministratorCommissioning::Id); + VerifyOrReturnError(mOriginalAttributeInterface, CHIP_ERROR_INTERNAL); + AttributeAccessInterfaceRegistry::Instance().Unregister(mOriginalAttributeInterface); + VerifyOrDie(AttributeAccessInterfaceRegistry::Instance().Register(this)); + return CHIP_NO_ERROR; +} + +CHIP_ERROR BridgedAdministratorCommissioning::Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder) +{ + VerifyOrDie(aPath.mClusterId == Clusters::AdministratorCommissioning::Id); + EndpointId endpointId = aPath.mEndpointId; + BridgedDevice * device = BridgeDeviceMgr().GetDevice(endpointId); + + if (!device) + { + VerifyOrDie(mOriginalAttributeInterface); + return mOriginalAttributeInterface->Read(aPath, aEncoder); + } + auto attr = device->GetAdminCommissioningAttributes(); + + switch (aPath.mAttributeId) + { + case Attributes::WindowStatus::Id: { + return aEncoder.Encode(attr.commissioningWindowStatus); + } + case Attributes::AdminFabricIndex::Id: { + DataModel::Nullable encodeableFabricIndex = DataModel::NullNullable; + if (attr.openerFabricIndex.has_value()) + { + encodeableFabricIndex.SetNonNull(attr.openerFabricIndex.value()); + } + return aEncoder.Encode(encodeableFabricIndex); + } + case Attributes::AdminVendorId::Id: { + DataModel::Nullable encodeableVendorId = DataModel::NullNullable; + if (attr.openerVendorId.has_value()) + { + encodeableVendorId.SetNonNull(attr.openerVendorId.value()); + } + return aEncoder.Encode(encodeableVendorId); + } + default: + break; + } + + return CHIP_NO_ERROR; +} diff --git a/examples/fabric-sync/bridge/src/BridgedDevice.cpp b/examples/fabric-sync/bridge/src/BridgedDevice.cpp new file mode 100644 index 00000000000000..f462d1cce6efd5 --- /dev/null +++ b/examples/fabric-sync/bridge/src/BridgedDevice.cpp @@ -0,0 +1,118 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "BridgedDevice.h" + +#include + +#include +#include +#include + +using namespace chip; +using namespace chip::app::Clusters::Actions; + +BridgedDevice::BridgedDevice(ScopedNodeId scopedNodeId) +{ + mReachable = false; + mScopedNodeId = scopedNodeId; + mEndpointId = kInvalidEndpointId; +} + +void BridgedDevice::LogActiveChangeEvent(uint32_t promisedActiveDurationMs) +{ + EndpointId endpointId = mEndpointId; + + DeviceLayer::SystemLayer().ScheduleLambda([endpointId, promisedActiveDurationMs]() { + app::Clusters::BridgedDeviceBasicInformation::Events::ActiveChanged::Type event{}; + event.promisedActiveDuration = promisedActiveDurationMs; + EventNumber eventNumber = 0; + + CHIP_ERROR err = app::LogEvent(event, endpointId, eventNumber); + if (err != CHIP_NO_ERROR) + { + ChipLogProgress(NotSpecified, "LogEvent for ActiveChanged failed %s", err.AsString()); + } + }); +} + +void BridgedDevice::SetReachable(bool reachable) +{ + mReachable = reachable; + + if (reachable) + { + ChipLogProgress(NotSpecified, "BridgedDevice[%s]: ONLINE", mAttributes.uniqueId.c_str()); + } + else + { + ChipLogProgress(NotSpecified, "BridgedDevice[%s]: OFFLINE", mAttributes.uniqueId.c_str()); + } +} + +void BridgedDevice::ReachableChanged(bool reachable) +{ + EndpointId endpointId = mEndpointId; + bool reachableChanged = (mReachable != reachable); + if (reachableChanged) + { + SetReachable(reachable); + DeviceLayer::SystemLayer().ScheduleLambda([endpointId]() { + MatterReportingAttributeChangeCallback(endpointId, app::Clusters::BridgedDeviceBasicInformation::Id, + app::Clusters::BridgedDeviceBasicInformation::Attributes::Reachable::Id); + + app::Clusters::BridgedDeviceBasicInformation::Events::ReachableChanged::Type event{}; + EventNumber eventNumber = 0; + + CHIP_ERROR err = app::LogEvent(event, endpointId, eventNumber); + if (err != CHIP_NO_ERROR) + { + ChipLogProgress(NotSpecified, "LogEvent for ActiveChanged failed %s", err.AsString()); + } + }); + } +} + +void BridgedDevice::SetAdminCommissioningAttributes(const AdminCommissioningAttributes & aAdminCommissioningAttributes) +{ + EndpointId endpointId = mEndpointId; + bool windowChanged = + (aAdminCommissioningAttributes.commissioningWindowStatus != mAdminCommissioningAttributes.commissioningWindowStatus); + bool fabricIndexChanged = (aAdminCommissioningAttributes.openerFabricIndex != mAdminCommissioningAttributes.openerFabricIndex); + bool vendorChanged = (aAdminCommissioningAttributes.openerVendorId != mAdminCommissioningAttributes.openerVendorId); + + mAdminCommissioningAttributes = aAdminCommissioningAttributes; + + DeviceLayer::SystemLayer().ScheduleLambda([endpointId, windowChanged, fabricIndexChanged, vendorChanged]() { + if (windowChanged) + { + MatterReportingAttributeChangeCallback(endpointId, app::Clusters::AdministratorCommissioning::Id, + app::Clusters::AdministratorCommissioning::Attributes::WindowStatus::Id); + } + if (fabricIndexChanged) + { + MatterReportingAttributeChangeCallback(endpointId, app::Clusters::AdministratorCommissioning::Id, + app::Clusters::AdministratorCommissioning::Attributes::AdminFabricIndex::Id); + } + if (vendorChanged) + { + MatterReportingAttributeChangeCallback(endpointId, app::Clusters::AdministratorCommissioning::Id, + app::Clusters::AdministratorCommissioning::Attributes::AdminVendorId::Id); + } + }); +} diff --git a/examples/fabric-sync/bridge/src/BridgedDeviceBasicInformationImpl.cpp b/examples/fabric-sync/bridge/src/BridgedDeviceBasicInformationImpl.cpp new file mode 100644 index 00000000000000..7fa48a4a158ddd --- /dev/null +++ b/examples/fabric-sync/bridge/src/BridgedDeviceBasicInformationImpl.cpp @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "BridgedDeviceBasicInformationImpl.h" + +#include "BridgedDeviceManager.h" + +#include +#include +#include + +#include + +static constexpr unsigned kBridgedDeviceBasicInformationClusterRevision = 4; + +using namespace ::chip; +using namespace ::chip::app; +using namespace ::chip::app::Clusters; + +CHIP_ERROR BridgedDeviceBasicInformationImpl::Read(const ConcreteReadAttributePath & path, AttributeValueEncoder & encoder) +{ + // Registration is done for the bridged device basic information only + VerifyOrDie(path.mClusterId == app::Clusters::BridgedDeviceBasicInformation::Id); + + BridgedDevice * dev = BridgeDeviceMgr().GetDevice(path.mEndpointId); + VerifyOrReturnError(dev != nullptr, CHIP_ERROR_NOT_FOUND); + + switch (path.mAttributeId) + { + case BasicInformation::Attributes::Reachable::Id: + encoder.Encode(dev->IsReachable()); + break; + case BasicInformation::Attributes::NodeLabel::Id: + encoder.Encode(CharSpan::fromCharString(dev->GetBridgedAttributes().nodeLabel.c_str())); + break; + case BasicInformation::Attributes::ClusterRevision::Id: + encoder.Encode(kBridgedDeviceBasicInformationClusterRevision); + break; + case BasicInformation::Attributes::FeatureMap::Id: { + BitMask features; + features.Set(Clusters::BridgedDeviceBasicInformation::Feature::kBridgedICDSupport, dev->IsIcd()); + encoder.Encode(features); + } + break; + case BasicInformation::Attributes::UniqueID::Id: + encoder.Encode(CharSpan::fromCharString(dev->GetBridgedAttributes().uniqueId.c_str())); + break; + case BasicInformation::Attributes::VendorName::Id: + encoder.Encode(CharSpan::fromCharString(dev->GetBridgedAttributes().vendorName.c_str())); + break; + case BasicInformation::Attributes::VendorID::Id: + encoder.Encode(dev->GetBridgedAttributes().vendorId); + break; + case BasicInformation::Attributes::ProductName::Id: + encoder.Encode(CharSpan::fromCharString(dev->GetBridgedAttributes().productName.c_str())); + break; + case BasicInformation::Attributes::ProductID::Id: + encoder.Encode(dev->GetBridgedAttributes().productId); + break; + case BasicInformation::Attributes::HardwareVersion::Id: + encoder.Encode(dev->GetBridgedAttributes().hardwareVersion); + break; + case BasicInformation::Attributes::HardwareVersionString::Id: + encoder.Encode(CharSpan::fromCharString(dev->GetBridgedAttributes().hardwareVersionString.c_str())); + break; + case BasicInformation::Attributes::SoftwareVersion::Id: + encoder.Encode(dev->GetBridgedAttributes().softwareVersion); + break; + case BasicInformation::Attributes::SoftwareVersionString::Id: + encoder.Encode(CharSpan::fromCharString(dev->GetBridgedAttributes().softwareVersionString.c_str())); + break; + default: + return CHIP_ERROR_INVALID_ARGUMENT; + } + return CHIP_NO_ERROR; +} + +CHIP_ERROR BridgedDeviceBasicInformationImpl::Write(const ConcreteDataAttributePath & path, AttributeValueDecoder & decoder) +{ + VerifyOrDie(path.mClusterId == app::Clusters::BridgedDeviceBasicInformation::Id); + + BridgedDevice * dev = BridgeDeviceMgr().GetDevice(path.mEndpointId); + VerifyOrReturnError(dev != nullptr, CHIP_ERROR_NOT_FOUND); + + if (!dev->IsReachable()) + { + return CHIP_ERROR_NOT_CONNECTED; + } + + ChipLogProgress(NotSpecified, "Bridged device basic information attempt to write attribute: ep=%d", path.mAttributeId); + + // nothing writable right now ... + + return CHIP_ERROR_INVALID_ARGUMENT; +} diff --git a/examples/fabric-sync/bridge/src/BridgedDeviceManager.cpp b/examples/fabric-sync/bridge/src/BridgedDeviceManager.cpp new file mode 100644 index 00000000000000..0265f912027ca0 --- /dev/null +++ b/examples/fabric-sync/bridge/src/BridgedDeviceManager.cpp @@ -0,0 +1,345 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "BridgedDeviceManager.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +using namespace chip; +using namespace chip::app; +using namespace chip::Credentials; +using namespace chip::Inet; +using namespace chip::Transport; +using namespace chip::DeviceLayer; +using namespace chip::app::Clusters; + +namespace { + +constexpr uint8_t kMaxRetries = 10; +constexpr int kNodeLabelSize = 32; +constexpr int kUniqueIdSize = 32; +constexpr int kVendorNameSize = 32; +constexpr int kProductNameSize = 32; +constexpr int kHardwareVersionSize = 64; +constexpr int kSoftwareVersionSize = 64; + +// Current ZCL implementation of Struct uses a max-size array of 254 bytes +constexpr int kDescriptorAttributeArraySize = 254; + +#define ZCL_ADMINISTRATOR_COMMISSIONING_CLUSTER_REVISION (1u) + +// ENDPOINT DEFINITIONS: +// ================================================================================= +// +// Endpoint definitions will be reused across multiple endpoints for every instance of the +// endpoint type. +// There will be no intrinsic storage for the endpoint attributes declared here. +// Instead, all attributes will be treated as EXTERNAL, and therefore all reads +// or writes to the attributes must be handled within the emberAfExternalAttributeWriteCallback +// and emberAfExternalAttributeReadCallback functions declared herein. This fits +// the typical model of a bridge, since a bridge typically maintains its own +// state database representing the devices connected to it. + +// (taken from matter-devices.xml) +#define DEVICE_TYPE_BRIDGED_NODE 0x0013 + +// Device Version for dynamic endpoints: +#define DEVICE_VERSION_DEFAULT 1 + +// --------------------------------------------------------------------------- +// +// SYNCED DEVICE ENDPOINT: contains the following clusters: +// - Descriptor +// - Bridged Device Basic Information +// - Administrator Commissioning + +// clang-format off +// Declare Descriptor cluster attributes +DECLARE_DYNAMIC_ATTRIBUTE_LIST_BEGIN(descriptorAttrs) + DECLARE_DYNAMIC_ATTRIBUTE(Descriptor::Attributes::DeviceTypeList::Id, ARRAY, kDescriptorAttributeArraySize, 0), /* device list */ + DECLARE_DYNAMIC_ATTRIBUTE(Descriptor::Attributes::ServerList::Id, ARRAY, kDescriptorAttributeArraySize, 0), /* server list */ + DECLARE_DYNAMIC_ATTRIBUTE(Descriptor::Attributes::ClientList::Id, ARRAY, kDescriptorAttributeArraySize, 0), /* client list */ + DECLARE_DYNAMIC_ATTRIBUTE(Descriptor::Attributes::PartsList::Id, ARRAY, kDescriptorAttributeArraySize, 0), /* parts list */ +DECLARE_DYNAMIC_ATTRIBUTE_LIST_END(); + +// Declare Bridged Device Basic Information cluster attributes +DECLARE_DYNAMIC_ATTRIBUTE_LIST_BEGIN(bridgedDeviceBasicAttrs) + // The attributes below are MANDATORY in the Bridged Device Information Cluster + DECLARE_DYNAMIC_ATTRIBUTE(BridgedDeviceBasicInformation::Attributes::Reachable::Id, BOOLEAN, 1, 0), + DECLARE_DYNAMIC_ATTRIBUTE(BridgedDeviceBasicInformation::Attributes::UniqueID::Id, CHAR_STRING, kUniqueIdSize, 0), + DECLARE_DYNAMIC_ATTRIBUTE(BridgedDeviceBasicInformation::Attributes::FeatureMap::Id, BITMAP32, 4, 0), + + // The attributes below are OPTIONAL in the bridged device, however they are MANDATORY in the BasicInformation cluster + // so they can always be provided if desired + DECLARE_DYNAMIC_ATTRIBUTE(BridgedDeviceBasicInformation::Attributes::VendorName::Id, CHAR_STRING, kVendorNameSize, 0), + DECLARE_DYNAMIC_ATTRIBUTE(BridgedDeviceBasicInformation::Attributes::VendorID::Id, INT16U, 2, 0), + DECLARE_DYNAMIC_ATTRIBUTE(BridgedDeviceBasicInformation::Attributes::ProductName::Id, CHAR_STRING, kProductNameSize, 0), + DECLARE_DYNAMIC_ATTRIBUTE(BridgedDeviceBasicInformation::Attributes::ProductID::Id, INT16U, 2, 0), + DECLARE_DYNAMIC_ATTRIBUTE(BridgedDeviceBasicInformation::Attributes::NodeLabel::Id, CHAR_STRING, kNodeLabelSize, 0), + DECLARE_DYNAMIC_ATTRIBUTE(BridgedDeviceBasicInformation::Attributes::HardwareVersion::Id, INT16U, 2, 0), + DECLARE_DYNAMIC_ATTRIBUTE(BridgedDeviceBasicInformation::Attributes::HardwareVersionString::Id, CHAR_STRING, + kHardwareVersionSize, 0), + DECLARE_DYNAMIC_ATTRIBUTE(BridgedDeviceBasicInformation::Attributes::SoftwareVersion::Id, INT32U, 4, 0), + DECLARE_DYNAMIC_ATTRIBUTE(BridgedDeviceBasicInformation::Attributes::SoftwareVersionString::Id, CHAR_STRING, + kSoftwareVersionSize, 0), +DECLARE_DYNAMIC_ATTRIBUTE_LIST_END(); + +// Declare Ecosystem Information cluster attributes +DECLARE_DYNAMIC_ATTRIBUTE_LIST_BEGIN(ecosystemInformationBasicAttrs) + DECLARE_DYNAMIC_ATTRIBUTE(EcosystemInformation::Attributes::DeviceDirectory::Id, ARRAY, kDescriptorAttributeArraySize, 0), + DECLARE_DYNAMIC_ATTRIBUTE(EcosystemInformation::Attributes::LocationDirectory::Id, ARRAY, kDescriptorAttributeArraySize, 0), + DECLARE_DYNAMIC_ATTRIBUTE_LIST_END(); + +// Declare Administrator Commissioning cluster attributes +DECLARE_DYNAMIC_ATTRIBUTE_LIST_BEGIN(AdministratorCommissioningAttrs) + DECLARE_DYNAMIC_ATTRIBUTE(AdministratorCommissioning::Attributes::WindowStatus::Id, ENUM8, 1, 0), + DECLARE_DYNAMIC_ATTRIBUTE(AdministratorCommissioning::Attributes::AdminFabricIndex::Id, FABRIC_IDX, 1, 0), + DECLARE_DYNAMIC_ATTRIBUTE(AdministratorCommissioning::Attributes::AdminVendorId::Id, VENDOR_ID, 2, 0), + DECLARE_DYNAMIC_ATTRIBUTE(AdministratorCommissioning::Attributes::ClusterRevision::Id, INT16U, ZCL_ADMINISTRATOR_COMMISSIONING_CLUSTER_REVISION, 0), +DECLARE_DYNAMIC_ATTRIBUTE_LIST_END(); +// clang-format on + +constexpr CommandId bridgedDeviceBasicInformationCommands[] = { + app::Clusters::BridgedDeviceBasicInformation::Commands::KeepActive::Id, + kInvalidCommandId, +}; + +constexpr CommandId administratorCommissioningCommands[] = { + app::Clusters::AdministratorCommissioning::Commands::OpenCommissioningWindow::Id, + app::Clusters::AdministratorCommissioning::Commands::OpenBasicCommissioningWindow::Id, + app::Clusters::AdministratorCommissioning::Commands::RevokeCommissioning::Id, + kInvalidCommandId, +}; + +// clang-format off +// Declare Cluster List for Bridged Node endpoint +DECLARE_DYNAMIC_CLUSTER_LIST_BEGIN(bridgedNodeClusters) + DECLARE_DYNAMIC_CLUSTER(Descriptor::Id, descriptorAttrs, ZAP_CLUSTER_MASK(SERVER), nullptr, nullptr), + DECLARE_DYNAMIC_CLUSTER(BridgedDeviceBasicInformation::Id, bridgedDeviceBasicAttrs, ZAP_CLUSTER_MASK(SERVER), nullptr, nullptr), + DECLARE_DYNAMIC_CLUSTER(EcosystemInformation::Id, ecosystemInformationBasicAttrs, ZAP_CLUSTER_MASK(SERVER), nullptr, nullptr), + DECLARE_DYNAMIC_CLUSTER(AdministratorCommissioning::Id, AdministratorCommissioningAttrs, ZAP_CLUSTER_MASK(SERVER), + administratorCommissioningCommands, nullptr) +DECLARE_DYNAMIC_CLUSTER_LIST_END; + +DECLARE_DYNAMIC_CLUSTER_LIST_BEGIN(icdBridgedNodeClusters) + DECLARE_DYNAMIC_CLUSTER(Descriptor::Id, descriptorAttrs, ZAP_CLUSTER_MASK(SERVER), nullptr, nullptr), + DECLARE_DYNAMIC_CLUSTER(BridgedDeviceBasicInformation::Id, bridgedDeviceBasicAttrs, ZAP_CLUSTER_MASK(SERVER), + bridgedDeviceBasicInformationCommands, nullptr), + DECLARE_DYNAMIC_CLUSTER(AdministratorCommissioning::Id, AdministratorCommissioningAttrs, ZAP_CLUSTER_MASK(SERVER), + administratorCommissioningCommands, nullptr) +DECLARE_DYNAMIC_CLUSTER_LIST_END; +// clang-format on + +// Declare Bridged Node endpoint +DECLARE_DYNAMIC_ENDPOINT(sBridgedNodeEndpoint, bridgedNodeClusters); +DECLARE_DYNAMIC_ENDPOINT(sIcdBridgedNodeEndpoint, icdBridgedNodeClusters); + +// TODO: this is a single version array, however we may have many +// different clusters that are independent. +DataVersion sBridgedNodeDataVersions[ArraySize(bridgedNodeClusters)]; + +const EmberAfDeviceType sBridgedDeviceTypes[] = { { DEVICE_TYPE_BRIDGED_NODE, DEVICE_VERSION_DEFAULT } }; + +} // namespace + +// Define the static member +BridgedDeviceManager BridgedDeviceManager::sInstance; + +void BridgedDeviceManager::Init() +{ + mFirstDynamicEndpointId = static_cast( + static_cast(emberAfEndpointFromIndex(static_cast(emberAfFixedEndpointCount() - 1))) + 1); + mCurrentEndpointId = mFirstDynamicEndpointId; +} + +std::optional BridgedDeviceManager::AddDeviceEndpoint(std::unique_ptr dev, + chip::EndpointId parentEndpointId) +{ + EmberAfEndpointType * ep = dev->IsIcd() ? &sIcdBridgedNodeEndpoint : &sBridgedNodeEndpoint; + + const chip::Span & deviceTypeList = Span(sBridgedDeviceTypes); + + // TODO: this shares data version among different clusters, which seems incorrect + const chip::Span & dataVersionStorage = Span(sBridgedNodeDataVersions); + + if (dev->GetBridgedAttributes().uniqueId.empty()) + { + dev->SetUniqueId(GenerateUniqueId()); + } + else if (GetDeviceByUniqueId(dev->GetBridgedAttributes().uniqueId) != nullptr) + { + ChipLogProgress(NotSpecified, "A device with unique id '%s' already exists", dev->GetBridgedAttributes().uniqueId.c_str()); + return std::nullopt; + } + + for (unsigned index = 0; index < CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT; index++) + { + if (mDevices[index]) + { + continue; + } + + for (int retryCount = 0; retryCount < kMaxRetries; retryCount++) + { + DeviceLayer::StackLock lock; + dev->SetEndpointId(mCurrentEndpointId); + dev->SetParentEndpointId(parentEndpointId); + CHIP_ERROR err = + emberAfSetDynamicEndpoint(index, mCurrentEndpointId, ep, dataVersionStorage, deviceTypeList, parentEndpointId); + if (err == CHIP_NO_ERROR) + { + ChipLogProgress(NotSpecified, "Added device with Id=[%d:0x" ChipLogFormatX64 "] to dynamic endpoint %d (index=%d)", + dev->GetScopedNodeId().GetFabricIndex(), ChipLogValueX64(dev->GetScopedNodeId().GetNodeId()), + mCurrentEndpointId, index); + mDevices[index] = std::move(dev); + return index; + } + if (err != CHIP_ERROR_ENDPOINT_EXISTS) + { + return std::nullopt; // Return error as endpoint addition failed due to an error other than endpoint already exists + } + // Increment the endpoint ID and handle wrap condition + if (++mCurrentEndpointId < mFirstDynamicEndpointId) + { + mCurrentEndpointId = mFirstDynamicEndpointId; + } + } + ChipLogError(NotSpecified, "Failed to add dynamic endpoint after %d retries", kMaxRetries); + return std::nullopt; // Return error as all retries are exhausted + } + + ChipLogProgress(NotSpecified, "Failed to add dynamic endpoint: No endpoints available!"); + return std::nullopt; +} + +int BridgedDeviceManager::RemoveDeviceEndpoint(BridgedDevice * dev) +{ + uint8_t index = 0; + while (index < CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT) + { + if (mDevices[index].get() == dev) + { + DeviceLayer::StackLock lock; + // Silence complaints about unused ep when progress logging + // disabled. + [[maybe_unused]] EndpointId ep = emberAfClearDynamicEndpoint(index); + mDevices[index] = nullptr; + ChipLogProgress(NotSpecified, "Removed device %s from dynamic endpoint %d (index=%d)", + dev->GetBridgedAttributes().uniqueId.c_str(), ep, index); + return index; + } + index++; + } + return -1; +} + +BridgedDevice * BridgedDeviceManager::GetDevice(chip::EndpointId endpointId) const +{ + for (uint8_t index = 0; index < CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT; ++index) + { + if (mDevices[index] && mDevices[index]->GetEndpointId() == endpointId) + { + return mDevices[index].get(); + } + } + return nullptr; +} + +std::string BridgedDeviceManager::GenerateUniqueId() +{ + char rand_buffer[kUniqueIdSize + 1]; + memset(rand_buffer, 0, sizeof(rand_buffer)); + + static const char kRandCharChoices[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + + while (true) + { + /// for nice viewing, prefix the generated value + memcpy(rand_buffer, "GEN-", 4); + for (unsigned idx = 4; idx < kUniqueIdSize; idx++) + { + rand_buffer[idx] = kRandCharChoices[Crypto::GetRandU8() % (sizeof(kRandCharChoices) - 1)]; + } + + // we know zero-terminated due to the memset + std::string uniqueIdChoice = rand_buffer; + + if (!GetDeviceByUniqueId(uniqueIdChoice)) + { + return uniqueIdChoice; + } + } +} + +BridgedDevice * BridgedDeviceManager::GetDeviceByUniqueId(const std::string & id) +{ + for (uint8_t index = 0; index < CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT; ++index) + { + if (mDevices[index] && mDevices[index]->GetBridgedAttributes().uniqueId == id) + { + return mDevices[index].get(); + } + } + return nullptr; +} + +BridgedDevice * BridgedDeviceManager::GetDeviceByScopedNodeId(chip::ScopedNodeId scopedNodeId) const +{ + for (uint8_t index = 0; index < CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT; ++index) + { + if (mDevices[index] && mDevices[index]->GetScopedNodeId() == scopedNodeId) + { + return mDevices[index].get(); + } + } + return nullptr; +} + +std::optional BridgedDeviceManager::RemoveDeviceByScopedNodeId(chip::ScopedNodeId scopedNodeId) +{ + for (unsigned index = 0; index < CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT; ++index) + { + if (mDevices[index] && mDevices[index]->GetScopedNodeId() == scopedNodeId) + { + DeviceLayer::StackLock lock; + EndpointId ep = emberAfClearDynamicEndpoint(index); + mDevices[index] = nullptr; + ChipLogProgress(NotSpecified, "Removed device with Id=[%d:0x" ChipLogFormatX64 "] from dynamic endpoint %d (index=%d)", + scopedNodeId.GetFabricIndex(), ChipLogValueX64(scopedNodeId.GetNodeId()), ep, index); + return index; + } + } + return std::nullopt; +} From 1eaa4b94e43c5da54fb340250515e3249ca85753 Mon Sep 17 00:00:00 2001 From: Yufeng Wang Date: Mon, 21 Oct 2024 19:37:13 -0700 Subject: [PATCH 059/149] Removed config flags inherited from tv-app (#36180) --- .../bridge/include/CHIPProjectAppConfig.h | 31 ------------------- 1 file changed, 31 deletions(-) diff --git a/examples/fabric-sync/bridge/include/CHIPProjectAppConfig.h b/examples/fabric-sync/bridge/include/CHIPProjectAppConfig.h index b2a999da741088..b1a711658d3b91 100644 --- a/examples/fabric-sync/bridge/include/CHIPProjectAppConfig.h +++ b/examples/fabric-sync/bridge/include/CHIPProjectAppConfig.h @@ -30,49 +30,18 @@ // FabricSync needs to be commissioners and likely want to be discoverable #define CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY 1 -// FabricSync can handle the memory impact of supporting a larger list -#define CHIP_DEVICE_CONFIG_UDC_MAX_TARGET_APPS 10 - // FabricSync will often enable this feature #define CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_PASSCODE 1 // FabricSync needs to be both commissioners and commissionees #define CHIP_DEVICE_CONFIG_ENABLE_BOTH_COMMISSIONER_AND_COMMISSIONEE 1 -// See issue 23625. -#define CHIP_CONFIG_UNSAFE_SUBSCRIPTION_EXCHANGE_MANAGER_USE 1 - -// FabricSync that are not commissionees, -// or that don't automatically enter commissioning mode should set this to 0 -#define CHIP_DEVICE_CONFIG_ENABLE_PAIRING_AUTOSTART 1 - -// FabricSync do not typically need this - enable for debugging -// #define CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONER_DISCOVERY_CLIENT 1 - -// Enable extended discovery, set timeout to 24 hours -#define CHIP_DEVICE_CONFIG_ENABLE_EXTENDED_DISCOVERY 1 -#define CHIP_DEVICE_CONFIG_EXTENDED_DISCOVERY_TIMEOUT_SECS (24 * 60 * 60) - -// Advertise TV device type in DNS-SD -#define CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONABLE_DEVICE_TYPE 1 - -#define CHIP_DEVICE_CONFIG_DEVICE_TYPE 35 // 0x0023 = 35 = Video Player - -// Include device name in discovery for casting use case -#define CHIP_DEVICE_CONFIG_ENABLE_COMMISSIONABLE_DEVICE_NAME 1 -#define CHIP_DEVICE_CONFIG_DEVICE_NAME "Test TV" - // Enable app platform #define CHIP_DEVICE_CONFIG_APP_PLATFORM_ENABLED 1 // overrides CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT in CHIPProjectConfig #define CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT 16 -// For casting, we need to allow more ACL entries, and more complex entries -#define CHIP_CONFIG_EXAMPLE_ACCESS_CONTROL_MAX_TARGETS_PER_ENTRY 20 -#define CHIP_CONFIG_EXAMPLE_ACCESS_CONTROL_MAX_SUBJECTS_PER_ENTRY 20 -#define CHIP_CONFIG_EXAMPLE_ACCESS_CONTROL_MAX_ENTRIES_PER_FABRIC 20 - // Allows app options (ports) to be configured on launch of app #define CHIP_DEVICE_ENABLE_PORT_PARAMS 1 From 8d44e77535ed70f50a44efcbf7c5f5c999f9f34f Mon Sep 17 00:00:00 2001 From: Terence Hampson Date: Mon, 21 Oct 2024 22:38:05 -0400 Subject: [PATCH 060/149] OpenDeviceCommissioningWindow verifies fabric index is what we expect (#36179) * OpenDeviceCommissioningWindow verifies fabric index is what we expect * Restyled by clang-format --------- Co-authored-by: Restyled.io --- .../device_manager/DeviceManager.cpp | 16 +++++++++++----- .../fabric-admin/device_manager/DeviceManager.h | 4 ++-- examples/fabric-admin/rpc/RpcServer.cpp | 11 +++++------ 3 files changed, 18 insertions(+), 13 deletions(-) diff --git a/examples/fabric-admin/device_manager/DeviceManager.cpp b/examples/fabric-admin/device_manager/DeviceManager.cpp index 0d7d656a4e685e..e52027c8f533f1 100644 --- a/examples/fabric-admin/device_manager/DeviceManager.cpp +++ b/examples/fabric-admin/device_manager/DeviceManager.cpp @@ -117,14 +117,19 @@ void DeviceManager::RemoveSyncedDevice(NodeId nodeId) ChipLogValueX64(device->GetNodeId()), device->GetEndpointId()); } -void DeviceManager::OpenDeviceCommissioningWindow(NodeId nodeId, uint32_t iterations, uint16_t commissioningTimeoutSec, +void DeviceManager::OpenDeviceCommissioningWindow(ScopedNodeId scopedNodeId, uint32_t iterations, uint16_t commissioningTimeoutSec, uint16_t discriminator, const ByteSpan & salt, const ByteSpan & verifier) { - ChipLogProgress(NotSpecified, "Opening commissioning window for Node ID: " ChipLogFormatX64, ChipLogValueX64(nodeId)); + // PairingManager isn't currently capable of OpenCommissioningWindow on a device of a fabric that it doesn't have + // the controller for. Currently no implementation need this functionality, but should they need it they will hit + // the verify or die below and it will be the responsiblity of whoever requires that functionality to implement. + VerifyOrDie(PairingManager::Instance().CurrentCommissioner().GetFabricIndex() == scopedNodeId.GetFabricIndex()); + ChipLogProgress(NotSpecified, "Opening commissioning window for Node ID: " ChipLogFormatX64, + ChipLogValueX64(scopedNodeId.GetNodeId())); // Open the commissioning window of a device within its own fabric. - CHIP_ERROR err = PairingManager::Instance().OpenCommissioningWindow(nodeId, kRootEndpointId, commissioningTimeoutSec, - iterations, discriminator, salt, verifier); + CHIP_ERROR err = PairingManager::Instance().OpenCommissioningWindow( + scopedNodeId.GetNodeId(), kRootEndpointId, commissioningTimeoutSec, iterations, discriminator, salt, verifier); if (err != CHIP_NO_ERROR) { ChipLogError(NotSpecified, "Failed to open commissioning window: %s", ErrorStr(err)); @@ -412,7 +417,8 @@ void DeviceManager::HandleReverseOpenCommissioningWindow(TLV::TLVReader & data) ChipLogProgress(NotSpecified, " PAKEPasscodeVerifier size: %lu", value.PAKEPasscodeVerifier.size()); ChipLogProgress(NotSpecified, " salt size: %lu", value.salt.size()); - OpenDeviceCommissioningWindow(mLocalBridgeNodeId, value.iterations, value.commissioningTimeout, value.discriminator, + ScopedNodeId scopedNodeId(mLocalBridgeNodeId, PairingManager::Instance().CurrentCommissioner().GetFabricIndex()); + OpenDeviceCommissioningWindow(scopedNodeId, value.iterations, value.commissioningTimeout, value.discriminator, ByteSpan(value.salt.data(), value.salt.size()), ByteSpan(value.PAKEPasscodeVerifier.data(), value.PAKEPasscodeVerifier.size())); } diff --git a/examples/fabric-admin/device_manager/DeviceManager.h b/examples/fabric-admin/device_manager/DeviceManager.h index d405bd358d5fdb..6adc8f243e6b1a 100644 --- a/examples/fabric-admin/device_manager/DeviceManager.h +++ b/examples/fabric-admin/device_manager/DeviceManager.h @@ -91,7 +91,7 @@ class DeviceManager : public PairingDelegate * * This function initiates the process to open the commissioning window for a device identified by the given node ID. * - * @param nodeId The ID of the node that should open the commissioning window. + * @param scopedNodeId The scoped node ID of the device that should open the commissioning window. * @param iterations The number of PBKDF (Password-Based Key Derivation Function) iterations to use * for deriving the PAKE (Password Authenticated Key Exchange) verifier. * @param commissioningTimeoutSec The time in seconds before the commissioning window closes. This value determines @@ -102,7 +102,7 @@ class DeviceManager : public PairingDelegate * @param verifier The PAKE verifier used to authenticate the commissioning process. * */ - void OpenDeviceCommissioningWindow(chip::NodeId nodeId, uint32_t iterations, uint16_t commissioningTimeoutSec, + void OpenDeviceCommissioningWindow(chip::ScopedNodeId scopedNodeId, uint32_t iterations, uint16_t commissioningTimeoutSec, uint16_t discriminator, const chip::ByteSpan & salt, const chip::ByteSpan & verifier); /** diff --git a/examples/fabric-admin/rpc/RpcServer.cpp b/examples/fabric-admin/rpc/RpcServer.cpp index 8613d06c6f3d9f..e10bb64cdc050f 100644 --- a/examples/fabric-admin/rpc/RpcServer.cpp +++ b/examples/fabric-admin/rpc/RpcServer.cpp @@ -98,20 +98,19 @@ class FabricAdmin final : public rpc::FabricAdmin, public IcdManager::Delegate chip_rpc_OperationStatus & response) override { VerifyOrReturnValue(request.has_id, pw::Status::InvalidArgument()); - // TODO(#35875): OpenDeviceCommissioningWindow uses the same controller every time and doesn't currently accept - // FabricIndex. For now we are dropping fabric index from the scoped node id. - NodeId nodeId = request.id.node_id; + ScopedNodeId scopedNodeId(request.id.node_id, request.id.fabric_index); uint32_t iterations = request.iterations; uint16_t discriminator = request.discriminator; uint16_t commissioningTimeoutSec = static_cast(request.commissioning_timeout); // Log the request details for debugging ChipLogProgress(NotSpecified, - "Received OpenCommissioningWindow request: NodeId 0x%lx, Timeout: %u, Iterations: %u, Discriminator: %u", - static_cast(nodeId), commissioningTimeoutSec, iterations, discriminator); + "Received OpenCommissioningWindow request: NodeId " ChipLogFormatX64 + ", Timeout: %u, Iterations: %u, Discriminator: %u", + ChipLogValueX64(scopedNodeId.GetNodeId()), commissioningTimeoutSec, iterations, discriminator); // Open the device commissioning window using raw binary data for salt and verifier - DeviceMgr().OpenDeviceCommissioningWindow(nodeId, iterations, commissioningTimeoutSec, discriminator, + DeviceMgr().OpenDeviceCommissioningWindow(scopedNodeId, iterations, commissioningTimeoutSec, discriminator, ByteSpan(request.salt.bytes, request.salt.size), ByteSpan(request.verifier.bytes, request.verifier.size)); From 44db0f660e20ed996add613b2a7ffb4f63955316 Mon Sep 17 00:00:00 2001 From: Terence Hampson Date: Mon, 21 Oct 2024 22:38:19 -0400 Subject: [PATCH 061/149] Call DeviceReachableChanged when subscription fails (#36175) * Call DeviceReachableChanged when subscription fails * Restyled by clang-format --------- Co-authored-by: Restyled.io --- .../device_manager/DeviceSubscription.cpp | 21 +++++++++++++++++- .../device_manager/DeviceSynchronization.cpp | 6 ++++- examples/fabric-admin/rpc/RpcClient.cpp | 22 +++++++++++++++++++ examples/fabric-admin/rpc/RpcClient.h | 11 ++++++++++ 4 files changed, 58 insertions(+), 2 deletions(-) diff --git a/examples/fabric-admin/device_manager/DeviceSubscription.cpp b/examples/fabric-admin/device_manager/DeviceSubscription.cpp index 0da2bdddd4fbf5..434d349e8c5113 100644 --- a/examples/fabric-admin/device_manager/DeviceSubscription.cpp +++ b/examples/fabric-admin/device_manager/DeviceSubscription.cpp @@ -125,6 +125,16 @@ void DeviceSubscription::OnDone(ReadClient * apReadClient) void DeviceSubscription::OnError(CHIP_ERROR error) { +#if defined(PW_RPC_ENABLED) + if (error == CHIP_ERROR_TIMEOUT && mState == State::SubscriptionStarted) + { + chip_rpc_ReachabilityChanged reachabilityChanged; + reachabilityChanged.has_id = true; + reachabilityChanged.id = mCurrentAdministratorCommissioningAttributes.id; + reachabilityChanged.reachability = false; + DeviceReachableChanged(reachabilityChanged); + } +#endif ChipLogProgress(NotSpecified, "Error subscribing: %" CHIP_ERROR_FORMAT, error.Format()); } @@ -198,7 +208,16 @@ void DeviceSubscription::OnDeviceConnectionFailure(const ScopedNodeId & peerId, { VerifyOrDie(mState == State::Connecting || mState == State::Stopping); ChipLogError(NotSpecified, "DeviceSubscription failed to connect to " ChipLogFormatX64, ChipLogValueX64(peerId.GetNodeId())); - // TODO(#35333) Figure out how we should recover if we fail to connect and mState == State::Connecting. +#if defined(PW_RPC_ENABLED) + if (mState == State::Connecting) + { + chip_rpc_ReachabilityChanged reachabilityChanged; + reachabilityChanged.has_id = true; + reachabilityChanged.id = mCurrentAdministratorCommissioningAttributes.id; + reachabilityChanged.reachability = false; + DeviceReachableChanged(reachabilityChanged); + } +#endif // After calling mOnDoneCallback we are indicating that `this` is deleted and we shouldn't do anything else with // DeviceSubscription. diff --git a/examples/fabric-admin/device_manager/DeviceSynchronization.cpp b/examples/fabric-admin/device_manager/DeviceSynchronization.cpp index 6c2284018e0d19..1e8728ee59b567 100644 --- a/examples/fabric-admin/device_manager/DeviceSynchronization.cpp +++ b/examples/fabric-admin/device_manager/DeviceSynchronization.cpp @@ -277,12 +277,16 @@ void DeviceSynchronizer::SynchronizationCompleteAddDevice() if (!mCurrentDeviceData.is_icd) { VerifyOrDie(mController); - // TODO(#35333) Figure out how we should recover in this circumstance. ScopedNodeId scopedNodeId(mNodeId, mController->GetFabricIndex()); CHIP_ERROR err = DeviceSubscriptionManager::Instance().StartSubscription(*mController, scopedNodeId); if (err != CHIP_NO_ERROR) { ChipLogError(NotSpecified, "Failed start subscription to NodeId:" ChipLogFormatX64, ChipLogValueX64(mNodeId)); + chip_rpc_ReachabilityChanged reachabilityChanged; + reachabilityChanged.has_id = true; + reachabilityChanged.id = mCurrentDeviceData.id; + reachabilityChanged.reachability = false; + DeviceReachableChanged(reachabilityChanged); } } #endif diff --git a/examples/fabric-admin/rpc/RpcClient.cpp b/examples/fabric-admin/rpc/RpcClient.cpp index e33dd0472e6fe2..9964dc6767b67e 100644 --- a/examples/fabric-admin/rpc/RpcClient.cpp +++ b/examples/fabric-admin/rpc/RpcClient.cpp @@ -205,3 +205,25 @@ CHIP_ERROR AdminCommissioningAttributeChanged(const chip_rpc_AdministratorCommis return WaitForResponse(call); } + +CHIP_ERROR DeviceReachableChanged(const chip_rpc_ReachabilityChanged & data) +{ + ChipLogProgress(NotSpecified, "DeviceReachableChanged"); + // TODO(#35333): When there is some sort of device manager in fabric-admin that handles all the devices we + // are currently connected to (and not just device on the remote bridge), we should notify that manager + // so that it can properly handle any sort of reconnection logic. This can either be done here when + // `data.reachability == false`, or more control can be given wherever DeviceReachableChanged is currently + // called + + // The RPC call is kept alive until it completes. When a response is received, it will be logged by the handler + // function and the call will complete. + auto call = fabricBridgeClient.DeviceReachableChanged(data, RpcCompletedWithEmptyResponse); + + if (!call.active()) + { + // The RPC call was not sent. This could occur due to, for example, an invalid channel ID. Handle if necessary. + return CHIP_ERROR_INTERNAL; + } + + return WaitForResponse(call); +} diff --git a/examples/fabric-admin/rpc/RpcClient.h b/examples/fabric-admin/rpc/RpcClient.h index da6a82115a3cd2..a4cefe8bd8e076 100644 --- a/examples/fabric-admin/rpc/RpcClient.h +++ b/examples/fabric-admin/rpc/RpcClient.h @@ -88,3 +88,14 @@ CHIP_ERROR ActiveChanged(chip::ScopedNodeId scopedNodeId, uint32_t promisedActiv * - CHIP_ERROR_INTERNAL: An internal error occurred while activating the RPC call. */ CHIP_ERROR AdminCommissioningAttributeChanged(const chip_rpc_AdministratorCommissioningChanged & data); + +/** + * @brief Notify that reachachability of the bridged device has changed + * + * @param data information regarding change in reachability of the bridged device. + * @return CHIP_ERROR An error code indicating the success or failure of the operation. + * - CHIP_NO_ERROR: The RPC command was successfully processed. + * - CHIP_ERROR_BUSY: Another operation is currently in progress. + * - CHIP_ERROR_INTERNAL: An internal error occurred while activating the RPC call. + */ +CHIP_ERROR DeviceReachableChanged(const chip_rpc_ReachabilityChanged & data); From 4269ff5c6157ded0ae3d2d4e82ca9a94782a46d6 Mon Sep 17 00:00:00 2001 From: Yufeng Wang Date: Mon, 21 Oct 2024 23:40:25 -0700 Subject: [PATCH 062/149] [Fabric-Bridge] Update Readme.txt to exclude incorrect path info (#36184) --- examples/fabric-bridge-app/linux/README.md | 7 ------- 1 file changed, 7 deletions(-) diff --git a/examples/fabric-bridge-app/linux/README.md b/examples/fabric-bridge-app/linux/README.md index 27a01d9ffec60a..ede6ce26399062 100644 --- a/examples/fabric-bridge-app/linux/README.md +++ b/examples/fabric-bridge-app/linux/README.md @@ -130,13 +130,6 @@ defined: scp ./fabric-bridge-app ubuntu@xxx.xxx.xxx.xxx:/home/ubuntu ``` -- To delete generated executable, libraries and object files use: - - ```sh - cd ~/connectedhomeip/examples/fabric-bridge-app/linux - rm -rf out/ - ``` - ## Running the Complete Example on Ubuntu - Building From 5eb3cc03533b5f562fd01c17ec1a3d26984cbd48 Mon Sep 17 00:00:00 2001 From: dinabenamar <108664279+dinabenamar@users.noreply.github.com> Date: Tue, 22 Oct 2024 13:50:44 +0200 Subject: [PATCH 063/149] [NXP][platform][common] Minor platform code updates (#36169) * [NXP][platform][common] Platform code updates Signed-off-by: Dina Benamar * Restyled by clang-format * [NXP] Fix include order after clang format Signed-off-by: Dina Benamar --------- Signed-off-by: Dina Benamar Co-authored-by: Restyled.io --- .../nxp/common/ota_requestor/include/OTARequestorInitiator.h | 4 ++-- src/platform/nxp/common/NXPConfigNVS.cpp | 2 +- src/platform/nxp/common/ble_zephyr/BLEAdvertisingArbiter.h | 3 ++- src/platform/nxp/rt/rw61x/PlatformManagerImpl.cpp | 2 +- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/examples/platform/nxp/common/ota_requestor/include/OTARequestorInitiator.h b/examples/platform/nxp/common/ota_requestor/include/OTARequestorInitiator.h index 4054bb4a2a473f..a6289fc3b8c86e 100644 --- a/examples/platform/nxp/common/ota_requestor/include/OTARequestorInitiator.h +++ b/examples/platform/nxp/common/ota_requestor/include/OTARequestorInitiator.h @@ -27,11 +27,11 @@ #ifdef CONFIG_CHIP_OTA_IMAGE_PROCESSOR_HEADER #include CONFIG_CHIP_OTA_IMAGE_PROCESSOR_HEADER #else -#ifdef CONFIG_CHIP +#ifndef CONFIG_APP_FREERTOS_OS #include #else #include "platform/nxp/common/OTAImageProcessorImpl.h" -#endif /* CONFIG_CHIP */ +#endif /* CONFIG_APP_FREERTOS_OS */ #endif /* CONFIG_CHIP_OTA_IMAGE_PROCESSOR_HEADER */ #include diff --git a/src/platform/nxp/common/NXPConfigNVS.cpp b/src/platform/nxp/common/NXPConfigNVS.cpp index 1aa1320383b662..6d0ce459a4187d 100644 --- a/src/platform/nxp/common/NXPConfigNVS.cpp +++ b/src/platform/nxp/common/NXPConfigNVS.cpp @@ -24,7 +24,7 @@ #include /* Only for flash init, to be move to sdk framework */ -#include "port/nvs_port.h" +#include "nvs_port.h" #if (CHIP_DEVICE_CONFIG_KVS_WEAR_STATS == 1) #include "fwk_nvs_stats.h" #endif /* CHIP_DEVICE_CONFIG_KVS_WEAR_STATS */ diff --git a/src/platform/nxp/common/ble_zephyr/BLEAdvertisingArbiter.h b/src/platform/nxp/common/ble_zephyr/BLEAdvertisingArbiter.h index 9c00edbb8e746d..11a90c7070cd0a 100644 --- a/src/platform/nxp/common/ble_zephyr/BLEAdvertisingArbiter.h +++ b/src/platform/nxp/common/ble_zephyr/BLEAdvertisingArbiter.h @@ -20,7 +20,8 @@ #include #include -#include + +#include #include diff --git a/src/platform/nxp/rt/rw61x/PlatformManagerImpl.cpp b/src/platform/nxp/rt/rw61x/PlatformManagerImpl.cpp index fe8c6b012b4c3f..a089a942932d3b 100644 --- a/src/platform/nxp/rt/rw61x/PlatformManagerImpl.cpp +++ b/src/platform/nxp/rt/rw61x/PlatformManagerImpl.cpp @@ -38,7 +38,7 @@ #include -#include MBEDTLS_PORT_INCLUDE +#include "els_pkc_mbedtls.h" #if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR #include "OtaSupport.h" From 5c0c92e671bee33cca8e6832b4f8744228d21363 Mon Sep 17 00:00:00 2001 From: C Freeman Date: Tue, 22 Oct 2024 09:41:38 -0400 Subject: [PATCH 064/149] Remove event list from generated code (#34997) * manual change * zap regen * ifdef some stray event lists * re-zap * one more ifdef * Remove some EVENT_LIST_ defines * Remove event list from ACL test --- .../air-purifier-app.matter | 27 - .../air-quality-sensor-app.matter | 15 - .../all-clusters-app.matter | 49 - .../all-clusters-common/all-clusters-app.zap | 792 +- .../all-clusters-minimal-app.matter | 27 - .../rootnode_airpurifier_73a6fe2651.matter | 6 - ...umiditysensor_thermostat_56de3d5f45.matter | 28 - ...ootnode_airqualitysensor_e63187f6c9.matter | 16 - ...ootnode_basicvideoplayer_0ff86e943b.matter | 14 - .../rootnode_contactsensor_27f76aeaf5.matter | 2 - .../rootnode_contactsensor_lFAGG1bfRO.matter | 2 - ...tnode_dimmablepluginunit_f8a9a0b9d4.matter | 6 - .../rootnode_dishwasher_cc105034fe.matter | 5 - .../rootnode_doorlock_aNKYAreMXE.matter | 4 - .../devices/rootnode_fan_7N2TobIlOX.matter | 1 - .../rootnode_genericswitch_2dfff6e516.matter | 4 - .../rootnode_genericswitch_9866e35d0b.matter | 4 - .../rootnode_laundrydryer_01796fe396.matter | 5 - .../rootnode_laundrywasher_fb10d238c8.matter | 2 - .../rootnode_onofflight_samplemei.matter | 1 - .../devices/rootnode_pump_5f904818cc.matter | 3 - ...eraturecontrolledcabinet_ffdb696680.matter | 4 - ...ode_roboticvacuumcleaner_1807ff0c49.matter | 7 - ...tnode_roomairconditioner_9cf3607804.matter | 12 - .../rootnode_smokecoalarm_686fe0dcb8.matter | 4 - ...otnode_waterleakdetector_0b067acfa3.matter | 6 - .../rootnode_watervalve_6bb39f1f67.matter | 5 - .../nxp/zap-lit/contact-sensor-app.matter | 9 - .../nxp/zap-sit/contact-sensor-app.matter | 9 - .../data_model/dishwasher-thread-app.matter | 10 - .../data_model/dishwasher-wifi-app.matter | 10 - .../energy-management-app.matter | 24 - .../fabric-bridge-app.matter | 1 - .../fabric-sync/bridge/fabric-bridge.matter | 1 - .../nxp/zap/laundry-washer-app.matter | 19 - .../light-switch-app/qpg/zap/switch.matter | 22 - .../data_model/lighting-thread-app.matter | 7 - .../data_model/lighting-wifi-app.matter | 7 - .../lit-icd-common/lit-icd-server-app.matter | 14 - examples/lock-app/lock-common/lock-app.matter | 15 - examples/lock-app/nxp/zap/lock-app.matter | 17 - examples/lock-app/qpg/zap/lock.matter | 1 - .../silabs/data_model/lock-app.matter | 15 - .../microwave-oven-app.matter | 5 - .../network-manager-app.matter | 5 - .../ota-requestor-app.matter | 12 - .../placeholder/linux/apps/app1/config.matter | 14 - .../placeholder/linux/apps/app2/config.matter | 13 - .../data_model/refrigerator-thread-app.matter | 6 - .../data_model/refrigerator-wifi-app.matter | 5 - examples/rvc-app/rvc-common/rvc-app.matter | 7 - .../smoke-co-alarm-app.matter | 4 - .../temperature-measurement.matter | 1 - .../nxp/zap/thermostat_matter_br.matter | 13 - .../nxp/zap/thermostat_matter_thread.matter | 8 - .../nxp/zap/thermostat_matter_wifi.matter | 9 - .../thread-br-common/thread-br-app.matter | 3 - examples/tv-app/tv-common/tv-app.matter | 4 - .../zap-generated/MCAttributeObjects.h | 27 - .../zap-generated/MCAttributeObjects.mm | 549 - .../zap-generated/MCClusterObjects.h | 45 - .../zap-generated/MCClusterObjects.mm | 54 - .../tv-casting-common/tv-casting-app.matter | 1 - .../virtual-device-app.matter | 4 - .../water-leak-detector-app.matter | 7 - examples/window-app/common/window-app.matter | 12 - ...oncentration-measurement-cluster-objects.h | 4 - .../mode-base-cluster-objects.h | 4 - .../resource-monitoring-cluster-objects.h | 8 - .../zcl/data-model/chip/global-attributes.xml | 1 - .../CHIPAttributeTLVValueDecoder.cpp | 4519 +------ .../python/chip/clusters/CHIPClusters.py | 762 -- .../python/chip/clusters/Objects.py | 2286 ---- .../MTRAttributeSpecifiedCheck.mm | 369 - .../MTRAttributeTLVValueDecoder.mm | 26 - .../CHIP/zap-generated/MTRBaseClusters.h | 738 - .../CHIP/zap-generated/MTRBaseClusters.mm | 4428 ------ .../CHIP/zap-generated/MTRClusterConstants.h | 124 - .../CHIP/zap-generated/MTRClusterNames.mm | 492 - .../CHIP/zap-generated/MTRClusters.h | 246 - .../CHIP/zap-generated/MTRClusters.mm | 615 - src/python_testing/TC_ACL_2_11.py | 14 +- .../zap-generated/cluster-objects.cpp | 254 - .../zap-generated/cluster-objects.h | 901 -- .../app-common/zap-generated/ids/Attributes.h | 512 - .../zap-generated/cluster/Commands.h | 635 - .../cluster/logging/DataModelLogger.cpp | 635 - .../cluster/logging/EntryToText.cpp | 254 - .../zap-generated/cluster/Commands.h | 11152 ---------------- 89 files changed, 679 insertions(+), 30340 deletions(-) diff --git a/examples/air-purifier-app/air-purifier-common/air-purifier-app.matter b/examples/air-purifier-app/air-purifier-common/air-purifier-app.matter index 95cd8bc2d0799e..8b8743c6b67330 100644 --- a/examples/air-purifier-app/air-purifier-common/air-purifier-app.matter +++ b/examples/air-purifier-app/air-purifier-common/air-purifier-app.matter @@ -2771,7 +2771,6 @@ endpoint 1 { ram attribute identifyType default = 0x0; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 4; @@ -2787,7 +2786,6 @@ endpoint 1 { callback attribute partsList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -2802,7 +2800,6 @@ endpoint 1 { callback attribute replacementProductList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 1; @@ -2819,7 +2816,6 @@ endpoint 1 { callback attribute replacementProductList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 1; @@ -2842,7 +2838,6 @@ endpoint 1 { ram attribute airflowDirection default = 0; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 63; ram attribute clusterRevision default = 4; @@ -2859,7 +2854,6 @@ endpoint 2 { ram attribute identifyType default = 0x00; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 4; @@ -2874,7 +2868,6 @@ endpoint 2 { callback attribute partsList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -2884,7 +2877,6 @@ endpoint 2 { callback attribute airQuality; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 1; @@ -2904,7 +2896,6 @@ endpoint 2 { callback attribute levelValue; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 3; @@ -2924,7 +2915,6 @@ endpoint 2 { callback attribute levelValue; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 3; @@ -2944,7 +2934,6 @@ endpoint 2 { callback attribute levelValue; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 3; @@ -2964,7 +2953,6 @@ endpoint 2 { callback attribute levelValue; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 3; @@ -2984,7 +2972,6 @@ endpoint 2 { callback attribute levelValue; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 3; @@ -3004,7 +2991,6 @@ endpoint 2 { callback attribute levelValue; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 3; @@ -3024,7 +3010,6 @@ endpoint 2 { callback attribute levelValue; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 3; @@ -3044,7 +3029,6 @@ endpoint 2 { callback attribute levelValue; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 3; @@ -3064,7 +3048,6 @@ endpoint 2 { callback attribute levelValue; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 3; @@ -3084,7 +3067,6 @@ endpoint 2 { callback attribute levelValue; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 3; @@ -3099,7 +3081,6 @@ endpoint 3 { ram attribute identifyType default = 0x00; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 4; @@ -3115,7 +3096,6 @@ endpoint 3 { callback attribute partsList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -3128,7 +3108,6 @@ endpoint 3 { ram attribute tolerance default = 0; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 4; @@ -3143,7 +3122,6 @@ endpoint 4 { ram attribute identifyType default = 0x00; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 4; @@ -3159,7 +3137,6 @@ endpoint 4 { callback attribute partsList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -3172,7 +3149,6 @@ endpoint 4 { ram attribute tolerance; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 3; @@ -3187,7 +3163,6 @@ endpoint 5 { ram attribute identifyType default = 0x00; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 4; @@ -3203,7 +3178,6 @@ endpoint 5 { callback attribute partsList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -3219,7 +3193,6 @@ endpoint 5 { ram attribute thermostatRunningState default = 0; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 1; ram attribute clusterRevision default = 6; diff --git a/examples/air-quality-sensor-app/air-quality-sensor-common/air-quality-sensor-app.matter b/examples/air-quality-sensor-app/air-quality-sensor-common/air-quality-sensor-app.matter index b9da1aef2413f9..896a27edd0d365 100644 --- a/examples/air-quality-sensor-app/air-quality-sensor-common/air-quality-sensor-app.matter +++ b/examples/air-quality-sensor-app/air-quality-sensor-common/air-quality-sensor-app.matter @@ -2621,7 +2621,6 @@ endpoint 1 { ram attribute identifyType default = 0x00; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 4; @@ -2636,7 +2635,6 @@ endpoint 1 { callback attribute partsList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -2646,7 +2644,6 @@ endpoint 1 { callback attribute airQuality; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 1; @@ -2658,7 +2655,6 @@ endpoint 1 { ram attribute maxMeasuredValue; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 4; @@ -2670,7 +2666,6 @@ endpoint 1 { ram attribute maxMeasuredValue; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 3; @@ -2682,7 +2677,6 @@ endpoint 1 { callback attribute maxMeasuredValue; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 3; @@ -2694,7 +2688,6 @@ endpoint 1 { callback attribute maxMeasuredValue; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 3; @@ -2706,7 +2699,6 @@ endpoint 1 { callback attribute maxMeasuredValue; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 3; @@ -2718,7 +2710,6 @@ endpoint 1 { callback attribute maxMeasuredValue; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 3; @@ -2730,7 +2721,6 @@ endpoint 1 { callback attribute maxMeasuredValue; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 3; @@ -2742,7 +2732,6 @@ endpoint 1 { callback attribute maxMeasuredValue; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 3; @@ -2754,7 +2743,6 @@ endpoint 1 { callback attribute maxMeasuredValue; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 3; @@ -2766,7 +2754,6 @@ endpoint 1 { callback attribute maxMeasuredValue; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 3; @@ -2778,7 +2765,6 @@ endpoint 1 { callback attribute maxMeasuredValue; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 3; @@ -2790,7 +2776,6 @@ endpoint 1 { callback attribute maxMeasuredValue; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 3; diff --git a/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter b/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter index 4888bf464cf85d..fb770209b996a3 100644 --- a/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter +++ b/examples/all-clusters-app/all-clusters-common/all-clusters-app.matter @@ -7579,7 +7579,6 @@ endpoint 0 { callback attribute tagList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -7601,7 +7600,6 @@ endpoint 0 { callback attribute accessControlEntriesPerFabric; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; callback attribute clusterRevision; @@ -7635,7 +7633,6 @@ endpoint 0 { callback attribute maxPathsPerInvoke; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 3; @@ -7660,7 +7657,6 @@ endpoint 0 { callback attribute supportedLocales; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -7672,7 +7668,6 @@ endpoint 0 { callback attribute supportedCalendarTypes; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 1; ram attribute clusterRevision default = 1; @@ -7682,7 +7677,6 @@ endpoint 0 { persist attribute temperatureUnit default = 0; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0x1; ram attribute clusterRevision default = 1; @@ -7704,7 +7698,6 @@ endpoint 0 { callback attribute endpointList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 2; ram attribute clusterRevision default = 2; @@ -7718,7 +7711,6 @@ endpoint 0 { callback attribute supportsConcurrentConnection; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -7745,7 +7737,6 @@ endpoint 0 { callback attribute threadVersion; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 2; ram attribute clusterRevision default = 1; @@ -7764,7 +7755,6 @@ endpoint 0 { server cluster DiagnosticLogs { callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -7789,7 +7779,6 @@ endpoint 0 { callback attribute testEventTriggersEnabled; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -7960,7 +7949,6 @@ endpoint 0 { callback attribute adminVendorId; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -7979,7 +7967,6 @@ endpoint 0 { callback attribute currentFabricIndex; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -8005,7 +7992,6 @@ endpoint 0 { callback attribute maxGroupKeysPerFabric; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -8060,7 +8046,6 @@ endpoint 1 { ram attribute identifyType default = 0x0; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 4; @@ -8073,7 +8058,6 @@ endpoint 1 { ram attribute nameSupport; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 4; @@ -8098,7 +8082,6 @@ endpoint 1 { persist attribute startUpOnOff default = 0xFF; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0x0001; ram attribute clusterRevision default = 6; @@ -8147,7 +8130,6 @@ endpoint 1 { callback attribute tagList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -8178,7 +8160,6 @@ endpoint 1 { callback attribute endpointList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 2; ram attribute clusterRevision default = 2; @@ -8221,7 +8202,6 @@ endpoint 1 { callback attribute operationalError; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -8238,7 +8218,6 @@ endpoint 1 { ram attribute currentMode; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -8252,7 +8231,6 @@ endpoint 1 { ram attribute selectedDrynessLevel; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -8312,7 +8290,6 @@ endpoint 1 { callback attribute supportedRinses; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 3; ram attribute clusterRevision default = 1; @@ -8323,7 +8300,6 @@ endpoint 1 { callback attribute currentMode; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 3; @@ -8337,7 +8313,6 @@ endpoint 1 { callback attribute currentMode; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 3; @@ -8446,7 +8421,6 @@ endpoint 1 { callback attribute currentMode; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 1; @@ -8485,7 +8459,6 @@ endpoint 1 { callback attribute operationalError; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -8502,7 +8475,6 @@ endpoint 1 { callback attribute fabricSceneInfo; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 1; ram attribute clusterRevision default = 1; @@ -8569,7 +8541,6 @@ endpoint 1 { ram attribute sensorFault default = 0; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0x0F; ram attribute clusterRevision default = 1; @@ -8594,7 +8565,6 @@ endpoint 1 { ram attribute levelStep default = 1; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 3; ram attribute clusterRevision default = 1; @@ -8626,7 +8596,6 @@ endpoint 1 { callback attribute neutralCurrent; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 1; @@ -8643,7 +8612,6 @@ endpoint 1 { callback attribute cumulativeEnergyReset; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 1; @@ -8658,7 +8626,6 @@ endpoint 1 { callback attribute boostState; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -8682,7 +8649,6 @@ endpoint 1 { callback attribute optOutState; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 3; @@ -8723,7 +8689,6 @@ endpoint 1 { callback attribute sessionEnergyCharged; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 2; @@ -8746,7 +8711,6 @@ endpoint 1 { ram attribute currentLowPowerModeSensitivity; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 3; ram attribute clusterRevision default = 1; @@ -8757,7 +8721,6 @@ endpoint 1 { callback attribute activeEndpoints; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 1; @@ -8768,7 +8731,6 @@ endpoint 1 { callback attribute currentMode; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 1; @@ -8782,7 +8744,6 @@ endpoint 1 { callback attribute currentMode; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 1; @@ -8796,7 +8757,6 @@ endpoint 1 { callback attribute currentMode; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 1; @@ -8899,7 +8859,6 @@ endpoint 1 { ram attribute setpointHoldExpiryTimestamp; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0x0123; ram attribute clusterRevision default = 7; @@ -9437,7 +9396,6 @@ endpoint 2 { ram attribute identifyType default = 0x00; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 4; @@ -9450,7 +9408,6 @@ endpoint 2 { ram attribute nameSupport; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 4; @@ -9475,7 +9432,6 @@ endpoint 2 { ram attribute startUpOnOff; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0x0001; ram attribute clusterRevision default = 6; @@ -9496,7 +9452,6 @@ endpoint 2 { callback attribute tagList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -9512,7 +9467,6 @@ endpoint 2 { callback attribute endpointList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 2; ram attribute clusterRevision default = 2; @@ -9524,7 +9478,6 @@ endpoint 2 { callback attribute fabricSceneInfo; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 1; ram attribute clusterRevision default = 1; @@ -9645,7 +9598,6 @@ endpoint 65534 { callback attribute partsList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -9662,7 +9614,6 @@ endpoint 65534 { callback attribute lastConnectErrorValue; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap default = 0; callback attribute clusterRevision default = 1; diff --git a/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap b/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap index 741812bc3c2b26..c3586287ea4285 100644 --- a/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap +++ b/examples/all-clusters-app/all-clusters-common/all-clusters-app.zap @@ -332,22 +332,6 @@ "maxInterval": 65534, "reportableChange": 0 }, - { - "name": "EventList", - "code": 65530, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, { "name": "AttributeList", "code": 65531, @@ -576,22 +560,6 @@ "maxInterval": 65534, "reportableChange": 0 }, - { - "name": "EventList", - "code": 65530, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, { "name": "AttributeList", "code": 65531, @@ -1050,22 +1018,6 @@ "maxInterval": 65534, "reportableChange": 0 }, - { - "name": "EventList", - "code": 65530, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 1, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, { "name": "AttributeList", "code": 65531, @@ -1392,22 +1344,6 @@ "maxInterval": 65534, "reportableChange": 0 }, - { - "name": "EventList", - "code": 65530, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, { "name": "AttributeList", "code": 65531, @@ -1546,22 +1482,6 @@ "maxInterval": 65534, "reportableChange": 0 }, - { - "name": "EventList", - "code": 65530, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, { "name": "AttributeList", "code": 65531, @@ -1668,22 +1588,6 @@ "maxInterval": 65534, "reportableChange": 0 }, - { - "name": "EventList", - "code": 65530, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, { "name": "AttributeList", "code": 65531, @@ -1944,22 +1848,6 @@ "maxInterval": 65534, "reportableChange": 0 }, - { - "name": "EventList", - "code": 65530, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, { "name": "AttributeList", "code": 65531, @@ -2180,22 +2068,6 @@ "maxInterval": 65534, "reportableChange": 0 }, - { - "name": "EventList", - "code": 65530, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, { "name": "AttributeList", "code": 65531, @@ -2536,22 +2408,6 @@ "maxInterval": 65534, "reportableChange": 0 }, - { - "name": "EventList", - "code": 65530, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, { "name": "AttributeList", "code": 65531, @@ -2660,22 +2516,6 @@ "maxInterval": 65534, "reportableChange": 0 }, - { - "name": "EventList", - "code": 65530, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, { "name": "AttributeList", "code": 65531, @@ -2952,22 +2792,6 @@ "maxInterval": 65534, "reportableChange": 0 }, - { - "name": "EventList", - "code": 65530, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, { "name": "AttributeList", "code": 65531, @@ -5195,22 +5019,6 @@ "maxInterval": 65534, "reportableChange": 0 }, - { - "name": "EventList", - "code": 65530, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, { "name": "AttributeList", "code": 65531, @@ -5495,22 +5303,6 @@ "maxInterval": 65534, "reportableChange": 0 }, - { - "name": "EventList", - "code": 65530, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, { "name": "AttributeList", "code": 65531, @@ -5715,22 +5507,6 @@ "maxInterval": 65534, "reportableChange": 0 }, - { - "name": "EventList", - "code": 65530, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, { "name": "AttributeList", "code": 65531, @@ -6226,22 +6002,6 @@ "maxInterval": 65534, "reportableChange": 0 }, - { - "name": "EventList", - "code": 65530, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, { "name": "AttributeList", "code": 65531, @@ -6430,22 +6190,6 @@ "maxInterval": 65534, "reportableChange": 0 }, - { - "name": "EventList", - "code": 65530, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, { "name": "AttributeList", "code": 65531, @@ -6700,22 +6444,6 @@ "maxInterval": 65534, "reportableChange": 0 }, - { - "name": "EventList", - "code": 65530, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, { "name": "AttributeList", "code": 65531, @@ -7218,22 +6946,6 @@ "maxInterval": 65534, "reportableChange": 0 }, - { - "name": "EventList", - "code": 65530, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, { "name": "AttributeList", "code": 65531, @@ -7584,22 +7296,6 @@ "maxInterval": 65534, "reportableChange": 0 }, - { - "name": "EventList", - "code": 65530, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, { "name": "AttributeList", "code": 65531, @@ -8094,22 +7790,6 @@ "maxInterval": 65534, "reportableChange": 0 }, - { - "name": "EventList", - "code": 65530, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, { "name": "AttributeList", "code": 65531, @@ -8266,22 +7946,6 @@ "maxInterval": 65534, "reportableChange": 0 }, - { - "name": "EventList", - "code": 65530, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, { "name": "AttributeList", "code": 65531, @@ -8404,22 +8068,6 @@ "maxInterval": 65534, "reportableChange": 0 }, - { - "name": "EventList", - "code": 65530, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, { "name": "AttributeList", "code": 65531, @@ -9130,22 +8778,6 @@ "maxInterval": 65534, "reportableChange": 0 }, - { - "name": "EventList", - "code": 65530, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, { "name": "AttributeList", "code": 65531, @@ -9286,22 +8918,6 @@ "maxInterval": 65534, "reportableChange": 0 }, - { - "name": "EventList", - "code": 65530, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, { "name": "AttributeList", "code": 65531, @@ -9442,22 +9058,6 @@ "maxInterval": 65534, "reportableChange": 0 }, - { - "name": "EventList", - "code": 65530, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, { "name": "AttributeList", "code": 65531, @@ -10657,22 +10257,6 @@ "maxInterval": 65534, "reportableChange": 0 }, - { - "name": "EventList", - "code": 65530, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, { "name": "AttributeList", "code": 65531, @@ -11137,22 +10721,6 @@ "maxInterval": 65534, "reportableChange": 0 }, - { - "name": "EventList", - "code": 65530, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, { "name": "AttributeList", "code": 65531, @@ -11430,22 +10998,6 @@ "maxInterval": 65534, "reportableChange": 0 }, - { - "name": "EventList", - "code": 65530, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, { "name": "AttributeList", "code": 65531, @@ -12074,22 +11626,6 @@ "maxInterval": 65534, "reportableChange": 0 }, - { - "name": "EventList", - "code": 65530, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, { "name": "AttributeList", "code": 65531, @@ -12390,22 +11926,6 @@ "maxInterval": 65534, "reportableChange": 0 }, - { - "name": "EventList", - "code": 65530, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, { "name": "AttributeList", "code": 65531, @@ -12785,24 +12305,8 @@ "reportableChange": 0 }, { - "name": "GeneratedCommandList", - "code": 65528, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "AcceptedCommandList", - "code": 65529, + "name": "GeneratedCommandList", + "code": 65528, "mfgCode": null, "side": "server", "type": "array", @@ -12817,8 +12321,8 @@ "reportableChange": 0 }, { - "name": "EventList", - "code": 65530, + "name": "AcceptedCommandList", + "code": 65529, "mfgCode": null, "side": "server", "type": "array", @@ -13027,22 +12531,6 @@ "maxInterval": 65534, "reportableChange": 0 }, - { - "name": "EventList", - "code": 65530, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, { "name": "AttributeList", "code": 65531, @@ -13264,22 +12752,6 @@ "maxInterval": 65534, "reportableChange": 0 }, - { - "name": "EventList", - "code": 65530, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, { "name": "AttributeList", "code": 65531, @@ -13565,22 +13037,6 @@ "maxInterval": 65534, "reportableChange": 0 }, - { - "name": "EventList", - "code": 65530, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, { "name": "AttributeList", "code": 65531, @@ -14039,22 +13495,6 @@ "maxInterval": 65534, "reportableChange": 0 }, - { - "name": "EventList", - "code": 65530, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, { "name": "AttributeList", "code": 65531, @@ -14270,22 +13710,6 @@ "maxInterval": 65534, "reportableChange": 0 }, - { - "name": "EventList", - "code": 65530, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, { "name": "AttributeList", "code": 65531, @@ -14408,22 +13832,6 @@ "maxInterval": 65534, "reportableChange": 0 }, - { - "name": "EventList", - "code": 65530, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, { "name": "AttributeList", "code": 65531, @@ -14564,22 +13972,6 @@ "maxInterval": 65534, "reportableChange": 0 }, - { - "name": "EventList", - "code": 65530, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, { "name": "AttributeList", "code": 65531, @@ -14720,22 +14112,6 @@ "maxInterval": 65534, "reportableChange": 0 }, - { - "name": "EventList", - "code": 65530, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, { "name": "AttributeList", "code": 65531, @@ -14877,22 +14253,6 @@ "maxInterval": 65534, "reportableChange": 0 }, - { - "name": "EventList", - "code": 65530, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, { "name": "AttributeList", "code": 65531, @@ -16335,22 +15695,6 @@ "maxInterval": 65534, "reportableChange": 0 }, - { - "name": "EventList", - "code": 65530, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, { "name": "AttributeList", "code": 65531, @@ -23394,22 +22738,6 @@ "maxInterval": 65534, "reportableChange": 0 }, - { - "name": "EventList", - "code": 65530, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, { "name": "AttributeList", "code": 65531, @@ -23598,22 +22926,6 @@ "maxInterval": 65534, "reportableChange": 0 }, - { - "name": "EventList", - "code": 65530, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, { "name": "AttributeList", "code": 65531, @@ -23834,22 +23146,6 @@ "maxInterval": 65534, "reportableChange": 0 }, - { - "name": "EventList", - "code": 65530, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, { "name": "AttributeList", "code": 65531, @@ -24020,22 +23316,6 @@ "maxInterval": 65534, "reportableChange": 0 }, - { - "name": "EventList", - "code": 65530, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, { "name": "AttributeList", "code": 65531, @@ -24238,22 +23518,6 @@ "maxInterval": 65534, "reportableChange": 0 }, - { - "name": "EventList", - "code": 65530, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, { "name": "AttributeList", "code": 65531, @@ -24515,22 +23779,6 @@ "maxInterval": 65534, "reportableChange": 0 }, - { - "name": "EventList", - "code": 65530, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, { "name": "AttributeList", "code": 65531, @@ -25728,22 +24976,6 @@ "maxInterval": 65534, "reportableChange": 0 }, - { - "name": "EventList", - "code": 65530, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, { "name": "AttributeList", "code": 65531, @@ -26036,22 +25268,6 @@ "maxInterval": 65534, "reportableChange": 0 }, - { - "name": "EventList", - "code": 65530, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, { "name": "AttributeList", "code": 65531, diff --git a/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.matter b/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.matter index 630f3a6d2e98df..ae50904721e813 100644 --- a/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.matter +++ b/examples/all-clusters-minimal-app/all-clusters-common/all-clusters-minimal-app.matter @@ -6275,7 +6275,6 @@ endpoint 0 { callback attribute partsList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -6296,7 +6295,6 @@ endpoint 0 { callback attribute accessControlEntriesPerFabric; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; callback attribute clusterRevision; @@ -6321,7 +6319,6 @@ endpoint 0 { callback attribute maxPathsPerInvoke; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 3; @@ -6346,7 +6343,6 @@ endpoint 0 { callback attribute supportedLocales; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -6356,7 +6352,6 @@ endpoint 0 { persist attribute hourFormat default = 0; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -6365,7 +6360,6 @@ endpoint 0 { server cluster UnitLocalization { callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -6378,7 +6372,6 @@ endpoint 0 { callback attribute endpointList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 2; @@ -6392,7 +6385,6 @@ endpoint 0 { callback attribute supportsConcurrentConnection; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -6419,7 +6411,6 @@ endpoint 0 { callback attribute threadVersion; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 2; ram attribute clusterRevision default = 1; @@ -6449,7 +6440,6 @@ endpoint 0 { callback attribute testEventTriggersEnabled; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -6520,7 +6510,6 @@ endpoint 0 { callback attribute adminVendorId; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -6538,7 +6527,6 @@ endpoint 0 { callback attribute currentFabricIndex; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -6564,7 +6552,6 @@ endpoint 0 { callback attribute maxGroupKeysPerFabric; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -6607,7 +6594,6 @@ endpoint 1 { ram attribute identifyType default = 0x0; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 4; @@ -6620,7 +6606,6 @@ endpoint 1 { ram attribute nameSupport; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 4; @@ -6645,7 +6630,6 @@ endpoint 1 { persist attribute startUpOnOff default = 0xFF; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 5; @@ -6684,7 +6668,6 @@ endpoint 1 { callback attribute partsList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -6710,7 +6693,6 @@ endpoint 1 { callback attribute endpointList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 2; @@ -6773,7 +6755,6 @@ endpoint 1 { callback attribute fabricSceneInfo; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 1; ram attribute clusterRevision default = 1; @@ -7181,7 +7162,6 @@ endpoint 2 { ram attribute identifyType default = 0x00; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 4; @@ -7194,7 +7174,6 @@ endpoint 2 { ram attribute nameSupport; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 4; @@ -7219,7 +7198,6 @@ endpoint 2 { ram attribute startUpOnOff; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0x0000; ram attribute clusterRevision default = 5; @@ -7239,7 +7217,6 @@ endpoint 2 { callback attribute partsList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -7252,7 +7229,6 @@ endpoint 2 { callback attribute endpointList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 2; @@ -7264,7 +7240,6 @@ endpoint 2 { callback attribute fabricSceneInfo; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 1; ram attribute clusterRevision default = 1; @@ -7303,7 +7278,6 @@ endpoint 65534 { callback attribute partsList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -7320,7 +7294,6 @@ endpoint 65534 { callback attribute lastConnectErrorValue; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap default = 0; callback attribute clusterRevision default = 1; diff --git a/examples/chef/devices/rootnode_airpurifier_73a6fe2651.matter b/examples/chef/devices/rootnode_airpurifier_73a6fe2651.matter index 6dc1faa51f4c03..dc4334462e5cd8 100644 --- a/examples/chef/devices/rootnode_airpurifier_73a6fe2651.matter +++ b/examples/chef/devices/rootnode_airpurifier_73a6fe2651.matter @@ -1929,7 +1929,6 @@ endpoint 1 { ram attribute identifyType default = 0x00; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 4; @@ -1941,7 +1940,6 @@ endpoint 1 { persist attribute onOff default = 0; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 6; @@ -1958,7 +1956,6 @@ endpoint 1 { callback attribute partsList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -1973,7 +1970,6 @@ endpoint 1 { callback attribute replacementProductList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 1; @@ -1990,7 +1986,6 @@ endpoint 1 { callback attribute replacementProductList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 1; @@ -2013,7 +2008,6 @@ endpoint 1 { ram attribute airflowDirection default = 0; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0x3F; ram attribute clusterRevision default = 4; diff --git a/examples/chef/devices/rootnode_airpurifier_airqualitysensor_temperaturesensor_humiditysensor_thermostat_56de3d5f45.matter b/examples/chef/devices/rootnode_airpurifier_airqualitysensor_temperaturesensor_humiditysensor_thermostat_56de3d5f45.matter index 8271fefe262f09..7c5232970dfaf5 100644 --- a/examples/chef/devices/rootnode_airpurifier_airqualitysensor_temperaturesensor_humiditysensor_thermostat_56de3d5f45.matter +++ b/examples/chef/devices/rootnode_airpurifier_airqualitysensor_temperaturesensor_humiditysensor_thermostat_56de3d5f45.matter @@ -2680,7 +2680,6 @@ endpoint 1 { ram attribute identifyType default = 0x0; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 4; @@ -2693,7 +2692,6 @@ endpoint 1 { ram attribute nameSupport; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 4; @@ -2717,7 +2715,6 @@ endpoint 1 { callback attribute partsList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -2732,7 +2729,6 @@ endpoint 1 { callback attribute replacementProductList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 1; @@ -2749,7 +2745,6 @@ endpoint 1 { callback attribute replacementProductList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 1; @@ -2772,7 +2767,6 @@ endpoint 1 { ram attribute airflowDirection default = 0; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0x3F; ram attribute clusterRevision default = 4; @@ -2789,7 +2783,6 @@ endpoint 2 { ram attribute identifyType default = 0x00; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 4; @@ -2804,7 +2797,6 @@ endpoint 2 { callback attribute partsList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -2814,7 +2806,6 @@ endpoint 2 { callback attribute airQuality; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 1; @@ -2834,7 +2825,6 @@ endpoint 2 { callback attribute levelValue; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 3; @@ -2854,7 +2844,6 @@ endpoint 2 { callback attribute levelValue; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 3; @@ -2874,7 +2863,6 @@ endpoint 2 { callback attribute levelValue; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 3; @@ -2894,7 +2882,6 @@ endpoint 2 { callback attribute levelValue; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 3; @@ -2914,7 +2901,6 @@ endpoint 2 { callback attribute levelValue; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 3; @@ -2934,7 +2920,6 @@ endpoint 2 { callback attribute levelValue; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 3; @@ -2954,7 +2939,6 @@ endpoint 2 { callback attribute levelValue; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 3; @@ -2974,7 +2958,6 @@ endpoint 2 { callback attribute levelValue; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 3; @@ -2994,7 +2977,6 @@ endpoint 2 { callback attribute levelValue; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 3; @@ -3014,7 +2996,6 @@ endpoint 2 { callback attribute levelValue; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 3; @@ -3029,7 +3010,6 @@ endpoint 3 { ram attribute identifyType default = 0x00; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 4; @@ -3045,7 +3025,6 @@ endpoint 3 { callback attribute partsList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -3058,7 +3037,6 @@ endpoint 3 { persist attribute tolerance default = 10; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 4; @@ -3073,7 +3051,6 @@ endpoint 4 { ram attribute identifyType default = 0x00; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 4; @@ -3089,7 +3066,6 @@ endpoint 4 { callback attribute partsList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -3102,7 +3078,6 @@ endpoint 4 { ram attribute tolerance default = 1; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 3; @@ -3117,7 +3092,6 @@ endpoint 5 { ram attribute identifyType default = 0x00; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 4; @@ -3133,7 +3107,6 @@ endpoint 5 { callback attribute partsList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -3151,7 +3124,6 @@ endpoint 5 { persist attribute systemMode default = 4; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 1; ram attribute clusterRevision default = 6; diff --git a/examples/chef/devices/rootnode_airqualitysensor_e63187f6c9.matter b/examples/chef/devices/rootnode_airqualitysensor_e63187f6c9.matter index cfdae69816e667..ac2265df8d50a4 100644 --- a/examples/chef/devices/rootnode_airqualitysensor_e63187f6c9.matter +++ b/examples/chef/devices/rootnode_airqualitysensor_e63187f6c9.matter @@ -2564,7 +2564,6 @@ endpoint 1 { ram attribute identifyType default = 0x00; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 4; @@ -2579,7 +2578,6 @@ endpoint 1 { callback attribute partsList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -2604,7 +2602,6 @@ endpoint 1 { callback attribute endpointList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0x06; ram attribute clusterRevision default = 1; @@ -2614,7 +2611,6 @@ endpoint 1 { callback attribute airQuality; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 1; @@ -2627,7 +2623,6 @@ endpoint 1 { persist attribute tolerance default = 0; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 4; @@ -2640,7 +2635,6 @@ endpoint 1 { persist attribute tolerance; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 3; @@ -2660,7 +2654,6 @@ endpoint 1 { callback attribute levelValue; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 3; @@ -2680,7 +2673,6 @@ endpoint 1 { callback attribute levelValue; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 3; @@ -2700,7 +2692,6 @@ endpoint 1 { callback attribute levelValue; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 3; @@ -2720,7 +2711,6 @@ endpoint 1 { callback attribute levelValue; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 3; @@ -2740,7 +2730,6 @@ endpoint 1 { callback attribute levelValue; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 3; @@ -2760,7 +2749,6 @@ endpoint 1 { callback attribute levelValue; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 3; @@ -2780,7 +2768,6 @@ endpoint 1 { callback attribute levelValue; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 3; @@ -2800,7 +2787,6 @@ endpoint 1 { callback attribute levelValue; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 3; @@ -2820,7 +2806,6 @@ endpoint 1 { callback attribute levelValue; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 3; @@ -2840,7 +2825,6 @@ endpoint 1 { callback attribute levelValue; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 3; diff --git a/examples/chef/devices/rootnode_basicvideoplayer_0ff86e943b.matter b/examples/chef/devices/rootnode_basicvideoplayer_0ff86e943b.matter index 0bf91385a5e179..f9b32f989dbce5 100644 --- a/examples/chef/devices/rootnode_basicvideoplayer_0ff86e943b.matter +++ b/examples/chef/devices/rootnode_basicvideoplayer_0ff86e943b.matter @@ -2505,7 +2505,6 @@ endpoint 1 { persist attribute onOff default = 0; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 6; @@ -2522,7 +2521,6 @@ endpoint 1 { callback attribute partsList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -2532,7 +2530,6 @@ endpoint 1 { ram attribute MACAddress; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -2544,7 +2541,6 @@ endpoint 1 { callback attribute currentChannel; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 3; ram attribute clusterRevision default = 1; @@ -2561,7 +2557,6 @@ endpoint 1 { persist attribute currentTarget default = 0; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -2581,7 +2576,6 @@ endpoint 1 { ram attribute seekRangeStart; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 3; ram attribute clusterRevision default = 1; @@ -2605,7 +2599,6 @@ endpoint 1 { persist attribute currentInput default = 0x00; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 1; ram attribute clusterRevision default = 1; @@ -2619,7 +2612,6 @@ endpoint 1 { server cluster LowPower { callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -2630,7 +2622,6 @@ endpoint 1 { server cluster KeypadInput { callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 7; ram attribute clusterRevision default = 1; @@ -2644,7 +2635,6 @@ endpoint 1 { persist attribute currentOutput default = 0x00; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 1; ram attribute clusterRevision default = 1; @@ -2662,7 +2652,6 @@ endpoint 2 { ram attribute identifyType default = 0x00; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 4; @@ -2675,7 +2664,6 @@ endpoint 2 { persist attribute onOff default = 0; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 6; @@ -2693,7 +2681,6 @@ endpoint 2 { ram attribute onLevel default = 0xFE; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 6; @@ -2715,7 +2702,6 @@ endpoint 2 { callback attribute partsList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; diff --git a/examples/chef/devices/rootnode_contactsensor_27f76aeaf5.matter b/examples/chef/devices/rootnode_contactsensor_27f76aeaf5.matter index 77375d8443e990..8c08a4e1540b5e 100644 --- a/examples/chef/devices/rootnode_contactsensor_27f76aeaf5.matter +++ b/examples/chef/devices/rootnode_contactsensor_27f76aeaf5.matter @@ -2469,7 +2469,6 @@ endpoint 1 { ram attribute identifyType default = 0x0; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 2; @@ -2507,7 +2506,6 @@ endpoint 1 { callback attribute endpointList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0x06; ram attribute clusterRevision default = 1; diff --git a/examples/chef/devices/rootnode_contactsensor_lFAGG1bfRO.matter b/examples/chef/devices/rootnode_contactsensor_lFAGG1bfRO.matter index 5265088575f8ca..1d5b5856208131 100644 --- a/examples/chef/devices/rootnode_contactsensor_lFAGG1bfRO.matter +++ b/examples/chef/devices/rootnode_contactsensor_lFAGG1bfRO.matter @@ -2108,7 +2108,6 @@ endpoint 1 { callback attribute endpointList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0x0A; ram attribute clusterRevision default = 1; @@ -2118,7 +2117,6 @@ endpoint 1 { ram attribute stateValue default = 0; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; diff --git a/examples/chef/devices/rootnode_dimmablepluginunit_f8a9a0b9d4.matter b/examples/chef/devices/rootnode_dimmablepluginunit_f8a9a0b9d4.matter index 44865e71f3a0a0..cc875bbd196bf7 100644 --- a/examples/chef/devices/rootnode_dimmablepluginunit_f8a9a0b9d4.matter +++ b/examples/chef/devices/rootnode_dimmablepluginunit_f8a9a0b9d4.matter @@ -2191,7 +2191,6 @@ endpoint 1 { ram attribute identifyType default = 0x0; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 4; @@ -2204,7 +2203,6 @@ endpoint 1 { ram attribute nameSupport default = 0; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 4; @@ -2229,7 +2227,6 @@ endpoint 1 { persist attribute startUpOnOff default = 0; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 1; ram attribute clusterRevision default = 6; @@ -2252,7 +2249,6 @@ endpoint 1 { persist attribute startUpCurrentLevel default = 0x00; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 3; ram attribute clusterRevision default = 5; @@ -2274,7 +2270,6 @@ endpoint 1 { callback attribute partsList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -2285,7 +2280,6 @@ endpoint 1 { callback attribute fabricSceneInfo; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; diff --git a/examples/chef/devices/rootnode_dishwasher_cc105034fe.matter b/examples/chef/devices/rootnode_dishwasher_cc105034fe.matter index 8f49c108e20fab..d730676d92ece9 100644 --- a/examples/chef/devices/rootnode_dishwasher_cc105034fe.matter +++ b/examples/chef/devices/rootnode_dishwasher_cc105034fe.matter @@ -1671,7 +1671,6 @@ endpoint 0 { callback attribute supportedLocales; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -1859,7 +1858,6 @@ endpoint 1 { ram attribute onOff default = 0; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 2; ram attribute clusterRevision default = 6; @@ -1888,7 +1886,6 @@ endpoint 1 { ram attribute step default = 0; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 5; ram attribute clusterRevision default = 1; @@ -1901,7 +1898,6 @@ endpoint 1 { callback attribute currentMode; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 2; @@ -1918,7 +1914,6 @@ endpoint 1 { ram attribute supported default = 0x3F; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 1; ram attribute clusterRevision default = 1; diff --git a/examples/chef/devices/rootnode_doorlock_aNKYAreMXE.matter b/examples/chef/devices/rootnode_doorlock_aNKYAreMXE.matter index c461e7324caf6d..6aa16252672dcd 100644 --- a/examples/chef/devices/rootnode_doorlock_aNKYAreMXE.matter +++ b/examples/chef/devices/rootnode_doorlock_aNKYAreMXE.matter @@ -2586,7 +2586,6 @@ endpoint 1 { ram attribute identifyType default = 0x0; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 2; @@ -2602,7 +2601,6 @@ endpoint 1 { callback attribute partsList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -2624,7 +2622,6 @@ endpoint 1 { callback attribute endpointList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0x0A; ram attribute clusterRevision default = 2; @@ -2666,7 +2663,6 @@ endpoint 1 { ram attribute requirePINforRemoteOperation default = 0; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0x1DB3; ram attribute clusterRevision default = 7; diff --git a/examples/chef/devices/rootnode_fan_7N2TobIlOX.matter b/examples/chef/devices/rootnode_fan_7N2TobIlOX.matter index d772e29c3c26fb..78e524d7eb140a 100644 --- a/examples/chef/devices/rootnode_fan_7N2TobIlOX.matter +++ b/examples/chef/devices/rootnode_fan_7N2TobIlOX.matter @@ -1888,7 +1888,6 @@ endpoint 1 { persist attribute airflowDirection default = 0; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0x3F; ram attribute clusterRevision default = 1; diff --git a/examples/chef/devices/rootnode_genericswitch_2dfff6e516.matter b/examples/chef/devices/rootnode_genericswitch_2dfff6e516.matter index ba63c3ee079d8e..0ae39923c10a27 100644 --- a/examples/chef/devices/rootnode_genericswitch_2dfff6e516.matter +++ b/examples/chef/devices/rootnode_genericswitch_2dfff6e516.matter @@ -1748,7 +1748,6 @@ endpoint 1 { ram attribute identifyType default = 0x00; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 4; @@ -1765,7 +1764,6 @@ endpoint 1 { callback attribute tagList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -1787,7 +1785,6 @@ endpoint 1 { callback attribute endpointList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0x0A; ram attribute clusterRevision default = 1; @@ -1802,7 +1799,6 @@ endpoint 1 { persist attribute currentPosition default = 0; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0xE; ram attribute clusterRevision default = 2; diff --git a/examples/chef/devices/rootnode_genericswitch_9866e35d0b.matter b/examples/chef/devices/rootnode_genericswitch_9866e35d0b.matter index 60699fd679f7ba..6a66018ef40f60 100644 --- a/examples/chef/devices/rootnode_genericswitch_9866e35d0b.matter +++ b/examples/chef/devices/rootnode_genericswitch_9866e35d0b.matter @@ -1748,7 +1748,6 @@ endpoint 1 { ram attribute identifyType default = 0x00; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 4; @@ -1765,7 +1764,6 @@ endpoint 1 { callback attribute tagList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -1787,7 +1785,6 @@ endpoint 1 { callback attribute endpointList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0x0A; ram attribute clusterRevision default = 1; @@ -1799,7 +1796,6 @@ endpoint 1 { persist attribute currentPosition default = 0; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 1; ram attribute clusterRevision default = 2; diff --git a/examples/chef/devices/rootnode_laundrydryer_01796fe396.matter b/examples/chef/devices/rootnode_laundrydryer_01796fe396.matter index b917fa102e6228..bb05b243f8283d 100644 --- a/examples/chef/devices/rootnode_laundrydryer_01796fe396.matter +++ b/examples/chef/devices/rootnode_laundrydryer_01796fe396.matter @@ -1562,7 +1562,6 @@ endpoint 0 { callback attribute supportedLocales; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -1750,7 +1749,6 @@ endpoint 1 { ram attribute onOff default = 0; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 2; ram attribute clusterRevision default = 6; @@ -1767,7 +1765,6 @@ endpoint 1 { callback attribute partsList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -1778,7 +1775,6 @@ endpoint 1 { callback attribute supportedTemperatureLevels; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 2; ram attribute clusterRevision default = 1; @@ -1797,7 +1793,6 @@ endpoint 1 { callback attribute operationalError; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 3; diff --git a/examples/chef/devices/rootnode_laundrywasher_fb10d238c8.matter b/examples/chef/devices/rootnode_laundrywasher_fb10d238c8.matter index e595c866c2a47b..f38dd8f3dfb7fd 100644 --- a/examples/chef/devices/rootnode_laundrywasher_fb10d238c8.matter +++ b/examples/chef/devices/rootnode_laundrywasher_fb10d238c8.matter @@ -1657,7 +1657,6 @@ endpoint 1 { callback attribute currentMode; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 2; @@ -1673,7 +1672,6 @@ endpoint 1 { callback attribute supportedRinses; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; diff --git a/examples/chef/devices/rootnode_onofflight_samplemei.matter b/examples/chef/devices/rootnode_onofflight_samplemei.matter index f7db9d69aeb50c..32b351b6e81791 100644 --- a/examples/chef/devices/rootnode_onofflight_samplemei.matter +++ b/examples/chef/devices/rootnode_onofflight_samplemei.matter @@ -2087,7 +2087,6 @@ endpoint 1 { ram attribute flipFlop default = false; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; diff --git a/examples/chef/devices/rootnode_pump_5f904818cc.matter b/examples/chef/devices/rootnode_pump_5f904818cc.matter index 8ea352ca7c785f..8cd43edf190fd9 100644 --- a/examples/chef/devices/rootnode_pump_5f904818cc.matter +++ b/examples/chef/devices/rootnode_pump_5f904818cc.matter @@ -1733,7 +1733,6 @@ endpoint 1 { ram attribute maxMeasuredValue default = 32767; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -1745,7 +1744,6 @@ endpoint 1 { ram attribute maxMeasuredValue default = 32767; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 3; @@ -1757,7 +1755,6 @@ endpoint 1 { ram attribute maxMeasuredValue default = 65534; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; diff --git a/examples/chef/devices/rootnode_refrigerator_temperaturecontrolledcabinet_temperaturecontrolledcabinet_ffdb696680.matter b/examples/chef/devices/rootnode_refrigerator_temperaturecontrolledcabinet_temperaturecontrolledcabinet_ffdb696680.matter index 80faecb735c5ff..bfbd486f6e0d01 100644 --- a/examples/chef/devices/rootnode_refrigerator_temperaturecontrolledcabinet_temperaturecontrolledcabinet_ffdb696680.matter +++ b/examples/chef/devices/rootnode_refrigerator_temperaturecontrolledcabinet_temperaturecontrolledcabinet_ffdb696680.matter @@ -1635,7 +1635,6 @@ endpoint 1 { callback attribute currentMode; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 2; @@ -1651,7 +1650,6 @@ endpoint 1 { ram attribute supported default = 0x1; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -1694,7 +1692,6 @@ endpoint 2 { ram attribute maxMeasuredValue default = 2000; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 4; @@ -1737,7 +1734,6 @@ endpoint 3 { ram attribute maxMeasuredValue default = 2000; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 4; diff --git a/examples/chef/devices/rootnode_roboticvacuumcleaner_1807ff0c49.matter b/examples/chef/devices/rootnode_roboticvacuumcleaner_1807ff0c49.matter index b4094e13d84761..dbc56cd15e5d26 100644 --- a/examples/chef/devices/rootnode_roboticvacuumcleaner_1807ff0c49.matter +++ b/examples/chef/devices/rootnode_roboticvacuumcleaner_1807ff0c49.matter @@ -1975,7 +1975,6 @@ endpoint 1 { ram attribute identifyType default = 0x0; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 2; @@ -1988,7 +1987,6 @@ endpoint 1 { ram attribute nameSupport; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 3; @@ -2012,7 +2010,6 @@ endpoint 1 { callback attribute partsList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -2028,7 +2025,6 @@ endpoint 1 { callback attribute endpointList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -2039,7 +2035,6 @@ endpoint 1 { callback attribute currentMode; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 3; @@ -2053,7 +2048,6 @@ endpoint 1 { callback attribute currentMode; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 3; @@ -2073,7 +2067,6 @@ endpoint 1 { callback attribute operationalError; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; diff --git a/examples/chef/devices/rootnode_roomairconditioner_9cf3607804.matter b/examples/chef/devices/rootnode_roomairconditioner_9cf3607804.matter index 3ebdc0a23132a1..467ad0c462767d 100644 --- a/examples/chef/devices/rootnode_roomairconditioner_9cf3607804.matter +++ b/examples/chef/devices/rootnode_roomairconditioner_9cf3607804.matter @@ -2084,7 +2084,6 @@ endpoint 1 { ram attribute identifyType default = 0x0; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 2; @@ -2117,7 +2116,6 @@ endpoint 1 { persist attribute onOff default = 0; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 2; ram attribute clusterRevision default = 5; @@ -2134,7 +2132,6 @@ endpoint 1 { callback attribute partsList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -2157,7 +2154,6 @@ endpoint 1 { persist attribute ACLouverPosition default = 0; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 3; ram attribute clusterRevision default = 7; @@ -2175,7 +2171,6 @@ endpoint 1 { ram attribute airflowDirection default = 0; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 37; ram attribute clusterRevision default = 1; @@ -2188,7 +2183,6 @@ endpoint 1 { ram attribute keypadLockout default = 0x00; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 2; @@ -2203,7 +2197,6 @@ endpoint 2 { ram attribute identifyType default = 0x00; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 4; @@ -2219,7 +2212,6 @@ endpoint 2 { callback attribute partsList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -2231,7 +2223,6 @@ endpoint 2 { ram attribute maxMeasuredValue default = 4500; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 3; @@ -2246,7 +2237,6 @@ endpoint 3 { ram attribute identifyType default = 0x00; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 4; @@ -2262,7 +2252,6 @@ endpoint 3 { callback attribute partsList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -2274,7 +2263,6 @@ endpoint 3 { ram attribute maxMeasuredValue default = 10000; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 3; diff --git a/examples/chef/devices/rootnode_smokecoalarm_686fe0dcb8.matter b/examples/chef/devices/rootnode_smokecoalarm_686fe0dcb8.matter index 1f6e1c17b7828e..b7e31f0bdcbf1c 100644 --- a/examples/chef/devices/rootnode_smokecoalarm_686fe0dcb8.matter +++ b/examples/chef/devices/rootnode_smokecoalarm_686fe0dcb8.matter @@ -1881,7 +1881,6 @@ endpoint 1 { ram attribute identifyType default = 0x0; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 2; @@ -1917,7 +1916,6 @@ endpoint 1 { callback attribute partsList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -1934,7 +1932,6 @@ endpoint 1 { callback attribute endpointList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 2; ram attribute clusterRevision default = 2; @@ -1967,7 +1964,6 @@ endpoint 1 { ram attribute expiryDate default = 0; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 3; ram attribute clusterRevision default = 1; diff --git a/examples/chef/devices/rootnode_waterleakdetector_0b067acfa3.matter b/examples/chef/devices/rootnode_waterleakdetector_0b067acfa3.matter index bd89a853121fcb..1ea6c421aba885 100644 --- a/examples/chef/devices/rootnode_waterleakdetector_0b067acfa3.matter +++ b/examples/chef/devices/rootnode_waterleakdetector_0b067acfa3.matter @@ -1845,7 +1845,6 @@ endpoint 1 { ram attribute identifyType default = 0x0; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 2; @@ -1858,7 +1857,6 @@ endpoint 1 { ram attribute nameSupport; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 3; @@ -1882,7 +1880,6 @@ endpoint 1 { callback attribute partsList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -1904,7 +1901,6 @@ endpoint 1 { callback attribute endpointList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0x06; ram attribute clusterRevision default = 1; @@ -1914,7 +1910,6 @@ endpoint 1 { ram attribute stateValue; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -1923,7 +1918,6 @@ endpoint 1 { server cluster BooleanStateConfiguration { callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; diff --git a/examples/chef/devices/rootnode_watervalve_6bb39f1f67.matter b/examples/chef/devices/rootnode_watervalve_6bb39f1f67.matter index cf3009d2913f9a..0e4ffe5dc8ee14 100644 --- a/examples/chef/devices/rootnode_watervalve_6bb39f1f67.matter +++ b/examples/chef/devices/rootnode_watervalve_6bb39f1f67.matter @@ -1652,7 +1652,6 @@ endpoint 0 { callback attribute supportedLocales; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -1787,7 +1786,6 @@ endpoint 1 { ram attribute identifyType default = 0x0; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 2; @@ -1803,7 +1801,6 @@ endpoint 1 { callback attribute partsList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -1826,7 +1823,6 @@ endpoint 1 { callback attribute endpointList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -1840,7 +1836,6 @@ endpoint 1 { ram attribute targetState; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; diff --git a/examples/contact-sensor-app/nxp/zap-lit/contact-sensor-app.matter b/examples/contact-sensor-app/nxp/zap-lit/contact-sensor-app.matter index a5e91d91f11783..dd5f9ab0616aa7 100644 --- a/examples/contact-sensor-app/nxp/zap-lit/contact-sensor-app.matter +++ b/examples/contact-sensor-app/nxp/zap-lit/contact-sensor-app.matter @@ -1746,7 +1746,6 @@ endpoint 0 { callback attribute accessControlEntriesPerFabric; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; callback attribute clusterRevision; @@ -1773,7 +1772,6 @@ endpoint 0 { callback attribute maxPathsPerInvoke; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 3; @@ -1801,7 +1799,6 @@ endpoint 0 { callback attribute supportsConcurrentConnection; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -1827,7 +1824,6 @@ endpoint 0 { ram attribute threadVersion; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 2; ram attribute clusterRevision default = 2; @@ -1845,7 +1841,6 @@ endpoint 0 { server cluster DiagnosticLogs { callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -1863,7 +1858,6 @@ endpoint 0 { callback attribute testEventTriggersEnabled default = false; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -1947,7 +1941,6 @@ endpoint 0 { callback attribute activeNetworkFaultsList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0x000F; ram attribute clusterRevision default = 2; @@ -2019,7 +2012,6 @@ endpoint 0 { callback attribute maximumCheckInBackOff; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0x000F; ram attribute clusterRevision default = 3; @@ -2065,7 +2057,6 @@ endpoint 1 { ram attribute stateValue default = 0; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; diff --git a/examples/contact-sensor-app/nxp/zap-sit/contact-sensor-app.matter b/examples/contact-sensor-app/nxp/zap-sit/contact-sensor-app.matter index 36db43dcb6487c..1cd10f35718b3f 100644 --- a/examples/contact-sensor-app/nxp/zap-sit/contact-sensor-app.matter +++ b/examples/contact-sensor-app/nxp/zap-sit/contact-sensor-app.matter @@ -1746,7 +1746,6 @@ endpoint 0 { callback attribute accessControlEntriesPerFabric; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; callback attribute clusterRevision; @@ -1773,7 +1772,6 @@ endpoint 0 { callback attribute maxPathsPerInvoke; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 3; @@ -1801,7 +1799,6 @@ endpoint 0 { callback attribute supportsConcurrentConnection; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -1827,7 +1824,6 @@ endpoint 0 { ram attribute threadVersion; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 2; ram attribute clusterRevision default = 2; @@ -1845,7 +1841,6 @@ endpoint 0 { server cluster DiagnosticLogs { callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -1863,7 +1858,6 @@ endpoint 0 { callback attribute testEventTriggersEnabled default = false; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -1947,7 +1941,6 @@ endpoint 0 { callback attribute activeNetworkFaultsList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0x000F; ram attribute clusterRevision default = 2; @@ -2012,7 +2005,6 @@ endpoint 0 { callback attribute activeModeThreshold; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0x0000; ram attribute clusterRevision default = 3; @@ -2052,7 +2044,6 @@ endpoint 1 { ram attribute stateValue default = 0; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; diff --git a/examples/dishwasher-app/silabs/data_model/dishwasher-thread-app.matter b/examples/dishwasher-app/silabs/data_model/dishwasher-thread-app.matter index 43ac95d4ba4b7c..93222a8580e5ba 100644 --- a/examples/dishwasher-app/silabs/data_model/dishwasher-thread-app.matter +++ b/examples/dishwasher-app/silabs/data_model/dishwasher-thread-app.matter @@ -2618,7 +2618,6 @@ endpoint 1 { ram attribute identifyType default = 0x00; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 4; @@ -2634,7 +2633,6 @@ endpoint 1 { callback attribute partsList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -2657,7 +2655,6 @@ endpoint 1 { callback attribute operationalError; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -2680,7 +2677,6 @@ endpoint 2 { callback attribute partsList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -2709,7 +2705,6 @@ endpoint 2 { callback attribute neutralCurrent; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 1; @@ -2722,7 +2717,6 @@ endpoint 2 { callback attribute cumulativeEnergyReset; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 1; @@ -2733,7 +2727,6 @@ endpoint 2 { callback attribute activeEndpoints; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 1; @@ -2750,7 +2743,6 @@ endpoint 3 { callback attribute partsList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -2771,7 +2763,6 @@ endpoint 3 { callback attribute optOutState; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 3; @@ -2791,7 +2782,6 @@ endpoint 3 { callback attribute currentMode; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 1; diff --git a/examples/dishwasher-app/silabs/data_model/dishwasher-wifi-app.matter b/examples/dishwasher-app/silabs/data_model/dishwasher-wifi-app.matter index 4d1106449ad2fd..24abdb39862888 100644 --- a/examples/dishwasher-app/silabs/data_model/dishwasher-wifi-app.matter +++ b/examples/dishwasher-app/silabs/data_model/dishwasher-wifi-app.matter @@ -2478,7 +2478,6 @@ endpoint 1 { ram attribute identifyType default = 0x00; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 4; @@ -2494,7 +2493,6 @@ endpoint 1 { callback attribute partsList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -2517,7 +2515,6 @@ endpoint 1 { callback attribute operationalError; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -2540,7 +2537,6 @@ endpoint 2 { callback attribute partsList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -2569,7 +2565,6 @@ endpoint 2 { callback attribute neutralCurrent; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 1; @@ -2582,7 +2577,6 @@ endpoint 2 { callback attribute cumulativeEnergyReset; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 1; @@ -2593,7 +2587,6 @@ endpoint 2 { callback attribute activeEndpoints; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 1; @@ -2610,7 +2603,6 @@ endpoint 3 { callback attribute partsList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -2631,7 +2623,6 @@ endpoint 3 { callback attribute optOutState; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 3; @@ -2651,7 +2642,6 @@ endpoint 3 { callback attribute currentMode; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 1; diff --git a/examples/energy-management-app/energy-management-common/energy-management-app.matter b/examples/energy-management-app/energy-management-common/energy-management-app.matter index 5da8448194d2f8..a3c2b9f58b5485 100644 --- a/examples/energy-management-app/energy-management-common/energy-management-app.matter +++ b/examples/energy-management-app/energy-management-common/energy-management-app.matter @@ -2409,7 +2409,6 @@ endpoint 0 { callback attribute partsList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -2423,7 +2422,6 @@ endpoint 0 { callback attribute accessControlEntriesPerFabric; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; callback attribute clusterRevision; @@ -2448,7 +2446,6 @@ endpoint 0 { callback attribute maxPathsPerInvoke; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 3; @@ -2459,7 +2456,6 @@ endpoint 0 { callback attribute supportedLocales; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -2469,7 +2465,6 @@ endpoint 0 { ram attribute hourFormat; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -2478,7 +2473,6 @@ endpoint 0 { server cluster UnitLocalization { callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -2494,7 +2488,6 @@ endpoint 0 { callback attribute endpointList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 2; @@ -2508,7 +2501,6 @@ endpoint 0 { callback attribute supportsConcurrentConnection; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -2531,7 +2523,6 @@ endpoint 0 { callback attribute supportedWiFiBands; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -2544,7 +2535,6 @@ endpoint 0 { ram attribute testEventTriggersEnabled; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -2560,7 +2550,6 @@ endpoint 0 { callback attribute adminVendorId; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -2578,7 +2567,6 @@ endpoint 0 { callback attribute currentFabricIndex; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -2604,7 +2592,6 @@ endpoint 0 { callback attribute maxGroupKeysPerFabric; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -2627,7 +2614,6 @@ endpoint 1 { ram attribute identifyType default = 0x00; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 4; @@ -2643,7 +2629,6 @@ endpoint 1 { callback attribute partsList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -2671,7 +2656,6 @@ endpoint 1 { callback attribute neutralCurrent; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 1; @@ -2688,7 +2672,6 @@ endpoint 1 { callback attribute cumulativeEnergyReset; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 1; @@ -2703,7 +2686,6 @@ endpoint 1 { callback attribute boostState; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -2727,7 +2709,6 @@ endpoint 1 { callback attribute optOutState; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 4; @@ -2768,7 +2749,6 @@ endpoint 1 { callback attribute sessionEnergyCharged; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 2; @@ -2786,7 +2766,6 @@ endpoint 1 { server cluster PowerTopology { callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 1; @@ -2797,7 +2776,6 @@ endpoint 1 { callback attribute currentMode; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 1; @@ -2811,7 +2789,6 @@ endpoint 1 { callback attribute currentMode; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 1; @@ -2825,7 +2802,6 @@ endpoint 1 { callback attribute currentMode; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 1; diff --git a/examples/fabric-bridge-app/fabric-bridge-common/fabric-bridge-app.matter b/examples/fabric-bridge-app/fabric-bridge-common/fabric-bridge-app.matter index 11dcf2f03db88e..06e76db5ecee1a 100644 --- a/examples/fabric-bridge-app/fabric-bridge-common/fabric-bridge-app.matter +++ b/examples/fabric-bridge-app/fabric-bridge-common/fabric-bridge-app.matter @@ -2094,7 +2094,6 @@ endpoint 1 { ram attribute supportedDeviceCategories default = 0; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; diff --git a/examples/fabric-sync/bridge/fabric-bridge.matter b/examples/fabric-sync/bridge/fabric-bridge.matter index 11dcf2f03db88e..06e76db5ecee1a 100644 --- a/examples/fabric-sync/bridge/fabric-bridge.matter +++ b/examples/fabric-sync/bridge/fabric-bridge.matter @@ -2094,7 +2094,6 @@ endpoint 1 { ram attribute supportedDeviceCategories default = 0; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; diff --git a/examples/laundry-washer-app/nxp/zap/laundry-washer-app.matter b/examples/laundry-washer-app/nxp/zap/laundry-washer-app.matter index 39546259b0bd19..28a2f46d284903 100644 --- a/examples/laundry-washer-app/nxp/zap/laundry-washer-app.matter +++ b/examples/laundry-washer-app/nxp/zap/laundry-washer-app.matter @@ -2208,7 +2208,6 @@ endpoint 0 { callback attribute maxPathsPerInvoke; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 2; @@ -2224,7 +2223,6 @@ endpoint 0 { ram attribute updateStateProgress default = 0; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -2235,7 +2233,6 @@ endpoint 0 { server cluster UnitLocalization { callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -2269,7 +2266,6 @@ endpoint 0 { ram attribute lastConnectErrorValue; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 2; ram attribute clusterRevision default = 1; @@ -2295,7 +2291,6 @@ endpoint 0 { callback attribute testEventTriggersEnabled default = false; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -2314,7 +2309,6 @@ endpoint 0 { callback attribute currentMaxRate; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -2380,7 +2374,6 @@ endpoint 1 { ram attribute identifyType default = 0x00; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 4; @@ -2393,7 +2386,6 @@ endpoint 1 { ram attribute nameSupport; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 4; @@ -2418,7 +2410,6 @@ endpoint 1 { persist attribute startUpOnOff default = 0xFF; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 1; ram attribute clusterRevision default = 5; @@ -2438,7 +2429,6 @@ endpoint 1 { callback attribute partsList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -2448,7 +2438,6 @@ endpoint 1 { callback attribute binding; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -2462,7 +2451,6 @@ endpoint 1 { callback attribute endpointList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 1; ram attribute clusterRevision default = 2; @@ -2472,7 +2460,6 @@ endpoint 1 { callback attribute labelList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -2482,7 +2469,6 @@ endpoint 1 { callback attribute labelList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -2497,7 +2483,6 @@ endpoint 1 { ram attribute onMode; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -2512,7 +2497,6 @@ endpoint 1 { callback attribute onMode; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 1; @@ -2528,7 +2512,6 @@ endpoint 1 { callback attribute supportedRinses; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 3; ram attribute clusterRevision default = 1; @@ -2539,7 +2522,6 @@ endpoint 1 { callback attribute supportedTemperatureLevels; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 2; ram attribute clusterRevision default = 1; @@ -2558,7 +2540,6 @@ endpoint 1 { callback attribute operationalError; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; diff --git a/examples/light-switch-app/qpg/zap/switch.matter b/examples/light-switch-app/qpg/zap/switch.matter index 979ae18fa4234a..03e0f51ad0830d 100644 --- a/examples/light-switch-app/qpg/zap/switch.matter +++ b/examples/light-switch-app/qpg/zap/switch.matter @@ -2898,7 +2898,6 @@ endpoint 0 { callback attribute partsList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -2914,7 +2913,6 @@ endpoint 0 { callback attribute accessControlEntriesPerFabric; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; callback attribute clusterRevision; @@ -2947,7 +2945,6 @@ endpoint 0 { callback attribute maxPathsPerInvoke; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 3; @@ -2963,7 +2960,6 @@ endpoint 0 { ram attribute updateStateProgress default = 0; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -2986,7 +2982,6 @@ endpoint 0 { callback attribute endpointList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 10; ram attribute clusterRevision default = 1; @@ -3000,7 +2995,6 @@ endpoint 0 { callback attribute supportsConcurrentConnection; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -3026,7 +3020,6 @@ endpoint 0 { callback attribute threadVersion; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 2; ram attribute clusterRevision default = 1; @@ -3044,7 +3037,6 @@ endpoint 0 { server cluster DiagnosticLogs { callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -3085,7 +3077,6 @@ endpoint 0 { callback attribute currentHeapHighWatermark; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 1; @@ -3156,7 +3147,6 @@ endpoint 0 { callback attribute activeNetworkFaultsList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0x000F; ram attribute clusterRevision default = 2; @@ -3170,7 +3160,6 @@ endpoint 0 { callback attribute adminVendorId; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 1; ram attribute clusterRevision default = 1; @@ -3189,7 +3178,6 @@ endpoint 0 { callback attribute currentFabricIndex; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -3215,7 +3203,6 @@ endpoint 0 { callback attribute maxGroupKeysPerFabric; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -3232,7 +3219,6 @@ endpoint 0 { callback attribute labelList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -3242,7 +3228,6 @@ endpoint 0 { callback attribute labelList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -3260,7 +3245,6 @@ endpoint 0 { ram attribute operatingMode default = 1; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0x0007; ram attribute clusterRevision default = 3; @@ -3286,7 +3270,6 @@ endpoint 1 { ram attribute identifyType default = 0x00; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 4; @@ -3322,7 +3305,6 @@ endpoint 1 { callback attribute partsList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -3332,7 +3314,6 @@ endpoint 1 { callback attribute binding; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -3347,7 +3328,6 @@ endpoint 2 { ram attribute identifyType default = 0x00; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 4; @@ -3363,7 +3343,6 @@ endpoint 2 { callback attribute partsList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -3381,7 +3360,6 @@ endpoint 2 { ram attribute multiPressMax default = 2; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 30; ram attribute clusterRevision default = 2; diff --git a/examples/lighting-app/silabs/data_model/lighting-thread-app.matter b/examples/lighting-app/silabs/data_model/lighting-thread-app.matter index cae4c8301878c4..49684770a3bcaa 100644 --- a/examples/lighting-app/silabs/data_model/lighting-thread-app.matter +++ b/examples/lighting-app/silabs/data_model/lighting-thread-app.matter @@ -2536,7 +2536,6 @@ endpoint 1 { ram attribute identifyType default = 0x0; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 4; @@ -2549,7 +2548,6 @@ endpoint 1 { ram attribute nameSupport; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 4; @@ -2574,7 +2572,6 @@ endpoint 1 { persist attribute startUpOnOff default = 0xFF; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 1; ram attribute clusterRevision default = 6; @@ -2604,7 +2601,6 @@ endpoint 1 { persist attribute startUpCurrentLevel default = 255; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 3; ram attribute clusterRevision default = 6; @@ -2626,7 +2622,6 @@ endpoint 1 { callback attribute partsList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -2638,7 +2633,6 @@ endpoint 1 { callback attribute fabricSceneInfo; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 1; ram attribute clusterRevision default = 1; @@ -2682,7 +2676,6 @@ endpoint 1 { persist attribute startUpColorTemperatureMireds default = 0x00FA; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0x1F; ram attribute clusterRevision default = 7; diff --git a/examples/lighting-app/silabs/data_model/lighting-wifi-app.matter b/examples/lighting-app/silabs/data_model/lighting-wifi-app.matter index 33e76146049534..003a38e52c0214 100644 --- a/examples/lighting-app/silabs/data_model/lighting-wifi-app.matter +++ b/examples/lighting-app/silabs/data_model/lighting-wifi-app.matter @@ -2808,7 +2808,6 @@ endpoint 1 { ram attribute identifyType default = 0x0; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 4; @@ -2821,7 +2820,6 @@ endpoint 1 { ram attribute nameSupport; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 4; @@ -2846,7 +2844,6 @@ endpoint 1 { persist attribute startUpOnOff default = 0xFF; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 1; ram attribute clusterRevision default = 6; @@ -2876,7 +2873,6 @@ endpoint 1 { persist attribute startUpCurrentLevel default = 255; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 3; ram attribute clusterRevision default = 6; @@ -2898,7 +2894,6 @@ endpoint 1 { callback attribute partsList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -2918,7 +2913,6 @@ endpoint 1 { callback attribute endpointList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 1; ram attribute clusterRevision default = 2; @@ -2930,7 +2924,6 @@ endpoint 1 { callback attribute fabricSceneInfo; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 1; ram attribute clusterRevision default = 1; diff --git a/examples/lit-icd-app/lit-icd-common/lit-icd-server-app.matter b/examples/lit-icd-app/lit-icd-common/lit-icd-server-app.matter index e67ae7524be12e..3c51bf0b1bdf73 100644 --- a/examples/lit-icd-app/lit-icd-common/lit-icd-server-app.matter +++ b/examples/lit-icd-app/lit-icd-common/lit-icd-server-app.matter @@ -1833,7 +1833,6 @@ endpoint 0 { callback attribute partsList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -1848,7 +1847,6 @@ endpoint 0 { callback attribute accessControlEntriesPerFabric; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; callback attribute clusterRevision; @@ -1873,7 +1871,6 @@ endpoint 0 { callback attribute maxPathsPerInvoke; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 3; @@ -1896,7 +1893,6 @@ endpoint 0 { server cluster UnitLocalization { callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -1910,7 +1906,6 @@ endpoint 0 { callback attribute supportsConcurrentConnection; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -1934,7 +1929,6 @@ endpoint 0 { ram attribute lastConnectErrorValue; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 2; ram attribute clusterRevision default = 1; @@ -1957,7 +1951,6 @@ endpoint 0 { callback attribute testEventTriggersEnabled; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -2021,7 +2014,6 @@ endpoint 0 { callback attribute adminVendorId; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -2039,7 +2031,6 @@ endpoint 0 { callback attribute currentFabricIndex; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -2065,7 +2056,6 @@ endpoint 0 { callback attribute maxGroupKeysPerFabric; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -2103,7 +2093,6 @@ endpoint 0 { callback attribute maximumCheckInBackOff; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0x000F; ram attribute clusterRevision default = 3; @@ -2124,7 +2113,6 @@ endpoint 1 { ram attribute identifyType default = 0x00; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 4; @@ -2140,7 +2128,6 @@ endpoint 1 { callback attribute partsList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -2150,7 +2137,6 @@ endpoint 1 { ram attribute stateValue; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; diff --git a/examples/lock-app/lock-common/lock-app.matter b/examples/lock-app/lock-common/lock-app.matter index 94c2fcf3bb04fb..650458149c4620 100644 --- a/examples/lock-app/lock-common/lock-app.matter +++ b/examples/lock-app/lock-common/lock-app.matter @@ -2811,7 +2811,6 @@ endpoint 0 { callback attribute partsList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -2827,7 +2826,6 @@ endpoint 0 { callback attribute accessControlEntriesPerFabric; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 1; callback attribute clusterRevision; @@ -2860,7 +2858,6 @@ endpoint 0 { callback attribute maxPathsPerInvoke; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 3; @@ -2883,7 +2880,6 @@ endpoint 0 { server cluster UnitLocalization { callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -2899,7 +2895,6 @@ endpoint 0 { callback attribute endpointList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 1; ram attribute clusterRevision default = 2; @@ -2913,7 +2908,6 @@ endpoint 0 { callback attribute supportsConcurrentConnection; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -2937,7 +2931,6 @@ endpoint 0 { ram attribute lastConnectErrorValue; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 2; ram attribute clusterRevision default = 1; @@ -2977,7 +2970,6 @@ endpoint 0 { callback attribute testEventTriggersEnabled default = false; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -3113,7 +3105,6 @@ endpoint 0 { callback attribute adminVendorId; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -3131,7 +3122,6 @@ endpoint 0 { callback attribute currentFabricIndex; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -3157,7 +3147,6 @@ endpoint 0 { callback attribute maxGroupKeysPerFabric; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -3200,7 +3189,6 @@ endpoint 1 { ram attribute identifyType default = 0x0; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 4; @@ -3216,7 +3204,6 @@ endpoint 1 { callback attribute partsList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -3234,7 +3221,6 @@ endpoint 1 { callback attribute endpointList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0x0A; ram attribute clusterRevision default = 2; @@ -3283,7 +3269,6 @@ endpoint 1 { callback attribute numberOfAliroEndpointKeysSupported; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0x7DB3; ram attribute clusterRevision default = 7; diff --git a/examples/lock-app/nxp/zap/lock-app.matter b/examples/lock-app/nxp/zap/lock-app.matter index 8cf448449a5d76..281f19877b8eab 100644 --- a/examples/lock-app/nxp/zap/lock-app.matter +++ b/examples/lock-app/nxp/zap/lock-app.matter @@ -2386,7 +2386,6 @@ endpoint 0 { callback attribute partsList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -2402,7 +2401,6 @@ endpoint 0 { callback attribute accessControlEntriesPerFabric; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 1; callback attribute clusterRevision; @@ -2429,7 +2427,6 @@ endpoint 0 { callback attribute maxPathsPerInvoke; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 3; @@ -2445,7 +2442,6 @@ endpoint 0 { ram attribute updateStateProgress default = 0; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -2458,7 +2454,6 @@ endpoint 0 { callback attribute supportedLocales; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -2472,7 +2467,6 @@ endpoint 0 { callback attribute supportsConcurrentConnection; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -2498,7 +2492,6 @@ endpoint 0 { ram attribute threadVersion; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 2; ram attribute clusterRevision default = 2; @@ -2516,7 +2509,6 @@ endpoint 0 { server cluster DiagnosticLogs { callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -2534,7 +2526,6 @@ endpoint 0 { callback attribute testEventTriggersEnabled default = false; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -2618,7 +2609,6 @@ endpoint 0 { callback attribute activeNetworkFaultsList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0x000F; ram attribute clusterRevision default = 2; @@ -2632,7 +2622,6 @@ endpoint 0 { callback attribute adminVendorId; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -2650,7 +2639,6 @@ endpoint 0 { callback attribute currentFabricIndex; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -2676,7 +2664,6 @@ endpoint 0 { callback attribute maxGroupKeysPerFabric; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -2695,7 +2682,6 @@ endpoint 0 { callback attribute activeModeThreshold; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0x0000; ram attribute clusterRevision default = 1; @@ -2710,7 +2696,6 @@ endpoint 1 { ram attribute identifyType default = 0x0; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 4; @@ -2726,7 +2711,6 @@ endpoint 1 { callback attribute partsList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -2775,7 +2759,6 @@ endpoint 1 { callback attribute numberOfAliroEndpointKeysSupported; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0x7DB3; ram attribute clusterRevision default = 7; diff --git a/examples/lock-app/qpg/zap/lock.matter b/examples/lock-app/qpg/zap/lock.matter index 53bf1d4f8d8499..74ab5d744a5702 100644 --- a/examples/lock-app/qpg/zap/lock.matter +++ b/examples/lock-app/qpg/zap/lock.matter @@ -2804,7 +2804,6 @@ endpoint 0 { callback attribute activeModeThreshold; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0x0000; ram attribute clusterRevision default = 3; diff --git a/examples/lock-app/silabs/data_model/lock-app.matter b/examples/lock-app/silabs/data_model/lock-app.matter index bf8c297e1c272f..512435d9989b24 100644 --- a/examples/lock-app/silabs/data_model/lock-app.matter +++ b/examples/lock-app/silabs/data_model/lock-app.matter @@ -2811,7 +2811,6 @@ endpoint 0 { callback attribute partsList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -2827,7 +2826,6 @@ endpoint 0 { callback attribute accessControlEntriesPerFabric; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 1; callback attribute clusterRevision; @@ -2860,7 +2858,6 @@ endpoint 0 { callback attribute maxPathsPerInvoke; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 3; @@ -2883,7 +2880,6 @@ endpoint 0 { server cluster UnitLocalization { callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -2899,7 +2895,6 @@ endpoint 0 { callback attribute endpointList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 1; ram attribute clusterRevision default = 2; @@ -2913,7 +2908,6 @@ endpoint 0 { callback attribute supportsConcurrentConnection; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -2937,7 +2931,6 @@ endpoint 0 { ram attribute lastConnectErrorValue; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 2; ram attribute clusterRevision default = 1; @@ -2977,7 +2970,6 @@ endpoint 0 { callback attribute testEventTriggersEnabled default = false; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -3113,7 +3105,6 @@ endpoint 0 { callback attribute adminVendorId; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -3131,7 +3122,6 @@ endpoint 0 { callback attribute currentFabricIndex; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -3157,7 +3147,6 @@ endpoint 0 { callback attribute maxGroupKeysPerFabric; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -3200,7 +3189,6 @@ endpoint 1 { ram attribute identifyType default = 0x0; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 4; @@ -3216,7 +3204,6 @@ endpoint 1 { callback attribute partsList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -3234,7 +3221,6 @@ endpoint 1 { callback attribute endpointList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0x0A; ram attribute clusterRevision default = 2; @@ -3274,7 +3260,6 @@ endpoint 1 { ram attribute requirePINforRemoteOperation default = 0; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0x7DB3; ram attribute clusterRevision default = 7; diff --git a/examples/microwave-oven-app/microwave-oven-common/microwave-oven-app.matter b/examples/microwave-oven-app/microwave-oven-common/microwave-oven-app.matter index f22729df8880f1..fbc5c3625aad5f 100644 --- a/examples/microwave-oven-app/microwave-oven-common/microwave-oven-app.matter +++ b/examples/microwave-oven-app/microwave-oven-common/microwave-oven-app.matter @@ -1537,7 +1537,6 @@ endpoint 0 { callback attribute maxPathsPerInvoke; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 3; @@ -1727,7 +1726,6 @@ endpoint 1 { callback attribute partsList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -1738,7 +1736,6 @@ endpoint 1 { callback attribute currentMode; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 1; @@ -1754,7 +1751,6 @@ endpoint 1 { callback attribute wattRating; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 1; @@ -1774,7 +1770,6 @@ endpoint 1 { callback attribute operationalError; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 2; diff --git a/examples/network-manager-app/network-manager-common/network-manager-app.matter b/examples/network-manager-app/network-manager-common/network-manager-app.matter index 5d53e157329f58..4847e0ff9e22c2 100644 --- a/examples/network-manager-app/network-manager-common/network-manager-app.matter +++ b/examples/network-manager-app/network-manager-common/network-manager-app.matter @@ -1697,7 +1697,6 @@ endpoint 0 { callback attribute activeNetworkFaultsList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 2; @@ -1802,7 +1801,6 @@ endpoint 1 { callback attribute partsList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -1813,7 +1811,6 @@ endpoint 1 { callback attribute passphraseSurrogate; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -1831,7 +1828,6 @@ endpoint 1 { callback attribute pendingDatasetTimestamp; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 1; @@ -1849,7 +1845,6 @@ endpoint 1 { callback attribute threadNetworkTableSize; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; diff --git a/examples/ota-requestor-app/ota-requestor-common/ota-requestor-app.matter b/examples/ota-requestor-app/ota-requestor-common/ota-requestor-app.matter index b7514cf573c870..5269b6e7094558 100644 --- a/examples/ota-requestor-app/ota-requestor-common/ota-requestor-app.matter +++ b/examples/ota-requestor-app/ota-requestor-common/ota-requestor-app.matter @@ -1556,7 +1556,6 @@ endpoint 0 { callback attribute partsList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -1572,7 +1571,6 @@ endpoint 0 { callback attribute accessControlEntriesPerFabric; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; callback attribute clusterRevision; @@ -1605,7 +1603,6 @@ endpoint 0 { callback attribute maxPathsPerInvoke; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 3; @@ -1621,7 +1618,6 @@ endpoint 0 { ram attribute updateStateProgress default = 0; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -1637,7 +1633,6 @@ endpoint 0 { callback attribute supportsConcurrentConnection; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -1661,7 +1656,6 @@ endpoint 0 { ram attribute lastConnectErrorValue; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 2; ram attribute clusterRevision default = 1; @@ -1690,7 +1684,6 @@ endpoint 0 { callback attribute testEventTriggersEnabled default = false; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -1706,7 +1699,6 @@ endpoint 0 { callback attribute adminVendorId; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -1725,7 +1717,6 @@ endpoint 0 { callback attribute currentFabricIndex; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -1751,7 +1742,6 @@ endpoint 0 { callback attribute maxGroupKeysPerFabric; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -1847,7 +1837,6 @@ endpoint 65534 { callback attribute partsList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -1864,7 +1853,6 @@ endpoint 65534 { callback attribute lastConnectErrorValue; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap default = 0; callback attribute clusterRevision default = 1; diff --git a/examples/placeholder/linux/apps/app1/config.matter b/examples/placeholder/linux/apps/app1/config.matter index 30f9ca883b0a9a..a6a1aa5c7f5a64 100644 --- a/examples/placeholder/linux/apps/app1/config.matter +++ b/examples/placeholder/linux/apps/app1/config.matter @@ -8603,7 +8603,6 @@ endpoint 0 { callback attribute partsList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -8618,7 +8617,6 @@ endpoint 0 { callback attribute accessControlEntriesPerFabric; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; callback attribute clusterRevision; @@ -8657,7 +8655,6 @@ endpoint 0 { callback attribute capabilityMinima; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 2; @@ -8668,7 +8665,6 @@ endpoint 0 { callback attribute supportedLocales; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -8680,7 +8676,6 @@ endpoint 0 { callback attribute supportedCalendarTypes; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -8689,7 +8684,6 @@ endpoint 0 { server cluster UnitLocalization { callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -8730,7 +8724,6 @@ endpoint 0 { callback attribute endpointList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 2; @@ -8744,7 +8737,6 @@ endpoint 0 { callback attribute supportsConcurrentConnection; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -8768,7 +8760,6 @@ endpoint 0 { ram attribute lastConnectErrorValue; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 2; ram attribute clusterRevision default = 1; @@ -8797,7 +8788,6 @@ endpoint 0 { callback attribute testEventTriggersEnabled default = false; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -8967,7 +8957,6 @@ endpoint 0 { callback attribute adminVendorId; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -8986,7 +8975,6 @@ endpoint 0 { callback attribute currentFabricIndex; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -9012,7 +9000,6 @@ endpoint 0 { callback attribute maxGroupKeysPerFabric; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -9680,7 +9667,6 @@ endpoint 1 { callback attribute pendingDatasetTimestamp; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 1; diff --git a/examples/placeholder/linux/apps/app2/config.matter b/examples/placeholder/linux/apps/app2/config.matter index d8ced986c7b0ce..0373748d9de69e 100644 --- a/examples/placeholder/linux/apps/app2/config.matter +++ b/examples/placeholder/linux/apps/app2/config.matter @@ -8516,7 +8516,6 @@ endpoint 0 { callback attribute partsList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -8531,7 +8530,6 @@ endpoint 0 { callback attribute accessControlEntriesPerFabric; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; callback attribute clusterRevision; @@ -8570,7 +8568,6 @@ endpoint 0 { callback attribute capabilityMinima; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 2; @@ -8581,7 +8578,6 @@ endpoint 0 { callback attribute supportedLocales; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -8593,7 +8589,6 @@ endpoint 0 { callback attribute supportedCalendarTypes; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -8603,7 +8598,6 @@ endpoint 0 { ram attribute temperatureUnit; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -8644,7 +8638,6 @@ endpoint 0 { callback attribute endpointList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 2; @@ -8658,7 +8651,6 @@ endpoint 0 { callback attribute supportsConcurrentConnection; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -8682,7 +8674,6 @@ endpoint 0 { ram attribute lastConnectErrorValue; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 2; ram attribute clusterRevision default = 1; @@ -8711,7 +8702,6 @@ endpoint 0 { callback attribute testEventTriggersEnabled default = false; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -8881,7 +8871,6 @@ endpoint 0 { callback attribute adminVendorId; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -8900,7 +8889,6 @@ endpoint 0 { callback attribute currentFabricIndex; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -8926,7 +8914,6 @@ endpoint 0 { callback attribute maxGroupKeysPerFabric; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; diff --git a/examples/refrigerator-app/silabs/data_model/refrigerator-thread-app.matter b/examples/refrigerator-app/silabs/data_model/refrigerator-thread-app.matter index 96d392547fafd2..173823b22d6439 100644 --- a/examples/refrigerator-app/silabs/data_model/refrigerator-thread-app.matter +++ b/examples/refrigerator-app/silabs/data_model/refrigerator-thread-app.matter @@ -1704,7 +1704,6 @@ endpoint 0 { server cluster OtaSoftwareUpdateProvider { callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -1723,7 +1722,6 @@ endpoint 0 { ram attribute updateStateProgress; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -1777,7 +1775,6 @@ endpoint 0 { server cluster DiagnosticLogs { callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -1831,7 +1828,6 @@ endpoint 0 { callback attribute activeNetworkFaultsList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 2; @@ -1915,7 +1911,6 @@ endpoint 1 { callback attribute currentMode; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 2; @@ -1930,7 +1925,6 @@ endpoint 1 { ram attribute supported default = 0; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; diff --git a/examples/refrigerator-app/silabs/data_model/refrigerator-wifi-app.matter b/examples/refrigerator-app/silabs/data_model/refrigerator-wifi-app.matter index 346471b31b3019..d3a8603e740154 100644 --- a/examples/refrigerator-app/silabs/data_model/refrigerator-wifi-app.matter +++ b/examples/refrigerator-app/silabs/data_model/refrigerator-wifi-app.matter @@ -1615,7 +1615,6 @@ endpoint 0 { server cluster OtaSoftwareUpdateProvider { callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -1634,7 +1633,6 @@ endpoint 0 { ram attribute updateStateProgress; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -1688,7 +1686,6 @@ endpoint 0 { server cluster DiagnosticLogs { callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -1823,7 +1820,6 @@ endpoint 1 { callback attribute currentMode; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 2; @@ -1838,7 +1834,6 @@ endpoint 1 { ram attribute supported default = 0; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; diff --git a/examples/rvc-app/rvc-common/rvc-app.matter b/examples/rvc-app/rvc-common/rvc-app.matter index 4f981a8f173a82..0db897b3f7bd23 100644 --- a/examples/rvc-app/rvc-common/rvc-app.matter +++ b/examples/rvc-app/rvc-common/rvc-app.matter @@ -1679,7 +1679,6 @@ endpoint 0 { callback attribute adminVendorId; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 0x0001; @@ -1737,7 +1736,6 @@ endpoint 1 { ram attribute identifyType default = 0x0; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 4; @@ -1753,7 +1751,6 @@ endpoint 1 { callback attribute partsList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -1764,7 +1761,6 @@ endpoint 1 { callback attribute currentMode; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 3; @@ -1778,7 +1774,6 @@ endpoint 1 { callback attribute currentMode; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 3; @@ -1797,7 +1792,6 @@ endpoint 1 { callback attribute operationalError; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -1817,7 +1811,6 @@ endpoint 1 { callback attribute progress; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 1; diff --git a/examples/smoke-co-alarm-app/smoke-co-alarm-common/smoke-co-alarm-app.matter b/examples/smoke-co-alarm-app/smoke-co-alarm-common/smoke-co-alarm-app.matter index a593b61e3ac6d5..d4d7f8c93ed3c9 100644 --- a/examples/smoke-co-alarm-app/smoke-co-alarm-common/smoke-co-alarm-app.matter +++ b/examples/smoke-co-alarm-app/smoke-co-alarm-common/smoke-co-alarm-app.matter @@ -2490,7 +2490,6 @@ endpoint 1 { ram attribute identifyType default = 0x00; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 4; @@ -2523,7 +2522,6 @@ endpoint 1 { callback attribute partsList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -2540,7 +2538,6 @@ endpoint 1 { callback attribute endpointList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 2; ram attribute clusterRevision default = 2; @@ -2573,7 +2570,6 @@ endpoint 1 { ram attribute expiryDate default = 0; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 3; ram attribute clusterRevision default = 1; diff --git a/examples/temperature-measurement-app/temperature-measurement-common/temperature-measurement.matter b/examples/temperature-measurement-app/temperature-measurement-common/temperature-measurement.matter index 84acb6b3c45376..17ab13992cbdc3 100644 --- a/examples/temperature-measurement-app/temperature-measurement-common/temperature-measurement.matter +++ b/examples/temperature-measurement-app/temperature-measurement-common/temperature-measurement.matter @@ -1707,7 +1707,6 @@ endpoint 0 { server cluster DiagnosticLogs { callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; diff --git a/examples/thermostat/nxp/zap/thermostat_matter_br.matter b/examples/thermostat/nxp/zap/thermostat_matter_br.matter index 72c23a4e22096a..f38e2b130b3a43 100644 --- a/examples/thermostat/nxp/zap/thermostat_matter_br.matter +++ b/examples/thermostat/nxp/zap/thermostat_matter_br.matter @@ -2301,7 +2301,6 @@ endpoint 0 { callback attribute maxPathsPerInvoke; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 3; @@ -2350,7 +2349,6 @@ endpoint 0 { callback attribute supportedWiFiBands; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 1; ram attribute clusterRevision default = 1; @@ -2369,7 +2367,6 @@ endpoint 0 { server cluster DiagnosticLogs { callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -2388,7 +2385,6 @@ endpoint 0 { callback attribute testEventTriggersEnabled default = false; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -2405,7 +2401,6 @@ endpoint 0 { callback attribute currentHeapHighWatermark; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 1; @@ -2427,7 +2422,6 @@ endpoint 0 { callback attribute overrunCount; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -2496,7 +2490,6 @@ endpoint 1 { ram attribute identifyType default = 0x0; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 4; @@ -2533,7 +2526,6 @@ endpoint 1 { server cluster FixedLabel { callback attribute labelList; - callback attribute eventList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; } @@ -2542,7 +2534,6 @@ endpoint 1 { callback attribute labelList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -2583,7 +2574,6 @@ endpoint 2 { callback attribute partsList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -2602,7 +2592,6 @@ endpoint 2 { ram attribute threadVersion; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -2685,7 +2674,6 @@ endpoint 2 { callback attribute activeNetworkFaultsList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 2; @@ -2702,7 +2690,6 @@ endpoint 2 { callback attribute pendingDatasetTimestamp; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 1; diff --git a/examples/thermostat/nxp/zap/thermostat_matter_thread.matter b/examples/thermostat/nxp/zap/thermostat_matter_thread.matter index 49856ff0108749..4c6b26a5789a58 100644 --- a/examples/thermostat/nxp/zap/thermostat_matter_thread.matter +++ b/examples/thermostat/nxp/zap/thermostat_matter_thread.matter @@ -2180,7 +2180,6 @@ endpoint 0 { callback attribute maxPathsPerInvoke; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 3; @@ -2230,7 +2229,6 @@ endpoint 0 { ram attribute threadVersion; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 2; ram attribute clusterRevision default = 1; @@ -2249,7 +2247,6 @@ endpoint 0 { server cluster DiagnosticLogs { callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -2268,7 +2265,6 @@ endpoint 0 { callback attribute testEventTriggersEnabled default = false; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -2285,7 +2281,6 @@ endpoint 0 { callback attribute currentHeapHighWatermark; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 1; @@ -2427,7 +2422,6 @@ endpoint 1 { ram attribute identifyType default = 0x0; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 4; @@ -2464,7 +2458,6 @@ endpoint 1 { server cluster FixedLabel { callback attribute labelList; - callback attribute eventList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; } @@ -2473,7 +2466,6 @@ endpoint 1 { callback attribute labelList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; diff --git a/examples/thermostat/nxp/zap/thermostat_matter_wifi.matter b/examples/thermostat/nxp/zap/thermostat_matter_wifi.matter index 1aad4ca9b0dd8e..9b09b05416f6e2 100644 --- a/examples/thermostat/nxp/zap/thermostat_matter_wifi.matter +++ b/examples/thermostat/nxp/zap/thermostat_matter_wifi.matter @@ -2091,7 +2091,6 @@ endpoint 0 { callback attribute maxPathsPerInvoke; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 3; @@ -2140,7 +2139,6 @@ endpoint 0 { callback attribute supportedWiFiBands; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 1; ram attribute clusterRevision default = 1; @@ -2159,7 +2157,6 @@ endpoint 0 { server cluster DiagnosticLogs { callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -2178,7 +2175,6 @@ endpoint 0 { callback attribute testEventTriggersEnabled default = false; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -2195,7 +2191,6 @@ endpoint 0 { callback attribute currentHeapHighWatermark; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 1; @@ -2220,7 +2215,6 @@ endpoint 0 { callback attribute overrunCount; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -2289,7 +2283,6 @@ endpoint 1 { ram attribute identifyType default = 0x0; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 4; @@ -2326,7 +2319,6 @@ endpoint 1 { server cluster FixedLabel { callback attribute labelList; - callback attribute eventList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; } @@ -2335,7 +2327,6 @@ endpoint 1 { callback attribute labelList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; diff --git a/examples/thread-br-app/thread-br-common/thread-br-app.matter b/examples/thread-br-app/thread-br-common/thread-br-app.matter index 63a6a567a3e291..4aa0db4a702334 100644 --- a/examples/thread-br-app/thread-br-common/thread-br-app.matter +++ b/examples/thread-br-app/thread-br-common/thread-br-app.matter @@ -1592,7 +1592,6 @@ endpoint 1 { callback attribute partsList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -1618,7 +1617,6 @@ endpoint 1 { callback attribute activeNetworkFaultsList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 2; @@ -1633,7 +1631,6 @@ endpoint 1 { callback attribute pendingDatasetTimestamp; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; ram attribute clusterRevision default = 1; diff --git a/examples/tv-app/tv-common/tv-app.matter b/examples/tv-app/tv-common/tv-app.matter index b3a06cd2d3533f..3cf472ee1de91c 100644 --- a/examples/tv-app/tv-common/tv-app.matter +++ b/examples/tv-app/tv-common/tv-app.matter @@ -3888,7 +3888,6 @@ endpoint 1 { callback attribute activeMessageIDs; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 3; @@ -4041,7 +4040,6 @@ endpoint 1 { ram attribute blockUnrated; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 28; ram attribute clusterRevision default = 2; @@ -4128,7 +4126,6 @@ endpoint 3 { callback attribute binding; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -4272,7 +4269,6 @@ endpoint 3 { ram attribute blockUnrated; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 28; ram attribute clusterRevision default = 1; diff --git a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/zap-generated/MCAttributeObjects.h b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/zap-generated/MCAttributeObjects.h index d11580a6e82bc3..0633da0cce03c2 100644 --- a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/zap-generated/MCAttributeObjects.h +++ b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/zap-generated/MCAttributeObjects.h @@ -48,9 +48,6 @@ @interface MCOnOffClusterAcceptedCommandListAttribute : MCAttribute @end -@interface MCOnOffClusterEventListAttribute : MCAttribute -@end - @interface MCOnOffClusterAttributeListAttribute : MCAttribute @end @@ -110,9 +107,6 @@ @interface MCLevelControlClusterAcceptedCommandListAttribute : MCAttribute @end -@interface MCLevelControlClusterEventListAttribute : MCAttribute -@end - @interface MCLevelControlClusterAttributeListAttribute : MCAttribute @end @@ -136,9 +130,6 @@ @interface MCWakeOnLanClusterAcceptedCommandListAttribute : MCAttribute @end -@interface MCWakeOnLanClusterEventListAttribute : MCAttribute -@end - @interface MCWakeOnLanClusterAttributeListAttribute : MCAttribute @end @@ -162,9 +153,6 @@ @interface MCTargetNavigatorClusterAcceptedCommandListAttribute : MCAttribute @end -@interface MCTargetNavigatorClusterEventListAttribute : MCAttribute -@end - @interface MCTargetNavigatorClusterAttributeListAttribute : MCAttribute @end @@ -215,9 +203,6 @@ @interface MCMediaPlaybackClusterAcceptedCommandListAttribute : MCAttribute @end -@interface MCMediaPlaybackClusterEventListAttribute : MCAttribute -@end - @interface MCMediaPlaybackClusterAttributeListAttribute : MCAttribute @end @@ -235,9 +220,6 @@ @interface MCKeypadInputClusterAcceptedCommandListAttribute : MCAttribute @end -@interface MCKeypadInputClusterEventListAttribute : MCAttribute -@end - @interface MCKeypadInputClusterAttributeListAttribute : MCAttribute @end @@ -261,9 +243,6 @@ @interface MCContentLauncherClusterAcceptedCommandListAttribute : MCAttribute @end -@interface MCContentLauncherClusterEventListAttribute : MCAttribute -@end - @interface MCContentLauncherClusterAttributeListAttribute : MCAttribute @end @@ -287,9 +266,6 @@ @interface MCApplicationLauncherClusterAcceptedCommandListAttribute : MCAttribute @end -@interface MCApplicationLauncherClusterEventListAttribute : MCAttribute -@end - @interface MCApplicationLauncherClusterAttributeListAttribute : MCAttribute @end @@ -331,9 +307,6 @@ @interface MCApplicationBasicClusterAcceptedCommandListAttribute : MCAttribute @end -@interface MCApplicationBasicClusterEventListAttribute : MCAttribute -@end - @interface MCApplicationBasicClusterAttributeListAttribute : MCAttribute @end diff --git a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/zap-generated/MCAttributeObjects.mm b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/zap-generated/MCAttributeObjects.mm index fc563f52649d95..fa7706e2ecb24e 100644 --- a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/zap-generated/MCAttributeObjects.mm +++ b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/zap-generated/MCAttributeObjects.mm @@ -388,67 +388,6 @@ - (id _Nullable)getObjCTypeFromCpp:(std::any)cppValue errorCode:(CHIP_ERROR *)aE } @end -@implementation MCOnOffClusterEventListAttribute -- (void)read:(void * _Nullable)context - completion:(void (^_Nonnull __strong)(void * _Nullable, id _Nullable __strong before, id _Nullable __strong after, NSError * _Nullable __strong error))completion -{ - MCAttributeTemplate * mcAttribute = new MCAttributeTemplate(self.cppAttribute, - [self](std::any cppValue, CHIP_ERROR * errPtr) { - return [self getObjCTypeFromCpp:cppValue errorCode:errPtr]; - }); - mcAttribute->read(context, [mcAttribute, completion](void * context, id before, id after, NSError * err) { - completion(context, before, after, err); - delete mcAttribute; - }); -} - -- (void)subscribe:(void * _Nullable)context - completion:(void (^_Nonnull __strong)(void * _Nullable, id _Nullable __strong before, id _Nullable __strong after, NSError * _Nullable __strong error))completion - minInterval:(NSNumber * _Nonnull)minInterval - maxInterval:(NSNumber * _Nonnull)maxInterval -{ - MCAttributeTemplate * mcAttribute = new MCAttributeTemplate(self.cppAttribute, - [self](std::any cppValue, CHIP_ERROR * errPtr) { - return [self getObjCTypeFromCpp:cppValue errorCode:errPtr]; - }); - mcAttribute->subscribe( - context, [mcAttribute, completion](void * context, id before, id after, NSError * err) { - completion(context, before, after, err); - delete mcAttribute; - }, minInterval, maxInterval); -} - -- (id _Nullable)getObjCTypeFromCpp:(std::any)cppValue errorCode:(CHIP_ERROR *)aError -{ - NSArray * value = nil; - if (cppValue.type() == typeid(std::shared_ptr)) { - std::shared_ptr sharedPtr = std::any_cast>(cppValue); - chip::app::Clusters::OnOff::Attributes::EventList::TypeInfo::DecodableType _cppValue = *sharedPtr; - *aError = CHIP_NO_ERROR; - NSArray * _Nonnull value; - { // Scope for our temporary variables - auto * array_0 = [NSMutableArray new]; - auto iter_0 = _cppValue.begin(); - while (iter_0.Next()) { - auto & entry_0 = iter_0.GetValue(); - NSNumber * newElement_0; - newElement_0 = [NSNumber numberWithUnsignedInt:entry_0]; - [array_0 addObject:newElement_0]; - } - CHIP_ERROR err = iter_0.GetStatus(); - if (err != CHIP_NO_ERROR) { - *aError = err; - return nil; - } - value = array_0; - } - return value; - } - *aError = CHIP_ERROR_INTERNAL; - return value; -} -@end - @implementation MCOnOffClusterAttributeListAttribute - (void)read:(void * _Nullable)context completion:(void (^_Nonnull __strong)(void * _Nullable, id _Nullable __strong before, id _Nullable __strong after, NSError * _Nullable __strong error))completion @@ -1394,67 +1333,6 @@ - (id _Nullable)getObjCTypeFromCpp:(std::any)cppValue errorCode:(CHIP_ERROR *)aE } @end -@implementation MCLevelControlClusterEventListAttribute -- (void)read:(void * _Nullable)context - completion:(void (^_Nonnull __strong)(void * _Nullable, id _Nullable __strong before, id _Nullable __strong after, NSError * _Nullable __strong error))completion -{ - MCAttributeTemplate * mcAttribute = new MCAttributeTemplate(self.cppAttribute, - [self](std::any cppValue, CHIP_ERROR * errPtr) { - return [self getObjCTypeFromCpp:cppValue errorCode:errPtr]; - }); - mcAttribute->read(context, [mcAttribute, completion](void * context, id before, id after, NSError * err) { - completion(context, before, after, err); - delete mcAttribute; - }); -} - -- (void)subscribe:(void * _Nullable)context - completion:(void (^_Nonnull __strong)(void * _Nullable, id _Nullable __strong before, id _Nullable __strong after, NSError * _Nullable __strong error))completion - minInterval:(NSNumber * _Nonnull)minInterval - maxInterval:(NSNumber * _Nonnull)maxInterval -{ - MCAttributeTemplate * mcAttribute = new MCAttributeTemplate(self.cppAttribute, - [self](std::any cppValue, CHIP_ERROR * errPtr) { - return [self getObjCTypeFromCpp:cppValue errorCode:errPtr]; - }); - mcAttribute->subscribe( - context, [mcAttribute, completion](void * context, id before, id after, NSError * err) { - completion(context, before, after, err); - delete mcAttribute; - }, minInterval, maxInterval); -} - -- (id _Nullable)getObjCTypeFromCpp:(std::any)cppValue errorCode:(CHIP_ERROR *)aError -{ - NSArray * value = nil; - if (cppValue.type() == typeid(std::shared_ptr)) { - std::shared_ptr sharedPtr = std::any_cast>(cppValue); - chip::app::Clusters::LevelControl::Attributes::EventList::TypeInfo::DecodableType _cppValue = *sharedPtr; - *aError = CHIP_NO_ERROR; - NSArray * _Nonnull value; - { // Scope for our temporary variables - auto * array_0 = [NSMutableArray new]; - auto iter_0 = _cppValue.begin(); - while (iter_0.Next()) { - auto & entry_0 = iter_0.GetValue(); - NSNumber * newElement_0; - newElement_0 = [NSNumber numberWithUnsignedInt:entry_0]; - [array_0 addObject:newElement_0]; - } - CHIP_ERROR err = iter_0.GetStatus(); - if (err != CHIP_NO_ERROR) { - *aError = err; - return nil; - } - value = array_0; - } - return value; - } - *aError = CHIP_ERROR_INTERNAL; - return value; -} -@end - @implementation MCLevelControlClusterAttributeListAttribute - (void)read:(void * _Nullable)context completion:(void (^_Nonnull __strong)(void * _Nullable, id _Nullable __strong before, id _Nullable __strong after, NSError * _Nullable __strong error))completion @@ -1829,67 +1707,6 @@ - (id _Nullable)getObjCTypeFromCpp:(std::any)cppValue errorCode:(CHIP_ERROR *)aE } @end -@implementation MCWakeOnLanClusterEventListAttribute -- (void)read:(void * _Nullable)context - completion:(void (^_Nonnull __strong)(void * _Nullable, id _Nullable __strong before, id _Nullable __strong after, NSError * _Nullable __strong error))completion -{ - MCAttributeTemplate * mcAttribute = new MCAttributeTemplate(self.cppAttribute, - [self](std::any cppValue, CHIP_ERROR * errPtr) { - return [self getObjCTypeFromCpp:cppValue errorCode:errPtr]; - }); - mcAttribute->read(context, [mcAttribute, completion](void * context, id before, id after, NSError * err) { - completion(context, before, after, err); - delete mcAttribute; - }); -} - -- (void)subscribe:(void * _Nullable)context - completion:(void (^_Nonnull __strong)(void * _Nullable, id _Nullable __strong before, id _Nullable __strong after, NSError * _Nullable __strong error))completion - minInterval:(NSNumber * _Nonnull)minInterval - maxInterval:(NSNumber * _Nonnull)maxInterval -{ - MCAttributeTemplate * mcAttribute = new MCAttributeTemplate(self.cppAttribute, - [self](std::any cppValue, CHIP_ERROR * errPtr) { - return [self getObjCTypeFromCpp:cppValue errorCode:errPtr]; - }); - mcAttribute->subscribe( - context, [mcAttribute, completion](void * context, id before, id after, NSError * err) { - completion(context, before, after, err); - delete mcAttribute; - }, minInterval, maxInterval); -} - -- (id _Nullable)getObjCTypeFromCpp:(std::any)cppValue errorCode:(CHIP_ERROR *)aError -{ - NSArray * value = nil; - if (cppValue.type() == typeid(std::shared_ptr)) { - std::shared_ptr sharedPtr = std::any_cast>(cppValue); - chip::app::Clusters::WakeOnLan::Attributes::EventList::TypeInfo::DecodableType _cppValue = *sharedPtr; - *aError = CHIP_NO_ERROR; - NSArray * _Nonnull value; - { // Scope for our temporary variables - auto * array_0 = [NSMutableArray new]; - auto iter_0 = _cppValue.begin(); - while (iter_0.Next()) { - auto & entry_0 = iter_0.GetValue(); - NSNumber * newElement_0; - newElement_0 = [NSNumber numberWithUnsignedInt:entry_0]; - [array_0 addObject:newElement_0]; - } - CHIP_ERROR err = iter_0.GetStatus(); - if (err != CHIP_NO_ERROR) { - *aError = err; - return nil; - } - value = array_0; - } - return value; - } - *aError = CHIP_ERROR_INTERNAL; - return value; -} -@end - @implementation MCWakeOnLanClusterAttributeListAttribute - (void)read:(void * _Nullable)context completion:(void (^_Nonnull __strong)(void * _Nullable, id _Nullable __strong before, id _Nullable __strong after, NSError * _Nullable __strong error))completion @@ -2281,67 +2098,6 @@ - (id _Nullable)getObjCTypeFromCpp:(std::any)cppValue errorCode:(CHIP_ERROR *)aE } @end -@implementation MCTargetNavigatorClusterEventListAttribute -- (void)read:(void * _Nullable)context - completion:(void (^_Nonnull __strong)(void * _Nullable, id _Nullable __strong before, id _Nullable __strong after, NSError * _Nullable __strong error))completion -{ - MCAttributeTemplate * mcAttribute = new MCAttributeTemplate(self.cppAttribute, - [self](std::any cppValue, CHIP_ERROR * errPtr) { - return [self getObjCTypeFromCpp:cppValue errorCode:errPtr]; - }); - mcAttribute->read(context, [mcAttribute, completion](void * context, id before, id after, NSError * err) { - completion(context, before, after, err); - delete mcAttribute; - }); -} - -- (void)subscribe:(void * _Nullable)context - completion:(void (^_Nonnull __strong)(void * _Nullable, id _Nullable __strong before, id _Nullable __strong after, NSError * _Nullable __strong error))completion - minInterval:(NSNumber * _Nonnull)minInterval - maxInterval:(NSNumber * _Nonnull)maxInterval -{ - MCAttributeTemplate * mcAttribute = new MCAttributeTemplate(self.cppAttribute, - [self](std::any cppValue, CHIP_ERROR * errPtr) { - return [self getObjCTypeFromCpp:cppValue errorCode:errPtr]; - }); - mcAttribute->subscribe( - context, [mcAttribute, completion](void * context, id before, id after, NSError * err) { - completion(context, before, after, err); - delete mcAttribute; - }, minInterval, maxInterval); -} - -- (id _Nullable)getObjCTypeFromCpp:(std::any)cppValue errorCode:(CHIP_ERROR *)aError -{ - NSArray * value = nil; - if (cppValue.type() == typeid(std::shared_ptr)) { - std::shared_ptr sharedPtr = std::any_cast>(cppValue); - chip::app::Clusters::TargetNavigator::Attributes::EventList::TypeInfo::DecodableType _cppValue = *sharedPtr; - *aError = CHIP_NO_ERROR; - NSArray * _Nonnull value; - { // Scope for our temporary variables - auto * array_0 = [NSMutableArray new]; - auto iter_0 = _cppValue.begin(); - while (iter_0.Next()) { - auto & entry_0 = iter_0.GetValue(); - NSNumber * newElement_0; - newElement_0 = [NSNumber numberWithUnsignedInt:entry_0]; - [array_0 addObject:newElement_0]; - } - CHIP_ERROR err = iter_0.GetStatus(); - if (err != CHIP_NO_ERROR) { - *aError = err; - return nil; - } - value = array_0; - } - return value; - } - *aError = CHIP_ERROR_INTERNAL; - return value; -} -@end - @implementation MCTargetNavigatorClusterAttributeListAttribute - (void)read:(void * _Nullable)context completion:(void (^_Nonnull __strong)(void * _Nullable, id _Nullable __strong before, id _Nullable __strong after, NSError * _Nullable __strong error))completion @@ -3321,67 +3077,6 @@ - (id _Nullable)getObjCTypeFromCpp:(std::any)cppValue errorCode:(CHIP_ERROR *)aE } @end -@implementation MCMediaPlaybackClusterEventListAttribute -- (void)read:(void * _Nullable)context - completion:(void (^_Nonnull __strong)(void * _Nullable, id _Nullable __strong before, id _Nullable __strong after, NSError * _Nullable __strong error))completion -{ - MCAttributeTemplate * mcAttribute = new MCAttributeTemplate(self.cppAttribute, - [self](std::any cppValue, CHIP_ERROR * errPtr) { - return [self getObjCTypeFromCpp:cppValue errorCode:errPtr]; - }); - mcAttribute->read(context, [mcAttribute, completion](void * context, id before, id after, NSError * err) { - completion(context, before, after, err); - delete mcAttribute; - }); -} - -- (void)subscribe:(void * _Nullable)context - completion:(void (^_Nonnull __strong)(void * _Nullable, id _Nullable __strong before, id _Nullable __strong after, NSError * _Nullable __strong error))completion - minInterval:(NSNumber * _Nonnull)minInterval - maxInterval:(NSNumber * _Nonnull)maxInterval -{ - MCAttributeTemplate * mcAttribute = new MCAttributeTemplate(self.cppAttribute, - [self](std::any cppValue, CHIP_ERROR * errPtr) { - return [self getObjCTypeFromCpp:cppValue errorCode:errPtr]; - }); - mcAttribute->subscribe( - context, [mcAttribute, completion](void * context, id before, id after, NSError * err) { - completion(context, before, after, err); - delete mcAttribute; - }, minInterval, maxInterval); -} - -- (id _Nullable)getObjCTypeFromCpp:(std::any)cppValue errorCode:(CHIP_ERROR *)aError -{ - NSArray * value = nil; - if (cppValue.type() == typeid(std::shared_ptr)) { - std::shared_ptr sharedPtr = std::any_cast>(cppValue); - chip::app::Clusters::MediaPlayback::Attributes::EventList::TypeInfo::DecodableType _cppValue = *sharedPtr; - *aError = CHIP_NO_ERROR; - NSArray * _Nonnull value; - { // Scope for our temporary variables - auto * array_0 = [NSMutableArray new]; - auto iter_0 = _cppValue.begin(); - while (iter_0.Next()) { - auto & entry_0 = iter_0.GetValue(); - NSNumber * newElement_0; - newElement_0 = [NSNumber numberWithUnsignedInt:entry_0]; - [array_0 addObject:newElement_0]; - } - CHIP_ERROR err = iter_0.GetStatus(); - if (err != CHIP_NO_ERROR) { - *aError = err; - return nil; - } - value = array_0; - } - return value; - } - *aError = CHIP_ERROR_INTERNAL; - return value; -} -@end - @implementation MCMediaPlaybackClusterAttributeListAttribute - (void)read:(void * _Nullable)context completion:(void (^_Nonnull __strong)(void * _Nullable, id _Nullable __strong before, id _Nullable __strong after, NSError * _Nullable __strong error))completion @@ -3659,67 +3354,6 @@ - (id _Nullable)getObjCTypeFromCpp:(std::any)cppValue errorCode:(CHIP_ERROR *)aE } @end -@implementation MCKeypadInputClusterEventListAttribute -- (void)read:(void * _Nullable)context - completion:(void (^_Nonnull __strong)(void * _Nullable, id _Nullable __strong before, id _Nullable __strong after, NSError * _Nullable __strong error))completion -{ - MCAttributeTemplate * mcAttribute = new MCAttributeTemplate(self.cppAttribute, - [self](std::any cppValue, CHIP_ERROR * errPtr) { - return [self getObjCTypeFromCpp:cppValue errorCode:errPtr]; - }); - mcAttribute->read(context, [mcAttribute, completion](void * context, id before, id after, NSError * err) { - completion(context, before, after, err); - delete mcAttribute; - }); -} - -- (void)subscribe:(void * _Nullable)context - completion:(void (^_Nonnull __strong)(void * _Nullable, id _Nullable __strong before, id _Nullable __strong after, NSError * _Nullable __strong error))completion - minInterval:(NSNumber * _Nonnull)minInterval - maxInterval:(NSNumber * _Nonnull)maxInterval -{ - MCAttributeTemplate * mcAttribute = new MCAttributeTemplate(self.cppAttribute, - [self](std::any cppValue, CHIP_ERROR * errPtr) { - return [self getObjCTypeFromCpp:cppValue errorCode:errPtr]; - }); - mcAttribute->subscribe( - context, [mcAttribute, completion](void * context, id before, id after, NSError * err) { - completion(context, before, after, err); - delete mcAttribute; - }, minInterval, maxInterval); -} - -- (id _Nullable)getObjCTypeFromCpp:(std::any)cppValue errorCode:(CHIP_ERROR *)aError -{ - NSArray * value = nil; - if (cppValue.type() == typeid(std::shared_ptr)) { - std::shared_ptr sharedPtr = std::any_cast>(cppValue); - chip::app::Clusters::KeypadInput::Attributes::EventList::TypeInfo::DecodableType _cppValue = *sharedPtr; - *aError = CHIP_NO_ERROR; - NSArray * _Nonnull value; - { // Scope for our temporary variables - auto * array_0 = [NSMutableArray new]; - auto iter_0 = _cppValue.begin(); - while (iter_0.Next()) { - auto & entry_0 = iter_0.GetValue(); - NSNumber * newElement_0; - newElement_0 = [NSNumber numberWithUnsignedInt:entry_0]; - [array_0 addObject:newElement_0]; - } - CHIP_ERROR err = iter_0.GetStatus(); - if (err != CHIP_NO_ERROR) { - *aError = err; - return nil; - } - value = array_0; - } - return value; - } - *aError = CHIP_ERROR_INTERNAL; - return value; -} -@end - @implementation MCKeypadInputClusterAttributeListAttribute - (void)read:(void * _Nullable)context completion:(void (^_Nonnull __strong)(void * _Nullable, id _Nullable __strong before, id _Nullable __strong after, NSError * _Nullable __strong error))completion @@ -4109,67 +3743,6 @@ - (id _Nullable)getObjCTypeFromCpp:(std::any)cppValue errorCode:(CHIP_ERROR *)aE } @end -@implementation MCContentLauncherClusterEventListAttribute -- (void)read:(void * _Nullable)context - completion:(void (^_Nonnull __strong)(void * _Nullable, id _Nullable __strong before, id _Nullable __strong after, NSError * _Nullable __strong error))completion -{ - MCAttributeTemplate * mcAttribute = new MCAttributeTemplate(self.cppAttribute, - [self](std::any cppValue, CHIP_ERROR * errPtr) { - return [self getObjCTypeFromCpp:cppValue errorCode:errPtr]; - }); - mcAttribute->read(context, [mcAttribute, completion](void * context, id before, id after, NSError * err) { - completion(context, before, after, err); - delete mcAttribute; - }); -} - -- (void)subscribe:(void * _Nullable)context - completion:(void (^_Nonnull __strong)(void * _Nullable, id _Nullable __strong before, id _Nullable __strong after, NSError * _Nullable __strong error))completion - minInterval:(NSNumber * _Nonnull)minInterval - maxInterval:(NSNumber * _Nonnull)maxInterval -{ - MCAttributeTemplate * mcAttribute = new MCAttributeTemplate(self.cppAttribute, - [self](std::any cppValue, CHIP_ERROR * errPtr) { - return [self getObjCTypeFromCpp:cppValue errorCode:errPtr]; - }); - mcAttribute->subscribe( - context, [mcAttribute, completion](void * context, id before, id after, NSError * err) { - completion(context, before, after, err); - delete mcAttribute; - }, minInterval, maxInterval); -} - -- (id _Nullable)getObjCTypeFromCpp:(std::any)cppValue errorCode:(CHIP_ERROR *)aError -{ - NSArray * value = nil; - if (cppValue.type() == typeid(std::shared_ptr)) { - std::shared_ptr sharedPtr = std::any_cast>(cppValue); - chip::app::Clusters::ContentLauncher::Attributes::EventList::TypeInfo::DecodableType _cppValue = *sharedPtr; - *aError = CHIP_NO_ERROR; - NSArray * _Nonnull value; - { // Scope for our temporary variables - auto * array_0 = [NSMutableArray new]; - auto iter_0 = _cppValue.begin(); - while (iter_0.Next()) { - auto & entry_0 = iter_0.GetValue(); - NSNumber * newElement_0; - newElement_0 = [NSNumber numberWithUnsignedInt:entry_0]; - [array_0 addObject:newElement_0]; - } - CHIP_ERROR err = iter_0.GetStatus(); - if (err != CHIP_NO_ERROR) { - *aError = err; - return nil; - } - value = array_0; - } - return value; - } - *aError = CHIP_ERROR_INTERNAL; - return value; -} -@end - @implementation MCContentLauncherClusterAttributeListAttribute - (void)read:(void * _Nullable)context completion:(void (^_Nonnull __strong)(void * _Nullable, id _Nullable __strong before, id _Nullable __strong after, NSError * _Nullable __strong error))completion @@ -4571,67 +4144,6 @@ - (id _Nullable)getObjCTypeFromCpp:(std::any)cppValue errorCode:(CHIP_ERROR *)aE } @end -@implementation MCApplicationLauncherClusterEventListAttribute -- (void)read:(void * _Nullable)context - completion:(void (^_Nonnull __strong)(void * _Nullable, id _Nullable __strong before, id _Nullable __strong after, NSError * _Nullable __strong error))completion -{ - MCAttributeTemplate * mcAttribute = new MCAttributeTemplate(self.cppAttribute, - [self](std::any cppValue, CHIP_ERROR * errPtr) { - return [self getObjCTypeFromCpp:cppValue errorCode:errPtr]; - }); - mcAttribute->read(context, [mcAttribute, completion](void * context, id before, id after, NSError * err) { - completion(context, before, after, err); - delete mcAttribute; - }); -} - -- (void)subscribe:(void * _Nullable)context - completion:(void (^_Nonnull __strong)(void * _Nullable, id _Nullable __strong before, id _Nullable __strong after, NSError * _Nullable __strong error))completion - minInterval:(NSNumber * _Nonnull)minInterval - maxInterval:(NSNumber * _Nonnull)maxInterval -{ - MCAttributeTemplate * mcAttribute = new MCAttributeTemplate(self.cppAttribute, - [self](std::any cppValue, CHIP_ERROR * errPtr) { - return [self getObjCTypeFromCpp:cppValue errorCode:errPtr]; - }); - mcAttribute->subscribe( - context, [mcAttribute, completion](void * context, id before, id after, NSError * err) { - completion(context, before, after, err); - delete mcAttribute; - }, minInterval, maxInterval); -} - -- (id _Nullable)getObjCTypeFromCpp:(std::any)cppValue errorCode:(CHIP_ERROR *)aError -{ - NSArray * value = nil; - if (cppValue.type() == typeid(std::shared_ptr)) { - std::shared_ptr sharedPtr = std::any_cast>(cppValue); - chip::app::Clusters::ApplicationLauncher::Attributes::EventList::TypeInfo::DecodableType _cppValue = *sharedPtr; - *aError = CHIP_NO_ERROR; - NSArray * _Nonnull value; - { // Scope for our temporary variables - auto * array_0 = [NSMutableArray new]; - auto iter_0 = _cppValue.begin(); - while (iter_0.Next()) { - auto & entry_0 = iter_0.GetValue(); - NSNumber * newElement_0; - newElement_0 = [NSNumber numberWithUnsignedInt:entry_0]; - [array_0 addObject:newElement_0]; - } - CHIP_ERROR err = iter_0.GetStatus(); - if (err != CHIP_NO_ERROR) { - *aError = err; - return nil; - } - value = array_0; - } - return value; - } - *aError = CHIP_ERROR_INTERNAL; - return value; -} -@end - @implementation MCApplicationLauncherClusterAttributeListAttribute - (void)read:(void * _Nullable)context completion:(void (^_Nonnull __strong)(void * _Nullable, id _Nullable __strong before, id _Nullable __strong after, NSError * _Nullable __strong error))completion @@ -5314,67 +4826,6 @@ - (id _Nullable)getObjCTypeFromCpp:(std::any)cppValue errorCode:(CHIP_ERROR *)aE } @end -@implementation MCApplicationBasicClusterEventListAttribute -- (void)read:(void * _Nullable)context - completion:(void (^_Nonnull __strong)(void * _Nullable, id _Nullable __strong before, id _Nullable __strong after, NSError * _Nullable __strong error))completion -{ - MCAttributeTemplate * mcAttribute = new MCAttributeTemplate(self.cppAttribute, - [self](std::any cppValue, CHIP_ERROR * errPtr) { - return [self getObjCTypeFromCpp:cppValue errorCode:errPtr]; - }); - mcAttribute->read(context, [mcAttribute, completion](void * context, id before, id after, NSError * err) { - completion(context, before, after, err); - delete mcAttribute; - }); -} - -- (void)subscribe:(void * _Nullable)context - completion:(void (^_Nonnull __strong)(void * _Nullable, id _Nullable __strong before, id _Nullable __strong after, NSError * _Nullable __strong error))completion - minInterval:(NSNumber * _Nonnull)minInterval - maxInterval:(NSNumber * _Nonnull)maxInterval -{ - MCAttributeTemplate * mcAttribute = new MCAttributeTemplate(self.cppAttribute, - [self](std::any cppValue, CHIP_ERROR * errPtr) { - return [self getObjCTypeFromCpp:cppValue errorCode:errPtr]; - }); - mcAttribute->subscribe( - context, [mcAttribute, completion](void * context, id before, id after, NSError * err) { - completion(context, before, after, err); - delete mcAttribute; - }, minInterval, maxInterval); -} - -- (id _Nullable)getObjCTypeFromCpp:(std::any)cppValue errorCode:(CHIP_ERROR *)aError -{ - NSArray * value = nil; - if (cppValue.type() == typeid(std::shared_ptr)) { - std::shared_ptr sharedPtr = std::any_cast>(cppValue); - chip::app::Clusters::ApplicationBasic::Attributes::EventList::TypeInfo::DecodableType _cppValue = *sharedPtr; - *aError = CHIP_NO_ERROR; - NSArray * _Nonnull value; - { // Scope for our temporary variables - auto * array_0 = [NSMutableArray new]; - auto iter_0 = _cppValue.begin(); - while (iter_0.Next()) { - auto & entry_0 = iter_0.GetValue(); - NSNumber * newElement_0; - newElement_0 = [NSNumber numberWithUnsignedInt:entry_0]; - [array_0 addObject:newElement_0]; - } - CHIP_ERROR err = iter_0.GetStatus(); - if (err != CHIP_NO_ERROR) { - *aError = err; - return nil; - } - value = array_0; - } - return value; - } - *aError = CHIP_ERROR_INTERNAL; - return value; -} -@end - @implementation MCApplicationBasicClusterAttributeListAttribute - (void)read:(void * _Nullable)context completion:(void (^_Nonnull __strong)(void * _Nullable, id _Nullable __strong before, id _Nullable __strong after, NSError * _Nullable __strong error))completion diff --git a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/zap-generated/MCClusterObjects.h b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/zap-generated/MCClusterObjects.h index 12a3d8d3bf59af..9534dfa0607aee 100644 --- a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/zap-generated/MCClusterObjects.h +++ b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/zap-generated/MCClusterObjects.h @@ -98,11 +98,6 @@ */ - (MCOnOffClusterAcceptedCommandListAttribute * _Nullable)acceptedCommandListAttribute; -/** - * @brief Returns non-nil pointer to MCOnOffClusterEventListAttribute if supported, nil otherwise. - */ -- (MCOnOffClusterEventListAttribute * _Nullable)eventListAttribute; - /** * @brief Returns non-nil pointer to MCOnOffClusterAttributeListAttribute if supported, nil otherwise. */ @@ -252,11 +247,6 @@ */ - (MCLevelControlClusterAcceptedCommandListAttribute * _Nullable)acceptedCommandListAttribute; -/** - * @brief Returns non-nil pointer to MCLevelControlClusterEventListAttribute if supported, nil otherwise. - */ -- (MCLevelControlClusterEventListAttribute * _Nullable)eventListAttribute; - /** * @brief Returns non-nil pointer to MCLevelControlClusterAttributeListAttribute if supported, nil otherwise. */ @@ -301,11 +291,6 @@ */ - (MCWakeOnLanClusterAcceptedCommandListAttribute * _Nullable)acceptedCommandListAttribute; -/** - * @brief Returns non-nil pointer to MCWakeOnLanClusterEventListAttribute if supported, nil otherwise. - */ -- (MCWakeOnLanClusterEventListAttribute * _Nullable)eventListAttribute; - /** * @brief Returns non-nil pointer to MCWakeOnLanClusterAttributeListAttribute if supported, nil otherwise. */ @@ -355,11 +340,6 @@ */ - (MCTargetNavigatorClusterAcceptedCommandListAttribute * _Nullable)acceptedCommandListAttribute; -/** - * @brief Returns non-nil pointer to MCTargetNavigatorClusterEventListAttribute if supported, nil otherwise. - */ -- (MCTargetNavigatorClusterEventListAttribute * _Nullable)eventListAttribute; - /** * @brief Returns non-nil pointer to MCTargetNavigatorClusterAttributeListAttribute if supported, nil otherwise. */ @@ -519,11 +499,6 @@ */ - (MCMediaPlaybackClusterAcceptedCommandListAttribute * _Nullable)acceptedCommandListAttribute; -/** - * @brief Returns non-nil pointer to MCMediaPlaybackClusterEventListAttribute if supported, nil otherwise. - */ -- (MCMediaPlaybackClusterEventListAttribute * _Nullable)eventListAttribute; - /** * @brief Returns non-nil pointer to MCMediaPlaybackClusterAttributeListAttribute if supported, nil otherwise. */ @@ -563,11 +538,6 @@ */ - (MCKeypadInputClusterAcceptedCommandListAttribute * _Nullable)acceptedCommandListAttribute; -/** - * @brief Returns non-nil pointer to MCKeypadInputClusterEventListAttribute if supported, nil otherwise. - */ -- (MCKeypadInputClusterEventListAttribute * _Nullable)eventListAttribute; - /** * @brief Returns non-nil pointer to MCKeypadInputClusterAttributeListAttribute if supported, nil otherwise. */ @@ -622,11 +592,6 @@ */ - (MCContentLauncherClusterAcceptedCommandListAttribute * _Nullable)acceptedCommandListAttribute; -/** - * @brief Returns non-nil pointer to MCContentLauncherClusterEventListAttribute if supported, nil otherwise. - */ -- (MCContentLauncherClusterEventListAttribute * _Nullable)eventListAttribute; - /** * @brief Returns non-nil pointer to MCContentLauncherClusterAttributeListAttribute if supported, nil otherwise. */ @@ -686,11 +651,6 @@ */ - (MCApplicationLauncherClusterAcceptedCommandListAttribute * _Nullable)acceptedCommandListAttribute; -/** - * @brief Returns non-nil pointer to MCApplicationLauncherClusterEventListAttribute if supported, nil otherwise. - */ -- (MCApplicationLauncherClusterEventListAttribute * _Nullable)eventListAttribute; - /** * @brief Returns non-nil pointer to MCApplicationLauncherClusterAttributeListAttribute if supported, nil otherwise. */ @@ -765,11 +725,6 @@ */ - (MCApplicationBasicClusterAcceptedCommandListAttribute * _Nullable)acceptedCommandListAttribute; -/** - * @brief Returns non-nil pointer to MCApplicationBasicClusterEventListAttribute if supported, nil otherwise. - */ -- (MCApplicationBasicClusterEventListAttribute * _Nullable)eventListAttribute; - /** * @brief Returns non-nil pointer to MCApplicationBasicClusterAttributeListAttribute if supported, nil otherwise. */ diff --git a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/zap-generated/MCClusterObjects.mm b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/zap-generated/MCClusterObjects.mm index 8c51871a2c985b..8d05bd52ed4d1d 100644 --- a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/zap-generated/MCClusterObjects.mm +++ b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge/zap-generated/MCClusterObjects.mm @@ -115,12 +115,6 @@ - (id)acceptedCommandListAttribute return cppAttribute != nil ? [[MCOnOffClusterAcceptedCommandListAttribute alloc] initWithCppAttribute:cppAttribute] : nil; } -- (id)eventListAttribute -{ - void * cppAttribute = self.cppCluster->GetAttribute(chip::app::Clusters::OnOff::Attributes::EventList::Id); - return cppAttribute != nil ? [[MCOnOffClusterEventListAttribute alloc] initWithCppAttribute:cppAttribute] : nil; -} - - (id)attributeListAttribute { void * cppAttribute = self.cppCluster->GetAttribute(chip::app::Clusters::OnOff::Attributes::AttributeList::Id); @@ -298,12 +292,6 @@ - (id)acceptedCommandListAttribute return cppAttribute != nil ? [[MCLevelControlClusterAcceptedCommandListAttribute alloc] initWithCppAttribute:cppAttribute] : nil; } -- (id)eventListAttribute -{ - void * cppAttribute = self.cppCluster->GetAttribute(chip::app::Clusters::LevelControl::Attributes::EventList::Id); - return cppAttribute != nil ? [[MCLevelControlClusterEventListAttribute alloc] initWithCppAttribute:cppAttribute] : nil; -} - - (id)attributeListAttribute { void * cppAttribute = self.cppCluster->GetAttribute(chip::app::Clusters::LevelControl::Attributes::AttributeList::Id); @@ -355,12 +343,6 @@ - (id)acceptedCommandListAttribute return cppAttribute != nil ? [[MCWakeOnLanClusterAcceptedCommandListAttribute alloc] initWithCppAttribute:cppAttribute] : nil; } -- (id)eventListAttribute -{ - void * cppAttribute = self.cppCluster->GetAttribute(chip::app::Clusters::WakeOnLan::Attributes::EventList::Id); - return cppAttribute != nil ? [[MCWakeOnLanClusterEventListAttribute alloc] initWithCppAttribute:cppAttribute] : nil; -} - - (id)attributeListAttribute { void * cppAttribute = self.cppCluster->GetAttribute(chip::app::Clusters::WakeOnLan::Attributes::AttributeList::Id); @@ -418,12 +400,6 @@ - (id)acceptedCommandListAttribute return cppAttribute != nil ? [[MCTargetNavigatorClusterAcceptedCommandListAttribute alloc] initWithCppAttribute:cppAttribute] : nil; } -- (id)eventListAttribute -{ - void * cppAttribute = self.cppCluster->GetAttribute(chip::app::Clusters::TargetNavigator::Attributes::EventList::Id); - return cppAttribute != nil ? [[MCTargetNavigatorClusterEventListAttribute alloc] initWithCppAttribute:cppAttribute] : nil; -} - - (id)attributeListAttribute { void * cppAttribute = self.cppCluster->GetAttribute(chip::app::Clusters::TargetNavigator::Attributes::AttributeList::Id); @@ -613,12 +589,6 @@ - (id)acceptedCommandListAttribute return cppAttribute != nil ? [[MCMediaPlaybackClusterAcceptedCommandListAttribute alloc] initWithCppAttribute:cppAttribute] : nil; } -- (id)eventListAttribute -{ - void * cppAttribute = self.cppCluster->GetAttribute(chip::app::Clusters::MediaPlayback::Attributes::EventList::Id); - return cppAttribute != nil ? [[MCMediaPlaybackClusterEventListAttribute alloc] initWithCppAttribute:cppAttribute] : nil; -} - - (id)attributeListAttribute { void * cppAttribute = self.cppCluster->GetAttribute(chip::app::Clusters::MediaPlayback::Attributes::AttributeList::Id); @@ -664,12 +634,6 @@ - (id)acceptedCommandListAttribute return cppAttribute != nil ? [[MCKeypadInputClusterAcceptedCommandListAttribute alloc] initWithCppAttribute:cppAttribute] : nil; } -- (id)eventListAttribute -{ - void * cppAttribute = self.cppCluster->GetAttribute(chip::app::Clusters::KeypadInput::Attributes::EventList::Id); - return cppAttribute != nil ? [[MCKeypadInputClusterEventListAttribute alloc] initWithCppAttribute:cppAttribute] : nil; -} - - (id)attributeListAttribute { void * cppAttribute = self.cppCluster->GetAttribute(chip::app::Clusters::KeypadInput::Attributes::AttributeList::Id); @@ -733,12 +697,6 @@ - (id)acceptedCommandListAttribute return cppAttribute != nil ? [[MCContentLauncherClusterAcceptedCommandListAttribute alloc] initWithCppAttribute:cppAttribute] : nil; } -- (id)eventListAttribute -{ - void * cppAttribute = self.cppCluster->GetAttribute(chip::app::Clusters::ContentLauncher::Attributes::EventList::Id); - return cppAttribute != nil ? [[MCContentLauncherClusterEventListAttribute alloc] initWithCppAttribute:cppAttribute] : nil; -} - - (id)attributeListAttribute { void * cppAttribute = self.cppCluster->GetAttribute(chip::app::Clusters::ContentLauncher::Attributes::AttributeList::Id); @@ -808,12 +766,6 @@ - (id)acceptedCommandListAttribute return cppAttribute != nil ? [[MCApplicationLauncherClusterAcceptedCommandListAttribute alloc] initWithCppAttribute:cppAttribute] : nil; } -- (id)eventListAttribute -{ - void * cppAttribute = self.cppCluster->GetAttribute(chip::app::Clusters::ApplicationLauncher::Attributes::EventList::Id); - return cppAttribute != nil ? [[MCApplicationLauncherClusterEventListAttribute alloc] initWithCppAttribute:cppAttribute] : nil; -} - - (id)attributeListAttribute { void * cppAttribute = self.cppCluster->GetAttribute(chip::app::Clusters::ApplicationLauncher::Attributes::AttributeList::Id); @@ -901,12 +853,6 @@ - (id)acceptedCommandListAttribute return cppAttribute != nil ? [[MCApplicationBasicClusterAcceptedCommandListAttribute alloc] initWithCppAttribute:cppAttribute] : nil; } -- (id)eventListAttribute -{ - void * cppAttribute = self.cppCluster->GetAttribute(chip::app::Clusters::ApplicationBasic::Attributes::EventList::Id); - return cppAttribute != nil ? [[MCApplicationBasicClusterEventListAttribute alloc] initWithCppAttribute:cppAttribute] : nil; -} - - (id)attributeListAttribute { void * cppAttribute = self.cppCluster->GetAttribute(chip::app::Clusters::ApplicationBasic::Attributes::AttributeList::Id); diff --git a/examples/tv-casting-app/tv-casting-common/tv-casting-app.matter b/examples/tv-casting-app/tv-casting-common/tv-casting-app.matter index 3dba518b755b89..b1f1cb4916fed1 100644 --- a/examples/tv-casting-app/tv-casting-common/tv-casting-app.matter +++ b/examples/tv-casting-app/tv-casting-common/tv-casting-app.matter @@ -3237,7 +3237,6 @@ endpoint 1 { server cluster ContentAppObserver { callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; diff --git a/examples/virtual-device-app/virtual-device-common/virtual-device-app.matter b/examples/virtual-device-app/virtual-device-common/virtual-device-app.matter index 22b2c8999a2cdc..b9a3224db7f109 100644 --- a/examples/virtual-device-app/virtual-device-common/virtual-device-app.matter +++ b/examples/virtual-device-app/virtual-device-common/virtual-device-app.matter @@ -3902,7 +3902,6 @@ endpoint 1 { callback attribute endpointList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 2; @@ -3913,7 +3912,6 @@ endpoint 1 { callback attribute fabricSceneInfo; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 1; ram attribute clusterRevision default = 1; @@ -4012,7 +4010,6 @@ endpoint 1 { ram attribute safetyStatus default = 0x0000; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 5; @@ -4040,7 +4037,6 @@ endpoint 1 { ram attribute colorCapabilities default = 0x0000; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 1; ram attribute clusterRevision default = 7; diff --git a/examples/water-leak-detector-app/water-leak-detector-common/water-leak-detector-app.matter b/examples/water-leak-detector-app/water-leak-detector-common/water-leak-detector-app.matter index f2cc365f2b6b0a..5d4d31b28f4e41 100644 --- a/examples/water-leak-detector-app/water-leak-detector-common/water-leak-detector-app.matter +++ b/examples/water-leak-detector-app/water-leak-detector-common/water-leak-detector-app.matter @@ -1738,7 +1738,6 @@ endpoint 0 { callback attribute supportedLocales; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -1873,7 +1872,6 @@ endpoint 1 { ram attribute identifyType default = 0x0; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 2; @@ -1886,7 +1884,6 @@ endpoint 1 { ram attribute nameSupport; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 3; @@ -1910,7 +1907,6 @@ endpoint 1 { callback attribute partsList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -1933,7 +1929,6 @@ endpoint 1 { callback attribute endpointList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -1943,7 +1938,6 @@ endpoint 1 { ram attribute stateValue; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -1952,7 +1946,6 @@ endpoint 1 { server cluster BooleanStateConfiguration { callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; diff --git a/examples/window-app/common/window-app.matter b/examples/window-app/common/window-app.matter index c7eee099b9c950..850b8f047ef83d 100644 --- a/examples/window-app/common/window-app.matter +++ b/examples/window-app/common/window-app.matter @@ -2342,7 +2342,6 @@ endpoint 0 { callback attribute partsList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -2358,7 +2357,6 @@ endpoint 0 { callback attribute accessControlEntriesPerFabric; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; callback attribute clusterRevision; @@ -2391,7 +2389,6 @@ endpoint 0 { callback attribute maxPathsPerInvoke; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 3; @@ -2414,7 +2411,6 @@ endpoint 0 { server cluster UnitLocalization { callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -2433,7 +2429,6 @@ endpoint 0 { callback attribute endpointList; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 2; @@ -2447,7 +2442,6 @@ endpoint 0 { callback attribute supportsConcurrentConnection; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -2471,7 +2465,6 @@ endpoint 0 { ram attribute lastConnectErrorValue; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 2; ram attribute clusterRevision default = 1; @@ -2500,7 +2493,6 @@ endpoint 0 { callback attribute testEventTriggersEnabled default = false; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -2634,7 +2626,6 @@ endpoint 0 { callback attribute adminVendorId; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -2652,7 +2643,6 @@ endpoint 0 { callback attribute currentFabricIndex; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0; ram attribute clusterRevision default = 1; @@ -2678,7 +2668,6 @@ endpoint 0 { callback attribute maxGroupKeysPerFabric; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; callback attribute featureMap; callback attribute clusterRevision; @@ -2709,7 +2698,6 @@ endpoint 0 { callback attribute activeModeThreshold; callback attribute generatedCommandList; callback attribute acceptedCommandList; - callback attribute eventList; callback attribute attributeList; ram attribute featureMap default = 0x0000; ram attribute clusterRevision default = 3; diff --git a/src/app/clusters/concentration-measurement-server/concentration-measurement-cluster-objects.h b/src/app/clusters/concentration-measurement-server/concentration-measurement-cluster-objects.h index d7fd36f4392edd..90dc6315143a64 100644 --- a/src/app/clusters/concentration-measurement-server/concentration-measurement-cluster-objects.h +++ b/src/app/clusters/concentration-measurement-server/concentration-measurement-cluster-objects.h @@ -245,10 +245,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList diff --git a/src/app/clusters/mode-base-server/mode-base-cluster-objects.h b/src/app/clusters/mode-base-server/mode-base-cluster-objects.h index 5d450c671408d5..8071cbca942fe4 100644 --- a/src/app/clusters/mode-base-server/mode-base-cluster-objects.h +++ b/src/app/clusters/mode-base-server/mode-base-cluster-objects.h @@ -90,10 +90,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList diff --git a/src/app/clusters/resource-monitoring-server/resource-monitoring-cluster-objects.h b/src/app/clusters/resource-monitoring-server/resource-monitoring-cluster-objects.h index 70e189bc028825..fdf660ef96ddde 100644 --- a/src/app/clusters/resource-monitoring-server/resource-monitoring-cluster-objects.h +++ b/src/app/clusters/resource-monitoring-server/resource-monitoring-cluster-objects.h @@ -229,14 +229,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ }; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; - -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ -}; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo diff --git a/src/app/zap-templates/zcl/data-model/chip/global-attributes.xml b/src/app/zap-templates/zcl/data-model/chip/global-attributes.xml index bad94e46df67bf..c196b39189c98f 100644 --- a/src/app/zap-templates/zcl/data-model/chip/global-attributes.xml +++ b/src/app/zap-templates/zcl/data-model/chip/global-attributes.xml @@ -19,7 +19,6 @@ limitations under the License. ClusterRevision FeatureMap AttributeList - EventList AcceptedCommandList GeneratedCommandList diff --git a/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp b/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp index 972cc32e536787..c49674fbbefe7e 100644 --- a/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp +++ b/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp @@ -123,31 +123,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -281,31 +256,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -510,31 +460,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -918,31 +843,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -1060,31 +960,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -1429,31 +1304,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -1690,31 +1540,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -2360,31 +2185,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -2675,31 +2475,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -3211,31 +2986,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -3353,31 +3103,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -3617,31 +3342,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -3792,31 +3492,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -3991,31 +3666,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -4149,31 +3799,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -4316,31 +3941,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -5046,31 +4646,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -5382,31 +4957,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -5819,31 +5369,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -5961,31 +5486,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -6390,31 +5890,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -6698,31 +6173,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -8368,31 +7818,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -8808,31 +8233,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -9115,31 +8515,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -9641,31 +9016,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -10053,31 +9403,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -10243,31 +9568,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -10447,31 +9747,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -10812,31 +10087,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -11140,31 +10390,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -11330,31 +10555,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -11520,31 +10720,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -11662,31 +10837,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -11804,31 +10954,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -11946,31 +11071,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -12104,31 +11204,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -12462,31 +11537,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -12652,31 +11702,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -13018,31 +12043,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -13333,8 +12333,148 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; + case Attributes::AttributeList::Id: { + using TypeInfo = Attributes::AttributeList::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + chip::JniReferences::GetInstance().CreateArrayList(value); + + auto iter_value_0 = cppValue.begin(); + while (iter_value_0.Next()) + { + auto & entry_0 = iter_value_0.GetValue(); + jobject newElement_0; + std::string newElement_0ClassName = "java/lang/Long"; + std::string newElement_0CtorSignature = "(J)V"; + jlong jninewElement_0 = static_cast(entry_0); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); + chip::JniReferences::GetInstance().AddToList(value, newElement_0); + } + return value; + } + case Attributes::FeatureMap::Id: { + using TypeInfo = Attributes::FeatureMap::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + std::string valueClassName = "java/lang/Long"; + std::string valueCtorSignature = "(J)V"; + jlong jnivalue = static_cast(cppValue); + chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), + jnivalue, value); + return value; + } + case Attributes::ClusterRevision::Id: { + using TypeInfo = Attributes::ClusterRevision::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + std::string valueClassName = "java/lang/Integer"; + std::string valueCtorSignature = "(I)V"; + jint jnivalue = static_cast(cppValue); + chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), jnivalue, + value); + return value; + } + default: + *aError = CHIP_ERROR_IM_MALFORMED_ATTRIBUTE_PATH_IB; + break; + } + break; + } + case app::Clusters::LaundryDryerControls::Id: { + using namespace app::Clusters::LaundryDryerControls; + switch (aPath.mAttributeId) + { + case Attributes::SupportedDrynessLevels::Id: { + using TypeInfo = Attributes::SupportedDrynessLevels::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + chip::JniReferences::GetInstance().CreateArrayList(value); + + auto iter_value_0 = cppValue.begin(); + while (iter_value_0.Next()) + { + auto & entry_0 = iter_value_0.GetValue(); + jobject newElement_0; + std::string newElement_0ClassName = "java/lang/Integer"; + std::string newElement_0CtorSignature = "(I)V"; + jint jninewElement_0 = static_cast(entry_0); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); + chip::JniReferences::GetInstance().AddToList(value, newElement_0); + } + return value; + } + case Attributes::SelectedDrynessLevel::Id: { + using TypeInfo = Attributes::SelectedDrynessLevel::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + if (cppValue.IsNull()) + { + value = nullptr; + } + else + { + std::string valueClassName = "java/lang/Integer"; + std::string valueCtorSignature = "(I)V"; + jint jnivalue = static_cast(cppValue.Value()); + chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), + jnivalue, value); + } + return value; + } + case Attributes::GeneratedCommandList::Id: { + using TypeInfo = Attributes::GeneratedCommandList::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + chip::JniReferences::GetInstance().CreateArrayList(value); + + auto iter_value_0 = cppValue.begin(); + while (iter_value_0.Next()) + { + auto & entry_0 = iter_value_0.GetValue(); + jobject newElement_0; + std::string newElement_0ClassName = "java/lang/Long"; + std::string newElement_0CtorSignature = "(J)V"; + jlong jninewElement_0 = static_cast(entry_0); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); + chip::JniReferences::GetInstance().AddToList(value, newElement_0); + } + return value; + } + case Attributes::AcceptedCommandList::Id: { + using TypeInfo = Attributes::AcceptedCommandList::TypeInfo; TypeInfo::DecodableType cppValue; *aError = app::DataModel::Decode(aReader, cppValue); if (*aError != CHIP_NO_ERROR) @@ -13421,12 +12561,12 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } break; } - case app::Clusters::LaundryDryerControls::Id: { - using namespace app::Clusters::LaundryDryerControls; + case app::Clusters::ModeSelect::Id: { + using namespace app::Clusters::ModeSelect; switch (aPath.mAttributeId) { - case Attributes::SupportedDrynessLevels::Id: { - using TypeInfo = Attributes::SupportedDrynessLevels::TypeInfo; + case Attributes::Description::Id: { + using TypeInfo = Attributes::Description::TypeInfo; TypeInfo::DecodableType cppValue; *aError = app::DataModel::Decode(aReader, cppValue); if (*aError != CHIP_NO_ERROR) @@ -13434,201 +12574,11 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR return nullptr; } jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Integer"; - std::string newElement_0CtorSignature = "(I)V"; - jint jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } + LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(cppValue, value)); return value; } - case Attributes::SelectedDrynessLevel::Id: { - using TypeInfo = Attributes::SelectedDrynessLevel::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - if (cppValue.IsNull()) - { - value = nullptr; - } - else - { - std::string valueClassName = "java/lang/Integer"; - std::string valueCtorSignature = "(I)V"; - jint jnivalue = static_cast(cppValue.Value()); - chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), - jnivalue, value); - } - return value; - } - case Attributes::GeneratedCommandList::Id: { - using TypeInfo = Attributes::GeneratedCommandList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } - case Attributes::AcceptedCommandList::Id: { - using TypeInfo = Attributes::AcceptedCommandList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } - case Attributes::AttributeList::Id: { - using TypeInfo = Attributes::AttributeList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } - case Attributes::FeatureMap::Id: { - using TypeInfo = Attributes::FeatureMap::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - std::string valueClassName = "java/lang/Long"; - std::string valueCtorSignature = "(J)V"; - jlong jnivalue = static_cast(cppValue); - chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), - jnivalue, value); - return value; - } - case Attributes::ClusterRevision::Id: { - using TypeInfo = Attributes::ClusterRevision::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - std::string valueClassName = "java/lang/Integer"; - std::string valueCtorSignature = "(I)V"; - jint jnivalue = static_cast(cppValue); - chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), jnivalue, - value); - return value; - } - default: - *aError = CHIP_ERROR_IM_MALFORMED_ATTRIBUTE_PATH_IB; - break; - } - break; - } - case app::Clusters::ModeSelect::Id: { - using namespace app::Clusters::ModeSelect; - switch (aPath.mAttributeId) - { - case Attributes::Description::Id: { - using TypeInfo = Attributes::Description::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - LogErrorOnFailure(chip::JniReferences::GetInstance().CharToStringUTF(cppValue, value)); - return value; - } - case Attributes::StandardNamespace::Id: { - using TypeInfo = Attributes::StandardNamespace::TypeInfo; + case Attributes::StandardNamespace::Id: { + using TypeInfo = Attributes::StandardNamespace::TypeInfo; TypeInfo::DecodableType cppValue; *aError = app::DataModel::Decode(aReader, cppValue); if (*aError != CHIP_NO_ERROR) @@ -13864,31 +12814,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -14181,31 +13106,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -14510,31 +13410,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -14737,31 +13612,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -15006,31 +13856,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -15276,31 +14101,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -15519,31 +14319,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -15709,31 +14484,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -16026,31 +14776,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -16184,31 +14909,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -16534,31 +15234,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -16740,31 +15415,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -17011,31 +15661,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -17306,31 +15931,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -17670,31 +16270,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -18035,31 +16610,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -18307,31 +16857,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -18592,31 +17117,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -18879,278 +17379,228 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } - case Attributes::AttributeList::Id: { - using TypeInfo = Attributes::AttributeList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } - case Attributes::FeatureMap::Id: { - using TypeInfo = Attributes::FeatureMap::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - std::string valueClassName = "java/lang/Long"; - std::string valueCtorSignature = "(J)V"; - jlong jnivalue = static_cast(cppValue); - chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), - jnivalue, value); - return value; - } - case Attributes::ClusterRevision::Id: { - using TypeInfo = Attributes::ClusterRevision::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - std::string valueClassName = "java/lang/Integer"; - std::string valueCtorSignature = "(I)V"; - jint jnivalue = static_cast(cppValue); - chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), jnivalue, - value); - return value; - } - default: - *aError = CHIP_ERROR_IM_MALFORMED_ATTRIBUTE_PATH_IB; - break; - } - break; - } - case app::Clusters::BooleanStateConfiguration::Id: { - using namespace app::Clusters::BooleanStateConfiguration; - switch (aPath.mAttributeId) - { - case Attributes::CurrentSensitivityLevel::Id: { - using TypeInfo = Attributes::CurrentSensitivityLevel::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - std::string valueClassName = "java/lang/Integer"; - std::string valueCtorSignature = "(I)V"; - jint jnivalue = static_cast(cppValue); - chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), jnivalue, - value); - return value; - } - case Attributes::SupportedSensitivityLevels::Id: { - using TypeInfo = Attributes::SupportedSensitivityLevels::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - std::string valueClassName = "java/lang/Integer"; - std::string valueCtorSignature = "(I)V"; - jint jnivalue = static_cast(cppValue); - chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), jnivalue, - value); - return value; - } - case Attributes::DefaultSensitivityLevel::Id: { - using TypeInfo = Attributes::DefaultSensitivityLevel::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - std::string valueClassName = "java/lang/Integer"; - std::string valueCtorSignature = "(I)V"; - jint jnivalue = static_cast(cppValue); - chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), jnivalue, - value); - return value; - } - case Attributes::AlarmsActive::Id: { - using TypeInfo = Attributes::AlarmsActive::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - std::string valueClassName = "java/lang/Integer"; - std::string valueCtorSignature = "(I)V"; - jint jnivalue = static_cast(cppValue.Raw()); - chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), jnivalue, - value); - return value; - } - case Attributes::AlarmsSuppressed::Id: { - using TypeInfo = Attributes::AlarmsSuppressed::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - std::string valueClassName = "java/lang/Integer"; - std::string valueCtorSignature = "(I)V"; - jint jnivalue = static_cast(cppValue.Raw()); - chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), jnivalue, - value); - return value; - } - case Attributes::AlarmsEnabled::Id: { - using TypeInfo = Attributes::AlarmsEnabled::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - std::string valueClassName = "java/lang/Integer"; - std::string valueCtorSignature = "(I)V"; - jint jnivalue = static_cast(cppValue.Raw()); - chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), jnivalue, - value); - return value; - } - case Attributes::AlarmsSupported::Id: { - using TypeInfo = Attributes::AlarmsSupported::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - std::string valueClassName = "java/lang/Integer"; - std::string valueCtorSignature = "(I)V"; - jint jnivalue = static_cast(cppValue.Raw()); - chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), jnivalue, - value); - return value; - } - case Attributes::SensorFault::Id: { - using TypeInfo = Attributes::SensorFault::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - std::string valueClassName = "java/lang/Integer"; - std::string valueCtorSignature = "(I)V"; - jint jnivalue = static_cast(cppValue.Raw()); - chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), jnivalue, - value); - return value; - } - case Attributes::GeneratedCommandList::Id: { - using TypeInfo = Attributes::GeneratedCommandList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } - case Attributes::AcceptedCommandList::Id: { - using TypeInfo = Attributes::AcceptedCommandList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; + case Attributes::AttributeList::Id: { + using TypeInfo = Attributes::AttributeList::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + chip::JniReferences::GetInstance().CreateArrayList(value); + + auto iter_value_0 = cppValue.begin(); + while (iter_value_0.Next()) + { + auto & entry_0 = iter_value_0.GetValue(); + jobject newElement_0; + std::string newElement_0ClassName = "java/lang/Long"; + std::string newElement_0CtorSignature = "(J)V"; + jlong jninewElement_0 = static_cast(entry_0); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); + chip::JniReferences::GetInstance().AddToList(value, newElement_0); + } + return value; + } + case Attributes::FeatureMap::Id: { + using TypeInfo = Attributes::FeatureMap::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + std::string valueClassName = "java/lang/Long"; + std::string valueCtorSignature = "(J)V"; + jlong jnivalue = static_cast(cppValue); + chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), + jnivalue, value); + return value; + } + case Attributes::ClusterRevision::Id: { + using TypeInfo = Attributes::ClusterRevision::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + std::string valueClassName = "java/lang/Integer"; + std::string valueCtorSignature = "(I)V"; + jint jnivalue = static_cast(cppValue); + chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), jnivalue, + value); + return value; + } + default: + *aError = CHIP_ERROR_IM_MALFORMED_ATTRIBUTE_PATH_IB; + break; + } + break; + } + case app::Clusters::BooleanStateConfiguration::Id: { + using namespace app::Clusters::BooleanStateConfiguration; + switch (aPath.mAttributeId) + { + case Attributes::CurrentSensitivityLevel::Id: { + using TypeInfo = Attributes::CurrentSensitivityLevel::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + std::string valueClassName = "java/lang/Integer"; + std::string valueCtorSignature = "(I)V"; + jint jnivalue = static_cast(cppValue); + chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), jnivalue, + value); + return value; + } + case Attributes::SupportedSensitivityLevels::Id: { + using TypeInfo = Attributes::SupportedSensitivityLevels::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + std::string valueClassName = "java/lang/Integer"; + std::string valueCtorSignature = "(I)V"; + jint jnivalue = static_cast(cppValue); + chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), jnivalue, + value); + return value; + } + case Attributes::DefaultSensitivityLevel::Id: { + using TypeInfo = Attributes::DefaultSensitivityLevel::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + std::string valueClassName = "java/lang/Integer"; + std::string valueCtorSignature = "(I)V"; + jint jnivalue = static_cast(cppValue); + chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), jnivalue, + value); + return value; + } + case Attributes::AlarmsActive::Id: { + using TypeInfo = Attributes::AlarmsActive::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + std::string valueClassName = "java/lang/Integer"; + std::string valueCtorSignature = "(I)V"; + jint jnivalue = static_cast(cppValue.Raw()); + chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), jnivalue, + value); + return value; + } + case Attributes::AlarmsSuppressed::Id: { + using TypeInfo = Attributes::AlarmsSuppressed::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + std::string valueClassName = "java/lang/Integer"; + std::string valueCtorSignature = "(I)V"; + jint jnivalue = static_cast(cppValue.Raw()); + chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), jnivalue, + value); + return value; + } + case Attributes::AlarmsEnabled::Id: { + using TypeInfo = Attributes::AlarmsEnabled::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + std::string valueClassName = "java/lang/Integer"; + std::string valueCtorSignature = "(I)V"; + jint jnivalue = static_cast(cppValue.Raw()); + chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), jnivalue, + value); + return value; + } + case Attributes::AlarmsSupported::Id: { + using TypeInfo = Attributes::AlarmsSupported::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + std::string valueClassName = "java/lang/Integer"; + std::string valueCtorSignature = "(I)V"; + jint jnivalue = static_cast(cppValue.Raw()); + chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), jnivalue, + value); + return value; + } + case Attributes::SensorFault::Id: { + using TypeInfo = Attributes::SensorFault::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + std::string valueClassName = "java/lang/Integer"; + std::string valueCtorSignature = "(I)V"; + jint jnivalue = static_cast(cppValue.Raw()); + chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), jnivalue, + value); + return value; + } + case Attributes::GeneratedCommandList::Id: { + using TypeInfo = Attributes::GeneratedCommandList::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + chip::JniReferences::GetInstance().CreateArrayList(value); + + auto iter_value_0 = cppValue.begin(); + while (iter_value_0.Next()) + { + auto & entry_0 = iter_value_0.GetValue(); + jobject newElement_0; + std::string newElement_0ClassName = "java/lang/Long"; + std::string newElement_0CtorSignature = "(J)V"; + jlong jninewElement_0 = static_cast(entry_0); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); + chip::JniReferences::GetInstance().AddToList(value, newElement_0); + } + return value; + } + case Attributes::AcceptedCommandList::Id: { + using TypeInfo = Attributes::AcceptedCommandList::TypeInfo; TypeInfo::DecodableType cppValue; *aError = app::DataModel::Decode(aReader, cppValue); if (*aError != CHIP_NO_ERROR) @@ -19523,31 +17973,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -20611,31 +19036,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -21607,31 +20007,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -21845,31 +20220,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -23302,31 +21652,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -23642,31 +21967,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -24528,31 +22828,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -25139,31 +23414,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -25464,31 +23714,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -25656,31 +23881,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -25927,31 +24127,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -26198,31 +24373,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -26471,31 +24621,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -27376,31 +25501,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -27926,31 +26026,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -28526,31 +26601,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -29162,31 +27212,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -30806,31 +28831,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -31154,31 +29154,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -31344,31 +29319,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -32391,31 +30341,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -32784,281 +30709,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } - case Attributes::AttributeList::Id: { - using TypeInfo = Attributes::AttributeList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } - case Attributes::FeatureMap::Id: { - using TypeInfo = Attributes::FeatureMap::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - std::string valueClassName = "java/lang/Long"; - std::string valueCtorSignature = "(J)V"; - jlong jnivalue = static_cast(cppValue); - chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), - jnivalue, value); - return value; - } - case Attributes::ClusterRevision::Id: { - using TypeInfo = Attributes::ClusterRevision::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - std::string valueClassName = "java/lang/Integer"; - std::string valueCtorSignature = "(I)V"; - jint jnivalue = static_cast(cppValue); - chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), jnivalue, - value); - return value; - } - default: - *aError = CHIP_ERROR_IM_MALFORMED_ATTRIBUTE_PATH_IB; - break; - } - break; - } - case app::Clusters::IlluminanceMeasurement::Id: { - using namespace app::Clusters::IlluminanceMeasurement; - switch (aPath.mAttributeId) - { - case Attributes::MeasuredValue::Id: { - using TypeInfo = Attributes::MeasuredValue::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - if (cppValue.IsNull()) - { - value = nullptr; - } - else - { - std::string valueClassName = "java/lang/Integer"; - std::string valueCtorSignature = "(I)V"; - jint jnivalue = static_cast(cppValue.Value()); - chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), - jnivalue, value); - } - return value; - } - case Attributes::MinMeasuredValue::Id: { - using TypeInfo = Attributes::MinMeasuredValue::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - if (cppValue.IsNull()) - { - value = nullptr; - } - else - { - std::string valueClassName = "java/lang/Integer"; - std::string valueCtorSignature = "(I)V"; - jint jnivalue = static_cast(cppValue.Value()); - chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), - jnivalue, value); - } - return value; - } - case Attributes::MaxMeasuredValue::Id: { - using TypeInfo = Attributes::MaxMeasuredValue::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - if (cppValue.IsNull()) - { - value = nullptr; - } - else - { - std::string valueClassName = "java/lang/Integer"; - std::string valueCtorSignature = "(I)V"; - jint jnivalue = static_cast(cppValue.Value()); - chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), - jnivalue, value); - } - return value; - } - case Attributes::Tolerance::Id: { - using TypeInfo = Attributes::Tolerance::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - std::string valueClassName = "java/lang/Integer"; - std::string valueCtorSignature = "(I)V"; - jint jnivalue = static_cast(cppValue); - chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), jnivalue, - value); - return value; - } - case Attributes::LightSensorType::Id: { - using TypeInfo = Attributes::LightSensorType::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - if (cppValue.IsNull()) - { - value = nullptr; - } - else - { - std::string valueClassName = "java/lang/Integer"; - std::string valueCtorSignature = "(I)V"; - jint jnivalue = static_cast(cppValue.Value()); - chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), - jnivalue, value); - } - return value; - } - case Attributes::GeneratedCommandList::Id: { - using TypeInfo = Attributes::GeneratedCommandList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } - case Attributes::AcceptedCommandList::Id: { - using TypeInfo = Attributes::AcceptedCommandList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -33122,8 +30772,8 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } break; } - case app::Clusters::TemperatureMeasurement::Id: { - using namespace app::Clusters::TemperatureMeasurement; + case app::Clusters::IlluminanceMeasurement::Id: { + using namespace app::Clusters::IlluminanceMeasurement; switch (aPath.mAttributeId) { case Attributes::MeasuredValue::Id: { @@ -33211,8 +30861,8 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR value); return value; } - case Attributes::GeneratedCommandList::Id: { - using TypeInfo = Attributes::GeneratedCommandList::TypeInfo; + case Attributes::LightSensorType::Id: { + using TypeInfo = Attributes::LightSensorType::TypeInfo; TypeInfo::DecodableType cppValue; *aError = app::DataModel::Decode(aReader, cppValue); if (*aError != CHIP_NO_ERROR) @@ -33220,24 +30870,22 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR return nullptr; } jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) + if (cppValue.IsNull()) { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); + value = nullptr; + } + else + { + std::string valueClassName = "java/lang/Integer"; + std::string valueCtorSignature = "(I)V"; + jint jnivalue = static_cast(cppValue.Value()); + chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), + jnivalue, value); } return value; } - case Attributes::AcceptedCommandList::Id: { - using TypeInfo = Attributes::AcceptedCommandList::TypeInfo; + case Attributes::GeneratedCommandList::Id: { + using TypeInfo = Attributes::GeneratedCommandList::TypeInfo; TypeInfo::DecodableType cppValue; *aError = app::DataModel::Decode(aReader, cppValue); if (*aError != CHIP_NO_ERROR) @@ -33261,8 +30909,8 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; + case Attributes::AcceptedCommandList::Id: { + using TypeInfo = Attributes::AcceptedCommandList::TypeInfo; TypeInfo::DecodableType cppValue; *aError = app::DataModel::Decode(aReader, cppValue); if (*aError != CHIP_NO_ERROR) @@ -33349,8 +30997,8 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } break; } - case app::Clusters::PressureMeasurement::Id: { - using namespace app::Clusters::PressureMeasurement; + case app::Clusters::TemperatureMeasurement::Id: { + using namespace app::Clusters::TemperatureMeasurement; switch (aPath.mAttributeId) { case Attributes::MeasuredValue::Id: { @@ -33438,107 +31086,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR value); return value; } - case Attributes::ScaledValue::Id: { - using TypeInfo = Attributes::ScaledValue::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - if (cppValue.IsNull()) - { - value = nullptr; - } - else - { - std::string valueClassName = "java/lang/Integer"; - std::string valueCtorSignature = "(I)V"; - jint jnivalue = static_cast(cppValue.Value()); - chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), - jnivalue, value); - } - return value; - } - case Attributes::MinScaledValue::Id: { - using TypeInfo = Attributes::MinScaledValue::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - if (cppValue.IsNull()) - { - value = nullptr; - } - else - { - std::string valueClassName = "java/lang/Integer"; - std::string valueCtorSignature = "(I)V"; - jint jnivalue = static_cast(cppValue.Value()); - chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), - jnivalue, value); - } - return value; - } - case Attributes::MaxScaledValue::Id: { - using TypeInfo = Attributes::MaxScaledValue::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - if (cppValue.IsNull()) - { - value = nullptr; - } - else - { - std::string valueClassName = "java/lang/Integer"; - std::string valueCtorSignature = "(I)V"; - jint jnivalue = static_cast(cppValue.Value()); - chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), - jnivalue, value); - } - return value; - } - case Attributes::ScaledTolerance::Id: { - using TypeInfo = Attributes::ScaledTolerance::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - std::string valueClassName = "java/lang/Integer"; - std::string valueCtorSignature = "(I)V"; - jint jnivalue = static_cast(cppValue); - chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), jnivalue, - value); - return value; - } - case Attributes::Scale::Id: { - using TypeInfo = Attributes::Scale::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - std::string valueClassName = "java/lang/Integer"; - std::string valueCtorSignature = "(I)V"; - jint jnivalue = static_cast(cppValue); - chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), jnivalue, - value); - return value; - } case Attributes::GeneratedCommandList::Id: { using TypeInfo = Attributes::GeneratedCommandList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -33589,31 +31136,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -33677,8 +31199,8 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } break; } - case app::Clusters::FlowMeasurement::Id: { - using namespace app::Clusters::FlowMeasurement; + case app::Clusters::PressureMeasurement::Id: { + using namespace app::Clusters::PressureMeasurement; switch (aPath.mAttributeId) { case Attributes::MeasuredValue::Id: { @@ -33750,8 +31272,93 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::Tolerance::Id: { - using TypeInfo = Attributes::Tolerance::TypeInfo; + case Attributes::Tolerance::Id: { + using TypeInfo = Attributes::Tolerance::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + std::string valueClassName = "java/lang/Integer"; + std::string valueCtorSignature = "(I)V"; + jint jnivalue = static_cast(cppValue); + chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), jnivalue, + value); + return value; + } + case Attributes::ScaledValue::Id: { + using TypeInfo = Attributes::ScaledValue::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + if (cppValue.IsNull()) + { + value = nullptr; + } + else + { + std::string valueClassName = "java/lang/Integer"; + std::string valueCtorSignature = "(I)V"; + jint jnivalue = static_cast(cppValue.Value()); + chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), + jnivalue, value); + } + return value; + } + case Attributes::MinScaledValue::Id: { + using TypeInfo = Attributes::MinScaledValue::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + if (cppValue.IsNull()) + { + value = nullptr; + } + else + { + std::string valueClassName = "java/lang/Integer"; + std::string valueCtorSignature = "(I)V"; + jint jnivalue = static_cast(cppValue.Value()); + chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), + jnivalue, value); + } + return value; + } + case Attributes::MaxScaledValue::Id: { + using TypeInfo = Attributes::MaxScaledValue::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + if (cppValue.IsNull()) + { + value = nullptr; + } + else + { + std::string valueClassName = "java/lang/Integer"; + std::string valueCtorSignature = "(I)V"; + jint jnivalue = static_cast(cppValue.Value()); + chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), + jnivalue, value); + } + return value; + } + case Attributes::ScaledTolerance::Id: { + using TypeInfo = Attributes::ScaledTolerance::TypeInfo; TypeInfo::DecodableType cppValue; *aError = app::DataModel::Decode(aReader, cppValue); if (*aError != CHIP_NO_ERROR) @@ -33766,8 +31373,8 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR value); return value; } - case Attributes::GeneratedCommandList::Id: { - using TypeInfo = Attributes::GeneratedCommandList::TypeInfo; + case Attributes::Scale::Id: { + using TypeInfo = Attributes::Scale::TypeInfo; TypeInfo::DecodableType cppValue; *aError = app::DataModel::Decode(aReader, cppValue); if (*aError != CHIP_NO_ERROR) @@ -33775,24 +31382,15 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR return nullptr; } jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } + std::string valueClassName = "java/lang/Integer"; + std::string valueCtorSignature = "(I)V"; + jint jnivalue = static_cast(cppValue); + chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), jnivalue, + value); return value; } - case Attributes::AcceptedCommandList::Id: { - using TypeInfo = Attributes::AcceptedCommandList::TypeInfo; + case Attributes::GeneratedCommandList::Id: { + using TypeInfo = Attributes::GeneratedCommandList::TypeInfo; TypeInfo::DecodableType cppValue; *aError = app::DataModel::Decode(aReader, cppValue); if (*aError != CHIP_NO_ERROR) @@ -33816,8 +31414,8 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; + case Attributes::AcceptedCommandList::Id: { + using TypeInfo = Attributes::AcceptedCommandList::TypeInfo; TypeInfo::DecodableType cppValue; *aError = app::DataModel::Decode(aReader, cppValue); if (*aError != CHIP_NO_ERROR) @@ -33904,8 +31502,8 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } break; } - case app::Clusters::RelativeHumidityMeasurement::Id: { - using namespace app::Clusters::RelativeHumidityMeasurement; + case app::Clusters::FlowMeasurement::Id: { + using namespace app::Clusters::FlowMeasurement; switch (aPath.mAttributeId) { case Attributes::MeasuredValue::Id: { @@ -34043,8 +31641,185 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; + case Attributes::AttributeList::Id: { + using TypeInfo = Attributes::AttributeList::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + chip::JniReferences::GetInstance().CreateArrayList(value); + + auto iter_value_0 = cppValue.begin(); + while (iter_value_0.Next()) + { + auto & entry_0 = iter_value_0.GetValue(); + jobject newElement_0; + std::string newElement_0ClassName = "java/lang/Long"; + std::string newElement_0CtorSignature = "(J)V"; + jlong jninewElement_0 = static_cast(entry_0); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); + chip::JniReferences::GetInstance().AddToList(value, newElement_0); + } + return value; + } + case Attributes::FeatureMap::Id: { + using TypeInfo = Attributes::FeatureMap::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + std::string valueClassName = "java/lang/Long"; + std::string valueCtorSignature = "(J)V"; + jlong jnivalue = static_cast(cppValue); + chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), + jnivalue, value); + return value; + } + case Attributes::ClusterRevision::Id: { + using TypeInfo = Attributes::ClusterRevision::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + std::string valueClassName = "java/lang/Integer"; + std::string valueCtorSignature = "(I)V"; + jint jnivalue = static_cast(cppValue); + chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), jnivalue, + value); + return value; + } + default: + *aError = CHIP_ERROR_IM_MALFORMED_ATTRIBUTE_PATH_IB; + break; + } + break; + } + case app::Clusters::RelativeHumidityMeasurement::Id: { + using namespace app::Clusters::RelativeHumidityMeasurement; + switch (aPath.mAttributeId) + { + case Attributes::MeasuredValue::Id: { + using TypeInfo = Attributes::MeasuredValue::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + if (cppValue.IsNull()) + { + value = nullptr; + } + else + { + std::string valueClassName = "java/lang/Integer"; + std::string valueCtorSignature = "(I)V"; + jint jnivalue = static_cast(cppValue.Value()); + chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), + jnivalue, value); + } + return value; + } + case Attributes::MinMeasuredValue::Id: { + using TypeInfo = Attributes::MinMeasuredValue::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + if (cppValue.IsNull()) + { + value = nullptr; + } + else + { + std::string valueClassName = "java/lang/Integer"; + std::string valueCtorSignature = "(I)V"; + jint jnivalue = static_cast(cppValue.Value()); + chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), + jnivalue, value); + } + return value; + } + case Attributes::MaxMeasuredValue::Id: { + using TypeInfo = Attributes::MaxMeasuredValue::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + if (cppValue.IsNull()) + { + value = nullptr; + } + else + { + std::string valueClassName = "java/lang/Integer"; + std::string valueCtorSignature = "(I)V"; + jint jnivalue = static_cast(cppValue.Value()); + chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), + jnivalue, value); + } + return value; + } + case Attributes::Tolerance::Id: { + using TypeInfo = Attributes::Tolerance::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + std::string valueClassName = "java/lang/Integer"; + std::string valueCtorSignature = "(I)V"; + jint jnivalue = static_cast(cppValue); + chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), jnivalue, + value); + return value; + } + case Attributes::GeneratedCommandList::Id: { + using TypeInfo = Attributes::GeneratedCommandList::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + chip::JniReferences::GetInstance().CreateArrayList(value); + + auto iter_value_0 = cppValue.begin(); + while (iter_value_0.Next()) + { + auto & entry_0 = iter_value_0.GetValue(); + jobject newElement_0; + std::string newElement_0ClassName = "java/lang/Long"; + std::string newElement_0CtorSignature = "(J)V"; + jlong jninewElement_0 = static_cast(entry_0); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); + chip::JniReferences::GetInstance().AddToList(value, newElement_0); + } + return value; + } + case Attributes::AcceptedCommandList::Id: { + using TypeInfo = Attributes::AcceptedCommandList::TypeInfo; TypeInfo::DecodableType cppValue; *aError = app::DataModel::Decode(aReader, cppValue); if (*aError != CHIP_NO_ERROR) @@ -34450,31 +32225,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -34803,31 +32553,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -35156,31 +32881,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -35509,31 +33209,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -35862,31 +33537,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -36215,31 +33865,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -36568,31 +34193,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -36921,31 +34521,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -37274,31 +34849,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -37627,31 +35177,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -37980,31 +35505,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -38167,31 +35667,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -38414,31 +35889,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -38664,31 +36114,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -38833,31 +36258,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -39304,31 +36704,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -39516,31 +36891,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -40274,31 +37624,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -40496,31 +37821,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -40638,31 +37938,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -40780,31 +38055,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -40959,31 +38209,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -41177,31 +38402,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -41440,31 +38640,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -41736,31 +38911,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -41878,31 +39028,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -42228,31 +39353,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -42370,31 +39470,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -42696,31 +39771,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -44632,31 +41682,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -44886,31 +41911,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -45140,31 +42140,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -45367,31 +42342,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -45811,31 +42761,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -45969,31 +42894,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -48919,31 +45819,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -49077,31 +45952,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; @@ -49235,31 +46085,6 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = app::DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) - { - return nullptr; - } - jobject value; - chip::JniReferences::GetInstance().CreateArrayList(value); - - auto iter_value_0 = cppValue.begin(); - while (iter_value_0.Next()) - { - auto & entry_0 = iter_value_0.GetValue(); - jobject newElement_0; - std::string newElement_0ClassName = "java/lang/Long"; - std::string newElement_0CtorSignature = "(J)V"; - jlong jninewElement_0 = static_cast(entry_0); - chip::JniReferences::GetInstance().CreateBoxedObject( - newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); - chip::JniReferences::GetInstance().AddToList(value, newElement_0); - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; diff --git a/src/controller/python/chip/clusters/CHIPClusters.py b/src/controller/python/chip/clusters/CHIPClusters.py index 7bc1cb66b4a9c4..395506b33bb843 100644 --- a/src/controller/python/chip/clusters/CHIPClusters.py +++ b/src/controller/python/chip/clusters/CHIPClusters.py @@ -76,12 +76,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -169,12 +163,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -287,12 +275,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -507,12 +489,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -551,12 +527,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -625,12 +595,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -676,12 +640,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -771,12 +729,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -934,12 +886,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -1125,12 +1071,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -1199,12 +1139,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -1279,12 +1213,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -1336,12 +1264,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -1400,12 +1322,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -1451,12 +1367,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -1501,12 +1411,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -1737,12 +1641,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -1873,12 +1771,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -2045,12 +1937,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -2098,12 +1984,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -2219,12 +2099,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -2293,12 +2167,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -2721,12 +2589,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -2849,12 +2711,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -2953,12 +2809,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -3112,12 +2962,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -3267,12 +3111,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -3329,12 +3167,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -3415,12 +3247,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -3557,12 +3383,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -3653,12 +3473,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -3703,12 +3517,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -3754,12 +3562,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -3798,12 +3600,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -3842,12 +3638,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -3886,12 +3676,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -3936,12 +3720,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -4066,12 +3844,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -4155,12 +3927,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -4259,12 +4025,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -4336,12 +4096,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -4393,12 +4147,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -4482,12 +4230,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -4559,12 +4301,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -4636,12 +4372,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -4706,12 +4436,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -4769,12 +4493,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -4832,12 +4550,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -4920,12 +4632,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -4982,12 +4688,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -5059,12 +4759,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -5109,12 +4803,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -5238,12 +4926,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -5320,12 +5002,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -5376,12 +5052,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -5492,12 +5162,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -5596,12 +5260,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -5694,12 +5352,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -5825,12 +5477,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -5912,12 +5558,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -5999,12 +5639,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -6106,12 +5740,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -6232,12 +5860,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -6390,12 +6012,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -6470,12 +6086,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -6563,12 +6173,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -6692,12 +6296,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -6768,12 +6366,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -6920,12 +6512,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -7153,12 +6739,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -7229,12 +6809,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -7285,12 +6859,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -7348,12 +6916,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -7411,12 +6973,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -7474,12 +7030,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -7983,12 +7533,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -8206,12 +7750,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -8300,12 +7838,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -8486,12 +8018,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -8974,12 +8500,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -9105,12 +8625,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -9170,12 +8684,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -9744,12 +9252,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -9882,12 +9384,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -9956,12 +9452,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -10024,12 +9514,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -10122,12 +9606,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -10190,12 +9668,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -10258,12 +9730,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -10396,12 +9862,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -10506,12 +9966,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -10616,12 +10070,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -10726,12 +10174,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -10836,12 +10278,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -10946,12 +10382,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -11056,12 +10486,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -11166,12 +10590,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -11276,12 +10694,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -11386,12 +10798,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -11496,12 +10902,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -11558,12 +10958,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -11665,12 +11059,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -11749,12 +11137,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -11805,12 +11187,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -11922,12 +11298,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -11986,12 +11356,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -12188,12 +11552,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -12271,12 +11629,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -12321,12 +11673,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -12372,12 +11718,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -12448,12 +11788,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -12519,12 +11853,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -12597,12 +11925,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -12689,12 +12011,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -12756,12 +12072,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -12915,12 +12225,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -12967,12 +12271,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -13066,12 +12364,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -13531,12 +12823,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -13631,12 +12917,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -13715,12 +12995,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -13785,12 +13059,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -13841,12 +13109,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -13909,12 +13171,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -14778,12 +14034,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -14849,12 +14099,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, @@ -14914,12 +14158,6 @@ class ChipClusters: "type": "int", "reportable": True, }, - 0x0000FFFA: { - "attributeName": "EventList", - "attributeId": 0x0000FFFA, - "type": "int", - "reportable": True, - }, 0x0000FFFB: { "attributeName": "AttributeList", "attributeId": 0x0000FFFB, diff --git a/src/controller/python/chip/clusters/Objects.py b/src/controller/python/chip/clusters/Objects.py index e6e74717dc739a..0cdc2a54549cce 100644 --- a/src/controller/python/chip/clusters/Objects.py +++ b/src/controller/python/chip/clusters/Objects.py @@ -485,7 +485,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="identifyType", Tag=0x00000001, Type=Identify.Enums.IdentifyTypeEnum), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -495,7 +494,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: identifyType: Identify.Enums.IdentifyTypeEnum = 0 generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -635,22 +633,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000003 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -711,7 +693,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="nameSupport", Tag=0x00000000, Type=uint), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -720,7 +701,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: nameSupport: uint = 0 generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -953,22 +933,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000004 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -1033,7 +997,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="startUpOnOff", Tag=0x00004003, Type=typing.Union[None, Nullable, OnOff.Enums.StartUpOnOffEnum]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -1046,7 +1009,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: startUpOnOff: typing.Union[None, Nullable, OnOff.Enums.StartUpOnOffEnum] = None generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -1302,22 +1264,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000006 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -1391,7 +1337,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="startUpCurrentLevel", Tag=0x00004000, Type=typing.Union[None, Nullable, uint]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -1413,7 +1358,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: startUpCurrentLevel: typing.Union[None, Nullable, uint] = None generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -1893,22 +1837,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000008 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -1968,7 +1896,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: Fields=[ ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -1976,7 +1903,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -2014,22 +1940,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x0000001C - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -2094,7 +2004,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="tagList", Tag=0x00000004, Type=typing.Optional[typing.List[Descriptor.Structs.SemanticTagStruct]]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -2107,7 +2016,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: tagList: typing.Optional[typing.List[Descriptor.Structs.SemanticTagStruct]] = None generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -2260,22 +2168,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x0000001D - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -2336,7 +2228,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="binding", Tag=0x00000000, Type=typing.List[Binding.Structs.TargetStruct]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -2345,7 +2236,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: binding: typing.List[Binding.Structs.TargetStruct] = field(default_factory=lambda: []) generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -2419,22 +2309,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x0000001E - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -2501,7 +2375,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="arl", Tag=0x00000006, Type=typing.Optional[typing.List[AccessControl.Structs.AccessRestrictionEntryStruct]]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -2516,7 +2389,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: arl: typing.Optional[typing.List[AccessControl.Structs.AccessRestrictionEntryStruct]] = None generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -2841,22 +2713,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x0000001F - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -2999,7 +2855,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="setupURL", Tag=0x00000002, Type=typing.Optional[str]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -3010,7 +2865,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: setupURL: typing.Optional[str] = None generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -3422,22 +3276,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000025 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -3569,7 +3407,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="maxPathsPerInvoke", Tag=0x00000016, Type=uint), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -3600,7 +3437,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: maxPathsPerInvoke: uint = 0 generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -4089,22 +3925,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000028 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -4238,7 +4058,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: Fields=[ ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -4246,7 +4065,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -4432,22 +4250,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000029 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -4511,7 +4313,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="updateStateProgress", Tag=0x00000003, Type=typing.Union[Nullable, uint]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -4523,7 +4324,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: updateStateProgress: typing.Union[Nullable, uint] = NullValue generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -4705,22 +4505,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x0000002A - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -4854,7 +4638,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="supportedLocales", Tag=0x00000001, Type=typing.List[str]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -4864,7 +4647,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: supportedLocales: typing.List[str] = field(default_factory=lambda: []) generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -4934,22 +4716,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x0000002B - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -5012,7 +4778,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="supportedCalendarTypes", Tag=0x00000002, Type=typing.Optional[typing.List[TimeFormatLocalization.Enums.CalendarTypeEnum]]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -5023,7 +4788,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: supportedCalendarTypes: typing.Optional[typing.List[TimeFormatLocalization.Enums.CalendarTypeEnum]] = None generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -5144,22 +4908,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x0000002C - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -5220,7 +4968,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="temperatureUnit", Tag=0x00000000, Type=typing.Optional[UnitLocalization.Enums.TempUnitEnum]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -5229,7 +4976,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: temperatureUnit: typing.Optional[UnitLocalization.Enums.TempUnitEnum] = None generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -5298,22 +5044,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x0000002D - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -5374,7 +5104,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="sources", Tag=0x00000000, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -5383,7 +5112,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: sources: typing.List[uint] = field(default_factory=lambda: []) generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -5437,22 +5165,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x0000002E - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -5544,7 +5256,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="endpointList", Tag=0x0000001F, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -5584,7 +5295,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: endpointList: typing.List[uint] = field(default_factory=lambda: []) generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -6400,22 +6110,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x0000002F - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -6549,7 +6243,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="TCUpdateDeadline", Tag=0x00000009, Type=typing.Optional[uint]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -6567,7 +6260,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: TCUpdateDeadline: typing.Optional[uint] = None generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -6949,22 +6641,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000030 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -7035,7 +6711,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="threadVersion", Tag=0x0000000A, Type=typing.Optional[uint]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -7054,7 +6729,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: threadVersion: typing.Optional[uint] = None generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -7609,22 +7283,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000031 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -7684,7 +7342,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: Fields=[ ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -7692,7 +7349,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -7805,22 +7461,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000032 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -7889,7 +7529,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="testEventTriggersEnabled", Tag=0x00000008, Type=bool), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -7906,7 +7545,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: testEventTriggersEnabled: bool = False generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -8274,22 +7912,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000033 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -8436,7 +8058,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="currentHeapHighWatermark", Tag=0x00000003, Type=typing.Optional[uint]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -8448,7 +8069,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: currentHeapHighWatermark: typing.Optional[uint] = None generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -8588,22 +8208,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000034 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -8750,7 +8354,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="activeNetworkFaultsList", Tag=0x0000003E, Type=typing.List[ThreadNetworkDiagnostics.Enums.NetworkFaultEnum]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -8821,7 +8424,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: activeNetworkFaultsList: typing.List[ThreadNetworkDiagnostics.Enums.NetworkFaultEnum] = field(default_factory=lambda: []) generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -10036,22 +9638,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000035 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -10165,7 +9751,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="overrunCount", Tag=0x0000000C, Type=typing.Union[None, Nullable, uint]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -10186,7 +9771,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: overrunCount: typing.Union[None, Nullable, uint] = None generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -10499,22 +10083,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000036 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -10643,7 +10211,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="timeSinceReset", Tag=0x00000008, Type=typing.Optional[uint]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -10660,7 +10227,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: timeSinceReset: typing.Optional[uint] = None generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -10879,22 +10445,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000037 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -10967,7 +10517,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="supportsDNSResolve", Tag=0x0000000C, Type=typing.Optional[bool]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -10988,7 +10537,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: supportsDNSResolve: typing.Optional[bool] = None generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -11456,22 +11004,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000038 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -11637,7 +11169,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="productAppearance", Tag=0x00000014, Type=typing.Optional[BridgedDeviceBasicInformation.Structs.ProductAppearanceStruct]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -11662,7 +11193,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: productAppearance: typing.Optional[BridgedDeviceBasicInformation.Structs.ProductAppearanceStruct] = None generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -12051,22 +11581,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000039 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -12219,7 +11733,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="multiPressMax", Tag=0x00000002, Type=typing.Optional[uint]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -12230,7 +11743,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: multiPressMax: typing.Optional[uint] = None generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -12325,22 +11837,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x0000003B - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -12541,7 +12037,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="adminVendorId", Tag=0x00000002, Type=typing.Union[Nullable, uint]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -12552,7 +12047,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: adminVendorId: typing.Union[Nullable, uint] = NullValue generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -12729,22 +12223,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x0000003C - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -12810,7 +12288,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="currentFabricIndex", Tag=0x00000005, Type=uint), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -12824,7 +12301,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: currentFabricIndex: uint = 0 generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -13235,22 +12711,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x0000003E - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -13314,7 +12774,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="maxGroupKeysPerFabric", Tag=0x00000003, Type=uint), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -13326,7 +12785,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: maxGroupKeysPerFabric: uint = 0 generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -13594,22 +13052,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x0000003F - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -13670,7 +13112,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="labelList", Tag=0x00000000, Type=typing.List[FixedLabel.Structs.LabelStruct]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -13679,7 +13120,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: labelList: typing.List[FixedLabel.Structs.LabelStruct] = field(default_factory=lambda: []) generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -13747,22 +13187,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000040 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -13823,7 +13247,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="labelList", Tag=0x00000000, Type=typing.List[UserLabel.Structs.LabelStruct]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -13832,7 +13255,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: labelList: typing.List[UserLabel.Structs.LabelStruct] = field(default_factory=lambda: []) generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -13900,22 +13322,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000041 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -13975,7 +13381,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: Fields=[ ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -13983,7 +13388,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -14021,22 +13425,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000042 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -14096,7 +13484,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: Fields=[ ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -14104,7 +13491,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -14142,22 +13528,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000043 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -14217,7 +13587,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: Fields=[ ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -14225,7 +13594,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -14263,22 +13631,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000044 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -14339,7 +13691,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="stateValue", Tag=0x00000000, Type=bool), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -14348,7 +13699,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: stateValue: bool = False generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -14402,22 +13752,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000045 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -14507,7 +13841,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="maximumCheckInBackOff", Tag=0x00000009, Type=typing.Optional[uint]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -14525,7 +13858,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: maximumCheckInBackOff: typing.Optional[uint] = None generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -14877,22 +14209,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000046 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -14955,7 +14271,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="timerState", Tag=0x00000002, Type=Timer.Enums.TimerStatusEnum), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -14966,7 +14281,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: timerState: Timer.Enums.TimerStatusEnum = 0 generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -15130,22 +14444,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000047 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -15211,7 +14509,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="operationalError", Tag=0x00000005, Type=OvenCavityOperationalState.Structs.ErrorStateStruct), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -15225,7 +14522,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: operationalError: OvenCavityOperationalState.Structs.ErrorStateStruct = field(default_factory=lambda: OvenCavityOperationalState.Structs.ErrorStateStruct()) generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -15480,22 +14776,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000048 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -15602,7 +14882,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="onMode", Tag=0x00000003, Type=typing.Union[None, Nullable, uint]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -15614,7 +14893,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: onMode: typing.Union[None, Nullable, uint] = None generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -15811,22 +15089,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000049 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -15888,7 +15150,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="selectedDrynessLevel", Tag=0x00000001, Type=typing.Union[Nullable, LaundryDryerControls.Enums.DrynessLevelEnum]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -15898,7 +15159,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: selectedDrynessLevel: typing.Union[Nullable, LaundryDryerControls.Enums.DrynessLevelEnum] = NullValue generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -15980,22 +15240,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x0000004A - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -16061,7 +15305,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="onMode", Tag=0x00000005, Type=typing.Union[None, Nullable, uint]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -16075,7 +15318,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: onMode: typing.Union[None, Nullable, uint] = None generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -16259,22 +15501,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000050 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -16338,7 +15564,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="onMode", Tag=0x00000003, Type=typing.Union[None, Nullable, uint]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -16350,7 +15575,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: onMode: typing.Union[None, Nullable, uint] = None generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -16542,22 +15766,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000051 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -16621,7 +15829,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="onMode", Tag=0x00000003, Type=typing.Union[None, Nullable, uint]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -16633,7 +15840,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: onMode: typing.Union[None, Nullable, uint] = None generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -16823,22 +16029,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000052 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -16902,7 +16092,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="supportedRinses", Tag=0x00000003, Type=typing.Optional[typing.List[LaundryWasherControls.Enums.NumberOfRinsesEnum]]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -16914,7 +16103,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: supportedRinses: typing.Optional[typing.List[LaundryWasherControls.Enums.NumberOfRinsesEnum]] = None generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -17033,22 +16221,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000053 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -17110,7 +16282,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="currentMode", Tag=0x00000001, Type=uint), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -17120,7 +16291,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: currentMode: uint = 0 generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -17294,22 +16464,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000054 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -17371,7 +16525,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="currentMode", Tag=0x00000001, Type=uint), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -17381,7 +16534,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: currentMode: uint = 0 generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -17548,22 +16700,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000055 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -17629,7 +16765,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="supportedTemperatureLevels", Tag=0x00000005, Type=typing.Optional[typing.List[str]]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -17643,7 +16778,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: supportedTemperatureLevels: typing.Optional[typing.List[str]] = None generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -17802,22 +16936,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000056 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -17880,7 +16998,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="supported", Tag=0x00000003, Type=uint), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -17891,7 +17008,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: supported: uint = 0 generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -17981,22 +17097,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000057 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -18086,7 +17186,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="onMode", Tag=0x00000003, Type=typing.Union[None, Nullable, uint]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -18098,7 +17197,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: onMode: typing.Union[None, Nullable, uint] = None generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -18289,22 +17387,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000059 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -18365,7 +17447,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="airQuality", Tag=0x00000000, Type=AirQuality.Enums.AirQualityEnum), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -18374,7 +17455,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: airQuality: AirQuality.Enums.AirQualityEnum = 0 generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -18450,22 +17530,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x0000005B - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -18538,7 +17602,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="expiryDate", Tag=0x0000000C, Type=typing.Optional[uint]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -18559,7 +17622,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: expiryDate: typing.Optional[uint] = None generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -18890,22 +17952,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x0000005C - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -19161,7 +18207,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="supported", Tag=0x00000003, Type=uint), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -19173,7 +18218,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: supported: uint = 0 generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -19320,22 +18364,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x0000005D - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -19423,7 +18451,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="currentMode", Tag=0x00000001, Type=uint), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -19433,7 +18460,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: currentMode: uint = 0 generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -19556,22 +18582,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x0000005E - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -19640,7 +18650,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="wattRating", Tag=0x00000008, Type=typing.Optional[uint]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -19657,7 +18666,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: wattRating: typing.Optional[uint] = None generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -19886,22 +18894,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x0000005F - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -19967,7 +18959,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="operationalError", Tag=0x00000005, Type=OperationalState.Structs.ErrorStateStruct), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -19981,7 +18972,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: operationalError: OperationalState.Structs.ErrorStateStruct = field(default_factory=lambda: OperationalState.Structs.ErrorStateStruct()) generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -20236,22 +19226,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000060 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -20360,7 +19334,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="operationalError", Tag=0x00000005, Type=RvcOperationalState.Structs.ErrorStateStruct), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -20374,7 +19347,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: operationalError: RvcOperationalState.Structs.ErrorStateStruct = field(default_factory=lambda: RvcOperationalState.Structs.ErrorStateStruct()) generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -20627,22 +19599,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000061 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -20748,7 +19704,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="fabricSceneInfo", Tag=0x00000002, Type=typing.List[ScenesManagement.Structs.SceneInfoStruct]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -20759,7 +19714,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: fabricSceneInfo: typing.List[ScenesManagement.Structs.SceneInfoStruct] = field(default_factory=lambda: []) generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -21215,22 +20169,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000062 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -21296,7 +20234,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="replacementProductList", Tag=0x00000005, Type=typing.Optional[typing.List[HepaFilterMonitoring.Structs.ReplacementProductStruct]]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -21310,7 +20247,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: replacementProductList: typing.Optional[typing.List[HepaFilterMonitoring.Structs.ReplacementProductStruct]] = None generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -21510,22 +20446,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000071 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -21591,7 +20511,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="replacementProductList", Tag=0x00000005, Type=typing.Optional[typing.List[ActivatedCarbonFilterMonitoring.Structs.ReplacementProductStruct]]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -21605,7 +20524,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: replacementProductList: typing.Optional[typing.List[ActivatedCarbonFilterMonitoring.Structs.ReplacementProductStruct]] = None generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -21805,22 +20723,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000072 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -21888,7 +20790,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="sensorFault", Tag=0x00000007, Type=typing.Optional[uint]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -21904,7 +20805,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: sensorFault: typing.Optional[uint] = None generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -22117,22 +21017,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000080 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -22244,7 +21128,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="levelStep", Tag=0x0000000A, Type=typing.Optional[uint]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -22263,7 +21146,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: levelStep: typing.Optional[uint] = None generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -22541,22 +21423,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000081 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -22676,7 +21542,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="neutralCurrent", Tag=0x00000012, Type=typing.Union[None, Nullable, int]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -22703,7 +21568,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: neutralCurrent: typing.Union[None, Nullable, int] = None generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -23175,22 +22039,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000090 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -23276,7 +22124,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="cumulativeEnergyReset", Tag=0x00000005, Type=typing.Union[None, Nullable, ElectricalEnergyMeasurement.Structs.CumulativeEnergyResetStruct]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -23290,7 +22137,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: cumulativeEnergyReset: typing.Union[None, Nullable, ElectricalEnergyMeasurement.Structs.CumulativeEnergyResetStruct] = None generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -23535,22 +22381,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000091 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -23659,7 +22489,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="boostState", Tag=0x00000005, Type=WaterHeaterManagement.Enums.BoostStateEnum), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -23673,7 +22502,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: boostState: WaterHeaterManagement.Enums.BoostStateEnum = 0 generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -23881,22 +22709,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000094 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -24000,7 +22812,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="defaultRandomDuration", Tag=0x00000007, Type=uint), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -24016,7 +22827,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: defaultRandomDuration: uint = 0 generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -24487,22 +23297,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000096 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -24602,7 +23396,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="activeMessageIDs", Tag=0x00000001, Type=typing.List[bytes]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -24612,7 +23405,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: activeMessageIDs: typing.List[bytes] = field(default_factory=lambda: []) generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -24802,22 +23594,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000097 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -24949,7 +23725,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="optOutState", Tag=0x00000007, Type=typing.Optional[DeviceEnergyManagement.Enums.OptOutStateEnum]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -24965,7 +23740,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: optOutState: typing.Optional[DeviceEnergyManagement.Enums.OptOutStateEnum] = None generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -25527,22 +24301,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000098 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -25700,7 +24458,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="sessionEnergyDischarged", Tag=0x00000043, Type=typing.Union[None, Nullable, int]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -25731,7 +24488,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: sessionEnergyDischarged: typing.Union[None, Nullable, int] = None generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -26396,22 +25152,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000099 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -26619,7 +25359,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="currentLowPowerModeSensitivity", Tag=0x00000004, Type=typing.Optional[uint]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -26632,7 +25371,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: currentLowPowerModeSensitivity: typing.Optional[uint] = None generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -26781,22 +25519,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x0000009B - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -26858,7 +25580,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="activeEndpoints", Tag=0x00000001, Type=typing.Optional[typing.List[uint]]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -26868,7 +25589,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: activeEndpoints: typing.Optional[typing.List[uint]] = None generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -26945,22 +25665,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x0000009C - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -27022,7 +25726,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="currentMode", Tag=0x00000001, Type=uint), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -27032,7 +25735,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: currentMode: uint = 0 generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -27192,22 +25894,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x0000009D - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -27269,7 +25955,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="currentMode", Tag=0x00000001, Type=uint), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -27279,7 +25964,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: currentMode: uint = 0 generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -27438,22 +26122,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x0000009E - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -27515,7 +26183,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="currentMode", Tag=0x00000001, Type=uint), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -27525,7 +26192,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: currentMode: uint = 0 generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -27685,22 +26351,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x0000009F - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -27805,7 +26455,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="numberOfAliroEndpointKeysSupported", Tag=0x00000088, Type=typing.Optional[uint]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -27858,7 +26507,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: numberOfAliroEndpointKeysSupported: typing.Optional[uint] = None generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -29635,22 +28283,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000101 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -29862,7 +28494,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="safetyStatus", Tag=0x0000001A, Type=typing.Optional[uint]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -29892,7 +28523,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: safetyStatus: typing.Optional[uint] = None generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -30479,22 +29109,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000102 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -30560,7 +29174,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="progress", Tag=0x00000005, Type=typing.Optional[typing.List[ServiceArea.Structs.ProgressStruct]]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -30574,7 +29187,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: progress: typing.Optional[typing.List[ServiceArea.Structs.ProgressStruct]] = None generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -30889,22 +29501,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000150 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -30987,7 +29583,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="controlMode", Tag=0x00000021, Type=typing.Optional[PumpConfigurationAndControl.Enums.ControlModeEnum]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -31018,7 +29613,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: controlMode: typing.Optional[PumpConfigurationAndControl.Enums.ControlModeEnum] = None generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -31470,22 +30064,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000200 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -31878,7 +30456,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="setpointHoldExpiryTimestamp", Tag=0x00000052, Type=typing.Union[None, Nullable, uint]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -31946,7 +30523,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: setpointHoldExpiryTimestamp: typing.Union[None, Nullable, uint] = None generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -33441,22 +32017,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000201 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -33528,7 +32088,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="airflowDirection", Tag=0x0000000B, Type=typing.Optional[FanControl.Enums.AirflowDirectionEnum]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -33548,7 +32107,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: airflowDirection: typing.Optional[FanControl.Enums.AirflowDirectionEnum] = None generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -33863,22 +32421,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000202 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -33941,7 +32483,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="scheduleProgrammingVisibility", Tag=0x00000002, Type=typing.Optional[ThermostatUserInterfaceConfiguration.Enums.ScheduleProgrammingVisibilityEnum]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -33952,7 +32493,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: scheduleProgrammingVisibility: typing.Optional[ThermostatUserInterfaceConfiguration.Enums.ScheduleProgrammingVisibilityEnum] = None generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -34070,22 +32610,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000204 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -34197,7 +32721,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="startUpColorTemperatureMireds", Tag=0x00004010, Type=typing.Union[None, Nullable, uint]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -34257,7 +32780,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: startUpColorTemperatureMireds: typing.Union[None, Nullable, uint] = None generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -35683,22 +34205,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000300 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -35772,7 +34278,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="lampBurnHoursTripPoint", Tag=0x00000035, Type=typing.Union[None, Nullable, uint]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -35794,7 +34299,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: lampBurnHoursTripPoint: typing.Union[None, Nullable, uint] = None generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -36064,22 +34568,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000301 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -36144,7 +34632,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="lightSensorType", Tag=0x00000004, Type=typing.Union[None, Nullable, IlluminanceMeasurement.Enums.LightSensorTypeEnum]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -36157,7 +34644,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: lightSensorType: typing.Union[None, Nullable, IlluminanceMeasurement.Enums.LightSensorTypeEnum] = None generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -36285,22 +34771,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000400 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -36364,7 +34834,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="tolerance", Tag=0x00000003, Type=typing.Optional[uint]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -36376,7 +34845,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: tolerance: typing.Optional[uint] = None generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -36478,22 +34946,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000402 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -36562,7 +35014,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="scale", Tag=0x00000014, Type=typing.Optional[int]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -36579,7 +35030,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: scale: typing.Optional[int] = None generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -36765,22 +35215,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000403 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -36844,7 +35278,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="tolerance", Tag=0x00000003, Type=typing.Optional[uint]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -36856,7 +35289,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: tolerance: typing.Optional[uint] = None generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -36958,22 +35390,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000404 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -37037,7 +35453,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="tolerance", Tag=0x00000003, Type=typing.Optional[uint]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -37049,7 +35464,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: tolerance: typing.Optional[uint] = None generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -37151,22 +35565,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000405 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -37240,7 +35638,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="physicalContactUnoccupiedToOccupiedThreshold", Tag=0x00000032, Type=typing.Optional[uint]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -37262,7 +35659,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: physicalContactUnoccupiedToOccupiedThreshold: typing.Optional[uint] = None generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -37571,22 +35967,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000406 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -37677,7 +36057,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="levelValue", Tag=0x0000000A, Type=typing.Optional[CarbonMonoxideConcentrationMeasurement.Enums.LevelValueEnum]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -37696,7 +36075,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: levelValue: typing.Optional[CarbonMonoxideConcentrationMeasurement.Enums.LevelValueEnum] = None generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -37957,22 +36335,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x0000040C - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -38043,7 +36405,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="levelValue", Tag=0x0000000A, Type=typing.Optional[CarbonDioxideConcentrationMeasurement.Enums.LevelValueEnum]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -38062,7 +36423,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: levelValue: typing.Optional[CarbonDioxideConcentrationMeasurement.Enums.LevelValueEnum] = None generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -38323,22 +36683,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x0000040D - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -38409,7 +36753,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="levelValue", Tag=0x0000000A, Type=typing.Optional[NitrogenDioxideConcentrationMeasurement.Enums.LevelValueEnum]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -38428,7 +36771,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: levelValue: typing.Optional[NitrogenDioxideConcentrationMeasurement.Enums.LevelValueEnum] = None generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -38689,22 +37031,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000413 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -38775,7 +37101,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="levelValue", Tag=0x0000000A, Type=typing.Optional[OzoneConcentrationMeasurement.Enums.LevelValueEnum]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -38794,7 +37119,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: levelValue: typing.Optional[OzoneConcentrationMeasurement.Enums.LevelValueEnum] = None generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -39055,22 +37379,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000415 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -39141,7 +37449,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="levelValue", Tag=0x0000000A, Type=typing.Optional[Pm25ConcentrationMeasurement.Enums.LevelValueEnum]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -39160,7 +37467,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: levelValue: typing.Optional[Pm25ConcentrationMeasurement.Enums.LevelValueEnum] = None generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -39421,22 +37727,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x0000042A - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -39507,7 +37797,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="levelValue", Tag=0x0000000A, Type=typing.Optional[FormaldehydeConcentrationMeasurement.Enums.LevelValueEnum]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -39526,7 +37815,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: levelValue: typing.Optional[FormaldehydeConcentrationMeasurement.Enums.LevelValueEnum] = None generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -39787,22 +38075,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x0000042B - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -39873,7 +38145,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="levelValue", Tag=0x0000000A, Type=typing.Optional[Pm1ConcentrationMeasurement.Enums.LevelValueEnum]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -39892,7 +38163,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: levelValue: typing.Optional[Pm1ConcentrationMeasurement.Enums.LevelValueEnum] = None generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -40153,22 +38423,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x0000042C - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -40239,7 +38493,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="levelValue", Tag=0x0000000A, Type=typing.Optional[Pm10ConcentrationMeasurement.Enums.LevelValueEnum]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -40258,7 +38511,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: levelValue: typing.Optional[Pm10ConcentrationMeasurement.Enums.LevelValueEnum] = None generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -40519,22 +38771,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x0000042D - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -40605,7 +38841,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="levelValue", Tag=0x0000000A, Type=typing.Optional[TotalVolatileOrganicCompoundsConcentrationMeasurement.Enums.LevelValueEnum]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -40624,7 +38859,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: levelValue: typing.Optional[TotalVolatileOrganicCompoundsConcentrationMeasurement.Enums.LevelValueEnum] = None generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -40885,22 +39119,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x0000042E - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -40971,7 +39189,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="levelValue", Tag=0x0000000A, Type=typing.Optional[RadonConcentrationMeasurement.Enums.LevelValueEnum]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -40990,7 +39207,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: levelValue: typing.Optional[RadonConcentrationMeasurement.Enums.LevelValueEnum] = None generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -41251,22 +39467,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x0000042F - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -41328,7 +39528,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="passphraseSurrogate", Tag=0x00000001, Type=typing.Union[Nullable, uint]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -41338,7 +39537,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: passphraseSurrogate: typing.Union[Nullable, uint] = NullValue generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -41438,22 +39636,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000451 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -41519,7 +39701,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="pendingDatasetTimestamp", Tag=0x00000005, Type=typing.Union[Nullable, uint]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -41533,7 +39714,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: pendingDatasetTimestamp: typing.Union[Nullable, uint] = NullValue generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -41748,22 +39928,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000452 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -41826,7 +39990,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="threadNetworkTableSize", Tag=0x00000002, Type=uint), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -41837,7 +40000,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: threadNetworkTableSize: uint = 0 generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -42014,22 +40176,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000453 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -42091,7 +40237,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="linkLocalAddress", Tag=0x00000001, Type=typing.Optional[bytes]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -42101,7 +40246,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: linkLocalAddress: typing.Optional[bytes] = None generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -42171,22 +40315,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000503 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -42249,7 +40377,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="currentChannel", Tag=0x00000002, Type=typing.Union[None, Nullable, Channel.Structs.ChannelInfoStruct]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -42260,7 +40387,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: currentChannel: typing.Union[None, Nullable, Channel.Structs.ChannelInfoStruct] = None generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -42715,22 +40841,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000504 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -42792,7 +40902,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="currentTarget", Tag=0x00000001, Type=typing.Optional[uint]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -42802,7 +40911,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: currentTarget: typing.Optional[uint] = None generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -42934,22 +41042,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000505 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -43044,7 +41136,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="availableTextTracks", Tag=0x0000000A, Type=typing.Union[None, Nullable, typing.List[MediaPlayback.Structs.TrackStruct]]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -43063,7 +41154,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: availableTextTracks: typing.Union[None, Nullable, typing.List[MediaPlayback.Structs.TrackStruct]] = None generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -43599,22 +41689,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000506 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -43712,7 +41786,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="currentInput", Tag=0x00000001, Type=uint), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -43722,7 +41795,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: currentInput: uint = 0 generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -43895,22 +41967,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000507 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -43970,7 +42026,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: Fields=[ ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -43978,7 +42033,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -44030,22 +42084,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000508 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -44105,7 +42143,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: Fields=[ ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -44113,7 +42150,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -44294,22 +42330,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000509 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -44371,7 +42391,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="supportedStreamingProtocols", Tag=0x00000001, Type=typing.Optional[uint]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -44381,7 +42400,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: supportedStreamingProtocols: typing.Optional[uint] = None generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -44718,22 +42736,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x0000050A - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -44795,7 +42797,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="currentOutput", Tag=0x00000001, Type=uint), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -44805,7 +42806,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: currentOutput: uint = 0 generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -44944,22 +42944,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x0000050B - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -45021,7 +43005,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="currentApp", Tag=0x00000001, Type=typing.Union[None, Nullable, ApplicationLauncher.Structs.ApplicationEPStruct]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -45031,7 +43014,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: currentApp: typing.Union[None, Nullable, ApplicationLauncher.Structs.ApplicationEPStruct] = None generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -45215,22 +43197,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x0000050C - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -45298,7 +43264,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="allowedVendorList", Tag=0x00000007, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -45314,7 +43279,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: allowedVendorList: typing.List[uint] = field(default_factory=lambda: []) generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -45506,22 +43470,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x0000050D - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -45581,7 +43529,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: Fields=[ ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -45589,7 +43536,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -45708,22 +43654,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x0000050E - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -45811,7 +43741,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="blockUnrated", Tag=0x00000007, Type=bool), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -45827,7 +43756,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: blockUnrated: bool = False generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -46181,22 +44109,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x0000050F - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -46273,7 +44185,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: Fields=[ ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -46281,7 +44192,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -46368,22 +44278,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000510 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -46447,7 +44341,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="sensitivity", Tag=0x00000003, Type=uint), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -46459,7 +44352,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: sensitivity: uint = 0 generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -46781,22 +44673,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000550 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -46946,7 +44822,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="depthSensorStatus", Tag=0x0000002E, Type=typing.Optional[CameraAvStreamManagement.Enums.TriStateAutoEnum]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -47001,7 +44876,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: depthSensorStatus: typing.Optional[CameraAvStreamManagement.Enums.TriStateAutoEnum] = None generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -48374,22 +46248,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000551 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -48552,7 +46410,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="currentSessions", Tag=0x00000000, Type=typing.List[WebRTCTransportProvider.Structs.WebRTCSessionStruct]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -48561,7 +46418,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: currentSessions: typing.List[WebRTCTransportProvider.Structs.WebRTCSessionStruct] = field(default_factory=lambda: []) generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -48844,22 +46700,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000553 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -48920,7 +46760,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="currentSessions", Tag=0x00000000, Type=typing.List[WebRTCTransportRequestor.Structs.WebRTCSessionStruct]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -48929,7 +46768,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: currentSessions: typing.List[WebRTCTransportRequestor.Structs.WebRTCSessionStruct] = field(default_factory=lambda: []) generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -49136,22 +46974,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000554 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -49214,7 +47036,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="enabled", Tag=0x00000002, Type=bool), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -49225,7 +47046,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: enabled: bool = False generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -49339,22 +47159,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000556 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -49416,7 +47220,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="locationDirectory", Tag=0x00000001, Type=typing.List[EcosystemInformation.Structs.EcosystemLocationStruct]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -49426,7 +47229,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: locationDirectory: typing.List[EcosystemInformation.Structs.EcosystemLocationStruct] = field(default_factory=lambda: []) generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -49552,22 +47354,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000750 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -49628,7 +47414,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="supportedDeviceCategories", Tag=0x00000000, Type=uint), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -49637,7 +47422,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: supportedDeviceCategories: uint = 0 generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -49760,22 +47544,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0x00000751 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -49949,7 +47717,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="nullableGlobalStruct", Tag=0x00004034, Type=typing.Union[Nullable, Globals.Structs.TestGlobalStruct]), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -50046,7 +47813,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: nullableGlobalStruct: typing.Union[Nullable, Globals.Structs.TestGlobalStruct] = NullValue generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -52493,22 +50259,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0xFFF1FC05 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -52652,7 +50402,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: Fields=[ ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -52660,7 +50409,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -52756,22 +50504,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0xFFF1FC06 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty @@ -52832,7 +50564,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="flipFlop", Tag=0x00000000, Type=bool), ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), - ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), @@ -52841,7 +50572,6 @@ def descriptor(cls) -> ClusterObjectDescriptor: flipFlop: bool = False generatedCommandList: typing.List[uint] = field(default_factory=lambda: []) acceptedCommandList: typing.List[uint] = field(default_factory=lambda: []) - eventList: typing.List[uint] = field(default_factory=lambda: []) attributeList: typing.List[uint] = field(default_factory=lambda: []) featureMap: uint = 0 clusterRevision: uint = 0 @@ -52943,22 +50673,6 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass - class EventList(ClusterAttributeDescriptor): - @ChipUtility.classproperty - def cluster_id(cls) -> int: - return 0xFFF1FC20 - - @ChipUtility.classproperty - def attribute_id(cls) -> int: - return 0x0000FFFA - - @ChipUtility.classproperty - def attribute_type(cls) -> ClusterObjectFieldDescriptor: - return ClusterObjectFieldDescriptor(Type=typing.List[uint]) - - value: typing.List[uint] = field(default_factory=lambda: []) - @dataclass class AttributeList(ClusterAttributeDescriptor): @ChipUtility.classproperty diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm index 4f75da11d76b1a..5495d6a9d7a0ca 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm @@ -39,9 +39,6 @@ static BOOL AttributeIsSpecifiedInIdentifyCluster(AttributeId aAttributeId) case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -69,9 +66,6 @@ static BOOL AttributeIsSpecifiedInGroupsCluster(AttributeId aAttributeId) case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -111,9 +105,6 @@ static BOOL AttributeIsSpecifiedInOnOffCluster(AttributeId aAttributeId) case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -180,9 +171,6 @@ static BOOL AttributeIsSpecifiedInLevelControlCluster(AttributeId aAttributeId) case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -207,9 +195,6 @@ static BOOL AttributeIsSpecifiedInPulseWidthModulationCluster(AttributeId aAttri case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -249,9 +234,6 @@ static BOOL AttributeIsSpecifiedInDescriptorCluster(AttributeId aAttributeId) case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -279,9 +261,6 @@ static BOOL AttributeIsSpecifiedInBindingCluster(AttributeId aAttributeId) case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -327,9 +306,6 @@ static BOOL AttributeIsSpecifiedInAccessControlCluster(AttributeId aAttributeId) case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -363,9 +339,6 @@ static BOOL AttributeIsSpecifiedInActionsCluster(AttributeId aAttributeId) case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -459,9 +432,6 @@ static BOOL AttributeIsSpecifiedInBasicInformationCluster(AttributeId aAttribute case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -486,9 +456,6 @@ static BOOL AttributeIsSpecifiedInOTASoftwareUpdateProviderCluster(AttributeId a case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -525,9 +492,6 @@ static BOOL AttributeIsSpecifiedInOTASoftwareUpdateRequestorCluster(AttributeId case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -558,9 +522,6 @@ static BOOL AttributeIsSpecifiedInLocalizationConfigurationCluster(AttributeId a case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -594,9 +555,6 @@ static BOOL AttributeIsSpecifiedInTimeFormatLocalizationCluster(AttributeId aAtt case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -624,9 +582,6 @@ static BOOL AttributeIsSpecifiedInUnitLocalizationCluster(AttributeId aAttribute case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -654,9 +609,6 @@ static BOOL AttributeIsSpecifiedInPowerSourceConfigurationCluster(AttributeId aA case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -777,9 +729,6 @@ static BOOL AttributeIsSpecifiedInPowerSourceCluster(AttributeId aAttributeId) case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -834,9 +783,6 @@ static BOOL AttributeIsSpecifiedInGeneralCommissioningCluster(AttributeId aAttri case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -894,9 +840,6 @@ static BOOL AttributeIsSpecifiedInNetworkCommissioningCluster(AttributeId aAttri case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -921,9 +864,6 @@ static BOOL AttributeIsSpecifiedInDiagnosticLogsCluster(AttributeId aAttributeId case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -975,9 +915,6 @@ static BOOL AttributeIsSpecifiedInGeneralDiagnosticsCluster(AttributeId aAttribu case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -1014,9 +951,6 @@ static BOOL AttributeIsSpecifiedInSoftwareDiagnosticsCluster(AttributeId aAttrib case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -1230,9 +1164,6 @@ static BOOL AttributeIsSpecifiedInThreadNetworkDiagnosticsCluster(AttributeId aA case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -1296,9 +1227,6 @@ static BOOL AttributeIsSpecifiedInWiFiNetworkDiagnosticsCluster(AttributeId aAtt case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -1350,9 +1278,6 @@ static BOOL AttributeIsSpecifiedInEthernetNetworkDiagnosticsCluster(AttributeId case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -1416,9 +1341,6 @@ static BOOL AttributeIsSpecifiedInTimeSynchronizationCluster(AttributeId aAttrib case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -1494,9 +1416,6 @@ static BOOL AttributeIsSpecifiedInBridgedDeviceBasicInformationCluster(Attribute case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -1530,9 +1449,6 @@ static BOOL AttributeIsSpecifiedInSwitchCluster(AttributeId aAttributeId) case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -1566,9 +1482,6 @@ static BOOL AttributeIsSpecifiedInAdministratorCommissioningCluster(AttributeId case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -1611,9 +1524,6 @@ static BOOL AttributeIsSpecifiedInOperationalCredentialsCluster(AttributeId aAtt case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -1650,9 +1560,6 @@ static BOOL AttributeIsSpecifiedInGroupKeyManagementCluster(AttributeId aAttribu case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -1680,9 +1587,6 @@ static BOOL AttributeIsSpecifiedInFixedLabelCluster(AttributeId aAttributeId) case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -1710,9 +1614,6 @@ static BOOL AttributeIsSpecifiedInUserLabelCluster(AttributeId aAttributeId) case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -1740,9 +1641,6 @@ static BOOL AttributeIsSpecifiedInBooleanStateCluster(AttributeId aAttributeId) case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -1797,9 +1695,6 @@ static BOOL AttributeIsSpecifiedInICDManagementCluster(AttributeId aAttributeId) case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -1833,9 +1728,6 @@ static BOOL AttributeIsSpecifiedInTimerCluster(AttributeId aAttributeId) case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -1878,9 +1770,6 @@ static BOOL AttributeIsSpecifiedInOvenCavityOperationalStateCluster(AttributeId case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -1917,9 +1806,6 @@ static BOOL AttributeIsSpecifiedInOvenModeCluster(AttributeId aAttributeId) case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -1950,9 +1836,6 @@ static BOOL AttributeIsSpecifiedInLaundryDryerControlsCluster(AttributeId aAttri case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -1995,9 +1878,6 @@ static BOOL AttributeIsSpecifiedInModeSelectCluster(AttributeId aAttributeId) case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -2034,9 +1914,6 @@ static BOOL AttributeIsSpecifiedInLaundryWasherModeCluster(AttributeId aAttribut case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -2073,9 +1950,6 @@ static BOOL AttributeIsSpecifiedInRefrigeratorAndTemperatureControlledCabinetMod case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -2112,9 +1986,6 @@ static BOOL AttributeIsSpecifiedInLaundryWasherControlsCluster(AttributeId aAttr case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -2145,9 +2016,6 @@ static BOOL AttributeIsSpecifiedInRVCRunModeCluster(AttributeId aAttributeId) case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -2178,9 +2046,6 @@ static BOOL AttributeIsSpecifiedInRVCCleanModeCluster(AttributeId aAttributeId) case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -2223,9 +2088,6 @@ static BOOL AttributeIsSpecifiedInTemperatureControlCluster(AttributeId aAttribu case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -2259,9 +2121,6 @@ static BOOL AttributeIsSpecifiedInRefrigeratorAlarmCluster(AttributeId aAttribut case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -2298,9 +2157,6 @@ static BOOL AttributeIsSpecifiedInDishwasherModeCluster(AttributeId aAttributeId case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -2328,9 +2184,6 @@ static BOOL AttributeIsSpecifiedInAirQualityCluster(AttributeId aAttributeId) case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -2394,9 +2247,6 @@ static BOOL AttributeIsSpecifiedInSmokeCOAlarmCluster(AttributeId aAttributeId) case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -2433,9 +2283,6 @@ static BOOL AttributeIsSpecifiedInDishwasherAlarmCluster(AttributeId aAttributeI case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -2466,9 +2313,6 @@ static BOOL AttributeIsSpecifiedInMicrowaveOvenModeCluster(AttributeId aAttribut case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -2520,9 +2364,6 @@ static BOOL AttributeIsSpecifiedInMicrowaveOvenControlCluster(AttributeId aAttri case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -2565,9 +2406,6 @@ static BOOL AttributeIsSpecifiedInOperationalStateCluster(AttributeId aAttribute case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -2610,9 +2448,6 @@ static BOOL AttributeIsSpecifiedInRVCOperationalStateCluster(AttributeId aAttrib case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -2646,9 +2481,6 @@ static BOOL AttributeIsSpecifiedInScenesManagementCluster(AttributeId aAttribute case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -2691,9 +2523,6 @@ static BOOL AttributeIsSpecifiedInHEPAFilterMonitoringCluster(AttributeId aAttri case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -2736,9 +2565,6 @@ static BOOL AttributeIsSpecifiedInActivatedCarbonFilterMonitoringCluster(Attribu case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -2787,9 +2613,6 @@ static BOOL AttributeIsSpecifiedInBooleanStateConfigurationCluster(AttributeId a case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -2847,9 +2670,6 @@ static BOOL AttributeIsSpecifiedInValveConfigurationAndControlCluster(AttributeI case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -2931,9 +2751,6 @@ static BOOL AttributeIsSpecifiedInElectricalPowerMeasurementCluster(AttributeId case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -2976,9 +2793,6 @@ static BOOL AttributeIsSpecifiedInElectricalEnergyMeasurementCluster(AttributeId case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -3021,9 +2835,6 @@ static BOOL AttributeIsSpecifiedInWaterHeaterManagementCluster(AttributeId aAttr case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -3072,9 +2883,6 @@ static BOOL AttributeIsSpecifiedInDemandResponseLoadControlCluster(AttributeId a case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -3105,9 +2913,6 @@ static BOOL AttributeIsSpecifiedInMessagesCluster(AttributeId aAttributeId) case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -3156,9 +2961,6 @@ static BOOL AttributeIsSpecifiedInDeviceEnergyManagementCluster(AttributeId aAtt case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -3252,9 +3054,6 @@ static BOOL AttributeIsSpecifiedInEnergyEVSECluster(AttributeId aAttributeId) case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -3294,9 +3093,6 @@ static BOOL AttributeIsSpecifiedInEnergyPreferenceCluster(AttributeId aAttribute case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -3327,9 +3123,6 @@ static BOOL AttributeIsSpecifiedInPowerTopologyCluster(AttributeId aAttributeId) case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -3360,9 +3153,6 @@ static BOOL AttributeIsSpecifiedInEnergyEVSEModeCluster(AttributeId aAttributeId case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -3393,9 +3183,6 @@ static BOOL AttributeIsSpecifiedInWaterHeaterModeCluster(AttributeId aAttributeI case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -3426,9 +3213,6 @@ static BOOL AttributeIsSpecifiedInDeviceEnergyManagementModeCluster(AttributeId case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -3588,9 +3372,6 @@ static BOOL AttributeIsSpecifiedInDoorLockCluster(AttributeId aAttributeId) case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -3681,9 +3462,6 @@ static BOOL AttributeIsSpecifiedInWindowCoveringCluster(AttributeId aAttributeId case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -3726,9 +3504,6 @@ static BOOL AttributeIsSpecifiedInServiceAreaCluster(AttributeId aAttributeId) case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -3822,9 +3597,6 @@ static BOOL AttributeIsSpecifiedInPumpConfigurationAndControlCluster(AttributeId case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -4029,9 +3801,6 @@ static BOOL AttributeIsSpecifiedInThermostatCluster(AttributeId aAttributeId) case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -4092,9 +3861,6 @@ static BOOL AttributeIsSpecifiedInFanControlCluster(AttributeId aAttributeId) case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -4128,9 +3894,6 @@ static BOOL AttributeIsSpecifiedInThermostatUserInterfaceConfigurationCluster(At case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -4311,9 +4074,6 @@ static BOOL AttributeIsSpecifiedInColorControlCluster(AttributeId aAttributeId) case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -4380,9 +4140,6 @@ static BOOL AttributeIsSpecifiedInBallastConfigurationCluster(AttributeId aAttri case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -4422,9 +4179,6 @@ static BOOL AttributeIsSpecifiedInIlluminanceMeasurementCluster(AttributeId aAtt case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -4461,9 +4215,6 @@ static BOOL AttributeIsSpecifiedInTemperatureMeasurementCluster(AttributeId aAtt case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -4515,9 +4266,6 @@ static BOOL AttributeIsSpecifiedInPressureMeasurementCluster(AttributeId aAttrib case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -4554,9 +4302,6 @@ static BOOL AttributeIsSpecifiedInFlowMeasurementCluster(AttributeId aAttributeI case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -4593,9 +4338,6 @@ static BOOL AttributeIsSpecifiedInRelativeHumidityMeasurementCluster(AttributeId case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -4662,9 +4404,6 @@ static BOOL AttributeIsSpecifiedInOccupancySensingCluster(AttributeId aAttribute case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -4722,9 +4461,6 @@ static BOOL AttributeIsSpecifiedInCarbonMonoxideConcentrationMeasurementCluster( case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -4782,9 +4518,6 @@ static BOOL AttributeIsSpecifiedInCarbonDioxideConcentrationMeasurementCluster(A case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -4842,9 +4575,6 @@ static BOOL AttributeIsSpecifiedInNitrogenDioxideConcentrationMeasurementCluster case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -4902,9 +4632,6 @@ static BOOL AttributeIsSpecifiedInOzoneConcentrationMeasurementCluster(Attribute case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -4962,9 +4689,6 @@ static BOOL AttributeIsSpecifiedInPM25ConcentrationMeasurementCluster(AttributeI case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -5022,9 +4746,6 @@ static BOOL AttributeIsSpecifiedInFormaldehydeConcentrationMeasurementCluster(At case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -5082,9 +4803,6 @@ static BOOL AttributeIsSpecifiedInPM1ConcentrationMeasurementCluster(AttributeId case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -5142,9 +4860,6 @@ static BOOL AttributeIsSpecifiedInPM10ConcentrationMeasurementCluster(AttributeI case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -5202,9 +4917,6 @@ static BOOL AttributeIsSpecifiedInTotalVolatileOrganicCompoundsConcentrationMeas case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -5262,9 +4974,6 @@ static BOOL AttributeIsSpecifiedInRadonConcentrationMeasurementCluster(Attribute case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -5295,9 +5004,6 @@ static BOOL AttributeIsSpecifiedInWiFiNetworkManagementCluster(AttributeId aAttr case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -5340,9 +5046,6 @@ static BOOL AttributeIsSpecifiedInThreadBorderRouterManagementCluster(AttributeI case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -5376,9 +5079,6 @@ static BOOL AttributeIsSpecifiedInThreadNetworkDirectoryCluster(AttributeId aAtt case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -5409,9 +5109,6 @@ static BOOL AttributeIsSpecifiedInWakeOnLANCluster(AttributeId aAttributeId) case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -5445,9 +5142,6 @@ static BOOL AttributeIsSpecifiedInChannelCluster(AttributeId aAttributeId) case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -5478,9 +5172,6 @@ static BOOL AttributeIsSpecifiedInTargetNavigatorCluster(AttributeId aAttributeI case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -5538,9 +5229,6 @@ static BOOL AttributeIsSpecifiedInMediaPlaybackCluster(AttributeId aAttributeId) case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -5571,9 +5259,6 @@ static BOOL AttributeIsSpecifiedInMediaInputCluster(AttributeId aAttributeId) case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -5598,9 +5283,6 @@ static BOOL AttributeIsSpecifiedInLowPowerCluster(AttributeId aAttributeId) case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -5625,9 +5307,6 @@ static BOOL AttributeIsSpecifiedInKeypadInputCluster(AttributeId aAttributeId) case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -5658,9 +5337,6 @@ static BOOL AttributeIsSpecifiedInContentLauncherCluster(AttributeId aAttributeI case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -5691,9 +5367,6 @@ static BOOL AttributeIsSpecifiedInAudioOutputCluster(AttributeId aAttributeId) case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -5724,9 +5397,6 @@ static BOOL AttributeIsSpecifiedInApplicationLauncherCluster(AttributeId aAttrib case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -5775,9 +5445,6 @@ static BOOL AttributeIsSpecifiedInApplicationBasicCluster(AttributeId aAttribute case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -5802,9 +5469,6 @@ static BOOL AttributeIsSpecifiedInAccountLoginCluster(AttributeId aAttributeId) case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -5853,9 +5517,6 @@ static BOOL AttributeIsSpecifiedInContentControlCluster(AttributeId aAttributeId case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -5880,9 +5541,6 @@ static BOOL AttributeIsSpecifiedInContentAppObserverCluster(AttributeId aAttribu case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -5919,9 +5577,6 @@ static BOOL AttributeIsSpecifiedInZoneManagementCluster(AttributeId aAttributeId case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -6087,9 +5742,6 @@ static BOOL AttributeIsSpecifiedInCameraAVStreamManagementCluster(AttributeId aA case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -6117,9 +5769,6 @@ static BOOL AttributeIsSpecifiedInWebRTCTransportProviderCluster(AttributeId aAt case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -6147,9 +5796,6 @@ static BOOL AttributeIsSpecifiedInWebRTCTransportRequestorCluster(AttributeId aA case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -6183,9 +5829,6 @@ static BOOL AttributeIsSpecifiedInChimeCluster(AttributeId aAttributeId) case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -6216,9 +5859,6 @@ static BOOL AttributeIsSpecifiedInEcosystemInformationCluster(AttributeId aAttri case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -6246,9 +5886,6 @@ static BOOL AttributeIsSpecifiedInCommissionerControlCluster(AttributeId aAttrib case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -6537,9 +6174,6 @@ static BOOL AttributeIsSpecifiedInUnitTestingCluster(AttributeId aAttributeId) case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } @@ -6570,9 +6204,6 @@ static BOOL AttributeIsSpecifiedInSampleMEICluster(AttributeId aAttributeId) case Attributes::AcceptedCommandList::Id: { return YES; } - case Attributes::EventList::Id: { - return YES; - } case Attributes::AttributeList::Id: { return YES; } diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm index b735c0f56c1ea1..b894c30f6cfc8e 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm @@ -88,32 +88,6 @@ static id _Nullable DecodeGlobalAttributeValue(AttributeId aAttributeId, TLV::TL } return value; } - case Attributes::EventList::Id: { - using TypeInfo = Attributes::EventList::TypeInfo; - TypeInfo::DecodableType cppValue; - *aError = DataModel::Decode(aReader, cppValue); - if (*aError != CHIP_NO_ERROR) { - return nil; - } - NSArray * _Nonnull value; - { // Scope for our temporary variables - auto * array_0 = [NSMutableArray new]; - auto iter_0 = cppValue.begin(); - while (iter_0.Next()) { - auto & entry_0 = iter_0.GetValue(); - NSNumber * newElement_0; - newElement_0 = [NSNumber numberWithUnsignedInt:entry_0]; - [array_0 addObject:newElement_0]; - } - CHIP_ERROR err = iter_0.GetStatus(); - if (err != CHIP_NO_ERROR) { - *aError = err; - return nil; - } - value = array_0; - } - return value; - } case Attributes::AttributeList::Id: { using TypeInfo = Attributes::AttributeList::TypeInfo; TypeInfo::DecodableType cppValue; diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h index eda0c7b5a06431..d3f7ba442b3c80 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h @@ -69,12 +69,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -175,12 +169,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -317,12 +305,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -532,12 +514,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -593,12 +569,6 @@ MTR_PROVISIONALLY_AVAILABLE reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -684,12 +654,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -753,12 +717,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -870,12 +828,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -1022,12 +974,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -1229,12 +1175,6 @@ MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -1309,12 +1249,6 @@ MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -1403,12 +1337,6 @@ MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -1481,12 +1409,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -1567,12 +1489,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -1639,12 +1555,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -1706,12 +1616,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -1959,12 +1863,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -2109,12 +2007,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -2283,12 +2175,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -2351,12 +2237,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -2487,12 +2367,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -2581,12 +2455,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -3029,12 +2897,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -3177,12 +3039,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -3301,12 +3157,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -3471,12 +3321,6 @@ MTR_PROVISIONALLY_AVAILABLE reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -3646,12 +3490,6 @@ MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -3727,12 +3565,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -3827,12 +3659,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -3973,12 +3799,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -4087,12 +3907,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -4155,12 +3969,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -4224,12 +4032,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -4291,12 +4093,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -4431,12 +4227,6 @@ MTR_PROVISIONALLY_AVAILABLE reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -4537,12 +4327,6 @@ MTR_PROVISIONALLY_AVAILABLE reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -4667,12 +4451,6 @@ MTR_PROVISIONALLY_AVAILABLE reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -4764,12 +4542,6 @@ MTR_PROVISIONALLY_AVAILABLE reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -4840,12 +4612,6 @@ MTR_PROVISIONALLY_AVAILABLE reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -4948,12 +4714,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -5045,12 +4805,6 @@ MTR_PROVISIONALLY_AVAILABLE reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -5142,12 +4896,6 @@ MTR_PROVISIONALLY_AVAILABLE reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -5231,12 +4979,6 @@ MTR_PROVISIONALLY_AVAILABLE reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -5312,12 +5054,6 @@ MTR_AVAILABLE(ios(17.4), macos(14.4), watchos(10.4), tvos(17.4)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(17.4), macos(14.4), watchos(10.4), tvos(17.4)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(17.4), macos(14.4), watchos(10.4), tvos(17.4)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(17.4), macos(14.4), watchos(10.4), tvos(17.4)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -5393,12 +5129,6 @@ MTR_AVAILABLE(ios(17.4), macos(14.4), watchos(10.4), tvos(17.4)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(17.4), macos(14.4), watchos(10.4), tvos(17.4)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(17.4), macos(14.4), watchos(10.4), tvos(17.4)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(17.4), macos(14.4), watchos(10.4), tvos(17.4)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -5499,12 +5229,6 @@ MTR_PROVISIONALLY_AVAILABLE reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -5578,12 +5302,6 @@ MTR_PROVISIONALLY_AVAILABLE reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -5675,12 +5393,6 @@ MTR_PROVISIONALLY_AVAILABLE reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -5742,12 +5454,6 @@ MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -5892,12 +5598,6 @@ MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -5990,12 +5690,6 @@ MTR_PROVISIONALLY_AVAILABLE reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -6063,12 +5757,6 @@ MTR_PROVISIONALLY_AVAILABLE reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -6193,12 +5881,6 @@ MTR_PROVISIONALLY_AVAILABLE reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -6323,12 +6005,6 @@ MTR_AVAILABLE(ios(17.4), macos(14.4), watchos(10.4), tvos(17.4)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(17.4), macos(14.4), watchos(10.4), tvos(17.4)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(17.4), macos(14.4), watchos(10.4), tvos(17.4)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(17.4), macos(14.4), watchos(10.4), tvos(17.4)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -6445,12 +6121,6 @@ MTR_AVAILABLE(ios(17.4), macos(14.4), watchos(10.4), tvos(17.4)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(17.4), macos(14.4), watchos(10.4), tvos(17.4)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(17.4), macos(14.4), watchos(10.4), tvos(17.4)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(17.4), macos(14.4), watchos(10.4), tvos(17.4)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -6573,12 +6243,6 @@ MTR_PROVISIONALLY_AVAILABLE reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -6681,12 +6345,6 @@ MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -6789,12 +6447,6 @@ MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -6913,12 +6565,6 @@ MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -7061,12 +6707,6 @@ MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -7236,12 +6876,6 @@ MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -7333,12 +6967,6 @@ MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -7445,12 +7073,6 @@ MTR_PROVISIONALLY_AVAILABLE reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -7591,12 +7213,6 @@ MTR_PROVISIONALLY_AVAILABLE reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -7677,12 +7293,6 @@ MTR_PROVISIONALLY_AVAILABLE reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -7841,12 +7451,6 @@ MTR_PROVISIONALLY_AVAILABLE reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -8097,12 +7701,6 @@ MTR_PROVISIONALLY_AVAILABLE reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -8192,12 +7790,6 @@ MTR_PROVISIONALLY_AVAILABLE reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -8265,12 +7857,6 @@ MTR_PROVISIONALLY_AVAILABLE reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -8345,12 +7931,6 @@ MTR_PROVISIONALLY_AVAILABLE reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -8425,12 +8005,6 @@ MTR_PROVISIONALLY_AVAILABLE reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -8505,12 +8079,6 @@ MTR_PROVISIONALLY_AVAILABLE reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -9007,12 +8575,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -9251,12 +8813,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -9361,12 +8917,6 @@ MTR_PROVISIONALLY_AVAILABLE reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -9568,12 +9118,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -10092,12 +9636,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -10246,12 +9784,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -10331,12 +9863,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -10845,12 +10371,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -11010,12 +10530,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -11101,12 +10615,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -11186,12 +10694,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -11301,12 +10803,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -11386,12 +10882,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -11471,12 +10961,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -11636,12 +11120,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -11763,12 +11241,6 @@ MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -11890,12 +11362,6 @@ MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -12017,12 +11483,6 @@ MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -12144,12 +11604,6 @@ MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -12271,12 +11725,6 @@ MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -12398,12 +11846,6 @@ MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -12525,12 +11967,6 @@ MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -12652,12 +12088,6 @@ MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -12779,12 +12209,6 @@ MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -12906,12 +12330,6 @@ MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -12988,12 +12406,6 @@ MTR_PROVISIONALLY_AVAILABLE reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -13114,12 +12526,6 @@ MTR_PROVISIONALLY_AVAILABLE reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -13214,12 +12620,6 @@ MTR_PROVISIONALLY_AVAILABLE reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -13287,12 +12687,6 @@ MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -13405,12 +12799,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -13485,12 +12873,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -13715,12 +13097,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -13817,12 +13193,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -13887,12 +13257,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -13955,12 +13319,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -14043,12 +13401,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -14129,12 +13481,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -14229,12 +13575,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -14338,12 +13678,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -14420,12 +13754,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -14602,12 +13930,6 @@ MTR_PROVISIONALLY_AVAILABLE reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -14670,12 +13992,6 @@ MTR_PROVISIONALLY_AVAILABLE reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -14786,12 +14102,6 @@ MTR_PROVISIONALLY_AVAILABLE reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -15254,12 +14564,6 @@ MTR_PROVISIONALLY_AVAILABLE reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -15352,12 +14656,6 @@ MTR_PROVISIONALLY_AVAILABLE reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -15444,12 +14742,6 @@ MTR_PROVISIONALLY_AVAILABLE reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -15536,12 +14828,6 @@ MTR_PROVISIONALLY_AVAILABLE reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -15609,12 +14895,6 @@ MTR_PROVISIONALLY_AVAILABLE reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -15689,12 +14969,6 @@ MTR_PROVISIONALLY_AVAILABLE reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -16656,12 +15930,6 @@ MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished @@ -16748,12 +16016,6 @@ MTR_PROVISIONALLY_AVAILABLE reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm index 6e2ea748a37766..eb2a2f5687c1f5 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm @@ -283,42 +283,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = Identify::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = Identify::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = Identify::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = Identify::Attributes::AttributeList::TypeInfo; @@ -963,42 +927,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = Groups::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = Groups::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = Groups::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = Groups::Attributes::AttributeList::TypeInfo; @@ -1881,42 +1809,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = OnOff::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = OnOff::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = OnOff::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = OnOff::Attributes::AttributeList::TypeInfo; @@ -3475,42 +3367,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = LevelControl::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = LevelControl::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = LevelControl::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = LevelControl::Attributes::AttributeList::TypeInfo; @@ -4473,42 +4329,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = PulseWidthModulation::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = PulseWidthModulation::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = PulseWidthModulation::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = PulseWidthModulation::Attributes::AttributeList::TypeInfo; @@ -4873,42 +4693,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = Descriptor::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = Descriptor::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = Descriptor::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = Descriptor::Attributes::AttributeList::TypeInfo; @@ -5520,42 +5304,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = Binding::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = Binding::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = Binding::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = Binding::Attributes::AttributeList::TypeInfo; @@ -6418,42 +6166,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = AccessControl::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = AccessControl::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = AccessControl::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = AccessControl::Attributes::AttributeList::TypeInfo; @@ -7412,42 +7124,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = Actions::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = Actions::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = Actions::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = Actions::Attributes::AttributeList::TypeInfo; @@ -8925,42 +8601,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = BasicInformation::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = BasicInformation::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = BasicInformation::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = BasicInformation::Attributes::AttributeList::TypeInfo; @@ -10141,42 +9781,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = OtaSoftwareUpdateProvider::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = OtaSoftwareUpdateProvider::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = OtaSoftwareUpdateProvider::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = OtaSoftwareUpdateProvider::Attributes::AttributeList::TypeInfo; @@ -10792,42 +10396,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = OtaSoftwareUpdateRequestor::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = OtaSoftwareUpdateRequestor::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = OtaSoftwareUpdateRequestor::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = OtaSoftwareUpdateRequestor::Attributes::AttributeList::TypeInfo; @@ -11455,42 +11023,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = LocalizationConfiguration::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = LocalizationConfiguration::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = LocalizationConfiguration::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = LocalizationConfiguration::Attributes::AttributeList::TypeInfo; @@ -12103,42 +11635,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = TimeFormatLocalization::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = TimeFormatLocalization::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = TimeFormatLocalization::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = TimeFormatLocalization::Attributes::AttributeList::TypeInfo; @@ -12694,42 +12190,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = UnitLocalization::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = UnitLocalization::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = UnitLocalization::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = UnitLocalization::Attributes::AttributeList::TypeInfo; @@ -13179,42 +12639,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = PowerSourceConfiguration::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = PowerSourceConfiguration::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = PowerSourceConfiguration::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = PowerSourceConfiguration::Attributes::AttributeList::TypeInfo; @@ -14772,42 +14196,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = PowerSource::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = PowerSource::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = PowerSource::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = PowerSource::Attributes::AttributeList::TypeInfo; @@ -16752,42 +16140,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = GeneralCommissioning::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = GeneralCommissioning::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = GeneralCommissioning::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = GeneralCommissioning::Attributes::AttributeList::TypeInfo; @@ -17967,42 +17319,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = NetworkCommissioning::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = NetworkCommissioning::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = NetworkCommissioning::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = NetworkCommissioning::Attributes::AttributeList::TypeInfo; @@ -18735,42 +18051,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = DiagnosticLogs::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = DiagnosticLogs::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = DiagnosticLogs::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = DiagnosticLogs::Attributes::AttributeList::TypeInfo; @@ -19551,42 +18831,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = GeneralDiagnostics::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = GeneralDiagnostics::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = GeneralDiagnostics::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = GeneralDiagnostics::Attributes::AttributeList::TypeInfo; @@ -20451,42 +19695,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = SoftwareDiagnostics::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = SoftwareDiagnostics::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = SoftwareDiagnostics::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = SoftwareDiagnostics::Attributes::AttributeList::TypeInfo; @@ -23304,42 +22512,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = ThreadNetworkDiagnostics::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = ThreadNetworkDiagnostics::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = ThreadNetworkDiagnostics::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = ThreadNetworkDiagnostics::Attributes::AttributeList::TypeInfo; @@ -26422,42 +25594,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = WiFiNetworkDiagnostics::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = WiFiNetworkDiagnostics::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = WiFiNetworkDiagnostics::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = WiFiNetworkDiagnostics::Attributes::AttributeList::TypeInfo; @@ -27646,42 +26782,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = EthernetNetworkDiagnostics::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = EthernetNetworkDiagnostics::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = EthernetNetworkDiagnostics::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = EthernetNetworkDiagnostics::Attributes::AttributeList::TypeInfo; @@ -28966,42 +28066,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = TimeSynchronization::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = TimeSynchronization::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = TimeSynchronization::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = TimeSynchronization::Attributes::AttributeList::TypeInfo; @@ -29851,42 +28915,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = BridgedDeviceBasicInformation::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = BridgedDeviceBasicInformation::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = BridgedDeviceBasicInformation::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = BridgedDeviceBasicInformation::Attributes::AttributeList::TypeInfo; @@ -30901,42 +29929,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = Switch::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = Switch::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = Switch::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = Switch::Attributes::AttributeList::TypeInfo; @@ -31606,42 +30598,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = AdministratorCommissioning::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = AdministratorCommissioning::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = AdministratorCommissioning::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = AdministratorCommissioning::Attributes::AttributeList::TypeInfo; @@ -32546,42 +31502,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = OperationalCredentials::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = OperationalCredentials::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = OperationalCredentials::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = OperationalCredentials::Attributes::AttributeList::TypeInfo; @@ -33520,42 +32440,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = GroupKeyManagement::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = GroupKeyManagement::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = GroupKeyManagement::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = GroupKeyManagement::Attributes::AttributeList::TypeInfo; @@ -34137,42 +33021,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = FixedLabel::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = FixedLabel::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = FixedLabel::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = FixedLabel::Attributes::AttributeList::TypeInfo; @@ -34664,42 +33512,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = UserLabel::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = UserLabel::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = UserLabel::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = UserLabel::Attributes::AttributeList::TypeInfo; @@ -35149,42 +33961,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = BooleanState::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = BooleanState::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = BooleanState::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = BooleanState::Attributes::AttributeList::TypeInfo; @@ -36023,42 +34799,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = IcdManagement::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = IcdManagement::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = IcdManagement::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = IcdManagement::Attributes::AttributeList::TypeInfo; @@ -36452,42 +35192,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = Timer::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = Timer::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = Timer::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = Timer::Attributes::AttributeList::TypeInfo; @@ -37001,42 +35705,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = OvenCavityOperationalState::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = OvenCavityOperationalState::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = OvenCavityOperationalState::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = OvenCavityOperationalState::Attributes::AttributeList::TypeInfo; @@ -37456,42 +36124,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = OvenMode::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = OvenMode::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = OvenMode::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = OvenMode::Attributes::AttributeList::TypeInfo; @@ -37781,42 +36413,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = LaundryDryerControls::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = LaundryDryerControls::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = LaundryDryerControls::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = LaundryDryerControls::Attributes::AttributeList::TypeInfo; @@ -38308,42 +36904,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = ModeSelect::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = ModeSelect::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = ModeSelect::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = ModeSelect::Attributes::AttributeList::TypeInfo; @@ -39181,42 +37741,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = LaundryWasherMode::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = LaundryWasherMode::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = LaundryWasherMode::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = LaundryWasherMode::Attributes::AttributeList::TypeInfo; @@ -39636,42 +38160,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = RefrigeratorAndTemperatureControlledCabinetMode::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = RefrigeratorAndTemperatureControlledCabinetMode::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = RefrigeratorAndTemperatureControlledCabinetMode::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = RefrigeratorAndTemperatureControlledCabinetMode::Attributes::AttributeList::TypeInfo; @@ -40061,42 +38549,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = LaundryWasherControls::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = LaundryWasherControls::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = LaundryWasherControls::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = LaundryWasherControls::Attributes::AttributeList::TypeInfo; @@ -40378,42 +38830,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = RvcRunMode::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = RvcRunMode::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = RvcRunMode::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = RvcRunMode::Attributes::AttributeList::TypeInfo; @@ -40695,42 +39111,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = RvcCleanMode::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = RvcCleanMode::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = RvcCleanMode::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = RvcCleanMode::Attributes::AttributeList::TypeInfo; @@ -41160,42 +39540,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = TemperatureControl::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = TemperatureControl::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = TemperatureControl::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = TemperatureControl::Attributes::AttributeList::TypeInfo; @@ -41488,42 +39832,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = RefrigeratorAlarm::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = RefrigeratorAlarm::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = RefrigeratorAlarm::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = RefrigeratorAlarm::Attributes::AttributeList::TypeInfo; @@ -41943,42 +40251,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = DishwasherMode::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = DishwasherMode::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = DishwasherMode::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = DishwasherMode::Attributes::AttributeList::TypeInfo; @@ -42199,42 +40471,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = AirQuality::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = AirQuality::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = AirQuality::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = AirQuality::Attributes::AttributeList::TypeInfo; @@ -42944,42 +41180,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = SmokeCoAlarm::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = SmokeCoAlarm::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = SmokeCoAlarm::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = SmokeCoAlarm::Attributes::AttributeList::TypeInfo; @@ -43357,42 +41557,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = DishwasherAlarm::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = DishwasherAlarm::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = DishwasherAlarm::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = DishwasherAlarm::Attributes::AttributeList::TypeInfo; @@ -43649,42 +41813,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = MicrowaveOvenMode::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = MicrowaveOvenMode::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = MicrowaveOvenMode::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = MicrowaveOvenMode::Attributes::AttributeList::TypeInfo; @@ -44246,42 +42374,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = MicrowaveOvenControl::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = MicrowaveOvenControl::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = MicrowaveOvenControl::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = MicrowaveOvenControl::Attributes::AttributeList::TypeInfo; @@ -44795,42 +42887,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = OperationalState::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = OperationalState::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = OperationalState::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = OperationalState::Attributes::AttributeList::TypeInfo; @@ -45316,42 +43372,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = RvcOperationalState::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = RvcOperationalState::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = RvcOperationalState::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = RvcOperationalState::Attributes::AttributeList::TypeInfo; @@ -45837,42 +43857,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = ScenesManagement::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = ScenesManagement::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = ScenesManagement::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = ScenesManagement::Attributes::AttributeList::TypeInfo; @@ -46335,42 +44319,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = HepaFilterMonitoring::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = HepaFilterMonitoring::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = HepaFilterMonitoring::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = HepaFilterMonitoring::Attributes::AttributeList::TypeInfo; @@ -46833,42 +44781,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = ActivatedCarbonFilterMonitoring::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = ActivatedCarbonFilterMonitoring::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = ActivatedCarbonFilterMonitoring::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = ActivatedCarbonFilterMonitoring::Attributes::AttributeList::TypeInfo; @@ -47418,42 +45330,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = BooleanStateConfiguration::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = BooleanStateConfiguration::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = BooleanStateConfiguration::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = BooleanStateConfiguration::Attributes::AttributeList::TypeInfo; @@ -48152,42 +46028,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = ValveConfigurationAndControl::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = ValveConfigurationAndControl::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = ValveConfigurationAndControl::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = ValveConfigurationAndControl::Attributes::AttributeList::TypeInfo; @@ -49056,42 +46896,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = ElectricalPowerMeasurement::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = ElectricalPowerMeasurement::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = ElectricalPowerMeasurement::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = ElectricalPowerMeasurement::Attributes::AttributeList::TypeInfo; @@ -49492,42 +47296,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = ElectricalEnergyMeasurement::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = ElectricalEnergyMeasurement::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = ElectricalEnergyMeasurement::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = ElectricalEnergyMeasurement::Attributes::AttributeList::TypeInfo; @@ -49981,42 +47749,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = WaterHeaterManagement::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = WaterHeaterManagement::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = WaterHeaterManagement::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = WaterHeaterManagement::Attributes::AttributeList::TypeInfo; @@ -50670,42 +48402,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = DemandResponseLoadControl::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = DemandResponseLoadControl::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = DemandResponseLoadControl::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = DemandResponseLoadControl::Attributes::AttributeList::TypeInfo; @@ -51011,42 +48707,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = Messages::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = Messages::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = Messages::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = Messages::Attributes::AttributeList::TypeInfo; @@ -51724,42 +49384,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = DeviceEnergyManagement::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = DeviceEnergyManagement::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = DeviceEnergyManagement::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = DeviceEnergyManagement::Attributes::AttributeList::TypeInfo; @@ -53067,42 +50691,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = EnergyEvse::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = EnergyEvse::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = EnergyEvse::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = EnergyEvse::Attributes::AttributeList::TypeInfo; @@ -53523,42 +51111,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = EnergyPreference::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = EnergyPreference::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = EnergyPreference::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = EnergyPreference::Attributes::AttributeList::TypeInfo; @@ -53815,42 +51367,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = PowerTopology::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = PowerTopology::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = PowerTopology::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = PowerTopology::Attributes::AttributeList::TypeInfo; @@ -54132,42 +51648,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = EnergyEvseMode::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = EnergyEvseMode::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = EnergyEvseMode::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = EnergyEvseMode::Attributes::AttributeList::TypeInfo; @@ -54449,42 +51929,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = WaterHeaterMode::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = WaterHeaterMode::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = WaterHeaterMode::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = WaterHeaterMode::Attributes::AttributeList::TypeInfo; @@ -54766,42 +52210,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = DeviceEnergyManagementMode::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = DeviceEnergyManagementMode::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = DeviceEnergyManagementMode::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = DeviceEnergyManagementMode::Attributes::AttributeList::TypeInfo; @@ -57661,42 +55069,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = DoorLock::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = DoorLock::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = DoorLock::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = DoorLock::Attributes::AttributeList::TypeInfo; @@ -60581,42 +57953,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = WindowCovering::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = WindowCovering::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = WindowCovering::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = WindowCovering::Attributes::AttributeList::TypeInfo; @@ -62078,42 +59414,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = ServiceArea::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = ServiceArea::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = ServiceArea::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = ServiceArea::Attributes::AttributeList::TypeInfo; @@ -63248,42 +60548,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = PumpConfigurationAndControl::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = PumpConfigurationAndControl::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = PumpConfigurationAndControl::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = PumpConfigurationAndControl::Attributes::AttributeList::TypeInfo; @@ -67781,42 +65045,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = Thermostat::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = Thermostat::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = Thermostat::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = Thermostat::Attributes::AttributeList::TypeInfo; @@ -70809,42 +68037,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = FanControl::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = FanControl::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = FanControl::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = FanControl::Attributes::AttributeList::TypeInfo; @@ -71840,42 +69032,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = ThermostatUserInterfaceConfiguration::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = ThermostatUserInterfaceConfiguration::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = ThermostatUserInterfaceConfiguration::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = ThermostatUserInterfaceConfiguration::Attributes::AttributeList::TypeInfo; @@ -75088,42 +72244,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = ColorControl::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = ColorControl::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = ColorControl::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = ColorControl::Attributes::AttributeList::TypeInfo; @@ -78323,42 +75443,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = BallastConfiguration::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = BallastConfiguration::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = BallastConfiguration::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = BallastConfiguration::Attributes::AttributeList::TypeInfo; @@ -79479,42 +76563,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = IlluminanceMeasurement::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = IlluminanceMeasurement::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = IlluminanceMeasurement::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = IlluminanceMeasurement::Attributes::AttributeList::TypeInfo; @@ -80204,42 +77252,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = TemperatureMeasurement::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = TemperatureMeasurement::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = TemperatureMeasurement::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = TemperatureMeasurement::Attributes::AttributeList::TypeInfo; @@ -81074,42 +78086,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = PressureMeasurement::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = PressureMeasurement::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = PressureMeasurement::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = PressureMeasurement::Attributes::AttributeList::TypeInfo; @@ -81939,42 +78915,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = FlowMeasurement::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = FlowMeasurement::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = FlowMeasurement::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = FlowMeasurement::Attributes::AttributeList::TypeInfo; @@ -82629,42 +79569,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = RelativeHumidityMeasurement::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = RelativeHumidityMeasurement::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = RelativeHumidityMeasurement::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = RelativeHumidityMeasurement::Attributes::AttributeList::TypeInfo; @@ -83959,42 +80863,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = OccupancySensing::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = OccupancySensing::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = OccupancySensing::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = OccupancySensing::Attributes::AttributeList::TypeInfo; @@ -85253,42 +82121,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = CarbonMonoxideConcentrationMeasurement::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = CarbonMonoxideConcentrationMeasurement::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = CarbonMonoxideConcentrationMeasurement::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = CarbonMonoxideConcentrationMeasurement::Attributes::AttributeList::TypeInfo; @@ -85869,42 +82701,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = CarbonDioxideConcentrationMeasurement::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = CarbonDioxideConcentrationMeasurement::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = CarbonDioxideConcentrationMeasurement::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = CarbonDioxideConcentrationMeasurement::Attributes::AttributeList::TypeInfo; @@ -86485,42 +83281,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = NitrogenDioxideConcentrationMeasurement::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = NitrogenDioxideConcentrationMeasurement::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = NitrogenDioxideConcentrationMeasurement::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = NitrogenDioxideConcentrationMeasurement::Attributes::AttributeList::TypeInfo; @@ -87101,42 +83861,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = OzoneConcentrationMeasurement::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = OzoneConcentrationMeasurement::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = OzoneConcentrationMeasurement::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = OzoneConcentrationMeasurement::Attributes::AttributeList::TypeInfo; @@ -87717,42 +84441,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = Pm25ConcentrationMeasurement::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = Pm25ConcentrationMeasurement::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = Pm25ConcentrationMeasurement::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = Pm25ConcentrationMeasurement::Attributes::AttributeList::TypeInfo; @@ -88333,42 +85021,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = FormaldehydeConcentrationMeasurement::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = FormaldehydeConcentrationMeasurement::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = FormaldehydeConcentrationMeasurement::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = FormaldehydeConcentrationMeasurement::Attributes::AttributeList::TypeInfo; @@ -88949,42 +85601,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = Pm1ConcentrationMeasurement::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = Pm1ConcentrationMeasurement::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = Pm1ConcentrationMeasurement::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = Pm1ConcentrationMeasurement::Attributes::AttributeList::TypeInfo; @@ -89565,42 +86181,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = Pm10ConcentrationMeasurement::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = Pm10ConcentrationMeasurement::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = Pm10ConcentrationMeasurement::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = Pm10ConcentrationMeasurement::Attributes::AttributeList::TypeInfo; @@ -90181,42 +86761,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = TotalVolatileOrganicCompoundsConcentrationMeasurement::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = TotalVolatileOrganicCompoundsConcentrationMeasurement::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = TotalVolatileOrganicCompoundsConcentrationMeasurement::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = TotalVolatileOrganicCompoundsConcentrationMeasurement::Attributes::AttributeList::TypeInfo; @@ -90797,42 +87341,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = RadonConcentrationMeasurement::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = RadonConcentrationMeasurement::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = RadonConcentrationMeasurement::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = RadonConcentrationMeasurement::Attributes::AttributeList::TypeInfo; @@ -91118,42 +87626,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = WiFiNetworkManagement::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = WiFiNetworkManagement::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = WiFiNetworkManagement::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = WiFiNetworkManagement::Attributes::AttributeList::TypeInfo; @@ -91659,42 +88131,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = ThreadBorderRouterManagement::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = ThreadBorderRouterManagement::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = ThreadBorderRouterManagement::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = ThreadBorderRouterManagement::Attributes::AttributeList::TypeInfo; @@ -92099,42 +88535,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = ThreadNetworkDirectory::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = ThreadNetworkDirectory::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = ThreadNetworkDirectory::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = ThreadNetworkDirectory::Attributes::AttributeList::TypeInfo; @@ -92391,42 +88791,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = WakeOnLan::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = WakeOnLan::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = WakeOnLan::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = WakeOnLan::Attributes::AttributeList::TypeInfo; @@ -93092,42 +89456,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = Channel::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = Channel::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = Channel::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = Channel::Attributes::AttributeList::TypeInfo; @@ -93719,42 +90047,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = TargetNavigator::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = TargetNavigator::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = TargetNavigator::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = TargetNavigator::Attributes::AttributeList::TypeInfo; @@ -94973,42 +91265,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = MediaPlayback::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = MediaPlayback::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = MediaPlayback::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = MediaPlayback::Attributes::AttributeList::TypeInfo; @@ -95922,42 +92178,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = MediaInput::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = MediaInput::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = MediaInput::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = MediaInput::Attributes::AttributeList::TypeInfo; @@ -96456,42 +92676,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = LowPower::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = LowPower::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = LowPower::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = LowPower::Attributes::AttributeList::TypeInfo; @@ -96897,42 +93081,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = KeypadInput::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = KeypadInput::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = KeypadInput::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = KeypadInput::Attributes::AttributeList::TypeInfo; @@ -97461,42 +93609,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = ContentLauncher::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = ContentLauncher::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = ContentLauncher::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = ContentLauncher::Attributes::AttributeList::TypeInfo; @@ -98083,42 +94195,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = AudioOutput::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = AudioOutput::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = AudioOutput::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = AudioOutput::Attributes::AttributeList::TypeInfo; @@ -98765,42 +94841,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = ApplicationLauncher::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = ApplicationLauncher::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = ApplicationLauncher::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = ApplicationLauncher::Attributes::AttributeList::TypeInfo; @@ -99562,42 +95602,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = ApplicationBasic::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = ApplicationBasic::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = ApplicationBasic::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = ApplicationBasic::Attributes::AttributeList::TypeInfo; @@ -100334,42 +96338,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = AccountLogin::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = AccountLogin::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = AccountLogin::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = AccountLogin::Attributes::AttributeList::TypeInfo; @@ -101316,42 +97284,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = ContentControl::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = ContentControl::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = ContentControl::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = ContentControl::Attributes::AttributeList::TypeInfo; @@ -101561,42 +97493,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = ContentAppObserver::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = ContentAppObserver::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = ContentAppObserver::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = ContentAppObserver::Attributes::AttributeList::TypeInfo; @@ -102106,42 +98002,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = ZoneManagement::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = ZoneManagement::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = ZoneManagement::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = ZoneManagement::Attributes::AttributeList::TypeInfo; @@ -104996,42 +100856,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = CameraAvStreamManagement::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = CameraAvStreamManagement::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = CameraAvStreamManagement::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = CameraAvStreamManagement::Attributes::AttributeList::TypeInfo; @@ -105373,42 +101197,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = WebRTCTransportProvider::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = WebRTCTransportProvider::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = WebRTCTransportProvider::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = WebRTCTransportProvider::Attributes::AttributeList::TypeInfo; @@ -105726,42 +101514,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = WebRTCTransportRequestor::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = WebRTCTransportRequestor::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = WebRTCTransportRequestor::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = WebRTCTransportRequestor::Attributes::AttributeList::TypeInfo; @@ -106139,42 +101891,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = Chime::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = Chime::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = Chime::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = Chime::Attributes::AttributeList::TypeInfo; @@ -106431,42 +102147,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = EcosystemInformation::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = EcosystemInformation::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = EcosystemInformation::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = EcosystemInformation::Attributes::AttributeList::TypeInfo; @@ -106736,42 +102416,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = CommissionerControl::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = CommissionerControl::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = CommissionerControl::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = CommissionerControl::Attributes::AttributeList::TypeInfo; @@ -113851,42 +109495,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = UnitTesting::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = UnitTesting::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = UnitTesting::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = UnitTesting::Attributes::AttributeList::TypeInfo; @@ -118157,42 +113765,6 @@ + (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCa completion:completion]; } -- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = SampleMei::Attributes::EventList::TypeInfo; - [self.device _readKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:nil - queue:self.callbackQueue - completion:completion]; -} - -- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params - subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished - reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler -{ - using TypeInfo = SampleMei::Attributes::EventList::TypeInfo; - [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID - clusterID:@(TypeInfo::GetClusterId()) - attributeID:@(TypeInfo::GetAttributeId()) - params:params - queue:self.callbackQueue - reportHandler:reportHandler - subscriptionEstablished:subscriptionEstablished]; -} - -+ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion -{ - using TypeInfo = SampleMei::Attributes::EventList::TypeInfo; - [clusterStateCacheContainer - _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) - clusterID:TypeInfo::GetClusterId() - attributeID:TypeInfo::GetAttributeId() - queue:queue - completion:completion]; -} - - (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion { using TypeInfo = SampleMei::Attributes::AttributeList::TypeInfo; diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h b/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h index 6f9901c3c8dc9a..7ee2c7d88af1c0 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h @@ -240,7 +240,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { // Global attributes MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x0000FFF8, MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x0000FFF9, - MTRAttributeIDTypeGlobalAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = 0x0000FFFA, MTRAttributeIDTypeGlobalAttributeAttributeListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x0000FFFB, MTRAttributeIDTypeGlobalAttributeFeatureMapID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x0000FFFC, MTRAttributeIDTypeGlobalAttributeClusterRevisionID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x0000FFFD, @@ -273,7 +272,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterIdentifyAttributeIdentifyTypeID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000001, MTRAttributeIDTypeClusterIdentifyAttributeGeneratedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterIdentifyAttributeAcceptedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterIdentifyAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterIdentifyAttributeAttributeListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterIdentifyAttributeFeatureMapID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterIdentifyAttributeClusterRevisionID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -302,7 +300,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterGroupsAttributeNameSupportID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000000, MTRAttributeIDTypeClusterGroupsAttributeGeneratedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterGroupsAttributeAcceptedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterGroupsAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterGroupsAttributeAttributeListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterGroupsAttributeFeatureMapID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterGroupsAttributeClusterRevisionID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -347,7 +344,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterOnOffAttributeStartUpOnOffID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00004003, MTRAttributeIDTypeClusterOnOffAttributeGeneratedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterOnOffAttributeAcceptedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterOnOffAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterOnOffAttributeAttributeListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterOnOffAttributeFeatureMapID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterOnOffAttributeClusterRevisionID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -428,7 +424,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterLevelControlAttributeStartUpCurrentLevelID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00004000, MTRAttributeIDTypeClusterLevelControlAttributeGeneratedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterLevelControlAttributeAcceptedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterLevelControlAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterLevelControlAttributeAttributeListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterLevelControlAttributeFeatureMapID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterLevelControlAttributeClusterRevisionID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -453,7 +448,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { // Cluster PulseWidthModulation attributes MTRAttributeIDTypeClusterPulseWidthModulationAttributeGeneratedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterPulseWidthModulationAttributeAcceptedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterPulseWidthModulationAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterPulseWidthModulationAttributeAttributeListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterPulseWidthModulationAttributeFeatureMapID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterPulseWidthModulationAttributeClusterRevisionID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -498,7 +492,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterDescriptorAttributeTagListID MTR_PROVISIONALLY_AVAILABLE = 0x00000004, MTRAttributeIDTypeClusterDescriptorAttributeGeneratedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterDescriptorAttributeAcceptedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterDescriptorAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterDescriptorAttributeAttributeListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterDescriptorAttributeFeatureMapID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterDescriptorAttributeClusterRevisionID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -527,7 +520,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterBindingAttributeBindingID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000000, MTRAttributeIDTypeClusterBindingAttributeGeneratedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterBindingAttributeAcceptedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterBindingAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterBindingAttributeAttributeListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterBindingAttributeFeatureMapID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterBindingAttributeClusterRevisionID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -574,7 +566,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterAccessControlAttributeARLID MTR_PROVISIONALLY_AVAILABLE = 0x00000006, MTRAttributeIDTypeClusterAccessControlAttributeGeneratedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterAccessControlAttributeAcceptedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterAccessControlAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterAccessControlAttributeAttributeListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterAccessControlAttributeFeatureMapID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterAccessControlAttributeClusterRevisionID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -611,7 +602,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterActionsAttributeSetupURLID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000002, MTRAttributeIDTypeClusterActionsAttributeGeneratedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterActionsAttributeAcceptedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterActionsAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterActionsAttributeAttributeListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterActionsAttributeFeatureMapID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterActionsAttributeClusterRevisionID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -719,7 +709,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterBasicInformationAttributeMaxPathsPerInvokeID MTR_PROVISIONALLY_AVAILABLE = 0x00000016, MTRAttributeIDTypeClusterBasicInformationAttributeGeneratedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterBasicInformationAttributeAcceptedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterBasicInformationAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterBasicInformationAttributeAttributeListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterBasicInformationAttributeFeatureMapID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterBasicInformationAttributeClusterRevisionID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -744,7 +733,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { // Cluster OTASoftwareUpdateProvider attributes MTRAttributeIDTypeClusterOTASoftwareUpdateProviderAttributeGeneratedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterOTASoftwareUpdateProviderAttributeAcceptedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterOTASoftwareUpdateProviderAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterOTASoftwareUpdateProviderAttributeAttributeListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterOTASoftwareUpdateProviderAttributeFeatureMapID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterOTASoftwareUpdateProviderAttributeClusterRevisionID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -785,7 +773,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterOTASoftwareUpdateRequestorAttributeUpdateStateProgressID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000003, MTRAttributeIDTypeClusterOTASoftwareUpdateRequestorAttributeGeneratedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterOTASoftwareUpdateRequestorAttributeAcceptedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterOTASoftwareUpdateRequestorAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterOTASoftwareUpdateRequestorAttributeAttributeListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterOTASoftwareUpdateRequestorAttributeFeatureMapID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterOTASoftwareUpdateRequestorAttributeClusterRevisionID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -818,7 +805,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterLocalizationConfigurationAttributeSupportedLocalesID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000001, MTRAttributeIDTypeClusterLocalizationConfigurationAttributeGeneratedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterLocalizationConfigurationAttributeAcceptedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterLocalizationConfigurationAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterLocalizationConfigurationAttributeAttributeListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterLocalizationConfigurationAttributeFeatureMapID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterLocalizationConfigurationAttributeClusterRevisionID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -855,7 +841,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterTimeFormatLocalizationAttributeSupportedCalendarTypesID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000002, MTRAttributeIDTypeClusterTimeFormatLocalizationAttributeGeneratedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterTimeFormatLocalizationAttributeAcceptedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterTimeFormatLocalizationAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterTimeFormatLocalizationAttributeAttributeListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterTimeFormatLocalizationAttributeFeatureMapID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterTimeFormatLocalizationAttributeClusterRevisionID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -884,7 +869,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterUnitLocalizationAttributeTemperatureUnitID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000000, MTRAttributeIDTypeClusterUnitLocalizationAttributeGeneratedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterUnitLocalizationAttributeAcceptedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterUnitLocalizationAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterUnitLocalizationAttributeAttributeListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterUnitLocalizationAttributeFeatureMapID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterUnitLocalizationAttributeClusterRevisionID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -913,7 +897,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterPowerSourceConfigurationAttributeSourcesID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000000, MTRAttributeIDTypeClusterPowerSourceConfigurationAttributeGeneratedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterPowerSourceConfigurationAttributeAcceptedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterPowerSourceConfigurationAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterPowerSourceConfigurationAttributeAttributeListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterPowerSourceConfigurationAttributeFeatureMapID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterPowerSourceConfigurationAttributeClusterRevisionID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -1063,7 +1046,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterPowerSourceAttributeEndpointListID MTR_AVAILABLE(ios(17.4), macos(14.4), watchos(10.4), tvos(17.4)) = 0x0000001F, MTRAttributeIDTypeClusterPowerSourceAttributeGeneratedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterPowerSourceAttributeAcceptedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterPowerSourceAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterPowerSourceAttributeAttributeListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterPowerSourceAttributeFeatureMapID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterPowerSourceAttributeClusterRevisionID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -1113,7 +1095,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterGeneralCommissioningAttributeTCUpdateDeadlineID MTR_PROVISIONALLY_AVAILABLE = 0x00000009, MTRAttributeIDTypeClusterGeneralCommissioningAttributeGeneratedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterGeneralCommissioningAttributeAcceptedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterGeneralCommissioningAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterGeneralCommissioningAttributeAttributeListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterGeneralCommissioningAttributeFeatureMapID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterGeneralCommissioningAttributeClusterRevisionID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -1173,7 +1154,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterNetworkCommissioningAttributeThreadVersionID MTR_PROVISIONALLY_AVAILABLE = 0x0000000A, MTRAttributeIDTypeClusterNetworkCommissioningAttributeGeneratedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterNetworkCommissioningAttributeAcceptedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterNetworkCommissioningAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterNetworkCommissioningAttributeAttributeListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterNetworkCommissioningAttributeFeatureMapID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterNetworkCommissioningAttributeClusterRevisionID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -1198,7 +1178,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { // Cluster DiagnosticLogs attributes MTRAttributeIDTypeClusterDiagnosticLogsAttributeGeneratedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterDiagnosticLogsAttributeAcceptedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterDiagnosticLogsAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterDiagnosticLogsAttributeAttributeListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterDiagnosticLogsAttributeFeatureMapID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterDiagnosticLogsAttributeClusterRevisionID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -1259,7 +1238,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterGeneralDiagnosticsAttributeTestEventTriggersEnabledID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000008, MTRAttributeIDTypeClusterGeneralDiagnosticsAttributeGeneratedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterGeneralDiagnosticsAttributeAcceptedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterGeneralDiagnosticsAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterGeneralDiagnosticsAttributeAttributeListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterGeneralDiagnosticsAttributeFeatureMapID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterGeneralDiagnosticsAttributeClusterRevisionID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -1300,7 +1278,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterSoftwareDiagnosticsAttributeCurrentHeapHighWatermarkID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000003, MTRAttributeIDTypeClusterSoftwareDiagnosticsAttributeGeneratedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterSoftwareDiagnosticsAttributeAcceptedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterSoftwareDiagnosticsAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterSoftwareDiagnosticsAttributeAttributeListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterSoftwareDiagnosticsAttributeFeatureMapID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterSoftwareDiagnosticsAttributeClusterRevisionID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -1577,7 +1554,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterThreadNetworkDiagnosticsAttributeActiveNetworkFaultsListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x0000003E, MTRAttributeIDTypeClusterThreadNetworkDiagnosticsAttributeGeneratedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterThreadNetworkDiagnosticsAttributeAcceptedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterThreadNetworkDiagnosticsAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterThreadNetworkDiagnosticsAttributeAttributeListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterThreadNetworkDiagnosticsAttributeFeatureMapID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterThreadNetworkDiagnosticsAttributeClusterRevisionID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -1654,7 +1630,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterWiFiNetworkDiagnosticsAttributeOverrunCountID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x0000000C, MTRAttributeIDTypeClusterWiFiNetworkDiagnosticsAttributeGeneratedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterWiFiNetworkDiagnosticsAttributeAcceptedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterWiFiNetworkDiagnosticsAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterWiFiNetworkDiagnosticsAttributeAttributeListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterWiFiNetworkDiagnosticsAttributeFeatureMapID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterWiFiNetworkDiagnosticsAttributeClusterRevisionID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -1715,7 +1690,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterEthernetNetworkDiagnosticsAttributeTimeSinceResetID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000008, MTRAttributeIDTypeClusterEthernetNetworkDiagnosticsAttributeGeneratedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterEthernetNetworkDiagnosticsAttributeAcceptedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterEthernetNetworkDiagnosticsAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterEthernetNetworkDiagnosticsAttributeAttributeListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterEthernetNetworkDiagnosticsAttributeFeatureMapID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterEthernetNetworkDiagnosticsAttributeClusterRevisionID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -1787,7 +1761,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterTimeSynchronizationAttributeSupportsDNSResolveID MTR_PROVISIONALLY_AVAILABLE = 0x0000000C, MTRAttributeIDTypeClusterTimeSynchronizationAttributeGeneratedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterTimeSynchronizationAttributeAcceptedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterTimeSynchronizationAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterTimeSynchronizationAttributeAttributeListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterTimeSynchronizationAttributeFeatureMapID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterTimeSynchronizationAttributeClusterRevisionID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -1874,7 +1847,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterBridgedDeviceBasicInformationAttributeProductAppearanceID MTR_AVAILABLE(ios(17.0), macos(14.0), watchos(10.0), tvos(17.0)) = 0x00000014, MTRAttributeIDTypeClusterBridgedDeviceBasicInformationAttributeGeneratedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterBridgedDeviceBasicInformationAttributeAcceptedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterBridgedDeviceBasicInformationAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterBridgedDeviceBasicInformationAttributeAttributeListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterBridgedDeviceBasicInformationAttributeFeatureMapID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterBridgedDeviceBasicInformationAttributeClusterRevisionID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -1911,7 +1883,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterSwitchAttributeMultiPressMaxID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000002, MTRAttributeIDTypeClusterSwitchAttributeGeneratedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterSwitchAttributeAcceptedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterSwitchAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterSwitchAttributeAttributeListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterSwitchAttributeFeatureMapID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterSwitchAttributeClusterRevisionID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -1948,7 +1919,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterAdministratorCommissioningAttributeAdminVendorIdID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000002, MTRAttributeIDTypeClusterAdministratorCommissioningAttributeGeneratedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterAdministratorCommissioningAttributeAcceptedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterAdministratorCommissioningAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterAdministratorCommissioningAttributeAttributeListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterAdministratorCommissioningAttributeFeatureMapID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterAdministratorCommissioningAttributeClusterRevisionID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -1997,7 +1967,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterOperationalCredentialsAttributeCurrentFabricIndexID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000005, MTRAttributeIDTypeClusterOperationalCredentialsAttributeGeneratedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterOperationalCredentialsAttributeAcceptedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterOperationalCredentialsAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterOperationalCredentialsAttributeAttributeListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterOperationalCredentialsAttributeFeatureMapID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterOperationalCredentialsAttributeClusterRevisionID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -2038,7 +2007,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterGroupKeyManagementAttributeMaxGroupKeysPerFabricID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000003, MTRAttributeIDTypeClusterGroupKeyManagementAttributeGeneratedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterGroupKeyManagementAttributeAcceptedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterGroupKeyManagementAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterGroupKeyManagementAttributeAttributeListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterGroupKeyManagementAttributeFeatureMapID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterGroupKeyManagementAttributeClusterRevisionID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -2067,7 +2035,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterFixedLabelAttributeLabelListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000000, MTRAttributeIDTypeClusterFixedLabelAttributeGeneratedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterFixedLabelAttributeAcceptedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterFixedLabelAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterFixedLabelAttributeAttributeListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterFixedLabelAttributeFeatureMapID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterFixedLabelAttributeClusterRevisionID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -2096,7 +2063,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterUserLabelAttributeLabelListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000000, MTRAttributeIDTypeClusterUserLabelAttributeGeneratedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterUserLabelAttributeAcceptedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterUserLabelAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterUserLabelAttributeAttributeListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterUserLabelAttributeFeatureMapID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterUserLabelAttributeClusterRevisionID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -2125,7 +2091,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterBooleanStateAttributeStateValueID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000000, MTRAttributeIDTypeClusterBooleanStateAttributeGeneratedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterBooleanStateAttributeAcceptedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterBooleanStateAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterBooleanStateAttributeAttributeListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterBooleanStateAttributeFeatureMapID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterBooleanStateAttributeClusterRevisionID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -2143,7 +2108,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterICDManagementAttributeMaximumCheckInBackOffID MTR_PROVISIONALLY_AVAILABLE = 0x00000009, MTRAttributeIDTypeClusterICDManagementAttributeGeneratedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterICDManagementAttributeAcceptedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterICDManagementAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterICDManagementAttributeAttributeListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterICDManagementAttributeFeatureMapID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterICDManagementAttributeClusterRevisionID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -2154,7 +2118,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterTimerAttributeTimerStateID MTR_PROVISIONALLY_AVAILABLE = 0x00000002, MTRAttributeIDTypeClusterTimerAttributeGeneratedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterTimerAttributeAcceptedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterTimerAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterTimerAttributeAttributeListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterTimerAttributeFeatureMapID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterTimerAttributeClusterRevisionID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -2168,7 +2131,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterOvenCavityOperationalStateAttributeOperationalErrorID MTR_PROVISIONALLY_AVAILABLE = 0x00000005, MTRAttributeIDTypeClusterOvenCavityOperationalStateAttributeGeneratedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterOvenCavityOperationalStateAttributeAcceptedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterOvenCavityOperationalStateAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterOvenCavityOperationalStateAttributeAttributeListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterOvenCavityOperationalStateAttributeFeatureMapID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterOvenCavityOperationalStateAttributeClusterRevisionID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -2180,7 +2142,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterOvenModeAttributeOnModeID MTR_PROVISIONALLY_AVAILABLE = 0x00000003, MTRAttributeIDTypeClusterOvenModeAttributeGeneratedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterOvenModeAttributeAcceptedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterOvenModeAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterOvenModeAttributeAttributeListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterOvenModeAttributeFeatureMapID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterOvenModeAttributeClusterRevisionID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -2190,7 +2151,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterLaundryDryerControlsAttributeSelectedDrynessLevelID MTR_PROVISIONALLY_AVAILABLE = 0x00000001, MTRAttributeIDTypeClusterLaundryDryerControlsAttributeGeneratedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterLaundryDryerControlsAttributeAcceptedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterLaundryDryerControlsAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterLaundryDryerControlsAttributeAttributeListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterLaundryDryerControlsAttributeFeatureMapID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterLaundryDryerControlsAttributeClusterRevisionID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -2239,7 +2199,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterModeSelectAttributeOnModeID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000005, MTRAttributeIDTypeClusterModeSelectAttributeGeneratedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterModeSelectAttributeAcceptedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterModeSelectAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterModeSelectAttributeAttributeListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterModeSelectAttributeFeatureMapID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterModeSelectAttributeClusterRevisionID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -2251,7 +2210,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterLaundryWasherModeAttributeOnModeID MTR_PROVISIONALLY_AVAILABLE = 0x00000003, MTRAttributeIDTypeClusterLaundryWasherModeAttributeGeneratedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterLaundryWasherModeAttributeAcceptedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterLaundryWasherModeAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterLaundryWasherModeAttributeAttributeListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterLaundryWasherModeAttributeFeatureMapID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterLaundryWasherModeAttributeClusterRevisionID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -2263,7 +2221,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterRefrigeratorAndTemperatureControlledCabinetModeAttributeOnModeID MTR_PROVISIONALLY_AVAILABLE = 0x00000003, MTRAttributeIDTypeClusterRefrigeratorAndTemperatureControlledCabinetModeAttributeGeneratedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterRefrigeratorAndTemperatureControlledCabinetModeAttributeAcceptedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterRefrigeratorAndTemperatureControlledCabinetModeAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterRefrigeratorAndTemperatureControlledCabinetModeAttributeAttributeListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterRefrigeratorAndTemperatureControlledCabinetModeAttributeFeatureMapID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterRefrigeratorAndTemperatureControlledCabinetModeAttributeClusterRevisionID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -2275,7 +2232,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterLaundryWasherControlsAttributeSupportedRinsesID MTR_PROVISIONALLY_AVAILABLE = 0x00000003, MTRAttributeIDTypeClusterLaundryWasherControlsAttributeGeneratedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterLaundryWasherControlsAttributeAcceptedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterLaundryWasherControlsAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterLaundryWasherControlsAttributeAttributeListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterLaundryWasherControlsAttributeFeatureMapID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterLaundryWasherControlsAttributeClusterRevisionID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -2285,7 +2241,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterRVCRunModeAttributeCurrentModeID MTR_AVAILABLE(ios(17.4), macos(14.4), watchos(10.4), tvos(17.4)) = 0x00000001, MTRAttributeIDTypeClusterRVCRunModeAttributeGeneratedCommandListID MTR_AVAILABLE(ios(17.4), macos(14.4), watchos(10.4), tvos(17.4)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterRVCRunModeAttributeAcceptedCommandListID MTR_AVAILABLE(ios(17.4), macos(14.4), watchos(10.4), tvos(17.4)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterRVCRunModeAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterRVCRunModeAttributeAttributeListID MTR_AVAILABLE(ios(17.4), macos(14.4), watchos(10.4), tvos(17.4)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterRVCRunModeAttributeFeatureMapID MTR_AVAILABLE(ios(17.4), macos(14.4), watchos(10.4), tvos(17.4)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterRVCRunModeAttributeClusterRevisionID MTR_AVAILABLE(ios(17.4), macos(14.4), watchos(10.4), tvos(17.4)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -2295,7 +2250,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterRVCCleanModeAttributeCurrentModeID MTR_AVAILABLE(ios(17.4), macos(14.4), watchos(10.4), tvos(17.4)) = 0x00000001, MTRAttributeIDTypeClusterRVCCleanModeAttributeGeneratedCommandListID MTR_AVAILABLE(ios(17.4), macos(14.4), watchos(10.4), tvos(17.4)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterRVCCleanModeAttributeAcceptedCommandListID MTR_AVAILABLE(ios(17.4), macos(14.4), watchos(10.4), tvos(17.4)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterRVCCleanModeAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterRVCCleanModeAttributeAttributeListID MTR_AVAILABLE(ios(17.4), macos(14.4), watchos(10.4), tvos(17.4)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterRVCCleanModeAttributeFeatureMapID MTR_AVAILABLE(ios(17.4), macos(14.4), watchos(10.4), tvos(17.4)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterRVCCleanModeAttributeClusterRevisionID MTR_AVAILABLE(ios(17.4), macos(14.4), watchos(10.4), tvos(17.4)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -2309,7 +2263,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterTemperatureControlAttributeSupportedTemperatureLevelsID MTR_PROVISIONALLY_AVAILABLE = 0x00000005, MTRAttributeIDTypeClusterTemperatureControlAttributeGeneratedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterTemperatureControlAttributeAcceptedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterTemperatureControlAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterTemperatureControlAttributeAttributeListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterTemperatureControlAttributeFeatureMapID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterTemperatureControlAttributeClusterRevisionID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -2320,7 +2273,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterRefrigeratorAlarmAttributeSupportedID MTR_PROVISIONALLY_AVAILABLE = 0x00000003, MTRAttributeIDTypeClusterRefrigeratorAlarmAttributeGeneratedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterRefrigeratorAlarmAttributeAcceptedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterRefrigeratorAlarmAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterRefrigeratorAlarmAttributeAttributeListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterRefrigeratorAlarmAttributeFeatureMapID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterRefrigeratorAlarmAttributeClusterRevisionID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -2332,7 +2284,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterDishwasherModeAttributeOnModeID MTR_PROVISIONALLY_AVAILABLE = 0x00000003, MTRAttributeIDTypeClusterDishwasherModeAttributeGeneratedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterDishwasherModeAttributeAcceptedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterDishwasherModeAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterDishwasherModeAttributeAttributeListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterDishwasherModeAttributeFeatureMapID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterDishwasherModeAttributeClusterRevisionID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -2341,7 +2292,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterAirQualityAttributeAirQualityID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = 0x00000000, MTRAttributeIDTypeClusterAirQualityAttributeGeneratedCommandListID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterAirQualityAttributeAcceptedCommandListID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterAirQualityAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterAirQualityAttributeAttributeListID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterAirQualityAttributeFeatureMapID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterAirQualityAttributeClusterRevisionID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -2362,7 +2312,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterSmokeCOAlarmAttributeExpiryDateID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = 0x0000000C, MTRAttributeIDTypeClusterSmokeCOAlarmAttributeGeneratedCommandListID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterSmokeCOAlarmAttributeAcceptedCommandListID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterSmokeCOAlarmAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterSmokeCOAlarmAttributeAttributeListID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterSmokeCOAlarmAttributeFeatureMapID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterSmokeCOAlarmAttributeClusterRevisionID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -2374,7 +2323,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterDishwasherAlarmAttributeSupportedID MTR_PROVISIONALLY_AVAILABLE = 0x00000003, MTRAttributeIDTypeClusterDishwasherAlarmAttributeGeneratedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterDishwasherAlarmAttributeAcceptedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterDishwasherAlarmAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterDishwasherAlarmAttributeAttributeListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterDishwasherAlarmAttributeFeatureMapID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterDishwasherAlarmAttributeClusterRevisionID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -2384,7 +2332,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterMicrowaveOvenModeAttributeCurrentModeID MTR_PROVISIONALLY_AVAILABLE = 0x00000001, MTRAttributeIDTypeClusterMicrowaveOvenModeAttributeGeneratedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterMicrowaveOvenModeAttributeAcceptedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterMicrowaveOvenModeAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterMicrowaveOvenModeAttributeAttributeListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterMicrowaveOvenModeAttributeFeatureMapID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterMicrowaveOvenModeAttributeClusterRevisionID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -2401,7 +2348,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterMicrowaveOvenControlAttributeWattRatingID MTR_PROVISIONALLY_AVAILABLE = 0x00000008, MTRAttributeIDTypeClusterMicrowaveOvenControlAttributeGeneratedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterMicrowaveOvenControlAttributeAcceptedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterMicrowaveOvenControlAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterMicrowaveOvenControlAttributeAttributeListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterMicrowaveOvenControlAttributeFeatureMapID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterMicrowaveOvenControlAttributeClusterRevisionID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -2415,7 +2361,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterOperationalStateAttributeOperationalErrorID MTR_AVAILABLE(ios(17.4), macos(14.4), watchos(10.4), tvos(17.4)) = 0x00000005, MTRAttributeIDTypeClusterOperationalStateAttributeGeneratedCommandListID MTR_AVAILABLE(ios(17.4), macos(14.4), watchos(10.4), tvos(17.4)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterOperationalStateAttributeAcceptedCommandListID MTR_AVAILABLE(ios(17.4), macos(14.4), watchos(10.4), tvos(17.4)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterOperationalStateAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterOperationalStateAttributeAttributeListID MTR_AVAILABLE(ios(17.4), macos(14.4), watchos(10.4), tvos(17.4)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterOperationalStateAttributeFeatureMapID MTR_AVAILABLE(ios(17.4), macos(14.4), watchos(10.4), tvos(17.4)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterOperationalStateAttributeClusterRevisionID MTR_AVAILABLE(ios(17.4), macos(14.4), watchos(10.4), tvos(17.4)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -2429,7 +2374,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterRVCOperationalStateAttributeOperationalErrorID MTR_AVAILABLE(ios(17.4), macos(14.4), watchos(10.4), tvos(17.4)) = 0x00000005, MTRAttributeIDTypeClusterRVCOperationalStateAttributeGeneratedCommandListID MTR_AVAILABLE(ios(17.4), macos(14.4), watchos(10.4), tvos(17.4)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterRVCOperationalStateAttributeAcceptedCommandListID MTR_AVAILABLE(ios(17.4), macos(14.4), watchos(10.4), tvos(17.4)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterRVCOperationalStateAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterRVCOperationalStateAttributeAttributeListID MTR_AVAILABLE(ios(17.4), macos(14.4), watchos(10.4), tvos(17.4)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterRVCOperationalStateAttributeFeatureMapID MTR_AVAILABLE(ios(17.4), macos(14.4), watchos(10.4), tvos(17.4)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterRVCOperationalStateAttributeClusterRevisionID MTR_AVAILABLE(ios(17.4), macos(14.4), watchos(10.4), tvos(17.4)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -2440,7 +2384,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterScenesManagementAttributeFabricSceneInfoID MTR_PROVISIONALLY_AVAILABLE = 0x00000002, MTRAttributeIDTypeClusterScenesManagementAttributeGeneratedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterScenesManagementAttributeAcceptedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterScenesManagementAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterScenesManagementAttributeAttributeListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterScenesManagementAttributeFeatureMapID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterScenesManagementAttributeClusterRevisionID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -2454,7 +2397,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterHEPAFilterMonitoringAttributeReplacementProductListID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = 0x00000005, MTRAttributeIDTypeClusterHEPAFilterMonitoringAttributeGeneratedCommandListID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterHEPAFilterMonitoringAttributeAcceptedCommandListID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterHEPAFilterMonitoringAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterHEPAFilterMonitoringAttributeAttributeListID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterHEPAFilterMonitoringAttributeFeatureMapID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterHEPAFilterMonitoringAttributeClusterRevisionID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -2468,7 +2410,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterActivatedCarbonFilterMonitoringAttributeReplacementProductListID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = 0x00000005, MTRAttributeIDTypeClusterActivatedCarbonFilterMonitoringAttributeGeneratedCommandListID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterActivatedCarbonFilterMonitoringAttributeAcceptedCommandListID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterActivatedCarbonFilterMonitoringAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterActivatedCarbonFilterMonitoringAttributeAttributeListID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterActivatedCarbonFilterMonitoringAttributeFeatureMapID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterActivatedCarbonFilterMonitoringAttributeClusterRevisionID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -2484,7 +2425,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterBooleanStateConfigurationAttributeSensorFaultID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = 0x00000007, MTRAttributeIDTypeClusterBooleanStateConfigurationAttributeGeneratedCommandListID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterBooleanStateConfigurationAttributeAcceptedCommandListID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterBooleanStateConfigurationAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterBooleanStateConfigurationAttributeAttributeListID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterBooleanStateConfigurationAttributeFeatureMapID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterBooleanStateConfigurationAttributeClusterRevisionID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -2503,7 +2443,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterValveConfigurationAndControlAttributeLevelStepID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = 0x0000000A, MTRAttributeIDTypeClusterValveConfigurationAndControlAttributeGeneratedCommandListID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterValveConfigurationAndControlAttributeAcceptedCommandListID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterValveConfigurationAndControlAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterValveConfigurationAndControlAttributeAttributeListID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterValveConfigurationAndControlAttributeFeatureMapID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterValveConfigurationAndControlAttributeClusterRevisionID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -2530,7 +2469,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterElectricalPowerMeasurementAttributeNeutralCurrentID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = 0x00000012, MTRAttributeIDTypeClusterElectricalPowerMeasurementAttributeGeneratedCommandListID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterElectricalPowerMeasurementAttributeAcceptedCommandListID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterElectricalPowerMeasurementAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterElectricalPowerMeasurementAttributeAttributeListID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterElectricalPowerMeasurementAttributeFeatureMapID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterElectricalPowerMeasurementAttributeClusterRevisionID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -2544,7 +2482,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterElectricalEnergyMeasurementAttributeCumulativeEnergyResetID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = 0x00000005, MTRAttributeIDTypeClusterElectricalEnergyMeasurementAttributeGeneratedCommandListID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterElectricalEnergyMeasurementAttributeAcceptedCommandListID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterElectricalEnergyMeasurementAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterElectricalEnergyMeasurementAttributeAttributeListID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterElectricalEnergyMeasurementAttributeFeatureMapID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterElectricalEnergyMeasurementAttributeClusterRevisionID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -2558,7 +2495,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterWaterHeaterManagementAttributeBoostStateID MTR_PROVISIONALLY_AVAILABLE = 0x00000005, MTRAttributeIDTypeClusterWaterHeaterManagementAttributeGeneratedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterWaterHeaterManagementAttributeAcceptedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterWaterHeaterManagementAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterWaterHeaterManagementAttributeAttributeListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterWaterHeaterManagementAttributeFeatureMapID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterWaterHeaterManagementAttributeClusterRevisionID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -2574,7 +2510,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterDemandResponseLoadControlAttributeDefaultRandomDurationID MTR_PROVISIONALLY_AVAILABLE = 0x00000007, MTRAttributeIDTypeClusterDemandResponseLoadControlAttributeGeneratedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterDemandResponseLoadControlAttributeAcceptedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterDemandResponseLoadControlAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterDemandResponseLoadControlAttributeAttributeListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterDemandResponseLoadControlAttributeFeatureMapID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterDemandResponseLoadControlAttributeClusterRevisionID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -2584,7 +2519,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterMessagesAttributeActiveMessageIDsID MTR_PROVISIONALLY_AVAILABLE = 0x00000001, MTRAttributeIDTypeClusterMessagesAttributeGeneratedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterMessagesAttributeAcceptedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterMessagesAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterMessagesAttributeAttributeListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterMessagesAttributeFeatureMapID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterMessagesAttributeClusterRevisionID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -2600,7 +2534,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterDeviceEnergyManagementAttributeOptOutStateID MTR_PROVISIONALLY_AVAILABLE = 0x00000007, MTRAttributeIDTypeClusterDeviceEnergyManagementAttributeGeneratedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterDeviceEnergyManagementAttributeAcceptedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterDeviceEnergyManagementAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterDeviceEnergyManagementAttributeAttributeListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterDeviceEnergyManagementAttributeFeatureMapID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterDeviceEnergyManagementAttributeClusterRevisionID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -2631,7 +2564,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterEnergyEVSEAttributeSessionEnergyDischargedID MTR_PROVISIONALLY_AVAILABLE = 0x00000043, MTRAttributeIDTypeClusterEnergyEVSEAttributeGeneratedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterEnergyEVSEAttributeAcceptedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterEnergyEVSEAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterEnergyEVSEAttributeAttributeListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterEnergyEVSEAttributeFeatureMapID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterEnergyEVSEAttributeClusterRevisionID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -2644,7 +2576,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterEnergyPreferenceAttributeCurrentLowPowerModeSensitivityID MTR_PROVISIONALLY_AVAILABLE = 0x00000004, MTRAttributeIDTypeClusterEnergyPreferenceAttributeGeneratedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterEnergyPreferenceAttributeAcceptedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterEnergyPreferenceAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterEnergyPreferenceAttributeAttributeListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterEnergyPreferenceAttributeFeatureMapID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterEnergyPreferenceAttributeClusterRevisionID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -2654,7 +2585,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterPowerTopologyAttributeActiveEndpointsID MTR_PROVISIONALLY_AVAILABLE = 0x00000001, MTRAttributeIDTypeClusterPowerTopologyAttributeGeneratedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterPowerTopologyAttributeAcceptedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterPowerTopologyAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterPowerTopologyAttributeAttributeListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterPowerTopologyAttributeFeatureMapID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterPowerTopologyAttributeClusterRevisionID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -2664,7 +2594,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterEnergyEVSEModeAttributeCurrentModeID MTR_PROVISIONALLY_AVAILABLE = 0x00000001, MTRAttributeIDTypeClusterEnergyEVSEModeAttributeGeneratedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterEnergyEVSEModeAttributeAcceptedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterEnergyEVSEModeAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterEnergyEVSEModeAttributeAttributeListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterEnergyEVSEModeAttributeFeatureMapID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterEnergyEVSEModeAttributeClusterRevisionID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -2674,7 +2603,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterWaterHeaterModeAttributeCurrentModeID MTR_PROVISIONALLY_AVAILABLE = 0x00000001, MTRAttributeIDTypeClusterWaterHeaterModeAttributeGeneratedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterWaterHeaterModeAttributeAcceptedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterWaterHeaterModeAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterWaterHeaterModeAttributeAttributeListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterWaterHeaterModeAttributeFeatureMapID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterWaterHeaterModeAttributeClusterRevisionID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -2684,7 +2612,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterDeviceEnergyManagementModeAttributeCurrentModeID MTR_PROVISIONALLY_AVAILABLE = 0x00000001, MTRAttributeIDTypeClusterDeviceEnergyManagementModeAttributeGeneratedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterDeviceEnergyManagementModeAttributeAcceptedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterDeviceEnergyManagementModeAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterDeviceEnergyManagementModeAttributeAttributeListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterDeviceEnergyManagementModeAttributeFeatureMapID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterDeviceEnergyManagementModeAttributeClusterRevisionID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -2862,7 +2789,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterDoorLockAttributeNumberOfAliroEndpointKeysSupportedID MTR_PROVISIONALLY_AVAILABLE = 0x00000088, MTRAttributeIDTypeClusterDoorLockAttributeGeneratedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterDoorLockAttributeAcceptedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterDoorLockAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterDoorLockAttributeAttributeListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterDoorLockAttributeFeatureMapID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterDoorLockAttributeClusterRevisionID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -2975,7 +2901,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterWindowCoveringAttributeSafetyStatusID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x0000001A, MTRAttributeIDTypeClusterWindowCoveringAttributeGeneratedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterWindowCoveringAttributeAcceptedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterWindowCoveringAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterWindowCoveringAttributeAttributeListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterWindowCoveringAttributeFeatureMapID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterWindowCoveringAttributeClusterRevisionID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -2989,7 +2914,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterServiceAreaAttributeProgressID MTR_PROVISIONALLY_AVAILABLE = 0x00000005, MTRAttributeIDTypeClusterServiceAreaAttributeGeneratedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterServiceAreaAttributeAcceptedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterServiceAreaAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterServiceAreaAttributeAttributeListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterServiceAreaAttributeFeatureMapID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterServiceAreaAttributeClusterRevisionID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -3106,7 +3030,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterPumpConfigurationAndControlAttributeControlModeID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000021, MTRAttributeIDTypeClusterPumpConfigurationAndControlAttributeGeneratedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterPumpConfigurationAndControlAttributeAcceptedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterPumpConfigurationAndControlAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterPumpConfigurationAndControlAttributeAttributeListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterPumpConfigurationAndControlAttributeFeatureMapID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterPumpConfigurationAndControlAttributeClusterRevisionID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -3338,7 +3261,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterThermostatAttributeSetpointHoldExpiryTimestampID MTR_PROVISIONALLY_AVAILABLE = 0x00000052, MTRAttributeIDTypeClusterThermostatAttributeGeneratedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterThermostatAttributeAcceptedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterThermostatAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterThermostatAttributeAttributeListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterThermostatAttributeFeatureMapID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterThermostatAttributeClusterRevisionID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -3408,7 +3330,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterFanControlAttributeAirflowDirectionID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = 0x0000000B, MTRAttributeIDTypeClusterFanControlAttributeGeneratedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterFanControlAttributeAcceptedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterFanControlAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterFanControlAttributeAttributeListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterFanControlAttributeFeatureMapID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterFanControlAttributeClusterRevisionID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -3445,7 +3366,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterThermostatUserInterfaceConfigurationAttributeScheduleProgrammingVisibilityID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000002, MTRAttributeIDTypeClusterThermostatUserInterfaceConfigurationAttributeGeneratedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterThermostatUserInterfaceConfigurationAttributeAcceptedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterThermostatUserInterfaceConfigurationAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterThermostatUserInterfaceConfigurationAttributeAttributeListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterThermostatUserInterfaceConfigurationAttributeFeatureMapID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterThermostatUserInterfaceConfigurationAttributeClusterRevisionID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -3678,7 +3598,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterColorControlAttributeStartUpColorTemperatureMiredsID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00004010, MTRAttributeIDTypeClusterColorControlAttributeGeneratedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterColorControlAttributeAcceptedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterColorControlAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterColorControlAttributeAttributeListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterColorControlAttributeFeatureMapID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterColorControlAttributeClusterRevisionID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -3759,7 +3678,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterBallastConfigurationAttributeLampBurnHoursTripPointID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000035, MTRAttributeIDTypeClusterBallastConfigurationAttributeGeneratedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterBallastConfigurationAttributeAcceptedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterBallastConfigurationAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterBallastConfigurationAttributeAttributeListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterBallastConfigurationAttributeFeatureMapID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterBallastConfigurationAttributeClusterRevisionID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -3804,7 +3722,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterIlluminanceMeasurementAttributeLightSensorTypeID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000004, MTRAttributeIDTypeClusterIlluminanceMeasurementAttributeGeneratedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterIlluminanceMeasurementAttributeAcceptedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterIlluminanceMeasurementAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterIlluminanceMeasurementAttributeAttributeListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterIlluminanceMeasurementAttributeFeatureMapID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterIlluminanceMeasurementAttributeClusterRevisionID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -3845,7 +3762,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterTemperatureMeasurementAttributeToleranceID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000003, MTRAttributeIDTypeClusterTemperatureMeasurementAttributeGeneratedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterTemperatureMeasurementAttributeAcceptedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterTemperatureMeasurementAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterTemperatureMeasurementAttributeAttributeListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterTemperatureMeasurementAttributeFeatureMapID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterTemperatureMeasurementAttributeClusterRevisionID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -3906,7 +3822,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterPressureMeasurementAttributeScaleID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000014, MTRAttributeIDTypeClusterPressureMeasurementAttributeGeneratedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterPressureMeasurementAttributeAcceptedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterPressureMeasurementAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterPressureMeasurementAttributeAttributeListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterPressureMeasurementAttributeFeatureMapID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterPressureMeasurementAttributeClusterRevisionID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -3947,7 +3862,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterFlowMeasurementAttributeToleranceID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000003, MTRAttributeIDTypeClusterFlowMeasurementAttributeGeneratedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterFlowMeasurementAttributeAcceptedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterFlowMeasurementAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterFlowMeasurementAttributeAttributeListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterFlowMeasurementAttributeFeatureMapID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterFlowMeasurementAttributeClusterRevisionID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -3988,7 +3902,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterRelativeHumidityMeasurementAttributeToleranceID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000003, MTRAttributeIDTypeClusterRelativeHumidityMeasurementAttributeGeneratedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterRelativeHumidityMeasurementAttributeAcceptedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterRelativeHumidityMeasurementAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterRelativeHumidityMeasurementAttributeAttributeListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterRelativeHumidityMeasurementAttributeFeatureMapID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterRelativeHumidityMeasurementAttributeClusterRevisionID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -4063,7 +3976,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterOccupancySensingAttributePhysicalContactUnoccupiedToOccupiedThresholdID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000032, MTRAttributeIDTypeClusterOccupancySensingAttributeGeneratedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterOccupancySensingAttributeAcceptedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterOccupancySensingAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterOccupancySensingAttributeAttributeListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterOccupancySensingAttributeFeatureMapID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterOccupancySensingAttributeClusterRevisionID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -4082,7 +3994,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterCarbonMonoxideConcentrationMeasurementAttributeLevelValueID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = 0x0000000A, MTRAttributeIDTypeClusterCarbonMonoxideConcentrationMeasurementAttributeGeneratedCommandListID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterCarbonMonoxideConcentrationMeasurementAttributeAcceptedCommandListID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterCarbonMonoxideConcentrationMeasurementAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterCarbonMonoxideConcentrationMeasurementAttributeAttributeListID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterCarbonMonoxideConcentrationMeasurementAttributeFeatureMapID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterCarbonMonoxideConcentrationMeasurementAttributeClusterRevisionID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -4101,7 +4012,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterCarbonDioxideConcentrationMeasurementAttributeLevelValueID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = 0x0000000A, MTRAttributeIDTypeClusterCarbonDioxideConcentrationMeasurementAttributeGeneratedCommandListID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterCarbonDioxideConcentrationMeasurementAttributeAcceptedCommandListID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterCarbonDioxideConcentrationMeasurementAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterCarbonDioxideConcentrationMeasurementAttributeAttributeListID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterCarbonDioxideConcentrationMeasurementAttributeFeatureMapID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterCarbonDioxideConcentrationMeasurementAttributeClusterRevisionID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -4120,7 +4030,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterNitrogenDioxideConcentrationMeasurementAttributeLevelValueID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = 0x0000000A, MTRAttributeIDTypeClusterNitrogenDioxideConcentrationMeasurementAttributeGeneratedCommandListID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterNitrogenDioxideConcentrationMeasurementAttributeAcceptedCommandListID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterNitrogenDioxideConcentrationMeasurementAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterNitrogenDioxideConcentrationMeasurementAttributeAttributeListID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterNitrogenDioxideConcentrationMeasurementAttributeFeatureMapID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterNitrogenDioxideConcentrationMeasurementAttributeClusterRevisionID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -4139,7 +4048,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterOzoneConcentrationMeasurementAttributeLevelValueID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = 0x0000000A, MTRAttributeIDTypeClusterOzoneConcentrationMeasurementAttributeGeneratedCommandListID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterOzoneConcentrationMeasurementAttributeAcceptedCommandListID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterOzoneConcentrationMeasurementAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterOzoneConcentrationMeasurementAttributeAttributeListID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterOzoneConcentrationMeasurementAttributeFeatureMapID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterOzoneConcentrationMeasurementAttributeClusterRevisionID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -4158,7 +4066,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterPM25ConcentrationMeasurementAttributeLevelValueID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = 0x0000000A, MTRAttributeIDTypeClusterPM25ConcentrationMeasurementAttributeGeneratedCommandListID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterPM25ConcentrationMeasurementAttributeAcceptedCommandListID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterPM25ConcentrationMeasurementAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterPM25ConcentrationMeasurementAttributeAttributeListID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterPM25ConcentrationMeasurementAttributeFeatureMapID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterPM25ConcentrationMeasurementAttributeClusterRevisionID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -4177,7 +4084,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterFormaldehydeConcentrationMeasurementAttributeLevelValueID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = 0x0000000A, MTRAttributeIDTypeClusterFormaldehydeConcentrationMeasurementAttributeGeneratedCommandListID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterFormaldehydeConcentrationMeasurementAttributeAcceptedCommandListID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterFormaldehydeConcentrationMeasurementAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterFormaldehydeConcentrationMeasurementAttributeAttributeListID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterFormaldehydeConcentrationMeasurementAttributeFeatureMapID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterFormaldehydeConcentrationMeasurementAttributeClusterRevisionID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -4196,7 +4102,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterPM1ConcentrationMeasurementAttributeLevelValueID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = 0x0000000A, MTRAttributeIDTypeClusterPM1ConcentrationMeasurementAttributeGeneratedCommandListID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterPM1ConcentrationMeasurementAttributeAcceptedCommandListID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterPM1ConcentrationMeasurementAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterPM1ConcentrationMeasurementAttributeAttributeListID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterPM1ConcentrationMeasurementAttributeFeatureMapID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterPM1ConcentrationMeasurementAttributeClusterRevisionID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -4215,7 +4120,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterPM10ConcentrationMeasurementAttributeLevelValueID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = 0x0000000A, MTRAttributeIDTypeClusterPM10ConcentrationMeasurementAttributeGeneratedCommandListID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterPM10ConcentrationMeasurementAttributeAcceptedCommandListID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterPM10ConcentrationMeasurementAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterPM10ConcentrationMeasurementAttributeAttributeListID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterPM10ConcentrationMeasurementAttributeFeatureMapID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterPM10ConcentrationMeasurementAttributeClusterRevisionID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -4234,7 +4138,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterTotalVolatileOrganicCompoundsConcentrationMeasurementAttributeLevelValueID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = 0x0000000A, MTRAttributeIDTypeClusterTotalVolatileOrganicCompoundsConcentrationMeasurementAttributeGeneratedCommandListID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterTotalVolatileOrganicCompoundsConcentrationMeasurementAttributeAcceptedCommandListID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterTotalVolatileOrganicCompoundsConcentrationMeasurementAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterTotalVolatileOrganicCompoundsConcentrationMeasurementAttributeAttributeListID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterTotalVolatileOrganicCompoundsConcentrationMeasurementAttributeFeatureMapID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterTotalVolatileOrganicCompoundsConcentrationMeasurementAttributeClusterRevisionID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -4253,7 +4156,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterRadonConcentrationMeasurementAttributeLevelValueID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = 0x0000000A, MTRAttributeIDTypeClusterRadonConcentrationMeasurementAttributeGeneratedCommandListID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterRadonConcentrationMeasurementAttributeAcceptedCommandListID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterRadonConcentrationMeasurementAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterRadonConcentrationMeasurementAttributeAttributeListID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterRadonConcentrationMeasurementAttributeFeatureMapID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterRadonConcentrationMeasurementAttributeClusterRevisionID MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -4263,7 +4165,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterWiFiNetworkManagementAttributePassphraseSurrogateID MTR_PROVISIONALLY_AVAILABLE = 0x00000001, MTRAttributeIDTypeClusterWiFiNetworkManagementAttributeGeneratedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterWiFiNetworkManagementAttributeAcceptedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterWiFiNetworkManagementAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterWiFiNetworkManagementAttributeAttributeListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterWiFiNetworkManagementAttributeFeatureMapID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterWiFiNetworkManagementAttributeClusterRevisionID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -4277,7 +4178,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterThreadBorderRouterManagementAttributePendingDatasetTimestampID MTR_PROVISIONALLY_AVAILABLE = 0x00000005, MTRAttributeIDTypeClusterThreadBorderRouterManagementAttributeGeneratedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterThreadBorderRouterManagementAttributeAcceptedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterThreadBorderRouterManagementAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterThreadBorderRouterManagementAttributeAttributeListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterThreadBorderRouterManagementAttributeFeatureMapID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterThreadBorderRouterManagementAttributeClusterRevisionID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -4288,7 +4188,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterThreadNetworkDirectoryAttributeThreadNetworkTableSizeID MTR_PROVISIONALLY_AVAILABLE = 0x00000002, MTRAttributeIDTypeClusterThreadNetworkDirectoryAttributeGeneratedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterThreadNetworkDirectoryAttributeAcceptedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterThreadNetworkDirectoryAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterThreadNetworkDirectoryAttributeAttributeListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterThreadNetworkDirectoryAttributeFeatureMapID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterThreadNetworkDirectoryAttributeClusterRevisionID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -4318,7 +4217,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterWakeOnLANAttributeLinkLocalAddressID MTR_PROVISIONALLY_AVAILABLE = 0x00000001, MTRAttributeIDTypeClusterWakeOnLANAttributeGeneratedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterWakeOnLANAttributeAcceptedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterWakeOnLANAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterWakeOnLANAttributeAttributeListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterWakeOnLANAttributeFeatureMapID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterWakeOnLANAttributeClusterRevisionID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -4355,7 +4253,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterChannelAttributeCurrentChannelID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000002, MTRAttributeIDTypeClusterChannelAttributeGeneratedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterChannelAttributeAcceptedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterChannelAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterChannelAttributeAttributeListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterChannelAttributeFeatureMapID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterChannelAttributeClusterRevisionID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -4388,7 +4285,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterTargetNavigatorAttributeCurrentTargetID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000001, MTRAttributeIDTypeClusterTargetNavigatorAttributeGeneratedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterTargetNavigatorAttributeAcceptedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterTargetNavigatorAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterTargetNavigatorAttributeAttributeListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterTargetNavigatorAttributeFeatureMapID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterTargetNavigatorAttributeClusterRevisionID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -4445,7 +4341,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterMediaPlaybackAttributeAvailableTextTracksID MTR_PROVISIONALLY_AVAILABLE = 0x0000000A, MTRAttributeIDTypeClusterMediaPlaybackAttributeGeneratedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterMediaPlaybackAttributeAcceptedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterMediaPlaybackAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterMediaPlaybackAttributeAttributeListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterMediaPlaybackAttributeFeatureMapID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterMediaPlaybackAttributeClusterRevisionID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -4478,7 +4373,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterMediaInputAttributeCurrentInputID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000001, MTRAttributeIDTypeClusterMediaInputAttributeGeneratedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterMediaInputAttributeAcceptedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterMediaInputAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterMediaInputAttributeAttributeListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterMediaInputAttributeFeatureMapID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterMediaInputAttributeClusterRevisionID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -4503,7 +4397,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { // Cluster LowPower attributes MTRAttributeIDTypeClusterLowPowerAttributeGeneratedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterLowPowerAttributeAcceptedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterLowPowerAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterLowPowerAttributeAttributeListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterLowPowerAttributeFeatureMapID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterLowPowerAttributeClusterRevisionID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -4528,7 +4421,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { // Cluster KeypadInput attributes MTRAttributeIDTypeClusterKeypadInputAttributeGeneratedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterKeypadInputAttributeAcceptedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterKeypadInputAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterKeypadInputAttributeAttributeListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterKeypadInputAttributeFeatureMapID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterKeypadInputAttributeClusterRevisionID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -4561,7 +4453,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterContentLauncherAttributeSupportedStreamingProtocolsID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000001, MTRAttributeIDTypeClusterContentLauncherAttributeGeneratedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterContentLauncherAttributeAcceptedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterContentLauncherAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterContentLauncherAttributeAttributeListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterContentLauncherAttributeFeatureMapID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterContentLauncherAttributeClusterRevisionID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -4594,7 +4485,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterAudioOutputAttributeCurrentOutputID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000001, MTRAttributeIDTypeClusterAudioOutputAttributeGeneratedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterAudioOutputAttributeAcceptedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterAudioOutputAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterAudioOutputAttributeAttributeListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterAudioOutputAttributeFeatureMapID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterAudioOutputAttributeClusterRevisionID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -4627,7 +4517,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterApplicationLauncherAttributeCurrentAppID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000001, MTRAttributeIDTypeClusterApplicationLauncherAttributeGeneratedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterApplicationLauncherAttributeAcceptedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterApplicationLauncherAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterApplicationLauncherAttributeAttributeListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterApplicationLauncherAttributeFeatureMapID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterApplicationLauncherAttributeClusterRevisionID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -4684,7 +4573,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterApplicationBasicAttributeAllowedVendorListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x00000007, MTRAttributeIDTypeClusterApplicationBasicAttributeGeneratedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterApplicationBasicAttributeAcceptedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterApplicationBasicAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterApplicationBasicAttributeAttributeListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterApplicationBasicAttributeFeatureMapID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterApplicationBasicAttributeClusterRevisionID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -4709,7 +4597,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { // Cluster AccountLogin attributes MTRAttributeIDTypeClusterAccountLoginAttributeGeneratedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterAccountLoginAttributeAcceptedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterAccountLoginAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterAccountLoginAttributeAttributeListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterAccountLoginAttributeFeatureMapID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterAccountLoginAttributeClusterRevisionID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -4725,7 +4612,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterContentControlAttributeBlockUnratedID MTR_PROVISIONALLY_AVAILABLE = 0x00000007, MTRAttributeIDTypeClusterContentControlAttributeGeneratedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterContentControlAttributeAcceptedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterContentControlAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterContentControlAttributeAttributeListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterContentControlAttributeFeatureMapID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterContentControlAttributeClusterRevisionID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -4733,7 +4619,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { // Cluster ContentAppObserver attributes MTRAttributeIDTypeClusterContentAppObserverAttributeGeneratedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterContentAppObserverAttributeAcceptedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterContentAppObserverAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterContentAppObserverAttributeAttributeListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterContentAppObserverAttributeFeatureMapID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterContentAppObserverAttributeClusterRevisionID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -4745,7 +4630,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterZoneManagementAttributeSensitivityID MTR_PROVISIONALLY_AVAILABLE = 0x00000003, MTRAttributeIDTypeClusterZoneManagementAttributeGeneratedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterZoneManagementAttributeAcceptedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterZoneManagementAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterZoneManagementAttributeAttributeListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterZoneManagementAttributeFeatureMapID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterZoneManagementAttributeClusterRevisionID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -4800,7 +4684,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeDepthSensorStatusID MTR_PROVISIONALLY_AVAILABLE = 0x0000002E, MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeGeneratedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeAcceptedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeAttributeListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeFeatureMapID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeClusterRevisionID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -4809,7 +4692,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterWebRTCTransportProviderAttributeCurrentSessionsID MTR_PROVISIONALLY_AVAILABLE = 0x00000000, MTRAttributeIDTypeClusterWebRTCTransportProviderAttributeGeneratedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterWebRTCTransportProviderAttributeAcceptedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterWebRTCTransportProviderAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterWebRTCTransportProviderAttributeAttributeListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterWebRTCTransportProviderAttributeFeatureMapID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterWebRTCTransportProviderAttributeClusterRevisionID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -4818,7 +4700,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterWebRTCTransportRequestorAttributeCurrentSessionsID MTR_PROVISIONALLY_AVAILABLE = 0x00000000, MTRAttributeIDTypeClusterWebRTCTransportRequestorAttributeGeneratedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterWebRTCTransportRequestorAttributeAcceptedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterWebRTCTransportRequestorAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterWebRTCTransportRequestorAttributeAttributeListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterWebRTCTransportRequestorAttributeFeatureMapID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterWebRTCTransportRequestorAttributeClusterRevisionID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -4829,7 +4710,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterChimeAttributeEnabledID MTR_PROVISIONALLY_AVAILABLE = 0x00000002, MTRAttributeIDTypeClusterChimeAttributeGeneratedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterChimeAttributeAcceptedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterChimeAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterChimeAttributeAttributeListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterChimeAttributeFeatureMapID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterChimeAttributeClusterRevisionID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -4839,7 +4719,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterEcosystemInformationAttributeLocationDirectoryID MTR_PROVISIONALLY_AVAILABLE = 0x00000001, MTRAttributeIDTypeClusterEcosystemInformationAttributeGeneratedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterEcosystemInformationAttributeAcceptedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterEcosystemInformationAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterEcosystemInformationAttributeAttributeListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterEcosystemInformationAttributeFeatureMapID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterEcosystemInformationAttributeClusterRevisionID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -4848,7 +4727,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterCommissionerControlAttributeSupportedDeviceCategoriesID MTR_PROVISIONALLY_AVAILABLE = 0x00000000, MTRAttributeIDTypeClusterCommissionerControlAttributeGeneratedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterCommissionerControlAttributeAcceptedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterCommissionerControlAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterCommissionerControlAttributeAttributeListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterCommissionerControlAttributeFeatureMapID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterCommissionerControlAttributeClusterRevisionID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -5207,7 +5085,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterUnitTestingAttributeNullableGlobalStructID MTR_PROVISIONALLY_AVAILABLE = 0x00004034, MTRAttributeIDTypeClusterUnitTestingAttributeGeneratedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterUnitTestingAttributeAcceptedCommandListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterUnitTestingAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterUnitTestingAttributeAttributeListID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterUnitTestingAttributeFeatureMapID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterUnitTestingAttributeClusterRevisionID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, @@ -5217,7 +5094,6 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterSampleMEIAttributeFlipFlopID MTR_PROVISIONALLY_AVAILABLE = 0x00000000, MTRAttributeIDTypeClusterSampleMEIAttributeGeneratedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, MTRAttributeIDTypeClusterSampleMEIAttributeAcceptedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, - MTRAttributeIDTypeClusterSampleMEIAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, MTRAttributeIDTypeClusterSampleMEIAttributeAttributeListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAttributeListID, MTRAttributeIDTypeClusterSampleMEIAttributeFeatureMapID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterSampleMEIAttributeClusterRevisionID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm b/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm index 1d7ffd3925f51f..08373371a7c5e2 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm @@ -434,10 +434,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterIdentifyAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterIdentifyAttributeAttributeListID: result = @"AttributeList"; break; @@ -473,10 +469,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterGroupsAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterGroupsAttributeAttributeListID: result = @"AttributeList"; break; @@ -528,10 +520,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterOnOffAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterOnOffAttributeAttributeListID: result = @"AttributeList"; break; @@ -619,10 +607,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterLevelControlAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterLevelControlAttributeAttributeListID: result = @"AttributeList"; break; @@ -654,10 +638,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterPulseWidthModulationAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterPulseWidthModulationAttributeAttributeListID: result = @"AttributeList"; break; @@ -709,10 +689,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterDescriptorAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterDescriptorAttributeAttributeListID: result = @"AttributeList"; break; @@ -748,10 +724,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterBindingAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterBindingAttributeAttributeListID: result = @"AttributeList"; break; @@ -811,10 +783,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterAccessControlAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterAccessControlAttributeAttributeListID: result = @"AttributeList"; break; @@ -858,10 +826,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterActionsAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterActionsAttributeAttributeListID: result = @"AttributeList"; break; @@ -985,10 +949,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterBasicInformationAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterBasicInformationAttributeAttributeListID: result = @"AttributeList"; break; @@ -1020,10 +980,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterOTASoftwareUpdateProviderAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterOTASoftwareUpdateProviderAttributeAttributeListID: result = @"AttributeList"; break; @@ -1071,10 +1027,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterOTASoftwareUpdateRequestorAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterOTASoftwareUpdateRequestorAttributeAttributeListID: result = @"AttributeList"; break; @@ -1114,10 +1066,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterLocalizationConfigurationAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterLocalizationConfigurationAttributeAttributeListID: result = @"AttributeList"; break; @@ -1161,10 +1109,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterTimeFormatLocalizationAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterTimeFormatLocalizationAttributeAttributeListID: result = @"AttributeList"; break; @@ -1200,10 +1144,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterUnitLocalizationAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterUnitLocalizationAttributeAttributeListID: result = @"AttributeList"; break; @@ -1239,10 +1179,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterPowerSourceConfigurationAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterPowerSourceConfigurationAttributeAttributeListID: result = @"AttributeList"; break; @@ -1402,10 +1338,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterPowerSourceAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterPowerSourceAttributeAttributeListID: result = @"AttributeList"; break; @@ -1477,10 +1409,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterGeneralCommissioningAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterGeneralCommissioningAttributeAttributeListID: result = @"AttributeList"; break; @@ -1556,10 +1484,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterNetworkCommissioningAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterNetworkCommissioningAttributeAttributeListID: result = @"AttributeList"; break; @@ -1591,10 +1515,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterDiagnosticLogsAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterDiagnosticLogsAttributeAttributeListID: result = @"AttributeList"; break; @@ -1662,10 +1582,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterGeneralDiagnosticsAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterGeneralDiagnosticsAttributeAttributeListID: result = @"AttributeList"; break; @@ -1713,10 +1629,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterSoftwareDiagnosticsAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterSoftwareDiagnosticsAttributeAttributeListID: result = @"AttributeList"; break; @@ -2000,10 +1912,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterThreadNetworkDiagnosticsAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterThreadNetworkDiagnosticsAttributeAttributeListID: result = @"AttributeList"; break; @@ -2087,10 +1995,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterWiFiNetworkDiagnosticsAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterWiFiNetworkDiagnosticsAttributeAttributeListID: result = @"AttributeList"; break; @@ -2158,10 +2062,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterEthernetNetworkDiagnosticsAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterEthernetNetworkDiagnosticsAttributeAttributeListID: result = @"AttributeList"; break; @@ -2245,10 +2145,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterTimeSynchronizationAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterTimeSynchronizationAttributeAttributeListID: result = @"AttributeList"; break; @@ -2348,10 +2244,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterBridgedDeviceBasicInformationAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterBridgedDeviceBasicInformationAttributeAttributeListID: result = @"AttributeList"; break; @@ -2395,10 +2287,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterSwitchAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterSwitchAttributeAttributeListID: result = @"AttributeList"; break; @@ -2442,10 +2330,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterAdministratorCommissioningAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterAdministratorCommissioningAttributeAttributeListID: result = @"AttributeList"; break; @@ -2501,10 +2385,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterOperationalCredentialsAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterOperationalCredentialsAttributeAttributeListID: result = @"AttributeList"; break; @@ -2552,10 +2432,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterGroupKeyManagementAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterGroupKeyManagementAttributeAttributeListID: result = @"AttributeList"; break; @@ -2591,10 +2467,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterFixedLabelAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterFixedLabelAttributeAttributeListID: result = @"AttributeList"; break; @@ -2630,10 +2502,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterUserLabelAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterUserLabelAttributeAttributeListID: result = @"AttributeList"; break; @@ -2669,10 +2537,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterBooleanStateAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterBooleanStateAttributeAttributeListID: result = @"AttributeList"; break; @@ -2744,10 +2608,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterICDManagementAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterICDManagementAttributeAttributeListID: result = @"AttributeList"; break; @@ -2791,10 +2651,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterTimerAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterTimerAttributeAttributeListID: result = @"AttributeList"; break; @@ -2850,10 +2706,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterOvenCavityOperationalStateAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterOvenCavityOperationalStateAttributeAttributeListID: result = @"AttributeList"; break; @@ -2901,10 +2753,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterOvenModeAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterOvenModeAttributeAttributeListID: result = @"AttributeList"; break; @@ -2944,10 +2792,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterLaundryDryerControlsAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterLaundryDryerControlsAttributeAttributeListID: result = @"AttributeList"; break; @@ -3003,10 +2847,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterModeSelectAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterModeSelectAttributeAttributeListID: result = @"AttributeList"; break; @@ -3054,10 +2894,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterLaundryWasherModeAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterLaundryWasherModeAttributeAttributeListID: result = @"AttributeList"; break; @@ -3105,10 +2941,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterRefrigeratorAndTemperatureControlledCabinetModeAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterRefrigeratorAndTemperatureControlledCabinetModeAttributeAttributeListID: result = @"AttributeList"; break; @@ -3156,10 +2988,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterLaundryWasherControlsAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterLaundryWasherControlsAttributeAttributeListID: result = @"AttributeList"; break; @@ -3199,10 +3027,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterRVCRunModeAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterRVCRunModeAttributeAttributeListID: result = @"AttributeList"; break; @@ -3242,10 +3066,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterRVCCleanModeAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterRVCCleanModeAttributeAttributeListID: result = @"AttributeList"; break; @@ -3301,10 +3121,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterTemperatureControlAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterTemperatureControlAttributeAttributeListID: result = @"AttributeList"; break; @@ -3348,10 +3164,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterRefrigeratorAlarmAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterRefrigeratorAlarmAttributeAttributeListID: result = @"AttributeList"; break; @@ -3399,10 +3211,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterDishwasherModeAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterDishwasherModeAttributeAttributeListID: result = @"AttributeList"; break; @@ -3438,10 +3246,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterAirQualityAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterAirQualityAttributeAttributeListID: result = @"AttributeList"; break; @@ -3525,10 +3329,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterSmokeCOAlarmAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterSmokeCOAlarmAttributeAttributeListID: result = @"AttributeList"; break; @@ -3576,10 +3376,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterDishwasherAlarmAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterDishwasherAlarmAttributeAttributeListID: result = @"AttributeList"; break; @@ -3619,10 +3415,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterMicrowaveOvenModeAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterMicrowaveOvenModeAttributeAttributeListID: result = @"AttributeList"; break; @@ -3690,10 +3482,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterMicrowaveOvenControlAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterMicrowaveOvenControlAttributeAttributeListID: result = @"AttributeList"; break; @@ -3749,10 +3537,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterOperationalStateAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterOperationalStateAttributeAttributeListID: result = @"AttributeList"; break; @@ -3808,10 +3592,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterRVCOperationalStateAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterRVCOperationalStateAttributeAttributeListID: result = @"AttributeList"; break; @@ -3855,10 +3635,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterScenesManagementAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterScenesManagementAttributeAttributeListID: result = @"AttributeList"; break; @@ -3914,10 +3690,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterHEPAFilterMonitoringAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterHEPAFilterMonitoringAttributeAttributeListID: result = @"AttributeList"; break; @@ -3973,10 +3745,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterActivatedCarbonFilterMonitoringAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterActivatedCarbonFilterMonitoringAttributeAttributeListID: result = @"AttributeList"; break; @@ -4040,10 +3808,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterBooleanStateConfigurationAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterBooleanStateConfigurationAttributeAttributeListID: result = @"AttributeList"; break; @@ -4119,10 +3883,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterValveConfigurationAndControlAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterValveConfigurationAndControlAttributeAttributeListID: result = @"AttributeList"; break; @@ -4230,10 +3990,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterElectricalPowerMeasurementAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterElectricalPowerMeasurementAttributeAttributeListID: result = @"AttributeList"; break; @@ -4289,10 +4045,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterElectricalEnergyMeasurementAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterElectricalEnergyMeasurementAttributeAttributeListID: result = @"AttributeList"; break; @@ -4348,10 +4100,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterWaterHeaterManagementAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterWaterHeaterManagementAttributeAttributeListID: result = @"AttributeList"; break; @@ -4415,10 +4163,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterDemandResponseLoadControlAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterDemandResponseLoadControlAttributeAttributeListID: result = @"AttributeList"; break; @@ -4458,10 +4202,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterMessagesAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterMessagesAttributeAttributeListID: result = @"AttributeList"; break; @@ -4525,10 +4265,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterDeviceEnergyManagementAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterDeviceEnergyManagementAttributeAttributeListID: result = @"AttributeList"; break; @@ -4652,10 +4388,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterEnergyEVSEAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterEnergyEVSEAttributeAttributeListID: result = @"AttributeList"; break; @@ -4707,10 +4439,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterEnergyPreferenceAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterEnergyPreferenceAttributeAttributeListID: result = @"AttributeList"; break; @@ -4750,10 +4478,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterPowerTopologyAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterPowerTopologyAttributeAttributeListID: result = @"AttributeList"; break; @@ -4793,10 +4517,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterEnergyEVSEModeAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterEnergyEVSEModeAttributeAttributeListID: result = @"AttributeList"; break; @@ -4836,10 +4556,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterWaterHeaterModeAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterWaterHeaterModeAttributeAttributeListID: result = @"AttributeList"; break; @@ -4879,10 +4595,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterDeviceEnergyManagementModeAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterDeviceEnergyManagementModeAttributeAttributeListID: result = @"AttributeList"; break; @@ -5094,10 +4806,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterDoorLockAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterDoorLockAttributeAttributeListID: result = @"AttributeList"; break; @@ -5217,10 +4925,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterWindowCoveringAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterWindowCoveringAttributeAttributeListID: result = @"AttributeList"; break; @@ -5276,10 +4980,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterServiceAreaAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterServiceAreaAttributeAttributeListID: result = @"AttributeList"; break; @@ -5403,10 +5103,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterPumpConfigurationAndControlAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterPumpConfigurationAndControlAttributeAttributeListID: result = @"AttributeList"; break; @@ -5678,10 +5374,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterThermostatAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterThermostatAttributeAttributeListID: result = @"AttributeList"; break; @@ -5761,10 +5453,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterFanControlAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterFanControlAttributeAttributeListID: result = @"AttributeList"; break; @@ -5808,10 +5496,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterThermostatUserInterfaceConfigurationAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterThermostatUserInterfaceConfigurationAttributeAttributeListID: result = @"AttributeList"; break; @@ -6051,10 +5735,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterColorControlAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterColorControlAttributeAttributeListID: result = @"AttributeList"; break; @@ -6142,10 +5822,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterBallastConfigurationAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterBallastConfigurationAttributeAttributeListID: result = @"AttributeList"; break; @@ -6197,10 +5873,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterIlluminanceMeasurementAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterIlluminanceMeasurementAttributeAttributeListID: result = @"AttributeList"; break; @@ -6248,10 +5920,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterTemperatureMeasurementAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterTemperatureMeasurementAttributeAttributeListID: result = @"AttributeList"; break; @@ -6319,10 +5987,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterPressureMeasurementAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterPressureMeasurementAttributeAttributeListID: result = @"AttributeList"; break; @@ -6370,10 +6034,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterFlowMeasurementAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterFlowMeasurementAttributeAttributeListID: result = @"AttributeList"; break; @@ -6421,10 +6081,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterRelativeHumidityMeasurementAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterRelativeHumidityMeasurementAttributeAttributeListID: result = @"AttributeList"; break; @@ -6512,10 +6168,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterOccupancySensingAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterOccupancySensingAttributeAttributeListID: result = @"AttributeList"; break; @@ -6591,10 +6243,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterCarbonMonoxideConcentrationMeasurementAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterCarbonMonoxideConcentrationMeasurementAttributeAttributeListID: result = @"AttributeList"; break; @@ -6670,10 +6318,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterCarbonDioxideConcentrationMeasurementAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterCarbonDioxideConcentrationMeasurementAttributeAttributeListID: result = @"AttributeList"; break; @@ -6749,10 +6393,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterNitrogenDioxideConcentrationMeasurementAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterNitrogenDioxideConcentrationMeasurementAttributeAttributeListID: result = @"AttributeList"; break; @@ -6828,10 +6468,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterOzoneConcentrationMeasurementAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterOzoneConcentrationMeasurementAttributeAttributeListID: result = @"AttributeList"; break; @@ -6907,10 +6543,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterPM25ConcentrationMeasurementAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterPM25ConcentrationMeasurementAttributeAttributeListID: result = @"AttributeList"; break; @@ -6986,10 +6618,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterFormaldehydeConcentrationMeasurementAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterFormaldehydeConcentrationMeasurementAttributeAttributeListID: result = @"AttributeList"; break; @@ -7065,10 +6693,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterPM1ConcentrationMeasurementAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterPM1ConcentrationMeasurementAttributeAttributeListID: result = @"AttributeList"; break; @@ -7144,10 +6768,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterPM10ConcentrationMeasurementAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterPM10ConcentrationMeasurementAttributeAttributeListID: result = @"AttributeList"; break; @@ -7223,10 +6843,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterTotalVolatileOrganicCompoundsConcentrationMeasurementAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterTotalVolatileOrganicCompoundsConcentrationMeasurementAttributeAttributeListID: result = @"AttributeList"; break; @@ -7302,10 +6918,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterRadonConcentrationMeasurementAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterRadonConcentrationMeasurementAttributeAttributeListID: result = @"AttributeList"; break; @@ -7345,10 +6957,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterWiFiNetworkManagementAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterWiFiNetworkManagementAttributeAttributeListID: result = @"AttributeList"; break; @@ -7404,10 +7012,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterThreadBorderRouterManagementAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterThreadBorderRouterManagementAttributeAttributeListID: result = @"AttributeList"; break; @@ -7451,10 +7055,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterThreadNetworkDirectoryAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterThreadNetworkDirectoryAttributeAttributeListID: result = @"AttributeList"; break; @@ -7494,10 +7094,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterWakeOnLANAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterWakeOnLANAttributeAttributeListID: result = @"AttributeList"; break; @@ -7541,10 +7137,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterChannelAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterChannelAttributeAttributeListID: result = @"AttributeList"; break; @@ -7584,10 +7176,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterTargetNavigatorAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterTargetNavigatorAttributeAttributeListID: result = @"AttributeList"; break; @@ -7663,10 +7251,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterMediaPlaybackAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterMediaPlaybackAttributeAttributeListID: result = @"AttributeList"; break; @@ -7706,10 +7290,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterMediaInputAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterMediaInputAttributeAttributeListID: result = @"AttributeList"; break; @@ -7741,10 +7321,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterLowPowerAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterLowPowerAttributeAttributeListID: result = @"AttributeList"; break; @@ -7776,10 +7352,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterKeypadInputAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterKeypadInputAttributeAttributeListID: result = @"AttributeList"; break; @@ -7819,10 +7391,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterContentLauncherAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterContentLauncherAttributeAttributeListID: result = @"AttributeList"; break; @@ -7862,10 +7430,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterAudioOutputAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterAudioOutputAttributeAttributeListID: result = @"AttributeList"; break; @@ -7905,10 +7469,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterApplicationLauncherAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterApplicationLauncherAttributeAttributeListID: result = @"AttributeList"; break; @@ -7972,10 +7532,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterApplicationBasicAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterApplicationBasicAttributeAttributeListID: result = @"AttributeList"; break; @@ -8007,10 +7563,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterAccountLoginAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterAccountLoginAttributeAttributeListID: result = @"AttributeList"; break; @@ -8074,10 +7626,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterContentControlAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterContentControlAttributeAttributeListID: result = @"AttributeList"; break; @@ -8109,10 +7657,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterContentAppObserverAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterContentAppObserverAttributeAttributeListID: result = @"AttributeList"; break; @@ -8160,10 +7704,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterZoneManagementAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterZoneManagementAttributeAttributeListID: result = @"AttributeList"; break; @@ -8383,10 +7923,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeAttributeListID: result = @"AttributeList"; break; @@ -8422,10 +7958,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterWebRTCTransportProviderAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterWebRTCTransportProviderAttributeAttributeListID: result = @"AttributeList"; break; @@ -8461,10 +7993,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterWebRTCTransportRequestorAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterWebRTCTransportRequestorAttributeAttributeListID: result = @"AttributeList"; break; @@ -8508,10 +8036,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterChimeAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterChimeAttributeAttributeListID: result = @"AttributeList"; break; @@ -8551,10 +8075,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterEcosystemInformationAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterEcosystemInformationAttributeAttributeListID: result = @"AttributeList"; break; @@ -8590,10 +8110,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterCommissionerControlAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterCommissionerControlAttributeAttributeListID: result = @"AttributeList"; break; @@ -8977,10 +8493,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterUnitTestingAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterUnitTestingAttributeAttributeListID: result = @"AttributeList"; break; @@ -9020,10 +8532,6 @@ result = @"AcceptedCommandList"; break; - case MTRAttributeIDTypeClusterSampleMEIAttributeEventListID: - result = @"EventList"; - break; - case MTRAttributeIDTypeClusterSampleMEIAttributeAttributeListID: result = @"AttributeList"; break; diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h index 6ee9d3d3943db0..d9ca769e250aaa 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h @@ -43,8 +43,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); @@ -90,8 +88,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); @@ -157,8 +153,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); @@ -245,8 +239,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); @@ -281,8 +273,6 @@ MTR_PROVISIONALLY_AVAILABLE - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; @@ -327,8 +317,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); @@ -367,8 +355,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); @@ -426,8 +412,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); @@ -481,8 +465,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); @@ -571,8 +553,6 @@ MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); @@ -611,8 +591,6 @@ MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); @@ -659,8 +637,6 @@ MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); @@ -704,8 +680,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); @@ -753,8 +727,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); @@ -796,8 +768,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); @@ -834,8 +804,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); @@ -934,8 +902,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); @@ -999,8 +965,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); @@ -1069,8 +1033,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); @@ -1107,8 +1069,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); @@ -1167,8 +1127,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); @@ -1215,8 +1173,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); @@ -1381,8 +1337,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); @@ -1447,8 +1401,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); @@ -1505,8 +1457,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); @@ -1573,8 +1523,6 @@ MTR_PROVISIONALLY_AVAILABLE - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; @@ -1650,8 +1598,6 @@ MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); @@ -1694,8 +1640,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); @@ -1742,8 +1686,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); @@ -1799,8 +1741,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); @@ -1852,8 +1792,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); @@ -1891,8 +1829,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); @@ -1931,8 +1867,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); @@ -1969,8 +1903,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); @@ -2029,8 +1961,6 @@ MTR_PROVISIONALLY_AVAILABLE - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; @@ -2078,8 +2008,6 @@ MTR_PROVISIONALLY_AVAILABLE - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; @@ -2139,8 +2067,6 @@ MTR_PROVISIONALLY_AVAILABLE - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; @@ -2189,8 +2115,6 @@ MTR_PROVISIONALLY_AVAILABLE - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; @@ -2232,8 +2156,6 @@ MTR_PROVISIONALLY_AVAILABLE - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; @@ -2286,8 +2208,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); @@ -2336,8 +2256,6 @@ MTR_PROVISIONALLY_AVAILABLE - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; @@ -2386,8 +2304,6 @@ MTR_PROVISIONALLY_AVAILABLE - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; @@ -2434,8 +2350,6 @@ MTR_PROVISIONALLY_AVAILABLE - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; @@ -2476,8 +2390,6 @@ MTR_AVAILABLE(ios(17.4), macos(14.4), watchos(10.4), tvos(17.4)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(17.4), macos(14.4), watchos(10.4), tvos(17.4)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(17.4), macos(14.4), watchos(10.4), tvos(17.4)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(17.4), macos(14.4), watchos(10.4), tvos(17.4)); @@ -2518,8 +2430,6 @@ MTR_AVAILABLE(ios(17.4), macos(14.4), watchos(10.4), tvos(17.4)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(17.4), macos(14.4), watchos(10.4), tvos(17.4)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(17.4), macos(14.4), watchos(10.4), tvos(17.4)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(17.4), macos(14.4), watchos(10.4), tvos(17.4)); @@ -2570,8 +2480,6 @@ MTR_PROVISIONALLY_AVAILABLE - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; @@ -2612,8 +2520,6 @@ MTR_PROVISIONALLY_AVAILABLE - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; @@ -2662,8 +2568,6 @@ MTR_PROVISIONALLY_AVAILABLE - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; @@ -2700,8 +2604,6 @@ MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); @@ -2768,8 +2670,6 @@ MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); @@ -2815,8 +2715,6 @@ MTR_PROVISIONALLY_AVAILABLE - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; @@ -2855,8 +2753,6 @@ MTR_PROVISIONALLY_AVAILABLE - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; @@ -2914,8 +2810,6 @@ MTR_PROVISIONALLY_AVAILABLE - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; @@ -2975,8 +2869,6 @@ MTR_AVAILABLE(ios(17.4), macos(14.4), watchos(10.4), tvos(17.4)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(17.4), macos(14.4), watchos(10.4), tvos(17.4)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(17.4), macos(14.4), watchos(10.4), tvos(17.4)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(17.4), macos(14.4), watchos(10.4), tvos(17.4)); @@ -3033,8 +2925,6 @@ MTR_AVAILABLE(ios(17.4), macos(14.4), watchos(10.4), tvos(17.4)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(17.4), macos(14.4), watchos(10.4), tvos(17.4)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(17.4), macos(14.4), watchos(10.4), tvos(17.4)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(17.4), macos(14.4), watchos(10.4), tvos(17.4)); @@ -3084,8 +2974,6 @@ MTR_PROVISIONALLY_AVAILABLE - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; @@ -3138,8 +3026,6 @@ MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); @@ -3192,8 +3078,6 @@ MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); @@ -3249,8 +3133,6 @@ MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); @@ -3318,8 +3200,6 @@ MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); @@ -3392,8 +3272,6 @@ MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); @@ -3440,8 +3318,6 @@ MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); @@ -3493,8 +3369,6 @@ MTR_PROVISIONALLY_AVAILABLE - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; @@ -3557,8 +3431,6 @@ MTR_PROVISIONALLY_AVAILABLE - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; @@ -3600,8 +3472,6 @@ MTR_PROVISIONALLY_AVAILABLE - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; @@ -3667,8 +3537,6 @@ MTR_PROVISIONALLY_AVAILABLE - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; @@ -3771,8 +3639,6 @@ MTR_PROVISIONALLY_AVAILABLE - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; @@ -3821,8 +3687,6 @@ MTR_PROVISIONALLY_AVAILABLE - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; @@ -3861,8 +3725,6 @@ MTR_PROVISIONALLY_AVAILABLE - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; @@ -3903,8 +3765,6 @@ MTR_PROVISIONALLY_AVAILABLE - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; @@ -3945,8 +3805,6 @@ MTR_PROVISIONALLY_AVAILABLE - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; @@ -3987,8 +3845,6 @@ MTR_PROVISIONALLY_AVAILABLE - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; @@ -4179,8 +4035,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); @@ -4275,8 +4129,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); @@ -4326,8 +4178,6 @@ MTR_PROVISIONALLY_AVAILABLE - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; @@ -4416,8 +4266,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); @@ -4640,8 +4488,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); @@ -4716,8 +4562,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); @@ -4764,8 +4608,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); @@ -4950,8 +4792,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); @@ -5034,8 +4874,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); @@ -5080,8 +4918,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); @@ -5124,8 +4960,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); @@ -5178,8 +5012,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); @@ -5222,8 +5054,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); @@ -5266,8 +5096,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); @@ -5350,8 +5178,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); @@ -5408,8 +5234,6 @@ MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); @@ -5466,8 +5290,6 @@ MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); @@ -5524,8 +5346,6 @@ MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); @@ -5582,8 +5402,6 @@ MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); @@ -5640,8 +5458,6 @@ MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); @@ -5698,8 +5514,6 @@ MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); @@ -5756,8 +5570,6 @@ MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); @@ -5814,8 +5626,6 @@ MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); @@ -5872,8 +5682,6 @@ MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); @@ -5930,8 +5738,6 @@ MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); @@ -5974,8 +5780,6 @@ MTR_PROVISIONALLY_AVAILABLE - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; @@ -6031,8 +5835,6 @@ MTR_PROVISIONALLY_AVAILABLE - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; @@ -6079,8 +5881,6 @@ MTR_PROVISIONALLY_AVAILABLE - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; @@ -6119,8 +5919,6 @@ MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); @@ -6170,8 +5968,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); @@ -6212,8 +6008,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); @@ -6303,8 +6097,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); @@ -6352,8 +6144,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); @@ -6392,8 +6182,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); @@ -6430,8 +6218,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); @@ -6475,8 +6261,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); @@ -6518,8 +6302,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); @@ -6570,8 +6352,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); @@ -6622,8 +6402,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); @@ -6664,8 +6442,6 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)); @@ -6739,8 +6515,6 @@ MTR_PROVISIONALLY_AVAILABLE - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; @@ -6777,8 +6551,6 @@ MTR_PROVISIONALLY_AVAILABLE - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; @@ -6832,8 +6604,6 @@ MTR_PROVISIONALLY_AVAILABLE - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; @@ -7022,8 +6792,6 @@ MTR_PROVISIONALLY_AVAILABLE - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; @@ -7066,8 +6834,6 @@ MTR_PROVISIONALLY_AVAILABLE - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; @@ -7109,8 +6875,6 @@ MTR_PROVISIONALLY_AVAILABLE - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; @@ -7159,8 +6923,6 @@ MTR_PROVISIONALLY_AVAILABLE - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; @@ -7199,8 +6961,6 @@ MTR_PROVISIONALLY_AVAILABLE - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; @@ -7240,8 +7000,6 @@ MTR_PROVISIONALLY_AVAILABLE - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; @@ -7670,8 +7428,6 @@ MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)); @@ -7719,8 +7475,6 @@ MTR_PROVISIONALLY_AVAILABLE - (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm index fbdc9bd48613a3..0923caca7cead0 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm @@ -128,11 +128,6 @@ - (void)writeAttributeIdentifyTimeWithValue:(NSDictionary *)data return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeIdentifyID) attributeID:@(MTRAttributeIDTypeClusterIdentifyAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeIdentifyID) attributeID:@(MTRAttributeIDTypeClusterIdentifyAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeIdentifyID) attributeID:@(MTRAttributeIDTypeClusterIdentifyAttributeAttributeListID) params:params]; @@ -352,11 +347,6 @@ - (void)addGroupIfIdentifyingWithParams:(MTRGroupsClusterAddGroupIfIdentifyingPa return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeGroupsID) attributeID:@(MTRAttributeIDTypeClusterGroupsAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeGroupsID) attributeID:@(MTRAttributeIDTypeClusterGroupsAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeGroupsID) attributeID:@(MTRAttributeIDTypeClusterGroupsAttributeAttributeListID) params:params]; @@ -677,11 +667,6 @@ - (void)writeAttributeStartUpOnOffWithValue:(NSDictionary *)data return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeOnOffID) attributeID:@(MTRAttributeIDTypeClusterOnOffAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeOnOffID) attributeID:@(MTRAttributeIDTypeClusterOnOffAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeOnOffID) attributeID:@(MTRAttributeIDTypeClusterOnOffAttributeAttributeListID) params:params]; @@ -1156,11 +1141,6 @@ - (void)writeAttributeStartUpCurrentLevelWithValue:(NSDictionary return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeLevelControlID) attributeID:@(MTRAttributeIDTypeClusterLevelControlAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeLevelControlID) attributeID:@(MTRAttributeIDTypeClusterLevelControlAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeLevelControlID) attributeID:@(MTRAttributeIDTypeClusterLevelControlAttributeAttributeListID) params:params]; @@ -1244,11 +1224,6 @@ @implementation MTRClusterPulseWidthModulation return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypePulseWidthModulationID) attributeID:@(MTRAttributeIDTypeClusterPulseWidthModulationAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypePulseWidthModulationID) attributeID:@(MTRAttributeIDTypeClusterPulseWidthModulationAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypePulseWidthModulationID) attributeID:@(MTRAttributeIDTypeClusterPulseWidthModulationAttributeAttributeListID) params:params]; @@ -1303,11 +1278,6 @@ @implementation MTRClusterDescriptor return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeDescriptorID) attributeID:@(MTRAttributeIDTypeClusterDescriptorAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeDescriptorID) attributeID:@(MTRAttributeIDTypeClusterDescriptorAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeDescriptorID) attributeID:@(MTRAttributeIDTypeClusterDescriptorAttributeAttributeListID) params:params]; @@ -1366,11 +1336,6 @@ - (void)writeAttributeBindingWithValue:(NSDictionary *)dataValue return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeBindingID) attributeID:@(MTRAttributeIDTypeClusterBindingAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeBindingID) attributeID:@(MTRAttributeIDTypeClusterBindingAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeBindingID) attributeID:@(MTRAttributeIDTypeClusterBindingAttributeAttributeListID) params:params]; @@ -1493,11 +1458,6 @@ - (void)writeAttributeExtensionWithValue:(NSDictionary *)dataVal return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeAccessControlID) attributeID:@(MTRAttributeIDTypeClusterAccessControlAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeAccessControlID) attributeID:@(MTRAttributeIDTypeClusterAccessControlAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeAccessControlID) attributeID:@(MTRAttributeIDTypeClusterAccessControlAttributeAttributeListID) params:params]; @@ -1887,11 +1847,6 @@ - (void)disableActionWithDurationWithParams:(MTRActionsClusterDisableActionWithD return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeActionsID) attributeID:@(MTRAttributeIDTypeClusterActionsAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeActionsID) attributeID:@(MTRAttributeIDTypeClusterActionsAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeActionsID) attributeID:@(MTRAttributeIDTypeClusterActionsAttributeAttributeListID) params:params]; @@ -2169,11 +2124,6 @@ - (void)writeAttributeLocalConfigDisabledWithValue:(NSDictionary return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeBasicInformationID) attributeID:@(MTRAttributeIDTypeClusterBasicInformationAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeBasicInformationID) attributeID:@(MTRAttributeIDTypeClusterBasicInformationAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeBasicInformationID) attributeID:@(MTRAttributeIDTypeClusterBasicInformationAttributeAttributeListID) params:params]; @@ -2304,11 +2254,6 @@ - (void)notifyUpdateAppliedWithParams:(MTROTASoftwareUpdateProviderClusterNotify return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeOTASoftwareUpdateProviderID) attributeID:@(MTRAttributeIDTypeClusterOTASoftwareUpdateProviderAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeOTASoftwareUpdateProviderID) attributeID:@(MTRAttributeIDTypeClusterOTASoftwareUpdateProviderAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeOTASoftwareUpdateProviderID) attributeID:@(MTRAttributeIDTypeClusterOTASoftwareUpdateProviderAttributeAttributeListID) params:params]; @@ -2428,11 +2373,6 @@ - (void)writeAttributeDefaultOTAProvidersWithValue:(NSDictionary return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeOTASoftwareUpdateRequestorID) attributeID:@(MTRAttributeIDTypeClusterOTASoftwareUpdateRequestorAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeOTASoftwareUpdateRequestorID) attributeID:@(MTRAttributeIDTypeClusterOTASoftwareUpdateRequestorAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeOTASoftwareUpdateRequestorID) attributeID:@(MTRAttributeIDTypeClusterOTASoftwareUpdateRequestorAttributeAttributeListID) params:params]; @@ -2511,11 +2451,6 @@ - (void)writeAttributeActiveLocaleWithValue:(NSDictionary *)data return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeLocalizationConfigurationID) attributeID:@(MTRAttributeIDTypeClusterLocalizationConfigurationAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeLocalizationConfigurationID) attributeID:@(MTRAttributeIDTypeClusterLocalizationConfigurationAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeLocalizationConfigurationID) attributeID:@(MTRAttributeIDTypeClusterLocalizationConfigurationAttributeAttributeListID) params:params]; @@ -2591,11 +2526,6 @@ - (void)writeAttributeActiveCalendarTypeWithValue:(NSDictionary return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeTimeFormatLocalizationID) attributeID:@(MTRAttributeIDTypeClusterTimeFormatLocalizationAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeTimeFormatLocalizationID) attributeID:@(MTRAttributeIDTypeClusterTimeFormatLocalizationAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeTimeFormatLocalizationID) attributeID:@(MTRAttributeIDTypeClusterTimeFormatLocalizationAttributeAttributeListID) params:params]; @@ -2650,11 +2580,6 @@ - (void)writeAttributeTemperatureUnitWithValue:(NSDictionary *)d return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeUnitLocalizationID) attributeID:@(MTRAttributeIDTypeClusterUnitLocalizationAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeUnitLocalizationID) attributeID:@(MTRAttributeIDTypeClusterUnitLocalizationAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeUnitLocalizationID) attributeID:@(MTRAttributeIDTypeClusterUnitLocalizationAttributeAttributeListID) params:params]; @@ -2698,11 +2623,6 @@ @implementation MTRClusterPowerSourceConfiguration return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypePowerSourceConfigurationID) attributeID:@(MTRAttributeIDTypeClusterPowerSourceConfigurationAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypePowerSourceConfigurationID) attributeID:@(MTRAttributeIDTypeClusterPowerSourceConfigurationAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypePowerSourceConfigurationID) attributeID:@(MTRAttributeIDTypeClusterPowerSourceConfigurationAttributeAttributeListID) params:params]; @@ -2901,11 +2821,6 @@ @implementation MTRClusterPowerSource return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypePowerSourceID) attributeID:@(MTRAttributeIDTypeClusterPowerSourceAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypePowerSourceID) attributeID:@(MTRAttributeIDTypeClusterPowerSourceAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypePowerSourceID) attributeID:@(MTRAttributeIDTypeClusterPowerSourceAttributeAttributeListID) params:params]; @@ -3117,11 +3032,6 @@ - (void)writeAttributeBreadcrumbWithValue:(NSDictionary *)dataVa return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeGeneralCommissioningID) attributeID:@(MTRAttributeIDTypeClusterGeneralCommissioningAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeGeneralCommissioningID) attributeID:@(MTRAttributeIDTypeClusterGeneralCommissioningAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeGeneralCommissioningID) attributeID:@(MTRAttributeIDTypeClusterGeneralCommissioningAttributeAttributeListID) params:params]; @@ -3447,11 +3357,6 @@ - (void)writeAttributeInterfaceEnabledWithValue:(NSDictionary *) return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeNetworkCommissioningID) attributeID:@(MTRAttributeIDTypeClusterNetworkCommissioningAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeNetworkCommissioningID) attributeID:@(MTRAttributeIDTypeClusterNetworkCommissioningAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeNetworkCommissioningID) attributeID:@(MTRAttributeIDTypeClusterNetworkCommissioningAttributeAttributeListID) params:params]; @@ -3565,11 +3470,6 @@ - (void)retrieveLogsRequestWithParams:(MTRDiagnosticLogsClusterRetrieveLogsReque return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeDiagnosticLogsID) attributeID:@(MTRAttributeIDTypeClusterDiagnosticLogsAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeDiagnosticLogsID) attributeID:@(MTRAttributeIDTypeClusterDiagnosticLogsAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeDiagnosticLogsID) attributeID:@(MTRAttributeIDTypeClusterDiagnosticLogsAttributeAttributeListID) params:params]; @@ -3746,11 +3646,6 @@ - (void)payloadTestRequestWithParams:(MTRGeneralDiagnosticsClusterPayloadTestReq return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeGeneralDiagnosticsID) attributeID:@(MTRAttributeIDTypeClusterGeneralDiagnosticsAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeGeneralDiagnosticsID) attributeID:@(MTRAttributeIDTypeClusterGeneralDiagnosticsAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeGeneralDiagnosticsID) attributeID:@(MTRAttributeIDTypeClusterGeneralDiagnosticsAttributeAttributeListID) params:params]; @@ -3849,11 +3744,6 @@ - (void)resetWatermarksWithParams:(MTRSoftwareDiagnosticsClusterResetWatermarksP return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeSoftwareDiagnosticsID) attributeID:@(MTRAttributeIDTypeClusterSoftwareDiagnosticsAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeSoftwareDiagnosticsID) attributeID:@(MTRAttributeIDTypeClusterSoftwareDiagnosticsAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeSoftwareDiagnosticsID) attributeID:@(MTRAttributeIDTypeClusterSoftwareDiagnosticsAttributeAttributeListID) params:params]; @@ -4247,11 +4137,6 @@ - (void)resetCountsWithParams:(MTRThreadNetworkDiagnosticsClusterResetCountsPara return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeThreadNetworkDiagnosticsID) attributeID:@(MTRAttributeIDTypeClusterThreadNetworkDiagnosticsAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeThreadNetworkDiagnosticsID) attributeID:@(MTRAttributeIDTypeClusterThreadNetworkDiagnosticsAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeThreadNetworkDiagnosticsID) attributeID:@(MTRAttributeIDTypeClusterThreadNetworkDiagnosticsAttributeAttributeListID) params:params]; @@ -4403,11 +4288,6 @@ - (void)resetCountsWithParams:(MTRWiFiNetworkDiagnosticsClusterResetCountsParams return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWiFiNetworkDiagnosticsID) attributeID:@(MTRAttributeIDTypeClusterWiFiNetworkDiagnosticsAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWiFiNetworkDiagnosticsID) attributeID:@(MTRAttributeIDTypeClusterWiFiNetworkDiagnosticsAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWiFiNetworkDiagnosticsID) attributeID:@(MTRAttributeIDTypeClusterWiFiNetworkDiagnosticsAttributeAttributeListID) params:params]; @@ -4539,11 +4419,6 @@ - (void)resetCountsWithParams:(MTREthernetNetworkDiagnosticsClusterResetCountsPa return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeEthernetNetworkDiagnosticsID) attributeID:@(MTRAttributeIDTypeClusterEthernetNetworkDiagnosticsAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeEthernetNetworkDiagnosticsID) attributeID:@(MTRAttributeIDTypeClusterEthernetNetworkDiagnosticsAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeEthernetNetworkDiagnosticsID) attributeID:@(MTRAttributeIDTypeClusterEthernetNetworkDiagnosticsAttributeAttributeListID) params:params]; @@ -4791,11 +4666,6 @@ - (void)setDefaultNTPWithParams:(MTRTimeSynchronizationClusterSetDefaultNTPParam return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeTimeSynchronizationID) attributeID:@(MTRAttributeIDTypeClusterTimeSynchronizationAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeTimeSynchronizationID) attributeID:@(MTRAttributeIDTypeClusterTimeSynchronizationAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeTimeSynchronizationID) attributeID:@(MTRAttributeIDTypeClusterTimeSynchronizationAttributeAttributeListID) params:params]; @@ -4948,11 +4818,6 @@ - (void)writeAttributeNodeLabelWithValue:(NSDictionary *)dataVal return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeBridgedDeviceBasicInformationID) attributeID:@(MTRAttributeIDTypeClusterBridgedDeviceBasicInformationAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeBridgedDeviceBasicInformationID) attributeID:@(MTRAttributeIDTypeClusterBridgedDeviceBasicInformationAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeBridgedDeviceBasicInformationID) attributeID:@(MTRAttributeIDTypeClusterBridgedDeviceBasicInformationAttributeAttributeListID) params:params]; @@ -5008,11 +4873,6 @@ @implementation MTRClusterSwitch return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeSwitchID) attributeID:@(MTRAttributeIDTypeClusterSwitchAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeSwitchID) attributeID:@(MTRAttributeIDTypeClusterSwitchAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeSwitchID) attributeID:@(MTRAttributeIDTypeClusterSwitchAttributeAttributeListID) params:params]; @@ -5160,11 +5020,6 @@ - (void)revokeCommissioningWithParams:(MTRAdministratorCommissioningClusterRevok return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeAdministratorCommissioningID) attributeID:@(MTRAttributeIDTypeClusterAdministratorCommissioningAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeAdministratorCommissioningID) attributeID:@(MTRAttributeIDTypeClusterAdministratorCommissioningAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeAdministratorCommissioningID) attributeID:@(MTRAttributeIDTypeClusterAdministratorCommissioningAttributeAttributeListID) params:params]; @@ -5468,11 +5323,6 @@ - (void)addTrustedRootCertificateWithParams:(MTROperationalCredentialsClusterAdd return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeOperationalCredentialsID) attributeID:@(MTRAttributeIDTypeClusterOperationalCredentialsAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeOperationalCredentialsID) attributeID:@(MTRAttributeIDTypeClusterOperationalCredentialsAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeOperationalCredentialsID) attributeID:@(MTRAttributeIDTypeClusterOperationalCredentialsAttributeAttributeListID) params:params]; @@ -5715,11 +5565,6 @@ - (void)writeAttributeGroupKeyMapWithValue:(NSDictionary *)dataV return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeGroupKeyManagementID) attributeID:@(MTRAttributeIDTypeClusterGroupKeyManagementAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeGroupKeyManagementID) attributeID:@(MTRAttributeIDTypeClusterGroupKeyManagementAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeGroupKeyManagementID) attributeID:@(MTRAttributeIDTypeClusterGroupKeyManagementAttributeAttributeListID) params:params]; @@ -5789,11 +5634,6 @@ @implementation MTRClusterFixedLabel return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeFixedLabelID) attributeID:@(MTRAttributeIDTypeClusterFixedLabelAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeFixedLabelID) attributeID:@(MTRAttributeIDTypeClusterFixedLabelAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeFixedLabelID) attributeID:@(MTRAttributeIDTypeClusterFixedLabelAttributeAttributeListID) params:params]; @@ -5848,11 +5688,6 @@ - (void)writeAttributeLabelListWithValue:(NSDictionary *)dataVal return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeUserLabelID) attributeID:@(MTRAttributeIDTypeClusterUserLabelAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeUserLabelID) attributeID:@(MTRAttributeIDTypeClusterUserLabelAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeUserLabelID) attributeID:@(MTRAttributeIDTypeClusterUserLabelAttributeAttributeListID) params:params]; @@ -5896,11 +5731,6 @@ @implementation MTRClusterBooleanState return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeBooleanStateID) attributeID:@(MTRAttributeIDTypeClusterBooleanStateAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeBooleanStateID) attributeID:@(MTRAttributeIDTypeClusterBooleanStateAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeBooleanStateID) attributeID:@(MTRAttributeIDTypeClusterBooleanStateAttributeAttributeListID) params:params]; @@ -6070,11 +5900,6 @@ - (void)stayActiveRequestWithParams:(MTRICDManagementClusterStayActiveRequestPar return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeICDManagementID) attributeID:@(MTRAttributeIDTypeClusterICDManagementAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeICDManagementID) attributeID:@(MTRAttributeIDTypeClusterICDManagementAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeICDManagementID) attributeID:@(MTRAttributeIDTypeClusterICDManagementAttributeAttributeListID) params:params]; @@ -6231,11 +6056,6 @@ - (void)reduceTimeWithParams:(MTRTimerClusterReduceTimeParams *)params expectedV return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeTimerID) attributeID:@(MTRAttributeIDTypeClusterTimerAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeTimerID) attributeID:@(MTRAttributeIDTypeClusterTimerAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeTimerID) attributeID:@(MTRAttributeIDTypeClusterTimerAttributeAttributeListID) params:params]; @@ -6419,11 +6239,6 @@ - (void)resumeWithParams:(MTROvenCavityOperationalStateClusterResumeParams * _Nu return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeOvenCavityOperationalStateID) attributeID:@(MTRAttributeIDTypeClusterOvenCavityOperationalStateAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeOvenCavityOperationalStateID) attributeID:@(MTRAttributeIDTypeClusterOvenCavityOperationalStateAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeOvenCavityOperationalStateID) attributeID:@(MTRAttributeIDTypeClusterOvenCavityOperationalStateAttributeAttributeListID) params:params]; @@ -6522,11 +6337,6 @@ - (void)writeAttributeOnModeWithValue:(NSDictionary *)dataValueD return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeOvenModeID) attributeID:@(MTRAttributeIDTypeClusterOvenModeAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeOvenModeID) attributeID:@(MTRAttributeIDTypeClusterOvenModeAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeOvenModeID) attributeID:@(MTRAttributeIDTypeClusterOvenModeAttributeAttributeListID) params:params]; @@ -6577,11 +6387,6 @@ - (void)writeAttributeSelectedDrynessLevelWithValue:(NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeLaundryDryerControlsID) attributeID:@(MTRAttributeIDTypeClusterLaundryDryerControlsAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeLaundryDryerControlsID) attributeID:@(MTRAttributeIDTypeClusterLaundryDryerControlsAttributeAttributeListID) params:params]; @@ -6690,11 +6495,6 @@ - (void)writeAttributeOnModeWithValue:(NSDictionary *)dataValueD return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeModeSelectID) attributeID:@(MTRAttributeIDTypeClusterModeSelectAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeModeSelectID) attributeID:@(MTRAttributeIDTypeClusterModeSelectAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeModeSelectID) attributeID:@(MTRAttributeIDTypeClusterModeSelectAttributeAttributeListID) params:params]; @@ -6807,11 +6607,6 @@ - (void)writeAttributeOnModeWithValue:(NSDictionary *)dataValueD return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeLaundryWasherModeID) attributeID:@(MTRAttributeIDTypeClusterLaundryWasherModeAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeLaundryWasherModeID) attributeID:@(MTRAttributeIDTypeClusterLaundryWasherModeAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeLaundryWasherModeID) attributeID:@(MTRAttributeIDTypeClusterLaundryWasherModeAttributeAttributeListID) params:params]; @@ -6910,11 +6705,6 @@ - (void)writeAttributeOnModeWithValue:(NSDictionary *)dataValueD return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeRefrigeratorAndTemperatureControlledCabinetModeID) attributeID:@(MTRAttributeIDTypeClusterRefrigeratorAndTemperatureControlledCabinetModeAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeRefrigeratorAndTemperatureControlledCabinetModeID) attributeID:@(MTRAttributeIDTypeClusterRefrigeratorAndTemperatureControlledCabinetModeAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeRefrigeratorAndTemperatureControlledCabinetModeID) attributeID:@(MTRAttributeIDTypeClusterRefrigeratorAndTemperatureControlledCabinetModeAttributeAttributeListID) params:params]; @@ -6986,11 +6776,6 @@ - (void)writeAttributeNumberOfRinsesWithValue:(NSDictionary *)da return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeLaundryWasherControlsID) attributeID:@(MTRAttributeIDTypeClusterLaundryWasherControlsAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeLaundryWasherControlsID) attributeID:@(MTRAttributeIDTypeClusterLaundryWasherControlsAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeLaundryWasherControlsID) attributeID:@(MTRAttributeIDTypeClusterLaundryWasherControlsAttributeAttributeListID) params:params]; @@ -7057,11 +6842,6 @@ - (void)changeToModeWithParams:(MTRRVCRunModeClusterChangeToModeParams *)params return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeRVCRunModeID) attributeID:@(MTRAttributeIDTypeClusterRVCRunModeAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeRVCRunModeID) attributeID:@(MTRAttributeIDTypeClusterRVCRunModeAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeRVCRunModeID) attributeID:@(MTRAttributeIDTypeClusterRVCRunModeAttributeAttributeListID) params:params]; @@ -7128,11 +6908,6 @@ - (void)changeToModeWithParams:(MTRRVCCleanModeClusterChangeToModeParams *)param return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeRVCCleanModeID) attributeID:@(MTRAttributeIDTypeClusterRVCCleanModeAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeRVCCleanModeID) attributeID:@(MTRAttributeIDTypeClusterRVCCleanModeAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeRVCCleanModeID) attributeID:@(MTRAttributeIDTypeClusterRVCCleanModeAttributeAttributeListID) params:params]; @@ -7223,11 +6998,6 @@ - (void)setTemperatureWithParams:(MTRTemperatureControlClusterSetTemperaturePara return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeTemperatureControlID) attributeID:@(MTRAttributeIDTypeClusterTemperatureControlAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeTemperatureControlID) attributeID:@(MTRAttributeIDTypeClusterTemperatureControlAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeTemperatureControlID) attributeID:@(MTRAttributeIDTypeClusterTemperatureControlAttributeAttributeListID) params:params]; @@ -7272,11 +7042,6 @@ @implementation MTRClusterRefrigeratorAlarm return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeRefrigeratorAlarmID) attributeID:@(MTRAttributeIDTypeClusterRefrigeratorAlarmAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeRefrigeratorAlarmID) attributeID:@(MTRAttributeIDTypeClusterRefrigeratorAlarmAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeRefrigeratorAlarmID) attributeID:@(MTRAttributeIDTypeClusterRefrigeratorAlarmAttributeAttributeListID) params:params]; @@ -7375,11 +7140,6 @@ - (void)writeAttributeOnModeWithValue:(NSDictionary *)dataValueD return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeDishwasherModeID) attributeID:@(MTRAttributeIDTypeClusterDishwasherModeAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeDishwasherModeID) attributeID:@(MTRAttributeIDTypeClusterDishwasherModeAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeDishwasherModeID) attributeID:@(MTRAttributeIDTypeClusterDishwasherModeAttributeAttributeListID) params:params]; @@ -7414,11 +7174,6 @@ @implementation MTRClusterAirQuality return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeAirQualityID) attributeID:@(MTRAttributeIDTypeClusterAirQualityAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeAirQualityID) attributeID:@(MTRAttributeIDTypeClusterAirQualityAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeAirQualityID) attributeID:@(MTRAttributeIDTypeClusterAirQualityAttributeAttributeListID) params:params]; @@ -7555,11 +7310,6 @@ - (void)writeAttributeSmokeSensitivityLevelWithValue:(NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeSmokeCOAlarmID) attributeID:@(MTRAttributeIDTypeClusterSmokeCOAlarmAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeSmokeCOAlarmID) attributeID:@(MTRAttributeIDTypeClusterSmokeCOAlarmAttributeAttributeListID) params:params]; @@ -7663,11 +7413,6 @@ - (void)modifyEnabledAlarmsWithParams:(MTRDishwasherAlarmClusterModifyEnabledAla return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeDishwasherAlarmID) attributeID:@(MTRAttributeIDTypeClusterDishwasherAlarmAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeDishwasherAlarmID) attributeID:@(MTRAttributeIDTypeClusterDishwasherAlarmAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeDishwasherAlarmID) attributeID:@(MTRAttributeIDTypeClusterDishwasherAlarmAttributeAttributeListID) params:params]; @@ -7707,11 +7452,6 @@ @implementation MTRClusterMicrowaveOvenMode return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeMicrowaveOvenModeID) attributeID:@(MTRAttributeIDTypeClusterMicrowaveOvenModeAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeMicrowaveOvenModeID) attributeID:@(MTRAttributeIDTypeClusterMicrowaveOvenModeAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeMicrowaveOvenModeID) attributeID:@(MTRAttributeIDTypeClusterMicrowaveOvenModeAttributeAttributeListID) params:params]; @@ -7844,11 +7584,6 @@ - (void)addMoreTimeWithParams:(MTRMicrowaveOvenControlClusterAddMoreTimeParams * return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeMicrowaveOvenControlID) attributeID:@(MTRAttributeIDTypeClusterMicrowaveOvenControlAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeMicrowaveOvenControlID) attributeID:@(MTRAttributeIDTypeClusterMicrowaveOvenControlAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeMicrowaveOvenControlID) attributeID:@(MTRAttributeIDTypeClusterMicrowaveOvenControlAttributeAttributeListID) params:params]; @@ -8032,11 +7767,6 @@ - (void)resumeWithParams:(MTROperationalStateClusterResumeParams * _Nullable)par return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeOperationalStateID) attributeID:@(MTRAttributeIDTypeClusterOperationalStateAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeOperationalStateID) attributeID:@(MTRAttributeIDTypeClusterOperationalStateAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeOperationalStateID) attributeID:@(MTRAttributeIDTypeClusterOperationalStateAttributeAttributeListID) params:params]; @@ -8189,11 +7919,6 @@ - (void)goHomeWithParams:(MTRRVCOperationalStateClusterGoHomeParams * _Nullable) return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeRVCOperationalStateID) attributeID:@(MTRAttributeIDTypeClusterRVCOperationalStateAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeRVCOperationalStateID) attributeID:@(MTRAttributeIDTypeClusterRVCOperationalStateAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeRVCOperationalStateID) attributeID:@(MTRAttributeIDTypeClusterRVCOperationalStateAttributeAttributeListID) params:params]; @@ -8454,11 +8179,6 @@ - (void)copySceneWithParams:(MTRScenesManagementClusterCopySceneParams *)params return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeScenesManagementID) attributeID:@(MTRAttributeIDTypeClusterScenesManagementAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeScenesManagementID) attributeID:@(MTRAttributeIDTypeClusterScenesManagementAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeScenesManagementID) attributeID:@(MTRAttributeIDTypeClusterScenesManagementAttributeAttributeListID) params:params]; @@ -8560,11 +8280,6 @@ - (void)writeAttributeLastChangedTimeWithValue:(NSDictionary *)d return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeHEPAFilterMonitoringID) attributeID:@(MTRAttributeIDTypeClusterHEPAFilterMonitoringAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeHEPAFilterMonitoringID) attributeID:@(MTRAttributeIDTypeClusterHEPAFilterMonitoringAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeHEPAFilterMonitoringID) attributeID:@(MTRAttributeIDTypeClusterHEPAFilterMonitoringAttributeAttributeListID) params:params]; @@ -8666,11 +8381,6 @@ - (void)writeAttributeLastChangedTimeWithValue:(NSDictionary *)d return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeActivatedCarbonFilterMonitoringID) attributeID:@(MTRAttributeIDTypeClusterActivatedCarbonFilterMonitoringAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeActivatedCarbonFilterMonitoringID) attributeID:@(MTRAttributeIDTypeClusterActivatedCarbonFilterMonitoringAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeActivatedCarbonFilterMonitoringID) attributeID:@(MTRAttributeIDTypeClusterActivatedCarbonFilterMonitoringAttributeAttributeListID) params:params]; @@ -8805,11 +8515,6 @@ - (void)writeAttributeCurrentSensitivityLevelWithValue:(NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeBooleanStateConfigurationID) attributeID:@(MTRAttributeIDTypeClusterBooleanStateConfigurationAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeBooleanStateConfigurationID) attributeID:@(MTRAttributeIDTypeClusterBooleanStateConfigurationAttributeAttributeListID) params:params]; @@ -8978,11 +8683,6 @@ - (void)writeAttributeDefaultOpenLevelWithValue:(NSDictionary *) return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeValveConfigurationAndControlID) attributeID:@(MTRAttributeIDTypeClusterValveConfigurationAndControlAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeValveConfigurationAndControlID) attributeID:@(MTRAttributeIDTypeClusterValveConfigurationAndControlAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeValveConfigurationAndControlID) attributeID:@(MTRAttributeIDTypeClusterValveConfigurationAndControlAttributeAttributeListID) params:params]; @@ -9107,11 +8807,6 @@ @implementation MTRClusterElectricalPowerMeasurement return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeElectricalPowerMeasurementID) attributeID:@(MTRAttributeIDTypeClusterElectricalPowerMeasurementAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeElectricalPowerMeasurementID) attributeID:@(MTRAttributeIDTypeClusterElectricalPowerMeasurementAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeElectricalPowerMeasurementID) attributeID:@(MTRAttributeIDTypeClusterElectricalPowerMeasurementAttributeAttributeListID) params:params]; @@ -9171,11 +8866,6 @@ @implementation MTRClusterElectricalEnergyMeasurement return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeElectricalEnergyMeasurementID) attributeID:@(MTRAttributeIDTypeClusterElectricalEnergyMeasurementAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeElectricalEnergyMeasurementID) attributeID:@(MTRAttributeIDTypeClusterElectricalEnergyMeasurementAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeElectricalEnergyMeasurementID) attributeID:@(MTRAttributeIDTypeClusterElectricalEnergyMeasurementAttributeAttributeListID) params:params]; @@ -9293,11 +8983,6 @@ - (void)cancelBoostWithParams:(MTRWaterHeaterManagementClusterCancelBoostParams return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWaterHeaterManagementID) attributeID:@(MTRAttributeIDTypeClusterWaterHeaterManagementAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWaterHeaterManagementID) attributeID:@(MTRAttributeIDTypeClusterWaterHeaterManagementAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWaterHeaterManagementID) attributeID:@(MTRAttributeIDTypeClusterWaterHeaterManagementAttributeAttributeListID) params:params]; @@ -9528,11 +9213,6 @@ - (void)writeAttributeDefaultRandomDurationWithValue:(NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeDemandResponseLoadControlID) attributeID:@(MTRAttributeIDTypeClusterDemandResponseLoadControlAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeDemandResponseLoadControlID) attributeID:@(MTRAttributeIDTypeClusterDemandResponseLoadControlAttributeAttributeListID) params:params]; @@ -9626,11 +9306,6 @@ - (void)cancelMessagesRequestWithParams:(MTRMessagesClusterCancelMessagesRequest return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeMessagesID) attributeID:@(MTRAttributeIDTypeClusterMessagesAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeMessagesID) attributeID:@(MTRAttributeIDTypeClusterMessagesAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeMessagesID) attributeID:@(MTRAttributeIDTypeClusterMessagesAttributeAttributeListID) params:params]; @@ -9928,11 +9603,6 @@ - (void)cancelRequestWithParams:(MTRDeviceEnergyManagementClusterCancelRequestPa return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeDeviceEnergyManagementID) attributeID:@(MTRAttributeIDTypeClusterDeviceEnergyManagementAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeDeviceEnergyManagementID) attributeID:@(MTRAttributeIDTypeClusterDeviceEnergyManagementAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeDeviceEnergyManagementID) attributeID:@(MTRAttributeIDTypeClusterDeviceEnergyManagementAttributeAttributeListID) params:params]; @@ -10336,11 +10006,6 @@ - (void)writeAttributeApproximateEVEfficiencyWithValue:(NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeEnergyEVSEID) attributeID:@(MTRAttributeIDTypeClusterEnergyEVSEAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeEnergyEVSEID) attributeID:@(MTRAttributeIDTypeClusterEnergyEVSEAttributeAttributeListID) params:params]; @@ -10417,11 +10082,6 @@ - (void)writeAttributeCurrentLowPowerModeSensitivityWithValue:(NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeEnergyPreferenceID) attributeID:@(MTRAttributeIDTypeClusterEnergyPreferenceAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeEnergyPreferenceID) attributeID:@(MTRAttributeIDTypeClusterEnergyPreferenceAttributeAttributeListID) params:params]; @@ -10461,11 +10121,6 @@ @implementation MTRClusterPowerTopology return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypePowerTopologyID) attributeID:@(MTRAttributeIDTypeClusterPowerTopologyAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypePowerTopologyID) attributeID:@(MTRAttributeIDTypeClusterPowerTopologyAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypePowerTopologyID) attributeID:@(MTRAttributeIDTypeClusterPowerTopologyAttributeAttributeListID) params:params]; @@ -10532,11 +10187,6 @@ - (void)changeToModeWithParams:(MTREnergyEVSEModeClusterChangeToModeParams *)par return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeEnergyEVSEModeID) attributeID:@(MTRAttributeIDTypeClusterEnergyEVSEModeAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeEnergyEVSEModeID) attributeID:@(MTRAttributeIDTypeClusterEnergyEVSEModeAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeEnergyEVSEModeID) attributeID:@(MTRAttributeIDTypeClusterEnergyEVSEModeAttributeAttributeListID) params:params]; @@ -10603,11 +10253,6 @@ - (void)changeToModeWithParams:(MTRWaterHeaterModeClusterChangeToModeParams *)pa return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWaterHeaterModeID) attributeID:@(MTRAttributeIDTypeClusterWaterHeaterModeAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWaterHeaterModeID) attributeID:@(MTRAttributeIDTypeClusterWaterHeaterModeAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWaterHeaterModeID) attributeID:@(MTRAttributeIDTypeClusterWaterHeaterModeAttributeAttributeListID) params:params]; @@ -10674,11 +10319,6 @@ - (void)changeToModeWithParams:(MTRDeviceEnergyManagementModeClusterChangeToMode return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeDeviceEnergyManagementModeID) attributeID:@(MTRAttributeIDTypeClusterDeviceEnergyManagementModeAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeDeviceEnergyManagementModeID) attributeID:@(MTRAttributeIDTypeClusterDeviceEnergyManagementModeAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeDeviceEnergyManagementModeID) attributeID:@(MTRAttributeIDTypeClusterDeviceEnergyManagementModeAttributeAttributeListID) params:params]; @@ -11744,11 +11384,6 @@ - (void)writeAttributeExpiringUserTimeoutWithValue:(NSDictionary return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeDoorLockID) attributeID:@(MTRAttributeIDTypeClusterDoorLockAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeDoorLockID) attributeID:@(MTRAttributeIDTypeClusterDoorLockAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeDoorLockID) attributeID:@(MTRAttributeIDTypeClusterDoorLockAttributeAttributeListID) params:params]; @@ -12217,11 +11852,6 @@ - (void)writeAttributeModeWithValue:(NSDictionary *)dataValueDic return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWindowCoveringID) attributeID:@(MTRAttributeIDTypeClusterWindowCoveringAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWindowCoveringID) attributeID:@(MTRAttributeIDTypeClusterWindowCoveringAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWindowCoveringID) attributeID:@(MTRAttributeIDTypeClusterWindowCoveringAttributeAttributeListID) params:params]; @@ -12391,11 +12021,6 @@ - (void)skipAreaWithParams:(MTRServiceAreaClusterSkipAreaParams *)params expecte return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeServiceAreaID) attributeID:@(MTRAttributeIDTypeClusterServiceAreaAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeServiceAreaID) attributeID:@(MTRAttributeIDTypeClusterServiceAreaAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeServiceAreaID) attributeID:@(MTRAttributeIDTypeClusterServiceAreaAttributeAttributeListID) params:params]; @@ -12584,11 +12209,6 @@ - (void)writeAttributeControlModeWithValue:(NSDictionary *)dataV return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypePumpConfigurationAndControlID) attributeID:@(MTRAttributeIDTypeClusterPumpConfigurationAndControlAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypePumpConfigurationAndControlID) attributeID:@(MTRAttributeIDTypeClusterPumpConfigurationAndControlAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypePumpConfigurationAndControlID) attributeID:@(MTRAttributeIDTypeClusterPumpConfigurationAndControlAttributeAttributeListID) params:params]; @@ -13439,11 +13059,6 @@ - (void)writeAttributeSchedulesWithValue:(NSDictionary *)dataVal return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeThermostatID) attributeID:@(MTRAttributeIDTypeClusterThermostatAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeThermostatID) attributeID:@(MTRAttributeIDTypeClusterThermostatAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeThermostatID) attributeID:@(MTRAttributeIDTypeClusterThermostatAttributeAttributeListID) params:params]; @@ -13673,11 +13288,6 @@ - (void)writeAttributeAirflowDirectionWithValue:(NSDictionary *) return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeFanControlID) attributeID:@(MTRAttributeIDTypeClusterFanControlAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeFanControlID) attributeID:@(MTRAttributeIDTypeClusterFanControlAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeFanControlID) attributeID:@(MTRAttributeIDTypeClusterFanControlAttributeAttributeListID) params:params]; @@ -13764,11 +13374,6 @@ - (void)writeAttributeScheduleProgrammingVisibilityWithValue:(NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeThermostatUserInterfaceConfigurationID) attributeID:@(MTRAttributeIDTypeClusterThermostatUserInterfaceConfigurationAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeThermostatUserInterfaceConfigurationID) attributeID:@(MTRAttributeIDTypeClusterThermostatUserInterfaceConfigurationAttributeAttributeListID) params:params]; @@ -14723,11 +14328,6 @@ - (void)writeAttributeStartUpColorTemperatureMiredsWithValue:(NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeColorControlID) attributeID:@(MTRAttributeIDTypeClusterColorControlAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeColorControlID) attributeID:@(MTRAttributeIDTypeClusterColorControlAttributeAttributeListID) params:params]; @@ -15041,11 +14641,6 @@ - (void)writeAttributeLampBurnHoursTripPointWithValue:(NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeBallastConfigurationID) attributeID:@(MTRAttributeIDTypeClusterBallastConfigurationAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeBallastConfigurationID) attributeID:@(MTRAttributeIDTypeClusterBallastConfigurationAttributeAttributeListID) params:params]; @@ -15121,11 +14716,6 @@ @implementation MTRClusterIlluminanceMeasurement return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeIlluminanceMeasurementID) attributeID:@(MTRAttributeIDTypeClusterIlluminanceMeasurementAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeIlluminanceMeasurementID) attributeID:@(MTRAttributeIDTypeClusterIlluminanceMeasurementAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeIlluminanceMeasurementID) attributeID:@(MTRAttributeIDTypeClusterIlluminanceMeasurementAttributeAttributeListID) params:params]; @@ -15184,11 +14774,6 @@ @implementation MTRClusterTemperatureMeasurement return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeTemperatureMeasurementID) attributeID:@(MTRAttributeIDTypeClusterTemperatureMeasurementAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeTemperatureMeasurementID) attributeID:@(MTRAttributeIDTypeClusterTemperatureMeasurementAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeTemperatureMeasurementID) attributeID:@(MTRAttributeIDTypeClusterTemperatureMeasurementAttributeAttributeListID) params:params]; @@ -15272,11 +14857,6 @@ @implementation MTRClusterPressureMeasurement return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypePressureMeasurementID) attributeID:@(MTRAttributeIDTypeClusterPressureMeasurementAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypePressureMeasurementID) attributeID:@(MTRAttributeIDTypeClusterPressureMeasurementAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypePressureMeasurementID) attributeID:@(MTRAttributeIDTypeClusterPressureMeasurementAttributeAttributeListID) params:params]; @@ -15335,11 +14915,6 @@ @implementation MTRClusterFlowMeasurement return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeFlowMeasurementID) attributeID:@(MTRAttributeIDTypeClusterFlowMeasurementAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeFlowMeasurementID) attributeID:@(MTRAttributeIDTypeClusterFlowMeasurementAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeFlowMeasurementID) attributeID:@(MTRAttributeIDTypeClusterFlowMeasurementAttributeAttributeListID) params:params]; @@ -15398,11 +14973,6 @@ @implementation MTRClusterRelativeHumidityMeasurement return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeRelativeHumidityMeasurementID) attributeID:@(MTRAttributeIDTypeClusterRelativeHumidityMeasurementAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeRelativeHumidityMeasurementID) attributeID:@(MTRAttributeIDTypeClusterRelativeHumidityMeasurementAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeRelativeHumidityMeasurementID) attributeID:@(MTRAttributeIDTypeClusterRelativeHumidityMeasurementAttributeAttributeListID) params:params]; @@ -15621,11 +15191,6 @@ - (void)writeAttributePhysicalContactUnoccupiedToOccupiedThresholdWithValue:(NSD return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeOccupancySensingID) attributeID:@(MTRAttributeIDTypeClusterOccupancySensingAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeOccupancySensingID) attributeID:@(MTRAttributeIDTypeClusterOccupancySensingAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeOccupancySensingID) attributeID:@(MTRAttributeIDTypeClusterOccupancySensingAttributeAttributeListID) params:params]; @@ -15755,11 +15320,6 @@ @implementation MTRClusterCarbonMonoxideConcentrationMeasurement return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeCarbonMonoxideConcentrationMeasurementID) attributeID:@(MTRAttributeIDTypeClusterCarbonMonoxideConcentrationMeasurementAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeCarbonMonoxideConcentrationMeasurementID) attributeID:@(MTRAttributeIDTypeClusterCarbonMonoxideConcentrationMeasurementAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeCarbonMonoxideConcentrationMeasurementID) attributeID:@(MTRAttributeIDTypeClusterCarbonMonoxideConcentrationMeasurementAttributeAttributeListID) params:params]; @@ -15844,11 +15404,6 @@ @implementation MTRClusterCarbonDioxideConcentrationMeasurement return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeCarbonDioxideConcentrationMeasurementID) attributeID:@(MTRAttributeIDTypeClusterCarbonDioxideConcentrationMeasurementAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeCarbonDioxideConcentrationMeasurementID) attributeID:@(MTRAttributeIDTypeClusterCarbonDioxideConcentrationMeasurementAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeCarbonDioxideConcentrationMeasurementID) attributeID:@(MTRAttributeIDTypeClusterCarbonDioxideConcentrationMeasurementAttributeAttributeListID) params:params]; @@ -15933,11 +15488,6 @@ @implementation MTRClusterNitrogenDioxideConcentrationMeasurement return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeNitrogenDioxideConcentrationMeasurementID) attributeID:@(MTRAttributeIDTypeClusterNitrogenDioxideConcentrationMeasurementAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeNitrogenDioxideConcentrationMeasurementID) attributeID:@(MTRAttributeIDTypeClusterNitrogenDioxideConcentrationMeasurementAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeNitrogenDioxideConcentrationMeasurementID) attributeID:@(MTRAttributeIDTypeClusterNitrogenDioxideConcentrationMeasurementAttributeAttributeListID) params:params]; @@ -16022,11 +15572,6 @@ @implementation MTRClusterOzoneConcentrationMeasurement return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeOzoneConcentrationMeasurementID) attributeID:@(MTRAttributeIDTypeClusterOzoneConcentrationMeasurementAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeOzoneConcentrationMeasurementID) attributeID:@(MTRAttributeIDTypeClusterOzoneConcentrationMeasurementAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeOzoneConcentrationMeasurementID) attributeID:@(MTRAttributeIDTypeClusterOzoneConcentrationMeasurementAttributeAttributeListID) params:params]; @@ -16111,11 +15656,6 @@ @implementation MTRClusterPM25ConcentrationMeasurement return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypePM25ConcentrationMeasurementID) attributeID:@(MTRAttributeIDTypeClusterPM25ConcentrationMeasurementAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypePM25ConcentrationMeasurementID) attributeID:@(MTRAttributeIDTypeClusterPM25ConcentrationMeasurementAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypePM25ConcentrationMeasurementID) attributeID:@(MTRAttributeIDTypeClusterPM25ConcentrationMeasurementAttributeAttributeListID) params:params]; @@ -16200,11 +15740,6 @@ @implementation MTRClusterFormaldehydeConcentrationMeasurement return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeFormaldehydeConcentrationMeasurementID) attributeID:@(MTRAttributeIDTypeClusterFormaldehydeConcentrationMeasurementAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeFormaldehydeConcentrationMeasurementID) attributeID:@(MTRAttributeIDTypeClusterFormaldehydeConcentrationMeasurementAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeFormaldehydeConcentrationMeasurementID) attributeID:@(MTRAttributeIDTypeClusterFormaldehydeConcentrationMeasurementAttributeAttributeListID) params:params]; @@ -16289,11 +15824,6 @@ @implementation MTRClusterPM1ConcentrationMeasurement return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypePM1ConcentrationMeasurementID) attributeID:@(MTRAttributeIDTypeClusterPM1ConcentrationMeasurementAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypePM1ConcentrationMeasurementID) attributeID:@(MTRAttributeIDTypeClusterPM1ConcentrationMeasurementAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypePM1ConcentrationMeasurementID) attributeID:@(MTRAttributeIDTypeClusterPM1ConcentrationMeasurementAttributeAttributeListID) params:params]; @@ -16378,11 +15908,6 @@ @implementation MTRClusterPM10ConcentrationMeasurement return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypePM10ConcentrationMeasurementID) attributeID:@(MTRAttributeIDTypeClusterPM10ConcentrationMeasurementAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypePM10ConcentrationMeasurementID) attributeID:@(MTRAttributeIDTypeClusterPM10ConcentrationMeasurementAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypePM10ConcentrationMeasurementID) attributeID:@(MTRAttributeIDTypeClusterPM10ConcentrationMeasurementAttributeAttributeListID) params:params]; @@ -16467,11 +15992,6 @@ @implementation MTRClusterTotalVolatileOrganicCompoundsConcentrationMeasurement return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeTotalVolatileOrganicCompoundsConcentrationMeasurementID) attributeID:@(MTRAttributeIDTypeClusterTotalVolatileOrganicCompoundsConcentrationMeasurementAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeTotalVolatileOrganicCompoundsConcentrationMeasurementID) attributeID:@(MTRAttributeIDTypeClusterTotalVolatileOrganicCompoundsConcentrationMeasurementAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeTotalVolatileOrganicCompoundsConcentrationMeasurementID) attributeID:@(MTRAttributeIDTypeClusterTotalVolatileOrganicCompoundsConcentrationMeasurementAttributeAttributeListID) params:params]; @@ -16556,11 +16076,6 @@ @implementation MTRClusterRadonConcentrationMeasurement return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeRadonConcentrationMeasurementID) attributeID:@(MTRAttributeIDTypeClusterRadonConcentrationMeasurementAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeRadonConcentrationMeasurementID) attributeID:@(MTRAttributeIDTypeClusterRadonConcentrationMeasurementAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeRadonConcentrationMeasurementID) attributeID:@(MTRAttributeIDTypeClusterRadonConcentrationMeasurementAttributeAttributeListID) params:params]; @@ -16631,11 +16146,6 @@ - (void)networkPassphraseRequestWithParams:(MTRWiFiNetworkManagementClusterNetwo return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWiFiNetworkManagementID) attributeID:@(MTRAttributeIDTypeClusterWiFiNetworkManagementAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWiFiNetworkManagementID) attributeID:@(MTRAttributeIDTypeClusterWiFiNetworkManagementAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWiFiNetworkManagementID) attributeID:@(MTRAttributeIDTypeClusterWiFiNetworkManagementAttributeAttributeListID) params:params]; @@ -16811,11 +16321,6 @@ - (void)setPendingDatasetRequestWithParams:(MTRThreadBorderRouterManagementClust return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeThreadBorderRouterManagementID) attributeID:@(MTRAttributeIDTypeClusterThreadBorderRouterManagementAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeThreadBorderRouterManagementID) attributeID:@(MTRAttributeIDTypeClusterThreadBorderRouterManagementAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeThreadBorderRouterManagementID) attributeID:@(MTRAttributeIDTypeClusterThreadBorderRouterManagementAttributeAttributeListID) params:params]; @@ -16958,11 +16463,6 @@ - (void)writeAttributePreferredExtendedPanIDWithValue:(NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeThreadNetworkDirectoryID) attributeID:@(MTRAttributeIDTypeClusterThreadNetworkDirectoryAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeThreadNetworkDirectoryID) attributeID:@(MTRAttributeIDTypeClusterThreadNetworkDirectoryAttributeAttributeListID) params:params]; @@ -17002,11 +16502,6 @@ @implementation MTRClusterWakeOnLAN return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWakeOnLANID) attributeID:@(MTRAttributeIDTypeClusterWakeOnLANAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWakeOnLANID) attributeID:@(MTRAttributeIDTypeClusterWakeOnLANAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWakeOnLANID) attributeID:@(MTRAttributeIDTypeClusterWakeOnLANAttributeAttributeListID) params:params]; @@ -17228,11 +16723,6 @@ - (void)cancelRecordProgramWithParams:(MTRChannelClusterCancelRecordProgramParam return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeChannelID) attributeID:@(MTRAttributeIDTypeClusterChannelAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeChannelID) attributeID:@(MTRAttributeIDTypeClusterChannelAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeChannelID) attributeID:@(MTRAttributeIDTypeClusterChannelAttributeAttributeListID) params:params]; @@ -17326,11 +16816,6 @@ - (void)navigateTargetWithParams:(MTRTargetNavigatorClusterNavigateTargetParams return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeTargetNavigatorID) attributeID:@(MTRAttributeIDTypeClusterTargetNavigatorAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeTargetNavigatorID) attributeID:@(MTRAttributeIDTypeClusterTargetNavigatorAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeTargetNavigatorID) attributeID:@(MTRAttributeIDTypeClusterTargetNavigatorAttributeAttributeListID) params:params]; @@ -17846,11 +17331,6 @@ - (void)deactivateTextTrackWithParams:(MTRMediaPlaybackClusterDeactivateTextTrac return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeMediaPlaybackID) attributeID:@(MTRAttributeIDTypeClusterMediaPlaybackAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeMediaPlaybackID) attributeID:@(MTRAttributeIDTypeClusterMediaPlaybackAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeMediaPlaybackID) attributeID:@(MTRAttributeIDTypeClusterMediaPlaybackAttributeAttributeListID) params:params]; @@ -18135,11 +17615,6 @@ - (void)renameInputWithParams:(MTRMediaInputClusterRenameInputParams *)params ex return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeMediaInputID) attributeID:@(MTRAttributeIDTypeClusterMediaInputAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeMediaInputID) attributeID:@(MTRAttributeIDTypeClusterMediaInputAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeMediaInputID) attributeID:@(MTRAttributeIDTypeClusterMediaInputAttributeAttributeListID) params:params]; @@ -18237,11 +17712,6 @@ - (void)sleepWithParams:(MTRLowPowerClusterSleepParams * _Nullable)params expect return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeLowPowerID) attributeID:@(MTRAttributeIDTypeClusterLowPowerAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeLowPowerID) attributeID:@(MTRAttributeIDTypeClusterLowPowerAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeLowPowerID) attributeID:@(MTRAttributeIDTypeClusterLowPowerAttributeAttributeListID) params:params]; @@ -18316,11 +17786,6 @@ - (void)sendKeyWithParams:(MTRKeypadInputClusterSendKeyParams *)params expectedV return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeKeypadInputID) attributeID:@(MTRAttributeIDTypeClusterKeypadInputAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeKeypadInputID) attributeID:@(MTRAttributeIDTypeClusterKeypadInputAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeKeypadInputID) attributeID:@(MTRAttributeIDTypeClusterKeypadInputAttributeAttributeListID) params:params]; @@ -18442,11 +17907,6 @@ - (void)writeAttributeSupportedStreamingProtocolsWithValue:(NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeContentLauncherID) attributeID:@(MTRAttributeIDTypeClusterContentLauncherAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeContentLauncherID) attributeID:@(MTRAttributeIDTypeClusterContentLauncherAttributeAttributeListID) params:params]; @@ -18565,11 +18025,6 @@ - (void)renameOutputWithParams:(MTRAudioOutputClusterRenameOutputParams *)params return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeAudioOutputID) attributeID:@(MTRAttributeIDTypeClusterAudioOutputAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeAudioOutputID) attributeID:@(MTRAttributeIDTypeClusterAudioOutputAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeAudioOutputID) attributeID:@(MTRAttributeIDTypeClusterAudioOutputAttributeAttributeListID) params:params]; @@ -18732,11 +18187,6 @@ - (void)writeAttributeCurrentAppWithValue:(NSDictionary *)dataVa return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeApplicationLauncherID) attributeID:@(MTRAttributeIDTypeClusterApplicationLauncherAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeApplicationLauncherID) attributeID:@(MTRAttributeIDTypeClusterApplicationLauncherAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeApplicationLauncherID) attributeID:@(MTRAttributeIDTypeClusterApplicationLauncherAttributeAttributeListID) params:params]; @@ -18839,11 +18289,6 @@ @implementation MTRClusterApplicationBasic return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeApplicationBasicID) attributeID:@(MTRAttributeIDTypeClusterApplicationBasicAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeApplicationBasicID) attributeID:@(MTRAttributeIDTypeClusterApplicationBasicAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeApplicationBasicID) attributeID:@(MTRAttributeIDTypeClusterApplicationBasicAttributeAttributeListID) params:params]; @@ -18976,11 +18421,6 @@ - (void)logoutWithParams:(MTRAccountLoginClusterLogoutParams * _Nullable)params return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeAccountLoginID) attributeID:@(MTRAttributeIDTypeClusterAccountLoginAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeAccountLoginID) attributeID:@(MTRAttributeIDTypeClusterAccountLoginAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeAccountLoginID) attributeID:@(MTRAttributeIDTypeClusterAccountLoginAttributeAttributeListID) params:params]; @@ -19375,11 +18815,6 @@ - (void)setScheduledContentRatingThresholdWithParams:(MTRContentControlClusterSe return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeContentControlID) attributeID:@(MTRAttributeIDTypeClusterContentControlAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeContentControlID) attributeID:@(MTRAttributeIDTypeClusterContentControlAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeContentControlID) attributeID:@(MTRAttributeIDTypeClusterContentControlAttributeAttributeListID) params:params]; @@ -19436,11 +18871,6 @@ - (void)contentAppMessageWithParams:(MTRContentAppObserverClusterContentAppMessa return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeContentAppObserverID) attributeID:@(MTRAttributeIDTypeClusterContentAppObserverAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeContentAppObserverID) attributeID:@(MTRAttributeIDTypeClusterContentAppObserverAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeContentAppObserverID) attributeID:@(MTRAttributeIDTypeClusterContentAppObserverAttributeAttributeListID) params:params]; @@ -19624,11 +19054,6 @@ - (void)writeAttributeSensitivityWithValue:(NSDictionary *)dataV return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeZoneManagementID) attributeID:@(MTRAttributeIDTypeClusterZoneManagementAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeZoneManagementID) attributeID:@(MTRAttributeIDTypeClusterZoneManagementAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeZoneManagementID) attributeID:@(MTRAttributeIDTypeClusterZoneManagementAttributeAttributeListID) params:params]; @@ -20497,11 +19922,6 @@ - (void)writeAttributeDepthSensorStatusWithValue:(NSDictionary * return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeCameraAVStreamManagementID) attributeID:@(MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeCameraAVStreamManagementID) attributeID:@(MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeCameraAVStreamManagementID) attributeID:@(MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeAttributeListID) params:params]; @@ -20671,11 +20091,6 @@ - (void)endSessionWithParams:(MTRWebRTCTransportProviderClusterEndSessionParams return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWebRTCTransportProviderID) attributeID:@(MTRAttributeIDTypeClusterWebRTCTransportProviderAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWebRTCTransportProviderID) attributeID:@(MTRAttributeIDTypeClusterWebRTCTransportProviderAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWebRTCTransportProviderID) attributeID:@(MTRAttributeIDTypeClusterWebRTCTransportProviderAttributeAttributeListID) params:params]; @@ -20818,11 +20233,6 @@ - (void)endWithParams:(MTRWebRTCTransportRequestorClusterEndParams *)params expe return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWebRTCTransportRequestorID) attributeID:@(MTRAttributeIDTypeClusterWebRTCTransportRequestorAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWebRTCTransportRequestorID) attributeID:@(MTRAttributeIDTypeClusterWebRTCTransportRequestorAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWebRTCTransportRequestorID) attributeID:@(MTRAttributeIDTypeClusterWebRTCTransportRequestorAttributeAttributeListID) params:params]; @@ -20920,11 +20330,6 @@ - (void)writeAttributeEnabledWithValue:(NSDictionary *)dataValue return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeChimeID) attributeID:@(MTRAttributeIDTypeClusterChimeAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeChimeID) attributeID:@(MTRAttributeIDTypeClusterChimeAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeChimeID) attributeID:@(MTRAttributeIDTypeClusterChimeAttributeAttributeListID) params:params]; @@ -20964,11 +20369,6 @@ @implementation MTRClusterEcosystemInformation return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeEcosystemInformationID) attributeID:@(MTRAttributeIDTypeClusterEcosystemInformationAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeEcosystemInformationID) attributeID:@(MTRAttributeIDTypeClusterEcosystemInformationAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeEcosystemInformationID) attributeID:@(MTRAttributeIDTypeClusterEcosystemInformationAttributeAttributeListID) params:params]; @@ -21057,11 +20457,6 @@ - (void)commissionNodeWithParams:(MTRCommissionerControlClusterCommissionNodePar return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeCommissionerControlID) attributeID:@(MTRAttributeIDTypeClusterCommissionerControlAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeCommissionerControlID) attributeID:@(MTRAttributeIDTypeClusterCommissionerControlAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeCommissionerControlID) attributeID:@(MTRAttributeIDTypeClusterCommissionerControlAttributeAttributeListID) params:params]; @@ -23262,11 +22657,6 @@ - (void)writeAttributeNullableGlobalStructWithValue:(NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeUnitTestingID) attributeID:@(MTRAttributeIDTypeClusterUnitTestingAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeUnitTestingID) attributeID:@(MTRAttributeIDTypeClusterUnitTestingAttributeAttributeListID) params:params]; @@ -23586,11 +22976,6 @@ - (void)writeAttributeFlipFlopWithValue:(NSDictionary *)dataValu return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeSampleMEIID) attributeID:@(MTRAttributeIDTypeClusterSampleMEIAttributeAcceptedCommandListID) params:params]; } -- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params -{ - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeSampleMEIID) attributeID:@(MTRAttributeIDTypeClusterSampleMEIAttributeEventListID) params:params]; -} - - (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params { return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeSampleMEIID) attributeID:@(MTRAttributeIDTypeClusterSampleMEIAttributeAttributeListID) params:params]; diff --git a/src/python_testing/TC_ACL_2_11.py b/src/python_testing/TC_ACL_2_11.py index e8aa253ae714af..0b58a7f317e22e 100644 --- a/src/python_testing/TC_ACL_2_11.py +++ b/src/python_testing/TC_ACL_2_11.py @@ -42,6 +42,7 @@ import queue import chip.clusters as Clusters +import matter_testing_infrastructure.chip.testing.global_attribute_ids as global_attribute_ids from chip.clusters.Attribute import EventReadResult, SubscriptionTransaction, ValueDecodeFailure from chip.clusters.ClusterObjects import ALL_ACCEPTED_COMMANDS, ALL_ATTRIBUTES, ALL_CLUSTERS, ClusterEvent from chip.clusters.Objects import AccessControl @@ -77,15 +78,6 @@ def WaitForEventReport(q: queue.Queue, expected_event: ClusterEvent): class TC_ACL_2_11(MatterBaseTest): - global_attributes = [ - Clusters.Descriptor.Attributes.GeneratedCommandList.attribute_id, - Clusters.Descriptor.Attributes.AcceptedCommandList.attribute_id, - Clusters.Descriptor.Attributes.AttributeList.attribute_id, - Clusters.Descriptor.Attributes.FeatureMap.attribute_id, - Clusters.Descriptor.Attributes.ClusterRevision.attribute_id, - Clusters.Descriptor.Attributes.EventList.attribute_id - ] - def pics_TC_ACL_2_11(self) -> list[str]: return ['ACL.S.F01'] @@ -154,7 +146,7 @@ async def test_TC_ACL_2_11(self): # if ID1 is null, it means it is a wildcard. We need to read all attributes on the cluster if ID1 is NullValue: for attr_id, attribute in ALL_ATTRIBUTES[C1].items(): - if attr_id not in self.global_attributes: + if global_attribute_ids.attribute_id_type(attr_id) != global_attribute_ids.AttributeIdType.kStandardGlobal: await self.read_single_attribute_expect_error(cluster=cluster, attribute=attribute, error=Status.AccessRestricted, endpoint=E1) else: attribute = ALL_ATTRIBUTES[C1][ID1] @@ -162,7 +154,7 @@ async def test_TC_ACL_2_11(self): elif restriction_type == AccessControl.Enums.AccessRestrictionTypeEnum.kAttributeWriteForbidden: if ID1 is NullValue: for attr_id, attribute in ALL_ATTRIBUTES[C1].items(): - if attr_id not in self.global_attributes: + if global_attribute_ids.attribute_id_type(attr_id) != global_attribute_ids.AttributeIdType.kStandardGlobal: status = await self.write_single_attribute(attribute_value=attribute(), endpoint_id=E1, expect_success=False) if status is not Status.UnsupportedWrite: asserts.assert_equal(status, Status.AccessRestricted, diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp index 6884315a0737e0..7e9752db4a888c 100644 --- a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp +++ b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp @@ -905,8 +905,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -1299,8 +1297,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -1503,8 +1499,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -1978,8 +1972,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -2008,8 +2000,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -2101,8 +2091,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -2207,8 +2195,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -2678,8 +2664,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -3483,8 +3467,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -3760,8 +3742,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -4173,8 +4153,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -4330,8 +4308,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -4505,8 +4481,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -4541,8 +4515,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -4573,8 +4545,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -4605,8 +4575,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -4824,8 +4792,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -5332,8 +5298,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -6054,8 +6018,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -6178,8 +6140,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -6476,8 +6436,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -6749,8 +6707,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -7288,8 +7244,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -7441,8 +7395,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -7621,8 +7573,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -8073,8 +8023,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -8359,8 +8307,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -8543,8 +8489,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -8946,8 +8890,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -9595,8 +9537,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -10026,8 +9966,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -10059,8 +9997,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -10092,8 +10028,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -10122,8 +10056,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -10152,8 +10084,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -10182,8 +10112,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -10214,8 +10142,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -10575,8 +10501,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -10734,8 +10658,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -10892,8 +10814,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -11086,8 +11006,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -11120,8 +11038,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -11286,8 +11202,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -11399,8 +11313,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -11512,8 +11424,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -11550,8 +11460,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -11659,8 +11567,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -11768,8 +11674,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -11850,8 +11754,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -11886,8 +11788,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -12050,8 +11950,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -12082,8 +11980,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -12159,8 +12055,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -12568,8 +12462,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -12654,8 +12546,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -12791,8 +12681,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -12949,8 +12837,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -13168,8 +13054,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -14152,8 +14036,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -14258,8 +14140,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -14364,8 +14244,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -14479,8 +14357,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -14667,8 +14543,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -14940,8 +14814,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -15127,8 +14999,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -15368,8 +15238,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -16023,8 +15891,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -16346,8 +16212,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -17223,8 +17087,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -17743,8 +17605,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -18107,8 +17967,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -18141,8 +17999,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -18250,8 +18106,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -18359,8 +18213,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -18468,8 +18320,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -19846,8 +19696,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -20378,8 +20226,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -20789,8 +20635,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -20865,8 +20709,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -22049,8 +21891,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -22148,8 +21988,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -22184,8 +22022,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -23325,8 +23161,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -23383,8 +23217,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -23423,8 +23255,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -23461,8 +23291,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -23509,8 +23337,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -23547,8 +23373,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -23585,8 +23409,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -23691,8 +23513,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -23779,8 +23599,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -23831,8 +23649,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -23883,8 +23699,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -23935,8 +23749,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -23987,8 +23799,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -24039,8 +23849,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -24091,8 +23899,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -24143,8 +23949,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -24195,8 +23999,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -24247,8 +24049,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -24336,8 +24136,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -24526,8 +24324,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -24752,8 +24548,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -24786,8 +24580,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -25666,8 +25458,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -25822,8 +25612,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -26468,8 +26256,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -26745,8 +26531,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -26796,8 +26580,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -26895,8 +26677,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -27437,8 +27217,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -27593,8 +27371,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -27817,8 +27593,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -27864,8 +27638,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -28041,8 +27813,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -28481,8 +28251,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -28617,8 +28385,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -29056,8 +28822,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -30460,8 +30224,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -31048,8 +30810,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -31248,8 +31008,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -31348,8 +31106,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -31570,8 +31326,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -31745,8 +31499,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -34182,8 +33934,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -34444,8 +34194,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): @@ -34570,8 +34318,6 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, generatedCommandList); case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, acceptedCommandList); - case Attributes::EventList::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, eventList); case Attributes::AttributeList::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, attributeList); case Attributes::FeatureMap::TypeInfo::GetAttributeId(): diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h index f2671adf0f2a03..4ec96663f8becd 100644 --- a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h +++ b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h @@ -497,18 +497,6 @@ struct TypeInfo }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo -{ - using Type = DataModel::List; - using DecodableType = DataModel::DecodableList; - using DecodableArgType = const DataModel::DecodableList &; - - static constexpr AttributeId GetAttributeId() { return Attributes::EventList::Id; } - static constexpr bool MustUseTimedWrite() { return false; } -}; -} // namespace EventList - namespace AttributeList { struct TypeInfo { @@ -673,12 +661,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::Identify::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::Identify::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -711,7 +693,6 @@ struct TypeInfo static_cast(0); Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -1142,12 +1123,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::Groups::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::Groups::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -1179,7 +1154,6 @@ struct TypeInfo static_cast>(0); Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -1486,12 +1460,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::OnOff::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::OnOff::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -1526,7 +1494,6 @@ struct TypeInfo Attributes::StartUpOnOff::TypeInfo::DecodableType startUpOnOff; Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -2125,12 +2092,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::LevelControl::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::LevelControl::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -2175,7 +2136,6 @@ struct TypeInfo Attributes::StartUpCurrentLevel::TypeInfo::DecodableType startUpCurrentLevel; Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -2199,12 +2159,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::PulseWidthModulation::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::PulseWidthModulation::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -2234,7 +2188,6 @@ struct TypeInfo Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -2352,12 +2305,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::Descriptor::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::Descriptor::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -2392,7 +2339,6 @@ struct TypeInfo Attributes::TagList::TypeInfo::DecodableType tagList; Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -2468,12 +2414,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::Binding::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::Binding::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -2504,7 +2444,6 @@ struct TypeInfo Attributes::Binding::TypeInfo::DecodableType binding; Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -2916,12 +2855,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::AccessControl::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::AccessControl::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -2958,7 +2891,6 @@ struct TypeInfo Attributes::Arl::TypeInfo::DecodableType arl; Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -3734,12 +3666,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::Actions::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::Actions::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -3772,7 +3698,6 @@ struct TypeInfo Attributes::SetupURL::TypeInfo::DecodableType setupURL; Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -4256,12 +4181,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::BasicInformation::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::BasicInformation::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -4314,7 +4233,6 @@ struct TypeInfo Attributes::MaxPathsPerInvoke::TypeInfo::DecodableType maxPathsPerInvoke = static_cast(0); Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -4711,12 +4629,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::OtaSoftwareUpdateProvider::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::OtaSoftwareUpdateProvider::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -4746,7 +4658,6 @@ struct TypeInfo Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -4912,12 +4823,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::OtaSoftwareUpdateRequestor::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::OtaSoftwareUpdateRequestor::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -4952,7 +4857,6 @@ struct TypeInfo Attributes::UpdateStateProgress::TypeInfo::DecodableType updateStateProgress; Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -5123,12 +5027,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::LocalizationConfiguration::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::LocalizationConfiguration::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -5160,7 +5058,6 @@ struct TypeInfo Attributes::SupportedLocales::TypeInfo::DecodableType supportedLocales; Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -5221,12 +5118,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::TimeFormatLocalization::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::TimeFormatLocalization::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -5261,7 +5152,6 @@ struct TypeInfo Attributes::SupportedCalendarTypes::TypeInfo::DecodableType supportedCalendarTypes; Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -5297,12 +5187,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::UnitLocalization::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::UnitLocalization::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -5334,7 +5218,6 @@ struct TypeInfo static_cast(0); Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -5370,12 +5253,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::PowerSourceConfiguration::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::PowerSourceConfiguration::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -5406,7 +5283,6 @@ struct TypeInfo Attributes::Sources::TypeInfo::DecodableType sources; Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -5910,12 +5786,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::PowerSource::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::PowerSource::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -5984,7 +5854,6 @@ struct TypeInfo Attributes::EndpointList::TypeInfo::DecodableType endpointList; Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -6584,12 +6453,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::GeneralCommissioning::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::GeneralCommissioning::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -6631,7 +6494,6 @@ struct TypeInfo Attributes::TCUpdateDeadline::TypeInfo::DecodableType TCUpdateDeadline = static_cast(0); Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -7367,12 +7229,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::NetworkCommissioning::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::NetworkCommissioning::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -7414,7 +7270,6 @@ struct TypeInfo Attributes::ThreadVersion::TypeInfo::DecodableType threadVersion = static_cast(0); Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -7535,12 +7390,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::DiagnosticLogs::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::DiagnosticLogs::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -7570,7 +7419,6 @@ struct TypeInfo Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -7956,12 +7804,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::GeneralDiagnostics::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::GeneralDiagnostics::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -8001,7 +7843,6 @@ struct TypeInfo Attributes::TestEventTriggersEnabled::TypeInfo::DecodableType testEventTriggersEnabled = static_cast(0); Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -8290,12 +8131,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::SoftwareDiagnostics::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::SoftwareDiagnostics::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -8329,7 +8164,6 @@ struct TypeInfo Attributes::CurrentHeapHighWatermark::TypeInfo::DecodableType currentHeapHighWatermark = static_cast(0); Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -9359,12 +9193,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::ThreadNetworkDiagnostics::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::ThreadNetworkDiagnostics::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -9458,7 +9286,6 @@ struct TypeInfo Attributes::ActiveNetworkFaultsList::TypeInfo::DecodableType activeNetworkFaultsList; Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -9751,12 +9578,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::WiFiNetworkDiagnostics::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::WiFiNetworkDiagnostics::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -9799,7 +9620,6 @@ struct TypeInfo Attributes::OverrunCount::TypeInfo::DecodableType overrunCount; Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -10076,12 +9896,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::EthernetNetworkDiagnostics::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::EthernetNetworkDiagnostics::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -10120,7 +9934,6 @@ struct TypeInfo Attributes::TimeSinceReset::TypeInfo::DecodableType timeSinceReset = static_cast(0); Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -10643,12 +10456,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::TimeSynchronization::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::TimeSynchronization::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -10694,7 +10501,6 @@ struct TypeInfo Attributes::SupportsDNSResolve::TypeInfo::DecodableType supportsDNSResolve = static_cast(0); Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -11162,12 +10968,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::BridgedDeviceBasicInformation::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::BridgedDeviceBasicInformation::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -11214,7 +11014,6 @@ struct TypeInfo Attributes::ProductAppearance::TypeInfo::DecodableType productAppearance; Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -11431,12 +11230,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::Switch::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::Switch::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -11469,7 +11262,6 @@ struct TypeInfo Attributes::MultiPressMax::TypeInfo::DecodableType multiPressMax = static_cast(0); Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -11895,12 +11687,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::AdministratorCommissioning::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::AdministratorCommissioning::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -11934,7 +11720,6 @@ struct TypeInfo Attributes::AdminVendorId::TypeInfo::DecodableType adminVendorId; Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -12591,12 +12376,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::OperationalCredentials::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::OperationalCredentials::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -12632,7 +12411,6 @@ struct TypeInfo Attributes::CurrentFabricIndex::TypeInfo::DecodableType currentFabricIndex = static_cast(0); Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -13052,12 +12830,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::GroupKeyManagement::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::GroupKeyManagement::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -13091,7 +12863,6 @@ struct TypeInfo Attributes::MaxGroupKeysPerFabric::TypeInfo::DecodableType maxGroupKeysPerFabric = static_cast(0); Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -13131,12 +12902,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::FixedLabel::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::FixedLabel::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -13167,7 +12932,6 @@ struct TypeInfo Attributes::LabelList::TypeInfo::DecodableType labelList; Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -13207,12 +12971,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::UserLabel::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::UserLabel::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -13243,7 +13001,6 @@ struct TypeInfo Attributes::LabelList::TypeInfo::DecodableType labelList; Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -13267,12 +13024,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::ProxyConfiguration::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::ProxyConfiguration::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -13302,7 +13053,6 @@ struct TypeInfo Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -13326,12 +13076,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::ProxyDiscovery::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::ProxyDiscovery::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -13361,7 +13105,6 @@ struct TypeInfo Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -13385,12 +13128,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::ProxyValid::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::ProxyValid::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -13420,7 +13157,6 @@ struct TypeInfo Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -13456,12 +13192,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::BooleanState::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::BooleanState::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -13492,7 +13222,6 @@ struct TypeInfo Attributes::StateValue::TypeInfo::DecodableType stateValue = static_cast(0); Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -13919,12 +13648,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::IcdManagement::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::IcdManagement::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -13966,7 +13689,6 @@ struct TypeInfo Attributes::MaximumCheckInBackOff::TypeInfo::DecodableType maximumCheckInBackOff = static_cast(0); Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -14178,12 +13900,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::Timer::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::Timer::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -14216,7 +13932,6 @@ struct TypeInfo Attributes::TimerState::TypeInfo::DecodableType timerState = static_cast(0); Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -14496,12 +14211,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::OvenCavityOperationalState::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::OvenCavityOperationalState::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -14538,7 +14247,6 @@ struct TypeInfo Attributes::OperationalError::TypeInfo::DecodableType operationalError; Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -14775,12 +14483,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::OvenMode::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::OvenMode::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -14814,7 +14516,6 @@ struct TypeInfo Attributes::OnMode::TypeInfo::DecodableType onMode; Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -14863,12 +14564,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::LaundryDryerControls::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::LaundryDryerControls::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -14900,7 +14595,6 @@ struct TypeInfo Attributes::SelectedDrynessLevel::TypeInfo::DecodableType selectedDrynessLevel; Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -15102,12 +14796,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::ModeSelect::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::ModeSelect::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -15143,7 +14831,6 @@ struct TypeInfo Attributes::OnMode::TypeInfo::DecodableType onMode; Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -15306,12 +14993,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::LaundryWasherMode::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::LaundryWasherMode::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -15345,7 +15026,6 @@ struct TypeInfo Attributes::OnMode::TypeInfo::DecodableType onMode; Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -15509,12 +15189,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::RefrigeratorAndTemperatureControlledCabinetMode::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::RefrigeratorAndTemperatureControlledCabinetMode::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -15548,7 +15222,6 @@ struct TypeInfo Attributes::OnMode::TypeInfo::DecodableType onMode; Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -15621,12 +15294,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::LaundryWasherControls::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::LaundryWasherControls::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -15661,7 +15328,6 @@ struct TypeInfo Attributes::SupportedRinses::TypeInfo::DecodableType supportedRinses; Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -15800,12 +15466,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::RvcRunMode::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::RvcRunMode::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -15837,7 +15497,6 @@ struct TypeInfo Attributes::CurrentMode::TypeInfo::DecodableType currentMode = static_cast(0); Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -15976,12 +15635,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::RvcCleanMode::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::RvcCleanMode::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -16013,7 +15666,6 @@ struct TypeInfo Attributes::CurrentMode::TypeInfo::DecodableType currentMode = static_cast(0); Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -16157,12 +15809,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::TemperatureControl::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::TemperatureControl::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -16198,7 +15844,6 @@ struct TypeInfo Attributes::SupportedTemperatureLevels::TypeInfo::DecodableType supportedTemperatureLevels; Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -16258,12 +15903,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::RefrigeratorAlarm::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::RefrigeratorAlarm::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -16299,7 +15938,6 @@ struct TypeInfo static_cast>(0); Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -16506,12 +16144,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::DishwasherMode::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::DishwasherMode::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -16545,7 +16177,6 @@ struct TypeInfo Attributes::OnMode::TypeInfo::DecodableType onMode; Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -16581,12 +16212,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::AirQuality::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::AirQuality::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -16618,7 +16243,6 @@ struct TypeInfo static_cast(0); Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -16839,12 +16463,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::SmokeCoAlarm::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::SmokeCoAlarm::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -16896,7 +16514,6 @@ struct TypeInfo Attributes::ExpiryDate::TypeInfo::DecodableType expiryDate = static_cast(0); Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -17385,12 +17002,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::DishwasherAlarm::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::DishwasherAlarm::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -17428,7 +17039,6 @@ struct TypeInfo static_cast>(0); Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -17526,12 +17136,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::MicrowaveOvenMode::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::MicrowaveOvenMode::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -17563,7 +17167,6 @@ struct TypeInfo Attributes::CurrentMode::TypeInfo::DecodableType currentMode = static_cast(0); Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -17789,12 +17392,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::MicrowaveOvenControl::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::MicrowaveOvenControl::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -17833,7 +17430,6 @@ struct TypeInfo Attributes::WattRating::TypeInfo::DecodableType wattRating = static_cast(0); Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -18112,12 +17708,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::OperationalState::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::OperationalState::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -18154,7 +17744,6 @@ struct TypeInfo Attributes::OperationalError::TypeInfo::DecodableType operationalError; Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -18474,12 +18063,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::RvcOperationalState::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::RvcOperationalState::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -18515,7 +18098,6 @@ struct TypeInfo Attributes::OperationalError::TypeInfo::DecodableType operationalError; Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -19412,12 +18994,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::ScenesManagement::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::ScenesManagement::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -19450,7 +19026,6 @@ struct TypeInfo Attributes::FabricSceneInfo::TypeInfo::DecodableType fabricSceneInfo; Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -19615,12 +19190,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::HepaFilterMonitoring::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::HepaFilterMonitoring::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -19658,7 +19227,6 @@ struct TypeInfo Attributes::ReplacementProductList::TypeInfo::DecodableType replacementProductList; Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -19823,12 +19391,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::ActivatedCarbonFilterMonitoring::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::ActivatedCarbonFilterMonitoring::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -19866,7 +19428,6 @@ struct TypeInfo Attributes::ReplacementProductList::TypeInfo::DecodableType replacementProductList; Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -20068,12 +19629,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::BooleanStateConfiguration::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::BooleanStateConfiguration::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -20116,7 +19671,6 @@ struct TypeInfo static_cast>(0); Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -20426,12 +19980,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::ValveConfigurationAndControl::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::ValveConfigurationAndControl::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -20473,7 +20021,6 @@ struct TypeInfo Attributes::LevelStep::TypeInfo::DecodableType levelStep = static_cast(0); Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -20876,12 +20423,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::ElectricalPowerMeasurement::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::ElectricalPowerMeasurement::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -20931,7 +20472,6 @@ struct TypeInfo Attributes::NeutralCurrent::TypeInfo::DecodableType neutralCurrent; Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -21138,12 +20678,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::ElectricalEnergyMeasurement::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::ElectricalEnergyMeasurement::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -21179,7 +20713,6 @@ struct TypeInfo Attributes::CumulativeEnergyReset::TypeInfo::DecodableType cumulativeEnergyReset; Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -21460,12 +20993,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::WaterHeaterManagement::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::WaterHeaterManagement::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -21504,7 +21031,6 @@ struct TypeInfo static_cast(0); Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -22111,12 +21637,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::DemandResponseLoadControl::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::DemandResponseLoadControl::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -22154,7 +21674,6 @@ struct TypeInfo Attributes::DefaultRandomDuration::TypeInfo::DecodableType defaultRandomDuration = static_cast(0); Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -22435,12 +21954,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::Messages::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::Messages::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -22472,7 +21985,6 @@ struct TypeInfo Attributes::ActiveMessageIDs::TypeInfo::DecodableType activeMessageIDs; Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -23289,12 +22801,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::DeviceEnergyManagement::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::DeviceEnergyManagement::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -23335,7 +22841,6 @@ struct TypeInfo static_cast(0); Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -24120,12 +23625,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::EnergyEvse::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::EnergyEvse::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -24180,7 +23679,6 @@ struct TypeInfo Attributes::SessionEnergyDischarged::TypeInfo::DecodableType sessionEnergyDischarged; Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -24535,12 +24033,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::EnergyPreference::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::EnergyPreference::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -24576,7 +24068,6 @@ struct TypeInfo static_cast(0); Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -24624,12 +24115,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::PowerTopology::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::PowerTopology::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -24661,7 +24146,6 @@ struct TypeInfo Attributes::ActiveEndpoints::TypeInfo::DecodableType activeEndpoints; Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -24800,12 +24284,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::EnergyEvseMode::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::EnergyEvseMode::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -24837,7 +24315,6 @@ struct TypeInfo Attributes::CurrentMode::TypeInfo::DecodableType currentMode = static_cast(0); Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -24976,12 +24453,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::WaterHeaterMode::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::WaterHeaterMode::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -25013,7 +24484,6 @@ struct TypeInfo Attributes::CurrentMode::TypeInfo::DecodableType currentMode = static_cast(0); Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -25152,12 +24622,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::DeviceEnergyManagementMode::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::DeviceEnergyManagementMode::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -25189,7 +24653,6 @@ struct TypeInfo Attributes::CurrentMode::TypeInfo::DecodableType currentMode = static_cast(0); Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -26972,12 +26435,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::DoorLock::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::DoorLock::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -27064,7 +26521,6 @@ struct TypeInfo static_cast(0); Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -27825,12 +27281,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::WindowCovering::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::WindowCovering::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -27886,7 +27336,6 @@ struct TypeInfo static_cast>(0); Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -28271,12 +27720,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::ServiceArea::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::ServiceArea::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -28312,7 +27755,6 @@ struct TypeInfo Attributes::Progress::TypeInfo::DecodableType progress; Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -28612,12 +28054,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::PumpConfigurationAndControl::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::PumpConfigurationAndControl::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -28675,7 +28111,6 @@ struct TypeInfo static_cast(0); Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -30461,12 +29896,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::Thermostat::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::Thermostat::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -30572,7 +30001,6 @@ struct TypeInfo Attributes::SetpointHoldExpiryTimestamp::TypeInfo::DecodableType setpointHoldExpiryTimestamp; Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -30791,12 +30219,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::FanControl::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::FanControl::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -30844,7 +30266,6 @@ struct TypeInfo static_cast(0); Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -30904,12 +30325,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::ThermostatUserInterfaceConfiguration::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::ThermostatUserInterfaceConfiguration::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -30945,7 +30360,6 @@ struct TypeInfo static_cast(0); Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -32521,12 +31935,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::ColorControl::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::ColorControl::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -32613,7 +32021,6 @@ struct TypeInfo Attributes::StartUpColorTemperatureMireds::TypeInfo::DecodableType startUpColorTemperatureMireds; Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -32807,12 +32214,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::BallastConfiguration::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::BallastConfiguration::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -32858,7 +32259,6 @@ struct TypeInfo Attributes::LampBurnHoursTripPoint::TypeInfo::DecodableType lampBurnHoursTripPoint; Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -32943,12 +32343,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::IlluminanceMeasurement::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::IlluminanceMeasurement::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -32983,7 +32377,6 @@ struct TypeInfo Attributes::LightSensorType::TypeInfo::DecodableType lightSensorType; Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -33055,12 +32448,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::TemperatureMeasurement::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::TemperatureMeasurement::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -33094,7 +32481,6 @@ struct TypeInfo Attributes::Tolerance::TypeInfo::DecodableType tolerance = static_cast(0); Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -33226,12 +32612,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::PressureMeasurement::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::PressureMeasurement::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -33270,7 +32650,6 @@ struct TypeInfo Attributes::Scale::TypeInfo::DecodableType scale = static_cast(0); Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -33342,12 +32721,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::FlowMeasurement::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::FlowMeasurement::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -33381,7 +32754,6 @@ struct TypeInfo Attributes::Tolerance::TypeInfo::DecodableType tolerance = static_cast(0); Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -33453,12 +32825,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::RelativeHumidityMeasurement::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::RelativeHumidityMeasurement::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -33492,7 +32858,6 @@ struct TypeInfo Attributes::Tolerance::TypeInfo::DecodableType tolerance = static_cast(0); Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -33711,12 +33076,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::OccupancySensing::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::OccupancySensing::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -33770,7 +33129,6 @@ struct TypeInfo physicalContactUnoccupiedToOccupiedThreshold = static_cast(0); Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -33961,12 +33319,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::CarbonMonoxideConcentrationMeasurement::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::CarbonMonoxideConcentrationMeasurement::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -34010,7 +33362,6 @@ struct TypeInfo static_cast(0); Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -34166,12 +33517,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::CarbonDioxideConcentrationMeasurement::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::CarbonDioxideConcentrationMeasurement::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -34215,7 +33560,6 @@ struct TypeInfo static_cast(0); Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -34371,12 +33715,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::NitrogenDioxideConcentrationMeasurement::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::NitrogenDioxideConcentrationMeasurement::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -34420,7 +33758,6 @@ struct TypeInfo static_cast(0); Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -34576,12 +33913,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::OzoneConcentrationMeasurement::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::OzoneConcentrationMeasurement::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -34625,7 +33956,6 @@ struct TypeInfo static_cast(0); Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -34781,12 +34111,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::Pm25ConcentrationMeasurement::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::Pm25ConcentrationMeasurement::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -34830,7 +34154,6 @@ struct TypeInfo static_cast(0); Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -34986,12 +34309,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::FormaldehydeConcentrationMeasurement::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::FormaldehydeConcentrationMeasurement::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -35035,7 +34352,6 @@ struct TypeInfo static_cast(0); Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -35191,12 +34507,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::Pm1ConcentrationMeasurement::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::Pm1ConcentrationMeasurement::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -35240,7 +34550,6 @@ struct TypeInfo static_cast(0); Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -35396,12 +34705,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::Pm10ConcentrationMeasurement::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::Pm10ConcentrationMeasurement::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -35445,7 +34748,6 @@ struct TypeInfo static_cast(0); Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -35601,12 +34903,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::TotalVolatileOrganicCompoundsConcentrationMeasurement::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::TotalVolatileOrganicCompoundsConcentrationMeasurement::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -35650,7 +34946,6 @@ struct TypeInfo static_cast(0); Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -35806,12 +35101,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::RadonConcentrationMeasurement::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::RadonConcentrationMeasurement::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -35855,7 +35144,6 @@ struct TypeInfo static_cast(0); Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -35982,12 +35270,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::WiFiNetworkManagement::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::WiFiNetworkManagement::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -36019,7 +35301,6 @@ struct TypeInfo Attributes::PassphraseSurrogate::TypeInfo::DecodableType passphraseSurrogate; Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -36305,12 +35586,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::ThreadBorderRouterManagement::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::ThreadBorderRouterManagement::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -36346,7 +35621,6 @@ struct TypeInfo Attributes::PendingDatasetTimestamp::TypeInfo::DecodableType pendingDatasetTimestamp; Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -36594,12 +35868,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::ThreadNetworkDirectory::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::ThreadNetworkDirectory::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -36632,7 +35900,6 @@ struct TypeInfo Attributes::ThreadNetworkTableSize::TypeInfo::DecodableType threadNetworkTableSize = static_cast(0); Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -36682,12 +35949,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::WakeOnLan::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::WakeOnLan::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -36719,7 +35980,6 @@ struct TypeInfo Attributes::LinkLocalAddress::TypeInfo::DecodableType linkLocalAddress; Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -37415,12 +36675,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::Channel::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::Channel::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -37453,7 +36707,6 @@ struct TypeInfo Attributes::CurrentChannel::TypeInfo::DecodableType currentChannel; Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -37616,12 +36869,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::TargetNavigator::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::TargetNavigator::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -37653,7 +36900,6 @@ struct TypeInfo Attributes::CurrentTarget::TypeInfo::DecodableType currentTarget = static_cast(0); Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -38472,12 +37718,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::MediaPlayback::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::MediaPlayback::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -38519,7 +37759,6 @@ struct TypeInfo Attributes::AvailableTextTracks::TypeInfo::DecodableType availableTextTracks; Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -38808,12 +38047,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::MediaInput::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::MediaInput::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -38845,7 +38078,6 @@ struct TypeInfo Attributes::CurrentInput::TypeInfo::DecodableType currentInput = static_cast(0); Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -38910,12 +38142,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::LowPower::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::LowPower::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -38945,7 +38171,6 @@ struct TypeInfo Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -39051,12 +38276,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::KeypadInput::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::KeypadInput::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -39086,7 +38305,6 @@ struct TypeInfo Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -39506,12 +38724,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::ContentLauncher::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::ContentLauncher::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -39544,7 +38756,6 @@ struct TypeInfo static_cast>(0); Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -39706,12 +38917,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::AudioOutput::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::AudioOutput::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -39743,7 +38948,6 @@ struct TypeInfo Attributes::CurrentOutput::TypeInfo::DecodableType currentOutput = static_cast(0); Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -39981,12 +39185,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::ApplicationLauncher::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::ApplicationLauncher::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -40018,7 +39216,6 @@ struct TypeInfo Attributes::CurrentApp::TypeInfo::DecodableType currentApp; Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -40144,12 +39341,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::ApplicationBasic::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::ApplicationBasic::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -40188,7 +39379,6 @@ struct TypeInfo Attributes::AllowedVendorList::TypeInfo::DecodableType allowedVendorList; Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -40374,12 +39564,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::AccountLogin::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::AccountLogin::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -40409,7 +39593,6 @@ struct TypeInfo Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -40996,12 +40179,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::ContentControl::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::ContentControl::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -41039,7 +40216,6 @@ struct TypeInfo Attributes::BlockUnrated::TypeInfo::DecodableType blockUnrated = static_cast(0); Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -41184,12 +40360,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::ContentAppObserver::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::ContentAppObserver::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -41219,7 +40389,6 @@ struct TypeInfo Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -41642,12 +40811,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::ZoneManagement::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::ZoneManagement::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -41681,7 +40844,6 @@ struct TypeInfo Attributes::Sensitivity::TypeInfo::DecodableType sensitivity = static_cast(0); Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -43334,12 +42496,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::CameraAvStreamManagement::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::CameraAvStreamManagement::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -43422,7 +42578,6 @@ struct TypeInfo static_cast(0); Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -43958,12 +43113,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::WebRTCTransportProvider::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::WebRTCTransportProvider::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -43994,7 +43143,6 @@ struct TypeInfo Attributes::CurrentSessions::TypeInfo::DecodableType currentSessions; Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -44211,12 +43359,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::WebRTCTransportRequestor::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::WebRTCTransportRequestor::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -44247,7 +43389,6 @@ struct TypeInfo Attributes::CurrentSessions::TypeInfo::DecodableType currentSessions; Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -44374,12 +43515,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::Chime::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::Chime::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -44412,7 +43547,6 @@ struct TypeInfo Attributes::Enabled::TypeInfo::DecodableType enabled = static_cast(0); Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -44563,12 +43697,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::EcosystemInformation::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::EcosystemInformation::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -44600,7 +43728,6 @@ struct TypeInfo Attributes::LocationDirectory::TypeInfo::DecodableType locationDirectory; Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -44779,12 +43906,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::CommissionerControl::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::CommissionerControl::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -44816,7 +43937,6 @@ struct TypeInfo static_cast>(0); Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -48009,12 +47129,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::UnitTesting::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::UnitTesting::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -48148,7 +47262,6 @@ struct TypeInfo Attributes::NullableGlobalStruct::TypeInfo::DecodableType nullableGlobalStruct; Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -48391,12 +47504,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::FaultInjection::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::FaultInjection::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -48426,7 +47533,6 @@ struct TypeInfo Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); @@ -48580,12 +47686,6 @@ struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::Typ static constexpr ClusterId GetClusterId() { return Clusters::SampleMei::Id; } }; } // namespace AcceptedCommandList -namespace EventList { -struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo -{ - static constexpr ClusterId GetClusterId() { return Clusters::SampleMei::Id; } -}; -} // namespace EventList namespace AttributeList { struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo { @@ -48616,7 +47716,6 @@ struct TypeInfo Attributes::FlipFlop::TypeInfo::DecodableType flipFlop = static_cast(0); Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; - Attributes::EventList::TypeInfo::DecodableType eventList; Attributes::AttributeList::TypeInfo::DecodableType attributeList; Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); diff --git a/zzz_generated/app-common/app-common/zap-generated/ids/Attributes.h b/zzz_generated/app-common/app-common/zap-generated/ids/Attributes.h index 030d38c2a5d779..8ee5cb21be8e31 100644 --- a/zzz_generated/app-common/app-common/zap-generated/ids/Attributes.h +++ b/zzz_generated/app-common/app-common/zap-generated/ids/Attributes.h @@ -36,10 +36,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = 0x0000FFF9; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = 0x0000FFFA; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = 0x0000FFFB; } // namespace AttributeList @@ -74,10 +70,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -108,10 +100,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -158,10 +146,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -244,10 +228,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -274,10 +254,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -324,10 +300,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -358,10 +330,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -416,10 +384,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -458,10 +422,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -580,10 +540,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -610,10 +566,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -656,10 +608,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -694,10 +642,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -736,10 +680,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -770,10 +710,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -804,10 +740,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -962,10 +894,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -1032,10 +960,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -1106,10 +1030,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -1136,10 +1056,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -1202,10 +1118,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -1248,10 +1160,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -1530,10 +1438,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -1612,10 +1516,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -1678,10 +1578,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -1760,10 +1656,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -1858,10 +1750,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -1900,10 +1788,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -1942,10 +1826,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -1996,10 +1876,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -2042,10 +1918,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -2076,10 +1948,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -2110,10 +1978,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -2140,10 +2004,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -2170,10 +2030,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -2200,10 +2056,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -2234,10 +2086,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -2304,10 +2152,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -2346,10 +2190,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -2400,10 +2240,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -2446,10 +2282,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -2484,10 +2316,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -2538,10 +2366,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -2584,10 +2408,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -2630,10 +2450,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -2676,10 +2492,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -2714,10 +2526,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -2752,10 +2560,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -2806,10 +2610,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -2848,10 +2648,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -2894,10 +2690,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -2928,10 +2720,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -3010,10 +2798,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -3056,10 +2840,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -3094,10 +2874,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -3160,10 +2936,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -3214,10 +2986,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -3268,10 +3036,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -3310,10 +3074,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -3364,10 +3124,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -3418,10 +3174,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -3480,10 +3232,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -3554,10 +3302,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -3660,10 +3404,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -3714,10 +3454,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -3768,10 +3504,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -3830,10 +3562,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -3868,10 +3596,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -3930,10 +3654,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -4052,10 +3772,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -4102,10 +3818,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -4140,10 +3852,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -4178,10 +3886,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -4216,10 +3920,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -4254,10 +3954,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -4464,10 +4160,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -4582,10 +4274,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -4636,10 +4324,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -4758,10 +4442,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -5028,10 +4708,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -5106,10 +4782,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -5148,10 +4820,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -5386,10 +5054,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -5472,10 +5136,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -5522,10 +5182,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -5568,10 +5224,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -5634,10 +5286,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -5680,10 +5328,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -5726,10 +5370,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -5812,10 +5452,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -5886,10 +5522,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -5960,10 +5592,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -6034,10 +5662,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -6108,10 +5732,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -6182,10 +5802,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -6256,10 +5872,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -6330,10 +5942,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -6404,10 +6012,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -6478,10 +6082,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -6552,10 +6152,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -6590,10 +6186,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -6644,10 +6236,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -6686,10 +6274,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -6724,10 +6308,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -6766,10 +6346,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -6804,10 +6380,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -6878,10 +6450,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -6916,10 +6484,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -6946,10 +6510,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -6976,10 +6536,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -7014,10 +6570,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -7052,10 +6604,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -7090,10 +6638,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -7152,10 +6696,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -7182,10 +6722,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -7244,10 +6780,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -7274,10 +6806,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -7320,10 +6848,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -7538,10 +7062,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -7572,10 +7092,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -7606,10 +7122,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -7648,10 +7160,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -7686,10 +7194,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -7720,10 +7224,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -8102,10 +7602,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -8136,10 +7632,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList @@ -8170,10 +7662,6 @@ namespace AcceptedCommandList { static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; } // namespace AcceptedCommandList -namespace EventList { -static constexpr AttributeId Id = Globals::Attributes::EventList::Id; -} // namespace EventList - namespace AttributeList { static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; } // namespace AttributeList diff --git a/zzz_generated/chip-tool/zap-generated/cluster/Commands.h b/zzz_generated/chip-tool/zap-generated/cluster/Commands.h index 244bc725ea5c8b..afcc2abd01d6fb 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/Commands.h +++ b/zzz_generated/chip-tool/zap-generated/cluster/Commands.h @@ -176,7 +176,6 @@ | * IdentifyType | 0x0001 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -274,7 +273,6 @@ class IdentifyTriggerEffect : public ClusterCommand | * NameSupport | 0x0000 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -527,7 +525,6 @@ class GroupsAddGroupIfIdentifying : public ClusterCommand | * StartUpOnOff | 0x4003 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -788,7 +785,6 @@ class OnOffOnWithTimedOff : public ClusterCommand | * StartUpCurrentLevel | 0x4000 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -1161,7 +1157,6 @@ class LevelControlMoveToClosestFrequency : public ClusterCommand | Attributes: | | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -1182,7 +1177,6 @@ class LevelControlMoveToClosestFrequency : public ClusterCommand | * TagList | 0x0004 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -1199,7 +1193,6 @@ class LevelControlMoveToClosestFrequency : public ClusterCommand | * Binding | 0x0000 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -1223,7 +1216,6 @@ class LevelControlMoveToClosestFrequency : public ClusterCommand | * Arl | 0x0006 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -1298,7 +1290,6 @@ class AccessControlReviewFabricRestrictions : public ClusterCommand | * SetupURL | 0x0002 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -1806,7 +1797,6 @@ class ActionsDisableActionWithDuration : public ClusterCommand | * MaxPathsPerInvoke | 0x0016 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -1866,7 +1856,6 @@ class BasicInformationMfgSpecificPing : public ClusterCommand | Attributes: | | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -2012,7 +2001,6 @@ class OtaSoftwareUpdateProviderNotifyUpdateApplied : public ClusterCommand | * UpdateStateProgress | 0x0003 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -2075,7 +2063,6 @@ class OtaSoftwareUpdateRequestorAnnounceOTAProvider : public ClusterCommand | * SupportedLocales | 0x0001 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -2094,7 +2081,6 @@ class OtaSoftwareUpdateRequestorAnnounceOTAProvider : public ClusterCommand | * SupportedCalendarTypes | 0x0002 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -2111,7 +2097,6 @@ class OtaSoftwareUpdateRequestorAnnounceOTAProvider : public ClusterCommand | * TemperatureUnit | 0x0000 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -2128,7 +2113,6 @@ class OtaSoftwareUpdateRequestorAnnounceOTAProvider : public ClusterCommand | * Sources | 0x0000 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -2176,7 +2160,6 @@ class OtaSoftwareUpdateRequestorAnnounceOTAProvider : public ClusterCommand | * EndpointList | 0x001F | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -2209,7 +2192,6 @@ class OtaSoftwareUpdateRequestorAnnounceOTAProvider : public ClusterCommand | * TCUpdateDeadline | 0x0009 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -2398,7 +2380,6 @@ class GeneralCommissioningSetTCAcknowledgements : public ClusterCommand | * ThreadVersion | 0x000A | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -2693,7 +2674,6 @@ class NetworkCommissioningQueryIdentity : public ClusterCommand | Attributes: | | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -2761,7 +2741,6 @@ class DiagnosticLogsRetrieveLogsRequest : public ClusterCommand | * TestEventTriggersEnabled | 0x0008 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -2902,7 +2881,6 @@ class GeneralDiagnosticsPayloadTestRequest : public ClusterCommand | * CurrentHeapHighWatermark | 0x0003 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -3020,7 +2998,6 @@ class SoftwareDiagnosticsResetWatermarks : public ClusterCommand | * ActiveNetworkFaultsList | 0x003E | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -3089,7 +3066,6 @@ class ThreadNetworkDiagnosticsResetCounts : public ClusterCommand | * OverrunCount | 0x000C | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -3155,7 +3131,6 @@ class WiFiNetworkDiagnosticsResetCounts : public ClusterCommand | * TimeSinceReset | 0x0008 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -3226,7 +3201,6 @@ class EthernetNetworkDiagnosticsResetCounts : public ClusterCommand | * SupportsDNSResolve | 0x000C | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -3463,7 +3437,6 @@ class TimeSynchronizationSetDefaultNTP : public ClusterCommand | * ProductAppearance | 0x0014 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -3526,7 +3499,6 @@ class BridgedDeviceBasicInformationKeepActive : public ClusterCommand | * MultiPressMax | 0x0002 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -3555,7 +3527,6 @@ class BridgedDeviceBasicInformationKeepActive : public ClusterCommand | * AdminVendorId | 0x0002 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -3706,7 +3677,6 @@ class AdministratorCommissioningRevokeCommissioning : public ClusterCommand | * CurrentFabricIndex | 0x0005 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -4037,7 +4007,6 @@ class OperationalCredentialsAddTrustedRootCertificate : public ClusterCommand | * MaxGroupKeysPerFabric | 0x0003 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -4205,7 +4174,6 @@ class GroupKeyManagementKeySetReadAllIndices : public ClusterCommand | * LabelList | 0x0000 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -4222,7 +4190,6 @@ class GroupKeyManagementKeySetReadAllIndices : public ClusterCommand | * LabelList | 0x0000 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -4238,7 +4205,6 @@ class GroupKeyManagementKeySetReadAllIndices : public ClusterCommand | Attributes: | | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -4254,7 +4220,6 @@ class GroupKeyManagementKeySetReadAllIndices : public ClusterCommand | Attributes: | | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -4270,7 +4235,6 @@ class GroupKeyManagementKeySetReadAllIndices : public ClusterCommand | Attributes: | | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -4287,7 +4251,6 @@ class GroupKeyManagementKeySetReadAllIndices : public ClusterCommand | * StateValue | 0x0000 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -4317,7 +4280,6 @@ class GroupKeyManagementKeySetReadAllIndices : public ClusterCommand | * MaximumCheckInBackOff | 0x0009 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -4458,7 +4420,6 @@ class IcdManagementStayActiveRequest : public ClusterCommand | * TimerState | 0x0002 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -4631,7 +4592,6 @@ class TimerReduceTime : public ClusterCommand | * OperationalError | 0x0005 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -4798,7 +4758,6 @@ class OvenCavityOperationalStateResume : public ClusterCommand | * OnMode | 0x0003 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -4853,7 +4812,6 @@ class OvenModeChangeToMode : public ClusterCommand | * SelectedDrynessLevel | 0x0001 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -4876,7 +4834,6 @@ class OvenModeChangeToMode : public ClusterCommand | * OnMode | 0x0005 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -4934,7 +4891,6 @@ class ModeSelectChangeToMode : public ClusterCommand | * OnMode | 0x0003 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -4993,7 +4949,6 @@ class LaundryWasherModeChangeToMode : public ClusterCommand | * OnMode | 0x0003 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -5053,7 +5008,6 @@ class RefrigeratorAndTemperatureControlledCabinetModeChangeToMode : public Clust | * SupportedRinses | 0x0003 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -5072,7 +5026,6 @@ class RefrigeratorAndTemperatureControlledCabinetModeChangeToMode : public Clust | * CurrentMode | 0x0001 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -5128,7 +5081,6 @@ class RvcRunModeChangeToMode : public ClusterCommand | * CurrentMode | 0x0001 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -5188,7 +5140,6 @@ class RvcCleanModeChangeToMode : public ClusterCommand | * SupportedTemperatureLevels | 0x0005 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -5246,7 +5197,6 @@ class TemperatureControlSetTemperature : public ClusterCommand | * Supported | 0x0003 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -5268,7 +5218,6 @@ class TemperatureControlSetTemperature : public ClusterCommand | * OnMode | 0x0003 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -5322,7 +5271,6 @@ class DishwasherModeChangeToMode : public ClusterCommand | * AirQuality | 0x0000 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -5352,7 +5300,6 @@ class DishwasherModeChangeToMode : public ClusterCommand | * ExpiryDate | 0x000C | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -5422,7 +5369,6 @@ class SmokeCoAlarmSelfTestRequest : public ClusterCommand | * Supported | 0x0003 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -5516,7 +5462,6 @@ class DishwasherAlarmModifyEnabledAlarms : public ClusterCommand | * CurrentMode | 0x0001 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -5543,7 +5488,6 @@ class DishwasherAlarmModifyEnabledAlarms : public ClusterCommand | * WattRating | 0x0008 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -5649,7 +5593,6 @@ class MicrowaveOvenControlAddMoreTime : public ClusterCommand | * OperationalError | 0x0005 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -5820,7 +5763,6 @@ class OperationalStateResume : public ClusterCommand | * OperationalError | 0x0005 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -5957,7 +5899,6 @@ class RvcOperationalStateGoHome : public ClusterCommand | * FabricSceneInfo | 0x0002 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -6294,7 +6235,6 @@ class ScenesManagementCopyScene : public ClusterCommand | * ReplacementProductList | 0x0005 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -6354,7 +6294,6 @@ class HepaFilterMonitoringResetCondition : public ClusterCommand | * ReplacementProductList | 0x0005 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -6417,7 +6356,6 @@ class ActivatedCarbonFilterMonitoringResetCondition : public ClusterCommand | * SensorFault | 0x0007 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -6524,7 +6462,6 @@ class BooleanStateConfigurationEnableDisableAlarm : public ClusterCommand | * LevelStep | 0x000A | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -6635,7 +6572,6 @@ class ValveConfigurationAndControlClose : public ClusterCommand | * NeutralCurrent | 0x0012 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -6658,7 +6594,6 @@ class ValveConfigurationAndControlClose : public ClusterCommand | * CumulativeEnergyReset | 0x0005 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -6684,7 +6619,6 @@ class ValveConfigurationAndControlClose : public ClusterCommand | * BoostState | 0x0005 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -6791,7 +6725,6 @@ class WaterHeaterManagementCancelBoost : public ClusterCommand | * DefaultRandomDuration | 0x0007 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -7016,7 +6949,6 @@ class DemandResponseLoadControlClearLoadControlEventsRequest : public ClusterCom | * ActiveMessageIDs | 0x0001 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -7137,7 +7069,6 @@ class MessagesCancelMessagesRequest : public ClusterCommand | * OptOutState | 0x0007 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -7503,7 +7434,6 @@ class DeviceEnergyManagementCancelRequest : public ClusterCommand | * SessionEnergyDischarged | 0x0043 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -7794,7 +7724,6 @@ class EnergyEvseClearTargets : public ClusterCommand | * CurrentLowPowerModeSensitivity | 0x0004 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -7812,7 +7741,6 @@ class EnergyEvseClearTargets : public ClusterCommand | * ActiveEndpoints | 0x0001 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -7831,7 +7759,6 @@ class EnergyEvseClearTargets : public ClusterCommand | * CurrentMode | 0x0001 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -7887,7 +7814,6 @@ class EnergyEvseModeChangeToMode : public ClusterCommand | * CurrentMode | 0x0001 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -7943,7 +7869,6 @@ class WaterHeaterModeChangeToMode : public ClusterCommand | * CurrentMode | 0x0001 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -8063,7 +7988,6 @@ class DeviceEnergyManagementModeChangeToMode : public ClusterCommand | * NumberOfAliroEndpointKeysSupported | 0x0088 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -8939,7 +8863,6 @@ class DoorLockClearAliroReaderConfig : public ClusterCommand | * SafetyStatus | 0x001A | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -9223,7 +9146,6 @@ class WindowCoveringGoToTiltPercentage : public ClusterCommand | * Progress | 0x0005 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -9338,7 +9260,6 @@ class ServiceAreaSkipArea : public ClusterCommand | * ControlMode | 0x0021 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -9438,7 +9359,6 @@ class ServiceAreaSkipArea : public ClusterCommand | * SetpointHoldExpiryTimestamp | 0x0052 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -9743,7 +9663,6 @@ class ThermostatAtomicRequest : public ClusterCommand | * AirflowDirection | 0x000B | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -9801,7 +9720,6 @@ class FanControlStep : public ClusterCommand | * ScheduleProgrammingVisibility | 0x0002 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -9888,7 +9806,6 @@ class FanControlStep : public ClusterCommand | * StartUpColorTemperatureMireds | 0x4010 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -10702,7 +10619,6 @@ class ColorControlStepColorTemperature : public ClusterCommand | * LampBurnHoursTripPoint | 0x0035 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -10723,7 +10639,6 @@ class ColorControlStepColorTemperature : public ClusterCommand | * LightSensorType | 0x0004 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -10743,7 +10658,6 @@ class ColorControlStepColorTemperature : public ClusterCommand | * Tolerance | 0x0003 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -10768,7 +10682,6 @@ class ColorControlStepColorTemperature : public ClusterCommand | * Scale | 0x0014 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -10788,7 +10701,6 @@ class ColorControlStepColorTemperature : public ClusterCommand | * Tolerance | 0x0003 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -10808,7 +10720,6 @@ class ColorControlStepColorTemperature : public ClusterCommand | * Tolerance | 0x0003 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -10838,7 +10749,6 @@ class ColorControlStepColorTemperature : public ClusterCommand | * PhysicalContactUnoccupiedToOccupiedThreshold | 0x0032 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -10866,7 +10776,6 @@ class ColorControlStepColorTemperature : public ClusterCommand | * LevelValue | 0x000A | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -10893,7 +10802,6 @@ class ColorControlStepColorTemperature : public ClusterCommand | * LevelValue | 0x000A | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -10920,7 +10828,6 @@ class ColorControlStepColorTemperature : public ClusterCommand | * LevelValue | 0x000A | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -10947,7 +10854,6 @@ class ColorControlStepColorTemperature : public ClusterCommand | * LevelValue | 0x000A | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -10974,7 +10880,6 @@ class ColorControlStepColorTemperature : public ClusterCommand | * LevelValue | 0x000A | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -11001,7 +10906,6 @@ class ColorControlStepColorTemperature : public ClusterCommand | * LevelValue | 0x000A | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -11028,7 +10932,6 @@ class ColorControlStepColorTemperature : public ClusterCommand | * LevelValue | 0x000A | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -11055,7 +10958,6 @@ class ColorControlStepColorTemperature : public ClusterCommand | * LevelValue | 0x000A | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -11082,7 +10984,6 @@ class ColorControlStepColorTemperature : public ClusterCommand | * LevelValue | 0x000A | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -11109,7 +11010,6 @@ class ColorControlStepColorTemperature : public ClusterCommand | * LevelValue | 0x000A | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -11128,7 +11028,6 @@ class ColorControlStepColorTemperature : public ClusterCommand | * PassphraseSurrogate | 0x0001 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -11191,7 +11090,6 @@ class WiFiNetworkManagementNetworkPassphraseRequest : public ClusterCommand | * PendingDatasetTimestamp | 0x0005 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -11372,7 +11270,6 @@ class ThreadBorderRouterManagementSetPendingDatasetRequest : public ClusterComma | * ThreadNetworkTableSize | 0x0002 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -11504,7 +11401,6 @@ class ThreadNetworkDirectoryGetOperationalDataset : public ClusterCommand | * LinkLocalAddress | 0x0001 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -11529,7 +11425,6 @@ class ThreadNetworkDirectoryGetOperationalDataset : public ClusterCommand | * CurrentChannel | 0x0002 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -11799,7 +11694,6 @@ class ChannelCancelRecordProgram : public ClusterCommand | * CurrentTarget | 0x0001 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -11880,7 +11774,6 @@ class TargetNavigatorNavigateTarget : public ClusterCommand | * AvailableTextTracks | 0x000A | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -12418,7 +12311,6 @@ class MediaPlaybackDeactivateTextTrack : public ClusterCommand | * CurrentInput | 0x0001 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -12582,7 +12474,6 @@ class MediaInputRenameInput : public ClusterCommand | Attributes: | | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -12635,7 +12526,6 @@ class LowPowerSleep : public ClusterCommand | Attributes: | | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -12692,7 +12582,6 @@ class KeypadInputSendKey : public ClusterCommand | * SupportedStreamingProtocols | 0x0001 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -12800,7 +12689,6 @@ class ContentLauncherLaunchURL : public ClusterCommand | * CurrentOutput | 0x0001 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -12896,7 +12784,6 @@ class AudioOutputRenameOutput : public ClusterCommand | * CurrentApp | 0x0001 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -13041,7 +12928,6 @@ class ApplicationLauncherHideApp : public ClusterCommand | * AllowedVendorList | 0x0007 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -13060,7 +12946,6 @@ class ApplicationLauncherHideApp : public ClusterCommand | Attributes: | | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -13208,7 +13093,6 @@ class AccountLoginLogout : public ClusterCommand | * BlockUnrated | 0x0007 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -13598,7 +13482,6 @@ class ContentControlSetScheduledContentRatingThreshold : public ClusterCommand | Attributes: | | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -13661,7 +13544,6 @@ class ContentAppObserverContentAppMessage : public ClusterCommand | * Sensitivity | 0x0003 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -13893,7 +13775,6 @@ class ZoneManagementRemoveZone : public ClusterCommand | * DepthSensorStatus | 0x002E | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -14454,7 +14335,6 @@ class CameraAvStreamManagementSetImageFlipVertical : public ClusterCommand | * CurrentSessions | 0x0000 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -14686,7 +14566,6 @@ class WebRTCTransportProviderEndSession : public ClusterCommand | * CurrentSessions | 0x0000 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -14865,7 +14744,6 @@ class WebRTCTransportRequestorEnd : public ClusterCommand | * Enabled | 0x0002 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -14919,7 +14797,6 @@ class ChimePlayChimeSound : public ClusterCommand | * LocationDirectory | 0x0001 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -14938,7 +14815,6 @@ class ChimePlayChimeSound : public ClusterCommand | * SupportedDeviceCategories | 0x0000 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -15150,7 +15026,6 @@ class CommissionerControlCommissionNode : public ClusterCommand | * NullableGlobalStruct | 0x4034 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -16252,7 +16127,6 @@ class UnitTestingTestDifferentVendorMeiRequest : public ClusterCommand | Attributes: | | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -16352,7 +16226,6 @@ class FaultInjectionFailRandomlyAtFault : public ClusterCommand | * FlipFlop | 0x0000 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -16459,7 +16332,6 @@ void registerClusterIdentify(Commands & commands, CredentialIssuerCommands * cre make_unique(Id, "identify-type", Attributes::IdentifyType::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -16473,8 +16345,6 @@ void registerClusterIdentify(Commands & commands, CredentialIssuerCommands * cre credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -16486,7 +16356,6 @@ void registerClusterIdentify(Commands & commands, CredentialIssuerCommands * cre make_unique(Id, "identify-type", Attributes::IdentifyType::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -16523,7 +16392,6 @@ void registerClusterGroups(Commands & commands, CredentialIssuerCommands * creds make_unique(Id, "name-support", Attributes::NameSupport::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -16535,8 +16403,6 @@ void registerClusterGroups(Commands & commands, CredentialIssuerCommands * creds credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -16547,7 +16413,6 @@ void registerClusterGroups(Commands & commands, CredentialIssuerCommands * creds make_unique(Id, "name-support", Attributes::NameSupport::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -16588,7 +16453,6 @@ void registerClusterOnOff(Commands & commands, CredentialIssuerCommands * credsI make_unique(Id, "start-up-on-off", Attributes::StartUpOnOff::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -16608,8 +16472,6 @@ void registerClusterOnOff(Commands & commands, CredentialIssuerCommands * credsI credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -16624,7 +16486,6 @@ void registerClusterOnOff(Commands & commands, CredentialIssuerCommands * credsI make_unique(Id, "start-up-on-off", Attributes::StartUpOnOff::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -16677,7 +16538,6 @@ void registerClusterLevelControl(Commands & commands, CredentialIssuerCommands * make_unique(Id, "start-up-current-level", Attributes::StartUpCurrentLevel::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -16718,8 +16578,6 @@ void registerClusterLevelControl(Commands & commands, CredentialIssuerCommands * credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -16743,7 +16601,6 @@ void registerClusterLevelControl(Commands & commands, CredentialIssuerCommands * make_unique(Id, "start-up-current-level", Attributes::StartUpCurrentLevel::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -16773,7 +16630,6 @@ void registerClusterPulseWidthModulation(Commands & commands, CredentialIssuerCo make_unique(Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -16783,8 +16639,6 @@ void registerClusterPulseWidthModulation(Commands & commands, CredentialIssuerCo credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -16794,7 +16648,6 @@ void registerClusterPulseWidthModulation(Commands & commands, CredentialIssuerCo make_unique(Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -16829,7 +16682,6 @@ void registerClusterDescriptor(Commands & commands, CredentialIssuerCommands * c make_unique(Id, "tag-list", Attributes::TagList::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -16851,8 +16703,6 @@ void registerClusterDescriptor(Commands & commands, CredentialIssuerCommands * c credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -16867,7 +16717,6 @@ void registerClusterDescriptor(Commands & commands, CredentialIssuerCommands * c make_unique(Id, "tag-list", Attributes::TagList::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -16898,7 +16747,6 @@ void registerClusterBinding(Commands & commands, CredentialIssuerCommands * cred make_unique(Id, "binding", Attributes::Binding::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -16911,8 +16759,6 @@ void registerClusterBinding(Commands & commands, CredentialIssuerCommands * cred credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -16923,7 +16769,6 @@ void registerClusterBinding(Commands & commands, CredentialIssuerCommands * cred make_unique(Id, "binding", Attributes::Binding::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -16964,7 +16809,6 @@ void registerClusterAccessControl(Commands & commands, CredentialIssuerCommands make_unique(Id, "arl", Attributes::Arl::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -16995,8 +16839,6 @@ void registerClusterAccessControl(Commands & commands, CredentialIssuerCommands credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -17016,7 +16858,6 @@ void registerClusterAccessControl(Commands & commands, CredentialIssuerCommands make_unique(Id, "arl", Attributes::Arl::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -17072,7 +16913,6 @@ void registerClusterActions(Commands & commands, CredentialIssuerCommands * cred make_unique(Id, "setup-url", Attributes::SetupURL::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -17090,8 +16930,6 @@ void registerClusterActions(Commands & commands, CredentialIssuerCommands * cred credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -17104,7 +16942,6 @@ void registerClusterActions(Commands & commands, CredentialIssuerCommands * cred make_unique(Id, "setup-url", Attributes::SetupURL::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -17162,7 +16999,6 @@ void registerClusterBasicInformation(Commands & commands, CredentialIssuerComman make_unique(Id, "max-paths-per-invoke", Attributes::MaxPathsPerInvoke::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -17218,8 +17054,6 @@ void registerClusterBasicInformation(Commands & commands, CredentialIssuerComman credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -17252,7 +17086,6 @@ void registerClusterBasicInformation(Commands & commands, CredentialIssuerComman make_unique(Id, "max-paths-per-invoke", Attributes::MaxPathsPerInvoke::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -17293,7 +17126,6 @@ void registerClusterOtaSoftwareUpdateProvider(Commands & commands, CredentialIss make_unique(Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -17303,8 +17135,6 @@ void registerClusterOtaSoftwareUpdateProvider(Commands & commands, CredentialIss credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -17314,7 +17144,6 @@ void registerClusterOtaSoftwareUpdateProvider(Commands & commands, CredentialIss make_unique(Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -17349,7 +17178,6 @@ void registerClusterOtaSoftwareUpdateRequestor(Commands & commands, CredentialIs make_unique(Id, "update-state-progress", Attributes::UpdateStateProgress::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -17369,8 +17197,6 @@ void registerClusterOtaSoftwareUpdateRequestor(Commands & commands, CredentialIs credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -17384,7 +17210,6 @@ void registerClusterOtaSoftwareUpdateRequestor(Commands & commands, CredentialIs make_unique(Id, "update-state-progress", Attributes::UpdateStateProgress::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -17422,7 +17247,6 @@ void registerClusterLocalizationConfiguration(Commands & commands, CredentialIss make_unique(Id, "supported-locales", Attributes::SupportedLocales::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -17436,8 +17260,6 @@ void registerClusterLocalizationConfiguration(Commands & commands, CredentialIss credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -17449,7 +17271,6 @@ void registerClusterLocalizationConfiguration(Commands & commands, CredentialIss make_unique(Id, "supported-locales", Attributes::SupportedLocales::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -17482,7 +17303,6 @@ void registerClusterTimeFormatLocalization(Commands & commands, CredentialIssuer make_unique(Id, "supported-calendar-types", Attributes::SupportedCalendarTypes::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -17501,8 +17321,6 @@ void registerClusterTimeFormatLocalization(Commands & commands, CredentialIssuer credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -17516,7 +17334,6 @@ void registerClusterTimeFormatLocalization(Commands & commands, CredentialIssuer credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -17547,7 +17364,6 @@ void registerClusterUnitLocalization(Commands & commands, CredentialIssuerComman make_unique(Id, "temperature-unit", Attributes::TemperatureUnit::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -17559,8 +17375,6 @@ void registerClusterUnitLocalization(Commands & commands, CredentialIssuerComman credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -17571,7 +17385,6 @@ void registerClusterUnitLocalization(Commands & commands, CredentialIssuerComman make_unique(Id, "temperature-unit", Attributes::TemperatureUnit::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -17602,7 +17415,6 @@ void registerClusterPowerSourceConfiguration(Commands & commands, CredentialIssu make_unique(Id, "sources", Attributes::Sources::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -17614,8 +17426,6 @@ void registerClusterPowerSourceConfiguration(Commands & commands, CredentialIssu credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -17626,7 +17436,6 @@ void registerClusterPowerSourceConfiguration(Commands & commands, CredentialIssu make_unique(Id, "sources", Attributes::Sources::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -17692,7 +17501,6 @@ void registerClusterPowerSource(Commands & commands, CredentialIssuerCommands * make_unique(Id, "endpoint-list", Attributes::EndpointList::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -17781,8 +17589,6 @@ void registerClusterPowerSource(Commands & commands, CredentialIssuerCommands * credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -17829,7 +17635,6 @@ void registerClusterPowerSource(Commands & commands, CredentialIssuerCommands * make_unique(Id, "endpoint-list", Attributes::EndpointList::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -17881,7 +17686,6 @@ void registerClusterGeneralCommissioning(Commands & commands, CredentialIssuerCo make_unique(Id, "tcupdate-deadline", Attributes::TCUpdateDeadline::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -17914,8 +17718,6 @@ void registerClusterGeneralCommissioning(Commands & commands, CredentialIssuerCo credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -17938,7 +17740,6 @@ void registerClusterGeneralCommissioning(Commands & commands, CredentialIssuerCo make_unique(Id, "tcupdate-deadline", Attributes::TCUpdateDeadline::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -17986,7 +17787,6 @@ void registerClusterNetworkCommissioning(Commands & commands, CredentialIssuerCo make_unique(Id, "thread-version", Attributes::ThreadVersion::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -18024,8 +17824,6 @@ void registerClusterNetworkCommissioning(Commands & commands, CredentialIssuerCo credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -18049,7 +17847,6 @@ void registerClusterNetworkCommissioning(Commands & commands, CredentialIssuerCo make_unique(Id, "thread-version", Attributes::ThreadVersion::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -18080,7 +17877,6 @@ void registerClusterDiagnosticLogs(Commands & commands, CredentialIssuerCommands make_unique(Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -18090,8 +17886,6 @@ void registerClusterDiagnosticLogs(Commands & commands, CredentialIssuerCommands credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -18101,7 +17895,6 @@ void registerClusterDiagnosticLogs(Commands & commands, CredentialIssuerCommands make_unique(Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -18144,7 +17937,6 @@ void registerClusterGeneralDiagnostics(Commands & commands, CredentialIssuerComm credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -18177,8 +17969,6 @@ void registerClusterGeneralDiagnostics(Commands & commands, CredentialIssuerComm credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -18198,7 +17988,6 @@ void registerClusterGeneralDiagnostics(Commands & commands, CredentialIssuerComm credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -18242,7 +18031,6 @@ void registerClusterSoftwareDiagnostics(Commands & commands, CredentialIssuerCom credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -18262,8 +18050,6 @@ void registerClusterSoftwareDiagnostics(Commands & commands, CredentialIssuerCom credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -18278,7 +18064,6 @@ void registerClusterSoftwareDiagnostics(Commands & commands, CredentialIssuerCom credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -18381,7 +18166,6 @@ void registerClusterThreadNetworkDiagnostics(Commands & commands, CredentialIssu make_unique(Id, "active-network-faults-list", Attributes::ActiveNetworkFaultsList::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -18537,8 +18321,6 @@ void registerClusterThreadNetworkDiagnostics(Commands & commands, CredentialIssu credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -18623,7 +18405,6 @@ void registerClusterThreadNetworkDiagnostics(Commands & commands, CredentialIssu credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -18671,7 +18452,6 @@ void registerClusterWiFiNetworkDiagnostics(Commands & commands, CredentialIssuer make_unique(Id, "overrun-count", Attributes::OverrunCount::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -18715,8 +18495,6 @@ void registerClusterWiFiNetworkDiagnostics(Commands & commands, CredentialIssuer credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -18741,7 +18519,6 @@ void registerClusterWiFiNetworkDiagnostics(Commands & commands, CredentialIssuer make_unique(Id, "overrun-count", Attributes::OverrunCount::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -18787,7 +18564,6 @@ void registerClusterEthernetNetworkDiagnostics(Commands & commands, CredentialIs make_unique(Id, "time-since-reset", Attributes::TimeSinceReset::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -18815,8 +18591,6 @@ void registerClusterEthernetNetworkDiagnostics(Commands & commands, CredentialIs credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -18835,7 +18609,6 @@ void registerClusterEthernetNetworkDiagnostics(Commands & commands, CredentialIs make_unique(Id, "time-since-reset", Attributes::TimeSinceReset::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -18883,7 +18656,6 @@ void registerClusterTimeSynchronization(Commands & commands, CredentialIssuerCom make_unique(Id, "supports-dnsresolve", Attributes::SupportsDNSResolve::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -18923,8 +18695,6 @@ void registerClusterTimeSynchronization(Commands & commands, CredentialIssuerCom credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -18947,7 +18717,6 @@ void registerClusterTimeSynchronization(Commands & commands, CredentialIssuerCom make_unique(Id, "supports-dnsresolve", Attributes::SupportsDNSResolve::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -19005,7 +18774,6 @@ void registerClusterBridgedDeviceBasicInformation(Commands & commands, Credentia make_unique(Id, "product-appearance", Attributes::ProductAppearance::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -19050,8 +18818,6 @@ void registerClusterBridgedDeviceBasicInformation(Commands & commands, Credentia credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -19078,7 +18844,6 @@ void registerClusterBridgedDeviceBasicInformation(Commands & commands, Credentia make_unique(Id, "product-appearance", Attributes::ProductAppearance::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -19121,7 +18886,6 @@ void registerClusterSwitch(Commands & commands, CredentialIssuerCommands * creds make_unique(Id, "multi-press-max", Attributes::MultiPressMax::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -19137,8 +18901,6 @@ void registerClusterSwitch(Commands & commands, CredentialIssuerCommands * creds credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -19151,7 +18913,6 @@ void registerClusterSwitch(Commands & commands, CredentialIssuerCommands * creds make_unique(Id, "multi-press-max", Attributes::MultiPressMax::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -19201,7 +18962,6 @@ void registerClusterAdministratorCommissioning(Commands & commands, CredentialIs make_unique(Id, "admin-vendor-id", Attributes::AdminVendorId::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -19219,8 +18979,6 @@ void registerClusterAdministratorCommissioning(Commands & commands, CredentialIs credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -19233,7 +18991,6 @@ void registerClusterAdministratorCommissioning(Commands & commands, CredentialIs make_unique(Id, "admin-vendor-id", Attributes::AdminVendorId::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -19277,7 +19034,6 @@ void registerClusterOperationalCredentials(Commands & commands, CredentialIssuer make_unique(Id, "current-fabric-index", Attributes::CurrentFabricIndex::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -19302,8 +19058,6 @@ void registerClusterOperationalCredentials(Commands & commands, CredentialIssuer credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -19320,7 +19074,6 @@ void registerClusterOperationalCredentials(Commands & commands, CredentialIssuer make_unique(Id, "current-fabric-index", Attributes::CurrentFabricIndex::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -19358,7 +19111,6 @@ void registerClusterGroupKeyManagement(Commands & commands, CredentialIssuerComm make_unique(Id, "max-group-keys-per-fabric", Attributes::MaxGroupKeysPerFabric::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -19378,8 +19130,6 @@ void registerClusterGroupKeyManagement(Commands & commands, CredentialIssuerComm credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -19394,7 +19144,6 @@ void registerClusterGroupKeyManagement(Commands & commands, CredentialIssuerComm credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -19425,7 +19174,6 @@ void registerClusterFixedLabel(Commands & commands, CredentialIssuerCommands * c make_unique(Id, "label-list", Attributes::LabelList::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -19438,8 +19186,6 @@ void registerClusterFixedLabel(Commands & commands, CredentialIssuerCommands * c credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -19450,7 +19196,6 @@ void registerClusterFixedLabel(Commands & commands, CredentialIssuerCommands * c make_unique(Id, "label-list", Attributes::LabelList::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -19481,7 +19226,6 @@ void registerClusterUserLabel(Commands & commands, CredentialIssuerCommands * cr make_unique(Id, "label-list", Attributes::LabelList::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -19494,8 +19238,6 @@ void registerClusterUserLabel(Commands & commands, CredentialIssuerCommands * cr credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -19506,7 +19248,6 @@ void registerClusterUserLabel(Commands & commands, CredentialIssuerCommands * cr make_unique(Id, "label-list", Attributes::LabelList::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -19536,7 +19277,6 @@ void registerClusterProxyConfiguration(Commands & commands, CredentialIssuerComm make_unique(Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -19546,8 +19286,6 @@ void registerClusterProxyConfiguration(Commands & commands, CredentialIssuerComm credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -19557,7 +19295,6 @@ void registerClusterProxyConfiguration(Commands & commands, CredentialIssuerComm make_unique(Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -19587,7 +19324,6 @@ void registerClusterProxyDiscovery(Commands & commands, CredentialIssuerCommands make_unique(Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -19597,8 +19333,6 @@ void registerClusterProxyDiscovery(Commands & commands, CredentialIssuerCommands credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -19608,7 +19342,6 @@ void registerClusterProxyDiscovery(Commands & commands, CredentialIssuerCommands make_unique(Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -19638,7 +19371,6 @@ void registerClusterProxyValid(Commands & commands, CredentialIssuerCommands * c make_unique(Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -19648,8 +19380,6 @@ void registerClusterProxyValid(Commands & commands, CredentialIssuerCommands * c credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -19659,7 +19389,6 @@ void registerClusterProxyValid(Commands & commands, CredentialIssuerCommands * c make_unique(Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -19690,7 +19419,6 @@ void registerClusterBooleanState(Commands & commands, CredentialIssuerCommands * make_unique(Id, "state-value", Attributes::StateValue::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -19702,8 +19430,6 @@ void registerClusterBooleanState(Commands & commands, CredentialIssuerCommands * credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -19714,7 +19440,6 @@ void registerClusterBooleanState(Commands & commands, CredentialIssuerCommands * make_unique(Id, "state-value", Attributes::StateValue::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -19762,7 +19487,6 @@ void registerClusterIcdManagement(Commands & commands, CredentialIssuerCommands make_unique(Id, "maximum-check-in-back-off", Attributes::MaximumCheckInBackOff::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -19796,8 +19520,6 @@ void registerClusterIcdManagement(Commands & commands, CredentialIssuerCommands credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -19821,7 +19543,6 @@ void registerClusterIcdManagement(Commands & commands, CredentialIssuerCommands credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -19858,7 +19579,6 @@ void registerClusterTimer(Commands & commands, CredentialIssuerCommands * credsI make_unique(Id, "timer-state", Attributes::TimerState::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -19874,8 +19594,6 @@ void registerClusterTimer(Commands & commands, CredentialIssuerCommands * credsI credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -19888,7 +19606,6 @@ void registerClusterTimer(Commands & commands, CredentialIssuerCommands * credsI make_unique(Id, "timer-state", Attributes::TimerState::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -19928,7 +19645,6 @@ void registerClusterOvenCavityOperationalState(Commands & commands, CredentialIs make_unique(Id, "operational-error", Attributes::OperationalError::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -19954,8 +19670,6 @@ void registerClusterOvenCavityOperationalState(Commands & commands, CredentialIs credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -19971,7 +19685,6 @@ void registerClusterOvenCavityOperationalState(Commands & commands, CredentialIs make_unique(Id, "operational-error", Attributes::OperationalError::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -20010,7 +19723,6 @@ void registerClusterOvenMode(Commands & commands, CredentialIssuerCommands * cre make_unique(Id, "on-mode", Attributes::OnMode::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -20029,8 +19741,6 @@ void registerClusterOvenMode(Commands & commands, CredentialIssuerCommands * cre credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -20044,7 +19754,6 @@ void registerClusterOvenMode(Commands & commands, CredentialIssuerCommands * cre make_unique(Id, "on-mode", Attributes::OnMode::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -20076,7 +19785,6 @@ void registerClusterLaundryDryerControls(Commands & commands, CredentialIssuerCo make_unique(Id, "selected-dryness-level", Attributes::SelectedDrynessLevel::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -20093,8 +19801,6 @@ void registerClusterLaundryDryerControls(Commands & commands, CredentialIssuerCo credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -20107,7 +19813,6 @@ void registerClusterLaundryDryerControls(Commands & commands, CredentialIssuerCo make_unique(Id, "selected-dryness-level", Attributes::SelectedDrynessLevel::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -20144,7 +19849,6 @@ void registerClusterModeSelect(Commands & commands, CredentialIssuerCommands * c make_unique(Id, "on-mode", Attributes::OnMode::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -20168,8 +19872,6 @@ void registerClusterModeSelect(Commands & commands, CredentialIssuerCommands * c credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -20185,7 +19887,6 @@ void registerClusterModeSelect(Commands & commands, CredentialIssuerCommands * c make_unique(Id, "on-mode", Attributes::OnMode::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -20220,7 +19921,6 @@ void registerClusterLaundryWasherMode(Commands & commands, CredentialIssuerComma make_unique(Id, "on-mode", Attributes::OnMode::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -20239,8 +19939,6 @@ void registerClusterLaundryWasherMode(Commands & commands, CredentialIssuerComma credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -20254,7 +19952,6 @@ void registerClusterLaundryWasherMode(Commands & commands, CredentialIssuerComma make_unique(Id, "on-mode", Attributes::OnMode::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -20290,7 +19987,6 @@ void registerClusterRefrigeratorAndTemperatureControlledCabinetMode(Commands & c make_unique(Id, "on-mode", Attributes::OnMode::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -20309,8 +20005,6 @@ void registerClusterRefrigeratorAndTemperatureControlledCabinetMode(Commands & c credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -20324,7 +20018,6 @@ void registerClusterRefrigeratorAndTemperatureControlledCabinetMode(Commands & c make_unique(Id, "on-mode", Attributes::OnMode::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -20358,7 +20051,6 @@ void registerClusterLaundryWasherControls(Commands & commands, CredentialIssuerC make_unique(Id, "supported-rinses", Attributes::SupportedRinses::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -20378,8 +20070,6 @@ void registerClusterLaundryWasherControls(Commands & commands, CredentialIssuerC credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -20393,7 +20083,6 @@ void registerClusterLaundryWasherControls(Commands & commands, CredentialIssuerC make_unique(Id, "supported-rinses", Attributes::SupportedRinses::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -20426,7 +20115,6 @@ void registerClusterRvcRunMode(Commands & commands, CredentialIssuerCommands * c make_unique(Id, "current-mode", Attributes::CurrentMode::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -20441,8 +20129,6 @@ void registerClusterRvcRunMode(Commands & commands, CredentialIssuerCommands * c credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -20454,7 +20140,6 @@ void registerClusterRvcRunMode(Commands & commands, CredentialIssuerCommands * c make_unique(Id, "current-mode", Attributes::CurrentMode::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -20487,7 +20172,6 @@ void registerClusterRvcCleanMode(Commands & commands, CredentialIssuerCommands * make_unique(Id, "current-mode", Attributes::CurrentMode::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -20502,8 +20186,6 @@ void registerClusterRvcCleanMode(Commands & commands, CredentialIssuerCommands * credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -20515,7 +20197,6 @@ void registerClusterRvcCleanMode(Commands & commands, CredentialIssuerCommands * make_unique(Id, "current-mode", Attributes::CurrentMode::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -20554,7 +20235,6 @@ void registerClusterTemperatureControl(Commands & commands, CredentialIssuerComm credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -20578,8 +20258,6 @@ void registerClusterTemperatureControl(Commands & commands, CredentialIssuerComm credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -20597,7 +20275,6 @@ void registerClusterTemperatureControl(Commands & commands, CredentialIssuerComm credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -20630,7 +20307,6 @@ void registerClusterRefrigeratorAlarm(Commands & commands, CredentialIssuerComma make_unique(Id, "supported", Attributes::Supported::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -20646,8 +20322,6 @@ void registerClusterRefrigeratorAlarm(Commands & commands, CredentialIssuerComma credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -20660,7 +20334,6 @@ void registerClusterRefrigeratorAlarm(Commands & commands, CredentialIssuerComma make_unique(Id, "supported", Attributes::Supported::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -20697,7 +20370,6 @@ void registerClusterDishwasherMode(Commands & commands, CredentialIssuerCommands make_unique(Id, "on-mode", Attributes::OnMode::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -20716,8 +20388,6 @@ void registerClusterDishwasherMode(Commands & commands, CredentialIssuerCommands credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -20731,7 +20401,6 @@ void registerClusterDishwasherMode(Commands & commands, CredentialIssuerCommands make_unique(Id, "on-mode", Attributes::OnMode::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -20762,7 +20431,6 @@ void registerClusterAirQuality(Commands & commands, CredentialIssuerCommands * c make_unique(Id, "air-quality", Attributes::AirQuality::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -20774,8 +20442,6 @@ void registerClusterAirQuality(Commands & commands, CredentialIssuerCommands * c credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -20786,7 +20452,6 @@ void registerClusterAirQuality(Commands & commands, CredentialIssuerCommands * c make_unique(Id, "air-quality", Attributes::AirQuality::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -20830,7 +20495,6 @@ void registerClusterSmokeCoAlarm(Commands & commands, CredentialIssuerCommands * make_unique(Id, "expiry-date", Attributes::ExpiryDate::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -20872,8 +20536,6 @@ void registerClusterSmokeCoAlarm(Commands & commands, CredentialIssuerCommands * credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -20897,7 +20559,6 @@ void registerClusterSmokeCoAlarm(Commands & commands, CredentialIssuerCommands * make_unique(Id, "expiry-date", Attributes::ExpiryDate::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -20955,7 +20616,6 @@ void registerClusterDishwasherAlarm(Commands & commands, CredentialIssuerCommand make_unique(Id, "supported", Attributes::Supported::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -20973,8 +20633,6 @@ void registerClusterDishwasherAlarm(Commands & commands, CredentialIssuerCommand credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -20988,7 +20646,6 @@ void registerClusterDishwasherAlarm(Commands & commands, CredentialIssuerCommand make_unique(Id, "supported", Attributes::Supported::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -21022,7 +20679,6 @@ void registerClusterMicrowaveOvenMode(Commands & commands, CredentialIssuerComma make_unique(Id, "current-mode", Attributes::CurrentMode::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -21037,8 +20693,6 @@ void registerClusterMicrowaveOvenMode(Commands & commands, CredentialIssuerComma credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -21050,7 +20704,6 @@ void registerClusterMicrowaveOvenMode(Commands & commands, CredentialIssuerComma make_unique(Id, "current-mode", Attributes::CurrentMode::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -21091,7 +20744,6 @@ void registerClusterMicrowaveOvenControl(Commands & commands, CredentialIssuerCo make_unique(Id, "watt-rating", Attributes::WattRating::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -21119,8 +20771,6 @@ void registerClusterMicrowaveOvenControl(Commands & commands, CredentialIssuerCo credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -21139,7 +20789,6 @@ void registerClusterMicrowaveOvenControl(Commands & commands, CredentialIssuerCo make_unique(Id, "watt-rating", Attributes::WattRating::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -21179,7 +20828,6 @@ void registerClusterOperationalState(Commands & commands, CredentialIssuerComman make_unique(Id, "operational-error", Attributes::OperationalError::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -21205,8 +20853,6 @@ void registerClusterOperationalState(Commands & commands, CredentialIssuerComman credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -21222,7 +20868,6 @@ void registerClusterOperationalState(Commands & commands, CredentialIssuerComman make_unique(Id, "operational-error", Attributes::OperationalError::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -21265,7 +20910,6 @@ void registerClusterRvcOperationalState(Commands & commands, CredentialIssuerCom make_unique(Id, "operational-error", Attributes::OperationalError::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -21290,8 +20934,6 @@ void registerClusterRvcOperationalState(Commands & commands, CredentialIssuerCom credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -21307,7 +20949,6 @@ void registerClusterRvcOperationalState(Commands & commands, CredentialIssuerCom make_unique(Id, "operational-error", Attributes::OperationalError::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -21352,7 +20993,6 @@ void registerClusterScenesManagement(Commands & commands, CredentialIssuerComman make_unique(Id, "fabric-scene-info", Attributes::FabricSceneInfo::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -21370,8 +21010,6 @@ void registerClusterScenesManagement(Commands & commands, CredentialIssuerComman credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -21384,7 +21022,6 @@ void registerClusterScenesManagement(Commands & commands, CredentialIssuerComman make_unique(Id, "fabric-scene-info", Attributes::FabricSceneInfo::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -21421,7 +21058,6 @@ void registerClusterHepaFilterMonitoring(Commands & commands, CredentialIssuerCo make_unique(Id, "replacement-product-list", Attributes::ReplacementProductList::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -21448,8 +21084,6 @@ void registerClusterHepaFilterMonitoring(Commands & commands, CredentialIssuerCo credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -21466,7 +21100,6 @@ void registerClusterHepaFilterMonitoring(Commands & commands, CredentialIssuerCo credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -21503,7 +21136,6 @@ void registerClusterActivatedCarbonFilterMonitoring(Commands & commands, Credent make_unique(Id, "replacement-product-list", Attributes::ReplacementProductList::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -21530,8 +21162,6 @@ void registerClusterActivatedCarbonFilterMonitoring(Commands & commands, Credent credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -21548,7 +21178,6 @@ void registerClusterActivatedCarbonFilterMonitoring(Commands & commands, Credent credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -21589,7 +21218,6 @@ void registerClusterBooleanStateConfiguration(Commands & commands, CredentialIss make_unique(Id, "sensor-fault", Attributes::SensorFault::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -21618,8 +21246,6 @@ void registerClusterBooleanStateConfiguration(Commands & commands, CredentialIss credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -21640,7 +21266,6 @@ void registerClusterBooleanStateConfiguration(Commands & commands, CredentialIss make_unique(Id, "sensor-fault", Attributes::SensorFault::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -21687,7 +21312,6 @@ void registerClusterValveConfigurationAndControl(Commands & commands, Credential make_unique(Id, "level-step", Attributes::LevelStep::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -21724,8 +21348,6 @@ void registerClusterValveConfigurationAndControl(Commands & commands, Credential credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -21746,7 +21368,6 @@ void registerClusterValveConfigurationAndControl(Commands & commands, Credential make_unique(Id, "level-step", Attributes::LevelStep::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -21800,7 +21421,6 @@ void registerClusterElectricalPowerMeasurement(Commands & commands, CredentialIs make_unique(Id, "neutral-current", Attributes::NeutralCurrent::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -21863,8 +21483,6 @@ void registerClusterElectricalPowerMeasurement(Commands & commands, CredentialIs credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -21894,7 +21512,6 @@ void registerClusterElectricalPowerMeasurement(Commands & commands, CredentialIs make_unique(Id, "neutral-current", Attributes::NeutralCurrent::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -21934,7 +21551,6 @@ void registerClusterElectricalEnergyMeasurement(Commands & commands, CredentialI make_unique(Id, "cumulative-energy-reset", Attributes::CumulativeEnergyReset::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -21967,8 +21583,6 @@ void registerClusterElectricalEnergyMeasurement(Commands & commands, CredentialI credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -21988,7 +21602,6 @@ void registerClusterElectricalEnergyMeasurement(Commands & commands, CredentialI make_unique(Id, "cumulative-energy-reset", Attributes::CumulativeEnergyReset::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -22030,7 +21643,6 @@ void registerClusterWaterHeaterManagement(Commands & commands, CredentialIssuerC make_unique(Id, "boost-state", Attributes::BoostState::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -22053,8 +21665,6 @@ void registerClusterWaterHeaterManagement(Commands & commands, CredentialIssuerC credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -22070,7 +21680,6 @@ void registerClusterWaterHeaterManagement(Commands & commands, CredentialIssuerC make_unique(Id, "boost-state", Attributes::BoostState::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -22119,7 +21728,6 @@ void registerClusterDemandResponseLoadControl(Commands & commands, CredentialIss make_unique(Id, "default-random-duration", Attributes::DefaultRandomDuration::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -22150,8 +21758,6 @@ void registerClusterDemandResponseLoadControl(Commands & commands, CredentialIss credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -22171,7 +21777,6 @@ void registerClusterDemandResponseLoadControl(Commands & commands, CredentialIss make_unique(Id, "default-random-duration", Attributes::DefaultRandomDuration::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -22209,7 +21814,6 @@ void registerClusterMessages(Commands & commands, CredentialIssuerCommands * cre make_unique(Id, "active-message-ids", Attributes::ActiveMessageIDs::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -22224,8 +21828,6 @@ void registerClusterMessages(Commands & commands, CredentialIssuerCommands * cre credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -22237,7 +21839,6 @@ void registerClusterMessages(Commands & commands, CredentialIssuerCommands * cre make_unique(Id, "active-message-ids", Attributes::ActiveMessageIDs::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -22290,7 +21891,6 @@ void registerClusterDeviceEnergyManagement(Commands & commands, CredentialIssuer make_unique(Id, "opt-out-state", Attributes::OptOutState::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -22319,8 +21919,6 @@ void registerClusterDeviceEnergyManagement(Commands & commands, CredentialIssuer credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -22339,7 +21937,6 @@ void registerClusterDeviceEnergyManagement(Commands & commands, CredentialIssuer make_unique(Id, "opt-out-state", Attributes::OptOutState::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -22410,7 +22007,6 @@ void registerClusterEnergyEvse(Commands & commands, CredentialIssuerCommands * c make_unique(Id, "session-energy-discharged", Attributes::SessionEnergyDischarged::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -22483,8 +22079,6 @@ void registerClusterEnergyEvse(Commands & commands, CredentialIssuerCommands * c credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -22524,7 +22118,6 @@ void registerClusterEnergyEvse(Commands & commands, CredentialIssuerCommands * c credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -22573,7 +22166,6 @@ void registerClusterEnergyPreference(Commands & commands, CredentialIssuerComman credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -22598,8 +22190,6 @@ void registerClusterEnergyPreference(Commands & commands, CredentialIssuerComman credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -22616,7 +22206,6 @@ void registerClusterEnergyPreference(Commands & commands, CredentialIssuerComman credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -22648,7 +22237,6 @@ void registerClusterPowerTopology(Commands & commands, CredentialIssuerCommands make_unique(Id, "active-endpoints", Attributes::ActiveEndpoints::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -22662,8 +22250,6 @@ void registerClusterPowerTopology(Commands & commands, CredentialIssuerCommands credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -22675,7 +22261,6 @@ void registerClusterPowerTopology(Commands & commands, CredentialIssuerCommands make_unique(Id, "active-endpoints", Attributes::ActiveEndpoints::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -22708,7 +22293,6 @@ void registerClusterEnergyEvseMode(Commands & commands, CredentialIssuerCommands make_unique(Id, "current-mode", Attributes::CurrentMode::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -22723,8 +22307,6 @@ void registerClusterEnergyEvseMode(Commands & commands, CredentialIssuerCommands credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -22736,7 +22318,6 @@ void registerClusterEnergyEvseMode(Commands & commands, CredentialIssuerCommands make_unique(Id, "current-mode", Attributes::CurrentMode::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -22769,7 +22350,6 @@ void registerClusterWaterHeaterMode(Commands & commands, CredentialIssuerCommand make_unique(Id, "current-mode", Attributes::CurrentMode::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -22784,8 +22364,6 @@ void registerClusterWaterHeaterMode(Commands & commands, CredentialIssuerCommand credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -22797,7 +22375,6 @@ void registerClusterWaterHeaterMode(Commands & commands, CredentialIssuerCommand make_unique(Id, "current-mode", Attributes::CurrentMode::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -22830,7 +22407,6 @@ void registerClusterDeviceEnergyManagementMode(Commands & commands, CredentialIs make_unique(Id, "current-mode", Attributes::CurrentMode::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -22845,8 +22421,6 @@ void registerClusterDeviceEnergyManagementMode(Commands & commands, CredentialIs credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -22858,7 +22432,6 @@ void registerClusterDeviceEnergyManagementMode(Commands & commands, CredentialIs make_unique(Id, "current-mode", Attributes::CurrentMode::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -22973,7 +22546,6 @@ void registerClusterDoorLock(Commands & commands, CredentialIssuerCommands * cre Attributes::NumberOfAliroEndpointKeysSupported::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -23095,8 +22667,6 @@ void registerClusterDoorLock(Commands & commands, CredentialIssuerCommands * cre credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -23177,7 +22747,6 @@ void registerClusterDoorLock(Commands & commands, CredentialIssuerCommands * cre Attributes::NumberOfAliroEndpointKeysSupported::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -23254,7 +22823,6 @@ void registerClusterWindowCovering(Commands & commands, CredentialIssuerCommands make_unique(Id, "safety-status", Attributes::SafetyStatus::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -23326,8 +22894,6 @@ void registerClusterWindowCovering(Commands & commands, CredentialIssuerCommands credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -23373,7 +22939,6 @@ void registerClusterWindowCovering(Commands & commands, CredentialIssuerCommands make_unique(Id, "safety-status", Attributes::SafetyStatus::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -23411,7 +22976,6 @@ void registerClusterServiceArea(Commands & commands, CredentialIssuerCommands * make_unique(Id, "progress", Attributes::Progress::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -23437,8 +23001,6 @@ void registerClusterServiceArea(Commands & commands, CredentialIssuerCommands * credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -23454,7 +23016,6 @@ void registerClusterServiceArea(Commands & commands, CredentialIssuerCommands * make_unique(Id, "progress", Attributes::Progress::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -23507,7 +23068,6 @@ void registerClusterPumpConfigurationAndControl(Commands & commands, CredentialI make_unique(Id, "control-mode", Attributes::ControlMode::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -23576,8 +23136,6 @@ void registerClusterPumpConfigurationAndControl(Commands & commands, CredentialI credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -23612,7 +23170,6 @@ void registerClusterPumpConfigurationAndControl(Commands & commands, CredentialI make_unique(Id, "control-mode", Attributes::ControlMode::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -23761,7 +23318,6 @@ void registerClusterThermostat(Commands & commands, CredentialIssuerCommands * c credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -23931,8 +23487,6 @@ void registerClusterThermostat(Commands & commands, CredentialIssuerCommands * c credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -24023,7 +23577,6 @@ void registerClusterThermostat(Commands & commands, CredentialIssuerCommands * c credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -24066,7 +23619,6 @@ void registerClusterFanControl(Commands & commands, CredentialIssuerCommands * c make_unique(Id, "airflow-direction", Attributes::AirflowDirection::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -24102,8 +23654,6 @@ void registerClusterFanControl(Commands & commands, CredentialIssuerCommands * c credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -24125,7 +23675,6 @@ void registerClusterFanControl(Commands & commands, CredentialIssuerCommands * c make_unique(Id, "airflow-direction", Attributes::AirflowDirection::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -24159,7 +23708,6 @@ void registerClusterThermostatUserInterfaceConfiguration(Commands & commands, Cr credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -24177,8 +23725,6 @@ void registerClusterThermostatUserInterfaceConfiguration(Commands & commands, Cr credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -24193,7 +23739,6 @@ void registerClusterThermostatUserInterfaceConfiguration(Commands & commands, Cr credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -24300,7 +23845,6 @@ void registerClusterColorControl(Commands & commands, CredentialIssuerCommands * credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -24433,8 +23977,6 @@ void registerClusterColorControl(Commands & commands, CredentialIssuerCommands * credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -24503,7 +24045,6 @@ void registerClusterColorControl(Commands & commands, CredentialIssuerCommands * credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -24547,7 +24088,6 @@ void registerClusterBallastConfiguration(Commands & commands, CredentialIssuerCo make_unique(Id, "lamp-burn-hours-trip-point", Attributes::LampBurnHoursTripPoint::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -24588,8 +24128,6 @@ void registerClusterBallastConfiguration(Commands & commands, CredentialIssuerCo credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -24616,7 +24154,6 @@ void registerClusterBallastConfiguration(Commands & commands, CredentialIssuerCo credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -24651,7 +24188,6 @@ void registerClusterIlluminanceMeasurement(Commands & commands, CredentialIssuer make_unique(Id, "light-sensor-type", Attributes::LightSensorType::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -24676,8 +24212,6 @@ void registerClusterIlluminanceMeasurement(Commands & commands, CredentialIssuer credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -24692,7 +24226,6 @@ void registerClusterIlluminanceMeasurement(Commands & commands, CredentialIssuer make_unique(Id, "light-sensor-type", Attributes::LightSensorType::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -24726,7 +24259,6 @@ void registerClusterTemperatureMeasurement(Commands & commands, CredentialIssuer make_unique(Id, "tolerance", Attributes::Tolerance::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -24747,8 +24279,6 @@ void registerClusterTemperatureMeasurement(Commands & commands, CredentialIssuer credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -24762,7 +24292,6 @@ void registerClusterTemperatureMeasurement(Commands & commands, CredentialIssuer make_unique(Id, "tolerance", Attributes::Tolerance::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -24801,7 +24330,6 @@ void registerClusterPressureMeasurement(Commands & commands, CredentialIssuerCom make_unique(Id, "scale", Attributes::Scale::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -24835,8 +24363,6 @@ void registerClusterPressureMeasurement(Commands & commands, CredentialIssuerCom credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -24855,7 +24381,6 @@ void registerClusterPressureMeasurement(Commands & commands, CredentialIssuerCom make_unique(Id, "scale", Attributes::Scale::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -24889,7 +24414,6 @@ void registerClusterFlowMeasurement(Commands & commands, CredentialIssuerCommand make_unique(Id, "tolerance", Attributes::Tolerance::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -24910,8 +24434,6 @@ void registerClusterFlowMeasurement(Commands & commands, CredentialIssuerCommand credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -24925,7 +24447,6 @@ void registerClusterFlowMeasurement(Commands & commands, CredentialIssuerCommand make_unique(Id, "tolerance", Attributes::Tolerance::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -24959,7 +24480,6 @@ void registerClusterRelativeHumidityMeasurement(Commands & commands, CredentialI make_unique(Id, "tolerance", Attributes::Tolerance::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -24980,8 +24500,6 @@ void registerClusterRelativeHumidityMeasurement(Commands & commands, CredentialI credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -24995,7 +24513,6 @@ void registerClusterRelativeHumidityMeasurement(Commands & commands, CredentialI make_unique(Id, "tolerance", Attributes::Tolerance::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -25049,7 +24566,6 @@ void registerClusterOccupancySensing(Commands & commands, CredentialIssuerComman Attributes::PhysicalContactUnoccupiedToOccupiedThreshold::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -25098,8 +24614,6 @@ void registerClusterOccupancySensing(Commands & commands, CredentialIssuerComman credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -25133,7 +24647,6 @@ void registerClusterOccupancySensing(Commands & commands, CredentialIssuerComman Attributes::PhysicalContactUnoccupiedToOccupiedThreshold::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -25177,7 +24690,6 @@ void registerClusterCarbonMonoxideConcentrationMeasurement(Commands & commands, make_unique(Id, "level-value", Attributes::LevelValue::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -25219,8 +24731,6 @@ void registerClusterCarbonMonoxideConcentrationMeasurement(Commands & commands, credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -25243,7 +24753,6 @@ void registerClusterCarbonMonoxideConcentrationMeasurement(Commands & commands, make_unique(Id, "level-value", Attributes::LevelValue::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -25285,7 +24794,6 @@ void registerClusterCarbonDioxideConcentrationMeasurement(Commands & commands, C make_unique(Id, "level-value", Attributes::LevelValue::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -25327,8 +24835,6 @@ void registerClusterCarbonDioxideConcentrationMeasurement(Commands & commands, C credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -25351,7 +24857,6 @@ void registerClusterCarbonDioxideConcentrationMeasurement(Commands & commands, C make_unique(Id, "level-value", Attributes::LevelValue::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -25393,7 +24898,6 @@ void registerClusterNitrogenDioxideConcentrationMeasurement(Commands & commands, make_unique(Id, "level-value", Attributes::LevelValue::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -25435,8 +24939,6 @@ void registerClusterNitrogenDioxideConcentrationMeasurement(Commands & commands, credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -25459,7 +24961,6 @@ void registerClusterNitrogenDioxideConcentrationMeasurement(Commands & commands, make_unique(Id, "level-value", Attributes::LevelValue::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -25501,7 +25002,6 @@ void registerClusterOzoneConcentrationMeasurement(Commands & commands, Credentia make_unique(Id, "level-value", Attributes::LevelValue::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -25543,8 +25043,6 @@ void registerClusterOzoneConcentrationMeasurement(Commands & commands, Credentia credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -25567,7 +25065,6 @@ void registerClusterOzoneConcentrationMeasurement(Commands & commands, Credentia make_unique(Id, "level-value", Attributes::LevelValue::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -25609,7 +25106,6 @@ void registerClusterPm25ConcentrationMeasurement(Commands & commands, Credential make_unique(Id, "level-value", Attributes::LevelValue::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -25651,8 +25147,6 @@ void registerClusterPm25ConcentrationMeasurement(Commands & commands, Credential credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -25675,7 +25169,6 @@ void registerClusterPm25ConcentrationMeasurement(Commands & commands, Credential make_unique(Id, "level-value", Attributes::LevelValue::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -25717,7 +25210,6 @@ void registerClusterFormaldehydeConcentrationMeasurement(Commands & commands, Cr make_unique(Id, "level-value", Attributes::LevelValue::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -25759,8 +25251,6 @@ void registerClusterFormaldehydeConcentrationMeasurement(Commands & commands, Cr credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -25783,7 +25273,6 @@ void registerClusterFormaldehydeConcentrationMeasurement(Commands & commands, Cr make_unique(Id, "level-value", Attributes::LevelValue::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -25825,7 +25314,6 @@ void registerClusterPm1ConcentrationMeasurement(Commands & commands, CredentialI make_unique(Id, "level-value", Attributes::LevelValue::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -25867,8 +25355,6 @@ void registerClusterPm1ConcentrationMeasurement(Commands & commands, CredentialI credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -25891,7 +25377,6 @@ void registerClusterPm1ConcentrationMeasurement(Commands & commands, CredentialI make_unique(Id, "level-value", Attributes::LevelValue::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -25933,7 +25418,6 @@ void registerClusterPm10ConcentrationMeasurement(Commands & commands, Credential make_unique(Id, "level-value", Attributes::LevelValue::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -25975,8 +25459,6 @@ void registerClusterPm10ConcentrationMeasurement(Commands & commands, Credential credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -25999,7 +25481,6 @@ void registerClusterPm10ConcentrationMeasurement(Commands & commands, Credential make_unique(Id, "level-value", Attributes::LevelValue::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -26042,7 +25523,6 @@ void registerClusterTotalVolatileOrganicCompoundsConcentrationMeasurement(Comman make_unique(Id, "level-value", Attributes::LevelValue::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -26086,8 +25566,6 @@ void registerClusterTotalVolatileOrganicCompoundsConcentrationMeasurement(Comman credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -26110,7 +25588,6 @@ void registerClusterTotalVolatileOrganicCompoundsConcentrationMeasurement(Comman make_unique(Id, "level-value", Attributes::LevelValue::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -26152,7 +25629,6 @@ void registerClusterRadonConcentrationMeasurement(Commands & commands, Credentia make_unique(Id, "level-value", Attributes::LevelValue::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -26194,8 +25670,6 @@ void registerClusterRadonConcentrationMeasurement(Commands & commands, Credentia credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -26218,7 +25692,6 @@ void registerClusterRadonConcentrationMeasurement(Commands & commands, Credentia make_unique(Id, "level-value", Attributes::LevelValue::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -26251,7 +25724,6 @@ void registerClusterWiFiNetworkManagement(Commands & commands, CredentialIssuerC make_unique(Id, "passphrase-surrogate", Attributes::PassphraseSurrogate::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -26266,8 +25738,6 @@ void registerClusterWiFiNetworkManagement(Commands & commands, CredentialIssuerC credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -26279,7 +25749,6 @@ void registerClusterWiFiNetworkManagement(Commands & commands, CredentialIssuerC make_unique(Id, "passphrase-surrogate", Attributes::PassphraseSurrogate::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -26319,7 +25788,6 @@ void registerClusterThreadBorderRouterManagement(Commands & commands, Credential make_unique(Id, "pending-dataset-timestamp", Attributes::PendingDatasetTimestamp::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -26343,8 +25811,6 @@ void registerClusterThreadBorderRouterManagement(Commands & commands, Credential credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -26362,7 +25828,6 @@ void registerClusterThreadBorderRouterManagement(Commands & commands, Credential credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -26398,7 +25863,6 @@ void registerClusterThreadNetworkDirectory(Commands & commands, CredentialIssuer make_unique(Id, "thread-network-table-size", Attributes::ThreadNetworkTableSize::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -26416,8 +25880,6 @@ void registerClusterThreadNetworkDirectory(Commands & commands, CredentialIssuer credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -26432,7 +25894,6 @@ void registerClusterThreadNetworkDirectory(Commands & commands, CredentialIssuer credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -26464,7 +25925,6 @@ void registerClusterWakeOnLan(Commands & commands, CredentialIssuerCommands * cr make_unique(Id, "link-local-address", Attributes::LinkLocalAddress::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -26478,8 +25938,6 @@ void registerClusterWakeOnLan(Commands & commands, CredentialIssuerCommands * cr credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -26491,7 +25949,6 @@ void registerClusterWakeOnLan(Commands & commands, CredentialIssuerCommands * cr make_unique(Id, "link-local-address", Attributes::LinkLocalAddress::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -26530,7 +25987,6 @@ void registerClusterChannel(Commands & commands, CredentialIssuerCommands * cred make_unique(Id, "current-channel", Attributes::CurrentChannel::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -26549,8 +26005,6 @@ void registerClusterChannel(Commands & commands, CredentialIssuerCommands * cred credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -26563,7 +26017,6 @@ void registerClusterChannel(Commands & commands, CredentialIssuerCommands * cred make_unique(Id, "current-channel", Attributes::CurrentChannel::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -26596,7 +26049,6 @@ void registerClusterTargetNavigator(Commands & commands, CredentialIssuerCommand make_unique(Id, "current-target", Attributes::CurrentTarget::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -26611,8 +26063,6 @@ void registerClusterTargetNavigator(Commands & commands, CredentialIssuerCommand credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -26624,7 +26074,6 @@ void registerClusterTargetNavigator(Commands & commands, CredentialIssuerCommand make_unique(Id, "current-target", Attributes::CurrentTarget::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -26681,7 +26130,6 @@ void registerClusterMediaPlayback(Commands & commands, CredentialIssuerCommands make_unique(Id, "available-text-tracks", Attributes::AvailableTextTracks::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -26721,8 +26169,6 @@ void registerClusterMediaPlayback(Commands & commands, CredentialIssuerCommands credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -26743,7 +26189,6 @@ void registerClusterMediaPlayback(Commands & commands, CredentialIssuerCommands make_unique(Id, "available-text-tracks", Attributes::AvailableTextTracks::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -26781,7 +26226,6 @@ void registerClusterMediaInput(Commands & commands, CredentialIssuerCommands * c make_unique(Id, "current-input", Attributes::CurrentInput::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -26796,8 +26240,6 @@ void registerClusterMediaInput(Commands & commands, CredentialIssuerCommands * c credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -26809,7 +26251,6 @@ void registerClusterMediaInput(Commands & commands, CredentialIssuerCommands * c make_unique(Id, "current-input", Attributes::CurrentInput::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -26840,7 +26281,6 @@ void registerClusterLowPower(Commands & commands, CredentialIssuerCommands * cre make_unique(Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -26850,8 +26290,6 @@ void registerClusterLowPower(Commands & commands, CredentialIssuerCommands * cre credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -26861,7 +26299,6 @@ void registerClusterLowPower(Commands & commands, CredentialIssuerCommands * cre make_unique(Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -26892,7 +26329,6 @@ void registerClusterKeypadInput(Commands & commands, CredentialIssuerCommands * make_unique(Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -26902,8 +26338,6 @@ void registerClusterKeypadInput(Commands & commands, CredentialIssuerCommands * credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -26913,7 +26347,6 @@ void registerClusterKeypadInput(Commands & commands, CredentialIssuerCommands * make_unique(Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -26948,7 +26381,6 @@ void registerClusterContentLauncher(Commands & commands, CredentialIssuerCommand credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -26963,8 +26395,6 @@ void registerClusterContentLauncher(Commands & commands, CredentialIssuerCommand credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -26977,7 +26407,6 @@ void registerClusterContentLauncher(Commands & commands, CredentialIssuerCommand credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -27011,7 +26440,6 @@ void registerClusterAudioOutput(Commands & commands, CredentialIssuerCommands * make_unique(Id, "current-output", Attributes::CurrentOutput::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -27026,8 +26454,6 @@ void registerClusterAudioOutput(Commands & commands, CredentialIssuerCommands * credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -27039,7 +26465,6 @@ void registerClusterAudioOutput(Commands & commands, CredentialIssuerCommands * make_unique(Id, "current-output", Attributes::CurrentOutput::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -27074,7 +26499,6 @@ void registerClusterApplicationLauncher(Commands & commands, CredentialIssuerCom make_unique(Id, "current-app", Attributes::CurrentApp::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -27089,8 +26513,6 @@ void registerClusterApplicationLauncher(Commands & commands, CredentialIssuerCom credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -27102,7 +26524,6 @@ void registerClusterApplicationLauncher(Commands & commands, CredentialIssuerCom make_unique(Id, "current-app", Attributes::CurrentApp::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -27140,7 +26561,6 @@ void registerClusterApplicationBasic(Commands & commands, CredentialIssuerComman make_unique(Id, "allowed-vendor-list", Attributes::AllowedVendorList::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -27166,8 +26586,6 @@ void registerClusterApplicationBasic(Commands & commands, CredentialIssuerComman credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -27185,7 +26603,6 @@ void registerClusterApplicationBasic(Commands & commands, CredentialIssuerComman make_unique(Id, "allowed-vendor-list", Attributes::AllowedVendorList::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -27218,7 +26635,6 @@ void registerClusterAccountLogin(Commands & commands, CredentialIssuerCommands * make_unique(Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -27228,8 +26644,6 @@ void registerClusterAccountLogin(Commands & commands, CredentialIssuerCommands * credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -27239,7 +26653,6 @@ void registerClusterAccountLogin(Commands & commands, CredentialIssuerCommands * make_unique(Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -27290,7 +26703,6 @@ void registerClusterContentControl(Commands & commands, CredentialIssuerCommands make_unique(Id, "block-unrated", Attributes::BlockUnrated::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -27320,8 +26732,6 @@ void registerClusterContentControl(Commands & commands, CredentialIssuerCommands credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -27342,7 +26752,6 @@ void registerClusterContentControl(Commands & commands, CredentialIssuerCommands make_unique(Id, "block-unrated", Attributes::BlockUnrated::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -27376,7 +26785,6 @@ void registerClusterContentAppObserver(Commands & commands, CredentialIssuerComm make_unique(Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -27386,8 +26794,6 @@ void registerClusterContentAppObserver(Commands & commands, CredentialIssuerComm credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -27397,7 +26803,6 @@ void registerClusterContentAppObserver(Commands & commands, CredentialIssuerComm make_unique(Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -27435,7 +26840,6 @@ void registerClusterZoneManagement(Commands & commands, CredentialIssuerCommands make_unique(Id, "sensitivity", Attributes::Sensitivity::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -27456,8 +26860,6 @@ void registerClusterZoneManagement(Commands & commands, CredentialIssuerCommands credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -27471,7 +26873,6 @@ void registerClusterZoneManagement(Commands & commands, CredentialIssuerCommands make_unique(Id, "sensitivity", Attributes::Sensitivity::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -27573,7 +26974,6 @@ void registerClusterCameraAvStreamManagement(Commands & commands, CredentialIssu make_unique(Id, "depth-sensor-status", Attributes::DepthSensorStatus::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -27700,8 +27100,6 @@ void registerClusterCameraAvStreamManagement(Commands & commands, CredentialIssu credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -27769,7 +27167,6 @@ void registerClusterCameraAvStreamManagement(Commands & commands, CredentialIssu make_unique(Id, "depth-sensor-status", Attributes::DepthSensorStatus::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -27811,7 +27208,6 @@ void registerClusterWebRTCTransportProvider(Commands & commands, CredentialIssue make_unique(Id, "current-sessions", Attributes::CurrentSessions::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -27824,8 +27220,6 @@ void registerClusterWebRTCTransportProvider(Commands & commands, CredentialIssue credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -27836,7 +27230,6 @@ void registerClusterWebRTCTransportProvider(Commands & commands, CredentialIssue make_unique(Id, "current-sessions", Attributes::CurrentSessions::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -27871,7 +27264,6 @@ void registerClusterWebRTCTransportRequestor(Commands & commands, CredentialIssu make_unique(Id, "current-sessions", Attributes::CurrentSessions::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -27884,8 +27276,6 @@ void registerClusterWebRTCTransportRequestor(Commands & commands, CredentialIssu credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -27896,7 +27286,6 @@ void registerClusterWebRTCTransportRequestor(Commands & commands, CredentialIssu make_unique(Id, "current-sessions", Attributes::CurrentSessions::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -27930,7 +27319,6 @@ void registerClusterChime(Commands & commands, CredentialIssuerCommands * credsI make_unique(Id, "enabled", Attributes::Enabled::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -27948,8 +27336,6 @@ void registerClusterChime(Commands & commands, CredentialIssuerCommands * credsI credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -27962,7 +27348,6 @@ void registerClusterChime(Commands & commands, CredentialIssuerCommands * credsI make_unique(Id, "enabled", Attributes::Enabled::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -27994,7 +27379,6 @@ void registerClusterEcosystemInformation(Commands & commands, CredentialIssuerCo make_unique(Id, "location-directory", Attributes::LocationDirectory::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -28010,8 +27394,6 @@ void registerClusterEcosystemInformation(Commands & commands, CredentialIssuerCo credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -28023,7 +27405,6 @@ void registerClusterEcosystemInformation(Commands & commands, CredentialIssuerCo make_unique(Id, "location-directory", Attributes::LocationDirectory::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -28057,7 +27438,6 @@ void registerClusterCommissionerControl(Commands & commands, CredentialIssuerCom credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -28070,8 +27450,6 @@ void registerClusterCommissionerControl(Commands & commands, CredentialIssuerCom credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -28083,7 +27461,6 @@ void registerClusterCommissionerControl(Commands & commands, CredentialIssuerCom credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -28236,7 +27613,6 @@ void registerClusterUnitTesting(Commands & commands, CredentialIssuerCommands * make_unique(Id, "nullable-global-struct", Attributes::NullableGlobalStruct::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -28454,8 +27830,6 @@ void registerClusterUnitTesting(Commands & commands, CredentialIssuerCommands * credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -28561,7 +27935,6 @@ void registerClusterUnitTesting(Commands & commands, CredentialIssuerCommands * make_unique(Id, "nullable-global-struct", Attributes::NullableGlobalStruct::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -28602,7 +27975,6 @@ void registerClusterFaultInjection(Commands & commands, CredentialIssuerCommands make_unique(Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -28612,8 +27984,6 @@ void registerClusterFaultInjection(Commands & commands, CredentialIssuerCommands credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -28623,7 +27993,6 @@ void registerClusterFaultInjection(Commands & commands, CredentialIssuerCommands make_unique(Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -28656,7 +28025,6 @@ void registerClusterSampleMei(Commands & commands, CredentialIssuerCommands * cr make_unique(Id, "flip-flop", Attributes::FlipFlop::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // @@ -28668,8 +28036,6 @@ void registerClusterSampleMei(Commands & commands, CredentialIssuerCommands * cr credsIssuerConfig), // make_unique>>( Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>>( - Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>>( Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, @@ -28680,7 +28046,6 @@ void registerClusterSampleMei(Commands & commands, CredentialIssuerCommands * cr make_unique(Id, "flip-flop", Attributes::FlipFlop::Id, credsIssuerConfig), // make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // - make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // diff --git a/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp b/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp index afd4cc609368ef..8a0e26cbca4bc1 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp +++ b/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp @@ -10056,11 +10056,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, Identify::Id); } - case Identify::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case Identify::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -10097,11 +10092,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, Groups::Id); } - case Groups::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case Groups::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -10158,11 +10148,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, OnOff::Id); } - case OnOff::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case OnOff::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -10264,11 +10249,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, LevelControl::Id); } - case LevelControl::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case LevelControl::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -10300,11 +10280,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, PulseWidthModulation::Id); } - case PulseWidthModulation::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case PulseWidthModulation::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -10361,11 +10336,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, Descriptor::Id); } - case Descriptor::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case Descriptor::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -10402,11 +10372,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, Binding::Id); } - case Binding::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case Binding::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -10481,11 +10446,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, AccessControl::Id); } - case AccessControl::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case AccessControl::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -10532,11 +10492,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, Actions::Id); } - case Actions::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case Actions::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -10683,11 +10638,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, BasicInformation::Id); } - case BasicInformation::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case BasicInformation::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -10719,11 +10669,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, OtaSoftwareUpdateProvider::Id); } - case OtaSoftwareUpdateProvider::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case OtaSoftwareUpdateProvider::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -10777,11 +10722,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, OtaSoftwareUpdateRequestor::Id); } - case OtaSoftwareUpdateRequestor::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case OtaSoftwareUpdateRequestor::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -10823,11 +10763,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, LocalizationConfiguration::Id); } - case LocalizationConfiguration::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case LocalizationConfiguration::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -10874,11 +10809,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, TimeFormatLocalization::Id); } - case TimeFormatLocalization::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case TimeFormatLocalization::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -10915,11 +10845,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, UnitLocalization::Id); } - case UnitLocalization::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case UnitLocalization::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -10956,11 +10881,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, PowerSourceConfiguration::Id); } - case PowerSourceConfiguration::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case PowerSourceConfiguration::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -11152,11 +11072,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, PowerSource::Id); } - case PowerSource::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case PowerSource::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -11238,11 +11153,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, GeneralCommissioning::Id); } - case GeneralCommissioning::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case GeneralCommissioning::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -11331,11 +11241,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, NetworkCommissioning::Id); } - case NetworkCommissioning::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case NetworkCommissioning::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -11367,11 +11272,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, DiagnosticLogs::Id); } - case DiagnosticLogs::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case DiagnosticLogs::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -11449,11 +11349,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, GeneralDiagnostics::Id); } - case GeneralDiagnostics::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case GeneralDiagnostics::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -11507,11 +11402,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, SoftwareDiagnostics::Id); } - case SoftwareDiagnostics::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case SoftwareDiagnostics::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -11865,11 +11755,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, ThreadNetworkDiagnostics::Id); } - case ThreadNetworkDiagnostics::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case ThreadNetworkDiagnostics::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -11966,11 +11851,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, WiFiNetworkDiagnostics::Id); } - case WiFiNetworkDiagnostics::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case WiFiNetworkDiagnostics::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -12047,11 +11927,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, EthernetNetworkDiagnostics::Id); } - case EthernetNetworkDiagnostics::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case EthernetNetworkDiagnostics::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -12152,11 +12027,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, TimeSynchronization::Id); } - case TimeSynchronization::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case TimeSynchronization::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -12273,11 +12143,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, BridgedDeviceBasicInformation::Id); } - case BridgedDeviceBasicInformation::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case BridgedDeviceBasicInformation::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -12324,11 +12189,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, Switch::Id); } - case Switch::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case Switch::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -12375,11 +12235,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, AdministratorCommissioning::Id); } - case AdministratorCommissioning::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case AdministratorCommissioning::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -12444,11 +12299,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, OperationalCredentials::Id); } - case OperationalCredentials::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case OperationalCredentials::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -12502,11 +12352,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, GroupKeyManagement::Id); } - case GroupKeyManagement::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case GroupKeyManagement::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -12543,11 +12388,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, FixedLabel::Id); } - case FixedLabel::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case FixedLabel::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -12584,11 +12424,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, UserLabel::Id); } - case UserLabel::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case UserLabel::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -12620,11 +12455,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, ProxyConfiguration::Id); } - case ProxyConfiguration::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case ProxyConfiguration::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -12656,11 +12486,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, ProxyDiscovery::Id); } - case ProxyDiscovery::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case ProxyDiscovery::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -12692,11 +12517,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, ProxyValid::Id); } - case ProxyValid::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case ProxyValid::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -12733,11 +12553,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, BooleanState::Id); } - case BooleanState::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case BooleanState::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -12821,11 +12636,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, IcdManagement::Id); } - case IcdManagement::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case IcdManagement::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -12872,11 +12682,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, Timer::Id); } - case Timer::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case Timer::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -12940,11 +12745,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, OvenCavityOperationalState::Id); } - case OvenCavityOperationalState::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case OvenCavityOperationalState::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -12996,11 +12796,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, OvenMode::Id); } - case OvenMode::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case OvenMode::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -13042,11 +12837,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, LaundryDryerControls::Id); } - case LaundryDryerControls::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case LaundryDryerControls::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -13108,11 +12898,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, ModeSelect::Id); } - case ModeSelect::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case ModeSelect::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -13165,11 +12950,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, LaundryWasherMode::Id); } - case LaundryWasherMode::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case LaundryWasherMode::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -13225,11 +13005,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, RefrigeratorAndTemperatureControlledCabinetMode::Id); } - case RefrigeratorAndTemperatureControlledCabinetMode::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case RefrigeratorAndTemperatureControlledCabinetMode::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -13281,11 +13056,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, LaundryWasherControls::Id); } - case LaundryWasherControls::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case LaundryWasherControls::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -13327,11 +13097,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, RvcRunMode::Id); } - case RvcRunMode::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case RvcRunMode::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -13373,11 +13138,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, RvcCleanMode::Id); } - case RvcCleanMode::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case RvcCleanMode::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -13439,11 +13199,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, TemperatureControl::Id); } - case TemperatureControl::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case TemperatureControl::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -13490,11 +13245,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, RefrigeratorAlarm::Id); } - case RefrigeratorAlarm::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case RefrigeratorAlarm::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -13547,11 +13297,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, DishwasherMode::Id); } - case DishwasherMode::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case DishwasherMode::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -13588,11 +13333,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, AirQuality::Id); } - case AirQuality::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case AirQuality::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -13689,11 +13429,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, SmokeCoAlarm::Id); } - case SmokeCoAlarm::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case SmokeCoAlarm::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -13745,11 +13480,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, DishwasherAlarm::Id); } - case DishwasherAlarm::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case DishwasherAlarm::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -13792,11 +13522,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, MicrowaveOvenMode::Id); } - case MicrowaveOvenMode::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case MicrowaveOvenMode::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -13873,11 +13598,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, MicrowaveOvenControl::Id); } - case MicrowaveOvenControl::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case MicrowaveOvenControl::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -13941,11 +13661,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, OperationalState::Id); } - case OperationalState::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case OperationalState::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -14009,11 +13724,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, RvcOperationalState::Id); } - case RvcOperationalState::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case RvcOperationalState::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -14061,11 +13771,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, ScenesManagement::Id); } - case ScenesManagement::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case ScenesManagement::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -14129,11 +13834,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, HepaFilterMonitoring::Id); } - case HepaFilterMonitoring::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case HepaFilterMonitoring::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -14197,11 +13897,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, ActivatedCarbonFilterMonitoring::Id); } - case ActivatedCarbonFilterMonitoring::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case ActivatedCarbonFilterMonitoring::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -14273,11 +13968,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, BooleanStateConfiguration::Id); } - case BooleanStateConfiguration::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case BooleanStateConfiguration::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -14364,11 +14054,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, ValveConfigurationAndControl::Id); } - case ValveConfigurationAndControl::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case ValveConfigurationAndControl::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -14503,11 +14188,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, ElectricalPowerMeasurement::Id); } - case ElectricalPowerMeasurement::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case ElectricalPowerMeasurement::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -14579,11 +14259,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, ElectricalEnergyMeasurement::Id); } - case ElectricalEnergyMeasurement::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case ElectricalEnergyMeasurement::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -14645,11 +14320,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, WaterHeaterManagement::Id); } - case WaterHeaterManagement::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case WaterHeaterManagement::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -14727,11 +14397,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, DemandResponseLoadControl::Id); } - case DemandResponseLoadControl::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case DemandResponseLoadControl::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -14773,11 +14438,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, Messages::Id); } - case Messages::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case Messages::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -14852,11 +14512,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, DeviceEnergyManagement::Id); } - case DeviceEnergyManagement::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case DeviceEnergyManagement::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -15003,11 +14658,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, EnergyEvse::Id); } - case EnergyEvse::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case EnergyEvse::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -15064,11 +14714,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, EnergyPreference::Id); } - case EnergyPreference::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case EnergyPreference::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -15110,11 +14755,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, PowerTopology::Id); } - case PowerTopology::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case PowerTopology::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -15157,11 +14797,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, EnergyEvseMode::Id); } - case EnergyEvseMode::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case EnergyEvseMode::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -15204,11 +14839,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, WaterHeaterMode::Id); } - case WaterHeaterMode::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case WaterHeaterMode::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -15252,11 +14882,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, DeviceEnergyManagementMode::Id); } - case DeviceEnergyManagementMode::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case DeviceEnergyManagementMode::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -15513,11 +15138,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, DoorLock::Id); } - case DoorLock::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case DoorLock::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -15659,11 +15279,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, WindowCovering::Id); } - case WindowCovering::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case WindowCovering::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -15725,11 +15340,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, ServiceArea::Id); } - case ServiceArea::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case ServiceArea::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -15876,11 +15486,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, PumpConfigurationAndControl::Id); } - case PumpConfigurationAndControl::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case PumpConfigurationAndControl::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -16212,11 +15817,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, Thermostat::Id); } - case Thermostat::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case Thermostat::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -16308,11 +15908,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, FanControl::Id); } - case FanControl::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case FanControl::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -16360,11 +15955,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, ThermostatUserInterfaceConfiguration::Id); } - case ThermostatUserInterfaceConfiguration::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case ThermostatUserInterfaceConfiguration::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -16656,11 +16246,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, ColorControl::Id); } - case ColorControl::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case ColorControl::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -16762,11 +16347,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, BallastConfiguration::Id); } - case BallastConfiguration::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case BallastConfiguration::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -16823,11 +16403,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, IlluminanceMeasurement::Id); } - case IlluminanceMeasurement::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case IlluminanceMeasurement::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -16879,11 +16454,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, TemperatureMeasurement::Id); } - case TemperatureMeasurement::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case TemperatureMeasurement::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -16960,11 +16530,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, PressureMeasurement::Id); } - case PressureMeasurement::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case PressureMeasurement::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -17016,11 +16581,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, FlowMeasurement::Id); } - case FlowMeasurement::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case FlowMeasurement::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -17072,11 +16632,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, RelativeHumidityMeasurement::Id); } - case RelativeHumidityMeasurement::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case RelativeHumidityMeasurement::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -17178,11 +16733,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, OccupancySensing::Id); } - case OccupancySensing::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case OccupancySensing::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -17271,11 +16821,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, CarbonMonoxideConcentrationMeasurement::Id); } - case CarbonMonoxideConcentrationMeasurement::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case CarbonMonoxideConcentrationMeasurement::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -17364,11 +16909,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, CarbonDioxideConcentrationMeasurement::Id); } - case CarbonDioxideConcentrationMeasurement::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case CarbonDioxideConcentrationMeasurement::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -17457,11 +16997,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, NitrogenDioxideConcentrationMeasurement::Id); } - case NitrogenDioxideConcentrationMeasurement::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case NitrogenDioxideConcentrationMeasurement::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -17548,11 +17083,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, OzoneConcentrationMeasurement::Id); } - case OzoneConcentrationMeasurement::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case OzoneConcentrationMeasurement::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -17639,11 +17169,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, Pm25ConcentrationMeasurement::Id); } - case Pm25ConcentrationMeasurement::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case Pm25ConcentrationMeasurement::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -17731,11 +17256,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, FormaldehydeConcentrationMeasurement::Id); } - case FormaldehydeConcentrationMeasurement::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case FormaldehydeConcentrationMeasurement::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -17822,11 +17342,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, Pm1ConcentrationMeasurement::Id); } - case Pm1ConcentrationMeasurement::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case Pm1ConcentrationMeasurement::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -17913,11 +17428,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, Pm10ConcentrationMeasurement::Id); } - case Pm10ConcentrationMeasurement::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case Pm10ConcentrationMeasurement::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -18006,11 +17516,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, TotalVolatileOrganicCompoundsConcentrationMeasurement::Id); } - case TotalVolatileOrganicCompoundsConcentrationMeasurement::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case TotalVolatileOrganicCompoundsConcentrationMeasurement::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -18098,11 +17603,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, RadonConcentrationMeasurement::Id); } - case RadonConcentrationMeasurement::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case RadonConcentrationMeasurement::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -18144,11 +17644,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, WiFiNetworkManagement::Id); } - case WiFiNetworkManagement::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case WiFiNetworkManagement::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -18210,11 +17705,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, ThreadBorderRouterManagement::Id); } - case ThreadBorderRouterManagement::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case ThreadBorderRouterManagement::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -18263,11 +17753,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, ThreadNetworkDirectory::Id); } - case ThreadNetworkDirectory::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case ThreadNetworkDirectory::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -18309,11 +17794,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, WakeOnLan::Id); } - case WakeOnLan::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case WakeOnLan::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -18360,11 +17840,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, Channel::Id); } - case Channel::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case Channel::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -18407,11 +17882,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, TargetNavigator::Id); } - case TargetNavigator::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case TargetNavigator::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -18503,11 +17973,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, MediaPlayback::Id); } - case MediaPlayback::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case MediaPlayback::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -18549,11 +18014,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, MediaInput::Id); } - case MediaInput::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case MediaInput::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -18585,11 +18045,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, LowPower::Id); } - case LowPower::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case LowPower::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -18621,11 +18076,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, KeypadInput::Id); } - case KeypadInput::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case KeypadInput::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -18667,11 +18117,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, ContentLauncher::Id); } - case ContentLauncher::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case ContentLauncher::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -18713,11 +18158,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, AudioOutput::Id); } - case AudioOutput::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case AudioOutput::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -18760,11 +18200,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, ApplicationLauncher::Id); } - case ApplicationLauncher::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case ApplicationLauncher::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -18836,11 +18271,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, ApplicationBasic::Id); } - case ApplicationBasic::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case ApplicationBasic::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -18872,11 +18302,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, AccountLogin::Id); } - case AccountLogin::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case AccountLogin::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -18950,11 +18375,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, ContentControl::Id); } - case ContentControl::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case ContentControl::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -18986,11 +18406,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, ContentAppObserver::Id); } - case ContentAppObserver::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case ContentAppObserver::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -19045,11 +18460,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, ZoneManagement::Id); } - case ZoneManagement::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case ZoneManagement::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -19326,11 +18736,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, CameraAvStreamManagement::Id); } - case CameraAvStreamManagement::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case CameraAvStreamManagement::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -19369,11 +18774,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, WebRTCTransportProvider::Id); } - case WebRTCTransportProvider::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case WebRTCTransportProvider::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -19412,11 +18812,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, WebRTCTransportRequestor::Id); } - case WebRTCTransportRequestor::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case WebRTCTransportRequestor::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -19463,11 +18858,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, Chime::Id); } - case Chime::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case Chime::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -19513,11 +18903,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, EcosystemInformation::Id); } - case EcosystemInformation::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case EcosystemInformation::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -19554,11 +18939,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, CommissionerControl::Id); } - case CommissionerControl::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case CommissionerControl::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -20033,11 +19413,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, UnitTesting::Id); } - case UnitTesting::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case UnitTesting::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -20074,11 +19449,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, FaultInjection::Id); } - case FaultInjection::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case FaultInjection::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); @@ -20115,11 +19485,6 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, SampleMei::Id); } - case SampleMei::Attributes::EventList::Id: { - chip::app::DataModel::DecodableList value; - ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("EventList", 1, value); - } case SampleMei::Attributes::AttributeList::Id: { chip::app::DataModel::DecodableList value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); diff --git a/zzz_generated/chip-tool/zap-generated/cluster/logging/EntryToText.cpp b/zzz_generated/chip-tool/zap-generated/cluster/logging/EntryToText.cpp index faafa6df9dd627..a5739f1228aad6 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/logging/EntryToText.cpp +++ b/zzz_generated/chip-tool/zap-generated/cluster/logging/EntryToText.cpp @@ -299,8 +299,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::Identify::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::Identify::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::Identify::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::Identify::Attributes::FeatureMap::Id: @@ -320,8 +318,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::Groups::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::Groups::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::Groups::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::Groups::Attributes::FeatureMap::Id: @@ -349,8 +345,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::OnOff::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::OnOff::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::OnOff::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::OnOff::Attributes::FeatureMap::Id: @@ -396,8 +390,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::LevelControl::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::LevelControl::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::LevelControl::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::LevelControl::Attributes::FeatureMap::Id: @@ -415,8 +407,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::PulseWidthModulation::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::PulseWidthModulation::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::PulseWidthModulation::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::PulseWidthModulation::Attributes::FeatureMap::Id: @@ -444,8 +434,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::Descriptor::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::Descriptor::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::Descriptor::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::Descriptor::Attributes::FeatureMap::Id: @@ -465,8 +453,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::Binding::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::Binding::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::Binding::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::Binding::Attributes::FeatureMap::Id: @@ -498,8 +484,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::AccessControl::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::AccessControl::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::AccessControl::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::AccessControl::Attributes::FeatureMap::Id: @@ -523,8 +507,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::Actions::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::Actions::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::Actions::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::Actions::Attributes::FeatureMap::Id: @@ -588,8 +570,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::BasicInformation::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::BasicInformation::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::BasicInformation::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::BasicInformation::Attributes::FeatureMap::Id: @@ -607,8 +587,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::OtaSoftwareUpdateProvider::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::OtaSoftwareUpdateProvider::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::OtaSoftwareUpdateProvider::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::OtaSoftwareUpdateProvider::Attributes::FeatureMap::Id: @@ -634,8 +612,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::OtaSoftwareUpdateRequestor::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::OtaSoftwareUpdateRequestor::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::OtaSoftwareUpdateRequestor::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::OtaSoftwareUpdateRequestor::Attributes::FeatureMap::Id: @@ -657,8 +633,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::LocalizationConfiguration::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::LocalizationConfiguration::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::LocalizationConfiguration::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::LocalizationConfiguration::Attributes::FeatureMap::Id: @@ -682,8 +656,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::TimeFormatLocalization::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::TimeFormatLocalization::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::TimeFormatLocalization::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::TimeFormatLocalization::Attributes::FeatureMap::Id: @@ -703,8 +675,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::UnitLocalization::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::UnitLocalization::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::UnitLocalization::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::UnitLocalization::Attributes::FeatureMap::Id: @@ -724,8 +694,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::PowerSourceConfiguration::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::PowerSourceConfiguration::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::PowerSourceConfiguration::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::PowerSourceConfiguration::Attributes::FeatureMap::Id: @@ -807,8 +775,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::PowerSource::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::PowerSource::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::PowerSource::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::PowerSource::Attributes::FeatureMap::Id: @@ -846,8 +812,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::GeneralCommissioning::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::GeneralCommissioning::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::GeneralCommissioning::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::GeneralCommissioning::Attributes::FeatureMap::Id: @@ -887,8 +851,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::NetworkCommissioning::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::NetworkCommissioning::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::NetworkCommissioning::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::NetworkCommissioning::Attributes::FeatureMap::Id: @@ -906,8 +868,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::DiagnosticLogs::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::DiagnosticLogs::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::DiagnosticLogs::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::DiagnosticLogs::Attributes::FeatureMap::Id: @@ -943,8 +903,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::GeneralDiagnostics::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::GeneralDiagnostics::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::GeneralDiagnostics::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::GeneralDiagnostics::Attributes::FeatureMap::Id: @@ -970,8 +928,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::SoftwareDiagnostics::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::SoftwareDiagnostics::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::SoftwareDiagnostics::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::SoftwareDiagnostics::Attributes::FeatureMap::Id: @@ -1115,8 +1071,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::ThreadNetworkDiagnostics::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::ThreadNetworkDiagnostics::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::ThreadNetworkDiagnostics::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::ThreadNetworkDiagnostics::Attributes::FeatureMap::Id: @@ -1160,8 +1114,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::WiFiNetworkDiagnostics::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::WiFiNetworkDiagnostics::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::WiFiNetworkDiagnostics::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::WiFiNetworkDiagnostics::Attributes::FeatureMap::Id: @@ -1197,8 +1149,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::EthernetNetworkDiagnostics::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::EthernetNetworkDiagnostics::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::EthernetNetworkDiagnostics::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::EthernetNetworkDiagnostics::Attributes::FeatureMap::Id: @@ -1242,8 +1192,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::TimeSynchronization::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::TimeSynchronization::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::TimeSynchronization::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::TimeSynchronization::Attributes::FeatureMap::Id: @@ -1295,8 +1243,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::BridgedDeviceBasicInformation::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::BridgedDeviceBasicInformation::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::BridgedDeviceBasicInformation::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::BridgedDeviceBasicInformation::Attributes::FeatureMap::Id: @@ -1320,8 +1266,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::Switch::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::Switch::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::Switch::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::Switch::Attributes::FeatureMap::Id: @@ -1345,8 +1289,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::AdministratorCommissioning::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::AdministratorCommissioning::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::AdministratorCommissioning::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::AdministratorCommissioning::Attributes::FeatureMap::Id: @@ -1376,8 +1318,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::OperationalCredentials::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::OperationalCredentials::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::OperationalCredentials::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::OperationalCredentials::Attributes::FeatureMap::Id: @@ -1403,8 +1343,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::GroupKeyManagement::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::GroupKeyManagement::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::GroupKeyManagement::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::GroupKeyManagement::Attributes::FeatureMap::Id: @@ -1424,8 +1362,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::FixedLabel::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::FixedLabel::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::FixedLabel::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::FixedLabel::Attributes::FeatureMap::Id: @@ -1445,8 +1381,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::UserLabel::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::UserLabel::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::UserLabel::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::UserLabel::Attributes::FeatureMap::Id: @@ -1464,8 +1398,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::ProxyConfiguration::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::ProxyConfiguration::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::ProxyConfiguration::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::ProxyConfiguration::Attributes::FeatureMap::Id: @@ -1483,8 +1415,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::ProxyDiscovery::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::ProxyDiscovery::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::ProxyDiscovery::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::ProxyDiscovery::Attributes::FeatureMap::Id: @@ -1502,8 +1432,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::ProxyValid::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::ProxyValid::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::ProxyValid::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::ProxyValid::Attributes::FeatureMap::Id: @@ -1523,8 +1451,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::BooleanState::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::BooleanState::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::BooleanState::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::BooleanState::Attributes::FeatureMap::Id: @@ -1562,8 +1488,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::IcdManagement::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::IcdManagement::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::IcdManagement::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::IcdManagement::Attributes::FeatureMap::Id: @@ -1587,8 +1511,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::Timer::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::Timer::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::Timer::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::Timer::Attributes::FeatureMap::Id: @@ -1618,8 +1540,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::OvenCavityOperationalState::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::OvenCavityOperationalState::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::OvenCavityOperationalState::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::OvenCavityOperationalState::Attributes::FeatureMap::Id: @@ -1645,8 +1565,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::OvenMode::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::OvenMode::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::OvenMode::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::OvenMode::Attributes::FeatureMap::Id: @@ -1668,8 +1586,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::LaundryDryerControls::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::LaundryDryerControls::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::LaundryDryerControls::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::LaundryDryerControls::Attributes::FeatureMap::Id: @@ -1699,8 +1615,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::ModeSelect::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::ModeSelect::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::ModeSelect::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::ModeSelect::Attributes::FeatureMap::Id: @@ -1726,8 +1640,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::LaundryWasherMode::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::LaundryWasherMode::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::LaundryWasherMode::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::LaundryWasherMode::Attributes::FeatureMap::Id: @@ -1753,8 +1665,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::RefrigeratorAndTemperatureControlledCabinetMode::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::RefrigeratorAndTemperatureControlledCabinetMode::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::RefrigeratorAndTemperatureControlledCabinetMode::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::RefrigeratorAndTemperatureControlledCabinetMode::Attributes::FeatureMap::Id: @@ -1780,8 +1690,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::LaundryWasherControls::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::LaundryWasherControls::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::LaundryWasherControls::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::LaundryWasherControls::Attributes::FeatureMap::Id: @@ -1803,8 +1711,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::RvcRunMode::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::RvcRunMode::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::RvcRunMode::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::RvcRunMode::Attributes::FeatureMap::Id: @@ -1826,8 +1732,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::RvcCleanMode::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::RvcCleanMode::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::RvcCleanMode::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::RvcCleanMode::Attributes::FeatureMap::Id: @@ -1857,8 +1761,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::TemperatureControl::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::TemperatureControl::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::TemperatureControl::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::TemperatureControl::Attributes::FeatureMap::Id: @@ -1882,8 +1784,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::RefrigeratorAlarm::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::RefrigeratorAlarm::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::RefrigeratorAlarm::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::RefrigeratorAlarm::Attributes::FeatureMap::Id: @@ -1909,8 +1809,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::DishwasherMode::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::DishwasherMode::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::DishwasherMode::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::DishwasherMode::Attributes::FeatureMap::Id: @@ -1930,8 +1828,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::AirQuality::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::AirQuality::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::AirQuality::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::AirQuality::Attributes::FeatureMap::Id: @@ -1975,8 +1871,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::SmokeCoAlarm::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::SmokeCoAlarm::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::SmokeCoAlarm::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::SmokeCoAlarm::Attributes::FeatureMap::Id: @@ -2002,8 +1896,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::DishwasherAlarm::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::DishwasherAlarm::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::DishwasherAlarm::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::DishwasherAlarm::Attributes::FeatureMap::Id: @@ -2025,8 +1917,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::MicrowaveOvenMode::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::MicrowaveOvenMode::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::MicrowaveOvenMode::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::MicrowaveOvenMode::Attributes::FeatureMap::Id: @@ -2062,8 +1952,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::MicrowaveOvenControl::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::MicrowaveOvenControl::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::MicrowaveOvenControl::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::MicrowaveOvenControl::Attributes::FeatureMap::Id: @@ -2093,8 +1981,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::OperationalState::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::OperationalState::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::OperationalState::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::OperationalState::Attributes::FeatureMap::Id: @@ -2124,8 +2010,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::RvcOperationalState::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::RvcOperationalState::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::RvcOperationalState::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::RvcOperationalState::Attributes::FeatureMap::Id: @@ -2149,8 +2033,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::ScenesManagement::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::ScenesManagement::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::ScenesManagement::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::ScenesManagement::Attributes::FeatureMap::Id: @@ -2180,8 +2062,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::HepaFilterMonitoring::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::HepaFilterMonitoring::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::HepaFilterMonitoring::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::HepaFilterMonitoring::Attributes::FeatureMap::Id: @@ -2211,8 +2091,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::ActivatedCarbonFilterMonitoring::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::ActivatedCarbonFilterMonitoring::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::ActivatedCarbonFilterMonitoring::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::ActivatedCarbonFilterMonitoring::Attributes::FeatureMap::Id: @@ -2246,8 +2124,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::BooleanStateConfiguration::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::BooleanStateConfiguration::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::BooleanStateConfiguration::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::BooleanStateConfiguration::Attributes::FeatureMap::Id: @@ -2287,8 +2163,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::ValveConfigurationAndControl::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::ValveConfigurationAndControl::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::ValveConfigurationAndControl::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::ValveConfigurationAndControl::Attributes::FeatureMap::Id: @@ -2344,8 +2218,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::ElectricalPowerMeasurement::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::ElectricalPowerMeasurement::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::ElectricalPowerMeasurement::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::ElectricalPowerMeasurement::Attributes::FeatureMap::Id: @@ -2375,8 +2247,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::ElectricalEnergyMeasurement::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::ElectricalEnergyMeasurement::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::ElectricalEnergyMeasurement::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::ElectricalEnergyMeasurement::Attributes::FeatureMap::Id: @@ -2406,8 +2276,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::WaterHeaterManagement::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::WaterHeaterManagement::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::WaterHeaterManagement::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::WaterHeaterManagement::Attributes::FeatureMap::Id: @@ -2441,8 +2309,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::DemandResponseLoadControl::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::DemandResponseLoadControl::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::DemandResponseLoadControl::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::DemandResponseLoadControl::Attributes::FeatureMap::Id: @@ -2464,8 +2330,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::Messages::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::Messages::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::Messages::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::Messages::Attributes::FeatureMap::Id: @@ -2499,8 +2363,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::DeviceEnergyManagement::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::DeviceEnergyManagement::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::DeviceEnergyManagement::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::DeviceEnergyManagement::Attributes::FeatureMap::Id: @@ -2564,8 +2426,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::EnergyEvse::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::EnergyEvse::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::EnergyEvse::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::EnergyEvse::Attributes::FeatureMap::Id: @@ -2593,8 +2453,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::EnergyPreference::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::EnergyPreference::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::EnergyPreference::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::EnergyPreference::Attributes::FeatureMap::Id: @@ -2616,8 +2474,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::PowerTopology::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::PowerTopology::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::PowerTopology::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::PowerTopology::Attributes::FeatureMap::Id: @@ -2639,8 +2495,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::EnergyEvseMode::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::EnergyEvseMode::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::EnergyEvseMode::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::EnergyEvseMode::Attributes::FeatureMap::Id: @@ -2662,8 +2516,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::WaterHeaterMode::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::WaterHeaterMode::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::WaterHeaterMode::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::WaterHeaterMode::Attributes::FeatureMap::Id: @@ -2685,8 +2537,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::DeviceEnergyManagementMode::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::DeviceEnergyManagementMode::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::DeviceEnergyManagementMode::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::DeviceEnergyManagementMode::Attributes::FeatureMap::Id: @@ -2794,8 +2644,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::DoorLock::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::DoorLock::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::DoorLock::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::DoorLock::Attributes::FeatureMap::Id: @@ -2857,8 +2705,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::WindowCovering::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::WindowCovering::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::WindowCovering::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::WindowCovering::Attributes::FeatureMap::Id: @@ -2888,8 +2734,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::ServiceArea::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::ServiceArea::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::ServiceArea::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::ServiceArea::Attributes::FeatureMap::Id: @@ -2953,8 +2797,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::PumpConfigurationAndControl::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::PumpConfigurationAndControl::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::PumpConfigurationAndControl::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::PumpConfigurationAndControl::Attributes::FeatureMap::Id: @@ -3092,8 +2934,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::Thermostat::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::Thermostat::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::Thermostat::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::Thermostat::Attributes::FeatureMap::Id: @@ -3135,8 +2975,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::FanControl::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::FanControl::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::FanControl::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::FanControl::Attributes::FeatureMap::Id: @@ -3160,8 +2998,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::ThermostatUserInterfaceConfiguration::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::ThermostatUserInterfaceConfiguration::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::ThermostatUserInterfaceConfiguration::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::ThermostatUserInterfaceConfiguration::Attributes::FeatureMap::Id: @@ -3283,8 +3119,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::ColorControl::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::ColorControl::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::ColorControl::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::ColorControl::Attributes::FeatureMap::Id: @@ -3330,8 +3164,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::BallastConfiguration::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::BallastConfiguration::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::BallastConfiguration::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::BallastConfiguration::Attributes::FeatureMap::Id: @@ -3359,8 +3191,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::IlluminanceMeasurement::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::IlluminanceMeasurement::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::IlluminanceMeasurement::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::IlluminanceMeasurement::Attributes::FeatureMap::Id: @@ -3386,8 +3216,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::TemperatureMeasurement::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::TemperatureMeasurement::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::TemperatureMeasurement::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::TemperatureMeasurement::Attributes::FeatureMap::Id: @@ -3423,8 +3251,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::PressureMeasurement::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::PressureMeasurement::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::PressureMeasurement::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::PressureMeasurement::Attributes::FeatureMap::Id: @@ -3450,8 +3276,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::FlowMeasurement::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::FlowMeasurement::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::FlowMeasurement::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::FlowMeasurement::Attributes::FeatureMap::Id: @@ -3477,8 +3301,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::RelativeHumidityMeasurement::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::RelativeHumidityMeasurement::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::RelativeHumidityMeasurement::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::RelativeHumidityMeasurement::Attributes::FeatureMap::Id: @@ -3524,8 +3346,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::OccupancySensing::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::OccupancySensing::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::OccupancySensing::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::OccupancySensing::Attributes::FeatureMap::Id: @@ -3565,8 +3385,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::CarbonMonoxideConcentrationMeasurement::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::CarbonMonoxideConcentrationMeasurement::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::CarbonMonoxideConcentrationMeasurement::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::CarbonMonoxideConcentrationMeasurement::Attributes::FeatureMap::Id: @@ -3606,8 +3424,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::CarbonDioxideConcentrationMeasurement::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::CarbonDioxideConcentrationMeasurement::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::CarbonDioxideConcentrationMeasurement::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::CarbonDioxideConcentrationMeasurement::Attributes::FeatureMap::Id: @@ -3647,8 +3463,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::NitrogenDioxideConcentrationMeasurement::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::NitrogenDioxideConcentrationMeasurement::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::NitrogenDioxideConcentrationMeasurement::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::NitrogenDioxideConcentrationMeasurement::Attributes::FeatureMap::Id: @@ -3688,8 +3502,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::OzoneConcentrationMeasurement::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::OzoneConcentrationMeasurement::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::OzoneConcentrationMeasurement::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::OzoneConcentrationMeasurement::Attributes::FeatureMap::Id: @@ -3729,8 +3541,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::Pm25ConcentrationMeasurement::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::Pm25ConcentrationMeasurement::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::Pm25ConcentrationMeasurement::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::Pm25ConcentrationMeasurement::Attributes::FeatureMap::Id: @@ -3770,8 +3580,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::FormaldehydeConcentrationMeasurement::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::FormaldehydeConcentrationMeasurement::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::FormaldehydeConcentrationMeasurement::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::FormaldehydeConcentrationMeasurement::Attributes::FeatureMap::Id: @@ -3811,8 +3619,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::Pm1ConcentrationMeasurement::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::Pm1ConcentrationMeasurement::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::Pm1ConcentrationMeasurement::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::Pm1ConcentrationMeasurement::Attributes::FeatureMap::Id: @@ -3852,8 +3658,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::Pm10ConcentrationMeasurement::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::Pm10ConcentrationMeasurement::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::Pm10ConcentrationMeasurement::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::Pm10ConcentrationMeasurement::Attributes::FeatureMap::Id: @@ -3893,8 +3697,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::TotalVolatileOrganicCompoundsConcentrationMeasurement::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::TotalVolatileOrganicCompoundsConcentrationMeasurement::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::TotalVolatileOrganicCompoundsConcentrationMeasurement::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::TotalVolatileOrganicCompoundsConcentrationMeasurement::Attributes::FeatureMap::Id: @@ -3934,8 +3736,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::RadonConcentrationMeasurement::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::RadonConcentrationMeasurement::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::RadonConcentrationMeasurement::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::RadonConcentrationMeasurement::Attributes::FeatureMap::Id: @@ -3957,8 +3757,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::WiFiNetworkManagement::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::WiFiNetworkManagement::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::WiFiNetworkManagement::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::WiFiNetworkManagement::Attributes::FeatureMap::Id: @@ -3988,8 +3786,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::ThreadBorderRouterManagement::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::ThreadBorderRouterManagement::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::ThreadBorderRouterManagement::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::ThreadBorderRouterManagement::Attributes::FeatureMap::Id: @@ -4013,8 +3809,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::ThreadNetworkDirectory::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::ThreadNetworkDirectory::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::ThreadNetworkDirectory::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::ThreadNetworkDirectory::Attributes::FeatureMap::Id: @@ -4036,8 +3830,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::WakeOnLan::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::WakeOnLan::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::WakeOnLan::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::WakeOnLan::Attributes::FeatureMap::Id: @@ -4061,8 +3853,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::Channel::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::Channel::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::Channel::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::Channel::Attributes::FeatureMap::Id: @@ -4084,8 +3874,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::TargetNavigator::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::TargetNavigator::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::TargetNavigator::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::TargetNavigator::Attributes::FeatureMap::Id: @@ -4125,8 +3913,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::MediaPlayback::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::MediaPlayback::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::MediaPlayback::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::MediaPlayback::Attributes::FeatureMap::Id: @@ -4148,8 +3934,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::MediaInput::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::MediaInput::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::MediaInput::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::MediaInput::Attributes::FeatureMap::Id: @@ -4167,8 +3951,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::LowPower::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::LowPower::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::LowPower::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::LowPower::Attributes::FeatureMap::Id: @@ -4186,8 +3968,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::KeypadInput::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::KeypadInput::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::KeypadInput::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::KeypadInput::Attributes::FeatureMap::Id: @@ -4209,8 +3989,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::ContentLauncher::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::ContentLauncher::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::ContentLauncher::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::ContentLauncher::Attributes::FeatureMap::Id: @@ -4232,8 +4010,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::AudioOutput::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::AudioOutput::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::AudioOutput::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::AudioOutput::Attributes::FeatureMap::Id: @@ -4255,8 +4031,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::ApplicationLauncher::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::ApplicationLauncher::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::ApplicationLauncher::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::ApplicationLauncher::Attributes::FeatureMap::Id: @@ -4290,8 +4064,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::ApplicationBasic::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::ApplicationBasic::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::ApplicationBasic::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::ApplicationBasic::Attributes::FeatureMap::Id: @@ -4309,8 +4081,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::AccountLogin::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::AccountLogin::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::AccountLogin::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::AccountLogin::Attributes::FeatureMap::Id: @@ -4344,8 +4114,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::ContentControl::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::ContentControl::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::ContentControl::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::ContentControl::Attributes::FeatureMap::Id: @@ -4363,8 +4131,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::ContentAppObserver::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::ContentAppObserver::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::ContentAppObserver::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::ContentAppObserver::Attributes::FeatureMap::Id: @@ -4390,8 +4156,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::ZoneManagement::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::ZoneManagement::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::ZoneManagement::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::ZoneManagement::Attributes::FeatureMap::Id: @@ -4503,8 +4267,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::CameraAvStreamManagement::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::CameraAvStreamManagement::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::CameraAvStreamManagement::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::CameraAvStreamManagement::Attributes::FeatureMap::Id: @@ -4524,8 +4286,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::WebRTCTransportProvider::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::WebRTCTransportProvider::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::WebRTCTransportProvider::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::WebRTCTransportProvider::Attributes::FeatureMap::Id: @@ -4545,8 +4305,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::WebRTCTransportRequestor::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::WebRTCTransportRequestor::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::WebRTCTransportRequestor::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::WebRTCTransportRequestor::Attributes::FeatureMap::Id: @@ -4570,8 +4328,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::Chime::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::Chime::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::Chime::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::Chime::Attributes::FeatureMap::Id: @@ -4593,8 +4349,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::EcosystemInformation::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::EcosystemInformation::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::EcosystemInformation::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::EcosystemInformation::Attributes::FeatureMap::Id: @@ -4614,8 +4368,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::CommissionerControl::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::CommissionerControl::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::CommissionerControl::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::CommissionerControl::Attributes::FeatureMap::Id: @@ -4809,8 +4561,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::UnitTesting::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::UnitTesting::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::UnitTesting::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::UnitTesting::Attributes::FeatureMap::Id: @@ -4830,8 +4580,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::FaultInjection::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::FaultInjection::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::FaultInjection::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::FaultInjection::Attributes::FeatureMap::Id: @@ -4851,8 +4599,6 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "GeneratedCommandList"; case chip::app::Clusters::SampleMei::Attributes::AcceptedCommandList::Id: return "AcceptedCommandList"; - case chip::app::Clusters::SampleMei::Attributes::EventList::Id: - return "EventList"; case chip::app::Clusters::SampleMei::Attributes::AttributeList::Id: return "AttributeList"; case chip::app::Clusters::SampleMei::Attributes::FeatureMap::Id: diff --git a/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h b/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h index cecd156144f022..4dc01523ea8db8 100644 --- a/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h +++ b/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h @@ -178,7 +178,6 @@ | * IdentifyType | 0x0001 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -651,92 +650,6 @@ class SubscribeAttributeIdentifyAcceptedCommandList : public SubscribeAttribute } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadIdentifyEventList : public ReadAttribute { -public: - ReadIdentifyEventList() - : ReadAttribute("event-list") - { - } - - ~ReadIdentifyEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::Identify::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::Identify::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterIdentify alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"Identify.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("Identify EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeIdentifyEventList : public SubscribeAttribute { -public: - SubscribeAttributeIdentifyEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeIdentifyEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::Identify::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::Identify::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterIdentify alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"Identify.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -998,7 +911,6 @@ class SubscribeAttributeIdentifyClusterRevision : public SubscribeAttribute { | * NameSupport | 0x0000 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -1569,92 +1481,6 @@ class SubscribeAttributeGroupsAcceptedCommandList : public SubscribeAttribute { } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadGroupsEventList : public ReadAttribute { -public: - ReadGroupsEventList() - : ReadAttribute("event-list") - { - } - - ~ReadGroupsEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::Groups::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::Groups::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterGroups alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"Groups.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("Groups EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeGroupsEventList : public SubscribeAttribute { -public: - SubscribeAttributeGroupsEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeGroupsEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::Groups::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::Groups::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterGroups alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"Groups.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -1920,7 +1746,6 @@ class SubscribeAttributeGroupsClusterRevision : public SubscribeAttribute { | * StartUpOnOff | 0x4003 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -2904,92 +2729,6 @@ class SubscribeAttributeOnOffAcceptedCommandList : public SubscribeAttribute { } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadOnOffEventList : public ReadAttribute { -public: - ReadOnOffEventList() - : ReadAttribute("event-list") - { - } - - ~ReadOnOffEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::OnOff::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::OnOff::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterOnOff alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"OnOff.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("OnOff EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeOnOffEventList : public SubscribeAttribute { -public: - SubscribeAttributeOnOffEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeOnOffEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::OnOff::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::OnOff::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterOnOff alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"OnOff.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -3267,7 +3006,6 @@ class SubscribeAttributeOnOffClusterRevision : public SubscribeAttribute { | * StartUpCurrentLevel | 0x4000 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -5380,92 +5118,6 @@ class SubscribeAttributeLevelControlAcceptedCommandList : public SubscribeAttrib } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadLevelControlEventList : public ReadAttribute { -public: - ReadLevelControlEventList() - : ReadAttribute("event-list") - { - } - - ~ReadLevelControlEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::LevelControl::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::LevelControl::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterLevelControl alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"LevelControl.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("LevelControl EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeLevelControlEventList : public SubscribeAttribute { -public: - SubscribeAttributeLevelControlEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeLevelControlEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::LevelControl::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::LevelControl::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterLevelControl alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"LevelControl.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -5721,7 +5373,6 @@ class SubscribeAttributeLevelControlClusterRevision : public SubscribeAttribute | Attributes: | | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -5901,91 +5552,6 @@ class SubscribeAttributePulseWidthModulationAcceptedCommandList : public Subscri #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL -/* - * Attribute EventList - */ -class ReadPulseWidthModulationEventList : public ReadAttribute { -public: - ReadPulseWidthModulationEventList() - : ReadAttribute("event-list") - { - } - - ~ReadPulseWidthModulationEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::PulseWidthModulation::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::PulseWidthModulation::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterPulseWidthModulation alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"PulseWidthModulation.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("PulseWidthModulation EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributePulseWidthModulationEventList : public SubscribeAttribute { -public: - SubscribeAttributePulseWidthModulationEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributePulseWidthModulationEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::PulseWidthModulation::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::PulseWidthModulation::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterPulseWidthModulation alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"PulseWidthModulation.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -6253,7 +5819,6 @@ class SubscribeAttributePulseWidthModulationClusterRevision : public SubscribeAt | * TagList | 0x0004 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -6839,92 +6404,6 @@ class SubscribeAttributeDescriptorAcceptedCommandList : public SubscribeAttribut } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadDescriptorEventList : public ReadAttribute { -public: - ReadDescriptorEventList() - : ReadAttribute("event-list") - { - } - - ~ReadDescriptorEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::Descriptor::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::Descriptor::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterDescriptor alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"Descriptor.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("Descriptor EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeDescriptorEventList : public SubscribeAttribute { -public: - SubscribeAttributeDescriptorEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeDescriptorEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::Descriptor::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::Descriptor::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterDescriptor alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"Descriptor.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -7180,7 +6659,6 @@ class SubscribeAttributeDescriptorClusterRevision : public SubscribeAttribute { | * Binding | 0x0000 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -7511,92 +6989,6 @@ class SubscribeAttributeBindingAcceptedCommandList : public SubscribeAttribute { } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadBindingEventList : public ReadAttribute { -public: - ReadBindingEventList() - : ReadAttribute("event-list") - { - } - - ~ReadBindingEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::Binding::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::Binding::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterBinding alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"Binding.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("Binding EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeBindingEventList : public SubscribeAttribute { -public: - SubscribeAttributeBindingEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeBindingEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::Binding::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::Binding::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterBinding alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"Binding.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -7859,7 +7251,6 @@ class SubscribeAttributeBindingClusterRevision : public SubscribeAttribute { | * Arl | 0x0006 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -8864,92 +8255,6 @@ class SubscribeAttributeAccessControlAcceptedCommandList : public SubscribeAttri } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadAccessControlEventList : public ReadAttribute { -public: - ReadAccessControlEventList() - : ReadAttribute("event-list") - { - } - - ~ReadAccessControlEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::AccessControl::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::AccessControl::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterAccessControl alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"AccessControl.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("AccessControl EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeAccessControlEventList : public SubscribeAttribute { -public: - SubscribeAttributeAccessControlEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeAccessControlEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::AccessControl::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::AccessControl::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterAccessControl alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"AccessControl.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -9219,7 +8524,6 @@ class SubscribeAttributeAccessControlClusterRevision : public SubscribeAttribute | * SetupURL | 0x0002 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -10285,92 +9589,6 @@ class SubscribeAttributeActionsAcceptedCommandList : public SubscribeAttribute { } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadActionsEventList : public ReadAttribute { -public: - ReadActionsEventList() - : ReadAttribute("event-list") - { - } - - ~ReadActionsEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::Actions::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::Actions::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterActions alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"Actions.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("Actions EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeActionsEventList : public SubscribeAttribute { -public: - SubscribeAttributeActionsEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeActionsEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::Actions::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::Actions::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterActions alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"Actions.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -10649,7 +9867,6 @@ class SubscribeAttributeActionsClusterRevision : public SubscribeAttribute { | * MaxPathsPerInvoke | 0x0016 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -12841,92 +12058,6 @@ class SubscribeAttributeBasicInformationAcceptedCommandList : public SubscribeAt } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadBasicInformationEventList : public ReadAttribute { -public: - ReadBasicInformationEventList() - : ReadAttribute("event-list") - { - } - - ~ReadBasicInformationEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::BasicInformation::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::BasicInformation::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterBasicInformation alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"BasicInformation.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("BasicInformation EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeBasicInformationEventList : public SubscribeAttribute { -public: - SubscribeAttributeBasicInformationEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeBasicInformationEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::BasicInformation::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::BasicInformation::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterBasicInformation alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"BasicInformation.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -13184,7 +12315,6 @@ class SubscribeAttributeBasicInformationClusterRevision : public SubscribeAttrib | Attributes: | | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -13553,92 +12683,6 @@ class SubscribeAttributeOtaSoftwareUpdateProviderAcceptedCommandList : public Su } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadOtaSoftwareUpdateProviderEventList : public ReadAttribute { -public: - ReadOtaSoftwareUpdateProviderEventList() - : ReadAttribute("event-list") - { - } - - ~ReadOtaSoftwareUpdateProviderEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::OtaSoftwareUpdateProvider::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::OtaSoftwareUpdateProvider::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterOTASoftwareUpdateProvider alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"OTASoftwareUpdateProvider.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("OTASoftwareUpdateProvider EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeOtaSoftwareUpdateProviderEventList : public SubscribeAttribute { -public: - SubscribeAttributeOtaSoftwareUpdateProviderEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeOtaSoftwareUpdateProviderEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::OtaSoftwareUpdateProvider::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::OtaSoftwareUpdateProvider::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterOTASoftwareUpdateProvider alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"OTASoftwareUpdateProvider.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -13898,7 +12942,6 @@ class SubscribeAttributeOtaSoftwareUpdateProviderClusterRevision : public Subscr | * UpdateStateProgress | 0x0003 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -14519,92 +13562,6 @@ class SubscribeAttributeOtaSoftwareUpdateRequestorAcceptedCommandList : public S } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadOtaSoftwareUpdateRequestorEventList : public ReadAttribute { -public: - ReadOtaSoftwareUpdateRequestorEventList() - : ReadAttribute("event-list") - { - } - - ~ReadOtaSoftwareUpdateRequestorEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::OtaSoftwareUpdateRequestor::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::OtaSoftwareUpdateRequestor::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterOTASoftwareUpdateRequestor alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"OTASoftwareUpdateRequestor.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("OTASoftwareUpdateRequestor EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeOtaSoftwareUpdateRequestorEventList : public SubscribeAttribute { -public: - SubscribeAttributeOtaSoftwareUpdateRequestorEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeOtaSoftwareUpdateRequestorEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::OtaSoftwareUpdateRequestor::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::OtaSoftwareUpdateRequestor::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterOTASoftwareUpdateRequestor alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"OTASoftwareUpdateRequestor.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -14861,7 +13818,6 @@ class SubscribeAttributeOtaSoftwareUpdateRequestorClusterRevision : public Subsc | * SupportedLocales | 0x0001 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -15238,92 +14194,6 @@ class SubscribeAttributeLocalizationConfigurationAcceptedCommandList : public Su } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadLocalizationConfigurationEventList : public ReadAttribute { -public: - ReadLocalizationConfigurationEventList() - : ReadAttribute("event-list") - { - } - - ~ReadLocalizationConfigurationEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::LocalizationConfiguration::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::LocalizationConfiguration::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterLocalizationConfiguration alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"LocalizationConfiguration.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("LocalizationConfiguration EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeLocalizationConfigurationEventList : public SubscribeAttribute { -public: - SubscribeAttributeLocalizationConfigurationEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeLocalizationConfigurationEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::LocalizationConfiguration::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::LocalizationConfiguration::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterLocalizationConfiguration alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"LocalizationConfiguration.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -15581,7 +14451,6 @@ class SubscribeAttributeLocalizationConfigurationClusterRevision : public Subscr | * SupportedCalendarTypes | 0x0002 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -16081,92 +14950,6 @@ class SubscribeAttributeTimeFormatLocalizationAcceptedCommandList : public Subsc } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadTimeFormatLocalizationEventList : public ReadAttribute { -public: - ReadTimeFormatLocalizationEventList() - : ReadAttribute("event-list") - { - } - - ~ReadTimeFormatLocalizationEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::TimeFormatLocalization::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::TimeFormatLocalization::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterTimeFormatLocalization alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"TimeFormatLocalization.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("TimeFormatLocalization EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeTimeFormatLocalizationEventList : public SubscribeAttribute { -public: - SubscribeAttributeTimeFormatLocalizationEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeTimeFormatLocalizationEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::TimeFormatLocalization::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::TimeFormatLocalization::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterTimeFormatLocalization alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"TimeFormatLocalization.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -16422,7 +15205,6 @@ class SubscribeAttributeTimeFormatLocalizationClusterRevision : public Subscribe | * TemperatureUnit | 0x0000 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -16717,92 +15499,6 @@ class SubscribeAttributeUnitLocalizationAcceptedCommandList : public SubscribeAt } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadUnitLocalizationEventList : public ReadAttribute { -public: - ReadUnitLocalizationEventList() - : ReadAttribute("event-list") - { - } - - ~ReadUnitLocalizationEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::UnitLocalization::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::UnitLocalization::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterUnitLocalization alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"UnitLocalization.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("UnitLocalization EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeUnitLocalizationEventList : public SubscribeAttribute { -public: - SubscribeAttributeUnitLocalizationEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeUnitLocalizationEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::UnitLocalization::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::UnitLocalization::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterUnitLocalization alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"UnitLocalization.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -17058,7 +15754,6 @@ class SubscribeAttributeUnitLocalizationClusterRevision : public SubscribeAttrib | * Sources | 0x0000 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -17312,92 +16007,6 @@ class SubscribeAttributePowerSourceConfigurationAcceptedCommandList : public Sub } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadPowerSourceConfigurationEventList : public ReadAttribute { -public: - ReadPowerSourceConfigurationEventList() - : ReadAttribute("event-list") - { - } - - ~ReadPowerSourceConfigurationEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::PowerSourceConfiguration::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::PowerSourceConfiguration::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterPowerSourceConfiguration alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"PowerSourceConfiguration.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("PowerSourceConfiguration EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributePowerSourceConfigurationEventList : public SubscribeAttribute { -public: - SubscribeAttributePowerSourceConfigurationEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributePowerSourceConfigurationEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::PowerSourceConfiguration::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::PowerSourceConfiguration::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterPowerSourceConfiguration alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"PowerSourceConfiguration.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -17684,7 +16293,6 @@ class SubscribeAttributePowerSourceConfigurationClusterRevision : public Subscri | * EndpointList | 0x001F | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -20483,92 +19091,6 @@ class SubscribeAttributePowerSourceAcceptedCommandList : public SubscribeAttribu } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadPowerSourceEventList : public ReadAttribute { -public: - ReadPowerSourceEventList() - : ReadAttribute("event-list") - { - } - - ~ReadPowerSourceEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::PowerSource::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::PowerSource::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterPowerSource alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"PowerSource.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("PowerSource EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributePowerSourceEventList : public SubscribeAttribute { -public: - SubscribeAttributePowerSourceEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributePowerSourceEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::PowerSource::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::PowerSource::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterPowerSource alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"PowerSource.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -20837,7 +19359,6 @@ class SubscribeAttributePowerSourceClusterRevision : public SubscribeAttribute { | * TCUpdateDeadline | 0x0009 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -22114,92 +20635,6 @@ class SubscribeAttributeGeneralCommissioningAcceptedCommandList : public Subscri } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadGeneralCommissioningEventList : public ReadAttribute { -public: - ReadGeneralCommissioningEventList() - : ReadAttribute("event-list") - { - } - - ~ReadGeneralCommissioningEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::GeneralCommissioning::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::GeneralCommissioning::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterGeneralCommissioning alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"GeneralCommissioning.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("GeneralCommissioning EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeGeneralCommissioningEventList : public SubscribeAttribute { -public: - SubscribeAttributeGeneralCommissioningEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeGeneralCommissioningEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::GeneralCommissioning::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::GeneralCommissioning::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterGeneralCommissioning alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"GeneralCommissioning.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -22472,7 +20907,6 @@ class SubscribeAttributeGeneralCommissioningClusterRevision : public SubscribeAt | * ThreadVersion | 0x000A | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -24063,92 +22497,6 @@ class SubscribeAttributeNetworkCommissioningAcceptedCommandList : public Subscri } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadNetworkCommissioningEventList : public ReadAttribute { -public: - ReadNetworkCommissioningEventList() - : ReadAttribute("event-list") - { - } - - ~ReadNetworkCommissioningEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::NetworkCommissioning::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::NetworkCommissioning::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterNetworkCommissioning alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"NetworkCommissioning.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("NetworkCommissioning EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeNetworkCommissioningEventList : public SubscribeAttribute { -public: - SubscribeAttributeNetworkCommissioningEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeNetworkCommissioningEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::NetworkCommissioning::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::NetworkCommissioning::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterNetworkCommissioning alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"NetworkCommissioning.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -24404,7 +22752,6 @@ class SubscribeAttributeNetworkCommissioningClusterRevision : public SubscribeAt | Attributes: | | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -24637,92 +22984,6 @@ class SubscribeAttributeDiagnosticLogsAcceptedCommandList : public SubscribeAttr } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadDiagnosticLogsEventList : public ReadAttribute { -public: - ReadDiagnosticLogsEventList() - : ReadAttribute("event-list") - { - } - - ~ReadDiagnosticLogsEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::DiagnosticLogs::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::DiagnosticLogs::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterDiagnosticLogs alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"DiagnosticLogs.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("DiagnosticLogs EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeDiagnosticLogsEventList : public SubscribeAttribute { -public: - SubscribeAttributeDiagnosticLogsEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeDiagnosticLogsEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::DiagnosticLogs::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::DiagnosticLogs::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterDiagnosticLogs alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"DiagnosticLogs.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -24989,7 +23250,6 @@ class SubscribeAttributeDiagnosticLogsClusterRevision : public SubscribeAttribut | * TestEventTriggersEnabled | 0x0008 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -26076,92 +24336,6 @@ class SubscribeAttributeGeneralDiagnosticsAcceptedCommandList : public Subscribe } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadGeneralDiagnosticsEventList : public ReadAttribute { -public: - ReadGeneralDiagnosticsEventList() - : ReadAttribute("event-list") - { - } - - ~ReadGeneralDiagnosticsEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::GeneralDiagnostics::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::GeneralDiagnostics::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterGeneralDiagnostics alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"GeneralDiagnostics.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("GeneralDiagnostics EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeGeneralDiagnosticsEventList : public SubscribeAttribute { -public: - SubscribeAttributeGeneralDiagnosticsEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeGeneralDiagnosticsEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::GeneralDiagnostics::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::GeneralDiagnostics::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterGeneralDiagnostics alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"GeneralDiagnostics.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -26421,7 +24595,6 @@ class SubscribeAttributeGeneralDiagnosticsClusterRevision : public SubscribeAttr | * CurrentHeapHighWatermark | 0x0003 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -26966,92 +25139,6 @@ class SubscribeAttributeSoftwareDiagnosticsAcceptedCommandList : public Subscrib } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadSoftwareDiagnosticsEventList : public ReadAttribute { -public: - ReadSoftwareDiagnosticsEventList() - : ReadAttribute("event-list") - { - } - - ~ReadSoftwareDiagnosticsEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::SoftwareDiagnostics::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::SoftwareDiagnostics::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterSoftwareDiagnostics alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"SoftwareDiagnostics.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("SoftwareDiagnostics EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeSoftwareDiagnosticsEventList : public SubscribeAttribute { -public: - SubscribeAttributeSoftwareDiagnosticsEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeSoftwareDiagnosticsEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::SoftwareDiagnostics::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::SoftwareDiagnostics::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterSoftwareDiagnostics alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"SoftwareDiagnostics.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -27370,7 +25457,6 @@ class SubscribeAttributeSoftwareDiagnosticsClusterRevision : public SubscribeAtt | * ActiveNetworkFaultsList | 0x003E | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -32754,92 +30840,6 @@ class SubscribeAttributeThreadNetworkDiagnosticsAcceptedCommandList : public Sub } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadThreadNetworkDiagnosticsEventList : public ReadAttribute { -public: - ReadThreadNetworkDiagnosticsEventList() - : ReadAttribute("event-list") - { - } - - ~ReadThreadNetworkDiagnosticsEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::ThreadNetworkDiagnostics::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::ThreadNetworkDiagnostics::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"ThreadNetworkDiagnostics.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("ThreadNetworkDiagnostics EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeThreadNetworkDiagnosticsEventList : public SubscribeAttribute { -public: - SubscribeAttributeThreadNetworkDiagnosticsEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeThreadNetworkDiagnosticsEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::ThreadNetworkDiagnostics::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::ThreadNetworkDiagnostics::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterThreadNetworkDiagnostics alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"ThreadNetworkDiagnostics.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -33108,7 +31108,6 @@ class SubscribeAttributeThreadNetworkDiagnosticsClusterRevision : public Subscri | * OverrunCount | 0x000C | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -34393,92 +32392,6 @@ class SubscribeAttributeWiFiNetworkDiagnosticsAcceptedCommandList : public Subsc } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadWiFiNetworkDiagnosticsEventList : public ReadAttribute { -public: - ReadWiFiNetworkDiagnosticsEventList() - : ReadAttribute("event-list") - { - } - - ~ReadWiFiNetworkDiagnosticsEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::WiFiNetworkDiagnostics::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::WiFiNetworkDiagnostics::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterWiFiNetworkDiagnostics alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"WiFiNetworkDiagnostics.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("WiFiNetworkDiagnostics EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeWiFiNetworkDiagnosticsEventList : public SubscribeAttribute { -public: - SubscribeAttributeWiFiNetworkDiagnosticsEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeWiFiNetworkDiagnosticsEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::WiFiNetworkDiagnostics::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::WiFiNetworkDiagnostics::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterWiFiNetworkDiagnostics alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"WiFiNetworkDiagnostics.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -34743,7 +32656,6 @@ class SubscribeAttributeWiFiNetworkDiagnosticsClusterRevision : public Subscribe | * TimeSinceReset | 0x0008 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -35697,92 +33609,6 @@ class SubscribeAttributeEthernetNetworkDiagnosticsAcceptedCommandList : public S } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadEthernetNetworkDiagnosticsEventList : public ReadAttribute { -public: - ReadEthernetNetworkDiagnosticsEventList() - : ReadAttribute("event-list") - { - } - - ~ReadEthernetNetworkDiagnosticsEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::EthernetNetworkDiagnostics::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::EthernetNetworkDiagnostics::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterEthernetNetworkDiagnostics alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"EthernetNetworkDiagnostics.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("EthernetNetworkDiagnostics EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeEthernetNetworkDiagnosticsEventList : public SubscribeAttribute { -public: - SubscribeAttributeEthernetNetworkDiagnosticsEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeEthernetNetworkDiagnosticsEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::EthernetNetworkDiagnostics::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::EthernetNetworkDiagnostics::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterEthernetNetworkDiagnostics alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"EthernetNetworkDiagnostics.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -36056,7 +33882,6 @@ class SubscribeAttributeEthernetNetworkDiagnosticsClusterRevision : public Subsc | * SupportsDNSResolve | 0x000C | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -37668,91 +35493,6 @@ class SubscribeAttributeTimeSynchronizationAcceptedCommandList : public Subscrib #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL -/* - * Attribute EventList - */ -class ReadTimeSynchronizationEventList : public ReadAttribute { -public: - ReadTimeSynchronizationEventList() - : ReadAttribute("event-list") - { - } - - ~ReadTimeSynchronizationEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::TimeSynchronization::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::TimeSynchronization::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterTimeSynchronization alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"TimeSynchronization.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("TimeSynchronization EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeTimeSynchronizationEventList : public SubscribeAttribute { -public: - SubscribeAttributeTimeSynchronizationEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeTimeSynchronizationEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::TimeSynchronization::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::TimeSynchronization::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterTimeSynchronization alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"TimeSynchronization.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -38033,7 +35773,6 @@ class SubscribeAttributeTimeSynchronizationClusterRevision : public SubscribeAtt | * ProductAppearance | 0x0014 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -39709,92 +37448,6 @@ class SubscribeAttributeBridgedDeviceBasicInformationAcceptedCommandList : publi } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadBridgedDeviceBasicInformationEventList : public ReadAttribute { -public: - ReadBridgedDeviceBasicInformationEventList() - : ReadAttribute("event-list") - { - } - - ~ReadBridgedDeviceBasicInformationEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::BridgedDeviceBasicInformation::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::BridgedDeviceBasicInformation::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterBridgedDeviceBasicInformation alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"BridgedDeviceBasicInformation.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("BridgedDeviceBasicInformation EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeBridgedDeviceBasicInformationEventList : public SubscribeAttribute { -public: - SubscribeAttributeBridgedDeviceBasicInformationEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeBridgedDeviceBasicInformationEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::BridgedDeviceBasicInformation::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::BridgedDeviceBasicInformation::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterBridgedDeviceBasicInformation alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"BridgedDeviceBasicInformation.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -40052,7 +37705,6 @@ class SubscribeAttributeBridgedDeviceBasicInformationClusterRevision : public Su | * MultiPressMax | 0x0002 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -40477,92 +38129,6 @@ class SubscribeAttributeSwitchAcceptedCommandList : public SubscribeAttribute { } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadSwitchEventList : public ReadAttribute { -public: - ReadSwitchEventList() - : ReadAttribute("event-list") - { - } - - ~ReadSwitchEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::Switch::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::Switch::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterSwitch alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"Switch.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("Switch EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeSwitchEventList : public SubscribeAttribute { -public: - SubscribeAttributeSwitchEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeSwitchEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::Switch::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::Switch::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterSwitch alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"Switch.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -40823,7 +38389,6 @@ class SubscribeAttributeSwitchClusterRevision : public SubscribeAttribute { | * AdminVendorId | 0x0002 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -41387,92 +38952,6 @@ class SubscribeAttributeAdministratorCommissioningAcceptedCommandList : public S } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadAdministratorCommissioningEventList : public ReadAttribute { -public: - ReadAdministratorCommissioningEventList() - : ReadAttribute("event-list") - { - } - - ~ReadAdministratorCommissioningEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::AdministratorCommissioning::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::AdministratorCommissioning::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterAdministratorCommissioning alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"AdministratorCommissioning.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("AdministratorCommissioning EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeAdministratorCommissioningEventList : public SubscribeAttribute { -public: - SubscribeAttributeAdministratorCommissioningEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeAdministratorCommissioningEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::AdministratorCommissioning::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::AdministratorCommissioning::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterAdministratorCommissioning alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"AdministratorCommissioning.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -41741,7 +39220,6 @@ class SubscribeAttributeAdministratorCommissioningClusterRevision : public Subsc | * CurrentFabricIndex | 0x0005 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -42855,92 +40333,6 @@ class SubscribeAttributeOperationalCredentialsAcceptedCommandList : public Subsc } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadOperationalCredentialsEventList : public ReadAttribute { -public: - ReadOperationalCredentialsEventList() - : ReadAttribute("event-list") - { - } - - ~ReadOperationalCredentialsEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::OperationalCredentials::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::OperationalCredentials::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterOperationalCredentials alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"OperationalCredentials.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("OperationalCredentials EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeOperationalCredentialsEventList : public SubscribeAttribute { -public: - SubscribeAttributeOperationalCredentialsEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeOperationalCredentialsEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::OperationalCredentials::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::OperationalCredentials::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterOperationalCredentials alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"OperationalCredentials.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -43203,7 +40595,6 @@ class SubscribeAttributeOperationalCredentialsClusterRevision : public Subscribe | * MaxGroupKeysPerFabric | 0x0003 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -43997,92 +41388,6 @@ class SubscribeAttributeGroupKeyManagementAcceptedCommandList : public Subscribe } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadGroupKeyManagementEventList : public ReadAttribute { -public: - ReadGroupKeyManagementEventList() - : ReadAttribute("event-list") - { - } - - ~ReadGroupKeyManagementEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::GroupKeyManagement::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::GroupKeyManagement::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterGroupKeyManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"GroupKeyManagement.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("GroupKeyManagement EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeGroupKeyManagementEventList : public SubscribeAttribute { -public: - SubscribeAttributeGroupKeyManagementEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeGroupKeyManagementEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::GroupKeyManagement::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::GroupKeyManagement::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterGroupKeyManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"GroupKeyManagement.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -44338,7 +41643,6 @@ class SubscribeAttributeGroupKeyManagementClusterRevision : public SubscribeAttr | * LabelList | 0x0000 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -44592,92 +41896,6 @@ class SubscribeAttributeFixedLabelAcceptedCommandList : public SubscribeAttribut } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadFixedLabelEventList : public ReadAttribute { -public: - ReadFixedLabelEventList() - : ReadAttribute("event-list") - { - } - - ~ReadFixedLabelEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::FixedLabel::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::FixedLabel::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterFixedLabel alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"FixedLabel.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("FixedLabel EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeFixedLabelEventList : public SubscribeAttribute { -public: - SubscribeAttributeFixedLabelEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeFixedLabelEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::FixedLabel::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::FixedLabel::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterFixedLabel alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"FixedLabel.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -44933,7 +42151,6 @@ class SubscribeAttributeFixedLabelClusterRevision : public SubscribeAttribute { | * LabelList | 0x0000 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -45241,92 +42458,6 @@ class SubscribeAttributeUserLabelAcceptedCommandList : public SubscribeAttribute } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadUserLabelEventList : public ReadAttribute { -public: - ReadUserLabelEventList() - : ReadAttribute("event-list") - { - } - - ~ReadUserLabelEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::UserLabel::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::UserLabel::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterUserLabel alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"UserLabel.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("UserLabel EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeUserLabelEventList : public SubscribeAttribute { -public: - SubscribeAttributeUserLabelEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeUserLabelEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::UserLabel::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::UserLabel::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterUserLabel alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"UserLabel.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -45582,7 +42713,6 @@ class SubscribeAttributeUserLabelClusterRevision : public SubscribeAttribute { | * StateValue | 0x0000 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -45837,92 +42967,6 @@ class SubscribeAttributeBooleanStateAcceptedCommandList : public SubscribeAttrib } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadBooleanStateEventList : public ReadAttribute { -public: - ReadBooleanStateEventList() - : ReadAttribute("event-list") - { - } - - ~ReadBooleanStateEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::BooleanState::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::BooleanState::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterBooleanState alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"BooleanState.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("BooleanState EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeBooleanStateEventList : public SubscribeAttribute { -public: - SubscribeAttributeBooleanStateEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeBooleanStateEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::BooleanState::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::BooleanState::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterBooleanState alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"BooleanState.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -46191,7 +43235,6 @@ class SubscribeAttributeBooleanStateClusterRevision : public SubscribeAttribute | * MaximumCheckInBackOff | 0x0009 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -47435,91 +44478,6 @@ class SubscribeAttributeIcdManagementAcceptedCommandList : public SubscribeAttri #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL -/* - * Attribute EventList - */ -class ReadIcdManagementEventList : public ReadAttribute { -public: - ReadIcdManagementEventList() - : ReadAttribute("event-list") - { - } - - ~ReadIcdManagementEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::IcdManagement::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::IcdManagement::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterICDManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"ICDManagement.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("ICDManagement EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeIcdManagementEventList : public SubscribeAttribute { -public: - SubscribeAttributeIcdManagementEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeIcdManagementEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::IcdManagement::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::IcdManagement::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterICDManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"ICDManagement.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -47790,7 +44748,6 @@ class SubscribeAttributeIcdManagementClusterRevision : public SubscribeAttribute | * TimerState | 0x0002 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -48431,91 +45388,6 @@ class SubscribeAttributeTimerAcceptedCommandList : public SubscribeAttribute { #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL -/* - * Attribute EventList - */ -class ReadTimerEventList : public ReadAttribute { -public: - ReadTimerEventList() - : ReadAttribute("event-list") - { - } - - ~ReadTimerEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::Timer::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::Timer::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterTimer alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"Timer.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("Timer EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeTimerEventList : public SubscribeAttribute { -public: - SubscribeAttributeTimerEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeTimerEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::Timer::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::Timer::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterTimer alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"Timer.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -48789,7 +45661,6 @@ class SubscribeAttributeTimerClusterRevision : public SubscribeAttribute { | * OperationalError | 0x0005 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -49690,91 +46561,6 @@ class SubscribeAttributeOvenCavityOperationalStateAcceptedCommandList : public S #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL -/* - * Attribute EventList - */ -class ReadOvenCavityOperationalStateEventList : public ReadAttribute { -public: - ReadOvenCavityOperationalStateEventList() - : ReadAttribute("event-list") - { - } - - ~ReadOvenCavityOperationalStateEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::OvenCavityOperationalState::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::OvenCavityOperationalState::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterOvenCavityOperationalState alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"OvenCavityOperationalState.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("OvenCavityOperationalState EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeOvenCavityOperationalStateEventList : public SubscribeAttribute { -public: - SubscribeAttributeOvenCavityOperationalStateEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeOvenCavityOperationalStateEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::OvenCavityOperationalState::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::OvenCavityOperationalState::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterOvenCavityOperationalState alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"OvenCavityOperationalState.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -50043,7 +46829,6 @@ class SubscribeAttributeOvenCavityOperationalStateClusterRevision : public Subsc | * OnMode | 0x0003 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -50711,91 +47496,6 @@ class SubscribeAttributeOvenModeAcceptedCommandList : public SubscribeAttribute #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL -/* - * Attribute EventList - */ -class ReadOvenModeEventList : public ReadAttribute { -public: - ReadOvenModeEventList() - : ReadAttribute("event-list") - { - } - - ~ReadOvenModeEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::OvenMode::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::OvenMode::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterOvenMode alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"OvenMode.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("OvenMode EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeOvenModeEventList : public SubscribeAttribute { -public: - SubscribeAttributeOvenModeEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeOvenModeEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::OvenMode::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::OvenMode::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterOvenMode alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"OvenMode.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -51061,7 +47761,6 @@ class SubscribeAttributeOvenModeClusterRevision : public SubscribeAttribute { | * SelectedDrynessLevel | 0x0001 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -51455,91 +48154,6 @@ class SubscribeAttributeLaundryDryerControlsAcceptedCommandList : public Subscri #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL -/* - * Attribute EventList - */ -class ReadLaundryDryerControlsEventList : public ReadAttribute { -public: - ReadLaundryDryerControlsEventList() - : ReadAttribute("event-list") - { - } - - ~ReadLaundryDryerControlsEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::LaundryDryerControls::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::LaundryDryerControls::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterLaundryDryerControls alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"LaundryDryerControls.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("LaundryDryerControls EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeLaundryDryerControlsEventList : public SubscribeAttribute { -public: - SubscribeAttributeLaundryDryerControlsEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeLaundryDryerControlsEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::LaundryDryerControls::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::LaundryDryerControls::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterLaundryDryerControls alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"LaundryDryerControls.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -51809,7 +48423,6 @@ class SubscribeAttributeLaundryDryerControlsClusterRevision : public SubscribeAt | * OnMode | 0x0005 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -52608,92 +49221,6 @@ class SubscribeAttributeModeSelectAcceptedCommandList : public SubscribeAttribut } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadModeSelectEventList : public ReadAttribute { -public: - ReadModeSelectEventList() - : ReadAttribute("event-list") - { - } - - ~ReadModeSelectEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::ModeSelect::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::ModeSelect::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterModeSelect alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"ModeSelect.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("ModeSelect EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeModeSelectEventList : public SubscribeAttribute { -public: - SubscribeAttributeModeSelectEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeModeSelectEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::ModeSelect::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::ModeSelect::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterModeSelect alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"ModeSelect.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -52954,7 +49481,6 @@ class SubscribeAttributeModeSelectClusterRevision : public SubscribeAttribute { | * OnMode | 0x0003 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -53622,91 +50148,6 @@ class SubscribeAttributeLaundryWasherModeAcceptedCommandList : public SubscribeA #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL -/* - * Attribute EventList - */ -class ReadLaundryWasherModeEventList : public ReadAttribute { -public: - ReadLaundryWasherModeEventList() - : ReadAttribute("event-list") - { - } - - ~ReadLaundryWasherModeEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::LaundryWasherMode::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::LaundryWasherMode::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterLaundryWasherMode alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"LaundryWasherMode.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("LaundryWasherMode EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeLaundryWasherModeEventList : public SubscribeAttribute { -public: - SubscribeAttributeLaundryWasherModeEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeLaundryWasherModeEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::LaundryWasherMode::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::LaundryWasherMode::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterLaundryWasherMode alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"LaundryWasherMode.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -53975,7 +50416,6 @@ class SubscribeAttributeLaundryWasherModeClusterRevision : public SubscribeAttri | * OnMode | 0x0003 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -54643,91 +51083,6 @@ class SubscribeAttributeRefrigeratorAndTemperatureControlledCabinetModeAcceptedC #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL -/* - * Attribute EventList - */ -class ReadRefrigeratorAndTemperatureControlledCabinetModeEventList : public ReadAttribute { -public: - ReadRefrigeratorAndTemperatureControlledCabinetModeEventList() - : ReadAttribute("event-list") - { - } - - ~ReadRefrigeratorAndTemperatureControlledCabinetModeEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::RefrigeratorAndTemperatureControlledCabinetMode::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::RefrigeratorAndTemperatureControlledCabinetMode::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterRefrigeratorAndTemperatureControlledCabinetMode alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"RefrigeratorAndTemperatureControlledCabinetMode.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("RefrigeratorAndTemperatureControlledCabinetMode EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeRefrigeratorAndTemperatureControlledCabinetModeEventList : public SubscribeAttribute { -public: - SubscribeAttributeRefrigeratorAndTemperatureControlledCabinetModeEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeRefrigeratorAndTemperatureControlledCabinetModeEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::RefrigeratorAndTemperatureControlledCabinetMode::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::RefrigeratorAndTemperatureControlledCabinetMode::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterRefrigeratorAndTemperatureControlledCabinetMode alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"RefrigeratorAndTemperatureControlledCabinetMode.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -54995,7 +51350,6 @@ class SubscribeAttributeRefrigeratorAndTemperatureControlledCabinetModeClusterRe | * SupportedRinses | 0x0003 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -55600,91 +51954,6 @@ class SubscribeAttributeLaundryWasherControlsAcceptedCommandList : public Subscr #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL -/* - * Attribute EventList - */ -class ReadLaundryWasherControlsEventList : public ReadAttribute { -public: - ReadLaundryWasherControlsEventList() - : ReadAttribute("event-list") - { - } - - ~ReadLaundryWasherControlsEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::LaundryWasherControls::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::LaundryWasherControls::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterLaundryWasherControls alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"LaundryWasherControls.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("LaundryWasherControls EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeLaundryWasherControlsEventList : public SubscribeAttribute { -public: - SubscribeAttributeLaundryWasherControlsEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeLaundryWasherControlsEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::LaundryWasherControls::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::LaundryWasherControls::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterLaundryWasherControls alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"LaundryWasherControls.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -55950,7 +52219,6 @@ class SubscribeAttributeLaundryWasherControlsClusterRevision : public SubscribeA | * CurrentMode | 0x0001 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -56339,92 +52607,6 @@ class SubscribeAttributeRvcRunModeAcceptedCommandList : public SubscribeAttribut } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadRvcRunModeEventList : public ReadAttribute { -public: - ReadRvcRunModeEventList() - : ReadAttribute("event-list") - { - } - - ~ReadRvcRunModeEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::RvcRunMode::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::RvcRunMode::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterRVCRunMode alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"RVCRunMode.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("RVCRunMode EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeRvcRunModeEventList : public SubscribeAttribute { -public: - SubscribeAttributeRvcRunModeEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeRvcRunModeEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::RvcRunMode::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::RvcRunMode::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterRVCRunMode alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"RVCRunMode.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -56682,7 +52864,6 @@ class SubscribeAttributeRvcRunModeClusterRevision : public SubscribeAttribute { | * CurrentMode | 0x0001 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -57071,92 +53252,6 @@ class SubscribeAttributeRvcCleanModeAcceptedCommandList : public SubscribeAttrib } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadRvcCleanModeEventList : public ReadAttribute { -public: - ReadRvcCleanModeEventList() - : ReadAttribute("event-list") - { - } - - ~ReadRvcCleanModeEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::RvcCleanMode::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::RvcCleanMode::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterRVCCleanMode alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"RVCCleanMode.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("RVCCleanMode EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeRvcCleanModeEventList : public SubscribeAttribute { -public: - SubscribeAttributeRvcCleanModeEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeRvcCleanModeEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::RvcCleanMode::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::RvcCleanMode::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterRVCCleanMode alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"RVCCleanMode.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -57419,7 +53514,6 @@ class SubscribeAttributeRvcCleanModeClusterRevision : public SubscribeAttribute | * SupportedTemperatureLevels | 0x0005 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -58177,91 +54271,6 @@ class SubscribeAttributeTemperatureControlAcceptedCommandList : public Subscribe #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL -/* - * Attribute EventList - */ -class ReadTemperatureControlEventList : public ReadAttribute { -public: - ReadTemperatureControlEventList() - : ReadAttribute("event-list") - { - } - - ~ReadTemperatureControlEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::TemperatureControl::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::TemperatureControl::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterTemperatureControl alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"TemperatureControl.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("TemperatureControl EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeTemperatureControlEventList : public SubscribeAttribute { -public: - SubscribeAttributeTemperatureControlEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeTemperatureControlEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::TemperatureControl::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::TemperatureControl::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterTemperatureControl alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"TemperatureControl.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -58528,7 +54537,6 @@ class SubscribeAttributeTemperatureControlClusterRevision : public SubscribeAttr | * Supported | 0x0003 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -58964,91 +54972,6 @@ class SubscribeAttributeRefrigeratorAlarmAcceptedCommandList : public SubscribeA #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL -/* - * Attribute EventList - */ -class ReadRefrigeratorAlarmEventList : public ReadAttribute { -public: - ReadRefrigeratorAlarmEventList() - : ReadAttribute("event-list") - { - } - - ~ReadRefrigeratorAlarmEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::RefrigeratorAlarm::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::RefrigeratorAlarm::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterRefrigeratorAlarm alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"RefrigeratorAlarm.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("RefrigeratorAlarm EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeRefrigeratorAlarmEventList : public SubscribeAttribute { -public: - SubscribeAttributeRefrigeratorAlarmEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeRefrigeratorAlarmEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::RefrigeratorAlarm::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::RefrigeratorAlarm::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterRefrigeratorAlarm alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"RefrigeratorAlarm.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -59317,7 +55240,6 @@ class SubscribeAttributeRefrigeratorAlarmClusterRevision : public SubscribeAttri | * OnMode | 0x0003 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -59985,91 +55907,6 @@ class SubscribeAttributeDishwasherModeAcceptedCommandList : public SubscribeAttr #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL -/* - * Attribute EventList - */ -class ReadDishwasherModeEventList : public ReadAttribute { -public: - ReadDishwasherModeEventList() - : ReadAttribute("event-list") - { - } - - ~ReadDishwasherModeEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::DishwasherMode::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::DishwasherMode::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterDishwasherMode alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"DishwasherMode.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("DishwasherMode EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeDishwasherModeEventList : public SubscribeAttribute { -public: - SubscribeAttributeDishwasherModeEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeDishwasherModeEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::DishwasherMode::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::DishwasherMode::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterDishwasherMode alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"DishwasherMode.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -60333,7 +56170,6 @@ class SubscribeAttributeDishwasherModeClusterRevision : public SubscribeAttribut | * AirQuality | 0x0000 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -60587,92 +56423,6 @@ class SubscribeAttributeAirQualityAcceptedCommandList : public SubscribeAttribut } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadAirQualityEventList : public ReadAttribute { -public: - ReadAirQualityEventList() - : ReadAttribute("event-list") - { - } - - ~ReadAirQualityEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::AirQuality::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::AirQuality::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterAirQuality alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"AirQuality.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("AirQuality EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeAirQualityEventList : public SubscribeAttribute { -public: - SubscribeAttributeAirQualityEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeAirQualityEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::AirQuality::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::AirQuality::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterAirQuality alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"AirQuality.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -60941,7 +56691,6 @@ class SubscribeAttributeAirQualityClusterRevision : public SubscribeAttribute { | * ExpiryDate | 0x000C | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -62275,92 +58024,6 @@ class SubscribeAttributeSmokeCoAlarmAcceptedCommandList : public SubscribeAttrib } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadSmokeCoAlarmEventList : public ReadAttribute { -public: - ReadSmokeCoAlarmEventList() - : ReadAttribute("event-list") - { - } - - ~ReadSmokeCoAlarmEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::SmokeCoAlarm::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::SmokeCoAlarm::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterSmokeCOAlarm alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"SmokeCOAlarm.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("SmokeCOAlarm EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeSmokeCoAlarmEventList : public SubscribeAttribute { -public: - SubscribeAttributeSmokeCoAlarmEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeSmokeCoAlarmEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::SmokeCoAlarm::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::SmokeCoAlarm::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterSmokeCOAlarm alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"SmokeCOAlarm.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -62622,7 +58285,6 @@ class SubscribeAttributeSmokeCoAlarmClusterRevision : public SubscribeAttribute | * Supported | 0x0003 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -63250,91 +58912,6 @@ class SubscribeAttributeDishwasherAlarmAcceptedCommandList : public SubscribeAtt #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL -/* - * Attribute EventList - */ -class ReadDishwasherAlarmEventList : public ReadAttribute { -public: - ReadDishwasherAlarmEventList() - : ReadAttribute("event-list") - { - } - - ~ReadDishwasherAlarmEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::DishwasherAlarm::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::DishwasherAlarm::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterDishwasherAlarm alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"DishwasherAlarm.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("DishwasherAlarm EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeDishwasherAlarmEventList : public SubscribeAttribute { -public: - SubscribeAttributeDishwasherAlarmEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeDishwasherAlarmEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::DishwasherAlarm::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::DishwasherAlarm::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterDishwasherAlarm alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"DishwasherAlarm.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -63600,7 +59177,6 @@ class SubscribeAttributeDishwasherAlarmClusterRevision : public SubscribeAttribu | * CurrentMode | 0x0001 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -63950,91 +59526,6 @@ class SubscribeAttributeMicrowaveOvenModeAcceptedCommandList : public SubscribeA #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL -/* - * Attribute EventList - */ -class ReadMicrowaveOvenModeEventList : public ReadAttribute { -public: - ReadMicrowaveOvenModeEventList() - : ReadAttribute("event-list") - { - } - - ~ReadMicrowaveOvenModeEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::MicrowaveOvenMode::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::MicrowaveOvenMode::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterMicrowaveOvenMode alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"MicrowaveOvenMode.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("MicrowaveOvenMode EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeMicrowaveOvenModeEventList : public SubscribeAttribute { -public: - SubscribeAttributeMicrowaveOvenModeEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeMicrowaveOvenModeEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::MicrowaveOvenMode::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::MicrowaveOvenMode::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterMicrowaveOvenMode alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"MicrowaveOvenMode.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -64309,7 +59800,6 @@ class SubscribeAttributeMicrowaveOvenModeClusterRevision : public SubscribeAttri | * WattRating | 0x0008 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -65405,91 +60895,6 @@ class SubscribeAttributeMicrowaveOvenControlAcceptedCommandList : public Subscri #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL -/* - * Attribute EventList - */ -class ReadMicrowaveOvenControlEventList : public ReadAttribute { -public: - ReadMicrowaveOvenControlEventList() - : ReadAttribute("event-list") - { - } - - ~ReadMicrowaveOvenControlEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::MicrowaveOvenControl::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::MicrowaveOvenControl::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterMicrowaveOvenControl alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"MicrowaveOvenControl.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("MicrowaveOvenControl EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeMicrowaveOvenControlEventList : public SubscribeAttribute { -public: - SubscribeAttributeMicrowaveOvenControlEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeMicrowaveOvenControlEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::MicrowaveOvenControl::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::MicrowaveOvenControl::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterMicrowaveOvenControl alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"MicrowaveOvenControl.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -65762,7 +61167,6 @@ class SubscribeAttributeMicrowaveOvenControlClusterRevision : public SubscribeAt | * OperationalError | 0x0005 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -66628,92 +62032,6 @@ class SubscribeAttributeOperationalStateAcceptedCommandList : public SubscribeAt } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadOperationalStateEventList : public ReadAttribute { -public: - ReadOperationalStateEventList() - : ReadAttribute("event-list") - { - } - - ~ReadOperationalStateEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::OperationalState::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::OperationalState::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterOperationalState alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"OperationalState.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("OperationalState EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeOperationalStateEventList : public SubscribeAttribute { -public: - SubscribeAttributeOperationalStateEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeOperationalStateEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::OperationalState::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::OperationalState::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterOperationalState alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"OperationalState.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -66977,7 +62295,6 @@ class SubscribeAttributeOperationalStateClusterRevision : public SubscribeAttrib | * OperationalError | 0x0005 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -67796,92 +63113,6 @@ class SubscribeAttributeRvcOperationalStateAcceptedCommandList : public Subscrib } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadRvcOperationalStateEventList : public ReadAttribute { -public: - ReadRvcOperationalStateEventList() - : ReadAttribute("event-list") - { - } - - ~ReadRvcOperationalStateEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::RvcOperationalState::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::RvcOperationalState::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterRVCOperationalState alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"RVCOperationalState.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("RVCOperationalState EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeRvcOperationalStateEventList : public SubscribeAttribute { -public: - SubscribeAttributeRvcOperationalStateEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeRvcOperationalStateEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::RvcOperationalState::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::RvcOperationalState::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterRVCOperationalState alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"RVCOperationalState.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -68148,7 +63379,6 @@ class SubscribeAttributeRvcOperationalStateClusterRevision : public SubscribeAtt | * FabricSceneInfo | 0x0002 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -69201,91 +64431,6 @@ class SubscribeAttributeScenesManagementAcceptedCommandList : public SubscribeAt #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL -/* - * Attribute EventList - */ -class ReadScenesManagementEventList : public ReadAttribute { -public: - ReadScenesManagementEventList() - : ReadAttribute("event-list") - { - } - - ~ReadScenesManagementEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::ScenesManagement::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::ScenesManagement::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterScenesManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"ScenesManagement.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("ScenesManagement EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeScenesManagementEventList : public SubscribeAttribute { -public: - SubscribeAttributeScenesManagementEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeScenesManagementEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::ScenesManagement::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::ScenesManagement::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterScenesManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"ScenesManagement.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -69555,7 +64700,6 @@ class SubscribeAttributeScenesManagementClusterRevision : public SubscribeAttrib | * ReplacementProductList | 0x0005 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -70307,92 +65451,6 @@ class SubscribeAttributeHepaFilterMonitoringAcceptedCommandList : public Subscri } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadHepaFilterMonitoringEventList : public ReadAttribute { -public: - ReadHepaFilterMonitoringEventList() - : ReadAttribute("event-list") - { - } - - ~ReadHepaFilterMonitoringEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::HepaFilterMonitoring::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::HepaFilterMonitoring::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterHEPAFilterMonitoring alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"HEPAFilterMonitoring.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("HEPAFilterMonitoring EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeHepaFilterMonitoringEventList : public SubscribeAttribute { -public: - SubscribeAttributeHepaFilterMonitoringEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeHepaFilterMonitoringEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::HepaFilterMonitoring::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::HepaFilterMonitoring::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterHEPAFilterMonitoring alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"HEPAFilterMonitoring.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -70654,7 +65712,6 @@ class SubscribeAttributeHepaFilterMonitoringClusterRevision : public SubscribeAt | * ReplacementProductList | 0x0005 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -71406,92 +66463,6 @@ class SubscribeAttributeActivatedCarbonFilterMonitoringAcceptedCommandList : pub } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadActivatedCarbonFilterMonitoringEventList : public ReadAttribute { -public: - ReadActivatedCarbonFilterMonitoringEventList() - : ReadAttribute("event-list") - { - } - - ~ReadActivatedCarbonFilterMonitoringEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::ActivatedCarbonFilterMonitoring::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::ActivatedCarbonFilterMonitoring::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterActivatedCarbonFilterMonitoring alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"ActivatedCarbonFilterMonitoring.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("ActivatedCarbonFilterMonitoring EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeActivatedCarbonFilterMonitoringEventList : public SubscribeAttribute { -public: - SubscribeAttributeActivatedCarbonFilterMonitoringEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeActivatedCarbonFilterMonitoringEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::ActivatedCarbonFilterMonitoring::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::ActivatedCarbonFilterMonitoring::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterActivatedCarbonFilterMonitoring alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"ActivatedCarbonFilterMonitoring.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -71756,7 +66727,6 @@ class SubscribeAttributeActivatedCarbonFilterMonitoringClusterRevision : public | * SensorFault | 0x0007 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -72721,92 +67691,6 @@ class SubscribeAttributeBooleanStateConfigurationAcceptedCommandList : public Su } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadBooleanStateConfigurationEventList : public ReadAttribute { -public: - ReadBooleanStateConfigurationEventList() - : ReadAttribute("event-list") - { - } - - ~ReadBooleanStateConfigurationEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::BooleanStateConfiguration::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::BooleanStateConfiguration::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterBooleanStateConfiguration alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"BooleanStateConfiguration.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("BooleanStateConfiguration EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeBooleanStateConfigurationEventList : public SubscribeAttribute { -public: - SubscribeAttributeBooleanStateConfigurationEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeBooleanStateConfigurationEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::BooleanStateConfiguration::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::BooleanStateConfiguration::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterBooleanStateConfiguration alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"BooleanStateConfiguration.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -73074,7 +67958,6 @@ class SubscribeAttributeBooleanStateConfigurationClusterRevision : public Subscr | * LevelStep | 0x000A | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -74340,92 +69223,6 @@ class SubscribeAttributeValveConfigurationAndControlAcceptedCommandList : public } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadValveConfigurationAndControlEventList : public ReadAttribute { -public: - ReadValveConfigurationAndControlEventList() - : ReadAttribute("event-list") - { - } - - ~ReadValveConfigurationAndControlEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::ValveConfigurationAndControl::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::ValveConfigurationAndControl::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterValveConfigurationAndControl alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"ValveConfigurationAndControl.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("ValveConfigurationAndControl EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeValveConfigurationAndControlEventList : public SubscribeAttribute { -public: - SubscribeAttributeValveConfigurationAndControlEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeValveConfigurationAndControlEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::ValveConfigurationAndControl::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::ValveConfigurationAndControl::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterValveConfigurationAndControl alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"ValveConfigurationAndControl.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -74699,7 +69496,6 @@ class SubscribeAttributeValveConfigurationAndControlClusterRevision : public Sub | * NeutralCurrent | 0x0012 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -76430,92 +71226,6 @@ class SubscribeAttributeElectricalPowerMeasurementAcceptedCommandList : public S } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadElectricalPowerMeasurementEventList : public ReadAttribute { -public: - ReadElectricalPowerMeasurementEventList() - : ReadAttribute("event-list") - { - } - - ~ReadElectricalPowerMeasurementEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::ElectricalPowerMeasurement::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::ElectricalPowerMeasurement::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterElectricalPowerMeasurement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"ElectricalPowerMeasurement.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("ElectricalPowerMeasurement EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeElectricalPowerMeasurementEventList : public SubscribeAttribute { -public: - SubscribeAttributeElectricalPowerMeasurementEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeElectricalPowerMeasurementEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::ElectricalPowerMeasurement::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::ElectricalPowerMeasurement::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterElectricalPowerMeasurement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"ElectricalPowerMeasurement.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -76776,7 +71486,6 @@ class SubscribeAttributeElectricalPowerMeasurementClusterRevision : public Subsc | * CumulativeEnergyReset | 0x0005 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -77442,92 +72151,6 @@ class SubscribeAttributeElectricalEnergyMeasurementAcceptedCommandList : public } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadElectricalEnergyMeasurementEventList : public ReadAttribute { -public: - ReadElectricalEnergyMeasurementEventList() - : ReadAttribute("event-list") - { - } - - ~ReadElectricalEnergyMeasurementEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::ElectricalEnergyMeasurement::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::ElectricalEnergyMeasurement::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterElectricalEnergyMeasurement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"ElectricalEnergyMeasurement.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("ElectricalEnergyMeasurement EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeElectricalEnergyMeasurementEventList : public SubscribeAttribute { -public: - SubscribeAttributeElectricalEnergyMeasurementEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeElectricalEnergyMeasurementEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::ElectricalEnergyMeasurement::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::ElectricalEnergyMeasurement::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterElectricalEnergyMeasurement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"ElectricalEnergyMeasurement.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -77791,7 +72414,6 @@ class SubscribeAttributeElectricalEnergyMeasurementClusterRevision : public Subs | * BoostState | 0x0005 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -78611,91 +73233,6 @@ class SubscribeAttributeWaterHeaterManagementAcceptedCommandList : public Subscr #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL -/* - * Attribute EventList - */ -class ReadWaterHeaterManagementEventList : public ReadAttribute { -public: - ReadWaterHeaterManagementEventList() - : ReadAttribute("event-list") - { - } - - ~ReadWaterHeaterManagementEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterManagement::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::WaterHeaterManagement::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterWaterHeaterManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"WaterHeaterManagement.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("WaterHeaterManagement EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeWaterHeaterManagementEventList : public SubscribeAttribute { -public: - SubscribeAttributeWaterHeaterManagementEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeWaterHeaterManagementEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterManagement::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::WaterHeaterManagement::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterWaterHeaterManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"WaterHeaterManagement.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -78972,7 +73509,6 @@ class SubscribeAttributeWaterHeaterManagementClusterRevision : public SubscribeA | * DefaultRandomDuration | 0x0007 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -80296,91 +74832,6 @@ class SubscribeAttributeDemandResponseLoadControlAcceptedCommandList : public Su #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL -/* - * Attribute EventList - */ -class ReadDemandResponseLoadControlEventList : public ReadAttribute { -public: - ReadDemandResponseLoadControlEventList() - : ReadAttribute("event-list") - { - } - - ~ReadDemandResponseLoadControlEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::DemandResponseLoadControl::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::DemandResponseLoadControl::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterDemandResponseLoadControl alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"DemandResponseLoadControl.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("DemandResponseLoadControl EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeDemandResponseLoadControlEventList : public SubscribeAttribute { -public: - SubscribeAttributeDemandResponseLoadControlEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeDemandResponseLoadControlEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::DemandResponseLoadControl::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::DemandResponseLoadControl::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterDemandResponseLoadControl alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"DemandResponseLoadControl.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -80648,7 +75099,6 @@ class SubscribeAttributeDemandResponseLoadControlClusterRevision : public Subscr | * ActiveMessageIDs | 0x0001 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -81186,91 +75636,6 @@ class SubscribeAttributeMessagesAcceptedCommandList : public SubscribeAttribute #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL -/* - * Attribute EventList - */ -class ReadMessagesEventList : public ReadAttribute { -public: - ReadMessagesEventList() - : ReadAttribute("event-list") - { - } - - ~ReadMessagesEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::Messages::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::Messages::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterMessages alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"Messages.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("Messages EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeMessagesEventList : public SubscribeAttribute { -public: - SubscribeAttributeMessagesEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeMessagesEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::Messages::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::Messages::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterMessages alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"Messages.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -81550,7 +75915,6 @@ class SubscribeAttributeMessagesClusterRevision : public SubscribeAttribute { | * OptOutState | 0x0007 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -82904,91 +77268,6 @@ class SubscribeAttributeDeviceEnergyManagementAcceptedCommandList : public Subsc #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL -/* - * Attribute EventList - */ -class ReadDeviceEnergyManagementEventList : public ReadAttribute { -public: - ReadDeviceEnergyManagementEventList() - : ReadAttribute("event-list") - { - } - - ~ReadDeviceEnergyManagementEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::DeviceEnergyManagement::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::DeviceEnergyManagement::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterDeviceEnergyManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"DeviceEnergyManagement.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("DeviceEnergyManagement EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeDeviceEnergyManagementEventList : public SubscribeAttribute { -public: - SubscribeAttributeDeviceEnergyManagementEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeDeviceEnergyManagementEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::DeviceEnergyManagement::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::DeviceEnergyManagement::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterDeviceEnergyManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"DeviceEnergyManagement.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -83282,7 +77561,6 @@ class SubscribeAttributeDeviceEnergyManagementClusterRevision : public Subscribe | * SessionEnergyDischarged | 0x0043 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -85956,91 +80234,6 @@ class SubscribeAttributeEnergyEvseAcceptedCommandList : public SubscribeAttribut #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL -/* - * Attribute EventList - */ -class ReadEnergyEvseEventList : public ReadAttribute { -public: - ReadEnergyEvseEventList() - : ReadAttribute("event-list") - { - } - - ~ReadEnergyEvseEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::EnergyEvse::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::EnergyEvse::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterEnergyEVSE alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"EnergyEVSE.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("EnergyEVSE EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeEnergyEvseEventList : public SubscribeAttribute { -public: - SubscribeAttributeEnergyEvseEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeEnergyEvseEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::EnergyEvse::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::EnergyEvse::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterEnergyEVSE alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"EnergyEVSE.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -86309,7 +80502,6 @@ class SubscribeAttributeEnergyEvseClusterRevision : public SubscribeAttribute { | * CurrentLowPowerModeSensitivity | 0x0004 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -86996,91 +81188,6 @@ class SubscribeAttributeEnergyPreferenceAcceptedCommandList : public SubscribeAt #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL -/* - * Attribute EventList - */ -class ReadEnergyPreferenceEventList : public ReadAttribute { -public: - ReadEnergyPreferenceEventList() - : ReadAttribute("event-list") - { - } - - ~ReadEnergyPreferenceEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::EnergyPreference::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::EnergyPreference::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterEnergyPreference alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"EnergyPreference.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("EnergyPreference EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeEnergyPreferenceEventList : public SubscribeAttribute { -public: - SubscribeAttributeEnergyPreferenceEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeEnergyPreferenceEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::EnergyPreference::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::EnergyPreference::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterEnergyPreference alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"EnergyPreference.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -87346,7 +81453,6 @@ class SubscribeAttributeEnergyPreferenceClusterRevision : public SubscribeAttrib | * ActiveEndpoints | 0x0001 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -87696,91 +81802,6 @@ class SubscribeAttributePowerTopologyAcceptedCommandList : public SubscribeAttri #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL -/* - * Attribute EventList - */ -class ReadPowerTopologyEventList : public ReadAttribute { -public: - ReadPowerTopologyEventList() - : ReadAttribute("event-list") - { - } - - ~ReadPowerTopologyEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::PowerTopology::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::PowerTopology::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterPowerTopology alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"PowerTopology.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("PowerTopology EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributePowerTopologyEventList : public SubscribeAttribute { -public: - SubscribeAttributePowerTopologyEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributePowerTopologyEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::PowerTopology::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::PowerTopology::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterPowerTopology alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"PowerTopology.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -88047,7 +82068,6 @@ class SubscribeAttributePowerTopologyClusterRevision : public SubscribeAttribute | * CurrentMode | 0x0001 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -88457,91 +82477,6 @@ class SubscribeAttributeEnergyEvseModeAcceptedCommandList : public SubscribeAttr #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL -/* - * Attribute EventList - */ -class ReadEnergyEvseModeEventList : public ReadAttribute { -public: - ReadEnergyEvseModeEventList() - : ReadAttribute("event-list") - { - } - - ~ReadEnergyEvseModeEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::EnergyEvseMode::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::EnergyEvseMode::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterEnergyEVSEMode alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"EnergyEVSEMode.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("EnergyEVSEMode EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeEnergyEvseModeEventList : public SubscribeAttribute { -public: - SubscribeAttributeEnergyEvseModeEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeEnergyEvseModeEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::EnergyEvseMode::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::EnergyEvseMode::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterEnergyEVSEMode alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"EnergyEVSEMode.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -88808,7 +82743,6 @@ class SubscribeAttributeEnergyEvseModeClusterRevision : public SubscribeAttribut | * CurrentMode | 0x0001 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -89218,91 +83152,6 @@ class SubscribeAttributeWaterHeaterModeAcceptedCommandList : public SubscribeAtt #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL -/* - * Attribute EventList - */ -class ReadWaterHeaterModeEventList : public ReadAttribute { -public: - ReadWaterHeaterModeEventList() - : ReadAttribute("event-list") - { - } - - ~ReadWaterHeaterModeEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterMode::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::WaterHeaterMode::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterWaterHeaterMode alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"WaterHeaterMode.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("WaterHeaterMode EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeWaterHeaterModeEventList : public SubscribeAttribute { -public: - SubscribeAttributeWaterHeaterModeEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeWaterHeaterModeEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::WaterHeaterMode::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::WaterHeaterMode::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterWaterHeaterMode alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"WaterHeaterMode.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -89569,7 +83418,6 @@ class SubscribeAttributeWaterHeaterModeClusterRevision : public SubscribeAttribu | * CurrentMode | 0x0001 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -89979,91 +83827,6 @@ class SubscribeAttributeDeviceEnergyManagementModeAcceptedCommandList : public S #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL -/* - * Attribute EventList - */ -class ReadDeviceEnergyManagementModeEventList : public ReadAttribute { -public: - ReadDeviceEnergyManagementModeEventList() - : ReadAttribute("event-list") - { - } - - ~ReadDeviceEnergyManagementModeEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::DeviceEnergyManagementMode::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::DeviceEnergyManagementMode::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterDeviceEnergyManagementMode alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"DeviceEnergyManagementMode.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("DeviceEnergyManagementMode EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeDeviceEnergyManagementModeEventList : public SubscribeAttribute { -public: - SubscribeAttributeDeviceEnergyManagementModeEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeDeviceEnergyManagementModeEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::DeviceEnergyManagementMode::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::DeviceEnergyManagementMode::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterDeviceEnergyManagementMode alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"DeviceEnergyManagementMode.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -90392,7 +84155,6 @@ class SubscribeAttributeDeviceEnergyManagementModeClusterRevision : public Subsc | * NumberOfAliroEndpointKeysSupported | 0x0088 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -96202,92 +89964,6 @@ class SubscribeAttributeDoorLockAcceptedCommandList : public SubscribeAttribute } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadDoorLockEventList : public ReadAttribute { -public: - ReadDoorLockEventList() - : ReadAttribute("event-list") - { - } - - ~ReadDoorLockEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::DoorLock::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::DoorLock::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"DoorLock.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("DoorLock EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeDoorLockEventList : public SubscribeAttribute { -public: - SubscribeAttributeDoorLockEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeDoorLockEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::DoorLock::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::DoorLock::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterDoorLock alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"DoorLock.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -96571,7 +90247,6 @@ class SubscribeAttributeDoorLockClusterRevision : public SubscribeAttribute { | * SafetyStatus | 0x001A | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -98908,92 +92583,6 @@ class SubscribeAttributeWindowCoveringAcceptedCommandList : public SubscribeAttr } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadWindowCoveringEventList : public ReadAttribute { -public: - ReadWindowCoveringEventList() - : ReadAttribute("event-list") - { - } - - ~ReadWindowCoveringEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::WindowCovering::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::WindowCovering::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterWindowCovering alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"WindowCovering.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("WindowCovering EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeWindowCoveringEventList : public SubscribeAttribute { -public: - SubscribeAttributeWindowCoveringEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeWindowCoveringEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::WindowCovering::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::WindowCovering::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterWindowCovering alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"WindowCovering.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -99257,7 +92846,6 @@ class SubscribeAttributeWindowCoveringClusterRevision : public SubscribeAttribut | * Progress | 0x0005 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -100076,91 +93664,6 @@ class SubscribeAttributeServiceAreaAcceptedCommandList : public SubscribeAttribu #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL -/* - * Attribute EventList - */ -class ReadServiceAreaEventList : public ReadAttribute { -public: - ReadServiceAreaEventList() - : ReadAttribute("event-list") - { - } - - ~ReadServiceAreaEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::ServiceArea::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::ServiceArea::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterServiceArea alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"ServiceArea.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("ServiceArea EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeServiceAreaEventList : public SubscribeAttribute { -public: - SubscribeAttributeServiceAreaEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeServiceAreaEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::ServiceArea::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::ServiceArea::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterServiceArea alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"ServiceArea.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -100446,7 +93949,6 @@ class SubscribeAttributeServiceAreaClusterRevision : public SubscribeAttribute { | * ControlMode | 0x0021 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -102691,92 +96193,6 @@ class SubscribeAttributePumpConfigurationAndControlAcceptedCommandList : public } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadPumpConfigurationAndControlEventList : public ReadAttribute { -public: - ReadPumpConfigurationAndControlEventList() - : ReadAttribute("event-list") - { - } - - ~ReadPumpConfigurationAndControlEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::PumpConfigurationAndControl::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::PumpConfigurationAndControl::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterPumpConfigurationAndControl alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"PumpConfigurationAndControl.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("PumpConfigurationAndControl EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributePumpConfigurationAndControlEventList : public SubscribeAttribute { -public: - SubscribeAttributePumpConfigurationAndControlEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributePumpConfigurationAndControlEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::PumpConfigurationAndControl::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::PumpConfigurationAndControl::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterPumpConfigurationAndControl alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"PumpConfigurationAndControl.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -103098,7 +96514,6 @@ class SubscribeAttributePumpConfigurationAndControlClusterRevision : public Subs | * SetpointHoldExpiryTimestamp | 0x0052 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -109944,92 +103359,6 @@ class SubscribeAttributeThermostatAcceptedCommandList : public SubscribeAttribut } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadThermostatEventList : public ReadAttribute { -public: - ReadThermostatEventList() - : ReadAttribute("event-list") - { - } - - ~ReadThermostatEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::Thermostat::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::Thermostat::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"Thermostat.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("Thermostat EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeThermostatEventList : public SubscribeAttribute { -public: - SubscribeAttributeThermostatEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeThermostatEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::Thermostat::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::Thermostat::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterThermostat alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"Thermostat.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -110297,7 +103626,6 @@ class SubscribeAttributeThermostatClusterRevision : public SubscribeAttribute { | * AirflowDirection | 0x000B | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -111764,92 +105092,6 @@ class SubscribeAttributeFanControlAcceptedCommandList : public SubscribeAttribut } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadFanControlEventList : public ReadAttribute { -public: - ReadFanControlEventList() - : ReadAttribute("event-list") - { - } - - ~ReadFanControlEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::FanControl::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::FanControl::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterFanControl alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"FanControl.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("FanControl EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeFanControlEventList : public SubscribeAttribute { -public: - SubscribeAttributeFanControlEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeFanControlEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::FanControl::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::FanControl::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterFanControl alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"FanControl.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -112107,7 +105349,6 @@ class SubscribeAttributeFanControlClusterRevision : public SubscribeAttribute { | * ScheduleProgrammingVisibility | 0x0002 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -112648,92 +105889,6 @@ class SubscribeAttributeThermostatUserInterfaceConfigurationAcceptedCommandList } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadThermostatUserInterfaceConfigurationEventList : public ReadAttribute { -public: - ReadThermostatUserInterfaceConfigurationEventList() - : ReadAttribute("event-list") - { - } - - ~ReadThermostatUserInterfaceConfigurationEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::ThermostatUserInterfaceConfiguration::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::ThermostatUserInterfaceConfiguration::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterThermostatUserInterfaceConfiguration alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"ThermostatUserInterfaceConfiguration.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("ThermostatUserInterfaceConfiguration EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeThermostatUserInterfaceConfigurationEventList : public SubscribeAttribute { -public: - SubscribeAttributeThermostatUserInterfaceConfigurationEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeThermostatUserInterfaceConfigurationEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::ThermostatUserInterfaceConfiguration::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::ThermostatUserInterfaceConfiguration::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterThermostatUserInterfaceConfiguration alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"ThermostatUserInterfaceConfiguration.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -113059,7 +106214,6 @@ class SubscribeAttributeThermostatUserInterfaceConfigurationClusterRevision : pu | * StartUpColorTemperatureMireds | 0x4010 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -119077,92 +112231,6 @@ class SubscribeAttributeColorControlAcceptedCommandList : public SubscribeAttrib } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadColorControlEventList : public ReadAttribute { -public: - ReadColorControlEventList() - : ReadAttribute("event-list") - { - } - - ~ReadColorControlEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::ColorControl::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::ColorControl::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"ColorControl.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("ColorControl EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeColorControlEventList : public SubscribeAttribute { -public: - SubscribeAttributeColorControlEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeColorControlEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::ColorControl::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::ColorControl::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterColorControl alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"ColorControl.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -119431,7 +112499,6 @@ class SubscribeAttributeColorControlClusterRevision : public SubscribeAttribute | * LampBurnHoursTripPoint | 0x0035 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -121176,92 +114243,6 @@ class SubscribeAttributeBallastConfigurationAcceptedCommandList : public Subscri } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadBallastConfigurationEventList : public ReadAttribute { -public: - ReadBallastConfigurationEventList() - : ReadAttribute("event-list") - { - } - - ~ReadBallastConfigurationEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::BallastConfiguration::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::BallastConfiguration::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterBallastConfiguration alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"BallastConfiguration.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("BallastConfiguration EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeBallastConfigurationEventList : public SubscribeAttribute { -public: - SubscribeAttributeBallastConfigurationEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeBallastConfigurationEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::BallastConfiguration::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::BallastConfiguration::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterBallastConfiguration alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"BallastConfiguration.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -121521,7 +114502,6 @@ class SubscribeAttributeBallastConfigurationClusterRevision : public SubscribeAt | * LightSensorType | 0x0004 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -122103,92 +115083,6 @@ class SubscribeAttributeIlluminanceMeasurementAcceptedCommandList : public Subsc } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadIlluminanceMeasurementEventList : public ReadAttribute { -public: - ReadIlluminanceMeasurementEventList() - : ReadAttribute("event-list") - { - } - - ~ReadIlluminanceMeasurementEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::IlluminanceMeasurement::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::IlluminanceMeasurement::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterIlluminanceMeasurement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"IlluminanceMeasurement.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("IlluminanceMeasurement EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeIlluminanceMeasurementEventList : public SubscribeAttribute { -public: - SubscribeAttributeIlluminanceMeasurementEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeIlluminanceMeasurementEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::IlluminanceMeasurement::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::IlluminanceMeasurement::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterIlluminanceMeasurement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"IlluminanceMeasurement.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -122447,7 +115341,6 @@ class SubscribeAttributeIlluminanceMeasurementClusterRevision : public Subscribe | * Tolerance | 0x0003 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -122947,92 +115840,6 @@ class SubscribeAttributeTemperatureMeasurementAcceptedCommandList : public Subsc } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadTemperatureMeasurementEventList : public ReadAttribute { -public: - ReadTemperatureMeasurementEventList() - : ReadAttribute("event-list") - { - } - - ~ReadTemperatureMeasurementEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::TemperatureMeasurement::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::TemperatureMeasurement::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterTemperatureMeasurement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"TemperatureMeasurement.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("TemperatureMeasurement EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeTemperatureMeasurementEventList : public SubscribeAttribute { -public: - SubscribeAttributeTemperatureMeasurementEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeTemperatureMeasurementEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::TemperatureMeasurement::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::TemperatureMeasurement::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterTemperatureMeasurement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"TemperatureMeasurement.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -123296,7 +116103,6 @@ class SubscribeAttributeTemperatureMeasurementClusterRevision : public Subscribe | * Scale | 0x0014 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -124206,92 +117012,6 @@ class SubscribeAttributePressureMeasurementAcceptedCommandList : public Subscrib } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadPressureMeasurementEventList : public ReadAttribute { -public: - ReadPressureMeasurementEventList() - : ReadAttribute("event-list") - { - } - - ~ReadPressureMeasurementEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::PressureMeasurement::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::PressureMeasurement::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterPressureMeasurement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"PressureMeasurement.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("PressureMeasurement EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributePressureMeasurementEventList : public SubscribeAttribute { -public: - SubscribeAttributePressureMeasurementEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributePressureMeasurementEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::PressureMeasurement::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::PressureMeasurement::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterPressureMeasurement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"PressureMeasurement.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -124550,7 +117270,6 @@ class SubscribeAttributePressureMeasurementClusterRevision : public SubscribeAtt | * Tolerance | 0x0003 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -125050,92 +117769,6 @@ class SubscribeAttributeFlowMeasurementAcceptedCommandList : public SubscribeAtt } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadFlowMeasurementEventList : public ReadAttribute { -public: - ReadFlowMeasurementEventList() - : ReadAttribute("event-list") - { - } - - ~ReadFlowMeasurementEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::FlowMeasurement::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::FlowMeasurement::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterFlowMeasurement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"FlowMeasurement.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("FlowMeasurement EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeFlowMeasurementEventList : public SubscribeAttribute { -public: - SubscribeAttributeFlowMeasurementEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeFlowMeasurementEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::FlowMeasurement::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::FlowMeasurement::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterFlowMeasurement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"FlowMeasurement.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -125394,7 +118027,6 @@ class SubscribeAttributeFlowMeasurementClusterRevision : public SubscribeAttribu | * Tolerance | 0x0003 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -125894,92 +118526,6 @@ class SubscribeAttributeRelativeHumidityMeasurementAcceptedCommandList : public } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadRelativeHumidityMeasurementEventList : public ReadAttribute { -public: - ReadRelativeHumidityMeasurementEventList() - : ReadAttribute("event-list") - { - } - - ~ReadRelativeHumidityMeasurementEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::RelativeHumidityMeasurement::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::RelativeHumidityMeasurement::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterRelativeHumidityMeasurement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"RelativeHumidityMeasurement.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("RelativeHumidityMeasurement EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeRelativeHumidityMeasurementEventList : public SubscribeAttribute { -public: - SubscribeAttributeRelativeHumidityMeasurementEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeRelativeHumidityMeasurementEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::RelativeHumidityMeasurement::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::RelativeHumidityMeasurement::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterRelativeHumidityMeasurement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"RelativeHumidityMeasurement.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -126248,7 +118794,6 @@ class SubscribeAttributeRelativeHumidityMeasurementClusterRevision : public Subs | * PhysicalContactUnoccupiedToOccupiedThreshold | 0x0032 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -127986,92 +120531,6 @@ class SubscribeAttributeOccupancySensingAcceptedCommandList : public SubscribeAt } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadOccupancySensingEventList : public ReadAttribute { -public: - ReadOccupancySensingEventList() - : ReadAttribute("event-list") - { - } - - ~ReadOccupancySensingEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::OccupancySensing::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::OccupancySensing::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterOccupancySensing alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"OccupancySensing.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("OccupancySensing EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeOccupancySensingEventList : public SubscribeAttribute { -public: - SubscribeAttributeOccupancySensingEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeOccupancySensingEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::OccupancySensing::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::OccupancySensing::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterOccupancySensing alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"OccupancySensing.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -128337,7 +120796,6 @@ class SubscribeAttributeOccupancySensingClusterRevision : public SubscribeAttrib | * LevelValue | 0x000A | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -129411,92 +121869,6 @@ class SubscribeAttributeCarbonMonoxideConcentrationMeasurementAcceptedCommandLis } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadCarbonMonoxideConcentrationMeasurementEventList : public ReadAttribute { -public: - ReadCarbonMonoxideConcentrationMeasurementEventList() - : ReadAttribute("event-list") - { - } - - ~ReadCarbonMonoxideConcentrationMeasurementEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::CarbonMonoxideConcentrationMeasurement::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::CarbonMonoxideConcentrationMeasurement::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterCarbonMonoxideConcentrationMeasurement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"CarbonMonoxideConcentrationMeasurement.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("CarbonMonoxideConcentrationMeasurement EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeCarbonMonoxideConcentrationMeasurementEventList : public SubscribeAttribute { -public: - SubscribeAttributeCarbonMonoxideConcentrationMeasurementEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeCarbonMonoxideConcentrationMeasurementEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::CarbonMonoxideConcentrationMeasurement::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::CarbonMonoxideConcentrationMeasurement::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterCarbonMonoxideConcentrationMeasurement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"CarbonMonoxideConcentrationMeasurement.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -129762,7 +122134,6 @@ class SubscribeAttributeCarbonMonoxideConcentrationMeasurementClusterRevision : | * LevelValue | 0x000A | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -130836,92 +123207,6 @@ class SubscribeAttributeCarbonDioxideConcentrationMeasurementAcceptedCommandList } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadCarbonDioxideConcentrationMeasurementEventList : public ReadAttribute { -public: - ReadCarbonDioxideConcentrationMeasurementEventList() - : ReadAttribute("event-list") - { - } - - ~ReadCarbonDioxideConcentrationMeasurementEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::CarbonDioxideConcentrationMeasurement::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::CarbonDioxideConcentrationMeasurement::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterCarbonDioxideConcentrationMeasurement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"CarbonDioxideConcentrationMeasurement.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("CarbonDioxideConcentrationMeasurement EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeCarbonDioxideConcentrationMeasurementEventList : public SubscribeAttribute { -public: - SubscribeAttributeCarbonDioxideConcentrationMeasurementEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeCarbonDioxideConcentrationMeasurementEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::CarbonDioxideConcentrationMeasurement::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::CarbonDioxideConcentrationMeasurement::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterCarbonDioxideConcentrationMeasurement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"CarbonDioxideConcentrationMeasurement.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -131187,7 +123472,6 @@ class SubscribeAttributeCarbonDioxideConcentrationMeasurementClusterRevision : p | * LevelValue | 0x000A | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -132261,92 +124545,6 @@ class SubscribeAttributeNitrogenDioxideConcentrationMeasurementAcceptedCommandLi } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadNitrogenDioxideConcentrationMeasurementEventList : public ReadAttribute { -public: - ReadNitrogenDioxideConcentrationMeasurementEventList() - : ReadAttribute("event-list") - { - } - - ~ReadNitrogenDioxideConcentrationMeasurementEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::NitrogenDioxideConcentrationMeasurement::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::NitrogenDioxideConcentrationMeasurement::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterNitrogenDioxideConcentrationMeasurement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"NitrogenDioxideConcentrationMeasurement.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("NitrogenDioxideConcentrationMeasurement EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeNitrogenDioxideConcentrationMeasurementEventList : public SubscribeAttribute { -public: - SubscribeAttributeNitrogenDioxideConcentrationMeasurementEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeNitrogenDioxideConcentrationMeasurementEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::NitrogenDioxideConcentrationMeasurement::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::NitrogenDioxideConcentrationMeasurement::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterNitrogenDioxideConcentrationMeasurement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"NitrogenDioxideConcentrationMeasurement.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -132612,7 +124810,6 @@ class SubscribeAttributeNitrogenDioxideConcentrationMeasurementClusterRevision : | * LevelValue | 0x000A | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -133686,92 +125883,6 @@ class SubscribeAttributeOzoneConcentrationMeasurementAcceptedCommandList : publi } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadOzoneConcentrationMeasurementEventList : public ReadAttribute { -public: - ReadOzoneConcentrationMeasurementEventList() - : ReadAttribute("event-list") - { - } - - ~ReadOzoneConcentrationMeasurementEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::OzoneConcentrationMeasurement::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::OzoneConcentrationMeasurement::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterOzoneConcentrationMeasurement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"OzoneConcentrationMeasurement.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("OzoneConcentrationMeasurement EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeOzoneConcentrationMeasurementEventList : public SubscribeAttribute { -public: - SubscribeAttributeOzoneConcentrationMeasurementEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeOzoneConcentrationMeasurementEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::OzoneConcentrationMeasurement::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::OzoneConcentrationMeasurement::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterOzoneConcentrationMeasurement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"OzoneConcentrationMeasurement.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -134037,7 +126148,6 @@ class SubscribeAttributeOzoneConcentrationMeasurementClusterRevision : public Su | * LevelValue | 0x000A | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -135111,92 +127221,6 @@ class SubscribeAttributePm25ConcentrationMeasurementAcceptedCommandList : public } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadPm25ConcentrationMeasurementEventList : public ReadAttribute { -public: - ReadPm25ConcentrationMeasurementEventList() - : ReadAttribute("event-list") - { - } - - ~ReadPm25ConcentrationMeasurementEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::Pm25ConcentrationMeasurement::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::Pm25ConcentrationMeasurement::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterPM25ConcentrationMeasurement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"PM25ConcentrationMeasurement.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("PM25ConcentrationMeasurement EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributePm25ConcentrationMeasurementEventList : public SubscribeAttribute { -public: - SubscribeAttributePm25ConcentrationMeasurementEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributePm25ConcentrationMeasurementEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::Pm25ConcentrationMeasurement::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::Pm25ConcentrationMeasurement::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterPM25ConcentrationMeasurement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"PM25ConcentrationMeasurement.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -135462,7 +127486,6 @@ class SubscribeAttributePm25ConcentrationMeasurementClusterRevision : public Sub | * LevelValue | 0x000A | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -136536,92 +128559,6 @@ class SubscribeAttributeFormaldehydeConcentrationMeasurementAcceptedCommandList } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadFormaldehydeConcentrationMeasurementEventList : public ReadAttribute { -public: - ReadFormaldehydeConcentrationMeasurementEventList() - : ReadAttribute("event-list") - { - } - - ~ReadFormaldehydeConcentrationMeasurementEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::FormaldehydeConcentrationMeasurement::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::FormaldehydeConcentrationMeasurement::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterFormaldehydeConcentrationMeasurement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"FormaldehydeConcentrationMeasurement.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("FormaldehydeConcentrationMeasurement EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeFormaldehydeConcentrationMeasurementEventList : public SubscribeAttribute { -public: - SubscribeAttributeFormaldehydeConcentrationMeasurementEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeFormaldehydeConcentrationMeasurementEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::FormaldehydeConcentrationMeasurement::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::FormaldehydeConcentrationMeasurement::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterFormaldehydeConcentrationMeasurement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"FormaldehydeConcentrationMeasurement.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -136887,7 +128824,6 @@ class SubscribeAttributeFormaldehydeConcentrationMeasurementClusterRevision : pu | * LevelValue | 0x000A | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -137961,92 +129897,6 @@ class SubscribeAttributePm1ConcentrationMeasurementAcceptedCommandList : public } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadPm1ConcentrationMeasurementEventList : public ReadAttribute { -public: - ReadPm1ConcentrationMeasurementEventList() - : ReadAttribute("event-list") - { - } - - ~ReadPm1ConcentrationMeasurementEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::Pm1ConcentrationMeasurement::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::Pm1ConcentrationMeasurement::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterPM1ConcentrationMeasurement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"PM1ConcentrationMeasurement.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("PM1ConcentrationMeasurement EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributePm1ConcentrationMeasurementEventList : public SubscribeAttribute { -public: - SubscribeAttributePm1ConcentrationMeasurementEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributePm1ConcentrationMeasurementEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::Pm1ConcentrationMeasurement::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::Pm1ConcentrationMeasurement::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterPM1ConcentrationMeasurement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"PM1ConcentrationMeasurement.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -138312,7 +130162,6 @@ class SubscribeAttributePm1ConcentrationMeasurementClusterRevision : public Subs | * LevelValue | 0x000A | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -139386,92 +131235,6 @@ class SubscribeAttributePm10ConcentrationMeasurementAcceptedCommandList : public } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadPm10ConcentrationMeasurementEventList : public ReadAttribute { -public: - ReadPm10ConcentrationMeasurementEventList() - : ReadAttribute("event-list") - { - } - - ~ReadPm10ConcentrationMeasurementEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::Pm10ConcentrationMeasurement::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::Pm10ConcentrationMeasurement::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterPM10ConcentrationMeasurement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"PM10ConcentrationMeasurement.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("PM10ConcentrationMeasurement EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributePm10ConcentrationMeasurementEventList : public SubscribeAttribute { -public: - SubscribeAttributePm10ConcentrationMeasurementEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributePm10ConcentrationMeasurementEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::Pm10ConcentrationMeasurement::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::Pm10ConcentrationMeasurement::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterPM10ConcentrationMeasurement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"PM10ConcentrationMeasurement.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -139737,7 +131500,6 @@ class SubscribeAttributePm10ConcentrationMeasurementClusterRevision : public Sub | * LevelValue | 0x000A | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -140811,92 +132573,6 @@ class SubscribeAttributeTotalVolatileOrganicCompoundsConcentrationMeasurementAcc } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadTotalVolatileOrganicCompoundsConcentrationMeasurementEventList : public ReadAttribute { -public: - ReadTotalVolatileOrganicCompoundsConcentrationMeasurementEventList() - : ReadAttribute("event-list") - { - } - - ~ReadTotalVolatileOrganicCompoundsConcentrationMeasurementEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::TotalVolatileOrganicCompoundsConcentrationMeasurement::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::TotalVolatileOrganicCompoundsConcentrationMeasurement::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterTotalVolatileOrganicCompoundsConcentrationMeasurement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"TotalVolatileOrganicCompoundsConcentrationMeasurement.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("TotalVolatileOrganicCompoundsConcentrationMeasurement EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeTotalVolatileOrganicCompoundsConcentrationMeasurementEventList : public SubscribeAttribute { -public: - SubscribeAttributeTotalVolatileOrganicCompoundsConcentrationMeasurementEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeTotalVolatileOrganicCompoundsConcentrationMeasurementEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::TotalVolatileOrganicCompoundsConcentrationMeasurement::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::TotalVolatileOrganicCompoundsConcentrationMeasurement::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterTotalVolatileOrganicCompoundsConcentrationMeasurement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"TotalVolatileOrganicCompoundsConcentrationMeasurement.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -141162,7 +132838,6 @@ class SubscribeAttributeTotalVolatileOrganicCompoundsConcentrationMeasurementClu | * LevelValue | 0x000A | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -142236,92 +133911,6 @@ class SubscribeAttributeRadonConcentrationMeasurementAcceptedCommandList : publi } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadRadonConcentrationMeasurementEventList : public ReadAttribute { -public: - ReadRadonConcentrationMeasurementEventList() - : ReadAttribute("event-list") - { - } - - ~ReadRadonConcentrationMeasurementEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::RadonConcentrationMeasurement::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::RadonConcentrationMeasurement::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterRadonConcentrationMeasurement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"RadonConcentrationMeasurement.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("RadonConcentrationMeasurement EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeRadonConcentrationMeasurementEventList : public SubscribeAttribute { -public: - SubscribeAttributeRadonConcentrationMeasurementEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeRadonConcentrationMeasurementEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::RadonConcentrationMeasurement::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::RadonConcentrationMeasurement::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterRadonConcentrationMeasurement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"RadonConcentrationMeasurement.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -142580,7 +134169,6 @@ class SubscribeAttributeRadonConcentrationMeasurementClusterRevision : public Su | * PassphraseSurrogate | 0x0001 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -142983,91 +134571,6 @@ class SubscribeAttributeWiFiNetworkManagementAcceptedCommandList : public Subscr #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL -/* - * Attribute EventList - */ -class ReadWiFiNetworkManagementEventList : public ReadAttribute { -public: - ReadWiFiNetworkManagementEventList() - : ReadAttribute("event-list") - { - } - - ~ReadWiFiNetworkManagementEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::WiFiNetworkManagement::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::WiFiNetworkManagement::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterWiFiNetworkManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"WiFiNetworkManagement.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("WiFiNetworkManagement EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeWiFiNetworkManagementEventList : public SubscribeAttribute { -public: - SubscribeAttributeWiFiNetworkManagementEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeWiFiNetworkManagementEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::WiFiNetworkManagement::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::WiFiNetworkManagement::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterWiFiNetworkManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"WiFiNetworkManagement.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -143341,7 +134844,6 @@ class SubscribeAttributeWiFiNetworkManagementClusterRevision : public SubscribeA | * PendingDatasetTimestamp | 0x0005 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -144252,91 +135754,6 @@ class SubscribeAttributeThreadBorderRouterManagementAcceptedCommandList : public #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL -/* - * Attribute EventList - */ -class ReadThreadBorderRouterManagementEventList : public ReadAttribute { -public: - ReadThreadBorderRouterManagementEventList() - : ReadAttribute("event-list") - { - } - - ~ReadThreadBorderRouterManagementEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::ThreadBorderRouterManagement::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::ThreadBorderRouterManagement::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterThreadBorderRouterManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"ThreadBorderRouterManagement.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("ThreadBorderRouterManagement EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeThreadBorderRouterManagementEventList : public SubscribeAttribute { -public: - SubscribeAttributeThreadBorderRouterManagementEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeThreadBorderRouterManagementEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::ThreadBorderRouterManagement::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::ThreadBorderRouterManagement::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterThreadBorderRouterManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"ThreadBorderRouterManagement.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -144606,7 +136023,6 @@ class SubscribeAttributeThreadBorderRouterManagementClusterRevision : public Sub | * ThreadNetworkTableSize | 0x0002 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -145251,91 +136667,6 @@ class SubscribeAttributeThreadNetworkDirectoryAcceptedCommandList : public Subsc #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL -/* - * Attribute EventList - */ -class ReadThreadNetworkDirectoryEventList : public ReadAttribute { -public: - ReadThreadNetworkDirectoryEventList() - : ReadAttribute("event-list") - { - } - - ~ReadThreadNetworkDirectoryEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::ThreadNetworkDirectory::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::ThreadNetworkDirectory::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterThreadNetworkDirectory alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"ThreadNetworkDirectory.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("ThreadNetworkDirectory EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeThreadNetworkDirectoryEventList : public SubscribeAttribute { -public: - SubscribeAttributeThreadNetworkDirectoryEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeThreadNetworkDirectoryEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::ThreadNetworkDirectory::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::ThreadNetworkDirectory::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterThreadNetworkDirectory alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"ThreadNetworkDirectory.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -145600,7 +136931,6 @@ class SubscribeAttributeThreadNetworkDirectoryClusterRevision : public Subscribe | * LinkLocalAddress | 0x0001 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -145940,92 +137270,6 @@ class SubscribeAttributeWakeOnLanAcceptedCommandList : public SubscribeAttribute } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadWakeOnLanEventList : public ReadAttribute { -public: - ReadWakeOnLanEventList() - : ReadAttribute("event-list") - { - } - - ~ReadWakeOnLanEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::WakeOnLan::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::WakeOnLan::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterWakeOnLAN alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"WakeOnLAN.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("WakeOnLAN EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeWakeOnLanEventList : public SubscribeAttribute { -public: - SubscribeAttributeWakeOnLanEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeWakeOnLanEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::WakeOnLan::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::WakeOnLan::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterWakeOnLAN alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"WakeOnLAN.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -146289,7 +137533,6 @@ class SubscribeAttributeWakeOnLanClusterRevision : public SubscribeAttribute { | * CurrentChannel | 0x0002 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -147212,92 +138455,6 @@ class SubscribeAttributeChannelAcceptedCommandList : public SubscribeAttribute { } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadChannelEventList : public ReadAttribute { -public: - ReadChannelEventList() - : ReadAttribute("event-list") - { - } - - ~ReadChannelEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::Channel::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::Channel::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterChannel alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"Channel.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("Channel EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeChannelEventList : public SubscribeAttribute { -public: - SubscribeAttributeChannelEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeChannelEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::Channel::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::Channel::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterChannel alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"Channel.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -147555,7 +138712,6 @@ class SubscribeAttributeChannelClusterRevision : public SubscribeAttribute { | * CurrentTarget | 0x0001 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -147951,92 +139107,6 @@ class SubscribeAttributeTargetNavigatorAcceptedCommandList : public SubscribeAtt } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadTargetNavigatorEventList : public ReadAttribute { -public: - ReadTargetNavigatorEventList() - : ReadAttribute("event-list") - { - } - - ~ReadTargetNavigatorEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::TargetNavigator::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::TargetNavigator::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterTargetNavigator alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"TargetNavigator.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("TargetNavigator EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeTargetNavigatorEventList : public SubscribeAttribute { -public: - SubscribeAttributeTargetNavigatorEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeTargetNavigatorEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::TargetNavigator::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::TargetNavigator::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterTargetNavigator alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"TargetNavigator.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -148316,7 +139386,6 @@ class SubscribeAttributeTargetNavigatorClusterRevision : public SubscribeAttribu | * AvailableTextTracks | 0x000A | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -150144,92 +141213,6 @@ class SubscribeAttributeMediaPlaybackAcceptedCommandList : public SubscribeAttri } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadMediaPlaybackEventList : public ReadAttribute { -public: - ReadMediaPlaybackEventList() - : ReadAttribute("event-list") - { - } - - ~ReadMediaPlaybackEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::MediaPlayback::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::MediaPlayback::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterMediaPlayback alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"MediaPlayback.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("MediaPlayback EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeMediaPlaybackEventList : public SubscribeAttribute { -public: - SubscribeAttributeMediaPlaybackEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeMediaPlaybackEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::MediaPlayback::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::MediaPlayback::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterMediaPlayback alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"MediaPlayback.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -150490,7 +141473,6 @@ class SubscribeAttributeMediaPlaybackClusterRevision : public SubscribeAttribute | * CurrentInput | 0x0001 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -151010,92 +141992,6 @@ class SubscribeAttributeMediaInputAcceptedCommandList : public SubscribeAttribut } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadMediaInputEventList : public ReadAttribute { -public: - ReadMediaInputEventList() - : ReadAttribute("event-list") - { - } - - ~ReadMediaInputEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::MediaInput::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::MediaInput::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterMediaInput alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"MediaInput.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("MediaInput EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeMediaInputEventList : public SubscribeAttribute { -public: - SubscribeAttributeMediaInputEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeMediaInputEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::MediaInput::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::MediaInput::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterMediaInput alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"MediaInput.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -151351,7 +142247,6 @@ class SubscribeAttributeMediaInputClusterRevision : public SubscribeAttribute { | Attributes: | | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -151567,92 +142462,6 @@ class SubscribeAttributeLowPowerAcceptedCommandList : public SubscribeAttribute } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadLowPowerEventList : public ReadAttribute { -public: - ReadLowPowerEventList() - : ReadAttribute("event-list") - { - } - - ~ReadLowPowerEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::LowPower::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::LowPower::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterLowPower alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"LowPower.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("LowPower EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeLowPowerEventList : public SubscribeAttribute { -public: - SubscribeAttributeLowPowerEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeLowPowerEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::LowPower::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::LowPower::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterLowPower alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"LowPower.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -151908,7 +142717,6 @@ class SubscribeAttributeLowPowerClusterRevision : public SubscribeAttribute { | Attributes: | | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -152133,92 +142941,6 @@ class SubscribeAttributeKeypadInputAcceptedCommandList : public SubscribeAttribu } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadKeypadInputEventList : public ReadAttribute { -public: - ReadKeypadInputEventList() - : ReadAttribute("event-list") - { - } - - ~ReadKeypadInputEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::KeypadInput::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::KeypadInput::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterKeypadInput alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"KeypadInput.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("KeypadInput EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeKeypadInputEventList : public SubscribeAttribute { -public: - SubscribeAttributeKeypadInputEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeKeypadInputEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::KeypadInput::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::KeypadInput::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterKeypadInput alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"KeypadInput.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -152477,7 +143199,6 @@ class SubscribeAttributeKeypadInputClusterRevision : public SubscribeAttribute { | * SupportedStreamingProtocols | 0x0001 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -153152,92 +143873,6 @@ class SubscribeAttributeContentLauncherAcceptedCommandList : public SubscribeAtt } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadContentLauncherEventList : public ReadAttribute { -public: - ReadContentLauncherEventList() - : ReadAttribute("event-list") - { - } - - ~ReadContentLauncherEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::ContentLauncher::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::ContentLauncher::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterContentLauncher alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"ContentLauncher.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("ContentLauncher EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeContentLauncherEventList : public SubscribeAttribute { -public: - SubscribeAttributeContentLauncherEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeContentLauncherEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::ContentLauncher::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::ContentLauncher::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterContentLauncher alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"ContentLauncher.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -153496,7 +144131,6 @@ class SubscribeAttributeContentLauncherClusterRevision : public SubscribeAttribu | * CurrentOutput | 0x0001 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -153928,92 +144562,6 @@ class SubscribeAttributeAudioOutputAcceptedCommandList : public SubscribeAttribu } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadAudioOutputEventList : public ReadAttribute { -public: - ReadAudioOutputEventList() - : ReadAttribute("event-list") - { - } - - ~ReadAudioOutputEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::AudioOutput::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::AudioOutput::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterAudioOutput alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"AudioOutput.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("AudioOutput EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeAudioOutputEventList : public SubscribeAttribute { -public: - SubscribeAttributeAudioOutputEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeAudioOutputEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::AudioOutput::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::AudioOutput::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterAudioOutput alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"AudioOutput.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -154273,7 +144821,6 @@ class SubscribeAttributeAudioOutputClusterRevision : public SubscribeAttribute { | * CurrentApp | 0x0001 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -154798,92 +145345,6 @@ class SubscribeAttributeApplicationLauncherAcceptedCommandList : public Subscrib } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadApplicationLauncherEventList : public ReadAttribute { -public: - ReadApplicationLauncherEventList() - : ReadAttribute("event-list") - { - } - - ~ReadApplicationLauncherEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::ApplicationLauncher::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::ApplicationLauncher::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterApplicationLauncher alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"ApplicationLauncher.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("ApplicationLauncher EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeApplicationLauncherEventList : public SubscribeAttribute { -public: - SubscribeAttributeApplicationLauncherEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeApplicationLauncherEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::ApplicationLauncher::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::ApplicationLauncher::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterApplicationLauncher alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"ApplicationLauncher.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -155146,7 +145607,6 @@ class SubscribeAttributeApplicationLauncherClusterRevision : public SubscribeAtt | * AllowedVendorList | 0x0007 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -155974,92 +146434,6 @@ class SubscribeAttributeApplicationBasicAcceptedCommandList : public SubscribeAt } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadApplicationBasicEventList : public ReadAttribute { -public: - ReadApplicationBasicEventList() - : ReadAttribute("event-list") - { - } - - ~ReadApplicationBasicEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::ApplicationBasic::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::ApplicationBasic::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterApplicationBasic alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"ApplicationBasic.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("ApplicationBasic EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeApplicationBasicEventList : public SubscribeAttribute { -public: - SubscribeAttributeApplicationBasicEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeApplicationBasicEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::ApplicationBasic::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::ApplicationBasic::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterApplicationBasic alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"ApplicationBasic.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -156317,7 +146691,6 @@ class SubscribeAttributeApplicationBasicClusterRevision : public SubscribeAttrib | Attributes: | | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -156657,92 +147030,6 @@ class SubscribeAttributeAccountLoginAcceptedCommandList : public SubscribeAttrib } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadAccountLoginEventList : public ReadAttribute { -public: - ReadAccountLoginEventList() - : ReadAttribute("event-list") - { - } - - ~ReadAccountLoginEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::AccountLogin::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::AccountLogin::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterAccountLogin alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"AccountLogin.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("AccountLogin EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeAccountLoginEventList : public SubscribeAttribute { -public: - SubscribeAttributeAccountLoginEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeAccountLoginEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::AccountLogin::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::AccountLogin::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterAccountLogin alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"AccountLogin.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -157016,7 +147303,6 @@ class SubscribeAttributeAccountLoginClusterRevision : public SubscribeAttribute | * BlockUnrated | 0x0007 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -158403,91 +148689,6 @@ class SubscribeAttributeContentControlAcceptedCommandList : public SubscribeAttr #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL -/* - * Attribute EventList - */ -class ReadContentControlEventList : public ReadAttribute { -public: - ReadContentControlEventList() - : ReadAttribute("event-list") - { - } - - ~ReadContentControlEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::ContentControl::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::ContentControl::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterContentControl alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"ContentControl.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("ContentControl EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeContentControlEventList : public SubscribeAttribute { -public: - SubscribeAttributeContentControlEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeContentControlEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::ContentControl::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::ContentControl::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterContentControl alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"ContentControl.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -158752,7 +148953,6 @@ class SubscribeAttributeContentControlClusterRevision : public SubscribeAttribut | Attributes: | | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -159002,91 +149202,6 @@ class SubscribeAttributeContentAppObserverAcceptedCommandList : public Subscribe #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL -/* - * Attribute EventList - */ -class ReadContentAppObserverEventList : public ReadAttribute { -public: - ReadContentAppObserverEventList() - : ReadAttribute("event-list") - { - } - - ~ReadContentAppObserverEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::ContentAppObserver::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::ContentAppObserver::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterContentAppObserver alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"ContentAppObserver.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("ContentAppObserver EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeContentAppObserverEventList : public SubscribeAttribute { -public: - SubscribeAttributeContentAppObserverEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeContentAppObserverEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::ContentAppObserver::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::ContentAppObserver::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterContentAppObserver alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"ContentAppObserver.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -159358,7 +149473,6 @@ class SubscribeAttributeContentAppObserverClusterRevision : public SubscribeAttr | * Sensitivity | 0x0003 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -160256,91 +150370,6 @@ class SubscribeAttributeZoneManagementAcceptedCommandList : public SubscribeAttr #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL -/* - * Attribute EventList - */ -class ReadZoneManagementEventList : public ReadAttribute { -public: - ReadZoneManagementEventList() - : ReadAttribute("event-list") - { - } - - ~ReadZoneManagementEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::ZoneManagement::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::ZoneManagement::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterZoneManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"ZoneManagement.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("ZoneManagement EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeZoneManagementEventList : public SubscribeAttribute { -public: - SubscribeAttributeZoneManagementEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeZoneManagementEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::ZoneManagement::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::ZoneManagement::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterZoneManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"ZoneManagement.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -160664,7 +150693,6 @@ class SubscribeAttributeZoneManagementClusterRevision : public SubscribeAttribut | * DepthSensorStatus | 0x002E | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -166714,91 +156742,6 @@ class SubscribeAttributeCameraAvStreamManagementAcceptedCommandList : public Sub #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL -/* - * Attribute EventList - */ -class ReadCameraAvStreamManagementEventList : public ReadAttribute { -public: - ReadCameraAvStreamManagementEventList() - : ReadAttribute("event-list") - { - } - - ~ReadCameraAvStreamManagementEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::CameraAvStreamManagement::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::CameraAvStreamManagement::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterCameraAVStreamManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"CameraAVStreamManagement.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("CameraAVStreamManagement EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeCameraAvStreamManagementEventList : public SubscribeAttribute { -public: - SubscribeAttributeCameraAvStreamManagementEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeCameraAvStreamManagementEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::CameraAvStreamManagement::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::CameraAvStreamManagement::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterCameraAVStreamManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"CameraAVStreamManagement.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -167068,7 +157011,6 @@ class SubscribeAttributeCameraAvStreamManagementClusterRevision : public Subscri | * CurrentSessions | 0x0000 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -167829,91 +157771,6 @@ class SubscribeAttributeWebRTCTransportProviderAcceptedCommandList : public Subs #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL -/* - * Attribute EventList - */ -class ReadWebRTCTransportProviderEventList : public ReadAttribute { -public: - ReadWebRTCTransportProviderEventList() - : ReadAttribute("event-list") - { - } - - ~ReadWebRTCTransportProviderEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::WebRTCTransportProvider::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::WebRTCTransportProvider::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterWebRTCTransportProvider alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"WebRTCTransportProvider.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("WebRTCTransportProvider EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeWebRTCTransportProviderEventList : public SubscribeAttribute { -public: - SubscribeAttributeWebRTCTransportProviderEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeWebRTCTransportProviderEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::WebRTCTransportProvider::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::WebRTCTransportProvider::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterWebRTCTransportProvider alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"WebRTCTransportProvider.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -168182,7 +158039,6 @@ class SubscribeAttributeWebRTCTransportProviderClusterRevision : public Subscrib | * CurrentSessions | 0x0000 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -168738,91 +158594,6 @@ class SubscribeAttributeWebRTCTransportRequestorAcceptedCommandList : public Sub #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL -/* - * Attribute EventList - */ -class ReadWebRTCTransportRequestorEventList : public ReadAttribute { -public: - ReadWebRTCTransportRequestorEventList() - : ReadAttribute("event-list") - { - } - - ~ReadWebRTCTransportRequestorEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::WebRTCTransportRequestor::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::WebRTCTransportRequestor::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterWebRTCTransportRequestor alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"WebRTCTransportRequestor.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("WebRTCTransportRequestor EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeWebRTCTransportRequestorEventList : public SubscribeAttribute { -public: - SubscribeAttributeWebRTCTransportRequestorEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeWebRTCTransportRequestorEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::WebRTCTransportRequestor::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::WebRTCTransportRequestor::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterWebRTCTransportRequestor alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"WebRTCTransportRequestor.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -169090,7 +158861,6 @@ class SubscribeAttributeWebRTCTransportRequestorClusterRevision : public Subscri | * Enabled | 0x0002 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -169654,91 +159424,6 @@ class SubscribeAttributeChimeAcceptedCommandList : public SubscribeAttribute { #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL -/* - * Attribute EventList - */ -class ReadChimeEventList : public ReadAttribute { -public: - ReadChimeEventList() - : ReadAttribute("event-list") - { - } - - ~ReadChimeEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::Chime::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::Chime::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterChime alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"Chime.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("Chime EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeChimeEventList : public SubscribeAttribute { -public: - SubscribeAttributeChimeEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeChimeEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::Chime::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::Chime::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterChime alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"Chime.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -170004,7 +159689,6 @@ class SubscribeAttributeChimeClusterRevision : public SubscribeAttribute { | * LocationDirectory | 0x0001 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -170362,91 +160046,6 @@ class SubscribeAttributeEcosystemInformationAcceptedCommandList : public Subscri #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL -/* - * Attribute EventList - */ -class ReadEcosystemInformationEventList : public ReadAttribute { -public: - ReadEcosystemInformationEventList() - : ReadAttribute("event-list") - { - } - - ~ReadEcosystemInformationEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::EcosystemInformation::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::EcosystemInformation::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterEcosystemInformation alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"EcosystemInformation.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("EcosystemInformation EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeEcosystemInformationEventList : public SubscribeAttribute { -public: - SubscribeAttributeEcosystemInformationEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeEcosystemInformationEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::EcosystemInformation::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::EcosystemInformation::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterEcosystemInformation alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"EcosystemInformation.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -170713,7 +160312,6 @@ class SubscribeAttributeEcosystemInformationClusterRevision : public SubscribeAt | * SupportedDeviceCategories | 0x0000 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -171120,91 +160718,6 @@ class SubscribeAttributeCommissionerControlAcceptedCommandList : public Subscrib #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL -/* - * Attribute EventList - */ -class ReadCommissionerControlEventList : public ReadAttribute { -public: - ReadCommissionerControlEventList() - : ReadAttribute("event-list") - { - } - - ~ReadCommissionerControlEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::CommissionerControl::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::CommissionerControl::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterCommissionerControl alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"CommissionerControl.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("CommissionerControl EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeCommissionerControlEventList : public SubscribeAttribute { -public: - SubscribeAttributeCommissionerControlEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeCommissionerControlEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::CommissionerControl::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::CommissionerControl::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterCommissionerControl alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"CommissionerControl.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -171582,7 +161095,6 @@ class SubscribeAttributeCommissionerControlClusterRevision : public SubscribeAtt | * NullableGlobalStruct | 0x4034 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -185060,92 +174572,6 @@ class SubscribeAttributeUnitTestingAcceptedCommandList : public SubscribeAttribu } }; -#if MTR_ENABLE_PROVISIONAL - -/* - * Attribute EventList - */ -class ReadUnitTestingEventList : public ReadAttribute { -public: - ReadUnitTestingEventList() - : ReadAttribute("event-list") - { - } - - ~ReadUnitTestingEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::UnitTesting::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::UnitTesting::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"UnitTesting.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("UnitTesting EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeUnitTestingEventList : public SubscribeAttribute { -public: - SubscribeAttributeUnitTestingEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeUnitTestingEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::UnitTesting::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::UnitTesting::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterUnitTesting alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"UnitTesting.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -185530,7 +174956,6 @@ class SubscribeAttributeUnitTestingMeiInt8u : public SubscribeAttribute { | * FlipFlop | 0x0000 | | * GeneratedCommandList | 0xFFF8 | | * AcceptedCommandList | 0xFFF9 | -| * EventList | 0xFFFA | | * AttributeList | 0xFFFB | | * FeatureMap | 0xFFFC | | * ClusterRevision | 0xFFFD | @@ -185949,91 +175374,6 @@ class SubscribeAttributeSampleMeiAcceptedCommandList : public SubscribeAttribute #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL -/* - * Attribute EventList - */ -class ReadSampleMeiEventList : public ReadAttribute { -public: - ReadSampleMeiEventList() - : ReadAttribute("event-list") - { - } - - ~ReadSampleMeiEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::SampleMei::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::SampleMei::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); - - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterSampleMEI alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"SampleMEI.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - LogNSError("SampleMEI EventList read Error", error); - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - return CHIP_NO_ERROR; - } -}; - -class SubscribeAttributeSampleMeiEventList : public SubscribeAttribute { -public: - SubscribeAttributeSampleMeiEventList() - : SubscribeAttribute("event-list") - { - } - - ~SubscribeAttributeSampleMeiEventList() - { - } - - CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override - { - constexpr chip::ClusterId clusterId = chip::app::Clusters::SampleMei::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::SampleMei::Attributes::EventList::Id; - - ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); - dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); - __auto_type * cluster = [[MTRBaseClusterSampleMEI alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; - if (mKeepSubscriptions.HasValue()) { - params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); - } - if (mFabricFiltered.HasValue()) { - params.filterByFabric = mFabricFiltered.Value(); - } - if (mAutoResubscribe.HasValue()) { - params.resubscribeAutomatically = mAutoResubscribe.Value(); - } - [cluster subscribeAttributeEventListWithParams:params - subscriptionEstablished:^() { mSubscriptionEstablished = YES; } - reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { - NSLog(@"SampleMEI.EventList response %@", [value description]); - if (error == nil) { - RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); - } else { - RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); - } - SetCommandExitStatus(error); - }]; - - return CHIP_NO_ERROR; - } -}; - -#endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - /* * Attribute AttributeList */ @@ -186314,10 +175654,6 @@ void registerClusterIdentify(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -186351,10 +175687,6 @@ void registerClusterGroups(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -186399,10 +175731,6 @@ void registerClusterOnOff(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -186472,10 +175800,6 @@ void registerClusterLevelControl(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -186506,10 +175830,6 @@ void registerClusterPulseWidthModulation(Commands & commands) make_unique(), // make_unique(), // #endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // @@ -186554,10 +175874,6 @@ void registerClusterDescriptor(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -186586,10 +175902,6 @@ void registerClusterBinding(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -186638,10 +175950,6 @@ void registerClusterAccessControl(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -186687,10 +175995,6 @@ void registerClusterActions(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -186771,10 +176075,6 @@ void registerClusterBasicInformation(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -186805,10 +176105,6 @@ void registerClusterOtaSoftwareUpdateProvider(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -186844,10 +176140,6 @@ void registerClusterOtaSoftwareUpdateRequestor(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -186880,10 +176172,6 @@ void registerClusterLocalizationConfiguration(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -186917,10 +176205,6 @@ void registerClusterTimeFormatLocalization(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -186949,10 +176233,6 @@ void registerClusterUnitLocalization(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -186980,10 +176260,6 @@ void registerClusterPowerSourceConfiguration(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -187073,10 +176349,6 @@ void registerClusterPowerSource(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -187141,10 +176413,6 @@ void registerClusterGeneralCommissioning(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -187208,10 +176476,6 @@ void registerClusterNetworkCommissioning(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -187238,10 +176502,6 @@ void registerClusterDiagnosticLogs(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -187292,10 +176552,6 @@ void registerClusterGeneralDiagnostics(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -187332,10 +176588,6 @@ void registerClusterSoftwareDiagnostics(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -187490,10 +176742,6 @@ void registerClusterThreadNetworkDiagnostics(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -187548,10 +176796,6 @@ void registerClusterWiFiNetworkDiagnostics(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -187598,10 +176842,6 @@ void registerClusterEthernetNetworkDiagnostics(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -187699,10 +176939,6 @@ void registerClusterTimeSynchronization(Commands & commands) make_unique(), // make_unique(), // #endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // @@ -187777,10 +177013,6 @@ void registerClusterBridgedDeviceBasicInformation(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -187814,10 +177046,6 @@ void registerClusterSwitch(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -187854,10 +177082,6 @@ void registerClusterAdministratorCommissioning(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -187903,10 +177127,6 @@ void registerClusterOperationalCredentials(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -187945,10 +177165,6 @@ void registerClusterGroupKeyManagement(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -187976,10 +177192,6 @@ void registerClusterFixedLabel(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -188008,10 +177220,6 @@ void registerClusterUserLabel(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -188039,10 +177247,6 @@ void registerClusterBooleanState(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -188124,10 +177328,6 @@ void registerClusterIcdManagement(Commands & commands) make_unique(), // make_unique(), // #endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // @@ -188189,10 +177389,6 @@ void registerClusterTimer(Commands & commands) make_unique(), // make_unique(), // #endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // @@ -188266,10 +177462,6 @@ void registerClusterOvenCavityOperationalState(Commands & commands) make_unique(), // make_unique(), // #endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // @@ -188330,10 +177522,6 @@ void registerClusterOvenMode(Commands & commands) make_unique(), // make_unique(), // #endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // @@ -188380,10 +177568,6 @@ void registerClusterLaundryDryerControls(Commands & commands) make_unique(), // make_unique(), // #endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // @@ -188431,10 +177615,6 @@ void registerClusterModeSelect(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -188486,10 +177666,6 @@ void registerClusterLaundryWasherMode(Commands & commands) make_unique(), // make_unique(), // #endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // @@ -188548,10 +177724,6 @@ void registerClusterRefrigeratorAndTemperatureControlledCabinetMode(Commands & c make_unique(), // make_unique(), // #endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // @@ -188607,10 +177779,6 @@ void registerClusterLaundryWasherControls(Commands & commands) make_unique(), // make_unique(), // #endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // @@ -188648,10 +177816,6 @@ void registerClusterRvcRunMode(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -188682,10 +177846,6 @@ void registerClusterRvcCleanMode(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -188743,10 +177903,6 @@ void registerClusterTemperatureControl(Commands & commands) make_unique(), // make_unique(), // #endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // @@ -188796,10 +177952,6 @@ void registerClusterRefrigeratorAlarm(Commands & commands) make_unique(), // make_unique(), // #endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // @@ -188860,10 +178012,6 @@ void registerClusterDishwasherMode(Commands & commands) make_unique(), // make_unique(), // #endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // @@ -188898,10 +178046,6 @@ void registerClusterAirQuality(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -188955,10 +178099,6 @@ void registerClusterSmokeCoAlarm(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -189013,10 +178153,6 @@ void registerClusterDishwasherAlarm(Commands & commands) make_unique(), // make_unique(), // #endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // @@ -189064,10 +178200,6 @@ void registerClusterMicrowaveOvenMode(Commands & commands) make_unique(), // make_unique(), // #endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // @@ -189147,10 +178279,6 @@ void registerClusterMicrowaveOvenControl(Commands & commands) make_unique(), // make_unique(), // #endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // @@ -189199,10 +178327,6 @@ void registerClusterOperationalState(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -189247,10 +178371,6 @@ void registerClusterRvcOperationalState(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -189319,10 +178439,6 @@ void registerClusterScenesManagement(Commands & commands) make_unique(), // make_unique(), // #endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // @@ -189369,10 +178485,6 @@ void registerClusterHepaFilterMonitoring(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -189412,10 +178524,6 @@ void registerClusterActivatedCarbonFilterMonitoring(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -189460,10 +178568,6 @@ void registerClusterBooleanStateConfiguration(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -189517,10 +178621,6 @@ void registerClusterValveConfigurationAndControl(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -189586,10 +178686,6 @@ void registerClusterElectricalPowerMeasurement(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -189629,10 +178725,6 @@ void registerClusterElectricalEnergyMeasurement(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -189695,10 +178787,6 @@ void registerClusterWaterHeaterManagement(Commands & commands) make_unique(), // make_unique(), // #endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // @@ -189787,10 +178875,6 @@ void registerClusterDemandResponseLoadControl(Commands & commands) make_unique(), // make_unique(), // #endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // @@ -189844,10 +178928,6 @@ void registerClusterMessages(Commands & commands) make_unique(), // make_unique(), // #endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // @@ -189943,10 +179023,6 @@ void registerClusterDeviceEnergyManagement(Commands & commands) make_unique(), // make_unique(), // #endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // @@ -190102,10 +179178,6 @@ void registerClusterEnergyEvse(Commands & commands) make_unique(), // make_unique(), // #endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // @@ -190167,10 +179239,6 @@ void registerClusterEnergyPreference(Commands & commands) make_unique(), // make_unique(), // #endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // @@ -190216,10 +179284,6 @@ void registerClusterPowerTopology(Commands & commands) make_unique(), // make_unique(), // #endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // @@ -190268,10 +179332,6 @@ void registerClusterEnergyEvseMode(Commands & commands) make_unique(), // make_unique(), // #endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // @@ -190320,10 +179380,6 @@ void registerClusterWaterHeaterMode(Commands & commands) make_unique(), // make_unique(), // #endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // @@ -190372,10 +179428,6 @@ void registerClusterDeviceEnergyManagementMode(Commands & commands) make_unique(), // make_unique(), // #endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // @@ -190561,10 +179613,6 @@ void registerClusterDoorLock(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -190644,10 +179692,6 @@ void registerClusterWindowCovering(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -190708,10 +179752,6 @@ void registerClusterServiceArea(Commands & commands) make_unique(), // make_unique(), // #endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // @@ -190794,10 +179834,6 @@ void registerClusterPumpConfigurationAndControl(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -191009,10 +180045,6 @@ void registerClusterThermostat(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -191069,10 +180101,6 @@ void registerClusterFanControl(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -191107,10 +180135,6 @@ void registerClusterThermostatUserInterfaceConfiguration(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -191272,10 +180296,6 @@ void registerClusterColorControl(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -191339,10 +180359,6 @@ void registerClusterBallastConfiguration(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -191378,10 +180394,6 @@ void registerClusterIlluminanceMeasurement(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -191415,10 +180427,6 @@ void registerClusterTemperatureMeasurement(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -191462,10 +180470,6 @@ void registerClusterPressureMeasurement(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -191499,10 +180503,6 @@ void registerClusterFlowMeasurement(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -191536,10 +180536,6 @@ void registerClusterRelativeHumidityMeasurement(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -191607,10 +180603,6 @@ void registerClusterOccupancySensing(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -191660,10 +180652,6 @@ void registerClusterCarbonMonoxideConcentrationMeasurement(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -191711,10 +180699,6 @@ void registerClusterCarbonDioxideConcentrationMeasurement(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -191762,10 +180746,6 @@ void registerClusterNitrogenDioxideConcentrationMeasurement(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -191813,10 +180793,6 @@ void registerClusterOzoneConcentrationMeasurement(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -191864,10 +180840,6 @@ void registerClusterPm25ConcentrationMeasurement(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -191915,10 +180887,6 @@ void registerClusterFormaldehydeConcentrationMeasurement(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -191966,10 +180934,6 @@ void registerClusterPm1ConcentrationMeasurement(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -192017,10 +180981,6 @@ void registerClusterPm10ConcentrationMeasurement(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -192068,10 +181028,6 @@ void registerClusterTotalVolatileOrganicCompoundsConcentrationMeasurement(Comman make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -192119,10 +181075,6 @@ void registerClusterRadonConcentrationMeasurement(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -192164,10 +181116,6 @@ void registerClusterWiFiNetworkManagement(Commands & commands) make_unique(), // make_unique(), // #endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // @@ -192241,10 +181189,6 @@ void registerClusterThreadBorderRouterManagement(Commands & commands) make_unique(), // make_unique(), // #endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // @@ -192304,10 +181248,6 @@ void registerClusterThreadNetworkDirectory(Commands & commands) make_unique(), // make_unique(), // #endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // @@ -192346,10 +181286,6 @@ void registerClusterWakeOnLan(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -192393,10 +181329,6 @@ void registerClusterChannel(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -192427,10 +181359,6 @@ void registerClusterTargetNavigator(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -192508,10 +181436,6 @@ void registerClusterMediaPlayback(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -192547,10 +181471,6 @@ void registerClusterMediaInput(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -192577,10 +181497,6 @@ void registerClusterLowPower(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -192607,10 +181523,6 @@ void registerClusterKeypadInput(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -192642,10 +181554,6 @@ void registerClusterContentLauncher(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -192677,10 +181585,6 @@ void registerClusterAudioOutput(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -192713,10 +181617,6 @@ void registerClusterApplicationLauncher(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -192758,10 +181658,6 @@ void registerClusterApplicationBasic(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -192790,10 +181686,6 @@ void registerClusterAccountLogin(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -192888,10 +181780,6 @@ void registerClusterContentControl(Commands & commands) make_unique(), // make_unique(), // #endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // @@ -192934,10 +181822,6 @@ void registerClusterContentAppObserver(Commands & commands) make_unique(), // make_unique(), // #endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // @@ -193005,10 +181889,6 @@ void registerClusterZoneManagement(Commands & commands) make_unique(), // make_unique(), // #endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // @@ -193298,10 +182178,6 @@ void registerClusterCameraAvStreamManagement(Commands & commands) make_unique(), // make_unique(), // #endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // @@ -193360,10 +182236,6 @@ void registerClusterWebRTCTransportProvider(Commands & commands) make_unique(), // make_unique(), // #endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // @@ -193417,10 +182289,6 @@ void registerClusterWebRTCTransportRequestor(Commands & commands) make_unique(), // make_unique(), // #endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // @@ -193475,10 +182343,6 @@ void registerClusterChime(Commands & commands) make_unique(), // make_unique(), // #endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // @@ -193524,10 +182388,6 @@ void registerClusterEcosystemInformation(Commands & commands) make_unique(), // make_unique(), // #endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // @@ -193575,10 +182435,6 @@ void registerClusterCommissionerControl(Commands & commands) make_unique(), // make_unique(), // #endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // @@ -193926,10 +182782,6 @@ void registerClusterUnitTesting(Commands & commands) make_unique(), // make_unique(), // make_unique(), // -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // make_unique(), // @@ -193978,10 +182830,6 @@ void registerClusterSampleMei(Commands & commands) make_unique(), // make_unique(), // #endif // MTR_ENABLE_PROVISIONAL -#if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // -#endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL make_unique(), // make_unique(), // From ed11b03ac660512d9c0ccdca1bfc44ec42022742 Mon Sep 17 00:00:00 2001 From: Yufeng Wang Date: Tue, 22 Oct 2024 09:29:40 -0700 Subject: [PATCH 065/149] Add build check for fabric-sync (#36182) --- .github/workflows/examples-linux-arm.yaml | 1 + .github/workflows/examples-linux-standalone.yaml | 10 ++++++++++ 2 files changed, 11 insertions(+) diff --git a/.github/workflows/examples-linux-arm.yaml b/.github/workflows/examples-linux-arm.yaml index 7000082f03e32e..78a1c8dea80809 100644 --- a/.github/workflows/examples-linux-arm.yaml +++ b/.github/workflows/examples-linux-arm.yaml @@ -70,6 +70,7 @@ jobs: --target linux-arm64-lit-icd-no-ble-clang \ --target linux-arm64-fabric-admin-clang-rpc \ --target linux-arm64-fabric-bridge-no-ble-clang-rpc \ + --target linux-arm64-fabric-sync-no-ble-clang \ build \ " - name: Bloat report - chip-tool diff --git a/.github/workflows/examples-linux-standalone.yaml b/.github/workflows/examples-linux-standalone.yaml index 83b82369ba4878..2bed5acd82f040 100644 --- a/.github/workflows/examples-linux-standalone.yaml +++ b/.github/workflows/examples-linux-standalone.yaml @@ -219,6 +219,16 @@ jobs: linux debug fabric-bridge-app \ out/linux-x64-fabric-bridge-no-ble-rpc/fabric-bridge-app \ /tmp/bloat_reports/ + - name: Build example Fabric Sync + run: | + ./scripts/run_in_build_env.sh \ + "./scripts/build/build_examples.py \ + --target linux-x64-fabric-sync-no-ble \ + build" + .environment/pigweed-venv/bin/python3 scripts/tools/memory/gh_sizes.py \ + linux debug fabric-sync \ + out/linux-x64-fabric-sync-no-ble/fabric-sync \ + /tmp/bloat_reports/ - name: Uploading Size Reports uses: ./.github/actions/upload-size-reports if: ${{ !env.ACT }} From 7ff4cd2872d55b966a4e7b4d65baf885d0ea8b31 Mon Sep 17 00:00:00 2001 From: lpbeliveau-silabs <112982107+lpbeliveau-silabs@users.noreply.github.com> Date: Tue, 22 Oct 2024 13:06:12 -0400 Subject: [PATCH 066/149] Updated the S_2_6 test steps according to plan and VS doc (#36145) --- .../suites/certification/Test_TC_S_2_6.yaml | 80 +++++++++---------- 1 file changed, 37 insertions(+), 43 deletions(-) diff --git a/src/app/tests/suites/certification/Test_TC_S_2_6.yaml b/src/app/tests/suites/certification/Test_TC_S_2_6.yaml index cff80b796ab11c..40f4fa89d46006 100644 --- a/src/app/tests/suites/certification/Test_TC_S_2_6.yaml +++ b/src/app/tests/suites/certification/Test_TC_S_2_6.yaml @@ -118,7 +118,7 @@ tests: Verify the RemoveAllScenesResponse with following fields: Status is SUCCESS - Group ID is 0x0000 on the TH(Chip-tool) log and below is the sample log provided for the raspi platform: + Group ID is 0x0000 on the TH2(Chip-tool) log and below is the sample log provided for the raspi platform: [1700826575.191275][15971:15973] CHIP:DMG: Received Command Response Data, Endpoint=1 Cluster=0x0000_0062 Command=0x0000_0003 [1700826575.191321][15971:15973] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0062 Command 0x0000_0003 @@ -135,7 +135,7 @@ tests: Verify the RemoveAllScenesResponse with following fields: Status is SUCCESS - Group ID is 0x0000 on the TH(Chip-tool) log and below is the sample log provided for the raspi platform: + Group ID is 0x0000 on the TH3(Chip-tool) log and below is the sample log provided for the raspi platform: [1700826595.190538][15975:15977] CHIP:DMG: Received Command Response Data, Endpoint=1 Cluster=0x0000_0062 Command=0x0000_0003 [1700826595.190578][15975:15977] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0062 Command 0x0000_0003 @@ -236,7 +236,7 @@ tests: CHIP:DMG: Refresh LivenessCheckTime for 9224 milliseconds with SubscriptionId = 0xce6a96bc Peer = 01:0000000000000001 disabled: true - - label: "Step 2d: Repeat Step 2b and 2c with TH2 and TH3" + - label: "Step 2d: Repeat Step 2b and 2c with TH2." verification: | TH2: @@ -974,44 +974,40 @@ tests: - label: "Step 7: TH3 sends a StoreScene command to DUT with the GroupID field - set to 0x0000, the SceneID field set to 0x01." + set to 0x0000, the SceneID field set to 0xfe." PICS: S.S.C04.Rsp verification: | - scenesmanagement store-scene 0x0000 0x01 3 1 --commissioner-name gamma + scenesmanagement store-scene 0x0000 0xfe 3 1 --commissioner-name gamma Verify the StoreSceneResponse with following fields: Status is RESOURCE_EXHAUSTED(0x89) on the TH3(Chip-tool) log and below is the sample log provided for the raspi platform: - [1705915551.740537][21417:21419] CHIP:DMG: }, - [1705915551.740557][21417:21419] CHIP:DMG: Received Command Response Data, Endpoint=1 Cluster=0x0000_0062 Command=0x0000_0004 - [1705915551.740566][21417:21419] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0062 Command 0x0000_0004 - [1705915551.740585][21417:21419] CHIP:TOO: StoreSceneResponse: { - [1705915551.740590][21417:21419] CHIP:TOO: status: 137 - [1705915551.740593][21417:21419] CHIP:TOO: groupID: 0 - [1705915551.740596][21417:21419] CHIP:TOO: sceneID: 1 - [1705915551.740598][21417:21419] CHIP:TOO: } + [1718862868.462786][6330:6332] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0062 Command 0x0000_0004 + [1718862868.462834][6330:6332] CHIP:TOO: StoreSceneResponse: { + [1718862868.462862][6330:6332] CHIP:TOO: status: 137 + [1718862868.462885][6330:6332] CHIP:TOO: groupID: 0 + [1718862868.462908][6330:6332] CHIP:TOO: sceneID: 254 + [1718862868.462930][6330:6332] CHIP:TOO: } disabled: true - label: "Step 8: TH sends a CopyScene command to DUT with the mode field set to 0x00, the group identifier from field set to 0x0000, the scene identifier from field set to 0x01, the group identifier to field set - to 0x0000 and the scene identifier to field set to 0xFE." + to 0x0000 and the scene identifier to field set to 0x02." PICS: S.S.C40.Rsp verification: | - scenesmanagement copy-scene 0x00 0x0000 0x02 0x0000 0x00 3 1 --commissioner-name gamma + scenesmanagement copy-scene 0x00 0x0000 0x01 0x0000 0x02 1 1 Verify the CopySceneResponse with following fields: - Status is RESOURCE_EXHAUSTED(0x89) on the TH(Chip-tool) log and below is the sample log provided for the raspi platform: - - [1705915659.672801][21417:21419] CHIP:DMG: }, - [1705915659.672875][21417:21419] CHIP:DMG: Received Command Response Data, Endpoint=1 Cluster=0x0000_0062 Command=0x0000_0040 - [1705915659.672891][21417:21419] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0062 Command 0x0000_0040 - [1705915659.672923][21417:21419] CHIP:TOO: CopySceneResponse: { - [1705915659.672937][21417:21419] CHIP:TOO: status: 133 - [1705915659.672950][21417:21419] CHIP:TOO: groupIdentifierFrom: 0 - [1705915659.672979][21417:21419] CHIP:TOO: sceneIdentifierFrom: 2 - [1705915659.672991][21417:21419] CHIP:TOO: } + Status is RESOURCE_EXHAUSTED(0x89), the group identifier from field set to 0x0000 and the scene identifier from field set to 1 on the TH(Chip-tool) log and below is the sample log provided for the raspi platform: + + [1708499075.003907][25643:25645] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0062 Command 0x0000_0040 + [1708499075.004059][25643:25645] CHIP:TOO: CopySceneResponse: { + [1708499075.004128][25643:25645] CHIP:TOO: status: 137 + [1708499075.004185][25643:25645] CHIP:TOO: groupIdentifierFrom: 0 + [1708499075.004240][25643:25645] CHIP:TOO: sceneIdentifierFrom: 1 + [1708499075.004293][25643:25645] CHIP:TOO: } disabled: true - label: @@ -1147,32 +1143,30 @@ tests: "Step 11a: TH1 removes the TH2 fabric by sending the RemoveFabric command to the DUT with the FabricIndex set to th2FabricIndex" verification: | - operationalcredentials remove-fabric th2FabricIndex 1 0 + operationalcredentials remove-fabric 2 1 0 - On TH1(chip-tool) verify the success with the nocresponse with statuscode is success(0) + Verify the DUT sends a response to TH with the Status field set to 0x00 (SUCCESS) and the FabricIndex field set to th2FabricIndex on TH1(Chip-tool) log and below is the sample log provided for the raspi platform: - [1784416866.004187][21433:21435] CHIP:DMG: Received Command Response Data, Endpoint=0 Cluster=0x0000_003E Command=0x0000_0008 - [1784416866.004214][21433:21435] CHIP:TOO: Endpoint: 0 Cluster: 0x0000_003E Command 0x0000_0008 - [1784416866.004236][21433:21435] CHIP:TOO: NOCResponse: { - [1784416866.004250][21433:21435] CHIP:TOO: statusCode: 0 - [1784416866.004255][21433:21435] CHIP:TOO: fabricIndex: th2FabricIndex - [1784416866.004259][21433:21435] CHIP:TOO: } - [1784416866.004270][21433:21435] CHIP:DMG: ICR moving to [AwaitingDe] + [1708332262.744710][18447:18449] CHIP:DMG: }, + [1708332262.744728][18447:18449] CHIP:DMG: Received Command Response Data, Endpoint=0 Cluster=0x0000_003E Command=0x0000_0008 + [1708332262.744737][18447:18449] CHIP:TOO: Endpoint: 0 Cluster: 0x0000_003E Command 0x0000_0008 + [1708332262.744755][18447:18449] CHIP:TOO: NOCResponse: { + [1708332262.744761][18447:18449] CHIP:TOO: statusCode: 0 + [1708332262.744765][18447:18449] CHIP:TOO: fabricIndex: 2 + [1708332262.744768][18447:18449] CHIP:TOO: } disabled: true - label: "Step 11b: TH1 removes the TH3 fabric by sending the RemoveFabric command to the DUT with the FabricIndex set to th3FabricIndex" verification: | - operationalcredentials remove-fabric th3FabricIndex 1 0 + operationalcredentials remove-fabric 3 1 0 - On TH1(chip-tool) verify the success with the nocresponse with statuscode is success(0) + Verify the DUT sends a response to TH with the Status field set to 0x00 (SUCCESS) and the FabricIndex field set to th3FabricIndex on TH1(Chip-tool) log and below is the sample log provided for the raspi platform: - [1784416866.004187][21433:21435] CHIP:DMG: Received Command Response Data, Endpoint=0 Cluster=0x0000_003E Command=0x0000_0008 - [1784416866.004214][21433:21435] CHIP:TOO: Endpoint: 0 Cluster: 0x0000_003E Command 0x0000_0008 - [1784416866.004236][21433:21435] CHIP:TOO: NOCResponse: { - [1784416866.004250][21433:21435] CHIP:TOO: statusCode: 0 - [1784416866.004255][21433:21435] CHIP:TOO: fabricIndex: th3FabricIndex - [1784416866.004259][21433:21435] CHIP:TOO: } - [1784416866.004270][21433:21435] CHIP:DMG: ICR moving to [AwaitingDe] + [1708332339.212544][18440:18442] CHIP:TOO: Endpoint: 0 Cluster: 0x0000_003E Command 0x0000_0008 + [1708332339.212553][18440:18442] CHIP:TOO: NOCResponse: { + [1708332339.212557][18440:18442] CHIP:TOO: statusCode: 0 + [1708332339.212560][18440:18442] CHIP:TOO: fabricIndex: 3 + [1708332339.212562][18440:18442] CHIP:TOO: } disabled: true From 9afad6610731f308f6a5da0aa058ce97b7e801a9 Mon Sep 17 00:00:00 2001 From: Yufeng Wang Date: Tue, 22 Oct 2024 10:21:42 -0700 Subject: [PATCH 067/149] Match the log with its implemantation (#36183) --- src/app/server/Server.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/server/Server.cpp b/src/app/server/Server.cpp index e4db190c507608..9a32401bc7a47d 100644 --- a/src/app/server/Server.cpp +++ b/src/app/server/Server.cpp @@ -343,9 +343,9 @@ CHIP_ERROR Server::Init(const ServerInitParams & initParams) if (GetFabricTable().FabricCount() != 0) { +#if CONFIG_NETWORK_LAYER_BLE // The device is already commissioned, proactively disable BLE advertisement. ChipLogProgress(AppServer, "Fabric already commissioned. Disabling BLE advertisement"); -#if CONFIG_NETWORK_LAYER_BLE chip::DeviceLayer::ConnectivityMgr().SetBLEAdvertisingEnabled(false); #endif } From c98b1f520a42004df3dff6f0e1413e49cdeb001e Mon Sep 17 00:00:00 2001 From: Amine Alami <43780877+Alami-Amine@users.noreply.github.com> Date: Tue, 22 Oct 2024 19:30:39 +0200 Subject: [PATCH 068/149] Improve Exit Error Handling for failures in PASE pairing requests (#36160) * Improve Error Handling for failures in PASE pairing requests * Integrating comments * clarifying Pair API contract regarding the delegate * integrating comment on API --- src/protocols/secure_channel/PASESession.cpp | 8 ++++++++ src/protocols/secure_channel/PASESession.h | 2 ++ 2 files changed, 10 insertions(+) diff --git a/src/protocols/secure_channel/PASESession.cpp b/src/protocols/secure_channel/PASESession.cpp index 638b99624bae6c..4bf1aa55217c57 100644 --- a/src/protocols/secure_channel/PASESession.cpp +++ b/src/protocols/secure_channel/PASESession.cpp @@ -232,7 +232,15 @@ CHIP_ERROR PASESession::Pair(SessionManager & sessionManager, uint32_t peerSetUp exit: if (err != CHIP_NO_ERROR) { + // If a failure happens before we have placed the incoming exchange into `mExchangeCtxt`, we need to make + // sure to close the exchange to fulfill our API contract. + if (!mExchangeCtxt.HasValue()) + { + exchangeCtxt->Close(); + } Clear(); + ChipLogError(SecureChannel, "Failed during PASE session pairing request: %" CHIP_ERROR_FORMAT, err.Format()); + MATTER_TRACE_COUNTER("PASEFail"); } return err; } diff --git a/src/protocols/secure_channel/PASESession.h b/src/protocols/secure_channel/PASESession.h index 2e731283c88aa8..92b4ee3d8b991c 100644 --- a/src/protocols/secure_channel/PASESession.h +++ b/src/protocols/secure_channel/PASESession.h @@ -99,6 +99,8 @@ class DLL_EXPORT PASESession : public Messaging::UnsolicitedMessageHandler, * ownership of the exchangeCtxt to PASESession object. PASESession * will close the exchange on (successful/failed) handshake completion. * @param delegate Callback object + * The delegate will be notified if and only if Pair() returns success. Errors occurring after Pair() + * returns success will be reported via the delegate. * * @return CHIP_ERROR The result of initialization */ From 0b93b0d97b90e15e64aa1a5bbaf5c3840398b59f Mon Sep 17 00:00:00 2001 From: arun-silabs <141724790+arun-silabs@users.noreply.github.com> Date: Tue, 22 Oct 2024 23:43:56 +0530 Subject: [PATCH 069/149] [Silabs] Update WiseConnect to v3.3.3 (#36086) * Update wifi sdk to v3.3.3 * Updated matter_support pointer * Updated docker image WiseConnect v3.3.3 * Reverting the docker changes * Updated comments in DockerFile * Removed unused source file * Updated workflow to pick-up latest docker image * Updated docker version in the build files * Added changes to resolve build errors for brd2605a * Corrected variable name in gn file * Removed TO-DO comment * Replaced SI917_DEVKIT macro to SL_MATTER_RGB_LED_ENABLED * Resolved review comments * Updated WiseMcuSpam.cpp as per the latest defines * Update third_party/silabs/silabs_board.gni * Added sl_enable_rgb_led in inside if-else of soc board condition --------- Co-authored-by: bhmanda Co-authored-by: Mathieu Kardous <84793247+mkardous-silabs@users.noreply.github.com> Co-authored-by: bhmanda-silabs <107180296+bhmanda-silabs@users.noreply.github.com> --- .github/workflows/examples-efr32.yaml | 2 +- .github/workflows/release_artifacts.yaml | 2 +- .gitmodules | 2 +- .../silabs/SiWx917/SiWx917/sl_wlan_config.h | 8 +++++ examples/platform/silabs/uart.cpp | 1 - integrations/cloudbuild/smoke-test.yaml | 14 ++++---- .../platformAbstraction/WiseMcuSpam.cpp | 26 +++++++++++--- src/platform/silabs/rs911x/rsi_ble_config.h | 12 +++++-- third_party/silabs/SiWx917_sdk.gni | 35 ++++++++++++++++--- third_party/silabs/matter_support | 2 +- third_party/silabs/silabs_board.gni | 6 ++++ third_party/silabs/wifi_sdk | 2 +- 12 files changed, 86 insertions(+), 26 deletions(-) diff --git a/.github/workflows/examples-efr32.yaml b/.github/workflows/examples-efr32.yaml index 57337d553128b5..9a483ab5ec4c9e 100644 --- a/.github/workflows/examples-efr32.yaml +++ b/.github/workflows/examples-efr32.yaml @@ -41,7 +41,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-efr32:81 + image: ghcr.io/project-chip/chip-build-efr32:83 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" steps: diff --git a/.github/workflows/release_artifacts.yaml b/.github/workflows/release_artifacts.yaml index 22cf6b335eaa12..45ef34c5ee5aae 100644 --- a/.github/workflows/release_artifacts.yaml +++ b/.github/workflows/release_artifacts.yaml @@ -64,7 +64,7 @@ jobs: runs-on: ubuntu-latest container: - image: ghcr.io/project-chip/chip-build-efr32:81 + image: ghcr.io/project-chip/chip-build-efr32:83 steps: - name: Checkout uses: actions/checkout@v4 diff --git a/.gitmodules b/.gitmodules index ed472c937c5e0d..c26ee8f792c1c3 100644 --- a/.gitmodules +++ b/.gitmodules @@ -223,7 +223,7 @@ [submodule "third_party/silabs/wifi_sdk"] path = third_party/silabs/wifi_sdk url = https://github.com/SiliconLabs/wiseconnect.git - branch = v3.3.2 + branch = v3.3.3 platforms = silabs [submodule "editline"] path = third_party/editline/repo diff --git a/examples/platform/silabs/SiWx917/SiWx917/sl_wlan_config.h b/examples/platform/silabs/SiWx917/SiWx917/sl_wlan_config.h index cd605b0f0a5152..57622a61ff65f4 100644 --- a/examples/platform/silabs/SiWx917/SiWx917/sl_wlan_config.h +++ b/examples/platform/silabs/SiWx917/SiWx917/sl_wlan_config.h @@ -29,6 +29,14 @@ //! Disable feature #define RSI_DISABLE 0 +// Temmporary work-around for wifi-init failure in ACX modules with WiseConnect v3.3.3. This can be removed after integrating with +// WiseConnect v3.4.0 +#if (SL_SI91X_ACX_MODULE == 1) +#define REGION_CODE IGNORE_REGION +#else +#define REGION_CODE US +#endif + static const sl_wifi_device_configuration_t config = { .boot_option = LOAD_NWP_FW, .mac_address = NULL, diff --git a/examples/platform/silabs/uart.cpp b/examples/platform/silabs/uart.cpp index 1af3cb75d9f507..390e151cb7fbbf 100644 --- a/examples/platform/silabs/uart.cpp +++ b/examples/platform/silabs/uart.cpp @@ -38,7 +38,6 @@ extern "C" { #include "rsi_board.h" #include "rsi_debug.h" #include "rsi_rom_egpio.h" -#include "sl_si91x_usart.h" #else // For EFR32 #if (_SILICON_LABS_32B_SERIES < 3) #include "em_core.h" diff --git a/integrations/cloudbuild/smoke-test.yaml b/integrations/cloudbuild/smoke-test.yaml index 99bc5042ed9939..b8c44cfa30c565 100644 --- a/integrations/cloudbuild/smoke-test.yaml +++ b/integrations/cloudbuild/smoke-test.yaml @@ -1,5 +1,5 @@ steps: - - name: "ghcr.io/project-chip/chip-build-vscode:81" + - name: "ghcr.io/project-chip/chip-build-vscode:83" entrypoint: "bash" args: - "-c" @@ -7,7 +7,7 @@ steps: git config --global --add safe.directory "*" python scripts/checkout_submodules.py --shallow --recursive --platform esp32 nrfconnect silabs linux android id: Submodules - - name: "ghcr.io/project-chip/chip-build-vscode:81" + - name: "ghcr.io/project-chip/chip-build-vscode:83" # NOTE: silabs boostrap is NOT done with the rest as it requests a conflicting # jinja2 version (asks for 3.1.3 when constraints.txt asks for 3.0.3) env: @@ -24,7 +24,7 @@ steps: path: /pwenv timeout: 900s - - name: "ghcr.io/project-chip/chip-build-vscode:81" + - name: "ghcr.io/project-chip/chip-build-vscode:83" id: ESP32 env: - PW_ENVIRONMENT_ROOT=/pwenv @@ -45,7 +45,7 @@ steps: volumes: - name: pwenv path: /pwenv - - name: "ghcr.io/project-chip/chip-build-vscode:81" + - name: "ghcr.io/project-chip/chip-build-vscode:83" id: NRFConnect env: - PW_ENVIRONMENT_ROOT=/pwenv @@ -66,7 +66,7 @@ steps: - name: pwenv path: /pwenv - - name: "ghcr.io/project-chip/chip-build-vscode:81" + - name: "ghcr.io/project-chip/chip-build-vscode:83" id: EFR32 env: - PW_ENVIRONMENT_ROOT=/pwenv @@ -88,7 +88,7 @@ steps: - name: pwenv path: /pwenv - - name: "ghcr.io/project-chip/chip-build-vscode:81" + - name: "ghcr.io/project-chip/chip-build-vscode:83" id: Linux env: - PW_ENVIRONMENT_ROOT=/pwenv @@ -141,7 +141,7 @@ steps: - name: pwenv path: /pwenv - - name: "ghcr.io/project-chip/chip-build-vscode:81" + - name: "ghcr.io/project-chip/chip-build-vscode:83" id: Android env: - PW_ENVIRONMENT_ROOT=/pwenv diff --git a/src/platform/silabs/platformAbstraction/WiseMcuSpam.cpp b/src/platform/silabs/platformAbstraction/WiseMcuSpam.cpp index a99ac5ea2908f9..cf60cf5c5892fe 100644 --- a/src/platform/silabs/platformAbstraction/WiseMcuSpam.cpp +++ b/src/platform/silabs/platformAbstraction/WiseMcuSpam.cpp @@ -36,8 +36,15 @@ extern "C" { #include "sl_event_handler.h" #include "sl_si91x_button.h" #include "sl_si91x_button_pin_config.h" +#if defined(SL_MATTER_RGB_LED_ENABLED) && SL_MATTER_RGB_LED_ENABLED +#include "sl_si91x_rgb_led.h" +#include "sl_si91x_rgb_led_config.h" +#include "sl_si91x_rgb_led_instances.h" +#else #include "sl_si91x_led.h" #include "sl_si91x_led_config.h" +#include "sl_si91x_led_instances.h" +#endif // defined(SL_MATTER_RGB_LED_ENABLED) && SL_MATTER_RGB_LED_ENABLED #if CHIP_CONFIG_ENABLE_ICD_SERVER == 0 void soc_pll_config(void); @@ -51,14 +58,15 @@ void soc_pll_config(void); #if SILABS_LOG_OUT_UART || ENABLE_CHIP_SHELL #include "uart.h" #endif -// TODO Remove this when SI91X-16606 is addressed -#ifdef SI917_DEVKIT -#define SL_LED_COUNT 1 -uint8_t ledPinArray[SL_LED_COUNT] = { SL_LED_LEDB_PIN }; + +#if defined(SL_MATTER_RGB_LED_ENABLED) && SL_MATTER_RGB_LED_ENABLED +#define SL_LED_COUNT SL_SI91X_RGB_LED_COUNT +const sl_rgb_led_t * ledPinArray[SL_LED_COUNT] = { &led_led0 }; +#define SL_RGB_LED_INSTANCE(n) (ledPinArray[n]) #else #define SL_LED_COUNT SL_SI91x_LED_COUNT uint8_t ledPinArray[SL_LED_COUNT] = { SL_LED_LED0_PIN, SL_LED_LED1_PIN }; -#endif +#endif // defined(SL_MATTER_RGB_LED_ENABLED) && SL_MATTER_RGB_LED_ENABLED namespace chip { namespace DeviceLayer { @@ -111,7 +119,11 @@ void SilabsPlatform::InitLed(void) CHIP_ERROR SilabsPlatform::SetLed(bool state, uint8_t led) { VerifyOrReturnError(led < SL_LED_COUNT, CHIP_ERROR_INVALID_ARGUMENT); +#if defined(SL_MATTER_RGB_LED_ENABLED) && SL_MATTER_RGB_LED_ENABLED + (state) ? sl_si91x_simple_rgb_led_on(SL_RGB_LED_INSTANCE(led)) : sl_si91x_simple_rgb_led_off(SL_RGB_LED_INSTANCE(led)); +#else (state) ? sl_si91x_led_set(ledPinArray[led]) : sl_si91x_led_clear(ledPinArray[led]); +#endif // defined(SL_MATTER_RGB_LED_ENABLED) && SL_MATTER_RGB_LED_ENABLED return CHIP_NO_ERROR; } @@ -124,7 +136,11 @@ bool SilabsPlatform::GetLedState(uint8_t led) CHIP_ERROR SilabsPlatform::ToggleLed(uint8_t led) { VerifyOrReturnError(led < SL_LED_COUNT, CHIP_ERROR_INVALID_ARGUMENT); +#if defined(SL_MATTER_RGB_LED_ENABLED) && SL_MATTER_RGB_LED_ENABLED + sl_si91x_simple_rgb_led_toggle(SL_RGB_LED_INSTANCE(led)); +#else sl_si91x_led_toggle(ledPinArray[led]); +#endif // defined(SL_MATTER_RGB_LED_ENABLED) && SL_MATTER_RGB_LED_ENABLED return CHIP_NO_ERROR; } #endif // ENABLE_WSTK_LEDS diff --git a/src/platform/silabs/rs911x/rsi_ble_config.h b/src/platform/silabs/rs911x/rsi_ble_config.h index de207a99af1601..f508c3396f4e09 100644 --- a/src/platform/silabs/rs911x/rsi_ble_config.h +++ b/src/platform/silabs/rs911x/rsi_ble_config.h @@ -232,7 +232,6 @@ //! Scan types #define SCAN_TYPE_ACTIVE (0x01) -#define SCAN_TYPE_PASSIVE (0x00) //! Scan filters #define SCAN_FILTER_TYPE_ALL (0x00) @@ -267,15 +266,22 @@ (SL_SI91X_TCP_IP_FEAT_DHCPV4_CLIENT) //! TCP/IP feature select bitmap for selecting TCP/IP features #define RSI_CUSTOM_FEATURE_BIT_MAP SL_SI91X_CUSTOM_FEAT_EXTENTION_VALID //! To set custom feature select bit map +// Enable front-end internal switch control for ACX module boards +#if (SL_SI91X_ACX_MODULE == 1) +#define FRONT_END_SWITCH_CTRL SL_SI91X_EXT_FEAT_FRONT_END_INTERNAL_SWITCH +#else +#define FRONT_END_SWITCH_CTRL SL_SI91X_EXT_FEAT_FRONT_END_SWITCH_PINS_ULP_GPIO_4_5_0 +#endif + #ifdef SLI_SI917 #if WIFI_ENABLE_SECURITY_WPA3_TRANSITION // Adding Support for WPA3 transition #define RSI_EXT_CUSTOM_FEATURE_BIT_MAP \ (SL_SI91X_EXT_FEAT_LOW_POWER_MODE | SL_SI91X_EXT_FEAT_XTAL_CLK_ENABLE(1) | SL_SI91X_RAM_LEVEL_NWP_BASIC_MCU_ADV | \ - SL_SI91X_EXT_FEAT_FRONT_END_SWITCH_PINS_ULP_GPIO_4_5_0 | SL_SI91X_EXT_FEAT_IEEE_80211W) + FRONT_END_SWITCH_CTRL | SL_SI91X_EXT_FEAT_IEEE_80211W) #else #define RSI_EXT_CUSTOM_FEATURE_BIT_MAP \ (SL_SI91X_EXT_FEAT_LOW_POWER_MODE | SL_SI91X_EXT_FEAT_XTAL_CLK_ENABLE(1) | SL_SI91X_RAM_LEVEL_NWP_BASIC_MCU_ADV | \ - SL_SI91X_EXT_FEAT_FRONT_END_SWITCH_PINS_ULP_GPIO_4_5_0) + FRONT_END_SWITCH_CTRL) #endif /* WIFI_ENABLE_SECURITY_WPA3_TRANSITION */ #else // EXP_BOARD #define RSI_EXT_CUSTOM_FEATURE_BIT_MAP (SL_SI91X_EXT_FEAT_LOW_POWER_MODE | SL_SI91X_EXT_FEAT_XTAL_CLK_ENABLE(2)) diff --git a/third_party/silabs/SiWx917_sdk.gni b/third_party/silabs/SiWx917_sdk.gni index d338ea7d0a9162..3accbed0bc12f2 100644 --- a/third_party/silabs/SiWx917_sdk.gni +++ b/third_party/silabs/SiWx917_sdk.gni @@ -137,8 +137,6 @@ template("siwx917_sdk") { "${efr32_sdk_root}/platform/service/iostream/inc", "${wifi_sdk_root}/components/device/silabs/si91x/mcu/drivers/hardware_drivers/button/inc", "${wifi_sdk_root}/components/device/silabs/si91x/mcu/drivers/hardware_drivers/button/config", - "${wifi_sdk_root}/components/device/silabs/si91x/mcu/drivers/hardware_drivers/led/inc", - "${wifi_sdk_root}/components/device/silabs/si91x/mcu/drivers/hardware_drivers/led/config", "${wifi_sdk_root}/components/device/silabs/si91x/mcu/core/config", # sl memory manager @@ -156,6 +154,18 @@ template("siwx917_sdk") { "${wifi_sdk_root}/components/device/silabs/si91x/mcu/drivers/service/power_manager/inc", ] + if (sl_enable_rgb_led) { + _include_dirs += [ + "${wifi_sdk_root}/components/device/silabs/si91x/mcu/drivers/hardware_drivers/rgb_led/inc", + "${wifi_sdk_root}/components/device/silabs/si91x/mcu/drivers/hardware_drivers/rgb_led/config", + ] + } else { + _include_dirs += [ + "${wifi_sdk_root}/components/device/silabs/si91x/mcu/drivers/hardware_drivers/led/inc", + "${wifi_sdk_root}/components/device/silabs/si91x/mcu/drivers/hardware_drivers/led/config", + ] + } + if (use_system_view) { _include_dirs += [ "${efr32_sdk_root}/util/third_party/segger/systemview/SEGGER", @@ -299,6 +309,12 @@ template("siwx917_sdk") { defines += [ "ENABLE_WSTK_LEDS" ] } + if (sl_enable_rgb_led) { + defines += [ "SL_MATTER_RGB_LED_ENABLED=1" ] + } else { + defines += [ "SL_MATTER_RGB_LED_ENABLED=0" ] + } + if (chip_enable_icd_server) { defines += [ "SL_ICD_ENABLED=1", @@ -649,7 +665,6 @@ template("siwx917_sdk") { "${wifi_sdk_root}/components/device/silabs/si91x/mcu/drivers/systemlevel/src/rsi_temp_sensor.c", "${wifi_sdk_root}/components/device/silabs/si91x/mcu/drivers/systemlevel/src/rsi_ulpss_clk.c", "${wifi_sdk_root}/components/device/silabs/si91x/mcu/drivers/unified_api/src/sl_si91x_driver_gpio.c", - "${wifi_sdk_root}/components/device/silabs/si91x/mcu/drivers/unified_api/src/sl_si91x_usart.c", "${wifi_sdk_root}/components/device/silabs/si91x/mcu/drivers/unified_peripheral_drivers/src/sl_si91x_peripheral_gpio.c", "${wifi_sdk_root}/components/device/silabs/si91x/wireless/ahb_interface/src/rsi_hal_mcu_m4_ram.c", "${wifi_sdk_root}/components/device/silabs/si91x/wireless/ahb_interface/src/rsi_hal_mcu_m4_rom.c", @@ -687,11 +702,9 @@ template("siwx917_sdk") { "${efr32_sdk_root}/util/third_party/freertos/kernel/timers.c", "${sdk_support_root}/matter/si91x/siwx917/${silabs_board}/autogen/sl_event_handler.c", "${sdk_support_root}/matter/si91x/siwx917/${silabs_board}/autogen/sl_si91x_button_instances.c", - "${sdk_support_root}/matter/si91x/siwx917/${silabs_board}/autogen/sl_si91x_led_instances.c", "${sdk_support_root}/matter/si91x/siwx917/${silabs_board}/autogen/sl_ulp_timer_init.c", "${sdk_support_root}/matter/si91x/support/hal/rsi_hal_mcu_m4.c", "${wifi_sdk_root}/components/device/silabs/si91x/mcu/drivers/hardware_drivers/button/src/sl_si91x_button.c", - "${wifi_sdk_root}/components/device/silabs/si91x/mcu/drivers/hardware_drivers/led/src/sl_si91x_led.c", "${wifi_sdk_root}/components/device/silabs/si91x/mcu/drivers/service/nvm3/src/sl_si91x_nvm3_hal_flash.c", # sl memory manager @@ -716,6 +729,18 @@ template("siwx917_sdk") { "${wifi_sdk_root}/components/device/silabs/si91x/wireless/firmware_upgrade/firmware_upgradation.c", ] + if (sl_enable_rgb_led) { + sources += [ + "${sdk_support_root}/matter/si91x/siwx917/${silabs_board}/autogen/sl_si91x_rgb_led_instances.c", + "${wifi_sdk_root}/components/device/silabs/si91x/mcu/drivers/hardware_drivers/rgb_led/src/sl_si91x_rgb_led.c", + ] + } else { + sources += [ + "${sdk_support_root}/matter/si91x/siwx917/${silabs_board}/autogen/sl_si91x_led_instances.c", + "${wifi_sdk_root}/components/device/silabs/si91x/mcu/drivers/hardware_drivers/led/src/sl_si91x_led.c", + ] + } + if (use_system_view) { sources += [ "${chip_root}/examples/platform/silabs/sl_systemview_config.h", diff --git a/third_party/silabs/matter_support b/third_party/silabs/matter_support index 841d43db7e8687..8dd7b9bb5f8577 160000 --- a/third_party/silabs/matter_support +++ b/third_party/silabs/matter_support @@ -1 +1 @@ -Subproject commit 841d43db7e86877636cd73b5244da4c34d38d544 +Subproject commit 8dd7b9bb5f8577834140bcc54f7497ae3f4b9bd0 diff --git a/third_party/silabs/silabs_board.gni b/third_party/silabs/silabs_board.gni index 03b2ea7cb67cb5..aa51817fffdae7 100644 --- a/third_party/silabs/silabs_board.gni +++ b/third_party/silabs/silabs_board.gni @@ -56,6 +56,9 @@ declare_args() { # Temperature Sensor support sl_enable_si70xx_sensor = false + + # RGB LED support + sl_enable_rgb_led = false } declare_args() { @@ -74,6 +77,9 @@ assert(silabs_board != "", "silabs_board must be specified") # Si917 WIFI board ---------- if (silabs_board == "BRD4338A" || silabs_board == "BRD2605A") { + if (silabs_board == "BRD2605A") { + sl_enable_rgb_led = true + } silabs_family = "SiWx917-common" silabs_mcu = "SiWG917M111MGTBA" wifi_soc = true diff --git a/third_party/silabs/wifi_sdk b/third_party/silabs/wifi_sdk index b5d6422f300cc0..a6390dd746f006 160000 --- a/third_party/silabs/wifi_sdk +++ b/third_party/silabs/wifi_sdk @@ -1 +1 @@ -Subproject commit b5d6422f300cc075c7eaeec96e9f7e3f4e23bf06 +Subproject commit a6390dd746f0067b855a6b41293159244f3ca1b4 From 9041169214bcf042ca4f706af92ea5765e423f72 Mon Sep 17 00:00:00 2001 From: C Freeman Date: Tue, 22 Oct 2024 16:12:32 -0400 Subject: [PATCH 070/149] Revert "[Feature] Adding Step Endpoint Information (#35662)" (#36198) This reverts commit 36fff943931278c6950c2330620ef36a23b79cb7. This breaks the TH and the API for the step command is overkill. --- .../matter_yamltests/hooks.py | 4 +- src/python_testing/TC_ACE_1_3.py | 236 +++++++++--------- src/python_testing/TC_BOOLCFG_2_1.py | 18 +- .../chip/testing/matter_testing.py | 22 +- .../test_testing/TestDecorators.py | 2 +- 5 files changed, 137 insertions(+), 145 deletions(-) diff --git a/scripts/py_matter_yamltests/matter_yamltests/hooks.py b/scripts/py_matter_yamltests/matter_yamltests/hooks.py index d14e90a7aabe90..ca739b8ea27633 100644 --- a/scripts/py_matter_yamltests/matter_yamltests/hooks.py +++ b/scripts/py_matter_yamltests/matter_yamltests/hooks.py @@ -152,7 +152,7 @@ def step_skipped(self, name: str, expression: str): """ pass - def step_start(self, request: TestStep, endpoint: Optional[int] = None): + def step_start(self, request: TestStep): """ This method is called when the runner starts running a step from the test. @@ -160,8 +160,6 @@ def step_start(self, request: TestStep, endpoint: Optional[int] = None): ---------- request: TestStep The original request as defined by the test step. - endpoint: int - An optional device endpoint the step will target. """ pass diff --git a/src/python_testing/TC_ACE_1_3.py b/src/python_testing/TC_ACE_1_3.py index 2868d9548f7733..1672eb65af2a51 100644 --- a/src/python_testing/TC_ACE_1_3.py +++ b/src/python_testing/TC_ACE_1_3.py @@ -54,16 +54,16 @@ async def write_acl(self, acl): asserts.assert_equal(result[0].Status, Status.Success, "ACL write failed") print(result) - async def read_descriptor_expect_success(self, th, endpoint: int): + async def read_descriptor_expect_success(self, th): cluster = Clusters.Objects.Descriptor attribute = Clusters.Descriptor.Attributes.DeviceTypeList - await self.read_single_attribute_check_success(dev_ctrl=th, endpoint=endpoint, cluster=cluster, attribute=attribute) + await self.read_single_attribute_check_success(dev_ctrl=th, endpoint=0, cluster=cluster, attribute=attribute) - async def read_descriptor_expect_unsupported_access(self, th, endpoint: int): + async def read_descriptor_expect_unsupported_access(self, th): cluster = Clusters.Objects.Descriptor attribute = Clusters.Descriptor.Attributes.DeviceTypeList await self.read_single_attribute_expect_error( - dev_ctrl=th, endpoint=endpoint, cluster=cluster, attribute=attribute, error=Status.UnsupportedAccess) + dev_ctrl=th, endpoint=0, cluster=cluster, attribute=attribute, error=Status.UnsupportedAccess) def desc_TC_ACE_1_3(self) -> str: return "[TC-ACE-1.3] Subjects" @@ -144,8 +144,6 @@ async def test_TC_ACE_1_3(self): cat2v3 = cat2_id | 0x0003 logging.info('cat1v1 0x%x', cat1v1) - endpoint = 0 - self.step(1) fabric_admin = self.certificate_authority_manager.activeCaList[0].adminList[0] @@ -165,266 +163,266 @@ async def test_TC_ACE_1_3(self): paaTrustStorePath=str(self.matter_test_config.paa_trust_store_path), catTags=[cat1v1, cat2v2]) - self.step(2, endpoint) + self.step(2) TH0_admin_acl = Clusters.AccessControl.Structs.AccessControlEntryStruct( privilege=Clusters.AccessControl.Enums.AccessControlEntryPrivilegeEnum.kAdminister, authMode=Clusters.AccessControl.Enums.AccessControlEntryAuthModeEnum.kCase, subjects=[TH0_nodeid], - targets=[Clusters.AccessControl.Structs.AccessControlTargetStruct(endpoint=endpoint, cluster=0x001f)]) + targets=[Clusters.AccessControl.Structs.AccessControlTargetStruct(endpoint=0, cluster=0x001f)]) all_view = Clusters.AccessControl.Structs.AccessControlEntryStruct( privilege=Clusters.AccessControl.Enums.AccessControlEntryPrivilegeEnum.kView, authMode=Clusters.AccessControl.Enums.AccessControlEntryAuthModeEnum.kCase, subjects=[], - targets=[Clusters.AccessControl.Structs.AccessControlTargetStruct(endpoint=endpoint)]) + targets=[Clusters.AccessControl.Structs.AccessControlTargetStruct(endpoint=0)]) acl = [TH0_admin_acl, all_view] await self.write_acl(acl) - self.step(3, endpoint) - await self.read_descriptor_expect_success(TH1, endpoint) + self.step(3) + await self.read_descriptor_expect_success(TH1) - self.step(4, endpoint) - await self.read_descriptor_expect_success(TH2, endpoint) + self.step(4) + await self.read_descriptor_expect_success(TH2) - self.step(5, endpoint) - await self.read_descriptor_expect_success(TH3, endpoint) + self.step(5) + await self.read_descriptor_expect_success(TH3) - self.step(6, endpoint) + self.step(6) th1_view = Clusters.AccessControl.Structs.AccessControlEntryStruct( privilege=Clusters.AccessControl.Enums.AccessControlEntryPrivilegeEnum.kView, authMode=Clusters.AccessControl.Enums.AccessControlEntryAuthModeEnum.kCase, subjects=[TH1_nodeid], - targets=[Clusters.AccessControl.Structs.AccessControlTargetStruct(endpoint=endpoint)]) + targets=[Clusters.AccessControl.Structs.AccessControlTargetStruct(endpoint=0)]) acl = [TH0_admin_acl, th1_view] await self.write_acl(acl) - self.step(7, endpoint) - await self.read_descriptor_expect_success(TH1, endpoint) + self.step(7) + await self.read_descriptor_expect_success(TH1) - self.step(8, endpoint) - await self.read_descriptor_expect_unsupported_access(TH2, endpoint) + self.step(8) + await self.read_descriptor_expect_unsupported_access(TH2) - self.step(9, endpoint) - await self.read_descriptor_expect_unsupported_access(TH3, endpoint) + self.step(9) + await self.read_descriptor_expect_unsupported_access(TH3) - self.step(10, endpoint) + self.step(10) th2_view = Clusters.AccessControl.Structs.AccessControlEntryStruct( privilege=Clusters.AccessControl.Enums.AccessControlEntryPrivilegeEnum.kView, authMode=Clusters.AccessControl.Enums.AccessControlEntryAuthModeEnum.kCase, subjects=[TH2_nodeid], - targets=[Clusters.AccessControl.Structs.AccessControlTargetStruct(endpoint=endpoint)]) + targets=[Clusters.AccessControl.Structs.AccessControlTargetStruct(endpoint=0)]) acl = [TH0_admin_acl, th2_view] await self.write_acl(acl) - self.step(11, endpoint) - await self.read_descriptor_expect_unsupported_access(TH1, endpoint) + self.step(11) + await self.read_descriptor_expect_unsupported_access(TH1) - self.step(12, endpoint) - await self.read_descriptor_expect_success(TH2, endpoint) + self.step(12) + await self.read_descriptor_expect_success(TH2) - self.step(13, endpoint) - await self.read_descriptor_expect_unsupported_access(TH3, endpoint) + self.step(13) + await self.read_descriptor_expect_unsupported_access(TH3) - self.step(14, endpoint) + self.step(14) th3_view = Clusters.AccessControl.Structs.AccessControlEntryStruct( privilege=Clusters.AccessControl.Enums.AccessControlEntryPrivilegeEnum.kView, authMode=Clusters.AccessControl.Enums.AccessControlEntryAuthModeEnum.kCase, subjects=[TH3_nodeid], - targets=[Clusters.AccessControl.Structs.AccessControlTargetStruct(endpoint=endpoint)]) + targets=[Clusters.AccessControl.Structs.AccessControlTargetStruct(endpoint=0)]) acl = [TH0_admin_acl, th3_view] await self.write_acl(acl) - self.step(15, endpoint) - await self.read_descriptor_expect_unsupported_access(TH1, endpoint) + self.step(15) + await self.read_descriptor_expect_unsupported_access(TH1) - self.step(16, endpoint) - await self.read_descriptor_expect_unsupported_access(TH2, endpoint) + self.step(16) + await self.read_descriptor_expect_unsupported_access(TH2) - self.step(17, endpoint) - await self.read_descriptor_expect_success(TH3, endpoint) + self.step(17) + await self.read_descriptor_expect_success(TH3) - self.step(18, endpoint) + self.step(18) th12_view = Clusters.AccessControl.Structs.AccessControlEntryStruct( privilege=Clusters.AccessControl.Enums.AccessControlEntryPrivilegeEnum.kView, authMode=Clusters.AccessControl.Enums.AccessControlEntryAuthModeEnum.kCase, subjects=[TH1_nodeid, TH2_nodeid], - targets=[Clusters.AccessControl.Structs.AccessControlTargetStruct(endpoint=endpoint)]) + targets=[Clusters.AccessControl.Structs.AccessControlTargetStruct(endpoint=0)]) acl = [TH0_admin_acl, th12_view] await self.write_acl(acl) - self.step(19, endpoint) - await self.read_descriptor_expect_success(TH1, endpoint) + self.step(19) + await self.read_descriptor_expect_success(TH1) - self.step(20, endpoint) - await self.read_descriptor_expect_success(TH2, endpoint) + self.step(20) + await self.read_descriptor_expect_success(TH2) - self.step(21, endpoint) - await self.read_descriptor_expect_unsupported_access(TH3, endpoint) + self.step(21) + await self.read_descriptor_expect_unsupported_access(TH3) - self.step(22, endpoint) + self.step(22) th13_view = Clusters.AccessControl.Structs.AccessControlEntryStruct( privilege=Clusters.AccessControl.Enums.AccessControlEntryPrivilegeEnum.kView, authMode=Clusters.AccessControl.Enums.AccessControlEntryAuthModeEnum.kCase, subjects=[TH1_nodeid, TH3_nodeid], - targets=[Clusters.AccessControl.Structs.AccessControlTargetStruct(endpoint=endpoint)]) + targets=[Clusters.AccessControl.Structs.AccessControlTargetStruct(endpoint=0)]) acl = [TH0_admin_acl, th13_view] await self.write_acl(acl) - self.step(23, endpoint) - await self.read_descriptor_expect_success(TH1, endpoint) + self.step(23) + await self.read_descriptor_expect_success(TH1) - self.step(24, endpoint) - await self.read_descriptor_expect_unsupported_access(TH2, endpoint) + self.step(24) + await self.read_descriptor_expect_unsupported_access(TH2) - self.step(25, endpoint) - await self.read_descriptor_expect_success(TH3, endpoint) + self.step(25) + await self.read_descriptor_expect_success(TH3) - self.step(26, endpoint) + self.step(26) th23_view = Clusters.AccessControl.Structs.AccessControlEntryStruct( privilege=Clusters.AccessControl.Enums.AccessControlEntryPrivilegeEnum.kView, authMode=Clusters.AccessControl.Enums.AccessControlEntryAuthModeEnum.kCase, subjects=[TH2_nodeid, TH3_nodeid], - targets=[Clusters.AccessControl.Structs.AccessControlTargetStruct(endpoint=endpoint)]) + targets=[Clusters.AccessControl.Structs.AccessControlTargetStruct(endpoint=0)]) acl = [TH0_admin_acl, th23_view] await self.write_acl(acl) - self.step(27, endpoint) - await self.read_descriptor_expect_unsupported_access(TH1, endpoint) + self.step(27) + await self.read_descriptor_expect_unsupported_access(TH1) - self.step(28, endpoint) - await self.read_descriptor_expect_success(TH2, endpoint) + self.step(28) + await self.read_descriptor_expect_success(TH2) - self.step(29, endpoint) - await self.read_descriptor_expect_success(TH3, endpoint) + self.step(29) + await self.read_descriptor_expect_success(TH3) - self.step(30, endpoint) + self.step(30) th123_view = Clusters.AccessControl.Structs.AccessControlEntryStruct( privilege=Clusters.AccessControl.Enums.AccessControlEntryPrivilegeEnum.kView, authMode=Clusters.AccessControl.Enums.AccessControlEntryAuthModeEnum.kCase, subjects=[TH1_nodeid, TH2_nodeid, TH3_nodeid], - targets=[Clusters.AccessControl.Structs.AccessControlTargetStruct(endpoint=endpoint)]) + targets=[Clusters.AccessControl.Structs.AccessControlTargetStruct(endpoint=0)]) acl = [TH0_admin_acl, th123_view] await self.write_acl(acl) - self.step(31, endpoint) - await self.read_descriptor_expect_success(TH1, endpoint) + self.step(31) + await self.read_descriptor_expect_success(TH1) - self.step(32, endpoint) - await self.read_descriptor_expect_success(TH2, endpoint) + self.step(32) + await self.read_descriptor_expect_success(TH2) - self.step(33, endpoint) - await self.read_descriptor_expect_success(TH3, endpoint) + self.step(33) + await self.read_descriptor_expect_success(TH3) - self.step(34, endpoint) + self.step(34) cat1v1_view = Clusters.AccessControl.Structs.AccessControlEntryStruct( privilege=Clusters.AccessControl.Enums.AccessControlEntryPrivilegeEnum.kView, authMode=Clusters.AccessControl.Enums.AccessControlEntryAuthModeEnum.kCase, subjects=[acl_subject(cat1v1)], - targets=[Clusters.AccessControl.Structs.AccessControlTargetStruct(endpoint=endpoint)]) + targets=[Clusters.AccessControl.Structs.AccessControlTargetStruct(endpoint=0)]) acl = [TH0_admin_acl, cat1v1_view] await self.write_acl(acl) - self.step(35, endpoint) - await self.read_descriptor_expect_success(TH1, endpoint) + self.step(35) + await self.read_descriptor_expect_success(TH1) - self.step(36, endpoint) - await self.read_descriptor_expect_success(TH2, endpoint) + self.step(36) + await self.read_descriptor_expect_success(TH2) - self.step(37, endpoint) - await self.read_descriptor_expect_success(TH3, endpoint) + self.step(37) + await self.read_descriptor_expect_success(TH3) - self.step(38, endpoint) + self.step(38) cat1v2_view = Clusters.AccessControl.Structs.AccessControlEntryStruct( privilege=Clusters.AccessControl.Enums.AccessControlEntryPrivilegeEnum.kView, authMode=Clusters.AccessControl.Enums.AccessControlEntryAuthModeEnum.kCase, subjects=[acl_subject(cat1v2)], - targets=[Clusters.AccessControl.Structs.AccessControlTargetStruct(endpoint=endpoint)]) + targets=[Clusters.AccessControl.Structs.AccessControlTargetStruct(endpoint=0)]) acl = [TH0_admin_acl, cat1v2_view] await self.write_acl(acl) - self.step(39, endpoint) - await self.read_descriptor_expect_success(TH1, endpoint) + self.step(39) + await self.read_descriptor_expect_success(TH1) - self.step(40, endpoint) - await self.read_descriptor_expect_success(TH2, endpoint) + self.step(40) + await self.read_descriptor_expect_success(TH2) - self.step(41, endpoint) - await self.read_descriptor_expect_unsupported_access(TH3, endpoint) + self.step(41) + await self.read_descriptor_expect_unsupported_access(TH3) - self.step(42, endpoint) + self.step(42) cat1v3_view = Clusters.AccessControl.Structs.AccessControlEntryStruct( privilege=Clusters.AccessControl.Enums.AccessControlEntryPrivilegeEnum.kView, authMode=Clusters.AccessControl.Enums.AccessControlEntryAuthModeEnum.kCase, subjects=[acl_subject(cat1v3)], - targets=[Clusters.AccessControl.Structs.AccessControlTargetStruct(endpoint=endpoint)]) + targets=[Clusters.AccessControl.Structs.AccessControlTargetStruct(endpoint=0)]) acl = [TH0_admin_acl, cat1v3_view] await self.write_acl(acl) - self.step(43, endpoint) - await self.read_descriptor_expect_success(TH1, endpoint) + self.step(43) + await self.read_descriptor_expect_success(TH1) - self.step(44, endpoint) - await self.read_descriptor_expect_unsupported_access(TH2, endpoint) + self.step(44) + await self.read_descriptor_expect_unsupported_access(TH2) - self.step(45, endpoint) - await self.read_descriptor_expect_unsupported_access(TH3, endpoint) + self.step(45) + await self.read_descriptor_expect_unsupported_access(TH3) - self.step(46, endpoint) + self.step(46) cat2v1_view = Clusters.AccessControl.Structs.AccessControlEntryStruct( privilege=Clusters.AccessControl.Enums.AccessControlEntryPrivilegeEnum.kView, authMode=Clusters.AccessControl.Enums.AccessControlEntryAuthModeEnum.kCase, subjects=[acl_subject(cat2v1)], - targets=[Clusters.AccessControl.Structs.AccessControlTargetStruct(endpoint=endpoint)]) + targets=[Clusters.AccessControl.Structs.AccessControlTargetStruct(endpoint=0)]) acl = [TH0_admin_acl, cat2v1_view] await self.write_acl(acl) - self.step(47, endpoint) - await self.read_descriptor_expect_unsupported_access(TH1, endpoint) + self.step(47) + await self.read_descriptor_expect_unsupported_access(TH1) - self.step(48, endpoint) - await self.read_descriptor_expect_success(TH2, endpoint) + self.step(48) + await self.read_descriptor_expect_success(TH2) - self.step(49, endpoint) - await self.read_descriptor_expect_success(TH3, endpoint) + self.step(49) + await self.read_descriptor_expect_success(TH3) - self.step(50, endpoint) + self.step(50) cat2v2_view = Clusters.AccessControl.Structs.AccessControlEntryStruct( privilege=Clusters.AccessControl.Enums.AccessControlEntryPrivilegeEnum.kView, authMode=Clusters.AccessControl.Enums.AccessControlEntryAuthModeEnum.kCase, subjects=[acl_subject(cat2v2)], - targets=[Clusters.AccessControl.Structs.AccessControlTargetStruct(endpoint=endpoint)]) + targets=[Clusters.AccessControl.Structs.AccessControlTargetStruct(endpoint=0)]) acl = [TH0_admin_acl, cat2v2_view] await self.write_acl(acl) - self.step(51, endpoint) - await self.read_descriptor_expect_unsupported_access(TH1, endpoint) + self.step(51) + await self.read_descriptor_expect_unsupported_access(TH1) - self.step(52, endpoint) - await self.read_descriptor_expect_unsupported_access(TH2, endpoint) + self.step(52) + await self.read_descriptor_expect_unsupported_access(TH2) - self.step(53, endpoint) - await self.read_descriptor_expect_success(TH3, endpoint) + self.step(53) + await self.read_descriptor_expect_success(TH3) - self.step(54, endpoint) + self.step(54) cat2v3_view = Clusters.AccessControl.Structs.AccessControlEntryStruct( privilege=Clusters.AccessControl.Enums.AccessControlEntryPrivilegeEnum.kView, authMode=Clusters.AccessControl.Enums.AccessControlEntryAuthModeEnum.kCase, subjects=[acl_subject(cat2v3)], - targets=[Clusters.AccessControl.Structs.AccessControlTargetStruct(endpoint=endpoint)]) + targets=[Clusters.AccessControl.Structs.AccessControlTargetStruct(endpoint=0)]) acl = [TH0_admin_acl, cat2v3_view] await self.write_acl(acl) - self.step(55, endpoint) - await self.read_descriptor_expect_unsupported_access(TH1, endpoint) + self.step(55) + await self.read_descriptor_expect_unsupported_access(TH1) - self.step(56, endpoint) - await self.read_descriptor_expect_unsupported_access(TH2, endpoint) + self.step(56) + await self.read_descriptor_expect_unsupported_access(TH2) - self.step(57, endpoint) - await self.read_descriptor_expect_unsupported_access(TH3, endpoint) + self.step(57) + await self.read_descriptor_expect_unsupported_access(TH3) self.step(58) diff --git a/src/python_testing/TC_BOOLCFG_2_1.py b/src/python_testing/TC_BOOLCFG_2_1.py index 2e90245f479d3d..2456457ce26ae7 100644 --- a/src/python_testing/TC_BOOLCFG_2_1.py +++ b/src/python_testing/TC_BOOLCFG_2_1.py @@ -81,12 +81,12 @@ async def test_TC_BOOLCFG_2_1(self): self.step(1) attributes = Clusters.BooleanStateConfiguration.Attributes - self.step(2, endpoint) + self.step(2) attribute_list = await self.read_boolcfg_attribute_expect_success(endpoint=endpoint, attribute=attributes.AttributeList) number_of_supported_levels = 0 - self.step(3, endpoint) + self.step(3) if attributes.SupportedSensitivityLevels.attribute_id in attribute_list: number_of_supported_levels = await self.read_boolcfg_attribute_expect_success(endpoint=endpoint, attribute=attributes.SupportedSensitivityLevels) asserts.assert_less_equal(number_of_supported_levels, 10, "SupportedSensitivityLevels attribute is out of range") @@ -94,7 +94,7 @@ async def test_TC_BOOLCFG_2_1(self): else: logging.info("Test step skipped") - self.step(4, endpoint) + self.step(4) if attributes.CurrentSensitivityLevel.attribute_id in attribute_list: current_sensitivity_level_dut = await self.read_boolcfg_attribute_expect_success(endpoint=endpoint, attribute=attributes.CurrentSensitivityLevel) asserts.assert_less_equal(current_sensitivity_level_dut, number_of_supported_levels, @@ -102,7 +102,7 @@ async def test_TC_BOOLCFG_2_1(self): else: logging.info("Test step skipped") - self.step(5, endpoint) + self.step(5) if attributes.DefaultSensitivityLevel.attribute_id in attribute_list: default_sensitivity_level_dut = await self.read_boolcfg_attribute_expect_success(endpoint=endpoint, attribute=attributes.DefaultSensitivityLevel) asserts.assert_less_equal(default_sensitivity_level_dut, number_of_supported_levels, @@ -110,35 +110,35 @@ async def test_TC_BOOLCFG_2_1(self): else: logging.info("Test step skipped") - self.step(6, endpoint) + self.step(6) if attributes.AlarmsActive.attribute_id in attribute_list: alarms_active_dut = await self.read_boolcfg_attribute_expect_success(endpoint=endpoint, attribute=attributes.AlarmsActive) asserts.assert_equal(alarms_active_dut & ~all_alarm_mode_bitmap_bits, 0, "AlarmsActive is not in valid range") else: logging.info("Test step skipped") - self.step(7, endpoint) + self.step(7) if attributes.AlarmsSuppressed.attribute_id in attribute_list: alarms_suppressed_dut = await self.read_boolcfg_attribute_expect_success(endpoint=endpoint, attribute=attributes.AlarmsSuppressed) asserts.assert_equal(alarms_suppressed_dut & ~all_alarm_mode_bitmap_bits, 0, "AlarmsSuppressed is not in valid range") else: logging.info("Test step skipped") - self.step(8, endpoint) + self.step(8) if attributes.AlarmsEnabled.attribute_id in attribute_list: alarms_enabled_dut = await self.read_boolcfg_attribute_expect_success(endpoint=endpoint, attribute=attributes.AlarmsEnabled) asserts.assert_equal(alarms_enabled_dut & ~all_alarm_mode_bitmap_bits, 0, "AlarmsEnabled is not in valid range") else: logging.info("Test step skipped") - self.step(9, endpoint) + self.step(9) if attributes.AlarmsSupported.attribute_id in attribute_list: alarms_supported_dut = await self.read_boolcfg_attribute_expect_success(endpoint=endpoint, attribute=attributes.AlarmsSupported) asserts.assert_equal(alarms_supported_dut & ~all_alarm_mode_bitmap_bits, 0, "AlarmsSupported is not in valid range") else: logging.info("Test step skipped") - self.step(10, endpoint) + self.step(10) if attributes.SensorFault.attribute_id in attribute_list: sensor_fault_dut = await self.read_boolcfg_attribute_expect_success(endpoint=endpoint, attribute=attributes.SensorFault) asserts.assert_equal(sensor_fault_dut & ~all_sensor_fault_bitmap_bits, 0, "SensorFault is not in valid range") diff --git a/src/python_testing/matter_testing_infrastructure/chip/testing/matter_testing.py b/src/python_testing/matter_testing_infrastructure/chip/testing/matter_testing.py index b16d1b42a08b45..0a40b1688d74cf 100644 --- a/src/python_testing/matter_testing_infrastructure/chip/testing/matter_testing.py +++ b/src/python_testing/matter_testing_infrastructure/chip/testing/matter_testing.py @@ -585,9 +585,9 @@ def step_skipped(self, name: str, expression: str): # TODO: Do we really need the expression as a string? We can evaluate this in code very easily logging.info(f'\t\t**** Skipping: {name}') - def step_start(self, name: str, endpoint: int | None = None): - # TODO: The way I'm calling this, the name already includes the step number, but it seems like it might be good to separate these - logging.info(f'\t\t***** Test Step {name} started with endpoint {endpoint} ') + def step_start(self, name: str): + # The way I'm calling this, the name is already includes the step number, but it seems like it might be good to separate these + logging.info(f'\t\t***** Test Step {name}') def step_success(self, logger, logs, duration: int, request): pass @@ -916,7 +916,6 @@ def hex_from_bytes(b: bytes) -> str: class TestStep: test_plan_number: typing.Union[int, str] description: str - endpoint: int | None = None expectation: str = "" is_commissioning: bool = False @@ -1284,9 +1283,8 @@ async def check_test_event_triggers_enabled(self): test_event_enabled = await self.read_single_attribute_check_success(endpoint=0, cluster=cluster, attribute=full_attr) asserts.assert_equal(test_event_enabled, True, "TestEventTriggersEnabled is False") - def print_step(self, stepnum: typing.Union[int, str], title: str, endpoint: int | None = None) -> None: - endpoint_info = f" with endpoint {endpoint}" if endpoint is not None else "" - logging.info(f'***** Test Step {stepnum} : {title}{endpoint_info}') + def print_step(self, stepnum: typing.Union[int, str], title: str) -> None: + logging.info(f'***** Test Step {stepnum} : {title}') def record_error(self, test_name: str, location: ProblemLocation, problem: str, spec_location: str = ""): self.problems.append(ProblemNotice(test_name, location, ProblemSeverity.ERROR, problem, spec_location)) @@ -1455,7 +1453,7 @@ def skip_all_remaining_steps(self, starting_step_number): for step in remaining: self.skip_step(step.test_plan_number) - def step(self, step: typing.Union[int, str], endpoint: Optional[int] = None): + def step(self, step: typing.Union[int, str]): test_name = self.current_test_info.name steps = self.get_test_steps(test_name) @@ -1464,7 +1462,7 @@ def step(self, step: typing.Union[int, str], endpoint: Optional[int] = None): asserts.fail(f'Unexpected test step: {step} - steps not called in order, or step does not exist') current_step = steps[self.current_step_index] - self.print_step(step, current_step.description, endpoint) + self.print_step(step, current_step.description) if self.runner_hook: # If we've reached the next step with no assertion and the step wasn't skipped, it passed @@ -1473,14 +1471,12 @@ def step(self, step: typing.Union[int, str], endpoint: Optional[int] = None): step_duration = (datetime.now(timezone.utc) - self.step_start_time) / timedelta(microseconds=1) self.runner_hook.step_success(logger=None, logs=None, duration=step_duration, request=None) - current_step.endpoint = endpoint - # TODO: it seems like the step start should take a number and a name name = f'{step} : {current_step.description}' + self.runner_hook.step_start(name=name) - self.runner_hook.step_start(name=name, endpoint=current_step.endpoint) self.step_start_time = datetime.now(tz=timezone.utc) - self.current_step_index += 1 + self.current_step_index = self.current_step_index + 1 self.step_skipped = False def get_setup_payload_info(self) -> List[SetupPayloadInfo]: diff --git a/src/python_testing/test_testing/TestDecorators.py b/src/python_testing/test_testing/TestDecorators.py index ce32518b71c7c3..c4851eaee56c35 100644 --- a/src/python_testing/test_testing/TestDecorators.py +++ b/src/python_testing/test_testing/TestDecorators.py @@ -76,7 +76,7 @@ def test_stop(self, exception: Exception, duration: int): def step_skipped(self, name: str, expression: str): pass - def step_start(self, name: str, endpoint: Optional[int] = None): + def step_start(self, name: str): pass def step_success(self, logger, logs, duration: int, request): From f32d00599fcd6103734329731e60b95702944d54 Mon Sep 17 00:00:00 2001 From: bhmanda-silabs <107180296+bhmanda-silabs@users.noreply.github.com> Date: Wed, 23 Oct 2024 02:39:16 +0530 Subject: [PATCH 071/149] [Silabs] Update WiseConnect-wifi-bt-sdk to 2.10.3 for RS9116 (#36117) * Updated wiseconnect pointer to 2.10.3 and added changes for wpa_wpa2_mixed security type for rs9116 board * updated example-efr32.yaml and release_artifacts.yaml with docker build version * Updated docker version in release_artifacts,smoke_test.yaml and .gitmodules with 2.10.3 --- .github/workflows/examples-efr32.yaml | 2 +- .github/workflows/release_artifacts.yaml | 2 +- .gitmodules | 2 +- examples/platform/silabs/efr32/rs911x/rsi_if.cpp | 4 ++++ integrations/cloudbuild/smoke-test.yaml | 14 +++++++------- src/platform/silabs/wifi/wfx_host_events.h | 13 +++++++------ third_party/silabs/wiseconnect-wifi-bt-sdk | 2 +- 7 files changed, 22 insertions(+), 17 deletions(-) diff --git a/.github/workflows/examples-efr32.yaml b/.github/workflows/examples-efr32.yaml index 9a483ab5ec4c9e..d9df0bca21637f 100644 --- a/.github/workflows/examples-efr32.yaml +++ b/.github/workflows/examples-efr32.yaml @@ -41,7 +41,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-efr32:83 + image: ghcr.io/project-chip/chip-build-efr32:84 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" steps: diff --git a/.github/workflows/release_artifacts.yaml b/.github/workflows/release_artifacts.yaml index 45ef34c5ee5aae..af90dc316d0f4a 100644 --- a/.github/workflows/release_artifacts.yaml +++ b/.github/workflows/release_artifacts.yaml @@ -64,7 +64,7 @@ jobs: runs-on: ubuntu-latest container: - image: ghcr.io/project-chip/chip-build-efr32:83 + image: ghcr.io/project-chip/chip-build-efr32:84 steps: - name: Checkout uses: actions/checkout@v4 diff --git a/.gitmodules b/.gitmodules index c26ee8f792c1c3..3f50d3079d4e03 100644 --- a/.gitmodules +++ b/.gitmodules @@ -218,7 +218,7 @@ [submodule "third_party/silabs/wiseconnect-wifi-bt-sdk"] path = third_party/silabs/wiseconnect-wifi-bt-sdk url = https://github.com/SiliconLabs/wiseconnect-wifi-bt-sdk.git - branch = 2.10.0 + branch = 2.10.3 platforms = silabs [submodule "third_party/silabs/wifi_sdk"] path = third_party/silabs/wifi_sdk diff --git a/examples/platform/silabs/efr32/rs911x/rsi_if.cpp b/examples/platform/silabs/efr32/rs911x/rsi_if.cpp index 4e9c40974c40e1..78d13498efa5ab 100644 --- a/examples/platform/silabs/efr32/rs911x/rsi_if.cpp +++ b/examples/platform/silabs/efr32/rs911x/rsi_if.cpp @@ -506,6 +506,9 @@ static void wfx_rsi_save_ap_info(void) // translation case SME_WPA2_ENTERPRISE: wfx_rsi.sec.security = WFX_SEC_WPA2; break; + case SME_WPA_WPA2_MIXED_MODE: + wfx_rsi.sec.security = WFX_SEC_WPA_WPA2_MIXED; + break; case SME_WEP: wfx_rsi.sec.security = WFX_SEC_WEP; break; @@ -551,6 +554,7 @@ static void wfx_rsi_do_join(void) break; case WFX_SEC_WPA: case WFX_SEC_WPA2: + case WFX_SEC_WPA_WPA2_MIXED: connect_security_mode = RSI_WPA_WPA2_MIXED; break; #if WIFI_ENABLE_SECURITY_WPA3_TRANSITION diff --git a/integrations/cloudbuild/smoke-test.yaml b/integrations/cloudbuild/smoke-test.yaml index b8c44cfa30c565..24a3029d2fe2f8 100644 --- a/integrations/cloudbuild/smoke-test.yaml +++ b/integrations/cloudbuild/smoke-test.yaml @@ -1,5 +1,5 @@ steps: - - name: "ghcr.io/project-chip/chip-build-vscode:83" + - name: "ghcr.io/project-chip/chip-build-vscode:84" entrypoint: "bash" args: - "-c" @@ -7,7 +7,7 @@ steps: git config --global --add safe.directory "*" python scripts/checkout_submodules.py --shallow --recursive --platform esp32 nrfconnect silabs linux android id: Submodules - - name: "ghcr.io/project-chip/chip-build-vscode:83" + - name: "ghcr.io/project-chip/chip-build-vscode:84" # NOTE: silabs boostrap is NOT done with the rest as it requests a conflicting # jinja2 version (asks for 3.1.3 when constraints.txt asks for 3.0.3) env: @@ -24,7 +24,7 @@ steps: path: /pwenv timeout: 900s - - name: "ghcr.io/project-chip/chip-build-vscode:83" + - name: "ghcr.io/project-chip/chip-build-vscode:84" id: ESP32 env: - PW_ENVIRONMENT_ROOT=/pwenv @@ -45,7 +45,7 @@ steps: volumes: - name: pwenv path: /pwenv - - name: "ghcr.io/project-chip/chip-build-vscode:83" + - name: "ghcr.io/project-chip/chip-build-vscode:84" id: NRFConnect env: - PW_ENVIRONMENT_ROOT=/pwenv @@ -66,7 +66,7 @@ steps: - name: pwenv path: /pwenv - - name: "ghcr.io/project-chip/chip-build-vscode:83" + - name: "ghcr.io/project-chip/chip-build-vscode:84" id: EFR32 env: - PW_ENVIRONMENT_ROOT=/pwenv @@ -88,7 +88,7 @@ steps: - name: pwenv path: /pwenv - - name: "ghcr.io/project-chip/chip-build-vscode:83" + - name: "ghcr.io/project-chip/chip-build-vscode:84" id: Linux env: - PW_ENVIRONMENT_ROOT=/pwenv @@ -141,7 +141,7 @@ steps: - name: pwenv path: /pwenv - - name: "ghcr.io/project-chip/chip-build-vscode:83" + - name: "ghcr.io/project-chip/chip-build-vscode:84" id: Android env: - PW_ENVIRONMENT_ROOT=/pwenv diff --git a/src/platform/silabs/wifi/wfx_host_events.h b/src/platform/silabs/wifi/wfx_host_events.h index de1759951c86a1..3bd973467bf915 100644 --- a/src/platform/silabs/wifi/wfx_host_events.h +++ b/src/platform/silabs/wifi/wfx_host_events.h @@ -147,12 +147,13 @@ typedef enum /* Note that these are same as RSI_security */ typedef enum { - WFX_SEC_UNSPECIFIED = 0, - WFX_SEC_NONE = 1, - WFX_SEC_WEP = 2, - WFX_SEC_WPA = 3, - WFX_SEC_WPA2 = 4, - WFX_SEC_WPA3 = 5, + WFX_SEC_UNSPECIFIED = 0, + WFX_SEC_NONE = 1, + WFX_SEC_WEP = 2, + WFX_SEC_WPA = 3, + WFX_SEC_WPA2 = 4, + WFX_SEC_WPA3 = 5, + WFX_SEC_WPA_WPA2_MIXED = 6, } wfx_sec_t; typedef struct diff --git a/third_party/silabs/wiseconnect-wifi-bt-sdk b/third_party/silabs/wiseconnect-wifi-bt-sdk index f94b83d050fe62..b6d6cb552beb4e 160000 --- a/third_party/silabs/wiseconnect-wifi-bt-sdk +++ b/third_party/silabs/wiseconnect-wifi-bt-sdk @@ -1 +1 @@ -Subproject commit f94b83d050fe6200c5ec2dacfafa2edc92ad5ef3 +Subproject commit b6d6cb552beb4ecb6e690e0db4c9d374f8ba1b15 From e36bde7fea73abc8503cbb57a71ee05f22388ebe Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Tue, 22 Oct 2024 17:57:32 -0400 Subject: [PATCH 072/149] Add an MTRDevice method for checking whether a data-value satisfies some expectation. (#36151) --- src/darwin/Framework/CHIP/MTRDevice.mm | 162 ++++++++ .../CHIP/MTRDeviceDataValueDictionary.h | 3 + .../Framework/CHIP/MTRDevice_Concrete.mm | 22 +- .../Framework/CHIP/MTRDevice_Internal.h | 5 + .../Framework/CHIPTests/MTRDeviceTests.m | 352 ++++++++++++++++++ .../TestHelpers/MTRTestDeclarations.h | 1 - 6 files changed, 525 insertions(+), 20 deletions(-) diff --git a/src/darwin/Framework/CHIP/MTRDevice.mm b/src/darwin/Framework/CHIP/MTRDevice.mm index e0154fdb8934e6..8e379980578f58 100644 --- a/src/darwin/Framework/CHIP/MTRDevice.mm +++ b/src/darwin/Framework/CHIP/MTRDevice.mm @@ -539,6 +539,8 @@ - (BOOL)deviceCachePrimed return NO; } +#pragma mark - Suspend/resume management + - (void)controllerSuspended { // Nothing to do for now. @@ -549,6 +551,166 @@ - (void)controllerResumed // Nothing to do for now. } +#pragma mark - Value comparisons + +- (BOOL)_attributeDataValue:(MTRDeviceDataValueDictionary)one isEqualToDataValue:(MTRDeviceDataValueDictionary)theOther +{ + // Sanity check for nil cases + if (!one && !theOther) { + MTR_LOG_ERROR("%@ attribute data-value comparison does not expect comparing two nil dictionaries", self); + return YES; + } + if (!one || !theOther) { + // Comparing against nil is expected, and should return NO quietly + return NO; + } + + // Attribute data-value dictionaries are equal if type and value are equal, and specifically, this should return true if values are both nil + return [one[MTRTypeKey] isEqual:theOther[MTRTypeKey]] && ((one[MTRValueKey] == theOther[MTRValueKey]) || [one[MTRValueKey] isEqual:theOther[MTRValueKey]]); +} + +// _attributeDataValue:satisfiesExpectedDataValue: checks whether the newly +// received attribute data value satisfies the expectation we have. +// +// For now, a value is considered to satisfy the expectation if it's equal to +// the expected value, though we allow the fields of structs to be in a +// different order than expected: while in theory the spec does require a +// specific ordering for struct fields, in practice we should not force certain +// API consumers to deal with knowing what that ordering is. +// +// Things to consider for future: +// +// 1) Should a value that has _extra_ fields in a struct compared to the expected +// value be considered as satisfying the expectation? Arguably, yes. +// +// 2) Should lists actually enforce order (as now), or should they allow +// reordering entries? +// +// 3) For fabric-scoped lists, should we have a way to check for just "our +// fabric's" entries? +- (BOOL)_attributeDataValue:(MTRDeviceDataValueDictionary)observed satisfiesValueExpectation:(MTRDeviceDataValueDictionary)expected +{ + // Sanity check for nil cases (which really should not happen!) + if (!observed && !expected) { + MTR_LOG_ERROR("%@ observed to expected attribute data-value comparison does not expect comparing two nil dictionaries", self); + return YES; + } + + if (!observed || !expected) { + // Again, not expected here. But clearly the expectation is not really + // satisfied, in some sense. + MTR_LOG_ERROR("@ observed to expected attribute data-value comparison does not expect a nil %s", observed ? "expected" : "observed"); + return NO; + } + + if (![observed[MTRTypeKey] isEqual:expected[MTRTypeKey]]) { + // Different types, does not satisfy expectation. + return NO; + } + + if ([MTRArrayValueType isEqual:expected[MTRTypeKey]]) { + // For array-values, check that sizes are same and entries satisfy expectations. + if (![observed[MTRValueKey] isKindOfClass:NSArray.class] || ![expected[MTRValueKey] isKindOfClass:NSArray.class]) { + // Malformed data, just claim expectation is not satisfied. + MTR_LOG_ERROR("%@ at least one of observed and expected value is not an NSArrray: %@, %@", self, observed, expected); + return NO; + } + + NSArray *> * observedArray = observed[MTRValueKey]; + NSArray *> * expectedArray = expected[MTRValueKey]; + + if (observedArray.count != expectedArray.count) { + return NO; + } + + for (NSUInteger i = 0; i < observedArray.count; ++i) { + NSDictionary * observedEntry = observedArray[i]; + NSDictionary * expectedEntry = expectedArray[i]; + + if (![observedEntry isKindOfClass:NSDictionary.class] || ![expectedEntry isKindOfClass:NSDictionary.class]) { + MTR_LOG_ERROR("%@ expected or observed array-value contains entries that are not NSDictionary: %@, %@", self, observedEntry, expectedEntry); + return NO; + } + + if (![self _attributeDataValue:observedEntry[MTRDataKey] satisfiesValueExpectation:expectedEntry[MTRDataKey]]) { + return NO; + } + } + + return YES; + } + + if (![MTRStructureValueType isEqual:expected[MTRTypeKey]]) { + // For everything except arrays and structs, expectation is satisfied + // exactly when the values are equal. + return [self _attributeDataValue:observed isEqualToDataValue:expected]; + } + + // Now we have two structure-values. Make sure they have the same number of fields + // in them. + if (![observed[MTRValueKey] isKindOfClass:NSArray.class] || ![expected[MTRValueKey] isKindOfClass:NSArray.class]) { + // Malformed data, just claim not equivalent. + MTR_LOG_ERROR("%@ at least one of observed and expected value is not an NSArrray: %@, %@", self, observed, expected); + return NO; + } + + NSArray *> * observedArray = observed[MTRValueKey]; + NSArray *> * expectedArray = expected[MTRValueKey]; + + if (observedArray.count != expectedArray.count) { + return NO; + } + + for (NSDictionary * expectedField in expectedArray) { + if (![expectedField[MTRContextTagKey] isKindOfClass:NSNumber.class] || ![expectedField[MTRDataKey] isKindOfClass:NSDictionary.class]) { + MTR_LOG_ERROR("%@ expected structure-value contains invalid field %@", self, expectedField); + return NO; + } + + NSNumber * expectedContextTag = expectedField[MTRContextTagKey]; + + // Make sure it's present in the other array. In practice, these are + // pretty small arrays, so the O(N^2) behavior here is ok. + BOOL found = NO; + for (NSDictionary * observedField in observedArray) { + if (![observedField[MTRContextTagKey] isKindOfClass:NSNumber.class] || ![observedField[MTRDataKey] isKindOfClass:NSDictionary.class]) { + MTR_LOG_ERROR("%@ observed structure-value contains invalid field %@", self, observedField); + return NO; + } + + NSNumber * observedContextTag = observedField[MTRContextTagKey]; + if ([expectedContextTag isEqual:observedContextTag]) { + found = YES; + + // Compare the data. + if (![self _attributeDataValue:observedField[MTRDataKey] satisfiesValueExpectation:expectedField[MTRDataKey]]) { + return NO; + } + + // Found a match for the context tag, stop looking. + break; + } + } + + if (!found) { + // Context tag present in expected but not observed. + return NO; + } + } + + // All entries in the first field array matched entries in the second field + // array. Since the lengths are equal, the two arrays must match, as long + // as all the context tags listed are distinct. If someone produces invalid + // TLV with the same context tag set in it multiple times, this method could + // claim two structure-values are equivalent when the first has two fields + // with context tag N and the second has a field with context tag N and + // another field with context tag M. That should be ok, in practice, but if + // we discover it's not we will need a better algorithm here. It's not + // clear what "equivalent" should mean for such malformed TLV, expecially if + // the same context tag maps to different values in one of the structs. + return YES; +} + @end /* BEGIN DRAGONS: Note methods here cannot be renamed, and are used by private callers, do not rename, remove or modify behavior here */ diff --git a/src/darwin/Framework/CHIP/MTRDeviceDataValueDictionary.h b/src/darwin/Framework/CHIP/MTRDeviceDataValueDictionary.h index 34e46b7ccd7ef3..53a6b2e6f914b7 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceDataValueDictionary.h +++ b/src/darwin/Framework/CHIP/MTRDeviceDataValueDictionary.h @@ -18,6 +18,9 @@ NS_ASSUME_NONNULL_BEGIN +/** + * A data-value as defined in MTRBaseDevice.h. + */ typedef NSDictionary * MTRDeviceDataValueDictionary; NS_ASSUME_NONNULL_END diff --git a/src/darwin/Framework/CHIP/MTRDevice_Concrete.mm b/src/darwin/Framework/CHIP/MTRDevice_Concrete.mm index 7276a5b5342eb1..2423e4e8769c45 100644 --- a/src/darwin/Framework/CHIP/MTRDevice_Concrete.mm +++ b/src/darwin/Framework/CHIP/MTRDevice_Concrete.mm @@ -3307,22 +3307,6 @@ - (void)_performScheduledExpirationCheck return nil; } -- (BOOL)_attributeDataValue:(NSDictionary *)one isEqualToDataValue:(NSDictionary *)theOther -{ - // Sanity check for nil cases - if (!one && !theOther) { - MTR_LOG_ERROR("%@ attribute data-value comparison does not expect comparing two nil dictionaries", self); - return YES; - } - if (!one || !theOther) { - // Comparing against nil is expected, and should return NO quietly - return NO; - } - - // Attribute data-value dictionaries are equal if type and value are equal, and specifically, this should return true if values are both nil - return [one[MTRTypeKey] isEqual:theOther[MTRTypeKey]] && ((one[MTRValueKey] == theOther[MTRValueKey]) || [one[MTRValueKey] isEqual:theOther[MTRValueKey]]); -} - // Utility to return data value dictionary without data version - (NSDictionary *)_dataValueWithoutDataVersion:(NSDictionary *)attributeValue { @@ -3538,9 +3522,9 @@ - (NSArray *)_getAttributesToReportWithReportedValues:(NSArray * attributeResponseValue in reportedAttributeValues) { MTRAttributePath * attributePath = attributeResponseValue[MTRAttributePathKey]; - NSDictionary * attributeDataValue = attributeResponseValue[MTRDataKey]; - NSError * attributeError = attributeResponseValue[MTRErrorKey]; - NSDictionary * previousValue; + MTRDeviceDataValueDictionary _Nullable attributeDataValue = attributeResponseValue[MTRDataKey]; + NSError * _Nullable attributeError = attributeResponseValue[MTRErrorKey]; + MTRDeviceDataValueDictionary _Nullable previousValue; // sanity check either data value or error must exist if (!attributeDataValue && !attributeError) { diff --git a/src/darwin/Framework/CHIP/MTRDevice_Internal.h b/src/darwin/Framework/CHIP/MTRDevice_Internal.h index f954979f131084..df4a8265538dfe 100644 --- a/src/darwin/Framework/CHIP/MTRDevice_Internal.h +++ b/src/darwin/Framework/CHIP/MTRDevice_Internal.h @@ -22,6 +22,7 @@ #import "MTRAsyncWorkQueue.h" #import "MTRDefines_Internal.h" +#import "MTRDeviceDataValueDictionary.h" #import "MTRDeviceStorageBehaviorConfiguration_Internal.h" NS_ASSUME_NONNULL_BEGIN @@ -164,6 +165,10 @@ MTR_DIRECT_MEMBERS - (void)controllerSuspended; - (void)controllerResumed; +// Methods for comparing attribute data values. +- (BOOL)_attributeDataValue:(MTRDeviceDataValueDictionary)one isEqualToDataValue:(MTRDeviceDataValueDictionary)theOther; +- (BOOL)_attributeDataValue:(MTRDeviceDataValueDictionary)observed satisfiesValueExpectation:(MTRDeviceDataValueDictionary)expected; + @end #pragma mark - MTRDevice internal state monitoring diff --git a/src/darwin/Framework/CHIPTests/MTRDeviceTests.m b/src/darwin/Framework/CHIPTests/MTRDeviceTests.m index 5fb3549a49216a..9d33649057ddb1 100644 --- a/src/darwin/Framework/CHIPTests/MTRDeviceTests.m +++ b/src/darwin/Framework/CHIPTests/MTRDeviceTests.m @@ -4467,6 +4467,358 @@ - (void)test039_GetAllAttributesReport } } +- (void)test040_AttributeValueExpectationSatisfaction +{ + __auto_type * device = [MTRDevice deviceWithNodeID:kDeviceId deviceController:sController]; + + __auto_type * testData = @[ + @{ + @"expected" : @ { + MTRTypeKey : MTRUnsignedIntegerValueType, + MTRValueKey : @(7), + }, + @"observed" : @ { + MTRTypeKey : MTRUnsignedIntegerValueType, + MTRValueKey : @(7) + }, + // Equal unsigned integer should satisfy expectation. + @"expectedComparison" : @(YES), + }, + @{ + @"expected" : @ { + MTRTypeKey : MTRUnsignedIntegerValueType, + MTRValueKey : @(7), + }, + @"observed" : @ { + MTRTypeKey : MTRUnsignedIntegerValueType, + MTRValueKey : @(9), + }, + // Unequal unsigned integer should not satisfy expectation + @"expectedComparison" : @(NO), + }, + @{ + @"expected" : @ { + MTRTypeKey : MTRUnsignedIntegerValueType, + MTRValueKey : @(7), + }, + @"observed" : @ { + MTRTypeKey : MTRSignedIntegerValueType, + MTRValueKey : @(7), + }, + // A signed integer does not satisfy expectation for an unsigned integer. + @"expectedComparison" : @(NO), + }, + @{ + @"expected" : @ { + MTRTypeKey : MTRNullValueType, + }, + @"observed" : @ { + MTRTypeKey : MTRNullValueType, + }, + // Null satisfies expectation for null. + @"expectedComparison" : @(YES), + }, + @{ + @"expected" : @ { + MTRTypeKey : MTRArrayValueType, + MTRValueKey : @[ + @{ + MTRDataKey : @ { + MTRTypeKey : MTRUnsignedIntegerValueType, + MTRValueKey : @(5), + } + }, + @{ + MTRDataKey : @ { + MTRTypeKey : MTRUnsignedIntegerValueType, + MTRValueKey : @(6), + } + }, + ], + }, + @"observed" : @ { + MTRTypeKey : MTRArrayValueType, + MTRValueKey : @[ + @{ + MTRDataKey : @ { + MTRTypeKey : MTRUnsignedIntegerValueType, + MTRValueKey : @(5), + } + }, + @{ + MTRDataKey : @ { + MTRTypeKey : MTRUnsignedIntegerValueType, + MTRValueKey : @(6), + } + }, + @{ + MTRDataKey : @ { + MTRTypeKey : MTRUnsignedIntegerValueType, + MTRValueKey : @(7), + } + }, + ], + }, + // A longer list does not satisfy expectation for a shorter array. + @"expectedComparison" : @(NO), + }, + @{ + @"expected" : @ { + MTRTypeKey : MTRArrayValueType, + MTRValueKey : @[ + @{ + MTRDataKey : @ { + MTRTypeKey : MTRUnsignedIntegerValueType, + MTRValueKey : @(5), + } + }, + @{ + MTRDataKey : @ { + MTRTypeKey : MTRUnsignedIntegerValueType, + MTRValueKey : @(6), + } + }, + @{ + MTRDataKey : @ { + MTRTypeKey : MTRUnsignedIntegerValueType, + MTRValueKey : @(7), + } + }, + ], + }, + @"observed" : @ { + MTRTypeKey : MTRArrayValueType, + MTRValueKey : @[ + @{ + MTRDataKey : @ { + MTRTypeKey : MTRUnsignedIntegerValueType, + MTRValueKey : @(5), + } + }, + @{ + MTRDataKey : @ { + MTRTypeKey : MTRUnsignedIntegerValueType, + MTRValueKey : @(6), + } + }, + ], + }, + // A shorter list does not satisfy expectation for a longer array. + @"expectedComparison" : @(NO), + }, + @{ + @"expected" : @ { + MTRTypeKey : MTRArrayValueType, + MTRValueKey : @[ + @{ + MTRDataKey : @ { + MTRTypeKey : MTRUnsignedIntegerValueType, + MTRValueKey : @(5), + } + }, + @{ + MTRDataKey : @ { + MTRTypeKey : MTRUnsignedIntegerValueType, + MTRValueKey : @(6), + } + }, + ], + }, + @"observed" : @ { + MTRTypeKey : MTRArrayValueType, + MTRValueKey : @[ + @{ + MTRDataKey : @ { + MTRTypeKey : MTRUnsignedIntegerValueType, + MTRValueKey : @(5), + } + }, + @{ + MTRDataKey : @ { + MTRTypeKey : MTRUnsignedIntegerValueType, + MTRValueKey : @(6), + } + }, + ], + }, + // An observed array identical to an expected one satisfies the expectation. + @"expectedComparison" : @(YES), + }, + @{ + @"expected" : @ { + MTRTypeKey : MTRArrayValueType, + MTRValueKey : @[ + @{ + MTRDataKey : @ { + MTRTypeKey : MTRUnsignedIntegerValueType, + MTRValueKey : @(5), + } + }, + @{ + MTRDataKey : @ { + MTRTypeKey : MTRUnsignedIntegerValueType, + MTRValueKey : @(6), + } + }, + ], + }, + @"observed" : @ { + MTRTypeKey : MTRArrayValueType, + MTRValueKey : @[ + @{ + MTRDataKey : @ { + MTRTypeKey : MTRUnsignedIntegerValueType, + MTRValueKey : @(6), + } + }, + @{ + MTRDataKey : @ { + MTRTypeKey : MTRUnsignedIntegerValueType, + MTRValueKey : @(5), + } + }, + ], + }, + // An array with entries in a different order does not satisfy the expectation. + @"expectedComparison" : @(NO), + }, + @{ + @"expected" : @ { + MTRTypeKey : MTRStructureValueType, + MTRValueKey : @[ + @{ + MTRContextTagKey : @(1), + MTRDataKey : @ { + MTRTypeKey : MTRUnsignedIntegerValueType, + MTRValueKey : @(6), + }, + }, + @{ + MTRContextTagKey : @(2), + MTRDataKey : @ { + MTRTypeKey : MTRUTF8StringValueType, + MTRValueKey : @("abc"), + }, + }, + ], + }, + @"observed" : @ { + MTRTypeKey : MTRStructureValueType, + MTRValueKey : @[ + @{ + MTRContextTagKey : @(1), + MTRDataKey : @ { + MTRTypeKey : MTRUnsignedIntegerValueType, + MTRValueKey : @(6), + }, + }, + @{ + MTRContextTagKey : @(2), + MTRDataKey : @ { + MTRTypeKey : MTRUTF8StringValueType, + MTRValueKey : @("abc"), + }, + }, + ], + }, + // A struct that has the same fields in the same order satisfiess the + // expectation. + @"expectedComparison" : @(YES), + }, + @{ + @"expected" : @ { + MTRTypeKey : MTRStructureValueType, + MTRValueKey : @[ + @{ + MTRContextTagKey : @(1), + MTRDataKey : @ { + MTRTypeKey : MTRUnsignedIntegerValueType, + MTRValueKey : @(6), + }, + }, + @{ + MTRContextTagKey : @(2), + MTRDataKey : @ { + MTRTypeKey : MTRUTF8StringValueType, + MTRValueKey : @("abc"), + }, + }, + ], + }, + @"observed" : @ { + MTRTypeKey : MTRStructureValueType, + MTRValueKey : @[ + @{ + MTRContextTagKey : @(1), + MTRDataKey : @ { + MTRTypeKey : MTRUnsignedIntegerValueType, + MTRValueKey : @(6), + }, + }, + @{ + MTRContextTagKey : @(2), + MTRDataKey : @ { + MTRTypeKey : MTRUTF8StringValueType, + MTRValueKey : @("abcd"), + }, + }, + ], + }, + // A struct that has different fields in the same order does not + // satisfy the expectation. + @"expectedComparison" : @(NO), + }, + @{ + @"expected" : @ { + MTRTypeKey : MTRStructureValueType, + MTRValueKey : @[ + @{ + MTRContextTagKey : @(1), + MTRDataKey : @ { + MTRTypeKey : MTRUnsignedIntegerValueType, + MTRValueKey : @(6), + }, + }, + @{ + MTRContextTagKey : @(2), + MTRDataKey : @ { + MTRTypeKey : MTRUTF8StringValueType, + MTRValueKey : @("abc"), + }, + }, + ], + }, + @"observed" : @ { + MTRTypeKey : MTRStructureValueType, + MTRValueKey : @[ + @{ + MTRContextTagKey : @(2), + MTRDataKey : @ { + MTRTypeKey : MTRUTF8StringValueType, + MTRValueKey : @("abc"), + }, + }, + @{ + MTRContextTagKey : @(1), + MTRDataKey : @ { + MTRTypeKey : MTRUnsignedIntegerValueType, + MTRValueKey : @(6), + }, + }, + ], + }, + // A struct that has the same fields in a different order satisfies + // the expectation. + @"expectedComparison" : @(YES), + }, + ]; + + for (NSDictionary * test in testData) { + XCTAssertEqual([device _attributeDataValue:test[@"observed"] satisfiesValueExpectation:test[@"expected"]], [test[@"expectedComparison"] boolValue], + "observed: %@, expected: %@", test[@"observed"], test[@"expected"]); + } +} + @end @interface MTRDeviceEncoderTests : XCTestCase diff --git a/src/darwin/Framework/CHIPTests/TestHelpers/MTRTestDeclarations.h b/src/darwin/Framework/CHIPTests/TestHelpers/MTRTestDeclarations.h index 74a7dc280b1216..b00507d665a9f0 100644 --- a/src/darwin/Framework/CHIPTests/TestHelpers/MTRTestDeclarations.h +++ b/src/darwin/Framework/CHIPTests/TestHelpers/MTRTestDeclarations.h @@ -49,7 +49,6 @@ NS_ASSUME_NONNULL_BEGIN @end @interface MTRDevice (Test) -- (BOOL)_attributeDataValue:(NSDictionary *)one isEqualToDataValue:(NSDictionary *)theOther; - (NSMutableArray *)arrayOfNumbersFromAttributeValue:(MTRDeviceDataValueDictionary)dataDictionary; - (void)setStorageBehaviorConfiguration:(MTRDeviceStorageBehaviorConfiguration *)storageBehaviorConfiguration; @end From ccaa0ed1409460709cb8b49238db273ef3cee922 Mon Sep 17 00:00:00 2001 From: Yufeng Wang Date: Tue, 22 Oct 2024 16:39:55 -0700 Subject: [PATCH 073/149] Add fabric-sync ad vscode debug target (#36197) --- .vscode/launch.json | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/.vscode/launch.json b/.vscode/launch.json index 898defc9c60fe1..fc821c76eb802c 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -419,6 +419,14 @@ "cwd": "${workspaceFolder}" }, + { + "name": "Fabric Sync (Linux)", + "type": "lldb", + "request": "launch", + "program": "${workspaceFolder}/out/debug/standalone/fabric-sync", + "cwd": "${workspaceFolder}" + }, + { "name": "OTA Requestor App (Linux)", "type": "lldb", From b1277405bc754b6c17a1c4f4be03d7433d0470d1 Mon Sep 17 00:00:00 2001 From: Pradip De Date: Tue, 22 Oct 2024 18:04:14 -0700 Subject: [PATCH 074/149] Camera AVStreamMgmt xml updates (#36133) * Incorporate Spec modifications into the Camera AVStreamManagement Cluster xml. Name changes to Max content buffer size and On screen display names. Adjust constraints for Min and Max fragment len. * Corresponding ZAP Autogen code changes. --- .../camera-av-stream-management-cluster.xml | 22 +++++------ .../data_model/controller-clusters.matter | 4 +- .../chip/devicecontroller/ChipClusters.java | 14 +++---- .../devicecontroller/ClusterIDMapping.java | 2 +- .../devicecontroller/ClusterReadMapping.java | 10 ++--- .../CameraAvStreamManagementCluster.kt | 8 ++-- .../CHIPAttributeTLVValueDecoder.cpp | 4 +- .../python/chip/clusters/CHIPClusters.py | 2 +- .../python/chip/clusters/Objects.py | 6 +-- .../MTRAttributeSpecifiedCheck.mm | 2 +- .../MTRAttributeTLVValueDecoder.mm | 4 +- .../CHIP/zap-generated/MTRBaseClusters.h | 6 +-- .../CHIP/zap-generated/MTRBaseClusters.mm | 12 +++--- .../CHIP/zap-generated/MTRClusterConstants.h | 2 +- .../CHIP/zap-generated/MTRClusterNames.mm | 4 +- .../CHIP/zap-generated/MTRClusters.h | 2 +- .../CHIP/zap-generated/MTRClusters.mm | 4 +- .../zap-generated/attributes/Accessors.cpp | 4 +- .../zap-generated/attributes/Accessors.h | 4 +- .../zap-generated/cluster-objects.cpp | 4 +- .../zap-generated/cluster-objects.h | 8 ++-- .../app-common/zap-generated/ids/Attributes.h | 4 +- .../zap-generated/cluster/Commands.h | 10 ++--- .../cluster/logging/DataModelLogger.cpp | 4 +- .../cluster/logging/EntryToText.cpp | 4 +- .../zap-generated/cluster/Commands.h | 38 +++++++++---------- 26 files changed, 94 insertions(+), 94 deletions(-) diff --git a/src/app/zap-templates/zcl/data-model/chip/camera-av-stream-management-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/camera-av-stream-management-cluster.xml index 463aa6af03f865..5cbf1d28ec89d3 100644 --- a/src/app/zap-templates/zcl/data-model/chip/camera-av-stream-management-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/camera-av-stream-management-cluster.xml @@ -18,7 +18,7 @@ limitations under the License. XML generated by Alchemy; DO NOT EDIT. Source: src/app_clusters/CameraAVStreamManagement.adoc Parameters: in-progress -Git: 0.9-fall2024-387-gfd3062545 +Git: 0.9-fall2024-411-g9835b5cd7 --> @@ -127,8 +127,8 @@ Git: 0.9-fall2024-387-gfd3062545 - - + + @@ -143,8 +143,8 @@ Git: 0.9-fall2024-387-gfd3062545 - - + + Camera AV Stream Management 0x0551 CAMERA_AV_STREAM_MANAGEMENT_CLUSTER @@ -172,7 +172,7 @@ Git: 0.9-fall2024-387-gfd3062545 - + @@ -187,7 +187,7 @@ Git: 0.9-fall2024-387-gfd3062545 NightVisionCapable MinViewport RateDistortionTradeOffPoints - MaxPreRollBufferSize + MaxContentBufferSize MicrophoneCapabilities SpeakerCapabilities TwoWayTalkSupport @@ -345,8 +345,8 @@ Git: 0.9-fall2024-387-gfd3062545 - - + + @@ -447,8 +447,8 @@ Git: 0.9-fall2024-387-gfd3062545 - - + + This event SHALL be generated when there is a modification in the corresponding video stream. diff --git a/src/controller/data_model/controller-clusters.matter b/src/controller/data_model/controller-clusters.matter index d663a5f018a217..24c7e00c623b53 100644 --- a/src/controller/data_model/controller-clusters.matter +++ b/src/controller/data_model/controller-clusters.matter @@ -9527,7 +9527,7 @@ provisional cluster ZoneManagement = 1360 { } /** The Camera AV Stream Management cluster is used to allow clients to manage, control, and configure various audio, video, and snapshot streams on a camera. */ -cluster CameraAvStreamManagement = 1361 { +provisional cluster CameraAvStreamManagement = 1361 { revision 1; enum AudioCodecEnum : enum8 { @@ -9695,7 +9695,7 @@ cluster CameraAvStreamManagement = 1361 { readonly attribute optional boolean nightVisionCapable = 3; readonly attribute optional VideoResolutionStruct minViewport = 4; readonly attribute optional RateDistortionTradeOffPointsStruct rateDistortionTradeOffPoints[] = 5; - readonly attribute optional int32u maxPreRollBufferSize = 6; + readonly attribute optional int32u maxContentBufferSize = 6; readonly attribute optional AudioCapabilitiesStruct microphoneCapabilities = 7; readonly attribute optional AudioCapabilitiesStruct speakerCapabilities = 8; readonly attribute optional TwoWayTalkSupportTypeEnum twoWayTalkSupport = 9; diff --git a/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java b/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java index dff134bddd1a18..06b8dd8ff0b54c 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java @@ -59730,7 +59730,7 @@ public static class CameraAvStreamManagementCluster extends BaseChipCluster { private static final long NIGHT_VISION_CAPABLE_ATTRIBUTE_ID = 3L; private static final long MIN_VIEWPORT_ATTRIBUTE_ID = 4L; private static final long RATE_DISTORTION_TRADE_OFF_POINTS_ATTRIBUTE_ID = 5L; - private static final long MAX_PRE_ROLL_BUFFER_SIZE_ATTRIBUTE_ID = 6L; + private static final long MAX_CONTENT_BUFFER_SIZE_ATTRIBUTE_ID = 6L; private static final long MICROPHONE_CAPABILITIES_ATTRIBUTE_ID = 7L; private static final long SPEAKER_CAPABILITIES_ATTRIBUTE_ID = 8L; private static final long TWO_WAY_TALK_SUPPORT_ATTRIBUTE_ID = 9L; @@ -60418,9 +60418,9 @@ public void onSuccess(byte[] tlv) { }, RATE_DISTORTION_TRADE_OFF_POINTS_ATTRIBUTE_ID, minInterval, maxInterval); } - public void readMaxPreRollBufferSizeAttribute( + public void readMaxContentBufferSizeAttribute( LongAttributeCallback callback) { - ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, MAX_PRE_ROLL_BUFFER_SIZE_ATTRIBUTE_ID); + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, MAX_CONTENT_BUFFER_SIZE_ATTRIBUTE_ID); readAttribute(new ReportCallbackImpl(callback, path) { @Override @@ -60428,12 +60428,12 @@ public void onSuccess(byte[] tlv) { Long value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); callback.onSuccess(value); } - }, MAX_PRE_ROLL_BUFFER_SIZE_ATTRIBUTE_ID, true); + }, MAX_CONTENT_BUFFER_SIZE_ATTRIBUTE_ID, true); } - public void subscribeMaxPreRollBufferSizeAttribute( + public void subscribeMaxContentBufferSizeAttribute( LongAttributeCallback callback, int minInterval, int maxInterval) { - ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, MAX_PRE_ROLL_BUFFER_SIZE_ATTRIBUTE_ID); + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, MAX_CONTENT_BUFFER_SIZE_ATTRIBUTE_ID); subscribeAttribute(new ReportCallbackImpl(callback, path) { @Override @@ -60441,7 +60441,7 @@ public void onSuccess(byte[] tlv) { Long value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); callback.onSuccess(value); } - }, MAX_PRE_ROLL_BUFFER_SIZE_ATTRIBUTE_ID, minInterval, maxInterval); + }, MAX_CONTENT_BUFFER_SIZE_ATTRIBUTE_ID, minInterval, maxInterval); } public void readMicrophoneCapabilitiesAttribute( diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java index a43df66e40bf0a..354f49ed6caa5d 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java @@ -17079,7 +17079,7 @@ public enum Attribute { NightVisionCapable(3L), MinViewport(4L), RateDistortionTradeOffPoints(5L), - MaxPreRollBufferSize(6L), + MaxContentBufferSize(6L), MicrophoneCapabilities(7L), SpeakerCapabilities(8L), TwoWayTalkSupport(9L), diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java index 9abbcd879c5503..843114b4374f58 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java @@ -18340,17 +18340,17 @@ private static Map readCameraAvStreamManagementInteract readCameraAvStreamManagementRateDistortionTradeOffPointsCommandParams ); result.put("readRateDistortionTradeOffPointsAttribute", readCameraAvStreamManagementRateDistortionTradeOffPointsAttributeInteractionInfo); - Map readCameraAvStreamManagementMaxPreRollBufferSizeCommandParams = new LinkedHashMap(); - InteractionInfo readCameraAvStreamManagementMaxPreRollBufferSizeAttributeInteractionInfo = new InteractionInfo( + Map readCameraAvStreamManagementMaxContentBufferSizeCommandParams = new LinkedHashMap(); + InteractionInfo readCameraAvStreamManagementMaxContentBufferSizeAttributeInteractionInfo = new InteractionInfo( (cluster, callback, commandArguments) -> { - ((ChipClusters.CameraAvStreamManagementCluster) cluster).readMaxPreRollBufferSizeAttribute( + ((ChipClusters.CameraAvStreamManagementCluster) cluster).readMaxContentBufferSizeAttribute( (ChipClusters.LongAttributeCallback) callback ); }, () -> new ClusterInfoMapping.DelegatedLongAttributeCallback(), - readCameraAvStreamManagementMaxPreRollBufferSizeCommandParams + readCameraAvStreamManagementMaxContentBufferSizeCommandParams ); - result.put("readMaxPreRollBufferSizeAttribute", readCameraAvStreamManagementMaxPreRollBufferSizeAttributeInteractionInfo); + result.put("readMaxContentBufferSizeAttribute", readCameraAvStreamManagementMaxContentBufferSizeAttributeInteractionInfo); Map readCameraAvStreamManagementTwoWayTalkSupportCommandParams = new LinkedHashMap(); InteractionInfo readCameraAvStreamManagementTwoWayTalkSupportAttributeInteractionInfo = new InteractionInfo( (cluster, callback, commandArguments) -> { diff --git a/src/controller/java/generated/java/matter/controller/cluster/clusters/CameraAvStreamManagementCluster.kt b/src/controller/java/generated/java/matter/controller/cluster/clusters/CameraAvStreamManagementCluster.kt index c9f6d50d065f8f..c0993403079dbf 100644 --- a/src/controller/java/generated/java/matter/controller/cluster/clusters/CameraAvStreamManagementCluster.kt +++ b/src/controller/java/generated/java/matter/controller/cluster/clusters/CameraAvStreamManagementCluster.kt @@ -1327,7 +1327,7 @@ class CameraAvStreamManagementCluster( } } - suspend fun readMaxPreRollBufferSizeAttribute(): UInt? { + suspend fun readMaxContentBufferSizeAttribute(): UInt? { val ATTRIBUTE_ID: UInt = 6u val attributePath = @@ -1349,7 +1349,7 @@ class CameraAvStreamManagementCluster( it.path.attributeId == ATTRIBUTE_ID } - requireNotNull(attributeData) { "Maxprerollbuffersize attribute not found in response" } + requireNotNull(attributeData) { "Maxcontentbuffersize attribute not found in response" } // Decode the TLV data into the appropriate type val tlvReader = TlvReader(attributeData.data) @@ -1363,7 +1363,7 @@ class CameraAvStreamManagementCluster( return decodedValue } - suspend fun subscribeMaxPreRollBufferSizeAttribute( + suspend fun subscribeMaxContentBufferSizeAttribute( minInterval: Int, maxInterval: Int, ): Flow { @@ -1399,7 +1399,7 @@ class CameraAvStreamManagementCluster( .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } requireNotNull(attributeData) { - "Maxprerollbuffersize attribute not found in Node State update" + "Maxcontentbuffersize attribute not found in Node State update" } // Decode the TLV data into the appropriate type diff --git a/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp b/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp index c49674fbbefe7e..c8247c5d4d31a8 100644 --- a/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp +++ b/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp @@ -40112,8 +40112,8 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } return value; } - case Attributes::MaxPreRollBufferSize::Id: { - using TypeInfo = Attributes::MaxPreRollBufferSize::TypeInfo; + case Attributes::MaxContentBufferSize::Id: { + using TypeInfo = Attributes::MaxContentBufferSize::TypeInfo; TypeInfo::DecodableType cppValue; *aError = app::DataModel::Decode(aReader, cppValue); if (*aError != CHIP_NO_ERROR) diff --git a/src/controller/python/chip/clusters/CHIPClusters.py b/src/controller/python/chip/clusters/CHIPClusters.py index 395506b33bb843..08f8182e6b6886 100644 --- a/src/controller/python/chip/clusters/CHIPClusters.py +++ b/src/controller/python/chip/clusters/CHIPClusters.py @@ -12543,7 +12543,7 @@ class ChipClusters: "reportable": True, }, 0x00000006: { - "attributeName": "MaxPreRollBufferSize", + "attributeName": "MaxContentBufferSize", "attributeId": 0x00000006, "type": "int", "reportable": True, diff --git a/src/controller/python/chip/clusters/Objects.py b/src/controller/python/chip/clusters/Objects.py index 0cdc2a54549cce..b7b73282715a22 100644 --- a/src/controller/python/chip/clusters/Objects.py +++ b/src/controller/python/chip/clusters/Objects.py @@ -44779,7 +44779,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: ClusterObjectFieldDescriptor(Label="nightVisionCapable", Tag=0x00000003, Type=typing.Optional[bool]), ClusterObjectFieldDescriptor(Label="minViewport", Tag=0x00000004, Type=typing.Optional[CameraAvStreamManagement.Structs.VideoResolutionStruct]), ClusterObjectFieldDescriptor(Label="rateDistortionTradeOffPoints", Tag=0x00000005, Type=typing.Optional[typing.List[CameraAvStreamManagement.Structs.RateDistortionTradeOffPointsStruct]]), - ClusterObjectFieldDescriptor(Label="maxPreRollBufferSize", Tag=0x00000006, Type=typing.Optional[uint]), + ClusterObjectFieldDescriptor(Label="maxContentBufferSize", Tag=0x00000006, Type=typing.Optional[uint]), ClusterObjectFieldDescriptor(Label="microphoneCapabilities", Tag=0x00000007, Type=typing.Optional[CameraAvStreamManagement.Structs.AudioCapabilitiesStruct]), ClusterObjectFieldDescriptor(Label="speakerCapabilities", Tag=0x00000008, Type=typing.Optional[CameraAvStreamManagement.Structs.AudioCapabilitiesStruct]), ClusterObjectFieldDescriptor(Label="twoWayTalkSupport", Tag=0x00000009, Type=typing.Optional[CameraAvStreamManagement.Enums.TwoWayTalkSupportTypeEnum]), @@ -44833,7 +44833,7 @@ def descriptor(cls) -> ClusterObjectDescriptor: nightVisionCapable: typing.Optional[bool] = None minViewport: typing.Optional[CameraAvStreamManagement.Structs.VideoResolutionStruct] = None rateDistortionTradeOffPoints: typing.Optional[typing.List[CameraAvStreamManagement.Structs.RateDistortionTradeOffPointsStruct]] = None - maxPreRollBufferSize: typing.Optional[uint] = None + maxContentBufferSize: typing.Optional[uint] = None microphoneCapabilities: typing.Optional[CameraAvStreamManagement.Structs.AudioCapabilitiesStruct] = None speakerCapabilities: typing.Optional[CameraAvStreamManagement.Structs.AudioCapabilitiesStruct] = None twoWayTalkSupport: typing.Optional[CameraAvStreamManagement.Enums.TwoWayTalkSupportTypeEnum] = None @@ -45561,7 +45561,7 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: typing.Optional[typing.List[CameraAvStreamManagement.Structs.RateDistortionTradeOffPointsStruct]] = None @dataclass - class MaxPreRollBufferSize(ClusterAttributeDescriptor): + class MaxContentBufferSize(ClusterAttributeDescriptor): @ChipUtility.classproperty def cluster_id(cls) -> int: return 0x00000551 diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm index 5495d6a9d7a0ca..43e0528c252c14 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm @@ -5613,7 +5613,7 @@ static BOOL AttributeIsSpecifiedInCameraAVStreamManagementCluster(AttributeId aA case Attributes::RateDistortionTradeOffPoints::Id: { return YES; } - case Attributes::MaxPreRollBufferSize::Id: { + case Attributes::MaxContentBufferSize::Id: { return YES; } case Attributes::MicrophoneCapabilities::Id: { diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm index b894c30f6cfc8e..16f882fe473a43 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm @@ -16999,8 +16999,8 @@ static id _Nullable DecodeAttributeValueForCameraAVStreamManagementCluster(Attri } return value; } - case Attributes::MaxPreRollBufferSize::Id: { - using TypeInfo = Attributes::MaxPreRollBufferSize::TypeInfo; + case Attributes::MaxContentBufferSize::Id: { + using TypeInfo = Attributes::MaxContentBufferSize::TypeInfo; TypeInfo::DecodableType cppValue; *aError = DataModel::Decode(aReader, cppValue); if (*aError != CHIP_NO_ERROR) { diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h index d3f7ba442b3c80..9c1755c5414f8f 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h @@ -14260,11 +14260,11 @@ MTR_PROVISIONALLY_AVAILABLE reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; + (void)readAttributeRateDistortionTradeOffPointsWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)readAttributeMaxPreRollBufferSizeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; -- (void)subscribeAttributeMaxPreRollBufferSizeWithParams:(MTRSubscribeParams *)params +- (void)readAttributeMaxContentBufferSizeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeMaxContentBufferSizeWithParams:(MTRSubscribeParams *)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; -+ (void)readAttributeMaxPreRollBufferSizeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeMaxContentBufferSizeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (void)readAttributeMicrophoneCapabilitiesWithCompletion:(void (^)(MTRCameraAVStreamManagementClusterAudioCapabilitiesStruct * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; - (void)subscribeAttributeMicrophoneCapabilitiesWithParams:(MTRSubscribeParams *)params diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm index eb2a2f5687c1f5..3c347c4472e132 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm @@ -98643,9 +98643,9 @@ + (void)readAttributeRateDistortionTradeOffPointsWithClusterStateCache:(MTRClust completion:completion]; } -- (void)readAttributeMaxPreRollBufferSizeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +- (void)readAttributeMaxContentBufferSizeWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion { - using TypeInfo = CameraAvStreamManagement::Attributes::MaxPreRollBufferSize::TypeInfo; + using TypeInfo = CameraAvStreamManagement::Attributes::MaxContentBufferSize::TypeInfo; [self.device _readKnownAttributeWithEndpointID:self.endpointID clusterID:@(TypeInfo::GetClusterId()) attributeID:@(TypeInfo::GetAttributeId()) @@ -98654,11 +98654,11 @@ - (void)readAttributeMaxPreRollBufferSizeWithCompletion:(void (^)(NSNumber * _Nu completion:completion]; } -- (void)subscribeAttributeMaxPreRollBufferSizeWithParams:(MTRSubscribeParams * _Nonnull)params +- (void)subscribeAttributeMaxContentBufferSizeWithParams:(MTRSubscribeParams * _Nonnull)params subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler { - using TypeInfo = CameraAvStreamManagement::Attributes::MaxPreRollBufferSize::TypeInfo; + using TypeInfo = CameraAvStreamManagement::Attributes::MaxContentBufferSize::TypeInfo; [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID clusterID:@(TypeInfo::GetClusterId()) attributeID:@(TypeInfo::GetAttributeId()) @@ -98668,9 +98668,9 @@ - (void)subscribeAttributeMaxPreRollBufferSizeWithParams:(MTRSubscribeParams * _ subscriptionEstablished:subscriptionEstablished]; } -+ (void)readAttributeMaxPreRollBufferSizeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion ++ (void)readAttributeMaxContentBufferSizeWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion { - using TypeInfo = CameraAvStreamManagement::Attributes::MaxPreRollBufferSize::TypeInfo; + using TypeInfo = CameraAvStreamManagement::Attributes::MaxContentBufferSize::TypeInfo; [clusterStateCacheContainer _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) clusterID:TypeInfo::GetClusterId() diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h b/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h index 7ee2c7d88af1c0..b1d26e9ce0fb12 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h @@ -4641,7 +4641,7 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeNightVisionCapableID MTR_PROVISIONALLY_AVAILABLE = 0x00000003, MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeMinViewportID MTR_PROVISIONALLY_AVAILABLE = 0x00000004, MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeRateDistortionTradeOffPointsID MTR_PROVISIONALLY_AVAILABLE = 0x00000005, - MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeMaxPreRollBufferSizeID MTR_PROVISIONALLY_AVAILABLE = 0x00000006, + MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeMaxContentBufferSizeID MTR_PROVISIONALLY_AVAILABLE = 0x00000006, MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeMicrophoneCapabilitiesID MTR_PROVISIONALLY_AVAILABLE = 0x00000007, MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeSpeakerCapabilitiesID MTR_PROVISIONALLY_AVAILABLE = 0x00000008, MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeTwoWayTalkSupportID MTR_PROVISIONALLY_AVAILABLE = 0x00000009, diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm b/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm index 08373371a7c5e2..ef41bc6487b379 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm @@ -7751,8 +7751,8 @@ result = @"RateDistortionTradeOffPoints"; break; - case MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeMaxPreRollBufferSizeID: - result = @"MaxPreRollBufferSize"; + case MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeMaxContentBufferSizeID: + result = @"MaxContentBufferSize"; break; case MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeMicrophoneCapabilitiesID: diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h index d9ca769e250aaa..111cab13f8af49 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h @@ -6660,7 +6660,7 @@ MTR_PROVISIONALLY_AVAILABLE - (NSDictionary * _Nullable)readAttributeRateDistortionTradeOffPointsWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; -- (NSDictionary * _Nullable)readAttributeMaxPreRollBufferSizeWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; +- (NSDictionary * _Nullable)readAttributeMaxContentBufferSizeWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; - (NSDictionary * _Nullable)readAttributeMicrophoneCapabilitiesWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm index 0923caca7cead0..b473aed7020e46 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm @@ -19454,9 +19454,9 @@ - (void)setImageFlipVerticalWithParams:(MTRCameraAVStreamManagementClusterSetIma return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeCameraAVStreamManagementID) attributeID:@(MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeRateDistortionTradeOffPointsID) params:params]; } -- (NSDictionary * _Nullable)readAttributeMaxPreRollBufferSizeWithParams:(MTRReadParams * _Nullable)params +- (NSDictionary * _Nullable)readAttributeMaxContentBufferSizeWithParams:(MTRReadParams * _Nullable)params { - return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeCameraAVStreamManagementID) attributeID:@(MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeMaxPreRollBufferSizeID) params:params]; + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeCameraAVStreamManagementID) attributeID:@(MTRAttributeIDTypeClusterCameraAVStreamManagementAttributeMaxContentBufferSizeID) params:params]; } - (NSDictionary * _Nullable)readAttributeMicrophoneCapabilitiesWithParams:(MTRReadParams * _Nullable)params diff --git a/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp b/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp index 382c808a78cc62..762cedbf1b5aa3 100644 --- a/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp +++ b/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp @@ -37056,7 +37056,7 @@ Protocols::InteractionModel::Status Set(EndpointId endpoint, bool value) } // namespace NightVisionCapable -namespace MaxPreRollBufferSize { +namespace MaxContentBufferSize { Protocols::InteractionModel::Status Get(EndpointId endpoint, uint32_t * value) { @@ -37101,7 +37101,7 @@ Protocols::InteractionModel::Status Set(EndpointId endpoint, uint32_t value) return emberAfWriteAttribute(endpoint, Clusters::CameraAvStreamManagement::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE); } -} // namespace MaxPreRollBufferSize +} // namespace MaxContentBufferSize namespace TwoWayTalkSupport { diff --git a/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.h b/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.h index e0a965b732a743..98aebd50964980 100644 --- a/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.h +++ b/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.h @@ -5620,11 +5620,11 @@ Protocols::InteractionModel::Status Set(EndpointId endpoint, bool value); Protocols::InteractionModel::Status Set(EndpointId endpoint, bool value, MarkAttributeDirty markDirty); } // namespace NightVisionCapable -namespace MaxPreRollBufferSize { +namespace MaxContentBufferSize { Protocols::InteractionModel::Status Get(EndpointId endpoint, uint32_t * value); // int32u Protocols::InteractionModel::Status Set(EndpointId endpoint, uint32_t value); Protocols::InteractionModel::Status Set(EndpointId endpoint, uint32_t value, MarkAttributeDirty markDirty); -} // namespace MaxPreRollBufferSize +} // namespace MaxContentBufferSize namespace TwoWayTalkSupport { Protocols::InteractionModel::Status diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp index 7e9752db4a888c..111324e9cb51ae 100644 --- a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp +++ b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp @@ -30138,8 +30138,8 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre return DataModel::Decode(reader, minViewport); case Attributes::RateDistortionTradeOffPoints::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, rateDistortionTradeOffPoints); - case Attributes::MaxPreRollBufferSize::TypeInfo::GetAttributeId(): - return DataModel::Decode(reader, maxPreRollBufferSize); + case Attributes::MaxContentBufferSize::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, maxContentBufferSize); case Attributes::MicrophoneCapabilities::TypeInfo::GetAttributeId(): return DataModel::Decode(reader, microphoneCapabilities); case Attributes::SpeakerCapabilities::TypeInfo::GetAttributeId(): diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h index 4ec96663f8becd..d7f69cc3818e3e 100644 --- a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h +++ b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h @@ -41980,7 +41980,7 @@ struct TypeInfo static constexpr bool MustUseTimedWrite() { return false; } }; } // namespace RateDistortionTradeOffPoints -namespace MaxPreRollBufferSize { +namespace MaxContentBufferSize { struct TypeInfo { using Type = uint32_t; @@ -41988,10 +41988,10 @@ struct TypeInfo using DecodableArgType = uint32_t; static constexpr ClusterId GetClusterId() { return Clusters::CameraAvStreamManagement::Id; } - static constexpr AttributeId GetAttributeId() { return Attributes::MaxPreRollBufferSize::Id; } + static constexpr AttributeId GetAttributeId() { return Attributes::MaxContentBufferSize::Id; } static constexpr bool MustUseTimedWrite() { return false; } }; -} // namespace MaxPreRollBufferSize +} // namespace MaxContentBufferSize namespace MicrophoneCapabilities { struct TypeInfo { @@ -42529,7 +42529,7 @@ struct TypeInfo Attributes::NightVisionCapable::TypeInfo::DecodableType nightVisionCapable = static_cast(0); Attributes::MinViewport::TypeInfo::DecodableType minViewport; Attributes::RateDistortionTradeOffPoints::TypeInfo::DecodableType rateDistortionTradeOffPoints; - Attributes::MaxPreRollBufferSize::TypeInfo::DecodableType maxPreRollBufferSize = static_cast(0); + Attributes::MaxContentBufferSize::TypeInfo::DecodableType maxContentBufferSize = static_cast(0); Attributes::MicrophoneCapabilities::TypeInfo::DecodableType microphoneCapabilities; Attributes::SpeakerCapabilities::TypeInfo::DecodableType speakerCapabilities; Attributes::TwoWayTalkSupport::TypeInfo::DecodableType twoWayTalkSupport = diff --git a/zzz_generated/app-common/app-common/zap-generated/ids/Attributes.h b/zzz_generated/app-common/app-common/zap-generated/ids/Attributes.h index 8ee5cb21be8e31..e9375f5dad786a 100644 --- a/zzz_generated/app-common/app-common/zap-generated/ids/Attributes.h +++ b/zzz_generated/app-common/app-common/zap-generated/ids/Attributes.h @@ -6890,9 +6890,9 @@ namespace RateDistortionTradeOffPoints { static constexpr AttributeId Id = 0x00000005; } // namespace RateDistortionTradeOffPoints -namespace MaxPreRollBufferSize { +namespace MaxContentBufferSize { static constexpr AttributeId Id = 0x00000006; -} // namespace MaxPreRollBufferSize +} // namespace MaxContentBufferSize namespace MicrophoneCapabilities { static constexpr AttributeId Id = 0x00000007; diff --git a/zzz_generated/chip-tool/zap-generated/cluster/Commands.h b/zzz_generated/chip-tool/zap-generated/cluster/Commands.h index afcc2abd01d6fb..4ee3c3e1f98afa 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/Commands.h +++ b/zzz_generated/chip-tool/zap-generated/cluster/Commands.h @@ -13732,7 +13732,7 @@ class ZoneManagementRemoveZone : public ClusterCommand | * NightVisionCapable | 0x0003 | | * MinViewport | 0x0004 | | * RateDistortionTradeOffPoints | 0x0005 | -| * MaxPreRollBufferSize | 0x0006 | +| * MaxContentBufferSize | 0x0006 | | * MicrophoneCapabilities | 0x0007 | | * SpeakerCapabilities | 0x0008 | | * TwoWayTalkSupport | 0x0009 | @@ -26925,7 +26925,7 @@ void registerClusterCameraAvStreamManagement(Commands & commands, CredentialIssu make_unique(Id, "min-viewport", Attributes::MinViewport::Id, credsIssuerConfig), // make_unique(Id, "rate-distortion-trade-off-points", Attributes::RateDistortionTradeOffPoints::Id, credsIssuerConfig), // - make_unique(Id, "max-pre-roll-buffer-size", Attributes::MaxPreRollBufferSize::Id, credsIssuerConfig), // + make_unique(Id, "max-content-buffer-size", Attributes::MaxContentBufferSize::Id, credsIssuerConfig), // make_unique(Id, "microphone-capabilities", Attributes::MicrophoneCapabilities::Id, credsIssuerConfig), // make_unique(Id, "speaker-capabilities", Attributes::SpeakerCapabilities::Id, credsIssuerConfig), // make_unique(Id, "two-way-talk-support", Attributes::TwoWayTalkSupport::Id, credsIssuerConfig), // @@ -26993,7 +26993,7 @@ void registerClusterCameraAvStreamManagement(Commands & commands, CredentialIssu const chip::app::Clusters::CameraAvStreamManagement::Structs::RateDistortionTradeOffPointsStruct::Type>>>( Id, "rate-distortion-trade-off-points", Attributes::RateDistortionTradeOffPoints::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // - make_unique>(Id, "max-pre-roll-buffer-size", 0, UINT32_MAX, Attributes::MaxPreRollBufferSize::Id, + make_unique>(Id, "max-content-buffer-size", 0, UINT32_MAX, Attributes::MaxContentBufferSize::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // make_unique>( Id, "microphone-capabilities", Attributes::MicrophoneCapabilities::Id, WriteCommandType::kForceWrite, @@ -27114,8 +27114,8 @@ void registerClusterCameraAvStreamManagement(Commands & commands, CredentialIssu make_unique(Id, "night-vision-capable", Attributes::NightVisionCapable::Id, credsIssuerConfig), // make_unique(Id, "min-viewport", Attributes::MinViewport::Id, credsIssuerConfig), // make_unique(Id, "rate-distortion-trade-off-points", Attributes::RateDistortionTradeOffPoints::Id, - credsIssuerConfig), // - make_unique(Id, "max-pre-roll-buffer-size", Attributes::MaxPreRollBufferSize::Id, credsIssuerConfig), // + credsIssuerConfig), // + make_unique(Id, "max-content-buffer-size", Attributes::MaxContentBufferSize::Id, credsIssuerConfig), // make_unique(Id, "microphone-capabilities", Attributes::MicrophoneCapabilities::Id, credsIssuerConfig), // make_unique(Id, "speaker-capabilities", Attributes::SpeakerCapabilities::Id, credsIssuerConfig), // diff --git a/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp b/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp index 8a0e26cbca4bc1..ac4e3adbbbebc3 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp +++ b/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp @@ -18513,10 +18513,10 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); return DataModelLogger::LogValue("RateDistortionTradeOffPoints", 1, value); } - case CameraAvStreamManagement::Attributes::MaxPreRollBufferSize::Id: { + case CameraAvStreamManagement::Attributes::MaxContentBufferSize::Id: { uint32_t value; ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); - return DataModelLogger::LogValue("MaxPreRollBufferSize", 1, value); + return DataModelLogger::LogValue("MaxContentBufferSize", 1, value); } case CameraAvStreamManagement::Attributes::MicrophoneCapabilities::Id: { chip::app::Clusters::CameraAvStreamManagement::Structs::AudioCapabilitiesStruct::DecodableType value; diff --git a/zzz_generated/chip-tool/zap-generated/cluster/logging/EntryToText.cpp b/zzz_generated/chip-tool/zap-generated/cluster/logging/EntryToText.cpp index a5739f1228aad6..0b5178d3bcb208 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/logging/EntryToText.cpp +++ b/zzz_generated/chip-tool/zap-generated/cluster/logging/EntryToText.cpp @@ -4181,8 +4181,8 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "MinViewport"; case chip::app::Clusters::CameraAvStreamManagement::Attributes::RateDistortionTradeOffPoints::Id: return "RateDistortionTradeOffPoints"; - case chip::app::Clusters::CameraAvStreamManagement::Attributes::MaxPreRollBufferSize::Id: - return "MaxPreRollBufferSize"; + case chip::app::Clusters::CameraAvStreamManagement::Attributes::MaxContentBufferSize::Id: + return "MaxContentBufferSize"; case chip::app::Clusters::CameraAvStreamManagement::Attributes::MicrophoneCapabilities::Id: return "MicrophoneCapabilities"; case chip::app::Clusters::CameraAvStreamManagement::Attributes::SpeakerCapabilities::Id: diff --git a/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h b/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h index 4dc01523ea8db8..bf6bff38ba079b 100644 --- a/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h +++ b/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h @@ -150650,7 +150650,7 @@ class SubscribeAttributeZoneManagementClusterRevision : public SubscribeAttribut | * NightVisionCapable | 0x0003 | | * MinViewport | 0x0004 | | * RateDistortionTradeOffPoints | 0x0005 | -| * MaxPreRollBufferSize | 0x0006 | +| * MaxContentBufferSize | 0x0006 | | * MicrophoneCapabilities | 0x0007 | | * SpeakerCapabilities | 0x0008 | | * TwoWayTalkSupport | 0x0009 | @@ -152134,34 +152134,34 @@ class SubscribeAttributeCameraAvStreamManagementRateDistortionTradeOffPoints : p #if MTR_ENABLE_PROVISIONAL /* - * Attribute MaxPreRollBufferSize + * Attribute MaxContentBufferSize */ -class ReadCameraAvStreamManagementMaxPreRollBufferSize : public ReadAttribute { +class ReadCameraAvStreamManagementMaxContentBufferSize : public ReadAttribute { public: - ReadCameraAvStreamManagementMaxPreRollBufferSize() - : ReadAttribute("max-pre-roll-buffer-size") + ReadCameraAvStreamManagementMaxContentBufferSize() + : ReadAttribute("max-content-buffer-size") { } - ~ReadCameraAvStreamManagementMaxPreRollBufferSize() + ~ReadCameraAvStreamManagementMaxContentBufferSize() { } CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override { constexpr chip::ClusterId clusterId = chip::app::Clusters::CameraAvStreamManagement::Id; - constexpr chip::AttributeId attributeId = chip::app::Clusters::CameraAvStreamManagement::Attributes::MaxPreRollBufferSize::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::CameraAvStreamManagement::Attributes::MaxContentBufferSize::Id; ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); __auto_type * cluster = [[MTRBaseClusterCameraAVStreamManagement alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; - [cluster readAttributeMaxPreRollBufferSizeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { - NSLog(@"CameraAVStreamManagement.MaxPreRollBufferSize response %@", [value description]); + [cluster readAttributeMaxContentBufferSizeWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"CameraAVStreamManagement.MaxContentBufferSize response %@", [value description]); if (error == nil) { RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); } else { - LogNSError("CameraAVStreamManagement MaxPreRollBufferSize read Error", error); + LogNSError("CameraAVStreamManagement MaxContentBufferSize read Error", error); RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); } SetCommandExitStatus(error); @@ -152170,21 +152170,21 @@ class ReadCameraAvStreamManagementMaxPreRollBufferSize : public ReadAttribute { } }; -class SubscribeAttributeCameraAvStreamManagementMaxPreRollBufferSize : public SubscribeAttribute { +class SubscribeAttributeCameraAvStreamManagementMaxContentBufferSize : public SubscribeAttribute { public: - SubscribeAttributeCameraAvStreamManagementMaxPreRollBufferSize() - : SubscribeAttribute("max-pre-roll-buffer-size") + SubscribeAttributeCameraAvStreamManagementMaxContentBufferSize() + : SubscribeAttribute("max-content-buffer-size") { } - ~SubscribeAttributeCameraAvStreamManagementMaxPreRollBufferSize() + ~SubscribeAttributeCameraAvStreamManagementMaxContentBufferSize() { } CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override { constexpr chip::ClusterId clusterId = chip::app::Clusters::CameraAvStreamManagement::Id; - constexpr chip::CommandId attributeId = chip::app::Clusters::CameraAvStreamManagement::Attributes::MaxPreRollBufferSize::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::CameraAvStreamManagement::Attributes::MaxContentBufferSize::Id; ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); @@ -152199,10 +152199,10 @@ class SubscribeAttributeCameraAvStreamManagementMaxPreRollBufferSize : public Su if (mAutoResubscribe.HasValue()) { params.resubscribeAutomatically = mAutoResubscribe.Value(); } - [cluster subscribeAttributeMaxPreRollBufferSizeWithParams:params + [cluster subscribeAttributeMaxContentBufferSizeWithParams:params subscriptionEstablished:^() { mSubscriptionEstablished = YES; } reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) { - NSLog(@"CameraAVStreamManagement.MaxPreRollBufferSize response %@", [value description]); + NSLog(@"CameraAVStreamManagement.MaxContentBufferSize response %@", [value description]); if (error == nil) { RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); } else { @@ -181984,8 +181984,8 @@ void registerClusterCameraAvStreamManagement(Commands & commands) make_unique(), // #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL - make_unique(), // - make_unique(), // + make_unique(), // + make_unique(), // #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL make_unique(), // From 631ad4376d50f947ad4cd0d296b2adfd9f718371 Mon Sep 17 00:00:00 2001 From: Raul Marquez <130402456+raul-marquez-csa@users.noreply.github.com> Date: Tue, 22 Oct 2024 20:51:46 -0700 Subject: [PATCH 075/149] Removes test case scripts (#36185) --- .../certification/Test_TC_DISHM_3_1.yaml | 219 ------ .../certification/Test_TC_DISHM_3_2.yaml | 237 ------ .../certification/Test_TC_DISHM_3_3.yaml | 274 ------- .../suites/certification/Test_TC_LWM_3_1.yaml | 134 ---- .../suites/certification/Test_TC_LWM_3_2.yaml | 172 ----- .../suites/certification/Test_TC_LWM_3_3.yaml | 189 ----- .../suites/certification/Test_TC_MOD_1_3.yaml | 722 ------------------ .../certification/Test_TC_OTCCM_3_1.yaml | 131 ---- .../certification/Test_TC_OTCCM_3_2.yaml | 171 ----- .../certification/Test_TC_OTCCM_3_3.yaml | 187 ----- .../certification/Test_TC_TCCM_3_1.yaml | 127 --- .../certification/Test_TC_TCCM_3_2.yaml | 176 ----- .../certification/Test_TC_TCCM_3_3.yaml | 195 ----- 13 files changed, 2934 deletions(-) delete mode 100644 src/app/tests/suites/certification/Test_TC_DISHM_3_1.yaml delete mode 100644 src/app/tests/suites/certification/Test_TC_DISHM_3_2.yaml delete mode 100644 src/app/tests/suites/certification/Test_TC_DISHM_3_3.yaml delete mode 100644 src/app/tests/suites/certification/Test_TC_LWM_3_1.yaml delete mode 100644 src/app/tests/suites/certification/Test_TC_LWM_3_2.yaml delete mode 100644 src/app/tests/suites/certification/Test_TC_LWM_3_3.yaml delete mode 100644 src/app/tests/suites/certification/Test_TC_MOD_1_3.yaml delete mode 100644 src/app/tests/suites/certification/Test_TC_OTCCM_3_1.yaml delete mode 100644 src/app/tests/suites/certification/Test_TC_OTCCM_3_2.yaml delete mode 100644 src/app/tests/suites/certification/Test_TC_OTCCM_3_3.yaml delete mode 100644 src/app/tests/suites/certification/Test_TC_TCCM_3_1.yaml delete mode 100644 src/app/tests/suites/certification/Test_TC_TCCM_3_2.yaml delete mode 100644 src/app/tests/suites/certification/Test_TC_TCCM_3_3.yaml diff --git a/src/app/tests/suites/certification/Test_TC_DISHM_3_1.yaml b/src/app/tests/suites/certification/Test_TC_DISHM_3_1.yaml deleted file mode 100644 index 5b3cbf40b3b5d5..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_DISHM_3_1.yaml +++ /dev/null @@ -1,219 +0,0 @@ -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# Auto-generated scripts for harness use only, please review before automation. The endpoints and cluster names are currently set to default - -name: 263.4.1. [TC-DISHM-3.1] On Mode functionality with DUT as Server - -PICS: - - DISHM.S.A0003 - - MOD.S.F00 - - OO.S.C00.Rsp - - OO.S.C01.Rsp - -config: - nodeId: 0x12344321 - cluster: "Basic Information" - endpoint: 0 - -tests: - - label: "Precondition" - verification: | - 1 Dishwasher Mode and OnOff clusters are available on the same endpoint - - 2 The OnMode attribute is set to a non-NULL value from the mode values indicated by the SupportedModes attribute. - - Read the SupportedModes attribute, select a value from SupportedModes and save the value as OnMode_value - - ./chip-tool dishwashermode read supported-modes 1 1 - - On TH(chip-tool) log, Verify the list of SupportedModes and below is the sample log provided for the raspi platform: - - [1692170674.471882][3058:3061] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0059 Attribute 0x0000_0000 DataVersion: 2502960191 - [1692170674.472010][3058:3061] CHIP:TOO: SupportedModes: 3 entries - [1692170674.472081][3058:3061] CHIP:TOO: [1]: { - [1692170674.472110][3058:3061] CHIP:TOO: Label: Normal - [1692170674.472135][3058:3061] CHIP:TOO: Mode: 0 - [1692170674.472163][3058:3061] CHIP:TOO: ModeTags: 1 entries - [1692170674.472223][3058:3061] CHIP:TOO: [1]: { - [1692170674.472252][3058:3061] CHIP:TOO: Value: 16384 - [1692170674.472288][3058:3061] CHIP:TOO: } - [1692170674.472314][3058:3061] CHIP:TOO: } - [1692170674.472385][3058:3061] CHIP:TOO: [2]: { - [1692170674.472411][3058:3061] CHIP:TOO: Label: Heavy - [1692170674.472435][3058:3061] CHIP:TOO: Mode: 1 - [1692170674.472475][3058:3061] CHIP:TOO: ModeTags: 2 entries - [1692170674.472506][3058:3061] CHIP:TOO: [1]: { - [1692170674.472542][3058:3061] CHIP:TOO: Value: 7 - [1692170674.472567][3058:3061] CHIP:TOO: } - [1692170674.472595][3058:3061] CHIP:TOO: [2]: { - [1692170674.472632][3058:3061] CHIP:TOO: Value: 16385 - [1692170674.472658][3058:3061] CHIP:TOO: } - [1692170674.472683][3058:3061] CHIP:TOO: } - [1692170674.472730][3058:3061] CHIP:TOO: [3]: { - [1692170674.472755][3058:3061] CHIP:TOO: Label: Light - [1692170674.472778][3058:3061] CHIP:TOO: Mode: 2 - [1692170674.472820][3058:3061] CHIP:TOO: ModeTags: 3 entries - [1692170674.472851][3058:3061] CHIP:TOO: [1]: { - [1692170674.472886][3058:3061] CHIP:TOO: Value: 16386 - [1692170674.472910][3058:3061] CHIP:TOO: } - [1692170674.472938][3058:3061] CHIP:TOO: [2]: { - [1692170674.472973][3058:3061] CHIP:TOO: Value: 8 - [1692170674.472996][3058:3061] CHIP:TOO: } - [1692170674.473024][3058:3061] CHIP:TOO: [3]: { - [1692170674.473048][3058:3061] CHIP:TOO: Value: 2 - [1692170674.473071][3058:3061] CHIP:TOO: } - [1692170674.473095][3058:3061] CHIP:TOO: } - - Set the OnMode attribute value to OnMode_value - - ./chip-tool dishwashermode write on-mode 0 1 1 - - On TH(chip-tool) log, Verify DUT responds with a SUCCESS (value 0x00) status response and below is the sample log provided for the raspi platform: - - [1692170913.264454][3071:3073] CHIP:DMG: StatusIB = - [1692170913.264489][3071:3073] CHIP:DMG: { - [1692170913.264522][3071:3073] CHIP:DMG: status = 0x00 (SUCCESS), - [1692170913.264557][3071:3073] CHIP:DMG: }, - disabled: true - - - label: - "Step 1: Commission DUT to TH (can be skipped if done in a preceding - test)." - verification: | - - disabled: true - - - label: "Step 2: TH reads from the DUT the OnMode attribute." - PICS: DISHM.S.A0003 && MOD.S.F00 - verification: | - ./chip-tool dishwashermode read on-mode 1 1 - - On TH(chip-tool), Verify that OnMode attribute value is an Integer - Save the value as on_mode_dut and below is the sample log provided for the raspi platform, here OnMode value is 0 - - [1690188734.934221][15978:15980] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0059 Attribute 0x0000_0003 DataVersion: 74242734 - [1690188734.934259][15978:15980] CHIP:TOO: OnMode: 0 - disabled: true - - - label: "Step 3: TH reads from the DUT the CurrentMode attribute." - PICS: DISHM.S.A0001 && MOD.S.F00 - verification: | - ./chip-tool dishwashermode read current-mode 1 1 - - On TH(chip-tool), Verify that CurrentMode attribute is an integer. - Save the value as old_current_mode_dut and below is the sample log provided for the raspi platform, Here CurrentMode value is 0 - - NOTE: If startup_mode_dut is equal to old_current_mode_dut proceed to step 4. Else proceed to step 6. - - [1690188747.957507][15982:15984] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0059 Attribute 0x0000_0001 DataVersion: 74242734 - [1690188747.957564][15982:15984] CHIP:TOO: CurrentMode: 0 - disabled: true - - - label: "Step 4: TH reads from the DUT the SupportedModes attribute." - PICS: DISHM.S.A0000 && MOD.S.F00 - verification: | - ./chip-tool dishwashermode read supported-modes 1 1 - - On TH(chip-tool) log, Verify DUT response contains a list of ModeOptionsStruct entries - - Verify that the list has two or more entries - - Save the Mode field values as supported_modes_dut - - Select a value from supported_modes_dut different from on_mode_dut. Save the value as new_mode_th, below is the sample log provided for the raspi platform: - - [1690188771.532158][15986:15988] CHIP:DMG: } - [1690188771.532258][15986:15988] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0059 Attribute 0x0000_0000 DataVersion: 74242734 - [1690188771.532287][15986:15988] CHIP:TOO: SupportedModes: 3 entries - [1690188771.532305][15986:15988] CHIP:TOO: [1]: { - [1690188771.532309][15986:15988] CHIP:TOO: Label: Normal - [1690188771.532316][15986:15988] CHIP:TOO: Mode: 0 - [1690188771.532321][15986:15988] CHIP:TOO: ModeTags: 1 entries - [1690188771.532327][15986:15988] CHIP:TOO: [1]: { - [1690188771.532331][15986:15988] CHIP:TOO: Value: 16384 - [1690188771.532334][15986:15988] CHIP:TOO: } - [1690188771.532338][15986:15988] CHIP:TOO: } - [1690188771.532345][15986:15988] CHIP:TOO: [2]: { - [1690188771.532348][15986:15988] CHIP:TOO: Label: Heavy - [1690188771.532352][15986:15988] CHIP:TOO: Mode: 1 - [1690188771.532358][15986:15988] CHIP:TOO: ModeTags: 2 entries - [1690188771.532363][15986:15988] CHIP:TOO: [1]: { - [1690188771.532366][15986:15988] CHIP:TOO: Value: 7 - [1690188771.532368][15986:15988] CHIP:TOO: } - [1690188771.532372][15986:15988] CHIP:TOO: [2]: { - [1690188771.532374][15986:15988] CHIP:TOO: Value: 16385 - [1690188771.532376][15986:15988] CHIP:TOO: } - [1690188771.532379][15986:15988] CHIP:TOO: } - [1690188771.532386][15986:15988] CHIP:TOO: [3]: { - [1690188771.532388][15986:15988] CHIP:TOO: Label: Light - [1690188771.532390][15986:15988] CHIP:TOO: Mode: 2 - [1690188771.532395][15986:15988] CHIP:TOO: ModeTags: 3 entries - [1690188771.532398][15986:15988] CHIP:TOO: [1]: { - [1690188771.532401][15986:15988] CHIP:TOO: Value: 16386 - [1690188771.532403][15986:15988] CHIP:TOO: } - [1690188771.532406][15986:15988] CHIP:TOO: [2]: { - [1690188771.532409][15986:15988] CHIP:TOO: Value: 8 - [1690188771.532411][15986:15988] CHIP:TOO: } - [1690188771.532414][15986:15988] CHIP:TOO: [3]: { - [1690188771.532417][15986:15988] CHIP:TOO: Value: 2 - [1690188771.532419][15986:15988] CHIP:TOO: } - [1690188771.532421][15986:15988] CHIP:TOO: } - disabled: true - - - label: - "Step 5: TH sends a ChangeToMode command to the DUT with NewMode set - to new_mode_th" - PICS: DISHM.S.C00.Rsp && MOD.S.F00 - verification: | - ./chip-tool dishwashermode change-to-mode 2 1 1 - - Verify on TH(chip-tool) log, DUT responds contains a ChangeToModeResponse command with a SUCCESS (value 0x00) status response and below is the sample log provided for the raspi platform: - - [1690198333.074192][17405:17407] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0059 Command 0x0000_0001 - [1690198333.074208][17405:17407] CHIP:TOO: ChangeToModeResponse: { - [1690198333.074213][17405:17407] CHIP:TOO: status: 0 - [1690198333.074216][17405:17407] CHIP:TOO: } - disabled: true - - - label: "Step 6: TH sends a Off command to the DUT" - PICS: OO.S.C00.Rsp && MOD.S.F00 - verification: | - ./chip-tool onoff off 1 1 - - On TH(chip-tool) log, Verify DUT responds with a successful (value 0x00) status response and below is the sample log provided for the raspi platform: - - [1684931101.118659][20709:20711] CHIP:DMG: { - [1684931101.118663][20709:20711] CHIP:DMG: status = 0x00 (SUCCESS), - [1684931101.118665][20709:20711] CHIP:DMG: }, - disabled: true - - - label: "Step 7: TH sends a On command to the DUT" - PICS: OO.S.C01.Rsp && MOD.S.F00 - verification: | - ./chip-tool onoff on 1 1 - - On TH(chip-tool) log, Verify DUT responds with a successful (value 0x00) status response and below is the sample log provided for the raspi platform: - - [1684931217.055517][20729:20731] CHIP:DMG: { - [1684931217.055520][20729:20731] CHIP:DMG: status = 0x00 (SUCCESS), - [1684931217.055523][20729:20731] CHIP:DMG: }, - disabled: true - - - label: "Step 8: TH reads from the DUT the CurrentMode attribute." - PICS: DISHM.S.A0001 && MOD.S.F00 - verification: | - ./chip-tool dishwashermode read current-mode 1 1 - - On TH(chip-tool), Verify that CurrentMode attribute value is an integer value and equal to on_mode_dut, below is the sample log provided for the raspi platform, here CurrentMode attribute value is 0 - - [1690188859.713934][16004:16006] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0059 Attribute 0x0000_0001 DataVersion: 74242736 - [1690188859.713980][16004:16006] CHIP:TOO: CurrentMode: 0 - disabled: true diff --git a/src/app/tests/suites/certification/Test_TC_DISHM_3_2.yaml b/src/app/tests/suites/certification/Test_TC_DISHM_3_2.yaml deleted file mode 100644 index c53124e903fb7a..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_DISHM_3_2.yaml +++ /dev/null @@ -1,237 +0,0 @@ -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# Auto-generated scripts for harness use only, please review before automation. The endpoints and cluster names are currently set to default - -name: 263.4.2. [TC-DISHM-3.2] Startup Mode functionality with DUT as Server - -PICS: - - DISHM.S.A0002 - -config: - nodeId: 0x12344321 - cluster: "Basic Information" - endpoint: 0 - -tests: - - label: "Preconditions" - verification: | - !DISHM.S.F00 | OnOff cluster’s StartUpOnOff attribute is NULL | StartUpOnOff is 0 | OnMode is NULL - disabled: true - - - label: "Note" - verification: | - To Execute the TC-DISHM-3.2 test case using reboot in raspi device we followed the below suggested way: - - To run a reboot test case on raspi, run the app with --KVS flag with a file in local directory and pass that file to the command to launch the app. Steps - - step-1: create a file using touch command , something like touch mytest.txt - step-2: chmod 777 mytest.txt - step-3: launch the app ./chip-all-clusters-app --KVS ./mytest.txt - - if you launch the app with the above commands and provision the app, even when you reboot the app with 'sudo reboot' , next time you launch the app with 'sudo ./out/all-clusters-app/chip-all-clusters-app --KVS ./mytest.txt' , you can run read/write attribs and commands without reprovisioning the device. - disabled: true - - - label: - "Step 1: Commission DUT to TH (can be skipped if done in a preceding - test)." - verification: | - - disabled: true - - - label: "Step 2: TH reads from the DUT the StartUpMode attribute." - PICS: DISHM.S.A0002 - verification: | - ./chip-tool dishwashermode read start-up-mode 1 1 - - On TH(chip-tool), Verify StartUpMode attribute value is an integer or null - - Save the value as startup_mode_dut and below is the sample log provided for the raspi platform, Here StartUpMode value is null - - NOTE: if startup_mode_dut is null proceed to step 3. Else save startup_mode_dut as new_start_up_mode_th and proceed to step 5. - - [1690188941.380388][16015:16017] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0059 Attribute 0x0000_0002 DataVersion: 74242738 - [1690188941.380430][16015:16017] CHIP:TOO: StartUpMode: null - disabled: true - - - label: "Step 3: TH reads from the DUT the SupportedModes attribute." - PICS: DISHM.S.A0000 - verification: | - ./chip-tool dishwashermode read supported-modes 1 1 - - On TH(chip-tool) log, Verify DUT response contains a list of ModeOptionsStruct entries - - Verify that the list has two or more entries - - Save the Mode field values as supported_modes_dut - - Select a value from supported_modes_dut and save the value as new_start_up_mode_th, below is the sample log provided for the raspi platform: - - [1690188996.754102][16022:16024] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0059 Attribute 0x0000_0000 DataVersion: 74242738 - [1690188996.754208][16022:16024] CHIP:TOO: SupportedModes: 3 entries - [1690188996.754248][16022:16024] CHIP:TOO: [1]: { - [1690188996.754258][16022:16024] CHIP:TOO: Label: Normal - [1690188996.754270][16022:16024] CHIP:TOO: Mode: 0 - [1690188996.754285][16022:16024] CHIP:TOO: ModeTags: 1 entries - [1690188996.754302][16022:16024] CHIP:TOO: [1]: { - [1690188996.754314][16022:16024] CHIP:TOO: Value: 16384 - [1690188996.754325][16022:16024] CHIP:TOO: } - [1690188996.754336][16022:16024] CHIP:TOO: } - [1690188996.754360][16022:16024] CHIP:TOO: [2]: { - [1690188996.754369][16022:16024] CHIP:TOO: Label: Heavy - [1690188996.754378][16022:16024] CHIP:TOO: Mode: 1 - [1690188996.754393][16022:16024] CHIP:TOO: ModeTags: 2 entries - [1690188996.754407][16022:16024] CHIP:TOO: [1]: { - [1690188996.754416][16022:16024] CHIP:TOO: Value: 7 - [1690188996.754425][16022:16024] CHIP:TOO: } - [1690188996.754439][16022:16024] CHIP:TOO: [2]: { - [1690188996.754450][16022:16024] CHIP:TOO: Value: 16385 - [1690188996.754459][16022:16024] CHIP:TOO: } - [1690188996.754469][16022:16024] CHIP:TOO: } - [1690188996.754493][16022:16024] CHIP:TOO: [3]: { - [1690188996.754501][16022:16024] CHIP:TOO: Label: Light - [1690188996.754511][16022:16024] CHIP:TOO: Mode: 2 - [1690188996.754548][16022:16024] CHIP:TOO: ModeTags: 3 entries - [1690188996.754564][16022:16024] CHIP:TOO: [1]: { - [1690188996.754574][16022:16024] CHIP:TOO: Value: 16386 - [1690188996.754583][16022:16024] CHIP:TOO: } - [1690188996.754597][16022:16024] CHIP:TOO: [2]: { - [1690188996.754606][16022:16024] CHIP:TOO: Value: 8 - [1690188996.754615][16022:16024] CHIP:TOO: } - [1690188996.754629][16022:16024] CHIP:TOO: [3]: { - [1690188996.754638][16022:16024] CHIP:TOO: Value: 2 - [1690188996.754646][16022:16024] CHIP:TOO: } - [1690188996.754654][16022:16024] CHIP:TOO: } - disabled: true - - - label: - "Step 4: TH writes to the DUT the StartUpMode attribute with the - new_start_up_mode_th value" - PICS: DISHM.S.A0002 - verification: | - ./chip-tool dishwashermode write start-up-mode 0 1 1 - - On TH(chip-tool) log, Verify that DUT responds with a successful (value 0x00) status response and below is the sample log provided for the raspi platform: - - [1690188912.259778][16011:16013] CHIP:DMG: { - [1690188912.259790][16011:16013] CHIP:DMG: status = 0x00 (SUCCESS), - [1690188912.259800][16011:16013] CHIP:DMG: }, - [1690188912.259813][16011:16013] CHIP:DMG: - - ./chip-tool dishwashermode read start-up-mode 1 1 - - On TH(chip-tool), Verify that StartUpMode attribute value is 0 and below is the sample log provided for the raspi platform . - - [1692171314.157274][3112:3114] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0059 Attribute 0x0000_0002 DataVersion: 2502960195 - [1692171314.157331][3112:3114] CHIP:TOO: StartUpMode: 0 - disabled: true - - - label: "Step 5: TH reads from the DUT the CurrentMode attribute." - PICS: DISHM.S.A0001 - verification: | - ./chip-tool dishwashermode read current-mode 1 1 - - On TH(chip-tool), Verify that CurrentMode attribute value is an integer value - - Save the value as old_current_mode_dut, below is the sample log provided for the raspi platform, Here CurrentMode attribute value is 0 - - NOTE: If startup_mode_dut is equal to old_current_mode_dut proceed to step 6. Else proceed to step 8. - - [1690189040.789208][16040:16042] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0059 Attribute 0x0000_0001 DataVersion: 1012425326 - [1690189040.789223][16040:16042] CHIP:TOO: CurrentMode: 0 - disabled: true - - - label: "Step 6: TH reads from the DUT the SupportedModes attribute." - PICS: DISHM.S.A0000 - verification: | - ./chip-tool dishwashermode read supported-modes 1 1 - - On TH(chip-tool) log, Verify DUT response contains a list of ModeOptionsStruct entries - - Verify that the list has two or more entries - - Save the Mode field values as supported_modes_dut - - Select a value from supported_modes_dut different from startup_mode_dut. Save the value as new_mode_th, below is the sample log provided for the raspi platform: - - [1690188996.754102][16022:16024] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0059 Attribute 0x0000_0000 DataVersion: 74242738 - [1690188996.754208][16022:16024] CHIP:TOO: SupportedModes: 3 entries - [1690188996.754248][16022:16024] CHIP:TOO: [1]: { - [1690188996.754258][16022:16024] CHIP:TOO: Label: Normal - [1690188996.754270][16022:16024] CHIP:TOO: Mode: 0 - [1690188996.754285][16022:16024] CHIP:TOO: ModeTags: 1 entries - [1690188996.754302][16022:16024] CHIP:TOO: [1]: { - [1690188996.754314][16022:16024] CHIP:TOO: Value: 16384 - [1690188996.754325][16022:16024] CHIP:TOO: } - [1690188996.754336][16022:16024] CHIP:TOO: } - [1690188996.754360][16022:16024] CHIP:TOO: [2]: { - [1690188996.754369][16022:16024] CHIP:TOO: Label: Heavy - [1690188996.754378][16022:16024] CHIP:TOO: Mode: 1 - [1690188996.754393][16022:16024] CHIP:TOO: ModeTags: 2 entries - [1690188996.754407][16022:16024] CHIP:TOO: [1]: { - [1690188996.754416][16022:16024] CHIP:TOO: Value: 7 - [1690188996.754425][16022:16024] CHIP:TOO: } - [1690188996.754439][16022:16024] CHIP:TOO: [2]: { - [1690188996.754450][16022:16024] CHIP:TOO: Value: 16385 - [1690188996.754459][16022:16024] CHIP:TOO: } - [1690188996.754469][16022:16024] CHIP:TOO: } - [1690188996.754493][16022:16024] CHIP:TOO: [3]: { - [1690188996.754501][16022:16024] CHIP:TOO: Label: Light - [1690188996.754511][16022:16024] CHIP:TOO: Mode: 2 - [1690188996.754548][16022:16024] CHIP:TOO: ModeTags: 3 entries - [1690188996.754564][16022:16024] CHIP:TOO: [1]: { - [1690188996.754574][16022:16024] CHIP:TOO: Value: 16386 - [1690188996.754583][16022:16024] CHIP:TOO: } - [1690188996.754597][16022:16024] CHIP:TOO: [2]: { - [1690188996.754606][16022:16024] CHIP:TOO: Value: 8 - [1690188996.754615][16022:16024] CHIP:TOO: } - [1690188996.754629][16022:16024] CHIP:TOO: [3]: { - [1690188996.754638][16022:16024] CHIP:TOO: Value: 2 - [1690188996.754646][16022:16024] CHIP:TOO: } - [1690188996.754654][16022:16024] CHIP:TOO: } - disabled: true - - - label: - "Step 7: TH sends a ChangeToMode command to the DUT with NewMode set - to new_mode_th" - PICS: DISHM.S.C00.Rsp - verification: | - ./chip-tool dishwashermode change-to-mode 2 1 1 - - Verify on TH(chip-tool) log, DUT responds contains a ChangeToModeResponse command with a SUCCESS (value 0x00) status response and below is the sample log provided for the raspi platform: - - [1690265961.529808][30174:30176] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0059 Command 0x0000_0001 - [1690265961.529857][30174:30176] CHIP:TOO: ChangeToModeResponse: { - [1690265961.529880][30174:30176] CHIP:TOO: status: 0 - [1690265961.529891][30174:30176] CHIP:TOO: } - disabled: true - - - label: "Step 8: Physically power cycle the device" - verification: | - Physically power cycle the device. - disabled: true - - - label: "Step 9: TH reads from the DUT the StartUpMode attribute." - PICS: DISHM.S.A0002 - verification: | - ./chip-tool dishwashermode read start-up-mode 1 1 - - On TH(chip-tool), Verify StartUpMode attribute value is an integer. - - Save the value as new_start_up_mode_dut and is equal to new_start_up_mode_th, below is the sample log provided for the raspi platform, Here StartUpMode value is 0 - - [1690188941.380388][16015:16017] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0059 Attribute 0x0000_0002 DataVersion: 74242738 - [1690188941.380430][16015:16017] CHIP:TOO: StartUpMode: 0 - disabled: true - - - label: "Step 10: TH reads from the DUT the CurrentMode attribute." - PICS: DISHM.S.A0001 - verification: | - ./chip-tool dishwashermode read current-mode 1 1 - - On TH(chip-tool), Verify that CurrentMode attribute value is an integer value and is equal to new_start_up_mode_dut, below is the sample log provided for the raspi platform, Here CurrentMode attribute value is 0 - - [1690189040.789208][16040:16042] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0059 Attribute 0x0000_0001 DataVersion: 1012425326 - [1690189040.789223][16040:16042] CHIP:TOO: CurrentMode: 0 - disabled: true diff --git a/src/app/tests/suites/certification/Test_TC_DISHM_3_3.yaml b/src/app/tests/suites/certification/Test_TC_DISHM_3_3.yaml deleted file mode 100644 index c9e788d45a6eef..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_DISHM_3_3.yaml +++ /dev/null @@ -1,274 +0,0 @@ -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# Auto-generated scripts for harness use only, please review before automation. The endpoints and cluster names are currently set to default - -name: - 189.3.3.[TC-DISHM-3.3] On Mode and Startup Mode functionality with DUT as - Server - -PICS: - - DISHM.S.A0002 - - DISHM.S.A0003 - - MOD.S.F00 - - OO.S.A4003 - -config: - nodeId: 0x12344321 - cluster: "Basic Information" - endpoint: 0 - -tests: - - label: "Note" - verification: | - To Execute the TC-DISH-3.3 test case using reboot in raspi device we followed the below suggested way: - - To run a reboot test case on raspi, run the app with --KVS flag with a file in local directory and pass that file to the command to launch the app. Steps - - step-1: create a file using touch command , something like touch mytest.txt - step-2: chmod 777 mytest.txt - step-3: launch the app ./chip-all-clusters-app --KVS ./mytest.txt - - if you launch the app with the above commands and provision the app, even when you reboot the app with 'sudo reboot' , next time you launch the app with 'sudo ./out/all-clusters-app/chip-all-clusters-app --KVS ./mytest.txt' , you can run read/write attribs and commands without reprovisioning the device. - disabled: true - - - label: - "Step 1: Commission DUT to TH (can be skipped if done in a preceding - test)." - verification: | - - disabled: true - - - label: "Step 2: TH reads from the DUT the StartUpMode attribute." - PICS: DISHM.S.A0002 - verification: | - ./chip-tool dishwashermode read start-up-mode 1 1 - - On TH(chip-tool), Verify that StartUpMode attribute value is an integer or Null - - Save the value as startup_mode_dut, below is the sample log provided for the raspi platform, Here StartUpMode attribute value is null - - NOTE: if startup_mode_dut is null proceed to step 3. Else save startup_mode_dut as new_start_up_mode_th and proceed to step 5. - - [1651099663211] [82177:7560652] CHIP: [TOO] Endpoint: 1 Cluster: 0x0000_0050 Attribute 0x0000_0004 DataVersion: 2609052118 - [1651099663212] [82177:7560652] CHIP: [TOO] StartUpMode: null - disabled: true - - - label: "Step 3: TH reads from the DUT the SupportedModes attribute." - PICS: DISHM.S.A0000 - verification: | - ./chip-tool dishwashermode read supported-modes 1 1 - - On TH(chip-tool) log, Verify DUT response contains a list of ModeOptionsStruct entries - - Verify that the list has two or more entries - - Save the Mode field values as supported_modes_dut - - Select a value from supported_modes_dut and save the value as new_start_up_mode_th, below is the sample log provided for the raspi platform: - - [1690189296.612007][16077:16079] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0059 Attribute 0x0000_0000 DataVersion: 1012425327 - [1690189296.612104][16077:16079] CHIP:TOO: SupportedModes: 3 entries - [1690189296.612139][16077:16079] CHIP:TOO: [1]: { - [1690189296.612149][16077:16079] CHIP:TOO: Label: Normal - [1690189296.612168][16077:16079] CHIP:TOO: Mode: 0 - [1690189296.612189][16077:16079] CHIP:TOO: ModeTags: 1 entries - [1690189296.612214][16077:16079] CHIP:TOO: [1]: { - [1690189296.612224][16077:16079] CHIP:TOO: Value: 16384 - [1690189296.612234][16077:16079] CHIP:TOO: } - [1690189296.612243][16077:16079] CHIP:TOO: } - [1690189296.612264][16077:16079] CHIP:TOO: [2]: { - [1690189296.612273][16077:16079] CHIP:TOO: Label: Heavy - [1690189296.612282][16077:16079] CHIP:TOO: Mode: 1 - [1690189296.612296][16077:16079] CHIP:TOO: ModeTags: 2 entries - [1690189296.612309][16077:16079] CHIP:TOO: [1]: { - [1690189296.612318][16077:16079] CHIP:TOO: Value: 7 - [1690189296.612327][16077:16079] CHIP:TOO: } - [1690189296.612339][16077:16079] CHIP:TOO: [2]: { - [1690189296.612348][16077:16079] CHIP:TOO: Value: 16385 - [1690189296.612356][16077:16079] CHIP:TOO: } - [1690189296.612365][16077:16079] CHIP:TOO: } - [1690189296.612384][16077:16079] CHIP:TOO: [3]: { - [1690189296.612392][16077:16079] CHIP:TOO: Label: Light - [1690189296.612398][16077:16079] CHIP:TOO: Mode: 2 - [1690189296.612413][16077:16079] CHIP:TOO: ModeTags: 3 entries - [1690189296.612425][16077:16079] CHIP:TOO: [1]: { - [1690189296.612433][16077:16079] CHIP:TOO: Value: 16386 - [1690189296.612443][16077:16079] CHIP:TOO: } - [1690189296.612456][16077:16079] CHIP:TOO: [2]: { - [1690189296.612465][16077:16079] CHIP:TOO: Value: 8 - [1690189296.612473][16077:16079] CHIP:TOO: } - [1690189296.612485][16077:16079] CHIP:TOO: [3]: { - [1690189296.612494][16077:16079] CHIP:TOO: Value: 2 - [1690189296.612502][16077:16079] CHIP:TOO: } - [1690189296.612511][16077:16079] CHIP:TOO: } - disabled: true - - - label: - "Step 4: TH writes to the DUT the StartUpMode attribute with the - new_start_up_mode_th value" - PICS: DISHM.S.A0002 - verification: | - ./chip-tool dishwashermode write start-up-mode 0 1 1 - - On TH(chip-tool) log, Verify that DUT responds with a successful (value 0x00) status response and below is the sample log provided for the raspi platform: - - [1690188912.259766][16011:16013] CHIP:DMG: StatusIB = - [1690188912.259778][16011:16013] CHIP:DMG: { - [1690188912.259790][16011:16013] CHIP:DMG: status = 0x00 (SUCCESS), - [1690188912.259800][16011:16013] CHIP:DMG: }, - [1690188912.259813][16011:16013] CHIP:DMG: - - ./chip-tool dishwashermode read start-up-mode 1 1 - - On TH(chip-tool), Verify that StartUpMode attribute value is 0 and below is the sample log provided for the raspi platform . - - [1692171314.157274][3112:3114] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0059 Attribute 0x0000_0002 DataVersion: 2502960195 - [1692171314.157331][3112:3114] CHIP:TOO: StartUpMode: 0 - disabled: true - - - label: "Step 5: TH reads from the DUT the OnMode attribute." - PICS: DISHM.S.A0003 && DISHM.S.A0002 - verification: | - As default value of OnMode attribute is NULL. Set the OnMode to any mode value listed in the SupportedModes entries. - - ./chip-tool dishwashermode write on-mode 0 1 1 - - On TH(chip-tool) log, Verify that DUT responds with a successful (value 0x00) status response and below is the sample log provided for the raspi platform: - - [1690189187.414225][16062:16064] CHIP:DMG: StatusIB = - [1690189187.414237][16062:16064] CHIP:DMG: { - [1690189187.414249][16062:16064] CHIP:DMG: status = 0x00 (SUCCESS), - [1690189187.414260][16062:16064] CHIP:DMG: }, - - - ./chip-tool dishwashermode read on-mode 1 1 - - On TH(chip-tool), Verify that OnMode attribute value is an integer value - - Save the value as old_on_mode_dut, below is the sample log provided for the raspi platform, here OnMode attribute value is 0 - - NOTE: If startup_mode_dut is equal to old_on_mode_dut proceed to step 6. Else proceed to step 8. - - [1690189501.554415][16104:16106] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0059 Attribute 0x0000_0003 DataVersion: 1012425329 - [1690189501.554429][16104:16106] CHIP:TOO: OnMode: 0 - disabled: true - - - label: "Step 6: TH reads from the DUT the SupportedModes attribute." - PICS: DISHM.S.A0000 && DISHM.S.A0002 - verification: | - ./chip-tool dishwashermode read supported-modes 1 1 - - On TH(chip-tool) log, Verify DUT response contains a list of ModeOptionsStruct entries - - Verify that the list has two or more entries - - Save the Mode field values as supported_modes_dut - - Select a value from supported_modes_dut different from startup_mode_dut. Save the value as new_mode_th, below is the sample log provided for the raspi platform: - - [1690189296.612007][16077:16079] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0059 Attribute 0x0000_0000 DataVersion: 1012425327 - [1690189296.612104][16077:16079] CHIP:TOO: SupportedModes: 3 entries - [1690189296.612139][16077:16079] CHIP:TOO: [1]: { - [1690189296.612149][16077:16079] CHIP:TOO: Label: Normal - [1690189296.612168][16077:16079] CHIP:TOO: Mode: 0 - [1690189296.612189][16077:16079] CHIP:TOO: ModeTags: 1 entries - [1690189296.612214][16077:16079] CHIP:TOO: [1]: { - [1690189296.612224][16077:16079] CHIP:TOO: Value: 16384 - [1690189296.612234][16077:16079] CHIP:TOO: } - [1690189296.612243][16077:16079] CHIP:TOO: } - [1690189296.612264][16077:16079] CHIP:TOO: [2]: { - [1690189296.612273][16077:16079] CHIP:TOO: Label: Heavy - [1690189296.612282][16077:16079] CHIP:TOO: Mode: 1 - [1690189296.612296][16077:16079] CHIP:TOO: ModeTags: 2 entries - [1690189296.612309][16077:16079] CHIP:TOO: [1]: { - [1690189296.612318][16077:16079] CHIP:TOO: Value: 7 - [1690189296.612327][16077:16079] CHIP:TOO: } - [1690189296.612339][16077:16079] CHIP:TOO: [2]: { - [1690189296.612348][16077:16079] CHIP:TOO: Value: 16385 - [1690189296.612356][16077:16079] CHIP:TOO: } - [1690189296.612365][16077:16079] CHIP:TOO: } - [1690189296.612384][16077:16079] CHIP:TOO: [3]: { - [1690189296.612392][16077:16079] CHIP:TOO: Label: Light - [1690189296.612398][16077:16079] CHIP:TOO: Mode: 2 - [1690189296.612413][16077:16079] CHIP:TOO: ModeTags: 3 entries - [1690189296.612425][16077:16079] CHIP:TOO: [1]: { - [1690189296.612433][16077:16079] CHIP:TOO: Value: 16386 - [1690189296.612443][16077:16079] CHIP:TOO: } - [1690189296.612456][16077:16079] CHIP:TOO: [2]: { - [1690189296.612465][16077:16079] CHIP:TOO: Value: 8 - [1690189296.612473][16077:16079] CHIP:TOO: } - [1690189296.612485][16077:16079] CHIP:TOO: [3]: { - [1690189296.612494][16077:16079] CHIP:TOO: Value: 2 - [1690189296.612502][16077:16079] CHIP:TOO: } - [1690189296.612511][16077:16079] CHIP:TOO: } - disabled: true - - - label: - "Step 7: TH writes to the DUT the OnMode attribute with the - new_mode_th value" - PICS: DISHM.S.A0003 - verification: | - ./chip-tool dishwashermode write on-mode 2 1 1 - - On TH(chip-tool) log, Verify DUT responds with a successful (value 0x00) status response and below is the sample log provided for the raspi platform: - - [1690189470.746137][16086:16088] CHIP:DMG: { - [1690189470.746140][16086:16088] CHIP:DMG: status = 0x00 (SUCCESS), - [1690189470.746142][16086:16088] CHIP:DMG: }, - disabled: true - - - label: "Step 8: TH reads from the DUT the OnMode attribute." - PICS: DISHM.S.A0003 && MOD.S.F00 - verification: | - ./chip-tool dishwashermode read on-mode 1 1 - - On TH(chip-tool), Verify that OnMode attribute value is an integer - - Save the value as new_on_mode_dut and is equal to new_mode_th and below is the sample log provided for the raspi platform, here OnMode attribute value is 2 - - [1690189501.554415][16104:16106] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0059 Attribute 0x0000_0003 DataVersion: 1012425329 - [1690189501.554429][16104:16106] CHIP:TOO: OnMode: 2 - disabled: true - - - label: - "Step 9: TH writes to the DUT the StartUpOnOff attribute with the - value 1." - PICS: OO.S.A4003 - verification: | - ./chip-tool onoff write start-up-on-off 1 1 1 - - On TH(chip-tool) log, Verify DUT responds with a successful (value 0x00) status response and below is the sample log provided for the raspi platform: - - [1651101661960] [90832:7598169] CHIP: [DMG] { - [1651101661960] [90832:7598169] CHIP: [DMG] status = 0x00 (SUCCESS), - [1651101661960] [90832:7598169] CHIP: [DMG] }, - disabled: true - - - label: "Step 10: Physically power cycle the device" - verification: | - Physically power cycle the device. - disabled: true - - - label: "Step 11: TH reads from the DUT the StartUpMode attribute." - PICS: DISHM.S.A0002 - verification: | - ./chip-tool dishwashermode read start-up-mode 1 1 - - On TH(chip-tool), Verify that StartUpMode attribute value is an integer and is equal to new_start_up_mode_th, below is the sample log provided for the raspi platform, Here StartUpMode attribute value is 0 - - [1651099663211] [82177:7560652] CHIP: [TOO] Endpoint: 1 Cluster: 0x0000_0050 Attribute 0x0000_0004 DataVersion: 2609052118 - [1651099663212] [82177:7560652] CHIP: [TOO] StartUpMode: 0 - disabled: true - - - label: "Step 12: TH reads from the DUT the CurrentMode attribute." - PICS: DISHM.S.A0001 - verification: | - ./chip-tool dishwashermode read current-mode 1 1 - - On TH(chip-tool), Verify that CurrentMode attribute value is an integer value and is equal to new_on_mode_dut, below is the sample log provided for the raspi platform, Here CurrentMode attribute value is 2 - - [1690189536.790233][16118:16120] CHIP:TOO: Endpoint: 1 Cluster: 0x0000_0059 Attribute 0x0000_0001 DataVersion: 4080703118 - [1690189536.790280][16118:16120] CHIP:TOO: CurrentMode: 2 - disabled: true diff --git a/src/app/tests/suites/certification/Test_TC_LWM_3_1.yaml b/src/app/tests/suites/certification/Test_TC_LWM_3_1.yaml deleted file mode 100644 index 2bafddfa303f64..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_LWM_3_1.yaml +++ /dev/null @@ -1,134 +0,0 @@ -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -name: 183.3.1. [TC-LWM-3.1] On Mode functionality with DUT as Server - -PICS: - - LWM.S.A0003 - - MOD.S.F00 - - OO.S.C00.Rsp - - OO.S.C01.Rsp - -config: - nodeId: 0x12344321 - cluster: "Laundry Washer Mode" - endpoint: 1 - - ConfigureOnMode: - type: int8u - defaultValue: 0 - new_mode_th: - type: int8u - defaultValue: 2 - -tests: - - label: - "Step 1: Commission DUT to TH (can be skipped if done in a preceding - test)." - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: - "Precondition: TH writes from the DUT the OnMode attribute.NOTE: To - execute this test case set onmode to any integer value because as - default it value has null." - PICS: LWM.S.A0003 && MOD.S.F00 - command: "writeAttribute" - attribute: "OnMode" - arguments: - value: ConfigureOnMode - - - label: "Step 2: TH reads from the DUT the OnMode attribute." - PICS: LWM.S.A0003 && MOD.S.F00 - command: "readAttribute" - attribute: "OnMode" - response: - saveAs: on_mode_dut - constraints: - type: int8u - minValue: 0 - maxValue: 254 - - - label: "Step 3: TH reads from the DUT the CurrentMode attribute." - PICS: LWM.S.A0001 && MOD.S.F00 - command: "readAttribute" - attribute: "CurrentMode" - response: - saveAs: old_current_mode_dut - constraints: - type: int8u - minValue: 0 - maxValue: 254 - - - label: - "If on_mode_dut is equal to old_current_mode_dut proceed to step 4. - Else proceed to step 6." - cluster: "EqualityCommands" - command: "UnsignedNumberEquals" - arguments: - values: - - name: "Value1" - value: on_mode_dut - - name: "Value2" - value: old_current_mode_dut - response: - - values: - - name: "Equals" - saveAs: IsExpectedValue - - - label: "Step 4: TH reads from the DUT the SupportedModes attribute." - runIf: IsExpectedValue - PICS: LWM.S.A0000 && MOD.S.F00 - command: "readAttribute" - attribute: "SupportedModes" - response: - constraints: - type: list - minLength: 2 - - - label: - "Step 5: TH sends a ChangeToMode command to the DUT with NewMode set - to new_mode_th" - runIf: IsExpectedValue - PICS: LWM.S.C00.Rsp && MOD.S.F00 - command: "ChangeToMode" - arguments: - values: - - name: "NewMode" - value: new_mode_th - response: - values: - - name: "Status" - value: 0x00 - - - label: "Step 6:TH sends a Off command to the DUT" - PICS: OO.S.C00.Rsp && MOD.S.F00 - cluster: "On/Off" - command: "Off" - - - label: "Step 7:TH sends a On command to the DUT" - PICS: OO.S.C01.Rsp && MOD.S.F00 - cluster: "On/Off" - command: "On" - - - label: "Step 8: TH reads from the DUT the CurrentMode attribute." - PICS: LWM.S.A0001 && MOD.S.F00 - command: "readAttribute" - attribute: "CurrentMode" - response: - value: on_mode_dut diff --git a/src/app/tests/suites/certification/Test_TC_LWM_3_2.yaml b/src/app/tests/suites/certification/Test_TC_LWM_3_2.yaml deleted file mode 100644 index fe8ff87e214e18..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_LWM_3_2.yaml +++ /dev/null @@ -1,172 +0,0 @@ -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -name: 183.3.2. [TC-LWM-3.2] Startup Mode functionality with DUT as Server - -PICS: - - LWM.S.A0002 - -config: - nodeId: 0x12344321 - cluster: "Laundry Washer Mode" - endpoint: 1 - - new_start_up_mode_th: - type: int8u - defaultValue: 0 - new_mode_th: - type: int8u - defaultValue: 1 - -tests: - - label: - "Step 1: Commission DUT to TH (can be skipped if done in a preceding - test)." - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: TH reads from the DUT the StartUpMode attribute." - PICS: LWM.S.A0002 - command: "readAttribute" - attribute: "StartUpMode" - response: - saveAs: startup_mode_dut - - - label: - "Step 2: If startup_mode_dut is null proceed to step 3. Else save - startup_mode_dut as new_start_up_mode_th and proceed to step 5." - PICS: LWM.S.A0002 - cluster: "EqualityCommands" - command: "UnsignedNumberEquals" - arguments: - values: - - name: "Value1" - value: startup_mode_dut - - name: "Value2" - value: null - response: - - values: - - name: "Equals" - saveAs: IsExpectedValue - - - label: "Step 3: TH reads from the DUT the SupportedModes attribute." - runIf: IsExpectedValue - PICS: LWM.S.A0000 - command: "readAttribute" - attribute: "SupportedModes" - response: - saveAs: supported_modes_dut - constraints: - type: list - minLength: 2 - - label: - "Step 4: TH writes to the DUT the StartUpMode attribute with the - new_start_up_mode_th value" - PICS: LWM.S.A0002 - runIf: IsExpectedValue - command: "writeAttribute" - attribute: "StartUpMode" - arguments: - value: new_start_up_mode_th - - - label: "Step 5: TH reads from the DUT the CurrentMode attribute." - PICS: LWM.S.A0001 - command: "readAttribute" - attribute: "CurrentMode" - response: - saveAs: old_current_mode_dut - - - label: - "Step 5: If startup_mode_dut is equal to old_current_mode_dut proceed - to step 6. Else proceed to step 8." - PICS: LWM.S.A0001 && LWM.S.A0002 - cluster: "EqualityCommands" - command: "UnsignedNumberEquals" - arguments: - values: - - name: "Value1" - value: startup_mode_dut - - name: "Value2" - value: old_current_mode_dut - response: - - values: - - name: "Equals" - saveAs: Step5_IsExpectedValue - - - label: "Step 6: TH reads from the DUT the SupportedModes attribute." - PICS: LWM.S.A0000 - runIf: Step5_IsExpectedValue - command: "readAttribute" - attribute: "SupportedModes" - response: - saveAs: Step6_supported_modes_dut - constraints: - type: list - minLength: 2 - - - label: - "Step 7: TH sends a ChangeToMode command to the DUT with NewMode set - to new_mode_th" - PICS: LWM.S.C00.Rsp - runIf: Step5_IsExpectedValue - command: "ChangeToMode" - arguments: - values: - - name: "NewMode" - value: new_mode_th - response: - values: - - name: "Status" - value: 0x00 - - - label: "Step 8: Physically power cycle the device" - verification: | - Physically power cycle the device. - cluster: "LogCommands" - command: "UserPrompt" - PICS: PICS_USER_PROMPT - arguments: - values: - - name: "message" - value: "Please enter 'y' for success" - - name: "expectedValue" - value: "y" - - - label: "Wait for the commissioned device to be retrieved" - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 9: TH reads from the DUT the StartUpMode attribute." - PICS: LWM.S.A0002 && PICS_USER_PROMPT - command: "readAttribute" - attribute: "StartUpMode" - response: - saveAs: new_start_up_mode_dut - constraints: - anyOf: [startup_mode_dut, new_start_up_mode_th] - - - label: "Step 10: TH reads from the DUT the CurrentMode attribute." - PICS: LWM.S.A0001 && PICS_USER_PROMPT - command: "readAttribute" - attribute: "CurrentMode" - response: - value: new_start_up_mode_dut diff --git a/src/app/tests/suites/certification/Test_TC_LWM_3_3.yaml b/src/app/tests/suites/certification/Test_TC_LWM_3_3.yaml deleted file mode 100644 index bf97f17f286154..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_LWM_3_3.yaml +++ /dev/null @@ -1,189 +0,0 @@ -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -name: - 183.3.3. [TC-LWM-3.3] On Mode and Startup Mode functionality with DUT as - Server - -PICS: - - LWM.S.A0002 - - LWM.S.A0003 - - MOD.S.F00 - - OO.S.A4003 - -config: - nodeId: 0x12344321 - cluster: "Laundry Washer Mode" - endpoint: 1 - - new_start_up_mode_th: - type: int8u - defaultValue: 0 - new_mode_th: - type: int8u - defaultValue: 1 - -tests: - - label: - "Step 1: Commission DUT to TH (can be skipped if done in a preceding - test)." - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: TH reads from the DUT the StartUpMode attribute." - PICS: LWM.S.A0002 - command: "readAttribute" - attribute: "StartUpMode" - response: - saveAs: startup_mode_dut - - - label: - "Step 2: If startup_mode_dut is null proceed to step 3. Else save - startup_mode_dut as new_start_up_mode_th and proceed to step 5." - PICS: LWM.S.A0002 - cluster: "EqualityCommands" - command: "UnsignedNumberEquals" - arguments: - values: - - name: "Value1" - value: startup_mode_dut - - name: "Value2" - value: null - response: - - values: - - name: "Equals" - saveAs: IsExpectedValue - - - label: "Step 3: TH reads from the DUT the SupportedModes attribute." - runIf: IsExpectedValue - PICS: LWM.S.A0000 - command: "readAttribute" - attribute: "SupportedModes" - response: - saveAs: supported_modes_dut - constraints: - type: list - minLength: 2 - - - label: - "Step 4: TH writes to the DUT the StartUpMode attribute with the - new_start_up_mode_th value" - PICS: LWM.S.A0002 - runIf: IsExpectedValue - command: "writeAttribute" - attribute: "StartUpMode" - arguments: - value: new_start_up_mode_th - - - label: "Step 5: TH reads from the DUT the OnMode attribute." - PICS: LWM.S.A0003 && LWM.S.A0002 - command: "readAttribute" - attribute: "OnMode" - response: - saveAs: old_on_mode_dut - - - label: - "Step 5: If startup_mode_dut is equal to old_on_mode_dut proceed to - step 6. Else proceed to step 8." - PICS: LWM.S.A0002 - cluster: "EqualityCommands" - command: "UnsignedNumberEquals" - arguments: - values: - - name: "Value1" - value: old_on_mode_dut - - name: "Value2" - value: startup_mode_dut - response: - - values: - - name: "Equals" - saveAs: Step5_IsExpectedValue - - - label: "Step 6: TH reads from the DUT the SupportedModes attribute." - PICS: LWM.S.A0000 && LWM.S.A0002 - runIf: Step5_IsExpectedValue - command: "readAttribute" - attribute: "SupportedModes" - response: - saveAs: Step6_supported_modes_dut - constraints: - type: list - minLength: 2 - - - label: - "Step 7: TH writes to the DUT the OnMode attribute with the - new_mode_th value" - PICS: LWM.S.A0003 - runIf: Step5_IsExpectedValue - command: "writeAttribute" - attribute: "OnMode" - arguments: - value: new_mode_th - - - label: "Step 8: TH reads from the DUT the OnMode attribute." - PICS: LWM.S.A0003 && MOD.S.F00 - command: "readAttribute" - attribute: "OnMode" - response: - saveAs: new_on_mode_dut - - - label: - "Step 9: TH writes to the DUT the StartUpOnOff attribute with the - value 1." - PICS: OO.S.A4003 - cluster: "On/Off" - command: "writeAttribute" - attribute: "StartUpOnOff" - arguments: - value: 1 - - - label: "Step 10: Physically power cycle the device" - verification: | - Physically power cycle the device. - cluster: "LogCommands" - command: "UserPrompt" - PICS: PICS_USER_PROMPT - arguments: - values: - - name: "message" - value: "Please enter 'y' for success" - - name: "expectedValue" - value: "y" - - - label: "Wait for the commissioned device to be retrieved" - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 11: TH reads from the DUT the StartUpMode attribute." - PICS: LWM.S.A0002 && PICS_USER_PROMPT - command: "readAttribute" - attribute: "StartUpMode" - response: - constraints: - anyOf: [new_start_up_mode_th, startup_mode_dut] - - - label: "Step 12: TH reads from the DUT the CurrentMode attribute." - PICS: LWM.S.A0001 && PICS_USER_PROMPT - command: "readAttribute" - attribute: "CurrentMode" - response: - value: new_on_mode_dut diff --git a/src/app/tests/suites/certification/Test_TC_MOD_1_3.yaml b/src/app/tests/suites/certification/Test_TC_MOD_1_3.yaml deleted file mode 100644 index 51f389b6afaffc..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_MOD_1_3.yaml +++ /dev/null @@ -1,722 +0,0 @@ -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# Auto-generated scripts for harness use only, please review before automation. The endpoints and cluster names are currently set to default - -name: 81.1.3. [TC-MOD-1.3] Attributes with client as DUT - -PICS: - - MOD.C - - MOD.C.AM-READ - - MOD.C.AO-READ - - MOD.C.AM-WRITE - - MOD.C.AO-WRITE - -config: - nodeId: 0x12344321 - cluster: "Basic Information" - endpoint: 0 - -tests: - - label: - "Step 1: DUT reads all supported mandatory attributes from TH one at a - time in a manufacturer specific order" - PICS: MOD.C.AM-READ - verification: | - ./chip-tool modeselect read supported-modes 1 1 - - Verify the "SupportedModes response" on the TH (all-cluster-app) log: - - [1666940683.282921][9718:9718] CHIP:DMG: ReportDataMessage = - [1666940683.282923][9718:9718] CHIP:DMG: { - [1666940683.282925][9718:9718] CHIP:DMG: AttributeReportIBs = - [1666940683.282928][9718:9718] CHIP:DMG: [ - [1666940683.282929][9718:9718] CHIP:DMG: AttributeReportIB = - [1666940683.282933][9718:9718] CHIP:DMG: { - [1666940683.282935][9718:9718] CHIP:DMG: AttributeDataIB = - [1666940683.282937][9718:9718] CHIP:DMG: { - [1666940683.282939][9718:9718] CHIP:DMG: DataVersion = 0xb4a9126f, - [1666940683.282941][9718:9718] CHIP:DMG: AttributePathIB = - [1666940683.282944][9718:9718] CHIP:DMG: { - [1666940683.282946][9718:9718] CHIP:DMG: Endpoint = 0x1, - [1666940683.282948][9718:9718] CHIP:DMG: Cluster = 0x50, - [1666940683.282950][9718:9718] CHIP:DMG: Attribute = 0x0000_0002, - [1666940683.282952][9718:9718] CHIP:DMG: } - [1666940683.282955][9718:9718] CHIP:DMG: - [1666940683.282957][9718:9718] CHIP:DMG: Data = [ - [1666940683.282959][9718:9718] CHIP:DMG: - [1666940683.282962][9718:9718] CHIP:DMG: ], - [1666940683.282964][9718:9718] CHIP:DMG: }, - [1666940683.282966][9718:9718] CHIP:DMG: - [1666940683.282968][9718:9718] CHIP:DMG: }, - [1666940683.282972][9718:9718] CHIP:DMG: - [1666940683.282974][9718:9718] CHIP:DMG: AttributeReportIB = - [1666940683.282978][9718:9718] CHIP:DMG: { - [1666940683.282980][9718:9718] CHIP:DMG: AttributeDataIB = - [1666940683.282982][9718:9718] CHIP:DMG: { - [1666940683.282984][9718:9718] CHIP:DMG: DataVersion = 0xb4a9126f, - [1666940683.282986][9718:9718] CHIP:DMG: AttributePathIB = - [1666940683.282988][9718:9718] CHIP:DMG: { - [1666940683.282990][9718:9718] CHIP:DMG: Endpoint = 0x1, - [1666940683.282992][9718:9718] CHIP:DMG: Cluster = 0x50, - [1666940683.282995][9718:9718] CHIP:DMG: Attribute = 0x0000_0002, - [1666940683.282997][9718:9718] CHIP:DMG: ListIndex = Null, - [1666940683.282999][9718:9718] CHIP:DMG: } - [1666940683.283001][9718:9718] CHIP:DMG: - [1666940683.283003][9718:9718] CHIP:DMG: Data = - [1666940683.283005][9718:9718] CHIP:DMG: { - [1666940683.283008][9718:9718] CHIP:DMG: 0x0 = "Black" (5 chars), - [1666940683.283011][9718:9718] CHIP:DMG: 0x1 = 0, - [1666940683.283013][9718:9718] CHIP:DMG: 0x2 = [ - [1666940683.283015][9718:9718] CHIP:DMG: - [1666940683.283020][9718:9718] CHIP:DMG: { - [1666940683.283022][9718:9718] CHIP:DMG: 0x0 = 0, - [1666940683.283025][9718:9718] CHIP:DMG: 0x1 = 0, - [1666940683.283027][9718:9718] CHIP:DMG: }, - [1666940683.283030][9718:9718] CHIP:DMG: ], - [1666940683.283032][9718:9718] CHIP:DMG: }, - [1666940683.283034][9718:9718] CHIP:DMG: }, - [1666940683.283037][9718:9718] CHIP:DMG: - [1666940683.283039][9718:9718] CHIP:DMG: }, - [1666940683.283044][9718:9718] CHIP:DMG: - [1666940683.283046][9718:9718] CHIP:DMG: AttributeReportIB = - [1666940683.283049][9718:9718] CHIP:DMG: { - [1666940683.283051][9718:9718] CHIP:DMG: AttributeDataIB = - [1666940683.283053][9718:9718] CHIP:DMG: { - [1666940683.283055][9718:9718] CHIP:DMG: DataVersion = 0xb4a9126f, - [1666940683.283057][9718:9718] CHIP:DMG: AttributePathIB = - [1666940683.283059][9718:9718] CHIP:DMG: { - [1666940683.283061][9718:9718] CHIP:DMG: Endpoint = 0x1, - [1666940683.283064][9718:9718] CHIP:DMG: Cluster = 0x50, - [1666940683.283066][9718:9718] CHIP:DMG: Attribute = 0x0000_0002, - [1666940683.283068][9718:9718] CHIP:DMG: ListIndex = Null, - [1666940683.283070][9718:9718] CHIP:DMG: } - [1666940683.283072][9718:9718] CHIP:DMG: - [1666940683.283074][9718:9718] CHIP:DMG: Data = - [1666940683.283076][9718:9718] CHIP:DMG: { - [1666940683.283079][9718:9718] CHIP:DMG: 0x0 = "Cappuccino" (10 chars), - [1666940683.283081][9718:9718] CHIP:DMG: 0x1 = 4, - [1666940683.283084][9718:9718] CHIP:DMG: 0x2 = [ - [1666940683.283086][9718:9718] CHIP:DMG: - [1666940683.283088][9718:9718] CHIP:DMG: { - [1666940683.283091][9718:9718] CHIP:DMG: 0x0 = 0, - [1666940683.283093][9718:9718] CHIP:DMG: 0x1 = 0, - [1666940683.283095][9718:9718] CHIP:DMG: }, - [1666940683.283098][9718:9718] CHIP:DMG: ], - [1666940683.283100][9718:9718] CHIP:DMG: }, - [1666940683.283102][9718:9718] CHIP:DMG: }, - [1666940683.283105][9718:9718] CHIP:DMG: - [1666940683.283107][9718:9718] CHIP:DMG: }, - [1666940683.283112][9718:9718] CHIP:DMG: - [1666940683.283114][9718:9718] CHIP:DMG: AttributeReportIB = - [1666940683.283117][9718:9718] CHIP:DMG: { - [1666940683.283119][9718:9718] CHIP:DMG: AttributeDataIB = - [1666940683.283121][9718:9718] CHIP:DMG: { - [1666940683.283123][9718:9718] CHIP:DMG: DataVersion = 0xb4a9126f, - [1666940683.283125][9718:9718] CHIP:DMG: AttributePathIB = - [1666940683.283128][9718:9718] CHIP:DMG: { - [1666940683.283130][9718:9718] CHIP:DMG: Endpoint = 0x1, - [1666940683.283132][9718:9718] CHIP:DMG: Cluster = 0x50, - [1666940683.283134][9718:9718] CHIP:DMG: Attribute = 0x0000_0002, - [1666940683.283136][9718:9718] CHIP:DMG: ListIndex = Null, - [1666940683.283138][9718:9718] CHIP:DMG: } - [1666940683.283141][9718:9718] CHIP:DMG: - [1666940683.283143][9718:9718] CHIP:DMG: Data = - [1666940683.283145][9718:9718] CHIP:DMG: { - [1666940683.283148][9718:9718] CHIP:DMG: 0x0 = "Espresso" (8 chars), - [1666940683.283150][9718:9718] CHIP:DMG: 0x1 = 7, - [1666940683.283152][9718:9718] CHIP:DMG: 0x2 = [ - [1666940683.283154][9718:9718] CHIP:DMG: - [1666940683.283157][9718:9718] CHIP:DMG: { - [1666940683.283159][9718:9718] CHIP:DMG: 0x0 = 0, - [1666940683.283161][9718:9718] CHIP:DMG: 0x1 = 0, - [1666940683.283164][9718:9718] CHIP:DMG: }, - [1666940683.283167][9718:9718] CHIP:DMG: ], - [1666940683.283169][9718:9718] CHIP:DMG: }, - [1666940683.283171][9718:9718] CHIP:DMG: }, - [1666940683.283174][9718:9718] CHIP:DMG: - [1666940683.283176][9718:9718] CHIP:DMG: }, - [1666940683.283179][9718:9718] CHIP:DMG: - [1666940683.283181][9718:9718] CHIP:DMG: ], - [1666940683.283188][9718:9718] CHIP:DMG: - [1666940683.283190][9718:9718] CHIP:DMG: SuppressResponse = true, - [1666940683.283192][9718:9718] CHIP:DMG: InteractionModelRevision = 1 - - - ./chip-tool modeselect read current-mode 1 1 - - Verify the "CurrentMode response" on the TH (all-cluster-app) log: - - [1666940720.150375][9718:9718] CHIP:DMG: ReportDataMessage = - [1666940720.150377][9718:9718] CHIP:DMG: { - [1666940720.150379][9718:9718] CHIP:DMG: AttributeReportIBs = - [1666940720.150382][9718:9718] CHIP:DMG: [ - [1666940720.150384][9718:9718] CHIP:DMG: AttributeReportIB = - [1666940720.150387][9718:9718] CHIP:DMG: { - [1666940720.150389][9718:9718] CHIP:DMG: AttributeDataIB = - [1666940720.150391][9718:9718] CHIP:DMG: { - [1666940720.150394][9718:9718] CHIP:DMG: DataVersion = 0xb4a9126f, - [1666940720.150396][9718:9718] CHIP:DMG: AttributePathIB = - [1666940720.150399][9718:9718] CHIP:DMG: { - [1666940720.150402][9718:9718] CHIP:DMG: Endpoint = 0x1, - [1666940720.150404][9718:9718] CHIP:DMG: Cluster = 0x50, - [1666940720.150406][9718:9718] CHIP:DMG: Attribute = 0x0000_0003, - [1666940720.150408][9718:9718] CHIP:DMG: } - [1666940720.150411][9718:9718] CHIP:DMG: - [1666940720.150414][9718:9718] CHIP:DMG: Data = 0, - [1666940720.150416][9718:9718] CHIP:DMG: }, - [1666940720.150419][9718:9718] CHIP:DMG: - [1666940720.150421][9718:9718] CHIP:DMG: }, - [1666940720.150424][9718:9718] CHIP:DMG: - [1666940720.150426][9718:9718] CHIP:DMG: ], - [1666940720.150429][9718:9718] CHIP:DMG: - [1666940720.150431][9718:9718] CHIP:DMG: SuppressResponse = true, - [1666940720.150433][9718:9718] CHIP:DMG: InteractionModelRevision = 1 - - ./chip-tool modeselect read standard-namespace 1 1 - - Verify the "StandardNamespace response" on the TH (all-cluster-app) log: - - 1668497274.561088][9289:9289] CHIP:DMG: ReportDataMessage = - [1668497274.561091][9289:9289] CHIP:DMG: { - [1668497274.561094][9289:9289] CHIP:DMG: AttributeReportIBs = - [1668497274.561100][9289:9289] CHIP:DMG: [ - [1668497274.561103][9289:9289] CHIP:DMG: AttributeReportIB = - [1668497274.561108][9289:9289] CHIP:DMG: { - [1668497274.561111][9289:9289] CHIP:DMG: AttributeDataIB = - [1668497274.561115][9289:9289] CHIP:DMG: { - [1668497274.561119][9289:9289] CHIP:DMG: DataVersion = 0x6c775d5f, - [1668497274.561123][9289:9289] CHIP:DMG: AttributePathIB = - [1668497274.561126][9289:9289] CHIP:DMG: { - [1668497274.561129][9289:9289] CHIP:DMG: Endpoint = 0x1, - [1668497274.561133][9289:9289] CHIP:DMG: Cluster = 0x50, - [1668497274.561137][9289:9289] CHIP:DMG: Attribute = 0x0000_0001, - [1668497274.561142][9289:9289] CHIP:DMG: } - [1668497274.561147][9289:9289] CHIP:DMG: - [1668497274.561153][9289:9289] CHIP:DMG: Data = 0, - [1668497274.561157][9289:9289] CHIP:DMG: }, - [1668497274.561162][9289:9289] CHIP:DMG: - [1668497274.561165][9289:9289] CHIP:DMG: }, - [1668497274.561169][9289:9289] CHIP:DMG: - [1668497274.561172][9289:9289] CHIP:DMG: ], - [1668497274.561177][9289:9289] CHIP:DMG: - [1668497274.561180][9289:9289] CHIP:DMG: SuppressResponse = true, - [1668497274.561183][9289:9289] CHIP:DMG: InteractionModelRevision = 1 - [1668497274.561185][9289:9289] CHIP:DMG: } - - ./chip-tool modeselect read description 1 1 - - Verify the "Description response" on the TH (all-cluster-app) log: - - [1668497391.858312][9289:9289] CHIP:DMG: ReportDataMessage = - [1668497391.858315][9289:9289] CHIP:DMG: { - [1668497391.858318][9289:9289] CHIP:DMG: AttributeReportIBs = - [1668497391.858324][9289:9289] CHIP:DMG: [ - [1668497391.858327][9289:9289] CHIP:DMG: AttributeReportIB = - [1668497391.858331][9289:9289] CHIP:DMG: { - [1668497391.858334][9289:9289] CHIP:DMG: AttributeDataIB = - [1668497391.858338][9289:9289] CHIP:DMG: { - [1668497391.858342][9289:9289] CHIP:DMG: DataVersion = 0x6c775d5f, - [1668497391.858345][9289:9289] CHIP:DMG: AttributePathIB = - [1668497391.858348][9289:9289] CHIP:DMG: { - [1668497391.858352][9289:9289] CHIP:DMG: Endpoint = 0x1, - [1668497391.858355][9289:9289] CHIP:DMG: Cluster = 0x50, - [1668497391.858359][9289:9289] CHIP:DMG: Attribute = 0x0000_0000, - [1668497391.858363][9289:9289] CHIP:DMG: } - [1668497391.858368][9289:9289] CHIP:DMG: - [1668497391.858372][9289:9289] CHIP:DMG: Data = "Coffee" (6 chars), - [1668497391.858375][9289:9289] CHIP:DMG: }, - [1668497391.858380][9289:9289] CHIP:DMG: - [1668497391.858383][9289:9289] CHIP:DMG: }, - [1668497391.858387][9289:9289] CHIP:DMG: - [1668497391.858390][9289:9289] CHIP:DMG: ], - [1668497391.858395][9289:9289] CHIP:DMG: - [1668497391.858398][9289:9289] CHIP:DMG: SuppressResponse = true, - [1668497391.858403][9289:9289] CHIP:DMG: InteractionModelRevision = 1 - [1668497391.858406][9289:9289] CHIP:DMG: } - disabled: true - - - label: - "Step 2: DUT reads all supported optional attributes from TH one at a - time in a manufacturer specific order" - PICS: MOD.C.AO-READ - verification: | - ./chip-tool modeselect read on-mode 1 1 - - Verify the "OnMode response" on the TH (all-cluster-app) log: - - [1666940828.515256][9718:9718] CHIP:DMG: ReportDataMessage = - [1666940828.515259][9718:9718] CHIP:DMG: { - [1666940828.515261][9718:9718] CHIP:DMG: AttributeReportIBs = - [1666940828.515265][9718:9718] CHIP:DMG: [ - [1666940828.515267][9718:9718] CHIP:DMG: AttributeReportIB = - [1666940828.515272][9718:9718] CHIP:DMG: { - [1666940828.515275][9718:9718] CHIP:DMG: AttributeDataIB = - [1666940828.515277][9718:9718] CHIP:DMG: { - [1666940828.515280][9718:9718] CHIP:DMG: DataVersion = 0xb4a9126f, - [1666940828.515282][9718:9718] CHIP:DMG: AttributePathIB = - [1666940828.515285][9718:9718] CHIP:DMG: { - [1666940828.515288][9718:9718] CHIP:DMG: Endpoint = 0x1, - [1666940828.515290][9718:9718] CHIP:DMG: Cluster = 0x50, - [1666940828.515293][9718:9718] CHIP:DMG: Attribute = 0x0000_0005, - [1666940828.515295][9718:9718] CHIP:DMG: } - [1666940828.515298][9718:9718] CHIP:DMG: - [1666940828.515301][9718:9718] CHIP:DMG: Data = NULL - [1666940828.515304][9718:9718] CHIP:DMG: }, - [1666940828.515307][9718:9718] CHIP:DMG: - [1666940828.515309][9718:9718] CHIP:DMG: }, - [1666940828.515312][9718:9718] CHIP:DMG: - [1666940828.515314][9718:9718] CHIP:DMG: ], - [1666940828.515317][9718:9718] CHIP:DMG: - [1666940828.515320][9718:9718] CHIP:DMG: SuppressResponse = true, - [1666940828.515322][9718:9718] CHIP:DMG: InteractionModelRevision = 1 - - ./chip-tool modeselect read start-up-mode 1 1 - - Verify the "StartUpMode response" on the TH (all-cluster-app) log: - - [1666940848.925393][9718:9718] CHIP:DMG: ReportDataMessage = - [1666940848.925396][9718:9718] CHIP:DMG: { - [1666940848.925397][9718:9718] CHIP:DMG: AttributeReportIBs = - [1666940848.925401][9718:9718] CHIP:DMG: [ - [1666940848.925403][9718:9718] CHIP:DMG: AttributeReportIB = - [1666940848.925407][9718:9718] CHIP:DMG: { - [1666940848.925410][9718:9718] CHIP:DMG: AttributeDataIB = - [1666940848.925414][9718:9718] CHIP:DMG: { - [1666940848.925416][9718:9718] CHIP:DMG: DataVersion = 0xb4a9126f, - [1666940848.925418][9718:9718] CHIP:DMG: AttributePathIB = - [1666940848.925421][9718:9718] CHIP:DMG: { - [1666940848.925423][9718:9718] CHIP:DMG: Endpoint = 0x1, - [1666940848.925428][9718:9718] CHIP:DMG: Cluster = 0x50, - [1666940848.925431][9718:9718] CHIP:DMG: Attribute = 0x0000_0004, - [1666940848.925433][9718:9718] CHIP:DMG: } - [1666940848.925436][9718:9718] CHIP:DMG: - [1666940848.925438][9718:9718] CHIP:DMG: Data = 0, - [1666940848.925440][9718:9718] CHIP:DMG: }, - [1666940848.925443][9718:9718] CHIP:DMG: - [1666940848.925445][9718:9718] CHIP:DMG: }, - [1666940848.925448][9718:9718] CHIP:DMG: - [1666940848.925450][9718:9718] CHIP:DMG: ], - [1666940848.925454][9718:9718] CHIP:DMG: - [1666940848.925456][9718:9718] CHIP:DMG: SuppressResponse = true, - [1666940848.925458][9718:9718] CHIP:DMG: InteractionModelRevision = 1 - disabled: true - - - label: - "Step 3: DUT writes a suitable value to all supported mandatory - attributes on the TH one at a time in a manufacturer specific order" - PICS: MOD.C.AM-WRITE - verification: | - This cluster doesn't have any writable attributes - disabled: true - - - label: - "Step 4: DUT writes a suitable value to all supported optional - attributes on the TH one at a time in a manufacturer specific order" - PICS: MOD.C.AO-WRITE - verification: | - ./chip-tool modeselect write on-mode 0 1 1 - - Verify the "WriteRequestMessage" on TH(all-cluster-app) log: - - WriteRequestMessage = - [1673335946.283857][10561:10561] CHIP:DMG: { - [1673335946.283866][10561:10561] CHIP:DMG: suppressResponse = false, - [1673335946.283878][10561:10561] CHIP:DMG: timedRequest = false, - [1673335946.283887][10561:10561] CHIP:DMG: AttributeDataIBs = - [1673335946.283905][10561:10561] CHIP:DMG: [ - [1673335946.283914][10561:10561] CHIP:DMG: AttributeDataIB = - [1673335946.283926][10561:10561] CHIP:DMG: { - [1673335946.283935][10561:10561] CHIP:DMG: AttributePathIB = - [1673335946.283947][10561:10561] CHIP:DMG: { - [1673335946.283959][10561:10561] CHIP:DMG: Endpoint = 0x1, - [1673335946.283971][10561:10561] CHIP:DMG: Cluster = 0x50, - [1673335946.283983][10561:10561] CHIP:DMG: Attribute = 0x0000_0005, - [1673335946.283994][10561:10561] CHIP:DMG: } - [1673335946.284008][10561:10561] CHIP:DMG: - [1673335946.284022][10561:10561] CHIP:DMG: Data = 0, - [1673335946.284032][10561:10561] CHIP:DMG: }, - [1673335946.284046][10561:10561] CHIP:DMG: - [1673335946.284055][10561:10561] CHIP:DMG: ], - [1673335946.284070][10561:10561] CHIP:DMG: - [1673335946.284081][10561:10561] CHIP:DMG: moreChunkedMessages = false, - [1673335946.284091][10561:10561] CHIP:DMG: InteractionModelRevision = 1 - [1673335946.284099][10561:10561] CHIP:DMG: }, - - ./chip-tool modeselect write start-up-mode 0 1 1 - - Verify the "WriteRequestMessage" on TH(all-cluster-app) log: - - WriteRequestMessage = - [1673336054.600463][10561:10561] CHIP:DMG: { - [1673336054.600470][10561:10561] CHIP:DMG: suppressResponse = false, - [1673336054.600479][10561:10561] CHIP:DMG: timedRequest = false, - [1673336054.600486][10561:10561] CHIP:DMG: AttributeDataIBs = - [1673336054.600501][10561:10561] CHIP:DMG: [ - [1673336054.600509][10561:10561] CHIP:DMG: AttributeDataIB = - [1673336054.600521][10561:10561] CHIP:DMG: { - [1673336054.600531][10561:10561] CHIP:DMG: AttributePathIB = - [1673336054.600544][10561:10561] CHIP:DMG: { - [1673336054.600557][10561:10561] CHIP:DMG: Endpoint = 0x1, - [1673336054.600569][10561:10561] CHIP:DMG: Cluster = 0x50, - [1673336054.600582][10561:10561] CHIP:DMG: Attribute = 0x0000_0004, - [1673336054.600593][10561:10561] CHIP:DMG: } - [1673336054.600608][10561:10561] CHIP:DMG: - [1673336054.600621][10561:10561] CHIP:DMG: Data = 0, - [1673336054.600631][10561:10561] CHIP:DMG: }, - [1673336054.600646][10561:10561] CHIP:DMG: - [1673336054.600656][10561:10561] CHIP:DMG: ], - [1673336054.600673][10561:10561] CHIP:DMG: - [1673336054.600683][10561:10561] CHIP:DMG: moreChunkedMessages = false, - [1673336054.600695][10561:10561] CHIP:DMG: InteractionModelRevision = 1 - [1673336054.600704][10561:10561] CHIP:DMG: }, - disabled: true - - - label: - "Step 5: Configure TH such that it implements mandatory and none of - the optional attributes of the server-side of the cluster, and that it - also reflects this in global attributes such as FeatureMap and - AttributeList. Commission DUT to TH again" - verification: | - ./chip-tool modeselect read attribute-list 1 1 - - Verify the "AttributeList response" on the TH (all-cluster-minimal-app) log: - - [1689750639.773775][3545:3547] CHIP:DMG: ReportDataMessage = - [1689750639.773815][3545:3547] CHIP:DMG: { - [1689750639.773846][3545:3547] CHIP:DMG: AttributeReportIBs = - [1689750639.773896][3545:3547] CHIP:DMG: [ - [1689750639.773928][3545:3547] CHIP:DMG: AttributeReportIB = - [1689750639.773980][3545:3547] CHIP:DMG: { - [1689750639.774014][3545:3547] CHIP:DMG: AttributeDataIB = - [1689750639.774052][3545:3547] CHIP:DMG: { - [1689750639.774093][3545:3547] CHIP:DMG: DataVersion = 0x346e22fd, - [1689750639.774132][3545:3547] CHIP:DMG: AttributePathIB = - [1689750639.774174][3545:3547] CHIP:DMG: { - [1689750639.774217][3545:3547] CHIP:DMG: Endpoint = 0x1, - [1689750639.774261][3545:3547] CHIP:DMG: Cluster = 0x50, - [1689750639.774304][3545:3547] CHIP:DMG: Attribute = 0x0000_FFFB, - [1689750639.774347][3545:3547] CHIP:DMG: } - [1689750639.774390][3545:3547] CHIP:DMG: - [1689750639.774430][3545:3547] CHIP:DMG: Data = [ - [1689750639.774515][3545:3547] CHIP:DMG: 0, 1, 2, 3, 65528, 65529, 65530, 65531, 65532, 65533, - [1689750639.774565][3545:3547] CHIP:DMG: ], - [1689750639.774604][3545:3547] CHIP:DMG: }, - [1689750639.774652][3545:3547] CHIP:DMG: - [1689750639.774685][3545:3547] CHIP:DMG: }, - [1689750639.774731][3545:3547] CHIP:DMG: - [1689750639.774761][3545:3547] CHIP:DMG: ], - [1689750639.774804][3545:3547] CHIP:DMG: - [1689750639.774835][3545:3547] CHIP:DMG: SuppressResponse = true, - [1689750639.774867][3545:3547] CHIP:DMG: InteractionModelRevision = 1 - [1689750639.774896][3545:3547] CHIP:DMG: } - - - ./chip-tool modeselect read feature-map 1 1 - - Verify the " FeatureMap " on the TH (all-cluster-minimal-app) log: - - [1666943338.908026][12769:12769] CHIP:DMG: ReportDataMessage = - [1666943338.908028][12769:12769] CHIP:DMG: { - [1666943338.908031][12769:12769] CHIP:DMG: AttributeReportIBs = - [1666943338.908035][12769:12769] CHIP:DMG: [ - [1666943338.908038][12769:12769] CHIP:DMG: AttributeReportIB = - [1666943338.908042][12769:12769] CHIP:DMG: { - [1666943338.908045][12769:12769] CHIP:DMG: AttributeDataIB = - [1666943338.908048][12769:12769] CHIP:DMG: { - [1666943338.908051][12769:12769] CHIP:DMG: DataVersion = 0x5fb921d0, - [1666943338.908054][12769:12769] CHIP:DMG: AttributePathIB = - [1666943338.908057][12769:12769] CHIP:DMG: { - [1666943338.908060][12769:12769] CHIP:DMG: Endpoint = 0x1, - [1666943338.908064][12769:12769] CHIP:DMG: Cluster = 0x50, - [1666943338.908067][12769:12769] CHIP:DMG: Attribute = 0x0000_FFFC, - [1666943338.908070][12769:12769] CHIP:DMG: } - [1666943338.908074][12769:12769] CHIP:DMG: - [1666943338.908077][12769:12769] CHIP:DMG: Data = 0, - [1666943338.908080][12769:12769] CHIP:DMG: }, - [1666943338.908084][12769:12769] CHIP:DMG: - [1666943338.908086][12769:12769] CHIP:DMG: }, - [1666943338.908090][12769:12769] CHIP:DMG: - [1666943338.908092][12769:12769] CHIP:DMG: ], - [1666943338.908096][12769:12769] CHIP:DMG: - [1666943338.908099][12769:12769] CHIP:DMG: SuppressResponse = true, - [1666943338.908102][12769:12769] CHIP:DMG: InteractionModelRevision = 1 - [1666943338.908104][12769:12769] CHIP:DMG: } - - - ./chip-tool modeselect read supported-modes 1 1 - - Verify the "SupportedModes response" on the TH (all-cluster-minimal-app) log: - - 1666943362.813636][12769:12769] CHIP:DMG: ReportDataMessage = - [1666943362.813638][12769:12769] CHIP:DMG: { - [1666943362.813640][12769:12769] CHIP:DMG: AttributeReportIBs = - [1666943362.813643][12769:12769] CHIP:DMG: [ - [1666943362.813645][12769:12769] CHIP:DMG: AttributeReportIB = - [1666943362.813650][12769:12769] CHIP:DMG: { - [1666943362.813652][12769:12769] CHIP:DMG: AttributeDataIB = - [1666943362.813655][12769:12769] CHIP:DMG: { - [1666943362.813657][12769:12769] CHIP:DMG: DataVersion = 0x5fb921d0, - [1666943362.813659][12769:12769] CHIP:DMG: AttributePathIB = - [1666943362.813662][12769:12769] CHIP:DMG: { - [1666943362.813664][12769:12769] CHIP:DMG: Endpoint = 0x1, - [1666943362.813666][12769:12769] CHIP:DMG: Cluster = 0x50, - [1666943362.813669][12769:12769] CHIP:DMG: Attribute = 0x0000_0002, - [1666943362.813671][12769:12769] CHIP:DMG: } - [1666943362.813674][12769:12769] CHIP:DMG: - [1666943362.813676][12769:12769] CHIP:DMG: Data = [ - [1666943362.813679][12769:12769] CHIP:DMG: - [1666943362.813681][12769:12769] CHIP:DMG: ], - [1666943362.813683][12769:12769] CHIP:DMG: }, - [1666943362.813686][12769:12769] CHIP:DMG: - [1666943362.813688][12769:12769] CHIP:DMG: }, - [1666943362.813692][12769:12769] CHIP:DMG: - [1666943362.813694][12769:12769] CHIP:DMG: AttributeReportIB = - [1666943362.813699][12769:12769] CHIP:DMG: { - [1666943362.813701][12769:12769] CHIP:DMG: AttributeDataIB = - [1666943362.813703][12769:12769] CHIP:DMG: { - [1666943362.813705][12769:12769] CHIP:DMG: DataVersion = 0x5fb921d0, - [1666943362.813707][12769:12769] CHIP:DMG: AttributePathIB = - [1666943362.813709][12769:12769] CHIP:DMG: { - [1666943362.813711][12769:12769] CHIP:DMG: Endpoint = 0x1, - [1666943362.813714][12769:12769] CHIP:DMG: Cluster = 0x50, - [1666943362.813716][12769:12769] CHIP:DMG: Attribute = 0x0000_0002, - [1666943362.813719][12769:12769] CHIP:DMG: ListIndex = Null, - [1666943362.813721][12769:12769] CHIP:DMG: } - [1666943362.813725][12769:12769] CHIP:DMG: - [1666943362.813727][12769:12769] CHIP:DMG: Data = - [1666943362.813729][12769:12769] CHIP:DMG: { - [1666943362.813732][12769:12769] CHIP:DMG: 0x0 = "Black" (5 chars), - [1666943362.813735][12769:12769] CHIP:DMG: 0x1 = 0, - [1666943362.813737][12769:12769] CHIP:DMG: 0x2 = [ - [1666943362.813740][12769:12769] CHIP:DMG: - [1666943362.813742][12769:12769] CHIP:DMG: { - [1666943362.813745][12769:12769] CHIP:DMG: 0x0 = 0, - [1666943362.813748][12769:12769] CHIP:DMG: 0x1 = 0, - [1666943362.813750][12769:12769] CHIP:DMG: }, - [1666943362.813752][12769:12769] CHIP:DMG: ], - [1666943362.813755][12769:12769] CHIP:DMG: }, - [1666943362.813756][12769:12769] CHIP:DMG: }, - [1666943362.813760][12769:12769] CHIP:DMG: - [1666943362.813762][12769:12769] CHIP:DMG: }, - [1666943362.813768][12769:12769] CHIP:DMG: - [1666943362.813770][12769:12769] CHIP:DMG: AttributeReportIB = - [1666943362.813775][12769:12769] CHIP:DMG: { - [1666943362.813776][12769:12769] CHIP:DMG: AttributeDataIB = - [1666943362.813779][12769:12769] CHIP:DMG: { - [1666943362.813781][12769:12769] CHIP:DMG: DataVersion = 0x5fb921d0, - [1666943362.813783][12769:12769] CHIP:DMG: AttributePathIB = - [1666943362.813786][12769:12769] CHIP:DMG: { - [1666943362.813788][12769:12769] CHIP:DMG: Endpoint = 0x1, - [1666943362.813790][12769:12769] CHIP:DMG: Cluster = 0x50, - [1666943362.813793][12769:12769] CHIP:DMG: Attribute = 0x0000_0002, - [1666943362.813795][12769:12769] CHIP:DMG: ListIndex = Null, - [1666943362.813797][12769:12769] CHIP:DMG: } - [1666943362.813801][12769:12769] CHIP:DMG: - [1666943362.813803][12769:12769] CHIP:DMG: Data = - [1666943362.813805][12769:12769] CHIP:DMG: { - [1666943362.813807][12769:12769] CHIP:DMG: 0x0 = "Cappuccino" (10 chars), - [1666943362.813810][12769:12769] CHIP:DMG: 0x1 = 4, - [1666943362.813812][12769:12769] CHIP:DMG: 0x2 = [ - [1666943362.813814][12769:12769] CHIP:DMG: - [1666943362.813817][12769:12769] CHIP:DMG: { - [1666943362.813820][12769:12769] CHIP:DMG: 0x0 = 0, - [1666943362.813823][12769:12769] CHIP:DMG: 0x1 = 0, - [1666943362.813826][12769:12769] CHIP:DMG: }, - [1666943362.813828][12769:12769] CHIP:DMG: ], - [1666943362.813830][12769:12769] CHIP:DMG: }, - [1666943362.813832][12769:12769] CHIP:DMG: }, - [1666943362.813836][12769:12769] CHIP:DMG: - [1666943362.813838][12769:12769] CHIP:DMG: }, - [1666943362.813844][12769:12769] CHIP:DMG: - [1666943362.813846][12769:12769] CHIP:DMG: AttributeReportIB = - [1666943362.813850][12769:12769] CHIP:DMG: { - [1666943362.813852][12769:12769] CHIP:DMG: AttributeDataIB = - [1666943362.813855][12769:12769] CHIP:DMG: { - [1666943362.813857][12769:12769] CHIP:DMG: DataVersion = 0x5fb921d0, - [1666943362.813860][12769:12769] CHIP:DMG: AttributePathIB = - [1666943362.813862][12769:12769] CHIP:DMG: { - [1666943362.813864][12769:12769] CHIP:DMG: Endpoint = 0x1, - [1666943362.813866][12769:12769] CHIP:DMG: Cluster = 0x50, - [1666943362.813869][12769:12769] CHIP:DMG: Attribute = 0x0000_0002, - [1666943362.813871][12769:12769] CHIP:DMG: ListIndex = Null, - [1666943362.813873][12769:12769] CHIP:DMG: } - [1666943362.813876][12769:12769] CHIP:DMG: - [1666943362.813878][12769:12769] CHIP:DMG: Data = - [1666943362.813881][12769:12769] CHIP:DMG: { - [1666943362.813883][12769:12769] CHIP:DMG: 0x0 = "Espresso" (8 chars), - [1666943362.813886][12769:12769] CHIP:DMG: 0x1 = 7, - [1666943362.813888][12769:12769] CHIP:DMG: 0x2 = [ - [1666943362.813890][12769:12769] CHIP:DMG: - [1666943362.813893][12769:12769] CHIP:DMG: { - [1666943362.813895][12769:12769] CHIP:DMG: 0x0 = 0, - [1666943362.813898][12769:12769] CHIP:DMG: 0x1 = 0, - [1666943362.813900][12769:12769] CHIP:DMG: }, - [1666943362.813903][12769:12769] CHIP:DMG: ], - [1666943362.813905][12769:12769] CHIP:DMG: }, - [1666943362.813907][12769:12769] CHIP:DMG: }, - [1666943362.813911][12769:12769] CHIP:DMG: - [1666943362.813913][12769:12769] CHIP:DMG: }, - [1666943362.813917][12769:12769] CHIP:DMG: - [1666943362.813918][12769:12769] CHIP:DMG: ], - [1666943362.813926][12769:12769] CHIP:DMG: - [1666943362.813928][12769:12769] CHIP:DMG: SuppressResponse = true, - [1666943362.813931][12769:12769] CHIP:DMG: InteractionModelRevision = 1 - [1666943362.813934][12769:12769] CHIP:DMG: } - [1666943362.813936][12769:12769] CHIP:DMG: - - - ./chip-tool modeselect read current-mode 1 1 - - Verify the "CurrentMode response" on the TH (all-cluster-minimal-app) log: - - 1666943427.104790][12769:12769] CHIP:DMG: ReportDataMessage = - [1666943427.104798][12769:12769] CHIP:DMG: { - [1666943427.104804][12769:12769] CHIP:DMG: AttributeReportIBs = - [1666943427.104814][12769:12769] CHIP:DMG: [ - [1666943427.104820][12769:12769] CHIP:DMG: AttributeReportIB = - [1666943427.104838][12769:12769] CHIP:DMG: { - [1666943427.104846][12769:12769] CHIP:DMG: AttributeDataIB = - [1666943427.104858][12769:12769] CHIP:DMG: { - [1666943427.104869][12769:12769] CHIP:DMG: DataVersion = 0x5fb921d0, - [1666943427.104880][12769:12769] CHIP:DMG: AttributePathIB = - [1666943427.104891][12769:12769] CHIP:DMG: { - [1666943427.104904][12769:12769] CHIP:DMG: Endpoint = 0x1, - [1666943427.104916][12769:12769] CHIP:DMG: Cluster = 0x50, - [1666943427.104931][12769:12769] CHIP:DMG: Attribute = 0x0000_0003, - [1666943427.104939][12769:12769] CHIP:DMG: } - [1666943427.104948][12769:12769] CHIP:DMG: - [1666943427.104956][12769:12769] CHIP:DMG: Data = 0, - [1666943427.104963][12769:12769] CHIP:DMG: }, - [1666943427.104974][12769:12769] CHIP:DMG: - [1666943427.104981][12769:12769] CHIP:DMG: }, - [1666943427.104991][12769:12769] CHIP:DMG: - [1666943427.105001][12769:12769] CHIP:DMG: ], - [1666943427.105017][12769:12769] CHIP:DMG: - [1666943427.105027][12769:12769] CHIP:DMG: SuppressResponse = true, - [1666943427.105037][12769:12769] CHIP:DMG: InteractionModelRevision = 1 - [1666943427.105045][12769:12769] CHIP:DMG: } - - - ./chip-tool modeselect read standard-namespace 1 1 - - Verify the "StandardNamespace response" on the TH (all-cluster-minimal-app) log: - - [1666943453.966995][12769:12769] CHIP:DMG: ReportDataMessage = - [1666943453.966997][12769:12769] CHIP:DMG: { - [1666943453.966999][12769:12769] CHIP:DMG: AttributeReportIBs = - [1666943453.967003][12769:12769] CHIP:DMG: [ - [1666943453.967005][12769:12769] CHIP:DMG: AttributeReportIB = - [1666943453.967008][12769:12769] CHIP:DMG: { - [1666943453.967010][12769:12769] CHIP:DMG: AttributeDataIB = - [1666943453.967014][12769:12769] CHIP:DMG: { - [1666943453.967017][12769:12769] CHIP:DMG: DataVersion = 0x5fb921d0, - [1666943453.967019][12769:12769] CHIP:DMG: AttributePathIB = - [1666943453.967021][12769:12769] CHIP:DMG: { - [1666943453.967025][12769:12769] CHIP:DMG: Endpoint = 0x1, - [1666943453.967027][12769:12769] CHIP:DMG: Cluster = 0x50, - [1666943453.967029][12769:12769] CHIP:DMG: Attribute = 0x0000_0001, - [1666943453.967033][12769:12769] CHIP:DMG: } - [1666943453.967035][12769:12769] CHIP:DMG: - [1666943453.967038][12769:12769] CHIP:DMG: Data = 0, - [1666943453.967040][12769:12769] CHIP:DMG: }, - [1666943453.967043][12769:12769] CHIP:DMG: - [1666943453.967045][12769:12769] CHIP:DMG: }, - [1666943453.967047][12769:12769] CHIP:DMG: - [1666943453.967050][12769:12769] CHIP:DMG: ], - [1666943453.967053][12769:12769] CHIP:DMG: - [1666943453.967055][12769:12769] CHIP:DMG: SuppressResponse = true, - [1666943453.967057][12769:12769] CHIP:DMG: InteractionModelRevision = 1 - - ./chip-tool modeselect read description 1 1 - - Verify the "Description response" on the TH (all-cluster-minimal-app) log: - - [1666941093.845092][9718:9718] CHIP:DMG: ReportDataMessage = - [1666941093.845094][9718:9718] CHIP:DMG: { - [1666941093.845096][9718:9718] CHIP:DMG: AttributeReportIBs = - [1666941093.845099][9718:9718] CHIP:DMG: [ - [1666941093.845101][9718:9718] CHIP:DMG: AttributeReportIB = - [1666941093.845105][9718:9718] CHIP:DMG: { - [1666941093.845107][9718:9718] CHIP:DMG: AttributeDataIB = - [1666941093.845110][9718:9718] CHIP:DMG: { - [1666941093.845112][9718:9718] CHIP:DMG: DataVersion = 0xb4a9126f, - [1666941093.845115][9718:9718] CHIP:DMG: AttributePathIB = - [1666941093.845117][9718:9718] CHIP:DMG: { - [1666941093.845119][9718:9718] CHIP:DMG: Endpoint = 0x1, - [1666941093.845122][9718:9718] CHIP:DMG: Cluster = 0x50, - [1666941093.845124][9718:9718] CHIP:DMG: Attribute = 0x0000_0000, - [1666941093.845126][9718:9718] CHIP:DMG: } - [1666941093.845129][9718:9718] CHIP:DMG: - [1666941093.845132][9718:9718] CHIP:DMG: Data = "Coffee" (6 chars), - [1666941093.845134][9718:9718] CHIP:DMG: }, - [1666941093.845137][9718:9718] CHIP:DMG: - [1666941093.845139][9718:9718] CHIP:DMG: }, - [1666941093.845142][9718:9718] CHIP:DMG: - [1666941093.845144][9718:9718] CHIP:DMG: ], - [1666941093.845147][9718:9718] CHIP:DMG: - [1666941093.845149][9718:9718] CHIP:DMG: SuppressResponse = true, - [1666941093.845152][9718:9718] CHIP:DMG: InteractionModelRevision = 1 - disabled: true - - - label: - "Step 6: DUT reads all supported optional attributes from TH one at a - time in a manufacturer specific order" - PICS: MOD.C.AO-READ - verification: | - ./chip-tool modeselect read on-mode 1 1 - - Verify status response as UNSUPPORTED_ATTRIBUTE on the TH (all-cluster-minimal-app) log: - - [1684929635.593547][20278:20280] CHIP:DMG: StatusIB = - [1684929635.593551][20278:20280] CHIP:DMG: { - [1684929635.593555][20278:20280] CHIP:DMG: status = 0x86 (UNSUPPORTED_ATTRIBUTE), - [1684929635.593558][20278:20280] CHIP:DMG: }, - - - ./chip-tool modeselect read start-up-mode 1 1 - - Verify status response as UNSUPPORTED_ATTRIBUTE on the TH (all-cluster-minimal-app) log: - - [1684929665.428885][20285:20287] CHIP:DMG: StatusIB = - [1684929665.428891][20285:20287] CHIP:DMG: { - [1684929665.428895][20285:20287] CHIP:DMG: status = 0x86 (UNSUPPORTED_ATTRIBUTE), - [1684929665.428900][20285:20287] CHIP:DMG: }, - disabled: true - - - label: - "Step 7: DUT writes a suitable value to all supported optional - attributes on the TH one at a time in a manufacturer specific order" - PICS: MOD.C.AO-WRITE - verification: | - ./chip-tool modeselect write on-mode 0 1 1 - - Verify status response as UNSUPPORTED_ATTRIBUTE on the TH (all-cluster-minimal-app) log: - - [1684929889.679386][20348:20350] CHIP:DMG: StatusIB = - [1684929889.679389][20348:20350] CHIP:DMG: { - [1684929889.679392][20348:20350] CHIP:DMG: status = 0x86 (UNSUPPORTED_ATTRIBUTE), - [1684929889.679395][20348:20350] CHIP:DMG: }, - [1684929889.679398][20348:20350] CHIP:DMG: - - - ./chip-tool modeselect write start-up-mode 0 1 1 - - Verify status response as UNSUPPORTED_ATTRIBUTE on the TH (all-cluster-minimal-app) log: - - [1684929889.679386][20348:20350] CHIP:DMG: StatusIB = - [1684929889.679389][20348:20350] CHIP:DMG: { - [1684929889.679392][20348:20350] CHIP:DMG: status = 0x86 (UNSUPPORTED_ATTRIBUTE), - [1684929889.679395][20348:20350] CHIP:DMG: }, - [1684929889.679398][20348:20350] CHIP:DMG: - disabled: true diff --git a/src/app/tests/suites/certification/Test_TC_OTCCM_3_1.yaml b/src/app/tests/suites/certification/Test_TC_OTCCM_3_1.yaml deleted file mode 100644 index 3d886d15ab6253..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_OTCCM_3_1.yaml +++ /dev/null @@ -1,131 +0,0 @@ -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -name: 3.4 [TC-OTCCM-3.1] On Mode functionality with DUT as Server - -PICS: - - OTCCM.S.A0003 - - MOD.S.F00 - - OO.S.C00.Rsp - - OO.S.C01.Rsp - -config: - nodeId: 0x12344321 - cluster: "Oven Mode" - endpoint: 1 - - ConfigureOnMode: - type: int8u - defaultValue: 0 - new_mode_th: - type: int8u - defaultValue: 2 - -tests: - - label: - "Step 1: Commission DUT to TH (can be skipped if done in a preceding - test)." - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: - "Precondition: TH writes from the DUT the OnMode attribute.NOTE: To - execute this test case set onmode to any integer value because as - default it value has null." - PICS: OTCCM.S.A0003 && MOD.S.F00 - command: "writeAttribute" - attribute: "OnMode" - arguments: - value: ConfigureOnMode - - - label: "Step 2: TH reads from the DUT the OnMode attribute." - PICS: OTCCM.S.A0003 && MOD.S.F00 - command: "readAttribute" - attribute: "OnMode" - response: - saveAs: on_mode_dut - constraints: - type: int8u - - - label: "Step 3: TH reads from the DUT the CurrentMode attribute." - PICS: OTCCM.S.A0001 && MOD.S.F00 - command: "readAttribute" - attribute: "CurrentMode" - response: - saveAs: old_current_mode_dut - constraints: - type: int8u - - - label: - "If on_mode_dut is equal to old_current_mode_dut proceed to step 4. - Else proceed to step 6." - PICS: OTCCM.S.A0001 && MOD.S.F00 && OTCCM.S.A0003 - cluster: "EqualityCommands" - command: "UnsignedNumberEquals" - arguments: - values: - - name: "Value1" - value: on_mode_dut - - name: "Value2" - value: old_current_mode_dut - response: - - values: - - name: "Equals" - saveAs: IsExpectedValue - - - label: "Step 4: TH reads from the DUT the SupportedModes attribute." - runIf: IsExpectedValue - PICS: OTCCM.S.A0000 && MOD.S.F00 - command: "readAttribute" - attribute: "SupportedModes" - response: - constraints: - type: list - minLength: 2 - - - label: - "Step 5: TH sends a ChangeToMode command to the DUT with NewMode set - to new_mode_th" - runIf: IsExpectedValue - PICS: OTCCM.S.C00.Rsp && MOD.S.F00 - command: "ChangeToMode" - arguments: - values: - - name: "NewMode" - value: new_mode_th - response: - values: - - name: "Status" - value: 0x00 - - - label: "Step 6:TH sends a Off command to the DUT" - PICS: OO.S.C00.Rsp && MOD.S.F00 - cluster: "On/Off" - command: "Off" - - - label: "Step 7:TH sends a On command to the DUT" - PICS: OO.S.C01.Rsp && MOD.S.F00 - cluster: "On/Off" - command: "On" - - - label: "Step 8: TH reads from the DUT the CurrentMode attribute." - PICS: OTCCM.S.A0001 && MOD.S.F00 - command: "readAttribute" - attribute: "CurrentMode" - response: - value: on_mode_dut diff --git a/src/app/tests/suites/certification/Test_TC_OTCCM_3_2.yaml b/src/app/tests/suites/certification/Test_TC_OTCCM_3_2.yaml deleted file mode 100644 index e1220de758e875..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_OTCCM_3_2.yaml +++ /dev/null @@ -1,171 +0,0 @@ -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -name: 3.5 [TC-OTCCM-3.2] Startup Mode functionality with DUT as Server - -PICS: - - OTCCM.S.A0002 - -config: - nodeId: 0x12344321 - cluster: "Oven Mode" - endpoint: 1 - - new_start-up_mode_th: - type: int8u - defaultValue: 0 - new_mode_th: - type: int8u - defaultValue: 1 - -tests: - - label: - "Step 1: Commission DUT to TH (can be skipped if done in a preceding - test)." - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: TH reads from the DUT the StartUpMode attribute." - PICS: OTCCM.S.A0002 - command: "readAttribute" - attribute: "StartUpMode" - response: - saveAs: startup_mode_dut - - - label: - "Step 2: If startup_mode_dut is null proceed to step 3. Else save - startup_mode_dut as new_start_up_mode_th and proceed to step 5." - PICS: OTCCM.S.A0002 - cluster: "EqualityCommands" - command: "UnsignedNumberEquals" - arguments: - values: - - name: "Value1" - value: startup_mode_dut - - name: "Value2" - value: null - response: - - values: - - name: "Equals" - saveAs: IsExpectedValue - - - label: "Step 3: TH reads from the DUT the SupportedModes attribute." - runIf: IsExpectedValue - PICS: OTCCM.S.A0000 - command: "readAttribute" - attribute: "SupportedModes" - response: - saveAs: supported_modes_dut - constraints: - type: list - minLength: 2 - - label: - "Step 4: TH writes to the DUT the StartUpMode attribute with the - new_start_up_mode_th value" - PICS: OTCCM.S.A0002 - runIf: IsExpectedValue - command: "writeAttribute" - attribute: "StartUpMode" - arguments: - value: new_start_up_mode_th - - - label: "Step 5: TH reads from the DUT the CurrentMode attribute." - PICS: OTCCM.S.A0001 - command: "readAttribute" - attribute: "CurrentMode" - response: - saveAs: old_current_mode_dut - - - label: - "Step 5: If startup_mode_dut is equal to old_current_mode_dut proceed - to step 6. Else proceed to step 8." - PICS: OTCCM.S.A0001 && OTCCM.S.A0002 - cluster: "EqualityCommands" - command: "UnsignedNumberEquals" - arguments: - values: - - name: "Value1" - value: startup_mode_dut - - name: "Value2" - value: old_current_mode_dut - response: - - values: - - name: "Equals" - saveAs: Step5_IsExpectedValue - - - label: "Step 6: TH reads from the DUT the SupportedModes attribute." - PICS: OTCCM.S.A0000 - runIf: Step5_IsExpectedValue - command: "readAttribute" - attribute: "SupportedModes" - response: - saveAs: Step6_supported_modes_dut - constraints: - type: list - minLength: 2 - - - label: - "Step 7: TH sends a ChangeToMode command to the DUT with NewMode set - to new_mode_th" - PICS: OTCCM.S.C00.Rsp - runIf: Step5_IsExpectedValue - command: "ChangeToMode" - arguments: - values: - - name: "NewMode" - value: new_mode_th - response: - values: - - name: "Status" - value: 0x00 - - - label: "Step 8: Physically power cycle the device" - verification: | - Physically power cycle the device. - cluster: "LogCommands" - command: "UserPrompt" - PICS: PICS_USER_PROMPT - arguments: - values: - - name: "message" - value: "Please enter 'y' for success" - - name: "expectedValue" - value: "y" - - - label: "Wait for the commissioned device to be retrieved" - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 9: TH reads from the DUT the StartUpMode attribute." - PICS: OTCCM.S.A0002 && PICS_USER_PROMPT - command: "readAttribute" - attribute: "StartUpMode" - response: - saveAs: new_start_up_mode_dut - value: new_start_up_mode_th - - - label: "Step 10: TH reads from the DUT the CurrentMode attribute." - PICS: OTCCM.S.A0001 && PICS_USER_PROMPT - command: "readAttribute" - attribute: "CurrentMode" - response: - value: new_start_up_mode_dut diff --git a/src/app/tests/suites/certification/Test_TC_OTCCM_3_3.yaml b/src/app/tests/suites/certification/Test_TC_OTCCM_3_3.yaml deleted file mode 100644 index 27184569f51b5a..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_OTCCM_3_3.yaml +++ /dev/null @@ -1,187 +0,0 @@ -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -name: - 3.6 [TC-OTCCM-3.3] On Mode and Startup Mode functionality with DUT as Server - -PICS: - - OTCCM.S.A0002 - - OTCCM.S.A0003 - - MOD.S.F00 - - OO.S.A4003 - -config: - nodeId: 0x12344321 - cluster: "Oven Mode" - endpoint: 1 - - new_start_up_mode_th: - type: int8u - defaultValue: 0 - new_mode_th: - type: int8u - defaultValue: 1 - -tests: - - label: - "Step 1: Commission DUT to TH (can be skipped if done in a preceding - test)." - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: TH reads from the DUT the StartUpMode attribute." - PICS: OTCCM.S.A0002 - command: "readAttribute" - attribute: "StartUpMode" - response: - saveAs: startup_mode_dut - - - label: - "Step 2: If startup_mode_dut is null proceed to step 3. Else save - startup_mode_dut as new_start_up_mode_th and proceed to step 5." - PICS: OTCCM.S.A0002 - cluster: "EqualityCommands" - command: "UnsignedNumberEquals" - arguments: - values: - - name: "Value1" - value: startup_mode_dut - - name: "Value2" - value: null - response: - - values: - - name: "Equals" - saveAs: IsExpectedValue - - - label: "Step 3: TH reads from the DUT the SupportedModes attribute." - runIf: IsExpectedValue - PICS: OTCCM.S.A0000 - command: "readAttribute" - attribute: "SupportedModes" - response: - saveAs: supported_modes_dut - constraints: - type: list - minLength: 2 - - - label: - "Step 4: TH writes to the DUT the StartUpMode attribute with the - new_start_up_mode_th value" - PICS: OTCCM.S.A0002 - runIf: IsExpectedValue - command: "writeAttribute" - attribute: "StartUpMode" - arguments: - value: new_start_up_mode_th - - - label: "Step 5: TH reads from the DUT the OnMode attribute." - PICS: OTCCM.S.A0003 && OTCCM.S.A0002 - command: "readAttribute" - attribute: "OnMode" - response: - saveAs: old_on_mode_dut - - - label: - "Step 5: If startup_mode_dut is equal to old_on_mode_dut proceed to - step 6. Else proceed to step 8." - PICS: OTCCM.S.A0002 - cluster: "EqualityCommands" - command: "UnsignedNumberEquals" - arguments: - values: - - name: "Value1" - value: old_on_mode_dut - - name: "Value2" - value: startup_mode_dut - response: - - values: - - name: "Equals" - saveAs: Step5_IsExpectedValue - - - label: "Step 6: TH reads from the DUT the SupportedModes attribute." - PICS: OTCCM.S.A0000 && OTCCM.S.A0002 - runIf: Step5_IsExpectedValue - command: "readAttribute" - attribute: "SupportedModes" - response: - saveAs: Step6_supported_modes_dut - constraints: - type: list - minLength: 2 - - - label: - "Step 7: TH writes to the DUT the OnMode attribute with the - new_mode_th value" - PICS: OTCCM.S.A0003 - runIf: Step5_IsExpectedValue - command: "writeAttribute" - attribute: "OnMode" - arguments: - value: new_mode_th - - - label: "Step 8: TH reads from the DUT the OnMode attribute." - PICS: OTCCM.S.A0003 && MOD.S.F00 - command: "readAttribute" - attribute: "OnMode" - response: - saveAs: new_on_mode_dut - - - label: - "Step 9: TH writes to the DUT the StartUpOnOff attribute with the - value 1." - PICS: OO.S.A4003 - cluster: "On/Off" - command: "writeAttribute" - attribute: "StartUpOnOff" - arguments: - value: 1 - - - label: "Step 10: Physically power cycle the device" - verification: | - Physically power cycle the device. - cluster: "LogCommands" - command: "UserPrompt" - PICS: PICS_USER_PROMPT - arguments: - values: - - name: "message" - value: "Please enter 'y' for success" - - name: "expectedValue" - value: "y" - - - label: "Wait for the commissioned device to be retrieved" - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 11: TH reads from the DUT the StartUpMode attribute." - PICS: OTCCM.S.A0002 && PICS_USER_PROMPT - command: "readAttribute" - attribute: "StartUpMode" - response: - value: new_start_up_mode_th - - - label: "Step 12: TH reads from the DUT the CurrentMode attribute." - PICS: OTCCM.S.A0001 && PICS_USER_PROMPT - command: "readAttribute" - attribute: "CurrentMode" - response: - value: new_on_mode_dut diff --git a/src/app/tests/suites/certification/Test_TC_TCCM_3_1.yaml b/src/app/tests/suites/certification/Test_TC_TCCM_3_1.yaml deleted file mode 100644 index 178357027408c7..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_TCCM_3_1.yaml +++ /dev/null @@ -1,127 +0,0 @@ -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -name: 219.3.1. [TC-TCCM-3.1] On Mode functionality with DUT as Server - -PICS: - - TCCM.S.A0003 - - MOD.S.F00 - - OO.S.C00.Rsp - - OO.S.C01.Rsp - -config: - nodeId: 0x12344321 - cluster: "Refrigerator And Temperature Controlled Cabinet Mode" - endpoint: 1 - #Configure newmode value - new_mode_th: - type: int8u - defaultValue: 2 - nonNull_OnMode_value: - type: int8u - defaultValue: 0 - -tests: - - label: - "Step 1: Commission DUT to TH (can be skipped if done in a preceding - test)." - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: - "Preconditions: The OnMode attribute is set to a non-NULL value from - the mode values indicated by the SupportedModes attribute." - PICS: TCCM.S.A0003 && MOD.S.F00 - command: "writeAttribute" - attribute: "OnMode" - arguments: - value: nonNull_OnMode_value - - - label: "Step 2: TH reads from the DUT the OnMode attribute." - PICS: TCCM.S.A0003 && MOD.S.F00 - command: "readAttribute" - attribute: "OnMode" - response: - saveAs: on_mode_dut - - - label: "Step 3a: TH reads from the DUT the CurrentMode attribute." - PICS: TCCM.S.A0001 && MOD.S.F00 - command: "readAttribute" - attribute: "CurrentMode" - response: - saveAs: old_current_mode_dut - - - label: - "Step 3b: If the OnMode and CurrentMode attributes have the same - value, proceed to step 4, Otherwise proceed to step 6" - PICS: TCCM.S.A0003 && TCCM.S.A0001 && MOD.S.F00 - cluster: "EqualityCommands" - command: "UnsignedNumberEquals" - arguments: - values: - - name: "Value1" - value: on_mode_dut - - name: "Value2" - value: old_current_mode_dut - response: - - values: - - name: "Equals" - saveAs: IsExpectedValue - - - label: "Step 4:TH reads the SupportedModes attribute from the DUT" - runIf: IsExpectedValue - PICS: TCCM.S.A0000 && MOD.S.F00 - command: "readAttribute" - attribute: "SupportedModes" - response: - constraints: - type: list - minLength: 2 - - - label: - "Step 5: Select a value from supported_modes_dut different from - on_mode_dut. Save the value as new_mode_th. TH sends a ChangeToMode - command to the DUT with NewMode set to new_mode_th" - runIf: IsExpectedValue - PICS: TCCM.S.C00.Rsp && MOD.S.F00 - command: "ChangeToMode" - arguments: - values: - - name: "NewMode" - value: new_mode_th - response: - values: - - name: "Status" - value: 0x00 - - - label: "Step 6: TH sends an Off command to the DUT" - PICS: OO.S.C00.Rsp && MOD.S.F00 - cluster: "On/Off" - command: "Off" - - - label: "Step 7: TH sends an On command to the DUT" - PICS: OO.S.C01.Rsp && MOD.S.F00 - cluster: "On/Off" - command: "On" - - - label: "Step 8: TH reads the CurrentMode attribute from the DUT" - PICS: TCCM.S.A0001 && MOD.S.F00 - command: "readAttribute" - attribute: "CurrentMode" - response: - value: on_mode_dut diff --git a/src/app/tests/suites/certification/Test_TC_TCCM_3_2.yaml b/src/app/tests/suites/certification/Test_TC_TCCM_3_2.yaml deleted file mode 100644 index b89db6a41925c2..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_TCCM_3_2.yaml +++ /dev/null @@ -1,176 +0,0 @@ -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -name: 219.3.2. [TC-TCCM-3.2] Startup Mode functionality with DUT as Server - -PICS: - - TCCM.S.A0002 - -config: - nodeId: 0x12344321 - cluster: "Refrigerator And Temperature Controlled Cabinet Mode" - endpoint: 1 - - new_start_up_mode_th: - type: int8u - defaultValue: 0 - new_mode_th: - type: int8u - defaultValue: 1 - -tests: - - label: - "Step 1: Commission DUT to TH (can be skipped if done in a preceding - test)." - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: TH reads from the DUT the StartUpMode attribute." - PICS: TCCM.S.A0002 - command: "readAttribute" - attribute: "StartUpMode" - response: - saveAs: startup_mode_dut - constraints: - type: int8u - - - label: - "If startup_mode_dut is null proceed to step 3. Else save - startup_mode_dut as new_start_up_mode_th and proceed to step 5" - PICS: TCCM.S.A0002 - cluster: "EqualityCommands" - command: "UnsignedNumberEquals" - arguments: - values: - - name: "Value1" - value: startup_mode_dut - - name: "Value2" - value: null - response: - - values: - - name: "Equals" - saveAs: IsExpectedValue - - - label: "Step 3: TH reads from the DUT the SupportedModes attribute." - runIf: IsExpectedValue - PICS: TCCM.S.A0000 - command: "readAttribute" - attribute: "SupportedModes" - response: - saveAs: supported_modes_dut - constraints: - type: list - minLength: 2 - - - label: - "Step 4:TH writes to the DUT the StartUpMode attribute with the - new_start_up_mode_th value" - runIf: IsExpectedValue - PICS: TCCM.S.A0002 - command: "writeAttribute" - attribute: "StartUpMode" - arguments: - value: new_start_up_mode_th - - - label: "Step 5: TH reads from the DUT the CurrentMode attribute." - PICS: TCCM.S.A0001 - command: "readAttribute" - attribute: "CurrentMode" - response: - saveAs: old_current_mode_dut - constraints: - type: int8u - - - label: - "If startup_mode_dut is equal to old_current_mode_dut proceed to step - 6. Else proceed to step 8" - PICS: TCCM.S.A0002 && TCCM.S.A0001 - cluster: "EqualityCommands" - command: "UnsignedNumberEquals" - arguments: - values: - - name: "Value1" - value: startup_mode_dut - - name: "Value2" - value: old_current_mode_dut - response: - - values: - - name: "Equals" - saveAs: Step5_IsExpectedValue - - - label: "Step 6: TH reads from the DUT the SupportedModes attribute." - runIf: Step5_IsExpectedValue - PICS: TCCM.S.A0000 - command: "readAttribute" - attribute: "SupportedModes" - response: - saveAs: Step6_supported_modes_dut - constraints: - type: list - minLength: 2 - - - label: - "Step 7: TH sends a ChangeToMode command to the DUT with NewMode set - to new_mode_th" - runIf: Step5_IsExpectedValue - PICS: DISHM.S.C00.Rsp - command: "ChangeToMode" - arguments: - values: - - name: "NewMode" - value: new_mode_th - - - label: "Step 8: Physically power cycle the device." - verification: | - Physically power cycle the device. - cluster: "LogCommands" - command: "UserPrompt" - PICS: PICS_SKIP_SAMPLE_APP - arguments: - values: - - name: "message" - value: "Please enter 'y' for success" - - name: "expectedValue" - value: "y" - - - label: "Wait for the commissioned device to be retrieved" - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 9: TH reads from the DUT the StartUpMode attribute." - PICS: TCCM.S.A0002 && PICS_SKIP_SAMPLE_APP - command: "readAttribute" - attribute: "StartUpMode" - response: - saveAs: new_start_up_mode_dut - constraints: - type: int8u - anyOf: [new_start_up_mode_th, startup_mode_dut] - - - label: "Step 10: TH reads from the DUT the CurrentMode attribute." - PICS: TCCM.S.A0001 && PICS_SKIP_SAMPLE_APP - command: "readAttribute" - attribute: "CurrentMode" - response: - value: new_start_up_mode_dut - constraints: - type: int8u diff --git a/src/app/tests/suites/certification/Test_TC_TCCM_3_3.yaml b/src/app/tests/suites/certification/Test_TC_TCCM_3_3.yaml deleted file mode 100644 index 64d8b3f7d637e9..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_TCCM_3_3.yaml +++ /dev/null @@ -1,195 +0,0 @@ -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -name: - 219.3.3. [TC-TCCM-3.3] On Mode and Startup Mode functionality with DUT as - Server - -PICS: - - TCCM.S.A0002 - - TCCM.S.A0003 - - MOD.S.F00 - - OO.S.A4003 - -config: - nodeId: 0x12344321 - cluster: "Refrigerator And Temperature Controlled Cabinet Mode" - endpoint: 1 - - new_start_up_mode_th: - type: int8u - defaultValue: 0 - new_mode_th: - type: int8u - defaultValue: 1 - -tests: - - label: - "Step 1: Commission DUT to TH (can be skipped if done in a preceding - test)." - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 2: TH reads from the DUT the SupportedModes attribute." - PICS: TCCM.S.A0002 - command: "readAttribute" - attribute: "StartUpMode" - response: - saveAs: startup_mode_dut - constraints: - type: int8u - - - label: - "If startup_mode_dut is null proceed to step 3. Else save - startup_mode_dut as new_start_up_mode_th and proceed to step 5" - PICS: TCCM.S.A0002 - cluster: "EqualityCommands" - command: "UnsignedNumberEquals" - arguments: - values: - - name: "Value1" - value: startup_mode_dut - - name: "Value2" - value: null - response: - - values: - - name: "Equals" - saveAs: IsExpectedValue - - - label: "Step 3: TH reads from the DUT the SupportedModes attribute." - runIf: IsExpectedValue - PICS: TCCM.S.A0000 - command: "readAttribute" - attribute: "SupportedModes" - response: - saveAs: supported_modes_dut - constraints: - type: list - minLength: 2 - - - label: - "Step 4:TH writes to the DUT the StartUpMode attribute with the - new_start_up_mode_th value" - runIf: IsExpectedValue - PICS: TCCM.S.A0002 - command: "writeAttribute" - attribute: "StartUpMode" - arguments: - value: new_start_up_mode_th - - - label: "Step 5: TH reads from the DUT the OnMode attribute." - PICS: TCCM.S.A0003 && TCCM.S.A0002 - command: "readAttribute" - attribute: "OnMode" - response: - saveAs: old_on_mode_dut - constraints: - type: int8u - - - label: - "If startup_mode_dut is equal to old_on_mode_dut proceed to step 6. - Else proceed to step 8." - PICS: TCCM.S.A0003 && TCCM.S.A0002 - cluster: "EqualityCommands" - command: "UnsignedNumberEquals" - arguments: - values: - - name: "Value1" - value: startup_mode_dut - - name: "Value2" - value: old_on_mode_dut - response: - - values: - - name: "Equals" - saveAs: Step5_IsExpectedValue - - - label: "Step 6: TH reads the SupportedModes attribute from the DUT" - runIf: Step5_IsExpectedValue - PICS: TCCM.S.A0000 && TCCM.S.A0002 - command: "readAttribute" - attribute: "SupportedModes" - response: - saveAs: step6_supported_modes_dut - constraints: - type: list - minLength: 2 - - - label: - "Step 7:TH writes to the DUT the OnMode attribute with the new_mode_th - value" - runIf: Step5_IsExpectedValue - PICS: TCCM.S.A0003 - command: "writeAttribute" - attribute: "OnMode" - arguments: - value: new_mode_th - - - label: "Step 8: TH reads from the DUT the OnMode attribute." - PICS: TCCM.S.A0003 && MOD.S.F00 - command: "readAttribute" - attribute: "OnMode" - response: - saveAs: new_on_mode_dut - constraints: - anyOf: [new_mode_th, old_on_mode_dut] - - - label: - "Step 9:TH writes to the DUT the StartUpOnOff attribute with the value - 1" - PICS: OO.S.A4003 - cluster: "On/Off" - command: "writeAttribute" - attribute: "StartUpOnOff" - arguments: - value: 1 - - - label: "Step 10: Physically power cycle the device." - verification: | - Physically power cycle the device. - cluster: "LogCommands" - command: "UserPrompt" - PICS: PICS_SKIP_SAMPLE_APP - arguments: - values: - - name: "message" - value: "Please enter 'y' for success" - - name: "expectedValue" - value: "y" - - - label: "Wait for the commissioned device to be retrieved" - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "Step 11: TH reads from the DUT the StartUpMode attribute." - PICS: TCCM.S.A0002 && PICS_SKIP_SAMPLE_APP - command: "readAttribute" - attribute: "StartUpMode" - response: - constraints: - anyOf: [new_start_up_mode_th, startup_mode_dut] - - - label: "Step 12: TH reads from the DUT the CurrentMode attribute." - PICS: TCCM.S.A0001 && PICS_SKIP_SAMPLE_APP - command: "readAttribute" - attribute: "CurrentMode" - response: - value: new_on_mode_dut From a0d7b14cde8f41d5096742bb50044b3408a532d9 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Wed, 23 Oct 2024 02:24:01 -0400 Subject: [PATCH 076/149] Add a method for validating data-value dictionaries. (#36207) --- src/darwin/Framework/CHIP/MTRBaseDevice.mm | 55 ++- .../Framework/CHIP/MTRBaseDevice_Internal.h | 4 +- .../Framework/CHIP/MTRDevice_Internal.h | 7 + .../Framework/CHIPTests/MTRDeviceTests.m | 368 ++++++++++++++++++ 4 files changed, 413 insertions(+), 21 deletions(-) diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.mm b/src/darwin/Framework/CHIP/MTRBaseDevice.mm index a298b296849d51..2f75038eda97a2 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.mm +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.mm @@ -613,7 +613,9 @@ - (void)subscribeWithQueue:(dispatch_queue_t)queue } } -static CHIP_ERROR MTREncodeTLVFromDataValueDictionaryInternal(id object, chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) +// writer is allowed to be null to just validate the incoming object without +// actually encoding. +static CHIP_ERROR MTREncodeTLVFromDataValueDictionaryInternal(id object, chip::TLV::TLVWriter * writer, chip::TLV::Tag tag) { if (![object isKindOfClass:[NSDictionary class]]) { MTR_LOG_ERROR("Error: Unsupported object to encode: %@", [object class]); @@ -631,60 +633,62 @@ static CHIP_ERROR MTREncodeTLVFromDataValueDictionaryInternal(id object, chip::T MTR_LOG_ERROR("Error: Object to encode has corrupt signed integer type: %@", [value class]); return CHIP_ERROR_INVALID_ARGUMENT; } - return writer.Put(tag, [value longLongValue]); + return writer ? writer->Put(tag, [value longLongValue]) : CHIP_NO_ERROR; } if ([typeName isEqualToString:MTRUnsignedIntegerValueType]) { if (![value isKindOfClass:[NSNumber class]]) { MTR_LOG_ERROR("Error: Object to encode has corrupt unsigned integer type: %@", [value class]); return CHIP_ERROR_INVALID_ARGUMENT; } - return writer.Put(tag, [value unsignedLongLongValue]); + return writer ? writer->Put(tag, [value unsignedLongLongValue]) : CHIP_NO_ERROR; } if ([typeName isEqualToString:MTRBooleanValueType]) { if (![value isKindOfClass:[NSNumber class]]) { MTR_LOG_ERROR("Error: Object to encode has corrupt boolean type: %@", [value class]); return CHIP_ERROR_INVALID_ARGUMENT; } - return writer.Put(tag, static_cast([value boolValue])); + return writer ? writer->Put(tag, static_cast([value boolValue])) : CHIP_NO_ERROR; } if ([typeName isEqualToString:MTRFloatValueType]) { if (![value isKindOfClass:[NSNumber class]]) { MTR_LOG_ERROR("Error: Object to encode has corrupt float type: %@", [value class]); return CHIP_ERROR_INVALID_ARGUMENT; } - return writer.Put(tag, [value floatValue]); + return writer ? writer->Put(tag, [value floatValue]) : CHIP_NO_ERROR; } if ([typeName isEqualToString:MTRDoubleValueType]) { if (![value isKindOfClass:[NSNumber class]]) { MTR_LOG_ERROR("Error: Object to encode has corrupt double type: %@", [value class]); return CHIP_ERROR_INVALID_ARGUMENT; } - return writer.Put(tag, [value doubleValue]); + return writer ? writer->Put(tag, [value doubleValue]) : CHIP_NO_ERROR; } if ([typeName isEqualToString:MTRNullValueType]) { - return writer.PutNull(tag); + return writer ? writer->PutNull(tag) : CHIP_NO_ERROR; } if ([typeName isEqualToString:MTRUTF8StringValueType]) { if (![value isKindOfClass:[NSString class]]) { MTR_LOG_ERROR("Error: Object to encode has corrupt UTF8 string type: %@", [value class]); return CHIP_ERROR_INVALID_ARGUMENT; } - return writer.PutString(tag, AsCharSpan(value)); + return writer ? writer->PutString(tag, AsCharSpan(value)) : CHIP_NO_ERROR; } if ([typeName isEqualToString:MTROctetStringValueType]) { if (![value isKindOfClass:[NSData class]]) { MTR_LOG_ERROR("Error: Object to encode has corrupt octet string type: %@", [value class]); return CHIP_ERROR_INVALID_ARGUMENT; } - return writer.Put(tag, AsByteSpan(value)); + return writer ? writer->Put(tag, AsByteSpan(value)) : CHIP_NO_ERROR; } if ([typeName isEqualToString:MTRStructureValueType]) { if (![value isKindOfClass:[NSArray class]]) { MTR_LOG_ERROR("Error: Object to encode has corrupt structure type: %@", [value class]); return CHIP_ERROR_INVALID_ARGUMENT; } - TLV::TLVType outer; - ReturnErrorOnFailure(writer.StartContainer(tag, chip::TLV::kTLVType_Structure, outer)); + TLV::TLVType outer = TLV::kTLVType_NotSpecified; + if (writer) { + ReturnErrorOnFailure(writer->StartContainer(tag, chip::TLV::kTLVType_Structure, outer)); + } for (id element in value) { if (![element isKindOfClass:[NSDictionary class]]) { MTR_LOG_ERROR("Error: Structure element to encode has corrupt type: %@", [element class]); @@ -713,7 +717,9 @@ static CHIP_ERROR MTREncodeTLVFromDataValueDictionaryInternal(id object, chip::T ReturnErrorOnFailure( MTREncodeTLVFromDataValueDictionaryInternal(elementValue, writer, tag)); } - ReturnErrorOnFailure(writer.EndContainer(outer)); + if (writer) { + ReturnErrorOnFailure(writer->EndContainer(outer)); + } return CHIP_NO_ERROR; } if ([typeName isEqualToString:MTRArrayValueType]) { @@ -721,8 +727,10 @@ static CHIP_ERROR MTREncodeTLVFromDataValueDictionaryInternal(id object, chip::T MTR_LOG_ERROR("Error: Object to encode has corrupt array type: %@", [value class]); return CHIP_ERROR_INVALID_ARGUMENT; } - TLV::TLVType outer; - ReturnErrorOnFailure(writer.StartContainer(tag, chip::TLV::kTLVType_Array, outer)); + TLV::TLVType outer = TLV::kTLVType_NotSpecified; + if (writer) { + ReturnErrorOnFailure(writer->StartContainer(tag, chip::TLV::kTLVType_Array, outer)); + } for (id element in value) { if (![element isKindOfClass:[NSDictionary class]]) { MTR_LOG_ERROR("Error: Array element to encode has corrupt type: %@", [element class]); @@ -735,14 +743,16 @@ static CHIP_ERROR MTREncodeTLVFromDataValueDictionaryInternal(id object, chip::T } ReturnErrorOnFailure(MTREncodeTLVFromDataValueDictionaryInternal(elementValue, writer, chip::TLV::AnonymousTag())); } - ReturnErrorOnFailure(writer.EndContainer(outer)); + if (writer) { + ReturnErrorOnFailure(writer->EndContainer(outer)); + } return CHIP_NO_ERROR; } MTR_LOG_ERROR("Error: Unsupported type to encode: %@", typeName); return CHIP_ERROR_INVALID_ARGUMENT; } -static CHIP_ERROR MTREncodeTLVFromDataValueDictionary(id object, chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) +static CHIP_ERROR MTREncodeTLVFromDataValueDictionary(id object, chip::TLV::TLVWriter * writer, chip::TLV::Tag tag) { CHIP_ERROR err = MTREncodeTLVFromDataValueDictionaryInternal(object, writer, tag); if (err != CHIP_NO_ERROR) { @@ -761,7 +771,7 @@ static CHIP_ERROR MTREncodeTLVFromDataValueDictionary(id object, chip::TLV::TLVW TLV::TLVWriter writer; writer.Init(buffer); - CHIP_ERROR err = MTREncodeTLVFromDataValueDictionary(value, writer, TLV::AnonymousTag()); + CHIP_ERROR err = MTREncodeTLVFromDataValueDictionary(value, &writer, TLV::AnonymousTag()); if (err != CHIP_NO_ERROR) { if (error) { *error = [MTRError errorForCHIPErrorCode:err]; @@ -772,6 +782,11 @@ static CHIP_ERROR MTREncodeTLVFromDataValueDictionary(id object, chip::TLV::TLVW return AsData(ByteSpan(buffer, writer.GetLengthWritten())); } +BOOL MTRDataValueDictionaryIsWellFormed(MTRDeviceDataValueDictionary value) +{ + return MTREncodeTLVFromDataValueDictionary(value, nullptr, TLV::AnonymousTag()) == CHIP_NO_ERROR; +} + // Callback type to pass data value as an NSObject typedef void (*MTRDataValueDictionaryCallback)(void * context, id value); @@ -798,7 +813,7 @@ CHIP_ERROR Decode(chip::TLV::TLVReader & data) CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, chip::TLV::Tag tag) const { - return MTREncodeTLVFromDataValueDictionary(decodedObj, writer, tag); + return MTREncodeTLVFromDataValueDictionary(decodedObj, &writer, tag); } static constexpr bool kIsFabricScoped = false; @@ -2212,7 +2227,7 @@ + (NSDictionary *)eventReportForHeader:(const chip::app::EventHeader &)header an // Commands never need chained buffers, since they cannot be chunked. writer.Init(std::move(buffer), /* useChainedBuffers = */ false); - CHIP_ERROR errorCode = MTREncodeTLVFromDataValueDictionary(data, writer, TLV::AnonymousTag()); + CHIP_ERROR errorCode = MTREncodeTLVFromDataValueDictionary(data, &writer, TLV::AnonymousTag()); if (errorCode != CHIP_NO_ERROR) { LogStringAndReturnError(@"Unable to encode data-value to TLV", errorCode, error); return System::PacketBufferHandle(); @@ -3082,7 +3097,7 @@ static bool EncodeDataValueToTLV(System::PacketBufferHandle & buffer, Platform:: System::PacketBufferTLVWriter writer; writer.Init(std::move(buffer), /* useChainedBuffers = */ true); - CHIP_ERROR errorCode = MTREncodeTLVFromDataValueDictionary(data, writer, TLV::AnonymousTag()); + CHIP_ERROR errorCode = MTREncodeTLVFromDataValueDictionary(data, &writer, TLV::AnonymousTag()); if (errorCode != CHIP_NO_ERROR) { LogStringAndReturnError(@"Unable to encode data-value to TLV", errorCode, error); return false; diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice_Internal.h b/src/darwin/Framework/CHIP/MTRBaseDevice_Internal.h index 1482d80634da43..075ee99da20990 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice_Internal.h +++ b/src/darwin/Framework/CHIP/MTRBaseDevice_Internal.h @@ -18,6 +18,8 @@ #import "MTRBaseDevice.h" #import +#import "MTRDeviceDataValueDictionary.h" + #include #include #include @@ -257,6 +259,6 @@ NSDictionary * _Nullable MTRDecodeDataValueDictionaryFromCHIPTLV // TLV Data with an anonymous tag. This method assumes the encoding of the // value fits in a single UDP MTU; for lists this method might need to be used // on each list item separately. -NSData * _Nullable MTREncodeTLVFromDataValueDictionary(NSDictionary * value, NSError * __autoreleasing * error); +NSData * _Nullable MTREncodeTLVFromDataValueDictionary(MTRDeviceDataValueDictionary value, NSError * __autoreleasing * error); NS_ASSUME_NONNULL_END diff --git a/src/darwin/Framework/CHIP/MTRDevice_Internal.h b/src/darwin/Framework/CHIP/MTRDevice_Internal.h index df4a8265538dfe..4414b3c6133b07 100644 --- a/src/darwin/Framework/CHIP/MTRDevice_Internal.h +++ b/src/darwin/Framework/CHIP/MTRDevice_Internal.h @@ -176,6 +176,13 @@ MTR_DIRECT_MEMBERS - (void)devicePrivateInternalStateChanged:(MTRDevice *)device internalState:(NSDictionary *)state; @end +// Returns whether a data-value dictionary is well-formed (in the sense that all +// the types of the objects inside are as expected, so it's actually a valid +// representation of some TLV). Implemented in MTRBaseDevice.mm because that's +// where the pieces needed to implement it are, but declared here so our tests +// can see it. +MTR_EXTERN MTR_TESTABLE BOOL MTRDataValueDictionaryIsWellFormed(MTRDeviceDataValueDictionary value); + #pragma mark - Constants static NSString * const kDefaultSubscriptionPoolSizeOverrideKey = @"subscriptionPoolSizeOverride"; diff --git a/src/darwin/Framework/CHIPTests/MTRDeviceTests.m b/src/darwin/Framework/CHIPTests/MTRDeviceTests.m index 9d33649057ddb1..3fa4ff45449f89 100644 --- a/src/darwin/Framework/CHIPTests/MTRDeviceTests.m +++ b/src/darwin/Framework/CHIPTests/MTRDeviceTests.m @@ -4819,6 +4819,374 @@ - (void)test040_AttributeValueExpectationSatisfaction } } +- (void)test041_AttributeDataValueValidation +{ + __auto_type * testData = @[ + @{ + @"input" : @ { + MTRTypeKey : MTRSignedIntegerValueType, + MTRValueKey : @(-5), + }, + // -5 is a valid signed integer. + @"valid" : @(YES), + }, + @{ + @"input" : @ { + MTRTypeKey : MTRSignedIntegerValueType, + MTRValueKey : @ {}, + }, + // A dictionary is not a valid signed integer. + @"valid" : @(NO), + }, + @{ + @"input" : @ { + MTRTypeKey : MTRUnsignedIntegerValueType, + MTRValueKey : @(7), + }, + // 7 is a valid unsigned integer. + @"valid" : @(YES), + }, + @{ + @"input" : @ { + MTRTypeKey : MTRUnsignedIntegerValueType, + MTRValueKey : @("abc"), + }, + // "abc" is not an unsigned integer. + @"valid" : @(NO), + }, + @{ + @"input" : @ { + MTRTypeKey : MTRBooleanValueType, + MTRValueKey : @(YES), + }, + // YES is a boolean. + @"valid" : @(YES), + }, + @{ + @"input" : @ { + MTRTypeKey : MTRBooleanValueType, + MTRValueKey : [NSData data], + }, + // NSData is not a boolean integer. + @"valid" : @(NO), + }, + @{ + @"input" : @ { + MTRTypeKey : MTRFloatValueType, + MTRValueKey : @(8), + }, + // 8 is a valid float. + @"valid" : @(YES), + }, + @{ + @"input" : @ { + MTRTypeKey : MTRFloatValueType, + MTRValueKey : @(8.5), + }, + // 8.5 is a valid float. + @"valid" : @(YES), + }, + @{ + @"input" : @ { + MTRTypeKey : MTRFloatValueType, + MTRValueKey : @[], + }, + // An array is not a float. + @"valid" : @(NO), + }, + @{ + @"input" : @ { + MTRTypeKey : MTRDoubleValueType, + MTRValueKey : @(180), + }, + // 180 is a valid double. + @"valid" : @(YES), + }, + @{ + @"input" : @ { + MTRTypeKey : MTRDoubleValueType, + MTRValueKey : @(9.5), + }, + // 9.5 is a valid double. + @"valid" : @(YES), + }, + @{ + @"input" : @ { + MTRTypeKey : MTRDoubleValueType, + MTRValueKey : [NSDate date], + }, + // A date is not a double. + @"valid" : @(NO), + }, + @{ + @"input" : @ { + MTRTypeKey : MTRNullValueType, + }, + // This is a valid null value. + @"valid" : @(YES), + }, + @{ + @"input" : @ { + MTRTypeKey : MTRUTF8StringValueType, + MTRValueKey : @("def"), + }, + // "def" is a valid string. + @"valid" : @(YES), + }, + @{ + @"input" : @ { + MTRTypeKey : MTRUTF8StringValueType, + MTRValueKey : [NSData data], + }, + // NSData is not a string. + @"valid" : @(NO), + }, + @{ + @"input" : @ { + MTRTypeKey : MTROctetStringValueType, + MTRValueKey : [NSData data], + }, + // NSData is an octet string. + @"valid" : @(YES), + }, + @{ + @"input" : @ { + MTRTypeKey : MTROctetStringValueType, + MTRValueKey : @(7), + }, + // 7 is not an octet string. + @"valid" : @(NO), + }, + @{ + @"input" : @ { + MTRTypeKey : MTROctetStringValueType, + MTRValueKey : @("abc"), + }, + // "abc" is not an octet string. + @"valid" : @(NO), + }, + @{ + @"input" : @ { + MTRTypeKey : MTRStructureValueType, + MTRValueKey : @[], + }, + // This is a valid empty structure. + @"valid" : @(YES), + }, + @{ + @"input" : @ { + MTRTypeKey : MTRStructureValueType, + MTRValueKey : @[], + }, + // This is a valid empty structure. + @"valid" : @(YES), + }, + @{ + @"input" : @ { + MTRTypeKey : MTRStructureValueType, + MTRValueKey : @[ + @{ + MTRContextTagKey : @(7), + MTRDataKey : @ { + MTRTypeKey : MTRNullValueType + }, + }, + ], + }, + // This is a valid structure, one null field. + @"valid" : @(YES), + }, + @{ + @"input" : @ { + MTRTypeKey : MTRStructureValueType, + MTRValueKey : @[ + @{ + MTRContextTagKey : @(1), + MTRDataKey : @ { + MTRTypeKey : MTRNullValueType + }, + }, + @{ + MTRContextTagKey : @(2), + MTRDataKey : @ { + MTRTypeKey : MTRUnsignedIntegerValueType, + MTRValueKey : @(9) + }, + }, + ], + }, + // This is a valid structure with two fields. + @"valid" : @(YES), + }, + @{ + @"input" : @ { + MTRTypeKey : MTRStructureValueType, + MTRValueKey : @(19), + }, + // 19 is not a structure. + @"valid" : @(NO), + }, + @{ + @"input" : @ { + MTRTypeKey : MTRStructureValueType, + MTRValueKey : @[ + @{ + MTRDataKey : @ { + MTRTypeKey : MTRNullValueType + }, + }, + ], + }, + // Field does not have a context tag. + @"valid" : @(NO), + }, + @{ + @"input" : @ { + MTRTypeKey : MTRStructureValueType, + MTRValueKey : @[ + @{ + MTRContextTagKey : @(7), + }, + ], + }, + // Field does not have a value. + @"valid" : @(NO), + }, + @{ + @"input" : @ { + MTRTypeKey : MTRStructureValueType, + MTRValueKey : @[ + @{ + MTRContextTagKey : @(7), + MTRDataKey : @(5), + }, + ], + }, + // Field value is a number, not a data-value + @"valid" : @(NO), + }, + @{ + @"input" : @ { + MTRTypeKey : MTRStructureValueType, + MTRValueKey : @[ + @{ + MTRContextTagKey : @(7), + MTRDataKey : @[], + }, + ], + }, + // Field value is an array, not a data-value + @"valid" : @(NO), + }, + @{ + @"input" : @ { + MTRTypeKey : MTRStructureValueType, + MTRValueKey : @[ + @{ + MTRContextTagKey : @(7), + MTRDataKey : @ {}, + }, + ], + }, + // Field value is an invalid data-value + @"valid" : @(NO), + }, + @{ + @"input" : @ { + MTRTypeKey : MTRStructureValueType, + MTRValueKey : @[ + @{ + MTRContextTagKey : @("abc"), + MTRDataKey : @ { + MTRTypeKey : MTRNullValueType + }, + }, + ], + }, + // Tag is not a number. + @"valid" : @(NO), + }, + @{ + @"input" : @ { + MTRTypeKey : MTRArrayValueType, + MTRValueKey : @[], + }, + // This is a valid empty array. + @"valid" : @(YES), + }, + @{ + @"input" : @ { + MTRTypeKey : MTRArrayValueType, + MTRValueKey : @[ + @{ + MTRDataKey : @ { + MTRTypeKey : MTRNullValueType + }, + }, + ], + }, + // This is an array with a single null value in it. + @"valid" : @(YES), + }, + @{ + @"input" : @ { + MTRTypeKey : MTRArrayValueType, + MTRValueKey : @[ + @{ + MTRDataKey : @ { + MTRTypeKey : MTRUnsignedIntegerValueType, + MTRValueKey : @(8), + }, + }, + @{ + MTRDataKey : @ { + MTRTypeKey : MTRUnsignedIntegerValueType, + MTRValueKey : @(10), + }, + }, + ], + }, + // This is an array with two integers in it. + @"valid" : @(YES), + }, + @{ + @"input" : @ { + MTRTypeKey : MTRArrayValueType, + MTRValueKey : @[ + @{ + MTRTypeKey : MTRUnsignedIntegerValueType, + MTRValueKey : @(8), + }, + ], + }, + // This does not have a proper array-value in the array: missing MTRDataKey. + @"valid" : @(NO), + }, + @{ + @"input" : @ { + MTRTypeKey : MTRArrayValueType, + MTRValueKey : @[ @(7) ], + }, + // This does not have a proper array-value in the array: not a dictionary. + @"valid" : @(NO), + }, + @{ + @"input" : @ { + MTRTypeKey : MTRArrayValueType, + MTRValueKey : @[ @{} ], + }, + // This does not have a proper array-value in the array: empty + // dictionary, so no MTRDataKey. + @"valid" : @(NO), + }, + ]; + + for (NSDictionary * test in testData) { + XCTAssertEqual(MTRDataValueDictionaryIsWellFormed(test[@"input"]), [test[@"valid"] boolValue], + "input: %@", test[@"input"]); + } +} + @end @interface MTRDeviceEncoderTests : XCTestCase From 42421c4d7da332d869774d47cc794d33a14824cd Mon Sep 17 00:00:00 2001 From: Arkadiusz Bokowy Date: Wed, 23 Oct 2024 14:25:21 +0200 Subject: [PATCH 077/149] Update pigweed to latest master (#36193) * Update pigweed to latest master * Fix matter_yamltests_distribution path after pigweed update * Regen configs * Drop `extern "C"` from main functions * Workaround for NuttX platform linking C++ main as C * Update pigweed --- .../all-clusters-app/nxp/common/main/main.cpp | 2 +- .../contact-sensor-app/nxp/common/main.cpp | 2 +- .../nxp/common/main/main.cpp | 2 +- examples/light-switch-app/genio/src/main.cpp | 2 +- .../linux/main.cpp | 2 +- examples/lighting-app/genio/src/main.cpp | 2 +- examples/lighting-app/linux/main.cpp | 13 +- examples/lighting-app/nxp/common/main.cpp | 2 +- examples/lock-app/genio/src/main.cpp | 2 +- examples/lock-app/nxp/common/main/main.cpp | 2 +- examples/ota-requestor-app/genio/src/main.cpp | 2 +- .../openiotsdk/app/openiotsdk_startup_gcc.cpp | 2 +- examples/shell/genio/src/main.cpp | 2 +- examples/thermostat/genio/src/main.cpp | 2 +- examples/thermostat/nxp/common/main/main.cpp | 2 +- scripts/BUILD.gn | 4 +- scripts/build_python.sh | 28 +--- .../app-templates/endpoint_config.h | 158 +++++++++--------- .../app-templates/endpoint_config.h | 18 +- src/lib/address_resolve/tool.cpp | 2 +- src/test_driver/nrfconnect/main/runner.cpp | 2 +- src/tools/chip-cert/chip-cert.cpp | 2 +- src/tools/spake2p/spake2p.cpp | 2 +- third_party/pigweed/repo | 2 +- third_party/pigweed/update.sh | 4 +- 25 files changed, 121 insertions(+), 142 deletions(-) mode change 100644 => 100755 third_party/pigweed/update.sh diff --git a/examples/all-clusters-app/nxp/common/main/main.cpp b/examples/all-clusters-app/nxp/common/main/main.cpp index b2aadab98ceb8b..26772e9e600659 100644 --- a/examples/all-clusters-app/nxp/common/main/main.cpp +++ b/examples/all-clusters-app/nxp/common/main/main.cpp @@ -32,7 +32,7 @@ uint8_t __attribute__((section(".heap"))) ucHeap[configTOTAL_HEAP_SIZE]; using namespace ::chip::DeviceLayer; -extern "C" int main(int argc, char * argv[]) +int main(int argc, char * argv[]) { TaskHandle_t taskHandle; diff --git a/examples/contact-sensor-app/nxp/common/main.cpp b/examples/contact-sensor-app/nxp/common/main.cpp index d9672b5402c867..ee193927912eeb 100644 --- a/examples/contact-sensor-app/nxp/common/main.cpp +++ b/examples/contact-sensor-app/nxp/common/main.cpp @@ -30,7 +30,7 @@ extern "C" void main_task(void const * argument) chip::NXP::App::GetAppTask().Start(); } #else -extern "C" int main(int argc, char * argv[]) +int main(int argc, char * argv[]) { chip::DeviceLayer::PlatformMgrImpl().HardwareInit(); chip::NXP::App::GetAppTask().Start(); diff --git a/examples/laundry-washer-app/nxp/common/main/main.cpp b/examples/laundry-washer-app/nxp/common/main/main.cpp index b2aadab98ceb8b..26772e9e600659 100644 --- a/examples/laundry-washer-app/nxp/common/main/main.cpp +++ b/examples/laundry-washer-app/nxp/common/main/main.cpp @@ -32,7 +32,7 @@ uint8_t __attribute__((section(".heap"))) ucHeap[configTOTAL_HEAP_SIZE]; using namespace ::chip::DeviceLayer; -extern "C" int main(int argc, char * argv[]) +int main(int argc, char * argv[]) { TaskHandle_t taskHandle; diff --git a/examples/light-switch-app/genio/src/main.cpp b/examples/light-switch-app/genio/src/main.cpp index d545409c706913..564233716d1d9a 100644 --- a/examples/light-switch-app/genio/src/main.cpp +++ b/examples/light-switch-app/genio/src/main.cpp @@ -251,7 +251,7 @@ void vStartTask(void * pvParameters) * Main Function ****************************************************************************/ -extern "C" int main(void) +int main(void) { mbedtls_platform_set_calloc_free(CHIPPlatformMemoryCalloc, CHIPPlatformMemoryFree); diff --git a/examples/lighting-app-data-mode-no-unique-id/linux/main.cpp b/examples/lighting-app-data-mode-no-unique-id/linux/main.cpp index 8e586b5cf56d54..56cafc2e527509 100644 --- a/examples/lighting-app-data-mode-no-unique-id/linux/main.cpp +++ b/examples/lighting-app-data-mode-no-unique-id/linux/main.cpp @@ -95,7 +95,7 @@ void ApplicationShutdown() } } -extern "C" int main(int argc, char * argv[]) +int main(int argc, char * argv[]) { if (ChipLinuxAppInit(argc, argv) != 0) { diff --git a/examples/lighting-app/genio/src/main.cpp b/examples/lighting-app/genio/src/main.cpp index 22f654eb5f2f50..2db77457d2e7b1 100644 --- a/examples/lighting-app/genio/src/main.cpp +++ b/examples/lighting-app/genio/src/main.cpp @@ -251,7 +251,7 @@ void vStartTask(void * pvParameters) * Main Function ****************************************************************************/ -extern "C" int main(void) +int main(void) { mbedtls_platform_set_calloc_free(CHIPPlatformMemoryCalloc, CHIPPlatformMemoryFree); diff --git a/examples/lighting-app/linux/main.cpp b/examples/lighting-app/linux/main.cpp index 8e586b5cf56d54..46dea03cdebccb 100644 --- a/examples/lighting-app/linux/main.cpp +++ b/examples/lighting-app/linux/main.cpp @@ -95,7 +95,14 @@ void ApplicationShutdown() } } -extern "C" int main(int argc, char * argv[]) +#ifdef __NuttX__ +// NuttX requires the main function to be defined with C-linkage. However, marking +// the main as extern "C" is not strictly conformant with the C++ standard. Since +// clang >= 20 such code triggers -Wmain warning. +extern "C" { +#endif + +int main(int argc, char * argv[]) { if (ChipLinuxAppInit(argc, argv) != 0) { @@ -124,3 +131,7 @@ extern "C" int main(int argc, char * argv[]) return 0; } + +#ifdef __NuttX__ +} +#endif diff --git a/examples/lighting-app/nxp/common/main.cpp b/examples/lighting-app/nxp/common/main.cpp index d9672b5402c867..ee193927912eeb 100644 --- a/examples/lighting-app/nxp/common/main.cpp +++ b/examples/lighting-app/nxp/common/main.cpp @@ -30,7 +30,7 @@ extern "C" void main_task(void const * argument) chip::NXP::App::GetAppTask().Start(); } #else -extern "C" int main(int argc, char * argv[]) +int main(int argc, char * argv[]) { chip::DeviceLayer::PlatformMgrImpl().HardwareInit(); chip::NXP::App::GetAppTask().Start(); diff --git a/examples/lock-app/genio/src/main.cpp b/examples/lock-app/genio/src/main.cpp index 92b16a39663ee4..36564e13330f93 100644 --- a/examples/lock-app/genio/src/main.cpp +++ b/examples/lock-app/genio/src/main.cpp @@ -251,7 +251,7 @@ void vStartTask(void * pvParameters) * Main Function ****************************************************************************/ -extern "C" int main(void) +int main(void) { mbedtls_platform_set_calloc_free(CHIPPlatformMemoryCalloc, CHIPPlatformMemoryFree); diff --git a/examples/lock-app/nxp/common/main/main.cpp b/examples/lock-app/nxp/common/main/main.cpp index 09de048127518b..8565ca01af32e9 100644 --- a/examples/lock-app/nxp/common/main/main.cpp +++ b/examples/lock-app/nxp/common/main/main.cpp @@ -39,7 +39,7 @@ extern "C" void main_task(void const * argument) chip::NXP::App::GetAppTask().Start(); } #else -extern "C" int main(int argc, char * argv[]) +int main(int argc, char * argv[]) { chip::DeviceLayer::PlatformMgrImpl().HardwareInit(); chip::NXP::App::GetAppTask().Start(); diff --git a/examples/ota-requestor-app/genio/src/main.cpp b/examples/ota-requestor-app/genio/src/main.cpp index e3676c5c9eacbd..6c9f4f16c274f4 100644 --- a/examples/ota-requestor-app/genio/src/main.cpp +++ b/examples/ota-requestor-app/genio/src/main.cpp @@ -281,7 +281,7 @@ void vStartTask(void * pvParameters) * Main Function ****************************************************************************/ -extern "C" int main(void) +int main(void) { mbedtls_platform_set_calloc_free(CHIPPlatformMemoryCalloc, CHIPPlatformMemoryFree); diff --git a/examples/platform/openiotsdk/app/openiotsdk_startup_gcc.cpp b/examples/platform/openiotsdk/app/openiotsdk_startup_gcc.cpp index 9add2ca4e53777..88488ff64763da 100644 --- a/examples/platform/openiotsdk/app/openiotsdk_startup_gcc.cpp +++ b/examples/platform/openiotsdk/app/openiotsdk_startup_gcc.cpp @@ -57,7 +57,7 @@ alignas(8) static uint8_t malloc_mutex_obj[80]; // C runtime import: constructor initialization and main extern "C" void __libc_init_array(void); -extern "C" int main(void); +int main(void); // IOT SDK serial declarations #define STDIN_FILENO 0 diff --git a/examples/shell/genio/src/main.cpp b/examples/shell/genio/src/main.cpp index 7190fd232a0969..fb4b3e068a0d0c 100644 --- a/examples/shell/genio/src/main.cpp +++ b/examples/shell/genio/src/main.cpp @@ -161,7 +161,7 @@ void vStartTask(void * pvParameters) * Main Function ****************************************************************************/ -extern "C" int main(void) +int main(void) { mbedtls_platform_set_calloc_free(CHIPPlatformMemoryCalloc, CHIPPlatformMemoryFree); diff --git a/examples/thermostat/genio/src/main.cpp b/examples/thermostat/genio/src/main.cpp index d545409c706913..564233716d1d9a 100644 --- a/examples/thermostat/genio/src/main.cpp +++ b/examples/thermostat/genio/src/main.cpp @@ -251,7 +251,7 @@ void vStartTask(void * pvParameters) * Main Function ****************************************************************************/ -extern "C" int main(void) +int main(void) { mbedtls_platform_set_calloc_free(CHIPPlatformMemoryCalloc, CHIPPlatformMemoryFree); diff --git a/examples/thermostat/nxp/common/main/main.cpp b/examples/thermostat/nxp/common/main/main.cpp index b2aadab98ceb8b..26772e9e600659 100644 --- a/examples/thermostat/nxp/common/main/main.cpp +++ b/examples/thermostat/nxp/common/main/main.cpp @@ -32,7 +32,7 @@ uint8_t __attribute__((section(".heap"))) ucHeap[configTOTAL_HEAP_SIZE]; using namespace ::chip::DeviceLayer; -extern "C" int main(int argc, char * argv[]) +int main(int argc, char * argv[]) { TaskHandle_t taskHandle; diff --git a/scripts/BUILD.gn b/scripts/BUILD.gn index 0ebcab979112ca..ea1d49662fcb11 100644 --- a/scripts/BUILD.gn +++ b/scripts/BUILD.gn @@ -20,8 +20,8 @@ import("$dir_pw_build/python_dist.gni") # This target creates a single Python package and wheel for yamltests. It will # merge all Python dependencies Matter. The output is located in: -# out/obj/matter_yamltests_distribution/ <- source files here -# out/obj/matter_yamltests_distribution._build_wheel/matter_yamltests-0.0.1-py3-none-any.whl +# out/obj/scripts/matter_yamltests_distribution/ <- source files here +# out/obj/scripts/matter_yamltests_distribution._build_wheel/matter_yamltests-0.0.1-py3-none-any.whl pw_python_distribution("matter_yamltests_distribution") { packages = [ "${chip_root}/scripts/py_matter_yamltests:matter_yamltests" ] generate_setup_cfg = { diff --git a/scripts/build_python.sh b/scripts/build_python.sh index da3fe0cbedf733..7f03815f3fe7e3 100755 --- a/scripts/build_python.sh +++ b/scripts/build_python.sh @@ -175,22 +175,6 @@ tracing_options="matter_log_json_payload_hex=true matter_log_json_payload_decode gn --root="$CHIP_ROOT" gen "$OUTPUT_ROOT" --args="$tracing_options chip_detail_logging=$chip_detail_logging chip_project_config_include_dirs=[\"//config/python\"] $chip_mdns_arg $chip_case_retry_arg $pregen_dir_arg chip_config_network_layer_ble=$enable_ble chip_enable_ble=$enable_ble chip_crypto=\"boringssl\"" -function ninja_target() { - # Print the ninja target required to build a gn label. - local GN_LABEL="$1" - local NINJA_TARGET="$(gn ls "$OUTPUT_ROOT" --as=output "$GN_LABEL")" - echo "$NINJA_TARGET" -} - -function wheel_output_dir() { - # Print the wheel output directory for a pw_python_package or - # pw_python_distribution. The label must end in "._build_wheel". - local GN_LABEL="$1" - local NINJA_TARGET="$(ninja_target "$GN_LABEL")" - local WHEEL_DIR="$OUTPUT_ROOT"/"$(dirname "$NINJA_TARGET")/$(basename -s .stamp "$NINJA_TARGET")" - echo "$WHEEL_DIR" -} - # Compile Python wheels ninja -C "$OUTPUT_ROOT" python_wheels @@ -200,6 +184,11 @@ WHEEL=("$OUTPUT_ROOT"/controller/python/chip*.whl) # Add the matter_testing_infrastructure wheel WHEEL+=("$OUTPUT_ROOT"/python/obj/src/python_testing/matter_testing_infrastructure/chip-testing._build_wheel/chip_testing-*.whl) +if [ "$install_pytest_requirements" = "yes" ]; then + # Add the matter_yamltests_distribution wheel + WHEEL+=("$OUTPUT_ROOT"/obj/scripts/matter_yamltests_distribution._build_wheel/matter_yamltests-*.whl) +fi + if [ -n "$extra_packages" ]; then WHEEL+=("$extra_packages") fi @@ -221,14 +210,7 @@ if [ -n "$install_virtual_env" ]; then "$ENVIRONMENT_ROOT"/bin/python -m pip install --upgrade "${WHEEL[@]}" if [ "$install_pytest_requirements" = "yes" ]; then - YAMLTESTS_GN_LABEL="//scripts:matter_yamltests_distribution._build_wheel" - # Add wheels from pw_python_package or pw_python_distribution templates. - YAMLTEST_WHEEL=( - "$(ls -tr "$(wheel_output_dir "$YAMLTESTS_GN_LABEL")"/*.whl | head -n 1)" - ) - echo_blue "Installing python test dependencies ..." - "$ENVIRONMENT_ROOT"/bin/pip install --upgrade "${YAMLTEST_WHEEL[@]}" "$ENVIRONMENT_ROOT"/bin/pip install -r "$CHIP_ROOT/scripts/tests/requirements.txt" "$ENVIRONMENT_ROOT"/bin/pip install -r "$CHIP_ROOT/src/python_testing/requirements.txt" fi diff --git a/scripts/tools/zap/tests/outputs/all-clusters-app/app-templates/endpoint_config.h b/scripts/tools/zap/tests/outputs/all-clusters-app/app-templates/endpoint_config.h index 08215244b039aa..ec8cbd60457450 100644 --- a/scripts/tools/zap/tests/outputs/all-clusters-app/app-templates/endpoint_config.h +++ b/scripts/tools/zap/tests/outputs/all-clusters-app/app-templates/endpoint_config.h @@ -606,84 +606,82 @@ /* Endpoint: 0, Cluster: Unit Localization (server) */ \ { (uint16_t) 0x0, (uint16_t) 0x0, (uint16_t) 0x2 }, /* TemperatureUnit */ \ \ - /* Endpoint: 1, Cluster: On/Off (server) */ \ - { (uint16_t) 0xFF, (uint16_t) 0x0, (uint16_t) 0x2 }, /* StartUpOnOff */ \ - \ - /* Endpoint: 1, Cluster: Level Control (server) */ \ - { (uint16_t) 0x0, (uint16_t) 0x0, (uint16_t) 0x3 }, /* Options */ \ - { (uint16_t) 0x32, (uint16_t) 0x1, (uint16_t) 0xFF }, /* DefaultMoveRate */ \ - \ - /* Endpoint: 1, Cluster: Laundry Washer Controls (server) */ \ - { (uint16_t) 0x0, (uint16_t) 0x0, (uint16_t) 0x1F }, /* SpinSpeedCurrent */ \ - \ - /* Endpoint: 1, Cluster: Smoke CO Alarm (server) */ \ - { (uint16_t) 0x1, (uint16_t) 0x0, (uint16_t) 0x2 }, /* SmokeSensitivityLevel */ \ - \ - /* Endpoint: 1, Cluster: Valve Configuration and Control (server) */ \ - { (uint16_t) 0x64, (uint16_t) 0x1, (uint16_t) 0x64 }, /* DefaultOpenLevel */ \ - \ - /* Endpoint: 1, Cluster: Energy EVSE (server) */ \ - { (uint16_t) 0x0, (uint16_t) 0x0, (uint16_t) 0xFFFE }, /* ApproximateEVEfficiency */ \ - \ - /* Endpoint: 1, Cluster: Window Covering (server) */ \ - { (uint16_t) 0x0, (uint16_t) 0x0, (uint16_t) 0xF }, /* Mode */ \ - \ - /* Endpoint: 1, Cluster: Pump Configuration and Control (server) */ \ - { (uint16_t) 0x0, (uint16_t) 0x0, (uint16_t) 0x3 }, /* OperationMode */ \ - { (uint16_t) 0x0, (uint16_t) 0x0, (uint16_t) 0x7 }, /* ControlMode */ \ - \ - /* Endpoint: 1, Cluster: Thermostat (server) */ \ - { (uint16_t) 0xA28, (uint16_t) -0x6AB3, (uint16_t) 0x7FFF }, /* OccupiedCoolingSetpoint */ \ - { (uint16_t) 0x7D0, (uint16_t) -0x6AB3, (uint16_t) 0x7FFF }, /* OccupiedHeatingSetpoint */ \ - { (uint16_t) 0x2BC, (uint16_t) -0x6AB3, (uint16_t) 0x7FFF }, /* MinHeatSetpointLimit */ \ - { (uint16_t) 0xBB8, (uint16_t) -0x6AB3, (uint16_t) 0x7FFF }, /* MaxHeatSetpointLimit */ \ - { (uint16_t) 0x640, (uint16_t) -0x6AB3, (uint16_t) 0x7FFF }, /* MinCoolSetpointLimit */ \ - { (uint16_t) 0xC80, (uint16_t) -0x6AB3, (uint16_t) 0x7FFF }, /* MaxCoolSetpointLimit */ \ - { (uint16_t) 0x19, (uint16_t) 0x0, (uint16_t) 0x7F }, /* MinSetpointDeadBand */ \ - { (uint16_t) 0x4, (uint16_t) 0x0, (uint16_t) 0x5 }, /* ControlSequenceOfOperation */ \ - { (uint16_t) 0x1, (uint16_t) 0x0, (uint16_t) 0x9 }, /* SystemMode */ \ - \ - /* Endpoint: 1, Cluster: Fan Control (server) */ \ - { (uint16_t) 0x0, (uint16_t) 0x0, (uint16_t) 0x6 }, /* FanMode */ \ - { (uint16_t) 0x0, (uint16_t) 0x0, (uint16_t) 0x64 }, /* PercentSetting */ \ - { (uint16_t) 0x0, (uint16_t) 0x0, (uint16_t) 0x64 }, /* SpeedSetting */ \ - \ - /* Endpoint: 1, Cluster: Thermostat User Interface Configuration (server) */ \ - { (uint16_t) 0x0, (uint16_t) 0x0, (uint16_t) 0x1 }, /* TemperatureDisplayMode */ \ - { (uint16_t) 0x0, (uint16_t) 0x0, (uint16_t) 0x5 }, /* KeypadLockout */ \ - { (uint16_t) 0x0, (uint16_t) 0x0, (uint16_t) 0x1 }, /* ScheduleProgrammingVisibility */ \ - \ - /* Endpoint: 1, Cluster: Color Control (server) */ \ - { (uint16_t) 0x0, (uint16_t) 0x0, (uint16_t) 0xFEFF }, /* WhitePointX */ \ - { (uint16_t) 0x0, (uint16_t) 0x0, (uint16_t) 0xFEFF }, /* WhitePointY */ \ - { (uint16_t) 0x0, (uint16_t) 0x0, (uint16_t) 0xFEFF }, /* ColorPointRX */ \ - { (uint16_t) 0x0, (uint16_t) 0x0, (uint16_t) 0xFEFF }, /* ColorPointRY */ \ - { (uint16_t) 0x0, (uint16_t) 0x0, (uint16_t) 0xFEFF }, /* ColorPointGX */ \ - { (uint16_t) 0x0, (uint16_t) 0x0, (uint16_t) 0xFEFF }, /* ColorPointGY */ \ - { (uint16_t) 0x0, (uint16_t) 0x0, (uint16_t) 0xFEFF }, /* ColorPointBX */ \ - { (uint16_t) 0x0, (uint16_t) 0x0, (uint16_t) 0xFEFF }, /* ColorPointBY */ \ - { (uint16_t) 0xFA, (uint16_t) 0x0, (uint16_t) 0xFEFF }, /* StartUpColorTemperatureMireds */ \ - \ - /* Endpoint: 1, Cluster: Ballast Configuration (server) */ \ - { (uint16_t) 0x1, (uint16_t) 0x1, (uint16_t) 0xFE }, /* MinLevel */ \ - { (uint16_t) 0xFE, (uint16_t) 0x1, (uint16_t) 0xFE }, /* MaxLevel */ \ - { (uint16_t) 0xFF, (uint16_t) 0x64, (uint16_t) 0xFFFF }, /* BallastFactorAdjustment */ \ - { (uint16_t) 0x0, (uint16_t) 0x0, (uint16_t) 0x1 }, /* LampAlarmMode */ \ - \ - /* Endpoint: 1, Cluster: Unit Testing (server) */ \ - { (uint16_t) 0x46, (uint16_t) 0x14, (uint16_t) 0x64 }, /* range_restricted_int8u */ \ - { (uint16_t) -0x14, (uint16_t) -0x28, (uint16_t) 0x32 }, /* range_restricted_int8s */ \ - { (uint16_t) 0xC8, (uint16_t) 0x64, (uint16_t) 0x3E8 }, /* range_restricted_int16u */ \ - { (uint16_t) -0x64, (uint16_t) -0x96, (uint16_t) 0xC8 }, /* range_restricted_int16s */ \ - { (uint16_t) 0x46, (uint16_t) 0x14, (uint16_t) 0x64 }, /* nullable_range_restricted_int8u */ \ - { (uint16_t) -0x14, (uint16_t) -0x28, (uint16_t) 0x32 }, /* nullable_range_restricted_int8s */ \ - { (uint16_t) 0xC8, (uint16_t) 0x64, (uint16_t) 0x3E8 }, /* nullable_range_restricted_int16u */ \ - { (uint16_t) -0x64, (uint16_t) -0x96, (uint16_t) 0xC8 }, /* nullable_range_restricted_int16s */ \ + /* Endpoint: 1, Cluster: On/Off (server) */ \ + { (uint16_t) 0xFF, (uint16_t) 0x0, (uint16_t) 0x2 }, /* StartUpOnOff */ \ + \ + /* Endpoint: 1, Cluster: Level Control (server) */ \ + { (uint16_t) 0x0, (uint16_t) 0x0, (uint16_t) 0x3 }, /* Options */ \ + { (uint16_t) 0x32, (uint16_t) 0x1, (uint16_t) 0xFF }, /* DefaultMoveRate */ \ + \ + /* Endpoint: 1, Cluster: Laundry Washer Controls (server) */ \ + { (uint16_t) 0x0, (uint16_t) 0x0, (uint16_t) 0x1F }, /* SpinSpeedCurrent */ \ + \ + /* Endpoint: 1, Cluster: Smoke CO Alarm (server) */ \ + { (uint16_t) 0x1, (uint16_t) 0x0, (uint16_t) 0x2 }, /* SmokeSensitivityLevel */ \ + \ + /* Endpoint: 1, Cluster: Valve Configuration and Control (server) */ \ + { (uint16_t) 0x64, (uint16_t) 0x1, (uint16_t) 0x64 }, /* DefaultOpenLevel */ \ + \ + /* Endpoint: 1, Cluster: Energy EVSE (server) */ \ + { (uint16_t) 0x0, (uint16_t) 0x0, (uint16_t) 0xFFFE }, /* ApproximateEVEfficiency */ \ + \ + /* Endpoint: 1, Cluster: Window Covering (server) */ \ + { (uint16_t) 0x0, (uint16_t) 0x0, (uint16_t) 0xF }, /* Mode */ \ + \ + /* Endpoint: 1, Cluster: Pump Configuration and Control (server) */ \ + { (uint16_t) 0x0, (uint16_t) 0x0, (uint16_t) 0x3 }, /* OperationMode */ \ + { (uint16_t) 0x0, (uint16_t) 0x0, (uint16_t) 0x7 }, /* ControlMode */ \ + \ + /* Endpoint: 1, Cluster: Thermostat (server) */ \ + { (uint16_t) 0xA28, (uint16_t) -0x6AB3, (uint16_t) 0x7FFF }, /* OccupiedCoolingSetpoint */ \ + { (uint16_t) 0x7D0, (uint16_t) -0x6AB3, (uint16_t) 0x7FFF }, /* OccupiedHeatingSetpoint */ \ + { (uint16_t) 0x2BC, (uint16_t) -0x6AB3, (uint16_t) 0x7FFF }, /* MinHeatSetpointLimit */ \ + { (uint16_t) 0xBB8, (uint16_t) -0x6AB3, (uint16_t) 0x7FFF }, /* MaxHeatSetpointLimit */ \ + { (uint16_t) 0x640, (uint16_t) -0x6AB3, (uint16_t) 0x7FFF }, /* MinCoolSetpointLimit */ \ + { (uint16_t) 0xC80, (uint16_t) -0x6AB3, (uint16_t) 0x7FFF }, /* MaxCoolSetpointLimit */ \ + { (uint16_t) 0x19, (uint16_t) 0x0, (uint16_t) 0x7F }, /* MinSetpointDeadBand */ \ + { (uint16_t) 0x4, (uint16_t) 0x0, (uint16_t) 0x5 }, /* ControlSequenceOfOperation */ \ + { (uint16_t) 0x1, (uint16_t) 0x0, (uint16_t) 0x9 }, /* SystemMode */ \ + \ + /* Endpoint: 1, Cluster: Fan Control (server) */ \ + { (uint16_t) 0x0, (uint16_t) 0x0, (uint16_t) 0x6 }, /* FanMode */ \ + { (uint16_t) 0x0, (uint16_t) 0x0, (uint16_t) 0x64 }, /* PercentSetting */ \ + { (uint16_t) 0x0, (uint16_t) 0x0, (uint16_t) 0x64 }, /* SpeedSetting */ \ + \ + /* Endpoint: 1, Cluster: Thermostat User Interface Configuration (server) */ \ + { (uint16_t) 0x0, (uint16_t) 0x0, (uint16_t) 0x1 }, /* TemperatureDisplayMode */ \ + { (uint16_t) 0x0, (uint16_t) 0x0, (uint16_t) 0x5 }, /* KeypadLockout */ \ + { (uint16_t) 0x0, (uint16_t) 0x0, (uint16_t) 0x1 }, /* ScheduleProgrammingVisibility */ \ + \ + /* Endpoint: 1, Cluster: Color Control (server) */ \ + { (uint16_t) 0x0, (uint16_t) 0x0, (uint16_t) 0xFEFF }, /* WhitePointX */ \ + { (uint16_t) 0x0, (uint16_t) 0x0, (uint16_t) 0xFEFF }, /* WhitePointY */ \ + { (uint16_t) 0x0, (uint16_t) 0x0, (uint16_t) 0xFEFF }, /* ColorPointRX */ \ + { (uint16_t) 0x0, (uint16_t) 0x0, (uint16_t) 0xFEFF }, /* ColorPointRY */ \ + { (uint16_t) 0x0, (uint16_t) 0x0, (uint16_t) 0xFEFF }, /* ColorPointGX */ \ + { (uint16_t) 0x0, (uint16_t) 0x0, (uint16_t) 0xFEFF }, /* ColorPointGY */ \ + { (uint16_t) 0x0, (uint16_t) 0x0, (uint16_t) 0xFEFF }, /* ColorPointBX */ \ + { (uint16_t) 0x0, (uint16_t) 0x0, (uint16_t) 0xFEFF }, /* ColorPointBY */ \ + { (uint16_t) 0xFA, (uint16_t) 0x0, (uint16_t) 0xFEFF }, /* StartUpColorTemperatureMireds */ \ + \ + /* Endpoint: 1, Cluster: Ballast Configuration (server) */ \ + { (uint16_t) 0x1, (uint16_t) 0x1, (uint16_t) 0xFE }, /* MinLevel */ \ + { (uint16_t) 0xFE, (uint16_t) 0x1, (uint16_t) 0xFE }, /* MaxLevel */ \ + { (uint16_t) 0xFF, (uint16_t) 0x64, (uint16_t) 0xFFFF }, /* BallastFactorAdjustment */ \ + { (uint16_t) 0x0, (uint16_t) 0x0, (uint16_t) 0x1 }, /* LampAlarmMode */ \ + \ + /* Endpoint: 1, Cluster: Unit Testing (server) */ \ + { (uint16_t) 0x46, (uint16_t) 0x14, (uint16_t) 0x64 }, /* range_restricted_int8u */ \ + { (uint16_t) -0x14, (uint16_t) -0x28, (uint16_t) 0x32 }, /* range_restricted_int8s */ \ + { (uint16_t) 0xC8, (uint16_t) 0x64, (uint16_t) 0x3E8 }, /* range_restricted_int16u */ \ + { (uint16_t) -0x64, (uint16_t) -0x96, (uint16_t) 0xC8 }, /* range_restricted_int16s */ \ + { (uint16_t) 0x46, (uint16_t) 0x14, (uint16_t) 0x64 }, /* nullable_range_restricted_int8u */ \ + { (uint16_t) -0x14, (uint16_t) -0x28, (uint16_t) 0x32 }, /* nullable_range_restricted_int8s */ \ + { (uint16_t) 0xC8, (uint16_t) 0x64, (uint16_t) 0x3E8 }, /* nullable_range_restricted_int16u */ \ + { (uint16_t) -0x64, (uint16_t) -0x96, (uint16_t) 0xC8 }, /* nullable_range_restricted_int16s */ \ \ /* Endpoint: 2, Cluster: On/Off (server) */ \ - { \ - (uint16_t) 0x0, (uint16_t) 0x0, (uint16_t) 0x2 \ - } /* StartUpOnOff */ \ + { (uint16_t) 0x0, (uint16_t) 0x0, (uint16_t) 0x2 } /* StartUpOnOff */ \ } // This is an array of EmberAfAttributeMetadata structures. @@ -4394,12 +4392,8 @@ static_assert(ATTRIBUTE_LARGEST <= CHIP_CONFIG_MAX_ATTRIBUTE_STORE_ELEMENT_SIZE, // Array of device types #define FIXED_DEVICE_TYPES \ - { \ - { 0x00000011, 1 }, { 0x00000016, 1 }, { 0x00000100, 1 }, { 0x00000011, 1 }, { 0x00000100, 1 }, { 0x00000011, 1 }, \ - { \ - 0x00000019, 1 \ - } \ - } + { { 0x00000011, 1 }, { 0x00000016, 1 }, { 0x00000100, 1 }, { 0x00000011, 1 }, \ + { 0x00000100, 1 }, { 0x00000011, 1 }, { 0x00000019, 1 } } // Array of device type offsets #define FIXED_DEVICE_TYPE_OFFSETS { 0, 2, 4, 6 } diff --git a/scripts/tools/zap/tests/outputs/lighting-app/app-templates/endpoint_config.h b/scripts/tools/zap/tests/outputs/lighting-app/app-templates/endpoint_config.h index fa214e1686690b..6395681cf33469 100644 --- a/scripts/tools/zap/tests/outputs/lighting-app/app-templates/endpoint_config.h +++ b/scripts/tools/zap/tests/outputs/lighting-app/app-templates/endpoint_config.h @@ -118,14 +118,12 @@ /* Endpoint: 1, Cluster: On/Off (server) */ \ { (uint16_t) 0xFF, (uint16_t) 0x0, (uint16_t) 0x2 }, /* StartUpOnOff */ \ \ - /* Endpoint: 1, Cluster: Level Control (server) */ \ - { (uint16_t) 0x0, (uint16_t) 0x0, (uint16_t) 0x3 }, /* Options */ \ - { (uint16_t) 0x32, (uint16_t) 0x1, (uint16_t) 0xFF }, /* DefaultMoveRate */ \ + /* Endpoint: 1, Cluster: Level Control (server) */ \ + { (uint16_t) 0x0, (uint16_t) 0x0, (uint16_t) 0x3 }, /* Options */ \ + { (uint16_t) 0x32, (uint16_t) 0x1, (uint16_t) 0xFF }, /* DefaultMoveRate */ \ \ /* Endpoint: 1, Cluster: Color Control (server) */ \ - { \ - (uint16_t) 0x0, (uint16_t) 0x0, (uint16_t) 0xFEFF \ - } /* StartUpColorTemperatureMireds */ \ + { (uint16_t) 0x0, (uint16_t) 0x0, (uint16_t) 0xFEFF } /* StartUpColorTemperatureMireds */ \ } // This is an array of EmberAfAttributeMetadata structures. @@ -1233,13 +1231,7 @@ static_assert(ATTRIBUTE_LARGEST <= CHIP_CONFIG_MAX_ATTRIBUTE_STORE_ELEMENT_SIZE, #define FIXED_PROFILE_IDS { 0x0103, 0x0103 } // Array of device types -#define FIXED_DEVICE_TYPES \ - { \ - { 0x00000016, 1 }, \ - { \ - 0x00000101, 1 \ - } \ - } +#define FIXED_DEVICE_TYPES { { 0x00000016, 1 }, { 0x00000101, 1 } } // Array of device type offsets #define FIXED_DEVICE_TYPE_OFFSETS { 0, 1 } diff --git a/src/lib/address_resolve/tool.cpp b/src/lib/address_resolve/tool.cpp index 53d01b4011806f..042f7c6f891753 100644 --- a/src/lib/address_resolve/tool.cpp +++ b/src/lib/address_resolve/tool.cpp @@ -147,7 +147,7 @@ extern "C" void StopSignalHandler(int signal) } // namespace -extern "C" int main(int argc, const char ** argv) +int main(int argc, const char ** argv) { Platform::MemoryInit(); diff --git a/src/test_driver/nrfconnect/main/runner.cpp b/src/test_driver/nrfconnect/main/runner.cpp index 44fb5bae2a6183..bd719fbd4e5b33 100644 --- a/src/test_driver/nrfconnect/main/runner.cpp +++ b/src/test_driver/nrfconnect/main/runner.cpp @@ -29,7 +29,7 @@ using namespace ::chip::DeviceLayer; LOG_MODULE_REGISTER(runner, CONFIG_MATTER_LOG_LEVEL); -extern "C" int main(void) +int main(void) { VerifyOrDie(settings_subsys_init() == 0); diff --git a/src/tools/chip-cert/chip-cert.cpp b/src/tools/chip-cert/chip-cert.cpp index 571a00421f2569..a06a7341fafc09 100644 --- a/src/tools/chip-cert/chip-cert.cpp +++ b/src/tools/chip-cert/chip-cert.cpp @@ -85,7 +85,7 @@ bool PrintVersion() } // namespace -extern "C" int main(int argc, char * argv[]) +int main(int argc, char * argv[]) { bool res = false; diff --git a/src/tools/spake2p/spake2p.cpp b/src/tools/spake2p/spake2p.cpp index 45f5cc9d7c4323..ce1c0f82c60212 100644 --- a/src/tools/spake2p/spake2p.cpp +++ b/src/tools/spake2p/spake2p.cpp @@ -62,7 +62,7 @@ bool PrintVersion() } // namespace -extern "C" int main(int argc, char * argv[]) +int main(int argc, char * argv[]) { bool res = false; diff --git a/third_party/pigweed/repo b/third_party/pigweed/repo index d5fcc90b39ee75..ce0e3e2d1b7eec 160000 --- a/third_party/pigweed/repo +++ b/third_party/pigweed/repo @@ -1 +1 @@ -Subproject commit d5fcc90b39ee7568855390535fa854cea8f33c95 +Subproject commit ce0e3e2d1b7eec7cdf59fbb2ceed2b1cb3edd1ec diff --git a/third_party/pigweed/update.sh b/third_party/pigweed/update.sh old mode 100644 new mode 100755 index c8dd96862d7285..b15e967930577b --- a/third_party/pigweed/update.sh +++ b/third_party/pigweed/update.sh @@ -3,8 +3,8 @@ # Update the submodule. cd "$(dirname "${BASH_SOURCE[0]}")/repo" -git fetch origin master -git checkout origin/master +git fetch origin main +git checkout origin/main # Copy the CIPD manifest but change the Python line so we don't use CIPD # Python on Linux. From 948755d516018c5402c65b8a2f1f0f03dc953263 Mon Sep 17 00:00:00 2001 From: Sergio Soares Date: Wed, 23 Oct 2024 12:07:03 -0400 Subject: [PATCH 078/149] Add missing Water Heater device to matter-devices.xml (#36125) * Add missing Water Heater device to matter-devices.xml This PR adds the missing Water Heater device to matter-devices.xml. The description was generated using the Alchemy tool (https://github.com/project-chip/alchemy) with the following command: `alchemy zap --attribute="in-progress" --sdkRoot=./connectedhomeip/ --specRoot=./connectedhomeip-spec/ ./connectedhomeip-spec/src/device_types/WaterHeater.adoc` I manually fixed the device nae from `Matter Water Heater` to `Water Heater`. * zap regen --- .../zcl/data-model/chip/matter-devices.xml | 43 +++++++++++++++++++ .../CHIP/zap-generated/MTRClusterConstants.h | 1 + .../zap-generated/MTRDeviceTypeMetadata.mm | 1 + .../cluster/logging/EntryToText.cpp | 2 + 4 files changed, 47 insertions(+) diff --git a/src/app/zap-templates/zcl/data-model/chip/matter-devices.xml b/src/app/zap-templates/zcl/data-model/chip/matter-devices.xml index f7f5699ef8fccf..ff485bbf6bba81 100644 --- a/src/app/zap-templates/zcl/data-model/chip/matter-devices.xml +++ b/src/app/zap-templates/zcl/data-model/chip/matter-devices.xml @@ -2698,4 +2698,47 @@ limitations under the License. + + MA-waterheater + CHIP + Water Heater + 0x0103 + 0x050F + Simple + Endpoint + + + CLIENT_LIST + DEVICE_TYPE_LIST + PARTS_LIST + SERVER_LIST + + + IDENTIFY_TIME + IDENTIFY_TYPE + Identify + + + CONTROL_SEQUENCE_OF_OPERATION + LOCAL_TEMPERATURE + SYSTEM_MODE + SetpointRaiseLower + + + BOOST_STATE + HEATER_TYPES + HEAT_DEMAND + BoostEnded + BoostStarted + Boost + CancelBoost + + + CURRENT_MODE + SUPPORTED_MODES + ChangeToMode + ChangeToModeResponse + + + diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h b/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h index b1d26e9ce0fb12..da2ce72f59373d 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h @@ -7625,6 +7625,7 @@ typedef NS_ENUM(uint32_t, MTRDeviceTypeIDType) { MTRDeviceTypeIDTypeHumiditySensorID MTR_NEWLY_AVAILABLE = 0x00000307, MTRDeviceTypeIDTypeEVSEID MTR_NEWLY_AVAILABLE = 0x0000050C, MTRDeviceTypeIDTypeDeviceEnergyManagementID MTR_NEWLY_AVAILABLE = 0x0000050D, + MTRDeviceTypeIDTypeWaterHeaterID MTR_PROVISIONALLY_AVAILABLE = 0x0000050F, MTRDeviceTypeIDTypeElectricalSensorID MTR_NEWLY_AVAILABLE = 0x00000510, MTRDeviceTypeIDTypeControlBridgeID MTR_NEWLY_AVAILABLE = 0x00000840, MTRDeviceTypeIDTypeOnOffSensorID MTR_NEWLY_AVAILABLE = 0x00000850, diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRDeviceTypeMetadata.mm b/src/darwin/Framework/CHIP/zap-generated/MTRDeviceTypeMetadata.mm index f0530c41a54f00..b4ea67c2ed66fe 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRDeviceTypeMetadata.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRDeviceTypeMetadata.mm @@ -85,6 +85,7 @@ { 0x00000307, MTRDeviceTypeClass::Simple, "Humidity Sensor" }, { 0x0000050C, MTRDeviceTypeClass::Simple, "EVSE" }, { 0x0000050D, MTRDeviceTypeClass::Simple, "Device Energy Management" }, + { 0x0000050F, MTRDeviceTypeClass::Simple, "Water Heater" }, { 0x00000510, MTRDeviceTypeClass::Utility, "Electrical Sensor" }, { 0x00000840, MTRDeviceTypeClass::Simple, "Control Bridge" }, { 0x00000850, MTRDeviceTypeClass::Simple, "On/Off Sensor" }, diff --git a/zzz_generated/chip-tool/zap-generated/cluster/logging/EntryToText.cpp b/zzz_generated/chip-tool/zap-generated/cluster/logging/EntryToText.cpp index 0b5178d3bcb208..7c4c38ae6cec3f 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/logging/EntryToText.cpp +++ b/zzz_generated/chip-tool/zap-generated/cluster/logging/EntryToText.cpp @@ -6495,6 +6495,8 @@ char const * DeviceTypeIdToText(chip::DeviceTypeId id) return "EVSE"; case 0x0000050D: return "Device Energy Management"; + case 0x0000050F: + return "Water Heater"; case 0x00000510: return "Electrical Sensor"; case 0x00000840: From a7a50045bab885aeb79a6a320a053655575af37a Mon Sep 17 00:00:00 2001 From: Raul Marquez <130402456+raul-marquez-csa@users.noreply.github.com> Date: Wed, 23 Oct 2024 09:07:34 -0700 Subject: [PATCH 079/149] Adds step 9c (#36157) --- .../tests/suites/certification/Test_TC_LVL_2_1.yaml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/app/tests/suites/certification/Test_TC_LVL_2_1.yaml b/src/app/tests/suites/certification/Test_TC_LVL_2_1.yaml index 8e9ee05b33e9ff..aa0fbcfddc83bf 100644 --- a/src/app/tests/suites/certification/Test_TC_LVL_2_1.yaml +++ b/src/app/tests/suites/certification/Test_TC_LVL_2_1.yaml @@ -188,6 +188,16 @@ tests: minValue: MinLevelFeatureMapNotSupportedValue maxValue: MaxLevelFeatureMapNotSupportedValue + - label: "Step 9c: TH reads the OnLevel attribute from the DUT" + PICS: LVL.S.A0011 && !LVL.S.F01 && !LVL.S.A0002 && !LVL.S.A0003 + command: "readAttribute" + attribute: "OnLevel" + response: + constraints: + type: int8u + minValue: 0 + maxValue: 254 + - label: "Step 10: TH reads the OnTransitionTime attribute from the DUT" PICS: LVL.S.A0012 command: "readAttribute" From 614a086b9151cd6b686f07efa9c56fcc1b06f1df Mon Sep 17 00:00:00 2001 From: Sergio Soares Date: Wed, 23 Oct 2024 12:08:35 -0400 Subject: [PATCH 080/149] python_testing: Add Checks for Command IDs (#36018) * python_testing: Add Checks for Command IDs This PR adds checks and unit tests for the command ID ranges defined in Table 79 of the spec. These checks will be used on the various Python tests, for example, TC_DeviceBasicComposition.py. * Restyled by isort * python_testing: Update command id error msg This PR uses the newly added command id check. It updates the error msg to indicate if it's a "Test Vendor" id. * fix merge conflicts * Restyled by isort --------- Co-authored-by: Restyled.io --- .../TC_DeviceBasicComposition.py | 5 +- src/python_testing/TestIdChecks.py | 71 ++++++++++++++++++- .../chip/testing/global_attribute_ids.py | 31 ++++++++ 3 files changed, 102 insertions(+), 5 deletions(-) diff --git a/src/python_testing/TC_DeviceBasicComposition.py b/src/python_testing/TC_DeviceBasicComposition.py index 59182fa4e2fcb2..0f227c2c672ea4 100644 --- a/src/python_testing/TC_DeviceBasicComposition.py +++ b/src/python_testing/TC_DeviceBasicComposition.py @@ -108,7 +108,8 @@ from chip.clusters.ClusterObjects import ClusterAttributeDescriptor, ClusterObjectFieldDescriptor from chip.interaction_model import InteractionModelError, Status from chip.testing.basic_composition import BasicCompositionTests -from chip.testing.global_attribute_ids import AttributeIdType, ClusterIdType, GlobalAttributeIds, attribute_id_type, cluster_id_type +from chip.testing.global_attribute_ids import (AttributeIdType, ClusterIdType, CommandIdType, GlobalAttributeIds, attribute_id_type, + cluster_id_type, command_id_type) from chip.testing.matter_testing import (AttributePathLocation, ClusterPathLocation, CommandPathLocation, MatterBaseTest, TestStep, async_test_body, default_matter_test_main) from chip.testing.taglist_and_topology_test import (create_device_type_list_for_root, create_device_type_lists, @@ -503,7 +504,7 @@ class RequiredMandatoryAttribute: location = CommandPathLocation(endpoint_id=endpoint_id, cluster_id=cluster_id, command_id=bad_cmd_id) vendor_id = get_vendor_id(bad_cmd_id) self.record_error(self.get_test_name( - ), location=location, problem=f'Command 0x{bad_cmd_id:08x} with bad prefix 0x{vendor_id:04x} in cluster 0x{cluster_id:08x}', spec_location='Manufacturer Extensible Identifier (MEI)') + ), location=location, problem=f'Command 0x{bad_cmd_id:08x} with bad prefix 0x{vendor_id:04x} in cluster 0x{cluster_id:08x}' + (' (Test Vendor)' if command_id_type(bad_cmd_id) == CommandIdType.kTest else ''), spec_location='Manufacturer Extensible Identifier (MEI)') success = False self.print_step(7, "Validate that none of the MEI global attribute IDs contain values outside of the allowed suffix range") diff --git a/src/python_testing/TestIdChecks.py b/src/python_testing/TestIdChecks.py index eda01ef9556493..c86d4bfe6d0d0b 100644 --- a/src/python_testing/TestIdChecks.py +++ b/src/python_testing/TestIdChecks.py @@ -15,9 +15,9 @@ # limitations under the License. # -from chip.testing.global_attribute_ids import (AttributeIdType, ClusterIdType, DeviceTypeIdType, attribute_id_type, cluster_id_type, - device_type_id_type, is_valid_attribute_id, is_valid_cluster_id, - is_valid_device_type_id) +from chip.testing.global_attribute_ids import (AttributeIdType, ClusterIdType, CommandIdType, DeviceTypeIdType, attribute_id_type, + cluster_id_type, command_id_type, device_type_id_type, is_valid_attribute_id, + is_valid_cluster_id, is_valid_command_id, is_valid_device_type_id) from chip.testing.matter_testing import MatterBaseTest, default_matter_test_main from mobly import asserts @@ -210,6 +210,71 @@ def check_all_bad(id): for id in prefix_bad: check_all_bad(id) + def test_command_ids(self): + standard_global_good = [0x0000_00E0, 0x0000_00FF, 0x0000_00E1, 0x0000_00FE] + standard_global_bad = [0x0000_01E0, 0x0000_0FFF, 0x0000_AAE1, 0x0000_BBFE, 0x0000_FFFF] + scoped_non_global_good = [0x0000_0000, 0x0000_00DF, 0x0000_0001] + scoped_non_global_bad = [0x0000_0F00, 0x0000_01DF, 0x0000_0F01] + manufacturer_good = [0x0001_0000, 0x0001_00FF, 0xFFF0_0000, 0xFFF0_00FF, 0x0001_00FE] + manufacturer_bad = [0x0001_0A00, 0x0001_0BFF, 0x0001_FFFF, 0xFFF0_0C00, 0xFFF0_D0FF, 0x0001_F0FE] + test_good = [0xFFF1_0000, 0xFFF1_00E0, 0xFFF1_00FF, 0xFFF4_0000, 0xFFF4_00E0, 0xFFF4_00FF] + test_bad = [0xFFF1_5000, 0xFFF1_F000, 0xFFF1_FFFF, 0xFFF4_5000, 0xFFF4_F000, 0xFFF4_FFFF] + prefix_bad = [0xFFF5_0000, 0xFFF5_4FFF, 0xFFF5_5000, 0xFFF5_F000, 0xFFF5_FFFF] + + def check_standard_global(id): + id_type = command_id_type(id) + msg = f"Incorrect command range assessment, expecting standard global {id:08x}, type = {id_type}" + asserts.assert_equal(id_type, CommandIdType.kStandardGlobal, msg) + asserts.assert_true(is_valid_command_id(id_type, allow_test=True), msg) + asserts.assert_true(is_valid_command_id(id_type, allow_test=False), msg) + + def check_scoped_non_global(id): + id_type = command_id_type(id) + msg = f"Incorrect command range assessment, expecting scoped non-global {id:08x}, type = {id_type}" + asserts.assert_equal(id_type, CommandIdType.kScopedNonGlobal, msg) + asserts.assert_true(is_valid_command_id(id_type, allow_test=True), msg) + asserts.assert_true(is_valid_command_id(id_type, allow_test=False), msg) + + def check_manufacturer(id): + id_type = command_id_type(id) + msg = f"Incorrect command range assessment, expecting manufacturer {id:08x}, type = {id_type}" + asserts.assert_equal(id_type, CommandIdType.kManufacturer, msg) + asserts.assert_true(is_valid_command_id(id_type, allow_test=True), msg) + asserts.assert_true(is_valid_command_id(id_type, allow_test=False), msg) + + def check_test(id): + id_type = command_id_type(id) + msg = f"Incorrect command range assessment, expecting test {id:08x}, type = {id_type}" + asserts.assert_equal(id_type, CommandIdType.kTest, msg) + asserts.assert_true(is_valid_command_id(id_type, allow_test=True), msg) + asserts.assert_false(is_valid_command_id(id_type, allow_test=False), msg) + + def check_all_bad(id): + id_type = command_id_type(id) + msg = f"Incorrect command range assessment, expecting invalid {id:08x}, type = {id_type}" + asserts.assert_equal(id_type, CommandIdType.kInvalid, msg) + asserts.assert_false(is_valid_command_id(id_type, allow_test=True), msg) + asserts.assert_false(is_valid_command_id(id_type, allow_test=False), msg) + + for id in standard_global_good: + check_standard_global(id) + for id in standard_global_bad: + check_all_bad(id) + for id in scoped_non_global_good: + check_scoped_non_global(id) + for id in scoped_non_global_bad: + check_all_bad(id) + for id in manufacturer_good: + check_manufacturer(id) + for id in manufacturer_bad: + check_all_bad(id) + for id in test_good: + check_test(id) + for id in test_bad: + check_all_bad(id) + for id in prefix_bad: + check_all_bad(id) + if __name__ == "__main__": default_matter_test_main() diff --git a/src/python_testing/matter_testing_infrastructure/chip/testing/global_attribute_ids.py b/src/python_testing/matter_testing_infrastructure/chip/testing/global_attribute_ids.py index e692adfdfb5a10..f9fbd2e2ade835 100644 --- a/src/python_testing/matter_testing_infrastructure/chip/testing/global_attribute_ids.py +++ b/src/python_testing/matter_testing_infrastructure/chip/testing/global_attribute_ids.py @@ -61,6 +61,15 @@ class AttributeIdType(Enum): kManufacturer = auto(), kTest = auto(), + +class CommandIdType(Enum): + kInvalid = auto() + kStandardGlobal = auto(), + kScopedNonGlobal = auto(), + kManufacturer = auto(), + kTest = auto(), + + # ID helper classes - this allows us to use the values from the prefix and suffix table directly # because the class handles the non-inclusive range. @@ -92,6 +101,9 @@ def __contains__(self, id: int): CLUSTER_ID_MANUFACTURER_RANGE_SUFFIX = SuffixIdRange(0xFC00, 0xFFFE) ATTRIBUTE_ID_GLOBAL_RANGE_SUFFIX = SuffixIdRange(0xF000, 0xFFFE) ATTRIBUTE_ID_NON_GLOBAL_RANGE_SUFFIX = SuffixIdRange(0x0000, 0x4FFF) +COMMAND_ID_GLOBAL_STANDARD_SUFFIX = SuffixIdRange(0x00E0, 0x00FF) +COMMAND_ID_NON_GLOBAL_SCOPED_SUFFIX = SuffixIdRange(0x0000, 0x00DF) +COMMAND_ID_SUFFIX = SuffixIdRange(0x0000, 0x00FF) def device_type_id_type(id: int) -> DeviceTypeIdType: @@ -145,3 +157,22 @@ def is_valid_attribute_id(id_type: AttributeIdType, allow_test: bool = False): if allow_test: valid.append(AttributeIdType.kTest) return id_type in valid + + +def command_id_type(id: int) -> CommandIdType: + if id in STANDARD_PREFIX and id in COMMAND_ID_GLOBAL_STANDARD_SUFFIX: + return CommandIdType.kStandardGlobal + if id in STANDARD_PREFIX and id in COMMAND_ID_NON_GLOBAL_SCOPED_SUFFIX: + return CommandIdType.kScopedNonGlobal + if id in MANUFACTURER_PREFIX and id in COMMAND_ID_SUFFIX: + return CommandIdType.kManufacturer + if id in TEST_PREFIX and id in COMMAND_ID_SUFFIX: + return CommandIdType.kTest + return CommandIdType.kInvalid + + +def is_valid_command_id(id_type: CommandIdType, allow_test: bool = False): + valid = [CommandIdType.kStandardGlobal, CommandIdType.kScopedNonGlobal, CommandIdType.kManufacturer] + if allow_test: + valid.append(CommandIdType.kTest) + return id_type in valid From c28bcdc20ec97e2b9a7383ec33154a0af70f5957 Mon Sep 17 00:00:00 2001 From: C Freeman Date: Wed, 23 Oct 2024 12:08:55 -0400 Subject: [PATCH 081/149] Pything testing: Add more info to error summary (#36216) Get correct line for assert.fail too --- .../chip/testing/matter_testing.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/python_testing/matter_testing_infrastructure/chip/testing/matter_testing.py b/src/python_testing/matter_testing_infrastructure/chip/testing/matter_testing.py index 0a40b1688d74cf..053fa575c6452d 100644 --- a/src/python_testing/matter_testing_infrastructure/chip/testing/matter_testing.py +++ b/src/python_testing/matter_testing_infrastructure/chip/testing/matter_testing.py @@ -919,6 +919,9 @@ class TestStep: expectation: str = "" is_commissioning: bool = False + def __str__(self): + return f'{self.test_plan_number}: {self.description}\tExpected outcome: {self.expectation}' + @dataclass class TestInfo: @@ -1325,7 +1328,7 @@ def extract_error_text() -> tuple[str, str]: if not trace: return no_stack_trace - if isinstance(exception, signals.TestError): + if isinstance(exception, signals.TestError) or isinstance(exception, signals.TestFailure): # Exception gets raised by the mobly framework, so the proximal error is one line back in the stack trace assert_candidates = [idx for idx, line in enumerate(trace) if "asserts" in line and "asserts.py" not in line] if not assert_candidates: @@ -1343,6 +1346,9 @@ def extract_error_text() -> tuple[str, str]: return probable_error.strip(), trace[file_candidates[-1]].strip() probable_error, probable_file = extract_error_text() + test_steps = self.get_defined_test_steps(self.current_test_info.name) + test_step = str(test_steps[self.current_step_index-1] + ) if test_steps is not None else 'UNKNOWN - no test steps provided in test script' logging.error(textwrap.dedent(f""" ****************************************************************** @@ -1353,8 +1359,12 @@ def extract_error_text() -> tuple[str, str]: * {probable_file} * {probable_error} * + * Test step: + * {test_step} + * + * Endpoint: {self.matter_test_config.endpoint} + * ******************************************************************* - """)) def on_pass(self, record): From 0a1867fe61933f42f2dbd2744b631e3f87c16bc9 Mon Sep 17 00:00:00 2001 From: JP Meijers Date: Wed, 23 Oct 2024 18:14:51 +0200 Subject: [PATCH 082/149] Add installation as snap instructions (#36099) * Add installation as snap instructions * Add hyperlink to snap store listing * Fix links to chip tool doc --- .../chip-tool/chip_tool_guide.md | 51 +++++++++++-------- .../light-switch-app/nrfconnect/README.md | 4 +- 2 files changed, 32 insertions(+), 23 deletions(-) diff --git a/docs/development_controllers/chip-tool/chip_tool_guide.md b/docs/development_controllers/chip-tool/chip_tool_guide.md index 8aac8daa121812..81000368a47f0c 100644 --- a/docs/development_controllers/chip-tool/chip_tool_guide.md +++ b/docs/development_controllers/chip-tool/chip_tool_guide.md @@ -9,33 +9,29 @@ the setup payload or performing discovery actions.
    -## Source files +## Installation -You can find source files of the CHIP Tool in the `examples/chip-tool` -directory. - -> **Note:** The CHIP Tool caches the configuration state in the -> `/tmp/chip_tool_config.ini` file. Deleting this and other `.ini` files in the -> `/tmp` directory can sometimes resolve issues related to stale configuration. +On Linux distributions +[running snapd](https://snapcraft.io/docs/installing-snapd), such as Ubuntu, the +CHIP Tool can be installed using the +[chip-tool snap](https://snapcraft.io/chip-tool). To do this, run: -> **Note:** To make the configuration persistent (since `/tmp` directory might -> be flushed at each reboot) you can change the directory where CHIP Tool caches -> its configuration by using the option `--storage-directory` +``` +sudo snap install chip-tool +``` -
    +## Building from source -## Building and running the CHIP Tool +The source files of the CHIP Tool are available in the `examples/chip-tool` +directory. -Before you can use the CHIP Tool, you must compile it from source on Linux -(amd64/aarch64) or macOS. If you want to run it on Raspberry Pi, it must use a -64-bit OS. +The source can be compiled on Linux (amd64/aarch64) or macOS. If you want to run +it on Raspberry Pi, you must use a 64-bit OS. > **Note:** To ensure compatibility, always build the CHIP Tool and the Matter > device from the same revision of the `connectedhomeip` repository. -### Building the CHIP Tool - -To build and run the CHIP Tool: +To build the CHIP Tool: 1. Install all required packages for Matter and prepare the source code and the build system. Read the [Building Matter](../../guides/BUILDING.md) guide for @@ -50,10 +46,16 @@ To build and run the CHIP Tool: In this command, `BUILD_PATH` specifies where the target binaries are to be placed. -### Running the CHIP Tool +## Running the CHIP Tool + +If you installed the CHIP Tool as a snap, the command to run it would be: + +``` +$ chip-tool +``` -To check if the CHIP Tool runs correctly, execute the following command from the -`BUILD_PATH` directory: +If you compiled the CHIP Tool from source, it can be executed with the following +command from the `BUILD_PATH` directory: ``` $ ./chip-tool @@ -68,6 +70,13 @@ more complex command by appending it with sub-commands. Examples of specific commands and their use cases are described in the [Supported commands and options](#supported-commands-and-options) section. +> **Note:** The CHIP Tool caches the configuration state in the +> `/tmp/chip_tool_config.ini` file. Deleting this and other `.ini` files in the +> `/tmp` directory can sometimes resolve issues related to stale configuration. +> To make the configuration persistent you can change the directory where CHIP +> Tool caches its configuration by using the command line option +> `--storage-directory` +
    ## CHIP Tool modes diff --git a/examples/light-switch-app/nrfconnect/README.md b/examples/light-switch-app/nrfconnect/README.md index 11e53793463570..02f7b500aa6270 100644 --- a/examples/light-switch-app/nrfconnect/README.md +++ b/examples/light-switch-app/nrfconnect/README.md @@ -638,7 +638,7 @@ same Matter network. To perform the unicast binding process, complete the following steps: 1. Build the CHIP Tool according to the steps from the - [CHIP Tool user guide](../../../docs/development_controllers/chip-tool/chip_tool_guide.md#building-and-running-the-chip-tool). + [CHIP Tool user guide](../../../docs/development_controllers/chip-tool/chip_tool_guide.md#building-from-source). 2. Go to the CHIP Tool build directory. 3. Add an ACL to the development kit that is programmed with the [Lighting Application Example](../../lighting-app/nrfconnect/README.md) by @@ -690,7 +690,7 @@ same Matter network. To perform the unicast binding process, complete the following steps: 1. Build the CHIP Tool according to the steps from the - [CHIP Tool user guide](../../../docs/development_controllers/chip-tool/chip_tool_guide.md#building-and-running-the-chip-tool). + [CHIP Tool user guide](../../../docs/development_controllers/chip-tool/chip_tool_guide.md#building-from-source). 2. Go to the CHIP Tool build directory. 3. Add the light switch device to the multicast group by running the following From 334c6693564dd9b33c62951c47a78d3676d5c473 Mon Sep 17 00:00:00 2001 From: Ethan Zhou <73028112+ethanzhouyc@users.noreply.github.com> Date: Wed, 23 Oct 2024 12:40:18 -0400 Subject: [PATCH 083/149] Generate Conformance Data with Alchemy (#36186) * generate conformance with Alchemy * add conform to color-control cluster extension --- .../chip/access-control-cluster.xml | 50 +- .../data-model/chip/account-login-cluster.xml | 11 +- .../zcl/data-model/chip/actions-cluster.xml | 33 +- .../administrator-commissioning-cluster.xml | 22 +- .../data-model/chip/air-quality-cluster.xml | 5 +- .../chip/application-basic-cluster.xml | 42 +- .../chip/application-launcher-cluster.xml | 18 +- .../data-model/chip/audio-output-cluster.xml | 16 +- .../chip/ballast-configuration-cluster.xml | 80 +- .../chip/basic-information-cluster.xml | 110 +- .../zcl/data-model/chip/binding-cluster.xml | 7 +- .../data-model/chip/boolean-state-cluster.xml | 8 +- .../boolean-state-configuration-cluster.xml | 81 +- .../zcl/data-model/chip/channel-cluster.xml | 53 +- .../data-model/chip/color-control-cluster.xml | 455 ++++- .../chip/commissioner-control-cluster.xml | 5 + .../concentration-measurement-cluster.xml | 1184 +++++++++---- .../chip/content-app-observer-cluster.xml | 2 + .../chip/content-control-cluster.xml | 86 +- .../chip/content-launch-cluster.xml | 30 +- .../data-model/chip/descriptor-cluster.xml | 29 +- .../chip/device-energy-management-cluster.xml | 95 +- .../device-energy-management-mode-cluster.xml | 12 +- .../chip/diagnostic-logs-cluster.xml | 86 +- .../chip/dishwasher-alarm-cluster.xml | 45 +- .../chip/dishwasher-mode-cluster.xml | 14 +- .../zcl/data-model/chip/door-lock-cluster.xml | 1514 ++++++++++------- .../zcl/data-model/chip/drlc-cluster.xml | 39 +- .../electrical-energy-measurement-cluster.xml | 58 +- .../electrical-power-measurement-cluster.xml | 122 +- .../data-model/chip/energy-evse-cluster.xml | 151 +- .../chip/energy-evse-mode-cluster.xml | 12 +- .../chip/energy-preference-cluster.xml | 35 +- .../ethernet-network-diagnostics-cluster.xml | 73 +- .../data-model/chip/fixed-label-cluster.xml | 5 +- .../chip/flow-measurement-cluster.xml | 20 +- .../chip/general-commissioning-cluster.xml | 71 +- .../chip/general-diagnostics-cluster.xml | 60 +- .../chip/group-key-mgmt-cluster.xml | 26 +- .../zcl/data-model/chip/groups-cluster.xml | 17 +- .../chip/icd-management-cluster.xml | 260 +-- .../zcl/data-model/chip/identify-cluster.xml | 16 +- .../chip/illuminance-measurement-cluster.xml | 41 +- .../data-model/chip/keypad-input-cluster.xml | 2 + .../chip/laundry-dryer-controls-cluster.xml | 16 +- .../chip/laundry-washer-mode-cluster.xml | 14 +- .../data-model/chip/level-control-cluster.xml | 95 +- .../localization-configuration-cluster.xml | 6 +- .../zcl/data-model/chip/low-power-cluster.xml | 1 + .../data-model/chip/media-input-cluster.xml | 16 +- .../chip/media-playback-cluster.xml | 103 +- .../zcl/data-model/chip/messages-cluster.xml | 17 +- .../chip/microwave-oven-control-cluster.xml | 73 +- .../chip/microwave-oven-mode-cluster.xml | 10 +- .../data-model/chip/mode-select-cluster.xml | 34 +- .../chip/network-commissioning-cluster.xml | 261 ++- .../chip/occupancy-sensing-cluster.xml | 228 ++- .../zcl/data-model/chip/onoff-cluster.xml | 53 +- .../chip/operational-credentials-cluster.xml | 40 +- .../chip/operational-state-cluster.xml | 71 +- .../chip/operational-state-oven-cluster.xml | 53 +- .../chip/operational-state-rvc-cluster.xml | 74 +- .../zcl/data-model/chip/oven-mode-cluster.xml | 14 +- .../data-model/chip/power-source-cluster.xml | 234 ++- .../power-source-configuration-cluster.xml | 5 +- .../chip/power-topology-cluster.xml | 14 +- .../chip/pressure-measurement-cluster.xml | 57 +- ...pump-configuration-and-control-cluster.xml | 188 +- .../data-model/chip/refrigerator-alarm.xml | 28 +- ...rature-controlled-cabinet-mode-cluster.xml | 14 +- .../relative-humidity-measurement-cluster.xml | 20 +- .../chip/resource-monitoring-cluster.xml | 78 +- .../chip/rvc-clean-mode-cluster.xml | 12 +- .../data-model/chip/rvc-run-mode-cluster.xml | 12 +- .../zcl/data-model/chip/scene.xml | 34 +- .../data-model/chip/service-area-cluster.xml | 42 +- .../chip/smoke-co-alarm-cluster.xml | 91 +- .../chip/software-diagnostics-cluster.xml | 28 +- .../zcl/data-model/chip/switch-cluster.xml | 45 +- .../chip/target-navigator-cluster.xml | 15 +- .../chip/temperature-control-cluster.xml | 49 +- .../chip/temperature-measurement-cluster.xml | 20 +- .../data-model/chip/thermostat-cluster.xml | 310 +++- ...t-user-interface-configuration-cluster.xml | 11 +- ...hread-border-router-management-cluster.xml | 51 +- .../thread-network-diagnostics-cluster.xml | 408 ++++- .../chip/thread-network-directory-cluster.xml | 109 +- .../chip/time-format-localization-cluster.xml | 21 +- .../chip/time-synchronization-cluster.xml | 118 +- .../chip/unit-localization-cluster.xml | 7 +- .../data-model/chip/user-label-cluster.xml | 1 + ...alve-configuration-and-control-cluster.xml | 71 +- .../data-model/chip/wake-on-lan-cluster.xml | 12 +- .../chip/washer-controls-cluster.xml | 30 +- .../chip/water-heater-management-cluster.xml | 40 +- .../chip/water-heater-mode-cluster.xml | 12 +- .../chip/wifi-network-diagnostics-cluster.xml | 87 +- .../chip/wifi-network-management-cluster.xml | 8 +- .../zcl/data-model/chip/window-covering.xml | 230 ++- 99 files changed, 6759 insertions(+), 2033 deletions(-) diff --git a/src/app/zap-templates/zcl/data-model/chip/access-control-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/access-control-cluster.xml index edf1b65e941ad0..831cc5b49361b0 100644 --- a/src/app/zap-templates/zcl/data-model/chip/access-control-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/access-control-cluster.xml @@ -113,29 +113,58 @@ limitations under the License. ACL +
    Extension + + + - SubjectsPerAccessControlEntry - TargetsPerAccessControlEntry - AccessControlEntriesPerFabric - CommissioningARL - ARL - + + SubjectsPerAccessControlEntry + + + + TargetsPerAccessControlEntry + + + + AccessControlEntriesPerFabric + + + + CommissioningARL + + + + + + ARL + + + + + This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. - + + + + Returns the review token for the request, which can be used to correlate with a FabricRestrictionReviewUpdate event. + + + @@ -145,6 +174,7 @@ limitations under the License. + @@ -154,6 +184,9 @@ limitations under the License. + + + @@ -162,6 +195,9 @@ limitations under the License. + + +
    diff --git a/src/app/zap-templates/zcl/data-model/chip/account-login-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/account-login-cluster.xml index baf74dc3c2e1da..38fcbcaaf9c5e4 100644 --- a/src/app/zap-templates/zcl/data-model/chip/account-login-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/account-login-cluster.xml @@ -28,31 +28,36 @@ limitations under the License. Upon receipt, the Content App checks if the account associated with the client Temp Account Identifier Rotating ID is the same acount that is active on the given Content App. If the accounts are the same, then the Content App includes the Setup PIN in the GetSetupPIN Response. - + + Upon receipt, the Content App checks if the account associated with the client’s Temp Account Identifier (Rotating ID) has a current active Setup PIN with the given value. If the Setup PIN is valid for the user account associated with the Temp Account Identifier, then the Content App MAY make that user account active. - + - + + The purpose of this command is to instruct the Content App to clear the current user account. This command SHOULD be used by clients of a Content App to indicate the end of a user session. + This message is sent in response to the GetSetupPIN Request, and contains the Setup PIN code, or null when the accounts identified in the request does not match the active account of the running Content App. + This event can be used by the Content App to indicate that the current user has logged out. In response to this event, the Fabric Admin SHALL remove access to this Content App by the specified Node. If no Node is provided, then the Fabric Admin SHALL remove access to all non-Admin Nodes. + diff --git a/src/app/zap-templates/zcl/data-model/chip/actions-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/actions-cluster.xml index acf28b88e46414..bed60efdf50c65 100644 --- a/src/app/zap-templates/zcl/data-model/chip/actions-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/actions-cluster.xml @@ -89,11 +89,20 @@ limitations under the License. 0x0025 ACTIONS_CLUSTER This cluster provides a standardized way for a Node (typically a Bridge, but could be any Node) to expose action information. - - ActionList - EndpointLists - SetupURL - + + + ActionList + + + + EndpointLists + + + + SetupURL + + + This command triggers an action (state change) on the involved endpoints. @@ -173,17 +182,19 @@ limitations under the License. This event SHALL be generated when there is a change in the Status of an ActionID. - - + + + This event SHALL be generated when there is some error which prevents the action from its normal planned execution. - - - - + + + + + diff --git a/src/app/zap-templates/zcl/data-model/chip/administrator-commissioning-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/administrator-commissioning-cluster.xml index 3532c89b931880..55a8310f0fa7ac 100644 --- a/src/app/zap-templates/zcl/data-model/chip/administrator-commissioning-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/administrator-commissioning-cluster.xml @@ -43,10 +43,19 @@ limitations under the License.
    - WindowStatus - AdminFabricIndex - AdminVendorId - + + WindowStatus + + + + AdminFabricIndex + + + + AdminVendorId + + + This command is used by a current Administrator to instruct a Node to go into commissioning mode using enhanced commissioning method. @@ -55,17 +64,22 @@ limitations under the License. + This command is used by a current Administrator to instruct a Node to go into commissioning mode using basic commissioning method, if the node supports it. + + + This command is used by a current Administrator to instruct a Node to revoke any active Open Commissioning Window or Open Basic Commissioning Window command. + diff --git a/src/app/zap-templates/zcl/data-model/chip/air-quality-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/air-quality-cluster.xml index bbc57510e85dce..6b91830856441c 100644 --- a/src/app/zap-templates/zcl/data-model/chip/air-quality-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/air-quality-cluster.xml @@ -41,7 +41,10 @@ limitations under the License. - AirQuality + + AirQuality + + diff --git a/src/app/zap-templates/zcl/data-model/chip/application-basic-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/application-basic-cluster.xml index e6331f698fd423..ea6be51e9bcb28 100644 --- a/src/app/zap-templates/zcl/data-model/chip/application-basic-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/application-basic-cluster.xml @@ -24,16 +24,38 @@ limitations under the License. true true This cluster provides information about an application running on a TV or media player device which is represented as an endpoint. - VendorName - VendorID - ApplicationName - ProductID - Application - Status - ApplicationVersion - - AllowedVendorList - + + VendorName + + + + VendorID + + + + ApplicationName + + + + ProductID + + + + Application + + + + Status + + + + ApplicationVersion + + + + AllowedVendorList + + diff --git a/src/app/zap-templates/zcl/data-model/chip/application-launcher-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/application-launcher-cluster.xml index 50b715e138a744..34eb73fde5b351 100644 --- a/src/app/zap-templates/zcl/data-model/chip/application-launcher-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/application-launcher-cluster.xml @@ -31,29 +31,41 @@ limitations under the License. - CatalogList - CurrentApp - + + CatalogList + + + + + + CurrentApp + + + Upon receipt, this SHALL launch the specified app with optional data. The TV Device SHALL launch and bring to foreground the identified application in the command if the application is not already launched and in foreground. The TV Device SHALL update state attribute on the Application Basic cluster of the Endpoint corresponding to the launched application. This command returns a Launch Response. + Upon receipt on a Video Player endpoint this SHALL stop the specified application if it is running. + Upon receipt on a Video Player endpoint this SHALL hide the specified application if it is running and visible. + This command SHALL be generated in response to LaunchApp commands. + diff --git a/src/app/zap-templates/zcl/data-model/chip/audio-output-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/audio-output-cluster.xml index acaa9deadb6a3b..0de5d0e3301de5 100644 --- a/src/app/zap-templates/zcl/data-model/chip/audio-output-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/audio-output-cluster.xml @@ -31,12 +31,19 @@ limitations under the License. - OutputList - CurrentOutput - + + OutputList + + + + CurrentOutput + + + Upon receipt, this SHALL change the output on the media device to the output at a specific index in the Output List. + @@ -44,6 +51,9 @@ limitations under the License. + + + diff --git a/src/app/zap-templates/zcl/data-model/chip/ballast-configuration-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/ballast-configuration-cluster.xml index 32450208914a6d..29ec1cd38108f3 100644 --- a/src/app/zap-templates/zcl/data-model/chip/ballast-configuration-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/ballast-configuration-cluster.xml @@ -41,53 +41,75 @@ limitations under the License. - PhysicalMinLevel - PhysicalMaxLevel - BallastStatus + + PhysicalMinLevel + + + + PhysicalMaxLevel + + + + BallastStatus + + - - MinLevel - + + MinLevel + + - - MaxLevel - + + MaxLevel + + - IntrinsicBallastFactor - + IntrinsicBallastFactor + + - - BallastFactorAdjustment - + + BallastFactorAdjustment + + - LampQuantity + + LampQuantity + + - LampType - + LampType + + - LampManufacturer - + LampManufacturer + + - - LampRatedHours - + + LampRatedHours + + - LampBurnHours - + LampBurnHours + + - LampAlarmMode - + LampAlarmMode + + - - LampBurnHoursTripPoint - + + LampBurnHoursTripPoint + + diff --git a/src/app/zap-templates/zcl/data-model/chip/basic-information-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/basic-information-cluster.xml index 7f6320a5880dc9..288c82f950b8ab 100644 --- a/src/app/zap-templates/zcl/data-model/chip/basic-information-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/basic-information-cluster.xml @@ -74,52 +74,118 @@ limitations under the License. which apply to the whole Node. Also allows setting user device information such as location. - DataModelRevision - VendorName - VendorID - ProductName - ProductID - + + DataModelRevision + + + + VendorName + + + + VendorID + + + + ProductName + + + + ProductID + + + NodeLabel + Location + + + + HardwareVersion + + + + HardwareVersionString + + + + SoftwareVersion + + + + SoftwareVersionString + + + + ManufacturingDate + - HardwareVersion - HardwareVersionString - SoftwareVersion - SoftwareVersionString - ManufacturingDate - PartNumber - ProductURL - ProductLabel - SerialNumber - + + PartNumber + + + + ProductURL + + + + ProductLabel + + + + SerialNumber + + + LocalConfigDisabled + + + + Reachable + + + + UniqueID + + + + CapabilityMinima + + + + ProductAppearance + + + + SpecificationVersion + + + + MaxPathsPerInvoke + - Reachable - UniqueID - CapabilityMinima - ProductAppearance - SpecificationVersion - MaxPathsPerInvoke The StartUp event SHALL be emitted by a Node as soon as reasonable after completing a boot or reboot process. + The ShutDown event SHOULD be emitted by a Node prior to any orderly shutdown sequence on a best-effort basis. + The Leave event SHOULD be emitted by a Node prior to permanently leaving the Fabric. + This event (when supported) SHALL be generated when there is a change in the Reachable attribute. diff --git a/src/app/zap-templates/zcl/data-model/chip/binding-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/binding-cluster.xml index 741a5a9372edc0..0b1cbd0c560091 100644 --- a/src/app/zap-templates/zcl/data-model/chip/binding-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/binding-cluster.xml @@ -31,9 +31,10 @@ limitations under the License. 0x001e BINDING_CLUSTER The Binding Cluster is meant to replace the support from the Zigbee Device Object (ZDO) for supporting the binding table. - - Binding - + + Binding + + diff --git a/src/app/zap-templates/zcl/data-model/chip/boolean-state-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/boolean-state-cluster.xml index 0dee692affacee..30a16e16bcc0b0 100644 --- a/src/app/zap-templates/zcl/data-model/chip/boolean-state-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/boolean-state-cluster.xml @@ -26,11 +26,15 @@ limitations under the License. true true - StateValue - + + StateValue + + + This event SHALL be generated when the StateValue attribute changes. + diff --git a/src/app/zap-templates/zcl/data-model/chip/boolean-state-configuration-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/boolean-state-configuration-cluster.xml index 4fb33dd9749a0e..85705e6a03050e 100644 --- a/src/app/zap-templates/zcl/data-model/chip/boolean-state-configuration-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/boolean-state-configuration-cluster.xml @@ -58,34 +58,97 @@ limitations under the License. - CurrentSensitivityLevel - SupportedSensitivityLevels - DefaultSensitivityLevel - AlarmsActive - AlarmsSuppressed - AlarmsEnabled - AlarmsSupported - SensorFault - + + CurrentSensitivityLevel + + + + + + SupportedSensitivityLevels + + + + + + DefaultSensitivityLevel + + + + + + AlarmsActive + + + + + + + + + AlarmsSuppressed + + + + + + AlarmsEnabled + + + + + + + + + AlarmsSupported + + + + + + + + + SensorFault + + + This command is used to suppress the specified alarm mode. + + + This command is used to enable or disable the specified alarm mode. + + + + + + This event SHALL be generated when any bits in the AlarmsActive and/or AlarmsSuppressed attributes change. + + + + + + This event SHALL be generated when the device registers or clears a fault. + diff --git a/src/app/zap-templates/zcl/data-model/chip/channel-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/channel-cluster.xml index 25ec7b7062f97a..c3a08ab084359b 100644 --- a/src/app/zap-templates/zcl/data-model/chip/channel-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/channel-cluster.xml @@ -41,30 +41,57 @@ limitations under the License. - ChannelList - Lineup - CurrentChannel - + + ChannelList + + + + + + Lineup + + + + + + CurrentChannel + + + Change the channel on the media player to the channel case-insensitive exact matching the value passed as an argument. + + + + + + Change the channel on the media plaeyer to the channel with the given Number in the ChannelList attribute. + This command provides channel up and channel down functionality, but allows channel index jumps of size Count. When the value of the increase or decrease is larger than the number of channels remaining in the given direction, then the behavior SHALL be to return to the beginning (or end) of the channel list and continue. For example, if the current channel is at index 0 and count value of -1 is given, then the current channel should change to the last channel. + Upon receipt, this SHALL display the active status of the input list on screen. + + + + + + @@ -76,12 +103,18 @@ limitations under the License. + + + This command is a response to the GetProgramGuide command. + + + @@ -90,6 +123,12 @@ limitations under the License. + + + + + + @@ -98,6 +137,12 @@ limitations under the License. + + + + + + diff --git a/src/app/zap-templates/zcl/data-model/chip/color-control-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/color-control-cluster.xml index 3623ce1ccf925c..a479da36375e4f 100644 --- a/src/app/zap-templates/zcl/data-model/chip/color-control-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/color-control-cluster.xml @@ -127,135 +127,401 @@ limitations under the License. - CurrentHue + + CurrentHue + + + + - CurrentSaturation + + CurrentSaturation + + + + - RemainingTime + + RemainingTime + + - CurrentX + + CurrentX + + + + - CurrentY + + CurrentY + + + + - DriftCompensation + + DriftCompensation + + - CompensationText + + CompensationText + + - ColorTemperatureMireds + + ColorTemperatureMireds + + + + - ColorMode + + ColorMode + + - Options + + Options + + - NumberOfPrimaries + + NumberOfPrimaries + + - Primary1X + + Primary1X + + + + + + + + + + - Primary1Y + + Primary1Y + + + + + + + + + + - Primary1Intensity + + Primary1Intensity + + + + + + + + + + - Primary2X + + Primary2X + + + + + + + + + + - Primary2Y + + Primary2Y + + + + + + + + + + - Primary2Intensity + + Primary2Intensity + + + + + + + + + + - Primary3X + + Primary3X + + + + + + + + + + - Primary3Y + + Primary3Y + + + + + + + + + + - Primary3Intensity + + Primary3Intensity + + + + + + + + + + - Primary4X + + Primary4X + + + + + + + + + + - Primary4Y + + Primary4Y + + + + + + + + + + - Primary4Intensity + + Primary4Intensity + + + + + + + + + + - Primary5X + + Primary5X + + + + + + + + + + - Primary5Y + + Primary5Y + + + + + + + + + + - Primary5Intensity + + Primary5Intensity + + + + + + + + + + - Primary6X + + Primary6X + + + + + + + + + + - Primary6Y + + Primary6Y + + + + + + + + + + - Primary6Intensity + + Primary6Intensity + + + + + + + + + + WhitePointX + WhitePointY + ColorPointRX + ColorPointRY + ColorPointRIntensity + ColorPointGX + ColorPointGY + ColorPointGIntensity + ColorPointBX + ColorPointBY + ColorPointBIntensity + - CoupleColorTempToLevelMinMireds - + + CoupleColorTempToLevelMinMireds + + + + + + + + StartUpColorTemperatureMireds + + + + + + @@ -267,6 +533,9 @@ limitations under the License. + + + @@ -277,6 +546,9 @@ limitations under the License. + + + @@ -288,6 +560,9 @@ limitations under the License. + + + @@ -298,6 +573,9 @@ limitations under the License. + + + @@ -308,6 +586,9 @@ limitations under the License. + + + @@ -319,6 +600,9 @@ limitations under the License. + + + @@ -330,6 +614,9 @@ limitations under the License. + + + @@ -341,6 +628,9 @@ limitations under the License. + + + @@ -351,6 +641,9 @@ limitations under the License. + + + @@ -362,6 +655,9 @@ limitations under the License. + + + @@ -372,20 +668,69 @@ limitations under the License. + + + - EnhancedCurrentHue - EnhancedColorMode - ColorLoopActive - ColorLoopDirection - ColorLoopTime - ColorLoopStartEnhancedHue - ColorLoopStoredEnhancedHue - ColorCapabilities - ColorTempPhysicalMinMireds - ColorTempPhysicalMaxMireds + + EnhancedCurrentHue + + + + + + EnhancedColorMode + + + + ColorLoopActive + + + + + + ColorLoopDirection + + + + + + ColorLoopTime + + + + + + ColorLoopStartEnhancedHue + + + + + + ColorLoopStoredEnhancedHue + + + + + + ColorCapabilities + + + + ColorTempPhysicalMinMireds + + + + + + ColorTempPhysicalMaxMireds + + + + @@ -396,6 +741,9 @@ limitations under the License. + + + @@ -406,6 +754,9 @@ limitations under the License. + + + @@ -417,6 +768,9 @@ limitations under the License. + + + @@ -428,6 +782,9 @@ limitations under the License. + + + @@ -441,6 +798,9 @@ limitations under the License. + + + @@ -449,6 +809,13 @@ limitations under the License. + + + + + + + @@ -461,6 +828,9 @@ limitations under the License. + + + @@ -474,6 +844,9 @@ limitations under the License. + + + diff --git a/src/app/zap-templates/zcl/data-model/chip/commissioner-control-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/commissioner-control-cluster.xml index dcfb1dfa7096b8..33f26e3689e5f4 100644 --- a/src/app/zap-templates/zcl/data-model/chip/commissioner-control-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/commissioner-control-cluster.xml @@ -35,6 +35,7 @@ limitations under the License. SupportedDeviceCategories + @@ -44,6 +45,7 @@ limitations under the License. + @@ -51,6 +53,7 @@ limitations under the License. + @@ -60,6 +63,7 @@ limitations under the License. + @@ -68,6 +72,7 @@ limitations under the License. + diff --git a/src/app/zap-templates/zcl/data-model/chip/concentration-measurement-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/concentration-measurement-cluster.xml index 4d03c539103970..e2116fc03cc80c 100644 --- a/src/app/zap-templates/zcl/data-model/chip/concentration-measurement-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/concentration-measurement-cluster.xml @@ -58,17 +58,70 @@ limitations under the License. - MeasuredValue - MinMeasuredValue - MaxMeasuredValue - PeakMeasuredValue - PeakMeasuredValueWindow - AverageMeasuredValue - AverageMeasuredValueWindow - Uncertainty - MeasurementUnit - MeasurementMedium - LevelValue + + MeasuredValue + + + + + + MinMeasuredValue + + + + + + MaxMeasuredValue + + + + + + PeakMeasuredValue + + + + + + PeakMeasuredValueWindow + + + + + + AverageMeasuredValue + + + + + + AverageMeasuredValueWindow + + + + + + Uncertainty + + + + + + MeasurementUnit + + + + + + MeasurementMedium + + + + LevelValue + + + + @@ -113,17 +166,70 @@ limitations under the License. - MeasuredValue - MinMeasuredValue - MaxMeasuredValue - PeakMeasuredValue - PeakMeasuredValueWindow - AverageMeasuredValue - AverageMeasuredValueWindow - Uncertainty - MeasurementUnit - MeasurementMedium - LevelValue + + MeasuredValue + + + + + + MinMeasuredValue + + + + + + MaxMeasuredValue + + + + + + PeakMeasuredValue + + + + + + PeakMeasuredValueWindow + + + + + + AverageMeasuredValue + + + + + + AverageMeasuredValueWindow + + + + + + Uncertainty + + + + + + MeasurementUnit + + + + + + MeasurementMedium + + + + LevelValue + + + + @@ -139,45 +245,98 @@ limitations under the License. - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + - MeasuredValue - MinMeasuredValue - MaxMeasuredValue - PeakMeasuredValue - PeakMeasuredValueWindow - AverageMeasuredValue - AverageMeasuredValueWindow - Uncertainty - MeasurementUnit - MeasurementMedium - LevelValue + + MeasuredValue + + + + + + MinMeasuredValue + + + + + + MaxMeasuredValue + + + + + + PeakMeasuredValue + + + + + + PeakMeasuredValueWindow + + + + + + AverageMeasuredValue + + + + + + AverageMeasuredValueWindow + + + + + + Uncertainty + + + + + + MeasurementUnit + + + + + + MeasurementMedium + + + + LevelValue + + + + @@ -193,45 +352,98 @@ limitations under the License. - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + - MeasuredValue - MinMeasuredValue - MaxMeasuredValue - PeakMeasuredValue - PeakMeasuredValueWindow - AverageMeasuredValue - AverageMeasuredValueWindow - Uncertainty - MeasurementUnit - MeasurementMedium - LevelValue + + MeasuredValue + + + + + + MinMeasuredValue + + + + + + MaxMeasuredValue + + + + + + PeakMeasuredValue + + + + + + PeakMeasuredValueWindow + + + + + + AverageMeasuredValue + + + + + + AverageMeasuredValueWindow + + + + + + Uncertainty + + + + + + MeasurementUnit + + + + + + MeasurementMedium + + + + LevelValue + + + + @@ -247,45 +459,98 @@ limitations under the License. - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + - MeasuredValue - MinMeasuredValue - MaxMeasuredValue - PeakMeasuredValue - PeakMeasuredValueWindow - AverageMeasuredValue - AverageMeasuredValueWindow - Uncertainty - MeasurementUnit - MeasurementMedium - LevelValue + + MeasuredValue + + + + + + MinMeasuredValue + + + + + + MaxMeasuredValue + + + + + + PeakMeasuredValue + + + + + + PeakMeasuredValueWindow + + + + + + AverageMeasuredValue + + + + + + AverageMeasuredValueWindow + + + + + + Uncertainty + + + + + + MeasurementUnit + + + + + + MeasurementMedium + + + + LevelValue + + + + @@ -301,45 +566,98 @@ limitations under the License. - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + - MeasuredValue - MinMeasuredValue - MaxMeasuredValue - PeakMeasuredValue - PeakMeasuredValueWindow - AverageMeasuredValue - AverageMeasuredValueWindow - Uncertainty - MeasurementUnit - MeasurementMedium - LevelValue + + MeasuredValue + + + + + + MinMeasuredValue + + + + + + MaxMeasuredValue + + + + + + PeakMeasuredValue + + + + + + PeakMeasuredValueWindow + + + + + + AverageMeasuredValue + + + + + + AverageMeasuredValueWindow + + + + + + Uncertainty + + + + + + MeasurementUnit + + + + + + MeasurementMedium + + + + LevelValue + + + + @@ -355,45 +673,98 @@ limitations under the License. - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + - MeasuredValue - MinMeasuredValue - MaxMeasuredValue - PeakMeasuredValue - PeakMeasuredValueWindow - AverageMeasuredValue - AverageMeasuredValueWindow - Uncertainty - MeasurementUnit - MeasurementMedium - LevelValue + + MeasuredValue + + + + + + MinMeasuredValue + + + + + + MaxMeasuredValue + + + + + + PeakMeasuredValue + + + + + + PeakMeasuredValueWindow + + + + + + AverageMeasuredValue + + + + + + AverageMeasuredValueWindow + + + + + + Uncertainty + + + + + + MeasurementUnit + + + + + + MeasurementMedium + + + + LevelValue + + + + @@ -409,45 +780,98 @@ limitations under the License. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - MeasuredValue - MinMeasuredValue - MaxMeasuredValue - PeakMeasuredValue - PeakMeasuredValueWindow - AverageMeasuredValue - AverageMeasuredValueWindow - Uncertainty - MeasurementUnit - MeasurementMedium - LevelValue + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MeasuredValue + + + + + + MinMeasuredValue + + + + + + MaxMeasuredValue + + + + + + PeakMeasuredValue + + + + + + PeakMeasuredValueWindow + + + + + + AverageMeasuredValue + + + + + + AverageMeasuredValueWindow + + + + + + Uncertainty + + + + + + MeasurementUnit + + + + + + MeasurementMedium + + + + LevelValue + + + + @@ -463,45 +887,98 @@ limitations under the License. - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + - MeasuredValue - MinMeasuredValue - MaxMeasuredValue - PeakMeasuredValue - PeakMeasuredValueWindow - AverageMeasuredValue - AverageMeasuredValueWindow - Uncertainty - MeasurementUnit - MeasurementMedium - LevelValue + + MeasuredValue + + + + + + MinMeasuredValue + + + + + + MaxMeasuredValue + + + + + + PeakMeasuredValue + + + + + + PeakMeasuredValueWindow + + + + + + AverageMeasuredValue + + + + + + AverageMeasuredValueWindow + + + + + + Uncertainty + + + + + + MeasurementUnit + + + + + + MeasurementMedium + + + + LevelValue + + + + @@ -517,45 +994,98 @@ limitations under the License. - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + - MeasuredValue - MinMeasuredValue - MaxMeasuredValue - PeakMeasuredValue - PeakMeasuredValueWindow - AverageMeasuredValue - AverageMeasuredValueWindow - Uncertainty - MeasurementUnit - MeasurementMedium - LevelValue + + MeasuredValue + + + + + + MinMeasuredValue + + + + + + MaxMeasuredValue + + + + + + PeakMeasuredValue + + + + + + PeakMeasuredValueWindow + + + + + + AverageMeasuredValue + + + + + + AverageMeasuredValueWindow + + + + + + Uncertainty + + + + + + MeasurementUnit + + + + + + MeasurementMedium + + + + LevelValue + + + + diff --git a/src/app/zap-templates/zcl/data-model/chip/content-app-observer-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/content-app-observer-cluster.xml index 6e241c7b5c3cd0..0f5a99b6ba9266 100644 --- a/src/app/zap-templates/zcl/data-model/chip/content-app-observer-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/content-app-observer-cluster.xml @@ -29,6 +29,7 @@ limitations under the License. Upon receipt, the data field MAY be parsed and interpreted. Message encoding is specific to the Content App. A Content App MAY when possible read attributes from the Basic Information Cluster on the Observer and use this to determine the Message encoding. + @@ -36,6 +37,7 @@ limitations under the License. + diff --git a/src/app/zap-templates/zcl/data-model/chip/content-control-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/content-control-cluster.xml index 06468c114c42dc..e42967b581fac6 100644 --- a/src/app/zap-templates/zcl/data-model/chip/content-control-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/content-control-cluster.xml @@ -43,69 +43,139 @@ limitations under the License. - Enabled - OnDemandRatings - OnDemandRatingThreshold - ScheduledContentRatings - ScheduledContentRatingThreshold - ScreenDailyTime - RemainingScreenTime - BlockUnrated + + Enabled + + + + OnDemandRatings + + + + + + OnDemandRatingThreshold + + + + + + ScheduledContentRatings + + + + + + ScheduledContentRatingThreshold + + + + + + ScreenDailyTime + + + + + + RemainingScreenTime + + + + + + BlockUnrated + + + + The purpose of this command is to update the PIN used for protecting configuration of the content control settings. Upon success, the old PIN SHALL no longer work. The PIN is used to ensure that only the Node (or User) with the PIN code can make changes to the Content Control settings, for example, turn off Content Controls or modify the ScreenDailyTime. The PIN is composed of a numeric string of up to 6 human readable characters (displayable) . Upon receipt of this command, the media device SHALL check if the OldPIN field of this command is the same as the current PIN. If the PINs are the same, then the PIN code SHALL be set to NewPIN. Otherwise a response with InvalidPINCode error status SHALL be returned. The media device MAY provide a default PIN to the User via an out of band mechanism. For security reasons, it is recommended that a client encourage the user to update the PIN from its default value when performing configuration of the Content Control settings exposed by this cluster. The ResetPIN command can also be used to obtain the default PIN. + + + The purpose of this command is to reset the PIN. If this command is executed successfully, a ResetPINResponse command with a new PIN SHALL be returned. + + + This command SHALL be generated in response to a ResetPIN command. The data for this command SHALL be as follows: + + + The purpose of this command is to turn on the Content Control feature on a media device. On receipt of the Enable command, the media device SHALL set the Enabled attribute to TRUE. + The purpose of this command is to turn off the Content Control feature on a media device. On receipt of the Disable command, the media device SHALL set the Enabled attribute to FALSE. + The purpose of this command is to add the extra screen time for the user. If a client with Operate privilege invokes this command, the media device SHALL check whether the PINCode passed in the command matches the current PINCode value. If these match, then the RemainingScreenTime attribute SHALL be increased by the specified BonusTime value. If the PINs do not match, then a response with InvalidPINCode error status SHALL be returned, and no changes SHALL be made to RemainingScreenTime. If a client with Manage privilege or greater invokes this command, the media device SHALL ignore the PINCode field and directly increase the RemainingScreenTime attribute by the specified BonusTime value. A server that does not support the PM feature SHALL respond with InvalidPINCode to clients that only have Operate privilege unless: It has been provided with the PIN value to expect via an out of band mechanism, and The client has provided a PINCode that matches the expected PIN value. + + + The purpose of this command is to set the ScreenDailyTime attribute. On receipt of the SetScreenDailyTime command, the media device SHALL set the ScreenDailyTime attribute to the ScreenTime value. + + + The purpose of this command is to specify whether programs with no Content rating must be blocked by this media device. On receipt of the BlockUnratedContent command, the media device SHALL set the BlockUnrated attribute to TRUE. + + + The purpose of this command is to specify whether programs with no Content rating must be blocked by this media device. On receipt of the UnblockUnratedContent command, the media device SHALL set the BlockUnrated attribute to FALSE. + + + The purpose of this command is to set the OnDemandRatingThreshold attribute. On receipt of the SetOnDemandRatingThreshold command, the media device SHALL check if the Rating field is one of values present in the OnDemandRatings attribute. If not, then a response with InvalidRating error status SHALL be returned. + + + The purpose of this command is to set ScheduledContentRatingThreshold attribute. On receipt of the SetScheduledContentRatingThreshold command, the media device SHALL check if the Rating field is one of values present in the ScheduledContentRatings attribute. If not, then a response with InvalidRating error status SHALL be returned. + + + This event SHALL be generated when the RemainingScreenTime equals 0. + + + diff --git a/src/app/zap-templates/zcl/data-model/chip/content-launch-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/content-launch-cluster.xml index 7058f969799087..31ad15a48b93ac 100644 --- a/src/app/zap-templates/zcl/data-model/chip/content-launch-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/content-launch-cluster.xml @@ -25,10 +25,20 @@ limitations under the License. true This cluster provides an interface for launching content on a media player device such as a TV or Speaker. - - AcceptHeader - SupportedStreamingProtocols - + + + AcceptHeader + + + + + + SupportedStreamingProtocols + + + + + Upon receipt, this SHALL launch the specified content with optional search criteria. @@ -36,6 +46,9 @@ limitations under the License. + + + @@ -43,12 +56,21 @@ limitations under the License. + + + This command SHALL be generated in response to LaunchContent command. + + + + + + diff --git a/src/app/zap-templates/zcl/data-model/chip/descriptor-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/descriptor-cluster.xml index d63dbeb05ca11a..f34d705a2486da 100644 --- a/src/app/zap-templates/zcl/data-model/chip/descriptor-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/descriptor-cluster.xml @@ -44,11 +44,28 @@ limitations under the License. - - DeviceTypeList - ServerList - ClientList - PartsList - TagList + + + DeviceTypeList + + + + ServerList + + + + ClientList + + + + PartsList + + + + TagList + + + + diff --git a/src/app/zap-templates/zcl/data-model/chip/device-energy-management-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/device-energy-management-cluster.xml index 3550dd0301be99..250e3546ea8805 100644 --- a/src/app/zap-templates/zcl/data-model/chip/device-energy-management-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/device-energy-management-cluster.xml @@ -74,41 +74,95 @@ Git: 1.4-prerelease-ipr-69-ge15ff5700 - ESAType - ESACanGenerate - ESAState - AbsMinPower - AbsMaxPower + + ESAType + + + + ESACanGenerate + + + + ESAState + + + + AbsMinPower + + + + AbsMaxPower + + - PowerAdjustmentCapability + + PowerAdjustmentCapability + + + + - Forecast - OptOutState + + Forecast + + + + + + + + + OptOutState + + + + + + + + + + Allows a client to request an adjustment in the power consumption of an ESA for a specified duration. + + + Allows a client to cancel an ongoing PowerAdjustmentRequest operation. + + + Allows a client to adjust the start time of a Forecast sequence that has not yet started operation (i.e. where the current Forecast StartTime is in the future). + + + Allows a client to temporarily pause an operation and reduce the ESAs energy demand. + + + Allows a client to cancel the PauseRequest command and enable earlier resumption of operation. + + + @@ -116,20 +170,36 @@ Git: 1.4-prerelease-ipr-69-ge15ff5700 + + + Allows a client to ask the ESA to recompute its Forecast based on power and time constraints. + + + Allows a client to request cancellation of a previous adjustment request in a StartTimeAdjustRequest, ModifyForecastRequest or RequestConstraintBasedForecast command. + + + + + + + This event SHALL be generated when the Power Adjustment session is started. + + + @@ -137,15 +207,24 @@ Git: 1.4-prerelease-ipr-69-ge15ff5700 + + + This event SHALL be generated when the ESA enters the Paused state. + + + This event SHALL be generated when the ESA leaves the Paused state and resumes operation. + + + diff --git a/src/app/zap-templates/zcl/data-model/chip/device-energy-management-mode-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/device-energy-management-mode-cluster.xml index c3440adebef3f6..470040b5c4f476 100644 --- a/src/app/zap-templates/zcl/data-model/chip/device-energy-management-mode-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/device-energy-management-mode-cluster.xml @@ -59,18 +59,26 @@ Git: 1.4-prerelease-ipr-69-ge15ff5700 - SupportedModes - CurrentMode + + SupportedModes + + + + CurrentMode + + This command is used to change device modes. + This command is sent by the device on receipt of the ChangeToMode command. + diff --git a/src/app/zap-templates/zcl/data-model/chip/diagnostic-logs-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/diagnostic-logs-cluster.xml index 27162f66e5e6db..4140fd18a0eaec 100644 --- a/src/app/zap-templates/zcl/data-model/chip/diagnostic-logs-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/diagnostic-logs-cluster.xml @@ -15,46 +15,48 @@ See the License for the specific language governing permissions and limitations under the License. --> - - - - - - - - - - - - - - - - - - - - - - Diagnostic Logs - CHIP - The cluster provides commands for retrieving unstructured diagnostic logs from a Node that may be used to aid in diagnostics. - 0x0032 - DIAGNOSTIC_LOGS_CLUSTER - true - true - - Retrieving diagnostic logs from a Node - - - - - - Response to the RetrieveLogsRequest - - - - - - + + + + + + + + + + + + + + + + + + + + + + Diagnostic Logs + CHIP + The cluster provides commands for retrieving unstructured diagnostic logs from a Node that may be used to aid in diagnostics. + 0x0032 + DIAGNOSTIC_LOGS_CLUSTER + true + true + + Retrieving diagnostic logs from a Node + + + + + + + Response to the RetrieveLogsRequest + + + + + + + diff --git a/src/app/zap-templates/zcl/data-model/chip/dishwasher-alarm-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/dishwasher-alarm-cluster.xml index 7e41a7a1c03f99..a8cf1e166219e2 100644 --- a/src/app/zap-templates/zcl/data-model/chip/dishwasher-alarm-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/dishwasher-alarm-cluster.xml @@ -43,27 +43,46 @@ limitations under the License. - Mask - Latch - State - Supported + + Mask + + + + Latch + + + + + + State + + + + Supported + + - Reset alarm - + Reset alarm + + + + - Modify enabled alarms - + Modify enabled alarms + + - Notify - - - - + Notify + + + + + diff --git a/src/app/zap-templates/zcl/data-model/chip/dishwasher-mode-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/dishwasher-mode-cluster.xml index 7c7dec635f3b6c..7cc15557f0c5a1 100644 --- a/src/app/zap-templates/zcl/data-model/chip/dishwasher-mode-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/dishwasher-mode-cluster.xml @@ -57,11 +57,17 @@ limitations under the License. - SupportedModes - CurrentMode + + SupportedModes + + + + CurrentMode + + StartUpMode OnMode - + @@ -69,6 +75,7 @@ limitations under the License. On receipt of this command the device SHALL respond with a ChangeToModeResponse command. + @@ -77,6 +84,7 @@ limitations under the License. + diff --git a/src/app/zap-templates/zcl/data-model/chip/door-lock-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/door-lock-cluster.xml index b25cd549d90091..f16bbbf28bbbba 100644 --- a/src/app/zap-templates/zcl/data-model/chip/door-lock-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/door-lock-cluster.xml @@ -131,659 +131,901 @@ limitations under the License. 3. Everything that depends on a certain feature is optional because we have no way of setting up the dependencies here. Dependencies would be probably resolved in the cluster itself. Those attributes/commands are marked with a special comment. --> + + + + LockState + + + + LockType + + + + ActuatorEnabled + + + + + DoorState + + + + + + + DoorOpenEvents + + + + + + + + + DoorClosedEvents + + + + + + + + + OpenPeriod + + + + + + + + + NumberOfTotalUsersSupported + + + + + + + NumberOfPINUsersSupported + + + + + + + NumberOfRFIDUsersSupported + + + + + + + NumberOfWeekDaySchedulesSupportedPerUser + + + + + + + NumberOfYearDaySchedulesSupportedPerUser + + + + + + + NumberOfHolidaySchedulesSupported + + + + + + + MaxPINCodeLength + + + + + + + MinPINCodeLength + + + + + + + MaxRFIDCodeLength + + + + + + + MinRFIDCodeLength + + + + + + + CredentialRulesSupport + + + + + + + NumberOfCredentialsSupportedPerUser + + + + + + Language + + + + + + LEDSettings + + + + + + AutoRelockTime + + + + + + SoundVolume + + + + + + OperatingMode + + + + + + SupportedOperatingModes + + + + DefaultConfigurationRegister + + + + EnableLocalProgramming + + + + + + EnableOneTouchLocking + + + + + + EnableInsideStatusLED + + + + + + EnablePrivacyModeButton + + + + + + LocalProgrammingFeatures + + + + + + + WrongCodeEntryLimit + + + + + + + + + + + + UserCodeTemporaryDisableTime + + + + + + + + + + + + SendPINOverTheAir + + + + + + + + + + + + + + RequirePINforRemoteOperation + + + + + + + + + + + + + ExpiringUserTimeout + + + + + + + + + AliroReaderVerificationKey + + + + + + + + AliroReaderGroupIdentifier + + + + + + + + AliroReaderGroupSubIdentifier + + + + + + + + AliroExpeditedTransactionSupportedProtocolVersions + + + + + + + + AliroGroupResolvingKey + + + + + + + + AliroSupportedBLEUWBProtocolVersions + + + + + + + + AliroBLEAdvertisingVersion + + + + + + + + NumberOfAliroCredentialIssuerKeysSupported + + + + + + + NumberOfAliroEndpointKeysSupported + + + + + + + This command causes the lock device to lock the door. + + + + + + This command causes the lock device to unlock the door. + + + + + + + This command causes the lock device to unlock the door with a timeout parameter. + + + + + + + + Set a weekly repeating schedule for a specified user. + + + + + + + + + + + + + + + Retrieve the specific weekly schedule for the specific user. + + + + + + + + + + Returns the weekly repeating schedule data for the specified schedule index. + + + + + + + + + + + + + + + Clear the specific weekly schedule or all weekly schedules for the specific user. + + + + + + + + + + Set a time-specific schedule ID for a specified user. + + + + + + + + + + + + Returns the year day schedule data for the specified schedule and user indexes. + + + + + + + + + + Returns the year day schedule data for the specified schedule and user indexes. + + + + + + + + + + + + Clears the specific year day schedule or all year day schedules for the specific user. + + + + + + + + + + Set the holiday Schedule by specifying local start time and local end time with respect to any Lock Operating Mode. + + + + + + + + + + + + Get the holiday schedule for the specified index. + + + + + + + + + Returns the Holiday Schedule Entry for the specified Holiday ID. + + + + + + + + + + + + Clears the holiday schedule or all holiday schedules. + + + + + + + + + Set User into the lock. + + + + + + + + + + + + + + + Retrieve User. + + + + + + + + + Returns the User for the specified UserIndex. + + + + + + + + + + + + + + + + + Clears a User or all Users. + + + + + + + + + Set a credential (e.g. PIN, RFID, Fingerprint, etc.) into the lock for a new user, existing user, or ProgrammingUser. + + + + + + + + + + + + + + Returns the status for setting the specified credential. + + + + + + + + + + Retrieve the status of a particular credential (e.g. PIN, RFID, Fingerprint, etc.) by index. + + + + + + + + + Returns the status for the specified credential. + + + + + + + + + + + + + Clear one, one type, or all credentials except ProgrammingPIN credential. + + + + + + + + This command causes the lock device to unlock the door without pulling the latch. + + + + + + + + This command communicates an Aliro Reader configuration to the lock. + + + + + + + + + + + This command clears an existing Aliro Reader configuration for the lock. + + + + + - - LockState - LockType - ActuatorEnabled - - DoorState - - - DoorOpenEvents - - - - - - DoorClosedEvents - - - - - - OpenPeriod - - - - - NumberOfTotalUsersSupported - - NumberOfPINUsersSupported - - NumberOfRFIDUsersSupported - - NumberOfWeekDaySchedulesSupportedPerUser - - NumberOfYearDaySchedulesSupportedPerUser - - NumberOfHolidaySchedulesSupported - - MaxPINCodeLength - - MinPINCodeLength - - MaxRFIDCodeLength - - MinRFIDCodeLength - - CredentialRulesSupport - - NumberOfCredentialsSupportedPerUser - - Language - - - - - LEDSettings - - - - - AutoRelockTime - - - - - SoundVolume - - - - - OperatingMode - - - - SupportedOperatingModes - DefaultConfigurationRegister - - EnableLocalProgramming - - - - - EnableOneTouchLocking - - - - - EnableInsideStatusLED - - - - - EnablePrivacyModeButton - - - - - LocalProgrammingFeatures - - - - - - WrongCodeEntryLimit - - - - - - UserCodeTemporaryDisableTime - - - - - - SendPINOverTheAir - - - - - - RequirePINforRemoteOperation - - - - - - - ExpiringUserTimeout - - - - - - AliroReaderVerificationKey - - - - - AliroReaderGroupIdentifier - - - - - AliroReaderGroupSubIdentifier - - - - - AliroExpeditedTransactionSupportedProtocolVersions - - - - - AliroGroupResolvingKey - - - - - AliroSupportedBLEUWBProtocolVersions - - - - - AliroBLEAdvertisingVersion - - - - NumberOfAliroCredentialIssuerKeysSupported - - NumberOfAliroEndpointKeysSupported - - - - This command causes the lock device to lock the door. - - - - - This command causes the lock device to unlock the door. - - - - - - This command causes the lock device to unlock the door with a timeout parameter. - - - - - - - Set a weekly repeating schedule for a specified user. - - - - - - - - - - - - Retrieve the specific weekly schedule for the specific user. - - - - - - - Returns the weekly repeating schedule data for the specified schedule index. - - - - - - - - - - - - Clear the specific weekly schedule or all weekly schedules for the specific user. - - - - - - - Set a time-specific schedule ID for a specified user. - - - - - - - - - Returns the year day schedule data for the specified schedule and user indexes. - - - - - - - Returns the year day schedule data for the specified schedule and user indexes. - - - - - - - - - Clears the specific year day schedule or all year day schedules for the specific user. - - - - - - - Set the holiday Schedule by specifying local start time and local end time with respect to any Lock Operating Mode. - - - - - - - - - Get the holiday schedule for the specified index. - - - - - - Returns the Holiday Schedule Entry for the specified Holiday ID. - - - - - - - - - Clears the holiday schedule or all holiday schedules. - - - - - - Set User into the lock. - - - - - - - - - - - - Retrieve User. - - - - - - Returns the User for the specified UserIndex. - - - - - - - - - - - - - - Clears a User or all Users. - - - - - - Set a credential (e.g. PIN, RFID, Fingerprint, etc.) into the lock for a new user, existing user, or ProgrammingUser. - - - - - - - - - - - Returns the status for setting the specified credential. - - - - - - - Retrieve the status of a particular credential (e.g. PIN, RFID, Fingerprint, etc.) by index. - - - - - - Returns the status for the specified credential. - - - - - - - - - - Clear one, one type, or all credentials except ProgrammingPIN credential. - - - - - This command causes the lock device to unlock the door without pulling the latch. - - - - - This command communicates an Aliro Reader configuration to the lock. - - - - - - - - This command clears an existing Aliro Reader configuration for the lock. - - - - - - - The door lock cluster provides several alarms which can be sent when there is a critical state on the door lock. - - - - - The door lock server sends out a DoorStateChange event when the door lock door state changes. - - - - The door lock server sends out a LockOperation event when the event is triggered by the various lock operation sources. - - - - - - - - - - The door lock server sends out a LockOperationError event when a lock operation fails for various reasons. - - - - - - - - - - - The door lock server sends out a LockUserChange event when a lock user, schedule, or credential change has occurred. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + The door lock cluster provides several alarms which can be sent when there is a critical state on the door lock. + + + + + + The door lock server sends out a DoorStateChange event when the door lock door state changes. + + + + + + + The door lock server sends out a LockOperation event when the event is triggered by the various lock operation sources. + + + + + + + + + + + The door lock server sends out a LockOperationError event when a lock operation fails for various reasons. + + + + + + + + + + + + The door lock server sends out a LockUserChange event when a lock user, schedule, or credential change has occurred. + + + + + + + + + + + + - - - - - - - - - - - + + + + + + + + + + + + - - - - - - - - - - - - + + + + + + - - - - - - + + + + + + - - - - - - - - - - + + + + + - - - - - - - - - + + + + + + + + + + + + - - - - - - - - - - - - - - - - - + + + + + + - - - - - - - - + + + + + + + + + + - - - - - - - - + + + + + + + + + - - - - - - - - + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - + + + + + + + + - - - - - - + + + + + + + + - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - + + + + + + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + - - - - - - - - - - - - - - - - + + + + + + + + + - - - - - - - - - - + + + + + + + + + + + + + + + + - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + @@ -796,7 +1038,7 @@ limitations under the License. - + @@ -808,7 +1050,7 @@ limitations under the License. - + @@ -824,7 +1066,7 @@ limitations under the License. - + @@ -836,7 +1078,7 @@ limitations under the License. - + @@ -846,7 +1088,7 @@ limitations under the License. - + @@ -858,7 +1100,7 @@ limitations under the License. - + diff --git a/src/app/zap-templates/zcl/data-model/chip/drlc-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/drlc-cluster.xml index d64bce1c85b7f6..d7e04ccf464668 100644 --- a/src/app/zap-templates/zcl/data-model/chip/drlc-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/drlc-cluster.xml @@ -199,21 +199,41 @@ limitations under the License. - LoadControlPrograms - NumberOfLoadControlPrograms - Events - ActiveEvents - NumberOfEventsPerProgram - NumberOfTransitions - + + LoadControlPrograms + + + + NumberOfLoadControlPrograms + + + + Events + + + + ActiveEvents + + + + NumberOfEventsPerProgram + + + + NumberOfTransitions + + + DefaultRandomStart + DefaultRandomDuration + @@ -221,18 +241,21 @@ limitations under the License. Upon receipt, this SHALL insert a new LoadControlProgramStruct into LoadControlPrograms, or if the ProgramID matches an existing LoadControlProgramStruct, then the provider SHALL be updated with the provided values. + Upon receipt, this SHALL remove a the LoadControlProgramStruct from LoadControlPrograms with the matching ProgramID. + On receipt of the AddLoadControlEventsRequest command, the server SHALL add a load control event. + @@ -240,6 +263,7 @@ limitations under the License. + + diff --git a/src/app/zap-templates/zcl/data-model/chip/electrical-energy-measurement-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/electrical-energy-measurement-cluster.xml index eb05052538d2de..3fbd9e984fc2a0 100644 --- a/src/app/zap-templates/zcl/data-model/chip/electrical-energy-measurement-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/electrical-energy-measurement-cluster.xml @@ -42,25 +42,71 @@ limitations under the License. - Accuracy - CumulativeEnergyImported + + Accuracy + + + + CumulativeEnergyImported + + + + + + + - CumulativeEnergyExported + + CumulativeEnergyExported + + + + + + + - PeriodicEnergyImported + + PeriodicEnergyImported + + + + + + + - PeriodicEnergyExported - CumulativeEnergyReset + + PeriodicEnergyExported + + + + + + + + + CumulativeEnergyReset + + + + CumulativeEnergyMeasured + + + PeriodicEnergyMeasured + + + diff --git a/src/app/zap-templates/zcl/data-model/chip/electrical-power-measurement-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/electrical-power-measurement-cluster.xml index 7f49a643d1b1f9..18ee20bad30481 100644 --- a/src/app/zap-templates/zcl/data-model/chip/electrical-power-measurement-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/electrical-power-measurement-cluster.xml @@ -51,40 +51,124 @@ limitations under the License. - PowerMode - NumberOfMeasurementTypes - Accuracy - Ranges - Voltage + + PowerMode + + + + NumberOfMeasurementTypes + + + + Accuracy + + + + Ranges + + + + Voltage + + - ActiveCurrent + + ActiveCurrent + + - ReactiveCurrent - ApparentCurrent + + ReactiveCurrent + + + + + + ApparentCurrent + + + + - ActivePower + + ActivePower + + - ReactivePower + + ReactivePower + + + + - ApparentPower + + ApparentPower + + + + - RMSVoltage + + RMSVoltage + + + + - RMSCurrent + + RMSCurrent + + + + - RMSPower + + RMSPower + + + + - Frequency + + Frequency + + + + - HarmonicCurrents + + HarmonicCurrents + + + + - HarmonicPhases + + HarmonicPhases + + + + - PowerFactor - NeutralCurrent + + PowerFactor + + + + + + NeutralCurrent + + + + MeasurementPeriodRanges + + + diff --git a/src/app/zap-templates/zcl/data-model/chip/energy-evse-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/energy-evse-cluster.xml index 7a4a40d2e39966..97709d706abf4d 100644 --- a/src/app/zap-templates/zcl/data-model/chip/energy-evse-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/energy-evse-cluster.xml @@ -128,53 +128,139 @@ Git: 1.4-prerelease-ipr-69-ge15ff5700 - State - SupplyState - FaultState - ChargingEnabledUntil + + State + + + + SupplyState + + + + FaultState + + + + ChargingEnabledUntil + + - DischargingEnabledUntil - CircuitCapacity - MinimumChargeCurrent - MaximumChargeCurrent + + DischargingEnabledUntil + + + + + + CircuitCapacity + + + + MinimumChargeCurrent + + + + MaximumChargeCurrent + + - MaximumDischargeCurrent + + MaximumDischargeCurrent + + + + UserMaximumChargeCurrent + RandomizationDelayWindow + - NextChargeStartTime + + NextChargeStartTime + + + + - NextChargeTargetTime + + NextChargeTargetTime + + + + - NextChargeRequiredEnergy + + NextChargeRequiredEnergy + + + + - NextChargeTargetSoC + + NextChargeTargetSoC + + + + ApproximateEVEfficiency + + + - StateOfCharge + + StateOfCharge + + + + - BatteryCapacity + + BatteryCapacity + + + + - VehicleID - SessionID - SessionDuration - SessionEnergyCharged + + VehicleID + + + + + + SessionID + + + + SessionDuration + + + + SessionEnergyCharged + + - SessionEnergyDischarged + + SessionEnergyDischarged + + + + Allows a client to disable the EVSE from charging and discharging. + @@ -182,39 +268,57 @@ Git: 1.4-prerelease-ipr-69-ge15ff5700 This command allows a client to enable the EVSE to charge an EV, and to provide or update the maximum and minimum charge current. + Upon receipt, this SHALL allow a client to enable the discharge of an EV, and to provide or update the maximum discharge current. + + + Allows a client to put the EVSE into a self-diagnostics mode. + Allows a client to set the user specified charging targets. + + + Allows a client to retrieve the current set of charging targets. + + + Allows a client to clear all stored charging targets. + + + The GetTargetsResponse is sent in response to the GetTargets Command. + + + This event SHALL be generated when the EV is plugged in. + @@ -224,6 +328,7 @@ Git: 1.4-prerelease-ipr-69-ge15ff5700 + @@ -232,6 +337,7 @@ Git: 1.4-prerelease-ipr-69-ge15ff5700 + @@ -241,6 +347,7 @@ Git: 1.4-prerelease-ipr-69-ge15ff5700 + @@ -249,11 +356,15 @@ Git: 1.4-prerelease-ipr-69-ge15ff5700 + This event SHALL be generated when a RFID card has been read. + + + diff --git a/src/app/zap-templates/zcl/data-model/chip/energy-evse-mode-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/energy-evse-mode-cluster.xml index b28daf8899636c..7c4ddac9f6f09b 100644 --- a/src/app/zap-templates/zcl/data-model/chip/energy-evse-mode-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/energy-evse-mode-cluster.xml @@ -59,18 +59,26 @@ Git: 1.4-prerelease-ipr-69-ge15ff5700 - SupportedModes - CurrentMode + + SupportedModes + + + + CurrentMode + + This command is used to change device modes. + This command is sent by the device on receipt of the ChangeToMode command. + diff --git a/src/app/zap-templates/zcl/data-model/chip/energy-preference-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/energy-preference-cluster.xml index a5e1ea8e950ae1..cf646ab0197be5 100644 --- a/src/app/zap-templates/zcl/data-model/chip/energy-preference-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/energy-preference-cluster.xml @@ -34,26 +34,47 @@ limitations under the License. - EnergyBalances - + + EnergyBalances + + + + + - + + CurrentEnergyBalance - CurrentEnergyBalance + + + - EnergyPriorities + + EnergyPriorities + + + + - LowPowerModeSensitivities + + LowPowerModeSensitivities + + + + - + CurrentLowPowerModeSensitivity + + + diff --git a/src/app/zap-templates/zcl/data-model/chip/ethernet-network-diagnostics-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/ethernet-network-diagnostics-cluster.xml index f2cf3173c68b29..d84f017f5eea00 100644 --- a/src/app/zap-templates/zcl/data-model/chip/ethernet-network-diagnostics-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/ethernet-network-diagnostics-cluster.xml @@ -37,26 +37,69 @@ limitations under the License. The Ethernet Network Diagnostics Cluster provides a means to acquire standardized diagnostics metrics that MAY be used by a Node to assist a user or Administrative Node in diagnosing potential problems. - + + + + + + + + + + PHYRate - - + + + FullDuplex - - - - PHYRate - FullDuplex - PacketRxCount - PacketTxCount - TxErrCount - CollisionCount - OverrunCount - CarrierDetect - TimeSinceReset + + + PacketRxCount + + + + + + PacketTxCount + + + + + + TxErrCount + + + + + + CollisionCount + + + + + + OverrunCount + + + + + + CarrierDetect + + + + TimeSinceReset + + Reception of this command SHALL reset the attributes: PacketRxCount, PacketTxCount, TxErrCount, CollisionCount, OverrunCount to 0 + + + + + + diff --git a/src/app/zap-templates/zcl/data-model/chip/fixed-label-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/fixed-label-cluster.xml index 96e420f01902de..5e4b1734efb46e 100644 --- a/src/app/zap-templates/zcl/data-model/chip/fixed-label-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/fixed-label-cluster.xml @@ -31,6 +31,9 @@ limitations under the License. FIXED_LABEL_CLUSTER The Fixed Label Cluster provides a feature for the device to tag an endpoint with zero or more read only labels. - LabelList + + LabelList + + diff --git a/src/app/zap-templates/zcl/data-model/chip/flow-measurement-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/flow-measurement-cluster.xml index 3e546e968514ea..b5336b50ad6406 100644 --- a/src/app/zap-templates/zcl/data-model/chip/flow-measurement-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/flow-measurement-cluster.xml @@ -24,10 +24,22 @@ limitations under the License. FLOW_MEASUREMENT_CLUSTER true true - MeasuredValue - MinMeasuredValue - MaxMeasuredValue - Tolerance + + MeasuredValue + + + + MinMeasuredValue + + + + MaxMeasuredValue + + + + Tolerance + + diff --git a/src/app/zap-templates/zcl/data-model/chip/general-commissioning-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/general-commissioning-cluster.xml index 167f7d13e322af..e8877b5c1cc9d9 100644 --- a/src/app/zap-templates/zcl/data-model/chip/general-commissioning-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/general-commissioning-cluster.xml @@ -56,41 +56,86 @@ limitations under the License. Breadcrumb + - BasicCommissioningInfo - RegulatoryConfig - LocationCapability - SupportsConcurrentConnection - + + BasicCommissioningInfo + + + + RegulatoryConfig + + + + LocationCapability + + + + SupportsConcurrentConnection + + + TCAcceptedVersion + + + + + + TCMinRequiredVersion + + + + + + TCAcknowledgements + + + + + + TCAcknowledgementsRequired + + + + + + TCUpdateDeadline + + + + + + Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock + Success/failure response for ArmFailSafe command + Set the regulatory configuration to be used during commissioning @@ -98,30 +143,46 @@ limitations under the License. + Success/failure response for SetRegulatoryConfig command + Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. + Indicates to client whether CommissioningComplete command succeeded + This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. + + + + + + This command is used to convey the result from SetTCAcknowledgements. + + + + + + diff --git a/src/app/zap-templates/zcl/data-model/chip/general-diagnostics-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/general-diagnostics-cluster.xml index 26f0e5708dd280..9383517eb95a5b 100644 --- a/src/app/zap-templates/zcl/data-model/chip/general-diagnostics-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/general-diagnostics-cluster.xml @@ -92,17 +92,44 @@ limitations under the License. - NetworkInterfaces - RebootCount + + NetworkInterfaces + + + + RebootCount + + - UpTime - TotalOperationalHours - BootReason - ActiveHardwareFaults - ActiveRadioFaults - ActiveNetworkFaults - TestEventTriggersEnabled + + UpTime + + + + TotalOperationalHours + + + + BootReason + + + + ActiveHardwareFaults + + + + ActiveRadioFaults + + + + ActiveNetworkFaults + + + + TestEventTriggersEnabled + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -> -> -> -> -> - - - - - - IdleModeDuration - ActiveModeDuration - ActiveModeThreshold - - RegisteredClients - - - - ICDCounter - - - ClientsSupportedPerFabric - UserActiveModeTriggerHint - UserActiveModeTriggerInstruction - OperatingMode - MaximumCheckInBackOff - - - Register a client to the end device - - - - - - - - - - RegisterClient response command - - - - - Unregister a client from an end device - - - - - - - Request the end device to stay in Active Mode for an additional ActiveModeThreshold - - - - - - StayActiveRequest response command - - - + + General + ICD Management + 0x0046 + ICD_MANAGEMENT_CLUSTER + Allows servers to ensure that listed clients are notified when a server is available for communication. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + IdleModeDuration + + + + ActiveModeDuration + + + + ActiveModeThreshold + + + + RegisteredClients + + + + + + + ICDCounter + + + + + + + ClientsSupportedPerFabric + + + + + + UserActiveModeTriggerHint + + + + + + + + + UserActiveModeTriggerInstruction + + + + OperatingMode + + + + + + + + + MaximumCheckInBackOff + + + + + + + Register a client to the end device + + + + + + + + + + + + + RegisterClient response command + + + + + + + + Unregister a client from an end device + + + + + + + + + + Request the end device to stay in Active Mode for an additional ActiveModeThreshold + + + + + + + + + + + + StayActiveRequest response command + + + + + + + + + diff --git a/src/app/zap-templates/zcl/data-model/chip/identify-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/identify-cluster.xml index b64eb7702f1517..27b94701fc3d07 100644 --- a/src/app/zap-templates/zcl/data-model/chip/identify-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/identify-cluster.xml @@ -51,16 +51,23 @@ limitations under the License. true true - - IdentifyTime - IdentifyType - + + + IdentifyTime + + + + IdentifyType + + + Command description for Identify + @@ -69,6 +76,7 @@ limitations under the License. + diff --git a/src/app/zap-templates/zcl/data-model/chip/illuminance-measurement-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/illuminance-measurement-cluster.xml index b744964ca0a9aa..22dcca9d5775fe 100644 --- a/src/app/zap-templates/zcl/data-model/chip/illuminance-measurement-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/illuminance-measurement-cluster.xml @@ -18,19 +18,34 @@ limitations under the License. - Illuminance Measurement - Measurement & Sensing - Attributes and commands for configuring the measurement of illuminance, and reporting illuminance measurements. - 0x0400 - ILLUMINANCE_MEASUREMENT_CLUSTER - true - true - - MeasuredValue - MinMeasuredValue - MaxMeasuredValue - Tolerance - LightSensorType + Illuminance Measurement + Measurement & Sensing + Attributes and commands for configuring the measurement of illuminance, and reporting illuminance measurements. + 0x0400 + ILLUMINANCE_MEASUREMENT_CLUSTER + true + true + + + MeasuredValue + + + + MinMeasuredValue + + + + MaxMeasuredValue + + + + Tolerance + + + + LightSensorType + + diff --git a/src/app/zap-templates/zcl/data-model/chip/keypad-input-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/keypad-input-cluster.xml index b43ace5c0c8383..c21a58ca0f0fbf 100644 --- a/src/app/zap-templates/zcl/data-model/chip/keypad-input-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/keypad-input-cluster.xml @@ -40,11 +40,13 @@ limitations under the License. Upon receipt, this SHALL process a keycode as input to the media device. + This command SHALL be generated in response to a SendKey Request command. + diff --git a/src/app/zap-templates/zcl/data-model/chip/laundry-dryer-controls-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/laundry-dryer-controls-cluster.xml index f126d8836f720c..171eb5cb91ee44 100644 --- a/src/app/zap-templates/zcl/data-model/chip/laundry-dryer-controls-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/laundry-dryer-controls-cluster.xml @@ -36,9 +36,15 @@ limitations under the License. This cluster provides a way to access options associated with the operation of a laundry dryer device type. - - - SupportedDrynessLevels - SelectedDrynessLevel - + + + + SupportedDrynessLevels + + + + SelectedDrynessLevel + + + diff --git a/src/app/zap-templates/zcl/data-model/chip/laundry-washer-mode-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/laundry-washer-mode-cluster.xml index b8afd87d76665c..e3778d2d938b60 100644 --- a/src/app/zap-templates/zcl/data-model/chip/laundry-washer-mode-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/laundry-washer-mode-cluster.xml @@ -58,11 +58,17 @@ limitations under the License. - SupportedModes - CurrentMode + + SupportedModes + + + + CurrentMode + + StartUpMode OnMode - + @@ -70,6 +76,7 @@ limitations under the License. On receipt of this command the device SHALL respond with a ChangeToModeResponse command. + @@ -78,6 +85,7 @@ limitations under the License. + diff --git a/src/app/zap-templates/zcl/data-model/chip/level-control-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/level-control-cluster.xml index 4d0e67ddbd1b47..8d2326e01fb278 100644 --- a/src/app/zap-templates/zcl/data-model/chip/level-control-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/level-control-cluster.xml @@ -61,25 +61,77 @@ limitations under the License. - - CurrentLevel - RemainingTime - MinLevel - MaxLevel - CurrentFrequency - MinFrequency - MaxFrequency - - OnOffTransitionTime - OnLevel - OnTransitionTime - OffTransitionTime - DefaultMoveRate - Options - + + CurrentLevel + + + + RemainingTime + + + + + + MinLevel + + + + + + + + MaxLevel + + + + CurrentFrequency + + + + + + MinFrequency + + + + + + MaxFrequency + + + + + + OnOffTransitionTime + + + + OnLevel + + + + OnTransitionTime + + + + OffTransitionTime + + + + DefaultMoveRate + + + + Options + + + StartUpCurrentLevel + + + @@ -90,6 +142,7 @@ limitations under the License. + @@ -100,6 +153,7 @@ limitations under the License. + @@ -111,6 +165,7 @@ limitations under the License. + @@ -119,6 +174,7 @@ limitations under the License. + @@ -129,6 +185,7 @@ limitations under the License. + @@ -139,6 +196,7 @@ limitations under the License. + @@ -150,6 +208,7 @@ limitations under the License. + @@ -158,6 +217,7 @@ limitations under the License. + @@ -166,6 +226,9 @@ limitations under the License. approximation if the exact provided one is not possible. + + + diff --git a/src/app/zap-templates/zcl/data-model/chip/localization-configuration-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/localization-configuration-cluster.xml index 9bdededd0fcd6e..34e81bbb445d0e 100644 --- a/src/app/zap-templates/zcl/data-model/chip/localization-configuration-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/localization-configuration-cluster.xml @@ -31,7 +31,11 @@ limitations under the License. ActiveLocale + + + + SupportedLocales + - SupportedLocales diff --git a/src/app/zap-templates/zcl/data-model/chip/low-power-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/low-power-cluster.xml index c1cc5b38ede202..4b9ea09104994e 100644 --- a/src/app/zap-templates/zcl/data-model/chip/low-power-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/low-power-cluster.xml @@ -26,6 +26,7 @@ limitations under the License. This cluster provides an interface for managing low power mode on a device. This command shall put the device into low power mode. + diff --git a/src/app/zap-templates/zcl/data-model/chip/media-input-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/media-input-cluster.xml index 597b285cc1b5dd..57fdda3bc7cb7f 100644 --- a/src/app/zap-templates/zcl/data-model/chip/media-input-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/media-input-cluster.xml @@ -32,20 +32,29 @@ limitations under the License. - InputList - CurrentInput + + InputList + + + + CurrentInput + + Upon receipt, this SHALL change the input on the media device to the input at a specific index in the Input List. + Upon receipt, this SHALL display the active status of the input list on screen. + Upon receipt, this SHALL hide the input list from the screen. + @@ -53,6 +62,9 @@ limitations under the License. + + + diff --git a/src/app/zap-templates/zcl/data-model/chip/media-playback-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/media-playback-cluster.xml index a77b8fa4befb4c..1c4f2e37c8e42b 100644 --- a/src/app/zap-templates/zcl/data-model/chip/media-playback-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/media-playback-cluster.xml @@ -46,87 +46,167 @@ limitations under the License. - CurrentState - StartTime - Duration - SampledPosition - PlaybackSpeed - SeekRangeEnd - SeekRangeStart - ActiveAudioTrack - AvailableAudioTracks - ActiveTextTrack - AvailableTextTracks + + CurrentState + + + + StartTime + + + + + + Duration + + + + + + SampledPosition + + + + + + PlaybackSpeed + + + + + + SeekRangeEnd + + + + + + SeekRangeStart + + + + + + ActiveAudioTrack + + + + + + AvailableAudioTracks + + + + + + ActiveTextTrack + + + + + + AvailableTextTracks + + + + Upon receipt, this SHALL play media. + Upon receipt, this SHALL pause media. + Upon receipt, this SHALL stop media. User experience is context-specific. This will often navigate the user back to the location where media was originally launched. + Upon receipt, this SHALL Start Over with the current media playback item. + Upon receipt, this SHALL cause the handler to be invoked for "Previous". User experience is context-specific. This will often Go back to the previous media playback item. + Upon receipt, this SHALL cause the handler to be invoked for "Next". User experience is context-specific. This will often Go forward to the next media playback item. + Upon receipt, this SHALL Rewind through media. Different Rewind speeds can be used on the TV based upon the number of sequential calls to this function. This is to avoid needing to define every speed now (multiple fast, slow motion, etc). + + + Upon receipt, this SHALL Advance through media. Different FF speeds can be used on the TV based upon the number of sequential calls to this function. This is to avoid needing to define every speed now (multiple fast, slow motion, etc). + + + Upon receipt, this SHALL Skip forward in the media by the given number of seconds, using the data as follows: + Upon receipt, this SHALL Skip backward in the media by the given number of seconds, using the data as follows: + Upon receipt, this SHALL Skip backward in the media by the given number of seconds, using the data as follows: + + + This command SHALL be generated in response to various Playback Request commands. + Upon receipt, the server SHALL set the active Audio Track to the one identified by the TrackID in the Track catalog for the streaming media. If the TrackID does not exist in the Track catalog, OR does not correspond to the streaming media OR no media is being streamed at the time of receipt of this command, the server will return an error status of INVALID_ARGUMENT. + + + Upon receipt, the server SHALL set the active Text Track to the one identified by the TrackID in the Track catalog for the streaming media. If the TrackID does not exist in the Track catalog, OR does not correspond to the streaming media OR no media is being streamed at the time of receipt of this command, the server SHALL return an error status of INVALID_ARGUMENT. + + + If a Text Track is active (i.e. being displayed), upon receipt of this command, the server SHALL stop displaying it. + + + @@ -140,6 +220,7 @@ limitations under the License. + diff --git a/src/app/zap-templates/zcl/data-model/chip/messages-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/messages-cluster.xml index 741ba801f5c092..901e63703eee1f 100644 --- a/src/app/zap-templates/zcl/data-model/chip/messages-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/messages-cluster.xml @@ -91,8 +91,14 @@ limitations under the License. - Messages - ActiveMessageIDs + + Messages + + + + ActiveMessageIDs + + Command for requesting messages be presented @@ -104,20 +110,24 @@ limitations under the License. + Command for cancelling message present requests + This event SHALL be generated when the message is confirmed by the user, or when the expiration date of the message is reached. + This event SHALL be generated when the message is presented to the user. + This event SHALL be generated when the message is confirmed by the user, or when the expiration date of the message is reached. @@ -125,6 +135,7 @@ limitations under the License. + - \ No newline at end of file + diff --git a/src/app/zap-templates/zcl/data-model/chip/microwave-oven-control-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/microwave-oven-control-cluster.xml index 954bd898b6aa00..fd44e47c2ca767 100644 --- a/src/app/zap-templates/zcl/data-model/chip/microwave-oven-control-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/microwave-oven-control-cluster.xml @@ -41,27 +41,74 @@ limitations under the License. - CookTime - MaxCookTime - PowerSetting - MinPower - MaxPower - PowerStep - SupportedWatts - SelectedWattIndex - WattRating - + + CookTime + + + + MaxCookTime + + + + PowerSetting + + + + + + MinPower + + + + + + MaxPower + + + + + + PowerStep + + + + + + SupportedWatts + + + + + + + + + SelectedWattIndex + + + + + + + + + WattRating + + + - Set Cooking Parameters + Set Cooking Parameters + - Add More Cooking Time - + Add More Cooking Time + + diff --git a/src/app/zap-templates/zcl/data-model/chip/microwave-oven-mode-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/microwave-oven-mode-cluster.xml index 856fde36da15ee..393354fb4ca461 100644 --- a/src/app/zap-templates/zcl/data-model/chip/microwave-oven-mode-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/microwave-oven-mode-cluster.xml @@ -55,7 +55,13 @@ limitations under the License. - SupportedModes - CurrentMode + + SupportedModes + + + + CurrentMode + + diff --git a/src/app/zap-templates/zcl/data-model/chip/mode-select-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/mode-select-cluster.xml index 443acb1c955c36..80e0267155496b 100644 --- a/src/app/zap-templates/zcl/data-model/chip/mode-select-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/mode-select-cluster.xml @@ -48,19 +48,39 @@ limitations under the License. Attributes and commands for selecting a mode from a list of supported options. - Description - StandardNamespace - SupportedModes - CurrentMode - StartUpMode - OnMode - + + Description + + + + StandardNamespace + + + + SupportedModes + + + + CurrentMode + + + + StartUpMode + + + + OnMode + + + + On receipt of this command, if the NewMode field matches the Mode field in an entry of the SupportedModes list, the server SHALL set the CurrentMode attribute to the NewMode value, otherwise, the server SHALL respond with an INVALID_COMMAND status response. + diff --git a/src/app/zap-templates/zcl/data-model/chip/network-commissioning-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/network-commissioning-cluster.xml index 964923be4f2dfa..02fcb28ee2e14b 100644 --- a/src/app/zap-templates/zcl/data-model/chip/network-commissioning-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/network-commissioning-cluster.xml @@ -107,120 +107,207 @@ limitations under the License. - - + + + + - + MaxNetworks + - + Networks + + + + ScanMaxTimeSeconds + + + + + + - ScanMaxTimeSeconds - ConnectMaxTimeSeconds - + + ConnectMaxTimeSeconds + + + + + + + + InterfaceEnabled + - + LastNetworkingStatus + - + LastNetworkID + - + LastConnectErrorValue + - + SupportedWiFiBands + + + - + SupportedThreadFeatures + + + - + ThreadVersion + + + - - Detemine the set of networks the device sees as available. - - - - - - Relay the set of networks the device sees as available back to the client. - - - - - - - Add or update the credentials for a given Wi-Fi network. - - - - - - - - - - Add or update the credentials for a given Thread network. - - - - - - Remove the definition of a given network (including its credentials). - - - - - - Response command for various commands that add/remove/modify network credentials. - - - - - - - - Connect to the specified network, using previously-defined credentials. - - - - - - Command that indicates whether we have succcessfully connected to a network. - - - - - - Modify the order in which networks will be presented in the Networks attribute. - - - - - - - Retrieve details about and optionally proof of possession of a network client identity. - - - - - - Command that contains details about a network client identity and optionally a proof of possession. - - - - + + Detemine the set of networks the device sees as available. + + + + + + + + + + + + Relay the set of networks the device sees as available back to the client. + + + + + + + + + + + + + Add or update the credentials for a given Wi-Fi network. + + + + + + + + + + + + + Add or update the credentials for a given Thread network. + + + + + + + + + Remove the definition of a given network (including its credentials). + + + + + + + + + + + + Response command for various commands that add/remove/modify network credentials. + + + + + + + + + + + + + + Connect to the specified network, using previously-defined credentials. + + + + + + + + + + + + Command that indicates whether we have succcessfully connected to a network. + + + + + + + + + + + + Modify the order in which networks will be presented in the Networks attribute. + + + + + + + + + + + + + Retrieve details about and optionally proof of possession of a network client identity. + + + + + + + + + Command that contains details about a network client identity and optionally a proof of possession. + + + + + + + diff --git a/src/app/zap-templates/zcl/data-model/chip/occupancy-sensing-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/occupancy-sensing-cluster.xml index 0141a7542f4d78..90f1a6a9f497a7 100644 --- a/src/app/zap-templates/zcl/data-model/chip/occupancy-sensing-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/occupancy-sensing-cluster.xml @@ -83,74 +83,288 @@ limitations under the License. - Occupancy - OccupancySensorType - OccupancySensorTypeBitmap + + Occupancy + + + + OccupancySensorType + + + + + + + OccupancySensorTypeBitmap + + + + + - HoldTime - + HoldTime + + - HoldTimeLimits - + + HoldTimeLimits + + + + + PIROccupiedToUnoccupiedDelay + + + + + + + + + + + + + + + + + + + + + + PIRUnoccupiedToOccupiedDelay + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + PIRUnoccupiedToOccupiedThreshold + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + UltrasonicOccupiedToUnoccupiedDelay + + + + + + + + + UltrasonicUnoccupiedToOccupiedDelay + + + + + + + + + + + + + + + + UltrasonicUnoccupiedToOccupiedThreshold + + + + + + + + + + + + + + + + PhysicalContactOccupiedToUnoccupiedDelay + + + + + + + + + PhysicalContactUnoccupiedToOccupiedDelay + + + + + + + + + + + + + + + + PhysicalContactUnoccupiedToOccupiedThreshold + + + + + + + + + + + + + + + + If this event is supported, it SHALL be generated when the Occupancy attribute changes. + diff --git a/src/app/zap-templates/zcl/data-model/chip/onoff-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/onoff-cluster.xml index 04dcfed83766e8..c1e87fd1ceb37d 100644 --- a/src/app/zap-templates/zcl/data-model/chip/onoff-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/onoff-cluster.xml @@ -81,37 +81,75 @@ limitations under the License. - - OnOff - GlobalSceneControl - OnTime - OffWaitTime - + + + OnOff + + + + GlobalSceneControl + + + + + + OnTime + + + + + + OffWaitTime + + + + + StartUpOnOff + + + On receipt of this command, a device SHALL enter its ‘Off’ state. This state is device dependent, but it is recommended that it is used for power off or similar functions. On receipt of the Off command, the OnTime attribute SHALL be set to 0. + On receipt of this command, a device SHALL enter its ‘On’ state. This state is device dependent, but it is recommended that it is used for power on or similar functions. On receipt of the On command, if the value of the OnTime attribute is equal to 0, the device SHALL set the OffWaitTime attribute to 0. + + + + + On receipt of this command, if a device is in its ‘Off’ state it SHALL enter its ‘On’ state. Otherwise, if it is in its ‘On’ state it SHALL enter its ‘Off’ state. On receipt of the Toggle command, if the value of the OnOff attribute is equal to FALSE and if the value of the OnTime attribute is equal to 0, the device SHALL set the OffWaitTime attribute to 0. If the value of the OnOff attribute is equal to TRUE, the OnTime attribute SHALL be set to 0. + + + + + The OffWithEffect command allows devices to be turned off using enhanced ways of fading. + + + The OnWithRecallGlobalScene command allows the recall of the settings when the device was turned off. + + + @@ -119,6 +157,9 @@ limitations under the License. + + + diff --git a/src/app/zap-templates/zcl/data-model/chip/operational-credentials-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/operational-credentials-cluster.xml index 5b06c93e0ab7fd..8be3ce077a2732 100644 --- a/src/app/zap-templates/zcl/data-model/chip/operational-credentials-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/operational-credentials-cluster.xml @@ -62,34 +62,54 @@ limitations under the License. NOCs + + + + Fabrics + + + + SupportedFabrics + + + + CommissionedFabrics + + + + TrustedRootCertificates + + + + CurrentFabricIndex + - Fabrics - SupportedFabrics - CommissionedFabrics - TrustedRootCertificates - CurrentFabricIndex Sender is requesting attestation information from the receiver. + An attestation information confirmation from the server. + Sender is requesting a device attestation certificate from the receiver. + A device attestation certificate (DAC) or product attestation intermediate (PAI) certificate from the server. + @@ -97,6 +117,7 @@ limitations under the License. + @@ -104,6 +125,7 @@ limitations under the License. A certificate signing request (CSR) from the server. + @@ -114,6 +136,7 @@ limitations under the License. + @@ -121,31 +144,36 @@ limitations under the License. + - + Response to AddNOC or UpdateNOC commands. + This command SHALL be used by an Administrative Node to set the user-visible Label field for a given Fabric, as reflected by entries in the Fabrics attribute. + This command is used by Administrative Nodes to remove a given fabric index and delete all associated fabric-scoped data. + This command SHALL add a Trusted Root CA Certificate, provided as its CHIP Certificate representation. + diff --git a/src/app/zap-templates/zcl/data-model/chip/operational-state-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/operational-state-cluster.xml index 53b9c73cad6b3e..9bc60ae2f73fef 100644 --- a/src/app/zap-templates/zcl/data-model/chip/operational-state-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/operational-state-cluster.xml @@ -58,47 +58,94 @@ limitations under the License. true true This cluster supports remotely monitoring and, where supported, changing the operational state of any device where a state machine is a part of the operation. - - - - PhaseList - CurrentPhase - CountdownTime - OperationalStateList - OperationalState - OperationalError - + + + + + PhaseList + + + + CurrentPhase + + + + CountdownTime + + + + OperationalStateList + + + + OperationalState + + + + OperationalError + + + Upon receipt, the device SHALL pause its operation if it is possible based on the current function of the server. + + + + + + Upon receipt, the device SHALL stop its operation if it is at a position where it is safe to do so and/or permitted. + + + + + + Upon receipt, the device SHALL start its operation if it is safe to do so and the device is in an operational state from which it can be started. + Upon receipt, the device SHALL resume its operation from the point it was at when it received the Pause command, or from the point when it was paused by means outside of this cluster (for example by manual button press). + + + + + + This command SHALL be generated in response to any of the Start, Stop, Pause, or Resume commands. + + + + + + + + OperationalError - + + OperationCompletion - + + diff --git a/src/app/zap-templates/zcl/data-model/chip/operational-state-oven-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/operational-state-oven-cluster.xml index fd52204b02fe85..800506d73c6079 100644 --- a/src/app/zap-templates/zcl/data-model/chip/operational-state-oven-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/operational-state-oven-cluster.xml @@ -53,13 +53,31 @@ limitations under the License. This cluster supports remotely monitoring and, where supported, changing the operational state of an Oven. - - PhaseList - CurrentPhase - CountdownTime - OperationalStateList - OperationalState - OperationalError + + + PhaseList + + + + CurrentPhase + + + + CountdownTime + + + + OperationalStateList + + + + OperationalState + + + + OperationalError + + Upon receipt, the device SHALL pause its operation if it is possible based on the current function of the server. @@ -67,10 +85,17 @@ limitations under the License. Upon receipt, the device SHALL stop its operation if it is at a position where it is safe to do so and/or permitted. + + + + + + Upon receipt, the device SHALL start its operation if it is safe to do so and the device is in an operational state from which it can be started. + @@ -80,18 +105,28 @@ limitations under the License. This command SHALL be generated in response to any of the Start, Stop, Pause, or Resume commands. + + + + + + + + OperationalError - + + OperationCompletion - + + diff --git a/src/app/zap-templates/zcl/data-model/chip/operational-state-rvc-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/operational-state-rvc-cluster.xml index e3b054fe3fedce..3c762879309e5c 100644 --- a/src/app/zap-templates/zcl/data-model/chip/operational-state-rvc-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/operational-state-rvc-cluster.xml @@ -64,24 +64,48 @@ limitations under the License. true true This cluster supports remotely monitoring and, where supported, changing the operational state of a Robotic Vacuum. - - - - PhaseList - CurrentPhase - CountdownTime - OperationalStateList - - - OperationalState - OperationalError + + OperationalState + + + + OperationalError + + Upon receipt, the device SHALL pause its operation if it is possible based on the current function of the server. + + + + + + @@ -90,27 +114,47 @@ both values from this cluster and from the base cluster. Upon receipt, the device SHALL resume its operation from the point it was at when it received the Pause command, or from the point when it was paused by means outside of this cluster (for example by manual button press). + + + + + + This command SHALL be generated in response to any of the Start, Stop, Pause, or Resume commands. + + + + + + + + On receipt of this command, the device SHALL start seeking the charging dock, if possible in the current state of the device. + + + + OperationalError - + + - + OperationCompletion - - + + + diff --git a/src/app/zap-templates/zcl/data-model/chip/oven-mode-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/oven-mode-cluster.xml index 0faa1b037eb318..8a54783445013f 100644 --- a/src/app/zap-templates/zcl/data-model/chip/oven-mode-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/oven-mode-cluster.xml @@ -62,11 +62,17 @@ limitations under the License. - SupportedModes - CurrentMode + + SupportedModes + + + + CurrentMode + + StartUpMode OnMode - + @@ -74,6 +80,7 @@ limitations under the License. On receipt of this command the device SHALL respond with a ChangeToModeResponse command. + @@ -82,6 +89,7 @@ limitations under the License. + diff --git a/src/app/zap-templates/zcl/data-model/chip/power-source-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/power-source-cluster.xml index 5701dc6ec61e65..8bbfe444227f1d 100644 --- a/src/app/zap-templates/zcl/data-model/chip/power-source-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/power-source-cluster.xml @@ -43,58 +43,222 @@ limitations under the License. - - Status - Order - Description - - WiredAssessedInputVoltage - WiredAssessedInputFrequency - WiredCurrentType - WiredAssessedCurrent - WiredNominalVoltage - WiredMaximumCurrent - WiredPresent - ActiveWiredFaults - - BatVoltage - BatPercentRemaining - BatTimeRemaining - BatChargeLevel - BatReplacementNeeded - BatReplaceability - BatPresent - ActiveBatFaults - BatReplacementDescription - BatCommonDesignation - BatANSIDesignation - BatIECDesignation - BatApprovedChemistry - BatCapacity - BatQuantity - BatChargeState - BatTimeToFullCharge - BatFunctionalWhileCharging - BatChargingCurrent - ActiveBatChargeFaults - EndpointList + + Status + + + + Order + + + + Description + + + + + WiredAssessedInputVoltage + + + + + + WiredAssessedInputFrequency + + + + + + WiredCurrentType + + + + + + WiredAssessedCurrent + + + + + + WiredNominalVoltage + + + + + + WiredMaximumCurrent + + + + + + WiredPresent + + + + + + ActiveWiredFaults + + + + + + + BatVoltage + + + + + + BatPercentRemaining + + + + + + BatTimeRemaining + + + + + + BatChargeLevel + + + + + + BatReplacementNeeded + + + + + + BatReplaceability + + + + + + BatPresent + + + + + + ActiveBatFaults + + + + + + BatReplacementDescription + + + + + + BatCommonDesignation + + + + + + BatANSIDesignation + + + + + + BatIECDesignation + + + + + + BatApprovedChemistry + + + + + + BatCapacity + + + + + + + + + BatQuantity + + + + + + BatChargeState + + + + + + BatTimeToFullCharge + + + + + + BatFunctionalWhileCharging + + + + + + BatChargingCurrent + + + + + + ActiveBatChargeFaults + + + + + + EndpointList + + + The WiredFaultChange Event SHALL indicate a change in the set of wired faults currently detected by the Node on this wired power source. + + + The BatFaultChange Event SHALL indicate a change in the set of battery faults currently detected by the Node on this battery power source. + + + The BatChargeFaultChange Event SHALL indicate a change in the set of charge faults currently detected by the Node on this battery power source. + + + diff --git a/src/app/zap-templates/zcl/data-model/chip/power-source-configuration-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/power-source-configuration-cluster.xml index 04a7cdb121c775..ba97841d3492e0 100644 --- a/src/app/zap-templates/zcl/data-model/chip/power-source-configuration-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/power-source-configuration-cluster.xml @@ -26,6 +26,9 @@ limitations under the License. true true - Sources + + Sources + + diff --git a/src/app/zap-templates/zcl/data-model/chip/power-topology-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/power-topology-cluster.xml index 3bca0bd43ee8af..c686115edcb8cb 100644 --- a/src/app/zap-templates/zcl/data-model/chip/power-topology-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/power-topology-cluster.xml @@ -44,7 +44,17 @@ limitations under the License. - AvailableEndpoints - ActiveEndpoints + + AvailableEndpoints + + + + + + ActiveEndpoints + + + + diff --git a/src/app/zap-templates/zcl/data-model/chip/pressure-measurement-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/pressure-measurement-cluster.xml index f9487af7f3a9e2..04100e82379f2d 100644 --- a/src/app/zap-templates/zcl/data-model/chip/pressure-measurement-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/pressure-measurement-cluster.xml @@ -31,16 +31,53 @@ limitations under the License. - - MeasuredValue - MinMeasuredValue - MaxMeasuredValue - Tolerance - ScaledValue - MinScaledValue - MaxScaledValue - ScaledTolerance - Scale + + + MeasuredValue + + + + MinMeasuredValue + + + + MaxMeasuredValue + + + + Tolerance + + + + ScaledValue + + + + + + MinScaledValue + + + + + + MaxScaledValue + + + + + + ScaledTolerance + + + + + + Scale + + + + diff --git a/src/app/zap-templates/zcl/data-model/chip/pump-configuration-and-control-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/pump-configuration-and-control-cluster.xml index 74416092e7c7f8..b23ad516515b11 100644 --- a/src/app/zap-templates/zcl/data-model/chip/pump-configuration-and-control-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/pump-configuration-and-control-cluster.xml @@ -49,97 +49,245 @@ limitations under the License. - - MaxPressure - MaxSpeed - MaxFlow - MinConstPressure - MaxConstPressure - MinCompPressure - MaxCompPressure - MinConstSpeed - MaxConstSpeed - MinConstFlow - MaxConstFlow - MinConstTemp - MaxConstTemp - PumpStatus - EffectiveOperationMode - EffectiveControlMode - Capacity - Speed + + + MaxPressure + + + + MaxSpeed + + + + MaxFlow + + + + MinConstPressure + + + + + + + + + + + MaxConstPressure + + + + + + + + + + + MinCompPressure + + + + + + + + + + + MaxCompPressure + + + + + + + + + + + MinConstSpeed + + + + + + + + + + + MaxConstSpeed + + + + + + + + + + + MinConstFlow + + + + + + + + + + + MaxConstFlow + + + + + + + + + + + MinConstTemp + + + + + + + + + + + MaxConstTemp + + + + + + + + + + + PumpStatus + + + + EffectiveOperationMode + + + + EffectiveControlMode + + + + Capacity + + + + Speed + + LifetimeRunningHours + + + + Power + - Power LifetimeEnergyConsumed + OperationMode + ControlMode + SupplyVoltageLow + SupplyVoltageHigh + PowerMissingPhase + SystemPressureLow + SystemPressureHigh + DryRunning + MotorTemperatureHigh + PumpMotorFatalFailure + ElectronicTemperatureHigh + PumpBlocked + SensorFailure + ElectronicNonFatalFailure + ElectronicFatalFailure + GeneralFault + Leakage + AirDetection + TurbineOperation + diff --git a/src/app/zap-templates/zcl/data-model/chip/refrigerator-alarm.xml b/src/app/zap-templates/zcl/data-model/chip/refrigerator-alarm.xml index 58fa70163f65ea..deeb16b4dae3d7 100644 --- a/src/app/zap-templates/zcl/data-model/chip/refrigerator-alarm.xml +++ b/src/app/zap-templates/zcl/data-model/chip/refrigerator-alarm.xml @@ -28,17 +28,27 @@ limitations under the License. REFRIGERATOR_ALARM_CLUSTER true true - - Mask - State - Supported + + + Mask + + + + State + + + + Supported + + - Notify - - - - + Notify + + + + + diff --git a/src/app/zap-templates/zcl/data-model/chip/refrigerator-and-temperature-controlled-cabinet-mode-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/refrigerator-and-temperature-controlled-cabinet-mode-cluster.xml index e29080ce4a43cb..a4fe78bc225d65 100644 --- a/src/app/zap-templates/zcl/data-model/chip/refrigerator-and-temperature-controlled-cabinet-mode-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/refrigerator-and-temperature-controlled-cabinet-mode-cluster.xml @@ -56,11 +56,17 @@ limitations under the License. - SupportedModes - CurrentMode + + SupportedModes + + + + CurrentMode + + StartUpMode OnMode - + @@ -68,6 +74,7 @@ limitations under the License. On receipt of this command the device SHALL respond with a ChangeToModeResponse command. + @@ -76,6 +83,7 @@ limitations under the License. + diff --git a/src/app/zap-templates/zcl/data-model/chip/relative-humidity-measurement-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/relative-humidity-measurement-cluster.xml index e309b75dcc46bd..7f8157572a4270 100644 --- a/src/app/zap-templates/zcl/data-model/chip/relative-humidity-measurement-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/relative-humidity-measurement-cluster.xml @@ -25,9 +25,21 @@ limitations under the License. true true - MeasuredValue - MinMeasuredValue - MaxMeasuredValue - Tolerance + + MeasuredValue + + + + MinMeasuredValue + + + + MaxMeasuredValue + + + + Tolerance + + diff --git a/src/app/zap-templates/zcl/data-model/chip/resource-monitoring-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/resource-monitoring-cluster.xml index 66de9ee66cbebd..25e586226f0d82 100644 --- a/src/app/zap-templates/zcl/data-model/chip/resource-monitoring-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/resource-monitoring-cluster.xml @@ -38,16 +38,41 @@ limitations under the License. - Condition - DegradationDirection - ChangeIndication - InPlaceIndicator - LastChangedTime - ReplacementProductList - + + Condition + + + + + + DegradationDirection + + + + + + ChangeIndication + + + + InPlaceIndicator + + + + LastChangedTime + + + + ReplacementProductList + + + + + Reset the condition of the replaceable to the non degraded state + @@ -73,16 +98,41 @@ limitations under the License. - Condition - DegradationDirection - ChangeIndication - InPlaceIndicator - LastChangedTime - ReplacementProductList - + + Condition + + + + + + DegradationDirection + + + + + + ChangeIndication + + + + InPlaceIndicator + + + + LastChangedTime + + + + ReplacementProductList + + + + + Reset the condition of the replaceable to the non degraded state + diff --git a/src/app/zap-templates/zcl/data-model/chip/rvc-clean-mode-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/rvc-clean-mode-cluster.xml index 65c2f17a3e8e75..a1fe4809ee1e17 100644 --- a/src/app/zap-templates/zcl/data-model/chip/rvc-clean-mode-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/rvc-clean-mode-cluster.xml @@ -67,8 +67,14 @@ limitations under the License. - SupportedModes - CurrentMode + + SupportedModes + + + + CurrentMode + + @@ -78,6 +84,7 @@ limitations under the License. On receipt of this command the device SHALL respond with a ChangeToModeResponse command. + @@ -86,6 +93,7 @@ limitations under the License. + diff --git a/src/app/zap-templates/zcl/data-model/chip/rvc-run-mode-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/rvc-run-mode-cluster.xml index ce835576396bb8..6cd765db7fab84 100644 --- a/src/app/zap-templates/zcl/data-model/chip/rvc-run-mode-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/rvc-run-mode-cluster.xml @@ -73,8 +73,14 @@ limitations under the License. - SupportedModes - CurrentMode + + SupportedModes + + + + CurrentMode + + @@ -84,6 +90,7 @@ limitations under the License. On receipt of this command the device SHALL respond with a ChangeToModeResponse command. + @@ -92,6 +99,7 @@ limitations under the License. + diff --git a/src/app/zap-templates/zcl/data-model/chip/scene.xml b/src/app/zap-templates/zcl/data-model/chip/scene.xml index b6315bdc1287c1..dcc929fa47e872 100644 --- a/src/app/zap-templates/zcl/data-model/chip/scene.xml +++ b/src/app/zap-templates/zcl/data-model/chip/scene.xml @@ -80,10 +80,19 @@ limitations under the License. - - LastConfiguredBy - SceneTableSize - FabricSceneInfo + + LastConfiguredBy + + + + SceneTableSize + + + + FabricSceneInfo + + + Add a scene to the scene table. Extension field sets are supported, and are inputed as '{"ClusterID": VALUE, "AttributeValueList":[{"AttributeID": VALUE, "Value*": VALUE}]}' @@ -94,6 +103,7 @@ limitations under the License. + @@ -102,6 +112,7 @@ limitations under the License. + @@ -111,6 +122,7 @@ limitations under the License. + @@ -119,6 +131,7 @@ limitations under the License. + @@ -128,6 +141,7 @@ limitations under the License. + @@ -137,6 +151,7 @@ limitations under the License. + @@ -144,6 +159,7 @@ limitations under the License. Get an unused scene identifier when no commissioning tool is in the network, or for a commissioning tool to get the used scene identifiers within a certain group + @@ -155,6 +171,7 @@ limitations under the License. + @@ -164,6 +181,7 @@ limitations under the License. + @@ -176,6 +194,7 @@ limitations under the License. + @@ -185,6 +204,7 @@ limitations under the License. + @@ -193,6 +213,7 @@ limitations under the License. + @@ -202,6 +223,7 @@ limitations under the License. + @@ -212,6 +234,7 @@ limitations under the License. + @@ -221,6 +244,9 @@ limitations under the License. + + + diff --git a/src/app/zap-templates/zcl/data-model/chip/service-area-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/service-area-cluster.xml index 8c2ba832c85604..c442136d46aa0a 100644 --- a/src/app/zap-templates/zcl/data-model/chip/service-area-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/service-area-cluster.xml @@ -96,19 +96,43 @@ limitations under the License. - SupportedAreas - SupportedMaps - SelectedAreas - CurrentArea - EstimatedEndTime - Progress - + + SupportedAreas + + + + SupportedMaps + + + + + + SelectedAreas + + + + CurrentArea + + + EstimatedEndTime + + + + + + Progress + + + + + Command used to select a set of device areas, where the device is to operate. + @@ -117,6 +141,7 @@ limitations under the License. + @@ -132,6 +157,9 @@ limitations under the License. + + + diff --git a/src/app/zap-templates/zcl/data-model/chip/smoke-co-alarm-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/smoke-co-alarm-cluster.xml index 31ae0bba9e7d99..a0543e04373dd5 100644 --- a/src/app/zap-templates/zcl/data-model/chip/smoke-co-alarm-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/smoke-co-alarm-cluster.xml @@ -46,66 +46,131 @@ limitations under the License. - ExpressedState - SmokeState - COState - BatteryAlert - DeviceMuted - TestInProgress - HardwareFaultAlert - EndOfServiceAlert - InterconnectSmokeAlarm - InterconnectCOAlarm - ContaminationState + + ExpressedState + + + + SmokeState + + + + + + COState + + + + + + BatteryAlert + + + + DeviceMuted + + + + TestInProgress + + + + HardwareFaultAlert + + + + EndOfServiceAlert + + + + InterconnectSmokeAlarm + + + + InterconnectCOAlarm + + + + ContaminationState + + + + SmokeSensitivityLevel + + + - ExpiryDate - + + ExpiryDate + + + This command SHALL initiate a device self-test. + This event SHALL be generated when SmokeState attribute changes to either Warning or Critical state. + + + This event SHALL be generated when COState attribute changes to either Warning or Critical state. + + + This event SHALL be generated when BatteryAlert attribute changes to either Warning or Critical state. + This event SHALL be generated when the device detects a hardware fault that leads to setting HardwareFaultAlert to True. + This event SHALL be generated when the EndOfServiceAlert is set to Expired. + This event SHALL be generated when the SelfTest completes, and the attribute TestInProgress changes to False. + This event SHALL be generated when the DeviceMuted attribute changes to Muted. + This event SHALL be generated when DeviceMuted attribute changes to NotMuted. + This event SHALL be generated when the device hosting the server receives a smoke alarm from an interconnected sensor. + + + This event SHALL be generated when the device hosting the server receives a smoke alarm from an interconnected sensor. + + + This event SHALL be generated when ExpressedState attribute returns to Normal state. + diff --git a/src/app/zap-templates/zcl/data-model/chip/software-diagnostics-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/software-diagnostics-cluster.xml index 3ac2ba42e8e22e..d0973998fa98d6 100644 --- a/src/app/zap-templates/zcl/data-model/chip/software-diagnostics-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/software-diagnostics-cluster.xml @@ -37,20 +37,38 @@ limitations under the License. - ThreadMetrics - CurrentHeapFree - CurrentHeapUsed - CurrentHeapHighWatermark + + ThreadMetrics + + + + CurrentHeapFree + + + + CurrentHeapUsed + + + + CurrentHeapHighWatermark + + + + Reception of this command SHALL reset the values: The StackFreeMinimum field of the ThreadMetrics attribute, CurrentHeapHighWaterMark attribute. + + + Indicate the last software fault that has taken place on the Node. - + + diff --git a/src/app/zap-templates/zcl/data-model/chip/switch-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/switch-cluster.xml index 176163fae7fce6..90f61cdedcfbc8 100644 --- a/src/app/zap-templates/zcl/data-model/chip/switch-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/switch-cluster.xml @@ -78,38 +78,75 @@ Interactions with the switch device are exposed as attributes (for the latching - NumberOfPositions - CurrentPosition - MultiPressMax + + NumberOfPositions + + + + CurrentPosition + + + + MultiPressMax + + + + SwitchLatched + + + InitialPress + + + LongPress + + + ShortRelease + + + LongRelease + + + MultiPressOngoing + + + + + + + + MultiPressComplete - + + + + diff --git a/src/app/zap-templates/zcl/data-model/chip/target-navigator-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/target-navigator-cluster.xml index bc665905df1eb2..c7d516bcdc7416 100644 --- a/src/app/zap-templates/zcl/data-model/chip/target-navigator-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/target-navigator-cluster.xml @@ -25,19 +25,27 @@ limitations under the License. true This cluster provides an interface for UX navigation within a set of targets on a device or endpoint. - TargetList - CurrentTarget - + + TargetList + + + + CurrentTarget + + + Upon receipt, this SHALL navigation the UX to the target identified. + This command SHALL be generated in response to NavigateTarget commands. + @@ -45,6 +53,7 @@ limitations under the License. + diff --git a/src/app/zap-templates/zcl/data-model/chip/temperature-control-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/temperature-control-cluster.xml index da0c0bcee983bb..2c7c173c6af8ff 100644 --- a/src/app/zap-templates/zcl/data-model/chip/temperature-control-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/temperature-control-cluster.xml @@ -40,17 +40,48 @@ limitations under the License. - TemperatureSetpoint - MinTemperature - MaxTemperature - Step - SelectedTemperatureLevel - SupportedTemperatureLevels + + TemperatureSetpoint + + + + + + MinTemperature + + + + + + MaxTemperature + + + + + + Step + + + + + + SelectedTemperatureLevel + + + + + + SupportedTemperatureLevels + + + + - Set Temperature - - + Set Temperature + + + diff --git a/src/app/zap-templates/zcl/data-model/chip/temperature-measurement-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/temperature-measurement-cluster.xml index d141743fafde56..45317b7b433894 100644 --- a/src/app/zap-templates/zcl/data-model/chip/temperature-measurement-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/temperature-measurement-cluster.xml @@ -24,9 +24,21 @@ limitations under the License. TEMPERATURE_MEASUREMENT_CLUSTER true true - MeasuredValue - MinMeasuredValue - MaxMeasuredValue - Tolerance + + MeasuredValue + + + + MinMeasuredValue + + + + MaxMeasuredValue + + + + Tolerance + + diff --git a/src/app/zap-templates/zcl/data-model/chip/thermostat-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/thermostat-cluster.xml index 6f75aa45e985f6..9a409b7a89c1bd 100644 --- a/src/app/zap-templates/zcl/data-model/chip/thermostat-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/thermostat-cluster.xml @@ -312,146 +312,368 @@ limitations under the License. - LocalTemperature - OutdoorTemperature - Occupancy - AbsMinHeatSetpointLimit - AbsMaxHeatSetpointLimit - AbsMinCoolSetpointLimit - AbsMaxCoolSetpointLimit - PICoolingDemand - PIHeatingDemand + + LocalTemperature + + + + OutdoorTemperature + + + + Occupancy + + + + + + AbsMinHeatSetpointLimit + + + + + + AbsMaxHeatSetpointLimit + + + + + + AbsMinCoolSetpointLimit + + + + + + AbsMaxCoolSetpointLimit + + + + + + PICoolingDemand + + + + + + PIHeatingDemand + + + + HVACSystemTypeConfiguration + LocalTemperatureCalibration + + + + + + + + OccupiedCoolingSetpoint + + + + + + OccupiedHeatingSetpoint + + + + + + UnoccupiedCoolingSetpoint + + + + + + + + + UnoccupiedHeatingSetpoint + + + + + + - OccupiedCoolingSetpoint - OccupiedHeatingSetpoint - UnoccupiedCoolingSetpoint - UnoccupiedHeatingSetpoint MinHeatSetpointLimit + + + MaxHeatSetpointLimit + + + MinCoolSetpointLimit + + + MaxCoolSetpointLimit + + + MinSetpointDeadBand + + + RemoteSensing + ControlSequenceOfOperation + SystemMode + + + + ThermostatRunningMode + + + + + + StartOfWeek + + + + + + NumberOfWeeklyTransitions + + + + + + NumberOfDailyTransitions + + + - ThermostatRunningMode - StartOfWeek - NumberOfWeeklyTransitions - NumberOfDailyTransitions TemperatureSetpointHold + TemperatureSetpointHoldDuration + ThermostatProgrammingOperationMode + + + + ThermostatRunningState + + + + SetpointChangeSource + + + + SetpointChangeAmount + + + + SetpointChangeSourceTimestamp + - ThermostatRunningState - SetpointChangeSource - SetpointChangeAmount - SetpointChangeSourceTimestamp OccupiedSetback + + + + + + OccupiedSetbackMin + + + + + + OccupiedSetbackMax + + + - OccupiedSetbackMin - OccupiedSetbackMax UnoccupiedSetback + + + + + + + + + UnoccupiedSetbackMin + + + + + + + + + UnoccupiedSetbackMax + + + + + + - UnoccupiedSetbackMin - UnoccupiedSetbackMax EmergencyHeatDelta + ACType + ACCapacity + ACRefrigerantType + ACCompressorType + ACErrorCode + ACLouverPosition + + + + ACCoilTemperature + - ACCoilTemperature ACCapacityformat + + + + PresetTypes + + + + + + ScheduleTypes + + + + + + NumberOfPresets + + + + + + NumberOfSchedules + + + + + + NumberOfScheduleTransitions + + + + + + NumberOfScheduleTransitionPerDay + + + + + + ActivePresetHandle + + + + + + ActiveScheduleHandle + + + - PresetTypes - ScheduleTypes - NumberOfPresets - NumberOfSchedules - NumberOfScheduleTransitions - NumberOfScheduleTransitionPerDay - ActivePresetHandle - ActiveScheduleHandle Presets + + + Schedules + + + + + + SetpointHoldExpiryTimestamp + - SetpointHoldExpiryTimestamp Upon receipt, the attributes for the indicated setpoint(s) SHALL have the amount specified in the Amount field added to them. + @@ -461,27 +683,42 @@ limitations under the License. + + + The Current Weekly Schedule Command is sent from the server in response to the Get Weekly Schedule Command. + + + This command is used to clear the weekly schedule. + + + Upon receipt, if the Schedules attribute contains a ScheduleStruct whose ScheduleHandle field matches the value of the ScheduleHandle field, the server SHALL set the thermostat's ActiveScheduleHandle attribute to the value of the ScheduleHandle field. + + + ID + + + @@ -491,6 +728,9 @@ limitations under the License. + + + diff --git a/src/app/zap-templates/zcl/data-model/chip/thermostat-user-interface-configuration-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/thermostat-user-interface-configuration-cluster.xml index cd3491cc079024..a95a9a31f32d9e 100644 --- a/src/app/zap-templates/zcl/data-model/chip/thermostat-user-interface-configuration-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/thermostat-user-interface-configuration-cluster.xml @@ -29,18 +29,23 @@ limitations under the License. - TemperatureDisplayMode - - + + TemperatureDisplayMode + + + + KeypadLockout + ScheduleProgrammingVisibility + diff --git a/src/app/zap-templates/zcl/data-model/chip/thread-border-router-management-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/thread-border-router-management-cluster.xml index d05ce70c34aca3..84132e495cf4c0 100644 --- a/src/app/zap-templates/zcl/data-model/chip/thread-border-router-management-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/thread-border-router-management-cluster.xml @@ -33,31 +33,52 @@ limitations under the License. - BorderRouterName - - BorderAgentID - - ThreadVersion - - InterfaceEnabled - - ActiveDatasetTimestamp - - PendingDatasetTimestamp - + + BorderRouterName + + + + + BorderAgentID + + + + + ThreadVersion + + + + + InterfaceEnabled + + + + + ActiveDatasetTimestamp + + + + + PendingDatasetTimestamp + + + Command to request the active operational dataset of the Thread network to which the border router is connected. This command must be sent over a valid CASE session + Command to request the pending dataset of the Thread network to which the border router is connected. This command must be sent over a valid CASE session + - + Generated response to GetActiveDatasetRequest or GetPendingDatasetRequest commands. + @@ -65,12 +86,16 @@ limitations under the License. + Command set or update the pending Dataset of the Thread network to which the Border Router is connected. + + + diff --git a/src/app/zap-templates/zcl/data-model/chip/thread-network-diagnostics-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/thread-network-diagnostics-cluster.xml index 77ec8699615156..8804d64e30c7c1 100644 --- a/src/app/zap-templates/zcl/data-model/chip/thread-network-diagnostics-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/thread-network-diagnostics-cluster.xml @@ -107,82 +107,362 @@ limitations under the License. - - Channel - RoutingRole - NetworkName - PanId - ExtendedPanId - MeshLocalPrefix - OverrunCount - NeighborTable - RouteTable - PartitionId - Weighting - DataVersion - StableDataVersion - LeaderRouterId - DetachedRoleCount - ChildRoleCount - RouterRoleCount - LeaderRoleCount - AttachAttemptCount - PartitionIdChangeCount - BetterPartitionAttachAttemptCount - ParentChangeCount - TxTotalCount - TxUnicastCount - TxBroadcastCount - TxAckRequestedCount - TxAckedCount - TxNoAckRequestedCount - TxDataCount - TxDataPollCount - TxBeaconCount - TxBeaconRequestCount - TxOtherCount - TxRetryCount - TxDirectMaxRetryExpiryCount - TxIndirectMaxRetryExpiryCount - TxErrCcaCount - TxErrAbortCount - TxErrBusyChannelCount - RxTotalCount - RxUnicastCount - RxBroadcastCount - RxDataCount - RxDataPollCount - RxBeaconCount - RxBeaconRequestCount - RxOtherCount - RxAddressFilteredCount - RxDestAddrFilteredCount - RxDuplicatedCount - RxErrNoFrameCount - RxErrUnknownNeighborCount - RxErrInvalidSrcAddrCount - RxErrSecCount - RxErrFcsCount - RxErrOtherCount - ActiveTimestamp - PendingTimestamp - Delay - SecurityPolicy - ChannelPage0Mask - OperationalDatasetComponents - ActiveNetworkFaultsList + + + Channel + + + + RoutingRole + + + + NetworkName + + + + PanId + + + + ExtendedPanId + + + + MeshLocalPrefix + + + + OverrunCount + + + + + + NeighborTable + + + + RouteTable + + + + PartitionId + + + + Weighting + + + + DataVersion + + + + StableDataVersion + + + + LeaderRouterId + + + + DetachedRoleCount + + + + + + ChildRoleCount + + + + + + RouterRoleCount + + + + + + LeaderRoleCount + + + + + + AttachAttemptCount + + + + + + PartitionIdChangeCount + + + + + + BetterPartitionAttachAttemptCount + + + + + + ParentChangeCount + + + + + + TxTotalCount + + + + + + TxUnicastCount + + + + + + TxBroadcastCount + + + + + + TxAckRequestedCount + + + + + + TxAckedCount + + + + + + TxNoAckRequestedCount + + + + + + TxDataCount + + + + + + TxDataPollCount + + + + + + TxBeaconCount + + + + + + TxBeaconRequestCount + + + + + + TxOtherCount + + + + + + TxRetryCount + + + + + + TxDirectMaxRetryExpiryCount + + + + + + TxIndirectMaxRetryExpiryCount + + + + + + TxErrCcaCount + + + + + + TxErrAbortCount + + + + + + TxErrBusyChannelCount + + + + + + RxTotalCount + + + + + + RxUnicastCount + + + + + + RxBroadcastCount + + + + + + RxDataCount + + + + + + RxDataPollCount + + + + + + RxBeaconCount + + + + + + RxBeaconRequestCount + + + + + + RxOtherCount + + + + + + RxAddressFilteredCount + + + + + + RxDestAddrFilteredCount + + + + + + RxDuplicatedCount + + + + + + RxErrNoFrameCount + + + + + + RxErrUnknownNeighborCount + + + + + + RxErrInvalidSrcAddrCount + + + + + + RxErrSecCount + + + + + + RxErrFcsCount + + + + + + RxErrOtherCount + + + + + + ActiveTimestamp + + + + PendingTimestamp + + + + Delay + + + + SecurityPolicy + + + + ChannelPage0Mask + + + + OperationalDatasetComponents + + + + ActiveNetworkFaultsList + + Reception of this command SHALL reset the OverrunCount attributes to 0 + + + Indicate that a Node’s connection status to a Thread network has changed + Indicate a change in the set of network faults currently detected by the Node + diff --git a/src/app/zap-templates/zcl/data-model/chip/thread-network-directory-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/thread-network-directory-cluster.xml index 3a6445b15bbad3..8f997cebc46d2f 100644 --- a/src/app/zap-templates/zcl/data-model/chip/thread-network-directory-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/thread-network-directory-cluster.xml @@ -15,58 +15,67 @@ See the License for the specific language governing permissions and limitations under the License. --> - + + + + + + + + + - - - - - - - + + Network Infrastructure + Thread Network Directory + 0x0453 + THREAD_NETWORK_DIRECTORY_CLUSTER + Manages the names and credentials of Thread networks visible to the user. - - Network Infrastructure - Thread Network Directory - 0x0453 - THREAD_NETWORK_DIRECTORY_CLUSTER - Manages the names and credentials of Thread networks visible to the user. + true + true - true - true + + + + + PreferredExtendedPanID + + + + + + ThreadNetworks + + + + + ThreadNetworkTableSize + + - - - - - PreferredExtendedPanID - - - - - ThreadNetworks - - - ThreadNetworkTableSize - - - Adds an entry to the ThreadNetworks list. - - - - - Removes an entry from the ThreadNetworks list. - - - - - Retrieves a Thread Operational Dataset from the ThreadNetworks list. - - - - - This is the response to a GetOperationalDataset request. - - - + + Adds an entry to the ThreadNetworks list. + + + + + + Removes an entry from the ThreadNetworks list. + + + + + + Retrieves a Thread Operational Dataset from the ThreadNetworks list. + + + + + + This is the response to a GetOperationalDataset request. + + + + diff --git a/src/app/zap-templates/zcl/data-model/chip/time-format-localization-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/time-format-localization-cluster.xml index 6ade7abe2e446c..bfc2222ef35a4a 100644 --- a/src/app/zap-templates/zcl/data-model/chip/time-format-localization-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/time-format-localization-cluster.xml @@ -58,14 +58,23 @@ limitations under the License. - - HourFormat - + + HourFormat + + - ActiveCalendarType - + ActiveCalendarType + + + + + + + SupportedCalendarTypes + + + - SupportedCalendarTypes diff --git a/src/app/zap-templates/zcl/data-model/chip/time-synchronization-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/time-synchronization-cluster.xml index 9336a6a944735e..201f71a201e523 100644 --- a/src/app/zap-templates/zcl/data-model/chip/time-synchronization-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/time-synchronization-cluster.xml @@ -114,78 +114,166 @@ limitations under the License. - UTCTime - Granularity - TimeSource - TrustedTimeSource - DefaultNTP - TimeZone - DSTOffset - LocalTime - TimeZoneDatabase - NTPServerAvailable - TimeZoneListMaxSize - DSTOffsetListMaxSize - SupportsDNSResolve - + + UTCTime + + + + Granularity + + + + TimeSource + + + + TrustedTimeSource + + + + + + DefaultNTP + + + + + + TimeZone + + + + + + DSTOffset + + + + + + LocalTime + + + + + + TimeZoneDatabase + + + + + + NTPServerAvailable + + + + + + TimeZoneListMaxSize + + + + + + DSTOffsetListMaxSize + + + + + + SupportsDNSResolve + + + + + This command MAY be issued by Administrator to set the time. + This command SHALL set TrustedTimeSource. + + + This command SHALL set TimeZone. + + + Response to SetTimeZone. + + + This command SHALL set DSTOffset. + + + This command is used to set DefaultNTP. + + + This event SHALL be generated when the server stops applying the current DSTOffset and there are no entries in the list with a larger ValidStarting time. + + + This event SHALL be generated when the server starts or stops applying a DST offset. - + + + + This event SHALL be generated when the server changes its time zone offset or name. + + + This event SHALL be generated if the node has attempted to update its time, but was unable to find a good time from any source. + This event SHALL be generated if the node attempts to update its time and finds that the TrustedTimeSource is null, or the specified peer cannot be reached. + + + diff --git a/src/app/zap-templates/zcl/data-model/chip/unit-localization-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/unit-localization-cluster.xml index fb6238add46a4f..0deb6225eedab9 100644 --- a/src/app/zap-templates/zcl/data-model/chip/unit-localization-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/unit-localization-cluster.xml @@ -43,8 +43,11 @@ limitations under the License. - TemperatureUnit - + TemperatureUnit + + + + diff --git a/src/app/zap-templates/zcl/data-model/chip/user-label-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/user-label-cluster.xml index 24260b78307bd3..14ffa15b70bd11 100644 --- a/src/app/zap-templates/zcl/data-model/chip/user-label-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/user-label-cluster.xml @@ -27,6 +27,7 @@ limitations under the License. LabelList + diff --git a/src/app/zap-templates/zcl/data-model/chip/valve-configuration-and-control-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/valve-configuration-and-control-cluster.xml index 80c1cdb60c8ccc..052a08108a69da 100644 --- a/src/app/zap-templates/zcl/data-model/chip/valve-configuration-and-control-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/valve-configuration-and-control-cluster.xml @@ -59,39 +59,86 @@ limitations under the License. - OpenDuration + + OpenDuration + + - DefaultOpenDuration - AutoCloseTime - RemainingDuration - CurrentState - TargetState - CurrentLevel - TargetLevel - DefaultOpenLevel - ValveFault - LevelStep - + + DefaultOpenDuration + + + + AutoCloseTime + + + + + + RemainingDuration + + + + CurrentState + + + + TargetState + + + + CurrentLevel + + + + + + TargetLevel + + + + + + DefaultOpenLevel + + + + + + ValveFault + + + + LevelStep + + + + + This command is used to set the valve to its open position. + This command is used to set the valve to its closed position. + This event SHALL be generated when the valve state changed. + This event SHALL be generated when the valve registers or clears a fault. + diff --git a/src/app/zap-templates/zcl/data-model/chip/wake-on-lan-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/wake-on-lan-cluster.xml index 90bd18b5b7baaa..50c88a02726515 100644 --- a/src/app/zap-templates/zcl/data-model/chip/wake-on-lan-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/wake-on-lan-cluster.xml @@ -27,8 +27,14 @@ limitations under the License. - - MACAddress - LinkLocalAddress + + + MACAddress + + + + LinkLocalAddress + + diff --git a/src/app/zap-templates/zcl/data-model/chip/washer-controls-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/washer-controls-cluster.xml index 2dc01920ae3e37..663f13dfcc1271 100644 --- a/src/app/zap-templates/zcl/data-model/chip/washer-controls-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/washer-controls-cluster.xml @@ -45,11 +45,31 @@ limitations under the License. - - SpinSpeeds - SpinSpeedCurrent - NumberOfRinses - SupportedRinses + + + SpinSpeeds + + + + + + SpinSpeedCurrent + + + + + + NumberOfRinses + + + + + + SupportedRinses + + + + diff --git a/src/app/zap-templates/zcl/data-model/chip/water-heater-management-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/water-heater-management-cluster.xml index beeaf277b77d2e..6e5c56e21f9670 100644 --- a/src/app/zap-templates/zcl/data-model/chip/water-heater-management-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/water-heater-management-cluster.xml @@ -64,30 +64,58 @@ Git: 1.4-prerelease-ipr-69-ge15ff5700 true - HeaterTypes - HeatDemand - TankVolume - EstimatedHeatRequired - TankPercentage - BoostState + + HeaterTypes + + + + HeatDemand + + + + TankVolume + + + + + + EstimatedHeatRequired + + + + + + TankPercentage + + + + + + BoostState + + Allows a client to request that the water heater is put into a Boost state. + Allows a client to cancel an ongoing Boost operation. + This event SHALL be generated whenever a Boost command is accepted. + This event SHALL be generated whenever the BoostState transitions from Active to Inactive. + diff --git a/src/app/zap-templates/zcl/data-model/chip/water-heater-mode-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/water-heater-mode-cluster.xml index d9211e808467fb..89d8b78436337c 100644 --- a/src/app/zap-templates/zcl/data-model/chip/water-heater-mode-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/water-heater-mode-cluster.xml @@ -58,18 +58,26 @@ Git: 1.4-prerelease-ipr-69-ge15ff5700 - SupportedModes - CurrentMode + + SupportedModes + + + + CurrentMode + + This command is used to change device modes. + This command is sent by the device on receipt of the ChangeToMode command. + diff --git a/src/app/zap-templates/zcl/data-model/chip/wifi-network-diagnostics-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/wifi-network-diagnostics-cluster.xml index 7fb35aab255ed7..f2a68e977bf965 100644 --- a/src/app/zap-templates/zcl/data-model/chip/wifi-network-diagnostics-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/wifi-network-diagnostics-cluster.xml @@ -63,35 +63,94 @@ limitations under the License. - - BSSID - SecurityType - WiFiVersion - ChannelNumber - RSSI - BeaconLostCount - BeaconRxCount - PacketMulticastRxCount - PacketMulticastTxCount - PacketUnicastRxCount - PacketUnicastTxCount - CurrentMaxRate - OverrunCount + + + BSSID + + + + SecurityType + + + + WiFiVersion + + + + ChannelNumber + + + + RSSI + + + + BeaconLostCount + + + + + + BeaconRxCount + + + + + + PacketMulticastRxCount + + + + + + PacketMulticastTxCount + + + + + + PacketUnicastRxCount + + + + + + PacketUnicastTxCount + + + + + + CurrentMaxRate + + + + OverrunCount + + + + Reception of this command SHALL reset the Breacon and Packet related count attributes to 0 + + + Indicate that a Node’s Wi-Fi connection has been disconnected as a result of de-authenticated or dis-association and indicates the reason. + Indicate that a Node has failed to connect, or reconnect, to a Wi-Fi access point. + Indicate that a Node’s connection status to a Wi-Fi network has changed. + diff --git a/src/app/zap-templates/zcl/data-model/chip/wifi-network-management-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/wifi-network-management-cluster.xml index 8c8b4d40c3abdd..c5246f6acddfc2 100644 --- a/src/app/zap-templates/zcl/data-model/chip/wifi-network-management-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/wifi-network-management-cluster.xml @@ -30,19 +30,25 @@ limitations under the License. - SSID + + SSID + + PassphraseSurrogate + Request the current WPA-Personal passphrase or PSK associated with the managed Wi-Fi network. + This is the response to a NetworkPassphraseRequest. + diff --git a/src/app/zap-templates/zcl/data-model/chip/window-covering.xml b/src/app/zap-templates/zcl/data-model/chip/window-covering.xml index 0e1c97a4d45040..1363b5c8aa4c9d 100644 --- a/src/app/zap-templates/zcl/data-model/chip/window-covering.xml +++ b/src/app/zap-templates/zcl/data-model/chip/window-covering.xml @@ -57,45 +57,186 @@ limitations under the License. - Type + + Type + + - PhysicalClosedLimitLift + + PhysicalClosedLimitLift + + + + + + + + - PhysicalClosedLimitTilt + + PhysicalClosedLimitTilt + + + + + + + + - CurrentPositionLift + + CurrentPositionLift + + + + + + + + - CurrentPositionTilt + + CurrentPositionTilt + + + + + + + + - NumberOfActuationsLift + + NumberOfActuationsLift + + + + - NumberOfActuationsTilt + + NumberOfActuationsTilt + + + + - ConfigStatus + + ConfigStatus + + - CurrentPositionLiftPercentage + + CurrentPositionLiftPercentage + + + + + + + - CurrentPositionTiltPercentage + + CurrentPositionTiltPercentage + + + + + + + - OperationalStatus + + OperationalStatus + + - TargetPositionLiftPercent100ths + + TargetPositionLiftPercent100ths + + + + + + + - TargetPositionTiltPercent100ths + + TargetPositionTiltPercent100ths + + + + + + + - EndProductType + + EndProductType + + - CurrentPositionLiftPercent100ths + + CurrentPositionLiftPercent100ths + + + + + + + - CurrentPositionTiltPercent100ths - + + CurrentPositionTiltPercent100ths + + + + + + + - InstalledOpenLimitLift - InstalledClosedLimitLift + + InstalledOpenLimitLift + + + + + + + + + + InstalledClosedLimitLift + + + + + + + + - InstalledOpenLimitTilt - InstalledClosedLimitTilt + + InstalledOpenLimitTilt + + + + + + + + + + InstalledClosedLimitTilt + + + + + + + + @@ -104,44 +245,85 @@ limitations under the License. Mode - + + - SafetyStatus - + + SafetyStatus + + + Moves window covering to InstalledOpenLimitLift and InstalledOpenLimitTilt + Moves window covering to InstalledClosedLimitLift and InstalledCloseLimitTilt + Stop any adjusting of window covering + Go to lift value specified + + + + + + Go to lift percentage specified + + + + + + + + + + + Go to tilt value specified + + + + + + Go to tilt percentage specified + + + + + + + + + + + From b99a978ee420afa7e503e50319d8605c8d6ad93a Mon Sep 17 00:00:00 2001 From: Mathieu Kardous <84793247+mkardous-silabs@users.noreply.github.com> Date: Wed, 23 Oct 2024 12:49:23 -0400 Subject: [PATCH 084/149] [Silabs] Bump Simplicity SDK to 2024.6.2 (#36213) --- .github/workflows/examples-efr32.yaml | 2 +- .github/workflows/release_artifacts.yaml | 2 +- .gitmodules | 2 +- integrations/cloudbuild/smoke-test.yaml | 14 +++++++------- third_party/openthread/platforms/efr32/BUILD.gn | 4 +++- third_party/silabs/BUILD.gn | 4 +++- third_party/silabs/lwip.gni | 4 +--- third_party/silabs/matter_support | 2 +- third_party/silabs/simplicity_sdk | 2 +- 9 files changed, 19 insertions(+), 17 deletions(-) diff --git a/.github/workflows/examples-efr32.yaml b/.github/workflows/examples-efr32.yaml index d9df0bca21637f..b0b4fef50e15df 100644 --- a/.github/workflows/examples-efr32.yaml +++ b/.github/workflows/examples-efr32.yaml @@ -41,7 +41,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-efr32:84 + image: ghcr.io/project-chip/chip-build-efr32:85 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" steps: diff --git a/.github/workflows/release_artifacts.yaml b/.github/workflows/release_artifacts.yaml index af90dc316d0f4a..54997b6efa9b39 100644 --- a/.github/workflows/release_artifacts.yaml +++ b/.github/workflows/release_artifacts.yaml @@ -64,7 +64,7 @@ jobs: runs-on: ubuntu-latest container: - image: ghcr.io/project-chip/chip-build-efr32:84 + image: ghcr.io/project-chip/chip-build-efr32:85 steps: - name: Checkout uses: actions/checkout@v4 diff --git a/.gitmodules b/.gitmodules index 3f50d3079d4e03..c2b9a95a5e0345 100644 --- a/.gitmodules +++ b/.gitmodules @@ -213,7 +213,7 @@ [submodule "third_party/silabs/simplicity_sdk"] path = third_party/silabs/simplicity_sdk url = https://github.com/SiliconLabs/simplicity_sdk.git - branch = v2024.6.1-0 + branch = v2024.6.2 platforms = silabs [submodule "third_party/silabs/wiseconnect-wifi-bt-sdk"] path = third_party/silabs/wiseconnect-wifi-bt-sdk diff --git a/integrations/cloudbuild/smoke-test.yaml b/integrations/cloudbuild/smoke-test.yaml index 24a3029d2fe2f8..824b79d6ce1a22 100644 --- a/integrations/cloudbuild/smoke-test.yaml +++ b/integrations/cloudbuild/smoke-test.yaml @@ -1,5 +1,5 @@ steps: - - name: "ghcr.io/project-chip/chip-build-vscode:84" + - name: "ghcr.io/project-chip/chip-build-vscode:85" entrypoint: "bash" args: - "-c" @@ -7,7 +7,7 @@ steps: git config --global --add safe.directory "*" python scripts/checkout_submodules.py --shallow --recursive --platform esp32 nrfconnect silabs linux android id: Submodules - - name: "ghcr.io/project-chip/chip-build-vscode:84" + - name: "ghcr.io/project-chip/chip-build-vscode:85" # NOTE: silabs boostrap is NOT done with the rest as it requests a conflicting # jinja2 version (asks for 3.1.3 when constraints.txt asks for 3.0.3) env: @@ -24,7 +24,7 @@ steps: path: /pwenv timeout: 900s - - name: "ghcr.io/project-chip/chip-build-vscode:84" + - name: "ghcr.io/project-chip/chip-build-vscode:85" id: ESP32 env: - PW_ENVIRONMENT_ROOT=/pwenv @@ -45,7 +45,7 @@ steps: volumes: - name: pwenv path: /pwenv - - name: "ghcr.io/project-chip/chip-build-vscode:84" + - name: "ghcr.io/project-chip/chip-build-vscode:85" id: NRFConnect env: - PW_ENVIRONMENT_ROOT=/pwenv @@ -66,7 +66,7 @@ steps: - name: pwenv path: /pwenv - - name: "ghcr.io/project-chip/chip-build-vscode:84" + - name: "ghcr.io/project-chip/chip-build-vscode:85" id: EFR32 env: - PW_ENVIRONMENT_ROOT=/pwenv @@ -88,7 +88,7 @@ steps: - name: pwenv path: /pwenv - - name: "ghcr.io/project-chip/chip-build-vscode:84" + - name: "ghcr.io/project-chip/chip-build-vscode:85" id: Linux env: - PW_ENVIRONMENT_ROOT=/pwenv @@ -141,7 +141,7 @@ steps: - name: pwenv path: /pwenv - - name: "ghcr.io/project-chip/chip-build-vscode:84" + - name: "ghcr.io/project-chip/chip-build-vscode:85" id: Android env: - PW_ENVIRONMENT_ROOT=/pwenv diff --git a/third_party/openthread/platforms/efr32/BUILD.gn b/third_party/openthread/platforms/efr32/BUILD.gn index 69e55a5d76151d..e270db2ae8757f 100644 --- a/third_party/openthread/platforms/efr32/BUILD.gn +++ b/third_party/openthread/platforms/efr32/BUILD.gn @@ -65,7 +65,6 @@ source_set("libopenthread-efr32") { "${sl_ot_efr32_root}/flash.c", "${sl_ot_efr32_root}/ieee802154-packet-utils.cpp", "${sl_ot_efr32_root}/misc.c", - "${sl_ot_efr32_root}/radio.c", "${sl_ot_efr32_root}/radio_coex.c", "${sl_ot_efr32_root}/radio_extension.c", "${sl_ot_efr32_root}/radio_power_manager.c", @@ -73,6 +72,9 @@ source_set("libopenthread-efr32") { "${sl_ot_efr32_root}/sleep.c", "${sl_ot_efr32_root}/soft_source_match_table.c", "${sl_ot_efr32_root}/system.c", + + # Temporary file until the files in the SI SDK is fixed + "${sdk_support_root}/protocol/openthread/platform-abstraction/efr32/radio.c", ] include_dirs = [ "${openthread_root}/examples/platforms/utils" ] diff --git a/third_party/silabs/BUILD.gn b/third_party/silabs/BUILD.gn index e08c7cd0bd11bd..16e0ba68c4607a 100644 --- a/third_party/silabs/BUILD.gn +++ b/third_party/silabs/BUILD.gn @@ -206,7 +206,9 @@ if (wifi_soc != true) { # CCP board "${openthread_root}/src/core/mac/mac_frame.cpp", "${openthread_root}/src/core/mac/sub_mac.cpp", "${openthread_root}/src/core/thread/mle.cpp", - "${sl_ot_platform_abstraction}/efr32/radio.c", + + # Temporary file until the files in the SI SDK is fixed + "${sdk_support_root}/protocol/openthread/platform-abstraction/efr32/radio.c", ] include_dirs = [ "${sl_ot_platform_abstraction}/include" ] diff --git a/third_party/silabs/lwip.gni b/third_party/silabs/lwip.gni index b0b6a0db0d2c9f..9a35e7c45f7a61 100644 --- a/third_party/silabs/lwip.gni +++ b/third_party/silabs/lwip.gni @@ -169,10 +169,8 @@ template("lwip_target") { "${_lwip_root}/src/core/ipv6/ip6.c", "${_lwip_root}/src/core/ipv6/ip6_addr.c", "${_lwip_root}/src/core/ipv6/ip6_frag.c", + "${_lwip_root}/src/core/ipv6/mld6.c", "${_lwip_root}/src/core/ipv6/nd6.c", - - # TODO: When updating to next Si SDK version, revert change. - "${sdk_support_root}/src/core/ipv6/mld6.c", ] } diff --git a/third_party/silabs/matter_support b/third_party/silabs/matter_support index 8dd7b9bb5f8577..bf647de36d841e 160000 --- a/third_party/silabs/matter_support +++ b/third_party/silabs/matter_support @@ -1 +1 @@ -Subproject commit 8dd7b9bb5f8577834140bcc54f7497ae3f4b9bd0 +Subproject commit bf647de36d841e62fdac5d37c0cdfc5ebf9200bc diff --git a/third_party/silabs/simplicity_sdk b/third_party/silabs/simplicity_sdk index aa5ce2e835dfdc..36e12f01947c2b 160000 --- a/third_party/silabs/simplicity_sdk +++ b/third_party/silabs/simplicity_sdk @@ -1 +1 @@ -Subproject commit aa5ce2e835dfdce8c20fb828f27d3a261946f946 +Subproject commit 36e12f01947c2bed82922015e87b926df0745bc2 From 7026061c166cee2a1969fbefe5e1bbc6f250af31 Mon Sep 17 00:00:00 2001 From: chirag-silabs <100861685+chirag-silabs@users.noreply.github.com> Date: Wed, 23 Oct 2024 22:32:42 +0530 Subject: [PATCH 085/149] [Silabs] Fixing the BLE Advertisement for the NCP and 917SoC devices (#36189) * ble fixes for the pointer * removing the global structure * addressing the review comments * removing the static keyword * modifying the assignment * restyling the PR * addressing review comments * restyling the PR * removing the TODOs * addressing the review comment * restyling the PR --- src/platform/silabs/BLEManagerImpl.h | 12 +- src/platform/silabs/rs911x/BLEManagerImpl.cpp | 156 ++++++++++++------ .../silabs/rs911x/wfx_sl_ble_init.cpp | 112 ++----------- src/platform/silabs/rs911x/wfx_sl_ble_init.h | 5 +- 4 files changed, 132 insertions(+), 153 deletions(-) diff --git a/src/platform/silabs/BLEManagerImpl.h b/src/platform/silabs/BLEManagerImpl.h index 6d901db16e95db..9380accce38e55 100644 --- a/src/platform/silabs/BLEManagerImpl.h +++ b/src/platform/silabs/BLEManagerImpl.h @@ -58,12 +58,12 @@ class BLEManagerImpl final : public BLEManager, private BleLayer, private BlePla #if (SLI_SI91X_ENABLE_BLE || RSI_BLE_ENABLE) // Used for posting the event in the BLE queue void BlePostEvent(SilabsBleWrapper::BleEvent_t * event); - void HandleConnectEvent(SilabsBleWrapper::sl_wfx_msg_t * evt); - void HandleConnectionCloseEvent(SilabsBleWrapper::sl_wfx_msg_t * evt); - void HandleWriteEvent(SilabsBleWrapper::sl_wfx_msg_t * evt); - void UpdateMtu(SilabsBleWrapper::sl_wfx_msg_t * evt); + void HandleConnectEvent(const SilabsBleWrapper::sl_wfx_msg_t & evt); + void HandleConnectionCloseEvent(const SilabsBleWrapper::sl_wfx_msg_t & evt); + void HandleWriteEvent(const SilabsBleWrapper::sl_wfx_msg_t & evt); + void UpdateMtu(const SilabsBleWrapper::sl_wfx_msg_t & evt); void HandleTxConfirmationEvent(BLE_CONNECTION_OBJECT conId); - void HandleTXCharCCCDWrite(SilabsBleWrapper::sl_wfx_msg_t * evt); + void HandleTXCharCCCDWrite(const SilabsBleWrapper::sl_wfx_msg_t & evt); void HandleSoftTimerEvent(void); int32_t SendBLEAdvertisementCommand(void); #else @@ -194,7 +194,7 @@ class BLEManagerImpl final : public BLEManager, private BleLayer, private BlePla #endif #if (SLI_SI91X_ENABLE_BLE || RSI_BLE_ENABLE) - void HandleRXCharWrite(SilabsBleWrapper::sl_wfx_msg_t * evt); + void HandleRXCharWrite(const SilabsBleWrapper::sl_wfx_msg_t & evt); #else void HandleRXCharWrite(volatile sl_bt_msg_t * evt); #endif diff --git a/src/platform/silabs/rs911x/BLEManagerImpl.cpp b/src/platform/silabs/rs911x/BLEManagerImpl.cpp index 44b2a17199b330..176f396f44cd1f 100644 --- a/src/platform/silabs/rs911x/BLEManagerImpl.cpp +++ b/src/platform/silabs/rs911x/BLEManagerImpl.cpp @@ -57,24 +57,7 @@ extern "C" { #define BLE_TIMEOUT_MS 400 #define BLE_SEND_INDICATION_TIMER_PERIOD_MS (5000) -// Used to send the Indication Confirmation -uint8_t dev_address[RSI_DEV_ADDR_LEN]; -uint16_t ble_measurement_hndl; - osSemaphoreId_t sl_rs_ble_init_sem; -osTimerId_t sbleAdvTimeoutTimer; - -static osThreadId_t sBleThread; -constexpr uint32_t kBleTaskSize = 2048; -static uint8_t bleStack[kBleTaskSize]; -static osThread_t sBleTaskControlBlock; -constexpr osThreadAttr_t kBleTaskAttr = { .name = "rsi_ble", - .attr_bits = osThreadDetached, - .cb_mem = &sBleTaskControlBlock, - .cb_size = osThreadCbSize, - .stack_mem = bleStack, - .stack_size = kBleTaskSize, - .priority = osPriorityHigh }; using namespace ::chip; using namespace ::chip::Ble; @@ -111,6 +94,84 @@ const uint8_t UUID_CHIPoBLEService[] = { 0xFB, 0x34, 0x9B, 0x5F, 0x80, 0x00 0x00, 0x10, 0x00, 0x00, 0xF6, 0xFF, 0x00, 0x00 }; const uint8_t ShortUUID_CHIPoBLEService[] = { 0xF6, 0xFF }; +// Used to send the Indication Confirmation +uint8_t dev_address[RSI_DEV_ADDR_LEN]; +uint16_t rsi_ble_measurement_hndl; +uint16_t rsi_ble_gatt_server_client_config_hndl; + +osTimerId_t sbleAdvTimeoutTimer; + +osThreadId_t sBleThread; +constexpr uint32_t kBleTaskSize = 2560; +uint8_t bleStack[kBleTaskSize]; +osThread_t sBleTaskControlBlock; +constexpr osThreadAttr_t kBleTaskAttr = { .name = "rsi_ble", + .attr_bits = osThreadDetached, + .cb_mem = &sBleTaskControlBlock, + .cb_size = osThreadCbSize, + .stack_mem = bleStack, + .stack_size = kBleTaskSize, + .priority = osPriorityHigh }; + +void rsi_ble_add_matter_service(void) +{ + constexpr uuid_t custom_service = { .size = RSI_BLE_MATTER_CUSTOM_SERVICE_SIZE, + .val = { .val16 = RSI_BLE_MATTER_CUSTOM_SERVICE_VALUE_16 } }; + uint8_t data[RSI_BLE_MATTER_CUSTOM_SERVICE_DATA_LENGTH] = { RSI_BLE_MATTER_CUSTOM_SERVICE_DATA }; + + constexpr uuid_t custom_characteristic_RX = { .size = RSI_BLE_CUSTOM_CHARACTERISTIC_RX_SIZE, + .reserved = { RSI_BLE_CUSTOM_CHARACTERISTIC_RX_RESERVED }, + .val = { .val128 = { + .data1 = { RSI_BLE_CUSTOM_CHARACTERISTIC_RX_VALUE_128_DATA_1 }, + .data2 = { RSI_BLE_CUSTOM_CHARACTERISTIC_RX_VALUE_128_DATA_2 }, + .data3 = { RSI_BLE_CUSTOM_CHARACTERISTIC_RX_VALUE_128_DATA_3 }, + .data4 = { RSI_BLE_CUSTOM_CHARACTERISTIC_RX_VALUE_128_DATA_4 } } } }; + + rsi_ble_resp_add_serv_t new_serv_resp = { 0 }; + rsi_ble_add_service(custom_service, &new_serv_resp); + + // Adding custom characteristic declaration to the custom service + SilabsBleWrapper::rsi_ble_add_char_serv_att( + new_serv_resp.serv_handler, new_serv_resp.start_handle + RSI_BLE_CHARACTERISTIC_RX_ATTRIBUTE_HANDLE_LOCATION, + RSI_BLE_ATT_PROPERTY_WRITE | RSI_BLE_ATT_PROPERTY_READ, // Set read, write, write without response + new_serv_resp.start_handle + RSI_BLE_CHARACTERISTIC_RX_VALUE_HANDLE_LOCATION, custom_characteristic_RX); + + // Adding characteristic value attribute to the service + SilabsBleWrapper::rsi_ble_add_char_val_att( + new_serv_resp.serv_handler, new_serv_resp.start_handle + RSI_BLE_CHARACTERISTIC_RX_VALUE_HANDLE_LOCATION, + custom_characteristic_RX, + RSI_BLE_ATT_PROPERTY_WRITE | RSI_BLE_ATT_PROPERTY_READ, // Set read, write, write without response + data, sizeof(data), ATT_REC_IN_HOST); + + constexpr uuid_t custom_characteristic_TX = { .size = RSI_BLE_CUSTOM_CHARACTERISTIC_TX_SIZE, + .reserved = { RSI_BLE_CUSTOM_CHARACTERISTIC_TX_RESERVED }, + .val = { .val128 = { + .data1 = { RSI_BLE_CUSTOM_CHARACTERISTIC_TX_VALUE_128_DATA_1 }, + .data2 = { RSI_BLE_CUSTOM_CHARACTERISTIC_TX_VALUE_128_DATA_2 }, + .data3 = { RSI_BLE_CUSTOM_CHARACTERISTIC_TX_VALUE_128_DATA_3 }, + .data4 = { RSI_BLE_CUSTOM_CHARACTERISTIC_TX_VALUE_128_DATA_4 } } } }; + + // Adding custom characteristic declaration to the custom service + SilabsBleWrapper::rsi_ble_add_char_serv_att( + new_serv_resp.serv_handler, new_serv_resp.start_handle + RSI_BLE_CHARACTERISTIC_TX_ATTRIBUTE_HANDLE_LOCATION, + RSI_BLE_ATT_PROPERTY_WRITE_NO_RESPONSE | RSI_BLE_ATT_PROPERTY_WRITE | RSI_BLE_ATT_PROPERTY_READ | + RSI_BLE_ATT_PROPERTY_NOTIFY | RSI_BLE_ATT_PROPERTY_INDICATE, // Set read, write, write without response + new_serv_resp.start_handle + RSI_BLE_CHARACTERISTIC_TX_MEASUREMENT_HANDLE_LOCATION, custom_characteristic_TX); + + // Adding characteristic value attribute to the service + rsi_ble_measurement_hndl = new_serv_resp.start_handle + RSI_BLE_CHARACTERISTIC_TX_MEASUREMENT_HANDLE_LOCATION; + + // Adding characteristic value attribute to the service + rsi_ble_gatt_server_client_config_hndl = + new_serv_resp.start_handle + RSI_BLE_CHARACTERISTIC_TX_GATT_SERVER_CLIENT_HANDLE_LOCATION; + + SilabsBleWrapper::rsi_ble_add_char_val_att(new_serv_resp.serv_handler, rsi_ble_measurement_hndl, custom_characteristic_TX, + RSI_BLE_ATT_PROPERTY_WRITE_NO_RESPONSE | RSI_BLE_ATT_PROPERTY_WRITE | + RSI_BLE_ATT_PROPERTY_READ | RSI_BLE_ATT_PROPERTY_NOTIFY | + RSI_BLE_ATT_PROPERTY_INDICATE, // Set read, write, write without response + data, sizeof(data), ATT_REC_MAINTAIN_IN_HOST); +} + } // namespace BLEManagerImpl BLEManagerImpl::sInstance; @@ -120,15 +181,14 @@ void BLEManagerImpl::ProcessEvent(SilabsBleWrapper::BleEvent_t inEvent) switch (inEvent.eventType) { case SilabsBleWrapper::BleEventType::RSI_BLE_CONN_EVENT: { - BLEMgrImpl().HandleConnectEvent((inEvent.eventData)); + BLEMgrImpl().HandleConnectEvent(inEvent.eventData); // Requests the connection parameters change with the remote device - rsi_ble_conn_params_update(inEvent.eventData->resp_enh_conn.dev_addr, BLE_MIN_CONNECTION_INTERVAL_MS, + rsi_ble_conn_params_update(inEvent.eventData.resp_enh_conn.dev_addr, BLE_MIN_CONNECTION_INTERVAL_MS, BLE_MAX_CONNECTION_INTERVAL_MS, BLE_SLAVE_LATENCY_MS, BLE_TIMEOUT_MS); - rsi_ble_set_data_len(inEvent.eventData->resp_enh_conn.dev_addr, RSI_BLE_TX_OCTETS, RSI_BLE_TX_TIME); + rsi_ble_set_data_len(inEvent.eventData.resp_enh_conn.dev_addr, RSI_BLE_TX_OCTETS, RSI_BLE_TX_TIME); // Used to send the Indication confirmation - memcpy(dev_address, inEvent.eventData->resp_enh_conn.dev_addr, RSI_DEV_ADDR_LEN); - ble_measurement_hndl = inEvent.eventData->rsi_ble_measurement_hndl; + memcpy(dev_address, inEvent.eventData.resp_enh_conn.dev_addr, RSI_DEV_ADDR_LEN); } break; case SilabsBleWrapper::BleEventType::RSI_BLE_DISCONN_EVENT: { @@ -143,7 +203,7 @@ void BLEManagerImpl::ProcessEvent(SilabsBleWrapper::BleEvent_t inEvent) break; case SilabsBleWrapper::BleEventType::RSI_BLE_EVENT_GATT_RD: { #if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING - if (inEvent.eventData->rsi_ble_read_req->type == 0) + if (inEvent.eventData.rsi_ble_read_req->type == 0) { BLEMgrImpl().HandleC3ReadRequest(inEvent.eventData); } @@ -220,10 +280,10 @@ void BLEManagerImpl::sl_ble_init() SilabsBleWrapper::rsi_ble_on_event_indication_confirmation, NULL); // Exchange of GATT info with BLE stack - SilabsBleWrapper::rsi_ble_add_matter_service(); + rsi_ble_add_matter_service(); rsi_ble_set_random_address_with_value(randomAddrBLE); - sInstance.sBleEventQueue = osMessageQueueNew(WFX_QUEUE_SIZE, sizeof(WfxEvent_t), NULL); + sInstance.sBleEventQueue = osMessageQueueNew(WFX_QUEUE_SIZE, sizeof(SilabsBleWrapper::BleEvent_t), NULL); VerifyOrDie(sInstance.sBleEventQueue != nullptr); chip::DeviceLayer::Internal::BLEMgrImpl().HandleBootEvent(); @@ -440,7 +500,7 @@ CHIP_ERROR BLEManagerImpl::SendIndication(BLE_CONNECTION_OBJECT conId, const Chi PacketBufferHandle data) { int32_t status = 0; - status = rsi_ble_indicate_value(dev_address, ble_measurement_hndl, data->DataLength(), data->Start()); + status = rsi_ble_indicate_value(dev_address, rsi_ble_measurement_hndl, data->DataLength(), data->Start()); if (status != RSI_SUCCESS) { ChipLogProgress(DeviceLayer, "indication failed with error code %lx ", status); @@ -734,9 +794,9 @@ CHIP_ERROR BLEManagerImpl::StopAdvertising(void) return err; } -void BLEManagerImpl::UpdateMtu(SilabsBleWrapper::sl_wfx_msg_t * evt) +void BLEManagerImpl::UpdateMtu(const SilabsBleWrapper::sl_wfx_msg_t & evt) { - CHIPoBLEConState * bleConnState = GetConnectionState(evt->connectionHandle); + CHIPoBLEConState * bleConnState = GetConnectionState(evt.connectionHandle); if (bleConnState != NULL) { // bleConnState->MTU is a 10-bit field inside a uint16_t. We're @@ -748,10 +808,10 @@ void BLEManagerImpl::UpdateMtu(SilabsBleWrapper::sl_wfx_msg_t * evt) // TODO: https://github.com/project-chip/connectedhomeip/issues/2569 // tracks making this safe with a check or explaining why no check // is needed. - ChipLogProgress(DeviceLayer, "DriveBLEState UpdateMtu %d", evt->rsi_ble_mtu.mtu_size); + ChipLogProgress(DeviceLayer, "DriveBLEState UpdateMtu %d", evt.rsi_ble_mtu.mtu_size); #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wconversion" - bleConnState->mtu = evt->rsi_ble_mtu.mtu_size; + bleConnState->mtu = evt.rsi_ble_mtu.mtu_size; #pragma GCC diagnostic pop ; } @@ -763,14 +823,13 @@ void BLEManagerImpl::HandleBootEvent(void) PlatformMgr().ScheduleWork(DriveBLEState, 0); } -void BLEManagerImpl::HandleConnectEvent(SilabsBleWrapper::sl_wfx_msg_t * evt) +void BLEManagerImpl::HandleConnectEvent(const SilabsBleWrapper::sl_wfx_msg_t & evt) { - AddConnection(evt->connectionHandle, evt->bondingHandle); + AddConnection(evt.connectionHandle, evt.bondingHandle); PlatformMgr().ScheduleWork(DriveBLEState, 0); } -// TODO:: Implementation need to be done. -void BLEManagerImpl::HandleConnectionCloseEvent(SilabsBleWrapper::sl_wfx_msg_t * evt) +void BLEManagerImpl::HandleConnectionCloseEvent(const SilabsBleWrapper::sl_wfx_msg_t & evt) { uint8_t connHandle = 1; @@ -780,7 +839,7 @@ void BLEManagerImpl::HandleConnectionCloseEvent(SilabsBleWrapper::sl_wfx_msg_t * event.Type = DeviceEventType::kCHIPoBLEConnectionError; event.CHIPoBLEConnectionError.ConId = connHandle; - switch (evt->reason) + switch (evt.reason) { case RSI_BT_CTRL_REMOTE_USER_TERMINATED: @@ -792,7 +851,7 @@ void BLEManagerImpl::HandleConnectionCloseEvent(SilabsBleWrapper::sl_wfx_msg_t * event.CHIPoBLEConnectionError.Reason = BLE_ERROR_CHIPOBLE_PROTOCOL_ABORT; } - ChipLogProgress(DeviceLayer, "BLE GATT connection closed (con %u, reason %x)", connHandle, evt->reason); + ChipLogProgress(DeviceLayer, "BLE GATT connection closed (con %u, reason %x)", connHandle, evt.reason); PlatformMgr().PostEventOrDie(&event); @@ -804,11 +863,11 @@ void BLEManagerImpl::HandleConnectionCloseEvent(SilabsBleWrapper::sl_wfx_msg_t * } } -void BLEManagerImpl::HandleWriteEvent(SilabsBleWrapper::sl_wfx_msg_t * evt) +void BLEManagerImpl::HandleWriteEvent(const SilabsBleWrapper::sl_wfx_msg_t & evt) { - ChipLogProgress(DeviceLayer, "Char Write Req, packet type %d", evt->rsi_ble_write.pkt_type); + ChipLogProgress(DeviceLayer, "Char Write Req, packet type %d", evt.rsi_ble_write.pkt_type); - if (evt->rsi_ble_write.handle[0] == (uint8_t) evt->rsi_ble_gatt_server_client_config_hndl) // TODO:: compare the handle exactly + if (evt.rsi_ble_write.handle[0] == (uint8_t) rsi_ble_gatt_server_client_config_hndl) // TODO:: compare the handle exactly { HandleTXCharCCCDWrite(evt); } @@ -818,23 +877,22 @@ void BLEManagerImpl::HandleWriteEvent(SilabsBleWrapper::sl_wfx_msg_t * evt) } } -// TODO:: Need to implement this -void BLEManagerImpl::HandleTXCharCCCDWrite(SilabsBleWrapper::sl_wfx_msg_t * evt) +void BLEManagerImpl::HandleTXCharCCCDWrite(const SilabsBleWrapper::sl_wfx_msg_t & evt) { CHIP_ERROR err = CHIP_NO_ERROR; bool isIndicationEnabled = false; ChipDeviceEvent event; CHIPoBLEConState * bleConnState; - bleConnState = GetConnectionState(evt->connectionHandle); + bleConnState = GetConnectionState(evt.connectionHandle); VerifyOrExit(bleConnState != NULL, err = CHIP_ERROR_NO_MEMORY); // Determine if the client is enabling or disabling notification/indication. - if (evt->rsi_ble_write.att_value[0] != 0) + if (evt.rsi_ble_write.att_value[0] != 0) { isIndicationEnabled = true; } - ChipLogProgress(DeviceLayer, "HandleTXcharCCCDWrite - Config Flags value : %d", evt->rsi_ble_write.att_value[0]); + ChipLogProgress(DeviceLayer, "HandleTXcharCCCDWrite - Config Flags value : %d", evt.rsi_ble_write.att_value[0]); ChipLogProgress(DeviceLayer, "CHIPoBLE %s received", isIndicationEnabled ? "subscribe" : "unsubscribe"); if (isIndicationEnabled) @@ -864,13 +922,13 @@ void BLEManagerImpl::HandleTXCharCCCDWrite(SilabsBleWrapper::sl_wfx_msg_t * evt) } } -void BLEManagerImpl::HandleRXCharWrite(SilabsBleWrapper::sl_wfx_msg_t * evt) +void BLEManagerImpl::HandleRXCharWrite(const SilabsBleWrapper::sl_wfx_msg_t & evt) { uint8_t conId = 1; CHIP_ERROR err = CHIP_NO_ERROR; System::PacketBufferHandle buf; - uint16_t writeLen = evt->rsi_ble_write.length; - uint8_t * data = (uint8_t *) evt->rsi_ble_write.att_value; + uint16_t writeLen = evt.rsi_ble_write.length; + uint8_t * data = (uint8_t *) evt.rsi_ble_write.att_value; // Copy the data to a packet buffer. buf = System::PacketBufferHandle::NewWithData(data, writeLen, 0, 0); @@ -997,9 +1055,9 @@ CHIP_ERROR BLEManagerImpl::EncodeAdditionalDataTlv() return err; } -void BLEManagerImpl::HandleC3ReadRequest(SilabsBleWrapper::sl_wfx_msg_t * evt) +void BLEManagerImpl::HandleC3ReadRequest(const SilabsBleWrapper::sl_wfx_msg_t & evt) { - sl_status_t ret = rsi_ble_gatt_read_response(evt->rsi_ble_read_req->dev_addr, GATT_READ_RESP, evt->rsi_ble_read_req->handle, + sl_status_t ret = rsi_ble_gatt_read_response(evt.rsi_ble_read_req->dev_addr, GATT_READ_RESP, evt.rsi_ble_read_req->handle, GATT_READ_ZERO_OFFSET, sInstance.c3AdditionalDataBufferHandle->DataLength(), sInstance.c3AdditionalDataBufferHandle->Start()); if (ret != SL_STATUS_OK) diff --git a/src/platform/silabs/rs911x/wfx_sl_ble_init.cpp b/src/platform/silabs/rs911x/wfx_sl_ble_init.cpp index c1af13e2cd807c..971852592c3e2e 100644 --- a/src/platform/silabs/rs911x/wfx_sl_ble_init.cpp +++ b/src/platform/silabs/rs911x/wfx_sl_ble_init.cpp @@ -26,9 +26,6 @@ using namespace chip::DeviceLayer::Internal; -// Global Variables -SilabsBleWrapper::BleEvent_t bleEvent; - /*==============================================*/ /** * @fn rsi_ble_on_mtu_event @@ -40,8 +37,9 @@ SilabsBleWrapper::BleEvent_t bleEvent; */ void SilabsBleWrapper::rsi_ble_on_mtu_event(rsi_ble_event_mtu_t * rsi_ble_mtu) { - bleEvent.eventType = BleEventType::RSI_BLE_MTU_EVENT; - memcpy(&bleEvent.eventData->rsi_ble_mtu, rsi_ble_mtu, sizeof(rsi_ble_event_mtu_t)); + SilabsBleWrapper::BleEvent_t bleEvent = { .eventType = BleEventType::RSI_BLE_MTU_EVENT, + .eventData = { .connectionHandle = 1, .rsi_ble_mtu = *rsi_ble_mtu } }; + BLEMgrImpl().BlePostEvent(&bleEvent); } @@ -57,9 +55,9 @@ void SilabsBleWrapper::rsi_ble_on_mtu_event(rsi_ble_event_mtu_t * rsi_ble_mtu) */ void SilabsBleWrapper::rsi_ble_on_gatt_write_event(uint16_t event_id, rsi_ble_event_write_t * rsi_ble_write) { - bleEvent.eventType = BleEventType::RSI_BLE_GATT_WRITE_EVENT; - bleEvent.eventData->event_id = event_id; - memcpy(&bleEvent.eventData->rsi_ble_write, rsi_ble_write, sizeof(rsi_ble_event_write_t)); + SilabsBleWrapper::BleEvent_t bleEvent = { .eventType = BleEventType::RSI_BLE_GATT_WRITE_EVENT, + .eventData = { + .connectionHandle = 1, .event_id = event_id, .rsi_ble_write = *rsi_ble_write } }; BLEMgrImpl().BlePostEvent(&bleEvent); } @@ -74,10 +72,12 @@ void SilabsBleWrapper::rsi_ble_on_gatt_write_event(uint16_t event_id, rsi_ble_ev */ void SilabsBleWrapper::rsi_ble_on_enhance_conn_status_event(rsi_ble_event_enhance_conn_status_t * resp_enh_conn) { - bleEvent.eventType = BleEventType::RSI_BLE_CONN_EVENT; - bleEvent.eventData->connectionHandle = 1; - bleEvent.eventData->bondingHandle = 255; - memcpy(bleEvent.eventData->resp_enh_conn.dev_addr, resp_enh_conn->dev_addr, RSI_DEV_ADDR_LEN); + SilabsBleWrapper::BleEvent_t bleEvent = { .eventType = BleEventType::RSI_BLE_CONN_EVENT, + .eventData = { + .connectionHandle = 1, + .bondingHandle = 255, + } }; + memcpy(bleEvent.eventData.resp_enh_conn.dev_addr, resp_enh_conn->dev_addr, RSI_DEV_ADDR_LEN); BLEMgrImpl().BlePostEvent(&bleEvent); } @@ -93,8 +93,7 @@ void SilabsBleWrapper::rsi_ble_on_enhance_conn_status_event(rsi_ble_event_enhanc */ void SilabsBleWrapper::rsi_ble_on_disconnect_event(rsi_ble_event_disconnect_t * resp_disconnect, uint16_t reason) { - bleEvent.eventType = BleEventType::RSI_BLE_DISCONN_EVENT; - bleEvent.eventData->reason = reason; + SilabsBleWrapper::BleEvent_t bleEvent = { .eventType = BleEventType::RSI_BLE_DISCONN_EVENT, .eventData = { .reason = reason } }; BLEMgrImpl().BlePostEvent(&bleEvent); } @@ -110,9 +109,9 @@ void SilabsBleWrapper::rsi_ble_on_disconnect_event(rsi_ble_event_disconnect_t * void SilabsBleWrapper::rsi_ble_on_event_indication_confirmation(uint16_t resp_status, rsi_ble_set_att_resp_t * rsi_ble_event_set_att_rsp) { - bleEvent.eventType = BleEventType::RSI_BLE_GATT_INDICATION_CONFIRMATION; - bleEvent.eventData->resp_status = resp_status; - memcpy(&bleEvent.eventData->rsi_ble_event_set_att_rsp, rsi_ble_event_set_att_rsp, sizeof(rsi_ble_set_att_resp_t)); + SilabsBleWrapper::BleEvent_t bleEvent = { .eventType = BleEventType::RSI_BLE_GATT_INDICATION_CONFIRMATION, + .eventData = { .resp_status = resp_status, + .rsi_ble_event_set_att_rsp = *rsi_ble_event_set_att_rsp } }; BLEMgrImpl().BlePostEvent(&bleEvent); } @@ -128,9 +127,8 @@ void SilabsBleWrapper::rsi_ble_on_event_indication_confirmation(uint16_t resp_st */ void SilabsBleWrapper::rsi_ble_on_read_req_event(uint16_t event_id, rsi_ble_read_req_t * rsi_ble_read_req) { - bleEvent.eventType = BleEventType::RSI_BLE_EVENT_GATT_RD; - bleEvent.eventData->event_id = event_id; - memcpy(&bleEvent.eventData->rsi_ble_read_req, rsi_ble_read_req, sizeof(rsi_ble_read_req_t)); + SilabsBleWrapper::BleEvent_t bleEvent = { .eventType = BleEventType::RSI_BLE_EVENT_GATT_RD, + .eventData = { .event_id = event_id, .rsi_ble_read_req = rsi_ble_read_req } }; BLEMgrImpl().BlePostEvent(&bleEvent); } @@ -282,77 +280,3 @@ void SilabsBleWrapper::rsi_ble_add_char_val_att(void * serv_handler, uint16_t ha return; } - -/*==============================================*/ -/** - * @fn rsi_ble_add_matter_service - * @brief this function is used to add service for matter - * @return status (uint32_t) 0 for success. - * @section description - * This function is used at application to create new service. - */ - -uint32_t SilabsBleWrapper::rsi_ble_add_matter_service(void) -{ - uuid_t custom_service = { RSI_BLE_MATTER_CUSTOM_SERVICE_UUID }; - custom_service.size = RSI_BLE_MATTER_CUSTOM_SERVICE_SIZE; - custom_service.val.val16 = RSI_BLE_MATTER_CUSTOM_SERVICE_VALUE_16; - uint8_t data[RSI_BLE_MATTER_CUSTOM_SERVICE_DATA_LENGTH] = { RSI_BLE_MATTER_CUSTOM_SERVICE_DATA }; - - static const uuid_t custom_characteristic_RX = { - .size = RSI_BLE_CUSTOM_CHARACTERISTIC_RX_SIZE, - .reserved = { RSI_BLE_CUSTOM_CHARACTERISTIC_RX_RESERVED }, - .val = { .val128 = { .data1 = { RSI_BLE_CUSTOM_CHARACTERISTIC_RX_VALUE_128_DATA_1 }, - .data2 = { RSI_BLE_CUSTOM_CHARACTERISTIC_RX_VALUE_128_DATA_2 }, - .data3 = { RSI_BLE_CUSTOM_CHARACTERISTIC_RX_VALUE_128_DATA_3 }, - .data4 = { RSI_BLE_CUSTOM_CHARACTERISTIC_RX_VALUE_128_DATA_4 } } } - }; - - rsi_ble_resp_add_serv_t new_serv_resp = { 0 }; - rsi_ble_add_service(custom_service, &new_serv_resp); - - // Adding custom characteristic declaration to the custom service - rsi_ble_add_char_serv_att( - new_serv_resp.serv_handler, new_serv_resp.start_handle + RSI_BLE_CHARACTERISTIC_RX_ATTRIBUTE_HANDLE_LOCATION, - RSI_BLE_ATT_PROPERTY_WRITE | RSI_BLE_ATT_PROPERTY_READ, // Set read, write, write without response - new_serv_resp.start_handle + RSI_BLE_CHARACTERISTIC_RX_VALUE_HANDLE_LOCATION, custom_characteristic_RX); - - // Adding characteristic value attribute to the service - rsi_ble_add_char_val_att(new_serv_resp.serv_handler, - new_serv_resp.start_handle + RSI_BLE_CHARACTERISTIC_RX_VALUE_HANDLE_LOCATION, custom_characteristic_RX, - RSI_BLE_ATT_PROPERTY_WRITE | RSI_BLE_ATT_PROPERTY_READ, // Set read, write, write without response - data, sizeof(data), ATT_REC_IN_HOST); - - static const uuid_t custom_characteristic_TX = { - .size = RSI_BLE_CUSTOM_CHARACTERISTIC_TX_SIZE, - .reserved = { RSI_BLE_CUSTOM_CHARACTERISTIC_TX_RESERVED }, - .val = { .val128 = { .data1 = { RSI_BLE_CUSTOM_CHARACTERISTIC_TX_VALUE_128_DATA_1 }, - .data2 = { RSI_BLE_CUSTOM_CHARACTERISTIC_TX_VALUE_128_DATA_2 }, - .data3 = { RSI_BLE_CUSTOM_CHARACTERISTIC_TX_VALUE_128_DATA_3 }, - .data4 = { RSI_BLE_CUSTOM_CHARACTERISTIC_TX_VALUE_128_DATA_4 } } } - }; - - // Adding custom characteristic declaration to the custom service - rsi_ble_add_char_serv_att( - new_serv_resp.serv_handler, new_serv_resp.start_handle + RSI_BLE_CHARACTERISTIC_TX_ATTRIBUTE_HANDLE_LOCATION, - RSI_BLE_ATT_PROPERTY_WRITE_NO_RESPONSE | RSI_BLE_ATT_PROPERTY_WRITE | RSI_BLE_ATT_PROPERTY_READ | - RSI_BLE_ATT_PROPERTY_NOTIFY | RSI_BLE_ATT_PROPERTY_INDICATE, // Set read, write, write without response - new_serv_resp.start_handle + RSI_BLE_CHARACTERISTIC_TX_MEASUREMENT_HANDLE_LOCATION, custom_characteristic_TX); - - // Adding characteristic value attribute to the service - bleEvent.eventData->rsi_ble_measurement_hndl = - new_serv_resp.start_handle + RSI_BLE_CHARACTERISTIC_TX_MEASUREMENT_HANDLE_LOCATION; - - // Adding characteristic value attribute to the service - bleEvent.eventData->rsi_ble_gatt_server_client_config_hndl = - new_serv_resp.start_handle + RSI_BLE_CHARACTERISTIC_TX_GATT_SERVER_CLIENT_HANDLE_LOCATION; - - rsi_ble_add_char_val_att(new_serv_resp.serv_handler, bleEvent.eventData->rsi_ble_measurement_hndl, custom_characteristic_TX, - RSI_BLE_ATT_PROPERTY_WRITE_NO_RESPONSE | RSI_BLE_ATT_PROPERTY_WRITE | RSI_BLE_ATT_PROPERTY_READ | - RSI_BLE_ATT_PROPERTY_NOTIFY | - RSI_BLE_ATT_PROPERTY_INDICATE, // Set read, write, write without response - data, sizeof(data), ATT_REC_MAINTAIN_IN_HOST); - - memset(&data, 0, sizeof(data)); - return 0; -} diff --git a/src/platform/silabs/rs911x/wfx_sl_ble_init.h b/src/platform/silabs/rs911x/wfx_sl_ble_init.h index 1e770de0727100..54351674ef121e 100644 --- a/src/platform/silabs/rs911x/wfx_sl_ble_init.h +++ b/src/platform/silabs/rs911x/wfx_sl_ble_init.h @@ -104,15 +104,13 @@ class SilabsBleWrapper rsi_ble_event_disconnect_t * resp_disconnect; rsi_ble_read_req_t * rsi_ble_read_req; rsi_ble_set_att_resp_t rsi_ble_event_set_att_rsp; - uint16_t rsi_ble_measurement_hndl; - uint16_t rsi_ble_gatt_server_client_config_hndl; uint16_t subscribed; }; struct BleEvent_t { BleEventType eventType; - sl_wfx_msg_t * eventData; + sl_wfx_msg_t eventData; }; // ALL Ble functions @@ -129,7 +127,6 @@ class SilabsBleWrapper uuid_t att_val_uuid); static void rsi_ble_add_char_val_att(void * serv_handler, uint16_t handle, uuid_t att_type_uuid, uint8_t val_prop, uint8_t * data, uint8_t data_len, uint8_t auth_read); - static uint32_t rsi_ble_add_matter_service(void); }; } // namespace Internal From a4a911c70bc3258077ce8a584ff55856d3e21dc5 Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Wed, 23 Oct 2024 13:35:15 -0400 Subject: [PATCH 086/149] Revert "Generate Conformance Data with Alchemy (#36186)" (#36220) This reverts commit 334c6693564dd9b33c62951c47a78d3676d5c473. --- .../chip/access-control-cluster.xml | 50 +- .../data-model/chip/account-login-cluster.xml | 11 +- .../zcl/data-model/chip/actions-cluster.xml | 33 +- .../administrator-commissioning-cluster.xml | 22 +- .../data-model/chip/air-quality-cluster.xml | 5 +- .../chip/application-basic-cluster.xml | 42 +- .../chip/application-launcher-cluster.xml | 18 +- .../data-model/chip/audio-output-cluster.xml | 16 +- .../chip/ballast-configuration-cluster.xml | 80 +- .../chip/basic-information-cluster.xml | 110 +- .../zcl/data-model/chip/binding-cluster.xml | 7 +- .../data-model/chip/boolean-state-cluster.xml | 8 +- .../boolean-state-configuration-cluster.xml | 81 +- .../zcl/data-model/chip/channel-cluster.xml | 53 +- .../data-model/chip/color-control-cluster.xml | 455 +---- .../chip/commissioner-control-cluster.xml | 5 - .../concentration-measurement-cluster.xml | 1184 ++++--------- .../chip/content-app-observer-cluster.xml | 2 - .../chip/content-control-cluster.xml | 86 +- .../chip/content-launch-cluster.xml | 30 +- .../data-model/chip/descriptor-cluster.xml | 29 +- .../chip/device-energy-management-cluster.xml | 95 +- .../device-energy-management-mode-cluster.xml | 12 +- .../chip/diagnostic-logs-cluster.xml | 86 +- .../chip/dishwasher-alarm-cluster.xml | 45 +- .../chip/dishwasher-mode-cluster.xml | 14 +- .../zcl/data-model/chip/door-lock-cluster.xml | 1514 +++++++---------- .../zcl/data-model/chip/drlc-cluster.xml | 39 +- .../electrical-energy-measurement-cluster.xml | 58 +- .../electrical-power-measurement-cluster.xml | 122 +- .../data-model/chip/energy-evse-cluster.xml | 151 +- .../chip/energy-evse-mode-cluster.xml | 12 +- .../chip/energy-preference-cluster.xml | 35 +- .../ethernet-network-diagnostics-cluster.xml | 73 +- .../data-model/chip/fixed-label-cluster.xml | 5 +- .../chip/flow-measurement-cluster.xml | 20 +- .../chip/general-commissioning-cluster.xml | 71 +- .../chip/general-diagnostics-cluster.xml | 60 +- .../chip/group-key-mgmt-cluster.xml | 26 +- .../zcl/data-model/chip/groups-cluster.xml | 17 +- .../chip/icd-management-cluster.xml | 260 ++- .../zcl/data-model/chip/identify-cluster.xml | 16 +- .../chip/illuminance-measurement-cluster.xml | 41 +- .../data-model/chip/keypad-input-cluster.xml | 2 - .../chip/laundry-dryer-controls-cluster.xml | 16 +- .../chip/laundry-washer-mode-cluster.xml | 14 +- .../data-model/chip/level-control-cluster.xml | 95 +- .../localization-configuration-cluster.xml | 6 +- .../zcl/data-model/chip/low-power-cluster.xml | 1 - .../data-model/chip/media-input-cluster.xml | 16 +- .../chip/media-playback-cluster.xml | 103 +- .../zcl/data-model/chip/messages-cluster.xml | 17 +- .../chip/microwave-oven-control-cluster.xml | 73 +- .../chip/microwave-oven-mode-cluster.xml | 10 +- .../data-model/chip/mode-select-cluster.xml | 34 +- .../chip/network-commissioning-cluster.xml | 261 +-- .../chip/occupancy-sensing-cluster.xml | 228 +-- .../zcl/data-model/chip/onoff-cluster.xml | 53 +- .../chip/operational-credentials-cluster.xml | 40 +- .../chip/operational-state-cluster.xml | 71 +- .../chip/operational-state-oven-cluster.xml | 53 +- .../chip/operational-state-rvc-cluster.xml | 74 +- .../zcl/data-model/chip/oven-mode-cluster.xml | 14 +- .../data-model/chip/power-source-cluster.xml | 234 +-- .../power-source-configuration-cluster.xml | 5 +- .../chip/power-topology-cluster.xml | 14 +- .../chip/pressure-measurement-cluster.xml | 57 +- ...pump-configuration-and-control-cluster.xml | 188 +- .../data-model/chip/refrigerator-alarm.xml | 28 +- ...rature-controlled-cabinet-mode-cluster.xml | 14 +- .../relative-humidity-measurement-cluster.xml | 20 +- .../chip/resource-monitoring-cluster.xml | 78 +- .../chip/rvc-clean-mode-cluster.xml | 12 +- .../data-model/chip/rvc-run-mode-cluster.xml | 12 +- .../zcl/data-model/chip/scene.xml | 34 +- .../data-model/chip/service-area-cluster.xml | 42 +- .../chip/smoke-co-alarm-cluster.xml | 91 +- .../chip/software-diagnostics-cluster.xml | 28 +- .../zcl/data-model/chip/switch-cluster.xml | 45 +- .../chip/target-navigator-cluster.xml | 15 +- .../chip/temperature-control-cluster.xml | 49 +- .../chip/temperature-measurement-cluster.xml | 20 +- .../data-model/chip/thermostat-cluster.xml | 310 +--- ...t-user-interface-configuration-cluster.xml | 11 +- ...hread-border-router-management-cluster.xml | 51 +- .../thread-network-diagnostics-cluster.xml | 408 +---- .../chip/thread-network-directory-cluster.xml | 109 +- .../chip/time-format-localization-cluster.xml | 21 +- .../chip/time-synchronization-cluster.xml | 118 +- .../chip/unit-localization-cluster.xml | 7 +- .../data-model/chip/user-label-cluster.xml | 1 - ...alve-configuration-and-control-cluster.xml | 71 +- .../data-model/chip/wake-on-lan-cluster.xml | 12 +- .../chip/washer-controls-cluster.xml | 30 +- .../chip/water-heater-management-cluster.xml | 40 +- .../chip/water-heater-mode-cluster.xml | 12 +- .../chip/wifi-network-diagnostics-cluster.xml | 87 +- .../chip/wifi-network-management-cluster.xml | 8 +- .../zcl/data-model/chip/window-covering.xml | 230 +-- 99 files changed, 2033 insertions(+), 6759 deletions(-) diff --git a/src/app/zap-templates/zcl/data-model/chip/access-control-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/access-control-cluster.xml index 831cc5b49361b0..edf1b65e941ad0 100644 --- a/src/app/zap-templates/zcl/data-model/chip/access-control-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/access-control-cluster.xml @@ -113,58 +113,29 @@ limitations under the License. ACL - Extension - - - - - SubjectsPerAccessControlEntry - - - - TargetsPerAccessControlEntry - - - - AccessControlEntriesPerFabric - - - - CommissioningARL - - - - - - ARL - - - - - + SubjectsPerAccessControlEntry + TargetsPerAccessControlEntry + AccessControlEntriesPerFabric + CommissioningARL + ARL + This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. - - - - + Returns the review token for the request, which can be used to correlate with a FabricRestrictionReviewUpdate event. - - - @@ -174,7 +145,6 @@ limitations under the License. - @@ -184,9 +154,6 @@ limitations under the License. - - - @@ -195,9 +162,6 @@ limitations under the License. - - - diff --git a/src/app/zap-templates/zcl/data-model/chip/account-login-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/account-login-cluster.xml index 38fcbcaaf9c5e4..baf74dc3c2e1da 100644 --- a/src/app/zap-templates/zcl/data-model/chip/account-login-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/account-login-cluster.xml @@ -28,36 +28,31 @@ limitations under the License. Upon receipt, the Content App checks if the account associated with the client Temp Account Identifier Rotating ID is the same acount that is active on the given Content App. If the accounts are the same, then the Content App includes the Setup PIN in the GetSetupPIN Response. - + - Upon receipt, the Content App checks if the account associated with the client’s Temp Account Identifier (Rotating ID) has a current active Setup PIN with the given value. If the Setup PIN is valid for the user account associated with the Temp Account Identifier, then the Content App MAY make that user account active. - + - - + The purpose of this command is to instruct the Content App to clear the current user account. This command SHOULD be used by clients of a Content App to indicate the end of a user session. - This message is sent in response to the GetSetupPIN Request, and contains the Setup PIN code, or null when the accounts identified in the request does not match the active account of the running Content App. - This event can be used by the Content App to indicate that the current user has logged out. In response to this event, the Fabric Admin SHALL remove access to this Content App by the specified Node. If no Node is provided, then the Fabric Admin SHALL remove access to all non-Admin Nodes. - diff --git a/src/app/zap-templates/zcl/data-model/chip/actions-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/actions-cluster.xml index bed60efdf50c65..acf28b88e46414 100644 --- a/src/app/zap-templates/zcl/data-model/chip/actions-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/actions-cluster.xml @@ -89,20 +89,11 @@ limitations under the License. 0x0025 ACTIONS_CLUSTER This cluster provides a standardized way for a Node (typically a Bridge, but could be any Node) to expose action information. - - - ActionList - - - - EndpointLists - - - - SetupURL - - - + + ActionList + EndpointLists + SetupURL + This command triggers an action (state change) on the involved endpoints. @@ -182,19 +173,17 @@ limitations under the License. This event SHALL be generated when there is a change in the Status of an ActionID. - - + + - This event SHALL be generated when there is some error which prevents the action from its normal planned execution. - - - - - + + + + diff --git a/src/app/zap-templates/zcl/data-model/chip/administrator-commissioning-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/administrator-commissioning-cluster.xml index 55a8310f0fa7ac..3532c89b931880 100644 --- a/src/app/zap-templates/zcl/data-model/chip/administrator-commissioning-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/administrator-commissioning-cluster.xml @@ -43,19 +43,10 @@ limitations under the License. - - WindowStatus - - - - AdminFabricIndex - - - - AdminVendorId - - - + WindowStatus + AdminFabricIndex + AdminVendorId + This command is used by a current Administrator to instruct a Node to go into commissioning mode using enhanced commissioning method. @@ -64,22 +55,17 @@ limitations under the License. - This command is used by a current Administrator to instruct a Node to go into commissioning mode using basic commissioning method, if the node supports it. - - - This command is used by a current Administrator to instruct a Node to revoke any active Open Commissioning Window or Open Basic Commissioning Window command. - diff --git a/src/app/zap-templates/zcl/data-model/chip/air-quality-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/air-quality-cluster.xml index 6b91830856441c..bbc57510e85dce 100644 --- a/src/app/zap-templates/zcl/data-model/chip/air-quality-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/air-quality-cluster.xml @@ -41,10 +41,7 @@ limitations under the License. - - AirQuality - - + AirQuality diff --git a/src/app/zap-templates/zcl/data-model/chip/application-basic-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/application-basic-cluster.xml index ea6be51e9bcb28..e6331f698fd423 100644 --- a/src/app/zap-templates/zcl/data-model/chip/application-basic-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/application-basic-cluster.xml @@ -24,38 +24,16 @@ limitations under the License. true true This cluster provides information about an application running on a TV or media player device which is represented as an endpoint. - - VendorName - - - - VendorID - - - - ApplicationName - - - - ProductID - - - - Application - - - - Status - - - - ApplicationVersion - - - - AllowedVendorList - - + VendorName + VendorID + ApplicationName + ProductID + Application + Status + ApplicationVersion + + AllowedVendorList + diff --git a/src/app/zap-templates/zcl/data-model/chip/application-launcher-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/application-launcher-cluster.xml index 34eb73fde5b351..50b715e138a744 100644 --- a/src/app/zap-templates/zcl/data-model/chip/application-launcher-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/application-launcher-cluster.xml @@ -31,41 +31,29 @@ limitations under the License. - - CatalogList - - - - - - CurrentApp - - - + CatalogList + CurrentApp + Upon receipt, this SHALL launch the specified app with optional data. The TV Device SHALL launch and bring to foreground the identified application in the command if the application is not already launched and in foreground. The TV Device SHALL update state attribute on the Application Basic cluster of the Endpoint corresponding to the launched application. This command returns a Launch Response. - Upon receipt on a Video Player endpoint this SHALL stop the specified application if it is running. - Upon receipt on a Video Player endpoint this SHALL hide the specified application if it is running and visible. - This command SHALL be generated in response to LaunchApp commands. - diff --git a/src/app/zap-templates/zcl/data-model/chip/audio-output-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/audio-output-cluster.xml index 0de5d0e3301de5..acaa9deadb6a3b 100644 --- a/src/app/zap-templates/zcl/data-model/chip/audio-output-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/audio-output-cluster.xml @@ -31,19 +31,12 @@ limitations under the License. - - OutputList - - - - CurrentOutput - - - + OutputList + CurrentOutput + Upon receipt, this SHALL change the output on the media device to the output at a specific index in the Output List. - @@ -51,9 +44,6 @@ limitations under the License. - - - diff --git a/src/app/zap-templates/zcl/data-model/chip/ballast-configuration-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/ballast-configuration-cluster.xml index 29ec1cd38108f3..32450208914a6d 100644 --- a/src/app/zap-templates/zcl/data-model/chip/ballast-configuration-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/ballast-configuration-cluster.xml @@ -41,75 +41,53 @@ limitations under the License. - - PhysicalMinLevel - - - - PhysicalMaxLevel - - - - BallastStatus - - + PhysicalMinLevel + PhysicalMaxLevel + BallastStatus - - MinLevel - - + + MinLevel + - - MaxLevel - - + + MaxLevel + - IntrinsicBallastFactor - - + IntrinsicBallastFactor + - - BallastFactorAdjustment - - + + BallastFactorAdjustment + - - LampQuantity - - + LampQuantity - LampType - - + LampType + - LampManufacturer - - + LampManufacturer + - - LampRatedHours - - + + LampRatedHours + - LampBurnHours - - + LampBurnHours + - LampAlarmMode - - + LampAlarmMode + - - LampBurnHoursTripPoint - - + + LampBurnHoursTripPoint + diff --git a/src/app/zap-templates/zcl/data-model/chip/basic-information-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/basic-information-cluster.xml index 288c82f950b8ab..7f6320a5880dc9 100644 --- a/src/app/zap-templates/zcl/data-model/chip/basic-information-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/basic-information-cluster.xml @@ -74,118 +74,52 @@ limitations under the License. which apply to the whole Node. Also allows setting user device information such as location. - - DataModelRevision - - - - VendorName - - - - VendorID - - - - ProductName - - - - ProductID - - - + DataModelRevision + VendorName + VendorID + ProductName + ProductID + NodeLabel - Location - - - - HardwareVersion - - - - HardwareVersionString - - - - SoftwareVersion - - - - SoftwareVersionString - - - - ManufacturingDate - - - PartNumber - - - - ProductURL - - - - ProductLabel - - - - SerialNumber - - - + HardwareVersion + HardwareVersionString + SoftwareVersion + SoftwareVersionString + ManufacturingDate + PartNumber + ProductURL + ProductLabel + SerialNumber + LocalConfigDisabled - - - - Reachable - - - - UniqueID - - - - CapabilityMinima - - - - ProductAppearance - - - - SpecificationVersion - - - - MaxPathsPerInvoke - + Reachable + UniqueID + CapabilityMinima + ProductAppearance + SpecificationVersion + MaxPathsPerInvoke The StartUp event SHALL be emitted by a Node as soon as reasonable after completing a boot or reboot process. - The ShutDown event SHOULD be emitted by a Node prior to any orderly shutdown sequence on a best-effort basis. - The Leave event SHOULD be emitted by a Node prior to permanently leaving the Fabric. - This event (when supported) SHALL be generated when there is a change in the Reachable attribute. diff --git a/src/app/zap-templates/zcl/data-model/chip/binding-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/binding-cluster.xml index 0b1cbd0c560091..741a5a9372edc0 100644 --- a/src/app/zap-templates/zcl/data-model/chip/binding-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/binding-cluster.xml @@ -31,10 +31,9 @@ limitations under the License. 0x001e BINDING_CLUSTER The Binding Cluster is meant to replace the support from the Zigbee Device Object (ZDO) for supporting the binding table. - - Binding - - + + Binding + diff --git a/src/app/zap-templates/zcl/data-model/chip/boolean-state-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/boolean-state-cluster.xml index 30a16e16bcc0b0..0dee692affacee 100644 --- a/src/app/zap-templates/zcl/data-model/chip/boolean-state-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/boolean-state-cluster.xml @@ -26,15 +26,11 @@ limitations under the License. true true - - StateValue - - - + StateValue + This event SHALL be generated when the StateValue attribute changes. - diff --git a/src/app/zap-templates/zcl/data-model/chip/boolean-state-configuration-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/boolean-state-configuration-cluster.xml index 85705e6a03050e..4fb33dd9749a0e 100644 --- a/src/app/zap-templates/zcl/data-model/chip/boolean-state-configuration-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/boolean-state-configuration-cluster.xml @@ -58,97 +58,34 @@ limitations under the License. - - CurrentSensitivityLevel - - - - - - SupportedSensitivityLevels - - - - - - DefaultSensitivityLevel - - - - - - AlarmsActive - - - - - - - - - AlarmsSuppressed - - - - - - AlarmsEnabled - - - - - - - - - AlarmsSupported - - - - - - - - - SensorFault - - - + CurrentSensitivityLevel + SupportedSensitivityLevels + DefaultSensitivityLevel + AlarmsActive + AlarmsSuppressed + AlarmsEnabled + AlarmsSupported + SensorFault + This command is used to suppress the specified alarm mode. - - - This command is used to enable or disable the specified alarm mode. - - - - - - This event SHALL be generated when any bits in the AlarmsActive and/or AlarmsSuppressed attributes change. - - - - - - This event SHALL be generated when the device registers or clears a fault. - diff --git a/src/app/zap-templates/zcl/data-model/chip/channel-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/channel-cluster.xml index c3a08ab084359b..25ec7b7062f97a 100644 --- a/src/app/zap-templates/zcl/data-model/chip/channel-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/channel-cluster.xml @@ -41,57 +41,30 @@ limitations under the License. - - ChannelList - - - - - - Lineup - - - - - - CurrentChannel - - - + ChannelList + Lineup + CurrentChannel + Change the channel on the media player to the channel case-insensitive exact matching the value passed as an argument. - - - - - - Change the channel on the media plaeyer to the channel with the given Number in the ChannelList attribute. - This command provides channel up and channel down functionality, but allows channel index jumps of size Count. When the value of the increase or decrease is larger than the number of channels remaining in the given direction, then the behavior SHALL be to return to the beginning (or end) of the channel list and continue. For example, if the current channel is at index 0 and count value of -1 is given, then the current channel should change to the last channel. - Upon receipt, this SHALL display the active status of the input list on screen. - - - - - - @@ -103,18 +76,12 @@ limitations under the License. - - - This command is a response to the GetProgramGuide command. - - - @@ -123,12 +90,6 @@ limitations under the License. - - - - - - @@ -137,12 +98,6 @@ limitations under the License. - - - - - - diff --git a/src/app/zap-templates/zcl/data-model/chip/color-control-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/color-control-cluster.xml index a479da36375e4f..3623ce1ccf925c 100644 --- a/src/app/zap-templates/zcl/data-model/chip/color-control-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/color-control-cluster.xml @@ -127,401 +127,135 @@ limitations under the License. - - CurrentHue - - - - + CurrentHue - - CurrentSaturation - - - - + CurrentSaturation - - RemainingTime - - + RemainingTime - - CurrentX - - - - + CurrentX - - CurrentY - - - - + CurrentY - - DriftCompensation - - + DriftCompensation - - CompensationText - - + CompensationText - - ColorTemperatureMireds - - - - + ColorTemperatureMireds - - ColorMode - - + ColorMode - - Options - - + Options - - NumberOfPrimaries - - + NumberOfPrimaries - - Primary1X - - - - - - - - - - + Primary1X - - Primary1Y - - - - - - - - - - + Primary1Y - - Primary1Intensity - - - - - - - - - - + Primary1Intensity - - Primary2X - - - - - - - - - - + Primary2X - - Primary2Y - - - - - - - - - - + Primary2Y - - Primary2Intensity - - - - - - - - - - + Primary2Intensity - - Primary3X - - - - - - - - - - + Primary3X - - Primary3Y - - - - - - - - - - + Primary3Y - - Primary3Intensity - - - - - - - - - - + Primary3Intensity - - Primary4X - - - - - - - - - - + Primary4X - - Primary4Y - - - - - - - - - - + Primary4Y - - Primary4Intensity - - - - - - - - - - + Primary4Intensity - - Primary5X - - - - - - - - - - + Primary5X - - Primary5Y - - - - - - - - - - + Primary5Y - - Primary5Intensity - - - - - - - - - - + Primary5Intensity - - Primary6X - - - - - - - - - - + Primary6X - - Primary6Y - - - - - - - - - - + Primary6Y - - Primary6Intensity - - - - - - - - - - + Primary6Intensity WhitePointX - WhitePointY - ColorPointRX - ColorPointRY - ColorPointRIntensity - ColorPointGX - ColorPointGY - ColorPointGIntensity - ColorPointBX - ColorPointBY - ColorPointBIntensity - - - CoupleColorTempToLevelMinMireds - - - - - - - - + CoupleColorTempToLevelMinMireds + StartUpColorTemperatureMireds - - - - - - @@ -533,9 +267,6 @@ limitations under the License. - - - @@ -546,9 +277,6 @@ limitations under the License. - - - @@ -560,9 +288,6 @@ limitations under the License. - - - @@ -573,9 +298,6 @@ limitations under the License. - - - @@ -586,9 +308,6 @@ limitations under the License. - - - @@ -600,9 +319,6 @@ limitations under the License. - - - @@ -614,9 +330,6 @@ limitations under the License. - - - @@ -628,9 +341,6 @@ limitations under the License. - - - @@ -641,9 +351,6 @@ limitations under the License. - - - @@ -655,9 +362,6 @@ limitations under the License. - - - @@ -668,69 +372,20 @@ limitations under the License. - - - - - EnhancedCurrentHue - - - - - - EnhancedColorMode - - - - ColorLoopActive - - - - - - ColorLoopDirection - - - - - - ColorLoopTime - - - - - - ColorLoopStartEnhancedHue - - - - - - ColorLoopStoredEnhancedHue - - - - - - ColorCapabilities - - - - ColorTempPhysicalMinMireds - - - - - - ColorTempPhysicalMaxMireds - - - - + EnhancedCurrentHue + EnhancedColorMode + ColorLoopActive + ColorLoopDirection + ColorLoopTime + ColorLoopStartEnhancedHue + ColorLoopStoredEnhancedHue + ColorCapabilities + ColorTempPhysicalMinMireds + ColorTempPhysicalMaxMireds @@ -741,9 +396,6 @@ limitations under the License. - - - @@ -754,9 +406,6 @@ limitations under the License. - - - @@ -768,9 +417,6 @@ limitations under the License. - - - @@ -782,9 +428,6 @@ limitations under the License. - - - @@ -798,9 +441,6 @@ limitations under the License. - - - @@ -809,13 +449,6 @@ limitations under the License. - - - - - - - @@ -828,9 +461,6 @@ limitations under the License. - - - @@ -844,9 +474,6 @@ limitations under the License. - - - diff --git a/src/app/zap-templates/zcl/data-model/chip/commissioner-control-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/commissioner-control-cluster.xml index 33f26e3689e5f4..dcfb1dfa7096b8 100644 --- a/src/app/zap-templates/zcl/data-model/chip/commissioner-control-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/commissioner-control-cluster.xml @@ -35,7 +35,6 @@ limitations under the License. SupportedDeviceCategories - @@ -45,7 +44,6 @@ limitations under the License. - @@ -53,7 +51,6 @@ limitations under the License. - @@ -63,7 +60,6 @@ limitations under the License. - @@ -72,7 +68,6 @@ limitations under the License. - diff --git a/src/app/zap-templates/zcl/data-model/chip/concentration-measurement-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/concentration-measurement-cluster.xml index e2116fc03cc80c..4d03c539103970 100644 --- a/src/app/zap-templates/zcl/data-model/chip/concentration-measurement-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/concentration-measurement-cluster.xml @@ -58,70 +58,17 @@ limitations under the License. - - MeasuredValue - - - - - - MinMeasuredValue - - - - - - MaxMeasuredValue - - - - - - PeakMeasuredValue - - - - - - PeakMeasuredValueWindow - - - - - - AverageMeasuredValue - - - - - - AverageMeasuredValueWindow - - - - - - Uncertainty - - - - - - MeasurementUnit - - - - - - MeasurementMedium - - - - LevelValue - - - - + MeasuredValue + MinMeasuredValue + MaxMeasuredValue + PeakMeasuredValue + PeakMeasuredValueWindow + AverageMeasuredValue + AverageMeasuredValueWindow + Uncertainty + MeasurementUnit + MeasurementMedium + LevelValue @@ -166,70 +113,17 @@ limitations under the License. - - MeasuredValue - - - - - - MinMeasuredValue - - - - - - MaxMeasuredValue - - - - - - PeakMeasuredValue - - - - - - PeakMeasuredValueWindow - - - - - - AverageMeasuredValue - - - - - - AverageMeasuredValueWindow - - - - - - Uncertainty - - - - - - MeasurementUnit - - - - - - MeasurementMedium - - - - LevelValue - - - - + MeasuredValue + MinMeasuredValue + MaxMeasuredValue + PeakMeasuredValue + PeakMeasuredValueWindow + AverageMeasuredValue + AverageMeasuredValueWindow + Uncertainty + MeasurementUnit + MeasurementMedium + LevelValue @@ -245,98 +139,45 @@ limitations under the License. - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + - - MeasuredValue - - - - - - MinMeasuredValue - - - - - - MaxMeasuredValue - - - - - - PeakMeasuredValue - - - - - - PeakMeasuredValueWindow - - - - - - AverageMeasuredValue - - - - - - AverageMeasuredValueWindow - - - - - - Uncertainty - - - - - - MeasurementUnit - - - - - - MeasurementMedium - - - - LevelValue - - - - + MeasuredValue + MinMeasuredValue + MaxMeasuredValue + PeakMeasuredValue + PeakMeasuredValueWindow + AverageMeasuredValue + AverageMeasuredValueWindow + Uncertainty + MeasurementUnit + MeasurementMedium + LevelValue @@ -352,98 +193,45 @@ limitations under the License. - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + - - MeasuredValue - - - - - - MinMeasuredValue - - - - - - MaxMeasuredValue - - - - - - PeakMeasuredValue - - - - - - PeakMeasuredValueWindow - - - - - - AverageMeasuredValue - - - - - - AverageMeasuredValueWindow - - - - - - Uncertainty - - - - - - MeasurementUnit - - - - - - MeasurementMedium - - - - LevelValue - - - - + MeasuredValue + MinMeasuredValue + MaxMeasuredValue + PeakMeasuredValue + PeakMeasuredValueWindow + AverageMeasuredValue + AverageMeasuredValueWindow + Uncertainty + MeasurementUnit + MeasurementMedium + LevelValue @@ -459,98 +247,45 @@ limitations under the License. - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + - - MeasuredValue - - - - - - MinMeasuredValue - - - - - - MaxMeasuredValue - - - - - - PeakMeasuredValue - - - - - - PeakMeasuredValueWindow - - - - - - AverageMeasuredValue - - - - - - AverageMeasuredValueWindow - - - - - - Uncertainty - - - - - - MeasurementUnit - - - - - - MeasurementMedium - - - - LevelValue - - - - + MeasuredValue + MinMeasuredValue + MaxMeasuredValue + PeakMeasuredValue + PeakMeasuredValueWindow + AverageMeasuredValue + AverageMeasuredValueWindow + Uncertainty + MeasurementUnit + MeasurementMedium + LevelValue @@ -566,98 +301,45 @@ limitations under the License. - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + - - MeasuredValue - - - - - - MinMeasuredValue - - - - - - MaxMeasuredValue - - - - - - PeakMeasuredValue - - - - - - PeakMeasuredValueWindow - - - - - - AverageMeasuredValue - - - - - - AverageMeasuredValueWindow - - - - - - Uncertainty - - - - - - MeasurementUnit - - - - - - MeasurementMedium - - - - LevelValue - - - - + MeasuredValue + MinMeasuredValue + MaxMeasuredValue + PeakMeasuredValue + PeakMeasuredValueWindow + AverageMeasuredValue + AverageMeasuredValueWindow + Uncertainty + MeasurementUnit + MeasurementMedium + LevelValue @@ -673,98 +355,45 @@ limitations under the License. - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + - - MeasuredValue - - - - - - MinMeasuredValue - - - - - - MaxMeasuredValue - - - - - - PeakMeasuredValue - - - - - - PeakMeasuredValueWindow - - - - - - AverageMeasuredValue - - - - - - AverageMeasuredValueWindow - - - - - - Uncertainty - - - - - - MeasurementUnit - - - - - - MeasurementMedium - - - - LevelValue - - - - + MeasuredValue + MinMeasuredValue + MaxMeasuredValue + PeakMeasuredValue + PeakMeasuredValueWindow + AverageMeasuredValue + AverageMeasuredValueWindow + Uncertainty + MeasurementUnit + MeasurementMedium + LevelValue @@ -780,98 +409,45 @@ limitations under the License. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - MeasuredValue - - - - - - MinMeasuredValue - - - - - - MaxMeasuredValue - - - - - - PeakMeasuredValue - - - - - - PeakMeasuredValueWindow - - - - - - AverageMeasuredValue - - - - - - AverageMeasuredValueWindow - - - - - - Uncertainty - - - - - - MeasurementUnit - - - - - - MeasurementMedium - - - - LevelValue - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + MeasuredValue + MinMeasuredValue + MaxMeasuredValue + PeakMeasuredValue + PeakMeasuredValueWindow + AverageMeasuredValue + AverageMeasuredValueWindow + Uncertainty + MeasurementUnit + MeasurementMedium + LevelValue @@ -887,98 +463,45 @@ limitations under the License. - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + - - MeasuredValue - - - - - - MinMeasuredValue - - - - - - MaxMeasuredValue - - - - - - PeakMeasuredValue - - - - - - PeakMeasuredValueWindow - - - - - - AverageMeasuredValue - - - - - - AverageMeasuredValueWindow - - - - - - Uncertainty - - - - - - MeasurementUnit - - - - - - MeasurementMedium - - - - LevelValue - - - - + MeasuredValue + MinMeasuredValue + MaxMeasuredValue + PeakMeasuredValue + PeakMeasuredValueWindow + AverageMeasuredValue + AverageMeasuredValueWindow + Uncertainty + MeasurementUnit + MeasurementMedium + LevelValue @@ -994,98 +517,45 @@ limitations under the License. - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + - - MeasuredValue - - - - - - MinMeasuredValue - - - - - - MaxMeasuredValue - - - - - - PeakMeasuredValue - - - - - - PeakMeasuredValueWindow - - - - - - AverageMeasuredValue - - - - - - AverageMeasuredValueWindow - - - - - - Uncertainty - - - - - - MeasurementUnit - - - - - - MeasurementMedium - - - - LevelValue - - - - + MeasuredValue + MinMeasuredValue + MaxMeasuredValue + PeakMeasuredValue + PeakMeasuredValueWindow + AverageMeasuredValue + AverageMeasuredValueWindow + Uncertainty + MeasurementUnit + MeasurementMedium + LevelValue diff --git a/src/app/zap-templates/zcl/data-model/chip/content-app-observer-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/content-app-observer-cluster.xml index 0f5a99b6ba9266..6e241c7b5c3cd0 100644 --- a/src/app/zap-templates/zcl/data-model/chip/content-app-observer-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/content-app-observer-cluster.xml @@ -29,7 +29,6 @@ limitations under the License. Upon receipt, the data field MAY be parsed and interpreted. Message encoding is specific to the Content App. A Content App MAY when possible read attributes from the Basic Information Cluster on the Observer and use this to determine the Message encoding. - @@ -37,7 +36,6 @@ limitations under the License. - diff --git a/src/app/zap-templates/zcl/data-model/chip/content-control-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/content-control-cluster.xml index e42967b581fac6..06468c114c42dc 100644 --- a/src/app/zap-templates/zcl/data-model/chip/content-control-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/content-control-cluster.xml @@ -43,139 +43,69 @@ limitations under the License. - - Enabled - - - - OnDemandRatings - - - - - - OnDemandRatingThreshold - - - - - - ScheduledContentRatings - - - - - - ScheduledContentRatingThreshold - - - - - - ScreenDailyTime - - - - - - RemainingScreenTime - - - - - - BlockUnrated - - - - + Enabled + OnDemandRatings + OnDemandRatingThreshold + ScheduledContentRatings + ScheduledContentRatingThreshold + ScreenDailyTime + RemainingScreenTime + BlockUnrated The purpose of this command is to update the PIN used for protecting configuration of the content control settings. Upon success, the old PIN SHALL no longer work. The PIN is used to ensure that only the Node (or User) with the PIN code can make changes to the Content Control settings, for example, turn off Content Controls or modify the ScreenDailyTime. The PIN is composed of a numeric string of up to 6 human readable characters (displayable) . Upon receipt of this command, the media device SHALL check if the OldPIN field of this command is the same as the current PIN. If the PINs are the same, then the PIN code SHALL be set to NewPIN. Otherwise a response with InvalidPINCode error status SHALL be returned. The media device MAY provide a default PIN to the User via an out of band mechanism. For security reasons, it is recommended that a client encourage the user to update the PIN from its default value when performing configuration of the Content Control settings exposed by this cluster. The ResetPIN command can also be used to obtain the default PIN. - - - The purpose of this command is to reset the PIN. If this command is executed successfully, a ResetPINResponse command with a new PIN SHALL be returned. - - - This command SHALL be generated in response to a ResetPIN command. The data for this command SHALL be as follows: - - - The purpose of this command is to turn on the Content Control feature on a media device. On receipt of the Enable command, the media device SHALL set the Enabled attribute to TRUE. - The purpose of this command is to turn off the Content Control feature on a media device. On receipt of the Disable command, the media device SHALL set the Enabled attribute to FALSE. - The purpose of this command is to add the extra screen time for the user. If a client with Operate privilege invokes this command, the media device SHALL check whether the PINCode passed in the command matches the current PINCode value. If these match, then the RemainingScreenTime attribute SHALL be increased by the specified BonusTime value. If the PINs do not match, then a response with InvalidPINCode error status SHALL be returned, and no changes SHALL be made to RemainingScreenTime. If a client with Manage privilege or greater invokes this command, the media device SHALL ignore the PINCode field and directly increase the RemainingScreenTime attribute by the specified BonusTime value. A server that does not support the PM feature SHALL respond with InvalidPINCode to clients that only have Operate privilege unless: It has been provided with the PIN value to expect via an out of band mechanism, and The client has provided a PINCode that matches the expected PIN value. - - - The purpose of this command is to set the ScreenDailyTime attribute. On receipt of the SetScreenDailyTime command, the media device SHALL set the ScreenDailyTime attribute to the ScreenTime value. - - - The purpose of this command is to specify whether programs with no Content rating must be blocked by this media device. On receipt of the BlockUnratedContent command, the media device SHALL set the BlockUnrated attribute to TRUE. - - - The purpose of this command is to specify whether programs with no Content rating must be blocked by this media device. On receipt of the UnblockUnratedContent command, the media device SHALL set the BlockUnrated attribute to FALSE. - - - The purpose of this command is to set the OnDemandRatingThreshold attribute. On receipt of the SetOnDemandRatingThreshold command, the media device SHALL check if the Rating field is one of values present in the OnDemandRatings attribute. If not, then a response with InvalidRating error status SHALL be returned. - - - The purpose of this command is to set ScheduledContentRatingThreshold attribute. On receipt of the SetScheduledContentRatingThreshold command, the media device SHALL check if the Rating field is one of values present in the ScheduledContentRatings attribute. If not, then a response with InvalidRating error status SHALL be returned. - - - This event SHALL be generated when the RemainingScreenTime equals 0. - - - diff --git a/src/app/zap-templates/zcl/data-model/chip/content-launch-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/content-launch-cluster.xml index 31ad15a48b93ac..7058f969799087 100644 --- a/src/app/zap-templates/zcl/data-model/chip/content-launch-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/content-launch-cluster.xml @@ -25,20 +25,10 @@ limitations under the License. true This cluster provides an interface for launching content on a media player device such as a TV or Speaker. - - - AcceptHeader - - - - - - SupportedStreamingProtocols - - - - - + + AcceptHeader + SupportedStreamingProtocols + Upon receipt, this SHALL launch the specified content with optional search criteria. @@ -46,9 +36,6 @@ limitations under the License. - - - @@ -56,21 +43,12 @@ limitations under the License. - - - This command SHALL be generated in response to LaunchContent command. - - - - - - diff --git a/src/app/zap-templates/zcl/data-model/chip/descriptor-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/descriptor-cluster.xml index f34d705a2486da..d63dbeb05ca11a 100644 --- a/src/app/zap-templates/zcl/data-model/chip/descriptor-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/descriptor-cluster.xml @@ -44,28 +44,11 @@ limitations under the License. - - - DeviceTypeList - - - - ServerList - - - - ClientList - - - - PartsList - - - - TagList - - - - + + DeviceTypeList + ServerList + ClientList + PartsList + TagList diff --git a/src/app/zap-templates/zcl/data-model/chip/device-energy-management-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/device-energy-management-cluster.xml index 250e3546ea8805..3550dd0301be99 100644 --- a/src/app/zap-templates/zcl/data-model/chip/device-energy-management-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/device-energy-management-cluster.xml @@ -74,95 +74,41 @@ Git: 1.4-prerelease-ipr-69-ge15ff5700 - - ESAType - - - - ESACanGenerate - - - - ESAState - - - - AbsMinPower - - - - AbsMaxPower - - + ESAType + ESACanGenerate + ESAState + AbsMinPower + AbsMaxPower - - PowerAdjustmentCapability - - - - + PowerAdjustmentCapability - - Forecast - - - - - - - - - OptOutState - - - - - - - - - - + Forecast + OptOutState Allows a client to request an adjustment in the power consumption of an ESA for a specified duration. - - - Allows a client to cancel an ongoing PowerAdjustmentRequest operation. - - - Allows a client to adjust the start time of a Forecast sequence that has not yet started operation (i.e. where the current Forecast StartTime is in the future). - - - Allows a client to temporarily pause an operation and reduce the ESAs energy demand. - - - Allows a client to cancel the PauseRequest command and enable earlier resumption of operation. - - - @@ -170,36 +116,20 @@ Git: 1.4-prerelease-ipr-69-ge15ff5700 - - - Allows a client to ask the ESA to recompute its Forecast based on power and time constraints. - - - Allows a client to request cancellation of a previous adjustment request in a StartTimeAdjustRequest, ModifyForecastRequest or RequestConstraintBasedForecast command. - - - - - - - This event SHALL be generated when the Power Adjustment session is started. - - - @@ -207,24 +137,15 @@ Git: 1.4-prerelease-ipr-69-ge15ff5700 - - - This event SHALL be generated when the ESA enters the Paused state. - - - This event SHALL be generated when the ESA leaves the Paused state and resumes operation. - - - diff --git a/src/app/zap-templates/zcl/data-model/chip/device-energy-management-mode-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/device-energy-management-mode-cluster.xml index 470040b5c4f476..c3440adebef3f6 100644 --- a/src/app/zap-templates/zcl/data-model/chip/device-energy-management-mode-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/device-energy-management-mode-cluster.xml @@ -59,26 +59,18 @@ Git: 1.4-prerelease-ipr-69-ge15ff5700 - - SupportedModes - - - - CurrentMode - - + SupportedModes + CurrentMode This command is used to change device modes. - This command is sent by the device on receipt of the ChangeToMode command. - diff --git a/src/app/zap-templates/zcl/data-model/chip/diagnostic-logs-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/diagnostic-logs-cluster.xml index 4140fd18a0eaec..27162f66e5e6db 100644 --- a/src/app/zap-templates/zcl/data-model/chip/diagnostic-logs-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/diagnostic-logs-cluster.xml @@ -15,48 +15,46 @@ See the License for the specific language governing permissions and limitations under the License. --> - - - - - - - - - - - - - - - - - - - - - - Diagnostic Logs - CHIP - The cluster provides commands for retrieving unstructured diagnostic logs from a Node that may be used to aid in diagnostics. - 0x0032 - DIAGNOSTIC_LOGS_CLUSTER - true - true - - Retrieving diagnostic logs from a Node - - - - - - - Response to the RetrieveLogsRequest - - - - - - - + + + + + + + + + + + + + + + + + + + + + + Diagnostic Logs + CHIP + The cluster provides commands for retrieving unstructured diagnostic logs from a Node that may be used to aid in diagnostics. + 0x0032 + DIAGNOSTIC_LOGS_CLUSTER + true + true + + Retrieving diagnostic logs from a Node + + + + + + Response to the RetrieveLogsRequest + + + + + + diff --git a/src/app/zap-templates/zcl/data-model/chip/dishwasher-alarm-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/dishwasher-alarm-cluster.xml index a8cf1e166219e2..7e41a7a1c03f99 100644 --- a/src/app/zap-templates/zcl/data-model/chip/dishwasher-alarm-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/dishwasher-alarm-cluster.xml @@ -43,46 +43,27 @@ limitations under the License. - - Mask - - - - Latch - - - - - - State - - - - Supported - - + Mask + Latch + State + Supported - Reset alarm - - - - + Reset alarm + - Modify enabled alarms - - + Modify enabled alarms + - Notify - - - - - + Notify + + + + diff --git a/src/app/zap-templates/zcl/data-model/chip/dishwasher-mode-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/dishwasher-mode-cluster.xml index 7cc15557f0c5a1..7c7dec635f3b6c 100644 --- a/src/app/zap-templates/zcl/data-model/chip/dishwasher-mode-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/dishwasher-mode-cluster.xml @@ -57,17 +57,11 @@ limitations under the License. - - SupportedModes - - - - CurrentMode - - + SupportedModes + CurrentMode StartUpMode OnMode - + @@ -75,7 +69,6 @@ limitations under the License. On receipt of this command the device SHALL respond with a ChangeToModeResponse command. - @@ -84,7 +77,6 @@ limitations under the License. - diff --git a/src/app/zap-templates/zcl/data-model/chip/door-lock-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/door-lock-cluster.xml index f16bbbf28bbbba..b25cd549d90091 100644 --- a/src/app/zap-templates/zcl/data-model/chip/door-lock-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/door-lock-cluster.xml @@ -131,901 +131,659 @@ limitations under the License. 3. Everything that depends on a certain feature is optional because we have no way of setting up the dependencies here. Dependencies would be probably resolved in the cluster itself. Those attributes/commands are marked with a special comment. --> - - - - LockState - - - - LockType - - - - ActuatorEnabled - - - - - DoorState - - - - - - - DoorOpenEvents - - - - - - - - - DoorClosedEvents - - - - - - - - - OpenPeriod - - - - - - - - - NumberOfTotalUsersSupported - - - - - - - NumberOfPINUsersSupported - - - - - - - NumberOfRFIDUsersSupported - - - - - - - NumberOfWeekDaySchedulesSupportedPerUser - - - - - - - NumberOfYearDaySchedulesSupportedPerUser - - - - - - - NumberOfHolidaySchedulesSupported - - - - - - - MaxPINCodeLength - - - - - - - MinPINCodeLength - - - - - - - MaxRFIDCodeLength - - - - - - - MinRFIDCodeLength - - - - - - - CredentialRulesSupport - - - - - - - NumberOfCredentialsSupportedPerUser - - - - - - Language - - - - - - LEDSettings - - - - - - AutoRelockTime - - - - - - SoundVolume - - - - - - OperatingMode - - - - - - SupportedOperatingModes - - - - DefaultConfigurationRegister - - - - EnableLocalProgramming - - - - - - EnableOneTouchLocking - - - - - - EnableInsideStatusLED - - - - - - EnablePrivacyModeButton - - - - - - LocalProgrammingFeatures - - - - - - - WrongCodeEntryLimit - - - - - - - - - - - - UserCodeTemporaryDisableTime - - - - - - - - - - - - SendPINOverTheAir - - - - - - - - - - - - - - RequirePINforRemoteOperation - - - - - - - - - - - - - ExpiringUserTimeout - - - - - - - - - AliroReaderVerificationKey - - - - - - - - AliroReaderGroupIdentifier - - - - - - - - AliroReaderGroupSubIdentifier - - - - - - - - AliroExpeditedTransactionSupportedProtocolVersions - - - - - - - - AliroGroupResolvingKey - - - - - - - - AliroSupportedBLEUWBProtocolVersions - - - - - - - - AliroBLEAdvertisingVersion - - - - - - - - NumberOfAliroCredentialIssuerKeysSupported - - - - - - - NumberOfAliroEndpointKeysSupported - - - - - - - This command causes the lock device to lock the door. - - - - - - This command causes the lock device to unlock the door. - - - - - - - This command causes the lock device to unlock the door with a timeout parameter. - - - - - - - - Set a weekly repeating schedule for a specified user. - - - - - - - - - - - - - - - Retrieve the specific weekly schedule for the specific user. - - - - - - - - - - Returns the weekly repeating schedule data for the specified schedule index. - - - - - - - - - - - - - - - Clear the specific weekly schedule or all weekly schedules for the specific user. - - - - - - - - - - Set a time-specific schedule ID for a specified user. - - - - - - - - - - - - Returns the year day schedule data for the specified schedule and user indexes. - - - - - - - - - - Returns the year day schedule data for the specified schedule and user indexes. - - - - - - - - - - - - Clears the specific year day schedule or all year day schedules for the specific user. - - - - - - - - - - Set the holiday Schedule by specifying local start time and local end time with respect to any Lock Operating Mode. - - - - - - - - - - - - Get the holiday schedule for the specified index. - - - - - - - - - Returns the Holiday Schedule Entry for the specified Holiday ID. - - - - - - - - - - - - Clears the holiday schedule or all holiday schedules. - - - - - - - - - Set User into the lock. - - - - - - - - - - - - - - - Retrieve User. - - - - - - - - - Returns the User for the specified UserIndex. - - - - - - - - - - - - - - - - - Clears a User or all Users. - - - - - - - - - Set a credential (e.g. PIN, RFID, Fingerprint, etc.) into the lock for a new user, existing user, or ProgrammingUser. - - - - - - - - - - - - - - Returns the status for setting the specified credential. - - - - - - - - - - Retrieve the status of a particular credential (e.g. PIN, RFID, Fingerprint, etc.) by index. - - - - - - - - - Returns the status for the specified credential. - - - - - - - - - - - - - Clear one, one type, or all credentials except ProgrammingPIN credential. - - - - - - - - This command causes the lock device to unlock the door without pulling the latch. - - - - - - - - This command communicates an Aliro Reader configuration to the lock. - - - - - - - - - - - This command clears an existing Aliro Reader configuration for the lock. - - - - - + + LockState + LockType + ActuatorEnabled + + DoorState + + + DoorOpenEvents + + + + + + DoorClosedEvents + + + + + + OpenPeriod + + + + + NumberOfTotalUsersSupported + + NumberOfPINUsersSupported + + NumberOfRFIDUsersSupported + + NumberOfWeekDaySchedulesSupportedPerUser + + NumberOfYearDaySchedulesSupportedPerUser + + NumberOfHolidaySchedulesSupported + + MaxPINCodeLength + + MinPINCodeLength + + MaxRFIDCodeLength + + MinRFIDCodeLength + + CredentialRulesSupport + + NumberOfCredentialsSupportedPerUser + + Language + + + + + LEDSettings + + + + + AutoRelockTime + + + + + SoundVolume + + + + + OperatingMode + + + + SupportedOperatingModes + DefaultConfigurationRegister + + EnableLocalProgramming + + + + + EnableOneTouchLocking + + + + + EnableInsideStatusLED + + + + + EnablePrivacyModeButton + + + + + LocalProgrammingFeatures + + + + + + WrongCodeEntryLimit + + + + + + UserCodeTemporaryDisableTime + + + + + + SendPINOverTheAir + + + + + + RequirePINforRemoteOperation + + + + + + + ExpiringUserTimeout + + + + + + AliroReaderVerificationKey + + + + + AliroReaderGroupIdentifier + + + + + AliroReaderGroupSubIdentifier + + + + + AliroExpeditedTransactionSupportedProtocolVersions + + + + + AliroGroupResolvingKey + + + + + AliroSupportedBLEUWBProtocolVersions + + + + + AliroBLEAdvertisingVersion + + + + NumberOfAliroCredentialIssuerKeysSupported + + NumberOfAliroEndpointKeysSupported + + + + This command causes the lock device to lock the door. + + + + + This command causes the lock device to unlock the door. + + + + + + This command causes the lock device to unlock the door with a timeout parameter. + + + + + + + Set a weekly repeating schedule for a specified user. + + + + + + + + + + + + Retrieve the specific weekly schedule for the specific user. + + + + + + + Returns the weekly repeating schedule data for the specified schedule index. + + + + + + + + + + + + Clear the specific weekly schedule or all weekly schedules for the specific user. + + + + + + + Set a time-specific schedule ID for a specified user. + + + + + + + + + Returns the year day schedule data for the specified schedule and user indexes. + + + + + + + Returns the year day schedule data for the specified schedule and user indexes. + + + + + + + + + Clears the specific year day schedule or all year day schedules for the specific user. + + + + + + + Set the holiday Schedule by specifying local start time and local end time with respect to any Lock Operating Mode. + + + + + + + + + Get the holiday schedule for the specified index. + + + + + + Returns the Holiday Schedule Entry for the specified Holiday ID. + + + + + + + + + Clears the holiday schedule or all holiday schedules. + + + + + + Set User into the lock. + + + + + + + + + + + + Retrieve User. + + + + + + Returns the User for the specified UserIndex. + + + + + + + + + + + + + + Clears a User or all Users. + + + + + + Set a credential (e.g. PIN, RFID, Fingerprint, etc.) into the lock for a new user, existing user, or ProgrammingUser. + + + + + + + + + + + Returns the status for setting the specified credential. + + + + + + + Retrieve the status of a particular credential (e.g. PIN, RFID, Fingerprint, etc.) by index. + + + + + + Returns the status for the specified credential. + + + + + + + + + + Clear one, one type, or all credentials except ProgrammingPIN credential. + + + + + This command causes the lock device to unlock the door without pulling the latch. + + + + + This command communicates an Aliro Reader configuration to the lock. + + + + + + + + This command clears an existing Aliro Reader configuration for the lock. + + + + + + + The door lock cluster provides several alarms which can be sent when there is a critical state on the door lock. + + + + + The door lock server sends out a DoorStateChange event when the door lock door state changes. + + + + The door lock server sends out a LockOperation event when the event is triggered by the various lock operation sources. + + + + + + + + + + The door lock server sends out a LockOperationError event when a lock operation fails for various reasons. + + + + + + + + + + + The door lock server sends out a LockUserChange event when a lock user, schedule, or credential change has occurred. + + + + + + + + + + + + + + + + + + + + + + + - - - The door lock cluster provides several alarms which can be sent when there is a critical state on the door lock. - - - - - - The door lock server sends out a DoorStateChange event when the door lock door state changes. - - - - - - - The door lock server sends out a LockOperation event when the event is triggered by the various lock operation sources. - - - - - - - - - - - The door lock server sends out a LockOperationError event when a lock operation fails for various reasons. - - - - - - - - - - - - The door lock server sends out a LockUserChange event when a lock user, schedule, or credential change has occurred. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + - - - - - - + + + + + + - - - - - + + + + + - - - - - - - - - - - - + + + + + + + + + + + + - - - - - - + + + + + + - - - - - - - - - - + + + + + + + + + + - - - - - - - - - + + + + + + + + + - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + - - - - - - - - + + + + + + + + - - - - - - - - + + + + + + + + - - - - - - - - + + + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + - - - - - - + + + + + + - - - - - - - - - - - - - + + + + + + + + + + + + + - - - - - - - - - + + + + + + + + + - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + - - - - - - - + + + + + + + - - - - - - - - - + + + + + + + + + - - - - - - - - - - + + + + + + + + + + - - - - - - - - + + + + + + + + - + @@ -1038,7 +796,7 @@ limitations under the License. - + @@ -1050,7 +808,7 @@ limitations under the License. - + @@ -1066,7 +824,7 @@ limitations under the License. - + @@ -1078,7 +836,7 @@ limitations under the License. - + @@ -1088,7 +846,7 @@ limitations under the License. - + @@ -1100,7 +858,7 @@ limitations under the License. - + diff --git a/src/app/zap-templates/zcl/data-model/chip/drlc-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/drlc-cluster.xml index d7e04ccf464668..d64bce1c85b7f6 100644 --- a/src/app/zap-templates/zcl/data-model/chip/drlc-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/drlc-cluster.xml @@ -199,41 +199,21 @@ limitations under the License. - - LoadControlPrograms - - - - NumberOfLoadControlPrograms - - - - Events - - - - ActiveEvents - - - - NumberOfEventsPerProgram - - - - NumberOfTransitions - - - + LoadControlPrograms + NumberOfLoadControlPrograms + Events + ActiveEvents + NumberOfEventsPerProgram + NumberOfTransitions + DefaultRandomStart - DefaultRandomDuration - @@ -241,21 +221,18 @@ limitations under the License. Upon receipt, this SHALL insert a new LoadControlProgramStruct into LoadControlPrograms, or if the ProgramID matches an existing LoadControlProgramStruct, then the provider SHALL be updated with the provided values. - Upon receipt, this SHALL remove a the LoadControlProgramStruct from LoadControlPrograms with the matching ProgramID. - On receipt of the AddLoadControlEventsRequest command, the server SHALL add a load control event. - @@ -263,7 +240,6 @@ limitations under the License. - - diff --git a/src/app/zap-templates/zcl/data-model/chip/electrical-energy-measurement-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/electrical-energy-measurement-cluster.xml index 3fbd9e984fc2a0..eb05052538d2de 100644 --- a/src/app/zap-templates/zcl/data-model/chip/electrical-energy-measurement-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/electrical-energy-measurement-cluster.xml @@ -42,71 +42,25 @@ limitations under the License. - - Accuracy - - - - CumulativeEnergyImported - - - - - - - + Accuracy + CumulativeEnergyImported - - CumulativeEnergyExported - - - - - - - + CumulativeEnergyExported - - PeriodicEnergyImported - - - - - - - + PeriodicEnergyImported - - PeriodicEnergyExported - - - - - - - - - CumulativeEnergyReset - - - - + PeriodicEnergyExported + CumulativeEnergyReset CumulativeEnergyMeasured - - - PeriodicEnergyMeasured - - - diff --git a/src/app/zap-templates/zcl/data-model/chip/electrical-power-measurement-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/electrical-power-measurement-cluster.xml index 18ee20bad30481..7f49a643d1b1f9 100644 --- a/src/app/zap-templates/zcl/data-model/chip/electrical-power-measurement-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/electrical-power-measurement-cluster.xml @@ -51,124 +51,40 @@ limitations under the License. - - PowerMode - - - - NumberOfMeasurementTypes - - - - Accuracy - - - - Ranges - - - - Voltage - - + PowerMode + NumberOfMeasurementTypes + Accuracy + Ranges + Voltage - - ActiveCurrent - - + ActiveCurrent - - ReactiveCurrent - - - - - - ApparentCurrent - - - - + ReactiveCurrent + ApparentCurrent - - ActivePower - - + ActivePower - - ReactivePower - - - - + ReactivePower - - ApparentPower - - - - + ApparentPower - - RMSVoltage - - - - + RMSVoltage - - RMSCurrent - - - - + RMSCurrent - - RMSPower - - - - + RMSPower - - Frequency - - - - + Frequency - - HarmonicCurrents - - - - + HarmonicCurrents - - HarmonicPhases - - - - + HarmonicPhases - - PowerFactor - - - - - - NeutralCurrent - - - - + PowerFactor + NeutralCurrent MeasurementPeriodRanges - - - diff --git a/src/app/zap-templates/zcl/data-model/chip/energy-evse-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/energy-evse-cluster.xml index 97709d706abf4d..7a4a40d2e39966 100644 --- a/src/app/zap-templates/zcl/data-model/chip/energy-evse-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/energy-evse-cluster.xml @@ -128,139 +128,53 @@ Git: 1.4-prerelease-ipr-69-ge15ff5700 - - State - - - - SupplyState - - - - FaultState - - - - ChargingEnabledUntil - - + State + SupplyState + FaultState + ChargingEnabledUntil - - DischargingEnabledUntil - - - - - - CircuitCapacity - - - - MinimumChargeCurrent - - - - MaximumChargeCurrent - - + DischargingEnabledUntil + CircuitCapacity + MinimumChargeCurrent + MaximumChargeCurrent - - MaximumDischargeCurrent - - - - + MaximumDischargeCurrent UserMaximumChargeCurrent - RandomizationDelayWindow - - - NextChargeStartTime - - - - + NextChargeStartTime - - NextChargeTargetTime - - - - + NextChargeTargetTime - - NextChargeRequiredEnergy - - - - + NextChargeRequiredEnergy - - NextChargeTargetSoC - - - - + NextChargeTargetSoC ApproximateEVEfficiency - - - - - StateOfCharge - - - - + StateOfCharge - - BatteryCapacity - - - - + BatteryCapacity - - VehicleID - - - - - - SessionID - - - - SessionDuration - - - - SessionEnergyCharged - - + VehicleID + SessionID + SessionDuration + SessionEnergyCharged - - SessionEnergyDischarged - - - - + SessionEnergyDischarged Allows a client to disable the EVSE from charging and discharging. - @@ -268,57 +182,39 @@ Git: 1.4-prerelease-ipr-69-ge15ff5700 This command allows a client to enable the EVSE to charge an EV, and to provide or update the maximum and minimum charge current. - Upon receipt, this SHALL allow a client to enable the discharge of an EV, and to provide or update the maximum discharge current. - - - Allows a client to put the EVSE into a self-diagnostics mode. - Allows a client to set the user specified charging targets. - - - Allows a client to retrieve the current set of charging targets. - - - Allows a client to clear all stored charging targets. - - - The GetTargetsResponse is sent in response to the GetTargets Command. - - - This event SHALL be generated when the EV is plugged in. - @@ -328,7 +224,6 @@ Git: 1.4-prerelease-ipr-69-ge15ff5700 - @@ -337,7 +232,6 @@ Git: 1.4-prerelease-ipr-69-ge15ff5700 - @@ -347,7 +241,6 @@ Git: 1.4-prerelease-ipr-69-ge15ff5700 - @@ -356,15 +249,11 @@ Git: 1.4-prerelease-ipr-69-ge15ff5700 - This event SHALL be generated when a RFID card has been read. - - - diff --git a/src/app/zap-templates/zcl/data-model/chip/energy-evse-mode-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/energy-evse-mode-cluster.xml index 7c4ddac9f6f09b..b28daf8899636c 100644 --- a/src/app/zap-templates/zcl/data-model/chip/energy-evse-mode-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/energy-evse-mode-cluster.xml @@ -59,26 +59,18 @@ Git: 1.4-prerelease-ipr-69-ge15ff5700 - - SupportedModes - - - - CurrentMode - - + SupportedModes + CurrentMode This command is used to change device modes. - This command is sent by the device on receipt of the ChangeToMode command. - diff --git a/src/app/zap-templates/zcl/data-model/chip/energy-preference-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/energy-preference-cluster.xml index cf646ab0197be5..a5e1ea8e950ae1 100644 --- a/src/app/zap-templates/zcl/data-model/chip/energy-preference-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/energy-preference-cluster.xml @@ -34,47 +34,26 @@ limitations under the License. - - EnergyBalances - - - - - + EnergyBalances + - - CurrentEnergyBalance + - - - + CurrentEnergyBalance - - EnergyPriorities - - - - + EnergyPriorities - - LowPowerModeSensitivities - - - - + LowPowerModeSensitivities - + CurrentLowPowerModeSensitivity - - - diff --git a/src/app/zap-templates/zcl/data-model/chip/ethernet-network-diagnostics-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/ethernet-network-diagnostics-cluster.xml index d84f017f5eea00..f2cf3173c68b29 100644 --- a/src/app/zap-templates/zcl/data-model/chip/ethernet-network-diagnostics-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/ethernet-network-diagnostics-cluster.xml @@ -37,69 +37,26 @@ limitations under the License. The Ethernet Network Diagnostics Cluster provides a means to acquire standardized diagnostics metrics that MAY be used by a Node to assist a user or Administrative Node in diagnosing potential problems. - - - - - - - - - - PHYRate + - - - FullDuplex + + - - - PacketRxCount - - - - - - PacketTxCount - - - - - - TxErrCount - - - - - - CollisionCount - - - - - - OverrunCount - - - - - - CarrierDetect - - - - TimeSinceReset - - + + + + PHYRate + FullDuplex + PacketRxCount + PacketTxCount + TxErrCount + CollisionCount + OverrunCount + CarrierDetect + TimeSinceReset Reception of this command SHALL reset the attributes: PacketRxCount, PacketTxCount, TxErrCount, CollisionCount, OverrunCount to 0 - - - - - - diff --git a/src/app/zap-templates/zcl/data-model/chip/fixed-label-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/fixed-label-cluster.xml index 5e4b1734efb46e..96e420f01902de 100644 --- a/src/app/zap-templates/zcl/data-model/chip/fixed-label-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/fixed-label-cluster.xml @@ -31,9 +31,6 @@ limitations under the License. FIXED_LABEL_CLUSTER The Fixed Label Cluster provides a feature for the device to tag an endpoint with zero or more read only labels. - - LabelList - - + LabelList diff --git a/src/app/zap-templates/zcl/data-model/chip/flow-measurement-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/flow-measurement-cluster.xml index b5336b50ad6406..3e546e968514ea 100644 --- a/src/app/zap-templates/zcl/data-model/chip/flow-measurement-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/flow-measurement-cluster.xml @@ -24,22 +24,10 @@ limitations under the License. FLOW_MEASUREMENT_CLUSTER true true - - MeasuredValue - - - - MinMeasuredValue - - - - MaxMeasuredValue - - - - Tolerance - - + MeasuredValue + MinMeasuredValue + MaxMeasuredValue + Tolerance diff --git a/src/app/zap-templates/zcl/data-model/chip/general-commissioning-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/general-commissioning-cluster.xml index e8877b5c1cc9d9..167f7d13e322af 100644 --- a/src/app/zap-templates/zcl/data-model/chip/general-commissioning-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/general-commissioning-cluster.xml @@ -56,86 +56,41 @@ limitations under the License. Breadcrumb - - - BasicCommissioningInfo - - - - RegulatoryConfig - - - - LocationCapability - - - - SupportsConcurrentConnection - - - + BasicCommissioningInfo + RegulatoryConfig + LocationCapability + SupportsConcurrentConnection + TCAcceptedVersion - - - - - - TCMinRequiredVersion - - - - - - TCAcknowledgements - - - - - - TCAcknowledgementsRequired - - - - - - TCUpdateDeadline - - - - - - Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock - Success/failure response for ArmFailSafe command - Set the regulatory configuration to be used during commissioning @@ -143,46 +98,30 @@ limitations under the License. - Success/failure response for SetRegulatoryConfig command - Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. - Indicates to client whether CommissioningComplete command succeeded - This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. - - - - - - This command is used to convey the result from SetTCAcknowledgements. - - - - - - diff --git a/src/app/zap-templates/zcl/data-model/chip/general-diagnostics-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/general-diagnostics-cluster.xml index 9383517eb95a5b..26f0e5708dd280 100644 --- a/src/app/zap-templates/zcl/data-model/chip/general-diagnostics-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/general-diagnostics-cluster.xml @@ -92,44 +92,17 @@ limitations under the License. - - NetworkInterfaces - - - - RebootCount - - + NetworkInterfaces + RebootCount - - UpTime - - - - TotalOperationalHours - - - - BootReason - - - - ActiveHardwareFaults - - - - ActiveRadioFaults - - - - ActiveNetworkFaults - - - - TestEventTriggersEnabled - - + UpTime + TotalOperationalHours + BootReason + ActiveHardwareFaults + ActiveRadioFaults + ActiveNetworkFaults + TestEventTriggersEnabled - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - IdleModeDuration - - - - ActiveModeDuration - - - - ActiveModeThreshold - - - - RegisteredClients - - - - - - - ICDCounter - - - - - - - ClientsSupportedPerFabric - - - - - - UserActiveModeTriggerHint - - - - - - - - - UserActiveModeTriggerInstruction - - - - OperatingMode - - - - - - - - - MaximumCheckInBackOff - - - - - - - Register a client to the end device - - - - - - - - - - - - - RegisterClient response command - - - - - - - - Unregister a client from an end device - - - - - - - - - - Request the end device to stay in Active Mode for an additional ActiveModeThreshold - - - - - - - - - - - - StayActiveRequest response command - - - - - - - - - + + General + ICD Management + 0x0046 + ICD_MANAGEMENT_CLUSTER + Allows servers to ensure that listed clients are notified when a server is available for communication. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +> +> +> +> +> + + + + + + IdleModeDuration + ActiveModeDuration + ActiveModeThreshold + + RegisteredClients + + + + ICDCounter + + + ClientsSupportedPerFabric + UserActiveModeTriggerHint + UserActiveModeTriggerInstruction + OperatingMode + MaximumCheckInBackOff + + + Register a client to the end device + + + + + + + + + + RegisterClient response command + + + + + Unregister a client from an end device + + + + + + + Request the end device to stay in Active Mode for an additional ActiveModeThreshold + + + + + + StayActiveRequest response command + + + diff --git a/src/app/zap-templates/zcl/data-model/chip/identify-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/identify-cluster.xml index 27b94701fc3d07..b64eb7702f1517 100644 --- a/src/app/zap-templates/zcl/data-model/chip/identify-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/identify-cluster.xml @@ -51,23 +51,16 @@ limitations under the License. true true - - - IdentifyTime - - - - IdentifyType - - - + + IdentifyTime + IdentifyType + Command description for Identify - @@ -76,7 +69,6 @@ limitations under the License. - diff --git a/src/app/zap-templates/zcl/data-model/chip/illuminance-measurement-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/illuminance-measurement-cluster.xml index 22dcca9d5775fe..b744964ca0a9aa 100644 --- a/src/app/zap-templates/zcl/data-model/chip/illuminance-measurement-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/illuminance-measurement-cluster.xml @@ -18,34 +18,19 @@ limitations under the License. - Illuminance Measurement - Measurement & Sensing - Attributes and commands for configuring the measurement of illuminance, and reporting illuminance measurements. - 0x0400 - ILLUMINANCE_MEASUREMENT_CLUSTER - true - true - - - MeasuredValue - - - - MinMeasuredValue - - - - MaxMeasuredValue - - - - Tolerance - - - - LightSensorType - - + Illuminance Measurement + Measurement & Sensing + Attributes and commands for configuring the measurement of illuminance, and reporting illuminance measurements. + 0x0400 + ILLUMINANCE_MEASUREMENT_CLUSTER + true + true + + MeasuredValue + MinMeasuredValue + MaxMeasuredValue + Tolerance + LightSensorType diff --git a/src/app/zap-templates/zcl/data-model/chip/keypad-input-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/keypad-input-cluster.xml index c21a58ca0f0fbf..b43ace5c0c8383 100644 --- a/src/app/zap-templates/zcl/data-model/chip/keypad-input-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/keypad-input-cluster.xml @@ -40,13 +40,11 @@ limitations under the License. Upon receipt, this SHALL process a keycode as input to the media device. - This command SHALL be generated in response to a SendKey Request command. - diff --git a/src/app/zap-templates/zcl/data-model/chip/laundry-dryer-controls-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/laundry-dryer-controls-cluster.xml index 171eb5cb91ee44..f126d8836f720c 100644 --- a/src/app/zap-templates/zcl/data-model/chip/laundry-dryer-controls-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/laundry-dryer-controls-cluster.xml @@ -36,15 +36,9 @@ limitations under the License. This cluster provides a way to access options associated with the operation of a laundry dryer device type. - - - - SupportedDrynessLevels - - - - SelectedDrynessLevel - - - + + + SupportedDrynessLevels + SelectedDrynessLevel + diff --git a/src/app/zap-templates/zcl/data-model/chip/laundry-washer-mode-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/laundry-washer-mode-cluster.xml index e3778d2d938b60..b8afd87d76665c 100644 --- a/src/app/zap-templates/zcl/data-model/chip/laundry-washer-mode-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/laundry-washer-mode-cluster.xml @@ -58,17 +58,11 @@ limitations under the License. - - SupportedModes - - - - CurrentMode - - + SupportedModes + CurrentMode StartUpMode OnMode - + @@ -76,7 +70,6 @@ limitations under the License. On receipt of this command the device SHALL respond with a ChangeToModeResponse command. - @@ -85,7 +78,6 @@ limitations under the License. - diff --git a/src/app/zap-templates/zcl/data-model/chip/level-control-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/level-control-cluster.xml index 8d2326e01fb278..4d0e67ddbd1b47 100644 --- a/src/app/zap-templates/zcl/data-model/chip/level-control-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/level-control-cluster.xml @@ -61,77 +61,25 @@ limitations under the License. - - CurrentLevel - - - - RemainingTime - - - - - - MinLevel - - - - - - - - MaxLevel - - - - CurrentFrequency - - - - - - MinFrequency - - - - - - MaxFrequency - - - - - - OnOffTransitionTime - - - - OnLevel - - - - OnTransitionTime - - - - OffTransitionTime - - - - DefaultMoveRate - - - - Options - - - + + CurrentLevel + RemainingTime + MinLevel + MaxLevel + CurrentFrequency + MinFrequency + MaxFrequency + + OnOffTransitionTime + OnLevel + OnTransitionTime + OffTransitionTime + DefaultMoveRate + Options + StartUpCurrentLevel - - - @@ -142,7 +90,6 @@ limitations under the License. - @@ -153,7 +100,6 @@ limitations under the License. - @@ -165,7 +111,6 @@ limitations under the License. - @@ -174,7 +119,6 @@ limitations under the License. - @@ -185,7 +129,6 @@ limitations under the License. - @@ -196,7 +139,6 @@ limitations under the License. - @@ -208,7 +150,6 @@ limitations under the License. - @@ -217,7 +158,6 @@ limitations under the License. - @@ -226,9 +166,6 @@ limitations under the License. approximation if the exact provided one is not possible. - - - diff --git a/src/app/zap-templates/zcl/data-model/chip/localization-configuration-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/localization-configuration-cluster.xml index 34e81bbb445d0e..9bdededd0fcd6e 100644 --- a/src/app/zap-templates/zcl/data-model/chip/localization-configuration-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/localization-configuration-cluster.xml @@ -31,11 +31,7 @@ limitations under the License. ActiveLocale - - - - SupportedLocales - + SupportedLocales diff --git a/src/app/zap-templates/zcl/data-model/chip/low-power-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/low-power-cluster.xml index 4b9ea09104994e..c1cc5b38ede202 100644 --- a/src/app/zap-templates/zcl/data-model/chip/low-power-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/low-power-cluster.xml @@ -26,7 +26,6 @@ limitations under the License. This cluster provides an interface for managing low power mode on a device. This command shall put the device into low power mode. - diff --git a/src/app/zap-templates/zcl/data-model/chip/media-input-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/media-input-cluster.xml index 57fdda3bc7cb7f..597b285cc1b5dd 100644 --- a/src/app/zap-templates/zcl/data-model/chip/media-input-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/media-input-cluster.xml @@ -32,29 +32,20 @@ limitations under the License. - - InputList - - - - CurrentInput - - + InputList + CurrentInput Upon receipt, this SHALL change the input on the media device to the input at a specific index in the Input List. - Upon receipt, this SHALL display the active status of the input list on screen. - Upon receipt, this SHALL hide the input list from the screen. - @@ -62,9 +53,6 @@ limitations under the License. - - - diff --git a/src/app/zap-templates/zcl/data-model/chip/media-playback-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/media-playback-cluster.xml index 1c4f2e37c8e42b..a77b8fa4befb4c 100644 --- a/src/app/zap-templates/zcl/data-model/chip/media-playback-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/media-playback-cluster.xml @@ -46,167 +46,87 @@ limitations under the License. - - CurrentState - - - - StartTime - - - - - - Duration - - - - - - SampledPosition - - - - - - PlaybackSpeed - - - - - - SeekRangeEnd - - - - - - SeekRangeStart - - - - - - ActiveAudioTrack - - - - - - AvailableAudioTracks - - - - - - ActiveTextTrack - - - - - - AvailableTextTracks - - - - + CurrentState + StartTime + Duration + SampledPosition + PlaybackSpeed + SeekRangeEnd + SeekRangeStart + ActiveAudioTrack + AvailableAudioTracks + ActiveTextTrack + AvailableTextTracks Upon receipt, this SHALL play media. - Upon receipt, this SHALL pause media. - Upon receipt, this SHALL stop media. User experience is context-specific. This will often navigate the user back to the location where media was originally launched. - Upon receipt, this SHALL Start Over with the current media playback item. - Upon receipt, this SHALL cause the handler to be invoked for "Previous". User experience is context-specific. This will often Go back to the previous media playback item. - Upon receipt, this SHALL cause the handler to be invoked for "Next". User experience is context-specific. This will often Go forward to the next media playback item. - Upon receipt, this SHALL Rewind through media. Different Rewind speeds can be used on the TV based upon the number of sequential calls to this function. This is to avoid needing to define every speed now (multiple fast, slow motion, etc). - - - Upon receipt, this SHALL Advance through media. Different FF speeds can be used on the TV based upon the number of sequential calls to this function. This is to avoid needing to define every speed now (multiple fast, slow motion, etc). - - - Upon receipt, this SHALL Skip forward in the media by the given number of seconds, using the data as follows: - Upon receipt, this SHALL Skip backward in the media by the given number of seconds, using the data as follows: - Upon receipt, this SHALL Skip backward in the media by the given number of seconds, using the data as follows: - - - This command SHALL be generated in response to various Playback Request commands. - Upon receipt, the server SHALL set the active Audio Track to the one identified by the TrackID in the Track catalog for the streaming media. If the TrackID does not exist in the Track catalog, OR does not correspond to the streaming media OR no media is being streamed at the time of receipt of this command, the server will return an error status of INVALID_ARGUMENT. - - - Upon receipt, the server SHALL set the active Text Track to the one identified by the TrackID in the Track catalog for the streaming media. If the TrackID does not exist in the Track catalog, OR does not correspond to the streaming media OR no media is being streamed at the time of receipt of this command, the server SHALL return an error status of INVALID_ARGUMENT. - - - If a Text Track is active (i.e. being displayed), upon receipt of this command, the server SHALL stop displaying it. - - - @@ -220,7 +140,6 @@ limitations under the License. - diff --git a/src/app/zap-templates/zcl/data-model/chip/messages-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/messages-cluster.xml index 901e63703eee1f..741ba801f5c092 100644 --- a/src/app/zap-templates/zcl/data-model/chip/messages-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/messages-cluster.xml @@ -91,14 +91,8 @@ limitations under the License. - - Messages - - - - ActiveMessageIDs - - + Messages + ActiveMessageIDs Command for requesting messages be presented @@ -110,24 +104,20 @@ limitations under the License. - Command for cancelling message present requests - This event SHALL be generated when the message is confirmed by the user, or when the expiration date of the message is reached. - This event SHALL be generated when the message is presented to the user. - This event SHALL be generated when the message is confirmed by the user, or when the expiration date of the message is reached. @@ -135,7 +125,6 @@ limitations under the License. - - + \ No newline at end of file diff --git a/src/app/zap-templates/zcl/data-model/chip/microwave-oven-control-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/microwave-oven-control-cluster.xml index fd44e47c2ca767..954bd898b6aa00 100644 --- a/src/app/zap-templates/zcl/data-model/chip/microwave-oven-control-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/microwave-oven-control-cluster.xml @@ -41,74 +41,27 @@ limitations under the License. - - CookTime - - - - MaxCookTime - - - - PowerSetting - - - - - - MinPower - - - - - - MaxPower - - - - - - PowerStep - - - - - - SupportedWatts - - - - - - - - - SelectedWattIndex - - - - - - - - - WattRating - - - + CookTime + MaxCookTime + PowerSetting + MinPower + MaxPower + PowerStep + SupportedWatts + SelectedWattIndex + WattRating + - Set Cooking Parameters + Set Cooking Parameters - - Add More Cooking Time - - + Add More Cooking Time + diff --git a/src/app/zap-templates/zcl/data-model/chip/microwave-oven-mode-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/microwave-oven-mode-cluster.xml index 393354fb4ca461..856fde36da15ee 100644 --- a/src/app/zap-templates/zcl/data-model/chip/microwave-oven-mode-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/microwave-oven-mode-cluster.xml @@ -55,13 +55,7 @@ limitations under the License. - - SupportedModes - - - - CurrentMode - - + SupportedModes + CurrentMode diff --git a/src/app/zap-templates/zcl/data-model/chip/mode-select-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/mode-select-cluster.xml index 80e0267155496b..443acb1c955c36 100644 --- a/src/app/zap-templates/zcl/data-model/chip/mode-select-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/mode-select-cluster.xml @@ -48,39 +48,19 @@ limitations under the License. Attributes and commands for selecting a mode from a list of supported options. - - Description - - - - StandardNamespace - - - - SupportedModes - - - - CurrentMode - - - - StartUpMode - - - - OnMode - - - - + Description + StandardNamespace + SupportedModes + CurrentMode + StartUpMode + OnMode + On receipt of this command, if the NewMode field matches the Mode field in an entry of the SupportedModes list, the server SHALL set the CurrentMode attribute to the NewMode value, otherwise, the server SHALL respond with an INVALID_COMMAND status response. - diff --git a/src/app/zap-templates/zcl/data-model/chip/network-commissioning-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/network-commissioning-cluster.xml index 02fcb28ee2e14b..964923be4f2dfa 100644 --- a/src/app/zap-templates/zcl/data-model/chip/network-commissioning-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/network-commissioning-cluster.xml @@ -107,207 +107,120 @@ limitations under the License. - - - - + + - + MaxNetworks - - + Networks - - - - ScanMaxTimeSeconds - - - - - - - - ConnectMaxTimeSeconds - - - - - - - - + ScanMaxTimeSeconds + ConnectMaxTimeSeconds + InterfaceEnabled - - + LastNetworkingStatus - - + LastNetworkID - - + LastConnectErrorValue - - + SupportedWiFiBands - - - - + SupportedThreadFeatures - - - - + ThreadVersion - - - - - Detemine the set of networks the device sees as available. - - - - - - - - - - - - Relay the set of networks the device sees as available back to the client. - - - - - - - - - - - - - Add or update the credentials for a given Wi-Fi network. - - - - - - - - - - - - - Add or update the credentials for a given Thread network. - - - - - - - - - Remove the definition of a given network (including its credentials). - - - - - - - - - - - - Response command for various commands that add/remove/modify network credentials. - - - - - - - - - - - - - - Connect to the specified network, using previously-defined credentials. - - - - - - - - - - - - Command that indicates whether we have succcessfully connected to a network. - - - - - - - - - - - - Modify the order in which networks will be presented in the Networks attribute. - - - - - - - - - - - - - Retrieve details about and optionally proof of possession of a network client identity. - - - - - - - - - Command that contains details about a network client identity and optionally a proof of possession. - - - - - - - + + Detemine the set of networks the device sees as available. + + + + + + Relay the set of networks the device sees as available back to the client. + + + + + + + Add or update the credentials for a given Wi-Fi network. + + + + + + + + + + Add or update the credentials for a given Thread network. + + + + + + Remove the definition of a given network (including its credentials). + + + + + + Response command for various commands that add/remove/modify network credentials. + + + + + + + + Connect to the specified network, using previously-defined credentials. + + + + + + Command that indicates whether we have succcessfully connected to a network. + + + + + + Modify the order in which networks will be presented in the Networks attribute. + + + + + + + Retrieve details about and optionally proof of possession of a network client identity. + + + + + + Command that contains details about a network client identity and optionally a proof of possession. + + + + diff --git a/src/app/zap-templates/zcl/data-model/chip/occupancy-sensing-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/occupancy-sensing-cluster.xml index 90f1a6a9f497a7..0141a7542f4d78 100644 --- a/src/app/zap-templates/zcl/data-model/chip/occupancy-sensing-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/occupancy-sensing-cluster.xml @@ -83,288 +83,74 @@ limitations under the License. - - Occupancy - - - - OccupancySensorType - - - - - - - OccupancySensorTypeBitmap - - - - - + Occupancy + OccupancySensorType + OccupancySensorTypeBitmap - HoldTime - - + HoldTime + - - HoldTimeLimits - - - - - + HoldTimeLimits + PIROccupiedToUnoccupiedDelay - - - - - - - - - - - - - - - - - - - - - - PIRUnoccupiedToOccupiedDelay - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - PIRUnoccupiedToOccupiedThreshold - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - UltrasonicOccupiedToUnoccupiedDelay - - - - - - - - - UltrasonicUnoccupiedToOccupiedDelay - - - - - - - - - - - - - - - - UltrasonicUnoccupiedToOccupiedThreshold - - - - - - - - - - - - - - - - PhysicalContactOccupiedToUnoccupiedDelay - - - - - - - - - PhysicalContactUnoccupiedToOccupiedDelay - - - - - - - - - - - - - - - - PhysicalContactUnoccupiedToOccupiedThreshold - - - - - - - - - - - - - - - - If this event is supported, it SHALL be generated when the Occupancy attribute changes. - diff --git a/src/app/zap-templates/zcl/data-model/chip/onoff-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/onoff-cluster.xml index c1e87fd1ceb37d..04dcfed83766e8 100644 --- a/src/app/zap-templates/zcl/data-model/chip/onoff-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/onoff-cluster.xml @@ -81,75 +81,37 @@ limitations under the License. - - - OnOff - - - - GlobalSceneControl - - - - - - OnTime - - - - - - OffWaitTime - - - - - + + OnOff + GlobalSceneControl + OnTime + OffWaitTime + StartUpOnOff - - - On receipt of this command, a device SHALL enter its ‘Off’ state. This state is device dependent, but it is recommended that it is used for power off or similar functions. On receipt of the Off command, the OnTime attribute SHALL be set to 0. - On receipt of this command, a device SHALL enter its ‘On’ state. This state is device dependent, but it is recommended that it is used for power on or similar functions. On receipt of the On command, if the value of the OnTime attribute is equal to 0, the device SHALL set the OffWaitTime attribute to 0. - - - - - On receipt of this command, if a device is in its ‘Off’ state it SHALL enter its ‘On’ state. Otherwise, if it is in its ‘On’ state it SHALL enter its ‘Off’ state. On receipt of the Toggle command, if the value of the OnOff attribute is equal to FALSE and if the value of the OnTime attribute is equal to 0, the device SHALL set the OffWaitTime attribute to 0. If the value of the OnOff attribute is equal to TRUE, the OnTime attribute SHALL be set to 0. - - - - - The OffWithEffect command allows devices to be turned off using enhanced ways of fading. - - - The OnWithRecallGlobalScene command allows the recall of the settings when the device was turned off. - - - @@ -157,9 +119,6 @@ limitations under the License. - - - diff --git a/src/app/zap-templates/zcl/data-model/chip/operational-credentials-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/operational-credentials-cluster.xml index 8be3ce077a2732..5b06c93e0ab7fd 100644 --- a/src/app/zap-templates/zcl/data-model/chip/operational-credentials-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/operational-credentials-cluster.xml @@ -62,54 +62,34 @@ limitations under the License. NOCs - - - - Fabrics - - - - SupportedFabrics - - - - CommissionedFabrics - - - - TrustedRootCertificates - - - - CurrentFabricIndex - + Fabrics + SupportedFabrics + CommissionedFabrics + TrustedRootCertificates + CurrentFabricIndex Sender is requesting attestation information from the receiver. - An attestation information confirmation from the server. - Sender is requesting a device attestation certificate from the receiver. - A device attestation certificate (DAC) or product attestation intermediate (PAI) certificate from the server. - @@ -117,7 +97,6 @@ limitations under the License. - @@ -125,7 +104,6 @@ limitations under the License. A certificate signing request (CSR) from the server. - @@ -136,7 +114,6 @@ limitations under the License. - @@ -144,36 +121,31 @@ limitations under the License. - - + Response to AddNOC or UpdateNOC commands. - This command SHALL be used by an Administrative Node to set the user-visible Label field for a given Fabric, as reflected by entries in the Fabrics attribute. - This command is used by Administrative Nodes to remove a given fabric index and delete all associated fabric-scoped data. - This command SHALL add a Trusted Root CA Certificate, provided as its CHIP Certificate representation. - diff --git a/src/app/zap-templates/zcl/data-model/chip/operational-state-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/operational-state-cluster.xml index 9bc60ae2f73fef..53b9c73cad6b3e 100644 --- a/src/app/zap-templates/zcl/data-model/chip/operational-state-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/operational-state-cluster.xml @@ -58,94 +58,47 @@ limitations under the License. true true This cluster supports remotely monitoring and, where supported, changing the operational state of any device where a state machine is a part of the operation. - - - - - PhaseList - - - - CurrentPhase - - - - CountdownTime - - - - OperationalStateList - - - - OperationalState - - - - OperationalError - - - + + + + PhaseList + CurrentPhase + CountdownTime + OperationalStateList + OperationalState + OperationalError + Upon receipt, the device SHALL pause its operation if it is possible based on the current function of the server. - - - - - - Upon receipt, the device SHALL stop its operation if it is at a position where it is safe to do so and/or permitted. - - - - - - Upon receipt, the device SHALL start its operation if it is safe to do so and the device is in an operational state from which it can be started. - Upon receipt, the device SHALL resume its operation from the point it was at when it received the Pause command, or from the point when it was paused by means outside of this cluster (for example by manual button press). - - - - - - This command SHALL be generated in response to any of the Start, Stop, Pause, or Resume commands. - - - - - - - - OperationalError - - + OperationCompletion - - + diff --git a/src/app/zap-templates/zcl/data-model/chip/operational-state-oven-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/operational-state-oven-cluster.xml index 800506d73c6079..fd52204b02fe85 100644 --- a/src/app/zap-templates/zcl/data-model/chip/operational-state-oven-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/operational-state-oven-cluster.xml @@ -53,31 +53,13 @@ limitations under the License. This cluster supports remotely monitoring and, where supported, changing the operational state of an Oven. - - - PhaseList - - - - CurrentPhase - - - - CountdownTime - - - - OperationalStateList - - - - OperationalState - - - - OperationalError - - + + PhaseList + CurrentPhase + CountdownTime + OperationalStateList + OperationalState + OperationalError Upon receipt, the device SHALL pause its operation if it is possible based on the current function of the server. @@ -85,17 +67,10 @@ limitations under the License. Upon receipt, the device SHALL stop its operation if it is at a position where it is safe to do so and/or permitted. - - - - - - Upon receipt, the device SHALL start its operation if it is safe to do so and the device is in an operational state from which it can be started. - @@ -105,28 +80,18 @@ limitations under the License. This command SHALL be generated in response to any of the Start, Stop, Pause, or Resume commands. - - - - - - - - OperationalError - - + OperationCompletion - - + diff --git a/src/app/zap-templates/zcl/data-model/chip/operational-state-rvc-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/operational-state-rvc-cluster.xml index 3c762879309e5c..e3b054fe3fedce 100644 --- a/src/app/zap-templates/zcl/data-model/chip/operational-state-rvc-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/operational-state-rvc-cluster.xml @@ -64,48 +64,24 @@ limitations under the License. true true This cluster supports remotely monitoring and, where supported, changing the operational state of a Robotic Vacuum. - - - - - PhaseList - - - - CurrentPhase - - - - CountdownTime - - - - OperationalStateList - - - - - - OperationalState - - - - OperationalError - - + OperationalState + OperationalError Upon receipt, the device SHALL pause its operation if it is possible based on the current function of the server. - - - - - - @@ -114,47 +90,27 @@ both values from this cluster and from the base cluster. Upon receipt, the device SHALL resume its operation from the point it was at when it received the Pause command, or from the point when it was paused by means outside of this cluster (for example by manual button press). - - - - - - This command SHALL be generated in response to any of the Start, Stop, Pause, or Resume commands. - - - - - - - - On receipt of this command, the device SHALL start seeking the charging dock, if possible in the current state of the device. - - - - OperationalError - - + - + OperationCompletion - - - + + diff --git a/src/app/zap-templates/zcl/data-model/chip/oven-mode-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/oven-mode-cluster.xml index 8a54783445013f..0faa1b037eb318 100644 --- a/src/app/zap-templates/zcl/data-model/chip/oven-mode-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/oven-mode-cluster.xml @@ -62,17 +62,11 @@ limitations under the License. - - SupportedModes - - - - CurrentMode - - + SupportedModes + CurrentMode StartUpMode OnMode - + @@ -80,7 +74,6 @@ limitations under the License. On receipt of this command the device SHALL respond with a ChangeToModeResponse command. - @@ -89,7 +82,6 @@ limitations under the License. - diff --git a/src/app/zap-templates/zcl/data-model/chip/power-source-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/power-source-cluster.xml index 8bbfe444227f1d..5701dc6ec61e65 100644 --- a/src/app/zap-templates/zcl/data-model/chip/power-source-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/power-source-cluster.xml @@ -43,222 +43,58 @@ limitations under the License. - - - Status - - - - Order - - - - Description - - - - - WiredAssessedInputVoltage - - - - - - WiredAssessedInputFrequency - - - - - - WiredCurrentType - - - - - - WiredAssessedCurrent - - - - - - WiredNominalVoltage - - - - - - WiredMaximumCurrent - - - - - - WiredPresent - - - - - - ActiveWiredFaults - - - - - - - BatVoltage - - - - - - BatPercentRemaining - - - - - - BatTimeRemaining - - - - - - BatChargeLevel - - - - - - BatReplacementNeeded - - - - - - BatReplaceability - - - - - - BatPresent - - - - - - ActiveBatFaults - - - - - - BatReplacementDescription - - - - - - BatCommonDesignation - - - - - - BatANSIDesignation - - - - - - BatIECDesignation - - - - - - BatApprovedChemistry - - - - - - BatCapacity - - - - - - - - - BatQuantity - - - - - - BatChargeState - - - - - - BatTimeToFullCharge - - - - - - BatFunctionalWhileCharging - - - - - - BatChargingCurrent - - - - - - ActiveBatChargeFaults - - - - - - EndpointList - - + Status + Order + Description + + WiredAssessedInputVoltage + WiredAssessedInputFrequency + WiredCurrentType + WiredAssessedCurrent + WiredNominalVoltage + WiredMaximumCurrent + WiredPresent + ActiveWiredFaults + + BatVoltage + BatPercentRemaining + BatTimeRemaining + BatChargeLevel + BatReplacementNeeded + BatReplaceability + BatPresent + ActiveBatFaults + BatReplacementDescription + BatCommonDesignation + BatANSIDesignation + BatIECDesignation + BatApprovedChemistry + BatCapacity + BatQuantity + BatChargeState + BatTimeToFullCharge + BatFunctionalWhileCharging + BatChargingCurrent + ActiveBatChargeFaults + EndpointList + The WiredFaultChange Event SHALL indicate a change in the set of wired faults currently detected by the Node on this wired power source. - - - The BatFaultChange Event SHALL indicate a change in the set of battery faults currently detected by the Node on this battery power source. - - - The BatChargeFaultChange Event SHALL indicate a change in the set of charge faults currently detected by the Node on this battery power source. - - - diff --git a/src/app/zap-templates/zcl/data-model/chip/power-source-configuration-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/power-source-configuration-cluster.xml index ba97841d3492e0..04a7cdb121c775 100644 --- a/src/app/zap-templates/zcl/data-model/chip/power-source-configuration-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/power-source-configuration-cluster.xml @@ -26,9 +26,6 @@ limitations under the License. true true - - Sources - - + Sources diff --git a/src/app/zap-templates/zcl/data-model/chip/power-topology-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/power-topology-cluster.xml index c686115edcb8cb..3bca0bd43ee8af 100644 --- a/src/app/zap-templates/zcl/data-model/chip/power-topology-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/power-topology-cluster.xml @@ -44,17 +44,7 @@ limitations under the License. - - AvailableEndpoints - - - - - - ActiveEndpoints - - - - + AvailableEndpoints + ActiveEndpoints diff --git a/src/app/zap-templates/zcl/data-model/chip/pressure-measurement-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/pressure-measurement-cluster.xml index 04100e82379f2d..f9487af7f3a9e2 100644 --- a/src/app/zap-templates/zcl/data-model/chip/pressure-measurement-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/pressure-measurement-cluster.xml @@ -31,53 +31,16 @@ limitations under the License. - - - MeasuredValue - - - - MinMeasuredValue - - - - MaxMeasuredValue - - - - Tolerance - - - - ScaledValue - - - - - - MinScaledValue - - - - - - MaxScaledValue - - - - - - ScaledTolerance - - - - - - Scale - - - - + + MeasuredValue + MinMeasuredValue + MaxMeasuredValue + Tolerance + ScaledValue + MinScaledValue + MaxScaledValue + ScaledTolerance + Scale diff --git a/src/app/zap-templates/zcl/data-model/chip/pump-configuration-and-control-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/pump-configuration-and-control-cluster.xml index b23ad516515b11..74416092e7c7f8 100644 --- a/src/app/zap-templates/zcl/data-model/chip/pump-configuration-and-control-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/pump-configuration-and-control-cluster.xml @@ -49,245 +49,97 @@ limitations under the License. - - - MaxPressure - - - - MaxSpeed - - - - MaxFlow - - - - MinConstPressure - - - - - - - - - - - MaxConstPressure - - - - - - - - - - - MinCompPressure - - - - - - - - - - - MaxCompPressure - - - - - - - - - - - MinConstSpeed - - - - - - - - - - - MaxConstSpeed - - - - - - - - - - - MinConstFlow - - - - - - - - - - - MaxConstFlow - - - - - - - - - - - MinConstTemp - - - - - - - - - - - MaxConstTemp - - - - - - - - - - - PumpStatus - - - - EffectiveOperationMode - - - - EffectiveControlMode - - - - Capacity - - - - Speed - - + + MaxPressure + MaxSpeed + MaxFlow + MinConstPressure + MaxConstPressure + MinCompPressure + MaxCompPressure + MinConstSpeed + MaxConstSpeed + MinConstFlow + MaxConstFlow + MinConstTemp + MaxConstTemp + PumpStatus + EffectiveOperationMode + EffectiveControlMode + Capacity + Speed LifetimeRunningHours - - - - Power - + Power LifetimeEnergyConsumed - OperationMode - ControlMode - SupplyVoltageLow - SupplyVoltageHigh - PowerMissingPhase - SystemPressureLow - SystemPressureHigh - DryRunning - MotorTemperatureHigh - PumpMotorFatalFailure - ElectronicTemperatureHigh - PumpBlocked - SensorFailure - ElectronicNonFatalFailure - ElectronicFatalFailure - GeneralFault - Leakage - AirDetection - TurbineOperation - diff --git a/src/app/zap-templates/zcl/data-model/chip/refrigerator-alarm.xml b/src/app/zap-templates/zcl/data-model/chip/refrigerator-alarm.xml index deeb16b4dae3d7..58fa70163f65ea 100644 --- a/src/app/zap-templates/zcl/data-model/chip/refrigerator-alarm.xml +++ b/src/app/zap-templates/zcl/data-model/chip/refrigerator-alarm.xml @@ -28,27 +28,17 @@ limitations under the License. REFRIGERATOR_ALARM_CLUSTER true true - - - Mask - - - - State - - - - Supported - - + + Mask + State + Supported - Notify - - - - - + Notify + + + + diff --git a/src/app/zap-templates/zcl/data-model/chip/refrigerator-and-temperature-controlled-cabinet-mode-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/refrigerator-and-temperature-controlled-cabinet-mode-cluster.xml index a4fe78bc225d65..e29080ce4a43cb 100644 --- a/src/app/zap-templates/zcl/data-model/chip/refrigerator-and-temperature-controlled-cabinet-mode-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/refrigerator-and-temperature-controlled-cabinet-mode-cluster.xml @@ -56,17 +56,11 @@ limitations under the License. - - SupportedModes - - - - CurrentMode - - + SupportedModes + CurrentMode StartUpMode OnMode - + @@ -74,7 +68,6 @@ limitations under the License. On receipt of this command the device SHALL respond with a ChangeToModeResponse command. - @@ -83,7 +76,6 @@ limitations under the License. - diff --git a/src/app/zap-templates/zcl/data-model/chip/relative-humidity-measurement-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/relative-humidity-measurement-cluster.xml index 7f8157572a4270..e309b75dcc46bd 100644 --- a/src/app/zap-templates/zcl/data-model/chip/relative-humidity-measurement-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/relative-humidity-measurement-cluster.xml @@ -25,21 +25,9 @@ limitations under the License. true true - - MeasuredValue - - - - MinMeasuredValue - - - - MaxMeasuredValue - - - - Tolerance - - + MeasuredValue + MinMeasuredValue + MaxMeasuredValue + Tolerance diff --git a/src/app/zap-templates/zcl/data-model/chip/resource-monitoring-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/resource-monitoring-cluster.xml index 25e586226f0d82..66de9ee66cbebd 100644 --- a/src/app/zap-templates/zcl/data-model/chip/resource-monitoring-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/resource-monitoring-cluster.xml @@ -38,41 +38,16 @@ limitations under the License. - - Condition - - - - - - DegradationDirection - - - - - - ChangeIndication - - - - InPlaceIndicator - - - - LastChangedTime - - - - ReplacementProductList - - - - - + Condition + DegradationDirection + ChangeIndication + InPlaceIndicator + LastChangedTime + ReplacementProductList + Reset the condition of the replaceable to the non degraded state - @@ -98,41 +73,16 @@ limitations under the License. - - Condition - - - - - - DegradationDirection - - - - - - ChangeIndication - - - - InPlaceIndicator - - - - LastChangedTime - - - - ReplacementProductList - - - - - + Condition + DegradationDirection + ChangeIndication + InPlaceIndicator + LastChangedTime + ReplacementProductList + Reset the condition of the replaceable to the non degraded state - diff --git a/src/app/zap-templates/zcl/data-model/chip/rvc-clean-mode-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/rvc-clean-mode-cluster.xml index a1fe4809ee1e17..65c2f17a3e8e75 100644 --- a/src/app/zap-templates/zcl/data-model/chip/rvc-clean-mode-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/rvc-clean-mode-cluster.xml @@ -67,14 +67,8 @@ limitations under the License. - - SupportedModes - - - - CurrentMode - - + SupportedModes + CurrentMode @@ -84,7 +78,6 @@ limitations under the License. On receipt of this command the device SHALL respond with a ChangeToModeResponse command. - @@ -93,7 +86,6 @@ limitations under the License. - diff --git a/src/app/zap-templates/zcl/data-model/chip/rvc-run-mode-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/rvc-run-mode-cluster.xml index 6cd765db7fab84..ce835576396bb8 100644 --- a/src/app/zap-templates/zcl/data-model/chip/rvc-run-mode-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/rvc-run-mode-cluster.xml @@ -73,14 +73,8 @@ limitations under the License. - - SupportedModes - - - - CurrentMode - - + SupportedModes + CurrentMode @@ -90,7 +84,6 @@ limitations under the License. On receipt of this command the device SHALL respond with a ChangeToModeResponse command. - @@ -99,7 +92,6 @@ limitations under the License. - diff --git a/src/app/zap-templates/zcl/data-model/chip/scene.xml b/src/app/zap-templates/zcl/data-model/chip/scene.xml index dcc929fa47e872..b6315bdc1287c1 100644 --- a/src/app/zap-templates/zcl/data-model/chip/scene.xml +++ b/src/app/zap-templates/zcl/data-model/chip/scene.xml @@ -80,19 +80,10 @@ limitations under the License. - - LastConfiguredBy - - - - SceneTableSize - - - - FabricSceneInfo - - - + + LastConfiguredBy + SceneTableSize + FabricSceneInfo Add a scene to the scene table. Extension field sets are supported, and are inputed as '{"ClusterID": VALUE, "AttributeValueList":[{"AttributeID": VALUE, "Value*": VALUE}]}' @@ -103,7 +94,6 @@ limitations under the License. - @@ -112,7 +102,6 @@ limitations under the License. - @@ -122,7 +111,6 @@ limitations under the License. - @@ -131,7 +119,6 @@ limitations under the License. - @@ -141,7 +128,6 @@ limitations under the License. - @@ -151,7 +137,6 @@ limitations under the License. - @@ -159,7 +144,6 @@ limitations under the License. Get an unused scene identifier when no commissioning tool is in the network, or for a commissioning tool to get the used scene identifiers within a certain group - @@ -171,7 +155,6 @@ limitations under the License. - @@ -181,7 +164,6 @@ limitations under the License. - @@ -194,7 +176,6 @@ limitations under the License. - @@ -204,7 +185,6 @@ limitations under the License. - @@ -213,7 +193,6 @@ limitations under the License. - @@ -223,7 +202,6 @@ limitations under the License. - @@ -234,7 +212,6 @@ limitations under the License. - @@ -244,9 +221,6 @@ limitations under the License. - - - diff --git a/src/app/zap-templates/zcl/data-model/chip/service-area-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/service-area-cluster.xml index c442136d46aa0a..8c2ba832c85604 100644 --- a/src/app/zap-templates/zcl/data-model/chip/service-area-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/service-area-cluster.xml @@ -96,43 +96,19 @@ limitations under the License. - - SupportedAreas - - - - SupportedMaps - - - - - - SelectedAreas - - - - CurrentArea - - - EstimatedEndTime - - - - - - Progress - - - - - + SupportedAreas + SupportedMaps + SelectedAreas + CurrentArea + EstimatedEndTime + Progress + Command used to select a set of device areas, where the device is to operate. - @@ -141,7 +117,6 @@ limitations under the License. - @@ -157,9 +132,6 @@ limitations under the License. - - - diff --git a/src/app/zap-templates/zcl/data-model/chip/smoke-co-alarm-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/smoke-co-alarm-cluster.xml index a0543e04373dd5..31ae0bba9e7d99 100644 --- a/src/app/zap-templates/zcl/data-model/chip/smoke-co-alarm-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/smoke-co-alarm-cluster.xml @@ -46,131 +46,66 @@ limitations under the License. - - ExpressedState - - - - SmokeState - - - - - - COState - - - - - - BatteryAlert - - - - DeviceMuted - - - - TestInProgress - - - - HardwareFaultAlert - - - - EndOfServiceAlert - - - - InterconnectSmokeAlarm - - - - InterconnectCOAlarm - - - - ContaminationState - - - - + ExpressedState + SmokeState + COState + BatteryAlert + DeviceMuted + TestInProgress + HardwareFaultAlert + EndOfServiceAlert + InterconnectSmokeAlarm + InterconnectCOAlarm + ContaminationState SmokeSensitivityLevel - - - - - - ExpiryDate - - + ExpiryDate + This command SHALL initiate a device self-test. - This event SHALL be generated when SmokeState attribute changes to either Warning or Critical state. - - - This event SHALL be generated when COState attribute changes to either Warning or Critical state. - - - This event SHALL be generated when BatteryAlert attribute changes to either Warning or Critical state. - This event SHALL be generated when the device detects a hardware fault that leads to setting HardwareFaultAlert to True. - This event SHALL be generated when the EndOfServiceAlert is set to Expired. - This event SHALL be generated when the SelfTest completes, and the attribute TestInProgress changes to False. - This event SHALL be generated when the DeviceMuted attribute changes to Muted. - This event SHALL be generated when DeviceMuted attribute changes to NotMuted. - This event SHALL be generated when the device hosting the server receives a smoke alarm from an interconnected sensor. - - - This event SHALL be generated when the device hosting the server receives a smoke alarm from an interconnected sensor. - - - This event SHALL be generated when ExpressedState attribute returns to Normal state. - diff --git a/src/app/zap-templates/zcl/data-model/chip/software-diagnostics-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/software-diagnostics-cluster.xml index d0973998fa98d6..3ac2ba42e8e22e 100644 --- a/src/app/zap-templates/zcl/data-model/chip/software-diagnostics-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/software-diagnostics-cluster.xml @@ -37,38 +37,20 @@ limitations under the License. - - ThreadMetrics - - - - CurrentHeapFree - - - - CurrentHeapUsed - - - - CurrentHeapHighWatermark - - - - + ThreadMetrics + CurrentHeapFree + CurrentHeapUsed + CurrentHeapHighWatermark Reception of this command SHALL reset the values: The StackFreeMinimum field of the ThreadMetrics attribute, CurrentHeapHighWaterMark attribute. - - - Indicate the last software fault that has taken place on the Node. - - + diff --git a/src/app/zap-templates/zcl/data-model/chip/switch-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/switch-cluster.xml index 90f61cdedcfbc8..176163fae7fce6 100644 --- a/src/app/zap-templates/zcl/data-model/chip/switch-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/switch-cluster.xml @@ -78,75 +78,38 @@ Interactions with the switch device are exposed as attributes (for the latching - - NumberOfPositions - - - - CurrentPosition - - - - MultiPressMax - - - - + NumberOfPositions + CurrentPosition + MultiPressMax SwitchLatched - - - InitialPress - - - LongPress - - - ShortRelease - - - LongRelease - - - MultiPressOngoing - - - - - - - - MultiPressComplete - - - - + diff --git a/src/app/zap-templates/zcl/data-model/chip/target-navigator-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/target-navigator-cluster.xml index c7d516bcdc7416..bc665905df1eb2 100644 --- a/src/app/zap-templates/zcl/data-model/chip/target-navigator-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/target-navigator-cluster.xml @@ -25,27 +25,19 @@ limitations under the License. true This cluster provides an interface for UX navigation within a set of targets on a device or endpoint. - - TargetList - - - - CurrentTarget - - - + TargetList + CurrentTarget + Upon receipt, this SHALL navigation the UX to the target identified. - This command SHALL be generated in response to NavigateTarget commands. - @@ -53,7 +45,6 @@ limitations under the License. - diff --git a/src/app/zap-templates/zcl/data-model/chip/temperature-control-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/temperature-control-cluster.xml index 2c7c173c6af8ff..da0c0bcee983bb 100644 --- a/src/app/zap-templates/zcl/data-model/chip/temperature-control-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/temperature-control-cluster.xml @@ -40,48 +40,17 @@ limitations under the License. - - TemperatureSetpoint - - - - - - MinTemperature - - - - - - MaxTemperature - - - - - - Step - - - - - - SelectedTemperatureLevel - - - - - - SupportedTemperatureLevels - - - - + TemperatureSetpoint + MinTemperature + MaxTemperature + Step + SelectedTemperatureLevel + SupportedTemperatureLevels - Set Temperature - - - + Set Temperature + + diff --git a/src/app/zap-templates/zcl/data-model/chip/temperature-measurement-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/temperature-measurement-cluster.xml index 45317b7b433894..d141743fafde56 100644 --- a/src/app/zap-templates/zcl/data-model/chip/temperature-measurement-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/temperature-measurement-cluster.xml @@ -24,21 +24,9 @@ limitations under the License. TEMPERATURE_MEASUREMENT_CLUSTER true true - - MeasuredValue - - - - MinMeasuredValue - - - - MaxMeasuredValue - - - - Tolerance - - + MeasuredValue + MinMeasuredValue + MaxMeasuredValue + Tolerance diff --git a/src/app/zap-templates/zcl/data-model/chip/thermostat-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/thermostat-cluster.xml index 9a409b7a89c1bd..6f75aa45e985f6 100644 --- a/src/app/zap-templates/zcl/data-model/chip/thermostat-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/thermostat-cluster.xml @@ -312,368 +312,146 @@ limitations under the License. - - LocalTemperature - - - - OutdoorTemperature - - - - Occupancy - - - - - - AbsMinHeatSetpointLimit - - - - - - AbsMaxHeatSetpointLimit - - - - - - AbsMinCoolSetpointLimit - - - - - - AbsMaxCoolSetpointLimit - - - - - - PICoolingDemand - - - - - - PIHeatingDemand - - - - + LocalTemperature + OutdoorTemperature + Occupancy + AbsMinHeatSetpointLimit + AbsMaxHeatSetpointLimit + AbsMinCoolSetpointLimit + AbsMaxCoolSetpointLimit + PICoolingDemand + PIHeatingDemand HVACSystemTypeConfiguration - LocalTemperatureCalibration - - - - - - - - OccupiedCoolingSetpoint - - - - - - OccupiedHeatingSetpoint - - - - - - UnoccupiedCoolingSetpoint - - - - - - - - - UnoccupiedHeatingSetpoint - - - - - - + OccupiedCoolingSetpoint + OccupiedHeatingSetpoint + UnoccupiedCoolingSetpoint + UnoccupiedHeatingSetpoint MinHeatSetpointLimit - - - MaxHeatSetpointLimit - - - MinCoolSetpointLimit - - - MaxCoolSetpointLimit - - - MinSetpointDeadBand - - - RemoteSensing - ControlSequenceOfOperation - SystemMode - - - - ThermostatRunningMode - - - - - - StartOfWeek - - - - - - NumberOfWeeklyTransitions - - - - - - NumberOfDailyTransitions - - - + ThermostatRunningMode + StartOfWeek + NumberOfWeeklyTransitions + NumberOfDailyTransitions TemperatureSetpointHold - TemperatureSetpointHoldDuration - ThermostatProgrammingOperationMode - - - - ThermostatRunningState - - - - SetpointChangeSource - - - - SetpointChangeAmount - - - - SetpointChangeSourceTimestamp - + ThermostatRunningState + SetpointChangeSource + SetpointChangeAmount + SetpointChangeSourceTimestamp OccupiedSetback - - - - - - OccupiedSetbackMin - - - - - - OccupiedSetbackMax - - - + OccupiedSetbackMin + OccupiedSetbackMax UnoccupiedSetback - - - - - - - - - UnoccupiedSetbackMin - - - - - - - - - UnoccupiedSetbackMax - - - - - - + UnoccupiedSetbackMin + UnoccupiedSetbackMax EmergencyHeatDelta - ACType - ACCapacity - ACRefrigerantType - ACCompressorType - ACErrorCode - ACLouverPosition - - - - ACCoilTemperature - + ACCoilTemperature ACCapacityformat - - - - PresetTypes - - - - - - ScheduleTypes - - - - - - NumberOfPresets - - - - - - NumberOfSchedules - - - - - - NumberOfScheduleTransitions - - - - - - NumberOfScheduleTransitionPerDay - - - - - - ActivePresetHandle - - - - - - ActiveScheduleHandle - - - + PresetTypes + ScheduleTypes + NumberOfPresets + NumberOfSchedules + NumberOfScheduleTransitions + NumberOfScheduleTransitionPerDay + ActivePresetHandle + ActiveScheduleHandle Presets - - - Schedules - - - - - - SetpointHoldExpiryTimestamp - + SetpointHoldExpiryTimestamp Upon receipt, the attributes for the indicated setpoint(s) SHALL have the amount specified in the Amount field added to them. - @@ -683,42 +461,27 @@ limitations under the License. - - - The Current Weekly Schedule Command is sent from the server in response to the Get Weekly Schedule Command. - - - This command is used to clear the weekly schedule. - - - Upon receipt, if the Schedules attribute contains a ScheduleStruct whose ScheduleHandle field matches the value of the ScheduleHandle field, the server SHALL set the thermostat's ActiveScheduleHandle attribute to the value of the ScheduleHandle field. - - - ID - - - @@ -728,9 +491,6 @@ limitations under the License. - - - diff --git a/src/app/zap-templates/zcl/data-model/chip/thermostat-user-interface-configuration-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/thermostat-user-interface-configuration-cluster.xml index a95a9a31f32d9e..cd3491cc079024 100644 --- a/src/app/zap-templates/zcl/data-model/chip/thermostat-user-interface-configuration-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/thermostat-user-interface-configuration-cluster.xml @@ -29,23 +29,18 @@ limitations under the License. - - TemperatureDisplayMode - - - - + TemperatureDisplayMode + + KeypadLockout - ScheduleProgrammingVisibility - diff --git a/src/app/zap-templates/zcl/data-model/chip/thread-border-router-management-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/thread-border-router-management-cluster.xml index 84132e495cf4c0..d05ce70c34aca3 100644 --- a/src/app/zap-templates/zcl/data-model/chip/thread-border-router-management-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/thread-border-router-management-cluster.xml @@ -33,52 +33,31 @@ limitations under the License. - - BorderRouterName - - - - - BorderAgentID - - - - - ThreadVersion - - - - - InterfaceEnabled - - - - - ActiveDatasetTimestamp - - - - - PendingDatasetTimestamp - - - + BorderRouterName + + BorderAgentID + + ThreadVersion + + InterfaceEnabled + + ActiveDatasetTimestamp + + PendingDatasetTimestamp + Command to request the active operational dataset of the Thread network to which the border router is connected. This command must be sent over a valid CASE session - Command to request the pending dataset of the Thread network to which the border router is connected. This command must be sent over a valid CASE session - - + Generated response to GetActiveDatasetRequest or GetPendingDatasetRequest commands. - @@ -86,16 +65,12 @@ limitations under the License. - Command set or update the pending Dataset of the Thread network to which the Border Router is connected. - - - diff --git a/src/app/zap-templates/zcl/data-model/chip/thread-network-diagnostics-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/thread-network-diagnostics-cluster.xml index 8804d64e30c7c1..77ec8699615156 100644 --- a/src/app/zap-templates/zcl/data-model/chip/thread-network-diagnostics-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/thread-network-diagnostics-cluster.xml @@ -107,362 +107,82 @@ limitations under the License. - - - Channel - - - - RoutingRole - - - - NetworkName - - - - PanId - - - - ExtendedPanId - - - - MeshLocalPrefix - - - - OverrunCount - - - - - - NeighborTable - - - - RouteTable - - - - PartitionId - - - - Weighting - - - - DataVersion - - - - StableDataVersion - - - - LeaderRouterId - - - - DetachedRoleCount - - - - - - ChildRoleCount - - - - - - RouterRoleCount - - - - - - LeaderRoleCount - - - - - - AttachAttemptCount - - - - - - PartitionIdChangeCount - - - - - - BetterPartitionAttachAttemptCount - - - - - - ParentChangeCount - - - - - - TxTotalCount - - - - - - TxUnicastCount - - - - - - TxBroadcastCount - - - - - - TxAckRequestedCount - - - - - - TxAckedCount - - - - - - TxNoAckRequestedCount - - - - - - TxDataCount - - - - - - TxDataPollCount - - - - - - TxBeaconCount - - - - - - TxBeaconRequestCount - - - - - - TxOtherCount - - - - - - TxRetryCount - - - - - - TxDirectMaxRetryExpiryCount - - - - - - TxIndirectMaxRetryExpiryCount - - - - - - TxErrCcaCount - - - - - - TxErrAbortCount - - - - - - TxErrBusyChannelCount - - - - - - RxTotalCount - - - - - - RxUnicastCount - - - - - - RxBroadcastCount - - - - - - RxDataCount - - - - - - RxDataPollCount - - - - - - RxBeaconCount - - - - - - RxBeaconRequestCount - - - - - - RxOtherCount - - - - - - RxAddressFilteredCount - - - - - - RxDestAddrFilteredCount - - - - - - RxDuplicatedCount - - - - - - RxErrNoFrameCount - - - - - - RxErrUnknownNeighborCount - - - - - - RxErrInvalidSrcAddrCount - - - - - - RxErrSecCount - - - - - - RxErrFcsCount - - - - - - RxErrOtherCount - - - - - - ActiveTimestamp - - - - PendingTimestamp - - - - Delay - - - - SecurityPolicy - - - - ChannelPage0Mask - - - - OperationalDatasetComponents - - - - ActiveNetworkFaultsList - - + + Channel + RoutingRole + NetworkName + PanId + ExtendedPanId + MeshLocalPrefix + OverrunCount + NeighborTable + RouteTable + PartitionId + Weighting + DataVersion + StableDataVersion + LeaderRouterId + DetachedRoleCount + ChildRoleCount + RouterRoleCount + LeaderRoleCount + AttachAttemptCount + PartitionIdChangeCount + BetterPartitionAttachAttemptCount + ParentChangeCount + TxTotalCount + TxUnicastCount + TxBroadcastCount + TxAckRequestedCount + TxAckedCount + TxNoAckRequestedCount + TxDataCount + TxDataPollCount + TxBeaconCount + TxBeaconRequestCount + TxOtherCount + TxRetryCount + TxDirectMaxRetryExpiryCount + TxIndirectMaxRetryExpiryCount + TxErrCcaCount + TxErrAbortCount + TxErrBusyChannelCount + RxTotalCount + RxUnicastCount + RxBroadcastCount + RxDataCount + RxDataPollCount + RxBeaconCount + RxBeaconRequestCount + RxOtherCount + RxAddressFilteredCount + RxDestAddrFilteredCount + RxDuplicatedCount + RxErrNoFrameCount + RxErrUnknownNeighborCount + RxErrInvalidSrcAddrCount + RxErrSecCount + RxErrFcsCount + RxErrOtherCount + ActiveTimestamp + PendingTimestamp + Delay + SecurityPolicy + ChannelPage0Mask + OperationalDatasetComponents + ActiveNetworkFaultsList Reception of this command SHALL reset the OverrunCount attributes to 0 - - - Indicate that a Node’s connection status to a Thread network has changed - Indicate a change in the set of network faults currently detected by the Node - diff --git a/src/app/zap-templates/zcl/data-model/chip/thread-network-directory-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/thread-network-directory-cluster.xml index 8f997cebc46d2f..3a6445b15bbad3 100644 --- a/src/app/zap-templates/zcl/data-model/chip/thread-network-directory-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/thread-network-directory-cluster.xml @@ -15,67 +15,58 @@ See the License for the specific language governing permissions and limitations under the License. --> - - - - - - - - - + - - Network Infrastructure - Thread Network Directory - 0x0453 - THREAD_NETWORK_DIRECTORY_CLUSTER - Manages the names and credentials of Thread networks visible to the user. + + + + + + + - true - true + + Network Infrastructure + Thread Network Directory + 0x0453 + THREAD_NETWORK_DIRECTORY_CLUSTER + Manages the names and credentials of Thread networks visible to the user. - - - - - PreferredExtendedPanID - - - - - - ThreadNetworks - - - - - ThreadNetworkTableSize - - + true + true - - Adds an entry to the ThreadNetworks list. - - - - - - Removes an entry from the ThreadNetworks list. - - - - - - Retrieves a Thread Operational Dataset from the ThreadNetworks list. - - - - - - This is the response to a GetOperationalDataset request. - - - - + + + + + PreferredExtendedPanID + + + + + ThreadNetworks + + + ThreadNetworkTableSize + + + Adds an entry to the ThreadNetworks list. + + + + + Removes an entry from the ThreadNetworks list. + + + + + Retrieves a Thread Operational Dataset from the ThreadNetworks list. + + + + + This is the response to a GetOperationalDataset request. + + + diff --git a/src/app/zap-templates/zcl/data-model/chip/time-format-localization-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/time-format-localization-cluster.xml index bfc2222ef35a4a..6ade7abe2e446c 100644 --- a/src/app/zap-templates/zcl/data-model/chip/time-format-localization-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/time-format-localization-cluster.xml @@ -58,23 +58,14 @@ limitations under the License. - - HourFormat - - + + HourFormat + - ActiveCalendarType - - - - - - - SupportedCalendarTypes - - - + ActiveCalendarType + + SupportedCalendarTypes diff --git a/src/app/zap-templates/zcl/data-model/chip/time-synchronization-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/time-synchronization-cluster.xml index 201f71a201e523..9336a6a944735e 100644 --- a/src/app/zap-templates/zcl/data-model/chip/time-synchronization-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/time-synchronization-cluster.xml @@ -114,166 +114,78 @@ limitations under the License. - - UTCTime - - - - Granularity - - - - TimeSource - - - - TrustedTimeSource - - - - - - DefaultNTP - - - - - - TimeZone - - - - - - DSTOffset - - - - - - LocalTime - - - - - - TimeZoneDatabase - - - - - - NTPServerAvailable - - - - - - TimeZoneListMaxSize - - - - - - DSTOffsetListMaxSize - - - - - - SupportsDNSResolve - - - - - + UTCTime + Granularity + TimeSource + TrustedTimeSource + DefaultNTP + TimeZone + DSTOffset + LocalTime + TimeZoneDatabase + NTPServerAvailable + TimeZoneListMaxSize + DSTOffsetListMaxSize + SupportsDNSResolve + This command MAY be issued by Administrator to set the time. - This command SHALL set TrustedTimeSource. - - - This command SHALL set TimeZone. - - - Response to SetTimeZone. - - - This command SHALL set DSTOffset. - - - This command is used to set DefaultNTP. - - - This event SHALL be generated when the server stops applying the current DSTOffset and there are no entries in the list with a larger ValidStarting time. - - - This event SHALL be generated when the server starts or stops applying a DST offset. - - - - + This event SHALL be generated when the server changes its time zone offset or name. - - - This event SHALL be generated if the node has attempted to update its time, but was unable to find a good time from any source. - This event SHALL be generated if the node attempts to update its time and finds that the TrustedTimeSource is null, or the specified peer cannot be reached. - - - diff --git a/src/app/zap-templates/zcl/data-model/chip/unit-localization-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/unit-localization-cluster.xml index 0deb6225eedab9..fb6238add46a4f 100644 --- a/src/app/zap-templates/zcl/data-model/chip/unit-localization-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/unit-localization-cluster.xml @@ -43,11 +43,8 @@ limitations under the License. - TemperatureUnit - - - - + TemperatureUnit + diff --git a/src/app/zap-templates/zcl/data-model/chip/user-label-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/user-label-cluster.xml index 14ffa15b70bd11..24260b78307bd3 100644 --- a/src/app/zap-templates/zcl/data-model/chip/user-label-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/user-label-cluster.xml @@ -27,7 +27,6 @@ limitations under the License. LabelList - diff --git a/src/app/zap-templates/zcl/data-model/chip/valve-configuration-and-control-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/valve-configuration-and-control-cluster.xml index 052a08108a69da..80c1cdb60c8ccc 100644 --- a/src/app/zap-templates/zcl/data-model/chip/valve-configuration-and-control-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/valve-configuration-and-control-cluster.xml @@ -59,86 +59,39 @@ limitations under the License. - - OpenDuration - - + OpenDuration - - DefaultOpenDuration - - - - AutoCloseTime - - - - - - RemainingDuration - - - - CurrentState - - - - TargetState - - - - CurrentLevel - - - - - - TargetLevel - - - - - - DefaultOpenLevel - - - - - - ValveFault - - - - LevelStep - - - - - + DefaultOpenDuration + AutoCloseTime + RemainingDuration + CurrentState + TargetState + CurrentLevel + TargetLevel + DefaultOpenLevel + ValveFault + LevelStep + This command is used to set the valve to its open position. - This command is used to set the valve to its closed position. - This event SHALL be generated when the valve state changed. - This event SHALL be generated when the valve registers or clears a fault. - diff --git a/src/app/zap-templates/zcl/data-model/chip/wake-on-lan-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/wake-on-lan-cluster.xml index 50c88a02726515..90bd18b5b7baaa 100644 --- a/src/app/zap-templates/zcl/data-model/chip/wake-on-lan-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/wake-on-lan-cluster.xml @@ -27,14 +27,8 @@ limitations under the License. - - - MACAddress - - - - LinkLocalAddress - - + + MACAddress + LinkLocalAddress diff --git a/src/app/zap-templates/zcl/data-model/chip/washer-controls-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/washer-controls-cluster.xml index 663f13dfcc1271..2dc01920ae3e37 100644 --- a/src/app/zap-templates/zcl/data-model/chip/washer-controls-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/washer-controls-cluster.xml @@ -45,31 +45,11 @@ limitations under the License. - - - SpinSpeeds - - - - - - SpinSpeedCurrent - - - - - - NumberOfRinses - - - - - - SupportedRinses - - - - + + SpinSpeeds + SpinSpeedCurrent + NumberOfRinses + SupportedRinses diff --git a/src/app/zap-templates/zcl/data-model/chip/water-heater-management-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/water-heater-management-cluster.xml index 6e5c56e21f9670..beeaf277b77d2e 100644 --- a/src/app/zap-templates/zcl/data-model/chip/water-heater-management-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/water-heater-management-cluster.xml @@ -64,58 +64,30 @@ Git: 1.4-prerelease-ipr-69-ge15ff5700 true - - HeaterTypes - - - - HeatDemand - - - - TankVolume - - - - - - EstimatedHeatRequired - - - - - - TankPercentage - - - - - - BoostState - - + HeaterTypes + HeatDemand + TankVolume + EstimatedHeatRequired + TankPercentage + BoostState Allows a client to request that the water heater is put into a Boost state. - Allows a client to cancel an ongoing Boost operation. - This event SHALL be generated whenever a Boost command is accepted. - This event SHALL be generated whenever the BoostState transitions from Active to Inactive. - diff --git a/src/app/zap-templates/zcl/data-model/chip/water-heater-mode-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/water-heater-mode-cluster.xml index 89d8b78436337c..d9211e808467fb 100644 --- a/src/app/zap-templates/zcl/data-model/chip/water-heater-mode-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/water-heater-mode-cluster.xml @@ -58,26 +58,18 @@ Git: 1.4-prerelease-ipr-69-ge15ff5700 - - SupportedModes - - - - CurrentMode - - + SupportedModes + CurrentMode This command is used to change device modes. - This command is sent by the device on receipt of the ChangeToMode command. - diff --git a/src/app/zap-templates/zcl/data-model/chip/wifi-network-diagnostics-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/wifi-network-diagnostics-cluster.xml index f2a68e977bf965..7fb35aab255ed7 100644 --- a/src/app/zap-templates/zcl/data-model/chip/wifi-network-diagnostics-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/wifi-network-diagnostics-cluster.xml @@ -63,94 +63,35 @@ limitations under the License. - - - BSSID - - - - SecurityType - - - - WiFiVersion - - - - ChannelNumber - - - - RSSI - - - - BeaconLostCount - - - - - - BeaconRxCount - - - - - - PacketMulticastRxCount - - - - - - PacketMulticastTxCount - - - - - - PacketUnicastRxCount - - - - - - PacketUnicastTxCount - - - - - - CurrentMaxRate - - - - OverrunCount - - - - + + BSSID + SecurityType + WiFiVersion + ChannelNumber + RSSI + BeaconLostCount + BeaconRxCount + PacketMulticastRxCount + PacketMulticastTxCount + PacketUnicastRxCount + PacketUnicastTxCount + CurrentMaxRate + OverrunCount Reception of this command SHALL reset the Breacon and Packet related count attributes to 0 - - - Indicate that a Node’s Wi-Fi connection has been disconnected as a result of de-authenticated or dis-association and indicates the reason. - Indicate that a Node has failed to connect, or reconnect, to a Wi-Fi access point. - Indicate that a Node’s connection status to a Wi-Fi network has changed. - diff --git a/src/app/zap-templates/zcl/data-model/chip/wifi-network-management-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/wifi-network-management-cluster.xml index c5246f6acddfc2..8c8b4d40c3abdd 100644 --- a/src/app/zap-templates/zcl/data-model/chip/wifi-network-management-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/wifi-network-management-cluster.xml @@ -30,25 +30,19 @@ limitations under the License. - - SSID - - + SSID PassphraseSurrogate - Request the current WPA-Personal passphrase or PSK associated with the managed Wi-Fi network. - This is the response to a NetworkPassphraseRequest. - diff --git a/src/app/zap-templates/zcl/data-model/chip/window-covering.xml b/src/app/zap-templates/zcl/data-model/chip/window-covering.xml index 1363b5c8aa4c9d..0e1c97a4d45040 100644 --- a/src/app/zap-templates/zcl/data-model/chip/window-covering.xml +++ b/src/app/zap-templates/zcl/data-model/chip/window-covering.xml @@ -57,186 +57,45 @@ limitations under the License. - - Type - - + Type - - PhysicalClosedLimitLift - - - - - - - - + PhysicalClosedLimitLift - - PhysicalClosedLimitTilt - - - - - - - - + PhysicalClosedLimitTilt - - CurrentPositionLift - - - - - - - - + CurrentPositionLift - - CurrentPositionTilt - - - - - - - - + CurrentPositionTilt - - NumberOfActuationsLift - - - - + NumberOfActuationsLift - - NumberOfActuationsTilt - - - - + NumberOfActuationsTilt - - ConfigStatus - - + ConfigStatus - - CurrentPositionLiftPercentage - - - - - - - + CurrentPositionLiftPercentage - - CurrentPositionTiltPercentage - - - - - - - + CurrentPositionTiltPercentage - - OperationalStatus - - + OperationalStatus - - TargetPositionLiftPercent100ths - - - - - - - + TargetPositionLiftPercent100ths - - TargetPositionTiltPercent100ths - - - - - - - + TargetPositionTiltPercent100ths - - EndProductType - - + EndProductType - - CurrentPositionLiftPercent100ths - - - - - - - + CurrentPositionLiftPercent100ths - - CurrentPositionTiltPercent100ths - - - - - - - + CurrentPositionTiltPercent100ths + - - InstalledOpenLimitLift - - - - - - - - - - InstalledClosedLimitLift - - - - - - - - + InstalledOpenLimitLift + InstalledClosedLimitLift - - InstalledOpenLimitTilt - - - - - - - - - - InstalledClosedLimitTilt - - - - - - - - + InstalledOpenLimitTilt + InstalledClosedLimitTilt @@ -245,85 +104,44 @@ limitations under the License. Mode - - + - - SafetyStatus - - - + SafetyStatus + Moves window covering to InstalledOpenLimitLift and InstalledOpenLimitTilt - Moves window covering to InstalledClosedLimitLift and InstalledCloseLimitTilt - Stop any adjusting of window covering - Go to lift value specified - - - - - - Go to lift percentage specified - - - - - - - - - - - Go to tilt value specified - - - - - - Go to tilt percentage specified - - - - - - - - - - - From f5a0b6f81c42f42b954d66079f709be087e34c9d Mon Sep 17 00:00:00 2001 From: Hasty Granbery Date: Wed, 23 Oct 2024 11:40:35 -0700 Subject: [PATCH 087/149] [HVAC] Add check for per-preset-scenario limit (#35310) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [HVAC] Check if number of preset scenarios exceeds maximum number of scenarios * [NXP][Zephyr] Provide AP band in connection request parameters (#35181) Signed-off-by: Axel Le Bourhis * Plumbing for CADMIN attribute updates from fabric-admin to fabric-bridge (#35222) * Fix TC_BRBINFO_4_1 for execution on TH (#35257) * [Fabric-Admin] Move DeviceSynchronization from pairing command to device_manager (#35260) * Move DeviceSynchronization from pairing command to device_manager * Restyled by gn --------- Co-authored-by: Restyled.io * Add command-line argument to allow userprompt at start of ECOINFO_2_1 (#35234) --------- Co-authored-by: Restyled.io Co-authored-by: saurabhst * Testing fixes for TC_SWTCH from TE2 (#34984) * Testing fixes for TC_SWTCH from TE2 - all-clusters-app was not generating button position changes in some cases. This was not detected in some situations since the test cases don't always test for this. - Prompts are missing endpoint ID which makes it hard when running per-endpoint tests to know where it applies. - Some partials could fail on decode errors, causing test errors instead of fails. This PR: - Adds correct generation of positions on press/release. - Adds a way to claim endpoint tested in user prompts - Fixes failing on decode errors in partials Testing done: - TC_SWTCH still passes - Manually validated button position in multi-press test/simulation (update to TC_SWTCH needs test plan changes). Issue is in all-clusters-app for CI only. See https://github.com/CHIP-Specifications/chip-test-plans/issues/4493 * Restyled by autopep8 * Update prompt support --------- Co-authored-by: Restyled.io * Add test cases for testing additional Presets write and commit constr… (#35141) * Add test cases for testing additional Presets write and commit constraints - Add a test for adding a preset with a preset scenario not present in PresetTypes - Add a test for testing addition of presets such that the total number of presets added is greater than the total number of presets supported * Add rollback after test step 18 * Modify the number of presets supported test case to read the number of presets supported and build a preset list whose size exceeds that to test * Modify the number of presets supported test case to read the number of presets supported and build a preset list whose size exceeds that to test * Update thermostat-delegate-impl.h * Address review comments * Add support to check for numberOfPresets supported for each preset type and build the presets list with multiple presets of each type * Restyled by autopep8 * Fix log line formatting * Update src/python_testing/TC_TSTAT_4_2.py Co-authored-by: Boris Zbarsky * Fix test step 17 to find a preset scenario in PresetScenarioEnum that is not present in PresetTypes to run the test - Fix test step 18 to build a presets list that exceeds the number of presets supported correctly * Restyled by autopep8 * Fix lint errors * Add a while loop to add more presets until max is reached --------- Co-authored-by: Restyled.io Co-authored-by: Boris Zbarsky * Allow TestAccessControl to run with ARL (#35262) * Allow TestAccessControl to run with ARL Since RequestType is required, set each test data entry to some value that will pass AccessRestrictionProvider checks (since the focus is on AccessControl for these tests). * Copy the test data's request path and optionally add RequestType * Make zap_downloadl.py create a usable zap.app on Mac (#35242) Use the unzip utility on Mac for unzipping instead of zipfile. In addition to not supporting file modes (which the script already works around) the zipfile module also doesn't support symlinks. The embedded frameworks inside zap.app rely on symlinks for the application to work. * TBRM Tests scripts consistency with te2 fixes (#35153) * Add files via upload Add yaml test script for TBRM * Update TEST_TC_TBRM_2.2.yaml * Update TEST_TC_TBRM_2.3.yaml * Update TEST_TC_TBRM_2.4.yaml * Test script consitancy wit test plan after TE2 * Test script consitancy wit test plan after TE2 * Update src/app/tests/suites/certification/Test_TC_TBRM_2_3.yaml Co-authored-by: Karsten Sperling <113487422+ksperling-apple@users.noreply.github.com> * Update src/app/tests/suites/certification/Test_TC_TBRM_2_2.yaml Co-authored-by: Karsten Sperling <113487422+ksperling-apple@users.noreply.github.com> * Restyled by whitespace * Restyled by prettier-yaml * Test_TC_TBRM_2_4. synchronisation with TC-THNETDIR-2.3 according test Plan * Restyled by whitespace * Test tweaks to get CI to pass - Use pairing payload matching the other parameters - Check response of ArmFailSafe commands - Fix bad merge in commissioner_commands.py * Restyled by prettier-yaml --------- Co-authored-by: StephaneGUELEC <94045077+StephaneGUELEC@users.noreply.github.com> Co-authored-by: Karsten Sperling <113487422+ksperling-apple@users.noreply.github.com> Co-authored-by: Restyled.io Co-authored-by: Karsten Sperling * [HVAC] Alter Thermostat Preset tests to not rely on knowledge of the server's initial state * Pick midpoint setpoints for new presets * Lint fixes * Apply suggestions from code review Co-authored-by: Boris Zbarsky * Fixes from code review * Apply suggestions from code review Co-authored-by: Boris Zbarsky * Fix remaining places with hard-coded setpoints * Don't abort test if there are no built-in presets * Remove unneeded length check * Fix max number of preset types * Add test for individual preset scenario limits * Fix lint issue * Return invalid in state if we're unable to iterate over the preset types for some reason * Apply suggestions from code review Co-authored-by: Boris Zbarsky * Remove unneeded active preset setting * Restyled patch * Suggestions from code review --------- Signed-off-by: Axel Le Bourhis Co-authored-by: Axel Le Bourhis <45206070+axelnxp@users.noreply.github.com> Co-authored-by: Terence Hampson Co-authored-by: Yufeng Wang Co-authored-by: Restyled.io Co-authored-by: saurabhst Co-authored-by: Tennessee Carmel-Veilleux Co-authored-by: Nivi Sarkar <55898241+nivi-apple@users.noreply.github.com> Co-authored-by: Boris Zbarsky Co-authored-by: Thomas Lea <35579828+tleacmcsa@users.noreply.github.com> Co-authored-by: Karsten Sperling <113487422+ksperling-apple@users.noreply.github.com> Co-authored-by: marchemi <56955785+marchemi@users.noreply.github.com> Co-authored-by: StephaneGUELEC <94045077+StephaneGUELEC@users.noreply.github.com> Co-authored-by: Karsten Sperling --- .../thermostat-server-presets.cpp | 109 +++++++++--------- src/python_testing/TC_TSTAT_4_2.py | 28 ++++- 2 files changed, 78 insertions(+), 59 deletions(-) diff --git a/src/app/clusters/thermostat-server/thermostat-server-presets.cpp b/src/app/clusters/thermostat-server/thermostat-server-presets.cpp index 9413513fd0cedd..1dede071619962 100644 --- a/src/app/clusters/thermostat-server/thermostat-server-presets.cpp +++ b/src/app/clusters/thermostat-server/thermostat-server-presets.cpp @@ -152,69 +152,36 @@ bool GetMatchingPresetInPresets(Delegate * delegate, const DataModel::NullableGetPendingPresetAtIndex(i, pendingPreset); - + PresetTypeStruct::Type presetType; + auto err = delegate->GetPresetTypeAtIndex(i, presetType); if (err == CHIP_ERROR_PROVIDER_LIST_EXHAUSTED) { - break; + // We exhausted the list trying to find the preset scenario + return CHIP_NO_ERROR; } if (err != CHIP_NO_ERROR) { - ChipLogError(Zcl, "CountNumberOfPendingPresets: GetPendingPresetAtIndex failed with error %" CHIP_ERROR_FORMAT, - err.Format()); - return 0; + return err; } - numberOfPendingPresets++; - } - - return numberOfPendingPresets; -} - -/** - * @brief Checks if the presetScenario is present in the PresetTypes attribute. - * - * @param[in] delegate The delegate to use. - * @param[in] presetScenario The presetScenario to match with. - * - * @return true if the presetScenario is found, false otherwise. - */ -bool PresetScenarioExistsInPresetTypes(Delegate * delegate, PresetScenarioEnum presetScenario) -{ - VerifyOrReturnValue(delegate != nullptr, false); - - for (uint8_t i = 0; true; i++) - { - PresetTypeStruct::Type presetType; - auto err = delegate->GetPresetTypeAtIndex(i, presetType); - if (err != CHIP_NO_ERROR) - { - return false; - } - if (presetType.presetScenario == presetScenario) { - return true; + count = presetType.numberOfPresets; + return CHIP_NO_ERROR; } } - return false; + return CHIP_NO_ERROR; } /** @@ -410,8 +377,16 @@ CHIP_ERROR ThermostatAttrAccess::AppendPendingPreset(Thermostat::Delegate * dele } } - if (!PresetScenarioExistsInPresetTypes(delegate, preset.GetPresetScenario())) + size_t maximumPresetCount = delegate->GetNumberOfPresets(); + size_t maximumPresetScenarioCount = 0; + if (MaximumPresetScenarioCount(delegate, preset.GetPresetScenario(), maximumPresetScenarioCount) != CHIP_NO_ERROR) { + return CHIP_IM_GLOBAL_STATUS(InvalidInState); + } + + if (maximumPresetScenarioCount == 0) + { + // This is not a supported preset scenario return CHIP_IM_GLOBAL_STATUS(ConstraintError); } @@ -423,16 +398,42 @@ CHIP_ERROR ThermostatAttrAccess::AppendPendingPreset(Thermostat::Delegate * dele // Before adding this preset to the pending presets, if the expected length of the pending presets' list // exceeds the total number of presets supported, return RESOURCE_EXHAUSTED. Note that the preset has not been appended yet. - uint8_t numberOfPendingPresets = CountNumberOfPendingPresets(delegate); + // We're going to append this preset, so let's assume a count as though it had already been inserted + size_t presetCount = 1; + size_t presetScenarioCount = 1; + for (uint8_t i = 0; true; i++) + { + PresetStructWithOwnedMembers otherPreset; + CHIP_ERROR err = delegate->GetPendingPresetAtIndex(i, otherPreset); + + if (err == CHIP_ERROR_PROVIDER_LIST_EXHAUSTED) + { + break; + } + if (err != CHIP_NO_ERROR) + { + return CHIP_IM_GLOBAL_STATUS(InvalidInState); + } + presetCount++; + if (preset.GetPresetScenario() == otherPreset.GetPresetScenario()) + { + presetScenarioCount++; + } + } - // We will be adding one more preset, so reject if the length is already at max. - if (numberOfPendingPresets >= delegate->GetNumberOfPresets()) + if (presetCount > maximumPresetCount) { + ChipLogError(Zcl, "Preset count exceeded %u: %u ", static_cast(maximumPresetCount), + static_cast(presetCount)); return CHIP_IM_GLOBAL_STATUS(ResourceExhausted); } - // TODO #34556 : Check if the number of presets for each presetScenario exceeds the max number of presets supported for that - // scenario. We plan to support only one preset for each presetScenario for our use cases so defer this for re-evaluation. + if (presetScenarioCount > maximumPresetScenarioCount) + { + ChipLogError(Zcl, "Preset scenario count exceeded %u: %u ", static_cast(maximumPresetScenarioCount), + static_cast(presetScenarioCount)); + return CHIP_IM_GLOBAL_STATUS(ResourceExhausted); + } return delegate->AppendToPendingPresetList(preset); } diff --git a/src/python_testing/TC_TSTAT_4_2.py b/src/python_testing/TC_TSTAT_4_2.py index 6dad144f3050c4..85ff487a9dc639 100644 --- a/src/python_testing/TC_TSTAT_4_2.py +++ b/src/python_testing/TC_TSTAT_4_2.py @@ -37,6 +37,7 @@ import copy import logging import random +from collections import namedtuple import chip.clusters as Clusters from chip import ChipDeviceCtrl # Needed before chip.FabricAdmin @@ -418,11 +419,6 @@ async def test_TC_TSTAT_4_2(self): logger.info( "Couldn't run test step 4 since there were no built-in presets") - # Send the SetActivePresetRequest command - await self.send_set_active_preset_handle_request_command(value=b'\x03') - - activePresetHandle = await self.read_single_attribute_check_success(endpoint=endpoint, cluster=cluster, attribute=cluster.Attributes.ActivePresetHandle) - self.step("5") if self.pics_guard(self.check_pics("TSTAT.S.F08") and self.check_pics("TSTAT.S.A0050") and self.check_pics("TSTAT.S.Cfe.Rsp")): @@ -714,6 +710,28 @@ async def test_TC_TSTAT_4_2(self): self.step("18") if self.pics_guard(self.check_pics("TSTAT.S.F08") and self.check_pics("TSTAT.S.A0050") and self.check_pics("TSTAT.S.Cfe.Rsp")): + ScenarioHeadroom = namedtuple("ScenarioHeadroom", "presetScenario remaining") + # Generate list of tuples of scenarios and number of remaining presets per scenario allowed + presetScenarioHeadrooms = list(ScenarioHeadroom(presetType.presetScenario, + presetType.numberOfPresets - presetScenarioCounts.get(presetType.presetScenario, 0)) for presetType in presetTypes) + + if presetScenarioHeadrooms: + # Find the preset scenario with the smallest number of remaining allowed presets + presetScenarioHeadrooms = sorted(presetScenarioHeadrooms, key=lambda psh: psh.remaining) + presetScenarioHeadroom = presetScenarioHeadrooms[0] + + # Add one more preset than is allowed by the preset type + test_presets = copy.deepcopy(current_presets) + test_presets.extend([cluster.Structs.PresetStruct(presetHandle=NullValue, presetScenario=presetScenarioHeadroom.presetScenario, + coolingSetpoint=coolSetpoint, heatingSetpoint=heatSetpoint, builtIn=False)] * (presetScenarioHeadroom.remaining + 1)) + + await self.send_atomic_request_begin_command() + + await self.write_presets(endpoint=endpoint, presets=test_presets, expected_status=Status.ResourceExhausted) + + # Clear state for next test. + await self.send_atomic_request_rollback_command() + # Calculate the length of the Presets list that could be created using the preset scenarios in PresetTypes and numberOfPresets supported for each scenario. totalExpectedPresetsLength = sum(presetType.numberOfPresets for presetType in presetTypes) From 8933398eda4f3ab3b4d9d9e6b85a0d5a121c1a7c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 23 Oct 2024 18:48:29 +0000 Subject: [PATCH 088/149] Bump third_party/openthread/repo from `2aeb8b8` to `287dbfa` (#36012) Bumps [third_party/openthread/repo](https://github.com/openthread/openthread) from `2aeb8b8` to `287dbfa`. - [Release notes](https://github.com/openthread/openthread/releases) - [Commits](https://github.com/openthread/openthread/compare/2aeb8b833ba760ec29d5f340dd1ce7bcb61c5d56...287dbfa25130ead5010877e934effbb0a2534265) --- updated-dependencies: - dependency-name: third_party/openthread/repo dependency-type: direct:production ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Andrei Litvin --- third_party/openthread/repo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/openthread/repo b/third_party/openthread/repo index 2aeb8b833ba760..287dbfa25130ea 160000 --- a/third_party/openthread/repo +++ b/third_party/openthread/repo @@ -1 +1 @@ -Subproject commit 2aeb8b833ba760ec29d5f340dd1ce7bcb61c5d56 +Subproject commit 287dbfa25130ead5010877e934effbb0a2534265 From 197f698bb873eab5cd70703d8855abd62367709d Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Wed, 23 Oct 2024 16:38:42 -0400 Subject: [PATCH 089/149] Add a BigEndian::Reader to be the equivalent for LittleEndian::Reader (#36195) * Add a big endian reader since we seem to potentially want this * Minor re-arrange * Fix includes * Restyled by clang-format * make some compilers happy * Update src/lib/support/BufferReader.h Co-authored-by: Boris Zbarsky --------- Co-authored-by: Andrei Litvin Co-authored-by: Restyled.io Co-authored-by: Boris Zbarsky --- src/lib/support/BufferReader.cpp | 91 +++++--- src/lib/support/BufferReader.h | 245 +++++++++++++++------ src/lib/support/tests/TestBufferReader.cpp | 49 +++-- 3 files changed, 276 insertions(+), 109 deletions(-) diff --git a/src/lib/support/BufferReader.cpp b/src/lib/support/BufferReader.cpp index 02bce8f3fe0615..cbd13f1ed172dc 100644 --- a/src/lib/support/BufferReader.cpp +++ b/src/lib/support/BufferReader.cpp @@ -18,12 +18,29 @@ #include "BufferReader.h" #include +#include +#include #include #include namespace chip { namespace Encoding { + +BufferReader & BufferReader::ReadBytes(uint8_t * dest, size_t size) +{ + static_assert(CHAR_BIT == 8, "Our various sizeof checks rely on bytes and octets being the same thing"); + + if (EnsureAvailable(size)) + { + memcpy(dest, mReadPtr, size); + mReadPtr += size; + mAvailable -= size; + } + + return *this; +} + namespace LittleEndian { namespace { @@ -58,37 +75,12 @@ void Reader::RawReadLowLevelBeCareful(T * retval) constexpr size_t data_size = sizeof(T); - if (mAvailable < data_size) - { - mStatus = CHIP_ERROR_BUFFER_TOO_SMALL; - // Ensure that future reads all fail. - mAvailable = 0; - return; - } - - ReadHelper(mReadPtr, retval); - mReadPtr += data_size; - - mAvailable = static_cast(mAvailable - data_size); -} - -Reader & Reader::ReadBytes(uint8_t * dest, size_t size) -{ - static_assert(CHAR_BIT == 8, "Our various sizeof checks rely on bytes and octets being the same thing"); - - if ((size > UINT16_MAX) || (mAvailable < size)) + if (EnsureAvailable(data_size)) { - mStatus = CHIP_ERROR_BUFFER_TOO_SMALL; - // Ensure that future reads all fail. - mAvailable = 0; - return *this; + ReadHelper(mReadPtr, retval); + mReadPtr += data_size; + mAvailable -= data_size; } - - memcpy(dest, mReadPtr, size); - - mReadPtr += size; - mAvailable = static_cast(mAvailable - size); - return *this; } // Explicit Read instantiations for the data types we want to support. @@ -104,5 +96,46 @@ template void Reader::RawReadLowLevelBeCareful(uint32_t *); template void Reader::RawReadLowLevelBeCareful(uint64_t *); } // namespace LittleEndian + +namespace BigEndian { + +Reader & Reader::Read16(uint16_t * dest) +{ + if (!EnsureAvailable(sizeof(uint16_t))) + { + return *this; + } + + static_assert(sizeof(*dest) == 2); + + *dest = static_cast((mReadPtr[0] << 8) + mReadPtr[1]); + mReadPtr += 2; + mAvailable -= 2; + return *this; +} + +Reader & Reader::Read32(uint32_t * dest) +{ + if (!EnsureAvailable(sizeof(uint32_t))) + { + return *this; + } + + static_assert(sizeof(*dest) == 4); + + *dest = 0; + for (unsigned i = 0; i < sizeof(uint32_t); i++) + { + *dest <<= 8; + *dest += mReadPtr[i]; + } + + mReadPtr += sizeof(uint32_t); + mAvailable -= sizeof(uint32_t); + return *this; +} + +} // namespace BigEndian + } // namespace Encoding } // namespace chip diff --git a/src/lib/support/BufferReader.h b/src/lib/support/BufferReader.h index ac9c7145359335..725ca8e23ea915 100644 --- a/src/lib/support/BufferReader.h +++ b/src/lib/support/BufferReader.h @@ -31,26 +31,11 @@ namespace chip { namespace Encoding { -namespace LittleEndian { -/** - * @class Reader - * - * Simple reader for reading little-endian things out of buffers. - */ -class Reader +class BufferReader { public: - /** - * Create a buffer reader from a given buffer and length. - * - * @param buffer The octet buffer from which to read. The caller must ensure - * (most simply by allocating the reader on the stack) that - * the buffer outlives the reader. If `buffer` is nullptr, - * length is automatically overridden to zero, to avoid accesses. - * @param buf_len The number of octets in the buffer. - */ - Reader(const uint8_t * buffer, size_t buf_len) : mBufStart(buffer), mReadPtr(buffer), mAvailable(buf_len) + BufferReader(const uint8_t * buffer, size_t buf_len) : mBufStart(buffer), mReadPtr(buffer), mAvailable(buf_len) { if (mBufStart == nullptr) { @@ -58,15 +43,6 @@ class Reader } } - /** - * Create a buffer reader from a given byte span. - * - * @param buffer The octet buffer byte span from which to read. The caller must ensure - * that the buffer outlives the reader. The buffer's ByteSpan .data() pointer - * is is nullptr, length is automatically overridden to zero, to avoid accesses. - */ - Reader(const ByteSpan & buffer) : Reader(buffer.data(), buffer.size()) {} - /** * Number of octets we have read so far. */ @@ -95,6 +71,121 @@ class Reader */ bool IsSuccess() const { return StatusCode() == CHIP_NO_ERROR; } + /** + * Read a byte string from the BufferReader + * + * @param [out] dest Where the bytes read + * @param [in] size How many bytes to read + * + * @note The read can put the reader in a failed-status state if there are + * not enough octets available. Callers must either continue to do + * more reads on the return value or check its status to see whether + * the sequence of reads that has been performed succeeded. + */ + CHECK_RETURN_VALUE + BufferReader & ReadBytes(uint8_t * dest, size_t size); + + /** + * Access bytes of size length, useful for in-place processing of strings + * + * data_ptr MUST NOT be null and will contain the data pointer with `len` bytes available + * if this call is successful + * + * If len is greater than the number of available bytes, the object enters in a failed status. + */ + CHECK_RETURN_VALUE + BufferReader & ZeroCopyProcessBytes(size_t len, const uint8_t ** data_ptr) + { + if (len > mAvailable) + { + *data_ptr = nullptr; + mStatus = CHIP_ERROR_BUFFER_TOO_SMALL; + // Ensure that future reads all fail. + mAvailable = 0; + } + else + { + *data_ptr = mReadPtr; + mReadPtr += len; + mAvailable -= len; + } + return *this; + } + + /** + * Advance the Reader forward by the specified number of octets. + * + * @param len The number of octets to skip. + * + * @note If the len argument is greater than the number of available octets + * remaining, the Reader will advance to the end of the buffer + * without entering a failed-status state. + */ + BufferReader & Skip(size_t len) + { + len = std::min(len, mAvailable); + mReadPtr += len; + mAvailable = static_cast(mAvailable - len); + return *this; + } + +protected: + /// Our buffer start. + const uint8_t * const mBufStart; + + /// Our current read point. + const uint8_t * mReadPtr; + + /// The number of octets we can still read starting at mReadPtr. + size_t mAvailable; + + /// Our current status. + CHIP_ERROR mStatus = CHIP_NO_ERROR; + + /// Make sure we have at least the given number of bytes available (does not consume them) + bool EnsureAvailable(size_t size) + { + if (mAvailable < size) + { + mStatus = CHIP_ERROR_BUFFER_TOO_SMALL; + // Ensure that future reads all fail. + mAvailable = 0; + return false; + } + return true; + } +}; + +namespace LittleEndian { + +/** + * @class Reader + * + * Simple reader for reading little-endian things out of buffers. + */ +class Reader : public BufferReader +{ +public: + /** + * Create a buffer reader from a given buffer and length. + * + * @param buffer The octet buffer from which to read. The caller must ensure + * (most simply by allocating the reader on the stack) that + * the buffer outlives the reader. If `buffer` is nullptr, + * length is automatically overridden to zero, to avoid accesses. + * @param buf_len The number of octets in the buffer. + */ + Reader(const uint8_t * buffer, size_t buf_len) : BufferReader(buffer, buf_len) {} + + /** + * Create a buffer reader from a given byte span. + * + * @param buffer The octet buffer byte span from which to read. The caller must ensure + * that the buffer outlives the reader. The buffer's ByteSpan .data() pointer + * is is nullptr, length is automatically overridden to zero, to avoid accesses. + */ + Reader(const ByteSpan & buffer) : Reader(buffer.data(), buffer.size()) {} + /** * Read a bool, assuming single byte storage. * @@ -267,20 +358,6 @@ class Reader return *this; } - /** - * Read a byte string from the BufferReader - * - * @param [out] dest Where the bytes read - * @param [in] size How many bytes to read - * - * @note The read can put the reader in a failed-status state if there are - * not enough octets available. Callers must either continue to do - * more reads on the return value or check its status to see whether - * the sequence of reads that has been performed succeeded. - */ - CHECK_RETURN_VALUE - Reader & ReadBytes(uint8_t * dest, size_t size); - /** * Helper for our various APIs so we don't have to write out various logic * multiple times. This is public so that consumers that want to read into @@ -290,46 +367,80 @@ class Reader */ template void RawReadLowLevelBeCareful(T * retval); +}; + +} // namespace LittleEndian +namespace BigEndian { + +/** + * @class Reader + * + * Simple reader for reading big-endian things out of buffers. + */ +class Reader : public BufferReader +{ +public: /** - * Advance the Reader forward by the specified number of octets. - * - * @param len The number of octets to skip. + * Create a buffer reader from a given buffer and length. * - * @note If the len argument is greater than the number of available octets - * remaining, the Reader will advance to the end of the buffer - * without entering a failed-status state. + * @param buffer The octet buffer from which to read. The caller must ensure + * (most simply by allocating the reader on the stack) that + * the buffer outlives the reader. If `buffer` is nullptr, + * length is automatically overridden to zero, to avoid accesses. + * @param buf_len The number of octets in the buffer. */ - Reader & Skip(size_t len) - { - len = std::min(len, mAvailable); - mReadPtr += len; - mAvailable = static_cast(mAvailable - len); - return *this; - } + Reader(const uint8_t * buffer, size_t buf_len) : BufferReader(buffer, buf_len) {} -private: /** - * Our buffer start. + * Create a buffer reader from a given byte span. + * + * @param buffer The octet buffer byte span from which to read. The caller must ensure + * that the buffer outlives the reader. If the buffer's ByteSpan .data() pointer + * is nullptr, length is automatically overridden to zero, to avoid accesses. */ - const uint8_t * const mBufStart; + Reader(const ByteSpan & buffer) : Reader(buffer.data(), buffer.size()) {} /** - * Our current read point. + * Read a single 8-bit unsigned integer. + * + * @param [out] dest Where the 8-bit integer goes. + * + * @note The read can put the reader in a failed-status state if there are + * not enough octets available. Callers must either continue to do + * more reads on the return value or check its status to see whether + * the sequence of reads that has been performed succeeded. */ - const uint8_t * mReadPtr; + CHECK_RETURN_VALUE + Reader & Read8(uint8_t * dest) + { + (void) ReadBytes(dest, 1); + return *this; + } - /** - * The number of octets we can still read starting at mReadPtr. - */ - size_t mAvailable; + CHECK_RETURN_VALUE + Reader & ReadChar(char * dest) + { + (void) ReadBytes(reinterpret_cast(dest), 1); + return *this; + } - /** - * Our current status. - */ - CHIP_ERROR mStatus = CHIP_NO_ERROR; + CHECK_RETURN_VALUE + Reader & ReadBool(char * dest) + { + (void) ReadBytes(reinterpret_cast(dest), 1); + return *this; + } + + /// NOTE: only a subset of reads are supported here, more can be added if used/needed + CHECK_RETURN_VALUE + Reader & Read16(uint16_t * dest); + + CHECK_RETURN_VALUE + Reader & Read32(uint32_t * dest); }; -} // namespace LittleEndian +} // namespace BigEndian + } // namespace Encoding } // namespace chip diff --git a/src/lib/support/tests/TestBufferReader.cpp b/src/lib/support/tests/TestBufferReader.cpp index 97db9cf09737b9..ee100e1506bada 100644 --- a/src/lib/support/tests/TestBufferReader.cpp +++ b/src/lib/support/tests/TestBufferReader.cpp @@ -30,21 +30,21 @@ #include using namespace chip; -using namespace chip::Encoding::LittleEndian; +using namespace chip::Encoding; static const uint8_t test_buffer[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21 }; -struct TestReader : public Reader +struct LittleEndianTestReader : public LittleEndian::Reader { - TestReader() : Reader(test_buffer, std::extent::value) {} + LittleEndianTestReader() : LittleEndian::Reader(test_buffer, std::extent::value) {} }; -struct TestSpanReader : public Reader +struct LittleEndianTestSpanReader : public LittleEndian::Reader { - TestSpanReader() : Reader(ByteSpan{ test_buffer, std::extent::value }) {} + LittleEndianTestSpanReader() : LittleEndian::Reader(ByteSpan{ test_buffer, std::extent::value }) {} }; -static void TestBufferReader_BasicImpl(Reader & reader) +static void TestBufferReader_BasicImpl(LittleEndian::Reader & reader) { uint8_t first; uint16_t second; @@ -75,21 +75,21 @@ static void TestBufferReader_BasicImpl(Reader & reader) TEST(TestBufferReader, TestBufferReader_Basic) { - TestReader reader; + LittleEndianTestReader reader; TestBufferReader_BasicImpl(reader); } TEST(TestBufferReader, TestBufferReader_BasicSpan) { - TestSpanReader reader; + LittleEndianTestSpanReader reader; TestBufferReader_BasicImpl(reader); } TEST(TestBufferReader, TestBufferReader_Saturation) { - TestReader reader; + LittleEndianTestReader reader; uint64_t temp; // Read some bytes out so we can get to the end of the buffer. CHIP_ERROR err = reader.Read64(&temp).StatusCode(); @@ -113,12 +113,13 @@ TEST(TestBufferReader, TestBufferReader_Saturation) TEST(TestBufferReader, TestBufferReader_Skip) { - TestReader reader; + LittleEndianTestReader reader; uint8_t temp = 0; uint16_t firstSkipLen = 2; // Verify Skip() advances the start pointer the correct amount. - CHIP_ERROR err = reader.Skip(firstSkipLen).Read8(&temp).StatusCode(); + reader.Skip(firstSkipLen); + CHIP_ERROR err = reader.Read8(&temp).StatusCode(); EXPECT_EQ(err, CHIP_NO_ERROR); EXPECT_EQ(temp, test_buffer[firstSkipLen]); EXPECT_EQ(reader.OctetsRead(), (firstSkipLen + 1u)); @@ -175,7 +176,8 @@ TEST(TestBufferReader, TestBufferReader_LittleEndianScalars) uint32_t val1 = 0; uint32_t val2 = 0; - EXPECT_TRUE(reader.Skip(1).Read32(&val1).Read32(&val2).IsSuccess()); + reader.Skip(1); + EXPECT_TRUE(reader.Read32(&val1).Read32(&val2).IsSuccess()); EXPECT_EQ(reader.Remaining(), 1u); EXPECT_EQ(val1, static_cast(0xfffffffeUL)); EXPECT_EQ(val2, static_cast(0xffffffffUL)); @@ -227,7 +229,8 @@ TEST(TestBufferReader, TestBufferReader_LittleEndianScalars) int32_t val1 = 0; int32_t val2 = 0; - EXPECT_TRUE(reader.Skip(1).ReadSigned32(&val1).ReadSigned32(&val2).IsSuccess()); + reader.Skip(1); + EXPECT_TRUE(reader.ReadSigned32(&val1).ReadSigned32(&val2).IsSuccess()); EXPECT_EQ(reader.Remaining(), 1u); EXPECT_EQ(val1, static_cast(-2L)); EXPECT_EQ(val2, static_cast(-1L)); @@ -272,3 +275,23 @@ TEST(TestBufferReader, TestBufferReader_LittleEndianScalars) EXPECT_EQ(val3, '\xff'); } } + +TEST(TestBigEndianBufferReader, GenericTests) +{ + uint8_t test_buf[] = { 0x12, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xBC, 1, 2, 3 }; + + chip::Encoding::BigEndian::Reader reader{ ByteSpan{ test_buf } }; + + uint16_t v1; + uint32_t v2; + uint8_t v3; + + EXPECT_TRUE(reader.Read16(&v1).Read32(&v2).Read8(&v3).IsSuccess()); + EXPECT_EQ(reader.Remaining(), 3u); + EXPECT_EQ(v1, 0x1223u); + EXPECT_EQ(v2, 0x456789ABu); + EXPECT_EQ(v3, 0xBCu); + + // Insufficient buffer after that + EXPECT_FALSE(reader.Read32(&v2).IsSuccess()); +} From 92fa1ad9f69eb24be8e7a82678fc57f93701ba72 Mon Sep 17 00:00:00 2001 From: Vivien Nicolas Date: Thu, 24 Oct 2024 08:17:30 +0200 Subject: [PATCH 090/149] [darwin-framework-tool] Sending a command or issuing a write using the any cluster leaks (#36215) * [darwin-framework-tool] ClusterCommandBridge.h does not release the custom argument data, making the leak detector complaining * [darwin-framework-tool] WriteAttributeCommandBridge.h does not release the custom argument data, making the leak detector complaining --- .../commands/clusters/ClusterCommandBridge.h | 47 +++++++++++------- .../clusters/WriteAttributeCommandBridge.h | 48 ++++++++++++------- 2 files changed, 62 insertions(+), 33 deletions(-) diff --git a/examples/darwin-framework-tool/commands/clusters/ClusterCommandBridge.h b/examples/darwin-framework-tool/commands/clusters/ClusterCommandBridge.h index 7bf34f11a62d94..50b9cfed5d912b 100644 --- a/examples/darwin-framework-tool/commands/clusters/ClusterCommandBridge.h +++ b/examples/darwin-framework-tool/commands/clusters/ClusterCommandBridge.h @@ -47,22 +47,8 @@ class ClusterCommand : public ModelCommand { CHIP_ERROR SendCommand(MTRBaseDevice * _Nonnull device, chip::EndpointId endpointId) override { - chip::TLV::TLVWriter writer; - chip::TLV::TLVReader reader; - - mData = static_cast(chip::Platform::MemoryCalloc(sizeof(uint8_t), mDataMaxLen)); - VerifyOrReturnError(mData != nullptr, CHIP_ERROR_NO_MEMORY); - - writer.Init(mData, mDataMaxLen); - - ReturnErrorOnFailure(mPayload.Encode(writer, chip::TLV::AnonymousTag())); - reader.Init(mData, writer.GetLengthWritten()); - ReturnErrorOnFailure(reader.Next()); - - id commandFields = NSObjectFromCHIPTLV(&reader); - if (commandFields == nil) { - return CHIP_ERROR_INTERNAL; - } + id commandFields; + ReturnErrorOnFailure(GetCommandFields(&commandFields)); return ClusterCommand::SendCommand(device, endpointId, mClusterId, mCommandId, commandFields); } @@ -136,6 +122,35 @@ class ClusterCommand : public ModelCommand { NSError * _Nullable mError = nil; private: + CHIP_ERROR GetCommandFields(id _Nonnull * _Nonnull outCommandFields) + { + CHIP_ERROR err = CHIP_NO_ERROR; + chip::TLV::TLVWriter writer; + chip::TLV::TLVReader reader; + + mData = static_cast(chip::Platform::MemoryCalloc(sizeof(uint8_t), mDataMaxLen)); + VerifyOrExit(mData != nullptr, err = CHIP_ERROR_NO_MEMORY); + + writer.Init(mData, mDataMaxLen); + + err = mPayload.Encode(writer, chip::TLV::AnonymousTag()); + SuccessOrExit(err); + + reader.Init(mData, writer.GetLengthWritten()); + err = reader.Next(); + SuccessOrExit(err); + + *outCommandFields = NSObjectFromCHIPTLV(&reader); + VerifyOrDo(nil != *outCommandFields, err = CHIP_ERROR_INTERNAL); + + exit: + if (nullptr != mData) { + chip::Platform::MemoryFree(mData); + mData = nullptr; + } + return err; + } + chip::ClusterId mClusterId; chip::CommandId mCommandId; diff --git a/examples/darwin-framework-tool/commands/clusters/WriteAttributeCommandBridge.h b/examples/darwin-framework-tool/commands/clusters/WriteAttributeCommandBridge.h index 66003042cccbe4..f274ea21aa654b 100644 --- a/examples/darwin-framework-tool/commands/clusters/WriteAttributeCommandBridge.h +++ b/examples/darwin-framework-tool/commands/clusters/WriteAttributeCommandBridge.h @@ -49,23 +49,8 @@ class WriteAttribute : public ModelCommand { CHIP_ERROR SendCommand(MTRBaseDevice * _Nonnull device, chip::EndpointId endpointId) override { - chip::TLV::TLVWriter writer; - chip::TLV::TLVReader reader; - - mData = static_cast(chip::Platform::MemoryCalloc(sizeof(uint8_t), mDataMaxLen)); - VerifyOrReturnError(mData != nullptr, CHIP_ERROR_NO_MEMORY); - - writer.Init(mData, mDataMaxLen); - - ReturnErrorOnFailure(mAttributeValue.Encode(writer, chip::TLV::AnonymousTag())); - reader.Init(mData, writer.GetLengthWritten()); - ReturnErrorOnFailure(reader.Next()); - - id value = NSObjectFromCHIPTLV(&reader); - if (value == nil) { - return CHIP_ERROR_INTERNAL; - } - + id value; + ReturnErrorOnFailure(GetValue(&value)); return WriteAttribute::SendCommand(device, endpointId, mClusterId, mAttributeId, value); } @@ -122,6 +107,35 @@ class WriteAttribute : public ModelCommand { chip::Optional mDataVersion; private: + CHIP_ERROR GetValue(id _Nonnull * _Nonnull outValue) + { + CHIP_ERROR err = CHIP_NO_ERROR; + chip::TLV::TLVWriter writer; + chip::TLV::TLVReader reader; + + mData = static_cast(chip::Platform::MemoryCalloc(sizeof(uint8_t), mDataMaxLen)); + VerifyOrExit(mData != nullptr, err = CHIP_ERROR_NO_MEMORY); + + writer.Init(mData, mDataMaxLen); + + err = mAttributeValue.Encode(writer, chip::TLV::AnonymousTag()); + SuccessOrExit(err); + + reader.Init(mData, writer.GetLengthWritten()); + err = reader.Next(); + SuccessOrExit(err); + + *outValue = NSObjectFromCHIPTLV(&reader); + VerifyOrDo(nil != *outValue, err = CHIP_ERROR_INTERNAL); + + exit: + if (nullptr != mData) { + chip::Platform::MemoryFree(mData); + mData = nullptr; + } + return err; + } + chip::ClusterId mClusterId; chip::AttributeId mAttributeId; CHIP_ERROR mError = CHIP_NO_ERROR; From ea8b849b5f64de40a449c28710eb476384fa87f5 Mon Sep 17 00:00:00 2001 From: Vivien Nicolas Date: Thu, 24 Oct 2024 08:19:38 +0200 Subject: [PATCH 091/149] [Matter.framework] Move various #define to src/platform/Darwin/CHIPPlatformConfig.h by defautl instead of relying on CHIPProjectAppConfig.h (#36178) --- config/{ios => darwin}/args.gni | 6 +-- config/ios/CHIPProjectConfig.h | 52 ------------------- config/ios/SystemProjectConfig.h | 26 ---------- examples/darwin-framework-tool/args.gni | 13 +---- .../include/CHIPProjectAppConfig.h | 31 ----------- .../project.pbxproj | 2 - examples/tv-casting-app/darwin/args.gni | 7 +-- .../include/CHIPProjectAppConfig.h | 2 + .../Matter.xcodeproj/project.pbxproj | 4 -- .../Framework/chip_xcode_build_connector.sh | 2 +- src/platform/Darwin/CHIPPlatformConfig.h | 28 ++++++++-- src/system/system.gni | 4 ++ 12 files changed, 38 insertions(+), 139 deletions(-) rename config/{ios => darwin}/args.gni (82%) delete mode 100644 config/ios/CHIPProjectConfig.h delete mode 100644 config/ios/SystemProjectConfig.h delete mode 100644 examples/darwin-framework-tool/include/CHIPProjectAppConfig.h diff --git a/config/ios/args.gni b/config/darwin/args.gni similarity index 82% rename from config/ios/args.gni rename to config/darwin/args.gni index b4426a61a43647..0e9731884040ea 100644 --- a/config/ios/args.gni +++ b/config/darwin/args.gni @@ -1,4 +1,4 @@ -# Copyright (c) 2020 Project CHIP Authors +# Copyright (c) 2024 Project CHIP Authors # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -14,9 +14,9 @@ import("//build_overrides/chip.gni") -chip_system_config_clock = "gettimeofday" chip_device_platform = "darwin" -chip_project_config_include_dirs = [ "${chip_root}/config/ios" ] +chip_project_config_include = "" +chip_system_project_config_include = "" pw_build_PIP_CONSTRAINTS = [ "${chip_root}/scripts/setup/constraints.txt" ] diff --git a/config/ios/CHIPProjectConfig.h b/config/ios/CHIPProjectConfig.h deleted file mode 100644 index dfa35f7cfd5254..00000000000000 --- a/config/ios/CHIPProjectConfig.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * - * Copyright (c) 2020-2022 Project CHIP Authors - * Copyright (c) 2016-2017 Nest Labs, Inc. - * Copyright (c) 2019-2020 Google LLC. - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @file - * Project-specific configuration file for iOS builds. - * - */ -#ifndef CHIPPROJECTCONFIG_H -#define CHIPPROJECTCONFIG_H - -// Enable UDP listening on demand in the CHIPDeviceController -#define CHIP_CONFIG_DEVICE_CONTROLLER_DEMAND_ENABLE_UDP 1 - -#define INET_CONFIG_OVERRIDE_SYSTEM_TCP_USER_TIMEOUT 0 - -// Uncomment this for a large Tunnel MTU. -//#define CHIP_CONFIG_TUNNEL_INTERFACE_MTU (9000) - -#define CHIP_SYSTEM_CONFIG_PACKETBUFFER_POOL_SIZE 0 - -#define CHIP_CONFIG_DATA_MANAGEMENT_CLIENT_EXPERIMENTAL 1 - -#define CHIP_CONFIG_MAX_SOFTWARE_VERSION_LENGTH 128 - -#ifndef CHIP_CONFIG_KVS_PATH -#define CHIP_CONFIG_KVS_PATH "chip.store" -#endif - -// The session pool size limits how many subscriptions we can have live at -// once. Home supports up to 1000 accessories, and we subscribe to all of them, -// so we need to make sure the pool is big enough for that. -#define CHIP_CONFIG_SECURE_SESSION_POOL_SIZE 1000 - -#endif /* CHIPPROJECTCONFIG_H */ diff --git a/config/ios/SystemProjectConfig.h b/config/ios/SystemProjectConfig.h deleted file mode 100644 index 06d9baaee59492..00000000000000 --- a/config/ios/SystemProjectConfig.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * - * Copyright (c) 2021 Project CHIP Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @file - * chip::System project configuration for standalone builds on iOS - * - */ -#ifndef SYSTEMPROJECTCONFIG_H -#define SYSTEMPROJECTCONFIG_H - -#endif /* SYSTEMPROJECTCONFIG_H */ diff --git a/examples/darwin-framework-tool/args.gni b/examples/darwin-framework-tool/args.gni index 6f0f1010a05f5d..4af7d4a7d19138 100644 --- a/examples/darwin-framework-tool/args.gni +++ b/examples/darwin-framework-tool/args.gni @@ -14,15 +14,4 @@ import("//build_overrides/chip.gni") -import("${chip_root}/config/standalone/args.gni") - -chip_crypto = "boringssl" - -chip_device_project_config_include = - "${chip_root}/examples/darwin-framework-tool/include/CHIPProjectAppConfig.h" -chip_project_config_include = - "${chip_root}/examples/darwin-framework-tool/include/CHIPProjectAppConfig.h" - -chip_project_config_include_dirs = - [ "${chip_root}/examples/darwin-framework-tool/include" ] -chip_project_config_include_dirs += [ "${chip_root}/config/standalone" ] +import("${chip_root}/config/darwin/args.gni") diff --git a/examples/darwin-framework-tool/include/CHIPProjectAppConfig.h b/examples/darwin-framework-tool/include/CHIPProjectAppConfig.h deleted file mode 100644 index 6f1764a52df56b..00000000000000 --- a/examples/darwin-framework-tool/include/CHIPProjectAppConfig.h +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2023 Project CHIP Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * @file - * Project configuration for Darwin Framework Tool. - * - */ -#ifndef CHIPPROJECTCONFIG_H -#define CHIPPROJECTCONFIG_H - -// Enable some test-only interaction model APIs. -#define CONFIG_BUILD_FOR_HOST_UNIT_TEST 1 - -// Allow us, for test purposes, to encode invalid enum values. -#define CHIP_CONFIG_IM_ENABLE_ENCODING_SENTINEL_ENUM_VALUES 1 - -#endif /* CHIPPROJECTCONFIG_H */ diff --git a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge.xcodeproj/project.pbxproj b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge.xcodeproj/project.pbxproj index 28793f5f60b8e7..882961ed913b3d 100644 --- a/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge.xcodeproj/project.pbxproj +++ b/examples/tv-casting-app/darwin/MatterTvCastingBridge/MatterTvCastingBridge.xcodeproj/project.pbxproj @@ -678,7 +678,6 @@ "$(CHIP_ROOT)/src/include", "$(CHIP_ROOT)/src/lib", "$(CHIP_ROOT)/src/app", - "$(CHIP_ROOT)/config/ios", "$(CHIP_ROOT)/src/app/util", "$(CHIP_ROOT)/third_party/nlassert/repo/include", "$(CHIP_ROOT)/third_party/nlio/repo/include", @@ -759,7 +758,6 @@ "$(CHIP_ROOT)/src/include", "$(CHIP_ROOT)/src/lib", "$(CHIP_ROOT)/src/app", - "$(CHIP_ROOT)/config/ios", "$(CHIP_ROOT)/src/app/util", "$(CHIP_ROOT)/third_party/nlassert/repo/include", "$(CHIP_ROOT)/third_party/nlio/repo/include", diff --git a/examples/tv-casting-app/darwin/args.gni b/examples/tv-casting-app/darwin/args.gni index 1158e98e5f2d99..10b02842ff4764 100644 --- a/examples/tv-casting-app/darwin/args.gni +++ b/examples/tv-casting-app/darwin/args.gni @@ -14,17 +14,14 @@ import("//build_overrides/chip.gni") -import("${chip_root}/config/ios/args.gni") +import("${chip_root}/config/darwin/args.gni") chip_device_project_config_include = "" -chip_project_config_include = "" -chip_system_project_config_include = "" -chip_project_config_include_dirs += [ +chip_project_config_include_dirs = [ "${chip_root}/examples/tv-casting-app/tv-casting-common/include", "${chip_root}/examples/tv-casting-app/tv-casting-common", ] -chip_project_config_include_dirs += [ "${chip_root}/config/ios" ] chip_build_libshell = true diff --git a/examples/tv-casting-app/tv-casting-common/include/CHIPProjectAppConfig.h b/examples/tv-casting-app/tv-casting-common/include/CHIPProjectAppConfig.h index f5887bc3828b08..0e9ccf7d67df19 100644 --- a/examples/tv-casting-app/tv-casting-common/include/CHIPProjectAppConfig.h +++ b/examples/tv-casting-app/tv-casting-common/include/CHIPProjectAppConfig.h @@ -92,4 +92,6 @@ // Include the CHIPProjectConfig from config/standalone // Add this at the end so that we can hit our #defines first +#ifndef CHIP_DEVICE_LAYER_TARGET_DARWIN #include +#endif // CHIP_DEVICE_LAYER_TARGET_DARWIN diff --git a/src/darwin/Framework/Matter.xcodeproj/project.pbxproj b/src/darwin/Framework/Matter.xcodeproj/project.pbxproj index bd05397c05c67e..a08a406778458e 100644 --- a/src/darwin/Framework/Matter.xcodeproj/project.pbxproj +++ b/src/darwin/Framework/Matter.xcodeproj/project.pbxproj @@ -2257,7 +2257,6 @@ "$(CHIP_ROOT)/third_party/nlio/repo/include", "$(CHIP_ROOT)/third_party/jsoncpp/repo/include", "$(CHIP_ROOT)/zzz_generated/darwin-framework-tool", - "$(CHIP_ROOT)/config/ios", "$(CHIP_ROOT)/third_party/editline/repo/include", "$(CHIP_ROOT)/src/include", "$(CONFIGURATION_TEMP_DIR)/Matter.build/out/gen/include", @@ -2334,7 +2333,6 @@ "$(CHIP_ROOT)/zzz_generated/app-common", "$(CHIP_ROOT)/third_party/nlio/repo/include", "$(CHIP_ROOT)/third_party/jsoncpp/repo/include", - "$(CHIP_ROOT)/config/ios", "$(CHIP_ROOT)/third_party/editline/repo/include", "$(CHIP_ROOT)/third_party/libwebsockets", "$(CHIP_ROOT)/third_party/libwebsockets/repo/include", @@ -2526,7 +2524,6 @@ SYSTEM_HEADER_SEARCH_PATHS = ( "$(TEMP_DIR)/out/gen/include", "$(CHIP_ROOT)/src/darwin/Framework/CHIP/", - "$(CHIP_ROOT)/config/ios", "$(CHIP_ROOT)/src", "$(CHIP_ROOT)/src/include", "$(CHIP_ROOT)/zzz_generated/", @@ -2698,7 +2695,6 @@ SYSTEM_HEADER_SEARCH_PATHS = ( "$(TEMP_DIR)/out/gen/include", "$(CHIP_ROOT)/src/darwin/Framework/CHIP/", - "$(CHIP_ROOT)/config/ios", "$(CHIP_ROOT)/src", "$(CHIP_ROOT)/src/include", "$(CHIP_ROOT)/zzz_generated/", diff --git a/src/darwin/Framework/chip_xcode_build_connector.sh b/src/darwin/Framework/chip_xcode_build_connector.sh index 5947ae7dd36490..0c08ab381b32f4 100755 --- a/src/darwin/Framework/chip_xcode_build_connector.sh +++ b/src/darwin/Framework/chip_xcode_build_connector.sh @@ -103,6 +103,7 @@ done [[ $ENABLE_BITCODE == YES ]] && target_cflags+=("-flto") declare -a args=( + 'import("//config/darwin/args.gni")' 'default_configs_cosmetic=[]' # suppress colorization 'chip_crypto="boringssl"' 'chip_build_controller_dynamic_server=false' @@ -132,7 +133,6 @@ esac [[ $PLATFORM_FAMILY_NAME != macOS ]] && { args+=( 'target_os="ios"' - 'import("//config/ios/args.gni")' ) } diff --git a/src/platform/Darwin/CHIPPlatformConfig.h b/src/platform/Darwin/CHIPPlatformConfig.h index d85194aaecb61e..72de356f2d00ee 100644 --- a/src/platform/Darwin/CHIPPlatformConfig.h +++ b/src/platform/Darwin/CHIPPlatformConfig.h @@ -23,6 +23,8 @@ #pragma once +#include + // ==================== General Platform Adaptations ==================== #define CHIP_CONFIG_ABORT() abort() @@ -53,9 +55,16 @@ extern "C" int __cxa_atexit(void (*f)(void *), void * p, void * d); #define CHIP_CONFIG_MAX_UNSOLICITED_MESSAGE_HANDLERS 8 #endif // CHIP_CONFIG_MAX_UNSOLICITED_MESSAGE_HANDLERS -#ifndef CHIP_CONFIG_MAX_EXCHANGE_CONTEXTS -#define CHIP_CONFIG_MAX_EXCHANGE_CONTEXTS 8 -#endif // CHIP_CONFIG_MAX_EXCHANGE_CONTEXTS +// +// Default of 8 ECs is not sufficient for some of the unit tests +// that try to validate multiple simultaneous interactions. +// In tests like TestReadHandler_MultipleSubscriptions, we are trying to issue as many read / subscription requests as possible in +// parallel. Since the default config says we support 16 fabrics, and we will have 4 read handlers for each fabric (3 subscriptions +// + 1 reserved for read) that is read transactions in parallel. Since the report handlers are allocated on the heap, we will issue +// 65 requests (the TestReadHandler_MultipleSubscriptions will issue CHIP_IM_MAX_NUM_READ_HANDLER + 1 subscriptions to verify heap +// allocation logic) in total and that is 130 ECs. Round this up to 150 ECs +// +#define CHIP_CONFIG_MAX_EXCHANGE_CONTEXTS 150 #ifndef CHIP_LOG_FILTERING #define CHIP_LOG_FILTERING 1 @@ -66,5 +75,18 @@ extern "C" int __cxa_atexit(void (*f)(void *), void * p, void * d); #endif // CHIP_CONFIG_BDX_MAX_NUM_TRANSFERS #ifndef CHIP_CONFIG_KVS_PATH +#if TARGET_OS_IPHONE +#define CHIP_CONFIG_KVS_PATH "chip.store" +#else #define CHIP_CONFIG_KVS_PATH "/tmp/chip_kvs" +#endif // TARGET_OS_IPHONE #endif // CHIP_CONFIG_KVS_PATH + +#define CHIP_SYSTEM_CONFIG_PACKETBUFFER_POOL_SIZE 0 + +// The session pool size limits how many subscriptions we can have live at +// once. Home supports up to 1000 accessories, and we subscribe to all of them, +// so we need to make sure the pool is big enough for that. +#define CHIP_CONFIG_SECURE_SESSION_POOL_SIZE 1000 + +#define INET_CONFIG_OVERRIDE_SYSTEM_TCP_USER_TIMEOUT 0 diff --git a/src/system/system.gni b/src/system/system.gni index 61efb846d89839..61cd52fa320245 100644 --- a/src/system/system.gni +++ b/src/system/system.gni @@ -71,6 +71,10 @@ if (chip_system_config_locking == "") { } } +if (target_os == "mac" || target_os == "ios") { + chip_system_config_clock = "gettimeofday" +} + assert( chip_system_config_locking == "posix" || chip_system_config_locking == "freertos" || From 75d7e6b04b80d83e7cedd9d3b5c1b6cabb411ef9 Mon Sep 17 00:00:00 2001 From: C Freeman Date: Thu, 24 Oct 2024 02:48:23 -0400 Subject: [PATCH 092/149] YAML linter: Add check for manual steps, remove known bad unit tests (#35493) * YAML linter: Add check for manual steps, remove known bad unit tests * test bad change * Restyled by isort * Trying again for CI - checkout had no depth * testing - I can't repro locally * ha...removed my test bad test * more testing...ci is different than local and act * debugging in ci...fun times * Restyled by whitespace * let's just run the one, ya? * Fix git on the VM * Actually error though * Revert "let's just run the one, ya?" This reverts commit e3c045dd01c65300d04d8d12cba97c4a24bcdb62. * Remove the added bad step --------- Co-authored-by: Restyled.io --- .github/workflows/cert_test_checks.yaml | 4 +++ scripts/tests/matter_yaml_linter.py | 35 +++++++++++++++++++++---- 2 files changed, 34 insertions(+), 5 deletions(-) diff --git a/.github/workflows/cert_test_checks.yaml b/.github/workflows/cert_test_checks.yaml index 44d545a6636897..3f8f54dcf2dc55 100644 --- a/.github/workflows/cert_test_checks.yaml +++ b/.github/workflows/cert_test_checks.yaml @@ -18,6 +18,8 @@ on: pull_request: paths: - "src/app/tests/suites/certification/**" +permissions: + contents: read jobs: check-certification-tests: @@ -30,6 +32,8 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 + with: + fetch-depth: 0 - name: Run checks run: | python3 scripts/tests/matter_yaml_linter.py diff --git a/scripts/tests/matter_yaml_linter.py b/scripts/tests/matter_yaml_linter.py index 4fdcb765ce6e0c..308e151824e6f8 100644 --- a/scripts/tests/matter_yaml_linter.py +++ b/scripts/tests/matter_yaml_linter.py @@ -15,6 +15,7 @@ # limitations under the License. import os import re +import subprocess import sys from pathlib import Path @@ -23,15 +24,12 @@ DEFAULT_CHIP_ROOT = os.path.abspath( os.path.join(os.path.dirname(__file__), '..', '..')) -# TODO: These tests need to be re-written. Please see https://github.com/project-chip/connectedhomeip/issues/32620 -KNOWN_BAD_UNIT_TESTING = set(('Test_TC_S_2_2.yaml', 'Test_TC_S_2_3.yaml')) - def _is_cert_test(path): return "certification" in os.path.dirname(path) -def main(): +def check_unit_testing(): bad_tests = set() for test in AllChipToolYamlTests(use_short_run_name=False): with open(test.run_name, "r") as f: @@ -47,10 +45,37 @@ def main(): print(f'\t{line+1}: {val}') bad_tests.add(Path(test.run_name).name) - if bad_tests - KNOWN_BAD_UNIT_TESTING: + if bad_tests: return 1 return 0 +def check_manual_steps(): + # Doing this on a test-by-test basis so the log message is more obvious + bad_test = False + # We are operating in a VM, and although there is a checkout, it is working in a scratch directory + # where the ownership is different than the runner. + # Adding an exception for this directory so that git can function properly. + subprocess.run("git config --global --add safe.directory '*'", shell=True) + for test in AllChipToolYamlTests(use_short_run_name=False): + + cmd = f'git diff HEAD^..HEAD --unified=0 -- {test.run_name}' + output = subprocess.check_output(cmd, shell=True).decode().splitlines() + user_prompt_added = [line for line in output if re.search(r'^\+.*UserPrompt.*', line)] + user_prompt_removed = [line for line in output if re.search(r'^\-.*UserPrompt.*', line)] + if len(user_prompt_added) > len(user_prompt_removed): + print(f'Found YAML test with additional manual steps: {test.name}') + bad_test = True + if bad_test: + return 1 + return 0 + + +def main(): + ret = check_unit_testing() + ret += check_manual_steps() + return ret + + if __name__ == '__main__': sys.exit(main()) From 736ed63b5208a1f1c02b3a78038a82060a21264f Mon Sep 17 00:00:00 2001 From: Vivien Nicolas Date: Thu, 24 Oct 2024 12:48:02 +0200 Subject: [PATCH 093/149] =?UTF-8?q?[Matter.framework]=20Enforce=20max=20re?= =?UTF-8?q?porting=20interval=20to=20kSubscriptionMax=E2=80=A6=20(#36112)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CHIP/MTRDeviceControllerFactory.mm | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/darwin/Framework/CHIP/MTRDeviceControllerFactory.mm b/src/darwin/Framework/CHIP/MTRDeviceControllerFactory.mm index 8ab6a7dc365f2a..9de51431bfe4f8 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceControllerFactory.mm +++ b/src/darwin/Framework/CHIP/MTRDeviceControllerFactory.mm @@ -78,6 +78,18 @@ @interface MTRDeviceControllerFactoryParams () @end +class MTRApplicationCallback : public app::ReadHandler::ApplicationCallback { + CHIP_ERROR OnSubscriptionRequested(app::ReadHandler & readHandler, Transport::SecureSession & secureSession) override + { + uint16_t requestedMinInterval = 0; + uint16_t requestedMaxInterval = 0; + readHandler.GetReportingIntervals(requestedMinInterval, requestedMaxInterval); + + uint16_t maximumMaxInterval = std::max(kSubscriptionMaxIntervalPublisherLimit, requestedMaxInterval); + return readHandler.SetMaxReportingInterval(maximumMaxInterval); + } +}; + MTR_DIRECT_MEMBERS @interface MTRDeviceControllerFactory () - (void)preWarmCommissioningSessionDone; @@ -90,6 +102,7 @@ @implementation MTRDeviceControllerFactory { Credentials::IgnoreCertificateValidityPeriodPolicy _certificateValidityPolicy; Crypto::RawKeySessionKeystore _sessionKeystore; + MTRApplicationCallback _applicationCallback; // We use TestPersistentStorageDelegate just to get an in-memory store to back // our group data provider impl. We initialize this store correctly on every // controller startup, so don't need to actually persist it. @@ -239,6 +252,8 @@ - (void)cleanupStartupObjects // Make sure the deinit order here is the reverse of the init order in // startControllerFactory: + app::InteractionModelEngine::GetInstance()->UnregisterReadHandlerAppCallback(); + _certificationDeclarationCertificates = nil; _productAttestationAuthorityCertificates = nil; @@ -367,6 +382,8 @@ - (BOOL)_startControllerFactory:(MTRDeviceControllerFactoryParams *)startupParam _productAttestationAuthorityCertificates = [startupParams.productAttestationAuthorityCertificates copy]; _certificationDeclarationCertificates = [startupParams.certificationDeclarationCertificates copy]; + app::InteractionModelEngine::GetInstance()->RegisterReadHandlerAppCallback(&_applicationCallback); + { chip::Controller::FactoryInitParams params; if (startupParams.port != nil) { From 70f168a4224f03996c4feeba527c3702f561b1ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mi=C5=82osz=20Tomkiel?= Date: Thu, 24 Oct 2024 13:43:01 +0200 Subject: [PATCH 094/149] [Tizen] Pass runner's path as QEMU argument (#36173) * Allow runner's path to be passed * Bump version --- integrations/docker/images/base/chip-build/version | 2 +- .../images/stage-3/chip-build-tizen-qemu/Dockerfile | 8 ++++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/integrations/docker/images/base/chip-build/version b/integrations/docker/images/base/chip-build/version index c79147db54915d..f44401475bad25 100644 --- a/integrations/docker/images/base/chip-build/version +++ b/integrations/docker/images/base/chip-build/version @@ -1 +1 @@ -85 : [Silabs] Update Silabs docker Simplicity SDK v2024.6.2 \ No newline at end of file +86 : [Tizen] Pass runner's path as QEMU argument \ No newline at end of file diff --git a/integrations/docker/images/stage-3/chip-build-tizen-qemu/Dockerfile b/integrations/docker/images/stage-3/chip-build-tizen-qemu/Dockerfile index d731ab2dc6a804..2d0bb55e3afeef 100644 --- a/integrations/docker/images/stage-3/chip-build-tizen-qemu/Dockerfile +++ b/integrations/docker/images/stage-3/chip-build-tizen-qemu/Dockerfile @@ -182,9 +182,13 @@ RUN set -x \ && echo -n \ "#!/bin/bash\n" \ "grep -q 'rootshell' /proc/cmdline && exit\n" \ - "if [[ -x /mnt/chip/runner.sh ]]; then\n" \ + "runner=\$(grep -o 'runner=[^ ]*' /proc/cmdline | sed 's/runner=//')\n" \ + "if [[ -z \"\$runner\" ]]; then\n" \ + " runner='/mnt/chip/runner.sh' \n" \ + "fi\n" \ + "if [[ -x \"\$runner\" ]]; then\n" \ " echo '### RUNNER START ###'\n" \ - " /mnt/chip/runner.sh\n" \ + " \"\$runner\"\n" \ " echo '### RUNNER STOP:' \$?\n" \ "else\n" \ " read -r -t 5 -p 'Press ENTER to access root shell...' && exit || echo ' timeout.'\n" \ From 037bc4cb669997cc2d55bd4b949c0ac24dc4acbf Mon Sep 17 00:00:00 2001 From: Arkadiusz Bokowy Date: Thu, 24 Oct 2024 14:03:19 +0200 Subject: [PATCH 095/149] Use GoogleTest back-end for unit tests running on host (#36137) * Use GoogleTest back-end for unit tests running on host * Setup googletest repo for Android and Tizen builds * Add missing override --- .gitmodules | 2 +- .gn | 6 ++++++ build/toolchain/pw_fuzzer/BUILD.gn | 3 ++- build_overrides/googletest.gni | 18 ++++++++++++++++++ examples/build_overrides/googletest.gni | 18 ++++++++++++++++++ src/test_driver/tizen/.gn | 5 ++++- 6 files changed, 49 insertions(+), 3 deletions(-) create mode 100644 build_overrides/googletest.gni create mode 100644 examples/build_overrides/googletest.gni diff --git a/.gitmodules b/.gitmodules index c2b9a95a5e0345..592c49a2a7085f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -340,7 +340,7 @@ [submodule "third_party/googletest"] path = third_party/googletest url = https://github.com/google/googletest - platforms = linux,darwin + platforms = linux,android,darwin,tizen [submodule "third_party/re2/src"] path = third_party/re2/src url = https://github.com/google/re2.git diff --git a/.gn b/.gn index f844fd20e9b87d..07b5accb51456c 100644 --- a/.gn +++ b/.gn @@ -13,6 +13,7 @@ # limitations under the License. import("//build_overrides/build.gni") +import("//build_overrides/googletest.gni") import("//build_overrides/pigweed.gni") # The location of the build configuration file. @@ -33,6 +34,11 @@ default_args = { # GN target to use for the default Python build venv. pw_build_PYTHON_BUILD_VENV = "//:matter_build_venv" + # Use the GoogleTest backend for unit tests running on host. + pw_unit_test_BACKEND = "$dir_pw_unit_test:googletest" + pw_unit_test_MAIN = "$dir_pigweed/third_party/googletest:gmock_main" + dir_pw_third_party_googletest = "$dir_googletest" + # Required for pw_unit_test pw_sys_io_BACKEND = "$dir_pw_sys_io_stdio" pw_assert_BACKEND = "$dir_pw_assert_log" diff --git a/build/toolchain/pw_fuzzer/BUILD.gn b/build/toolchain/pw_fuzzer/BUILD.gn index 385e57cc81be39..468a615448312a 100644 --- a/build/toolchain/pw_fuzzer/BUILD.gn +++ b/build/toolchain/pw_fuzzer/BUILD.gn @@ -13,6 +13,7 @@ # limitations under the License. import("//build_overrides/build.gni") +import("//build_overrides/googletest.gni") import("//build_overrides/pigweed.gni") import("$dir_pigweed/targets/host/target_toolchains.gni") @@ -61,7 +62,7 @@ gcc_toolchain("chip_pw_fuzztest") { dir_pw_third_party_abseil_cpp = "//third_party/abseil-cpp/src" dir_pw_third_party_fuzztest = "//third_party/fuzztest" - dir_pw_third_party_googletest = "//third_party/googletest" + dir_pw_third_party_googletest = "$dir_googletest" # TODO: Seems that re2 support within FuzzTest was deprecated, keeping it defined is triggering warning # Remove if re2 is indeed not needed diff --git a/build_overrides/googletest.gni b/build_overrides/googletest.gni new file mode 100644 index 00000000000000..c06354b399c70c --- /dev/null +++ b/build_overrides/googletest.gni @@ -0,0 +1,18 @@ +# Copyright (c) 2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +declare_args() { + # Location of the GoogleTest repository. + dir_googletest = "//third_party/googletest" +} diff --git a/examples/build_overrides/googletest.gni b/examples/build_overrides/googletest.gni new file mode 100644 index 00000000000000..71ce4642720312 --- /dev/null +++ b/examples/build_overrides/googletest.gni @@ -0,0 +1,18 @@ +# Copyright (c) 2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +declare_args() { + # Location of the GoogleTest repository. + dir_googletest = "//third_party/connectedhomeip/third_party/googletest" +} diff --git a/src/test_driver/tizen/.gn b/src/test_driver/tizen/.gn index 65992f8720b0c5..26cd7015b64f76 100644 --- a/src/test_driver/tizen/.gn +++ b/src/test_driver/tizen/.gn @@ -14,6 +14,7 @@ import("//build_overrides/build.gni") import("//build_overrides/chip.gni") +import("//build_overrides/googletest.gni") import("//build_overrides/pigweed.gni") # The location of the build configuration file. @@ -29,7 +30,9 @@ default_args = { pw_assert_BACKEND = "$dir_pw_assert_log" pw_log_BACKEND = "$dir_pw_log_basic" - pw_unit_test_BACKEND = "$dir_pw_unit_test:light" + pw_unit_test_BACKEND = "$dir_pw_unit_test:googletest" + pw_unit_test_MAIN = "$dir_pigweed/third_party/googletest:gmock_main" + dir_pw_third_party_googletest = "$dir_googletest" # TODO: Make sure only unit tests link against this pw_build_LINK_DEPS = [ From de6dd8fd5d73b2d5b04cd6eeca4fd05339d21694 Mon Sep 17 00:00:00 2001 From: arun-silabs <141724790+arun-silabs@users.noreply.github.com> Date: Thu, 24 Oct 2024 18:01:38 +0530 Subject: [PATCH 096/149] [Silabs] Add BRD4343a support (#36111) * Added required changes for enabling brd4343a * Reverted matter_support submodule pointer * Modified as per review comments --- examples/platform/silabs/SiWx917/SiWx917/sl_wlan_config.h | 2 +- scripts/build/build/targets.py | 1 + scripts/build/builders/efr32.py | 3 +++ scripts/build/testdata/all_targets_linux_x64.txt | 2 +- scripts/examples/gn_silabs_example.sh | 2 +- third_party/silabs/silabs_board.gni | 3 ++- 6 files changed, 9 insertions(+), 4 deletions(-) diff --git a/examples/platform/silabs/SiWx917/SiWx917/sl_wlan_config.h b/examples/platform/silabs/SiWx917/SiWx917/sl_wlan_config.h index 57622a61ff65f4..21ee4a5555f514 100644 --- a/examples/platform/silabs/SiWx917/SiWx917/sl_wlan_config.h +++ b/examples/platform/silabs/SiWx917/SiWx917/sl_wlan_config.h @@ -41,7 +41,7 @@ static const sl_wifi_device_configuration_t config = { .boot_option = LOAD_NWP_FW, .mac_address = NULL, .band = SL_SI91X_WIFI_BAND_2_4GHZ, - .region_code = US, + .region_code = REGION_CODE, .boot_config = { .oper_mode = SL_SI91X_CLIENT_MODE, .coex_mode = SL_SI91X_WLAN_BLE_MODE, .feature_bit_map = diff --git a/scripts/build/build/targets.py b/scripts/build/build/targets.py index 9ddb7801530ae1..779855f4ed2633 100755 --- a/scripts/build/build/targets.py +++ b/scripts/build/build/targets.py @@ -259,6 +259,7 @@ def BuildEfr32Target(): TargetPart('brd2703a', board=Efr32Board.BRD2703A), TargetPart('brd4338a', board=Efr32Board.BRD4338A, enable_wifi=True, enable_917_soc=True), TargetPart('brd2605a', board=Efr32Board.BRD2605A, enable_wifi=True, enable_917_soc=True), + TargetPart('brd4343a', board=Efr32Board.BRD4343A, enable_wifi=True, enable_917_soc=True), ]) # apps diff --git a/scripts/build/builders/efr32.py b/scripts/build/builders/efr32.py index 0ca8649b1a3728..cb80eab890495d 100644 --- a/scripts/build/builders/efr32.py +++ b/scripts/build/builders/efr32.py @@ -112,6 +112,7 @@ class Efr32Board(Enum): BRD4338A = 11 BRD2703A = 12 BRD2605A = 13 + BRD4343A = 14 def GnArgName(self): if self == Efr32Board.BRD2704B: @@ -140,6 +141,8 @@ def GnArgName(self): return 'BRD2703A' elif self == Efr32Board.BRD2605A: return 'BRD2605A' + elif self == Efr32Board.BRD4343A: + return 'BRD4343A' else: raise Exception('Unknown board #: %r' % self) diff --git a/scripts/build/testdata/all_targets_linux_x64.txt b/scripts/build/testdata/all_targets_linux_x64.txt index 59466f91e6ec42..084b80bea3ab17 100644 --- a/scripts/build/testdata/all_targets_linux_x64.txt +++ b/scripts/build/testdata/all_targets_linux_x64.txt @@ -5,7 +5,7 @@ bouffalolab-{bl602dk,bl704ldk,bl706dk,bl602-night-light,bl706-night-light,bl602- cc32xx-{lock,air-purifier} ti-cc13x4_26x4-{lighting,lock,pump,pump-controller}[-mtd][-ftd] cyw30739-{cyw30739b2_p5_evk_01,cyw30739b2_p5_evk_02,cyw30739b2_p5_evk_03,cyw930739m2evb_01,cyw930739m2evb_02}-{light,light-switch,lock,thermostat} -efr32-{brd2704b,brd4316a,brd4317a,brd4318a,brd4319a,brd4186a,brd4187a,brd2601b,brd4187c,brd4186c,brd2703a,brd4338a,brd2605a}-{window-covering,switch,unit-test,light,lock,thermostat,pump,air-quality-sensor-app}[-rpc][-with-ota-requestor][-icd][-low-power][-shell][-no-logging][-openthread-mtd][-heap-monitoring][-no-openthread-cli][-show-qr-code][-wifi][-rs9116][-wf200][-siwx917][-ipv4][-additional-data-advertising][-use-ot-lib][-use-ot-coap-lib][-no-version][-skip-rps-generation] +efr32-{brd2704b,brd4316a,brd4317a,brd4318a,brd4319a,brd4186a,brd4187a,brd2601b,brd4187c,brd4186c,brd2703a,brd4338a,brd2605a,brd4343a}-{window-covering,switch,unit-test,light,lock,thermostat,pump,air-quality-sensor-app}[-rpc][-with-ota-requestor][-icd][-low-power][-shell][-no-logging][-openthread-mtd][-heap-monitoring][-no-openthread-cli][-show-qr-code][-wifi][-rs9116][-wf200][-siwx917][-ipv4][-additional-data-advertising][-use-ot-lib][-use-ot-coap-lib][-no-version][-skip-rps-generation] esp32-{m5stack,c3devkit,devkitc,qemu}-{all-clusters,all-clusters-minimal,energy-management,ota-provider,ota-requestor,shell,light,lock,bridge,temperature-measurement,ota-requestor,tests}[-rpc][-ipv6only][-tracing][-data-model-disabled][-data-model-enabled] genio-lighting-app linux-fake-tests[-mbedtls][-boringssl][-asan][-tsan][-ubsan][-libfuzzer][-ossfuzz][-pw-fuzztest][-coverage][-dmalloc][-clang] diff --git a/scripts/examples/gn_silabs_example.sh b/scripts/examples/gn_silabs_example.sh index a72e4e1a904e55..bc06f8b2d28b0c 100755 --- a/scripts/examples/gn_silabs_example.sh +++ b/scripts/examples/gn_silabs_example.sh @@ -302,7 +302,7 @@ else fi # 917 exception. TODO find a more generic way - if [ "$SILABS_BOARD" == "BRD4338A" ] || [ "$SILABS_BOARD" == "BRD2605A" ]; then + if [ "$SILABS_BOARD" == "BRD4338A" ] || [ "$SILABS_BOARD" == "BRD2605A" ] || [ "$SILABS_BOARD" == "BRD4343A" ]; then echo "Compiling for 917 WiFi SOC" USE_WIFI=true fi diff --git a/third_party/silabs/silabs_board.gni b/third_party/silabs/silabs_board.gni index aa51817fffdae7..c240405df80163 100644 --- a/third_party/silabs/silabs_board.gni +++ b/third_party/silabs/silabs_board.gni @@ -76,7 +76,8 @@ if (silabs_board == "") { assert(silabs_board != "", "silabs_board must be specified") # Si917 WIFI board ---------- -if (silabs_board == "BRD4338A" || silabs_board == "BRD2605A") { +if (silabs_board == "BRD4338A" || silabs_board == "BRD2605A" || + silabs_board == "BRD4343A") { if (silabs_board == "BRD2605A") { sl_enable_rgb_led = true } From 1de2c6fa47023fa8f312bacfac0d5d6083511f0d Mon Sep 17 00:00:00 2001 From: Shubham Patil Date: Thu, 24 Oct 2024 18:32:05 +0530 Subject: [PATCH 097/149] [ESP32] Implement providers which reads unique data from the secure cert partition (#35821) * [ESP32] Implement providers which reads unique data from the secure cert partition Right now secure cert partition stores only device attestation data i.e. DAC and PAI. This can be extended to store the sort of unique data that is discriminator, verifier/salt/iteration-count for passcode, and unique-id for generating rotating id. - Update the esp_secure_cert_mgr version to 2.5.0 * address review comments --- .../esp32/components/chip/idf_component.yml | 2 +- src/platform/ESP32/BUILD.gn | 8 + .../ESP32/ESP32SecureCertDataProvider.cpp | 145 ++++++++++++++++++ .../ESP32/ESP32SecureCertDataProvider.h | 51 ++++++ 4 files changed, 205 insertions(+), 1 deletion(-) create mode 100644 src/platform/ESP32/ESP32SecureCertDataProvider.cpp create mode 100644 src/platform/ESP32/ESP32SecureCertDataProvider.h diff --git a/config/esp32/components/chip/idf_component.yml b/config/esp32/components/chip/idf_component.yml index 1917fcf4de18f5..2e7415827ff264 100644 --- a/config/esp32/components/chip/idf_component.yml +++ b/config/esp32/components/chip/idf_component.yml @@ -7,7 +7,7 @@ dependencies: - if: "target != esp32h2" espressif/esp_secure_cert_mgr: - version: "^2.3.0" + version: "^2.5.0" rules: - if: "idf_version >=4.3" diff --git a/src/platform/ESP32/BUILD.gn b/src/platform/ESP32/BUILD.gn index 91922dcebb9fc5..1ffae2593e8b9d 100644 --- a/src/platform/ESP32/BUILD.gn +++ b/src/platform/ESP32/BUILD.gn @@ -205,6 +205,14 @@ static_library("ESP32") { ] } + if (chip_use_factory_data_provider && chip_use_secure_cert_dac_provider) { + # These files have no dependency on chip_use_secure_cert_dac_provider, but if we are reading the commissionable data from the secure cert, we should expect the attestation data to be present there as well. + sources += [ + "ESP32SecureCertDataProvider.cpp", + "ESP32SecureCertDataProvider.h", + ] + } + if (chip_use_esp32_ecdsa_peripheral) { sources += [ "ESP32CHIPCryptoPAL.cpp", diff --git a/src/platform/ESP32/ESP32SecureCertDataProvider.cpp b/src/platform/ESP32/ESP32SecureCertDataProvider.cpp new file mode 100644 index 00000000000000..e3bb02155bfc9b --- /dev/null +++ b/src/platform/ESP32/ESP32SecureCertDataProvider.cpp @@ -0,0 +1,145 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#include +#include +#include +#include +#include + +namespace chip { +namespace DeviceLayer { + +namespace { +// Define Matter-specific TLV subtypes for fields in the secure cert partition +enum class MatterTLVSubType : uint8_t +{ + kSetupDiscriminator = 0, + kSpake2pVerifier = 1, + kSpake2pSalt = 2, + kSpake2pIterationCount = 3, + kRotatingDeviceIdUniqueId = 4, +}; + +// Scoped wrapper class for handling TLV data retrieval from secure cert partition +class ScopedTLVInfo +{ +public: + ScopedTLVInfo(MatterTLVSubType subType) : mTLVConfig(GetMatterTLVConfig(subType)) {} + + ~ScopedTLVInfo() { esp_secure_cert_free_tlv_info(&mTLVInfo); } + + CHIP_ERROR GetValue(MutableByteSpan & span) + { + ReturnErrorOnFailure(PopulateTLVInfo()); + VerifyOrReturnError(mTLVInfo.length <= span.size(), CHIP_ERROR_BUFFER_TOO_SMALL); + + memcpy(span.data(), mTLVInfo.data, mTLVInfo.length); + span.reduce_size(mTLVInfo.length); + + return CHIP_NO_ERROR; + } + + CHIP_ERROR GetValue(uint16_t & value) + { + ReturnErrorOnFailure(PopulateTLVInfo()); + VerifyOrReturnError(mTLVInfo.length == sizeof(uint16_t), CHIP_ERROR_INTERNAL, + ChipLogError(DeviceLayer, "secure cert tlv size mismatch")); + + value = Encoding::LittleEndian::Get16(reinterpret_cast(mTLVInfo.data)); + ChipLogDetail(DeviceLayer, "secure cert tlv value:%u", value); + return CHIP_NO_ERROR; + } + + CHIP_ERROR GetValue(uint32_t & value) + { + ReturnErrorOnFailure(PopulateTLVInfo()); + VerifyOrReturnError(mTLVInfo.length == sizeof(uint32_t), CHIP_ERROR_INTERNAL, + ChipLogError(DeviceLayer, "secure cert tlv size mismatch")); + + value = Encoding::LittleEndian::Get32(reinterpret_cast(mTLVInfo.data)); + ChipLogDetail(DeviceLayer, "secure cert tlv value:%" PRIu32, value); + return CHIP_NO_ERROR; + } + +private: + esp_secure_cert_tlv_info_t mTLVInfo; + esp_secure_cert_tlv_config_t mTLVConfig; + + esp_secure_cert_tlv_config_t GetMatterTLVConfig(MatterTLVSubType subType) + { + return { .type = ESP_SECURE_CERT_MATTER_TLV_1, .subtype = static_cast(subType) }; + } + + CHIP_ERROR PopulateTLVInfo() + { + esp_err_t err = esp_secure_cert_get_tlv_info(&mTLVConfig, &mTLVInfo); + VerifyOrReturnError(err == ESP_OK, CHIP_ERROR_INTERNAL, + ChipLogError(DeviceLayer, "esp_secure_cert_get_tlv_info failed: type:%u, subtype:%u, err:%d", + mTLVConfig.type, mTLVConfig.subtype, err)); + + ChipLogDetail(DeviceLayer, "secure cert tlv info type:%u subtype:%u length:%" PRIu32 " flags:%u", mTLVInfo.type, + mTLVInfo.subtype, mTLVInfo.length, mTLVInfo.flags); + + return CHIP_NO_ERROR; + } +}; + +} // anonymous namespace + +CHIP_ERROR ESP32SecureCertDataProvider::GetSetupDiscriminator(uint16_t & setupDiscriminator) +{ + ScopedTLVInfo tlvInfo(MatterTLVSubType::kSetupDiscriminator); + return tlvInfo.GetValue(setupDiscriminator); +} + +CHIP_ERROR ESP32SecureCertDataProvider::GetSpake2pIterationCount(uint32_t & iterationCount) +{ + ScopedTLVInfo tlvInfo(MatterTLVSubType::kSpake2pIterationCount); + return tlvInfo.GetValue(iterationCount); +} + +CHIP_ERROR ESP32SecureCertDataProvider::GetSpake2pSalt(MutableByteSpan & saltBuf) +{ + ScopedTLVInfo tlvInfo(MatterTLVSubType::kSpake2pSalt); + return tlvInfo.GetValue(saltBuf); +} + +CHIP_ERROR ESP32SecureCertDataProvider::GetSpake2pVerifier(MutableByteSpan & verifierBuf, size_t & verifierLen) +{ + ScopedTLVInfo tlvInfo(MatterTLVSubType::kSpake2pVerifier); + ReturnErrorOnFailure(tlvInfo.GetValue(verifierBuf)); + verifierLen = verifierBuf.size(); + return CHIP_NO_ERROR; +} + +CHIP_ERROR ESP32SecureCertDataProvider::GetRotatingDeviceIdUniqueId(MutableByteSpan & uniqueIdSpan) +{ +#if CHIP_ENABLE_ROTATING_DEVICE_ID + ScopedTLVInfo tlvInfo(MatterTLVSubType::kRotatingDeviceIdUniqueId); + return tlvInfo.GetValue(uniqueIdSpan); +#else + return CHIP_ERROR_NOT_IMPLEMENTED; +#endif // CHIP_ENABLE_ROTATING_DEVICE_ID +} + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/ESP32/ESP32SecureCertDataProvider.h b/src/platform/ESP32/ESP32SecureCertDataProvider.h new file mode 100644 index 00000000000000..ba17fc15b9136a --- /dev/null +++ b/src/platform/ESP32/ESP32SecureCertDataProvider.h @@ -0,0 +1,51 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * ESP32FactoryDataProvider reads the commissionable data and device instance information from the factory partition. + * This implementation extends that behaviour to read the commissionable data from secure cert partition. + * It also extends the behaviour to read the unique id for generating rotating device identifier from the secure cert + * partition. + * + */ + +#pragma once + +#include +#include +#include + +#include + +namespace chip { +namespace DeviceLayer { + +class ESP32SecureCertDataProvider : public ESP32FactoryDataProvider +{ +public: + // CommissionableDataProvider implementation + CHIP_ERROR GetSetupDiscriminator(uint16_t & setupDiscriminator) override; + CHIP_ERROR GetSpake2pIterationCount(uint32_t & iterationCount) override; + CHIP_ERROR GetSpake2pSalt(MutableByteSpan & saltBuf) override; + CHIP_ERROR GetSpake2pVerifier(MutableByteSpan & verifierBuf, size_t & verifierLen) override; + + // GetRotatingDeviceIdUniqueId from GenericDeviceInstanceInfoProvider + CHIP_ERROR GetRotatingDeviceIdUniqueId(MutableByteSpan & uniqueIdSpan) override; +}; + +} // namespace DeviceLayer +} // namespace chip From ab04f038b682e96f8096ae283b12d105ca6f96bf Mon Sep 17 00:00:00 2001 From: Alexander Mazuruk Date: Thu, 24 Oct 2024 15:16:26 +0200 Subject: [PATCH 098/149] Switch lwIP to git submodule, update it. (#29056) * Remove lwip commited directly to repository Signed-off-by: Alexander Mazuruk * Re-add lwip as git submodule Checked out to lastest release as it includes fix applied in Matter repository as well as some stuff referred to in repository issues. PBUF_POOL_BUFSIZE does not use sizeof anymore (it is used in one if in the lwip upstream code). Additionally removed turning off sanity checks that were necessary due to aforementioned sizeof usage. Added LwIPLog to Bouffalolab Logging as I couldnt find it defined anywhere for this platform. Signed-off-by: Alexander Mazuruk * Remove lwip's mdns from cc32xx Signed-off-by: Alexander Mazuruk * Adjust lwipopt Signed-off-by: Alexander Mazuruk --------- Signed-off-by: Alexander Mazuruk Co-authored-by: Arkadiusz Bokowy Co-authored-by: Andrei Litvin --- .gitmodules | 3 + src/lwip/BUILD.gn | 3 +- src/lwip/cc13xx_26xx/lwipopts.h | 2 + src/lwip/cc32xx/lwipopts.h | 2 + src/lwip/standalone/arch/cc.h | 4 + src/lwip/standalone/lwipopts.h | 17 +- src/lwip/standalone/pbuf_pool_assert.c | 27 + third_party/lwip/lwip.gni | 95 +- third_party/lwip/repo | 1 + third_party/lwip/repo/lwip.url | 1 - third_party/lwip/repo/lwip.version | 1 - third_party/lwip/repo/lwip/.gitattributes | 4 - third_party/lwip/repo/lwip/.gitignore | 18 - third_party/lwip/repo/lwip/CHANGELOG | 4295 ----------------- third_party/lwip/repo/lwip/COPYING | 33 - third_party/lwip/repo/lwip/FILES | 5 - third_party/lwip/repo/lwip/README | 100 - third_party/lwip/repo/lwip/UPGRADING | 243 - third_party/lwip/repo/lwip/doc/FILES | 9 - .../lwip/repo/lwip/doc/NO_SYS_SampleCode.c | 122 - third_party/lwip/repo/lwip/doc/contrib.txt | 58 - .../lwip/repo/lwip/doc/doxygen/generate.bat | 1 - .../lwip/repo/lwip/doc/doxygen/generate.sh | 3 - .../lwip/repo/lwip/doc/doxygen/lwip.Doxyfile | 2505 ---------- .../lwip/repo/lwip/doc/doxygen/main_page.h | 132 - .../repo/lwip/doc/doxygen/output/index.html | 10 - third_party/lwip/repo/lwip/doc/mdns.txt | 113 - .../lwip/repo/lwip/doc/mqtt_client.txt | 162 - third_party/lwip/repo/lwip/doc/ppp.txt | 529 -- third_party/lwip/repo/lwip/doc/rawapi.txt | 499 -- third_party/lwip/repo/lwip/doc/savannah.txt | 120 - third_party/lwip/repo/lwip/doc/sys_arch.txt | 308 -- third_party/lwip/repo/lwip/src/FILES | 15 - third_party/lwip/repo/lwip/src/Filelists.mk | 181 - third_party/lwip/repo/lwip/src/api/api_lib.c | 1010 ---- third_party/lwip/repo/lwip/src/api/api_msg.c | 1953 -------- third_party/lwip/repo/lwip/src/api/err.c | 115 - third_party/lwip/repo/lwip/src/api/if.c | 77 - third_party/lwip/repo/lwip/src/api/netbuf.c | 246 - third_party/lwip/repo/lwip/src/api/netdb.c | 413 -- third_party/lwip/repo/lwip/src/api/netifapi.c | 316 -- third_party/lwip/repo/lwip/src/api/sockets.c | 2827 ----------- third_party/lwip/repo/lwip/src/api/tcpip.c | 565 --- .../lwip/repo/lwip/src/apps/httpd/fs.c | 179 - .../lwip/repo/lwip/src/apps/httpd/fs/404.html | 21 - .../repo/lwip/src/apps/httpd/fs/img/sics.gif | Bin 724 -> 0 bytes .../repo/lwip/src/apps/httpd/fs/index.html | 47 - .../lwip/repo/lwip/src/apps/httpd/fsdata.c | 298 -- .../lwip/repo/lwip/src/apps/httpd/fsdata.h | 50 - .../lwip/repo/lwip/src/apps/httpd/httpd.c | 2629 ---------- .../repo/lwip/src/apps/httpd/httpd_structs.h | 114 - .../lwip/src/apps/httpd/makefsdata/makefsdata | 97 - .../src/apps/httpd/makefsdata/makefsdata.c | 1033 ---- .../lwip/src/apps/httpd/makefsdata/readme.txt | 13 - .../lwip/repo/lwip/src/apps/lwiperf/lwiperf.c | 661 --- .../lwip/repo/lwip/src/apps/mdns/mdns.c | 2028 -------- .../lwip/repo/lwip/src/apps/mqtt/mqtt.c | 1342 ----- .../repo/lwip/src/apps/netbiosns/netbiosns.c | 367 -- .../lwip/repo/lwip/src/apps/snmp/snmp_asn1.c | 749 --- .../lwip/repo/lwip/src/apps/snmp/snmp_asn1.h | 108 - .../lwip/repo/lwip/src/apps/snmp/snmp_core.c | 1349 ------ .../repo/lwip/src/apps/snmp/snmp_core_priv.h | 76 - .../lwip/repo/lwip/src/apps/snmp/snmp_mib2.c | 116 - .../repo/lwip/src/apps/snmp/snmp_mib2_icmp.c | 182 - .../lwip/src/apps/snmp/snmp_mib2_interfaces.c | 375 -- .../repo/lwip/src/apps/snmp/snmp_mib2_ip.c | 743 --- .../repo/lwip/src/apps/snmp/snmp_mib2_snmp.c | 227 - .../lwip/src/apps/snmp/snmp_mib2_system.c | 377 -- .../repo/lwip/src/apps/snmp/snmp_mib2_tcp.c | 594 --- .../repo/lwip/src/apps/snmp/snmp_mib2_udp.c | 357 -- .../lwip/repo/lwip/src/apps/snmp/snmp_msg.c | 1668 ------- .../lwip/repo/lwip/src/apps/snmp/snmp_msg.h | 194 - .../repo/lwip/src/apps/snmp/snmp_netconn.c | 121 - .../lwip/src/apps/snmp/snmp_pbuf_stream.c | 156 - .../lwip/src/apps/snmp/snmp_pbuf_stream.h | 73 - .../lwip/repo/lwip/src/apps/snmp/snmp_raw.c | 100 - .../repo/lwip/src/apps/snmp/snmp_scalar.c | 220 - .../lwip/repo/lwip/src/apps/snmp/snmp_table.c | 343 -- .../repo/lwip/src/apps/snmp/snmp_threadsync.c | 219 - .../lwip/repo/lwip/src/apps/snmp/snmp_traps.c | 445 -- .../lwip/repo/lwip/src/apps/snmp/snmpv3.c | 136 - .../repo/lwip/src/apps/snmp/snmpv3_dummy.c | 145 - .../repo/lwip/src/apps/snmp/snmpv3_mbedtls.c | 331 -- .../repo/lwip/src/apps/snmp/snmpv3_priv.h | 66 - .../lwip/repo/lwip/src/apps/sntp/sntp.c | 727 --- .../repo/lwip/src/apps/tftp/tftp_server.c | 417 -- third_party/lwip/repo/lwip/src/core/def.c | 222 - third_party/lwip/repo/lwip/src/core/dns.c | 1921 -------- .../lwip/repo/lwip/src/core/inet_chksum.c | 609 --- third_party/lwip/repo/lwip/src/core/init.c | 384 -- third_party/lwip/repo/lwip/src/core/ip.c | 185 - .../lwip/repo/lwip/src/core/ipv4/autoip.c | 530 -- .../lwip/repo/lwip/src/core/ipv4/dhcp.c | 1961 -------- .../lwip/repo/lwip/src/core/ipv4/etharp.c | 1206 ----- .../lwip/repo/lwip/src/core/ipv4/icmp.c | 397 -- .../lwip/repo/lwip/src/core/ipv4/igmp.c | 800 --- .../lwip/repo/lwip/src/core/ipv4/ip4.c | 1111 ----- .../lwip/repo/lwip/src/core/ipv4/ip4_addr.c | 331 -- .../lwip/repo/lwip/src/core/ipv4/ip4_frag.c | 864 ---- .../lwip/repo/lwip/src/core/ipv6/dhcp6.c | 50 - .../lwip/repo/lwip/src/core/ipv6/ethip6.c | 137 - .../lwip/repo/lwip/src/core/ipv6/icmp6.c | 352 -- .../lwip/repo/lwip/src/core/ipv6/inet6.c | 53 - .../lwip/repo/lwip/src/core/ipv6/ip6.c | 1201 ----- .../lwip/repo/lwip/src/core/ipv6/ip6_addr.c | 292 -- .../lwip/repo/lwip/src/core/ipv6/ip6_frag.c | 805 --- .../repo/lwip/src/core/ipv6/ip6_route_table.c | 252 - .../lwip/repo/lwip/src/core/ipv6/mld6.c | 623 --- .../lwip/repo/lwip/src/core/ipv6/nd6.c | 2341 --------- third_party/lwip/repo/lwip/src/core/mem.c | 778 --- third_party/lwip/repo/lwip/src/core/memp.c | 636 --- third_party/lwip/repo/lwip/src/core/netif.c | 1517 ------ third_party/lwip/repo/lwip/src/core/pbuf.c | 1599 ------ third_party/lwip/repo/lwip/src/core/raw.c | 645 --- third_party/lwip/repo/lwip/src/core/stats.c | 169 - third_party/lwip/repo/lwip/src/core/sys.c | 106 - third_party/lwip/repo/lwip/src/core/tcp.c | 2214 --------- third_party/lwip/repo/lwip/src/core/tcp_in.c | 1859 ------- third_party/lwip/repo/lwip/src/core/tcp_out.c | 1685 ------- .../lwip/repo/lwip/src/core/timeouts.c | 451 -- third_party/lwip/repo/lwip/src/core/udp.c | 1257 ----- .../lwip/repo/lwip/src/include/lwip/api.h | 400 -- .../repo/lwip/src/include/lwip/apps/FILES | 2 - .../lwip/repo/lwip/src/include/lwip/apps/fs.h | 103 - .../repo/lwip/src/include/lwip/apps/httpd.h | 236 - .../lwip/src/include/lwip/apps/httpd_opts.h | 323 -- .../repo/lwip/src/include/lwip/apps/lwiperf.h | 84 - .../repo/lwip/src/include/lwip/apps/mdns.h | 69 - .../lwip/src/include/lwip/apps/mdns_opts.h | 74 - .../lwip/src/include/lwip/apps/mdns_priv.h | 66 - .../repo/lwip/src/include/lwip/apps/mqtt.h | 244 - .../lwip/src/include/lwip/apps/mqtt_opts.h | 103 - .../lwip/src/include/lwip/apps/netbiosns.h | 43 - .../src/include/lwip/apps/netbiosns_opts.h | 59 - .../repo/lwip/src/include/lwip/apps/snmp.h | 128 - .../lwip/src/include/lwip/apps/snmp_core.h | 364 -- .../lwip/src/include/lwip/apps/snmp_mib2.h | 78 - .../lwip/src/include/lwip/apps/snmp_opts.h | 293 -- .../lwip/src/include/lwip/apps/snmp_scalar.h | 113 - .../lwip/src/include/lwip/apps/snmp_table.h | 134 - .../src/include/lwip/apps/snmp_threadsync.h | 114 - .../repo/lwip/src/include/lwip/apps/snmpv3.h | 90 - .../repo/lwip/src/include/lwip/apps/sntp.h | 76 - .../lwip/src/include/lwip/apps/sntp_opts.h | 173 - .../lwip/src/include/lwip/apps/tftp_opts.h | 105 - .../lwip/src/include/lwip/apps/tftp_server.h | 94 - .../lwip/repo/lwip/src/include/lwip/arch.h | 323 -- .../lwip/repo/lwip/src/include/lwip/autoip.h | 99 - .../lwip/repo/lwip/src/include/lwip/debug.h | 167 - .../lwip/repo/lwip/src/include/lwip/def.h | 141 - .../lwip/repo/lwip/src/include/lwip/dhcp.h | 143 - .../lwip/repo/lwip/src/include/lwip/dhcp6.h | 58 - .../lwip/repo/lwip/src/include/lwip/dns.h | 169 - .../lwip/repo/lwip/src/include/lwip/err.h | 119 - .../lwip/repo/lwip/src/include/lwip/errno.h | 193 - .../lwip/repo/lwip/src/include/lwip/etharp.h | 106 - .../lwip/repo/lwip/src/include/lwip/ethip6.h | 68 - .../lwip/repo/lwip/src/include/lwip/icmp.h | 110 - .../lwip/repo/lwip/src/include/lwip/icmp6.h | 70 - .../lwip/repo/lwip/src/include/lwip/if.h | 59 - .../lwip/repo/lwip/src/include/lwip/igmp.h | 118 - .../lwip/repo/lwip/src/include/lwip/inet.h | 172 - .../repo/lwip/src/include/lwip/inet_chksum.h | 105 - .../lwip/repo/lwip/src/include/lwip/init.h | 100 - .../lwip/repo/lwip/src/include/lwip/ip.h | 325 -- .../lwip/repo/lwip/src/include/lwip/ip4.h | 111 - .../repo/lwip/src/include/lwip/ip4_addr.h | 227 - .../repo/lwip/src/include/lwip/ip4_frag.h | 100 - .../lwip/repo/lwip/src/include/lwip/ip6.h | 93 - .../repo/lwip/src/include/lwip/ip6_addr.h | 306 -- .../repo/lwip/src/include/lwip/ip6_frag.h | 120 - .../lwip/src/include/lwip/ip6_route_table.h | 90 - .../lwip/repo/lwip/src/include/lwip/ip_addr.h | 407 -- .../lwip/repo/lwip/src/include/lwip/mem.h | 82 - .../lwip/repo/lwip/src/include/lwip/memp.h | 164 - .../lwip/repo/lwip/src/include/lwip/mld6.h | 97 - .../lwip/repo/lwip/src/include/lwip/nd6.h | 85 - .../lwip/repo/lwip/src/include/lwip/netbuf.h | 118 - .../lwip/repo/lwip/src/include/lwip/netdb.h | 150 - .../lwip/repo/lwip/src/include/lwip/netif.h | 515 -- .../repo/lwip/src/include/lwip/netifapi.h | 154 - .../lwip/repo/lwip/src/include/lwip/opt.h | 3014 ------------ .../lwip/repo/lwip/src/include/lwip/pbuf.h | 269 -- .../repo/lwip/src/include/lwip/priv/api_msg.h | 216 - .../lwip/src/include/lwip/priv/memp_priv.h | 183 - .../lwip/src/include/lwip/priv/memp_std.h | 146 - .../lwip/src/include/lwip/priv/nd6_priv.h | 140 - .../lwip/src/include/lwip/priv/tcp_priv.h | 507 -- .../lwip/src/include/lwip/priv/tcpip_priv.h | 161 - .../repo/lwip/src/include/lwip/prot/autoip.h | 78 - .../repo/lwip/src/include/lwip/prot/dhcp.h | 183 - .../repo/lwip/src/include/lwip/prot/dns.h | 140 - .../repo/lwip/src/include/lwip/prot/etharp.h | 91 - .../lwip/src/include/lwip/prot/ethernet.h | 170 - .../repo/lwip/src/include/lwip/prot/icmp.h | 91 - .../repo/lwip/src/include/lwip/prot/icmp6.h | 170 - .../repo/lwip/src/include/lwip/prot/igmp.h | 90 - .../lwip/repo/lwip/src/include/lwip/prot/ip.h | 51 - .../repo/lwip/src/include/lwip/prot/ip4.h | 127 - .../repo/lwip/src/include/lwip/prot/ip6.h | 171 - .../repo/lwip/src/include/lwip/prot/mld6.h | 70 - .../repo/lwip/src/include/lwip/prot/nd6.h | 290 -- .../repo/lwip/src/include/lwip/prot/tcp.h | 98 - .../repo/lwip/src/include/lwip/prot/udp.h | 68 - .../lwip/repo/lwip/src/include/lwip/raw.h | 147 - .../lwip/repo/lwip/src/include/lwip/sio.h | 142 - .../lwip/repo/lwip/src/include/lwip/snmp.h | 213 - .../lwip/repo/lwip/src/include/lwip/sockets.h | 593 --- .../lwip/repo/lwip/src/include/lwip/stats.h | 491 -- .../lwip/repo/lwip/src/include/lwip/sys.h | 462 -- .../lwip/repo/lwip/src/include/lwip/tcp.h | 438 -- .../lwip/repo/lwip/src/include/lwip/tcpip.h | 116 - .../repo/lwip/src/include/lwip/timeouts.h | 121 - .../lwip/repo/lwip/src/include/lwip/udp.h | 196 - .../lwip/repo/lwip/src/include/netif/etharp.h | 4 - .../repo/lwip/src/include/netif/ethernet.h | 77 - .../repo/lwip/src/include/netif/lowpan6.h | 86 - .../lwip/src/include/netif/lowpan6_opts.h | 70 - .../repo/lwip/src/include/netif/ppp/ccp.h | 156 - .../lwip/src/include/netif/ppp/chap-md5.h | 36 - .../lwip/src/include/netif/ppp/chap-new.h | 192 - .../repo/lwip/src/include/netif/ppp/chap_ms.h | 44 - .../repo/lwip/src/include/netif/ppp/eap.h | 169 - .../repo/lwip/src/include/netif/ppp/ecp.h | 50 - .../repo/lwip/src/include/netif/ppp/eui64.h | 94 - .../repo/lwip/src/include/netif/ppp/fsm.h | 175 - .../repo/lwip/src/include/netif/ppp/ipcp.h | 126 - .../repo/lwip/src/include/netif/ppp/ipv6cp.h | 183 - .../repo/lwip/src/include/netif/ppp/lcp.h | 171 - .../repo/lwip/src/include/netif/ppp/magic.h | 122 - .../repo/lwip/src/include/netif/ppp/mppe.h | 173 - .../src/include/netif/ppp/polarssl/arc4.h | 81 - .../lwip/src/include/netif/ppp/polarssl/des.h | 92 - .../lwip/src/include/netif/ppp/polarssl/md4.h | 97 - .../lwip/src/include/netif/ppp/polarssl/md5.h | 96 - .../src/include/netif/ppp/polarssl/sha1.h | 96 - .../repo/lwip/src/include/netif/ppp/ppp.h | 690 --- .../lwip/src/include/netif/ppp/ppp_impl.h | 629 --- .../lwip/src/include/netif/ppp/ppp_opts.h | 593 --- .../repo/lwip/src/include/netif/ppp/pppapi.h | 137 - .../lwip/src/include/netif/ppp/pppcrypt.h | 136 - .../lwip/src/include/netif/ppp/pppdebug.h | 80 - .../repo/lwip/src/include/netif/ppp/pppoe.h | 179 - .../lwip/src/include/netif/ppp/pppol2tp.h | 201 - .../repo/lwip/src/include/netif/ppp/pppos.h | 118 - .../repo/lwip/src/include/netif/ppp/upap.h | 123 - .../lwip/repo/lwip/src/include/netif/ppp/vj.h | 161 - .../lwip/repo/lwip/src/include/netif/slipif.h | 87 - .../lwip/repo/lwip/src/include/posix/errno.h | 33 - .../lwip/repo/lwip/src/include/posix/net/if.h | 33 - .../lwip/repo/lwip/src/include/posix/netdb.h | 33 - .../repo/lwip/src/include/posix/sys/socket.h | 33 - third_party/lwip/repo/lwip/src/netif/FILES | 24 - .../lwip/repo/lwip/src/netif/ethernet.c | 314 -- .../lwip/repo/lwip/src/netif/ethernetif.c | 335 -- .../lwip/repo/lwip/src/netif/lowpan6.c | 1193 ----- .../repo/lwip/src/netif/ppp/PPPD_FOLLOWUP | 473 -- .../lwip/repo/lwip/src/netif/ppp/auth.c | 2510 ---------- .../lwip/repo/lwip/src/netif/ppp/ccp.c | 1740 ------- .../lwip/repo/lwip/src/netif/ppp/chap-md5.c | 126 - .../lwip/repo/lwip/src/netif/ppp/chap-new.c | 677 --- .../lwip/repo/lwip/src/netif/ppp/chap_ms.c | 962 ---- .../lwip/repo/lwip/src/netif/ppp/demand.c | 465 -- .../lwip/repo/lwip/src/netif/ppp/eap.c | 2423 ---------- .../lwip/repo/lwip/src/netif/ppp/ecp.c | 191 - .../lwip/repo/lwip/src/netif/ppp/eui64.c | 56 - .../lwip/repo/lwip/src/netif/ppp/fsm.c | 799 --- .../lwip/repo/lwip/src/netif/ppp/ipcp.c | 2418 ---------- .../lwip/repo/lwip/src/netif/ppp/ipv6cp.c | 1533 ------ .../lwip/repo/lwip/src/netif/ppp/lcp.c | 2790 ----------- .../lwip/repo/lwip/src/netif/ppp/magic.c | 294 -- .../lwip/repo/lwip/src/netif/ppp/mppe.c | 412 -- .../lwip/repo/lwip/src/netif/ppp/multilink.c | 609 --- .../repo/lwip/src/netif/ppp/polarssl/README | 22 - .../repo/lwip/src/netif/ppp/polarssl/arc4.c | 101 - .../repo/lwip/src/netif/ppp/polarssl/des.c | 422 -- .../repo/lwip/src/netif/ppp/polarssl/md4.c | 281 -- .../repo/lwip/src/netif/ppp/polarssl/md5.c | 300 -- .../repo/lwip/src/netif/ppp/polarssl/sha1.c | 335 -- .../lwip/repo/lwip/src/netif/ppp/ppp.c | 1647 ------- .../lwip/repo/lwip/src/netif/ppp/pppapi.c | 427 -- .../lwip/repo/lwip/src/netif/ppp/pppcrypt.c | 66 - .../lwip/repo/lwip/src/netif/ppp/pppoe.c | 1191 ----- .../lwip/repo/lwip/src/netif/ppp/pppol2tp.c | 1131 ----- .../lwip/repo/lwip/src/netif/ppp/pppos.c | 875 ---- .../lwip/repo/lwip/src/netif/ppp/upap.c | 677 --- .../lwip/repo/lwip/src/netif/ppp/utils.c | 959 ---- third_party/lwip/repo/lwip/src/netif/ppp/vj.c | 695 --- third_party/lwip/repo/lwip/src/netif/slipif.c | 555 --- 289 files changed, 128 insertions(+), 120210 deletions(-) create mode 100644 src/lwip/standalone/pbuf_pool_assert.c create mode 160000 third_party/lwip/repo delete mode 100644 third_party/lwip/repo/lwip.url delete mode 100644 third_party/lwip/repo/lwip.version delete mode 100644 third_party/lwip/repo/lwip/.gitattributes delete mode 100644 third_party/lwip/repo/lwip/.gitignore delete mode 100644 third_party/lwip/repo/lwip/CHANGELOG delete mode 100644 third_party/lwip/repo/lwip/COPYING delete mode 100644 third_party/lwip/repo/lwip/FILES delete mode 100644 third_party/lwip/repo/lwip/README delete mode 100644 third_party/lwip/repo/lwip/UPGRADING delete mode 100644 third_party/lwip/repo/lwip/doc/FILES delete mode 100644 third_party/lwip/repo/lwip/doc/NO_SYS_SampleCode.c delete mode 100644 third_party/lwip/repo/lwip/doc/contrib.txt delete mode 100644 third_party/lwip/repo/lwip/doc/doxygen/generate.bat delete mode 100755 third_party/lwip/repo/lwip/doc/doxygen/generate.sh delete mode 100644 third_party/lwip/repo/lwip/doc/doxygen/lwip.Doxyfile delete mode 100644 third_party/lwip/repo/lwip/doc/doxygen/main_page.h delete mode 100644 third_party/lwip/repo/lwip/doc/doxygen/output/index.html delete mode 100644 third_party/lwip/repo/lwip/doc/mdns.txt delete mode 100644 third_party/lwip/repo/lwip/doc/mqtt_client.txt delete mode 100644 third_party/lwip/repo/lwip/doc/ppp.txt delete mode 100644 third_party/lwip/repo/lwip/doc/rawapi.txt delete mode 100644 third_party/lwip/repo/lwip/doc/savannah.txt delete mode 100644 third_party/lwip/repo/lwip/doc/sys_arch.txt delete mode 100644 third_party/lwip/repo/lwip/src/FILES delete mode 100644 third_party/lwip/repo/lwip/src/Filelists.mk delete mode 100644 third_party/lwip/repo/lwip/src/api/api_lib.c delete mode 100644 third_party/lwip/repo/lwip/src/api/api_msg.c delete mode 100644 third_party/lwip/repo/lwip/src/api/err.c delete mode 100644 third_party/lwip/repo/lwip/src/api/if.c delete mode 100644 third_party/lwip/repo/lwip/src/api/netbuf.c delete mode 100644 third_party/lwip/repo/lwip/src/api/netdb.c delete mode 100644 third_party/lwip/repo/lwip/src/api/netifapi.c delete mode 100644 third_party/lwip/repo/lwip/src/api/sockets.c delete mode 100644 third_party/lwip/repo/lwip/src/api/tcpip.c delete mode 100644 third_party/lwip/repo/lwip/src/apps/httpd/fs.c delete mode 100644 third_party/lwip/repo/lwip/src/apps/httpd/fs/404.html delete mode 100644 third_party/lwip/repo/lwip/src/apps/httpd/fs/img/sics.gif delete mode 100644 third_party/lwip/repo/lwip/src/apps/httpd/fs/index.html delete mode 100644 third_party/lwip/repo/lwip/src/apps/httpd/fsdata.c delete mode 100644 third_party/lwip/repo/lwip/src/apps/httpd/fsdata.h delete mode 100644 third_party/lwip/repo/lwip/src/apps/httpd/httpd.c delete mode 100644 third_party/lwip/repo/lwip/src/apps/httpd/httpd_structs.h delete mode 100644 third_party/lwip/repo/lwip/src/apps/httpd/makefsdata/makefsdata delete mode 100644 third_party/lwip/repo/lwip/src/apps/httpd/makefsdata/makefsdata.c delete mode 100644 third_party/lwip/repo/lwip/src/apps/httpd/makefsdata/readme.txt delete mode 100644 third_party/lwip/repo/lwip/src/apps/lwiperf/lwiperf.c delete mode 100644 third_party/lwip/repo/lwip/src/apps/mdns/mdns.c delete mode 100644 third_party/lwip/repo/lwip/src/apps/mqtt/mqtt.c delete mode 100644 third_party/lwip/repo/lwip/src/apps/netbiosns/netbiosns.c delete mode 100644 third_party/lwip/repo/lwip/src/apps/snmp/snmp_asn1.c delete mode 100644 third_party/lwip/repo/lwip/src/apps/snmp/snmp_asn1.h delete mode 100644 third_party/lwip/repo/lwip/src/apps/snmp/snmp_core.c delete mode 100644 third_party/lwip/repo/lwip/src/apps/snmp/snmp_core_priv.h delete mode 100644 third_party/lwip/repo/lwip/src/apps/snmp/snmp_mib2.c delete mode 100644 third_party/lwip/repo/lwip/src/apps/snmp/snmp_mib2_icmp.c delete mode 100644 third_party/lwip/repo/lwip/src/apps/snmp/snmp_mib2_interfaces.c delete mode 100644 third_party/lwip/repo/lwip/src/apps/snmp/snmp_mib2_ip.c delete mode 100644 third_party/lwip/repo/lwip/src/apps/snmp/snmp_mib2_snmp.c delete mode 100644 third_party/lwip/repo/lwip/src/apps/snmp/snmp_mib2_system.c delete mode 100644 third_party/lwip/repo/lwip/src/apps/snmp/snmp_mib2_tcp.c delete mode 100644 third_party/lwip/repo/lwip/src/apps/snmp/snmp_mib2_udp.c delete mode 100644 third_party/lwip/repo/lwip/src/apps/snmp/snmp_msg.c delete mode 100644 third_party/lwip/repo/lwip/src/apps/snmp/snmp_msg.h delete mode 100644 third_party/lwip/repo/lwip/src/apps/snmp/snmp_netconn.c delete mode 100644 third_party/lwip/repo/lwip/src/apps/snmp/snmp_pbuf_stream.c delete mode 100644 third_party/lwip/repo/lwip/src/apps/snmp/snmp_pbuf_stream.h delete mode 100644 third_party/lwip/repo/lwip/src/apps/snmp/snmp_raw.c delete mode 100644 third_party/lwip/repo/lwip/src/apps/snmp/snmp_scalar.c delete mode 100644 third_party/lwip/repo/lwip/src/apps/snmp/snmp_table.c delete mode 100644 third_party/lwip/repo/lwip/src/apps/snmp/snmp_threadsync.c delete mode 100644 third_party/lwip/repo/lwip/src/apps/snmp/snmp_traps.c delete mode 100644 third_party/lwip/repo/lwip/src/apps/snmp/snmpv3.c delete mode 100644 third_party/lwip/repo/lwip/src/apps/snmp/snmpv3_dummy.c delete mode 100644 third_party/lwip/repo/lwip/src/apps/snmp/snmpv3_mbedtls.c delete mode 100644 third_party/lwip/repo/lwip/src/apps/snmp/snmpv3_priv.h delete mode 100644 third_party/lwip/repo/lwip/src/apps/sntp/sntp.c delete mode 100644 third_party/lwip/repo/lwip/src/apps/tftp/tftp_server.c delete mode 100644 third_party/lwip/repo/lwip/src/core/def.c delete mode 100644 third_party/lwip/repo/lwip/src/core/dns.c delete mode 100644 third_party/lwip/repo/lwip/src/core/inet_chksum.c delete mode 100644 third_party/lwip/repo/lwip/src/core/init.c delete mode 100644 third_party/lwip/repo/lwip/src/core/ip.c delete mode 100644 third_party/lwip/repo/lwip/src/core/ipv4/autoip.c delete mode 100644 third_party/lwip/repo/lwip/src/core/ipv4/dhcp.c delete mode 100644 third_party/lwip/repo/lwip/src/core/ipv4/etharp.c delete mode 100644 third_party/lwip/repo/lwip/src/core/ipv4/icmp.c delete mode 100644 third_party/lwip/repo/lwip/src/core/ipv4/igmp.c delete mode 100644 third_party/lwip/repo/lwip/src/core/ipv4/ip4.c delete mode 100644 third_party/lwip/repo/lwip/src/core/ipv4/ip4_addr.c delete mode 100644 third_party/lwip/repo/lwip/src/core/ipv4/ip4_frag.c delete mode 100644 third_party/lwip/repo/lwip/src/core/ipv6/dhcp6.c delete mode 100644 third_party/lwip/repo/lwip/src/core/ipv6/ethip6.c delete mode 100644 third_party/lwip/repo/lwip/src/core/ipv6/icmp6.c delete mode 100644 third_party/lwip/repo/lwip/src/core/ipv6/inet6.c delete mode 100644 third_party/lwip/repo/lwip/src/core/ipv6/ip6.c delete mode 100644 third_party/lwip/repo/lwip/src/core/ipv6/ip6_addr.c delete mode 100644 third_party/lwip/repo/lwip/src/core/ipv6/ip6_frag.c delete mode 100644 third_party/lwip/repo/lwip/src/core/ipv6/ip6_route_table.c delete mode 100644 third_party/lwip/repo/lwip/src/core/ipv6/mld6.c delete mode 100644 third_party/lwip/repo/lwip/src/core/ipv6/nd6.c delete mode 100644 third_party/lwip/repo/lwip/src/core/mem.c delete mode 100644 third_party/lwip/repo/lwip/src/core/memp.c delete mode 100644 third_party/lwip/repo/lwip/src/core/netif.c delete mode 100644 third_party/lwip/repo/lwip/src/core/pbuf.c delete mode 100644 third_party/lwip/repo/lwip/src/core/raw.c delete mode 100644 third_party/lwip/repo/lwip/src/core/stats.c delete mode 100644 third_party/lwip/repo/lwip/src/core/sys.c delete mode 100644 third_party/lwip/repo/lwip/src/core/tcp.c delete mode 100644 third_party/lwip/repo/lwip/src/core/tcp_in.c delete mode 100644 third_party/lwip/repo/lwip/src/core/tcp_out.c delete mode 100644 third_party/lwip/repo/lwip/src/core/timeouts.c delete mode 100644 third_party/lwip/repo/lwip/src/core/udp.c delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/api.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/apps/FILES delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/apps/fs.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/apps/httpd.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/apps/httpd_opts.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/apps/lwiperf.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/apps/mdns.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/apps/mdns_opts.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/apps/mdns_priv.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/apps/mqtt.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/apps/mqtt_opts.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/apps/netbiosns.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/apps/netbiosns_opts.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/apps/snmp.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/apps/snmp_core.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/apps/snmp_mib2.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/apps/snmp_opts.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/apps/snmp_scalar.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/apps/snmp_table.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/apps/snmp_threadsync.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/apps/snmpv3.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/apps/sntp.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/apps/sntp_opts.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/apps/tftp_opts.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/apps/tftp_server.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/arch.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/autoip.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/debug.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/def.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/dhcp.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/dhcp6.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/dns.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/err.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/errno.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/etharp.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/ethip6.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/icmp.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/icmp6.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/if.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/igmp.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/inet.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/inet_chksum.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/init.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/ip.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/ip4.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/ip4_addr.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/ip4_frag.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/ip6.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/ip6_addr.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/ip6_frag.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/ip6_route_table.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/ip_addr.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/mem.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/memp.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/mld6.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/nd6.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/netbuf.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/netdb.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/netif.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/netifapi.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/opt.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/pbuf.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/priv/api_msg.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/priv/memp_priv.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/priv/memp_std.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/priv/nd6_priv.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/priv/tcp_priv.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/priv/tcpip_priv.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/prot/autoip.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/prot/dhcp.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/prot/dns.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/prot/etharp.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/prot/ethernet.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/prot/icmp.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/prot/icmp6.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/prot/igmp.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/prot/ip.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/prot/ip4.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/prot/ip6.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/prot/mld6.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/prot/nd6.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/prot/tcp.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/prot/udp.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/raw.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/sio.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/snmp.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/sockets.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/stats.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/sys.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/tcp.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/tcpip.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/timeouts.h delete mode 100644 third_party/lwip/repo/lwip/src/include/lwip/udp.h delete mode 100644 third_party/lwip/repo/lwip/src/include/netif/etharp.h delete mode 100644 third_party/lwip/repo/lwip/src/include/netif/ethernet.h delete mode 100644 third_party/lwip/repo/lwip/src/include/netif/lowpan6.h delete mode 100644 third_party/lwip/repo/lwip/src/include/netif/lowpan6_opts.h delete mode 100644 third_party/lwip/repo/lwip/src/include/netif/ppp/ccp.h delete mode 100644 third_party/lwip/repo/lwip/src/include/netif/ppp/chap-md5.h delete mode 100644 third_party/lwip/repo/lwip/src/include/netif/ppp/chap-new.h delete mode 100644 third_party/lwip/repo/lwip/src/include/netif/ppp/chap_ms.h delete mode 100644 third_party/lwip/repo/lwip/src/include/netif/ppp/eap.h delete mode 100644 third_party/lwip/repo/lwip/src/include/netif/ppp/ecp.h delete mode 100644 third_party/lwip/repo/lwip/src/include/netif/ppp/eui64.h delete mode 100644 third_party/lwip/repo/lwip/src/include/netif/ppp/fsm.h delete mode 100644 third_party/lwip/repo/lwip/src/include/netif/ppp/ipcp.h delete mode 100644 third_party/lwip/repo/lwip/src/include/netif/ppp/ipv6cp.h delete mode 100644 third_party/lwip/repo/lwip/src/include/netif/ppp/lcp.h delete mode 100644 third_party/lwip/repo/lwip/src/include/netif/ppp/magic.h delete mode 100644 third_party/lwip/repo/lwip/src/include/netif/ppp/mppe.h delete mode 100644 third_party/lwip/repo/lwip/src/include/netif/ppp/polarssl/arc4.h delete mode 100644 third_party/lwip/repo/lwip/src/include/netif/ppp/polarssl/des.h delete mode 100644 third_party/lwip/repo/lwip/src/include/netif/ppp/polarssl/md4.h delete mode 100644 third_party/lwip/repo/lwip/src/include/netif/ppp/polarssl/md5.h delete mode 100644 third_party/lwip/repo/lwip/src/include/netif/ppp/polarssl/sha1.h delete mode 100644 third_party/lwip/repo/lwip/src/include/netif/ppp/ppp.h delete mode 100644 third_party/lwip/repo/lwip/src/include/netif/ppp/ppp_impl.h delete mode 100644 third_party/lwip/repo/lwip/src/include/netif/ppp/ppp_opts.h delete mode 100644 third_party/lwip/repo/lwip/src/include/netif/ppp/pppapi.h delete mode 100644 third_party/lwip/repo/lwip/src/include/netif/ppp/pppcrypt.h delete mode 100644 third_party/lwip/repo/lwip/src/include/netif/ppp/pppdebug.h delete mode 100644 third_party/lwip/repo/lwip/src/include/netif/ppp/pppoe.h delete mode 100644 third_party/lwip/repo/lwip/src/include/netif/ppp/pppol2tp.h delete mode 100644 third_party/lwip/repo/lwip/src/include/netif/ppp/pppos.h delete mode 100644 third_party/lwip/repo/lwip/src/include/netif/ppp/upap.h delete mode 100644 third_party/lwip/repo/lwip/src/include/netif/ppp/vj.h delete mode 100644 third_party/lwip/repo/lwip/src/include/netif/slipif.h delete mode 100644 third_party/lwip/repo/lwip/src/include/posix/errno.h delete mode 100644 third_party/lwip/repo/lwip/src/include/posix/net/if.h delete mode 100644 third_party/lwip/repo/lwip/src/include/posix/netdb.h delete mode 100644 third_party/lwip/repo/lwip/src/include/posix/sys/socket.h delete mode 100644 third_party/lwip/repo/lwip/src/netif/FILES delete mode 100644 third_party/lwip/repo/lwip/src/netif/ethernet.c delete mode 100644 third_party/lwip/repo/lwip/src/netif/ethernetif.c delete mode 100644 third_party/lwip/repo/lwip/src/netif/lowpan6.c delete mode 100644 third_party/lwip/repo/lwip/src/netif/ppp/PPPD_FOLLOWUP delete mode 100644 third_party/lwip/repo/lwip/src/netif/ppp/auth.c delete mode 100644 third_party/lwip/repo/lwip/src/netif/ppp/ccp.c delete mode 100644 third_party/lwip/repo/lwip/src/netif/ppp/chap-md5.c delete mode 100644 third_party/lwip/repo/lwip/src/netif/ppp/chap-new.c delete mode 100644 third_party/lwip/repo/lwip/src/netif/ppp/chap_ms.c delete mode 100644 third_party/lwip/repo/lwip/src/netif/ppp/demand.c delete mode 100644 third_party/lwip/repo/lwip/src/netif/ppp/eap.c delete mode 100644 third_party/lwip/repo/lwip/src/netif/ppp/ecp.c delete mode 100644 third_party/lwip/repo/lwip/src/netif/ppp/eui64.c delete mode 100644 third_party/lwip/repo/lwip/src/netif/ppp/fsm.c delete mode 100644 third_party/lwip/repo/lwip/src/netif/ppp/ipcp.c delete mode 100644 third_party/lwip/repo/lwip/src/netif/ppp/ipv6cp.c delete mode 100644 third_party/lwip/repo/lwip/src/netif/ppp/lcp.c delete mode 100644 third_party/lwip/repo/lwip/src/netif/ppp/magic.c delete mode 100644 third_party/lwip/repo/lwip/src/netif/ppp/mppe.c delete mode 100644 third_party/lwip/repo/lwip/src/netif/ppp/multilink.c delete mode 100644 third_party/lwip/repo/lwip/src/netif/ppp/polarssl/README delete mode 100644 third_party/lwip/repo/lwip/src/netif/ppp/polarssl/arc4.c delete mode 100644 third_party/lwip/repo/lwip/src/netif/ppp/polarssl/des.c delete mode 100644 third_party/lwip/repo/lwip/src/netif/ppp/polarssl/md4.c delete mode 100644 third_party/lwip/repo/lwip/src/netif/ppp/polarssl/md5.c delete mode 100644 third_party/lwip/repo/lwip/src/netif/ppp/polarssl/sha1.c delete mode 100644 third_party/lwip/repo/lwip/src/netif/ppp/ppp.c delete mode 100644 third_party/lwip/repo/lwip/src/netif/ppp/pppapi.c delete mode 100644 third_party/lwip/repo/lwip/src/netif/ppp/pppcrypt.c delete mode 100644 third_party/lwip/repo/lwip/src/netif/ppp/pppoe.c delete mode 100644 third_party/lwip/repo/lwip/src/netif/ppp/pppol2tp.c delete mode 100644 third_party/lwip/repo/lwip/src/netif/ppp/pppos.c delete mode 100644 third_party/lwip/repo/lwip/src/netif/ppp/upap.c delete mode 100644 third_party/lwip/repo/lwip/src/netif/ppp/utils.c delete mode 100644 third_party/lwip/repo/lwip/src/netif/ppp/vj.c delete mode 100644 third_party/lwip/repo/lwip/src/netif/slipif.c diff --git a/.gitmodules b/.gitmodules index 592c49a2a7085f..824bd9954e506c 100644 --- a/.gitmodules +++ b/.gitmodules @@ -329,6 +329,9 @@ path = third_party/infineon/psoc6/psoc6_sdk/libs/lwip-network-interface-integration url = https://github.com/Infineon/lwip-network-interface-integration.git platforms = infineon +[submodule "third_party/lwip/repo"] + path = third_party/lwip/repo + url = https://github.com/lwip-tcpip/lwip.git [submodule "third_party/abseil-cpp/src"] path = third_party/abseil-cpp/src url = https://github.com/abseil/abseil-cpp.git diff --git a/src/lwip/BUILD.gn b/src/lwip/BUILD.gn index 145bc2dd1d0183..ca08a8c392182d 100644 --- a/src/lwip/BUILD.gn +++ b/src/lwip/BUILD.gn @@ -202,6 +202,7 @@ if (current_os == "zephyr" || current_os == "mbed") { if (lwip_platform == "standalone") { public += [ "standalone/arch/sys_arch.h" ] sources += [ "standalone/sys_arch.c" ] + sources += [ "standalone/pbuf_pool_assert.c" ] } else if (lwip_platform == "cyw30739") { } else if (lwip_platform == "mt793x") { } else { @@ -217,8 +218,6 @@ if (current_os == "zephyr" || current_os == "mbed") { public_deps += [ "${ti_simplelink_sdk_build_root}:ti_simplelink_sdk" ] } else if (lwip_platform == "cc32xx") { public_deps += [ "${ti_simplelink_sdk_build_root}:ti_simplelink_sdk" ] - sources += - [ "${chip_root}/third_party/lwip/repo/lwip/src/apps/mdns/mdns.c" ] } else if (lwip_platform == "silabs") { public_deps += [ "${efr32_sdk_build_root}:efr32_sdk" ] diff --git a/src/lwip/cc13xx_26xx/lwipopts.h b/src/lwip/cc13xx_26xx/lwipopts.h index 26a1bb6641cb00..194e81a9440385 100644 --- a/src/lwip/cc13xx_26xx/lwipopts.h +++ b/src/lwip/cc13xx_26xx/lwipopts.h @@ -72,9 +72,11 @@ #define LWIP_IGMP (0) #define LWIP_DHCP (0) #define LWIP_IPV6_REASS (0) +#define LWIP_IPV6_FRAG 0 #define LWIP_IPV6_DHCP6 0 #define LWIP_IPV6_AUTOCONFIG (0) #define LWIP_IPV6_ROUTER_SUPPORT 0 +#define LWIP_IPV6_FORWARD 0 #define LWIP_ND6_LISTEN_RA 0 #define LWIP_ND6_NUM_NEIGHBORS (1) diff --git a/src/lwip/cc32xx/lwipopts.h b/src/lwip/cc32xx/lwipopts.h index 146ff2bec8556a..972766336a6473 100644 --- a/src/lwip/cc32xx/lwipopts.h +++ b/src/lwip/cc32xx/lwipopts.h @@ -78,9 +78,11 @@ #define LWIP_IGMP (1) #define LWIP_DHCP (1) #define LWIP_IPV6_REASS (0) +#define LWIP_IPV6_FRAG 0 #define LWIP_IPV6_DHCP6 0 #define LWIP_IPV6_AUTOCONFIG (0) #define LWIP_IPV6_ROUTER_SUPPORT 0 +#define LWIP_IPV6_FORWARD 0 #define LWIP_ND6_LISTEN_RA 0 #define LWIP_ND6_NUM_NEIGHBORS (0) diff --git a/src/lwip/standalone/arch/cc.h b/src/lwip/standalone/arch/cc.h index 74110797475de8..4b7aca34f4a4d1 100644 --- a/src/lwip/standalone/arch/cc.h +++ b/src/lwip/standalone/arch/cc.h @@ -52,6 +52,10 @@ #ifndef __ARCH_CC_H__ #define __ARCH_CC_H__ +#if CHIP_HAVE_CONFIG_H +#include +#endif + /* Include some files for defining library routines */ #include #include diff --git a/src/lwip/standalone/lwipopts.h b/src/lwip/standalone/lwipopts.h index 84aa44e1c5c62a..c4fab1ec677739 100644 --- a/src/lwip/standalone/lwipopts.h +++ b/src/lwip/standalone/lwipopts.h @@ -28,10 +28,6 @@ #ifndef __LWIPOPTS_H__ #define __LWIPOPTS_H__ -#if CHIP_HAVE_CONFIG_H -#include -#endif - #include /** @@ -137,11 +133,12 @@ * PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. The default is * designed to accommodate single full size link-layer frame in one pbuf, including * the link-layer header and any link-layer encapsulation header, and the pbuf - * structure itself. + * structure itself. pbuf struct consists of 2 pointers, 2 u16_t, 4 u8_t. */ #define PBUF_POOL_BUFSIZE \ - LWIP_MEM_ALIGN_SIZE(PAYLOAD_MTU + PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN) + LWIP_MEM_ALIGN_SIZE(sizeof(struct pbuf) + 1) + LWIP_MEM_ALIGN_SIZE(PAYLOAD_MTU + PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN) + \ + LWIP_MEM_ALIGN_SIZE(2 * __SIZEOF_POINTER__ + (2 * 2) + (4 * 1) + 1) /** * TCP_SND_BUF: TCP sender buffer space (bytes). @@ -414,14 +411,6 @@ extern unsigned char gLwIP_DebugFlags; #endif -/** - * The WICED definition of PBUF_POOL_BUFSIZE includes a number of - * sizeof() instantiations which causes the C preprocessor to - * fail. Disable TCP configuration constant sanity checks to work - * around this. - */ -#define LWIP_DISABLE_TCP_SANITY_CHECKS (1) - /** * LwIP defaults the size of most mailboxes (i.e. message queues) to * zero (0). That generally makes RTOSes such as FreeRTOS very diff --git a/src/lwip/standalone/pbuf_pool_assert.c b/src/lwip/standalone/pbuf_pool_assert.c new file mode 100644 index 00000000000000..1e743e25d6377a --- /dev/null +++ b/src/lwip/standalone/pbuf_pool_assert.c @@ -0,0 +1,27 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "lwip/pbuf.h" +#include "lwipopts.h" + +/** + * PBUF_POOL_BUFSIZE, defined in lwipopts.h was previously using sizeof, but as it is used in other preprocessor macros in lwip + * code, it failed. Below is to make sure that current calculation aligns with previous. + */ +_Static_assert((LWIP_MEM_ALIGN_SIZE(2 * __SIZEOF_POINTER__ + (2 * 2) + (4 * 1) + 1) == + LWIP_MEM_ALIGN_SIZE(sizeof(struct pbuf) + 1)), + "PBUF_POOL_BUFFSIZE in lwipopts.h needs adjusting."); diff --git a/third_party/lwip/lwip.gni b/third_party/lwip/lwip.gni index 68d776be47472f..720e669510543a 100644 --- a/third_party/lwip/lwip.gni +++ b/third_party/lwip/lwip.gni @@ -19,7 +19,7 @@ import("//build_overrides/lwip.gni") # lwIP depends on external header files to compile. This template defines # a combined build of the lwIP sources plus target configuration. template("lwip_target") { - _lwip_root = "${lwip_root}/repo/lwip" + _lwip_root = "${lwip_root}/repo" lwip_target_name = target_name @@ -29,9 +29,12 @@ template("lwip_target") { "lwip_ipv4", "lwip_ipv6", "lwip_api", + "lwip_bridge", "lwip_ethernet", "lwip_slip", "lwip_6lowpan", + "lwip_6lowpan_ble", + "lwip_zep", ]) if (!defined(lwip_ipv4)) { @@ -43,6 +46,9 @@ template("lwip_target") { if (!defined(lwip_api)) { lwip_api = true } + if (!defined(lwip_bridge)) { + lwip_bridge = false + } if (!defined(lwip_ethernet)) { lwip_ethernet = true } @@ -52,9 +58,18 @@ template("lwip_target") { if (!defined(lwip_6lowpan)) { lwip_6lowpan = false } + if (!defined(lwip_6lowpan_ble)) { + lwip_6lowpan_ble = false + } + if (!defined(lwip_zep)) { + lwip_zep = false + } config("${lwip_target_name}_base_config") { - include_dirs = [ "${lwip_root}/repo/lwip/src/include" ] + include_dirs = [ + "${lwip_root}/repo/src/include", + "${lwip_root}/repo/contrib/addons/ipv6_static_routing/", + ] } source_set(lwip_target_name) { @@ -69,6 +84,11 @@ template("lwip_target") { # lwIP headers become empty if the relevant feature is disabled, so the # whole interface can be public regardless of build options. public += [ + "${_lwip_root}/contrib/addons/ipv6_static_routing/ip6_route_table.h", + "${_lwip_root}/src/include/lwip/acd.h", + "${_lwip_root}/src/include/lwip/altcp.h", + "${_lwip_root}/src/include/lwip/altcp_tcp.h", + "${_lwip_root}/src/include/lwip/altcp_tls.h", "${_lwip_root}/src/include/lwip/api.h", "${_lwip_root}/src/include/lwip/autoip.h", "${_lwip_root}/src/include/lwip/debug.h", @@ -77,21 +97,23 @@ template("lwip_target") { "${_lwip_root}/src/include/lwip/dhcp6.h", "${_lwip_root}/src/include/lwip/dns.h", "${_lwip_root}/src/include/lwip/err.h", + "${_lwip_root}/src/include/lwip/errno.h", "${_lwip_root}/src/include/lwip/etharp.h", "${_lwip_root}/src/include/lwip/ethip6.h", "${_lwip_root}/src/include/lwip/icmp.h", "${_lwip_root}/src/include/lwip/icmp6.h", - "${_lwip_root}/src/include/lwip/if.h", + "${_lwip_root}/src/include/lwip/if_api.h", "${_lwip_root}/src/include/lwip/igmp.h", "${_lwip_root}/src/include/lwip/inet.h", "${_lwip_root}/src/include/lwip/inet_chksum.h", "${_lwip_root}/src/include/lwip/init.h", "${_lwip_root}/src/include/lwip/ip.h", + "${_lwip_root}/src/include/lwip/ip4_addr.h", "${_lwip_root}/src/include/lwip/ip4_frag.h", "${_lwip_root}/src/include/lwip/ip6.h", "${_lwip_root}/src/include/lwip/ip6_addr.h", "${_lwip_root}/src/include/lwip/ip6_frag.h", - "${_lwip_root}/src/include/lwip/ip6_route_table.h", + "${_lwip_root}/src/include/lwip/ip6_zone.h", "${_lwip_root}/src/include/lwip/ip_addr.h", "${_lwip_root}/src/include/lwip/mem.h", "${_lwip_root}/src/include/lwip/memp.h", @@ -103,28 +125,62 @@ template("lwip_target") { "${_lwip_root}/src/include/lwip/netifapi.h", "${_lwip_root}/src/include/lwip/opt.h", "${_lwip_root}/src/include/lwip/pbuf.h", + "${_lwip_root}/src/include/lwip/priv/altcp_priv.h", + "${_lwip_root}/src/include/lwip/priv/api_msg.h", + "${_lwip_root}/src/include/lwip/priv/mem_priv.h", + "${_lwip_root}/src/include/lwip/priv/memp_priv.h", + "${_lwip_root}/src/include/lwip/priv/memp_std.h", + "${_lwip_root}/src/include/lwip/priv/nd6_priv.h", + "${_lwip_root}/src/include/lwip/priv/raw_priv.h", + "${_lwip_root}/src/include/lwip/priv/sockets_priv.h", "${_lwip_root}/src/include/lwip/priv/tcp_priv.h", "${_lwip_root}/src/include/lwip/priv/tcpip_priv.h", + "${_lwip_root}/src/include/lwip/prot/acd.h", "${_lwip_root}/src/include/lwip/prot/autoip.h", "${_lwip_root}/src/include/lwip/prot/dhcp.h", + "${_lwip_root}/src/include/lwip/prot/dhcp6.h", "${_lwip_root}/src/include/lwip/prot/dns.h", + "${_lwip_root}/src/include/lwip/prot/etharp.h", "${_lwip_root}/src/include/lwip/prot/ethernet.h", + "${_lwip_root}/src/include/lwip/prot/iana.h", "${_lwip_root}/src/include/lwip/prot/icmp6.h", + "${_lwip_root}/src/include/lwip/prot/ieee.h", "${_lwip_root}/src/include/lwip/prot/igmp.h", + "${_lwip_root}/src/include/lwip/prot/ip.h", + "${_lwip_root}/src/include/lwip/prot/ip4.h", + "${_lwip_root}/src/include/lwip/prot/ip6.h", "${_lwip_root}/src/include/lwip/prot/mld6.h", "${_lwip_root}/src/include/lwip/prot/nd6.h", + "${_lwip_root}/src/include/lwip/prot/tcp.h", + "${_lwip_root}/src/include/lwip/prot/udp.h", "${_lwip_root}/src/include/lwip/raw.h", + "${_lwip_root}/src/include/lwip/sio.h", "${_lwip_root}/src/include/lwip/snmp.h", "${_lwip_root}/src/include/lwip/sockets.h", "${_lwip_root}/src/include/lwip/stats.h", "${_lwip_root}/src/include/lwip/sys.h", "${_lwip_root}/src/include/lwip/tcp.h", + "${_lwip_root}/src/include/lwip/tcpbase.h", "${_lwip_root}/src/include/lwip/tcpip.h", "${_lwip_root}/src/include/lwip/timeouts.h", "${_lwip_root}/src/include/lwip/udp.h", + "${_lwip_root}/src/include/netif/bridgeif.h", + "${_lwip_root}/src/include/netif/bridgeif_opts.h", + "${_lwip_root}/src/include/netif/etharp.h", + "${_lwip_root}/src/include/netif/ethernet.h", + "${_lwip_root}/src/include/netif/ieee802154.h", + "${_lwip_root}/src/include/netif/lowpan6.h", + "${_lwip_root}/src/include/netif/lowpan6_ble.h", + "${_lwip_root}/src/include/netif/lowpan6_common.h", + "${_lwip_root}/src/include/netif/lowpan6_opts.h", + "${_lwip_root}/src/include/netif/slipif.h", + "${_lwip_root}/src/include/netif/zepif.h", ] sources += [ + "${_lwip_root}/src/core/altcp.c", + "${_lwip_root}/src/core/altcp_alloc.c", + "${_lwip_root}/src/core/altcp_tcp.c", "${_lwip_root}/src/core/def.c", "${_lwip_root}/src/core/dns.c", "${_lwip_root}/src/core/inet_chksum.c", @@ -142,13 +198,11 @@ template("lwip_target") { "${_lwip_root}/src/core/tcp_out.c", "${_lwip_root}/src/core/timeouts.c", "${_lwip_root}/src/core/udp.c", - "${_lwip_root}/src/include/lwip/priv/api_msg.h", - "${_lwip_root}/src/include/lwip/priv/memp_std.h", - "${_lwip_root}/src/include/lwip/priv/nd6_priv.h", ] if (lwip_ipv4) { sources += [ + "${_lwip_root}/src/core/ipv4/acd.c", "${_lwip_root}/src/core/ipv4/autoip.c", "${_lwip_root}/src/core/ipv4/dhcp.c", "${_lwip_root}/src/core/ipv4/etharp.c", @@ -162,6 +216,7 @@ template("lwip_target") { if (lwip_ipv6) { sources += [ + "${_lwip_root}/contrib/addons/ipv6_static_routing/ip6_route_table.c", "${_lwip_root}/src/core/ipv6/dhcp6.c", "${_lwip_root}/src/core/ipv6/ethip6.c", "${_lwip_root}/src/core/ipv6/icmp6.c", @@ -169,7 +224,6 @@ template("lwip_target") { "${_lwip_root}/src/core/ipv6/ip6.c", "${_lwip_root}/src/core/ipv6/ip6_addr.c", "${_lwip_root}/src/core/ipv6/ip6_frag.c", - "${_lwip_root}/src/core/ipv6/ip6_route_table.c", "${_lwip_root}/src/core/ipv6/mld6.c", "${_lwip_root}/src/core/ipv6/nd6.c", ] @@ -180,7 +234,7 @@ template("lwip_target") { "${_lwip_root}/src/api/api_lib.c", "${_lwip_root}/src/api/api_msg.c", "${_lwip_root}/src/api/err.c", - "${_lwip_root}/src/api/if.c", + "${_lwip_root}/src/api/if_api.c", "${_lwip_root}/src/api/netbuf.c", "${_lwip_root}/src/api/netdb.c", "${_lwip_root}/src/api/netifapi.c", @@ -189,6 +243,13 @@ template("lwip_target") { ] } + if (lwip_bridge) { + sources += [ + "${_lwip_root}/src/netif/bridgeif.c", + "${_lwip_root}/src/netif/bridgeif_fdb.c", + ] + } + if (lwip_ethernet) { sources += [ "${_lwip_root}/src/netif/ethernet.c" ] } @@ -198,7 +259,21 @@ template("lwip_target") { } if (lwip_6lowpan) { - sources += [ "${_lwip_root}/src/netif/lowpan6.c" ] + sources += [ + "${_lwip_root}/src/netif/lowpan6.c", + "${_lwip_root}/src/netif/lowpan6_common.c", + ] + } + + if (lwip_6lowpan_ble) { + sources += [ + "${_lwip_root}/src/netif/lowpan6_ble.c", + "${_lwip_root}/src/netif/lowpan6_common.c", + ] + } + + if (lwip_zep) { + sources += [ "${_lwip_root}/src/netif/zepif.c" ] } if (defined(lwip_remove_configs)) { diff --git a/third_party/lwip/repo b/third_party/lwip/repo new file mode 160000 index 00000000000000..84fde1ebbfe35b --- /dev/null +++ b/third_party/lwip/repo @@ -0,0 +1 @@ +Subproject commit 84fde1ebbfe35b3125fc2d89b8a456cbacf148e9 diff --git a/third_party/lwip/repo/lwip.url b/third_party/lwip/repo/lwip.url deleted file mode 100644 index 81ebe7d7db9580..00000000000000 --- a/third_party/lwip/repo/lwip.url +++ /dev/null @@ -1 +0,0 @@ -https://git.savannah.nongnu.org/git/lwip.git diff --git a/third_party/lwip/repo/lwip.version b/third_party/lwip/repo/lwip.version deleted file mode 100644 index d804aa18bbd762..00000000000000 --- a/third_party/lwip/repo/lwip.version +++ /dev/null @@ -1 +0,0 @@ -92f23d6ca0971a32f2085b9480e738d34174417b diff --git a/third_party/lwip/repo/lwip/.gitattributes b/third_party/lwip/repo/lwip/.gitattributes deleted file mode 100644 index f34d43dc57185a..00000000000000 --- a/third_party/lwip/repo/lwip/.gitattributes +++ /dev/null @@ -1,4 +0,0 @@ -# These files are text and should be normalized -*.txt text -*.c text -*.h text diff --git a/third_party/lwip/repo/lwip/.gitignore b/third_party/lwip/repo/lwip/.gitignore deleted file mode 100644 index cb0ed5341f7474..00000000000000 --- a/third_party/lwip/repo/lwip/.gitignore +++ /dev/null @@ -1,18 +0,0 @@ -*.o -*.a -/doc/doxygen/output/html -/src/apps/snmp/LwipMibCompiler/CCodeGeneration/bin/ -/src/apps/snmp/LwipMibCompiler/CCodeGeneration/obj/ -/src/apps/snmp/LwipMibCompiler/LwipMibCompiler/bin/ -/src/apps/snmp/LwipMibCompiler/LwipMibCompiler/obj/ -/src/apps/snmp/LwipMibCompiler/MibViewer/bin/ -/src/apps/snmp/LwipMibCompiler/MibViewer/obj/ -/src/apps/snmp/LwipMibCompiler/LwipSnmpCodeGeneration/bin/ -/src/apps/snmp/LwipMibCompiler/LwipSnmpCodeGeneration/obj/ -/src/apps/snmp/LwipMibCompiler/SharpSnmpLib/bin/ -/src/apps/snmp/LwipMibCompiler/SharpSnmpLib/obj/ -/src/apps/snmp/LwipMibCompiler/LwipMibCompiler.userprefs -/src/apps/snmp/LwipMibCompiler/*.suo -/test/fuzz/output -/test/fuzz/lwip_fuzz -/test/fuzz/.depend diff --git a/third_party/lwip/repo/lwip/CHANGELOG b/third_party/lwip/repo/lwip/CHANGELOG deleted file mode 100644 index 306217fe5a642f..00000000000000 --- a/third_party/lwip/repo/lwip/CHANGELOG +++ /dev/null @@ -1,4295 +0,0 @@ -HISTORY - -(git master) - - * [Enter new changes just after this line - do not remove this line] - -(STABLE-2.0.3) - - ++ Bugfixes: - - 2017-09-11: Simon Goldschmidt - * tcp_in.c: fix bug #51937 (leaking tcp_pcbs on passive close with unacked data) - - 2017-08-02: Abroz Bizjak/Simon Goldschmidt - * multiple fixes in IPv4 reassembly (leading to corrupted datagrams received) - - 2017-03-30: Simon Goldschmidt - * dhcp.c: return ERR_VAL instead of asserting on offset-out-of-pbuf - - 2017-03-23: Dirk Ziegelmeier - * dhcp.h: fix bug #50618 (dhcp_remove_struct() macro does not work) - -(STABLE-2.0.2) - - ++ New features: - - 2017-02-10: Dirk Ziegelmeier - * Implement task #14367: Hooks need a better place to be defined: - We now have a #define for a header file name that is #included in every .c - file that provides hooks. - - 2017-02-10: Simon Goldschmidt - * tcp_close does not fail on memory error (instead, FIN is sent from tcp_tmr) - - ++ Bugfixes: - - 2017-03-08 - * tcp: do not keep sending SYNs when getting ACKs - - 2017-03-08: Joel Cunningham - * tcp: Initialize ssthresh to TCP_SND_BUF (bug #50476) - - 2017-03-01: Simon Goldschmidt - * httpd: LWIP_HTTPD_POST_MANUAL_WND: fixed double-free when httpd_post_data_recved - is called nested from httpd_post_receive_data() (bug #50424) - - 2017-02-28: David van Moolenbroek/Simon Goldschmidt - * tcp: fixed bug #50418: LWIP_EVENT_API: fix invalid calbacks for SYN_RCVD pcb - - 2017-02-17: Simon Goldschmidt - * dns: Improved DNS_LOCAL_HOSTLIST interface (bug #50325) - - 2017-02-16: Simon Goldschmidt - * LWIP_NETCONN_FULLDUPLEX: fixed shutdown during write (bug #50274) - - 2017-02-13: Simon Goldschmidt/Dirk Ziegelmeier - * For tiny targtes, LWIP_RAND is optional (fix compile time checks) - - 2017-02-10: Simon Goldschmidt - * tcp: Fixed bug #47485 (tcp_close() should not fail on memory error) by retrying - to send FIN from tcp_fasttmr - - 2017-02-09: Simon Goldschmidt - * sockets: Fixed bug #44032 (LWIP_NETCONN_FULLDUPLEX: select might work on - invalid/reused socket) by not allowing to reallocate a socket that has - "select_waiting != 0" - - 2017-02-09: Simon Goldschmidt - * httpd: Fixed bug #50059 (httpd LWIP_HTTPD_SUPPORT_11_KEEPALIVE vs. - LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED) - - 2017-02-08: Dirk Ziegelmeier - * Rename "IPv6 mapped IPv4 addresses" to their correct name from RFC4191: - "IPv4-mapped IPv6 address" - - 2017-02-08: Luc Revardel - * mld6.c: Fix bug #50220 (mld6_leavegroup does not send ICMP6_TYPE_MLD, even - if last reporter) - - 2017-02-08: David van Moolenbroek - * ip6.c: Patch #9250: fix source substitution in ip6_output_if() - - 2017-02-08: Simon Goldschmidt - * tcp_out.c: Fixed bug #50090 (last_unsent->oversize_left can become wrong value - in tcp_write error path) - - 2017-02-02: Dirk Ziegelmeier - * Fix bug #50206: UDP Netconn bind to IP6_ADDR_ANY fails - - 2017-01-18: Dirk Ziegelmeier - * Fix zero-copy RX, see bug bug #50064. PBUF_REFs were not supported as ARP requests. - - 2017-01-15: Axel Lin, Dirk Ziegelmeier - * minor bug fixes in mqtt - - 2017-01-11: Knut Andre Tidemann - * sockets/netconn: fix broken default ICMPv6 handling of checksums - -(STABLE-2.0.1) - - ++ New features: - - 2016-12-31: Simon Goldschmidt - * tcp.h/.c: added function tcp_listen_with_backlog_and_err() to get the error - reason when listening fails (bug #49861) - - 2016-12-20: Erik Andersen - * Add MQTT client - - 2016-12-14: Jan Breuer: - * opt.h, ndc.h/.c: add support for RDNSS option (as per RFC 6106) - - 2016-12-14: David van Moolenbroek - * opt.h, nd6.c: Added LWIP_HOOK_ND6_GET_GW() - - 2016-12-09: Dirk Ziegelmeier - * ip6_frag.c: Implemented support for LWIP_NETIF_TX_SINGLE_PBUF - - 2016-12-09: Simon Goldschmidt - * dns.c: added one-shot multicast DNS queries - - 2016-11-24: Ambroz Bizjak, David van Moolenbroek - * tcp_out.c: Optimize passing contiguous nocopy buffers to tcp_write (bug #46290) - - 2016-11-16: Dirk Ziegelmeier - * sockets.c: added support for IPv6 mapped IPv4 addresses - - ++ Bugfixes: - - 2016-12-16: Thomas Mueller - * api_lib.c: fixed race condition in return value of netconn_gethostbyname() - (and thus also lwip_gethostbyname/_r() and lwip_getaddrinfo()) - - 2016-12-15: David van Moolenbroek - * opt.h, tcp: added LWIP_HOOK_TCP_ISN() to implement less predictable initial - sequence numbers (see contrib/addons/tcp_isn for an example implementation) - - 2016-12-05: Dirk Ziegelmeier - * fixed compiling with IPv4 disabled (IPv6 only case) - - 2016-11-28: Simon Goldschmidt - * api_lib.c: fixed bug #49725 (send-timeout: netconn_write() can return - ERR_OK without all bytes being written) - - 2016-11-28: Ambroz Bizjak - * tcpi_in.c: fixed bug #49717 (window size in received SYN and SYN-ACK - assumed scaled) - - 2016-11-25: Simon Goldschmidt - * dhcp.c: fixed bug #49676 (Possible endless loop when parsing dhcp options) - - 2016-11-23: Dirk Ziegelmeier - * udp.c: fixed bug #49662: multicast traffic is now only received on a UDP PCB - (and therefore on a UDP socket/netconn) when the PCB is bound to IP_ADDR_ANY - - 2016-11-16: Dirk Ziegelmeier - * *: Fixed dual-stack behaviour, IPv6 mapped IPv4 support in socket API - - 2016-11-14: Joel Cunningham - * tcp_out.c: fixed bug #49533 (start persist timer when unsent seg can't fit - in window) - - 2016-11-16: Roberto Barbieri Carrera - * autoip.c: fixed bug #49610 (sometimes AutoIP fails to reuse the same address) - - 2016-11-11: Dirk Ziegelmeier - * sockets.c: fixed bug #49578 (dropping multicast membership does not work - with LWIP_SOCKET_OFFSET) - -(STABLE-2.0.0) - - ++ New features: - - 2016-07-27: Simon Goldschmidt - * opt.h, timeouts.h/.c: added LWIP_TIMERS_CUSTOM to override the default - implementation of timeouts - - 2016-07-xx: Dirk Ziegelmeier - * Large overhaul of doxygen documentation - - 2016-04-05: Simon Goldschmidt - * timers.h/.c: prepare for overriding current timeout implementation: all - stack-internal caclic timers are avaliable in the lwip_cyclic_timers array - - 2016-03-23: Simon Goldschmidt - * tcp: call accept-callback with ERR_MEM when allocating a pcb fails on - passive open to inform the application about this error - ATTENTION: applications have to handle NULL pcb in accept callback! - - 2016-02-22: Ivan Delamer - * Initial 6LoWPAN support - - 2016-02-XX to 2016-03-XX: Dirk Ziegelmeier - * Cleanup TCPIP thread sync methods in a way that it is possibe to use them - in arbitrary code that needs things to be done in TCPIP thread. Used to - decouple netconn, netif, ppp and 6LoWPAN from LWIP core. - - 2016-02-XX: Dirk Ziegelmeier - * Implement dual-stack support in RAW, UDP and TCP. Add new IP address - type IPADDR_ANY_TYPE for this. Netconn/Socket API: Dual-stack is - automatically supported when an IPv6 netconn/socket is created. - - 2015-12-26: Martin Hentschel and Dirk Ziegelmeier - * Rewrite SNMP agent. SNMPv2c + MIB compiler. - - 2015-11-12: Dirk Ziegelmeier - * Decouple SNMP stack from lwIP core and move stack to apps/ directory. - Breaking change: Users have to call snmp_init() now! - - 2015-11-12: Dirk Ziegelmeier - * Implement possibility to declare private memory pools. This is useful to - decouple some apps from the core (SNMP stack) or make contrib app usage - simpler (httpserver_raw) - - 2015-10-09: Simon Goldschmidt - * started to move "private" header files containing implementation details to - "lwip/priv/" include directory to seperate the API from the implementation. - - 2015-10-07: Simon Goldschmidt - * added sntp client as first "supported" application layer protocol implementation - added 'apps' folder - - 2015-09-30: Dirk Ziegelmeier - * snmp_structs.h, mib_structs.c, mib2.c: snmp: fixed ugly inheritance - implementation by aggregating the "base class" (struct mib_node) in all - derived node classes to get more type-safe code - - 2015-09-23: Simon Goldschmidt - * netif.h/.c, nd6.c: task #13729: Convert netif addresses (IPv4 & IPv6) to - ip_addr_t (so they can be used without conversion/temporary storage) - - 2015-09-08: Dirk Ziegelmeier - * snmp: Separate mib2 counter/table callbacks from snmp agent. This both cleans - up the code and should allow integration of a 3rd party agent/mib2. Simple - counters are kept in MIB2_STATS, tree/table change function prototypes moved to - snmp_mib2.h. - - 2015-09-03: Simon Goldschmidt - * opt.h, dns.h/.c: DNS/IPv6: added support for AAAA records - - 2015-09-01: Simon Goldschmidt - * task #12178: hardware checksum capabilities can be configured per netif - (use NETIF_SET_CHECKSUM_CTRL() in your netif's init function) - - 2015-08-30: Simon Goldschmidt - * PBUF_REF with "custom" pbufs is now supported for RX pbufs (see pcapif in - contrib for an example, LWIP_SUPPORT_CUSTOM_PBUF is required) - - 2015-08-30: Simon Goldschmidt - * support IPv4 source based routing: define LWIP_HOOK_IP4_ROUTE_SRC to point - to a routing function - - 2015-08-05: Simon Goldschmidt - * many files: allow multicast socket options IP_MULTICAST_TTL, IP_MULTICAST_IF - and IP_MULTICAST_LOOP to be used without IGMP - - 2015-04-24: Simon Goldschmidt - * dhcp.h/c, autoip.h/.c: added functions dhcp/autoip_supplied_address() to - check for the source of address assignment (replacement for NETIF_FLAG_DHCP) - - 2015-04-10: Simon Goldschmidt - * many files: task #13480: added LWIP_IPV4 define - IPv4 can be disabled, - leaving an IPv6-only stack - - 2015-04-09: Simon Goldschmidt - * nearly all files: task #12722 (improve IPv4/v6 address handling): renamed - ip_addr_t to ip4_addr_t, renamed ipX_addr_t to ip_addr_t and added IP - version; ip_addr_t is used for all generic IP addresses for the API, - ip(4/6)_addr_t are only used internally or when initializing netifs or when - calling version-related functions - - 2015-03-24: Simon Goldschmidt - * opt.h, ip4_addr.h, ip4.c, ip6.c: loopif is not required for loopback traffic - any more but passed through any netif (ENABLE_LOOPBACK has to be enabled) - - 2015-03-23: Simon Goldschmidt - * opt.h, etharp.c: with ETHARP_TABLE_MATCH_NETIF== 1, duplicate (Auto)-IP - addresses on multiple netifs should now be working correctly (if correctly - addressed by routing, that is) - - 2015-03-23: Simon Goldschmidt - * etharp.c: Stable etharp entries that are about to expire are now refreshed - using unicast to prevent unnecessary broadcast. Only if no answer is received - after 15 seconds, broadcast is used. - - 2015-03-06: Philip Gladstone - * netif.h/.c: patch #8359 (Provide utility function to add an IPv6 address to - an interface) - - 2015-03-05: Simon Goldschmidt - * netif.c, ip4.c, dhcp.c, autoip.c: fixed bug #37068 (netif up/down handling - is unclear): correclty separated administrative status of a netif (up/down) - from 'valid address' status - ATTENTION: netif_set_up() now always has to be called, even when dhcp/autoip - is used! - - 2015-02-26: patch by TabascoEye - * netif.c, udp.h/.c: fixed bug #40753 (re-bind UDP pcbs on change of IP address) - - 2015-02-22: chrysn, Simon Goldschmidt - * *.*: Changed nearly all functions taking 'ip(X)_addr_t' pointer to take - const pointers (changed user callbacks: raw_recv_fn, udp_recv_fn; changed - port callbacks: netif_output_fn, netif_igmp_mac_filter_fn) - - 2015-02-19: Ivan Delamer - * netif.h, dhcp.c: Removed unused netif flag for DHCP. The preferred way to evaluate - if DHCP is active is through netif->dhcp field. - - 2015-02-19: Ivan Delamer - * netif.h, slipif.c, ppp.c: Removed unused netif flag for point to point connections - - 2015-02-18: Simon Goldschmidt - * api_lib.c: fixed bug #37958 "netconn API doesn't handle correctly - connections half-closed by peer" - - 2015-02-18: Simon Goldschmidt - * tcp.c: tcp_alloc() prefers killing CLOSING/LAST_ACK over active connections - (see bug #39565) - - 2015-02-16: Claudius Zingerli, Sergio Caprile - * opt.h, dhcp.h/.c: patch #8361 "Add support for NTP option in DHCP" - - 2015-02-14: Simon Goldschmidt - * opt.h, snmp*: added support for write-access community and dedicated - community for sending traps - - 2015-02-13: Simon Goldschmidt - * opt.h, memp.c: added hook LWIP_HOOK_MEMP_AVAILABLE() to get informed when - a memp pool was empty and an item is now available - - 2015-02-13: Simon Goldschmidt - * opt.h, pbuf.h/.c, etharp.c: Added the option PBUF_LINK_ENCAPSULATION_HLEN to - allocate additional header space for TX on netifs requiring additional headers - - 2015-02-12: chrysn - * timers.h/.c: introduce sys_timeouts_sleeptime (returns the time left before - the next timeout is due, for NO_SYS==1) - - 2015-02-11: Nick van Ijzendoorn - * opt.h, sockets.h/c: patch #7702 "Include ability to increase the socket number - with defined offset" - - 2015-02-11: Frederick Baksik - * opt.h, def.h, others: patch #8423 "arch/perf.h" should be made an optional item - - 2015-02-11: Simon Goldschmidt - * api_msg.c, opt.h: started to implement fullduplex sockets/netconns - (note that this is highly unstable yet!) - - 2015-01-17: Simon Goldschmidt - * api: allow enabling socket API without (public) netconn API - netconn API is - still used by sockets, but keeping it private (static) should allow better - compiler optimizations - - 2015-01-16: Simon Goldschmidt - * tcp_in.c: fixed bug #20506 "Initial congestion window is very small" again - by implementing the calculation formula from RFC3390 - - 2014-12-10: Simon Goldschmidt - * api: added option LWIP_NETCONN_SEM_PER_THREAD to use a semaphore per thread - instead of using one per netconn and per select call - - 2014-12-08: Simon Goldschmidt - * ip6.h: fixed bug #43778: IPv6 header version not set on 16-bit platform - (macro IP6H_VTCFL_SET()) - - 2014-12-08: Simon Goldschmidt - * icmp.c, ip4.c, pbuf.c, udp.c, pbuf.h: task #11472 Support PBUF_REF for RX - (IPv6 and IPv4/v6 reassembly might not work yet) - - 2014-11-06: Simon Goldschmidt - * sockets.c/.h, init.c: lwip_socket_init() is not needed any more - -> compatibility define - - 2014-09-16: Simon Goldschmidt - * dns.c, opt.h: reduced ram usage by parsing DNS responses in place - - 2014-09-16: Simon Goldschmidt - * pbuf.h/.c: added pbuf_take_at() and pbuf_put_at() - - 2014-09-15: Simon Goldschmidt - * dns.c: added source port randomization to make the DNS client more robust - (see bug #43144) - - 2013-09-02: Simon Goldschmidt - * arch.h and many other files: added optional macros PACK_STRUCT_FLD_8() and - PACK_STRUCT_FLD_S() to prevent gcc 4 from warning about struct members that - do not need packing - - 2013-08-19: Simon Goldschmidt - * netif.h: bug #42998: made NETIF_MAX_HWADDR_LEN overridable for some special - networks - - 2013-03-17: Simon Goldschmidt (patch by Ghobad Emadi) - * opt.h, etharp.c: Added LWIP_HOOK_ETHARP_GET_GW to implement IPv4 routing with - multiple gateways - - 2013-04-20: Fatih Asici - * opt.h, etharp.h/.c: patch #7993: Added support for transmitting packets - with VLAN headers via hook function LWIP_HOOK_VLAN_SET and to check them - via hook function LWIP_HOOK_VLAN_CHECK - - 2014-02-20: Simon Goldschmidt (based on patch by Artem Pisarenko) - * patch #7885: modification of api modules to support FreeRTOS-MPU - (don't pass stack-pointers to other threads) - - 2014-02-05: Simon Goldschmidt (patch by "xtian" and "alex_ab") - * patch #6537/#7858: TCP window scaling support - - 2014-01-17: Jiri Engelthaler - * icmp, icmp6, opt.h: patch #8027: Completed HW checksuming for IPv4 and - IPv6 ICMP's - - 2012-08-22: Sylvain Rochet - * New PPP stack for lwIP, developed in ppp-new branch. - Based from pppd 2.4.5, released 2009-11-17, with huge changes to match - code size and memory requirements for embedded devices, including: - - Gluing together the previous low-level PPP code in lwIP to pppd 2.4.5, which - is more or less what pppd sys-* files are, so that we get something working - using the unix port. - - Merged some patchs from lwIP Git repository which add interesting features - or fix bugs. - - Merged some patchs from Debian pppd package which add interesting features - or fix bugs. - - Ported PPP timeout handling to the lwIP timers system - - Disabled all the PPP code using filesystem access, replaced in necessary cases - to configuration variables. - - Disabled all the PPP code forking processes. - - Removed IPX support, lwIP does not support IPX. - - Ported and improved random module from the previous PPP port. - - Removed samba TDB (file-driven database) usage, because it needs a filesystem. - - MS-CHAP required a DES implementation, we added the latest PolarSSL DES - implementation which is under a BSD-ish license. - - Also switched to PolarSSL MD4,MD5,SHA1 implementations, which are meant to be - used in embedded devices with reduced memory footprint. - - Removed PPP configuration file parsing support. - - Added macro definition EAP_SUPPORT to make EAP support optional. - - Added macro definition CHAP_SUPPORT to make CHAP support optional. - - Added macro definition MSCHAP_SUPPORT to make MSCHAP support optional. - - Added macro definition PAP_SUPPORT to make PAP support optional. - - Cleared all Linux syscall calls. - - Disabled demand support using a macro, so that it can be ported later. - - Disabled ECP support using a macro, so that it can be ported later. - - Disabled CCP support using a macro, so that it can be ported later. - - Disabled CBCP support using a macro, so that it can be ported later. - - Disabled LQR support using a macro, so that it can be ported later. - - Print packet debug feature optional, through PRINTPKT_SUPPORT - - Removed POSIX signal usage. - - Fully ported PPPoS code from the previous port. - - Fully ported PPPoE code from the previous port. - - Fully ported VJ compression protocol code from the previous port. - - Removed all malloc()/free() use from PPP, replaced by stack usage or PBUF. - - Disabled PPP server support using a macro, so that it can be ported later. - - Switched all PPP debug to lwIP debug system. - - Created PPP Control Block (PPP PCB), removed PPP unit integer everywhere, - removed all global variables everywhere, did everything necessary for - the PPP stack to support more than one PPP session (pppd only support - one session per process). - - Removed the statically allocated output buffer, now using PBUF. - - Improved structure size of all PPP modules, deep analyze of code to reduce - variables size to the bare minimum. Switched all boolean type (char type in - most architecture) to compiler generated bitfields. - - Added PPP IPv6 support, glued lwIP IPv6 support to PPP. - - Now using a persistent netif interface which can then be used in lwIP - functions requiring a netif. - - Now initializing PPP in lwip_init() function. - - Reworked completely the PPP state machine, so that we don't end up in - anymore in inconsistent state, especially with PPPoE. - - Improved the way we handle PPP reconnection after disconnect, cleaning - everything required so that we start the PPP connection again from a - clean state. - - Added PPP holdoff support, allow the lwIP user to wait a little bit before - reconnecting, prevents connection flood, especially when using PPPoL2TP. - - Added PPPoL2TP LAC support (a.k.a. UDP tunnels), adding a VPN client - feature to lwIP, L2TP being a widely used tunnel protocol. - - Switched all used PPP types to lwIP types (u8t, u16t, u32t, ...) - - Added PPP API "sequential" thread-safe API, based from NETIFAPI. - - 2011-07-21: Simon Goldschmidt - * sockets.c, opt.h: (bug #30185): added LWIP_FIONREAD_LINUXMODE that makes - ioctl/FIONREAD return the size of the next pending datagram. - - 2011-05-25: Simon Goldschmidt - * again nearly the whole stack, renamed ip.c to ip4.c, ip_addr.c to ip4_addr.c, - combined ipv4/ipv6 inet_chksum.c, added ip.h, ip_addr.h: Combined IPv4 - and IPv6 code where possible, added defines to access IPv4/IPv6 in non-IP - code so that the code is more readable. - - 2011-05-17: Patch by Ivan Delamer (only checked in by Simon Goldschmidt) - * nearly the whole stack: Finally, we got decent IPv6 support, big thanks to - Ivan! (this is work in progress: we're just post release anyway :-) - - - ++ Bugfixes: - - 2016-08-23: Simon Goldschmidt - * etharp: removed ETHARP_TRUST_IP_MAC since it is insecure and we don't need - it any more after implementing unicast ARP renewal towards arp entry timeout - - 2016-07-20: Simon Goldschmidt - * memp.h/.c: fixed bug #48442 (memp stats don't work for MEMP_MEM_MALLOC) - - 2016-07-21: Simon Goldschmidt (patch by Ambroz Bizjak) - * tcp_in.c, tcp_out.c: fixed bug #48543 (TCP sent callback may prematurely - report sent data when only part of a segment is acked) and don't include - SYN/FIN in snd_buf counter - - 2016-07-19: Simon Goldschmidt - * etharp.c: fixed bug #48477 (ARP input packet might update static entry) - - 2016-07-11: Simon Goldschmidt - * tcp_in.c: fixed bug #48476 (TCP sent callback called wrongly due to picking - up old pcb->acked - - 2016-06-30: Simon Goldschmidt (original patch by Fabian Koch) - * tcp_in.c: fixed bug #48170 (Vulnerable to TCP RST spoofing) - - 2016-05-20: Dirk Ziegelmeier - * sntp.h/.c: Fix return value of sntp_getserver() call to return a pointer - - 2016-04-05: Simon Goldschmidt (patch by Philip Gladstone) - * udp.c: patch #8358: allow more combinations of listening PCB for IPv6 - - 2016-04-05: Simon Goldschmidt - * netconn/socket API: fixed bug# 43739 (Accept not reporting errors about - aborted connections): netconn_accept() returns ERR_ABRT (sockets: ECONNABORTED) - for aborted connections, ERR_CLSD (sockets: EINVAL) if the listening netconn - is closed, which better seems to follow the standard. - - 2016-03-23: Florent Matignon - * dhcp.c: fixed bug #38203: DHCP options are not recorded in all DHCP ack messages - - 2016-03-22: Simon Goldschmidt - * tcp: changed accept handling to be done internally: the application does not - have to call tcp_accepted() any more. Instead, when delaying accept (e.g. sockets - do), call tcp_backlog_delayed()/tcp_backlog_accepted() (fixes bug #46696) - - 2016-03-22: Simon Goldschmidt - * dns.c: ignore dns response parsing errors, only abort resolving for correct - responses or error responses from correct server (bug #47459) - - 2016-03-17: Simon Goldschmidt - * api_msg.c: fixed bug #47448 (netconn/socket leak if RST is received during close) - - 2016-03-17: Joel Cunningham - * api_msg.c: don't fail closing a socket/netconn when failing to allocate the - FIN segment; blocking the calling thread for a while is better than risking - leaking a netconn/socket (see bug #46701) - - 2016-03-16: Joel Cunningham - * tcp_out.c: reset rto timer on fast retransmission - - 2016-03-16: Deomid Ryabkov - * tcp_out.c: fixed bug #46384 Segment size calculation bug with MSS != TCP_MSS - - 2016-03-05: Simon Goldschmidt - * err.h/.c, sockets.c: ERR_IF is not necessarily a fatal error - - 2015-11-19: fix by Kerem Hadimli - * sockets.c: fixed bug #46471: lwip_accept() leaks socket descriptors if new - netconn was already closed because of peer behavior - - 2015-11-12: fix by Valery Ushakov - * tcp_in.c: fixed bug #46365 tcp_accept_null() should call tcp_abort() - - 2015-10-02: Dirk Ziegelmeier/Simon Goldschmidt - * snmp: cleaned up snmp structs API (fixed race conditions from bug #46089, - reduce ram/rom usage of tables): incompatible change for private MIBs - - 2015-09-30: Simon Goldschmidt - * ip4_addr.c: fixed bug #46072: ip4addr_aton() does not check the number range - of all address parts - - 2015-08-28: Simon Goldschmidt - * tcp.c, tcp_in.c: fixed bug #44023: TCP ssthresh value is unclear: ssthresh - is set to the full send window for active open, too, and is updated once - after SYN to ensure the correct send window is used - - 2015-08-28: Simon Goldschmidt - * tcp: fixed bug #45559: Window scaling casts u32_t to u16_t without checks - - 2015-08-26: Simon Goldschmidt - * ip6_frag.h/.c: fixed bug bug #41009: IPv6 reassembly broken on 64-bit platforms: - define IPV6_FRAG_COPYHEADER==1 on these platforms to copy the IPv6 header - instead of referencing it, which gives more room for struct ip6_reass_helper - - 2015-08-25: Simon Goldschmidt - * sockets.c: fixed bug #45827: recvfrom: TCP window is updated with MSG_PEEK - - 2015-08-20: Manoj Kumar - * snmp_msg.h, msg_in.c: fixed bug #43790: Sending octet string of Length >255 - from SNMP agent - - 2015-08-19: Jens Nielsen - * icmp.c, ip4.c, tcp_in.c, udp.c, raw.c: fixed bug #45120: Broadcast & multiple - interfaces handling - - 2015-08-19: Simon Goldschmidt (patch by "Sandra") - * dns.c: fixed bug #45004: dns response without answer might be discarded - - 2015-08-18: Chrysn - * timers.c: patch #8704 fix sys_timeouts_sleeptime function - - 2015-07-01: Erik Ekman - * puf.c: fixed bug #45454 (pbuf_take_at() skips write and returns OK if offset - is at start of pbuf in chain) - - 2015-05-19: Simon Goldschmidt - * dhcp.h/.c: fixed bugs #45140 and #45141 (dhcp was not stopped correctly after - fixing bug #38204) - - 2015-03-21: Simon Goldschmidt (patch by Homyak) - * tcp_in.c: fixed bug #44766 (LWIP_WND_SCALE: tcphdr->wnd was not scaled in - two places) - - 2015-03-21: Simon Goldschmidt - * tcp_impl.h, tcp.c, tcp_in.c: fixed bug #41318 (Bad memory ref in tcp_input() - after tcp_close()) - - 2015-03-21: Simon Goldschmidt - * tcp_in.c: fixed bug #38468 (tcp_sent() not called on half-open connection for - data ACKed with the same ack as FIN) - - 2015-03-21: Simon Goldschmidt (patch by Christoffer Lind) - * dhcp.h/.c: fixed bug #38204 (DHCP lease time not handled correctly) - - 2015-03-20: Simon Goldschmidt - * dhcp.c: fixed bug #38714 (Missing option and client address in DHCPRELEASE message) - - 2015-03-19: Simon Goldschmidt - * api.h, tcpip.h, api_lib.c, api_msg.c: fixed race conditions in assigning - netconn->last_err (fixed bugs #38121 and #37676) - - 2015-03-09: Simon Goldschmidt - * ip4.c: fixed the IPv4 part of bug #43904 (ip_route() must detect linkup status) - - 2015-03-04: Simon Goldschmidt - * nd6.c: fixed bug #43784 (a host should send at least one Router Solicitation) - - 2015-03-04: Valery Ushakov - * ip6.c: fixed bug #41094 (Byte-order bug in IPv6 fragmentation header test) - - 2015-03-04: Zach Smith - * nd6.c: fixed bug #38153 (nd6_input() byte order issues) - - 2015-02-26: Simon Goldschmidt - * netif.c, tcp.h/.c: fixed bug #44378 (TCP connections are not aborted on netif - remove) - - 2015-02-25: Simon Goldschmidt - * ip4.c, etharp.c: fixed bug #40177 (System hangs when dealing with corrupted - packets), implemented task #12357 (Ensure that malicious packets don't - assert-fail): improved some pbuf_header calls to not assert-fail. - - 2015-02-25: patch by Joel Cunningham - * udp.h/.c, sockets.c: fixed bug #43028 (IP_MULTICAST_TTL affects unicast - datagrams) - - 2015-02-25: patch by Greg Renda - * ip4_frag.c: fixed bug #38210 (ip reassembly while remove oldest datagram) - - 2015-02-25: Simon Goldschmidt - * sockets.c: fixed bug #38165 (socket with mulicast): ensure igmp membership - are dropped when socket (not netconn!) is closed. - - 2015-02-25: Simon Goldschmidt - * ip4.h/.c, udp.c: fixed bug #38061 (wrong multicast routing in IPv4) by - adding an optional default netif for multicast routing - - 2015-02-25: Simon Goldschmidt - * netconn API: fixed that netconn_connect still used message passing for - LWIP_TCPIP_CORE_LOCKING==1 - - 2015-02-22: patch by Jens Nielsen - * icmp.c: fixed bug #38803 (Source address in broadcast ping reply) - - 2015-02-22: Simon Goldschmidt - * udp.h, sockets.c: added proper accessor functions for pcb->multicast_ip - (previously used by get/setsockopt only) - - 2015-02-18: Simon Goldschmidt - * sockets.c: Fixed select not reporting received FIN as 'readable' in certain - rare cases (bug #43779: select(), close(), and TCP retransmission error) - - 2015-02-17: Simon Goldschmidt - * err.h, sockets.c, api_msg.c: fixed bug #38853 "connect() use a wrong errno": - return ERR_ALREADY/EALRADY during connect, ERR_ISCONN/EISCONN when already - connected - - 2015-02-17: Simon Goldschmidt - * tcp_impl.h, tcp_out.c, tcp.c, api_msg.c: fixed bug #37614 "Errors from - ipX_output are not processed". Now tcp_output(_segment) checks for the return - value of ipX_output and does not try to send more on error. A netif driver - can call tcp_txnow() (from tcpip_thread!) to try to send again if TX buffers - are available again. - - 2015-02-14: patches by Freddie Chopin - * snmp*: made community writable, fixed some const pointers - - 2015-02-13: Simon Goldschmidt - * msg_in.c: fixed bug #22070 "MIB_OBJECT_WRITE_ONLY not implemented in SNMP" - - 2015-02-12: Simon Goldschmidt - * ip.h, ip4.c, ip6.c: fixed bug #36403 "ip4_input() and ip6_input() always pass - inp to higher layers": now the accepting netif is passed up, but the input - netif is available through ip_current_input_netif() if required. - - 2015-02-11: patch by hichard - * tcpip.c: fixed bug #43094 "The function tcpip_input() forget to handle IPv6" - - 2015-02-10: Simon Goldschmidt - * netconn API: fixed that netconn_close/netconn_delete still used message passing - for LWIP_TCPIP_CORE_LOCKING==1 - - 2015-02-10: Simon Goldschmidt - * netconn/socket api: fixed bug #44225 "closing TCP socket should time out - eventually", implemented task #6930 "Implement SO_LINGER": closing TCP sockets - times out after 20 seconds or after the configured SND_TIMEOUT or depending - on the linger settings. - - 2015-01-27: Simon Goldschmidt - * api_msg.c: fixed that SHUT_RD followed by SHUT_WR was different to SHUT_RDWR, - fixed return value of lwip_netconn_do_close on unconnected netconns - - 2015-01-17: Simon Goldschmidt - * sockets.c: fixed bug #43361 select() crashes with stale FDs - - 2015-01-17: Simon Goldschmidt - * sockets.c/.h, memp_std.h: fixed bug #40788 "lwip_setsockopt_internal() crashes" - by rewriting set/getsockopt functions to combine checks with the actual code - and add more NULL checks; this also fixes that CORE_LOCKING used message - passing for set/getsockopt. - - 2014-12-19: Simon Goldschmidt - * opt.h, dhcp.h/.c: prevent dhcp from starting when netif link is down (only - when LWIP_DHCP_CHECK_LINK_UP==1, which is disabled by default for - compatibility reasons) - - 2014-12-17: Simon Goldschmidt - * tcp_out.c: fixed bug #43840 Checksum error for TCP_CHECKSUM_ON_COPY==1 for - no-copy data with odd length - - 2014-12-10: Simon Goldschmidt - * sockets.c, tcp.c, others: fixed bug #43797 set/getsockopt: SO_SNDTIMEO/SO_RCVTIMEO - take int as option but should take timeval (LWIP_SO_SNDRCVTIMEO_STANDARD==0 can - be used to revert to the old 'winsock' style behaviour) - Fixed implementation of SO_ACCEPTCONN to just look at the pcb state - - 2014-12-09: Simon Goldschmidt - * ip4.c: fixed bug #43596 IGMP queries from 0.0.0.0 are discarded - - 2014-10-21: Simon Goldschmidt (patch by Joel Cunningham and Albert Huitsing) - * sockts.c: fixed bugs #41495 Possible threading issue in select() and #43278 - event_callback() handle context switch when calling sys_sem_signal() - - 2014-10-21: Simon Goldschmidt - * api_msg.c: fixed bug #38219 Assert on TCP netconn_write with sndtimeout set - - 2014-09-16: Kevin Cernekee - * dns.c: patch #8480 Fix handling of dns_seqno wraparound - - 2014-09-16: Simon Goldschmidt - * tcp_out.c: fixed bug #43192 tcp_enqueue_flags() should not check TCP_SND_QUEUELEN - when sending FIN - - 2014-09-03: Simon Goldschmidt - * msg_in.c: fixed bug #39355 SNMP Memory Leak in case of error - - 2014-09-02: Simon Goldschmidt - * err.h/.c, sockets.c, api_msg.c: fixed bug #43110 call getpeername() before - listen() will cause a error - - 2014-09-02: Simon Goldschmidt - * sockets.c: fixed bug #42117 lwip_fcntl does not set errno - - 2014-09-02: Simon Goldschmidt - * tcp.c: fixed bug #42299 tcp_abort() leaves freed pcb on tcp_bound_pcbs list - - 2014-08-20: Simon Goldschmidt - * dns.c: fixed bug #42987 lwIP is vulnerable to DNS cache poisoning due to - non-randomized TXIDs - - 2014-06-03: Simon Goldschmidt - * tcp_impl.h, tcp_in.c: fixed bug #37969 SYN packet dropped as short packet in - tcp_input function - - 2014-05-20: Simon Goldschmidt - * tcp_out.c: fixed bug #37184 tcp_write problem for pcbs in the SYN_SENT state - - 2014-05-19: Simon Goldschmidt - * *.h: Fixed bug #35874 reserved identifier violation (removed leading underscores - from header include guards) - - 2014-04-08: Simon Goldschmidt - * tcp.c: Fixed bug #36167 tcp server crash when client closes (maximum window) - - 2014-04-06: Simon Goldschmidt - * tcp_in.c: Fixed bug #36210 lwIP does not elicit an empty ACK when received - unacceptable ACK - - 2014-04-06: Simon Goldschmidt - * dhcp.c, ip4.c/.h, ip6.c/.h, udp.c/.h, ip.h: Fixed bug #41787 DHCP Discovery - is invalid when an IP is set to thet netif. - - 2014-03-14: Simon Goldschmidt - * tcp_out.c: Fixed bug #36153 TCP Cheksum error if LWIP_CHECKSUM_ON_COPY=1 - - 2014-03-11: Simon Goldschmidt (patch by Mason) - * opt.h, sockets.c: fixed bug #35928 BSD sockets functions must set errno for - POSIX-compliance - - 2014-02-27: Simon Goldschmidt - * dhcp.c: fixed bug #40303 DHCP xid renewed when sending a DHCPREQUEST - - 2014-02-27: Simon Goldschmidt - * raw.c: fixed bug #41680 raw socket can not receive IPv6 packet when - IP_SOF_BROADCAST_RECV==1 - - 2014-02-27: Simon Goldschmidt - * api_msg.c, sockets.c: fixed bug #38404 getpeeraddr returns success on - unconnected/listening TCP sockets - - 2014-02-27: Simon Goldschmidt - * sockets.c: fixed bug #41729 Some socket functions return Exyz instead of -1 - - 2014-02-25: Simon Goldschmidt - * ip4.c: fixed bug #39514 ip_route() may return an IPv6-only interface - - 2014-02-25: Simon Goldschmidt, patch by Fatih Asici - * pbuf.c: fixed bug #39356 Wrong increment in pbuf_memfind() - - 2014-02-25: Simon Goldschmidt - * netif.c/.h, udp.c: fixed bug #39225 udp.c uses netif_matches_ip6_addr() incorrectly; - renamed function netif_matches_ip6_addr() to netif_get_ip6_addr_match() - - 2014-02-25: Simon Goldschmidt - * igmp.c: fixed bug #39145 IGMP membership report for 224.0.0.1 - - 2014-02-22: Simon Goldschmidt (patch by Amir Shalem) - * etharp.c, opt.h: fixed bug #34681 Limit ARP queue length by ARP_QUEUE_LEN (=3) - - 2014-02-22: Simon Goldschmidt (patch by Amir Shalem) - * etharp.h/.c: fixed bug #34682 Limit ARP request flood for unresolved entry - - 2014-02-20: Simon Goldschmidt - * tcp_out.c: fixed bug #39683 Assertion "seg->tcphdr not aligned" failed with - MEM_ALIGNMENT = 8 - - 2014-02-20: Simon Goldschmidt - * sockets.c: fixed bug #39882 No function shall set errno to 0 - - 2014-02-20: Simon Goldschmidt - * mib_structs.c: fixed bug #40050 SNMP problem with MIB arrays > 255 - - 2014-02-20: Simon Goldschmidt - * api.h, sockets.c: fixed bug #41499 netconn::recv_avail can overflow - - 2014-01-08: Stathis Voukelatos - * memp_std.h: patch #7928 Fixed size calculation in MALLOC memory pool - creation macro - - 2014-01-18: Brian Fahs - * tcp_out.c: patch #8237: tcp_rexmit_rto fails to update pcb->unsent_oversize - when necessary - - 2014-01-17: Grant Erickson, Jay Logue, Simon Goldschmidt - * ipv6.c, netif.c: patch #7913 Enable Support for IPv6 Loopback - - 2014-01-16: Stathis Voukelatos - * netif.c: patch #7902 Fixed netif_poll() operation when LWIP_LOOPBACK_MAX_PBUFS > 0 - - 2014-01-14: "Freddie Chopin" - * snmp.h, mib2.c: fixed constness and spelling of sysdescr - - 2014-01-14: Simon Goldschmidt (patch by Thomas Faber) - * tcpip.c: patch #8241: Fix implicit declaration of ip_input with - LWIP_TCPIP_CORE_LOCKING_INPUT disabled - - 2014-01-14: chrysn - * timers.c: patch #8244 make timeouts usable reliably from outside of the - timeout routine - - 2014-01-10: Simon Goldschmidt - * ip_frag.c, ip6_frag.c: fixed bug #41041 Potential use-after-free in IPv6 reassembly - - 2014-01-10: Simon Goldschmidt - * memp.c: fixed bug #41188 Alignment error in memp_init() when MEMP_SEPARATE_POOLS==1 - - 2014-01-10: Simon Goldschmidt - * tcp.c: fixed bug #39898 tcp_fasttmr() possible lock due to infinte queue process loop - - 2013-06-29: Simon Goldschmidt - * inet.h, sockets.h: partially fixed bug #37585: IPv6 compatibility (in socket structs) - - 2013-06-29: Simon Goldschmidt - * inet6.h: bug #37585/task #12600: fixed struct in6_addr.s6_addr to conform to spec - - 2013-04-24: patch by Liam - * api_msg.c: patch #8008 Fix a potential null pointer dereference in assert - - 2013-04-24: Simon Goldschmidt - * igmp.c: fixed possible division by zero - - 2013-04-24: Simon Goldschmidt - * ip6.h, some ipv6 C files: fixed bug #38526 Coverity: Recursive Header Inclusion in ip6.h - - 2013-04-24: Simon Goldschmidt (patch by Emil Ljungdahl): - * netif.c: fixed bug #38586 netif_loop_output() "deadlocks" - - 2013-01-15: Simon Goldschmidt - * ip4.c: fixed bug #37665 ip_canforward operates on address in wrong byte order - - 2013-01-15: Simon Goldschmidt - * pbuf.h: fixed bug #38097 pbuf_free_ooseq() warning - - 2013-01-14: Simon Goldschmidt - * dns.c: fixed bug #37705 Possible memory corruption in DNS query - - 2013-01-11: Simon Goldschmidt - * raw.c: fixed bug #38066 Raw pcbs can alter packet without eating it - - 2012-08-22: Simon Goldschmidt - * memp.c: fixed bug #37166: memp_sanity check loops itself - - 2012-08-13: Simon Goldschmidt - * dhcp.c: fixed bug #36645: Calling dhcp_release before dhcp_start - dereferences NULL - - 2012-08-13: Simon Goldschmidt - * msg_out.c: fixed bug #36840 snmp_send_trap() NULL de-reference if traps - configured but no interfaces available - - 2012-08-13: Simon Goldschmidt - * dns.c: fixed bug #36899 DNS TTL 0 is cached for a long time - - 2012-05-11: Simon Goldschmidt (patch by Marty) - * memp.c: fixed bug #36412: memp.c does not compile when - MEMP_OVERFLOW_CHECK > zero and MEMP_SEPARATE_POOLS == 1 - - 2012-05-03: Simon Goldschmidt (patch by Sylvain Rochet) - * ppp.c: fixed bug #36283 (PPP struct used on header size computation and - not packed) - - 2012-05-03: Simon Goldschmidt (patch by David Empson) - * ppp.c: fixed bug #36388 (PPP: checksum-only in last pbuf leads to pbuf with - zero length) - - 2012-03-25: Simon Goldschmidt - * api_msg.c: Fixed bug #35817: do_connect() invalidly signals op_completed - for UDP/RAW with LWIP_TCPIP_CORE_LOCKING==1 - - 2012-03-25: Simon Goldschmidt - * api_msg.h, api_lib.c, api_msg.c, netifapi.c: fixed bug #35931: Name space - pollution in api_msg.c and netifapi.c - - 2011-08-24: Simon Goldschmidt - * inet6.h: fixed bug #34124 struct in6_addr does not conform to the standard - - - -(STABLE-1.4.1) - - ++ New features: - - 2012-03-25: Simon Goldschmidt (idea by Mason) - * posix/*: added posix-compatibility include files posix/netdb.h and posix/sys/socket.h - which are a simple wrapper to the correct lwIP include files. - - 2012-01-16: Simon Goldschmidt - * opt.h, icmp.c: Added option CHECKSUM_GEN_ICMP - - 2011-12-17: Simon Goldschmidt - * ip.h: implemented API functions to access so_options of IP pcbs (UDP, TCP, RAW) - (fixes bug #35061) - - 2011-09-27: Simon Goldschmidt - * opt.h, tcp.c, tcp_in.c: Implemented limiting data on ooseq queue (task #9989) - (define TCP_OOSEQ_MAX_BYTES / TCP_OOSEQ_MAX_PBUFS in lwipopts.h) - - 2011-09-21: Simon Goldschmidt - * opt.h, api.h, api_lib.c, api_msg.h/.c, sockets.c: Implemented timeout on - send (TCP only, bug #33820) - - 2011-09-21: Simon Goldschmidt - * init.c: Converted runtime-sanity-checks into compile-time checks that can - be disabled (since runtime checks can often not be seen on embedded targets) - - 2011-09-11: Simon Goldschmidt - * ppp.h, ppp_impl.h: splitted ppp.h to an internal and external header file - to get a clear separation of which functions an application or port may use - (task #11281) - - 2011-09-11: Simon Goldschmidt - * opt.h, tcp_impl.h, tcp.c, udp.h/.c: Added a config option to randomize - initial local TCP/UDP ports (so that different port ranges are used after - a reboot; bug #33818; this one added tcp_init/udp_init functions again) - - 2011-09-03: Simon Goldschmidt - * dhcp.c: DHCP uses LWIP_RAND() for xid's (bug #30302) - - 2011-08-24: Simon Goldschmidt - * opt.h, netif.h/.c: added netif remove callback (bug #32397) - - 2011-07-26: Simon Goldschmidt - * etharp.c: ETHARP_SUPPORT_VLAN: add support for an external VLAN filter - function instead of only checking for one VLAN (define ETHARP_VLAN_CHECK_FN) - - 2011-07-21: Simon Goldschmidt (patch by hanhui) - * ip4.c, etharp.c, pbuf.h: bug #33634 ip_forward() have a faulty behaviour: - Added pbuf flags to mark incoming packets as link-layer broadcast/multicast. - Also added code to allow ip_forward() to forward non-broadcast packets to - the input netif (set IP_FORWARD_ALLOW_TX_ON_RX_NETIF==1). - - 2011-06-26: Simon Goldschmidt (patch by Cameron Gutman) - * tcp.c, tcp_out.c: bug #33604: added some more asserts to check that - pcb->state != LISTEN - - 2011-05-14: Simon Goldschmidt (patch by Stéphane Lesage) - * tcpip.c/.h: patch #7449 allow tcpip callback from interrupt with static - memory message - - - ++ Bugfixes: - - 2012-09-26: Simon Goldschmidt - * api_msg.c: fixed bug #37405 'err_tcp()' uses already freed 'netconn' object - - 2012-09-26: patch by Henrik Persson - * dhcp.c: patch #7843 Fix corner case with dhcp timeouts - - 2012-09-26: patch by Henrik Persson - * dhcp.c: patch #7840 Segfault in dhcp_parse_reply if no end marker in dhcp packet - - 2012-08-22: Simon Goldschmidt - * memp.c: fixed bug #37166: memp_sanity check loops itself - - 2012-05-08: Simon Goldschmidt - * tcp_out.c: fixed bug: #36380 unsent_oversize mismatch in 1.4.1RC1 (this was - a debug-check issue only) - - 2012-03-27: Simon Goldschmidt - * vj.c: fixed bug #35756 header length calculation problem in ppp/vj.c - - 2012-03-27: Simon Goldschmidt (patch by Mason) - * tcp_out.c: fixed bug #35945: SYN packet should provide the recv MSS not the - send MSS - - 2012-03-22: Simon Goldschmidt - * ip4.c: fixed bug #35927: missing refragmentaion in ip_forward - - 2012-03-20: Simon Goldschmidt (patch by Mason) - * netdb.c: fixed bug #35907: lwip_gethostbyname_r returns an invalid h_addr_list - - 2012-03-12: Simon Goldschmidt (patch by Bostjan Meglic) - * ppp.c: fixed bug #35809: PPP GetMask(): Compiler warning on big endian, - possible bug on little endian system - - 2012-02-23: Simon Goldschmidt - * etharp.c: fixed bug #35595: Impossible to send broadcast without a gateway - (introduced when fixing bug# 33551) - - 2012-02-16: Simon Goldschmidt - * ppp.c: fixed pbuf leak when PPP session is aborted through pppSigHUP() - (bug #35541: PPP Memory Leak) - - 2012-02-16: Simon Goldschmidt - * etharp.c: fixed bug #35531: Impossible to send multicast without a gateway - (introduced when fixing bug# 33551) - - 2012-02-16: Simon Goldschmidt (patch by Stéphane Lesage) - * msg_in.c, msg_out.c: fixed bug #35536 SNMP: error too big response is malformed - - 2012-02-15: Simon Goldschmidt - * init.c: fixed bug #35537: MEMP_NUM_* sanity checks should be disabled with - MEMP_MEM_MALLOC==1 - - 2012-02-12: Simon Goldschmidt - * tcp.h, tcp_in.c, tcp_out.c: partly fixed bug #25882: TCP hangs on - MSS > pcb->snd_wnd (by not creating segments bigger than half the window) - - 2012-02-11: Simon Goldschmidt - * tcp.c: fixed bug #35435: No pcb state check before adding it to time-wait - queue while closing - - 2012-01-22: Simon Goldschmidt - * tcp.c, tcp_in.c: fixed bug #35305: pcb may be freed too early on shutdown(WR) - - 2012-01-21: Simon Goldschmidt - * tcp.c: fixed bug #34636: FIN_WAIT_2 - Incorrect shutdown of TCP pcb - - 2012-01-20: Simon Goldschmidt - * dhcp.c: fixed bug #35151: DHCP asserts on incoming option lengths - - 2012-01-20: Simon Goldschmidt - * pbuf.c: fixed bug #35291: NULL pointer in pbuf_copy - - 2011-11-25: Simon Goldschmidt - * tcp.h/.c, tcp_impl.h, tcp_in.c: fixed bug #31177: tcp timers can corrupt - tcp_active_pcbs in some cases - - 2011-11-23: Simon Goldschmidt - * sys.c: fixed bug #34884: sys_msleep() body needs to be surrounded with - '#ifndef sys_msleep' - - 2011-11-22: Simon Goldschmidt - * netif.c, etharp.h/.c: fixed bug #34684: Clear the arp table cache when - netif is brought down - - 2011-10-28: Simon Goldschmidt - * tcp_in.c: fixed bug #34638: Dead code in tcp_receive - pcb->dupacks - - 2011-10-23: Simon Goldschmidt - * mem.c: fixed bug #34429: possible memory corruption with - LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT set to 1 - - 2011-10-18: Simon Goldschmidt - * arch.h, netdb.c: fixed bug #34592: lwip_gethostbyname_r uses nonstandard - error value - - 2011-10-18: Simon Goldschmidt - * opt.h: fixed default values of TCP_SNDLOWAT and TCP_SNDQUEUELOWAT for small - windows (bug #34176 select after non-blocking send times out) - - 2011-10-18: Simon Goldschmidt - * tcp_impl.h, tcp_out.c: fixed bug #34587: TCP_BUILD_MSS_OPTION doesn't - consider netif->mtu, causes slow network - - 2011-10-18: Simon Goldschmidt - * sockets.c: fixed bug #34581 missing parentheses in udplite sockets code - - 2011-10-18: Simon Goldschmidt - * sockets.h: fixed bug #34580 fcntl() is missing in LWIP_COMPAT_SOCKETS - - 2011-10-17: Simon Goldschmidt - * api_msg.c: fixed bug #34569: shutdown(SHUT_WR) crashes netconn/socket api - - 2011-10-13: Simon Goldschmidt - * tcp_in.c, tcp_out.c: fixed bug #34517 (persist timer is started although no - zero window is received) by starting the persist timer when a zero window is - received, not when we have more data queued for sending than fits into the - window - - 2011-10-13: Simon Goldschmidt - * def.h, timers.c: fixed bug #34541: LWIP_U32_DIFF is unnecessarily complex - - 2011-10-13: Simon Goldschmidt - * sockets.c, api_lib.c: fixed bug #34540: compiler error when CORE_LOCKING is - used and not all protocols are enabled - - 2011-10-12: Simon Goldschmidt - * pbuf.c: fixed bug #34534: Error in sending fragmented IP if MEM_ALIGNMENT > 4 - - 2011-10-09: Simon Goldschmidt - * tcp_out.c: fixed bug #34426: tcp_zero_window_probe() transmits incorrect - byte value when pcb->unacked != NULL - - 2011-10-09: Simon Goldschmidt - * ip4.c: fixed bug #34447 LWIP_IP_ACCEPT_UDP_PORT(dst_port) wrong - - 2011-09-27: Simon Goldschmidt - * tcp_in.c, tcp_out.c: Reset pcb->unsent_oversize in 2 more places... - - 2011-09-27: Simon Goldschmidt - * tcp_in.c: fixed bug #28288: Data after FIN in oos queue - - 2011-09-27: Simon Goldschmidt - * dhcp.c: fixed bug #34406 dhcp_option_hostname() can overflow the pbuf - - 2011-09-24: Simon Goldschmidt - * mem.h: fixed bug #34377 MEM_SIZE_F is not defined if MEM_LIBC_MALLOC==1 - - 2011-09-23: Simon Goldschmidt - * pbuf.h, tcp.c, tcp_in.c: fixed bug #33871: rejecting TCP_EVENT_RECV() for - the last packet including FIN can lose data - - 2011-09-22: Simon Goldschmidt - * tcp_impl.h: fixed bug #34355: nagle does not take snd_buf/snd_queuelen into - account - - 2011-09-21: Simon Goldschmidt - * opt.h: fixed default value of TCP_SND_BUF to not violate the sanity checks - in init.c - - 2011-09-20: Simon Goldschmidt - * timers.c: fixed bug #34337 (possible NULL pointer in sys_check_timeouts) - - 2011-09-11: Simon Goldschmidt - * tcp_out.c: use pcb->mss instead of TCP_MSS for preallocate mss-sized pbufs - (bug #34019) - - 2011-09-09: Simon Goldschmidt - * udp.c: fixed bug #34072: UDP broadcast is received from wrong UDP pcb if - udp port matches - - 2011-09-03: Simon Goldschmidt - * tcp_in.c: fixed bug #33952 PUSH flag in incoming packet is lost when packet - is aggregated and sent to application - - 2011-09-01: Simon Goldschmidt - * opt.h: fixed bug #31809 LWIP_EVENT_API in opts.h is inconsistent compared - to other options - - 2011-09-01: Simon Goldschmidt - * tcp_in.c: fixed bug #34111 RST for ACK to listening pcb has wrong seqno - - 2011-08-24: Simon Goldschmidt - * api_msg.c, sockets.c: fixed bug #33956 Wrong error returned when calling - accept() on UDP connections - - 2011-08-24: Simon Goldschmidt - * sockets.h: fixed bug #34057 socklen_t should be a typedef - - 2011-08-24: Simon Goldschmidt - * pbuf.c: fixed bug #34112 Odd check in pbuf_alloced_custom (typo) - - 2011-08-24: Simon Goldschmidt - * dhcp.c: fixed bug #34122 dhcp: hostname can overflow - - 2011-08-24: Simon Goldschmidt - * netif.c: fixed bug #34121 netif_add/netif_set_ipaddr fail on NULL ipaddr - - 2011-08-22: Simon Goldschmidt - * tcp_out.c: fixed bug #33962 TF_FIN not always set after FIN is sent. (This - merely prevents nagle from not transmitting fast after closing.) - - 2011-07-22: Simon Goldschmidt - * api_lib.c, api_msg.c, sockets.c, api.h: fixed bug #31084 (socket API returns - always EMSGSIZE on non-blocking sockets if data size > send buffers) -> now - lwip_send() sends as much as possible for non-blocking sockets - - 2011-07-22: Simon Goldschmidt - * pbuf.c/.h, timers.c: freeing ooseq pbufs when the pbuf pool is empty implemented - for NO_SYS==1: when not using sys_check_timeouts(), call PBUF_CHECK_FREE_OOSEQ() - at regular intervals from main level. - - 2011-07-21: Simon Goldschmidt - * etharp.c: fixed bug #33551 (ARP entries may time out although in use) by - sending an ARP request when an ARP entry is used in the last minute before - it would time out. - - 2011-07-04: Simon Goldschmidt - * sys_arch.txt: Fixed documentation after changing sys arch prototypes for 1.4.0. - - 2011-06-26: Simon Goldschmidt - * tcp.c: fixed bug #31723 (tcp_kill_prio() kills pcbs with the same prio) by - updating its documentation only. - - 2011-06-26: Simon Goldschmidt - * mem.c: fixed bug #33545: With MEM_USE_POOLS==1, mem_malloc can return an - unaligned pointer. - - 2011-06-26: Simon Goldschmidt - * mem.c: fixed bug #33544 "warning in mem.c in lwip 1.4.0 with NO_SYS=1" - - 2011-05-25: Simon Goldschmidt - * tcp.c: fixed bug #33398 (pointless conversion when checking TCP port range) - - - -(STABLE-1.4.0) - - ++ New features: - - 2011-03-27: Simon Goldschmidt - * tcp_impl.h, tcp_in.c, tcp_out.c: Removed 'dataptr' from 'struct tcp_seg' and - calculate it in tcp_zero_window_probe (the only place where it was used). - - 2010-11-21: Simon Goldschmidt - * dhcp.c/.h: Added a function to deallocate the struct dhcp from a netif - (fixes bug #31525). - - 2010-07-12: Simon Goldschmidt (patch by Stephane Lesage) - * ip.c, udp.c/.h, pbuf.h, sockets.c: task #10495: Added support for - IP_MULTICAST_LOOP at socket- and raw-API level. - - 2010-06-16: Simon Goldschmidt - * ip.c: Added an optional define (LWIP_IP_ACCEPT_UDP_PORT) that can allow - link-layer-addressed UDP traffic to be received while a netif is down (just - like DHCP during configuration) - - 2010-05-22: Simon Goldschmidt - * many many files: bug #27352: removed packing from ip_addr_t, the packed - version is now only used in protocol headers. Added global storage for - current src/dest IP address while in input functions. - - 2010-05-16: Simon Goldschmidt - * def.h: task #10391: Add preprocessor-macros for compile-time htonl - calculation (and use them throughout the stack where applicable) - - 2010-05-16: Simon Goldschmidt - * opt.h, memp_std.h, memp.c, ppp_oe.h/.c: PPPoE now uses its own MEMP pool - instead of the heap (moved struct pppoe_softc from ppp_oe.c to ppp_oe.h) - - 2010-05-16: Simon Goldschmidt - * opt.h, memp_std.h, dns.h/.c: DNS_LOCAL_HOSTLIST_IS_DYNAMIC uses its own - MEMP pool instead of the heap - - 2010-05-13: Simon Goldschmidt - * tcp.c, udp.c: task #6995: Implement SO_REUSEADDR (correctly), added - new option SO_REUSE_RXTOALL to pass received UDP broadcast/multicast - packets to more than one pcb. - - 2010-05-02: Simon Goldschmidt - * netbuf.h/.c, sockets.c, api_msg.c: use checksum-on-copy for sending - UDP data for LWIP_NETIF_TX_SINGLE_PBUF==1 - - 2010-04-30: Simon Goldschmidt - * udp.h/.c, pbuf.h/.c: task #6849: added udp_send(_to/_if) functions that - take a precalculated checksum, added pbuf_fill_chksum() to copy data - into a pbuf and at the same time calculating the checksum for that data - - 2010-04-29: Simon Goldschmidt - * ip_addr.h, etharp.h/.c, autoip.c: Create overridable macros for copying - 2-byte-aligned IP addresses and MAC addresses - - 2010-04-28: Patch by Bill Auerbach - * ip.c: Inline generating IP checksum to save a function call - - 2010-04-14: Simon Goldschmidt - * tcpip.h/.c, timers.c: Added an overridable define to get informed when the - tcpip_thread processes messages or timeouts to implement a watchdog. - - 2010-03-28: Simon Goldschmidt - * ip_frag.c: create a new (contiguous) PBUF_RAM for every outgoing - fragment if LWIP_NETIF_TX_SINGLE_PBUF==1 - - 2010-03-27: Simon Goldschmidt - * etharp.c: Speedup TX by moving code from find_entry to etharp_output/ - etharp_query to prevent unnecessary function calls (inspired by - patch #7135). - - 2010-03-20: Simon Goldschmidt - * opt.h, tcpip.c/.h: Added an option to disable tcpip_(un)timeout code - since the linker cannot do this automatically to save space. - - 2010-03-20: Simon Goldschmidt - * opt.h, etharp.c/.h: Added support for static ARP table entries - - 2010-03-14: Simon Goldschmidt - * tcp_impl.h, tcp_out.c, inet_chksum.h/.c: task #6849: Calculate checksum - when creating TCP segments, not when (re-)transmitting them. - - 2010-03-07: Simon Goldschmidt - * sockets.c: bug #28775 (select/event_callback: only check select_cb_list - on change) plus use SYS_LIGHTWEIGHT_PROT to protect the select code. - This should speed up receiving data on sockets as the select code in - event_callback is only executed when select is waiting. - - 2010-03-06: Simon Goldschmidt - * tcp_out.c: task #7013 (Create option to have all packets delivered to - netif->output in one piece): Always copy to try to create single pbufs - in tcp_write. - - 2010-03-06: Simon Goldschmidt - * api.h, api_lib.c, sockets.c: task #10167 (sockets: speed up TCP recv - by not allocating a netbuf): added function netconn_recv_tcp_pbuf() - for tcp netconns to receive pbufs, not netbufs; use that function - for tcp sockets. - - 2010-03-05: Jakob Ole Stoklundsen / Simon Goldschmidt - * opt.h, tcp.h, tcp_impl.h, tcp.c, tcp_in.c, tcp_out.c: task #7040: - Work on tcp_enqueue: Don't waste memory when chaining segments, - added option TCP_OVERSIZE to prevent creating many small pbufs when - calling tcp_write with many small blocks of data. Instead, pbufs are - allocated larger than needed and the space is used for later calls to - tcp_write. - - 2010-02-21: Simon Goldschmidt - * stats.c/.h: Added const char* name to mem- and memp-stats for easier - debugging. - - 2010-02-21: Simon Goldschmidt - * tcp.h (and usages), added tcp_impl.h: Splitted API and internal - implementation of tcp to make API usage cleare to application programmers - - 2010-02-14: Simon Goldschmidt/Stephane Lesage - * ip_addr.h: Improved some defines working on ip addresses, added faster - macro to copy addresses that cannot be NULL - - 2010-02-13: Simon Goldschmidt - * api.h, api_lib.c, api_msg.c, sockets.c: task #7865 (implement non- - blocking send operation) - - 2010-02-12: Simon Goldschmidt - * sockets.c/.h: Added a minimal version of posix fctl() to have a - standardised way to set O_NONBLOCK for nonblocking sockets. - - 2010-02-12: Simon Goldschmidt - * dhcp.c/.h, autoip.c/.h: task #10139 (Prefer statically allocated - memory): added autoip_set_struct() and dhcp_set_struct() to let autoip - and dhcp work with user-allocated structs instead of callin mem_malloc - - 2010-02-12: Simon Goldschmidt/Jeff Barber - * tcp.c/h: patch #6865 (SO_REUSEADDR for TCP): if pcb.so_options has - SOF_REUSEADDR set, allow binding to endpoint in TIME_WAIT - - 2010-02-12: Simon Goldschmidt - * sys layer: task #10139 (Prefer statically allocated memory): converted - mbox and semaphore functions to take pointers to sys_mbox_t/sys_sem_t; - converted sys_mbox_new/sys_sem_new to take pointers and return err_t; - task #7212: Add Mutex concept in sys_arch (define LWIP_COMPAT_MUTEX - to let sys.h use binary semaphores instead of mutexes - as before) - - 2010-02-09: Simon Goldschmidt (Simon Kallweit) - * timers.c/.h: Added function sys_restart_timeouts() from patch #7085 - (Restart system timeout handling) - - 2010-02-09: Simon Goldschmidt - * netif.c/.h, removed loopif.c/.h: task #10153 (Integrate loopif into - netif.c) - loopif does not have to be created by the port any more, - just define LWIP_HAVE_LOOPIF to 1. - - 2010-02-08: Simon Goldschmidt - * inet.h, ip_addr.c/.h: Added reentrant versions of inet_ntoa/ipaddr_ntoa - inet_ntoa_r/ipaddr_ntoa_r - - 2010-02-08: Simon Goldschmidt - * netif.h: Added netif_s/get_igmp_mac_filter() macros - - 2010-02-05: Simon Goldschmidt - * netif.h: Added function-like macros to get/set the hostname on a netif - - 2010-02-04: Simon Goldschmidt - * nearly every file: Replaced struct ip_addr by typedef ip_addr_t to - make changing the actual implementation behind the typedef easier. - - 2010-02-01: Simon Goldschmidt - * opt.h, memp_std.h, dns.h, netdb.c, memp.c: Let netdb use a memp pool - for allocating memory when getaddrinfo() is called. - - 2010-01-31: Simon Goldschmidt - * dhcp.h, dhcp.c: Reworked the code that parses DHCP options: parse - them once instead of parsing for every option. This also removes - the need for mem_malloc from dhcp_recv and makes it possible to - correctly retrieve the BOOTP file. - - 2010-01-30: simon Goldschmidt - * sockets.c: Use SYS_LIGHTWEIGHT_PROT instead of a semaphore to protect - the sockets array. - - 2010-01-29: Simon Goldschmidt (patch by Laura Garrett) - * api.h, api_msg.c, sockets.c: Added except set support in select - (patch #6860) - - 2010-01-29: Simon Goldschmidt (patch by Laura Garrett) - * api.h, sockets.h, err.h, api_lib.c, api_msg.c, sockets.c, err.c: - Add non-blocking support for connect (partly from patch #6860), - plus many cleanups in socket & netconn API. - - 2010-01-27: Simon Goldschmidt - * opt.h, tcp.h, init.c, api_msg.c: Added TCP_SNDQUEUELOWAT corresponding - to TCP_SNDLOWAT and added tcp_sndqueuelen() - this fixes bug #28605 - - 2010-01-26: Simon Goldschmidt - * snmp: Use memp pools for snmp instead of the heap; added 4 new pools. - - 2010-01-14: Simon Goldschmidt - * ppp.c/.h: Fixed bug #27856: PPP: Set netif link- and status-callback - by adding ppp_set_netif_statuscallback()/ppp_set_netif_linkcallback() - - 2010-01-13: Simon Goldschmidt - * mem.c: The heap now may be moved to user-defined memory by defining - LWIP_RAM_HEAP_POINTER as a void pointer to that memory's address - (patch #6966 and bug #26133) - - 2010-01-10: Simon Goldschmidt (Bill Auerbach) - * opt.h, memp.c: patch #6822 (Add option to place memory pools in - separate arrays) - - 2010-01-10: Simon Goldschmidt - * init.c, igmp.c: patch #6463 (IGMP - Adding Random Delay): added define - LWIP_RAND() for lwip-wide randomization (to be defined in cc.h) - - 2009-12-31: Simon Goldschmidt - * tcpip.c, init.c, memp.c, sys.c, memp_std.h, sys.h, tcpip.h - added timers.c/.h: Separated timer implementation from semaphore/mbox - implementation, moved timer implementation to timers.c/.h, timers are - now only called from tcpip_thread or by explicitly checking them. - (TASK#7235) - - 2009-12-27: Simon Goldschmidt - * opt.h, etharp.h/.c, init.c, tcpip.c: Added an additional option - LWIP_ETHERNET to support ethernet without ARP (necessary for pure PPPoE) - - - ++ Bugfixes: - - 2011-04-20: Simon Goldschmidt - * sys_arch.txt: sys_arch_timeouts() is not needed any more. - - 2011-04-13: Simon Goldschmidt - * tcp.c, udp.c: Fixed bug #33048 (Bad range for IP source port numbers) by - using ports in the IANA private/dynamic range (49152 through 65535). - - 2011-03-29: Simon Goldschmidt, patch by Emil Lhungdahl: - * etharp.h/.c: Fixed broken VLAN support. - - 2011-03-27: Simon Goldschmidt - * tcp.c: Fixed bug #32926 (TCP_RMV(&tcp_bound_pcbs) is called on unbound tcp - pcbs) by checking if the pcb was bound (local_port != 0). - - 2011-03-27: Simon Goldschmidt - * ppp.c: Fixed bug #32280 (ppp: a pbuf is freed twice) - - 2011-03-27: Simon Goldschmidt - * sockets.c: Fixed bug #32906: lwip_connect+lwip_send did not work for udp and - raw pcbs with LWIP_TCPIP_CORE_LOCKING==1. - - 2011-03-27: Simon Goldschmidt - * tcp_out.c: Fixed bug #32820 (Outgoing TCP connections created before route - is present never times out) by starting retransmission timer before checking - route. - - 2011-03-22: Simon Goldschmidt - * ppp.c: Fixed bug #32648 (PPP code crashes when terminating a link) by only - calling sio_read_abort() if the file descriptor is valid. - - 2011-03-14: Simon Goldschmidt - * err.h/.c, sockets.c, api_msg.c: fixed bug #31748 (Calling non-blocking connect - more than once can render a socket useless) since it mainly involves changing - "FATAL" classification of error codes: ERR_USE and ERR_ISCONN just aren't fatal. - - 2011-03-13: Simon Goldschmidt - * sockets.c: fixed bug #32769 (ESHUTDOWN is linux-specific) by fixing - err_to_errno_table (ERR_CLSD: ENOTCONN instead of ESHUTDOWN), ERR_ISCONN: - use EALRADY instead of -1 - - 2011-03-13: Simon Goldschmidt - * api_lib.c: netconn_accept: return ERR_ABRT instead of ERR_CLSD if the - connection has been aborted by err_tcp (since this is not a normal closing - procedure). - - 2011-03-13: Simon Goldschmidt - * tcp.c: tcp_bind: return ERR_VAL instead of ERR_ISCONN when trying to bind - with pcb->state != CLOSED - - 2011-02-17: Simon Goldschmidt - * rawapi.txt: Fixed bug #32561 tcp_poll argument definition out-of-order in - documentation - - 2011-02-17: Simon Goldschmidt - * many files: Added missing U/UL modifiers to fix 16-bit-arch portability. - - 2011-01-24: Simon Goldschmidt - * sockets.c: Fixed bug #31741: lwip_select seems to have threading problems - - 2010-12-02: Simon Goldschmidt - * err.h: Fixed ERR_IS_FATAL so that ERR_WOULDBLOCK is not fatal. - - 2010-11-23: Simon Goldschmidt - * api.h, api_lib.c, api_msg.c, sockets.c: netconn.recv_avail is only used for - LWIP_SO_RCVBUF and ioctl/FIONREAD. - - 2010-11-23: Simon Goldschmidt - * etharp.c: Fixed bug #31720: ARP-queueing: RFC 1122 recommends to queue at - least 1 packet -> ARP_QUEUEING==0 now queues the most recent packet. - - 2010-11-23: Simon Goldschmidt - * tcp_in.c: Fixed bug #30577: tcp_input: don't discard ACK-only packets after - refusing 'refused_data' again. - - 2010-11-22: Simon Goldschmidt - * sockets.c: Fixed bug #31590: getsockopt(... SO_ERROR ...) gives EINPROGRESS - after a successful nonblocking connection. - - 2010-11-22: Simon Goldschmidt - * etharp.c: Fixed bug #31722: IP packets sent with an AutoIP source addr - must be sent link-local - - 2010-11-22: Simon Goldschmidt - * timers.c: patch #7329: tcp_timer_needed prototype was ifdef'ed out for - LWIP_TIMERS==0 - - 2010-11-20: Simon Goldschmidt - * sockets.c: Fixed bug #31170: lwip_setsockopt() does not set socket number - - 2010-11-20: Simon Goldschmidt - * sockets.h: Fixed bug #31304: Changed SHUT_RD, SHUT_WR and SHUT_RDWR to - resemble other stacks. - - 2010-11-20: Simon Goldschmidt - * dns.c: Fixed bug #31535: TCP_SND_QUEUELEN must be at least 2 or else - no-copy TCP writes will never succeed. - - 2010-11-20: Simon Goldschmidt - * dns.c: Fixed bug #31701: Error return value from dns_gethostbyname() does - not match documentation: return ERR_ARG instead of ERR_VAL if not - initialized or wrong argument. - - 2010-10-20: Simon Goldschmidt - * sockets.h: Fixed bug #31385: sizeof(struct sockaddr) is 30 but should be 16 - - 2010-10-05: Simon Goldschmidt - * dhcp.c: Once again fixed #30038: DHCP/AutoIP cooperation failed when - replugging the network cable after an AutoIP address was assigned. - - 2010-08-10: Simon Goldschmidt - * tcp.c: Fixed bug #30728: tcp_new_port() did not check listen pcbs - - 2010-08-03: Simon Goldschmidt - * udp.c, raw.c: Don't chain empty pbufs when sending them (fixes bug #30625) - - 2010-08-01: Simon Goldschmidt (patch by Greg Renda) - * ppp.c: Applied patch #7264 (PPP protocols are rejected incorrectly on big - endian architectures) - - 2010-07-28: Simon Goldschmidt - * api_lib.c, api_msg.c, sockets.c, mib2.c: Fixed compilation with TCP or UDP - disabled. - - 2010-07-27: Simon Goldschmidt - * tcp.c: Fixed bug #30565 (tcp_connect() check bound list): that check did no - harm but never did anything - - 2010-07-21: Simon Goldschmidt - * ip.c: Fixed invalid fix for bug #30402 (CHECKSUM_GEN_IP_INLINE does not - add IP options) - - 2010-07-16: Kieran Mansley - * msg_in.c: Fixed SNMP ASN constant defines to not use ! operator - - 2010-07-10: Simon Goldschmidt - * ip.c: Fixed bug #30402: CHECKSUM_GEN_IP_INLINE does not add IP options - - 2010-06-30: Simon Goldschmidt - * api_msg.c: fixed bug #30300 (shutdown parameter was not initialized in - netconn_delete) - - 2010-06-28: Kieran Mansley - * timers.c remove unportable printing of C function pointers - - 2010-06-24: Simon Goldschmidt - * init.c, timers.c/.h, opt.h, memp_std.h: From patch #7221: added flag - NO_SYS_NO_TIMERS to drop timer support for NO_SYS==1 for easier upgrading - - 2010-06-24: Simon Goldschmidt - * api(_lib).c/.h, api_msg.c/.h, sockets.c/.h: Fixed bug #10088: Correctly - implemented shutdown at socket level. - - 2010-06-21: Simon Goldschmidt - * pbuf.c/.h, ip_frag.c/.h, opt.h, memp_std.h: Fixed bug #29361 (ip_frag has - problems with zero-copy DMA MACs) by adding custom pbufs and implementing - custom pbufs that reference other (original) pbufs. Additionally set - IP_FRAG_USES_STATIC_BUF=0 as default to be on the safe side. - - 2010-06-15: Simon Goldschmidt - * dhcp.c: Fixed bug #29970: DHCP endian issue parsing option responses - - 2010-06-14: Simon Goldschmidt - * autoip.c: Fixed bug #30039: AutoIP does not reuse previous addresses - - 2010-06-12: Simon Goldschmidt - * dhcp.c: Fixed bug #30038: dhcp_network_changed doesn't reset AUTOIP coop - state - - 2010-05-17: Simon Goldschmidt - * netdb.c: Correctly NULL-terminate h_addr_list - - 2010-05-16: Simon Goldschmidt - * def.h/.c: changed the semantics of LWIP_PREFIX_BYTEORDER_FUNCS to prevent - "symbol already defined" i.e. when linking to winsock - - 2010-05-05: Simon Goldschmidt - * def.h, timers.c: Fixed bug #29769 (sys_check_timeouts: sys_now() may - overflow) - - 2010-04-21: Simon Goldschmidt - * api_msg.c: Fixed bug #29617 (sometime cause stall on delete listening - connection) - - 2010-03-28: Luca Ceresoli - * ip_addr.c/.h: patch #7143: Add a few missing const qualifiers - - 2010-03-27: Luca Ceresoli - * mib2.c: patch #7130: remove meaningless const qualifiers - - 2010-03-26: Simon Goldschmidt - * tcp_out.c: Make LWIP_NETIF_TX_SINGLE_PBUF work for TCP, too - - 2010-03-26: Simon Goldschmidt - * various files: Fixed compiling with different options disabled (TCP/UDP), - triggered by bug #29345; don't allocate acceptmbox if LWIP_TCP is disabled - - 2010-03-25: Simon Goldschmidt - * sockets.c: Fixed bug #29332: lwip_select() processes readset incorrectly - - 2010-03-25: Simon Goldschmidt - * tcp_in.c, test_tcp_oos.c: Fixed bug #29080: Correctly handle remote side - overrunning our rcv_wnd in ooseq case. - - 2010-03-22: Simon Goldschmidt - * tcp.c: tcp_listen() did not copy the pcb's prio. - - 2010-03-19: Simon Goldschmidt - * snmp_msg.c: Fixed bug #29256: SNMP Trap address was not correctly set - - 2010-03-14: Simon Goldschmidt - * opt.h, etharp.h: Fixed bug #29148 (Incorrect PBUF_POOL_BUFSIZE for ports - where ETH_PAD_SIZE > 0) by moving definition of ETH_PAD_SIZE to opt.h - and basing PBUF_LINK_HLEN on it. - - 2010-03-08: Simon Goldschmidt - * netif.c, ipv4/ip.c: task #10241 (AutoIP: don't break existing connections - when assiging routable address): when checking incoming packets and - aborting existing connection on address change, filter out link-local - addresses. - - 2010-03-06: Simon Goldschmidt - * sockets.c: Fixed LWIP_NETIF_TX_SINGLE_PBUF for LWIP_TCPIP_CORE_LOCKING - - 2010-03-06: Simon Goldschmidt - * ipv4/ip.c: Don't try to forward link-local addresses - - 2010-03-06: Simon Goldschmidt - * etharp.c: Fixed bug #29087: etharp: don't send packets for LinkLocal- - addresses to gw - - 2010-03-05: Simon Goldschmidt - * dhcp.c: Fixed bug #29072: Correctly set ciaddr based on message-type - and state. - - 2010-03-05: Simon Goldschmidt - * api_msg.c: Correctly set TCP_WRITE_FLAG_MORE when netconn_write is split - into multiple calls to tcp_write. - - 2010-02-21: Simon Goldschmidt - * opt.h, mem.h, dns.c: task #10140: Remove DNS_USES_STATIC_BUF (keep - the implementation of DNS_USES_STATIC_BUF==1) - - 2010-02-20: Simon Goldschmidt - * tcp.h, tcp.c, tcp_in.c, tcp_out.c: Task #10088: Correctly implement - close() vs. shutdown(). Now the application does not get any more - recv callbacks after calling tcp_close(). Added tcp_shutdown(). - - 2010-02-19: Simon Goldschmidt - * mem.c/.h, pbuf.c: Renamed mem_realloc() to mem_trim() to prevent - confusion with realloc() - - 2010-02-15: Simon Goldschmidt/Stephane Lesage - * netif.c/.h: Link status does not depend on LWIP_NETIF_LINK_CALLBACK - (fixes bug #28899) - - 2010-02-14: Simon Goldschmidt - * netif.c: Fixed bug #28877 (Duplicate ARP gratuitous packet with - LWIP_NETIF_LINK_CALLBACK set on) by only sending if both link- and - admin-status of a netif are up - - 2010-02-14: Simon Goldschmidt - * opt.h: Disable ETHARP_TRUST_IP_MAC by default since it slows down packet - reception and is not really necessary - - 2010-02-14: Simon Goldschmidt - * etharp.c/.h: Fixed ARP input processing: only add a new entry if a - request was directed as us (RFC 826, Packet Reception), otherwise - only update existing entries; internalized some functions - - 2010-02-14: Simon Goldschmidt - * netif.h, etharp.c, tcpip.c: Fixed bug #28183 (ARP and TCP/IP cannot be - disabled on netif used for PPPoE) by adding a new netif flag - (NETIF_FLAG_ETHERNET) that tells the stack the device is an ethernet - device but prevents usage of ARP (so that ethernet_input can be used - for PPPoE). - - 2010-02-12: Simon Goldschmidt - * netif.c: netif_set_link_up/down: only do something if the link state - actually changes - - 2010-02-12: Simon Goldschmidt/Stephane Lesage - * api_msg.c: Fixed bug #28865 (Cannot close socket/netconn in non-blocking - connect) - - 2010-02-12: Simon Goldschmidt - * mem.h: Fixed bug #28866 (mem_realloc function defined in mem.h) - - 2010-02-09: Simon Goldschmidt - * api_lib.c, api_msg.c, sockets.c, api.h, api_msg.h: Fixed bug #22110 - (recv() makes receive window update for data that wasn't received by - application) - - 2010-02-09: Simon Goldschmidt/Stephane Lesage - * sockets.c: Fixed bug #28853 (lwip_recvfrom() returns 0 on receive time-out - or any netconn_recv() error) - - 2010-02-09: Simon Goldschmidt - * ppp.c: task #10154 (PPP: Update snmp in/out counters for tx/rx packets) - - 2010-02-09: Simon Goldschmidt - * netif.c: For loopback packets, adjust the stats- and snmp-counters - for the loopback netif. - - 2010-02-08: Simon Goldschmidt - * igmp.c/.h, ip.h: Moved most defines from igmp.h to igmp.c for clarity - since they are not used anywhere else. - - 2010-02-08: Simon Goldschmidt (Stéphane Lesage) - * igmp.c, igmp.h, stats.c, stats.h: Improved IGMP stats - (patch from bug #28798) - - 2010-02-08: Simon Goldschmidt (Stéphane Lesage) - * igmp.c: Fixed bug #28798 (Error in "Max Response Time" processing) and - another bug when LWIP_RAND() returns zero. - - 2010-02-04: Simon Goldschmidt - * nearly every file: Use macros defined in ip_addr.h (some of them new) - to work with IP addresses (preparation for bug #27352 - Change ip_addr - from struct to typedef (u32_t) - and better code). - - 2010-01-31: Simon Goldschmidt - * netif.c: Don't call the link-callback from netif_set_up/down() since - this invalidly retriggers DHCP. - - 2010-01-29: Simon Goldschmidt - * ip_addr.h, inet.h, def.h, inet.c, def.c, more: Cleanly separate the - portability file inet.h and its contents from the stack: moved htonX- - functions to def.h (and the new def.c - they are not ipv4 dependent), - let inet.h depend on ip_addr.h and not the other way round. - This fixes bug #28732. - - 2010-01-28: Kieran Mansley - * tcp.c: Ensure ssthresh >= 2*MSS - - 2010-01-27: Simon Goldschmidt - * tcp.h, tcp.c, tcp_in.c: Fixed bug #27871: Calling tcp_abort() in recv - callback can lead to accessing unallocated memory. As a consequence, - ERR_ABRT means the application has called tcp_abort()! - - 2010-01-25: Simon Goldschmidt - * snmp_structs.h, msg_in.c: Partly fixed bug #22070 (MIB_OBJECT_WRITE_ONLY - not implemented in SNMP): write-only or not-accessible are still - returned by getnext (though not by get) - - 2010-01-24: Simon Goldschmidt - * snmp: Renamed the private mib node from 'private' to 'mib_private' to - not use reserved C/C++ keywords - - 2010-01-23: Simon Goldschmidt - * sockets.c: Fixed bug #28716: select() returns 0 after waiting for less - than 1 ms - - 2010-01-21: Simon Goldschmidt - * tcp.c, api_msg.c: Fixed bug #28651 (tcp_connect: no callbacks called - if tcp_enqueue fails) both in raw- and netconn-API - - 2010-01-19: Simon Goldschmidt - * api_msg.c: Fixed bug #27316: netconn: Possible deadlock in err_tcp - - 2010-01-18: Iordan Neshev/Simon Goldschmidt - * src/netif/ppp: reorganised PPP sourcecode to 2.3.11 including some - bugfix backports from 2.4.x. - - 2010-01-18: Simon Goldschmidt - * mem.c: Fixed bug #28679: mem_realloc calculates mem_stats wrong - - 2010-01-17: Simon Goldschmidt - * api_lib.c, api_msg.c, (api_msg.h, api.h, sockets.c, tcpip.c): - task #10102: "netconn: clean up conn->err threading issues" by adding - error return value to struct api_msg_msg - - 2010-01-17: Simon Goldschmidt - * api.h, api_lib.c, sockets.c: Changed netconn_recv() and netconn_accept() - to return err_t (bugs #27709 and #28087) - - 2010-01-14: Simon Goldschmidt - * ...: Use typedef for function prototypes throughout the stack. - - 2010-01-13: Simon Goldschmidt - * api_msg.h/.c, api_lib.c: Fixed bug #26672 (close connection when receive - window = 0) by correctly draining recvmbox/acceptmbox - - 2010-01-11: Simon Goldschmidt - * pap.c: Fixed bug #13315 (PPP PAP authentication can result in - erroneous callbacks) by copying the code from recent pppd - - 2010-01-10: Simon Goldschmidt - * raw.c: Fixed bug #28506 (raw_bind should filter received packets) - - 2010-01-10: Simon Goldschmidt - * tcp.h/.c: bug #28127 (remove call to tcp_output() from tcp_ack(_now)()) - - 2010-01-08: Simon Goldschmidt - * sockets.c: Fixed bug #28519 (lwip_recvfrom bug with len > 65535) - - 2010-01-08: Simon Goldschmidt - * dns.c: Copy hostname for DNS_LOCAL_HOSTLIST_IS_DYNAMIC==1 since string - passed to dns_local_addhost() might be volatile - - 2010-01-07: Simon Goldschmidt - * timers.c, tcp.h: Call tcp_timer_needed() with NO_SYS==1, too - - 2010-01-06: Simon Goldschmidt - * netdb.h: Fixed bug #28496: missing include guards in netdb.h - - 2009-12-31: Simon Goldschmidt - * many ppp files: Reorganised PPP source code from ucip structure to pppd - structure to easily compare our code against the pppd code (around v2.3.1) - - 2009-12-27: Simon Goldschmidt - * tcp_in.c: Another fix for bug #28241 (ooseq processing) and adapted - unit test - - -(STABLE-1.3.2) - - ++ New features: - - 2009-10-27 Simon Goldschmidt/Stephan Lesage - * netifapi.c/.h: Added netifapi_netif_set_addr() - - 2009-10-07 Simon Goldschmidt/Fabian Koch - * api_msg.c, netbuf.c/.h, opt.h: patch #6888: Patch for UDP Netbufs to - support dest-addr and dest-port (optional: LWIP_NETBUF_RECVINFO) - - 2009-08-26 Simon Goldschmidt/Simon Kallweit - * slipif.c/.h: bug #26397: SLIP polling support - - 2009-08-25 Simon Goldschmidt - * opt.h, etharp.h/.c: task #9033: Support IEEE 802.1q tagged frame (VLAN), - New configuration options ETHARP_SUPPORT_VLAN and ETHARP_VLAN_CHECK. - - 2009-08-25 Simon Goldschmidt - * ip_addr.h, netdb.c: patch #6900: added define ip_ntoa(struct ip_addr*) - - 2009-08-24 Jakob Stoklund Olesen - * autoip.c, dhcp.c, netif.c: patch #6725: Teach AutoIP and DHCP to respond - to netif_set_link_up(). - - 2009-08-23 Simon Goldschmidt - * tcp.h/.c: Added function tcp_debug_state_str() to convert a tcp state - to a human-readable string. - - ++ Bugfixes: - - 2009-12-24: Kieran Mansley - * tcp_in.c Apply patches from Oleg Tyshev to improve OOS processing - (BUG#28241) - - 2009-12-06: Simon Goldschmidt - * ppp.h/.c: Fixed bug #27079 (Yet another leak in PPP): outpacket_buf can - be statically allocated (like in ucip) - - 2009-12-04: Simon Goldschmidt (patch by Ioardan Neshev) - * pap.c: patch #6969: PPP: missing PAP authentication UNTIMEOUT - - 2009-12-03: Simon Goldschmidt - * tcp.h, tcp_in.c, tcp_out.c: Fixed bug #28106: dup ack for fast retransmit - could have non-zero length - - 2009-12-02: Simon Goldschmidt - * tcp_in.c: Fixed bug #27904: TCP sends too many ACKs: delay resetting - tcp_input_pcb until after calling the pcb's callbacks - - 2009-11-29: Simon Goldschmidt - * tcp_in.c: Fixed bug #28054: Two segments with FIN flag on the out-of- - sequence queue, also fixed PBUF_POOL leak in the out-of-sequence code - - 2009-11-29: Simon Goldschmidt - * pbuf.c: Fixed bug #28064: pbuf_alloc(PBUF_POOL) is not thread-safe by - queueing a call into tcpip_thread to free ooseq-bufs if the pool is empty - - 2009-11-26: Simon Goldschmidt - * tcp.h: Fixed bug #28098: Nagle can prevent fast retransmit from sending - segment - - 2009-11-26: Simon Goldschmidt - * tcp.h, sockets.c: Fixed bug #28099: API required to disable Nagle - algorithm at PCB level - - 2009-11-22: Simon Goldschmidt - * tcp_out.c: Fixed bug #27905: FIN isn't combined with data on unsent - - 2009-11-22: Simon Goldschmidt (suggested by Bill Auerbach) - * tcp.c: tcp_alloc: prevent increasing stats.err for MEMP_TCP_PCB when - reusing time-wait pcb - - 2009-11-20: Simon Goldschmidt (patch by Albert Bartel) - * sockets.c: Fixed bug #28062: Data received directly after accepting - does not wake up select - - 2009-11-11: Simon Goldschmidt - * netdb.h: Fixed bug #27994: incorrect define for freeaddrinfo(addrinfo) - - 2009-10-30: Simon Goldschmidt - * opt.h: Increased default value for TCP_MSS to 536, updated default - value for TCP_WND to 4*TCP_MSS to keep delayed ACK working. - - 2009-10-28: Kieran Mansley - * tcp_in.c, tcp_out.c, tcp.h: re-work the fast retransmission code - to follow algorithm from TCP/IP Illustrated - - 2009-10-27: Kieran Mansley - * tcp_in.c: fix BUG#27445: grow cwnd with every duplicate ACK - - 2009-10-25: Simon Goldschmidt - * tcp.h: bug-fix in the TCP_EVENT_RECV macro (has to call tcp_recved if - pcb->recv is NULL to keep rcv_wnd correct) - - 2009-10-25: Simon Goldschmidt - * tcp_in.c: Fixed bug #26251: RST process in TIME_WAIT TCP state - - 2009-10-23: Simon Goldschmidt (David Empson) - * tcp.c: Fixed bug #27783: Silly window avoidance for small window sizes - - 2009-10-21: Simon Goldschmidt - * tcp_in.c: Fixed bug #27215: TCP sent() callback gives leading and - trailing 1 byte len (SYN/FIN) - - 2009-10-21: Simon Goldschmidt - * tcp_out.c: Fixed bug #27315: zero window probe and FIN - - 2009-10-19: Simon Goldschmidt - * dhcp.c/.h: Minor code simplification (don't store received pbuf, change - conditional code to assert where applicable), check pbuf length before - testing for valid reply - - 2009-10-19: Simon Goldschmidt - * dhcp.c: Removed most calls to udp_connect since they aren't necessary - when using udp_sendto_if() - always stay connected to IP_ADDR_ANY. - - 2009-10-16: Simon Goldschmidt - * ip.c: Fixed bug #27390: Source IP check in ip_input() causes it to drop - valid DHCP packets -> allow 0.0.0.0 as source address when LWIP_DHCP is - enabled - - 2009-10-15: Simon Goldschmidt (Oleg Tyshev) - * tcp_in.c: Fixed bug #27329: dupacks by unidirectional data transmit - - 2009-10-15: Simon Goldschmidt - * api_lib.c: Fixed bug #27709: conn->err race condition on netconn_recv() - timeout - - 2009-10-15: Simon Goldschmidt - * autoip.c: Fixed bug #27704: autoip starts with wrong address - LWIP_AUTOIP_CREATE_SEED_ADDR() returned address in host byte order instead - of network byte order - - 2009-10-11 Simon Goldschmidt (Jörg Kesten) - * tcp_out.c: Fixed bug #27504: tcp_enqueue wrongly concatenates segments - which are not consecutive when retransmitting unacked segments - - 2009-10-09 Simon Goldschmidt - * opt.h: Fixed default values of some stats to only be enabled if used - Fixes bug #27338: sys_stats is defined when NO_SYS = 1 - - 2009-08-30 Simon Goldschmidt - * ip.c: Fixed bug bug #27345: "ip_frag() does not use the LWIP_NETIF_LOOPBACK - function" by checking for loopback before calling ip_frag - - 2009-08-25 Simon Goldschmidt - * dhcp.c: fixed invalid dependency to etharp_query if DHCP_DOES_ARP_CHECK==0 - - 2009-08-23 Simon Goldschmidt - * ppp.c: bug #27078: Possible memory leak in pppInit() - - 2009-08-23 Simon Goldschmidt - * netdb.c, dns.c: bug #26657: DNS, if host name is "localhost", result - is error. - - 2009-08-23 Simon Goldschmidt - * opt.h, init.c: bug #26649: TCP fails when TCP_MSS > TCP_SND_BUF - Fixed wrong parenthesis, added check in init.c - - 2009-08-23 Simon Goldschmidt - * ppp.c: bug #27266: wait-state debug message in pppMain occurs every ms - - 2009-08-23 Simon Goldschmidt - * many ppp files: bug #27267: Added include to string.h where needed - - 2009-08-23 Simon Goldschmidt - * tcp.h: patch #6843: tcp.h macro optimization patch (for little endian) - - -(STABLE-1.3.1) - - ++ New features: - - 2009-05-10 Simon Goldschmidt - * opt.h, sockets.c, pbuf.c, netbuf.h, pbuf.h: task #7013: Added option - LWIP_NETIF_TX_SINGLE_PBUF to try to create transmit packets from only - one pbuf to help MACs that don't support scatter-gather DMA. - - 2009-05-09 Simon Goldschmidt - * icmp.h, icmp.c: Shrinked ICMP code, added option to NOT check icoming - ECHO pbuf for size (just use it): LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN - - 2009-05-05 Simon Goldschmidt, Jakob Stoklund Olesen - * ip.h, ip.c: Added ip_current_netif() & ip_current_header() to receive - extended info about the currently received packet. - - 2009-04-27 Simon Goldschmidt - * sys.h: Made SYS_LIGHTWEIGHT_PROT and sys_now() work with NO_SYS=1 - - 2009-04-25 Simon Goldschmidt - * mem.c, opt.h: Added option MEM_USE_POOLS_TRY_BIGGER_POOL to try the next - bigger malloc pool if one is empty (only usable with MEM_USE_POOLS). - - 2009-04-21 Simon Goldschmidt - * dns.c, init.c, dns.h, opt.h: task #7507, patch #6786: DNS supports static - hosts table. New configuration options DNS_LOCAL_HOSTLIST and - DNS_LOCAL_HOSTLIST_IS_DYNAMIC. Also, DNS_LOOKUP_LOCAL_EXTERN() can be defined - as an external function for lookup. - - 2009-04-15 Simon Goldschmidt - * dhcp.c: patch #6763: Global DHCP XID can be redefined to something more unique - - 2009-03-31 Kieran Mansley - * tcp.c, tcp_out.c, tcp_in.c, sys.h, tcp.h, opts.h: add support for - TCP timestamp options, off by default. Rework tcp_enqueue() to - take option flags rather than specified option data - - 2009-02-18 Simon Goldschmidt - * cc.h: Added printf formatter for size_t: SZT_F - - 2009-02-16 Simon Goldschmidt (patch by Rishi Khan) - * icmp.c, opt.h: patch #6539: (configurable) response to broadcast- and multicast - pings - - 2009-02-12 Simon Goldschmidt - * init.h: Added LWIP_VERSION to get the current version of the stack - - 2009-02-11 Simon Goldschmidt (suggested by Gottfried Spitaler) - * opt.h, memp.h/.c: added MEMP_MEM_MALLOC to use mem_malloc/mem_free instead - of the pool allocator (can save code size with MEM_LIBC_MALLOC if libc-malloc - is otherwise used) - - 2009-01-28 Jonathan Larmour (suggested by Bill Bauerbach) - * ipv4/inet_chksum.c, ipv4/lwip/inet_chksum.h: inet_chksum_pseudo_partial() - is only used by UDPLITE at present, so conditionalise it. - - 2008-12-03 Simon Goldschmidt (base on patch from Luca Ceresoli) - * autoip.c: checked in (slightly modified) patch #6683: Customizable AUTOIP - "seed" address. This should reduce AUTOIP conflicts if - LWIP_AUTOIP_CREATE_SEED_ADDR is overridden. - - 2008-10-02 Jonathan Larmour and Rishi Khan - * sockets.c (lwip_accept): Return EWOULDBLOCK if would block on non-blocking - socket. - - 2008-06-30 Simon Goldschmidt - * mem.c, opt.h, stats.h: fixed bug #21433: Calling mem_free/pbuf_free from - interrupt context isn't safe: LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT allows - mem_free to run between mem_malloc iterations. Added illegal counter for - mem stats. - - 2008-06-27 Simon Goldschmidt - * stats.h/.c, some other files: patch #6483: stats module improvement: - Added defines to display each module's statistic individually, added stats - defines for MEM, MEMP and SYS modules, removed (unused) rexmit counter. - - 2008-06-17 Simon Goldschmidt - * err.h: patch #6459: Made err_t overridable to use a more efficient type - (define LWIP_ERR_T in cc.h) - - 2008-06-17 Simon Goldschmidt - * slipif.c: patch #6480: Added a configuration option for slipif for symmetry - to loopif - - 2008-06-17 Simon Goldschmidt (patch by Luca Ceresoli) - * netif.c, loopif.c, ip.c, netif.h, loopif.h, opt.h: Checked in slightly - modified version of patch # 6370: Moved loopif code to netif.c so that - loopback traffic is supported on all netifs (all local IPs). - Added option to limit loopback packets for each netifs. - - - ++ Bugfixes: - 2009-08-12 Kieran Mansley - * tcp_in.c, tcp.c: Fix bug #27209: handle trimming of segments when - out of window or out of order properly - - 2009-08-12 Kieran Mansley - * tcp_in.c: Fix bug #27199: use snd_wl2 instead of snd_wl1 - - 2009-07-28 Simon Goldschmidt - * mem.h: Fixed bug #27105: "realloc() cannot replace mem_realloc()"s - - 2009-07-27 Kieran Mansley - * api.h api_msg.h netdb.h sockets.h: add missing #include directives - - 2009-07-09 Kieran Mansley - * api_msg.c, sockets.c, api.h: BUG23240 use signed counters for - recv_avail and don't increment counters until message successfully - sent to mbox - - 2009-06-25 Kieran Mansley - * api_msg.c api.h: BUG26722: initialise netconn write variables - in netconn_alloc - - 2009-06-25 Kieran Mansley - * tcp.h: BUG26879: set ret value in TCP_EVENT macros when function is not set - - 2009-06-25 Kieran Mansley - * tcp.c, tcp_in.c, tcp_out.c, tcp.h: BUG26301 and BUG26267: correct - simultaneous close behaviour, and make snd_nxt have the same meaning - as in the RFCs. - - 2009-05-12 Simon Goldschmidt - * etharp.h, etharp.c, netif.c: fixed bug #26507: "Gratuitous ARP depends on - arp_table / uses etharp_query" by adding etharp_gratuitous() - - 2009-05-12 Simon Goldschmidt - * ip.h, ip.c, igmp.c: bug #26487: Added ip_output_if_opt that can add IP options - to the IP header (used by igmp_ip_output_if) - - 2009-05-06 Simon Goldschmidt - * inet_chksum.c: On little endian architectures, use LWIP_PLATFORM_HTONS (if - defined) for SWAP_BYTES_IN_WORD to speed up checksumming. - - 2009-05-05 Simon Goldschmidt - * sockets.c: bug #26405: Prematurely released semaphore causes lwip_select() - to crash - - 2009-05-04 Simon Goldschmidt - * init.c: snmp was not initialized in lwip_init() - - 2009-05-04 Frédéric Bernon - * dhcp.c, netbios.c: Changes if IP_SOF_BROADCAST is enabled. - - 2009-05-03 Simon Goldschmidt - * tcp.h: bug #26349: Nagle algorithm doesn't send although segment is full - (and unsent->next == NULL) - - 2009-05-02 Simon Goldschmidt - * tcpip.h, tcpip.c: fixed tcpip_untimeout (does not need the time, broken after - 1.3.0 in CVS only) - fixes compilation of ppp_oe.c - - 2009-05-02 Simon Goldschmidt - * msg_in.c: fixed bug #25636: SNMPSET value is ignored for integer fields - - 2009-05-01 Simon Goldschmidt - * pap.c: bug #21680: PPP upap_rauthnak() drops legal NAK packets - - 2009-05-01 Simon Goldschmidt - * ppp.c: bug #24228: Memory corruption with PPP and DHCP - - 2009-04-29 Frédéric Bernon - * raw.c, udp.c, init.c, opt.h, ip.h, sockets.h: bug #26309: Implement the - SO(F)_BROADCAST filter for all API layers. Avoid the unindented reception - of broadcast packets even when this option wasn't set. Port maintainers - which want to enable this filter have to set IP_SOF_BROADCAST=1 in opt.h. - If you want this option also filter broadcast on recv operations, you also - have to set IP_SOF_BROADCAST_RECV=1 in opt.h. - - 2009-04-28 Simon Goldschmidt, Jakob Stoklund Olesen - * dhcp.c: patch #6721, bugs #25575, #25576: Some small fixes to DHCP and - DHCP/AUTOIP cooperation - - 2009-04-25 Simon Goldschmidt, Oleg Tyshev - * tcp_out.c: bug #24212: Deadlocked tcp_retransmit due to exceeded pcb->cwnd - Fixed by sorting the unsent and unacked queues (segments are inserted at the - right place in tcp_output and tcp_rexmit). - - 2009-04-25 Simon Goldschmidt - * memp.c, mem.c, memp.h, mem_std.h: bug #26213 "Problem with memory allocation - when debugging": memp_sizes contained the wrong sizes (including sanity - regions); memp pools for MEM_USE_POOLS were too small - - 2009-04-24 Simon Goldschmidt, Frédéric Bernon - * inet.c: patch #6765: Fix a small problem with the last changes (incorrect - behavior, with with ip address string not ended by a '\0', a space or a - end of line) - - 2009-04-19 Simon Goldschmidt - * rawapi.txt: Fixed bug #26069: Corrected documentation: if tcp_connect fails, - pcb->err is called, not pcb->connected (with an error code). - - 2009-04-19 Simon Goldschmidt - * tcp_out.c: Fixed bug #26236: "TCP options (timestamp) don't work with - no-copy-tcpwrite": deallocate option data, only concat segments with same flags - - 2009-04-19 Simon Goldschmidt - * tcp_out.c: Fixed bug #25094: "Zero-length pbuf" (options are now allocated - in the header pbuf, not the data pbuf) - - 2009-04-18 Simon Goldschmidt - * api_msg.c: fixed bug #25695: Segmentation fault in do_writemore() - - 2009-04-15 Simon Goldschmidt - * sockets.c: tried to fix bug #23559: lwip_recvfrom problem with tcp - - 2009-04-15 Simon Goldschmidt - * dhcp.c: task #9192: mem_free of dhcp->options_in and dhcp->msg_in - - 2009-04-15 Simon Goldschmidt - * ip.c, ip6.c, tcp_out.c, ip.h: patch #6808: Add a utility function - ip_hinted_output() (for smaller code mainly) - - 2009-04-15 Simon Goldschmidt - * inet.c: patch #6765: Supporting new line characters in inet_aton() - - 2009-04-15 Simon Goldschmidt - * dhcp.c: patch #6764: DHCP rebind and renew did not send hostnam option; - Converted constant OPTION_MAX_MSG_SIZE to netif->mtu, check if netif->mtu - is big enough in dhcp_start - - 2009-04-15 Simon Goldschmidt - * netbuf.c: bug #26027: netbuf_chain resulted in pbuf memory leak - - 2009-04-15 Simon Goldschmidt - * sockets.c, ppp.c: bug #25763: corrected 4 occurrences of SMEMCPY to MEMCPY - - 2009-04-15 Simon Goldschmidt - * sockets.c: bug #26121: set_errno can be overridden - - 2009-04-09 Kieran Mansley (patch from Luca Ceresoli ) - * init.c, opt.h: Patch#6774 TCP_QUEUE_OOSEQ breaks compilation when - LWIP_TCP==0 - - 2009-04-09 Kieran Mansley (patch from Roy Lee ) - * tcp.h: Patch#6802 Add do-while-clauses to those function like - macros in tcp.h - - 2009-03-31 Kieran Mansley - * tcp.c, tcp_in.c, tcp_out.c, tcp.h, opt.h: Rework the way window - updates are calculated and sent (BUG20515) - - * tcp_in.c: cope with SYN packets received during established states, - and retransmission of initial SYN. - - * tcp_out.c: set push bit correctly when tcp segments are merged - - 2009-03-27 Kieran Mansley - * tcp_out.c set window correctly on probes (correcting change made - yesterday) - - 2009-03-26 Kieran Mansley - * tcp.c, tcp_in.c, tcp.h: add tcp_abandon() to cope with dropping - connections where no reset required (bug #25622) - - * tcp_out.c: set TCP_ACK flag on keepalive and zero window probes - (bug #20779) - - 2009-02-18 Simon Goldschmidt (Jonathan Larmour and Bill Auerbach) - * ip_frag.c: patch #6528: the buffer used for IP_FRAG_USES_STATIC_BUF could be - too small depending on MEM_ALIGNMENT - - 2009-02-16 Simon Goldschmidt - * sockets.h/.c, api_*.h/.c: fixed arguments of socket functions to match the standard; - converted size argument of netconn_write to 'size_t' - - 2009-02-16 Simon Goldschmidt - * tcp.h, tcp.c: fixed bug #24440: TCP connection close problem on 64-bit host - by moving accept callback function pointer to TCP_PCB_COMMON - - 2009-02-12 Simon Goldschmidt - * dhcp.c: fixed bug #25345 (DHCPDECLINE is sent with "Maximum message size" - option) - - 2009-02-11 Simon Goldschmidt - * dhcp.c: fixed bug #24480 (releasing old udp_pdb and pbuf in dhcp_start) - - 2009-02-11 Simon Goldschmidt - * opt.h, api_msg.c: added configurable default valud for netconn->recv_bufsize: - RECV_BUFSIZE_DEFAULT (fixes bug #23726: pbuf pool exhaustion on slow recv()) - - 2009-02-10 Simon Goldschmidt - * tcp.c: fixed bug #25467: Listen backlog is not reset on timeout in SYN_RCVD: - Accepts_pending is decrease on a corresponding listen pcb when a connection - in state SYN_RCVD is close. - - 2009-01-28 Jonathan Larmour - * pbuf.c: reclaim pbufs from TCP out-of-sequence segments if we run - out of pool pbufs. - - 2008-12-19 Simon Goldschmidt - * many files: patch #6699: fixed some warnings on platform where sizeof(int) == 2 - - 2008-12-10 Tamas Somogyi, Frédéric Bernon - * sockets.c: fixed bug #25051: lwip_recvfrom problem with udp: fromaddr and - port uses deleted netbuf. - - 2008-10-18 Simon Goldschmidt - * tcp_in.c: fixed bug ##24596: Vulnerability on faulty TCP options length - in tcp_parseopt - - 2008-10-15 Simon Goldschmidt - * ip_frag.c: fixed bug #24517: IP reassembly crashes on unaligned IP headers - by packing the struct ip_reass_helper. - - 2008-10-03 David Woodhouse, Jonathan Larmour - * etharp.c (etharp_arp_input): Fix type aliasing problem copying ip address. - - 2008-10-02 Jonathan Larmour - * dns.c: Hard-code structure sizes, to avoid issues on some compilers where - padding is included. - - 2008-09-30 Jonathan Larmour - * sockets.c (lwip_accept): check addr isn't NULL. If it's valid, do an - assertion check that addrlen isn't NULL. - - 2008-09-30 Jonathan Larmour - * tcp.c: Fix bug #24227, wrong error message in tcp_bind. - - 2008-08-26 Simon Goldschmidt - * inet.h, ip_addr.h: fixed bug #24132: Cross-dependency between ip_addr.h and - inet.h -> moved declaration of struct in_addr from ip_addr.h to inet.h - - 2008-08-14 Simon Goldschmidt - * api_msg.c: fixed bug #23847: do_close_internal references freed memory (when - tcp_close returns != ERR_OK) - - 2008-07-08 Frédéric Bernon - * stats.h: Fix some build bugs introduced with patch #6483 (missing some parameters - in macros, mainly if MEM_STATS=0 and MEMP_STATS=0). - - 2008-06-24 Jonathan Larmour - * tcp_in.c: Fix for bug #23693 as suggested by Art R. Ensure cseg is unused - if tcp_seg_copy fails. - - 2008-06-17 Simon Goldschmidt - * inet_chksum.c: Checked in some ideas of patch #6460 (loop optimizations) - and created defines for swapping bytes and folding u32 to u16. - - 2008-05-30 Kieran Mansley - * tcp_in.c Remove redundant "if" statement, and use real rcv_wnd - rather than rcv_ann_wnd when deciding if packets are in-window. - Contributed by - - 2008-05-30 Kieran Mansley - * mem.h: Fix BUG#23254. Change macro definition of mem_* to allow - passing as function pointers when MEM_LIBC_MALLOC is defined. - - 2008-05-09 Jonathan Larmour - * err.h, err.c, sockets.c: Fix bug #23119: Reorder timeout error code to - stop it being treated as a fatal error. - - 2008-04-15 Simon Goldschmidt - * dhcp.c: fixed bug #22804: dhcp_stop doesn't clear NETIF_FLAG_DHCP - (flag now cleared) - - 2008-03-27 Simon Goldschmidt - * mem.c, tcpip.c, tcpip.h, opt.h: fixed bug #21433 (Calling mem_free/pbuf_free - from interrupt context isn't safe): set LWIP_USE_HEAP_FROM_INTERRUPT to 1 - in lwipopts.h or use pbuf_free_callback(p)/mem_free_callback(m) to free pbufs - or heap memory from interrupt context - - 2008-03-26 Simon Goldschmidt - * tcp_in.c, tcp.c: fixed bug #22249: division by zero could occur if a remote - host sent a zero mss as TCP option. - - -(STABLE-1.3.0) - - ++ New features: - - 2008-03-10 Jonathan Larmour - * inet_chksum.c: Allow choice of one of the sample algorithms to be - made from lwipopts.h. Fix comment on how to override LWIP_CHKSUM. - - 2008-01-22 Frédéric Bernon - * tcp.c, tcp_in.c, tcp.h, opt.h: Rename LWIP_CALCULATE_EFF_SEND_MSS in - TCP_CALCULATE_EFF_SEND_MSS to have coherent TCP options names. - - 2008-01-14 Frédéric Bernon - * rawapi.txt, api_msg.c, tcp.c, tcp_in.c, tcp.h: changes for task #7675 "Enable - to refuse data on a TCP_EVENT_RECV call". Important, behavior changes for the - tcp_recv callback (see rawapi.txt). - - 2008-01-14 Frédéric Bernon, Marc Chaland - * ip.c: Integrate patch #6369" ip_input : checking before realloc". - - 2008-01-12 Frédéric Bernon - * tcpip.h, tcpip.c, api.h, api_lib.c, api_msg.c, sockets.c: replace the field - netconn::sem per netconn::op_completed like suggested for the task #7490 - "Add return value to sys_mbox_post". - - 2008-01-12 Frédéric Bernon - * api_msg.c, opt.h: replace DEFAULT_RECVMBOX_SIZE per DEFAULT_TCP_RECVMBOX_SIZE, - DEFAULT_UDP_RECVMBOX_SIZE and DEFAULT_RAW_RECVMBOX_SIZE (to optimize queues - sizes), like suggested for the task #7490 "Add return value to sys_mbox_post". - - 2008-01-10 Frédéric Bernon - * tcpip.h, tcpip.c: add tcpip_callback_with_block function for the task #7490 - "Add return value to sys_mbox_post". tcpip_callback is always defined as - "blocking" ("block" parameter = 1). - - 2008-01-10 Frédéric Bernon - * tcpip.h, tcpip.c, api.h, api_lib.c, api_msg.c, sockets.c: replace the field - netconn::mbox (sys_mbox_t) per netconn::sem (sys_sem_t) for the task #7490 - "Add return value to sys_mbox_post". - - 2008-01-05 Frédéric Bernon - * sys_arch.txt, api.h, api_lib.c, api_msg.h, api_msg.c, tcpip.c, sys.h, opt.h: - Introduce changes for task #7490 "Add return value to sys_mbox_post" with some - modifications in the sys_mbox api: sys_mbox_new take a "size" parameters which - indicate the number of pointers query by the mailbox. There is three defines - in opt.h to indicate sizes for tcpip::mbox, netconn::recvmbox, and for the - netconn::acceptmbox. Port maintainers, you can decide to just add this new - parameter in your implementation, but to ignore it to keep the previous behavior. - The new sys_mbox_trypost function return a value to know if the mailbox is - full or if the message is posted. Take a look to sys_arch.txt for more details. - This new function is used in tcpip_input (so, can be called in an interrupt - context since the function is not blocking), and in recv_udp and recv_raw. - - 2008-01-04 Frédéric Bernon, Simon Goldschmidt, Jonathan Larmour - * rawapi.txt, api.h, api_lib.c, api_msg.h, api_msg.c, sockets.c, tcp.h, tcp.c, - tcp_in.c, init.c, opt.h: rename backlog options with TCP_ prefix, limit the - "backlog" parameter in an u8_t, 0 is interpreted as "smallest queue", add - documentation in the rawapi.txt file. - - 2007-12-31 Kieran Mansley (based on patch from Per-Henrik Lundbolm) - * tcp.c, tcp_in.c, tcp_out.c, tcp.h: Add TCP persist timer - - 2007-12-31 Frédéric Bernon, Luca Ceresoli - * autoip.c, etharp.c: ip_addr.h: Integrate patch #6348: "Broadcast ARP packets - in autoip". The change in etharp_raw could be removed, since all calls to - etharp_raw use ethbroadcast for the "ethdst_addr" parameter. But it could be - wrong in the future. - - 2007-12-30 Frédéric Bernon, Tom Evans - * ip.c: Fix bug #21846 "LwIP doesn't appear to perform any IP Source Address - Filtering" reported by Tom Evans. - - 2007-12-21 Frédéric Bernon, Simon Goldschmidt, Jonathan Larmour - * tcp.h, opt.h, api.h, api_msg.h, tcp.c, tcp_in.c, api_lib.c, api_msg.c, - sockets.c, init.c: task #7252: Implement TCP listen backlog: Warning: raw API - applications have to call 'tcp_accepted(pcb)' in their accept callback to - keep accepting new connections. - - 2007-12-13 Frédéric Bernon - * api_msg.c, err.h, err.c, sockets.c, dns.c, dns.h: replace "enum dns_result" - by err_t type. Add a new err_t code "ERR_INPROGRESS". - - 2007-12-12 Frédéric Bernon - * dns.h, dns.c, opt.h: move DNS options to the "right" place. Most visibles - are the one which have ram usage. - - 2007-12-05 Frédéric Bernon - * netdb.c: add a LWIP_DNS_API_HOSTENT_STORAGE option to decide to use a static - set of variables (=0) or a local one (=1). In this last case, your port should - provide a function "struct hostent* sys_thread_hostent( struct hostent* h)" - which have to do a copy of "h" and return a pointer ont the "per-thread" copy. - - 2007-12-03 Simon Goldschmidt - * ip.c: ip_input: check if a packet is for inp first before checking all other - netifs on netif_list (speeds up packet receiving in most cases) - - 2007-11-30 Simon Goldschmidt - * udp.c, raw.c: task #7497: Sort lists (pcb, netif, ...) for faster access - UDP: move a (connected) pcb selected for input to the front of the list of - pcbs so that it is found faster next time. Same for RAW pcbs that have eaten - a packet. - - 2007-11-28 Simon Goldschmidt - * etharp.c, stats.c, stats.h, opt.h: Introduced ETHARP_STATS - - 2007-11-25 Simon Goldschmidt - * dhcp.c: dhcp_unfold_reply() uses pbuf_copy_partial instead of its own copy - algorithm. - - 2007-11-24 Simon Goldschmidt - * netdb.h, netdb.c, sockets.h/.c: Moved lwip_gethostbyname from sockets.c - to the new file netdb.c; included lwip_getaddrinfo. - - 2007-11-21 Simon Goldschmidt - * tcp.h, opt.h, tcp.c, tcp_in.c: implemented calculating the effective send-mss - based on the MTU of the netif used to send. Enabled by default. Disable by - setting LWIP_CALCULATE_EFF_SEND_MSS to 0. This fixes bug #21492. - - 2007-11-19 Frédéric Bernon - * api_msg.c, dns.h, dns.c: Implement DNS_DOES_NAME_CHECK option (check if name - received match the name query), implement DNS_USES_STATIC_BUF (the place where - copy dns payload to parse the response), return an error if there is no place - for a new query, and fix some minor problems. - - 2007-11-16 Simon Goldschmidt - * new files: ipv4/inet.c, ipv4/inet_chksum.c, ipv6/inet6.c - removed files: core/inet.c, core/inet6.c - Moved inet files into ipv4/ipv6 directory; splitted inet.c/inet.h into - inet and chksum part; changed includes in all lwIP files as appropriate - - 2007-11-16 Simon Goldschmidt - * api.h, api_msg.h, api_lib.c, api_msg.c, socket.h, socket.c: Added sequential - dns resolver function for netconn api (netconn_gethostbyname) and socket api - (gethostbyname/gethostbyname_r). - - 2007-11-15 Jim Pettinato, Frédéric Bernon - * opt.h, init.c, tcpip.c, dhcp.c, dns.h, dns.c: add DNS client for simple name - requests with RAW api interface. Initialization is done in lwip_init() with - build time options. DNS timer is added in tcpip_thread context. DHCP can set - DNS server ip addresses when options are received. You need to set LWIP_DNS=1 - in your lwipopts.h file (LWIP_DNS=0 in opt.h). DNS_DEBUG can be set to get - some traces with LWIP_DEBUGF. Sanity check have been added. There is a "todo" - list with points to improve. - - 2007-11-06 Simon Goldschmidt - * opt.h, mib2.c: Patch #6215: added ifAdminStatus write support (if explicitly - enabled by defining SNMP_SAFE_REQUESTS to 0); added code to check link status - for ifOperStatus if LWIP_NETIF_LINK_CALLBACK is defined. - - 2007-11-06 Simon Goldschmidt - * api.h, api_msg.h and dependent files: Task #7410: Removed the need to include - core header files in api.h (ip/tcp/udp/raw.h) to hide the internal - implementation from netconn api applications. - - 2007-11-03 Frédéric Bernon - * api.h, api_lib.c, api_msg.c, sockets.c, opt.h: add SO_RCVBUF option for UDP & - RAW netconn. You need to set LWIP_SO_RCVBUF=1 in your lwipopts.h (it's disabled - by default). Netconn API users can use the netconn_recv_bufsize macro to access - it. This is a first release which have to be improve for TCP. Note it used the - netconn::recv_avail which need to be more "thread-safe" (note there is already - the problem for FIONREAD with lwip_ioctl/ioctlsocket). - - 2007-11-01 Frédéric Bernon, Marc Chaland - * sockets.h, sockets.c, api.h, api_lib.c, api_msg.h, api_msg.c, tcp.h, tcp_out.c: - Integrate "patch #6250 : MSG_MORE flag for send". MSG_MORE is used at socket api - layer, NETCONN_MORE at netconn api layer, and TCP_WRITE_FLAG_MORE at raw api - layer. This option enable to delayed TCP PUSH flag on multiple "write" calls. - Note that previous "copy" parameter for "write" APIs is now called "apiflags". - - 2007-10-24 Frédéric Bernon - * api.h, api_lib.c, api_msg.c: Add macro API_EVENT in the same spirit than - TCP_EVENT_xxx macros to get a code more readable. It could also help to remove - some code (like we have talk in "patch #5919 : Create compile switch to remove - select code"), but it could be done later. - - 2007-10-08 Simon Goldschmidt - * many files: Changed initialization: many init functions are not needed any - more since we now rely on the compiler initializing global and static - variables to zero! - - 2007-10-06 Simon Goldschmidt - * ip_frag.c, memp.c, mib2.c, ip_frag.h, memp_std.h, opt.h: Changed IP_REASSEMBLY - to enqueue the received pbufs so that multiple packets can be reassembled - simultaneously and no static reassembly buffer is needed. - - 2007-10-05 Simon Goldschmidt - * tcpip.c, etharp.h, etharp.c: moved ethernet_input from tcpip.c to etharp.c so - all netifs (or ports) can use it. - - 2007-10-05 Frédéric Bernon - * netifapi.h, netifapi.c: add function netifapi_netif_set_default. Change the - common function to reduce a little bit the footprint (for all functions using - only the "netif" parameter). - - 2007-10-03 Frédéric Bernon - * netifapi.h, netifapi.c: add functions netifapi_netif_set_up, netifapi_netif_set_down, - netifapi_autoip_start and netifapi_autoip_stop. Use a common function to reduce - a little bit the footprint (for all functions using only the "netif" parameter). - - 2007-09-15 Frédéric Bernon - * udp.h, udp.c, sockets.c: Changes for "#20503 IGMP Improvement". Add IP_MULTICAST_IF - option in socket API, and a new field "multicast_ip" in "struct udp_pcb" (for - netconn and raw API users), only if LWIP_IGMP=1. Add getsockopt processing for - IP_MULTICAST_TTL and IP_MULTICAST_IF. - - 2007-09-10 Frédéric Bernon - * snmp.h, mib2.c: enable to remove SNMP timer (which consumne several cycles - even when it's not necessary). snmp_agent.txt tell to call snmp_inc_sysuptime() - each 10ms (but, it's intrusive if you use sys_timeout feature). Now, you can - decide to call snmp_add_sysuptime(100) each 1000ms (which is bigger "step", but - call to a lower frequency). Or, you can decide to not call snmp_inc_sysuptime() - or snmp_add_sysuptime(), and to define the SNMP_GET_SYSUPTIME(sysuptime) macro. - This one is undefined by default in mib2.c. SNMP_GET_SYSUPTIME is called inside - snmp_get_sysuptime(u32_t *value), and enable to change "sysuptime" value only - when it's queried (any direct call to "sysuptime" is changed by a call to - snmp_get_sysuptime). - - 2007-09-09 Frédéric Bernon, Bill Florac - * igmp.h, igmp.c, netif.h, netif.c, ip.c: To enable to have interfaces with IGMP, - and others without it, there is a new NETIF_FLAG_IGMP flag to set in netif->flags - if you want IGMP on an interface. igmp_stop() is now called inside netif_remove(). - igmp_report_groups() is now called inside netif_set_link_up() (need to have - LWIP_NETIF_LINK_CALLBACK=1) to resend reports once the link is up (avoid to wait - the next query message to receive the matching multicast streams). - - 2007-09-08 Frédéric Bernon - * sockets.c, ip.h, api.h, tcp.h: declare a "struct ip_pcb" which only contains - IP_PCB. Add in the netconn's "pcb" union a "struct ip_pcb *ip;" (no size change). - Use this new field to access to common pcb fields (ttl, tos, so_options, etc...). - Enable to access to these fields with LWIP_TCP=0. - - 2007-09-05 Frédéric Bernon - * udp.c, ipv4/icmp.c, ipv4/ip.c, ipv6/icmp.c, ipv6/ip6.c, ipv4/icmp.h, - ipv6/icmp.h, opt.h: Integrate "task #7272 : LWIP_ICMP option". The new option - LWIP_ICMP enable/disable ICMP module inside the IP stack (enable per default). - Be careful, disabling ICMP make your product non-compliant to RFC1122, but - help to reduce footprint, and to reduce "visibility" on the Internet. - - 2007-09-05 Frédéric Bernon, Bill Florac - * opt.h, sys.h, tcpip.c, slipif.c, ppp.c, sys_arch.txt: Change parameters list - for sys_thread_new (see "task #7252 : Create sys_thread_new_ex()"). Two new - parameters have to be provided: a task name, and a task stack size. For this - one, since it's platform dependant, you could define the best one for you in - your lwipopts.h. For port maintainers, you can just add these new parameters - in your sys_arch.c file, and but it's not mandatory, use them in your OS - specific functions. - - 2007-09-05 Frédéric Bernon - * inet.c, autoip.c, msg_in.c, msg_out.c, init.c: Move some build time checkings - inside init.c for task #7142 "Sanity check user-configurable values". - - 2007-09-04 Frédéric Bernon, Bill Florac - * igmp.h, igmp.c, memp_std.h, memp.c, init.c, opt.h: Replace mem_malloc call by - memp_malloc, and use a new MEMP_NUM_IGMP_GROUP option (see opt.h to define the - value). It will avoid potential fragmentation problems, use a counter to know - how many times a group is used on an netif, and free it when all applications - leave it. MEMP_NUM_IGMP_GROUP got 8 as default value (and init.c got a sanity - check if LWIP_IGMP!=0). - - 2007-09-03 Frédéric Bernon - * igmp.h, igmp.c, sockets.c, api_msg.c: Changes for "#20503 IGMP Improvement". - Initialize igmp_mac_filter to NULL in netif_add (this field should be set in - the netif's "init" function). Use the "imr_interface" field (for socket layer) - and/or the "interface" field (for netconn layer), for join/leave operations. - The igmp_join/leavegroup first parameter change from a netif to an ipaddr. - This field could be a netif's ipaddr, or "any" (same meaning than ip_addr_isany). - - 2007-08-30 Frédéric Bernon - * Add netbuf.h, netbuf.c, Change api.h, api_lib.c: #7249 "Split netbuf functions - from api/api_lib". Now netbuf API is independant of netconn, and can be used - with other API (application based on raw API, or future "socket2" API). Ports - maintainers just have to add src/api/netbuf.c in their makefile/projects. - - 2007-08-30 Frédéric Bernon, Jonathan Larmour - * init.c: Add first version of lwip_sanity_check for task #7142 "Sanity check - user-configurable values". - - 2007-08-29 Frédéric Bernon - * igmp.h, igmp.c, tcpip.c, init.c, netif.c: change igmp_init and add igmp_start. - igmp_start is call inside netif_add. Now, igmp initialization is in the same - spirit than the others modules. Modify some IGMP debug traces. - - 2007-08-29 Frédéric Bernon - * Add init.h, init.c, Change opt.h, tcpip.c: Task #7213 "Add a lwip_init function" - Add lwip_init function to regroup all modules initializations, and to provide - a place to add code for task #7142 "Sanity check user-configurable values". - Ports maintainers should remove direct initializations calls from their code, - and add init.c in their makefiles. Note that lwip_init() function is called - inside tcpip_init, but can also be used by raw api users since all calls are - disabled when matching options are disabled. Also note that their is new options - in opt.h, you should configure in your lwipopts.h (they are enabled per default). - - 2007-08-26 Marc Boucher - * api_msg.c: do_close_internal(): Reset the callbacks and arg (conn) to NULL - since they can under certain circumstances be called with an invalid conn - pointer after the connection has been closed (and conn has been freed). - - 2007-08-25 Frédéric Bernon (Artem Migaev's Patch) - * netif.h, netif.c: Integrate "patch #6163 : Function to check if link layer is up". - Add a netif_is_link_up() function if LWIP_NETIF_LINK_CALLBACK option is set. - - 2007-08-22 Frédéric Bernon - * netif.h, netif.c, opt.h: Rename LWIP_NETIF_CALLBACK in LWIP_NETIF_STATUS_CALLBACK - to be coherent with new LWIP_NETIF_LINK_CALLBACK option before next release. - - 2007-08-22 Frédéric Bernon - * tcpip.h, tcpip.c, ethernetif.c, opt.h: remove options ETHARP_TCPIP_INPUT & - ETHARP_TCPIP_ETHINPUT, now, only "ethinput" code is supported, even if the - name is tcpip_input (we keep the name of 1.2.0 function). - - 2007-08-17 Jared Grubb - * memp_std.h, memp.h, memp.c, mem.c, stats.c: (Task #7136) Centralize mempool - settings into new memp_std.h and optional user file lwippools.h. This adds - more dynamic mempools, and allows the user to create an arbitrary number of - mempools for mem_malloc. - - 2007-08-16 Marc Boucher - * api_msg.c: Initialize newconn->state to NETCONN_NONE in accept_function; - otherwise it was left to NETCONN_CLOSE and sent_tcp() could prematurely - close the connection. - - 2007-08-16 Marc Boucher - * sockets.c: lwip_accept(): check netconn_peer() error return. - - 2007-08-16 Marc Boucher - * mem.c, mem.h: Added mem_calloc(). - - 2007-08-16 Marc Boucher - * tcpip.c, tcpip.h memp.c, memp.h: Added distinct memp (MEMP_TCPIP_MSG_INPKT) - for input packets to prevent floods from consuming all of MEMP_TCPIP_MSG - and starving other message types. - Renamed MEMP_TCPIP_MSG to MEMP_TCPIP_MSG_API - - 2007-08-16 Marc Boucher - * pbuf.c, pbuf.h, etharp.c, tcp_in.c, sockets.c: Split pbuf flags in pbuf - type and flgs (later renamed to flags). - Use enum pbuf_flag as pbuf_type. Renumber PBUF_FLAG_*. - Improved lwip_recvfrom(). TCP push now propagated. - - 2007-08-16 Marc Boucher - * ethernetif.c, contrib/ports/various: ethbroadcast now a shared global - provided by etharp. - - 2007-08-16 Marc Boucher - * ppp_oe.c ppp_oe.h, auth.c chap.c fsm.c lcp.c ppp.c ppp.h, - etharp.c ethernetif.c, etharp.h, opt.h tcpip.h, tcpip.c: - Added PPPoE support and various PPP improvements. - - 2007-07-25 Simon Goldschmidt - * api_lib.c, ip_frag.c, pbuf.c, api.h, pbuf.h: Introduced pbuf_copy_partial, - making netbuf_copy_partial use this function. - - 2007-07-25 Simon Goldschmidt - * tcp_in.c: Fix bug #20506: Slow start / initial congestion window starts with - 2 * mss (instead of 1 * mss previously) to comply with some newer RFCs and - other stacks. - - 2007-07-13 Jared Grubb (integrated by Frédéric Bernon) - * opt.h, netif.h, netif.c, ethernetif.c: Add new configuration option to add - a link callback in the netif struct, and functions to handle it. Be carefull - for port maintainers to add the NETIF_FLAG_LINK_UP flag (like in ethernetif.c) - if you want to be sure to be compatible with future changes... - - 2007-06-30 Frédéric Bernon - * sockets.h, sockets.c: Implement MSG_PEEK flag for recv/recvfrom functions. - - 2007-06-21 Simon Goldschmidt - * etharp.h, etharp.c: Combined etharp_request with etharp_raw for both - LWIP_AUTOIP =0 and =1 to remove redundant code. - - 2007-06-21 Simon Goldschmidt - * mem.c, memp.c, mem.h, memp.h, opt.h: task #6863: Introduced the option - MEM_USE_POOLS to use 4 pools with different sized elements instead of a - heap. This both prevents memory fragmentation and gives a higher speed - at the cost of more memory consumption. Turned off by default. - - 2007-06-21 Simon Goldschmidt - * api_lib.c, api_msg.c, api.h, api_msg.h: Converted the length argument of - netconn_write (and therefore also api_msg_msg.msg.w.len) from u16_t into - int to be able to send a bigger buffer than 64K with one time (mainly - used from lwip_send). - - 2007-06-21 Simon Goldschmidt - * tcp.h, api_msg.c: Moved the nagle algorithm from netconn_write/do_write - into a define (tcp_output_nagle) in tcp.h to provide it to raw api users, too. - - 2007-06-21 Simon Goldschmidt - * api.h, api_lib.c, api_msg.c: Fixed bug #20021: Moved sendbuf-processing in - netconn_write from api_lib.c to api_msg.c to also prevent multiple context- - changes on low memory or empty send-buffer. - - 2007-06-18 Simon Goldschmidt - * etharp.c, etharp.h: Changed etharp to use a defined hardware address length - of 6 to avoid loading netif->hwaddr_len every time (since this file is only - used for ethernet and struct eth_addr already had a defined length of 6). - - 2007-06-17 Simon Goldschmidt - * sockets.c, sockets.h: Implemented socket options SO_NO_CHECK for UDP sockets - to disable UDP checksum generation on transmit. - - 2007-06-13 Frédéric Bernon, Simon Goldschmidt - * debug.h, api_msg.c: change LWIP_ERROR to use it to check errors like invalid - pointers or parameters, and let the possibility to redefined it in cc.h. Use - this macro to check "conn" parameter in api_msg.c functions. - - 2007-06-11 Simon Goldschmidt - * sockets.c, sockets.h: Added UDP lite support for sockets - - 2007-06-10 Simon Goldschmidt - * udp.h, opt.h, api_msg.c, ip.c, udp.c: Included switch LWIP_UDPLITE (enabled - by default) to switch off UDP-Lite support if not needed (reduces udp.c code - size) - - 2007-06-09 Dominik Spies (integrated by Frédéric Bernon) - * autoip.h, autoip.c, dhcp.h, dhcp.c, netif.h, netif.c, etharp.h, etharp.c, opt.h: - AutoIP implementation available for IPv4, with new options LWIP_AUTOIP and - LWIP_DHCP_AUTOIP_COOP if you want to cooperate with DHCP. Some tips to adapt - (see TODO mark in the source code). - - 2007-06-09 Simon Goldschmidt - * etharp.h, etharp.c, ethernetif.c: Modified order of parameters for - etharp_output() to match netif->output so etharp_output() can be used - directly as netif->output to save one function call. - - 2007-06-08 Simon Goldschmidt - * netif.h, ethernetif.c, slipif.c, loopif.c: Added define - NETIF_INIT_SNMP(netif, type, speed) to initialize per-netif snmp variables, - added initialization of those to ethernetif, slipif and loopif. - - 2007-05-18 Simon Goldschmidt - * opt.h, ip_frag.c, ip_frag.h, ip.c: Added option IP_FRAG_USES_STATIC_BUF - (defaulting to off for now) that can be set to 0 to send fragmented - packets by passing PBUF_REFs down the stack. - - 2007-05-23 Frédéric Bernon - * api_lib.c: Implement SO_RCVTIMEO for accept and recv on TCP - connections, such present in patch #5959. - - 2007-05-23 Frédéric Bernon - * api.h, api_lib.c, api_msg.c, sockets.c: group the different NETCONN_UDPxxx - code in only one part... - - 2007-05-18 Simon Goldschmidt - * opt.h, memp.h, memp.c: Added option MEMP_OVERFLOW_CHECK to check for memp - elements to overflow. This is achieved by adding some bytes before and after - each pool element (increasing their size, of course), filling them with a - prominent value and checking them on freeing the element. - Set it to 2 to also check every element in every pool each time memp_malloc() - or memp_free() is called (slower but more helpful). - - 2007-05-10 Simon Goldschmidt - * opt.h, memp.h, memp.c, pbuf.c (see task #6831): use a new memp pool for - PBUF_POOL pbufs instead of the old pool implementation in pbuf.c to reduce - code size. - - 2007-05-11 Frédéric Bernon - * sockets.c, api_lib.c, api_msg.h, api_msg.c, netifapi.h, netifapi.c, tcpip.c: - Include a function pointer instead of a table index in the message to reduce - footprint. Disable some part of lwip_send and lwip_sendto if some options are - not set (LWIP_TCP, LWIP_UDP, LWIP_RAW). - - 2007-05-10 Simon Goldschmidt - * *.h (except netif/ppp/*.h): Included patch #5448: include '#ifdef __cplusplus - \ extern "C" {' in all header files. Now you can write your application using - the lwIP stack in C++ and simply #include the core files. Note I have left - out the netif/ppp/*h header files for now, since I don't know which files are - included by applications and which are for internal use only. - - 2007-05-09 Simon Goldschmidt - * opt.h, *.c/*.h: Included patch #5920: Create define to override C-library - memcpy. 2 Defines are created: MEMCPY() for normal memcpy, SMEMCPY() for - situations where some compilers might inline the copy and save a function - call. Also replaced all calls to memcpy() with calls to (S)MEMCPY(). - - 2007-05-08 Simon Goldschmidt - * mem.h: If MEM_LIBC_MALLOC==1, allow the defines (e.g. mem_malloc() -> malloc()) - to be overriden in case the C-library malloc implementation is not protected - against concurrent access. - - 2007-05-04 Simon Goldschmidt (Atte Kojo) - * etharp.c: Introduced fast one-entry-cache to speed up ARP lookup when sending - multiple packets to the same host. - - 2007-05-04 Frédéric Bernon, Jonathan Larmour - * sockets.c, api.h, api_lib.c, api_msg.h, api_msg.c: Fix bug #19162 "lwip_sento: a possible - to corrupt remote addr/port connection state". Reduce problems "not enought memory" with - netbuf (if we receive lot of datagrams). Improve lwip_sendto (only one exchange between - sockets api and api_msg which run in tcpip_thread context). Add netconn_sento function. - Warning, if you directly access to "fromaddr" & "fromport" field from netbuf struct, - these fields are now renamed "addr" & "port". - - 2007-04-11 Jonathan Larmour - * sys.h, api_lib.c: Provide new sys_mbox_tryfetch function. Require ports to provide new - sys_arch_mbox_tryfetch function to get a message if one is there, otherwise return - with SYS_MBOX_EMPTY. sys_arch_mbox_tryfetch can be implemented as a function-like macro - by the port in sys_arch.h if desired. - - 2007-04-06 Frédéric Bernon, Simon Goldschmidt - * opt.h, tcpip.h, tcpip.c, netifapi.h, netifapi.c: New configuration option LWIP_NETIF_API - allow to use thread-safe functions to add/remove netif in list, and to start/stop dhcp - clients, using new functions from netifapi.h. Disable as default (no port change to do). - - 2007-04-05 Frédéric Bernon - * sockets.c: remplace ENOBUFS errors on alloc_socket by ENFILE to be more BSD compliant. - - 2007-04-04 Simon Goldschmidt - * arch.h, api_msg.c, dhcp.c, msg_in.c, sockets.c: Introduced #define LWIP_UNUSED_ARG(x) - use this for and architecture-independent form to tell the compiler you intentionally - are not using this variable. Can be overriden in cc.h. - - 2007-03-28 Frédéric Bernon - * opt.h, netif.h, dhcp.h, dhcp.c: New configuration option LWIP_NETIF_HOSTNAME allow to - define a hostname in netif struct (this is just a pointer, so, you can use a hardcoded - string, point on one of your's ethernetif field, or alloc a string you will free yourself). - It will be used by DHCP to register a client hostname, but can also be use when you call - snmp_set_sysname. - - 2007-03-28 Frédéric Bernon - * netif.h, netif.c: A new NETIF_FLAG_ETHARP flag is defined in netif.h, to allow to - initialize a network interface's flag with. It tell this interface is an ethernet - device, and we can use ARP with it to do a "gratuitous ARP" (RFC 3220 "IP Mobility - Support for IPv4" section 4.6) when interface is "up" with netif_set_up(). - - 2007-03-26 Frédéric Bernon, Jonathan Larmour - * opt.h, tcpip.c: New configuration option LWIP_ARP allow to disable ARP init at build - time if you only use PPP or SLIP. The default is enable. Note we don't have to call - etharp_init in your port's initilization sequence if you use tcpip.c, because this call - is done in tcpip_init function. - - 2007-03-22 Frédéric Bernon - * stats.h, stats.c, msg_in.c: Stats counters can be change to u32_t if necessary with the - new option LWIP_STATS_LARGE. If you need this option, define LWIP_STATS_LARGE to 1 in - your lwipopts.h. More, unused counters are not defined in the stats structs, and not - display by stats_display(). Note that some options (SYS_STATS and RAW_STATS) are defined - but never used. Fix msg_in.c with the correct #if test for a stat display. - - 2007-03-21 Kieran Mansley - * netif.c, netif.h: Apply patch#4197 with some changes (originator: rireland@hmgsl.com). - Provides callback on netif up/down state change. - - 2007-03-11 Frédéric Bernon, Mace Gael, Steve Reynolds - * sockets.h, sockets.c, api.h, api_lib.c, api_msg.h, api_msg.c, igmp.h, igmp.c, - ip.c, netif.h, tcpip.c, opt.h: - New configuration option LWIP_IGMP to enable IGMP processing. Based on only one - filter per all network interfaces. Declare a new function in netif to enable to - control the MAC filter (to reduce lwIP traffic processing). - - 2007-03-11 Frédéric Bernon - * tcp.h, tcp.c, sockets.c, tcp_out.c, tcp_in.c, opt.h: Keepalive values can - be configured at run time with LWIP_TCP_KEEPALIVE, but don't change this - unless you know what you're doing (default are RFC1122 compliant). Note - that TCP_KEEPIDLE and TCP_KEEPINTVL have to be set in seconds. - - 2007-03-08 Frédéric Bernon - * tcp.h: Keepalive values can be configured at compile time, but don't change - this unless you know what you're doing (default are RFC1122 compliant). - - 2007-03-08 Frédéric Bernon - * sockets.c, api.h, api_lib.c, tcpip.c, sys.h, sys.c, err.c, opt.h: - Implement LWIP_SO_RCVTIMEO configuration option to enable/disable SO_RCVTIMEO - on UDP sockets/netconn. - - 2007-03-08 Simon Goldschmidt - * snmp_msg.h, msg_in.c: SNMP UDP ports can be configured at compile time. - - 2007-03-06 Frédéric Bernon - * api.h, api_lib.c, sockets.h, sockets.c, tcpip.c, sys.h, sys.c, err.h: - Implement SO_RCVTIMEO on UDP sockets/netconn. - - 2007-02-28 Kieran Mansley (based on patch from Simon Goldschmidt) - * api_lib.c, tcpip.c, memp.c, memp.h: make API msg structs allocated - on the stack and remove the API msg type from memp - - 2007-02-26 Jonathan Larmour (based on patch from Simon Goldschmidt) - * sockets.h, sockets.c: Move socket initialization to new - lwip_socket_init() function. - NOTE: this changes the API with ports. Ports will have to be - updated to call lwip_socket_init() now. - - 2007-02-26 Jonathan Larmour (based on patch from Simon Goldschmidt) - * api_lib.c: Use memcpy in netbuf_copy_partial. - - - ++ Bug fixes: - - 2008-03-17 Frédéric Bernon, Ed Kerekes - * igmp.h, igmp.c: Fix bug #22613 "IGMP iphdr problem" (could have - some problems to fill the IP header on some targets, use now the - ip.h macros to do it). - - 2008-03-13 Frédéric Bernon - * sockets.c: Fix bug #22435 "lwip_recvfrom with TCP break;". Using - (lwip_)recvfrom with valid "from" and "fromlen" parameters, on a - TCP connection caused a crash. Note that using (lwip_)recvfrom - like this is a bit slow and that using (lwip)getpeername is the - good lwip way to do it (so, using recv is faster on tcp sockets). - - 2008-03-12 Frédéric Bernon, Jonathan Larmour - * api_msg.c, contrib/apps/ping.c: Fix bug #22530 "api_msg.c's - recv_raw() does not consume data", and the ping sample (with - LWIP_SOCKET=1, the code did the wrong supposition that lwip_recvfrom - returned the IP payload, without the IP header). - - 2008-03-04 Jonathan Larmour - * mem.c, stats.c, mem.h: apply patch #6414 to avoid compiler errors - and/or warnings on some systems where mem_size_t and size_t differ. - * pbuf.c, ppp.c: Fix warnings on some systems with mem_malloc. - - 2008-03-04 Kieran Mansley (contributions by others) - * Numerous small compiler error/warning fixes from contributions to - mailing list after 1.3.0 release candidate made. - - 2008-01-25 Cui hengbin (integrated by Frédéric Bernon) - * dns.c: Fix bug #22108 "DNS problem" caused by unaligned structures. - - 2008-01-15 Kieran Mansley - * tcp_out.c: BUG20511. Modify persist timer to start when we are - prevented from sending by a small send window, not just a zero - send window. - - 2008-01-09 Jonathan Larmour - * opt.h, ip.c: Rename IP_OPTIONS define to IP_OPTIONS_ALLOWED to avoid - conflict with Linux system headers. - - 2008-01-06 Jonathan Larmour - * dhcp.c: fix bug #19927: "DHCP NACK problem" by clearing any existing set IP - address entirely on receiving a DHCPNAK, and restarting discovery. - - 2007-12-21 Simon Goldschmidt - * sys.h, api_lib.c, api_msg.c, sockets.c: fix bug #21698: "netconn->recv_avail - is not protected" by using new macros for interlocked access to modify/test - netconn->recv_avail. - - 2007-12-20 Kieran Mansley (based on patch from Oleg Tyshev) - * tcp_in.c: fix bug# 21535 (nrtx not reset correctly in SYN_SENT state) - - 2007-12-20 Kieran Mansley (based on patch from Per-Henrik Lundbolm) - * tcp.c, tcp_in.c, tcp_out.c, tcp.h: fix bug #20199 (better handling - of silly window avoidance and prevent lwIP from shrinking the window) - - 2007-12-04 Simon Goldschmidt - * tcp.c, tcp_in.c: fix bug #21699 (segment leak in ooseq processing when last - data packet was lost): add assert that all segment lists are empty in - tcp_pcb_remove before setting pcb to CLOSED state; don't directly set CLOSED - state from LAST_ACK in tcp_process - - 2007-12-02 Simon Goldschmidt - * sockets.h: fix bug #21654: exclude definition of struct timeval from #ifndef FD_SET - If including for system-struct timeval, LWIP_TIMEVAL_PRIVATE now - has to be set to 0 in lwipopts.h - - 2007-12-02 Simon Goldschmidt - * api_msg.c, api_lib.c: fix bug #21656 (recvmbox problem in netconn API): always - allocate a recvmbox in netconn_new_with_proto_and_callback. For a tcp-listen - netconn, this recvmbox is later freed and a new mbox is allocated for acceptmbox. - This is a fix for thread-safety and allocates all items needed for a netconn - when the netconn is created. - - 2007-11-30 Simon Goldschmidt - * udp.c: first attempt to fix bug #21655 (DHCP doesn't work reliably with multiple - netifs): if LWIP_DHCP is enabled, UDP packets to DHCP_CLIENT_PORT are passed - to netif->dhcp->pcb only (if that exists) and not to any other pcb for the same - port (only solution to let UDP pcbs 'bind' to a netif instead of an IP address) - - 2007-11-27 Simon Goldschmidt - * ip.c: fixed bug #21643 (udp_send/raw_send don't fail if netif is down) by - letting ip_route only use netifs that are up. - - 2007-11-27 Simon Goldschmidt - * err.h, api_lib.c, api_msg.c, sockets.c: Changed error handling: ERR_MEM, ERR_BUF - and ERR_RTE are seen as non-fatal, all other errors are fatal. netconns and - sockets block most operations once they have seen a fatal error. - - 2007-11-27 Simon Goldschmidt - * udp.h, udp.c, dhcp.c: Implemented new function udp_sendto_if which takes the - netif to send as an argument (to be able to send on netifs that are down). - - 2007-11-26 Simon Goldschmidt - * tcp_in.c: Fixed bug #21582: pcb->acked accounting can be wrong when ACKs - arrive out-of-order - - 2007-11-21 Simon Goldschmidt - * tcp.h, tcp_out.c, api_msg.c: Fixed bug #20287: tcp_output_nagle sends too early - Fixed the nagle algorithm; nagle now also works for all raw API applications - and has to be explicitly disabled with 'tcp_pcb->flags |= TF_NODELAY' - - 2007-11-12 Frédéric Bernon - * sockets.c, api.h, api_lib.c, api_msg.h, api_msg.c: Fixed bug #20900. Now, most - of the netconn_peer and netconn_addr processing is done inside tcpip_thread - context in do_getaddr. - - 2007-11-10 Simon Goldschmidt - * etharp.c: Fixed bug: assert fired when MEMP_ARP_QUEUE was empty (which can - happen any time). Now the packet simply isn't enqueued when out of memory. - - 2007-11-01 Simon Goldschmidt - * tcp.c, tcp_in.c: Fixed bug #21494: The send mss (pcb->mss) is set to 536 (or - TCP_MSS if that is smaller) as long as no MSS option is received from the - remote host. - - 2007-11-01 Simon Goldschmidt - * tcp.h, tcp.c, tcp_in.c: Fixed bug #21491: The MSS option sent (with SYN) - is now based on TCP_MSS instead of pcb->mss (on passive open now effectively - sending our configured TCP_MSS instead of the one received). - - 2007-11-01 Simon Goldschmidt - * tcp_in.c: Fixed bug #21181: On active open, the initial congestion window was - calculated based on the configured TCP_MSS, not on the MSS option received - with SYN+ACK. - - 2007-10-09 Simon Goldschmidt - * udp.c, inet.c, inet.h: Fixed UDPLite: send: Checksum was always generated too - short and also was generated wrong if checksum coverage != tot_len; - receive: checksum was calculated wrong if checksum coverage != tot_len - - 2007-10-08 Simon Goldschmidt - * mem.c: lfree was not updated in mem_realloc! - - 2007-10-07 Frédéric Bernon - * sockets.c, api.h, api_lib.c: First step to fix "bug #20900 : Potential - crash error problem with netconn_peer & netconn_addr". VERY IMPORTANT: - this change cause an API breakage for netconn_addr, since a parameter - type change. Any compiler should cause an error without any changes in - yours netconn_peer calls (so, it can't be a "silent change"). It also - reduce a little bit the footprint for socket layer (lwip_getpeername & - lwip_getsockname use now a common lwip_getaddrname function since - netconn_peer & netconn_addr have the same parameters). - - 2007-09-20 Simon Goldschmidt - * tcp.c: Fixed bug #21080 (tcp_bind without check pcbs in TIME_WAIT state) - by checking tcp_tw_pcbs also - - 2007-09-19 Simon Goldschmidt - * icmp.c: Fixed bug #21107 (didn't reset IP TTL in ICMP echo replies) - - 2007-09-15 Mike Kleshov - * mem.c: Fixed bug #21077 (inaccuracy in calculation of lwip_stat.mem.used) - - 2007-09-06 Frédéric Bernon - * several-files: replace some #include "arch/cc.h" by "lwip/arch.h", or simply remove - it as long as "lwip/opt.h" is included before (this one include "lwip/debug.h" which - already include "lwip/arch.h"). Like that, default defines are provided by "lwip/arch.h" - if they are not defined in cc.h, in the same spirit than "lwip/opt.h" for lwipopts.h. - - 2007-08-30 Frédéric Bernon - * igmp.h, igmp.c: Some changes to remove some redundant code, add some traces, - and fix some coding style. - - 2007-08-28 Frédéric Bernon - * tcpip.c: Fix TCPIP_MSG_INPKT processing: now, tcpip_input can be used for any - kind of packets. These packets are considered like Ethernet packets (payload - pointing to ethhdr) if the netif got the NETIF_FLAG_ETHARP flag. Else, packets - are considered like IP packets (payload pointing to iphdr). - - 2007-08-27 Frédéric Bernon - * api.h, api_lib.c, api_msg.c: First fix for "bug #20900 : Potential crash error - problem with netconn_peer & netconn_addr". Introduce NETCONN_LISTEN netconn_state - and remove obsolete ones (NETCONN_RECV & NETCONN_ACCEPT). - - 2007-08-24 Kieran Mansley - * inet.c Modify (acc >> 16) test to ((acc >> 16) != 0) to help buggy - compiler (Paradigm C++) - - 2007-08-09 Frédéric Bernon, Bill Florac - * stats.h, stats.c, igmp.h, igmp.c, opt.h: Fix for bug #20503 : IGMP Improvement. - Introduce IGMP_STATS to centralize statistics management. - - 2007-08-09 Frédéric Bernon, Bill Florac - * udp.c: Fix for bug #20503 : IGMP Improvement. Enable to receive a multicast - packet on a udp pcb binded on an netif's IP address, and not on "any". - - 2007-08-09 Frédéric Bernon, Bill Florac - * igmp.h, igmp.c, ip.c: Fix minor changes from bug #20503 : IGMP Improvement. - This is mainly on using lookup/lookfor, and some coding styles... - - 2007-07-26 Frédéric Bernon (and "thedoctor") - * igmp.c: Fix bug #20595 to accept IGMPv3 "Query" messages. - - 2007-07-25 Simon Goldschmidt - * api_msg.c, tcp.c: Another fix for bug #20021: by not returning an error if - tcp_output fails in tcp_close, the code in do_close_internal gets simpler - (tcp_output is called again later from tcp timers). - - 2007-07-25 Simon Goldschmidt - * ip_frag.c: Fixed bug #20429: use the new pbuf_copy_partial instead of the old - copy_from_pbuf, which illegally modified the given pbuf. - - 2007-07-25 Simon Goldschmidt - * tcp_out.c: tcp_enqueue: pcb->snd_queuelen didn't work for chaine PBUF_RAMs: - changed snd_queuelen++ to snd_queuelen += pbuf_clen(p). - - 2007-07-24 Simon Goldschmidt - * api_msg.c, tcp.c: Fix bug #20480: Check the pcb passed to tcp_listen() for the - correct state (must be CLOSED). - - 2007-07-13 Thomas Taranowski (commited by Jared Grubb) - * memp.c: Fix bug #20478: memp_malloc returned NULL+MEMP_SIZE on failed - allocation. It now returns NULL. - - 2007-07-13 Frédéric Bernon - * api_msg.c: Fix bug #20318: api_msg "recv" callbacks don't call pbuf_free in - all error cases. - - 2007-07-13 Frédéric Bernon - * api_msg.c: Fix bug #20315: possible memory leak problem if tcp_listen failed, - because current code doesn't follow rawapi.txt documentation. - - 2007-07-13 Kieran Mansley - * src/core/tcp_in.c Apply patch#5741 from Oleg Tyshev to fix bug in - out of sequence processing of received packets - - 2007-07-03 Simon Goldschmidt - * nearly-all-files: Added assertions where PBUF_RAM pbufs are used and an - assumption is made that this pbuf is in one piece (i.e. not chained). These - assumptions clash with the possibility of converting to fully pool-based - pbuf implementations, where PBUF_RAM pbufs might be chained. - - 2007-07-03 Simon Goldschmidt - * api.h, api_lib.c, api_msg.c: Final fix for bug #20021 and some other problems - when closing tcp netconns: removed conn->sem, less context switches when - closing, both netconn_close and netconn_delete should safely close tcp - connections. - - 2007-07-02 Simon Goldschmidt - * ipv4/ip.h, ipv6/ip.h, opt.h, netif.h, etharp.h, ipv4/ip.c, netif.c, raw.c, - tcp_out.c, udp.c, etharp.c: Added option LWIP_NETIF_HWADDRHINT (default=off) - to cache ARP table indices with each pcb instead of single-entry cache for - the complete stack. - - 2007-07-02 Simon Goldschmidt - * tcp.h, tcp.c, tcp_in.c, tcp_out.c: Added some ASSERTS and casts to prevent - warnings when assigning to smaller types. - - 2007-06-28 Simon Goldschmidt - * tcp_out.c: Added check to prevent tcp_pcb->snd_queuelen from overflowing. - - 2007-06-28 Simon Goldschmidt - * tcp.h: Fixed bug #20287: Fixed nagle algorithm (sending was done too early if - a segment contained chained pbufs) - - 2007-06-28 Frédéric Bernon - * autoip.c: replace most of rand() calls by a macro LWIP_AUTOIP_RAND which compute - a "pseudo-random" value based on netif's MAC and some autoip fields. It's always - possible to define this macro in your own lwipopts.h to always use C library's - rand(). Note that autoip_create_rand_addr doesn't use this macro. - - 2007-06-28 Frédéric Bernon - * netifapi.h, netifapi.c, tcpip.h, tcpip.c: Update code to handle the option - LWIP_TCPIP_CORE_LOCKING, and do some changes to be coherent with last modifications - in api_lib/api_msg (use pointers and not type with table, etc...) - - 2007-06-26 Simon Goldschmidt - * udp.h: Fixed bug #20259: struct udp_hdr was lacking the packin defines. - - 2007-06-25 Simon Goldschmidt - * udp.c: Fixed bug #20253: icmp_dest_unreach was called with a wrong p->payload - for udp packets with no matching pcb. - - 2007-06-25 Simon Goldschmidt - * udp.c: Fixed bug #20220: UDP PCB search in udp_input(): a non-local match - could get udp input packets if the remote side matched. - - 2007-06-13 Simon Goldschmidt - * netif.c: Fixed bug #20180 (TCP pcbs listening on IP_ADDR_ANY could get - changed in netif_set_ipaddr if previous netif->ip_addr.addr was 0. - - 2007-06-13 Simon Goldschmidt - * api_msg.c: pcb_new sets conn->err if protocol is not implemented - -> netconn_new_..() does not allocate a new connection for unsupported - protocols. - - 2007-06-13 Frédéric Bernon, Simon Goldschmidt - * api_lib.c: change return expression in netconn_addr and netconn_peer, because - conn->err was reset to ERR_OK without any reasons (and error was lost)... - - 2007-06-13 Frédéric Bernon, Matthias Weisser - * opt.h, mem.h, mem.c, memp.c, pbuf.c, ip_frag.c, vj.c: Fix bug #20162. Rename - MEM_ALIGN in LWIP_MEM_ALIGN and MEM_ALIGN_SIZE in LWIP_MEM_ALIGN_SIZE to avoid - some macro names collision with some OS macros. - - 2007-06-11 Simon Goldschmidt - * udp.c: UDP Lite: corrected the use of chksum_len (based on RFC3828: if it's 0, - create checksum over the complete packet. On RX, if it's < 8 (and not 0), - discard the packet. Also removed the duplicate 'udphdr->chksum = 0' for both - UDP & UDP Lite. - - 2007-06-11 Srinivas Gollakota & Oleg Tyshev - * tcp_out.c: Fix for bug #20075 : "A problem with keep-alive timer and TCP flags" - where TCP flags wasn't initialized in tcp_keepalive. - - 2007-06-03 Simon Goldschmidt - * udp.c: udp_input(): Input pbuf was not freed if pcb had no recv function - registered, p->payload was modified without modifying p->len if sending - icmp_dest_unreach() (had no negative effect but was definitively wrong). - - 2007-06-03 Simon Goldschmidt - * icmp.c: Corrected bug #19937: For responding to an icmp echo request, icmp - re-used the input pbuf even if that didn't have enough space to include the - link headers. Now the space is tested and a new pbuf is allocated for the - echo response packet if the echo request pbuf isn't big enough. - - 2007-06-01 Simon Goldschmidt - * sockets.c: Checked in patch #5914: Moved sockopt processing into tcpip_thread. - - 2007-05-23 Frédéric Bernon - * api_lib.c, sockets.c: Fixed bug #5958 for netconn_listen (acceptmbox only - allocated by do_listen if success) and netconn_accept errors handling. In - most of api_lib functions, we replace some errors checkings like "if (conn==NULL)" - by ASSERT, except for netconn_delete. - - 2007-05-23 Frédéric Bernon - * api_lib.c: Fixed bug #5957 "Safe-thread problem inside netconn_recv" to return - an error code if it's impossible to fetch a pbuf on a TCP connection (and not - directly close the recvmbox). - - 2007-05-22 Simon Goldschmidt - * tcp.c: Fixed bug #1895 (tcp_bind not correct) by introducing a list of - bound but unconnected (and non-listening) tcp_pcbs. - - 2007-05-22 Frédéric Bernon - * sys.h, sys.c, api_lib.c, tcpip.c: remove sys_mbox_fetch_timeout() (was only - used for LWIP_SO_RCVTIMEO option) and use sys_arch_mbox_fetch() instead of - sys_mbox_fetch() in api files. Now, users SHOULD NOT use internal lwIP features - like "sys_timeout" in their application threads. - - 2007-05-22 Frédéric Bernon - * api.h, api_lib.c, api_msg.h, api_msg.c: change the struct api_msg_msg to see - which parameters are used by which do_xxx function, and to avoid "misusing" - parameters (patch #5938). - - 2007-05-22 Simon Goldschmidt - * api_lib.c, api_msg.c, raw.c, api.h, api_msg.h, raw.h: Included patch #5938: - changed raw_pcb.protocol from u16_t to u8_t since for IPv4 and IPv6, proto - is only 8 bits wide. This affects the api, as there, the protocol was - u16_t, too. - - 2007-05-18 Simon Goldschmidt - * memp.c: addition to patch #5913: smaller pointer was returned but - memp_memory was the same size -> did not save memory. - - 2007-05-16 Simon Goldschmidt - * loopif.c, slipif.c: Fix bug #19729: free pbuf if netif->input() returns - != ERR_OK. - - 2007-05-16 Simon Goldschmidt - * api_msg.c, udp.c: If a udp_pcb has a local_ip set, check if it is the same - as the one of the netif used for sending to prevent sending from old - addresses after a netif address gets changed (partly fixes bug #3168). - - 2007-05-16 Frédéric Bernon - * tcpip.c, igmp.h, igmp.c: Fixed bug "#19800 : IGMP: igmp_tick() will not work - with NO_SYS=1". Note that igmp_init is always in tcpip_thread (and not in - tcpip_init) because we have to be sure that network interfaces are already - added (mac filter is updated only in igmp_init for the moment). - - 2007-05-16 Simon Goldschmidt - * mem.c, memp.c: Removed semaphores from memp, changed sys_sem_wait calls - into sys_arch_sem_wait calls to prevent timers from running while waiting - for the heap. This fixes bug #19167. - - 2007-05-13 Simon Goldschmidt - * tcp.h, sockets.h, sockets.c: Fixed bug from patch #5865 by moving the defines - for socket options (lwip_set/-getsockopt) used with level IPPROTO_TCP from - tcp.h to sockets.h. - - 2007-05-07 Simon Goldschmidt - * mem.c: Another attempt to fix bug #17922. - - 2007-05-04 Simon Goldschmidt - * pbuf.c, pbuf.h, etharp.c: Further update to ARP queueing: Changed pbuf_copy() - implementation so that it can be reused (don't allocate the target - pbuf inside pbuf_copy()). - - 2007-05-04 Simon Goldschmidt - * memp.c: checked in patch #5913: in memp_malloc() we can return memp as mem - to save a little RAM (next pointer of memp is not used while not in pool). - - 2007-05-03 "maq" - * sockets.c: Fix ioctl FIONREAD when some data remains from last recv. - (patch #3574). - - 2007-04-23 Simon Goldschmidt - * loopif.c, loopif.h, opt.h, src/netif/FILES: fix bug #2595: "loopif results - in NULL reference for incoming TCP packets". Loopif has to be configured - (using LWIP_LOOPIF_MULTITHREADING) to directly call netif->input() - (multithreading environments, e.g. netif->input() = tcpip_input()) or - putting packets on a list that is fed to the stack by calling loopif_poll() - (single-thread / NO_SYS / polling environment where e.g. - netif->input() = ip_input). - - 2007-04-17 Jonathan Larmour - * pbuf.c: Use s32_t in pbuf_realloc(), as an s16_t can't reliably hold - the difference between two u16_t's. - * sockets.h: FD_SETSIZE needs to match number of sockets, which is - MEMP_NUM_NETCONN in sockets.c right now. - - 2007-04-12 Jonathan Larmour - * icmp.c: Reset IP header TTL in ICMP ECHO responses (bug #19580). - - 2007-04-12 Kieran Mansley - * tcp.c, tcp_in.c, tcp_out.c, tcp.h: Modify way the retransmission - timer is reset to fix bug#19434, with help from Oleg Tyshev. - - 2007-04-11 Simon Goldschmidt - * etharp.c, pbuf.c, pbuf.h: 3rd fix for bug #11400 (arp-queuing): More pbufs than - previously thought need to be copied (everything but PBUF_ROM!). Cleaned up - pbuf.c: removed functions no needed any more (by etharp). - - 2007-04-11 Kieran Mansley - * inet.c, ip_addr.h, sockets.h, sys.h, tcp.h: Apply patch #5745: Fix - "Constant is long" warnings with 16bit compilers. Contributed by - avatar@mmlab.cse.yzu.edu.tw - - 2007-04-05 Frédéric Bernon, Jonathan Larmour - * api_msg.c: Fix bug #16830: "err_tcp() posts to connection mailbox when no pend on - the mailbox is active". Now, the post is only done during a connect, and do_send, - do_write and do_join_leave_group don't do anything if a previous error was signaled. - - 2007-04-03 Frédéric Bernon - * ip.c: Don't set the IP_DF ("Don't fragment") flag in the IP header in IP output - packets. See patch #5834. - - 2007-03-30 Frédéric Bernon - * api_msg.c: add a "pcb_new" helper function to avoid redundant code, and to add - missing pcb allocations checking (in do_bind, and for each raw_new). Fix style. - - 2007-03-30 Frédéric Bernon - * most of files: prefix all debug.h define with "LWIP_" to avoid any conflict with - others environment defines (these were too "generic"). - - 2007-03-28 Frédéric Bernon - * api.h, api_lib.c, sockets.c: netbuf_ref doesn't check its internal pbuf_alloc call - result and can cause a crash. lwip_send now check netbuf_ref result. - - 2007-03-28 Simon Goldschmidt - * sockets.c Remove "#include " from sockets.c to avoid multiple - definition of macros (in errno.h and lwip/arch.h) if LWIP_PROVIDE_ERRNO is - defined. This is the way it should have been already (looking at - doc/sys_arch.txt) - - 2007-03-28 Kieran Mansley - * opt.h Change default PBUF_POOL_BUFSIZE (again) to accomodate default MSS + - IP and TCP headers *and* physical link headers - - 2007-03-26 Frédéric Bernon (based on patch from Dmitry Potapov) - * api_lib.c: patch for netconn_write(), fixes a possible race condition which cause - to send some garbage. It is not a definitive solution, but the patch does solve - the problem for most cases. - - 2007-03-22 Frédéric Bernon - * api_msg.h, api_msg.c: Remove obsolete API_MSG_ACCEPT and do_accept (never used). - - 2007-03-22 Frédéric Bernon - * api_lib.c: somes resources couldn't be freed if there was errors during - netconn_new_with_proto_and_callback. - - 2007-03-22 Frédéric Bernon - * ethernetif.c: update netif->input calls to check return value. In older ports, - it's a good idea to upgrade them, even if before, there could be another problem - (access to an uninitialized mailbox). - - 2007-03-21 Simon Goldschmidt - * sockets.c: fixed bug #5067 (essentialy a signed/unsigned warning fixed - by casting to unsigned). - - 2007-03-21 Frédéric Bernon - * api_lib.c, api_msg.c, tcpip.c: integrate sys_mbox_fetch(conn->mbox, NULL) calls from - api_lib.c to tcpip.c's tcpip_apimsg(). Now, use a local variable and not a - dynamic one from memp to send tcpip_msg to tcpip_thread in a synchrone call. - Free tcpip_msg from tcpip_apimsg is not done in tcpip_thread. This give a - faster and more reliable communication between api_lib and tcpip. - - 2007-03-21 Frédéric Bernon - * opt.h: Add LWIP_NETIF_CALLBACK (to avoid compiler warning) and set it to 0. - - 2007-03-21 Frédéric Bernon - * api_msg.c, igmp.c, igmp.h: Fix C++ style comments - - 2007-03-21 Kieran Mansley - * opt.h Change default PBUF_POOL_BUFSIZE to accomodate default MSS + - IP and TCP headers - - 2007-03-21 Kieran Mansley - * Fix all uses of pbuf_header to check the return value. In some - cases just assert if it fails as I'm not sure how to fix them, but - this is no worse than before when they would carry on regardless - of the failure. - - 2007-03-21 Kieran Mansley - * sockets.c, igmp.c, igmp.h, memp.h: Fix C++ style comments and - comment out missing header include in icmp.c - - 2007-03-20 Frédéric Bernon - * memp.h, stats.c: Fix stats_display function where memp_names table wasn't - synchronized with memp.h. - - 2007-03-20 Frédéric Bernon - * tcpip.c: Initialize tcpip's mbox, and verify if initialized in tcpip_input, - tcpip_ethinput, tcpip_callback, tcpip_apimsg, to fix a init problem with - network interfaces. Also fix a compiler warning. - - 2007-03-20 Kieran Mansley - * udp.c: Only try and use pbuf_header() to make space for headers if - not a ROM or REF pbuf. - - 2007-03-19 Frédéric Bernon - * api_msg.h, api_msg.c, tcpip.h, tcpip.c: Add return types to tcpip_apimsg() - and api_msg_post(). - - 2007-03-19 Frédéric Bernon - * Remove unimplemented "memp_realloc" function from memp.h. - - 2007-03-11 Simon Goldschmidt - * pbuf.c: checked in patch #5796: pbuf_alloc: len field claculation caused - memory corruption. - - 2007-03-11 Simon Goldschmidt (based on patch from Dmitry Potapov) - * api_lib.c, sockets.c, api.h, api_msg.h, sockets.h: Fixed bug #19251 - (missing `const' qualifier in socket functions), to get more compatible to - standard POSIX sockets. - - 2007-03-11 Frédéric Bernon (based on patch from Dmitry Potapov) - * sockets.c: Add asserts inside bind, connect and sendto to check input - parameters. Remove excessive set_errno() calls after get_socket(), because - errno is set inside of get_socket(). Move last sock_set_errno() inside - lwip_close. - - 2007-03-09 Simon Goldschmidt - * memp.c: Fixed bug #11400: New etharp queueing introduced bug: memp_memory - was allocated too small. - - 2007-03-06 Simon Goldschmidt - * tcpip.c: Initialize dhcp timers in tcpip_thread (if LWIP_DHCP) to protect - the stack from concurrent access. - - 2007-03-06 Frédéric Bernon, Dmitry Potapov - * tcpip.c, ip_frag.c, ethernetif.c: Fix some build problems, and a redundancy - call to "lwip_stats.link.recv++;" in low_level_input() & ethernetif_input(). - - 2007-03-06 Simon Goldschmidt - * ip_frag.c, ip_frag.h: Reduce code size: don't include code in those files - if IP_FRAG == 0 and IP_REASSEMBLY == 0 - - 2007-03-06 Frédéric Bernon, Simon Goldschmidt - * opt.h, ip_frag.h, tcpip.h, tcpip.c, ethernetif.c: add new configuration - option named ETHARP_TCPIP_ETHINPUT, which enable the new tcpip_ethinput. - Allow to do ARP processing for incoming packets inside tcpip_thread - (protecting ARP layer against concurrent access). You can also disable - old code using tcp_input with new define ETHARP_TCPIP_INPUT set to 0. - Older ports have to use tcpip_ethinput. - - 2007-03-06 Simon Goldschmidt (based on patch from Dmitry Potapov) - * err.h, err.c: fixed compiler warning "initialization dircards qualifiers - from pointer target type" - - 2007-03-05 Frédéric Bernon - * opt.h, sockets.h: add new configuration options (LWIP_POSIX_SOCKETS_IO_NAMES, - ETHARP_TRUST_IP_MAC, review SO_REUSE) - - 2007-03-04 Frédéric Bernon - * api_msg.c: Remove some compiler warnings : parameter "pcb" was never - referenced. - - 2007-03-04 Frédéric Bernon - * api_lib.c: Fix "[patch #5764] api_lib.c cleanup: after patch #5687" (from - Dmitry Potapov). - The api_msg struct stay on the stack (not moved to netconn struct). - - 2007-03-04 Simon Goldschmidt (based on patch from Dmitry Potapov) - * pbuf.c: Fix BUG#19168 - pbuf_free can cause deadlock (if - SYS_LIGHTWEIGHT_PROT=1 & freeing PBUF_RAM when mem_sem is not available) - Also fixed cast warning in pbuf_alloc() - - 2007-03-04 Simon Goldschmidt - * etharp.c, etharp.h, memp.c, memp.h, opt.h: Fix BUG#11400 - don't corrupt - existing pbuf chain when enqueuing multiple pbufs to a pending ARP request - - 2007-03-03 Frédéric Bernon - * udp.c: remove obsolete line "static struct udp_pcb *pcb_cache = NULL;" - It is static, and never used in udp.c except udp_init(). - - 2007-03-02 Simon Goldschmidt - * tcpip.c: Moved call to ip_init(), udp_init() and tcp_init() from - tcpip_thread() to tcpip_init(). This way, raw API connections can be - initialized before tcpip_thread is running (e.g. before OS is started) - - 2007-03-02 Frédéric Bernon - * rawapi.txt: Fix documentation mismatch with etharp.h about etharp_tmr's call - interval. - - 2007-02-28 Kieran Mansley - * pbuf.c: Fix BUG#17645 - ensure pbuf payload pointer is not moved - outside the region of the pbuf by pbuf_header() - - 2007-02-28 Kieran Mansley - * sockets.c: Fix BUG#19161 - ensure milliseconds timeout is non-zero - when supplied timeout is also non-zero - -(STABLE-1.2.0) - - 2006-12-05 Leon Woestenberg - * CHANGELOG: Mention STABLE-1.2.0 release. - - ++ New features: - - 2006-12-01 Christiaan Simons - * mem.h, opt.h: Added MEM_LIBC_MALLOC option. - Note this is a workaround. Currently I have no other options left. - - 2006-10-26 Christiaan Simons (accepted patch by Jonathan Larmour) - * ipv4/ip_frag.c: rename MAX_MTU to IP_FRAG_MAX_MTU and move define - to include/lwip/opt.h. - * ipv4/lwip/ip_frag.h: Remove unused IP_REASS_INTERVAL. - Move IP_REASS_MAXAGE and IP_REASS_BUFSIZE to include/lwip/opt.h. - * opt.h: Add above new options. - - 2006-08-18 Christiaan Simons - * tcp_{in,out}.c: added SNMP counters. - * ipv4/ip.c: added SNMP counters. - * ipv4/ip_frag.c: added SNMP counters. - - 2006-08-08 Christiaan Simons - * etharp.{c,h}: added etharp_find_addr() to read - (stable) ethernet/IP address pair from ARP table - - 2006-07-14 Christiaan Simons - * mib_structs.c: added - * include/lwip/snmp_structs.h: added - * netif.{c,h}, netif/ethernetif.c: added SNMP statistics to netif struct - - 2006-07-06 Christiaan Simons - * snmp/asn1_{enc,dec}.c added - * snmp/mib2.c added - * snmp/msg_{in,out}.c added - * include/lwip/snmp_asn1.h added - * include/lwip/snmp_msg.h added - * doc/snmp_agent.txt added - - 2006-03-29 Christiaan Simons - * inet.c, inet.h: Added platform byteswap support. - Added LWIP_PLATFORM_BYTESWAP define (defaults to 0) and - optional LWIP_PLATFORM_HTONS(), LWIP_PLATFORM_HTONL() macros. - - ++ Bug fixes: - - 2006-11-30 Christiaan Simons - * dhcp.c: Fixed false triggers of request_timeout. - - 2006-11-28 Christiaan Simons - * netif.c: In netif_add() fixed missing clear of ip_addr, netmask, gw and flags. - - 2006-10-11 Christiaan Simons - * api_lib.c etharp.c, ip.c, memp.c, stats.c, sys.{c,h} tcp.h: - Partially accepted patch #5449 for ANSI C compatibility / build fixes. - * ipv4/lwip/ip.h ipv6/lwip/ip.h: Corrected UDP-Lite protocol - identifier from 170 to 136 (bug #17574). - - 2006-10-10 Christiaan Simons - * api_msg.c: Fixed Nagle algorithm as reported by Bob Grice. - - 2006-08-17 Christiaan Simons - * udp.c: Fixed bug #17200, added check for broadcast - destinations for PCBs bound to a unicast address. - - 2006-08-07 Christiaan Simons - * api_msg.c: Flushing TCP output in do_close() (bug #15926). - - 2006-06-27 Christiaan Simons - * api_msg.c: Applied patch for cold case (bug #11135). - In accept_function() ensure newconn->callback is always initialized. - - 2006-06-15 Christiaan Simons - * mem.h: added MEM_SIZE_F alias to fix an ancient cold case (bug #1748), - facilitate printing of mem_size_t and u16_t statistics. - - 2006-06-14 Christiaan Simons - * api_msg.c: Applied patch #5146 to handle allocation failures - in accept() by Kevin Lawson. - - 2006-05-26 Christiaan Simons - * api_lib.c: Removed conn->sem creation and destruction - from netconn_write() and added sys_sem_new to netconn_new_*. - -(STABLE-1_1_1) - - 2006-03-03 Christiaan Simons - * ipv4/ip_frag.c: Added bound-checking assertions on ip_reassbitmap - access and added pbuf_alloc() return value checks. - - 2006-01-01 Leon Woestenberg - * tcp_{in,out}.c, tcp_out.c: Removed 'even sndbuf' fix in TCP, which is - now handled by the checksum routine properly. - - 2006-02-27 Leon Woestenberg - * pbuf.c: Fix alignment; pbuf_init() would not work unless - pbuf_pool_memory[] was properly aligned. (Patch by Curt McDowell.) - - 2005-12-20 Leon Woestenberg - * tcp.c: Remove PCBs which stay in LAST_ACK state too long. Patch - submitted by Mitrani Hiroshi. - - 2005-12-15 Christiaan Simons - * inet.c: Disabled the added summing routine to preserve code space. - - 2005-12-14 Leon Woestenberg - * tcp_in.c: Duplicate FIN ACK race condition fix by Kelvin Lawson. - Added Curt McDowell's optimized checksumming routine for future - inclusion. Need to create test case for unaliged, aligned, odd, - even length combination of cases on various endianess machines. - - 2005-12-09 Christiaan Simons - * inet.c: Rewrote standard checksum routine in proper portable C. - - 2005-11-25 Christiaan Simons - * udp.c tcp.c: Removed SO_REUSE hack. Should reside in socket code only. - * *.c: introduced cc.h LWIP_DEBUG formatters matching the u16_t, s16_t, - u32_t, s32_t typedefs. This solves most debug word-length assumes. - - 2005-07-17 Leon Woestenberg - * inet.c: Fixed unaligned 16-bit access in the standard checksum - routine by Peter Jolasson. - * slipif.c: Fixed implementation assumption of single-pbuf datagrams. - - 2005-02-04 Leon Woestenberg - * tcp_out.c: Fixed uninitialized 'queue' referenced in memerr branch. - * tcp_{out|in}.c: Applied patch fixing unaligned access. - - 2005-01-04 Leon Woestenberg - * pbuf.c: Fixed missing semicolon after LWIP_DEBUG statement. - - 2005-01-03 Leon Woestenberg - * udp.c: UDP pcb->recv() was called even when it was NULL. - -(STABLE-1_1_0) - - 2004-12-28 Leon Woestenberg - * etharp.*: Disabled multiple packets on the ARP queue. - This clashes with TCP queueing. - - 2004-11-28 Leon Woestenberg - * etharp.*: Fixed race condition from ARP request to ARP timeout. - Halved the ARP period, doubled the period counts. - ETHARP_MAX_PENDING now should be at least 2. This prevents - the counter from reaching 0 right away (which would allow - too little time for ARP responses to be received). - - 2004-11-25 Leon Woestenberg - * dhcp.c: Decline messages were not multicast but unicast. - * etharp.c: ETHARP_CREATE is renamed to ETHARP_TRY_HARD. - Do not try hard to insert arbitrary packet's source address, - etharp_ip_input() now calls etharp_update() without ETHARP_TRY_HARD. - etharp_query() now always DOES call ETHARP_TRY_HARD so that users - querying an address will see it appear in the cache (DHCP could - suffer from this when a server invalidly gave an in-use address.) - * ipv4/ip_addr.h: Renamed ip_addr_maskcmp() to _netcmp() as we are - comparing network addresses (identifiers), not the network masks - themselves. - * ipv4/ip_addr.c: ip_addr_isbroadcast() now checks that the given - IP address actually belongs to the network of the given interface. - - 2004-11-24 Kieran Mansley - * tcp.c: Increment pcb->snd_buf when ACK is received in SYN_SENT state. - -(STABLE-1_1_0-RC1) - - 2004-10-16 Kieran Mansley - * tcp.c: Add code to tcp_recved() to send an ACK (window update) immediately, - even if one is already pending, if the rcv_wnd is above a threshold - (currently TCP_WND/2). This avoids waiting for a timer to expire to send a - delayed ACK in order to open the window if the stack is only receiving data. - - 2004-09-12 Kieran Mansley - * tcp*.*: Retransmit time-out handling improvement by Sam Jansen. - - 2004-08-20 Tony Mountifield - * etharp.c: Make sure the first pbuf queued on an ARP entry - is properly ref counted. - - 2004-07-27 Tony Mountifield - * debug.h: Added (int) cast in LWIP_DEBUGF() to avoid compiler - warnings about comparison. - * pbuf.c: Stopped compiler complaining of empty if statement - when LWIP_DEBUGF() empty. Closed an unclosed comment. - * tcp.c: Stopped compiler complaining of empty if statement - when LWIP_DEBUGF() empty. - * ip.h Corrected IPH_TOS() macro: returns a byte, so doesn't need htons(). - * inet.c: Added a couple of casts to quiet the compiler. - No need to test isascii(c) before isdigit(c) or isxdigit(c). - - 2004-07-22 Tony Mountifield - * inet.c: Made data types consistent in inet_ntoa(). - Added casts for return values of checksum routines, to pacify compiler. - * ip_frag.c, tcp_out.c, sockets.c, pbuf.c - Small corrections to some debugging statements, to pacify compiler. - - 2004-07-21 Tony Mountifield - * etharp.c: Removed spurious semicolon and added missing end-of-comment. - * ethernetif.c Updated low_level_output() to match prototype for - netif->linkoutput and changed low_level_input() similarly for consistency. - * api_msg.c: Changed recv_raw() from int to u8_t, to match prototype - of raw_recv() in raw.h and so avoid compiler error. - * sockets.c: Added trivial (int) cast to keep compiler happier. - * ip.c, netif.c Changed debug statements to use the tidier ip4_addrN() macros. - -(STABLE-1_0_0) - - ++ Changes: - - 2004-07-05 Leon Woestenberg - * sockets.*: Restructured LWIP_PRIVATE_TIMEVAL. Make sure - your cc.h file defines this either 1 or 0. If non-defined, - defaults to 1. - * .c: Added and includes where used. - * etharp.c: Made some array indices unsigned. - - 2004-06-27 Leon Woestenberg - * netif.*: Added netif_set_up()/down(). - * dhcp.c: Changes to restart program flow. - - 2004-05-07 Leon Woestenberg - * etharp.c: In find_entry(), instead of a list traversal per candidate, do a - single-pass lookup for different candidates. Should exploit locality. - - 2004-04-29 Leon Woestenberg - * tcp*.c: Cleaned up source comment documentation for Doxygen processing. - * opt.h: ETHARP_ALWAYS_INSERT option removed to comply with ARP RFC. - * etharp.c: update_arp_entry() only adds new ARP entries when adviced to by - the caller. This deprecates the ETHARP_ALWAYS_INSERT overrule option. - - ++ Bug fixes: - - 2004-04-27 Leon Woestenberg - * etharp.c: Applied patch of bug #8708 by Toni Mountifield with a solution - suggested by Timmy Brolin. Fix for 32-bit processors that cannot access - non-aligned 32-bit words, such as soms 32-bit TCP/IP header fields. Fix - is to prefix the 14-bit Ethernet headers with two padding bytes. - - 2004-04-23 Leon Woestenberg - * ip_addr.c: Fix in the ip_addr_isbroadcast() check. - * etharp.c: Fixed the case where the packet that initiates the ARP request - is not queued, and gets lost. Fixed the case where the packets destination - address is already known; we now always queue the packet and perform an ARP - request. - -(STABLE-0_7_0) - - ++ Bug fixes: - - * Fixed TCP bug for SYN_SENT to ESTABLISHED state transition. - * Fixed TCP bug in dequeueing of FIN from out of order segment queue. - * Fixed two possible NULL references in rare cases. - -(STABLE-0_6_6) - - ++ Bug fixes: - - * Fixed DHCP which did not include the IP address in DECLINE messages. - - ++ Changes: - - * etharp.c has been hauled over a bit. - -(STABLE-0_6_5) - - ++ Bug fixes: - - * Fixed TCP bug induced by bad window resizing with unidirectional TCP traffic. - * Packets sent from ARP queue had invalid source hardware address. - - ++ Changes: - - * Pass-by ARP requests do now update the cache. - - ++ New features: - - * No longer dependent on ctype.h. - * New socket options. - * Raw IP pcb support. - -(STABLE-0_6_4) - - ++ Bug fixes: - - * Some debug formatters and casts fixed. - * Numereous fixes in PPP. - - ++ Changes: - - * DEBUGF now is LWIP_DEBUGF - * pbuf_dechain() has been re-enabled. - * Mentioned the changed use of CVS branches in README. - -(STABLE-0_6_3) - - ++ Bug fixes: - - * Fixed pool pbuf memory leak in pbuf_alloc(). - Occured if not enough PBUF_POOL pbufs for a packet pbuf chain. - Reported by Savin Zlobec. - - * PBUF_POOL chains had their tot_len field not set for non-first - pbufs. Fixed in pbuf_alloc(). - - ++ New features: - - * Added PPP stack contributed by Marc Boucher - - ++ Changes: - - * Now drops short packets for ICMP/UDP/TCP protocols. More robust. - - * ARP queueuing now queues the latest packet instead of the first. - This is the RFC recommended behaviour, but can be overridden in - lwipopts.h. - -(0.6.2) - - ++ Bugfixes: - - * TCP has been fixed to deal with the new use of the pbuf->ref - counter. - - * DHCP dhcp_inform() crash bug fixed. - - ++ Changes: - - * Removed pbuf_pool_free_cache and pbuf_pool_alloc_cache. Also removed - pbuf_refresh(). This has sped up pbuf pool operations considerably. - Implemented by David Haas. - -(0.6.1) - - ++ New features: - - * The packet buffer implementation has been enhanced to support - zero-copy and copy-on-demand for packet buffers which have their - payloads in application-managed memory. - Implemented by David Haas. - - Use PBUF_REF to make a pbuf refer to RAM. lwIP will use zero-copy - if an outgoing packet can be directly sent on the link, or perform - a copy-on-demand when necessary. - - The application can safely assume the packet is sent, and the RAM - is available to the application directly after calling udp_send() - or similar function. - - ++ Bugfixes: - - * ARP_QUEUEING should now correctly work for all cases, including - PBUF_REF. - Implemented by Leon Woestenberg. - - ++ Changes: - - * IP_ADDR_ANY is no longer a NULL pointer. Instead, it is a pointer - to a '0.0.0.0' IP address. - - * The packet buffer implementation is changed. The pbuf->ref counter - meaning has changed, and several pbuf functions have been - adapted accordingly. - - * netif drivers have to be changed to set the hardware address length field - that must be initialized correctly by the driver (hint: 6 for Ethernet MAC). - See the contrib/ports/c16x cs8900 driver as a driver example. - - * netif's have a dhcp field that must be initialized to NULL by the driver. - See the contrib/ports/c16x cs8900 driver as a driver example. - -(0.5.x) This file has been unmaintained up to 0.6.1. All changes are - logged in CVS but have not been explained here. - -(0.5.3) Changes since version 0.5.2 - - ++ Bugfixes: - - * memp_malloc(MEMP_API_MSG) could fail with multiple application - threads because it wasn't protected by semaphores. - - ++ Other changes: - - * struct ip_addr now packed. - - * The name of the time variable in arp.c has been changed to ctime - to avoid conflicts with the time() function. - -(0.5.2) Changes since version 0.5.1 - - ++ New features: - - * A new TCP function, tcp_tmr(), now handles both TCP timers. - - ++ Bugfixes: - - * A bug in tcp_parseopt() could cause the stack to hang because of a - malformed TCP option. - - * The address of new connections in the accept() function in the BSD - socket library was not handled correctly. - - * pbuf_dechain() did not update the ->tot_len field of the tail. - - * Aborted TCP connections were not handled correctly in all - situations. - - ++ Other changes: - - * All protocol header structs are now packed. - - * The ->len field in the tcp_seg structure now counts the actual - amount of data, and does not add one for SYN and FIN segments. - -(0.5.1) Changes since version 0.5.0 - - ++ New features: - - * Possible to run as a user process under Linux. - - * Preliminary support for cross platform packed structs. - - * ARP timer now implemented. - - ++ Bugfixes: - - * TCP output queue length was badly initialized when opening - connections. - - * TCP delayed ACKs were not sent correctly. - - * Explicit initialization of BSS segment variables. - - * read() in BSD socket library could drop data. - - * Problems with memory alignment. - - * Situations when all TCP buffers were used could lead to - starvation. - - * TCP MSS option wasn't parsed correctly. - - * Problems with UDP checksum calculation. - - * IP multicast address tests had endianess problems. - - * ARP requests had wrong destination hardware address. - - ++ Other changes: - - * struct eth_addr changed from u16_t[3] array to u8_t[6]. - - * A ->linkoutput() member was added to struct netif. - - * TCP and UDP ->dest_* struct members where changed to ->remote_*. - - * ntoh* macros are now null definitions for big endian CPUs. - -(0.5.0) Changes since version 0.4.2 - - ++ New features: - - * Redesigned operating system emulation layer to make porting easier. - - * Better control over TCP output buffers. - - * Documenation added. - - ++ Bugfixes: - - * Locking issues in buffer management. - - * Bugfixes in the sequential API. - - * IP forwarding could cause memory leakage. This has been fixed. - - ++ Other changes: - - * Directory structure somewhat changed; the core/ tree has been - collapsed. - -(0.4.2) Changes since version 0.4.1 - - ++ New features: - - * Experimental ARP implementation added. - - * Skeleton Ethernet driver added. - - * Experimental BSD socket API library added. - - ++ Bugfixes: - - * In very intense situations, memory leakage could occur. This has - been fixed. - - ++ Other changes: - - * Variables named "data" and "code" have been renamed in order to - avoid name conflicts in certain compilers. - - * Variable++ have in appliciable cases been translated to ++variable - since some compilers generate better code in the latter case. - -(0.4.1) Changes since version 0.4 - - ++ New features: - - * TCP: Connection attempts time out earlier than data - transmissions. Nagle algorithm implemented. Push flag set on the - last segment in a burst. - - * UDP: experimental support for UDP-Lite extensions. - - ++ Bugfixes: - - * TCP: out of order segments were in some cases handled incorrectly, - and this has now been fixed. Delayed acknowledgements was broken - in 0.4, has now been fixed. Binding to an address that is in use - now results in an error. Reset connections sometimes hung an - application; this has been fixed. - - * Checksum calculation sometimes failed for chained pbufs with odd - lengths. This has been fixed. - - * API: a lot of bug fixes in the API. The UDP API has been improved - and tested. Error reporting and handling has been - improved. Logical flaws and race conditions for incoming TCP - connections has been found and removed. - - * Memory manager: alignment issues. Reallocating memory sometimes - failed, this has been fixed. - - * Generic library: bcopy was flawed and has been fixed. - - ++ Other changes: - - * API: all datatypes has been changed from generic ones such as - ints, to specified ones such as u16_t. Functions that return - errors now have the correct type (err_t). - - * General: A lot of code cleaned up and debugging code removed. Many - portability issues have been fixed. - - * The license was changed; the advertising clause was removed. - - * C64 port added. - - * Thanks: Huge thanks go to Dagan Galarneau, Horst Garnetzke, Petri - Kosunen, Mikael Caleres, and Frits Wilmink for reporting and - fixing bugs! - -(0.4) Changes since version 0.3.1 - - * Memory management has been radically changed; instead of - allocating memory from a shared heap, memory for objects that are - rapidly allocated and deallocated is now kept in pools. Allocation - and deallocation from those memory pools is very fast. The shared - heap is still present but is used less frequently. - - * The memory, memory pool, and packet buffer subsystems now support - 4-, 2-, or 1-byte alignment. - - * "Out of memory" situations are handled in a more robust way. - - * Stack usage has been reduced. - - * Easier configuration of lwIP parameters such as memory usage, - TTLs, statistics gathering, etc. All configuration parameters are - now kept in a single header file "lwipopts.h". - - * The directory structure has been changed slightly so that all - architecture specific files are kept under the src/arch - hierarchy. - - * Error propagation has been improved, both in the protocol modules - and in the API. - - * The code for the RTXC architecture has been implemented, tested - and put to use. - - * Bugs have been found and corrected in the TCP, UDP, IP, API, and - the Internet checksum modules. - - * Bugs related to porting between a 32-bit and a 16-bit architecture - have been found and corrected. - - * The license has been changed slightly to conform more with the - original BSD license, including the advertisement clause. - -(0.3.1) Changes since version 0.3 - - * Fix of a fatal bug in the buffer management. Pbufs with allocated - RAM never returned the RAM when the pbuf was deallocated. - - * TCP congestion control, window updates and retransmissions did not - work correctly. This has now been fixed. - - * Bugfixes in the API. - -(0.3) Changes since version 0.2 - - * New and improved directory structure. All include files are now - kept in a dedicated include/ directory. - - * The API now has proper error handling. A new function, - netconn_err(), now returns an error code for the connection in - case of errors. - - * Improvements in the memory management subsystem. The system now - keeps a pointer to the lowest free memory block. A new function, - mem_malloc2() tries to allocate memory once, and if it fails tries - to free some memory and retry the allocation. - - * Much testing has been done with limited memory - configurations. lwIP now does a better job when overloaded. - - * Some bugfixes and improvements to the buffer (pbuf) subsystem. - - * Many bugfixes in the TCP code: - - - Fixed a bug in tcp_close(). - - - The TCP receive window was incorrectly closed when out of - sequence segments was received. This has been fixed. - - - Connections are now timed-out of the FIN-WAIT-2 state. - - - The initial congestion window could in some cases be too - large. This has been fixed. - - - The retransmission queue could in some cases be screwed up. This - has been fixed. - - - TCP RST flag now handled correctly. - - - Out of sequence data was in some cases never delivered to the - application. This has been fixed. - - - Retransmitted segments now contain the correct acknowledgment - number and advertised window. - - - TCP retransmission timeout backoffs are not correctly computed - (ala BSD). After a number of retransmissions, TCP now gives up - the connection. - - * TCP connections now are kept on three lists, one for active - connections, one for listening connections, and one for - connections that are in TIME-WAIT. This greatly speeds up the fast - timeout processing for sending delayed ACKs. - - * TCP now provides proper feedback to the application when a - connection has been successfully set up. - - * More comments have been added to the code. The code has also been - somewhat cleaned up. - -(0.2) Initial public release. diff --git a/third_party/lwip/repo/lwip/COPYING b/third_party/lwip/repo/lwip/COPYING deleted file mode 100644 index e23898b5e8feae..00000000000000 --- a/third_party/lwip/repo/lwip/COPYING +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2001, 2002 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ - - diff --git a/third_party/lwip/repo/lwip/FILES b/third_party/lwip/repo/lwip/FILES deleted file mode 100644 index e6e09989d94849..00000000000000 --- a/third_party/lwip/repo/lwip/FILES +++ /dev/null @@ -1,5 +0,0 @@ -src/ - The source code for the lwIP TCP/IP stack. -doc/ - The documentation for lwIP. -test/ - Some code to test whether the sources do what they should. - -See also the FILES file in each subdirectory. diff --git a/third_party/lwip/repo/lwip/README b/third_party/lwip/repo/lwip/README deleted file mode 100644 index 0884d27bea5ae3..00000000000000 --- a/third_party/lwip/repo/lwip/README +++ /dev/null @@ -1,100 +0,0 @@ -INTRODUCTION - -lwIP is a small independent implementation of the TCP/IP protocol -suite that has been developed by Adam Dunkels at the Computer and -Networks Architectures (CNA) lab at the Swedish Institute of Computer -Science (SICS). - -The focus of the lwIP TCP/IP implementation is to reduce the RAM usage -while still having a full scale TCP. This making lwIP suitable for use -in embedded systems with tens of kilobytes of free RAM and room for -around 40 kilobytes of code ROM. - - -FEATURES - - * IP (Internet Protocol, IPv4 and IPv6) including packet forwarding over - multiple network interfaces - * ICMP (Internet Control Message Protocol) for network maintenance and debugging - * IGMP (Internet Group Management Protocol) for multicast traffic management - * MLD (Multicast listener discovery for IPv6). Aims to be compliant with - RFC 2710. No support for MLDv2 - * ND (Neighbor discovery and stateless address autoconfiguration for IPv6). - Aims to be compliant with RFC 4861 (Neighbor discovery) and RFC 4862 - (Address autoconfiguration) - * UDP (User Datagram Protocol) including experimental UDP-lite extensions - * TCP (Transmission Control Protocol) with congestion control, RTT estimation - and fast recovery/fast retransmit - * raw/native API for enhanced performance - * Optional Berkeley-like socket API - * DNS (Domain names resolver) - - -APPLICATIONS - - * HTTP server with SSI and CGI - * SNMPv2c agent with MIB compiler (Simple Network Management Protocol) - * SNTP (Simple network time protocol) - * NetBIOS name service responder - * MDNS (Multicast DNS) responder - * iPerf server implementation - - -LICENSE - -lwIP is freely available under a BSD license. - - -DEVELOPMENT - -lwIP has grown into an excellent TCP/IP stack for embedded devices, -and developers using the stack often submit bug fixes, improvements, -and additions to the stack to further increase its usefulness. - -Development of lwIP is hosted on Savannah, a central point for -software development, maintenance and distribution. Everyone can -help improve lwIP by use of Savannah's interface, Git and the -mailing list. A core team of developers will commit changes to the -Git source tree. - -The lwIP TCP/IP stack is maintained in the 'lwip' Git module and -contributions (such as platform ports) are in the 'contrib' Git module. - -See doc/savannah.txt for details on Git server access for users and -developers. - -The current Git trees are web-browsable: - http://git.savannah.gnu.org/cgit/lwip.git - http://git.savannah.gnu.org/cgit/lwip/lwip-contrib.git - -Submit patches and bugs via the lwIP project page: - http://savannah.nongnu.org/projects/lwip/ - -Continuous integration builds (GCC, clang): - https://travis-ci.org/yarrick/lwip-merged - - -DOCUMENTATION - -Self documentation of the source code is regularly extracted from the current -Git sources and is available from this web page: - http://www.nongnu.org/lwip/ - -There is now a constantly growing wiki about lwIP at - http://lwip.wikia.com/wiki/LwIP_Wiki - -Also, there are mailing lists you can subscribe at - http://savannah.nongnu.org/mail/?group=lwip -plus searchable archives: - http://lists.nongnu.org/archive/html/lwip-users/ - http://lists.nongnu.org/archive/html/lwip-devel/ - -lwIP was originally written by Adam Dunkels: - http://dunkels.com/adam/ - -Reading Adam's papers, the files in docs/, browsing the source code -documentation and browsing the mailing list archives is a good way to -become familiar with the design of lwIP. - -Adam Dunkels -Leon Woestenberg diff --git a/third_party/lwip/repo/lwip/UPGRADING b/third_party/lwip/repo/lwip/UPGRADING deleted file mode 100644 index 89267aec5f49f6..00000000000000 --- a/third_party/lwip/repo/lwip/UPGRADING +++ /dev/null @@ -1,243 +0,0 @@ -This file lists major changes between release versions that require -ports or applications to be changed. Use it to update a port or an -application written for an older version of lwIP to correctly work -with newer versions. - - -(git master) - - * [Enter new changes just after this line - do not remove this line] - -(2.0.2) - - ++ Application changes: - - * slipif: The way to pass serial port number has changed. netif->num is not - supported any more, netif->state is interpreted as an u8_t port number now - (it's not a POINTER to an u8_t any more!) - -(2.0.1) - - ++ Application changes: - - * UDP does NOT receive multicast traffic from ALL netifs on an UDP PCB bound to a specific - netif any more. Users need to bind to IP_ADDR_ANY to receive multicast traffic and compare - ip_current_netif() to the desired netif for every packet. - See bug #49662 for an explanation. - -(2.0.0) - - ++ Application changes: - - * Changed netif "up" flag handling to be an administrative flag (as opposed to the previous meaning of - "ip4-address-valid", a netif will now not be used for transmission if not up) -> even a DHCP netif - has to be set "up" before starting the DHCP client - * Added IPv6 support (dual-stack or IPv4/IPv6 only) - * Changed ip_addr_t to be a union in dual-stack mode (use ip4_addr_t where referring to IPv4 only). - * Major rewrite of SNMP (added MIB parser that creates code stubs for custom MIBs); - supports SNMPv2c (experimental v3 support) - * Moved some core applications from contrib repository to src/apps (and include/lwip/apps) - - +++ Raw API: - * Changed TCP listen backlog: removed tcp_accepted(), added the function pair tcp_backlog_delayed()/ - tcp_backlog_accepted() to explicitly delay backlog handling on a connection pcb - - +++ Socket API: - * Added an implementation for posix sendmsg() - * Added LWIP_FIONREAD_LINUXMODE that makes ioctl/FIONREAD return the size of the next pending datagram - - ++ Port changes - - +++ new files: - * MANY new and moved files! - * Added src/Filelists.mk for use in Makefile projects - * Continued moving stack-internal parts from abc.h to abc_priv.h in sub-folder "priv" - to let abc.h only contain the actual application programmer's API - - +++ sys layer: - * Made LWIP_TCPIP_CORE_LOCKING==1 the default as it usually performs better than - the traditional message passing (although with LWIP_COMPAT_MUTEX you are still - open to priority inversion, so this is not recommended any more) - * Added LWIP_NETCONN_SEM_PER_THREAD to use one "op_completed" semaphore per thread - instead of using one per netconn (these semaphores are used even with core locking - enabled as some longer lasting functions like big writes still need to delay) - * Added generalized abstraction for itoa(), strnicmp(), stricmp() and strnstr() - in def.h (to be overridden in cc.h) instead of config - options for netbiosns, httpd, dns, etc. ... - * New abstraction for hton* and ntoh* functions in def.h. - To override them, use the following in cc.h: - #define lwip_htons(x) - #define lwip_htonl(x) - - +++ new options: - * TODO - - +++ new pools: - * Added LWIP_MEMPOOL_* (declare/init/alloc/free) to declare private memp pools - that share memp.c code but do not have to be made global via lwippools.h - * Added pools for IPv6, MPU_COMPATIBLE, dns-api, netif-api, etc. - * added hook LWIP_HOOK_MEMP_AVAILABLE() to get informed when a memp pool was empty and an item - is now available - - * Signature of LWIP_HOOK_VLAN_SET macro was changed - - * LWIP_DECLARE_MEMORY_ALIGNED() may be used to declare aligned memory buffers (mem/memp) - or to move buffers to dedicated memory using compiler attributes - - * Standard C headers are used to define sized types and printf formatters - (disable by setting LWIP_NO_STDINT_H=1 or LWIP_NO_INTTYPES_H=1 if your compiler - does not support these) - - - ++ Major bugfixes/improvements - - * Added IPv6 support (dual-stack or IPv4/IPv6 only) - * Major rewrite of PPP (incl. keep-up with apache pppd) - see doc/ppp.txt for an upgrading how-to - * Major rewrite of SNMP (incl. MIB parser) - * Fixed timing issues that might have lead to losing a DHCP lease - * Made rx processing path more robust against crafted errors - * TCP window scaling support - * modification of api modules to support FreeRTOS-MPU (don't pass stack-pointers to other threads) - * made DNS client more robust - * support PBUF_REF for RX packets - * LWIP_NETCONN_FULLDUPLEX allows netconn/sockets to be used for reading/writing from separate - threads each (needs LWIP_NETCONN_SEM_PER_THREAD) - * Moved and reordered stats (mainly memp/mib2) - -(1.4.0) - - ++ Application changes: - - * Replaced struct ip_addr by typedef ip_addr_t (struct ip_addr is kept for - compatibility to old applications, but will be removed in the future). - - * Renamed mem_realloc() to mem_trim() to prevent confusion with realloc() - - +++ Raw API: - * Changed the semantics of tcp_close() (since it was rather a - shutdown before): Now the application does *NOT* get any calls to the recv - callback (aside from NULL/closed) after calling tcp_close() - - * When calling tcp_abort() from a raw API TCP callback function, - make sure you return ERR_ABRT to prevent accessing unallocated memory. - (ERR_ABRT now means the applicaiton has called tcp_abort!) - - +++ Netconn API: - * Changed netconn_receive() and netconn_accept() to return - err_t, not a pointer to new data/netconn. - - +++ Socket API: - * LWIP_SO_RCVTIMEO: when accept() or recv() time out, they - now set errno to EWOULDBLOCK/EAGAIN, not ETIMEDOUT. - - * Added a minimal version of posix fctl() to have a - standardised way to set O_NONBLOCK for nonblocking sockets. - - +++ all APIs: - * correctly implemented SO(F)_REUSEADDR - - ++ Port changes - - +++ new files: - - * Added 4 new files: def.c, timers.c, timers.h, tcp_impl.h: - - * Moved stack-internal parts of tcp.h to tcp_impl.h, tcp.h now only contains - the actual application programmer's API - - * Separated timer implementation from sys.h/.c, moved to timers.h/.c; - Added timer implementation for NO_SYS==1, set NO_SYS_NO_TIMERS==1 if you - still want to use your own timer implementation for NO_SYS==0 (as before). - - +++ sys layer: - - * Converted mbox- and semaphore-functions to take pointers to sys_mbox_t/ - sys_sem_t; - - * Converted sys_mbox_new/sys_sem_new to take pointers and return err_t; - - * Added Mutex concept in sys_arch (define LWIP_COMPAT_MUTEX to let sys.h use - binary semaphores instead of mutexes - as before) - - +++ new options: - - * Don't waste memory when chaining segments, added option TCP_OVERSIZE to - prevent creating many small pbufs when calling tcp_write with many small - blocks of data. Instead, pbufs are allocated larger than needed and the - space is used for later calls to tcp_write. - - * Added LWIP_NETIF_TX_SINGLE_PBUF to always copy to try to create single pbufs - in tcp_write/udp_send. - - * Added an additional option LWIP_ETHERNET to support ethernet without ARP - (necessary for pure PPPoE) - - * Add MEMP_SEPARATE_POOLS to place memory pools in separate arrays. This may - be used to place these pools into user-defined memory by using external - declaration. - - * Added TCP_SNDQUEUELOWAT corresponding to TCP_SNDLOWAT - - +++ new pools: - - * Netdb uses a memp pool for allocating memory when getaddrinfo() is called, - so MEMP_NUM_NETDB has to be set accordingly. - - * DNS_LOCAL_HOSTLIST_IS_DYNAMIC uses a memp pool instead of the heap, so - MEMP_NUM_LOCALHOSTLIST has to be set accordingly. - - * Snmp-agent uses a memp pools instead of the heap, so MEMP_NUM_SNMP_* have - to be set accordingly. - - * PPPoE uses a MEMP pool instead of the heap, so MEMP_NUM_PPPOE_INTERFACES - has to be set accordingly - - * Integrated loopif into netif.c - loopif does not have to be created by the - port any more, just define LWIP_HAVE_LOOPIF to 1. - - * Added define LWIP_RAND() for lwip-wide randomization (needs to be defined - in cc.h, e.g. used by igmp) - - * Added printf-formatter X8_F to printf u8_t as hex - - * The heap now may be moved to user-defined memory by defining - LWIP_RAM_HEAP_POINTER as a void pointer to that memory's address - - * added autoip_set_struct() and dhcp_set_struct() to let autoip and dhcp work - with user-allocated structs instead of calling mem_malloc - - * Added const char* name to mem- and memp-stats for easier debugging. - - * Calculate the TCP/UDP checksum while copying to only fetch data once: - Define LWIP_CHKSUM_COPY to a memcpy-like function that returns the checksum - - * Added SO_REUSE_RXTOALL to pass received UDP broadcast/multicast packets to - more than one pcb. - - * Changed the semantics of ARP_QUEUEING==0: ARP_QUEUEING now cannot be turned - off any more, if this is set to 0, only one packet (the most recent one) is - queued (like demanded by RFC 1122). - - - ++ Major bugfixes/improvements - - * Implemented tcp_shutdown() to only shut down one end of a connection - * Implemented shutdown() at socket- and netconn-level - * Added errorset support to select() + improved select speed overhead - * Merged pppd to v2.3.11 (including some backported bugfixes from 2.4.x) - * Added timer implementation for NO_SYS==1 (may be disabled with NO_SYS_NO_TIMERS==1 - * Use macros defined in ip_addr.h to work with IP addresses - * Implemented many nonblocking socket/netconn functions - * Fixed ARP input processing: only add a new entry if a request was directed as us - * mem_realloc() to mem_trim() to prevent confusion with realloc() - * Some improvements for AutoIP (don't route/forward link-local addresses, don't break - existing connections when assigning a routable address) - * Correctly handle remote side overrunning our rcv_wnd in ooseq case - * Removed packing from ip_addr_t, the packed version is now only used in protocol headers - * Corrected PBUF_POOL_BUFSIZE for ports where ETH_PAD_SIZE > 0 - * Added support for static ARP table entries - -(STABLE-1.3.2) - - * initial version of this file diff --git a/third_party/lwip/repo/lwip/doc/FILES b/third_party/lwip/repo/lwip/doc/FILES deleted file mode 100644 index e588575085a812..00000000000000 --- a/third_party/lwip/repo/lwip/doc/FILES +++ /dev/null @@ -1,9 +0,0 @@ -doxygen/ - Configuration files and scripts to create the lwIP doxygen source - documentation (found at http://www.nongnu.org/lwip/) - -savannah.txt - How to obtain the current development source code. -contrib.txt - How to contribute to lwIP as a developer. -rawapi.txt - The documentation for the core API of lwIP. - Also provides an overview about the other APIs and multithreading. -sys_arch.txt - The documentation for a system abstraction layer of lwIP. -ppp.txt - Documentation of the PPP interface for lwIP. diff --git a/third_party/lwip/repo/lwip/doc/NO_SYS_SampleCode.c b/third_party/lwip/repo/lwip/doc/NO_SYS_SampleCode.c deleted file mode 100644 index f0af6600b7d5c9..00000000000000 --- a/third_party/lwip/repo/lwip/doc/NO_SYS_SampleCode.c +++ /dev/null @@ -1,122 +0,0 @@ -void -eth_mac_irq() -{ - /* Service MAC IRQ here */ - - /* Allocate pbuf from pool (avoid using heap in interrupts) */ - struct pbuf* p = pbuf_alloc(PBUF_RAW, eth_data_count, PBUF_POOL); - - if(p != NULL) { - /* Copy ethernet frame into pbuf */ - pbuf_take(p, eth_data, eth_data_count); - - /* Put in a queue which is processed in main loop */ - if(!queue_try_put(&queue, p)) { - /* queue is full -> packet loss */ - pbuf_free(p); - } - } -} - -static err_t -netif_output(struct netif *netif, struct pbuf *p) -{ - LINK_STATS_INC(link.xmit); - - /* Update SNMP stats (only if you use SNMP) */ - MIB2_STATS_NETIF_ADD(netif, ifoutoctets, p->tot_len); - int unicast = ((p->payload[0] & 0x01) == 0); - if (unicast) { - MIB2_STATS_NETIF_INC(netif, ifoutucastpkts); - } else { - MIB2_STATS_NETIF_INC(netif, ifoutnucastpkts); - } - - lock_interrupts(); - pbuf_copy_partial(p, mac_send_buffer, p->tot_len, 0); - /* Start MAC transmit here */ - unlock_interrupts(); - - return ERR_OK; -} - -static void -netif_status_callback(struct netif *netif) -{ - printf("netif status changed %s\n", ip4addr_ntoa(netif_ip4_addr(netif))); -} - -static err_t -netif_init(struct netif *netif) -{ - netif->linkoutput = netif_output; - netif->output = etharp_output; - netif->output_ip6 = ethip6_output; - netif->mtu = ETHERNET_MTU; - netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET | NETIF_FLAG_IGMP | NETIF_FLAG_MLD6; - MIB2_INIT_NETIF(netif, snmp_ifType_ethernet_csmacd, 100000000); - - SMEMCPY(netif->hwaddr, your_mac_address_goes_here, sizeof(netif->hwaddr)); - netif->hwaddr_len = sizeof(netif->hwaddr); - - return ERR_OK; -} - -void -main(void) -{ - struct netif netif; - - lwip_init(); - - netif_add(&netif, IP4_ADDR_ANY, IP4_ADDR_ANY, IP4_ADDR_ANY, NULL, netif_init, netif_input); - netif.name[0] = 'e'; - netif.name[1] = '0'; - netif_create_ip6_linklocal_address(&netif, 1); - netif.ip6_autoconfig_enabled = 1; - netif_set_status_callback(&netif, netif_status_callback); - netif_set_default(&netif); - netif_set_up(&netif); - - /* Start DHCP and HTTPD */ - dhcp_start(&netif ); - httpd_init(); - - while(1) { - /* Check link state, e.g. via MDIO communication with PHY */ - if(link_state_changed()) { - if(link_is_up()) { - netif_set_link_up(&netif); - } else { - netif_set_link_down(&netif); - } - } - - /* Check for received frames, feed them to lwIP */ - lock_interrupts(); - struct pbuf* p = queue_try_get(&queue); - unlock_interrupts(); - - if(p != NULL) { - LINK_STATS_INC(link.recv); - - /* Update SNMP stats (only if you use SNMP) */ - MIB2_STATS_NETIF_ADD(netif, ifinoctets, p->tot_len); - int unicast = ((p->payload[0] & 0x01) == 0); - if (unicast) { - MIB2_STATS_NETIF_INC(netif, ifinucastpkts); - } else { - MIB2_STATS_NETIF_INC(netif, ifinnucastpkts); - } - - if(netif.input(p, &netif) != ERR_OK) { - pbuf_free(p); - } - } - - /* Cyclic lwIP timers check */ - sys_check_timeouts(); - - /* your application goes here */ - } -} diff --git a/third_party/lwip/repo/lwip/doc/contrib.txt b/third_party/lwip/repo/lwip/doc/contrib.txt deleted file mode 100644 index 6f0d7bc516780b..00000000000000 --- a/third_party/lwip/repo/lwip/doc/contrib.txt +++ /dev/null @@ -1,58 +0,0 @@ -1 Introduction - -This document describes some guidelines for people participating -in lwIP development. - -2 How to contribute to lwIP - -Here is a short list of suggestions to anybody working with lwIP and -trying to contribute bug reports, fixes, enhancements, platform ports etc. -First of all as you may already know lwIP is a volunteer project so feedback -to fixes or questions might often come late. Hopefully the bug and patch tracking -features of Savannah help us not lose users' input. - -2.1 Source code style: - -1. do not use tabs. -2. indentation is two spaces per level (i.e. per tab). -3. end debug messages with a trailing newline (\n). -4. one space between keyword and opening bracket. -5. no space between function and opening bracket. -6. one space and no newline before opening curly braces of a block. -7. closing curly brace on a single line. -8. spaces surrounding assignment and comparisons. -9. don't initialize static and/or global variables to zero, the compiler takes care of that. -10. use current source code style as further reference. - -2.2 Source code documentation style: - -1. JavaDoc compliant and Doxygen compatible. -2. Function documentation above functions in .c files, not .h files. - (This forces you to synchronize documentation and implementation.) -3. Use current documentation style as further reference. - -2.3 Bug reports and patches: - -1. Make sure you are reporting bugs or send patches against the latest - sources. (From the latest release and/or the current Git sources.) -2. If you think you found a bug make sure it's not already filed in the - bugtracker at Savannah. -3. If you have a fix put the patch on Savannah. If it is a patch that affects - both core and arch specific stuff please separate them so that the core can - be applied separately while leaving the other patch 'open'. The preferred way - is to NOT touch archs you can't test and let maintainers take care of them. - This is a good way to see if they are used at all - the same goes for unix - netifs except tapif. -4. Do not file a bug and post a fix to it to the patch area. Either a bug report - or a patch will be enough. - If you correct an existing bug then attach the patch to the bug rather than creating a new entry in the patch area. -5. Patches should be specific to a single change or to related changes. Do not mix bugfixes with spelling and other - trivial fixes unless the bugfix is trivial too. Do not reorganize code and rename identifiers in the same patch you - change behaviour if not necessary. A patch is easier to read and understand if it's to the point and short than - if it's not to the point and long :) so the chances for it to be applied are greater. - -2.4 Platform porters: - -1. If you have ported lwIP to a platform (an OS, a uC/processor or a combination of these) and - you think it could benefit others[1] you might want discuss this on the mailing list. You - can also ask for Git access to submit and maintain your port in the contrib Git module. diff --git a/third_party/lwip/repo/lwip/doc/doxygen/generate.bat b/third_party/lwip/repo/lwip/doc/doxygen/generate.bat deleted file mode 100644 index 99afb124bec10e..00000000000000 --- a/third_party/lwip/repo/lwip/doc/doxygen/generate.bat +++ /dev/null @@ -1 +0,0 @@ -doxygen lwip.Doxyfile diff --git a/third_party/lwip/repo/lwip/doc/doxygen/generate.sh b/third_party/lwip/repo/lwip/doc/doxygen/generate.sh deleted file mode 100755 index 89344b0e812c73..00000000000000 --- a/third_party/lwip/repo/lwip/doc/doxygen/generate.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh - -doxygen lwip.Doxyfile diff --git a/third_party/lwip/repo/lwip/doc/doxygen/lwip.Doxyfile b/third_party/lwip/repo/lwip/doc/doxygen/lwip.Doxyfile deleted file mode 100644 index 95fa363b41a533..00000000000000 --- a/third_party/lwip/repo/lwip/doc/doxygen/lwip.Doxyfile +++ /dev/null @@ -1,2505 +0,0 @@ -# Doxyfile 1.8.11 - -# This file describes the settings to be used by the documentation system -# doxygen (www.doxygen.org) for a project. -# -# All text after a double hash (##) is considered a comment and is placed in -# front of the TAG it is preceding. -# -# All text after a single hash (#) is considered a comment and will be ignored. -# The format is: -# TAG = value [value, ...] -# For lists, items can also be appended using: -# TAG += value [value, ...] -# Values that contain spaces should be placed between quotes (\" \"). - -#--------------------------------------------------------------------------- -# Project related configuration options -#--------------------------------------------------------------------------- - -# This tag specifies the encoding used for all characters in the config file -# that follow. The default is UTF-8 which is also the encoding used for all text -# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv -# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv -# for the list of possible encodings. -# The default value is: UTF-8. - -DOXYFILE_ENCODING = UTF-8 - -# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by -# double-quotes, unless you are using Doxywizard) that should identify the -# project for which the documentation is generated. This name is used in the -# title of most generated pages and in a few other places. -# The default value is: My Project. - -PROJECT_NAME = "lwIP" - -# The PROJECT_NUMBER tag can be used to enter a project or revision number. This -# could be handy for archiving the generated documentation or if some version -# control system is used. - -PROJECT_NUMBER = "2.0.3" - -# Using the PROJECT_BRIEF tag one can provide an optional one line description -# for a project that appears at the top of each page and should give viewer a -# quick idea about the purpose of the project. Keep the description short. - -PROJECT_BRIEF = "Lightweight IP stack" - -# With the PROJECT_LOGO tag one can specify a logo or an icon that is included -# in the documentation. The maximum height of the logo should not exceed 55 -# pixels and the maximum width should not exceed 200 pixels. Doxygen will copy -# the logo to the output directory. - -PROJECT_LOGO = - -# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path -# into which the generated documentation will be written. If a relative path is -# entered, it will be relative to the location where doxygen was started. If -# left blank the current directory will be used. - -OUTPUT_DIRECTORY = output - -# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- -# directories (in 2 levels) under the output directory of each output format and -# will distribute the generated files over these directories. Enabling this -# option can be useful when feeding doxygen a huge amount of source files, where -# putting all generated files in the same directory would otherwise causes -# performance problems for the file system. -# The default value is: NO. - -CREATE_SUBDIRS = NO - -# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII -# characters to appear in the names of generated files. If set to NO, non-ASCII -# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode -# U+3044. -# The default value is: NO. - -ALLOW_UNICODE_NAMES = NO - -# The OUTPUT_LANGUAGE tag is used to specify the language in which all -# documentation generated by doxygen is written. Doxygen will use this -# information to generate all constant output in the proper language. -# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese, -# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States), -# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian, -# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages), -# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian, -# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian, -# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish, -# Ukrainian and Vietnamese. -# The default value is: English. - -OUTPUT_LANGUAGE = English - -# If the BRIEF_MEMBER_DESC tag is set to YES, doxygen will include brief member -# descriptions after the members that are listed in the file and class -# documentation (similar to Javadoc). Set to NO to disable this. -# The default value is: YES. - -BRIEF_MEMBER_DESC = YES - -# If the REPEAT_BRIEF tag is set to YES, doxygen will prepend the brief -# description of a member or function before the detailed description -# -# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the -# brief descriptions will be completely suppressed. -# The default value is: YES. - -REPEAT_BRIEF = YES - -# This tag implements a quasi-intelligent brief description abbreviator that is -# used to form the text in various listings. Each string in this list, if found -# as the leading text of the brief description, will be stripped from the text -# and the result, after processing the whole list, is used as the annotated -# text. Otherwise, the brief description is used as-is. If left blank, the -# following values are used ($name is automatically replaced with the name of -# the entity):The $name class, The $name widget, The $name file, is, provides, -# specifies, contains, represents, a, an and the. - -ABBREVIATE_BRIEF = "The $name class " \ - "The $name widget " \ - "The $name file " \ - is \ - provides \ - specifies \ - contains \ - represents \ - a \ - an \ - the - -# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then -# doxygen will generate a detailed section even if there is only a brief -# description. -# The default value is: NO. - -ALWAYS_DETAILED_SEC = NO - -# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all -# inherited members of a class in the documentation of that class as if those -# members were ordinary class members. Constructors, destructors and assignment -# operators of the base classes will not be shown. -# The default value is: NO. - -INLINE_INHERITED_MEMB = NO - -# If the FULL_PATH_NAMES tag is set to YES, doxygen will prepend the full path -# before files name in the file list and in the header files. If set to NO the -# shortest path that makes the file name unique will be used -# The default value is: YES. - -FULL_PATH_NAMES = YES - -# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. -# Stripping is only done if one of the specified strings matches the left-hand -# part of the path. The tag can be used to show relative paths in the file list. -# If left blank the directory from which doxygen is run is used as the path to -# strip. -# -# Note that you can specify absolute paths here, but also relative paths, which -# will be relative from the directory where doxygen is started. -# This tag requires that the tag FULL_PATH_NAMES is set to YES. - -STRIP_FROM_PATH = ../../ - -# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the -# path mentioned in the documentation of a class, which tells the reader which -# header file to include in order to use a class. If left blank only the name of -# the header file containing the class definition is used. Otherwise one should -# specify the list of include paths that are normally passed to the compiler -# using the -I flag. - -STRIP_FROM_INC_PATH = - -# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but -# less readable) file names. This can be useful is your file systems doesn't -# support long names like on DOS, Mac, or CD-ROM. -# The default value is: NO. - -SHORT_NAMES = NO - -# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the -# first line (until the first dot) of a Javadoc-style comment as the brief -# description. If set to NO, the Javadoc-style will behave just like regular Qt- -# style comments (thus requiring an explicit @brief command for a brief -# description.) -# The default value is: NO. - -JAVADOC_AUTOBRIEF = NO - -# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first -# line (until the first dot) of a Qt-style comment as the brief description. If -# set to NO, the Qt-style will behave just like regular Qt-style comments (thus -# requiring an explicit \brief command for a brief description.) -# The default value is: NO. - -QT_AUTOBRIEF = NO - -# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a -# multi-line C++ special comment block (i.e. a block of //! or /// comments) as -# a brief description. This used to be the default behavior. The new default is -# to treat a multi-line C++ comment block as a detailed description. Set this -# tag to YES if you prefer the old behavior instead. -# -# Note that setting this tag to YES also means that rational rose comments are -# not recognized any more. -# The default value is: NO. - -MULTILINE_CPP_IS_BRIEF = NO - -# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the -# documentation from any documented member that it re-implements. -# The default value is: YES. - -INHERIT_DOCS = YES - -# If the SEPARATE_MEMBER_PAGES tag is set to YES then doxygen will produce a new -# page for each member. If set to NO, the documentation of a member will be part -# of the file/class/namespace that contains it. -# The default value is: NO. - -SEPARATE_MEMBER_PAGES = NO - -# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen -# uses this value to replace tabs by spaces in code fragments. -# Minimum value: 1, maximum value: 16, default value: 4. - -TAB_SIZE = 8 - -# This tag can be used to specify a number of aliases that act as commands in -# the documentation. An alias has the form: -# name=value -# For example adding -# "sideeffect=@par Side Effects:\n" -# will allow you to put the command \sideeffect (or @sideeffect) in the -# documentation, which will result in a user-defined paragraph with heading -# "Side Effects:". You can put \n's in the value part of an alias to insert -# newlines. - -ALIASES = - -# This tag can be used to specify a number of word-keyword mappings (TCL only). -# A mapping has the form "name=value". For example adding "class=itcl::class" -# will allow you to use the command class in the itcl::class meaning. - -TCL_SUBST = - -# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources -# only. Doxygen will then generate output that is more tailored for C. For -# instance, some of the names that are used will be different. The list of all -# members will be omitted, etc. -# The default value is: NO. - -OPTIMIZE_OUTPUT_FOR_C = YES - -# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or -# Python sources only. Doxygen will then generate output that is more tailored -# for that language. For instance, namespaces will be presented as packages, -# qualified scopes will look different, etc. -# The default value is: NO. - -OPTIMIZE_OUTPUT_JAVA = NO - -# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran -# sources. Doxygen will then generate output that is tailored for Fortran. -# The default value is: NO. - -OPTIMIZE_FOR_FORTRAN = NO - -# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL -# sources. Doxygen will then generate output that is tailored for VHDL. -# The default value is: NO. - -OPTIMIZE_OUTPUT_VHDL = NO - -# Doxygen selects the parser to use depending on the extension of the files it -# parses. With this tag you can assign which parser to use for a given -# extension. Doxygen has a built-in mapping, but you can override or extend it -# using this tag. The format is ext=language, where ext is a file extension, and -# language is one of the parsers supported by doxygen: IDL, Java, Javascript, -# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran: -# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran: -# Fortran. In the later case the parser tries to guess whether the code is fixed -# or free formatted code, this is the default for Fortran type files), VHDL. For -# instance to make doxygen treat .inc files as Fortran files (default is PHP), -# and .f files as C (default is Fortran), use: inc=Fortran f=C. -# -# Note: For files without extension you can use no_extension as a placeholder. -# -# Note that for custom extensions you also need to set FILE_PATTERNS otherwise -# the files are not read by doxygen. - -EXTENSION_MAPPING = - -# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments -# according to the Markdown format, which allows for more readable -# documentation. See http://daringfireball.net/projects/markdown/ for details. -# The output of markdown processing is further processed by doxygen, so you can -# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in -# case of backward compatibilities issues. -# The default value is: YES. - -MARKDOWN_SUPPORT = YES - -# When enabled doxygen tries to link words that correspond to documented -# classes, or namespaces to their corresponding documentation. Such a link can -# be prevented in individual cases by putting a % sign in front of the word or -# globally by setting AUTOLINK_SUPPORT to NO. -# The default value is: YES. - -AUTOLINK_SUPPORT = YES - -# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want -# to include (a tag file for) the STL sources as input, then you should set this -# tag to YES in order to let doxygen match functions declarations and -# definitions whose arguments contain STL classes (e.g. func(std::string); -# versus func(std::string) {}). This also make the inheritance and collaboration -# diagrams that involve STL classes more complete and accurate. -# The default value is: NO. - -BUILTIN_STL_SUPPORT = NO - -# If you use Microsoft's C++/CLI language, you should set this option to YES to -# enable parsing support. -# The default value is: NO. - -CPP_CLI_SUPPORT = NO - -# Set the SIP_SUPPORT tag to YES if your project consists of sip (see: -# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen -# will parse them like normal C++ but will assume all classes use public instead -# of private inheritance when no explicit protection keyword is present. -# The default value is: NO. - -SIP_SUPPORT = NO - -# For Microsoft's IDL there are propget and propput attributes to indicate -# getter and setter methods for a property. Setting this option to YES will make -# doxygen to replace the get and set methods by a property in the documentation. -# This will only work if the methods are indeed getting or setting a simple -# type. If this is not the case, or you want to show the methods anyway, you -# should set this option to NO. -# The default value is: YES. - -IDL_PROPERTY_SUPPORT = YES - -# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC -# tag is set to YES then doxygen will reuse the documentation of the first -# member in the group (if any) for the other members of the group. By default -# all members of a group must be documented explicitly. -# The default value is: NO. - -DISTRIBUTE_GROUP_DOC = NO - -# If one adds a struct or class to a group and this option is enabled, then also -# any nested class or struct is added to the same group. By default this option -# is disabled and one has to add nested compounds explicitly via \ingroup. -# The default value is: NO. - -GROUP_NESTED_COMPOUNDS = NO - -# Set the SUBGROUPING tag to YES to allow class member groups of the same type -# (for instance a group of public functions) to be put as a subgroup of that -# type (e.g. under the Public Functions section). Set it to NO to prevent -# subgrouping. Alternatively, this can be done per class using the -# \nosubgrouping command. -# The default value is: YES. - -SUBGROUPING = YES - -# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions -# are shown inside the group in which they are included (e.g. using \ingroup) -# instead of on a separate page (for HTML and Man pages) or section (for LaTeX -# and RTF). -# -# Note that this feature does not work in combination with -# SEPARATE_MEMBER_PAGES. -# The default value is: NO. - -INLINE_GROUPED_CLASSES = NO - -# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions -# with only public data fields or simple typedef fields will be shown inline in -# the documentation of the scope in which they are defined (i.e. file, -# namespace, or group documentation), provided this scope is documented. If set -# to NO, structs, classes, and unions are shown on a separate page (for HTML and -# Man pages) or section (for LaTeX and RTF). -# The default value is: NO. - -INLINE_SIMPLE_STRUCTS = NO - -# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or -# enum is documented as struct, union, or enum with the name of the typedef. So -# typedef struct TypeS {} TypeT, will appear in the documentation as a struct -# with name TypeT. When disabled the typedef will appear as a member of a file, -# namespace, or class. And the struct will be named TypeS. This can typically be -# useful for C code in case the coding convention dictates that all compound -# types are typedef'ed and only the typedef is referenced, never the tag name. -# The default value is: NO. - -TYPEDEF_HIDES_STRUCT = NO - -# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This -# cache is used to resolve symbols given their name and scope. Since this can be -# an expensive process and often the same symbol appears multiple times in the -# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small -# doxygen will become slower. If the cache is too large, memory is wasted. The -# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range -# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536 -# symbols. At the end of a run doxygen will report the cache usage and suggest -# the optimal cache size from a speed point of view. -# Minimum value: 0, maximum value: 9, default value: 0. - -LOOKUP_CACHE_SIZE = 0 - -#--------------------------------------------------------------------------- -# Build related configuration options -#--------------------------------------------------------------------------- - -# If the EXTRACT_ALL tag is set to YES, doxygen will assume all entities in -# documentation are documented, even if no documentation was available. Private -# class members and static file members will be hidden unless the -# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES. -# Note: This will also disable the warnings about undocumented members that are -# normally produced when WARNINGS is set to YES. -# The default value is: NO. - -EXTRACT_ALL = NO - -# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will -# be included in the documentation. -# The default value is: NO. - -EXTRACT_PRIVATE = NO - -# If the EXTRACT_PACKAGE tag is set to YES, all members with package or internal -# scope will be included in the documentation. -# The default value is: NO. - -EXTRACT_PACKAGE = NO - -# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be -# included in the documentation. -# The default value is: NO. - -EXTRACT_STATIC = NO - -# If the EXTRACT_LOCAL_CLASSES tag is set to YES, classes (and structs) defined -# locally in source files will be included in the documentation. If set to NO, -# only classes defined in header files are included. Does not have any effect -# for Java sources. -# The default value is: YES. - -EXTRACT_LOCAL_CLASSES = YES - -# This flag is only useful for Objective-C code. If set to YES, local methods, -# which are defined in the implementation section but not in the interface are -# included in the documentation. If set to NO, only methods in the interface are -# included. -# The default value is: NO. - -EXTRACT_LOCAL_METHODS = NO - -# If this flag is set to YES, the members of anonymous namespaces will be -# extracted and appear in the documentation as a namespace called -# 'anonymous_namespace{file}', where file will be replaced with the base name of -# the file that contains the anonymous namespace. By default anonymous namespace -# are hidden. -# The default value is: NO. - -EXTRACT_ANON_NSPACES = NO - -# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all -# undocumented members inside documented classes or files. If set to NO these -# members will be included in the various overviews, but no documentation -# section is generated. This option has no effect if EXTRACT_ALL is enabled. -# The default value is: NO. - -HIDE_UNDOC_MEMBERS = YES - -# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all -# undocumented classes that are normally visible in the class hierarchy. If set -# to NO, these classes will be included in the various overviews. This option -# has no effect if EXTRACT_ALL is enabled. -# The default value is: NO. - -HIDE_UNDOC_CLASSES = YES - -# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend -# (class|struct|union) declarations. If set to NO, these declarations will be -# included in the documentation. -# The default value is: NO. - -HIDE_FRIEND_COMPOUNDS = NO - -# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any -# documentation blocks found inside the body of a function. If set to NO, these -# blocks will be appended to the function's detailed documentation block. -# The default value is: NO. - -HIDE_IN_BODY_DOCS = NO - -# The INTERNAL_DOCS tag determines if documentation that is typed after a -# \internal command is included. If the tag is set to NO then the documentation -# will be excluded. Set it to YES to include the internal documentation. -# The default value is: NO. - -INTERNAL_DOCS = NO - -# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file -# names in lower-case letters. If set to YES, upper-case letters are also -# allowed. This is useful if you have classes or files whose names only differ -# in case and if your file system supports case sensitive file names. Windows -# and Mac users are advised to set this option to NO. -# The default value is: system dependent. - -CASE_SENSE_NAMES = NO - -# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with -# their full class and namespace scopes in the documentation. If set to YES, the -# scope will be hidden. -# The default value is: NO. - -HIDE_SCOPE_NAMES = NO - -# If the HIDE_COMPOUND_REFERENCE tag is set to NO (default) then doxygen will -# append additional text to a page's title, such as Class Reference. If set to -# YES the compound reference will be hidden. -# The default value is: NO. - -HIDE_COMPOUND_REFERENCE= NO - -# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of -# the files that are included by a file in the documentation of that file. -# The default value is: YES. - -SHOW_INCLUDE_FILES = YES - -# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each -# grouped member an include statement to the documentation, telling the reader -# which file to include in order to use the member. -# The default value is: NO. - -SHOW_GROUPED_MEMB_INC = NO - -# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include -# files with double quotes in the documentation rather than with sharp brackets. -# The default value is: NO. - -FORCE_LOCAL_INCLUDES = NO - -# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the -# documentation for inline members. -# The default value is: YES. - -INLINE_INFO = YES - -# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the -# (detailed) documentation of file and class members alphabetically by member -# name. If set to NO, the members will appear in declaration order. -# The default value is: YES. - -SORT_MEMBER_DOCS = YES - -# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief -# descriptions of file, namespace and class members alphabetically by member -# name. If set to NO, the members will appear in declaration order. Note that -# this will also influence the order of the classes in the class list. -# The default value is: NO. - -SORT_BRIEF_DOCS = NO - -# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the -# (brief and detailed) documentation of class members so that constructors and -# destructors are listed first. If set to NO the constructors will appear in the -# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS. -# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief -# member documentation. -# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting -# detailed member documentation. -# The default value is: NO. - -SORT_MEMBERS_CTORS_1ST = NO - -# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy -# of group names into alphabetical order. If set to NO the group names will -# appear in their defined order. -# The default value is: NO. - -SORT_GROUP_NAMES = NO - -# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by -# fully-qualified names, including namespaces. If set to NO, the class list will -# be sorted only by class name, not including the namespace part. -# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. -# Note: This option applies only to the class list, not to the alphabetical -# list. -# The default value is: NO. - -SORT_BY_SCOPE_NAME = NO - -# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper -# type resolution of all parameters of a function it will reject a match between -# the prototype and the implementation of a member function even if there is -# only one candidate or it is obvious which candidate to choose by doing a -# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still -# accept a match between prototype and implementation in such cases. -# The default value is: NO. - -STRICT_PROTO_MATCHING = NO - -# The GENERATE_TODOLIST tag can be used to enable (YES) or disable (NO) the todo -# list. This list is created by putting \todo commands in the documentation. -# The default value is: YES. - -GENERATE_TODOLIST = NO - -# The GENERATE_TESTLIST tag can be used to enable (YES) or disable (NO) the test -# list. This list is created by putting \test commands in the documentation. -# The default value is: YES. - -GENERATE_TESTLIST = YES - -# The GENERATE_BUGLIST tag can be used to enable (YES) or disable (NO) the bug -# list. This list is created by putting \bug commands in the documentation. -# The default value is: YES. - -GENERATE_BUGLIST = YES - -# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or disable (NO) -# the deprecated list. This list is created by putting \deprecated commands in -# the documentation. -# The default value is: YES. - -GENERATE_DEPRECATEDLIST= YES - -# The ENABLED_SECTIONS tag can be used to enable conditional documentation -# sections, marked by \if ... \endif and \cond -# ... \endcond blocks. - -ENABLED_SECTIONS = - -# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the -# initial value of a variable or macro / define can have for it to appear in the -# documentation. If the initializer consists of more lines than specified here -# it will be hidden. Use a value of 0 to hide initializers completely. The -# appearance of the value of individual variables and macros / defines can be -# controlled using \showinitializer or \hideinitializer command in the -# documentation regardless of this setting. -# Minimum value: 0, maximum value: 10000, default value: 30. - -MAX_INITIALIZER_LINES = 30 - -# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at -# the bottom of the documentation of classes and structs. If set to YES, the -# list will mention the files that were used to generate the documentation. -# The default value is: YES. - -SHOW_USED_FILES = YES - -# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This -# will remove the Files entry from the Quick Index and from the Folder Tree View -# (if specified). -# The default value is: YES. - -SHOW_FILES = YES - -# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces -# page. This will remove the Namespaces entry from the Quick Index and from the -# Folder Tree View (if specified). -# The default value is: YES. - -SHOW_NAMESPACES = YES - -# The FILE_VERSION_FILTER tag can be used to specify a program or script that -# doxygen should invoke to get the current version for each file (typically from -# the version control system). Doxygen will invoke the program by executing (via -# popen()) the command command input-file, where command is the value of the -# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided -# by doxygen. Whatever the program writes to standard output is used as the file -# version. For an example see the documentation. - -FILE_VERSION_FILTER = - -# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed -# by doxygen. The layout file controls the global structure of the generated -# output files in an output format independent way. To create the layout file -# that represents doxygen's defaults, run doxygen with the -l option. You can -# optionally specify a file name after the option, if omitted DoxygenLayout.xml -# will be used as the name of the layout file. -# -# Note that if you run doxygen from a directory containing a file called -# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE -# tag is left empty. - -LAYOUT_FILE = - -# The CITE_BIB_FILES tag can be used to specify one or more bib files containing -# the reference definitions. This must be a list of .bib files. The .bib -# extension is automatically appended if omitted. This requires the bibtex tool -# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info. -# For LaTeX the style of the bibliography can be controlled using -# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the -# search path. See also \cite for info how to create references. - -CITE_BIB_FILES = - -#--------------------------------------------------------------------------- -# Configuration options related to warning and progress messages -#--------------------------------------------------------------------------- - -# The QUIET tag can be used to turn on/off the messages that are generated to -# standard output by doxygen. If QUIET is set to YES this implies that the -# messages are off. -# The default value is: NO. - -QUIET = NO - -# The WARNINGS tag can be used to turn on/off the warning messages that are -# generated to standard error (stderr) by doxygen. If WARNINGS is set to YES -# this implies that the warnings are on. -# -# Tip: Turn warnings on while writing the documentation. -# The default value is: YES. - -WARNINGS = YES - -# If the WARN_IF_UNDOCUMENTED tag is set to YES then doxygen will generate -# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag -# will automatically be disabled. -# The default value is: YES. - -WARN_IF_UNDOCUMENTED = YES - -# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for -# potential errors in the documentation, such as not documenting some parameters -# in a documented function, or documenting parameters that don't exist or using -# markup commands wrongly. -# The default value is: YES. - -WARN_IF_DOC_ERROR = YES - -# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that -# are documented, but have no documentation for their parameters or return -# value. If set to NO, doxygen will only warn about wrong or incomplete -# parameter documentation, but not about the absence of documentation. -# The default value is: NO. - -WARN_NO_PARAMDOC = NO - -# If the WARN_AS_ERROR tag is set to YES then doxygen will immediately stop when -# a warning is encountered. -# The default value is: NO. - -WARN_AS_ERROR = NO - -# The WARN_FORMAT tag determines the format of the warning messages that doxygen -# can produce. The string should contain the $file, $line, and $text tags, which -# will be replaced by the file and line number from which the warning originated -# and the warning text. Optionally the format may contain $version, which will -# be replaced by the version of the file (if it could be obtained via -# FILE_VERSION_FILTER) -# The default value is: $file:$line: $text. - -WARN_FORMAT = "$file:$line: $text " - -# The WARN_LOGFILE tag can be used to specify a file to which warning and error -# messages should be written. If left blank the output is written to standard -# error (stderr). - -WARN_LOGFILE = - -#--------------------------------------------------------------------------- -# Configuration options related to the input files -#--------------------------------------------------------------------------- - -# The INPUT tag is used to specify the files and/or directories that contain -# documented source files. You may enter file names like myfile.cpp or -# directories like /usr/src/myproject. Separate the files or directories with -# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING -# Note: If this tag is empty the current directory is searched. - -INPUT = main_page.h ../../src - -# This tag can be used to specify the character encoding of the source files -# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses -# libiconv (or the iconv built into libc) for the transcoding. See the libiconv -# documentation (see: http://www.gnu.org/software/libiconv) for the list of -# possible encodings. -# The default value is: UTF-8. - -INPUT_ENCODING = UTF-8 - -# If the value of the INPUT tag contains directories, you can use the -# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and -# *.h) to filter out the source-files in the directories. -# -# Note that for custom extensions or not directly supported extensions you also -# need to set EXTENSION_MAPPING for the extension otherwise the files are not -# read by doxygen. -# -# If left blank the following patterns are tested:*.c, *.cc, *.cxx, *.cpp, -# *.c++, *.java, *.ii, *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, -# *.hh, *.hxx, *.hpp, *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, -# *.m, *.markdown, *.md, *.mm, *.dox, *.py, *.pyw, *.f90, *.f, *.for, *.tcl, -# *.vhd, *.vhdl, *.ucf, *.qsf, *.as and *.js. - -FILE_PATTERNS = *.c \ - *.cc \ - *.cxx \ - *.cpp \ - *.c++ \ - *.java \ - *.ii \ - *.ixx \ - *.ipp \ - *.i++ \ - *.inl \ - *.h \ - *.hh \ - *.hxx \ - *.hpp \ - *.h++ \ - *.idl \ - *.odl \ - *.inc \ - *.m \ - *.mm \ - *.dox - -# The RECURSIVE tag can be used to specify whether or not subdirectories should -# be searched for input files as well. -# The default value is: NO. - -RECURSIVE = YES - -# The EXCLUDE tag can be used to specify files and/or directories that should be -# excluded from the INPUT source files. This way you can easily exclude a -# subdirectory from a directory tree whose root is specified with the INPUT tag. -# -# Note that relative paths are relative to the directory from which doxygen is -# run. - -EXCLUDE = ../../src/include/netif/ppp/polarssl - -# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or -# directories that are symbolic links (a Unix file system feature) are excluded -# from the input. -# The default value is: NO. - -EXCLUDE_SYMLINKS = NO - -# If the value of the INPUT tag contains directories, you can use the -# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude -# certain files from those directories. -# -# Note that the wildcards are matched against the file with absolute path, so to -# exclude all test directories for example use the pattern */test/* - -EXCLUDE_PATTERNS = - -# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names -# (namespaces, classes, functions, etc.) that should be excluded from the -# output. The symbol name can be a fully qualified name, a word, or if the -# wildcard * is used, a substring. Examples: ANamespace, AClass, -# AClass::ANamespace, ANamespace::*Test -# -# Note that the wildcards are matched against the file with absolute path, so to -# exclude all test directories use the pattern */test/* - -EXCLUDE_SYMBOLS = - -# The EXAMPLE_PATH tag can be used to specify one or more files or directories -# that contain example code fragments that are included (see the \include -# command). - -EXAMPLE_PATH = ../ ../../ - -# If the value of the EXAMPLE_PATH tag contains directories, you can use the -# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and -# *.h) to filter out the source-files in the directories. If left blank all -# files are included. - -EXAMPLE_PATTERNS = * - -# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be -# searched for input files to be used with the \include or \dontinclude commands -# irrespective of the value of the RECURSIVE tag. -# The default value is: NO. - -EXAMPLE_RECURSIVE = NO - -# The IMAGE_PATH tag can be used to specify one or more files or directories -# that contain images that are to be included in the documentation (see the -# \image command). - -IMAGE_PATH = - -# The INPUT_FILTER tag can be used to specify a program that doxygen should -# invoke to filter for each input file. Doxygen will invoke the filter program -# by executing (via popen()) the command: -# -# -# -# where is the value of the INPUT_FILTER tag, and is the -# name of an input file. Doxygen will then use the output that the filter -# program writes to standard output. If FILTER_PATTERNS is specified, this tag -# will be ignored. -# -# Note that the filter must not add or remove lines; it is applied before the -# code is scanned, but not when the output code is generated. If lines are added -# or removed, the anchors will not be placed correctly. -# -# Note that for custom extensions or not directly supported extensions you also -# need to set EXTENSION_MAPPING for the extension otherwise the files are not -# properly processed by doxygen. - -INPUT_FILTER = - -# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern -# basis. Doxygen will compare the file name with each pattern and apply the -# filter if there is a match. The filters are a list of the form: pattern=filter -# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how -# filters are used. If the FILTER_PATTERNS tag is empty or if none of the -# patterns match the file name, INPUT_FILTER is applied. -# -# Note that for custom extensions or not directly supported extensions you also -# need to set EXTENSION_MAPPING for the extension otherwise the files are not -# properly processed by doxygen. - -FILTER_PATTERNS = - -# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using -# INPUT_FILTER) will also be used to filter the input files that are used for -# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES). -# The default value is: NO. - -FILTER_SOURCE_FILES = NO - -# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file -# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and -# it is also possible to disable source filtering for a specific pattern using -# *.ext= (so without naming a filter). -# This tag requires that the tag FILTER_SOURCE_FILES is set to YES. - -FILTER_SOURCE_PATTERNS = - -# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that -# is part of the input, its contents will be placed on the main page -# (index.html). This can be useful if you have a project on for instance GitHub -# and want to reuse the introduction page also for the doxygen output. - -USE_MDFILE_AS_MAINPAGE = main_page.h - -#--------------------------------------------------------------------------- -# Configuration options related to source browsing -#--------------------------------------------------------------------------- - -# If the SOURCE_BROWSER tag is set to YES then a list of source files will be -# generated. Documented entities will be cross-referenced with these sources. -# -# Note: To get rid of all source code in the generated output, make sure that -# also VERBATIM_HEADERS is set to NO. -# The default value is: NO. - -SOURCE_BROWSER = NO - -# Setting the INLINE_SOURCES tag to YES will include the body of functions, -# classes and enums directly into the documentation. -# The default value is: NO. - -INLINE_SOURCES = NO - -# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any -# special comment blocks from generated source code fragments. Normal C, C++ and -# Fortran comments will always remain visible. -# The default value is: YES. - -STRIP_CODE_COMMENTS = YES - -# If the REFERENCED_BY_RELATION tag is set to YES then for each documented -# function all documented functions referencing it will be listed. -# The default value is: NO. - -REFERENCED_BY_RELATION = NO - -# If the REFERENCES_RELATION tag is set to YES then for each documented function -# all documented entities called/used by that function will be listed. -# The default value is: NO. - -REFERENCES_RELATION = NO - -# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set -# to YES then the hyperlinks from functions in REFERENCES_RELATION and -# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will -# link to the documentation. -# The default value is: YES. - -REFERENCES_LINK_SOURCE = YES - -# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the -# source code will show a tooltip with additional information such as prototype, -# brief description and links to the definition and documentation. Since this -# will make the HTML file larger and loading of large files a bit slower, you -# can opt to disable this feature. -# The default value is: YES. -# This tag requires that the tag SOURCE_BROWSER is set to YES. - -SOURCE_TOOLTIPS = YES - -# If the USE_HTAGS tag is set to YES then the references to source code will -# point to the HTML generated by the htags(1) tool instead of doxygen built-in -# source browser. The htags tool is part of GNU's global source tagging system -# (see http://www.gnu.org/software/global/global.html). You will need version -# 4.8.6 or higher. -# -# To use it do the following: -# - Install the latest version of global -# - Enable SOURCE_BROWSER and USE_HTAGS in the config file -# - Make sure the INPUT points to the root of the source tree -# - Run doxygen as normal -# -# Doxygen will invoke htags (and that will in turn invoke gtags), so these -# tools must be available from the command line (i.e. in the search path). -# -# The result: instead of the source browser generated by doxygen, the links to -# source code will now point to the output of htags. -# The default value is: NO. -# This tag requires that the tag SOURCE_BROWSER is set to YES. - -USE_HTAGS = NO - -# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a -# verbatim copy of the header file for each class for which an include is -# specified. Set to NO to disable this. -# See also: Section \class. -# The default value is: YES. - -VERBATIM_HEADERS = NO - -# If the CLANG_ASSISTED_PARSING tag is set to YES then doxygen will use the -# clang parser (see: http://clang.llvm.org/) for more accurate parsing at the -# cost of reduced performance. This can be particularly helpful with template -# rich C++ code for which doxygen's built-in parser lacks the necessary type -# information. -# Note: The availability of this option depends on whether or not doxygen was -# generated with the -Duse-libclang=ON option for CMake. -# The default value is: NO. - -CLANG_ASSISTED_PARSING = NO - -# If clang assisted parsing is enabled you can provide the compiler with command -# line options that you would normally use when invoking the compiler. Note that -# the include paths will already be set by doxygen for the files and directories -# specified with INPUT and INCLUDE_PATH. -# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES. - -CLANG_OPTIONS = - -#--------------------------------------------------------------------------- -# Configuration options related to the alphabetical class index -#--------------------------------------------------------------------------- - -# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all -# compounds will be generated. Enable this if the project contains a lot of -# classes, structs, unions or interfaces. -# The default value is: YES. - -ALPHABETICAL_INDEX = NO - -# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in -# which the alphabetical index list will be split. -# Minimum value: 1, maximum value: 20, default value: 5. -# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. - -COLS_IN_ALPHA_INDEX = 5 - -# In case all classes in a project start with a common prefix, all classes will -# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag -# can be used to specify a prefix (or a list of prefixes) that should be ignored -# while generating the index headers. -# This tag requires that the tag ALPHABETICAL_INDEX is set to YES. - -IGNORE_PREFIX = - -#--------------------------------------------------------------------------- -# Configuration options related to the HTML output -#--------------------------------------------------------------------------- - -# If the GENERATE_HTML tag is set to YES, doxygen will generate HTML output -# The default value is: YES. - -GENERATE_HTML = YES - -# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a -# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of -# it. -# The default directory is: html. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_OUTPUT = html - -# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each -# generated HTML page (for example: .htm, .php, .asp). -# The default value is: .html. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_FILE_EXTENSION = .html - -# The HTML_HEADER tag can be used to specify a user-defined HTML header file for -# each generated HTML page. If the tag is left blank doxygen will generate a -# standard header. -# -# To get valid HTML the header file that includes any scripts and style sheets -# that doxygen needs, which is dependent on the configuration options used (e.g. -# the setting GENERATE_TREEVIEW). It is highly recommended to start with a -# default header using -# doxygen -w html new_header.html new_footer.html new_stylesheet.css -# YourConfigFile -# and then modify the file new_header.html. See also section "Doxygen usage" -# for information on how to generate the default header that doxygen normally -# uses. -# Note: The header is subject to change so you typically have to regenerate the -# default header when upgrading to a newer version of doxygen. For a description -# of the possible markers and block names see the documentation. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_HEADER = - -# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each -# generated HTML page. If the tag is left blank doxygen will generate a standard -# footer. See HTML_HEADER for more information on how to generate a default -# footer and what special commands can be used inside the footer. See also -# section "Doxygen usage" for information on how to generate the default footer -# that doxygen normally uses. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_FOOTER = - -# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style -# sheet that is used by each HTML page. It can be used to fine-tune the look of -# the HTML output. If left blank doxygen will generate a default style sheet. -# See also section "Doxygen usage" for information on how to generate the style -# sheet that doxygen normally uses. -# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as -# it is more robust and this tag (HTML_STYLESHEET) will in the future become -# obsolete. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_STYLESHEET = - -# The HTML_EXTRA_STYLESHEET tag can be used to specify additional user-defined -# cascading style sheets that are included after the standard style sheets -# created by doxygen. Using this option one can overrule certain style aspects. -# This is preferred over using HTML_STYLESHEET since it does not replace the -# standard style sheet and is therefore more robust against future updates. -# Doxygen will copy the style sheet files to the output directory. -# Note: The order of the extra style sheet files is of importance (e.g. the last -# style sheet in the list overrules the setting of the previous ones in the -# list). For an example see the documentation. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_EXTRA_STYLESHEET = - -# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or -# other source files which should be copied to the HTML output directory. Note -# that these files will be copied to the base HTML output directory. Use the -# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these -# files. In the HTML_STYLESHEET file, use the file name only. Also note that the -# files will be copied as-is; there are no commands or markers available. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_EXTRA_FILES = - -# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen -# will adjust the colors in the style sheet and background images according to -# this color. Hue is specified as an angle on a colorwheel, see -# http://en.wikipedia.org/wiki/Hue for more information. For instance the value -# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 -# purple, and 360 is red again. -# Minimum value: 0, maximum value: 359, default value: 220. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_COLORSTYLE_HUE = 220 - -# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors -# in the HTML output. For a value of 0 the output will use grayscales only. A -# value of 255 will produce the most vivid colors. -# Minimum value: 0, maximum value: 255, default value: 100. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_COLORSTYLE_SAT = 100 - -# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the -# luminance component of the colors in the HTML output. Values below 100 -# gradually make the output lighter, whereas values above 100 make the output -# darker. The value divided by 100 is the actual gamma applied, so 80 represents -# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not -# change the gamma. -# Minimum value: 40, maximum value: 240, default value: 80. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_COLORSTYLE_GAMMA = 80 - -# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML -# page will contain the date and time when the page was generated. Setting this -# to YES can help to show when doxygen was last run and thus if the -# documentation is up to date. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_TIMESTAMP = NO - -# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML -# documentation will contain sections that can be hidden and shown after the -# page has loaded. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_DYNAMIC_SECTIONS = NO - -# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries -# shown in the various tree structured indices initially; the user can expand -# and collapse entries dynamically later on. Doxygen will expand the tree to -# such a level that at most the specified number of entries are visible (unless -# a fully collapsed tree already exceeds this amount). So setting the number of -# entries 1 will produce a full collapsed tree by default. 0 is a special value -# representing an infinite number of entries and will result in a full expanded -# tree by default. -# Minimum value: 0, maximum value: 9999, default value: 100. -# This tag requires that the tag GENERATE_HTML is set to YES. - -HTML_INDEX_NUM_ENTRIES = 100 - -# If the GENERATE_DOCSET tag is set to YES, additional index files will be -# generated that can be used as input for Apple's Xcode 3 integrated development -# environment (see: http://developer.apple.com/tools/xcode/), introduced with -# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a -# Makefile in the HTML output directory. Running make will produce the docset in -# that directory and running make install will install the docset in -# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at -# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html -# for more information. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -GENERATE_DOCSET = NO - -# This tag determines the name of the docset feed. A documentation feed provides -# an umbrella under which multiple documentation sets from a single provider -# (such as a company or product suite) can be grouped. -# The default value is: Doxygen generated docs. -# This tag requires that the tag GENERATE_DOCSET is set to YES. - -DOCSET_FEEDNAME = "Doxygen generated docs" - -# This tag specifies a string that should uniquely identify the documentation -# set bundle. This should be a reverse domain-name style string, e.g. -# com.mycompany.MyDocSet. Doxygen will append .docset to the name. -# The default value is: org.doxygen.Project. -# This tag requires that the tag GENERATE_DOCSET is set to YES. - -DOCSET_BUNDLE_ID = org.doxygen.Project - -# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify -# the documentation publisher. This should be a reverse domain-name style -# string, e.g. com.mycompany.MyDocSet.documentation. -# The default value is: org.doxygen.Publisher. -# This tag requires that the tag GENERATE_DOCSET is set to YES. - -DOCSET_PUBLISHER_ID = org.doxygen.Publisher - -# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher. -# The default value is: Publisher. -# This tag requires that the tag GENERATE_DOCSET is set to YES. - -DOCSET_PUBLISHER_NAME = Publisher - -# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three -# additional HTML index files: index.hhp, index.hhc, and index.hhk. The -# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop -# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on -# Windows. -# -# The HTML Help Workshop contains a compiler that can convert all HTML output -# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML -# files are now used as the Windows 98 help format, and will replace the old -# Windows help format (.hlp) on all Windows platforms in the future. Compressed -# HTML files also contain an index, a table of contents, and you can search for -# words in the documentation. The HTML workshop also contains a viewer for -# compressed HTML files. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -GENERATE_HTMLHELP = NO - -# The CHM_FILE tag can be used to specify the file name of the resulting .chm -# file. You can add a path in front of the file if the result should not be -# written to the html output directory. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -CHM_FILE = lwip.chm - -# The HHC_LOCATION tag can be used to specify the location (absolute path -# including file name) of the HTML help compiler (hhc.exe). If non-empty, -# doxygen will try to run the HTML help compiler on the generated index.hhp. -# The file has to be specified with full path. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -HHC_LOCATION = - -# The GENERATE_CHI flag controls if a separate .chi index file is generated -# (YES) or that it should be included in the master .chm file (NO). -# The default value is: NO. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -GENERATE_CHI = NO - -# The CHM_INDEX_ENCODING is used to encode HtmlHelp index (hhk), content (hhc) -# and project file content. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -CHM_INDEX_ENCODING = - -# The BINARY_TOC flag controls whether a binary table of contents is generated -# (YES) or a normal table of contents (NO) in the .chm file. Furthermore it -# enables the Previous and Next buttons. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -BINARY_TOC = NO - -# The TOC_EXPAND flag can be set to YES to add extra items for group members to -# the table of contents of the HTML help documentation and to the tree view. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTMLHELP is set to YES. - -TOC_EXPAND = NO - -# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and -# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that -# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help -# (.qch) of the generated HTML documentation. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -GENERATE_QHP = NO - -# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify -# the file name of the resulting .qch file. The path specified is relative to -# the HTML output folder. -# This tag requires that the tag GENERATE_QHP is set to YES. - -QCH_FILE = - -# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help -# Project output. For more information please see Qt Help Project / Namespace -# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace). -# The default value is: org.doxygen.Project. -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHP_NAMESPACE = org.doxygen.Project - -# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt -# Help Project output. For more information please see Qt Help Project / Virtual -# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual- -# folders). -# The default value is: doc. -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHP_VIRTUAL_FOLDER = doc - -# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom -# filter to add. For more information please see Qt Help Project / Custom -# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- -# filters). -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHP_CUST_FILTER_NAME = - -# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the -# custom filter to add. For more information please see Qt Help Project / Custom -# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- -# filters). -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHP_CUST_FILTER_ATTRS = - -# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this -# project's filter section matches. Qt Help Project / Filter Attributes (see: -# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes). -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHP_SECT_FILTER_ATTRS = - -# The QHG_LOCATION tag can be used to specify the location of Qt's -# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the -# generated .qhp file. -# This tag requires that the tag GENERATE_QHP is set to YES. - -QHG_LOCATION = - -# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be -# generated, together with the HTML files, they form an Eclipse help plugin. To -# install this plugin and make it available under the help contents menu in -# Eclipse, the contents of the directory containing the HTML and XML files needs -# to be copied into the plugins directory of eclipse. The name of the directory -# within the plugins directory should be the same as the ECLIPSE_DOC_ID value. -# After copying Eclipse needs to be restarted before the help appears. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -GENERATE_ECLIPSEHELP = NO - -# A unique identifier for the Eclipse help plugin. When installing the plugin -# the directory name containing the HTML and XML files should also have this -# name. Each documentation set should have its own identifier. -# The default value is: org.doxygen.Project. -# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES. - -ECLIPSE_DOC_ID = org.doxygen.Project - -# If you want full control over the layout of the generated HTML pages it might -# be necessary to disable the index and replace it with your own. The -# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top -# of each HTML page. A value of NO enables the index and the value YES disables -# it. Since the tabs in the index contain the same information as the navigation -# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -DISABLE_INDEX = NO - -# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index -# structure should be generated to display hierarchical information. If the tag -# value is set to YES, a side panel will be generated containing a tree-like -# index structure (just like the one that is generated for HTML Help). For this -# to work a browser that supports JavaScript, DHTML, CSS and frames is required -# (i.e. any modern browser). Windows users are probably better off using the -# HTML help feature. Via custom style sheets (see HTML_EXTRA_STYLESHEET) one can -# further fine-tune the look of the index. As an example, the default style -# sheet generated by doxygen has an example that shows how to put an image at -# the root of the tree instead of the PROJECT_NAME. Since the tree basically has -# the same information as the tab index, you could consider setting -# DISABLE_INDEX to YES when enabling this option. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -GENERATE_TREEVIEW = YES - -# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that -# doxygen will group on one line in the generated HTML documentation. -# -# Note that a value of 0 will completely suppress the enum values from appearing -# in the overview section. -# Minimum value: 0, maximum value: 20, default value: 4. -# This tag requires that the tag GENERATE_HTML is set to YES. - -ENUM_VALUES_PER_LINE = 4 - -# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used -# to set the initial width (in pixels) of the frame in which the tree is shown. -# Minimum value: 0, maximum value: 1500, default value: 250. -# This tag requires that the tag GENERATE_HTML is set to YES. - -TREEVIEW_WIDTH = 250 - -# If the EXT_LINKS_IN_WINDOW option is set to YES, doxygen will open links to -# external symbols imported via tag files in a separate window. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -EXT_LINKS_IN_WINDOW = NO - -# Use this tag to change the font size of LaTeX formulas included as images in -# the HTML documentation. When you change the font size after a successful -# doxygen run you need to manually remove any form_*.png images from the HTML -# output directory to force them to be regenerated. -# Minimum value: 8, maximum value: 50, default value: 10. -# This tag requires that the tag GENERATE_HTML is set to YES. - -FORMULA_FONTSIZE = 10 - -# Use the FORMULA_TRANPARENT tag to determine whether or not the images -# generated for formulas are transparent PNGs. Transparent PNGs are not -# supported properly for IE 6.0, but are supported on all modern browsers. -# -# Note that when changing this option you need to delete any form_*.png files in -# the HTML output directory before the changes have effect. -# The default value is: YES. -# This tag requires that the tag GENERATE_HTML is set to YES. - -FORMULA_TRANSPARENT = YES - -# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see -# http://www.mathjax.org) which uses client side Javascript for the rendering -# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX -# installed or if you want to formulas look prettier in the HTML output. When -# enabled you may also need to install MathJax separately and configure the path -# to it using the MATHJAX_RELPATH option. -# The default value is: NO. -# This tag requires that the tag GENERATE_HTML is set to YES. - -USE_MATHJAX = NO - -# When MathJax is enabled you can set the default output format to be used for -# the MathJax output. See the MathJax site (see: -# http://docs.mathjax.org/en/latest/output.html) for more details. -# Possible values are: HTML-CSS (which is slower, but has the best -# compatibility), NativeMML (i.e. MathML) and SVG. -# The default value is: HTML-CSS. -# This tag requires that the tag USE_MATHJAX is set to YES. - -MATHJAX_FORMAT = HTML-CSS - -# When MathJax is enabled you need to specify the location relative to the HTML -# output directory using the MATHJAX_RELPATH option. The destination directory -# should contain the MathJax.js script. For instance, if the mathjax directory -# is located at the same level as the HTML output directory, then -# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax -# Content Delivery Network so you can quickly see the result without installing -# MathJax. However, it is strongly recommended to install a local copy of -# MathJax from http://www.mathjax.org before deployment. -# The default value is: http://cdn.mathjax.org/mathjax/latest. -# This tag requires that the tag USE_MATHJAX is set to YES. - -MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest - -# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax -# extension names that should be enabled during MathJax rendering. For example -# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols -# This tag requires that the tag USE_MATHJAX is set to YES. - -MATHJAX_EXTENSIONS = - -# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces -# of code that will be used on startup of the MathJax code. See the MathJax site -# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an -# example see the documentation. -# This tag requires that the tag USE_MATHJAX is set to YES. - -MATHJAX_CODEFILE = - -# When the SEARCHENGINE tag is enabled doxygen will generate a search box for -# the HTML output. The underlying search engine uses javascript and DHTML and -# should work on any modern browser. Note that when using HTML help -# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET) -# there is already a search function so this one should typically be disabled. -# For large projects the javascript based search engine can be slow, then -# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to -# search using the keyboard; to jump to the search box use + S -# (what the is depends on the OS and browser, but it is typically -# , /
    index.html - - diff --git a/third_party/lwip/repo/lwip/doc/mdns.txt b/third_party/lwip/repo/lwip/doc/mdns.txt deleted file mode 100644 index c322843217fbf7..00000000000000 --- a/third_party/lwip/repo/lwip/doc/mdns.txt +++ /dev/null @@ -1,113 +0,0 @@ -Multicast DNS for lwIP - -Author: Erik Ekman - - -Note! The MDNS responder does not have all features required by the standards. -See notes in src/apps/mdns/mdns.c for what is left. It is however usable in normal -cases - but watch out if many devices on the same network try to use the same -host/service instance names. - - -How to enable: -============== - -MDNS support does not depend on DNS. -MDNS supports using IPv4 only, v6 only, or v4+v6. - -To enable MDNS responder, set - LWIP_MDNS_RESPONDER = 1 -in lwipopts.h and add src/apps/mdns/mdns.c to your list of files to build. - -The max number of services supported per netif is defined by MDNS_MAX_SERVICES, -default is 1. - -Increase MEMP_NUM_UDP_PCB by 1. MDNS needs one PCB. -Increase LWIP_NUM_NETIF_CLIENT_DATA by 1 (MDNS needs one entry on netif). - -MDNS with IPv4 requires LWIP_IGMP = 1, and preferably LWIP_AUTOIP = 1. -MDNS with IPv6 requires LWIP_IPV6_MLD = 1, and that a link-local address is -generated. - -The MDNS code puts its structs on the stack where suitable to reduce dynamic -memory allocation. It may use up to 1kB of stack. - -MDNS needs a strncasecmp() implementation. If you have one, define -LWIP_MDNS_STRNCASECMP to it. Otherwise the code will provide an implementation -for you. - - -How to use: -=========== - -Call mdns_resp_init() during system initialization. -This opens UDP sockets on port 5353 for IPv4 and IPv6. - - -To start responding on a netif, run - mdns_resp_add_netif(struct netif *netif, char *hostname, u32_t dns_ttl) - -The hostname will be copied. If this returns successfully, the netif will join -the multicast groups and any MDNS/legacy DNS requests sent unicast or multicast -to port 5353 will be handled: -- .local type A, AAAA or ANY returns relevant IP addresses -- Reverse lookups (PTR in-addr.arpa, ip6.arpa) of netif addresses - returns .local -Answers will use the supplied TTL (in seconds) -MDNS allows UTF-8 names, but it is recommended to stay within ASCII, -since the default case-insensitive comparison assumes this. - -It is recommended to call this function after an IPv4 address has been set, -since there is currently no check if the v4 address is valid. - -Call mdns_resp_netif_settings_changed() every time the IP address -on the netif has changed. - -To stop responding on a netif, run - mdns_resp_remove_netif(struct netif *netif) - - -Adding services: -================ - -The netif first needs to be registered. Then run - mdns_resp_add_service(struct netif *netif, char *name, char *service, - u16_t proto, u16_t port, u32_t dns_ttl, - service_get_txt_fn_t txt_fn, void *txt_userdata); - -The name and service pointers will be copied. Name refers to the name of the -service instance, and service is the type of service, like _http -proto can be DNSSD_PROTO_UDP or DNSSD_PROTO_TCP which represent _udp and _tcp. -If this call returns successfully, the following queries will be answered: -- _services._dns-sd._udp.local type PTR returns ..local -- ..local type PTR returns ...local -- ...local type SRV returns hostname and port of service -- ...local type TXT builds text strings by calling txt_fn - with the supplied userdata. The callback adds strings to the reply by calling - mdns_resp_add_service_txtitem(struct mdns_service *service, char *txt, - int txt_len). Example callback method: - - static void srv_txt(struct mdns_service *service, void *txt_userdata) - { - res = mdns_resp_add_service_txtitem(service, "path=/", 6); - LWIP_ERROR("mdns add service txt failed\n", (res == ERR_OK), return); - } - - Since a hostname struct is used for TXT storage each single item can be max - 63 bytes long, and the total max length (including length bytes for each - item) is 255 bytes. - -If your device runs a webserver on port 80, an example call might be: - - mdns_resp_add_service(netif, "myweb", "_http" - DNSSD_PROTO_TCP, 80, 3600, srv_txt, NULL); - -which will publish myweb._http._tcp.local for any hosts looking for web servers, -and point them to .local:80 - -Relevant information will be sent as additional records to reduce number of -requests required from a client. - -Removing services is currently not supported. Services are removed when the -netif is removed. - diff --git a/third_party/lwip/repo/lwip/doc/mqtt_client.txt b/third_party/lwip/repo/lwip/doc/mqtt_client.txt deleted file mode 100644 index 3e67defdc56701..00000000000000 --- a/third_party/lwip/repo/lwip/doc/mqtt_client.txt +++ /dev/null @@ -1,162 +0,0 @@ -MQTT client for lwIP - -Author: Erik Andersson - -Details of the MQTT protocol can be found at: -http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html - ------------------------------------------------------------------ -1. Initial steps, reserve memory and make connection to server: - -1.1: Provide storage - -Static allocation: - mqtt_client_t static_client; - example_do_connect(&static_client); - -Dynamic allocation: - mqtt_client_t *client = mqtt_client_new(); - if(client != NULL) { - example_do_connect(&client); - } - -1.2: Establish Connection with server - -void example_do_connect(mqtt_client_t *client) -{ - struct mqtt_connect_client_info_t ci; - err_t err; - - /* Setup an empty client info structure */ - memset(&ci, 0, sizeof(ci)); - - /* Minimal amount of information required is client identifier, so set it here */ - ci.client_id = "lwip_test"; - - /* Initiate client and connect to server, if this fails immediately an error code is returned - otherwise mqtt_connection_cb will be called with connection result after attempting - to establish a connection with the server. - For now MQTT version 3.1.1 is always used */ - - err = mqtt_client_connect(client, ip_addr, MQTT_PORT, mqtt_connection_cb, 0, &ci); - - /* For now just print the result code if something goes wrong - if(err != ERR_OK) { - printf("mqtt_connect return %d\n", err); - } -} - -Connection to server can also be probed by calling mqtt_client_is_connected(client) - ------------------------------------------------------------------ -2. Implementing the connection status callback - - -static void mqtt_connection_cb(mqtt_client_t *client, void *arg, mqtt_connection_status_t status) -{ - err_t err; - if(status == MQTT_CONNECT_ACCEPTED) { - printf("mqtt_connection_cb: Successfully connected\n"); - - /* Setup callback for incoming publish requests */ - mqtt_set_inpub_callback(client, mqtt_incoming_publish_cb, mqtt_incoming_data_cb, arg); - - /* Subscribe to a topic named "subtopic" with QoS level 1, call mqtt_sub_request_cb with result */ - err = mqtt_subscribe(client, "subtopic", 1, mqtt_sub_request_cb, arg); - - if(err != ERR_OK) { - printf("mqtt_subscribe return: %d\n", err); - } - } else { - printf("mqtt_connection_cb: Disconnected, reason: %d\n", status); - - /* Its more nice to be connected, so try to reconnect */ - example_do_connect(client); - } -} - -static void mqtt_sub_request_cb(void *arg, err_t result) -{ - /* Just print the result code here for simplicity, - normal behaviour would be to take some action if subscribe fails like - notifying user, retry subscribe or disconnect from server */ - printf("Subscribe result: %d\n", result); -} - ------------------------------------------------------------------ -3. Implementing callbacks for incoming publish and data - -/* The idea is to demultiplex topic and create some reference to be used in data callbacks - Example here uses a global variable, better would be to use a member in arg - If RAM and CPU budget allows it, the easiest implementation might be to just take a copy of - the topic string and use it in mqtt_incoming_data_cb -*/ -static int inpub_id; -static void mqtt_incoming_publish_cb(void *arg, const char *topic, u32_t tot_len) -{ - printf("Incoming publish at topic %s with total length %u\n", topic, (unsigned int)tot_len); - - /* Decode topic string into a user defined reference */ - if(strcmp(topic, "print_payload") == 0) { - inpub_id = 0; - } else if(topic[0] == 'A') { - /* All topics starting with 'A' might be handled at the same way */ - inpub_id = 1; - } else { - /* For all other topics */ - inpub_id = 2; - } -} - -static void mqtt_incoming_data_cb(void *arg, const u8_t *data, u16_t len, u8_t flags) -{ - printf("Incoming publish payload with length %d, flags %u\n", len, (unsigned int)flags); - - if(flags & MQTT_DATA_FLAG_LAST) { - /* Last fragment of payload received (or whole part if payload fits receive buffer - See MQTT_VAR_HEADER_BUFFER_LEN) */ - - /* Call function or do action depending on reference, in this case inpub_id */ - if(inpub_id == 0) { - /* Don't trust the publisher, check zero termination */ - if(data[len-1] == 0) { - printf("mqtt_incoming_data_cb: %s\n", (const char *)data); - } - } else if(inpub_id == 1) { - /* Call an 'A' function... */ - } else { - printf("mqtt_incoming_data_cb: Ignoring payload...\n"); - } - } else { - /* Handle fragmented payload, store in buffer, write to file or whatever */ - } -} - ------------------------------------------------------------------ -4. Using outgoing publish - - -void example_publish(mqtt_client_t *client, void *arg) -{ - const char *pub_payload= "PubSubHubLubJub"; - err_t err; - u8_t qos = 2; /* 0 1 or 2, see MQTT specification */ - u8_t retain = 0; /* No don't retain such crappy payload... */ - err = mqtt_publish(client, "pub_topic", pub_payload, strlen(pub_payload), qos, retain, mqtt_pub_request_cb, arg); - if(err != ERR_OK) { - printf("Publish err: %d\n", err); - } -} - -/* Called when publish is complete either with sucess or failure */ -static void mqtt_pub_request_cb(void *arg, err_t result) -{ - if(result != ERR_OK) { - printf("Publish result: %d\n", result); - } -} - ------------------------------------------------------------------ -5. Disconnecting - -Simply call mqtt_disconnect(client) diff --git a/third_party/lwip/repo/lwip/doc/ppp.txt b/third_party/lwip/repo/lwip/doc/ppp.txt deleted file mode 100644 index 8b88b3a6714328..00000000000000 --- a/third_party/lwip/repo/lwip/doc/ppp.txt +++ /dev/null @@ -1,529 +0,0 @@ -PPP interface for lwIP - -Author: Sylvain Rochet - -Table of Contents: - -1 - Supported PPP protocols and features -2 - Raw API PPP example for all protocols -3 - PPPoS input path (raw API, IRQ safe API, TCPIP API) -4 - Thread safe PPP API (PPPAPI) -5 - Notify phase callback (PPP_NOTIFY_PHASE) -6 - Upgrading from lwIP <= 1.4.x to lwIP >= 2.0.x - - - -1 Supported PPP protocols and features -====================================== - -Supported Low level protocols: -* PPP over serial using HDLC-like framing, such as wired dialup modems - or mobile telecommunications GPRS/EDGE/UMTS/HSPA+/LTE modems -* PPP over Ethernet, such as xDSL modems -* PPP over L2TP (Layer 2 Tunneling Protocol) LAC (L2TP Access Concentrator), - IP tunnel over UDP, such as VPN access - -Supported auth protocols: -* PAP, Password Authentication Protocol -* CHAP, Challenge-Handshake Authentication Protocol, also known as CHAP-MD5 -* MSCHAPv1, Microsoft version of CHAP, version 1 -* MSCHAPv2, Microsoft version of CHAP, version 2 -* EAP, Extensible Authentication Protocol - -Supported address protocols: -* IPCP, IP Control Protocol, IPv4 addresses negotiation -* IP6CP, IPv6 Control Protocol, IPv6 link-local addresses negotiation - -Supported encryption protocols: -* MPPE, Microsoft Point-to-Point Encryption - -Supported compression or miscellaneous protocols, for serial links only: -* PFC, Protocol Field Compression -* ACFC, Address-and-Control-Field-Compression -* ACCM, Asynchronous-Control-Character-Map -* VJ, Van Jacobson TCP/IP Header Compression - - - -2 Raw API PPP example for all protocols -======================================= - -As usual, raw API for lwIP means the lightweight API which *MUST* only be used -for NO_SYS=1 systems or called inside lwIP core thread for NO_SYS=0 systems. - -/* - * Globals - * ======= - */ - -/* The PPP control block */ -ppp_pcb *ppp; - -/* The PPP IP interface */ -struct netif ppp_netif; - - -/* - * PPP status callback - * =================== - * - * PPP status callback is called on PPP status change (up, down, …) from lwIP - * core thread - */ - -/* PPP status callback example */ -static void status_cb(ppp_pcb *pcb, int err_code, void *ctx) { - struct netif *pppif = ppp_netif(pcb); - LWIP_UNUSED_ARG(ctx); - - switch(err_code) { - case PPPERR_NONE: { -#if LWIP_DNS - const ip_addr_t *ns; -#endif /* LWIP_DNS */ - printf("status_cb: Connected\n"); -#if PPP_IPV4_SUPPORT - printf(" our_ipaddr = %s\n", ipaddr_ntoa(&pppif->ip_addr)); - printf(" his_ipaddr = %s\n", ipaddr_ntoa(&pppif->gw)); - printf(" netmask = %s\n", ipaddr_ntoa(&pppif->netmask)); -#if LWIP_DNS - ns = dns_getserver(0); - printf(" dns1 = %s\n", ipaddr_ntoa(ns)); - ns = dns_getserver(1); - printf(" dns2 = %s\n", ipaddr_ntoa(ns)); -#endif /* LWIP_DNS */ -#endif /* PPP_IPV4_SUPPORT */ -#if PPP_IPV6_SUPPORT - printf(" our6_ipaddr = %s\n", ip6addr_ntoa(netif_ip6_addr(pppif, 0))); -#endif /* PPP_IPV6_SUPPORT */ - break; - } - case PPPERR_PARAM: { - printf("status_cb: Invalid parameter\n"); - break; - } - case PPPERR_OPEN: { - printf("status_cb: Unable to open PPP session\n"); - break; - } - case PPPERR_DEVICE: { - printf("status_cb: Invalid I/O device for PPP\n"); - break; - } - case PPPERR_ALLOC: { - printf("status_cb: Unable to allocate resources\n"); - break; - } - case PPPERR_USER: { - printf("status_cb: User interrupt\n"); - break; - } - case PPPERR_CONNECT: { - printf("status_cb: Connection lost\n"); - break; - } - case PPPERR_AUTHFAIL: { - printf("status_cb: Failed authentication challenge\n"); - break; - } - case PPPERR_PROTOCOL: { - printf("status_cb: Failed to meet protocol\n"); - break; - } - case PPPERR_PEERDEAD: { - printf("status_cb: Connection timeout\n"); - break; - } - case PPPERR_IDLETIMEOUT: { - printf("status_cb: Idle Timeout\n"); - break; - } - case PPPERR_CONNECTTIME: { - printf("status_cb: Max connect time reached\n"); - break; - } - case PPPERR_LOOPBACK: { - printf("status_cb: Loopback detected\n"); - break; - } - default: { - printf("status_cb: Unknown error code %d\n", err_code); - break; - } - } - -/* - * This should be in the switch case, this is put outside of the switch - * case for example readability. - */ - - if (err_code == PPPERR_NONE) { - return; - } - - /* ppp_close() was previously called, don't reconnect */ - if (err_code == PPPERR_USER) { - /* ppp_free(); -- can be called here */ - return; - } - - /* - * Try to reconnect in 30 seconds, if you need a modem chatscript you have - * to do a much better signaling here ;-) - */ - ppp_connect(pcb, 30); - /* OR ppp_listen(pcb); */ -} - - -/* - * Creating a new PPPoS session - * ============================ - * - * In lwIP, PPPoS is not PPPoSONET, in lwIP PPPoS is PPPoSerial. - */ - -#include "netif/ppp/pppos.h" - -/* - * PPPoS serial output callback - * - * ppp_pcb, PPP control block - * data, buffer to write to serial port - * len, length of the data buffer - * ctx, optional user-provided callback context pointer - * - * Return value: len if write succeed - */ -static u32_t output_cb(ppp_pcb *pcb, u8_t *data, u32_t len, void *ctx) { - return uart_write(UART, data, len); -} - -/* - * Create a new PPPoS interface - * - * ppp_netif, netif to use for this PPP link, i.e. PPP IP interface - * output_cb, PPPoS serial output callback - * status_cb, PPP status callback, called on PPP status change (up, down, …) - * ctx_cb, optional user-provided callback context pointer - */ -ppp = pppos_create(&ppp_netif, - output_cb, status_cb, ctx_cb); - - -/* - * Creating a new PPPoE session - * ============================ - */ - -#include "netif/ppp/pppoe.h" - -/* - * Create a new PPPoE interface - * - * ppp_netif, netif to use for this PPP link, i.e. PPP IP interface - * ethif, already existing and setup Ethernet interface to use - * service_name, PPPoE service name discriminator (not supported yet) - * concentrator_name, PPPoE concentrator name discriminator (not supported yet) - * status_cb, PPP status callback, called on PPP status change (up, down, …) - * ctx_cb, optional user-provided callback context pointer - */ -ppp = pppoe_create(&ppp_netif, - ðif, - service_name, concentrator_name, - status_cb, ctx_cb); - - -/* - * Creating a new PPPoL2TP session - * =============================== - */ - -#include "netif/ppp/pppol2tp.h" - -/* - * Create a new PPPoL2TP interface - * - * ppp_netif, netif to use for this PPP link, i.e. PPP IP interface - * netif, optional already existing and setup output netif, necessary if you - * want to set this interface as default route to settle the chicken - * and egg problem with VPN links - * ipaddr, IP to connect to - * port, UDP port to connect to (usually 1701) - * secret, L2TP secret to use - * secret_len, size in bytes of the L2TP secret - * status_cb, PPP status callback, called on PPP status change (up, down, …) - * ctx_cb, optional user-provided callback context pointer - */ -ppp = pppol2tp_create(&ppp_netif, - struct netif *netif, ip_addr_t *ipaddr, u16_t port, - u8_t *secret, u8_t secret_len, - ppp_link_status_cb_fn link_status_cb, void *ctx_cb); - - -/* - * Initiate PPP client connection - * ============================== - */ - -/* Set this interface as default route */ -ppp_set_default(ppp); - -/* - * Basic PPP client configuration. Can only be set if PPP session is in the - * dead state (i.e. disconnected). We don't need to provide thread-safe - * equivalents through PPPAPI because those helpers are only changing - * structure members while session is inactive for lwIP core. Configuration - * only need to be done once. - */ - -/* Ask the peer for up to 2 DNS server addresses. */ -ppp_set_usepeerdns(ppp, 1); - -/* Auth configuration, this is pretty self-explanatory */ -ppp_set_auth(ppp, PPPAUTHTYPE_ANY, "login", "password"); - -/* - * Initiate PPP negotiation, without waiting (holdoff=0), can only be called - * if PPP session is in the dead state (i.e. disconnected). - */ -u16_t holdoff = 0; -ppp_connect(ppp, holdoff); - - -/* - * Initiate PPP server listener - * ============================ - */ - -/* - * Basic PPP server configuration. Can only be set if PPP session is in the - * dead state (i.e. disconnected). We don't need to provide thread-safe - * equivalents through PPPAPI because those helpers are only changing - * structure members while session is inactive for lwIP core. Configuration - * only need to be done once. - */ -ip4_addr_t addr; - -/* Set our address */ -IP4_ADDR(&addr, 192,168,0,1); -ppp_set_ipcp_ouraddr(ppp, &addr); - -/* Set peer(his) address */ -IP4_ADDR(&addr, 192,168,0,2); -ppp_set_ipcp_hisaddr(ppp, &addr); - -/* Set primary DNS server */ -IP4_ADDR(&addr, 192,168,10,20); -ppp_set_ipcp_dnsaddr(ppp, 0, &addr); - -/* Set secondary DNS server */ -IP4_ADDR(&addr, 192,168,10,21); -ppp_set_ipcp_dnsaddr(ppp, 1, &addr); - -/* Auth configuration, this is pretty self-explanatory */ -ppp_set_auth(ppp, PPPAUTHTYPE_ANY, "login", "password"); - -/* Require peer to authenticate */ -ppp_set_auth_required(ppp, 1); - -/* - * Only for PPPoS, the PPP session should be up and waiting for input. - * - * Note: for PPPoS, ppp_connect() and ppp_listen() are actually the same thing. - * The listen call is meant for future support of PPPoE and PPPoL2TP server - * mode, where we will need to negotiate the incoming PPPoE session or L2TP - * session before initiating PPP itself. We need this call because there is - * two passive modes for PPPoS, ppp_set_passive and ppp_set_silent. - */ -ppp_set_silent(pppos, 1); - -/* - * Initiate PPP listener (i.e. wait for an incoming connection), can only - * be called if PPP session is in the dead state (i.e. disconnected). - */ -ppp_listen(ppp); - - -/* - * Closing PPP connection - * ====================== - */ - -/* - * Initiate the end of the PPP session, without carrier lost signal - * (nocarrier=0), meaning a clean shutdown of PPP protocols. - * You can call this function at anytime. - */ -u8_t nocarrier = 0; -ppp_close(ppp, nocarrier); -/* - * Then you must wait your status_cb() to be called, it may takes from a few - * seconds to several tens of seconds depending on the current PPP state. - */ - -/* - * Freeing a PPP connection - * ======================== - */ - -/* - * Free the PPP control block, can only be called if PPP session is in the - * dead state (i.e. disconnected). You need to call ppp_close() before. - */ -ppp_free(ppp); - - - -3 PPPoS input path (raw API, IRQ safe API, TCPIP API) -===================================================== - -Received data on serial port should be sent to lwIP using the pppos_input() -function or the pppos_input_tcpip() function. - -If NO_SYS is 1 and if PPP_INPROC_IRQ_SAFE is 0 (the default), pppos_input() -is not IRQ safe and then *MUST* only be called inside your main loop. - -Whatever the NO_SYS value, if PPP_INPROC_IRQ_SAFE is 1, pppos_input() is IRQ -safe and can be safely called from an interrupt context, using that is going -to reduce your need of buffer if pppos_input() is called byte after byte in -your rx serial interrupt. - -if NO_SYS is 0, the thread safe way outside an interrupt context is to use -the pppos_input_tcpip() function to pass input data to the lwIP core thread -using the TCPIP API. This is thread safe in all cases but you should avoid -passing data byte after byte because it uses heavy locking (mailbox) and it -allocates pbuf, better fill them ! - -if NO_SYS is 0 and if PPP_INPROC_IRQ_SAFE is 1, you may also use pppos_input() -from an RX thread, however pppos_input() is not thread safe by itself. You can -do that *BUT* you should NEVER call pppos_connect(), pppos_listen() and -ppp_free() if pppos_input() can still be running, doing this is NOT thread safe -at all. Using PPP_INPROC_IRQ_SAFE from an RX thread is discouraged unless you -really know what you are doing, your move ;-) - - -/* - * Fonction to call for received data - * - * ppp, PPP control block - * buffer, input buffer - * buffer_len, buffer length in bytes - */ -void pppos_input(ppp, buffer, buffer_len); - -or - -void pppos_input_tcpip(ppp, buffer, buffer_len); - - - -4 Thread safe PPP API (PPPAPI) -============================== - -There is a thread safe API for all corresponding ppp_* functions, you have to -enable LWIP_PPP_API in your lwipopts.h file, then see -include/netif/ppp/pppapi.h, this is actually pretty obvious. - - - -5 Notify phase callback (PPP_NOTIFY_PHASE) -========================================== - -Notify phase callback, enabled using the PPP_NOTIFY_PHASE config option, let -you configure a callback that is called on each PPP internal state change. -This is different from the status callback which only warns you about -up(running) and down(dead) events. - -Notify phase callback can be used, for example, to set a LED pattern depending -on the current phase of the PPP session. Here is a callback example which -tries to mimic what we usually see on xDSL modems while they are negotiating -the link, which should be self-explanatory: - -static void ppp_notify_phase_cb(ppp_pcb *pcb, u8_t phase, void *ctx) { - switch (phase) { - - /* Session is down (either permanently or briefly) */ - case PPP_PHASE_DEAD: - led_set(PPP_LED, LED_OFF); - break; - - /* We are between two sessions */ - case PPP_PHASE_HOLDOFF: - led_set(PPP_LED, LED_SLOW_BLINK); - break; - - /* Session just started */ - case PPP_PHASE_INITIALIZE: - led_set(PPP_LED, LED_FAST_BLINK); - break; - - /* Session is running */ - case PPP_PHASE_RUNNING: - led_set(PPP_LED, LED_ON); - break; - - default: - break; - } -} - - - -6 Upgrading from lwIP <= 1.4.x to lwIP >= 2.0.x -=============================================== - -PPP API was fully reworked between 1.4.x and 2.0.x releases. However porting -from previous lwIP version is pretty easy: - -* Previous PPP API used an integer to identify PPP sessions, we are now - using ppp_pcb* control block, therefore all functions changed from "int ppp" - to "ppp_pcb *ppp" - -* struct netif was moved outside the PPP structure, you have to provide a netif - for PPP interface in pppoX_create() functions - -* PPP session are not started automatically after you created them anymore, - you have to call ppp_connect(), this way you can configure the session before - starting it. - -* Previous PPP API used CamelCase, we are now using snake_case. - -* Previous PPP API mixed PPPoS and PPPoE calls, this isn't the case anymore, - PPPoS functions are now prefixed pppos_ and PPPoE functions are now prefixed - pppoe_, common functions are now prefixed ppp_. - -* New PPPERR_ error codes added, check you have all of them in your status - callback function - -* Only the following include files should now be used in user application: - #include "netif/ppp/pppapi.h" - #include "netif/ppp/pppos.h" - #include "netif/ppp/pppoe.h" - #include "netif/ppp/pppol2tp.h" - - Functions from ppp.h can be used, but you don't need to include this header - file as it is already included by above header files. - -* PPP_INPROC_OWNTHREAD was broken by design and was removed, you have to create - your own serial rx thread - -* PPP_INPROC_MULTITHREADED option was misnamed and confusing and was renamed - PPP_INPROC_IRQ_SAFE, please read the "PPPoS input path" documentation above - because you might have been fooled by that - -* If you used tcpip_callback_with_block() on ppp_ functions you may wish to use - the PPPAPI API instead. - -* ppp_sighup and ppp_close functions were merged using an optional argument - "nocarrier" on ppp_close. - -* DNS servers are now only remotely asked if LWIP_DNS is set and if - ppp_set_usepeerdns() is set to true, they are now automatically registered - using the dns_setserver() function so you don't need to do that in the PPP - callback anymore. - -* PPPoS does not use the SIO API anymore, as such it now requires a serial - output callback in place of sio_write - -* PPP_MAXIDLEFLAG is now in ms instead of jiffies diff --git a/third_party/lwip/repo/lwip/doc/rawapi.txt b/third_party/lwip/repo/lwip/doc/rawapi.txt deleted file mode 100644 index 0cdfdcead14b6b..00000000000000 --- a/third_party/lwip/repo/lwip/doc/rawapi.txt +++ /dev/null @@ -1,499 +0,0 @@ -Raw TCP/IP interface for lwIP - -Authors: Adam Dunkels, Leon Woestenberg, Christiaan Simons - -lwIP provides three Application Program's Interfaces (APIs) for programs -to use for communication with the TCP/IP code: -* low-level "core" / "callback" or "raw" API. -* higher-level "sequential" API. -* BSD-style socket API. - -The raw API (sometimes called native API) is an event-driven API designed -to be used without an operating system that implements zero-copy send and -receive. This API is also used by the core stack for interaction between -the various protocols. It is the only API available when running lwIP -without an operating system. - -The sequential API provides a way for ordinary, sequential, programs -to use the lwIP stack. It is quite similar to the BSD socket API. The -model of execution is based on the blocking open-read-write-close -paradigm. Since the TCP/IP stack is event based by nature, the TCP/IP -code and the application program must reside in different execution -contexts (threads). - -The socket API is a compatibility API for existing applications, -currently it is built on top of the sequential API. It is meant to -provide all functions needed to run socket API applications running -on other platforms (e.g. unix / windows etc.). However, due to limitations -in the specification of this API, there might be incompatibilities -that require small modifications of existing programs. - -** Multithreading - -lwIP started targeting single-threaded environments. When adding multi- -threading support, instead of making the core thread-safe, another -approach was chosen: there is one main thread running the lwIP core -(also known as the "tcpip_thread"). When running in a multithreaded -environment, raw API functions MUST only be called from the core thread -since raw API functions are not protected from concurrent access (aside -from pbuf- and memory management functions). Application threads using -the sequential- or socket API communicate with this main thread through -message passing. - - As such, the list of functions that may be called from - other threads or an ISR is very limited! Only functions - from these API header files are thread-safe: - - api.h - - netbuf.h - - netdb.h - - netifapi.h - - pppapi.h - - sockets.h - - sys.h - - Additionaly, memory (de-)allocation functions may be - called from multiple threads (not ISR!) with NO_SYS=0 - since they are protected by SYS_LIGHTWEIGHT_PROT and/or - semaphores. - - Netconn or Socket API functions are thread safe against the - core thread but they are not reentrant at the control block - granularity level. That is, a UDP or TCP control block must - not be shared among multiple threads without proper locking. - - If SYS_LIGHTWEIGHT_PROT is set to 1 and - LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT is set to 1, - pbuf_free() may also be called from another thread or - an ISR (since only then, mem_free - for PBUF_RAM - may - be called from an ISR: otherwise, the HEAP is only - protected by semaphores). - - -** The remainder of this document discusses the "raw" API. ** - -The raw TCP/IP interface allows the application program to integrate -better with the TCP/IP code. Program execution is event based by -having callback functions being called from within the TCP/IP -code. The TCP/IP code and the application program both run in the same -thread. The sequential API has a much higher overhead and is not very -well suited for small systems since it forces a multithreaded paradigm -on the application. - -The raw TCP/IP interface is not only faster in terms of code execution -time but is also less memory intensive. The drawback is that program -development is somewhat harder and application programs written for -the raw TCP/IP interface are more difficult to understand. Still, this -is the preferred way of writing applications that should be small in -code size and memory usage. - -All APIs can be used simultaneously by different application -programs. In fact, the sequential API is implemented as an application -program using the raw TCP/IP interface. - -Do not confuse the lwIP raw API with raw Ethernet or IP sockets. -The former is a way of interfacing the lwIP network stack (including -TCP and UDP), the later refers to processing raw Ethernet or IP data -instead of TCP connections or UDP packets. - -Raw API applications may never block since all packet processing -(input and output) as well as timer processing (TCP mainly) is done -in a single execution context. - ---- Callbacks - -Program execution is driven by callbacks functions, which are then -invoked by the lwIP core when activity related to that application -occurs. A particular application may register to be notified via a -callback function for events such as incoming data available, outgoing -data sent, error notifications, poll timer expiration, connection -closed, etc. An application can provide a callback function to perform -processing for any or all of these events. Each callback is an ordinary -C function that is called from within the TCP/IP code. Every callback -function is passed the current TCP or UDP connection state as an -argument. Also, in order to be able to keep program specific state, -the callback functions are called with a program specified argument -that is independent of the TCP/IP state. - -The function for setting the application connection state is: - -- void tcp_arg(struct tcp_pcb *pcb, void *arg) - - Specifies the program specific state that should be passed to all - other callback functions. The "pcb" argument is the current TCP - connection control block, and the "arg" argument is the argument - that will be passed to the callbacks. - - ---- TCP connection setup - -The functions used for setting up connections is similar to that of -the sequential API and of the BSD socket API. A new TCP connection -identifier (i.e., a protocol control block - PCB) is created with the -tcp_new() function. This PCB can then be either set to listen for new -incoming connections or be explicitly connected to another host. - -- struct tcp_pcb *tcp_new(void) - - Creates a new connection identifier (PCB). If memory is not - available for creating the new pcb, NULL is returned. - -- err_t tcp_bind(struct tcp_pcb *pcb, ip_addr_t *ipaddr, - u16_t port) - - Binds the pcb to a local IP address and port number. The IP address - can be specified as IP_ADDR_ANY in order to bind the connection to - all local IP addresses. - - If another connection is bound to the same port, the function will - return ERR_USE, otherwise ERR_OK is returned. - -- struct tcp_pcb *tcp_listen(struct tcp_pcb *pcb) - - Commands a pcb to start listening for incoming connections. When an - incoming connection is accepted, the function specified with the - tcp_accept() function will be called. The pcb will have to be bound - to a local port with the tcp_bind() function. - - The tcp_listen() function returns a new connection identifier, and - the one passed as an argument to the function will be - deallocated. The reason for this behavior is that less memory is - needed for a connection that is listening, so tcp_listen() will - reclaim the memory needed for the original connection and allocate a - new smaller memory block for the listening connection. - - tcp_listen() may return NULL if no memory was available for the - listening connection. If so, the memory associated with the pcb - passed as an argument to tcp_listen() will not be deallocated. - -- struct tcp_pcb *tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog) - - Same as tcp_listen, but limits the number of outstanding connections - in the listen queue to the value specified by the backlog argument. - To use it, your need to set TCP_LISTEN_BACKLOG=1 in your lwipopts.h. - -- void tcp_accept(struct tcp_pcb *pcb, - err_t (* accept)(void *arg, struct tcp_pcb *newpcb, - err_t err)) - - Specified the callback function that should be called when a new - connection arrives on a listening connection. - -- err_t tcp_connect(struct tcp_pcb *pcb, ip_addr_t *ipaddr, - u16_t port, err_t (* connected)(void *arg, - struct tcp_pcb *tpcb, - err_t err)); - - Sets up the pcb to connect to the remote host and sends the - initial SYN segment which opens the connection. - - The tcp_connect() function returns immediately; it does not wait for - the connection to be properly setup. Instead, it will call the - function specified as the fourth argument (the "connected" argument) - when the connection is established. If the connection could not be - properly established, either because the other host refused the - connection or because the other host didn't answer, the "err" - callback function of this pcb (registered with tcp_err, see below) - will be called. - - The tcp_connect() function can return ERR_MEM if no memory is - available for enqueueing the SYN segment. If the SYN indeed was - enqueued successfully, the tcp_connect() function returns ERR_OK. - - ---- Sending TCP data - -TCP data is sent by enqueueing the data with a call to -tcp_write(). When the data is successfully transmitted to the remote -host, the application will be notified with a call to a specified -callback function. - -- err_t tcp_write(struct tcp_pcb *pcb, const void *dataptr, u16_t len, - u8_t apiflags) - - Enqueues the data pointed to by the argument dataptr. The length of - the data is passed as the len parameter. The apiflags can be one or more of: - - TCP_WRITE_FLAG_COPY: indicates whether the new memory should be allocated - for the data to be copied into. If this flag is not given, no new memory - should be allocated and the data should only be referenced by pointer. This - also means that the memory behind dataptr must not change until the data is - ACKed by the remote host - - TCP_WRITE_FLAG_MORE: indicates that more data follows. If this is omitted, - the PSH flag is set in the last segment created by this call to tcp_write. - If this flag is given, the PSH flag is not set. - - The tcp_write() function will fail and return ERR_MEM if the length - of the data exceeds the current send buffer size or if the length of - the queue of outgoing segment is larger than the upper limit defined - in lwipopts.h. The number of bytes available in the output queue can - be retrieved with the tcp_sndbuf() function. - - The proper way to use this function is to call the function with at - most tcp_sndbuf() bytes of data. If the function returns ERR_MEM, - the application should wait until some of the currently enqueued - data has been successfully received by the other host and try again. - -- void tcp_sent(struct tcp_pcb *pcb, - err_t (* sent)(void *arg, struct tcp_pcb *tpcb, - u16_t len)) - - Specifies the callback function that should be called when data has - successfully been received (i.e., acknowledged) by the remote - host. The len argument passed to the callback function gives the - amount bytes that was acknowledged by the last acknowledgment. - - ---- Receiving TCP data - -TCP data reception is callback based - an application specified -callback function is called when new data arrives. When the -application has taken the data, it has to call the tcp_recved() -function to indicate that TCP can advertise increase the receive -window. - -- void tcp_recv(struct tcp_pcb *pcb, - err_t (* recv)(void *arg, struct tcp_pcb *tpcb, - struct pbuf *p, err_t err)) - - Sets the callback function that will be called when new data - arrives. The callback function will be passed a NULL pbuf to - indicate that the remote host has closed the connection. If - there are no errors and the callback function is to return - ERR_OK, then it must free the pbuf. Otherwise, it must not - free the pbuf so that lwIP core code can store it. - -- void tcp_recved(struct tcp_pcb *pcb, u16_t len) - - Must be called when the application has received the data. The len - argument indicates the length of the received data. - - ---- Application polling - -When a connection is idle (i.e., no data is either transmitted or -received), lwIP will repeatedly poll the application by calling a -specified callback function. This can be used either as a watchdog -timer for killing connections that have stayed idle for too long, or -as a method of waiting for memory to become available. For instance, -if a call to tcp_write() has failed because memory wasn't available, -the application may use the polling functionality to call tcp_write() -again when the connection has been idle for a while. - -- void tcp_poll(struct tcp_pcb *pcb, - err_t (* poll)(void *arg, struct tcp_pcb *tpcb), - u8_t interval) - - Specifies the polling interval and the callback function that should - be called to poll the application. The interval is specified in - number of TCP coarse grained timer shots, which typically occurs - twice a second. An interval of 10 means that the application would - be polled every 5 seconds. - - ---- Closing and aborting connections - -- err_t tcp_close(struct tcp_pcb *pcb) - - Closes the connection. The function may return ERR_MEM if no memory - was available for closing the connection. If so, the application - should wait and try again either by using the acknowledgment - callback or the polling functionality. If the close succeeds, the - function returns ERR_OK. - - The pcb is deallocated by the TCP code after a call to tcp_close(). - -- void tcp_abort(struct tcp_pcb *pcb) - - Aborts the connection by sending a RST (reset) segment to the remote - host. The pcb is deallocated. This function never fails. - - ATTENTION: When calling this from one of the TCP callbacks, make - sure you always return ERR_ABRT (and never return ERR_ABRT otherwise - or you will risk accessing deallocated memory or memory leaks! - - -If a connection is aborted because of an error, the application is -alerted of this event by the err callback. Errors that might abort a -connection are when there is a shortage of memory. The callback -function to be called is set using the tcp_err() function. - -- void tcp_err(struct tcp_pcb *pcb, void (* err)(void *arg, - err_t err)) - - The error callback function does not get the pcb passed to it as a - parameter since the pcb may already have been deallocated. - - ---- UDP interface - -The UDP interface is similar to that of TCP, but due to the lower -level of complexity of UDP, the interface is significantly simpler. - -- struct udp_pcb *udp_new(void) - - Creates a new UDP pcb which can be used for UDP communication. The - pcb is not active until it has either been bound to a local address - or connected to a remote address. - -- void udp_remove(struct udp_pcb *pcb) - - Removes and deallocates the pcb. - -- err_t udp_bind(struct udp_pcb *pcb, ip_addr_t *ipaddr, - u16_t port) - - Binds the pcb to a local address. The IP-address argument "ipaddr" - can be IP_ADDR_ANY to indicate that it should listen to any local IP - address. The function currently always return ERR_OK. - -- err_t udp_connect(struct udp_pcb *pcb, ip_addr_t *ipaddr, - u16_t port) - - Sets the remote end of the pcb. This function does not generate any - network traffic, but only set the remote address of the pcb. - -- err_t udp_disconnect(struct udp_pcb *pcb) - - Remove the remote end of the pcb. This function does not generate - any network traffic, but only removes the remote address of the pcb. - -- err_t udp_send(struct udp_pcb *pcb, struct pbuf *p) - - Sends the pbuf p. The pbuf is not deallocated. - -- void udp_recv(struct udp_pcb *pcb, - void (* recv)(void *arg, struct udp_pcb *upcb, - struct pbuf *p, - ip_addr_t *addr, - u16_t port), - void *recv_arg) - - Specifies a callback function that should be called when a UDP - datagram is received. - - ---- System initalization - -A truly complete and generic sequence for initializing the lwIP stack -cannot be given because it depends on additional initializations for -your runtime environment (e.g. timers). - -We can give you some idea on how to proceed when using the raw API. -We assume a configuration using a single Ethernet netif and the -UDP and TCP transport layers, IPv4 and the DHCP client. - -Call these functions in the order of appearance: - -- lwip_init() - - Initialize the lwIP stack and all of its subsystems. - -- netif_add(struct netif *netif, const ip4_addr_t *ipaddr, - const ip4_addr_t *netmask, const ip4_addr_t *gw, - void *state, netif_init_fn init, netif_input_fn input) - - Adds your network interface to the netif_list. Allocate a struct - netif and pass a pointer to this structure as the first argument. - Give pointers to cleared ip_addr structures when using DHCP, - or fill them with sane numbers otherwise. The state pointer may be NULL. - - The init function pointer must point to a initialization function for - your Ethernet netif interface. The following code illustrates its use. - - err_t netif_if_init(struct netif *netif) - { - u8_t i; - - for (i = 0; i < ETHARP_HWADDR_LEN; i++) { - netif->hwaddr[i] = some_eth_addr[i]; - } - init_my_eth_device(); - return ERR_OK; - } - - For Ethernet drivers, the input function pointer must point to the lwIP - function ethernet_input() declared in "netif/etharp.h". Other drivers - must use ip_input() declared in "lwip/ip.h". - -- netif_set_default(struct netif *netif) - - Registers the default network interface. - -- netif_set_link_up(struct netif *netif) - - This is the hardware link state; e.g. whether cable is plugged for wired - Ethernet interface. This function must be called even if you don't know - the current state. Having link up and link down events is optional but - DHCP and IPv6 discover benefit well from those events. - -- netif_set_up(struct netif *netif) - - This is the administrative (= software) state of the netif, when the - netif is fully configured this function must be called. - -- dhcp_start(struct netif *netif) - - Creates a new DHCP client for this interface on the first call. - - You can peek in the netif->dhcp struct for the actual DHCP status. - -- sys_check_timeouts() - - When the system is running, you have to periodically call - sys_check_timeouts() which will handle all timers for all protocols in - the stack; add this to your main loop or equivalent. - - ---- Optimalization hints - -The first thing you want to optimize is the lwip_standard_checksum() -routine from src/core/inet.c. You can override this standard -function with the #define LWIP_CHKSUM . - -There are C examples given in inet.c or you might want to -craft an assembly function for this. RFC1071 is a good -introduction to this subject. - -Other significant improvements can be made by supplying -assembly or inline replacements for htons() and htonl() -if you're using a little-endian architecture. -#define lwip_htons(x) -#define lwip_htonl(x) -If you #define them to htons() and htonl(), you should -#define LWIP_DONT_PROVIDE_BYTEORDER_FUNCTIONS to prevent lwIP from -defining hton*/ntoh* compatibility macros. - -Check your network interface driver if it reads at -a higher speed than the maximum wire-speed. If the -hardware isn't serviced frequently and fast enough -buffer overflows are likely to occur. - -E.g. when using the cs8900 driver, call cs8900if_service(ethif) -as frequently as possible. When using an RTOS let the cs8900 interrupt -wake a high priority task that services your driver using a binary -semaphore or event flag. Some drivers might allow additional tuning -to match your application and network. - -For a production release it is recommended to set LWIP_STATS to 0. -Note that speed performance isn't influenced much by simply setting -high values to the memory options. - -For more optimization hints take a look at the lwIP wiki. - ---- Zero-copy MACs - -To achieve zero-copy on transmit, the data passed to the raw API must -remain unchanged until sent. Because the send- (or write-)functions return -when the packets have been enqueued for sending, data must be kept stable -after that, too. - -This implies that PBUF_RAM/PBUF_POOL pbufs passed to raw-API send functions -must *not* be reused by the application unless their ref-count is 1. - -For no-copy pbufs (PBUF_ROM/PBUF_REF), data must be kept unchanged, too, -but the stack/driver will/must copy PBUF_REF'ed data when enqueueing, while -PBUF_ROM-pbufs are just enqueued (as ROM-data is expected to never change). - -Also, data passed to tcp_write without the copy-flag must not be changed! - -Therefore, be careful which type of PBUF you use and if you copy TCP data -or not! diff --git a/third_party/lwip/repo/lwip/doc/savannah.txt b/third_party/lwip/repo/lwip/doc/savannah.txt deleted file mode 100644 index d7d19eb6eb70dc..00000000000000 --- a/third_party/lwip/repo/lwip/doc/savannah.txt +++ /dev/null @@ -1,120 +0,0 @@ -Daily Use Guide for using Savannah for lwIP - -Table of Contents: - -1 - Obtaining lwIP from the Git repository -2 - Committers/developers Git access using SSH -3 - Merging a development branch to master branch -4 - How to release lwIP - - - -1 Obtaining lwIP from the Git repository ----------------------------------------- - -To perform an anonymous Git clone of the master branch (this is where -bug fixes and incremental enhancements occur), do this: - git clone git://git.savannah.nongnu.org/lwip.git - -Or, obtain a stable branch (updated with bug fixes only) as follows: - git clone --branch DEVEL-1_4_1 git://git.savannah.nongnu.org/lwip.git - -Or, obtain a specific (fixed) release as follows: - git clone --branch STABLE-1_4_1 git://git.savannah.nongnu.org/lwip.git - - -2 Committers/developers Git access using SSH --------------------------------------------- - -The Savannah server uses SSH (Secure Shell) protocol 2 authentication and encryption. -As such, Git commits to the server occur through a SSH tunnel for project members. -To create a SSH2 key pair in UNIX-like environments, do this: - ssh-keygen -t dsa - -Under Windows, a recommended SSH client is "PuTTY", freely available with good -documentation and a graphic user interface. Use its key generator. - -Now paste the id_dsa.pub contents into your Savannah account public key list. Wait -a while so that Savannah can update its configuration (This can take minutes). - -Try to login using SSH: - ssh -v your_login@git.sv.gnu.org - -If it tells you: - Linux vcs.savannah.gnu.org 2.6.32-5-xen-686 #1 SMP Wed Jun 17 17:10:03 UTC 2015 i686 - - Interactive shell login is not possible for security reasons. - VCS commands are allowed. - Last login: Tue May 15 23:10:12 2012 from 82.245.102.129 - You tried to execute: - Sorry, you are not allowed to execute that command. - Shared connection to git.sv.gnu.org closed. - -then you could login; Savannah refuses to give you a shell - which is OK, as we -are allowed to use SSH for Git only. Now, you should be able to do this: - git clone your_login@git.sv.gnu.org:/srv/git/lwip.git - -After which you can edit your local files with bug fixes or new features and -commit them. Make sure you know what you are doing when using Git to make -changes on the repository. If in doubt, ask on the lwip-members mailing list. - -(If SSH asks about authenticity of the host, you can check the key -fingerprint against https://savannah.nongnu.org/git/?group=lwip - - -3 - Merging a development branch to master branch -------------------------------------------------- - -Merging is a straightforward process in Git. How to merge all changes in a -development branch since our last merge from main: - -Checkout the master branch: - git checkout master - -Merge the development branch to master: - git merge your-development-branch - -Resolve any conflict. - -Commit the merge result. - git commit -a - -Push your commits: - git push - - -4 How to release lwIP ---------------------- - -First, tag the release using Git: (I use release number 1.4.1 throughout -this example). - git tag -a STABLE-1_4_1 - -Share the tag reference by pushing it to remote: - git push origin STABLE-1_4_1 - -Prepare the release: - cp -r lwip lwip-1.4.1 - rm -rf lwip-1.4.1/.git lwip-1.4.1/.gitattributes - -Archive the current directory using tar, gzip'd, bzip2'd and zip'd. - tar czvf lwip-1.4.1.tar.gz lwip-1.4.1 - tar cjvf lwip-1.4.1.tar.bz2 lwip-1.4.1 - zip -r lwip-1.4.1.zip lwip-1.4.1 - -Now, sign the archives with a detached GPG binary signature as follows: - gpg -b lwip-1.4.1.tar.gz - gpg -b lwip-1.4.1.tar.bz2 - gpg -b lwip-1.4.1.zip - -Upload these files using anonymous FTP: - ncftp ftp://savannah.gnu.org/incoming/savannah/lwip - ncftp> mput *1.4.1.* - -Additionally, you may post a news item on Savannah, like this: - -A new 1.4.1 release is now available here: -http://savannah.nongnu.org/files/?group=lwip&highlight=1.4.1 - -You will have to submit this via the user News interface, then approve -this via the Administrator News interface. diff --git a/third_party/lwip/repo/lwip/doc/sys_arch.txt b/third_party/lwip/repo/lwip/doc/sys_arch.txt deleted file mode 100644 index 187073c1201bec..00000000000000 --- a/third_party/lwip/repo/lwip/doc/sys_arch.txt +++ /dev/null @@ -1,308 +0,0 @@ -sys_arch interface for lwIP - -Author: Adam Dunkels - Simon Goldschmidt - -The operating system emulation layer provides a common interface -between the lwIP code and the underlying operating system kernel. The -general idea is that porting lwIP to new architectures requires only -small changes to a few header files and a new sys_arch -implementation. It is also possible to do a sys_arch implementation -that does not rely on any underlying operating system. - -The sys_arch provides semaphores, mailboxes and mutexes to lwIP. For the full -lwIP functionality, multiple threads support can be implemented in the -sys_arch, but this is not required for the basic lwIP -functionality. Timer scheduling is implemented in lwIP, but can be implemented -by the sys_arch port (LWIP_TIMERS_CUSTOM==1). - -In addition to the source file providing the functionality of sys_arch, -the OS emulation layer must provide several header files defining -macros used throughout lwip. The files required and the macros they -must define are listed below the sys_arch description. - -Semaphores can be either counting or binary - lwIP works with both -kinds. Mailboxes should be implemented as a queue which allows multiple messages -to be posted (implementing as a rendez-vous point where only one message can be -posted at a time can have a highly negative impact on performance). A message -in a mailbox is just a pointer, nothing more. - -Semaphores are represented by the type "sys_sem_t" which is typedef'd -in the sys_arch.h file. Mailboxes are equivalently represented by the -type "sys_mbox_t". Mutexes are represented by the type "sys_mutex_t". -lwIP does not place any restrictions on how these types are represented -internally. - -Since lwIP 1.4.0, semaphore, mutexes and mailbox functions are prototyped in a way that -allows both using pointers or actual OS structures to be used. This way, memory -required for such types can be either allocated in place (globally or on the -stack) or on the heap (allocated internally in the "*_new()" functions). - -The following functions must be implemented by the sys_arch: - -- void sys_init(void) - - Is called to initialize the sys_arch layer. - -- err_t sys_sem_new(sys_sem_t *sem, u8_t count) - - Creates a new semaphore. The semaphore is allocated to the memory that 'sem' - points to (which can be both a pointer or the actual OS structure). - The "count" argument specifies the initial state of the semaphore (which is - either 0 or 1). - If the semaphore has been created, ERR_OK should be returned. Returning any - other error will provide a hint what went wrong, but except for assertions, - no real error handling is implemented. - -- void sys_sem_free(sys_sem_t *sem) - - Deallocates a semaphore. - -- void sys_sem_signal(sys_sem_t *sem) - - Signals a semaphore. - -- u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout) - - Blocks the thread while waiting for the semaphore to be - signaled. If the "timeout" argument is non-zero, the thread should - only be blocked for the specified time (measured in - milliseconds). If the "timeout" argument is zero, the thread should be - blocked until the semaphore is signalled. - - If the timeout argument is non-zero, the return value is the number of - milliseconds spent waiting for the semaphore to be signaled. If the - semaphore wasn't signaled within the specified time, the return value is - SYS_ARCH_TIMEOUT. If the thread didn't have to wait for the semaphore - (i.e., it was already signaled), the function may return zero. - - Notice that lwIP implements a function with a similar name, - sys_sem_wait(), that uses the sys_arch_sem_wait() function. - -- int sys_sem_valid(sys_sem_t *sem) - - Returns 1 if the semaphore is valid, 0 if it is not valid. - When using pointers, a simple way is to check the pointer for != NULL. - When directly using OS structures, implementing this may be more complex. - This may also be a define, in which case the function is not prototyped. - -- void sys_sem_set_invalid(sys_sem_t *sem) - - Invalidate a semaphore so that sys_sem_valid() returns 0. - ATTENTION: This does NOT mean that the semaphore shall be deallocated: - sys_sem_free() is always called before calling this function! - This may also be a define, in which case the function is not prototyped. - -- void sys_mutex_new(sys_mutex_t *mutex) - - Creates a new mutex. The mutex is allocated to the memory that 'mutex' - points to (which can be both a pointer or the actual OS structure). - If the mutex has been created, ERR_OK should be returned. Returning any - other error will provide a hint what went wrong, but except for assertions, - no real error handling is implemented. - -- void sys_mutex_free(sys_mutex_t *mutex) - - Deallocates a mutex. - -- void sys_mutex_lock(sys_mutex_t *mutex) - - Blocks the thread until the mutex can be grabbed. - -- void sys_mutex_unlock(sys_mutex_t *mutex) - - Releases the mutex previously locked through 'sys_mutex_lock()'. - -- void sys_mutex_valid(sys_mutex_t *mutex) - - Returns 1 if the mutes is valid, 0 if it is not valid. - When using pointers, a simple way is to check the pointer for != NULL. - When directly using OS structures, implementing this may be more complex. - This may also be a define, in which case the function is not prototyped. - -- void sys_mutex_set_invalid(sys_mutex_t *mutex) - - Invalidate a mutex so that sys_mutex_valid() returns 0. - ATTENTION: This does NOT mean that the mutex shall be deallocated: - sys_mutex_free() is always called before calling this function! - This may also be a define, in which case the function is not prototyped. - -- err_t sys_mbox_new(sys_mbox_t *mbox, int size) - - Creates an empty mailbox for maximum "size" elements. Elements stored - in mailboxes are pointers. You have to define macros "_MBOX_SIZE" - in your lwipopts.h, or ignore this parameter in your implementation - and use a default size. - If the mailbox has been created, ERR_OK should be returned. Returning any - other error will provide a hint what went wrong, but except for assertions, - no real error handling is implemented. - -- void sys_mbox_free(sys_mbox_t *mbox) - - Deallocates a mailbox. If there are messages still present in the - mailbox when the mailbox is deallocated, it is an indication of a - programming error in lwIP and the developer should be notified. - -- void sys_mbox_post(sys_mbox_t *mbox, void *msg) - - Posts the "msg" to the mailbox. This function have to block until - the "msg" is really posted. - -- err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg) - - Try to post the "msg" to the mailbox. Returns ERR_MEM if this one - is full, else, ERR_OK if the "msg" is posted. - -- u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout) - - Blocks the thread until a message arrives in the mailbox, but does - not block the thread longer than "timeout" milliseconds (similar to - the sys_arch_sem_wait() function). If "timeout" is 0, the thread should - be blocked until a message arrives. The "msg" argument is a result - parameter that is set by the function (i.e., by doing "*msg = - ptr"). The "msg" parameter maybe NULL to indicate that the message - should be dropped. - - The return values are the same as for the sys_arch_sem_wait() function: - Number of milliseconds spent waiting or SYS_ARCH_TIMEOUT if there was a - timeout. - - Note that a function with a similar name, sys_mbox_fetch(), is - implemented by lwIP. - -- u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg) - - This is similar to sys_arch_mbox_fetch, however if a message is not - present in the mailbox, it immediately returns with the code - SYS_MBOX_EMPTY. On success 0 is returned. - - To allow for efficient implementations, this can be defined as a - function-like macro in sys_arch.h instead of a normal function. For - example, a naive implementation could be: - #define sys_arch_mbox_tryfetch(mbox,msg) \ - sys_arch_mbox_fetch(mbox,msg,1) - although this would introduce unnecessary delays. - -- int sys_mbox_valid(sys_mbox_t *mbox) - - Returns 1 if the mailbox is valid, 0 if it is not valid. - When using pointers, a simple way is to check the pointer for != NULL. - When directly using OS structures, implementing this may be more complex. - This may also be a define, in which case the function is not prototyped. - -- void sys_mbox_set_invalid(sys_mbox_t *mbox) - - Invalidate a mailbox so that sys_mbox_valid() returns 0. - ATTENTION: This does NOT mean that the mailbox shall be deallocated: - sys_mbox_free() is always called before calling this function! - This may also be a define, in which case the function is not prototyped. - -If threads are supported by the underlying operating system and if -such functionality is needed in lwIP, the following function will have -to be implemented as well: - -- sys_thread_t sys_thread_new(char *name, void (* thread)(void *arg), void *arg, int stacksize, int prio) - - Starts a new thread named "name" with priority "prio" that will begin its - execution in the function "thread()". The "arg" argument will be passed as an - argument to the thread() function. The stack size to used for this thread is - the "stacksize" parameter. The id of the new thread is returned. Both the id - and the priority are system dependent. - -- err_t sys_thread_finish(sys_thread_t t) - - Terminates an existing thread 't'. Return ERR_OK only if the thread finishes - gracefully. Otherwise, error code is returned from tcpip_finish(). - -When lwIP is used from more than one context (e.g. from multiple threads OR from -main-loop and from interrupts), the SYS_LIGHTWEIGHT_PROT protection SHOULD be enabled! - -- sys_prot_t sys_arch_protect(void) - - This optional function does a "fast" critical region protection and returns - the previous protection level. This function is only called during very short - critical regions. An embedded system which supports ISR-based drivers might - want to implement this function by disabling interrupts. Task-based systems - might want to implement this by using a mutex or disabling tasking. This - function should support recursive calls from the same task or interrupt. In - other words, sys_arch_protect() could be called while already protected. In - that case the return value indicates that it is already protected. - - sys_arch_protect() is only required if your port is supporting an operating - system. - -- void sys_arch_unprotect(sys_prot_t pval) - - This optional function does a "fast" set of critical region protection to the - value specified by pval. See the documentation for sys_arch_protect() for - more information. This function is only required if your port is supporting - an operating system. - -For some configurations, you also need: - -- u32_t sys_now(void) - - This optional function returns the current time in milliseconds (don't care - for wraparound, this is only used for time diffs). - Not implementing this function means you cannot use some modules (e.g. TCP - timestamps, internal timeouts for NO_SYS==1). - - -Note: - -Be careful with using mem_malloc() in sys_arch. When malloc() refers to -mem_malloc() you can run into a circular function call problem. In mem.c -mem_init() tries to allcate a semaphore using mem_malloc, which of course -can't be performed when sys_arch uses mem_malloc. - -------------------------------------------------------------------------------- -Additional files required for the "OS support" emulation layer: -------------------------------------------------------------------------------- - -cc.h - Architecture environment, some compiler specific, some - environment specific (probably should move env stuff - to sys_arch.h.) - - Typedefs for the types used by lwip - - u8_t, s8_t, u16_t, s16_t, u32_t, s32_t, mem_ptr_t - - Compiler hints for packing lwip's structures - - PACK_STRUCT_FIELD(x) - PACK_STRUCT_STRUCT - PACK_STRUCT_BEGIN - PACK_STRUCT_END - - Platform specific diagnostic output - - LWIP_PLATFORM_DIAG(x) - non-fatal, print a message. - LWIP_PLATFORM_ASSERT(x) - fatal, print message and abandon execution. - Portability defines for printf formatters: - U16_F, S16_F, X16_F, U32_F, S32_F, X32_F, SZT_F - - "lightweight" synchronization mechanisms - - SYS_ARCH_DECL_PROTECT(x) - declare a protection state variable. - SYS_ARCH_PROTECT(x) - enter protection mode. - SYS_ARCH_UNPROTECT(x) - leave protection mode. - - If the compiler does not provide memset() this file must include a - definition of it, or include a file which defines it. - - This file must either include a system-local which defines - the standard *nix error codes, or it should #define LWIP_PROVIDE_ERRNO - to make lwip/arch.h define the codes which are used throughout. - - -perf.h - Architecture specific performance measurement. - Measurement calls made throughout lwip, these can be defined to nothing. - PERF_START - start measuring something. - PERF_STOP(x) - stop measuring something, and record the result. - -sys_arch.h - Tied to sys_arch.c - - Arch dependent types for the following objects: - sys_sem_t, sys_mbox_t, sys_thread_t, - And, optionally: - sys_prot_t - - Defines to set vars of sys_mbox_t and sys_sem_t to NULL. - SYS_MBOX_NULL NULL - SYS_SEM_NULL NULL diff --git a/third_party/lwip/repo/lwip/src/FILES b/third_party/lwip/repo/lwip/src/FILES deleted file mode 100644 index 0be0741d0858c6..00000000000000 --- a/third_party/lwip/repo/lwip/src/FILES +++ /dev/null @@ -1,15 +0,0 @@ -api/ - The code for the high-level wrapper API. Not needed if - you use the lowel-level call-back/raw API. - -apps/ - Higher layer applications that are specifically programmed - with the lwIP low-level raw API. - -core/ - The core of the TPC/IP stack; protocol implementations, - memory and buffer management, and the low-level raw API. - -include/ - lwIP include files. - -netif/ - Generic network interface device drivers are kept here. - -For more information on the various subdirectories, check the FILES -file in each directory. diff --git a/third_party/lwip/repo/lwip/src/Filelists.mk b/third_party/lwip/repo/lwip/src/Filelists.mk deleted file mode 100644 index 7d30bb8f5397c1..00000000000000 --- a/third_party/lwip/repo/lwip/src/Filelists.mk +++ /dev/null @@ -1,181 +0,0 @@ -# -# Copyright (c) 2001, 2002 Swedish Institute of Computer Science. -# All rights reserved. -# -# Redistribution and use in source and binary forms, with or without modification, -# are permitted provided that the following conditions are met: -# -# 1. Redistributions of source code must retain the above copyright notice, -# this list of conditions and the following disclaimer. -# 2. Redistributions in binary form must reproduce the above copyright notice, -# this list of conditions and the following disclaimer in the documentation -# and/or other materials provided with the distribution. -# 3. The name of the author may not be used to endorse or promote products -# derived from this software without specific prior written permission. -# -# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED -# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT -# SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT -# OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING -# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY -# OF SUCH DAMAGE. -# -# This file is part of the lwIP TCP/IP stack. -# -# Author: Adam Dunkels -# - -# COREFILES, CORE4FILES: The minimum set of files needed for lwIP. -COREFILES=$(LWIPDIR)/core/init.c \ - $(LWIPDIR)/core/def.c \ - $(LWIPDIR)/core/dns.c \ - $(LWIPDIR)/core/inet_chksum.c \ - $(LWIPDIR)/core/ip.c \ - $(LWIPDIR)/core/mem.c \ - $(LWIPDIR)/core/memp.c \ - $(LWIPDIR)/core/netif.c \ - $(LWIPDIR)/core/pbuf.c \ - $(LWIPDIR)/core/raw.c \ - $(LWIPDIR)/core/stats.c \ - $(LWIPDIR)/core/sys.c \ - $(LWIPDIR)/core/tcp.c \ - $(LWIPDIR)/core/tcp_in.c \ - $(LWIPDIR)/core/tcp_out.c \ - $(LWIPDIR)/core/timeouts.c \ - $(LWIPDIR)/core/udp.c - -CORE4FILES=$(LWIPDIR)/core/ipv4/autoip.c \ - $(LWIPDIR)/core/ipv4/dhcp.c \ - $(LWIPDIR)/core/ipv4/etharp.c \ - $(LWIPDIR)/core/ipv4/icmp.c \ - $(LWIPDIR)/core/ipv4/igmp.c \ - $(LWIPDIR)/core/ipv4/ip4_frag.c \ - $(LWIPDIR)/core/ipv4/ip4.c \ - $(LWIPDIR)/core/ipv4/ip4_addr.c - -CORE6FILES=$(LWIPDIR)/core/ipv6/dhcp6.c \ - $(LWIPDIR)/core/ipv6/ethip6.c \ - $(LWIPDIR)/core/ipv6/icmp6.c \ - $(LWIPDIR)/core/ipv6/inet6.c \ - $(LWIPDIR)/core/ipv6/ip6.c \ - $(LWIPDIR)/core/ipv6/ip6_addr.c \ - $(LWIPDIR)/core/ipv6/ip6_frag.c \ - $(LWIPDIR)/core/ipv6/mld6.c \ - $(LWIPDIR)/core/ipv6/nd6.c - -# APIFILES: The files which implement the sequential and socket APIs. -APIFILES=$(LWIPDIR)/api/api_lib.c \ - $(LWIPDIR)/api/api_msg.c \ - $(LWIPDIR)/api/err.c \ - $(LWIPDIR)/api/netbuf.c \ - $(LWIPDIR)/api/netdb.c \ - $(LWIPDIR)/api/netifapi.c \ - $(LWIPDIR)/api/sockets.c \ - $(LWIPDIR)/api/tcpip.c - -# NETIFFILES: Files implementing various generic network interface functions -NETIFFILES=$(LWIPDIR)/netif/ethernet.c \ - $(LWIPDIR)/netif/slipif.c - -# SIXLOWPAN: 6LoWPAN -SIXLOWPAN=$(LWIPDIR)/netif/lowpan6.c \ - -# PPPFILES: PPP -PPPFILES=$(LWIPDIR)/netif/ppp/auth.c \ - $(LWIPDIR)/netif/ppp/ccp.c \ - $(LWIPDIR)/netif/ppp/chap-md5.c \ - $(LWIPDIR)/netif/ppp/chap_ms.c \ - $(LWIPDIR)/netif/ppp/chap-new.c \ - $(LWIPDIR)/netif/ppp/demand.c \ - $(LWIPDIR)/netif/ppp/eap.c \ - $(LWIPDIR)/netif/ppp/ecp.c \ - $(LWIPDIR)/netif/ppp/eui64.c \ - $(LWIPDIR)/netif/ppp/fsm.c \ - $(LWIPDIR)/netif/ppp/ipcp.c \ - $(LWIPDIR)/netif/ppp/ipv6cp.c \ - $(LWIPDIR)/netif/ppp/lcp.c \ - $(LWIPDIR)/netif/ppp/magic.c \ - $(LWIPDIR)/netif/ppp/mppe.c \ - $(LWIPDIR)/netif/ppp/multilink.c \ - $(LWIPDIR)/netif/ppp/ppp.c \ - $(LWIPDIR)/netif/ppp/pppapi.c \ - $(LWIPDIR)/netif/ppp/pppcrypt.c \ - $(LWIPDIR)/netif/ppp/pppoe.c \ - $(LWIPDIR)/netif/ppp/pppol2tp.c \ - $(LWIPDIR)/netif/ppp/pppos.c \ - $(LWIPDIR)/netif/ppp/upap.c \ - $(LWIPDIR)/netif/ppp/utils.c \ - $(LWIPDIR)/netif/ppp/vj.c \ - $(LWIPDIR)/netif/ppp/polarssl/arc4.c \ - $(LWIPDIR)/netif/ppp/polarssl/des.c \ - $(LWIPDIR)/netif/ppp/polarssl/md4.c \ - $(LWIPDIR)/netif/ppp/polarssl/md5.c \ - $(LWIPDIR)/netif/ppp/polarssl/sha1.c - -# LWIPNOAPPSFILES: All LWIP files without apps -LWIPNOAPPSFILES=$(COREFILES) \ - $(CORE4FILES) \ - $(CORE6FILES) \ - $(APIFILES) \ - $(NETIFFILES) \ - $(PPPFILES) \ - $(SIXLOWPAN) - -# SNMPFILES: SNMPv2c agent -SNMPFILES=$(LWIPDIR)/apps/snmp/snmp_asn1.c \ - $(LWIPDIR)/apps/snmp/snmp_core.c \ - $(LWIPDIR)/apps/snmp/snmp_mib2.c \ - $(LWIPDIR)/apps/snmp/snmp_mib2_icmp.c \ - $(LWIPDIR)/apps/snmp/snmp_mib2_interfaces.c \ - $(LWIPDIR)/apps/snmp/snmp_mib2_ip.c \ - $(LWIPDIR)/apps/snmp/snmp_mib2_snmp.c \ - $(LWIPDIR)/apps/snmp/snmp_mib2_system.c \ - $(LWIPDIR)/apps/snmp/snmp_mib2_tcp.c \ - $(LWIPDIR)/apps/snmp/snmp_mib2_udp.c \ - $(LWIPDIR)/apps/snmp/snmp_msg.c \ - $(LWIPDIR)/apps/snmp/snmpv3.c \ - $(LWIPDIR)/apps/snmp/snmp_netconn.c \ - $(LWIPDIR)/apps/snmp/snmp_pbuf_stream.c \ - $(LWIPDIR)/apps/snmp/snmp_raw.c \ - $(LWIPDIR)/apps/snmp/snmp_scalar.c \ - $(LWIPDIR)/apps/snmp/snmp_table.c \ - $(LWIPDIR)/apps/snmp/snmp_threadsync.c \ - $(LWIPDIR)/apps/snmp/snmp_traps.c \ - $(LWIPDIR)/apps/snmp/snmpv3_mbedtls.c \ - $(LWIPDIR)/apps/snmp/snmpv3_dummy.c - -# HTTPDFILES: HTTP server -HTTPDFILES=$(LWIPDIR)/apps/httpd/fs.c \ - $(LWIPDIR)/apps/httpd/httpd.c - -# LWIPERFFILES: IPERF server -LWIPERFFILES=$(LWIPDIR)/apps/lwiperf/lwiperf.c - -# SNTPFILES: SNTP client -SNTPFILES=$(LWIPDIR)/apps/sntp/sntp.c - -# MDNSFILES: MDNS responder -MDNSFILES=$(LWIPDIR)/apps/mdns/mdns.c - -# NETBIOSNSFILES: NetBIOS name server -NETBIOSNSFILES=$(LWIPDIR)/apps/netbiosns/netbiosns.c - -# TFTPFILES: TFTP server files -TFTPFILES=$(LWIPDIR)/apps/tftp/tftp_server.c - -# MQTTFILES: MQTT client files -MQTTFILES=$(LWIPDIR)/apps/mqtt/mqtt.c - -# LWIPAPPFILES: All LWIP APPs -LWIPAPPFILES=$(SNMPFILES) \ - $(HTTPDFILES) \ - $(LWIPERFFILES) \ - $(SNTPFILES) \ - $(MDNSFILES) \ - $(NETBIOSNSFILES) \ - $(TFTPFILES) \ - $(MQTTFILES) diff --git a/third_party/lwip/repo/lwip/src/api/api_lib.c b/third_party/lwip/repo/lwip/src/api/api_lib.c deleted file mode 100644 index 3c1d6a6c27031b..00000000000000 --- a/third_party/lwip/repo/lwip/src/api/api_lib.c +++ /dev/null @@ -1,1010 +0,0 @@ -/** - * @file - * Sequential API External module - * - * @defgroup netconn Netconn API - * @ingroup sequential_api - * Thread-safe, to be called from non-TCPIP threads only. - * TX/RX handling based on @ref netbuf (containing @ref pbuf) - * to avoid copying data around. - * - * @defgroup netconn_common Common functions - * @ingroup netconn - * For use with TCP and UDP - * - * @defgroup netconn_tcp TCP only - * @ingroup netconn - * TCP only functions - * - * @defgroup netconn_udp UDP only - * @ingroup netconn - * UDP only functions - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - */ - -/* This is the part of the API that is linked with - the application */ - -#include "lwip/opt.h" - -#if LWIP_NETCONN /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/api.h" -#include "lwip/memp.h" - -#include "lwip/ip.h" -#include "lwip/raw.h" -#include "lwip/udp.h" -#include "lwip/priv/api_msg.h" -#include "lwip/priv/tcp_priv.h" -#include "lwip/priv/tcpip_priv.h" - -#include - -#define API_MSG_VAR_REF(name) API_VAR_REF(name) -#define API_MSG_VAR_DECLARE(name) API_VAR_DECLARE(struct api_msg, name) -#define API_MSG_VAR_ALLOC(name) API_VAR_ALLOC(struct api_msg, MEMP_API_MSG, name, ERR_MEM) -#define API_MSG_VAR_ALLOC_RETURN_NULL(name) API_VAR_ALLOC(struct api_msg, MEMP_API_MSG, name, NULL) -#define API_MSG_VAR_FREE(name) API_VAR_FREE(MEMP_API_MSG, name) - -static err_t netconn_close_shutdown(struct netconn *conn, u8_t how); - -/** - * Call the lower part of a netconn_* function - * This function is then running in the thread context - * of tcpip_thread and has exclusive access to lwIP core code. - * - * @param fn function to call - * @param apimsg a struct containing the function to call and its parameters - * @return ERR_OK if the function was called, another err_t if not - */ -static err_t -netconn_apimsg(tcpip_callback_fn fn, struct api_msg *apimsg) -{ - err_t err; - -#ifdef LWIP_DEBUG - /* catch functions that don't set err */ - apimsg->err = ERR_VAL; -#endif /* LWIP_DEBUG */ - -#if LWIP_NETCONN_SEM_PER_THREAD - apimsg->op_completed_sem = LWIP_NETCONN_THREAD_SEM_GET(); -#endif /* LWIP_NETCONN_SEM_PER_THREAD */ - - err = tcpip_send_msg_wait_sem(fn, apimsg, LWIP_API_MSG_SEM(apimsg)); - if (err == ERR_OK) { - return apimsg->err; - } - return err; -} - -/** - * Create a new netconn (of a specific type) that has a callback function. - * The corresponding pcb is also created. - * - * @param t the type of 'connection' to create (@see enum netconn_type) - * @param proto the IP protocol for RAW IP pcbs - * @param callback a function to call on status changes (RX available, TX'ed) - * @return a newly allocated struct netconn or - * NULL on memory error - */ -struct netconn* -netconn_new_with_proto_and_callback(enum netconn_type t, u8_t proto, netconn_callback callback) -{ - struct netconn *conn; - API_MSG_VAR_DECLARE(msg); - API_MSG_VAR_ALLOC_RETURN_NULL(msg); - - conn = netconn_alloc(t, callback); - if (conn != NULL) { - err_t err; - - API_MSG_VAR_REF(msg).msg.n.proto = proto; - API_MSG_VAR_REF(msg).conn = conn; - err = netconn_apimsg(lwip_netconn_do_newconn, &API_MSG_VAR_REF(msg)); - if (err != ERR_OK) { - LWIP_ASSERT("freeing conn without freeing pcb", conn->pcb.tcp == NULL); - LWIP_ASSERT("conn has no recvmbox", sys_mbox_valid(&conn->recvmbox)); -#if LWIP_TCP - LWIP_ASSERT("conn->acceptmbox shouldn't exist", !sys_mbox_valid(&conn->acceptmbox)); -#endif /* LWIP_TCP */ -#if !LWIP_NETCONN_SEM_PER_THREAD - LWIP_ASSERT("conn has no op_completed", sys_sem_valid(&conn->op_completed)); - sys_sem_free(&conn->op_completed); -#endif /* !LWIP_NETCONN_SEM_PER_THREAD */ - sys_mbox_free(&conn->recvmbox); - memp_free(MEMP_NETCONN, conn); - API_MSG_VAR_FREE(msg); - return NULL; - } - } - API_MSG_VAR_FREE(msg); - return conn; -} - -/** - * @ingroup netconn_common - * Close a netconn 'connection' and free its resources. - * UDP and RAW connection are completely closed, TCP pcbs might still be in a waitstate - * after this returns. - * - * @param conn the netconn to delete - * @return ERR_OK if the connection was deleted - */ -err_t -netconn_delete(struct netconn *conn) -{ - err_t err; - API_MSG_VAR_DECLARE(msg); - - /* No ASSERT here because possible to get a (conn == NULL) if we got an accept error */ - if (conn == NULL) { - return ERR_OK; - } - - API_MSG_VAR_ALLOC(msg); - API_MSG_VAR_REF(msg).conn = conn; -#if LWIP_SO_SNDTIMEO || LWIP_SO_LINGER - /* get the time we started, which is later compared to - sys_now() + conn->send_timeout */ - API_MSG_VAR_REF(msg).msg.sd.time_started = sys_now(); -#else /* LWIP_SO_SNDTIMEO || LWIP_SO_LINGER */ -#if LWIP_TCP - API_MSG_VAR_REF(msg).msg.sd.polls_left = - ((LWIP_TCP_CLOSE_TIMEOUT_MS_DEFAULT + TCP_SLOW_INTERVAL - 1) / TCP_SLOW_INTERVAL) + 1; -#endif /* LWIP_TCP */ -#endif /* LWIP_SO_SNDTIMEO || LWIP_SO_LINGER */ - err = netconn_apimsg(lwip_netconn_do_delconn, &API_MSG_VAR_REF(msg)); - API_MSG_VAR_FREE(msg); - - if (err != ERR_OK) { - return err; - } - - netconn_free(conn); - - return ERR_OK; -} - -/** - * Get the local or remote IP address and port of a netconn. - * For RAW netconns, this returns the protocol instead of a port! - * - * @param conn the netconn to query - * @param addr a pointer to which to save the IP address - * @param port a pointer to which to save the port (or protocol for RAW) - * @param local 1 to get the local IP address, 0 to get the remote one - * @return ERR_CONN for invalid connections - * ERR_OK if the information was retrieved - */ -err_t -netconn_getaddr(struct netconn *conn, ip_addr_t *addr, u16_t *port, u8_t local) -{ - API_MSG_VAR_DECLARE(msg); - err_t err; - - LWIP_ERROR("netconn_getaddr: invalid conn", (conn != NULL), return ERR_ARG;); - LWIP_ERROR("netconn_getaddr: invalid addr", (addr != NULL), return ERR_ARG;); - LWIP_ERROR("netconn_getaddr: invalid port", (port != NULL), return ERR_ARG;); - - API_MSG_VAR_ALLOC(msg); - API_MSG_VAR_REF(msg).conn = conn; - API_MSG_VAR_REF(msg).msg.ad.local = local; -#if LWIP_MPU_COMPATIBLE - err = netconn_apimsg(lwip_netconn_do_getaddr, &API_MSG_VAR_REF(msg)); - *addr = msg->msg.ad.ipaddr; - *port = msg->msg.ad.port; -#else /* LWIP_MPU_COMPATIBLE */ - msg.msg.ad.ipaddr = addr; - msg.msg.ad.port = port; - err = netconn_apimsg(lwip_netconn_do_getaddr, &msg); -#endif /* LWIP_MPU_COMPATIBLE */ - API_MSG_VAR_FREE(msg); - - return err; -} - -/** - * @ingroup netconn_common - * Bind a netconn to a specific local IP address and port. - * Binding one netconn twice might not always be checked correctly! - * - * @param conn the netconn to bind - * @param addr the local IP address to bind the netconn to - * (use IP4_ADDR_ANY/IP6_ADDR_ANY to bind to all addresses) - * @param port the local port to bind the netconn to (not used for RAW) - * @return ERR_OK if bound, any other err_t on failure - */ -err_t -netconn_bind(struct netconn *conn, const ip_addr_t *addr, u16_t port) -{ - API_MSG_VAR_DECLARE(msg); - err_t err; - - LWIP_ERROR("netconn_bind: invalid conn", (conn != NULL), return ERR_ARG;); - -#if LWIP_IPV4 - /* Don't propagate NULL pointer (IP_ADDR_ANY alias) to subsequent functions */ - if (addr == NULL) { - addr = IP4_ADDR_ANY; - } -#endif /* LWIP_IPV4 */ - -#if LWIP_IPV4 && LWIP_IPV6 - /* "Socket API like" dual-stack support: If IP to bind to is IP6_ADDR_ANY, - * and NETCONN_FLAG_IPV6_V6ONLY is 0, use IP_ANY_TYPE to bind - */ - if ((netconn_get_ipv6only(conn) == 0) && - ip_addr_cmp(addr, IP6_ADDR_ANY)) { - addr = IP_ANY_TYPE; - } -#endif /* LWIP_IPV4 && LWIP_IPV6 */ - - API_MSG_VAR_ALLOC(msg); - API_MSG_VAR_REF(msg).conn = conn; - API_MSG_VAR_REF(msg).msg.bc.ipaddr = API_MSG_VAR_REF(addr); - API_MSG_VAR_REF(msg).msg.bc.port = port; - err = netconn_apimsg(lwip_netconn_do_bind, &API_MSG_VAR_REF(msg)); - API_MSG_VAR_FREE(msg); - - return err; -} - -/** - * @ingroup netconn_common - * Connect a netconn to a specific remote IP address and port. - * - * @param conn the netconn to connect - * @param addr the remote IP address to connect to - * @param port the remote port to connect to (no used for RAW) - * @return ERR_OK if connected, return value of tcp_/udp_/raw_connect otherwise - */ -err_t -netconn_connect(struct netconn *conn, const ip_addr_t *addr, u16_t port) -{ - API_MSG_VAR_DECLARE(msg); - err_t err; - - LWIP_ERROR("netconn_connect: invalid conn", (conn != NULL), return ERR_ARG;); - -#if LWIP_IPV4 - /* Don't propagate NULL pointer (IP_ADDR_ANY alias) to subsequent functions */ - if (addr == NULL) { - addr = IP4_ADDR_ANY; - } -#endif /* LWIP_IPV4 */ - - API_MSG_VAR_ALLOC(msg); - API_MSG_VAR_REF(msg).conn = conn; - API_MSG_VAR_REF(msg).msg.bc.ipaddr = API_MSG_VAR_REF(addr); - API_MSG_VAR_REF(msg).msg.bc.port = port; - err = netconn_apimsg(lwip_netconn_do_connect, &API_MSG_VAR_REF(msg)); - API_MSG_VAR_FREE(msg); - - return err; -} - -/** - * @ingroup netconn_udp - * Disconnect a netconn from its current peer (only valid for UDP netconns). - * - * @param conn the netconn to disconnect - * @return See @ref err_t - */ -err_t -netconn_disconnect(struct netconn *conn) -{ - API_MSG_VAR_DECLARE(msg); - err_t err; - - LWIP_ERROR("netconn_disconnect: invalid conn", (conn != NULL), return ERR_ARG;); - - API_MSG_VAR_ALLOC(msg); - API_MSG_VAR_REF(msg).conn = conn; - err = netconn_apimsg(lwip_netconn_do_disconnect, &API_MSG_VAR_REF(msg)); - API_MSG_VAR_FREE(msg); - - return err; -} - -/** - * @ingroup netconn_tcp - * Set a TCP netconn into listen mode - * - * @param conn the tcp netconn to set to listen mode - * @param backlog the listen backlog, only used if TCP_LISTEN_BACKLOG==1 - * @return ERR_OK if the netconn was set to listen (UDP and RAW netconns - * don't return any error (yet?)) - */ -err_t -netconn_listen_with_backlog(struct netconn *conn, u8_t backlog) -{ -#if LWIP_TCP - API_MSG_VAR_DECLARE(msg); - err_t err; - - /* This does no harm. If TCP_LISTEN_BACKLOG is off, backlog is unused. */ - LWIP_UNUSED_ARG(backlog); - - LWIP_ERROR("netconn_listen: invalid conn", (conn != NULL), return ERR_ARG;); - - API_MSG_VAR_ALLOC(msg); - API_MSG_VAR_REF(msg).conn = conn; -#if TCP_LISTEN_BACKLOG - API_MSG_VAR_REF(msg).msg.lb.backlog = backlog; -#endif /* TCP_LISTEN_BACKLOG */ - err = netconn_apimsg(lwip_netconn_do_listen, &API_MSG_VAR_REF(msg)); - API_MSG_VAR_FREE(msg); - - return err; -#else /* LWIP_TCP */ - LWIP_UNUSED_ARG(conn); - LWIP_UNUSED_ARG(backlog); - return ERR_ARG; -#endif /* LWIP_TCP */ -} - -/** - * @ingroup netconn_tcp - * Accept a new connection on a TCP listening netconn. - * - * @param conn the TCP listen netconn - * @param new_conn pointer where the new connection is stored - * @return ERR_OK if a new connection has been received or an error - * code otherwise - */ -err_t -netconn_accept(struct netconn *conn, struct netconn **new_conn) -{ -#if LWIP_TCP - void *accept_ptr; - struct netconn *newconn; -#if TCP_LISTEN_BACKLOG - API_MSG_VAR_DECLARE(msg); -#endif /* TCP_LISTEN_BACKLOG */ - - LWIP_ERROR("netconn_accept: invalid pointer", (new_conn != NULL), return ERR_ARG;); - *new_conn = NULL; - LWIP_ERROR("netconn_accept: invalid conn", (conn != NULL), return ERR_ARG;); - - if (ERR_IS_FATAL(conn->last_err)) { - /* don't recv on fatal errors: this might block the application task - waiting on acceptmbox forever! */ - return conn->last_err; - } - if (!sys_mbox_valid(&conn->acceptmbox)) { - return ERR_CLSD; - } - -#if TCP_LISTEN_BACKLOG - API_MSG_VAR_ALLOC(msg); -#endif /* TCP_LISTEN_BACKLOG */ - -#if LWIP_SO_RCVTIMEO - if (sys_arch_mbox_fetch(&conn->acceptmbox, &accept_ptr, conn->recv_timeout) == SYS_ARCH_TIMEOUT) { -#if TCP_LISTEN_BACKLOG - API_MSG_VAR_FREE(msg); -#endif /* TCP_LISTEN_BACKLOG */ - return ERR_TIMEOUT; - } -#else - sys_arch_mbox_fetch(&conn->acceptmbox, &accept_ptr, 0); -#endif /* LWIP_SO_RCVTIMEO*/ - newconn = (struct netconn *)accept_ptr; - /* Register event with callback */ - API_EVENT(conn, NETCONN_EVT_RCVMINUS, 0); - - if (accept_ptr == &netconn_aborted) { - /* a connection has been aborted: out of pcbs or out of netconns during accept */ - /* @todo: set netconn error, but this would be fatal and thus block further accepts */ -#if TCP_LISTEN_BACKLOG - API_MSG_VAR_FREE(msg); -#endif /* TCP_LISTEN_BACKLOG */ - return ERR_ABRT; - } - if (newconn == NULL) { - /* connection has been aborted */ - /* in this special case, we set the netconn error from application thread, as - on a ready-to-accept listening netconn, there should not be anything running - in tcpip_thread */ - NETCONN_SET_SAFE_ERR(conn, ERR_CLSD); -#if TCP_LISTEN_BACKLOG - API_MSG_VAR_FREE(msg); -#endif /* TCP_LISTEN_BACKLOG */ - return ERR_CLSD; - } -#if TCP_LISTEN_BACKLOG - /* Let the stack know that we have accepted the connection. */ - API_MSG_VAR_REF(msg).conn = newconn; - /* don't care for the return value of lwip_netconn_do_recv */ - netconn_apimsg(lwip_netconn_do_accepted, &API_MSG_VAR_REF(msg)); - API_MSG_VAR_FREE(msg); -#endif /* TCP_LISTEN_BACKLOG */ - - *new_conn = newconn; - /* don't set conn->last_err: it's only ERR_OK, anyway */ - return ERR_OK; -#else /* LWIP_TCP */ - LWIP_UNUSED_ARG(conn); - LWIP_UNUSED_ARG(new_conn); - return ERR_ARG; -#endif /* LWIP_TCP */ -} - -/** - * @ingroup netconn_common - * Receive data: actual implementation that doesn't care whether pbuf or netbuf - * is received - * - * @param conn the netconn from which to receive data - * @param new_buf pointer where a new pbuf/netbuf is stored when received data - * @return ERR_OK if data has been received, an error code otherwise (timeout, - * memory error or another error) - */ -static err_t -netconn_recv_data(struct netconn *conn, void **new_buf) -{ - void *buf = NULL; - u16_t len; -#if LWIP_TCP - API_MSG_VAR_DECLARE(msg); -#if LWIP_MPU_COMPATIBLE - msg = NULL; -#endif -#endif /* LWIP_TCP */ - - LWIP_ERROR("netconn_recv: invalid pointer", (new_buf != NULL), return ERR_ARG;); - *new_buf = NULL; - LWIP_ERROR("netconn_recv: invalid conn", (conn != NULL), return ERR_ARG;); -#if LWIP_TCP -#if (LWIP_UDP || LWIP_RAW) - if (NETCONNTYPE_GROUP(conn->type) == NETCONN_TCP) -#endif /* (LWIP_UDP || LWIP_RAW) */ - { - if (!sys_mbox_valid(&conn->recvmbox)) { - /* This happens when calling this function after receiving FIN */ - return sys_mbox_valid(&conn->acceptmbox) ? ERR_CONN : ERR_CLSD; - } - } -#endif /* LWIP_TCP */ - LWIP_ERROR("netconn_recv: invalid recvmbox", sys_mbox_valid(&conn->recvmbox), return ERR_CONN;); - - if (ERR_IS_FATAL(conn->last_err)) { - /* don't recv on fatal errors: this might block the application task - waiting on recvmbox forever! */ - /* @todo: this does not allow us to fetch data that has been put into recvmbox - before the fatal error occurred - is that a problem? */ - return conn->last_err; - } -#if LWIP_TCP -#if (LWIP_UDP || LWIP_RAW) - if (NETCONNTYPE_GROUP(conn->type) == NETCONN_TCP) -#endif /* (LWIP_UDP || LWIP_RAW) */ - { - API_MSG_VAR_ALLOC(msg); - } -#endif /* LWIP_TCP */ - -#if LWIP_SO_RCVTIMEO - if (sys_arch_mbox_fetch(&conn->recvmbox, &buf, conn->recv_timeout) == SYS_ARCH_TIMEOUT) { -#if LWIP_TCP -#if (LWIP_UDP || LWIP_RAW) - if (NETCONNTYPE_GROUP(conn->type) == NETCONN_TCP) -#endif /* (LWIP_UDP || LWIP_RAW) */ - { - API_MSG_VAR_FREE(msg); - } -#endif /* LWIP_TCP */ - return ERR_TIMEOUT; - } -#else - sys_arch_mbox_fetch(&conn->recvmbox, &buf, 0); -#endif /* LWIP_SO_RCVTIMEO*/ - -#if LWIP_TCP -#if (LWIP_UDP || LWIP_RAW) - if (NETCONNTYPE_GROUP(conn->type) == NETCONN_TCP) -#endif /* (LWIP_UDP || LWIP_RAW) */ - { - /* Let the stack know that we have taken the data. */ - /* @todo: Speedup: Don't block and wait for the answer here - (to prevent multiple thread-switches). */ - API_MSG_VAR_REF(msg).conn = conn; - if (buf != NULL) { - API_MSG_VAR_REF(msg).msg.r.len = ((struct pbuf *)buf)->tot_len; - } else { - API_MSG_VAR_REF(msg).msg.r.len = 1; - } - - /* don't care for the return value of lwip_netconn_do_recv */ - netconn_apimsg(lwip_netconn_do_recv, &API_MSG_VAR_REF(msg)); - API_MSG_VAR_FREE(msg); - - /* If we are closed, we indicate that we no longer wish to use the socket */ - if (buf == NULL) { - API_EVENT(conn, NETCONN_EVT_RCVMINUS, 0); - if (conn->pcb.ip == NULL) { - /* race condition: RST during recv */ - return conn->last_err == ERR_OK ? ERR_RST : conn->last_err; - } - /* RX side is closed, so deallocate the recvmbox */ - netconn_close_shutdown(conn, NETCONN_SHUT_RD); - /* Don' store ERR_CLSD as conn->err since we are only half-closed */ - return ERR_CLSD; - } - len = ((struct pbuf *)buf)->tot_len; - } -#endif /* LWIP_TCP */ -#if LWIP_TCP && (LWIP_UDP || LWIP_RAW) - else -#endif /* LWIP_TCP && (LWIP_UDP || LWIP_RAW) */ -#if (LWIP_UDP || LWIP_RAW) - { - LWIP_ASSERT("buf != NULL", buf != NULL); - len = netbuf_len((struct netbuf*)buf); - } -#endif /* (LWIP_UDP || LWIP_RAW) */ - -#if LWIP_SO_RCVBUF - SYS_ARCH_DEC(conn->recv_avail, len); -#endif /* LWIP_SO_RCVBUF */ - /* Register event with callback */ - API_EVENT(conn, NETCONN_EVT_RCVMINUS, len); - - LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_recv_data: received %p, len=%"U16_F"\n", buf, len)); - - *new_buf = buf; - /* don't set conn->last_err: it's only ERR_OK, anyway */ - return ERR_OK; -} - -/** - * @ingroup netconn_tcp - * Receive data (in form of a pbuf) from a TCP netconn - * - * @param conn the netconn from which to receive data - * @param new_buf pointer where a new pbuf is stored when received data - * @return ERR_OK if data has been received, an error code otherwise (timeout, - * memory error or another error) - * ERR_ARG if conn is not a TCP netconn - */ -err_t -netconn_recv_tcp_pbuf(struct netconn *conn, struct pbuf **new_buf) -{ - LWIP_ERROR("netconn_recv: invalid conn", (conn != NULL) && - NETCONNTYPE_GROUP(netconn_type(conn)) == NETCONN_TCP, return ERR_ARG;); - - return netconn_recv_data(conn, (void **)new_buf); -} - -/** - * @ingroup netconn_common - * Receive data (in form of a netbuf containing a packet buffer) from a netconn - * - * @param conn the netconn from which to receive data - * @param new_buf pointer where a new netbuf is stored when received data - * @return ERR_OK if data has been received, an error code otherwise (timeout, - * memory error or another error) - */ -err_t -netconn_recv(struct netconn *conn, struct netbuf **new_buf) -{ -#if LWIP_TCP - struct netbuf *buf = NULL; - err_t err; -#endif /* LWIP_TCP */ - - LWIP_ERROR("netconn_recv: invalid pointer", (new_buf != NULL), return ERR_ARG;); - *new_buf = NULL; - LWIP_ERROR("netconn_recv: invalid conn", (conn != NULL), return ERR_ARG;); - -#if LWIP_TCP -#if (LWIP_UDP || LWIP_RAW) - if (NETCONNTYPE_GROUP(conn->type) == NETCONN_TCP) -#endif /* (LWIP_UDP || LWIP_RAW) */ - { - struct pbuf *p = NULL; - /* This is not a listening netconn, since recvmbox is set */ - - buf = (struct netbuf *)memp_malloc(MEMP_NETBUF); - if (buf == NULL) { - return ERR_MEM; - } - - err = netconn_recv_data(conn, (void **)&p); - if (err != ERR_OK) { - memp_free(MEMP_NETBUF, buf); - return err; - } - LWIP_ASSERT("p != NULL", p != NULL); - - buf->p = p; - buf->ptr = p; - buf->port = 0; - ip_addr_set_zero(&buf->addr); - *new_buf = buf; - /* don't set conn->last_err: it's only ERR_OK, anyway */ - return ERR_OK; - } -#endif /* LWIP_TCP */ -#if LWIP_TCP && (LWIP_UDP || LWIP_RAW) - else -#endif /* LWIP_TCP && (LWIP_UDP || LWIP_RAW) */ - { -#if (LWIP_UDP || LWIP_RAW) - return netconn_recv_data(conn, (void **)new_buf); -#endif /* (LWIP_UDP || LWIP_RAW) */ - } -} - -/** - * @ingroup netconn_udp - * Send data (in form of a netbuf) to a specific remote IP address and port. - * Only to be used for UDP and RAW netconns (not TCP). - * - * @param conn the netconn over which to send data - * @param buf a netbuf containing the data to send - * @param addr the remote IP address to which to send the data - * @param port the remote port to which to send the data - * @return ERR_OK if data was sent, any other err_t on error - */ -err_t -netconn_sendto(struct netconn *conn, struct netbuf *buf, const ip_addr_t *addr, u16_t port) -{ - if (buf != NULL) { - ip_addr_set(&buf->addr, addr); - buf->port = port; - return netconn_send(conn, buf); - } - return ERR_VAL; -} - -/** - * @ingroup netconn_udp - * Send data over a UDP or RAW netconn (that is already connected). - * - * @param conn the UDP or RAW netconn over which to send data - * @param buf a netbuf containing the data to send - * @return ERR_OK if data was sent, any other err_t on error - */ -err_t -netconn_send(struct netconn *conn, struct netbuf *buf) -{ - API_MSG_VAR_DECLARE(msg); - err_t err; - - LWIP_ERROR("netconn_send: invalid conn", (conn != NULL), return ERR_ARG;); - - LWIP_DEBUGF(API_LIB_DEBUG, ("netconn_send: sending %"U16_F" bytes\n", buf->p->tot_len)); - - API_MSG_VAR_ALLOC(msg); - API_MSG_VAR_REF(msg).conn = conn; - API_MSG_VAR_REF(msg).msg.b = buf; - err = netconn_apimsg(lwip_netconn_do_send, &API_MSG_VAR_REF(msg)); - API_MSG_VAR_FREE(msg); - - return err; -} - -/** - * @ingroup netconn_tcp - * Send data over a TCP netconn. - * - * @param conn the TCP netconn over which to send data - * @param dataptr pointer to the application buffer that contains the data to send - * @param size size of the application data to send - * @param apiflags combination of following flags : - * - NETCONN_COPY: data will be copied into memory belonging to the stack - * - NETCONN_MORE: for TCP connection, PSH flag will be set on last segment sent - * - NETCONN_DONTBLOCK: only write the data if all data can be written at once - * @param bytes_written pointer to a location that receives the number of written bytes - * @return ERR_OK if data was sent, any other err_t on error - */ -err_t -netconn_write_partly(struct netconn *conn, const void *dataptr, size_t size, - u8_t apiflags, size_t *bytes_written) -{ - API_MSG_VAR_DECLARE(msg); - err_t err; - u8_t dontblock; - - LWIP_ERROR("netconn_write: invalid conn", (conn != NULL), return ERR_ARG;); - LWIP_ERROR("netconn_write: invalid conn->type", (NETCONNTYPE_GROUP(conn->type)== NETCONN_TCP), return ERR_VAL;); - if (size == 0) { - return ERR_OK; - } - dontblock = netconn_is_nonblocking(conn) || (apiflags & NETCONN_DONTBLOCK); -#if LWIP_SO_SNDTIMEO - if (conn->send_timeout != 0) { - dontblock = 1; - } -#endif /* LWIP_SO_SNDTIMEO */ - if (dontblock && !bytes_written) { - /* This implies netconn_write() cannot be used for non-blocking send, since - it has no way to return the number of bytes written. */ - return ERR_VAL; - } - - API_MSG_VAR_ALLOC(msg); - /* non-blocking write sends as much */ - API_MSG_VAR_REF(msg).conn = conn; - API_MSG_VAR_REF(msg).msg.w.dataptr = dataptr; - API_MSG_VAR_REF(msg).msg.w.apiflags = apiflags; - API_MSG_VAR_REF(msg).msg.w.len = size; -#if LWIP_SO_SNDTIMEO - if (conn->send_timeout != 0) { - /* get the time we started, which is later compared to - sys_now() + conn->send_timeout */ - API_MSG_VAR_REF(msg).msg.w.time_started = sys_now(); - } else { - API_MSG_VAR_REF(msg).msg.w.time_started = 0; - } -#endif /* LWIP_SO_SNDTIMEO */ - - /* For locking the core: this _can_ be delayed on low memory/low send buffer, - but if it is, this is done inside api_msg.c:do_write(), so we can use the - non-blocking version here. */ - err = netconn_apimsg(lwip_netconn_do_write, &API_MSG_VAR_REF(msg)); - if ((err == ERR_OK) && (bytes_written != NULL)) { - if (dontblock) { - /* nonblocking write: maybe the data has been sent partly */ - *bytes_written = API_MSG_VAR_REF(msg).msg.w.len; - } else { - /* blocking call succeeded: all data has been sent if it */ - *bytes_written = size; - } - } - API_MSG_VAR_FREE(msg); - - return err; -} - -/** - * @ingroup netconn_tcp - * Close or shutdown a TCP netconn (doesn't delete it). - * - * @param conn the TCP netconn to close or shutdown - * @param how fully close or only shutdown one side? - * @return ERR_OK if the netconn was closed, any other err_t on error - */ -static err_t -netconn_close_shutdown(struct netconn *conn, u8_t how) -{ - API_MSG_VAR_DECLARE(msg); - err_t err; - LWIP_UNUSED_ARG(how); - - LWIP_ERROR("netconn_close: invalid conn", (conn != NULL), return ERR_ARG;); - - API_MSG_VAR_ALLOC(msg); - API_MSG_VAR_REF(msg).conn = conn; -#if LWIP_TCP - /* shutting down both ends is the same as closing */ - API_MSG_VAR_REF(msg).msg.sd.shut = how; -#if LWIP_SO_SNDTIMEO || LWIP_SO_LINGER - /* get the time we started, which is later compared to - sys_now() + conn->send_timeout */ - API_MSG_VAR_REF(msg).msg.sd.time_started = sys_now(); -#else /* LWIP_SO_SNDTIMEO || LWIP_SO_LINGER */ - API_MSG_VAR_REF(msg).msg.sd.polls_left = - ((LWIP_TCP_CLOSE_TIMEOUT_MS_DEFAULT + TCP_SLOW_INTERVAL - 1) / TCP_SLOW_INTERVAL) + 1; -#endif /* LWIP_SO_SNDTIMEO || LWIP_SO_LINGER */ -#endif /* LWIP_TCP */ - err = netconn_apimsg(lwip_netconn_do_close, &API_MSG_VAR_REF(msg)); - API_MSG_VAR_FREE(msg); - - return err; -} - -/** - * @ingroup netconn_tcp - * Close a TCP netconn (doesn't delete it). - * - * @param conn the TCP netconn to close - * @return ERR_OK if the netconn was closed, any other err_t on error - */ -err_t -netconn_close(struct netconn *conn) -{ - /* shutting down both ends is the same as closing */ - return netconn_close_shutdown(conn, NETCONN_SHUT_RDWR); -} - -/** - * @ingroup netconn_tcp - * Shut down one or both sides of a TCP netconn (doesn't delete it). - * - * @param conn the TCP netconn to shut down - * @param shut_rx shut down the RX side (no more read possible after this) - * @param shut_tx shut down the TX side (no more write possible after this) - * @return ERR_OK if the netconn was closed, any other err_t on error - */ -err_t -netconn_shutdown(struct netconn *conn, u8_t shut_rx, u8_t shut_tx) -{ - return netconn_close_shutdown(conn, (shut_rx ? NETCONN_SHUT_RD : 0) | (shut_tx ? NETCONN_SHUT_WR : 0)); -} - -#if LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) -/** - * @ingroup netconn_udp - * Join multicast groups for UDP netconns. - * - * @param conn the UDP netconn for which to change multicast addresses - * @param multiaddr IP address of the multicast group to join or leave - * @param netif_addr the IP address of the network interface on which to send - * the igmp message - * @param join_or_leave flag whether to send a join- or leave-message - * @return ERR_OK if the action was taken, any err_t on error - */ -err_t -netconn_join_leave_group(struct netconn *conn, - const ip_addr_t *multiaddr, - const ip_addr_t *netif_addr, - enum netconn_igmp join_or_leave) -{ - API_MSG_VAR_DECLARE(msg); - err_t err; - - LWIP_ERROR("netconn_join_leave_group: invalid conn", (conn != NULL), return ERR_ARG;); - - API_MSG_VAR_ALLOC(msg); - -#if LWIP_IPV4 - /* Don't propagate NULL pointer (IP_ADDR_ANY alias) to subsequent functions */ - if (multiaddr == NULL) { - multiaddr = IP4_ADDR_ANY; - } - if (netif_addr == NULL) { - netif_addr = IP4_ADDR_ANY; - } -#endif /* LWIP_IPV4 */ - - API_MSG_VAR_REF(msg).conn = conn; - API_MSG_VAR_REF(msg).msg.jl.multiaddr = API_MSG_VAR_REF(multiaddr); - API_MSG_VAR_REF(msg).msg.jl.netif_addr = API_MSG_VAR_REF(netif_addr); - API_MSG_VAR_REF(msg).msg.jl.join_or_leave = join_or_leave; - err = netconn_apimsg(lwip_netconn_do_join_leave_group, &API_MSG_VAR_REF(msg)); - API_MSG_VAR_FREE(msg); - - return err; -} -#endif /* LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) */ - -#if LWIP_DNS -/** - * @ingroup netconn_common - * Execute a DNS query, only one IP address is returned - * - * @param name a string representation of the DNS host name to query - * @param addr a preallocated ip_addr_t where to store the resolved IP address - * @param dns_addrtype IP address type (IPv4 / IPv6) - * @return ERR_OK: resolving succeeded - * ERR_MEM: memory error, try again later - * ERR_ARG: dns client not initialized or invalid hostname - * ERR_VAL: dns server response was invalid - */ -#if LWIP_IPV4 && LWIP_IPV6 -err_t -netconn_gethostbyname_addrtype(const char *name, ip_addr_t *addr, u8_t dns_addrtype) -#else -err_t -netconn_gethostbyname(const char *name, ip_addr_t *addr) -#endif -{ - API_VAR_DECLARE(struct dns_api_msg, msg); -#if !LWIP_MPU_COMPATIBLE - sys_sem_t sem; -#endif /* LWIP_MPU_COMPATIBLE */ - err_t err; - err_t cberr; - - LWIP_ERROR("netconn_gethostbyname: invalid name", (name != NULL), return ERR_ARG;); - LWIP_ERROR("netconn_gethostbyname: invalid addr", (addr != NULL), return ERR_ARG;); -#if LWIP_MPU_COMPATIBLE - if (strlen(name) >= DNS_MAX_NAME_LENGTH) { - return ERR_ARG; - } -#endif - - API_VAR_ALLOC(struct dns_api_msg, MEMP_DNS_API_MSG, msg, ERR_MEM); -#if LWIP_MPU_COMPATIBLE - strncpy(API_VAR_REF(msg).name, name, DNS_MAX_NAME_LENGTH-1); - API_VAR_REF(msg).name[DNS_MAX_NAME_LENGTH-1] = 0; -#else /* LWIP_MPU_COMPATIBLE */ - msg.err = &err; - msg.sem = &sem; - API_VAR_REF(msg).addr = API_VAR_REF(addr); - API_VAR_REF(msg).name = name; -#endif /* LWIP_MPU_COMPATIBLE */ -#if LWIP_IPV4 && LWIP_IPV6 - API_VAR_REF(msg).dns_addrtype = dns_addrtype; -#endif /* LWIP_IPV4 && LWIP_IPV6 */ -#if LWIP_NETCONN_SEM_PER_THREAD - API_VAR_REF(msg).sem = LWIP_NETCONN_THREAD_SEM_GET(); -#else /* LWIP_NETCONN_SEM_PER_THREAD*/ - err = sys_sem_new(API_EXPR_REF(API_VAR_REF(msg).sem), 0); - if (err != ERR_OK) { - API_VAR_FREE(MEMP_DNS_API_MSG, msg); - return err; - } -#endif /* LWIP_NETCONN_SEM_PER_THREAD */ - - cberr = tcpip_callback(lwip_netconn_do_gethostbyname, &API_VAR_REF(msg)); - if (cberr != ERR_OK) { -#if !LWIP_NETCONN_SEM_PER_THREAD - sys_sem_free(API_EXPR_REF(API_VAR_REF(msg).sem)); -#endif /* !LWIP_NETCONN_SEM_PER_THREAD */ - API_VAR_FREE(MEMP_DNS_API_MSG, msg); - return cberr; - } - sys_sem_wait(API_EXPR_REF_SEM(API_VAR_REF(msg).sem)); -#if !LWIP_NETCONN_SEM_PER_THREAD - sys_sem_free(API_EXPR_REF(API_VAR_REF(msg).sem)); -#endif /* !LWIP_NETCONN_SEM_PER_THREAD */ - -#if LWIP_MPU_COMPATIBLE - *addr = msg->addr; - err = msg->err; -#endif /* LWIP_MPU_COMPATIBLE */ - - API_VAR_FREE(MEMP_DNS_API_MSG, msg); - return err; -} -#endif /* LWIP_DNS*/ - -#if LWIP_NETCONN_SEM_PER_THREAD -void -netconn_thread_init(void) -{ - sys_sem_t *sem = LWIP_NETCONN_THREAD_SEM_GET(); - if ((sem == NULL) || !sys_sem_valid(sem)) { - /* call alloc only once */ - LWIP_NETCONN_THREAD_SEM_ALLOC(); - LWIP_ASSERT("LWIP_NETCONN_THREAD_SEM_ALLOC() failed", sys_sem_valid(LWIP_NETCONN_THREAD_SEM_GET())); - } -} - -void -netconn_thread_cleanup(void) -{ - sys_sem_t *sem = LWIP_NETCONN_THREAD_SEM_GET(); - if ((sem != NULL) && sys_sem_valid(sem)) { - /* call free only once */ - LWIP_NETCONN_THREAD_SEM_FREE(); - } -} -#endif /* LWIP_NETCONN_SEM_PER_THREAD */ - -#endif /* LWIP_NETCONN */ diff --git a/third_party/lwip/repo/lwip/src/api/api_msg.c b/third_party/lwip/repo/lwip/src/api/api_msg.c deleted file mode 100644 index 5a8dad9bcacbf1..00000000000000 --- a/third_party/lwip/repo/lwip/src/api/api_msg.c +++ /dev/null @@ -1,1953 +0,0 @@ -/** - * @file - * Sequential API Internal module - * - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ - -#include "lwip/opt.h" - -#if LWIP_NETCONN /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/priv/api_msg.h" - -#include "lwip/ip.h" -#include "lwip/ip_addr.h" -#include "lwip/udp.h" -#include "lwip/tcp.h" -#include "lwip/raw.h" - -#include "lwip/memp.h" -#include "lwip/igmp.h" -#include "lwip/dns.h" -#include "lwip/mld6.h" -#include "lwip/priv/tcpip_priv.h" - -#include - -/* netconns are polled once per second (e.g. continue write on memory error) */ -#define NETCONN_TCP_POLL_INTERVAL 2 - -#define SET_NONBLOCKING_CONNECT(conn, val) do { if (val) { \ - (conn)->flags |= NETCONN_FLAG_IN_NONBLOCKING_CONNECT; \ -} else { \ - (conn)->flags &= ~ NETCONN_FLAG_IN_NONBLOCKING_CONNECT; }} while(0) -#define IN_NONBLOCKING_CONNECT(conn) (((conn)->flags & NETCONN_FLAG_IN_NONBLOCKING_CONNECT) != 0) - -/* forward declarations */ -#if LWIP_TCP -#if LWIP_TCPIP_CORE_LOCKING -#define WRITE_DELAYED , 1 -#define WRITE_DELAYED_PARAM , u8_t delayed -#else /* LWIP_TCPIP_CORE_LOCKING */ -#define WRITE_DELAYED -#define WRITE_DELAYED_PARAM -#endif /* LWIP_TCPIP_CORE_LOCKING */ -static err_t lwip_netconn_do_writemore(struct netconn *conn WRITE_DELAYED_PARAM); -static err_t lwip_netconn_do_close_internal(struct netconn *conn WRITE_DELAYED_PARAM); -#endif - -#if LWIP_TCPIP_CORE_LOCKING -#define TCPIP_APIMSG_ACK(m) NETCONN_SET_SAFE_ERR((m)->conn, (m)->err) -#else /* LWIP_TCPIP_CORE_LOCKING */ -#define TCPIP_APIMSG_ACK(m) do { NETCONN_SET_SAFE_ERR((m)->conn, (m)->err); sys_sem_signal(LWIP_API_MSG_SEM(m)); } while(0) -#endif /* LWIP_TCPIP_CORE_LOCKING */ - -#if LWIP_TCP -u8_t netconn_aborted; -#endif /* LWIP_TCP */ - -#if LWIP_RAW -/** - * Receive callback function for RAW netconns. - * Doesn't 'eat' the packet, only copies it and sends it to - * conn->recvmbox - * - * @see raw.h (struct raw_pcb.recv) for parameters and return value - */ -static u8_t -recv_raw(void *arg, struct raw_pcb *pcb, struct pbuf *p, - const ip_addr_t *addr) -{ - struct pbuf *q; - struct netbuf *buf; - struct netconn *conn; - - LWIP_UNUSED_ARG(addr); - conn = (struct netconn *)arg; - - if ((conn != NULL) && sys_mbox_valid(&conn->recvmbox)) { -#if LWIP_SO_RCVBUF - int recv_avail; - SYS_ARCH_GET(conn->recv_avail, recv_avail); - if ((recv_avail + (int)(p->tot_len)) > conn->recv_bufsize) { - return 0; - } -#endif /* LWIP_SO_RCVBUF */ - /* copy the whole packet into new pbufs */ - q = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_RAM); - if (q != NULL) { - if (pbuf_copy(q, p) != ERR_OK) { - pbuf_free(q); - q = NULL; - } - } - - if (q != NULL) { - u16_t len; - buf = (struct netbuf *)memp_malloc(MEMP_NETBUF); - if (buf == NULL) { - pbuf_free(q); - return 0; - } - - buf->p = q; - buf->ptr = q; - ip_addr_copy(buf->addr, *ip_current_src_addr()); - buf->port = pcb->protocol; - - len = q->tot_len; - if (sys_mbox_trypost(&conn->recvmbox, buf) != ERR_OK) { - netbuf_delete(buf); - return 0; - } else { -#if LWIP_SO_RCVBUF - SYS_ARCH_INC(conn->recv_avail, len); -#endif /* LWIP_SO_RCVBUF */ - /* Register event with callback */ - API_EVENT(conn, NETCONN_EVT_RCVPLUS, len); - } - } - } - - return 0; /* do not eat the packet */ -} -#endif /* LWIP_RAW*/ - -#if LWIP_UDP -/** - * Receive callback function for UDP netconns. - * Posts the packet to conn->recvmbox or deletes it on memory error. - * - * @see udp.h (struct udp_pcb.recv) for parameters - */ -static void -recv_udp(void *arg, struct udp_pcb *pcb, struct pbuf *p, - const ip_addr_t *addr, u16_t port) -{ - struct netbuf *buf; - struct netconn *conn; - u16_t len; -#if LWIP_SO_RCVBUF - int recv_avail; -#endif /* LWIP_SO_RCVBUF */ - - LWIP_UNUSED_ARG(pcb); /* only used for asserts... */ - LWIP_ASSERT("recv_udp must have a pcb argument", pcb != NULL); - LWIP_ASSERT("recv_udp must have an argument", arg != NULL); - conn = (struct netconn *)arg; - - if (conn == NULL) { - pbuf_free(p); - return; - } - - LWIP_ASSERT("recv_udp: recv for wrong pcb!", conn->pcb.udp == pcb); - -#if LWIP_SO_RCVBUF - SYS_ARCH_GET(conn->recv_avail, recv_avail); - if (!sys_mbox_valid(&conn->recvmbox) || - ((recv_avail + (int)(p->tot_len)) > conn->recv_bufsize)) { -#else /* LWIP_SO_RCVBUF */ - if (!sys_mbox_valid(&conn->recvmbox)) { -#endif /* LWIP_SO_RCVBUF */ - pbuf_free(p); - return; - } - - buf = (struct netbuf *)memp_malloc(MEMP_NETBUF); - if (buf == NULL) { - pbuf_free(p); - return; - } else { - buf->p = p; - buf->ptr = p; - ip_addr_set(&buf->addr, addr); - buf->port = port; -#if LWIP_NETBUF_RECVINFO - { - /* get the UDP header - always in the first pbuf, ensured by udp_input */ - const struct udp_hdr* udphdr = (const struct udp_hdr*)ip_next_header_ptr(); -#if LWIP_CHECKSUM_ON_COPY - buf->flags = NETBUF_FLAG_DESTADDR; -#endif /* LWIP_CHECKSUM_ON_COPY */ - ip_addr_set(&buf->toaddr, ip_current_dest_addr()); - buf->toport_chksum = udphdr->dest; - } -#endif /* LWIP_NETBUF_RECVINFO */ - } - - len = p->tot_len; - if (sys_mbox_trypost(&conn->recvmbox, buf) != ERR_OK) { - netbuf_delete(buf); - return; - } else { -#if LWIP_SO_RCVBUF - SYS_ARCH_INC(conn->recv_avail, len); -#endif /* LWIP_SO_RCVBUF */ - /* Register event with callback */ - API_EVENT(conn, NETCONN_EVT_RCVPLUS, len); - } -} -#endif /* LWIP_UDP */ - -#if LWIP_TCP -/** - * Receive callback function for TCP netconns. - * Posts the packet to conn->recvmbox, but doesn't delete it on errors. - * - * @see tcp.h (struct tcp_pcb.recv) for parameters and return value - */ -static err_t -recv_tcp(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) -{ - struct netconn *conn; - u16_t len; - - LWIP_UNUSED_ARG(pcb); - LWIP_ASSERT("recv_tcp must have a pcb argument", pcb != NULL); - LWIP_ASSERT("recv_tcp must have an argument", arg != NULL); - conn = (struct netconn *)arg; - - if (conn == NULL) { - return ERR_VAL; - } - LWIP_ASSERT("recv_tcp: recv for wrong pcb!", conn->pcb.tcp == pcb); - - if (!sys_mbox_valid(&conn->recvmbox)) { - /* recvmbox already deleted */ - if (p != NULL) { - tcp_recved(pcb, p->tot_len); - pbuf_free(p); - } - return ERR_OK; - } - /* Unlike for UDP or RAW pcbs, don't check for available space - using recv_avail since that could break the connection - (data is already ACKed) */ - - /* don't overwrite fatal errors! */ - if (err != ERR_OK) { - NETCONN_SET_SAFE_ERR(conn, err); - } - - if (p != NULL) { - len = p->tot_len; - } else { - len = 0; - } - - if (sys_mbox_trypost(&conn->recvmbox, p) != ERR_OK) { - /* don't deallocate p: it is presented to us later again from tcp_fasttmr! */ - return ERR_MEM; - } else { -#if LWIP_SO_RCVBUF - SYS_ARCH_INC(conn->recv_avail, len); -#endif /* LWIP_SO_RCVBUF */ - /* Register event with callback */ - API_EVENT(conn, NETCONN_EVT_RCVPLUS, len); - } - - return ERR_OK; -} - -/** - * Poll callback function for TCP netconns. - * Wakes up an application thread that waits for a connection to close - * or data to be sent. The application thread then takes the - * appropriate action to go on. - * - * Signals the conn->sem. - * netconn_close waits for conn->sem if closing failed. - * - * @see tcp.h (struct tcp_pcb.poll) for parameters and return value - */ -static err_t -poll_tcp(void *arg, struct tcp_pcb *pcb) -{ - struct netconn *conn = (struct netconn *)arg; - - LWIP_UNUSED_ARG(pcb); - LWIP_ASSERT("conn != NULL", (conn != NULL)); - - if (conn->state == NETCONN_WRITE) { - lwip_netconn_do_writemore(conn WRITE_DELAYED); - } else if (conn->state == NETCONN_CLOSE) { -#if !LWIP_SO_SNDTIMEO && !LWIP_SO_LINGER - if (conn->current_msg && conn->current_msg->msg.sd.polls_left) { - conn->current_msg->msg.sd.polls_left--; - } -#endif /* !LWIP_SO_SNDTIMEO && !LWIP_SO_LINGER */ - lwip_netconn_do_close_internal(conn WRITE_DELAYED); - } - /* @todo: implement connect timeout here? */ - - /* Did a nonblocking write fail before? Then check available write-space. */ - if (conn->flags & NETCONN_FLAG_CHECK_WRITESPACE) { - /* If the queued byte- or pbuf-count drops below the configured low-water limit, - let select mark this pcb as writable again. */ - if ((conn->pcb.tcp != NULL) && (tcp_sndbuf(conn->pcb.tcp) > TCP_SNDLOWAT) && - (tcp_sndqueuelen(conn->pcb.tcp) < TCP_SNDQUEUELOWAT)) { - conn->flags &= ~NETCONN_FLAG_CHECK_WRITESPACE; - API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0); - } - } - - return ERR_OK; -} - -/** - * Sent callback function for TCP netconns. - * Signals the conn->sem and calls API_EVENT. - * netconn_write waits for conn->sem if send buffer is low. - * - * @see tcp.h (struct tcp_pcb.sent) for parameters and return value - */ -static err_t -sent_tcp(void *arg, struct tcp_pcb *pcb, u16_t len) -{ - struct netconn *conn = (struct netconn *)arg; - - LWIP_UNUSED_ARG(pcb); - LWIP_ASSERT("conn != NULL", (conn != NULL)); - - if (conn) { - if (conn->state == NETCONN_WRITE) { - lwip_netconn_do_writemore(conn WRITE_DELAYED); - } else if (conn->state == NETCONN_CLOSE) { - lwip_netconn_do_close_internal(conn WRITE_DELAYED); - } - - /* If the queued byte- or pbuf-count drops below the configured low-water limit, - let select mark this pcb as writable again. */ - if ((conn->pcb.tcp != NULL) && (tcp_sndbuf(conn->pcb.tcp) > TCP_SNDLOWAT) && - (tcp_sndqueuelen(conn->pcb.tcp) < TCP_SNDQUEUELOWAT)) { - conn->flags &= ~NETCONN_FLAG_CHECK_WRITESPACE; - API_EVENT(conn, NETCONN_EVT_SENDPLUS, len); - } - } - - return ERR_OK; -} - -/** - * Error callback function for TCP netconns. - * Signals conn->sem, posts to all conn mboxes and calls API_EVENT. - * The application thread has then to decide what to do. - * - * @see tcp.h (struct tcp_pcb.err) for parameters - */ -static void -err_tcp(void *arg, err_t err) -{ - struct netconn *conn; - enum netconn_state old_state; - - conn = (struct netconn *)arg; - LWIP_ASSERT("conn != NULL", (conn != NULL)); - - conn->pcb.tcp = NULL; - - /* reset conn->state now before waking up other threads */ - old_state = conn->state; - conn->state = NETCONN_NONE; - - if (old_state == NETCONN_CLOSE) { - /* RST during close: let close return success & dealloc the netconn */ - err = ERR_OK; - NETCONN_SET_SAFE_ERR(conn, ERR_OK); - } else { - /* no check since this is always fatal! */ - SYS_ARCH_SET(conn->last_err, err); - } - - /* @todo: the type of NETCONN_EVT created should depend on 'old_state' */ - - /* Notify the user layer about a connection error. Used to signal select. */ - API_EVENT(conn, NETCONN_EVT_ERROR, 0); - /* Try to release selects pending on 'read' or 'write', too. - They will get an error if they actually try to read or write. */ - API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0); - API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0); - - /* pass NULL-message to recvmbox to wake up pending recv */ - if (sys_mbox_valid(&conn->recvmbox)) { - /* use trypost to prevent deadlock */ - sys_mbox_trypost(&conn->recvmbox, NULL); - } - /* pass NULL-message to acceptmbox to wake up pending accept */ - if (sys_mbox_valid(&conn->acceptmbox)) { - /* use trypost to preven deadlock */ - sys_mbox_trypost(&conn->acceptmbox, NULL); - } - - if ((old_state == NETCONN_WRITE) || (old_state == NETCONN_CLOSE) || - (old_state == NETCONN_CONNECT)) { - /* calling lwip_netconn_do_writemore/lwip_netconn_do_close_internal is not necessary - since the pcb has already been deleted! */ - int was_nonblocking_connect = IN_NONBLOCKING_CONNECT(conn); - SET_NONBLOCKING_CONNECT(conn, 0); - - if (!was_nonblocking_connect) { - sys_sem_t* op_completed_sem; - /* set error return code */ - LWIP_ASSERT("conn->current_msg != NULL", conn->current_msg != NULL); - conn->current_msg->err = err; - op_completed_sem = LWIP_API_MSG_SEM(conn->current_msg); - LWIP_ASSERT("inavlid op_completed_sem", sys_sem_valid(op_completed_sem)); - conn->current_msg = NULL; - /* wake up the waiting task */ - NETCONN_SET_SAFE_ERR(conn, err); - sys_sem_signal(op_completed_sem); - } - } else { - LWIP_ASSERT("conn->current_msg == NULL", conn->current_msg == NULL); - } -} - -/** - * Setup a tcp_pcb with the correct callback function pointers - * and their arguments. - * - * @param conn the TCP netconn to setup - */ -static void -setup_tcp(struct netconn *conn) -{ - struct tcp_pcb *pcb; - - pcb = conn->pcb.tcp; - tcp_arg(pcb, conn); - tcp_recv(pcb, recv_tcp); - tcp_sent(pcb, sent_tcp); - tcp_poll(pcb, poll_tcp, NETCONN_TCP_POLL_INTERVAL); - tcp_err(pcb, err_tcp); -} - -/** - * Accept callback function for TCP netconns. - * Allocates a new netconn and posts that to conn->acceptmbox. - * - * @see tcp.h (struct tcp_pcb_listen.accept) for parameters and return value - */ -static err_t -accept_function(void *arg, struct tcp_pcb *newpcb, err_t err) -{ - struct netconn *newconn; - struct netconn *conn = (struct netconn *)arg; - - if (conn == NULL) { - return ERR_VAL; - } - if (!sys_mbox_valid(&conn->acceptmbox)) { - LWIP_DEBUGF(API_MSG_DEBUG, ("accept_function: acceptmbox already deleted\n")); - return ERR_VAL; - } - - if (newpcb == NULL) { - /* out-of-pcbs during connect: pass on this error to the application */ - if (sys_mbox_trypost(&conn->acceptmbox, &netconn_aborted) == ERR_OK) { - /* Register event with callback */ - API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0); - } - return ERR_VAL; - } - - LWIP_DEBUGF(API_MSG_DEBUG, ("accept_function: newpcb->tate: %s\n", tcp_debug_state_str(newpcb->state))); - - /* We have to set the callback here even though - * the new socket is unknown. newconn->socket is marked as -1. */ - newconn = netconn_alloc(conn->type, conn->callback); - if (newconn == NULL) { - /* outof netconns: pass on this error to the application */ - if (sys_mbox_trypost(&conn->acceptmbox, &netconn_aborted) == ERR_OK) { - /* Register event with callback */ - API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0); - } - return ERR_MEM; - } - newconn->pcb.tcp = newpcb; - setup_tcp(newconn); - /* no protection: when creating the pcb, the netconn is not yet known - to the application thread */ - newconn->last_err = err; - - /* handle backlog counter */ - tcp_backlog_delayed(newpcb); - - if (sys_mbox_trypost(&conn->acceptmbox, newconn) != ERR_OK) { - /* When returning != ERR_OK, the pcb is aborted in tcp_process(), - so do nothing here! */ - /* remove all references to this netconn from the pcb */ - struct tcp_pcb* pcb = newconn->pcb.tcp; - tcp_arg(pcb, NULL); - tcp_recv(pcb, NULL); - tcp_sent(pcb, NULL); - tcp_poll(pcb, NULL, 0); - tcp_err(pcb, NULL); - /* remove reference from to the pcb from this netconn */ - newconn->pcb.tcp = NULL; - /* no need to drain since we know the recvmbox is empty. */ - sys_mbox_free(&newconn->recvmbox); - sys_mbox_set_invalid(&newconn->recvmbox); - netconn_free(newconn); - return ERR_MEM; - } else { - /* Register event with callback */ - API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0); - } - - return ERR_OK; -} -#endif /* LWIP_TCP */ - -/** - * Create a new pcb of a specific type. - * Called from lwip_netconn_do_newconn(). - * - * @param msg the api_msg_msg describing the connection type - */ -static void -pcb_new(struct api_msg *msg) -{ - enum lwip_ip_addr_type iptype = IPADDR_TYPE_V4; - - LWIP_ASSERT("pcb_new: pcb already allocated", msg->conn->pcb.tcp == NULL); - -#if LWIP_IPV6 && LWIP_IPV4 - /* IPv6: Dual-stack by default, unless netconn_set_ipv6only() is called */ - if(NETCONNTYPE_ISIPV6(netconn_type(msg->conn))) { - iptype = IPADDR_TYPE_ANY; - } -#endif - - /* Allocate a PCB for this connection */ - switch(NETCONNTYPE_GROUP(msg->conn->type)) { -#if LWIP_RAW - case NETCONN_RAW: - msg->conn->pcb.raw = raw_new_ip_type(iptype, msg->msg.n.proto); - if (msg->conn->pcb.raw != NULL) { -#if LWIP_IPV6 - /* ICMPv6 packets should always have checksum calculated by the stack as per RFC 3542 chapter 3.1 */ - if (NETCONNTYPE_ISIPV6(msg->conn->type) && msg->conn->pcb.raw->protocol == IP6_NEXTH_ICMP6) { - msg->conn->pcb.raw->chksum_reqd = 1; - msg->conn->pcb.raw->chksum_offset = 2; - } -#endif /* LWIP_IPV6 */ - raw_recv(msg->conn->pcb.raw, recv_raw, msg->conn); - } - break; -#endif /* LWIP_RAW */ -#if LWIP_UDP - case NETCONN_UDP: - msg->conn->pcb.udp = udp_new_ip_type(iptype); - if (msg->conn->pcb.udp != NULL) { -#if LWIP_UDPLITE - if (NETCONNTYPE_ISUDPLITE(msg->conn->type)) { - udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_UDPLITE); - } -#endif /* LWIP_UDPLITE */ - if (NETCONNTYPE_ISUDPNOCHKSUM(msg->conn->type)) { - udp_setflags(msg->conn->pcb.udp, UDP_FLAGS_NOCHKSUM); - } - udp_recv(msg->conn->pcb.udp, recv_udp, msg->conn); - } - break; -#endif /* LWIP_UDP */ -#if LWIP_TCP - case NETCONN_TCP: - msg->conn->pcb.tcp = tcp_new_ip_type(iptype); - if (msg->conn->pcb.tcp != NULL) { - setup_tcp(msg->conn); - } - break; -#endif /* LWIP_TCP */ - default: - /* Unsupported netconn type, e.g. protocol disabled */ - msg->err = ERR_VAL; - return; - } - if (msg->conn->pcb.ip == NULL) { - msg->err = ERR_MEM; - } -} - -/** - * Create a new pcb of a specific type inside a netconn. - * Called from netconn_new_with_proto_and_callback. - * - * @param m the api_msg_msg describing the connection type - */ -void -lwip_netconn_do_newconn(void *m) -{ - struct api_msg *msg = (struct api_msg*)m; - - msg->err = ERR_OK; - if (msg->conn->pcb.tcp == NULL) { - pcb_new(msg); - } - /* Else? This "new" connection already has a PCB allocated. */ - /* Is this an error condition? Should it be deleted? */ - /* We currently just are happy and return. */ - - TCPIP_APIMSG_ACK(msg); -} - -/** - * Create a new netconn (of a specific type) that has a callback function. - * The corresponding pcb is NOT created! - * - * @param t the type of 'connection' to create (@see enum netconn_type) - * @param callback a function to call on status changes (RX available, TX'ed) - * @return a newly allocated struct netconn or - * NULL on memory error - */ -struct netconn* -netconn_alloc(enum netconn_type t, netconn_callback callback) -{ - struct netconn *conn; - int size; - - conn = (struct netconn *)memp_malloc(MEMP_NETCONN); - if (conn == NULL) { - return NULL; - } - - conn->last_err = ERR_OK; - conn->type = t; - conn->pcb.tcp = NULL; - - /* If all sizes are the same, every compiler should optimize this switch to nothing */ - switch(NETCONNTYPE_GROUP(t)) { -#if LWIP_RAW - case NETCONN_RAW: - size = DEFAULT_RAW_RECVMBOX_SIZE; - break; -#endif /* LWIP_RAW */ -#if LWIP_UDP - case NETCONN_UDP: - size = DEFAULT_UDP_RECVMBOX_SIZE; - break; -#endif /* LWIP_UDP */ -#if LWIP_TCP - case NETCONN_TCP: - size = DEFAULT_TCP_RECVMBOX_SIZE; - break; -#endif /* LWIP_TCP */ - default: - LWIP_ASSERT("netconn_alloc: undefined netconn_type", 0); - goto free_and_return; - } - - if (sys_mbox_new(&conn->recvmbox, size) != ERR_OK) { - goto free_and_return; - } -#if !LWIP_NETCONN_SEM_PER_THREAD - if (sys_sem_new(&conn->op_completed, 0) != ERR_OK) { - sys_mbox_free(&conn->recvmbox); - goto free_and_return; - } -#endif - -#if LWIP_TCP - sys_mbox_set_invalid(&conn->acceptmbox); -#endif - conn->state = NETCONN_NONE; -#if LWIP_SOCKET - /* initialize socket to -1 since 0 is a valid socket */ - conn->socket = -1; -#endif /* LWIP_SOCKET */ - conn->callback = callback; -#if LWIP_TCP - conn->current_msg = NULL; - conn->write_offset = 0; -#endif /* LWIP_TCP */ -#if LWIP_SO_SNDTIMEO - conn->send_timeout = 0; -#endif /* LWIP_SO_SNDTIMEO */ -#if LWIP_SO_RCVTIMEO - conn->recv_timeout = 0; -#endif /* LWIP_SO_RCVTIMEO */ -#if LWIP_SO_RCVBUF - conn->recv_bufsize = RECV_BUFSIZE_DEFAULT; - conn->recv_avail = 0; -#endif /* LWIP_SO_RCVBUF */ -#if LWIP_SO_LINGER - conn->linger = -1; -#endif /* LWIP_SO_LINGER */ - conn->flags = 0; - return conn; -free_and_return: - memp_free(MEMP_NETCONN, conn); - return NULL; -} - -/** - * Delete a netconn and all its resources. - * The pcb is NOT freed (since we might not be in the right thread context do this). - * - * @param conn the netconn to free - */ -void -netconn_free(struct netconn *conn) -{ - LWIP_ASSERT("PCB must be deallocated outside this function", conn->pcb.tcp == NULL); - LWIP_ASSERT("recvmbox must be deallocated before calling this function", - !sys_mbox_valid(&conn->recvmbox)); -#if LWIP_TCP - LWIP_ASSERT("acceptmbox must be deallocated before calling this function", - !sys_mbox_valid(&conn->acceptmbox)); -#endif /* LWIP_TCP */ - -#if !LWIP_NETCONN_SEM_PER_THREAD - sys_sem_free(&conn->op_completed); - sys_sem_set_invalid(&conn->op_completed); -#endif - - memp_free(MEMP_NETCONN, conn); -} - -/** - * Delete rcvmbox and acceptmbox of a netconn and free the left-over data in - * these mboxes - * - * @param conn the netconn to free - * @bytes_drained bytes drained from recvmbox - * @accepts_drained pending connections drained from acceptmbox - */ -static void -netconn_drain(struct netconn *conn) -{ - void *mem; -#if LWIP_TCP - struct pbuf *p; -#endif /* LWIP_TCP */ - - /* This runs in tcpip_thread, so we don't need to lock against rx packets */ - - /* Delete and drain the recvmbox. */ - if (sys_mbox_valid(&conn->recvmbox)) { - while (sys_mbox_tryfetch(&conn->recvmbox, &mem) != SYS_MBOX_EMPTY) { -#if LWIP_TCP - if (NETCONNTYPE_GROUP(conn->type) == NETCONN_TCP) { - if (mem != NULL) { - p = (struct pbuf*)mem; - /* pcb might be set to NULL already by err_tcp() */ - if (conn->pcb.tcp != NULL) { - tcp_recved(conn->pcb.tcp, p->tot_len); - } - pbuf_free(p); - } - } else -#endif /* LWIP_TCP */ - { - netbuf_delete((struct netbuf *)mem); - } - } - sys_mbox_free(&conn->recvmbox); - sys_mbox_set_invalid(&conn->recvmbox); - } - - /* Delete and drain the acceptmbox. */ -#if LWIP_TCP - if (sys_mbox_valid(&conn->acceptmbox)) { - while (sys_mbox_tryfetch(&conn->acceptmbox, &mem) != SYS_MBOX_EMPTY) { - if (mem != &netconn_aborted) { - struct netconn *newconn = (struct netconn *)mem; - /* Only tcp pcbs have an acceptmbox, so no need to check conn->type */ - /* pcb might be set to NULL already by err_tcp() */ - /* drain recvmbox */ - netconn_drain(newconn); - if (newconn->pcb.tcp != NULL) { - tcp_abort(newconn->pcb.tcp); - newconn->pcb.tcp = NULL; - } - netconn_free(newconn); - } - } - sys_mbox_free(&conn->acceptmbox); - sys_mbox_set_invalid(&conn->acceptmbox); - } -#endif /* LWIP_TCP */ -} - -#if LWIP_TCP -/** - * Internal helper function to close a TCP netconn: since this sometimes - * doesn't work at the first attempt, this function is called from multiple - * places. - * - * @param conn the TCP netconn to close - */ -static err_t -lwip_netconn_do_close_internal(struct netconn *conn WRITE_DELAYED_PARAM) -{ - err_t err; - u8_t shut, shut_rx, shut_tx, close; - u8_t close_finished = 0; - struct tcp_pcb* tpcb; -#if LWIP_SO_LINGER - u8_t linger_wait_required = 0; -#endif /* LWIP_SO_LINGER */ - - LWIP_ASSERT("invalid conn", (conn != NULL)); - LWIP_ASSERT("this is for tcp netconns only", (NETCONNTYPE_GROUP(conn->type) == NETCONN_TCP)); - LWIP_ASSERT("conn must be in state NETCONN_CLOSE", (conn->state == NETCONN_CLOSE)); - LWIP_ASSERT("pcb already closed", (conn->pcb.tcp != NULL)); - LWIP_ASSERT("conn->current_msg != NULL", conn->current_msg != NULL); - - tpcb = conn->pcb.tcp; - shut = conn->current_msg->msg.sd.shut; - shut_rx = shut & NETCONN_SHUT_RD; - shut_tx = shut & NETCONN_SHUT_WR; - /* shutting down both ends is the same as closing - (also if RD or WR side was shut down before already) */ - if (shut == NETCONN_SHUT_RDWR) { - close = 1; - } else if (shut_rx && - ((tpcb->state == FIN_WAIT_1) || - (tpcb->state == FIN_WAIT_2) || - (tpcb->state == CLOSING))) { - close = 1; - } else if (shut_tx && ((tpcb->flags & TF_RXCLOSED) != 0)) { - close = 1; - } else { - close = 0; - } - - /* Set back some callback pointers */ - if (close) { - tcp_arg(tpcb, NULL); - } - if (tpcb->state == LISTEN) { - tcp_accept(tpcb, NULL); - } else { - /* some callbacks have to be reset if tcp_close is not successful */ - if (shut_rx) { - tcp_recv(tpcb, NULL); - tcp_accept(tpcb, NULL); - } - if (shut_tx) { - tcp_sent(tpcb, NULL); - } - if (close) { - tcp_poll(tpcb, NULL, 0); - tcp_err(tpcb, NULL); - } - } - /* Try to close the connection */ - if (close) { -#if LWIP_SO_LINGER - /* check linger possibilites before calling tcp_close */ - err = ERR_OK; - /* linger enabled/required at all? (i.e. is there untransmitted data left?) */ - if ((conn->linger >= 0) && (conn->pcb.tcp->unsent || conn->pcb.tcp->unacked)) { - if ((conn->linger == 0)) { - /* data left but linger prevents waiting */ - tcp_abort(tpcb); - tpcb = NULL; - } else if (conn->linger > 0) { - /* data left and linger says we should wait */ - if (netconn_is_nonblocking(conn)) { - /* data left on a nonblocking netconn -> cannot linger */ - err = ERR_WOULDBLOCK; - } else if ((s32_t)(sys_now() - conn->current_msg->msg.sd.time_started) >= - (conn->linger * 1000)) { - /* data left but linger timeout has expired (this happens on further - calls to this function through poll_tcp */ - tcp_abort(tpcb); - tpcb = NULL; - } else { - /* data left -> need to wait for ACK after successful close */ - linger_wait_required = 1; - } - } - } - if ((err == ERR_OK) && (tpcb != NULL)) -#endif /* LWIP_SO_LINGER */ - { - err = tcp_close(tpcb); - } - } else { - err = tcp_shutdown(tpcb, shut_rx, shut_tx); - } - if (err == ERR_OK) { - close_finished = 1; -#if LWIP_SO_LINGER - if (linger_wait_required) { - /* wait for ACK of all unsent/unacked data by just getting called again */ - close_finished = 0; - err = ERR_INPROGRESS; - } -#endif /* LWIP_SO_LINGER */ - } else { - if (err == ERR_MEM) { - /* Closing failed because of memory shortage, try again later. Even for - nonblocking netconns, we have to wait since no standard socket application - is prepared for close failing because of resource shortage. - Check the timeout: this is kind of an lwip addition to the standard sockets: - we wait for some time when failing to allocate a segment for the FIN */ -#if LWIP_SO_SNDTIMEO || LWIP_SO_LINGER - s32_t close_timeout = LWIP_TCP_CLOSE_TIMEOUT_MS_DEFAULT; -#if LWIP_SO_SNDTIMEO - if (conn->send_timeout > 0) { - close_timeout = conn->send_timeout; - } -#endif /* LWIP_SO_SNDTIMEO */ -#if LWIP_SO_LINGER - if (conn->linger >= 0) { - /* use linger timeout (seconds) */ - close_timeout = conn->linger * 1000U; - } -#endif - if ((s32_t)(sys_now() - conn->current_msg->msg.sd.time_started) >= close_timeout) { -#else /* LWIP_SO_SNDTIMEO || LWIP_SO_LINGER */ - if (conn->current_msg->msg.sd.polls_left == 0) { -#endif /* LWIP_SO_SNDTIMEO || LWIP_SO_LINGER */ - close_finished = 1; - if (close) { - /* in this case, we want to RST the connection */ - tcp_abort(tpcb); - err = ERR_OK; - } - } - } else { - /* Closing failed for a non-memory error: give up */ - close_finished = 1; - } - } - if (close_finished) { - /* Closing done (succeeded, non-memory error, nonblocking error or timeout) */ - sys_sem_t* op_completed_sem = LWIP_API_MSG_SEM(conn->current_msg); - conn->current_msg->err = err; - conn->current_msg = NULL; - conn->state = NETCONN_NONE; - if (err == ERR_OK) { - if (close) { - /* Set back some callback pointers as conn is going away */ - conn->pcb.tcp = NULL; - /* Trigger select() in socket layer. Make sure everybody notices activity - on the connection, error first! */ - API_EVENT(conn, NETCONN_EVT_ERROR, 0); - } - if (shut_rx) { - API_EVENT(conn, NETCONN_EVT_RCVPLUS, 0); - } - if (shut_tx) { - API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0); - } - } - NETCONN_SET_SAFE_ERR(conn, err); -#if LWIP_TCPIP_CORE_LOCKING - if (delayed) -#endif - { - /* wake up the application task */ - sys_sem_signal(op_completed_sem); - } - return ERR_OK; - } - if (!close_finished) { - /* Closing failed and we want to wait: restore some of the callbacks */ - /* Closing of listen pcb will never fail! */ - LWIP_ASSERT("Closing a listen pcb may not fail!", (tpcb->state != LISTEN)); - if (shut_tx) { - tcp_sent(tpcb, sent_tcp); - } - /* when waiting for close, set up poll interval to 500ms */ - tcp_poll(tpcb, poll_tcp, 1); - tcp_err(tpcb, err_tcp); - tcp_arg(tpcb, conn); - /* don't restore recv callback: we don't want to receive any more data */ - } - /* If closing didn't succeed, we get called again either - from poll_tcp or from sent_tcp */ - LWIP_ASSERT("err != ERR_OK", err != ERR_OK); - return err; -} -#endif /* LWIP_TCP */ - -/** - * Delete the pcb inside a netconn. - * Called from netconn_delete. - * - * @param m the api_msg_msg pointing to the connection - */ -void -lwip_netconn_do_delconn(void *m) -{ - struct api_msg *msg = (struct api_msg*)m; - - enum netconn_state state = msg->conn->state; - LWIP_ASSERT("netconn state error", /* this only happens for TCP netconns */ - (state == NETCONN_NONE) || (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP)); -#if LWIP_NETCONN_FULLDUPLEX - /* In full duplex mode, blocking write/connect is aborted with ERR_CLSD */ - if (state != NETCONN_NONE) { - if ((state == NETCONN_WRITE) || - ((state == NETCONN_CONNECT) && !IN_NONBLOCKING_CONNECT(msg->conn))) { - /* close requested, abort running write/connect */ - sys_sem_t* op_completed_sem; - LWIP_ASSERT("msg->conn->current_msg != NULL", msg->conn->current_msg != NULL); - op_completed_sem = LWIP_API_MSG_SEM(msg->conn->current_msg); - msg->conn->current_msg->err = ERR_CLSD; - msg->conn->current_msg = NULL; - msg->conn->write_offset = 0; - msg->conn->state = NETCONN_NONE; - NETCONN_SET_SAFE_ERR(msg->conn, ERR_CLSD); - sys_sem_signal(op_completed_sem); - } - } -#else /* LWIP_NETCONN_FULLDUPLEX */ - if (((state != NETCONN_NONE) && - (state != NETCONN_LISTEN) && - (state != NETCONN_CONNECT)) || - ((state == NETCONN_CONNECT) && !IN_NONBLOCKING_CONNECT(msg->conn))) { - /* This means either a blocking write or blocking connect is running - (nonblocking write returns and sets state to NONE) */ - msg->err = ERR_INPROGRESS; - } else -#endif /* LWIP_NETCONN_FULLDUPLEX */ - { - LWIP_ASSERT("blocking connect in progress", - (state != NETCONN_CONNECT) || IN_NONBLOCKING_CONNECT(msg->conn)); - msg->err = ERR_OK; - /* Drain and delete mboxes */ - netconn_drain(msg->conn); - - if (msg->conn->pcb.tcp != NULL) { - - switch (NETCONNTYPE_GROUP(msg->conn->type)) { -#if LWIP_RAW - case NETCONN_RAW: - raw_remove(msg->conn->pcb.raw); - break; -#endif /* LWIP_RAW */ -#if LWIP_UDP - case NETCONN_UDP: - msg->conn->pcb.udp->recv_arg = NULL; - udp_remove(msg->conn->pcb.udp); - break; -#endif /* LWIP_UDP */ -#if LWIP_TCP - case NETCONN_TCP: - LWIP_ASSERT("already writing or closing", msg->conn->current_msg == NULL && - msg->conn->write_offset == 0); - msg->conn->state = NETCONN_CLOSE; - msg->msg.sd.shut = NETCONN_SHUT_RDWR; - msg->conn->current_msg = msg; -#if LWIP_TCPIP_CORE_LOCKING - if (lwip_netconn_do_close_internal(msg->conn, 0) != ERR_OK) { - LWIP_ASSERT("state!", msg->conn->state == NETCONN_CLOSE); - UNLOCK_TCPIP_CORE(); - sys_arch_sem_wait(LWIP_API_MSG_SEM(msg), 0); - LOCK_TCPIP_CORE(); - LWIP_ASSERT("state!", msg->conn->state == NETCONN_NONE); - } -#else /* LWIP_TCPIP_CORE_LOCKING */ - lwip_netconn_do_close_internal(msg->conn); -#endif /* LWIP_TCPIP_CORE_LOCKING */ - /* API_EVENT is called inside lwip_netconn_do_close_internal, before releasing - the application thread, so we can return at this point! */ - return; -#endif /* LWIP_TCP */ - default: - break; - } - msg->conn->pcb.tcp = NULL; - } - /* tcp netconns don't come here! */ - - /* @todo: this lets select make the socket readable and writable, - which is wrong! errfd instead? */ - API_EVENT(msg->conn, NETCONN_EVT_RCVPLUS, 0); - API_EVENT(msg->conn, NETCONN_EVT_SENDPLUS, 0); - } - if (sys_sem_valid(LWIP_API_MSG_SEM(msg))) { - TCPIP_APIMSG_ACK(msg); - } -} - -/** - * Bind a pcb contained in a netconn - * Called from netconn_bind. - * - * @param m the api_msg_msg pointing to the connection and containing - * the IP address and port to bind to - */ -void -lwip_netconn_do_bind(void *m) -{ - struct api_msg *msg = (struct api_msg*)m; - - if (ERR_IS_FATAL(msg->conn->last_err)) { - msg->err = msg->conn->last_err; - } else { - msg->err = ERR_VAL; - if (msg->conn->pcb.tcp != NULL) { - switch (NETCONNTYPE_GROUP(msg->conn->type)) { -#if LWIP_RAW - case NETCONN_RAW: - msg->err = raw_bind(msg->conn->pcb.raw, API_EXPR_REF(msg->msg.bc.ipaddr)); - break; -#endif /* LWIP_RAW */ -#if LWIP_UDP - case NETCONN_UDP: - msg->err = udp_bind(msg->conn->pcb.udp, API_EXPR_REF(msg->msg.bc.ipaddr), msg->msg.bc.port); - break; -#endif /* LWIP_UDP */ -#if LWIP_TCP - case NETCONN_TCP: - msg->err = tcp_bind(msg->conn->pcb.tcp, API_EXPR_REF(msg->msg.bc.ipaddr), msg->msg.bc.port); - break; -#endif /* LWIP_TCP */ - default: - break; - } - } - } - TCPIP_APIMSG_ACK(msg); -} - -#if LWIP_TCP -/** - * TCP callback function if a connection (opened by tcp_connect/lwip_netconn_do_connect) has - * been established (or reset by the remote host). - * - * @see tcp.h (struct tcp_pcb.connected) for parameters and return values - */ -static err_t -lwip_netconn_do_connected(void *arg, struct tcp_pcb *pcb, err_t err) -{ - struct netconn *conn; - int was_blocking; - sys_sem_t* op_completed_sem = NULL; - - LWIP_UNUSED_ARG(pcb); - - conn = (struct netconn *)arg; - - if (conn == NULL) { - return ERR_VAL; - } - - LWIP_ASSERT("conn->state == NETCONN_CONNECT", conn->state == NETCONN_CONNECT); - LWIP_ASSERT("(conn->current_msg != NULL) || conn->in_non_blocking_connect", - (conn->current_msg != NULL) || IN_NONBLOCKING_CONNECT(conn)); - - if (conn->current_msg != NULL) { - conn->current_msg->err = err; - op_completed_sem = LWIP_API_MSG_SEM(conn->current_msg); - } - if ((NETCONNTYPE_GROUP(conn->type) == NETCONN_TCP) && (err == ERR_OK)) { - setup_tcp(conn); - } - was_blocking = !IN_NONBLOCKING_CONNECT(conn); - SET_NONBLOCKING_CONNECT(conn, 0); - LWIP_ASSERT("blocking connect state error", - (was_blocking && op_completed_sem != NULL) || - (!was_blocking && op_completed_sem == NULL)); - conn->current_msg = NULL; - conn->state = NETCONN_NONE; - NETCONN_SET_SAFE_ERR(conn, ERR_OK); - API_EVENT(conn, NETCONN_EVT_SENDPLUS, 0); - - if (was_blocking) { - sys_sem_signal(op_completed_sem); - } - return ERR_OK; -} -#endif /* LWIP_TCP */ - -/** - * Connect a pcb contained inside a netconn - * Called from netconn_connect. - * - * @param m the api_msg_msg pointing to the connection and containing - * the IP address and port to connect to - */ -void -lwip_netconn_do_connect(void *m) -{ - struct api_msg *msg = (struct api_msg*)m; - - if (msg->conn->pcb.tcp == NULL) { - /* This may happen when calling netconn_connect() a second time */ - msg->err = ERR_CLSD; - } else { - switch (NETCONNTYPE_GROUP(msg->conn->type)) { -#if LWIP_RAW - case NETCONN_RAW: - msg->err = raw_connect(msg->conn->pcb.raw, API_EXPR_REF(msg->msg.bc.ipaddr)); - break; -#endif /* LWIP_RAW */ -#if LWIP_UDP - case NETCONN_UDP: - msg->err = udp_connect(msg->conn->pcb.udp, API_EXPR_REF(msg->msg.bc.ipaddr), msg->msg.bc.port); - break; -#endif /* LWIP_UDP */ -#if LWIP_TCP - case NETCONN_TCP: - /* Prevent connect while doing any other action. */ - if (msg->conn->state == NETCONN_CONNECT) { - msg->err = ERR_ALREADY; - } else if (msg->conn->state != NETCONN_NONE) { - msg->err = ERR_ISCONN; - } else { - setup_tcp(msg->conn); - msg->err = tcp_connect(msg->conn->pcb.tcp, API_EXPR_REF(msg->msg.bc.ipaddr), - msg->msg.bc.port, lwip_netconn_do_connected); - if (msg->err == ERR_OK) { - u8_t non_blocking = netconn_is_nonblocking(msg->conn); - msg->conn->state = NETCONN_CONNECT; - SET_NONBLOCKING_CONNECT(msg->conn, non_blocking); - if (non_blocking) { - msg->err = ERR_INPROGRESS; - } else { - msg->conn->current_msg = msg; - /* sys_sem_signal() is called from lwip_netconn_do_connected (or err_tcp()), - when the connection is established! */ -#if LWIP_TCPIP_CORE_LOCKING - LWIP_ASSERT("state!", msg->conn->state == NETCONN_CONNECT); - UNLOCK_TCPIP_CORE(); - sys_arch_sem_wait(LWIP_API_MSG_SEM(msg), 0); - LOCK_TCPIP_CORE(); - LWIP_ASSERT("state!", msg->conn->state != NETCONN_CONNECT); -#endif /* LWIP_TCPIP_CORE_LOCKING */ - return; - } - } - } - break; -#endif /* LWIP_TCP */ - default: - LWIP_ERROR("Invalid netconn type", 0, do{ msg->err = ERR_VAL; }while(0)); - break; - } - } - /* For all other protocols, netconn_connect() calls TCPIP_APIMSG(), - so use TCPIP_APIMSG_ACK() here. */ - TCPIP_APIMSG_ACK(msg); -} - -/** - * Disconnect a pcb contained inside a netconn - * Only used for UDP netconns. - * Called from netconn_disconnect. - * - * @param m the api_msg_msg pointing to the connection to disconnect - */ -void -lwip_netconn_do_disconnect(void *m) -{ - struct api_msg *msg = (struct api_msg*)m; - -#if LWIP_UDP - if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_UDP) { - udp_disconnect(msg->conn->pcb.udp); - msg->err = ERR_OK; - } else -#endif /* LWIP_UDP */ - { - msg->err = ERR_VAL; - } - TCPIP_APIMSG_ACK(msg); -} - -#if LWIP_TCP -/** - * Set a TCP pcb contained in a netconn into listen mode - * Called from netconn_listen. - * - * @param m the api_msg_msg pointing to the connection - */ -void -lwip_netconn_do_listen(void *m) -{ - struct api_msg *msg = (struct api_msg*)m; - - if (ERR_IS_FATAL(msg->conn->last_err)) { - msg->err = msg->conn->last_err; - } else { - msg->err = ERR_CONN; - if (msg->conn->pcb.tcp != NULL) { - if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP) { - if (msg->conn->state == NETCONN_NONE) { - struct tcp_pcb* lpcb; - if (msg->conn->pcb.tcp->state != CLOSED) { - /* connection is not closed, cannot listen */ - msg->err = ERR_VAL; - } else { - err_t err; - u8_t backlog; -#if TCP_LISTEN_BACKLOG - backlog = msg->msg.lb.backlog; -#else /* TCP_LISTEN_BACKLOG */ - backlog = TCP_DEFAULT_LISTEN_BACKLOG; -#endif /* TCP_LISTEN_BACKLOG */ -#if LWIP_IPV4 && LWIP_IPV6 - /* "Socket API like" dual-stack support: If IP to listen to is IP6_ADDR_ANY, - * and NETCONN_FLAG_IPV6_V6ONLY is NOT set, use IP_ANY_TYPE to listen - */ - if (ip_addr_cmp(&msg->conn->pcb.ip->local_ip, IP6_ADDR_ANY) && - (netconn_get_ipv6only(msg->conn) == 0)) { - /* change PCB type to IPADDR_TYPE_ANY */ - IP_SET_TYPE_VAL(msg->conn->pcb.tcp->local_ip, IPADDR_TYPE_ANY); - IP_SET_TYPE_VAL(msg->conn->pcb.tcp->remote_ip, IPADDR_TYPE_ANY); - } -#endif /* LWIP_IPV4 && LWIP_IPV6 */ - - lpcb = tcp_listen_with_backlog_and_err(msg->conn->pcb.tcp, backlog, &err); - - if (lpcb == NULL) { - /* in this case, the old pcb is still allocated */ - msg->err = err; - } else { - /* delete the recvmbox and allocate the acceptmbox */ - if (sys_mbox_valid(&msg->conn->recvmbox)) { - /** @todo: should we drain the recvmbox here? */ - sys_mbox_free(&msg->conn->recvmbox); - sys_mbox_set_invalid(&msg->conn->recvmbox); - } - msg->err = ERR_OK; - if (!sys_mbox_valid(&msg->conn->acceptmbox)) { - msg->err = sys_mbox_new(&msg->conn->acceptmbox, DEFAULT_ACCEPTMBOX_SIZE); - } - if (msg->err == ERR_OK) { - msg->conn->state = NETCONN_LISTEN; - msg->conn->pcb.tcp = lpcb; - tcp_arg(msg->conn->pcb.tcp, msg->conn); - tcp_accept(msg->conn->pcb.tcp, accept_function); - } else { - /* since the old pcb is already deallocated, free lpcb now */ - tcp_close(lpcb); - msg->conn->pcb.tcp = NULL; - } - } - } - } else if (msg->conn->state == NETCONN_LISTEN) { - /* already listening, allow updating of the backlog */ - msg->err = ERR_OK; - tcp_backlog_set(msg->conn->pcb.tcp, msg->msg.lb.backlog); - } - } else { - msg->err = ERR_ARG; - } - } - } - TCPIP_APIMSG_ACK(msg); -} -#endif /* LWIP_TCP */ - -/** - * Send some data on a RAW or UDP pcb contained in a netconn - * Called from netconn_send - * - * @param m the api_msg_msg pointing to the connection - */ -void -lwip_netconn_do_send(void *m) -{ - struct api_msg *msg = (struct api_msg*)m; - - if (ERR_IS_FATAL(msg->conn->last_err)) { - msg->err = msg->conn->last_err; - } else { - msg->err = ERR_CONN; - if (msg->conn->pcb.tcp != NULL) { - switch (NETCONNTYPE_GROUP(msg->conn->type)) { -#if LWIP_RAW - case NETCONN_RAW: - if (ip_addr_isany(&msg->msg.b->addr) || IP_IS_ANY_TYPE_VAL(msg->msg.b->addr)) { - msg->err = raw_send(msg->conn->pcb.raw, msg->msg.b->p); - } else { - msg->err = raw_sendto(msg->conn->pcb.raw, msg->msg.b->p, &msg->msg.b->addr); - } - break; -#endif -#if LWIP_UDP - case NETCONN_UDP: -#if LWIP_CHECKSUM_ON_COPY - if (ip_addr_isany(&msg->msg.b->addr) || IP_IS_ANY_TYPE_VAL(msg->msg.b->addr)) { - msg->err = udp_send_chksum(msg->conn->pcb.udp, msg->msg.b->p, - msg->msg.b->flags & NETBUF_FLAG_CHKSUM, msg->msg.b->toport_chksum); - } else { - msg->err = udp_sendto_chksum(msg->conn->pcb.udp, msg->msg.b->p, - &msg->msg.b->addr, msg->msg.b->port, - msg->msg.b->flags & NETBUF_FLAG_CHKSUM, msg->msg.b->toport_chksum); - } -#else /* LWIP_CHECKSUM_ON_COPY */ - if (ip_addr_isany_val(msg->msg.b->addr) || IP_IS_ANY_TYPE_VAL(msg->msg.b->addr)) { - msg->err = udp_send(msg->conn->pcb.udp, msg->msg.b->p); - } else { - msg->err = udp_sendto(msg->conn->pcb.udp, msg->msg.b->p, &msg->msg.b->addr, msg->msg.b->port); - } -#endif /* LWIP_CHECKSUM_ON_COPY */ - break; -#endif /* LWIP_UDP */ - default: - break; - } - } - } - TCPIP_APIMSG_ACK(msg); -} - -#if LWIP_TCP -/** - * Indicate data has been received from a TCP pcb contained in a netconn - * Called from netconn_recv - * - * @param m the api_msg_msg pointing to the connection - */ -void -lwip_netconn_do_recv(void *m) -{ - struct api_msg *msg = (struct api_msg*)m; - - msg->err = ERR_OK; - if (msg->conn->pcb.tcp != NULL) { - if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP) { - u32_t remaining = msg->msg.r.len; - do { - u16_t recved = (remaining > 0xffff) ? 0xffff : (u16_t)remaining; - tcp_recved(msg->conn->pcb.tcp, recved); - remaining -= recved; - } while (remaining != 0); - } - } - TCPIP_APIMSG_ACK(msg); -} - -#if TCP_LISTEN_BACKLOG -/** Indicate that a TCP pcb has been accepted - * Called from netconn_accept - * - * @param m the api_msg_msg pointing to the connection - */ -void -lwip_netconn_do_accepted(void *m) -{ - struct api_msg *msg = (struct api_msg*)m; - - msg->err = ERR_OK; - if (msg->conn->pcb.tcp != NULL) { - if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP) { - tcp_backlog_accepted(msg->conn->pcb.tcp); - } - } - TCPIP_APIMSG_ACK(msg); -} -#endif /* TCP_LISTEN_BACKLOG */ - -/** - * See if more data needs to be written from a previous call to netconn_write. - * Called initially from lwip_netconn_do_write. If the first call can't send all data - * (because of low memory or empty send-buffer), this function is called again - * from sent_tcp() or poll_tcp() to send more data. If all data is sent, the - * blocking application thread (waiting in netconn_write) is released. - * - * @param conn netconn (that is currently in state NETCONN_WRITE) to process - * @return ERR_OK - * ERR_MEM if LWIP_TCPIP_CORE_LOCKING=1 and sending hasn't yet finished - */ -static err_t -lwip_netconn_do_writemore(struct netconn *conn WRITE_DELAYED_PARAM) -{ - err_t err; - const void *dataptr; - u16_t len, available; - u8_t write_finished = 0; - size_t diff; - u8_t dontblock; - u8_t apiflags; - - LWIP_ASSERT("conn != NULL", conn != NULL); - LWIP_ASSERT("conn->state == NETCONN_WRITE", (conn->state == NETCONN_WRITE)); - LWIP_ASSERT("conn->current_msg != NULL", conn->current_msg != NULL); - LWIP_ASSERT("conn->pcb.tcp != NULL", conn->pcb.tcp != NULL); - LWIP_ASSERT("conn->write_offset < conn->current_msg->msg.w.len", - conn->write_offset < conn->current_msg->msg.w.len); - - apiflags = conn->current_msg->msg.w.apiflags; - dontblock = netconn_is_nonblocking(conn) || (apiflags & NETCONN_DONTBLOCK); - -#if LWIP_SO_SNDTIMEO - if ((conn->send_timeout != 0) && - ((s32_t)(sys_now() - conn->current_msg->msg.w.time_started) >= conn->send_timeout)) { - write_finished = 1; - if (conn->write_offset == 0) { - /* nothing has been written */ - err = ERR_WOULDBLOCK; - conn->current_msg->msg.w.len = 0; - } else { - /* partial write */ - err = ERR_OK; - conn->current_msg->msg.w.len = conn->write_offset; - conn->write_offset = 0; - } - } else -#endif /* LWIP_SO_SNDTIMEO */ - { - dataptr = (const u8_t*)conn->current_msg->msg.w.dataptr + conn->write_offset; - diff = conn->current_msg->msg.w.len - conn->write_offset; - if (diff > 0xffffUL) { /* max_u16_t */ - len = 0xffff; - apiflags |= TCP_WRITE_FLAG_MORE; - } else { - len = (u16_t)diff; - } - available = tcp_sndbuf(conn->pcb.tcp); - if (available < len) { - /* don't try to write more than sendbuf */ - len = available; - if (dontblock) { - if (!len) { - err = ERR_WOULDBLOCK; - goto err_mem; - } - } else { - apiflags |= TCP_WRITE_FLAG_MORE; - } - } - LWIP_ASSERT("lwip_netconn_do_writemore: invalid length!", ((conn->write_offset + len) <= conn->current_msg->msg.w.len)); - err = tcp_write(conn->pcb.tcp, dataptr, len, apiflags); - /* if OK or memory error, check available space */ - if ((err == ERR_OK) || (err == ERR_MEM)) { -err_mem: - if (dontblock && (len < conn->current_msg->msg.w.len)) { - /* non-blocking write did not write everything: mark the pcb non-writable - and let poll_tcp check writable space to mark the pcb writable again */ - API_EVENT(conn, NETCONN_EVT_SENDMINUS, len); - conn->flags |= NETCONN_FLAG_CHECK_WRITESPACE; - } else if ((tcp_sndbuf(conn->pcb.tcp) <= TCP_SNDLOWAT) || - (tcp_sndqueuelen(conn->pcb.tcp) >= TCP_SNDQUEUELOWAT)) { - /* The queued byte- or pbuf-count exceeds the configured low-water limit, - let select mark this pcb as non-writable. */ - API_EVENT(conn, NETCONN_EVT_SENDMINUS, len); - } - } - - if (err == ERR_OK) { - err_t out_err; - conn->write_offset += len; - if ((conn->write_offset == conn->current_msg->msg.w.len) || dontblock) { - /* return sent length */ - conn->current_msg->msg.w.len = conn->write_offset; - /* everything was written */ - write_finished = 1; - } - out_err = tcp_output(conn->pcb.tcp); - if (ERR_IS_FATAL(out_err) || (out_err == ERR_RTE)) { - /* If tcp_output fails with fatal error or no route is found, - don't try writing any more but return the error - to the application thread. */ - err = out_err; - write_finished = 1; - conn->current_msg->msg.w.len = 0; - } - } else if (err == ERR_MEM) { - /* If ERR_MEM, we wait for sent_tcp or poll_tcp to be called. - For blocking sockets, we do NOT return to the application - thread, since ERR_MEM is only a temporary error! Non-blocking - will remain non-writable until sent_tcp/poll_tcp is called */ - - /* tcp_write returned ERR_MEM, try tcp_output anyway */ - err_t out_err = tcp_output(conn->pcb.tcp); - if (ERR_IS_FATAL(out_err) || (out_err == ERR_RTE)) { - /* If tcp_output fails with fatal error or no route is found, - don't try writing any more but return the error - to the application thread. */ - err = out_err; - write_finished = 1; - conn->current_msg->msg.w.len = 0; - } else if (dontblock) { - /* non-blocking write is done on ERR_MEM */ - err = ERR_WOULDBLOCK; - write_finished = 1; - conn->current_msg->msg.w.len = 0; - } - } else { - /* On errors != ERR_MEM, we don't try writing any more but return - the error to the application thread. */ - write_finished = 1; - conn->current_msg->msg.w.len = 0; - } - } - if (write_finished) { - /* everything was written: set back connection state - and back to application task */ - sys_sem_t* op_completed_sem = LWIP_API_MSG_SEM(conn->current_msg); - conn->current_msg->err = err; - conn->current_msg = NULL; - conn->write_offset = 0; - conn->state = NETCONN_NONE; - NETCONN_SET_SAFE_ERR(conn, err); -#if LWIP_TCPIP_CORE_LOCKING - if (delayed) -#endif - { - sys_sem_signal(op_completed_sem); - } - } -#if LWIP_TCPIP_CORE_LOCKING - else { - return ERR_MEM; - } -#endif - return ERR_OK; -} -#endif /* LWIP_TCP */ - -/** - * Send some data on a TCP pcb contained in a netconn - * Called from netconn_write - * - * @param m the api_msg_msg pointing to the connection - */ -void -lwip_netconn_do_write(void *m) -{ - struct api_msg *msg = (struct api_msg*)m; - - if (ERR_IS_FATAL(msg->conn->last_err)) { - msg->err = msg->conn->last_err; - } else { - if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP) { -#if LWIP_TCP - if (msg->conn->state != NETCONN_NONE) { - /* netconn is connecting, closing or in blocking write */ - msg->err = ERR_INPROGRESS; - } else if (msg->conn->pcb.tcp != NULL) { - msg->conn->state = NETCONN_WRITE; - /* set all the variables used by lwip_netconn_do_writemore */ - LWIP_ASSERT("already writing or closing", msg->conn->current_msg == NULL && - msg->conn->write_offset == 0); - LWIP_ASSERT("msg->msg.w.len != 0", msg->msg.w.len != 0); - msg->conn->current_msg = msg; - msg->conn->write_offset = 0; -#if LWIP_TCPIP_CORE_LOCKING - if (lwip_netconn_do_writemore(msg->conn, 0) != ERR_OK) { - LWIP_ASSERT("state!", msg->conn->state == NETCONN_WRITE); - UNLOCK_TCPIP_CORE(); - sys_arch_sem_wait(LWIP_API_MSG_SEM(msg), 0); - LOCK_TCPIP_CORE(); - LWIP_ASSERT("state!", msg->conn->state != NETCONN_WRITE); - } -#else /* LWIP_TCPIP_CORE_LOCKING */ - lwip_netconn_do_writemore(msg->conn); -#endif /* LWIP_TCPIP_CORE_LOCKING */ - /* for both cases: if lwip_netconn_do_writemore was called, don't ACK the APIMSG - since lwip_netconn_do_writemore ACKs it! */ - return; - } else { - msg->err = ERR_CONN; - } -#else /* LWIP_TCP */ - msg->err = ERR_VAL; -#endif /* LWIP_TCP */ -#if (LWIP_UDP || LWIP_RAW) - } else { - msg->err = ERR_VAL; -#endif /* (LWIP_UDP || LWIP_RAW) */ - } - } - TCPIP_APIMSG_ACK(msg); -} - -/** - * Return a connection's local or remote address - * Called from netconn_getaddr - * - * @param m the api_msg_msg pointing to the connection - */ -void -lwip_netconn_do_getaddr(void *m) -{ - struct api_msg *msg = (struct api_msg*)m; - - if (msg->conn->pcb.ip != NULL) { - if (msg->msg.ad.local) { - ip_addr_copy(API_EXPR_DEREF(msg->msg.ad.ipaddr), - msg->conn->pcb.ip->local_ip); - } else { - ip_addr_copy(API_EXPR_DEREF(msg->msg.ad.ipaddr), - msg->conn->pcb.ip->remote_ip); - } - - msg->err = ERR_OK; - switch (NETCONNTYPE_GROUP(msg->conn->type)) { -#if LWIP_RAW - case NETCONN_RAW: - if (msg->msg.ad.local) { - API_EXPR_DEREF(msg->msg.ad.port) = msg->conn->pcb.raw->protocol; - } else { - /* return an error as connecting is only a helper for upper layers */ - msg->err = ERR_CONN; - } - break; -#endif /* LWIP_RAW */ -#if LWIP_UDP - case NETCONN_UDP: - if (msg->msg.ad.local) { - API_EXPR_DEREF(msg->msg.ad.port) = msg->conn->pcb.udp->local_port; - } else { - if ((msg->conn->pcb.udp->flags & UDP_FLAGS_CONNECTED) == 0) { - msg->err = ERR_CONN; - } else { - API_EXPR_DEREF(msg->msg.ad.port) = msg->conn->pcb.udp->remote_port; - } - } - break; -#endif /* LWIP_UDP */ -#if LWIP_TCP - case NETCONN_TCP: - if ((msg->msg.ad.local == 0) && - ((msg->conn->pcb.tcp->state == CLOSED) || (msg->conn->pcb.tcp->state == LISTEN))) { - /* pcb is not connected and remote name is requested */ - msg->err = ERR_CONN; - } else { - API_EXPR_DEREF(msg->msg.ad.port) = (msg->msg.ad.local ? msg->conn->pcb.tcp->local_port : msg->conn->pcb.tcp->remote_port); - } - break; -#endif /* LWIP_TCP */ - default: - LWIP_ASSERT("invalid netconn_type", 0); - break; - } - } else { - msg->err = ERR_CONN; - } - TCPIP_APIMSG_ACK(msg); -} - -/** - * Close or half-shutdown a TCP pcb contained in a netconn - * Called from netconn_close - * In contrast to closing sockets, the netconn is not deallocated. - * - * @param m the api_msg_msg pointing to the connection - */ -void -lwip_netconn_do_close(void *m) -{ - struct api_msg *msg = (struct api_msg*)m; - -#if LWIP_TCP - enum netconn_state state = msg->conn->state; - /* First check if this is a TCP netconn and if it is in a correct state - (LISTEN doesn't support half shutdown) */ - if ((msg->conn->pcb.tcp != NULL) && - (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_TCP) && - ((msg->msg.sd.shut == NETCONN_SHUT_RDWR) || (state != NETCONN_LISTEN))) { - /* Check if we are in a connected state */ - if (state == NETCONN_CONNECT) { - /* TCP connect in progress: cannot shutdown */ - msg->err = ERR_CONN; - } else if (state == NETCONN_WRITE) { -#if LWIP_NETCONN_FULLDUPLEX - if (msg->msg.sd.shut & NETCONN_SHUT_WR) { - /* close requested, abort running write */ - sys_sem_t* write_completed_sem; - LWIP_ASSERT("msg->conn->current_msg != NULL", msg->conn->current_msg != NULL); - write_completed_sem = LWIP_API_MSG_SEM(msg->conn->current_msg); - msg->conn->current_msg->err = ERR_CLSD; - msg->conn->current_msg = NULL; - msg->conn->write_offset = 0; - msg->conn->state = NETCONN_NONE; - state = NETCONN_NONE; - NETCONN_SET_SAFE_ERR(msg->conn, ERR_CLSD); - sys_sem_signal(write_completed_sem); - } else { - LWIP_ASSERT("msg->msg.sd.shut == NETCONN_SHUT_RD", msg->msg.sd.shut == NETCONN_SHUT_RD); - /* In this case, let the write continue and do not interfere with - conn->current_msg or conn->state! */ - msg->err = tcp_shutdown(msg->conn->pcb.tcp, 1, 0); - } - } - if (state == NETCONN_NONE) { -#else /* LWIP_NETCONN_FULLDUPLEX */ - msg->err = ERR_INPROGRESS; - } else { -#endif /* LWIP_NETCONN_FULLDUPLEX */ - if (msg->msg.sd.shut & NETCONN_SHUT_RD) { - /* Drain and delete mboxes */ - netconn_drain(msg->conn); - } - LWIP_ASSERT("already writing or closing", msg->conn->current_msg == NULL && - msg->conn->write_offset == 0); - msg->conn->state = NETCONN_CLOSE; - msg->conn->current_msg = msg; -#if LWIP_TCPIP_CORE_LOCKING - if (lwip_netconn_do_close_internal(msg->conn, 0) != ERR_OK) { - LWIP_ASSERT("state!", msg->conn->state == NETCONN_CLOSE); - UNLOCK_TCPIP_CORE(); - sys_arch_sem_wait(LWIP_API_MSG_SEM(msg), 0); - LOCK_TCPIP_CORE(); - LWIP_ASSERT("state!", msg->conn->state == NETCONN_NONE); - } -#else /* LWIP_TCPIP_CORE_LOCKING */ - lwip_netconn_do_close_internal(msg->conn); -#endif /* LWIP_TCPIP_CORE_LOCKING */ - /* for tcp netconns, lwip_netconn_do_close_internal ACKs the message */ - return; - } - } else -#endif /* LWIP_TCP */ - { - msg->err = ERR_CONN; - } - TCPIP_APIMSG_ACK(msg); -} - -#if LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) -/** - * Join multicast groups for UDP netconns. - * Called from netconn_join_leave_group - * - * @param m the api_msg_msg pointing to the connection - */ -void -lwip_netconn_do_join_leave_group(void *m) -{ - struct api_msg *msg = (struct api_msg*)m; - - if (ERR_IS_FATAL(msg->conn->last_err)) { - msg->err = msg->conn->last_err; - } else { - if (msg->conn->pcb.tcp != NULL) { - if (NETCONNTYPE_GROUP(msg->conn->type) == NETCONN_UDP) { -#if LWIP_UDP -#if LWIP_IPV6 && LWIP_IPV6_MLD - if (NETCONNTYPE_ISIPV6(msg->conn->type)) { - if (msg->msg.jl.join_or_leave == NETCONN_JOIN) { - msg->err = mld6_joingroup(ip_2_ip6(API_EXPR_REF(msg->msg.jl.netif_addr)), - ip_2_ip6(API_EXPR_REF(msg->msg.jl.multiaddr))); - } else { - msg->err = mld6_leavegroup(ip_2_ip6(API_EXPR_REF(msg->msg.jl.netif_addr)), - ip_2_ip6(API_EXPR_REF(msg->msg.jl.multiaddr))); - } - } - else -#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */ - { -#if LWIP_IGMP - if (msg->msg.jl.join_or_leave == NETCONN_JOIN) { - msg->err = igmp_joingroup(ip_2_ip4(API_EXPR_REF(msg->msg.jl.netif_addr)), - ip_2_ip4(API_EXPR_REF(msg->msg.jl.multiaddr))); - } else { - msg->err = igmp_leavegroup(ip_2_ip4(API_EXPR_REF(msg->msg.jl.netif_addr)), - ip_2_ip4(API_EXPR_REF(msg->msg.jl.multiaddr))); - } -#endif /* LWIP_IGMP */ - } -#endif /* LWIP_UDP */ -#if (LWIP_TCP || LWIP_RAW) - } else { - msg->err = ERR_VAL; -#endif /* (LWIP_TCP || LWIP_RAW) */ - } - } else { - msg->err = ERR_CONN; - } - } - TCPIP_APIMSG_ACK(msg); -} -#endif /* LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) */ - -#if LWIP_DNS -/** - * Callback function that is called when DNS name is resolved - * (or on timeout). A waiting application thread is waked up by - * signaling the semaphore. - */ -static void -lwip_netconn_do_dns_found(const char *name, const ip_addr_t *ipaddr, void *arg) -{ - struct dns_api_msg *msg = (struct dns_api_msg*)arg; - - /* we trust the internal implementation to be correct :-) */ - LWIP_UNUSED_ARG(name); - - if (ipaddr == NULL) { - /* timeout or memory error */ - API_EXPR_DEREF(msg->err) = ERR_VAL; - } else { - /* address was resolved */ - API_EXPR_DEREF(msg->err) = ERR_OK; - API_EXPR_DEREF(msg->addr) = *ipaddr; - } - /* wake up the application task waiting in netconn_gethostbyname */ - sys_sem_signal(API_EXPR_REF_SEM(msg->sem)); -} - -/** - * Execute a DNS query - * Called from netconn_gethostbyname - * - * @param arg the dns_api_msg pointing to the query - */ -void -lwip_netconn_do_gethostbyname(void *arg) -{ - struct dns_api_msg *msg = (struct dns_api_msg*)arg; - u8_t addrtype = -#if LWIP_IPV4 && LWIP_IPV6 - msg->dns_addrtype; -#else - LWIP_DNS_ADDRTYPE_DEFAULT; -#endif - - API_EXPR_DEREF(msg->err) = dns_gethostbyname_addrtype(msg->name, - API_EXPR_REF(msg->addr), lwip_netconn_do_dns_found, msg, addrtype); - if (API_EXPR_DEREF(msg->err) != ERR_INPROGRESS) { - /* on error or immediate success, wake up the application - * task waiting in netconn_gethostbyname */ - sys_sem_signal(API_EXPR_REF_SEM(msg->sem)); - } -} -#endif /* LWIP_DNS */ - -#endif /* LWIP_NETCONN */ diff --git a/third_party/lwip/repo/lwip/src/api/err.c b/third_party/lwip/repo/lwip/src/api/err.c deleted file mode 100644 index 35e9c025eaafed..00000000000000 --- a/third_party/lwip/repo/lwip/src/api/err.c +++ /dev/null @@ -1,115 +0,0 @@ -/** - * @file - * Error Management module - * - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ - -#include "lwip/err.h" -#include "lwip/def.h" -#include "lwip/sys.h" - -#include "lwip/errno.h" - -#if !NO_SYS -/** Table to quickly map an lwIP error (err_t) to a socket error - * by using -err as an index */ -static const int err_to_errno_table[] = { - 0, /* ERR_OK 0 No error, everything OK. */ - ENOMEM, /* ERR_MEM -1 Out of memory error. */ - ENOBUFS, /* ERR_BUF -2 Buffer error. */ - EWOULDBLOCK, /* ERR_TIMEOUT -3 Timeout */ - EHOSTUNREACH, /* ERR_RTE -4 Routing problem. */ - EINPROGRESS, /* ERR_INPROGRESS -5 Operation in progress */ - EINVAL, /* ERR_VAL -6 Illegal value. */ - EWOULDBLOCK, /* ERR_WOULDBLOCK -7 Operation would block. */ - EADDRINUSE, /* ERR_USE -8 Address in use. */ - EALREADY, /* ERR_ALREADY -9 Already connecting. */ - EISCONN, /* ERR_ISCONN -10 Conn already established.*/ - ENOTCONN, /* ERR_CONN -11 Not connected. */ - -1, /* ERR_IF -12 Low-level netif error */ - ECONNABORTED, /* ERR_ABRT -13 Connection aborted. */ - ECONNRESET, /* ERR_RST -14 Connection reset. */ - ENOTCONN, /* ERR_CLSD -15 Connection closed. */ - EIO /* ERR_ARG -16 Illegal argument. */ -}; - -int -err_to_errno(err_t err) -{ - if ((err > 0) || (-err >= (err_t)LWIP_ARRAYSIZE(err_to_errno_table))) { - return EIO; - } - return err_to_errno_table[-err]; -} -#endif /* !NO_SYS */ - -#ifdef LWIP_DEBUG - -static const char *err_strerr[] = { - "Ok.", /* ERR_OK 0 */ - "Out of memory error.", /* ERR_MEM -1 */ - "Buffer error.", /* ERR_BUF -2 */ - "Timeout.", /* ERR_TIMEOUT -3 */ - "Routing problem.", /* ERR_RTE -4 */ - "Operation in progress.", /* ERR_INPROGRESS -5 */ - "Illegal value.", /* ERR_VAL -6 */ - "Operation would block.", /* ERR_WOULDBLOCK -7 */ - "Address in use.", /* ERR_USE -8 */ - "Already connecting.", /* ERR_ALREADY -9 */ - "Already connected.", /* ERR_ISCONN -10 */ - "Not connected.", /* ERR_CONN -11 */ - "Low-level netif error.", /* ERR_IF -12 */ - "Connection aborted.", /* ERR_ABRT -13 */ - "Connection reset.", /* ERR_RST -14 */ - "Connection closed.", /* ERR_CLSD -15 */ - "Illegal argument." /* ERR_ARG -16 */ -}; - -/** - * Convert an lwip internal error to a string representation. - * - * @param err an lwip internal err_t - * @return a string representation for err - */ -const char * -lwip_strerr(err_t err) -{ - if ((err > 0) || (-err >= (err_t)LWIP_ARRAYSIZE(err_strerr))) { - return "Unknown error."; - } - return err_strerr[-err]; -} - -#endif /* LWIP_DEBUG */ diff --git a/third_party/lwip/repo/lwip/src/api/if.c b/third_party/lwip/repo/lwip/src/api/if.c deleted file mode 100644 index 4edf7b96d0e30b..00000000000000 --- a/third_party/lwip/repo/lwip/src/api/if.c +++ /dev/null @@ -1,77 +0,0 @@ -/** - * @file - * Interface Identification APIs from: - * RFC 3493: Basic Socket Interface Extensions for IPv6 - * Section 4: Interface Identification - */ - -/* - * Copyright (c) 2017 Joel Cunningham - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modificat -ion, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO E -VENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREM -ENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARIS -ING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Joel Cunningham - * - */ -#include "lwip/opt.h" - -#if LWIP_SOCKET - -#include "lwip/netifapi.h" - -char * -lwip_if_indextoname(unsigned ifindex, char *ifname) -{ - err_t err; - if (ifindex > 0xff) { - return NULL; - } - - err = netifapi_netif_index_to_name((u8_t)ifindex, ifname); - if (!err && ifname[0] != '\0') { - return ifname; - } - return NULL; -} - -unsigned int -lwip_if_nametoindex(const char *ifname) -{ - err_t err; - u8_t index; - - err = netifapi_netif_name_to_index(ifname, &index); - if (!err) { - return index; - } - return 0; /* invalid index */ -} - -#endif /* LWIP_SOCKET */ diff --git a/third_party/lwip/repo/lwip/src/api/netbuf.c b/third_party/lwip/repo/lwip/src/api/netbuf.c deleted file mode 100644 index eb250115ff65ac..00000000000000 --- a/third_party/lwip/repo/lwip/src/api/netbuf.c +++ /dev/null @@ -1,246 +0,0 @@ -/** - * @file - * Network buffer management - * - * @defgroup netbuf Network buffers - * @ingroup netconn - * Network buffer descriptor for @ref netconn. Based on @ref pbuf internally - * to avoid copying data around.\n - * Buffers must not be shared accross multiple threads, all functions except - * netbuf_new() and netbuf_delete() are not thread-safe. - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ - -#include "lwip/opt.h" - -#if LWIP_NETCONN /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/netbuf.h" -#include "lwip/memp.h" - -#include - -/** - * @ingroup netbuf - * Create (allocate) and initialize a new netbuf. - * The netbuf doesn't yet contain a packet buffer! - * - * @return a pointer to a new netbuf - * NULL on lack of memory - */ -struct -netbuf *netbuf_new(void) -{ - struct netbuf *buf; - - buf = (struct netbuf *)memp_malloc(MEMP_NETBUF); - if (buf != NULL) { - memset(buf, 0, sizeof(struct netbuf)); - } - return buf; -} - -/** - * @ingroup netbuf - * Deallocate a netbuf allocated by netbuf_new(). - * - * @param buf pointer to a netbuf allocated by netbuf_new() - */ -void -netbuf_delete(struct netbuf *buf) -{ - if (buf != NULL) { - if (buf->p != NULL) { - pbuf_free(buf->p); - buf->p = buf->ptr = NULL; - } - memp_free(MEMP_NETBUF, buf); - } -} - -/** - * @ingroup netbuf - * Allocate memory for a packet buffer for a given netbuf. - * - * @param buf the netbuf for which to allocate a packet buffer - * @param size the size of the packet buffer to allocate - * @return pointer to the allocated memory - * NULL if no memory could be allocated - */ -void * -netbuf_alloc(struct netbuf *buf, u16_t size) -{ - LWIP_ERROR("netbuf_alloc: invalid buf", (buf != NULL), return NULL;); - - /* Deallocate any previously allocated memory. */ - if (buf->p != NULL) { - pbuf_free(buf->p); - } - buf->p = pbuf_alloc(PBUF_TRANSPORT, size, PBUF_RAM); - if (buf->p == NULL) { - return NULL; - } - LWIP_ASSERT("check that first pbuf can hold size", - (buf->p->len >= size)); - buf->ptr = buf->p; - return buf->p->payload; -} - -/** - * @ingroup netbuf - * Free the packet buffer included in a netbuf - * - * @param buf pointer to the netbuf which contains the packet buffer to free - */ -void -netbuf_free(struct netbuf *buf) -{ - LWIP_ERROR("netbuf_free: invalid buf", (buf != NULL), return;); - if (buf->p != NULL) { - pbuf_free(buf->p); - } - buf->p = buf->ptr = NULL; -} - -/** - * @ingroup netbuf - * Let a netbuf reference existing (non-volatile) data. - * - * @param buf netbuf which should reference the data - * @param dataptr pointer to the data to reference - * @param size size of the data - * @return ERR_OK if data is referenced - * ERR_MEM if data couldn't be referenced due to lack of memory - */ -err_t -netbuf_ref(struct netbuf *buf, const void *dataptr, u16_t size) -{ - LWIP_ERROR("netbuf_ref: invalid buf", (buf != NULL), return ERR_ARG;); - if (buf->p != NULL) { - pbuf_free(buf->p); - } - buf->p = pbuf_alloc(PBUF_TRANSPORT, 0, PBUF_REF); - if (buf->p == NULL) { - buf->ptr = NULL; - return ERR_MEM; - } - ((struct pbuf_rom*)buf->p)->payload = dataptr; - buf->p->len = buf->p->tot_len = size; - buf->ptr = buf->p; - return ERR_OK; -} - -/** - * @ingroup netbuf - * Chain one netbuf to another (@see pbuf_chain) - * - * @param head the first netbuf - * @param tail netbuf to chain after head, freed by this function, may not be reference after returning - */ -void -netbuf_chain(struct netbuf *head, struct netbuf *tail) -{ - LWIP_ERROR("netbuf_chain: invalid head", (head != NULL), return;); - LWIP_ERROR("netbuf_chain: invalid tail", (tail != NULL), return;); - pbuf_cat(head->p, tail->p); - head->ptr = head->p; - memp_free(MEMP_NETBUF, tail); -} - -/** - * @ingroup netbuf - * Get the data pointer and length of the data inside a netbuf. - * - * @param buf netbuf to get the data from - * @param dataptr pointer to a void pointer where to store the data pointer - * @param len pointer to an u16_t where the length of the data is stored - * @return ERR_OK if the information was retrieved, - * ERR_BUF on error. - */ -err_t -netbuf_data(struct netbuf *buf, void **dataptr, u16_t *len) -{ - LWIP_ERROR("netbuf_data: invalid buf", (buf != NULL), return ERR_ARG;); - LWIP_ERROR("netbuf_data: invalid dataptr", (dataptr != NULL), return ERR_ARG;); - LWIP_ERROR("netbuf_data: invalid len", (len != NULL), return ERR_ARG;); - - if (buf->ptr == NULL) { - return ERR_BUF; - } - *dataptr = buf->ptr->payload; - *len = buf->ptr->len; - return ERR_OK; -} - -/** - * @ingroup netbuf - * Move the current data pointer of a packet buffer contained in a netbuf - * to the next part. - * The packet buffer itself is not modified. - * - * @param buf the netbuf to modify - * @return -1 if there is no next part - * 1 if moved to the next part but now there is no next part - * 0 if moved to the next part and there are still more parts - */ -s8_t -netbuf_next(struct netbuf *buf) -{ - LWIP_ERROR("netbuf_next: invalid buf", (buf != NULL), return -1;); - if (buf->ptr->next == NULL) { - return -1; - } - buf->ptr = buf->ptr->next; - if (buf->ptr->next == NULL) { - return 1; - } - return 0; -} - -/** - * @ingroup netbuf - * Move the current data pointer of a packet buffer contained in a netbuf - * to the beginning of the packet. - * The packet buffer itself is not modified. - * - * @param buf the netbuf to modify - */ -void -netbuf_first(struct netbuf *buf) -{ - LWIP_ERROR("netbuf_first: invalid buf", (buf != NULL), return;); - buf->ptr = buf->p; -} - -#endif /* LWIP_NETCONN */ diff --git a/third_party/lwip/repo/lwip/src/api/netdb.c b/third_party/lwip/repo/lwip/src/api/netdb.c deleted file mode 100644 index ccd9586fda0685..00000000000000 --- a/third_party/lwip/repo/lwip/src/api/netdb.c +++ /dev/null @@ -1,413 +0,0 @@ -/** - * @file - * API functions for name resolving - * - * @defgroup netdbapi NETDB API - * @ingroup socket - */ - -/* - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Simon Goldschmidt - * - */ - -#include "lwip/netdb.h" - -#if LWIP_DNS && LWIP_SOCKET - -#include "lwip/err.h" -#include "lwip/mem.h" -#include "lwip/memp.h" -#include "lwip/ip_addr.h" -#include "lwip/api.h" -#include "lwip/dns.h" - -#include /* memset */ -#include /* atoi */ - -/** helper struct for gethostbyname_r to access the char* buffer */ -struct gethostbyname_r_helper { - ip_addr_t *addr_list[2]; - ip_addr_t addr; - char *aliases; -}; - -/** h_errno is exported in netdb.h for access by applications. */ -#if LWIP_DNS_API_DECLARE_H_ERRNO -int h_errno; -#endif /* LWIP_DNS_API_DECLARE_H_ERRNO */ - -/** define "hostent" variables storage: 0 if we use a static (but unprotected) - * set of variables for lwip_gethostbyname, 1 if we use a local storage */ -#ifndef LWIP_DNS_API_HOSTENT_STORAGE -#define LWIP_DNS_API_HOSTENT_STORAGE 0 -#endif - -/** define "hostent" variables storage */ -#if LWIP_DNS_API_HOSTENT_STORAGE -#define HOSTENT_STORAGE -#else -#define HOSTENT_STORAGE static -#endif /* LWIP_DNS_API_STATIC_HOSTENT */ - -/** - * Returns an entry containing addresses of address family AF_INET - * for the host with name name. - * Due to dns_gethostbyname limitations, only one address is returned. - * - * @param name the hostname to resolve - * @return an entry containing addresses of address family AF_INET - * for the host with name name - */ -struct hostent* -lwip_gethostbyname(const char *name) -{ - err_t err; - ip_addr_t addr; - - /* buffer variables for lwip_gethostbyname() */ - HOSTENT_STORAGE struct hostent s_hostent; - HOSTENT_STORAGE char *s_aliases; - HOSTENT_STORAGE ip_addr_t s_hostent_addr; - HOSTENT_STORAGE ip_addr_t *s_phostent_addr[2]; - HOSTENT_STORAGE char s_hostname[DNS_MAX_NAME_LENGTH + 1]; - - /* query host IP address */ - err = netconn_gethostbyname(name, &addr); - if (err != ERR_OK) { - LWIP_DEBUGF(DNS_DEBUG, ("lwip_gethostbyname(%s) failed, err=%d\n", name, err)); - h_errno = HOST_NOT_FOUND; - return NULL; - } - - /* fill hostent */ - s_hostent_addr = addr; - s_phostent_addr[0] = &s_hostent_addr; - s_phostent_addr[1] = NULL; - strncpy(s_hostname, name, DNS_MAX_NAME_LENGTH); - s_hostname[DNS_MAX_NAME_LENGTH] = 0; - s_hostent.h_name = s_hostname; - s_aliases = NULL; - s_hostent.h_aliases = &s_aliases; - s_hostent.h_addrtype = AF_INET; - s_hostent.h_length = sizeof(ip_addr_t); - s_hostent.h_addr_list = (char**)&s_phostent_addr; - -#if DNS_DEBUG - /* dump hostent */ - LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_name == %s\n", s_hostent.h_name)); - LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_aliases == %p\n", (void*)s_hostent.h_aliases)); - /* h_aliases are always empty */ - LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addrtype == %d\n", s_hostent.h_addrtype)); - LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_length == %d\n", s_hostent.h_length)); - LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addr_list == %p\n", (void*)s_hostent.h_addr_list)); - if (s_hostent.h_addr_list != NULL) { - u8_t idx; - for (idx=0; s_hostent.h_addr_list[idx]; idx++) { - LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addr_list[%i] == %p\n", idx, s_hostent.h_addr_list[idx])); - LWIP_DEBUGF(DNS_DEBUG, ("hostent.h_addr_list[%i]-> == %s\n", idx, ipaddr_ntoa((ip_addr_t*)s_hostent.h_addr_list[idx]))); - } - } -#endif /* DNS_DEBUG */ - -#if LWIP_DNS_API_HOSTENT_STORAGE - /* this function should return the "per-thread" hostent after copy from s_hostent */ - return sys_thread_hostent(&s_hostent); -#else - return &s_hostent; -#endif /* LWIP_DNS_API_HOSTENT_STORAGE */ -} - -/** - * Thread-safe variant of lwip_gethostbyname: instead of using a static - * buffer, this function takes buffer and errno pointers as arguments - * and uses these for the result. - * - * @param name the hostname to resolve - * @param ret pre-allocated struct where to store the result - * @param buf pre-allocated buffer where to store additional data - * @param buflen the size of buf - * @param result pointer to a hostent pointer that is set to ret on success - * and set to zero on error - * @param h_errnop pointer to an int where to store errors (instead of modifying - * the global h_errno) - * @return 0 on success, non-zero on error, additional error information - * is stored in *h_errnop instead of h_errno to be thread-safe - */ -int -lwip_gethostbyname_r(const char *name, struct hostent *ret, char *buf, - size_t buflen, struct hostent **result, int *h_errnop) -{ - err_t err; - struct gethostbyname_r_helper *h; - char *hostname; - size_t namelen; - int lh_errno; - - if (h_errnop == NULL) { - /* ensure h_errnop is never NULL */ - h_errnop = &lh_errno; - } - - if (result == NULL) { - /* not all arguments given */ - *h_errnop = EINVAL; - return -1; - } - /* first thing to do: set *result to nothing */ - *result = NULL; - if ((name == NULL) || (ret == NULL) || (buf == NULL)) { - /* not all arguments given */ - *h_errnop = EINVAL; - return -1; - } - - namelen = strlen(name); - if (buflen < (sizeof(struct gethostbyname_r_helper) + namelen + 1 + (MEM_ALIGNMENT - 1))) { - /* buf can't hold the data needed + a copy of name */ - *h_errnop = ERANGE; - return -1; - } - - h = (struct gethostbyname_r_helper*)LWIP_MEM_ALIGN(buf); - hostname = ((char*)h) + sizeof(struct gethostbyname_r_helper); - - /* query host IP address */ - err = netconn_gethostbyname(name, &h->addr); - if (err != ERR_OK) { - LWIP_DEBUGF(DNS_DEBUG, ("lwip_gethostbyname(%s) failed, err=%d\n", name, err)); - *h_errnop = HOST_NOT_FOUND; - return -1; - } - - /* copy the hostname into buf */ - MEMCPY(hostname, name, namelen); - hostname[namelen] = 0; - - /* fill hostent */ - h->addr_list[0] = &h->addr; - h->addr_list[1] = NULL; - h->aliases = NULL; - ret->h_name = hostname; - ret->h_aliases = &h->aliases; - ret->h_addrtype = AF_INET; - ret->h_length = sizeof(ip_addr_t); - ret->h_addr_list = (char**)&h->addr_list; - - /* set result != NULL */ - *result = ret; - - /* return success */ - return 0; -} - -/** - * Frees one or more addrinfo structures returned by getaddrinfo(), along with - * any additional storage associated with those structures. If the ai_next field - * of the structure is not null, the entire list of structures is freed. - * - * @param ai struct addrinfo to free - */ -void -lwip_freeaddrinfo(struct addrinfo *ai) -{ - struct addrinfo *next; - - while (ai != NULL) { - next = ai->ai_next; - memp_free(MEMP_NETDB, ai); - ai = next; - } -} - -/** - * Translates the name of a service location (for example, a host name) and/or - * a service name and returns a set of socket addresses and associated - * information to be used in creating a socket with which to address the - * specified service. - * Memory for the result is allocated internally and must be freed by calling - * lwip_freeaddrinfo()! - * - * Due to a limitation in dns_gethostbyname, only the first address of a - * host is returned. - * Also, service names are not supported (only port numbers)! - * - * @param nodename descriptive name or address string of the host - * (may be NULL -> local address) - * @param servname port number as string of NULL - * @param hints structure containing input values that set socktype and protocol - * @param res pointer to a pointer where to store the result (set to NULL on failure) - * @return 0 on success, non-zero on failure - * - * @todo: implement AI_V4MAPPED, AI_ADDRCONFIG - */ -int -lwip_getaddrinfo(const char *nodename, const char *servname, - const struct addrinfo *hints, struct addrinfo **res) -{ - err_t err; - ip_addr_t addr; - struct addrinfo *ai; - struct sockaddr_storage *sa = NULL; - int port_nr = 0; - size_t total_size; - size_t namelen = 0; - int ai_family; - - if (res == NULL) { - return EAI_FAIL; - } - *res = NULL; - if ((nodename == NULL) && (servname == NULL)) { - return EAI_NONAME; - } - - if (hints != NULL) { - ai_family = hints->ai_family; - if ((ai_family != AF_UNSPEC) -#if LWIP_IPV4 - && (ai_family != AF_INET) -#endif /* LWIP_IPV4 */ -#if LWIP_IPV6 - && (ai_family != AF_INET6) -#endif /* LWIP_IPV6 */ - ) { - return EAI_FAMILY; - } - } else { - ai_family = AF_UNSPEC; - } - - if (servname != NULL) { - /* service name specified: convert to port number - * @todo?: currently, only ASCII integers (port numbers) are supported (AI_NUMERICSERV)! */ - port_nr = atoi(servname); - if ((port_nr <= 0) || (port_nr > 0xffff)) { - return EAI_SERVICE; - } - } - - if (nodename != NULL) { - /* service location specified, try to resolve */ - if ((hints != NULL) && (hints->ai_flags & AI_NUMERICHOST)) { - /* no DNS lookup, just parse for an address string */ - if (!ipaddr_aton(nodename, &addr)) { - return EAI_NONAME; - } -#if LWIP_IPV4 && LWIP_IPV6 - if ((IP_IS_V6_VAL(addr) && ai_family == AF_INET) || - (IP_IS_V4_VAL(addr) && ai_family == AF_INET6)) { - return EAI_NONAME; - } -#endif /* LWIP_IPV4 && LWIP_IPV6 */ - } else { -#if LWIP_IPV4 && LWIP_IPV6 - /* AF_UNSPEC: prefer IPv4 */ - u8_t type = NETCONN_DNS_IPV4_IPV6; - if (ai_family == AF_INET) { - type = NETCONN_DNS_IPV4; - } else if (ai_family == AF_INET6) { - type = NETCONN_DNS_IPV6; - } -#endif /* LWIP_IPV4 && LWIP_IPV6 */ - err = netconn_gethostbyname_addrtype(nodename, &addr, type); - if (err != ERR_OK) { - return EAI_FAIL; - } - } - } else { - /* service location specified, use loopback address */ - if ((hints != NULL) && (hints->ai_flags & AI_PASSIVE)) { - ip_addr_set_any(ai_family == AF_INET6, &addr); - } else { - ip_addr_set_loopback(ai_family == AF_INET6, &addr); - } - } - - total_size = sizeof(struct addrinfo) + sizeof(struct sockaddr_storage); - if (nodename != NULL) { - namelen = strlen(nodename); - if (namelen > DNS_MAX_NAME_LENGTH) { - /* invalid name length */ - return EAI_FAIL; - } - LWIP_ASSERT("namelen is too long", total_size + namelen + 1 > total_size); - total_size += namelen + 1; - } - /* If this fails, please report to lwip-devel! :-) */ - LWIP_ASSERT("total_size <= NETDB_ELEM_SIZE: please report this!", - total_size <= NETDB_ELEM_SIZE); - ai = (struct addrinfo *)memp_malloc(MEMP_NETDB); - if (ai == NULL) { - return EAI_MEMORY; - } - memset(ai, 0, total_size); - /* cast through void* to get rid of alignment warnings */ - sa = (struct sockaddr_storage *)(void*)((u8_t*)ai + sizeof(struct addrinfo)); - if (IP_IS_V6_VAL(addr)) { -#if LWIP_IPV6 - struct sockaddr_in6 *sa6 = (struct sockaddr_in6*)sa; - /* set up sockaddr */ - inet6_addr_from_ip6addr(&sa6->sin6_addr, ip_2_ip6(&addr)); - sa6->sin6_family = AF_INET6; - sa6->sin6_len = sizeof(struct sockaddr_in6); - sa6->sin6_port = lwip_htons((u16_t)port_nr); - ai->ai_family = AF_INET6; -#endif /* LWIP_IPV6 */ - } else { -#if LWIP_IPV4 - struct sockaddr_in *sa4 = (struct sockaddr_in*)sa; - /* set up sockaddr */ - inet_addr_from_ip4addr(&sa4->sin_addr, ip_2_ip4(&addr)); - sa4->sin_family = AF_INET; - sa4->sin_len = sizeof(struct sockaddr_in); - sa4->sin_port = lwip_htons((u16_t)port_nr); - ai->ai_family = AF_INET; -#endif /* LWIP_IPV4 */ - } - - /* set up addrinfo */ - if (hints != NULL) { - /* copy socktype & protocol from hints if specified */ - ai->ai_socktype = hints->ai_socktype; - ai->ai_protocol = hints->ai_protocol; - } - if (nodename != NULL) { - /* copy nodename to canonname if specified */ - ai->ai_canonname = ((char*)ai + sizeof(struct addrinfo) + sizeof(struct sockaddr_storage)); - MEMCPY(ai->ai_canonname, nodename, namelen); - ai->ai_canonname[namelen] = 0; - } - ai->ai_addrlen = sizeof(struct sockaddr_storage); - ai->ai_addr = (struct sockaddr*)sa; - - *res = ai; - - return 0; -} - -#endif /* LWIP_DNS && LWIP_SOCKET */ diff --git a/third_party/lwip/repo/lwip/src/api/netifapi.c b/third_party/lwip/repo/lwip/src/api/netifapi.c deleted file mode 100644 index 364889d7f01117..00000000000000 --- a/third_party/lwip/repo/lwip/src/api/netifapi.c +++ /dev/null @@ -1,316 +0,0 @@ -/** - * @file - * Network Interface Sequential API module - * - * @defgroup netifapi NETIF API - * @ingroup sequential_api - * Thread-safe functions to be called from non-TCPIP threads - * - * @defgroup netifapi_netif NETIF related - * @ingroup netifapi - * To be called from non-TCPIP threads - */ - -/* - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - */ - -#include "lwip/opt.h" - -#if LWIP_NETIF_API /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/netifapi.h" -#include "lwip/memp.h" -#include "lwip/priv/tcpip_priv.h" - -#include /* strncpy */ - -#define NETIFAPI_VAR_REF(name) API_VAR_REF(name) -#define NETIFAPI_VAR_DECLARE(name) API_VAR_DECLARE(struct netifapi_msg, name) -#define NETIFAPI_VAR_ALLOC(name) API_VAR_ALLOC(struct netifapi_msg, MEMP_NETIFAPI_MSG, name, ERR_MEM) -#define NETIFAPI_VAR_FREE(name) API_VAR_FREE(MEMP_NETIFAPI_MSG, name) - -/** - * Call netif_add() inside the tcpip_thread context. - */ -static err_t -netifapi_do_netif_add(struct tcpip_api_call_data *m) -{ - /* cast through void* to silence alignment warnings. - * We know it works because the structs have been instantiated as struct netifapi_msg */ - struct netifapi_msg *msg = (struct netifapi_msg*)(void*)m; - - if (!netif_add( msg->netif, -#if LWIP_IPV4 - API_EXPR_REF(msg->msg.add.ipaddr), - API_EXPR_REF(msg->msg.add.netmask), - API_EXPR_REF(msg->msg.add.gw), -#endif /* LWIP_IPV4 */ - msg->msg.add.state, - msg->msg.add.init, - msg->msg.add.input)) { - return ERR_IF; - } else { - return ERR_OK; - } -} - -#if LWIP_IPV4 -/** - * Call netif_set_addr() inside the tcpip_thread context. - */ -static err_t -netifapi_do_netif_set_addr(struct tcpip_api_call_data *m) -{ - /* cast through void* to silence alignment warnings. - * We know it works because the structs have been instantiated as struct netifapi_msg */ - struct netifapi_msg *msg = (struct netifapi_msg*)(void*)m; - - netif_set_addr( msg->netif, - API_EXPR_REF(msg->msg.add.ipaddr), - API_EXPR_REF(msg->msg.add.netmask), - API_EXPR_REF(msg->msg.add.gw)); - return ERR_OK; -} -#endif /* LWIP_IPV4 */ - -/** -* Call netif_name_to_index() inside the tcpip_thread context. -*/ -static err_t -netifapi_do_name_to_index(struct tcpip_api_call_data *m) -{ - /* cast through void* to silence alignment warnings. - * We know it works because the structs have been instantiated as struct netifapi_msg */ - struct netifapi_msg *msg = (struct netifapi_msg*)(void*)m; - - msg->msg.ifs.index = netif_name_to_index(msg->msg.ifs.name); - return ERR_OK; -} - -/** -* Call netif_index_to_name() inside the tcpip_thread context. -*/ -static err_t -netifapi_do_index_to_name(struct tcpip_api_call_data *m) -{ - /* cast through void* to silence alignment warnings. - * We know it works because the structs have been instantiated as struct netifapi_msg */ - struct netifapi_msg *msg = (struct netifapi_msg*)(void*)m; - - if (!netif_index_to_name(msg->msg.ifs.index, msg->msg.ifs.name)) { - /* return failure via empty name */ - msg->msg.ifs.name[0] = '\0'; - } - return ERR_OK; -} - -/** - * Call the "errtfunc" (or the "voidfunc" if "errtfunc" is NULL) inside the - * tcpip_thread context. - */ -static err_t -netifapi_do_netif_common(struct tcpip_api_call_data *m) -{ - /* cast through void* to silence alignment warnings. - * We know it works because the structs have been instantiated as struct netifapi_msg */ - struct netifapi_msg *msg = (struct netifapi_msg*)(void*)m; - - if (msg->msg.common.errtfunc != NULL) { - return msg->msg.common.errtfunc(msg->netif); - } else { - msg->msg.common.voidfunc(msg->netif); - return ERR_OK; - } -} - -/** - * @ingroup netifapi_netif - * Call netif_add() in a thread-safe way by running that function inside the - * tcpip_thread context. - * - * @note for params @see netif_add() - */ -err_t -netifapi_netif_add(struct netif *netif, -#if LWIP_IPV4 - const ip4_addr_t *ipaddr, const ip4_addr_t *netmask, const ip4_addr_t *gw, -#endif /* LWIP_IPV4 */ - void *state, netif_init_fn init, netif_input_fn input) -{ - err_t err; - NETIFAPI_VAR_DECLARE(msg); - NETIFAPI_VAR_ALLOC(msg); - -#if LWIP_IPV4 - if (ipaddr == NULL) { - ipaddr = IP4_ADDR_ANY4; - } - if (netmask == NULL) { - netmask = IP4_ADDR_ANY4; - } - if (gw == NULL) { - gw = IP4_ADDR_ANY4; - } -#endif /* LWIP_IPV4 */ - - NETIFAPI_VAR_REF(msg).netif = netif; -#if LWIP_IPV4 - NETIFAPI_VAR_REF(msg).msg.add.ipaddr = NETIFAPI_VAR_REF(ipaddr); - NETIFAPI_VAR_REF(msg).msg.add.netmask = NETIFAPI_VAR_REF(netmask); - NETIFAPI_VAR_REF(msg).msg.add.gw = NETIFAPI_VAR_REF(gw); -#endif /* LWIP_IPV4 */ - NETIFAPI_VAR_REF(msg).msg.add.state = state; - NETIFAPI_VAR_REF(msg).msg.add.init = init; - NETIFAPI_VAR_REF(msg).msg.add.input = input; - err = tcpip_api_call(netifapi_do_netif_add, &API_VAR_REF(msg).call); - NETIFAPI_VAR_FREE(msg); - return err; -} - -#if LWIP_IPV4 -/** - * @ingroup netifapi_netif - * Call netif_set_addr() in a thread-safe way by running that function inside the - * tcpip_thread context. - * - * @note for params @see netif_set_addr() - */ -err_t -netifapi_netif_set_addr(struct netif *netif, - const ip4_addr_t *ipaddr, - const ip4_addr_t *netmask, - const ip4_addr_t *gw) -{ - err_t err; - NETIFAPI_VAR_DECLARE(msg); - NETIFAPI_VAR_ALLOC(msg); - - if (ipaddr == NULL) { - ipaddr = IP4_ADDR_ANY4; - } - if (netmask == NULL) { - netmask = IP4_ADDR_ANY4; - } - if (gw == NULL) { - gw = IP4_ADDR_ANY4; - } - - NETIFAPI_VAR_REF(msg).netif = netif; - NETIFAPI_VAR_REF(msg).msg.add.ipaddr = NETIFAPI_VAR_REF(ipaddr); - NETIFAPI_VAR_REF(msg).msg.add.netmask = NETIFAPI_VAR_REF(netmask); - NETIFAPI_VAR_REF(msg).msg.add.gw = NETIFAPI_VAR_REF(gw); - err = tcpip_api_call(netifapi_do_netif_set_addr, &API_VAR_REF(msg).call); - NETIFAPI_VAR_FREE(msg); - return err; -} -#endif /* LWIP_IPV4 */ - -/** - * call the "errtfunc" (or the "voidfunc" if "errtfunc" is NULL) in a thread-safe - * way by running that function inside the tcpip_thread context. - * - * @note use only for functions where there is only "netif" parameter. - */ -err_t -netifapi_netif_common(struct netif *netif, netifapi_void_fn voidfunc, - netifapi_errt_fn errtfunc) -{ - err_t err; - NETIFAPI_VAR_DECLARE(msg); - NETIFAPI_VAR_ALLOC(msg); - - NETIFAPI_VAR_REF(msg).netif = netif; - NETIFAPI_VAR_REF(msg).msg.common.voidfunc = voidfunc; - NETIFAPI_VAR_REF(msg).msg.common.errtfunc = errtfunc; - err = tcpip_api_call(netifapi_do_netif_common, &API_VAR_REF(msg).call); - NETIFAPI_VAR_FREE(msg); - return err; -} - -/** -* @ingroup netifapi_netif -* Call netif_name_to_index() in a thread-safe way by running that function inside the -* tcpip_thread context. -* -* @param name the interface name of the netif -* @param index output index of the found netif -*/ -err_t -netifapi_netif_name_to_index(const char *name, u8_t *index) -{ - err_t err; - NETIFAPI_VAR_DECLARE(msg); - NETIFAPI_VAR_ALLOC(msg); - - *index = 0; - -#if LWIP_MPU_COMPATIBLE - strncpy(NETIFAPI_VAR_REF(msg).msg.ifs.name, name, IF_NAMESIZE - 1); - NETIFAPI_VAR_REF(msg).msg.ifs.name[IF_NAMESIZE - 1] = '\0'; -#else - NETIFAPI_VAR_REF(msg).msg.ifs.name = (char *)name; -#endif /* LWIP_MPU_COMPATIBLE */ - err = tcpip_api_call(netifapi_do_name_to_index, &API_VAR_REF(msg).call); - if (!err) { - *index = NETIFAPI_VAR_REF(msg).msg.ifs.index; - } - NETIFAPI_VAR_FREE(msg); - return err; -} - -/** -* @ingroup netifapi_netif -* Call netif_index_to_name() in a thread-safe way by running that function inside the -* tcpip_thread context. -* -* @param index the interface index of the netif -* @param name output name of the found netif, empty '\0' string if netif not found. -* name should be of at least IF_NAMESIZE bytes -*/ -err_t -netifapi_netif_index_to_name(u8_t index, char *name) -{ - err_t err; - NETIFAPI_VAR_DECLARE(msg); - NETIFAPI_VAR_ALLOC(msg); - - NETIFAPI_VAR_REF(msg).msg.ifs.index = index; -#if !LWIP_MPU_COMPATIBLE - NETIFAPI_VAR_REF(msg).msg.ifs.name = name; -#endif /* LWIP_MPU_COMPATIBLE */ - err = tcpip_api_call(netifapi_do_index_to_name, &API_VAR_REF(msg).call); -#if LWIP_MPU_COMPATIBLE - if (!err) { - strncpy(name, NETIFAPI_VAR_REF(msg).msg.ifs.name, IF_NAMESIZE - 1); - name[IF_NAMESIZE - 1] = '\0'; - } -#endif /* LWIP_MPU_COMPATIBLE */ - NETIFAPI_VAR_FREE(msg); - return err; -} - -#endif /* LWIP_NETIF_API */ diff --git a/third_party/lwip/repo/lwip/src/api/sockets.c b/third_party/lwip/repo/lwip/src/api/sockets.c deleted file mode 100644 index 47bd97ee87fc26..00000000000000 --- a/third_party/lwip/repo/lwip/src/api/sockets.c +++ /dev/null @@ -1,2827 +0,0 @@ -/** - * @file - * Sockets BSD-Like API module - * - * @defgroup socket Socket API - * @ingroup sequential_api - * BSD-style socket API.\n - * Thread-safe, to be called from non-TCPIP threads only.\n - * Can be activated by defining @ref LWIP_SOCKET to 1.\n - * Header is in posix/sys/socket.h\b - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - * Improved by Marc Boucher and David Haas - * - */ - -#include "lwip/opt.h" - -#if LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/sockets.h" -#include "lwip/api.h" -#include "lwip/sys.h" -#include "lwip/igmp.h" -#include "lwip/inet.h" -#include "lwip/tcp.h" -#include "lwip/raw.h" -#include "lwip/udp.h" -#include "lwip/memp.h" -#include "lwip/pbuf.h" -#include "lwip/priv/tcpip_priv.h" -#if LWIP_CHECKSUM_ON_COPY -#include "lwip/inet_chksum.h" -#endif - -#include - -/* If the netconn API is not required publicly, then we include the necessary - files here to get the implementation */ -#if !LWIP_NETCONN -#undef LWIP_NETCONN -#define LWIP_NETCONN 1 -#include "api_msg.c" -#include "api_lib.c" -#include "netbuf.c" -#undef LWIP_NETCONN -#define LWIP_NETCONN 0 -#endif - -#if LWIP_IPV4 -#define IP4ADDR_PORT_TO_SOCKADDR(sin, ipaddr, port) do { \ - (sin)->sin_len = sizeof(struct sockaddr_in); \ - (sin)->sin_family = AF_INET; \ - (sin)->sin_port = lwip_htons((port)); \ - inet_addr_from_ip4addr(&(sin)->sin_addr, ipaddr); \ - memset((sin)->sin_zero, 0, SIN_ZERO_LEN); }while(0) -#define SOCKADDR4_TO_IP4ADDR_PORT(sin, ipaddr, port) do { \ - inet_addr_to_ip4addr(ip_2_ip4(ipaddr), &((sin)->sin_addr)); \ - (port) = lwip_ntohs((sin)->sin_port); }while(0) -#endif /* LWIP_IPV4 */ - -#if LWIP_IPV6 -#define IP6ADDR_PORT_TO_SOCKADDR(sin6, ipaddr, port) do { \ - (sin6)->sin6_len = sizeof(struct sockaddr_in6); \ - (sin6)->sin6_family = AF_INET6; \ - (sin6)->sin6_port = lwip_htons((port)); \ - (sin6)->sin6_flowinfo = 0; \ - inet6_addr_from_ip6addr(&(sin6)->sin6_addr, ipaddr); \ - (sin6)->sin6_scope_id = 0; }while(0) -#define SOCKADDR6_TO_IP6ADDR_PORT(sin6, ipaddr, port) do { \ - inet6_addr_to_ip6addr(ip_2_ip6(ipaddr), &((sin6)->sin6_addr)); \ - (port) = lwip_ntohs((sin6)->sin6_port); }while(0) -#endif /* LWIP_IPV6 */ - -#if LWIP_IPV4 && LWIP_IPV6 -static void sockaddr_to_ipaddr_port(const struct sockaddr* sockaddr, ip_addr_t* ipaddr, u16_t* port); - -#define IS_SOCK_ADDR_LEN_VALID(namelen) (((namelen) == sizeof(struct sockaddr_in)) || \ - ((namelen) == sizeof(struct sockaddr_in6))) -#define IS_SOCK_ADDR_TYPE_VALID(name) (((name)->sa_family == AF_INET) || \ - ((name)->sa_family == AF_INET6)) -#define SOCK_ADDR_TYPE_MATCH(name, sock) \ - ((((name)->sa_family == AF_INET) && !(NETCONNTYPE_ISIPV6((sock)->conn->type))) || \ - (((name)->sa_family == AF_INET6) && (NETCONNTYPE_ISIPV6((sock)->conn->type)))) -#define IPADDR_PORT_TO_SOCKADDR(sockaddr, ipaddr, port) do { \ - if (IP_IS_V6(ipaddr)) { \ - IP6ADDR_PORT_TO_SOCKADDR((struct sockaddr_in6*)(void*)(sockaddr), ip_2_ip6(ipaddr), port); \ - } else { \ - IP4ADDR_PORT_TO_SOCKADDR((struct sockaddr_in*)(void*)(sockaddr), ip_2_ip4(ipaddr), port); \ - } } while(0) -#define SOCKADDR_TO_IPADDR_PORT(sockaddr, ipaddr, port) sockaddr_to_ipaddr_port(sockaddr, ipaddr, &(port)) -#define DOMAIN_TO_NETCONN_TYPE(domain, type) (((domain) == AF_INET) ? \ - (type) : (enum netconn_type)((type) | NETCONN_TYPE_IPV6)) -#elif LWIP_IPV6 /* LWIP_IPV4 && LWIP_IPV6 */ -#define IS_SOCK_ADDR_LEN_VALID(namelen) ((namelen) == sizeof(struct sockaddr_in6)) -#define IS_SOCK_ADDR_TYPE_VALID(name) ((name)->sa_family == AF_INET6) -#define SOCK_ADDR_TYPE_MATCH(name, sock) 1 -#define IPADDR_PORT_TO_SOCKADDR(sockaddr, ipaddr, port) \ - IP6ADDR_PORT_TO_SOCKADDR((struct sockaddr_in6*)(void*)(sockaddr), ip_2_ip6(ipaddr), port) -#define SOCKADDR_TO_IPADDR_PORT(sockaddr, ipaddr, port) \ - SOCKADDR6_TO_IP6ADDR_PORT((const struct sockaddr_in6*)(const void*)(sockaddr), ipaddr, port) -#define DOMAIN_TO_NETCONN_TYPE(domain, netconn_type) (netconn_type) -#else /*-> LWIP_IPV4: LWIP_IPV4 && LWIP_IPV6 */ -#define IS_SOCK_ADDR_LEN_VALID(namelen) ((namelen) == sizeof(struct sockaddr_in)) -#define IS_SOCK_ADDR_TYPE_VALID(name) ((name)->sa_family == AF_INET) -#define SOCK_ADDR_TYPE_MATCH(name, sock) 1 -#define IPADDR_PORT_TO_SOCKADDR(sockaddr, ipaddr, port) \ - IP4ADDR_PORT_TO_SOCKADDR((struct sockaddr_in*)(void*)(sockaddr), ip_2_ip4(ipaddr), port) -#define SOCKADDR_TO_IPADDR_PORT(sockaddr, ipaddr, port) \ - SOCKADDR4_TO_IP4ADDR_PORT((const struct sockaddr_in*)(const void*)(sockaddr), ipaddr, port) -#define DOMAIN_TO_NETCONN_TYPE(domain, netconn_type) (netconn_type) -#endif /* LWIP_IPV6 */ - -#define IS_SOCK_ADDR_TYPE_VALID_OR_UNSPEC(name) (((name)->sa_family == AF_UNSPEC) || \ - IS_SOCK_ADDR_TYPE_VALID(name)) -#define SOCK_ADDR_TYPE_MATCH_OR_UNSPEC(name, sock) (((name)->sa_family == AF_UNSPEC) || \ - SOCK_ADDR_TYPE_MATCH(name, sock)) -#define IS_SOCK_ADDR_ALIGNED(name) ((((mem_ptr_t)(name)) % 4) == 0) - - -#define LWIP_SOCKOPT_CHECK_OPTLEN(optlen, opttype) do { if ((optlen) < sizeof(opttype)) { return EINVAL; }}while(0) -#define LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, optlen, opttype) do { \ - LWIP_SOCKOPT_CHECK_OPTLEN(optlen, opttype); \ - if ((sock)->conn == NULL) { return EINVAL; } }while(0) -#define LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, optlen, opttype) do { \ - LWIP_SOCKOPT_CHECK_OPTLEN(optlen, opttype); \ - if (((sock)->conn == NULL) || ((sock)->conn->pcb.tcp == NULL)) { return EINVAL; } }while(0) -#define LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, opttype, netconntype) do { \ - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, optlen, opttype); \ - if (NETCONNTYPE_GROUP(netconn_type((sock)->conn)) != netconntype) { return ENOPROTOOPT; } }while(0) - - -#define LWIP_SETGETSOCKOPT_DATA_VAR_REF(name) API_VAR_REF(name) -#define LWIP_SETGETSOCKOPT_DATA_VAR_DECLARE(name) API_VAR_DECLARE(struct lwip_setgetsockopt_data, name) -#define LWIP_SETGETSOCKOPT_DATA_VAR_FREE(name) API_VAR_FREE(MEMP_SOCKET_SETGETSOCKOPT_DATA, name) -#if LWIP_MPU_COMPATIBLE -#define LWIP_SETGETSOCKOPT_DATA_VAR_ALLOC(name, sock) do { \ - name = (struct lwip_setgetsockopt_data *)memp_malloc(MEMP_SOCKET_SETGETSOCKOPT_DATA); \ - if (name == NULL) { \ - sock_set_errno(sock, ENOMEM); \ - return -1; \ - } }while(0) -#else /* LWIP_MPU_COMPATIBLE */ -#define LWIP_SETGETSOCKOPT_DATA_VAR_ALLOC(name, sock) -#endif /* LWIP_MPU_COMPATIBLE */ - -#if LWIP_SO_SNDRCVTIMEO_NONSTANDARD -#define LWIP_SO_SNDRCVTIMEO_OPTTYPE int -#define LWIP_SO_SNDRCVTIMEO_SET(optval, val) (*(int *)(optval) = (val)) -#define LWIP_SO_SNDRCVTIMEO_GET_MS(optval) ((s32_t)*(const int*)(optval)) -#else -#define LWIP_SO_SNDRCVTIMEO_OPTTYPE struct timeval -#define LWIP_SO_SNDRCVTIMEO_SET(optval, val) do { \ - s32_t loc = (val); \ - ((struct timeval *)(optval))->tv_sec = (loc) / 1000U; \ - ((struct timeval *)(optval))->tv_usec = ((loc) % 1000U) * 1000U; }while(0) -#define LWIP_SO_SNDRCVTIMEO_GET_MS(optval) ((((const struct timeval *)(optval))->tv_sec * 1000U) + (((const struct timeval *)(optval))->tv_usec / 1000U)) -#endif - -#define NUM_SOCKETS MEMP_NUM_NETCONN - -/** This is overridable for the rare case where more than 255 threads - * select on the same socket... - */ -#ifndef SELWAIT_T -#define SELWAIT_T u8_t -#endif - -/** Contains all internal pointers and states used for a socket */ -struct lwip_sock { - /** sockets currently are built on netconns, each socket has one netconn */ - struct netconn *conn; - /** data that was left from the previous read */ - void *lastdata; - /** offset in the data that was left from the previous read */ - u16_t lastoffset; - /** number of times data was received, set by event_callback(), - tested by the receive and select functions */ - s16_t rcvevent; - /** number of times data was ACKed (free send buffer), set by event_callback(), - tested by select */ - u16_t sendevent; - /** error happened for this socket, set by event_callback(), tested by select */ - u16_t errevent; - /** last error that occurred on this socket (in fact, all our errnos fit into an u8_t) */ - u8_t err; - /** counter of how many threads are waiting for this socket using select */ - SELWAIT_T select_waiting; -}; - -#if LWIP_NETCONN_SEM_PER_THREAD -#define SELECT_SEM_T sys_sem_t* -#define SELECT_SEM_PTR(sem) (sem) -#else /* LWIP_NETCONN_SEM_PER_THREAD */ -#define SELECT_SEM_T sys_sem_t -#define SELECT_SEM_PTR(sem) (&(sem)) -#endif /* LWIP_NETCONN_SEM_PER_THREAD */ - -/** Description for a task waiting in select */ -struct lwip_select_cb { - /** Pointer to the next waiting task */ - struct lwip_select_cb *next; - /** Pointer to the previous waiting task */ - struct lwip_select_cb *prev; - /** readset passed to select */ - fd_set *readset; - /** writeset passed to select */ - fd_set *writeset; - /** unimplemented: exceptset passed to select */ - fd_set *exceptset; - /** don't signal the same semaphore twice: set to 1 when signalled */ - int sem_signalled; - /** semaphore to wake up a task waiting for select */ - SELECT_SEM_T sem; -}; - -/** A struct sockaddr replacement that has the same alignment as sockaddr_in/ - * sockaddr_in6 if instantiated. - */ -union sockaddr_aligned { - struct sockaddr sa; -#if LWIP_IPV6 - struct sockaddr_in6 sin6; -#endif /* LWIP_IPV6 */ -#if LWIP_IPV4 - struct sockaddr_in sin; -#endif /* LWIP_IPV4 */ -}; - -#if LWIP_IGMP -/* Define the number of IPv4 multicast memberships, default is one per socket */ -#ifndef LWIP_SOCKET_MAX_MEMBERSHIPS -#define LWIP_SOCKET_MAX_MEMBERSHIPS NUM_SOCKETS -#endif - -/* This is to keep track of IP_ADD_MEMBERSHIP calls to drop the membership when - a socket is closed */ -struct lwip_socket_multicast_pair { - /** the socket */ - struct lwip_sock* sock; - /** the interface address */ - ip4_addr_t if_addr; - /** the group address */ - ip4_addr_t multi_addr; -}; - -struct lwip_socket_multicast_pair socket_ipv4_multicast_memberships[LWIP_SOCKET_MAX_MEMBERSHIPS]; - -static int lwip_socket_register_membership(int s, const ip4_addr_t *if_addr, const ip4_addr_t *multi_addr); -static void lwip_socket_unregister_membership(int s, const ip4_addr_t *if_addr, const ip4_addr_t *multi_addr); -static void lwip_socket_drop_registered_memberships(int s); -#endif /* LWIP_IGMP */ - -/** The global array of available sockets */ -static struct lwip_sock sockets[NUM_SOCKETS]; -/** The global list of tasks waiting for select */ -static struct lwip_select_cb *select_cb_list; -/** This counter is increased from lwip_select when the list is changed - and checked in event_callback to see if it has changed. */ -static volatile int select_cb_ctr; - -#if LWIP_SOCKET_SET_ERRNO -#ifndef set_errno -#define set_errno(err) do { if (err) { errno = (err); } } while(0) -#endif -#else /* LWIP_SOCKET_SET_ERRNO */ -#define set_errno(err) -#endif /* LWIP_SOCKET_SET_ERRNO */ - -#define sock_set_errno(sk, e) do { \ - const int sockerr = (e); \ - sk->err = (u8_t)sockerr; \ - set_errno(sockerr); \ -} while (0) - -/* Forward declaration of some functions */ -static void event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len); -#if !LWIP_TCPIP_CORE_LOCKING -static void lwip_getsockopt_callback(void *arg); -static void lwip_setsockopt_callback(void *arg); -#endif -static u8_t lwip_getsockopt_impl(int s, int level, int optname, void *optval, socklen_t *optlen); -static u8_t lwip_setsockopt_impl(int s, int level, int optname, const void *optval, socklen_t optlen); - -#if LWIP_IPV4 && LWIP_IPV6 -static void -sockaddr_to_ipaddr_port(const struct sockaddr* sockaddr, ip_addr_t* ipaddr, u16_t* port) -{ - if ((sockaddr->sa_family) == AF_INET6) { - SOCKADDR6_TO_IP6ADDR_PORT((const struct sockaddr_in6*)(const void*)(sockaddr), ipaddr, *port); - ipaddr->type = IPADDR_TYPE_V6; - } else { - SOCKADDR4_TO_IP4ADDR_PORT((const struct sockaddr_in*)(const void*)(sockaddr), ipaddr, *port); - ipaddr->type = IPADDR_TYPE_V4; - } -} -#endif /* LWIP_IPV4 && LWIP_IPV6 */ - -/** LWIP_NETCONN_SEM_PER_THREAD==1: initialize thread-local semaphore */ -void -lwip_socket_thread_init(void) -{ - netconn_thread_init(); -} - -/** LWIP_NETCONN_SEM_PER_THREAD==1: destroy thread-local semaphore */ -void -lwip_socket_thread_cleanup(void) -{ - netconn_thread_cleanup(); -} - -/** - * Map a externally used socket index to the internal socket representation. - * - * @param s externally used socket index - * @return struct lwip_sock for the socket or NULL if not found - */ -static struct lwip_sock * -get_socket(int s) -{ - struct lwip_sock *sock; - - s -= LWIP_SOCKET_OFFSET; - - if ((s < 0) || (s >= NUM_SOCKETS)) { - LWIP_DEBUGF(SOCKETS_DEBUG, ("get_socket(%d): invalid\n", s + LWIP_SOCKET_OFFSET)); - set_errno(EBADF); - return NULL; - } - - sock = &sockets[s]; - - if (!sock->conn) { - LWIP_DEBUGF(SOCKETS_DEBUG, ("get_socket(%d): not active\n", s + LWIP_SOCKET_OFFSET)); - set_errno(EBADF); - return NULL; - } - - return sock; -} - -/** - * Same as get_socket but doesn't set errno - * - * @param s externally used socket index - * @return struct lwip_sock for the socket or NULL if not found - */ -static struct lwip_sock * -tryget_socket(int s) -{ - s -= LWIP_SOCKET_OFFSET; - if ((s < 0) || (s >= NUM_SOCKETS)) { - return NULL; - } - if (!sockets[s].conn) { - return NULL; - } - return &sockets[s]; -} - -/** - * Allocate a new socket for a given netconn. - * - * @param newconn the netconn for which to allocate a socket - * @param accepted 1 if socket has been created by accept(), - * 0 if socket has been created by socket() - * @return the index of the new socket; -1 on error - */ -static int -alloc_socket(struct netconn *newconn, int accepted) -{ - int i; - SYS_ARCH_DECL_PROTECT(lev); - - /* allocate a new socket identifier */ - for (i = 0; i < NUM_SOCKETS; ++i) { - /* Protect socket array */ - SYS_ARCH_PROTECT(lev); - if (!sockets[i].conn && (sockets[i].select_waiting == 0)) { - sockets[i].conn = newconn; - /* The socket is not yet known to anyone, so no need to protect - after having marked it as used. */ - SYS_ARCH_UNPROTECT(lev); - sockets[i].lastdata = NULL; - sockets[i].lastoffset = 0; - sockets[i].rcvevent = 0; - /* TCP sendbuf is empty, but the socket is not yet writable until connected - * (unless it has been created by accept()). */ - sockets[i].sendevent = (NETCONNTYPE_GROUP(newconn->type) == NETCONN_TCP ? (accepted != 0) : 1); - sockets[i].errevent = 0; - sockets[i].err = 0; - return i + LWIP_SOCKET_OFFSET; - } - SYS_ARCH_UNPROTECT(lev); - } - return -1; -} - -/** Free a socket. The socket's netconn must have been - * delete before! - * - * @param sock the socket to free - * @param is_tcp != 0 for TCP sockets, used to free lastdata - */ -static void -free_socket(struct lwip_sock *sock, int is_tcp) -{ - void *lastdata; - - lastdata = sock->lastdata; - sock->lastdata = NULL; - sock->lastoffset = 0; - sock->err = 0; - - /* Protect socket array */ - SYS_ARCH_SET(sock->conn, NULL); - /* don't use 'sock' after this line, as another task might have allocated it */ - - if (lastdata != NULL) { - if (is_tcp) { - pbuf_free((struct pbuf *)lastdata); - } else { - netbuf_delete((struct netbuf *)lastdata); - } - } -} - -/* Below this, the well-known socket functions are implemented. - * Use google.com or opengroup.org to get a good description :-) - * - * Exceptions are documented! - */ - -int -lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen) -{ - struct lwip_sock *sock, *nsock; - struct netconn *newconn; - ip_addr_t naddr; - u16_t port = 0; - int newsock; - err_t err; - SYS_ARCH_DECL_PROTECT(lev); - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d)...\n", s)); - sock = get_socket(s); - if (!sock) { - return -1; - } - - if (netconn_is_nonblocking(sock->conn) && (sock->rcvevent <= 0)) { - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d): returning EWOULDBLOCK\n", s)); - set_errno(EWOULDBLOCK); - return -1; - } - - /* wait for a new connection */ - err = netconn_accept(sock->conn, &newconn); - if (err != ERR_OK) { - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d): netconn_acept failed, err=%d\n", s, err)); - if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_TCP) { - sock_set_errno(sock, EOPNOTSUPP); - } else if (err == ERR_CLSD) { - sock_set_errno(sock, EINVAL); - } else { - sock_set_errno(sock, err_to_errno(err)); - } - return -1; - } - LWIP_ASSERT("newconn != NULL", newconn != NULL); - - newsock = alloc_socket(newconn, 1); - if (newsock == -1) { - netconn_delete(newconn); - sock_set_errno(sock, ENFILE); - return -1; - } - LWIP_ASSERT("invalid socket index", (newsock >= LWIP_SOCKET_OFFSET) && (newsock < NUM_SOCKETS + LWIP_SOCKET_OFFSET)); - LWIP_ASSERT("newconn->callback == event_callback", newconn->callback == event_callback); - nsock = &sockets[newsock - LWIP_SOCKET_OFFSET]; - - /* See event_callback: If data comes in right away after an accept, even - * though the server task might not have created a new socket yet. - * In that case, newconn->socket is counted down (newconn->socket--), - * so nsock->rcvevent is >= 1 here! - */ - SYS_ARCH_PROTECT(lev); - nsock->rcvevent += (s16_t)(-1 - newconn->socket); - newconn->socket = newsock; - SYS_ARCH_UNPROTECT(lev); - - /* Note that POSIX only requires us to check addr is non-NULL. addrlen must - * not be NULL if addr is valid. - */ - if (addr != NULL) { - union sockaddr_aligned tempaddr; - /* get the IP address and port of the remote host */ - err = netconn_peer(newconn, &naddr, &port); - if (err != ERR_OK) { - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d): netconn_peer failed, err=%d\n", s, err)); - netconn_delete(newconn); - free_socket(nsock, 1); - sock_set_errno(sock, err_to_errno(err)); - return -1; - } - LWIP_ASSERT("addr valid but addrlen NULL", addrlen != NULL); - - IPADDR_PORT_TO_SOCKADDR(&tempaddr, &naddr, port); - if (*addrlen > tempaddr.sa.sa_len) { - *addrlen = tempaddr.sa.sa_len; - } - MEMCPY(addr, &tempaddr, *addrlen); - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d) returning new sock=%d addr=", s, newsock)); - ip_addr_debug_print_val(SOCKETS_DEBUG, naddr); - LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F"\n", port)); - } else { - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_accept(%d) returning new sock=%d", s, newsock)); - } - - sock_set_errno(sock, 0); - return newsock; -} - -int -lwip_bind(int s, const struct sockaddr *name, socklen_t namelen) -{ - struct lwip_sock *sock; - ip_addr_t local_addr; - u16_t local_port; - err_t err; - - sock = get_socket(s); - if (!sock) { - return -1; - } - - if (!SOCK_ADDR_TYPE_MATCH(name, sock)) { - /* sockaddr does not match socket type (IPv4/IPv6) */ - sock_set_errno(sock, err_to_errno(ERR_VAL)); - return -1; - } - - /* check size, family and alignment of 'name' */ - LWIP_ERROR("lwip_bind: invalid address", (IS_SOCK_ADDR_LEN_VALID(namelen) && - IS_SOCK_ADDR_TYPE_VALID(name) && IS_SOCK_ADDR_ALIGNED(name)), - sock_set_errno(sock, err_to_errno(ERR_ARG)); return -1;); - LWIP_UNUSED_ARG(namelen); - - SOCKADDR_TO_IPADDR_PORT(name, &local_addr, local_port); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_bind(%d, addr=", s)); - ip_addr_debug_print_val(SOCKETS_DEBUG, local_addr); - LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F")\n", local_port)); - -#if LWIP_IPV4 && LWIP_IPV6 - /* Dual-stack: Unmap IPv4 mapped IPv6 addresses */ - if (IP_IS_V6_VAL(local_addr) && ip6_addr_isipv4mappedipv6(ip_2_ip6(&local_addr))) { - unmap_ipv4_mapped_ipv6(ip_2_ip4(&local_addr), ip_2_ip6(&local_addr)); - IP_SET_TYPE_VAL(local_addr, IPADDR_TYPE_V4); - } -#endif /* LWIP_IPV4 && LWIP_IPV6 */ - - err = netconn_bind(sock->conn, &local_addr, local_port); - - if (err != ERR_OK) { - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_bind(%d) failed, err=%d\n", s, err)); - sock_set_errno(sock, err_to_errno(err)); - return -1; - } - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_bind(%d) succeeded\n", s)); - sock_set_errno(sock, 0); - return 0; -} - -int -lwip_close(int s) -{ - struct lwip_sock *sock; - int is_tcp = 0; - err_t err; - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_close(%d)\n", s)); - - sock = get_socket(s); - if (!sock) { - return -1; - } - - if (sock->conn != NULL) { - is_tcp = NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP; - } else { - LWIP_ASSERT("sock->lastdata == NULL", sock->lastdata == NULL); - } - -#if LWIP_IGMP - /* drop all possibly joined IGMP memberships */ - lwip_socket_drop_registered_memberships(s); -#endif /* LWIP_IGMP */ - - err = netconn_delete(sock->conn); - if (err != ERR_OK) { - sock_set_errno(sock, err_to_errno(err)); - return -1; - } - - free_socket(sock, is_tcp); - set_errno(0); - return 0; -} - -int -lwip_connect(int s, const struct sockaddr *name, socklen_t namelen) -{ - struct lwip_sock *sock; - err_t err; - - sock = get_socket(s); - if (!sock) { - return -1; - } - - if (!SOCK_ADDR_TYPE_MATCH_OR_UNSPEC(name, sock)) { - /* sockaddr does not match socket type (IPv4/IPv6) */ - sock_set_errno(sock, err_to_errno(ERR_VAL)); - return -1; - } - - LWIP_UNUSED_ARG(namelen); - if (name->sa_family == AF_UNSPEC) { - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d, AF_UNSPEC)\n", s)); - err = netconn_disconnect(sock->conn); - } else { - ip_addr_t remote_addr; - u16_t remote_port; - - /* check size, family and alignment of 'name' */ - LWIP_ERROR("lwip_connect: invalid address", IS_SOCK_ADDR_LEN_VALID(namelen) && - IS_SOCK_ADDR_TYPE_VALID_OR_UNSPEC(name) && IS_SOCK_ADDR_ALIGNED(name), - sock_set_errno(sock, err_to_errno(ERR_ARG)); return -1;); - - SOCKADDR_TO_IPADDR_PORT(name, &remote_addr, remote_port); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d, addr=", s)); - ip_addr_debug_print_val(SOCKETS_DEBUG, remote_addr); - LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F")\n", remote_port)); - -#if LWIP_IPV4 && LWIP_IPV6 - /* Dual-stack: Unmap IPv4 mapped IPv6 addresses */ - if (IP_IS_V6_VAL(remote_addr) && ip6_addr_isipv4mappedipv6(ip_2_ip6(&remote_addr))) { - unmap_ipv4_mapped_ipv6(ip_2_ip4(&remote_addr), ip_2_ip6(&remote_addr)); - IP_SET_TYPE_VAL(remote_addr, IPADDR_TYPE_V4); - } -#endif /* LWIP_IPV4 && LWIP_IPV6 */ - - err = netconn_connect(sock->conn, &remote_addr, remote_port); - } - - if (err != ERR_OK) { - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d) failed, err=%d\n", s, err)); - sock_set_errno(sock, err_to_errno(err)); - return -1; - } - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_connect(%d) succeeded\n", s)); - sock_set_errno(sock, 0); - return 0; -} - -/** - * Set a socket into listen mode. - * The socket may not have been used for another connection previously. - * - * @param s the socket to set to listening mode - * @param backlog (ATTENTION: needs TCP_LISTEN_BACKLOG=1) - * @return 0 on success, non-zero on failure - */ -int -lwip_listen(int s, int backlog) -{ - struct lwip_sock *sock; - err_t err; - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_listen(%d, backlog=%d)\n", s, backlog)); - - sock = get_socket(s); - if (!sock) { - return -1; - } - - /* limit the "backlog" parameter to fit in an u8_t */ - backlog = LWIP_MIN(LWIP_MAX(backlog, 0), 0xff); - - err = netconn_listen_with_backlog(sock->conn, (u8_t)backlog); - - if (err != ERR_OK) { - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_listen(%d) failed, err=%d\n", s, err)); - if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_TCP) { - sock_set_errno(sock, EOPNOTSUPP); - return -1; - } - sock_set_errno(sock, err_to_errno(err)); - return -1; - } - - sock_set_errno(sock, 0); - return 0; -} - -int -lwip_recvfrom(int s, void *mem, size_t len, int flags, - struct sockaddr *from, socklen_t *fromlen) -{ - struct lwip_sock *sock; - void *buf = NULL; - struct pbuf *p; - u16_t buflen, copylen; - int off = 0; - u8_t done = 0; - err_t err; - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d, %p, %"SZT_F", 0x%x, ..)\n", s, mem, len, flags)); - sock = get_socket(s); - if (!sock) { - return -1; - } - - do { - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom: top while sock->lastdata=%p\n", sock->lastdata)); - /* Check if there is data left from the last recv operation. */ - if (sock->lastdata) { - buf = sock->lastdata; - } else { - /* If this is non-blocking call, then check first */ - if (((flags & MSG_DONTWAIT) || netconn_is_nonblocking(sock->conn)) && - (sock->rcvevent <= 0)) { - if (off > 0) { - /* already received data, return that */ - sock_set_errno(sock, 0); - return off; - } - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): returning EWOULDBLOCK\n", s)); - set_errno(EWOULDBLOCK); - return -1; - } - - /* No data was left from the previous operation, so we try to get - some from the network. */ - if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP) { - err = netconn_recv_tcp_pbuf(sock->conn, (struct pbuf **)&buf); - } else { - err = netconn_recv(sock->conn, (struct netbuf **)&buf); - } - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom: netconn_recv err=%d, netbuf=%p\n", - err, buf)); - - if (err != ERR_OK) { - if (off > 0) { - if (err == ERR_CLSD) { - /* closed but already received data, ensure select gets the FIN, too */ - event_callback(sock->conn, NETCONN_EVT_RCVPLUS, 0); - } - /* already received data, return that */ - sock_set_errno(sock, 0); - return off; - } - /* We should really do some error checking here. */ - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): buf == NULL, error is \"%s\"!\n", - s, lwip_strerr(err))); - sock_set_errno(sock, err_to_errno(err)); - if (err == ERR_CLSD) { - return 0; - } else { - return -1; - } - } - LWIP_ASSERT("buf != NULL", buf != NULL); - sock->lastdata = buf; - } - - if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP) { - p = (struct pbuf *)buf; - } else { - p = ((struct netbuf *)buf)->p; - } - buflen = p->tot_len; - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom: buflen=%"U16_F" len=%"SZT_F" off=%d sock->lastoffset=%"U16_F"\n", - buflen, len, off, sock->lastoffset)); - - buflen -= sock->lastoffset; - - if (len > buflen) { - copylen = buflen; - } else { - copylen = (u16_t)len; - } - - /* copy the contents of the received buffer into - the supplied memory pointer mem */ - pbuf_copy_partial(p, (u8_t*)mem + off, copylen, sock->lastoffset); - - off += copylen; - - if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP) { - LWIP_ASSERT("invalid copylen, len would underflow", len >= copylen); - len -= copylen; - if ((len <= 0) || - (p->flags & PBUF_FLAG_PUSH) || - (sock->rcvevent <= 0) || - ((flags & MSG_PEEK) != 0)) { - done = 1; - } - } else { - done = 1; - } - - /* Check to see from where the data was.*/ - if (done) { -#if !SOCKETS_DEBUG - if (from && fromlen) -#endif /* !SOCKETS_DEBUG */ - { - u16_t port; - ip_addr_t tmpaddr; - ip_addr_t *fromaddr; - union sockaddr_aligned saddr; - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom(%d): addr=", s)); - if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP) { - fromaddr = &tmpaddr; - netconn_getaddr(sock->conn, fromaddr, &port, 0); - } else { - port = netbuf_fromport((struct netbuf *)buf); - fromaddr = netbuf_fromaddr((struct netbuf *)buf); - } - -#if LWIP_IPV4 && LWIP_IPV6 - /* Dual-stack: Map IPv4 addresses to IPv4 mapped IPv6 */ - if (NETCONNTYPE_ISIPV6(netconn_type(sock->conn)) && IP_IS_V4(fromaddr)) { - ip4_2_ipv4_mapped_ipv6(ip_2_ip6(fromaddr), ip_2_ip4(fromaddr)); - IP_SET_TYPE(fromaddr, IPADDR_TYPE_V6); - } -#endif /* LWIP_IPV4 && LWIP_IPV6 */ - - IPADDR_PORT_TO_SOCKADDR(&saddr, fromaddr, port); - ip_addr_debug_print(SOCKETS_DEBUG, fromaddr); - LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F" len=%d\n", port, off)); -#if SOCKETS_DEBUG - if (from && fromlen) -#endif /* SOCKETS_DEBUG */ - { - if (*fromlen > saddr.sa.sa_len) { - *fromlen = saddr.sa.sa_len; - } - MEMCPY(from, &saddr, *fromlen); - } - } - } - - /* If we don't peek the incoming message... */ - if ((flags & MSG_PEEK) == 0) { - /* If this is a TCP socket, check if there is data left in the - buffer. If so, it should be saved in the sock structure for next - time around. */ - if ((NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP) && (buflen - copylen > 0)) { - sock->lastdata = buf; - sock->lastoffset += copylen; - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom: lastdata now netbuf=%p\n", buf)); - } else { - sock->lastdata = NULL; - sock->lastoffset = 0; - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_recvfrom: deleting netbuf=%p\n", buf)); - if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP) { - pbuf_free((struct pbuf *)buf); - } else { - netbuf_delete((struct netbuf *)buf); - } - buf = NULL; - } - } - } while (!done); - - sock_set_errno(sock, 0); - return off; -} - -int -lwip_read(int s, void *mem, size_t len) -{ - return lwip_recvfrom(s, mem, len, 0, NULL, NULL); -} - -int -lwip_recv(int s, void *mem, size_t len, int flags) -{ - return lwip_recvfrom(s, mem, len, flags, NULL, NULL); -} - -int -lwip_send(int s, const void *data, size_t size, int flags) -{ - struct lwip_sock *sock; - err_t err; - u8_t write_flags; - size_t written; - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d, data=%p, size=%"SZT_F", flags=0x%x)\n", - s, data, size, flags)); - - sock = get_socket(s); - if (!sock) { - return -1; - } - - if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_TCP) { -#if (LWIP_UDP || LWIP_RAW) - return lwip_sendto(s, data, size, flags, NULL, 0); -#else /* (LWIP_UDP || LWIP_RAW) */ - sock_set_errno(sock, err_to_errno(ERR_ARG)); - return -1; -#endif /* (LWIP_UDP || LWIP_RAW) */ - } - - write_flags = NETCONN_COPY | - ((flags & MSG_MORE) ? NETCONN_MORE : 0) | - ((flags & MSG_DONTWAIT) ? NETCONN_DONTBLOCK : 0); - written = 0; - err = netconn_write_partly(sock->conn, data, size, write_flags, &written); - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_send(%d) err=%d written=%"SZT_F"\n", s, err, written)); - sock_set_errno(sock, err_to_errno(err)); - return (err == ERR_OK ? (int)written : -1); -} - -int -lwip_sendmsg(int s, const struct msghdr *msg, int flags) -{ - struct lwip_sock *sock; - int i; -#if LWIP_TCP - u8_t write_flags; - size_t written; -#endif - int size = 0; - err_t err = ERR_OK; - - sock = get_socket(s); - if (!sock) { - return -1; - } - - LWIP_ERROR("lwip_sendmsg: invalid msghdr", msg != NULL, - sock_set_errno(sock, err_to_errno(ERR_ARG)); return -1;); - - LWIP_UNUSED_ARG(msg->msg_control); - LWIP_UNUSED_ARG(msg->msg_controllen); - LWIP_UNUSED_ARG(msg->msg_flags); - LWIP_ERROR("lwip_sendmsg: invalid msghdr iov", (msg->msg_iov != NULL && msg->msg_iovlen != 0), - sock_set_errno(sock, err_to_errno(ERR_ARG)); return -1;); - - if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP) { -#if LWIP_TCP - write_flags = NETCONN_COPY | - ((flags & MSG_MORE) ? NETCONN_MORE : 0) | - ((flags & MSG_DONTWAIT) ? NETCONN_DONTBLOCK : 0); - - for (i = 0; i < msg->msg_iovlen; i++) { - u8_t apiflags = write_flags; - if (i + 1 < msg->msg_iovlen) { - apiflags |= NETCONN_MORE; - } - written = 0; - err = netconn_write_partly(sock->conn, msg->msg_iov[i].iov_base, msg->msg_iov[i].iov_len, write_flags, &written); - if (err == ERR_OK) { - size += written; - /* check that the entire IO vector was accepected, if not return a partial write */ - if (written != msg->msg_iov[i].iov_len) - break; - } - /* none of this IO vector was accepted, but previous was, return partial write and conceal ERR_WOULDBLOCK */ - else if (err == ERR_WOULDBLOCK && size > 0) { - err = ERR_OK; - /* let ERR_WOULDBLOCK persist on the netconn since we are returning ERR_OK */ - break; - } else { - size = -1; - break; - } - } - sock_set_errno(sock, err_to_errno(err)); - return size; -#else /* LWIP_TCP */ - sock_set_errno(sock, err_to_errno(ERR_ARG)); - return -1; -#endif /* LWIP_TCP */ - } - /* else, UDP and RAW NETCONNs */ -#if LWIP_UDP || LWIP_RAW - { - struct netbuf *chain_buf; - - LWIP_UNUSED_ARG(flags); - LWIP_ERROR("lwip_sendmsg: invalid msghdr name", (((msg->msg_name == NULL) && (msg->msg_namelen == 0)) || - IS_SOCK_ADDR_LEN_VALID(msg->msg_namelen)) , - sock_set_errno(sock, err_to_errno(ERR_ARG)); return -1;); - - /* initialize chain buffer with destination */ - chain_buf = netbuf_new(); - if (!chain_buf) { - sock_set_errno(sock, err_to_errno(ERR_MEM)); - return -1; - } - if (msg->msg_name) { - u16_t remote_port; - SOCKADDR_TO_IPADDR_PORT((const struct sockaddr *)msg->msg_name, &chain_buf->addr, remote_port); - netbuf_fromport(chain_buf) = remote_port; - } -#if LWIP_NETIF_TX_SINGLE_PBUF - for (i = 0; i < msg->msg_iovlen; i++) { - size += msg->msg_iov[i].iov_len; - } - /* Allocate a new netbuf and copy the data into it. */ - if (netbuf_alloc(chain_buf, (u16_t)size) == NULL) { - err = ERR_MEM; - } else { - /* flatten the IO vectors */ - size_t offset = 0; - for (i = 0; i < msg->msg_iovlen; i++) { - MEMCPY(&((u8_t*)chain_buf->p->payload)[offset], msg->msg_iov[i].iov_base, msg->msg_iov[i].iov_len); - offset += msg->msg_iov[i].iov_len; - } -#if LWIP_CHECKSUM_ON_COPY - { - /* This can be improved by using LWIP_CHKSUM_COPY() and aggregating the checksum for each IO vector */ - u16_t chksum = ~inet_chksum_pbuf(chain_buf->p); - netbuf_set_chksum(chain_buf, chksum); - } -#endif /* LWIP_CHECKSUM_ON_COPY */ - err = ERR_OK; - } -#else /* LWIP_NETIF_TX_SINGLE_PBUF */ - /* create a chained netbuf from the IO vectors. NOTE: we assemble a pbuf chain - manually to avoid having to allocate, chain, and delete a netbuf for each iov */ - for (i = 0; i < msg->msg_iovlen; i++) { - struct pbuf *p = pbuf_alloc(PBUF_TRANSPORT, 0, PBUF_REF); - if (p == NULL) { - err = ERR_MEM; /* let netbuf_delete() cleanup chain_buf */ - break; - } - p->payload = msg->msg_iov[i].iov_base; - LWIP_ASSERT("iov_len < u16_t", msg->msg_iov[i].iov_len <= 0xFFFF); - p->len = p->tot_len = (u16_t)msg->msg_iov[i].iov_len; - /* netbuf empty, add new pbuf */ - if (chain_buf->p == NULL) { - chain_buf->p = chain_buf->ptr = p; - /* add pbuf to existing pbuf chain */ - } else { - pbuf_cat(chain_buf->p, p); - } - } - /* save size of total chain */ - if (err == ERR_OK) { - size = netbuf_len(chain_buf); - } -#endif /* LWIP_NETIF_TX_SINGLE_PBUF */ - - if (err == ERR_OK) { -#if LWIP_IPV4 && LWIP_IPV6 - /* Dual-stack: Unmap IPv4 mapped IPv6 addresses */ - if (IP_IS_V6_VAL(chain_buf->addr) && ip6_addr_isipv4mappedipv6(ip_2_ip6(&chain_buf->addr))) { - unmap_ipv4_mapped_ipv6(ip_2_ip4(&chain_buf->addr), ip_2_ip6(&chain_buf->addr)); - IP_SET_TYPE_VAL(chain_buf->addr, IPADDR_TYPE_V4); - } -#endif /* LWIP_IPV4 && LWIP_IPV6 */ - - /* send the data */ - err = netconn_send(sock->conn, chain_buf); - } - - /* deallocated the buffer */ - netbuf_delete(chain_buf); - - sock_set_errno(sock, err_to_errno(err)); - return (err == ERR_OK ? size : -1); - } -#else /* LWIP_UDP || LWIP_RAW */ - sock_set_errno(sock, err_to_errno(ERR_ARG)); - return -1; -#endif /* LWIP_UDP || LWIP_RAW */ -} - -int -lwip_sendto(int s, const void *data, size_t size, int flags, - const struct sockaddr *to, socklen_t tolen) -{ - struct lwip_sock *sock; - err_t err; - u16_t short_size; - u16_t remote_port; - struct netbuf buf; - - sock = get_socket(s); - if (!sock) { - return -1; - } - - if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) == NETCONN_TCP) { -#if LWIP_TCP - return lwip_send(s, data, size, flags); -#else /* LWIP_TCP */ - LWIP_UNUSED_ARG(flags); - sock_set_errno(sock, err_to_errno(ERR_ARG)); - return -1; -#endif /* LWIP_TCP */ - } - - /* @todo: split into multiple sendto's? */ - LWIP_ASSERT("lwip_sendto: size must fit in u16_t", size <= 0xffff); - short_size = (u16_t)size; - LWIP_ERROR("lwip_sendto: invalid address", (((to == NULL) && (tolen == 0)) || - (IS_SOCK_ADDR_LEN_VALID(tolen) && - IS_SOCK_ADDR_TYPE_VALID(to) && IS_SOCK_ADDR_ALIGNED(to))), - sock_set_errno(sock, err_to_errno(ERR_ARG)); return -1;); - LWIP_UNUSED_ARG(tolen); - - /* initialize a buffer */ - buf.p = buf.ptr = NULL; -#if LWIP_CHECKSUM_ON_COPY - buf.flags = 0; -#endif /* LWIP_CHECKSUM_ON_COPY */ - if (to) { - SOCKADDR_TO_IPADDR_PORT(to, &buf.addr, remote_port); - } else { - remote_port = 0; - ip_addr_set_any(NETCONNTYPE_ISIPV6(netconn_type(sock->conn)), &buf.addr); - } - netbuf_fromport(&buf) = remote_port; - - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_sendto(%d, data=%p, short_size=%"U16_F", flags=0x%x to=", - s, data, short_size, flags)); - ip_addr_debug_print(SOCKETS_DEBUG, &buf.addr); - LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F"\n", remote_port)); - - /* make the buffer point to the data that should be sent */ -#if LWIP_NETIF_TX_SINGLE_PBUF - /* Allocate a new netbuf and copy the data into it. */ - if (netbuf_alloc(&buf, short_size) == NULL) { - err = ERR_MEM; - } else { -#if LWIP_CHECKSUM_ON_COPY - if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_RAW) { - u16_t chksum = LWIP_CHKSUM_COPY(buf.p->payload, data, short_size); - netbuf_set_chksum(&buf, chksum); - } else -#endif /* LWIP_CHECKSUM_ON_COPY */ - { - MEMCPY(buf.p->payload, data, short_size); - } - err = ERR_OK; - } -#else /* LWIP_NETIF_TX_SINGLE_PBUF */ - err = netbuf_ref(&buf, data, short_size); -#endif /* LWIP_NETIF_TX_SINGLE_PBUF */ - if (err == ERR_OK) { -#if LWIP_IPV4 && LWIP_IPV6 - /* Dual-stack: Unmap IPv4 mapped IPv6 addresses */ - if (IP_IS_V6_VAL(buf.addr) && ip6_addr_isipv4mappedipv6(ip_2_ip6(&buf.addr))) { - unmap_ipv4_mapped_ipv6(ip_2_ip4(&buf.addr), ip_2_ip6(&buf.addr)); - IP_SET_TYPE_VAL(buf.addr, IPADDR_TYPE_V4); - } -#endif /* LWIP_IPV4 && LWIP_IPV6 */ - - /* send the data */ - err = netconn_send(sock->conn, &buf); - } - - /* deallocated the buffer */ - netbuf_free(&buf); - - sock_set_errno(sock, err_to_errno(err)); - return (err == ERR_OK ? short_size : -1); -} - -int -lwip_socket(int domain, int type, int protocol) -{ - struct netconn *conn; - int i; - - LWIP_UNUSED_ARG(domain); /* @todo: check this */ - - /* create a netconn */ - switch (type) { - case SOCK_RAW: - conn = netconn_new_with_proto_and_callback(DOMAIN_TO_NETCONN_TYPE(domain, NETCONN_RAW), - (u8_t)protocol, event_callback); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%s, SOCK_RAW, %d) = ", - domain == PF_INET ? "PF_INET" : "UNKNOWN", protocol)); - break; - case SOCK_DGRAM: - conn = netconn_new_with_callback(DOMAIN_TO_NETCONN_TYPE(domain, - ((protocol == IPPROTO_UDPLITE) ? NETCONN_UDPLITE : NETCONN_UDP)) , - event_callback); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%s, SOCK_DGRAM, %d) = ", - domain == PF_INET ? "PF_INET" : "UNKNOWN", protocol)); - break; - case SOCK_STREAM: - conn = netconn_new_with_callback(DOMAIN_TO_NETCONN_TYPE(domain, NETCONN_TCP), event_callback); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%s, SOCK_STREAM, %d) = ", - domain == PF_INET ? "PF_INET" : "UNKNOWN", protocol)); - break; - default: - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_socket(%d, %d/UNKNOWN, %d) = -1\n", - domain, type, protocol)); - set_errno(EINVAL); - return -1; - } - - if (!conn) { - LWIP_DEBUGF(SOCKETS_DEBUG, ("-1 / ENOBUFS (could not create netconn)\n")); - set_errno(ENOBUFS); - return -1; - } - - i = alloc_socket(conn, 0); - - if (i == -1) { - netconn_delete(conn); - set_errno(ENFILE); - return -1; - } - conn->socket = i; - LWIP_DEBUGF(SOCKETS_DEBUG, ("%d\n", i)); - set_errno(0); - return i; -} - -int -lwip_write(int s, const void *data, size_t size) -{ - return lwip_send(s, data, size, 0); -} - -int -lwip_writev(int s, const struct iovec *iov, int iovcnt) -{ - struct msghdr msg; - - msg.msg_name = NULL; - msg.msg_namelen = 0; - /* Hack: we have to cast via number to cast from 'const' pointer to non-const. - Blame the opengroup standard for this inconsistency. */ - msg.msg_iov = LWIP_CONST_CAST(struct iovec *, iov); - msg.msg_iovlen = iovcnt; - msg.msg_control = NULL; - msg.msg_controllen = 0; - msg.msg_flags = 0; - return lwip_sendmsg(s, &msg, 0); -} - -/** - * Go through the readset and writeset lists and see which socket of the sockets - * set in the sets has events. On return, readset, writeset and exceptset have - * the sockets enabled that had events. - * - * @param maxfdp1 the highest socket index in the sets - * @param readset_in set of sockets to check for read events - * @param writeset_in set of sockets to check for write events - * @param exceptset_in set of sockets to check for error events - * @param readset_out set of sockets that had read events - * @param writeset_out set of sockets that had write events - * @param exceptset_out set os sockets that had error events - * @return number of sockets that had events (read/write/exception) (>= 0) - */ -static int -lwip_selscan(int maxfdp1, fd_set *readset_in, fd_set *writeset_in, fd_set *exceptset_in, - fd_set *readset_out, fd_set *writeset_out, fd_set *exceptset_out) -{ - int i, nready = 0; - fd_set lreadset, lwriteset, lexceptset; - struct lwip_sock *sock; - SYS_ARCH_DECL_PROTECT(lev); - - FD_ZERO(&lreadset); - FD_ZERO(&lwriteset); - FD_ZERO(&lexceptset); - - /* Go through each socket in each list to count number of sockets which - currently match */ - for (i = LWIP_SOCKET_OFFSET; i < maxfdp1; i++) { - /* if this FD is not in the set, continue */ - if (!(readset_in && FD_ISSET(i, readset_in)) && - !(writeset_in && FD_ISSET(i, writeset_in)) && - !(exceptset_in && FD_ISSET(i, exceptset_in))) { - continue; - } - /* First get the socket's status (protected)... */ - SYS_ARCH_PROTECT(lev); - sock = tryget_socket(i); - if (sock != NULL) { - void* lastdata = sock->lastdata; - s16_t rcvevent = sock->rcvevent; - u16_t sendevent = sock->sendevent; - u16_t errevent = sock->errevent; - SYS_ARCH_UNPROTECT(lev); - - /* ... then examine it: */ - /* See if netconn of this socket is ready for read */ - if (readset_in && FD_ISSET(i, readset_in) && ((lastdata != NULL) || (rcvevent > 0))) { - FD_SET(i, &lreadset); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_selscan: fd=%d ready for reading\n", i)); - nready++; - } - /* See if netconn of this socket is ready for write */ - if (writeset_in && FD_ISSET(i, writeset_in) && (sendevent != 0)) { - FD_SET(i, &lwriteset); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_selscan: fd=%d ready for writing\n", i)); - nready++; - } - /* See if netconn of this socket had an error */ - if (exceptset_in && FD_ISSET(i, exceptset_in) && (errevent != 0)) { - FD_SET(i, &lexceptset); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_selscan: fd=%d ready for exception\n", i)); - nready++; - } - } else { - SYS_ARCH_UNPROTECT(lev); - /* continue on to next FD in list */ - } - } - /* copy local sets to the ones provided as arguments */ - *readset_out = lreadset; - *writeset_out = lwriteset; - *exceptset_out = lexceptset; - - LWIP_ASSERT("nready >= 0", nready >= 0); - return nready; -} - -int -lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset, - struct timeval *timeout) -{ - u32_t waitres = 0; - int nready; - fd_set lreadset, lwriteset, lexceptset; - u32_t msectimeout; - struct lwip_select_cb select_cb; - int i; - int maxfdp2; -#if LWIP_NETCONN_SEM_PER_THREAD - int waited = 0; -#endif - SYS_ARCH_DECL_PROTECT(lev); - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select(%d, %p, %p, %p, tvsec=%"S32_F" tvusec=%"S32_F")\n", - maxfdp1, (void *)readset, (void *) writeset, (void *) exceptset, - timeout ? (s32_t)timeout->tv_sec : (s32_t)-1, - timeout ? (s32_t)timeout->tv_usec : (s32_t)-1)); - - /* Go through each socket in each list to count number of sockets which - currently match */ - nready = lwip_selscan(maxfdp1, readset, writeset, exceptset, &lreadset, &lwriteset, &lexceptset); - - /* If we don't have any current events, then suspend if we are supposed to */ - if (!nready) { - if (timeout && timeout->tv_sec == 0 && timeout->tv_usec == 0) { - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: no timeout, returning 0\n")); - /* This is OK as the local fdsets are empty and nready is zero, - or we would have returned earlier. */ - goto return_copy_fdsets; - } - - /* None ready: add our semaphore to list: - We don't actually need any dynamic memory. Our entry on the - list is only valid while we are in this function, so it's ok - to use local variables. */ - - select_cb.next = NULL; - select_cb.prev = NULL; - select_cb.readset = readset; - select_cb.writeset = writeset; - select_cb.exceptset = exceptset; - select_cb.sem_signalled = 0; -#if LWIP_NETCONN_SEM_PER_THREAD - select_cb.sem = LWIP_NETCONN_THREAD_SEM_GET(); -#else /* LWIP_NETCONN_SEM_PER_THREAD */ - if (sys_sem_new(&select_cb.sem, 0) != ERR_OK) { - /* failed to create semaphore */ - set_errno(ENOMEM); - return -1; - } -#endif /* LWIP_NETCONN_SEM_PER_THREAD */ - - /* Protect the select_cb_list */ - SYS_ARCH_PROTECT(lev); - - /* Put this select_cb on top of list */ - select_cb.next = select_cb_list; - if (select_cb_list != NULL) { - select_cb_list->prev = &select_cb; - } - select_cb_list = &select_cb; - /* Increasing this counter tells event_callback that the list has changed. */ - select_cb_ctr++; - - /* Now we can safely unprotect */ - SYS_ARCH_UNPROTECT(lev); - - /* Increase select_waiting for each socket we are interested in */ - maxfdp2 = maxfdp1; - for (i = LWIP_SOCKET_OFFSET; i < maxfdp1; i++) { - if ((readset && FD_ISSET(i, readset)) || - (writeset && FD_ISSET(i, writeset)) || - (exceptset && FD_ISSET(i, exceptset))) { - struct lwip_sock *sock; - SYS_ARCH_PROTECT(lev); - sock = tryget_socket(i); - if (sock != NULL) { - sock->select_waiting++; - LWIP_ASSERT("sock->select_waiting > 0", sock->select_waiting > 0); - } else { - /* Not a valid socket */ - nready = -1; - maxfdp2 = i; - SYS_ARCH_UNPROTECT(lev); - break; - } - SYS_ARCH_UNPROTECT(lev); - } - } - - if (nready >= 0) { - /* Call lwip_selscan again: there could have been events between - the last scan (without us on the list) and putting us on the list! */ - nready = lwip_selscan(maxfdp1, readset, writeset, exceptset, &lreadset, &lwriteset, &lexceptset); - if (!nready) { - /* Still none ready, just wait to be woken */ - if (timeout == 0) { - /* Wait forever */ - msectimeout = 0; - } else { - msectimeout = ((timeout->tv_sec * 1000) + ((timeout->tv_usec + 500)/1000)); - if (msectimeout == 0) { - /* Wait 1ms at least (0 means wait forever) */ - msectimeout = 1; - } - } - - waitres = sys_arch_sem_wait(SELECT_SEM_PTR(select_cb.sem), msectimeout); -#if LWIP_NETCONN_SEM_PER_THREAD - waited = 1; -#endif - } - } - - /* Decrease select_waiting for each socket we are interested in */ - for (i = LWIP_SOCKET_OFFSET; i < maxfdp2; i++) { - if ((readset && FD_ISSET(i, readset)) || - (writeset && FD_ISSET(i, writeset)) || - (exceptset && FD_ISSET(i, exceptset))) { - struct lwip_sock *sock; - SYS_ARCH_PROTECT(lev); - sock = tryget_socket(i); - if (sock != NULL) { - /* for now, handle select_waiting==0... */ - LWIP_ASSERT("sock->select_waiting > 0", sock->select_waiting > 0); - if (sock->select_waiting > 0) { - sock->select_waiting--; - } - } else { - /* Not a valid socket */ - nready = -1; - } - SYS_ARCH_UNPROTECT(lev); - } - } - /* Take us off the list */ - SYS_ARCH_PROTECT(lev); - if (select_cb.next != NULL) { - select_cb.next->prev = select_cb.prev; - } - if (select_cb_list == &select_cb) { - LWIP_ASSERT("select_cb.prev == NULL", select_cb.prev == NULL); - select_cb_list = select_cb.next; - } else { - LWIP_ASSERT("select_cb.prev != NULL", select_cb.prev != NULL); - select_cb.prev->next = select_cb.next; - } - /* Increasing this counter tells event_callback that the list has changed. */ - select_cb_ctr++; - SYS_ARCH_UNPROTECT(lev); - -#if LWIP_NETCONN_SEM_PER_THREAD - if (select_cb.sem_signalled && (!waited || (waitres == SYS_ARCH_TIMEOUT))) { - /* don't leave the thread-local semaphore signalled */ - sys_arch_sem_wait(select_cb.sem, 1); - } -#else /* LWIP_NETCONN_SEM_PER_THREAD */ - sys_sem_free(&select_cb.sem); -#endif /* LWIP_NETCONN_SEM_PER_THREAD */ - - if (nready < 0) { - /* This happens when a socket got closed while waiting */ - set_errno(EBADF); - return -1; - } - - if (waitres == SYS_ARCH_TIMEOUT) { - /* Timeout */ - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: timeout expired\n")); - /* This is OK as the local fdsets are empty and nready is zero, - or we would have returned earlier. */ - goto return_copy_fdsets; - } - - /* See what's set */ - nready = lwip_selscan(maxfdp1, readset, writeset, exceptset, &lreadset, &lwriteset, &lexceptset); - } - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_select: nready=%d\n", nready)); -return_copy_fdsets: - set_errno(0); - if (readset) { - *readset = lreadset; - } - if (writeset) { - *writeset = lwriteset; - } - if (exceptset) { - *exceptset = lexceptset; - } - return nready; -} - -/** - * Callback registered in the netconn layer for each socket-netconn. - * Processes recvevent (data available) and wakes up tasks waiting for select. - */ -static void -event_callback(struct netconn *conn, enum netconn_evt evt, u16_t len) -{ - int s; - struct lwip_sock *sock; - struct lwip_select_cb *scb; - int last_select_cb_ctr; - SYS_ARCH_DECL_PROTECT(lev); - - LWIP_UNUSED_ARG(len); - - /* Get socket */ - if (conn) { - s = conn->socket; - if (s < 0) { - /* Data comes in right away after an accept, even though - * the server task might not have created a new socket yet. - * Just count down (or up) if that's the case and we - * will use the data later. Note that only receive events - * can happen before the new socket is set up. */ - SYS_ARCH_PROTECT(lev); - if (conn->socket < 0) { - if (evt == NETCONN_EVT_RCVPLUS) { - conn->socket--; - } - SYS_ARCH_UNPROTECT(lev); - return; - } - s = conn->socket; - SYS_ARCH_UNPROTECT(lev); - } - - sock = get_socket(s); - if (!sock) { - return; - } - } else { - return; - } - - SYS_ARCH_PROTECT(lev); - /* Set event as required */ - switch (evt) { - case NETCONN_EVT_RCVPLUS: - sock->rcvevent++; - break; - case NETCONN_EVT_RCVMINUS: - sock->rcvevent--; - break; - case NETCONN_EVT_SENDPLUS: - sock->sendevent = 1; - break; - case NETCONN_EVT_SENDMINUS: - sock->sendevent = 0; - break; - case NETCONN_EVT_ERROR: - sock->errevent = 1; - break; - default: - LWIP_ASSERT("unknown event", 0); - break; - } - - if (sock->select_waiting == 0) { - /* noone is waiting for this socket, no need to check select_cb_list */ - SYS_ARCH_UNPROTECT(lev); - return; - } - - /* Now decide if anyone is waiting for this socket */ - /* NOTE: This code goes through the select_cb_list list multiple times - ONLY IF a select was actually waiting. We go through the list the number - of waiting select calls + 1. This list is expected to be small. */ - - /* At this point, SYS_ARCH is still protected! */ -again: - for (scb = select_cb_list; scb != NULL; scb = scb->next) { - /* remember the state of select_cb_list to detect changes */ - last_select_cb_ctr = select_cb_ctr; - if (scb->sem_signalled == 0) { - /* semaphore not signalled yet */ - int do_signal = 0; - /* Test this select call for our socket */ - if (sock->rcvevent > 0) { - if (scb->readset && FD_ISSET(s, scb->readset)) { - do_signal = 1; - } - } - if (sock->sendevent != 0) { - if (!do_signal && scb->writeset && FD_ISSET(s, scb->writeset)) { - do_signal = 1; - } - } - if (sock->errevent != 0) { - if (!do_signal && scb->exceptset && FD_ISSET(s, scb->exceptset)) { - do_signal = 1; - } - } - if (do_signal) { - scb->sem_signalled = 1; - /* Don't call SYS_ARCH_UNPROTECT() before signaling the semaphore, as this might - lead to the select thread taking itself off the list, invalidating the semaphore. */ - sys_sem_signal(SELECT_SEM_PTR(scb->sem)); - } - } - /* unlock interrupts with each step */ - SYS_ARCH_UNPROTECT(lev); - /* this makes sure interrupt protection time is short */ - SYS_ARCH_PROTECT(lev); - if (last_select_cb_ctr != select_cb_ctr) { - /* someone has changed select_cb_list, restart at the beginning */ - goto again; - } - } - SYS_ARCH_UNPROTECT(lev); -} - -/** - * Close one end of a full-duplex connection. - */ -int -lwip_shutdown(int s, int how) -{ - struct lwip_sock *sock; - err_t err; - u8_t shut_rx = 0, shut_tx = 0; - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_shutdown(%d, how=%d)\n", s, how)); - - sock = get_socket(s); - if (!sock) { - return -1; - } - - if (sock->conn != NULL) { - if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_TCP) { - sock_set_errno(sock, EOPNOTSUPP); - return -1; - } - } else { - sock_set_errno(sock, ENOTCONN); - return -1; - } - - if (how == SHUT_RD) { - shut_rx = 1; - } else if (how == SHUT_WR) { - shut_tx = 1; - } else if (how == SHUT_RDWR) { - shut_rx = 1; - shut_tx = 1; - } else { - sock_set_errno(sock, EINVAL); - return -1; - } - err = netconn_shutdown(sock->conn, shut_rx, shut_tx); - - sock_set_errno(sock, err_to_errno(err)); - return (err == ERR_OK ? 0 : -1); -} - -static int -lwip_getaddrname(int s, struct sockaddr *name, socklen_t *namelen, u8_t local) -{ - struct lwip_sock *sock; - union sockaddr_aligned saddr; - ip_addr_t naddr; - u16_t port; - err_t err; - - sock = get_socket(s); - if (!sock) { - return -1; - } - - /* get the IP address and port */ - err = netconn_getaddr(sock->conn, &naddr, &port, local); - if (err != ERR_OK) { - sock_set_errno(sock, err_to_errno(err)); - return -1; - } - -#if LWIP_IPV4 && LWIP_IPV6 - /* Dual-stack: Map IPv4 addresses to IPv4 mapped IPv6 */ - if (NETCONNTYPE_ISIPV6(netconn_type(sock->conn)) && - IP_IS_V4_VAL(naddr)) { - ip4_2_ipv4_mapped_ipv6(ip_2_ip6(&naddr), ip_2_ip4(&naddr)); - IP_SET_TYPE_VAL(naddr, IPADDR_TYPE_V6); - } -#endif /* LWIP_IPV4 && LWIP_IPV6 */ - - IPADDR_PORT_TO_SOCKADDR(&saddr, &naddr, port); - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getaddrname(%d, addr=", s)); - ip_addr_debug_print_val(SOCKETS_DEBUG, naddr); - LWIP_DEBUGF(SOCKETS_DEBUG, (" port=%"U16_F")\n", port)); - - if (*namelen > saddr.sa.sa_len) { - *namelen = saddr.sa.sa_len; - } - MEMCPY(name, &saddr, *namelen); - - sock_set_errno(sock, 0); - return 0; -} - -int -lwip_getpeername(int s, struct sockaddr *name, socklen_t *namelen) -{ - return lwip_getaddrname(s, name, namelen, 0); -} - -int -lwip_getsockname(int s, struct sockaddr *name, socklen_t *namelen) -{ - return lwip_getaddrname(s, name, namelen, 1); -} - -int -lwip_getsockopt(int s, int level, int optname, void *optval, socklen_t *optlen) -{ - u8_t err; - struct lwip_sock *sock = get_socket(s); -#if !LWIP_TCPIP_CORE_LOCKING - LWIP_SETGETSOCKOPT_DATA_VAR_DECLARE(data); -#endif /* !LWIP_TCPIP_CORE_LOCKING */ - - if (!sock) { - return -1; - } - - if ((NULL == optval) || (NULL == optlen)) { - sock_set_errno(sock, EFAULT); - return -1; - } - -#if LWIP_TCPIP_CORE_LOCKING - /* core-locking can just call the -impl function */ - LOCK_TCPIP_CORE(); - err = lwip_getsockopt_impl(s, level, optname, optval, optlen); - UNLOCK_TCPIP_CORE(); - -#else /* LWIP_TCPIP_CORE_LOCKING */ - -#if LWIP_MPU_COMPATIBLE - /* MPU_COMPATIBLE copies the optval data, so check for max size here */ - if (*optlen > LWIP_SETGETSOCKOPT_MAXOPTLEN) { - sock_set_errno(sock, ENOBUFS); - return -1; - } -#endif /* LWIP_MPU_COMPATIBLE */ - - LWIP_SETGETSOCKOPT_DATA_VAR_ALLOC(data, sock); - LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).s = s; - LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).level = level; - LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optname = optname; - LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optlen = *optlen; -#if !LWIP_MPU_COMPATIBLE - LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optval.p = optval; -#endif /* !LWIP_MPU_COMPATIBLE */ - LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).err = 0; -#if LWIP_NETCONN_SEM_PER_THREAD - LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).completed_sem = LWIP_NETCONN_THREAD_SEM_GET(); -#else - LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).completed_sem = &sock->conn->op_completed; -#endif - err = tcpip_callback(lwip_getsockopt_callback, &LWIP_SETGETSOCKOPT_DATA_VAR_REF(data)); - if (err != ERR_OK) { - LWIP_SETGETSOCKOPT_DATA_VAR_FREE(data); - sock_set_errno(sock, err_to_errno(err)); - return -1; - } - sys_arch_sem_wait((sys_sem_t*)(LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).completed_sem), 0); - - /* write back optlen and optval */ - *optlen = LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optlen; -#if LWIP_MPU_COMPATIBLE - MEMCPY(optval, LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optval, - LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optlen); -#endif /* LWIP_MPU_COMPATIBLE */ - - /* maybe lwip_getsockopt_internal has changed err */ - err = LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).err; - LWIP_SETGETSOCKOPT_DATA_VAR_FREE(data); -#endif /* LWIP_TCPIP_CORE_LOCKING */ - - sock_set_errno(sock, err); - return err ? -1 : 0; -} - -#if !LWIP_TCPIP_CORE_LOCKING -/** lwip_getsockopt_callback: only used without CORE_LOCKING - * to get into the tcpip_thread - */ -static void -lwip_getsockopt_callback(void *arg) -{ - struct lwip_setgetsockopt_data *data; - LWIP_ASSERT("arg != NULL", arg != NULL); - data = (struct lwip_setgetsockopt_data*)arg; - - data->err = lwip_getsockopt_impl(data->s, data->level, data->optname, -#if LWIP_MPU_COMPATIBLE - data->optval, -#else /* LWIP_MPU_COMPATIBLE */ - data->optval.p, -#endif /* LWIP_MPU_COMPATIBLE */ - &data->optlen); - - sys_sem_signal((sys_sem_t*)(data->completed_sem)); -} -#endif /* LWIP_TCPIP_CORE_LOCKING */ - -/** lwip_getsockopt_impl: the actual implementation of getsockopt: - * same argument as lwip_getsockopt, either called directly or through callback - */ -static u8_t -lwip_getsockopt_impl(int s, int level, int optname, void *optval, socklen_t *optlen) -{ - u8_t err = 0; - struct lwip_sock *sock = tryget_socket(s); - if (!sock) { - return EBADF; - } - - switch (level) { - -/* Level: SOL_SOCKET */ - case SOL_SOCKET: - switch (optname) { - -#if LWIP_TCP - case SO_ACCEPTCONN: - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen, int); - if (NETCONNTYPE_GROUP(sock->conn->type) != NETCONN_TCP) { - return ENOPROTOOPT; - } - if ((sock->conn->pcb.tcp != NULL) && (sock->conn->pcb.tcp->state == LISTEN)) { - *(int*)optval = 1; - } else { - *(int*)optval = 0; - } - break; -#endif /* LWIP_TCP */ - - /* The option flags */ - case SO_BROADCAST: - case SO_KEEPALIVE: -#if SO_REUSE - case SO_REUSEADDR: -#endif /* SO_REUSE */ - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen, int); - *(int*)optval = ip_get_option(sock->conn->pcb.ip, optname); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, optname=0x%x, ..) = %s\n", - s, optname, (*(int*)optval?"on":"off"))); - break; - - case SO_TYPE: - LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, *optlen, int); - switch (NETCONNTYPE_GROUP(netconn_type(sock->conn))) { - case NETCONN_RAW: - *(int*)optval = SOCK_RAW; - break; - case NETCONN_TCP: - *(int*)optval = SOCK_STREAM; - break; - case NETCONN_UDP: - *(int*)optval = SOCK_DGRAM; - break; - default: /* unrecognized socket type */ - *(int*)optval = netconn_type(sock->conn); - LWIP_DEBUGF(SOCKETS_DEBUG, - ("lwip_getsockopt(%d, SOL_SOCKET, SO_TYPE): unrecognized socket type %d\n", - s, *(int *)optval)); - } /* switch (netconn_type(sock->conn)) */ - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, SO_TYPE) = %d\n", - s, *(int *)optval)); - break; - - case SO_ERROR: - LWIP_SOCKOPT_CHECK_OPTLEN(*optlen, int); - /* only overwrite ERR_OK or temporary errors */ - if (((sock->err == 0) || (sock->err == EINPROGRESS)) && (sock->conn != NULL)) { - sock_set_errno(sock, err_to_errno(sock->conn->last_err)); - } - *(int *)optval = (sock->err == 0xFF ? (int)-1 : (int)sock->err); - sock->err = 0; - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, SO_ERROR) = %d\n", - s, *(int *)optval)); - break; - -#if LWIP_SO_SNDTIMEO - case SO_SNDTIMEO: - LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, *optlen, LWIP_SO_SNDRCVTIMEO_OPTTYPE); - LWIP_SO_SNDRCVTIMEO_SET(optval, netconn_get_sendtimeout(sock->conn)); - break; -#endif /* LWIP_SO_SNDTIMEO */ -#if LWIP_SO_RCVTIMEO - case SO_RCVTIMEO: - LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, *optlen, LWIP_SO_SNDRCVTIMEO_OPTTYPE); - LWIP_SO_SNDRCVTIMEO_SET(optval, netconn_get_recvtimeout(sock->conn)); - break; -#endif /* LWIP_SO_RCVTIMEO */ -#if LWIP_SO_RCVBUF - case SO_RCVBUF: - LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, *optlen, int); - *(int *)optval = netconn_get_recvbufsize(sock->conn); - break; -#endif /* LWIP_SO_RCVBUF */ -#if LWIP_SO_LINGER - case SO_LINGER: - { - s16_t conn_linger; - struct linger* linger = (struct linger*)optval; - LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, *optlen, struct linger); - conn_linger = sock->conn->linger; - if (conn_linger >= 0) { - linger->l_onoff = 1; - linger->l_linger = (int)conn_linger; - } else { - linger->l_onoff = 0; - linger->l_linger = 0; - } - } - break; -#endif /* LWIP_SO_LINGER */ -#if LWIP_UDP - case SO_NO_CHECK: - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, *optlen, int, NETCONN_UDP); -#if LWIP_UDPLITE - if ((udp_flags(sock->conn->pcb.udp) & UDP_FLAGS_UDPLITE) != 0) { - /* this flag is only available for UDP, not for UDP lite */ - return EAFNOSUPPORT; - } -#endif /* LWIP_UDPLITE */ - *(int*)optval = (udp_flags(sock->conn->pcb.udp) & UDP_FLAGS_NOCHKSUM) ? 1 : 0; - break; -#endif /* LWIP_UDP*/ - default: - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, SOL_SOCKET, UNIMPL: optname=0x%x, ..)\n", - s, optname)); - err = ENOPROTOOPT; - break; - } /* switch (optname) */ - break; - -/* Level: IPPROTO_IP */ - case IPPROTO_IP: - switch (optname) { - case IP_TTL: - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen, int); - *(int*)optval = sock->conn->pcb.ip->ttl; - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_TTL) = %d\n", - s, *(int *)optval)); - break; - case IP_TOS: - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen, int); - *(int*)optval = sock->conn->pcb.ip->tos; - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_TOS) = %d\n", - s, *(int *)optval)); - break; -#if LWIP_IPV4 && LWIP_MULTICAST_TX_OPTIONS && LWIP_UDP - case IP_MULTICAST_TTL: - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen, u8_t); - if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_UDP) { - return ENOPROTOOPT; - } - *(u8_t*)optval = udp_get_multicast_ttl(sock->conn->pcb.udp); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_MULTICAST_TTL) = %d\n", - s, *(int *)optval)); - break; - case IP_MULTICAST_IF: - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen, struct in_addr); - if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_UDP) { - return ENOPROTOOPT; - } - inet_addr_from_ip4addr((struct in_addr*)optval, udp_get_multicast_netif_addr(sock->conn->pcb.udp)); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_MULTICAST_IF) = 0x%"X32_F"\n", - s, *(u32_t *)optval)); - break; - case IP_MULTICAST_LOOP: - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen, u8_t); - if ((sock->conn->pcb.udp->flags & UDP_FLAGS_MULTICAST_LOOP) != 0) { - *(u8_t*)optval = 1; - } else { - *(u8_t*)optval = 0; - } - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, IP_MULTICAST_LOOP) = %d\n", - s, *(int *)optval)); - break; -#endif /* LWIP_IPV4 && LWIP_MULTICAST_TX_OPTIONS && LWIP_UDP */ - default: - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IP, UNIMPL: optname=0x%x, ..)\n", - s, optname)); - err = ENOPROTOOPT; - break; - } /* switch (optname) */ - break; - -#if LWIP_TCP -/* Level: IPPROTO_TCP */ - case IPPROTO_TCP: - /* Special case: all IPPROTO_TCP option take an int */ - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, *optlen, int, NETCONN_TCP); - if (sock->conn->pcb.tcp->state == LISTEN) { - return EINVAL; - } - switch (optname) { - case TCP_NODELAY: - *(int*)optval = tcp_nagle_disabled(sock->conn->pcb.tcp); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_TCP, TCP_NODELAY) = %s\n", - s, (*(int*)optval)?"on":"off") ); - break; - case TCP_KEEPALIVE: - *(int*)optval = (int)sock->conn->pcb.tcp->keep_idle; - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_TCP, TCP_KEEPALIVE) = %d\n", - s, *(int *)optval)); - break; - -#if LWIP_TCP_KEEPALIVE - case TCP_KEEPIDLE: - *(int*)optval = (int)(sock->conn->pcb.tcp->keep_idle/1000); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_TCP, TCP_KEEPIDLE) = %d\n", - s, *(int *)optval)); - break; - case TCP_KEEPINTVL: - *(int*)optval = (int)(sock->conn->pcb.tcp->keep_intvl/1000); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_TCP, TCP_KEEPINTVL) = %d\n", - s, *(int *)optval)); - break; - case TCP_KEEPCNT: - *(int*)optval = (int)sock->conn->pcb.tcp->keep_cnt; - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_TCP, TCP_KEEPCNT) = %d\n", - s, *(int *)optval)); - break; -#endif /* LWIP_TCP_KEEPALIVE */ - default: - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_TCP, UNIMPL: optname=0x%x, ..)\n", - s, optname)); - err = ENOPROTOOPT; - break; - } /* switch (optname) */ - break; -#endif /* LWIP_TCP */ - -#if LWIP_IPV6 -/* Level: IPPROTO_IPV6 */ - case IPPROTO_IPV6: - switch (optname) { - case IPV6_V6ONLY: - LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, *optlen, int); - *(int*)optval = (netconn_get_ipv6only(sock->conn) ? 1 : 0); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IPV6, IPV6_V6ONLY) = %d\n", - s, *(int *)optval)); - break; - default: - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_IPV6, UNIMPL: optname=0x%x, ..)\n", - s, optname)); - err = ENOPROTOOPT; - break; - } /* switch (optname) */ - break; -#endif /* LWIP_IPV6 */ - -#if LWIP_UDP && LWIP_UDPLITE - /* Level: IPPROTO_UDPLITE */ - case IPPROTO_UDPLITE: - /* Special case: all IPPROTO_UDPLITE option take an int */ - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, *optlen, int); - /* If this is no UDP lite socket, ignore any options. */ - if (!NETCONNTYPE_ISUDPLITE(netconn_type(sock->conn))) { - return ENOPROTOOPT; - } - switch (optname) { - case UDPLITE_SEND_CSCOV: - *(int*)optval = sock->conn->pcb.udp->chksum_len_tx; - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_UDPLITE, UDPLITE_SEND_CSCOV) = %d\n", - s, (*(int*)optval)) ); - break; - case UDPLITE_RECV_CSCOV: - *(int*)optval = sock->conn->pcb.udp->chksum_len_rx; - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_UDPLITE, UDPLITE_RECV_CSCOV) = %d\n", - s, (*(int*)optval)) ); - break; - default: - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_UDPLITE, UNIMPL: optname=0x%x, ..)\n", - s, optname)); - err = ENOPROTOOPT; - break; - } /* switch (optname) */ - break; -#endif /* LWIP_UDP */ - /* Level: IPPROTO_RAW */ - case IPPROTO_RAW: - switch (optname) { -#if LWIP_IPV6 && LWIP_RAW - case IPV6_CHECKSUM: - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, *optlen, int, NETCONN_RAW); - if (sock->conn->pcb.raw->chksum_reqd == 0) { - *(int *)optval = -1; - } else { - *(int *)optval = sock->conn->pcb.raw->chksum_offset; - } - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_RAW, IPV6_CHECKSUM) = %d\n", - s, (*(int*)optval)) ); - break; -#endif /* LWIP_IPV6 && LWIP_RAW */ - default: - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, IPPROTO_RAW, UNIMPL: optname=0x%x, ..)\n", - s, optname)); - err = ENOPROTOOPT; - break; - } /* switch (optname) */ - break; - default: - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_getsockopt(%d, level=0x%x, UNIMPL: optname=0x%x, ..)\n", - s, level, optname)); - err = ENOPROTOOPT; - break; - } /* switch (level) */ - - return err; -} - -int -lwip_setsockopt(int s, int level, int optname, const void *optval, socklen_t optlen) -{ - u8_t err = 0; - struct lwip_sock *sock = get_socket(s); -#if !LWIP_TCPIP_CORE_LOCKING - LWIP_SETGETSOCKOPT_DATA_VAR_DECLARE(data); -#endif /* !LWIP_TCPIP_CORE_LOCKING */ - - if (!sock) { - return -1; - } - - if (NULL == optval) { - sock_set_errno(sock, EFAULT); - return -1; - } - -#if LWIP_TCPIP_CORE_LOCKING - /* core-locking can just call the -impl function */ - LOCK_TCPIP_CORE(); - err = lwip_setsockopt_impl(s, level, optname, optval, optlen); - UNLOCK_TCPIP_CORE(); - -#else /* LWIP_TCPIP_CORE_LOCKING */ - -#if LWIP_MPU_COMPATIBLE - /* MPU_COMPATIBLE copies the optval data, so check for max size here */ - if (optlen > LWIP_SETGETSOCKOPT_MAXOPTLEN) { - sock_set_errno(sock, ENOBUFS); - return -1; - } -#endif /* LWIP_MPU_COMPATIBLE */ - - LWIP_SETGETSOCKOPT_DATA_VAR_ALLOC(data, sock); - LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).s = s; - LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).level = level; - LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optname = optname; - LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optlen = optlen; -#if LWIP_MPU_COMPATIBLE - MEMCPY(LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optval, optval, optlen); -#else /* LWIP_MPU_COMPATIBLE */ - LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).optval.pc = (const void*)optval; -#endif /* LWIP_MPU_COMPATIBLE */ - LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).err = 0; -#if LWIP_NETCONN_SEM_PER_THREAD - LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).completed_sem = LWIP_NETCONN_THREAD_SEM_GET(); -#else - LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).completed_sem = &sock->conn->op_completed; -#endif - err = tcpip_callback(lwip_setsockopt_callback, &LWIP_SETGETSOCKOPT_DATA_VAR_REF(data)); - if (err != ERR_OK) { - LWIP_SETGETSOCKOPT_DATA_VAR_FREE(data); - sock_set_errno(sock, err_to_errno(err)); - return -1; - } - sys_arch_sem_wait((sys_sem_t*)(LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).completed_sem), 0); - - /* maybe lwip_getsockopt_internal has changed err */ - err = LWIP_SETGETSOCKOPT_DATA_VAR_REF(data).err; - LWIP_SETGETSOCKOPT_DATA_VAR_FREE(data); -#endif /* LWIP_TCPIP_CORE_LOCKING */ - - sock_set_errno(sock, err); - return err ? -1 : 0; -} - -#if !LWIP_TCPIP_CORE_LOCKING -/** lwip_setsockopt_callback: only used without CORE_LOCKING - * to get into the tcpip_thread - */ -static void -lwip_setsockopt_callback(void *arg) -{ - struct lwip_setgetsockopt_data *data; - LWIP_ASSERT("arg != NULL", arg != NULL); - data = (struct lwip_setgetsockopt_data*)arg; - - data->err = lwip_setsockopt_impl(data->s, data->level, data->optname, -#if LWIP_MPU_COMPATIBLE - data->optval, -#else /* LWIP_MPU_COMPATIBLE */ - data->optval.pc, -#endif /* LWIP_MPU_COMPATIBLE */ - data->optlen); - - sys_sem_signal((sys_sem_t*)(data->completed_sem)); -} -#endif /* LWIP_TCPIP_CORE_LOCKING */ - -/** lwip_setsockopt_impl: the actual implementation of setsockopt: - * same argument as lwip_setsockopt, either called directly or through callback - */ -static u8_t -lwip_setsockopt_impl(int s, int level, int optname, const void *optval, socklen_t optlen) -{ - u8_t err = 0; - struct lwip_sock *sock = tryget_socket(s); - if (!sock) { - return EBADF; - } - - switch (level) { - -/* Level: SOL_SOCKET */ - case SOL_SOCKET: - switch (optname) { - - /* SO_ACCEPTCONN is get-only */ - - /* The option flags */ - case SO_BROADCAST: - case SO_KEEPALIVE: -#if SO_REUSE - case SO_REUSEADDR: -#endif /* SO_REUSE */ - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, optlen, int); - if (*(const int*)optval) { - ip_set_option(sock->conn->pcb.ip, optname); - } else { - ip_reset_option(sock->conn->pcb.ip, optname); - } - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, SOL_SOCKET, optname=0x%x, ..) -> %s\n", - s, optname, (*(const int*)optval?"on":"off"))); - break; - - /* SO_TYPE is get-only */ - /* SO_ERROR is get-only */ - -#if LWIP_SO_SNDTIMEO - case SO_SNDTIMEO: - LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, optlen, LWIP_SO_SNDRCVTIMEO_OPTTYPE); - netconn_set_sendtimeout(sock->conn, LWIP_SO_SNDRCVTIMEO_GET_MS(optval)); - break; -#endif /* LWIP_SO_SNDTIMEO */ -#if LWIP_SO_RCVTIMEO - case SO_RCVTIMEO: - LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, optlen, LWIP_SO_SNDRCVTIMEO_OPTTYPE); - netconn_set_recvtimeout(sock->conn, (int)LWIP_SO_SNDRCVTIMEO_GET_MS(optval)); - break; -#endif /* LWIP_SO_RCVTIMEO */ -#if LWIP_SO_RCVBUF - case SO_RCVBUF: - LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, optlen, int); - netconn_set_recvbufsize(sock->conn, *(const int*)optval); - break; -#endif /* LWIP_SO_RCVBUF */ -#if LWIP_SO_LINGER - case SO_LINGER: - { - const struct linger* linger = (const struct linger*)optval; - LWIP_SOCKOPT_CHECK_OPTLEN_CONN(sock, optlen, struct linger); - if (linger->l_onoff) { - int lingersec = linger->l_linger; - if (lingersec < 0) { - return EINVAL; - } - if (lingersec > 0xFFFF) { - lingersec = 0xFFFF; - } - sock->conn->linger = (s16_t)lingersec; - } else { - sock->conn->linger = -1; - } - } - break; -#endif /* LWIP_SO_LINGER */ -#if LWIP_UDP - case SO_NO_CHECK: - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, int, NETCONN_UDP); -#if LWIP_UDPLITE - if ((udp_flags(sock->conn->pcb.udp) & UDP_FLAGS_UDPLITE) != 0) { - /* this flag is only available for UDP, not for UDP lite */ - return EAFNOSUPPORT; - } -#endif /* LWIP_UDPLITE */ - if (*(const int*)optval) { - udp_setflags(sock->conn->pcb.udp, udp_flags(sock->conn->pcb.udp) | UDP_FLAGS_NOCHKSUM); - } else { - udp_setflags(sock->conn->pcb.udp, udp_flags(sock->conn->pcb.udp) & ~UDP_FLAGS_NOCHKSUM); - } - break; -#endif /* LWIP_UDP */ - default: - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, SOL_SOCKET, UNIMPL: optname=0x%x, ..)\n", - s, optname)); - err = ENOPROTOOPT; - break; - } /* switch (optname) */ - break; - -/* Level: IPPROTO_IP */ - case IPPROTO_IP: - switch (optname) { - case IP_TTL: - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, optlen, int); - sock->conn->pcb.ip->ttl = (u8_t)(*(const int*)optval); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IP, IP_TTL, ..) -> %d\n", - s, sock->conn->pcb.ip->ttl)); - break; - case IP_TOS: - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, optlen, int); - sock->conn->pcb.ip->tos = (u8_t)(*(const int*)optval); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IP, IP_TOS, ..)-> %d\n", - s, sock->conn->pcb.ip->tos)); - break; -#if LWIP_IPV4 && LWIP_MULTICAST_TX_OPTIONS && LWIP_UDP - case IP_MULTICAST_TTL: - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, u8_t, NETCONN_UDP); - udp_set_multicast_ttl(sock->conn->pcb.udp, (u8_t)(*(const u8_t*)optval)); - break; - case IP_MULTICAST_IF: - { - ip4_addr_t if_addr; - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, struct in_addr, NETCONN_UDP); - inet_addr_to_ip4addr(&if_addr, (const struct in_addr*)optval); - udp_set_multicast_netif_addr(sock->conn->pcb.udp, &if_addr); - } - break; - case IP_MULTICAST_LOOP: - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, u8_t, NETCONN_UDP); - if (*(const u8_t*)optval) { - udp_setflags(sock->conn->pcb.udp, udp_flags(sock->conn->pcb.udp) | UDP_FLAGS_MULTICAST_LOOP); - } else { - udp_setflags(sock->conn->pcb.udp, udp_flags(sock->conn->pcb.udp) & ~UDP_FLAGS_MULTICAST_LOOP); - } - break; -#endif /* LWIP_IPV4 && LWIP_MULTICAST_TX_OPTIONS && LWIP_UDP */ -#if LWIP_IGMP - case IP_ADD_MEMBERSHIP: - case IP_DROP_MEMBERSHIP: - { - /* If this is a TCP or a RAW socket, ignore these options. */ - /* @todo: assign membership to this socket so that it is dropped when closing the socket */ - err_t igmp_err; - const struct ip_mreq *imr = (const struct ip_mreq *)optval; - ip4_addr_t if_addr; - ip4_addr_t multi_addr; - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, struct ip_mreq, NETCONN_UDP); - inet_addr_to_ip4addr(&if_addr, &imr->imr_interface); - inet_addr_to_ip4addr(&multi_addr, &imr->imr_multiaddr); - if (optname == IP_ADD_MEMBERSHIP) { - if (!lwip_socket_register_membership(s, &if_addr, &multi_addr)) { - /* cannot track membership (out of memory) */ - err = ENOMEM; - igmp_err = ERR_OK; - } else { - igmp_err = igmp_joingroup(&if_addr, &multi_addr); - } - } else { - igmp_err = igmp_leavegroup(&if_addr, &multi_addr); - lwip_socket_unregister_membership(s, &if_addr, &multi_addr); - } - if (igmp_err != ERR_OK) { - err = EADDRNOTAVAIL; - } - } - break; -#endif /* LWIP_IGMP */ - default: - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IP, UNIMPL: optname=0x%x, ..)\n", - s, optname)); - err = ENOPROTOOPT; - break; - } /* switch (optname) */ - break; - -#if LWIP_TCP -/* Level: IPPROTO_TCP */ - case IPPROTO_TCP: - /* Special case: all IPPROTO_TCP option take an int */ - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, int, NETCONN_TCP); - if (sock->conn->pcb.tcp->state == LISTEN) { - return EINVAL; - } - switch (optname) { - case TCP_NODELAY: - if (*(const int*)optval) { - tcp_nagle_disable(sock->conn->pcb.tcp); - } else { - tcp_nagle_enable(sock->conn->pcb.tcp); - } - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_NODELAY) -> %s\n", - s, (*(const int *)optval)?"on":"off") ); - break; - case TCP_KEEPALIVE: - sock->conn->pcb.tcp->keep_idle = (u32_t)(*(const int*)optval); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPALIVE) -> %"U32_F"\n", - s, sock->conn->pcb.tcp->keep_idle)); - break; - -#if LWIP_TCP_KEEPALIVE - case TCP_KEEPIDLE: - sock->conn->pcb.tcp->keep_idle = 1000*(u32_t)(*(const int*)optval); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPIDLE) -> %"U32_F"\n", - s, sock->conn->pcb.tcp->keep_idle)); - break; - case TCP_KEEPINTVL: - sock->conn->pcb.tcp->keep_intvl = 1000*(u32_t)(*(const int*)optval); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPINTVL) -> %"U32_F"\n", - s, sock->conn->pcb.tcp->keep_intvl)); - break; - case TCP_KEEPCNT: - sock->conn->pcb.tcp->keep_cnt = (u32_t)(*(const int*)optval); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, TCP_KEEPCNT) -> %"U32_F"\n", - s, sock->conn->pcb.tcp->keep_cnt)); - break; -#endif /* LWIP_TCP_KEEPALIVE */ - default: - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_TCP, UNIMPL: optname=0x%x, ..)\n", - s, optname)); - err = ENOPROTOOPT; - break; - } /* switch (optname) */ - break; -#endif /* LWIP_TCP*/ - -#if LWIP_IPV6 -/* Level: IPPROTO_IPV6 */ - case IPPROTO_IPV6: - switch (optname) { - case IPV6_V6ONLY: - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, int, NETCONN_TCP); - if (*(const int*)optval) { - netconn_set_ipv6only(sock->conn, 1); - } else { - netconn_set_ipv6only(sock->conn, 0); - } - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IPV6, IPV6_V6ONLY, ..) -> %d\n", - s, (netconn_get_ipv6only(sock->conn) ? 1 : 0))); - break; - default: - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_IPV6, UNIMPL: optname=0x%x, ..)\n", - s, optname)); - err = ENOPROTOOPT; - break; - } /* switch (optname) */ - break; -#endif /* LWIP_IPV6 */ - -#if LWIP_UDP && LWIP_UDPLITE - /* Level: IPPROTO_UDPLITE */ - case IPPROTO_UDPLITE: - /* Special case: all IPPROTO_UDPLITE option take an int */ - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB(sock, optlen, int); - /* If this is no UDP lite socket, ignore any options. */ - if (!NETCONNTYPE_ISUDPLITE(netconn_type(sock->conn))) { - return ENOPROTOOPT; - } - switch (optname) { - case UDPLITE_SEND_CSCOV: - if ((*(const int*)optval != 0) && ((*(const int*)optval < 8) || (*(const int*)optval > 0xffff))) { - /* don't allow illegal values! */ - sock->conn->pcb.udp->chksum_len_tx = 8; - } else { - sock->conn->pcb.udp->chksum_len_tx = (u16_t)*(const int*)optval; - } - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_UDPLITE, UDPLITE_SEND_CSCOV) -> %d\n", - s, (*(const int*)optval)) ); - break; - case UDPLITE_RECV_CSCOV: - if ((*(const int*)optval != 0) && ((*(const int*)optval < 8) || (*(const int*)optval > 0xffff))) { - /* don't allow illegal values! */ - sock->conn->pcb.udp->chksum_len_rx = 8; - } else { - sock->conn->pcb.udp->chksum_len_rx = (u16_t)*(const int*)optval; - } - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_UDPLITE, UDPLITE_RECV_CSCOV) -> %d\n", - s, (*(const int*)optval)) ); - break; - default: - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_UDPLITE, UNIMPL: optname=0x%x, ..)\n", - s, optname)); - err = ENOPROTOOPT; - break; - } /* switch (optname) */ - break; -#endif /* LWIP_UDP */ - /* Level: IPPROTO_RAW */ - case IPPROTO_RAW: - switch (optname) { -#if LWIP_IPV6 && LWIP_RAW - case IPV6_CHECKSUM: - /* It should not be possible to disable the checksum generation with ICMPv6 - * as per RFC 3542 chapter 3.1 */ - if(sock->conn->pcb.raw->protocol == IPPROTO_ICMPV6) { - return EINVAL; - } - - LWIP_SOCKOPT_CHECK_OPTLEN_CONN_PCB_TYPE(sock, optlen, int, NETCONN_RAW); - if (*(const int *)optval < 0) { - sock->conn->pcb.raw->chksum_reqd = 0; - } else if (*(const int *)optval & 1) { - /* Per RFC3542, odd offsets are not allowed */ - return EINVAL; - } else { - sock->conn->pcb.raw->chksum_reqd = 1; - sock->conn->pcb.raw->chksum_offset = (u16_t)*(const int *)optval; - } - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_RAW, IPV6_CHECKSUM, ..) -> %d\n", - s, sock->conn->pcb.raw->chksum_reqd)); - break; -#endif /* LWIP_IPV6 && LWIP_RAW */ - default: - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, IPPROTO_RAW, UNIMPL: optname=0x%x, ..)\n", - s, optname)); - err = ENOPROTOOPT; - break; - } /* switch (optname) */ - break; - default: - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_setsockopt(%d, level=0x%x, UNIMPL: optname=0x%x, ..)\n", - s, level, optname)); - err = ENOPROTOOPT; - break; - } /* switch (level) */ - - return err; -} - -int -lwip_ioctl(int s, long cmd, void *argp) -{ - struct lwip_sock *sock = get_socket(s); - u8_t val; -#if LWIP_SO_RCVBUF - u16_t buflen = 0; - int recv_avail; -#endif /* LWIP_SO_RCVBUF */ - - if (!sock) { - return -1; - } - - switch (cmd) { -#if LWIP_SO_RCVBUF || LWIP_FIONREAD_LINUXMODE - case FIONREAD: - if (!argp) { - sock_set_errno(sock, EINVAL); - return -1; - } -#if LWIP_FIONREAD_LINUXMODE - if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_TCP) { - struct pbuf *p; - if (sock->lastdata) { - p = ((struct netbuf *)sock->lastdata)->p; - *((int*)argp) = p->tot_len - sock->lastoffset; - } else { - struct netbuf *rxbuf; - err_t err; - if (sock->rcvevent <= 0) { - *((int*)argp) = 0; - } else { - err = netconn_recv(sock->conn, &rxbuf); - if (err != ERR_OK) { - *((int*)argp) = 0; - } else { - sock->lastdata = rxbuf; - sock->lastoffset = 0; - *((int*)argp) = rxbuf->p->tot_len; - } - } - } - return 0; - } -#endif /* LWIP_FIONREAD_LINUXMODE */ - -#if LWIP_SO_RCVBUF - /* we come here if either LWIP_FIONREAD_LINUXMODE==0 or this is a TCP socket */ - SYS_ARCH_GET(sock->conn->recv_avail, recv_avail); - if (recv_avail < 0) { - recv_avail = 0; - } - *((int*)argp) = recv_avail; - - /* Check if there is data left from the last recv operation. /maq 041215 */ - if (sock->lastdata) { - struct pbuf *p = (struct pbuf *)sock->lastdata; - if (NETCONNTYPE_GROUP(netconn_type(sock->conn)) != NETCONN_TCP) { - p = ((struct netbuf *)p)->p; - } - buflen = p->tot_len; - buflen -= sock->lastoffset; - - *((int*)argp) += buflen; - } - - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(%d, FIONREAD, %p) = %"U16_F"\n", s, argp, *((u16_t*)argp))); - sock_set_errno(sock, 0); - return 0; -#else /* LWIP_SO_RCVBUF */ - break; -#endif /* LWIP_SO_RCVBUF */ -#endif /* LWIP_SO_RCVBUF || LWIP_FIONREAD_LINUXMODE */ - - case (long)FIONBIO: - val = 0; - if (argp && *(u32_t*)argp) { - val = 1; - } - netconn_set_nonblocking(sock->conn, val); - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(%d, FIONBIO, %d)\n", s, val)); - sock_set_errno(sock, 0); - return 0; - - default: - break; - } /* switch (cmd) */ - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_ioctl(%d, UNIMPL: 0x%lx, %p)\n", s, cmd, argp)); - sock_set_errno(sock, ENOSYS); /* not yet implemented */ - return -1; -} - -/** A minimal implementation of fcntl. - * Currently only the commands F_GETFL and F_SETFL are implemented. - * Only the flag O_NONBLOCK is implemented. - */ -int -lwip_fcntl(int s, int cmd, int val) -{ - struct lwip_sock *sock = get_socket(s); - int ret = -1; - - if (!sock) { - return -1; - } - - switch (cmd) { - case F_GETFL: - ret = netconn_is_nonblocking(sock->conn) ? O_NONBLOCK : 0; - sock_set_errno(sock, 0); - break; - case F_SETFL: - if ((val & ~O_NONBLOCK) == 0) { - /* only O_NONBLOCK, all other bits are zero */ - netconn_set_nonblocking(sock->conn, val & O_NONBLOCK); - ret = 0; - sock_set_errno(sock, 0); - } else { - sock_set_errno(sock, ENOSYS); /* not yet implemented */ - } - break; - default: - LWIP_DEBUGF(SOCKETS_DEBUG, ("lwip_fcntl(%d, UNIMPL: %d, %d)\n", s, cmd, val)); - sock_set_errno(sock, ENOSYS); /* not yet implemented */ - break; - } - return ret; -} - -#if LWIP_IGMP -/** Register a new IGMP membership. On socket close, the membership is dropped automatically. - * - * ATTENTION: this function is called from tcpip_thread (or under CORE_LOCK). - * - * @return 1 on success, 0 on failure - */ -static int -lwip_socket_register_membership(int s, const ip4_addr_t *if_addr, const ip4_addr_t *multi_addr) -{ - struct lwip_sock *sock = get_socket(s); - int i; - - if (!sock) { - return 0; - } - - for (i = 0; i < LWIP_SOCKET_MAX_MEMBERSHIPS; i++) { - if (socket_ipv4_multicast_memberships[i].sock == NULL) { - socket_ipv4_multicast_memberships[i].sock = sock; - ip4_addr_copy(socket_ipv4_multicast_memberships[i].if_addr, *if_addr); - ip4_addr_copy(socket_ipv4_multicast_memberships[i].multi_addr, *multi_addr); - return 1; - } - } - return 0; -} - -/** Unregister a previously registered membership. This prevents dropping the membership - * on socket close. - * - * ATTENTION: this function is called from tcpip_thread (or under CORE_LOCK). - */ -static void -lwip_socket_unregister_membership(int s, const ip4_addr_t *if_addr, const ip4_addr_t *multi_addr) -{ - struct lwip_sock *sock = get_socket(s); - int i; - - if (!sock) { - return; - } - - for (i = 0; i < LWIP_SOCKET_MAX_MEMBERSHIPS; i++) { - if ((socket_ipv4_multicast_memberships[i].sock == sock) && - ip4_addr_cmp(&socket_ipv4_multicast_memberships[i].if_addr, if_addr) && - ip4_addr_cmp(&socket_ipv4_multicast_memberships[i].multi_addr, multi_addr)) { - socket_ipv4_multicast_memberships[i].sock = NULL; - ip4_addr_set_zero(&socket_ipv4_multicast_memberships[i].if_addr); - ip4_addr_set_zero(&socket_ipv4_multicast_memberships[i].multi_addr); - return; - } - } -} - -/** Drop all memberships of a socket that were not dropped explicitly via setsockopt. - * - * ATTENTION: this function is NOT called from tcpip_thread (or under CORE_LOCK). - */ -static void -lwip_socket_drop_registered_memberships(int s) -{ - struct lwip_sock *sock = get_socket(s); - int i; - - if (!sock) { - return; - } - - for (i = 0; i < LWIP_SOCKET_MAX_MEMBERSHIPS; i++) { - if (socket_ipv4_multicast_memberships[i].sock == sock) { - ip_addr_t multi_addr, if_addr; - ip_addr_copy_from_ip4(multi_addr, socket_ipv4_multicast_memberships[i].multi_addr); - ip_addr_copy_from_ip4(if_addr, socket_ipv4_multicast_memberships[i].if_addr); - socket_ipv4_multicast_memberships[i].sock = NULL; - ip4_addr_set_zero(&socket_ipv4_multicast_memberships[i].if_addr); - ip4_addr_set_zero(&socket_ipv4_multicast_memberships[i].multi_addr); - - netconn_join_leave_group(sock->conn, &multi_addr, &if_addr, NETCONN_LEAVE); - } - } -} -#endif /* LWIP_IGMP */ -#endif /* LWIP_SOCKET */ diff --git a/third_party/lwip/repo/lwip/src/api/tcpip.c b/third_party/lwip/repo/lwip/src/api/tcpip.c deleted file mode 100644 index 6c9a5015dd2219..00000000000000 --- a/third_party/lwip/repo/lwip/src/api/tcpip.c +++ /dev/null @@ -1,565 +0,0 @@ -/** - * @file - * Sequential API Main thread module - * - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ - -#include "lwip/opt.h" - -#if !NO_SYS /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/priv/tcpip_priv.h" -#include "lwip/sys.h" -#include "lwip/memp.h" -#include "lwip/mem.h" -#include "lwip/init.h" -#include "lwip/ip.h" -#include "lwip/pbuf.h" -#include "lwip/etharp.h" -#include "netif/ethernet.h" - -#define TCPIP_MSG_VAR_REF(name) API_VAR_REF(name) -#define TCPIP_MSG_VAR_DECLARE(name) API_VAR_DECLARE(struct tcpip_msg, name) -#define TCPIP_MSG_VAR_ALLOC(name) API_VAR_ALLOC(struct tcpip_msg, MEMP_TCPIP_MSG_API, name, ERR_MEM) -#define TCPIP_MSG_VAR_FREE(name) API_VAR_FREE(MEMP_TCPIP_MSG_API, name) - -/* global variables */ -static sys_thread_t tcpip_thread_obj; -static tcpip_init_done_fn tcpip_init_done; -static tcpip_will_finish_fn tcpip_will_finish; -static void *tcpip_init_done_arg; -static void *tcpip_will_finish_arg; -static sys_mbox_t mbox; - -#if LWIP_TCPIP_CORE_LOCKING -/** The global semaphore to lock the stack. */ -sys_mutex_t lock_tcpip_core; -#endif /* LWIP_TCPIP_CORE_LOCKING */ - -#if LWIP_TIMERS -/* wait for a message, timeouts are processed while waiting */ -#define TCPIP_MBOX_FETCH(mbox, msg) sys_timeouts_mbox_fetch(mbox, msg) -#else /* LWIP_TIMERS */ -/* wait for a message with timers disabled (e.g. pass a timer-check trigger into tcpip_thread) */ -#define TCPIP_MBOX_FETCH(mbox, msg) sys_mbox_fetch(mbox, msg) -#endif /* LWIP_TIMERS */ - -/** - * The main lwIP thread. This thread has exclusive access to lwIP core functions - * (unless access to them is not locked). Other threads communicate with this - * thread using message boxes. - * - * It also starts all the timers to make sure they are running in the right - * thread context. - * - * @param arg unused argument - */ -static void -tcpip_thread(void *arg) -{ - struct tcpip_msg *msg; - int finish = 0; - LWIP_UNUSED_ARG(arg); - - LWIP_MARK_TCPIP_THREAD(); - - if (tcpip_init_done != NULL) { - tcpip_init_done(tcpip_init_done_arg); - } - - LOCK_TCPIP_CORE(); - while (!finish) { /* MAIN Loop */ - UNLOCK_TCPIP_CORE(); - LWIP_TCPIP_THREAD_ALIVE(); - /* wait for a message, timeouts are processed while waiting */ - TCPIP_MBOX_FETCH(&mbox, (void **)&msg); - LOCK_TCPIP_CORE(); - if (msg == NULL) { - LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: invalid message: NULL\n")); - LWIP_ASSERT("tcpip_thread: invalid message", 0); - continue; - } - switch (msg->type) { -#if !LWIP_TCPIP_CORE_LOCKING - case TCPIP_MSG_API: - LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: API message %p\n", (void *)msg)); - msg->msg.api_msg.function(msg->msg.api_msg.msg); - break; - case TCPIP_MSG_API_CALL: - LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: API CALL message %p\n", (void *)msg)); - msg->msg.api_call.arg->err = msg->msg.api_call.function(msg->msg.api_call.arg); - sys_sem_signal(msg->msg.api_call.sem); - break; -#endif /* !LWIP_TCPIP_CORE_LOCKING */ - -#if !LWIP_TCPIP_CORE_LOCKING_INPUT - case TCPIP_MSG_INPKT: - LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: PACKET %p\n", (void *)msg)); - msg->msg.inp.input_fn(msg->msg.inp.p, msg->msg.inp.netif); - memp_free(MEMP_TCPIP_MSG_INPKT, msg); - break; -#endif /* !LWIP_TCPIP_CORE_LOCKING_INPUT */ - -#if LWIP_TCPIP_TIMEOUT && LWIP_TIMERS - case TCPIP_MSG_TIMEOUT: - LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: TIMEOUT %p\n", (void *)msg)); - sys_timeout(msg->msg.tmo.msecs, msg->msg.tmo.h, msg->msg.tmo.arg); - memp_free(MEMP_TCPIP_MSG_API, msg); - break; - case TCPIP_MSG_UNTIMEOUT: - LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: UNTIMEOUT %p\n", (void *)msg)); - sys_untimeout(msg->msg.tmo.h, msg->msg.tmo.arg); - memp_free(MEMP_TCPIP_MSG_API, msg); - break; -#endif /* LWIP_TCPIP_TIMEOUT && LWIP_TIMERS */ - - case TCPIP_MSG_CALLBACK: - LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: CALLBACK %p\n", (void *)msg)); - msg->msg.cb.function(msg->msg.cb.ctx); - memp_free(MEMP_TCPIP_MSG_API, msg); - break; - - case TCPIP_MSG_CALLBACK_STATIC: - LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: CALLBACK_STATIC %p\n", (void *)msg)); - msg->msg.cb.function(msg->msg.cb.ctx); - break; - - case TCPIP_MSG_FINISH: - LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: FINISH %p\n", (void*)msg)); - memp_free(MEMP_TCPIP_MSG_API, msg); - finish = 1; - break; - - default: - LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_thread: invalid message: %d\n", msg->type)); - LWIP_ASSERT("tcpip_thread: invalid message", 0); - break; - } - } - - if (tcpip_will_finish != NULL) { - tcpip_will_finish(tcpip_will_finish_arg); - } -} - -/** - * Pass a received packet to tcpip_thread for input processing - * - * @param p the received packet - * @param inp the network interface on which the packet was received - * @param input_fn input function to call - */ -err_t -tcpip_inpkt(struct pbuf *p, struct netif *inp, netif_input_fn input_fn) -{ -#if LWIP_TCPIP_CORE_LOCKING_INPUT - err_t ret; - LWIP_DEBUGF(TCPIP_DEBUG, ("tcpip_inpkt: PACKET %p/%p\n", (void *)p, (void *)inp)); - LOCK_TCPIP_CORE(); - ret = input_fn(p, inp); - UNLOCK_TCPIP_CORE(); - return ret; -#else /* LWIP_TCPIP_CORE_LOCKING_INPUT */ - struct tcpip_msg *msg; - - LWIP_ASSERT("Invalid mbox", sys_mbox_valid_val(mbox)); - - msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_INPKT); - if (msg == NULL) { - return ERR_MEM; - } - - msg->type = TCPIP_MSG_INPKT; - msg->msg.inp.p = p; - msg->msg.inp.netif = inp; - msg->msg.inp.input_fn = input_fn; - if (sys_mbox_trypost(&mbox, msg) != ERR_OK) { - memp_free(MEMP_TCPIP_MSG_INPKT, msg); - return ERR_MEM; - } - return ERR_OK; -#endif /* LWIP_TCPIP_CORE_LOCKING_INPUT */ -} - -/** - * @ingroup lwip_os - * Pass a received packet to tcpip_thread for input processing with - * ethernet_input or ip_input. Don't call directly, pass to netif_add() - * and call netif->input(). - * - * @param p the received packet, p->payload pointing to the Ethernet header or - * to an IP header (if inp doesn't have NETIF_FLAG_ETHARP or - * NETIF_FLAG_ETHERNET flags) - * @param inp the network interface on which the packet was received - */ -err_t -tcpip_input(struct pbuf *p, struct netif *inp) -{ -#if LWIP_ETHERNET - if (inp->flags & (NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET)) { - return tcpip_inpkt(p, inp, ethernet_input); - } else -#endif /* LWIP_ETHERNET */ - return tcpip_inpkt(p, inp, ip_input); -} - -/** - * Call a specific function in the thread context of - * tcpip_thread for easy access synchronization. - * A function called in that way may access lwIP core code - * without fearing concurrent access. - * - * @param function the function to call - * @param ctx parameter passed to f - * @param block 1 to block until the request is posted, 0 to non-blocking mode - * @return ERR_OK if the function was called, another err_t if not - */ -err_t -tcpip_callback_with_block(tcpip_callback_fn function, void *ctx, u8_t block) -{ - struct tcpip_msg *msg; - - LWIP_ASSERT("Invalid mbox", sys_mbox_valid_val(mbox)); - - msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API); - if (msg == NULL) { - return ERR_MEM; - } - - msg->type = TCPIP_MSG_CALLBACK; - msg->msg.cb.function = function; - msg->msg.cb.ctx = ctx; - if (block) { - sys_mbox_post(&mbox, msg); - } else { - if (sys_mbox_trypost(&mbox, msg) != ERR_OK) { - memp_free(MEMP_TCPIP_MSG_API, msg); - return ERR_MEM; - } - } - return ERR_OK; -} - -#if LWIP_TCPIP_TIMEOUT && LWIP_TIMERS -/** - * call sys_timeout in tcpip_thread - * - * @param msecs time in milliseconds for timeout - * @param h function to be called on timeout - * @param arg argument to pass to timeout function h - * @return ERR_MEM on memory error, ERR_OK otherwise - */ -err_t -tcpip_timeout(u32_t msecs, sys_timeout_handler h, void *arg) -{ - struct tcpip_msg *msg; - - LWIP_ASSERT("Invalid mbox", sys_mbox_valid_val(mbox)); - - msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API); - if (msg == NULL) { - return ERR_MEM; - } - - msg->type = TCPIP_MSG_TIMEOUT; - msg->msg.tmo.msecs = msecs; - msg->msg.tmo.h = h; - msg->msg.tmo.arg = arg; - sys_mbox_post(&mbox, msg); - return ERR_OK; -} - -/** - * call sys_untimeout in tcpip_thread - * - * @param h function to be called on timeout - * @param arg argument to pass to timeout function h - * @return ERR_MEM on memory error, ERR_OK otherwise - */ -err_t -tcpip_untimeout(sys_timeout_handler h, void *arg) -{ - struct tcpip_msg *msg; - - LWIP_ASSERT("Invalid mbox", sys_mbox_valid_val(mbox)); - - msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API); - if (msg == NULL) { - return ERR_MEM; - } - - msg->type = TCPIP_MSG_UNTIMEOUT; - msg->msg.tmo.h = h; - msg->msg.tmo.arg = arg; - sys_mbox_post(&mbox, msg); - return ERR_OK; -} -#endif /* LWIP_TCPIP_TIMEOUT && LWIP_TIMERS */ - - -/** - * Sends a message to TCPIP thread to call a function. Caller thread blocks on - * on a provided semaphore, which ist NOT automatically signalled by TCPIP thread, - * this has to be done by the user. - * It is recommended to use LWIP_TCPIP_CORE_LOCKING since this is the way - * with least runtime overhead. - * - * @param fn function to be called from TCPIP thread - * @param apimsg argument to API function - * @param sem semaphore to wait on - * @return ERR_OK if the function was called, another err_t if not - */ -err_t -tcpip_send_msg_wait_sem(tcpip_callback_fn fn, void *apimsg, sys_sem_t* sem) -{ -#if LWIP_TCPIP_CORE_LOCKING - LWIP_UNUSED_ARG(sem); - LOCK_TCPIP_CORE(); - fn(apimsg); - UNLOCK_TCPIP_CORE(); - return ERR_OK; -#else /* LWIP_TCPIP_CORE_LOCKING */ - TCPIP_MSG_VAR_DECLARE(msg); - - LWIP_ASSERT("semaphore not initialized", sys_sem_valid(sem)); - LWIP_ASSERT("Invalid mbox", sys_mbox_valid_val(mbox)); - - TCPIP_MSG_VAR_ALLOC(msg); - TCPIP_MSG_VAR_REF(msg).type = TCPIP_MSG_API; - TCPIP_MSG_VAR_REF(msg).msg.api_msg.function = fn; - TCPIP_MSG_VAR_REF(msg).msg.api_msg.msg = apimsg; - sys_mbox_post(&mbox, &TCPIP_MSG_VAR_REF(msg)); - sys_arch_sem_wait(sem, 0); - TCPIP_MSG_VAR_FREE(msg); - return ERR_OK; -#endif /* LWIP_TCPIP_CORE_LOCKING */ -} - -/** - * Synchronously calls function in TCPIP thread and waits for its completion. - * It is recommended to use LWIP_TCPIP_CORE_LOCKING (preferred) or - * LWIP_NETCONN_SEM_PER_THREAD. - * If not, a semaphore is created and destroyed on every call which is usually - * an expensive/slow operation. - * @param fn Function to call - * @param call Call parameters - * @return Return value from tcpip_api_call_fn - */ -err_t -tcpip_api_call(tcpip_api_call_fn fn, struct tcpip_api_call_data *call) -{ -#if LWIP_TCPIP_CORE_LOCKING - err_t err; - LOCK_TCPIP_CORE(); - err = fn(call); - UNLOCK_TCPIP_CORE(); - return err; -#else /* LWIP_TCPIP_CORE_LOCKING */ - TCPIP_MSG_VAR_DECLARE(msg); - -#if !LWIP_NETCONN_SEM_PER_THREAD - err_t err = sys_sem_new(&call->sem, 0); - if (err != ERR_OK) { - return err; - } -#endif /* LWIP_NETCONN_SEM_PER_THREAD */ - - LWIP_ASSERT("Invalid mbox", sys_mbox_valid_val(mbox)); - - TCPIP_MSG_VAR_ALLOC(msg); - TCPIP_MSG_VAR_REF(msg).type = TCPIP_MSG_API_CALL; - TCPIP_MSG_VAR_REF(msg).msg.api_call.arg = call; - TCPIP_MSG_VAR_REF(msg).msg.api_call.function = fn; -#if LWIP_NETCONN_SEM_PER_THREAD - TCPIP_MSG_VAR_REF(msg).msg.api_call.sem = LWIP_NETCONN_THREAD_SEM_GET(); -#else /* LWIP_NETCONN_SEM_PER_THREAD */ - TCPIP_MSG_VAR_REF(msg).msg.api_call.sem = &call->sem; -#endif /* LWIP_NETCONN_SEM_PER_THREAD */ - sys_mbox_post(&mbox, &TCPIP_MSG_VAR_REF(msg)); - sys_arch_sem_wait(TCPIP_MSG_VAR_REF(msg).msg.api_call.sem, 0); - TCPIP_MSG_VAR_FREE(msg); - -#if !LWIP_NETCONN_SEM_PER_THREAD - sys_sem_free(&call->sem); -#endif /* LWIP_NETCONN_SEM_PER_THREAD */ - - return call->err; -#endif /* LWIP_TCPIP_CORE_LOCKING */ -} - -/** - * Allocate a structure for a static callback message and initialize it. - * This is intended to be used to send "static" messages from interrupt context. - * - * @param function the function to call - * @param ctx parameter passed to function - * @return a struct pointer to pass to tcpip_trycallback(). - */ -struct tcpip_callback_msg* -tcpip_callbackmsg_new(tcpip_callback_fn function, void *ctx) -{ - struct tcpip_msg *msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API); - if (msg == NULL) { - return NULL; - } - msg->type = TCPIP_MSG_CALLBACK_STATIC; - msg->msg.cb.function = function; - msg->msg.cb.ctx = ctx; - return (struct tcpip_callback_msg*)msg; -} - -/** - * Free a callback message allocated by tcpip_callbackmsg_new(). - * - * @param msg the message to free - */ -void -tcpip_callbackmsg_delete(struct tcpip_callback_msg* msg) -{ - memp_free(MEMP_TCPIP_MSG_API, msg); -} - -/** - * Try to post a callback-message to the tcpip_thread mbox - * This is intended to be used to send "static" messages from interrupt context. - * - * @param msg pointer to the message to post - * @return sys_mbox_trypost() return code - */ -err_t -tcpip_trycallback(struct tcpip_callback_msg* msg) -{ - LWIP_ASSERT("Invalid mbox", sys_mbox_valid_val(mbox)); - return sys_mbox_trypost(&mbox, msg); -} - -/** - * @ingroup lwip_os - * Initialize this module: - * - initialize all sub modules - * - start the tcpip_thread - * - * @param initfunc a function to call when tcpip_thread is running and finished initializing - * @param arg argument to pass to initfunc - */ -void -tcpip_init(tcpip_init_done_fn initfunc, void *arg) -{ - lwip_init(); - - tcpip_init_done = initfunc; - tcpip_init_done_arg = arg; - if (sys_mbox_new(&mbox, TCPIP_MBOX_SIZE) != ERR_OK) { - LWIP_ASSERT("failed to create tcpip_thread mbox", 0); - } -#if LWIP_TCPIP_CORE_LOCKING - if (sys_mutex_new(&lock_tcpip_core) != ERR_OK) { - LWIP_ASSERT("failed to create lock_tcpip_core", 0); - } -#endif /* LWIP_TCPIP_CORE_LOCKING */ - - tcpip_thread_obj = sys_thread_new(TCPIP_THREAD_NAME, tcpip_thread, NULL, TCPIP_THREAD_STACKSIZE, TCPIP_THREAD_PRIO); -} - -/** - * Finalize this module: - * - initialize all sub modules - * - start the tcpip_thread - * - * @param finish a function to call while tcpip_thread is still running and ready to exit - * @param arg argument to pass to finish - */ -err_t -tcpip_finish(tcpip_will_finish_fn finish, void *arg) -{ - tcpip_will_finish = finish; - tcpip_will_finish_arg = arg; - - if (sys_mbox_valid(&mbox)) { - struct tcpip_msg *msg; - - msg = (struct tcpip_msg *)memp_malloc(MEMP_TCPIP_MSG_API); - if (msg == NULL) { - return ERR_MEM; - } - - msg->type = TCPIP_MSG_FINISH; - sys_mbox_post(&mbox, msg); - - return sys_thread_finish(tcpip_thread_obj); - } - - return ERR_OK; -} - -/** - * Simple callback function used with tcpip_callback to free a pbuf - * (pbuf_free has a wrong signature for tcpip_callback) - * - * @param p The pbuf (chain) to be dereferenced. - */ -static void -pbuf_free_int(void *p) -{ - struct pbuf *q = (struct pbuf *)p; - pbuf_free(q); -} - -/** - * A simple wrapper function that allows you to free a pbuf from interrupt context. - * - * @param p The pbuf (chain) to be dereferenced. - * @return ERR_OK if callback could be enqueued, an err_t if not - */ -err_t -pbuf_free_callback(struct pbuf *p) -{ - return tcpip_callback_with_block(pbuf_free_int, p, 0); -} - -/** - * A simple wrapper function that allows you to free heap memory from - * interrupt context. - * - * @param m the heap memory to free - * @return ERR_OK if callback could be enqueued, an err_t if not - */ -err_t -mem_free_callback(void *m) -{ - return tcpip_callback_with_block(mem_free, m, 0); -} - -#endif /* !NO_SYS */ diff --git a/third_party/lwip/repo/lwip/src/apps/httpd/fs.c b/third_party/lwip/repo/lwip/src/apps/httpd/fs.c deleted file mode 100644 index 35b5e3103812c8..00000000000000 --- a/third_party/lwip/repo/lwip/src/apps/httpd/fs.c +++ /dev/null @@ -1,179 +0,0 @@ -/* - * Copyright (c) 2001-2003 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ - -#include "lwip/apps/httpd_opts.h" -#include "lwip/def.h" -#include "lwip/apps/fs.h" -#include "fsdata.h" -#include - - -#if HTTPD_USE_CUSTOM_FSDATA -#include "fsdata_custom.c" -#else /* HTTPD_USE_CUSTOM_FSDATA */ -#include "fsdata.c" -#endif /* HTTPD_USE_CUSTOM_FSDATA */ - -/*-----------------------------------------------------------------------------------*/ - -#if LWIP_HTTPD_CUSTOM_FILES -int fs_open_custom(struct fs_file *file, const char *name); -void fs_close_custom(struct fs_file *file); -#if LWIP_HTTPD_FS_ASYNC_READ -u8_t fs_canread_custom(struct fs_file *file); -u8_t fs_wait_read_custom(struct fs_file *file, fs_wait_cb callback_fn, void *callback_arg); -int fs_read_async_custom(struct fs_file *file, char *buffer, int count, fs_wait_cb callback_fn, void *callback_arg); -#else /* LWIP_HTTPD_FS_ASYNC_READ */ -int fs_read_custom(struct fs_file *file, char *buffer, int count); -#endif /* LWIP_HTTPD_FS_ASYNC_READ */ -#endif /* LWIP_HTTPD_CUSTOM_FILES */ - -/*-----------------------------------------------------------------------------------*/ -err_t -fs_open(struct fs_file *file, const char *name) -{ - const struct fsdata_file *f; - - if ((file == NULL) || (name == NULL)) { - return ERR_ARG; - } - -#if LWIP_HTTPD_CUSTOM_FILES - if (fs_open_custom(file, name)) { - file->is_custom_file = 1; - return ERR_OK; - } - file->is_custom_file = 0; -#endif /* LWIP_HTTPD_CUSTOM_FILES */ - - for (f = FS_ROOT; f != NULL; f = f->next) { - if (!strcmp(name, (const char *)f->name)) { - file->data = (const char *)f->data; - file->len = f->len; - file->index = f->len; - file->pextension = NULL; - file->flags = f->flags; -#if HTTPD_PRECALCULATED_CHECKSUM - file->chksum_count = f->chksum_count; - file->chksum = f->chksum; -#endif /* HTTPD_PRECALCULATED_CHECKSUM */ -#if LWIP_HTTPD_FILE_STATE - file->state = fs_state_init(file, name); -#endif /* #if LWIP_HTTPD_FILE_STATE */ - return ERR_OK; - } - } - /* file not found */ - return ERR_VAL; -} - -/*-----------------------------------------------------------------------------------*/ -void -fs_close(struct fs_file *file) -{ -#if LWIP_HTTPD_CUSTOM_FILES - if (file->is_custom_file) { - fs_close_custom(file); - } -#endif /* LWIP_HTTPD_CUSTOM_FILES */ -#if LWIP_HTTPD_FILE_STATE - fs_state_free(file, file->state); -#endif /* #if LWIP_HTTPD_FILE_STATE */ - LWIP_UNUSED_ARG(file); -} -/*-----------------------------------------------------------------------------------*/ -#if LWIP_HTTPD_DYNAMIC_FILE_READ -#if LWIP_HTTPD_FS_ASYNC_READ -int -fs_read_async(struct fs_file *file, char *buffer, int count, fs_wait_cb callback_fn, void *callback_arg) -#else /* LWIP_HTTPD_FS_ASYNC_READ */ -int -fs_read(struct fs_file *file, char *buffer, int count) -#endif /* LWIP_HTTPD_FS_ASYNC_READ */ -{ - int read; - if(file->index == file->len) { - return FS_READ_EOF; - } -#if LWIP_HTTPD_FS_ASYNC_READ - LWIP_UNUSED_ARG(callback_fn); - LWIP_UNUSED_ARG(callback_arg); -#endif /* LWIP_HTTPD_FS_ASYNC_READ */ -#if LWIP_HTTPD_CUSTOM_FILES - if (file->is_custom_file) { -#if LWIP_HTTPD_FS_ASYNC_READ - return fs_read_async_custom(file, buffer, count, callback_fn, callback_arg); -#else /* LWIP_HTTPD_FS_ASYNC_READ */ - return fs_read_custom(file, buffer, count); -#endif /* LWIP_HTTPD_FS_ASYNC_READ */ - } -#endif /* LWIP_HTTPD_CUSTOM_FILES */ - - read = file->len - file->index; - if(read > count) { - read = count; - } - - MEMCPY(buffer, (file->data + file->index), read); - file->index += read; - - return(read); -} -#endif /* LWIP_HTTPD_DYNAMIC_FILE_READ */ -/*-----------------------------------------------------------------------------------*/ -#if LWIP_HTTPD_FS_ASYNC_READ -int -fs_is_file_ready(struct fs_file *file, fs_wait_cb callback_fn, void *callback_arg) -{ - if (file != NULL) { -#if LWIP_HTTPD_FS_ASYNC_READ -#if LWIP_HTTPD_CUSTOM_FILES - if (!fs_canread_custom(file)) { - if (fs_wait_read_custom(file, callback_fn, callback_arg)) { - return 0; - } - } -#else /* LWIP_HTTPD_CUSTOM_FILES */ - LWIP_UNUSED_ARG(callback_fn); - LWIP_UNUSED_ARG(callback_arg); -#endif /* LWIP_HTTPD_CUSTOM_FILES */ -#endif /* LWIP_HTTPD_FS_ASYNC_READ */ - } - return 1; -} -#endif /* LWIP_HTTPD_FS_ASYNC_READ */ -/*-----------------------------------------------------------------------------------*/ -int -fs_bytes_left(struct fs_file *file) -{ - return file->len - file->index; -} diff --git a/third_party/lwip/repo/lwip/src/apps/httpd/fs/404.html b/third_party/lwip/repo/lwip/src/apps/httpd/fs/404.html deleted file mode 100644 index 40b343a91e248d..00000000000000 --- a/third_party/lwip/repo/lwip/src/apps/httpd/fs/404.html +++ /dev/null @@ -1,21 +0,0 @@ - -lwIP - A Lightweight TCP/IP Stack - - - - -
    - SICS logo - -

    lwIP - A Lightweight TCP/IP Stack

    -

    404 - Page not found

    -

    - Sorry, the page you are requesting was not found on this - server. -

    -
    -   -
    - - diff --git a/third_party/lwip/repo/lwip/src/apps/httpd/fs/img/sics.gif b/third_party/lwip/repo/lwip/src/apps/httpd/fs/img/sics.gif deleted file mode 100644 index 0a4fc7bb07050eec9226ca93bc9ad237f35502c8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 724 zcmZ?wbhEHbbYoCrSjxa~Q`<5tD{KG${gWq8=I7_%uwlcpWy=~G8p_Jb4zT=SA;^3z!7uBu>UZ()&> z+r1;Oh0mFly?klC)5cAV$sD}98F{LBUHERS_hGGKac5`W-mvIltqUt73*&`X?UVf< z%Uqmm^}K~z9MaFS-jwgVGIUF9Z77P_s7Vc}y?@_XT+GT)AcZF$6%$qQsA+Q0bF z!Mss%ktc&>+n*qp2aIzy6-8A8zNf3ovHkU%wPnH@(O;*7g5`QX{a~M@%VFg!JaWkVUk6yFE1wL^V{({yi?^s!by^W;pXIz%mY}~L;uBR^JK|)kW|Avap zVzxyL+2N;b1q1f77^T<4c)gUoN8c;6;F^+^0^VN o#HPS7gPr3^SVM!%(d|c@c+6frXclnOc-SHmma$O4k%7S)08~d;ZvX%Q diff --git a/third_party/lwip/repo/lwip/src/apps/httpd/fs/index.html b/third_party/lwip/repo/lwip/src/apps/httpd/fs/index.html deleted file mode 100644 index ab575ef0891887..00000000000000 --- a/third_party/lwip/repo/lwip/src/apps/httpd/fs/index.html +++ /dev/null @@ -1,47 +0,0 @@ - -lwIP - A Lightweight TCP/IP Stack - - - - -
    - SICS logo - -

    lwIP - A Lightweight TCP/IP Stack

    -

    - The web page you are watching was served by a simple web - server running on top of the lightweight TCP/IP stack lwIP. -

    -

    - lwIP is an open source implementation of the TCP/IP - protocol suite that was originally written by Adam Dunkels - of the Swedish Institute of Computer Science but now is - being actively developed by a team of developers - distributed world-wide. Since it's release, lwIP has - spurred a lot of interest and has been ported to several - platforms and operating systems. lwIP can be used either - with or without an underlying OS. -

    -

    - The focus of the lwIP TCP/IP implementation is to reduce - the RAM usage while still having a full scale TCP. This - makes lwIP suitable for use in embedded systems with tens - of kilobytes of free RAM and room for around 40 kilobytes - of code ROM. -

    -

    - More information about lwIP can be found at the lwIP - homepage at http://savannah.nongnu.org/projects/lwip/ - or at the lwIP wiki at http://lwip.wikia.com/. -

    -
    -   -
    - - - diff --git a/third_party/lwip/repo/lwip/src/apps/httpd/fsdata.c b/third_party/lwip/repo/lwip/src/apps/httpd/fsdata.c deleted file mode 100644 index 6170ce63264583..00000000000000 --- a/third_party/lwip/repo/lwip/src/apps/httpd/fsdata.c +++ /dev/null @@ -1,298 +0,0 @@ -#include "lwip/apps/fs.h" -#include "lwip/def.h" -#include "fsdata.h" - - -#define file_NULL (struct fsdata_file *) NULL - - -static const unsigned int dummy_align__img_sics_gif = 0; -static const unsigned char data__img_sics_gif[] = { -/* /img/sics.gif (14 chars) */ -0x2f,0x69,0x6d,0x67,0x2f,0x73,0x69,0x63,0x73,0x2e,0x67,0x69,0x66,0x00,0x00,0x00, - -/* HTTP header */ -/* "HTTP/1.0 200 OK -" (17 bytes) */ -0x48,0x54,0x54,0x50,0x2f,0x31,0x2e,0x30,0x20,0x32,0x30,0x30,0x20,0x4f,0x4b,0x0d, -0x0a, -/* "Server: lwIP/1.3.1 (http://savannah.nongnu.org/projects/lwip) -" (63 bytes) */ -0x53,0x65,0x72,0x76,0x65,0x72,0x3a,0x20,0x6c,0x77,0x49,0x50,0x2f,0x31,0x2e,0x33, -0x2e,0x31,0x20,0x28,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x73,0x61,0x76,0x61,0x6e, -0x6e,0x61,0x68,0x2e,0x6e,0x6f,0x6e,0x67,0x6e,0x75,0x2e,0x6f,0x72,0x67,0x2f,0x70, -0x72,0x6f,0x6a,0x65,0x63,0x74,0x73,0x2f,0x6c,0x77,0x69,0x70,0x29,0x0d,0x0a, -/* "Content-type: image/gif - -" (27 bytes) */ -0x43,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x2d,0x74,0x79,0x70,0x65,0x3a,0x20,0x69,0x6d, -0x61,0x67,0x65,0x2f,0x67,0x69,0x66,0x0d,0x0a,0x0d,0x0a, -/* raw file data (724 bytes) */ -0x47,0x49,0x46,0x38,0x39,0x61,0x46,0x00,0x22,0x00,0xa5,0x00,0x00,0xd9,0x2b,0x39, -0x6a,0x6a,0x6a,0xbf,0xbf,0xbf,0x93,0x93,0x93,0x0f,0x0f,0x0f,0xb0,0xb0,0xb0,0xa6, -0xa6,0xa6,0x80,0x80,0x80,0x76,0x76,0x76,0x1e,0x1e,0x1e,0x9d,0x9d,0x9d,0x2e,0x2e, -0x2e,0x49,0x49,0x49,0x54,0x54,0x54,0x8a,0x8a,0x8a,0x60,0x60,0x60,0xc6,0xa6,0x99, -0xbd,0xb5,0xb2,0xc2,0xab,0xa1,0xd9,0x41,0x40,0xd5,0x67,0x55,0xc0,0xb0,0xaa,0xd5, -0x5e,0x4e,0xd6,0x50,0x45,0xcc,0x93,0x7d,0xc8,0xa1,0x90,0xce,0x8b,0x76,0xd2,0x7b, -0x65,0xd1,0x84,0x6d,0xc9,0x99,0x86,0x3a,0x3a,0x3a,0x00,0x00,0x00,0xb8,0xb8,0xb8, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x2c,0x00,0x00, -0x00,0x00,0x46,0x00,0x22,0x00,0x00,0x06,0xfe,0x40,0x90,0x70,0x48,0x2c,0x1a,0x8f, -0xc8,0xa4,0x72,0xc9,0x6c,0x3a,0x9f,0xd0,0xa8,0x74,0x4a,0xad,0x5a,0xaf,0xd8,0xac, -0x76,0xa9,0x40,0x04,0xbe,0x83,0xe2,0x60,0x3c,0x50,0x20,0x0d,0x8e,0x6f,0x00,0x31, -0x28,0x1c,0x0d,0x07,0xb5,0xc3,0x60,0x75,0x24,0x3e,0xf8,0xfc,0x87,0x11,0x06,0xe9, -0x3d,0x46,0x07,0x0b,0x7a,0x7a,0x7c,0x43,0x06,0x1e,0x84,0x78,0x0b,0x07,0x6e,0x51, -0x01,0x8a,0x84,0x08,0x7e,0x79,0x80,0x87,0x89,0x91,0x7a,0x93,0x0a,0x04,0x99,0x78, -0x96,0x4f,0x03,0x9e,0x79,0x01,0x94,0x9f,0x43,0x9c,0xa3,0xa4,0x05,0x77,0xa3,0xa0, -0x4e,0x98,0x79,0x0b,0x1e,0x83,0xa4,0xa6,0x1f,0x96,0x05,0x9d,0xaa,0x78,0x01,0x07, -0x84,0x04,0x1e,0x1e,0xbb,0xb8,0x51,0x84,0x0e,0x43,0x05,0x07,0x77,0xa5,0x7f,0x42, -0xb1,0xb2,0x01,0x63,0x08,0x0d,0xbb,0x01,0x0c,0x7a,0x0d,0x44,0x0e,0xd8,0xaf,0x4c, -0x05,0x7a,0x04,0x47,0x07,0x07,0xb7,0x80,0xa2,0xe1,0x7d,0x44,0x05,0x01,0x04,0x01, -0xd0,0xea,0x87,0x93,0x4f,0xe0,0x9a,0x49,0xce,0xd8,0x79,0x04,0x66,0x20,0x15,0x10, -0x10,0x11,0x92,0x29,0x80,0xb6,0xc0,0x91,0x15,0x45,0x1e,0x90,0x19,0x71,0x46,0xa8, -0x5c,0x04,0x0e,0x00,0x22,0x4e,0xe8,0x40,0x24,0x9f,0x3e,0x04,0x06,0xa7,0x58,0xd4, -0x93,0xa0,0x1c,0x91,0x3f,0xe8,0xf0,0x88,0x03,0xb1,0x21,0xa2,0x49,0x00,0x19,0x86, -0xfc,0x52,0x44,0xe0,0x01,0x9d,0x29,0x21,0x15,0x25,0x50,0xf7,0x67,0x25,0x1e,0x06, -0xfd,0x4e,0x9a,0xb4,0x90,0xac,0x15,0xfa,0xcb,0x52,0x53,0x1e,0x8c,0xf2,0xf8,0x07, -0x92,0x2d,0x08,0x3a,0x4d,0x12,0x49,0x95,0x49,0xdb,0x14,0x04,0xc4,0x14,0x85,0x29, -0xaa,0xe7,0x01,0x08,0xa4,0x49,0x01,0x14,0x51,0xe0,0x53,0x91,0xd5,0x29,0x06,0x1a, -0x64,0x02,0xf4,0xc7,0x81,0x9e,0x05,0x20,0x22,0x64,0xa5,0x30,0xae,0xab,0x9e,0x97, -0x53,0xd8,0xb9,0xfd,0x50,0xef,0x93,0x02,0x42,0x74,0x34,0xe8,0x9c,0x20,0x21,0xc9, -0x01,0x68,0x78,0xe6,0x55,0x29,0x20,0x56,0x4f,0x4c,0x40,0x51,0x71,0x82,0xc0,0x70, -0x21,0x22,0x85,0xbe,0x4b,0x1c,0x44,0x05,0xea,0xa4,0x01,0xbf,0x22,0xb5,0xf0,0x1c, -0x06,0x51,0x38,0x8f,0xe0,0x22,0xec,0x18,0xac,0x39,0x22,0xd4,0xd6,0x93,0x44,0x01, -0x32,0x82,0xc8,0xfc,0x61,0xb3,0x01,0x45,0x0c,0x2e,0x83,0x30,0xd0,0x0e,0x17,0x24, -0x0f,0x70,0x85,0x94,0xee,0x05,0x05,0x53,0x4b,0x32,0x1b,0x3f,0x98,0xd3,0x1d,0x29, -0x81,0xb0,0xae,0x1e,0x8c,0x7e,0x68,0xe0,0x60,0x5a,0x54,0x8f,0xb0,0x78,0x69,0x73, -0x06,0xa2,0x00,0x6b,0x57,0xca,0x3d,0x11,0x50,0xbd,0x04,0x30,0x4b,0x3a,0xd4,0xab, -0x5f,0x1f,0x9b,0x3d,0x13,0x74,0x27,0x88,0x3c,0x25,0xe0,0x17,0xbe,0x7a,0x79,0x45, -0x0d,0x0c,0xb0,0x8b,0xda,0x90,0xca,0x80,0x06,0x5d,0x17,0x60,0x1c,0x22,0x4c,0xd8, -0x57,0x22,0x06,0x20,0x00,0x98,0x07,0x08,0xe4,0x56,0x80,0x80,0x1c,0xc5,0xb7,0xc5, -0x82,0x0c,0x36,0xe8,0xe0,0x83,0x10,0x46,0x28,0xe1,0x84,0x14,0x56,0x68,0xa1,0x10, -0x41,0x00,0x00,0x3b,}; - -static const unsigned int dummy_align__404_html = 1; -static const unsigned char data__404_html[] = { -/* /404.html (10 chars) */ -0x2f,0x34,0x30,0x34,0x2e,0x68,0x74,0x6d,0x6c,0x00,0x00,0x00, - -/* HTTP header */ -/* "HTTP/1.0 404 File not found -" (29 bytes) */ -0x48,0x54,0x54,0x50,0x2f,0x31,0x2e,0x30,0x20,0x34,0x30,0x34,0x20,0x46,0x69,0x6c, -0x65,0x20,0x6e,0x6f,0x74,0x20,0x66,0x6f,0x75,0x6e,0x64,0x0d,0x0a, -/* "Server: lwIP/1.3.1 (http://savannah.nongnu.org/projects/lwip) -" (63 bytes) */ -0x53,0x65,0x72,0x76,0x65,0x72,0x3a,0x20,0x6c,0x77,0x49,0x50,0x2f,0x31,0x2e,0x33, -0x2e,0x31,0x20,0x28,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x73,0x61,0x76,0x61,0x6e, -0x6e,0x61,0x68,0x2e,0x6e,0x6f,0x6e,0x67,0x6e,0x75,0x2e,0x6f,0x72,0x67,0x2f,0x70, -0x72,0x6f,0x6a,0x65,0x63,0x74,0x73,0x2f,0x6c,0x77,0x69,0x70,0x29,0x0d,0x0a, -/* "Content-type: text/html - -" (27 bytes) */ -0x43,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x2d,0x74,0x79,0x70,0x65,0x3a,0x20,0x74,0x65, -0x78,0x74,0x2f,0x68,0x74,0x6d,0x6c,0x0d,0x0a,0x0d,0x0a, -/* raw file data (565 bytes) */ -0x3c,0x68,0x74,0x6d,0x6c,0x3e,0x0d,0x0a,0x3c,0x68,0x65,0x61,0x64,0x3e,0x3c,0x74, -0x69,0x74,0x6c,0x65,0x3e,0x6c,0x77,0x49,0x50,0x20,0x2d,0x20,0x41,0x20,0x4c,0x69, -0x67,0x68,0x74,0x77,0x65,0x69,0x67,0x68,0x74,0x20,0x54,0x43,0x50,0x2f,0x49,0x50, -0x20,0x53,0x74,0x61,0x63,0x6b,0x3c,0x2f,0x74,0x69,0x74,0x6c,0x65,0x3e,0x3c,0x2f, -0x68,0x65,0x61,0x64,0x3e,0x0d,0x0a,0x3c,0x62,0x6f,0x64,0x79,0x20,0x62,0x67,0x63, -0x6f,0x6c,0x6f,0x72,0x3d,0x22,0x77,0x68,0x69,0x74,0x65,0x22,0x20,0x74,0x65,0x78, -0x74,0x3d,0x22,0x62,0x6c,0x61,0x63,0x6b,0x22,0x3e,0x0d,0x0a,0x0d,0x0a,0x20,0x20, -0x20,0x20,0x3c,0x74,0x61,0x62,0x6c,0x65,0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22, -0x31,0x30,0x30,0x25,0x22,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x3c,0x74, -0x72,0x20,0x76,0x61,0x6c,0x69,0x67,0x6e,0x3d,0x22,0x74,0x6f,0x70,0x22,0x3e,0x3c, -0x74,0x64,0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22,0x38,0x30,0x22,0x3e,0x09,0x20, -0x20,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x68, -0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x73,0x69,0x63,0x73,0x2e,0x73, -0x65,0x2f,0x22,0x3e,0x3c,0x69,0x6d,0x67,0x20,0x73,0x72,0x63,0x3d,0x22,0x2f,0x69, -0x6d,0x67,0x2f,0x73,0x69,0x63,0x73,0x2e,0x67,0x69,0x66,0x22,0x0d,0x0a,0x09,0x20, -0x20,0x62,0x6f,0x72,0x64,0x65,0x72,0x3d,0x22,0x30,0x22,0x20,0x61,0x6c,0x74,0x3d, -0x22,0x53,0x49,0x43,0x53,0x20,0x6c,0x6f,0x67,0x6f,0x22,0x20,0x74,0x69,0x74,0x6c, -0x65,0x3d,0x22,0x53,0x49,0x43,0x53,0x20,0x6c,0x6f,0x67,0x6f,0x22,0x3e,0x3c,0x2f, -0x61,0x3e,0x0d,0x0a,0x09,0x3c,0x2f,0x74,0x64,0x3e,0x3c,0x74,0x64,0x20,0x77,0x69, -0x64,0x74,0x68,0x3d,0x22,0x35,0x30,0x30,0x22,0x3e,0x09,0x20,0x20,0x0d,0x0a,0x09, -0x20,0x20,0x3c,0x68,0x31,0x3e,0x6c,0x77,0x49,0x50,0x20,0x2d,0x20,0x41,0x20,0x4c, -0x69,0x67,0x68,0x74,0x77,0x65,0x69,0x67,0x68,0x74,0x20,0x54,0x43,0x50,0x2f,0x49, -0x50,0x20,0x53,0x74,0x61,0x63,0x6b,0x3c,0x2f,0x68,0x31,0x3e,0x0d,0x0a,0x09,0x20, -0x20,0x3c,0x68,0x32,0x3e,0x34,0x30,0x34,0x20,0x2d,0x20,0x50,0x61,0x67,0x65,0x20, -0x6e,0x6f,0x74,0x20,0x66,0x6f,0x75,0x6e,0x64,0x3c,0x2f,0x68,0x32,0x3e,0x0d,0x0a, -0x09,0x20,0x20,0x3c,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x53,0x6f,0x72, -0x72,0x79,0x2c,0x20,0x74,0x68,0x65,0x20,0x70,0x61,0x67,0x65,0x20,0x79,0x6f,0x75, -0x20,0x61,0x72,0x65,0x20,0x72,0x65,0x71,0x75,0x65,0x73,0x74,0x69,0x6e,0x67,0x20, -0x77,0x61,0x73,0x20,0x6e,0x6f,0x74,0x20,0x66,0x6f,0x75,0x6e,0x64,0x20,0x6f,0x6e, -0x20,0x74,0x68,0x69,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x73,0x65,0x72,0x76, -0x65,0x72,0x2e,0x20,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x2f,0x70,0x3e,0x0d,0x0a,0x09, -0x3c,0x2f,0x74,0x64,0x3e,0x3c,0x74,0x64,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x26,0x6e, -0x62,0x73,0x70,0x3b,0x0d,0x0a,0x09,0x3c,0x2f,0x74,0x64,0x3e,0x3c,0x2f,0x74,0x72, -0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x3c,0x2f,0x74,0x61,0x62,0x6c,0x65, -0x3e,0x0d,0x0a,0x3c,0x2f,0x62,0x6f,0x64,0x79,0x3e,0x0d,0x0a,0x3c,0x2f,0x68,0x74, -0x6d,0x6c,0x3e,0x0d,0x0a,}; - -static const unsigned int dummy_align__index_html = 2; -static const unsigned char data__index_html[] = { -/* /index.html (12 chars) */ -0x2f,0x69,0x6e,0x64,0x65,0x78,0x2e,0x68,0x74,0x6d,0x6c,0x00, - -/* HTTP header */ -/* "HTTP/1.0 200 OK -" (17 bytes) */ -0x48,0x54,0x54,0x50,0x2f,0x31,0x2e,0x30,0x20,0x32,0x30,0x30,0x20,0x4f,0x4b,0x0d, -0x0a, -/* "Server: lwIP/1.3.1 (http://savannah.nongnu.org/projects/lwip) -" (63 bytes) */ -0x53,0x65,0x72,0x76,0x65,0x72,0x3a,0x20,0x6c,0x77,0x49,0x50,0x2f,0x31,0x2e,0x33, -0x2e,0x31,0x20,0x28,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x73,0x61,0x76,0x61,0x6e, -0x6e,0x61,0x68,0x2e,0x6e,0x6f,0x6e,0x67,0x6e,0x75,0x2e,0x6f,0x72,0x67,0x2f,0x70, -0x72,0x6f,0x6a,0x65,0x63,0x74,0x73,0x2f,0x6c,0x77,0x69,0x70,0x29,0x0d,0x0a, -/* "Content-type: text/html - -" (27 bytes) */ -0x43,0x6f,0x6e,0x74,0x65,0x6e,0x74,0x2d,0x74,0x79,0x70,0x65,0x3a,0x20,0x74,0x65, -0x78,0x74,0x2f,0x68,0x74,0x6d,0x6c,0x0d,0x0a,0x0d,0x0a, -/* raw file data (1751 bytes) */ -0x3c,0x68,0x74,0x6d,0x6c,0x3e,0x0d,0x0a,0x3c,0x68,0x65,0x61,0x64,0x3e,0x3c,0x74, -0x69,0x74,0x6c,0x65,0x3e,0x6c,0x77,0x49,0x50,0x20,0x2d,0x20,0x41,0x20,0x4c,0x69, -0x67,0x68,0x74,0x77,0x65,0x69,0x67,0x68,0x74,0x20,0x54,0x43,0x50,0x2f,0x49,0x50, -0x20,0x53,0x74,0x61,0x63,0x6b,0x3c,0x2f,0x74,0x69,0x74,0x6c,0x65,0x3e,0x3c,0x2f, -0x68,0x65,0x61,0x64,0x3e,0x0d,0x0a,0x3c,0x62,0x6f,0x64,0x79,0x20,0x62,0x67,0x63, -0x6f,0x6c,0x6f,0x72,0x3d,0x22,0x77,0x68,0x69,0x74,0x65,0x22,0x20,0x74,0x65,0x78, -0x74,0x3d,0x22,0x62,0x6c,0x61,0x63,0x6b,0x22,0x3e,0x0d,0x0a,0x0d,0x0a,0x20,0x20, -0x20,0x20,0x3c,0x74,0x61,0x62,0x6c,0x65,0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22, -0x31,0x30,0x30,0x25,0x22,0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x3c,0x74, -0x72,0x20,0x76,0x61,0x6c,0x69,0x67,0x6e,0x3d,0x22,0x74,0x6f,0x70,0x22,0x3e,0x3c, -0x74,0x64,0x20,0x77,0x69,0x64,0x74,0x68,0x3d,0x22,0x38,0x30,0x22,0x3e,0x09,0x20, -0x20,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x61,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x68, -0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x73,0x69,0x63,0x73,0x2e,0x73, -0x65,0x2f,0x22,0x3e,0x3c,0x69,0x6d,0x67,0x20,0x73,0x72,0x63,0x3d,0x22,0x2f,0x69, -0x6d,0x67,0x2f,0x73,0x69,0x63,0x73,0x2e,0x67,0x69,0x66,0x22,0x0d,0x0a,0x09,0x20, -0x20,0x62,0x6f,0x72,0x64,0x65,0x72,0x3d,0x22,0x30,0x22,0x20,0x61,0x6c,0x74,0x3d, -0x22,0x53,0x49,0x43,0x53,0x20,0x6c,0x6f,0x67,0x6f,0x22,0x20,0x74,0x69,0x74,0x6c, -0x65,0x3d,0x22,0x53,0x49,0x43,0x53,0x20,0x6c,0x6f,0x67,0x6f,0x22,0x3e,0x3c,0x2f, -0x61,0x3e,0x0d,0x0a,0x09,0x3c,0x2f,0x74,0x64,0x3e,0x3c,0x74,0x64,0x20,0x77,0x69, -0x64,0x74,0x68,0x3d,0x22,0x35,0x30,0x30,0x22,0x3e,0x09,0x20,0x20,0x0d,0x0a,0x09, -0x20,0x20,0x3c,0x68,0x31,0x3e,0x6c,0x77,0x49,0x50,0x20,0x2d,0x20,0x41,0x20,0x4c, -0x69,0x67,0x68,0x74,0x77,0x65,0x69,0x67,0x68,0x74,0x20,0x54,0x43,0x50,0x2f,0x49, -0x50,0x20,0x53,0x74,0x61,0x63,0x6b,0x3c,0x2f,0x68,0x31,0x3e,0x0d,0x0a,0x09,0x20, -0x20,0x3c,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x54,0x68,0x65,0x20,0x77, -0x65,0x62,0x20,0x70,0x61,0x67,0x65,0x20,0x79,0x6f,0x75,0x20,0x61,0x72,0x65,0x20, -0x77,0x61,0x74,0x63,0x68,0x69,0x6e,0x67,0x20,0x77,0x61,0x73,0x20,0x73,0x65,0x72, -0x76,0x65,0x64,0x20,0x62,0x79,0x20,0x61,0x20,0x73,0x69,0x6d,0x70,0x6c,0x65,0x20, -0x77,0x65,0x62,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x73,0x65,0x72,0x76,0x65,0x72, -0x20,0x72,0x75,0x6e,0x6e,0x69,0x6e,0x67,0x20,0x6f,0x6e,0x20,0x74,0x6f,0x70,0x20, -0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x6c,0x69,0x67,0x68,0x74,0x77,0x65,0x69,0x67, -0x68,0x74,0x20,0x54,0x43,0x50,0x2f,0x49,0x50,0x20,0x73,0x74,0x61,0x63,0x6b,0x20, -0x3c,0x61,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x68, -0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77,0x77,0x2e,0x73,0x69,0x63,0x73,0x2e,0x73, -0x65,0x2f,0x7e,0x61,0x64,0x61,0x6d,0x2f,0x6c,0x77,0x69,0x70,0x2f,0x22,0x3e,0x6c, -0x77,0x49,0x50,0x3c,0x2f,0x61,0x3e,0x2e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x2f,0x70, -0x3e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20, -0x6c,0x77,0x49,0x50,0x20,0x69,0x73,0x20,0x61,0x6e,0x20,0x6f,0x70,0x65,0x6e,0x20, -0x73,0x6f,0x75,0x72,0x63,0x65,0x20,0x69,0x6d,0x70,0x6c,0x65,0x6d,0x65,0x6e,0x74, -0x61,0x74,0x69,0x6f,0x6e,0x20,0x6f,0x66,0x20,0x74,0x68,0x65,0x20,0x54,0x43,0x50, -0x2f,0x49,0x50,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x70,0x72,0x6f,0x74,0x6f,0x63, -0x6f,0x6c,0x20,0x73,0x75,0x69,0x74,0x65,0x20,0x74,0x68,0x61,0x74,0x20,0x77,0x61, -0x73,0x20,0x6f,0x72,0x69,0x67,0x69,0x6e,0x61,0x6c,0x6c,0x79,0x20,0x77,0x72,0x69, -0x74,0x74,0x65,0x6e,0x20,0x62,0x79,0x20,0x3c,0x61,0x0d,0x0a,0x09,0x20,0x20,0x20, -0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x77,0x77, -0x77,0x2e,0x73,0x69,0x63,0x73,0x2e,0x73,0x65,0x2f,0x7e,0x61,0x64,0x61,0x6d,0x2f, -0x6c,0x77,0x69,0x70,0x2f,0x22,0x3e,0x41,0x64,0x61,0x6d,0x20,0x44,0x75,0x6e,0x6b, -0x65,0x6c,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x6f,0x66,0x20,0x74,0x68,0x65, -0x20,0x53,0x77,0x65,0x64,0x69,0x73,0x68,0x20,0x49,0x6e,0x73,0x74,0x69,0x74,0x75, -0x74,0x65,0x20,0x6f,0x66,0x20,0x43,0x6f,0x6d,0x70,0x75,0x74,0x65,0x72,0x20,0x53, -0x63,0x69,0x65,0x6e,0x63,0x65,0x3c,0x2f,0x61,0x3e,0x20,0x62,0x75,0x74,0x20,0x6e, -0x6f,0x77,0x20,0x69,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x62,0x65,0x69,0x6e, -0x67,0x20,0x61,0x63,0x74,0x69,0x76,0x65,0x6c,0x79,0x20,0x64,0x65,0x76,0x65,0x6c, -0x6f,0x70,0x65,0x64,0x20,0x62,0x79,0x20,0x61,0x20,0x74,0x65,0x61,0x6d,0x20,0x6f, -0x66,0x20,0x64,0x65,0x76,0x65,0x6c,0x6f,0x70,0x65,0x72,0x73,0x0d,0x0a,0x09,0x20, -0x20,0x20,0x20,0x64,0x69,0x73,0x74,0x72,0x69,0x62,0x75,0x74,0x65,0x64,0x20,0x77, -0x6f,0x72,0x6c,0x64,0x2d,0x77,0x69,0x64,0x65,0x2e,0x20,0x53,0x69,0x6e,0x63,0x65, -0x20,0x69,0x74,0x27,0x73,0x20,0x72,0x65,0x6c,0x65,0x61,0x73,0x65,0x2c,0x20,0x6c, -0x77,0x49,0x50,0x20,0x68,0x61,0x73,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x73,0x70, -0x75,0x72,0x72,0x65,0x64,0x20,0x61,0x20,0x6c,0x6f,0x74,0x20,0x6f,0x66,0x20,0x69, -0x6e,0x74,0x65,0x72,0x65,0x73,0x74,0x20,0x61,0x6e,0x64,0x20,0x68,0x61,0x73,0x20, -0x62,0x65,0x65,0x6e,0x20,0x70,0x6f,0x72,0x74,0x65,0x64,0x20,0x74,0x6f,0x20,0x73, -0x65,0x76,0x65,0x72,0x61,0x6c,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x70,0x6c,0x61, -0x74,0x66,0x6f,0x72,0x6d,0x73,0x20,0x61,0x6e,0x64,0x20,0x6f,0x70,0x65,0x72,0x61, -0x74,0x69,0x6e,0x67,0x20,0x73,0x79,0x73,0x74,0x65,0x6d,0x73,0x2e,0x20,0x6c,0x77, -0x49,0x50,0x20,0x63,0x61,0x6e,0x20,0x62,0x65,0x20,0x75,0x73,0x65,0x64,0x20,0x65, -0x69,0x74,0x68,0x65,0x72,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x77,0x69,0x74,0x68, -0x20,0x6f,0x72,0x20,0x77,0x69,0x74,0x68,0x6f,0x75,0x74,0x20,0x61,0x6e,0x20,0x75, -0x6e,0x64,0x65,0x72,0x6c,0x79,0x69,0x6e,0x67,0x20,0x4f,0x53,0x2e,0x0d,0x0a,0x09, -0x20,0x20,0x3c,0x2f,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x70,0x3e,0x0d,0x0a, -0x09,0x20,0x20,0x20,0x20,0x54,0x68,0x65,0x20,0x66,0x6f,0x63,0x75,0x73,0x20,0x6f, -0x66,0x20,0x74,0x68,0x65,0x20,0x6c,0x77,0x49,0x50,0x20,0x54,0x43,0x50,0x2f,0x49, -0x50,0x20,0x69,0x6d,0x70,0x6c,0x65,0x6d,0x65,0x6e,0x74,0x61,0x74,0x69,0x6f,0x6e, -0x20,0x69,0x73,0x20,0x74,0x6f,0x20,0x72,0x65,0x64,0x75,0x63,0x65,0x0d,0x0a,0x09, -0x20,0x20,0x20,0x20,0x74,0x68,0x65,0x20,0x52,0x41,0x4d,0x20,0x75,0x73,0x61,0x67, -0x65,0x20,0x77,0x68,0x69,0x6c,0x65,0x20,0x73,0x74,0x69,0x6c,0x6c,0x20,0x68,0x61, -0x76,0x69,0x6e,0x67,0x20,0x61,0x20,0x66,0x75,0x6c,0x6c,0x20,0x73,0x63,0x61,0x6c, -0x65,0x20,0x54,0x43,0x50,0x2e,0x20,0x54,0x68,0x69,0x73,0x0d,0x0a,0x09,0x20,0x20, -0x20,0x20,0x6d,0x61,0x6b,0x65,0x73,0x20,0x6c,0x77,0x49,0x50,0x20,0x73,0x75,0x69, -0x74,0x61,0x62,0x6c,0x65,0x20,0x66,0x6f,0x72,0x20,0x75,0x73,0x65,0x20,0x69,0x6e, -0x20,0x65,0x6d,0x62,0x65,0x64,0x64,0x65,0x64,0x20,0x73,0x79,0x73,0x74,0x65,0x6d, -0x73,0x20,0x77,0x69,0x74,0x68,0x20,0x74,0x65,0x6e,0x73,0x0d,0x0a,0x09,0x20,0x20, -0x20,0x20,0x6f,0x66,0x20,0x6b,0x69,0x6c,0x6f,0x62,0x79,0x74,0x65,0x73,0x20,0x6f, -0x66,0x20,0x66,0x72,0x65,0x65,0x20,0x52,0x41,0x4d,0x20,0x61,0x6e,0x64,0x20,0x72, -0x6f,0x6f,0x6d,0x20,0x66,0x6f,0x72,0x20,0x61,0x72,0x6f,0x75,0x6e,0x64,0x20,0x34, -0x30,0x20,0x6b,0x69,0x6c,0x6f,0x62,0x79,0x74,0x65,0x73,0x0d,0x0a,0x09,0x20,0x20, -0x20,0x20,0x6f,0x66,0x20,0x63,0x6f,0x64,0x65,0x20,0x52,0x4f,0x4d,0x2e,0x0d,0x0a, -0x09,0x20,0x20,0x3c,0x2f,0x70,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x70,0x3e,0x0d, -0x0a,0x09,0x20,0x20,0x20,0x20,0x4d,0x6f,0x72,0x65,0x20,0x69,0x6e,0x66,0x6f,0x72, -0x6d,0x61,0x74,0x69,0x6f,0x6e,0x20,0x61,0x62,0x6f,0x75,0x74,0x20,0x6c,0x77,0x49, -0x50,0x20,0x63,0x61,0x6e,0x20,0x62,0x65,0x20,0x66,0x6f,0x75,0x6e,0x64,0x20,0x61, -0x74,0x20,0x74,0x68,0x65,0x20,0x6c,0x77,0x49,0x50,0x0d,0x0a,0x09,0x20,0x20,0x20, -0x20,0x68,0x6f,0x6d,0x65,0x70,0x61,0x67,0x65,0x20,0x61,0x74,0x20,0x3c,0x61,0x0d, -0x0a,0x09,0x20,0x20,0x20,0x20,0x68,0x72,0x65,0x66,0x3d,0x22,0x68,0x74,0x74,0x70, -0x3a,0x2f,0x2f,0x73,0x61,0x76,0x61,0x6e,0x6e,0x61,0x68,0x2e,0x6e,0x6f,0x6e,0x67, -0x6e,0x75,0x2e,0x6f,0x72,0x67,0x2f,0x70,0x72,0x6f,0x6a,0x65,0x63,0x74,0x73,0x2f, -0x6c,0x77,0x69,0x70,0x2f,0x22,0x3e,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x73,0x61, -0x76,0x61,0x6e,0x6e,0x61,0x68,0x2e,0x6e,0x6f,0x6e,0x67,0x6e,0x75,0x2e,0x6f,0x72, -0x67,0x2f,0x70,0x72,0x6f,0x6a,0x65,0x63,0x74,0x73,0x2f,0x6c,0x77,0x69,0x70,0x2f, -0x3c,0x2f,0x61,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x6f,0x72,0x20,0x61,0x74, -0x20,0x74,0x68,0x65,0x20,0x6c,0x77,0x49,0x50,0x20,0x77,0x69,0x6b,0x69,0x20,0x61, -0x74,0x20,0x3c,0x61,0x0d,0x0a,0x09,0x20,0x20,0x20,0x20,0x68,0x72,0x65,0x66,0x3d, -0x22,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f,0x6c,0x77,0x69,0x70,0x2e,0x77,0x69,0x6b, -0x69,0x61,0x2e,0x63,0x6f,0x6d,0x2f,0x22,0x3e,0x68,0x74,0x74,0x70,0x3a,0x2f,0x2f, -0x6c,0x77,0x69,0x70,0x2e,0x77,0x69,0x6b,0x69,0x61,0x2e,0x63,0x6f,0x6d,0x2f,0x3c, -0x2f,0x61,0x3e,0x2e,0x0d,0x0a,0x09,0x20,0x20,0x3c,0x2f,0x70,0x3e,0x0d,0x0a,0x09, -0x3c,0x2f,0x74,0x64,0x3e,0x3c,0x74,0x64,0x3e,0x0d,0x0a,0x09,0x20,0x20,0x26,0x6e, -0x62,0x73,0x70,0x3b,0x0d,0x0a,0x09,0x3c,0x2f,0x74,0x64,0x3e,0x3c,0x2f,0x74,0x72, -0x3e,0x0d,0x0a,0x20,0x20,0x20,0x20,0x20,0x20,0x3c,0x2f,0x74,0x61,0x62,0x6c,0x65, -0x3e,0x0d,0x0a,0x3c,0x2f,0x62,0x6f,0x64,0x79,0x3e,0x0d,0x0a,0x3c,0x2f,0x68,0x74, -0x6d,0x6c,0x3e,0x0d,0x0a,0x0d,0x0a,}; - - - -const struct fsdata_file file__img_sics_gif[] = { { -file_NULL, -data__img_sics_gif, -data__img_sics_gif + 16, -sizeof(data__img_sics_gif) - 16, -1, -}}; - -const struct fsdata_file file__404_html[] = { { -file__img_sics_gif, -data__404_html, -data__404_html + 12, -sizeof(data__404_html) - 12, -1, -}}; - -const struct fsdata_file file__index_html[] = { { -file__404_html, -data__index_html, -data__index_html + 12, -sizeof(data__index_html) - 12, -1, -}}; - -#define FS_ROOT file__index_html -#define FS_NUMFILES 3 - diff --git a/third_party/lwip/repo/lwip/src/apps/httpd/fsdata.h b/third_party/lwip/repo/lwip/src/apps/httpd/fsdata.h deleted file mode 100644 index ac4548c7857d5a..00000000000000 --- a/third_party/lwip/repo/lwip/src/apps/httpd/fsdata.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2001-2003 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_FSDATA_H -#define LWIP_FSDATA_H - -#include "lwip/apps/httpd_opts.h" -#include "lwip/apps/fs.h" - -struct fsdata_file { - const struct fsdata_file *next; - const unsigned char *name; - const unsigned char *data; - int len; - u8_t flags; -#if HTTPD_PRECALCULATED_CHECKSUM - u16_t chksum_count; - const struct fsdata_chksum *chksum; -#endif /* HTTPD_PRECALCULATED_CHECKSUM */ -}; - -#endif /* LWIP_FSDATA_H */ diff --git a/third_party/lwip/repo/lwip/src/apps/httpd/httpd.c b/third_party/lwip/repo/lwip/src/apps/httpd/httpd.c deleted file mode 100644 index 43195d7c54a344..00000000000000 --- a/third_party/lwip/repo/lwip/src/apps/httpd/httpd.c +++ /dev/null @@ -1,2629 +0,0 @@ -/** - * @file - * LWIP HTTP server implementation - */ - -/* - * Copyright (c) 2001-2003 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * Simon Goldschmidt - * - */ - -/** - * @defgroup httpd HTTP server - * @ingroup apps - * - * This httpd supports for a - * rudimentary server-side-include facility which will replace tags of the form - * in any file whose extension is .shtml, .shtm or .ssi with - * strings provided by an include handler whose pointer is provided to the - * module via function http_set_ssi_handler(). - * Additionally, a simple common - * gateway interface (CGI) handling mechanism has been added to allow clients - * to hook functions to particular request URIs. - * - * To enable SSI support, define label LWIP_HTTPD_SSI in lwipopts.h. - * To enable CGI support, define label LWIP_HTTPD_CGI in lwipopts.h. - * - * By default, the server assumes that HTTP headers are already present in - * each file stored in the file system. By defining LWIP_HTTPD_DYNAMIC_HEADERS in - * lwipopts.h, this behavior can be changed such that the server inserts the - * headers automatically based on the extension of the file being served. If - * this mode is used, be careful to ensure that the file system image used - * does not already contain the header information. - * - * File system images without headers can be created using the makefsfile - * tool with the -h command line option. - * - * - * Notes about valid SSI tags - * -------------------------- - * - * The following assumptions are made about tags used in SSI markers: - * - * 1. No tag may contain '-' or whitespace characters within the tag name. - * 2. Whitespace is allowed between the tag leadin "". - * 3. The maximum tag name length is LWIP_HTTPD_MAX_TAG_NAME_LEN, currently 8 characters. - * - * Notes on CGI usage - * ------------------ - * - * The simple CGI support offered here works with GET method requests only - * and can handle up to 16 parameters encoded into the URI. The handler - * function may not write directly to the HTTP output but must return a - * filename that the HTTP server will send to the browser as a response to - * the incoming CGI request. - * - * - * - * The list of supported file types is quite short, so if makefsdata complains - * about an unknown extension, make sure to add it (and its doctype) to - * the 'g_psHTTPHeaders' list. - */ -#include "lwip/init.h" -#include "lwip/apps/httpd.h" -#include "lwip/debug.h" -#include "lwip/stats.h" -#include "lwip/apps/fs.h" -#include "httpd_structs.h" -#include "lwip/def.h" -#include "lwip/ip.h" -#include "lwip/tcp.h" - -#include /* memset */ -#include /* atoi */ -#include - -#if LWIP_TCP && LWIP_CALLBACK_API - -/** Minimum length for a valid HTTP/0.9 request: "GET /\r\n" -> 7 bytes */ -#define MIN_REQ_LEN 7 - -#define CRLF "\r\n" -#if LWIP_HTTPD_SUPPORT_11_KEEPALIVE -#define HTTP11_CONNECTIONKEEPALIVE "Connection: keep-alive" -#define HTTP11_CONNECTIONKEEPALIVE2 "Connection: Keep-Alive" -#endif - -/** These defines check whether tcp_write has to copy data or not */ - -/** This was TI's check whether to let TCP copy data or not - * \#define HTTP_IS_DATA_VOLATILE(hs) ((hs->file < (char *)0x20000000) ? 0 : TCP_WRITE_FLAG_COPY) - */ -#ifndef HTTP_IS_DATA_VOLATILE -#if LWIP_HTTPD_SSI -/* Copy for SSI files, no copy for non-SSI files */ -#define HTTP_IS_DATA_VOLATILE(hs) ((hs)->ssi ? TCP_WRITE_FLAG_COPY : 0) -#else /* LWIP_HTTPD_SSI */ -/** Default: don't copy if the data is sent from file-system directly */ -#define HTTP_IS_DATA_VOLATILE(hs) (((hs->file != NULL) && (hs->handle != NULL) && (hs->file == \ - (const char*)hs->handle->data + hs->handle->len - hs->left)) \ - ? 0 : TCP_WRITE_FLAG_COPY) -#endif /* LWIP_HTTPD_SSI */ -#endif - -/** Default: headers are sent from ROM */ -#ifndef HTTP_IS_HDR_VOLATILE -#define HTTP_IS_HDR_VOLATILE(hs, ptr) 0 -#endif - -/* Return values for http_send_*() */ -#define HTTP_DATA_TO_SEND_BREAK 2 -#define HTTP_DATA_TO_SEND_CONTINUE 1 -#define HTTP_NO_DATA_TO_SEND 0 - -typedef struct -{ - const char *name; - u8_t shtml; -} default_filename; - -const default_filename g_psDefaultFilenames[] = { - {"/index.shtml", 1 }, - {"/index.ssi", 1 }, - {"/index.shtm", 1 }, - {"/index.html", 0 }, - {"/index.htm", 0 } -}; - -#define NUM_DEFAULT_FILENAMES (sizeof(g_psDefaultFilenames) / \ - sizeof(default_filename)) - -#if LWIP_HTTPD_SUPPORT_REQUESTLIST -/** HTTP request is copied here from pbufs for simple parsing */ -static char httpd_req_buf[LWIP_HTTPD_MAX_REQ_LENGTH+1]; -#endif /* LWIP_HTTPD_SUPPORT_REQUESTLIST */ - -#if LWIP_HTTPD_SUPPORT_POST -#if LWIP_HTTPD_POST_MAX_RESPONSE_URI_LEN > LWIP_HTTPD_MAX_REQUEST_URI_LEN -#define LWIP_HTTPD_URI_BUF_LEN LWIP_HTTPD_POST_MAX_RESPONSE_URI_LEN -#endif -#endif -#ifndef LWIP_HTTPD_URI_BUF_LEN -#define LWIP_HTTPD_URI_BUF_LEN LWIP_HTTPD_MAX_REQUEST_URI_LEN -#endif -#if LWIP_HTTPD_URI_BUF_LEN -/* Filename for response file to send when POST is finished or - * search for default files when a directory is requested. */ -static char http_uri_buf[LWIP_HTTPD_URI_BUF_LEN+1]; -#endif - -#if LWIP_HTTPD_DYNAMIC_HEADERS -/* The number of individual strings that comprise the headers sent before each - * requested file. - */ -#define NUM_FILE_HDR_STRINGS 5 -#define HDR_STRINGS_IDX_HTTP_STATUS 0 /* e.g. "HTTP/1.0 200 OK\r\n" */ -#define HDR_STRINGS_IDX_SERVER_NAME 1 /* e.g. "Server: "HTTPD_SERVER_AGENT"\r\n" */ -#define HDR_STRINGS_IDX_CONTENT_LEN_KEPALIVE 2 /* e.g. "Content-Length: xy\r\n" and/or "Connection: keep-alive\r\n" */ -#define HDR_STRINGS_IDX_CONTENT_LEN_NR 3 /* the byte count, when content-length is used */ -#define HDR_STRINGS_IDX_CONTENT_TYPE 4 /* the content type (or default answer content type including default document) */ - -/* The dynamically generated Content-Length buffer needs space for CRLF + NULL */ -#define LWIP_HTTPD_MAX_CONTENT_LEN_OFFSET 3 -#ifndef LWIP_HTTPD_MAX_CONTENT_LEN_SIZE -/* The dynamically generated Content-Length buffer shall be able to work with - ~953 MB (9 digits) */ -#define LWIP_HTTPD_MAX_CONTENT_LEN_SIZE (9 + LWIP_HTTPD_MAX_CONTENT_LEN_OFFSET) -#endif -#endif /* LWIP_HTTPD_DYNAMIC_HEADERS */ - -#if LWIP_HTTPD_SSI - -#define HTTPD_LAST_TAG_PART 0xFFFF - -enum tag_check_state { - TAG_NONE, /* Not processing an SSI tag */ - TAG_LEADIN, /* Tag lead in "" being processed */ - TAG_SENDING /* Sending tag replacement string */ -}; - -struct http_ssi_state { - const char *parsed; /* Pointer to the first unparsed byte in buf. */ -#if !LWIP_HTTPD_SSI_INCLUDE_TAG - const char *tag_started;/* Pointer to the first opening '<' of the tag. */ -#endif /* !LWIP_HTTPD_SSI_INCLUDE_TAG */ - const char *tag_end; /* Pointer to char after the closing '>' of the tag. */ - u32_t parse_left; /* Number of unparsed bytes in buf. */ - u16_t tag_index; /* Counter used by tag parsing state machine */ - u16_t tag_insert_len; /* Length of insert in string tag_insert */ -#if LWIP_HTTPD_SSI_MULTIPART - u16_t tag_part; /* Counter passed to and changed by tag insertion function to insert multiple times */ -#endif /* LWIP_HTTPD_SSI_MULTIPART */ - u8_t tag_name_len; /* Length of the tag name in string tag_name */ - char tag_name[LWIP_HTTPD_MAX_TAG_NAME_LEN + 1]; /* Last tag name extracted */ - char tag_insert[LWIP_HTTPD_MAX_TAG_INSERT_LEN + 1]; /* Insert string for tag_name */ - enum tag_check_state tag_state; /* State of the tag processor */ -}; -#endif /* LWIP_HTTPD_SSI */ - -struct http_state { -#if LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED - struct http_state *next; -#endif /* LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED */ - struct fs_file file_handle; - struct fs_file *handle; - const char *file; /* Pointer to first unsent byte in buf. */ - - struct tcp_pcb *pcb; -#if LWIP_HTTPD_SUPPORT_REQUESTLIST - struct pbuf *req; -#endif /* LWIP_HTTPD_SUPPORT_REQUESTLIST */ - -#if LWIP_HTTPD_DYNAMIC_FILE_READ - char *buf; /* File read buffer. */ - int buf_len; /* Size of file read buffer, buf. */ -#endif /* LWIP_HTTPD_DYNAMIC_FILE_READ */ - u32_t left; /* Number of unsent bytes in buf. */ - u8_t retries; -#if LWIP_HTTPD_SUPPORT_11_KEEPALIVE - u8_t keepalive; -#endif /* LWIP_HTTPD_SUPPORT_11_KEEPALIVE */ -#if LWIP_HTTPD_SSI - struct http_ssi_state *ssi; -#endif /* LWIP_HTTPD_SSI */ -#if LWIP_HTTPD_CGI - char *params[LWIP_HTTPD_MAX_CGI_PARAMETERS]; /* Params extracted from the request URI */ - char *param_vals[LWIP_HTTPD_MAX_CGI_PARAMETERS]; /* Values for each extracted param */ -#endif /* LWIP_HTTPD_CGI */ -#if LWIP_HTTPD_DYNAMIC_HEADERS - const char *hdrs[NUM_FILE_HDR_STRINGS]; /* HTTP headers to be sent. */ - char hdr_content_len[LWIP_HTTPD_MAX_CONTENT_LEN_SIZE]; - u16_t hdr_pos; /* The position of the first unsent header byte in the - current string */ - u16_t hdr_index; /* The index of the hdr string currently being sent. */ -#endif /* LWIP_HTTPD_DYNAMIC_HEADERS */ -#if LWIP_HTTPD_TIMING - u32_t time_started; -#endif /* LWIP_HTTPD_TIMING */ -#if LWIP_HTTPD_SUPPORT_POST - u32_t post_content_len_left; -#if LWIP_HTTPD_POST_MANUAL_WND - u32_t unrecved_bytes; - u8_t no_auto_wnd; - u8_t post_finished; -#endif /* LWIP_HTTPD_POST_MANUAL_WND */ -#endif /* LWIP_HTTPD_SUPPORT_POST*/ -}; - -#if HTTPD_USE_MEM_POOL -LWIP_MEMPOOL_DECLARE(HTTPD_STATE, MEMP_NUM_PARALLEL_HTTPD_CONNS, sizeof(struct http_state), "HTTPD_STATE") -#if LWIP_HTTPD_SSI -LWIP_MEMPOOL_DECLARE(HTTPD_SSI_STATE, MEMP_NUM_PARALLEL_HTTPD_SSI_CONNS, sizeof(struct http_ssi_state), "HTTPD_SSI_STATE") -#define HTTP_FREE_SSI_STATE(x) LWIP_MEMPOOL_FREE(HTTPD_SSI_STATE, (x)) -#define HTTP_ALLOC_SSI_STATE() (struct http_ssi_state *)LWIP_MEMPOOL_ALLOC(HTTPD_SSI_STATE) -#endif /* LWIP_HTTPD_SSI */ -#define HTTP_ALLOC_HTTP_STATE() (struct http_state *)LWIP_MEMPOOL_ALLOC(HTTPD_STATE) -#define HTTP_FREE_HTTP_STATE(x) LWIP_MEMPOOL_FREE(HTTPD_STATE, (x)) -#else /* HTTPD_USE_MEM_POOL */ -#define HTTP_ALLOC_HTTP_STATE() (struct http_state *)mem_malloc(sizeof(struct http_state)) -#define HTTP_FREE_HTTP_STATE(x) mem_free(x) -#if LWIP_HTTPD_SSI -#define HTTP_ALLOC_SSI_STATE() (struct http_ssi_state *)mem_malloc(sizeof(struct http_ssi_state)) -#define HTTP_FREE_SSI_STATE(x) mem_free(x) -#endif /* LWIP_HTTPD_SSI */ -#endif /* HTTPD_USE_MEM_POOL */ - -static err_t http_close_conn(struct tcp_pcb *pcb, struct http_state *hs); -static err_t http_close_or_abort_conn(struct tcp_pcb *pcb, struct http_state *hs, u8_t abort_conn); -static err_t http_find_file(struct http_state *hs, const char *uri, int is_09); -static err_t http_init_file(struct http_state *hs, struct fs_file *file, int is_09, const char *uri, u8_t tag_check, char* params); -static err_t http_poll(void *arg, struct tcp_pcb *pcb); -static u8_t http_check_eof(struct tcp_pcb *pcb, struct http_state *hs); -#if LWIP_HTTPD_FS_ASYNC_READ -static void http_continue(void *connection); -#endif /* LWIP_HTTPD_FS_ASYNC_READ */ - -#if LWIP_HTTPD_SSI -/* SSI insert handler function pointer. */ -tSSIHandler g_pfnSSIHandler; -#if !LWIP_HTTPD_SSI_RAW -int g_iNumTags; -const char **g_ppcTags; -#endif /* !LWIP_HTTPD_SSI_RAW */ - -#define LEN_TAG_LEAD_IN 5 -const char * const g_pcTagLeadIn = ""; -#endif /* LWIP_HTTPD_SSI */ - -#if LWIP_HTTPD_CGI -/* CGI handler information */ -const tCGI *g_pCGIs; -int g_iNumCGIs; -int http_cgi_paramcount; -#define http_cgi_params hs->params -#define http_cgi_param_vals hs->param_vals -#elif LWIP_HTTPD_CGI_SSI -char *http_cgi_params[LWIP_HTTPD_MAX_CGI_PARAMETERS]; /* Params extracted from the request URI */ -char *http_cgi_param_vals[LWIP_HTTPD_MAX_CGI_PARAMETERS]; /* Values for each extracted param */ -#endif /* LWIP_HTTPD_CGI */ - -#if LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED -/** global list of active HTTP connections, use to kill the oldest when - running out of memory */ -static struct http_state *http_connections; - -static void -http_add_connection(struct http_state *hs) -{ - /* add the connection to the list */ - hs->next = http_connections; - http_connections = hs; -} - -static void -http_remove_connection(struct http_state *hs) -{ - /* take the connection off the list */ - if (http_connections) { - if (http_connections == hs) { - http_connections = hs->next; - } else { - struct http_state *last; - for(last = http_connections; last->next != NULL; last = last->next) { - if (last->next == hs) { - last->next = hs->next; - break; - } - } - } - } -} - -static void -http_kill_oldest_connection(u8_t ssi_required) -{ - struct http_state *hs = http_connections; - struct http_state *hs_free_next = NULL; - while(hs && hs->next) { -#if LWIP_HTTPD_SSI - if (ssi_required) { - if (hs->next->ssi != NULL) { - hs_free_next = hs; - } - } else -#else /* LWIP_HTTPD_SSI */ - LWIP_UNUSED_ARG(ssi_required); -#endif /* LWIP_HTTPD_SSI */ - { - hs_free_next = hs; - } - LWIP_ASSERT("broken list", hs != hs->next); - hs = hs->next; - } - if (hs_free_next != NULL) { - LWIP_ASSERT("hs_free_next->next != NULL", hs_free_next->next != NULL); - LWIP_ASSERT("hs_free_next->next->pcb != NULL", hs_free_next->next->pcb != NULL); - /* send RST when killing a connection because of memory shortage */ - http_close_or_abort_conn(hs_free_next->next->pcb, hs_free_next->next, 1); /* this also unlinks the http_state from the list */ - } -} -#else /* LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED */ - -#define http_add_connection(hs) -#define http_remove_connection(hs) - -#endif /* LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED */ - -#if LWIP_HTTPD_SSI -/** Allocate as struct http_ssi_state. */ -static struct http_ssi_state* -http_ssi_state_alloc(void) -{ - struct http_ssi_state *ret = HTTP_ALLOC_SSI_STATE(); -#if LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED - if (ret == NULL) { - http_kill_oldest_connection(1); - ret = HTTP_ALLOC_SSI_STATE(); - } -#endif /* LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED */ - if (ret != NULL) { - memset(ret, 0, sizeof(struct http_ssi_state)); - } - return ret; -} - -/** Free a struct http_ssi_state. */ -static void -http_ssi_state_free(struct http_ssi_state *ssi) -{ - if (ssi != NULL) { - HTTP_FREE_SSI_STATE(ssi); - } -} -#endif /* LWIP_HTTPD_SSI */ - -/** Initialize a struct http_state. - */ -static void -http_state_init(struct http_state* hs) -{ - /* Initialize the structure. */ - memset(hs, 0, sizeof(struct http_state)); -#if LWIP_HTTPD_DYNAMIC_HEADERS - /* Indicate that the headers are not yet valid */ - hs->hdr_index = NUM_FILE_HDR_STRINGS; -#endif /* LWIP_HTTPD_DYNAMIC_HEADERS */ -} - -/** Allocate a struct http_state. */ -static struct http_state* -http_state_alloc(void) -{ - struct http_state *ret = HTTP_ALLOC_HTTP_STATE(); -#if LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED - if (ret == NULL) { - http_kill_oldest_connection(0); - ret = HTTP_ALLOC_HTTP_STATE(); - } -#endif /* LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED */ - if (ret != NULL) { - http_state_init(ret); - http_add_connection(ret); - } - return ret; -} - -/** Free a struct http_state. - * Also frees the file data if dynamic. - */ -static void -http_state_eof(struct http_state *hs) -{ - if(hs->handle) { -#if LWIP_HTTPD_TIMING - u32_t ms_needed = sys_now() - hs->time_started; - u32_t needed = LWIP_MAX(1, (ms_needed/100)); - LWIP_DEBUGF(HTTPD_DEBUG_TIMING, ("httpd: needed %"U32_F" ms to send file of %d bytes -> %"U32_F" bytes/sec\n", - ms_needed, hs->handle->len, ((((u32_t)hs->handle->len) * 10) / needed))); -#endif /* LWIP_HTTPD_TIMING */ - fs_close(hs->handle); - hs->handle = NULL; - } -#if LWIP_HTTPD_DYNAMIC_FILE_READ - if (hs->buf != NULL) { - mem_free(hs->buf); - hs->buf = NULL; - } -#endif /* LWIP_HTTPD_DYNAMIC_FILE_READ */ -#if LWIP_HTTPD_SSI - if (hs->ssi) { - http_ssi_state_free(hs->ssi); - hs->ssi = NULL; - } -#endif /* LWIP_HTTPD_SSI */ -#if LWIP_HTTPD_SUPPORT_REQUESTLIST - if (hs->req) { - pbuf_free(hs->req); - hs->req = NULL; - } -#endif /* LWIP_HTTPD_SUPPORT_REQUESTLIST */ -} - -/** Free a struct http_state. - * Also frees the file data if dynamic. - */ -static void -http_state_free(struct http_state *hs) -{ - if (hs != NULL) { - http_state_eof(hs); - http_remove_connection(hs); - HTTP_FREE_HTTP_STATE(hs); - } -} - -/** Call tcp_write() in a loop trying smaller and smaller length - * - * @param pcb tcp_pcb to send - * @param ptr Data to send - * @param length Length of data to send (in/out: on return, contains the - * amount of data sent) - * @param apiflags directly passed to tcp_write - * @return the return value of tcp_write - */ -static err_t -http_write(struct tcp_pcb *pcb, const void* ptr, u16_t *length, u8_t apiflags) -{ - u16_t len, max_len; - err_t err; - LWIP_ASSERT("length != NULL", length != NULL); - len = *length; - if (len == 0) { - return ERR_OK; - } - /* We cannot send more data than space available in the send buffer. */ - max_len = tcp_sndbuf(pcb); - if (max_len < len) { - len = max_len; - } -#ifdef HTTPD_MAX_WRITE_LEN - /* Additional limitation: e.g. don't enqueue more than 2*mss at once */ - max_len = HTTPD_MAX_WRITE_LEN(pcb); - if(len > max_len) { - len = max_len; - } -#endif /* HTTPD_MAX_WRITE_LEN */ - do { - LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("Trying go send %d bytes\n", len)); - err = tcp_write(pcb, ptr, len, apiflags); - if (err == ERR_MEM) { - if ((tcp_sndbuf(pcb) == 0) || - (tcp_sndqueuelen(pcb) >= TCP_SND_QUEUELEN)) { - /* no need to try smaller sizes */ - len = 1; - } else { - len /= 2; - } - LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, - ("Send failed, trying less (%d bytes)\n", len)); - } - } while ((err == ERR_MEM) && (len > 1)); - - if (err == ERR_OK) { - LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("Sent %d bytes\n", len)); - *length = len; - } else { - LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("Send failed with err %d (\"%s\")\n", err, lwip_strerr(err))); - *length = 0; - } - -#if LWIP_HTTPD_SUPPORT_11_KEEPALIVE - /* ensure nagle is normally enabled (only disabled for persistent connections - when all data has been enqueued but the connection stays open for the next - request */ - tcp_nagle_enable(pcb); -#endif - - return err; -} - -/** - * The connection shall be actively closed (using RST to close from fault states). - * Reset the sent- and recv-callbacks. - * - * @param pcb the tcp pcb to reset callbacks - * @param hs connection state to free - */ -static err_t -http_close_or_abort_conn(struct tcp_pcb *pcb, struct http_state *hs, u8_t abort_conn) -{ - err_t err; - LWIP_DEBUGF(HTTPD_DEBUG, ("Closing connection %p\n", (void*)pcb)); - -#if LWIP_HTTPD_SUPPORT_POST - if (hs != NULL) { - if ((hs->post_content_len_left != 0) -#if LWIP_HTTPD_POST_MANUAL_WND - || ((hs->no_auto_wnd != 0) && (hs->unrecved_bytes != 0)) -#endif /* LWIP_HTTPD_POST_MANUAL_WND */ - ) { - /* make sure the post code knows that the connection is closed */ - http_uri_buf[0] = 0; - httpd_post_finished(hs, http_uri_buf, LWIP_HTTPD_URI_BUF_LEN); - } - } -#endif /* LWIP_HTTPD_SUPPORT_POST*/ - - - tcp_arg(pcb, NULL); - tcp_recv(pcb, NULL); - tcp_err(pcb, NULL); - tcp_poll(pcb, NULL, 0); - tcp_sent(pcb, NULL); - if (hs != NULL) { - http_state_free(hs); - } - - if (abort_conn) { - tcp_abort(pcb); - return ERR_OK; - } - err = tcp_close(pcb); - if (err != ERR_OK) { - LWIP_DEBUGF(HTTPD_DEBUG, ("Error %d closing %p\n", err, (void*)pcb)); - /* error closing, try again later in poll */ - tcp_poll(pcb, http_poll, HTTPD_POLL_INTERVAL); - } - return err; -} - -/** - * The connection shall be actively closed. - * Reset the sent- and recv-callbacks. - * - * @param pcb the tcp pcb to reset callbacks - * @param hs connection state to free - */ -static err_t -http_close_conn(struct tcp_pcb *pcb, struct http_state *hs) -{ - return http_close_or_abort_conn(pcb, hs, 0); -} - -/** End of file: either close the connection (Connection: close) or - * close the file (Connection: keep-alive) - */ -static void -http_eof(struct tcp_pcb *pcb, struct http_state *hs) -{ - /* HTTP/1.1 persistent connection? (Not supported for SSI) */ -#if LWIP_HTTPD_SUPPORT_11_KEEPALIVE - if (hs->keepalive) { - http_remove_connection(hs); - - http_state_eof(hs); - http_state_init(hs); - /* restore state: */ - hs->pcb = pcb; - hs->keepalive = 1; - http_add_connection(hs); - /* ensure nagle doesn't interfere with sending all data as fast as possible: */ - tcp_nagle_disable(pcb); - } else -#endif /* LWIP_HTTPD_SUPPORT_11_KEEPALIVE */ - { - http_close_conn(pcb, hs); - } -} - -#if LWIP_HTTPD_CGI || LWIP_HTTPD_CGI_SSI -/** - * Extract URI parameters from the parameter-part of an URI in the form - * "test.cgi?x=y" @todo: better explanation! - * Pointers to the parameters are stored in hs->param_vals. - * - * @param hs http connection state - * @param params pointer to the NULL-terminated parameter string from the URI - * @return number of parameters extracted - */ -static int -extract_uri_parameters(struct http_state *hs, char *params) -{ - char *pair; - char *equals; - int loop; - - LWIP_UNUSED_ARG(hs); - - /* If we have no parameters at all, return immediately. */ - if(!params || (params[0] == '\0')) { - return(0); - } - - /* Get a pointer to our first parameter */ - pair = params; - - /* Parse up to LWIP_HTTPD_MAX_CGI_PARAMETERS from the passed string and ignore the - * remainder (if any) */ - for(loop = 0; (loop < LWIP_HTTPD_MAX_CGI_PARAMETERS) && pair; loop++) { - - /* Save the name of the parameter */ - http_cgi_params[loop] = pair; - - /* Remember the start of this name=value pair */ - equals = pair; - - /* Find the start of the next name=value pair and replace the delimiter - * with a 0 to terminate the previous pair string. */ - pair = strchr(pair, '&'); - if(pair) { - *pair = '\0'; - pair++; - } else { - /* We didn't find a new parameter so find the end of the URI and - * replace the space with a '\0' */ - pair = strchr(equals, ' '); - if(pair) { - *pair = '\0'; - } - - /* Revert to NULL so that we exit the loop as expected. */ - pair = NULL; - } - - /* Now find the '=' in the previous pair, replace it with '\0' and save - * the parameter value string. */ - equals = strchr(equals, '='); - if(equals) { - *equals = '\0'; - http_cgi_param_vals[loop] = equals + 1; - } else { - http_cgi_param_vals[loop] = NULL; - } - } - - return loop; -} -#endif /* LWIP_HTTPD_CGI || LWIP_HTTPD_CGI_SSI */ - -#if LWIP_HTTPD_SSI -/** - * Insert a tag (found in an shtml in the form of "" into the file. - * The tag's name is stored in ssi->tag_name (NULL-terminated), the replacement - * should be written to hs->tag_insert (up to a length of LWIP_HTTPD_MAX_TAG_INSERT_LEN). - * The amount of data written is stored to ssi->tag_insert_len. - * - * @todo: return tag_insert_len - maybe it can be removed from struct http_state? - * - * @param hs http connection state - */ -static void -get_tag_insert(struct http_state *hs) -{ -#if LWIP_HTTPD_SSI_RAW - const char* tag; -#else /* LWIP_HTTPD_SSI_RAW */ - int tag; -#endif /* LWIP_HTTPD_SSI_RAW */ - size_t len; - struct http_ssi_state *ssi; -#if LWIP_HTTPD_SSI_MULTIPART - u16_t current_tag_part; -#endif /* LWIP_HTTPD_SSI_MULTIPART */ - - LWIP_ASSERT("hs != NULL", hs != NULL); - ssi = hs->ssi; - LWIP_ASSERT("ssi != NULL", ssi != NULL); -#if LWIP_HTTPD_SSI_MULTIPART - current_tag_part = ssi->tag_part; - ssi->tag_part = HTTPD_LAST_TAG_PART; -#endif /* LWIP_HTTPD_SSI_MULTIPART */ -#if LWIP_HTTPD_SSI_RAW - tag = ssi->tag_name; -#endif - - if(g_pfnSSIHandler -#if !LWIP_HTTPD_SSI_RAW - && g_ppcTags && g_iNumTags -#endif /* !LWIP_HTTPD_SSI_RAW */ - ) { - - /* Find this tag in the list we have been provided. */ -#if LWIP_HTTPD_SSI_RAW - { -#else /* LWIP_HTTPD_SSI_RAW */ - for(tag = 0; tag < g_iNumTags; tag++) { - if(strcmp(ssi->tag_name, g_ppcTags[tag]) == 0) -#endif /* LWIP_HTTPD_SSI_RAW */ - { - ssi->tag_insert_len = g_pfnSSIHandler(tag, ssi->tag_insert, - LWIP_HTTPD_MAX_TAG_INSERT_LEN -#if LWIP_HTTPD_SSI_MULTIPART - , current_tag_part, &ssi->tag_part -#endif /* LWIP_HTTPD_SSI_MULTIPART */ -#if LWIP_HTTPD_FILE_STATE - , (hs->handle ? hs->handle->state : NULL) -#endif /* LWIP_HTTPD_FILE_STATE */ - ); -#if LWIP_HTTPD_SSI_RAW - if (ssi->tag_insert_len != HTTPD_SSI_TAG_UNKNOWN) -#endif /* LWIP_HTTPD_SSI_RAW */ - { - return; - } - } - } - } - - /* If we drop out, we were asked to serve a page which contains tags that - * we don't have a handler for. Merely echo back the tags with an error - * marker. */ -#define UNKNOWN_TAG1_TEXT "***UNKNOWN TAG " -#define UNKNOWN_TAG1_LEN 18 -#define UNKNOWN_TAG2_TEXT "***" -#define UNKNOWN_TAG2_LEN 7 - len = LWIP_MIN(sizeof(ssi->tag_name), LWIP_MIN(strlen(ssi->tag_name), - LWIP_HTTPD_MAX_TAG_INSERT_LEN - (UNKNOWN_TAG1_LEN + UNKNOWN_TAG2_LEN))); - MEMCPY(ssi->tag_insert, UNKNOWN_TAG1_TEXT, UNKNOWN_TAG1_LEN); - MEMCPY(&ssi->tag_insert[UNKNOWN_TAG1_LEN], ssi->tag_name, len); - MEMCPY(&ssi->tag_insert[UNKNOWN_TAG1_LEN + len], UNKNOWN_TAG2_TEXT, UNKNOWN_TAG2_LEN); - ssi->tag_insert[UNKNOWN_TAG1_LEN + len + UNKNOWN_TAG2_LEN] = 0; - - len = strlen(ssi->tag_insert); - LWIP_ASSERT("len <= 0xffff", len <= 0xffff); - ssi->tag_insert_len = (u16_t)len; -} -#endif /* LWIP_HTTPD_SSI */ - -#if LWIP_HTTPD_DYNAMIC_HEADERS -/** - * Generate the relevant HTTP headers for the given filename and write - * them into the supplied buffer. - */ -static void -get_http_headers(struct http_state *hs, const char *uri) -{ - size_t content_type; - char *tmp; - char *ext; - char *vars; - u8_t add_content_len; - - /* In all cases, the second header we send is the server identification - so set it here. */ - hs->hdrs[HDR_STRINGS_IDX_SERVER_NAME] = g_psHTTPHeaderStrings[HTTP_HDR_SERVER]; - hs->hdrs[HDR_STRINGS_IDX_CONTENT_LEN_KEPALIVE] = NULL; - hs->hdrs[HDR_STRINGS_IDX_CONTENT_LEN_NR] = NULL; - - /* Is this a normal file or the special case we use to send back the - default "404: Page not found" response? */ - if (uri == NULL) { - hs->hdrs[HDR_STRINGS_IDX_HTTP_STATUS] = g_psHTTPHeaderStrings[HTTP_HDR_NOT_FOUND]; -#if LWIP_HTTPD_SUPPORT_11_KEEPALIVE - if (hs->keepalive) { - hs->hdrs[HDR_STRINGS_IDX_CONTENT_TYPE] = g_psHTTPHeaderStrings[DEFAULT_404_HTML_PERSISTENT]; - } else -#endif - { - hs->hdrs[HDR_STRINGS_IDX_CONTENT_TYPE] = g_psHTTPHeaderStrings[DEFAULT_404_HTML]; - } - - /* Set up to send the first header string. */ - hs->hdr_index = 0; - hs->hdr_pos = 0; - return; - } - /* We are dealing with a particular filename. Look for one other - special case. We assume that any filename with "404" in it must be - indicative of a 404 server error whereas all other files require - the 200 OK header. */ - if (strstr(uri, "404")) { - hs->hdrs[HDR_STRINGS_IDX_HTTP_STATUS] = g_psHTTPHeaderStrings[HTTP_HDR_NOT_FOUND]; - } else if (strstr(uri, "400")) { - hs->hdrs[HDR_STRINGS_IDX_HTTP_STATUS] = g_psHTTPHeaderStrings[HTTP_HDR_BAD_REQUEST]; - } else if (strstr(uri, "501")) { - hs->hdrs[HDR_STRINGS_IDX_HTTP_STATUS] = g_psHTTPHeaderStrings[HTTP_HDR_NOT_IMPL]; - } else { - hs->hdrs[HDR_STRINGS_IDX_HTTP_STATUS] = g_psHTTPHeaderStrings[HTTP_HDR_OK]; - } - - /* Determine if the URI has any variables and, if so, temporarily remove - them. */ - vars = strchr(uri, '?'); - if(vars) { - *vars = '\0'; - } - - /* Get a pointer to the file extension. We find this by looking for the - last occurrence of "." in the filename passed. */ - ext = NULL; - tmp = strchr(uri, '.'); - while (tmp) { - ext = tmp + 1; - tmp = strchr(ext, '.'); - } - if (ext != NULL) { - /* Now determine the content type and add the relevant header for that. */ - for (content_type = 0; content_type < NUM_HTTP_HEADERS; content_type++) { - /* Have we found a matching extension? */ - if(!lwip_stricmp(g_psHTTPHeaders[content_type].extension, ext)) { - break; - } - } - } else { - content_type = NUM_HTTP_HEADERS; - } - - /* Reinstate the parameter marker if there was one in the original URI. */ - if (vars) { - *vars = '?'; - } - -#if LWIP_HTTPD_OMIT_HEADER_FOR_EXTENSIONLESS_URI - /* Does the URL passed have any file extension? If not, we assume it - is a special-case URL used for control state notification and we do - not send any HTTP headers with the response. */ - if (!ext) { - /* Force the header index to a value indicating that all headers - have already been sent. */ - hs->hdr_index = NUM_FILE_HDR_STRINGS; - return; - } -#endif /* LWIP_HTTPD_OMIT_HEADER_FOR_EXTENSIONLESS_URI */ - add_content_len = 1; - /* Did we find a matching extension? */ - if(content_type < NUM_HTTP_HEADERS) { - /* yes, store it */ - hs->hdrs[HDR_STRINGS_IDX_CONTENT_TYPE] = g_psHTTPHeaders[content_type].content_type; - } else if (!ext) { - /* no, no extension found -> use binary transfer to prevent the browser adding '.txt' on save */ - hs->hdrs[HDR_STRINGS_IDX_CONTENT_TYPE] = HTTP_HDR_APP; - } else { - /* No - use the default, plain text file type. */ - hs->hdrs[HDR_STRINGS_IDX_CONTENT_TYPE] = HTTP_HDR_DEFAULT_TYPE; - } - /* Add content-length header? */ -#if LWIP_HTTPD_SSI - if (hs->ssi != NULL) { - add_content_len = 0; /* @todo: get maximum file length from SSI */ - } else -#endif /* LWIP_HTTPD_SSI */ - if ((hs->handle == NULL) || - ((hs->handle->flags & (FS_FILE_FLAGS_HEADER_INCLUDED|FS_FILE_FLAGS_HEADER_PERSISTENT)) == FS_FILE_FLAGS_HEADER_INCLUDED)) { - add_content_len = 0; - } - if (add_content_len) { - size_t len; - lwip_itoa(hs->hdr_content_len, (size_t)LWIP_HTTPD_MAX_CONTENT_LEN_SIZE, - hs->handle->len); - len = strlen(hs->hdr_content_len); - if (len <= LWIP_HTTPD_MAX_CONTENT_LEN_SIZE - LWIP_HTTPD_MAX_CONTENT_LEN_OFFSET) { - SMEMCPY(&hs->hdr_content_len[len], CRLF "\0", 3); - hs->hdrs[HDR_STRINGS_IDX_CONTENT_LEN_NR] = hs->hdr_content_len; - } else { - add_content_len = 0; - } - } -#if LWIP_HTTPD_SUPPORT_11_KEEPALIVE - if (add_content_len) { - hs->hdrs[HDR_STRINGS_IDX_CONTENT_LEN_KEPALIVE] = g_psHTTPHeaderStrings[HTTP_HDR_KEEPALIVE_LEN]; - } else { - hs->hdrs[HDR_STRINGS_IDX_CONTENT_LEN_KEPALIVE] = g_psHTTPHeaderStrings[HTTP_HDR_CONN_CLOSE]; - } -#else /* LWIP_HTTPD_SUPPORT_11_KEEPALIVE */ - if (add_content_len) { - hs->hdrs[HDR_STRINGS_IDX_CONTENT_LEN_KEPALIVE] = g_psHTTPHeaderStrings[HTTP_HDR_CONTENT_LENGTH]; - } -#endif /* LWIP_HTTPD_SUPPORT_11_KEEPALIVE */ - - /* Set up to send the first header string. */ - hs->hdr_index = 0; - hs->hdr_pos = 0; -} - -/** Sub-function of http_send(): send dynamic headers - * - * @returns: - HTTP_NO_DATA_TO_SEND: no new data has been enqueued - * - HTTP_DATA_TO_SEND_CONTINUE: continue with sending HTTP body - * - HTTP_DATA_TO_SEND_BREAK: data has been enqueued, headers pending, - * so don't send HTTP body yet - */ -static u8_t -http_send_headers(struct tcp_pcb *pcb, struct http_state *hs) -{ - err_t err; - u16_t len; - u8_t data_to_send = HTTP_NO_DATA_TO_SEND; - u16_t hdrlen, sendlen; - - /* How much data can we send? */ - len = tcp_sndbuf(pcb); - sendlen = len; - - while(len && (hs->hdr_index < NUM_FILE_HDR_STRINGS) && sendlen) { - const void *ptr; - u16_t old_sendlen; - u8_t apiflags; - /* How much do we have to send from the current header? */ - hdrlen = (u16_t)strlen(hs->hdrs[hs->hdr_index]); - - /* How much of this can we send? */ - sendlen = (len < (hdrlen - hs->hdr_pos)) ? len : (hdrlen - hs->hdr_pos); - - /* Send this amount of data or as much as we can given memory - * constraints. */ - ptr = (const void *)(hs->hdrs[hs->hdr_index] + hs->hdr_pos); - old_sendlen = sendlen; - apiflags = HTTP_IS_HDR_VOLATILE(hs, ptr); - if (hs->hdr_index == HDR_STRINGS_IDX_CONTENT_LEN_NR) { - /* content-length is always volatile */ - apiflags |= TCP_WRITE_FLAG_COPY; - } - if (hs->hdr_index < NUM_FILE_HDR_STRINGS - 1) { - apiflags |= TCP_WRITE_FLAG_MORE; - } - err = http_write(pcb, ptr, &sendlen, apiflags); - if ((err == ERR_OK) && (old_sendlen != sendlen)) { - /* Remember that we added some more data to be transmitted. */ - data_to_send = HTTP_DATA_TO_SEND_CONTINUE; - } else if (err != ERR_OK) { - /* special case: http_write does not try to send 1 byte */ - sendlen = 0; - } - - /* Fix up the header position for the next time round. */ - hs->hdr_pos += sendlen; - len -= sendlen; - - /* Have we finished sending this string? */ - if(hs->hdr_pos == hdrlen) { - /* Yes - move on to the next one */ - hs->hdr_index++; - /* skip headers that are NULL (not all headers are required) */ - while ((hs->hdr_index < NUM_FILE_HDR_STRINGS) && - (hs->hdrs[hs->hdr_index] == NULL)) { - hs->hdr_index++; - } - hs->hdr_pos = 0; - } - } - - if ((hs->hdr_index >= NUM_FILE_HDR_STRINGS) && (hs->file == NULL)) { - /* When we are at the end of the headers, check for data to send - * instead of waiting for ACK from remote side to continue - * (which would happen when sending files from async read). */ - if(http_check_eof(pcb, hs)) { - data_to_send = HTTP_DATA_TO_SEND_CONTINUE; - } - } - /* If we get here and there are still header bytes to send, we send - * the header information we just wrote immediately. If there are no - * more headers to send, but we do have file data to send, drop through - * to try to send some file data too. */ - if((hs->hdr_index < NUM_FILE_HDR_STRINGS) || !hs->file) { - LWIP_DEBUGF(HTTPD_DEBUG, ("tcp_output\n")); - return HTTP_DATA_TO_SEND_BREAK; - } - return data_to_send; -} -#endif /* LWIP_HTTPD_DYNAMIC_HEADERS */ - -/** Sub-function of http_send(): end-of-file (or block) is reached, - * either close the file or read the next block (if supported). - * - * @returns: 0 if the file is finished or no data has been read - * 1 if the file is not finished and data has been read - */ -static u8_t -http_check_eof(struct tcp_pcb *pcb, struct http_state *hs) -{ - int bytes_left; -#if LWIP_HTTPD_DYNAMIC_FILE_READ - int count; -#ifdef HTTPD_MAX_WRITE_LEN - int max_write_len; -#endif /* HTTPD_MAX_WRITE_LEN */ -#endif /* LWIP_HTTPD_DYNAMIC_FILE_READ */ - - /* Do we have a valid file handle? */ - if (hs->handle == NULL) { - /* No - close the connection. */ - http_eof(pcb, hs); - return 0; - } - bytes_left = fs_bytes_left(hs->handle); - if (bytes_left <= 0) { - /* We reached the end of the file so this request is done. */ - LWIP_DEBUGF(HTTPD_DEBUG, ("End of file.\n")); - http_eof(pcb, hs); - return 0; - } -#if LWIP_HTTPD_DYNAMIC_FILE_READ - /* Do we already have a send buffer allocated? */ - if(hs->buf) { - /* Yes - get the length of the buffer */ - count = LWIP_MIN(hs->buf_len, bytes_left); - } else { - /* We don't have a send buffer so allocate one now */ - count = tcp_sndbuf(pcb); - if(bytes_left < count) { - count = bytes_left; - } -#ifdef HTTPD_MAX_WRITE_LEN - /* Additional limitation: e.g. don't enqueue more than 2*mss at once */ - max_write_len = HTTPD_MAX_WRITE_LEN(pcb); - if (count > max_write_len) { - count = max_write_len; - } -#endif /* HTTPD_MAX_WRITE_LEN */ - do { - hs->buf = (char*)mem_malloc((mem_size_t)count); - if (hs->buf != NULL) { - hs->buf_len = count; - break; - } - count = count / 2; - } while (count > 100); - - /* Did we get a send buffer? If not, return immediately. */ - if (hs->buf == NULL) { - LWIP_DEBUGF(HTTPD_DEBUG, ("No buff\n")); - return 0; - } - } - - /* Read a block of data from the file. */ - LWIP_DEBUGF(HTTPD_DEBUG, ("Trying to read %d bytes.\n", count)); - -#if LWIP_HTTPD_FS_ASYNC_READ - count = fs_read_async(hs->handle, hs->buf, count, http_continue, hs); -#else /* LWIP_HTTPD_FS_ASYNC_READ */ - count = fs_read(hs->handle, hs->buf, count); -#endif /* LWIP_HTTPD_FS_ASYNC_READ */ - if (count < 0) { - if (count == FS_READ_DELAYED) { - /* Delayed read, wait for FS to unblock us */ - return 0; - } - /* We reached the end of the file so this request is done. - * @todo: close here for HTTP/1.1 when reading file fails */ - LWIP_DEBUGF(HTTPD_DEBUG, ("End of file.\n")); - http_eof(pcb, hs); - return 0; - } - - /* Set up to send the block of data we just read */ - LWIP_DEBUGF(HTTPD_DEBUG, ("Read %d bytes.\n", count)); - hs->left = count; - hs->file = hs->buf; -#if LWIP_HTTPD_SSI - if (hs->ssi) { - hs->ssi->parse_left = count; - hs->ssi->parsed = hs->buf; - } -#endif /* LWIP_HTTPD_SSI */ -#else /* LWIP_HTTPD_DYNAMIC_FILE_READ */ - LWIP_ASSERT("SSI and DYNAMIC_HEADERS turned off but eof not reached", 0); -#endif /* LWIP_HTTPD_SSI || LWIP_HTTPD_DYNAMIC_HEADERS */ - return 1; -} - -/** Sub-function of http_send(): This is the normal send-routine for non-ssi files - * - * @returns: - 1: data has been written (so call tcp_ouput) - * - 0: no data has been written (no need to call tcp_output) - */ -static u8_t -http_send_data_nonssi(struct tcp_pcb *pcb, struct http_state *hs) -{ - err_t err; - u16_t len; - u8_t data_to_send = 0; - - /* We are not processing an SHTML file so no tag checking is necessary. - * Just send the data as we received it from the file. */ - len = (u16_t)LWIP_MIN(hs->left, 0xffff); - - err = http_write(pcb, hs->file, &len, HTTP_IS_DATA_VOLATILE(hs)); - if (err == ERR_OK) { - data_to_send = 1; - hs->file += len; - hs->left -= len; - } - - return data_to_send; -} - -#if LWIP_HTTPD_SSI -/** Sub-function of http_send(): This is the send-routine for ssi files - * - * @returns: - 1: data has been written (so call tcp_ouput) - * - 0: no data has been written (no need to call tcp_output) - */ -static u8_t -http_send_data_ssi(struct tcp_pcb *pcb, struct http_state *hs) -{ - err_t err = ERR_OK; - u16_t len; - u8_t data_to_send = 0; - - struct http_ssi_state *ssi = hs->ssi; - LWIP_ASSERT("ssi != NULL", ssi != NULL); - /* We are processing an SHTML file so need to scan for tags and replace - * them with insert strings. We need to be careful here since a tag may - * straddle the boundary of two blocks read from the file and we may also - * have to split the insert string between two tcp_write operations. */ - - /* How much data could we send? */ - len = tcp_sndbuf(pcb); - - /* Do we have remaining data to send before parsing more? */ - if(ssi->parsed > hs->file) { - len = (u16_t)LWIP_MIN(ssi->parsed - hs->file, 0xffff); - - err = http_write(pcb, hs->file, &len, HTTP_IS_DATA_VOLATILE(hs)); - if (err == ERR_OK) { - data_to_send = 1; - hs->file += len; - hs->left -= len; - } - - /* If the send buffer is full, return now. */ - if(tcp_sndbuf(pcb) == 0) { - return data_to_send; - } - } - - LWIP_DEBUGF(HTTPD_DEBUG, ("State %d, %d left\n", ssi->tag_state, (int)ssi->parse_left)); - - /* We have sent all the data that was already parsed so continue parsing - * the buffer contents looking for SSI tags. */ - while((ssi->parse_left) && (err == ERR_OK)) { - if (len == 0) { - return data_to_send; - } - switch(ssi->tag_state) { - case TAG_NONE: - /* We are not currently processing an SSI tag so scan for the - * start of the lead-in marker. */ - if(*ssi->parsed == g_pcTagLeadIn[0]) { - /* We found what could be the lead-in for a new tag so change - * state appropriately. */ - ssi->tag_state = TAG_LEADIN; - ssi->tag_index = 1; -#if !LWIP_HTTPD_SSI_INCLUDE_TAG - ssi->tag_started = ssi->parsed; -#endif /* !LWIP_HTTPD_SSI_INCLUDE_TAG */ - } - - /* Move on to the next character in the buffer */ - ssi->parse_left--; - ssi->parsed++; - break; - - case TAG_LEADIN: - /* We are processing the lead-in marker, looking for the start of - * the tag name. */ - - /* Have we reached the end of the leadin? */ - if(ssi->tag_index == LEN_TAG_LEAD_IN) { - ssi->tag_index = 0; - ssi->tag_state = TAG_FOUND; - } else { - /* Have we found the next character we expect for the tag leadin? */ - if(*ssi->parsed == g_pcTagLeadIn[ssi->tag_index]) { - /* Yes - move to the next one unless we have found the complete - * leadin, in which case we start looking for the tag itself */ - ssi->tag_index++; - } else { - /* We found an unexpected character so this is not a tag. Move - * back to idle state. */ - ssi->tag_state = TAG_NONE; - } - - /* Move on to the next character in the buffer */ - ssi->parse_left--; - ssi->parsed++; - } - break; - - case TAG_FOUND: - /* We are reading the tag name, looking for the start of the - * lead-out marker and removing any whitespace found. */ - - /* Remove leading whitespace between the tag leading and the first - * tag name character. */ - if((ssi->tag_index == 0) && ((*ssi->parsed == ' ') || - (*ssi->parsed == '\t') || (*ssi->parsed == '\n') || - (*ssi->parsed == '\r'))) { - /* Move on to the next character in the buffer */ - ssi->parse_left--; - ssi->parsed++; - break; - } - - /* Have we found the end of the tag name? This is signalled by - * us finding the first leadout character or whitespace */ - if((*ssi->parsed == g_pcTagLeadOut[0]) || - (*ssi->parsed == ' ') || (*ssi->parsed == '\t') || - (*ssi->parsed == '\n') || (*ssi->parsed == '\r')) { - - if(ssi->tag_index == 0) { - /* We read a zero length tag so ignore it. */ - ssi->tag_state = TAG_NONE; - } else { - /* We read a non-empty tag so go ahead and look for the - * leadout string. */ - ssi->tag_state = TAG_LEADOUT; - LWIP_ASSERT("ssi->tag_index <= 0xff", ssi->tag_index <= 0xff); - ssi->tag_name_len = (u8_t)ssi->tag_index; - ssi->tag_name[ssi->tag_index] = '\0'; - if(*ssi->parsed == g_pcTagLeadOut[0]) { - ssi->tag_index = 1; - } else { - ssi->tag_index = 0; - } - } - } else { - /* This character is part of the tag name so save it */ - if(ssi->tag_index < LWIP_HTTPD_MAX_TAG_NAME_LEN) { - ssi->tag_name[ssi->tag_index++] = *ssi->parsed; - } else { - /* The tag was too long so ignore it. */ - ssi->tag_state = TAG_NONE; - } - } - - /* Move on to the next character in the buffer */ - ssi->parse_left--; - ssi->parsed++; - - break; - - /* We are looking for the end of the lead-out marker. */ - case TAG_LEADOUT: - /* Remove leading whitespace between the tag leading and the first - * tag leadout character. */ - if((ssi->tag_index == 0) && ((*ssi->parsed == ' ') || - (*ssi->parsed == '\t') || (*ssi->parsed == '\n') || - (*ssi->parsed == '\r'))) { - /* Move on to the next character in the buffer */ - ssi->parse_left--; - ssi->parsed++; - break; - } - - /* Have we found the next character we expect for the tag leadout? */ - if(*ssi->parsed == g_pcTagLeadOut[ssi->tag_index]) { - /* Yes - move to the next one unless we have found the complete - * leadout, in which case we need to call the client to process - * the tag. */ - - /* Move on to the next character in the buffer */ - ssi->parse_left--; - ssi->parsed++; - - if(ssi->tag_index == (LEN_TAG_LEAD_OUT - 1)) { - /* Call the client to ask for the insert string for the - * tag we just found. */ -#if LWIP_HTTPD_SSI_MULTIPART - ssi->tag_part = 0; /* start with tag part 0 */ -#endif /* LWIP_HTTPD_SSI_MULTIPART */ - get_tag_insert(hs); - - /* Next time through, we are going to be sending data - * immediately, either the end of the block we start - * sending here or the insert string. */ - ssi->tag_index = 0; - ssi->tag_state = TAG_SENDING; - ssi->tag_end = ssi->parsed; -#if !LWIP_HTTPD_SSI_INCLUDE_TAG - ssi->parsed = ssi->tag_started; -#endif /* !LWIP_HTTPD_SSI_INCLUDE_TAG*/ - - /* If there is any unsent data in the buffer prior to the - * tag, we need to send it now. */ - if (ssi->tag_end > hs->file) { - /* How much of the data can we send? */ -#if LWIP_HTTPD_SSI_INCLUDE_TAG - len = (u16_t)LWIP_MIN(ssi->tag_end - hs->file, 0xffff); -#else /* LWIP_HTTPD_SSI_INCLUDE_TAG*/ - /* we would include the tag in sending */ - len = (u16_t)LWIP_MIN(ssi->tag_started - hs->file, 0xffff); -#endif /* LWIP_HTTPD_SSI_INCLUDE_TAG*/ - - err = http_write(pcb, hs->file, &len, HTTP_IS_DATA_VOLATILE(hs)); - if (err == ERR_OK) { - data_to_send = 1; -#if !LWIP_HTTPD_SSI_INCLUDE_TAG - if(ssi->tag_started <= hs->file) { - /* pretend to have sent the tag, too */ - len += ssi->tag_end - ssi->tag_started; - } -#endif /* !LWIP_HTTPD_SSI_INCLUDE_TAG*/ - hs->file += len; - hs->left -= len; - } - } - } else { - ssi->tag_index++; - } - } else { - /* We found an unexpected character so this is not a tag. Move - * back to idle state. */ - ssi->parse_left--; - ssi->parsed++; - ssi->tag_state = TAG_NONE; - } - break; - - /* - * We have found a valid tag and are in the process of sending - * data as a result of that discovery. We send either remaining data - * from the file prior to the insert point or the insert string itself. - */ - case TAG_SENDING: - /* Do we have any remaining file data to send from the buffer prior - * to the tag? */ - if(ssi->tag_end > hs->file) { - /* How much of the data can we send? */ -#if LWIP_HTTPD_SSI_INCLUDE_TAG - len = (u16_t)LWIP_MIN(ssi->tag_end - hs->file, 0xffff); -#else /* LWIP_HTTPD_SSI_INCLUDE_TAG*/ - LWIP_ASSERT("hs->started >= hs->file", ssi->tag_started >= hs->file); - /* we would include the tag in sending */ - len = (u16_t)LWIP_MIN(ssi->tag_started - hs->file, 0xffff); -#endif /* LWIP_HTTPD_SSI_INCLUDE_TAG*/ - if (len != 0) { - err = http_write(pcb, hs->file, &len, HTTP_IS_DATA_VOLATILE(hs)); - } else { - err = ERR_OK; - } - if (err == ERR_OK) { - data_to_send = 1; -#if !LWIP_HTTPD_SSI_INCLUDE_TAG - if(ssi->tag_started <= hs->file) { - /* pretend to have sent the tag, too */ - len += ssi->tag_end - ssi->tag_started; - } -#endif /* !LWIP_HTTPD_SSI_INCLUDE_TAG*/ - hs->file += len; - hs->left -= len; - } - } else { -#if LWIP_HTTPD_SSI_MULTIPART - if(ssi->tag_index >= ssi->tag_insert_len) { - /* Did the last SSIHandler have more to send? */ - if (ssi->tag_part != HTTPD_LAST_TAG_PART) { - /* If so, call it again */ - ssi->tag_index = 0; - get_tag_insert(hs); - } - } -#endif /* LWIP_HTTPD_SSI_MULTIPART */ - - /* Do we still have insert data left to send? */ - if(ssi->tag_index < ssi->tag_insert_len) { - /* We are sending the insert string itself. How much of the - * insert can we send? */ - len = (ssi->tag_insert_len - ssi->tag_index); - - /* Note that we set the copy flag here since we only have a - * single tag insert buffer per connection. If we don't do - * this, insert corruption can occur if more than one insert - * is processed before we call tcp_output. */ - err = http_write(pcb, &(ssi->tag_insert[ssi->tag_index]), &len, - HTTP_IS_TAG_VOLATILE(hs)); - if (err == ERR_OK) { - data_to_send = 1; - ssi->tag_index += len; - /* Don't return here: keep on sending data */ - } - } else { -#if LWIP_HTTPD_SSI_MULTIPART - if (ssi->tag_part == HTTPD_LAST_TAG_PART) -#endif /* LWIP_HTTPD_SSI_MULTIPART */ - { - /* We have sent all the insert data so go back to looking for - * a new tag. */ - LWIP_DEBUGF(HTTPD_DEBUG, ("Everything sent.\n")); - ssi->tag_index = 0; - ssi->tag_state = TAG_NONE; -#if !LWIP_HTTPD_SSI_INCLUDE_TAG - ssi->parsed = ssi->tag_end; -#endif /* !LWIP_HTTPD_SSI_INCLUDE_TAG*/ - } - } - break; - default: - break; - } - } - } - - /* If we drop out of the end of the for loop, this implies we must have - * file data to send so send it now. In TAG_SENDING state, we've already - * handled this so skip the send if that's the case. */ - if((ssi->tag_state != TAG_SENDING) && (ssi->parsed > hs->file)) { - len = (u16_t)LWIP_MIN(ssi->parsed - hs->file, 0xffff); - - err = http_write(pcb, hs->file, &len, HTTP_IS_DATA_VOLATILE(hs)); - if (err == ERR_OK) { - data_to_send = 1; - hs->file += len; - hs->left -= len; - } - } - return data_to_send; -} -#endif /* LWIP_HTTPD_SSI */ - -/** - * Try to send more data on this pcb. - * - * @param pcb the pcb to send data - * @param hs connection state - */ -static u8_t -http_send(struct tcp_pcb *pcb, struct http_state *hs) -{ - u8_t data_to_send = HTTP_NO_DATA_TO_SEND; - - LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("http_send: pcb=%p hs=%p left=%d\n", (void*)pcb, - (void*)hs, hs != NULL ? (int)hs->left : 0)); - -#if LWIP_HTTPD_SUPPORT_POST && LWIP_HTTPD_POST_MANUAL_WND - if (hs->unrecved_bytes != 0) { - return 0; - } -#endif /* LWIP_HTTPD_SUPPORT_POST && LWIP_HTTPD_POST_MANUAL_WND */ - - /* If we were passed a NULL state structure pointer, ignore the call. */ - if (hs == NULL) { - return 0; - } - -#if LWIP_HTTPD_FS_ASYNC_READ - /* Check if we are allowed to read from this file. - (e.g. SSI might want to delay sending until data is available) */ - if (!fs_is_file_ready(hs->handle, http_continue, hs)) { - return 0; - } -#endif /* LWIP_HTTPD_FS_ASYNC_READ */ - -#if LWIP_HTTPD_DYNAMIC_HEADERS - /* Do we have any more header data to send for this file? */ - if (hs->hdr_index < NUM_FILE_HDR_STRINGS) { - data_to_send = http_send_headers(pcb, hs); - if ((data_to_send != HTTP_DATA_TO_SEND_CONTINUE) && - (hs->hdr_index < NUM_FILE_HDR_STRINGS)) { - return data_to_send; - } - } -#endif /* LWIP_HTTPD_DYNAMIC_HEADERS */ - - /* Have we run out of file data to send? If so, we need to read the next - * block from the file. */ - if (hs->left == 0) { - if (!http_check_eof(pcb, hs)) { - return 0; - } - } - -#if LWIP_HTTPD_SSI - if(hs->ssi) { - data_to_send = http_send_data_ssi(pcb, hs); - } else -#endif /* LWIP_HTTPD_SSI */ - { - data_to_send = http_send_data_nonssi(pcb, hs); - } - - if((hs->left == 0) && (fs_bytes_left(hs->handle) <= 0)) { - /* We reached the end of the file so this request is done. - * This adds the FIN flag right into the last data segment. */ - LWIP_DEBUGF(HTTPD_DEBUG, ("End of file.\n")); - http_eof(pcb, hs); - return 0; - } - LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("send_data end.\n")); - return data_to_send; -} - -#if LWIP_HTTPD_SUPPORT_EXTSTATUS -/** Initialize a http connection with a file to send for an error message - * - * @param hs http connection state - * @param error_nr HTTP error number - * @return ERR_OK if file was found and hs has been initialized correctly - * another err_t otherwise - */ -static err_t -http_find_error_file(struct http_state *hs, u16_t error_nr) -{ - const char *uri1, *uri2, *uri3; - err_t err; - - if (error_nr == 501) { - uri1 = "/501.html"; - uri2 = "/501.htm"; - uri3 = "/501.shtml"; - } else { - /* 400 (bad request is the default) */ - uri1 = "/400.html"; - uri2 = "/400.htm"; - uri3 = "/400.shtml"; - } - err = fs_open(&hs->file_handle, uri1); - if (err != ERR_OK) { - err = fs_open(&hs->file_handle, uri2); - if (err != ERR_OK) { - err = fs_open(&hs->file_handle, uri3); - if (err != ERR_OK) { - LWIP_DEBUGF(HTTPD_DEBUG, ("Error page for error %"U16_F" not found\n", - error_nr)); - return ERR_ARG; - } - } - } - return http_init_file(hs, &hs->file_handle, 0, NULL, 0, NULL); -} -#else /* LWIP_HTTPD_SUPPORT_EXTSTATUS */ -#define http_find_error_file(hs, error_nr) ERR_ARG -#endif /* LWIP_HTTPD_SUPPORT_EXTSTATUS */ - -/** - * Get the file struct for a 404 error page. - * Tries some file names and returns NULL if none found. - * - * @param uri pointer that receives the actual file name URI - * @return file struct for the error page or NULL no matching file was found - */ -static struct fs_file * -http_get_404_file(struct http_state *hs, const char **uri) -{ - err_t err; - - *uri = "/404.html"; - err = fs_open(&hs->file_handle, *uri); - if (err != ERR_OK) { - /* 404.html doesn't exist. Try 404.htm instead. */ - *uri = "/404.htm"; - err = fs_open(&hs->file_handle, *uri); - if (err != ERR_OK) { - /* 404.htm doesn't exist either. Try 404.shtml instead. */ - *uri = "/404.shtml"; - err = fs_open(&hs->file_handle, *uri); - if (err != ERR_OK) { - /* 404.htm doesn't exist either. Indicate to the caller that it should - * send back a default 404 page. - */ - *uri = NULL; - return NULL; - } - } - } - - return &hs->file_handle; -} - -#if LWIP_HTTPD_SUPPORT_POST -static err_t -http_handle_post_finished(struct http_state *hs) -{ -#if LWIP_HTTPD_POST_MANUAL_WND - /* Prevent multiple calls to httpd_post_finished, since it might have already - been called before from httpd_post_data_recved(). */ - if (hs->post_finished) { - return ERR_OK; - } - hs->post_finished = 1; -#endif /* LWIP_HTTPD_POST_MANUAL_WND */ - /* application error or POST finished */ - /* NULL-terminate the buffer */ - http_uri_buf[0] = 0; - httpd_post_finished(hs, http_uri_buf, LWIP_HTTPD_URI_BUF_LEN); - return http_find_file(hs, http_uri_buf, 0); -} - -/** Pass received POST body data to the application and correctly handle - * returning a response document or closing the connection. - * ATTENTION: The application is responsible for the pbuf now, so don't free it! - * - * @param hs http connection state - * @param p pbuf to pass to the application - * @return ERR_OK if passed successfully, another err_t if the response file - * hasn't been found (after POST finished) - */ -static err_t -http_post_rxpbuf(struct http_state *hs, struct pbuf *p) -{ - err_t err; - - if (p != NULL) { - /* adjust remaining Content-Length */ - if (hs->post_content_len_left < p->tot_len) { - hs->post_content_len_left = 0; - } else { - hs->post_content_len_left -= p->tot_len; - } - } -#if LWIP_HTTPD_SUPPORT_POST && LWIP_HTTPD_POST_MANUAL_WND - /* prevent connection being closed if httpd_post_data_recved() is called nested */ - hs->unrecved_bytes++; -#endif - err = httpd_post_receive_data(hs, p); -#if LWIP_HTTPD_SUPPORT_POST && LWIP_HTTPD_POST_MANUAL_WND - hs->unrecved_bytes--; -#endif - if (err != ERR_OK) { - /* Ignore remaining content in case of application error */ - hs->post_content_len_left = 0; - } - if (hs->post_content_len_left == 0) { -#if LWIP_HTTPD_SUPPORT_POST && LWIP_HTTPD_POST_MANUAL_WND - if (hs->unrecved_bytes != 0) { - return ERR_OK; - } -#endif /* LWIP_HTTPD_SUPPORT_POST && LWIP_HTTPD_POST_MANUAL_WND */ - /* application error or POST finished */ - return http_handle_post_finished(hs); - } - - return ERR_OK; -} - -/** Handle a post request. Called from http_parse_request when method 'POST' - * is found. - * - * @param p The input pbuf (containing the POST header and body). - * @param hs The http connection state. - * @param data HTTP request (header and part of body) from input pbuf(s). - * @param data_len Size of 'data'. - * @param uri The HTTP URI parsed from input pbuf(s). - * @param uri_end Pointer to the end of 'uri' (here, the rest of the HTTP - * header starts). - * @return ERR_OK: POST correctly parsed and accepted by the application. - * ERR_INPROGRESS: POST not completely parsed (no error yet) - * another err_t: Error parsing POST or denied by the application - */ -static err_t -http_post_request(struct pbuf *inp, struct http_state *hs, - char *data, u16_t data_len, char *uri, char *uri_end) -{ - err_t err; - /* search for end-of-header (first double-CRLF) */ - char* crlfcrlf = lwip_strnstr(uri_end + 1, CRLF CRLF, data_len - (uri_end + 1 - data)); - - if (crlfcrlf != NULL) { - /* search for "Content-Length: " */ -#define HTTP_HDR_CONTENT_LEN "Content-Length: " -#define HTTP_HDR_CONTENT_LEN_LEN 16 -#define HTTP_HDR_CONTENT_LEN_DIGIT_MAX_LEN 10 - char *scontent_len = lwip_strnstr(uri_end + 1, HTTP_HDR_CONTENT_LEN, crlfcrlf - (uri_end + 1)); - if (scontent_len != NULL) { - char *scontent_len_end = lwip_strnstr(scontent_len + HTTP_HDR_CONTENT_LEN_LEN, CRLF, HTTP_HDR_CONTENT_LEN_DIGIT_MAX_LEN); - if (scontent_len_end != NULL) { - int content_len; - char *content_len_num = scontent_len + HTTP_HDR_CONTENT_LEN_LEN; - content_len = atoi(content_len_num); - if (content_len == 0) { - /* if atoi returns 0 on error, fix this */ - if ((content_len_num[0] != '0') || (content_len_num[1] != '\r')) { - content_len = -1; - } - } - if (content_len >= 0) { - /* adjust length of HTTP header passed to application */ - const char *hdr_start_after_uri = uri_end + 1; - u16_t hdr_len = (u16_t)LWIP_MIN(data_len, crlfcrlf + 4 - data); - u16_t hdr_data_len = (u16_t)LWIP_MIN(data_len, crlfcrlf + 4 - hdr_start_after_uri); - u8_t post_auto_wnd = 1; - http_uri_buf[0] = 0; - /* trim http header */ - *crlfcrlf = 0; - err = httpd_post_begin(hs, uri, hdr_start_after_uri, hdr_data_len, content_len, - http_uri_buf, LWIP_HTTPD_URI_BUF_LEN, &post_auto_wnd); - if (err == ERR_OK) { - /* try to pass in data of the first pbuf(s) */ - struct pbuf *q = inp; - u16_t start_offset = hdr_len; -#if LWIP_HTTPD_POST_MANUAL_WND - hs->no_auto_wnd = !post_auto_wnd; -#endif /* LWIP_HTTPD_POST_MANUAL_WND */ - /* set the Content-Length to be received for this POST */ - hs->post_content_len_left = (u32_t)content_len; - - /* get to the pbuf where the body starts */ - while((q != NULL) && (q->len <= start_offset)) { - start_offset -= q->len; - q = q->next; - } - if (q != NULL) { - /* hide the remaining HTTP header */ - pbuf_header(q, -(s16_t)start_offset); -#if LWIP_HTTPD_POST_MANUAL_WND - if (!post_auto_wnd) { - /* already tcp_recved() this data... */ - hs->unrecved_bytes = q->tot_len; - } -#endif /* LWIP_HTTPD_POST_MANUAL_WND */ - pbuf_ref(q); - return http_post_rxpbuf(hs, q); - } else if (hs->post_content_len_left == 0) { - q = pbuf_alloc(PBUF_RAW, 0, PBUF_REF); - return http_post_rxpbuf(hs, q); - } else { - return ERR_OK; - } - } else { - /* return file passed from application */ - return http_find_file(hs, http_uri_buf, 0); - } - } else { - LWIP_DEBUGF(HTTPD_DEBUG, ("POST received invalid Content-Length: %s\n", - content_len_num)); - return ERR_ARG; - } - } - } - /* If we come here, headers are fully received (double-crlf), but Content-Length - was not included. Since this is currently the only supported method, we have - to fail in this case! */ - LWIP_DEBUGF(HTTPD_DEBUG, ("Error when parsing Content-Length\n")); - return ERR_ARG; - } - /* if we come here, the POST is incomplete */ -#if LWIP_HTTPD_SUPPORT_REQUESTLIST - return ERR_INPROGRESS; -#else /* LWIP_HTTPD_SUPPORT_REQUESTLIST */ - return ERR_ARG; -#endif /* LWIP_HTTPD_SUPPORT_REQUESTLIST */ -} - -#if LWIP_HTTPD_POST_MANUAL_WND -/** A POST implementation can call this function to update the TCP window. - * This can be used to throttle data reception (e.g. when received data is - * programmed to flash and data is received faster than programmed). - * - * @param connection A connection handle passed to httpd_post_begin for which - * httpd_post_finished has *NOT* been called yet! - * @param recved_len Length of data received (for window update) - */ -void httpd_post_data_recved(void *connection, u16_t recved_len) -{ - struct http_state *hs = (struct http_state*)connection; - if (hs != NULL) { - if (hs->no_auto_wnd) { - u16_t len = recved_len; - if (hs->unrecved_bytes >= recved_len) { - hs->unrecved_bytes -= recved_len; - } else { - LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_LEVEL_WARNING, ("httpd_post_data_recved: recved_len too big\n")); - len = (u16_t)hs->unrecved_bytes; - hs->unrecved_bytes = 0; - } - if (hs->pcb != NULL) { - if (len != 0) { - tcp_recved(hs->pcb, len); - } - if ((hs->post_content_len_left == 0) && (hs->unrecved_bytes == 0)) { - /* finished handling POST */ - http_handle_post_finished(hs); - http_send(hs->pcb, hs); - } - } - } - } -} -#endif /* LWIP_HTTPD_POST_MANUAL_WND */ - -#endif /* LWIP_HTTPD_SUPPORT_POST */ - -#if LWIP_HTTPD_FS_ASYNC_READ -/** Try to send more data if file has been blocked before - * This is a callback function passed to fs_read_async(). - */ -static void -http_continue(void *connection) -{ - struct http_state *hs = (struct http_state*)connection; - if (hs && (hs->pcb) && (hs->handle)) { - LWIP_ASSERT("hs->pcb != NULL", hs->pcb != NULL); - LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("httpd_continue: try to send more data\n")); - if (http_send(hs->pcb, hs)) { - /* If we wrote anything to be sent, go ahead and send it now. */ - LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("tcp_output\n")); - tcp_output(hs->pcb); - } - } -} -#endif /* LWIP_HTTPD_FS_ASYNC_READ */ - -/** - * When data has been received in the correct state, try to parse it - * as a HTTP request. - * - * @param inp the received pbuf - * @param hs the connection state - * @param pcb the tcp_pcb which received this packet - * @return ERR_OK if request was OK and hs has been initialized correctly - * ERR_INPROGRESS if request was OK so far but not fully received - * another err_t otherwise - */ -static err_t -http_parse_request(struct pbuf *inp, struct http_state *hs, struct tcp_pcb *pcb) -{ - char *data; - char *crlf; - u16_t data_len; - struct pbuf *p = inp; -#if LWIP_HTTPD_SUPPORT_REQUESTLIST - u16_t clen; -#endif /* LWIP_HTTPD_SUPPORT_REQUESTLIST */ -#if LWIP_HTTPD_SUPPORT_POST - err_t err; -#endif /* LWIP_HTTPD_SUPPORT_POST */ - - LWIP_UNUSED_ARG(pcb); /* only used for post */ - LWIP_ASSERT("p != NULL", p != NULL); - LWIP_ASSERT("hs != NULL", hs != NULL); - - if ((hs->handle != NULL) || (hs->file != NULL)) { - LWIP_DEBUGF(HTTPD_DEBUG, ("Received data while sending a file\n")); - /* already sending a file */ - /* @todo: abort? */ - return ERR_USE; - } - -#if LWIP_HTTPD_SUPPORT_REQUESTLIST - - LWIP_DEBUGF(HTTPD_DEBUG, ("Received %"U16_F" bytes\n", p->tot_len)); - - /* first check allowed characters in this pbuf? */ - - /* enqueue the pbuf */ - if (hs->req == NULL) { - LWIP_DEBUGF(HTTPD_DEBUG, ("First pbuf\n")); - hs->req = p; - } else { - LWIP_DEBUGF(HTTPD_DEBUG, ("pbuf enqueued\n")); - pbuf_cat(hs->req, p); - } - /* increase pbuf ref counter as it is freed when we return but we want to - keep it on the req list */ - pbuf_ref(p); - - if (hs->req->next != NULL) { - data_len = LWIP_MIN(hs->req->tot_len, LWIP_HTTPD_MAX_REQ_LENGTH); - pbuf_copy_partial(hs->req, httpd_req_buf, data_len, 0); - data = httpd_req_buf; - } else -#endif /* LWIP_HTTPD_SUPPORT_REQUESTLIST */ - { - data = (char *)p->payload; - data_len = p->len; - if (p->len != p->tot_len) { - LWIP_DEBUGF(HTTPD_DEBUG, ("Warning: incomplete header due to chained pbufs\n")); - } - } - - /* received enough data for minimal request? */ - if (data_len >= MIN_REQ_LEN) { - /* wait for CRLF before parsing anything */ - crlf = lwip_strnstr(data, CRLF, data_len); - if (crlf != NULL) { -#if LWIP_HTTPD_SUPPORT_POST - int is_post = 0; -#endif /* LWIP_HTTPD_SUPPORT_POST */ - int is_09 = 0; - char *sp1, *sp2; - u16_t left_len, uri_len; - LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("CRLF received, parsing request\n")); - /* parse method */ - if (!strncmp(data, "GET ", 4)) { - sp1 = data + 3; - /* received GET request */ - LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("Received GET request\"\n")); -#if LWIP_HTTPD_SUPPORT_POST - } else if (!strncmp(data, "POST ", 5)) { - /* store request type */ - is_post = 1; - sp1 = data + 4; - /* received GET request */ - LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("Received POST request\n")); -#endif /* LWIP_HTTPD_SUPPORT_POST */ - } else { - /* null-terminate the METHOD (pbuf is freed anyway wen returning) */ - data[4] = 0; - /* unsupported method! */ - LWIP_DEBUGF(HTTPD_DEBUG, ("Unsupported request method (not implemented): \"%s\"\n", - data)); - return http_find_error_file(hs, 501); - } - /* if we come here, method is OK, parse URI */ - left_len = (u16_t)(data_len - ((sp1 +1) - data)); - sp2 = lwip_strnstr(sp1 + 1, " ", left_len); -#if LWIP_HTTPD_SUPPORT_V09 - if (sp2 == NULL) { - /* HTTP 0.9: respond with correct protocol version */ - sp2 = lwip_strnstr(sp1 + 1, CRLF, left_len); - is_09 = 1; -#if LWIP_HTTPD_SUPPORT_POST - if (is_post) { - /* HTTP/0.9 does not support POST */ - goto badrequest; - } -#endif /* LWIP_HTTPD_SUPPORT_POST */ - } -#endif /* LWIP_HTTPD_SUPPORT_V09 */ - uri_len = (u16_t)(sp2 - (sp1 + 1)); - if ((sp2 != 0) && (sp2 > sp1)) { - /* wait for CRLFCRLF (indicating end of HTTP headers) before parsing anything */ - if (lwip_strnstr(data, CRLF CRLF, data_len) != NULL) { - char *uri = sp1 + 1; -#if LWIP_HTTPD_SUPPORT_11_KEEPALIVE - /* This is HTTP/1.0 compatible: for strict 1.1, a connection - would always be persistent unless "close" was specified. */ - if (!is_09 && (lwip_strnstr(data, HTTP11_CONNECTIONKEEPALIVE, data_len) || - lwip_strnstr(data, HTTP11_CONNECTIONKEEPALIVE2, data_len))) { - hs->keepalive = 1; - } else { - hs->keepalive = 0; - } -#endif /* LWIP_HTTPD_SUPPORT_11_KEEPALIVE */ - /* null-terminate the METHOD (pbuf is freed anyway wen returning) */ - *sp1 = 0; - uri[uri_len] = 0; - LWIP_DEBUGF(HTTPD_DEBUG, ("Received \"%s\" request for URI: \"%s\"\n", - data, uri)); -#if LWIP_HTTPD_SUPPORT_POST - if (is_post) { -#if LWIP_HTTPD_SUPPORT_REQUESTLIST - struct pbuf *q = hs->req; -#else /* LWIP_HTTPD_SUPPORT_REQUESTLIST */ - struct pbuf *q = inp; -#endif /* LWIP_HTTPD_SUPPORT_REQUESTLIST */ - err = http_post_request(q, hs, data, data_len, uri, sp2); - if (err != ERR_OK) { - /* restore header for next try */ - *sp1 = ' '; - *sp2 = ' '; - uri[uri_len] = ' '; - } - if (err == ERR_ARG) { - goto badrequest; - } - return err; - } else -#endif /* LWIP_HTTPD_SUPPORT_POST */ - { - return http_find_file(hs, uri, is_09); - } - } - } else { - LWIP_DEBUGF(HTTPD_DEBUG, ("invalid URI\n")); - } - } - } - -#if LWIP_HTTPD_SUPPORT_REQUESTLIST - clen = pbuf_clen(hs->req); - if ((hs->req->tot_len <= LWIP_HTTPD_REQ_BUFSIZE) && - (clen <= LWIP_HTTPD_REQ_QUEUELEN)) { - /* request not fully received (too short or CRLF is missing) */ - return ERR_INPROGRESS; - } else -#endif /* LWIP_HTTPD_SUPPORT_REQUESTLIST */ - { -#if LWIP_HTTPD_SUPPORT_POST -badrequest: -#endif /* LWIP_HTTPD_SUPPORT_POST */ - LWIP_DEBUGF(HTTPD_DEBUG, ("bad request\n")); - /* could not parse request */ - return http_find_error_file(hs, 400); - } -} - -/** Try to find the file specified by uri and, if found, initialize hs - * accordingly. - * - * @param hs the connection state - * @param uri the HTTP header URI - * @param is_09 1 if the request is HTTP/0.9 (no HTTP headers in response) - * @return ERR_OK if file was found and hs has been initialized correctly - * another err_t otherwise - */ -static err_t -http_find_file(struct http_state *hs, const char *uri, int is_09) -{ - size_t loop; - struct fs_file *file = NULL; - char *params = NULL; - err_t err; -#if LWIP_HTTPD_CGI - int i; -#endif /* LWIP_HTTPD_CGI */ -#if !LWIP_HTTPD_SSI - const -#endif /* !LWIP_HTTPD_SSI */ - /* By default, assume we will not be processing server-side-includes tags */ - u8_t tag_check = 0; - - /* Have we been asked for the default file (in root or a directory) ? */ -#if LWIP_HTTPD_MAX_REQUEST_URI_LEN - size_t uri_len = strlen(uri); - if ((uri_len > 0) && (uri[uri_len-1] == '/') && - ((uri != http_uri_buf) || (uri_len == 1))) { - size_t copy_len = LWIP_MIN(sizeof(http_uri_buf) - 1, uri_len - 1); - if (copy_len > 0) { - MEMCPY(http_uri_buf, uri, copy_len); - http_uri_buf[copy_len] = 0; - } -#else /* LWIP_HTTPD_MAX_REQUEST_URI_LEN */ - if ((uri[0] == '/') && (uri[1] == 0)) { -#endif /* LWIP_HTTPD_MAX_REQUEST_URI_LEN */ - /* Try each of the configured default filenames until we find one - that exists. */ - for (loop = 0; loop < NUM_DEFAULT_FILENAMES; loop++) { - const char* file_name; -#if LWIP_HTTPD_MAX_REQUEST_URI_LEN - if (copy_len > 0) { - size_t len_left = sizeof(http_uri_buf) - copy_len - 1; - if (len_left > 0) { - size_t name_len = strlen(g_psDefaultFilenames[loop].name); - size_t name_copy_len = LWIP_MIN(len_left, name_len); - MEMCPY(&http_uri_buf[copy_len], g_psDefaultFilenames[loop].name, name_copy_len); - } - file_name = http_uri_buf; - } else -#endif /* LWIP_HTTPD_MAX_REQUEST_URI_LEN */ - { - file_name = g_psDefaultFilenames[loop].name; - } - LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("Looking for %s...\n", file_name)); - err = fs_open(&hs->file_handle, file_name); - if(err == ERR_OK) { - uri = file_name; - file = &hs->file_handle; - LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("Opened.\n")); -#if LWIP_HTTPD_SSI - tag_check = g_psDefaultFilenames[loop].shtml; -#endif /* LWIP_HTTPD_SSI */ - break; - } - } - } - if (file == NULL) { - /* No - we've been asked for a specific file. */ - /* First, isolate the base URI (without any parameters) */ - params = (char *)strchr(uri, '?'); - if (params != NULL) { - /* URI contains parameters. NULL-terminate the base URI */ - *params = '\0'; - params++; - } - -#if LWIP_HTTPD_CGI - http_cgi_paramcount = -1; - /* Does the base URI we have isolated correspond to a CGI handler? */ - if (g_iNumCGIs && g_pCGIs) { - for (i = 0; i < g_iNumCGIs; i++) { - if (strcmp(uri, g_pCGIs[i].pcCGIName) == 0) { - /* - * We found a CGI that handles this URI so extract the - * parameters and call the handler. - */ - http_cgi_paramcount = extract_uri_parameters(hs, params); - uri = g_pCGIs[i].pfnCGIHandler(i, http_cgi_paramcount, hs->params, - hs->param_vals); - break; - } - } - } -#endif /* LWIP_HTTPD_CGI */ - - LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("Opening %s\n", uri)); - - err = fs_open(&hs->file_handle, uri); - if (err == ERR_OK) { - file = &hs->file_handle; - } else { - file = http_get_404_file(hs, &uri); - } -#if LWIP_HTTPD_SSI - if (file != NULL) { - /* See if we have been asked for an shtml file and, if so, - enable tag checking. */ - const char* ext = NULL, *sub; - char* param = (char*)strstr(uri, "?"); - if (param != NULL) { - /* separate uri from parameters for now, set back later */ - *param = 0; - } - sub = uri; - ext = uri; - for (sub = strstr(sub, "."); sub != NULL; sub = strstr(sub, ".")) - { - ext = sub; - sub++; - } - tag_check = 0; - for (loop = 0; loop < NUM_SHTML_EXTENSIONS; loop++) { - if (!lwip_stricmp(ext, g_pcSSIExtensions[loop])) { - tag_check = 1; - break; - } - } - if (param != NULL) { - *param = '?'; - } - } -#endif /* LWIP_HTTPD_SSI */ - } - if (file == NULL) { - /* None of the default filenames exist so send back a 404 page */ - file = http_get_404_file(hs, &uri); - } - return http_init_file(hs, file, is_09, uri, tag_check, params); -} - -/** Initialize a http connection with a file to send (if found). - * Called by http_find_file and http_find_error_file. - * - * @param hs http connection state - * @param file file structure to send (or NULL if not found) - * @param is_09 1 if the request is HTTP/0.9 (no HTTP headers in response) - * @param uri the HTTP header URI - * @param tag_check enable SSI tag checking - * @param params != NULL if URI has parameters (separated by '?') - * @return ERR_OK if file was found and hs has been initialized correctly - * another err_t otherwise - */ -static err_t -http_init_file(struct http_state *hs, struct fs_file *file, int is_09, const char *uri, - u8_t tag_check, char* params) -{ - if (file != NULL) { - /* file opened, initialise struct http_state */ -#if LWIP_HTTPD_SSI - if (tag_check) { - struct http_ssi_state *ssi = http_ssi_state_alloc(); - if (ssi != NULL) { - ssi->tag_index = 0; - ssi->tag_state = TAG_NONE; - ssi->parsed = file->data; - ssi->parse_left = file->len; - ssi->tag_end = file->data; - hs->ssi = ssi; - } - } -#else /* LWIP_HTTPD_SSI */ - LWIP_UNUSED_ARG(tag_check); -#endif /* LWIP_HTTPD_SSI */ - hs->handle = file; - hs->file = file->data; - LWIP_ASSERT("File length must be positive!", (file->len >= 0)); -#if LWIP_HTTPD_CUSTOM_FILES - if (file->is_custom_file && (file->data == NULL)) { - /* custom file, need to read data first (via fs_read_custom) */ - hs->left = 0; - } else -#endif /* LWIP_HTTPD_CUSTOM_FILES */ - { - hs->left = file->len; - } - hs->retries = 0; -#if LWIP_HTTPD_TIMING - hs->time_started = sys_now(); -#endif /* LWIP_HTTPD_TIMING */ -#if !LWIP_HTTPD_DYNAMIC_HEADERS - LWIP_ASSERT("HTTP headers not included in file system", - (hs->handle->flags & FS_FILE_FLAGS_HEADER_INCLUDED) != 0); -#endif /* !LWIP_HTTPD_DYNAMIC_HEADERS */ -#if LWIP_HTTPD_SUPPORT_V09 - if (is_09 && ((hs->handle->flags & FS_FILE_FLAGS_HEADER_INCLUDED) != 0)) { - /* HTTP/0.9 responses are sent without HTTP header, - search for the end of the header. */ - char *file_start = lwip_strnstr(hs->file, CRLF CRLF, hs->left); - if (file_start != NULL) { - size_t diff = file_start + 4 - hs->file; - hs->file += diff; - hs->left -= (u32_t)diff; - } - } -#endif /* LWIP_HTTPD_SUPPORT_V09*/ -#if LWIP_HTTPD_CGI_SSI - if (params != NULL) { - /* URI contains parameters, call generic CGI handler */ - int count; -#if LWIP_HTTPD_CGI - if (http_cgi_paramcount >= 0) { - count = http_cgi_paramcount; - } else -#endif - { - count = extract_uri_parameters(hs, params); - } - httpd_cgi_handler(uri, count, http_cgi_params, http_cgi_param_vals -#if defined(LWIP_HTTPD_FILE_STATE) && LWIP_HTTPD_FILE_STATE - , hs->handle->state -#endif /* LWIP_HTTPD_FILE_STATE */ - ); - } -#else /* LWIP_HTTPD_CGI_SSI */ - LWIP_UNUSED_ARG(params); -#endif /* LWIP_HTTPD_CGI_SSI */ - } else { - hs->handle = NULL; - hs->file = NULL; - hs->left = 0; - hs->retries = 0; - } -#if LWIP_HTTPD_DYNAMIC_HEADERS - /* Determine the HTTP headers to send based on the file extension of - * the requested URI. */ - if ((hs->handle == NULL) || ((hs->handle->flags & FS_FILE_FLAGS_HEADER_INCLUDED) == 0)) { - get_http_headers(hs, uri); - } -#else /* LWIP_HTTPD_DYNAMIC_HEADERS */ - LWIP_UNUSED_ARG(uri); -#endif /* LWIP_HTTPD_DYNAMIC_HEADERS */ -#if LWIP_HTTPD_SUPPORT_11_KEEPALIVE - if (hs->keepalive) { -#if LWIP_HTTPD_SSI - if (hs->ssi != NULL) { - hs->keepalive = 0; - } else -#endif /* LWIP_HTTPD_SSI */ - { - if ((hs->handle != NULL) && - ((hs->handle->flags & (FS_FILE_FLAGS_HEADER_INCLUDED|FS_FILE_FLAGS_HEADER_PERSISTENT)) == FS_FILE_FLAGS_HEADER_INCLUDED)) { - hs->keepalive = 0; - } - } - } -#endif /* LWIP_HTTPD_SUPPORT_11_KEEPALIVE */ - return ERR_OK; -} - -/** - * The pcb had an error and is already deallocated. - * The argument might still be valid (if != NULL). - */ -static void -http_err(void *arg, err_t err) -{ - struct http_state *hs = (struct http_state *)arg; - LWIP_UNUSED_ARG(err); - - LWIP_DEBUGF(HTTPD_DEBUG, ("http_err: %s", lwip_strerr(err))); - - if (hs != NULL) { - http_state_free(hs); - } -} - -/** - * Data has been sent and acknowledged by the remote host. - * This means that more data can be sent. - */ -static err_t -http_sent(void *arg, struct tcp_pcb *pcb, u16_t len) -{ - struct http_state *hs = (struct http_state *)arg; - - LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("http_sent %p\n", (void*)pcb)); - - LWIP_UNUSED_ARG(len); - - if (hs == NULL) { - return ERR_OK; - } - - hs->retries = 0; - - http_send(pcb, hs); - - return ERR_OK; -} - -/** - * The poll function is called every 2nd second. - * If there has been no data sent (which resets the retries) in 8 seconds, close. - * If the last portion of a file has not been sent in 2 seconds, close. - * - * This could be increased, but we don't want to waste resources for bad connections. - */ -static err_t -http_poll(void *arg, struct tcp_pcb *pcb) -{ - struct http_state *hs = (struct http_state *)arg; - LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("http_poll: pcb=%p hs=%p pcb_state=%s\n", - (void*)pcb, (void*)hs, tcp_debug_state_str(pcb->state))); - - if (hs == NULL) { - err_t closed; - /* arg is null, close. */ - LWIP_DEBUGF(HTTPD_DEBUG, ("http_poll: arg is NULL, close\n")); - closed = http_close_conn(pcb, NULL); - LWIP_UNUSED_ARG(closed); -#if LWIP_HTTPD_ABORT_ON_CLOSE_MEM_ERROR - if (closed == ERR_MEM) { - tcp_abort(pcb); - return ERR_ABRT; - } -#endif /* LWIP_HTTPD_ABORT_ON_CLOSE_MEM_ERROR */ - return ERR_OK; - } else { - hs->retries++; - if (hs->retries == HTTPD_MAX_RETRIES) { - LWIP_DEBUGF(HTTPD_DEBUG, ("http_poll: too many retries, close\n")); - http_close_conn(pcb, hs); - return ERR_OK; - } - - /* If this connection has a file open, try to send some more data. If - * it has not yet received a GET request, don't do this since it will - * cause the connection to close immediately. */ - if(hs && (hs->handle)) { - LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("http_poll: try to send more data\n")); - if(http_send(pcb, hs)) { - /* If we wrote anything to be sent, go ahead and send it now. */ - LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("tcp_output\n")); - tcp_output(pcb); - } - } - } - - return ERR_OK; -} - -/** - * Data has been received on this pcb. - * For HTTP 1.0, this should normally only happen once (if the request fits in one packet). - */ -static err_t -http_recv(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) -{ - struct http_state *hs = (struct http_state *)arg; - LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("http_recv: pcb=%p pbuf=%p err=%s\n", (void*)pcb, - (void*)p, lwip_strerr(err))); - - if ((err != ERR_OK) || (p == NULL) || (hs == NULL)) { - /* error or closed by other side? */ - if (p != NULL) { - /* Inform TCP that we have taken the data. */ - tcp_recved(pcb, p->tot_len); - pbuf_free(p); - } - if (hs == NULL) { - /* this should not happen, only to be robust */ - LWIP_DEBUGF(HTTPD_DEBUG, ("Error, http_recv: hs is NULL, close\n")); - } - http_close_conn(pcb, hs); - return ERR_OK; - } - -#if LWIP_HTTPD_SUPPORT_POST && LWIP_HTTPD_POST_MANUAL_WND - if (hs->no_auto_wnd) { - hs->unrecved_bytes += p->tot_len; - } else -#endif /* LWIP_HTTPD_SUPPORT_POST && LWIP_HTTPD_POST_MANUAL_WND */ - { - /* Inform TCP that we have taken the data. */ - tcp_recved(pcb, p->tot_len); - } - -#if LWIP_HTTPD_SUPPORT_POST - if (hs->post_content_len_left > 0) { - /* reset idle counter when POST data is received */ - hs->retries = 0; - /* this is data for a POST, pass the complete pbuf to the application */ - http_post_rxpbuf(hs, p); - /* pbuf is passed to the application, don't free it! */ - if (hs->post_content_len_left == 0) { - /* all data received, send response or close connection */ - http_send(pcb, hs); - } - return ERR_OK; - } else -#endif /* LWIP_HTTPD_SUPPORT_POST */ - { - if (hs->handle == NULL) { - err_t parsed = http_parse_request(p, hs, pcb); - LWIP_ASSERT("http_parse_request: unexpected return value", parsed == ERR_OK - || parsed == ERR_INPROGRESS ||parsed == ERR_ARG || parsed == ERR_USE); -#if LWIP_HTTPD_SUPPORT_REQUESTLIST - if (parsed != ERR_INPROGRESS) { - /* request fully parsed or error */ - if (hs->req != NULL) { - pbuf_free(hs->req); - hs->req = NULL; - } - } -#endif /* LWIP_HTTPD_SUPPORT_REQUESTLIST */ - pbuf_free(p); - if (parsed == ERR_OK) { -#if LWIP_HTTPD_SUPPORT_POST - if (hs->post_content_len_left == 0) -#endif /* LWIP_HTTPD_SUPPORT_POST */ - { - LWIP_DEBUGF(HTTPD_DEBUG | LWIP_DBG_TRACE, ("http_recv: data %p len %"S32_F"\n", (const void*)hs->file, hs->left)); - http_send(pcb, hs); - } - } else if (parsed == ERR_ARG) { - /* @todo: close on ERR_USE? */ - http_close_conn(pcb, hs); - } - } else { - LWIP_DEBUGF(HTTPD_DEBUG, ("http_recv: already sending data\n")); - /* already sending but still receiving data, we might want to RST here? */ - pbuf_free(p); - } - } - return ERR_OK; -} - -/** - * A new incoming connection has been accepted. - */ -static err_t -http_accept(void *arg, struct tcp_pcb *pcb, err_t err) -{ - struct http_state *hs; - LWIP_UNUSED_ARG(err); - LWIP_UNUSED_ARG(arg); - LWIP_DEBUGF(HTTPD_DEBUG, ("http_accept %p / %p\n", (void*)pcb, arg)); - - if ((err != ERR_OK) || (pcb == NULL)) { - return ERR_VAL; - } - - /* Set priority */ - tcp_setprio(pcb, HTTPD_TCP_PRIO); - - /* Allocate memory for the structure that holds the state of the - connection - initialized by that function. */ - hs = http_state_alloc(); - if (hs == NULL) { - LWIP_DEBUGF(HTTPD_DEBUG, ("http_accept: Out of memory, RST\n")); - return ERR_MEM; - } - hs->pcb = pcb; - - /* Tell TCP that this is the structure we wish to be passed for our - callbacks. */ - tcp_arg(pcb, hs); - - /* Set up the various callback functions */ - tcp_recv(pcb, http_recv); - tcp_err(pcb, http_err); - tcp_poll(pcb, http_poll, HTTPD_POLL_INTERVAL); - tcp_sent(pcb, http_sent); - - return ERR_OK; -} - -/** - * @ingroup httpd - * Initialize the httpd: set up a listening PCB and bind it to the defined port - */ -void -httpd_init(void) -{ - struct tcp_pcb *pcb; - err_t err; - -#if HTTPD_USE_MEM_POOL - LWIP_MEMPOOL_INIT(HTTPD_STATE); -#if LWIP_HTTPD_SSI - LWIP_MEMPOOL_INIT(HTTPD_SSI_STATE); -#endif -#endif - LWIP_DEBUGF(HTTPD_DEBUG, ("httpd_init\n")); - - pcb = tcp_new_ip_type(IPADDR_TYPE_ANY); - LWIP_ASSERT("httpd_init: tcp_new failed", pcb != NULL); - tcp_setprio(pcb, HTTPD_TCP_PRIO); - /* set SOF_REUSEADDR here to explicitly bind httpd to multiple interfaces */ - err = tcp_bind(pcb, IP_ANY_TYPE, HTTPD_SERVER_PORT); - LWIP_UNUSED_ARG(err); /* in case of LWIP_NOASSERT */ - LWIP_ASSERT("httpd_init: tcp_bind failed", err == ERR_OK); - pcb = tcp_listen(pcb); - LWIP_ASSERT("httpd_init: tcp_listen failed", pcb != NULL); - tcp_accept(pcb, http_accept); -} - -#if LWIP_HTTPD_SSI -/** - * Set the SSI handler function. - * - * @param ssi_handler the SSI handler function - * @param tags an array of SSI tag strings to search for in SSI-enabled files - * @param num_tags number of tags in the 'tags' array - */ -void -http_set_ssi_handler(tSSIHandler ssi_handler, const char **tags, int num_tags) -{ - LWIP_DEBUGF(HTTPD_DEBUG, ("http_set_ssi_handler\n")); - - LWIP_ASSERT("no ssi_handler given", ssi_handler != NULL); - g_pfnSSIHandler = ssi_handler; - -#if LWIP_HTTPD_SSI_RAW - LWIP_UNUSED_ARG(tags); - LWIP_UNUSED_ARG(num_tags); -#else /* LWIP_HTTPD_SSI_RAW */ - LWIP_ASSERT("no tags given", tags != NULL); - LWIP_ASSERT("invalid number of tags", num_tags > 0); - - g_ppcTags = tags; - g_iNumTags = num_tags; -#endif /* !LWIP_HTTPD_SSI_RAW */ -} -#endif /* LWIP_HTTPD_SSI */ - -#if LWIP_HTTPD_CGI -/** - * Set an array of CGI filenames/handler functions - * - * @param cgis an array of CGI filenames/handler functions - * @param num_handlers number of elements in the 'cgis' array - */ -void -http_set_cgi_handlers(const tCGI *cgis, int num_handlers) -{ - LWIP_ASSERT("no cgis given", cgis != NULL); - LWIP_ASSERT("invalid number of handlers", num_handlers > 0); - - g_pCGIs = cgis; - g_iNumCGIs = num_handlers; -} -#endif /* LWIP_HTTPD_CGI */ - -#endif /* LWIP_TCP && LWIP_CALLBACK_API */ diff --git a/third_party/lwip/repo/lwip/src/apps/httpd/httpd_structs.h b/third_party/lwip/repo/lwip/src/apps/httpd/httpd_structs.h deleted file mode 100644 index fbd135a8c6a4f9..00000000000000 --- a/third_party/lwip/repo/lwip/src/apps/httpd/httpd_structs.h +++ /dev/null @@ -1,114 +0,0 @@ -#ifndef LWIP_HTTPD_STRUCTS_H -#define LWIP_HTTPD_STRUCTS_H - -#include "lwip/apps/httpd.h" - -#if LWIP_HTTPD_DYNAMIC_HEADERS -/** This struct is used for a list of HTTP header strings for various - * filename extensions. */ -typedef struct -{ - const char *extension; - const char *content_type; -} tHTTPHeader; - -/** A list of strings used in HTTP headers (see RFC 1945 HTTP/1.0 and - * RFC 2616 HTTP/1.1 for header field definitions) */ -static const char * const g_psHTTPHeaderStrings[] = -{ - "HTTP/1.0 200 OK\r\n", - "HTTP/1.0 404 File not found\r\n", - "HTTP/1.0 400 Bad Request\r\n", - "HTTP/1.0 501 Not Implemented\r\n", - "HTTP/1.1 200 OK\r\n", - "HTTP/1.1 404 File not found\r\n", - "HTTP/1.1 400 Bad Request\r\n", - "HTTP/1.1 501 Not Implemented\r\n", - "Content-Length: ", - "Connection: Close\r\n", - "Connection: keep-alive\r\n", - "Connection: keep-alive\r\nContent-Length: ", - "Server: "HTTPD_SERVER_AGENT"\r\n", - "\r\n

    404: The requested file cannot be found.

    \r\n" -#if LWIP_HTTPD_SUPPORT_11_KEEPALIVE - ,"Connection: keep-alive\r\nContent-Length: 77\r\n\r\n

    404: The requested file cannot be found.

    \r\n" -#endif -}; - -/* Indexes into the g_psHTTPHeaderStrings array */ -#define HTTP_HDR_OK 0 /* 200 OK */ -#define HTTP_HDR_NOT_FOUND 1 /* 404 File not found */ -#define HTTP_HDR_BAD_REQUEST 2 /* 400 Bad request */ -#define HTTP_HDR_NOT_IMPL 3 /* 501 Not Implemented */ -#define HTTP_HDR_OK_11 4 /* 200 OK */ -#define HTTP_HDR_NOT_FOUND_11 5 /* 404 File not found */ -#define HTTP_HDR_BAD_REQUEST_11 6 /* 400 Bad request */ -#define HTTP_HDR_NOT_IMPL_11 7 /* 501 Not Implemented */ -#define HTTP_HDR_CONTENT_LENGTH 8 /* Content-Length: (HTTP 1.0)*/ -#define HTTP_HDR_CONN_CLOSE 9 /* Connection: Close (HTTP 1.1) */ -#define HTTP_HDR_CONN_KEEPALIVE 10 /* Connection: keep-alive (HTTP 1.1) */ -#define HTTP_HDR_KEEPALIVE_LEN 11 /* Connection: keep-alive + Content-Length: (HTTP 1.1)*/ -#define HTTP_HDR_SERVER 12 /* Server: HTTPD_SERVER_AGENT */ -#define DEFAULT_404_HTML 13 /* default 404 body */ -#if LWIP_HTTPD_SUPPORT_11_KEEPALIVE -#define DEFAULT_404_HTML_PERSISTENT 14 /* default 404 body, but including Connection: keep-alive */ -#endif - - -#define HTTP_HDR_HTML "Content-type: text/html\r\n\r\n" -#define HTTP_HDR_SSI "Content-type: text/html\r\nExpires: Fri, 10 Apr 2008 14:00:00 GMT\r\nPragma: no-cache\r\n\r\n" -#define HTTP_HDR_GIF "Content-type: image/gif\r\n\r\n" -#define HTTP_HDR_PNG "Content-type: image/png\r\n\r\n" -#define HTTP_HDR_JPG "Content-type: image/jpeg\r\n\r\n" -#define HTTP_HDR_BMP "Content-type: image/bmp\r\n\r\n" -#define HTTP_HDR_ICO "Content-type: image/x-icon\r\n\r\n" -#define HTTP_HDR_APP "Content-type: application/octet-stream\r\n\r\n" -#define HTTP_HDR_JS "Content-type: application/javascript\r\n\r\n" -#define HTTP_HDR_RA "Content-type: application/javascript\r\n\r\n" -#define HTTP_HDR_CSS "Content-type: text/css\r\n\r\n" -#define HTTP_HDR_SWF "Content-type: application/x-shockwave-flash\r\n\r\n" -#define HTTP_HDR_XML "Content-type: text/xml\r\n\r\n" -#define HTTP_HDR_PDF "Content-type: application/pdf\r\n\r\n" -#define HTTP_HDR_JSON "Content-type: application/json\r\n\r\n" - -#define HTTP_HDR_DEFAULT_TYPE "Content-type: text/plain\r\n\r\n" - -/** A list of extension-to-HTTP header strings (see outdated RFC 1700 MEDIA TYPES - * and http://www.iana.org/assignments/media-types for registered content types - * and subtypes) */ -static const tHTTPHeader g_psHTTPHeaders[] = -{ - { "html", HTTP_HDR_HTML}, - { "htm", HTTP_HDR_HTML}, - { "shtml",HTTP_HDR_SSI}, - { "shtm", HTTP_HDR_SSI}, - { "ssi", HTTP_HDR_SSI}, - { "gif", HTTP_HDR_GIF}, - { "png", HTTP_HDR_PNG}, - { "jpg", HTTP_HDR_JPG}, - { "bmp", HTTP_HDR_BMP}, - { "ico", HTTP_HDR_ICO}, - { "class",HTTP_HDR_APP}, - { "cls", HTTP_HDR_APP}, - { "js", HTTP_HDR_JS}, - { "ram", HTTP_HDR_RA}, - { "css", HTTP_HDR_CSS}, - { "swf", HTTP_HDR_SWF}, - { "xml", HTTP_HDR_XML}, - { "xsl", HTTP_HDR_XML}, - { "pdf", HTTP_HDR_PDF}, - { "json", HTTP_HDR_JSON} -}; - -#define NUM_HTTP_HEADERS (sizeof(g_psHTTPHeaders) / sizeof(tHTTPHeader)) - -#endif /* LWIP_HTTPD_DYNAMIC_HEADERS */ - -#if LWIP_HTTPD_SSI -static const char * const g_pcSSIExtensions[] = { - ".shtml", ".shtm", ".ssi", ".xml" -}; -#define NUM_SHTML_EXTENSIONS (sizeof(g_pcSSIExtensions) / sizeof(const char *)) -#endif /* LWIP_HTTPD_SSI */ - -#endif /* LWIP_HTTPD_STRUCTS_H */ diff --git a/third_party/lwip/repo/lwip/src/apps/httpd/makefsdata/makefsdata b/third_party/lwip/repo/lwip/src/apps/httpd/makefsdata/makefsdata deleted file mode 100644 index 37b4203e6e1c5d..00000000000000 --- a/third_party/lwip/repo/lwip/src/apps/httpd/makefsdata/makefsdata +++ /dev/null @@ -1,97 +0,0 @@ -#!/usr/bin/perl - -open(OUTPUT, "> fsdata.c"); - -chdir("fs"); -open(FILES, "find . -type f |"); - -while($file = ) { - - # Do not include files in CVS directories nor backup files. - if($file =~ /(CVS|~)/) { - next; - } - - chop($file); - - open(HEADER, "> /tmp/header") || die $!; - if($file =~ /404/) { - print(HEADER "HTTP/1.0 404 File not found\r\n"); - } else { - print(HEADER "HTTP/1.0 200 OK\r\n"); - } - print(HEADER "Server: lwIP/pre-0.6 (http://www.sics.se/~adam/lwip/)\r\n"); - if($file =~ /\.html$/) { - print(HEADER "Content-type: text/html\r\n"); - } elsif($file =~ /\.gif$/) { - print(HEADER "Content-type: image/gif\r\n"); - } elsif($file =~ /\.png$/) { - print(HEADER "Content-type: image/png\r\n"); - } elsif($file =~ /\.jpg$/) { - print(HEADER "Content-type: image/jpeg\r\n"); - } elsif($file =~ /\.class$/) { - print(HEADER "Content-type: application/octet-stream\r\n"); - } elsif($file =~ /\.ram$/) { - print(HEADER "Content-type: audio/x-pn-realaudio\r\n"); - } else { - print(HEADER "Content-type: text/plain\r\n"); - } - print(HEADER "\r\n"); - close(HEADER); - - unless($file =~ /\.plain$/ || $file =~ /cgi/) { - system("cat /tmp/header $file > /tmp/file"); - } else { - system("cp $file /tmp/file"); - } - - open(FILE, "/tmp/file"); - unlink("/tmp/file"); - unlink("/tmp/header"); - - $file =~ s/\.//; - $fvar = $file; - $fvar =~ s-/-_-g; - $fvar =~ s-\.-_-g; - print(OUTPUT "static const unsigned char data".$fvar."[] = {\n"); - print(OUTPUT "\t/* $file */\n\t"); - for($j = 0; $j < length($file); $j++) { - printf(OUTPUT "%#02x, ", unpack("C", substr($file, $j, 1))); - } - printf(OUTPUT "0,\n"); - - - $i = 0; - while(read(FILE, $data, 1)) { - if($i == 0) { - print(OUTPUT "\t"); - } - printf(OUTPUT "%#02x, ", unpack("C", $data)); - $i++; - if($i == 10) { - print(OUTPUT "\n"); - $i = 0; - } - } - print(OUTPUT "};\n\n"); - close(FILE); - push(@fvars, $fvar); - push(@files, $file); -} - -for($i = 0; $i < @fvars; $i++) { - $file = $files[$i]; - $fvar = $fvars[$i]; - - if($i == 0) { - $prevfile = "NULL"; - } else { - $prevfile = "file" . $fvars[$i - 1]; - } - print(OUTPUT "const struct fsdata_file file".$fvar."[] = {{$prevfile, data$fvar, "); - print(OUTPUT "data$fvar + ". (length($file) + 1) .", "); - print(OUTPUT "sizeof(data$fvar) - ". (length($file) + 1) ."}};\n\n"); -} - -print(OUTPUT "#define FS_ROOT file$fvars[$i - 1]\n\n"); -print(OUTPUT "#define FS_NUMFILES $i\n"); diff --git a/third_party/lwip/repo/lwip/src/apps/httpd/makefsdata/makefsdata.c b/third_party/lwip/repo/lwip/src/apps/httpd/makefsdata/makefsdata.c deleted file mode 100644 index 934e721948e320..00000000000000 --- a/third_party/lwip/repo/lwip/src/apps/httpd/makefsdata/makefsdata.c +++ /dev/null @@ -1,1033 +0,0 @@ -/** - * makefsdata: Converts a directory structure for use with the lwIP httpd. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Jim Pettinato - * Simon Goldschmidt - * - * @todo: - * - take TCP_MSS, LWIP_TCP_TIMESTAMPS and - * PAYLOAD_ALIGN_TYPE/PAYLOAD_ALIGNMENT as arguments - */ - -#include -#include -#ifdef WIN32 -#define WIN32_LEAN_AND_MEAN -#include "windows.h" -#else -#include -#endif -#include -#include -#include -#include - -/** Makefsdata can generate *all* files deflate-compressed (where file size shrinks). - * Since nearly all browsers support this, this is a good way to reduce ROM size. - * To compress the files, "miniz.c" must be downloaded seperately. - */ -#ifndef MAKEFS_SUPPORT_DEFLATE -#define MAKEFS_SUPPORT_DEFLATE 0 -#endif - -#define COPY_BUFSIZE (1024*1024) /* 1 MByte */ - -#if MAKEFS_SUPPORT_DEFLATE -#include "../miniz.c" - -typedef unsigned char uint8; -typedef unsigned short uint16; -typedef unsigned int uint; - -#define my_max(a,b) (((a) > (b)) ? (a) : (b)) -#define my_min(a,b) (((a) < (b)) ? (a) : (b)) - -/* COMP_OUT_BUF_SIZE is the size of the output buffer used during compression. - COMP_OUT_BUF_SIZE must be >= 1 and <= OUT_BUF_SIZE */ -#define COMP_OUT_BUF_SIZE COPY_BUFSIZE - -/* OUT_BUF_SIZE is the size of the output buffer used during decompression. - OUT_BUF_SIZE must be a power of 2 >= TINFL_LZ_DICT_SIZE (because the low-level decompressor not only writes, but reads from the output buffer as it decompresses) */ -#define OUT_BUF_SIZE COPY_BUFSIZE -static uint8 s_outbuf[OUT_BUF_SIZE]; -static uint8 s_checkbuf[OUT_BUF_SIZE]; - -/* tdefl_compressor contains all the state needed by the low-level compressor so it's a pretty big struct (~300k). - This example makes it a global vs. putting it on the stack, of course in real-world usage you'll probably malloc() or new it. */ -tdefl_compressor g_deflator; -tinfl_decompressor g_inflator; - -int deflate_level = 10; /* default compression level, can be changed via command line */ -#define USAGE_ARG_DEFLATE " [-defl<:compr_level>]" -#else /* MAKEFS_SUPPORT_DEFLATE */ -#define USAGE_ARG_DEFLATE "" -#endif /* MAKEFS_SUPPORT_DEFLATE */ - -/* Compatibility defines Win32 vs. DOS */ -#ifdef WIN32 - -#define FIND_T WIN32_FIND_DATAA -#define FIND_T_FILENAME(fInfo) (fInfo.cFileName) -#define FIND_T_IS_DIR(fInfo) ((fInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0) -#define FIND_T_IS_FILE(fInfo) ((fInfo.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) == 0) -#define FIND_RET_T HANDLE -#define FINDFIRST_FILE(path, result) FindFirstFileA(path, result) -#define FINDFIRST_DIR(path, result) FindFirstFileA(path, result) -#define FINDNEXT(ff_res, result) FindNextFileA(ff_res, result) -#define FINDFIRST_SUCCEEDED(ret) (ret != INVALID_HANDLE_VALUE) -#define FINDNEXT_SUCCEEDED(ret) (ret == TRUE) - -#define GETCWD(path, len) GetCurrentDirectoryA(len, path) -#define CHDIR(path) SetCurrentDirectoryA(path) -#define CHDIR_SUCCEEDED(ret) (ret == TRUE) - -#else - -#define FIND_T struct ffblk -#define FIND_T_FILENAME(fInfo) (fInfo.ff_name) -#define FIND_T_IS_DIR(fInfo) ((fInfo.ff_attrib & FA_DIREC) == FA_DIREC) -#define FIND_T_IS_FILE(fInfo) (1) -#define FIND_RET_T int -#define FINDFIRST_FILE(path, result) findfirst(path, result, FA_ARCH) -#define FINDFIRST_DIR(path, result) findfirst(path, result, FA_DIREC) -#define FINDNEXT(ff_res, result) FindNextFileA(ff_res, result) -#define FINDFIRST_SUCCEEDED(ret) (ret == 0) -#define FINDNEXT_SUCCEEDED(ret) (ret == 0) - -#define GETCWD(path, len) getcwd(path, len) -#define CHDIR(path) chdir(path) -#define CHDIR_SUCCEEDED(ret) (ret == 0) - -#endif - -#define NEWLINE "\r\n" -#define NEWLINE_LEN 2 - -/* define this to get the header variables we use to build HTTP headers */ -#define LWIP_HTTPD_DYNAMIC_HEADERS 1 -#define LWIP_HTTPD_SSI 1 -#include "lwip/init.h" -#include "../httpd_structs.h" -#include "lwip/apps/fs.h" - -#include "../core/inet_chksum.c" -#include "../core/def.c" - -/** (Your server name here) */ -const char *serverID = "Server: "HTTPD_SERVER_AGENT"\r\n"; -char serverIDBuffer[1024]; - -/* change this to suit your MEM_ALIGNMENT */ -#define PAYLOAD_ALIGNMENT 4 -/* set this to 0 to prevent aligning payload */ -#define ALIGN_PAYLOAD 1 -/* define this to a type that has the required alignment */ -#define PAYLOAD_ALIGN_TYPE "unsigned int" -static int payload_alingment_dummy_counter = 0; - -#define HEX_BYTES_PER_LINE 16 - -#define MAX_PATH_LEN 256 - -struct file_entry -{ - struct file_entry* next; - const char* filename_c; -}; - -int process_sub(FILE *data_file, FILE *struct_file); -int process_file(FILE *data_file, FILE *struct_file, const char *filename); -int file_write_http_header(FILE *data_file, const char *filename, int file_size, u16_t *http_hdr_len, - u16_t *http_hdr_chksum, u8_t provide_content_len, int is_compressed); -int file_put_ascii(FILE *file, const char *ascii_string, int len, int *i); -int s_put_ascii(char *buf, const char *ascii_string, int len, int *i); -void concat_files(const char *file1, const char *file2, const char *targetfile); -int check_path(char* path, size_t size); - -/* 5 bytes per char + 3 bytes per line */ -static char file_buffer_c[COPY_BUFSIZE * 5 + ((COPY_BUFSIZE / HEX_BYTES_PER_LINE) * 3)]; - -char curSubdir[MAX_PATH_LEN]; -char lastFileVar[MAX_PATH_LEN]; -char hdr_buf[4096]; - -unsigned char processSubs = 1; -unsigned char includeHttpHeader = 1; -unsigned char useHttp11 = 0; -unsigned char supportSsi = 1; -unsigned char precalcChksum = 0; -unsigned char includeLastModified = 0; -#if MAKEFS_SUPPORT_DEFLATE -unsigned char deflateNonSsiFiles = 0; -size_t deflatedBytesReduced = 0; -size_t overallDataBytes = 0; -#endif - -struct file_entry* first_file = NULL; -struct file_entry* last_file = NULL; - -static void print_usage(void) -{ - printf(" Usage: htmlgen [targetdir] [-s] [-e] [-i] [-11] [-nossi] [-c] [-f:] [-m] [-svr:]" USAGE_ARG_DEFLATE NEWLINE NEWLINE); - printf(" targetdir: relative or absolute path to files to convert" NEWLINE); - printf(" switch -s: toggle processing of subdirectories (default is on)" NEWLINE); - printf(" switch -e: exclude HTTP header from file (header is created at runtime, default is off)" NEWLINE); - printf(" switch -11: include HTTP 1.1 header (1.0 is default)" NEWLINE); - printf(" switch -nossi: no support for SSI (cannot calculate Content-Length for SSI)" NEWLINE); - printf(" switch -c: precalculate checksums for all pages (default is off)" NEWLINE); - printf(" switch -f: target filename (default is \"fsdata.c\")" NEWLINE); - printf(" switch -m: include \"Last-Modified\" header based on file time" NEWLINE); - printf(" switch -svr: server identifier sent in HTTP response header ('Server' field)" NEWLINE); -#if MAKEFS_SUPPORT_DEFLATE - printf(" switch -defl: deflate-compress all non-SSI files (with opt. compr.-level, default=10)" NEWLINE); - printf(" ATTENTION: browser has to support \"Content-Encoding: deflate\"!" NEWLINE); -#endif - printf(" if targetdir not specified, htmlgen will attempt to" NEWLINE); - printf(" process files in subdirectory 'fs'" NEWLINE); -} - -int main(int argc, char *argv[]) -{ - char path[MAX_PATH_LEN]; - char appPath[MAX_PATH_LEN]; - FILE *data_file; - FILE *struct_file; - int filesProcessed; - int i; - char targetfile[MAX_PATH_LEN]; - strcpy(targetfile, "fsdata.c"); - - memset(path, 0, sizeof(path)); - memset(appPath, 0, sizeof(appPath)); - - printf(NEWLINE " makefsdata - HTML to C source converter" NEWLINE); - printf(" by Jim Pettinato - circa 2003 " NEWLINE); - printf(" extended by Simon Goldschmidt - 2009 " NEWLINE NEWLINE); - - strcpy(path, "fs"); - for (i = 1; i < argc; i++) { - if (argv[i] == NULL) { - continue; - } - if (argv[i][0] == '-') { - if (strstr(argv[i], "-svr:") == argv[i]) { - snprintf(serverIDBuffer, sizeof(serverIDBuffer), "Server: %s\r\n", &argv[i][5]); - serverID = serverIDBuffer; - printf("Using Server-ID: \"%s\"\n", serverID); - } else if (strstr(argv[i], "-s") == argv[i]) { - processSubs = 0; - } else if (strstr(argv[i], "-e") == argv[i]) { - includeHttpHeader = 0; - } else if (strstr(argv[i], "-11") == argv[i]) { - useHttp11 = 1; - } else if (strstr(argv[i], "-nossi") == argv[i]) { - supportSsi = 0; - } else if (strstr(argv[i], "-c") == argv[i]) { - precalcChksum = 1; - } else if (strstr(argv[i], "-f:") == argv[i]) { - strncpy(targetfile, &argv[i][3], sizeof(targetfile) - 1); - targetfile[sizeof(targetfile) - 1] = 0; - printf("Writing to file \"%s\"\n", targetfile); - } else if (strstr(argv[i], "-m") == argv[i]) { - includeLastModified = 1; - } else if (strstr(argv[i], "-defl") == argv[i]) { -#if MAKEFS_SUPPORT_DEFLATE - char* colon = strstr(argv[i], ":"); - if (colon) { - if (colon[1] != 0) { - int defl_level = atoi(&colon[1]); - if ((defl_level >= 0) && (defl_level <= 10)) { - deflate_level = defl_level; - } else { - printf("ERROR: deflate level must be [0..10]" NEWLINE); - exit(0); - } - } - } - deflateNonSsiFiles = 1; - printf("Deflating all non-SSI files with level %d (but only if size is reduced)" NEWLINE, deflate_level); -#else - printf("WARNING: Deflate support is disabled\n"); -#endif - } else if ((strstr(argv[i], "-?")) || (strstr(argv[i], "-h"))) { - print_usage(); - exit(0); - } - } else if ((argv[i][0] == '/') && (argv[i][1] == '?') && (argv[i][2] == 0)) { - print_usage(); - exit(0); - } else { - strncpy(path, argv[i], sizeof(path)-1); - path[sizeof(path)-1] = 0; - } - } - - if (!check_path(path, sizeof(path))) { - printf("Invalid path: \"%s\"." NEWLINE, path); - exit(-1); - } - - GETCWD(appPath, MAX_PATH_LEN); - /* if command line param or subdir named 'fs' not found spout usage verbiage */ - if (!CHDIR_SUCCEEDED(CHDIR(path))) { - /* if no subdir named 'fs' (or the one which was given) exists, spout usage verbiage */ - printf(" Failed to open directory \"%s\"." NEWLINE NEWLINE, path); - print_usage(); - exit(-1); - } - CHDIR(appPath); - - printf("HTTP %sheader will %s statically included." NEWLINE, - (includeHttpHeader ? (useHttp11 ? "1.1 " : "1.0 ") : ""), - (includeHttpHeader ? "be" : "not be")); - - sprintf(curSubdir, ""); /* start off in web page's root directory - relative paths */ - printf(" Processing all files in directory %s", path); - if (processSubs) { - printf(" and subdirectories..." NEWLINE NEWLINE); - } else { - printf("..." NEWLINE NEWLINE); - } - - data_file = fopen("fsdata.tmp", "wb"); - if (data_file == NULL) { - printf("Failed to create file \"fsdata.tmp\"\n"); - exit(-1); - } - struct_file = fopen("fshdr.tmp", "wb"); - if (struct_file == NULL) { - printf("Failed to create file \"fshdr.tmp\"\n"); - fclose(data_file); - exit(-1); - } - - CHDIR(path); - - fprintf(data_file, "#include \"lwip/apps/fs.h\"" NEWLINE); - fprintf(data_file, "#include \"lwip/def.h\"" NEWLINE); - fprintf(data_file, "#include \"fsdata.h\"" NEWLINE NEWLINE NEWLINE); - - fprintf(data_file, "#define file_NULL (struct fsdata_file *) NULL" NEWLINE NEWLINE NEWLINE); - /* define FS_FILE_FLAGS_HEADER_INCLUDED to 1 if not defined (compatibility with older httpd/fs) */ - fprintf(data_file, "#ifndef FS_FILE_FLAGS_HEADER_INCLUDED" NEWLINE "#define FS_FILE_FLAGS_HEADER_INCLUDED 1" NEWLINE "#endif" NEWLINE); - /* define FS_FILE_FLAGS_HEADER_PERSISTENT to 0 if not defined (compatibility with older httpd/fs: wasn't supported back then) */ - fprintf(data_file, "#ifndef FS_FILE_FLAGS_HEADER_PERSISTENT" NEWLINE "#define FS_FILE_FLAGS_HEADER_PERSISTENT 0" NEWLINE "#endif" NEWLINE); - - /* define alignment defines */ -#if ALIGN_PAYLOAD - fprintf(data_file, "/* FSDATA_FILE_ALIGNMENT: 0=off, 1=by variable, 2=by include */" NEWLINE "#ifndef FSDATA_FILE_ALIGNMENT" NEWLINE "#define FSDATA_FILE_ALIGNMENT 0" NEWLINE "#endif" NEWLINE); -#endif - fprintf(data_file, "#ifndef FSDATA_ALIGN_PRE" NEWLINE "#define FSDATA_ALIGN_PRE" NEWLINE "#endif" NEWLINE); - fprintf(data_file, "#ifndef FSDATA_ALIGN_POST" NEWLINE "#define FSDATA_ALIGN_POST" NEWLINE "#endif" NEWLINE); -#if ALIGN_PAYLOAD - fprintf(data_file, "#if FSDATA_FILE_ALIGNMENT==2" NEWLINE "#include \"fsdata_alignment.h\"" NEWLINE "#endif" NEWLINE); -#endif - - sprintf(lastFileVar, "NULL"); - - filesProcessed = process_sub(data_file, struct_file); - - /* data_file now contains all of the raw data.. now append linked list of - * file header structs to allow embedded app to search for a file name */ - fprintf(data_file, NEWLINE NEWLINE); - fprintf(struct_file, "#define FS_ROOT file_%s" NEWLINE, lastFileVar); - fprintf(struct_file, "#define FS_NUMFILES %d" NEWLINE NEWLINE, filesProcessed); - - fclose(data_file); - fclose(struct_file); - - CHDIR(appPath); - /* append struct_file to data_file */ - printf(NEWLINE "Creating target file..." NEWLINE NEWLINE); - concat_files("fsdata.tmp", "fshdr.tmp", targetfile); - - /* if succeeded, delete the temporary files */ - if (remove("fsdata.tmp") != 0) { - printf("Warning: failed to delete fsdata.tmp\n"); - } - if (remove("fshdr.tmp") != 0) { - printf("Warning: failed to delete fshdr.tmp\n"); - } - - printf(NEWLINE "Processed %d files - done." NEWLINE, filesProcessed); -#if MAKEFS_SUPPORT_DEFLATE - if (deflateNonSsiFiles) { - printf("(Deflated total byte reduction: %d bytes -> %d bytes (%.02f%%)" NEWLINE, - (int)overallDataBytes, (int)deflatedBytesReduced, (float)((deflatedBytesReduced*100.0)/overallDataBytes)); - } -#endif - printf(NEWLINE); - - while (first_file != NULL) { - struct file_entry* fe = first_file; - first_file = fe->next; - free(fe); - } - - return 0; -} - -int check_path(char* path, size_t size) -{ - size_t slen; - if (path[0] == 0) { - /* empty */ - return 0; - } - slen = strlen(path); - if (slen >= size) { - /* not NULL-terminated */ - return 0; - } - while ((slen > 0) && ((path[slen] == '\\') || (path[slen] == '/'))) { - /* path should not end with trailing backslash */ - path[slen] = 0; - slen--; - } - if (slen == 0) { - return 0; - } - return 1; -} - -static void copy_file(const char *filename_in, FILE *fout) -{ - FILE *fin; - size_t len; - void* buf; - fin = fopen(filename_in, "rb"); - if (fin == NULL) { - printf("Failed to open file \"%s\"\n", filename_in); - exit(-1); - } - buf = malloc(COPY_BUFSIZE); - while ((len = fread(buf, 1, COPY_BUFSIZE, fin)) > 0) { - fwrite(buf, 1, len, fout); - } - free(buf); - fclose(fin); -} - -void concat_files(const char *file1, const char *file2, const char *targetfile) -{ - FILE *fout; - fout = fopen(targetfile, "wb"); - if (fout == NULL) { - printf("Failed to open file \"%s\"\n", targetfile); - exit(-1); - } - copy_file(file1, fout); - copy_file(file2, fout); - fclose(fout); -} - -int process_sub(FILE *data_file, FILE *struct_file) -{ - FIND_T fInfo; - FIND_RET_T fret; - int filesProcessed = 0; - - if (processSubs) { - /* process subs recursively */ - size_t sublen = strlen(curSubdir); - size_t freelen = sizeof(curSubdir) - sublen - 1; - LWIP_ASSERT("sublen < sizeof(curSubdir)", sublen < sizeof(curSubdir)); - fret = FINDFIRST_DIR("*", &fInfo); - if (FINDFIRST_SUCCEEDED(fret)) { - do { - const char *curName = FIND_T_FILENAME(fInfo); - if ((curName[0] == '.') || (strcmp(curName, "CVS") == 0)) { - continue; - } - if (!FIND_T_IS_DIR(fInfo)) { - continue; - } - if (freelen > 0) { - CHDIR(curName); - strncat(curSubdir, "/", freelen); - strncat(curSubdir, curName, freelen - 1); - curSubdir[sizeof(curSubdir) - 1] = 0; - printf("processing subdirectory %s/..." NEWLINE, curSubdir); - filesProcessed += process_sub(data_file, struct_file); - CHDIR(".."); - curSubdir[sublen] = 0; - } else { - printf("WARNING: cannot process sub due to path length restrictions: \"%s/%s\"\n", curSubdir, curName); - } - } while (FINDNEXT_SUCCEEDED(FINDNEXT(fret, &fInfo))); - } - } - - fret = FINDFIRST_FILE("*.*", &fInfo); - if (FINDFIRST_SUCCEEDED(fret)) { - /* at least one file in directory */ - do { - if (FIND_T_IS_FILE(fInfo)) { - const char *curName = FIND_T_FILENAME(fInfo); - printf("processing %s/%s..." NEWLINE, curSubdir, curName); - if (process_file(data_file, struct_file, curName) < 0) { - printf(NEWLINE "Error... aborting" NEWLINE); - return -1; - } - filesProcessed++; - } - } while (FINDNEXT_SUCCEEDED(FINDNEXT(fret, &fInfo))); - } - return filesProcessed; -} - -u8_t* get_file_data(const char* filename, int* file_size, int can_be_compressed, int* is_compressed) -{ - FILE *inFile; - size_t fsize = 0; - u8_t* buf; - size_t r; - int rs; - inFile = fopen(filename, "rb"); - if (inFile == NULL) { - printf("Failed to open file \"%s\"\n", filename); - exit(-1); - } - fseek(inFile, 0, SEEK_END); - rs = ftell(inFile); - if (rs < 0) { - printf("ftell failed with %d\n", errno); - exit(-1); - } - fsize = (size_t)rs; - fseek(inFile, 0, SEEK_SET); - buf = (u8_t*)malloc(fsize); - LWIP_ASSERT("buf != NULL", buf != NULL); - r = fread(buf, 1, fsize, inFile); - *file_size = fsize; - *is_compressed = 0; -#if MAKEFS_SUPPORT_DEFLATE - overallDataBytes += fsize; - if (deflateNonSsiFiles) { - if (can_be_compressed) { - if (fsize < OUT_BUF_SIZE) { - u8_t* ret_buf; - tdefl_status status; - size_t in_bytes = fsize; - size_t out_bytes = OUT_BUF_SIZE; - const void *next_in = buf; - void *next_out = s_outbuf; - /* create tdefl() compatible flags (we have to compose the low-level flags ourselves, or use tdefl_create_comp_flags_from_zip_params() but that means MINIZ_NO_ZLIB_APIS can't be defined). */ - mz_uint comp_flags = s_tdefl_num_probes[MZ_MIN(10, deflate_level)] | ((deflate_level <= 3) ? TDEFL_GREEDY_PARSING_FLAG : 0); - if (!deflate_level) { - comp_flags |= TDEFL_FORCE_ALL_RAW_BLOCKS; - } - status = tdefl_init(&g_deflator, NULL, NULL, comp_flags); - if (status != TDEFL_STATUS_OKAY) { - printf("tdefl_init() failed!\n"); - exit(-1); - } - memset(s_outbuf, 0, sizeof(s_outbuf)); - status = tdefl_compress(&g_deflator, next_in, &in_bytes, next_out, &out_bytes, TDEFL_FINISH); - if (status != TDEFL_STATUS_DONE) { - printf("deflate failed: %d\n", status); - exit(-1); - } - LWIP_ASSERT("out_bytes <= COPY_BUFSIZE", out_bytes <= OUT_BUF_SIZE); - if (out_bytes < fsize) { - ret_buf = (u8_t*)malloc(out_bytes); - LWIP_ASSERT("ret_buf != NULL", ret_buf != NULL); - memcpy(ret_buf, s_outbuf, out_bytes); - { - /* sanity-check compression be inflating and comparing to the original */ - tinfl_status dec_status; - tinfl_decompressor inflator; - size_t dec_in_bytes = out_bytes; - size_t dec_out_bytes = OUT_BUF_SIZE; - next_out = s_checkbuf; - - tinfl_init(&inflator); - memset(s_checkbuf, 0, sizeof(s_checkbuf)); - dec_status = tinfl_decompress(&inflator, (const mz_uint8 *)ret_buf, &dec_in_bytes, s_checkbuf, (mz_uint8 *)next_out, &dec_out_bytes, 0); - LWIP_ASSERT("tinfl_decompress failed", dec_status == TINFL_STATUS_DONE); - LWIP_ASSERT("tinfl_decompress size mismatch", fsize == dec_out_bytes); - LWIP_ASSERT("decompressed memcmp failed", !memcmp(s_checkbuf, buf, fsize)); - } - /* free original buffer, use compressed data + size */ - free(buf); - buf = ret_buf; - *file_size = out_bytes; - printf(" - deflate: %d bytes -> %d bytes (%.02f%%)" NEWLINE, (int)fsize, (int)out_bytes, (float)((out_bytes*100.0)/fsize)); - deflatedBytesReduced += (size_t)(fsize - out_bytes); - *is_compressed = 1; - } else { - printf(" - uncompressed: (would be %d bytes larger using deflate)" NEWLINE, (int)(out_bytes - fsize)); - } - } else { - printf(" - uncompressed: (file is larger than deflate bufer)" NEWLINE); - } - } else { - printf(" - SSI file, cannot be compressed" NEWLINE); - } - } -#else - LWIP_UNUSED_ARG(can_be_compressed); -#endif - fclose(inFile); - return buf; -} - -void process_file_data(FILE* data_file, u8_t* file_data, size_t file_size) -{ - size_t written, i, src_off=0; - - size_t off = 0; - for (i = 0; i < file_size; i++) { - LWIP_ASSERT("file_buffer_c overflow", off < sizeof(file_buffer_c) - 5); - sprintf(&file_buffer_c[off], "0x%02.2x,", file_data[i]); - off += 5; - if ((++src_off % HEX_BYTES_PER_LINE) == 0) { - LWIP_ASSERT("file_buffer_c overflow", off < sizeof(file_buffer_c) - NEWLINE_LEN); - memcpy(&file_buffer_c[off], NEWLINE, NEWLINE_LEN); - off += NEWLINE_LEN; - } - if (off + 20 >= sizeof(file_buffer_c)) { - written = fwrite(file_buffer_c, 1, off, data_file); - LWIP_ASSERT("written == off", written == off); - off = 0; - } - } - written = fwrite(file_buffer_c, 1, off, data_file); - LWIP_ASSERT("written == off", written == off); -} - -int write_checksums(FILE *struct_file, const char *varname, - u16_t hdr_len, u16_t hdr_chksum, const u8_t* file_data, size_t file_size) -{ - int chunk_size = TCP_MSS; - int offset, src_offset; - size_t len; - int i = 0; -#if LWIP_TCP_TIMESTAMPS - /* when timestamps are used, usable space is 12 bytes less per segment */ - chunk_size -= 12; -#endif - - fprintf(struct_file, "#if HTTPD_PRECALCULATED_CHECKSUM" NEWLINE); - fprintf(struct_file, "const struct fsdata_chksum chksums_%s[] = {" NEWLINE, varname); - - if (hdr_len > 0) { - /* add checksum for HTTP header */ - fprintf(struct_file, "{%d, 0x%04x, %d}," NEWLINE, 0, hdr_chksum, hdr_len); - i++; - } - src_offset = 0; - for (offset = hdr_len; ; offset += len) { - unsigned short chksum; - void* data = (void*)&file_data[src_offset]; - len = LWIP_MIN(chunk_size, (int)file_size - src_offset); - if (len == 0) { - break; - } - chksum = ~inet_chksum(data, (u16_t)len); - /* add checksum for data */ - fprintf(struct_file, "{%d, 0x%04x, %d}," NEWLINE, offset, chksum, len); - i++; - } - fprintf(struct_file, "};" NEWLINE); - fprintf(struct_file, "#endif /* HTTPD_PRECALCULATED_CHECKSUM */" NEWLINE); - return i; -} - -static int is_valid_char_for_c_var(char x) -{ - if (((x >= 'A') && (x <= 'Z')) || - ((x >= 'a') && (x <= 'z')) || - ((x >= '0') && (x <= '9')) || - (x == '_')) { - return 1; - } - return 0; -} - -static void fix_filename_for_c(char* qualifiedName, size_t max_len) -{ - struct file_entry* f; - size_t len = strlen(qualifiedName); - char *new_name = (char*)malloc(len + 2); - int filename_ok; - int cnt = 0; - size_t i; - if (len + 3 == max_len) { - printf("File name too long: \"%s\"\n", qualifiedName); - exit(-1); - } - strcpy(new_name, qualifiedName); - for (i = 0; i < len; i++) { - if (!is_valid_char_for_c_var(new_name[i])) { - new_name[i] = '_'; - } - } - do { - filename_ok = 1; - for (f = first_file; f != NULL; f = f->next) { - if (!strcmp(f->filename_c, new_name)) { - filename_ok = 0; - cnt++; - /* try next unique file name */ - sprintf(&new_name[len], "%d", cnt); - break; - } - } - } while (!filename_ok && (cnt < 999)); - if (!filename_ok) { - printf("Failed to get unique file name: \"%s\"\n", qualifiedName); - exit(-1); - } - strcpy(qualifiedName, new_name); - free(new_name); -} - -static void register_filename(const char* qualifiedName) -{ - struct file_entry* fe = (struct file_entry*)malloc(sizeof(struct file_entry)); - fe->filename_c = strdup(qualifiedName); - fe->next = NULL; - if (first_file == NULL) { - first_file = last_file = fe; - } else { - last_file->next = fe; - last_file = fe; - } -} - -int is_ssi_file(const char* filename) -{ - size_t loop; - for (loop = 0; loop < NUM_SHTML_EXTENSIONS; loop++) { - if (strstr(filename, g_pcSSIExtensions[loop])) { - return 1; - } - } - return 0; -} - -int process_file(FILE *data_file, FILE *struct_file, const char *filename) -{ - char varname[MAX_PATH_LEN]; - int i = 0; - char qualifiedName[MAX_PATH_LEN]; - int file_size; - u16_t http_hdr_chksum = 0; - u16_t http_hdr_len = 0; - int chksum_count = 0; - u8_t flags = 0; - const char* flags_str; - u8_t has_content_len; - u8_t* file_data; - int is_compressed = 0; - - /* create qualified name (@todo: prepend slash or not?) */ - sprintf(qualifiedName,"%s/%s", curSubdir, filename); - /* create C variable name */ - strcpy(varname, qualifiedName); - /* convert slashes & dots to underscores */ - fix_filename_for_c(varname, MAX_PATH_LEN); - register_filename(varname); -#if ALIGN_PAYLOAD - /* to force even alignment of array, type 1 */ - fprintf(data_file, "#if FSDATA_FILE_ALIGNMENT==1" NEWLINE); - fprintf(data_file, "static const " PAYLOAD_ALIGN_TYPE " dummy_align_%s = %d;" NEWLINE, varname, payload_alingment_dummy_counter++); - fprintf(data_file, "#endif" NEWLINE); -#endif /* ALIGN_PAYLOAD */ - fprintf(data_file, "static const unsigned char FSDATA_ALIGN_PRE data_%s[] FSDATA_ALIGN_POST = {" NEWLINE, varname); - /* encode source file name (used by file system, not returned to browser) */ - fprintf(data_file, "/* %s (%d chars) */" NEWLINE, qualifiedName, strlen(qualifiedName)+1); - file_put_ascii(data_file, qualifiedName, strlen(qualifiedName)+1, &i); -#if ALIGN_PAYLOAD - /* pad to even number of bytes to assure payload is on aligned boundary */ - while(i % PAYLOAD_ALIGNMENT != 0) { - fprintf(data_file, "0x%02.2x,", 0); - i++; - } -#endif /* ALIGN_PAYLOAD */ - fprintf(data_file, NEWLINE); - - has_content_len = !is_ssi_file(filename); - file_data = get_file_data(filename, &file_size, includeHttpHeader && has_content_len, &is_compressed); - if (includeHttpHeader) { - file_write_http_header(data_file, filename, file_size, &http_hdr_len, &http_hdr_chksum, has_content_len, is_compressed); - flags = FS_FILE_FLAGS_HEADER_INCLUDED; - if (has_content_len) { - flags |= FS_FILE_FLAGS_HEADER_PERSISTENT; - } - } - if (precalcChksum) { - chksum_count = write_checksums(struct_file, varname, http_hdr_len, http_hdr_chksum, file_data, file_size); - } - - /* build declaration of struct fsdata_file in temp file */ - fprintf(struct_file, "const struct fsdata_file file_%s[] = { {" NEWLINE, varname); - fprintf(struct_file, "file_%s," NEWLINE, lastFileVar); - fprintf(struct_file, "data_%s," NEWLINE, varname); - fprintf(struct_file, "data_%s + %d," NEWLINE, varname, i); - fprintf(struct_file, "sizeof(data_%s) - %d," NEWLINE, varname, i); - switch(flags) - { - case(FS_FILE_FLAGS_HEADER_INCLUDED): - flags_str = "FS_FILE_FLAGS_HEADER_INCLUDED"; - break; - case(FS_FILE_FLAGS_HEADER_PERSISTENT): - flags_str = "FS_FILE_FLAGS_HEADER_PERSISTENT"; - break; - case(FS_FILE_FLAGS_HEADER_INCLUDED | FS_FILE_FLAGS_HEADER_PERSISTENT): - flags_str = "FS_FILE_FLAGS_HEADER_INCLUDED | FS_FILE_FLAGS_HEADER_PERSISTENT"; - break; - default: - flags_str = "0"; - break; - } - fprintf(struct_file, "%s," NEWLINE, flags_str); - if (precalcChksum) { - fprintf(struct_file, "#if HTTPD_PRECALCULATED_CHECKSUM" NEWLINE); - fprintf(struct_file, "%d, chksums_%s," NEWLINE, chksum_count, varname); - fprintf(struct_file, "#endif /* HTTPD_PRECALCULATED_CHECKSUM */" NEWLINE); - } - fprintf(struct_file, "}};" NEWLINE NEWLINE); - strcpy(lastFileVar, varname); - - /* write actual file contents */ - i = 0; - fprintf(data_file, NEWLINE "/* raw file data (%d bytes) */" NEWLINE, file_size); - process_file_data(data_file, file_data, file_size); - fprintf(data_file, "};" NEWLINE NEWLINE); - free(file_data); - return 0; -} - -int file_write_http_header(FILE *data_file, const char *filename, int file_size, u16_t *http_hdr_len, - u16_t *http_hdr_chksum, u8_t provide_content_len, int is_compressed) -{ - int i = 0; - int response_type = HTTP_HDR_OK; - const char* file_type; - const char *cur_string; - size_t cur_len; - int written = 0; - size_t hdr_len = 0; - u16_t acc; - const char *file_ext; - int j; - u8_t provide_last_modified = includeLastModified; - - memset(hdr_buf, 0, sizeof(hdr_buf)); - - if (useHttp11) { - response_type = HTTP_HDR_OK_11; - } - - fprintf(data_file, NEWLINE "/* HTTP header */"); - if (strstr(filename, "404") == filename) { - response_type = HTTP_HDR_NOT_FOUND; - if (useHttp11) { - response_type = HTTP_HDR_NOT_FOUND_11; - } - } else if (strstr(filename, "400") == filename) { - response_type = HTTP_HDR_BAD_REQUEST; - if (useHttp11) { - response_type = HTTP_HDR_BAD_REQUEST_11; - } - } else if (strstr(filename, "501") == filename) { - response_type = HTTP_HDR_NOT_IMPL; - if (useHttp11) { - response_type = HTTP_HDR_NOT_IMPL_11; - } - } - cur_string = g_psHTTPHeaderStrings[response_type]; - cur_len = strlen(cur_string); - fprintf(data_file, NEWLINE "/* \"%s\" (%d bytes) */" NEWLINE, cur_string, cur_len); - written += file_put_ascii(data_file, cur_string, cur_len, &i); - i = 0; - if (precalcChksum) { - memcpy(&hdr_buf[hdr_len], cur_string, cur_len); - hdr_len += cur_len; - } - - cur_string = serverID; - cur_len = strlen(cur_string); - fprintf(data_file, NEWLINE "/* \"%s\" (%d bytes) */" NEWLINE, cur_string, cur_len); - written += file_put_ascii(data_file, cur_string, cur_len, &i); - i = 0; - if (precalcChksum) { - memcpy(&hdr_buf[hdr_len], cur_string, cur_len); - hdr_len += cur_len; - } - - file_ext = filename; - if (file_ext != NULL) { - while(strstr(file_ext, ".") != NULL) { - file_ext = strstr(file_ext, "."); - file_ext++; - } - } - if ((file_ext == NULL) || (*file_ext == 0)) { - printf("failed to get extension for file \"%s\", using default.\n", filename); - file_type = HTTP_HDR_DEFAULT_TYPE; - } else { - file_type = NULL; - for (j = 0; j < NUM_HTTP_HEADERS; j++) { - if (!strcmp(file_ext, g_psHTTPHeaders[j].extension)) { - file_type = g_psHTTPHeaders[j].content_type; - break; - } - } - if (file_type == NULL) { - printf("failed to get file type for extension \"%s\", using default.\n", file_ext); - file_type = HTTP_HDR_DEFAULT_TYPE; - } - } - - /* Content-Length is used for persistent connections in HTTP/1.1 but also for - download progress in older versions - @todo: just use a big-enough buffer and let the HTTPD send spaces? */ - if (provide_content_len) { - char intbuf[MAX_PATH_LEN]; - int content_len = file_size; - memset(intbuf, 0, sizeof(intbuf)); - cur_string = g_psHTTPHeaderStrings[HTTP_HDR_CONTENT_LENGTH]; - cur_len = strlen(cur_string); - fprintf(data_file, NEWLINE "/* \"%s%d\r\n\" (%d+ bytes) */" NEWLINE, cur_string, content_len, cur_len+2); - written += file_put_ascii(data_file, cur_string, cur_len, &i); - if (precalcChksum) { - memcpy(&hdr_buf[hdr_len], cur_string, cur_len); - hdr_len += cur_len; - } - - _itoa(content_len, intbuf, 10); - strcat(intbuf, "\r\n"); - cur_len = strlen(intbuf); - written += file_put_ascii(data_file, intbuf, cur_len, &i); - i = 0; - if (precalcChksum) { - memcpy(&hdr_buf[hdr_len], intbuf, cur_len); - hdr_len += cur_len; - } - } - if (provide_last_modified) { - char modbuf[256]; - struct stat stat_data; - struct tm* t; - memset(modbuf, 0, sizeof(modbuf)); - memset(&stat_data, 0, sizeof(stat_data)); - cur_string = modbuf; - strcpy(modbuf, "Last-Modified: "); - if (stat(filename, &stat_data) != 0) { - printf("stat(%s) failed with error %d\n", filename, errno); - exit(-1); - } - t = gmtime(&stat_data.st_mtime); - if (t == NULL) { - printf("gmtime() failed with error %d\n", errno); - exit(-1); - } - strftime(&modbuf[15], sizeof(modbuf)-15, "%a, %d %b %Y %H:%M:%S GMT", t); - cur_len = strlen(cur_string); - fprintf(data_file, NEWLINE "/* \"%s\"\r\n\" (%d+ bytes) */" NEWLINE, cur_string, cur_len+2); - written += file_put_ascii(data_file, cur_string, cur_len, &i); - if (precalcChksum) { - memcpy(&hdr_buf[hdr_len], cur_string, cur_len); - hdr_len += cur_len; - } - - modbuf[0] = 0; - strcat(modbuf, "\r\n"); - cur_len = strlen(modbuf); - written += file_put_ascii(data_file, modbuf, cur_len, &i); - i = 0; - if (precalcChksum) { - memcpy(&hdr_buf[hdr_len], modbuf, cur_len); - hdr_len += cur_len; - } - } - - /* HTTP/1.1 implements persistent connections */ - if (useHttp11) { - if (provide_content_len) { - cur_string = g_psHTTPHeaderStrings[HTTP_HDR_CONN_KEEPALIVE]; - } else { - /* no Content-Length available, so a persistent connection is no possible - because the client does not know the data length */ - cur_string = g_psHTTPHeaderStrings[HTTP_HDR_CONN_CLOSE]; - } - cur_len = strlen(cur_string); - fprintf(data_file, NEWLINE "/* \"%s\" (%d bytes) */" NEWLINE, cur_string, cur_len); - written += file_put_ascii(data_file, cur_string, cur_len, &i); - i = 0; - if (precalcChksum) { - memcpy(&hdr_buf[hdr_len], cur_string, cur_len); - hdr_len += cur_len; - } - } - -#if MAKEFS_SUPPORT_DEFLATE - if (is_compressed) { - /* tell the client about the deflate encoding */ - LWIP_ASSERT("error", deflateNonSsiFiles); - cur_string = "Content-Encoding: deflate\r\n"; - cur_len = strlen(cur_string); - fprintf(data_file, NEWLINE "/* \"%s\" (%d bytes) */" NEWLINE, cur_string, cur_len); - written += file_put_ascii(data_file, cur_string, cur_len, &i); - i = 0; - } -#else - LWIP_UNUSED_ARG(is_compressed); -#endif - - /* write content-type, ATTENTION: this includes the double-CRLF! */ - cur_string = file_type; - cur_len = strlen(cur_string); - fprintf(data_file, NEWLINE "/* \"%s\" (%d bytes) */" NEWLINE, cur_string, cur_len); - written += file_put_ascii(data_file, cur_string, cur_len, &i); - i = 0; - - /* ATTENTION: headers are done now (double-CRLF has been written!) */ - - if (precalcChksum) { - memcpy(&hdr_buf[hdr_len], cur_string, cur_len); - hdr_len += cur_len; - - LWIP_ASSERT("hdr_len <= 0xffff", hdr_len <= 0xffff); - LWIP_ASSERT("strlen(hdr_buf) == hdr_len", strlen(hdr_buf) == hdr_len); - acc = ~inet_chksum(hdr_buf, (u16_t)hdr_len); - *http_hdr_len = (u16_t)hdr_len; - *http_hdr_chksum = acc; - } - - return written; -} - -int file_put_ascii(FILE *file, const char* ascii_string, int len, int *i) -{ - int x; - for (x = 0; x < len; x++) { - unsigned char cur = ascii_string[x]; - fprintf(file, "0x%02.2x,", cur); - if ((++(*i) % HEX_BYTES_PER_LINE) == 0) { - fprintf(file, NEWLINE); - } - } - return len; -} - -int s_put_ascii(char *buf, const char *ascii_string, int len, int *i) -{ - int x; - int idx = 0; - for (x = 0; x < len; x++) { - unsigned char cur = ascii_string[x]; - sprintf(&buf[idx], "0x%02.2x,", cur); - idx += 5; - if ((++(*i) % HEX_BYTES_PER_LINE) == 0) { - sprintf(&buf[idx], NEWLINE); - idx += NEWLINE_LEN; - } - } - return len; -} diff --git a/third_party/lwip/repo/lwip/src/apps/httpd/makefsdata/readme.txt b/third_party/lwip/repo/lwip/src/apps/httpd/makefsdata/readme.txt deleted file mode 100644 index 3768585ef9228d..00000000000000 --- a/third_party/lwip/repo/lwip/src/apps/httpd/makefsdata/readme.txt +++ /dev/null @@ -1,13 +0,0 @@ -This directory contains a script ('makefsdata') to create C code suitable for -httpd for given html pages (or other files) in a directory. - -There is also a plain C console application doing the same and extended a bit. - -Usage: htmlgen [targetdir] [-s] [-i]s - targetdir: relative or absolute path to files to convert - switch -s: toggle processing of subdirectories (default is on) - switch -e: exclude HTTP header from file (header is created at runtime, default is on) - switch -11: include HTTP 1.1 header (1.0 is default) - - if targetdir not specified, makefsdata will attempt to - process files in subdirectory 'fs'. diff --git a/third_party/lwip/repo/lwip/src/apps/lwiperf/lwiperf.c b/third_party/lwip/repo/lwip/src/apps/lwiperf/lwiperf.c deleted file mode 100644 index efabe478e36f45..00000000000000 --- a/third_party/lwip/repo/lwip/src/apps/lwiperf/lwiperf.c +++ /dev/null @@ -1,661 +0,0 @@ -/** - * @file - * lwIP iPerf server implementation - */ - -/** - * @defgroup iperf Iperf server - * @ingroup apps - * - * This is a simple performance measuring server to check your bandwith using - * iPerf2 on a PC as client. - * It is currently a minimal implementation providing an IPv4 TCP server only. - * - * @todo: implement UDP mode and IPv6 - */ - -/* - * Copyright (c) 2014 Simon Goldschmidt - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Simon Goldschmidt - */ - -#include "lwip/apps/lwiperf.h" - -#include "lwip/tcp.h" -#include "lwip/sys.h" - -#include - -/* Currently, only TCP-over-IPv4 is implemented (does iperf support IPv6 anyway?) */ -#if LWIP_IPV4 && LWIP_TCP && LWIP_CALLBACK_API - -/** Specify the idle timeout (in seconds) after that the test fails */ -#ifndef LWIPERF_TCP_MAX_IDLE_SEC -#define LWIPERF_TCP_MAX_IDLE_SEC 10U -#endif -#if LWIPERF_TCP_MAX_IDLE_SEC > 255 -#error LWIPERF_TCP_MAX_IDLE_SEC must fit into an u8_t -#endif - -/* File internal memory allocation (struct lwiperf_*): this defaults to - the heap */ -#ifndef LWIPERF_ALLOC -#define LWIPERF_ALLOC(type) mem_malloc(sizeof(type)) -#define LWIPERF_FREE(type, item) mem_free(item) -#endif - -/** If this is 1, check that received data has the correct format */ -#ifndef LWIPERF_CHECK_RX_DATA -#define LWIPERF_CHECK_RX_DATA 0 -#endif - -/** This is the Iperf settings struct sent from the client */ -typedef struct _lwiperf_settings { -#define LWIPERF_FLAGS_ANSWER_TEST 0x80000000 -#define LWIPERF_FLAGS_ANSWER_NOW 0x00000001 - u32_t flags; - u32_t num_threads; /* unused for now */ - u32_t remote_port; - u32_t buffer_len; /* unused for now */ - u32_t win_band; /* TCP window / UDP rate: unused for now */ - u32_t amount; /* pos. value: bytes?; neg. values: time (unit is 10ms: 1/100 second) */ -} lwiperf_settings_t; - -/** Basic connection handle */ -struct _lwiperf_state_base; -typedef struct _lwiperf_state_base lwiperf_state_base_t; -struct _lwiperf_state_base { - /* 1=tcp, 0=udp */ - u8_t tcp; - /* 1=server, 0=client */ - u8_t server; - lwiperf_state_base_t* next; - lwiperf_state_base_t* related_server_state; -}; - -/** Connection handle for a TCP iperf session */ -typedef struct _lwiperf_state_tcp { - lwiperf_state_base_t base; - struct tcp_pcb* server_pcb; - struct tcp_pcb* conn_pcb; - u32_t time_started; - lwiperf_report_fn report_fn; - void* report_arg; - u8_t poll_count; - u8_t next_num; - u32_t bytes_transferred; - lwiperf_settings_t settings; - u8_t have_settings_buf; -} lwiperf_state_tcp_t; - -/** List of active iperf sessions */ -static lwiperf_state_base_t* lwiperf_all_connections; -/** A const buffer to send from: we want to measure sending, not copying! */ -static const u8_t lwiperf_txbuf_const[1600] = { - '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', - '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', - '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', - '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', - '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', - '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', - '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', - '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', - '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', - '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', - '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', - '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', - '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', - '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', - '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', - '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', - '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', - '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', - '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', - '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', - '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', - '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', - '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', - '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', - '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', - '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', - '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', - '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', - '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', - '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', - '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', - '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', - '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', - '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', - '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', - '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', - '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', - '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', - '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', - '0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9','0','1','2','3','4','5','6','7','8','9', -}; - -static err_t lwiperf_tcp_poll(void *arg, struct tcp_pcb *tpcb); -static void lwiperf_tcp_err(void *arg, err_t err); - -/** Add an iperf session to the 'active' list */ -static void -lwiperf_list_add(lwiperf_state_base_t* item) -{ - if (lwiperf_all_connections == NULL) { - lwiperf_all_connections = item; - } else { - item = lwiperf_all_connections; - } -} - -/** Remove an iperf session from the 'active' list */ -static void -lwiperf_list_remove(lwiperf_state_base_t* item) -{ - lwiperf_state_base_t* prev = NULL; - lwiperf_state_base_t* iter; - for (iter = lwiperf_all_connections; iter != NULL; prev = iter, iter = iter->next) { - if (iter == item) { - if (prev == NULL) { - lwiperf_all_connections = iter->next; - } else { - prev->next = item; - } - /* @debug: ensure this item is listed only once */ - for (iter = iter->next; iter != NULL; iter = iter->next) { - LWIP_ASSERT("duplicate entry", iter != item); - } - break; - } - } -} - -/** Call the report function of an iperf tcp session */ -static void -lwip_tcp_conn_report(lwiperf_state_tcp_t* conn, enum lwiperf_report_type report_type) -{ - if ((conn != NULL) && (conn->report_fn != NULL)) { - u32_t now, duration_ms, bandwidth_kbitpsec; - now = sys_now(); - duration_ms = now - conn->time_started; - if (duration_ms == 0) { - bandwidth_kbitpsec = 0; - } else { - bandwidth_kbitpsec = (conn->bytes_transferred / duration_ms) * 8U; - } - conn->report_fn(conn->report_arg, report_type, - &conn->conn_pcb->local_ip, conn->conn_pcb->local_port, - &conn->conn_pcb->remote_ip, conn->conn_pcb->remote_port, - conn->bytes_transferred, duration_ms, bandwidth_kbitpsec); - } -} - -/** Close an iperf tcp session */ -static void -lwiperf_tcp_close(lwiperf_state_tcp_t* conn, enum lwiperf_report_type report_type) -{ - err_t err; - - lwip_tcp_conn_report(conn, report_type); - lwiperf_list_remove(&conn->base); - if (conn->conn_pcb != NULL) { - tcp_arg(conn->conn_pcb, NULL); - tcp_poll(conn->conn_pcb, NULL, 0); - tcp_sent(conn->conn_pcb, NULL); - tcp_recv(conn->conn_pcb, NULL); - tcp_err(conn->conn_pcb, NULL); - err = tcp_close(conn->conn_pcb); - if (err != ERR_OK) { - /* don't want to wait for free memory here... */ - tcp_abort(conn->conn_pcb); - } - } else { - /* no conn pcb, this is the server pcb */ - err = tcp_close(conn->server_pcb); - LWIP_ASSERT("error", err != ERR_OK); - } - LWIPERF_FREE(lwiperf_state_tcp_t, conn); -} - -/** Try to send more data on an iperf tcp session */ -static err_t -lwiperf_tcp_client_send_more(lwiperf_state_tcp_t* conn) -{ - int send_more; - err_t err; - u16_t txlen; - u16_t txlen_max; - void* txptr; - u8_t apiflags; - - LWIP_ASSERT("conn invalid", (conn != NULL) && conn->base.tcp && (conn->base.server == 0)); - - do { - send_more = 0; - if (conn->settings.amount & PP_HTONL(0x80000000)) { - /* this session is time-limited */ - u32_t now = sys_now(); - u32_t diff_ms = now - conn->time_started; - u32_t time = (u32_t)-(s32_t)lwip_htonl(conn->settings.amount); - u32_t time_ms = time * 10; - if (diff_ms >= time_ms) { - /* time specified by the client is over -> close the connection */ - lwiperf_tcp_close(conn, LWIPERF_TCP_DONE_CLIENT); - return ERR_OK; - } - } else { - /* this session is byte-limited */ - u32_t amount_bytes = lwip_htonl(conn->settings.amount); - /* @todo: this can send up to 1*MSS more than requested... */ - if (amount_bytes >= conn->bytes_transferred) { - /* all requested bytes transferred -> close the connection */ - lwiperf_tcp_close(conn, LWIPERF_TCP_DONE_CLIENT); - return ERR_OK; - } - } - - if (conn->bytes_transferred < 24) { - /* transmit the settings a first time */ - txptr = &((u8_t*)&conn->settings)[conn->bytes_transferred]; - txlen_max = (u16_t)(24 - conn->bytes_transferred); - apiflags = TCP_WRITE_FLAG_COPY; - } else if (conn->bytes_transferred < 48) { - /* transmit the settings a second time */ - txptr = &((u8_t*)&conn->settings)[conn->bytes_transferred - 24]; - txlen_max = (u16_t)(48 - conn->bytes_transferred); - apiflags = TCP_WRITE_FLAG_COPY | TCP_WRITE_FLAG_MORE; - send_more = 1; - } else { - /* transmit data */ - /* @todo: every x bytes, transmit the settings again */ - txptr = LWIP_CONST_CAST(void*, &lwiperf_txbuf_const[conn->bytes_transferred % 10]); - txlen_max = TCP_MSS; - if (conn->bytes_transferred == 48) { /* @todo: fix this for intermediate settings, too */ - txlen_max = TCP_MSS - 24; - } - apiflags = 0; /* no copying needed */ - send_more = 1; - } - txlen = txlen_max; - do { - err = tcp_write(conn->conn_pcb, txptr, txlen, apiflags); - if (err == ERR_MEM) { - txlen /= 2; - } - } while ((err == ERR_MEM) && (txlen >= (TCP_MSS/2))); - - if (err == ERR_OK) { - conn->bytes_transferred += txlen; - } else { - send_more = 0; - } - } while(send_more); - - tcp_output(conn->conn_pcb); - return ERR_OK; -} - -/** TCP sent callback, try to send more data */ -static err_t -lwiperf_tcp_client_sent(void *arg, struct tcp_pcb *tpcb, u16_t len) -{ - lwiperf_state_tcp_t* conn = (lwiperf_state_tcp_t*)arg; - /* @todo: check 'len' (e.g. to time ACK of all data)? for now, we just send more... */ - LWIP_ASSERT("invalid conn", conn->conn_pcb == tpcb); - LWIP_UNUSED_ARG(tpcb); - LWIP_UNUSED_ARG(len); - - conn->poll_count = 0; - - return lwiperf_tcp_client_send_more(conn); -} - -/** TCP connected callback (active connection), send data now */ -static err_t -lwiperf_tcp_client_connected(void *arg, struct tcp_pcb *tpcb, err_t err) -{ - lwiperf_state_tcp_t* conn = (lwiperf_state_tcp_t*)arg; - LWIP_ASSERT("invalid conn", conn->conn_pcb == tpcb); - LWIP_UNUSED_ARG(tpcb); - if (err != ERR_OK) { - lwiperf_tcp_close(conn, LWIPERF_TCP_ABORTED_REMOTE); - return ERR_OK; - } - conn->poll_count = 0; - conn->time_started = sys_now(); - return lwiperf_tcp_client_send_more(conn); -} - -/** Start TCP connection back to the client (either parallel or after the - * receive test has finished. - */ -static err_t -lwiperf_tx_start(lwiperf_state_tcp_t* conn) -{ - err_t err; - lwiperf_state_tcp_t* client_conn; - struct tcp_pcb* newpcb; - ip_addr_t remote_addr; - u16_t remote_port; - - client_conn = (lwiperf_state_tcp_t*)LWIPERF_ALLOC(lwiperf_state_tcp_t); - if (client_conn == NULL) { - return ERR_MEM; - } - newpcb = tcp_new(); - if (newpcb == NULL) { - LWIPERF_FREE(lwiperf_state_tcp_t, client_conn); - return ERR_MEM; - } - - MEMCPY(client_conn, conn, sizeof(lwiperf_state_tcp_t)); - client_conn->base.server = 0; - client_conn->server_pcb = NULL; - client_conn->conn_pcb = newpcb; - client_conn->time_started = sys_now(); /* @todo: set this again on 'connected' */ - client_conn->poll_count = 0; - client_conn->next_num = 4; /* initial nr is '4' since the header has 24 byte */ - client_conn->bytes_transferred = 0; - client_conn->settings.flags = 0; /* prevent the remote side starting back as client again */ - - tcp_arg(newpcb, client_conn); - tcp_sent(newpcb, lwiperf_tcp_client_sent); - tcp_poll(newpcb, lwiperf_tcp_poll, 2U); - tcp_err(newpcb, lwiperf_tcp_err); - - ip_addr_copy(remote_addr, conn->conn_pcb->remote_ip); - remote_port = (u16_t)lwip_htonl(client_conn->settings.remote_port); - - err = tcp_connect(newpcb, &remote_addr, remote_port, lwiperf_tcp_client_connected); - if (err != ERR_OK) { - lwiperf_tcp_close(client_conn, LWIPERF_TCP_ABORTED_LOCAL); - return err; - } - lwiperf_list_add(&client_conn->base); - return ERR_OK; -} - -/** Receive data on an iperf tcp session */ -static err_t -lwiperf_tcp_recv(void *arg, struct tcp_pcb *tpcb, struct pbuf *p, err_t err) -{ - u8_t tmp; - u16_t tot_len; - u32_t packet_idx; - struct pbuf* q; - lwiperf_state_tcp_t* conn = (lwiperf_state_tcp_t*)arg; - - LWIP_ASSERT("pcb mismatch", conn->conn_pcb == tpcb); - LWIP_UNUSED_ARG(tpcb); - - if (err != ERR_OK) { - lwiperf_tcp_close(conn, LWIPERF_TCP_ABORTED_REMOTE); - return ERR_OK; - } - if (p == NULL) { - /* connection closed -> test done */ - if ((conn->settings.flags & PP_HTONL(LWIPERF_FLAGS_ANSWER_TEST|LWIPERF_FLAGS_ANSWER_NOW)) == - PP_HTONL(LWIPERF_FLAGS_ANSWER_TEST)) { - /* client requested transmission after end of test */ - lwiperf_tx_start(conn); - } - lwiperf_tcp_close(conn, LWIPERF_TCP_DONE_SERVER); - return ERR_OK; - } - tot_len = p->tot_len; - - conn->poll_count = 0; - - if ((!conn->have_settings_buf) || ((conn->bytes_transferred -24) % (1024*128) == 0)) { - /* wait for 24-byte header */ - if (p->tot_len < sizeof(lwiperf_settings_t)) { - lwiperf_tcp_close(conn, LWIPERF_TCP_ABORTED_LOCAL_DATAERROR); - pbuf_free(p); - return ERR_VAL; - } - if (!conn->have_settings_buf) { - if (pbuf_copy_partial(p, &conn->settings, sizeof(lwiperf_settings_t), 0) != sizeof(lwiperf_settings_t)) { - lwiperf_tcp_close(conn, LWIPERF_TCP_ABORTED_LOCAL); - pbuf_free(p); - return ERR_VAL; - } - conn->have_settings_buf = 1; - if ((conn->settings.flags & PP_HTONL(LWIPERF_FLAGS_ANSWER_TEST|LWIPERF_FLAGS_ANSWER_NOW)) == - PP_HTONL(LWIPERF_FLAGS_ANSWER_TEST|LWIPERF_FLAGS_ANSWER_NOW)) { - /* client requested parallel transmission test */ - err_t err2 = lwiperf_tx_start(conn); - if (err2 != ERR_OK) { - lwiperf_tcp_close(conn, LWIPERF_TCP_ABORTED_LOCAL_TXERROR); - pbuf_free(p); - return err2; - } - } - } else { - if (pbuf_memcmp(p, 0, &conn->settings, sizeof(lwiperf_settings_t)) != 0) { - lwiperf_tcp_close(conn, LWIPERF_TCP_ABORTED_LOCAL_DATAERROR); - pbuf_free(p); - return ERR_VAL; - } - } - conn->bytes_transferred += sizeof(lwiperf_settings_t); - if (conn->bytes_transferred <= 24) { - conn->time_started = sys_now(); - tcp_recved(tpcb, p->tot_len); - pbuf_free(p); - return ERR_OK; - } - conn->next_num = 4; /* 24 bytes received... */ - tmp = pbuf_header(p, -24); - LWIP_ASSERT("pbuf_header failed", tmp == 0); - } - - packet_idx = 0; - for (q = p; q != NULL; q = q->next) { -#if LWIPERF_CHECK_RX_DATA - const u8_t* payload = (const u8_t*)q->payload; - u16_t i; - for (i = 0; i < q->len; i++) { - u8_t val = payload[i]; - u8_t num = val - '0'; - if (num == conn->next_num) { - conn->next_num++; - if (conn->next_num == 10) { - conn->next_num = 0; - } - } else { - lwiperf_tcp_close(conn, LWIPERF_TCP_ABORTED_LOCAL_DATAERROR); - pbuf_free(p); - return ERR_VAL; - } - } -#endif - packet_idx += q->len; - } - LWIP_ASSERT("count mismatch", packet_idx == p->tot_len); - conn->bytes_transferred += packet_idx; - tcp_recved(tpcb, tot_len); - pbuf_free(p); - return ERR_OK; -} - -/** Error callback, iperf tcp session aborted */ -static void -lwiperf_tcp_err(void *arg, err_t err) -{ - lwiperf_state_tcp_t* conn = (lwiperf_state_tcp_t*)arg; - LWIP_UNUSED_ARG(err); - lwiperf_tcp_close(conn, LWIPERF_TCP_ABORTED_REMOTE); -} - -/** TCP poll callback, try to send more data */ -static err_t -lwiperf_tcp_poll(void *arg, struct tcp_pcb *tpcb) -{ - lwiperf_state_tcp_t* conn = (lwiperf_state_tcp_t*)arg; - LWIP_ASSERT("pcb mismatch", conn->conn_pcb == tpcb); - LWIP_UNUSED_ARG(tpcb); - if (++conn->poll_count >= LWIPERF_TCP_MAX_IDLE_SEC) { - lwiperf_tcp_close(conn, LWIPERF_TCP_ABORTED_LOCAL); - return ERR_OK; /* lwiperf_tcp_close frees conn */ - } - - if (!conn->base.server) { - lwiperf_tcp_client_send_more(conn); - } - - return ERR_OK; -} - -/** This is called when a new client connects for an iperf tcp session */ -static err_t -lwiperf_tcp_accept(void *arg, struct tcp_pcb *newpcb, err_t err) -{ - lwiperf_state_tcp_t *s, *conn; - if ((err != ERR_OK) || (newpcb == NULL) || (arg == NULL)) { - return ERR_VAL; - } - - s = (lwiperf_state_tcp_t*)arg; - conn = (lwiperf_state_tcp_t*)LWIPERF_ALLOC(lwiperf_state_tcp_t); - if (conn == NULL) { - return ERR_MEM; - } - memset(conn, 0, sizeof(lwiperf_state_tcp_t)); - conn->base.tcp = 1; - conn->base.server = 1; - conn->base.related_server_state = &s->base; - conn->server_pcb = s->server_pcb; - conn->conn_pcb = newpcb; - conn->time_started = sys_now(); - conn->report_fn = s->report_fn; - conn->report_arg = s->report_arg; - - /* setup the tcp rx connection */ - tcp_arg(newpcb, conn); - tcp_recv(newpcb, lwiperf_tcp_recv); - tcp_poll(newpcb, lwiperf_tcp_poll, 2U); - tcp_err(conn->conn_pcb, lwiperf_tcp_err); - - lwiperf_list_add(&conn->base); - return ERR_OK; -} - -/** - * @ingroup iperf - * Start a TCP iperf server on the default TCP port (5001) and listen for - * incoming connections from iperf clients. - * - * @returns a connection handle that can be used to abort the server - * by calling @ref lwiperf_abort() - */ -void* -lwiperf_start_tcp_server_default(lwiperf_report_fn report_fn, void* report_arg) -{ - return lwiperf_start_tcp_server(IP_ADDR_ANY, LWIPERF_TCP_PORT_DEFAULT, - report_fn, report_arg); -} - -/** - * @ingroup iperf - * Start a TCP iperf server on a specific IP address and port and listen for - * incoming connections from iperf clients. - * - * @returns a connection handle that can be used to abort the server - * by calling @ref lwiperf_abort() - */ -void* -lwiperf_start_tcp_server(const ip_addr_t* local_addr, u16_t local_port, - lwiperf_report_fn report_fn, void* report_arg) -{ - err_t err; - struct tcp_pcb* pcb; - lwiperf_state_tcp_t* s; - - if (local_addr == NULL) { - return NULL; - } - - s = (lwiperf_state_tcp_t*)LWIPERF_ALLOC(lwiperf_state_tcp_t); - if (s == NULL) { - return NULL; - } - memset(s, 0, sizeof(lwiperf_state_tcp_t)); - s->base.tcp = 1; - s->base.server = 1; - s->report_fn = report_fn; - s->report_arg = report_arg; - - pcb = tcp_new(); - if (pcb != NULL) { - err = tcp_bind(pcb, local_addr, local_port); - if (err == ERR_OK) { - s->server_pcb = tcp_listen_with_backlog(pcb, 1); - } - } - if (s->server_pcb == NULL) { - if (pcb != NULL) { - tcp_close(pcb); - } - LWIPERF_FREE(lwiperf_state_tcp_t, s); - return NULL; - } - pcb = NULL; - - tcp_arg(s->server_pcb, s); - tcp_accept(s->server_pcb, lwiperf_tcp_accept); - - lwiperf_list_add(&s->base); - return s; -} - -/** - * @ingroup iperf - * Abort an iperf session (handle returned by lwiperf_start_tcp_server*()) - */ -void -lwiperf_abort(void* lwiperf_session) -{ - lwiperf_state_base_t* i, *dealloc, *last = NULL; - - for (i = lwiperf_all_connections; i != NULL; ) { - if ((i == lwiperf_session) || (i->related_server_state == lwiperf_session)) { - dealloc = i; - i = i->next; - if (last != NULL) { - last->next = i; - } - LWIPERF_FREE(lwiperf_state_tcp_t, dealloc); /* @todo: type? */ - } else { - last = i; - i = i->next; - } - } -} - -#endif /* LWIP_IPV4 && LWIP_TCP && LWIP_CALLBACK_API */ diff --git a/third_party/lwip/repo/lwip/src/apps/mdns/mdns.c b/third_party/lwip/repo/lwip/src/apps/mdns/mdns.c deleted file mode 100644 index 14334fc856b8f5..00000000000000 --- a/third_party/lwip/repo/lwip/src/apps/mdns/mdns.c +++ /dev/null @@ -1,2028 +0,0 @@ -/** - * @file - * MDNS responder implementation - * - * @defgroup mdns MDNS - * @ingroup apps - * - * RFC 6762 - Multicast DNS\n - * RFC 6763 - DNS-Based Service Discovery\n - * - * @verbinclude mdns.txt - * - * Things left to implement: - * ------------------------- - * - * - Probing/conflict resolution - * - Sending goodbye messages (zero ttl) - shutdown, DHCP lease about to expire, DHCP turned off... - * - Checking that source address of unicast requests are on the same network - * - Limiting multicast responses to 1 per second per resource record - * - Fragmenting replies if required - * - Subscribe to netif address/link change events and act on them (currently needs to be done manually) - * - Handling multi-packet known answers - * - Individual known answer detection for all local IPv6 addresses - * - Dynamic size of outgoing packet - */ - -/* - * Copyright (c) 2015 Verisure Innovation AB - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Erik Ekman - * - */ - -#include "lwip/apps/mdns.h" -#include "lwip/apps/mdns_priv.h" -#include "lwip/netif.h" -#include "lwip/udp.h" -#include "lwip/ip_addr.h" -#include "lwip/mem.h" -#include "lwip/prot/dns.h" - -#include - -#if LWIP_MDNS_RESPONDER - -#if (LWIP_IPV4 && !LWIP_IGMP) - #error "If you want to use MDNS with IPv4, you have to define LWIP_IGMP=1 in your lwipopts.h" -#endif -#if (LWIP_IPV6 && !LWIP_IPV6_MLD) -#error "If you want to use MDNS with IPv6, you have to define LWIP_IPV6_MLD=1 in your lwipopts.h" -#endif -#if (!LWIP_UDP) - #error "If you want to use MDNS, you have to define LWIP_UDP=1 in your lwipopts.h" -#endif - -#if LWIP_IPV4 -#include "lwip/igmp.h" -/* IPv4 multicast group 224.0.0.251 */ -static const ip_addr_t v4group = DNS_MQUERY_IPV4_GROUP_INIT; -#endif - -#if LWIP_IPV6 -#include "lwip/mld6.h" -/* IPv6 multicast group FF02::FB */ -static const ip_addr_t v6group = DNS_MQUERY_IPV6_GROUP_INIT; -#endif - -#define MDNS_PORT 5353 -#define MDNS_TTL 255 - -/* Stored offsets to beginning of domain names - * Used for compression. - */ -#define NUM_DOMAIN_OFFSETS 10 -#define DOMAIN_JUMP_SIZE 2 -#define DOMAIN_JUMP 0xc000 - -static u8_t mdns_netif_client_id; -static struct udp_pcb *mdns_pcb; - -#define NETIF_TO_HOST(netif) (struct mdns_host*)(netif_get_client_data(netif, mdns_netif_client_id)) - -#define TOPDOMAIN_LOCAL "local" - -#define REVERSE_PTR_TOPDOMAIN "arpa" -#define REVERSE_PTR_V4_DOMAIN "in-addr" -#define REVERSE_PTR_V6_DOMAIN "ip6" - -#define SRV_PRIORITY 0 -#define SRV_WEIGHT 0 - -/* Payload size allocated for each outgoing UDP packet */ -#define OUTPACKET_SIZE 500 - -/* Lookup from hostname -> IPv4 */ -#define REPLY_HOST_A 0x01 -/* Lookup from IPv4/v6 -> hostname */ -#define REPLY_HOST_PTR_V4 0x02 -/* Lookup from hostname -> IPv6 */ -#define REPLY_HOST_AAAA 0x04 -/* Lookup from hostname -> IPv6 */ -#define REPLY_HOST_PTR_V6 0x08 - -/* Lookup for service types */ -#define REPLY_SERVICE_TYPE_PTR 0x10 -/* Lookup for instances of service */ -#define REPLY_SERVICE_NAME_PTR 0x20 -/* Lookup for location of service instance */ -#define REPLY_SERVICE_SRV 0x40 -/* Lookup for text info on service instance */ -#define REPLY_SERVICE_TXT 0x80 - -static const char *dnssd_protos[] = { - "_udp", /* DNSSD_PROTO_UDP */ - "_tcp", /* DNSSD_PROTO_TCP */ -}; - -/** Description of a service */ -struct mdns_service { - /** TXT record to answer with */ - struct mdns_domain txtdata; - /** Name of service, like 'myweb' */ - char name[MDNS_LABEL_MAXLEN + 1]; - /** Type of service, like '_http' */ - char service[MDNS_LABEL_MAXLEN + 1]; - /** Callback function and userdata - * to update txtdata buffer */ - service_get_txt_fn_t txt_fn; - void *txt_userdata; - /** TTL in seconds of SRV/TXT replies */ - u32_t dns_ttl; - /** Protocol, TCP or UDP */ - u16_t proto; - /** Port of the service */ - u16_t port; -}; - -/** Description of a host/netif */ -struct mdns_host { - /** Hostname */ - char name[MDNS_LABEL_MAXLEN + 1]; - /** Pointer to services */ - struct mdns_service *services[MDNS_MAX_SERVICES]; - /** TTL in seconds of A/AAAA/PTR replies */ - u32_t dns_ttl; -}; - -/** Information about received packet */ -struct mdns_packet { - /** Sender IP/port */ - ip_addr_t source_addr; - u16_t source_port; - /** If packet was received unicast */ - u16_t recv_unicast; - /** Netif that received the packet */ - struct netif *netif; - /** Packet data */ - struct pbuf *pbuf; - /** Current parsing offset in packet */ - u16_t parse_offset; - /** Identifier. Used in legacy queries */ - u16_t tx_id; - /** Number of questions in packet, - * read from packet header */ - u16_t questions; - /** Number of unparsed questions */ - u16_t questions_left; - /** Number of answers in packet, - * (sum of normal, authorative and additional answers) - * read from packet header */ - u16_t answers; - /** Number of unparsed answers */ - u16_t answers_left; -}; - -/** Information about outgoing packet */ -struct mdns_outpacket { - /** Netif to send the packet on */ - struct netif *netif; - /** Packet data */ - struct pbuf *pbuf; - /** Current write offset in packet */ - u16_t write_offset; - /** Identifier. Used in legacy queries */ - u16_t tx_id; - /** Destination IP/port if sent unicast */ - ip_addr_t dest_addr; - u16_t dest_port; - /** Number of questions written */ - u16_t questions; - /** Number of normal answers written */ - u16_t answers; - /** Number of additional answers written */ - u16_t additional; - /** Offsets for written domain names in packet. - * Used for compression */ - u16_t domain_offsets[NUM_DOMAIN_OFFSETS]; - /** If all answers in packet should set cache_flush bit */ - u8_t cache_flush; - /** If reply should be sent unicast */ - u8_t unicast_reply; - /** If legacy query. (tx_id needed, and write - * question again in reply before answer) */ - u8_t legacy_query; - /* Reply bitmask for host information */ - u8_t host_replies; - /* Bitmask for which reverse IPv6 hosts to answer */ - u8_t host_reverse_v6_replies; - /* Reply bitmask per service */ - u8_t serv_replies[MDNS_MAX_SERVICES]; -}; - -/** Domain, type and class. - * Shared between questions and answers */ -struct mdns_rr_info { - struct mdns_domain domain; - u16_t type; - u16_t klass; -}; - -struct mdns_question { - struct mdns_rr_info info; - /** unicast reply requested */ - u16_t unicast; -}; - -struct mdns_answer { - struct mdns_rr_info info; - /** cache flush command bit */ - u16_t cache_flush; - /* Validity time in seconds */ - u32_t ttl; - /** Length of variable answer */ - u16_t rd_length; - /** Offset of start of variable answer in packet */ - u16_t rd_offset; -}; - -/** - * Add a label part to a domain - * @param domain The domain to add a label to - * @param label The label to add, like <hostname>, 'local', 'com' or '' - * @param len The length of the label - * @return ERR_OK on success, an err_t otherwise if label too long - */ -err_t -mdns_domain_add_label(struct mdns_domain *domain, const char *label, u8_t len) -{ - if (len > MDNS_LABEL_MAXLEN) { - return ERR_VAL; - } - if (len > 0 && (1 + len + domain->length >= MDNS_DOMAIN_MAXLEN)) { - return ERR_VAL; - } - /* Allow only zero marker on last byte */ - if (len == 0 && (1 + domain->length > MDNS_DOMAIN_MAXLEN)) { - return ERR_VAL; - } - domain->name[domain->length] = len; - domain->length++; - if (len) { - MEMCPY(&domain->name[domain->length], label, len); - domain->length += len; - } - return ERR_OK; -} - -/** - * Internal readname function with max 6 levels of recursion following jumps - * while decompressing name - */ -static u16_t -mdns_readname_loop(struct pbuf *p, u16_t offset, struct mdns_domain *domain, unsigned depth) -{ - u8_t c; - - do { - if (depth > 5) { - /* Too many jumps */ - return MDNS_READNAME_ERROR; - } - - c = pbuf_get_at(p, offset); - offset++; - - /* is this a compressed label? */ - if((c & 0xc0) == 0xc0) { - u16_t jumpaddr; - if (offset >= p->tot_len) { - /* Make sure both jump bytes fit in the packet */ - return MDNS_READNAME_ERROR; - } - jumpaddr = (((c & 0x3f) << 8) | (pbuf_get_at(p, offset) & 0xff)); - offset++; - if (jumpaddr >= SIZEOF_DNS_HDR && jumpaddr < p->tot_len) { - u16_t res; - /* Recursive call, maximum depth will be checked */ - res = mdns_readname_loop(p, jumpaddr, domain, depth + 1); - /* Dont return offset since new bytes were not read (jumped to somewhere in packet) */ - if (res == MDNS_READNAME_ERROR) { - return res; - } - } else { - return MDNS_READNAME_ERROR; - } - break; - } - - /* normal label */ - if (c <= MDNS_LABEL_MAXLEN) { - u8_t label[MDNS_LABEL_MAXLEN]; - err_t res; - - if (c + domain->length >= MDNS_DOMAIN_MAXLEN) { - return MDNS_READNAME_ERROR; - } - if (c != 0) { - if (pbuf_copy_partial(p, label, c, offset) != c) { - return MDNS_READNAME_ERROR; - } - offset += c; - } - res = mdns_domain_add_label(domain, (char *) label, c); - if (res != ERR_OK) { - return MDNS_READNAME_ERROR; - } - } else { - /* bad length byte */ - return MDNS_READNAME_ERROR; - } - } while (c != 0); - - return offset; -} - -/** - * Read possibly compressed domain name from packet buffer - * @param p The packet - * @param offset start position of domain name in packet - * @param domain The domain name destination - * @return The new offset after the domain, or MDNS_READNAME_ERROR - * if reading failed - */ -u16_t -mdns_readname(struct pbuf *p, u16_t offset, struct mdns_domain *domain) -{ - memset(domain, 0, sizeof(struct mdns_domain)); - return mdns_readname_loop(p, offset, domain, 0); -} - -/** - * Print domain name to debug output - * @param domain The domain name - */ -static void -mdns_domain_debug_print(struct mdns_domain *domain) -{ - u8_t *src = domain->name; - u8_t i; - - while (*src) { - u8_t label_len = *src; - src++; - for (i = 0; i < label_len; i++) { - LWIP_DEBUGF(MDNS_DEBUG, ("%c", src[i])); - } - src += label_len; - LWIP_DEBUGF(MDNS_DEBUG, (".")); - } -} - -/** - * Return 1 if contents of domains match (case-insensitive) - * @param a Domain name to compare 1 - * @param b Domain name to compare 2 - * @return 1 if domains are equal ignoring case, 0 otherwise - */ -int -mdns_domain_eq(struct mdns_domain *a, struct mdns_domain *b) -{ - u8_t *ptra, *ptrb; - u8_t len; - int res; - - if (a->length != b->length) { - return 0; - } - - ptra = a->name; - ptrb = b->name; - while (*ptra && *ptrb && ptra < &a->name[a->length]) { - if (*ptra != *ptrb) { - return 0; - } - len = *ptra; - ptra++; - ptrb++; - res = lwip_strnicmp((char *) ptra, (char *) ptrb, len); - if (res != 0) { - return 0; - } - ptra += len; - ptrb += len; - } - if (*ptra != *ptrb && ptra < &a->name[a->length]) { - return 0; - } - return 1; -} - -/** - * Call user supplied function to setup TXT data - * @param service The service to build TXT record for - */ -static void -mdns_prepare_txtdata(struct mdns_service *service) -{ - memset(&service->txtdata, 0, sizeof(struct mdns_domain)); - if (service->txt_fn) { - service->txt_fn(service, service->txt_userdata); - } -} - -#if LWIP_IPV4 -/** - * Build domain for reverse lookup of IPv4 address - * like 12.0.168.192.in-addr.arpa. for 192.168.0.12 - * @param domain Where to write the domain name - * @param addr Pointer to an IPv4 address to encode - * @return ERR_OK if domain was written, an err_t otherwise - */ -static err_t -mdns_build_reverse_v4_domain(struct mdns_domain *domain, const ip4_addr_t *addr) -{ - int i; - err_t res; - const u8_t *ptr; - if (!domain || !addr) { - return ERR_ARG; - } - memset(domain, 0, sizeof(struct mdns_domain)); - ptr = (const u8_t *) addr; - for (i = sizeof(ip4_addr_t) - 1; i >= 0; i--) { - char buf[4]; - u8_t val = ptr[i]; - - lwip_itoa(buf, sizeof(buf), val); - res = mdns_domain_add_label(domain, buf, (u8_t)strlen(buf)); - LWIP_ERROR("mdns_build_reverse_v4_domain: Failed to add label", (res == ERR_OK), return res); - } - res = mdns_domain_add_label(domain, REVERSE_PTR_V4_DOMAIN, (u8_t)(sizeof(REVERSE_PTR_V4_DOMAIN)-1)); - LWIP_ERROR("mdns_build_reverse_v4_domain: Failed to add label", (res == ERR_OK), return res); - res = mdns_domain_add_label(domain, REVERSE_PTR_TOPDOMAIN, (u8_t)(sizeof(REVERSE_PTR_TOPDOMAIN)-1)); - LWIP_ERROR("mdns_build_reverse_v4_domain: Failed to add label", (res == ERR_OK), return res); - res = mdns_domain_add_label(domain, NULL, 0); - LWIP_ERROR("mdns_build_reverse_v4_domain: Failed to add label", (res == ERR_OK), return res); - - return ERR_OK; -} -#endif - -#if LWIP_IPV6 -/** - * Build domain for reverse lookup of IP address - * like b.a.9.8.7.6.5.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.b.d.0.1.0.0.2.ip6.arpa. for 2001:db8::567:89ab - * @param domain Where to write the domain name - * @param addr Pointer to an IPv6 address to encode - * @return ERR_OK if domain was written, an err_t otherwise - */ -static err_t -mdns_build_reverse_v6_domain(struct mdns_domain *domain, const ip6_addr_t *addr) -{ - int i; - err_t res; - const u8_t *ptr; - if (!domain || !addr) { - return ERR_ARG; - } - memset(domain, 0, sizeof(struct mdns_domain)); - ptr = (const u8_t *) addr; - for (i = sizeof(ip6_addr_t) - 1; i >= 0; i--) { - char buf; - u8_t byte = ptr[i]; - int j; - for (j = 0; j < 2; j++) { - if ((byte & 0x0F) < 0xA) { - buf = '0' + (byte & 0x0F); - } else { - buf = 'a' + (byte & 0x0F) - 0xA; - } - res = mdns_domain_add_label(domain, &buf, sizeof(buf)); - LWIP_ERROR("mdns_build_reverse_v6_domain: Failed to add label", (res == ERR_OK), return res); - byte >>= 4; - } - } - res = mdns_domain_add_label(domain, REVERSE_PTR_V6_DOMAIN, (u8_t)(sizeof(REVERSE_PTR_V6_DOMAIN)-1)); - LWIP_ERROR("mdns_build_reverse_v6_domain: Failed to add label", (res == ERR_OK), return res); - res = mdns_domain_add_label(domain, REVERSE_PTR_TOPDOMAIN, (u8_t)(sizeof(REVERSE_PTR_TOPDOMAIN)-1)); - LWIP_ERROR("mdns_build_reverse_v6_domain: Failed to add label", (res == ERR_OK), return res); - res = mdns_domain_add_label(domain, NULL, 0); - LWIP_ERROR("mdns_build_reverse_v6_domain: Failed to add label", (res == ERR_OK), return res); - - return ERR_OK; -} -#endif - -/* Add .local. to domain */ -static err_t -mdns_add_dotlocal(struct mdns_domain *domain) -{ - err_t res = mdns_domain_add_label(domain, TOPDOMAIN_LOCAL, (u8_t)(sizeof(TOPDOMAIN_LOCAL)-1)); - LWIP_ERROR("mdns_add_dotlocal: Failed to add label", (res == ERR_OK), return res); - return mdns_domain_add_label(domain, NULL, 0); -} - -/** - * Build the .local. domain name - * @param domain Where to write the domain name - * @param mdns TMDNS netif descriptor. - * @return ERR_OK if domain .local. was written, an err_t otherwise - */ -static err_t -mdns_build_host_domain(struct mdns_domain *domain, struct mdns_host *mdns) -{ - err_t res; - memset(domain, 0, sizeof(struct mdns_domain)); - LWIP_ERROR("mdns_build_host_domain: mdns != NULL", (mdns != NULL), return ERR_VAL); - res = mdns_domain_add_label(domain, mdns->name, (u8_t)strlen(mdns->name)); - LWIP_ERROR("mdns_build_host_domain: Failed to add label", (res == ERR_OK), return res); - return mdns_add_dotlocal(domain); -} - -/** - * Build the lookup-all-services special DNS-SD domain name - * @param domain Where to write the domain name - * @return ERR_OK if domain _services._dns-sd._udp.local. was written, an err_t otherwise - */ -static err_t -mdns_build_dnssd_domain(struct mdns_domain *domain) -{ - err_t res; - memset(domain, 0, sizeof(struct mdns_domain)); - res = mdns_domain_add_label(domain, "_services", (u8_t)(sizeof("_services")-1)); - LWIP_ERROR("mdns_build_dnssd_domain: Failed to add label", (res == ERR_OK), return res); - res = mdns_domain_add_label(domain, "_dns-sd", (u8_t)(sizeof("_dns-sd")-1)); - LWIP_ERROR("mdns_build_dnssd_domain: Failed to add label", (res == ERR_OK), return res); - res = mdns_domain_add_label(domain, dnssd_protos[DNSSD_PROTO_UDP], (u8_t)strlen(dnssd_protos[DNSSD_PROTO_UDP])); - LWIP_ERROR("mdns_build_dnssd_domain: Failed to add label", (res == ERR_OK), return res); - return mdns_add_dotlocal(domain); -} - -/** - * Build domain name for a service - * @param domain Where to write the domain name - * @param service The service struct, containing service name, type and protocol - * @param include_name Whether to include the service name in the domain - * @return ERR_OK if domain was written. If service name is included, - * ...local. will be written, otherwise ..local. - * An err_t is returned on error. - */ -static err_t -mdns_build_service_domain(struct mdns_domain *domain, struct mdns_service *service, int include_name) -{ - err_t res; - memset(domain, 0, sizeof(struct mdns_domain)); - if (include_name) { - res = mdns_domain_add_label(domain, service->name, (u8_t)strlen(service->name)); - LWIP_ERROR("mdns_build_service_domain: Failed to add label", (res == ERR_OK), return res); - } - res = mdns_domain_add_label(domain, service->service, (u8_t)strlen(service->service)); - LWIP_ERROR("mdns_build_service_domain: Failed to add label", (res == ERR_OK), return res); - res = mdns_domain_add_label(domain, dnssd_protos[service->proto], (u8_t)strlen(dnssd_protos[service->proto])); - LWIP_ERROR("mdns_build_service_domain: Failed to add label", (res == ERR_OK), return res); - return mdns_add_dotlocal(domain); -} - -/** - * Check which replies we should send for a host/netif based on question - * @param netif The network interface that received the question - * @param rr Domain/type/class from a question - * @param reverse_v6_reply Bitmask of which IPv6 addresses to send reverse PTRs for - * if reply bit has REPLY_HOST_PTR_V6 set - * @return Bitmask of which replies to send - */ -static int -check_host(struct netif *netif, struct mdns_rr_info *rr, u8_t *reverse_v6_reply) -{ - err_t res; - int replies = 0; - struct mdns_domain mydomain; - - LWIP_UNUSED_ARG(reverse_v6_reply); /* if ipv6 is disabled */ - - if (rr->klass != DNS_RRCLASS_IN && rr->klass != DNS_RRCLASS_ANY) { - /* Invalid class */ - return replies; - } - - /* Handle PTR for our addresses */ - if (rr->type == DNS_RRTYPE_PTR || rr->type == DNS_RRTYPE_ANY) { -#if LWIP_IPV6 - int i; - for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { - if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i))) { - res = mdns_build_reverse_v6_domain(&mydomain, netif_ip6_addr(netif, i)); - if (res == ERR_OK && mdns_domain_eq(&rr->domain, &mydomain)) { - replies |= REPLY_HOST_PTR_V6; - /* Mark which addresses where requested */ - if (reverse_v6_reply) { - *reverse_v6_reply |= (1 << i); - } - } - } - } -#endif -#if LWIP_IPV4 - if (!ip4_addr_isany_val(*netif_ip4_addr(netif))) { - res = mdns_build_reverse_v4_domain(&mydomain, netif_ip4_addr(netif)); - if (res == ERR_OK && mdns_domain_eq(&rr->domain, &mydomain)) { - replies |= REPLY_HOST_PTR_V4; - } - } -#endif - } - - res = mdns_build_host_domain(&mydomain, NETIF_TO_HOST(netif)); - /* Handle requests for our hostname */ - if (res == ERR_OK && mdns_domain_eq(&rr->domain, &mydomain)) { - /* TODO return NSEC if unsupported protocol requested */ -#if LWIP_IPV4 - if (!ip4_addr_isany_val(*netif_ip4_addr(netif)) - && (rr->type == DNS_RRTYPE_A || rr->type == DNS_RRTYPE_ANY)) { - replies |= REPLY_HOST_A; - } -#endif -#if LWIP_IPV6 - if (rr->type == DNS_RRTYPE_AAAA || rr->type == DNS_RRTYPE_ANY) { - replies |= REPLY_HOST_AAAA; - } -#endif - } - - return replies; -} - -/** - * Check which replies we should send for a service based on question - * @param service A registered MDNS service - * @param rr Domain/type/class from a question - * @return Bitmask of which replies to send - */ -static int -check_service(struct mdns_service *service, struct mdns_rr_info *rr) -{ - err_t res; - int replies = 0; - struct mdns_domain mydomain; - - if (rr->klass != DNS_RRCLASS_IN && rr->klass != DNS_RRCLASS_ANY) { - /* Invalid class */ - return 0; - } - - res = mdns_build_dnssd_domain(&mydomain); - if (res == ERR_OK && mdns_domain_eq(&rr->domain, &mydomain) && - (rr->type == DNS_RRTYPE_PTR || rr->type == DNS_RRTYPE_ANY)) { - /* Request for all service types */ - replies |= REPLY_SERVICE_TYPE_PTR; - } - - res = mdns_build_service_domain(&mydomain, service, 0); - if (res == ERR_OK && mdns_domain_eq(&rr->domain, &mydomain) && - (rr->type == DNS_RRTYPE_PTR || rr->type == DNS_RRTYPE_ANY)) { - /* Request for the instance of my service */ - replies |= REPLY_SERVICE_NAME_PTR; - } - - res = mdns_build_service_domain(&mydomain, service, 1); - if (res == ERR_OK && mdns_domain_eq(&rr->domain, &mydomain)) { - /* Request for info about my service */ - if (rr->type == DNS_RRTYPE_SRV || rr->type == DNS_RRTYPE_ANY) { - replies |= REPLY_SERVICE_SRV; - } - if (rr->type == DNS_RRTYPE_TXT || rr->type == DNS_RRTYPE_ANY) { - replies |= REPLY_SERVICE_TXT; - } - } - - return replies; -} - -/** - * Return bytes needed to write before jump for best result of compressing supplied domain - * against domain in outpacket starting at specified offset. - * If a match is found, offset is updated to where to jump to - * @param pbuf Pointer to pbuf with the partially constructed DNS packet - * @param offset Start position of a domain written earlier. If this location is suitable - * for compression, the pointer is updated to where in the domain to jump to. - * @param domain The domain to write - * @return Number of bytes to write of the new domain before writing a jump to the offset. - * If compression can not be done against this previous domain name, the full new - * domain length is returned. - */ -u16_t -mdns_compress_domain(struct pbuf *pbuf, u16_t *offset, struct mdns_domain *domain) -{ - struct mdns_domain target; - u16_t target_end; - u8_t target_len; - u8_t writelen = 0; - u8_t *ptr; - if (pbuf == NULL) { - return domain->length; - } - target_end = mdns_readname(pbuf, *offset, &target); - if (target_end == MDNS_READNAME_ERROR) { - return domain->length; - } - target_len = (u8_t)(target_end - *offset); - ptr = domain->name; - while (writelen < domain->length) { - u8_t domainlen = (u8_t)(domain->length - writelen); - u8_t labellen; - if (domainlen <= target.length && domainlen > DOMAIN_JUMP_SIZE) { - /* Compare domains if target is long enough, and we have enough left of the domain */ - u8_t targetpos = (u8_t)(target.length - domainlen); - if ((targetpos + DOMAIN_JUMP_SIZE) >= target_len) { - /* We are checking at or beyond a jump in the original, stop looking */ - break; - } - if (target.length >= domainlen && - memcmp(&domain->name[writelen], &target.name[targetpos], domainlen) == 0) { - *offset += targetpos; - return writelen; - } - } - /* Skip to next label in domain */ - labellen = *ptr; - writelen += 1 + labellen; - ptr += 1 + labellen; - } - /* Nothing found */ - return domain->length; -} - -/** - * Write domain to outpacket. Compression will be attempted, - * unless domain->skip_compression is set. - * @param outpkt The outpacket to write to - * @param domain The domain name to write - * @return ERR_OK on success, an err_t otherwise - */ -static err_t -mdns_write_domain(struct mdns_outpacket *outpkt, struct mdns_domain *domain) -{ - int i; - err_t res; - u16_t writelen = domain->length; - u16_t jump_offset = 0; - u16_t jump; - - if (!domain->skip_compression) { - for (i = 0; i < NUM_DOMAIN_OFFSETS; ++i) { - u16_t offset = outpkt->domain_offsets[i]; - if (offset) { - u16_t len = mdns_compress_domain(outpkt->pbuf, &offset, domain); - if (len < writelen) { - writelen = len; - jump_offset = offset; - } - } - } - } - - if (writelen) { - /* Write uncompressed part of name */ - res = pbuf_take_at(outpkt->pbuf, domain->name, writelen, outpkt->write_offset); - if (res != ERR_OK) { - return res; - } - - /* Store offset of this new domain */ - for (i = 0; i < NUM_DOMAIN_OFFSETS; ++i) { - if (outpkt->domain_offsets[i] == 0) { - outpkt->domain_offsets[i] = outpkt->write_offset; - break; - } - } - - outpkt->write_offset += writelen; - } - if (jump_offset) { - /* Write jump */ - jump = lwip_htons(DOMAIN_JUMP | jump_offset); - res = pbuf_take_at(outpkt->pbuf, &jump, DOMAIN_JUMP_SIZE, outpkt->write_offset); - if (res != ERR_OK) { - return res; - } - outpkt->write_offset += DOMAIN_JUMP_SIZE; - } - return ERR_OK; -} - -/** - * Write a question to an outpacket - * A question contains domain, type and class. Since an answer also starts with these fields this function is also - * called from mdns_add_answer(). - * @param outpkt The outpacket to write to - * @param domain The domain name the answer is for - * @param type The DNS type of the answer (like 'AAAA', 'SRV') - * @param klass The DNS type of the answer (like 'IN') - * @param unicast If highest bit in class should be set, to instruct the responder to - * reply with a unicast packet - * @return ERR_OK on success, an err_t otherwise - */ -static err_t -mdns_add_question(struct mdns_outpacket *outpkt, struct mdns_domain *domain, u16_t type, u16_t klass, u16_t unicast) -{ - u16_t question_len; - u16_t field16; - err_t res; - - if (!outpkt->pbuf) { - /* If no pbuf is active, allocate one */ - outpkt->pbuf = pbuf_alloc(PBUF_TRANSPORT, OUTPACKET_SIZE, PBUF_RAM); - if (!outpkt->pbuf) { - return ERR_MEM; - } - outpkt->write_offset = SIZEOF_DNS_HDR; - } - - /* Worst case calculation. Domain string might be compressed */ - question_len = domain->length + sizeof(type) + sizeof(klass); - if (outpkt->write_offset + question_len > outpkt->pbuf->tot_len) { - /* No space */ - return ERR_MEM; - } - - /* Write name */ - res = mdns_write_domain(outpkt, domain); - if (res != ERR_OK) { - return res; - } - - /* Write type */ - field16 = lwip_htons(type); - res = pbuf_take_at(outpkt->pbuf, &field16, sizeof(field16), outpkt->write_offset); - if (res != ERR_OK) { - return res; - } - outpkt->write_offset += sizeof(field16); - - /* Write class */ - if (unicast) { - klass |= 0x8000; - } - field16 = lwip_htons(klass); - res = pbuf_take_at(outpkt->pbuf, &field16, sizeof(field16), outpkt->write_offset); - if (res != ERR_OK) { - return res; - } - outpkt->write_offset += sizeof(field16); - - return ERR_OK; -} - -/** - * Write answer to reply packet. - * buf or answer_domain can be null. The rd_length written will be buf_length + - * size of (compressed) domain. Most uses will need either buf or answer_domain, - * special case is SRV that starts with 3 u16 and then a domain name. - * @param reply The outpacket to write to - * @param domain The domain name the answer is for - * @param type The DNS type of the answer (like 'AAAA', 'SRV') - * @param klass The DNS type of the answer (like 'IN') - * @param cache_flush If highest bit in class should be set, to instruct receiver that - * this reply replaces any earlier answer for this domain/type/class - * @param ttl Validity time in seconds to send out for IP address data in DNS replies - * @param buf Pointer to buffer of answer data - * @param buf_length Length of variable data - * @param answer_domain A domain to write after any buffer data as answer - * @return ERR_OK on success, an err_t otherwise - */ -static err_t -mdns_add_answer(struct mdns_outpacket *reply, struct mdns_domain *domain, u16_t type, u16_t klass, u16_t cache_flush, - u32_t ttl, const u8_t *buf, size_t buf_length, struct mdns_domain *answer_domain) -{ - u16_t answer_len; - u16_t field16; - u16_t rdlen_offset; - u16_t answer_offset; - u32_t field32; - err_t res; - - if (!reply->pbuf) { - /* If no pbuf is active, allocate one */ - reply->pbuf = pbuf_alloc(PBUF_TRANSPORT, OUTPACKET_SIZE, PBUF_RAM); - if (!reply->pbuf) { - return ERR_MEM; - } - reply->write_offset = SIZEOF_DNS_HDR; - } - - /* Worst case calculation. Domain strings might be compressed */ - answer_len = domain->length + sizeof(type) + sizeof(klass) + sizeof(ttl) + sizeof(field16)/*rd_length*/; - if (buf) { - answer_len += (u16_t)buf_length; - } - if (answer_domain) { - answer_len += answer_domain->length; - } - if (reply->write_offset + answer_len > reply->pbuf->tot_len) { - /* No space */ - return ERR_MEM; - } - - /* Answer starts with same data as question, then more fields */ - mdns_add_question(reply, domain, type, klass, cache_flush); - - /* Write TTL */ - field32 = lwip_htonl(ttl); - res = pbuf_take_at(reply->pbuf, &field32, sizeof(field32), reply->write_offset); - if (res != ERR_OK) { - return res; - } - reply->write_offset += sizeof(field32); - - /* Store offsets and skip forward to the data */ - rdlen_offset = reply->write_offset; - reply->write_offset += sizeof(field16); - answer_offset = reply->write_offset; - - if (buf) { - /* Write static data */ - res = pbuf_take_at(reply->pbuf, buf, (u16_t)buf_length, reply->write_offset); - if (res != ERR_OK) { - return res; - } - reply->write_offset += (u16_t)buf_length; - } - - if (answer_domain) { - /* Write name answer (compressed if possible) */ - res = mdns_write_domain(reply, answer_domain); - if (res != ERR_OK) { - return res; - } - } - - /* Write rd_length after when we know the answer size */ - field16 = lwip_htons(reply->write_offset - answer_offset); - res = pbuf_take_at(reply->pbuf, &field16, sizeof(field16), rdlen_offset); - - return res; -} - -/** - * Helper function for mdns_read_question/mdns_read_answer - * Reads a domain, type and class from the packet - * @param pkt The MDNS packet to read from. The parse_offset field will be - * incremented to point to the next unparsed byte. - * @param info The struct to fill with domain, type and class - * @return ERR_OK on success, an err_t otherwise - */ -static err_t -mdns_read_rr_info(struct mdns_packet *pkt, struct mdns_rr_info *info) -{ - u16_t field16, copied; - pkt->parse_offset = mdns_readname(pkt->pbuf, pkt->parse_offset, &info->domain); - if (pkt->parse_offset == MDNS_READNAME_ERROR) { - return ERR_VAL; - } - - copied = pbuf_copy_partial(pkt->pbuf, &field16, sizeof(field16), pkt->parse_offset); - if (copied != sizeof(field16)) { - return ERR_VAL; - } - pkt->parse_offset += copied; - info->type = lwip_ntohs(field16); - - copied = pbuf_copy_partial(pkt->pbuf, &field16, sizeof(field16), pkt->parse_offset); - if (copied != sizeof(field16)) { - return ERR_VAL; - } - pkt->parse_offset += copied; - info->klass = lwip_ntohs(field16); - - return ERR_OK; -} - -/** - * Read a question from the packet. - * All questions have to be read before the answers. - * @param pkt The MDNS packet to read from. The questions_left field will be decremented - * and the parse_offset will be updated. - * @param question The struct to fill with question data - * @return ERR_OK on success, an err_t otherwise - */ -static err_t -mdns_read_question(struct mdns_packet *pkt, struct mdns_question *question) -{ - /* Safety check */ - if (pkt->pbuf->tot_len < pkt->parse_offset) { - return ERR_VAL; - } - - if (pkt->questions_left) { - err_t res; - pkt->questions_left--; - - memset(question, 0, sizeof(struct mdns_question)); - res = mdns_read_rr_info(pkt, &question->info); - if (res != ERR_OK) { - return res; - } - - /* Extract unicast flag from class field */ - question->unicast = question->info.klass & 0x8000; - question->info.klass &= 0x7FFF; - - return ERR_OK; - } - return ERR_VAL; -} - -/** - * Read an answer from the packet - * The variable length reply is not copied, its pbuf offset and length is stored instead. - * @param pkt The MDNS packet to read. The answers_left field will be decremented and - * the parse_offset will be updated. - * @param answer The struct to fill with answer data - * @return ERR_OK on success, an err_t otherwise - */ -static err_t -mdns_read_answer(struct mdns_packet *pkt, struct mdns_answer *answer) -{ - /* Read questions first */ - if (pkt->questions_left) { - return ERR_VAL; - } - - /* Safety check */ - if (pkt->pbuf->tot_len < pkt->parse_offset) { - return ERR_VAL; - } - - if (pkt->answers_left) { - u16_t copied, field16; - u32_t ttl; - err_t res; - pkt->answers_left--; - - memset(answer, 0, sizeof(struct mdns_answer)); - res = mdns_read_rr_info(pkt, &answer->info); - if (res != ERR_OK) { - return res; - } - - /* Extract cache_flush flag from class field */ - answer->cache_flush = answer->info.klass & 0x8000; - answer->info.klass &= 0x7FFF; - - copied = pbuf_copy_partial(pkt->pbuf, &ttl, sizeof(ttl), pkt->parse_offset); - if (copied != sizeof(ttl)) { - return ERR_VAL; - } - pkt->parse_offset += copied; - answer->ttl = lwip_ntohl(ttl); - - copied = pbuf_copy_partial(pkt->pbuf, &field16, sizeof(field16), pkt->parse_offset); - if (copied != sizeof(field16)) { - return ERR_VAL; - } - pkt->parse_offset += copied; - answer->rd_length = lwip_ntohs(field16); - - answer->rd_offset = pkt->parse_offset; - pkt->parse_offset += answer->rd_length; - - return ERR_OK; - } - return ERR_VAL; -} - -#if LWIP_IPV4 -/** Write an IPv4 address (A) RR to outpacket */ -static err_t -mdns_add_a_answer(struct mdns_outpacket *reply, u16_t cache_flush, struct netif *netif) -{ - struct mdns_domain host; - mdns_build_host_domain(&host, NETIF_TO_HOST(netif)); - LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Responding with A record\n")); - return mdns_add_answer(reply, &host, DNS_RRTYPE_A, DNS_RRCLASS_IN, cache_flush, (NETIF_TO_HOST(netif))->dns_ttl, (const u8_t *) netif_ip4_addr(netif), sizeof(ip4_addr_t), NULL); -} - -/** Write a 4.3.2.1.in-addr.arpa -> hostname.local PTR RR to outpacket */ -static err_t -mdns_add_hostv4_ptr_answer(struct mdns_outpacket *reply, u16_t cache_flush, struct netif *netif) -{ - struct mdns_domain host, revhost; - mdns_build_host_domain(&host, NETIF_TO_HOST(netif)); - mdns_build_reverse_v4_domain(&revhost, netif_ip4_addr(netif)); - LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Responding with v4 PTR record\n")); - return mdns_add_answer(reply, &revhost, DNS_RRTYPE_PTR, DNS_RRCLASS_IN, cache_flush, (NETIF_TO_HOST(netif))->dns_ttl, NULL, 0, &host); -} -#endif - -#if LWIP_IPV6 -/** Write an IPv6 address (AAAA) RR to outpacket */ -static err_t -mdns_add_aaaa_answer(struct mdns_outpacket *reply, u16_t cache_flush, struct netif *netif, int addrindex) -{ - struct mdns_domain host; - mdns_build_host_domain(&host, NETIF_TO_HOST(netif)); - LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Responding with AAAA record\n")); - return mdns_add_answer(reply, &host, DNS_RRTYPE_AAAA, DNS_RRCLASS_IN, cache_flush, (NETIF_TO_HOST(netif))->dns_ttl, (const u8_t *) netif_ip6_addr(netif, addrindex), sizeof(ip6_addr_t), NULL); -} - -/** Write a x.y.z.ip6.arpa -> hostname.local PTR RR to outpacket */ -static err_t -mdns_add_hostv6_ptr_answer(struct mdns_outpacket *reply, u16_t cache_flush, struct netif *netif, int addrindex) -{ - struct mdns_domain host, revhost; - mdns_build_host_domain(&host, NETIF_TO_HOST(netif)); - mdns_build_reverse_v6_domain(&revhost, netif_ip6_addr(netif, addrindex)); - LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Responding with v6 PTR record\n")); - return mdns_add_answer(reply, &revhost, DNS_RRTYPE_PTR, DNS_RRCLASS_IN, cache_flush, (NETIF_TO_HOST(netif))->dns_ttl, NULL, 0, &host); -} -#endif - -/** Write an all-services -> servicetype PTR RR to outpacket */ -static err_t -mdns_add_servicetype_ptr_answer(struct mdns_outpacket *reply, struct mdns_service *service) -{ - struct mdns_domain service_type, service_dnssd; - mdns_build_service_domain(&service_type, service, 0); - mdns_build_dnssd_domain(&service_dnssd); - LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Responding with service type PTR record\n")); - return mdns_add_answer(reply, &service_dnssd, DNS_RRTYPE_PTR, DNS_RRCLASS_IN, 0, service->dns_ttl, NULL, 0, &service_type); -} - -/** Write a servicetype -> servicename PTR RR to outpacket */ -static err_t -mdns_add_servicename_ptr_answer(struct mdns_outpacket *reply, struct mdns_service *service) -{ - struct mdns_domain service_type, service_instance; - mdns_build_service_domain(&service_type, service, 0); - mdns_build_service_domain(&service_instance, service, 1); - LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Responding with service name PTR record\n")); - return mdns_add_answer(reply, &service_type, DNS_RRTYPE_PTR, DNS_RRCLASS_IN, 0, service->dns_ttl, NULL, 0, &service_instance); -} - -/** Write a SRV RR to outpacket */ -static err_t -mdns_add_srv_answer(struct mdns_outpacket *reply, u16_t cache_flush, struct mdns_host *mdns, struct mdns_service *service) -{ - struct mdns_domain service_instance, srvhost; - u16_t srvdata[3]; - mdns_build_service_domain(&service_instance, service, 1); - mdns_build_host_domain(&srvhost, mdns); - if (reply->legacy_query) { - /* RFC 6762 section 18.14: - * In legacy unicast responses generated to answer legacy queries, - * name compression MUST NOT be performed on SRV records. - */ - srvhost.skip_compression = 1; - } - srvdata[0] = lwip_htons(SRV_PRIORITY); - srvdata[1] = lwip_htons(SRV_WEIGHT); - srvdata[2] = lwip_htons(service->port); - LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Responding with SRV record\n")); - return mdns_add_answer(reply, &service_instance, DNS_RRTYPE_SRV, DNS_RRCLASS_IN, cache_flush, service->dns_ttl, - (const u8_t *) &srvdata, sizeof(srvdata), &srvhost); -} - -/** Write a TXT RR to outpacket */ -static err_t -mdns_add_txt_answer(struct mdns_outpacket *reply, u16_t cache_flush, struct mdns_service *service) -{ - struct mdns_domain service_instance; - mdns_build_service_domain(&service_instance, service, 1); - mdns_prepare_txtdata(service); - LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Responding with TXT record\n")); - return mdns_add_answer(reply, &service_instance, DNS_RRTYPE_TXT, DNS_RRCLASS_IN, cache_flush, service->dns_ttl, - (u8_t *) &service->txtdata.name, service->txtdata.length, NULL); -} - -/** - * Setup outpacket as a reply to the incoming packet - */ -static void -mdns_init_outpacket(struct mdns_outpacket *out, struct mdns_packet *in) -{ - memset(out, 0, sizeof(struct mdns_outpacket)); - out->cache_flush = 1; - out->netif = in->netif; - - /* Copy source IP/port to use when responding unicast, or to choose - * which pcb to use for multicast (IPv4/IPv6) - */ - SMEMCPY(&out->dest_addr, &in->source_addr, sizeof(ip_addr_t)); - out->dest_port = in->source_port; - - if (in->source_port != MDNS_PORT) { - out->unicast_reply = 1; - out->cache_flush = 0; - if (in->questions == 1) { - out->legacy_query = 1; - out->tx_id = in->tx_id; - } - } - - if (in->recv_unicast) { - out->unicast_reply = 1; - } -} - -/** - * Send chosen answers as a reply - * - * Add all selected answers (first write will allocate pbuf) - * Add additional answers based on the selected answers - * Send the packet - */ -static void -mdns_send_outpacket(struct mdns_outpacket *outpkt) -{ - struct mdns_service *service; - err_t res; - int i; - struct mdns_host* mdns = NETIF_TO_HOST(outpkt->netif); - - /* Write answers to host questions */ -#if LWIP_IPV4 - if (outpkt->host_replies & REPLY_HOST_A) { - res = mdns_add_a_answer(outpkt, outpkt->cache_flush, outpkt->netif); - if (res != ERR_OK) { - goto cleanup; - } - outpkt->answers++; - } - if (outpkt->host_replies & REPLY_HOST_PTR_V4) { - res = mdns_add_hostv4_ptr_answer(outpkt, outpkt->cache_flush, outpkt->netif); - if (res != ERR_OK) { - goto cleanup; - } - outpkt->answers++; - } -#endif -#if LWIP_IPV6 - if (outpkt->host_replies & REPLY_HOST_AAAA) { - int addrindex; - for (addrindex = 0; addrindex < LWIP_IPV6_NUM_ADDRESSES; ++addrindex) { - if (ip6_addr_isvalid(netif_ip6_addr_state(outpkt->netif, addrindex))) { - res = mdns_add_aaaa_answer(outpkt, outpkt->cache_flush, outpkt->netif, addrindex); - if (res != ERR_OK) { - goto cleanup; - } - outpkt->answers++; - } - } - } - if (outpkt->host_replies & REPLY_HOST_PTR_V6) { - u8_t rev_addrs = outpkt->host_reverse_v6_replies; - int addrindex = 0; - while (rev_addrs) { - if (rev_addrs & 1) { - res = mdns_add_hostv6_ptr_answer(outpkt, outpkt->cache_flush, outpkt->netif, addrindex); - if (res != ERR_OK) { - goto cleanup; - } - outpkt->answers++; - } - addrindex++; - rev_addrs >>= 1; - } - } -#endif - - /* Write answers to service questions */ - for (i = 0; i < MDNS_MAX_SERVICES; ++i) { - service = mdns->services[i]; - if (!service) { - continue; - } - - if (outpkt->serv_replies[i] & REPLY_SERVICE_TYPE_PTR) { - res = mdns_add_servicetype_ptr_answer(outpkt, service); - if (res != ERR_OK) { - goto cleanup; - } - outpkt->answers++; - } - - if (outpkt->serv_replies[i] & REPLY_SERVICE_NAME_PTR) { - res = mdns_add_servicename_ptr_answer(outpkt, service); - if (res != ERR_OK) { - goto cleanup; - } - outpkt->answers++; - } - - if (outpkt->serv_replies[i] & REPLY_SERVICE_SRV) { - res = mdns_add_srv_answer(outpkt, outpkt->cache_flush, mdns, service); - if (res != ERR_OK) { - goto cleanup; - } - outpkt->answers++; - } - - if (outpkt->serv_replies[i] & REPLY_SERVICE_TXT) { - res = mdns_add_txt_answer(outpkt, outpkt->cache_flush, service); - if (res != ERR_OK) { - goto cleanup; - } - outpkt->answers++; - } - } - - /* All answers written, add additional RRs */ - for (i = 0; i < MDNS_MAX_SERVICES; ++i) { - service = mdns->services[i]; - if (!service) { - continue; - } - - if (outpkt->serv_replies[i] & REPLY_SERVICE_NAME_PTR) { - /* Our service instance requested, include SRV & TXT - * if they are already not requested. */ - if (!(outpkt->serv_replies[i] & REPLY_SERVICE_SRV)) { - res = mdns_add_srv_answer(outpkt, outpkt->cache_flush, mdns, service); - if (res != ERR_OK) { - goto cleanup; - } - outpkt->additional++; - } - - if (!(outpkt->serv_replies[i] & REPLY_SERVICE_TXT)) { - res = mdns_add_txt_answer(outpkt, outpkt->cache_flush, service); - if (res != ERR_OK) { - goto cleanup; - } - outpkt->additional++; - } - } - - /* If service instance, SRV, record or an IP address is requested, - * supply all addresses for the host - */ - if ((outpkt->serv_replies[i] & (REPLY_SERVICE_NAME_PTR | REPLY_SERVICE_SRV)) || - (outpkt->host_replies & (REPLY_HOST_A | REPLY_HOST_AAAA))) { -#if LWIP_IPV6 - if (!(outpkt->host_replies & REPLY_HOST_AAAA)) { - int addrindex; - for (addrindex = 0; addrindex < LWIP_IPV6_NUM_ADDRESSES; ++addrindex) { - if (ip6_addr_isvalid(netif_ip6_addr_state(outpkt->netif, addrindex))) { - res = mdns_add_aaaa_answer(outpkt, outpkt->cache_flush, outpkt->netif, addrindex); - if (res != ERR_OK) { - goto cleanup; - } - outpkt->additional++; - } - } - } -#endif -#if LWIP_IPV4 - if (!(outpkt->host_replies & REPLY_HOST_A)) { - res = mdns_add_a_answer(outpkt, outpkt->cache_flush, outpkt->netif); - if (res != ERR_OK) { - goto cleanup; - } - outpkt->additional++; - } -#endif - } - } - - if (outpkt->pbuf) { - const ip_addr_t *mcast_destaddr; - struct dns_hdr hdr; - - /* Write header */ - memset(&hdr, 0, sizeof(hdr)); - hdr.flags1 = DNS_FLAG1_RESPONSE | DNS_FLAG1_AUTHORATIVE; - hdr.numanswers = lwip_htons(outpkt->answers); - hdr.numextrarr = lwip_htons(outpkt->additional); - if (outpkt->legacy_query) { - hdr.numquestions = lwip_htons(1); - hdr.id = lwip_htons(outpkt->tx_id); - } - pbuf_take(outpkt->pbuf, &hdr, sizeof(hdr)); - - /* Shrink packet */ - pbuf_realloc(outpkt->pbuf, outpkt->write_offset); - - if (IP_IS_V6_VAL(outpkt->dest_addr)) { -#if LWIP_IPV6 - mcast_destaddr = &v6group; -#endif - } else { -#if LWIP_IPV4 - mcast_destaddr = &v4group; -#endif - } - /* Send created packet */ - LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Sending packet, len=%d, unicast=%d\n", outpkt->write_offset, outpkt->unicast_reply)); - if (outpkt->unicast_reply) { - udp_sendto_if(mdns_pcb, outpkt->pbuf, &outpkt->dest_addr, outpkt->dest_port, outpkt->netif); - } else { - udp_sendto_if(mdns_pcb, outpkt->pbuf, mcast_destaddr, MDNS_PORT, outpkt->netif); - } - } - -cleanup: - if (outpkt->pbuf) { - pbuf_free(outpkt->pbuf); - outpkt->pbuf = NULL; - } -} - -/** - * Send unsolicited answer containing all our known data - * @param netif The network interface to send on - * @param destination The target address to send to (usually multicast address) - */ -static void -mdns_announce(struct netif *netif, const ip_addr_t *destination) -{ - struct mdns_outpacket announce; - int i; - struct mdns_host* mdns = NETIF_TO_HOST(netif); - - memset(&announce, 0, sizeof(announce)); - announce.netif = netif; - announce.cache_flush = 1; -#if LWIP_IPV4 - if (!ip4_addr_isany_val(*netif_ip4_addr(netif))) - announce.host_replies = REPLY_HOST_A | REPLY_HOST_PTR_V4; -#endif -#if LWIP_IPV6 - for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; ++i) { - if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i))) { - announce.host_replies |= REPLY_HOST_AAAA | REPLY_HOST_PTR_V6; - announce.host_reverse_v6_replies |= (1 << i); - } - } -#endif - - for (i = 0; i < MDNS_MAX_SERVICES; i++) { - struct mdns_service *serv = mdns->services[i]; - if (serv) { - announce.serv_replies[i] = REPLY_SERVICE_TYPE_PTR | REPLY_SERVICE_NAME_PTR | - REPLY_SERVICE_SRV | REPLY_SERVICE_TXT; - } - } - - announce.dest_port = MDNS_PORT; - SMEMCPY(&announce.dest_addr, destination, sizeof(announce.dest_addr)); - mdns_send_outpacket(&announce); -} - -/** - * Handle question MDNS packet - * 1. Parse all questions and set bits what answers to send - * 2. Clear pending answers if known answers are supplied - * 3. Put chosen answers in new packet and send as reply - */ -static void -mdns_handle_question(struct mdns_packet *pkt) -{ - struct mdns_service *service; - struct mdns_outpacket reply; - int replies = 0; - int i; - err_t res; - struct mdns_host* mdns = NETIF_TO_HOST(pkt->netif); - - mdns_init_outpacket(&reply, pkt); - - while (pkt->questions_left) { - struct mdns_question q; - - res = mdns_read_question(pkt, &q); - if (res != ERR_OK) { - LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Failed to parse question, skipping query packet\n")); - return; - } - - LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Query for domain ")); - mdns_domain_debug_print(&q.info.domain); - LWIP_DEBUGF(MDNS_DEBUG, (" type %d class %d\n", q.info.type, q.info.klass)); - - if (q.unicast) { - /* Reply unicast if any question is unicast */ - reply.unicast_reply = 1; - } - - reply.host_replies |= check_host(pkt->netif, &q.info, &reply.host_reverse_v6_replies); - replies |= reply.host_replies; - - for (i = 0; i < MDNS_MAX_SERVICES; ++i) { - service = mdns->services[i]; - if (!service) { - continue; - } - reply.serv_replies[i] |= check_service(service, &q.info); - replies |= reply.serv_replies[i]; - } - - if (replies && reply.legacy_query) { - /* Add question to reply packet (legacy packet only has 1 question) */ - res = mdns_add_question(&reply, &q.info.domain, q.info.type, q.info.klass, 0); - if (res != ERR_OK) { - goto cleanup; - } - } - } - - /* Handle known answers */ - while (pkt->answers_left) { - struct mdns_answer ans; - u8_t rev_v6; - int match; - - res = mdns_read_answer(pkt, &ans); - if (res != ERR_OK) { - LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Failed to parse answer, skipping query packet\n")); - goto cleanup; - } - - LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Known answer for domain ")); - mdns_domain_debug_print(&ans.info.domain); - LWIP_DEBUGF(MDNS_DEBUG, (" type %d class %d\n", ans.info.type, ans.info.klass)); - - - if (ans.info.type == DNS_RRTYPE_ANY || ans.info.klass == DNS_RRCLASS_ANY) { - /* Skip known answers for ANY type & class */ - continue; - } - - rev_v6 = 0; - match = reply.host_replies & check_host(pkt->netif, &ans.info, &rev_v6); - if (match && (ans.ttl > (mdns->dns_ttl / 2))) { - /* The RR in the known answer matches an RR we are planning to send, - * and the TTL is less than half gone. - * If the payload matches we should not send that answer. - */ - if (ans.info.type == DNS_RRTYPE_PTR) { - /* Read domain and compare */ - struct mdns_domain known_ans, my_ans; - u16_t len; - len = mdns_readname(pkt->pbuf, ans.rd_offset, &known_ans); - res = mdns_build_host_domain(&my_ans, mdns); - if (len != MDNS_READNAME_ERROR && res == ERR_OK && mdns_domain_eq(&known_ans, &my_ans)) { -#if LWIP_IPV4 - if (match & REPLY_HOST_PTR_V4) { - LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Skipping known answer: v4 PTR\n")); - reply.host_replies &= ~REPLY_HOST_PTR_V4; - } -#endif -#if LWIP_IPV6 - if (match & REPLY_HOST_PTR_V6) { - LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Skipping known answer: v6 PTR\n")); - reply.host_reverse_v6_replies &= ~rev_v6; - if (reply.host_reverse_v6_replies == 0) { - reply.host_replies &= ~REPLY_HOST_PTR_V6; - } - } -#endif - } - } else if (match & REPLY_HOST_A) { -#if LWIP_IPV4 - if (ans.rd_length == sizeof(ip4_addr_t) && - pbuf_memcmp(pkt->pbuf, ans.rd_offset, netif_ip4_addr(pkt->netif), ans.rd_length) == 0) { - LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Skipping known answer: A\n")); - reply.host_replies &= ~REPLY_HOST_A; - } -#endif - } else if (match & REPLY_HOST_AAAA) { -#if LWIP_IPV6 - if (ans.rd_length == sizeof(ip6_addr_t) && - /* TODO this clears all AAAA responses if first addr is set as known */ - pbuf_memcmp(pkt->pbuf, ans.rd_offset, netif_ip6_addr(pkt->netif, 0), ans.rd_length) == 0) { - LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Skipping known answer: AAAA\n")); - reply.host_replies &= ~REPLY_HOST_AAAA; - } -#endif - } - } - - for (i = 0; i < MDNS_MAX_SERVICES; ++i) { - service = mdns->services[i]; - if (!service) { - continue; - } - match = reply.serv_replies[i] & check_service(service, &ans.info); - if (match && (ans.ttl > (service->dns_ttl / 2))) { - /* The RR in the known answer matches an RR we are planning to send, - * and the TTL is less than half gone. - * If the payload matches we should not send that answer. - */ - if (ans.info.type == DNS_RRTYPE_PTR) { - /* Read domain and compare */ - struct mdns_domain known_ans, my_ans; - u16_t len; - len = mdns_readname(pkt->pbuf, ans.rd_offset, &known_ans); - if (len != MDNS_READNAME_ERROR) { - if (match & REPLY_SERVICE_TYPE_PTR) { - res = mdns_build_service_domain(&my_ans, service, 0); - if (res == ERR_OK && mdns_domain_eq(&known_ans, &my_ans)) { - LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Skipping known answer: service type PTR\n")); - reply.serv_replies[i] &= ~REPLY_SERVICE_TYPE_PTR; - } - } - if (match & REPLY_SERVICE_NAME_PTR) { - res = mdns_build_service_domain(&my_ans, service, 1); - if (res == ERR_OK && mdns_domain_eq(&known_ans, &my_ans)) { - LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Skipping known answer: service name PTR\n")); - reply.serv_replies[i] &= ~REPLY_SERVICE_NAME_PTR; - } - } - } - } else if (match & REPLY_SERVICE_SRV) { - /* Read and compare to my SRV record */ - u16_t field16, len, read_pos; - struct mdns_domain known_ans, my_ans; - read_pos = ans.rd_offset; - do { - /* Check priority field */ - len = pbuf_copy_partial(pkt->pbuf, &field16, sizeof(field16), read_pos); - if (len != sizeof(field16) || lwip_ntohs(field16) != SRV_PRIORITY) { - break; - } - read_pos += len; - /* Check weight field */ - len = pbuf_copy_partial(pkt->pbuf, &field16, sizeof(field16), read_pos); - if (len != sizeof(field16) || lwip_ntohs(field16) != SRV_WEIGHT) { - break; - } - read_pos += len; - /* Check port field */ - len = pbuf_copy_partial(pkt->pbuf, &field16, sizeof(field16), read_pos); - if (len != sizeof(field16) || lwip_ntohs(field16) != service->port) { - break; - } - read_pos += len; - /* Check host field */ - len = mdns_readname(pkt->pbuf, read_pos, &known_ans); - mdns_build_host_domain(&my_ans, mdns); - if (len == MDNS_READNAME_ERROR || !mdns_domain_eq(&known_ans, &my_ans)) { - break; - } - LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Skipping known answer: SRV\n")); - reply.serv_replies[i] &= ~REPLY_SERVICE_SRV; - } while (0); - } else if (match & REPLY_SERVICE_TXT) { - mdns_prepare_txtdata(service); - if (service->txtdata.length == ans.rd_length && - pbuf_memcmp(pkt->pbuf, ans.rd_offset, service->txtdata.name, ans.rd_length) == 0) { - LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Skipping known answer: TXT\n")); - reply.serv_replies[i] &= ~REPLY_SERVICE_TXT; - } - } - } - } - } - - mdns_send_outpacket(&reply); - -cleanup: - if (reply.pbuf) { - /* This should only happen if we fail to alloc/write question for legacy query */ - pbuf_free(reply.pbuf); - reply.pbuf = NULL; - } -} - -/** - * Handle response MDNS packet - * Only prints debug for now. Will need more code to do conflict resolution. - */ -static void -mdns_handle_response(struct mdns_packet *pkt) -{ - /* Ignore all questions */ - while (pkt->questions_left) { - struct mdns_question q; - err_t res; - - res = mdns_read_question(pkt, &q); - if (res != ERR_OK) { - LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Failed to parse question, skipping response packet\n")); - return; - } - } - - while (pkt->answers_left) { - struct mdns_answer ans; - err_t res; - - res = mdns_read_answer(pkt, &ans); - if (res != ERR_OK) { - LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Failed to parse answer, skipping response packet\n")); - return; - } - - LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Answer for domain ")); - mdns_domain_debug_print(&ans.info.domain); - LWIP_DEBUGF(MDNS_DEBUG, (" type %d class %d\n", ans.info.type, ans.info.klass)); - } -} - -/** - * Receive input function for MDNS packets. - * Handles both IPv4 and IPv6 UDP pcbs. - */ -static void -mdns_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port) -{ - struct dns_hdr hdr; - struct mdns_packet packet; - struct netif *recv_netif = ip_current_input_netif(); - u16_t offset = 0; - - LWIP_UNUSED_ARG(arg); - LWIP_UNUSED_ARG(pcb); - - LWIP_DEBUGF(MDNS_DEBUG, ("MDNS: Received IPv%d MDNS packet, len %d\n", IP_IS_V6(addr)? 6 : 4, p->tot_len)); - - if (NETIF_TO_HOST(recv_netif) == NULL) { - /* From netif not configured for MDNS */ - goto dealloc; - } - - if (pbuf_copy_partial(p, &hdr, SIZEOF_DNS_HDR, offset) < SIZEOF_DNS_HDR) { - /* Too small */ - goto dealloc; - } - offset += SIZEOF_DNS_HDR; - - if (DNS_HDR_GET_OPCODE(&hdr)) { - /* Ignore non-standard queries in multicast packets (RFC 6762, section 18.3) */ - goto dealloc; - } - - memset(&packet, 0, sizeof(packet)); - SMEMCPY(&packet.source_addr, addr, sizeof(packet.source_addr)); - packet.source_port = port; - packet.netif = recv_netif; - packet.pbuf = p; - packet.parse_offset = offset; - packet.tx_id = lwip_ntohs(hdr.id); - packet.questions = packet.questions_left = lwip_ntohs(hdr.numquestions); - packet.answers = packet.answers_left = lwip_ntohs(hdr.numanswers) + lwip_ntohs(hdr.numauthrr) + lwip_ntohs(hdr.numextrarr); - -#if LWIP_IPV6 - if (IP_IS_V6(ip_current_dest_addr())) { - if (!ip_addr_cmp(ip_current_dest_addr(), &v6group)) { - packet.recv_unicast = 1; - } - } -#endif -#if LWIP_IPV4 - if (!IP_IS_V6(ip_current_dest_addr())) { - if (!ip_addr_cmp(ip_current_dest_addr(), &v4group)) { - packet.recv_unicast = 1; - } - } -#endif - - if (hdr.flags1 & DNS_FLAG1_RESPONSE) { - mdns_handle_response(&packet); - } else { - mdns_handle_question(&packet); - } - -dealloc: - pbuf_free(p); -} - -/** - * @ingroup mdns - * Initiate MDNS responder. Will open UDP sockets on port 5353 - */ -void -mdns_resp_init(void) -{ - err_t res; - - mdns_pcb = udp_new_ip_type(IPADDR_TYPE_ANY); - LWIP_ASSERT("Failed to allocate pcb", mdns_pcb != NULL); -#if LWIP_MULTICAST_TX_OPTIONS - udp_set_multicast_ttl(mdns_pcb, MDNS_TTL); -#else - mdns_pcb->ttl = MDNS_TTL; -#endif - res = udp_bind(mdns_pcb, IP_ANY_TYPE, MDNS_PORT); - LWIP_UNUSED_ARG(res); /* in case of LWIP_NOASSERT */ - LWIP_ASSERT("Failed to bind pcb", res == ERR_OK); - udp_recv(mdns_pcb, mdns_recv, NULL); - - mdns_netif_client_id = netif_alloc_client_data_id(); -} - -/** - * @ingroup mdns - * Announce IP settings have changed on netif. - * Call this in your callback registered by netif_set_status_callback(). - * This function may go away in the future when netif supports registering - * multiple callback functions. - * @param netif The network interface where settings have changed. - */ -void -mdns_resp_netif_settings_changed(struct netif *netif) -{ - LWIP_ERROR("mdns_resp_netif_ip_changed: netif != NULL", (netif != NULL), return); - - if (NETIF_TO_HOST(netif) == NULL) { - return; - } - - /* Announce on IPv6 and IPv4 */ -#if LWIP_IPV6 - mdns_announce(netif, IP6_ADDR_ANY); -#endif -#if LWIP_IPV4 - mdns_announce(netif, IP4_ADDR_ANY); -#endif -} - -/** - * @ingroup mdns - * Activate MDNS responder for a network interface and send announce packets. - * @param netif The network interface to activate. - * @param hostname Name to use. Queries for <hostname>.local will be answered - * with the IP addresses of the netif. The hostname will be copied, the - * given pointer can be on the stack. - * @param dns_ttl Validity time in seconds to send out for IP address data in DNS replies - * @return ERR_OK if netif was added, an err_t otherwise - */ -err_t -mdns_resp_add_netif(struct netif *netif, const char *hostname, u32_t dns_ttl) -{ - err_t res; - struct mdns_host* mdns; - - LWIP_ERROR("mdns_resp_add_netif: netif != NULL", (netif != NULL), return ERR_VAL); - LWIP_ERROR("mdns_resp_add_netif: Hostname too long", (strlen(hostname) <= MDNS_LABEL_MAXLEN), return ERR_VAL); - - LWIP_ASSERT("mdns_resp_add_netif: Double add", NETIF_TO_HOST(netif) == NULL); - mdns = (struct mdns_host *) mem_malloc(sizeof(struct mdns_host)); - LWIP_ERROR("mdns_resp_add_netif: Alloc failed", (mdns != NULL), return ERR_MEM); - - netif_set_client_data(netif, mdns_netif_client_id, mdns); - - memset(mdns, 0, sizeof(struct mdns_host)); - MEMCPY(&mdns->name, hostname, LWIP_MIN(MDNS_LABEL_MAXLEN, strlen(hostname))); - mdns->dns_ttl = dns_ttl; - - /* Join multicast groups */ -#if LWIP_IPV4 - res = igmp_joingroup_netif(netif, ip_2_ip4(&v4group)); - if (res != ERR_OK) { - goto cleanup; - } -#endif -#if LWIP_IPV6 - res = mld6_joingroup_netif(netif, ip_2_ip6(&v6group)); - if (res != ERR_OK) { - goto cleanup; - } -#endif - - mdns_resp_netif_settings_changed(netif); - return ERR_OK; - -cleanup: - mem_free(mdns); - netif_set_client_data(netif, mdns_netif_client_id, NULL); - return res; -} - -/** - * @ingroup mdns - * Stop responding to MDNS queries on this interface, leave multicast groups, - * and free the helper structure and any of its services. - * @param netif The network interface to remove. - * @return ERR_OK if netif was removed, an err_t otherwise - */ -err_t -mdns_resp_remove_netif(struct netif *netif) -{ - int i; - struct mdns_host* mdns; - - LWIP_ASSERT("mdns_resp_remove_netif: Null pointer", netif); - mdns = NETIF_TO_HOST(netif); - LWIP_ERROR("mdns_resp_remove_netif: Not an active netif", (mdns != NULL), return ERR_VAL); - - for (i = 0; i < MDNS_MAX_SERVICES; i++) { - struct mdns_service *service = mdns->services[i]; - if (service) { - mem_free(service); - } - } - - /* Leave multicast groups */ -#if LWIP_IPV4 - igmp_leavegroup_netif(netif, ip_2_ip4(&v4group)); -#endif -#if LWIP_IPV6 - mld6_leavegroup_netif(netif, ip_2_ip6(&v6group)); -#endif - - mem_free(mdns); - netif_set_client_data(netif, mdns_netif_client_id, NULL); - return ERR_OK; -} - -/** - * @ingroup mdns - * Add a service to the selected network interface. - * @param netif The network interface to publish this service on - * @param name The name of the service - * @param service The service type, like "_http" - * @param proto The service protocol, DNSSD_PROTO_TCP for TCP ("_tcp") and DNSSD_PROTO_UDP - * for others ("_udp") - * @param port The port the service listens to - * @param dns_ttl Validity time in seconds to send out for service data in DNS replies - * @param txt_fn Callback to get TXT data. Will be called each time a TXT reply is created to - * allow dynamic replies. - * @param txt_data Userdata pointer for txt_fn - * @return ERR_OK if the service was added to the netif, an err_t otherwise - */ -err_t -mdns_resp_add_service(struct netif *netif, const char *name, const char *service, enum mdns_sd_proto proto, u16_t port, u32_t dns_ttl, service_get_txt_fn_t txt_fn, void *txt_data) -{ - int i; - int slot = -1; - struct mdns_service *srv; - struct mdns_host* mdns; - - LWIP_ASSERT("mdns_resp_add_service: netif != NULL", netif); - mdns = NETIF_TO_HOST(netif); - LWIP_ERROR("mdns_resp_add_service: Not an mdns netif", (mdns != NULL), return ERR_VAL); - - LWIP_ERROR("mdns_resp_add_service: Name too long", (strlen(name) <= MDNS_LABEL_MAXLEN), return ERR_VAL); - LWIP_ERROR("mdns_resp_add_service: Service too long", (strlen(service) <= MDNS_LABEL_MAXLEN), return ERR_VAL); - LWIP_ERROR("mdns_resp_add_service: Bad proto (need TCP or UDP)", (proto == DNSSD_PROTO_TCP || proto == DNSSD_PROTO_UDP), return ERR_VAL); - - for (i = 0; i < MDNS_MAX_SERVICES; i++) { - if (mdns->services[i] == NULL) { - slot = i; - break; - } - } - LWIP_ERROR("mdns_resp_add_service: Service list full (increase MDNS_MAX_SERVICES)", (slot >= 0), return ERR_MEM); - - srv = (struct mdns_service*)mem_malloc(sizeof(struct mdns_service)); - LWIP_ERROR("mdns_resp_add_service: Alloc failed", (srv != NULL), return ERR_MEM); - - memset(srv, 0, sizeof(struct mdns_service)); - - MEMCPY(&srv->name, name, LWIP_MIN(MDNS_LABEL_MAXLEN, strlen(name))); - MEMCPY(&srv->service, service, LWIP_MIN(MDNS_LABEL_MAXLEN, strlen(service))); - srv->txt_fn = txt_fn; - srv->txt_userdata = txt_data; - srv->proto = (u16_t)proto; - srv->port = port; - srv->dns_ttl = dns_ttl; - - mdns->services[slot] = srv; - - /* Announce on IPv6 and IPv4 */ -#if LWIP_IPV6 - mdns_announce(netif, IP6_ADDR_ANY); -#endif -#if LWIP_IPV4 - mdns_announce(netif, IP4_ADDR_ANY); -#endif - - return ERR_OK; -} - -/** - * @ingroup mdns - * Call this function from inside the service_get_txt_fn_t callback to add text data. - * Buffer for TXT data is 256 bytes, and each field is prefixed with a length byte. - * @param service The service provided to the get_txt callback - * @param txt String to add to the TXT field. - * @param txt_len Length of string - * @return ERR_OK if the string was added to the reply, an err_t otherwise - */ -err_t -mdns_resp_add_service_txtitem(struct mdns_service *service, const char *txt, u8_t txt_len) -{ - LWIP_ASSERT("mdns_resp_add_service_txtitem: service != NULL", service); - - /* Use a mdns_domain struct to store txt chunks since it is the same encoding */ - return mdns_domain_add_label(&service->txtdata, txt, txt_len); -} - -#endif /* LWIP_MDNS_RESPONDER */ diff --git a/third_party/lwip/repo/lwip/src/apps/mqtt/mqtt.c b/third_party/lwip/repo/lwip/src/apps/mqtt/mqtt.c deleted file mode 100644 index 899e2cbff997fd..00000000000000 --- a/third_party/lwip/repo/lwip/src/apps/mqtt/mqtt.c +++ /dev/null @@ -1,1342 +0,0 @@ -/** - * @file - * MQTT client - * - * @defgroup mqtt MQTT client - * @ingroup apps - * @verbinclude mqtt_client.txt - */ - -/* - * Copyright (c) 2016 Erik Andersson - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack - * - * Author: Erik Andersson - * - * - * @todo: - * - Handle large outgoing payloads for PUBLISH messages - * - Fix restriction of a single topic in each (UN)SUBSCRIBE message (protocol has support for multiple topics) - * - Add support for legacy MQTT protocol version - * - * Please coordinate changes and requests with Erik Andersson - * Erik Andersson - * - */ -#include "lwip/apps/mqtt.h" -#include "lwip/timeouts.h" -#include "lwip/ip_addr.h" -#include "lwip/mem.h" -#include "lwip/err.h" -#include "lwip/pbuf.h" -#include "lwip/tcp.h" -#include - -#if LWIP_TCP && LWIP_CALLBACK_API - -/** - * MQTT_DEBUG: Default is off. - */ -#if !defined MQTT_DEBUG || defined __DOXYGEN__ -#define MQTT_DEBUG LWIP_DBG_OFF -#endif - -#define MQTT_DEBUG_TRACE (MQTT_DEBUG | LWIP_DBG_TRACE) -#define MQTT_DEBUG_STATE (MQTT_DEBUG | LWIP_DBG_STATE) -#define MQTT_DEBUG_WARN (MQTT_DEBUG | LWIP_DBG_LEVEL_WARNING) -#define MQTT_DEBUG_WARN_STATE (MQTT_DEBUG | LWIP_DBG_LEVEL_WARNING | LWIP_DBG_STATE) -#define MQTT_DEBUG_SERIOUS (MQTT_DEBUG | LWIP_DBG_LEVEL_SERIOUS) - -static void mqtt_cyclic_timer(void *arg); - -/** - * MQTT client connection states - */ -enum { - TCP_DISCONNECTED, - TCP_CONNECTING, - MQTT_CONNECTING, - MQTT_CONNECTED -}; - -/** - * MQTT control message types - */ -enum mqtt_message_type { - MQTT_MSG_TYPE_CONNECT = 1, - MQTT_MSG_TYPE_CONNACK = 2, - MQTT_MSG_TYPE_PUBLISH = 3, - MQTT_MSG_TYPE_PUBACK = 4, - MQTT_MSG_TYPE_PUBREC = 5, - MQTT_MSG_TYPE_PUBREL = 6, - MQTT_MSG_TYPE_PUBCOMP = 7, - MQTT_MSG_TYPE_SUBSCRIBE = 8, - MQTT_MSG_TYPE_SUBACK = 9, - MQTT_MSG_TYPE_UNSUBSCRIBE = 10, - MQTT_MSG_TYPE_UNSUBACK = 11, - MQTT_MSG_TYPE_PINGREQ = 12, - MQTT_MSG_TYPE_PINGRESP = 13, - MQTT_MSG_TYPE_DISCONNECT = 14 -}; - -/** Helpers to extract control packet type and qos from first byte in fixed header */ -#define MQTT_CTL_PACKET_TYPE(fixed_hdr_byte0) ((fixed_hdr_byte0 & 0xf0) >> 4) -#define MQTT_CTL_PACKET_QOS(fixed_hdr_byte0) ((fixed_hdr_byte0 & 0x6) >> 1) - -/** - * MQTT connect flags, only used in CONNECT message - */ -enum mqtt_connect_flag { - MQTT_CONNECT_FLAG_USERNAME = 1 << 7, - MQTT_CONNECT_FLAG_PASSWORD = 1 << 6, - MQTT_CONNECT_FLAG_WILL_RETAIN = 1 << 5, - MQTT_CONNECT_FLAG_WILL = 1 << 2, - MQTT_CONNECT_FLAG_CLEAN_SESSION = 1 << 1 -}; - - -#if defined(LWIP_DEBUG) -static const char * const mqtt_message_type_str[15] = -{ - "UNDEFINED", - "CONNECT", - "CONNACK", - "PUBLISH", - "PUBACK", - "PUBREC", - "PUBREL", - "PUBCOMP", - "SUBSCRIBE", - "SUBACK", - "UNSUBSCRIBE", - "UNSUBACK", - "PINGREQ", - "PINGRESP", - "DISCONNECT" -}; - -/** - * Message type value to string - * @param msg_type see enum mqtt_message_type - * - * @return Control message type text string - */ -static const char * -mqtt_msg_type_to_str(u8_t msg_type) -{ - if (msg_type >= LWIP_ARRAYSIZE(mqtt_message_type_str)) { - msg_type = 0; - } - return mqtt_message_type_str[msg_type]; -} - -#endif - - -/** - * Generate MQTT packet identifier - * @param client MQTT client - * @return New packet identifier, range 1 to 65535 - */ -static u16_t -msg_generate_packet_id(mqtt_client_t *client) -{ - client->pkt_id_seq++; - if (client->pkt_id_seq == 0) { - client->pkt_id_seq++; - } - return client->pkt_id_seq; -} - -/*--------------------------------------------------------------------------------------------------------------------- */ -/* Output ring buffer */ - - -#define MQTT_RINGBUF_IDX_MASK ((MQTT_OUTPUT_RINGBUF_SIZE) - 1) - -/** Add single item to ring buffer */ -#define mqtt_ringbuf_put(rb, item) ((rb)->buf)[(rb)->put++ & MQTT_RINGBUF_IDX_MASK] = (item) - -/** Return number of bytes in ring buffer */ -#define mqtt_ringbuf_len(rb) ((u16_t)((rb)->put - (rb)->get)) - -/** Return number of bytes free in ring buffer */ -#define mqtt_ringbuf_free(rb) (MQTT_OUTPUT_RINGBUF_SIZE - mqtt_ringbuf_len(rb)) - -/** Return number of bytes possible to read without wrapping around */ -#define mqtt_ringbuf_linear_read_length(rb) LWIP_MIN(mqtt_ringbuf_len(rb), (MQTT_OUTPUT_RINGBUF_SIZE - ((rb)->get & MQTT_RINGBUF_IDX_MASK))) - -/** Return pointer to ring buffer get position */ -#define mqtt_ringbuf_get_ptr(rb) (&(rb)->buf[(rb)->get & MQTT_RINGBUF_IDX_MASK]) - -#define mqtt_ringbuf_advance_get_idx(rb, len) ((rb)->get += (len)) - - -/** - * Try send as many bytes as possible from output ring buffer - * @param rb Output ring buffer - * @param tpcb TCP connection handle - */ -static void -mqtt_output_send(struct mqtt_ringbuf_t *rb, struct tcp_pcb *tpcb) -{ - err_t err; - u8_t wrap = 0; - u16_t ringbuf_lin_len = mqtt_ringbuf_linear_read_length(rb); - u16_t send_len = tcp_sndbuf(tpcb); - LWIP_ASSERT("mqtt_output_send: tpcb != NULL", tpcb != NULL); - - if (send_len == 0 || ringbuf_lin_len == 0) { - return; - } - - LWIP_DEBUGF(MQTT_DEBUG_TRACE,("mqtt_output_send: tcp_sndbuf: %d bytes, ringbuf_linear_available: %d, get %d, put %d\n", - send_len, ringbuf_lin_len, ((rb)->get & MQTT_RINGBUF_IDX_MASK), ((rb)->put & MQTT_RINGBUF_IDX_MASK))); - - if (send_len > ringbuf_lin_len) { - /* Space in TCP output buffer is larger than available in ring buffer linear portion */ - send_len = ringbuf_lin_len; - /* Wrap around if more data in ring buffer after linear portion */ - wrap = (mqtt_ringbuf_len(rb) > ringbuf_lin_len); - } - err = tcp_write(tpcb, mqtt_ringbuf_get_ptr(rb), send_len, TCP_WRITE_FLAG_COPY | (wrap ? TCP_WRITE_FLAG_MORE : 0)); - if ((err == ERR_OK) && wrap) { - mqtt_ringbuf_advance_get_idx(rb, send_len); - /* Use the lesser one of ring buffer linear length and TCP send buffer size */ - send_len = LWIP_MIN(tcp_sndbuf(tpcb), mqtt_ringbuf_linear_read_length(rb)); - err = tcp_write(tpcb, mqtt_ringbuf_get_ptr(rb), send_len, TCP_WRITE_FLAG_COPY); - } - - if (err == ERR_OK) { - mqtt_ringbuf_advance_get_idx(rb, send_len); - /* Flush */ - tcp_output(tpcb); - } else { - LWIP_DEBUGF(MQTT_DEBUG_WARN, ("mqtt_output_send: Send failed with err %d (\"%s\")\n", err, lwip_strerr(err))); - } -} - - - -/*--------------------------------------------------------------------------------------------------------------------- */ -/* Request queue */ - -/** - * Create request item - * @param r_objs Pointer to request objects - * @param pkt_id Packet identifier of request - * @param cb Packet callback to call when requests lifetime ends - * @param arg Parameter following callback - * @return Request or NULL if failed to create - */ -static struct mqtt_request_t * -mqtt_create_request(struct mqtt_request_t *r_objs, u16_t pkt_id, mqtt_request_cb_t cb, void *arg) -{ - struct mqtt_request_t *r = NULL; - u8_t n; - LWIP_ASSERT("mqtt_create_request: r_objs != NULL", r_objs != NULL); - for (n = 0; n < MQTT_REQ_MAX_IN_FLIGHT; n++) { - /* Item point to itself if not in use */ - if (r_objs[n].next == &r_objs[n]) { - r = &r_objs[n]; - r->next = NULL; - r->cb = cb; - r->arg = arg; - r->pkt_id = pkt_id; - break; - } - } - return r; -} - - -/** - * Append request to pending request queue - * @param tail Pointer to request queue tail pointer - * @param r Request to append - */ -static void -mqtt_append_request(struct mqtt_request_t **tail, struct mqtt_request_t *r) -{ - struct mqtt_request_t *head = NULL; - s16_t time_before = 0; - struct mqtt_request_t *iter; - - LWIP_ASSERT("mqtt_append_request: tail != NULL", tail != NULL); - - /* Iterate trough queue to find head, and count total timeout time */ - for (iter = *tail; iter != NULL; iter = iter->next) { - time_before += iter->timeout_diff; - head = iter; - } - - LWIP_ASSERT("mqtt_append_request: time_before <= MQTT_REQ_TIMEOUT", time_before <= MQTT_REQ_TIMEOUT); - r->timeout_diff = MQTT_REQ_TIMEOUT - time_before; - if (head == NULL) { - *tail = r; - } else { - head->next = r; - } -} - - -/** - * Delete request item - * @param r Request item to delete - */ -static void -mqtt_delete_request(struct mqtt_request_t *r) -{ - if (r != NULL) { - r->next = r; - } -} - -/** - * Remove a request item with a specific packet identifier from request queue - * @param tail Pointer to request queue tail pointer - * @param pkt_id Packet identifier of request to take - * @return Request item if found, NULL if not - */ -static struct mqtt_request_t * -mqtt_take_request(struct mqtt_request_t **tail, u16_t pkt_id) -{ - struct mqtt_request_t *iter = NULL, *prev = NULL; - LWIP_ASSERT("mqtt_take_request: tail != NULL", tail != NULL); - /* Search all request for pkt_id */ - for (iter = *tail; iter != NULL; iter = iter->next) { - if (iter->pkt_id == pkt_id) { - break; - } - prev = iter; - } - - /* If request was found */ - if (iter != NULL) { - /* unchain */ - if (prev == NULL) { - *tail= iter->next; - } else { - prev->next = iter->next; - } - /* If exists, add remaining timeout time for the request to next */ - if (iter->next != NULL) { - iter->next->timeout_diff += iter->timeout_diff; - } - iter->next = NULL; - } - return iter; -} - -/** - * Handle requests timeout - * @param tail Pointer to request queue tail pointer - * @param t Time since last call in seconds - */ -static void -mqtt_request_time_elapsed(struct mqtt_request_t **tail, u8_t t) -{ - struct mqtt_request_t *r; - LWIP_ASSERT("mqtt_request_time_elapsed: tail != NULL", tail != NULL); - r = *tail; - while (t > 0 && r != NULL) { - if (t >= r->timeout_diff) { - t -= (u8_t)r->timeout_diff; - /* Unchain */ - *tail = r->next; - /* Notify upper layer about timeout */ - if (r->cb != NULL) { - r->cb(r->arg, ERR_TIMEOUT); - } - mqtt_delete_request(r); - /* Tail might be be modified in callback, so re-read it in every iteration */ - r = *(struct mqtt_request_t * const volatile *)tail; - } else { - r->timeout_diff -= t; - t = 0; - } - } -} - -/** - * Free all request items - * @param tail Pointer to request queue tail pointer - */ -static void -mqtt_clear_requests(struct mqtt_request_t **tail) -{ - struct mqtt_request_t *iter, *next; - LWIP_ASSERT("mqtt_clear_requests: tail != NULL", tail != NULL); - for (iter = *tail; iter != NULL; iter = next) { - next = iter->next; - mqtt_delete_request(iter); - } - *tail = NULL; -} -/** - * Initialize all request items - * @param r_objs Pointer to request objects - */ -static void -mqtt_init_requests(struct mqtt_request_t *r_objs) -{ - u8_t n; - LWIP_ASSERT("mqtt_init_requests: r_objs != NULL", r_objs != NULL); - for (n = 0; n < MQTT_REQ_MAX_IN_FLIGHT; n++) { - /* Item pointing to itself indicates unused */ - r_objs[n].next = &r_objs[n]; - } -} - -/*--------------------------------------------------------------------------------------------------------------------- */ -/* Output message build helpers */ - - -static void -mqtt_output_append_u8(struct mqtt_ringbuf_t *rb, u8_t value) -{ - mqtt_ringbuf_put(rb, value); -} - -static -void mqtt_output_append_u16(struct mqtt_ringbuf_t *rb, u16_t value) -{ - mqtt_ringbuf_put(rb, value >> 8); - mqtt_ringbuf_put(rb, value & 0xff); -} - -static void -mqtt_output_append_buf(struct mqtt_ringbuf_t *rb, const void *data, u16_t length) -{ - u16_t n; - for (n = 0; n < length; n++) { - mqtt_ringbuf_put(rb, ((const u8_t *)data)[n]); - } -} - -static void -mqtt_output_append_string(struct mqtt_ringbuf_t *rb, const char *str, u16_t length) -{ - u16_t n; - mqtt_ringbuf_put(rb, length >> 8); - mqtt_ringbuf_put(rb, length & 0xff); - for (n = 0; n < length; n++) { - mqtt_ringbuf_put(rb, str[n]); - } -} - -/** - * Append fixed header - * @param rb Output ring buffer - * @param msg_type see enum mqtt_message_type - * @param dup MQTT DUP flag - * @param qos MQTT QoS field - * @param retain MQTT retain flag - * @param r_length Remaining length after fixed header - */ - -static void -mqtt_output_append_fixed_header(struct mqtt_ringbuf_t *rb, u8_t msg_type, u8_t dup, - u8_t qos, u8_t retain, u16_t r_length) -{ - /* Start with control byte */ - mqtt_output_append_u8(rb, (((msg_type & 0x0f) << 4) | ((dup & 1) << 3) | ((qos & 3) << 1) | (retain & 1))); - /* Encode remaining length field */ - do { - mqtt_output_append_u8(rb, (r_length & 0x7f) | (r_length >= 128 ? 0x80 : 0)); - r_length >>= 7; - } while (r_length > 0); -} - - -/** - * Check output buffer space - * @param rb Output ring buffer - * @param r_length Remaining length after fixed header - * @return 1 if message will fit, 0 if not enough buffer space - */ -static u8_t -mqtt_output_check_space(struct mqtt_ringbuf_t *rb, u16_t r_length) -{ - /* Start with length of type byte + remaining length */ - u16_t total_len = 1 + r_length; - - LWIP_ASSERT("mqtt_output_check_space: rb != NULL", rb != NULL); - - /* Calculate number of required bytes to contain the remaining bytes field and add to total*/ - do { - total_len++; - r_length >>= 7; - } while (r_length > 0); - - return (total_len <= mqtt_ringbuf_free(rb)); -} - - -/** - * Close connection to server - * @param client MQTT client - * @param reason Reason for disconnection - */ -static void -mqtt_close(mqtt_client_t *client, mqtt_connection_status_t reason) -{ - LWIP_ASSERT("mqtt_close: client != NULL", client != NULL); - - /* Bring down TCP connection if not already done */ - if (client->conn != NULL) { - err_t res; - tcp_recv(client->conn, NULL); - tcp_err(client->conn, NULL); - tcp_sent(client->conn, NULL); - res = tcp_close(client->conn); - if (res != ERR_OK) { - tcp_abort(client->conn); - LWIP_DEBUGF(MQTT_DEBUG_TRACE,("mqtt_close: Close err=%s\n", lwip_strerr(res))); - } - client->conn = NULL; - } - - /* Remove all pending requests */ - mqtt_clear_requests(&client->pend_req_queue); - /* Stop cyclic timer */ - sys_untimeout(mqtt_cyclic_timer, client); - - /* Notify upper layer of disconnection if changed state */ - if (client->conn_state != TCP_DISCONNECTED) { - - client->conn_state = TCP_DISCONNECTED; - if (client->connect_cb != NULL) { - client->connect_cb(client, client->connect_arg, reason); - } - } -} - - -/** - * Interval timer, called every MQTT_CYCLIC_TIMER_INTERVAL seconds in MQTT_CONNECTING and MQTT_CONNECTED states - * @param arg MQTT client - */ -static void -mqtt_cyclic_timer(void *arg) -{ - u8_t restart_timer = 1; - mqtt_client_t *client = (mqtt_client_t *)arg; - LWIP_ASSERT("mqtt_cyclic_timer: client != NULL", client != NULL); - - if (client->conn_state == MQTT_CONNECTING) { - client->cyclic_tick++; - if ((client->cyclic_tick * MQTT_CYCLIC_TIMER_INTERVAL) >= MQTT_CONNECT_TIMOUT) { - LWIP_DEBUGF(MQTT_DEBUG_TRACE,("mqtt_cyclic_timer: CONNECT attempt to server timed out\n")); - /* Disconnect TCP */ - mqtt_close(client, MQTT_CONNECT_TIMEOUT); - restart_timer = 0; - } - } else if (client->conn_state == MQTT_CONNECTED) { - /* Handle timeout for pending requests */ - mqtt_request_time_elapsed(&client->pend_req_queue, MQTT_CYCLIC_TIMER_INTERVAL); - - /* keep_alive > 0 means keep alive functionality shall be used */ - if (client->keep_alive > 0) { - - client->server_watchdog++; - /* If reception from server has been idle for 1.5*keep_alive time, server is considered unresponsive */ - if ((client->server_watchdog * MQTT_CYCLIC_TIMER_INTERVAL) > (client->keep_alive + client->keep_alive/2)) { - LWIP_DEBUGF(MQTT_DEBUG_WARN,("mqtt_cyclic_timer: Server incoming keep-alive timeout\n")); - mqtt_close(client, MQTT_CONNECT_TIMEOUT); - restart_timer = 0; - } - - /* If time for a keep alive message to be sent, transmission has been idle for keep_alive time */ - if ((client->cyclic_tick * MQTT_CYCLIC_TIMER_INTERVAL) >= client->keep_alive) { - LWIP_DEBUGF(MQTT_DEBUG_TRACE,("mqtt_cyclic_timer: Sending keep-alive message to server\n")); - if (mqtt_output_check_space(&client->output, 0) != 0) { - mqtt_output_append_fixed_header(&client->output, MQTT_MSG_TYPE_PINGREQ, 0, 0, 0, 0); - client->cyclic_tick = 0; - } - } else { - client->cyclic_tick++; - } - } - } else { - LWIP_DEBUGF(MQTT_DEBUG_WARN,("mqtt_cyclic_timer: Timer should not be running in state %d\n", client->conn_state)); - restart_timer = 0; - } - if (restart_timer) { - sys_timeout(MQTT_CYCLIC_TIMER_INTERVAL*1000, mqtt_cyclic_timer, arg); - } -} - - -/** - * Send PUBACK, PUBREC or PUBREL response message - * @param client MQTT client - * @param msg PUBACK, PUBREC or PUBREL - * @param pkt_id Packet identifier - * @param qos QoS value - * @return ERR_OK if successful, ERR_MEM if out of memory - */ -static err_t -pub_ack_rec_rel_response(mqtt_client_t *client, u8_t msg, u16_t pkt_id, u8_t qos) -{ - err_t err = ERR_OK; - if (mqtt_output_check_space(&client->output, 2)) { - mqtt_output_append_fixed_header(&client->output, msg, 0, qos, 0, 2); - mqtt_output_append_u16(&client->output, pkt_id); - mqtt_output_send(&client->output, client->conn); - } else { - LWIP_DEBUGF(MQTT_DEBUG_TRACE,("pub_ack_rec_rel_response: OOM creating response: %s with pkt_id: %d\n", - mqtt_msg_type_to_str(msg), pkt_id)); - err = ERR_MEM; - } - return err; -} - -/** - * Subscribe response from server - * @param r Matching request - * @param result Result code from server - */ -static void -mqtt_incomming_suback(struct mqtt_request_t *r, u8_t result) -{ - if (r->cb != NULL) { - r->cb(r->arg, result < 3 ? ERR_OK : ERR_ABRT); - } -} - - -/** - * Complete MQTT message received or buffer full - * @param client MQTT client - * @param fixed_hdr_idx header index - * @param length length received part - * @param remaining_length Remaining length of complete message - */ -static mqtt_connection_status_t - mqtt_message_received(mqtt_client_t *client, u8_t fixed_hdr_idx, u16_t length, u32_t remaining_length) -{ - mqtt_connection_status_t res = MQTT_CONNECT_ACCEPTED; - - u8_t *var_hdr_payload = client->rx_buffer + fixed_hdr_idx; - - /* Control packet type */ - u8_t pkt_type = MQTT_CTL_PACKET_TYPE(client->rx_buffer[0]); - u16_t pkt_id = 0; - - if (pkt_type == MQTT_MSG_TYPE_CONNACK) { - if (client->conn_state == MQTT_CONNECTING) { - /* Get result code from CONNACK */ - res = (mqtt_connection_status_t)var_hdr_payload[1]; - LWIP_DEBUGF(MQTT_DEBUG_TRACE,("mqtt_message_received: Connect response code %d\n", res)); - if (res == MQTT_CONNECT_ACCEPTED) { - /* Reset cyclic_tick when changing to connected state */ - client->cyclic_tick = 0; - client->conn_state = MQTT_CONNECTED; - /* Notify upper layer */ - if (client->connect_cb != 0) { - client->connect_cb(client, client->connect_arg, res); - } - } - } else { - LWIP_DEBUGF(MQTT_DEBUG_WARN,("mqtt_message_received: Received CONNACK in connected state\n")); - } - } else if (pkt_type == MQTT_MSG_TYPE_PINGRESP) { - LWIP_DEBUGF(MQTT_DEBUG_TRACE,( "mqtt_message_received: Received PINGRESP from server\n")); - - } else if (pkt_type == MQTT_MSG_TYPE_PUBLISH) { - u16_t payload_offset = 0; - u16_t payload_length = length; - u8_t qos = MQTT_CTL_PACKET_QOS(client->rx_buffer[0]); - - if (client->msg_idx <= MQTT_VAR_HEADER_BUFFER_LEN) { - /* Should have topic and pkt id*/ - uint8_t *topic; - uint16_t after_topic; - u8_t bkp; - u16_t topic_len = var_hdr_payload[0]; - topic_len = (topic_len << 8) + (u16_t)(var_hdr_payload[1]); - - topic = var_hdr_payload + 2; - after_topic = 2 + topic_len; - /* Check length, add one byte even for QoS 0 so that zero termination will fit */ - if ((after_topic + (qos? 2 : 1)) > length) { - LWIP_DEBUGF(MQTT_DEBUG_WARN,("mqtt_message_received: Receive buffer can not fit topic + pkt_id\n")); - goto out_disconnect; - } - - /* id for QoS 1 and 2 */ - if (qos > 0) { - client->inpub_pkt_id = ((u16_t)var_hdr_payload[after_topic] << 8) + (u16_t)var_hdr_payload[after_topic + 1]; - after_topic += 2; - } else { - client->inpub_pkt_id = 0; - } - /* Take backup of byte after topic */ - bkp = topic[topic_len]; - /* Zero terminate string */ - topic[topic_len] = 0; - /* Payload data remaining in receive buffer */ - payload_length = length - after_topic; - payload_offset = after_topic; - - LWIP_DEBUGF(MQTT_DEBUG_TRACE,("mqtt_incomming_publish: Received message with QoS %d at topic: %s, payload length %d\n", - qos, topic, remaining_length + payload_length)); - if (client->pub_cb != NULL) { - client->pub_cb(client->inpub_arg, (const char *)topic, remaining_length + payload_length); - } - /* Restore byte after topic */ - topic[topic_len] = bkp; - } - if (payload_length > 0 || remaining_length == 0) { - client->data_cb(client->inpub_arg, var_hdr_payload + payload_offset, payload_length, remaining_length == 0 ? MQTT_DATA_FLAG_LAST : 0); - /* Reply if QoS > 0 */ - if (remaining_length == 0 && qos > 0) { - /* Send PUBACK for QoS 1 or PUBREC for QoS 2 */ - u8_t resp_msg = (qos == 1) ? MQTT_MSG_TYPE_PUBACK : MQTT_MSG_TYPE_PUBREC; - LWIP_DEBUGF(MQTT_DEBUG_TRACE,("mqtt_incomming_publish: Sending publish response: %s with pkt_id: %d\n", - mqtt_msg_type_to_str(resp_msg), client->inpub_pkt_id)); - pub_ack_rec_rel_response(client, resp_msg, client->inpub_pkt_id, 0); - } - } - } else { - /* Get packet identifier */ - pkt_id = (u16_t)var_hdr_payload[0] << 8; - pkt_id |= (u16_t)var_hdr_payload[1]; - if (pkt_id == 0) { - LWIP_DEBUGF(MQTT_DEBUG_WARN,("mqtt_message_received: Got message with illegal packet identifier: 0\n")); - goto out_disconnect; - } - if (pkt_type == MQTT_MSG_TYPE_PUBREC) { - LWIP_DEBUGF(MQTT_DEBUG_TRACE,("mqtt_message_received: PUBREC, sending PUBREL with pkt_id: %d\n",pkt_id)); - pub_ack_rec_rel_response(client, MQTT_MSG_TYPE_PUBREL, pkt_id, 1); - - } else if (pkt_type == MQTT_MSG_TYPE_PUBREL) { - LWIP_DEBUGF(MQTT_DEBUG_TRACE,("mqtt_message_received: PUBREL, sending PUBCOMP response with pkt_id: %d\n",pkt_id)); - pub_ack_rec_rel_response(client, MQTT_MSG_TYPE_PUBCOMP, pkt_id, 0); - - } else if (pkt_type == MQTT_MSG_TYPE_SUBACK || pkt_type == MQTT_MSG_TYPE_UNSUBACK || - pkt_type == MQTT_MSG_TYPE_PUBCOMP || pkt_type == MQTT_MSG_TYPE_PUBACK) { - struct mqtt_request_t *r = mqtt_take_request(&client->pend_req_queue, pkt_id); - if (r != NULL) { - LWIP_DEBUGF(MQTT_DEBUG_TRACE,("mqtt_message_received: %s response with id %d\n", mqtt_msg_type_to_str(pkt_type), pkt_id)); - if (pkt_type == MQTT_MSG_TYPE_SUBACK) { - if (length < 3) { - LWIP_DEBUGF(MQTT_DEBUG_WARN,("mqtt_message_received: To small SUBACK packet\n")); - goto out_disconnect; - } else { - mqtt_incomming_suback(r, var_hdr_payload[2]); - } - } else if (r->cb != NULL) { - r->cb(r->arg, ERR_OK); - } - mqtt_delete_request(r); - } else { - LWIP_DEBUGF(MQTT_DEBUG_WARN,( "mqtt_message_received: Received %s reply, with wrong pkt_id: %d\n", mqtt_msg_type_to_str(pkt_type), pkt_id)); - } - } else { - LWIP_DEBUGF(MQTT_DEBUG_WARN,( "mqtt_message_received: Received unknown message type: %d\n", pkt_type)); - goto out_disconnect; - } - } - return res; -out_disconnect: - return MQTT_CONNECT_DISCONNECTED; -} - - -/** - * MQTT incoming message parser - * @param client MQTT client - * @param p PBUF chain of received data - * @return Connection status - */ -static mqtt_connection_status_t -mqtt_parse_incoming(mqtt_client_t *client, struct pbuf *p) -{ - u16_t in_offset = 0; - u32_t msg_rem_len = 0; - u8_t fixed_hdr_idx = 0; - u8_t b = 0; - - while (p->tot_len > in_offset) { - if ((fixed_hdr_idx < 2) || ((b & 0x80) != 0)) { - - if (fixed_hdr_idx < client->msg_idx) { - b = client->rx_buffer[fixed_hdr_idx]; - } else { - b = pbuf_get_at(p, in_offset++); - client->rx_buffer[client->msg_idx++] = b; - } - fixed_hdr_idx++; - - if (fixed_hdr_idx >= 2) { - msg_rem_len |= (u32_t)(b & 0x7f) << ((fixed_hdr_idx - 2) * 7); - if ((b & 0x80) == 0) { - LWIP_DEBUGF(MQTT_DEBUG_TRACE,("mqtt_parse_incoming: Remaining length after fixed header: %d\n", msg_rem_len)); - if (msg_rem_len == 0) { - /* Complete message with no extra headers of payload received */ - mqtt_message_received(client, fixed_hdr_idx, 0, 0); - client->msg_idx = 0; - fixed_hdr_idx = 0; - } else { - /* Bytes remaining in message */ - msg_rem_len = (msg_rem_len + fixed_hdr_idx) - client->msg_idx; - } - } - } - } else { - u16_t cpy_len, cpy_start, buffer_space; - - cpy_start = (client->msg_idx - fixed_hdr_idx) % (MQTT_VAR_HEADER_BUFFER_LEN - fixed_hdr_idx) + fixed_hdr_idx; - - /* Allow to copy the lesser one of available length in input data or bytes remaining in message */ - cpy_len = (u16_t)LWIP_MIN((u16_t)(p->tot_len - in_offset), msg_rem_len); - - /* Limit to available space in buffer */ - buffer_space = MQTT_VAR_HEADER_BUFFER_LEN - cpy_start; - if (cpy_len > buffer_space) { - cpy_len = buffer_space; - } - pbuf_copy_partial(p, client->rx_buffer+cpy_start, cpy_len, in_offset); - - /* Advance get and put indexes */ - client->msg_idx += cpy_len; - in_offset += cpy_len; - msg_rem_len -= cpy_len; - - LWIP_DEBUGF(MQTT_DEBUG_TRACE,("mqtt_parse_incoming: msg_idx: %d, cpy_len: %d, remaining %d\n", client->msg_idx, cpy_len, msg_rem_len)); - if (msg_rem_len == 0 || cpy_len == buffer_space) { - /* Whole message received or buffer is full */ - mqtt_connection_status_t res = mqtt_message_received(client, fixed_hdr_idx, (cpy_start + cpy_len) - fixed_hdr_idx, msg_rem_len); - if (res != MQTT_CONNECT_ACCEPTED) { - return res; - } - if (msg_rem_len == 0) { - /* Reset parser state */ - client->msg_idx = 0; - /* msg_tot_len = 0; */ - fixed_hdr_idx = 0; - } - } - } - } - return MQTT_CONNECT_ACCEPTED; -} - - -/** - * TCP received callback function. @see tcp_recv_fn - * @param arg MQTT client - * @param p PBUF chain of received data - * @param err Passed as return value if not ERR_OK - * @return ERR_OK or err passed into callback - */ -static err_t -mqtt_tcp_recv_cb(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) -{ - mqtt_client_t *client = (mqtt_client_t *)arg; - LWIP_ASSERT("mqtt_tcp_recv_cb: client != NULL", client != NULL); - LWIP_ASSERT("mqtt_tcp_recv_cb: client->conn == pcb", client->conn == pcb); - - if (p == NULL) { - LWIP_DEBUGF(MQTT_DEBUG_TRACE,("mqtt_tcp_recv_cb: Recv pbuf=NULL, remote has closed connection\n")); - mqtt_close(client, MQTT_CONNECT_DISCONNECTED); - } else { - mqtt_connection_status_t res; - if (err != ERR_OK) { - LWIP_DEBUGF(MQTT_DEBUG_WARN,("mqtt_tcp_recv_cb: Recv err=%d\n", err)); - pbuf_free(p); - return err; - } - - /* Tell remote that data has been received */ - tcp_recved(pcb, p->tot_len); - res = mqtt_parse_incoming(client, p); - pbuf_free(p); - - if (res != MQTT_CONNECT_ACCEPTED) { - mqtt_close(client, res); - } - /* If keep alive functionality is used */ - if (client->keep_alive != 0) { - /* Reset server alive watchdog */ - client->server_watchdog = 0; - } - - } - return ERR_OK; -} - - -/** - * TCP data sent callback function. @see tcp_sent_fn - * @param arg MQTT client - * @param tpcb TCP connection handle - * @param len Number of bytes sent - * @return ERR_OK - */ -static err_t -mqtt_tcp_sent_cb(void *arg, struct tcp_pcb *tpcb, u16_t len) -{ - mqtt_client_t *client = (mqtt_client_t *)arg; - - LWIP_UNUSED_ARG(tpcb); - LWIP_UNUSED_ARG(len); - - if (client->conn_state == MQTT_CONNECTED) { - struct mqtt_request_t *r; - - /* Reset keep-alive send timer and server watchdog */ - client->cyclic_tick = 0; - client->server_watchdog = 0; - /* QoS 0 publish has no response from server, so call its callbacks here */ - while ((r = mqtt_take_request(&client->pend_req_queue, 0)) != NULL) { - LWIP_DEBUGF(MQTT_DEBUG_TRACE,("mqtt_tcp_sent_cb: Calling QoS 0 publish complete callback\n")); - if (r->cb != NULL) { - r->cb(r->arg, ERR_OK); - } - mqtt_delete_request(r); - } - /* Try send any remaining buffers from output queue */ - mqtt_output_send(&client->output, client->conn); - } - return ERR_OK; -} - -/** - * TCP error callback function. @see tcp_err_fn - * @param arg MQTT client - * @param err Error encountered - */ -static void -mqtt_tcp_err_cb(void *arg, err_t err) -{ - mqtt_client_t *client = (mqtt_client_t *)arg; - LWIP_UNUSED_ARG(err); /* only used for debug output */ - LWIP_DEBUGF(MQTT_DEBUG_TRACE,("mqtt_tcp_err_cb: TCP error callback: error %d, arg: %p\n", err, arg)); - LWIP_ASSERT("mqtt_tcp_err_cb: client != NULL", client != NULL); - /* Set conn to null before calling close as pcb is already deallocated*/ - client->conn = 0; - mqtt_close(client, MQTT_CONNECT_DISCONNECTED); -} - -/** - * TCP poll callback function. @see tcp_poll_fn - * @param arg MQTT client - * @param tpcb TCP connection handle - * @return err ERR_OK - */ -static err_t -mqtt_tcp_poll_cb(void *arg, struct tcp_pcb *tpcb) -{ - mqtt_client_t *client = (mqtt_client_t *)arg; - if (client->conn_state == MQTT_CONNECTED) { - /* Try send any remaining buffers from output queue */ - mqtt_output_send(&client->output, tpcb); - } - return ERR_OK; -} - -/** - * TCP connect callback function. @see tcp_connected_fn - * @param arg MQTT client - * @param err Always ERR_OK, mqtt_tcp_err_cb is called in case of error - * @return ERR_OK - */ -static err_t -mqtt_tcp_connect_cb(void *arg, struct tcp_pcb *tpcb, err_t err) -{ - mqtt_client_t* client = (mqtt_client_t *)arg; - - if (err != ERR_OK) { - LWIP_DEBUGF(MQTT_DEBUG_WARN,("mqtt_tcp_connect_cb: TCP connect error %d\n", err)); - return err; - } - - /* Initiate receiver state */ - client->msg_idx = 0; - - /* Setup TCP callbacks */ - tcp_recv(tpcb, mqtt_tcp_recv_cb); - tcp_sent(tpcb, mqtt_tcp_sent_cb); - tcp_poll(tpcb, mqtt_tcp_poll_cb, 2); - - LWIP_DEBUGF(MQTT_DEBUG_TRACE,("mqtt_tcp_connect_cb: TCP connection established to server\n")); - /* Enter MQTT connect state */ - client->conn_state = MQTT_CONNECTING; - - /* Start cyclic timer */ - sys_timeout(MQTT_CYCLIC_TIMER_INTERVAL*1000, mqtt_cyclic_timer, client); - client->cyclic_tick = 0; - - /* Start transmission from output queue, connect message is the first one out*/ - mqtt_output_send(&client->output, client->conn); - - return ERR_OK; -} - - - -/*---------------------------------------------------------------------------------------------------- */ -/* Public API */ - - -/** - * @ingroup mqtt - * MQTT publish function. - * @param client MQTT client - * @param topic Publish topic string - * @param payload Data to publish (NULL is allowed) - * @param payload_length: Length of payload (0 is allowed) - * @param qos Quality of service, 0 1 or 2 - * @param retain MQTT retain flag - * @param cb Callback to call when publish is complete or has timed out - * @param arg User supplied argument to publish callback - * @return ERR_OK if successful - * ERR_CONN if client is disconnected - * ERR_MEM if short on memory - */ -err_t -mqtt_publish(mqtt_client_t *client, const char *topic, const void *payload, u16_t payload_length, u8_t qos, u8_t retain, - mqtt_request_cb_t cb, void *arg) -{ - struct mqtt_request_t *r; - u16_t pkt_id; - size_t topic_strlen; - size_t total_len; - u16_t topic_len; - u16_t remaining_length; - - LWIP_ASSERT("mqtt_publish: client != NULL", client); - LWIP_ASSERT("mqtt_publish: topic != NULL", topic); - LWIP_ERROR("mqtt_publish: TCP disconnected", (client->conn_state != TCP_DISCONNECTED), return ERR_CONN); - - topic_strlen = strlen(topic); - LWIP_ERROR("mqtt_publish: topic length overflow", (topic_strlen <= (0xFFFF - 2)), return ERR_ARG); - topic_len = (u16_t)topic_strlen; - total_len = 2 + topic_len + payload_length; - LWIP_ERROR("mqtt_publish: total length overflow", (total_len <= 0xFFFF), return ERR_ARG); - remaining_length = (u16_t)total_len; - - LWIP_DEBUGF(MQTT_DEBUG_TRACE,("mqtt_publish: Publish with payload length %d to topic \"%s\"\n", payload_length, topic)); - - if (qos > 0) { - remaining_length += 2; - /* Generate pkt_id id for QoS1 and 2 */ - pkt_id = msg_generate_packet_id(client); - } else { - /* Use reserved value pkt_id 0 for QoS 0 in request handle */ - pkt_id = 0; - } - - r = mqtt_create_request(client->req_list, pkt_id, cb, arg); - if (r == NULL) { - return ERR_MEM; - } - - if (mqtt_output_check_space(&client->output, remaining_length) == 0) { - mqtt_delete_request(r); - return ERR_MEM; - } - /* Append fixed header */ - mqtt_output_append_fixed_header(&client->output, MQTT_MSG_TYPE_PUBLISH, 0, qos, retain, remaining_length); - - /* Append Topic */ - mqtt_output_append_string(&client->output, topic, topic_len); - - /* Append packet if for QoS 1 and 2*/ - if (qos > 0) { - mqtt_output_append_u16(&client->output, pkt_id); - } - - /* Append optional publish payload */ - if ((payload != NULL) && (payload_length > 0)) { - mqtt_output_append_buf(&client->output, payload, payload_length); - } - - mqtt_append_request(&client->pend_req_queue, r); - mqtt_output_send(&client->output, client->conn); - return ERR_OK; -} - - -/** - * @ingroup mqtt - * MQTT subscribe/unsubscribe function. - * @param client MQTT client - * @param topic topic to subscribe to - * @param qos Quality of service, 0 1 or 2 (only used for subscribe) - * @param cb Callback to call when subscribe/unsubscribe reponse is received - * @param arg User supplied argument to publish callback - * @param sub 1 for subscribe, 0 for unsubscribe - * @return ERR_OK if successful, @see err_t enum for other results - */ -err_t -mqtt_sub_unsub(mqtt_client_t *client, const char *topic, u8_t qos, mqtt_request_cb_t cb, void *arg, u8_t sub) -{ - size_t topic_strlen; - size_t total_len; - u16_t topic_len; - u16_t remaining_length; - u16_t pkt_id; - struct mqtt_request_t *r; - - LWIP_ASSERT("mqtt_sub_unsub: client != NULL", client); - LWIP_ASSERT("mqtt_sub_unsub: topic != NULL", topic); - - topic_strlen = strlen(topic); - LWIP_ERROR("mqtt_sub_unsub: topic length overflow", (topic_strlen <= (0xFFFF - 2)), return ERR_ARG); - topic_len = (u16_t)topic_strlen; - /* Topic string, pkt_id, qos for subscribe */ - total_len = topic_len + 2 + 2 + (sub != 0); - LWIP_ERROR("mqtt_sub_unsub: total length overflow", (total_len <= 0xFFFF), return ERR_ARG); - remaining_length = (u16_t)total_len; - - LWIP_ASSERT("mqtt_sub_unsub: qos < 3", qos < 3); - if (client->conn_state == TCP_DISCONNECTED) { - LWIP_DEBUGF(MQTT_DEBUG_WARN,("mqtt_sub_unsub: Can not (un)subscribe in disconnected state\n")); - return ERR_CONN; - } - - pkt_id = msg_generate_packet_id(client); - r = mqtt_create_request(client->req_list, pkt_id, cb, arg); - if (r == NULL) { - return ERR_MEM; - } - - if (mqtt_output_check_space(&client->output, remaining_length) == 0) { - mqtt_delete_request(r); - return ERR_MEM; - } - - LWIP_DEBUGF(MQTT_DEBUG_TRACE,("mqtt_sub_unsub: Client (un)subscribe to topic \"%s\", id: %d\n", topic, pkt_id)); - - mqtt_output_append_fixed_header(&client->output, sub ? MQTT_MSG_TYPE_SUBSCRIBE : MQTT_MSG_TYPE_UNSUBSCRIBE, 0, 1, 0, remaining_length); - /* Packet id */ - mqtt_output_append_u16(&client->output, pkt_id); - /* Topic */ - mqtt_output_append_string(&client->output, topic, topic_len); - /* QoS */ - if (sub != 0) { - mqtt_output_append_u8(&client->output, LWIP_MIN(qos, 2)); - } - - mqtt_append_request(&client->pend_req_queue, r); - mqtt_output_send(&client->output, client->conn); - return ERR_OK; -} - - -/** - * @ingroup mqtt - * Set callback to handle incoming publish requests from server - * @param client MQTT client - * @param pub_cb Callback invoked when publish starts, contain topic and total length of payload - * @param data_cb Callback for each fragment of payload that arrives - * @param arg User supplied argument to both callbacks - */ -void -mqtt_set_inpub_callback(mqtt_client_t *client, mqtt_incoming_publish_cb_t pub_cb, - mqtt_incoming_data_cb_t data_cb, void *arg) -{ - LWIP_ASSERT("mqtt_set_inpub_callback: client != NULL", client != NULL); - client->data_cb = data_cb; - client->pub_cb = pub_cb; - client->inpub_arg = arg; -} - -/** - * @ingroup mqtt - * Create a new MQTT client instance - * @return Pointer to instance on success, NULL otherwise - */ -mqtt_client_t * -mqtt_client_new(void) -{ - mqtt_client_t *client = (mqtt_client_t *)mem_malloc(sizeof(mqtt_client_t)); - if (client != NULL) { - memset(client, 0, sizeof(mqtt_client_t)); - } - return client; -} - - -/** - * @ingroup mqtt - * Connect to MQTT server - * @param client MQTT client - * @param ip_addr Server IP - * @param port Server port - * @param cb Connection state change callback - * @param arg User supplied argument to connection callback - * @param client_info Client identification and connection options - * @return ERR_OK if successful, @see err_t enum for other results - */ -err_t -mqtt_client_connect(mqtt_client_t *client, const ip_addr_t *ip_addr, u16_t port, mqtt_connection_cb_t cb, void *arg, - const struct mqtt_connect_client_info_t *client_info) -{ - err_t err; - size_t len; - u16_t client_id_length; - /* Length is the sum of 2+"MQTT", protocol level, flags and keep alive */ - u16_t remaining_length = 2 + 4 + 1 + 1 + 2; - u8_t flags = 0, will_topic_len = 0, will_msg_len = 0; - - LWIP_ASSERT("mqtt_client_connect: client != NULL", client != NULL); - LWIP_ASSERT("mqtt_client_connect: ip_addr != NULL", ip_addr != NULL); - LWIP_ASSERT("mqtt_client_connect: client_info != NULL", client_info != NULL); - LWIP_ASSERT("mqtt_client_connect: client_info->client_id != NULL", client_info->client_id != NULL); - - if (client->conn_state != TCP_DISCONNECTED) { - LWIP_DEBUGF(MQTT_DEBUG_WARN,("mqtt_client_connect: Already connected\n")); - return ERR_ISCONN; - } - - /* Wipe clean */ - memset(client, 0, sizeof(mqtt_client_t)); - client->connect_arg = arg; - client->connect_cb = cb; - client->keep_alive = client_info->keep_alive; - mqtt_init_requests(client->req_list); - - /* Build connect message */ - if (client_info->will_topic != NULL && client_info->will_msg != NULL) { - flags |= MQTT_CONNECT_FLAG_WILL; - flags |= (client_info->will_qos & 3) << 3; - if (client_info->will_retain) { - flags |= MQTT_CONNECT_FLAG_WILL_RETAIN; - } - len = strlen(client_info->will_topic); - LWIP_ERROR("mqtt_client_connect: client_info->will_topic length overflow", len <= 0xFF, return ERR_VAL); - LWIP_ERROR("mqtt_client_connect: client_info->will_topic length must be > 0", len > 0, return ERR_VAL); - will_topic_len = (u8_t)len; - len = strlen(client_info->will_msg); - LWIP_ERROR("mqtt_client_connect: client_info->will_msg length overflow", len <= 0xFF, return ERR_VAL); - will_msg_len = (u8_t)len; - len = remaining_length + 2 + will_topic_len + 2 + will_msg_len; - LWIP_ERROR("mqtt_client_connect: remaining_length overflow", len <= 0xFFFF, return ERR_VAL); - remaining_length = (u16_t)len; - } - - /* Don't complicate things, always connect using clean session */ - flags |= MQTT_CONNECT_FLAG_CLEAN_SESSION; - - len = strlen(client_info->client_id); - LWIP_ERROR("mqtt_client_connect: client_info->client_id length overflow", len <= 0xFFFF, return ERR_VAL); - client_id_length = (u16_t)len; - len = remaining_length + 2 + client_id_length; - LWIP_ERROR("mqtt_client_connect: remaining_length overflow", len <= 0xFFFF, return ERR_VAL); - remaining_length = (u16_t)len; - - if (mqtt_output_check_space(&client->output, remaining_length) == 0) { - return ERR_MEM; - } - - client->conn = tcp_new(); - if (client->conn == NULL) { - return ERR_MEM; - } - - /* Set arg pointer for callbacks */ - tcp_arg(client->conn, client); - /* Any local address, pick random local port number */ - err = tcp_bind(client->conn, IP_ADDR_ANY, 0); - if (err != ERR_OK) { - LWIP_DEBUGF(MQTT_DEBUG_WARN,("mqtt_client_connect: Error binding to local ip/port, %d\n", err)); - goto tcp_fail; - } - LWIP_DEBUGF(MQTT_DEBUG_TRACE,("mqtt_client_connect: Connecting to host: %s at port:%"U16_F"\n", ipaddr_ntoa(ip_addr), port)); - - /* Connect to server */ - err = tcp_connect(client->conn, ip_addr, port, mqtt_tcp_connect_cb); - if (err != ERR_OK) { - LWIP_DEBUGF(MQTT_DEBUG_TRACE,("mqtt_client_connect: Error connecting to remote ip/port, %d\n", err)); - goto tcp_fail; - } - /* Set error callback */ - tcp_err(client->conn, mqtt_tcp_err_cb); - client->conn_state = TCP_CONNECTING; - - /* Append fixed header */ - mqtt_output_append_fixed_header(&client->output, MQTT_MSG_TYPE_CONNECT, 0, 0, 0, remaining_length); - /* Append Protocol string */ - mqtt_output_append_string(&client->output, "MQTT", 4); - /* Append Protocol level */ - mqtt_output_append_u8(&client->output, 4); - /* Append connect flags */ - mqtt_output_append_u8(&client->output, flags); - /* Append keep-alive */ - mqtt_output_append_u16(&client->output, client_info->keep_alive); - /* Append client id */ - mqtt_output_append_string(&client->output, client_info->client_id, client_id_length); - /* Append will message if used */ - if ((flags & MQTT_CONNECT_FLAG_WILL) != 0) { - mqtt_output_append_string(&client->output, client_info->will_topic, will_topic_len); - mqtt_output_append_string(&client->output, client_info->will_msg, will_msg_len); - } - return ERR_OK; - -tcp_fail: - tcp_abort(client->conn); - client->conn = NULL; - return err; -} - - -/** - * @ingroup mqtt - * Disconnect from MQTT server - * @param client MQTT client - */ -void -mqtt_disconnect(mqtt_client_t *client) -{ - LWIP_ASSERT("mqtt_disconnect: client != NULL", client); - /* If connection in not already closed */ - if (client->conn_state != TCP_DISCONNECTED) { - /* Set conn_state before calling mqtt_close to prevent callback from being called */ - client->conn_state = TCP_DISCONNECTED; - mqtt_close(client, (mqtt_connection_status_t)0); - } -} - -/** - * @ingroup mqtt - * Check connection with server - * @param client MQTT client - * @return 1 if connected to server, 0 otherwise - */ -u8_t -mqtt_client_is_connected(mqtt_client_t *client) -{ - LWIP_ASSERT("mqtt_client_is_connected: client != NULL", client); - return client->conn_state == MQTT_CONNECTED; -} - -#endif /* LWIP_TCP && LWIP_CALLBACK_API */ diff --git a/third_party/lwip/repo/lwip/src/apps/netbiosns/netbiosns.c b/third_party/lwip/repo/lwip/src/apps/netbiosns/netbiosns.c deleted file mode 100644 index 2dfbe6590107ff..00000000000000 --- a/third_party/lwip/repo/lwip/src/apps/netbiosns/netbiosns.c +++ /dev/null @@ -1,367 +0,0 @@ -/** - * @file - * NetBIOS name service responder - */ - -/** - * @defgroup netbiosns NETBIOS responder - * @ingroup apps - * - * This is an example implementation of a NetBIOS name server. - * It responds to name queries for a configurable name. - * Name resolving is not supported. - * - * Note that the device doesn't broadcast it's own name so can't - * detect duplicate names! - */ - -/* - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - */ - -#include "lwip/apps/netbiosns.h" - -#if LWIP_IPV4 && LWIP_UDP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/def.h" -#include "lwip/udp.h" -#include "lwip/netif.h" - -#include - -/** default port number for "NetBIOS Name service */ -#define NETBIOS_PORT 137 - -/** size of a NetBIOS name */ -#define NETBIOS_NAME_LEN 16 - -/** The Time-To-Live for NetBIOS name responds (in seconds) - * Default is 300000 seconds (3 days, 11 hours, 20 minutes) */ -#define NETBIOS_NAME_TTL 300000u - -/** NetBIOS header flags */ -#define NETB_HFLAG_RESPONSE 0x8000U -#define NETB_HFLAG_OPCODE 0x7800U -#define NETB_HFLAG_OPCODE_NAME_QUERY 0x0000U -#define NETB_HFLAG_AUTHORATIVE 0x0400U -#define NETB_HFLAG_TRUNCATED 0x0200U -#define NETB_HFLAG_RECURS_DESIRED 0x0100U -#define NETB_HFLAG_RECURS_AVAILABLE 0x0080U -#define NETB_HFLAG_BROADCAST 0x0010U -#define NETB_HFLAG_REPLYCODE 0x0008U -#define NETB_HFLAG_REPLYCODE_NOERROR 0x0000U - -/** NetBIOS name flags */ -#define NETB_NFLAG_UNIQUE 0x8000U -#define NETB_NFLAG_NODETYPE 0x6000U -#define NETB_NFLAG_NODETYPE_HNODE 0x6000U -#define NETB_NFLAG_NODETYPE_MNODE 0x4000U -#define NETB_NFLAG_NODETYPE_PNODE 0x2000U -#define NETB_NFLAG_NODETYPE_BNODE 0x0000U - -/** NetBIOS message header */ -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct netbios_hdr { - PACK_STRUCT_FIELD(u16_t trans_id); - PACK_STRUCT_FIELD(u16_t flags); - PACK_STRUCT_FIELD(u16_t questions); - PACK_STRUCT_FIELD(u16_t answerRRs); - PACK_STRUCT_FIELD(u16_t authorityRRs); - PACK_STRUCT_FIELD(u16_t additionalRRs); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -/** NetBIOS message name part */ -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct netbios_name_hdr { - PACK_STRUCT_FLD_8(u8_t nametype); - PACK_STRUCT_FLD_8(u8_t encname[(NETBIOS_NAME_LEN*2)+1]); - PACK_STRUCT_FIELD(u16_t type); - PACK_STRUCT_FIELD(u16_t cls); - PACK_STRUCT_FIELD(u32_t ttl); - PACK_STRUCT_FIELD(u16_t datalen); - PACK_STRUCT_FIELD(u16_t flags); - PACK_STRUCT_FLD_S(ip4_addr_p_t addr); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -/** NetBIOS message */ -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct netbios_resp -{ - struct netbios_hdr resp_hdr; - struct netbios_name_hdr resp_name; -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -#ifdef NETBIOS_LWIP_NAME -#define NETBIOS_LOCAL_NAME NETBIOS_LWIP_NAME -#else -static char netbiosns_local_name[NETBIOS_NAME_LEN]; -#define NETBIOS_LOCAL_NAME netbiosns_local_name -#endif - -struct udp_pcb *netbiosns_pcb; - -/** Decode a NetBIOS name (from packet to string) */ -static int -netbiosns_name_decode(char *name_enc, char *name_dec, int name_dec_len) -{ - char *pname; - char cname; - char cnbname; - int idx = 0; - - LWIP_UNUSED_ARG(name_dec_len); - - /* Start decoding netbios name. */ - pname = name_enc; - for (;;) { - /* Every two characters of the first level-encoded name - * turn into one character in the decoded name. */ - cname = *pname; - if (cname == '\0') - break; /* no more characters */ - if (cname == '.') - break; /* scope ID follows */ - if (cname < 'A' || cname > 'Z') { - /* Not legal. */ - return -1; - } - cname -= 'A'; - cnbname = cname << 4; - pname++; - - cname = *pname; - if (cname == '\0' || cname == '.') { - /* No more characters in the name - but we're in - * the middle of a pair. Not legal. */ - return -1; - } - if (cname < 'A' || cname > 'Z') { - /* Not legal. */ - return -1; - } - cname -= 'A'; - cnbname |= cname; - pname++; - - /* Do we have room to store the character? */ - if (idx < NETBIOS_NAME_LEN) { - /* Yes - store the character. */ - name_dec[idx++] = (cnbname!=' '?cnbname:'\0'); - } - } - - return 0; -} - -#if 0 /* function currently unused */ -/** Encode a NetBIOS name (from string to packet) - currently unused because - we don't ask for names. */ -static int -netbiosns_name_encode(char *name_enc, char *name_dec, int name_dec_len) -{ - char *pname; - char cname; - unsigned char ucname; - int idx = 0; - - /* Start encoding netbios name. */ - pname = name_enc; - - for (;;) { - /* Every two characters of the first level-encoded name - * turn into one character in the decoded name. */ - cname = *pname; - if (cname == '\0') - break; /* no more characters */ - if (cname == '.') - break; /* scope ID follows */ - if ((cname < 'A' || cname > 'Z') && (cname < '0' || cname > '9')) { - /* Not legal. */ - return -1; - } - - /* Do we have room to store the character? */ - if (idx >= name_dec_len) { - return -1; - } - - /* Yes - store the character. */ - ucname = cname; - name_dec[idx++] = ('A'+((ucname>>4) & 0x0F)); - name_dec[idx++] = ('A'+( ucname & 0x0F)); - pname++; - } - - /* Fill with "space" coding */ - for (;idx < name_dec_len - 1;) { - name_dec[idx++] = 'C'; - name_dec[idx++] = 'A'; - } - - /* Terminate string */ - name_dec[idx] = '\0'; - - return 0; -} -#endif /* 0 */ - -/** NetBIOS Name service recv callback */ -static void -netbiosns_recv(void *arg, struct udp_pcb *upcb, struct pbuf *p, const ip_addr_t *addr, u16_t port) -{ - LWIP_UNUSED_ARG(arg); - - /* if packet is valid */ - if (p != NULL) { - char netbios_name[NETBIOS_NAME_LEN+1]; - struct netbios_hdr* netbios_hdr = (struct netbios_hdr*)p->payload; - struct netbios_name_hdr* netbios_name_hdr = (struct netbios_name_hdr*)(netbios_hdr+1); - - /* we only answer if we got a default interface */ - if (netif_default != NULL) { - /* @todo: do we need to check answerRRs/authorityRRs/additionalRRs? */ - /* if the packet is a NetBIOS name query question */ - if (((netbios_hdr->flags & PP_NTOHS(NETB_HFLAG_OPCODE)) == PP_NTOHS(NETB_HFLAG_OPCODE_NAME_QUERY)) && - ((netbios_hdr->flags & PP_NTOHS(NETB_HFLAG_RESPONSE)) == 0) && - (netbios_hdr->questions == PP_NTOHS(1))) { - /* decode the NetBIOS name */ - netbiosns_name_decode((char*)(netbios_name_hdr->encname), netbios_name, sizeof(netbios_name)); - /* if the packet is for us */ - if (lwip_strnicmp(netbios_name, NETBIOS_LOCAL_NAME, sizeof(NETBIOS_LOCAL_NAME)) == 0) { - struct pbuf *q; - struct netbios_resp *resp; - - q = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct netbios_resp), PBUF_RAM); - if (q != NULL) { - resp = (struct netbios_resp*)q->payload; - - /* prepare NetBIOS header response */ - resp->resp_hdr.trans_id = netbios_hdr->trans_id; - resp->resp_hdr.flags = PP_HTONS(NETB_HFLAG_RESPONSE | - NETB_HFLAG_OPCODE_NAME_QUERY | - NETB_HFLAG_AUTHORATIVE | - NETB_HFLAG_RECURS_DESIRED); - resp->resp_hdr.questions = 0; - resp->resp_hdr.answerRRs = PP_HTONS(1); - resp->resp_hdr.authorityRRs = 0; - resp->resp_hdr.additionalRRs = 0; - - /* prepare NetBIOS header datas */ - MEMCPY( resp->resp_name.encname, netbios_name_hdr->encname, sizeof(netbios_name_hdr->encname)); - resp->resp_name.nametype = netbios_name_hdr->nametype; - resp->resp_name.type = netbios_name_hdr->type; - resp->resp_name.cls = netbios_name_hdr->cls; - resp->resp_name.ttl = PP_HTONL(NETBIOS_NAME_TTL); - resp->resp_name.datalen = PP_HTONS(sizeof(resp->resp_name.flags)+sizeof(resp->resp_name.addr)); - resp->resp_name.flags = PP_HTONS(NETB_NFLAG_NODETYPE_BNODE); - ip4_addr_copy(resp->resp_name.addr, *netif_ip4_addr(netif_default)); - - /* send the NetBIOS response */ - udp_sendto(upcb, q, addr, port); - - /* free the "reference" pbuf */ - pbuf_free(q); - } - } - } - } - /* free the pbuf */ - pbuf_free(p); - } -} - -/** - * @ingroup netbiosns - * Init netbios responder - */ -void -netbiosns_init(void) -{ -#ifdef NETBIOS_LWIP_NAME - LWIP_ASSERT("NetBIOS name is too long!", strlen(NETBIOS_LWIP_NAME) < NETBIOS_NAME_LEN); -#endif - - netbiosns_pcb = udp_new_ip_type(IPADDR_TYPE_ANY); - if (netbiosns_pcb != NULL) { - /* we have to be allowed to send broadcast packets! */ - ip_set_option(netbiosns_pcb, SOF_BROADCAST); - udp_bind(netbiosns_pcb, IP_ANY_TYPE, NETBIOS_PORT); - udp_recv(netbiosns_pcb, netbiosns_recv, netbiosns_pcb); - } -} - -#ifndef NETBIOS_LWIP_NAME -/** - * @ingroup netbiosns - * Set netbios name. ATTENTION: the hostname must be less than 15 characters! - */ -void -netbiosns_set_name(const char* hostname) -{ - size_t copy_len = strlen(hostname); - LWIP_ASSERT("NetBIOS name is too long!", copy_len < NETBIOS_NAME_LEN); - if (copy_len >= NETBIOS_NAME_LEN) { - copy_len = NETBIOS_NAME_LEN - 1; - } - MEMCPY(netbiosns_local_name, hostname, copy_len + 1); -} -#endif - -/** - * @ingroup netbiosns - * Stop netbios responder - */ -void -netbiosns_stop(void) -{ - if (netbiosns_pcb != NULL) { - udp_remove(netbiosns_pcb); - netbiosns_pcb = NULL; - } -} - -#endif /* LWIP_IPV4 && LWIP_UDP */ diff --git a/third_party/lwip/repo/lwip/src/apps/snmp/snmp_asn1.c b/third_party/lwip/repo/lwip/src/apps/snmp/snmp_asn1.c deleted file mode 100644 index f35b760462b0bf..00000000000000 --- a/third_party/lwip/repo/lwip/src/apps/snmp/snmp_asn1.c +++ /dev/null @@ -1,749 +0,0 @@ -/** - * @file - * Abstract Syntax Notation One (ISO 8824, 8825) encoding - * - * @todo not optimised (yet), favor correctness over speed, favor speed over size - */ - -/* - * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * Author: Christiaan Simons - * Martin Hentschel - */ - -#include "lwip/apps/snmp_opts.h" - -#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */ - -#include "snmp_asn1.h" - -#define PBUF_OP_EXEC(code) \ - if ((code) != ERR_OK) { \ - return ERR_BUF; \ - } - -/** - * Encodes a TLV into a pbuf stream. - * - * @param pbuf_stream points to a pbuf stream - * @param tlv TLV to encode - * @return ERR_OK if successful, ERR_ARG if we can't (or won't) encode - */ -err_t -snmp_ans1_enc_tlv(struct snmp_pbuf_stream* pbuf_stream, struct snmp_asn1_tlv* tlv) -{ - u8_t data; - u8_t length_bytes_required; - - /* write type */ - if ((tlv->type & SNMP_ASN1_DATATYPE_MASK) == SNMP_ASN1_DATATYPE_EXTENDED) { - /* extended format is not used by SNMP so we do not accept those values */ - return ERR_ARG; - } - if (tlv->type_len != 0) { - /* any other value as auto is not accepted for type (we always use one byte because extended syntax is prohibited) */ - return ERR_ARG; - } - - PBUF_OP_EXEC(snmp_pbuf_stream_write(pbuf_stream, tlv->type)); - tlv->type_len = 1; - - /* write length */ - if (tlv->value_len <= 127) { - length_bytes_required = 1; - } else if (tlv->value_len <= 255) { - length_bytes_required = 2; - } else { - length_bytes_required = 3; - } - - /* check for forced min length */ - if (tlv->length_len > 0) { - if (tlv->length_len < length_bytes_required) { - /* unable to code requested length in requested number of bytes */ - return ERR_ARG; - } - - length_bytes_required = tlv->length_len; - } else { - tlv->length_len = length_bytes_required; - } - - if (length_bytes_required > 1) { - /* multi byte representation required */ - length_bytes_required--; - data = 0x80 | length_bytes_required; /* extended length definition, 1 length byte follows */ - - PBUF_OP_EXEC(snmp_pbuf_stream_write(pbuf_stream, data)); - - while (length_bytes_required > 1) { - if (length_bytes_required == 2) { - /* append high byte */ - data = (u8_t)(tlv->value_len >> 8); - } else { - /* append leading 0x00 */ - data = 0x00; - } - - PBUF_OP_EXEC(snmp_pbuf_stream_write(pbuf_stream, data)); - length_bytes_required--; - } - } - - /* append low byte */ - data = (u8_t)(tlv->value_len & 0xFF); - PBUF_OP_EXEC(snmp_pbuf_stream_write(pbuf_stream, data)); - - return ERR_OK; -} - -/** - * Encodes raw data (octet string, opaque) into a pbuf chained ASN1 msg. - * - * @param pbuf_stream points to a pbuf stream - * @param raw_len raw data length - * @param raw points raw data - * @return ERR_OK if successful, ERR_ARG if we can't (or won't) encode - */ -err_t -snmp_asn1_enc_raw(struct snmp_pbuf_stream* pbuf_stream, const u8_t *raw, u16_t raw_len) -{ - PBUF_OP_EXEC(snmp_pbuf_stream_writebuf(pbuf_stream, raw, raw_len)); - - return ERR_OK; -} - -/** - * Encodes u32_t (counter, gauge, timeticks) into a pbuf chained ASN1 msg. - * - * @param pbuf_stream points to a pbuf stream - * @param octets_needed encoding length (from snmp_asn1_enc_u32t_cnt()) - * @param value is the host order u32_t value to be encoded - * @return ERR_OK if successful, ERR_ARG if we can't (or won't) encode - * - * @see snmp_asn1_enc_u32t_cnt() - */ -err_t -snmp_asn1_enc_u32t(struct snmp_pbuf_stream* pbuf_stream, u16_t octets_needed, u32_t value) -{ - if (octets_needed > 5) { - return ERR_ARG; - } - if (octets_needed == 5) { - /* not enough bits in 'value' add leading 0x00 */ - PBUF_OP_EXEC(snmp_pbuf_stream_write(pbuf_stream, 0x00)); - octets_needed--; - } - - while (octets_needed > 1) { - octets_needed--; - PBUF_OP_EXEC(snmp_pbuf_stream_write(pbuf_stream, (u8_t)(value >> (octets_needed << 3)))); - } - - /* (only) one least significant octet */ - PBUF_OP_EXEC(snmp_pbuf_stream_write(pbuf_stream, (u8_t)value)); - - return ERR_OK; -} - -/** - * Encodes u64_t (counter64) into a pbuf chained ASN1 msg. - * - * @param pbuf_stream points to a pbuf stream - * @param octets_needed encoding length (from snmp_asn1_enc_u32t_cnt()) - * @param value is the host order u32_t value to be encoded - * @return ERR_OK if successful, ERR_ARG if we can't (or won't) encode - * - * @see snmp_asn1_enc_u64t_cnt() - */ -err_t -snmp_asn1_enc_u64t(struct snmp_pbuf_stream* pbuf_stream, u16_t octets_needed, const u32_t* value) -{ - if (octets_needed > 9) { - return ERR_ARG; - } - if (octets_needed == 9) { - /* not enough bits in 'value' add leading 0x00 */ - PBUF_OP_EXEC(snmp_pbuf_stream_write(pbuf_stream, 0x00)); - octets_needed--; - } - - while (octets_needed > 4) { - octets_needed--; - PBUF_OP_EXEC(snmp_pbuf_stream_write(pbuf_stream, (u8_t)(*value >> ((octets_needed-4) << 3)))); - } - - /* skip to low u32 */ - value++; - - while (octets_needed > 1) { - octets_needed--; - PBUF_OP_EXEC(snmp_pbuf_stream_write(pbuf_stream, (u8_t)(*value >> (octets_needed << 3)))); - } - - /* always write at least one octet (also in case of value == 0) */ - PBUF_OP_EXEC(snmp_pbuf_stream_write(pbuf_stream, (u8_t)(*value))); - - return ERR_OK; -} - -/** - * Encodes s32_t integer into a pbuf chained ASN1 msg. - * - * @param pbuf_stream points to a pbuf stream - * @param octets_needed encoding length (from snmp_asn1_enc_s32t_cnt()) - * @param value is the host order s32_t value to be encoded - * @return ERR_OK if successful, ERR_ARG if we can't (or won't) encode - * - * @see snmp_asn1_enc_s32t_cnt() - */ -err_t -snmp_asn1_enc_s32t(struct snmp_pbuf_stream* pbuf_stream, u16_t octets_needed, s32_t value) -{ - while (octets_needed > 1) { - octets_needed--; - - PBUF_OP_EXEC(snmp_pbuf_stream_write(pbuf_stream, (u8_t)(value >> (octets_needed << 3)))); - } - - /* (only) one least significant octet */ - PBUF_OP_EXEC(snmp_pbuf_stream_write(pbuf_stream, (u8_t)value)); - - return ERR_OK; -} - -/** - * Encodes object identifier into a pbuf chained ASN1 msg. - * - * @param pbuf_stream points to a pbuf stream - * @param oid points to object identifier array - * @param oid_len object identifier array length - * @return ERR_OK if successful, ERR_ARG if we can't (or won't) encode - */ -err_t -snmp_asn1_enc_oid(struct snmp_pbuf_stream* pbuf_stream, const u32_t *oid, u16_t oid_len) -{ - if (oid_len > 1) { - /* write compressed first two sub id's */ - u32_t compressed_byte = ((oid[0] * 40) + oid[1]); - PBUF_OP_EXEC(snmp_pbuf_stream_write(pbuf_stream, (u8_t)compressed_byte)); - oid_len -= 2; - oid += 2; - } else { - /* @bug: allow empty varbinds for symmetry (we must decode them for getnext), allow partial compression?? */ - /* ident_len <= 1, at least we need zeroDotZero (0.0) (ident_len == 2) */ - return ERR_ARG; - } - - while (oid_len > 0) { - u32_t sub_id; - u8_t shift, tail; - - oid_len--; - sub_id = *oid; - tail = 0; - shift = 28; - while (shift > 0) { - u8_t code; - - code = (u8_t)(sub_id >> shift); - if ((code != 0) || (tail != 0)) { - tail = 1; - PBUF_OP_EXEC(snmp_pbuf_stream_write(pbuf_stream, code | 0x80)); - } - shift -= 7; - } - PBUF_OP_EXEC(snmp_pbuf_stream_write(pbuf_stream, (u8_t)sub_id & 0x7F)); - - /* proceed to next sub-identifier */ - oid++; - } - return ERR_OK; -} - -/** - * Returns octet count for length. - * - * @param length parameter length - * @param octets_needed points to the return value - */ -void -snmp_asn1_enc_length_cnt(u16_t length, u8_t *octets_needed) -{ - if (length < 0x80U) { - *octets_needed = 1; - } else if (length < 0x100U) { - *octets_needed = 2; - } else { - *octets_needed = 3; - } -} - -/** - * Returns octet count for an u32_t. - * - * @param value value to be encoded - * @param octets_needed points to the return value - * - * @note ASN coded integers are _always_ signed. E.g. +0xFFFF is coded - * as 0x00,0xFF,0xFF. Note the leading sign octet. A positive value - * of 0xFFFFFFFF is preceded with 0x00 and the length is 5 octets!! - */ -void -snmp_asn1_enc_u32t_cnt(u32_t value, u16_t *octets_needed) -{ - if (value < 0x80UL) { - *octets_needed = 1; - } else if (value < 0x8000UL) { - *octets_needed = 2; - } else if (value < 0x800000UL) { - *octets_needed = 3; - } else if (value < 0x80000000UL) { - *octets_needed = 4; - } else { - *octets_needed = 5; - } -} - -/** - * Returns octet count for an u64_t. - * - * @param value value to be encoded - * @param octets_needed points to the return value - * - * @note ASN coded integers are _always_ signed. E.g. +0xFFFF is coded - * as 0x00,0xFF,0xFF. Note the leading sign octet. A positive value - * of 0xFFFFFFFF is preceded with 0x00 and the length is 5 octets!! - */ -void -snmp_asn1_enc_u64t_cnt(const u32_t *value, u16_t *octets_needed) -{ - /* check if high u32 is 0 */ - if (*value == 0x00) { - /* only low u32 is important */ - value++; - snmp_asn1_enc_u32t_cnt(*value, octets_needed); - } else { - /* low u32 does not matter for length determination */ - snmp_asn1_enc_u32t_cnt(*value, octets_needed); - *octets_needed = *octets_needed + 4; /* add the 4 bytes of low u32 */ - } -} - -/** - * Returns octet count for an s32_t. - * - * @param value value to be encoded - * @param octets_needed points to the return value - * - * @note ASN coded integers are _always_ signed. - */ -void -snmp_asn1_enc_s32t_cnt(s32_t value, u16_t *octets_needed) -{ - if (value < 0) { - value = ~value; - } - if (value < 0x80L) { - *octets_needed = 1; - } else if (value < 0x8000L) { - *octets_needed = 2; - } else if (value < 0x800000L) { - *octets_needed = 3; - } else { - *octets_needed = 4; - } -} - -/** - * Returns octet count for an object identifier. - * - * @param oid points to object identifier array - * @param oid_len object identifier array length - * @param octets_needed points to the return value - */ -void -snmp_asn1_enc_oid_cnt(const u32_t *oid, u16_t oid_len, u16_t *octets_needed) -{ - u32_t sub_id; - - *octets_needed = 0; - if (oid_len > 1) { - /* compressed prefix in one octet */ - (*octets_needed)++; - oid_len -= 2; - oid += 2; - } - while (oid_len > 0) { - oid_len--; - sub_id = *oid; - - sub_id >>= 7; - (*octets_needed)++; - while (sub_id > 0) { - sub_id >>= 7; - (*octets_needed)++; - } - oid++; - } -} - -/** - * Decodes a TLV from a pbuf stream. - * - * @param pbuf_stream points to a pbuf stream - * @param tlv returns decoded TLV - * @return ERR_OK if successful, ERR_VAL if we can't decode - */ -err_t -snmp_asn1_dec_tlv(struct snmp_pbuf_stream* pbuf_stream, struct snmp_asn1_tlv* tlv) -{ - u8_t data; - - /* decode type first */ - PBUF_OP_EXEC(snmp_pbuf_stream_read(pbuf_stream, &data)); - tlv->type = data; - - if ((tlv->type & SNMP_ASN1_DATATYPE_MASK) == SNMP_ASN1_DATATYPE_EXTENDED) { - /* extended format is not used by SNMP so we do not accept those values */ - return ERR_VAL; - } - tlv->type_len = 1; - - /* now, decode length */ - PBUF_OP_EXEC(snmp_pbuf_stream_read(pbuf_stream, &data)); - - if (data < 0x80) { /* short form */ - tlv->length_len = 1; - tlv->value_len = data; - } else if (data > 0x80) { /* long form */ - u8_t length_bytes = data - 0x80; - tlv->length_len = length_bytes + 1; /* this byte + defined number of length bytes following */ - tlv->value_len = 0; - - while (length_bytes > 0) { - /* we only support up to u16.maxvalue-1 (2 bytes) but have to accept leading zero bytes */ - if (tlv->value_len > 0xFF) { - return ERR_VAL; - } - PBUF_OP_EXEC(snmp_pbuf_stream_read(pbuf_stream, &data)); - tlv->value_len <<= 8; - tlv->value_len |= data; - - /* take care for special value used for indefinite length */ - if (tlv->value_len == 0xFFFF) { - return ERR_VAL; - } - - length_bytes--; - } - } else { /* data == 0x80 indefinite length form */ - /* (not allowed for SNMP; RFC 1157, 3.2.2) */ - return ERR_VAL; - } - - return ERR_OK; -} - -/** - * Decodes positive integer (counter, gauge, timeticks) into u32_t. - * - * @param pbuf_stream points to a pbuf stream - * @param len length of the coded integer field - * @param value return host order integer - * @return ERR_OK if successful, ERR_ARG if we can't (or won't) decode - * - * @note ASN coded integers are _always_ signed. E.g. +0xFFFF is coded - * as 0x00,0xFF,0xFF. Note the leading sign octet. A positive value - * of 0xFFFFFFFF is preceded with 0x00 and the length is 5 octets!! - */ -err_t -snmp_asn1_dec_u32t(struct snmp_pbuf_stream *pbuf_stream, u16_t len, u32_t *value) -{ - u8_t data; - - if ((len > 0) && (len <= 5)) { - PBUF_OP_EXEC(snmp_pbuf_stream_read(pbuf_stream, &data)); - - /* expecting sign bit to be zero, only unsigned please! */ - if (((len == 5) && (data == 0x00)) || ((len < 5) && ((data & 0x80) == 0))) { - *value = data; - len--; - - while (len > 0) { - PBUF_OP_EXEC(snmp_pbuf_stream_read(pbuf_stream, &data)); - len--; - - *value <<= 8; - *value |= data; - } - - return ERR_OK; - } - } - - return ERR_VAL; -} - -/** - * Decodes large positive integer (counter64) into 2x u32_t. - * - * @param pbuf_stream points to a pbuf stream - * @param len length of the coded integer field - * @param value return host order integer - * @return ERR_OK if successful, ERR_ARG if we can't (or won't) decode - * - * @note ASN coded integers are _always_ signed. E.g. +0xFFFF is coded - * as 0x00,0xFF,0xFF. Note the leading sign octet. A positive value - * of 0xFFFFFFFF is preceded with 0x00 and the length is 5 octets!! - */ -err_t -snmp_asn1_dec_u64t(struct snmp_pbuf_stream *pbuf_stream, u16_t len, u32_t *value) -{ - u8_t data; - - if (len <= 4) { - /* high u32 is 0 */ - *value = 0; - /* directly skip to low u32 */ - value++; - } - - if ((len > 0) && (len <= 9)) { - PBUF_OP_EXEC(snmp_pbuf_stream_read(pbuf_stream, &data)); - - /* expecting sign bit to be zero, only unsigned please! */ - if (((len == 9) && (data == 0x00)) || ((len < 9) && ((data & 0x80) == 0))) { - *value = data; - len--; - - while (len > 0) { - PBUF_OP_EXEC(snmp_pbuf_stream_read(pbuf_stream, &data)); - - if (len == 4) { - /* skip to low u32 */ - value++; - *value = 0; - } else { - *value <<= 8; - } - - *value |= data; - len--; - } - - return ERR_OK; - } - } - - return ERR_VAL; -} - -/** - * Decodes integer into s32_t. - * - * @param pbuf_stream points to a pbuf stream - * @param len length of the coded integer field - * @param value return host order integer - * @return ERR_OK if successful, ERR_ARG if we can't (or won't) decode - * - * @note ASN coded integers are _always_ signed! - */ -err_t -snmp_asn1_dec_s32t(struct snmp_pbuf_stream *pbuf_stream, u16_t len, s32_t *value) -{ -#if BYTE_ORDER == LITTLE_ENDIAN - u8_t *lsb_ptr = (u8_t*)value; -#endif -#if BYTE_ORDER == BIG_ENDIAN - u8_t *lsb_ptr = (u8_t*)value + sizeof(s32_t) - 1; -#endif - u8_t sign; - u8_t data; - - if ((len > 0) && (len < 5)) { - PBUF_OP_EXEC(snmp_pbuf_stream_read(pbuf_stream, &data)); - len--; - - if (data & 0x80) { - /* negative, start from -1 */ - *value = -1; - sign = 1; - *lsb_ptr &= data; - } else { - /* positive, start from 0 */ - *value = 0; - sign = 0; - *lsb_ptr |= data; - } - - /* OR/AND octets with value */ - while (len > 0) { - PBUF_OP_EXEC(snmp_pbuf_stream_read(pbuf_stream, &data)); - len--; - -#if BYTE_ORDER == LITTLE_ENDIAN - *value <<= 8; -#endif -#if BYTE_ORDER == BIG_ENDIAN - *value >>= 8; -#endif - - if (sign) { - *lsb_ptr |= 255; - *lsb_ptr &= data; - } else { - *lsb_ptr |= data; - } - } - - return ERR_OK; - } - - return ERR_VAL; -} - -/** - * Decodes object identifier from incoming message into array of u32_t. - * - * @param pbuf_stream points to a pbuf stream - * @param len length of the coded object identifier - * @param oid return decoded object identifier - * @param oid_len return decoded object identifier length - * @param oid_max_len size of oid buffer - * @return ERR_OK if successful, ERR_ARG if we can't (or won't) decode - */ -err_t -snmp_asn1_dec_oid(struct snmp_pbuf_stream *pbuf_stream, u16_t len, u32_t* oid, u8_t* oid_len, u8_t oid_max_len) -{ - u32_t *oid_ptr; - u8_t data; - - *oid_len = 0; - oid_ptr = oid; - if (len > 0) { - if (oid_max_len < 2) { - return ERR_MEM; - } - - PBUF_OP_EXEC(snmp_pbuf_stream_read(pbuf_stream, &data)); - len--; - - /* first compressed octet */ - if (data == 0x2B) { - /* (most) common case 1.3 (iso.org) */ - *oid_ptr = 1; - oid_ptr++; - *oid_ptr = 3; - oid_ptr++; - } else if (data < 40) { - *oid_ptr = 0; - oid_ptr++; - *oid_ptr = data; - oid_ptr++; - } else if (data < 80) { - *oid_ptr = 1; - oid_ptr++; - *oid_ptr = data - 40; - oid_ptr++; - } else { - *oid_ptr = 2; - oid_ptr++; - *oid_ptr = data - 80; - oid_ptr++; - } - *oid_len = 2; - } else { - /* accepting zero length identifiers e.g. for getnext operation. uncommon but valid */ - return ERR_OK; - } - - while ((len > 0) && (*oid_len < oid_max_len)) { - PBUF_OP_EXEC(snmp_pbuf_stream_read(pbuf_stream, &data)); - len--; - - if ((data & 0x80) == 0x00) { - /* sub-identifier uses single octet */ - *oid_ptr = data; - } else { - /* sub-identifier uses multiple octets */ - u32_t sub_id = (data & ~0x80); - while ((len > 0) && ((data & 0x80) != 0)) { - PBUF_OP_EXEC(snmp_pbuf_stream_read(pbuf_stream, &data)); - len--; - - sub_id = (sub_id << 7) + (data & ~0x80); - } - - if ((data & 0x80) != 0) { - /* "more bytes following" bit still set at end of len */ - return ERR_VAL; - } - *oid_ptr = sub_id; - } - oid_ptr++; - (*oid_len)++; - } - - if (len > 0) { - /* OID to long to fit in our buffer */ - return ERR_MEM; - } - - return ERR_OK; -} - -/** - * Decodes (copies) raw data (ip-addresses, octet strings, opaque encoding) - * from incoming message into array. - * - * @param pbuf_stream points to a pbuf stream - * @param len length of the coded raw data (zero is valid, e.g. empty string!) - * @param buf return raw bytes - * @param buf_len returns length of the raw return value - * @param buf_max_len buffer size - * @return ERR_OK if successful, ERR_ARG if we can't (or won't) decode - */ -err_t -snmp_asn1_dec_raw(struct snmp_pbuf_stream *pbuf_stream, u16_t len, u8_t *buf, u16_t* buf_len, u16_t buf_max_len) -{ - if (len > buf_max_len) { - /* not enough dst space */ - return ERR_MEM; - } - *buf_len = len; - - while (len > 0) { - PBUF_OP_EXEC(snmp_pbuf_stream_read(pbuf_stream, buf)); - buf++; - len--; - } - - return ERR_OK; -} - -#endif /* LWIP_SNMP */ diff --git a/third_party/lwip/repo/lwip/src/apps/snmp/snmp_asn1.h b/third_party/lwip/repo/lwip/src/apps/snmp/snmp_asn1.h deleted file mode 100644 index ec50d8c9e3cb67..00000000000000 --- a/third_party/lwip/repo/lwip/src/apps/snmp/snmp_asn1.h +++ /dev/null @@ -1,108 +0,0 @@ -/** - * @file - * Abstract Syntax Notation One (ISO 8824, 8825) codec. - */ - -/* - * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands. - * Copyright (c) 2016 Elias Oenal. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * Author: Christiaan Simons - * Martin Hentschel - * Elias Oenal - */ - -#ifndef LWIP_HDR_APPS_SNMP_ASN1_H -#define LWIP_HDR_APPS_SNMP_ASN1_H - -#include "lwip/apps/snmp_opts.h" - -#if LWIP_SNMP - -#include "lwip/err.h" -#include "lwip/apps/snmp_core.h" -#include "snmp_pbuf_stream.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define SNMP_ASN1_TLV_INDEFINITE_LENGTH 0x80 - -#define SNMP_ASN1_CLASS_MASK 0xC0 -#define SNMP_ASN1_CONTENTTYPE_MASK 0x20 -#define SNMP_ASN1_DATATYPE_MASK 0x1F -#define SNMP_ASN1_DATATYPE_EXTENDED 0x1F /* DataType indicating that datatype is encoded in following bytes */ - -/* context specific (SNMP) tags (from SNMP spec. RFC1157) */ -#define SNMP_ASN1_CONTEXT_PDU_GET_REQ 0 -#define SNMP_ASN1_CONTEXT_PDU_GET_NEXT_REQ 1 -#define SNMP_ASN1_CONTEXT_PDU_GET_RESP 2 -#define SNMP_ASN1_CONTEXT_PDU_SET_REQ 3 -#define SNMP_ASN1_CONTEXT_PDU_TRAP 4 -#define SNMP_ASN1_CONTEXT_PDU_GET_BULK_REQ 5 - -#define SNMP_ASN1_CONTEXT_VARBIND_NO_SUCH_OBJECT 0 -#define SNMP_ASN1_CONTEXT_VARBIND_END_OF_MIB_VIEW 2 - -struct snmp_asn1_tlv -{ - u8_t type; /* only U8 because extended types are not specified by SNMP */ - u8_t type_len; /* encoded length of 'type' field (normally 1) */ - u8_t length_len; /* indicates how many bytes are required to encode the 'value_len' field */ - u16_t value_len; /* encoded length of the value */ -}; -#define SNMP_ASN1_TLV_HDR_LENGTH(tlv) ((tlv).type_len + (tlv).length_len) -#define SNMP_ASN1_TLV_LENGTH(tlv) ((tlv).type_len + (tlv).length_len + (tlv).value_len) -#define SNMP_ASN1_SET_TLV_PARAMS(tlv, type_, length_len_, value_len_) do { (tlv).type = (type_); (tlv).type_len = 0; (tlv).length_len = (length_len_); (tlv).value_len = (value_len_); } while (0); - -err_t snmp_asn1_dec_tlv(struct snmp_pbuf_stream* pbuf_stream, struct snmp_asn1_tlv* tlv); -err_t snmp_asn1_dec_u32t(struct snmp_pbuf_stream *pbuf_stream, u16_t len, u32_t *value); -err_t snmp_asn1_dec_u64t(struct snmp_pbuf_stream *pbuf_stream, u16_t len, u32_t *value); -err_t snmp_asn1_dec_s32t(struct snmp_pbuf_stream *pbuf_stream, u16_t len, s32_t *value); -err_t snmp_asn1_dec_oid(struct snmp_pbuf_stream *pbuf_stream, u16_t len, u32_t* oid, u8_t* oid_len, u8_t oid_max_len); -err_t snmp_asn1_dec_raw(struct snmp_pbuf_stream *pbuf_stream, u16_t len, u8_t *buf, u16_t* buf_len, u16_t buf_max_len); - -err_t snmp_ans1_enc_tlv(struct snmp_pbuf_stream* pbuf_stream, struct snmp_asn1_tlv* tlv); - -void snmp_asn1_enc_length_cnt(u16_t length, u8_t *octets_needed); -void snmp_asn1_enc_u32t_cnt(u32_t value, u16_t *octets_needed); -void snmp_asn1_enc_u64t_cnt(const u32_t *value, u16_t *octets_needed); -void snmp_asn1_enc_s32t_cnt(s32_t value, u16_t *octets_needed); -void snmp_asn1_enc_oid_cnt(const u32_t *oid, u16_t oid_len, u16_t *octets_needed); -err_t snmp_asn1_enc_oid(struct snmp_pbuf_stream* pbuf_stream, const u32_t *oid, u16_t oid_len); -err_t snmp_asn1_enc_s32t(struct snmp_pbuf_stream* pbuf_stream, u16_t octets_needed, s32_t value); -err_t snmp_asn1_enc_u32t(struct snmp_pbuf_stream* pbuf_stream, u16_t octets_needed, u32_t value); -err_t snmp_asn1_enc_u64t(struct snmp_pbuf_stream* pbuf_stream, u16_t octets_needed, const u32_t* value); -err_t snmp_asn1_enc_raw(struct snmp_pbuf_stream* pbuf_stream, const u8_t *raw, u16_t raw_len); - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_SNMP */ - -#endif /* LWIP_HDR_APPS_SNMP_ASN1_H */ diff --git a/third_party/lwip/repo/lwip/src/apps/snmp/snmp_core.c b/third_party/lwip/repo/lwip/src/apps/snmp/snmp_core.c deleted file mode 100644 index c0418336171cc4..00000000000000 --- a/third_party/lwip/repo/lwip/src/apps/snmp/snmp_core.c +++ /dev/null @@ -1,1349 +0,0 @@ -/** - * @file - * MIB tree access/construction functions. - */ - -/* - * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * Author: Christiaan Simons - * Martin Hentschel -*/ - -/** - * @defgroup snmp SNMPv2c agent - * @ingroup apps - * SNMPv2c compatible agent\n - * There is also a MIB compiler and a MIB viewer in lwIP contrib repository - * (lwip-contrib/apps/LwipMibCompiler).\n - * The agent implements the most important MIB2 MIBs including IPv6 support - * (interfaces, UDP, TCP, SNMP, ICMP, SYSTEM). IP MIB is an older version - * whithout IPv6 statistics (TODO).\n - * Rewritten by Martin Hentschel and - * Dirk Ziegelmeier \n - * Work on SNMPv3 has started, but is not finished.\n - * - * 0 Agent Capabilities - * ==================== - * - * Features: - * --------- - * - SNMPv2c support. - * - Low RAM usage - no memory pools, stack only. - * - MIB2 implementation is separated from SNMP stack. - * - Support for multiple MIBs (snmp_set_mibs() call) - e.g. for private MIB. - * - Simple and generic API for MIB implementation. - * - Comfortable node types and helper functions for scalar arrays and tables. - * - Counter64, bit and truthvalue datatype support. - * - Callbacks for SNMP writes e.g. to implement persistency. - * - Runs on two APIs: RAW and netconn. - * - Async API is gone - the stack now supports netconn API instead, - * so blocking operations can be done in MIB calls. - * SNMP runs in a worker thread when netconn API is used. - * - Simplified thread sync support for MIBs - useful when MIBs - * need to access variables shared with other threads where no locking is - * possible. Used in MIB2 to access lwIP stats from lwIP thread. - * - * MIB compiler (code generator): - * ------------------------------ - * - Provided in lwIP contrib repository. - * - Written in C#. MIB viewer used Windows Forms. - * - Developed on Windows with Visual Studio 2010. - * - Can be compiled and used on all platforms with http://www.monodevelop.com/. - * - Based on a heavily modified version of of SharpSnmpLib (a4bd05c6afb4) - * (https://sharpsnmplib.codeplex.com/SourceControl/network/forks/Nemo157/MIBParserUpdate). - * - MIB parser, C file generation framework and LWIP code generation are cleanly - * separated, which means the code may be useful as a base for code generation - * of other SNMP agents. - * - * Notes: - * ------ - * - Stack and MIB compiler were used to implement a Profinet device. - * Compiled/implemented MIBs: LLDP-MIB, LLDP-EXT-DOT3-MIB, LLDP-EXT-PNO-MIB. - * - * SNMPv1 per RFC1157 and SNMPv2c per RFC 3416 - * ------------------------------------------- - * Note the S in SNMP stands for "Simple". Note that "Simple" is - * relative. SNMP is simple compared to the complex ISO network - * management protocols CMIP (Common Management Information Protocol) - * and CMOT (CMip Over Tcp). - * - * MIB II - * ------ - * The standard lwIP stack management information base. - * This is a required MIB, so this is always enabled. - * The groups EGP, CMOT and transmission are disabled by default. - * - * Most mib-2 objects are not writable except: - * sysName, sysLocation, sysContact, snmpEnableAuthenTraps. - * Writing to or changing the ARP and IP address and route - * tables is not possible. - * - * Note lwIP has a very limited notion of IP routing. It currently - * doen't have a route table and doesn't have a notion of the U,G,H flags. - * Instead lwIP uses the interface list with only one default interface - * acting as a single gateway interface (G) for the default route. - * - * The agent returns a "virtual table" with the default route 0.0.0.0 - * for the default interface and network routes (no H) for each - * network interface in the netif_list. - * All routes are considered to be up (U). - * - * Loading additional MIBs - * ----------------------- - * MIBs can only be added in compile-time, not in run-time. - * - * - * 1 Building the Agent - * ==================== - * First of all you'll need to add the following define - * to your local lwipopts.h: - * \#define LWIP_SNMP 1 - * - * and add the source files your makefile. - * - * Note you'll might need to adapt you network driver to update - * the mib2 variables for your interface. - * - * 2 Running the Agent - * =================== - * The following function calls must be made in your program to - * actually get the SNMP agent running. - * - * Before starting the agent you should supply pointers - * for sysContact, sysLocation, and snmpEnableAuthenTraps. - * You can do this by calling - * - * - snmp_mib2_set_syscontact() - * - snmp_mib2_set_syslocation() - * - snmp_set_auth_traps_enabled() - * - * You can register a callback which is called on successful write access: - * snmp_set_write_callback(). - * - * Additionally you may want to set - * - * - snmp_mib2_set_sysdescr() - * - snmp_set_device_enterprise_oid() - * - snmp_mib2_set_sysname() - * - * Also before starting the agent you need to setup - * one or more trap destinations using these calls: - * - * - snmp_trap_dst_enable() - * - snmp_trap_dst_ip_set() - * - * If you need more than MIB2, set the MIBs you want to use - * by snmp_set_mibs(). - * - * Finally, enable the agent by calling snmp_init() - * - * @defgroup snmp_core Core - * @ingroup snmp - * - * @defgroup snmp_traps Traps - * @ingroup snmp - */ - -#include "lwip/apps/snmp_opts.h" - -#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/apps/snmp.h" -#include "lwip/apps/snmp_core.h" -#include "snmp_core_priv.h" -#include "lwip/netif.h" -#include - - -#if (LWIP_SNMP && (SNMP_TRAP_DESTINATIONS<=0)) - #error "If you want to use SNMP, you have to define SNMP_TRAP_DESTINATIONS>=1 in your lwipopts.h" -#endif -#if (!LWIP_UDP && LWIP_SNMP) - #error "If you want to use SNMP, you have to define LWIP_UDP=1 in your lwipopts.h" -#endif - -struct snmp_statistics snmp_stats; -static const struct snmp_obj_id snmp_device_enterprise_oid_default = {SNMP_DEVICE_ENTERPRISE_OID_LEN, SNMP_DEVICE_ENTERPRISE_OID}; -static const struct snmp_obj_id* snmp_device_enterprise_oid = &snmp_device_enterprise_oid_default; - -const u32_t snmp_zero_dot_zero_values[] = { 0, 0 }; -const struct snmp_obj_id_const_ref snmp_zero_dot_zero = { LWIP_ARRAYSIZE(snmp_zero_dot_zero_values), snmp_zero_dot_zero_values }; - - -#if SNMP_LWIP_MIB2 -#include "lwip/apps/snmp_mib2.h" -static const struct snmp_mib* const default_mibs[] = { &mib2 }; -static u8_t snmp_num_mibs = 1; -#else -static const struct snmp_mib* const default_mibs[] = { NULL }; -static u8_t snmp_num_mibs = 0; -#endif - -/* List of known mibs */ -static struct snmp_mib const * const *snmp_mibs = default_mibs; - -/** - * @ingroup snmp_core - * Sets the MIBs to use. - * Example: call snmp_set_mibs() as follows: - * static const struct snmp_mib *my_snmp_mibs[] = { - * &mib2, - * &private_mib - * }; - * snmp_set_mibs(my_snmp_mibs, LWIP_ARRAYSIZE(my_snmp_mibs)); - */ -void -snmp_set_mibs(const struct snmp_mib **mibs, u8_t num_mibs) -{ - LWIP_ASSERT("mibs pointer must be != NULL", (mibs != NULL)); - LWIP_ASSERT("num_mibs pointer must be != 0", (num_mibs != 0)); - snmp_mibs = mibs; - snmp_num_mibs = num_mibs; -} - -/** - * @ingroup snmp_core - * 'device enterprise oid' is used for 'device OID' field in trap PDU's (for identification of generating device) - * as well as for value returned by MIB-2 'sysObjectID' field (if internal MIB2 implementation is used). - * The 'device enterprise oid' shall point to an OID located under 'private-enterprises' branch (1.3.6.1.4.1.XXX). If a vendor - * wants to provide a custom object there, he has to get its own enterprise oid from IANA (http://www.iana.org). It - * is not allowed to use LWIP enterprise ID! - * In order to identify a specific device it is recommended to create a dedicated OID for each device type under its own - * enterprise oid. - * e.g. - * device a > 1.3.6.1.4.1.XXX(ent-oid).1(devices).1(device a) - * device b > 1.3.6.1.4.1.XXX(ent-oid).1(devices).2(device b) - * for more details see description of 'sysObjectID' field in RFC1213-MIB - */ -void snmp_set_device_enterprise_oid(const struct snmp_obj_id* device_enterprise_oid) -{ - if (device_enterprise_oid == NULL) { - snmp_device_enterprise_oid = &snmp_device_enterprise_oid_default; - } else { - snmp_device_enterprise_oid = device_enterprise_oid; - } -} - -/** - * @ingroup snmp_core - * Get 'device enterprise oid' - */ -const struct snmp_obj_id* snmp_get_device_enterprise_oid(void) -{ - return snmp_device_enterprise_oid; -} - -#if LWIP_IPV4 -/** - * Conversion from InetAddressIPv4 oid to lwIP ip4_addr - * @param oid points to u32_t ident[4] input - * @param ip points to output struct - */ -u8_t -snmp_oid_to_ip4(const u32_t *oid, ip4_addr_t *ip) -{ - if ((oid[0] > 0xFF) || - (oid[1] > 0xFF) || - (oid[2] > 0xFF) || - (oid[3] > 0xFF)) { - ip4_addr_copy(*ip, *IP4_ADDR_ANY4); - return 0; - } - - IP4_ADDR(ip, oid[0], oid[1], oid[2], oid[3]); - return 1; -} - -/** - * Convert ip4_addr to InetAddressIPv4 (no InetAddressType) - * @param ip points to input struct - * @param oid points to u32_t ident[4] output - */ -void -snmp_ip4_to_oid(const ip4_addr_t *ip, u32_t *oid) -{ - oid[0] = ip4_addr1(ip); - oid[1] = ip4_addr2(ip); - oid[2] = ip4_addr3(ip); - oid[3] = ip4_addr4(ip); -} -#endif /* LWIP_IPV4 */ - -#if LWIP_IPV6 -/** - * Conversion from InetAddressIPv6 oid to lwIP ip6_addr - * @param oid points to u32_t oid[16] input - * @param ip points to output struct - */ -u8_t -snmp_oid_to_ip6(const u32_t *oid, ip6_addr_t *ip) -{ - if ((oid[0] > 0xFF) || - (oid[1] > 0xFF) || - (oid[2] > 0xFF) || - (oid[3] > 0xFF) || - (oid[4] > 0xFF) || - (oid[5] > 0xFF) || - (oid[6] > 0xFF) || - (oid[7] > 0xFF) || - (oid[8] > 0xFF) || - (oid[9] > 0xFF) || - (oid[10] > 0xFF) || - (oid[11] > 0xFF) || - (oid[12] > 0xFF) || - (oid[13] > 0xFF) || - (oid[14] > 0xFF) || - (oid[15] > 0xFF)) { - ip6_addr_set_any(ip); - return 0; - } - - ip->addr[0] = (oid[0] << 24) | (oid[1] << 16) | (oid[2] << 8) | (oid[3] << 0); - ip->addr[1] = (oid[4] << 24) | (oid[5] << 16) | (oid[6] << 8) | (oid[7] << 0); - ip->addr[2] = (oid[8] << 24) | (oid[9] << 16) | (oid[10] << 8) | (oid[11] << 0); - ip->addr[3] = (oid[12] << 24) | (oid[13] << 16) | (oid[14] << 8) | (oid[15] << 0); - return 1; -} - -/** - * Convert ip6_addr to InetAddressIPv6 (no InetAddressType) - * @param ip points to input struct - * @param oid points to u32_t ident[16] output - */ -void -snmp_ip6_to_oid(const ip6_addr_t *ip, u32_t *oid) -{ - oid[0] = (ip->addr[0] & 0xFF000000) >> 24; - oid[1] = (ip->addr[0] & 0x00FF0000) >> 16; - oid[2] = (ip->addr[0] & 0x0000FF00) >> 8; - oid[3] = (ip->addr[0] & 0x000000FF) >> 0; - oid[4] = (ip->addr[1] & 0xFF000000) >> 24; - oid[5] = (ip->addr[1] & 0x00FF0000) >> 16; - oid[6] = (ip->addr[1] & 0x0000FF00) >> 8; - oid[7] = (ip->addr[1] & 0x000000FF) >> 0; - oid[8] = (ip->addr[2] & 0xFF000000) >> 24; - oid[9] = (ip->addr[2] & 0x00FF0000) >> 16; - oid[10] = (ip->addr[2] & 0x0000FF00) >> 8; - oid[11] = (ip->addr[2] & 0x000000FF) >> 0; - oid[12] = (ip->addr[3] & 0xFF000000) >> 24; - oid[13] = (ip->addr[3] & 0x00FF0000) >> 16; - oid[14] = (ip->addr[3] & 0x0000FF00) >> 8; - oid[15] = (ip->addr[3] & 0x000000FF) >> 0; -} -#endif /* LWIP_IPV6 */ - -#if LWIP_IPV4 || LWIP_IPV6 -/** - * Convert to InetAddressType+InetAddress+InetPortNumber - * @param ip IP address - * @param port Port - * @param oid OID - * @return OID length - */ -u8_t -snmp_ip_port_to_oid(const ip_addr_t *ip, u16_t port, u32_t *oid) -{ - u8_t idx; - - idx = snmp_ip_to_oid(ip, oid); - oid[idx] = port; - idx++; - - return idx; -} - -/** - * Convert to InetAddressType+InetAddress - * @param ip IP address - * @param oid OID - * @return OID length - */ -u8_t -snmp_ip_to_oid(const ip_addr_t *ip, u32_t *oid) -{ - if (IP_IS_ANY_TYPE_VAL(*ip)) { - oid[0] = 0; /* any */ - oid[1] = 0; /* no IP OIDs follow */ - return 2; - } else if (IP_IS_V6(ip)) { -#if LWIP_IPV6 - oid[0] = 2; /* ipv6 */ - oid[1] = 16; /* 16 InetAddressIPv6 OIDs follow */ - snmp_ip6_to_oid(ip_2_ip6(ip), &oid[2]); - return 18; -#else /* LWIP_IPV6 */ - return 0; -#endif /* LWIP_IPV6 */ - } else { -#if LWIP_IPV4 - oid[0] = 1; /* ipv4 */ - oid[1] = 4; /* 4 InetAddressIPv4 OIDs follow */ - snmp_ip4_to_oid(ip_2_ip4(ip), &oid[2]); - return 6; -#else /* LWIP_IPV4 */ - return 0; -#endif /* LWIP_IPV4 */ - } -} - -/** - * Convert from InetAddressType+InetAddress to ip_addr_t - * @param oid OID - * @param oid_len OID length - * @param ip IP address - * @return Parsed OID length - */ -u8_t -snmp_oid_to_ip(const u32_t *oid, u8_t oid_len, ip_addr_t *ip) -{ - /* InetAddressType */ - if (oid_len < 1) { - return 0; - } - - if (oid[0] == 0) { /* any */ - /* 1x InetAddressType, 1x OID len */ - if (oid_len < 2) { - return 0; - } - if (oid[1] != 0) { - return 0; - } - - memset(ip, 0, sizeof(*ip)); - IP_SET_TYPE(ip, IPADDR_TYPE_ANY); - - return 2; - } else if (oid[0] == 1) { /* ipv4 */ -#if LWIP_IPV4 - /* 1x InetAddressType, 1x OID len, 4x InetAddressIPv4 */ - if (oid_len < 6) { - return 0; - } - - /* 4x ipv4 OID */ - if (oid[1] != 4) { - return 0; - } - - IP_SET_TYPE(ip, IPADDR_TYPE_V4); - if (!snmp_oid_to_ip4(&oid[2], ip_2_ip4(ip))) { - return 0; - } - - return 6; -#else /* LWIP_IPV4 */ - return 0; -#endif /* LWIP_IPV4 */ - } else if (oid[0] == 2) { /* ipv6 */ -#if LWIP_IPV6 - /* 1x InetAddressType, 1x OID len, 16x InetAddressIPv6 */ - if (oid_len < 18) { - return 0; - } - - /* 16x ipv6 OID */ - if (oid[1] != 16) { - return 0; - } - - IP_SET_TYPE(ip, IPADDR_TYPE_V6); - if (!snmp_oid_to_ip6(&oid[2], ip_2_ip6(ip))) { - return 0; - } - - return 18; -#else /* LWIP_IPV6 */ - return 0; -#endif /* LWIP_IPV6 */ - } else { /* unsupported InetAddressType */ - return 0; - } -} - -/** - * Convert from InetAddressType+InetAddress+InetPortNumber to ip_addr_t and u16_t - * @param oid OID - * @param oid_len OID length - * @param ip IP address - * @param port Port - * @return Parsed OID length - */ -u8_t -snmp_oid_to_ip_port(const u32_t *oid, u8_t oid_len, ip_addr_t *ip, u16_t *port) -{ - u8_t idx = 0; - - /* InetAddressType + InetAddress */ - idx += snmp_oid_to_ip(&oid[idx], oid_len-idx, ip); - if (idx == 0) { - return 0; - } - - /* InetPortNumber */ - if (oid_len < (idx+1)) { - return 0; - } - if (oid[idx] > 0xffff) { - return 0; - } - *port = (u16_t)oid[idx]; - idx++; - - return idx; -} - -#endif /* LWIP_IPV4 || LWIP_IPV6 */ - -/** - * Assign an OID to struct snmp_obj_id - * @param target Assignment target - * @param oid OID - * @param oid_len OID length - */ -void -snmp_oid_assign(struct snmp_obj_id* target, const u32_t *oid, u8_t oid_len) -{ - LWIP_ASSERT("oid_len <= LWIP_SNMP_OBJ_ID_LEN", oid_len <= SNMP_MAX_OBJ_ID_LEN); - - target->len = oid_len; - - if (oid_len > 0) { - MEMCPY(target->id, oid, oid_len * sizeof(u32_t)); - } -} - -/** - * Prefix an OID to OID in struct snmp_obj_id - * @param target Assignment target to prefix - * @param oid OID - * @param oid_len OID length - */ -void -snmp_oid_prefix(struct snmp_obj_id* target, const u32_t *oid, u8_t oid_len) -{ - LWIP_ASSERT("target->len + oid_len <= LWIP_SNMP_OBJ_ID_LEN", (target->len + oid_len) <= SNMP_MAX_OBJ_ID_LEN); - - if (oid_len > 0) { - /* move existing OID to make room at the beginning for OID to insert */ - int i; - for (i = target->len-1; i>=0; i--) { - target->id[i + oid_len] = target->id[i]; - } - - /* paste oid at the beginning */ - MEMCPY(target->id, oid, oid_len * sizeof(u32_t)); - } -} - -/** - * Combine two OIDs into struct snmp_obj_id - * @param target Assignmet target - * @param oid1 OID 1 - * @param oid1_len OID 1 length - * @param oid2 OID 2 - * @param oid2_len OID 2 length - */ -void -snmp_oid_combine(struct snmp_obj_id* target, const u32_t *oid1, u8_t oid1_len, const u32_t *oid2, u8_t oid2_len) -{ - snmp_oid_assign(target, oid1, oid1_len); - snmp_oid_append(target, oid2, oid2_len); -} - -/** - * Append OIDs to struct snmp_obj_id - * @param target Assignment target to append to - * @param oid OID - * @param oid_len OID length - */ -void -snmp_oid_append(struct snmp_obj_id* target, const u32_t *oid, u8_t oid_len) -{ - LWIP_ASSERT("offset + oid_len <= LWIP_SNMP_OBJ_ID_LEN", (target->len + oid_len) <= SNMP_MAX_OBJ_ID_LEN); - - if (oid_len > 0) { - MEMCPY(&target->id[target->len], oid, oid_len * sizeof(u32_t)); - target->len += oid_len; - } -} - -/** - * Compare two OIDs - * @param oid1 OID 1 - * @param oid1_len OID 1 length - * @param oid2 OID 2 - * @param oid2_len OID 2 length - * @return -1: OID1<OID2 1: OID1 >OID2 0: equal - */ -s8_t -snmp_oid_compare(const u32_t *oid1, u8_t oid1_len, const u32_t *oid2, u8_t oid2_len) -{ - u8_t level = 0; - LWIP_ASSERT("'oid1' param must not be NULL or 'oid1_len' param be 0!", (oid1 != NULL) || (oid1_len == 0)); - LWIP_ASSERT("'oid2' param must not be NULL or 'oid2_len' param be 0!", (oid2 != NULL) || (oid2_len == 0)); - - while ((level < oid1_len) && (level < oid2_len)) { - if (*oid1 < *oid2) { - return -1; - } - if (*oid1 > *oid2) { - return 1; - } - - level++; - oid1++; - oid2++; - } - - /* common part of both OID's is equal, compare length */ - if (oid1_len < oid2_len) { - return -1; - } - if (oid1_len > oid2_len) { - return 1; - } - - /* they are equal */ - return 0; -} - - -/** - * Check of two OIDs are equal - * @param oid1 OID 1 - * @param oid1_len OID 1 length - * @param oid2 OID 2 - * @param oid2_len OID 2 length - * @return 1: equal 0: non-equal - */ -u8_t -snmp_oid_equal(const u32_t *oid1, u8_t oid1_len, const u32_t *oid2, u8_t oid2_len) -{ - return (snmp_oid_compare(oid1, oid1_len, oid2, oid2_len) == 0)? 1 : 0; -} - -/** - * Convert netif to interface index - * @param netif netif - * @return index - */ -u8_t -netif_to_num(const struct netif *netif) -{ - u8_t result = 0; - struct netif *netif_iterator = netif_list; - - while (netif_iterator != NULL) { - result++; - - if (netif_iterator == netif) { - return result; - } - - netif_iterator = netif_iterator->next; - } - - LWIP_ASSERT("netif not found in netif_list", 0); - return 0; -} - -static const struct snmp_mib* -snmp_get_mib_from_oid(const u32_t *oid, u8_t oid_len) -{ - const u32_t* list_oid; - const u32_t* searched_oid; - u8_t i, l; - - u8_t max_match_len = 0; - const struct snmp_mib* matched_mib = NULL; - - LWIP_ASSERT("'oid' param must not be NULL!", (oid != NULL)); - - if (oid_len == 0) { - return NULL; - } - - for (i = 0; i < snmp_num_mibs; i++) { - LWIP_ASSERT("MIB array not initialized correctly", (snmp_mibs[i] != NULL)); - LWIP_ASSERT("MIB array not initialized correctly - base OID is NULL", (snmp_mibs[i]->base_oid != NULL)); - - if (oid_len >= snmp_mibs[i]->base_oid_len) { - l = snmp_mibs[i]->base_oid_len; - list_oid = snmp_mibs[i]->base_oid; - searched_oid = oid; - - while (l > 0) { - if (*list_oid != *searched_oid) { - break; - } - - l--; - list_oid++; - searched_oid++; - } - - if ((l == 0) && (snmp_mibs[i]->base_oid_len > max_match_len)) { - max_match_len = snmp_mibs[i]->base_oid_len; - matched_mib = snmp_mibs[i]; - } - } - } - - return matched_mib; -} - -static const struct snmp_mib* -snmp_get_next_mib(const u32_t *oid, u8_t oid_len) -{ - u8_t i; - const struct snmp_mib* next_mib = NULL; - - LWIP_ASSERT("'oid' param must not be NULL!", (oid != NULL)); - - if (oid_len == 0) { - return NULL; - } - - for (i = 0; i < snmp_num_mibs; i++) { - if (snmp_mibs[i]->base_oid != NULL) { - /* check if mib is located behind starting point */ - if (snmp_oid_compare(snmp_mibs[i]->base_oid, snmp_mibs[i]->base_oid_len, oid, oid_len) > 0) { - if ((next_mib == NULL) || - (snmp_oid_compare(snmp_mibs[i]->base_oid, snmp_mibs[i]->base_oid_len, - next_mib->base_oid, next_mib->base_oid_len) < 0)) { - next_mib = snmp_mibs[i]; - } - } - } - } - - return next_mib; -} - -static const struct snmp_mib* -snmp_get_mib_between(const u32_t *oid1, u8_t oid1_len, const u32_t *oid2, u8_t oid2_len) -{ - const struct snmp_mib* next_mib = snmp_get_next_mib(oid1, oid1_len); - - LWIP_ASSERT("'oid2' param must not be NULL!", (oid2 != NULL)); - LWIP_ASSERT("'oid2_len' param must be greater than 0!", (oid2_len > 0)); - - if (next_mib != NULL) { - if (snmp_oid_compare(next_mib->base_oid, next_mib->base_oid_len, oid2, oid2_len) < 0) { - return next_mib; - } - } - - return NULL; -} - -u8_t -snmp_get_node_instance_from_oid(const u32_t *oid, u8_t oid_len, struct snmp_node_instance* node_instance) -{ - u8_t result = SNMP_ERR_NOSUCHOBJECT; - const struct snmp_mib *mib; - const struct snmp_node *mn = NULL; - - mib = snmp_get_mib_from_oid(oid, oid_len); - if (mib != NULL) { - u8_t oid_instance_len; - - mn = snmp_mib_tree_resolve_exact(mib, oid, oid_len, &oid_instance_len); - if ((mn != NULL) && (mn->node_type != SNMP_NODE_TREE)) { - /* get instance */ - const struct snmp_leaf_node* leaf_node = (const struct snmp_leaf_node*)(const void*)mn; - - node_instance->node = mn; - snmp_oid_assign(&node_instance->instance_oid, oid + (oid_len - oid_instance_len), oid_instance_len); - - result = leaf_node->get_instance( - oid, - oid_len - oid_instance_len, - node_instance); - -#ifdef LWIP_DEBUG - if (result == SNMP_ERR_NOERROR) { - if (((node_instance->access & SNMP_NODE_INSTANCE_ACCESS_READ) != 0) && (node_instance->get_value == NULL)) { - LWIP_DEBUGF(SNMP_DEBUG, ("SNMP inconsistent access: node is readable but no get_value function is specified\n")); - } - if (((node_instance->access & SNMP_NODE_INSTANCE_ACCESS_WRITE) != 0) && (node_instance->set_value == NULL)) { - LWIP_DEBUGF(SNMP_DEBUG, ("SNMP inconsistent access: node is writable but no set_value and/or set_test function is specified\n")); - } - } -#endif - } - } - - return result; -} - -u8_t -snmp_get_next_node_instance_from_oid(const u32_t *oid, u8_t oid_len, snmp_validate_node_instance_method validate_node_instance_method, void* validate_node_instance_arg, struct snmp_obj_id* node_oid, struct snmp_node_instance* node_instance) -{ - const struct snmp_mib *mib; - const struct snmp_node *mn = NULL; - const u32_t* start_oid = NULL; - u8_t start_oid_len = 0; - - /* resolve target MIB from passed OID */ - mib = snmp_get_mib_from_oid(oid, oid_len); - if (mib == NULL) { - /* passed OID does not reference any known MIB, start at the next closest MIB */ - mib = snmp_get_next_mib(oid, oid_len); - - if (mib != NULL) { - start_oid = mib->base_oid; - start_oid_len = mib->base_oid_len; - } - } else { - start_oid = oid; - start_oid_len = oid_len; - } - - /* resolve target node from MIB, skip to next MIB if no suitable node is found in current MIB */ - while ((mib != NULL) && (mn == NULL)) { - u8_t oid_instance_len; - - /* check if OID directly references a node inside current MIB, in this case we have to ask this node for the next instance */ - mn = snmp_mib_tree_resolve_exact(mib, start_oid, start_oid_len, &oid_instance_len); - if (mn != NULL) { - snmp_oid_assign(node_oid, start_oid, start_oid_len - oid_instance_len); /* set oid to node */ - snmp_oid_assign(&node_instance->instance_oid, start_oid + (start_oid_len - oid_instance_len), oid_instance_len); /* set (relative) instance oid */ - } else { - /* OID does not reference a node, search for the next closest node inside MIB; set instance_oid.len to zero because we want the first instance of this node */ - mn = snmp_mib_tree_resolve_next(mib, start_oid, start_oid_len, node_oid); - node_instance->instance_oid.len = 0; - } - - /* validate the node; if the node has no further instance or the returned instance is invalid, search for the next in MIB and validate again */ - node_instance->node = mn; - while (mn != NULL) { - u8_t result; - - /* clear fields which may have values from previous loops */ - node_instance->asn1_type = 0; - node_instance->access = SNMP_NODE_INSTANCE_NOT_ACCESSIBLE; - node_instance->get_value = NULL; - node_instance->set_test = NULL; - node_instance->set_value = NULL; - node_instance->release_instance = NULL; - node_instance->reference.ptr = NULL; - node_instance->reference_len = 0; - - result = ((const struct snmp_leaf_node*)(const void*)mn)->get_next_instance( - node_oid->id, - node_oid->len, - node_instance); - - if (result == SNMP_ERR_NOERROR) { -#ifdef LWIP_DEBUG - if (((node_instance->access & SNMP_NODE_INSTANCE_ACCESS_READ) != 0) && (node_instance->get_value == NULL)) { - LWIP_DEBUGF(SNMP_DEBUG, ("SNMP inconsistent access: node is readable but no get_value function is specified\n")); - } - if (((node_instance->access & SNMP_NODE_INSTANCE_ACCESS_WRITE) != 0) && (node_instance->set_value == NULL)) { - LWIP_DEBUGF(SNMP_DEBUG, ("SNMP inconsistent access: node is writable but no set_value function is specified\n")); - } -#endif - - /* validate node because the node may be not accessible for example (but let the caller decide what is valid */ - if ((validate_node_instance_method == NULL) || - (validate_node_instance_method(node_instance, validate_node_instance_arg) == SNMP_ERR_NOERROR)) { - /* node_oid "returns" the full result OID (including the instance part) */ - snmp_oid_append(node_oid, node_instance->instance_oid.id, node_instance->instance_oid.len); - break; - } - - if (node_instance->release_instance != NULL) { - node_instance->release_instance(node_instance); - } - /* - the instance itself is not valid, ask for next instance from same node. - we don't have to change any variables because node_instance->instance_oid is used as input (starting point) - as well as output (resulting next OID), so we have to simply call get_next_instance method again - */ - } else { - if (node_instance->release_instance != NULL) { - node_instance->release_instance(node_instance); - } - - /* the node has no further instance, skip to next node */ - mn = snmp_mib_tree_resolve_next(mib, node_oid->id, node_oid->len, &node_instance->instance_oid); /* misuse node_instance->instance_oid as tmp buffer */ - if (mn != NULL) { - /* prepare for next loop */ - snmp_oid_assign(node_oid, node_instance->instance_oid.id, node_instance->instance_oid.len); - node_instance->instance_oid.len = 0; - node_instance->node = mn; - } - } - } - - if (mn != NULL) { - /* - we found a suitable next node, - now we have to check if a inner MIB is located between the searched OID and the resulting OID. - this is possible because MIB's may be located anywhere in the global tree, that means also in - the subtree of another MIB (e.g. if searched OID is .2 and resulting OID is .4, then another - MIB having .3 as root node may exist) - */ - const struct snmp_mib *intermediate_mib; - intermediate_mib = snmp_get_mib_between(start_oid, start_oid_len, node_oid->id, node_oid->len); - - if (intermediate_mib != NULL) { - /* search for first node inside intermediate mib in next loop */ - if (node_instance->release_instance != NULL) { - node_instance->release_instance(node_instance); - } - - mn = NULL; - mib = intermediate_mib; - start_oid = mib->base_oid; - start_oid_len = mib->base_oid_len; - } - /* else { we found out target node } */ - } else { - /* - there is no further (suitable) node inside this MIB, search for the next MIB with following priority - 1. search for inner MIB's (whose root is located inside tree of current MIB) - 2. search for surrouding MIB's (where the current MIB is the inner MIB) and continue there if any - 3. take the next closest MIB (not being related to the current MIB) - */ - const struct snmp_mib *next_mib; - next_mib = snmp_get_next_mib(start_oid, start_oid_len); /* returns MIB's related to point 1 and 3 */ - - /* is the found MIB an inner MIB? (point 1) */ - if ((next_mib != NULL) && (next_mib->base_oid_len > mib->base_oid_len) && - (snmp_oid_compare(next_mib->base_oid, mib->base_oid_len, mib->base_oid, mib->base_oid_len) == 0)) { - /* yes it is -> continue at inner MIB */ - mib = next_mib; - start_oid = mib->base_oid; - start_oid_len = mib->base_oid_len; - } else { - /* check if there is a surrounding mib where to continue (point 2) (only possible if OID length > 1) */ - if (mib->base_oid_len > 1) { - mib = snmp_get_mib_from_oid(mib->base_oid, mib->base_oid_len - 1); - - if (mib == NULL) { - /* no surrounding mib, use next mib encountered above (point 3) */ - mib = next_mib; - - if (mib != NULL) { - start_oid = mib->base_oid; - start_oid_len = mib->base_oid_len; - } - } - /* else { start_oid stays the same because we want to continue from current offset in surrounding mib (point 2) } */ - } - } - } - } - - if (mib == NULL) { - /* loop is only left when mib == null (error) or mib_node != NULL (success) */ - return SNMP_ERR_ENDOFMIBVIEW; - } - - return SNMP_ERR_NOERROR; -} - -/** - * Searches tree for the supplied object identifier. - * - */ -const struct snmp_node * -snmp_mib_tree_resolve_exact(const struct snmp_mib *mib, const u32_t *oid, u8_t oid_len, u8_t* oid_instance_len) -{ - const struct snmp_node* const* node = &mib->root_node; - u8_t oid_offset = mib->base_oid_len; - - while ((oid_offset < oid_len) && ((*node)->node_type == SNMP_NODE_TREE)) { - /* search for matching sub node */ - u32_t subnode_oid = *(oid + oid_offset); - - u32_t i = (*(const struct snmp_tree_node* const*)node)->subnode_count; - node = (*(const struct snmp_tree_node* const*)node)->subnodes; - while ((i > 0) && ((*node)->oid != subnode_oid)) { - node++; - i--; - } - - if (i == 0) { - /* no matching subnode found */ - return NULL; - } - - oid_offset++; - } - - if ((*node)->node_type != SNMP_NODE_TREE) { - /* we found a leaf node */ - *oid_instance_len = oid_len - oid_offset; - return (*node); - } - - return NULL; -} - -const struct snmp_node* -snmp_mib_tree_resolve_next(const struct snmp_mib *mib, const u32_t *oid, u8_t oid_len, struct snmp_obj_id* oidret) -{ - u8_t oid_offset = mib->base_oid_len; - const struct snmp_node* const* node; - const struct snmp_tree_node* node_stack[SNMP_MAX_OBJ_ID_LEN]; - s32_t nsi = 0; /* NodeStackIndex */ - u32_t subnode_oid; - - if (mib->root_node->node_type != SNMP_NODE_TREE) { - /* a next operation on a mib with only a leaf node will always return NULL because there is no other node */ - return NULL; - } - - /* first build node stack related to passed oid (as far as possible), then go backwards to determine the next node */ - node_stack[nsi] = (const struct snmp_tree_node*)(const void*)mib->root_node; - while (oid_offset < oid_len) { - /* search for matching sub node */ - u32_t i = node_stack[nsi]->subnode_count; - node = node_stack[nsi]->subnodes; - - subnode_oid = *(oid + oid_offset); - - while ((i > 0) && ((*node)->oid != subnode_oid)) { - node++; - i--; - } - - if ((i == 0) || ((*node)->node_type != SNMP_NODE_TREE)) { - /* no (matching) tree-subnode found */ - break; - } - nsi++; - node_stack[nsi] = (const struct snmp_tree_node*)(const void*)(*node); - - oid_offset++; - } - - - if (oid_offset >= oid_len) { - /* passed oid references a tree node -> return first useable sub node of it */ - subnode_oid = 0; - } else { - subnode_oid = *(oid + oid_offset) + 1; - } - - while (nsi >= 0) { - const struct snmp_node* subnode = NULL; - - /* find next node on current level */ - s32_t i = node_stack[nsi]->subnode_count; - node = node_stack[nsi]->subnodes; - while (i > 0) { - if ((*node)->oid == subnode_oid) { - subnode = *node; - break; - } else if (((*node)->oid > subnode_oid) && ((subnode == NULL) || ((*node)->oid < subnode->oid))) { - subnode = *node; - } - - node++; - i--; - } - - if (subnode == NULL) { - /* no further node found on this level, go one level up and start searching with index of current node*/ - subnode_oid = node_stack[nsi]->node.oid + 1; - nsi--; - } else { - if (subnode->node_type == SNMP_NODE_TREE) { - /* next is a tree node, go into it and start searching */ - nsi++; - node_stack[nsi] = (const struct snmp_tree_node*)(const void*)subnode; - subnode_oid = 0; - } else { - /* we found a leaf node -> fill oidret and return it */ - snmp_oid_assign(oidret, mib->base_oid, mib->base_oid_len); - i = 1; - while (i <= nsi) { - oidret->id[oidret->len] = node_stack[i]->node.oid; - oidret->len++; - i++; - } - - oidret->id[oidret->len] = subnode->oid; - oidret->len++; - - return subnode; - } - } - } - - return NULL; -} - -/** initialize struct next_oid_state using this function before passing it to next_oid_check */ -void -snmp_next_oid_init(struct snmp_next_oid_state *state, - const u32_t *start_oid, u8_t start_oid_len, - u32_t *next_oid_buf, u8_t next_oid_max_len) -{ - state->start_oid = start_oid; - state->start_oid_len = start_oid_len; - state->next_oid = next_oid_buf; - state->next_oid_len = 0; - state->next_oid_max_len = next_oid_max_len; - state->status = SNMP_NEXT_OID_STATUS_NO_MATCH; -} - -/** checks if the passed incomplete OID may be a possible candidate for snmp_next_oid_check(); -this methid is intended if the complete OID is not yet known but it is very expensive to build it up, -so it is possible to test the starting part before building up the complete oid and pass it to snmp_next_oid_check()*/ -u8_t -snmp_next_oid_precheck(struct snmp_next_oid_state *state, const u32_t *oid, const u8_t oid_len) -{ - if (state->status != SNMP_NEXT_OID_STATUS_BUF_TO_SMALL) { - u8_t start_oid_len = (oid_len < state->start_oid_len) ? oid_len : state->start_oid_len; - - /* check passed OID is located behind start offset */ - if (snmp_oid_compare(oid, oid_len, state->start_oid, start_oid_len) >= 0) { - /* check if new oid is located closer to start oid than current closest oid */ - if ((state->status == SNMP_NEXT_OID_STATUS_NO_MATCH) || - (snmp_oid_compare(oid, oid_len, state->next_oid, state->next_oid_len) < 0)) { - return 1; - } - } - } - - return 0; -} - -/** checks the passed OID if it is a candidate to be the next one (get_next); returns !=0 if passed oid is currently closest, otherwise 0 */ -u8_t -snmp_next_oid_check(struct snmp_next_oid_state *state, const u32_t *oid, const u8_t oid_len, void* reference) -{ - /* do not overwrite a fail result */ - if (state->status != SNMP_NEXT_OID_STATUS_BUF_TO_SMALL) { - /* check passed OID is located behind start offset */ - if (snmp_oid_compare(oid, oid_len, state->start_oid, state->start_oid_len) > 0) { - /* check if new oid is located closer to start oid than current closest oid */ - if ((state->status == SNMP_NEXT_OID_STATUS_NO_MATCH) || - (snmp_oid_compare(oid, oid_len, state->next_oid, state->next_oid_len) < 0)) { - if (oid_len <= state->next_oid_max_len) { - MEMCPY(state->next_oid, oid, oid_len * sizeof(u32_t)); - state->next_oid_len = oid_len; - state->status = SNMP_NEXT_OID_STATUS_SUCCESS; - state->reference = reference; - return 1; - } else { - state->status = SNMP_NEXT_OID_STATUS_BUF_TO_SMALL; - } - } - } - } - - return 0; -} - -u8_t -snmp_oid_in_range(const u32_t *oid_in, u8_t oid_len, const struct snmp_oid_range *oid_ranges, u8_t oid_ranges_len) -{ - u8_t i; - - if (oid_len != oid_ranges_len) { - return 0; - } - - for (i = 0; i < oid_ranges_len; i++) { - if ((oid_in[i] < oid_ranges[i].min) || (oid_in[i] > oid_ranges[i].max)) { - return 0; - } - } - - return 1; -} - -snmp_err_t -snmp_set_test_ok(struct snmp_node_instance* instance, u16_t value_len, void* value) -{ - LWIP_UNUSED_ARG(instance); - LWIP_UNUSED_ARG(value_len); - LWIP_UNUSED_ARG(value); - - return SNMP_ERR_NOERROR; -} - -/** - * Decodes BITS pseudotype value from ASN.1 OctetString. - * - * @note Because BITS pseudo type is encoded as OCTET STRING, it cannot directly - * be encoded/decoded by the agent. Instead call this function as required from - * get/test/set methods. - * - * @param buf points to a buffer holding the ASN1 octet string - * @param buf_len length of octet string - * @param bit_value decoded Bit value with Bit0 == LSB - * @return ERR_OK if successful, ERR_ARG if bit value contains more than 32 bit - */ -err_t -snmp_decode_bits(const u8_t *buf, u32_t buf_len, u32_t *bit_value) -{ - u8_t b; - u8_t bits_processed = 0; - *bit_value = 0; - - while (buf_len > 0) { - /* any bit set in this byte? */ - if (*buf != 0x00) { - if (bits_processed >= 32) { - /* accept more than 4 bytes, but only when no bits are set */ - return ERR_VAL; - } - - b = *buf; - do { - if (b & 0x80) { - *bit_value |= (1 << bits_processed); - } - bits_processed++; - b <<= 1; - } - while ((bits_processed & 0x07) != 0); /* &0x07 -> % 8 */ - } else { - bits_processed += 8; - } - - buf_len--; - buf++; - } - - return ERR_OK; -} - -err_t -snmp_decode_truthvalue(const s32_t *asn1_value, u8_t *bool_value) -{ - /* defined by RFC1443: - TruthValue ::= TEXTUAL-CONVENTION - STATUS current - DESCRIPTION - "Represents a boolean value." - SYNTAX INTEGER { true(1), false(2) } - */ - - if ((asn1_value == NULL) || (bool_value == NULL)) { - return ERR_ARG; - } - - if (*asn1_value == 1) { - *bool_value = 1; - } else if (*asn1_value == 2) { - *bool_value = 0; - } else { - return ERR_VAL; - } - - return ERR_OK; -} - -/** - * Encodes BITS pseudotype value into ASN.1 OctetString. - * - * @note Because BITS pseudo type is encoded as OCTET STRING, it cannot directly - * be encoded/decoded by the agent. Instead call this function as required from - * get/test/set methods. - * - * @param buf points to a buffer where the resulting ASN1 octet string is stored to - * @param buf_len max length of the bufffer - * @param bit_value Bit value to encode with Bit0 == LSB - * @param bit_count Number of possible bits for the bit value (according to rfc we have to send all bits independant from their truth value) - * @return number of bytes used from buffer to store the resulting OctetString - */ -u8_t -snmp_encode_bits(u8_t *buf, u32_t buf_len, u32_t bit_value, u8_t bit_count) -{ - u8_t len = 0; - u8_t min_bytes = (bit_count + 7) >> 3; /* >>3 -> / 8 */ - - while ((buf_len > 0) && (bit_value != 0x00)) { - s8_t i = 7; - *buf = 0x00; - while (i >= 0) { - if (bit_value & 0x01) { - *buf |= 0x01; - } - - if (i > 0) { - *buf <<= 1; - } - - bit_value >>= 1; - i--; - } - - buf++; - buf_len--; - len++; - } - - if (len < min_bytes) { - buf += len; - buf_len -= len; - - while ((len < min_bytes) && (buf_len > 0)) { - *buf = 0x00; - buf++; - buf_len--; - len++; - } - } - - return len; -} - -u8_t -snmp_encode_truthvalue(s32_t *asn1_value, u32_t bool_value) -{ - /* defined by RFC1443: - TruthValue ::= TEXTUAL-CONVENTION - STATUS current - DESCRIPTION - "Represents a boolean value." - SYNTAX INTEGER { true(1), false(2) } - */ - - if (asn1_value == NULL) { - return 0; - } - - if (bool_value) { - *asn1_value = 1; /* defined by RFC1443 */ - } else { - *asn1_value = 2; /* defined by RFC1443 */ - } - - return sizeof(s32_t); -} - -#endif /* LWIP_SNMP */ diff --git a/third_party/lwip/repo/lwip/src/apps/snmp/snmp_core_priv.h b/third_party/lwip/repo/lwip/src/apps/snmp/snmp_core_priv.h deleted file mode 100644 index 5552177d747c75..00000000000000 --- a/third_party/lwip/repo/lwip/src/apps/snmp/snmp_core_priv.h +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Martin Hentschel - * - */ - -#ifndef LWIP_HDR_APPS_SNMP_CORE_PRIV_H -#define LWIP_HDR_APPS_SNMP_CORE_PRIV_H - -#include "lwip/apps/snmp_opts.h" - -#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/apps/snmp_core.h" -#include "snmp_asn1.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* (outdated) SNMPv1 error codes - * shall not be used by MIBS anymore, nevertheless required from core for properly answering a v1 request - */ -#define SNMP_ERR_NOSUCHNAME 2 -#define SNMP_ERR_BADVALUE 3 -#define SNMP_ERR_READONLY 4 -/* error codes which are internal and shall not be used by MIBS - * shall not be used by MIBS anymore, nevertheless required from core for properly answering a v1 request - */ -#define SNMP_ERR_TOOBIG 1 -#define SNMP_ERR_AUTHORIZATIONERROR 16 -#define SNMP_ERR_NOSUCHOBJECT SNMP_VARBIND_EXCEPTION_OFFSET + SNMP_ASN1_CONTEXT_VARBIND_NO_SUCH_OBJECT -#define SNMP_ERR_ENDOFMIBVIEW SNMP_VARBIND_EXCEPTION_OFFSET + SNMP_ASN1_CONTEXT_VARBIND_END_OF_MIB_VIEW - - -const struct snmp_node* snmp_mib_tree_resolve_exact(const struct snmp_mib *mib, const u32_t *oid, u8_t oid_len, u8_t* oid_instance_len); -const struct snmp_node* snmp_mib_tree_resolve_next(const struct snmp_mib *mib, const u32_t *oid, u8_t oid_len, struct snmp_obj_id* oidret); - -typedef u8_t (*snmp_validate_node_instance_method)(struct snmp_node_instance*, void*); - -u8_t snmp_get_node_instance_from_oid(const u32_t *oid, u8_t oid_len, struct snmp_node_instance* node_instance); -u8_t snmp_get_next_node_instance_from_oid(const u32_t *oid, u8_t oid_len, snmp_validate_node_instance_method validate_node_instance_method, void* validate_node_instance_arg, struct snmp_obj_id* node_oid, struct snmp_node_instance* node_instance); - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_SNMP */ - -#endif /* LWIP_HDR_APPS_SNMP_CORE_PRIV_H */ diff --git a/third_party/lwip/repo/lwip/src/apps/snmp/snmp_mib2.c b/third_party/lwip/repo/lwip/src/apps/snmp/snmp_mib2.c deleted file mode 100644 index 9d8c43c108ad8b..00000000000000 --- a/third_party/lwip/repo/lwip/src/apps/snmp/snmp_mib2.c +++ /dev/null @@ -1,116 +0,0 @@ -/** - * @file - * Management Information Base II (RFC1213) objects and functions. - */ - -/* - * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * Author: Dirk Ziegelmeier - * Christiaan Simons - */ - -/** - * @defgroup snmp_mib2 MIB2 - * @ingroup snmp - */ - -#include "lwip/apps/snmp_opts.h" - -#if LWIP_SNMP && SNMP_LWIP_MIB2 /* don't build if not configured for use in lwipopts.h */ - -#if !LWIP_STATS -#error LWIP_SNMP MIB2 needs LWIP_STATS (for MIB2) -#endif -#if !MIB2_STATS -#error LWIP_SNMP MIB2 needs MIB2_STATS (for MIB2) -#endif - -#include "lwip/snmp.h" -#include "lwip/apps/snmp.h" -#include "lwip/apps/snmp_core.h" -#include "lwip/apps/snmp_mib2.h" -#include "lwip/apps/snmp_scalar.h" - -#if SNMP_USE_NETCONN -#include "lwip/tcpip.h" -#include "lwip/priv/tcpip_priv.h" -void -snmp_mib2_lwip_synchronizer(snmp_threadsync_called_fn fn, void* arg) -{ -#if LWIP_TCPIP_CORE_LOCKING - LOCK_TCPIP_CORE(); - fn(arg); - UNLOCK_TCPIP_CORE(); -#else - tcpip_callback(fn, arg); -#endif -} - -struct snmp_threadsync_instance snmp_mib2_lwip_locks; -#endif - -/* dot3 and EtherLike MIB not planned. (transmission .1.3.6.1.2.1.10) */ -/* historical (some say hysterical). (cmot .1.3.6.1.2.1.9) */ -/* lwIP has no EGP, thus may not implement it. (egp .1.3.6.1.2.1.8) */ - -/* --- mib-2 .1.3.6.1.2.1 ----------------------------------------------------- */ -extern const struct snmp_scalar_array_node snmp_mib2_snmp_root; -extern const struct snmp_tree_node snmp_mib2_udp_root; -extern const struct snmp_tree_node snmp_mib2_tcp_root; -extern const struct snmp_scalar_array_node snmp_mib2_icmp_root; -extern const struct snmp_tree_node snmp_mib2_interface_root; -extern const struct snmp_scalar_array_node snmp_mib2_system_node; -extern const struct snmp_tree_node snmp_mib2_at_root; -extern const struct snmp_tree_node snmp_mib2_ip_root; - -static const struct snmp_node* const mib2_nodes[] = { - &snmp_mib2_system_node.node.node, - &snmp_mib2_interface_root.node, -#if LWIP_ARP && LWIP_IPV4 - &snmp_mib2_at_root.node, -#endif /* LWIP_ARP && LWIP_IPV4 */ -#if LWIP_IPV4 - &snmp_mib2_ip_root.node, -#endif /* LWIP_IPV4 */ -#if LWIP_ICMP - &snmp_mib2_icmp_root.node.node, -#endif /* LWIP_ICMP */ -#if LWIP_TCP - &snmp_mib2_tcp_root.node, -#endif /* LWIP_TCP */ -#if LWIP_UDP - &snmp_mib2_udp_root.node, -#endif /* LWIP_UDP */ - &snmp_mib2_snmp_root.node.node -}; - -static const struct snmp_tree_node mib2_root = SNMP_CREATE_TREE_NODE(1, mib2_nodes); - -static const u32_t mib2_base_oid_arr[] = { 1,3,6,1,2,1 }; -const struct snmp_mib mib2 = SNMP_MIB_CREATE(mib2_base_oid_arr, &mib2_root.node); - -#endif /* LWIP_SNMP && SNMP_LWIP_MIB2 */ diff --git a/third_party/lwip/repo/lwip/src/apps/snmp/snmp_mib2_icmp.c b/third_party/lwip/repo/lwip/src/apps/snmp/snmp_mib2_icmp.c deleted file mode 100644 index 995bd320a5d7db..00000000000000 --- a/third_party/lwip/repo/lwip/src/apps/snmp/snmp_mib2_icmp.c +++ /dev/null @@ -1,182 +0,0 @@ -/** - * @file - * Management Information Base II (RFC1213) ICMP objects and functions. - */ - -/* - * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * Author: Dirk Ziegelmeier - * Christiaan Simons - */ - -#include "lwip/snmp.h" -#include "lwip/apps/snmp.h" -#include "lwip/apps/snmp_core.h" -#include "lwip/apps/snmp_mib2.h" -#include "lwip/apps/snmp_table.h" -#include "lwip/apps/snmp_scalar.h" -#include "lwip/icmp.h" -#include "lwip/stats.h" - -#if LWIP_SNMP && SNMP_LWIP_MIB2 && LWIP_ICMP - -#if SNMP_USE_NETCONN -#define SYNC_NODE_NAME(node_name) node_name ## _synced -#define CREATE_LWIP_SYNC_NODE(oid, node_name) \ - static const struct snmp_threadsync_node node_name ## _synced = SNMP_CREATE_THREAD_SYNC_NODE(oid, &node_name.node, &snmp_mib2_lwip_locks); -#else -#define SYNC_NODE_NAME(node_name) node_name -#define CREATE_LWIP_SYNC_NODE(oid, node_name) -#endif - -/* --- icmp .1.3.6.1.2.1.5 ----------------------------------------------------- */ - -static s16_t -icmp_get_value(const struct snmp_scalar_array_node_def *node, void *value) -{ - u32_t *uint_ptr = (u32_t*)value; - - switch (node->oid) { - case 1: /* icmpInMsgs */ - *uint_ptr = STATS_GET(mib2.icmpinmsgs); - return sizeof(*uint_ptr); - case 2: /* icmpInErrors */ - *uint_ptr = STATS_GET(mib2.icmpinerrors); - return sizeof(*uint_ptr); - case 3: /* icmpInDestUnreachs */ - *uint_ptr = STATS_GET(mib2.icmpindestunreachs); - return sizeof(*uint_ptr); - case 4: /* icmpInTimeExcds */ - *uint_ptr = STATS_GET(mib2.icmpintimeexcds); - return sizeof(*uint_ptr); - case 5: /* icmpInParmProbs */ - *uint_ptr = STATS_GET(mib2.icmpinparmprobs); - return sizeof(*uint_ptr); - case 6: /* icmpInSrcQuenchs */ - *uint_ptr = STATS_GET(mib2.icmpinsrcquenchs); - return sizeof(*uint_ptr); - case 7: /* icmpInRedirects */ - *uint_ptr = STATS_GET(mib2.icmpinredirects); - return sizeof(*uint_ptr); - case 8: /* icmpInEchos */ - *uint_ptr = STATS_GET(mib2.icmpinechos); - return sizeof(*uint_ptr); - case 9: /* icmpInEchoReps */ - *uint_ptr = STATS_GET(mib2.icmpinechoreps); - return sizeof(*uint_ptr); - case 10: /* icmpInTimestamps */ - *uint_ptr = STATS_GET(mib2.icmpintimestamps); - return sizeof(*uint_ptr); - case 11: /* icmpInTimestampReps */ - *uint_ptr = STATS_GET(mib2.icmpintimestampreps); - return sizeof(*uint_ptr); - case 12: /* icmpInAddrMasks */ - *uint_ptr = STATS_GET(mib2.icmpinaddrmasks); - return sizeof(*uint_ptr); - case 13: /* icmpInAddrMaskReps */ - *uint_ptr = STATS_GET(mib2.icmpinaddrmaskreps); - return sizeof(*uint_ptr); - case 14: /* icmpOutMsgs */ - *uint_ptr = STATS_GET(mib2.icmpoutmsgs); - return sizeof(*uint_ptr); - case 15: /* icmpOutErrors */ - *uint_ptr = STATS_GET(mib2.icmpouterrors); - return sizeof(*uint_ptr); - case 16: /* icmpOutDestUnreachs */ - *uint_ptr = STATS_GET(mib2.icmpoutdestunreachs); - return sizeof(*uint_ptr); - case 17: /* icmpOutTimeExcds */ - *uint_ptr = STATS_GET(mib2.icmpouttimeexcds); - return sizeof(*uint_ptr); - case 18: /* icmpOutParmProbs: not supported -> always 0 */ - *uint_ptr = 0; - return sizeof(*uint_ptr); - case 19: /* icmpOutSrcQuenchs: not supported -> always 0 */ - *uint_ptr = 0; - return sizeof(*uint_ptr); - case 20: /* icmpOutRedirects: not supported -> always 0 */ - *uint_ptr = 0; - return sizeof(*uint_ptr); - case 21: /* icmpOutEchos */ - *uint_ptr = STATS_GET(mib2.icmpoutechos); - return sizeof(*uint_ptr); - case 22: /* icmpOutEchoReps */ - *uint_ptr = STATS_GET(mib2.icmpoutechoreps); - return sizeof(*uint_ptr); - case 23: /* icmpOutTimestamps: not supported -> always 0 */ - *uint_ptr = 0; - return sizeof(*uint_ptr); - case 24: /* icmpOutTimestampReps: not supported -> always 0 */ - *uint_ptr = 0; - return sizeof(*uint_ptr); - case 25: /* icmpOutAddrMasks: not supported -> always 0 */ - *uint_ptr = 0; - return sizeof(*uint_ptr); - case 26: /* icmpOutAddrMaskReps: not supported -> always 0 */ - *uint_ptr = 0; - return sizeof(*uint_ptr); - default: - LWIP_DEBUGF(SNMP_MIB_DEBUG,("icmp_get_value(): unknown id: %"S32_F"\n", node->oid)); - break; - } - - return 0; -} - - -static const struct snmp_scalar_array_node_def icmp_nodes[] = { - { 1, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, - { 2, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, - { 3, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, - { 4, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, - { 5, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, - { 6, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, - { 7, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, - { 8, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, - { 9, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, - {10, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, - {11, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, - {12, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, - {13, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, - {14, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, - {15, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, - {16, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, - {17, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, - {18, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, - {19, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, - {20, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, - {21, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, - {22, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, - {23, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, - {24, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, - {25, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, - {26, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY} -}; - -const struct snmp_scalar_array_node snmp_mib2_icmp_root = SNMP_SCALAR_CREATE_ARRAY_NODE(5, icmp_nodes, icmp_get_value, NULL, NULL); - -#endif /* LWIP_SNMP && SNMP_LWIP_MIB2 && LWIP_ICMP */ diff --git a/third_party/lwip/repo/lwip/src/apps/snmp/snmp_mib2_interfaces.c b/third_party/lwip/repo/lwip/src/apps/snmp/snmp_mib2_interfaces.c deleted file mode 100644 index 979b5073ea663b..00000000000000 --- a/third_party/lwip/repo/lwip/src/apps/snmp/snmp_mib2_interfaces.c +++ /dev/null @@ -1,375 +0,0 @@ -/** - * @file - * Management Information Base II (RFC1213) INTERFACES objects and functions. - */ - -/* - * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * Author: Dirk Ziegelmeier - * Christiaan Simons - */ - -#include "lwip/snmp.h" -#include "lwip/apps/snmp.h" -#include "lwip/apps/snmp_core.h" -#include "lwip/apps/snmp_mib2.h" -#include "lwip/apps/snmp_table.h" -#include "lwip/apps/snmp_scalar.h" -#include "lwip/netif.h" -#include "lwip/stats.h" - -#include - -#if LWIP_SNMP && SNMP_LWIP_MIB2 - -#if SNMP_USE_NETCONN -#define SYNC_NODE_NAME(node_name) node_name ## _synced -#define CREATE_LWIP_SYNC_NODE(oid, node_name) \ - static const struct snmp_threadsync_node node_name ## _synced = SNMP_CREATE_THREAD_SYNC_NODE(oid, &node_name.node, &snmp_mib2_lwip_locks); -#else -#define SYNC_NODE_NAME(node_name) node_name -#define CREATE_LWIP_SYNC_NODE(oid, node_name) -#endif - - -/* --- interfaces .1.3.6.1.2.1.2 ----------------------------------------------------- */ - -static s16_t -interfaces_get_value(struct snmp_node_instance* instance, void* value) -{ - if (instance->node->oid == 1) { - s32_t *sint_ptr = (s32_t*)value; - s32_t num_netifs = 0; - - struct netif *netif = netif_list; - while (netif != NULL) { - num_netifs++; - netif = netif->next; - } - - *sint_ptr = num_netifs; - return sizeof(*sint_ptr); - } - - return 0; -} - -/* list of allowed value ranges for incoming OID */ -static const struct snmp_oid_range interfaces_Table_oid_ranges[] = { - { 1, 0xff } /* netif->num is u8_t */ -}; - -static const u8_t iftable_ifOutQLen = 0; - -static const u8_t iftable_ifOperStatus_up = 1; -static const u8_t iftable_ifOperStatus_down = 2; - -static const u8_t iftable_ifAdminStatus_up = 1; -static const u8_t iftable_ifAdminStatus_lowerLayerDown = 7; -static const u8_t iftable_ifAdminStatus_down = 2; - -static snmp_err_t -interfaces_Table_get_cell_instance(const u32_t* column, const u32_t* row_oid, u8_t row_oid_len, struct snmp_node_instance* cell_instance) -{ - u32_t ifIndex; - struct netif *netif; - - LWIP_UNUSED_ARG(column); - - /* check if incoming OID length and if values are in plausible range */ - if (!snmp_oid_in_range(row_oid, row_oid_len, interfaces_Table_oid_ranges, LWIP_ARRAYSIZE(interfaces_Table_oid_ranges))) { - return SNMP_ERR_NOSUCHINSTANCE; - } - - /* get netif index from incoming OID */ - ifIndex = row_oid[0]; - - /* find netif with index */ - netif = netif_list; - while (netif != NULL) { - if (netif_to_num(netif) == ifIndex) { - /* store netif pointer for subsequent operations (get/test/set) */ - cell_instance->reference.ptr = netif; - return SNMP_ERR_NOERROR; - } - netif = netif->next; - } - - /* not found */ - return SNMP_ERR_NOSUCHINSTANCE; -} - -static snmp_err_t -interfaces_Table_get_next_cell_instance(const u32_t* column, struct snmp_obj_id* row_oid, struct snmp_node_instance* cell_instance) -{ - struct netif *netif; - struct snmp_next_oid_state state; - u32_t result_temp[LWIP_ARRAYSIZE(interfaces_Table_oid_ranges)]; - - LWIP_UNUSED_ARG(column); - - /* init struct to search next oid */ - snmp_next_oid_init(&state, row_oid->id, row_oid->len, result_temp, LWIP_ARRAYSIZE(interfaces_Table_oid_ranges)); - - /* iterate over all possible OIDs to find the next one */ - netif = netif_list; - while (netif != NULL) { - u32_t test_oid[LWIP_ARRAYSIZE(interfaces_Table_oid_ranges)]; - test_oid[0] = netif_to_num(netif); - - /* check generated OID: is it a candidate for the next one? */ - snmp_next_oid_check(&state, test_oid, LWIP_ARRAYSIZE(interfaces_Table_oid_ranges), netif); - - netif = netif->next; - } - - /* did we find a next one? */ - if (state.status == SNMP_NEXT_OID_STATUS_SUCCESS) { - snmp_oid_assign(row_oid, state.next_oid, state.next_oid_len); - /* store netif pointer for subsequent operations (get/test/set) */ - cell_instance->reference.ptr = /* (struct netif*) */state.reference; - return SNMP_ERR_NOERROR; - } - - /* not found */ - return SNMP_ERR_NOSUCHINSTANCE; -} - -static s16_t -interfaces_Table_get_value(struct snmp_node_instance* instance, void* value) -{ - struct netif *netif = (struct netif*)instance->reference.ptr; - u32_t* value_u32 = (u32_t*)value; - s32_t* value_s32 = (s32_t*)value; - u16_t value_len; - - switch (SNMP_TABLE_GET_COLUMN_FROM_OID(instance->instance_oid.id)) - { - case 1: /* ifIndex */ - *value_s32 = netif_to_num(netif); - value_len = sizeof(*value_s32); - break; - case 2: /* ifDescr */ - value_len = sizeof(netif->name); - MEMCPY(value, netif->name, value_len); - break; - case 3: /* ifType */ - *value_s32 = netif->link_type; - value_len = sizeof(*value_s32); - break; - case 4: /* ifMtu */ - *value_s32 = netif->mtu; - value_len = sizeof(*value_s32); - break; - case 5: /* ifSpeed */ - *value_u32 = netif->link_speed; - value_len = sizeof(*value_u32); - break; - case 6: /* ifPhysAddress */ - value_len = sizeof(netif->hwaddr); - MEMCPY(value, &netif->hwaddr, value_len); - break; - case 7: /* ifAdminStatus */ - if (netif_is_up(netif)) { - *value_s32 = iftable_ifOperStatus_up; - } else { - *value_s32 = iftable_ifOperStatus_down; - } - value_len = sizeof(*value_s32); - break; - case 8: /* ifOperStatus */ - if (netif_is_up(netif)) { - if (netif_is_link_up(netif)) { - *value_s32 = iftable_ifAdminStatus_up; - } else { - *value_s32 = iftable_ifAdminStatus_lowerLayerDown; - } - } else { - *value_s32 = iftable_ifAdminStatus_down; - } - value_len = sizeof(*value_s32); - break; - case 9: /* ifLastChange */ - *value_u32 = netif->ts; - value_len = sizeof(*value_u32); - break; - case 10: /* ifInOctets */ - *value_u32 = netif->mib2_counters.ifinoctets; - value_len = sizeof(*value_u32); - break; - case 11: /* ifInUcastPkts */ - *value_u32 = netif->mib2_counters.ifinucastpkts; - value_len = sizeof(*value_u32); - break; - case 12: /* ifInNUcastPkts */ - *value_u32 = netif->mib2_counters.ifinnucastpkts; - value_len = sizeof(*value_u32); - break; - case 13: /* ifInDiscards */ - *value_u32 = netif->mib2_counters.ifindiscards; - value_len = sizeof(*value_u32); - break; - case 14: /* ifInErrors */ - *value_u32 = netif->mib2_counters.ifinerrors; - value_len = sizeof(*value_u32); - break; - case 15: /* ifInUnkownProtos */ - *value_u32 = netif->mib2_counters.ifinunknownprotos; - value_len = sizeof(*value_u32); - break; - case 16: /* ifOutOctets */ - *value_u32 = netif->mib2_counters.ifoutoctets; - value_len = sizeof(*value_u32); - break; - case 17: /* ifOutUcastPkts */ - *value_u32 = netif->mib2_counters.ifoutucastpkts; - value_len = sizeof(*value_u32); - break; - case 18: /* ifOutNUcastPkts */ - *value_u32 = netif->mib2_counters.ifoutnucastpkts; - value_len = sizeof(*value_u32); - break; - case 19: /* ifOutDiscarts */ - *value_u32 = netif->mib2_counters.ifoutdiscards; - value_len = sizeof(*value_u32); - break; - case 20: /* ifOutErrors */ - *value_u32 = netif->mib2_counters.ifouterrors; - value_len = sizeof(*value_u32); - break; - case 21: /* ifOutQLen */ - *value_u32 = iftable_ifOutQLen; - value_len = sizeof(*value_u32); - break; - /** @note returning zeroDotZero (0.0) no media specific MIB support */ - case 22: /* ifSpecific */ - value_len = snmp_zero_dot_zero.len * sizeof(u32_t); - MEMCPY(value, snmp_zero_dot_zero.id, value_len); - break; - default: - return 0; - } - - return value_len; -} - -#if !SNMP_SAFE_REQUESTS - -static snmp_err_t -interfaces_Table_set_test(struct snmp_node_instance* instance, u16_t len, void *value) -{ - s32_t *sint_ptr = (s32_t*)value; - - /* stack should never call this method for another column, - because all other columns are set to readonly */ - LWIP_ASSERT("Invalid column", (SNMP_TABLE_GET_COLUMN_FROM_OID(instance->instance_oid.id) == 7)); - LWIP_UNUSED_ARG(len); - - if (*sint_ptr == 1 || *sint_ptr == 2) { - return SNMP_ERR_NOERROR; - } - - return SNMP_ERR_WRONGVALUE; -} - -static snmp_err_t -interfaces_Table_set_value(struct snmp_node_instance* instance, u16_t len, void *value) -{ - struct netif *netif = (struct netif*)instance->reference.ptr; - s32_t *sint_ptr = (s32_t*)value; - - /* stack should never call this method for another column, - because all other columns are set to readonly */ - LWIP_ASSERT("Invalid column", (SNMP_TABLE_GET_COLUMN_FROM_OID(instance->instance_oid.id) == 7)); - LWIP_UNUSED_ARG(len); - - if (*sint_ptr == 1) { - netif_set_up(netif); - } else if (*sint_ptr == 2) { - netif_set_down(netif); - } - - return SNMP_ERR_NOERROR; -} - -#endif /* SNMP_SAFE_REQUESTS */ - -static const struct snmp_scalar_node interfaces_Number = SNMP_SCALAR_CREATE_NODE_READONLY(1, SNMP_ASN1_TYPE_INTEGER, interfaces_get_value); - -static const struct snmp_table_col_def interfaces_Table_columns[] = { - { 1, SNMP_ASN1_TYPE_INTEGER, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifIndex */ - { 2, SNMP_ASN1_TYPE_OCTET_STRING, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifDescr */ - { 3, SNMP_ASN1_TYPE_INTEGER, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifType */ - { 4, SNMP_ASN1_TYPE_INTEGER, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifMtu */ - { 5, SNMP_ASN1_TYPE_GAUGE, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifSpeed */ - { 6, SNMP_ASN1_TYPE_OCTET_STRING, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifPhysAddress */ -#if !SNMP_SAFE_REQUESTS - { 7, SNMP_ASN1_TYPE_INTEGER, SNMP_NODE_INSTANCE_READ_WRITE }, /* ifAdminStatus */ -#else - { 7, SNMP_ASN1_TYPE_INTEGER, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifAdminStatus */ -#endif - { 8, SNMP_ASN1_TYPE_INTEGER, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifOperStatus */ - { 9, SNMP_ASN1_TYPE_TIMETICKS, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifLastChange */ - { 10, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifInOctets */ - { 11, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifInUcastPkts */ - { 12, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifInNUcastPkts */ - { 13, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifInDiscarts */ - { 14, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifInErrors */ - { 15, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifInUnkownProtos */ - { 16, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifOutOctets */ - { 17, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifOutUcastPkts */ - { 18, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifOutNUcastPkts */ - { 19, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifOutDiscarts */ - { 20, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifOutErrors */ - { 21, SNMP_ASN1_TYPE_GAUGE, SNMP_NODE_INSTANCE_READ_ONLY }, /* ifOutQLen */ - { 22, SNMP_ASN1_TYPE_OBJECT_ID, SNMP_NODE_INSTANCE_READ_ONLY } /* ifSpecific */ -}; - -#if !SNMP_SAFE_REQUESTS -static const struct snmp_table_node interfaces_Table = SNMP_TABLE_CREATE( - 2, interfaces_Table_columns, - interfaces_Table_get_cell_instance, interfaces_Table_get_next_cell_instance, - interfaces_Table_get_value, interfaces_Table_set_test, interfaces_Table_set_value); -#else -static const struct snmp_table_node interfaces_Table = SNMP_TABLE_CREATE( - 2, interfaces_Table_columns, - interfaces_Table_get_cell_instance, interfaces_Table_get_next_cell_instance, - interfaces_Table_get_value, NULL, NULL); -#endif - -/* the following nodes access variables in LWIP stack from SNMP worker thread and must therefore be synced to LWIP (TCPIP) thread */ -CREATE_LWIP_SYNC_NODE(1, interfaces_Number) -CREATE_LWIP_SYNC_NODE(2, interfaces_Table) - -static const struct snmp_node* const interface_nodes[] = { - &SYNC_NODE_NAME(interfaces_Number).node.node, - &SYNC_NODE_NAME(interfaces_Table).node.node -}; - -const struct snmp_tree_node snmp_mib2_interface_root = SNMP_CREATE_TREE_NODE(2, interface_nodes); - -#endif /* LWIP_SNMP && SNMP_LWIP_MIB2 */ diff --git a/third_party/lwip/repo/lwip/src/apps/snmp/snmp_mib2_ip.c b/third_party/lwip/repo/lwip/src/apps/snmp/snmp_mib2_ip.c deleted file mode 100644 index 4f05180a396253..00000000000000 --- a/third_party/lwip/repo/lwip/src/apps/snmp/snmp_mib2_ip.c +++ /dev/null @@ -1,743 +0,0 @@ -/** - * @file - * Management Information Base II (RFC1213) IP objects and functions. - */ - -/* - * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * Author: Dirk Ziegelmeier - * Christiaan Simons - */ - -#include "lwip/snmp.h" -#include "lwip/apps/snmp.h" -#include "lwip/apps/snmp_core.h" -#include "lwip/apps/snmp_mib2.h" -#include "lwip/apps/snmp_table.h" -#include "lwip/apps/snmp_scalar.h" -#include "lwip/stats.h" -#include "lwip/netif.h" -#include "lwip/ip.h" -#include "lwip/etharp.h" - -#if LWIP_SNMP && SNMP_LWIP_MIB2 - -#if SNMP_USE_NETCONN -#define SYNC_NODE_NAME(node_name) node_name ## _synced -#define CREATE_LWIP_SYNC_NODE(oid, node_name) \ - static const struct snmp_threadsync_node node_name ## _synced = SNMP_CREATE_THREAD_SYNC_NODE(oid, &node_name.node, &snmp_mib2_lwip_locks); -#else -#define SYNC_NODE_NAME(node_name) node_name -#define CREATE_LWIP_SYNC_NODE(oid, node_name) -#endif - -#if LWIP_IPV4 -/* --- ip .1.3.6.1.2.1.4 ----------------------------------------------------- */ - -static s16_t -ip_get_value(struct snmp_node_instance* instance, void* value) -{ - s32_t* sint_ptr = (s32_t*)value; - u32_t* uint_ptr = (u32_t*)value; - - switch (instance->node->oid) { - case 1: /* ipForwarding */ -#if IP_FORWARD - /* forwarding */ - *sint_ptr = 1; -#else - /* not-forwarding */ - *sint_ptr = 2; -#endif - return sizeof(*sint_ptr); - case 2: /* ipDefaultTTL */ - *sint_ptr = IP_DEFAULT_TTL; - return sizeof(*sint_ptr); - case 3: /* ipInReceives */ - *uint_ptr = STATS_GET(mib2.ipinreceives); - return sizeof(*uint_ptr); - case 4: /* ipInHdrErrors */ - *uint_ptr = STATS_GET(mib2.ipinhdrerrors); - return sizeof(*uint_ptr); - case 5: /* ipInAddrErrors */ - *uint_ptr = STATS_GET(mib2.ipinaddrerrors); - return sizeof(*uint_ptr); - case 6: /* ipForwDatagrams */ - *uint_ptr = STATS_GET(mib2.ipforwdatagrams); - return sizeof(*uint_ptr); - case 7: /* ipInUnknownProtos */ - *uint_ptr = STATS_GET(mib2.ipinunknownprotos); - return sizeof(*uint_ptr); - case 8: /* ipInDiscards */ - *uint_ptr = STATS_GET(mib2.ipindiscards); - return sizeof(*uint_ptr); - case 9: /* ipInDelivers */ - *uint_ptr = STATS_GET(mib2.ipindelivers); - return sizeof(*uint_ptr); - case 10: /* ipOutRequests */ - *uint_ptr = STATS_GET(mib2.ipoutrequests); - return sizeof(*uint_ptr); - case 11: /* ipOutDiscards */ - *uint_ptr = STATS_GET(mib2.ipoutdiscards); - return sizeof(*uint_ptr); - case 12: /* ipOutNoRoutes */ - *uint_ptr = STATS_GET(mib2.ipoutnoroutes); - return sizeof(*uint_ptr); - case 13: /* ipReasmTimeout */ -#if IP_REASSEMBLY - *sint_ptr = IP_REASS_MAXAGE; -#else - *sint_ptr = 0; -#endif - return sizeof(*sint_ptr); - case 14: /* ipReasmReqds */ - *uint_ptr = STATS_GET(mib2.ipreasmreqds); - return sizeof(*uint_ptr); - case 15: /* ipReasmOKs */ - *uint_ptr = STATS_GET(mib2.ipreasmoks); - return sizeof(*uint_ptr); - case 16: /* ipReasmFails */ - *uint_ptr = STATS_GET(mib2.ipreasmfails); - return sizeof(*uint_ptr); - case 17: /* ipFragOKs */ - *uint_ptr = STATS_GET(mib2.ipfragoks); - return sizeof(*uint_ptr); - case 18: /* ipFragFails */ - *uint_ptr = STATS_GET(mib2.ipfragfails); - return sizeof(*uint_ptr); - case 19: /* ipFragCreates */ - *uint_ptr = STATS_GET(mib2.ipfragcreates); - return sizeof(*uint_ptr); - case 23: /* ipRoutingDiscards: not supported -> always 0 */ - *uint_ptr = 0; - return sizeof(*uint_ptr); - default: - LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_get_value(): unknown id: %"S32_F"\n", instance->node->oid)); - break; - } - - return 0; -} - -/** - * Test ip object value before setting. - * - * @param instance node instance - * @param len return value space (in bytes) - * @param value points to (varbind) space to copy value from. - * - * @note we allow set if the value matches the hardwired value, - * otherwise return badvalue. - */ -static snmp_err_t -ip_set_test(struct snmp_node_instance* instance, u16_t len, void *value) -{ - snmp_err_t ret = SNMP_ERR_WRONGVALUE; - s32_t *sint_ptr = (s32_t*)value; - - LWIP_UNUSED_ARG(len); - switch (instance->node->oid) { - case 1: /* ipForwarding */ -#if IP_FORWARD - /* forwarding */ - if (*sint_ptr == 1) -#else - /* not-forwarding */ - if (*sint_ptr == 2) -#endif - { - ret = SNMP_ERR_NOERROR; - } - break; - case 2: /* ipDefaultTTL */ - if (*sint_ptr == IP_DEFAULT_TTL) { - ret = SNMP_ERR_NOERROR; - } - break; - default: - LWIP_DEBUGF(SNMP_MIB_DEBUG,("ip_set_test(): unknown id: %"S32_F"\n", instance->node->oid)); - break; - } - - return ret; -} - -static snmp_err_t -ip_set_value(struct snmp_node_instance* instance, u16_t len, void *value) -{ - LWIP_UNUSED_ARG(instance); - LWIP_UNUSED_ARG(len); - LWIP_UNUSED_ARG(value); - /* nothing to do here because in set_test we only accept values being the same as our own stored value -> no need to store anything */ - return SNMP_ERR_NOERROR; -} - -/* --- ipAddrTable --- */ - -/* list of allowed value ranges for incoming OID */ -static const struct snmp_oid_range ip_AddrTable_oid_ranges[] = { - { 0, 0xff }, /* IP A */ - { 0, 0xff }, /* IP B */ - { 0, 0xff }, /* IP C */ - { 0, 0xff } /* IP D */ -}; - -static snmp_err_t -ip_AddrTable_get_cell_value_core(struct netif *netif, const u32_t* column, union snmp_variant_value* value, u32_t* value_len) -{ - LWIP_UNUSED_ARG(value_len); - - switch (*column) { - case 1: /* ipAdEntAddr */ - value->u32 = netif_ip4_addr(netif)->addr; - break; - case 2: /* ipAdEntIfIndex */ - value->u32 = netif_to_num(netif); - break; - case 3: /* ipAdEntNetMask */ - value->u32 = netif_ip4_netmask(netif)->addr; - break; - case 4: /* ipAdEntBcastAddr */ - /* lwIP oddity, there's no broadcast - address in the netif we can rely on */ - value->u32 = IPADDR_BROADCAST & 1; - break; - case 5: /* ipAdEntReasmMaxSize */ -#if IP_REASSEMBLY - /* @todo The theoretical maximum is IP_REASS_MAX_PBUFS * size of the pbufs, - * but only if receiving one fragmented packet at a time. - * The current solution is to calculate for 2 simultaneous packets... - */ - value->u32 = (IP_HLEN + ((IP_REASS_MAX_PBUFS/2) * - (PBUF_POOL_BUFSIZE - PBUF_LINK_ENCAPSULATION_HLEN - PBUF_LINK_HLEN - IP_HLEN))); -#else - /** @todo returning MTU would be a bad thing and - returning a wild guess like '576' isn't good either */ - value->u32 = 0; -#endif - break; - default: - return SNMP_ERR_NOSUCHINSTANCE; - } - - return SNMP_ERR_NOERROR; -} - -static snmp_err_t -ip_AddrTable_get_cell_value(const u32_t* column, const u32_t* row_oid, u8_t row_oid_len, union snmp_variant_value* value, u32_t* value_len) -{ - ip4_addr_t ip; - struct netif *netif; - - /* check if incoming OID length and if values are in plausible range */ - if (!snmp_oid_in_range(row_oid, row_oid_len, ip_AddrTable_oid_ranges, LWIP_ARRAYSIZE(ip_AddrTable_oid_ranges))) { - return SNMP_ERR_NOSUCHINSTANCE; - } - - /* get IP from incoming OID */ - snmp_oid_to_ip4(&row_oid[0], &ip); /* we know it succeeds because of oid_in_range check above */ - - /* find netif with requested ip */ - netif = netif_list; - while (netif != NULL) { - if (ip4_addr_cmp(&ip, netif_ip4_addr(netif))) { - /* fill in object properties */ - return ip_AddrTable_get_cell_value_core(netif, column, value, value_len); - } - - netif = netif->next; - } - - /* not found */ - return SNMP_ERR_NOSUCHINSTANCE; -} - -static snmp_err_t -ip_AddrTable_get_next_cell_instance_and_value(const u32_t* column, struct snmp_obj_id* row_oid, union snmp_variant_value* value, u32_t* value_len) -{ - struct netif *netif; - struct snmp_next_oid_state state; - u32_t result_temp[LWIP_ARRAYSIZE(ip_AddrTable_oid_ranges)]; - - /* init struct to search next oid */ - snmp_next_oid_init(&state, row_oid->id, row_oid->len, result_temp, LWIP_ARRAYSIZE(ip_AddrTable_oid_ranges)); - - /* iterate over all possible OIDs to find the next one */ - netif = netif_list; - while (netif != NULL) { - u32_t test_oid[LWIP_ARRAYSIZE(ip_AddrTable_oid_ranges)]; - snmp_ip4_to_oid(netif_ip4_addr(netif), &test_oid[0]); - - /* check generated OID: is it a candidate for the next one? */ - snmp_next_oid_check(&state, test_oid, LWIP_ARRAYSIZE(ip_AddrTable_oid_ranges), netif); - - netif = netif->next; - } - - /* did we find a next one? */ - if (state.status == SNMP_NEXT_OID_STATUS_SUCCESS) { - snmp_oid_assign(row_oid, state.next_oid, state.next_oid_len); - /* fill in object properties */ - return ip_AddrTable_get_cell_value_core((struct netif*)state.reference, column, value, value_len); - } - - /* not found */ - return SNMP_ERR_NOSUCHINSTANCE; -} - -/* --- ipRouteTable --- */ - -/* list of allowed value ranges for incoming OID */ -static const struct snmp_oid_range ip_RouteTable_oid_ranges[] = { - { 0, 0xff }, /* IP A */ - { 0, 0xff }, /* IP B */ - { 0, 0xff }, /* IP C */ - { 0, 0xff }, /* IP D */ -}; - -static snmp_err_t -ip_RouteTable_get_cell_value_core(struct netif *netif, u8_t default_route, const u32_t* column, union snmp_variant_value* value, u32_t* value_len) -{ - switch (*column) { - case 1: /* ipRouteDest */ - if (default_route) { - /* default rte has 0.0.0.0 dest */ - value->u32 = IP4_ADDR_ANY4->addr; - } else { - /* netifs have netaddress dest */ - ip4_addr_t tmp; - ip4_addr_get_network(&tmp, netif_ip4_addr(netif), netif_ip4_netmask(netif)); - value->u32 = tmp.addr; - } - break; - case 2: /* ipRouteIfIndex */ - value->u32 = netif_to_num(netif); - break; - case 3: /* ipRouteMetric1 */ - if (default_route) { - value->s32 = 1; /* default */ - } else { - value->s32 = 0; /* normal */ - } - break; - case 4: /* ipRouteMetric2 */ - case 5: /* ipRouteMetric3 */ - case 6: /* ipRouteMetric4 */ - value->s32 = -1; /* none */ - break; - case 7: /* ipRouteNextHop */ - if (default_route) { - /* default rte: gateway */ - value->u32 = netif_ip4_gw(netif)->addr; - } else { - /* other rtes: netif ip_addr */ - value->u32 = netif_ip4_addr(netif)->addr; - } - break; - case 8: /* ipRouteType */ - if (default_route) { - /* default rte is indirect */ - value->u32 = 4; /* indirect */ - } else { - /* other rtes are direct */ - value->u32 = 3; /* direct */ - } - break; - case 9: /* ipRouteProto */ - /* locally defined routes */ - value->u32 = 2; /* local */ - break; - case 10: /* ipRouteAge */ - /* @todo (sysuptime - timestamp last change) / 100 */ - value->u32 = 0; - break; - case 11: /* ipRouteMask */ - if (default_route) { - /* default rte use 0.0.0.0 mask */ - value->u32 = IP4_ADDR_ANY4->addr; - } else { - /* other rtes use netmask */ - value->u32 = netif_ip4_netmask(netif)->addr; - } - break; - case 12: /* ipRouteMetric5 */ - value->s32 = -1; /* none */ - break; - case 13: /* ipRouteInfo */ - value->const_ptr = snmp_zero_dot_zero.id; - *value_len = snmp_zero_dot_zero.len * sizeof(u32_t); - break; - default: - return SNMP_ERR_NOSUCHINSTANCE; - } - - return SNMP_ERR_NOERROR; -} - -static snmp_err_t -ip_RouteTable_get_cell_value(const u32_t* column, const u32_t* row_oid, u8_t row_oid_len, union snmp_variant_value* value, u32_t* value_len) -{ - ip4_addr_t test_ip; - struct netif *netif; - - /* check if incoming OID length and if values are in plausible range */ - if (!snmp_oid_in_range(row_oid, row_oid_len, ip_RouteTable_oid_ranges, LWIP_ARRAYSIZE(ip_RouteTable_oid_ranges))) { - return SNMP_ERR_NOSUCHINSTANCE; - } - - /* get IP and port from incoming OID */ - snmp_oid_to_ip4(&row_oid[0], &test_ip); /* we know it succeeds because of oid_in_range check above */ - - /* default route is on default netif */ - if (ip4_addr_isany_val(test_ip) && (netif_default != NULL)) { - /* fill in object properties */ - return ip_RouteTable_get_cell_value_core(netif_default, 1, column, value, value_len); - } - - /* find netif with requested route */ - netif = netif_list; - while (netif != NULL) { - ip4_addr_t dst; - ip4_addr_get_network(&dst, netif_ip4_addr(netif), netif_ip4_netmask(netif)); - - if (ip4_addr_cmp(&dst, &test_ip)) { - /* fill in object properties */ - return ip_RouteTable_get_cell_value_core(netif, 0, column, value, value_len); - } - - netif = netif->next; - } - - /* not found */ - return SNMP_ERR_NOSUCHINSTANCE; -} - -static snmp_err_t -ip_RouteTable_get_next_cell_instance_and_value(const u32_t* column, struct snmp_obj_id* row_oid, union snmp_variant_value* value, u32_t* value_len) -{ - struct netif *netif; - struct snmp_next_oid_state state; - u32_t result_temp[LWIP_ARRAYSIZE(ip_RouteTable_oid_ranges)]; - u32_t test_oid[LWIP_ARRAYSIZE(ip_RouteTable_oid_ranges)]; - - /* init struct to search next oid */ - snmp_next_oid_init(&state, row_oid->id, row_oid->len, result_temp, LWIP_ARRAYSIZE(ip_RouteTable_oid_ranges)); - - /* check default route */ - if (netif_default != NULL) { - snmp_ip4_to_oid(IP4_ADDR_ANY4, &test_oid[0]); - snmp_next_oid_check(&state, test_oid, LWIP_ARRAYSIZE(ip_RouteTable_oid_ranges), netif_default); - } - - /* iterate over all possible OIDs to find the next one */ - netif = netif_list; - while (netif != NULL) { - ip4_addr_t dst; - ip4_addr_get_network(&dst, netif_ip4_addr(netif), netif_ip4_netmask(netif)); - - /* check generated OID: is it a candidate for the next one? */ - if (!ip4_addr_isany_val(dst)) { - snmp_ip4_to_oid(&dst, &test_oid[0]); - snmp_next_oid_check(&state, test_oid, LWIP_ARRAYSIZE(ip_RouteTable_oid_ranges), netif); - } - - netif = netif->next; - } - - /* did we find a next one? */ - if (state.status == SNMP_NEXT_OID_STATUS_SUCCESS) { - ip4_addr_t dst; - snmp_oid_to_ip4(&result_temp[0], &dst); - snmp_oid_assign(row_oid, state.next_oid, state.next_oid_len); - /* fill in object properties */ - return ip_RouteTable_get_cell_value_core((struct netif*)state.reference, ip4_addr_isany_val(dst), column, value, value_len); - } else { - /* not found */ - return SNMP_ERR_NOSUCHINSTANCE; - } -} - -#if LWIP_ARP && LWIP_IPV4 -/* --- ipNetToMediaTable --- */ - -/* list of allowed value ranges for incoming OID */ -static const struct snmp_oid_range ip_NetToMediaTable_oid_ranges[] = { - { 1, 0xff }, /* IfIndex */ - { 0, 0xff }, /* IP A */ - { 0, 0xff }, /* IP B */ - { 0, 0xff }, /* IP C */ - { 0, 0xff } /* IP D */ -}; - -static snmp_err_t -ip_NetToMediaTable_get_cell_value_core(u8_t arp_table_index, const u32_t* column, union snmp_variant_value* value, u32_t* value_len) -{ - ip4_addr_t *ip; - struct netif *netif; - struct eth_addr *ethaddr; - - etharp_get_entry(arp_table_index, &ip, &netif, ðaddr); - - /* value */ - switch (*column) { - case 1: /* atIfIndex / ipNetToMediaIfIndex */ - value->u32 = netif_to_num(netif); - break; - case 2: /* atPhysAddress / ipNetToMediaPhysAddress */ - value->ptr = ethaddr; - *value_len = sizeof(*ethaddr); - break; - case 3: /* atNetAddress / ipNetToMediaNetAddress */ - value->u32 = ip->addr; - break; - case 4: /* ipNetToMediaType */ - value->u32 = 3; /* dynamic*/ - break; - default: - return SNMP_ERR_NOSUCHINSTANCE; - } - - return SNMP_ERR_NOERROR; -} - -static snmp_err_t -ip_NetToMediaTable_get_cell_value(const u32_t* column, const u32_t* row_oid, u8_t row_oid_len, union snmp_variant_value* value, u32_t* value_len) -{ - ip4_addr_t ip_in; - u8_t netif_index; - u8_t i; - - /* check if incoming OID length and if values are in plausible range */ - if (!snmp_oid_in_range(row_oid, row_oid_len, ip_NetToMediaTable_oid_ranges, LWIP_ARRAYSIZE(ip_NetToMediaTable_oid_ranges))) { - return SNMP_ERR_NOSUCHINSTANCE; - } - - /* get IP from incoming OID */ - netif_index = (u8_t)row_oid[0]; - snmp_oid_to_ip4(&row_oid[1], &ip_in); /* we know it succeeds because of oid_in_range check above */ - - /* find requested entry */ - for (i=0; iid, row_oid->len, result_temp, LWIP_ARRAYSIZE(ip_NetToMediaTable_oid_ranges)); - - /* iterate over all possible OIDs to find the next one */ - for (i=0; i - * Christiaan Simons - */ - -#include "lwip/snmp.h" -#include "lwip/apps/snmp.h" -#include "lwip/apps/snmp_core.h" -#include "lwip/apps/snmp_mib2.h" -#include "lwip/apps/snmp_scalar.h" - -#if LWIP_SNMP && SNMP_LWIP_MIB2 - -#define MIB2_AUTH_TRAPS_ENABLED 1 -#define MIB2_AUTH_TRAPS_DISABLED 2 - -/* --- snmp .1.3.6.1.2.1.11 ----------------------------------------------------- */ -static s16_t -snmp_get_value(const struct snmp_scalar_array_node_def *node, void *value) -{ - u32_t *uint_ptr = (u32_t*)value; - switch (node->oid) { - case 1: /* snmpInPkts */ - *uint_ptr = snmp_stats.inpkts; - break; - case 2: /* snmpOutPkts */ - *uint_ptr = snmp_stats.outpkts; - break; - case 3: /* snmpInBadVersions */ - *uint_ptr = snmp_stats.inbadversions; - break; - case 4: /* snmpInBadCommunityNames */ - *uint_ptr = snmp_stats.inbadcommunitynames; - break; - case 5: /* snmpInBadCommunityUses */ - *uint_ptr = snmp_stats.inbadcommunityuses; - break; - case 6: /* snmpInASNParseErrs */ - *uint_ptr = snmp_stats.inasnparseerrs; - break; - case 8: /* snmpInTooBigs */ - *uint_ptr = snmp_stats.intoobigs; - break; - case 9: /* snmpInNoSuchNames */ - *uint_ptr = snmp_stats.innosuchnames; - break; - case 10: /* snmpInBadValues */ - *uint_ptr = snmp_stats.inbadvalues; - break; - case 11: /* snmpInReadOnlys */ - *uint_ptr = snmp_stats.inreadonlys; - break; - case 12: /* snmpInGenErrs */ - *uint_ptr = snmp_stats.ingenerrs; - break; - case 13: /* snmpInTotalReqVars */ - *uint_ptr = snmp_stats.intotalreqvars; - break; - case 14: /* snmpInTotalSetVars */ - *uint_ptr = snmp_stats.intotalsetvars; - break; - case 15: /* snmpInGetRequests */ - *uint_ptr = snmp_stats.ingetrequests; - break; - case 16: /* snmpInGetNexts */ - *uint_ptr = snmp_stats.ingetnexts; - break; - case 17: /* snmpInSetRequests */ - *uint_ptr = snmp_stats.insetrequests; - break; - case 18: /* snmpInGetResponses */ - *uint_ptr = snmp_stats.ingetresponses; - break; - case 19: /* snmpInTraps */ - *uint_ptr = snmp_stats.intraps; - break; - case 20: /* snmpOutTooBigs */ - *uint_ptr = snmp_stats.outtoobigs; - break; - case 21: /* snmpOutNoSuchNames */ - *uint_ptr = snmp_stats.outnosuchnames; - break; - case 22: /* snmpOutBadValues */ - *uint_ptr = snmp_stats.outbadvalues; - break; - case 24: /* snmpOutGenErrs */ - *uint_ptr = snmp_stats.outgenerrs; - break; - case 25: /* snmpOutGetRequests */ - *uint_ptr = snmp_stats.outgetrequests; - break; - case 26: /* snmpOutGetNexts */ - *uint_ptr = snmp_stats.outgetnexts; - break; - case 27: /* snmpOutSetRequests */ - *uint_ptr = snmp_stats.outsetrequests; - break; - case 28: /* snmpOutGetResponses */ - *uint_ptr = snmp_stats.outgetresponses; - break; - case 29: /* snmpOutTraps */ - *uint_ptr = snmp_stats.outtraps; - break; - case 30: /* snmpEnableAuthenTraps */ - if (snmp_get_auth_traps_enabled() == SNMP_AUTH_TRAPS_DISABLED) { - *uint_ptr = MIB2_AUTH_TRAPS_DISABLED; - } else { - *uint_ptr = MIB2_AUTH_TRAPS_ENABLED; - } - break; - case 31: /* snmpSilentDrops */ - *uint_ptr = 0; /* not supported */ - break; - case 32: /* snmpProxyDrops */ - *uint_ptr = 0; /* not supported */ - break; - default: - LWIP_DEBUGF(SNMP_MIB_DEBUG,("snmp_get_value(): unknown id: %"S32_F"\n", node->oid)); - return 0; - } - - return sizeof(*uint_ptr); -} - -static snmp_err_t -snmp_set_test(const struct snmp_scalar_array_node_def *node, u16_t len, void *value) -{ - snmp_err_t ret = SNMP_ERR_WRONGVALUE; - LWIP_UNUSED_ARG(len); - - if (node->oid == 30) { - /* snmpEnableAuthenTraps */ - s32_t *sint_ptr = (s32_t*)value; - - /* we should have writable non-volatile mem here */ - if ((*sint_ptr == MIB2_AUTH_TRAPS_DISABLED) || (*sint_ptr == MIB2_AUTH_TRAPS_ENABLED)) { - ret = SNMP_ERR_NOERROR; - } - } - return ret; -} - -static snmp_err_t -snmp_set_value(const struct snmp_scalar_array_node_def *node, u16_t len, void *value) -{ - LWIP_UNUSED_ARG(len); - - if (node->oid == 30) { - /* snmpEnableAuthenTraps */ - s32_t *sint_ptr = (s32_t*)value; - if (*sint_ptr == MIB2_AUTH_TRAPS_DISABLED) { - snmp_set_auth_traps_enabled(SNMP_AUTH_TRAPS_DISABLED); - } else { - snmp_set_auth_traps_enabled(SNMP_AUTH_TRAPS_ENABLED); - } - } - - return SNMP_ERR_NOERROR; -} - -/* the following nodes access variables in SNMP stack (snmp_stats) from SNMP worker thread -> OK, no sync needed */ -static const struct snmp_scalar_array_node_def snmp_nodes[] = { - { 1, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpInPkts */ - { 2, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpOutPkts */ - { 3, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpInBadVersions */ - { 4, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpInBadCommunityNames */ - { 5, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpInBadCommunityUses */ - { 6, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpInASNParseErrs */ - { 8, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpInTooBigs */ - { 9, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpInNoSuchNames */ - {10, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpInBadValues */ - {11, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpInReadOnlys */ - {12, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpInGenErrs */ - {13, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpInTotalReqVars */ - {14, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpInTotalSetVars */ - {15, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpInGetRequests */ - {16, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpInGetNexts */ - {17, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpInSetRequests */ - {18, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpInGetResponses */ - {19, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpInTraps */ - {20, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpOutTooBigs */ - {21, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpOutNoSuchNames */ - {22, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpOutBadValues */ - {24, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpOutGenErrs */ - {25, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpOutGetRequests */ - {26, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpOutGetNexts */ - {27, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpOutSetRequests */ - {28, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpOutGetResponses */ - {29, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpOutTraps */ - {30, SNMP_ASN1_TYPE_INTEGER, SNMP_NODE_INSTANCE_READ_WRITE}, /* snmpEnableAuthenTraps */ - {31, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY}, /* snmpSilentDrops */ - {32, SNMP_ASN1_TYPE_COUNTER, SNMP_NODE_INSTANCE_READ_ONLY} /* snmpProxyDrops */ -}; - -const struct snmp_scalar_array_node snmp_mib2_snmp_root = SNMP_SCALAR_CREATE_ARRAY_NODE(11, snmp_nodes, snmp_get_value, snmp_set_test, snmp_set_value); - -#endif /* LWIP_SNMP && SNMP_LWIP_MIB2 */ diff --git a/third_party/lwip/repo/lwip/src/apps/snmp/snmp_mib2_system.c b/third_party/lwip/repo/lwip/src/apps/snmp/snmp_mib2_system.c deleted file mode 100644 index 90e57805d248a2..00000000000000 --- a/third_party/lwip/repo/lwip/src/apps/snmp/snmp_mib2_system.c +++ /dev/null @@ -1,377 +0,0 @@ -/** - * @file - * Management Information Base II (RFC1213) SYSTEM objects and functions. - */ - -/* - * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * Author: Dirk Ziegelmeier - * Christiaan Simons - */ - -#include "lwip/snmp.h" -#include "lwip/apps/snmp.h" -#include "lwip/apps/snmp_core.h" -#include "lwip/apps/snmp_mib2.h" -#include "lwip/apps/snmp_table.h" -#include "lwip/apps/snmp_scalar.h" -#include "lwip/sys.h" - -#include - -#if LWIP_SNMP && SNMP_LWIP_MIB2 - -#if SNMP_USE_NETCONN -#define SYNC_NODE_NAME(node_name) node_name ## _synced -#define CREATE_LWIP_SYNC_NODE(oid, node_name) \ - static const struct snmp_threadsync_node node_name ## _synced = SNMP_CREATE_THREAD_SYNC_NODE(oid, &node_name.node, &snmp_mib2_lwip_locks); -#else -#define SYNC_NODE_NAME(node_name) node_name -#define CREATE_LWIP_SYNC_NODE(oid, node_name) -#endif - -/* --- system .1.3.6.1.2.1.1 ----------------------------------------------------- */ - -/** mib-2.system.sysDescr */ -static const u8_t sysdescr_default[] = SNMP_LWIP_MIB2_SYSDESC; -static const u8_t* sysdescr = sysdescr_default; -static const u16_t* sysdescr_len = NULL; /* use strlen for determining len */ - -/** mib-2.system.sysContact */ -static const u8_t syscontact_default[] = SNMP_LWIP_MIB2_SYSCONTACT; -static const u8_t* syscontact = syscontact_default; -static const u16_t* syscontact_len = NULL; /* use strlen for determining len */ -static u8_t* syscontact_wr = NULL; /* if writable, points to the same buffer as syscontact (required for correct constness) */ -static u16_t* syscontact_wr_len = NULL; /* if writable, points to the same buffer as syscontact_len (required for correct constness) */ -static u16_t syscontact_bufsize = 0; /* 0=not writable */ - -/** mib-2.system.sysName */ -static const u8_t sysname_default[] = SNMP_LWIP_MIB2_SYSNAME; -static const u8_t* sysname = sysname_default; -static const u16_t* sysname_len = NULL; /* use strlen for determining len */ -static u8_t* sysname_wr = NULL; /* if writable, points to the same buffer as sysname (required for correct constness) */ -static u16_t* sysname_wr_len = NULL; /* if writable, points to the same buffer as sysname_len (required for correct constness) */ -static u16_t sysname_bufsize = 0; /* 0=not writable */ - -/** mib-2.system.sysLocation */ -static const u8_t syslocation_default[] = SNMP_LWIP_MIB2_SYSLOCATION; -static const u8_t* syslocation = syslocation_default; -static const u16_t* syslocation_len = NULL; /* use strlen for determining len */ -static u8_t* syslocation_wr = NULL; /* if writable, points to the same buffer as syslocation (required for correct constness) */ -static u16_t* syslocation_wr_len = NULL; /* if writable, points to the same buffer as syslocation_len (required for correct constness) */ -static u16_t syslocation_bufsize = 0; /* 0=not writable */ - -/** - * @ingroup snmp_mib2 - * Initializes sysDescr pointers. - * - * @param str if non-NULL then copy str pointer - * @param len points to string length, excluding zero terminator - */ -void -snmp_mib2_set_sysdescr(const u8_t *str, const u16_t *len) -{ - if (str != NULL) { - sysdescr = str; - sysdescr_len = len; - } -} - -/** - * @ingroup snmp_mib2 - * Initializes sysContact pointers - * - * @param ocstr if non-NULL then copy str pointer - * @param ocstrlen points to string length, excluding zero terminator. - * if set to NULL it is assumed that ocstr is NULL-terminated. - * @param bufsize size of the buffer in bytes. - * (this is required because the buffer can be overwritten by snmp-set) - * if ocstrlen is NULL buffer needs space for terminating 0 byte. - * otherwise complete buffer is used for string. - * if bufsize is set to 0, the value is regarded as read-only. - */ -void -snmp_mib2_set_syscontact(u8_t *ocstr, u16_t *ocstrlen, u16_t bufsize) -{ - if (ocstr != NULL) { - syscontact = ocstr; - syscontact_wr = ocstr; - syscontact_len = ocstrlen; - syscontact_wr_len = ocstrlen; - syscontact_bufsize = bufsize; - } -} - -/** - * @ingroup snmp_mib2 - * see \ref snmp_mib2_set_syscontact but set pointer to readonly memory - */ -void -snmp_mib2_set_syscontact_readonly(const u8_t *ocstr, const u16_t *ocstrlen) -{ - if (ocstr != NULL) { - syscontact = ocstr; - syscontact_len = ocstrlen; - syscontact_wr = NULL; - syscontact_wr_len = NULL; - syscontact_bufsize = 0; - } -} - - -/** - * @ingroup snmp_mib2 - * Initializes sysName pointers - * - * @param ocstr if non-NULL then copy str pointer - * @param ocstrlen points to string length, excluding zero terminator. - * if set to NULL it is assumed that ocstr is NULL-terminated. - * @param bufsize size of the buffer in bytes. - * (this is required because the buffer can be overwritten by snmp-set) - * if ocstrlen is NULL buffer needs space for terminating 0 byte. - * otherwise complete buffer is used for string. - * if bufsize is set to 0, the value is regarded as read-only. - */ -void -snmp_mib2_set_sysname(u8_t *ocstr, u16_t *ocstrlen, u16_t bufsize) -{ - if (ocstr != NULL) { - sysname = ocstr; - sysname_wr = ocstr; - sysname_len = ocstrlen; - sysname_wr_len = ocstrlen; - sysname_bufsize = bufsize; - } -} - -/** - * @ingroup snmp_mib2 - * see \ref snmp_mib2_set_sysname but set pointer to readonly memory - */ -void -snmp_mib2_set_sysname_readonly(const u8_t *ocstr, const u16_t *ocstrlen) -{ - if (ocstr != NULL) { - sysname = ocstr; - sysname_len = ocstrlen; - sysname_wr = NULL; - sysname_wr_len = NULL; - sysname_bufsize = 0; - } -} - -/** - * @ingroup snmp_mib2 - * Initializes sysLocation pointers - * - * @param ocstr if non-NULL then copy str pointer - * @param ocstrlen points to string length, excluding zero terminator. - * if set to NULL it is assumed that ocstr is NULL-terminated. - * @param bufsize size of the buffer in bytes. - * (this is required because the buffer can be overwritten by snmp-set) - * if ocstrlen is NULL buffer needs space for terminating 0 byte. - * otherwise complete buffer is used for string. - * if bufsize is set to 0, the value is regarded as read-only. - */ -void -snmp_mib2_set_syslocation(u8_t *ocstr, u16_t *ocstrlen, u16_t bufsize) -{ - if (ocstr != NULL) { - syslocation = ocstr; - syslocation_wr = ocstr; - syslocation_len = ocstrlen; - syslocation_wr_len = ocstrlen; - syslocation_bufsize = bufsize; - } -} - -/** - * @ingroup snmp_mib2 - * see \ref snmp_mib2_set_syslocation but set pointer to readonly memory - */ -void -snmp_mib2_set_syslocation_readonly(const u8_t *ocstr, const u16_t *ocstrlen) -{ - if (ocstr != NULL) { - syslocation = ocstr; - syslocation_len = ocstrlen; - syslocation_wr = NULL; - syslocation_wr_len = NULL; - syslocation_bufsize = 0; - } -} - - -static s16_t -system_get_value(const struct snmp_scalar_array_node_def *node, void *value) -{ - const u8_t* var = NULL; - const s16_t* var_len; - u16_t result; - - switch (node->oid) { - case 1: /* sysDescr */ - var = sysdescr; - var_len = (const s16_t*)sysdescr_len; - break; - case 2: /* sysObjectID */ - { - const struct snmp_obj_id* dev_enterprise_oid = snmp_get_device_enterprise_oid(); - MEMCPY(value, dev_enterprise_oid->id, dev_enterprise_oid->len * sizeof(u32_t)); - return dev_enterprise_oid->len * sizeof(u32_t); - } - case 3: /* sysUpTime */ - MIB2_COPY_SYSUPTIME_TO((u32_t*)value); - return sizeof(u32_t); - case 4: /* sysContact */ - var = syscontact; - var_len = (const s16_t*)syscontact_len; - break; - case 5: /* sysName */ - var = sysname; - var_len = (const s16_t*)sysname_len; - break; - case 6: /* sysLocation */ - var = syslocation; - var_len = (const s16_t*)syslocation_len; - break; - case 7: /* sysServices */ - *(s32_t*)value = SNMP_SYSSERVICES; - return sizeof(s32_t); - default: - LWIP_DEBUGF(SNMP_MIB_DEBUG,("system_get_value(): unknown id: %"S32_F"\n", node->oid)); - return 0; - } - - /* handle string values (OID 1,4,5 and 6) */ - LWIP_ASSERT("", (value != NULL)); - if (var_len == NULL) { - result = (s16_t)strlen((const char*)var); - } else { - result = *var_len; - } - MEMCPY(value, var, result); - return result; -} - -static snmp_err_t -system_set_test(const struct snmp_scalar_array_node_def *node, u16_t len, void *value) -{ - snmp_err_t ret = SNMP_ERR_WRONGVALUE; - const u16_t* var_bufsize = NULL; - const u16_t* var_wr_len; - - LWIP_UNUSED_ARG(value); - - switch (node->oid) { - case 4: /* sysContact */ - var_bufsize = &syscontact_bufsize; - var_wr_len = syscontact_wr_len; - break; - case 5: /* sysName */ - var_bufsize = &sysname_bufsize; - var_wr_len = sysname_wr_len; - break; - case 6: /* sysLocation */ - var_bufsize = &syslocation_bufsize; - var_wr_len = syslocation_wr_len; - break; - default: - LWIP_DEBUGF(SNMP_MIB_DEBUG,("system_set_test(): unknown id: %"S32_F"\n", node->oid)); - return ret; - } - - /* check if value is writable at all */ - if (*var_bufsize > 0) { - if (var_wr_len == NULL) { - /* we have to take the terminating 0 into account */ - if (len < *var_bufsize) { - ret = SNMP_ERR_NOERROR; - } - } else { - if (len <= *var_bufsize) { - ret = SNMP_ERR_NOERROR; - } - } - } else { - ret = SNMP_ERR_NOTWRITABLE; - } - - return ret; -} - -static snmp_err_t -system_set_value(const struct snmp_scalar_array_node_def *node, u16_t len, void *value) -{ - u8_t* var_wr = NULL; - u16_t* var_wr_len; - - switch (node->oid) { - case 4: /* sysContact */ - var_wr = syscontact_wr; - var_wr_len = syscontact_wr_len; - break; - case 5: /* sysName */ - var_wr = sysname_wr; - var_wr_len = sysname_wr_len; - break; - case 6: /* sysLocation */ - var_wr = syslocation_wr; - var_wr_len = syslocation_wr_len; - break; - default: - LWIP_DEBUGF(SNMP_MIB_DEBUG,("system_set_value(): unknown id: %"S32_F"\n", node->oid)); - return SNMP_ERR_GENERROR; - } - - /* no need to check size of target buffer, this was already done in set_test method */ - LWIP_ASSERT("", var_wr != NULL); - MEMCPY(var_wr, value, len); - - if (var_wr_len == NULL) { - /* add terminating 0 */ - var_wr[len] = 0; - } else { - *var_wr_len = len; - } - - return SNMP_ERR_NOERROR; -} - -static const struct snmp_scalar_array_node_def system_nodes[] = { - {1, SNMP_ASN1_TYPE_OCTET_STRING, SNMP_NODE_INSTANCE_READ_ONLY}, /* sysDescr */ - {2, SNMP_ASN1_TYPE_OBJECT_ID, SNMP_NODE_INSTANCE_READ_ONLY}, /* sysObjectID */ - {3, SNMP_ASN1_TYPE_TIMETICKS, SNMP_NODE_INSTANCE_READ_ONLY}, /* sysUpTime */ - {4, SNMP_ASN1_TYPE_OCTET_STRING, SNMP_NODE_INSTANCE_READ_WRITE}, /* sysContact */ - {5, SNMP_ASN1_TYPE_OCTET_STRING, SNMP_NODE_INSTANCE_READ_WRITE}, /* sysName */ - {6, SNMP_ASN1_TYPE_OCTET_STRING, SNMP_NODE_INSTANCE_READ_WRITE}, /* sysLocation */ - {7, SNMP_ASN1_TYPE_INTEGER, SNMP_NODE_INSTANCE_READ_ONLY} /* sysServices */ -}; - -const struct snmp_scalar_array_node snmp_mib2_system_node = SNMP_SCALAR_CREATE_ARRAY_NODE(1, system_nodes, system_get_value, system_set_test, system_set_value); - -#endif /* LWIP_SNMP && SNMP_LWIP_MIB2 */ diff --git a/third_party/lwip/repo/lwip/src/apps/snmp/snmp_mib2_tcp.c b/third_party/lwip/repo/lwip/src/apps/snmp/snmp_mib2_tcp.c deleted file mode 100644 index 21f6965662c68c..00000000000000 --- a/third_party/lwip/repo/lwip/src/apps/snmp/snmp_mib2_tcp.c +++ /dev/null @@ -1,594 +0,0 @@ -/** - * @file - * Management Information Base II (RFC1213) TCP objects and functions. - */ - -/* - * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * Author: Dirk Ziegelmeier - * Christiaan Simons - */ - -#include "lwip/snmp.h" -#include "lwip/apps/snmp.h" -#include "lwip/apps/snmp_core.h" -#include "lwip/apps/snmp_mib2.h" -#include "lwip/apps/snmp_table.h" -#include "lwip/apps/snmp_scalar.h" -#include "lwip/tcp.h" -#include "lwip/priv/tcp_priv.h" -#include "lwip/stats.h" - -#include - -#if LWIP_SNMP && SNMP_LWIP_MIB2 && LWIP_TCP - -#if SNMP_USE_NETCONN -#define SYNC_NODE_NAME(node_name) node_name ## _synced -#define CREATE_LWIP_SYNC_NODE(oid, node_name) \ - static const struct snmp_threadsync_node node_name ## _synced = SNMP_CREATE_THREAD_SYNC_NODE(oid, &node_name.node, &snmp_mib2_lwip_locks); -#else -#define SYNC_NODE_NAME(node_name) node_name -#define CREATE_LWIP_SYNC_NODE(oid, node_name) -#endif - -/* --- tcp .1.3.6.1.2.1.6 ----------------------------------------------------- */ - -static s16_t -tcp_get_value(struct snmp_node_instance* instance, void* value) -{ - u32_t *uint_ptr = (u32_t*)value; - s32_t *sint_ptr = (s32_t*)value; - - switch (instance->node->oid) { - case 1: /* tcpRtoAlgorithm, vanj(4) */ - *sint_ptr = 4; - return sizeof(*sint_ptr); - case 2: /* tcpRtoMin */ - /* @todo not the actual value, a guess, - needs to be calculated */ - *sint_ptr = 1000; - return sizeof(*sint_ptr); - case 3: /* tcpRtoMax */ - /* @todo not the actual value, a guess, - needs to be calculated */ - *sint_ptr = 60000; - return sizeof(*sint_ptr); - case 4: /* tcpMaxConn */ - *sint_ptr = MEMP_NUM_TCP_PCB; - return sizeof(*sint_ptr); - case 5: /* tcpActiveOpens */ - *uint_ptr = STATS_GET(mib2.tcpactiveopens); - return sizeof(*uint_ptr); - case 6: /* tcpPassiveOpens */ - *uint_ptr = STATS_GET(mib2.tcppassiveopens); - return sizeof(*uint_ptr); - case 7: /* tcpAttemptFails */ - *uint_ptr = STATS_GET(mib2.tcpattemptfails); - return sizeof(*uint_ptr); - case 8: /* tcpEstabResets */ - *uint_ptr = STATS_GET(mib2.tcpestabresets); - return sizeof(*uint_ptr); - case 9: /* tcpCurrEstab */ - { - u16_t tcpcurrestab = 0; - struct tcp_pcb *pcb = tcp_active_pcbs; - while (pcb != NULL) { - if ((pcb->state == ESTABLISHED) || - (pcb->state == CLOSE_WAIT)) { - tcpcurrestab++; - } - pcb = pcb->next; - } - *uint_ptr = tcpcurrestab; - } - return sizeof(*uint_ptr); - case 10: /* tcpInSegs */ - *uint_ptr = STATS_GET(mib2.tcpinsegs); - return sizeof(*uint_ptr); - case 11: /* tcpOutSegs */ - *uint_ptr = STATS_GET(mib2.tcpoutsegs); - return sizeof(*uint_ptr); - case 12: /* tcpRetransSegs */ - *uint_ptr = STATS_GET(mib2.tcpretranssegs); - return sizeof(*uint_ptr); - case 14: /* tcpInErrs */ - *uint_ptr = STATS_GET(mib2.tcpinerrs); - return sizeof(*uint_ptr); - case 15: /* tcpOutRsts */ - *uint_ptr = STATS_GET(mib2.tcpoutrsts); - return sizeof(*uint_ptr); - case 17: /* tcpHCInSegs */ - memset(value, 0, 2*sizeof(u32_t)); /* not supported */ - return 2*sizeof(u32_t); - case 18: /* tcpHCOutSegs */ - memset(value, 0, 2*sizeof(u32_t)); /* not supported */ - return 2*sizeof(u32_t); - default: - LWIP_DEBUGF(SNMP_MIB_DEBUG,("tcp_get_value(): unknown id: %"S32_F"\n", instance->node->oid)); - break; - } - - return 0; -} - -/* --- tcpConnTable --- */ - -#if LWIP_IPV4 - -/* list of allowed value ranges for incoming OID */ -static const struct snmp_oid_range tcp_ConnTable_oid_ranges[] = { - { 0, 0xff }, /* IP A */ - { 0, 0xff }, /* IP B */ - { 0, 0xff }, /* IP C */ - { 0, 0xff }, /* IP D */ - { 0, 0xffff }, /* Port */ - { 0, 0xff }, /* IP A */ - { 0, 0xff }, /* IP B */ - { 0, 0xff }, /* IP C */ - { 0, 0xff }, /* IP D */ - { 0, 0xffff } /* Port */ -}; - -static snmp_err_t -tcp_ConnTable_get_cell_value_core(struct tcp_pcb *pcb, const u32_t* column, union snmp_variant_value* value, u32_t* value_len) -{ - LWIP_UNUSED_ARG(value_len); - - /* value */ - switch (*column) { - case 1: /* tcpConnState */ - value->u32 = pcb->state + 1; - break; - case 2: /* tcpConnLocalAddress */ - value->u32 = ip_2_ip4(&pcb->local_ip)->addr; - break; - case 3: /* tcpConnLocalPort */ - value->u32 = pcb->local_port; - break; - case 4: /* tcpConnRemAddress */ - if (pcb->state == LISTEN) { - value->u32 = IP4_ADDR_ANY4->addr; - } else { - value->u32 = ip_2_ip4(&pcb->remote_ip)->addr; - } - break; - case 5: /* tcpConnRemPort */ - if (pcb->state == LISTEN) { - value->u32 = 0; - } else { - value->u32 = pcb->remote_port; - } - break; - default: - LWIP_ASSERT("invalid id", 0); - return SNMP_ERR_NOSUCHINSTANCE; - } - - return SNMP_ERR_NOERROR; -} - -static snmp_err_t -tcp_ConnTable_get_cell_value(const u32_t* column, const u32_t* row_oid, u8_t row_oid_len, union snmp_variant_value* value, u32_t* value_len) -{ - u8_t i; - ip4_addr_t local_ip; - ip4_addr_t remote_ip; - u16_t local_port; - u16_t remote_port; - struct tcp_pcb *pcb; - - /* check if incoming OID length and if values are in plausible range */ - if (!snmp_oid_in_range(row_oid, row_oid_len, tcp_ConnTable_oid_ranges, LWIP_ARRAYSIZE(tcp_ConnTable_oid_ranges))) { - return SNMP_ERR_NOSUCHINSTANCE; - } - - /* get IPs and ports from incoming OID */ - snmp_oid_to_ip4(&row_oid[0], &local_ip); /* we know it succeeds because of oid_in_range check above */ - local_port = (u16_t)row_oid[4]; - snmp_oid_to_ip4(&row_oid[5], &remote_ip); /* we know it succeeds because of oid_in_range check above */ - remote_port = (u16_t)row_oid[9]; - - /* find tcp_pcb with requested ips and ports */ - for (i = 0; i < LWIP_ARRAYSIZE(tcp_pcb_lists); i++) { - pcb = *tcp_pcb_lists[i]; - - while (pcb != NULL) { - /* do local IP and local port match? */ - if (IP_IS_V4_VAL(pcb->local_ip) && - ip4_addr_cmp(&local_ip, ip_2_ip4(&pcb->local_ip)) && (local_port == pcb->local_port)) { - - /* PCBs in state LISTEN are not connected and have no remote_ip or remote_port */ - if (pcb->state == LISTEN) { - if (ip4_addr_cmp(&remote_ip, IP4_ADDR_ANY4) && (remote_port == 0)) { - /* fill in object properties */ - return tcp_ConnTable_get_cell_value_core(pcb, column, value, value_len); - } - } else { - if (IP_IS_V4_VAL(pcb->remote_ip) && - ip4_addr_cmp(&remote_ip, ip_2_ip4(&pcb->remote_ip)) && (remote_port == pcb->remote_port)) { - /* fill in object properties */ - return tcp_ConnTable_get_cell_value_core(pcb, column, value, value_len); - } - } - } - - pcb = pcb->next; - } - } - - /* not found */ - return SNMP_ERR_NOSUCHINSTANCE; -} - -static snmp_err_t -tcp_ConnTable_get_next_cell_instance_and_value(const u32_t* column, struct snmp_obj_id* row_oid, union snmp_variant_value* value, u32_t* value_len) -{ - u8_t i; - struct tcp_pcb *pcb; - struct snmp_next_oid_state state; - u32_t result_temp[LWIP_ARRAYSIZE(tcp_ConnTable_oid_ranges)]; - - /* init struct to search next oid */ - snmp_next_oid_init(&state, row_oid->id, row_oid->len, result_temp, LWIP_ARRAYSIZE(tcp_ConnTable_oid_ranges)); - - /* iterate over all possible OIDs to find the next one */ - for (i = 0; i < LWIP_ARRAYSIZE(tcp_pcb_lists); i++) { - pcb = *tcp_pcb_lists[i]; - while (pcb != NULL) { - u32_t test_oid[LWIP_ARRAYSIZE(tcp_ConnTable_oid_ranges)]; - - if (IP_IS_V4_VAL(pcb->local_ip)) { - snmp_ip4_to_oid(ip_2_ip4(&pcb->local_ip), &test_oid[0]); - test_oid[4] = pcb->local_port; - - /* PCBs in state LISTEN are not connected and have no remote_ip or remote_port */ - if (pcb->state == LISTEN) { - snmp_ip4_to_oid(IP4_ADDR_ANY4, &test_oid[5]); - test_oid[9] = 0; - } else { - if (IP_IS_V6_VAL(pcb->remote_ip)) { /* should never happen */ - continue; - } - snmp_ip4_to_oid(ip_2_ip4(&pcb->remote_ip), &test_oid[5]); - test_oid[9] = pcb->remote_port; - } - - /* check generated OID: is it a candidate for the next one? */ - snmp_next_oid_check(&state, test_oid, LWIP_ARRAYSIZE(tcp_ConnTable_oid_ranges), pcb); - } - - pcb = pcb->next; - } - } - - /* did we find a next one? */ - if (state.status == SNMP_NEXT_OID_STATUS_SUCCESS) { - snmp_oid_assign(row_oid, state.next_oid, state.next_oid_len); - /* fill in object properties */ - return tcp_ConnTable_get_cell_value_core((struct tcp_pcb*)state.reference, column, value, value_len); - } - - /* not found */ - return SNMP_ERR_NOSUCHINSTANCE; -} - -#endif /* LWIP_IPV4 */ - -/* --- tcpConnectionTable --- */ - -static snmp_err_t -tcp_ConnectionTable_get_cell_value_core(const u32_t* column, struct tcp_pcb *pcb, union snmp_variant_value* value) -{ - /* all items except tcpConnectionState and tcpConnectionProcess are declared as not-accessible */ - switch (*column) { - case 7: /* tcpConnectionState */ - value->u32 = pcb->state + 1; - break; - case 8: /* tcpConnectionProcess */ - value->u32 = 0; /* not supported */ - break; - default: - return SNMP_ERR_NOSUCHINSTANCE; - } - - return SNMP_ERR_NOERROR; -} - -static snmp_err_t -tcp_ConnectionTable_get_cell_value(const u32_t* column, const u32_t* row_oid, u8_t row_oid_len, union snmp_variant_value* value, u32_t* value_len) -{ - ip_addr_t local_ip, remote_ip; - u16_t local_port, remote_port; - struct tcp_pcb *pcb; - u8_t idx = 0; - u8_t i; - struct tcp_pcb ** const tcp_pcb_nonlisten_lists[] = {&tcp_bound_pcbs, &tcp_active_pcbs, &tcp_tw_pcbs}; - - LWIP_UNUSED_ARG(value_len); - - /* tcpConnectionLocalAddressType + tcpConnectionLocalAddress + tcpConnectionLocalPort */ - idx += snmp_oid_to_ip_port(&row_oid[idx], row_oid_len-idx, &local_ip, &local_port); - if (idx == 0) { - return SNMP_ERR_NOSUCHINSTANCE; - } - - /* tcpConnectionRemAddressType + tcpConnectionRemAddress + tcpConnectionRemPort */ - idx += snmp_oid_to_ip_port(&row_oid[idx], row_oid_len-idx, &remote_ip, &remote_port); - if (idx == 0) { - return SNMP_ERR_NOSUCHINSTANCE; - } - - /* find tcp_pcb with requested ip and port*/ - for (i = 0; i < LWIP_ARRAYSIZE(tcp_pcb_nonlisten_lists); i++) { - pcb = *tcp_pcb_nonlisten_lists[i]; - - while (pcb != NULL) { - if (ip_addr_cmp(&local_ip, &pcb->local_ip) && - (local_port == pcb->local_port) && - ip_addr_cmp(&remote_ip, &pcb->remote_ip) && - (remote_port == pcb->remote_port)) { - /* fill in object properties */ - return tcp_ConnectionTable_get_cell_value_core(column, pcb, value); - } - pcb = pcb->next; - } - } - - /* not found */ - return SNMP_ERR_NOSUCHINSTANCE; -} - -static snmp_err_t -tcp_ConnectionTable_get_next_cell_instance_and_value(const u32_t* column, struct snmp_obj_id* row_oid, union snmp_variant_value* value, u32_t* value_len) -{ - struct tcp_pcb *pcb; - struct snmp_next_oid_state state; - /* 1x tcpConnectionLocalAddressType + 1x OID len + 16x tcpConnectionLocalAddress + 1x tcpConnectionLocalPort - * 1x tcpConnectionRemAddressType + 1x OID len + 16x tcpConnectionRemAddress + 1x tcpConnectionRemPort */ - u32_t result_temp[38]; - u8_t i; - struct tcp_pcb ** const tcp_pcb_nonlisten_lists[] = {&tcp_bound_pcbs, &tcp_active_pcbs, &tcp_tw_pcbs}; - - LWIP_UNUSED_ARG(value_len); - - /* init struct to search next oid */ - snmp_next_oid_init(&state, row_oid->id, row_oid->len, result_temp, LWIP_ARRAYSIZE(result_temp)); - - /* iterate over all possible OIDs to find the next one */ - for (i = 0; i < LWIP_ARRAYSIZE(tcp_pcb_nonlisten_lists); i++) { - pcb = *tcp_pcb_nonlisten_lists[i]; - - while (pcb != NULL) { - u8_t idx = 0; - u32_t test_oid[LWIP_ARRAYSIZE(result_temp)]; - - /* tcpConnectionLocalAddressType + tcpConnectionLocalAddress + tcpConnectionLocalPort */ - idx += snmp_ip_port_to_oid(&pcb->local_ip, pcb->local_port, &test_oid[idx]); - - /* tcpConnectionRemAddressType + tcpConnectionRemAddress + tcpConnectionRemPort */ - idx += snmp_ip_port_to_oid(&pcb->remote_ip, pcb->remote_port, &test_oid[idx]); - - /* check generated OID: is it a candidate for the next one? */ - snmp_next_oid_check(&state, test_oid, idx, pcb); - - pcb = pcb->next; - } - } - - /* did we find a next one? */ - if (state.status == SNMP_NEXT_OID_STATUS_SUCCESS) { - snmp_oid_assign(row_oid, state.next_oid, state.next_oid_len); - /* fill in object properties */ - return tcp_ConnectionTable_get_cell_value_core(column, (struct tcp_pcb*)state.reference, value); - } else { - /* not found */ - return SNMP_ERR_NOSUCHINSTANCE; - } -} - -/* --- tcpListenerTable --- */ - -static snmp_err_t -tcp_ListenerTable_get_cell_value_core(const u32_t* column, union snmp_variant_value* value) -{ - /* all items except tcpListenerProcess are declared as not-accessible */ - switch (*column) { - case 4: /* tcpListenerProcess */ - value->u32 = 0; /* not supported */ - break; - default: - return SNMP_ERR_NOSUCHINSTANCE; - } - - return SNMP_ERR_NOERROR; -} - -static snmp_err_t -tcp_ListenerTable_get_cell_value(const u32_t* column, const u32_t* row_oid, u8_t row_oid_len, union snmp_variant_value* value, u32_t* value_len) -{ - ip_addr_t local_ip; - u16_t local_port; - struct tcp_pcb_listen *pcb; - u8_t idx = 0; - - LWIP_UNUSED_ARG(value_len); - - /* tcpListenerLocalAddressType + tcpListenerLocalAddress + tcpListenerLocalPort */ - idx += snmp_oid_to_ip_port(&row_oid[idx], row_oid_len-idx, &local_ip, &local_port); - if (idx == 0) { - return SNMP_ERR_NOSUCHINSTANCE; - } - - /* find tcp_pcb with requested ip and port*/ - pcb = tcp_listen_pcbs.listen_pcbs; - while (pcb != NULL) { - if (ip_addr_cmp(&local_ip, &pcb->local_ip) && - (local_port == pcb->local_port)) { - /* fill in object properties */ - return tcp_ListenerTable_get_cell_value_core(column, value); - } - pcb = pcb->next; - } - - /* not found */ - return SNMP_ERR_NOSUCHINSTANCE; -} - -static snmp_err_t -tcp_ListenerTable_get_next_cell_instance_and_value(const u32_t* column, struct snmp_obj_id* row_oid, union snmp_variant_value* value, u32_t* value_len) -{ - struct tcp_pcb_listen *pcb; - struct snmp_next_oid_state state; - /* 1x tcpListenerLocalAddressType + 1x OID len + 16x tcpListenerLocalAddress + 1x tcpListenerLocalPort */ - u32_t result_temp[19]; - - LWIP_UNUSED_ARG(value_len); - - /* init struct to search next oid */ - snmp_next_oid_init(&state, row_oid->id, row_oid->len, result_temp, LWIP_ARRAYSIZE(result_temp)); - - /* iterate over all possible OIDs to find the next one */ - pcb = tcp_listen_pcbs.listen_pcbs; - while (pcb != NULL) { - u8_t idx = 0; - u32_t test_oid[LWIP_ARRAYSIZE(result_temp)]; - - /* tcpListenerLocalAddressType + tcpListenerLocalAddress + tcpListenerLocalPort */ - idx += snmp_ip_port_to_oid(&pcb->local_ip, pcb->local_port, &test_oid[idx]); - - /* check generated OID: is it a candidate for the next one? */ - snmp_next_oid_check(&state, test_oid, idx, NULL); - - pcb = pcb->next; - } - - /* did we find a next one? */ - if (state.status == SNMP_NEXT_OID_STATUS_SUCCESS) { - snmp_oid_assign(row_oid, state.next_oid, state.next_oid_len); - /* fill in object properties */ - return tcp_ListenerTable_get_cell_value_core(column, value); - } else { - /* not found */ - return SNMP_ERR_NOSUCHINSTANCE; - } -} - -static const struct snmp_scalar_node tcp_RtoAlgorithm = SNMP_SCALAR_CREATE_NODE_READONLY(1, SNMP_ASN1_TYPE_INTEGER, tcp_get_value); -static const struct snmp_scalar_node tcp_RtoMin = SNMP_SCALAR_CREATE_NODE_READONLY(2, SNMP_ASN1_TYPE_INTEGER, tcp_get_value); -static const struct snmp_scalar_node tcp_RtoMax = SNMP_SCALAR_CREATE_NODE_READONLY(3, SNMP_ASN1_TYPE_INTEGER, tcp_get_value); -static const struct snmp_scalar_node tcp_MaxConn = SNMP_SCALAR_CREATE_NODE_READONLY(4, SNMP_ASN1_TYPE_INTEGER, tcp_get_value); -static const struct snmp_scalar_node tcp_ActiveOpens = SNMP_SCALAR_CREATE_NODE_READONLY(5, SNMP_ASN1_TYPE_COUNTER, tcp_get_value); -static const struct snmp_scalar_node tcp_PassiveOpens = SNMP_SCALAR_CREATE_NODE_READONLY(6, SNMP_ASN1_TYPE_COUNTER, tcp_get_value); -static const struct snmp_scalar_node tcp_AttemptFails = SNMP_SCALAR_CREATE_NODE_READONLY(7, SNMP_ASN1_TYPE_COUNTER, tcp_get_value); -static const struct snmp_scalar_node tcp_EstabResets = SNMP_SCALAR_CREATE_NODE_READONLY(8, SNMP_ASN1_TYPE_COUNTER, tcp_get_value); -static const struct snmp_scalar_node tcp_CurrEstab = SNMP_SCALAR_CREATE_NODE_READONLY(9, SNMP_ASN1_TYPE_GAUGE, tcp_get_value); -static const struct snmp_scalar_node tcp_InSegs = SNMP_SCALAR_CREATE_NODE_READONLY(10, SNMP_ASN1_TYPE_COUNTER, tcp_get_value); -static const struct snmp_scalar_node tcp_OutSegs = SNMP_SCALAR_CREATE_NODE_READONLY(11, SNMP_ASN1_TYPE_COUNTER, tcp_get_value); -static const struct snmp_scalar_node tcp_RetransSegs = SNMP_SCALAR_CREATE_NODE_READONLY(12, SNMP_ASN1_TYPE_COUNTER, tcp_get_value); -static const struct snmp_scalar_node tcp_InErrs = SNMP_SCALAR_CREATE_NODE_READONLY(14, SNMP_ASN1_TYPE_COUNTER, tcp_get_value); -static const struct snmp_scalar_node tcp_OutRsts = SNMP_SCALAR_CREATE_NODE_READONLY(15, SNMP_ASN1_TYPE_COUNTER, tcp_get_value); -static const struct snmp_scalar_node tcp_HCInSegs = SNMP_SCALAR_CREATE_NODE_READONLY(17, SNMP_ASN1_TYPE_COUNTER64, tcp_get_value); -static const struct snmp_scalar_node tcp_HCOutSegs = SNMP_SCALAR_CREATE_NODE_READONLY(18, SNMP_ASN1_TYPE_COUNTER64, tcp_get_value); - -#if LWIP_IPV4 -static const struct snmp_table_simple_col_def tcp_ConnTable_columns[] = { - { 1, SNMP_ASN1_TYPE_INTEGER, SNMP_VARIANT_VALUE_TYPE_U32 }, /* tcpConnState */ - { 2, SNMP_ASN1_TYPE_IPADDR, SNMP_VARIANT_VALUE_TYPE_U32 }, /* tcpConnLocalAddress */ - { 3, SNMP_ASN1_TYPE_INTEGER, SNMP_VARIANT_VALUE_TYPE_U32 }, /* tcpConnLocalPort */ - { 4, SNMP_ASN1_TYPE_IPADDR, SNMP_VARIANT_VALUE_TYPE_U32 }, /* tcpConnRemAddress */ - { 5, SNMP_ASN1_TYPE_INTEGER, SNMP_VARIANT_VALUE_TYPE_U32 } /* tcpConnRemPort */ -}; - -static const struct snmp_table_simple_node tcp_ConnTable = SNMP_TABLE_CREATE_SIMPLE(13, tcp_ConnTable_columns, tcp_ConnTable_get_cell_value, tcp_ConnTable_get_next_cell_instance_and_value); -#endif /* LWIP_IPV4 */ - -static const struct snmp_table_simple_col_def tcp_ConnectionTable_columns[] = { - /* all items except tcpConnectionState and tcpConnectionProcess are declared as not-accessible */ - { 7, SNMP_ASN1_TYPE_INTEGER, SNMP_VARIANT_VALUE_TYPE_U32 }, /* tcpConnectionState */ - { 8, SNMP_ASN1_TYPE_UNSIGNED32, SNMP_VARIANT_VALUE_TYPE_U32 } /* tcpConnectionProcess */ -}; - -static const struct snmp_table_simple_node tcp_ConnectionTable = SNMP_TABLE_CREATE_SIMPLE(19, tcp_ConnectionTable_columns, tcp_ConnectionTable_get_cell_value, tcp_ConnectionTable_get_next_cell_instance_and_value); - - -static const struct snmp_table_simple_col_def tcp_ListenerTable_columns[] = { - /* all items except tcpListenerProcess are declared as not-accessible */ - { 4, SNMP_ASN1_TYPE_UNSIGNED32, SNMP_VARIANT_VALUE_TYPE_U32 } /* tcpListenerProcess */ -}; - -static const struct snmp_table_simple_node tcp_ListenerTable = SNMP_TABLE_CREATE_SIMPLE(20, tcp_ListenerTable_columns, tcp_ListenerTable_get_cell_value, tcp_ListenerTable_get_next_cell_instance_and_value); - -/* the following nodes access variables in LWIP stack from SNMP worker thread and must therefore be synced to LWIP (TCPIP) thread */ -CREATE_LWIP_SYNC_NODE( 1, tcp_RtoAlgorithm) -CREATE_LWIP_SYNC_NODE( 2, tcp_RtoMin) -CREATE_LWIP_SYNC_NODE( 3, tcp_RtoMax) -CREATE_LWIP_SYNC_NODE( 4, tcp_MaxConn) -CREATE_LWIP_SYNC_NODE( 5, tcp_ActiveOpens) -CREATE_LWIP_SYNC_NODE( 6, tcp_PassiveOpens) -CREATE_LWIP_SYNC_NODE( 7, tcp_AttemptFails) -CREATE_LWIP_SYNC_NODE( 8, tcp_EstabResets) -CREATE_LWIP_SYNC_NODE( 9, tcp_CurrEstab) -CREATE_LWIP_SYNC_NODE(10, tcp_InSegs) -CREATE_LWIP_SYNC_NODE(11, tcp_OutSegs) -CREATE_LWIP_SYNC_NODE(12, tcp_RetransSegs) -#if LWIP_IPV4 -CREATE_LWIP_SYNC_NODE(13, tcp_ConnTable) -#endif /* LWIP_IPV4 */ -CREATE_LWIP_SYNC_NODE(14, tcp_InErrs) -CREATE_LWIP_SYNC_NODE(15, tcp_OutRsts) -CREATE_LWIP_SYNC_NODE(17, tcp_HCInSegs) -CREATE_LWIP_SYNC_NODE(18, tcp_HCOutSegs) -CREATE_LWIP_SYNC_NODE(19, tcp_ConnectionTable) -CREATE_LWIP_SYNC_NODE(20, tcp_ListenerTable) - -static const struct snmp_node* const tcp_nodes[] = { - &SYNC_NODE_NAME(tcp_RtoAlgorithm).node.node, - &SYNC_NODE_NAME(tcp_RtoMin).node.node, - &SYNC_NODE_NAME(tcp_RtoMax).node.node, - &SYNC_NODE_NAME(tcp_MaxConn).node.node, - &SYNC_NODE_NAME(tcp_ActiveOpens).node.node, - &SYNC_NODE_NAME(tcp_PassiveOpens).node.node, - &SYNC_NODE_NAME(tcp_AttemptFails).node.node, - &SYNC_NODE_NAME(tcp_EstabResets).node.node, - &SYNC_NODE_NAME(tcp_CurrEstab).node.node, - &SYNC_NODE_NAME(tcp_InSegs).node.node, - &SYNC_NODE_NAME(tcp_OutSegs).node.node, - &SYNC_NODE_NAME(tcp_RetransSegs).node.node, -#if LWIP_IPV4 - &SYNC_NODE_NAME(tcp_ConnTable).node.node, -#endif /* LWIP_IPV4 */ - &SYNC_NODE_NAME(tcp_InErrs).node.node, - &SYNC_NODE_NAME(tcp_OutRsts).node.node, - &SYNC_NODE_NAME(tcp_HCInSegs).node.node, - &SYNC_NODE_NAME(tcp_HCOutSegs).node.node, - &SYNC_NODE_NAME(tcp_ConnectionTable).node.node, - &SYNC_NODE_NAME(tcp_ListenerTable).node.node -}; - -const struct snmp_tree_node snmp_mib2_tcp_root = SNMP_CREATE_TREE_NODE(6, tcp_nodes); -#endif /* LWIP_SNMP && SNMP_LWIP_MIB2 && LWIP_TCP */ diff --git a/third_party/lwip/repo/lwip/src/apps/snmp/snmp_mib2_udp.c b/third_party/lwip/repo/lwip/src/apps/snmp/snmp_mib2_udp.c deleted file mode 100644 index 6a983df20bbaa3..00000000000000 --- a/third_party/lwip/repo/lwip/src/apps/snmp/snmp_mib2_udp.c +++ /dev/null @@ -1,357 +0,0 @@ -/** - * @file - * Management Information Base II (RFC1213) UDP objects and functions. - */ - -/* - * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * Author: Dirk Ziegelmeier - * Christiaan Simons - */ - -#include "lwip/snmp.h" -#include "lwip/apps/snmp.h" -#include "lwip/apps/snmp_core.h" -#include "lwip/apps/snmp_mib2.h" -#include "lwip/apps/snmp_table.h" -#include "lwip/apps/snmp_scalar.h" -#include "lwip/udp.h" -#include "lwip/stats.h" - -#include - -#if LWIP_SNMP && SNMP_LWIP_MIB2 && LWIP_UDP - -#if SNMP_USE_NETCONN -#define SYNC_NODE_NAME(node_name) node_name ## _synced -#define CREATE_LWIP_SYNC_NODE(oid, node_name) \ - static const struct snmp_threadsync_node node_name ## _synced = SNMP_CREATE_THREAD_SYNC_NODE(oid, &node_name.node, &snmp_mib2_lwip_locks); -#else -#define SYNC_NODE_NAME(node_name) node_name -#define CREATE_LWIP_SYNC_NODE(oid, node_name) -#endif - -/* --- udp .1.3.6.1.2.1.7 ----------------------------------------------------- */ - -static s16_t -udp_get_value(struct snmp_node_instance* instance, void* value) -{ - u32_t *uint_ptr = (u32_t*)value; - - switch (instance->node->oid) { - case 1: /* udpInDatagrams */ - *uint_ptr = STATS_GET(mib2.udpindatagrams); - return sizeof(*uint_ptr); - case 2: /* udpNoPorts */ - *uint_ptr = STATS_GET(mib2.udpnoports); - return sizeof(*uint_ptr); - case 3: /* udpInErrors */ - *uint_ptr = STATS_GET(mib2.udpinerrors); - return sizeof(*uint_ptr); - case 4: /* udpOutDatagrams */ - *uint_ptr = STATS_GET(mib2.udpoutdatagrams); - return sizeof(*uint_ptr); - case 8: /* udpHCInDatagrams */ - memset(value, 0, 2*sizeof(u32_t)); /* not supported */ - return 2*sizeof(u32_t); - case 9: /* udpHCOutDatagrams */ - memset(value, 0, 2*sizeof(u32_t)); /* not supported */ - return 2*sizeof(u32_t); - default: - LWIP_DEBUGF(SNMP_MIB_DEBUG,("udp_get_value(): unknown id: %"S32_F"\n", instance->node->oid)); - break; - } - - return 0; -} - -/* --- udpEndpointTable --- */ - -static snmp_err_t -udp_endpointTable_get_cell_value_core(const u32_t* column, union snmp_variant_value* value) -{ - /* all items except udpEndpointProcess are declared as not-accessible */ - switch (*column) { - case 8: /* udpEndpointProcess */ - value->u32 = 0; /* not supported */ - break; - default: - return SNMP_ERR_NOSUCHINSTANCE; - } - - return SNMP_ERR_NOERROR; -} - -static snmp_err_t -udp_endpointTable_get_cell_value(const u32_t* column, const u32_t* row_oid, u8_t row_oid_len, union snmp_variant_value* value, u32_t* value_len) -{ - ip_addr_t local_ip, remote_ip; - u16_t local_port, remote_port; - struct udp_pcb *pcb; - u8_t idx = 0; - - LWIP_UNUSED_ARG(value_len); - - /* udpEndpointLocalAddressType + udpEndpointLocalAddress + udpEndpointLocalPort */ - idx += snmp_oid_to_ip_port(&row_oid[idx], row_oid_len-idx, &local_ip, &local_port); - if (idx == 0) { - return SNMP_ERR_NOSUCHINSTANCE; - } - - /* udpEndpointRemoteAddressType + udpEndpointRemoteAddress + udpEndpointRemotePort */ - idx += snmp_oid_to_ip_port(&row_oid[idx], row_oid_len-idx, &remote_ip, &remote_port); - if (idx == 0) { - return SNMP_ERR_NOSUCHINSTANCE; - } - - /* udpEndpointInstance */ - if (row_oid_len < (idx+1)) { - return SNMP_ERR_NOSUCHINSTANCE; - } - if (row_oid[idx] != 0) { - return SNMP_ERR_NOSUCHINSTANCE; - } - - /* find udp_pcb with requested ip and port*/ - pcb = udp_pcbs; - while (pcb != NULL) { - if (ip_addr_cmp(&local_ip, &pcb->local_ip) && - (local_port == pcb->local_port) && - ip_addr_cmp(&remote_ip, &pcb->remote_ip) && - (remote_port == pcb->remote_port)) { - /* fill in object properties */ - return udp_endpointTable_get_cell_value_core(column, value); - } - pcb = pcb->next; - } - - /* not found */ - return SNMP_ERR_NOSUCHINSTANCE; -} - -static snmp_err_t -udp_endpointTable_get_next_cell_instance_and_value(const u32_t* column, struct snmp_obj_id* row_oid, union snmp_variant_value* value, u32_t* value_len) -{ - struct udp_pcb *pcb; - struct snmp_next_oid_state state; - /* 1x udpEndpointLocalAddressType + 1x OID len + 16x udpEndpointLocalAddress + 1x udpEndpointLocalPort + - * 1x udpEndpointRemoteAddressType + 1x OID len + 16x udpEndpointRemoteAddress + 1x udpEndpointRemotePort + - * 1x udpEndpointInstance = 39 - */ - u32_t result_temp[39]; - - LWIP_UNUSED_ARG(value_len); - - /* init struct to search next oid */ - snmp_next_oid_init(&state, row_oid->id, row_oid->len, result_temp, LWIP_ARRAYSIZE(result_temp)); - - /* iterate over all possible OIDs to find the next one */ - pcb = udp_pcbs; - while (pcb != NULL) { - u32_t test_oid[LWIP_ARRAYSIZE(result_temp)]; - u8_t idx = 0; - - /* udpEndpointLocalAddressType + udpEndpointLocalAddress + udpEndpointLocalPort */ - idx += snmp_ip_port_to_oid(&pcb->local_ip, pcb->local_port, &test_oid[idx]); - - /* udpEndpointRemoteAddressType + udpEndpointRemoteAddress + udpEndpointRemotePort */ - idx += snmp_ip_port_to_oid(&pcb->remote_ip, pcb->remote_port, &test_oid[idx]); - - test_oid[idx] = 0; /* udpEndpointInstance */ - idx++; - - /* check generated OID: is it a candidate for the next one? */ - snmp_next_oid_check(&state, test_oid, idx, NULL); - - pcb = pcb->next; - } - - /* did we find a next one? */ - if (state.status == SNMP_NEXT_OID_STATUS_SUCCESS) { - snmp_oid_assign(row_oid, state.next_oid, state.next_oid_len); - /* fill in object properties */ - return udp_endpointTable_get_cell_value_core(column, value); - } else { - /* not found */ - return SNMP_ERR_NOSUCHINSTANCE; - } -} - -/* --- udpTable --- */ - -#if LWIP_IPV4 - -/* list of allowed value ranges for incoming OID */ -static const struct snmp_oid_range udp_Table_oid_ranges[] = { - { 0, 0xff }, /* IP A */ - { 0, 0xff }, /* IP B */ - { 0, 0xff }, /* IP C */ - { 0, 0xff }, /* IP D */ - { 1, 0xffff } /* Port */ -}; - -static snmp_err_t -udp_Table_get_cell_value_core(struct udp_pcb *pcb, const u32_t* column, union snmp_variant_value* value, u32_t* value_len) -{ - LWIP_UNUSED_ARG(value_len); - - switch (*column) { - case 1: /* udpLocalAddress */ - /* set reference to PCB local IP and return a generic node that copies IP4 addresses */ - value->u32 = ip_2_ip4(&pcb->local_ip)->addr; - break; - case 2: /* udpLocalPort */ - /* set reference to PCB local port and return a generic node that copies u16_t values */ - value->u32 = pcb->local_port; - break; - default: - return SNMP_ERR_NOSUCHINSTANCE; - } - - return SNMP_ERR_NOERROR; -} - -static snmp_err_t -udp_Table_get_cell_value(const u32_t* column, const u32_t* row_oid, u8_t row_oid_len, union snmp_variant_value* value, u32_t* value_len) -{ - ip4_addr_t ip; - u16_t port; - struct udp_pcb *pcb; - - /* check if incoming OID length and if values are in plausible range */ - if (!snmp_oid_in_range(row_oid, row_oid_len, udp_Table_oid_ranges, LWIP_ARRAYSIZE(udp_Table_oid_ranges))) { - return SNMP_ERR_NOSUCHINSTANCE; - } - - /* get IP and port from incoming OID */ - snmp_oid_to_ip4(&row_oid[0], &ip); /* we know it succeeds because of oid_in_range check above */ - port = (u16_t)row_oid[4]; - - /* find udp_pcb with requested ip and port*/ - pcb = udp_pcbs; - while (pcb != NULL) { - if (IP_IS_V4_VAL(pcb->local_ip)) { - if (ip4_addr_cmp(&ip, ip_2_ip4(&pcb->local_ip)) && (port == pcb->local_port)) { - /* fill in object properties */ - return udp_Table_get_cell_value_core(pcb, column, value, value_len); - } - } - pcb = pcb->next; - } - - /* not found */ - return SNMP_ERR_NOSUCHINSTANCE; -} - -static snmp_err_t -udp_Table_get_next_cell_instance_and_value(const u32_t* column, struct snmp_obj_id* row_oid, union snmp_variant_value* value, u32_t* value_len) -{ - struct udp_pcb *pcb; - struct snmp_next_oid_state state; - u32_t result_temp[LWIP_ARRAYSIZE(udp_Table_oid_ranges)]; - - /* init struct to search next oid */ - snmp_next_oid_init(&state, row_oid->id, row_oid->len, result_temp, LWIP_ARRAYSIZE(udp_Table_oid_ranges)); - - /* iterate over all possible OIDs to find the next one */ - pcb = udp_pcbs; - while (pcb != NULL) { - u32_t test_oid[LWIP_ARRAYSIZE(udp_Table_oid_ranges)]; - - if (IP_IS_V4_VAL(pcb->local_ip)) { - snmp_ip4_to_oid(ip_2_ip4(&pcb->local_ip), &test_oid[0]); - test_oid[4] = pcb->local_port; - - /* check generated OID: is it a candidate for the next one? */ - snmp_next_oid_check(&state, test_oid, LWIP_ARRAYSIZE(udp_Table_oid_ranges), pcb); - } - - pcb = pcb->next; - } - - /* did we find a next one? */ - if (state.status == SNMP_NEXT_OID_STATUS_SUCCESS) { - snmp_oid_assign(row_oid, state.next_oid, state.next_oid_len); - /* fill in object properties */ - return udp_Table_get_cell_value_core((struct udp_pcb*)state.reference, column, value, value_len); - } else { - /* not found */ - return SNMP_ERR_NOSUCHINSTANCE; - } -} - -#endif /* LWIP_IPV4 */ - -static const struct snmp_scalar_node udp_inDatagrams = SNMP_SCALAR_CREATE_NODE_READONLY(1, SNMP_ASN1_TYPE_COUNTER, udp_get_value); -static const struct snmp_scalar_node udp_noPorts = SNMP_SCALAR_CREATE_NODE_READONLY(2, SNMP_ASN1_TYPE_COUNTER, udp_get_value); -static const struct snmp_scalar_node udp_inErrors = SNMP_SCALAR_CREATE_NODE_READONLY(3, SNMP_ASN1_TYPE_COUNTER, udp_get_value); -static const struct snmp_scalar_node udp_outDatagrams = SNMP_SCALAR_CREATE_NODE_READONLY(4, SNMP_ASN1_TYPE_COUNTER, udp_get_value); -static const struct snmp_scalar_node udp_HCInDatagrams = SNMP_SCALAR_CREATE_NODE_READONLY(8, SNMP_ASN1_TYPE_COUNTER64, udp_get_value); -static const struct snmp_scalar_node udp_HCOutDatagrams = SNMP_SCALAR_CREATE_NODE_READONLY(9, SNMP_ASN1_TYPE_COUNTER64, udp_get_value); - -#if LWIP_IPV4 -static const struct snmp_table_simple_col_def udp_Table_columns[] = { - { 1, SNMP_ASN1_TYPE_IPADDR, SNMP_VARIANT_VALUE_TYPE_U32 }, /* udpLocalAddress */ - { 2, SNMP_ASN1_TYPE_INTEGER, SNMP_VARIANT_VALUE_TYPE_U32 } /* udpLocalPort */ -}; -static const struct snmp_table_simple_node udp_Table = SNMP_TABLE_CREATE_SIMPLE(5, udp_Table_columns, udp_Table_get_cell_value, udp_Table_get_next_cell_instance_and_value); -#endif /* LWIP_IPV4 */ - -static const struct snmp_table_simple_col_def udp_endpointTable_columns[] = { - /* all items except udpEndpointProcess are declared as not-accessible */ - { 8, SNMP_ASN1_TYPE_UNSIGNED32, SNMP_VARIANT_VALUE_TYPE_U32 } /* udpEndpointProcess */ -}; - -static const struct snmp_table_simple_node udp_endpointTable = SNMP_TABLE_CREATE_SIMPLE(7, udp_endpointTable_columns, udp_endpointTable_get_cell_value, udp_endpointTable_get_next_cell_instance_and_value); - -/* the following nodes access variables in LWIP stack from SNMP worker thread and must therefore be synced to LWIP (TCPIP) thread */ -CREATE_LWIP_SYNC_NODE(1, udp_inDatagrams) -CREATE_LWIP_SYNC_NODE(2, udp_noPorts) -CREATE_LWIP_SYNC_NODE(3, udp_inErrors) -CREATE_LWIP_SYNC_NODE(4, udp_outDatagrams) -#if LWIP_IPV4 -CREATE_LWIP_SYNC_NODE(5, udp_Table) -#endif /* LWIP_IPV4 */ -CREATE_LWIP_SYNC_NODE(7, udp_endpointTable) -CREATE_LWIP_SYNC_NODE(8, udp_HCInDatagrams) -CREATE_LWIP_SYNC_NODE(9, udp_HCOutDatagrams) - -static const struct snmp_node* const udp_nodes[] = { - &SYNC_NODE_NAME(udp_inDatagrams).node.node, - &SYNC_NODE_NAME(udp_noPorts).node.node, - &SYNC_NODE_NAME(udp_inErrors).node.node, - &SYNC_NODE_NAME(udp_outDatagrams).node.node, -#if LWIP_IPV4 - &SYNC_NODE_NAME(udp_Table).node.node, -#endif /* LWIP_IPV4 */ - &SYNC_NODE_NAME(udp_endpointTable).node.node, - &SYNC_NODE_NAME(udp_HCInDatagrams).node.node, - &SYNC_NODE_NAME(udp_HCOutDatagrams).node.node -}; - -const struct snmp_tree_node snmp_mib2_udp_root = SNMP_CREATE_TREE_NODE(7, udp_nodes); -#endif /* LWIP_SNMP && SNMP_LWIP_MIB2 && LWIP_UDP */ diff --git a/third_party/lwip/repo/lwip/src/apps/snmp/snmp_msg.c b/third_party/lwip/repo/lwip/src/apps/snmp/snmp_msg.c deleted file mode 100644 index 0cb7ca997cad6c..00000000000000 --- a/third_party/lwip/repo/lwip/src/apps/snmp/snmp_msg.c +++ /dev/null @@ -1,1668 +0,0 @@ -/** - * @file - * SNMP message processing (RFC1157). - */ - -/* - * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands. - * Copyright (c) 2016 Elias Oenal. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * Author: Christiaan Simons - * Martin Hentschel - * Elias Oenal - */ - -#include "lwip/apps/snmp_opts.h" - -#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */ - -#include "snmp_msg.h" -#include "snmp_asn1.h" -#include "snmp_core_priv.h" -#include "lwip/ip_addr.h" -#include "lwip/stats.h" - -#if LWIP_SNMP_V3 -#include "lwip/apps/snmpv3.h" -#include "snmpv3_priv.h" -#ifdef LWIP_SNMPV3_INCLUDE_ENGINE -#include LWIP_SNMPV3_INCLUDE_ENGINE -#endif -#endif - -#include - -/* public (non-static) constants */ -/** SNMP community string */ -const char *snmp_community = SNMP_COMMUNITY; -/** SNMP community string for write access */ -const char *snmp_community_write = SNMP_COMMUNITY_WRITE; -/** SNMP community string for sending traps */ -const char *snmp_community_trap = SNMP_COMMUNITY_TRAP; - -snmp_write_callback_fct snmp_write_callback = NULL; -void* snmp_write_callback_arg = NULL; - -/** - * @ingroup snmp_core - * Returns current SNMP community string. - * @return current SNMP community string - */ -const char * -snmp_get_community(void) -{ - return snmp_community; -} - -/** - * @ingroup snmp_core - * Sets SNMP community string. - * The string itself (its storage) must be valid throughout the whole life of - * program (or until it is changed to sth else). - * - * @param community is a pointer to new community string - */ -void -snmp_set_community(const char * const community) -{ - LWIP_ASSERT("community string is too long!", strlen(community) <= SNMP_MAX_COMMUNITY_STR_LEN); - snmp_community = community; -} - -/** - * @ingroup snmp_core - * Returns current SNMP write-access community string. - * @return current SNMP write-access community string - */ -const char * -snmp_get_community_write(void) -{ - return snmp_community_write; -} - -/** - * @ingroup snmp_traps - * Returns current SNMP community string used for sending traps. - * @return current SNMP community string used for sending traps - */ -const char * -snmp_get_community_trap(void) -{ - return snmp_community_trap; -} - -/** - * @ingroup snmp_core - * Sets SNMP community string for write-access. - * The string itself (its storage) must be valid throughout the whole life of - * program (or until it is changed to sth else). - * - * @param community is a pointer to new write-access community string - */ -void -snmp_set_community_write(const char * const community) -{ - LWIP_ASSERT("community string must not be NULL", community != NULL); - LWIP_ASSERT("community string is too long!", strlen(community) <= SNMP_MAX_COMMUNITY_STR_LEN); - snmp_community_write = community; -} - -/** - * @ingroup snmp_traps - * Sets SNMP community string used for sending traps. - * The string itself (its storage) must be valid throughout the whole life of - * program (or until it is changed to sth else). - * - * @param community is a pointer to new trap community string - */ -void -snmp_set_community_trap(const char * const community) -{ - LWIP_ASSERT("community string is too long!", strlen(community) <= SNMP_MAX_COMMUNITY_STR_LEN); - snmp_community_trap = community; -} - -/** - * @ingroup snmp_core - * Callback fired on every successful write access - */ -void -snmp_set_write_callback(snmp_write_callback_fct write_callback, void* callback_arg) -{ - snmp_write_callback = write_callback; - snmp_write_callback_arg = callback_arg; -} - -/* ----------------------------------------------------------------------- */ -/* forward declarations */ -/* ----------------------------------------------------------------------- */ - -static err_t snmp_process_get_request(struct snmp_request *request); -static err_t snmp_process_getnext_request(struct snmp_request *request); -static err_t snmp_process_getbulk_request(struct snmp_request *request); -static err_t snmp_process_set_request(struct snmp_request *request); - -static err_t snmp_parse_inbound_frame(struct snmp_request *request); -static err_t snmp_prepare_outbound_frame(struct snmp_request *request); -static err_t snmp_complete_outbound_frame(struct snmp_request *request); -static void snmp_execute_write_callbacks(struct snmp_request *request); - - -/* ----------------------------------------------------------------------- */ -/* implementation */ -/* ----------------------------------------------------------------------- */ - -void -snmp_receive(void *handle, struct pbuf *p, const ip_addr_t *source_ip, u16_t port) -{ - err_t err; - struct snmp_request request; - - memset(&request, 0, sizeof(request)); - request.handle = handle; - request.source_ip = source_ip; - request.source_port = port; - request.inbound_pbuf = p; - - snmp_stats.inpkts++; - - err = snmp_parse_inbound_frame(&request); - if (err == ERR_OK) { - err = snmp_prepare_outbound_frame(&request); - if (err == ERR_OK) { - - if (request.error_status == SNMP_ERR_NOERROR) { - /* only process frame if we do not already have an error to return (e.g. all readonly) */ - if (request.request_type == SNMP_ASN1_CONTEXT_PDU_GET_REQ) { - err = snmp_process_get_request(&request); - } else if (request.request_type == SNMP_ASN1_CONTEXT_PDU_GET_NEXT_REQ) { - err = snmp_process_getnext_request(&request); - } else if (request.request_type == SNMP_ASN1_CONTEXT_PDU_GET_BULK_REQ) { - err = snmp_process_getbulk_request(&request); - } else if (request.request_type == SNMP_ASN1_CONTEXT_PDU_SET_REQ) { - err = snmp_process_set_request(&request); - } - } - - if (err == ERR_OK) { - err = snmp_complete_outbound_frame(&request); - - if (err == ERR_OK) { - err = snmp_sendto(request.handle, request.outbound_pbuf, request.source_ip, request.source_port); - - if ((request.request_type == SNMP_ASN1_CONTEXT_PDU_SET_REQ) - && (request.error_status == SNMP_ERR_NOERROR) - && (snmp_write_callback != NULL)) { - /* raise write notification for all written objects */ - snmp_execute_write_callbacks(&request); - } - } - } - } - - if (request.outbound_pbuf != NULL) { - pbuf_free(request.outbound_pbuf); - } - } -} - -static u8_t -snmp_msg_getnext_validate_node_inst(struct snmp_node_instance* node_instance, void* validate_arg) -{ - if (((node_instance->access & SNMP_NODE_INSTANCE_ACCESS_READ) != SNMP_NODE_INSTANCE_ACCESS_READ) || (node_instance->get_value == NULL)) { - return SNMP_ERR_NOSUCHINSTANCE; - } - - if ((node_instance->asn1_type == SNMP_ASN1_TYPE_COUNTER64) && (((struct snmp_request*)validate_arg)->version == SNMP_VERSION_1)) { - /* according to RFC 2089 skip Counter64 objects in GetNext requests from v1 clients */ - return SNMP_ERR_NOSUCHINSTANCE; - } - - return SNMP_ERR_NOERROR; -} - -static void -snmp_process_varbind(struct snmp_request *request, struct snmp_varbind *vb, u8_t get_next) -{ - err_t err; - struct snmp_node_instance node_instance; - memset(&node_instance, 0, sizeof(node_instance)); - - if (get_next) { - struct snmp_obj_id result_oid; - request->error_status = snmp_get_next_node_instance_from_oid(vb->oid.id, vb->oid.len, snmp_msg_getnext_validate_node_inst, request, &result_oid, &node_instance); - - if (request->error_status == SNMP_ERR_NOERROR) { - snmp_oid_assign(&vb->oid, result_oid.id, result_oid.len); - } - } else { - request->error_status = snmp_get_node_instance_from_oid(vb->oid.id, vb->oid.len, &node_instance); - - if (request->error_status == SNMP_ERR_NOERROR) { - /* use 'getnext_validate' method for validation to avoid code duplication (some checks have to be executed here) */ - request->error_status = snmp_msg_getnext_validate_node_inst(&node_instance, request); - - if (request->error_status != SNMP_ERR_NOERROR) { - if (node_instance.release_instance != NULL) { - node_instance.release_instance(&node_instance); - } - } - } - } - - if (request->error_status != SNMP_ERR_NOERROR) { - if (request->error_status >= SNMP_VARBIND_EXCEPTION_OFFSET) { - if ((request->version == SNMP_VERSION_2c) || request->version == SNMP_VERSION_3) { - /* in SNMP v2c a varbind related exception is stored in varbind and not in frame header */ - vb->type = (SNMP_ASN1_CONTENTTYPE_PRIMITIVE | SNMP_ASN1_CLASS_CONTEXT | (request->error_status & SNMP_VARBIND_EXCEPTION_MASK)); - vb->value_len = 0; - - err = snmp_append_outbound_varbind(&(request->outbound_pbuf_stream), vb); - if (err == ERR_OK) { - /* we stored the exception in varbind -> go on */ - request->error_status = SNMP_ERR_NOERROR; - } else if (err == ERR_BUF) { - request->error_status = SNMP_ERR_TOOBIG; - } else { - request->error_status = SNMP_ERR_GENERROR; - } - } - } else { - /* according to RFC 1157/1905, all other errors only return genError */ - request->error_status = SNMP_ERR_GENERROR; - } - } else { - s16_t len = node_instance.get_value(&node_instance, vb->value); - vb->type = node_instance.asn1_type; - - if(len >= 0) { - vb->value_len = (u16_t)len; /* cast is OK because we checked >= 0 above */ - - LWIP_ASSERT("SNMP_MAX_VALUE_SIZE is configured too low", (vb->value_len & ~SNMP_GET_VALUE_RAW_DATA) <= SNMP_MAX_VALUE_SIZE); - err = snmp_append_outbound_varbind(&request->outbound_pbuf_stream, vb); - - if (err == ERR_BUF) { - request->error_status = SNMP_ERR_TOOBIG; - } else if (err != ERR_OK) { - request->error_status = SNMP_ERR_GENERROR; - } - } else { - request->error_status = SNMP_ERR_GENERROR; - } - - if (node_instance.release_instance != NULL) { - node_instance.release_instance(&node_instance); - } - } -} - - -/** - * Service an internal or external event for SNMP GET. - * - * @param request points to the associated message process state - */ -static err_t -snmp_process_get_request(struct snmp_request *request) -{ - snmp_vb_enumerator_err_t err; - struct snmp_varbind vb; - vb.value = request->value_buffer; - - LWIP_DEBUGF(SNMP_DEBUG, ("SNMP get request\n")); - - while (request->error_status == SNMP_ERR_NOERROR) { - err = snmp_vb_enumerator_get_next(&request->inbound_varbind_enumerator, &vb); - if (err == SNMP_VB_ENUMERATOR_ERR_OK) { - if ((vb.type == SNMP_ASN1_TYPE_NULL) && (vb.value_len == 0)) { - snmp_process_varbind(request, &vb, 0); - } else { - request->error_status = SNMP_ERR_GENERROR; - } - } else if (err == SNMP_VB_ENUMERATOR_ERR_EOVB) { - /* no more varbinds in request */ - break; - } else if (err == SNMP_VB_ENUMERATOR_ERR_ASN1ERROR) { - /* malformed ASN.1, don't answer */ - return ERR_ARG; - } else { - request->error_status = SNMP_ERR_GENERROR; - } - } - - return ERR_OK; -} - -/** - * Service an internal or external event for SNMP GET. - * - * @param request points to the associated message process state - */ -static err_t -snmp_process_getnext_request(struct snmp_request *request) -{ - snmp_vb_enumerator_err_t err; - struct snmp_varbind vb; - vb.value = request->value_buffer; - - LWIP_DEBUGF(SNMP_DEBUG, ("SNMP get-next request\n")); - - while (request->error_status == SNMP_ERR_NOERROR) { - err = snmp_vb_enumerator_get_next(&request->inbound_varbind_enumerator, &vb); - if (err == SNMP_VB_ENUMERATOR_ERR_OK) { - if ((vb.type == SNMP_ASN1_TYPE_NULL) && (vb.value_len == 0)) { - snmp_process_varbind(request, &vb, 1); - } else { - request->error_status = SNMP_ERR_GENERROR; - } - } else if (err == SNMP_VB_ENUMERATOR_ERR_EOVB) { - /* no more varbinds in request */ - break; - } else if (err == SNMP_VB_ENUMERATOR_ERR_ASN1ERROR) { - /* malformed ASN.1, don't answer */ - return ERR_ARG; - } else { - request->error_status = SNMP_ERR_GENERROR; - } - } - - return ERR_OK; -} - -/** - * Service an internal or external event for SNMP GETBULKT. - * - * @param request points to the associated message process state - */ -static err_t -snmp_process_getbulk_request(struct snmp_request *request) -{ - snmp_vb_enumerator_err_t err; - s32_t non_repeaters = request->non_repeaters; - s32_t repetitions; - u16_t repetition_offset = 0; - struct snmp_varbind_enumerator repetition_varbind_enumerator; - struct snmp_varbind vb; - vb.value = request->value_buffer; - - if (SNMP_LWIP_GETBULK_MAX_REPETITIONS > 0) { - repetitions = LWIP_MIN(request->max_repetitions, SNMP_LWIP_GETBULK_MAX_REPETITIONS); - } else { - repetitions = request->max_repetitions; - } - - LWIP_DEBUGF(SNMP_DEBUG, ("SNMP get-bulk request\n")); - - /* process non repeaters and first repetition */ - while (request->error_status == SNMP_ERR_NOERROR) { - if (non_repeaters == 0) { - repetition_offset = request->outbound_pbuf_stream.offset; - - if (repetitions == 0) { - /* do not resolve repeaters when repetitions is set to 0 */ - break; - } - repetitions--; - } - - err = snmp_vb_enumerator_get_next(&request->inbound_varbind_enumerator, &vb); - if (err == SNMP_VB_ENUMERATOR_ERR_EOVB) { - /* no more varbinds in request */ - break; - } else if (err == SNMP_VB_ENUMERATOR_ERR_ASN1ERROR) { - /* malformed ASN.1, don't answer */ - return ERR_ARG; - } else if ((err != SNMP_VB_ENUMERATOR_ERR_OK) || (vb.type != SNMP_ASN1_TYPE_NULL) || (vb.value_len != 0)) { - request->error_status = SNMP_ERR_GENERROR; - } else { - snmp_process_varbind(request, &vb, 1); - non_repeaters--; - } - } - - /* process repetitions > 1 */ - while ((request->error_status == SNMP_ERR_NOERROR) && (repetitions > 0) && (request->outbound_pbuf_stream.offset != repetition_offset)) { - - u8_t all_endofmibview = 1; - - snmp_vb_enumerator_init(&repetition_varbind_enumerator, request->outbound_pbuf, repetition_offset, request->outbound_pbuf_stream.offset - repetition_offset); - repetition_offset = request->outbound_pbuf_stream.offset; /* for next loop */ - - while (request->error_status == SNMP_ERR_NOERROR) { - vb.value = NULL; /* do NOT decode value (we enumerate outbound buffer here, so all varbinds have values assigned) */ - err = snmp_vb_enumerator_get_next(&repetition_varbind_enumerator, &vb); - if (err == SNMP_VB_ENUMERATOR_ERR_OK) { - vb.value = request->value_buffer; - snmp_process_varbind(request, &vb, 1); - - if (request->error_status != SNMP_ERR_NOERROR) { - /* already set correct error-index (here it cannot be taken from inbound varbind enumerator) */ - request->error_index = request->non_repeaters + repetition_varbind_enumerator.varbind_count; - } else if (vb.type != (SNMP_ASN1_CONTENTTYPE_PRIMITIVE | SNMP_ASN1_CLASS_CONTEXT | SNMP_ASN1_CONTEXT_VARBIND_END_OF_MIB_VIEW)) { - all_endofmibview = 0; - } - } else if (err == SNMP_VB_ENUMERATOR_ERR_EOVB) { - /* no more varbinds in request */ - break; - } else { - LWIP_DEBUGF(SNMP_DEBUG, ("Very strange, we cannot parse the varbind output that we created just before!")); - request->error_status = SNMP_ERR_GENERROR; - request->error_index = request->non_repeaters + repetition_varbind_enumerator.varbind_count; - } - } - - if ((request->error_status == SNMP_ERR_NOERROR) && all_endofmibview) { - /* stop when all varbinds in a loop return EndOfMibView */ - break; - } - - repetitions--; - } - - if (request->error_status == SNMP_ERR_TOOBIG) { - /* for GetBulk it is ok, if not all requested variables fit into the response -> just return the varbinds added so far */ - request->error_status = SNMP_ERR_NOERROR; - } - - return ERR_OK; -} - -/** - * Service an internal or external event for SNMP SET. - * - * @param request points to the associated message process state - */ -static err_t -snmp_process_set_request(struct snmp_request *request) -{ - snmp_vb_enumerator_err_t err; - struct snmp_varbind vb; - vb.value = request->value_buffer; - - LWIP_DEBUGF(SNMP_DEBUG, ("SNMP set request\n")); - - /* perform set test on all objects */ - while (request->error_status == SNMP_ERR_NOERROR) { - err = snmp_vb_enumerator_get_next(&request->inbound_varbind_enumerator, &vb); - if (err == SNMP_VB_ENUMERATOR_ERR_OK) { - struct snmp_node_instance node_instance; - memset(&node_instance, 0, sizeof(node_instance)); - - request->error_status = snmp_get_node_instance_from_oid(vb.oid.id, vb.oid.len, &node_instance); - if (request->error_status == SNMP_ERR_NOERROR) { - if (node_instance.asn1_type != vb.type) { - request->error_status = SNMP_ERR_WRONGTYPE; - } else if (((node_instance.access & SNMP_NODE_INSTANCE_ACCESS_WRITE) != SNMP_NODE_INSTANCE_ACCESS_WRITE) || (node_instance.set_value == NULL)) { - request->error_status = SNMP_ERR_NOTWRITABLE; - } else { - if (node_instance.set_test != NULL) { - request->error_status = node_instance.set_test(&node_instance, vb.value_len, vb.value); - } - } - - if (node_instance.release_instance != NULL) { - node_instance.release_instance(&node_instance); - } - } - } else if (err == SNMP_VB_ENUMERATOR_ERR_EOVB) { - /* no more varbinds in request */ - break; - } else if (err == SNMP_VB_ENUMERATOR_ERR_INVALIDLENGTH) { - request->error_status = SNMP_ERR_WRONGLENGTH; - } else if (err == SNMP_VB_ENUMERATOR_ERR_ASN1ERROR) { - /* malformed ASN.1, don't answer */ - return ERR_ARG; - } else { - request->error_status = SNMP_ERR_GENERROR; - } - } - - /* perform real set operation on all objects */ - if (request->error_status == SNMP_ERR_NOERROR) { - snmp_vb_enumerator_init(&request->inbound_varbind_enumerator, request->inbound_pbuf, request->inbound_varbind_offset, request->inbound_varbind_len); - while (request->error_status == SNMP_ERR_NOERROR) { - err = snmp_vb_enumerator_get_next(&request->inbound_varbind_enumerator, &vb); - if (err == SNMP_VB_ENUMERATOR_ERR_OK) { - struct snmp_node_instance node_instance; - memset(&node_instance, 0, sizeof(node_instance)); - request->error_status = snmp_get_node_instance_from_oid(vb.oid.id, vb.oid.len, &node_instance); - if (request->error_status == SNMP_ERR_NOERROR) { - if (node_instance.set_value(&node_instance, vb.value_len, vb.value) != SNMP_ERR_NOERROR) { - if (request->inbound_varbind_enumerator.varbind_count == 1) { - request->error_status = SNMP_ERR_COMMITFAILED; - } else { - /* we cannot undo the set operations done so far */ - request->error_status = SNMP_ERR_UNDOFAILED; - } - } - - if (node_instance.release_instance != NULL) { - node_instance.release_instance(&node_instance); - } - } - } else if (err == SNMP_VB_ENUMERATOR_ERR_EOVB) { - /* no more varbinds in request */ - break; - } else { - /* first time enumerating varbinds work but second time not, although nothing should have changed in between ??? */ - request->error_status = SNMP_ERR_GENERROR; - } - } - } - - return ERR_OK; -} - -#define PARSE_EXEC(code, retValue) \ - if ((code) != ERR_OK) { \ - LWIP_DEBUGF(SNMP_DEBUG, ("Malformed ASN.1 detected.\n")); \ - snmp_stats.inasnparseerrs++; \ - return retValue; \ - } - -#define PARSE_ASSERT(cond, retValue) \ - if (!(cond)) { \ - LWIP_DEBUGF(SNMP_DEBUG, ("SNMP parse assertion failed!: " # cond)); \ - snmp_stats.inasnparseerrs++; \ - return retValue; \ - } - -#define BUILD_EXEC(code, retValue) \ - if ((code) != ERR_OK) { \ - LWIP_DEBUGF(SNMP_DEBUG, ("SNMP error during creation of outbound frame!: " # code)); \ - return retValue; \ - } - -#define IF_PARSE_EXEC(code) PARSE_EXEC(code, ERR_ARG) -#define IF_PARSE_ASSERT(code) PARSE_ASSERT(code, ERR_ARG) - -/** - * Checks and decodes incoming SNMP message header, logs header errors. - * - * @param request points to the current message request state return - * @return - * - ERR_OK SNMP header is sane and accepted - * - ERR_VAL SNMP header is either malformed or rejected - */ -static err_t -snmp_parse_inbound_frame(struct snmp_request *request) -{ - struct snmp_pbuf_stream pbuf_stream; - struct snmp_asn1_tlv tlv; - s32_t parent_tlv_value_len; - s32_t s32_value; - err_t err; - - IF_PARSE_EXEC(snmp_pbuf_stream_init(&pbuf_stream, request->inbound_pbuf, 0, request->inbound_pbuf->tot_len)); - - /* decode main container consisting of version, community and PDU */ - IF_PARSE_EXEC(snmp_asn1_dec_tlv(&pbuf_stream, &tlv)); - IF_PARSE_ASSERT((tlv.type == SNMP_ASN1_TYPE_SEQUENCE) && (tlv.value_len == pbuf_stream.length)); - parent_tlv_value_len = tlv.value_len; - - /* decode version */ - IF_PARSE_EXEC(snmp_asn1_dec_tlv(&pbuf_stream, &tlv)); - IF_PARSE_ASSERT(tlv.type == SNMP_ASN1_TYPE_INTEGER); - parent_tlv_value_len -= SNMP_ASN1_TLV_LENGTH(tlv); - IF_PARSE_ASSERT(parent_tlv_value_len > 0); - - IF_PARSE_EXEC(snmp_asn1_dec_s32t(&pbuf_stream, tlv.value_len, &s32_value)); - if ((s32_value != SNMP_VERSION_1) && - (s32_value != SNMP_VERSION_2c) -#if LWIP_SNMP_V3 - && (s32_value != SNMP_VERSION_3) -#endif - ) - { - /* unsupported SNMP version */ - snmp_stats.inbadversions++; - return ERR_ARG; - } - request->version = (u8_t)s32_value; - -#if LWIP_SNMP_V3 - if (request->version == SNMP_VERSION_3) { - u16_t u16_value; - u16_t inbound_msgAuthenticationParameters_offset; - - /* SNMPv3 doesn't use communities */ - /* @todo: Differentiate read/write access */ - strcpy((char*)request->community, snmp_community); - request->community_strlen = (u16_t)strlen(snmp_community); - - /* RFC3414 globalData */ - IF_PARSE_EXEC(snmp_asn1_dec_tlv(&pbuf_stream, &tlv)); - IF_PARSE_ASSERT(tlv.type == SNMP_ASN1_TYPE_SEQUENCE); - parent_tlv_value_len -= SNMP_ASN1_TLV_HDR_LENGTH(tlv); - IF_PARSE_ASSERT(parent_tlv_value_len > 0); - - /* decode msgID */ - IF_PARSE_EXEC(snmp_asn1_dec_tlv(&pbuf_stream, &tlv)); - IF_PARSE_ASSERT(tlv.type == SNMP_ASN1_TYPE_INTEGER); - parent_tlv_value_len -= SNMP_ASN1_TLV_LENGTH(tlv); - IF_PARSE_ASSERT(parent_tlv_value_len > 0); - - IF_PARSE_EXEC(snmp_asn1_dec_s32t(&pbuf_stream, tlv.value_len, &s32_value)); - request->msg_id = s32_value; - - /* decode msgMaxSize */ - IF_PARSE_EXEC(snmp_asn1_dec_tlv(&pbuf_stream, &tlv)); - IF_PARSE_ASSERT(tlv.type == SNMP_ASN1_TYPE_INTEGER); - parent_tlv_value_len -= SNMP_ASN1_TLV_LENGTH(tlv); - IF_PARSE_ASSERT(parent_tlv_value_len > 0); - - IF_PARSE_EXEC(snmp_asn1_dec_s32t(&pbuf_stream, tlv.value_len, &s32_value)); - request->msg_max_size = s32_value; - - /* decode msgFlags */ - IF_PARSE_EXEC(snmp_asn1_dec_tlv(&pbuf_stream, &tlv)); - IF_PARSE_ASSERT(tlv.type == SNMP_ASN1_TYPE_OCTET_STRING); - parent_tlv_value_len -= SNMP_ASN1_TLV_LENGTH(tlv); - IF_PARSE_ASSERT(parent_tlv_value_len > 0); - - IF_PARSE_EXEC(snmp_asn1_dec_s32t(&pbuf_stream, tlv.value_len, &s32_value)); - request->msg_flags = (u8_t)s32_value; - - /* decode msgSecurityModel */ - IF_PARSE_EXEC(snmp_asn1_dec_tlv(&pbuf_stream, &tlv)); - IF_PARSE_ASSERT(tlv.type == SNMP_ASN1_TYPE_INTEGER); - parent_tlv_value_len -= SNMP_ASN1_TLV_LENGTH(tlv); - IF_PARSE_ASSERT(parent_tlv_value_len > 0); - - IF_PARSE_EXEC(snmp_asn1_dec_s32t(&pbuf_stream, tlv.value_len, &s32_value)); - request->msg_security_model = s32_value; - - /* RFC3414 msgSecurityParameters - * The User-based Security Model defines the contents of the OCTET - * STRING as a SEQUENCE. - * - * We skip the protective dummy OCTET STRING header - * to access the SEQUENCE header. - */ - IF_PARSE_EXEC(snmp_asn1_dec_tlv(&pbuf_stream, &tlv)); - IF_PARSE_ASSERT(tlv.type == SNMP_ASN1_TYPE_OCTET_STRING); - parent_tlv_value_len -= SNMP_ASN1_TLV_HDR_LENGTH(tlv); - IF_PARSE_ASSERT(parent_tlv_value_len > 0); - - /* msgSecurityParameters SEQUENCE header */ - IF_PARSE_EXEC(snmp_asn1_dec_tlv(&pbuf_stream, &tlv)); - IF_PARSE_ASSERT(tlv.type == SNMP_ASN1_TYPE_SEQUENCE); - parent_tlv_value_len -= SNMP_ASN1_TLV_HDR_LENGTH(tlv); - IF_PARSE_ASSERT(parent_tlv_value_len > 0); - - /* decode msgAuthoritativeEngineID */ - IF_PARSE_EXEC(snmp_asn1_dec_tlv(&pbuf_stream, &tlv)); - IF_PARSE_ASSERT(tlv.type == SNMP_ASN1_TYPE_OCTET_STRING); - parent_tlv_value_len -= SNMP_ASN1_TLV_LENGTH(tlv); - IF_PARSE_ASSERT(parent_tlv_value_len > 0); - - IF_PARSE_EXEC(snmp_asn1_dec_raw(&pbuf_stream, tlv.value_len, request->msg_authoritative_engine_id, - &u16_value, SNMP_V3_MAX_ENGINE_ID_LENGTH)); - request->msg_authoritative_engine_id_len = (u8_t)u16_value; - - /* msgAuthoritativeEngineBoots */ - IF_PARSE_EXEC(snmp_asn1_dec_tlv(&pbuf_stream, &tlv)); - IF_PARSE_ASSERT(tlv.type == SNMP_ASN1_TYPE_INTEGER); - parent_tlv_value_len -= SNMP_ASN1_TLV_LENGTH(tlv); - IF_PARSE_ASSERT(parent_tlv_value_len > 0); - IF_PARSE_EXEC(snmp_asn1_dec_s32t(&pbuf_stream, tlv.value_len, &request->msg_authoritative_engine_boots)); - - /* msgAuthoritativeEngineTime */ - IF_PARSE_EXEC(snmp_asn1_dec_tlv(&pbuf_stream, &tlv)); - IF_PARSE_ASSERT(tlv.type == SNMP_ASN1_TYPE_INTEGER); - parent_tlv_value_len -= SNMP_ASN1_TLV_LENGTH(tlv); - IF_PARSE_ASSERT(parent_tlv_value_len > 0); - IF_PARSE_EXEC(snmp_asn1_dec_s32t(&pbuf_stream, tlv.value_len, &request->msg_authoritative_engine_time)); - /* @todo: Implement time window checking */ - - /* msgUserName */ - IF_PARSE_EXEC(snmp_asn1_dec_tlv(&pbuf_stream, &tlv)); - IF_PARSE_ASSERT(tlv.type == SNMP_ASN1_TYPE_OCTET_STRING); - parent_tlv_value_len -= SNMP_ASN1_TLV_LENGTH(tlv); - IF_PARSE_ASSERT(parent_tlv_value_len > 0); - - IF_PARSE_EXEC(snmp_asn1_dec_raw(&pbuf_stream, tlv.value_len, request->msg_user_name, - &u16_value, SNMP_V3_MAX_USER_LENGTH)); - request->msg_user_name_len = (u8_t)u16_value; - /* @todo: Implement unknown user error response */ - IF_PARSE_EXEC(snmpv3_get_user((char*)request->msg_user_name, NULL, NULL, NULL, NULL)); - - /* msgAuthenticationParameters */ - memset(request->msg_authentication_parameters, 0, SNMP_V3_MAX_AUTH_PARAM_LENGTH); - IF_PARSE_EXEC(snmp_asn1_dec_tlv(&pbuf_stream, &tlv)); - IF_PARSE_ASSERT(tlv.type == SNMP_ASN1_TYPE_OCTET_STRING); - parent_tlv_value_len -= SNMP_ASN1_TLV_LENGTH(tlv); - IF_PARSE_ASSERT(parent_tlv_value_len > 0); - /* Remember position */ - inbound_msgAuthenticationParameters_offset = pbuf_stream.offset; - LWIP_UNUSED_ARG(inbound_msgAuthenticationParameters_offset); - /* Read auth parameters */ - IF_PARSE_ASSERT(tlv.value_len <= SNMP_V3_MAX_AUTH_PARAM_LENGTH); - IF_PARSE_EXEC(snmp_asn1_dec_raw(&pbuf_stream, tlv.value_len, request->msg_authentication_parameters, - &u16_value, tlv.value_len)); - -#if LWIP_SNMP_V3_CRYPTO - if (request->msg_flags & SNMP_V3_AUTH_FLAG) { - const u8_t zero_arr[SNMP_V3_MAX_AUTH_PARAM_LENGTH] = { 0 }; - u8_t key[20]; - u8_t algo; - u8_t hmac[LWIP_MAX(SNMP_V3_SHA_LEN, SNMP_V3_MD5_LEN)]; - struct snmp_pbuf_stream auth_stream; - - /* Rewind stream */ - IF_PARSE_EXEC(snmp_pbuf_stream_init(&pbuf_stream, request->inbound_pbuf, 0, request->inbound_pbuf->tot_len)); - IF_PARSE_EXEC(snmp_pbuf_stream_seek_abs(&pbuf_stream, inbound_msgAuthenticationParameters_offset)); - /* Set auth parameters to zero for verification */ - IF_PARSE_EXEC(snmp_asn1_enc_raw(&pbuf_stream, zero_arr, tlv.value_len)); - - /* Verify authentication */ - IF_PARSE_EXEC(snmp_pbuf_stream_init(&auth_stream, request->inbound_pbuf, 0, request->inbound_pbuf->tot_len)); - - IF_PARSE_EXEC(snmpv3_get_user((char*)request->msg_user_name, &algo, key, NULL, NULL)); - IF_PARSE_EXEC(snmpv3_auth(&auth_stream, request->inbound_pbuf->tot_len, key, algo, hmac)); - /* @todo: Implement error response */ - IF_PARSE_EXEC(memcmp(request->msg_authentication_parameters, hmac, SNMP_V3_MAX_AUTH_PARAM_LENGTH)); - } -#else - /* Ungraceful exit if we encounter cryptography and don't support it. - * @todo: Implement error response - */ - IF_PARSE_ASSERT(!(request->msg_flags & (SNMP_V3_AUTH_FLAG | SNMP_V3_PRIV_FLAG))); -#endif - - /* msgPrivacyParameters */ - memset(request->msg_privacy_parameters, 0, SNMP_V3_MAX_PRIV_PARAM_LENGTH); - IF_PARSE_EXEC(snmp_asn1_dec_tlv(&pbuf_stream, &tlv)); - IF_PARSE_ASSERT(tlv.type == SNMP_ASN1_TYPE_OCTET_STRING); - parent_tlv_value_len -= SNMP_ASN1_TLV_LENGTH(tlv); - IF_PARSE_ASSERT(parent_tlv_value_len > 0); - - IF_PARSE_EXEC(snmp_asn1_dec_raw(&pbuf_stream, tlv.value_len, request->msg_privacy_parameters, - &u16_value, SNMP_V3_MAX_PRIV_PARAM_LENGTH)); - -#if LWIP_SNMP_V3_CRYPTO - /* Decrypt message */ - if (request->msg_flags & SNMP_V3_PRIV_FLAG) { - u8_t key[20]; - u8_t algo; - - IF_PARSE_EXEC(snmp_asn1_dec_tlv(&pbuf_stream, &tlv)); - IF_PARSE_ASSERT(tlv.type == SNMP_ASN1_TYPE_OCTET_STRING); - parent_tlv_value_len -= SNMP_ASN1_TLV_HDR_LENGTH(tlv); - IF_PARSE_ASSERT(parent_tlv_value_len > 0); - - IF_PARSE_EXEC(snmpv3_get_user((char*)request->msg_user_name, NULL, NULL, &algo, key)); - IF_PARSE_EXEC(snmpv3_crypt(&pbuf_stream, tlv.value_len, key, - request->msg_privacy_parameters, request->msg_authoritative_engine_boots, - request->msg_authoritative_engine_time, algo, SNMP_V3_PRIV_MODE_DECRYPT)); - } -#endif - - /* Scoped PDU - * Encryption context - */ - IF_PARSE_EXEC(snmp_asn1_dec_tlv(&pbuf_stream, &tlv)); - IF_PARSE_ASSERT(tlv.type == SNMP_ASN1_TYPE_SEQUENCE); - parent_tlv_value_len -= SNMP_ASN1_TLV_HDR_LENGTH(tlv); - IF_PARSE_ASSERT(parent_tlv_value_len > 0); - - /* contextEngineID */ - IF_PARSE_EXEC(snmp_asn1_dec_tlv(&pbuf_stream, &tlv)); - IF_PARSE_ASSERT(tlv.type == SNMP_ASN1_TYPE_OCTET_STRING); - parent_tlv_value_len -= SNMP_ASN1_TLV_LENGTH(tlv); - IF_PARSE_ASSERT(parent_tlv_value_len > 0); - - IF_PARSE_EXEC(snmp_asn1_dec_raw(&pbuf_stream, tlv.value_len, request->context_engine_id, - &u16_value, SNMP_V3_MAX_ENGINE_ID_LENGTH)); - request->context_engine_id_len = (u8_t)u16_value; - - /* contextName */ - IF_PARSE_EXEC(snmp_asn1_dec_tlv(&pbuf_stream, &tlv)); - IF_PARSE_ASSERT(tlv.type == SNMP_ASN1_TYPE_OCTET_STRING); - parent_tlv_value_len -= SNMP_ASN1_TLV_LENGTH(tlv); - IF_PARSE_ASSERT(parent_tlv_value_len > 0); - - IF_PARSE_EXEC(snmp_asn1_dec_raw(&pbuf_stream, tlv.value_len, request->context_name, - &u16_value, SNMP_V3_MAX_ENGINE_ID_LENGTH)); - request->context_name_len = (u8_t)u16_value; - } else -#endif - { - /* decode community */ - IF_PARSE_EXEC(snmp_asn1_dec_tlv(&pbuf_stream, &tlv)); - IF_PARSE_ASSERT(tlv.type == SNMP_ASN1_TYPE_OCTET_STRING); - parent_tlv_value_len -= SNMP_ASN1_TLV_LENGTH(tlv); - IF_PARSE_ASSERT(parent_tlv_value_len > 0); - - err = snmp_asn1_dec_raw(&pbuf_stream, tlv.value_len, request->community, &request->community_strlen, SNMP_MAX_COMMUNITY_STR_LEN); - if (err == ERR_MEM) { - /* community string does not fit in our buffer -> its too long -> its invalid */ - request->community_strlen = 0; - snmp_pbuf_stream_seek(&pbuf_stream, tlv.value_len); - } else { - IF_PARSE_ASSERT(err == ERR_OK); - } - /* add zero terminator */ - request->community[request->community_strlen] = 0; - } - - /* decode PDU type (next container level) */ - IF_PARSE_EXEC(snmp_asn1_dec_tlv(&pbuf_stream, &tlv)); - IF_PARSE_ASSERT(tlv.value_len <= pbuf_stream.length); - request->inbound_padding_len = pbuf_stream.length - tlv.value_len; - parent_tlv_value_len = tlv.value_len; - - /* validate PDU type */ - switch(tlv.type) { - case (SNMP_ASN1_CLASS_CONTEXT | SNMP_ASN1_CONTENTTYPE_CONSTRUCTED | SNMP_ASN1_CONTEXT_PDU_GET_REQ): - /* GetRequest PDU */ - snmp_stats.ingetrequests++; - break; - case (SNMP_ASN1_CLASS_CONTEXT | SNMP_ASN1_CONTENTTYPE_CONSTRUCTED | SNMP_ASN1_CONTEXT_PDU_GET_NEXT_REQ): - /* GetNextRequest PDU */ - snmp_stats.ingetnexts++; - break; - case (SNMP_ASN1_CLASS_CONTEXT | SNMP_ASN1_CONTENTTYPE_CONSTRUCTED | SNMP_ASN1_CONTEXT_PDU_GET_BULK_REQ): - /* GetBulkRequest PDU */ - if (request->version < SNMP_VERSION_2c) { - /* RFC2089: invalid, drop packet */ - return ERR_ARG; - } - break; - case (SNMP_ASN1_CLASS_CONTEXT | SNMP_ASN1_CONTENTTYPE_CONSTRUCTED | SNMP_ASN1_CONTEXT_PDU_SET_REQ): - /* SetRequest PDU */ - snmp_stats.insetrequests++; - break; - default: - /* unsupported input PDU for this agent (no parse error) */ - LWIP_DEBUGF(SNMP_DEBUG, ("Unknown/Invalid SNMP PDU type received: %d", tlv.type)); \ - return ERR_ARG; - break; - } - request->request_type = tlv.type & SNMP_ASN1_DATATYPE_MASK; - - /* validate community (do this after decoding PDU type because we don't want to increase 'inbadcommunitynames' for wrong frame types */ - if (request->community_strlen == 0) { - /* community string was too long or really empty*/ - snmp_stats.inbadcommunitynames++; - snmp_authfail_trap(); - return ERR_ARG; - } else if (request->request_type == SNMP_ASN1_CONTEXT_PDU_SET_REQ) { - if (snmp_community_write[0] == 0) { - /* our write community is empty, that means all our objects are readonly */ - request->error_status = SNMP_ERR_NOTWRITABLE; - request->error_index = 1; - } else if (strncmp(snmp_community_write, (const char*)request->community, SNMP_MAX_COMMUNITY_STR_LEN) != 0) { - /* community name does not match */ - snmp_stats.inbadcommunitynames++; - snmp_authfail_trap(); - return ERR_ARG; - } - } else { - if (strncmp(snmp_community, (const char*)request->community, SNMP_MAX_COMMUNITY_STR_LEN) != 0) { - /* community name does not match */ - snmp_stats.inbadcommunitynames++; - snmp_authfail_trap(); - return ERR_ARG; - } - } - - /* decode request ID */ - IF_PARSE_EXEC(snmp_asn1_dec_tlv(&pbuf_stream, &tlv)); - IF_PARSE_ASSERT(tlv.type == SNMP_ASN1_TYPE_INTEGER); - parent_tlv_value_len -= SNMP_ASN1_TLV_LENGTH(tlv); - IF_PARSE_ASSERT(parent_tlv_value_len > 0); - - IF_PARSE_EXEC(snmp_asn1_dec_s32t(&pbuf_stream, tlv.value_len, &request->request_id)); - - /* decode error status / non-repeaters */ - IF_PARSE_EXEC(snmp_asn1_dec_tlv(&pbuf_stream, &tlv)); - IF_PARSE_ASSERT(tlv.type == SNMP_ASN1_TYPE_INTEGER); - parent_tlv_value_len -= SNMP_ASN1_TLV_LENGTH(tlv); - IF_PARSE_ASSERT(parent_tlv_value_len > 0); - - if (request->request_type == SNMP_ASN1_CONTEXT_PDU_GET_BULK_REQ) { - IF_PARSE_EXEC(snmp_asn1_dec_s32t(&pbuf_stream, tlv.value_len, &request->non_repeaters)); - if (request->non_repeaters < 0) { - /* RFC 1905, 4.2.3 */ - request->non_repeaters = 0; - } - } else { - /* only check valid value, don't touch 'request->error_status', maybe a response error status was already set to above; */ - IF_PARSE_EXEC(snmp_asn1_dec_s32t(&pbuf_stream, tlv.value_len, &s32_value)); - IF_PARSE_ASSERT(s32_value == SNMP_ERR_NOERROR); - } - - /* decode error index / max-repetitions */ - IF_PARSE_EXEC(snmp_asn1_dec_tlv(&pbuf_stream, &tlv)); - IF_PARSE_ASSERT(tlv.type == SNMP_ASN1_TYPE_INTEGER); - parent_tlv_value_len -= SNMP_ASN1_TLV_LENGTH(tlv); - IF_PARSE_ASSERT(parent_tlv_value_len > 0); - - if (request->request_type == SNMP_ASN1_CONTEXT_PDU_GET_BULK_REQ) { - IF_PARSE_EXEC(snmp_asn1_dec_s32t(&pbuf_stream, tlv.value_len, &request->max_repetitions)); - if (request->max_repetitions < 0) { - /* RFC 1905, 4.2.3 */ - request->max_repetitions = 0; - } - } else { - IF_PARSE_EXEC(snmp_asn1_dec_s32t(&pbuf_stream, tlv.value_len, &request->error_index)); - IF_PARSE_ASSERT(s32_value == 0); - } - - /* decode varbind-list type (next container level) */ - IF_PARSE_EXEC(snmp_asn1_dec_tlv(&pbuf_stream, &tlv)); - IF_PARSE_ASSERT((tlv.type == SNMP_ASN1_TYPE_SEQUENCE) && (tlv.value_len <= pbuf_stream.length)); - - request->inbound_varbind_offset = pbuf_stream.offset; - request->inbound_varbind_len = pbuf_stream.length - request->inbound_padding_len; - snmp_vb_enumerator_init(&(request->inbound_varbind_enumerator), request->inbound_pbuf, request->inbound_varbind_offset, request->inbound_varbind_len); - - return ERR_OK; -} - -#define OF_BUILD_EXEC(code) BUILD_EXEC(code, ERR_ARG) - -static err_t -snmp_prepare_outbound_frame(struct snmp_request *request) -{ - struct snmp_asn1_tlv tlv; - struct snmp_pbuf_stream* pbuf_stream = &(request->outbound_pbuf_stream); - - /* try allocating pbuf(s) for maximum response size */ - request->outbound_pbuf = pbuf_alloc(PBUF_TRANSPORT, 1472, PBUF_RAM); - if (request->outbound_pbuf == NULL) { - return ERR_MEM; - } - - snmp_pbuf_stream_init(pbuf_stream, request->outbound_pbuf, 0, request->outbound_pbuf->tot_len); - - /* 'Message' sequence */ - SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_SEQUENCE, 3, 0); - OF_BUILD_EXEC( snmp_ans1_enc_tlv(pbuf_stream, &tlv) ); - - /* version */ - SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_INTEGER, 0, 0); - snmp_asn1_enc_s32t_cnt(request->version, &tlv.value_len); - OF_BUILD_EXEC( snmp_ans1_enc_tlv(pbuf_stream, &tlv) ); - OF_BUILD_EXEC( snmp_asn1_enc_s32t(pbuf_stream, tlv.value_len, request->version) ); - -#if LWIP_SNMP_V3 - if (request->version < SNMP_VERSION_3) { -#endif - /* community */ - SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_OCTET_STRING, 0, request->community_strlen); - OF_BUILD_EXEC( snmp_ans1_enc_tlv(pbuf_stream, &tlv) ); - OF_BUILD_EXEC( snmp_asn1_enc_raw(pbuf_stream, request->community, request->community_strlen) ); -#if LWIP_SNMP_V3 - } else { - const char* id; - - /* globalData */ - request->outbound_msg_global_data_offset = pbuf_stream->offset; - SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_SEQUENCE, 1, 0); - OF_BUILD_EXEC(snmp_ans1_enc_tlv(pbuf_stream, &tlv)); - - /* msgID */ - SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_INTEGER, 0, 1); - snmp_asn1_enc_s32t_cnt(request->msg_id, &tlv.value_len); - OF_BUILD_EXEC(snmp_ans1_enc_tlv(pbuf_stream, &tlv)); - OF_BUILD_EXEC(snmp_asn1_enc_s32t(pbuf_stream, tlv.value_len, request->msg_id)); - - /* msgMaxSize */ - SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_INTEGER, 0, 1); - snmp_asn1_enc_s32t_cnt(request->msg_max_size, &tlv.value_len); - OF_BUILD_EXEC(snmp_ans1_enc_tlv(pbuf_stream, &tlv)); - OF_BUILD_EXEC(snmp_asn1_enc_s32t(pbuf_stream, tlv.value_len, request->msg_max_size)); - - /* msgFlags */ - SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_OCTET_STRING, 0, 1); - OF_BUILD_EXEC(snmp_ans1_enc_tlv(pbuf_stream, &tlv)); - OF_BUILD_EXEC(snmp_asn1_enc_raw(pbuf_stream, &request->msg_flags, 1)); - - /* msgSecurityModel */ - SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_INTEGER, 0, 1); - snmp_asn1_enc_s32t_cnt(request->msg_security_model, &tlv.value_len); - OF_BUILD_EXEC(snmp_ans1_enc_tlv(pbuf_stream, &tlv)); - OF_BUILD_EXEC(snmp_asn1_enc_s32t(pbuf_stream, tlv.value_len, request->msg_security_model)); - - /* end of msgGlobalData */ - request->outbound_msg_global_data_end = pbuf_stream->offset; - - /* msgSecurityParameters */ - request->outbound_msg_security_parameters_str_offset = pbuf_stream->offset; - SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_OCTET_STRING, 1, 0); - OF_BUILD_EXEC(snmp_ans1_enc_tlv(pbuf_stream, &tlv)); - - request->outbound_msg_security_parameters_seq_offset = pbuf_stream->offset; - SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_SEQUENCE, 1, 0); - OF_BUILD_EXEC(snmp_ans1_enc_tlv(pbuf_stream, &tlv)); - - /* msgAuthoritativeEngineID */ - snmpv3_get_engine_id(&id, &request->msg_authoritative_engine_id_len); - MEMCPY(request->msg_authoritative_engine_id, id, request->msg_authoritative_engine_id_len); - SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_OCTET_STRING, 0, request->msg_authoritative_engine_id_len); - OF_BUILD_EXEC(snmp_ans1_enc_tlv(pbuf_stream, &tlv)); - OF_BUILD_EXEC(snmp_asn1_enc_raw(pbuf_stream, request->msg_authoritative_engine_id, request->msg_authoritative_engine_id_len)); - - request->msg_authoritative_engine_time = snmpv3_get_engine_time(); - request->msg_authoritative_engine_boots = snmpv3_get_engine_boots(); - - /* msgAuthoritativeEngineBoots */ - SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_INTEGER, 0, 0); - snmp_asn1_enc_s32t_cnt(request->msg_authoritative_engine_boots, &tlv.value_len); - OF_BUILD_EXEC(snmp_ans1_enc_tlv(pbuf_stream, &tlv)); - OF_BUILD_EXEC(snmp_asn1_enc_s32t(pbuf_stream, tlv.value_len, request->msg_authoritative_engine_boots)); - - /* msgAuthoritativeEngineTime */ - SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_INTEGER, 0, 0); - snmp_asn1_enc_s32t_cnt(request->msg_authoritative_engine_time, &tlv.value_len); - OF_BUILD_EXEC(snmp_ans1_enc_tlv(pbuf_stream, &tlv)); - OF_BUILD_EXEC(snmp_asn1_enc_s32t(pbuf_stream, tlv.value_len, request->msg_authoritative_engine_time)); - - /* msgUserName */ - SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_OCTET_STRING, 0, request->msg_user_name_len); - OF_BUILD_EXEC(snmp_ans1_enc_tlv(pbuf_stream, &tlv)); - OF_BUILD_EXEC(snmp_asn1_enc_raw(pbuf_stream, request->msg_user_name, request->msg_user_name_len)); - -#if LWIP_SNMP_V3_CRYPTO - /* msgAuthenticationParameters */ - if (request->msg_flags & SNMP_V3_AUTH_FLAG) { - memset(request->msg_authentication_parameters, 0, SNMP_V3_MAX_AUTH_PARAM_LENGTH); - request->outbound_msg_authentication_parameters_offset = pbuf_stream->offset; - SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_OCTET_STRING, 1, SNMP_V3_MAX_AUTH_PARAM_LENGTH); - OF_BUILD_EXEC(snmp_ans1_enc_tlv(pbuf_stream, &tlv)); - OF_BUILD_EXEC(snmp_asn1_enc_raw(pbuf_stream, request->msg_authentication_parameters, SNMP_V3_MAX_AUTH_PARAM_LENGTH)); - } else -#endif - { - SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_OCTET_STRING, 0, 0); - OF_BUILD_EXEC(snmp_ans1_enc_tlv(pbuf_stream, &tlv)); - } - -#if LWIP_SNMP_V3_CRYPTO - /* msgPrivacyParameters */ - if (request->msg_flags & SNMP_V3_PRIV_FLAG) { - snmpv3_build_priv_param(request->msg_privacy_parameters); - - SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_OCTET_STRING, 0, SNMP_V3_MAX_PRIV_PARAM_LENGTH); - OF_BUILD_EXEC(snmp_ans1_enc_tlv(pbuf_stream, &tlv)); - OF_BUILD_EXEC(snmp_asn1_enc_raw(pbuf_stream, request->msg_privacy_parameters, SNMP_V3_MAX_PRIV_PARAM_LENGTH)); - } else -#endif - { - SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_OCTET_STRING, 0, 0); - OF_BUILD_EXEC(snmp_ans1_enc_tlv(pbuf_stream, &tlv) ); - } - - /* End of msgSecurityParameters, so we can calculate the length of this sequence later */ - request->outbound_msg_security_parameters_end = pbuf_stream->offset; - -#if LWIP_SNMP_V3_CRYPTO - /* For encryption we have to encapsulate the payload in an octet string */ - if (request->msg_flags & SNMP_V3_PRIV_FLAG) { - request->outbound_scoped_pdu_string_offset = pbuf_stream->offset; - SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_OCTET_STRING, 3, 0); - OF_BUILD_EXEC(snmp_ans1_enc_tlv(pbuf_stream, &tlv)); - } -#endif - /* Scoped PDU - * Encryption context - */ - request->outbound_scoped_pdu_seq_offset = pbuf_stream->offset; - SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_SEQUENCE, 3, 0); - OF_BUILD_EXEC(snmp_ans1_enc_tlv(pbuf_stream, &tlv)); - - /* contextEngineID */ - snmpv3_get_engine_id(&id, &request->context_engine_id_len); - MEMCPY(request->context_engine_id, id, request->context_engine_id_len); - SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_OCTET_STRING, 0, request->context_engine_id_len); - OF_BUILD_EXEC(snmp_ans1_enc_tlv(pbuf_stream, &tlv)); - OF_BUILD_EXEC(snmp_asn1_enc_raw(pbuf_stream, request->context_engine_id, request->context_engine_id_len)); - - /* contextName */ - SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_OCTET_STRING, 0, request->context_name_len); - OF_BUILD_EXEC(snmp_ans1_enc_tlv(pbuf_stream, &tlv)); - OF_BUILD_EXEC(snmp_asn1_enc_raw(pbuf_stream, request->context_name, request->context_name_len)); - } -#endif - - /* 'PDU' sequence */ - request->outbound_pdu_offset = pbuf_stream->offset; - SNMP_ASN1_SET_TLV_PARAMS(tlv, (SNMP_ASN1_CLASS_CONTEXT | SNMP_ASN1_CONTENTTYPE_CONSTRUCTED | SNMP_ASN1_CONTEXT_PDU_GET_RESP), 3, 0); - OF_BUILD_EXEC( snmp_ans1_enc_tlv(pbuf_stream, &tlv) ); - - /* request ID */ - SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_INTEGER, 0, 0); - snmp_asn1_enc_s32t_cnt(request->request_id, &tlv.value_len); - OF_BUILD_EXEC( snmp_ans1_enc_tlv(pbuf_stream, &tlv) ); - OF_BUILD_EXEC( snmp_asn1_enc_s32t(pbuf_stream, tlv.value_len, request->request_id) ); - - /* error status */ - SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_INTEGER, 0, 1); - OF_BUILD_EXEC( snmp_ans1_enc_tlv(pbuf_stream, &tlv) ); - request->outbound_error_status_offset = pbuf_stream->offset; - OF_BUILD_EXEC( snmp_pbuf_stream_write(pbuf_stream, 0) ); - - /* error index */ - SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_INTEGER, 0, 1); - OF_BUILD_EXEC( snmp_ans1_enc_tlv(pbuf_stream, &tlv) ); - request->outbound_error_index_offset = pbuf_stream->offset; - OF_BUILD_EXEC( snmp_pbuf_stream_write(pbuf_stream, 0) ); - - /* 'VarBindList' sequence */ - SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_SEQUENCE, 3, 0); - OF_BUILD_EXEC( snmp_ans1_enc_tlv(pbuf_stream, &tlv) ); - - request->outbound_varbind_offset = pbuf_stream->offset; - - return ERR_OK; -} - -/** Calculate the length of a varbind list */ -err_t -snmp_varbind_length(struct snmp_varbind *varbind, struct snmp_varbind_len *len) -{ - /* calculate required lengths */ - snmp_asn1_enc_oid_cnt(varbind->oid.id, varbind->oid.len, &len->oid_value_len); - snmp_asn1_enc_length_cnt(len->oid_value_len, &len->oid_len_len); - - if (varbind->value_len == 0) { - len->value_value_len = 0; - } else if (varbind->value_len & SNMP_GET_VALUE_RAW_DATA) { - len->value_value_len = varbind->value_len & (~SNMP_GET_VALUE_RAW_DATA); - } else { - switch (varbind->type) { - case SNMP_ASN1_TYPE_INTEGER: - if (varbind->value_len != sizeof (s32_t)) { - return ERR_VAL; - } - snmp_asn1_enc_s32t_cnt(*((s32_t*) varbind->value), &len->value_value_len); - break; - case SNMP_ASN1_TYPE_COUNTER: - case SNMP_ASN1_TYPE_GAUGE: - case SNMP_ASN1_TYPE_TIMETICKS: - if (varbind->value_len != sizeof (u32_t)) { - return ERR_VAL; - } - snmp_asn1_enc_u32t_cnt(*((u32_t*) varbind->value), &len->value_value_len); - break; - case SNMP_ASN1_TYPE_OCTET_STRING: - case SNMP_ASN1_TYPE_IPADDR: - case SNMP_ASN1_TYPE_OPAQUE: - len->value_value_len = varbind->value_len; - break; - case SNMP_ASN1_TYPE_NULL: - if (varbind->value_len != 0) { - return ERR_VAL; - } - len->value_value_len = 0; - break; - case SNMP_ASN1_TYPE_OBJECT_ID: - if ((varbind->value_len & 0x03) != 0) { - return ERR_VAL; - } - snmp_asn1_enc_oid_cnt((u32_t*) varbind->value, varbind->value_len >> 2, &len->value_value_len); - break; - case SNMP_ASN1_TYPE_COUNTER64: - if (varbind->value_len != (2 * sizeof (u32_t))) { - return ERR_VAL; - } - snmp_asn1_enc_u64t_cnt((u32_t*) varbind->value, &len->value_value_len); - break; - default: - /* unsupported type */ - return ERR_VAL; - } - } - snmp_asn1_enc_length_cnt(len->value_value_len, &len->value_len_len); - - len->vb_value_len = 1 + len->oid_len_len + len->oid_value_len + 1 + len->value_len_len + len->value_value_len; - snmp_asn1_enc_length_cnt(len->vb_value_len, &len->vb_len_len); - - return ERR_OK; -} - -#define OVB_BUILD_EXEC(code) BUILD_EXEC(code, ERR_ARG) - -err_t -snmp_append_outbound_varbind(struct snmp_pbuf_stream *pbuf_stream, struct snmp_varbind* varbind) -{ - struct snmp_asn1_tlv tlv; - struct snmp_varbind_len len; - err_t err; - - err = snmp_varbind_length(varbind, &len); - - if (err != ERR_OK) { - return err; - } - - /* check length already before adding first data because in case of GetBulk, - * data added so far is returned and therefore no partial data shall be added - */ - if ((1 + len.vb_len_len + len.vb_value_len) > pbuf_stream->length) { - return ERR_BUF; - } - - /* 'VarBind' sequence */ - SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_SEQUENCE, len.vb_len_len, len.vb_value_len); - OVB_BUILD_EXEC(snmp_ans1_enc_tlv(pbuf_stream, &tlv)); - - /* VarBind OID */ - SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_OBJECT_ID, len.oid_len_len, len.oid_value_len); - OVB_BUILD_EXEC(snmp_ans1_enc_tlv(pbuf_stream, &tlv)); - OVB_BUILD_EXEC(snmp_asn1_enc_oid(pbuf_stream, varbind->oid.id, varbind->oid.len)); - - /* VarBind value */ - SNMP_ASN1_SET_TLV_PARAMS(tlv, varbind->type, len.value_len_len, len.value_value_len); - OVB_BUILD_EXEC(snmp_ans1_enc_tlv(pbuf_stream, &tlv)); - - if (len.value_value_len > 0) { - if (varbind->value_len & SNMP_GET_VALUE_RAW_DATA) { - OVB_BUILD_EXEC(snmp_asn1_enc_raw(pbuf_stream, (u8_t*) varbind->value, len.value_value_len)); - } else { - switch (varbind->type) { - case SNMP_ASN1_TYPE_INTEGER: - OVB_BUILD_EXEC(snmp_asn1_enc_s32t(pbuf_stream, len.value_value_len, *((s32_t*) varbind->value))); - break; - case SNMP_ASN1_TYPE_COUNTER: - case SNMP_ASN1_TYPE_GAUGE: - case SNMP_ASN1_TYPE_TIMETICKS: - OVB_BUILD_EXEC(snmp_asn1_enc_u32t(pbuf_stream, len.value_value_len, *((u32_t*) varbind->value))); - break; - case SNMP_ASN1_TYPE_OCTET_STRING: - case SNMP_ASN1_TYPE_IPADDR: - case SNMP_ASN1_TYPE_OPAQUE: - OVB_BUILD_EXEC(snmp_asn1_enc_raw(pbuf_stream, (u8_t*) varbind->value, len.value_value_len)); - len.value_value_len = varbind->value_len; - break; - case SNMP_ASN1_TYPE_OBJECT_ID: - OVB_BUILD_EXEC(snmp_asn1_enc_oid(pbuf_stream, (u32_t*) varbind->value, varbind->value_len / sizeof (u32_t))); - break; - case SNMP_ASN1_TYPE_COUNTER64: - OVB_BUILD_EXEC(snmp_asn1_enc_u64t(pbuf_stream, len.value_value_len, (u32_t*) varbind->value)); - break; - default: - LWIP_ASSERT("Unknown variable type", 0); - break; - } - } - } - - return ERR_OK; -} - -static err_t -snmp_complete_outbound_frame(struct snmp_request *request) -{ - struct snmp_asn1_tlv tlv; - u16_t frame_size; - u8_t outbound_padding = 0; - - if (request->version == SNMP_VERSION_1) { - if (request->error_status != SNMP_ERR_NOERROR) { - /* map v2c error codes to v1 compliant error code (according to RFC 2089) */ - switch (request->error_status) { - /* mapping of implementation specific "virtual" error codes - * (during processing of frame we already stored them in error_status field, - * so no need to check all varbinds here for those exceptions as suggested by RFC) */ - case SNMP_ERR_NOSUCHINSTANCE: - case SNMP_ERR_NOSUCHOBJECT: - case SNMP_ERR_ENDOFMIBVIEW: - request->error_status = SNMP_ERR_NOSUCHNAME; - break; - /* mapping according to RFC */ - case SNMP_ERR_WRONGVALUE: - case SNMP_ERR_WRONGENCODING: - case SNMP_ERR_WRONGTYPE: - case SNMP_ERR_WRONGLENGTH: - case SNMP_ERR_INCONSISTENTVALUE: - request->error_status = SNMP_ERR_BADVALUE; - break; - case SNMP_ERR_NOACCESS: - case SNMP_ERR_NOTWRITABLE: - case SNMP_ERR_NOCREATION: - case SNMP_ERR_INCONSISTENTNAME: - case SNMP_ERR_AUTHORIZATIONERROR: - request->error_status = SNMP_ERR_NOSUCHNAME; - break; - case SNMP_ERR_RESOURCEUNAVAILABLE: - case SNMP_ERR_COMMITFAILED: - case SNMP_ERR_UNDOFAILED: - default: - request->error_status = SNMP_ERR_GENERROR; - break; - } - } - } else { - if (request->request_type == SNMP_ASN1_CONTEXT_PDU_SET_REQ) { - /* map error codes to according to RFC 1905 (4.2.5. The SetRequest-PDU) return 'NotWritable' for unknown OIDs) */ - switch (request->error_status) { - case SNMP_ERR_NOSUCHINSTANCE: - case SNMP_ERR_NOSUCHOBJECT: - case SNMP_ERR_ENDOFMIBVIEW: - request->error_status = SNMP_ERR_NOTWRITABLE; - break; - default: - break; - } - } - - if (request->error_status >= SNMP_VARBIND_EXCEPTION_OFFSET) { - /* should never occur because v2 frames store exceptions directly inside varbinds and not as frame error_status */ - LWIP_DEBUGF(SNMP_DEBUG, ("snmp_complete_outbound_frame() > Found v2 request with varbind exception code stored as error status!\n")); - return ERR_ARG; - } - } - - if ((request->error_status != SNMP_ERR_NOERROR) || (request->request_type == SNMP_ASN1_CONTEXT_PDU_SET_REQ)) { - /* all inbound vars are returned in response without any modification for error responses and successful set requests*/ - struct snmp_pbuf_stream inbound_stream; - OF_BUILD_EXEC( snmp_pbuf_stream_init(&inbound_stream, request->inbound_pbuf, request->inbound_varbind_offset, request->inbound_varbind_len) ); - OF_BUILD_EXEC( snmp_pbuf_stream_init(&(request->outbound_pbuf_stream), request->outbound_pbuf, request->outbound_varbind_offset, request->outbound_pbuf->tot_len - request->outbound_varbind_offset) ); - snmp_pbuf_stream_writeto(&inbound_stream, &(request->outbound_pbuf_stream), 0); - } - - frame_size = request->outbound_pbuf_stream.offset; - -#if LWIP_SNMP_V3 && LWIP_SNMP_V3_CRYPTO - /* Calculate padding for encryption */ - if (request->version == SNMP_VERSION_3 && (request->msg_flags & SNMP_V3_PRIV_FLAG)) { - u8_t i; - outbound_padding = (8 - (u8_t)((frame_size - request->outbound_scoped_pdu_seq_offset) & 0x07)) & 0x07; - for (i = 0; i < outbound_padding; i++) { - snmp_pbuf_stream_write(&request->outbound_pbuf_stream, 0); - } - } -#endif - - /* complete missing length in 'Message' sequence ; 'Message' tlv is located at the beginning (offset 0) */ - SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_SEQUENCE, 3, frame_size + outbound_padding - 1 - 3); /* - type - length_len(fixed, see snmp_prepare_outbound_frame()) */ - OF_BUILD_EXEC( snmp_pbuf_stream_init(&(request->outbound_pbuf_stream), request->outbound_pbuf, 0, request->outbound_pbuf->tot_len) ); - OF_BUILD_EXEC( snmp_ans1_enc_tlv(&(request->outbound_pbuf_stream), &tlv) ); - -#if LWIP_SNMP_V3 - if (request->version == SNMP_VERSION_3) { - /* complete missing length in 'globalData' sequence */ - /* - type - length_len(fixed, see snmp_prepare_outbound_frame()) */ - SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_SEQUENCE, 1, request->outbound_msg_global_data_end - - request->outbound_msg_global_data_offset - 1 - 1); - OF_BUILD_EXEC(snmp_pbuf_stream_seek_abs(&(request->outbound_pbuf_stream), request->outbound_msg_global_data_offset)); - OF_BUILD_EXEC(snmp_ans1_enc_tlv(&(request->outbound_pbuf_stream), &tlv)); - - /* complete missing length in 'msgSecurityParameters' sequence */ - SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_OCTET_STRING, 1, request->outbound_msg_security_parameters_end - - request->outbound_msg_security_parameters_str_offset - 1 - 1); - OF_BUILD_EXEC(snmp_pbuf_stream_seek_abs(&(request->outbound_pbuf_stream), request->outbound_msg_security_parameters_str_offset)); - OF_BUILD_EXEC(snmp_ans1_enc_tlv(&(request->outbound_pbuf_stream), &tlv)); - - SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_SEQUENCE, 1, request->outbound_msg_security_parameters_end - - request->outbound_msg_security_parameters_seq_offset - 1 - 1); - OF_BUILD_EXEC(snmp_pbuf_stream_seek_abs(&(request->outbound_pbuf_stream), request->outbound_msg_security_parameters_seq_offset)); - OF_BUILD_EXEC(snmp_ans1_enc_tlv(&(request->outbound_pbuf_stream), &tlv)); - - /* complete missing length in scoped PDU sequence */ - SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_SEQUENCE, 3, frame_size - request->outbound_scoped_pdu_seq_offset - 1 - 3); - OF_BUILD_EXEC(snmp_pbuf_stream_seek_abs(&(request->outbound_pbuf_stream), request->outbound_scoped_pdu_seq_offset)); - OF_BUILD_EXEC(snmp_ans1_enc_tlv(&(request->outbound_pbuf_stream), &tlv)); - } -#endif - - /* complete missing length in 'PDU' sequence */ - SNMP_ASN1_SET_TLV_PARAMS(tlv, (SNMP_ASN1_CLASS_CONTEXT | SNMP_ASN1_CONTENTTYPE_CONSTRUCTED | SNMP_ASN1_CONTEXT_PDU_GET_RESP), 3, - frame_size - request->outbound_pdu_offset - 1 - 3); /* - type - length_len(fixed, see snmp_prepare_outbound_frame()) */ - OF_BUILD_EXEC( snmp_pbuf_stream_seek_abs(&(request->outbound_pbuf_stream), request->outbound_pdu_offset) ); - OF_BUILD_EXEC( snmp_ans1_enc_tlv(&(request->outbound_pbuf_stream), &tlv) ); - - /* process and encode final error status */ - if (request->error_status != 0) { - u16_t len; - snmp_asn1_enc_s32t_cnt(request->error_status, &len); - if (len != 1) { - /* error, we only reserved one byte for it */ - return ERR_ARG; - } - OF_BUILD_EXEC( snmp_pbuf_stream_seek_abs(&(request->outbound_pbuf_stream), request->outbound_error_status_offset) ); - OF_BUILD_EXEC( snmp_asn1_enc_s32t(&(request->outbound_pbuf_stream), len, request->error_status) ); - - /* for compatibility to v1, log statistics; in v2 (RFC 1907) these statistics are obsoleted */ - switch (request->error_status) { - case SNMP_ERR_TOOBIG: - snmp_stats.outtoobigs++; - break; - case SNMP_ERR_NOSUCHNAME: - snmp_stats.outnosuchnames++; - break; - case SNMP_ERR_BADVALUE: - snmp_stats.outbadvalues++; - break; - case SNMP_ERR_GENERROR: - default: - snmp_stats.outgenerrs++; - break; - } - - if (request->error_status == SNMP_ERR_TOOBIG) { - request->error_index = 0; /* defined by RFC 1157 */ - } else if (request->error_index == 0) { - /* set index to varbind where error occured (if not already set before, e.g. during GetBulk processing) */ - request->error_index = request->inbound_varbind_enumerator.varbind_count; - } - } else { - if (request->request_type == SNMP_ASN1_CONTEXT_PDU_SET_REQ) { - snmp_stats.intotalsetvars += request->inbound_varbind_enumerator.varbind_count; - } else { - snmp_stats.intotalreqvars += request->inbound_varbind_enumerator.varbind_count; - } - } - - /* encode final error index*/ - if (request->error_index != 0) { - u16_t len; - snmp_asn1_enc_s32t_cnt(request->error_index, &len); - if (len != 1) { - /* error, we only reserved one byte for it */ - return ERR_VAL; - } - OF_BUILD_EXEC( snmp_pbuf_stream_seek_abs(&(request->outbound_pbuf_stream), request->outbound_error_index_offset) ); - OF_BUILD_EXEC( snmp_asn1_enc_s32t(&(request->outbound_pbuf_stream), len, request->error_index) ); - } - - /* complete missing length in 'VarBindList' sequence ; 'VarBindList' tlv is located directly before varbind offset */ - SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_SEQUENCE, 3, frame_size - request->outbound_varbind_offset); - OF_BUILD_EXEC( snmp_pbuf_stream_seek_abs(&(request->outbound_pbuf_stream), request->outbound_varbind_offset - 1 - 3) ); /* - type - length_len(fixed, see snmp_prepare_outbound_frame()) */ - OF_BUILD_EXEC( snmp_ans1_enc_tlv(&(request->outbound_pbuf_stream), &tlv) ); - - /* Authenticate response */ -#if LWIP_SNMP_V3 && LWIP_SNMP_V3_CRYPTO - /* Encrypt response */ - if (request->version == SNMP_VERSION_3 && (request->msg_flags & SNMP_V3_PRIV_FLAG)) { - u8_t key[20]; - u8_t algo; - - /* complete missing length in PDU sequence */ - OF_BUILD_EXEC(snmp_pbuf_stream_init(&request->outbound_pbuf_stream, request->outbound_pbuf, 0, request->outbound_pbuf->tot_len)); - OF_BUILD_EXEC(snmp_pbuf_stream_seek_abs(&(request->outbound_pbuf_stream), request->outbound_scoped_pdu_string_offset)); - SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_OCTET_STRING, 3, frame_size + outbound_padding - - request->outbound_scoped_pdu_string_offset - 1 - 3); - OF_BUILD_EXEC(snmp_ans1_enc_tlv(&(request->outbound_pbuf_stream), &tlv)); - - OF_BUILD_EXEC(snmpv3_get_user((char*)request->msg_user_name, NULL, NULL, &algo, key)); - - OF_BUILD_EXEC(snmpv3_crypt(&request->outbound_pbuf_stream, tlv.value_len, key, - request->msg_privacy_parameters, request->msg_authoritative_engine_boots, - request->msg_authoritative_engine_time, algo, SNMP_V3_PRIV_MODE_ENCRYPT)); - } - - if (request->version == SNMP_VERSION_3 && (request->msg_flags & SNMP_V3_AUTH_FLAG)) { - u8_t key[20]; - u8_t algo; - u8_t hmac[20]; - - OF_BUILD_EXEC(snmpv3_get_user((char*)request->msg_user_name, &algo, key, NULL, NULL)); - OF_BUILD_EXEC(snmp_pbuf_stream_init(&(request->outbound_pbuf_stream), - request->outbound_pbuf, 0, request->outbound_pbuf->tot_len)); - OF_BUILD_EXEC(snmpv3_auth(&request->outbound_pbuf_stream, frame_size + outbound_padding, key, algo, hmac)); - - MEMCPY(request->msg_authentication_parameters, hmac, SNMP_V3_MAX_AUTH_PARAM_LENGTH); - OF_BUILD_EXEC(snmp_pbuf_stream_init(&request->outbound_pbuf_stream, - request->outbound_pbuf, 0, request->outbound_pbuf->tot_len)); - OF_BUILD_EXEC(snmp_pbuf_stream_seek_abs(&request->outbound_pbuf_stream, - request->outbound_msg_authentication_parameters_offset)); - - SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_OCTET_STRING, 1, SNMP_V3_MAX_AUTH_PARAM_LENGTH); - OF_BUILD_EXEC(snmp_ans1_enc_tlv(&request->outbound_pbuf_stream, &tlv)); - OF_BUILD_EXEC(snmp_asn1_enc_raw(&request->outbound_pbuf_stream, - request->msg_authentication_parameters, SNMP_V3_MAX_AUTH_PARAM_LENGTH)); - } -#endif - - pbuf_realloc(request->outbound_pbuf, frame_size + outbound_padding); - - snmp_stats.outgetresponses++; - snmp_stats.outpkts++; - - return ERR_OK; -} - -static void -snmp_execute_write_callbacks(struct snmp_request *request) -{ - struct snmp_varbind_enumerator inbound_varbind_enumerator; - struct snmp_varbind vb; - - snmp_vb_enumerator_init(&inbound_varbind_enumerator, request->inbound_pbuf, request->inbound_varbind_offset, request->inbound_varbind_len); - vb.value = NULL; /* do NOT decode value (we enumerate outbound buffer here, so all varbinds have values assigned, which we don't need here) */ - - while (snmp_vb_enumerator_get_next(&inbound_varbind_enumerator, &vb) == SNMP_VB_ENUMERATOR_ERR_OK) { - snmp_write_callback(vb.oid.id, vb.oid.len, snmp_write_callback_arg); - } -} - - -/* ----------------------------------------------------------------------- */ -/* VarBind enumerator methods */ -/* ----------------------------------------------------------------------- */ - -void -snmp_vb_enumerator_init(struct snmp_varbind_enumerator* enumerator, struct pbuf* p, u16_t offset, u16_t length) -{ - snmp_pbuf_stream_init(&(enumerator->pbuf_stream), p, offset, length); - enumerator->varbind_count = 0; -} - -#define VB_PARSE_EXEC(code) PARSE_EXEC(code, SNMP_VB_ENUMERATOR_ERR_ASN1ERROR) -#define VB_PARSE_ASSERT(code) PARSE_ASSERT(code, SNMP_VB_ENUMERATOR_ERR_ASN1ERROR) - -snmp_vb_enumerator_err_t -snmp_vb_enumerator_get_next(struct snmp_varbind_enumerator* enumerator, struct snmp_varbind* varbind) -{ - struct snmp_asn1_tlv tlv; - u16_t varbind_len; - err_t err; - - if (enumerator->pbuf_stream.length == 0) - { - return SNMP_VB_ENUMERATOR_ERR_EOVB; - } - enumerator->varbind_count++; - - /* decode varbind itself (parent container of a varbind) */ - VB_PARSE_EXEC(snmp_asn1_dec_tlv(&(enumerator->pbuf_stream), &tlv)); - VB_PARSE_ASSERT((tlv.type == SNMP_ASN1_TYPE_SEQUENCE) && (tlv.value_len <= enumerator->pbuf_stream.length)); - varbind_len = tlv.value_len; - - /* decode varbind name (object id) */ - VB_PARSE_EXEC(snmp_asn1_dec_tlv(&(enumerator->pbuf_stream), &tlv)); - VB_PARSE_ASSERT((tlv.type == SNMP_ASN1_TYPE_OBJECT_ID) && (SNMP_ASN1_TLV_LENGTH(tlv) < varbind_len) && (tlv.value_len < enumerator->pbuf_stream.length)); - - VB_PARSE_EXEC(snmp_asn1_dec_oid(&(enumerator->pbuf_stream), tlv.value_len, varbind->oid.id, &(varbind->oid.len), SNMP_MAX_OBJ_ID_LEN)); - varbind_len -= SNMP_ASN1_TLV_LENGTH(tlv); - - /* decode varbind value (object id) */ - VB_PARSE_EXEC(snmp_asn1_dec_tlv(&(enumerator->pbuf_stream), &tlv)); - VB_PARSE_ASSERT((SNMP_ASN1_TLV_LENGTH(tlv) == varbind_len) && (tlv.value_len <= enumerator->pbuf_stream.length)); - varbind->type = tlv.type; - - /* shall the value be decoded ? */ - if (varbind->value != NULL) { - switch (varbind->type) { - case SNMP_ASN1_TYPE_INTEGER: - VB_PARSE_EXEC(snmp_asn1_dec_s32t(&(enumerator->pbuf_stream), tlv.value_len, (s32_t*)varbind->value)); - varbind->value_len = sizeof(s32_t*); - break; - case SNMP_ASN1_TYPE_COUNTER: - case SNMP_ASN1_TYPE_GAUGE: - case SNMP_ASN1_TYPE_TIMETICKS: - VB_PARSE_EXEC(snmp_asn1_dec_u32t(&(enumerator->pbuf_stream), tlv.value_len, (u32_t*)varbind->value)); - varbind->value_len = sizeof(u32_t*); - break; - case SNMP_ASN1_TYPE_OCTET_STRING: - case SNMP_ASN1_TYPE_OPAQUE: - err = snmp_asn1_dec_raw(&(enumerator->pbuf_stream), tlv.value_len, (u8_t*)varbind->value, &varbind->value_len, SNMP_MAX_VALUE_SIZE); - if (err == ERR_MEM) { - return SNMP_VB_ENUMERATOR_ERR_INVALIDLENGTH; - } - VB_PARSE_ASSERT(err == ERR_OK); - break; - case SNMP_ASN1_TYPE_NULL: - varbind->value_len = 0; - break; - case SNMP_ASN1_TYPE_OBJECT_ID: - /* misuse tlv.length_len as OID_length transporter */ - err = snmp_asn1_dec_oid(&(enumerator->pbuf_stream), tlv.value_len, (u32_t*)varbind->value, &tlv.length_len, SNMP_MAX_OBJ_ID_LEN); - if (err == ERR_MEM) { - return SNMP_VB_ENUMERATOR_ERR_INVALIDLENGTH; - } - VB_PARSE_ASSERT(err == ERR_OK); - varbind->value_len = tlv.length_len * sizeof(u32_t); - break; - case SNMP_ASN1_TYPE_IPADDR: - if (tlv.value_len == 4) { - /* must be exactly 4 octets! */ - VB_PARSE_EXEC(snmp_asn1_dec_raw(&(enumerator->pbuf_stream), tlv.value_len, (u8_t*)varbind->value, &varbind->value_len, SNMP_MAX_VALUE_SIZE)); - } else { - VB_PARSE_ASSERT(0); - } - break; - case SNMP_ASN1_TYPE_COUNTER64: - VB_PARSE_EXEC(snmp_asn1_dec_u64t(&(enumerator->pbuf_stream), tlv.value_len, (u32_t*)varbind->value)); - varbind->value_len = 2 * sizeof(u32_t*); - break; - default: - VB_PARSE_ASSERT(0); - break; - } - } else { - snmp_pbuf_stream_seek(&(enumerator->pbuf_stream), tlv.value_len); - varbind->value_len = tlv.value_len; - } - - return SNMP_VB_ENUMERATOR_ERR_OK; -} - -#endif /* LWIP_SNMP */ diff --git a/third_party/lwip/repo/lwip/src/apps/snmp/snmp_msg.h b/third_party/lwip/repo/lwip/src/apps/snmp/snmp_msg.h deleted file mode 100644 index 2d01ef36eb919d..00000000000000 --- a/third_party/lwip/repo/lwip/src/apps/snmp/snmp_msg.h +++ /dev/null @@ -1,194 +0,0 @@ -/** - * @file - * SNMP Agent message handling structures (internal API, do not use in client code). - */ - -/* - * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands. - * Copyright (c) 2016 Elias Oenal. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * Author: Christiaan Simons - * Martin Hentschel - * Elias Oenal - */ - -#ifndef LWIP_HDR_APPS_SNMP_MSG_H -#define LWIP_HDR_APPS_SNMP_MSG_H - -#include "lwip/apps/snmp_opts.h" - -#if LWIP_SNMP - -#include "lwip/apps/snmp.h" -#include "lwip/apps/snmp_core.h" -#include "snmp_pbuf_stream.h" -#include "lwip/ip_addr.h" -#include "lwip/err.h" - -#if LWIP_SNMP_V3 -#include "snmpv3_priv.h" -#endif - - -#ifdef __cplusplus -extern "C" { -#endif - -/* The listen port of the SNMP agent. Clients have to make their requests to - this port. Most standard clients won't work if you change this! */ -#ifndef SNMP_IN_PORT -#define SNMP_IN_PORT 161 -#endif -/* The remote port the SNMP agent sends traps to. Most standard trap sinks won't - work if you change this! */ -#ifndef SNMP_TRAP_PORT -#define SNMP_TRAP_PORT 162 -#endif - -/* version defines used in PDU */ -#define SNMP_VERSION_1 0 -#define SNMP_VERSION_2c 1 -#define SNMP_VERSION_3 3 - -struct snmp_varbind_enumerator -{ - struct snmp_pbuf_stream pbuf_stream; - u16_t varbind_count; -}; - -typedef enum { - SNMP_VB_ENUMERATOR_ERR_OK = 0, - SNMP_VB_ENUMERATOR_ERR_EOVB = 1, - SNMP_VB_ENUMERATOR_ERR_ASN1ERROR = 2, - SNMP_VB_ENUMERATOR_ERR_INVALIDLENGTH = 3 -} snmp_vb_enumerator_err_t; - -void snmp_vb_enumerator_init(struct snmp_varbind_enumerator* enumerator, struct pbuf* p, u16_t offset, u16_t length); -snmp_vb_enumerator_err_t snmp_vb_enumerator_get_next(struct snmp_varbind_enumerator* enumerator, struct snmp_varbind* varbind); - -struct snmp_request -{ - /* Communication handle */ - void *handle; - /* source IP address */ - const ip_addr_t *source_ip; - /* source UDP port */ - u16_t source_port; - /* incoming snmp version */ - u8_t version; - /* community name (zero terminated) */ - u8_t community[SNMP_MAX_COMMUNITY_STR_LEN + 1]; - /* community string length (exclusive zero term) */ - u16_t community_strlen; - /* request type */ - u8_t request_type; - /* request ID */ - s32_t request_id; - /* error status */ - s32_t error_status; - /* error index */ - s32_t error_index; - /* non-repeaters (getBulkRequest (SNMPv2c)) */ - s32_t non_repeaters; - /* max-repetitions (getBulkRequest (SNMPv2c)) */ - s32_t max_repetitions; - -#if LWIP_SNMP_V3 - s32_t msg_id; - s32_t msg_max_size; - u8_t msg_flags; - s32_t msg_security_model; - u8_t msg_authoritative_engine_id[SNMP_V3_MAX_ENGINE_ID_LENGTH]; - u8_t msg_authoritative_engine_id_len; - s32_t msg_authoritative_engine_boots; - s32_t msg_authoritative_engine_time; - u8_t msg_user_name[SNMP_V3_MAX_USER_LENGTH]; - u8_t msg_user_name_len; - u8_t msg_authentication_parameters[SNMP_V3_MAX_AUTH_PARAM_LENGTH]; - u8_t msg_privacy_parameters[SNMP_V3_MAX_PRIV_PARAM_LENGTH]; - u8_t context_engine_id[SNMP_V3_MAX_ENGINE_ID_LENGTH]; - u8_t context_engine_id_len; - u8_t context_name[SNMP_V3_MAX_ENGINE_ID_LENGTH]; - u8_t context_name_len; -#endif - - struct pbuf *inbound_pbuf; - struct snmp_varbind_enumerator inbound_varbind_enumerator; - u16_t inbound_varbind_offset; - u16_t inbound_varbind_len; - u16_t inbound_padding_len; - - struct pbuf *outbound_pbuf; - struct snmp_pbuf_stream outbound_pbuf_stream; - u16_t outbound_pdu_offset; - u16_t outbound_error_status_offset; - u16_t outbound_error_index_offset; - u16_t outbound_varbind_offset; -#if LWIP_SNMP_V3 - u16_t outbound_msg_global_data_offset; - u16_t outbound_msg_global_data_end; - u16_t outbound_msg_security_parameters_str_offset; - u16_t outbound_msg_security_parameters_seq_offset; - u16_t outbound_msg_security_parameters_end; - u16_t outbound_msg_authentication_parameters_offset; - u16_t outbound_scoped_pdu_seq_offset; - u16_t outbound_scoped_pdu_string_offset; -#endif - - u8_t value_buffer[SNMP_MAX_VALUE_SIZE]; -}; - -/** A helper struct keeping length information about varbinds */ -struct snmp_varbind_len -{ - u8_t vb_len_len; - u16_t vb_value_len; - u8_t oid_len_len; - u16_t oid_value_len; - u8_t value_len_len; - u16_t value_value_len; -}; - -/** Agent community string */ -extern const char *snmp_community; -/** Agent community string for write access */ -extern const char *snmp_community_write; -/** handle for sending traps */ -extern void* snmp_traps_handle; - -void snmp_receive(void *handle, struct pbuf *p, const ip_addr_t *source_ip, u16_t port); -err_t snmp_sendto(void *handle, struct pbuf *p, const ip_addr_t *dst, u16_t port); -u8_t snmp_get_local_ip_for_dst(void* handle, const ip_addr_t *dst, ip_addr_t *result); -err_t snmp_varbind_length(struct snmp_varbind *varbind, struct snmp_varbind_len *len); -err_t snmp_append_outbound_varbind(struct snmp_pbuf_stream *pbuf_stream, struct snmp_varbind* varbind); - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_SNMP */ - -#endif /* LWIP_HDR_APPS_SNMP_MSG_H */ diff --git a/third_party/lwip/repo/lwip/src/apps/snmp/snmp_netconn.c b/third_party/lwip/repo/lwip/src/apps/snmp/snmp_netconn.c deleted file mode 100644 index 24c3e265316931..00000000000000 --- a/third_party/lwip/repo/lwip/src/apps/snmp/snmp_netconn.c +++ /dev/null @@ -1,121 +0,0 @@ -/** - * @file - * SNMP netconn frontend. - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * Author: Dirk Ziegelmeier - */ - -#include "lwip/apps/snmp_opts.h" - -#if LWIP_SNMP && SNMP_USE_NETCONN - -#include -#include "lwip/api.h" -#include "lwip/ip.h" -#include "lwip/udp.h" -#include "snmp_msg.h" -#include "lwip/sys.h" - -/** SNMP netconn API worker thread */ -static void -snmp_netconn_thread(void *arg) -{ - struct netconn *conn; - struct netbuf *buf; - err_t err; - LWIP_UNUSED_ARG(arg); - - /* Bind to SNMP port with default IP address */ -#if LWIP_IPV6 - conn = netconn_new(NETCONN_UDP_IPV6); - netconn_bind(conn, IP6_ADDR_ANY, SNMP_IN_PORT); -#else /* LWIP_IPV6 */ - conn = netconn_new(NETCONN_UDP); - netconn_bind(conn, IP4_ADDR_ANY, SNMP_IN_PORT); -#endif /* LWIP_IPV6 */ - LWIP_ERROR("snmp_netconn: invalid conn", (conn != NULL), return;); - - snmp_traps_handle = conn; - - do { - err = netconn_recv(conn, &buf); - - if (err == ERR_OK) { - snmp_receive(conn, buf->p, &buf->addr, buf->port); - } - - if (buf != NULL) { - netbuf_delete(buf); - } - } while(1); -} - -err_t -snmp_sendto(void *handle, struct pbuf *p, const ip_addr_t *dst, u16_t port) -{ - err_t result; - struct netbuf buf; - - memset(&buf, 0, sizeof(buf)); - buf.p = p; - result = netconn_sendto((struct netconn*)handle, &buf, dst, port); - - return result; -} - -u8_t -snmp_get_local_ip_for_dst(void* handle, const ip_addr_t *dst, ip_addr_t *result) -{ - struct netconn* conn = (struct netconn*)handle; - struct netif *dst_if; - const ip_addr_t* dst_ip; - - LWIP_UNUSED_ARG(conn); /* unused in case of IPV4 only configuration */ - - ip_route_get_local_ip(&conn->pcb.udp->local_ip, dst, dst_if, dst_ip); - - if ((dst_if != NULL) && (dst_ip != NULL)) { - ip_addr_copy(*result, *dst_ip); - return 1; - } else { - return 0; - } -} - -/** - * Starts SNMP Agent. - */ -void -snmp_init(void) -{ - sys_thread_new("snmp_netconn", snmp_netconn_thread, NULL, SNMP_STACK_SIZE, SNMP_THREAD_PRIO); -} - -#endif /* LWIP_SNMP && SNMP_USE_NETCONN */ diff --git a/third_party/lwip/repo/lwip/src/apps/snmp/snmp_pbuf_stream.c b/third_party/lwip/repo/lwip/src/apps/snmp/snmp_pbuf_stream.c deleted file mode 100644 index 3c1217d710be90..00000000000000 --- a/third_party/lwip/repo/lwip/src/apps/snmp/snmp_pbuf_stream.c +++ /dev/null @@ -1,156 +0,0 @@ -/** - * @file - * SNMP pbuf stream wrapper implementation (internal API, do not use in client code). - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Martin Hentschel - * - */ - -#include "lwip/apps/snmp_opts.h" - -#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */ - -#include "snmp_pbuf_stream.h" -#include "lwip/def.h" -#include - -err_t -snmp_pbuf_stream_init(struct snmp_pbuf_stream* pbuf_stream, struct pbuf* p, u16_t offset, u16_t length) -{ - pbuf_stream->offset = offset; - pbuf_stream->length = length; - pbuf_stream->pbuf = p; - - return ERR_OK; -} - -err_t -snmp_pbuf_stream_read(struct snmp_pbuf_stream* pbuf_stream, u8_t* data) -{ - if (pbuf_stream->length == 0) { - return ERR_BUF; - } - - if (pbuf_copy_partial(pbuf_stream->pbuf, data, 1, pbuf_stream->offset) == 0) { - return ERR_BUF; - } - - pbuf_stream->offset++; - pbuf_stream->length--; - - return ERR_OK; -} - -err_t -snmp_pbuf_stream_write(struct snmp_pbuf_stream* pbuf_stream, u8_t data) -{ - return snmp_pbuf_stream_writebuf(pbuf_stream, &data, 1); -} - -err_t -snmp_pbuf_stream_writebuf(struct snmp_pbuf_stream* pbuf_stream, const void* buf, u16_t buf_len) -{ - if (pbuf_stream->length < buf_len) { - return ERR_BUF; - } - - if (pbuf_take_at(pbuf_stream->pbuf, buf, buf_len, pbuf_stream->offset) != ERR_OK) { - return ERR_BUF; - } - - pbuf_stream->offset += buf_len; - pbuf_stream->length -= buf_len; - - return ERR_OK; -} - -err_t -snmp_pbuf_stream_writeto(struct snmp_pbuf_stream* pbuf_stream, struct snmp_pbuf_stream* target_pbuf_stream, u16_t len) -{ - - if ((pbuf_stream == NULL) || (target_pbuf_stream == NULL)) { - return ERR_ARG; - } - if ((len > pbuf_stream->length) || (len > target_pbuf_stream->length)) { - return ERR_ARG; - } - - if (len == 0) { - len = LWIP_MIN(pbuf_stream->length, target_pbuf_stream->length); - } - - while (len > 0) { - u16_t chunk_len; - err_t err; - u16_t target_offset; - struct pbuf* pbuf = pbuf_skip(pbuf_stream->pbuf, pbuf_stream->offset, &target_offset); - - if ((pbuf == NULL) || (pbuf->len == 0)) { - return ERR_BUF; - } - - chunk_len = LWIP_MIN(len, pbuf->len); - err = snmp_pbuf_stream_writebuf(target_pbuf_stream, &((u8_t*)pbuf->payload)[target_offset], chunk_len); - if (err != ERR_OK) { - return err; - } - - pbuf_stream->offset += chunk_len; - pbuf_stream->length -= chunk_len; - len -= chunk_len; - } - - return ERR_OK; -} - -err_t -snmp_pbuf_stream_seek(struct snmp_pbuf_stream* pbuf_stream, s32_t offset) -{ - if ((offset < 0) || (offset > pbuf_stream->length)) { - /* we cannot seek backwards or forward behind stream end */ - return ERR_ARG; - } - - pbuf_stream->offset += (u16_t)offset; - pbuf_stream->length -= (u16_t)offset; - - return ERR_OK; -} - -err_t -snmp_pbuf_stream_seek_abs(struct snmp_pbuf_stream* pbuf_stream, u32_t offset) -{ - s32_t rel_offset = offset - pbuf_stream->offset; - return snmp_pbuf_stream_seek(pbuf_stream, rel_offset); -} - -#endif /* LWIP_SNMP */ diff --git a/third_party/lwip/repo/lwip/src/apps/snmp/snmp_pbuf_stream.h b/third_party/lwip/repo/lwip/src/apps/snmp/snmp_pbuf_stream.h deleted file mode 100644 index 9778de774e6b38..00000000000000 --- a/third_party/lwip/repo/lwip/src/apps/snmp/snmp_pbuf_stream.h +++ /dev/null @@ -1,73 +0,0 @@ -/** - * @file - * SNMP pbuf stream wrapper (internal API, do not use in client code). - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Martin Hentschel - * - */ - -#ifndef LWIP_HDR_APPS_SNMP_PBUF_STREAM_H -#define LWIP_HDR_APPS_SNMP_PBUF_STREAM_H - -#include "lwip/apps/snmp_opts.h" - -#if LWIP_SNMP - -#include "lwip/err.h" -#include "lwip/pbuf.h" - -#ifdef __cplusplus -extern "C" { -#endif - -struct snmp_pbuf_stream -{ - struct pbuf* pbuf; - u16_t offset; - u16_t length; -}; - -err_t snmp_pbuf_stream_init(struct snmp_pbuf_stream* pbuf_stream, struct pbuf* p, u16_t offset, u16_t length); -err_t snmp_pbuf_stream_read(struct snmp_pbuf_stream* pbuf_stream, u8_t* data); -err_t snmp_pbuf_stream_write(struct snmp_pbuf_stream* pbuf_stream, u8_t data); -err_t snmp_pbuf_stream_writebuf(struct snmp_pbuf_stream* pbuf_stream, const void* buf, u16_t buf_len); -err_t snmp_pbuf_stream_writeto(struct snmp_pbuf_stream* pbuf_stream, struct snmp_pbuf_stream* target_pbuf_stream, u16_t len); -err_t snmp_pbuf_stream_seek(struct snmp_pbuf_stream* pbuf_stream, s32_t offset); -err_t snmp_pbuf_stream_seek_abs(struct snmp_pbuf_stream* pbuf_stream, u32_t offset); - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_SNMP */ - -#endif /* LWIP_HDR_APPS_SNMP_PBUF_STREAM_H */ diff --git a/third_party/lwip/repo/lwip/src/apps/snmp/snmp_raw.c b/third_party/lwip/repo/lwip/src/apps/snmp/snmp_raw.c deleted file mode 100644 index 4a40864fc9d20c..00000000000000 --- a/third_party/lwip/repo/lwip/src/apps/snmp/snmp_raw.c +++ /dev/null @@ -1,100 +0,0 @@ -/** - * @file - * SNMP RAW API frontend. - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * Author: Dirk Ziegelmeier - */ - -#include "lwip/apps/snmp_opts.h" -#include "lwip/ip_addr.h" - -#if LWIP_SNMP && SNMP_USE_RAW - -#include "lwip/udp.h" -#include "lwip/ip.h" -#include "snmp_msg.h" - -/* lwIP UDP receive callback function */ -static void -snmp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port) -{ - LWIP_UNUSED_ARG(arg); - - snmp_receive(pcb, p, addr, port); - - pbuf_free(p); -} - -err_t -snmp_sendto(void *handle, struct pbuf *p, const ip_addr_t *dst, u16_t port) -{ - return udp_sendto((struct udp_pcb*)handle, p, dst, port); -} - -u8_t -snmp_get_local_ip_for_dst(void* handle, const ip_addr_t *dst, ip_addr_t *result) -{ - struct udp_pcb* udp_pcb = (struct udp_pcb*)handle; - struct netif *dst_if; - const ip_addr_t* dst_ip; - - LWIP_UNUSED_ARG(udp_pcb); /* unused in case of IPV4 only configuration */ - - ip_route_get_local_ip(&udp_pcb->local_ip, dst, dst_if, dst_ip); - - if ((dst_if != NULL) && (dst_ip != NULL)) { - ip_addr_copy(*result, *dst_ip); - return 1; - } else { - return 0; - } -} - -/** - * @ingroup snmp_core - * Starts SNMP Agent. - * Allocates UDP pcb and binds it to IP_ANY_TYPE port 161. - */ -void -snmp_init(void) -{ - err_t err; - - struct udp_pcb *snmp_pcb = udp_new_ip_type(IPADDR_TYPE_ANY); - LWIP_ERROR("snmp_raw: no PCB", (snmp_pcb != NULL), return;); - - snmp_traps_handle = snmp_pcb; - - udp_recv(snmp_pcb, snmp_recv, (void *)SNMP_IN_PORT); - err = udp_bind(snmp_pcb, IP_ANY_TYPE, SNMP_IN_PORT); - LWIP_ERROR("snmp_raw: Unable to bind PCB", (err == ERR_OK), return;); -} - -#endif /* LWIP_SNMP && SNMP_USE_RAW */ diff --git a/third_party/lwip/repo/lwip/src/apps/snmp/snmp_scalar.c b/third_party/lwip/repo/lwip/src/apps/snmp/snmp_scalar.c deleted file mode 100644 index 136c9eccd0aff7..00000000000000 --- a/third_party/lwip/repo/lwip/src/apps/snmp/snmp_scalar.c +++ /dev/null @@ -1,220 +0,0 @@ -/** - * @file - * SNMP scalar node support implementation. - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Martin Hentschel - * - */ - -#include "lwip/apps/snmp_opts.h" - -#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/apps/snmp_scalar.h" -#include "lwip/apps/snmp_core.h" - -static s16_t snmp_scalar_array_get_value(struct snmp_node_instance* instance, void* value); -static snmp_err_t snmp_scalar_array_set_test(struct snmp_node_instance* instance, u16_t value_len, void* value); -static snmp_err_t snmp_scalar_array_set_value(struct snmp_node_instance* instance, u16_t value_len, void* value); - -snmp_err_t -snmp_scalar_get_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance) -{ - const struct snmp_scalar_node* scalar_node = (const struct snmp_scalar_node*)(const void*)instance->node; - - LWIP_UNUSED_ARG(root_oid); - LWIP_UNUSED_ARG(root_oid_len); - - /* scalar only has one dedicated instance: .0 */ - if ((instance->instance_oid.len != 1) || (instance->instance_oid.id[0] != 0)) { - return SNMP_ERR_NOSUCHINSTANCE; - } - - instance->access = scalar_node->access; - instance->asn1_type = scalar_node->asn1_type; - instance->get_value = scalar_node->get_value; - instance->set_test = scalar_node->set_test; - instance->set_value = scalar_node->set_value; - return SNMP_ERR_NOERROR; -} - -snmp_err_t -snmp_scalar_get_next_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance) -{ - /* because our only instance is .0 we can only return a next instance if no instance oid is passed */ - if (instance->instance_oid.len == 0) { - instance->instance_oid.len = 1; - instance->instance_oid.id[0] = 0; - - return snmp_scalar_get_instance(root_oid, root_oid_len, instance); - } - - return SNMP_ERR_NOSUCHINSTANCE; -} - - -snmp_err_t -snmp_scalar_array_get_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance) -{ - LWIP_UNUSED_ARG(root_oid); - LWIP_UNUSED_ARG(root_oid_len); - - if ((instance->instance_oid.len == 2) && (instance->instance_oid.id[1] == 0)) { - const struct snmp_scalar_array_node* array_node = (const struct snmp_scalar_array_node*)(const void*)instance->node; - const struct snmp_scalar_array_node_def* array_node_def = array_node->array_nodes; - u32_t i = 0; - - while (i < array_node->array_node_count) { - if (array_node_def->oid == instance->instance_oid.id[0]) { - break; - } - - array_node_def++; - i++; - } - - if (i < array_node->array_node_count) { - instance->access = array_node_def->access; - instance->asn1_type = array_node_def->asn1_type; - instance->get_value = snmp_scalar_array_get_value; - instance->set_test = snmp_scalar_array_set_test; - instance->set_value = snmp_scalar_array_set_value; - instance->reference.const_ptr = array_node_def; - - return SNMP_ERR_NOERROR; - } - } - - return SNMP_ERR_NOSUCHINSTANCE; -} - -snmp_err_t -snmp_scalar_array_get_next_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance) -{ - const struct snmp_scalar_array_node* array_node = (const struct snmp_scalar_array_node*)(const void*)instance->node; - const struct snmp_scalar_array_node_def* array_node_def = array_node->array_nodes; - const struct snmp_scalar_array_node_def* result = NULL; - - LWIP_UNUSED_ARG(root_oid); - LWIP_UNUSED_ARG(root_oid_len); - - if ((instance->instance_oid.len == 0) && (array_node->array_node_count > 0)) { - /* return node with lowest OID */ - u16_t i = 0; - - result = array_node_def; - array_node_def++; - - for (i = 1; i < array_node->array_node_count; i++) { - if (array_node_def->oid < result->oid) { - result = array_node_def; - } - array_node_def++; - } - } else if (instance->instance_oid.len >= 1) { - if (instance->instance_oid.len == 1) { - /* if we have the requested OID we return its instance, otherwise we search for the next available */ - u16_t i = 0; - while (i < array_node->array_node_count) { - if (array_node_def->oid == instance->instance_oid.id[0]) { - result = array_node_def; - break; - } - - array_node_def++; - i++; - } - } - if (result == NULL) { - u32_t oid_dist = 0xFFFFFFFFUL; - u16_t i = 0; - array_node_def = array_node->array_nodes; /* may be already at the end when if case before was executed without result -> reinitialize to start */ - while (i < array_node->array_node_count) { - if ((array_node_def->oid > instance->instance_oid.id[0]) && - ((u32_t)(array_node_def->oid - instance->instance_oid.id[0]) < oid_dist)) { - result = array_node_def; - oid_dist = array_node_def->oid - instance->instance_oid.id[0]; - } - - array_node_def++; - i++; - } - } - } - - if (result == NULL) { - /* nothing to return */ - return SNMP_ERR_NOSUCHINSTANCE; - } - - instance->instance_oid.len = 2; - instance->instance_oid.id[0] = result->oid; - instance->instance_oid.id[1] = 0; - - instance->access = result->access; - instance->asn1_type = result->asn1_type; - instance->get_value = snmp_scalar_array_get_value; - instance->set_test = snmp_scalar_array_set_test; - instance->set_value = snmp_scalar_array_set_value; - instance->reference.const_ptr = result; - - return SNMP_ERR_NOERROR; -} - -static s16_t -snmp_scalar_array_get_value(struct snmp_node_instance* instance, void* value) -{ - const struct snmp_scalar_array_node* array_node = (const struct snmp_scalar_array_node*)(const void*)instance->node; - const struct snmp_scalar_array_node_def* array_node_def = (const struct snmp_scalar_array_node_def*)instance->reference.const_ptr; - - return array_node->get_value(array_node_def, value); -} - -static snmp_err_t -snmp_scalar_array_set_test(struct snmp_node_instance* instance, u16_t value_len, void* value) -{ - const struct snmp_scalar_array_node* array_node = (const struct snmp_scalar_array_node*)(const void*)instance->node; - const struct snmp_scalar_array_node_def* array_node_def = (const struct snmp_scalar_array_node_def*)instance->reference.const_ptr; - - return array_node->set_test(array_node_def, value_len, value); -} - -static snmp_err_t -snmp_scalar_array_set_value(struct snmp_node_instance* instance, u16_t value_len, void* value) -{ - const struct snmp_scalar_array_node* array_node = (const struct snmp_scalar_array_node*)(const void*)instance->node; - const struct snmp_scalar_array_node_def* array_node_def = (const struct snmp_scalar_array_node_def*)instance->reference.const_ptr; - - return array_node->set_value(array_node_def, value_len, value); -} - -#endif /* LWIP_SNMP */ diff --git a/third_party/lwip/repo/lwip/src/apps/snmp/snmp_table.c b/third_party/lwip/repo/lwip/src/apps/snmp/snmp_table.c deleted file mode 100644 index 63ca5956330e2e..00000000000000 --- a/third_party/lwip/repo/lwip/src/apps/snmp/snmp_table.c +++ /dev/null @@ -1,343 +0,0 @@ -/** - * @file - * SNMP table support implementation. - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Martin Hentschel - * - */ - -#include "lwip/apps/snmp_opts.h" - -#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/apps/snmp_core.h" -#include "lwip/apps/snmp_table.h" -#include - -snmp_err_t snmp_table_get_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance) -{ - snmp_err_t ret = SNMP_ERR_NOSUCHINSTANCE; - const struct snmp_table_node* table_node = (const struct snmp_table_node*)(const void*)instance->node; - - LWIP_UNUSED_ARG(root_oid); - LWIP_UNUSED_ARG(root_oid_len); - - /* check min. length (fixed row entry definition, column, row instance oid with at least one entry */ - /* fixed row entry always has oid 1 */ - if ((instance->instance_oid.len >= 3) && (instance->instance_oid.id[0] == 1)) { - /* search column */ - const struct snmp_table_col_def* col_def = table_node->columns; - u16_t i = table_node->column_count; - while (i > 0) { - if (col_def->index == instance->instance_oid.id[1]) { - break; - } - - col_def++; - i--; - } - - if (i > 0) { - /* everything may be overwritten by get_cell_instance_method() in order to implement special handling for single columns/cells */ - instance->asn1_type = col_def->asn1_type; - instance->access = col_def->access; - instance->get_value = table_node->get_value; - instance->set_test = table_node->set_test; - instance->set_value = table_node->set_value; - - ret = table_node->get_cell_instance( - &(instance->instance_oid.id[1]), - &(instance->instance_oid.id[2]), - instance->instance_oid.len-2, - instance); - } - } - - return ret; -} - -snmp_err_t snmp_table_get_next_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance) -{ - const struct snmp_table_node* table_node = (const struct snmp_table_node*)(const void*)instance->node; - const struct snmp_table_col_def* col_def; - struct snmp_obj_id row_oid; - u32_t column = 0; - snmp_err_t result; - - LWIP_UNUSED_ARG(root_oid); - LWIP_UNUSED_ARG(root_oid_len); - - /* check that first part of id is 0 or 1, referencing fixed row entry */ - if ((instance->instance_oid.len > 0) && (instance->instance_oid.id[0] > 1)) { - return SNMP_ERR_NOSUCHINSTANCE; - } - if (instance->instance_oid.len > 1) { - column = instance->instance_oid.id[1]; - } - if (instance->instance_oid.len > 2) { - snmp_oid_assign(&row_oid, &(instance->instance_oid.id[2]), instance->instance_oid.len - 2); - } else { - row_oid.len = 0; - } - - instance->get_value = table_node->get_value; - instance->set_test = table_node->set_test; - instance->set_value = table_node->set_value; - - /* resolve column and value */ - do { - u16_t i; - const struct snmp_table_col_def* next_col_def = NULL; - col_def = table_node->columns; - - for (i = 0; i < table_node->column_count; i++) { - if (col_def->index == column) { - next_col_def = col_def; - break; - } else if ((col_def->index > column) && ((next_col_def == NULL) || (col_def->index < next_col_def->index))) { - next_col_def = col_def; - } - col_def++; - } - - if (next_col_def == NULL) { - /* no further column found */ - return SNMP_ERR_NOSUCHINSTANCE; - } - - instance->asn1_type = next_col_def->asn1_type; - instance->access = next_col_def->access; - - result = table_node->get_next_cell_instance( - &next_col_def->index, - &row_oid, - instance); - - if (result == SNMP_ERR_NOERROR) { - col_def = next_col_def; - break; - } - - row_oid.len = 0; /* reset row_oid because we switch to next column and start with the first entry there */ - column = next_col_def->index + 1; - } while (1); - - /* build resulting oid */ - instance->instance_oid.len = 2; - instance->instance_oid.id[0] = 1; - instance->instance_oid.id[1] = col_def->index; - snmp_oid_append(&instance->instance_oid, row_oid.id, row_oid.len); - - return SNMP_ERR_NOERROR; -} - - -snmp_err_t snmp_table_simple_get_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance) -{ - snmp_err_t ret = SNMP_ERR_NOSUCHINSTANCE; - const struct snmp_table_simple_node* table_node = (const struct snmp_table_simple_node*)(const void*)instance->node; - - LWIP_UNUSED_ARG(root_oid); - LWIP_UNUSED_ARG(root_oid_len); - - /* check min. length (fixed row entry definition, column, row instance oid with at least one entry */ - /* fixed row entry always has oid 1 */ - if ((instance->instance_oid.len >= 3) && (instance->instance_oid.id[0] == 1)) { - ret = table_node->get_cell_value( - &(instance->instance_oid.id[1]), - &(instance->instance_oid.id[2]), - instance->instance_oid.len-2, - &instance->reference, - &instance->reference_len); - - if (ret == SNMP_ERR_NOERROR) { - /* search column */ - const struct snmp_table_simple_col_def* col_def = table_node->columns; - u32_t i = table_node->column_count; - while (i > 0) { - if (col_def->index == instance->instance_oid.id[1]) { - break; - } - - col_def++; - i--; - } - - if (i > 0) { - instance->asn1_type = col_def->asn1_type; - instance->access = SNMP_NODE_INSTANCE_READ_ONLY; - instance->set_test = NULL; - instance->set_value = NULL; - - switch (col_def->data_type) { - case SNMP_VARIANT_VALUE_TYPE_U32: - instance->get_value = snmp_table_extract_value_from_u32ref; - break; - case SNMP_VARIANT_VALUE_TYPE_S32: - instance->get_value = snmp_table_extract_value_from_s32ref; - break; - case SNMP_VARIANT_VALUE_TYPE_PTR: /* fall through */ - case SNMP_VARIANT_VALUE_TYPE_CONST_PTR: - instance->get_value = snmp_table_extract_value_from_refconstptr; - break; - default: - LWIP_DEBUGF(SNMP_DEBUG, ("snmp_table_simple_get_instance(): unknown column data_type: %d\n", col_def->data_type)); - return SNMP_ERR_GENERROR; - } - - ret = SNMP_ERR_NOERROR; - } else { - ret = SNMP_ERR_NOSUCHINSTANCE; - } - } - } - - return ret; -} - -snmp_err_t snmp_table_simple_get_next_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance) -{ - const struct snmp_table_simple_node* table_node = (const struct snmp_table_simple_node*)(const void*)instance->node; - const struct snmp_table_simple_col_def* col_def; - struct snmp_obj_id row_oid; - u32_t column = 0; - snmp_err_t result; - - LWIP_UNUSED_ARG(root_oid); - LWIP_UNUSED_ARG(root_oid_len); - - /* check that first part of id is 0 or 1, referencing fixed row entry */ - if ((instance->instance_oid.len > 0) && (instance->instance_oid.id[0] > 1)) { - return SNMP_ERR_NOSUCHINSTANCE; - } - if (instance->instance_oid.len > 1) { - column = instance->instance_oid.id[1]; - } - if (instance->instance_oid.len > 2) { - snmp_oid_assign(&row_oid, &(instance->instance_oid.id[2]), instance->instance_oid.len - 2); - } else { - row_oid.len = 0; - } - - /* resolve column and value */ - do { - u32_t i; - const struct snmp_table_simple_col_def* next_col_def = NULL; - col_def = table_node->columns; - - for (i = 0; i < table_node->column_count; i++) { - if (col_def->index == column) { - next_col_def = col_def; - break; - } else if ((col_def->index > column) && ((next_col_def == NULL) || - (col_def->index < next_col_def->index))) { - next_col_def = col_def; - } - col_def++; - } - - if (next_col_def == NULL) { - /* no further column found */ - return SNMP_ERR_NOSUCHINSTANCE; - } - - result = table_node->get_next_cell_instance_and_value( - &next_col_def->index, - &row_oid, - &instance->reference, - &instance->reference_len); - - if (result == SNMP_ERR_NOERROR) { - col_def = next_col_def; - break; - } - - row_oid.len = 0; /* reset row_oid because we switch to next column and start with the first entry there */ - column = next_col_def->index + 1; - } - while (1); - - instance->asn1_type = col_def->asn1_type; - instance->access = SNMP_NODE_INSTANCE_READ_ONLY; - instance->set_test = NULL; - instance->set_value = NULL; - - switch (col_def->data_type) { - case SNMP_VARIANT_VALUE_TYPE_U32: - instance->get_value = snmp_table_extract_value_from_u32ref; - break; - case SNMP_VARIANT_VALUE_TYPE_S32: - instance->get_value = snmp_table_extract_value_from_s32ref; - break; - case SNMP_VARIANT_VALUE_TYPE_PTR: /* fall through */ - case SNMP_VARIANT_VALUE_TYPE_CONST_PTR: - instance->get_value = snmp_table_extract_value_from_refconstptr; - break; - default: - LWIP_DEBUGF(SNMP_DEBUG, ("snmp_table_simple_get_instance(): unknown column data_type: %d\n", col_def->data_type)); - return SNMP_ERR_GENERROR; - } - - /* build resulting oid */ - instance->instance_oid.len = 2; - instance->instance_oid.id[0] = 1; - instance->instance_oid.id[1] = col_def->index; - snmp_oid_append(&instance->instance_oid, row_oid.id, row_oid.len); - - return SNMP_ERR_NOERROR; -} - - -s16_t -snmp_table_extract_value_from_s32ref(struct snmp_node_instance* instance, void* value) -{ - s32_t *dst = (s32_t*)value; - *dst = instance->reference.s32; - return sizeof(*dst); -} - -s16_t -snmp_table_extract_value_from_u32ref(struct snmp_node_instance* instance, void* value) -{ - u32_t *dst = (u32_t*)value; - *dst = instance->reference.u32; - return sizeof(*dst); -} - -s16_t -snmp_table_extract_value_from_refconstptr(struct snmp_node_instance* instance, void* value) -{ - MEMCPY(value, instance->reference.const_ptr, instance->reference_len); - return (u16_t)instance->reference_len; -} - -#endif /* LWIP_SNMP */ diff --git a/third_party/lwip/repo/lwip/src/apps/snmp/snmp_threadsync.c b/third_party/lwip/repo/lwip/src/apps/snmp/snmp_threadsync.c deleted file mode 100644 index 204f265dc8dd71..00000000000000 --- a/third_party/lwip/repo/lwip/src/apps/snmp/snmp_threadsync.c +++ /dev/null @@ -1,219 +0,0 @@ -/** - * @file - * SNMP thread synchronization implementation. - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * Author: Dirk Ziegelmeier - */ - -#include "lwip/apps/snmp_opts.h" - -#if LWIP_SNMP && (NO_SYS == 0) /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/apps/snmp_threadsync.h" -#include "lwip/apps/snmp_core.h" -#include "lwip/sys.h" -#include - -static void -call_synced_function(struct threadsync_data *call_data, snmp_threadsync_called_fn fn) -{ - sys_mutex_lock(&call_data->threadsync_node->instance->sem_usage_mutex); - call_data->threadsync_node->instance->sync_fn(fn, call_data); - sys_sem_wait(&call_data->threadsync_node->instance->sem); - sys_mutex_unlock(&call_data->threadsync_node->instance->sem_usage_mutex); -} - -static void -threadsync_get_value_synced(void *ctx) -{ - struct threadsync_data *call_data = (struct threadsync_data*)ctx; - - call_data->retval.s16 = call_data->proxy_instance.get_value(&call_data->proxy_instance, call_data->arg1.value); - - sys_sem_signal(&call_data->threadsync_node->instance->sem); -} - -static s16_t -threadsync_get_value(struct snmp_node_instance* instance, void* value) -{ - struct threadsync_data *call_data = (struct threadsync_data*)instance->reference.ptr; - - call_data->arg1.value = value; - call_synced_function(call_data, threadsync_get_value_synced); - - return call_data->retval.s16; -} - -static void -threadsync_set_test_synced(void *ctx) -{ - struct threadsync_data *call_data = (struct threadsync_data*)ctx; - - call_data->retval.err = call_data->proxy_instance.set_test(&call_data->proxy_instance, call_data->arg2.len, call_data->arg1.value); - - sys_sem_signal(&call_data->threadsync_node->instance->sem); -} - -static snmp_err_t -threadsync_set_test(struct snmp_node_instance* instance, u16_t len, void *value) -{ - struct threadsync_data *call_data = (struct threadsync_data*)instance->reference.ptr; - - call_data->arg1.value = value; - call_data->arg2.len = len; - call_synced_function(call_data, threadsync_set_test_synced); - - return call_data->retval.err; -} - -static void -threadsync_set_value_synced(void *ctx) -{ - struct threadsync_data *call_data = (struct threadsync_data*)ctx; - - call_data->retval.err = call_data->proxy_instance.set_value(&call_data->proxy_instance, call_data->arg2.len, call_data->arg1.value); - - sys_sem_signal(&call_data->threadsync_node->instance->sem); -} - -static snmp_err_t -threadsync_set_value(struct snmp_node_instance* instance, u16_t len, void *value) -{ - struct threadsync_data *call_data = (struct threadsync_data*)instance->reference.ptr; - - call_data->arg1.value = value; - call_data->arg2.len = len; - call_synced_function(call_data, threadsync_set_value_synced); - - return call_data->retval.err; -} - -static void -threadsync_release_instance_synced(void* ctx) -{ - struct threadsync_data *call_data = (struct threadsync_data*)ctx; - - call_data->proxy_instance.release_instance(&call_data->proxy_instance); - - sys_sem_signal(&call_data->threadsync_node->instance->sem); -} - -static void -threadsync_release_instance(struct snmp_node_instance *instance) -{ - struct threadsync_data *call_data = (struct threadsync_data*)instance->reference.ptr; - - if (call_data->proxy_instance.release_instance != NULL) { - call_synced_function(call_data, threadsync_release_instance_synced); - } -} - -static void -get_instance_synced(void* ctx) -{ - struct threadsync_data *call_data = (struct threadsync_data*)ctx; - const struct snmp_leaf_node *leaf = (const struct snmp_leaf_node*)(const void*)call_data->proxy_instance.node; - - call_data->retval.err = leaf->get_instance(call_data->arg1.root_oid, call_data->arg2.root_oid_len, &call_data->proxy_instance); - - sys_sem_signal(&call_data->threadsync_node->instance->sem); -} - -static void -get_next_instance_synced(void* ctx) -{ - struct threadsync_data *call_data = (struct threadsync_data*)ctx; - const struct snmp_leaf_node *leaf = (const struct snmp_leaf_node*)(const void*)call_data->proxy_instance.node; - - call_data->retval.err = leaf->get_next_instance(call_data->arg1.root_oid, call_data->arg2.root_oid_len, &call_data->proxy_instance); - - sys_sem_signal(&call_data->threadsync_node->instance->sem); -} - -static snmp_err_t -do_sync(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance, snmp_threadsync_called_fn fn) -{ - const struct snmp_threadsync_node *threadsync_node = (const struct snmp_threadsync_node*)(const void*)instance->node; - struct threadsync_data *call_data = &threadsync_node->instance->data; - - if (threadsync_node->node.node.oid != threadsync_node->target->node.oid) { - LWIP_DEBUGF(SNMP_DEBUG, ("Sync node OID does not match target node OID")); - return SNMP_ERR_NOSUCHINSTANCE; - } - - memset(&call_data->proxy_instance, 0, sizeof(call_data->proxy_instance)); - - instance->reference.ptr = call_data; - snmp_oid_assign(&call_data->proxy_instance.instance_oid, instance->instance_oid.id, instance->instance_oid.len); - - call_data->proxy_instance.node = &threadsync_node->target->node; - call_data->threadsync_node = threadsync_node; - - call_data->arg1.root_oid = root_oid; - call_data->arg2.root_oid_len = root_oid_len; - call_synced_function(call_data, fn); - - if (call_data->retval.err == SNMP_ERR_NOERROR) { - instance->access = call_data->proxy_instance.access; - instance->asn1_type = call_data->proxy_instance.asn1_type; - instance->release_instance = threadsync_release_instance; - instance->get_value = (call_data->proxy_instance.get_value != NULL)? threadsync_get_value : NULL; - instance->set_value = (call_data->proxy_instance.set_value != NULL)? threadsync_set_value : NULL; - instance->set_test = (call_data->proxy_instance.set_test != NULL)? threadsync_set_test : NULL; - snmp_oid_assign(&instance->instance_oid, call_data->proxy_instance.instance_oid.id, call_data->proxy_instance.instance_oid.len); - } - - return call_data->retval.err; -} - -snmp_err_t -snmp_threadsync_get_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance) -{ - return do_sync(root_oid, root_oid_len, instance, get_instance_synced); -} - -snmp_err_t -snmp_threadsync_get_next_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance) -{ - return do_sync(root_oid, root_oid_len, instance, get_next_instance_synced); -} - -/** Initializes thread synchronization instance */ -void snmp_threadsync_init(struct snmp_threadsync_instance *instance, snmp_threadsync_synchronizer_fn sync_fn) -{ - err_t err = sys_mutex_new(&instance->sem_usage_mutex); - LWIP_ASSERT("Failed to set up mutex", err == ERR_OK); - err = sys_sem_new(&instance->sem, 0); - LWIP_UNUSED_ARG(err); /* in case of LWIP_NOASSERT */ - LWIP_ASSERT("Failed to set up semaphore", err == ERR_OK); - instance->sync_fn = sync_fn; -} - -#endif /* LWIP_SNMP */ diff --git a/third_party/lwip/repo/lwip/src/apps/snmp/snmp_traps.c b/third_party/lwip/repo/lwip/src/apps/snmp/snmp_traps.c deleted file mode 100644 index 0d2df64991b8e2..00000000000000 --- a/third_party/lwip/repo/lwip/src/apps/snmp/snmp_traps.c +++ /dev/null @@ -1,445 +0,0 @@ -/** - * @file - * SNMPv1 traps implementation. - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Martin Hentschel - * Christiaan Simons - * - */ - -#include "lwip/apps/snmp_opts.h" - -#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */ - -#include - -#include "lwip/snmp.h" -#include "lwip/sys.h" -#include "lwip/apps/snmp.h" -#include "lwip/apps/snmp_core.h" -#include "snmp_msg.h" -#include "snmp_asn1.h" -#include "snmp_core_priv.h" - -struct snmp_msg_trap -{ - /* source enterprise ID (sysObjectID) */ - const struct snmp_obj_id *enterprise; - /* source IP address, raw network order format */ - ip_addr_t sip; - /* generic trap code */ - u32_t gen_trap; - /* specific trap code */ - u32_t spc_trap; - /* timestamp */ - u32_t ts; - /* snmp_version */ - u32_t snmp_version; - - /* output trap lengths used in ASN encoding */ - /* encoding pdu length */ - u16_t pdulen; - /* encoding community length */ - u16_t comlen; - /* encoding sequence length */ - u16_t seqlen; - /* encoding varbinds sequence length */ - u16_t vbseqlen; -}; - -static u16_t snmp_trap_varbind_sum(struct snmp_msg_trap *trap, struct snmp_varbind *varbinds); -static u16_t snmp_trap_header_sum(struct snmp_msg_trap *trap, u16_t vb_len); -static void snmp_trap_header_enc(struct snmp_msg_trap *trap, struct snmp_pbuf_stream *pbuf_stream); -static void snmp_trap_varbind_enc(struct snmp_msg_trap *trap, struct snmp_pbuf_stream *pbuf_stream, struct snmp_varbind *varbinds); - -/** Agent community string for sending traps */ -extern const char *snmp_community_trap; - -void* snmp_traps_handle; - -struct snmp_trap_dst -{ - /* destination IP address in network order */ - ip_addr_t dip; - /* set to 0 when disabled, >0 when enabled */ - u8_t enable; -}; -static struct snmp_trap_dst trap_dst[SNMP_TRAP_DESTINATIONS]; - -static u8_t snmp_auth_traps_enabled = 0; - -/** - * @ingroup snmp_traps - * Sets enable switch for this trap destination. - * @param dst_idx index in 0 .. SNMP_TRAP_DESTINATIONS-1 - * @param enable switch if 0 destination is disabled >0 enabled. - */ -void -snmp_trap_dst_enable(u8_t dst_idx, u8_t enable) -{ - if (dst_idx < SNMP_TRAP_DESTINATIONS) { - trap_dst[dst_idx].enable = enable; - } -} - -/** - * @ingroup snmp_traps - * Sets IPv4 address for this trap destination. - * @param dst_idx index in 0 .. SNMP_TRAP_DESTINATIONS-1 - * @param dst IPv4 address in host order. - */ -void -snmp_trap_dst_ip_set(u8_t dst_idx, const ip_addr_t *dst) -{ - if (dst_idx < SNMP_TRAP_DESTINATIONS) { - ip_addr_set(&trap_dst[dst_idx].dip, dst); - } -} - -/** - * @ingroup snmp_traps - * Enable/disable authentication traps - */ -void -snmp_set_auth_traps_enabled(u8_t enable) -{ - snmp_auth_traps_enabled = enable; -} - -/** - * @ingroup snmp_traps - * Get authentication traps enabled state - */ -u8_t -snmp_get_auth_traps_enabled(void) -{ - return snmp_auth_traps_enabled; -} - - -/** - * @ingroup snmp_traps - * Sends a generic or enterprise specific trap message. - * - * @param eoid points to enterprise object identifier - * @param generic_trap is the trap code - * @param specific_trap used for enterprise traps when generic_trap == 6 - * @param varbinds linked list of varbinds to be sent - * @return ERR_OK when success, ERR_MEM if we're out of memory - * - * @note the use of the enterprise identifier field - * is per RFC1215. - * Use .iso.org.dod.internet.mgmt.mib-2.snmp for generic traps - * and .iso.org.dod.internet.private.enterprises.yourenterprise - * (sysObjectID) for specific traps. - */ -err_t -snmp_send_trap(const struct snmp_obj_id* eoid, s32_t generic_trap, s32_t specific_trap, struct snmp_varbind *varbinds) -{ - struct snmp_msg_trap trap_msg; - struct snmp_trap_dst *td; - struct pbuf *p; - u16_t i, tot_len; - err_t err = ERR_OK; - - trap_msg.snmp_version = 0; - - for (i = 0, td = &trap_dst[0]; i < SNMP_TRAP_DESTINATIONS; i++, td++) { - if ((td->enable != 0) && !ip_addr_isany(&td->dip)) { - /* lookup current source address for this dst */ - if (snmp_get_local_ip_for_dst(snmp_traps_handle, &td->dip, &trap_msg.sip)) { - if (eoid == NULL) { - trap_msg.enterprise = snmp_get_device_enterprise_oid(); - } else { - trap_msg.enterprise = eoid; - } - - trap_msg.gen_trap = generic_trap; - if (generic_trap == SNMP_GENTRAP_ENTERPRISE_SPECIFIC) { - trap_msg.spc_trap = specific_trap; - } else { - trap_msg.spc_trap = 0; - } - - MIB2_COPY_SYSUPTIME_TO(&trap_msg.ts); - - /* pass 0, calculate length fields */ - tot_len = snmp_trap_varbind_sum(&trap_msg, varbinds); - tot_len = snmp_trap_header_sum(&trap_msg, tot_len); - - /* allocate pbuf(s) */ - p = pbuf_alloc(PBUF_TRANSPORT, tot_len, PBUF_RAM); - if (p != NULL) { - struct snmp_pbuf_stream pbuf_stream; - snmp_pbuf_stream_init(&pbuf_stream, p, 0, tot_len); - - /* pass 1, encode packet ino the pbuf(s) */ - snmp_trap_header_enc(&trap_msg, &pbuf_stream); - snmp_trap_varbind_enc(&trap_msg, &pbuf_stream, varbinds); - - snmp_stats.outtraps++; - snmp_stats.outpkts++; - - /** send to the TRAP destination */ - snmp_sendto(snmp_traps_handle, p, &td->dip, SNMP_TRAP_PORT); - pbuf_free(p); - } else { - err = ERR_MEM; - } - } else { - /* routing error */ - err = ERR_RTE; - } - } - } - return err; -} - -/** - * @ingroup snmp_traps - * Send generic SNMP trap - */ -err_t -snmp_send_trap_generic(s32_t generic_trap) -{ - static const struct snmp_obj_id oid = { 7, { 1, 3, 6, 1, 2, 1, 11 } }; - return snmp_send_trap(&oid, generic_trap, 0, NULL); -} - -/** - * @ingroup snmp_traps - * Send specific SNMP trap with variable bindings - */ -err_t -snmp_send_trap_specific(s32_t specific_trap, struct snmp_varbind *varbinds) -{ - return snmp_send_trap(NULL, SNMP_GENTRAP_ENTERPRISE_SPECIFIC, specific_trap, varbinds); -} - -/** - * @ingroup snmp_traps - * Send coldstart trap - */ -void -snmp_coldstart_trap(void) -{ - snmp_send_trap_generic(SNMP_GENTRAP_COLDSTART); -} - -/** - * @ingroup snmp_traps - * Send authentication failure trap (used internally by agent) - */ -void -snmp_authfail_trap(void) -{ - if (snmp_auth_traps_enabled != 0) { - snmp_send_trap_generic(SNMP_GENTRAP_AUTH_FAILURE); - } -} - -static u16_t -snmp_trap_varbind_sum(struct snmp_msg_trap *trap, struct snmp_varbind *varbinds) -{ - struct snmp_varbind *varbind; - u16_t tot_len; - u8_t tot_len_len; - - tot_len = 0; - varbind = varbinds; - while (varbind != NULL) { - struct snmp_varbind_len len; - - if (snmp_varbind_length(varbind, &len) == ERR_OK) { - tot_len += 1 + len.vb_len_len + len.vb_value_len; - } - - varbind = varbind->next; - } - - trap->vbseqlen = tot_len; - snmp_asn1_enc_length_cnt(trap->vbseqlen, &tot_len_len); - tot_len += 1 + tot_len_len; - - return tot_len; -} - -/** - * Sums trap header field lengths from tail to head and - * returns trap_header_lengths for second encoding pass. - * - * @param trap Trap message - * @param vb_len varbind-list length - * @return the required length for encoding the trap header - */ -static u16_t -snmp_trap_header_sum(struct snmp_msg_trap *trap, u16_t vb_len) -{ - u16_t tot_len; - u16_t len; - u8_t lenlen; - - tot_len = vb_len; - - snmp_asn1_enc_u32t_cnt(trap->ts, &len); - snmp_asn1_enc_length_cnt(len, &lenlen); - tot_len += 1 + len + lenlen; - - snmp_asn1_enc_s32t_cnt(trap->spc_trap, &len); - snmp_asn1_enc_length_cnt(len, &lenlen); - tot_len += 1 + len + lenlen; - - snmp_asn1_enc_s32t_cnt(trap->gen_trap, &len); - snmp_asn1_enc_length_cnt(len, &lenlen); - tot_len += 1 + len + lenlen; - - if (IP_IS_V6_VAL(trap->sip)) { -#if LWIP_IPV6 - len = sizeof(ip_2_ip6(&trap->sip)->addr); -#endif - } else { -#if LWIP_IPV4 - len = sizeof(ip_2_ip4(&trap->sip)->addr); -#endif - } - snmp_asn1_enc_length_cnt(len, &lenlen); - tot_len += 1 + len + lenlen; - - snmp_asn1_enc_oid_cnt(trap->enterprise->id, trap->enterprise->len, &len); - snmp_asn1_enc_length_cnt(len, &lenlen); - tot_len += 1 + len + lenlen; - - trap->pdulen = tot_len; - snmp_asn1_enc_length_cnt(trap->pdulen, &lenlen); - tot_len += 1 + lenlen; - - trap->comlen = (u16_t)LWIP_MIN(strlen(snmp_community_trap), 0xFFFF); - snmp_asn1_enc_length_cnt(trap->comlen, &lenlen); - tot_len += 1 + lenlen + trap->comlen; - - snmp_asn1_enc_s32t_cnt(trap->snmp_version, &len); - snmp_asn1_enc_length_cnt(len, &lenlen); - tot_len += 1 + len + lenlen; - - trap->seqlen = tot_len; - snmp_asn1_enc_length_cnt(trap->seqlen, &lenlen); - tot_len += 1 + lenlen; - - return tot_len; -} - -static void -snmp_trap_varbind_enc(struct snmp_msg_trap *trap, struct snmp_pbuf_stream *pbuf_stream, struct snmp_varbind *varbinds) -{ - struct snmp_asn1_tlv tlv; - struct snmp_varbind *varbind; - - varbind = varbinds; - - SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_SEQUENCE, 0, trap->vbseqlen); - snmp_ans1_enc_tlv(pbuf_stream, &tlv); - - while (varbind != NULL) { - snmp_append_outbound_varbind(pbuf_stream, varbind); - - varbind = varbind->next; - } -} - -/** - * Encodes trap header from head to tail. - */ -static void -snmp_trap_header_enc(struct snmp_msg_trap *trap, struct snmp_pbuf_stream *pbuf_stream) -{ - struct snmp_asn1_tlv tlv; - - /* 'Message' sequence */ - SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_SEQUENCE, 0, trap->seqlen); - snmp_ans1_enc_tlv(pbuf_stream, &tlv); - - /* version */ - SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_INTEGER, 0, 0); - snmp_asn1_enc_s32t_cnt(trap->snmp_version, &tlv.value_len); - snmp_ans1_enc_tlv(pbuf_stream, &tlv); - snmp_asn1_enc_s32t(pbuf_stream, tlv.value_len, trap->snmp_version); - - /* community */ - SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_OCTET_STRING, 0, trap->comlen); - snmp_ans1_enc_tlv(pbuf_stream, &tlv); - snmp_asn1_enc_raw(pbuf_stream, (const u8_t *)snmp_community_trap, trap->comlen); - - /* 'PDU' sequence */ - SNMP_ASN1_SET_TLV_PARAMS(tlv, (SNMP_ASN1_CLASS_CONTEXT | SNMP_ASN1_CONTENTTYPE_CONSTRUCTED | SNMP_ASN1_CONTEXT_PDU_TRAP), 0, trap->pdulen); - snmp_ans1_enc_tlv(pbuf_stream, &tlv); - - /* object ID */ - SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_OBJECT_ID, 0, 0); - snmp_asn1_enc_oid_cnt(trap->enterprise->id, trap->enterprise->len, &tlv.value_len); - snmp_ans1_enc_tlv(pbuf_stream, &tlv); - snmp_asn1_enc_oid(pbuf_stream, trap->enterprise->id, trap->enterprise->len); - - /* IP addr */ - if (IP_IS_V6_VAL(trap->sip)) { -#if LWIP_IPV6 - SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_IPADDR, 0, sizeof(ip_2_ip6(&trap->sip)->addr)); - snmp_ans1_enc_tlv(pbuf_stream, &tlv); - snmp_asn1_enc_raw(pbuf_stream, (const u8_t *)&ip_2_ip6(&trap->sip)->addr, sizeof(ip_2_ip6(&trap->sip)->addr)); -#endif - } else { -#if LWIP_IPV4 - SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_IPADDR, 0, sizeof(ip_2_ip4(&trap->sip)->addr)); - snmp_ans1_enc_tlv(pbuf_stream, &tlv); - snmp_asn1_enc_raw(pbuf_stream, (const u8_t *)&ip_2_ip4(&trap->sip)->addr, sizeof(ip_2_ip4(&trap->sip)->addr)); -#endif - } - - /* trap length */ - SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_INTEGER, 0, 0); - snmp_asn1_enc_s32t_cnt(trap->gen_trap, &tlv.value_len); - snmp_ans1_enc_tlv(pbuf_stream, &tlv); - snmp_asn1_enc_s32t(pbuf_stream, tlv.value_len, trap->gen_trap); - - /* specific trap */ - SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_INTEGER, 0, 0); - snmp_asn1_enc_s32t_cnt(trap->spc_trap, &tlv.value_len); - snmp_ans1_enc_tlv(pbuf_stream, &tlv); - snmp_asn1_enc_s32t(pbuf_stream, tlv.value_len, trap->spc_trap); - - /* timestamp */ - SNMP_ASN1_SET_TLV_PARAMS(tlv, SNMP_ASN1_TYPE_TIMETICKS, 0, 0); - snmp_asn1_enc_s32t_cnt(trap->ts, &tlv.value_len); - snmp_ans1_enc_tlv(pbuf_stream, &tlv); - snmp_asn1_enc_s32t(pbuf_stream, tlv.value_len, trap->ts); -} - -#endif /* LWIP_SNMP */ diff --git a/third_party/lwip/repo/lwip/src/apps/snmp/snmpv3.c b/third_party/lwip/repo/lwip/src/apps/snmp/snmpv3.c deleted file mode 100644 index 69fb3a0aafa5be..00000000000000 --- a/third_party/lwip/repo/lwip/src/apps/snmp/snmpv3.c +++ /dev/null @@ -1,136 +0,0 @@ -/** - * @file - * Additional SNMPv3 functionality RFC3414 and RFC3826. - */ - -/* - * Copyright (c) 2016 Elias Oenal. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * Author: Elias Oenal - */ - -#include "snmpv3_priv.h" -#include "lwip/apps/snmpv3.h" -#include "lwip/sys.h" -#include - -#if LWIP_SNMP && LWIP_SNMP_V3 - -#ifdef LWIP_SNMPV3_INCLUDE_ENGINE -#include LWIP_SNMPV3_INCLUDE_ENGINE -#endif - -#define SNMP_MAX_TIME_BOOT 2147483647UL - -/** Call this if engine has been changed. Has to reset boots, see below */ -void -snmpv3_engine_id_changed(void) -{ - snmpv3_set_engine_boots(0); -} - -/** According to RFC3414 2.2.2. - * - * The number of times that the SNMP engine has - * (re-)initialized itself since snmpEngineID - * was last configured. - */ -u32_t -snmpv3_get_engine_boots_internal(void) -{ - if (snmpv3_get_engine_boots() == 0 || - snmpv3_get_engine_boots() < SNMP_MAX_TIME_BOOT) { - return snmpv3_get_engine_boots(); - } - - snmpv3_set_engine_boots(SNMP_MAX_TIME_BOOT); - return snmpv3_get_engine_boots(); -} - -/** RFC3414 2.2.2. - * - * Once the timer reaches 2147483647 it gets reset to zero and the - * engine boot ups get incremented. - */ -u32_t -snmpv3_get_engine_time_internal(void) -{ - if (snmpv3_get_engine_time() >= SNMP_MAX_TIME_BOOT) { - snmpv3_reset_engine_time(); - - if (snmpv3_get_engine_boots() < SNMP_MAX_TIME_BOOT - 1) { - snmpv3_set_engine_boots(snmpv3_get_engine_boots() + 1); - } else { - snmpv3_set_engine_boots(SNMP_MAX_TIME_BOOT); - } - } - - return snmpv3_get_engine_time(); -} - -#if LWIP_SNMP_V3_CRYPTO - -/* This function ignores the byte order suggestion in RFC3414 - * since it simply doesn't influence the effectiveness of an IV. - * - * Implementing RFC3826 priv param algorithm if LWIP_RAND is available. - * - * @todo: This is a potential thread safety issue. - */ -err_t -snmpv3_build_priv_param(u8_t* priv_param) -{ -#ifdef LWIP_RAND /* Based on RFC3826 */ - static u8_t init; - static u32_t priv1, priv2; - - /* Lazy initialisation */ - if (init == 0) { - init = 1; - priv1 = LWIP_RAND(); - priv2 = LWIP_RAND(); - } - - SMEMCPY(&priv_param[0], &priv1, sizeof(priv1)); - SMEMCPY(&priv_param[4], &priv2, sizeof(priv2)); - - /* Emulate 64bit increment */ - priv1++; - if (!priv1) { /* Overflow */ - priv2++; - } -#else /* Based on RFC3414 */ - static u32_t ctr; - u32_t boots = LWIP_SNMPV3_GET_ENGINE_BOOTS(); - SMEMCPY(&priv_param[0], &boots, 4); - SMEMCPY(&priv_param[4], &ctr, 4); - ctr++; -#endif - return ERR_OK; -} -#endif /* LWIP_SNMP_V3_CRYPTO */ - -#endif diff --git a/third_party/lwip/repo/lwip/src/apps/snmp/snmpv3_dummy.c b/third_party/lwip/repo/lwip/src/apps/snmp/snmpv3_dummy.c deleted file mode 100644 index bdfe8449940c7c..00000000000000 --- a/third_party/lwip/repo/lwip/src/apps/snmp/snmpv3_dummy.c +++ /dev/null @@ -1,145 +0,0 @@ -/** - * @file - * Dummy SNMPv3 functions. - */ - -/* - * Copyright (c) 2016 Elias Oenal. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * Author: Elias Oenal - * Dirk Ziegelmeier - */ - -#include "lwip/apps/snmpv3.h" -#include "snmpv3_priv.h" -#include -#include "lwip/err.h" - -#if LWIP_SNMP && LWIP_SNMP_V3 - -/** - * @param username is a pointer to a string. - * @param auth_algo is a pointer to u8_t. The implementation has to set this if user was found. - * @param auth_key is a pointer to a pointer to a string. Implementation has to set this if user was found. - * @param priv_algo is a pointer to u8_t. The implementation has to set this if user was found. - * @param priv_key is a pointer to a pointer to a string. Implementation has to set this if user was found. - */ -err_t -snmpv3_get_user(const char* username, u8_t *auth_algo, u8_t *auth_key, u8_t *priv_algo, u8_t *priv_key) -{ - const char* engine_id; - u8_t engine_id_len; - - if(strlen(username) == 0) { - return ERR_OK; - } - - if(memcmp(username, "lwip", 4) != 0) { - return ERR_VAL; - } - - snmpv3_get_engine_id(&engine_id, &engine_id_len); - - if(auth_key != NULL) { - snmpv3_password_to_key_sha((const u8_t*)"maplesyrup", 10, - (const u8_t*)engine_id, engine_id_len, - auth_key); - *auth_algo = SNMP_V3_AUTH_ALGO_SHA; - } - if(priv_key != NULL) { - snmpv3_password_to_key_sha((const u8_t*)"maplesyrup", 10, - (const u8_t*)engine_id, engine_id_len, - priv_key); - *priv_algo = SNMP_V3_PRIV_ALGO_DES; - } - return ERR_OK; -} - -/** - * Get engine ID from persistence - * @param id - * @param len - */ -void -snmpv3_get_engine_id(const char **id, u8_t *len) -{ - *id = "\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02"; - *len = 12; -} - -/** - * Store engine ID in persistence - * @param id - * @param len - */ -err_t -snmpv3_set_engine_id(const char *id, u8_t len) -{ - LWIP_UNUSED_ARG(id); - LWIP_UNUSED_ARG(len); - return ERR_OK; -} - -/** - * Get engine boots from persistence. Must be increased on each boot. - * @return - */ -u32_t -snmpv3_get_engine_boots(void) -{ - return 0; -} - -/** - * Store engine boots in persistence - * @param boots - */ -void -snmpv3_set_engine_boots(u32_t boots) -{ - LWIP_UNUSED_ARG(boots); -} - -/** - * RFC3414 2.2.2. - * Once the timer reaches 2147483647 it gets reset to zero and the - * engine boot ups get incremented. - */ -u32_t -snmpv3_get_engine_time(void) -{ - return 0; -} - -/** - * Reset current engine time to 0 - */ -void -snmpv3_reset_engine_time(void) -{ -} - -#endif /* LWIP_SNMP && LWIP_SNMP_V3 */ diff --git a/third_party/lwip/repo/lwip/src/apps/snmp/snmpv3_mbedtls.c b/third_party/lwip/repo/lwip/src/apps/snmp/snmpv3_mbedtls.c deleted file mode 100644 index 0b1eefb87e1039..00000000000000 --- a/third_party/lwip/repo/lwip/src/apps/snmp/snmpv3_mbedtls.c +++ /dev/null @@ -1,331 +0,0 @@ -/** - * @file - * SNMPv3 crypto/auth functions implemented for ARM mbedtls. - */ - -/* - * Copyright (c) 2016 Elias Oenal and Dirk Ziegelmeier. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * Author: Elias Oenal - * Dirk Ziegelmeier - */ - -#include "lwip/apps/snmpv3.h" -#include "snmpv3_priv.h" -#include "lwip/arch.h" -#include "snmp_msg.h" -#include "lwip/sys.h" -#include - -#if LWIP_SNMP && LWIP_SNMP_V3 && LWIP_SNMP_V3_MBEDTLS - -#include "mbedtls/md.h" -#include "mbedtls/cipher.h" - -#include "mbedtls/md5.h" -#include "mbedtls/sha1.h" - -err_t -snmpv3_auth(struct snmp_pbuf_stream* stream, u16_t length, - const u8_t* key, u8_t algo, u8_t* hmac_out) -{ - u32_t i; - u8_t key_len; - const mbedtls_md_info_t *md_info; - mbedtls_md_context_t ctx; - struct snmp_pbuf_stream read_stream; - snmp_pbuf_stream_init(&read_stream, stream->pbuf, stream->offset, stream->length); - - if (algo == SNMP_V3_AUTH_ALGO_MD5) { - md_info = mbedtls_md_info_from_type(MBEDTLS_MD_MD5); - key_len = SNMP_V3_MD5_LEN; - } else if (algo == SNMP_V3_AUTH_ALGO_SHA) { - md_info = mbedtls_md_info_from_type(MBEDTLS_MD_SHA1); - key_len = SNMP_V3_SHA_LEN; - } else { - return ERR_ARG; - } - - mbedtls_md_init(&ctx); - if(mbedtls_md_setup(&ctx, md_info, 1) != 0) { - return ERR_ARG; - } - - if (mbedtls_md_hmac_starts(&ctx, key, key_len) != 0) { - goto free_md; - } - - for (i = 0; i < length; i++) { - u8_t byte; - - if (snmp_pbuf_stream_read(&read_stream, &byte)) { - goto free_md; - } - - if (mbedtls_md_hmac_update(&ctx, &byte, 1) != 0) { - goto free_md; - } - } - - if (mbedtls_md_hmac_finish(&ctx, hmac_out) != 0) { - goto free_md; - } - - mbedtls_md_free(&ctx); - return ERR_OK; - -free_md: - mbedtls_md_free(&ctx); - return ERR_ARG; -} - -#if LWIP_SNMP_V3_CRYPTO - -err_t -snmpv3_crypt(struct snmp_pbuf_stream* stream, u16_t length, - const u8_t* key, const u8_t* priv_param, const u32_t engine_boots, - const u32_t engine_time, u8_t algo, u8_t mode) -{ - size_t i; - mbedtls_cipher_context_t ctx; - const mbedtls_cipher_info_t *cipher_info; - - struct snmp_pbuf_stream read_stream; - struct snmp_pbuf_stream write_stream; - snmp_pbuf_stream_init(&read_stream, stream->pbuf, stream->offset, stream->length); - snmp_pbuf_stream_init(&write_stream, stream->pbuf, stream->offset, stream->length); - mbedtls_cipher_init(&ctx); - - if (algo == SNMP_V3_PRIV_ALGO_DES) { - u8_t iv_local[8]; - u8_t out_bytes[8]; - size_t out_len; - - /* RFC 3414 mandates padding for DES */ - if ((length & 0x07) != 0) { - return ERR_ARG; - } - - cipher_info = mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_DES_CBC); - if(mbedtls_cipher_setup(&ctx, cipher_info) != 0) { - return ERR_ARG; - } - if(mbedtls_cipher_set_padding_mode(&ctx, MBEDTLS_PADDING_NONE) != 0) { - return ERR_ARG; - } - if(mbedtls_cipher_setkey(&ctx, key, 8*8, (mode == SNMP_V3_PRIV_MODE_ENCRYPT)? MBEDTLS_ENCRYPT : MBEDTLS_DECRYPT) != 0) { - goto error; - } - - /* Prepare IV */ - for (i = 0; i < LWIP_ARRAYSIZE(iv_local); i++) { - iv_local[i] = priv_param[i] ^ key[i + 8]; - } - if(mbedtls_cipher_set_iv(&ctx, iv_local, LWIP_ARRAYSIZE(iv_local)) != 0) { - goto error; - } - - for (i = 0; i < length; i += 8) { - size_t j; - u8_t in_bytes[8]; - out_len = LWIP_ARRAYSIZE(out_bytes) ; - - for (j = 0; j < LWIP_ARRAYSIZE(in_bytes); j++) { - snmp_pbuf_stream_read(&read_stream, &in_bytes[j]); - } - - if(mbedtls_cipher_update(&ctx, in_bytes, LWIP_ARRAYSIZE(in_bytes), out_bytes, &out_len) != 0) { - goto error; - } - - snmp_pbuf_stream_writebuf(&write_stream, out_bytes, out_len); - } - - out_len = LWIP_ARRAYSIZE(out_bytes); - if(mbedtls_cipher_finish(&ctx, out_bytes, &out_len) != 0) { - goto error; - } - snmp_pbuf_stream_writebuf(&write_stream, out_bytes, out_len); - } else if (algo == SNMP_V3_PRIV_ALGO_AES) { - u8_t iv_local[16]; - - cipher_info = mbedtls_cipher_info_from_type(MBEDTLS_CIPHER_AES_128_CFB128); - if(mbedtls_cipher_setup(&ctx, cipher_info) != 0) { - return ERR_ARG; - } - if(mbedtls_cipher_setkey(&ctx, key, 16*8, (mode == SNMP_V3_PRIV_MODE_ENCRYPT)? MBEDTLS_ENCRYPT : MBEDTLS_DECRYPT) != 0) { - goto error; - } - - /* - * IV is the big endian concatenation of boots, - * uptime and priv param - see RFC3826. - */ - iv_local[0 + 0] = (engine_boots >> 24) & 0xFF; - iv_local[0 + 1] = (engine_boots >> 16) & 0xFF; - iv_local[0 + 2] = (engine_boots >> 8) & 0xFF; - iv_local[0 + 3] = (engine_boots >> 0) & 0xFF; - iv_local[4 + 0] = (engine_time >> 24) & 0xFF; - iv_local[4 + 1] = (engine_time >> 16) & 0xFF; - iv_local[4 + 2] = (engine_time >> 8) & 0xFF; - iv_local[4 + 3] = (engine_time >> 0) & 0xFF; - SMEMCPY(iv_local + 8, priv_param, 8); - if(mbedtls_cipher_set_iv(&ctx, iv_local, LWIP_ARRAYSIZE(iv_local)) != 0) { - goto error; - } - - for (i = 0; i < length; i++) { - u8_t in_byte; - u8_t out_byte; - size_t out_len = sizeof(out_byte); - - snmp_pbuf_stream_read(&read_stream, &in_byte); - if(mbedtls_cipher_update(&ctx, &in_byte, sizeof(in_byte), &out_byte, &out_len) != 0) { - goto error; - } - snmp_pbuf_stream_write(&write_stream, out_byte); - } - } else { - return ERR_ARG; - } - - mbedtls_cipher_free(&ctx); - return ERR_OK; - -error: - mbedtls_cipher_free(&ctx); - return ERR_OK; -} - -#endif /* LWIP_SNMP_V3_CRYPTO */ - -/* A.2.1. Password to Key Sample Code for MD5 */ -void -snmpv3_password_to_key_md5( - const u8_t *password, /* IN */ - u8_t passwordlen, /* IN */ - const u8_t *engineID, /* IN - pointer to snmpEngineID */ - u8_t engineLength,/* IN - length of snmpEngineID */ - u8_t *key) /* OUT - pointer to caller 16-octet buffer */ -{ - mbedtls_md5_context MD; - u8_t *cp, password_buf[64]; - u32_t password_index = 0; - u8_t i; - u32_t count = 0; - - mbedtls_md5_init(&MD); /* initialize MD5 */ - mbedtls_md5_starts(&MD); - - /**********************************************/ - /* Use while loop until we've done 1 Megabyte */ - /**********************************************/ - while (count < 1048576) { - cp = password_buf; - for (i = 0; i < 64; i++) { - /*************************************************/ - /* Take the next octet of the password, wrapping */ - /* to the beginning of the password as necessary.*/ - /*************************************************/ - *cp++ = password[password_index++ % passwordlen]; - } - mbedtls_md5_update(&MD, password_buf, 64); - count += 64; - } - mbedtls_md5_finish(&MD, key); /* tell MD5 we're done */ - - /*****************************************************/ - /* Now localize the key with the engineID and pass */ - /* through MD5 to produce final key */ - /* May want to ensure that engineLength <= 32, */ - /* otherwise need to use a buffer larger than 64 */ - /*****************************************************/ - SMEMCPY(password_buf, key, 16); - MEMCPY(password_buf + 16, engineID, engineLength); - SMEMCPY(password_buf + 16 + engineLength, key, 16); - - mbedtls_md5_starts(&MD); - mbedtls_md5_update(&MD, password_buf, 32 + engineLength); - mbedtls_md5_finish(&MD, key); - - mbedtls_md5_free(&MD); - return; -} - -/* A.2.2. Password to Key Sample Code for SHA */ -void -snmpv3_password_to_key_sha( - const u8_t *password, /* IN */ - u8_t passwordlen, /* IN */ - const u8_t *engineID, /* IN - pointer to snmpEngineID */ - u8_t engineLength,/* IN - length of snmpEngineID */ - u8_t *key) /* OUT - pointer to caller 20-octet buffer */ -{ - mbedtls_sha1_context SH; - u8_t *cp, password_buf[72]; - u32_t password_index = 0; - u8_t i; - u32_t count = 0; - - mbedtls_sha1_init(&SH); /* initialize SHA */ - mbedtls_sha1_starts(&SH); - - /**********************************************/ - /* Use while loop until we've done 1 Megabyte */ - /**********************************************/ - while (count < 1048576) { - cp = password_buf; - for (i = 0; i < 64; i++) { - /*************************************************/ - /* Take the next octet of the password, wrapping */ - /* to the beginning of the password as necessary.*/ - /*************************************************/ - *cp++ = password[password_index++ % passwordlen]; - } - mbedtls_sha1_update(&SH, password_buf, 64); - count += 64; - } - mbedtls_sha1_finish(&SH, key); /* tell SHA we're done */ - - /*****************************************************/ - /* Now localize the key with the engineID and pass */ - /* through SHA to produce final key */ - /* May want to ensure that engineLength <= 32, */ - /* otherwise need to use a buffer larger than 72 */ - /*****************************************************/ - SMEMCPY(password_buf, key, 20); - MEMCPY(password_buf + 20, engineID, engineLength); - SMEMCPY(password_buf + 20 + engineLength, key, 20); - - mbedtls_sha1_starts(&SH); - mbedtls_sha1_update(&SH, password_buf, 40 + engineLength); - mbedtls_sha1_finish(&SH, key); - - mbedtls_sha1_free(&SH); - return; -} - -#endif /* LWIP_SNMP && LWIP_SNMP_V3 && LWIP_SNMP_V3_MBEDTLS */ diff --git a/third_party/lwip/repo/lwip/src/apps/snmp/snmpv3_priv.h b/third_party/lwip/repo/lwip/src/apps/snmp/snmpv3_priv.h deleted file mode 100644 index b87666da9935a8..00000000000000 --- a/third_party/lwip/repo/lwip/src/apps/snmp/snmpv3_priv.h +++ /dev/null @@ -1,66 +0,0 @@ -/** - * @file - * Additional SNMPv3 functionality RFC3414 and RFC3826 (internal API, do not use in client code). - */ - -/* - * Copyright (c) 2016 Elias Oenal. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * Author: Elias Oenal - */ - -#ifndef LWIP_HDR_APPS_SNMP_V3_PRIV_H -#define LWIP_HDR_APPS_SNMP_V3_PRIV_H - -#include "lwip/apps/snmp_opts.h" - -#if LWIP_SNMP && LWIP_SNMP_V3 - -#include "snmp_pbuf_stream.h" - -/* According to RFC 3411 */ -#define SNMP_V3_MAX_ENGINE_ID_LENGTH 32 -#define SNMP_V3_MAX_USER_LENGTH 32 - -#define SNMP_V3_MAX_AUTH_PARAM_LENGTH 12 -#define SNMP_V3_MAX_PRIV_PARAM_LENGTH 8 - -#define SNMP_V3_AUTH_FLAG 0x01 -#define SNMP_V3_PRIV_FLAG 0x02 - -#define SNMP_V3_MD5_LEN 16 -#define SNMP_V3_SHA_LEN 20 - -u32_t snmpv3_get_engine_boots_internal(void); -u32_t snmpv3_get_engine_time_internal(void); -err_t snmpv3_auth(struct snmp_pbuf_stream* stream, u16_t length, const u8_t* key, u8_t algo, u8_t* hmac_out); -err_t snmpv3_crypt(struct snmp_pbuf_stream* stream, u16_t length, const u8_t* key, - const u8_t* priv_param, const u32_t engine_boots, const u32_t engine_time, u8_t algo, u8_t mode); -err_t snmpv3_build_priv_param(u8_t* priv_param); - -#endif - -#endif /* LWIP_HDR_APPS_SNMP_V3_PRIV_H */ diff --git a/third_party/lwip/repo/lwip/src/apps/sntp/sntp.c b/third_party/lwip/repo/lwip/src/apps/sntp/sntp.c deleted file mode 100644 index 71b2abedb8fb69..00000000000000 --- a/third_party/lwip/repo/lwip/src/apps/sntp/sntp.c +++ /dev/null @@ -1,727 +0,0 @@ -/** - * @file - * SNTP client module - */ - -/* - * Copyright (c) 2007-2009 Frédéric Bernon, Simon Goldschmidt - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Frédéric Bernon, Simon Goldschmidt - */ - - -/** - * @defgroup sntp SNTP - * @ingroup apps - * - * This is simple "SNTP" client for the lwIP raw API. - * It is a minimal implementation of SNTPv4 as specified in RFC 4330. - * - * For a list of some public NTP servers, see this link : - * http://support.ntp.org/bin/view/Servers/NTPPoolServers - * - * @todo: - * - set/change servers at runtime - * - complete SNTP_CHECK_RESPONSE checks 3 and 4 - */ - -#include "lwip/apps/sntp.h" - -#include "lwip/opt.h" -#include "lwip/timeouts.h" -#include "lwip/udp.h" -#include "lwip/dns.h" -#include "lwip/ip_addr.h" -#include "lwip/pbuf.h" -#include "lwip/dhcp.h" - -#include -#include - -#if LWIP_UDP - -/* Handle support for more than one server via SNTP_MAX_SERVERS */ -#if SNTP_MAX_SERVERS > 1 -#define SNTP_SUPPORT_MULTIPLE_SERVERS 1 -#else /* NTP_MAX_SERVERS > 1 */ -#define SNTP_SUPPORT_MULTIPLE_SERVERS 0 -#endif /* NTP_MAX_SERVERS > 1 */ - -#if (SNTP_UPDATE_DELAY < 15000) && !defined(SNTP_SUPPRESS_DELAY_CHECK) -#error "SNTPv4 RFC 4330 enforces a minimum update time of 15 seconds (define SNTP_SUPPRESS_DELAY_CHECK to disable this error)!" -#endif - -/* Configure behaviour depending on microsecond or second precision */ -#ifdef SNTP_SET_SYSTEM_TIME_US -#define SNTP_CALC_TIME_US 1 -#define SNTP_RECEIVE_TIME_SIZE 2 -#else -#define SNTP_SET_SYSTEM_TIME_US(sec, us) -#define SNTP_CALC_TIME_US 0 -#define SNTP_RECEIVE_TIME_SIZE 1 -#endif - - -/* the various debug levels for this file */ -#define SNTP_DEBUG_TRACE (SNTP_DEBUG | LWIP_DBG_TRACE) -#define SNTP_DEBUG_STATE (SNTP_DEBUG | LWIP_DBG_STATE) -#define SNTP_DEBUG_WARN (SNTP_DEBUG | LWIP_DBG_LEVEL_WARNING) -#define SNTP_DEBUG_WARN_STATE (SNTP_DEBUG | LWIP_DBG_LEVEL_WARNING | LWIP_DBG_STATE) -#define SNTP_DEBUG_SERIOUS (SNTP_DEBUG | LWIP_DBG_LEVEL_SERIOUS) - -#define SNTP_ERR_KOD 1 - -/* SNTP protocol defines */ -#define SNTP_MSG_LEN 48 - -#define SNTP_OFFSET_LI_VN_MODE 0 -#define SNTP_LI_MASK 0xC0 -#define SNTP_LI_NO_WARNING 0x00 -#define SNTP_LI_LAST_MINUTE_61_SEC 0x01 -#define SNTP_LI_LAST_MINUTE_59_SEC 0x02 -#define SNTP_LI_ALARM_CONDITION 0x03 /* (clock not synchronized) */ - -#define SNTP_VERSION_MASK 0x38 -#define SNTP_VERSION (4/* NTP Version 4*/<<3) - -#define SNTP_MODE_MASK 0x07 -#define SNTP_MODE_CLIENT 0x03 -#define SNTP_MODE_SERVER 0x04 -#define SNTP_MODE_BROADCAST 0x05 - -#define SNTP_OFFSET_STRATUM 1 -#define SNTP_STRATUM_KOD 0x00 - -#define SNTP_OFFSET_ORIGINATE_TIME 24 -#define SNTP_OFFSET_RECEIVE_TIME 32 -#define SNTP_OFFSET_TRANSMIT_TIME 40 - -/* number of seconds between 1900 and 1970 (MSB=1)*/ -#define DIFF_SEC_1900_1970 (2208988800UL) -/* number of seconds between 1970 and Feb 7, 2036 (6:28:16 UTC) (MSB=0) */ -#define DIFF_SEC_1970_2036 (2085978496UL) - -/** - * SNTP packet format (without optional fields) - * Timestamps are coded as 64 bits: - * - 32 bits seconds since Jan 01, 1970, 00:00 - * - 32 bits seconds fraction (0-padded) - * For future use, if the MSB in the seconds part is set, seconds are based - * on Feb 07, 2036, 06:28:16. - */ -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct sntp_msg { - PACK_STRUCT_FLD_8(u8_t li_vn_mode); - PACK_STRUCT_FLD_8(u8_t stratum); - PACK_STRUCT_FLD_8(u8_t poll); - PACK_STRUCT_FLD_8(u8_t precision); - PACK_STRUCT_FIELD(u32_t root_delay); - PACK_STRUCT_FIELD(u32_t root_dispersion); - PACK_STRUCT_FIELD(u32_t reference_identifier); - PACK_STRUCT_FIELD(u32_t reference_timestamp[2]); - PACK_STRUCT_FIELD(u32_t originate_timestamp[2]); - PACK_STRUCT_FIELD(u32_t receive_timestamp[2]); - PACK_STRUCT_FIELD(u32_t transmit_timestamp[2]); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -/* function prototypes */ -static void sntp_request(void *arg); - -/** The operating mode */ -static u8_t sntp_opmode; - -/** The UDP pcb used by the SNTP client */ -static struct udp_pcb* sntp_pcb; -/** Names/Addresses of servers */ -struct sntp_server { -#if SNTP_SERVER_DNS - char* name; -#endif /* SNTP_SERVER_DNS */ - ip_addr_t addr; -}; -static struct sntp_server sntp_servers[SNTP_MAX_SERVERS]; - -#if SNTP_GET_SERVERS_FROM_DHCP -static u8_t sntp_set_servers_from_dhcp; -#endif /* SNTP_GET_SERVERS_FROM_DHCP */ -#if SNTP_SUPPORT_MULTIPLE_SERVERS -/** The currently used server (initialized to 0) */ -static u8_t sntp_current_server; -#else /* SNTP_SUPPORT_MULTIPLE_SERVERS */ -#define sntp_current_server 0 -#endif /* SNTP_SUPPORT_MULTIPLE_SERVERS */ - -#if SNTP_RETRY_TIMEOUT_EXP -#define SNTP_RESET_RETRY_TIMEOUT() sntp_retry_timeout = SNTP_RETRY_TIMEOUT -/** Retry time, initialized with SNTP_RETRY_TIMEOUT and doubled with each retry. */ -static u32_t sntp_retry_timeout; -#else /* SNTP_RETRY_TIMEOUT_EXP */ -#define SNTP_RESET_RETRY_TIMEOUT() -#define sntp_retry_timeout SNTP_RETRY_TIMEOUT -#endif /* SNTP_RETRY_TIMEOUT_EXP */ - -#if SNTP_CHECK_RESPONSE >= 1 -/** Saves the last server address to compare with response */ -static ip_addr_t sntp_last_server_address; -#endif /* SNTP_CHECK_RESPONSE >= 1 */ - -#if SNTP_CHECK_RESPONSE >= 2 -/** Saves the last timestamp sent (which is sent back by the server) - * to compare against in response */ -static u32_t sntp_last_timestamp_sent[2]; -#endif /* SNTP_CHECK_RESPONSE >= 2 */ - -/** - * SNTP processing of received timestamp - */ -static void -sntp_process(u32_t *receive_timestamp) -{ - /* convert SNTP time (1900-based) to unix GMT time (1970-based) - * if MSB is 0, SNTP time is 2036-based! - */ - u32_t rx_secs = lwip_ntohl(receive_timestamp[0]); - int is_1900_based = ((rx_secs & 0x80000000) != 0); - u32_t t = is_1900_based ? (rx_secs - DIFF_SEC_1900_1970) : (rx_secs + DIFF_SEC_1970_2036); - time_t tim = t; - -#if SNTP_CALC_TIME_US - u32_t us = lwip_ntohl(receive_timestamp[1]) / 4295; - SNTP_SET_SYSTEM_TIME_US(t, us); - /* display local time from GMT time */ - LWIP_DEBUGF(SNTP_DEBUG_TRACE, ("sntp_process: %s, %"U32_F" us", ctime(&tim), us)); - -#else /* SNTP_CALC_TIME_US */ - - /* change system time and/or the update the RTC clock */ - SNTP_SET_SYSTEM_TIME(t); - /* display local time from GMT time */ - LWIP_DEBUGF(SNTP_DEBUG_TRACE, ("sntp_process: %s", ctime(&tim))); -#endif /* SNTP_CALC_TIME_US */ - LWIP_UNUSED_ARG(tim); -} - -/** - * Initialize request struct to be sent to server. - */ -static void -sntp_initialize_request(struct sntp_msg *req) -{ - memset(req, 0, SNTP_MSG_LEN); - req->li_vn_mode = SNTP_LI_NO_WARNING | SNTP_VERSION | SNTP_MODE_CLIENT; - -#if SNTP_CHECK_RESPONSE >= 2 - { - u32_t sntp_time_sec, sntp_time_us; - /* fill in transmit timestamp and save it in 'sntp_last_timestamp_sent' */ - SNTP_GET_SYSTEM_TIME(sntp_time_sec, sntp_time_us); - sntp_last_timestamp_sent[0] = lwip_htonl(sntp_time_sec + DIFF_SEC_1900_1970); - req->transmit_timestamp[0] = sntp_last_timestamp_sent[0]; - /* we send/save us instead of fraction to be faster... */ - sntp_last_timestamp_sent[1] = lwip_htonl(sntp_time_us); - req->transmit_timestamp[1] = sntp_last_timestamp_sent[1]; - } -#endif /* SNTP_CHECK_RESPONSE >= 2 */ -} - -/** - * Retry: send a new request (and increase retry timeout). - * - * @param arg is unused (only necessary to conform to sys_timeout) - */ -static void -sntp_retry(void* arg) -{ - LWIP_UNUSED_ARG(arg); - - LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_retry: Next request will be sent in %"U32_F" ms\n", - sntp_retry_timeout)); - - /* set up a timer to send a retry and increase the retry delay */ - sys_timeout(sntp_retry_timeout, sntp_request, NULL); - -#if SNTP_RETRY_TIMEOUT_EXP - { - u32_t new_retry_timeout; - /* increase the timeout for next retry */ - new_retry_timeout = sntp_retry_timeout << 1; - /* limit to maximum timeout and prevent overflow */ - if ((new_retry_timeout <= SNTP_RETRY_TIMEOUT_MAX) && - (new_retry_timeout > sntp_retry_timeout)) { - sntp_retry_timeout = new_retry_timeout; - } - } -#endif /* SNTP_RETRY_TIMEOUT_EXP */ -} - -#if SNTP_SUPPORT_MULTIPLE_SERVERS -/** - * If Kiss-of-Death is received (or another packet parsing error), - * try the next server or retry the current server and increase the retry - * timeout if only one server is available. - * (implicitly, SNTP_MAX_SERVERS > 1) - * - * @param arg is unused (only necessary to conform to sys_timeout) - */ -static void -sntp_try_next_server(void* arg) -{ - u8_t old_server, i; - LWIP_UNUSED_ARG(arg); - - old_server = sntp_current_server; - for (i = 0; i < SNTP_MAX_SERVERS - 1; i++) { - sntp_current_server++; - if (sntp_current_server >= SNTP_MAX_SERVERS) { - sntp_current_server = 0; - } - if (!ip_addr_isany(&sntp_servers[sntp_current_server].addr) -#if SNTP_SERVER_DNS - || (sntp_servers[sntp_current_server].name != NULL) -#endif - ) { - LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_try_next_server: Sending request to server %"U16_F"\n", - (u16_t)sntp_current_server)); - /* new server: reset retry timeout */ - SNTP_RESET_RETRY_TIMEOUT(); - /* instantly send a request to the next server */ - sntp_request(NULL); - return; - } - } - /* no other valid server found */ - sntp_current_server = old_server; - sntp_retry(NULL); -} -#else /* SNTP_SUPPORT_MULTIPLE_SERVERS */ -/* Always retry on error if only one server is supported */ -#define sntp_try_next_server sntp_retry -#endif /* SNTP_SUPPORT_MULTIPLE_SERVERS */ - -/** UDP recv callback for the sntp pcb */ -static void -sntp_recv(void *arg, struct udp_pcb* pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port) -{ - u8_t mode; - u8_t stratum; - u32_t receive_timestamp[SNTP_RECEIVE_TIME_SIZE]; - err_t err; - - LWIP_UNUSED_ARG(arg); - LWIP_UNUSED_ARG(pcb); - - /* packet received: stop retry timeout */ - sys_untimeout(sntp_try_next_server, NULL); - sys_untimeout(sntp_request, NULL); - - err = ERR_ARG; -#if SNTP_CHECK_RESPONSE >= 1 - /* check server address and port */ - if (((sntp_opmode != SNTP_OPMODE_POLL) || ip_addr_cmp(addr, &sntp_last_server_address)) && - (port == SNTP_PORT)) -#else /* SNTP_CHECK_RESPONSE >= 1 */ - LWIP_UNUSED_ARG(addr); - LWIP_UNUSED_ARG(port); -#endif /* SNTP_CHECK_RESPONSE >= 1 */ - { - /* process the response */ - if (p->tot_len == SNTP_MSG_LEN) { - pbuf_copy_partial(p, &mode, 1, SNTP_OFFSET_LI_VN_MODE); - mode &= SNTP_MODE_MASK; - /* if this is a SNTP response... */ - if (((sntp_opmode == SNTP_OPMODE_POLL) && (mode == SNTP_MODE_SERVER)) || - ((sntp_opmode == SNTP_OPMODE_LISTENONLY) && (mode == SNTP_MODE_BROADCAST))) { - pbuf_copy_partial(p, &stratum, 1, SNTP_OFFSET_STRATUM); - if (stratum == SNTP_STRATUM_KOD) { - /* Kiss-of-death packet. Use another server or increase UPDATE_DELAY. */ - err = SNTP_ERR_KOD; - LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_recv: Received Kiss-of-Death\n")); - } else { -#if SNTP_CHECK_RESPONSE >= 2 - /* check originate_timetamp against sntp_last_timestamp_sent */ - u32_t originate_timestamp[2]; - pbuf_copy_partial(p, &originate_timestamp, 8, SNTP_OFFSET_ORIGINATE_TIME); - if ((originate_timestamp[0] != sntp_last_timestamp_sent[0]) || - (originate_timestamp[1] != sntp_last_timestamp_sent[1])) - { - LWIP_DEBUGF(SNTP_DEBUG_WARN, ("sntp_recv: Invalid originate timestamp in response\n")); - } else -#endif /* SNTP_CHECK_RESPONSE >= 2 */ - /* @todo: add code for SNTP_CHECK_RESPONSE >= 3 and >= 4 here */ - { - /* correct answer */ - err = ERR_OK; - pbuf_copy_partial(p, &receive_timestamp, SNTP_RECEIVE_TIME_SIZE * 4, SNTP_OFFSET_TRANSMIT_TIME); - } - } - } else { - LWIP_DEBUGF(SNTP_DEBUG_WARN, ("sntp_recv: Invalid mode in response: %"U16_F"\n", (u16_t)mode)); - /* wait for correct response */ - err = ERR_TIMEOUT; - } - } else { - LWIP_DEBUGF(SNTP_DEBUG_WARN, ("sntp_recv: Invalid packet length: %"U16_F"\n", p->tot_len)); - } - } -#if SNTP_CHECK_RESPONSE >= 1 - else { - /* packet from wrong remote address or port, wait for correct response */ - err = ERR_TIMEOUT; - } -#endif /* SNTP_CHECK_RESPONSE >= 1 */ - pbuf_free(p); - if (err == ERR_OK) { - sntp_process(receive_timestamp); - - /* Set up timeout for next request (only if poll response was received)*/ - if (sntp_opmode == SNTP_OPMODE_POLL) { - /* Correct response, reset retry timeout */ - SNTP_RESET_RETRY_TIMEOUT(); - - sys_timeout((u32_t)SNTP_UPDATE_DELAY, sntp_request, NULL); - LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_recv: Scheduled next time request: %"U32_F" ms\n", - (u32_t)SNTP_UPDATE_DELAY)); - } - } else if (err != ERR_TIMEOUT) { - /* Errors are only processed in case of an explicit poll response */ - if (sntp_opmode == SNTP_OPMODE_POLL) { - if (err == SNTP_ERR_KOD) { - /* Kiss-of-death packet. Use another server or increase UPDATE_DELAY. */ - sntp_try_next_server(NULL); - } else { - /* another error, try the same server again */ - sntp_retry(NULL); - } - } - } -} - -/** Actually send an sntp request to a server. - * - * @param server_addr resolved IP address of the SNTP server - */ -static void -sntp_send_request(const ip_addr_t *server_addr) -{ - struct pbuf* p; - p = pbuf_alloc(PBUF_TRANSPORT, SNTP_MSG_LEN, PBUF_RAM); - if (p != NULL) { - struct sntp_msg *sntpmsg = (struct sntp_msg *)p->payload; - LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_send_request: Sending request to server\n")); - /* initialize request message */ - sntp_initialize_request(sntpmsg); - /* send request */ - udp_sendto(sntp_pcb, p, server_addr, SNTP_PORT); - /* free the pbuf after sending it */ - pbuf_free(p); - /* set up receive timeout: try next server or retry on timeout */ - sys_timeout((u32_t)SNTP_RECV_TIMEOUT, sntp_try_next_server, NULL); -#if SNTP_CHECK_RESPONSE >= 1 - /* save server address to verify it in sntp_recv */ - ip_addr_set(&sntp_last_server_address, server_addr); -#endif /* SNTP_CHECK_RESPONSE >= 1 */ - } else { - LWIP_DEBUGF(SNTP_DEBUG_SERIOUS, ("sntp_send_request: Out of memory, trying again in %"U32_F" ms\n", - (u32_t)SNTP_RETRY_TIMEOUT)); - /* out of memory: set up a timer to send a retry */ - sys_timeout((u32_t)SNTP_RETRY_TIMEOUT, sntp_request, NULL); - } -} - -#if SNTP_SERVER_DNS -/** - * DNS found callback when using DNS names as server address. - */ -static void -sntp_dns_found(const char* hostname, const ip_addr_t *ipaddr, void *arg) -{ - LWIP_UNUSED_ARG(hostname); - LWIP_UNUSED_ARG(arg); - - if (ipaddr != NULL) { - /* Address resolved, send request */ - LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_dns_found: Server address resolved, sending request\n")); - sntp_send_request(ipaddr); - } else { - /* DNS resolving failed -> try another server */ - LWIP_DEBUGF(SNTP_DEBUG_WARN_STATE, ("sntp_dns_found: Failed to resolve server address resolved, trying next server\n")); - sntp_try_next_server(NULL); - } -} -#endif /* SNTP_SERVER_DNS */ - -/** - * Send out an sntp request. - * - * @param arg is unused (only necessary to conform to sys_timeout) - */ -static void -sntp_request(void *arg) -{ - ip_addr_t sntp_server_address; - err_t err; - - LWIP_UNUSED_ARG(arg); - - /* initialize SNTP server address */ -#if SNTP_SERVER_DNS - if (sntp_servers[sntp_current_server].name) { - /* always resolve the name and rely on dns-internal caching & timeout */ - ip_addr_set_zero(&sntp_servers[sntp_current_server].addr); - err = dns_gethostbyname(sntp_servers[sntp_current_server].name, &sntp_server_address, - sntp_dns_found, NULL); - if (err == ERR_INPROGRESS) { - /* DNS request sent, wait for sntp_dns_found being called */ - LWIP_DEBUGF(SNTP_DEBUG_STATE, ("sntp_request: Waiting for server address to be resolved.\n")); - return; - } else if (err == ERR_OK) { - sntp_servers[sntp_current_server].addr = sntp_server_address; - } - } else -#endif /* SNTP_SERVER_DNS */ - { - sntp_server_address = sntp_servers[sntp_current_server].addr; - err = (ip_addr_isany_val(sntp_server_address)) ? ERR_ARG : ERR_OK; - } - - if (err == ERR_OK) { - LWIP_DEBUGF(SNTP_DEBUG_TRACE, ("sntp_request: current server address is %s\n", - ipaddr_ntoa(&sntp_server_address))); - sntp_send_request(&sntp_server_address); - } else { - /* address conversion failed, try another server */ - LWIP_DEBUGF(SNTP_DEBUG_WARN_STATE, ("sntp_request: Invalid server address, trying next server.\n")); - sys_timeout((u32_t)SNTP_RETRY_TIMEOUT, sntp_try_next_server, NULL); - } -} - -/** - * @ingroup sntp - * Initialize this module. - * Send out request instantly or after SNTP_STARTUP_DELAY(_FUNC). - */ -void -sntp_init(void) -{ -#ifdef SNTP_SERVER_ADDRESS -#if SNTP_SERVER_DNS - sntp_setservername(0, SNTP_SERVER_ADDRESS); -#else -#error SNTP_SERVER_ADDRESS string not supported SNTP_SERVER_DNS==0 -#endif -#endif /* SNTP_SERVER_ADDRESS */ - - if (sntp_pcb == NULL) { - sntp_pcb = udp_new_ip_type(IPADDR_TYPE_ANY); - LWIP_ASSERT("Failed to allocate udp pcb for sntp client", sntp_pcb != NULL); - if (sntp_pcb != NULL) { - udp_recv(sntp_pcb, sntp_recv, NULL); - - if (sntp_opmode == SNTP_OPMODE_POLL) { - SNTP_RESET_RETRY_TIMEOUT(); -#if SNTP_STARTUP_DELAY - sys_timeout((u32_t)SNTP_STARTUP_DELAY_FUNC, sntp_request, NULL); -#else - sntp_request(NULL); -#endif - } else if (sntp_opmode == SNTP_OPMODE_LISTENONLY) { - ip_set_option(sntp_pcb, SOF_BROADCAST); - udp_bind(sntp_pcb, IP_ANY_TYPE, SNTP_PORT); - } - } - } -} - -/** - * @ingroup sntp - * Stop this module. - */ -void -sntp_stop(void) -{ - if (sntp_pcb != NULL) { - sys_untimeout(sntp_request, NULL); - sys_untimeout(sntp_try_next_server, NULL); - udp_remove(sntp_pcb); - sntp_pcb = NULL; - } -} - -/** - * @ingroup sntp - * Get enabled state. - */ -u8_t sntp_enabled(void) -{ - return (sntp_pcb != NULL)? 1 : 0; -} - -/** - * @ingroup sntp - * Sets the operating mode. - * @param operating_mode one of the available operating modes - */ -void -sntp_setoperatingmode(u8_t operating_mode) -{ - LWIP_ASSERT("Invalid operating mode", operating_mode <= SNTP_OPMODE_LISTENONLY); - LWIP_ASSERT("Operating mode must not be set while SNTP client is running", sntp_pcb == NULL); - sntp_opmode = operating_mode; -} - -/** - * @ingroup sntp - * Gets the operating mode. - */ -u8_t -sntp_getoperatingmode(void) -{ - return sntp_opmode; -} - -#if SNTP_GET_SERVERS_FROM_DHCP -/** - * Config SNTP server handling by IP address, name, or DHCP; clear table - * @param set_servers_from_dhcp enable or disable getting server addresses from dhcp - */ -void -sntp_servermode_dhcp(int set_servers_from_dhcp) -{ - u8_t new_mode = set_servers_from_dhcp ? 1 : 0; - if (sntp_set_servers_from_dhcp != new_mode) { - sntp_set_servers_from_dhcp = new_mode; - } -} -#endif /* SNTP_GET_SERVERS_FROM_DHCP */ - -/** - * @ingroup sntp - * Initialize one of the NTP servers by IP address - * - * @param idx the index of the NTP server to set must be < SNTP_MAX_SERVERS - * @param server IP address of the NTP server to set - */ -void -sntp_setserver(u8_t idx, const ip_addr_t *server) -{ - if (idx < SNTP_MAX_SERVERS) { - if (server != NULL) { - sntp_servers[idx].addr = (*server); - } else { - ip_addr_set_zero(&sntp_servers[idx].addr); - } -#if SNTP_SERVER_DNS - sntp_servers[idx].name = NULL; -#endif - } -} - -#if LWIP_DHCP && SNTP_GET_SERVERS_FROM_DHCP -/** - * Initialize one of the NTP servers by IP address, required by DHCP - * - * @param numdns the index of the NTP server to set must be < SNTP_MAX_SERVERS - * @param dnsserver IP address of the NTP server to set - */ -void -dhcp_set_ntp_servers(u8_t num, const ip4_addr_t *server) -{ - LWIP_DEBUGF(SNTP_DEBUG_TRACE, ("sntp: %s %u.%u.%u.%u as NTP server #%u via DHCP\n", - (sntp_set_servers_from_dhcp ? "Got" : "Rejected"), - ip4_addr1(server), ip4_addr2(server), ip4_addr3(server), ip4_addr4(server), num)); - if (sntp_set_servers_from_dhcp && num) { - u8_t i; - for (i = 0; (i < num) && (i < SNTP_MAX_SERVERS); i++) { - ip_addr_t addr; - ip_addr_copy_from_ip4(addr, server[i]); - sntp_setserver(i, &addr); - } - for (i = num; i < SNTP_MAX_SERVERS; i++) { - sntp_setserver(i, NULL); - } - } -} -#endif /* LWIP_DHCP && SNTP_GET_SERVERS_FROM_DHCP */ - -/** - * @ingroup sntp - * Obtain one of the currently configured by IP address (or DHCP) NTP servers - * - * @param idx the index of the NTP server - * @return IP address of the indexed NTP server or "ip_addr_any" if the NTP - * server has not been configured by address (or at all). - */ -const ip_addr_t* -sntp_getserver(u8_t idx) -{ - if (idx < SNTP_MAX_SERVERS) { - return &sntp_servers[idx].addr; - } - return IP_ADDR_ANY; -} - -#if SNTP_SERVER_DNS -/** - * Initialize one of the NTP servers by name - * - * @param numdns the index of the NTP server to set must be < SNTP_MAX_SERVERS - * @param dnsserver DNS name of the NTP server to set, to be resolved at contact time - */ -void -sntp_setservername(u8_t idx, char *server) -{ - if (idx < SNTP_MAX_SERVERS) { - sntp_servers[idx].name = server; - } -} - -/** - * Obtain one of the currently configured by name NTP servers. - * - * @param numdns the index of the NTP server - * @return IP address of the indexed NTP server or NULL if the NTP - * server has not been configured by name (or at all) - */ -char * -sntp_getservername(u8_t idx) -{ - if (idx < SNTP_MAX_SERVERS) { - return sntp_servers[idx].name; - } - return NULL; -} -#endif /* SNTP_SERVER_DNS */ - -#endif /* LWIP_UDP */ diff --git a/third_party/lwip/repo/lwip/src/apps/tftp/tftp_server.c b/third_party/lwip/repo/lwip/src/apps/tftp/tftp_server.c deleted file mode 100644 index 243b0924bd18d0..00000000000000 --- a/third_party/lwip/repo/lwip/src/apps/tftp/tftp_server.c +++ /dev/null @@ -1,417 +0,0 @@ -/****************************************************************//** - * - * @file tftp_server.c - * - * @author Logan Gunthorpe - * Dirk Ziegelmeier - * - * @brief Trivial File Transfer Protocol (RFC 1350) - * - * Copyright (c) Deltatee Enterprises Ltd. 2013 - * All rights reserved. - * - ********************************************************************/ - -/* - * Redistribution and use in source and binary forms, with or without - * modification,are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO - * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Author: Logan Gunthorpe - * Dirk Ziegelmeier - * - */ - -/** - * @defgroup tftp TFTP server - * @ingroup apps - * - * This is simple TFTP server for the lwIP raw API. - */ - -#include "lwip/apps/tftp_server.h" - -#if LWIP_UDP - -#include "lwip/udp.h" -#include "lwip/timeouts.h" -#include "lwip/debug.h" - -#define TFTP_MAX_PAYLOAD_SIZE 512 -#define TFTP_HEADER_LENGTH 4 - -#define TFTP_RRQ 1 -#define TFTP_WRQ 2 -#define TFTP_DATA 3 -#define TFTP_ACK 4 -#define TFTP_ERROR 5 - -enum tftp_error { - TFTP_ERROR_FILE_NOT_FOUND = 1, - TFTP_ERROR_ACCESS_VIOLATION = 2, - TFTP_ERROR_DISK_FULL = 3, - TFTP_ERROR_ILLEGAL_OPERATION = 4, - TFTP_ERROR_UNKNOWN_TRFR_ID = 5, - TFTP_ERROR_FILE_EXISTS = 6, - TFTP_ERROR_NO_SUCH_USER = 7 -}; - -#include - -struct tftp_state { - const struct tftp_context *ctx; - void *handle; - struct pbuf *last_data; - struct udp_pcb *upcb; - ip_addr_t addr; - u16_t port; - int timer; - int last_pkt; - u16_t blknum; - u8_t retries; - u8_t mode_write; -}; - -static struct tftp_state tftp_state; - -static void tftp_tmr(void* arg); - -static void -close_handle(void) -{ - tftp_state.port = 0; - ip_addr_set_any(0, &tftp_state.addr); - - if(tftp_state.last_data != NULL) { - pbuf_free(tftp_state.last_data); - tftp_state.last_data = NULL; - } - - sys_untimeout(tftp_tmr, NULL); - - if (tftp_state.handle) { - tftp_state.ctx->close(tftp_state.handle); - tftp_state.handle = NULL; - LWIP_DEBUGF(TFTP_DEBUG | LWIP_DBG_STATE, ("tftp: closing\n")); - } -} - -static void -send_error(const ip_addr_t *addr, u16_t port, enum tftp_error code, const char *str) -{ - int str_length = strlen(str); - struct pbuf* p; - u16_t* payload; - - p = pbuf_alloc(PBUF_TRANSPORT, (u16_t)(TFTP_HEADER_LENGTH + str_length + 1), PBUF_RAM); - if(p == NULL) { - return; - } - - payload = (u16_t*) p->payload; - payload[0] = PP_HTONS(TFTP_ERROR); - payload[1] = lwip_htons(code); - MEMCPY(&payload[2], str, str_length + 1); - - udp_sendto(tftp_state.upcb, p, addr, port); - pbuf_free(p); -} - -static void -send_ack(u16_t blknum) -{ - struct pbuf* p; - u16_t* payload; - - p = pbuf_alloc(PBUF_TRANSPORT, TFTP_HEADER_LENGTH, PBUF_RAM); - if(p == NULL) { - return; - } - payload = (u16_t*) p->payload; - - payload[0] = PP_HTONS(TFTP_ACK); - payload[1] = lwip_htons(blknum); - udp_sendto(tftp_state.upcb, p, &tftp_state.addr, tftp_state.port); - pbuf_free(p); -} - -static void -resend_data(void) -{ - struct pbuf *p = pbuf_alloc(PBUF_TRANSPORT, tftp_state.last_data->len, PBUF_RAM); - if(p == NULL) { - return; - } - - if(pbuf_copy(p, tftp_state.last_data) != ERR_OK) { - pbuf_free(p); - return; - } - - udp_sendto(tftp_state.upcb, p, &tftp_state.addr, tftp_state.port); - pbuf_free(p); -} - -static void -send_data(void) -{ - u16_t *payload; - int ret; - - if(tftp_state.last_data != NULL) { - pbuf_free(tftp_state.last_data); - } - - tftp_state.last_data = pbuf_alloc(PBUF_TRANSPORT, TFTP_HEADER_LENGTH + TFTP_MAX_PAYLOAD_SIZE, PBUF_RAM); - if(tftp_state.last_data == NULL) { - return; - } - - payload = (u16_t *) tftp_state.last_data->payload; - payload[0] = PP_HTONS(TFTP_DATA); - payload[1] = lwip_htons(tftp_state.blknum); - - ret = tftp_state.ctx->read(tftp_state.handle, &payload[2], TFTP_MAX_PAYLOAD_SIZE); - if (ret < 0) { - send_error(&tftp_state.addr, tftp_state.port, TFTP_ERROR_ACCESS_VIOLATION, "Error occured while reading the file."); - close_handle(); - return; - } - - pbuf_realloc(tftp_state.last_data, (u16_t)(TFTP_HEADER_LENGTH + ret)); - resend_data(); -} - -static void -recv(void *arg, struct udp_pcb *upcb, struct pbuf *p, const ip_addr_t *addr, u16_t port) -{ - u16_t *sbuf = (u16_t *) p->payload; - int opcode; - - LWIP_UNUSED_ARG(arg); - LWIP_UNUSED_ARG(upcb); - - if (((tftp_state.port != 0) && (port != tftp_state.port)) || - (!ip_addr_isany_val(tftp_state.addr) && !ip_addr_cmp(&tftp_state.addr, addr))) { - send_error(addr, port, TFTP_ERROR_ACCESS_VIOLATION, "Only one connection at a time is supported"); - pbuf_free(p); - return; - } - - opcode = sbuf[0]; - - tftp_state.last_pkt = tftp_state.timer; - tftp_state.retries = 0; - - switch (opcode) { - case PP_HTONS(TFTP_RRQ): /* fall through */ - case PP_HTONS(TFTP_WRQ): - { - const char tftp_null = 0; - char filename[TFTP_MAX_FILENAME_LEN]; - char mode[TFTP_MAX_MODE_LEN]; - u16_t filename_end_offset; - u16_t mode_end_offset; - - if(tftp_state.handle != NULL) { - send_error(addr, port, TFTP_ERROR_ACCESS_VIOLATION, "Only one connection at a time is supported"); - break; - } - - sys_timeout(TFTP_TIMER_MSECS, tftp_tmr, NULL); - - /* find \0 in pbuf -> end of filename string */ - filename_end_offset = pbuf_memfind(p, &tftp_null, sizeof(tftp_null), 2); - if((u16_t)(filename_end_offset-2) > sizeof(filename)) { - send_error(addr, port, TFTP_ERROR_ACCESS_VIOLATION, "Filename too long/not NULL terminated"); - break; - } - pbuf_copy_partial(p, filename, filename_end_offset-2, 2); - - /* find \0 in pbuf -> end of mode string */ - mode_end_offset = pbuf_memfind(p, &tftp_null, sizeof(tftp_null), filename_end_offset+1); - if((u16_t)(mode_end_offset-filename_end_offset) > sizeof(mode)) { - send_error(addr, port, TFTP_ERROR_ACCESS_VIOLATION, "Mode too long/not NULL terminated"); - break; - } - pbuf_copy_partial(p, mode, mode_end_offset-filename_end_offset, filename_end_offset+1); - - tftp_state.handle = tftp_state.ctx->open(filename, mode, opcode == PP_HTONS(TFTP_WRQ)); - tftp_state.blknum = 1; - - if (!tftp_state.handle) { - send_error(addr, port, TFTP_ERROR_FILE_NOT_FOUND, "Unable to open requested file."); - break; - } - - LWIP_DEBUGF(TFTP_DEBUG | LWIP_DBG_STATE, ("tftp: %s request from ", (opcode == PP_HTONS(TFTP_WRQ)) ? "write" : "read")); - ip_addr_debug_print(TFTP_DEBUG | LWIP_DBG_STATE, addr); - LWIP_DEBUGF(TFTP_DEBUG | LWIP_DBG_STATE, (" for '%s' mode '%s'\n", filename, mode)); - - ip_addr_copy(tftp_state.addr, *addr); - tftp_state.port = port; - - if (opcode == PP_HTONS(TFTP_WRQ)) { - tftp_state.mode_write = 1; - send_ack(0); - } else { - tftp_state.mode_write = 0; - send_data(); - } - - break; - } - - case PP_HTONS(TFTP_DATA): - { - int ret; - u16_t blknum; - - if (tftp_state.handle == NULL) { - send_error(addr, port, TFTP_ERROR_ACCESS_VIOLATION, "No connection"); - break; - } - - if (tftp_state.mode_write != 1) { - send_error(addr, port, TFTP_ERROR_ACCESS_VIOLATION, "Not a write connection"); - break; - } - - blknum = lwip_ntohs(sbuf[1]); - pbuf_header(p, -TFTP_HEADER_LENGTH); - - ret = tftp_state.ctx->write(tftp_state.handle, p); - if (ret < 0) { - send_error(addr, port, TFTP_ERROR_ACCESS_VIOLATION, "error writing file"); - close_handle(); - } else { - send_ack(blknum); - } - - if (p->tot_len < TFTP_MAX_PAYLOAD_SIZE) { - close_handle(); - } - break; - } - - case PP_HTONS(TFTP_ACK): - { - u16_t blknum; - int lastpkt; - - if (tftp_state.handle == NULL) { - send_error(addr, port, TFTP_ERROR_ACCESS_VIOLATION, "No connection"); - break; - } - - if (tftp_state.mode_write != 0) { - send_error(addr, port, TFTP_ERROR_ACCESS_VIOLATION, "Not a read connection"); - break; - } - - blknum = lwip_ntohs(sbuf[1]); - if (blknum != tftp_state.blknum) { - send_error(addr, port, TFTP_ERROR_UNKNOWN_TRFR_ID, "Wrong block number"); - break; - } - - lastpkt = 0; - - if (tftp_state.last_data != NULL) { - lastpkt = tftp_state.last_data->tot_len != (TFTP_MAX_PAYLOAD_SIZE + TFTP_HEADER_LENGTH); - } - - if (!lastpkt) { - tftp_state.blknum++; - send_data(); - } else { - close_handle(); - } - - break; - } - - default: - send_error(addr, port, TFTP_ERROR_ILLEGAL_OPERATION, "Unknown operation"); - break; - } - - pbuf_free(p); -} - -static void -tftp_tmr(void* arg) -{ - LWIP_UNUSED_ARG(arg); - - tftp_state.timer++; - - if (tftp_state.handle == NULL) { - return; - } - - sys_timeout(TFTP_TIMER_MSECS, tftp_tmr, NULL); - - if ((tftp_state.timer - tftp_state.last_pkt) > (TFTP_TIMEOUT_MSECS / TFTP_TIMER_MSECS)) { - if ((tftp_state.last_data != NULL) && (tftp_state.retries < TFTP_MAX_RETRIES)) { - LWIP_DEBUGF(TFTP_DEBUG | LWIP_DBG_STATE, ("tftp: timeout, retrying\n")); - resend_data(); - tftp_state.retries++; - } else { - LWIP_DEBUGF(TFTP_DEBUG | LWIP_DBG_STATE, ("tftp: timeout\n")); - close_handle(); - } - } -} - -/** @ingroup tftp - * Initialize TFTP server. - * @param ctx TFTP callback struct - */ -err_t -tftp_init(const struct tftp_context *ctx) -{ - err_t ret; - - struct udp_pcb *pcb = udp_new_ip_type(IPADDR_TYPE_ANY); - if (pcb == NULL) { - return ERR_MEM; - } - - ret = udp_bind(pcb, IP_ANY_TYPE, TFTP_PORT); - if (ret != ERR_OK) { - udp_remove(pcb); - return ret; - } - - tftp_state.handle = NULL; - tftp_state.port = 0; - tftp_state.ctx = ctx; - tftp_state.timer = 0; - tftp_state.last_data = NULL; - tftp_state.upcb = pcb; - - udp_recv(pcb, recv, NULL); - - return ERR_OK; -} - -#endif /* LWIP_UDP */ diff --git a/third_party/lwip/repo/lwip/src/core/def.c b/third_party/lwip/repo/lwip/src/core/def.c deleted file mode 100644 index 8125313f41ce35..00000000000000 --- a/third_party/lwip/repo/lwip/src/core/def.c +++ /dev/null @@ -1,222 +0,0 @@ -/** - * @file - * Common functions used throughout the stack. - * - * These are reference implementations of the byte swapping functions. - * Again with the aim of being simple, correct and fully portable. - * Byte swapping is the second thing you would want to optimize. You will - * need to port it to your architecture and in your cc.h: - * - * \#define lwip_htons(x) your_htons - * \#define lwip_htonl(x) your_htonl - * - * Note lwip_ntohs() and lwip_ntohl() are merely references to the htonx counterparts. - * - * If you \#define them to htons() and htonl(), you should - * \#define LWIP_DONT_PROVIDE_BYTEORDER_FUNCTIONS to prevent lwIP from - * defining htonx/ntohx compatibility macros. - - * @defgroup sys_nonstandard Non-standard functions - * @ingroup sys_layer - * lwIP provides default implementations for non-standard functions. - * These can be mapped to OS functions to reduce code footprint if desired. - * All defines related to this section must not be placed in lwipopts.h, - * but in arch/cc.h! - * These options cannot be \#defined in lwipopts.h since they are not options - * of lwIP itself, but options of the lwIP port to your system. - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Simon Goldschmidt - * - */ - -#include "lwip/opt.h" -#include "lwip/def.h" - -#include - -#if BYTE_ORDER == LITTLE_ENDIAN - -#if !defined(lwip_htons) -/** - * Convert an u16_t from host- to network byte order. - * - * @param n u16_t in host byte order - * @return n in network byte order - */ -u16_t -lwip_htons(u16_t n) -{ - return (u16_t)PP_HTONS(n); -} -#endif /* lwip_htons */ - -#if !defined(lwip_htonl) -/** - * Convert an u32_t from host- to network byte order. - * - * @param n u32_t in host byte order - * @return n in network byte order - */ -u32_t -lwip_htonl(u32_t n) -{ - return (u32_t)PP_HTONL(n); -} -#endif /* lwip_htonl */ - -#endif /* BYTE_ORDER == LITTLE_ENDIAN */ - -#ifndef lwip_strnstr -/** - * @ingroup sys_nonstandard - * lwIP default implementation for strnstr() non-standard function. - * This can be \#defined to strnstr() depending on your platform port. - */ -char* -lwip_strnstr(const char* buffer, const char* token, size_t n) -{ - const char* p; - size_t tokenlen = strlen(token); - if (tokenlen == 0) { - return LWIP_CONST_CAST(char *, buffer); - } - for (p = buffer; *p && (p + tokenlen <= buffer + n); p++) { - if ((*p == *token) && (strncmp(p, token, tokenlen) == 0)) { - return LWIP_CONST_CAST(char *, p); - } - } - return NULL; -} -#endif - -#ifndef lwip_stricmp -/** - * @ingroup sys_nonstandard - * lwIP default implementation for stricmp() non-standard function. - * This can be \#defined to stricmp() depending on your platform port. - */ -int -lwip_stricmp(const char* str1, const char* str2) -{ - char c1, c2; - - do { - c1 = *str1++; - c2 = *str2++; - if (c1 != c2) { - char c1_upc = c1 | 0x20; - if ((c1_upc >= 'a') && (c1_upc <= 'z')) { - /* characters are not equal an one is in the alphabet range: - downcase both chars and check again */ - char c2_upc = c2 | 0x20; - if (c1_upc != c2_upc) { - /* still not equal */ - /* don't care for < or > */ - return 1; - } - } else { - /* characters are not equal but none is in the alphabet range */ - return 1; - } - } - } while (c1 != 0); - return 0; -} -#endif - -#ifndef lwip_strnicmp -/** - * @ingroup sys_nonstandard - * lwIP default implementation for strnicmp() non-standard function. - * This can be \#defined to strnicmp() depending on your platform port. - */ -int -lwip_strnicmp(const char* str1, const char* str2, size_t len) -{ - char c1, c2; - - do { - c1 = *str1++; - c2 = *str2++; - if (c1 != c2) { - char c1_upc = c1 | 0x20; - if ((c1_upc >= 'a') && (c1_upc <= 'z')) { - /* characters are not equal an one is in the alphabet range: - downcase both chars and check again */ - char c2_upc = c2 | 0x20; - if (c1_upc != c2_upc) { - /* still not equal */ - /* don't care for < or > */ - return 1; - } - } else { - /* characters are not equal but none is in the alphabet range */ - return 1; - } - } - } while (len-- && c1 != 0); - return 0; -} -#endif - -#ifndef lwip_itoa -/** - * @ingroup sys_nonstandard - * lwIP default implementation for itoa() non-standard function. - * This can be \#defined to itoa() or snprintf(result, bufsize, "%d", number) depending on your platform port. - */ -void -lwip_itoa(char* result, size_t bufsize, int number) -{ - const int base = 10; - char* ptr = result, *ptr1 = result, tmp_char; - int tmp_value; - LWIP_UNUSED_ARG(bufsize); - - do { - tmp_value = number; - number /= base; - *ptr++ = "zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz"[35 + (tmp_value - number * base)]; - } while(number); - - /* Apply negative sign */ - if (tmp_value < 0) { - *ptr++ = '-'; - } - *ptr-- = '\0'; - while(ptr1 < ptr) { - tmp_char = *ptr; - *ptr--= *ptr1; - *ptr1++ = tmp_char; - } -} -#endif diff --git a/third_party/lwip/repo/lwip/src/core/dns.c b/third_party/lwip/repo/lwip/src/core/dns.c deleted file mode 100644 index be7deab23d0716..00000000000000 --- a/third_party/lwip/repo/lwip/src/core/dns.c +++ /dev/null @@ -1,1921 +0,0 @@ -/** - * @file - * DNS - host name to IP address resolver. - * - * @defgroup dns DNS - * @ingroup callbackstyle_api - * - * Implements a DNS host name to IP address resolver. - * - * The lwIP DNS resolver functions are used to lookup a host name and - * map it to a numerical IP address. It maintains a list of resolved - * hostnames that can be queried with the dns_lookup() function. - * New hostnames can be resolved using the dns_query() function. - * - * The lwIP version of the resolver also adds a non-blocking version of - * gethostbyname() that will work with a raw API application. This function - * checks for an IP address string first and converts it if it is valid. - * gethostbyname() then does a dns_lookup() to see if the name is - * already in the table. If so, the IP is returned. If not, a query is - * issued and the function returns with a ERR_INPROGRESS status. The app - * using the dns client must then go into a waiting state. - * - * Once a hostname has been resolved (or found to be non-existent), - * the resolver code calls a specified callback function (which - * must be implemented by the module that uses the resolver). - * - * Multicast DNS queries are supported for names ending on ".local". - * However, only "One-Shot Multicast DNS Queries" are supported (RFC 6762 - * chapter 5.1), this is not a fully compliant implementation of continuous - * mDNS querying! - * - * All functions must be called from TCPIP thread. - * - * @see @ref netconn_common for thread-safe access. - */ - -/* - * Port to lwIP from uIP - * by Jim Pettinato April 2007 - * - * security fixes and more by Simon Goldschmidt - * - * uIP version Copyright (c) 2002-2003, Adam Dunkels. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/*----------------------------------------------------------------------------- - * RFC 1035 - Domain names - implementation and specification - * RFC 2181 - Clarifications to the DNS Specification - *----------------------------------------------------------------------------*/ - -/** @todo: define good default values (rfc compliance) */ -/** @todo: improve answer parsing, more checkings... */ -/** @todo: check RFC1035 - 7.3. Processing responses */ -/** @todo: one-shot mDNS: dual-stack fallback to another IP version */ - -/*----------------------------------------------------------------------------- - * Includes - *----------------------------------------------------------------------------*/ - -#include "lwip/opt.h" - -#if LWIP_DNS /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/def.h" -#include "lwip/udp.h" -#include "lwip/mem.h" -#include "lwip/memp.h" -#include "lwip/dns.h" -#include "lwip/prot/dns.h" - -#include -#include - -/** Random generator function to create random TXIDs and source ports for queries */ -#ifndef DNS_RAND_TXID -#if ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_RAND_XID) != 0) -#define DNS_RAND_TXID LWIP_RAND -#else -static u16_t dns_txid; -#define DNS_RAND_TXID() (++dns_txid) -#endif -#endif - -/** Limits the source port to be >= 1024 by default */ -#ifndef DNS_PORT_ALLOWED -#define DNS_PORT_ALLOWED(port) ((port) >= 1024) -#endif - -/** DNS maximum number of retries when asking for a name, before "timeout". */ -#ifndef DNS_MAX_RETRIES -#define DNS_MAX_RETRIES 4 -#endif - -/** DNS resource record max. TTL (one week as default) */ -#ifndef DNS_MAX_TTL -#define DNS_MAX_TTL 604800 -#elif DNS_MAX_TTL > 0x7FFFFFFF -#error DNS_MAX_TTL must be a positive 32-bit value -#endif - -#if DNS_TABLE_SIZE > 255 -#error DNS_TABLE_SIZE must fit into an u8_t -#endif -#if DNS_MAX_SERVERS > 255 -#error DNS_MAX_SERVERS must fit into an u8_t -#endif - -/* The number of parallel requests (i.e. calls to dns_gethostbyname - * that cannot be answered from the DNS table. - * This is set to the table size by default. - */ -#if ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_NO_MULTIPLE_OUTSTANDING) != 0) -#ifndef DNS_MAX_REQUESTS -#define DNS_MAX_REQUESTS DNS_TABLE_SIZE -#else -#if DNS_MAX_REQUESTS > 255 -#error DNS_MAX_REQUESTS must fit into an u8_t -#endif -#endif -#else -/* In this configuration, both arrays have to have the same size and are used - * like one entry (used/free) */ -#define DNS_MAX_REQUESTS DNS_TABLE_SIZE -#endif - -/* The number of UDP source ports used in parallel */ -#if ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_RAND_SRC_PORT) != 0) -#ifndef DNS_MAX_SOURCE_PORTS -#define DNS_MAX_SOURCE_PORTS DNS_MAX_REQUESTS -#else -#if DNS_MAX_SOURCE_PORTS > 255 -#error DNS_MAX_SOURCE_PORTS must fit into an u8_t -#endif -#endif -#else -#ifdef DNS_MAX_SOURCE_PORTS -#undef DNS_MAX_SOURCE_PORTS -#endif -#define DNS_MAX_SOURCE_PORTS 1 -#endif - -#if LWIP_IPV4 && LWIP_IPV6 -#define LWIP_DNS_ADDRTYPE_IS_IPV6(t) (((t) == LWIP_DNS_ADDRTYPE_IPV6_IPV4) || ((t) == LWIP_DNS_ADDRTYPE_IPV6)) -#define LWIP_DNS_ADDRTYPE_MATCH_IP(t, ip) (IP_IS_V6_VAL(ip) ? LWIP_DNS_ADDRTYPE_IS_IPV6(t) : (!LWIP_DNS_ADDRTYPE_IS_IPV6(t))) -#define LWIP_DNS_ADDRTYPE_ARG(x) , x -#define LWIP_DNS_ADDRTYPE_ARG_OR_ZERO(x) x -#define LWIP_DNS_SET_ADDRTYPE(x, y) do { x = y; } while(0) -#else -#if LWIP_IPV6 -#define LWIP_DNS_ADDRTYPE_IS_IPV6(t) 1 -#else -#define LWIP_DNS_ADDRTYPE_IS_IPV6(t) 0 -#endif -#define LWIP_DNS_ADDRTYPE_MATCH_IP(t, ip) 1 -#define LWIP_DNS_ADDRTYPE_ARG(x) -#define LWIP_DNS_ADDRTYPE_ARG_OR_ZERO(x) 0 -#define LWIP_DNS_SET_ADDRTYPE(x, y) -#endif /* LWIP_IPV4 && LWIP_IPV6 */ - -#if LWIP_DNS_SUPPORT_MDNS_QUERIES -#define LWIP_DNS_ISMDNS_ARG(x) , x -#else -#define LWIP_DNS_ISMDNS_ARG(x) -#endif - -#if DNS_MAX_ADDRS_PER_NAME > 1 -#define LWIP_DNS_NUMIPADDRS_ARG(x) , x -#define LWIP_DNS_ISMULTI_ARG(x) , x -#else -#define LWIP_DNS_NUMIPADDRS_ARG(x) -#define LWIP_DNS_ISMULTI_ARG(x) -#endif - -/** DNS query message structure. - No packing needed: only used locally on the stack. */ -struct dns_query { - /* DNS query record starts with either a domain name or a pointer - to a name already present somewhere in the packet. */ - u16_t type; - u16_t cls; -}; -#define SIZEOF_DNS_QUERY 4 - -/** DNS answer message structure. - No packing needed: only used locally on the stack. */ -struct dns_answer { - /* DNS answer record starts with either a domain name or a pointer - to a name already present somewhere in the packet. */ - u16_t type; - u16_t cls; - u32_t ttl; - u16_t len; -}; -#define SIZEOF_DNS_ANSWER 10 -/* maximum allowed size for the struct due to non-packed */ -#define SIZEOF_DNS_ANSWER_ASSERT 12 - -/* DNS table entry states */ -typedef enum { - DNS_STATE_UNUSED = 0, - DNS_STATE_NEW = 1, - DNS_STATE_ASKING = 2, - DNS_STATE_UNANSWERED = 3, - DNS_STATE_DONE = 4 -} dns_state_enum_t; - -/** DNS table entry */ -struct dns_table_entry { - u32_t ttl; - u16_t txid; - u8_t state; - u8_t server_idx; - u8_t tmr; -#if DNS_MAX_ADDRS_PER_NAME > 1 - u8_t is_multi; -#endif - u8_t retries; - u8_t seqno; -#if ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_RAND_SRC_PORT) != 0) - u8_t pcb_idx; -#endif - u8_t err; - char name[DNS_MAX_NAME_LENGTH]; -#if DNS_MAX_ADDRS_PER_NAME > 1 - ip_addr_t ipaddrs[DNS_MAX_ADDRS_PER_NAME]; - u8_t numipaddrs; - u8_t offset; -#else - ip_addr_t addr; -#endif -#if LWIP_IPV4 && LWIP_IPV6 - u8_t reqaddrtype; -#endif /* LWIP_IPV4 && LWIP_IPV6 */ -#if LWIP_DNS_SUPPORT_MDNS_QUERIES - u8_t is_mdns; -#endif -}; - -/** DNS request table entry: used when dns_gehostbyname cannot answer the - * request from the DNS table */ -struct dns_req_entry { - /* pointer to callback on DNS query done */ - LWIP_DNS_FOUND_CALLBACK_TYPE found; - /* argument passed to the callback function */ - void *arg; -#if ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_NO_MULTIPLE_OUTSTANDING) != 0) - u8_t dns_table_idx; -#endif -#if LWIP_IPV4 && LWIP_IPV6 - u8_t reqaddrtype; -#endif /* LWIP_IPV4 && LWIP_IPV6 */ -#if DNS_MAX_ADDRS_PER_NAME > 1 - u8_t is_multi; -#endif -}; - -#if DNS_LOCAL_HOSTLIST - -#if DNS_LOCAL_HOSTLIST_IS_DYNAMIC -/** Local host-list. For hostnames in this list, no - * external name resolution is performed */ -static struct local_hostlist_entry *local_hostlist_dynamic; -#else /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ - -/** Defining this allows the local_hostlist_static to be placed in a different - * linker section (e.g. FLASH) */ -#ifndef DNS_LOCAL_HOSTLIST_STORAGE_PRE -#define DNS_LOCAL_HOSTLIST_STORAGE_PRE static -#endif /* DNS_LOCAL_HOSTLIST_STORAGE_PRE */ -/** Defining this allows the local_hostlist_static to be placed in a different - * linker section (e.g. FLASH) */ -#ifndef DNS_LOCAL_HOSTLIST_STORAGE_POST -#define DNS_LOCAL_HOSTLIST_STORAGE_POST -#endif /* DNS_LOCAL_HOSTLIST_STORAGE_POST */ -DNS_LOCAL_HOSTLIST_STORAGE_PRE struct local_hostlist_entry local_hostlist_static[] - DNS_LOCAL_HOSTLIST_STORAGE_POST = DNS_LOCAL_HOSTLIST_INIT; - -#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ - -static void dns_init_local(void); -static err_t dns_lookup_local(const char *hostname, ip_addr_t *addr LWIP_DNS_ADDRTYPE_ARG(u8_t dns_addrtype)); -#endif /* DNS_LOCAL_HOSTLIST */ - - -/* forward declarations */ -static void dns_recv(void *s, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port); -static void dns_check_entries(void); -static void dns_call_found(u8_t idx, ip_addr_t* addr); - -/*----------------------------------------------------------------------------- - * Globals - *----------------------------------------------------------------------------*/ - -/* DNS variables */ -static struct udp_pcb *dns_pcbs[DNS_MAX_SOURCE_PORTS]; -#if ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_RAND_SRC_PORT) != 0) -static u8_t dns_last_pcb_idx; -#endif -static u8_t dns_seqno; -static struct dns_table_entry dns_table[DNS_TABLE_SIZE]; -static struct dns_req_entry dns_requests[DNS_MAX_REQUESTS]; -static ip_addr_t dns_servers[DNS_MAX_SERVERS]; - -#if LWIP_IPV4 -const ip_addr_t dns_mquery_v4group = DNS_MQUERY_IPV4_GROUP_INIT; -#endif /* LWIP_IPV4 */ -#if LWIP_IPV6 -const ip_addr_t dns_mquery_v6group = DNS_MQUERY_IPV6_GROUP_INIT; -#endif /* LWIP_IPV6 */ - -/** - * Initialize the resolver: set up the UDP pcb and configure the default server - * (if DNS_SERVER_ADDRESS is set). - */ -void -dns_init(void) -{ -#ifdef DNS_SERVER_ADDRESS - /* initialize default DNS server address */ - ip_addr_t dnsserver; - DNS_SERVER_ADDRESS(&dnsserver); - dns_setserver(0, &dnsserver); -#endif /* DNS_SERVER_ADDRESS */ - - LWIP_ASSERT("sanity check SIZEOF_DNS_QUERY", - sizeof(struct dns_query) == SIZEOF_DNS_QUERY); - LWIP_ASSERT("sanity check SIZEOF_DNS_ANSWER", - sizeof(struct dns_answer) <= SIZEOF_DNS_ANSWER_ASSERT); - - LWIP_DEBUGF(DNS_DEBUG, ("dns_init: initializing\n")); - - /* if dns client not yet initialized... */ -#if ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_RAND_SRC_PORT) == 0) - if (dns_pcbs[0] == NULL) { - dns_pcbs[0] = udp_new_ip_type(IPADDR_TYPE_ANY); - LWIP_ASSERT("dns_pcbs[0] != NULL", dns_pcbs[0] != NULL); - - /* initialize DNS table not needed (initialized to zero since it is a - * global variable) */ - LWIP_ASSERT("For implicit initialization to work, DNS_STATE_UNUSED needs to be 0", - DNS_STATE_UNUSED == 0); - - /* initialize DNS client */ - udp_bind(dns_pcbs[0], IP_ANY_TYPE, 0); - udp_recv(dns_pcbs[0], dns_recv, NULL); - } -#endif - -#if DNS_LOCAL_HOSTLIST - dns_init_local(); -#endif -} - -/** - * @ingroup dns - * Initialize one of the DNS servers. - * - * @param numdns the index of the DNS server to set must be < DNS_MAX_SERVERS - * @param dnsserver IP address of the DNS server to set - */ -void -dns_setserver(u8_t numdns, const ip_addr_t *dnsserver) -{ - if (numdns < DNS_MAX_SERVERS) { - if (dnsserver != NULL) { - dns_servers[numdns] = (*dnsserver); - } else { - dns_servers[numdns] = *IP_ADDR_ANY; - } - } -} - -/** - * @ingroup dns - * Obtain one of the currently configured DNS server. - * - * @param numdns the index of the DNS server - * @return IP address of the indexed DNS server or "ip_addr_any" if the DNS - * server has not been configured. - */ -const ip_addr_t* -dns_getserver(u8_t numdns) -{ - if (numdns < DNS_MAX_SERVERS) { - return &dns_servers[numdns]; - } else { - return IP_ADDR_ANY; - } -} - -/** - * The DNS resolver client timer - handle retries and timeouts and should - * be called every DNS_TMR_INTERVAL milliseconds (every second by default). - */ -void -dns_tmr(void) -{ - LWIP_DEBUGF(DNS_DEBUG, ("dns_tmr: dns_check_entries\n")); - dns_check_entries(); -} - -#if DNS_LOCAL_HOSTLIST -static void -dns_init_local(void) -{ -#if DNS_LOCAL_HOSTLIST_IS_DYNAMIC && defined(DNS_LOCAL_HOSTLIST_INIT) - size_t i; - struct local_hostlist_entry *entry; - /* Dynamic: copy entries from DNS_LOCAL_HOSTLIST_INIT to list */ - struct local_hostlist_entry local_hostlist_init[] = DNS_LOCAL_HOSTLIST_INIT; - size_t namelen; - for (i = 0; i < LWIP_ARRAYSIZE(local_hostlist_init); i++) { - struct local_hostlist_entry *init_entry = &local_hostlist_init[i]; - LWIP_ASSERT("invalid host name (NULL)", init_entry->name != NULL); - namelen = strlen(init_entry->name); - LWIP_ASSERT("namelen <= DNS_LOCAL_HOSTLIST_MAX_NAMELEN", namelen <= DNS_LOCAL_HOSTLIST_MAX_NAMELEN); - entry = (struct local_hostlist_entry *)memp_malloc(MEMP_LOCALHOSTLIST); - LWIP_ASSERT("mem-error in dns_init_local", entry != NULL); - if (entry != NULL) { - char* entry_name = (char*)entry + sizeof(struct local_hostlist_entry); - MEMCPY(entry_name, init_entry->name, namelen); - entry_name[namelen] = 0; - entry->name = entry_name; - entry->addr = init_entry->addr; - entry->next = local_hostlist_dynamic; - local_hostlist_dynamic = entry; - } - } -#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC && defined(DNS_LOCAL_HOSTLIST_INIT) */ -} - -/** - * @ingroup dns - * Iterate the local host-list for a hostname. - * - * @param iterator_fn a function that is called for every entry in the local host-list - * @param iterator_arg 3rd argument passed to iterator_fn - * @return the number of entries in the local host-list - */ -size_t -dns_local_iterate(dns_found_callback iterator_fn, void *iterator_arg) -{ - size_t i; -#if DNS_LOCAL_HOSTLIST_IS_DYNAMIC - struct local_hostlist_entry *entry = local_hostlist_dynamic; - i = 0; - while (entry != NULL) { - if (iterator_fn != NULL) { - iterator_fn(entry->name, &entry->addr, iterator_arg); - } - i++; - entry = entry->next; - } -#else /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ - for (i = 0; i < LWIP_ARRAYSIZE(local_hostlist_static); i++) { - if (iterator_fn != NULL) { - iterator_fn(local_hostlist_static[i].name, &local_hostlist_static[i].addr, iterator_arg); - } - } -#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ - return i; -} - -/** - * @ingroup dns - * Scans the local host-list for a hostname. - * - * @param hostname Hostname to look for in the local host-list - * @param addr the first IP address for the hostname in the local host-list or - * IPADDR_NONE if not found. - * @param dns_addrtype - LWIP_DNS_ADDRTYPE_IPV4_IPV6: try to resolve IPv4 (ATTENTION: no fallback here!) - * - LWIP_DNS_ADDRTYPE_IPV6_IPV4: try to resolve IPv6 (ATTENTION: no fallback here!) - * - LWIP_DNS_ADDRTYPE_IPV4: try to resolve IPv4 only - * - LWIP_DNS_ADDRTYPE_IPV6: try to resolve IPv6 only - * @return ERR_OK if found, ERR_ARG if not found - */ -err_t -dns_local_lookup(const char *hostname, ip_addr_t *addr, u8_t dns_addrtype) -{ - LWIP_UNUSED_ARG(dns_addrtype); - return dns_lookup_local(hostname, addr LWIP_DNS_ADDRTYPE_ARG(dns_addrtype)); -} - -/* Internal implementation for dns_local_lookup and dns_lookup */ -static err_t -dns_lookup_local(const char *hostname, ip_addr_t *addr LWIP_DNS_ADDRTYPE_ARG(u8_t dns_addrtype)) -{ -#if DNS_LOCAL_HOSTLIST_IS_DYNAMIC - struct local_hostlist_entry *entry = local_hostlist_dynamic; - while (entry != NULL) { - if ((lwip_stricmp(entry->name, hostname) == 0) && - LWIP_DNS_ADDRTYPE_MATCH_IP(dns_addrtype, entry->addr)) { - if (addr) { - ip_addr_copy(*addr, entry->addr); - } - return ERR_OK; - } - entry = entry->next; - } -#else /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ - size_t i; - for (i = 0; i < LWIP_ARRAYSIZE(local_hostlist_static); i++) { - if ((lwip_stricmp(local_hostlist_static[i].name, hostname) == 0) && - LWIP_DNS_ADDRTYPE_MATCH_IP(dns_addrtype, local_hostlist_static[i].addr)) { - if (addr) { - ip_addr_copy(*addr, local_hostlist_static[i].addr); - } - return ERR_OK; - } - } -#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ - return ERR_ARG; -} - -#if DNS_LOCAL_HOSTLIST_IS_DYNAMIC -/** - * @ingroup dns - * Remove all entries from the local host-list for a specific hostname - * and/or IP address - * - * @param hostname hostname for which entries shall be removed from the local - * host-list - * @param addr address for which entries shall be removed from the local host-list - * @return the number of removed entries - */ -int -dns_local_removehost(const char *hostname, const ip_addr_t *addr) -{ - int removed = 0; - struct local_hostlist_entry *entry = local_hostlist_dynamic; - struct local_hostlist_entry *last_entry = NULL; - while (entry != NULL) { - if (((hostname == NULL) || !lwip_stricmp(entry->name, hostname)) && - ((addr == NULL) || ip_addr_cmp(&entry->addr, addr))) { - struct local_hostlist_entry *free_entry; - if (last_entry != NULL) { - last_entry->next = entry->next; - } else { - local_hostlist_dynamic = entry->next; - } - free_entry = entry; - entry = entry->next; - memp_free(MEMP_LOCALHOSTLIST, free_entry); - removed++; - } else { - last_entry = entry; - entry = entry->next; - } - } - return removed; -} - -/** - * @ingroup dns - * Add a hostname/IP address pair to the local host-list. - * Duplicates are not checked. - * - * @param hostname hostname of the new entry - * @param addr IP address of the new entry - * @return ERR_OK if succeeded or ERR_MEM on memory error - */ -err_t -dns_local_addhost(const char *hostname, const ip_addr_t *addr) -{ - struct local_hostlist_entry *entry; - size_t namelen; - char* entry_name; - LWIP_ASSERT("invalid host name (NULL)", hostname != NULL); - namelen = strlen(hostname); - LWIP_ASSERT("namelen <= DNS_LOCAL_HOSTLIST_MAX_NAMELEN", namelen <= DNS_LOCAL_HOSTLIST_MAX_NAMELEN); - entry = (struct local_hostlist_entry *)memp_malloc(MEMP_LOCALHOSTLIST); - if (entry == NULL) { - return ERR_MEM; - } - entry_name = (char*)entry + sizeof(struct local_hostlist_entry); - MEMCPY(entry_name, hostname, namelen); - entry_name[namelen] = 0; - entry->name = entry_name; - ip_addr_copy(entry->addr, *addr); - entry->next = local_hostlist_dynamic; - local_hostlist_dynamic = entry; - return ERR_OK; -} -#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC*/ -#endif /* DNS_LOCAL_HOSTLIST */ - -/** - * @ingroup dns - * Look up a hostname in the array of known hostnames. - * - * @note This function only looks in the internal array of known - * hostnames, it does not send out a query for the hostname if none - * was found. The function dns_enqueue() can be used to send a query - * for a hostname. - * - * @param name the hostname to look up - * @param addr the hostname's IP address, as u32_t (instead of ip_addr_t to - * better check for failure: != IPADDR_NONE) or IPADDR_NONE if the hostname - * was not found in the cached dns_table. - * @return ERR_OK if found, ERR_ARG if not found - * @param ipaddrs the ip_addr_t array where the found IP addresses are saved (if any) - * @param numipaddrs maximum number of IP addresses the caller is asking for - * @return true if at least one IP address is associated with hostname (false if none are found) - */ -static err_t -dns_lookup(const char *name, ip_addr_t *ipaddr LWIP_DNS_NUMIPADDRS_ARG(u8_t *numipaddrs) LWIP_DNS_ADDRTYPE_ARG(u8_t dns_addrtype)) -{ - u8_t i, j; -#if DNS_LOCAL_HOSTLIST || defined(DNS_LOOKUP_LOCAL_EXTERN) -#endif /* DNS_LOCAL_HOSTLIST || defined(DNS_LOOKUP_LOCAL_EXTERN) */ -#if DNS_LOCAL_HOSTLIST - if (dns_lookup_local(name, ipaddr LWIP_DNS_ADDRTYPE_ARG(dns_addrtype)) == ERR_OK) { -#if DNS_MAX_ADDRS_PER_NAME > 1 - *numipaddrs = 1; -#endif - return ERR_OK; - } -#endif /* DNS_LOCAL_HOSTLIST */ -#ifdef DNS_LOOKUP_LOCAL_EXTERN - if (DNS_LOOKUP_LOCAL_EXTERN(name, ipaddr, LWIP_DNS_ADDRTYPE_ARG_OR_ZERO(dns_addrtype)) == ERR_OK) { -#if DNS_MAX_ADDRS_PER_NAME > 1 - *numipaddrs = 1; -#endif - return ERR_OK; - } -#endif /* DNS_LOOKUP_LOCAL_EXTERN */ - - /* Walk through name list, return true if found. If not, return false. */ - for (i = 0; i < DNS_TABLE_SIZE; ++i) { - if ((dns_table[i].state == DNS_STATE_DONE) && - (lwip_strnicmp(name, dns_table[i].name, sizeof(dns_table[i].name)) == 0) -#if LWIP_IPV4 && LWIP_IPV6 - && dns_addrtype == dns_table[i].reqaddrtype -#endif - ) { -#if DNS_MAX_ADDRS_PER_NAME > 1 - ++dns_table[i].offset; - if (dns_table[i].offset >= DNS_MAX_ADDRS_PER_NAME) { - dns_table[i].offset = 0; - } - *numipaddrs = LWIP_MIN(dns_table[i].numipaddrs, *numipaddrs); - if (*numipaddrs > 0) { - LWIP_DEBUGF(DNS_DEBUG, ("dns_lookup: \"%s\": ", name)); - for (j = 0; j < *numipaddrs; ++j) { - memcpy(&ipaddr[j], &dns_table[i].ipaddrs[(dns_table[i].offset + j) % dns_table[i].numipaddrs], sizeof(ip_addr_t)); - LWIP_DEBUGF(DNS_DEBUG, (" found=")); - ip_addr_debug_print(DNS_DEBUG, &ipaddr[j]); - } - LWIP_DEBUGF(DNS_DEBUG, ("\n")); - } -#else - LWIP_DEBUGF(DNS_DEBUG, ("dns_lookup: \"%s\": found = ", name)); - ip_addr_debug_print(DNS_DEBUG, &(dns_table[i].ipaddr)); - LWIP_DEBUGF(DNS_DEBUG, ("\n")); - if (ipaddr) { - ip_addr_copy(*ipaddr, dns_table[i].ipaddr); - } -#endif - return ERR_OK; - } - } - - return ERR_ARG; -} - -/** - * Compare the "dotted" name "query" with the encoded name "response" - * to make sure an answer from the DNS server matches the current dns_table - * entry (otherwise, answers might arrive late for hostname not on the list - * any more). - * - * @param query hostname (not encoded) from the dns_table - * @param p pbuf containing the encoded hostname in the DNS response - * @param start_offset offset into p where the name starts - * @return 0xFFFF: names differ, other: names equal -> offset behind name - */ -static u16_t -dns_compare_name(const char *query, struct pbuf* p, u16_t start_offset) -{ - int n; - u16_t response_offset = start_offset; - - do { - n = pbuf_try_get_at(p, response_offset++); - if (n < 0) { - return 0xFFFF; - } - /** @see RFC 1035 - 4.1.4. Message compression */ - if ((n & 0xc0) == 0xc0) { - /* Compressed name: cannot be equal since we don't send them */ - return 0xFFFF; - } else { - /* Not compressed name */ - while (n > 0) { - int c = pbuf_try_get_at(p, response_offset); - if (c < 0) { - return 0xFFFF; - } - if ((*query) != (u8_t)c) { - return 0xFFFF; - } - ++response_offset; - ++query; - --n; - } - ++query; - } - n = pbuf_try_get_at(p, response_offset); - if (n < 0) { - return 0xFFFF; - } - } while (n != 0); - - return response_offset + 1; -} - -/** - * Walk through a compact encoded DNS name and return the end of the name. - * - * @param p pbuf containing the name - * @param query_idx start index into p pointing to encoded DNS name in the DNS server response - * @return index to end of the name - */ -static u16_t -dns_skip_name(struct pbuf* p, u16_t query_idx) -{ - int n; - u16_t offset = query_idx; - - do { - n = pbuf_try_get_at(p, offset++); - if (n < 0) { - return 0xFFFF; - } - /** @see RFC 1035 - 4.1.4. Message compression */ - if ((n & 0xc0) == 0xc0) { - /* Compressed name: since we only want to skip it (not check it), stop here */ - break; - } else { - /* Not compressed name */ - if (offset + n >= p->tot_len) { - return 0xFFFF; - } - offset = (u16_t)(offset + n); - } - n = pbuf_try_get_at(p, offset); - if (n < 0) { - return 0xFFFF; - } - } while (n != 0); - - return offset + 1; -} - -/** - * Send a DNS query packet. - * - * @param idx the DNS table entry index for which to send a request - * @return ERR_OK if packet is sent; an err_t indicating the problem otherwise - */ -static err_t -dns_send(u8_t idx) -{ - err_t err; - struct dns_hdr hdr; - struct dns_query qry; - struct pbuf *p; - u16_t query_idx, copy_len; - const char *hostname, *hostname_part; - u8_t n; - u8_t pcb_idx; - struct dns_table_entry* entry = &dns_table[idx]; - - LWIP_DEBUGF(DNS_DEBUG, ("dns_send: dns_servers[%"U16_F"] \"%s\": request\n", - (u16_t)(entry->server_idx), entry->name)); - LWIP_ASSERT("dns server out of array", entry->server_idx < DNS_MAX_SERVERS); - if (ip_addr_isany_val(dns_servers[entry->server_idx]) -#if LWIP_DNS_SUPPORT_MDNS_QUERIES - && !entry->is_mdns -#endif - ) { - /* DNS server not valid anymore, e.g. PPP netif has been shut down */ - /* call specified callback function if provided */ - dns_call_found(idx, NULL); - /* flush this entry */ - entry->state = DNS_STATE_UNUSED; - return ERR_OK; - } - - /* if here, we have either a new query or a retry on a previous query to process */ - p = pbuf_alloc(PBUF_TRANSPORT, (u16_t)(SIZEOF_DNS_HDR + strlen(entry->name) + 2 + - SIZEOF_DNS_QUERY), PBUF_RAM); - if (p != NULL) { - const ip_addr_t* dst; - u16_t dst_port; - /* fill dns header */ - memset(&hdr, 0, SIZEOF_DNS_HDR); - hdr.id = lwip_htons(entry->txid); - hdr.flags1 = DNS_FLAG1_RD; - hdr.numquestions = PP_HTONS(1); - pbuf_take(p, &hdr, SIZEOF_DNS_HDR); - hostname = entry->name; - --hostname; - - /* convert hostname into suitable query format. */ - query_idx = SIZEOF_DNS_HDR; - do { - ++hostname; - hostname_part = hostname; - for (n = 0; *hostname != '.' && *hostname != 0; ++hostname) { - ++n; - } - copy_len = (u16_t)(hostname - hostname_part); - pbuf_put_at(p, query_idx, n); - pbuf_take_at(p, hostname_part, copy_len, query_idx + 1); - query_idx += n + 1; - } while (*hostname != 0); - pbuf_put_at(p, query_idx, 0); - query_idx++; - - /* fill dns query */ - if (LWIP_DNS_ADDRTYPE_IS_IPV6(entry->reqaddrtype)) { - qry.type = PP_HTONS(DNS_RRTYPE_AAAA); - } else { - qry.type = PP_HTONS(DNS_RRTYPE_A); - } - qry.cls = PP_HTONS(DNS_RRCLASS_IN); - pbuf_take_at(p, &qry, SIZEOF_DNS_QUERY, query_idx); - -#if ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_RAND_SRC_PORT) != 0) - pcb_idx = entry->pcb_idx; -#else - pcb_idx = 0; -#endif - /* send dns packet */ - LWIP_DEBUGF(DNS_DEBUG, ("sending DNS request ID %d for name \"%s\" to server %d\r\n", - entry->txid, entry->name, entry->server_idx)); -#if LWIP_DNS_SUPPORT_MDNS_QUERIES - if (entry->is_mdns) { - dst_port = DNS_MQUERY_PORT; -#if LWIP_IPV6 - if (LWIP_DNS_ADDRTYPE_IS_IPV6(entry->reqaddrtype)) - { - dst = &dns_mquery_v6group; - } -#endif -#if LWIP_IPV4 && LWIP_IPV6 - else -#endif -#if LWIP_IPV4 - { - dst = &dns_mquery_v4group; - } -#endif - } else -#endif /* LWIP_DNS_SUPPORT_MDNS_QUERIES */ - { - dst_port = DNS_SERVER_PORT; - dst = &dns_servers[entry->server_idx]; - } - err = udp_sendto(dns_pcbs[pcb_idx], p, dst, dst_port); - - /* free pbuf */ - pbuf_free(p); - } else { - err = ERR_MEM; - } - - return err; -} - -#if ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_RAND_SRC_PORT) != 0) -static struct udp_pcb* -dns_alloc_random_port(void) -{ - err_t err; - struct udp_pcb* ret; - - ret = udp_new_ip_type(IPADDR_TYPE_ANY); - if (ret == NULL) { - /* out of memory, have to reuse an existing pcb */ - return NULL; - } - do { - u16_t port = (u16_t)DNS_RAND_TXID(); - if (!DNS_PORT_ALLOWED(port)) { - /* this port is not allowed, try again */ - err = ERR_USE; - continue; - } - err = udp_bind(ret, IP_ANY_TYPE, port); - } while (err == ERR_USE); - if (err != ERR_OK) { - udp_remove(ret); - return NULL; - } - udp_recv(ret, dns_recv, NULL); - return ret; -} - -/** - * dns_alloc_pcb() - allocates a new pcb (or reuses an existing one) to be used - * for sending a request - * - * @return an index into dns_pcbs - */ -static u8_t -dns_alloc_pcb(void) -{ - u8_t i; - u8_t idx; - - for (i = 0; i < DNS_MAX_SOURCE_PORTS; i++) { - if (dns_pcbs[i] == NULL) { - break; - } - } - if (i < DNS_MAX_SOURCE_PORTS) { - dns_pcbs[i] = dns_alloc_random_port(); - if (dns_pcbs[i] != NULL) { - /* succeeded */ - dns_last_pcb_idx = i; - return i; - } - } - /* if we come here, creating a new UDP pcb failed, so we have to use - an already existing one */ - for (i = 0, idx = dns_last_pcb_idx + 1; i < DNS_MAX_SOURCE_PORTS; i++, idx++) { - if (idx >= DNS_MAX_SOURCE_PORTS) { - idx = 0; - } - if (dns_pcbs[idx] != NULL) { - dns_last_pcb_idx = idx; - return idx; - } - } - return DNS_MAX_SOURCE_PORTS; -} -#endif /* ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_RAND_SRC_PORT) != 0) */ - -/** - * Call appropriate single or multi version of found callback. - * - * @param entry the pointer to the DNS cache entry - * @param error boolean indicating error - */ -static void -dns_exec_found_callback(const struct dns_req_entry *req, err_t err) { - if (req->found) { - const struct dns_table_entry *tbl = &dns_table[req->dns_table_idx]; - LWIP_ASSERT("invalid table index", req->dns_table_idx < DNS_TABLE_SIZE); -#if DNS_MAX_ADDRS_PER_NAME > 1 - if (req->is_multi) { - if (tbl->numipaddrs == 0 || err) { - ((dns_found_callback_multi)(*req->found))(tbl->name, NULL, 0, req->arg); - } else { - ((dns_found_callback_multi)(*req->found))(tbl->name, tbl->ipaddrs, tbl->numipaddrs, req->arg); - } - } else { - if (tbl->numipaddrs == 0 || err) { - ((dns_found_callback)(*req->found))(tbl->name, NULL, req->arg); - } else { - ((dns_found_callback)(*req->found))(tbl->name, tbl->ipaddrs, req->arg); - } - } -#else - (*req->found)(tbl->name, (err ? tbl->addr : NULL), req->arg); -#endif - } -} - -/** - * dns_call_found() - call the found callback and check if there are duplicate - * entries for the given hostname. If there are any, their found callback will - * be called and they will be removed. - * - * @param idx dns table index of the entry that is resolved or removed - * @param addr IP address for the hostname (or NULL on error or memory shortage) - */ -static void -dns_call_found(u8_t idx, ip_addr_t* addr) -{ -#if ((LWIP_DNS_SECURE & (LWIP_DNS_SECURE_NO_MULTIPLE_OUTSTANDING | LWIP_DNS_SECURE_RAND_SRC_PORT)) != 0) - u8_t i; -#endif - -#if LWIP_IPV4 && LWIP_IPV6 - if (addr != NULL) { - /* check that address type matches the request and adapt the table entry */ - if (IP_IS_V6_VAL(*addr)) { - LWIP_ASSERT("invalid response", LWIP_DNS_ADDRTYPE_IS_IPV6(dns_table[idx].reqaddrtype)); - dns_table[idx].reqaddrtype = LWIP_DNS_ADDRTYPE_IPV6; - } else { - LWIP_ASSERT("invalid response", !LWIP_DNS_ADDRTYPE_IS_IPV6(dns_table[idx].reqaddrtype)); - dns_table[idx].reqaddrtype = LWIP_DNS_ADDRTYPE_IPV4; - } - } -#endif /* LWIP_IPV4 && LWIP_IPV6 */ - -#if ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_NO_MULTIPLE_OUTSTANDING) != 0) - for (i = 0; i < DNS_MAX_REQUESTS; i++) { - if (dns_requests[i].found && (dns_requests[i].dns_table_idx == idx)) { - dns_exec_found_callback(&dns_requests[i], ERR_OK); - /* flush this entry */ - dns_requests[i].found = NULL; - } - } -#else - if (dns_requests[idx].found) { - dns_exec_found_callback(&dns_requests[idx], ERR_OK); - } - dns_requests[idx].found = NULL; -#endif -#if ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_RAND_SRC_PORT) != 0) - /* close the pcb used unless other request are using it */ - for (i = 0; i < DNS_MAX_REQUESTS; i++) { - if (i == idx) { - continue; /* only check other requests */ - } - if (dns_table[i].state == DNS_STATE_ASKING) { - if (dns_table[i].pcb_idx == dns_table[idx].pcb_idx) { - /* another request is still using the same pcb */ - dns_table[idx].pcb_idx = DNS_MAX_SOURCE_PORTS; - break; - } - } - } - if (dns_table[idx].pcb_idx < DNS_MAX_SOURCE_PORTS) { - /* if we come here, the pcb is not used any more and can be removed */ - udp_remove(dns_pcbs[dns_table[idx].pcb_idx]); - dns_pcbs[dns_table[idx].pcb_idx] = NULL; - dns_table[idx].pcb_idx = DNS_MAX_SOURCE_PORTS; - } -#endif -} - -/* Create a query transmission ID that is unique for all outstanding queries */ -static u16_t -dns_create_txid(void) -{ - u16_t txid; - u8_t i; - -again: - txid = (u16_t)DNS_RAND_TXID(); - - /* check whether the ID is unique */ - for (i = 0; i < DNS_TABLE_SIZE; i++) { - if ((dns_table[i].state == DNS_STATE_ASKING) && - (dns_table[i].txid == txid)) { - /* ID already used by another pending query */ - goto again; - } - } - - return txid; -} - -/** - * dns_check_entry() - see if entry has not yet been queried and, if so, sends out a query. - * Check an entry in the dns_table: - * - send out query for new entries - * - retry old pending entries on timeout (also with different servers) - * - remove completed entries from the table if their TTL has expired - * - * @param i index of the dns_table entry to check - */ -static void -dns_check_entry(u8_t i) -{ - err_t err; - struct dns_table_entry *entry = &dns_table[i]; - - LWIP_ASSERT("array index out of bounds", i < DNS_TABLE_SIZE); - - switch (entry->state) { - case DNS_STATE_NEW: - /* initialize new entry */ - entry->txid = dns_create_txid(); - entry->state = DNS_STATE_ASKING; - entry->server_idx = 0; - entry->tmr = 1; - entry->retries = 0; -#if DNS_MAX_ADDRS_PER_NAME > 1 - entry->numipaddrs = 0; - entry->offset = 0; -#endif - - LWIP_DEBUGF(DNS_DEBUG, ("dns_check_entry: new id: 0x%x\n", entry->txid)); - - /* send DNS packet for this entry */ - err = dns_send(i); - if (err != ERR_OK) { - LWIP_DEBUGF(DNS_DEBUG | LWIP_DBG_LEVEL_WARNING, - ("dns_send returned error: %s\n", lwip_strerr(err))); - } - break; - case DNS_STATE_ASKING: - LWIP_ASSERT("timer already zero", entry->tmr > 0); - if (--entry->tmr == 0) { - if (++entry->retries == DNS_MAX_RETRIES) { - if ((entry->server_idx + 1 < DNS_MAX_SERVERS) && !ip_addr_isany_val(dns_servers[entry->server_idx + 1]) -#if LWIP_DNS_SUPPORT_MDNS_QUERIES - && !entry->is_mdns -#endif /* LWIP_DNS_SUPPORT_MDNS_QUERIES */ - ) { - /* change of server */ - entry->server_idx++; - entry->tmr = 1; - entry->retries = 0; - } else { - LWIP_DEBUGF(DNS_DEBUG, ("dns_check_entry: \"%s\": timeout\n", entry->name)); - /* call specified callback function if provided */ - dns_call_found(i, NULL); - /* flush this entry */ - entry->state = DNS_STATE_UNANSWERED; - break; - } - } else { - /* wait longer for the next retry */ - entry->tmr = entry->retries; - } - - /* send DNS packet for this entry */ - err = dns_send(i); - if (err != ERR_OK) { - LWIP_DEBUGF(DNS_DEBUG | LWIP_DBG_LEVEL_WARNING, - ("dns_send returned error: %s\n", lwip_strerr(err))); - } - } - break; - case DNS_STATE_DONE: - /* if the time to live is nul */ - if ((entry->ttl == 0) || (--entry->ttl == 0)) { - LWIP_DEBUGF(DNS_DEBUG, ("dns_check_entry: \"%s\": flush\n", entry->name)); - /* flush this entry, there cannot be any related pending entries in this state */ - entry->state = DNS_STATE_UNUSED; - } - break; - case DNS_STATE_UNANSWERED: - case DNS_STATE_UNUSED: - /* nothing to do */ - break; - default: - LWIP_ASSERT("unknown dns_table entry state:", 0); - break; - } -} - -/** - * Call dns_check_entry for each entry in dns_table - check all entries. - */ -static void -dns_check_entries(void) -{ - u8_t i; - - for (i = 0; i < DNS_TABLE_SIZE; ++i) { - dns_check_entry(i); - } -} - -/** - * Determines whether a DNS entry can be recycled - * - * @param entry An entry object to check - * @return a boolean representing whether the entry can be recycled. - * (0 == DNS entry CANNOT be recycled, 1/nonzero == DNS entry CAN be recycled) - */ -static u8_t -dns_can_recycle_entry(const struct dns_table_entry *pEntry) -{ - u8_t result; - - switch(pEntry->state) { - case DNS_STATE_DONE: - case DNS_STATE_UNANSWERED: - result = 1; - break; - - default: - result = 0; - break; - } - - return result; -} - -#if LWIP_TEST_CODE -u8_t -dns_expire_asking_entries(void) -{ - int j; - struct dns_table_entry *entry; - u8_t num_matched_entries = 0; - for (j = 0; j < DNS_TABLE_SIZE; ++j) { - entry = &dns_table[j]; - if (entry->state == DNS_STATE_ASKING) { - num_matched_entries++; - entry->tmr = 1; - entry->retries = (DNS_MAX_RETRIES - 1); - entry->server_idx = DNS_MAX_SERVERS; - } - } - return num_matched_entries; -} - -u8_t -dns_flush_cache(void) -{ - int j; - struct dns_table_entry *entry; - u8_t num_matched_entries = 0; - for (j = 0; j < DNS_TABLE_SIZE; ++j) { - entry = &dns_table[j]; - if (dns_can_recycle_entry(entry)) { - memset(entry, 0, sizeof(struct dns_table_entry)); - num_matched_entries++; - } - } - return num_matched_entries; -} -#endif - -static u8_t -dns_retry_pending(const struct dns_table_entry *entry) -{ - u8_t ret = 0; - - if (entry) { - if ((entry->server_idx+1server_idx+1])) { - ret = 1; - } - } - return ret; -} - -/** - * Save TTL and call dns_call_found for correct response. - */ -static void -dns_correct_response(u8_t idx, u32_t ttl) -{ - struct dns_table_entry *entry = &dns_table[idx]; -#if DNS_MAX_ADDRS_PER_NAME > 1 - unsigned int i; -#endif - - entry->state = DNS_STATE_DONE; - -#if DNS_MAX_ADDRS_PER_NAME > 1 - LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: \"%s\": response = { ", entry->name)); - for (i = 0; i < entry->numipaddrs; ++i) { - if (i > 0) { - LWIP_DEBUGF(DNS_DEBUG, (", ")); - } - LWIP_DEBUGF(DNS_DEBUG, (".[%u]=", i)); - ip_addr_debug_print(DNS_DEBUG, (&(entry->ipaddrs[i]))); - } - LWIP_DEBUGF(DNS_DEBUG, (" }\n")); -#else - LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: \"%s\": response = ", entry->name)); - ip_addr_debug_print(DNS_DEBUG, (&(entry->addr))); - LWIP_DEBUGF(DNS_DEBUG, ("\n")); -#endif - - /* read the answer resource record's TTL, and maximize it if needed */ - entry->ttl = ttl; - if (entry->ttl > DNS_MAX_TTL) { - entry->ttl = DNS_MAX_TTL; - } -#if DNS_MAX_ADDRS_PER_NAME > 1 - dns_call_found(idx, &entry->ipaddrs[0]); /* address is non-null when response is correct. */ -#else - dns_call_found(idx, &entry->addr); -#endif - - if (entry->ttl == 0) { - /* RFC 883, page 29: "Zero values are - interpreted to mean that the RR can only be used for the - transaction in progress, and should not be cached." - -> flush this entry now */ - /* entry reused during callback? */ - if (entry->state == DNS_STATE_DONE) { - entry->state = DNS_STATE_UNUSED; - } - } -} -/** - * Receive input function for DNS response packets arriving for the dns UDP pcb. - */ -static void -dns_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port) -{ - u8_t i; - u16_t txid; - u16_t res_idx; - struct dns_hdr hdr; - struct dns_answer ans; - struct dns_query qry; - u16_t nquestions, nanswers; - - LWIP_UNUSED_ARG(arg); - LWIP_UNUSED_ARG(pcb); - LWIP_UNUSED_ARG(port); - - /* is the dns message too big ? */ - if (p->tot_len > DNS_MSG_SIZE) { - LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: pbuf too big\n")); - /* free pbuf and return */ - goto memerr; - } - - /* is the dns message big enough ? */ - if (p->tot_len < (SIZEOF_DNS_HDR + SIZEOF_DNS_QUERY)) { - LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: pbuf too small\n")); - /* free pbuf and return */ - goto memerr; - } - - /* copy dns payload inside static buffer for processing */ - if (pbuf_copy_partial(p, &hdr, SIZEOF_DNS_HDR, 0) == SIZEOF_DNS_HDR) { - int was_unanswered = 0; - int found = 0; - - /* Match the ID in the DNS header with the name table. */ - txid = lwip_htons(hdr.id); - for (i = 0; i < DNS_TABLE_SIZE; i++) { - struct dns_table_entry *entry = &dns_table[i]; - - if (entry->txid == txid) { - if (entry->state == DNS_STATE_UNANSWERED) { - LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: late answer, putting in cache\n")); - entry->state = DNS_STATE_ASKING; - entry->tmr = 1; - was_unanswered = 1; - } - - if (entry->state == DNS_STATE_ASKING) { - found = 1; - - /* We only care about the question(s) and the answers. The authrr - and the extrarr are simply discarded. */ - nquestions = lwip_htons(hdr.numquestions); - nanswers = lwip_htons(hdr.numanswers); - - /* Check for error. If so, call callback to inform. */ - if (((hdr.flags1 & DNS_FLAG1_RESPONSE) == 0) || (entry->err != 0) || (nquestions != 1)) { - LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: \"%s\": error in flags\n", entry->name)); - if (!was_unanswered) { - /* call callback to indicate error, clean up memory and return */ - if (dns_retry_pending(entry)) { - entry->state = DNS_STATE_ASKING; - } else { - dns_call_found(i, NULL); - dns_table[i].state = DNS_STATE_UNUSED; - } - } - goto memerr; - } - } - -#if LWIP_DNS_SUPPORT_MDNS_QUERIES - if (!entry->is_mdns) -#endif /* LWIP_DNS_SUPPORT_MDNS_QUERIES */ - { - /* Check whether response comes from the same network address to which the - question was sent. (RFC 5452) */ - if (!ip_addr_cmp(addr, &dns_servers[entry->server_idx])) { - if (!was_unanswered) { - if (dns_retry_pending(entry)) { - entry->state = DNS_STATE_ASKING; - } else { - dns_call_found(i, NULL); - dns_table[i].state = DNS_STATE_UNUSED; - } - } - goto memerr; /* ignore this packet */ - } - } - - /* Check if the name in the "question" part match with the name in the entry and - skip it if equal. */ - res_idx = dns_compare_name(entry->name, p, SIZEOF_DNS_HDR); - if (res_idx == 0xFFFF) { - LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: \"%s\": response not match to query\n", entry->name)); - goto memerr; /* ignore this packet */ - } - - /* check if "question" part matches the request */ - if (pbuf_copy_partial(p, &qry, SIZEOF_DNS_QUERY, res_idx) != SIZEOF_DNS_QUERY) { - goto memerr; /* ignore this packet */ - } - if ((qry.cls != PP_HTONS(DNS_RRCLASS_IN)) || - (LWIP_DNS_ADDRTYPE_IS_IPV6(entry->reqaddrtype) && (qry.type != PP_HTONS(DNS_RRTYPE_AAAA))) || - (!LWIP_DNS_ADDRTYPE_IS_IPV6(entry->reqaddrtype) && (qry.type != PP_HTONS(DNS_RRTYPE_A)))) { - LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: \"%s\": response not match to query\n", entry->name)); - goto memerr; /* ignore this packet */ - } - /* skip the rest of the "question" part */ - res_idx += SIZEOF_DNS_QUERY; - - /* Check for error. If so, call callback to inform. */ - if (hdr.flags2 & DNS_FLAG2_ERR_MASK) { - LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: \"%s\": error in flags\n", entry->name)); - } else { - while ((nanswers > 0) && (res_idx < p->tot_len)) { - /* skip answer resource record's host name */ - res_idx = dns_skip_name(p, res_idx); - if (res_idx == 0xFFFF) { - goto memerr; /* ignore this packet */ - } - - /* Check for IP address type and Internet class. Others are discarded. */ - if (pbuf_copy_partial(p, &ans, SIZEOF_DNS_ANSWER, res_idx) != SIZEOF_DNS_ANSWER) { - goto memerr; /* ignore this packet */ - } - res_idx += SIZEOF_DNS_ANSWER; - - if (ans.cls == PP_HTONS(DNS_RRCLASS_IN)) { -#if LWIP_IPV4 - if ((ans.type == PP_HTONS(DNS_RRTYPE_A)) && (ans.len == PP_HTONS(sizeof(ip4_addr_t)))) { -#if LWIP_IPV4 && LWIP_IPV6 - if (!LWIP_DNS_ADDRTYPE_IS_IPV6(entry->reqaddrtype)) -#endif /* LWIP_IPV4 && LWIP_IPV6 */ - { - ip4_addr_t ip4addr; - /* read the IP address after answer resource record's header */ - if (pbuf_copy_partial(p, &ip4addr, sizeof(ip4_addr_t), res_idx) != sizeof(ip4_addr_t)) { - goto memerr; /* ignore this packet */ - } - LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: \"%s\": A ", entry->name)); - ip4_addr_debug_print_val(DNS_DEBUG, (ip4addr)); - LWIP_DEBUGF(DNS_DEBUG, (" -> dns_table[%u].ipaddrs[%u]\n", i, dns_table[i].numipaddrs)); - ip_addr_copy_from_ip4(dns_table[i].ipaddrs[dns_table[i].numipaddrs], ip4addr); - ++dns_table[i].numipaddrs; - } - } -#endif /* LWIP_IPV4 */ -#if LWIP_IPV6 - if ((ans.type == PP_HTONS(DNS_RRTYPE_AAAA)) && (ans.len == PP_HTONS(sizeof(ip6_addr_t)))) { -#if LWIP_IPV4 && LWIP_IPV6 - if (LWIP_DNS_ADDRTYPE_IS_IPV6(entry->reqaddrtype)) -#endif /* LWIP_IPV4 && LWIP_IPV6 */ - { - ip6_addr_t ip6addr; - /* read the IP address after answer resource record's header */ - if (pbuf_copy_partial(p, &ip6addr, sizeof(ip6_addr_t), res_idx) != sizeof(ip6_addr_t)) { - goto memerr; /* ignore this packet */ - } - LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: \"%s\": AAAA ", entry->name)); - ip6_addr_debug_print_val(DNS_DEBUG, (ip6addr)); - LWIP_DEBUGF(DNS_DEBUG, (" -> dns_table[%u].ipaddrs[%u]\n", i, dns_table[i].numipaddrs)); - ip_addr_copy_from_ip6(dns_table[i].ipaddrs[dns_table[i].numipaddrs], ip6addr); - ++dns_table[i].numipaddrs; - } - } -#endif /* LWIP_IPV6 */ - } - if (dns_table[i].numipaddrs > 0) { - pbuf_free(p); - /* handle correct response */ - dns_correct_response(i, lwip_ntohl(ans.ttl)); - return; - } - /* skip this answer */ - if ((res_idx + lwip_htons(ans.len)) > 0xFFFF) - { - goto memerr; /* ignore this packet */ - } - res_idx += lwip_htons(ans.len); - --nanswers; - } -#if LWIP_IPV4 && LWIP_IPV6 - if ((entry->reqaddrtype == LWIP_DNS_ADDRTYPE_IPV4_IPV6) || - (entry->reqaddrtype == LWIP_DNS_ADDRTYPE_IPV6_IPV4)) { - if (entry->reqaddrtype == LWIP_DNS_ADDRTYPE_IPV4_IPV6) { - /* IPv4 failed, try IPv6 */ - dns_table[i].reqaddrtype = LWIP_DNS_ADDRTYPE_IPV6; - } else { - /* IPv6 failed, try IPv4 */ - dns_table[i].reqaddrtype = LWIP_DNS_ADDRTYPE_IPV4; - } - pbuf_free(p); - dns_table[i].state = DNS_STATE_NEW; - dns_check_entry(i); - return; - } -#endif /* LWIP_IPV4 && LWIP_IPV6 */ - LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: \"%s\": error in response\n", entry->name)); - } - /* call callback to indicate error, clean up memory and return */ - pbuf_free(p); - if (!was_unanswered) { - if ((entry->numipaddrs == 0) && dns_retry_pending(entry)) { - entry->state = DNS_STATE_ASKING; - } else { - dns_call_found(i, NULL); - dns_table[i].state = DNS_STATE_UNUSED; - } - } - /* invalidate entry if the minimal TTL is zero */ - if (entry->ttl == 0) { - dns_call_found(i, NULL); - dns_table[i].state = DNS_STATE_UNUSED; - } - return; - } - } - if (!found) { - LWIP_DEBUGF(DNS_DEBUG, ("dns_recv: response with unknown id: 0x%x\n", txid)); - } - } - -memerr: - /* deallocate memory and return */ - pbuf_free(p); - return; -} - -/** - * Queues a new hostname to resolve and sends out a DNS query for that hostname - * - * @param name the hostname that is to be queried - * @param hostnamelen length of the hostname - * @param found a callback function to be called on success, failure or timeout - * @param callback_arg argument to pass to the callback function - * @param dns_addrtype address type - * @param is_mdns boolean indicating whether this is a MDNS query - * @param is_multi boolean indicating what version of the found callback is passed - * (0 == dns_found_callback, 1 == dns_found_callback_multi) - * @return err_t return code. - */ -static err_t -dns_enqueue(const char *name, size_t hostnamelen, LWIP_DNS_FOUND_CALLBACK_TYPE found, - void *callback_arg LWIP_DNS_ADDRTYPE_ARG(u8_t dns_addrtype) LWIP_DNS_ISMDNS_ARG(u8_t is_mdns) - LWIP_DNS_ISMULTI_ARG(u8_t is_multi)) -{ - u8_t i; - u8_t lseq, lseqi; - struct dns_table_entry *entry = NULL; - size_t namelen; - struct dns_req_entry* req; - -#if ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_NO_MULTIPLE_OUTSTANDING) != 0) - u8_t r; - /* check for duplicate entries */ - for (i = 0; i < DNS_TABLE_SIZE; i++) { - if ((dns_table[i].state == DNS_STATE_ASKING) && - (lwip_strnicmp(name, dns_table[i].name, sizeof(dns_table[i].name)) == 0)) { -#if LWIP_IPV4 && LWIP_IPV6 - if (dns_table[i].reqaddrtype != dns_addrtype) { - /* requested address types don't match - this can lead to 2 concurrent requests, but mixing the address types - for the same host should not be that common */ - continue; - } -#endif /* LWIP_IPV4 && LWIP_IPV6 */ - /* this is a duplicate entry, find a free request entry */ - for (r = 0; r < DNS_MAX_REQUESTS; r++) { - if (dns_requests[r].found == 0) { - dns_requests[r].found = found; - dns_requests[r].arg = callback_arg; - dns_requests[r].dns_table_idx = i; - LWIP_DNS_SET_ADDRTYPE(dns_requests[r].reqaddrtype, dns_addrtype); - LWIP_DEBUGF(DNS_DEBUG, ("dns_enqueue: \"%s\": duplicate request\n", name)); - return ERR_INPROGRESS; - } - } - } - } - /* no duplicate entries found */ -#endif - - /* search an unused entry, or the oldest one */ - lseq = 0; - lseqi = DNS_TABLE_SIZE; - for (i = 0; i < DNS_TABLE_SIZE; ++i) { - entry = &dns_table[i]; - /* is it an unused entry ? */ - if (entry->state == DNS_STATE_UNUSED) { - break; - } - /* check if this is the oldest completed entry */ - if (dns_can_recycle_entry(entry)) { - u8_t age = (dns_seqno >= entry->seqno) - ? (dns_seqno - entry->seqno) - : (dns_seqno + (UINT8_MAX - entry->seqno)); - if (age > lseq) { - lseq = age; - lseqi = i; - } - } - } - - /* if we don't have found an unused entry, use the oldest completed one */ - if (i == DNS_TABLE_SIZE) { - if ((lseqi >= DNS_TABLE_SIZE) || !dns_can_recycle_entry(&dns_table[lseqi])) { - /* no entry can be used now, table is full */ - LWIP_DEBUGF(DNS_DEBUG, ("dns_enqueue: \"%s\": DNS entries table is full\n", name)); - return ERR_MEM; - } else { - /* use the oldest completed one */ - i = lseqi; - entry = &dns_table[i]; - } - } - -#if ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_NO_MULTIPLE_OUTSTANDING) != 0) - /* find a free request entry */ - req = NULL; - for (r = 0; r < DNS_MAX_REQUESTS; r++) { - if (dns_requests[r].found == NULL) { - req = &dns_requests[r]; - break; - } - } - if (req == NULL) { - /* no request entry can be used now, table is full */ - LWIP_DEBUGF(DNS_DEBUG, ("dns_enqueue: \"%s\": DNS request entries table is full\n", name)); - return ERR_MEM; - } - req->dns_table_idx = i; -#else - /* in this configuration, the entry index is the same as the request index */ - req = &dns_requests[i]; -#endif - - /* use this entry */ - LWIP_DEBUGF(DNS_DEBUG, ("dns_enqueue: \"%s\": use DNS entry %"U16_F"\n", name, (u16_t)(i))); - - /* fill the entry */ - entry->state = DNS_STATE_NEW; - entry->seqno = dns_seqno; -#if DNS_MAX_ADDRS_PER_NAME > 1 - entry->is_multi = is_multi; -#endif - LWIP_DNS_SET_ADDRTYPE(entry->reqaddrtype, dns_addrtype); - LWIP_DNS_SET_ADDRTYPE(req->reqaddrtype, dns_addrtype); - req->found = found; - req->arg = callback_arg; - namelen = LWIP_MIN(hostnamelen, DNS_MAX_NAME_LENGTH-1); - MEMCPY(entry->name, name, namelen); - entry->name[namelen] = 0; - -#if ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_RAND_SRC_PORT) != 0) - entry->pcb_idx = dns_alloc_pcb(); - if (entry->pcb_idx >= DNS_MAX_SOURCE_PORTS) { - /* failed to get a UDP pcb */ - LWIP_DEBUGF(DNS_DEBUG, ("dns_enqueue: \"%s\": failed to allocate a pcb\n", name)); - entry->state = DNS_STATE_UNUSED; - req->found = NULL; - return ERR_MEM; - } - LWIP_DEBUGF(DNS_DEBUG, ("dns_enqueue: \"%s\": use DNS pcb %"U16_F"\n", name, (u16_t)(entry->pcb_idx))); -#endif - -#if LWIP_DNS_SUPPORT_MDNS_QUERIES - entry->is_mdns = is_mdns; -#endif - - dns_seqno++; - - /* force to send query without waiting timer */ - dns_check_entry(i); - - /* dns query is enqueued */ - return ERR_INPROGRESS; -} - -/** - * @ingroup dns - * Resolve a hostname (string) into IP address(es). - * NON-BLOCKING callback version for use with raw API!!! - * - * Returns immediately with one of err_t return codes: - * - ERR_OK if hostname is a valid IP address string or the host - * name is already in the local names table. - * - ERR_INPROGRESS enqueue a request to be sent to the DNS server - * for resolution if no errors are present. - * - ERR_ARG: dns client not initialized or invalid hostname - * - * @param hostname the hostname that is to be queried - * @param ipaddrs pointer to the ip_addr_t array where to store the addresses if they are already - * cached in the dns_table (only valid if ERR_OK is returned!) - * @param numipaddrs size of the ipaddrs array. - * @note This is both an input and an output parameter. - * @param found a callback function to be called on success, failure or timeout (only if - * ERR_INPROGRESS is returned!) - * @param callback_arg argument to pass to the callback function - * @return a err_t return code. - */ -static err_t -dns_gethostbyname_internal(const char *hostname, ip_addr_t *ipaddrs, - LWIP_DNS_FOUND_CALLBACK_TYPE found, void *callback_arg - LWIP_DNS_NUMIPADDRS_ARG(u8_t *numipaddrs) - LWIP_DNS_ISMULTI_ARG(u8_t is_multi)) -{ - return dns_gethostbyname_addrtype(hostname, ipaddrs, found, - callback_arg LWIP_DNS_ADDRTYPE_ARG(LWIP_DNS_ADDRTYPE_DEFAULT)); -} - -/** - * @ingroup dns - * Like dns_gethostbyname, but returned address type can be controlled: - * @param hostname the hostname that is to be queried - * @param addr pointer to a ip_addr_t where to store the address if it is already - * cached in the dns_table (only valid if ERR_OK is returned!) - * @param found a callback function to be called on success, failure or timeout (only if - * ERR_INPROGRESS is returned!) - * @param callback_arg argument to pass to the callback function - * @param dns_addrtype - LWIP_DNS_ADDRTYPE_IPV4_IPV6: try to resolve IPv4 first, try IPv6 if IPv4 fails only - * - LWIP_DNS_ADDRTYPE_IPV6_IPV4: try to resolve IPv6 first, try IPv4 if IPv6 fails only - * - LWIP_DNS_ADDRTYPE_IPV4: try to resolve IPv4 only - * - LWIP_DNS_ADDRTYPE_IPV6: try to resolve IPv6 only - */ -err_t -dns_gethostbyname_addrtype(const char *hostname, ip_addr_t *addr, LWIP_DNS_FOUND_CALLBACK_TYPE found, - void *callback_arg LWIP_DNS_ADDRTYPE_ARG(u8_t dns_addrtype)) -{ - size_t hostnamelen; -#if LWIP_DNS_SUPPORT_MDNS_QUERIES - u8_t is_mdns; -#endif -#if DNS_MAX_ADDRS_PER_NAME > 1 - u8_t numipaddrs = 1; -#endif - - /* not initialized or no valid server yet, or invalid addr pointer - * or invalid hostname or invalid hostname length */ - if ((addr == NULL) || - (!hostname) || (!hostname[0])) { - return ERR_ARG; - } -#if ((LWIP_DNS_SECURE & LWIP_DNS_SECURE_RAND_SRC_PORT) == 0) - if (dns_pcbs[0] == NULL) { - return ERR_ARG; - } -#endif - hostnamelen = strlen(hostname); - if (hostnamelen >= DNS_MAX_NAME_LENGTH) { - LWIP_DEBUGF(DNS_DEBUG, ("dns_gethostbyname: name too long to resolve")); - return ERR_ARG; - } - - -#if LWIP_HAVE_LOOPIF - if (strcmp(hostname, "localhost") == 0) { - ip_addr_set_loopback(LWIP_DNS_ADDRTYPE_IS_IPV6(dns_addrtype), addr); - return ERR_OK; - } -#endif /* LWIP_HAVE_LOOPIF */ - - /* host name already in octet notation? set ip addr and return ERR_OK */ - if (ipaddr_aton(hostname, addr)) { -#if LWIP_IPV4 && LWIP_IPV6 - if ((IP_IS_V6(addr) && (dns_addrtype != LWIP_DNS_ADDRTYPE_IPV4)) || - (IP_IS_V4(addr) && (dns_addrtype != LWIP_DNS_ADDRTYPE_IPV6))) -#endif /* LWIP_IPV4 && LWIP_IPV6 */ - { - return ERR_OK; - } - } - /* already have this address cached? */ - if (dns_lookup(hostname, addr LWIP_DNS_NUMIPADDRS_ARG(&numipaddrs) LWIP_DNS_ADDRTYPE_ARG(dns_addrtype)) == ERR_OK) { - return ERR_OK; - } -#if LWIP_IPV4 && LWIP_IPV6 - if ((dns_addrtype == LWIP_DNS_ADDRTYPE_IPV4_IPV6) || (dns_addrtype == LWIP_DNS_ADDRTYPE_IPV6_IPV4)) { - /* fallback to 2nd IP type and try again to lookup */ - u8_t fallback; - if (dns_addrtype == LWIP_DNS_ADDRTYPE_IPV4_IPV6) { - fallback = LWIP_DNS_ADDRTYPE_IPV6; - } else { - fallback = LWIP_DNS_ADDRTYPE_IPV4; - } - if (dns_lookup(hostname, addr LWIP_DNS_NUMIPADDRS_ARG(&numipaddrs) LWIP_DNS_ADDRTYPE_ARG(fallback)) == ERR_OK) { - return ERR_OK; - } - } -#else /* LWIP_IPV4 && LWIP_IPV6 */ - LWIP_UNUSED_ARG(dns_addrtype); -#endif /* LWIP_IPV4 && LWIP_IPV6 */ - -#if LWIP_DNS_SUPPORT_MDNS_QUERIES - if (strstr(hostname, ".local") == &hostname[hostnamelen] - 6) { - is_mdns = 1; - } else { - is_mdns = 0; - } - - if (!is_mdns) -#endif /* LWIP_DNS_SUPPORT_MDNS_QUERIES */ - { - /* prevent calling found callback if no server is set, return error instead */ - if (ip_addr_isany_val(dns_servers[0])) { - return ERR_VAL; - } - } - - /* queue query with specified callback */ - return dns_enqueue(hostname, hostnamelen, found, callback_arg LWIP_DNS_ADDRTYPE_ARG(dns_addrtype) - LWIP_DNS_ISMDNS_ARG(is_mdns) LWIP_DNS_ISMULTI_ARG(0)); -} - -/** - * Resolve a hostname (string) into a single IP address. - * NON-BLOCKING callback version for use with raw API!!! - * - * Returns immediately with one of err_t return codes: - * - ERR_OK if hostname is a valid IP address string or the host - * name is already in the local names table. - * - ERR_INPROGRESS enqueue a request to be sent to the DNS server - * for resolution if no errors are present. - * - ERR_ARG: dns client not initialized or invalid hostname - * - * @param hostname the hostname that is to be queried - * @param ipaddr pointer to the ip_addr_t where to store the addresses if it is already - * cached in the dns_table (only valid if ERR_OK is returned!) - * @param found a callback function to be called on success, failure or timeout (only if - * ERR_INPROGRESS is returned!) - * @param callback_arg argument to pass to the callback function - * @return a err_t return code. - */ -err_t -dns_gethostbyname(const char *hostname, ip_addr_t *ipaddr, - LWIP_DNS_FOUND_CALLBACK_TYPE found, void *callback_arg) -{ -#if DNS_MAX_ADDRS_PER_NAME > 1 - u8_t singleaddr = 1; -#endif - return dns_gethostbyname_internal(hostname, ipaddr, - (dns_found_callbackX)found, callback_arg - LWIP_DNS_NUMIPADDRS_ARG(&singleaddr) - LWIP_DNS_ISMULTI_ARG(0)); -} - -/** - * Resolve a hostname (string) into a set of IP addresses. - * NON-BLOCKING callback version for use with raw API!!! - * - * Returns immediately with one of err_t return codes: - * - ERR_OK if hostname is a valid IP address string or the host - * name is already in the local names table. - * - ERR_INPROGRESS enqueue a request to be sent to the DNS server - * for resolution if no errors are present. - * - ERR_ARG: dns client not initialized or invalid hostname - * - * @param hostname the hostname that is to be queried - * @param ipaddrs pointer to the ip_addr_t array where to store the addresses if they are already - * cached in the dns_table (only valid if ERR_OK is returned!) - * @param numipaddrs size of the ipaddrs array - * @param found a callback function to be called on success, failure or timeout (only if - * ERR_INPROGRESS is returned!) - * @param callback_arg argument to pass to the callback function - * @return a err_t return code. - */ -err_t -dns_gethostbyname_multi(const char *hostname, ip_addr_t *ipaddrs, u8_t *numipaddrs, - dns_found_callback_multi found, void *callback_arg) -{ - return dns_gethostbyname_internal(hostname, ipaddrs, - (dns_found_callbackX)found, callback_arg - LWIP_DNS_NUMIPADDRS_ARG(numipaddrs) - LWIP_DNS_ISMULTI_ARG(1)); -} - -/** - * Cancel one or more entries from the DNS table. - * - * All entries in the DNS table that match a certain callback and argument are reset. - * This means that after a request to resolve a host name has been sent to a DNS server - * but before the response has been received, the caller can cancel - * the request and avoid being prompted when the response is finally received. - * Of course this function can be used to simply move entries to DNS_STATE_UNUSED. - * - * @param found the callback executed in case of a cache hit. - * @param arg argument passed to the callback. - * @return number of entries that have been canceled. - */ -u8_t -dns_cancel(LWIP_DNS_FOUND_CALLBACK_TYPE found, void *arg) -{ - int j; - u8_t num_matched_entries = 0; - for (j = 0; j < DNS_MAX_REQUESTS; ++j) { - if ((dns_requests[j].found == found) && - (dns_requests[j].arg == arg)) { - num_matched_entries++; - memset(&dns_requests[j], 0, sizeof(struct dns_req_entry)); - } - } - return num_matched_entries; -} - -#endif /* LWIP_DNS */ diff --git a/third_party/lwip/repo/lwip/src/core/inet_chksum.c b/third_party/lwip/repo/lwip/src/core/inet_chksum.c deleted file mode 100644 index 917f3e4f1aaceb..00000000000000 --- a/third_party/lwip/repo/lwip/src/core/inet_chksum.c +++ /dev/null @@ -1,609 +0,0 @@ -/** - * @file - * Incluse internet checksum functions.\n - * - * These are some reference implementations of the checksum algorithm, with the - * aim of being simple, correct and fully portable. Checksumming is the - * first thing you would want to optimize for your platform. If you create - * your own version, link it in and in your cc.h put: - * - * \#define LWIP_CHKSUM your_checksum_routine - * - * Or you can select from the implementations below by defining - * LWIP_CHKSUM_ALGORITHM to 1, 2 or 3. - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ - -#include "lwip/opt.h" - -#include "lwip/inet_chksum.h" -#include "lwip/def.h" -#include "lwip/ip_addr.h" - -#include - -#ifndef LWIP_CHKSUM -# define LWIP_CHKSUM lwip_standard_chksum -# ifndef LWIP_CHKSUM_ALGORITHM -# define LWIP_CHKSUM_ALGORITHM 2 -# endif -u16_t lwip_standard_chksum(const void *dataptr, int len); -#endif -/* If none set: */ -#ifndef LWIP_CHKSUM_ALGORITHM -# define LWIP_CHKSUM_ALGORITHM 0 -#endif - -#if (LWIP_CHKSUM_ALGORITHM == 1) /* Version #1 */ -/** - * lwip checksum - * - * @param dataptr points to start of data to be summed at any boundary - * @param len length of data to be summed - * @return host order (!) lwip checksum (non-inverted Internet sum) - * - * @note accumulator size limits summable length to 64k - * @note host endianess is irrelevant (p3 RFC1071) - */ -u16_t -lwip_standard_chksum(const void *dataptr, int len) -{ - u32_t acc; - u16_t src; - const u8_t *octetptr; - - acc = 0; - /* dataptr may be at odd or even addresses */ - octetptr = (const u8_t*)dataptr; - while (len > 1) { - /* declare first octet as most significant - thus assume network order, ignoring host order */ - src = (*octetptr) << 8; - octetptr++; - /* declare second octet as least significant */ - src |= (*octetptr); - octetptr++; - acc += src; - len -= 2; - } - if (len > 0) { - /* accumulate remaining octet */ - src = (*octetptr) << 8; - acc += src; - } - /* add deferred carry bits */ - acc = (acc >> 16) + (acc & 0x0000ffffUL); - if ((acc & 0xffff0000UL) != 0) { - acc = (acc >> 16) + (acc & 0x0000ffffUL); - } - /* This maybe a little confusing: reorder sum using lwip_htons() - instead of lwip_ntohs() since it has a little less call overhead. - The caller must invert bits for Internet sum ! */ - return lwip_htons((u16_t)acc); -} -#endif - -#if (LWIP_CHKSUM_ALGORITHM == 2) /* Alternative version #2 */ -/* - * Curt McDowell - * Broadcom Corp. - * csm@broadcom.com - * - * IP checksum two bytes at a time with support for - * unaligned buffer. - * Works for len up to and including 0x20000. - * by Curt McDowell, Broadcom Corp. 12/08/2005 - * - * @param dataptr points to start of data to be summed at any boundary - * @param len length of data to be summed - * @return host order (!) lwip checksum (non-inverted Internet sum) - */ -u16_t -lwip_standard_chksum(const void *dataptr, int len) -{ - const u8_t *pb = (const u8_t *)dataptr; - const u16_t *ps; - u16_t t = 0; - u32_t sum = 0; - int odd = ((mem_ptr_t)pb & 1); - - /* Get aligned to u16_t */ - if (odd && len > 0) { - ((u8_t *)&t)[1] = *pb++; - len--; - } - - /* Add the bulk of the data */ - ps = (const u16_t *)(const void *)pb; - while (len > 1) { - sum += *ps++; - len -= 2; - } - - /* Consume left-over byte, if any */ - if (len > 0) { - ((u8_t *)&t)[0] = *(const u8_t *)ps; - } - - /* Add end bytes */ - sum += t; - - /* Fold 32-bit sum to 16 bits - calling this twice is probably faster than if statements... */ - sum = FOLD_U32T(sum); - sum = FOLD_U32T(sum); - - /* Swap if alignment was odd */ - if (odd) { - sum = SWAP_BYTES_IN_WORD(sum); - } - - return (u16_t)sum; -} -#endif - -#if (LWIP_CHKSUM_ALGORITHM == 3) /* Alternative version #3 */ -/** - * An optimized checksum routine. Basically, it uses loop-unrolling on - * the checksum loop, treating the head and tail bytes specially, whereas - * the inner loop acts on 8 bytes at a time. - * - * @arg start of buffer to be checksummed. May be an odd byte address. - * @len number of bytes in the buffer to be checksummed. - * @return host order (!) lwip checksum (non-inverted Internet sum) - * - * by Curt McDowell, Broadcom Corp. December 8th, 2005 - */ -u16_t -lwip_standard_chksum(const void *dataptr, int len) -{ - const u8_t *pb = (const u8_t *)dataptr; - const u16_t *ps; - u16_t t = 0; - const u32_t *pl; - u32_t sum = 0, tmp; - /* starts at odd byte address? */ - int odd = ((mem_ptr_t)pb & 1); - - if (odd && len > 0) { - ((u8_t *)&t)[1] = *pb++; - len--; - } - - ps = (const u16_t *)(const void*)pb; - - if (((mem_ptr_t)ps & 3) && len > 1) { - sum += *ps++; - len -= 2; - } - - pl = (const u32_t *)(const void*)ps; - - while (len > 7) { - tmp = sum + *pl++; /* ping */ - if (tmp < sum) { - tmp++; /* add back carry */ - } - - sum = tmp + *pl++; /* pong */ - if (sum < tmp) { - sum++; /* add back carry */ - } - - len -= 8; - } - - /* make room in upper bits */ - sum = FOLD_U32T(sum); - - ps = (const u16_t *)pl; - - /* 16-bit aligned word remaining? */ - while (len > 1) { - sum += *ps++; - len -= 2; - } - - /* dangling tail byte remaining? */ - if (len > 0) { /* include odd byte */ - ((u8_t *)&t)[0] = *(const u8_t *)ps; - } - - sum += t; /* add end bytes */ - - /* Fold 32-bit sum to 16 bits - calling this twice is probably faster than if statements... */ - sum = FOLD_U32T(sum); - sum = FOLD_U32T(sum); - - if (odd) { - sum = SWAP_BYTES_IN_WORD(sum); - } - - return (u16_t)sum; -} -#endif - -/** Parts of the pseudo checksum which are common to IPv4 and IPv6 */ -static u16_t -inet_cksum_pseudo_base(struct pbuf *p, u8_t proto, u16_t proto_len, u32_t acc) -{ - struct pbuf *q; - u8_t swapped = 0; - - /* iterate through all pbuf in chain */ - for (q = p; q != NULL; q = q->next) { - LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): checksumming pbuf %p (has next %p) \n", - (void *)q, (void *)q->next)); - acc += LWIP_CHKSUM(q->payload, q->len); - /*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): unwrapped lwip_chksum()=%"X32_F" \n", acc));*/ - /* just executing this next line is probably faster that the if statement needed - to check whether we really need to execute it, and does no harm */ - acc = FOLD_U32T(acc); - if (q->len % 2 != 0) { - swapped = 1 - swapped; - acc = SWAP_BYTES_IN_WORD(acc); - } - /*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): wrapped lwip_chksum()=%"X32_F" \n", acc));*/ - } - - if (swapped) { - acc = SWAP_BYTES_IN_WORD(acc); - } - - acc += (u32_t)lwip_htons((u16_t)proto); - acc += (u32_t)lwip_htons(proto_len); - - /* Fold 32-bit sum to 16 bits - calling this twice is probably faster than if statements... */ - acc = FOLD_U32T(acc); - acc = FOLD_U32T(acc); - LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): pbuf chain lwip_chksum()=%"X32_F"\n", acc)); - return (u16_t)~(acc & 0xffffUL); -} - -#if LWIP_IPV4 -/* inet_chksum_pseudo: - * - * Calculates the IPv4 pseudo Internet checksum used by TCP and UDP for a pbuf chain. - * IP addresses are expected to be in network byte order. - * - * @param p chain of pbufs over that a checksum should be calculated (ip data part) - * @param src source ip address (used for checksum of pseudo header) - * @param dst destination ip address (used for checksum of pseudo header) - * @param proto ip protocol (used for checksum of pseudo header) - * @param proto_len length of the ip data part (used for checksum of pseudo header) - * @return checksum (as u16_t) to be saved directly in the protocol header - */ -u16_t -inet_chksum_pseudo(struct pbuf *p, u8_t proto, u16_t proto_len, - const ip4_addr_t *src, const ip4_addr_t *dest) -{ - u32_t acc; - u32_t addr; - - addr = ip4_addr_get_u32(src); - acc = (addr & 0xffffUL); - acc += ((addr >> 16) & 0xffffUL); - addr = ip4_addr_get_u32(dest); - acc += (addr & 0xffffUL); - acc += ((addr >> 16) & 0xffffUL); - /* fold down to 16 bits */ - acc = FOLD_U32T(acc); - acc = FOLD_U32T(acc); - - return inet_cksum_pseudo_base(p, proto, proto_len, acc); -} -#endif /* LWIP_IPV4 */ - -#if LWIP_IPV6 -/** - * Calculates the checksum with IPv6 pseudo header used by TCP and UDP for a pbuf chain. - * IPv6 addresses are expected to be in network byte order. - * - * @param p chain of pbufs over that a checksum should be calculated (ip data part) - * @param proto ipv6 protocol/next header (used for checksum of pseudo header) - * @param proto_len length of the ipv6 payload (used for checksum of pseudo header) - * @param src source ipv6 address (used for checksum of pseudo header) - * @param dest destination ipv6 address (used for checksum of pseudo header) - * @return checksum (as u16_t) to be saved directly in the protocol header - */ -u16_t -ip6_chksum_pseudo(struct pbuf *p, u8_t proto, u16_t proto_len, - const ip6_addr_t *src, const ip6_addr_t *dest) -{ - u32_t acc = 0; - u32_t addr; - u8_t addr_part; - - for (addr_part = 0; addr_part < 4; addr_part++) { - addr = src->addr[addr_part]; - acc += (addr & 0xffffUL); - acc += ((addr >> 16) & 0xffffUL); - addr = dest->addr[addr_part]; - acc += (addr & 0xffffUL); - acc += ((addr >> 16) & 0xffffUL); - } - /* fold down to 16 bits */ - acc = FOLD_U32T(acc); - acc = FOLD_U32T(acc); - - return inet_cksum_pseudo_base(p, proto, proto_len, acc); -} -#endif /* LWIP_IPV6 */ - -/* ip_chksum_pseudo: - * - * Calculates the IPv4 or IPv6 pseudo Internet checksum used by TCP and UDP for a pbuf chain. - * IP addresses are expected to be in network byte order. - * - * @param p chain of pbufs over that a checksum should be calculated (ip data part) - * @param src source ip address (used for checksum of pseudo header) - * @param dst destination ip address (used for checksum of pseudo header) - * @param proto ip protocol (used for checksum of pseudo header) - * @param proto_len length of the ip data part (used for checksum of pseudo header) - * @return checksum (as u16_t) to be saved directly in the protocol header - */ -u16_t -ip_chksum_pseudo(struct pbuf *p, u8_t proto, u16_t proto_len, - const ip_addr_t *src, const ip_addr_t *dest) -{ -#if LWIP_IPV6 - if (IP_IS_V6(dest)) { - return ip6_chksum_pseudo(p, proto, proto_len, ip_2_ip6(src), ip_2_ip6(dest)); - } -#endif /* LWIP_IPV6 */ -#if LWIP_IPV4 && LWIP_IPV6 - else -#endif /* LWIP_IPV4 && LWIP_IPV6 */ -#if LWIP_IPV4 - { - return inet_chksum_pseudo(p, proto, proto_len, ip_2_ip4(src), ip_2_ip4(dest)); - } -#endif /* LWIP_IPV4 */ -} - -/** Parts of the pseudo checksum which are common to IPv4 and IPv6 */ -static u16_t -inet_cksum_pseudo_partial_base(struct pbuf *p, u8_t proto, u16_t proto_len, - u16_t chksum_len, u32_t acc) -{ - struct pbuf *q; - u8_t swapped = 0; - u16_t chklen; - - /* iterate through all pbuf in chain */ - for (q = p; (q != NULL) && (chksum_len > 0); q = q->next) { - LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): checksumming pbuf %p (has next %p) \n", - (void *)q, (void *)q->next)); - chklen = q->len; - if (chklen > chksum_len) { - chklen = chksum_len; - } - acc += LWIP_CHKSUM(q->payload, chklen); - chksum_len -= chklen; - LWIP_ASSERT("delete me", chksum_len < 0x7fff); - /*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): unwrapped lwip_chksum()=%"X32_F" \n", acc));*/ - /* fold the upper bit down */ - acc = FOLD_U32T(acc); - if (q->len % 2 != 0) { - swapped = 1 - swapped; - acc = SWAP_BYTES_IN_WORD(acc); - } - /*LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): wrapped lwip_chksum()=%"X32_F" \n", acc));*/ - } - - if (swapped) { - acc = SWAP_BYTES_IN_WORD(acc); - } - - acc += (u32_t)lwip_htons((u16_t)proto); - acc += (u32_t)lwip_htons(proto_len); - - /* Fold 32-bit sum to 16 bits - calling this twice is probably faster than if statements... */ - acc = FOLD_U32T(acc); - acc = FOLD_U32T(acc); - LWIP_DEBUGF(INET_DEBUG, ("inet_chksum_pseudo(): pbuf chain lwip_chksum()=%"X32_F"\n", acc)); - return (u16_t)~(acc & 0xffffUL); -} - -#if LWIP_IPV4 -/* inet_chksum_pseudo_partial: - * - * Calculates the IPv4 pseudo Internet checksum used by TCP and UDP for a pbuf chain. - * IP addresses are expected to be in network byte order. - * - * @param p chain of pbufs over that a checksum should be calculated (ip data part) - * @param src source ip address (used for checksum of pseudo header) - * @param dst destination ip address (used for checksum of pseudo header) - * @param proto ip protocol (used for checksum of pseudo header) - * @param proto_len length of the ip data part (used for checksum of pseudo header) - * @return checksum (as u16_t) to be saved directly in the protocol header - */ -u16_t -inet_chksum_pseudo_partial(struct pbuf *p, u8_t proto, u16_t proto_len, - u16_t chksum_len, const ip4_addr_t *src, const ip4_addr_t *dest) -{ - u32_t acc; - u32_t addr; - - addr = ip4_addr_get_u32(src); - acc = (addr & 0xffffUL); - acc += ((addr >> 16) & 0xffffUL); - addr = ip4_addr_get_u32(dest); - acc += (addr & 0xffffUL); - acc += ((addr >> 16) & 0xffffUL); - /* fold down to 16 bits */ - acc = FOLD_U32T(acc); - acc = FOLD_U32T(acc); - - return inet_cksum_pseudo_partial_base(p, proto, proto_len, chksum_len, acc); -} -#endif /* LWIP_IPV4 */ - -#if LWIP_IPV6 -/** - * Calculates the checksum with IPv6 pseudo header used by TCP and UDP for a pbuf chain. - * IPv6 addresses are expected to be in network byte order. Will only compute for a - * portion of the payload. - * - * @param p chain of pbufs over that a checksum should be calculated (ip data part) - * @param proto ipv6 protocol/next header (used for checksum of pseudo header) - * @param proto_len length of the ipv6 payload (used for checksum of pseudo header) - * @param chksum_len number of payload bytes used to compute chksum - * @param src source ipv6 address (used for checksum of pseudo header) - * @param dest destination ipv6 address (used for checksum of pseudo header) - * @return checksum (as u16_t) to be saved directly in the protocol header - */ -u16_t -ip6_chksum_pseudo_partial(struct pbuf *p, u8_t proto, u16_t proto_len, - u16_t chksum_len, const ip6_addr_t *src, const ip6_addr_t *dest) -{ - u32_t acc = 0; - u32_t addr; - u8_t addr_part; - - for (addr_part = 0; addr_part < 4; addr_part++) { - addr = src->addr[addr_part]; - acc += (addr & 0xffffUL); - acc += ((addr >> 16) & 0xffffUL); - addr = dest->addr[addr_part]; - acc += (addr & 0xffffUL); - acc += ((addr >> 16) & 0xffffUL); - } - /* fold down to 16 bits */ - acc = FOLD_U32T(acc); - acc = FOLD_U32T(acc); - - return inet_cksum_pseudo_partial_base(p, proto, proto_len, chksum_len, acc); -} -#endif /* LWIP_IPV6 */ - -/* ip_chksum_pseudo_partial: - * - * Calculates the IPv4 or IPv6 pseudo Internet checksum used by TCP and UDP for a pbuf chain. - * - * @param p chain of pbufs over that a checksum should be calculated (ip data part) - * @param src source ip address (used for checksum of pseudo header) - * @param dst destination ip address (used for checksum of pseudo header) - * @param proto ip protocol (used for checksum of pseudo header) - * @param proto_len length of the ip data part (used for checksum of pseudo header) - * @return checksum (as u16_t) to be saved directly in the protocol header - */ -u16_t -ip_chksum_pseudo_partial(struct pbuf *p, u8_t proto, u16_t proto_len, - u16_t chksum_len, const ip_addr_t *src, const ip_addr_t *dest) -{ -#if LWIP_IPV6 - if (IP_IS_V6(dest)) { - return ip6_chksum_pseudo_partial(p, proto, proto_len, chksum_len, ip_2_ip6(src), ip_2_ip6(dest)); - } -#endif /* LWIP_IPV6 */ -#if LWIP_IPV4 && LWIP_IPV6 - else -#endif /* LWIP_IPV4 && LWIP_IPV6 */ -#if LWIP_IPV4 - { - return inet_chksum_pseudo_partial(p, proto, proto_len, chksum_len, ip_2_ip4(src), ip_2_ip4(dest)); - } -#endif /* LWIP_IPV4 */ -} - -/* inet_chksum: - * - * Calculates the Internet checksum over a portion of memory. Used primarily for IP - * and ICMP. - * - * @param dataptr start of the buffer to calculate the checksum (no alignment needed) - * @param len length of the buffer to calculate the checksum - * @return checksum (as u16_t) to be saved directly in the protocol header - */ - -u16_t -inet_chksum(const void *dataptr, u16_t len) -{ - return (u16_t)~(unsigned int)LWIP_CHKSUM(dataptr, len); -} - -/** - * Calculate a checksum over a chain of pbufs (without pseudo-header, much like - * inet_chksum only pbufs are used). - * - * @param p pbuf chain over that the checksum should be calculated - * @return checksum (as u16_t) to be saved directly in the protocol header - */ -u16_t -inet_chksum_pbuf(struct pbuf *p) -{ - u32_t acc; - struct pbuf *q; - u8_t swapped; - - acc = 0; - swapped = 0; - for (q = p; q != NULL; q = q->next) { - acc += LWIP_CHKSUM(q->payload, q->len); - acc = FOLD_U32T(acc); - if (q->len % 2 != 0) { - swapped = 1 - swapped; - acc = SWAP_BYTES_IN_WORD(acc); - } - } - - if (swapped) { - acc = SWAP_BYTES_IN_WORD(acc); - } - return (u16_t)~(acc & 0xffffUL); -} - -/* These are some implementations for LWIP_CHKSUM_COPY, which copies data - * like MEMCPY but generates a checksum at the same time. Since this is a - * performance-sensitive function, you might want to create your own version - * in assembly targeted at your hardware by defining it in lwipopts.h: - * #define LWIP_CHKSUM_COPY(dst, src, len) your_chksum_copy(dst, src, len) - */ - -#if (LWIP_CHKSUM_COPY_ALGORITHM == 1) /* Version #1 */ -/** Safe but slow: first call MEMCPY, then call LWIP_CHKSUM. - * For architectures with big caches, data might still be in cache when - * generating the checksum after copying. - */ -u16_t -lwip_chksum_copy(void *dst, const void *src, u16_t len) -{ - MEMCPY(dst, src, len); - return LWIP_CHKSUM(dst, len); -} -#endif /* (LWIP_CHKSUM_COPY_ALGORITHM == 1) */ diff --git a/third_party/lwip/repo/lwip/src/core/init.c b/third_party/lwip/repo/lwip/src/core/init.c deleted file mode 100644 index cb534fa405f83c..00000000000000 --- a/third_party/lwip/repo/lwip/src/core/init.c +++ /dev/null @@ -1,384 +0,0 @@ -/** - * @file - * Modules initialization - * - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - */ - -#include "lwip/opt.h" - -#include "lwip/init.h" -#include "lwip/stats.h" -#include "lwip/sys.h" -#include "lwip/mem.h" -#include "lwip/memp.h" -#include "lwip/pbuf.h" -#include "lwip/netif.h" -#include "lwip/sockets.h" -#include "lwip/ip.h" -#include "lwip/raw.h" -#include "lwip/udp.h" -#include "lwip/priv/tcp_priv.h" -#include "lwip/igmp.h" -#include "lwip/dns.h" -#include "lwip/timeouts.h" -#include "lwip/etharp.h" -#include "lwip/ip6.h" -#include "lwip/nd6.h" -#include "lwip/mld6.h" -#include "lwip/api.h" - -#include "netif/ppp/ppp_opts.h" -#include "netif/ppp/ppp_impl.h" - -#ifndef LWIP_SKIP_PACKING_CHECK - -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct packed_struct_test -{ - PACK_STRUCT_FLD_8(u8_t dummy1); - PACK_STRUCT_FIELD(u32_t dummy2); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif -#define PACKED_STRUCT_TEST_EXPECTED_SIZE 5 - -#endif - -/* Compile-time sanity checks for configuration errors. - * These can be done independently of LWIP_DEBUG, without penalty. - */ -#ifndef BYTE_ORDER - #error "BYTE_ORDER is not defined, you have to define it in your cc.h" -#endif -#if (!IP_SOF_BROADCAST && IP_SOF_BROADCAST_RECV) - #error "If you want to use broadcast filter per pcb on recv operations, you have to define IP_SOF_BROADCAST=1 in your lwipopts.h" -#endif -#if (!LWIP_UDP && LWIP_UDPLITE) - #error "If you want to use UDP Lite, you have to define LWIP_UDP=1 in your lwipopts.h" -#endif -#if (!LWIP_UDP && LWIP_DHCP) - #error "If you want to use DHCP, you have to define LWIP_UDP=1 in your lwipopts.h" -#endif -#if (!LWIP_UDP && !LWIP_RAW && LWIP_MULTICAST_TX_OPTIONS) - #error "If you want to use LWIP_MULTICAST_TX_OPTIONS, you have to define LWIP_UDP=1 and/or LWIP_RAW=1 in your lwipopts.h" -#endif -#if (!LWIP_UDP && LWIP_DNS) - #error "If you want to use DNS, you have to define LWIP_UDP=1 in your lwipopts.h" -#endif -#if !MEMP_MEM_MALLOC /* MEMP_NUM_* checks are disabled when not using the pool allocator */ -#if (LWIP_ARP && ARP_QUEUEING && (MEMP_NUM_ARP_QUEUE<=0)) - #error "If you want to use ARP Queueing, you have to define MEMP_NUM_ARP_QUEUE>=1 in your lwipopts.h" -#endif -#if (LWIP_RAW && (MEMP_NUM_RAW_PCB<=0)) - #error "If you want to use RAW, you have to define MEMP_NUM_RAW_PCB>=1 in your lwipopts.h" -#endif -#if (LWIP_UDP && (MEMP_NUM_UDP_PCB<=0)) - #error "If you want to use UDP, you have to define MEMP_NUM_UDP_PCB>=1 in your lwipopts.h" -#endif -#if (LWIP_TCP && (MEMP_NUM_TCP_PCB<=0)) - #error "If you want to use TCP, you have to define MEMP_NUM_TCP_PCB>=1 in your lwipopts.h" -#endif -#if (LWIP_IGMP && (MEMP_NUM_IGMP_GROUP<=1)) - #error "If you want to use IGMP, you have to define MEMP_NUM_IGMP_GROUP>1 in your lwipopts.h" -#endif -#if (LWIP_IGMP && !LWIP_MULTICAST_TX_OPTIONS) - #error "If you want to use IGMP, you have to define LWIP_MULTICAST_TX_OPTIONS==1 in your lwipopts.h" -#endif -#if (LWIP_IGMP && !LWIP_IPV4) - #error "IGMP needs LWIP_IPV4 enabled in your lwipopts.h" -#endif -#if ((LWIP_NETCONN || LWIP_SOCKET) && (MEMP_NUM_TCPIP_MSG_API<=0)) - #error "If you want to use Sequential API, you have to define MEMP_NUM_TCPIP_MSG_API>=1 in your lwipopts.h" -#endif -/* There must be sufficient timeouts, taking into account requirements of the subsystems. */ -#if LWIP_TIMERS && (MEMP_NUM_SYS_TIMEOUT < (LWIP_TCP + IP_REASSEMBLY + LWIP_ARP + (2*LWIP_DHCP) + LWIP_AUTOIP + LWIP_IGMP + LWIP_DNS + PPP_SUPPORT + (LWIP_IPV6 ? (1 + LWIP_IPV6_REASS + LWIP_IPV6_MLD) : 0))) - #error "MEMP_NUM_SYS_TIMEOUT is too low to accomodate all required timeouts" -#endif -#if (IP_REASSEMBLY && (MEMP_NUM_REASSDATA > IP_REASS_MAX_PBUFS)) - #error "MEMP_NUM_REASSDATA > IP_REASS_MAX_PBUFS doesn't make sense since each struct ip_reassdata must hold 2 pbufs at least!" -#endif -#endif /* !MEMP_MEM_MALLOC */ -#if LWIP_WND_SCALE -#if (LWIP_TCP && (TCP_WND > 0xffffffff)) - #error "If you want to use TCP, TCP_WND must fit in an u32_t, so, you have to reduce it in your lwipopts.h" -#endif -#if (LWIP_TCP && (TCP_RCV_SCALE > 14)) - #error "The maximum valid window scale value is 14!" -#endif -#if (LWIP_TCP && (TCP_WND > (0xFFFFU << TCP_RCV_SCALE))) - #error "TCP_WND is bigger than the configured LWIP_WND_SCALE allows!" -#endif -#if (LWIP_TCP && ((TCP_WND >> TCP_RCV_SCALE) == 0)) - #error "TCP_WND is too small for the configured LWIP_WND_SCALE (results in zero window)!" -#endif -#else /* LWIP_WND_SCALE */ -#if (LWIP_TCP && (TCP_WND > 0xffff)) - #error "If you want to use TCP, TCP_WND must fit in an u16_t, so, you have to reduce it in your lwipopts.h (or enable window scaling)" -#endif -#endif /* LWIP_WND_SCALE */ -#if (LWIP_TCP && (TCP_SND_QUEUELEN > 0xffff)) - #error "If you want to use TCP, TCP_SND_QUEUELEN must fit in an u16_t, so, you have to reduce it in your lwipopts.h" -#endif -#if (LWIP_TCP && (TCP_SND_QUEUELEN < 2)) - #error "TCP_SND_QUEUELEN must be at least 2 for no-copy TCP writes to work" -#endif -#if (LWIP_TCP && ((TCP_MAXRTX > 12) || (TCP_SYNMAXRTX > 12))) - #error "If you want to use TCP, TCP_MAXRTX and TCP_SYNMAXRTX must less or equal to 12 (due to tcp_backoff table), so, you have to reduce them in your lwipopts.h" -#endif -#if (LWIP_TCP && TCP_LISTEN_BACKLOG && ((TCP_DEFAULT_LISTEN_BACKLOG < 0) || (TCP_DEFAULT_LISTEN_BACKLOG > 0xff))) - #error "If you want to use TCP backlog, TCP_DEFAULT_LISTEN_BACKLOG must fit into an u8_t" -#endif -#if (LWIP_NETIF_API && (NO_SYS==1)) - #error "If you want to use NETIF API, you have to define NO_SYS=0 in your lwipopts.h" -#endif -#if ((LWIP_SOCKET || LWIP_NETCONN) && (NO_SYS==1)) - #error "If you want to use Sequential API, you have to define NO_SYS=0 in your lwipopts.h" -#endif -#if (LWIP_PPP_API && (NO_SYS==1)) - #error "If you want to use PPP API, you have to define NO_SYS=0 in your lwipopts.h" -#endif -#if (LWIP_PPP_API && (PPP_SUPPORT==0)) - #error "If you want to use PPP API, you have to enable PPP_SUPPORT in your lwipopts.h" -#endif -#if (((!LWIP_DHCP) || (!LWIP_AUTOIP)) && LWIP_DHCP_AUTOIP_COOP) - #error "If you want to use DHCP/AUTOIP cooperation mode, you have to define LWIP_DHCP=1 and LWIP_AUTOIP=1 in your lwipopts.h" -#endif -#if (((!LWIP_DHCP) || (!LWIP_ARP)) && DHCP_DOES_ARP_CHECK) - #error "If you want to use DHCP ARP checking, you have to define LWIP_DHCP=1 and LWIP_ARP=1 in your lwipopts.h" -#endif -#if (!LWIP_ARP && LWIP_AUTOIP) - #error "If you want to use AUTOIP, you have to define LWIP_ARP=1 in your lwipopts.h" -#endif -#if (LWIP_TCP && ((LWIP_EVENT_API && LWIP_CALLBACK_API) || (!LWIP_EVENT_API && !LWIP_CALLBACK_API))) - #error "One and exactly one of LWIP_EVENT_API and LWIP_CALLBACK_API has to be enabled in your lwipopts.h" -#endif -#if (MEM_LIBC_MALLOC && MEM_USE_POOLS) - #error "MEM_LIBC_MALLOC and MEM_USE_POOLS may not both be simultaneously enabled in your lwipopts.h" -#endif -#if (MEM_USE_POOLS && !MEMP_USE_CUSTOM_POOLS) - #error "MEM_USE_POOLS requires custom pools (MEMP_USE_CUSTOM_POOLS) to be enabled in your lwipopts.h" -#endif - -#if !LWIP_PBUF_FROM_CUSTOM_POOLS -extern int PBUFF_POOL_SIZE_TOO_SMALL[ (signed)(PBUF_POOL_BUFSIZE - MEM_ALIGNMENT - 1) ]; // error: PBUF_POOL_BUFSIZE must be greater than MEM_ALIGNMENT or the offset may take the full first pbuf -#endif - -#if (DNS_LOCAL_HOSTLIST && !DNS_LOCAL_HOSTLIST_IS_DYNAMIC && !(defined(DNS_LOCAL_HOSTLIST_INIT))) - #error "you have to define define DNS_LOCAL_HOSTLIST_INIT {{'host1', 0x123}, {'host2', 0x234}} to initialize DNS_LOCAL_HOSTLIST" -#endif -#if PPP_SUPPORT && !PPPOS_SUPPORT && !PPPOE_SUPPORT && !PPPOL2TP_SUPPORT - #error "PPP_SUPPORT needs at least one of PPPOS_SUPPORT, PPPOE_SUPPORT or PPPOL2TP_SUPPORT turned on" -#endif -#if PPP_SUPPORT && !PPP_IPV4_SUPPORT && !PPP_IPV6_SUPPORT - #error "PPP_SUPPORT needs PPP_IPV4_SUPPORT and/or PPP_IPV6_SUPPORT turned on" -#endif -#if PPP_SUPPORT && PPP_IPV4_SUPPORT && !LWIP_IPV4 - #error "PPP_IPV4_SUPPORT needs LWIP_IPV4 turned on" -#endif -#if PPP_SUPPORT && PPP_IPV6_SUPPORT && !LWIP_IPV6 - #error "PPP_IPV6_SUPPORT needs LWIP_IPV6 turned on" -#endif -#if !LWIP_ETHERNET && (LWIP_ARP || PPPOE_SUPPORT) - #error "LWIP_ETHERNET needs to be turned on for LWIP_ARP or PPPOE_SUPPORT" -#endif -#if LWIP_TCPIP_CORE_LOCKING_INPUT && !LWIP_TCPIP_CORE_LOCKING - #error "When using LWIP_TCPIP_CORE_LOCKING_INPUT, LWIP_TCPIP_CORE_LOCKING must be enabled, too" -#endif -#if LWIP_TCP && LWIP_NETIF_TX_SINGLE_PBUF && !TCP_OVERSIZE - #error "LWIP_NETIF_TX_SINGLE_PBUF needs TCP_OVERSIZE enabled to create single-pbuf TCP packets" -#endif -#if LWIP_NETCONN && LWIP_TCP -#if NETCONN_COPY != TCP_WRITE_FLAG_COPY - #error "NETCONN_COPY != TCP_WRITE_FLAG_COPY" -#endif -#if NETCONN_MORE != TCP_WRITE_FLAG_MORE - #error "NETCONN_MORE != TCP_WRITE_FLAG_MORE" -#endif -#endif /* LWIP_NETCONN && LWIP_TCP */ -#if LWIP_SOCKET -/* Check that the SO_* socket options and SOF_* lwIP-internal flags match */ -#if SO_REUSEADDR != SOF_REUSEADDR - #error "WARNING: SO_REUSEADDR != SOF_REUSEADDR" -#endif -#if SO_KEEPALIVE != SOF_KEEPALIVE - #error "WARNING: SO_KEEPALIVE != SOF_KEEPALIVE" -#endif -#if SO_BROADCAST != SOF_BROADCAST - #error "WARNING: SO_BROADCAST != SOF_BROADCAST" -#endif -#endif /* LWIP_SOCKET */ - - -/* Compile-time checks for deprecated options. - */ -#ifdef MEMP_NUM_TCPIP_MSG - #error "MEMP_NUM_TCPIP_MSG option is deprecated. Remove it from your lwipopts.h." -#endif -#ifdef TCP_REXMIT_DEBUG - #error "TCP_REXMIT_DEBUG option is deprecated. Remove it from your lwipopts.h." -#endif -#ifdef RAW_STATS - #error "RAW_STATS option is deprecated. Remove it from your lwipopts.h." -#endif -#ifdef ETHARP_QUEUE_FIRST - #error "ETHARP_QUEUE_FIRST option is deprecated. Remove it from your lwipopts.h." -#endif -#ifdef ETHARP_ALWAYS_INSERT - #error "ETHARP_ALWAYS_INSERT option is deprecated. Remove it from your lwipopts.h." -#endif -#if !NO_SYS && LWIP_TCPIP_CORE_LOCKING && LWIP_COMPAT_MUTEX && !defined(LWIP_COMPAT_MUTEX_ALLOWED) - #error "LWIP_COMPAT_MUTEX cannot prevent priority inversion. It is recommended to implement priority-aware mutexes. (Define LWIP_COMPAT_MUTEX_ALLOWED to disable this error.)" -#endif - -#ifndef LWIP_DISABLE_TCP_SANITY_CHECKS -#define LWIP_DISABLE_TCP_SANITY_CHECKS 0 -#endif -#ifndef LWIP_DISABLE_MEMP_SANITY_CHECKS -#define LWIP_DISABLE_MEMP_SANITY_CHECKS 0 -#endif - -/* MEMP sanity checks */ -#if MEMP_MEM_MALLOC -#if !LWIP_DISABLE_MEMP_SANITY_CHECKS -#if LWIP_NETCONN || LWIP_SOCKET -#if !MEMP_NUM_NETCONN && LWIP_SOCKET -#error "lwip_sanity_check: WARNING: MEMP_NUM_NETCONN cannot be 0 when using sockets!" -#endif -#else /* MEMP_MEM_MALLOC */ -#if MEMP_NUM_NETCONN > (MEMP_NUM_TCP_PCB+MEMP_NUM_TCP_PCB_LISTEN+MEMP_NUM_UDP_PCB+MEMP_NUM_RAW_PCB) -#error "lwip_sanity_check: WARNING: MEMP_NUM_NETCONN should be less than the sum of MEMP_NUM_{TCP,RAW,UDP}_PCB+MEMP_NUM_TCP_PCB_LISTEN. If you know what you are doing, define LWIP_DISABLE_MEMP_SANITY_CHECKS to 1 to disable this error." -#endif -#endif /* LWIP_NETCONN || LWIP_SOCKET */ -#endif /* !LWIP_DISABLE_MEMP_SANITY_CHECKS */ -#if MEM_USE_POOLS -#error "MEMP_MEM_MALLOC and MEM_USE_POOLS cannot be enabled at the same time" -#endif -#ifdef LWIP_HOOK_MEMP_AVAILABLE -#error "LWIP_HOOK_MEMP_AVAILABLE doesn't make sense with MEMP_MEM_MALLOC" -#endif -#endif /* MEMP_MEM_MALLOC */ - -/* TCP sanity checks */ -#if !LWIP_DISABLE_TCP_SANITY_CHECKS -#if LWIP_TCP -#if !MEMP_MEM_MALLOC && (MEMP_NUM_TCP_SEG < TCP_SND_QUEUELEN) - #error "lwip_sanity_check: WARNING: MEMP_NUM_TCP_SEG should be at least as big as TCP_SND_QUEUELEN. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error." -#endif -#if TCP_SND_BUF < (2 * TCP_MSS) - #error "lwip_sanity_check: WARNING: TCP_SND_BUF must be at least as much as (2 * TCP_MSS) for things to work smoothly. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error." -#endif -#if TCP_SND_QUEUELEN < (2 * (TCP_SND_BUF / TCP_MSS)) - #error "lwip_sanity_check: WARNING: TCP_SND_QUEUELEN must be at least as much as (2 * TCP_SND_BUF/TCP_MSS) for things to work. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error." -#endif -#if TCP_SNDLOWAT >= TCP_SND_BUF - #error "lwip_sanity_check: WARNING: TCP_SNDLOWAT must be less than TCP_SND_BUF. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error." -#endif -#if TCP_SNDLOWAT >= (0xFFFF - (4 * TCP_MSS)) - #error "lwip_sanity_check: WARNING: TCP_SNDLOWAT must at least be 4*MSS below u16_t overflow!" -#endif -#if TCP_SNDQUEUELOWAT >= TCP_SND_QUEUELEN - #error "lwip_sanity_check: WARNING: TCP_SNDQUEUELOWAT must be less than TCP_SND_QUEUELEN. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error." -#endif -#if !MEMP_MEM_MALLOC && PBUF_POOL_SIZE && (PBUF_POOL_BUFSIZE <= (PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN)) - #error "lwip_sanity_check: WARNING: PBUF_POOL_BUFSIZE does not provide enough space for protocol headers. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error." -#endif -#if !MEMP_MEM_MALLOC && PBUF_POOL_SIZE && (TCP_WND > (PBUF_POOL_SIZE * (PBUF_POOL_BUFSIZE - (PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN)))) - #error "lwip_sanity_check: WARNING: TCP_WND is larger than space provided by PBUF_POOL_SIZE * (PBUF_POOL_BUFSIZE - protocol headers). If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error." -#endif -#if TCP_WND < TCP_MSS - #error "lwip_sanity_check: WARNING: TCP_WND is smaller than MSS. If you know what you are doing, define LWIP_DISABLE_TCP_SANITY_CHECKS to 1 to disable this error." -#endif -#endif /* LWIP_TCP */ -#endif /* !LWIP_DISABLE_TCP_SANITY_CHECKS */ - -/** - * @ingroup lwip_nosys - * Initialize all modules. - * Use this in NO_SYS mode. Use tcpip_init() otherwise. - */ -void -lwip_init(void) -{ -#ifndef LWIP_SKIP_CONST_CHECK - int a = 0; - LWIP_UNUSED_ARG(a); - LWIP_ASSERT("LWIP_CONST_CAST not implemented correctly. Check your lwIP port.", LWIP_CONST_CAST(void*, &a) == &a); -#endif -#ifndef LWIP_SKIP_PACKING_CHECK - LWIP_ASSERT("Struct packing not implemented correctly. Check your lwIP port.", sizeof(struct packed_struct_test) == PACKED_STRUCT_TEST_EXPECTED_SIZE); -#endif - - /* Modules initialization */ - stats_init(); -#if !NO_SYS - sys_init(); -#endif /* !NO_SYS */ - mem_init(); - memp_init(); - pbuf_init(); - netif_init(); -#if LWIP_IPV4 - ip_init(); -#if LWIP_ARP - etharp_init(); -#endif /* LWIP_ARP */ -#endif /* LWIP_IPV4 */ -#if LWIP_RAW - raw_init(); -#endif /* LWIP_RAW */ -#if LWIP_UDP - udp_init(); -#endif /* LWIP_UDP */ -#if LWIP_TCP - tcp_init(); -#endif /* LWIP_TCP */ -#if LWIP_IGMP - igmp_init(); -#endif /* LWIP_IGMP */ -#if LWIP_DNS - dns_init(); -#endif /* LWIP_DNS */ -#if PPP_SUPPORT - ppp_init(); -#endif - -#if LWIP_TIMERS - sys_timeouts_init(); -#endif /* LWIP_TIMERS */ -} diff --git a/third_party/lwip/repo/lwip/src/core/ip.c b/third_party/lwip/repo/lwip/src/core/ip.c deleted file mode 100644 index 51010785b3eb07..00000000000000 --- a/third_party/lwip/repo/lwip/src/core/ip.c +++ /dev/null @@ -1,185 +0,0 @@ -/** - * @file - * Common IPv4 and IPv6 code - * - * @defgroup ip IP - * @ingroup callbackstyle_api - * - * @defgroup ip4 IPv4 - * @ingroup ip - * - * @defgroup ip6 IPv6 - * @ingroup ip - * - * @defgroup ipaddr IP address handling - * @ingroup infrastructure - * - * @defgroup ip4addr IPv4 only - * @ingroup ipaddr - * - * @defgroup ip6addr IPv6 only - * @ingroup ipaddr - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ - -#include "lwip/opt.h" - -#if LWIP_IPV4 || LWIP_IPV6 - -#include "lwip/ip_addr.h" -#include "lwip/ip.h" - -/** Global data for both IPv4 and IPv6 */ -struct ip_globals ip_data; - -#if LWIP_IP_DEBUG_TARGET - -#define DEBUG_TARGET_MODE_ALLOW_ALL 0 -#define DEBUG_TARGET_MODE_ALLOW_NONE 1 -#define DEBUG_TARGET_MODE_FILTER 2 - -int debug_target_mode = DEBUG_TARGET_MODE_ALLOW_ALL; -int debug_target_is_ipv6; -ipX_addr_t debug_target_ip; - -int lwip_set_debug_target(const char *addr) -{ - if (addr == 0) { - debug_target_mode = DEBUG_TARGET_MODE_ALLOW_ALL; - } - else if (*addr == 0) { - debug_target_mode = DEBUG_TARGET_MODE_ALLOW_NONE; - } - else { - if (ipaddr_aton(addr, ipX_2_ip(&debug_target_ip))) { - debug_target_is_ipv6 = 0; - debug_target_mode = DEBUG_TARGET_MODE_FILTER; - } -#if LWIP_IPV6 - else if (ip6addr_aton(addr, ipX_2_ip6(&debug_target_ip))) { - debug_target_is_ipv6 = 1; - debug_target_mode = DEBUG_TARGET_MODE_FILTER; - } -#endif - else { - return 0; - } - } - return 1; -} - -int debug_target_match(int is_ipv6, ipX_addr_t *src, ipX_addr_t *dest) -{ - if (debug_target_mode == DEBUG_TARGET_MODE_ALLOW_ALL) { - return 1; - } - if (debug_target_mode == DEBUG_TARGET_MODE_ALLOW_NONE) { - return 0; - } - if (is_ipv6 != debug_target_is_ipv6) { - return 0; - } - if (ipX_addr_isany(is_ipv6, &debug_target_ip)) { - return 1; - } - if (ipX_addr_cmp(is_ipv6, &debug_target_ip, src)) { - return 1; - } - if (ipX_addr_cmp(is_ipv6, &debug_target_ip, dest)) { - return 1; - } - return 0; -} - -#endif - -#if LWIP_IPV4 && LWIP_IPV6 - -const ip_addr_t ip_addr_any_type = IPADDR_ANY_TYPE_INIT; - -/** - * @ingroup ipaddr - * Convert IP address string (both versions) to numeric. - * The version is auto-detected from the string. - * - * @param cp IP address string to convert - * @param addr conversion result is stored here - * @return 1 on success, 0 on error - */ -int -ipaddr_aton(const char *cp, ip_addr_t *addr) -{ - if (cp != NULL) { - const char* c; - for (c = cp; *c != 0; c++) { - if (*c == ':') { - /* contains a colon: IPv6 address */ - if (addr) { - IP_SET_TYPE_VAL(*addr, IPADDR_TYPE_V6); - } - return ip6addr_aton(cp, ip_2_ip6(addr)); - } else if (*c == '.') { - /* contains a dot: IPv4 address */ - break; - } - } - /* call ip4addr_aton as fallback or if IPv4 was found */ - if (addr) { - IP_SET_TYPE_VAL(*addr, IPADDR_TYPE_V4); - } - return ip4addr_aton(cp, ip_2_ip4(addr)); - } - return 0; -} - -/** - * @ingroup lwip_nosys - * If both IP versions are enabled, this function can dispatch packets to the correct one. - * Don't call directly, pass to netif_add() and call netif->input(). - */ -err_t -ip_input(struct pbuf *p, struct netif *inp) -{ - if (p != NULL) { - if (IP_HDR_GET_VERSION(p->payload) == 6) { - return ip6_input(p, inp); - } - return ip4_input(p, inp); - } - return ERR_VAL; -} - -#endif /* LWIP_IPV4 && LWIP_IPV6 */ - -#endif /* LWIP_IPV4 || LWIP_IPV6 */ diff --git a/third_party/lwip/repo/lwip/src/core/ipv4/autoip.c b/third_party/lwip/repo/lwip/src/core/ipv4/autoip.c deleted file mode 100644 index e072bc5a89fcc4..00000000000000 --- a/third_party/lwip/repo/lwip/src/core/ipv4/autoip.c +++ /dev/null @@ -1,530 +0,0 @@ -/** - * @file - * AutoIP Automatic LinkLocal IP Configuration - * - * This is a AutoIP implementation for the lwIP TCP/IP stack. It aims to conform - * with RFC 3927. - * - * @defgroup autoip AUTOIP - * @ingroup ip4 - * AUTOIP related functions - * USAGE: - * - * define @ref LWIP_AUTOIP 1 in your lwipopts.h - * Options: - * AUTOIP_TMR_INTERVAL msecs, - * I recommend a value of 100. The value must divide 1000 with a remainder almost 0. - * Possible values are 1000, 500, 333, 250, 200, 166, 142, 125, 111, 100 .... - * - * Without DHCP: - * - Call autoip_start() after netif_add(). - * - * With DHCP: - * - define @ref LWIP_DHCP_AUTOIP_COOP 1 in your lwipopts.h. - * - Configure your DHCP Client. - * - * @see netifapi_autoip - */ - -/* - * - * Copyright (c) 2007 Dominik Spies - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * Author: Dominik Spies - */ - -#include "lwip/opt.h" - -#if LWIP_IPV4 && LWIP_AUTOIP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/mem.h" -/* #include "lwip/udp.h" */ -#include "lwip/ip_addr.h" -#include "lwip/netif.h" -#include "lwip/autoip.h" -#include "lwip/etharp.h" -#include "lwip/prot/autoip.h" - -#include - -/** Pseudo random macro based on netif informations. - * You could use "rand()" from the C Library if you define LWIP_AUTOIP_RAND in lwipopts.h */ -#ifndef LWIP_AUTOIP_RAND -#define LWIP_AUTOIP_RAND(netif) ( (((u32_t)((netif->hwaddr[5]) & 0xff) << 24) | \ - ((u32_t)((netif->hwaddr[3]) & 0xff) << 16) | \ - ((u32_t)((netif->hwaddr[2]) & 0xff) << 8) | \ - ((u32_t)((netif->hwaddr[4]) & 0xff))) + \ - (netif_autoip_data(netif)? netif_autoip_data(netif)->tried_llipaddr : 0)) -#endif /* LWIP_AUTOIP_RAND */ - -/** - * Macro that generates the initial IP address to be tried by AUTOIP. - * If you want to override this, define it to something else in lwipopts.h. - */ -#ifndef LWIP_AUTOIP_CREATE_SEED_ADDR -#define LWIP_AUTOIP_CREATE_SEED_ADDR(netif) \ - lwip_htonl(AUTOIP_RANGE_START + ((u32_t)(((u8_t)(netif->hwaddr[4])) | \ - ((u32_t)((u8_t)(netif->hwaddr[5]))) << 8))) -#endif /* LWIP_AUTOIP_CREATE_SEED_ADDR */ - -/* static functions */ -static err_t autoip_arp_announce(struct netif *netif); -static void autoip_start_probing(struct netif *netif); - -/** - * @ingroup autoip - * Set a statically allocated struct autoip to work with. - * Using this prevents autoip_start to allocate it using mem_malloc. - * - * @param netif the netif for which to set the struct autoip - * @param autoip (uninitialised) autoip struct allocated by the application - */ -void -autoip_set_struct(struct netif *netif, struct autoip *autoip) -{ - LWIP_ASSERT_CORE_LOCKED(); - LWIP_ASSERT("netif != NULL", netif != NULL); - LWIP_ASSERT("autoip != NULL", autoip != NULL); - LWIP_ASSERT("netif already has a struct autoip set", - netif_autoip_data(netif) == NULL); - - /* clear data structure */ - memset(autoip, 0, sizeof(struct autoip)); - /* autoip->state = AUTOIP_STATE_OFF; */ - netif_set_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_AUTOIP, autoip); -} - -/** Restart AutoIP client and check the next address (conflict detected) - * - * @param netif The netif under AutoIP control - */ -static void -autoip_restart(struct netif *netif) -{ - struct autoip* autoip = netif_autoip_data(netif); - autoip->tried_llipaddr++; - autoip_start(netif); -} - -/** - * Handle a IP address conflict after an ARP conflict detection - */ -static void -autoip_handle_arp_conflict(struct netif *netif) -{ - struct autoip* autoip = netif_autoip_data(netif); - - /* RFC3927, 2.5 "Conflict Detection and Defense" allows two options where - a) means retreat on the first conflict and - b) allows to keep an already configured address when having only one - conflict in 10 seconds - We use option b) since it helps to improve the chance that one of the two - conflicting hosts may be able to retain its address. */ - - if (autoip->lastconflict > 0) { - /* retreat, there was a conflicting ARP in the last DEFEND_INTERVAL seconds */ - LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, - ("autoip_handle_arp_conflict(): we are defending, but in DEFEND_INTERVAL, retreating\n")); - - /* Active TCP sessions are aborted when removing the ip addresss */ - autoip_restart(netif); - } else { - LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, - ("autoip_handle_arp_conflict(): we are defend, send ARP Announce\n")); - autoip_arp_announce(netif); - autoip->lastconflict = DEFEND_INTERVAL * AUTOIP_TICKS_PER_SECOND; - } -} - -/** - * Create an IP-Address out of range 169.254.1.0 to 169.254.254.255 - * - * @param netif network interface on which create the IP-Address - * @param ipaddr ip address to initialize - */ -static void -autoip_create_addr(struct netif *netif, ip4_addr_t *ipaddr) -{ - struct autoip* autoip = netif_autoip_data(netif); - - /* Here we create an IP-Address out of range 169.254.1.0 to 169.254.254.255 - * compliant to RFC 3927 Section 2.1 - * We have 254 * 256 possibilities */ - - u32_t addr = lwip_ntohl(LWIP_AUTOIP_CREATE_SEED_ADDR(netif)); - addr += autoip->tried_llipaddr; - addr = AUTOIP_NET | (addr & 0xffff); - /* Now, 169.254.0.0 <= addr <= 169.254.255.255 */ - - if (addr < AUTOIP_RANGE_START) { - addr += AUTOIP_RANGE_END - AUTOIP_RANGE_START + 1; - } - if (addr > AUTOIP_RANGE_END) { - addr -= AUTOIP_RANGE_END - AUTOIP_RANGE_START + 1; - } - LWIP_ASSERT("AUTOIP address not in range", (addr >= AUTOIP_RANGE_START) && - (addr <= AUTOIP_RANGE_END)); - ip4_addr_set_u32(ipaddr, lwip_htonl(addr)); - - LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, - ("autoip_create_addr(): tried_llipaddr=%"U16_F", %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", - (u16_t)(autoip->tried_llipaddr), ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), - ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr))); -} - -/** - * Sends an ARP probe from a network interface - * - * @param netif network interface used to send the probe - */ -static err_t -autoip_arp_probe(struct netif *netif) -{ - struct autoip* autoip = netif_autoip_data(netif); - /* this works because netif->ip_addr is ANY */ - return etharp_request(netif, &autoip->llipaddr); -} - -/** - * Sends an ARP announce from a network interface - * - * @param netif network interface used to send the announce - */ -static err_t -autoip_arp_announce(struct netif *netif) -{ - return etharp_gratuitous(netif); -} - -/** - * Configure interface for use with current LL IP-Address - * - * @param netif network interface to configure with current LL IP-Address - */ -static err_t -autoip_bind(struct netif *netif) -{ - struct autoip* autoip = netif_autoip_data(netif); - ip4_addr_t sn_mask, gw_addr; - - LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, - ("autoip_bind(netif=%p) %c%c%"U16_F" %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", - (void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num, - ip4_addr1_16(&autoip->llipaddr), ip4_addr2_16(&autoip->llipaddr), - ip4_addr3_16(&autoip->llipaddr), ip4_addr4_16(&autoip->llipaddr))); - - IP4_ADDR(&sn_mask, 255, 255, 0, 0); - IP4_ADDR(&gw_addr, 0, 0, 0, 0); - - netif_set_addr(netif, &autoip->llipaddr, &sn_mask, &gw_addr); - /* interface is used by routing now that an address is set */ - - return ERR_OK; -} - -/** - * @ingroup autoip - * Start AutoIP client - * - * @param netif network interface on which start the AutoIP client - */ -err_t -autoip_start(struct netif *netif) -{ - struct autoip* autoip = netif_autoip_data(netif); - err_t result = ERR_OK; - - LWIP_ASSERT_CORE_LOCKED(); - LWIP_ERROR("netif is not up, old style port?", netif_is_up(netif), return ERR_ARG;); - - /* Set IP-Address, Netmask and Gateway to 0 to make sure that - * ARP Packets are formed correctly - */ - netif_set_addr(netif, IP4_ADDR_ANY4, IP4_ADDR_ANY4, IP4_ADDR_ANY4); - - LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, - ("autoip_start(netif=%p) %c%c%"U16_F"\n", (void*)netif, netif->name[0], - netif->name[1], (u16_t)netif->num)); - if (autoip == NULL) { - /* no AutoIP client attached yet? */ - LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, - ("autoip_start(): starting new AUTOIP client\n")); - autoip = (struct autoip *)mem_malloc(sizeof(struct autoip)); - if (autoip == NULL) { - LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, - ("autoip_start(): could not allocate autoip\n")); - return ERR_MEM; - } - memset(autoip, 0, sizeof(struct autoip)); - /* store this AutoIP client in the netif */ - netif_set_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_AUTOIP, autoip); - LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, ("autoip_start(): allocated autoip")); - } else { - autoip->state = AUTOIP_STATE_OFF; - autoip->ttw = 0; - autoip->sent_num = 0; - ip4_addr_set_zero(&autoip->llipaddr); - autoip->lastconflict = 0; - } - - autoip_create_addr(netif, &(autoip->llipaddr)); - autoip_start_probing(netif); - - return result; -} - -static void -autoip_start_probing(struct netif *netif) -{ - struct autoip* autoip = netif_autoip_data(netif); - - autoip->state = AUTOIP_STATE_PROBING; - autoip->sent_num = 0; - LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, - ("autoip_start_probing(): changing state to PROBING: %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", - ip4_addr1_16(&autoip->llipaddr), ip4_addr2_16(&autoip->llipaddr), - ip4_addr3_16(&autoip->llipaddr), ip4_addr4_16(&autoip->llipaddr))); - - /* time to wait to first probe, this is randomly - * chosen out of 0 to PROBE_WAIT seconds. - * compliant to RFC 3927 Section 2.2.1 - */ - autoip->ttw = (u16_t)(LWIP_AUTOIP_RAND(netif) % (PROBE_WAIT * AUTOIP_TICKS_PER_SECOND)); - - /* - * if we tried more then MAX_CONFLICTS we must limit our rate for - * acquiring and probing address - * compliant to RFC 3927 Section 2.2.1 - */ - if (autoip->tried_llipaddr > MAX_CONFLICTS) { - autoip->ttw = RATE_LIMIT_INTERVAL * AUTOIP_TICKS_PER_SECOND; - } -} - -/** - * Handle a possible change in the network configuration. - * - * If there is an AutoIP address configured, take the interface down - * and begin probing with the same address. - */ -void -autoip_network_changed(struct netif *netif) -{ - struct autoip* autoip = netif_autoip_data(netif); - - if (autoip && (autoip->state != AUTOIP_STATE_OFF)) { - autoip_start_probing(netif); - } -} - -/** - * @ingroup autoip - * Stop AutoIP client - * - * @param netif network interface on which stop the AutoIP client - */ -err_t -autoip_stop(struct netif *netif) -{ - struct autoip* autoip = netif_autoip_data(netif); - - LWIP_ASSERT_CORE_LOCKED(); - if (autoip != NULL) { - autoip->state = AUTOIP_STATE_OFF; - if (ip4_addr_islinklocal(netif_ip4_addr(netif))) { - netif_set_addr(netif, IP4_ADDR_ANY4, IP4_ADDR_ANY4, IP4_ADDR_ANY4); - } - } - return ERR_OK; -} - -/** - * Has to be called in loop every AUTOIP_TMR_INTERVAL milliseconds - */ -void -autoip_tmr(void) -{ - struct netif *netif = netif_list; - /* loop through netif's */ - while (netif != NULL) { - struct autoip* autoip = netif_autoip_data(netif); - /* only act on AutoIP configured interfaces */ - if (autoip != NULL) { - if (autoip->lastconflict > 0) { - autoip->lastconflict--; - } - - LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, - ("autoip_tmr() AutoIP-State: %"U16_F", ttw=%"U16_F"\n", - (u16_t)(autoip->state), autoip->ttw)); - - if (autoip->ttw > 0) { - autoip->ttw--; - } - - switch(autoip->state) { - case AUTOIP_STATE_PROBING: - if (autoip->ttw == 0) { - if (autoip->sent_num >= PROBE_NUM) { - /* Switch to ANNOUNCING: now we can bind to an IP address and use it */ - autoip->state = AUTOIP_STATE_ANNOUNCING; - autoip_bind(netif); - /* autoip_bind() calls netif_set_addr(): this triggers a gratuitous ARP - which counts as an announcement */ - autoip->sent_num = 1; - autoip->ttw = ANNOUNCE_WAIT * AUTOIP_TICKS_PER_SECOND; - LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, - ("autoip_tmr(): changing state to ANNOUNCING: %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", - ip4_addr1_16(&autoip->llipaddr), ip4_addr2_16(&autoip->llipaddr), - ip4_addr3_16(&autoip->llipaddr), ip4_addr4_16(&autoip->llipaddr))); - } else { - autoip_arp_probe(netif); - LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, ("autoip_tmr() PROBING Sent Probe\n")); - autoip->sent_num++; - if (autoip->sent_num == PROBE_NUM) { - /* calculate time to wait to for announce */ - autoip->ttw = ANNOUNCE_WAIT * AUTOIP_TICKS_PER_SECOND; - } else { - /* calculate time to wait to next probe */ - autoip->ttw = (u16_t)((LWIP_AUTOIP_RAND(netif) % - ((PROBE_MAX - PROBE_MIN) * AUTOIP_TICKS_PER_SECOND) ) + - PROBE_MIN * AUTOIP_TICKS_PER_SECOND); - } - } - } - break; - - case AUTOIP_STATE_ANNOUNCING: - if (autoip->ttw == 0) { - autoip_arp_announce(netif); - LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, ("autoip_tmr() ANNOUNCING Sent Announce\n")); - autoip->ttw = ANNOUNCE_INTERVAL * AUTOIP_TICKS_PER_SECOND; - autoip->sent_num++; - - if (autoip->sent_num >= ANNOUNCE_NUM) { - autoip->state = AUTOIP_STATE_BOUND; - autoip->sent_num = 0; - autoip->ttw = 0; - LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, - ("autoip_tmr(): changing state to BOUND: %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", - ip4_addr1_16(&autoip->llipaddr), ip4_addr2_16(&autoip->llipaddr), - ip4_addr3_16(&autoip->llipaddr), ip4_addr4_16(&autoip->llipaddr))); - } - } - break; - - default: - /* nothing to do in other states */ - break; - } - } - /* proceed to next network interface */ - netif = netif->next; - } -} - -/** - * Handles every incoming ARP Packet, called by etharp_input(). - * - * @param netif network interface to use for autoip processing - * @param hdr Incoming ARP packet - */ -void -autoip_arp_reply(struct netif *netif, struct etharp_hdr *hdr) -{ - struct autoip* autoip = netif_autoip_data(netif); - - LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE, ("autoip_arp_reply()\n")); - if ((autoip != NULL) && (autoip->state != AUTOIP_STATE_OFF)) { - /* when ip.src == llipaddr && hw.src != netif->hwaddr - * - * when probing ip.dst == llipaddr && hw.src != netif->hwaddr - * we have a conflict and must solve it - */ - ip4_addr_t sipaddr, dipaddr; - struct eth_addr netifaddr; - ETHADDR16_COPY(netifaddr.addr, netif->hwaddr); - - /* Copy struct ip4_addr2 to aligned ip4_addr, to support compilers without - * structure packing (not using structure copy which breaks strict-aliasing rules). - */ - IPADDR2_COPY(&sipaddr, &hdr->sipaddr); - IPADDR2_COPY(&dipaddr, &hdr->dipaddr); - - if (autoip->state == AUTOIP_STATE_PROBING) { - /* RFC 3927 Section 2.2.1: - * from beginning to after ANNOUNCE_WAIT - * seconds we have a conflict if - * ip.src == llipaddr OR - * ip.dst == llipaddr && hw.src != own hwaddr - */ - if ((ip4_addr_cmp(&sipaddr, &autoip->llipaddr)) || - (ip4_addr_isany_val(sipaddr) && - ip4_addr_cmp(&dipaddr, &autoip->llipaddr) && - !eth_addr_cmp(&netifaddr, &hdr->shwaddr))) { - LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE | LWIP_DBG_LEVEL_WARNING, - ("autoip_arp_reply(): Probe Conflict detected\n")); - autoip_restart(netif); - } - } else { - /* RFC 3927 Section 2.5: - * in any state we have a conflict if - * ip.src == llipaddr && hw.src != own hwaddr - */ - if (ip4_addr_cmp(&sipaddr, &autoip->llipaddr) && - !eth_addr_cmp(&netifaddr, &hdr->shwaddr)) { - LWIP_DEBUGF(AUTOIP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE | LWIP_DBG_LEVEL_WARNING, - ("autoip_arp_reply(): Conflicting ARP-Packet detected\n")); - autoip_handle_arp_conflict(netif); - } - } - } -} - -/** check if AutoIP supplied netif->ip_addr - * - * @param netif the netif to check - * @return 1 if AutoIP supplied netif->ip_addr (state BOUND or ANNOUNCING), - * 0 otherwise - */ -u8_t -autoip_supplied_address(const struct netif *netif) -{ - if ((netif != NULL) && (netif_autoip_data(netif) != NULL)) { - struct autoip* autoip = netif_autoip_data(netif); - return (autoip->state == AUTOIP_STATE_BOUND) || (autoip->state == AUTOIP_STATE_ANNOUNCING); - } - return 0; -} - -u8_t -autoip_accept_packet(struct netif *netif, const ip4_addr_t *addr) -{ - struct autoip* autoip = netif_autoip_data(netif); - return (autoip != NULL) && ip4_addr_cmp(addr, &(autoip->llipaddr)); -} - -#endif /* LWIP_IPV4 && LWIP_AUTOIP */ diff --git a/third_party/lwip/repo/lwip/src/core/ipv4/dhcp.c b/third_party/lwip/repo/lwip/src/core/ipv4/dhcp.c deleted file mode 100644 index b5e468ba5d2e8d..00000000000000 --- a/third_party/lwip/repo/lwip/src/core/ipv4/dhcp.c +++ /dev/null @@ -1,1961 +0,0 @@ -/** - * @file - * Dynamic Host Configuration Protocol client - * - * @defgroup dhcp4 DHCPv4 - * @ingroup ip4 - * DHCP (IPv4) related functions - * This is a DHCP client for the lwIP TCP/IP stack. It aims to conform - * with RFC 2131 and RFC 2132. - * - * @todo: - * - Support for interfaces other than Ethernet (SLIP, PPP, ...) - * - * Options: - * @ref DHCP_COARSE_TIMER_SECS (recommended 60 which is a minute) - * @ref DHCP_FINE_TIMER_MSECS (recommended 500 which equals TCP coarse timer) - * - * dhcp_start() starts a DHCP client instance which - * configures the interface by obtaining an IP address lease and maintaining it. - * - * Use dhcp_release() to end the lease and use dhcp_stop() - * to remove the DHCP client. - * - * @see netifapi_dhcp4 - */ - -/* - * Copyright (c) 2001-2004 Leon Woestenberg - * Copyright (c) 2001-2004 Axon Digital Design B.V., The Netherlands. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * The Swedish Institute of Computer Science and Adam Dunkels - * are specifically granted permission to redistribute this - * source code. - * - * Author: Leon Woestenberg - * - */ - -#include "lwip/opt.h" - -#if LWIP_IPV4 && LWIP_DHCP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/stats.h" -#include "lwip/mem.h" -#include "lwip/udp.h" -#include "lwip/ip_addr.h" -#include "lwip/netif.h" -#include "lwip/def.h" -#include "lwip/dhcp.h" -#include "lwip/autoip.h" -#include "lwip/dns.h" -#include "lwip/etharp.h" -#include "lwip/prot/dhcp.h" - -#include - -/** DHCP_CREATE_RAND_XID: if this is set to 1, the xid is created using - * LWIP_RAND() (this overrides DHCP_GLOBAL_XID) - */ -#ifndef DHCP_CREATE_RAND_XID -#define DHCP_CREATE_RAND_XID 1 -#endif - -/** Default for DHCP_GLOBAL_XID is 0xABCD0000 - * This can be changed by defining DHCP_GLOBAL_XID and DHCP_GLOBAL_XID_HEADER, e.g. - * \#define DHCP_GLOBAL_XID_HEADER "stdlib.h" - * \#define DHCP_GLOBAL_XID rand() - */ -#ifdef DHCP_GLOBAL_XID_HEADER -#include DHCP_GLOBAL_XID_HEADER /* include optional starting XID generation prototypes */ -#endif - -/** DHCP_OPTION_MAX_MSG_SIZE is set to the MTU - * MTU is checked to be big enough in dhcp_start */ -#define DHCP_MAX_MSG_LEN(netif) (netif->mtu) -#define DHCP_MAX_MSG_LEN_MIN_REQUIRED 576 -/** Minimum length for reply before packet is parsed */ -#define DHCP_MIN_REPLY_LEN 44 - -#define REBOOT_TRIES 2 - -#if LWIP_DNS && LWIP_DHCP_MAX_DNS_SERVERS -#if DNS_MAX_SERVERS > LWIP_DHCP_MAX_DNS_SERVERS -#define LWIP_DHCP_PROVIDE_DNS_SERVERS LWIP_DHCP_MAX_DNS_SERVERS -#else -#define LWIP_DHCP_PROVIDE_DNS_SERVERS DNS_MAX_SERVERS -#endif -#else -#define LWIP_DHCP_PROVIDE_DNS_SERVERS 0 -#endif - -/** Option handling: options are parsed in dhcp_parse_reply - * and saved in an array where other functions can load them from. - * This might be moved into the struct dhcp (not necessarily since - * lwIP is single-threaded and the array is only used while in recv - * callback). */ -enum dhcp_option_idx { - DHCP_OPTION_IDX_OVERLOAD = 0, - DHCP_OPTION_IDX_MSG_TYPE, - DHCP_OPTION_IDX_SERVER_ID, - DHCP_OPTION_IDX_LEASE_TIME, - DHCP_OPTION_IDX_T1, - DHCP_OPTION_IDX_T2, - DHCP_OPTION_IDX_SUBNET_MASK, - DHCP_OPTION_IDX_ROUTER, -#if LWIP_DHCP_PROVIDE_DNS_SERVERS - DHCP_OPTION_IDX_DNS_SERVER, - DHCP_OPTION_IDX_DNS_SERVER_LAST = DHCP_OPTION_IDX_DNS_SERVER + LWIP_DHCP_PROVIDE_DNS_SERVERS - 1, -#endif /* LWIP_DHCP_PROVIDE_DNS_SERVERS */ -#if LWIP_DHCP_GET_NTP_SRV - DHCP_OPTION_IDX_NTP_SERVER, - DHCP_OPTION_IDX_NTP_SERVER_LAST = DHCP_OPTION_IDX_NTP_SERVER + LWIP_DHCP_MAX_NTP_SERVERS - 1, -#endif /* LWIP_DHCP_GET_NTP_SRV */ - DHCP_OPTION_IDX_MAX -}; - -/** Holds the decoded option values, only valid while in dhcp_recv. - @todo: move this into struct dhcp? */ -u32_t dhcp_rx_options_val[DHCP_OPTION_IDX_MAX]; -/** Holds a flag which option was received and is contained in dhcp_rx_options_val, - only valid while in dhcp_recv. - @todo: move this into struct dhcp? */ -u8_t dhcp_rx_options_given[DHCP_OPTION_IDX_MAX]; - -static u8_t dhcp_discover_request_options[] = { - DHCP_OPTION_SUBNET_MASK, - DHCP_OPTION_ROUTER, - DHCP_OPTION_BROADCAST -#if LWIP_DHCP_PROVIDE_DNS_SERVERS - , DHCP_OPTION_DNS_SERVER -#endif /* LWIP_DHCP_PROVIDE_DNS_SERVERS */ -#if LWIP_DHCP_GET_NTP_SRV - , DHCP_OPTION_NTP -#endif /* LWIP_DHCP_GET_NTP_SRV */ - }; - -#ifdef DHCP_GLOBAL_XID -static u32_t xid; -static u8_t xid_initialised; -#endif /* DHCP_GLOBAL_XID */ - -#define dhcp_option_given(dhcp, idx) (dhcp_rx_options_given[idx] != 0) -#define dhcp_got_option(dhcp, idx) (dhcp_rx_options_given[idx] = 1) -#define dhcp_clear_option(dhcp, idx) (dhcp_rx_options_given[idx] = 0) -#define dhcp_clear_all_options(dhcp) (memset(dhcp_rx_options_given, 0, sizeof(dhcp_rx_options_given))) -#define dhcp_get_option_value(dhcp, idx) (dhcp_rx_options_val[idx]) -#define dhcp_set_option_value(dhcp, idx, val) (dhcp_rx_options_val[idx] = (val)) - -static struct udp_pcb *dhcp_pcb; -static u8_t dhcp_pcb_refcount; - -/* DHCP client state machine functions */ -static err_t dhcp_discover(struct netif *netif); -static err_t dhcp_select(struct netif *netif); -static void dhcp_bind(struct netif *netif); -#if DHCP_DOES_ARP_CHECK -static err_t dhcp_decline(struct netif *netif); -#endif /* DHCP_DOES_ARP_CHECK */ -static err_t dhcp_rebind(struct netif *netif); -static err_t dhcp_reboot(struct netif *netif); -static void dhcp_set_state(struct dhcp *dhcp, u8_t new_state); - -/* receive, unfold, parse and free incoming messages */ -static void dhcp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port); - -/* set the DHCP timers */ -static void dhcp_timeout(struct netif *netif); -static void dhcp_t1_timeout(struct netif *netif); -static void dhcp_t2_timeout(struct netif *netif); - -/* build outgoing messages */ -/* create a DHCP message, fill in common headers */ -static err_t dhcp_create_msg(struct netif *netif, struct dhcp *dhcp, u8_t message_type); -/* free a DHCP request */ -static void dhcp_delete_msg(struct dhcp *dhcp); -/* add a DHCP option (type, then length in bytes) */ -static void dhcp_option(struct dhcp *dhcp, u8_t option_type, u8_t option_len); -/* add option values */ -static void dhcp_option_byte(struct dhcp *dhcp, u8_t value); -static void dhcp_option_short(struct dhcp *dhcp, u16_t value); -static void dhcp_option_long(struct dhcp *dhcp, u32_t value); -#if LWIP_NETIF_HOSTNAME -static void dhcp_option_hostname(struct dhcp *dhcp, struct netif *netif); -#endif /* LWIP_NETIF_HOSTNAME */ -/* always add the DHCP options trailer to end and pad */ -static void dhcp_option_trailer(struct dhcp *dhcp); - -/** Ensure DHCP PCB is allocated and bound */ -static err_t -dhcp_inc_pcb_refcount(void) -{ - if (dhcp_pcb_refcount == 0) { - LWIP_ASSERT("dhcp_inc_pcb_refcount(): memory leak", dhcp_pcb == NULL); - - /* allocate UDP PCB */ - dhcp_pcb = udp_new(); - - if (dhcp_pcb == NULL) { - return ERR_MEM; - } - - ip_set_option(dhcp_pcb, SOF_BROADCAST); - - /* set up local and remote port for the pcb -> listen on all interfaces on all src/dest IPs */ - udp_bind(dhcp_pcb, IP4_ADDR_ANY, DHCP_CLIENT_PORT); - udp_connect(dhcp_pcb, IP4_ADDR_ANY, DHCP_SERVER_PORT); - udp_recv(dhcp_pcb, dhcp_recv, NULL); - } - - dhcp_pcb_refcount++; - - return ERR_OK; -} - -/** Free DHCP PCB if the last netif stops using it */ -static void -dhcp_dec_pcb_refcount(void) -{ - LWIP_ASSERT("dhcp_pcb_refcount(): refcount error", (dhcp_pcb_refcount > 0)); - dhcp_pcb_refcount--; - - if (dhcp_pcb_refcount == 0) { - udp_remove(dhcp_pcb); - dhcp_pcb = NULL; - } -} - -/** - * Back-off the DHCP client (because of a received NAK response). - * - * Back-off the DHCP client because of a received NAK. Receiving a - * NAK means the client asked for something non-sensible, for - * example when it tries to renew a lease obtained on another network. - * - * We clear any existing set IP address and restart DHCP negotiation - * afresh (as per RFC2131 3.2.3). - * - * @param netif the netif under DHCP control - */ -static void -dhcp_handle_nak(struct netif *netif) -{ - struct dhcp *dhcp = netif_dhcp_data(netif); - - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_handle_nak(netif=%p) %c%c%"U16_F"\n", - (void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num)); - /* Change to a defined state - set this before assigning the address - to ensure the callback can use dhcp_supplied_address() */ - dhcp_set_state(dhcp, DHCP_STATE_BACKING_OFF); - /* remove IP address from interface (must no longer be used, as per RFC2131) */ - netif_set_addr(netif, IP4_ADDR_ANY4, IP4_ADDR_ANY4, IP4_ADDR_ANY4); - /* We can immediately restart discovery */ - dhcp_discover(netif); -} - -#if DHCP_DOES_ARP_CHECK -/** - * Checks if the offered IP address is already in use. - * - * It does so by sending an ARP request for the offered address and - * entering CHECKING state. If no ARP reply is received within a small - * interval, the address is assumed to be free for use by us. - * - * @param netif the netif under DHCP control - */ -static void -dhcp_check(struct netif *netif) -{ - struct dhcp *dhcp = netif_dhcp_data(netif); - err_t result; - u16_t msecs; - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_check(netif=%p) %c%c\n", (void *)netif, (s16_t)netif->name[0], - (s16_t)netif->name[1])); - dhcp_set_state(dhcp, DHCP_STATE_CHECKING); - /* create an ARP query for the offered IP address, expecting that no host - responds, as the IP address should not be in use. */ - result = etharp_query(netif, &dhcp->offered_ip_addr, NULL); - if (result != ERR_OK) { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("dhcp_check: could not perform ARP query\n")); - } - if (dhcp->tries < 255) { - dhcp->tries++; - } - msecs = 500; - dhcp->request_timeout = (u16_t)((msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS); - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_check(): set request timeout %"U16_F" msecs\n", msecs)); -} -#endif /* DHCP_DOES_ARP_CHECK */ - -/** - * Remember the configuration offered by a DHCP server. - * - * @param netif the netif under DHCP control - */ -static void -dhcp_handle_offer(struct netif *netif) -{ - struct dhcp *dhcp = netif_dhcp_data(netif); - - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_handle_offer(netif=%p) %c%c%"U16_F"\n", - (void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num)); - /* obtain the server address */ - if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_SERVER_ID)) { - ip_addr_set_ip4_u32(&dhcp->server_ip_addr, lwip_htonl(dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_SERVER_ID))); - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_handle_offer(): server 0x%08"X32_F"\n", - ip4_addr_get_u32(ip_2_ip4(&dhcp->server_ip_addr)))); - /* remember offered address */ - ip4_addr_copy(dhcp->offered_ip_addr, dhcp->msg_in->yiaddr); - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_handle_offer(): offer for 0x%08"X32_F"\n", - ip4_addr_get_u32(&dhcp->offered_ip_addr))); - - dhcp_select(netif); - } else { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, - ("dhcp_handle_offer(netif=%p) did not get server ID!\n", (void*)netif)); - } -} - -/** - * Select a DHCP server offer out of all offers. - * - * Simply select the first offer received. - * - * @param netif the netif under DHCP control - * @return lwIP specific error (see error.h) - */ -static err_t -dhcp_select(struct netif *netif) -{ - struct dhcp *dhcp = netif_dhcp_data(netif); - err_t result; - u16_t msecs; - u8_t i; - - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_select(netif=%p) %c%c%"U16_F"\n", (void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num)); - dhcp_set_state(dhcp, DHCP_STATE_REQUESTING); - - /* create and initialize the DHCP message header */ - result = dhcp_create_msg(netif, dhcp, DHCP_REQUEST); - if (result == ERR_OK) { - dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN); - dhcp_option_short(dhcp, DHCP_MAX_MSG_LEN(netif)); - - /* MUST request the offered IP address */ - dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4); - dhcp_option_long(dhcp, lwip_ntohl(ip4_addr_get_u32(&dhcp->offered_ip_addr))); - - dhcp_option(dhcp, DHCP_OPTION_SERVER_ID, 4); - dhcp_option_long(dhcp, lwip_ntohl(ip4_addr_get_u32(ip_2_ip4(&dhcp->server_ip_addr)))); - - dhcp_option(dhcp, DHCP_OPTION_PARAMETER_REQUEST_LIST, LWIP_ARRAYSIZE(dhcp_discover_request_options)); - for (i = 0; i < LWIP_ARRAYSIZE(dhcp_discover_request_options); i++) { - dhcp_option_byte(dhcp, dhcp_discover_request_options[i]); - } - -#if LWIP_NETIF_HOSTNAME - dhcp_option_hostname(dhcp, netif); -#endif /* LWIP_NETIF_HOSTNAME */ - - dhcp_option_trailer(dhcp); - - /* send broadcast to any DHCP server */ - udp_sendto_if_src(dhcp_pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT, netif, IP4_ADDR_ANY); - dhcp_delete_msg(dhcp); - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_select: REQUESTING\n")); - } else { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("dhcp_select: could not allocate DHCP request\n")); - } - if (dhcp->tries < 255) { - dhcp->tries++; - } - msecs = (u16_t)((dhcp->tries < 6 ? 1 << dhcp->tries : 60) * 1000); - dhcp->request_timeout = (u16_t)((msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS); - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_select(): set request timeout %"U16_F" msecs\n", msecs)); - return result; -} - -/** - * The DHCP timer that checks for lease renewal/rebind timeouts. - * Must be called once a minute (see @ref DHCP_COARSE_TIMER_SECS). - */ -void -dhcp_coarse_tmr(void) -{ - struct netif *netif = netif_list; - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_coarse_tmr()\n")); - /* iterate through all network interfaces */ - while (netif != NULL) { - /* only act on DHCP configured interfaces */ - struct dhcp *dhcp = netif_dhcp_data(netif); - if ((dhcp != NULL) && (dhcp->state != DHCP_STATE_OFF)) { - /* compare lease time to expire timeout */ - if (dhcp->t0_timeout && (++dhcp->lease_used == dhcp->t0_timeout)) { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_coarse_tmr(): t0 timeout\n")); - /* this clients' lease time has expired */ - dhcp_release(netif); - dhcp_discover(netif); - /* timer is active (non zero), and triggers (zeroes) now? */ - } else if (dhcp->t2_rebind_time && (dhcp->t2_rebind_time-- == 1)) { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_coarse_tmr(): t2 timeout\n")); - /* this clients' rebind timeout triggered */ - dhcp_t2_timeout(netif); - /* timer is active (non zero), and triggers (zeroes) now */ - } else if (dhcp->t1_renew_time && (dhcp->t1_renew_time-- == 1)) { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_coarse_tmr(): t1 timeout\n")); - /* this clients' renewal timeout triggered */ - dhcp_t1_timeout(netif); - } - } - /* proceed to next netif */ - netif = netif->next; - } -} - -/** - * DHCP transaction timeout handling (this function must be called every 500ms, - * see @ref DHCP_FINE_TIMER_MSECS). - * - * A DHCP server is expected to respond within a short period of time. - * This timer checks whether an outstanding DHCP request is timed out. - */ -void -dhcp_fine_tmr(void) -{ - struct netif *netif = netif_list; - /* loop through netif's */ - while (netif != NULL) { - struct dhcp *dhcp = netif_dhcp_data(netif); - /* only act on DHCP configured interfaces */ - if (dhcp != NULL) { - /* timer is active (non zero), and is about to trigger now */ - if (dhcp->request_timeout > 1) { - dhcp->request_timeout--; - } - else if (dhcp->request_timeout == 1) { - dhcp->request_timeout--; - /* { netif->dhcp->request_timeout == 0 } */ - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_fine_tmr(): request timeout\n")); - /* this client's request timeout triggered */ - dhcp_timeout(netif); - } - } - /* proceed to next network interface */ - netif = netif->next; - } -} - -/** - * A DHCP negotiation transaction, or ARP request, has timed out. - * - * The timer that was started with the DHCP or ARP request has - * timed out, indicating no response was received in time. - * - * @param netif the netif under DHCP control - */ -static void -dhcp_timeout(struct netif *netif) -{ - struct dhcp *dhcp = netif_dhcp_data(netif); - - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_timeout()\n")); - /* back-off period has passed, or server selection timed out */ - if ((dhcp->state == DHCP_STATE_BACKING_OFF) || (dhcp->state == DHCP_STATE_SELECTING)) { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_timeout(): restarting discovery\n")); - dhcp_discover(netif); - /* receiving the requested lease timed out */ - } else if (dhcp->state == DHCP_STATE_REQUESTING) { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): REQUESTING, DHCP request timed out\n")); - if (dhcp->tries <= 5) { - dhcp_select(netif); - } else { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): REQUESTING, releasing, restarting\n")); - dhcp_release(netif); - dhcp_discover(netif); - } -#if DHCP_DOES_ARP_CHECK - /* received no ARP reply for the offered address (which is good) */ - } else if (dhcp->state == DHCP_STATE_CHECKING) { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_timeout(): CHECKING, ARP request timed out\n")); - if (dhcp->tries <= 1) { - dhcp_check(netif); - /* no ARP replies on the offered address, - looks like the IP address is indeed free */ - } else { - /* bind the interface to the offered address */ - dhcp_bind(netif); - } -#endif /* DHCP_DOES_ARP_CHECK */ - } else if (dhcp->state == DHCP_STATE_REBOOTING) { - if (dhcp->tries < REBOOT_TRIES) { - dhcp_reboot(netif); - } else { - dhcp_discover(netif); - } - } -} - -/** - * The renewal period has timed out. - * - * @param netif the netif under DHCP control - */ -static void -dhcp_t1_timeout(struct netif *netif) -{ - struct dhcp *dhcp = netif_dhcp_data(netif); - - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_t1_timeout()\n")); - if ((dhcp->state == DHCP_STATE_REQUESTING) || (dhcp->state == DHCP_STATE_BOUND) || - (dhcp->state == DHCP_STATE_RENEWING)) { - /* just retry to renew - note that the rebind timer (t2) will - * eventually time-out if renew tries fail. */ - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, - ("dhcp_t1_timeout(): must renew\n")); - /* This slightly different to RFC2131: DHCPREQUEST will be sent from state - DHCP_STATE_RENEWING, not DHCP_STATE_BOUND */ - dhcp_renew(netif); - /* Calculate next timeout */ - if (((dhcp->t2_timeout - dhcp->lease_used) / 2) >= ((60 + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS)) - { - dhcp->t1_renew_time = (u16_t)((dhcp->t2_timeout - dhcp->lease_used) / 2); - } - } -} - -/** - * The rebind period has timed out. - * - * @param netif the netif under DHCP control - */ -static void -dhcp_t2_timeout(struct netif *netif) -{ - struct dhcp *dhcp = netif_dhcp_data(netif); - - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_t2_timeout()\n")); - if ((dhcp->state == DHCP_STATE_REQUESTING) || (dhcp->state == DHCP_STATE_BOUND) || - (dhcp->state == DHCP_STATE_RENEWING) || (dhcp->state == DHCP_STATE_REBINDING)) { - /* just retry to rebind */ - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, - ("dhcp_t2_timeout(): must rebind\n")); - /* This slightly different to RFC2131: DHCPREQUEST will be sent from state - DHCP_STATE_REBINDING, not DHCP_STATE_BOUND */ - dhcp_rebind(netif); - /* Calculate next timeout */ - if (((dhcp->t0_timeout - dhcp->lease_used) / 2) >= ((60 + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS)) - { - dhcp->t2_rebind_time = (u16_t)((dhcp->t0_timeout - dhcp->lease_used) / 2); - } - } -} - -/** - * Handle a DHCP ACK packet - * - * @param netif the netif under DHCP control - */ -static void -dhcp_handle_ack(struct netif *netif) -{ - struct dhcp *dhcp = netif_dhcp_data(netif); - -#if LWIP_DHCP_PROVIDE_DNS_SERVERS || LWIP_DHCP_GET_NTP_SRV - u8_t n; -#endif /* LWIP_DHCP_PROVIDE_DNS_SERVERS || LWIP_DHCP_GET_NTP_SRV */ -#if LWIP_DHCP_GET_NTP_SRV - ip4_addr_t ntp_server_addrs[LWIP_DHCP_MAX_NTP_SERVERS]; -#endif - - /* clear options we might not get from the ACK */ - ip4_addr_set_zero(&dhcp->offered_sn_mask); - ip4_addr_set_zero(&dhcp->offered_gw_addr); -#if LWIP_DHCP_BOOTP_FILE - ip4_addr_set_zero(&dhcp->offered_si_addr); -#endif /* LWIP_DHCP_BOOTP_FILE */ - - /* lease time given? */ - if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_LEASE_TIME)) { - /* remember offered lease time */ - dhcp->offered_t0_lease = dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_LEASE_TIME); - } - /* renewal period given? */ - if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_T1)) { - /* remember given renewal period */ - dhcp->offered_t1_renew = dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_T1); - } else { - /* calculate safe periods for renewal */ - dhcp->offered_t1_renew = dhcp->offered_t0_lease / 2; - } - - /* renewal period given? */ - if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_T2)) { - /* remember given rebind period */ - dhcp->offered_t2_rebind = dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_T2); - } else { - /* calculate safe periods for rebinding (offered_t0_lease * 0.875 -> 87.5%)*/ - dhcp->offered_t2_rebind = (dhcp->offered_t0_lease * 7U) / 8U; - } - - /* (y)our internet address */ - ip4_addr_copy(dhcp->offered_ip_addr, dhcp->msg_in->yiaddr); - -#if LWIP_DHCP_BOOTP_FILE - /* copy boot server address, - boot file name copied in dhcp_parse_reply if not overloaded */ - ip4_addr_copy(dhcp->offered_si_addr, dhcp->msg_in->siaddr); -#endif /* LWIP_DHCP_BOOTP_FILE */ - - /* subnet mask given? */ - if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_SUBNET_MASK)) { - /* remember given subnet mask */ - ip4_addr_set_u32(&dhcp->offered_sn_mask, lwip_htonl(dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_SUBNET_MASK))); - dhcp->subnet_mask_given = 1; - } else { - dhcp->subnet_mask_given = 0; - } - - /* gateway router */ - if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_ROUTER)) { - ip4_addr_set_u32(&dhcp->offered_gw_addr, lwip_htonl(dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_ROUTER))); - } - -#if LWIP_DHCP_GET_NTP_SRV - /* NTP servers */ - for (n = 0; (n < LWIP_DHCP_MAX_NTP_SERVERS) && dhcp_option_given(dhcp, DHCP_OPTION_IDX_NTP_SERVER + n); n++) { - ip4_addr_set_u32(&ntp_server_addrs[n], lwip_htonl(dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_NTP_SERVER + n))); - } - dhcp_set_ntp_servers(n, ntp_server_addrs); -#endif /* LWIP_DHCP_GET_NTP_SRV */ - -#if LWIP_DHCP_PROVIDE_DNS_SERVERS - /* DNS servers */ - for (n = 0; (n < LWIP_DHCP_PROVIDE_DNS_SERVERS) && dhcp_option_given(dhcp, DHCP_OPTION_IDX_DNS_SERVER + n); n++) { - ip_addr_t dns_addr; - ip_addr_set_ip4_u32(&dns_addr, lwip_htonl(dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_DNS_SERVER + n))); - dns_setserver(n, &dns_addr); - } -#endif /* LWIP_DHCP_PROVIDE_DNS_SERVERS */ -} - -/** - * @ingroup dhcp4 - * Set a statically allocated struct dhcp to work with. - * Using this prevents dhcp_start to allocate it using mem_malloc. - * - * @param netif the netif for which to set the struct dhcp - * @param dhcp (uninitialised) dhcp struct allocated by the application - */ -void -dhcp_set_struct(struct netif *netif, struct dhcp *dhcp) -{ - LWIP_ASSERT_CORE_LOCKED(); - LWIP_ASSERT("netif != NULL", netif != NULL); - LWIP_ASSERT("dhcp != NULL", dhcp != NULL); - LWIP_ASSERT("netif already has a struct dhcp set", netif_dhcp_data(netif) == NULL); - - /* clear data structure */ - memset(dhcp, 0, sizeof(struct dhcp)); - /* dhcp_set_state(&dhcp, DHCP_STATE_OFF); */ - netif_set_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_DHCP, dhcp); -} - -/** - * @ingroup dhcp4 - * Removes a struct dhcp from a netif. - * - * ATTENTION: Only use this when not using dhcp_set_struct() to allocate the - * struct dhcp since the memory is passed back to the heap. - * - * @param netif the netif from which to remove the struct dhcp - */ -void dhcp_cleanup(struct netif *netif) -{ - LWIP_ASSERT_CORE_LOCKED(); - LWIP_ASSERT("netif != NULL", netif != NULL); - - if (netif_dhcp_data(netif) != NULL) { - mem_free(netif_dhcp_data(netif)); - netif_set_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_DHCP, NULL); - } -} - -/** - * @ingroup dhcp4 - * Start DHCP negotiation for a network interface. - * - * If no DHCP client instance was attached to this interface, - * a new client is created first. If a DHCP client instance - * was already present, it restarts negotiation. - * - * @param netif The lwIP network interface - * @return lwIP error code - * - ERR_OK - No error - * - ERR_MEM - Out of memory - */ -err_t -dhcp_start(struct netif *netif) -{ - struct dhcp *dhcp; - err_t result; - - LWIP_ASSERT_CORE_LOCKED(); - LWIP_ERROR("netif != NULL", (netif != NULL), return ERR_ARG;); - LWIP_ERROR("netif is not up, old style port?", netif_is_up(netif), return ERR_ARG;); - dhcp = netif_dhcp_data(netif); - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_start(netif=%p) %c%c%"U16_F"\n", (void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num)); - - /* check MTU of the netif */ - if (netif->mtu < DHCP_MAX_MSG_LEN_MIN_REQUIRED) { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): Cannot use this netif with DHCP: MTU is too small\n")); - return ERR_MEM; - } - - /* no DHCP client attached yet? */ - if (dhcp == NULL) { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): mallocing new DHCP client\n")); - dhcp = (struct dhcp *)mem_malloc(sizeof(struct dhcp)); - if (dhcp == NULL) { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): could not allocate dhcp\n")); - return ERR_MEM; - } - - /* store this dhcp client in the netif */ - netif_set_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_DHCP, dhcp); - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): allocated dhcp")); - /* already has DHCP client attached */ - } else { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_start(): restarting DHCP configuration\n")); - LWIP_ASSERT("pbuf p_out wasn't freed", dhcp->p_out == NULL); - LWIP_ASSERT("reply wasn't freed", dhcp->msg_in == NULL ); - - if (dhcp->pcb_allocated != 0) { - dhcp_dec_pcb_refcount(); /* free DHCP PCB if not needed any more */ - } - /* dhcp is cleared below, no need to reset flag*/ - } - - /* clear data structure */ - memset(dhcp, 0, sizeof(struct dhcp)); - /* dhcp_set_state(&dhcp, DHCP_STATE_OFF); */ - - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_start(): starting DHCP configuration\n")); - - if (dhcp_inc_pcb_refcount() != ERR_OK) { /* ensure DHCP PCB is allocated */ - return ERR_MEM; - } - dhcp->pcb_allocated = 1; - -#if LWIP_DHCP_CHECK_LINK_UP - if (!netif_is_link_up(netif)) { - /* set state INIT and wait for dhcp_network_changed() to call dhcp_discover() */ - dhcp_set_state(dhcp, DHCP_STATE_INIT); - return ERR_OK; - } -#endif /* LWIP_DHCP_CHECK_LINK_UP */ - - - /* (re)start the DHCP negotiation */ - result = dhcp_discover(netif); - if (result != ERR_OK) { - /* free resources allocated above */ - dhcp_stop(netif); - return ERR_MEM; - } - return result; -} - -/** - * @ingroup dhcp4 - * Inform a DHCP server of our manual configuration. - * - * This informs DHCP servers of our fixed IP address configuration - * by sending an INFORM message. It does not involve DHCP address - * configuration, it is just here to be nice to the network. - * - * @param netif The lwIP network interface - */ -void -dhcp_inform(struct netif *netif) -{ - struct dhcp dhcp; - err_t result = ERR_OK; - - LWIP_ASSERT_CORE_LOCKED(); - LWIP_ERROR("netif != NULL", (netif != NULL), return;); - - if (dhcp_inc_pcb_refcount() != ERR_OK) { /* ensure DHCP PCB is allocated */ - return; - } - - memset(&dhcp, 0, sizeof(struct dhcp)); - dhcp_set_state(&dhcp, DHCP_STATE_INFORMING); - - /* create and initialize the DHCP message header */ - result = dhcp_create_msg(netif, &dhcp, DHCP_INFORM); - if (result == ERR_OK) { - dhcp_option(&dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN); - dhcp_option_short(&dhcp, DHCP_MAX_MSG_LEN(netif)); - - dhcp_option_trailer(&dhcp); - - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_inform: INFORMING\n")); - - udp_sendto_if(dhcp_pcb, dhcp.p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT, netif); - - dhcp_delete_msg(&dhcp); - } else { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_inform: could not allocate DHCP request\n")); - } - - dhcp_dec_pcb_refcount(); /* delete DHCP PCB if not needed any more */ -} - -/** Handle a possible change in the network configuration. - * - * This enters the REBOOTING state to verify that the currently bound - * address is still valid. - */ -void -dhcp_network_changed(struct netif *netif) -{ - struct dhcp *dhcp = netif_dhcp_data(netif); - - if (!dhcp) - return; - switch (dhcp->state) { - case DHCP_STATE_REBINDING: - case DHCP_STATE_RENEWING: - case DHCP_STATE_BOUND: - case DHCP_STATE_REBOOTING: - dhcp->tries = 0; - dhcp_reboot(netif); - break; - case DHCP_STATE_OFF: - /* stay off */ - break; - default: - /* INIT/REQUESTING/CHECKING/BACKING_OFF restart with new 'rid' because the - state changes, SELECTING: continue with current 'rid' as we stay in the - same state */ -#if LWIP_DHCP_AUTOIP_COOP - if (dhcp->autoip_coop_state == DHCP_AUTOIP_COOP_STATE_ON) { - autoip_stop(netif); - dhcp->autoip_coop_state = DHCP_AUTOIP_COOP_STATE_OFF; - } -#endif /* LWIP_DHCP_AUTOIP_COOP */ - /* ensure we start with short timeouts, even if already discovering */ - dhcp->tries = 0; - dhcp_discover(netif); - break; - } -} - -#if DHCP_DOES_ARP_CHECK -/** - * Match an ARP reply with the offered IP address: - * check whether the offered IP address is not in use using ARP - * - * @param netif the network interface on which the reply was received - * @param addr The IP address we received a reply from - */ -void -dhcp_arp_reply(struct netif *netif, const ip4_addr_t *addr) -{ - struct dhcp *dhcp; - - LWIP_ERROR("netif != NULL", (netif != NULL), return;); - dhcp = netif_dhcp_data(netif); - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_arp_reply()\n")); - /* is a DHCP client doing an ARP check? */ - if ((dhcp != NULL) && (dhcp->state == DHCP_STATE_CHECKING)) { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_arp_reply(): CHECKING, arp reply for 0x%08"X32_F"\n", - ip4_addr_get_u32(addr))); - /* did a host respond with the address we - were offered by the DHCP server? */ - if (ip4_addr_cmp(addr, &dhcp->offered_ip_addr)) { - /* we will not accept the offered address */ - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE | LWIP_DBG_LEVEL_WARNING, - ("dhcp_arp_reply(): arp reply matched with offered address, declining\n")); - dhcp_decline(netif); - } - } -} - -/** - * Decline an offered lease. - * - * Tell the DHCP server we do not accept the offered address. - * One reason to decline the lease is when we find out the address - * is already in use by another host (through ARP). - * - * @param netif the netif under DHCP control - */ -static err_t -dhcp_decline(struct netif *netif) -{ - struct dhcp *dhcp = netif_dhcp_data(netif); - err_t result = ERR_OK; - u16_t msecs; - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_decline()\n")); - dhcp_set_state(dhcp, DHCP_STATE_BACKING_OFF); - /* create and initialize the DHCP message header */ - result = dhcp_create_msg(netif, dhcp, DHCP_DECLINE); - if (result == ERR_OK) { - dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4); - dhcp_option_long(dhcp, lwip_ntohl(ip4_addr_get_u32(&dhcp->offered_ip_addr))); - - dhcp_option_trailer(dhcp); - - /* per section 4.4.4, broadcast DECLINE messages */ - udp_sendto_if_src(dhcp_pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT, netif, IP4_ADDR_ANY); - dhcp_delete_msg(dhcp); - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_decline: BACKING OFF\n")); - } else { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, - ("dhcp_decline: could not allocate DHCP request\n")); - } - if (dhcp->tries < 255) { - dhcp->tries++; - } - msecs = 10*1000; - dhcp->request_timeout = (u16_t)((msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS); - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_decline(): set request timeout %"U16_F" msecs\n", msecs)); - return result; -} -#endif /* DHCP_DOES_ARP_CHECK */ - - -/** - * Start the DHCP process, discover a DHCP server. - * - * @param netif the netif under DHCP control - */ -static err_t -dhcp_discover(struct netif *netif) -{ - struct dhcp *dhcp = netif_dhcp_data(netif); - err_t result = ERR_OK; - u16_t msecs; - u8_t i; - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover()\n")); - ip4_addr_set_any(&dhcp->offered_ip_addr); - dhcp_set_state(dhcp, DHCP_STATE_SELECTING); - /* create and initialize the DHCP message header */ - result = dhcp_create_msg(netif, dhcp, DHCP_DISCOVER); - if (result == ERR_OK) { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover: making request\n")); - - dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN); - dhcp_option_short(dhcp, DHCP_MAX_MSG_LEN(netif)); - - dhcp_option(dhcp, DHCP_OPTION_PARAMETER_REQUEST_LIST, LWIP_ARRAYSIZE(dhcp_discover_request_options)); - for (i = 0; i < LWIP_ARRAYSIZE(dhcp_discover_request_options); i++) { - dhcp_option_byte(dhcp, dhcp_discover_request_options[i]); - } - dhcp_option_trailer(dhcp); - - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover: sendto(DISCOVER, IP_ADDR_BROADCAST, DHCP_SERVER_PORT)\n")); - udp_sendto_if_src(dhcp_pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT, netif, IP4_ADDR_ANY); - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_discover: deleting()ing\n")); - dhcp_delete_msg(dhcp); - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_discover: SELECTING\n")); - } else { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_discover: could not allocate DHCP request\n")); - } - if (dhcp->tries < 255) { - dhcp->tries++; - } -#if LWIP_DHCP_AUTOIP_COOP - if (dhcp->tries >= LWIP_DHCP_AUTOIP_COOP_TRIES && dhcp->autoip_coop_state == DHCP_AUTOIP_COOP_STATE_OFF) { - dhcp->autoip_coop_state = DHCP_AUTOIP_COOP_STATE_ON; - autoip_start(netif); - } -#endif /* LWIP_DHCP_AUTOIP_COOP */ - msecs = (u16_t)((dhcp->tries < 6 ? 1 << dhcp->tries : 60) * 1000); - dhcp->request_timeout = (u16_t)((msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS); - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_discover(): set request timeout %"U16_F" msecs\n", msecs)); - return result; -} - - -/** - * Bind the interface to the offered IP address. - * - * @param netif network interface to bind to the offered address - */ -static void -dhcp_bind(struct netif *netif) -{ - u32_t timeout; - struct dhcp *dhcp; - ip4_addr_t sn_mask, gw_addr; - LWIP_ERROR("dhcp_bind: netif != NULL", (netif != NULL), return;); - dhcp = netif_dhcp_data(netif); - LWIP_ERROR("dhcp_bind: dhcp != NULL", (dhcp != NULL), return;); - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_bind(netif=%p) %c%c%"U16_F"\n", (void*)netif, netif->name[0], netif->name[1], (u16_t)netif->num)); - - /* reset time used of lease */ - dhcp->lease_used = 0; - - if (dhcp->offered_t0_lease != 0xffffffffUL) { - /* set renewal period timer */ - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_bind(): t0 renewal timer %"U32_F" secs\n", dhcp->offered_t0_lease)); - timeout = (dhcp->offered_t0_lease + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS; - if (timeout > 0xffff) { - timeout = 0xffff; - } - dhcp->t0_timeout = (u16_t)timeout; - if (dhcp->t0_timeout == 0) { - dhcp->t0_timeout = 1; - } - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_bind(): set request timeout %"U32_F" msecs\n", dhcp->offered_t0_lease*1000)); - } - - /* temporary DHCP lease? */ - if (dhcp->offered_t1_renew != 0xffffffffUL) { - /* set renewal period timer */ - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_bind(): t1 renewal timer %"U32_F" secs\n", dhcp->offered_t1_renew)); - timeout = (dhcp->offered_t1_renew + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS; - if (timeout > 0xffff) { - timeout = 0xffff; - } - dhcp->t1_timeout = (u16_t)timeout; - if (dhcp->t1_timeout == 0) { - dhcp->t1_timeout = 1; - } - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_bind(): set request timeout %"U32_F" msecs\n", dhcp->offered_t1_renew*1000)); - dhcp->t1_renew_time = dhcp->t1_timeout; - } - /* set renewal period timer */ - if (dhcp->offered_t2_rebind != 0xffffffffUL) { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_bind(): t2 rebind timer %"U32_F" secs\n", dhcp->offered_t2_rebind)); - timeout = (dhcp->offered_t2_rebind + DHCP_COARSE_TIMER_SECS / 2) / DHCP_COARSE_TIMER_SECS; - if (timeout > 0xffff) { - timeout = 0xffff; - } - dhcp->t2_timeout = (u16_t)timeout; - if (dhcp->t2_timeout == 0) { - dhcp->t2_timeout = 1; - } - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_bind(): set request timeout %"U32_F" msecs\n", dhcp->offered_t2_rebind*1000)); - dhcp->t2_rebind_time = dhcp->t2_timeout; - } - - /* If we have sub 1 minute lease, t2 and t1 will kick in at the same time. */ - if ((dhcp->t1_timeout >= dhcp->t2_timeout) && (dhcp->t2_timeout > 0)) { - dhcp->t1_timeout = 0; - } - - if (dhcp->subnet_mask_given) { - /* copy offered network mask */ - ip4_addr_copy(sn_mask, dhcp->offered_sn_mask); - } else { - /* subnet mask not given, choose a safe subnet mask given the network class */ - u8_t first_octet = ip4_addr1(&dhcp->offered_ip_addr); - if (first_octet <= 127) { - ip4_addr_set_u32(&sn_mask, PP_HTONL(0xff000000UL)); - } else if (first_octet >= 192) { - ip4_addr_set_u32(&sn_mask, PP_HTONL(0xffffff00UL)); - } else { - ip4_addr_set_u32(&sn_mask, PP_HTONL(0xffff0000UL)); - } - } - - ip4_addr_copy(gw_addr, dhcp->offered_gw_addr); - /* gateway address not given? */ - if (ip4_addr_isany_val(gw_addr)) { - /* copy network address */ - ip4_addr_get_network(&gw_addr, &dhcp->offered_ip_addr, &sn_mask); - /* use first host address on network as gateway */ - ip4_addr_set_u32(&gw_addr, ip4_addr_get_u32(&gw_addr) | PP_HTONL(0x00000001UL)); - } - -#if LWIP_DHCP_AUTOIP_COOP - if (dhcp->autoip_coop_state == DHCP_AUTOIP_COOP_STATE_ON) { - autoip_stop(netif); - dhcp->autoip_coop_state = DHCP_AUTOIP_COOP_STATE_OFF; - } -#endif /* LWIP_DHCP_AUTOIP_COOP */ - - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_STATE, ("dhcp_bind(): IP: 0x%08"X32_F" SN: 0x%08"X32_F" GW: 0x%08"X32_F"\n", - ip4_addr_get_u32(&dhcp->offered_ip_addr), ip4_addr_get_u32(&sn_mask), ip4_addr_get_u32(&gw_addr))); - /* netif is now bound to DHCP leased address - set this before assigning the address - to ensure the callback can use dhcp_supplied_address() */ - dhcp_set_state(dhcp, DHCP_STATE_BOUND); - - netif_set_addr(netif, &dhcp->offered_ip_addr, &sn_mask, &gw_addr); - /* interface is used by routing now that an address is set */ -} - -/** - * @ingroup dhcp4 - * Renew an existing DHCP lease at the involved DHCP server. - * - * @param netif network interface which must renew its lease - */ -err_t -dhcp_renew(struct netif *netif) -{ - struct dhcp *dhcp = netif_dhcp_data(netif); - err_t result; - u16_t msecs; - u8_t i; - - LWIP_ASSERT_CORE_LOCKED(); - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_renew()\n")); - dhcp_set_state(dhcp, DHCP_STATE_RENEWING); - - /* create and initialize the DHCP message header */ - result = dhcp_create_msg(netif, dhcp, DHCP_REQUEST); - if (result == ERR_OK) { - dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN); - dhcp_option_short(dhcp, DHCP_MAX_MSG_LEN(netif)); - - dhcp_option(dhcp, DHCP_OPTION_PARAMETER_REQUEST_LIST, LWIP_ARRAYSIZE(dhcp_discover_request_options)); - for (i = 0; i < LWIP_ARRAYSIZE(dhcp_discover_request_options); i++) { - dhcp_option_byte(dhcp, dhcp_discover_request_options[i]); - } - -#if LWIP_NETIF_HOSTNAME - dhcp_option_hostname(dhcp, netif); -#endif /* LWIP_NETIF_HOSTNAME */ - - /* append DHCP message trailer */ - dhcp_option_trailer(dhcp); - - udp_sendto_if(dhcp_pcb, dhcp->p_out, &dhcp->server_ip_addr, DHCP_SERVER_PORT, netif); - dhcp_delete_msg(dhcp); - - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_renew: RENEWING\n")); - } else { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_renew: could not allocate DHCP request\n")); - } - if (dhcp->tries < 255) { - dhcp->tries++; - } - /* back-off on retries, but to a maximum of 20 seconds */ - msecs = (u16_t)(dhcp->tries < 10 ? dhcp->tries * 2000 : 20 * 1000); - dhcp->request_timeout = (u16_t)((msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS); - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_renew(): set request timeout %"U16_F" msecs\n", msecs)); - return result; -} - -/** - * Rebind with a DHCP server for an existing DHCP lease. - * - * @param netif network interface which must rebind with a DHCP server - */ -static err_t -dhcp_rebind(struct netif *netif) -{ - struct dhcp *dhcp = netif_dhcp_data(netif); - err_t result; - u16_t msecs; - u8_t i; - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_rebind()\n")); - dhcp_set_state(dhcp, DHCP_STATE_REBINDING); - - /* create and initialize the DHCP message header */ - result = dhcp_create_msg(netif, dhcp, DHCP_REQUEST); - if (result == ERR_OK) { - dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN); - dhcp_option_short(dhcp, DHCP_MAX_MSG_LEN(netif)); - - dhcp_option(dhcp, DHCP_OPTION_PARAMETER_REQUEST_LIST, LWIP_ARRAYSIZE(dhcp_discover_request_options)); - for (i = 0; i < LWIP_ARRAYSIZE(dhcp_discover_request_options); i++) { - dhcp_option_byte(dhcp, dhcp_discover_request_options[i]); - } - -#if LWIP_NETIF_HOSTNAME - dhcp_option_hostname(dhcp, netif); -#endif /* LWIP_NETIF_HOSTNAME */ - - dhcp_option_trailer(dhcp); - - /* broadcast to server */ - udp_sendto_if(dhcp_pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT, netif); - dhcp_delete_msg(dhcp); - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_rebind: REBINDING\n")); - } else { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_rebind: could not allocate DHCP request\n")); - } - if (dhcp->tries < 255) { - dhcp->tries++; - } - msecs = (u16_t)(dhcp->tries < 10 ? dhcp->tries * 1000 : 10 * 1000); - dhcp->request_timeout = (u16_t)((msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS); - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_rebind(): set request timeout %"U16_F" msecs\n", msecs)); - return result; -} - -/** - * Enter REBOOTING state to verify an existing lease - * - * @param netif network interface which must reboot - */ -static err_t -dhcp_reboot(struct netif *netif) -{ - struct dhcp *dhcp = netif_dhcp_data(netif); - err_t result; - u16_t msecs; - u8_t i; - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_reboot()\n")); - dhcp_set_state(dhcp, DHCP_STATE_REBOOTING); - - /* create and initialize the DHCP message header */ - result = dhcp_create_msg(netif, dhcp, DHCP_REQUEST); - if (result == ERR_OK) { - dhcp_option(dhcp, DHCP_OPTION_MAX_MSG_SIZE, DHCP_OPTION_MAX_MSG_SIZE_LEN); - dhcp_option_short(dhcp, DHCP_MAX_MSG_LEN_MIN_REQUIRED); - - dhcp_option(dhcp, DHCP_OPTION_REQUESTED_IP, 4); - dhcp_option_long(dhcp, lwip_ntohl(ip4_addr_get_u32(&dhcp->offered_ip_addr))); - - dhcp_option(dhcp, DHCP_OPTION_PARAMETER_REQUEST_LIST, LWIP_ARRAYSIZE(dhcp_discover_request_options)); - for (i = 0; i < LWIP_ARRAYSIZE(dhcp_discover_request_options); i++) { - dhcp_option_byte(dhcp, dhcp_discover_request_options[i]); - } - - dhcp_option_trailer(dhcp); - - /* broadcast to server */ - udp_sendto_if(dhcp_pcb, dhcp->p_out, IP_ADDR_BROADCAST, DHCP_SERVER_PORT, netif); - dhcp_delete_msg(dhcp); - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_reboot: REBOOTING\n")); - } else { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_reboot: could not allocate DHCP request\n")); - } - if (dhcp->tries < 255) { - dhcp->tries++; - } - msecs = (u16_t)(dhcp->tries < 10 ? dhcp->tries * 1000 : 10 * 1000); - dhcp->request_timeout = (u16_t)((msecs + DHCP_FINE_TIMER_MSECS - 1) / DHCP_FINE_TIMER_MSECS); - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_reboot(): set request timeout %"U16_F" msecs\n", msecs)); - return result; -} - - -/** - * @ingroup dhcp4 - * Release a DHCP lease (usually called before @ref dhcp_stop). - * - * @param netif network interface which must release its lease - */ -err_t -dhcp_release(struct netif *netif) -{ - struct dhcp *dhcp = netif_dhcp_data(netif); - err_t result; - ip_addr_t server_ip_addr; - u8_t is_dhcp_supplied_address; - - LWIP_ASSERT_CORE_LOCKED(); - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_release()\n")); - if (dhcp == NULL) { - return ERR_ARG; - } - ip_addr_copy(server_ip_addr, dhcp->server_ip_addr); - - is_dhcp_supplied_address = dhcp_supplied_address(netif); - - /* idle DHCP client */ - dhcp_set_state(dhcp, DHCP_STATE_OFF); - /* clean old DHCP offer */ - ip_addr_set_zero_ip4(&dhcp->server_ip_addr); - ip4_addr_set_zero(&dhcp->offered_ip_addr); - ip4_addr_set_zero(&dhcp->offered_sn_mask); - ip4_addr_set_zero(&dhcp->offered_gw_addr); -#if LWIP_DHCP_BOOTP_FILE - ip4_addr_set_zero(&dhcp->offered_si_addr); -#endif /* LWIP_DHCP_BOOTP_FILE */ - dhcp->offered_t0_lease = dhcp->offered_t1_renew = dhcp->offered_t2_rebind = 0; - dhcp->t1_renew_time = dhcp->t2_rebind_time = dhcp->lease_used = dhcp->t0_timeout = 0; - - if (!is_dhcp_supplied_address) { - /* don't issue release message when address is not dhcp-assigned */ - return ERR_OK; - } - - /* create and initialize the DHCP message header */ - result = dhcp_create_msg(netif, dhcp, DHCP_RELEASE); - if (result == ERR_OK) { - dhcp_option(dhcp, DHCP_OPTION_SERVER_ID, 4); - dhcp_option_long(dhcp, lwip_ntohl(ip4_addr_get_u32(ip_2_ip4(&server_ip_addr)))); - - dhcp_option_trailer(dhcp); - - udp_sendto_if(dhcp_pcb, dhcp->p_out, &server_ip_addr, DHCP_SERVER_PORT, netif); - dhcp_delete_msg(dhcp); - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("dhcp_release: RELEASED, DHCP_STATE_OFF\n")); - } else { - /* sending release failed, but that's not a problem since the correct behaviour of dhcp does not rely on release */ - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("dhcp_release: could not allocate DHCP request\n")); - } - /* remove IP address from interface (prevents routing from selecting this interface) */ - netif_set_addr(netif, IP4_ADDR_ANY4, IP4_ADDR_ANY4, IP4_ADDR_ANY4); - - return result; -} - -/** - * @ingroup dhcp4 - * Remove the DHCP client from the interface. - * - * @param netif The network interface to stop DHCP on - */ -void -dhcp_stop(struct netif *netif) -{ - struct dhcp *dhcp; - LWIP_ERROR("dhcp_stop: netif != NULL", (netif != NULL), return;); - dhcp = netif_dhcp_data(netif); - - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_stop()\n")); - /* netif is DHCP configured? */ - if (dhcp != NULL) { -#if LWIP_DHCP_AUTOIP_COOP - if (dhcp->autoip_coop_state == DHCP_AUTOIP_COOP_STATE_ON) { - autoip_stop(netif); - dhcp->autoip_coop_state = DHCP_AUTOIP_COOP_STATE_OFF; - } -#endif /* LWIP_DHCP_AUTOIP_COOP */ - - LWIP_ASSERT("reply wasn't freed", dhcp->msg_in == NULL); - dhcp_set_state(dhcp, DHCP_STATE_OFF); - - if (dhcp->pcb_allocated != 0) { - dhcp_dec_pcb_refcount(); /* free DHCP PCB if not needed any more */ - dhcp->pcb_allocated = 0; - } - } -} - -/* - * Set the DHCP state of a DHCP client. - * - * If the state changed, reset the number of tries. - */ -static void -dhcp_set_state(struct dhcp *dhcp, u8_t new_state) -{ - if (new_state != dhcp->state) { - dhcp->state = new_state; - dhcp->tries = 0; - dhcp->request_timeout = 0; - } -} - -/* - * Concatenate an option type and length field to the outgoing - * DHCP message. - * - */ -static void -dhcp_option(struct dhcp *dhcp, u8_t option_type, u8_t option_len) -{ - LWIP_ASSERT("dhcp_option: dhcp->options_out_len + 2 + option_len <= DHCP_OPTIONS_LEN", dhcp->options_out_len + 2U + option_len <= DHCP_OPTIONS_LEN); - dhcp->msg_out->options[dhcp->options_out_len++] = option_type; - dhcp->msg_out->options[dhcp->options_out_len++] = option_len; -} -/* - * Concatenate a single byte to the outgoing DHCP message. - * - */ -static void -dhcp_option_byte(struct dhcp *dhcp, u8_t value) -{ - LWIP_ASSERT("dhcp_option_byte: dhcp->options_out_len < DHCP_OPTIONS_LEN", dhcp->options_out_len < DHCP_OPTIONS_LEN); - dhcp->msg_out->options[dhcp->options_out_len++] = value; -} - -static void -dhcp_option_short(struct dhcp *dhcp, u16_t value) -{ - LWIP_ASSERT("dhcp_option_short: dhcp->options_out_len + 2 <= DHCP_OPTIONS_LEN", dhcp->options_out_len + 2U <= DHCP_OPTIONS_LEN); - dhcp->msg_out->options[dhcp->options_out_len++] = (u8_t)((value & 0xff00U) >> 8); - dhcp->msg_out->options[dhcp->options_out_len++] = (u8_t) (value & 0x00ffU); -} - -static void -dhcp_option_long(struct dhcp *dhcp, u32_t value) -{ - LWIP_ASSERT("dhcp_option_long: dhcp->options_out_len + 4 <= DHCP_OPTIONS_LEN", dhcp->options_out_len + 4U <= DHCP_OPTIONS_LEN); - dhcp->msg_out->options[dhcp->options_out_len++] = (u8_t)((value & 0xff000000UL) >> 24); - dhcp->msg_out->options[dhcp->options_out_len++] = (u8_t)((value & 0x00ff0000UL) >> 16); - dhcp->msg_out->options[dhcp->options_out_len++] = (u8_t)((value & 0x0000ff00UL) >> 8); - dhcp->msg_out->options[dhcp->options_out_len++] = (u8_t)((value & 0x000000ffUL)); -} - -#if LWIP_NETIF_HOSTNAME -static void -dhcp_option_hostname(struct dhcp *dhcp, struct netif *netif) -{ - if (netif->hostname != NULL) { - size_t namelen = strlen(netif->hostname); - if (namelen > 0) { - size_t len; - const char *p = netif->hostname; - /* Shrink len to available bytes (need 2 bytes for OPTION_HOSTNAME - and 1 byte for trailer) */ - size_t available = DHCP_OPTIONS_LEN - dhcp->options_out_len - 3; - LWIP_ASSERT("DHCP: hostname is too long!", namelen <= available); - len = LWIP_MIN(namelen, available); - LWIP_ASSERT("DHCP: hostname is too long!", len <= 0xFF); - dhcp_option(dhcp, DHCP_OPTION_HOSTNAME, (u8_t)len); - while (len--) { - dhcp_option_byte(dhcp, *p++); - } - } - } -} -#endif /* LWIP_NETIF_HOSTNAME */ - -/** - * Extract the DHCP message and the DHCP options. - * - * Extract the DHCP message and the DHCP options, each into a contiguous - * piece of memory. As a DHCP message is variable sized by its options, - * and also allows overriding some fields for options, the easy approach - * is to first unfold the options into a contiguous piece of memory, and - * use that further on. - * - */ -static err_t -dhcp_parse_reply(struct dhcp *dhcp, struct pbuf *p) -{ - u8_t *options; - u16_t offset; - u16_t offset_max; - u16_t options_idx; - u16_t options_idx_max; - struct pbuf *q; - int parse_file_as_options = 0; - int parse_sname_as_options = 0; - - /* clear received options */ - dhcp_clear_all_options(dhcp); - /* check that beginning of dhcp_msg (up to and including chaddr) is in first pbuf */ - if (p->len < DHCP_SNAME_OFS) { - return ERR_BUF; - } - dhcp->msg_in = (struct dhcp_msg *)p->payload; -#if LWIP_DHCP_BOOTP_FILE - /* clear boot file name */ - dhcp->boot_file_name[0] = 0; -#endif /* LWIP_DHCP_BOOTP_FILE */ - - /* parse options */ - - /* start with options field */ - options_idx = DHCP_OPTIONS_OFS; - /* parse options to the end of the received packet */ - options_idx_max = p->tot_len; -again: - q = p; - while ((q != NULL) && (options_idx >= q->len)) { - options_idx = (u16_t)(options_idx - q->len); - options_idx_max = (u16_t)(options_idx_max - q->len); - q = q->next; - } - if (q == NULL) { - return ERR_BUF; - } - offset = options_idx; - offset_max = options_idx_max; - options = (u8_t*)q->payload; - /* at least 1 byte to read and no end marker, then at least 3 bytes to read? */ - while ((q != NULL) && (offset < offset_max) && (options[offset] != DHCP_OPTION_END)) { - u8_t op = options[offset]; - u8_t len; - u8_t decode_len = 0; - int decode_idx = -1; - u16_t val_offset = (u16_t)(offset + 2); - if (val_offset < offset) { - /* overflow */ - return ERR_BUF; - } - /* len byte might be in the next pbuf */ - if ((offset + 1) < q->len) { - len = options[offset + 1]; - } else { - len = (q->next != NULL ? ((u8_t*)q->next->payload)[0] : 0); - } - /* LWIP_DEBUGF(DHCP_DEBUG, ("msg_offset=%"U16_F", q->len=%"U16_F, msg_offset, q->len)); */ - decode_len = len; - switch(op) { - /* case(DHCP_OPTION_END): handled above */ - case(DHCP_OPTION_PAD): - /* special option: no len encoded */ - decode_len = len = 0; - /* will be increased below */ - offset--; - break; - case(DHCP_OPTION_SUBNET_MASK): - LWIP_ERROR("len == 4", len == 4, return ERR_VAL;); - decode_idx = DHCP_OPTION_IDX_SUBNET_MASK; - break; - case(DHCP_OPTION_ROUTER): - decode_len = 4; /* only copy the first given router */ - LWIP_ERROR("len >= decode_len", len >= decode_len, return ERR_VAL;); - decode_idx = DHCP_OPTION_IDX_ROUTER; - break; -#if LWIP_DHCP_PROVIDE_DNS_SERVERS - case(DHCP_OPTION_DNS_SERVER): - /* special case: there might be more than one server */ - LWIP_ERROR("len %% 4 == 0", len % 4 == 0, return ERR_VAL;); - /* limit number of DNS servers */ - decode_len = LWIP_MIN(len, 4 * DNS_MAX_SERVERS); - LWIP_ERROR("len >= decode_len", len >= decode_len, return ERR_VAL;); - decode_idx = DHCP_OPTION_IDX_DNS_SERVER; - break; -#endif /* LWIP_DHCP_PROVIDE_DNS_SERVERS */ - case(DHCP_OPTION_LEASE_TIME): - LWIP_ERROR("len == 4", len == 4, return ERR_VAL;); - decode_idx = DHCP_OPTION_IDX_LEASE_TIME; - break; -#if LWIP_DHCP_GET_NTP_SRV - case(DHCP_OPTION_NTP): - /* special case: there might be more than one server */ - LWIP_ERROR("len %% 4 == 0", len % 4 == 0, return ERR_VAL;); - /* limit number of NTP servers */ - decode_len = LWIP_MIN(len, 4 * LWIP_DHCP_MAX_NTP_SERVERS); - LWIP_ERROR("len >= decode_len", len >= decode_len, return ERR_VAL;); - decode_idx = DHCP_OPTION_IDX_NTP_SERVER; - break; -#endif /* LWIP_DHCP_GET_NTP_SRV*/ - case(DHCP_OPTION_OVERLOAD): - LWIP_ERROR("len == 1", len == 1, return ERR_VAL;); - /* decode overload only in options, not in file/sname: invalid packet */ - LWIP_ERROR("overload in file/sname", options_idx == DHCP_OPTIONS_OFS, return ERR_VAL;); - decode_idx = DHCP_OPTION_IDX_OVERLOAD; - break; - case(DHCP_OPTION_MESSAGE_TYPE): - LWIP_ERROR("len == 1", len == 1, return ERR_VAL;); - decode_idx = DHCP_OPTION_IDX_MSG_TYPE; - break; - case(DHCP_OPTION_SERVER_ID): - LWIP_ERROR("len == 4", len == 4, return ERR_VAL;); - decode_idx = DHCP_OPTION_IDX_SERVER_ID; - break; - case(DHCP_OPTION_T1): - LWIP_ERROR("len == 4", len == 4, return ERR_VAL;); - decode_idx = DHCP_OPTION_IDX_T1; - break; - case(DHCP_OPTION_T2): - LWIP_ERROR("len == 4", len == 4, return ERR_VAL;); - decode_idx = DHCP_OPTION_IDX_T2; - break; - default: - decode_len = 0; - LWIP_DEBUGF(DHCP_DEBUG, ("skipping option %"U16_F" in options\n", (u16_t)op)); - break; - } - if (offset + len + 2 > 0xFFFF) { - /* overflow */ - return ERR_BUF; - } - offset = (u16_t)(offset + len + 2); - if (decode_len > 0) { - u32_t value = 0; - u16_t copy_len; -decode_next: - LWIP_ASSERT("check decode_idx", decode_idx >= 0 && decode_idx < DHCP_OPTION_IDX_MAX); - if (!dhcp_option_given(dhcp, decode_idx)) { - copy_len = LWIP_MIN(decode_len, 4); - if (pbuf_copy_partial(q, &value, copy_len, val_offset) != copy_len) { - return ERR_BUF; - } - if (decode_len > 4) { - /* decode more than one u32_t */ - u16_t next_val_offset; - LWIP_ERROR("decode_len %% 4 == 0", decode_len % 4 == 0, return ERR_VAL;); - dhcp_got_option(dhcp, decode_idx); - dhcp_set_option_value(dhcp, decode_idx, lwip_htonl(value)); - decode_len = (u8_t)(decode_len - 4); - next_val_offset = (u16_t)(val_offset + 4); - if (next_val_offset < val_offset) { - /* overflow */ - return ERR_BUF; - } - val_offset = next_val_offset; - decode_idx++; - goto decode_next; - } else if (decode_len == 4) { - value = lwip_ntohl(value); - } else { - LWIP_ERROR("invalid decode_len", decode_len == 1, return ERR_VAL;); - value = ((u8_t*)&value)[0]; - } - dhcp_got_option(dhcp, decode_idx); - dhcp_set_option_value(dhcp, decode_idx, value); - } - } - if (offset >= q->len) { - offset = (u16_t)(offset - q->len); - offset_max = (u16_t)(offset_max - q->len); - if ((offset < offset_max) && offset_max) { - q = q->next; - LWIP_ERROR("next pbuf was null", q != NULL, return ERR_VAL;); - options = (u8_t*)q->payload; - } else { - /* We've run out of bytes, probably no end marker. Don't proceed. */ - break; - } - } - } - /* is this an overloaded message? */ - if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_OVERLOAD)) { - u32_t overload = dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_OVERLOAD); - dhcp_clear_option(dhcp, DHCP_OPTION_IDX_OVERLOAD); - if (overload == DHCP_OVERLOAD_FILE) { - parse_file_as_options = 1; - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("overloaded file field\n")); - } else if (overload == DHCP_OVERLOAD_SNAME) { - parse_sname_as_options = 1; - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("overloaded sname field\n")); - } else if (overload == DHCP_OVERLOAD_SNAME_FILE) { - parse_sname_as_options = 1; - parse_file_as_options = 1; - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("overloaded sname and file field\n")); - } else { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("invalid overload option: %d\n", (int)overload)); - } -#if LWIP_DHCP_BOOTP_FILE - if (!parse_file_as_options) { - /* only do this for ACK messages */ - if (dhcp_option_given(dhcp, DHCP_OPTION_IDX_MSG_TYPE) && - (dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_MSG_TYPE) == DHCP_ACK)) - /* copy bootp file name, don't care for sname (server hostname) */ - if (pbuf_copy_partial(p, dhcp->boot_file_name, DHCP_FILE_LEN-1, DHCP_FILE_OFS) != (DHCP_FILE_LEN-1)) { - return ERR_BUF; - } - /* make sure the string is really NULL-terminated */ - dhcp->boot_file_name[DHCP_FILE_LEN-1] = 0; - } -#endif /* LWIP_DHCP_BOOTP_FILE */ - } - if (parse_file_as_options) { - /* if both are overloaded, parse file first and then sname (RFC 2131 ch. 4.1) */ - parse_file_as_options = 0; - options_idx = DHCP_FILE_OFS; - options_idx_max = DHCP_FILE_OFS + DHCP_FILE_LEN; - goto again; - } else if (parse_sname_as_options) { - parse_sname_as_options = 0; - options_idx = DHCP_SNAME_OFS; - options_idx_max = DHCP_SNAME_OFS + DHCP_SNAME_LEN; - goto again; - } - return ERR_OK; -} - -/** - * If an incoming DHCP message is in response to us, then trigger the state machine - */ -static void -dhcp_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port) -{ - struct netif *netif = ip_current_input_netif(); - struct dhcp *dhcp = netif_dhcp_data(netif); - struct dhcp_msg *reply_msg = (struct dhcp_msg *)p->payload; - u8_t msg_type; - u8_t i; - - LWIP_UNUSED_ARG(arg); - - /* Caught DHCP message from netif that does not have DHCP enabled? -> not interested */ - if ((dhcp == NULL) || (dhcp->pcb_allocated == 0)) { - goto free_pbuf_and_return; - } - - LWIP_ASSERT("invalid server address type", IP_IS_V4(addr)); - - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_recv(pbuf = %p) from DHCP server %"U16_F".%"U16_F".%"U16_F".%"U16_F" port %"U16_F"\n", (void*)p, - ip4_addr1_16(ip_2_ip4(addr)), ip4_addr2_16(ip_2_ip4(addr)), ip4_addr3_16(ip_2_ip4(addr)), ip4_addr4_16(ip_2_ip4(addr)), port)); - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("pbuf->len = %"U16_F"\n", p->len)); - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("pbuf->tot_len = %"U16_F"\n", p->tot_len)); - /* prevent warnings about unused arguments */ - LWIP_UNUSED_ARG(pcb); - LWIP_UNUSED_ARG(addr); - LWIP_UNUSED_ARG(port); - - LWIP_ASSERT("reply wasn't freed", dhcp->msg_in == NULL); - - if (p->len < DHCP_MIN_REPLY_LEN) { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("DHCP reply message or pbuf too short\n")); - goto free_pbuf_and_return; - } - - if (reply_msg->op != DHCP_BOOTREPLY) { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("not a DHCP reply message, but type %"U16_F"\n", (u16_t)reply_msg->op)); - goto free_pbuf_and_return; - } - /* iterate through hardware address and match against DHCP message */ - for (i = 0; i < netif->hwaddr_len && i < NETIF_MAX_HWADDR_LEN && i < DHCP_CHADDR_LEN; i++) { - if (netif->hwaddr[i] != reply_msg->chaddr[i]) { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, - ("netif->hwaddr[%"U16_F"]==%02"X16_F" != reply_msg->chaddr[%"U16_F"]==%02"X16_F"\n", - (u16_t)i, (u16_t)netif->hwaddr[i], (u16_t)i, (u16_t)reply_msg->chaddr[i])); - goto free_pbuf_and_return; - } - } - /* match transaction ID against what we expected */ - if (lwip_ntohl(reply_msg->xid) != dhcp->xid) { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, - ("transaction id mismatch reply_msg->xid(%"X32_F")!=dhcp->xid(%"X32_F")\n",lwip_ntohl(reply_msg->xid),dhcp->xid)); - goto free_pbuf_and_return; - } - /* option fields could be unfold? */ - if (dhcp_parse_reply(dhcp, p) != ERR_OK) { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, - ("problem unfolding DHCP message - too short on memory?\n")); - goto free_pbuf_and_return; - } - - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("searching DHCP_OPTION_MESSAGE_TYPE\n")); - /* obtain pointer to DHCP message type */ - if (!dhcp_option_given(dhcp, DHCP_OPTION_IDX_MSG_TYPE)) { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("DHCP_OPTION_MESSAGE_TYPE option not found\n")); - goto free_pbuf_and_return; - } - - /* read DHCP message type */ - msg_type = (u8_t)dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_MSG_TYPE); - /* message type is DHCP ACK? */ - if (msg_type == DHCP_ACK) { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("DHCP_ACK received\n")); - /* in requesting state? */ - if (dhcp->state == DHCP_STATE_REQUESTING) { - dhcp_handle_ack(netif); -#if DHCP_DOES_ARP_CHECK - if ((netif->flags & NETIF_FLAG_ETHARP) != 0) { - /* check if the acknowledged lease address is already in use */ - dhcp_check(netif); - } else { - /* bind interface to the acknowledged lease address */ - dhcp_bind(netif); - } -#else - /* bind interface to the acknowledged lease address */ - dhcp_bind(netif); -#endif - } - /* already bound to the given lease address? */ - else if ((dhcp->state == DHCP_STATE_REBOOTING) || (dhcp->state == DHCP_STATE_REBINDING) || - (dhcp->state == DHCP_STATE_RENEWING)) { - dhcp_handle_ack(netif); - dhcp_bind(netif); - } - } - /* received a DHCP_NAK in appropriate state? */ - else if ((msg_type == DHCP_NAK) && - ((dhcp->state == DHCP_STATE_REBOOTING) || (dhcp->state == DHCP_STATE_REQUESTING) || - (dhcp->state == DHCP_STATE_REBINDING) || (dhcp->state == DHCP_STATE_RENEWING ))) { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("DHCP_NAK received\n")); - dhcp_handle_nak(netif); - } - /* received a DHCP_OFFER in DHCP_STATE_SELECTING state? */ - else if ((msg_type == DHCP_OFFER) && (dhcp->state == DHCP_STATE_SELECTING)) { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("DHCP_OFFER received in DHCP_STATE_SELECTING state\n")); - dhcp->request_timeout = 0; - /* remember offered lease */ - dhcp_handle_offer(netif); - } - -free_pbuf_and_return: - if (dhcp != NULL) { - dhcp->msg_in = NULL; - } - pbuf_free(p); -} - -/** - * Create a DHCP request, fill in common headers - * - * @param netif the netif under DHCP control - * @param dhcp dhcp control struct - * @param message_type message type of the request - */ -static err_t -dhcp_create_msg(struct netif *netif, struct dhcp *dhcp, u8_t message_type) -{ - u16_t i; -#ifndef DHCP_GLOBAL_XID - /** default global transaction identifier starting value (easy to match - * with a packet analyser). We simply increment for each new request. - * Predefine DHCP_GLOBAL_XID to a better value or a function call to generate one - * at runtime, any supporting function prototypes can be defined in DHCP_GLOBAL_XID_HEADER */ -#if DHCP_CREATE_RAND_XID && defined(LWIP_RAND) - static u32_t xid; -#else /* DHCP_CREATE_RAND_XID && defined(LWIP_RAND) */ - static u32_t xid = 0xABCD0000; -#endif /* DHCP_CREATE_RAND_XID && defined(LWIP_RAND) */ -#else - if (!xid_initialised) { - xid = DHCP_GLOBAL_XID; - xid_initialised = !xid_initialised; - } -#endif - LWIP_ERROR("dhcp_create_msg: netif != NULL", (netif != NULL), return ERR_ARG;); - LWIP_ERROR("dhcp_create_msg: dhcp != NULL", (dhcp != NULL), return ERR_VAL;); - - /* free previous dhcp msg, in case it is not freed yet */ - /* otherwise, memory leaks */ - if (dhcp->p_out != NULL) - dhcp_delete_msg(dhcp); - - dhcp->p_out = pbuf_alloc(PBUF_TRANSPORT, sizeof(struct dhcp_msg), PBUF_RAM); - if (dhcp->p_out == NULL) { - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, - ("dhcp_create_msg(): could not allocate pbuf\n")); - return ERR_MEM; - } - LWIP_ASSERT("dhcp_create_msg: check that first pbuf can hold struct dhcp_msg", - (dhcp->p_out->len >= sizeof(struct dhcp_msg))); - - /* DHCP_REQUEST should reuse 'xid' from DHCPOFFER */ - if ((message_type != DHCP_REQUEST) || (dhcp->state == DHCP_STATE_REBOOTING)) { - /* reuse transaction identifier in retransmissions */ - if (dhcp->tries == 0) { -#if DHCP_CREATE_RAND_XID && defined(LWIP_RAND) - xid = LWIP_RAND(); -#else /* DHCP_CREATE_RAND_XID && defined(LWIP_RAND) */ - xid++; -#endif /* DHCP_CREATE_RAND_XID && defined(LWIP_RAND) */ - } - dhcp->xid = xid; - } - LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, - ("transaction id xid(%"X32_F")\n", xid)); - - dhcp->msg_out = (struct dhcp_msg *)dhcp->p_out->payload; - - dhcp->msg_out->op = DHCP_BOOTREQUEST; - /* @todo: make link layer independent */ - dhcp->msg_out->htype = DHCP_HTYPE_ETH; - dhcp->msg_out->hlen = netif->hwaddr_len; - dhcp->msg_out->hops = 0; - dhcp->msg_out->xid = lwip_htonl(dhcp->xid); - dhcp->msg_out->secs = 0; - /* we don't need the broadcast flag since we can receive unicast traffic - before being fully configured! */ - dhcp->msg_out->flags = 0; - ip4_addr_set_zero(&dhcp->msg_out->ciaddr); - /* set ciaddr to netif->ip_addr based on message_type and state */ - if ((message_type == DHCP_INFORM) || (message_type == DHCP_DECLINE) || (message_type == DHCP_RELEASE) || - ((message_type == DHCP_REQUEST) && /* DHCP_STATE_BOUND not used for sending! */ - ((dhcp->state== DHCP_STATE_RENEWING) || dhcp->state== DHCP_STATE_REBINDING))) { - ip4_addr_copy(dhcp->msg_out->ciaddr, *netif_ip4_addr(netif)); - } - ip4_addr_set_zero(&dhcp->msg_out->yiaddr); - ip4_addr_set_zero(&dhcp->msg_out->siaddr); - ip4_addr_set_zero(&dhcp->msg_out->giaddr); - for (i = 0; i < DHCP_CHADDR_LEN; i++) { - /* copy netif hardware address, pad with zeroes */ - dhcp->msg_out->chaddr[i] = (i < netif->hwaddr_len && i < NETIF_MAX_HWADDR_LEN) ? netif->hwaddr[i] : 0/* pad byte*/; - } - for (i = 0; i < DHCP_SNAME_LEN; i++) { - dhcp->msg_out->sname[i] = 0; - } - for (i = 0; i < DHCP_FILE_LEN; i++) { - dhcp->msg_out->file[i] = 0; - } - dhcp->msg_out->cookie = PP_HTONL(DHCP_MAGIC_COOKIE); - dhcp->options_out_len = 0; - /* fill options field with an incrementing array (for debugging purposes) */ - for (i = 0; i < DHCP_OPTIONS_LEN; i++) { - dhcp->msg_out->options[i] = (u8_t)i; /* for debugging only, no matter if truncated */ - } - /* Add option MESSAGE_TYPE */ - dhcp_option(dhcp, DHCP_OPTION_MESSAGE_TYPE, DHCP_OPTION_MESSAGE_TYPE_LEN); - dhcp_option_byte(dhcp, message_type); - return ERR_OK; -} - -/** - * Free previously allocated memory used to send a DHCP request. - * - * @param dhcp the dhcp struct to free the request from - */ -static void -dhcp_delete_msg(struct dhcp *dhcp) -{ - LWIP_ERROR("dhcp_delete_msg: dhcp != NULL", (dhcp != NULL), return;); - LWIP_ASSERT("dhcp_delete_msg: dhcp->p_out != NULL", dhcp->p_out != NULL); - LWIP_ASSERT("dhcp_delete_msg: dhcp->msg_out != NULL", dhcp->msg_out != NULL); - if (dhcp->p_out != NULL) { - pbuf_free(dhcp->p_out); - } - dhcp->p_out = NULL; - dhcp->msg_out = NULL; -} - -/** - * Add a DHCP message trailer - * - * Adds the END option to the DHCP message, and if - * necessary, up to three padding bytes. - * - * @param dhcp DHCP state structure - */ -static void -dhcp_option_trailer(struct dhcp *dhcp) -{ - LWIP_ERROR("dhcp_option_trailer: dhcp != NULL", (dhcp != NULL), return;); - LWIP_ASSERT("dhcp_option_trailer: dhcp->msg_out != NULL\n", dhcp->msg_out != NULL); - LWIP_ASSERT("dhcp_option_trailer: dhcp->options_out_len < DHCP_OPTIONS_LEN\n", dhcp->options_out_len < DHCP_OPTIONS_LEN); - dhcp->msg_out->options[dhcp->options_out_len++] = DHCP_OPTION_END; - /* packet is too small, or not 4 byte aligned? */ - while (((dhcp->options_out_len < DHCP_MIN_OPTIONS_LEN) || (dhcp->options_out_len & 3)) && - (dhcp->options_out_len < DHCP_OPTIONS_LEN)) { - /* add a fill/padding byte */ - dhcp->msg_out->options[dhcp->options_out_len++] = 0; - } - /* shrink the pbuf to the actual content length */ - pbuf_realloc(dhcp->p_out, (u16_t)(sizeof(struct dhcp_msg) - DHCP_OPTIONS_LEN + dhcp->options_out_len)); -} - -/** check if DHCP supplied netif->ip_addr - * - * @param netif the netif to check - * @return 1 if DHCP supplied netif->ip_addr (states BOUND or RENEWING), - * 0 otherwise - */ -u8_t -dhcp_supplied_address(const struct netif *netif) -{ - if ((netif != NULL) && (netif_dhcp_data(netif) != NULL)) { - struct dhcp* dhcp = netif_dhcp_data(netif); - return (dhcp->state == DHCP_STATE_BOUND) || (dhcp->state == DHCP_STATE_RENEWING) || - (dhcp->state == DHCP_STATE_REBINDING); - } - return 0; -} - -#endif /* LWIP_IPV4 && LWIP_DHCP */ diff --git a/third_party/lwip/repo/lwip/src/core/ipv4/etharp.c b/third_party/lwip/repo/lwip/src/core/ipv4/etharp.c deleted file mode 100644 index 4a4cebac0da79e..00000000000000 --- a/third_party/lwip/repo/lwip/src/core/ipv4/etharp.c +++ /dev/null @@ -1,1206 +0,0 @@ -/** - * @file - * Address Resolution Protocol module for IP over Ethernet - * - * Functionally, ARP is divided into two parts. The first maps an IP address - * to a physical address when sending a packet, and the second part answers - * requests from other machines for our physical address. - * - * This implementation complies with RFC 826 (Ethernet ARP). It supports - * Gratuitious ARP from RFC3220 (IP Mobility Support for IPv4) section 4.6 - * if an interface calls etharp_gratuitous(our_netif) upon address change. - */ - -/* - * Copyright (c) 2001-2003 Swedish Institute of Computer Science. - * Copyright (c) 2003-2004 Leon Woestenberg - * Copyright (c) 2003-2004 Axon Digital Design B.V., The Netherlands. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - */ - -#include "lwip/opt.h" - -#if LWIP_ARP || LWIP_ETHERNET - -#include "lwip/etharp.h" -#include "lwip/stats.h" -#include "lwip/snmp.h" -#include "lwip/dhcp.h" -#include "lwip/autoip.h" -#include "netif/ethernet.h" - -#include - -#ifdef LWIP_HOOK_FILENAME -#include LWIP_HOOK_FILENAME -#endif - -#if LWIP_IPV4 && LWIP_ARP /* don't build if not configured for use in lwipopts.h */ - -/** Re-request a used ARP entry 1 minute before it would expire to prevent - * breaking a steadily used connection because the ARP entry timed out. */ -#define ARP_AGE_REREQUEST_USED_UNICAST (ARP_MAXAGE - 30) -#define ARP_AGE_REREQUEST_USED_BROADCAST (ARP_MAXAGE - 15) - -/** the time an ARP entry stays pending after first request, - * for ARP_TMR_INTERVAL = 1000, this is - * 10 seconds. - * - * @internal Keep this number at least 2, otherwise it might - * run out instantly if the timeout occurs directly after a request. - */ -#define ARP_MAXPENDING 5 - -/** ARP states */ -enum etharp_state { - ETHARP_STATE_EMPTY = 0, - ETHARP_STATE_PENDING, - ETHARP_STATE_STABLE, - ETHARP_STATE_STABLE_REREQUESTING_1, - ETHARP_STATE_STABLE_REREQUESTING_2 -#if ETHARP_SUPPORT_STATIC_ENTRIES - ,ETHARP_STATE_STATIC -#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ -}; - -struct etharp_entry { -#if ARP_QUEUEING - /** Pointer to queue of pending outgoing packets on this ARP entry. */ - struct etharp_q_entry *q; -#else /* ARP_QUEUEING */ - /** Pointer to a single pending outgoing packet on this ARP entry. */ - struct pbuf *q; -#endif /* ARP_QUEUEING */ - ip4_addr_t ipaddr; - struct netif *netif; - struct eth_addr ethaddr; - u16_t ctime; - u8_t state; -}; - -static struct etharp_entry arp_table[ARP_TABLE_SIZE]; - -#if !LWIP_NETIF_HWADDRHINT -static u8_t etharp_cached_entry; -#endif /* !LWIP_NETIF_HWADDRHINT */ - -/** Try hard to create a new entry - we want the IP address to appear in - the cache (even if this means removing an active entry or so). */ -#define ETHARP_FLAG_TRY_HARD 1 -#define ETHARP_FLAG_FIND_ONLY 2 -#if ETHARP_SUPPORT_STATIC_ENTRIES -#define ETHARP_FLAG_STATIC_ENTRY 4 -#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ - -#if LWIP_NETIF_HWADDRHINT -#define ETHARP_SET_HINT(netif, hint) if (((netif) != NULL) && ((netif)->addr_hint != NULL)) \ - *((netif)->addr_hint) = (hint); -#else /* LWIP_NETIF_HWADDRHINT */ -#define ETHARP_SET_HINT(netif, hint) (etharp_cached_entry = (hint)) -#endif /* LWIP_NETIF_HWADDRHINT */ - - -/* Some checks, instead of etharp_init(): */ -#if (LWIP_ARP && (ARP_TABLE_SIZE > 0x7f)) - #error "ARP_TABLE_SIZE must fit in an s8_t, you have to reduce it in your lwipopts.h" -#endif - - -static err_t etharp_request_dst(struct netif *netif, const ip4_addr_t *ipaddr, const struct eth_addr* hw_dst_addr); -static err_t etharp_raw(struct netif *netif, - const struct eth_addr *ethsrc_addr, const struct eth_addr *ethdst_addr, - const struct eth_addr *hwsrc_addr, const ip4_addr_t *ipsrc_addr, - const struct eth_addr *hwdst_addr, const ip4_addr_t *ipdst_addr, - const u16_t opcode); - -#if ARP_QUEUEING -/** - * Free a complete queue of etharp entries - * - * @param q a qeueue of etharp_q_entry's to free - */ -static void -free_etharp_q(struct etharp_q_entry *q) -{ - struct etharp_q_entry *r; - LWIP_ASSERT("q != NULL", q != NULL); - LWIP_ASSERT("q->p != NULL", q->p != NULL); - while (q) { - r = q; - q = q->next; - LWIP_ASSERT("r->p != NULL", (r->p != NULL)); - pbuf_free(r->p); - memp_free(MEMP_ARP_QUEUE, r); - } -} -#else /* ARP_QUEUEING */ - -/** Compatibility define: free the queued pbuf */ -#define free_etharp_q(q) pbuf_free(q) - -#endif /* ARP_QUEUEING */ - -/** Clean up ARP table entries */ -static void -etharp_free_entry(int i) -{ - /* remove from SNMP ARP index tree */ - mib2_remove_arp_entry(arp_table[i].netif, &arp_table[i].ipaddr); - /* and empty packet queue */ - if (arp_table[i].q != NULL) { - /* remove all queued packets */ - LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_free_entry: freeing entry %"U16_F", packet queue %p.\n", (u16_t)i, (void *)(arp_table[i].q))); - free_etharp_q(arp_table[i].q); - arp_table[i].q = NULL; - } - /* recycle entry for re-use */ - arp_table[i].state = ETHARP_STATE_EMPTY; -#ifdef LWIP_DEBUG - /* for debugging, clean out the complete entry */ - arp_table[i].ctime = 0; - arp_table[i].netif = NULL; - ip4_addr_set_zero(&arp_table[i].ipaddr); - arp_table[i].ethaddr = ethzero; -#endif /* LWIP_DEBUG */ -} - -/** - * Clears expired entries in the ARP table. - * - * This function should be called every ARP_TMR_INTERVAL milliseconds (1 second), - * in order to expire entries in the ARP table. - */ -void -etharp_tmr(void) -{ - u8_t i; - - LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer\n")); - /* remove expired entries from the ARP table */ - for (i = 0; i < ARP_TABLE_SIZE; ++i) { - u8_t state = arp_table[i].state; - if (state != ETHARP_STATE_EMPTY -#if ETHARP_SUPPORT_STATIC_ENTRIES - && (state != ETHARP_STATE_STATIC) -#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ - ) { - arp_table[i].ctime++; - if ((arp_table[i].ctime >= ARP_MAXAGE) || - ((arp_table[i].state == ETHARP_STATE_PENDING) && - (arp_table[i].ctime >= ARP_MAXPENDING))) { - /* pending or stable entry has become old! */ - LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_timer: expired %s entry %"U16_F".\n", - arp_table[i].state >= ETHARP_STATE_STABLE ? "stable" : "pending", (u16_t)i)); - /* clean up entries that have just been expired */ - etharp_free_entry(i); - } else if (arp_table[i].state == ETHARP_STATE_STABLE_REREQUESTING_1) { - /* Don't send more than one request every 2 seconds. */ - arp_table[i].state = ETHARP_STATE_STABLE_REREQUESTING_2; - } else if (arp_table[i].state == ETHARP_STATE_STABLE_REREQUESTING_2) { - /* Reset state to stable, so that the next transmitted packet will - re-send an ARP request. */ - arp_table[i].state = ETHARP_STATE_STABLE; - } else if (arp_table[i].state == ETHARP_STATE_PENDING) { - /* still pending, resend an ARP query */ - etharp_request(arp_table[i].netif, &arp_table[i].ipaddr); - } - } - } -} - -/** - * Search the ARP table for a matching or new entry. - * - * If an IP address is given, return a pending or stable ARP entry that matches - * the address. If no match is found, create a new entry with this address set, - * but in state ETHARP_EMPTY. The caller must check and possibly change the - * state of the returned entry. - * - * If ipaddr is NULL, return a initialized new entry in state ETHARP_EMPTY. - * - * In all cases, attempt to create new entries from an empty entry. If no - * empty entries are available and ETHARP_FLAG_TRY_HARD flag is set, recycle - * old entries. Heuristic choose the least important entry for recycling. - * - * @param ipaddr IP address to find in ARP cache, or to add if not found. - * @param flags See @ref etharp_state - * @param netif netif related to this address (used for NETIF_HWADDRHINT) - * - * @return The ARP entry index that matched or is created, ERR_MEM if no - * entry is found or could be recycled. - */ -static s8_t -etharp_find_entry(const ip4_addr_t *ipaddr, u8_t flags, struct netif* netif) -{ - s8_t old_pending = ARP_TABLE_SIZE, old_stable = ARP_TABLE_SIZE; - s8_t empty = ARP_TABLE_SIZE; - u8_t i = 0; - /* oldest entry with packets on queue */ - s8_t old_queue = ARP_TABLE_SIZE; - /* its age */ - u16_t age_queue = 0, age_pending = 0, age_stable = 0; - - LWIP_UNUSED_ARG(netif); - - /** - * a) do a search through the cache, remember candidates - * b) select candidate entry - * c) create new entry - */ - - /* a) in a single search sweep, do all of this - * 1) remember the first empty entry (if any) - * 2) remember the oldest stable entry (if any) - * 3) remember the oldest pending entry without queued packets (if any) - * 4) remember the oldest pending entry with queued packets (if any) - * 5) search for a matching IP entry, either pending or stable - * until 5 matches, or all entries are searched for. - */ - - for (i = 0; i < ARP_TABLE_SIZE; ++i) { - u8_t state = arp_table[i].state; - /* no empty entry found yet and now we do find one? */ - if ((empty == ARP_TABLE_SIZE) && (state == ETHARP_STATE_EMPTY)) { - LWIP_DEBUGF(ETHARP_DEBUG, ("etharp_find_entry: found empty entry %"U16_F"\n", (u16_t)i)); - /* remember first empty entry */ - empty = i; - } else if (state != ETHARP_STATE_EMPTY) { - LWIP_ASSERT("state == ETHARP_STATE_PENDING || state >= ETHARP_STATE_STABLE", - state == ETHARP_STATE_PENDING || state >= ETHARP_STATE_STABLE); - /* if given, does IP address match IP address in ARP entry? */ - if (ipaddr && ip4_addr_cmp(ipaddr, &arp_table[i].ipaddr) -#if ETHARP_TABLE_MATCH_NETIF - && ((netif == NULL) || (netif == arp_table[i].netif)) -#endif /* ETHARP_TABLE_MATCH_NETIF */ - ) { - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: found matching entry %"U16_F"\n", (u16_t)i)); - /* found exact IP address match, simply bail out */ - return i; - } - /* pending entry? */ - if (state == ETHARP_STATE_PENDING) { - /* pending with queued packets? */ - if (arp_table[i].q != NULL) { - if (arp_table[i].ctime >= age_queue) { - old_queue = i; - age_queue = arp_table[i].ctime; - } - } else - /* pending without queued packets? */ - { - if (arp_table[i].ctime >= age_pending) { - old_pending = i; - age_pending = arp_table[i].ctime; - } - } - /* stable entry? */ - } else if (state >= ETHARP_STATE_STABLE) { -#if ETHARP_SUPPORT_STATIC_ENTRIES - /* don't record old_stable for static entries since they never expire */ - if (state < ETHARP_STATE_STATIC) -#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ - { - /* remember entry with oldest stable entry in oldest, its age in maxtime */ - if (arp_table[i].ctime >= age_stable) { - old_stable = i; - age_stable = arp_table[i].ctime; - } - } - } - } - } - /* { we have no match } => try to create a new entry */ - - /* don't create new entry, only search? */ - if (((flags & ETHARP_FLAG_FIND_ONLY) != 0) || - /* or no empty entry found and not allowed to recycle? */ - ((empty == ARP_TABLE_SIZE) && ((flags & ETHARP_FLAG_TRY_HARD) == 0))) { - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: no empty entry found and not allowed to recycle\n")); - return (s8_t)ERR_MEM; - } - - /* b) choose the least destructive entry to recycle: - * 1) empty entry - * 2) oldest stable entry - * 3) oldest pending entry without queued packets - * 4) oldest pending entry with queued packets - * - * { ETHARP_FLAG_TRY_HARD is set at this point } - */ - - /* 1) empty entry available? */ - if (empty < ARP_TABLE_SIZE) { - i = empty; - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: selecting empty entry %"U16_F"\n", (u16_t)i)); - } else { - /* 2) found recyclable stable entry? */ - if (old_stable < ARP_TABLE_SIZE) { - /* recycle oldest stable*/ - i = old_stable; - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: selecting oldest stable entry %"U16_F"\n", (u16_t)i)); - /* no queued packets should exist on stable entries */ - LWIP_ASSERT("arp_table[i].q == NULL", arp_table[i].q == NULL); - /* 3) found recyclable pending entry without queued packets? */ - } else if (old_pending < ARP_TABLE_SIZE) { - /* recycle oldest pending */ - i = old_pending; - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: selecting oldest pending entry %"U16_F" (without queue)\n", (u16_t)i)); - /* 4) found recyclable pending entry with queued packets? */ - } else if (old_queue < ARP_TABLE_SIZE) { - /* recycle oldest pending (queued packets are free in etharp_free_entry) */ - i = old_queue; - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: selecting oldest pending entry %"U16_F", freeing packet queue %p\n", (u16_t)i, (void *)(arp_table[i].q))); - /* no empty or recyclable entries found */ - } else { - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_find_entry: no empty or recyclable entries found\n")); - return (s8_t)ERR_MEM; - } - - /* { empty or recyclable entry found } */ - LWIP_ASSERT("i < ARP_TABLE_SIZE", i < ARP_TABLE_SIZE); - etharp_free_entry(i); - } - - LWIP_ASSERT("i < ARP_TABLE_SIZE", i < ARP_TABLE_SIZE); - LWIP_ASSERT("arp_table[i].state == ETHARP_STATE_EMPTY", - arp_table[i].state == ETHARP_STATE_EMPTY); - - /* IP address given? */ - if (ipaddr != NULL) { - /* set IP address */ - ip4_addr_copy(arp_table[i].ipaddr, *ipaddr); - } - arp_table[i].ctime = 0; -#if ETHARP_TABLE_MATCH_NETIF - arp_table[i].netif = netif; -#endif /* ETHARP_TABLE_MATCH_NETIF*/ - return (err_t)i; -} - -/** - * Update (or insert) a IP/MAC address pair in the ARP cache. - * - * If a pending entry is resolved, any queued packets will be sent - * at this point. - * - * @param netif netif related to this entry (used for NETIF_ADDRHINT) - * @param ipaddr IP address of the inserted ARP entry. - * @param ethaddr Ethernet address of the inserted ARP entry. - * @param flags See @ref etharp_state - * - * @return - * - ERR_OK Successfully updated ARP cache. - * - ERR_MEM If we could not add a new ARP entry when ETHARP_FLAG_TRY_HARD was set. - * - ERR_ARG Non-unicast address given, those will not appear in ARP cache. - * - * @see pbuf_free() - */ -static err_t -etharp_update_arp_entry(struct netif *netif, const ip4_addr_t *ipaddr, struct eth_addr *ethaddr, u8_t flags) -{ - s8_t i; - LWIP_ASSERT("netif->hwaddr_len == ETH_HWADDR_LEN", netif->hwaddr_len == ETH_HWADDR_LEN); - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_update_arp_entry: %"U16_F".%"U16_F".%"U16_F".%"U16_F" - %02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F"\n", - ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr), - (u16_t)ethaddr->addr[0], (u16_t)ethaddr->addr[1], (u16_t)ethaddr->addr[2], - (u16_t)ethaddr->addr[3], (u16_t)ethaddr->addr[4], (u16_t)ethaddr->addr[5])); - /* non-unicast address? */ - if (ip4_addr_isany(ipaddr) || - ip4_addr_isbroadcast(ipaddr, netif) || - ip4_addr_ismulticast(ipaddr)) { - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_update_arp_entry: will not add non-unicast IP address to ARP cache\n")); - return ERR_ARG; - } - /* find or create ARP entry */ - i = etharp_find_entry(ipaddr, flags, netif); - /* bail out if no entry could be found */ - if (i < 0) { - return (err_t)i; - } - -#if ETHARP_SUPPORT_STATIC_ENTRIES - if (flags & ETHARP_FLAG_STATIC_ENTRY) { - /* record static type */ - arp_table[i].state = ETHARP_STATE_STATIC; - } else if (arp_table[i].state == ETHARP_STATE_STATIC) { - /* found entry is a static type, don't overwrite it */ - return ERR_VAL; - } else -#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ - { - /* mark it stable */ - arp_table[i].state = ETHARP_STATE_STABLE; - } - - /* record network interface */ - arp_table[i].netif = netif; - /* insert in SNMP ARP index tree */ - mib2_add_arp_entry(netif, &arp_table[i].ipaddr); - - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_update_arp_entry: updating stable entry %"S16_F"\n", (s16_t)i)); - /* update address */ - ETHADDR32_COPY(&arp_table[i].ethaddr, ethaddr); - /* reset time stamp */ - arp_table[i].ctime = 0; - /* this is where we will send out queued packets! */ -#if ARP_QUEUEING - while (arp_table[i].q != NULL) { - struct pbuf *p; - /* remember remainder of queue */ - struct etharp_q_entry *q = arp_table[i].q; - /* pop first item off the queue */ - arp_table[i].q = q->next; - /* get the packet pointer */ - p = q->p; - /* now queue entry can be freed */ - memp_free(MEMP_ARP_QUEUE, q); -#else /* ARP_QUEUEING */ - if (arp_table[i].q != NULL) { - struct pbuf *p = arp_table[i].q; - arp_table[i].q = NULL; -#endif /* ARP_QUEUEING */ - /* send the queued IP packet */ - ethernet_output(netif, p, (struct eth_addr*)(netif->hwaddr), ethaddr, ETHTYPE_IP); - /* free the queued IP packet */ - pbuf_free(p); - } - return ERR_OK; -} - -#if ETHARP_SUPPORT_STATIC_ENTRIES -/** Add a new static entry to the ARP table. If an entry exists for the - * specified IP address, this entry is overwritten. - * If packets are queued for the specified IP address, they are sent out. - * - * @param ipaddr IP address for the new static entry - * @param ethaddr ethernet address for the new static entry - * @return See return values of etharp_add_static_entry - */ -err_t -etharp_add_static_entry(const ip4_addr_t *ipaddr, struct eth_addr *ethaddr) -{ - struct netif *netif; - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_add_static_entry: %"U16_F".%"U16_F".%"U16_F".%"U16_F" - %02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F"\n", - ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr), - (u16_t)ethaddr->addr[0], (u16_t)ethaddr->addr[1], (u16_t)ethaddr->addr[2], - (u16_t)ethaddr->addr[3], (u16_t)ethaddr->addr[4], (u16_t)ethaddr->addr[5])); - - netif = ip4_route(ipaddr); - if (netif == NULL) { - return ERR_RTE; - } - - return etharp_update_arp_entry(netif, ipaddr, ethaddr, ETHARP_FLAG_TRY_HARD | ETHARP_FLAG_STATIC_ENTRY); -} - -/** Remove a static entry from the ARP table previously added with a call to - * etharp_add_static_entry. - * - * @param ipaddr IP address of the static entry to remove - * @return ERR_OK: entry removed - * ERR_MEM: entry wasn't found - * ERR_ARG: entry wasn't a static entry but a dynamic one - */ -err_t -etharp_remove_static_entry(const ip4_addr_t *ipaddr) -{ - s8_t i; - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_remove_static_entry: %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", - ip4_addr1_16(ipaddr), ip4_addr2_16(ipaddr), ip4_addr3_16(ipaddr), ip4_addr4_16(ipaddr))); - - /* find or create ARP entry */ - i = etharp_find_entry(ipaddr, ETHARP_FLAG_FIND_ONLY, NULL); - /* bail out if no entry could be found */ - if (i < 0) { - return (err_t)i; - } - - if (arp_table[i].state != ETHARP_STATE_STATIC) { - /* entry wasn't a static entry, cannot remove it */ - return ERR_ARG; - } - /* entry found, free it */ - etharp_free_entry(i); - return ERR_OK; -} -#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ - -/** - * Remove all ARP table entries of the specified netif. - * - * @param netif points to a network interface - */ -void -etharp_cleanup_netif(struct netif *netif) -{ - u8_t i; - - for (i = 0; i < ARP_TABLE_SIZE; ++i) { - u8_t state = arp_table[i].state; - if ((state != ETHARP_STATE_EMPTY) && (arp_table[i].netif == netif)) { - etharp_free_entry(i); - } - } -} - -/** - * Finds (stable) ethernet/IP address pair from ARP table - * using interface and IP address index. - * @note the addresses in the ARP table are in network order! - * - * @param netif points to interface index - * @param ipaddr points to the (network order) IP address index - * @param eth_ret points to return pointer - * @param ip_ret points to return pointer - * @return table index if found, -1 otherwise - */ -s8_t -etharp_find_addr(struct netif *netif, const ip4_addr_t *ipaddr, - struct eth_addr **eth_ret, const ip4_addr_t **ip_ret) -{ - s8_t i; - - LWIP_ASSERT("eth_ret != NULL && ip_ret != NULL", - eth_ret != NULL && ip_ret != NULL); - - LWIP_UNUSED_ARG(netif); - - i = etharp_find_entry(ipaddr, ETHARP_FLAG_FIND_ONLY, netif); - if ((i >= 0) && (arp_table[i].state >= ETHARP_STATE_STABLE)) { - *eth_ret = &arp_table[i].ethaddr; - *ip_ret = &arp_table[i].ipaddr; - return i; - } - return -1; -} - -/** - * Possibility to iterate over stable ARP table entries - * - * @param i entry number, 0 to ARP_TABLE_SIZE - * @param ipaddr return value: IP address - * @param netif return value: points to interface - * @param eth_ret return value: ETH address - * @return 1 on valid index, 0 otherwise - */ -u8_t -etharp_get_entry(u8_t i, ip4_addr_t **ipaddr, struct netif **netif, struct eth_addr **eth_ret) -{ - LWIP_ASSERT("ipaddr != NULL", ipaddr != NULL); - LWIP_ASSERT("netif != NULL", netif != NULL); - LWIP_ASSERT("eth_ret != NULL", eth_ret != NULL); - - if((i < ARP_TABLE_SIZE) && (arp_table[i].state >= ETHARP_STATE_STABLE)) { - *ipaddr = &arp_table[i].ipaddr; - *netif = arp_table[i].netif; - *eth_ret = &arp_table[i].ethaddr; - return 1; - } else { - return 0; - } -} - -/** - * Responds to ARP requests to us. Upon ARP replies to us, add entry to cache - * send out queued IP packets. Updates cache with snooped address pairs. - * - * Should be called for incoming ARP packets. The pbuf in the argument - * is freed by this function. - * - * @param p The ARP packet that arrived on netif. Is freed by this function. - * @param netif The lwIP network interface on which the ARP packet pbuf arrived. - * - * @see pbuf_free() - */ -void -etharp_input(struct pbuf *p, struct netif *netif) -{ - struct etharp_hdr *hdr; - /* these are aligned properly, whereas the ARP header fields might not be */ - ip4_addr_t sipaddr, dipaddr; - u8_t for_us; - - LWIP_ERROR("netif != NULL", (netif != NULL), return;); - - hdr = (struct etharp_hdr *)p->payload; - - /* RFC 826 "Packet Reception": */ - if ((hdr->hwtype != PP_HTONS(HWTYPE_ETHERNET)) || - (hdr->hwlen != ETH_HWADDR_LEN) || - (hdr->protolen != sizeof(ip4_addr_t)) || - (hdr->proto != PP_HTONS(ETHTYPE_IP))) { - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, - ("etharp_input: packet dropped, wrong hw type, hwlen, proto, protolen or ethernet type (%"U16_F"/%"U16_F"/%"U16_F"/%"U16_F")\n", - hdr->hwtype, (u16_t)hdr->hwlen, hdr->proto, (u16_t)hdr->protolen)); - ETHARP_STATS_INC(etharp.proterr); - ETHARP_STATS_INC(etharp.drop); - pbuf_free(p); - return; - } - ETHARP_STATS_INC(etharp.recv); - -#if LWIP_AUTOIP - /* We have to check if a host already has configured our random - * created link local address and continuously check if there is - * a host with this IP-address so we can detect collisions */ - autoip_arp_reply(netif, hdr); -#endif /* LWIP_AUTOIP */ - - /* Copy struct ip4_addr2 to aligned ip4_addr, to support compilers without - * structure packing (not using structure copy which breaks strict-aliasing rules). */ - IPADDR2_COPY(&sipaddr, &hdr->sipaddr); - IPADDR2_COPY(&dipaddr, &hdr->dipaddr); - - /* this interface is not configured? */ - if (ip4_addr_isany_val(*netif_ip4_addr(netif))) { - for_us = 0; - } else { - /* ARP packet directed to us? */ - for_us = (u8_t)ip4_addr_cmp(&dipaddr, netif_ip4_addr(netif)); - } - - /* ARP message directed to us? - -> add IP address in ARP cache; assume requester wants to talk to us, - can result in directly sending the queued packets for this host. - ARP message not directed to us? - -> update the source IP address in the cache, if present */ - etharp_update_arp_entry(netif, &sipaddr, &(hdr->shwaddr), - for_us ? ETHARP_FLAG_TRY_HARD : ETHARP_FLAG_FIND_ONLY); - - /* now act on the message itself */ - switch (hdr->opcode) { - /* ARP request? */ - case PP_HTONS(ARP_REQUEST): - /* ARP request. If it asked for our address, we send out a - * reply. In any case, we time-stamp any existing ARP entry, - * and possibly send out an IP packet that was queued on it. */ - - LWIP_DEBUGF (ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_input: incoming ARP request\n")); - /* ARP request for our address? */ - if (for_us) { - /* send ARP response */ - etharp_raw(netif, - (struct eth_addr *)netif->hwaddr, &hdr->shwaddr, - (struct eth_addr *)netif->hwaddr, netif_ip4_addr(netif), - &hdr->shwaddr, &sipaddr, - ARP_REPLY); - /* we are not configured? */ - } else if (ip4_addr_isany_val(*netif_ip4_addr(netif))) { - /* { for_us == 0 and netif->ip_addr.addr == 0 } */ - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_input: we are unconfigured, ARP request ignored.\n")); - /* request was not directed to us */ - } else { - /* { for_us == 0 and netif->ip_addr.addr != 0 } */ - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_input: ARP request was not for us.\n")); - } - break; - case PP_HTONS(ARP_REPLY): - /* ARP reply. We already updated the ARP cache earlier. */ - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_input: incoming ARP reply\n")); -#if (LWIP_DHCP && DHCP_DOES_ARP_CHECK) - /* DHCP wants to know about ARP replies from any host with an - * IP address also offered to us by the DHCP server. We do not - * want to take a duplicate IP address on a single network. - * @todo How should we handle redundant (fail-over) interfaces? */ - dhcp_arp_reply(netif, &sipaddr); -#endif /* (LWIP_DHCP && DHCP_DOES_ARP_CHECK) */ - break; - default: - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_input: ARP unknown opcode type %"S16_F"\n", lwip_htons(hdr->opcode))); - ETHARP_STATS_INC(etharp.err); - break; - } - /* free ARP packet */ - pbuf_free(p); -} - -/** Just a small helper function that sends a pbuf to an ethernet address - * in the arp_table specified by the index 'arp_idx'. - */ -static err_t -etharp_output_to_arp_index(struct netif *netif, struct pbuf *q, u8_t arp_idx) -{ - LWIP_ASSERT("arp_table[arp_idx].state >= ETHARP_STATE_STABLE", - arp_table[arp_idx].state >= ETHARP_STATE_STABLE); - /* if arp table entry is about to expire: re-request it, - but only if its state is ETHARP_STATE_STABLE to prevent flooding the - network with ARP requests if this address is used frequently. */ - if (arp_table[arp_idx].state == ETHARP_STATE_STABLE) { - if (arp_table[arp_idx].ctime >= ARP_AGE_REREQUEST_USED_BROADCAST) { - /* issue a standard request using broadcast */ - if (etharp_request(netif, &arp_table[arp_idx].ipaddr) == ERR_OK) { - arp_table[arp_idx].state = ETHARP_STATE_STABLE_REREQUESTING_1; - } - } else if (arp_table[arp_idx].ctime >= ARP_AGE_REREQUEST_USED_UNICAST) { - /* issue a unicast request (for 15 seconds) to prevent unnecessary broadcast */ - if (etharp_request_dst(netif, &arp_table[arp_idx].ipaddr, &arp_table[arp_idx].ethaddr) == ERR_OK) { - arp_table[arp_idx].state = ETHARP_STATE_STABLE_REREQUESTING_1; - } - } - } - - return ethernet_output(netif, q, (struct eth_addr*)(netif->hwaddr), &arp_table[arp_idx].ethaddr, ETHTYPE_IP); -} - -/** - * Resolve and fill-in Ethernet address header for outgoing IP packet. - * - * For IP multicast and broadcast, corresponding Ethernet addresses - * are selected and the packet is transmitted on the link. - * - * For unicast addresses, the packet is submitted to etharp_query(). In - * case the IP address is outside the local network, the IP address of - * the gateway is used. - * - * @param netif The lwIP network interface which the IP packet will be sent on. - * @param q The pbuf(s) containing the IP packet to be sent. - * @param ipaddr The IP address of the packet destination. - * - * @return - * - ERR_RTE No route to destination (no gateway to external networks), - * or the return type of either etharp_query() or ethernet_output(). - */ -err_t -etharp_output(struct netif *netif, struct pbuf *q, const ip4_addr_t *ipaddr) -{ - const struct eth_addr *dest; - struct eth_addr mcastaddr; - const ip4_addr_t *dst_addr = ipaddr; - - LWIP_ASSERT("netif != NULL", netif != NULL); - LWIP_ASSERT("q != NULL", q != NULL); - LWIP_ASSERT("ipaddr != NULL", ipaddr != NULL); - - /* Determine on destination hardware address. Broadcasts and multicasts - * are special, other IP addresses are looked up in the ARP table. */ - - /* broadcast destination IP address? */ - if (ip4_addr_isbroadcast(ipaddr, netif)) { - /* broadcast on Ethernet also */ - dest = ðbroadcast; - /* multicast destination IP address? */ - } else if (ip4_addr_ismulticast(ipaddr)) { - /* Hash IP multicast address to MAC address.*/ - mcastaddr.addr[0] = LL_IP4_MULTICAST_ADDR_0; - mcastaddr.addr[1] = LL_IP4_MULTICAST_ADDR_1; - mcastaddr.addr[2] = LL_IP4_MULTICAST_ADDR_2; - mcastaddr.addr[3] = ip4_addr2(ipaddr) & 0x7f; - mcastaddr.addr[4] = ip4_addr3(ipaddr); - mcastaddr.addr[5] = ip4_addr4(ipaddr); - /* destination Ethernet address is multicast */ - dest = &mcastaddr; - /* unicast destination IP address? */ - } else { - s8_t i; - /* outside local network? if so, this can neither be a global broadcast nor - a subnet broadcast. */ - if (!ip4_addr_netcmp(ipaddr, netif_ip4_addr(netif), netif_ip4_netmask(netif)) && - !ip4_addr_islinklocal(ipaddr)) { -#if LWIP_AUTOIP - struct ip_hdr *iphdr = LWIP_ALIGNMENT_CAST(struct ip_hdr*, q->payload); - /* According to RFC 3297, chapter 2.6.2 (Forwarding Rules), a packet with - a link-local source address must always be "directly to its destination - on the same physical link. The host MUST NOT send the packet to any - router for forwarding". */ - if (!ip4_addr_islinklocal(&iphdr->src)) -#endif /* LWIP_AUTOIP */ - { -#ifdef LWIP_HOOK_ETHARP_GET_GW - /* For advanced routing, a single default gateway might not be enough, so get - the IP address of the gateway to handle the current destination address. */ - dst_addr = LWIP_HOOK_ETHARP_GET_GW(netif, ipaddr); - if (dst_addr == NULL) -#endif /* LWIP_HOOK_ETHARP_GET_GW */ - { - /* interface has default gateway? */ - if (!ip4_addr_isany_val(*netif_ip4_gw(netif))) { - /* send to hardware address of default gateway IP address */ - dst_addr = netif_ip4_gw(netif); - /* no default gateway available */ - } else { - /* no route to destination error (default gateway missing) */ - return ERR_RTE; - } - } - } - } -#if LWIP_NETIF_HWADDRHINT - if (netif->addr_hint != NULL) { - /* per-pcb cached entry was given */ - u8_t etharp_cached_entry = *(netif->addr_hint); - if (etharp_cached_entry < ARP_TABLE_SIZE) { -#endif /* LWIP_NETIF_HWADDRHINT */ - if ((arp_table[etharp_cached_entry].state >= ETHARP_STATE_STABLE) && -#if ETHARP_TABLE_MATCH_NETIF - (arp_table[etharp_cached_entry].netif == netif) && -#endif - (ip4_addr_cmp(dst_addr, &arp_table[etharp_cached_entry].ipaddr))) { - /* the per-pcb-cached entry is stable and the right one! */ - ETHARP_STATS_INC(etharp.cachehit); - return etharp_output_to_arp_index(netif, q, etharp_cached_entry); - } -#if LWIP_NETIF_HWADDRHINT - } - } -#endif /* LWIP_NETIF_HWADDRHINT */ - - /* find stable entry: do this here since this is a critical path for - throughput and etharp_find_entry() is kind of slow */ - for (i = 0; i < ARP_TABLE_SIZE; i++) { - if ((arp_table[i].state >= ETHARP_STATE_STABLE) && -#if ETHARP_TABLE_MATCH_NETIF - (arp_table[i].netif == netif) && -#endif - (ip4_addr_cmp(dst_addr, &arp_table[i].ipaddr))) { - /* found an existing, stable entry */ - ETHARP_SET_HINT(netif, i); - return etharp_output_to_arp_index(netif, q, i); - } - } - /* no stable entry found, use the (slower) query function: - queue on destination Ethernet address belonging to ipaddr */ - return etharp_query(netif, dst_addr, q); - } - - /* continuation for multicast/broadcast destinations */ - /* obtain source Ethernet address of the given interface */ - /* send packet directly on the link */ - return ethernet_output(netif, q, (struct eth_addr*)(netif->hwaddr), dest, ETHTYPE_IP); -} - -/** - * Send an ARP request for the given IP address and/or queue a packet. - * - * If the IP address was not yet in the cache, a pending ARP cache entry - * is added and an ARP request is sent for the given address. The packet - * is queued on this entry. - * - * If the IP address was already pending in the cache, a new ARP request - * is sent for the given address. The packet is queued on this entry. - * - * If the IP address was already stable in the cache, and a packet is - * given, it is directly sent and no ARP request is sent out. - * - * If the IP address was already stable in the cache, and no packet is - * given, an ARP request is sent out. - * - * @param netif The lwIP network interface on which ipaddr - * must be queried for. - * @param ipaddr The IP address to be resolved. - * @param q If non-NULL, a pbuf that must be delivered to the IP address. - * q is not freed by this function. - * - * @note q must only be ONE packet, not a packet queue! - * - * @return - * - ERR_BUF Could not make room for Ethernet header. - * - ERR_MEM Hardware address unknown, and no more ARP entries available - * to query for address or queue the packet. - * - ERR_MEM Could not queue packet due to memory shortage. - * - ERR_RTE No route to destination (no gateway to external networks). - * - ERR_ARG Non-unicast address given, those will not appear in ARP cache. - * - */ -err_t -etharp_query(struct netif *netif, const ip4_addr_t *ipaddr, struct pbuf *q) -{ - struct eth_addr * srcaddr = (struct eth_addr *)netif->hwaddr; - err_t result = ERR_MEM; - int is_new_entry = 0; - s8_t i; /* ARP entry index */ - - /* non-unicast address? */ - if (ip4_addr_isbroadcast(ipaddr, netif) || - ip4_addr_ismulticast(ipaddr) || - ip4_addr_isany(ipaddr)) { - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: will not add non-unicast IP address to ARP cache\n")); - return ERR_ARG; - } - - /* find entry in ARP cache, ask to create entry if queueing packet */ - i = etharp_find_entry(ipaddr, ETHARP_FLAG_TRY_HARD, netif); - - /* could not find or create entry? */ - if (i < 0) { - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: could not create ARP entry\n")); - if (q) { - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: packet dropped\n")); - ETHARP_STATS_INC(etharp.memerr); - } - return (err_t)i; - } - - /* mark a fresh entry as pending (we just sent a request) */ - if (arp_table[i].state == ETHARP_STATE_EMPTY) { - is_new_entry = 1; - arp_table[i].state = ETHARP_STATE_PENDING; - /* record network interface for re-sending arp request in etharp_tmr */ - arp_table[i].netif = netif; - } - - /* { i is either a STABLE or (new or existing) PENDING entry } */ - LWIP_ASSERT("arp_table[i].state == PENDING or STABLE", - ((arp_table[i].state == ETHARP_STATE_PENDING) || - (arp_table[i].state >= ETHARP_STATE_STABLE))); - - /* do we have a new entry? or an implicit query request? */ - if (is_new_entry || (q == NULL)) { - /* try to resolve it; send out ARP request */ - result = etharp_request(netif, ipaddr); - if (result != ERR_OK) { - /* ARP request couldn't be sent */ - /* We don't re-send arp request in etharp_tmr, but we still queue packets, - since this failure could be temporary, and the next packet calling - etharp_query again could lead to sending the queued packets. */ - } - if (q == NULL) { - return result; - } - } - - /* packet given? */ - LWIP_ASSERT("q != NULL", q != NULL); - /* stable entry? */ - if (arp_table[i].state >= ETHARP_STATE_STABLE) { - /* we have a valid IP->Ethernet address mapping */ - ETHARP_SET_HINT(netif, i); - /* send the packet */ - result = ethernet_output(netif, q, srcaddr, &(arp_table[i].ethaddr), ETHTYPE_IP); - /* pending entry? (either just created or already pending */ - } else if (arp_table[i].state == ETHARP_STATE_PENDING) { - /* entry is still pending, queue the given packet 'q' */ - struct pbuf *p; - int copy_needed = 0; - /* IF q includes a PBUF_REF, PBUF_POOL or PBUF_RAM, we have no choice but - * to copy the whole queue into a new PBUF_RAM (see bug #11400) - * PBUF_ROMs can be left as they are, since ROM must not get changed. */ - p = q; - while (p) { - LWIP_ASSERT("no packet queues allowed!", (p->len != p->tot_len) || (p->next == 0)); - if (p->type != PBUF_ROM) { - copy_needed = 1; - break; - } - p = p->next; - } - if (copy_needed) { - /* copy the whole packet into new pbufs */ - p = pbuf_alloc(PBUF_LINK, p->tot_len, PBUF_RAM); - if (p != NULL) { - if (pbuf_copy(p, q) != ERR_OK) { - pbuf_free(p); - p = NULL; - } - } - } else { - /* referencing the old pbuf is enough */ - p = q; - pbuf_ref(p); - } - /* packet could be taken over? */ - if (p != NULL) { - /* queue packet ... */ -#if ARP_QUEUEING - struct etharp_q_entry *new_entry; - /* allocate a new arp queue entry */ - new_entry = (struct etharp_q_entry *)memp_malloc(MEMP_ARP_QUEUE); - if (new_entry != NULL) { - unsigned int qlen = 0; - new_entry->next = 0; - new_entry->p = p; - if (arp_table[i].q != NULL) { - /* queue was already existent, append the new entry to the end */ - struct etharp_q_entry *r; - r = arp_table[i].q; - qlen++; - while (r->next != NULL) { - r = r->next; - qlen++; - } - r->next = new_entry; - } else { - /* queue did not exist, first item in queue */ - arp_table[i].q = new_entry; - } -#if ARP_QUEUE_LEN - if (qlen >= ARP_QUEUE_LEN) { - struct etharp_q_entry *old; - old = arp_table[i].q; - arp_table[i].q = arp_table[i].q->next; - pbuf_free(old->p); - memp_free(MEMP_ARP_QUEUE, old); - } -#endif - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: queued packet %p on ARP entry %"S16_F"\n", (void *)q, (s16_t)i)); - result = ERR_OK; - } else { - /* the pool MEMP_ARP_QUEUE is empty */ - pbuf_free(p); - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: could not queue a copy of PBUF_REF packet %p (out of memory)\n", (void *)q)); - result = ERR_MEM; - } -#else /* ARP_QUEUEING */ - /* always queue one packet per ARP request only, freeing a previously queued packet */ - if (arp_table[i].q != NULL) { - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: dropped previously queued packet %p for ARP entry %"S16_F"\n", (void *)q, (s16_t)i)); - pbuf_free(arp_table[i].q); - } - arp_table[i].q = p; - result = ERR_OK; - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: queued packet %p on ARP entry %"S16_F"\n", (void *)q, (s16_t)i)); -#endif /* ARP_QUEUEING */ - } else { - ETHARP_STATS_INC(etharp.memerr); - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_query: could not queue a copy of PBUF_REF packet %p (out of memory)\n", (void *)q)); - result = ERR_MEM; - } - } - return result; -} - -/** - * Send a raw ARP packet (opcode and all addresses can be modified) - * - * @param netif the lwip network interface on which to send the ARP packet - * @param ethsrc_addr the source MAC address for the ethernet header - * @param ethdst_addr the destination MAC address for the ethernet header - * @param hwsrc_addr the source MAC address for the ARP protocol header - * @param ipsrc_addr the source IP address for the ARP protocol header - * @param hwdst_addr the destination MAC address for the ARP protocol header - * @param ipdst_addr the destination IP address for the ARP protocol header - * @param opcode the type of the ARP packet - * @return ERR_OK if the ARP packet has been sent - * ERR_MEM if the ARP packet couldn't be allocated - * any other err_t on failure - */ -static err_t -etharp_raw(struct netif *netif, const struct eth_addr *ethsrc_addr, - const struct eth_addr *ethdst_addr, - const struct eth_addr *hwsrc_addr, const ip4_addr_t *ipsrc_addr, - const struct eth_addr *hwdst_addr, const ip4_addr_t *ipdst_addr, - const u16_t opcode) -{ - struct pbuf *p; - err_t result = ERR_OK; - struct etharp_hdr *hdr; - - LWIP_ASSERT("netif != NULL", netif != NULL); - - /* allocate a pbuf for the outgoing ARP request packet */ - p = pbuf_alloc(PBUF_LINK, SIZEOF_ETHARP_HDR, PBUF_RAM); - /* could allocate a pbuf for an ARP request? */ - if (p == NULL) { - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, - ("etharp_raw: could not allocate pbuf for ARP request.\n")); - ETHARP_STATS_INC(etharp.memerr); - return ERR_MEM; - } - LWIP_ASSERT("check that first pbuf can hold struct etharp_hdr", - (p->len >= SIZEOF_ETHARP_HDR)); - - hdr = (struct etharp_hdr *)p->payload; - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_raw: sending raw ARP packet.\n")); - hdr->opcode = lwip_htons(opcode); - - LWIP_ASSERT("netif->hwaddr_len must be the same as ETH_HWADDR_LEN for etharp!", - (netif->hwaddr_len == ETH_HWADDR_LEN)); - - /* Write the ARP MAC-Addresses */ - ETHADDR16_COPY(&hdr->shwaddr, hwsrc_addr); - ETHADDR16_COPY(&hdr->dhwaddr, hwdst_addr); - /* Copy struct ip4_addr2 to aligned ip4_addr, to support compilers without - * structure packing. */ - IPADDR2_COPY(&hdr->sipaddr, ipsrc_addr); - IPADDR2_COPY(&hdr->dipaddr, ipdst_addr); - - hdr->hwtype = PP_HTONS(HWTYPE_ETHERNET); - hdr->proto = PP_HTONS(ETHTYPE_IP); - /* set hwlen and protolen */ - hdr->hwlen = ETH_HWADDR_LEN; - hdr->protolen = sizeof(ip4_addr_t); - - /* send ARP query */ -#if LWIP_AUTOIP - /* If we are using Link-Local, all ARP packets that contain a Link-Local - * 'sender IP address' MUST be sent using link-layer broadcast instead of - * link-layer unicast. (See RFC3927 Section 2.5, last paragraph) */ - if(ip4_addr_islinklocal(ipsrc_addr)) { - ethernet_output(netif, p, ethsrc_addr, ðbroadcast, ETHTYPE_ARP); - } else -#endif /* LWIP_AUTOIP */ - { - ethernet_output(netif, p, ethsrc_addr, ethdst_addr, ETHTYPE_ARP); - } - - ETHARP_STATS_INC(etharp.xmit); - /* free ARP query packet */ - pbuf_free(p); - p = NULL; - /* could not allocate pbuf for ARP request */ - - return result; -} - -/** - * Send an ARP request packet asking for ipaddr to a specific eth address. - * Used to send unicast request to refresh the ARP table just before an entry - * times out - * - * @param netif the lwip network interface on which to send the request - * @param ipaddr the IP address for which to ask - * @param hw_dst_addr the ethernet address to send this packet to - * @return ERR_OK if the request has been sent - * ERR_MEM if the ARP packet couldn't be allocated - * any other err_t on failure - */ -static err_t -etharp_request_dst(struct netif *netif, const ip4_addr_t *ipaddr, const struct eth_addr* hw_dst_addr) -{ - return etharp_raw(netif, (struct eth_addr *)netif->hwaddr, hw_dst_addr, - (struct eth_addr *)netif->hwaddr, netif_ip4_addr(netif), ðzero, - ipaddr, ARP_REQUEST); -} - -/** - * Send an ARP request packet asking for ipaddr. - * - * @param netif the lwip network interface on which to send the request - * @param ipaddr the IP address for which to ask - * @return ERR_OK if the request has been sent - * ERR_MEM if the ARP packet couldn't be allocated - * any other err_t on failure - */ -err_t -etharp_request(struct netif *netif, const ip4_addr_t *ipaddr) -{ - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("etharp_request: sending ARP request.\n")); - return etharp_request_dst(netif, ipaddr, ðbroadcast); -} -#endif /* LWIP_IPV4 && LWIP_ARP */ - -#endif /* LWIP_ARP || LWIP_ETHERNET */ diff --git a/third_party/lwip/repo/lwip/src/core/ipv4/icmp.c b/third_party/lwip/repo/lwip/src/core/ipv4/icmp.c deleted file mode 100644 index 5ee24eedfa1e81..00000000000000 --- a/third_party/lwip/repo/lwip/src/core/ipv4/icmp.c +++ /dev/null @@ -1,397 +0,0 @@ -/** - * @file - * ICMP - Internet Control Message Protocol - * - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ - -/* Some ICMP messages should be passed to the transport protocols. This - is not implemented. */ - -#include "lwip/opt.h" - -#if LWIP_IPV4 && LWIP_ICMP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/icmp.h" -#include "lwip/inet_chksum.h" -#include "lwip/ip.h" -#include "lwip/def.h" -#include "lwip/stats.h" - -#include - -#ifdef LWIP_HOOK_FILENAME -#include LWIP_HOOK_FILENAME -#endif - -/** Small optimization: set to 0 if incoming PBUF_POOL pbuf always can be - * used to modify and send a response packet (and to 1 if this is not the case, - * e.g. when link header is stripped of when receiving) */ -#ifndef LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN -#define LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN 1 -#endif /* LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN */ - -/* The amount of data from the original packet to return in a dest-unreachable */ -#define ICMP_DEST_UNREACH_DATASIZE 8 - -static void icmp_send_response(struct pbuf *p, u8_t type, u8_t code); - -/** - * Processes ICMP input packets, called from ip_input(). - * - * Currently only processes icmp echo requests and sends - * out the echo response. - * - * @param p the icmp echo request packet, p->payload pointing to the icmp header - * @param inp the netif on which this packet was received - */ -void -icmp_input(struct pbuf *p, struct netif *inp) -{ - u8_t type; -#ifdef LWIP_DEBUG - u8_t code; -#endif /* LWIP_DEBUG */ - struct icmp_echo_hdr *iecho; - const struct ip_hdr *iphdr_in; - u16_t hlen; - const ip4_addr_t* src; - - ICMP_STATS_INC(icmp.recv); - MIB2_STATS_INC(mib2.icmpinmsgs); - - iphdr_in = ip4_current_header(); - hlen = IPH_HL(iphdr_in) * 4; - if (hlen < IP_HLEN) { - LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: short IP header (%"S16_F" bytes) received\n", hlen)); - goto lenerr; - } - if (p->len < sizeof(u16_t)*2) { - LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: short ICMP (%"U16_F" bytes) received\n", p->tot_len)); - goto lenerr; - } - - type = *((u8_t *)p->payload); -#ifdef LWIP_DEBUG - code = *(((u8_t *)p->payload)+1); -#endif /* LWIP_DEBUG */ - switch (type) { - case ICMP_ER: - /* This is OK, echo reply might have been parsed by a raw PCB - (as obviously, an echo request has been sent, too). */ - MIB2_STATS_INC(mib2.icmpinechoreps); - break; - case ICMP_ECHO: - MIB2_STATS_INC(mib2.icmpinechos); - src = ip4_current_dest_addr(); - /* multicast destination address? */ - if (ip4_addr_ismulticast(ip4_current_dest_addr())) { -#if LWIP_MULTICAST_PING - /* For multicast, use address of receiving interface as source address */ - src = netif_ip4_addr(inp); -#else /* LWIP_MULTICAST_PING */ - LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: Not echoing to multicast pings\n")); - goto icmperr; -#endif /* LWIP_MULTICAST_PING */ - } - /* broadcast destination address? */ - if (ip4_addr_isbroadcast(ip4_current_dest_addr(), ip_current_netif())) { -#if LWIP_BROADCAST_PING - /* For broadcast, use address of receiving interface as source address */ - src = netif_ip4_addr(inp); -#else /* LWIP_BROADCAST_PING */ - LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: Not echoing to broadcast pings\n")); - goto icmperr; -#endif /* LWIP_BROADCAST_PING */ - } - LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ping\n")); - if (p->tot_len < sizeof(struct icmp_echo_hdr)) { - LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: bad ICMP echo received\n")); - goto lenerr; - } -#if CHECKSUM_CHECK_ICMP - IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_CHECK_ICMP) { - if (inet_chksum_pbuf(p) != 0) { - LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: checksum failed for received ICMP echo\n")); - pbuf_free(p); - ICMP_STATS_INC(icmp.chkerr); - MIB2_STATS_INC(mib2.icmpinerrors); - return; - } - } -#endif -#if LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN - if (pbuf_header(p, (s16_t)(hlen + PBUF_LINK_HLEN + PBUF_LINK_ENCAPSULATION_HLEN))) { - /* p is not big enough to contain link headers - * allocate a new one and copy p into it - */ - struct pbuf *r; - /* allocate new packet buffer with space for link headers */ - r = pbuf_alloc(PBUF_LINK, p->tot_len + hlen, PBUF_RAM); - if (r == NULL) { - LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: allocating new pbuf failed\n")); - goto icmperr; - } - if (r->len < hlen + sizeof(struct icmp_echo_hdr)) { - LWIP_DEBUGF(ICMP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("first pbuf cannot hold the ICMP header")); - pbuf_free(r); - goto icmperr; - } - /* copy the ip header */ - MEMCPY(r->payload, iphdr_in, hlen); - /* switch r->payload back to icmp header (cannot fail) */ - if (pbuf_header(r, (s16_t)-hlen)) { - LWIP_ASSERT("icmp_input: moving r->payload to icmp header failed\n", 0); - pbuf_free(r); - goto icmperr; - } - /* copy the rest of the packet without ip header */ - if (pbuf_copy(r, p) != ERR_OK) { - LWIP_DEBUGF(ICMP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("icmp_input: copying to new pbuf failed")); - pbuf_free(r); - goto icmperr; - } - /* free the original p */ - pbuf_free(p); - /* we now have an identical copy of p that has room for link headers */ - p = r; - } else { - /* restore p->payload to point to icmp header (cannot fail) */ - if (pbuf_header(p, -(s16_t)(hlen + PBUF_LINK_HLEN + PBUF_LINK_ENCAPSULATION_HLEN))) { - LWIP_ASSERT("icmp_input: restoring original p->payload failed\n", 0); - goto icmperr; - } - } -#endif /* LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN */ - /* At this point, all checks are OK. */ - /* We generate an answer by switching the dest and src ip addresses, - * setting the icmp type to ECHO_RESPONSE and updating the checksum. */ - iecho = (struct icmp_echo_hdr *)p->payload; - if (pbuf_header(p, (s16_t)hlen)) { - LWIP_DEBUGF(ICMP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("Can't move over header in packet")); - } else { - err_t ret; - struct ip_hdr *iphdr = (struct ip_hdr*)p->payload; - ip4_addr_copy(iphdr->src, *src); - ip4_addr_copy(iphdr->dest, *ip4_current_src_addr()); - ICMPH_TYPE_SET(iecho, ICMP_ER); -#if CHECKSUM_GEN_ICMP - IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_GEN_ICMP) { - /* adjust the checksum */ - if (iecho->chksum > PP_HTONS(0xffffU - (ICMP_ECHO << 8))) { - iecho->chksum += PP_HTONS(ICMP_ECHO << 8) + 1; - } else { - iecho->chksum += PP_HTONS(ICMP_ECHO << 8); - } - } -#if LWIP_CHECKSUM_CTRL_PER_NETIF - else { - iecho->chksum = 0; - } -#endif /* LWIP_CHECKSUM_CTRL_PER_NETIF */ -#else /* CHECKSUM_GEN_ICMP */ - iecho->chksum = 0; -#endif /* CHECKSUM_GEN_ICMP */ - - /* Set the correct TTL and recalculate the header checksum. */ - IPH_TTL_SET(iphdr, ICMP_TTL); - IPH_CHKSUM_SET(iphdr, 0); -#if CHECKSUM_GEN_IP - IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_GEN_IP) { - IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, hlen)); - } -#endif /* CHECKSUM_GEN_IP */ - - ICMP_STATS_INC(icmp.xmit); - /* increase number of messages attempted to send */ - MIB2_STATS_INC(mib2.icmpoutmsgs); - /* increase number of echo replies attempted to send */ - MIB2_STATS_INC(mib2.icmpoutechoreps); - - /* send an ICMP packet */ - ret = ip4_output_if(p, src, LWIP_IP_HDRINCL, - ICMP_TTL, 0, IP_PROTO_ICMP, inp); - if (ret != ERR_OK) { - LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ip_output_if returned an error: %s\n", lwip_strerr(ret))); - } - } - break; - default: - if (type == ICMP_DUR) { - MIB2_STATS_INC(mib2.icmpindestunreachs); - } else if (type == ICMP_TE) { - MIB2_STATS_INC(mib2.icmpintimeexcds); - } else if (type == ICMP_PP) { - MIB2_STATS_INC(mib2.icmpinparmprobs); - } else if (type == ICMP_SQ) { - MIB2_STATS_INC(mib2.icmpinsrcquenchs); - } else if (type == ICMP_RD) { - MIB2_STATS_INC(mib2.icmpinredirects); - } else if (type == ICMP_TS) { - MIB2_STATS_INC(mib2.icmpintimestamps); - } else if (type == ICMP_TSR) { - MIB2_STATS_INC(mib2.icmpintimestampreps); - } else if (type == ICMP_AM) { - MIB2_STATS_INC(mib2.icmpinaddrmasks); - } else if (type == ICMP_AMR) { - MIB2_STATS_INC(mib2.icmpinaddrmaskreps); - } - LWIP_DEBUGF(ICMP_DEBUG, ("icmp_input: ICMP type %"S16_F" code %"S16_F" not supported.\n", - (s16_t)type, (s16_t)code)); - ICMP_STATS_INC(icmp.proterr); - ICMP_STATS_INC(icmp.drop); - } - pbuf_free(p); - return; -lenerr: - pbuf_free(p); - ICMP_STATS_INC(icmp.lenerr); - MIB2_STATS_INC(mib2.icmpinerrors); - return; -#if LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN || !LWIP_MULTICAST_PING || !LWIP_BROADCAST_PING -icmperr: - pbuf_free(p); - ICMP_STATS_INC(icmp.err); - MIB2_STATS_INC(mib2.icmpinerrors); - return; -#endif /* LWIP_ICMP_ECHO_CHECK_INPUT_PBUF_LEN || !LWIP_MULTICAST_PING || !LWIP_BROADCAST_PING */ -} - -/** - * Send an icmp 'destination unreachable' packet, called from ip_input() if - * the transport layer protocol is unknown and from udp_input() if the local - * port is not bound. - * - * @param p the input packet for which the 'unreachable' should be sent, - * p->payload pointing to the IP header - * @param t type of the 'unreachable' packet - */ -void -icmp_dest_unreach(struct pbuf *p, enum icmp_dur_type t) -{ - MIB2_STATS_INC(mib2.icmpoutdestunreachs); - icmp_send_response(p, ICMP_DUR, t); -} - -#if IP_FORWARD || IP_REASSEMBLY -/** - * Send a 'time exceeded' packet, called from ip_forward() if TTL is 0. - * - * @param p the input packet for which the 'time exceeded' should be sent, - * p->payload pointing to the IP header - * @param t type of the 'time exceeded' packet - */ -void -icmp_time_exceeded(struct pbuf *p, enum icmp_te_type t) -{ - MIB2_STATS_INC(mib2.icmpouttimeexcds); - icmp_send_response(p, ICMP_TE, t); -} - -#endif /* IP_FORWARD || IP_REASSEMBLY */ - -/** - * Send an icmp packet in response to an incoming packet. - * - * @param p the input packet for which the 'unreachable' should be sent, - * p->payload pointing to the IP header - * @param type Type of the ICMP header - * @param code Code of the ICMP header - */ -static void -icmp_send_response(struct pbuf *p, u8_t type, u8_t code) -{ - struct pbuf *q; - struct ip_hdr *iphdr; - /* we can use the echo header here */ - struct icmp_echo_hdr *icmphdr; - ip4_addr_t iphdr_src; - struct netif *netif; - - /* increase number of messages attempted to send */ - MIB2_STATS_INC(mib2.icmpoutmsgs); - - /* ICMP header + IP header + 8 bytes of data */ - q = pbuf_alloc(PBUF_IP, sizeof(struct icmp_echo_hdr) + IP_HLEN + ICMP_DEST_UNREACH_DATASIZE, - PBUF_RAM); - if (q == NULL) { - LWIP_DEBUGF(ICMP_DEBUG, ("icmp_time_exceeded: failed to allocate pbuf for ICMP packet.\n")); - MIB2_STATS_INC(mib2.icmpouterrors); - return; - } - LWIP_ASSERT("check that first pbuf can hold icmp message", - (q->len >= (sizeof(struct icmp_echo_hdr) + IP_HLEN + ICMP_DEST_UNREACH_DATASIZE))); - - iphdr = (struct ip_hdr *)p->payload; - LWIP_DEBUGF(ICMP_DEBUG, ("icmp_time_exceeded from ")); - ip4_addr_debug_print_val(ICMP_DEBUG, iphdr->src); - LWIP_DEBUGF(ICMP_DEBUG, (" to ")); - ip4_addr_debug_print_val(ICMP_DEBUG, iphdr->dest); - LWIP_DEBUGF(ICMP_DEBUG, ("\n")); - - icmphdr = (struct icmp_echo_hdr *)q->payload; - icmphdr->type = type; - icmphdr->code = code; - icmphdr->id = 0; - icmphdr->seqno = 0; - - /* copy fields from original packet */ - SMEMCPY((u8_t *)q->payload + sizeof(struct icmp_echo_hdr), (u8_t *)p->payload, - IP_HLEN + ICMP_DEST_UNREACH_DATASIZE); - - ip4_addr_copy(iphdr_src, iphdr->src); -#ifdef LWIP_HOOK_IP4_ROUTE_SRC - { - ip4_addr_t iphdr_dst; - ip4_addr_copy(iphdr_dst, iphdr->dest); - netif = ip4_route_src(&iphdr_src, &iphdr_dst); - } -#else - netif = ip4_route(&iphdr_src); -#endif - if (netif != NULL) { - /* calculate checksum */ - icmphdr->chksum = 0; -#if CHECKSUM_GEN_ICMP - IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_ICMP) { - icmphdr->chksum = inet_chksum(icmphdr, q->len); - } -#endif - ICMP_STATS_INC(icmp.xmit); - ip4_output_if(q, NULL, &iphdr_src, ICMP_TTL, 0, IP_PROTO_ICMP, netif); - } - pbuf_free(q); -} - -#endif /* LWIP_IPV4 && LWIP_ICMP */ diff --git a/third_party/lwip/repo/lwip/src/core/ipv4/igmp.c b/third_party/lwip/repo/lwip/src/core/ipv4/igmp.c deleted file mode 100644 index 74a6c377314905..00000000000000 --- a/third_party/lwip/repo/lwip/src/core/ipv4/igmp.c +++ /dev/null @@ -1,800 +0,0 @@ -/** - * @file - * IGMP - Internet Group Management Protocol - * - * @defgroup igmp IGMP - * @ingroup ip4 - * To be called from TCPIP thread - */ - -/* - * Copyright (c) 2002 CITEL Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of CITEL Technologies Ltd nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY CITEL TECHNOLOGIES AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL CITEL TECHNOLOGIES OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is a contribution to the lwIP TCP/IP stack. - * The Swedish Institute of Computer Science and Adam Dunkels - * are specifically granted permission to redistribute this - * source code. -*/ - -/*------------------------------------------------------------- -Note 1) -Although the rfc requires V1 AND V2 capability -we will only support v2 since now V1 is very old (August 1989) -V1 can be added if required - -a debug print and statistic have been implemented to -show this up. -------------------------------------------------------------- -------------------------------------------------------------- -Note 2) -A query for a specific group address (as opposed to ALLHOSTS) -has now been implemented as I am unsure if it is required - -a debug print and statistic have been implemented to -show this up. -------------------------------------------------------------- -------------------------------------------------------------- -Note 3) -The router alert rfc 2113 is implemented in outgoing packets -but not checked rigorously incoming -------------------------------------------------------------- -Steve Reynolds -------------------------------------------------------------*/ - -/*----------------------------------------------------------------------------- - * RFC 988 - Host extensions for IP multicasting - V0 - * RFC 1054 - Host extensions for IP multicasting - - * RFC 1112 - Host extensions for IP multicasting - V1 - * RFC 2236 - Internet Group Management Protocol, Version 2 - V2 <- this code is based on this RFC (it's the "de facto" standard) - * RFC 3376 - Internet Group Management Protocol, Version 3 - V3 - * RFC 4604 - Using Internet Group Management Protocol Version 3... - V3+ - * RFC 2113 - IP Router Alert Option - - *----------------------------------------------------------------------------*/ - -/*----------------------------------------------------------------------------- - * Includes - *----------------------------------------------------------------------------*/ - -#include "lwip/opt.h" - -#if LWIP_IPV4 && LWIP_IGMP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/igmp.h" -#include "lwip/debug.h" -#include "lwip/def.h" -#include "lwip/mem.h" -#include "lwip/ip.h" -#include "lwip/inet_chksum.h" -#include "lwip/netif.h" -#include "lwip/stats.h" -#include "lwip/prot/igmp.h" - -#include "string.h" - -static struct igmp_group *igmp_lookup_group(struct netif *ifp, const ip4_addr_t *addr); -static err_t igmp_remove_group(struct netif* netif, struct igmp_group *group); -static void igmp_timeout(struct netif *netif, struct igmp_group *group); -static void igmp_start_timer(struct igmp_group *group, u8_t max_time); -static void igmp_delaying_member(struct igmp_group *group, u8_t maxresp); -static err_t igmp_ip_output_if(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest, struct netif *netif); -static void igmp_send(struct netif *netif, struct igmp_group *group, u8_t type); - -static ip4_addr_t allsystems; -static ip4_addr_t allrouters; - -/** - * Initialize the IGMP module - */ -void -igmp_init(void) -{ - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_init: initializing\n")); - - IP4_ADDR(&allsystems, 224, 0, 0, 1); - IP4_ADDR(&allrouters, 224, 0, 0, 2); -} - -/** - * Start IGMP processing on interface - * - * @param netif network interface on which start IGMP processing - */ -err_t -igmp_start(struct netif *netif) -{ - struct igmp_group* group; - - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_start: starting IGMP processing on if %p\n", (void*)netif)); - - group = igmp_lookup_group(netif, &allsystems); - - if (group != NULL) { - group->group_state = IGMP_GROUP_IDLE_MEMBER; - group->use++; - - /* Allow the igmp messages at the MAC level */ - if (netif->igmp_mac_filter != NULL) { - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_start: igmp_mac_filter(ADD ")); - ip4_addr_debug_print_val(IGMP_DEBUG, allsystems); - LWIP_DEBUGF(IGMP_DEBUG, (") on if %p\n", (void*)netif)); - netif->igmp_mac_filter(netif, &allsystems, NETIF_ADD_MAC_FILTER); - } - - return ERR_OK; - } - - return ERR_MEM; -} - -/** - * Stop IGMP processing on interface - * - * @param netif network interface on which stop IGMP processing - */ -err_t -igmp_stop(struct netif *netif) -{ - struct igmp_group *group = netif_igmp_data(netif); - - netif_set_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_IGMP, NULL); - - while (group != NULL) { - struct igmp_group *next = group->next; /* avoid use-after-free below */ - - /* disable the group at the MAC level */ - if (netif->igmp_mac_filter != NULL) { - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_stop: igmp_mac_filter(DEL ")); - ip4_addr_debug_print(IGMP_DEBUG, &group->group_address); - LWIP_DEBUGF(IGMP_DEBUG, (") on if %p\n", (void*)netif)); - netif->igmp_mac_filter(netif, &(group->group_address), NETIF_DEL_MAC_FILTER); - } - - /* free group */ - memp_free(MEMP_IGMP_GROUP, group); - - /* move to "next" */ - group = next; - } - return ERR_OK; -} - -/** - * Report IGMP memberships for this interface - * - * @param netif network interface on which report IGMP memberships - */ -void -igmp_report_groups(struct netif *netif) -{ - struct igmp_group *group = netif_igmp_data(netif); - - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_report_groups: sending IGMP reports on if %p\n", (void*)netif)); - - /* Skip the first group in the list, it is always the allsystems group added in igmp_start() */ - if(group != NULL) { - group = group->next; - } - - while (group != NULL) { - igmp_delaying_member(group, IGMP_JOIN_DELAYING_MEMBER_TMR); - group = group->next; - } -} - -/** - * Search for a group in the global igmp_group_list - * - * @param ifp the network interface for which to look - * @param addr the group ip address to search for - * @return a struct igmp_group* if the group has been found, - * NULL if the group wasn't found. - */ -struct igmp_group * -igmp_lookfor_group(struct netif *ifp, const ip4_addr_t *addr) -{ - struct igmp_group *group = netif_igmp_data(ifp); - - while (group != NULL) { - if (ip4_addr_cmp(&(group->group_address), addr)) { - return group; - } - group = group->next; - } - - /* to be clearer, we return NULL here instead of - * 'group' (which is also NULL at this point). - */ - return NULL; -} - -/** - * Search for a specific igmp group and create a new one if not found- - * - * @param ifp the network interface for which to look - * @param addr the group ip address to search - * @return a struct igmp_group*, - * NULL on memory error. - */ -static struct igmp_group * -igmp_lookup_group(struct netif *ifp, const ip4_addr_t *addr) -{ - struct igmp_group *group; - struct igmp_group *list_head = netif_igmp_data(ifp); - - /* Search if the group already exists */ - group = igmp_lookfor_group(ifp, addr); - if (group != NULL) { - /* Group already exists. */ - return group; - } - - /* Group doesn't exist yet, create a new one */ - group = (struct igmp_group *)memp_malloc(MEMP_IGMP_GROUP); - if (group != NULL) { - ip4_addr_set(&(group->group_address), addr); - group->timer = 0; /* Not running */ - group->group_state = IGMP_GROUP_NON_MEMBER; - group->last_reporter_flag = 0; - group->use = 0; - - /* Ensure allsystems group is always first in list */ - if (list_head == NULL) { - /* this is the first entry in linked list */ - LWIP_ASSERT("igmp_lookup_group: first group must be allsystems", - (ip4_addr_cmp(addr, &allsystems) != 0)); - group->next = NULL; - netif_set_client_data(ifp, LWIP_NETIF_CLIENT_DATA_INDEX_IGMP, group); - } else { - /* append _after_ first entry */ - LWIP_ASSERT("igmp_lookup_group: all except first group must not be allsystems", - (ip4_addr_cmp(addr, &allsystems) == 0)); - group->next = list_head->next; - list_head->next = group; - } - } - - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_lookup_group: %sallocated a new group with address ", (group?"":"impossible to "))); - ip4_addr_debug_print(IGMP_DEBUG, addr); - LWIP_DEBUGF(IGMP_DEBUG, (" on if %p\n", (void*)ifp)); - - return group; -} - -/** - * Remove a group in the global igmp_group_list, but don't free it yet - * - * @param group the group to remove from the global igmp_group_list - * @return ERR_OK if group was removed from the list, an err_t otherwise - */ -static err_t -igmp_remove_group(struct netif* netif, struct igmp_group *group) -{ - err_t err = ERR_OK; - struct igmp_group *tmp_group; - - /* Skip the first group in the list, it is always the allsystems group added in igmp_start() */ - for (tmp_group = netif_igmp_data(netif); tmp_group != NULL; tmp_group = tmp_group->next) { - if (tmp_group->next == group) { - tmp_group->next = group->next; - break; - } - } - /* Group not found in the global igmp_group_list */ - if (tmp_group == NULL) { - err = ERR_ARG; - } - - return err; -} - -/** - * Called from ip_input() if a new IGMP packet is received. - * - * @param p received igmp packet, p->payload pointing to the igmp header - * @param inp network interface on which the packet was received - * @param dest destination ip address of the igmp packet - */ -void -igmp_input(struct pbuf *p, struct netif *inp, const ip4_addr_t *dest) -{ - struct igmp_msg* igmp; - struct igmp_group* group; - struct igmp_group* groupref; - - IGMP_STATS_INC(igmp.recv); - - /* Note that the length CAN be greater than 8 but only 8 are used - All are included in the checksum */ - if (p->len < IGMP_MINLEN) { - pbuf_free(p); - IGMP_STATS_INC(igmp.lenerr); - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: length error\n")); - return; - } - - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: message from ")); - ip4_addr_debug_print(IGMP_DEBUG, &(ip4_current_header()->src)); - LWIP_DEBUGF(IGMP_DEBUG, (" to address ")); - ip4_addr_debug_print(IGMP_DEBUG, &(ip4_current_header()->dest)); - LWIP_DEBUGF(IGMP_DEBUG, (" on if %p\n", (void*)inp)); - - /* Now calculate and check the checksum */ - igmp = (struct igmp_msg *)p->payload; - if (inet_chksum(igmp, p->len)) { - pbuf_free(p); - IGMP_STATS_INC(igmp.chkerr); - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: checksum error\n")); - return; - } - - /* Packet is ok so find an existing group */ - group = igmp_lookfor_group(inp, dest); /* use the destination IP address of incoming packet */ - - /* If group can be found or create... */ - if (!group) { - pbuf_free(p); - IGMP_STATS_INC(igmp.drop); - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: IGMP frame not for us\n")); - return; - } - - /* NOW ACT ON THE INCOMING MESSAGE TYPE... */ - switch (igmp->igmp_msgtype) { - case IGMP_MEMB_QUERY: - /* IGMP_MEMB_QUERY to the "all systems" address ? */ - if ((ip4_addr_cmp(dest, &allsystems)) && ip4_addr_isany(&igmp->igmp_group_address)) { - /* THIS IS THE GENERAL QUERY */ - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: General IGMP_MEMB_QUERY on \"ALL SYSTEMS\" address (224.0.0.1) [igmp_maxresp=%i]\n", (int)(igmp->igmp_maxresp))); - - if (igmp->igmp_maxresp == 0) { - IGMP_STATS_INC(igmp.rx_v1); - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: got an all hosts query with time== 0 - this is V1 and not implemented - treat as v2\n")); - igmp->igmp_maxresp = IGMP_V1_DELAYING_MEMBER_TMR; - } else { - IGMP_STATS_INC(igmp.rx_general); - } - - groupref = netif_igmp_data(inp); - - /* Do not send messages on the all systems group address! */ - /* Skip the first group in the list, it is always the allsystems group added in igmp_start() */ - if(groupref != NULL) { - groupref = groupref->next; - } - - while (groupref) { - igmp_delaying_member(groupref, igmp->igmp_maxresp); - groupref = groupref->next; - } - } else { - /* IGMP_MEMB_QUERY to a specific group ? */ - if (!ip4_addr_isany(&igmp->igmp_group_address)) { - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: IGMP_MEMB_QUERY to a specific group ")); - ip4_addr_debug_print(IGMP_DEBUG, &igmp->igmp_group_address); - if (ip4_addr_cmp(dest, &allsystems)) { - ip4_addr_t groupaddr; - LWIP_DEBUGF(IGMP_DEBUG, (" using \"ALL SYSTEMS\" address (224.0.0.1) [igmp_maxresp=%i]\n", (int)(igmp->igmp_maxresp))); - /* we first need to re-look for the group since we used dest last time */ - ip4_addr_copy(groupaddr, igmp->igmp_group_address); - group = igmp_lookfor_group(inp, &groupaddr); - } else { - LWIP_DEBUGF(IGMP_DEBUG, (" with the group address as destination [igmp_maxresp=%i]\n", (int)(igmp->igmp_maxresp))); - } - - if (group != NULL) { - IGMP_STATS_INC(igmp.rx_group); - igmp_delaying_member(group, igmp->igmp_maxresp); - } else { - IGMP_STATS_INC(igmp.drop); - } - } else { - IGMP_STATS_INC(igmp.proterr); - } - } - break; - case IGMP_V2_MEMB_REPORT: - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: IGMP_V2_MEMB_REPORT\n")); - IGMP_STATS_INC(igmp.rx_report); - if (group->group_state == IGMP_GROUP_DELAYING_MEMBER) { - /* This is on a specific group we have already looked up */ - group->timer = 0; /* stopped */ - group->group_state = IGMP_GROUP_IDLE_MEMBER; - group->last_reporter_flag = 0; - } - break; - default: - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_input: unexpected msg %d in state %d on group %p on if %p\n", - igmp->igmp_msgtype, group->group_state, (void*)&group, (void*)inp)); - IGMP_STATS_INC(igmp.proterr); - break; - } - - pbuf_free(p); - return; -} - -/** - * @ingroup igmp - * Join a group on one network interface. - * - * @param ifaddr ip address of the network interface which should join a new group - * @param groupaddr the ip address of the group which to join - * @return ERR_OK if group was joined on the netif(s), an err_t otherwise - */ -err_t -igmp_joingroup(const ip4_addr_t *ifaddr, const ip4_addr_t *groupaddr) -{ - err_t err = ERR_VAL; /* no matching interface */ - struct netif *netif; - - /* make sure it is multicast address */ - LWIP_ERROR("igmp_joingroup: attempt to join non-multicast address", ip4_addr_ismulticast(groupaddr), return ERR_VAL;); - LWIP_ERROR("igmp_joingroup: attempt to join allsystems address", (!ip4_addr_cmp(groupaddr, &allsystems)), return ERR_VAL;); - - /* loop through netif's */ - netif = netif_list; - while (netif != NULL) { - /* Should we join this interface ? */ - if ((netif->flags & NETIF_FLAG_IGMP) && ((ip4_addr_isany(ifaddr) || ip4_addr_cmp(netif_ip4_addr(netif), ifaddr)))) { - err = igmp_joingroup_netif(netif, groupaddr); - if (err != ERR_OK) { - /* Return an error even if some network interfaces are joined */ - /** @todo undo any other netif already joined */ - return err; - } - } - /* proceed to next network interface */ - netif = netif->next; - } - - return err; -} - -/** - * @ingroup igmp - * Join a group on one network interface. - * - * @param netif the network interface which should join a new group - * @param groupaddr the ip address of the group which to join - * @return ERR_OK if group was joined on the netif, an err_t otherwise - */ -err_t -igmp_joingroup_netif(struct netif *netif, const ip4_addr_t *groupaddr) -{ - struct igmp_group *group; - - /* make sure it is multicast address */ - LWIP_ERROR("igmp_joingroup_netif: attempt to join non-multicast address", ip4_addr_ismulticast(groupaddr), return ERR_VAL;); - LWIP_ERROR("igmp_joingroup_netif: attempt to join allsystems address", (!ip4_addr_cmp(groupaddr, &allsystems)), return ERR_VAL;); - - /* make sure it is an igmp-enabled netif */ - LWIP_ERROR("igmp_joingroup_netif: attempt to join on non-IGMP netif", netif->flags & NETIF_FLAG_IGMP, return ERR_VAL;); - - /* find group or create a new one if not found */ - group = igmp_lookup_group(netif, groupaddr); - - if (group != NULL) { - /* This should create a new group, check the state to make sure */ - if (group->group_state != IGMP_GROUP_NON_MEMBER) { - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_joingroup_netif: join to group not in state IGMP_GROUP_NON_MEMBER\n")); - } else { - /* OK - it was new group */ - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_joingroup_netif: join to new group: ")); - ip4_addr_debug_print(IGMP_DEBUG, groupaddr); - LWIP_DEBUGF(IGMP_DEBUG, ("\n")); - - /* If first use of the group, allow the group at the MAC level */ - if ((group->use==0) && (netif->igmp_mac_filter != NULL)) { - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_joingroup_netif: igmp_mac_filter(ADD ")); - ip4_addr_debug_print(IGMP_DEBUG, groupaddr); - LWIP_DEBUGF(IGMP_DEBUG, (") on if %p\n", (void*)netif)); - netif->igmp_mac_filter(netif, groupaddr, NETIF_ADD_MAC_FILTER); - } - - IGMP_STATS_INC(igmp.tx_join); - igmp_send(netif, group, IGMP_V2_MEMB_REPORT); - - igmp_start_timer(group, IGMP_JOIN_DELAYING_MEMBER_TMR); - - /* Need to work out where this timer comes from */ - group->group_state = IGMP_GROUP_DELAYING_MEMBER; - } - /* Increment group use */ - group->use++; - /* Join on this interface */ - return ERR_OK; - } else { - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_joingroup_netif: Not enough memory to join to group\n")); - return ERR_MEM; - } -} - -/** - * @ingroup igmp - * Leave a group on one network interface. - * - * @param ifaddr ip address of the network interface which should leave a group - * @param groupaddr the ip address of the group which to leave - * @return ERR_OK if group was left on the netif(s), an err_t otherwise - */ -err_t -igmp_leavegroup(const ip4_addr_t *ifaddr, const ip4_addr_t *groupaddr) -{ - err_t err = ERR_VAL; /* no matching interface */ - struct netif *netif; - - /* make sure it is multicast address */ - LWIP_ERROR("igmp_leavegroup: attempt to leave non-multicast address", ip4_addr_ismulticast(groupaddr), return ERR_VAL;); - LWIP_ERROR("igmp_leavegroup: attempt to leave allsystems address", (!ip4_addr_cmp(groupaddr, &allsystems)), return ERR_VAL;); - - /* loop through netif's */ - netif = netif_list; - while (netif != NULL) { - /* Should we leave this interface ? */ - if ((netif->flags & NETIF_FLAG_IGMP) && ((ip4_addr_isany(ifaddr) || ip4_addr_cmp(netif_ip4_addr(netif), ifaddr)))) { - err_t res = igmp_leavegroup_netif(netif, groupaddr); - if (err != ERR_OK) { - /* Store this result if we have not yet gotten a success */ - err = res; - } - } - /* proceed to next network interface */ - netif = netif->next; - } - - return err; -} - -/** - * @ingroup igmp - * Leave a group on one network interface. - * - * @param netif the network interface which should leave a group - * @param groupaddr the ip address of the group which to leave - * @return ERR_OK if group was left on the netif, an err_t otherwise - */ -err_t -igmp_leavegroup_netif(struct netif *netif, const ip4_addr_t *groupaddr) -{ - struct igmp_group *group; - - /* make sure it is multicast address */ - LWIP_ERROR("igmp_leavegroup_netif: attempt to leave non-multicast address", ip4_addr_ismulticast(groupaddr), return ERR_VAL;); - LWIP_ERROR("igmp_leavegroup_netif: attempt to leave allsystems address", (!ip4_addr_cmp(groupaddr, &allsystems)), return ERR_VAL;); - - /* make sure it is an igmp-enabled netif */ - LWIP_ERROR("igmp_leavegroup_netif: attempt to leave on non-IGMP netif", netif->flags & NETIF_FLAG_IGMP, return ERR_VAL;); - - /* find group */ - group = igmp_lookfor_group(netif, groupaddr); - - if (group != NULL) { - /* Only send a leave if the flag is set according to the state diagram */ - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_leavegroup_netif: Leaving group: ")); - ip4_addr_debug_print(IGMP_DEBUG, groupaddr); - LWIP_DEBUGF(IGMP_DEBUG, ("\n")); - - /* If there is no other use of the group */ - if (group->use <= 1) { - /* Remove the group from the list */ - igmp_remove_group(netif, group); - - /* If we are the last reporter for this group */ - if (group->last_reporter_flag) { - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_leavegroup_netif: sending leaving group\n")); - IGMP_STATS_INC(igmp.tx_leave); - igmp_send(netif, group, IGMP_LEAVE_GROUP); - } - - /* Disable the group at the MAC level */ - if (netif->igmp_mac_filter != NULL) { - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_leavegroup_netif: igmp_mac_filter(DEL ")); - ip4_addr_debug_print(IGMP_DEBUG, groupaddr); - LWIP_DEBUGF(IGMP_DEBUG, (") on if %p\n", (void*)netif)); - netif->igmp_mac_filter(netif, groupaddr, NETIF_DEL_MAC_FILTER); - } - - /* Free group struct */ - memp_free(MEMP_IGMP_GROUP, group); - } else { - /* Decrement group use */ - group->use--; - } - return ERR_OK; - } else { - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_leavegroup_netif: not member of group\n")); - return ERR_VAL; - } -} - -/** - * The igmp timer function (both for NO_SYS=1 and =0) - * Should be called every IGMP_TMR_INTERVAL milliseconds (100 ms is default). - */ -void -igmp_tmr(void) -{ - struct netif *netif = netif_list; - - while (netif != NULL) { - struct igmp_group *group = netif_igmp_data(netif); - - while (group != NULL) { - if (group->timer > 0) { - group->timer--; - if (group->timer == 0) { - igmp_timeout(netif, group); - } - } - group = group->next; - } - netif = netif->next; - } -} - -/** - * Called if a timeout for one group is reached. - * Sends a report for this group. - * - * @param group an igmp_group for which a timeout is reached - */ -static void -igmp_timeout(struct netif *netif, struct igmp_group *group) -{ - /* If the state is IGMP_GROUP_DELAYING_MEMBER then we send a report for this group - (unless it is the allsystems group) */ - if ((group->group_state == IGMP_GROUP_DELAYING_MEMBER) && - (!(ip4_addr_cmp(&(group->group_address), &allsystems)))) { - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_timeout: report membership for group with address ")); - ip4_addr_debug_print(IGMP_DEBUG, &(group->group_address)); - LWIP_DEBUGF(IGMP_DEBUG, (" on if %p\n", (void*)netif)); - - group->group_state = IGMP_GROUP_IDLE_MEMBER; - - IGMP_STATS_INC(igmp.tx_report); - igmp_send(netif, group, IGMP_V2_MEMB_REPORT); - } -} - -/** - * Start a timer for an igmp group - * - * @param group the igmp_group for which to start a timer - * @param max_time the time in multiples of IGMP_TMR_INTERVAL (decrease with - * every call to igmp_tmr()) - */ -static void -igmp_start_timer(struct igmp_group *group, u8_t max_time) -{ -#ifdef LWIP_RAND - group->timer = max_time > 2 ? (LWIP_RAND() % max_time) : 1; -#else /* LWIP_RAND */ - /* ATTENTION: use this only if absolutely necessary! */ - group->timer = max_time / 2; -#endif /* LWIP_RAND */ - - if (group->timer == 0) { - group->timer = 1; - } -} - -/** - * Delaying membership report for a group if necessary - * - * @param group the igmp_group for which "delaying" membership report - * @param maxresp query delay - */ -static void -igmp_delaying_member(struct igmp_group *group, u8_t maxresp) -{ - if ((group->group_state == IGMP_GROUP_IDLE_MEMBER) || - ((group->group_state == IGMP_GROUP_DELAYING_MEMBER) && - ((group->timer == 0) || (maxresp < group->timer)))) { - igmp_start_timer(group, maxresp); - group->group_state = IGMP_GROUP_DELAYING_MEMBER; - } -} - - -/** - * Sends an IP packet on a network interface. This function constructs the IP header - * and calculates the IP header checksum. If the source IP address is NULL, - * the IP address of the outgoing network interface is filled in as source address. - * - * @param p the packet to send (p->payload points to the data, e.g. next - protocol header; if dest == LWIP_IP_HDRINCL, p already includes an - IP header and p->payload points to that IP header) - * @param src the source IP address to send from (if src == IP4_ADDR_ANY, the - * IP address of the netif used to send is used as source address) - * @param dest the destination IP address to send the packet to - * @param netif the netif on which to send this packet - * @return ERR_OK if the packet was sent OK - * ERR_BUF if p doesn't have enough space for IP/LINK headers - * returns errors returned by netif->output - */ -static err_t -igmp_ip_output_if(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest, struct netif *netif) -{ - /* This is the "router alert" option */ - u16_t ra[2]; - ra[0] = PP_HTONS(ROUTER_ALERT); - ra[1] = 0x0000; /* Router shall examine packet */ - IGMP_STATS_INC(igmp.xmit); - return ip4_output_if_opt(p, src, dest, IGMP_TTL, 0, IP_PROTO_IGMP, netif, ra, ROUTER_ALERTLEN); -} - -/** - * Send an igmp packet to a specific group. - * - * @param group the group to which to send the packet - * @param type the type of igmp packet to send - */ -static void -igmp_send(struct netif *netif, struct igmp_group *group, u8_t type) -{ - struct pbuf* p = NULL; - struct igmp_msg* igmp = NULL; - ip4_addr_t src = *IP4_ADDR_ANY4; - ip4_addr_t* dest = NULL; - - /* IP header + "router alert" option + IGMP header */ - p = pbuf_alloc(PBUF_TRANSPORT, IGMP_MINLEN, PBUF_RAM); - - if (p) { - igmp = (struct igmp_msg *)p->payload; - LWIP_ASSERT("igmp_send: check that first pbuf can hold struct igmp_msg", - (p->len >= sizeof(struct igmp_msg))); - ip4_addr_copy(src, *netif_ip4_addr(netif)); - - if (type == IGMP_V2_MEMB_REPORT) { - dest = &(group->group_address); - ip4_addr_copy(igmp->igmp_group_address, group->group_address); - group->last_reporter_flag = 1; /* Remember we were the last to report */ - } else { - if (type == IGMP_LEAVE_GROUP) { - dest = &allrouters; - ip4_addr_copy(igmp->igmp_group_address, group->group_address); - } - } - - if ((type == IGMP_V2_MEMB_REPORT) || (type == IGMP_LEAVE_GROUP)) { - igmp->igmp_msgtype = type; - igmp->igmp_maxresp = 0; - igmp->igmp_checksum = 0; - igmp->igmp_checksum = inet_chksum(igmp, IGMP_MINLEN); - - igmp_ip_output_if(p, &src, dest, netif); - } - - pbuf_free(p); - } else { - LWIP_DEBUGF(IGMP_DEBUG, ("igmp_send: not enough memory for igmp_send\n")); - IGMP_STATS_INC(igmp.memerr); - } -} - -#endif /* LWIP_IPV4 && LWIP_IGMP */ diff --git a/third_party/lwip/repo/lwip/src/core/ipv4/ip4.c b/third_party/lwip/repo/lwip/src/core/ipv4/ip4.c deleted file mode 100644 index 93bceb741e9523..00000000000000 --- a/third_party/lwip/repo/lwip/src/core/ipv4/ip4.c +++ /dev/null @@ -1,1111 +0,0 @@ -/** - * @file - * This is the IPv4 layer implementation for incoming and outgoing IP traffic. - * - * @see ip_frag.c - * - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ - -#include "lwip/opt.h" - -#if LWIP_IPV4 - -#include "lwip/ip.h" -#include "lwip/def.h" -#include "lwip/mem.h" -#include "lwip/ip4_frag.h" -#include "lwip/inet_chksum.h" -#include "lwip/netif.h" -#include "lwip/icmp.h" -#include "lwip/igmp.h" -#include "lwip/raw.h" -#include "lwip/udp.h" -#include "lwip/priv/tcp_priv.h" -#include "lwip/autoip.h" -#include "lwip/stats.h" -#include "lwip/prot/dhcp.h" - -#include - -#ifdef LWIP_HOOK_FILENAME -#include LWIP_HOOK_FILENAME -#endif - -/** Set this to 0 in the rare case of wanting to call an extra function to - * generate the IP checksum (in contrast to calculating it on-the-fly). */ -#ifndef LWIP_INLINE_IP_CHKSUM -#if LWIP_CHECKSUM_CTRL_PER_NETIF -#define LWIP_INLINE_IP_CHKSUM 0 -#else /* LWIP_CHECKSUM_CTRL_PER_NETIF */ -#define LWIP_INLINE_IP_CHKSUM 1 -#endif /* LWIP_CHECKSUM_CTRL_PER_NETIF */ -#endif - -#if LWIP_INLINE_IP_CHKSUM && CHECKSUM_GEN_IP -#define CHECKSUM_GEN_IP_INLINE 1 -#else -#define CHECKSUM_GEN_IP_INLINE 0 -#endif - -#if LWIP_DHCP || defined(LWIP_IP_ACCEPT_UDP_PORT) -#define IP_ACCEPT_LINK_LAYER_ADDRESSING 1 - -/** Some defines for DHCP to let link-layer-addressed packets through while the - * netif is down. - * To use this in your own application/protocol, define LWIP_IP_ACCEPT_UDP_PORT(port) - * to return 1 if the port is accepted and 0 if the port is not accepted. - */ -#if LWIP_DHCP && defined(LWIP_IP_ACCEPT_UDP_PORT) -/* accept DHCP client port and custom port */ -#define IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(port) (((port) == PP_NTOHS(DHCP_CLIENT_PORT)) \ - || (LWIP_IP_ACCEPT_UDP_PORT(port))) -#elif defined(LWIP_IP_ACCEPT_UDP_PORT) /* LWIP_DHCP && defined(LWIP_IP_ACCEPT_UDP_PORT) */ -/* accept custom port only */ -#define IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(port) (LWIP_IP_ACCEPT_UDP_PORT(port)) -#else /* LWIP_DHCP && defined(LWIP_IP_ACCEPT_UDP_PORT) */ -/* accept DHCP client port only */ -#define IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(port) ((port) == PP_NTOHS(DHCP_CLIENT_PORT)) -#endif /* LWIP_DHCP && defined(LWIP_IP_ACCEPT_UDP_PORT) */ - -#else /* LWIP_DHCP */ -#define IP_ACCEPT_LINK_LAYER_ADDRESSING 0 -#endif /* LWIP_DHCP */ - -/** The IP header ID of the next outgoing IP packet */ -static u16_t ip_id; - -#if LWIP_MULTICAST_TX_OPTIONS -/** The default netif used for multicast */ -static struct netif* ip4_default_multicast_netif; - -/** - * @ingroup ip4 - * Set a default netif for IPv4 multicast. */ -void -ip4_set_default_multicast_netif(struct netif* default_multicast_netif) -{ - ip4_default_multicast_netif = default_multicast_netif; -} -#endif /* LWIP_MULTICAST_TX_OPTIONS */ - -#ifdef LWIP_HOOK_IP4_ROUTE_SRC -/** - * Source based IPv4 routing must be fully implemented in - * LWIP_HOOK_IP4_ROUTE_SRC(). This function only provides he parameters. - */ -struct netif * -ip4_route_src(const ip4_addr_t *dest, const ip4_addr_t *src) -{ - if (src != NULL) { - /* when src==NULL, the hook is called from ip4_route(dest) */ - struct netif *netif = LWIP_HOOK_IP4_ROUTE_SRC(dest, src); - if (netif != NULL) { - return netif; - } - } - return ip4_route(dest); -} -#endif /* LWIP_HOOK_IP4_ROUTE_SRC */ - -/** - * Finds the appropriate network interface for a given IP address. It - * searches the list of network interfaces linearly. A match is found - * if the masked IP address of the network interface equals the masked - * IP address given to the function. - * - * @param dest the destination IP address for which to find the route - * @return the netif on which to send to reach dest - */ -struct netif * -ip4_route(const ip4_addr_t *dest) -{ - struct netif *netif; - -#if LWIP_MULTICAST_TX_OPTIONS - /* Use administratively selected interface for multicast by default */ - if (ip4_addr_ismulticast(dest) && ip4_default_multicast_netif) { - return ip4_default_multicast_netif; - } -#endif /* LWIP_MULTICAST_TX_OPTIONS */ - - /* iterate through netifs */ - for (netif = netif_list; netif != NULL; netif = netif->next) { - /* is the netif up, does it have a link and a valid address? */ - if (netif_is_up(netif) && netif_is_link_up(netif) && !ip4_addr_isany_val(*netif_ip4_addr(netif))) { - /* network mask matches? */ - if (ip4_addr_netcmp(dest, netif_ip4_addr(netif), netif_ip4_netmask(netif))) { - /* return netif on which to forward IP packet */ - return netif; - } - /* gateway matches on a non broadcast interface? (i.e. peer in a point to point interface) */ - if (((netif->flags & NETIF_FLAG_BROADCAST) == 0) && ip4_addr_cmp(dest, netif_ip4_gw(netif))) { - /* return netif on which to forward IP packet */ - return netif; - } - } - } - -#if LWIP_NETIF_LOOPBACK && !LWIP_HAVE_LOOPIF - /* loopif is disabled, looopback traffic is passed through any netif */ - if (ip4_addr_isloopback(dest)) { - /* don't check for link on loopback traffic */ - if (netif_default != NULL && netif_is_up(netif_default)) { - return netif_default; - } - /* default netif is not up, just use any netif for loopback traffic */ - for (netif = netif_list; netif != NULL; netif = netif->next) { - if (netif_is_up(netif)) { - return netif; - } - } - return NULL; - } -#endif /* LWIP_NETIF_LOOPBACK && !LWIP_HAVE_LOOPIF */ - -#ifdef LWIP_HOOK_IP4_ROUTE_SRC - netif = LWIP_HOOK_IP4_ROUTE_SRC(dest, NULL); - if (netif != NULL) { - return netif; - } -#elif defined(LWIP_HOOK_IP4_ROUTE) - netif = LWIP_HOOK_IP4_ROUTE(dest); - if (netif != NULL) { - return netif; - } -#endif - - if ((netif_default == NULL) || !netif_is_up(netif_default) || !netif_is_link_up(netif_default) || - ip4_addr_isany_val(*netif_ip4_addr(netif_default))) { - /* No matching netif found and default netif is not usable. - If this is not good enough for you, use LWIP_HOOK_IP4_ROUTE() */ - LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip4_route: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", - ip4_addr1_16(dest), ip4_addr2_16(dest), ip4_addr3_16(dest), ip4_addr4_16(dest))); - IP_STATS_INC(ip.rterr); - MIB2_STATS_INC(mib2.ipoutnoroutes); - return NULL; - } - - return netif_default; -} - -#if IP_FORWARD -/** - * Determine whether an IP address is in a reserved set of addresses - * that may not be forwarded, or whether datagrams to that destination - * may be forwarded. - * @param p the packet to forward - * @return 1: can forward 0: discard - */ -static int -ip4_canforward(struct pbuf *p) -{ - u32_t addr = lwip_htonl(ip4_addr_get_u32(ip4_current_dest_addr())); - - if (p->flags & PBUF_FLAG_LLBCAST) { - /* don't route link-layer broadcasts */ - return 0; - } - if ((p->flags & PBUF_FLAG_LLMCAST) && !IP_MULTICAST(addr)) { - /* don't route link-layer multicasts unless the destination address is an IP - multicast address */ - return 0; - } - if (IP_EXPERIMENTAL(addr)) { - return 0; - } - if (IP_CLASSA(addr)) { - u32_t net = addr & IP_CLASSA_NET; - if ((net == 0) || (net == ((u32_t)IP_LOOPBACKNET << IP_CLASSA_NSHIFT))) { - /* don't route loopback packets */ - return 0; - } - } - return 1; -} - -/** - * Forwards an IP packet. It finds an appropriate route for the - * packet, decrements the TTL value of the packet, adjusts the - * checksum and outputs the packet on the appropriate interface. - * - * @param p the packet to forward (p->payload points to IP header) - * @param iphdr the IP header of the input packet - * @param inp the netif on which this packet was received - */ -static void -ip4_forward(struct pbuf *p, struct ip_hdr *iphdr, struct netif *inp) -{ - struct netif *netif; - - PERF_START; - LWIP_UNUSED_ARG(inp); - - if (!ip4_canforward(p)) { - goto return_noroute; - } - - /* RFC3927 2.7: do not forward link-local addresses */ - if (ip4_addr_islinklocal(ip4_current_dest_addr())) { - LWIP_DEBUGF(IP_DEBUG, ("ip4_forward: not forwarding LLA %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", - ip4_addr1_16(ip4_current_dest_addr()), ip4_addr2_16(ip4_current_dest_addr()), - ip4_addr3_16(ip4_current_dest_addr()), ip4_addr4_16(ip4_current_dest_addr()))); - goto return_noroute; - } - - /* Find network interface where to forward this IP packet to. */ - netif = ip4_route_src(ip4_current_dest_addr(), ip4_current_src_addr()); - if (netif == NULL) { - LWIP_DEBUGF(IP_DEBUG, ("ip4_forward: no forwarding route for %"U16_F".%"U16_F".%"U16_F".%"U16_F" found\n", - ip4_addr1_16(ip4_current_dest_addr()), ip4_addr2_16(ip4_current_dest_addr()), - ip4_addr3_16(ip4_current_dest_addr()), ip4_addr4_16(ip4_current_dest_addr()))); - /* @todo: send ICMP_DUR_NET? */ - goto return_noroute; - } -#if !IP_FORWARD_ALLOW_TX_ON_RX_NETIF - /* Do not forward packets onto the same network interface on which - * they arrived. */ - if (netif == inp) { - LWIP_DEBUGF(IP_DEBUG, ("ip4_forward: not bouncing packets back on incoming interface.\n")); - goto return_noroute; - } -#endif /* IP_FORWARD_ALLOW_TX_ON_RX_NETIF */ - - /* decrement TTL */ - IPH_TTL_SET(iphdr, IPH_TTL(iphdr) - 1); - /* send ICMP if TTL == 0 */ - if (IPH_TTL(iphdr) == 0) { - MIB2_STATS_INC(mib2.ipinhdrerrors); -#if LWIP_ICMP - /* Don't send ICMP messages in response to ICMP messages */ - if (IPH_PROTO(iphdr) != IP_PROTO_ICMP) { - icmp_time_exceeded(p, ICMP_TE_TTL); - } -#endif /* LWIP_ICMP */ - return; - } - - /* Incrementally update the IP checksum. */ - if (IPH_CHKSUM(iphdr) >= PP_HTONS(0xffffU - 0x100)) { - IPH_CHKSUM_SET(iphdr, IPH_CHKSUM(iphdr) + PP_HTONS(0x100) + 1); - } else { - IPH_CHKSUM_SET(iphdr, IPH_CHKSUM(iphdr) + PP_HTONS(0x100)); - } - - LWIP_DEBUGF(IP_DEBUG, ("ip4_forward: forwarding packet to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", - ip4_addr1_16(ip4_current_dest_addr()), ip4_addr2_16(ip4_current_dest_addr()), - ip4_addr3_16(ip4_current_dest_addr()), ip4_addr4_16(ip4_current_dest_addr()))); - - IP_STATS_INC(ip.fw); - MIB2_STATS_INC(mib2.ipforwdatagrams); - IP_STATS_INC(ip.xmit); - - PERF_STOP("ip4_forward"); - /* don't fragment if interface has mtu set to 0 [loopif] */ - if (netif->mtu && (p->tot_len > netif->mtu)) { - if ((IPH_OFFSET(iphdr) & PP_NTOHS(IP_DF)) == 0) { -#if IP_FRAG - ip4_frag(p, netif, ip4_current_dest_addr()); -#else /* IP_FRAG */ - /* @todo: send ICMP Destination Unreachable code 13 "Communication administratively prohibited"? */ -#endif /* IP_FRAG */ - } else { -#if LWIP_ICMP - /* send ICMP Destination Unreachable code 4: "Fragmentation Needed and DF Set" */ - icmp_dest_unreach(p, ICMP_DUR_FRAG); -#endif /* LWIP_ICMP */ - } - return; - } - /* transmit pbuf on chosen interface */ - netif->output(netif, p, ip4_current_dest_addr()); - return; -return_noroute: - MIB2_STATS_INC(mib2.ipoutnoroutes); -} -#endif /* IP_FORWARD */ - -/** - * This function is called by the network interface device driver when - * an IP packet is received. The function does the basic checks of the - * IP header such as packet size being at least larger than the header - * size etc. If the packet was not destined for us, the packet is - * forwarded (using ip_forward). The IP checksum is always checked. - * - * Finally, the packet is sent to the upper layer protocol input function. - * - * @param p the received IP packet (p->payload points to IP header) - * @param inp the netif on which this packet was received - * @return ERR_OK if the packet was processed (could return ERR_* if it wasn't - * processed, but currently always returns ERR_OK) - */ -err_t -ip4_input(struct pbuf *p, struct netif *inp) -{ - struct ip_hdr *iphdr; - struct netif *netif; - u16_t iphdr_hlen; - u16_t iphdr_len; -#if IP_ACCEPT_LINK_LAYER_ADDRESSING || LWIP_IGMP - int check_ip_src = 1; -#endif /* IP_ACCEPT_LINK_LAYER_ADDRESSING || LWIP_IGMP */ - - LWIP_ASSERT_CORE_LOCKED(); - - IP_STATS_INC(ip.recv); - MIB2_STATS_INC(mib2.ipinreceives); - - /* identify the IP header */ - iphdr = (struct ip_hdr *)p->payload; - if (IPH_V(iphdr) != 4) { - LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_WARNING, ("IP packet dropped due to bad version number %"U16_F"\n", (u16_t)IPH_V(iphdr))); - ip4_debug_print(p); - pbuf_free(p); - IP_STATS_INC(ip.err); - IP_STATS_INC(ip.drop); - MIB2_STATS_INC(mib2.ipinhdrerrors); - return ERR_OK; - } - -#ifdef LWIP_HOOK_IP4_INPUT - if (LWIP_HOOK_IP4_INPUT(p, inp)) { - /* the packet has been eaten */ - return ERR_OK; - } -#endif - - /* obtain IP header length in number of 32-bit words */ - iphdr_hlen = IPH_HL(iphdr); - /* calculate IP header length in bytes */ - iphdr_hlen *= 4; - /* obtain ip length in bytes */ - iphdr_len = lwip_ntohs(IPH_LEN(iphdr)); - - /* Trim pbuf. This is especially required for packets < 60 bytes. */ - if (iphdr_len < p->tot_len) { - pbuf_realloc(p, iphdr_len); - } - - /* header length exceeds first pbuf length, or ip length exceeds total pbuf length? */ - if ((iphdr_hlen > p->len) || (iphdr_len > p->tot_len) || (iphdr_hlen < IP_HLEN)) { - if (iphdr_hlen < IP_HLEN) { - LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, - ("ip4_input: short IP header (%"U16_F" bytes) received, IP packet dropped\n", iphdr_hlen)); - } - if (iphdr_hlen > p->len) { - LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, - ("IP header (len %"U16_F") does not fit in first pbuf (len %"U16_F"), IP packet dropped.\n", - iphdr_hlen, p->len)); - } - if (iphdr_len > p->tot_len) { - LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, - ("IP (len %"U16_F") is longer than pbuf (len %"U16_F"), IP packet dropped.\n", - iphdr_len, p->tot_len)); - } - /* free (drop) packet pbufs */ - pbuf_free(p); - IP_STATS_INC(ip.lenerr); - IP_STATS_INC(ip.drop); - MIB2_STATS_INC(mib2.ipindiscards); - return ERR_OK; - } - - /* verify checksum */ -#if CHECKSUM_CHECK_IP - IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_CHECK_IP) { - if (inet_chksum(iphdr, iphdr_hlen) != 0) { - - LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, - ("Checksum (0x%"X16_F") failed, IP packet dropped.\n", inet_chksum(iphdr, iphdr_hlen))); - ip4_debug_print(p); - pbuf_free(p); - IP_STATS_INC(ip.chkerr); - IP_STATS_INC(ip.drop); - MIB2_STATS_INC(mib2.ipinhdrerrors); - return ERR_OK; - } - } -#endif - - /* copy IP addresses to aligned ip_addr_t */ - ip_addr_copy_from_ip4(ip_data.current_iphdr_dest, iphdr->dest); - ip_addr_copy_from_ip4(ip_data.current_iphdr_src, iphdr->src); - - /* match packet against an interface, i.e. is this packet for us? */ - if (ip4_addr_ismulticast(ip4_current_dest_addr())) { -#if LWIP_IGMP - if ((inp->flags & NETIF_FLAG_IGMP) && (igmp_lookfor_group(inp, ip4_current_dest_addr()))) { - /* IGMP snooping switches need 0.0.0.0 to be allowed as source address (RFC 4541) */ - ip4_addr_t allsystems; - IP4_ADDR(&allsystems, 224, 0, 0, 1); - if (ip4_addr_cmp(ip4_current_dest_addr(), &allsystems) && - ip4_addr_isany(ip4_current_src_addr())) { - check_ip_src = 0; - } - netif = inp; - } else { - netif = NULL; - } -#else /* LWIP_IGMP */ - if ((netif_is_up(inp)) && (!ip4_addr_isany_val(*netif_ip4_addr(inp)))) { - netif = inp; - } else { - netif = NULL; - } -#endif /* LWIP_IGMP */ - } else { - /* start trying with inp. if that's not acceptable, start walking the - list of configured netifs. - 'first' is used as a boolean to mark whether we started walking the list */ - int first = 1; - netif = inp; - do { - LWIP_DEBUGF(IP_DEBUG, ("ip_input: iphdr->dest 0x%"X32_F" netif->ip_addr 0x%"X32_F" (0x%"X32_F", 0x%"X32_F", 0x%"X32_F")\n", - ip4_addr_get_u32(&iphdr->dest), ip4_addr_get_u32(netif_ip4_addr(netif)), - ip4_addr_get_u32(&iphdr->dest) & ip4_addr_get_u32(netif_ip4_netmask(netif)), - ip4_addr_get_u32(netif_ip4_addr(netif)) & ip4_addr_get_u32(netif_ip4_netmask(netif)), - ip4_addr_get_u32(&iphdr->dest) & ~ip4_addr_get_u32(netif_ip4_netmask(netif)))); - - /* interface is up and configured? */ - if ((netif_is_up(netif)) && (!ip4_addr_isany_val(*netif_ip4_addr(netif)))) { - /* unicast to this interface address? */ - if (ip4_addr_cmp(ip4_current_dest_addr(), netif_ip4_addr(netif)) || - /* or broadcast on this interface network address? */ - ip4_addr_isbroadcast(ip4_current_dest_addr(), netif) -#if LWIP_NETIF_LOOPBACK && !LWIP_HAVE_LOOPIF - || (ip4_addr_get_u32(ip4_current_dest_addr()) == PP_HTONL(IPADDR_LOOPBACK)) -#endif /* LWIP_NETIF_LOOPBACK && !LWIP_HAVE_LOOPIF */ - ) { - LWIP_DEBUGF(IP_DEBUG, ("ip4_input: packet accepted on interface %c%c\n", - netif->name[0], netif->name[1])); - /* break out of for loop */ - break; - } -#if LWIP_AUTOIP - /* connections to link-local addresses must persist after changing - the netif's address (RFC3927 ch. 1.9) */ - if (autoip_accept_packet(netif, ip4_current_dest_addr())) { - LWIP_DEBUGF(IP_DEBUG, ("ip4_input: LLA packet accepted on interface %c%c\n", - netif->name[0], netif->name[1])); - /* break out of for loop */ - break; - } -#endif /* LWIP_AUTOIP */ - } - if (first) { -#if !LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF - /* Packets sent to the loopback address must not be accepted on an - * interface that does not have the loopback address assigned to it, - * unless a non-loopback interface is used for loopback traffic. */ - if (ip4_addr_isloopback(ip4_current_dest_addr())) { - netif = NULL; - break; - } -#endif /* !LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF */ - first = 0; - netif = netif_list; - } else { - netif = netif->next; - } - if (netif == inp) { - netif = netif->next; - } - } while (netif != NULL); - } - -#if IP_ACCEPT_LINK_LAYER_ADDRESSING - /* Pass DHCP messages regardless of destination address. DHCP traffic is addressed - * using link layer addressing (such as Ethernet MAC) so we must not filter on IP. - * According to RFC 1542 section 3.1.1, referred by RFC 2131). - * - * If you want to accept private broadcast communication while a netif is down, - * define LWIP_IP_ACCEPT_UDP_PORT(dst_port), e.g.: - * - * #define LWIP_IP_ACCEPT_UDP_PORT(dst_port) ((dst_port) == PP_NTOHS(12345)) - */ - if (netif == NULL) { - /* remote port is DHCP server? */ - if (IPH_PROTO(iphdr) == IP_PROTO_UDP) { - struct udp_hdr *udphdr = (struct udp_hdr *)((u8_t *)iphdr + iphdr_hlen); - LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE, ("ip4_input: UDP packet to DHCP client port %"U16_F"\n", - lwip_ntohs(udphdr->dest))); - if (IP_ACCEPT_LINK_LAYER_ADDRESSED_PORT(udphdr->dest)) { - LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE, ("ip4_input: DHCP packet accepted.\n")); - netif = inp; - check_ip_src = 0; - } - } - } -#endif /* IP_ACCEPT_LINK_LAYER_ADDRESSING */ - - /* broadcast or multicast packet source address? Compliant with RFC 1122: 3.2.1.3 */ -#if LWIP_IGMP || IP_ACCEPT_LINK_LAYER_ADDRESSING - if (check_ip_src -#if IP_ACCEPT_LINK_LAYER_ADDRESSING - /* DHCP servers need 0.0.0.0 to be allowed as source address (RFC 1.1.2.2: 3.2.1.3/a) */ - && !ip4_addr_isany_val(*ip4_current_src_addr()) -#endif /* IP_ACCEPT_LINK_LAYER_ADDRESSING */ - ) -#endif /* LWIP_IGMP || IP_ACCEPT_LINK_LAYER_ADDRESSING */ - { - if ((ip4_addr_isbroadcast(ip4_current_src_addr(), inp)) || - (ip4_addr_ismulticast(ip4_current_src_addr()))) { - /* packet source is not valid */ - LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("ip4_input: packet source is not valid.\n")); - /* free (drop) packet pbufs */ - pbuf_free(p); - IP_STATS_INC(ip.drop); - MIB2_STATS_INC(mib2.ipinaddrerrors); - MIB2_STATS_INC(mib2.ipindiscards); - return ERR_OK; - } - } - - /* packet not for us? */ - if (netif == NULL) { - /* packet not for us, route or discard */ - LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_TRACE, ("ip4_input: packet not for us.\n")); -#if IP_FORWARD - /* non-broadcast packet? */ - if (!ip4_addr_isbroadcast(ip4_current_dest_addr(), inp)) { - /* try to forward IP packet on (other) interfaces */ - ip4_forward(p, iphdr, inp); - } else -#endif /* IP_FORWARD */ - { - IP_STATS_INC(ip.drop); - MIB2_STATS_INC(mib2.ipinaddrerrors); - MIB2_STATS_INC(mib2.ipindiscards); - } - pbuf_free(p); - return ERR_OK; - } - /* packet consists of multiple fragments? */ - if ((IPH_OFFSET(iphdr) & PP_HTONS(IP_OFFMASK | IP_MF)) != 0) { -#if IP_REASSEMBLY /* packet fragment reassembly code present? */ - LWIP_DEBUGF(IP_DEBUG, ("IP packet is a fragment (id=0x%04"X16_F" tot_len=%"U16_F" len=%"U16_F" MF=%"U16_F" offset=%"U16_F"), calling ip4_reass()\n", - lwip_ntohs(IPH_ID(iphdr)), p->tot_len, lwip_ntohs(IPH_LEN(iphdr)), (u16_t)!!(IPH_OFFSET(iphdr) & PP_HTONS(IP_MF)), (u16_t)((lwip_ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK)*8))); - /* reassemble the packet*/ - p = ip4_reass(p); - /* packet not fully reassembled yet? */ - if (p == NULL) { - return ERR_OK; - } - iphdr = (struct ip_hdr *)p->payload; -#else /* IP_REASSEMBLY == 0, no packet fragment reassembly code present */ - pbuf_free(p); - LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("IP packet dropped since it was fragmented (0x%"X16_F") (while IP_REASSEMBLY == 0).\n", - lwip_ntohs(IPH_OFFSET(iphdr)))); - IP_STATS_INC(ip.opterr); - IP_STATS_INC(ip.drop); - /* unsupported protocol feature */ - MIB2_STATS_INC(mib2.ipinunknownprotos); - return ERR_OK; -#endif /* IP_REASSEMBLY */ - } - -#if IP_OPTIONS_ALLOWED == 0 /* no support for IP options in the IP header? */ - -#if LWIP_IGMP - /* there is an extra "router alert" option in IGMP messages which we allow for but do not police */ - if ((iphdr_hlen > IP_HLEN) && (IPH_PROTO(iphdr) != IP_PROTO_IGMP)) { -#else - if (iphdr_hlen > IP_HLEN) { -#endif /* LWIP_IGMP */ - LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("IP packet dropped since there were IP options (while IP_OPTIONS_ALLOWED == 0).\n")); - pbuf_free(p); - IP_STATS_INC(ip.opterr); - IP_STATS_INC(ip.drop); - /* unsupported protocol feature */ - MIB2_STATS_INC(mib2.ipinunknownprotos); - return ERR_OK; - } -#endif /* IP_OPTIONS_ALLOWED == 0 */ - - /* send to upper layers */ -#if IP_DEBUG && LWIP_IP_DEBUG_TARGET - if (debug_target_match(0, ip_2_ipX(&iphdr->src), ip_2_ipX(&iphdr->dest))) - { -#endif - LWIP_DEBUGF(IP_DEBUG, ("ip4_input: \n")); - ip4_debug_print(p); - LWIP_DEBUGF(IP_DEBUG, ("ip4_input: p->len %"U16_F" p->tot_len %"U16_F"\n", p->len, p->tot_len)); -#if IP_DEBUG && LWIP_IP_DEBUG_TARGET - } -#endif - - ip_data.current_netif = netif; - ip_data.current_input_netif = inp; - ip_data.current_ip4_header = iphdr; - ip_data.current_ip_header_tot_len = IPH_HL(iphdr) * 4; - -#if LWIP_RAW - /* raw input did not eat the packet? */ - if (raw_input(p, inp) == 0) -#endif /* LWIP_RAW */ - { - pbuf_header(p, -(s16_t)iphdr_hlen); /* Move to payload, no check necessary. */ - - switch (IPH_PROTO(iphdr)) { -#if LWIP_UDP - case IP_PROTO_UDP: -#if LWIP_UDPLITE - case IP_PROTO_UDPLITE: -#endif /* LWIP_UDPLITE */ - MIB2_STATS_INC(mib2.ipindelivers); - udp_input(p, inp); - break; -#endif /* LWIP_UDP */ -#if LWIP_TCP - case IP_PROTO_TCP: - MIB2_STATS_INC(mib2.ipindelivers); - tcp_input(p, inp); - break; -#endif /* LWIP_TCP */ -#if LWIP_ICMP - case IP_PROTO_ICMP: - MIB2_STATS_INC(mib2.ipindelivers); - icmp_input(p, inp); - break; -#endif /* LWIP_ICMP */ -#if LWIP_IGMP - case IP_PROTO_IGMP: - igmp_input(p, inp, ip4_current_dest_addr()); - break; -#endif /* LWIP_IGMP */ - default: -#if LWIP_ICMP - /* send ICMP destination protocol unreachable unless is was a broadcast */ - if (!ip4_addr_isbroadcast(ip4_current_dest_addr(), netif) && - !ip4_addr_ismulticast(ip4_current_dest_addr())) { - pbuf_header_force(p, iphdr_hlen); /* Move to ip header, no check necessary. */ - p->payload = iphdr; - icmp_dest_unreach(p, ICMP_DUR_PROTO); - } -#endif /* LWIP_ICMP */ - pbuf_free(p); - - LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("Unsupported transport protocol %"U16_F"\n", (u16_t)IPH_PROTO(iphdr))); - - IP_STATS_INC(ip.proterr); - IP_STATS_INC(ip.drop); - MIB2_STATS_INC(mib2.ipinunknownprotos); - } - } - - /* @todo: this is not really necessary... */ - ip_data.current_netif = NULL; - ip_data.current_input_netif = NULL; - ip_data.current_ip4_header = NULL; - ip_data.current_ip_header_tot_len = 0; - ip4_addr_set_any(ip4_current_src_addr()); - ip4_addr_set_any(ip4_current_dest_addr()); - - return ERR_OK; -} - -/** - * Sends an IP packet on a network interface. This function constructs - * the IP header and calculates the IP header checksum. If the source - * IP address is NULL, the IP address of the outgoing network - * interface is filled in as source address. - * If the destination IP address is LWIP_IP_HDRINCL, p is assumed to already - * include an IP header and p->payload points to it instead of the data. - * - * @param p the packet to send (p->payload points to the data, e.g. next - protocol header; if dest == LWIP_IP_HDRINCL, p already includes an - IP header and p->payload points to that IP header) - * @param src the source IP address to send from (if src == IP4_ADDR_ANY, the - * IP address of the netif used to send is used as source address) - * @param dest the destination IP address to send the packet to - * @param ttl the TTL value to be set in the IP header - * @param tos the TOS value to be set in the IP header - * @param proto the PROTOCOL to be set in the IP header - * @param netif the netif on which to send this packet - * @return ERR_OK if the packet was sent OK - * ERR_BUF if p doesn't have enough space for IP/LINK headers - * returns errors returned by netif->output - * - * @note ip_id: RFC791 "some host may be able to simply use - * unique identifiers independent of destination" - */ -err_t -ip4_output_if(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest, - u8_t ttl, u8_t tos, - u8_t proto, struct netif *netif) -{ -#if IP_OPTIONS_SEND - return ip4_output_if_opt(p, src, dest, ttl, tos, proto, netif, NULL, 0); -} - -/** - * Same as ip_output_if() but with the possibility to include IP options: - * - * @ param ip_options pointer to the IP options, copied into the IP header - * @ param optlen length of ip_options - */ -err_t -ip4_output_if_opt(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest, - u8_t ttl, u8_t tos, u8_t proto, struct netif *netif, void *ip_options, - u16_t optlen) -{ -#endif /* IP_OPTIONS_SEND */ - const ip4_addr_t *src_used = src; - if (dest != LWIP_IP_HDRINCL) { - if (ip4_addr_isany(src)) { - src_used = netif_ip4_addr(netif); - } - } - -#if IP_OPTIONS_SEND - return ip4_output_if_opt_src(p, src_used, dest, ttl, tos, proto, netif, - ip_options, optlen); -#else /* IP_OPTIONS_SEND */ - return ip4_output_if_src(p, src_used, dest, ttl, tos, proto, netif); -#endif /* IP_OPTIONS_SEND */ -} - -/** - * Same as ip_output_if() but 'src' address is not replaced by netif address - * when it is 'any'. - */ -err_t -ip4_output_if_src(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest, - u8_t ttl, u8_t tos, - u8_t proto, struct netif *netif) -{ -#if IP_OPTIONS_SEND - return ip4_output_if_opt_src(p, src, dest, ttl, tos, proto, netif, NULL, 0); -} - -/** - * Same as ip_output_if_opt() but 'src' address is not replaced by netif address - * when it is 'any'. - */ -err_t -ip4_output_if_opt_src(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest, - u8_t ttl, u8_t tos, u8_t proto, struct netif *netif, void *ip_options, - u16_t optlen) -{ -#endif /* IP_OPTIONS_SEND */ - struct ip_hdr *iphdr; - ip4_addr_t dest_addr; -#if CHECKSUM_GEN_IP_INLINE - u32_t chk_sum = 0; -#endif /* CHECKSUM_GEN_IP_INLINE */ - - LWIP_IP_CHECK_PBUF_REF_COUNT_FOR_TX(p); - - MIB2_STATS_INC(mib2.ipoutrequests); - - /* Should the IP header be generated or is it already included in p? */ - if (dest != LWIP_IP_HDRINCL) { - u16_t ip_hlen = IP_HLEN; -#if IP_OPTIONS_SEND - u16_t optlen_aligned = 0; - if (optlen != 0) { -#if CHECKSUM_GEN_IP_INLINE - int i; -#endif /* CHECKSUM_GEN_IP_INLINE */ - /* round up to a multiple of 4 */ - optlen_aligned = ((optlen + 3) & ~3); - ip_hlen += optlen_aligned; - /* First write in the IP options */ - if (pbuf_header(p, optlen_aligned)) { - LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip4_output_if_opt: not enough room for IP options in pbuf\n")); - IP_STATS_INC(ip.err); - MIB2_STATS_INC(mib2.ipoutdiscards); - return ERR_BUF; - } - MEMCPY(p->payload, ip_options, optlen); - if (optlen < optlen_aligned) { - /* zero the remaining bytes */ - memset(((char*)p->payload) + optlen, 0, optlen_aligned - optlen); - } -#if CHECKSUM_GEN_IP_INLINE - for (i = 0; i < optlen_aligned/2; i++) { - chk_sum += ((u16_t*)p->payload)[i]; - } -#endif /* CHECKSUM_GEN_IP_INLINE */ - } -#endif /* IP_OPTIONS_SEND */ - /* generate IP header */ - if (pbuf_header(p, IP_HLEN)) { - LWIP_DEBUGF(IP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip4_output: not enough room for IP header in pbuf\n")); - - IP_STATS_INC(ip.err); - MIB2_STATS_INC(mib2.ipoutdiscards); - return ERR_BUF; - } - - iphdr = (struct ip_hdr *)p->payload; - LWIP_ASSERT("check that first pbuf can hold struct ip_hdr", - (p->len >= sizeof(struct ip_hdr))); - - IPH_TTL_SET(iphdr, ttl); - IPH_PROTO_SET(iphdr, proto); -#if CHECKSUM_GEN_IP_INLINE - chk_sum += PP_NTOHS(proto | (ttl << 8)); -#endif /* CHECKSUM_GEN_IP_INLINE */ - - /* dest cannot be NULL here */ - ip4_addr_copy(iphdr->dest, *dest); -#if CHECKSUM_GEN_IP_INLINE - chk_sum += ip4_addr_get_u32(&iphdr->dest) & 0xFFFF; - chk_sum += ip4_addr_get_u32(&iphdr->dest) >> 16; -#endif /* CHECKSUM_GEN_IP_INLINE */ - - IPH_VHL_SET(iphdr, 4, ip_hlen / 4); - IPH_TOS_SET(iphdr, tos); -#if CHECKSUM_GEN_IP_INLINE - chk_sum += PP_NTOHS(tos | (iphdr->_v_hl << 8)); -#endif /* CHECKSUM_GEN_IP_INLINE */ - IPH_LEN_SET(iphdr, lwip_htons(p->tot_len)); -#if CHECKSUM_GEN_IP_INLINE - chk_sum += iphdr->_len; -#endif /* CHECKSUM_GEN_IP_INLINE */ - IPH_OFFSET_SET(iphdr, 0); - IPH_ID_SET(iphdr, lwip_htons(ip_id)); -#if CHECKSUM_GEN_IP_INLINE - chk_sum += iphdr->_id; -#endif /* CHECKSUM_GEN_IP_INLINE */ - ++ip_id; - - if (src == NULL) { - ip4_addr_copy(iphdr->src, *IP4_ADDR_ANY4); - } else { - /* src cannot be NULL here */ - ip4_addr_copy(iphdr->src, *src); - } - -#if CHECKSUM_GEN_IP_INLINE - chk_sum += ip4_addr_get_u32(&iphdr->src) & 0xFFFF; - chk_sum += ip4_addr_get_u32(&iphdr->src) >> 16; - chk_sum = (chk_sum >> 16) + (chk_sum & 0xFFFF); - chk_sum = (chk_sum >> 16) + chk_sum; - chk_sum = ~chk_sum; - IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_IP) { - iphdr->_chksum = (u16_t)chk_sum; /* network order */ - } -#if LWIP_CHECKSUM_CTRL_PER_NETIF - else { - IPH_CHKSUM_SET(iphdr, 0); - } -#endif /* LWIP_CHECKSUM_CTRL_PER_NETIF*/ -#else /* CHECKSUM_GEN_IP_INLINE */ - IPH_CHKSUM_SET(iphdr, 0); -#if CHECKSUM_GEN_IP - IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_IP) { - IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, ip_hlen)); - } -#endif /* CHECKSUM_GEN_IP */ -#endif /* CHECKSUM_GEN_IP_INLINE */ - } else { - /* IP header already included in p */ - iphdr = (struct ip_hdr *)p->payload; - ip4_addr_copy(dest_addr, iphdr->dest); - dest = &dest_addr; - } - - IP_STATS_INC(ip.xmit); - -#if IP_DEBUG && LWIP_IP_DEBUG_TARGET - if (debug_target_match(0, ip_2_ipX(src), ip_2_ipX(dest))) - { -#endif - LWIP_DEBUGF(IP_DEBUG, ("ip4_output_if: %c%c%"U16_F"\n", netif->name[0], netif->name[1], (u16_t)netif->num)); - ip4_debug_print(p); -#if IP_DEBUG && LWIP_IP_DEBUG_TARGET - } -#endif - -#if ENABLE_LOOPBACK - if (ip4_addr_cmp(dest, netif_ip4_addr(netif)) -#if !LWIP_HAVE_LOOPIF - || ip4_addr_isloopback(dest) -#endif /* !LWIP_HAVE_LOOPIF */ - ) { - /* Packet to self, enqueue it for loopback */ - LWIP_DEBUGF(IP_DEBUG, ("netif_loop_output()")); - return netif_loop_output(netif, p); - } -#if LWIP_MULTICAST_TX_OPTIONS - if ((p->flags & PBUF_FLAG_MCASTLOOP) != 0) { - netif_loop_output(netif, p); - } -#endif /* LWIP_MULTICAST_TX_OPTIONS */ -#endif /* ENABLE_LOOPBACK */ -#if IP_FRAG - /* don't fragment if interface has mtu set to 0 [loopif] */ - if (netif->mtu && (p->tot_len > netif->mtu)) { - return ip4_frag(p, netif, dest); - } -#endif /* IP_FRAG */ - - LWIP_DEBUGF(IP_DEBUG, ("ip4_output_if: call netif->output()\n")); - if (netif->output != NULL) { - return netif->output(netif, p, dest); - } - return ERR_RTE; -} - -/** - * Simple interface to ip_output_if. It finds the outgoing network - * interface and calls upon ip_output_if to do the actual work. - * - * @param p the packet to send (p->payload points to the data, e.g. next - protocol header; if dest == LWIP_IP_HDRINCL, p already includes an - IP header and p->payload points to that IP header) - * @param src the source IP address to send from (if src == IP4_ADDR_ANY, the - * IP address of the netif used to send is used as source address) - * @param dest the destination IP address to send the packet to - * @param ttl the TTL value to be set in the IP header - * @param tos the TOS value to be set in the IP header - * @param proto the PROTOCOL to be set in the IP header - * @param pcb the management channel - * - * @return ERR_RTE if no route is found - * see ip_output_if() for more return values - */ -err_t -ip4_output(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest, - u8_t ttl, u8_t tos, u8_t proto, struct ip_pcb *pcb) -{ - err_t ret; - struct netif *netif; - - LWIP_IP_CHECK_PBUF_REF_COUNT_FOR_TX(p); - - if ((netif = ip4_route_src(dest, src)) == NULL) { - LWIP_DEBUGF(IP_DEBUG, ("ip4_output: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", - ip4_addr1_16(dest), ip4_addr2_16(dest), ip4_addr3_16(dest), ip4_addr4_16(dest))); - IP_STATS_INC(ip.rterr); - return ERR_RTE; - } - - netif_apply_pcb(netif, pcb); - ret = ip4_output_if(p, src, dest, ttl, tos, proto, netif); - netif_apply_pcb(netif, NULL); - - return ret; -} - -#if LWIP_NETIF_HWADDRHINT -/** Like ip_output, but takes and addr_hint pointer that is passed on to netif->addr_hint - * before calling ip_output_if. - * - * @param p the packet to send (p->payload points to the data, e.g. next - protocol header; if dest == LWIP_IP_HDRINCL, p already includes an - IP header and p->payload points to that IP header) - * @param src the source IP address to send from (if src == IP4_ADDR_ANY, the - * IP address of the netif used to send is used as source address) - * @param dest the destination IP address to send the packet to - * @param ttl the TTL value to be set in the IP header - * @param tos the TOS value to be set in the IP header - * @param proto the PROTOCOL to be set in the IP header - * @param addr_hint address hint pointer set to netif->addr_hint before - * calling ip_output_if() - * - * @return ERR_RTE if no route is found - * see ip_output_if() for more return values - */ -err_t -ip4_output_hinted(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest, - u8_t ttl, u8_t tos, u8_t proto, u8_t *addr_hint) -{ - struct netif *netif; - err_t err; - - LWIP_IP_CHECK_PBUF_REF_COUNT_FOR_TX(p); - - if ((netif = ip4_route_src(dest, src)) == NULL) { - LWIP_DEBUGF(IP_DEBUG, ("ip4_output: No route to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", - ip4_addr1_16(dest), ip4_addr2_16(dest), ip4_addr3_16(dest), ip4_addr4_16(dest))); - IP_STATS_INC(ip.rterr); - return ERR_RTE; - } - - NETIF_SET_HWADDRHINT(netif, addr_hint); - err = ip4_output_if(p, src, dest, ttl, tos, proto, netif); - NETIF_SET_HWADDRHINT(netif, NULL); - - return err; -} -#endif /* LWIP_NETIF_HWADDRHINT*/ - -#if IP_DEBUG -/* Print an IP header by using LWIP_DEBUGF - * @param p an IP packet, p->payload pointing to the IP header - */ -void -ip4_debug_print(struct pbuf *p) -{ - struct ip_hdr *iphdr = (struct ip_hdr *)p->payload; - - LWIP_DEBUGF(IP_DEBUG, ("IP header:\n")); - LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); - LWIP_DEBUGF(IP_DEBUG, ("|%2"S16_F" |%2"S16_F" | 0x%02"X16_F" | %5"U16_F" | (v, hl, tos, len)\n", - (u16_t)IPH_V(iphdr), - (u16_t)IPH_HL(iphdr), - (u16_t)IPH_TOS(iphdr), - lwip_ntohs(IPH_LEN(iphdr)))); - LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); - LWIP_DEBUGF(IP_DEBUG, ("| %5"U16_F" |%"U16_F"%"U16_F"%"U16_F"| %4"U16_F" | (id, flags, offset)\n", - lwip_ntohs(IPH_ID(iphdr)), - (u16_t)(lwip_ntohs(IPH_OFFSET(iphdr)) >> 15 & 1), - (u16_t)(lwip_ntohs(IPH_OFFSET(iphdr)) >> 14 & 1), - (u16_t)(lwip_ntohs(IPH_OFFSET(iphdr)) >> 13 & 1), - (u16_t)(lwip_ntohs(IPH_OFFSET(iphdr)) & IP_OFFMASK))); - LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); - LWIP_DEBUGF(IP_DEBUG, ("| %3"U16_F" | %3"U16_F" | 0x%04"X16_F" | (ttl, proto, chksum)\n", - (u16_t)IPH_TTL(iphdr), - (u16_t)IPH_PROTO(iphdr), - lwip_ntohs(IPH_CHKSUM(iphdr)))); - LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); - LWIP_DEBUGF(IP_DEBUG, ("| %3"U16_F" | %3"U16_F" | %3"U16_F" | %3"U16_F" | (src)\n", - ip4_addr1_16(&iphdr->src), - ip4_addr2_16(&iphdr->src), - ip4_addr3_16(&iphdr->src), - ip4_addr4_16(&iphdr->src))); - LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); - LWIP_DEBUGF(IP_DEBUG, ("| %3"U16_F" | %3"U16_F" | %3"U16_F" | %3"U16_F" | (dest)\n", - ip4_addr1_16(&iphdr->dest), - ip4_addr2_16(&iphdr->dest), - ip4_addr3_16(&iphdr->dest), - ip4_addr4_16(&iphdr->dest))); - LWIP_DEBUGF(IP_DEBUG, ("+-------------------------------+\n")); -} -#endif /* IP_DEBUG */ - -#endif /* LWIP_IPV4 */ diff --git a/third_party/lwip/repo/lwip/src/core/ipv4/ip4_addr.c b/third_party/lwip/repo/lwip/src/core/ipv4/ip4_addr.c deleted file mode 100644 index 2d479923bd55c0..00000000000000 --- a/third_party/lwip/repo/lwip/src/core/ipv4/ip4_addr.c +++ /dev/null @@ -1,331 +0,0 @@ -/** - * @file - * This is the IPv4 address tools implementation. - * - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ - -#include "lwip/opt.h" - -#if LWIP_IPV4 - -#include "lwip/ip_addr.h" -#include "lwip/netif.h" - -/* used by IP4_ADDR_ANY and IP_ADDR_BROADCAST in ip_addr.h */ -const ip_addr_t ip_addr_any = IPADDR4_INIT(IPADDR_ANY); -const ip_addr_t ip_addr_broadcast = IPADDR4_INIT(IPADDR_BROADCAST); - -/** - * Determine if an address is a broadcast address on a network interface - * - * @param addr address to be checked - * @param netif the network interface against which the address is checked - * @return returns non-zero if the address is a broadcast address - */ -u8_t -ip4_addr_isbroadcast_u32(u32_t addr, const struct netif *netif) -{ - ip4_addr_t ipaddr; - ip4_addr_set_u32(&ipaddr, addr); - - /* all ones (broadcast) or all zeroes (old skool broadcast) */ - if ((~addr == IPADDR_ANY) || - (addr == IPADDR_ANY)) { - return 1; - /* no broadcast support on this network interface? */ - } else if ((netif->flags & NETIF_FLAG_BROADCAST) == 0) { - /* the given address cannot be a broadcast address - * nor can we check against any broadcast addresses */ - return 0; - /* address matches network interface address exactly? => no broadcast */ - } else if (addr == ip4_addr_get_u32(netif_ip4_addr(netif))) { - return 0; - /* on the same (sub) network... */ - } else if (ip4_addr_netcmp(&ipaddr, netif_ip4_addr(netif), netif_ip4_netmask(netif)) - /* ...and host identifier bits are all ones? =>... */ - && ((addr & ~ip4_addr_get_u32(netif_ip4_netmask(netif))) == - (IPADDR_BROADCAST & ~ip4_addr_get_u32(netif_ip4_netmask(netif))))) { - /* => network broadcast address */ - return 1; - } else { - return 0; - } -} - -/** Checks if a netmask is valid (starting with ones, then only zeros) - * - * @param netmask the IPv4 netmask to check (in network byte order!) - * @return 1 if the netmask is valid, 0 if it is not - */ -u8_t -ip4_addr_netmask_valid(u32_t netmask) -{ - u32_t mask; - u32_t nm_hostorder = lwip_htonl(netmask); - - /* first, check for the first zero */ - for (mask = 1UL << 31 ; mask != 0; mask >>= 1) { - if ((nm_hostorder & mask) == 0) { - break; - } - } - /* then check that there is no one */ - for (; mask != 0; mask >>= 1) { - if ((nm_hostorder & mask) != 0) { - /* there is a one after the first zero -> invalid */ - return 0; - } - } - /* no one after the first zero -> valid */ - return 1; -} - -/* Here for now until needed in other places in lwIP */ -#ifndef isprint -#define in_range(c, lo, up) ((u8_t)c >= lo && (u8_t)c <= up) -#define isprint(c) in_range(c, 0x20, 0x7f) -#define isdigit(c) in_range(c, '0', '9') -#define isxdigit(c) (isdigit(c) || in_range(c, 'a', 'f') || in_range(c, 'A', 'F')) -#define islower(c) in_range(c, 'a', 'z') -#define isspace(c) (c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v') -#endif - -/** - * Ascii internet address interpretation routine. - * The value returned is in network order. - * - * @param cp IP address in ascii representation (e.g. "127.0.0.1") - * @return ip address in network order - */ -u32_t -ipaddr_addr(const char *cp) -{ - ip4_addr_t val; - - if (ip4addr_aton(cp, &val)) { - return ip4_addr_get_u32(&val); - } - return (IPADDR_NONE); -} - -/** - * Check whether "cp" is a valid ascii representation - * of an Internet address and convert to a binary address. - * Returns 1 if the address is valid, 0 if not. - * This replaces inet_addr, the return value from which - * cannot distinguish between failure and a local broadcast address. - * - * @param cp IP address in ascii representation (e.g. "127.0.0.1") - * @param addr pointer to which to save the ip address in network order - * @return 1 if cp could be converted to addr, 0 on failure - */ -int -ip4addr_aton(const char *cp, ip4_addr_t *addr) -{ - u32_t val; - u8_t base; - char c; - u32_t parts[4]; - u32_t *pp = parts; - - c = *cp; - for (;;) { - /* - * Collect number up to ``.''. - * Values are specified as for C: - * 0x=hex, 0=octal, 1-9=decimal. - */ - if (!isdigit(c)) { - return 0; - } - val = 0; - base = 10; - if (c == '0') { - c = *++cp; - if (c == 'x' || c == 'X') { - base = 16; - c = *++cp; - } else { - base = 8; - } - } - for (;;) { - if (isdigit(c)) { - val = (val * base) + (u32_t)(c - '0'); - c = *++cp; - } else if (base == 16 && isxdigit(c)) { - val = (val << 4) | (u32_t)(c + 10 - (islower(c) ? 'a' : 'A')); - c = *++cp; - } else { - break; - } - } - if (c == '.') { - /* - * Internet format: - * a.b.c.d - * a.b.c (with c treated as 16 bits) - * a.b (with b treated as 24 bits) - */ - if (pp >= parts + 3) { - return 0; - } - *pp++ = val; - c = *++cp; - } else { - break; - } - } - /* - * Check for trailing characters. - */ - if (c != '\0' && !isspace(c)) { - return 0; - } - /* - * Concoct the address according to - * the number of parts specified. - */ - switch (pp - parts + 1) { - - case 0: - return 0; /* initial nondigit */ - - case 1: /* a -- 32 bits */ - break; - - case 2: /* a.b -- 8.24 bits */ - if (val > 0xffffffUL) { - return 0; - } - if (parts[0] > 0xff) { - return 0; - } - val |= parts[0] << 24; - break; - - case 3: /* a.b.c -- 8.8.16 bits */ - if (val > 0xffff) { - return 0; - } - if ((parts[0] > 0xff) || (parts[1] > 0xff)) { - return 0; - } - val |= (parts[0] << 24) | (parts[1] << 16); - break; - - case 4: /* a.b.c.d -- 8.8.8.8 bits */ - if (val > 0xff) { - return 0; - } - if ((parts[0] > 0xff) || (parts[1] > 0xff) || (parts[2] > 0xff)) { - return 0; - } - val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8); - break; - default: - LWIP_ASSERT("unhandled", 0); - break; - } - if (addr) { - ip4_addr_set_u32(addr, lwip_htonl(val)); - } - return 1; -} - -/** - * Convert numeric IP address into decimal dotted ASCII representation. - * returns ptr to static buffer; not reentrant! - * - * @param addr ip address in network order to convert - * @return pointer to a global static (!) buffer that holds the ASCII - * representation of addr - */ -char* -ip4addr_ntoa(const ip4_addr_t *addr) -{ - static char str[IP4ADDR_STRLEN_MAX]; - return ip4addr_ntoa_r(addr, str, IP4ADDR_STRLEN_MAX); -} - -/** - * Same as ipaddr_ntoa, but reentrant since a user-supplied buffer is used. - * - * @param addr ip address in network order to convert - * @param buf target buffer where the string is stored - * @param buflen length of buf - * @return either pointer to buf which now holds the ASCII - * representation of addr or NULL if buf was too small - */ -char* -ip4addr_ntoa_r(const ip4_addr_t *addr, char *buf, int buflen) -{ - u32_t s_addr; - char inv[3]; - char *rp; - u8_t *ap; - u8_t rem; - u8_t n; - u8_t i; - int len = 0; - - s_addr = ip4_addr_get_u32(addr); - - rp = buf; - ap = (u8_t *)&s_addr; - for (n = 0; n < 4; n++) { - i = 0; - do { - rem = *ap % (u8_t)10; - *ap /= (u8_t)10; - inv[i++] = (char)('0' + rem); - } while (*ap); - while (i--) { - if (len++ >= buflen) { - return NULL; - } - *rp++ = inv[i]; - } - if (len++ >= buflen) { - return NULL; - } - *rp++ = '.'; - ap++; - } - *--rp = 0; - return buf; -} - -#endif /* LWIP_IPV4 */ diff --git a/third_party/lwip/repo/lwip/src/core/ipv4/ip4_frag.c b/third_party/lwip/repo/lwip/src/core/ipv4/ip4_frag.c deleted file mode 100644 index fdb20886cb78a8..00000000000000 --- a/third_party/lwip/repo/lwip/src/core/ipv4/ip4_frag.c +++ /dev/null @@ -1,864 +0,0 @@ -/** - * @file - * This is the IPv4 packet segmentation and reassembly implementation. - * - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Jani Monoses - * Simon Goldschmidt - * original reassembly code by Adam Dunkels - * - */ - -#include "lwip/opt.h" - -#if LWIP_IPV4 - -#include "lwip/ip4_frag.h" -#include "lwip/def.h" -#include "lwip/inet_chksum.h" -#include "lwip/netif.h" -#include "lwip/stats.h" -#include "lwip/icmp.h" - -#include - -#if IP_REASSEMBLY -/** - * The IP reassembly code currently has the following limitations: - * - IP header options are not supported - * - fragments must not overlap (e.g. due to different routes), - * currently, overlapping or duplicate fragments are thrown away - * if IP_REASS_CHECK_OVERLAP=1 (the default)! - * - * @todo: work with IP header options - */ - -/** Setting this to 0, you can turn off checking the fragments for overlapping - * regions. The code gets a little smaller. Only use this if you know that - * overlapping won't occur on your network! */ -#ifndef IP_REASS_CHECK_OVERLAP -#define IP_REASS_CHECK_OVERLAP 1 -#endif /* IP_REASS_CHECK_OVERLAP */ - -/** Set to 0 to prevent freeing the oldest datagram when the reassembly buffer is - * full (IP_REASS_MAX_PBUFS pbufs are enqueued). The code gets a little smaller. - * Datagrams will be freed by timeout only. Especially useful when MEMP_NUM_REASSDATA - * is set to 1, so one datagram can be reassembled at a time, only. */ -#ifndef IP_REASS_FREE_OLDEST -#define IP_REASS_FREE_OLDEST 1 -#endif /* IP_REASS_FREE_OLDEST */ - -#define IP_REASS_FLAG_LASTFRAG 0x01 - -#define IP_REASS_VALIDATE_TELEGRAM_FINISHED 1 -#define IP_REASS_VALIDATE_PBUF_QUEUED 0 -#define IP_REASS_VALIDATE_PBUF_DROPPED -1 - -/** This is a helper struct which holds the starting - * offset and the ending offset of this fragment to - * easily chain the fragments. - * It has the same packing requirements as the IP header, since it replaces - * the IP header in memory in incoming fragments (after copying it) to keep - * track of the various fragments. (-> If the IP header doesn't need packing, - * this struct doesn't need packing, too.) - */ -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct ip_reass_helper { - PACK_STRUCT_FIELD(struct pbuf *next_pbuf); - PACK_STRUCT_FIELD(u16_t start); - PACK_STRUCT_FIELD(u16_t end); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -#define IP_ADDRESSES_AND_ID_MATCH(iphdrA, iphdrB) \ - (ip4_addr_cmp(&(iphdrA)->src, &(iphdrB)->src) && \ - ip4_addr_cmp(&(iphdrA)->dest, &(iphdrB)->dest) && \ - IPH_ID(iphdrA) == IPH_ID(iphdrB)) ? 1 : 0 - -/* global variables */ -static struct ip_reassdata *reassdatagrams; -static u16_t ip_reass_pbufcount; - -/* function prototypes */ -static void ip_reass_dequeue_datagram(struct ip_reassdata *ipr, struct ip_reassdata *prev); -static int ip_reass_free_complete_datagram(struct ip_reassdata *ipr, struct ip_reassdata *prev); - -/** - * Reassembly timer base function - * for both NO_SYS == 0 and 1 (!). - * - * Should be called every 1000 msec (defined by IP_TMR_INTERVAL). - */ -void -ip_reass_tmr(void) -{ - struct ip_reassdata *r, *prev = NULL; - - r = reassdatagrams; - while (r != NULL) { - /* Decrement the timer. Once it reaches 0, - * clean up the incomplete fragment assembly */ - if (r->timer > 0) { - r->timer--; - LWIP_DEBUGF(IP_REASS_DEBUG, ("ip_reass_tmr: timer dec %"U16_F"\n",(u16_t)r->timer)); - prev = r; - r = r->next; - } else { - /* reassembly timed out */ - struct ip_reassdata *tmp; - LWIP_DEBUGF(IP_REASS_DEBUG, ("ip_reass_tmr: timer timed out\n")); - tmp = r; - /* get the next pointer before freeing */ - r = r->next; - /* free the helper struct and all enqueued pbufs */ - ip_reass_free_complete_datagram(tmp, prev); - } - } -} - -/** - * Free a datagram (struct ip_reassdata) and all its pbufs. - * Updates the total count of enqueued pbufs (ip_reass_pbufcount), - * SNMP counters and sends an ICMP time exceeded packet. - * - * @param ipr datagram to free - * @param prev the previous datagram in the linked list - * @return the number of pbufs freed - */ -static int -ip_reass_free_complete_datagram(struct ip_reassdata *ipr, struct ip_reassdata *prev) -{ - u16_t pbufs_freed = 0; - u16_t clen; - struct pbuf *p; - struct ip_reass_helper *iprh; - - LWIP_ASSERT("prev != ipr", prev != ipr); - if (prev != NULL) { - LWIP_ASSERT("prev->next == ipr", prev->next == ipr); - } - - MIB2_STATS_INC(mib2.ipreasmfails); -#if LWIP_ICMP - iprh = (struct ip_reass_helper *)ipr->p->payload; - if (iprh->start == 0) { - /* The first fragment was received, send ICMP time exceeded. */ - /* First, de-queue the first pbuf from r->p. */ - p = ipr->p; - ipr->p = iprh->next_pbuf; - /* Then, copy the original header into it. */ - SMEMCPY(p->payload, &ipr->iphdr, IP_HLEN); - icmp_time_exceeded(p, ICMP_TE_FRAG); - clen = pbuf_clen(p); - LWIP_ASSERT("pbufs_freed + clen <= 0xffff", pbufs_freed + clen <= 0xffff); - pbufs_freed += clen; - pbuf_free(p); - } -#endif /* LWIP_ICMP */ - - /* First, free all received pbufs. The individual pbufs need to be released - separately as they have not yet been chained */ - p = ipr->p; - while (p != NULL) { - struct pbuf *pcur; - iprh = (struct ip_reass_helper *)p->payload; - pcur = p; - /* get the next pointer before freeing */ - p = iprh->next_pbuf; - clen = pbuf_clen(pcur); - LWIP_ASSERT("pbufs_freed + clen <= 0xffff", pbufs_freed + clen <= 0xffff); - pbufs_freed += clen; - pbuf_free(pcur); - } - /* Then, unchain the struct ip_reassdata from the list and free it. */ - ip_reass_dequeue_datagram(ipr, prev); - LWIP_ASSERT("ip_reass_pbufcount >= clen", ip_reass_pbufcount >= pbufs_freed); - ip_reass_pbufcount -= pbufs_freed; - - return pbufs_freed; -} - -#if IP_REASS_FREE_OLDEST -/** - * Free the oldest datagram to make room for enqueueing new fragments. - * The datagram 'fraghdr' belongs to is not freed! - * - * @param fraghdr IP header of the current fragment - * @param pbufs_needed number of pbufs needed to enqueue - * (used for freeing other datagrams if not enough space) - * @return the number of pbufs freed - */ -static int -ip_reass_remove_oldest_datagram(struct ip_hdr *fraghdr, int pbufs_needed) -{ - /* @todo Can't we simply remove the last datagram in the - * linked list behind reassdatagrams? - */ - struct ip_reassdata *r, *oldest, *prev, *oldest_prev; - int pbufs_freed = 0, pbufs_freed_current; - int other_datagrams; - - /* Free datagrams until being allowed to enqueue 'pbufs_needed' pbufs, - * but don't free the datagram that 'fraghdr' belongs to! */ - do { - oldest = NULL; - prev = NULL; - oldest_prev = NULL; - other_datagrams = 0; - r = reassdatagrams; - while (r != NULL) { - if (!IP_ADDRESSES_AND_ID_MATCH(&r->iphdr, fraghdr)) { - /* Not the same datagram as fraghdr */ - other_datagrams++; - if (oldest == NULL) { - oldest = r; - oldest_prev = prev; - } else if (r->timer <= oldest->timer) { - /* older than the previous oldest */ - oldest = r; - oldest_prev = prev; - } - } - if (r->next != NULL) { - prev = r; - } - r = r->next; - } - if (oldest != NULL) { - pbufs_freed_current = ip_reass_free_complete_datagram(oldest, oldest_prev); - pbufs_freed += pbufs_freed_current; - } - } while ((pbufs_freed < pbufs_needed) && (other_datagrams > 1)); - return pbufs_freed; -} -#endif /* IP_REASS_FREE_OLDEST */ - -/** - * Enqueues a new fragment into the fragment queue - * @param fraghdr points to the new fragments IP hdr - * @param clen number of pbufs needed to enqueue (used for freeing other datagrams if not enough space) - * @return A pointer to the queue location into which the fragment was enqueued - */ -static struct ip_reassdata* -ip_reass_enqueue_new_datagram(struct ip_hdr *fraghdr, int clen) -{ - struct ip_reassdata* ipr; -#if ! IP_REASS_FREE_OLDEST - LWIP_UNUSED_ARG(clen); -#endif - - /* No matching previous fragment found, allocate a new reassdata struct */ - ipr = (struct ip_reassdata *)memp_malloc(MEMP_REASSDATA); - if (ipr == NULL) { -#if IP_REASS_FREE_OLDEST - if (ip_reass_remove_oldest_datagram(fraghdr, clen) >= clen) { - ipr = (struct ip_reassdata *)memp_malloc(MEMP_REASSDATA); - } - if (ipr == NULL) -#endif /* IP_REASS_FREE_OLDEST */ - { - IPFRAG_STATS_INC(ip_frag.memerr); - LWIP_DEBUGF(IP_REASS_DEBUG,("Failed to alloc reassdata struct\n")); - return NULL; - } - } - memset(ipr, 0, sizeof(struct ip_reassdata)); - ipr->timer = IP_REASS_MAXAGE; - - /* enqueue the new structure to the front of the list */ - ipr->next = reassdatagrams; - reassdatagrams = ipr; - /* copy the ip header for later tests and input */ - /* @todo: no ip options supported? */ - SMEMCPY(&(ipr->iphdr), fraghdr, IP_HLEN); - return ipr; -} - -/** - * Dequeues a datagram from the datagram queue. Doesn't deallocate the pbufs. - * @param ipr points to the queue entry to dequeue - */ -static void -ip_reass_dequeue_datagram(struct ip_reassdata *ipr, struct ip_reassdata *prev) -{ - /* dequeue the reass struct */ - if (reassdatagrams == ipr) { - /* it was the first in the list */ - reassdatagrams = ipr->next; - } else { - /* it wasn't the first, so it must have a valid 'prev' */ - LWIP_ASSERT("sanity check linked list", prev != NULL); - prev->next = ipr->next; - } - - /* now we can free the ip_reassdata struct */ - memp_free(MEMP_REASSDATA, ipr); -} - -/** - * Chain a new pbuf into the pbuf list that composes the datagram. The pbuf list - * will grow over time as new pbufs are rx. - * Also checks that the datagram passes basic continuity checks (if the last - * fragment was received at least once). - * @param ipr points to the reassembly state - * @param new_p points to the pbuf for the current fragment - * @param is_last is 1 if this pbuf has MF==0 (ipr->flags not updated yet) - * @return see IP_REASS_VALIDATE_* defines - */ -static int -ip_reass_chain_frag_into_datagram_and_validate(struct ip_reassdata *ipr, struct pbuf *new_p, int is_last) -{ - struct ip_reass_helper *iprh, *iprh_tmp, *iprh_prev=NULL; - struct pbuf *q; - u16_t offset, len; - struct ip_hdr *fraghdr; - int valid = 1; - - /* Extract length and fragment offset from current fragment */ - fraghdr = (struct ip_hdr*)new_p->payload; - len = lwip_ntohs(IPH_LEN(fraghdr)) - IPH_HL(fraghdr) * 4; - offset = (lwip_ntohs(IPH_OFFSET(fraghdr)) & IP_OFFMASK) * 8; - - /* overwrite the fragment's ip header from the pbuf with our helper struct, - * and setup the embedded helper structure. */ - /* make sure the struct ip_reass_helper fits into the IP header */ - LWIP_ASSERT("sizeof(struct ip_reass_helper) <= IP_HLEN", - sizeof(struct ip_reass_helper) <= IP_HLEN); - iprh = (struct ip_reass_helper*)new_p->payload; - iprh->next_pbuf = NULL; - iprh->start = offset; - iprh->end = offset + len; - - /* Iterate through until we either get to the end of the list (append), - * or we find one with a larger offset (insert). */ - for (q = ipr->p; q != NULL;) { - iprh_tmp = (struct ip_reass_helper*)q->payload; - if (iprh->start < iprh_tmp->start) { - /* the new pbuf should be inserted before this */ - iprh->next_pbuf = q; - if (iprh_prev != NULL) { - /* not the fragment with the lowest offset */ -#if IP_REASS_CHECK_OVERLAP - if ((iprh->start < iprh_prev->end) || (iprh->end > iprh_tmp->start)) { - /* fragment overlaps with previous or following, throw away */ - goto freepbuf; - } -#endif /* IP_REASS_CHECK_OVERLAP */ - iprh_prev->next_pbuf = new_p; - if (iprh_prev->end != iprh->start) { - /* There is a fragment missing between the current - * and the previous fragment */ - valid = 0; - } - } else { -#if IP_REASS_CHECK_OVERLAP - if (iprh->end > iprh_tmp->start) { - /* fragment overlaps with following, throw away */ - goto freepbuf; - } -#endif /* IP_REASS_CHECK_OVERLAP */ - /* fragment with the lowest offset */ - ipr->p = new_p; - } - break; - } else if (iprh->start == iprh_tmp->start) { - /* received the same datagram twice: no need to keep the datagram */ - goto freepbuf; -#if IP_REASS_CHECK_OVERLAP - } else if (iprh->start < iprh_tmp->end) { - /* overlap: no need to keep the new datagram */ - goto freepbuf; -#endif /* IP_REASS_CHECK_OVERLAP */ - } else { - /* Check if the fragments received so far have no holes. */ - if (iprh_prev != NULL) { - if (iprh_prev->end != iprh_tmp->start) { - /* There is a fragment missing between the current - * and the previous fragment */ - valid = 0; - } - } - } - q = iprh_tmp->next_pbuf; - iprh_prev = iprh_tmp; - } - - /* If q is NULL, then we made it to the end of the list. Determine what to do now */ - if (q == NULL) { - if (iprh_prev != NULL) { - /* this is (for now), the fragment with the highest offset: - * chain it to the last fragment */ -#if IP_REASS_CHECK_OVERLAP - LWIP_ASSERT("check fragments don't overlap", iprh_prev->end <= iprh->start); -#endif /* IP_REASS_CHECK_OVERLAP */ - iprh_prev->next_pbuf = new_p; - if (iprh_prev->end != iprh->start) { - valid = 0; - } - } else { -#if IP_REASS_CHECK_OVERLAP - LWIP_ASSERT("no previous fragment, this must be the first fragment!", - ipr->p == NULL); -#endif /* IP_REASS_CHECK_OVERLAP */ - /* this is the first fragment we ever received for this ip datagram */ - ipr->p = new_p; - } - } - - /* At this point, the validation part begins: */ - /* If we already received the last fragment */ - if (is_last || ((ipr->flags & IP_REASS_FLAG_LASTFRAG) != 0)) { - /* and had no holes so far */ - if (valid) { - /* then check if the rest of the fragments is here */ - /* Check if the queue starts with the first datagram */ - if ((ipr->p == NULL) || (((struct ip_reass_helper*)ipr->p->payload)->start != 0)) { - valid = 0; - } else { - /* and check that there are no holes after this datagram */ - iprh_prev = iprh; - q = iprh->next_pbuf; - while (q != NULL) { - iprh = (struct ip_reass_helper*)q->payload; - if (iprh_prev->end != iprh->start) { - valid = 0; - break; - } - iprh_prev = iprh; - q = iprh->next_pbuf; - } - /* if still valid, all fragments are received - * (because to the MF==0 already arrived */ - if (valid) { - LWIP_ASSERT("sanity check", ipr->p != NULL); - LWIP_ASSERT("sanity check", - ((struct ip_reass_helper*)ipr->p->payload) != iprh); - LWIP_ASSERT("validate_datagram:next_pbuf!=NULL", - iprh->next_pbuf == NULL); - } - } - } - /* If valid is 0 here, there are some fragments missing in the middle - * (since MF == 0 has already arrived). Such datagrams simply time out if - * no more fragments are received... */ - return valid ? IP_REASS_VALIDATE_TELEGRAM_FINISHED : IP_REASS_VALIDATE_PBUF_QUEUED; - } - /* If we come here, not all fragments were received, yet! */ - return IP_REASS_VALIDATE_PBUF_QUEUED; /* not yet valid! */ -#if IP_REASS_CHECK_OVERLAP -freepbuf: - ip_reass_pbufcount -= pbuf_clen(new_p); - pbuf_free(new_p); - return IP_REASS_VALIDATE_PBUF_DROPPED; -#endif /* IP_REASS_CHECK_OVERLAP */ -} - -/** - * Reassembles incoming IP fragments into an IP datagram. - * - * @param p points to a pbuf chain of the fragment - * @return NULL if reassembly is incomplete, ? otherwise - */ -struct pbuf * -ip4_reass(struct pbuf *p) -{ - struct pbuf *r; - struct ip_hdr *fraghdr; - struct ip_reassdata *ipr; - struct ip_reass_helper *iprh; - u16_t offset, len, clen; - int valid; - int is_last; - - IPFRAG_STATS_INC(ip_frag.recv); - MIB2_STATS_INC(mib2.ipreasmreqds); - - fraghdr = (struct ip_hdr*)p->payload; - - if ((IPH_HL(fraghdr) * 4) != IP_HLEN) { - LWIP_DEBUGF(IP_REASS_DEBUG,("ip4_reass: IP options currently not supported!\n")); - IPFRAG_STATS_INC(ip_frag.err); - goto nullreturn; - } - - offset = (lwip_ntohs(IPH_OFFSET(fraghdr)) & IP_OFFMASK) * 8; - len = lwip_ntohs(IPH_LEN(fraghdr)) - IPH_HL(fraghdr) * 4; - - /* Check if we are allowed to enqueue more datagrams. */ - clen = pbuf_clen(p); - if ((ip_reass_pbufcount + clen) > IP_REASS_MAX_PBUFS) { -#if IP_REASS_FREE_OLDEST - if (!ip_reass_remove_oldest_datagram(fraghdr, clen) || - ((ip_reass_pbufcount + clen) > IP_REASS_MAX_PBUFS)) -#endif /* IP_REASS_FREE_OLDEST */ - { - /* No datagram could be freed and still too many pbufs enqueued */ - LWIP_DEBUGF(IP_REASS_DEBUG,("ip4_reass: Overflow condition: pbufct=%d, clen=%d, MAX=%d\n", - ip_reass_pbufcount, clen, IP_REASS_MAX_PBUFS)); - IPFRAG_STATS_INC(ip_frag.memerr); - /* @todo: send ICMP time exceeded here? */ - /* drop this pbuf */ - goto nullreturn; - } - } - - /* Look for the datagram the fragment belongs to in the current datagram queue, - * remembering the previous in the queue for later dequeueing. */ - for (ipr = reassdatagrams; ipr != NULL; ipr = ipr->next) { - /* Check if the incoming fragment matches the one currently present - in the reassembly buffer. If so, we proceed with copying the - fragment into the buffer. */ - if (IP_ADDRESSES_AND_ID_MATCH(&ipr->iphdr, fraghdr)) { - LWIP_DEBUGF(IP_REASS_DEBUG, ("ip4_reass: matching previous fragment ID=%"X16_F"\n", - lwip_ntohs(IPH_ID(fraghdr)))); - IPFRAG_STATS_INC(ip_frag.cachehit); - break; - } - } - - if (ipr == NULL) { - /* Enqueue a new datagram into the datagram queue */ - ipr = ip_reass_enqueue_new_datagram(fraghdr, clen); - /* Bail if unable to enqueue */ - if (ipr == NULL) { - goto nullreturn; - } - } else { - if (((lwip_ntohs(IPH_OFFSET(fraghdr)) & IP_OFFMASK) == 0) && - ((lwip_ntohs(IPH_OFFSET(&ipr->iphdr)) & IP_OFFMASK) != 0)) { - /* ipr->iphdr is not the header from the first fragment, but fraghdr is - * -> copy fraghdr into ipr->iphdr since we want to have the header - * of the first fragment (for ICMP time exceeded and later, for copying - * all options, if supported)*/ - SMEMCPY(&ipr->iphdr, fraghdr, IP_HLEN); - } - } - - /* At this point, we have either created a new entry or pointing - * to an existing one */ - - /* check for 'no more fragments', and update queue entry*/ - is_last = (IPH_OFFSET(fraghdr) & PP_NTOHS(IP_MF)) == 0; - if (is_last) { - u16_t datagram_len = (u16_t)(offset + len); - if ((datagram_len < offset) || (datagram_len > (0xFFFF - IP_HLEN))) { - /* u16_t overflow, cannot handle this */ - goto nullreturn; - } - } - /* find the right place to insert this pbuf */ - /* @todo: trim pbufs if fragments are overlapping */ - valid = ip_reass_chain_frag_into_datagram_and_validate(ipr, p, is_last); - if (valid == IP_REASS_VALIDATE_PBUF_DROPPED) { - goto nullreturn; - } - /* if we come here, the pbuf has been enqueued */ - - /* Track the current number of pbufs current 'in-flight', in order to limit - the number of fragments that may be enqueued at any one time - (overflow checked by testing against IP_REASS_MAX_PBUFS) */ - ip_reass_pbufcount = (u16_t)(ip_reass_pbufcount + clen); - if (is_last) { - u16_t datagram_len = (u16_t)(offset + len); - ipr->datagram_len = datagram_len; - ipr->flags |= IP_REASS_FLAG_LASTFRAG; - LWIP_DEBUGF(IP_REASS_DEBUG, - ("ip4_reass: last fragment seen, total len %"S16_F"\n", - ipr->datagram_len)); - } - - if (valid == IP_REASS_VALIDATE_TELEGRAM_FINISHED) { - struct ip_reassdata *ipr_prev; - /* the totally last fragment (flag more fragments = 0) was received at least - * once AND all fragments are received */ - ipr->datagram_len += IP_HLEN; - - /* save the second pbuf before copying the header over the pointer */ - r = ((struct ip_reass_helper*)ipr->p->payload)->next_pbuf; - - /* copy the original ip header back to the first pbuf */ - fraghdr = (struct ip_hdr*)(ipr->p->payload); - SMEMCPY(fraghdr, &ipr->iphdr, IP_HLEN); - IPH_LEN_SET(fraghdr, lwip_htons(ipr->datagram_len)); - IPH_OFFSET_SET(fraghdr, 0); - IPH_CHKSUM_SET(fraghdr, 0); - /* @todo: do we need to set/calculate the correct checksum? */ -#if CHECKSUM_GEN_IP - IF__NETIF_CHECKSUM_ENABLED(ip_current_input_netif(), NETIF_CHECKSUM_GEN_IP) { - IPH_CHKSUM_SET(fraghdr, inet_chksum(fraghdr, IP_HLEN)); - } -#endif /* CHECKSUM_GEN_IP */ - - p = ipr->p; - - /* chain together the pbufs contained within the reass_data list. */ - while (r != NULL) { - iprh = (struct ip_reass_helper*)r->payload; - - /* hide the ip header for every succeeding fragment */ - pbuf_header(r, -IP_HLEN); - pbuf_cat(p, r); - r = iprh->next_pbuf; - } - - /* find the previous entry in the linked list */ - if (ipr == reassdatagrams) { - ipr_prev = NULL; - } else { - for (ipr_prev = reassdatagrams; ipr_prev != NULL; ipr_prev = ipr_prev->next) { - if (ipr_prev->next == ipr) { - break; - } - } - } - - /* release the sources allocate for the fragment queue entry */ - ip_reass_dequeue_datagram(ipr, ipr_prev); - - /* and adjust the number of pbufs currently queued for reassembly. */ - ip_reass_pbufcount -= pbuf_clen(p); - - MIB2_STATS_INC(mib2.ipreasmoks); - - /* Return the pbuf chain */ - return p; - } - /* the datagram is not (yet?) reassembled completely */ - LWIP_DEBUGF(IP_REASS_DEBUG,("ip_reass_pbufcount: %d out\n", ip_reass_pbufcount)); - return NULL; - -nullreturn: - LWIP_DEBUGF(IP_REASS_DEBUG,("ip4_reass: nullreturn\n")); - IPFRAG_STATS_INC(ip_frag.drop); - pbuf_free(p); - return NULL; -} -#endif /* IP_REASSEMBLY */ - -#if IP_FRAG -#if !LWIP_NETIF_TX_SINGLE_PBUF -/** Allocate a new struct pbuf_custom_ref */ -static struct pbuf_custom_ref* -ip_frag_alloc_pbuf_custom_ref(void) -{ - return (struct pbuf_custom_ref*)memp_malloc(MEMP_FRAG_PBUF); -} - -/** Free a struct pbuf_custom_ref */ -static void -ip_frag_free_pbuf_custom_ref(struct pbuf_custom_ref* p) -{ - LWIP_ASSERT("p != NULL", p != NULL); - memp_free(MEMP_FRAG_PBUF, p); -} - -/** Free-callback function to free a 'struct pbuf_custom_ref', called by - * pbuf_free. */ -static void -ipfrag_free_pbuf_custom(struct pbuf *p) -{ - struct pbuf_custom_ref *pcr = (struct pbuf_custom_ref*)p; - LWIP_ASSERT("pcr != NULL", pcr != NULL); - LWIP_ASSERT("pcr == p", (void*)pcr == (void*)p); - if (pcr->original != NULL) { - pbuf_free(pcr->original); - } - ip_frag_free_pbuf_custom_ref(pcr); -} -#endif /* !LWIP_NETIF_TX_SINGLE_PBUF */ - -/** - * Fragment an IP datagram if too large for the netif. - * - * Chop the datagram in MTU sized chunks and send them in order - * by pointing PBUF_REFs into p. - * - * @param p ip packet to send - * @param netif the netif on which to send - * @param dest destination ip address to which to send - * - * @return ERR_OK if sent successfully, err_t otherwise - */ -err_t -ip4_frag(struct pbuf *p, struct netif *netif, const ip4_addr_t *dest) -{ - struct pbuf *rambuf; -#if !LWIP_NETIF_TX_SINGLE_PBUF - struct pbuf *newpbuf; - u16_t newpbuflen = 0; - u16_t left_to_copy; -#endif - struct ip_hdr *original_iphdr; - struct ip_hdr *iphdr; - const u16_t nfb = (netif->mtu - IP_HLEN) / 8; - u16_t left, fragsize; - u16_t ofo; - int last; - u16_t poff = IP_HLEN; - u16_t tmp; - - original_iphdr = (struct ip_hdr *)p->payload; - iphdr = original_iphdr; - LWIP_ERROR("ip4_frag() does not support IP options", IPH_HL(iphdr) * 4 == IP_HLEN, return ERR_VAL); - - /* Save original offset */ - tmp = lwip_ntohs(IPH_OFFSET(iphdr)); - ofo = tmp & IP_OFFMASK; - LWIP_ERROR("ip_frag(): MF already set", (tmp & IP_MF) == 0, return ERR_VAL); - - left = p->tot_len - IP_HLEN; - - while (left) { - /* Fill this fragment */ - fragsize = LWIP_MIN(left, nfb * 8); - -#if LWIP_NETIF_TX_SINGLE_PBUF - rambuf = pbuf_alloc(PBUF_IP, fragsize, PBUF_RAM); - if (rambuf == NULL) { - goto memerr; - } - LWIP_ASSERT("this needs a pbuf in one piece!", - (rambuf->len == rambuf->tot_len) && (rambuf->next == NULL)); - poff += pbuf_copy_partial(p, rambuf->payload, fragsize, poff); - /* make room for the IP header */ - if (pbuf_header(rambuf, IP_HLEN)) { - pbuf_free(rambuf); - goto memerr; - } - /* fill in the IP header */ - SMEMCPY(rambuf->payload, original_iphdr, IP_HLEN); - iphdr = (struct ip_hdr*)rambuf->payload; -#else /* LWIP_NETIF_TX_SINGLE_PBUF */ - /* When not using a static buffer, create a chain of pbufs. - * The first will be a PBUF_RAM holding the link and IP header. - * The rest will be PBUF_REFs mirroring the pbuf chain to be fragged, - * but limited to the size of an mtu. - */ - rambuf = pbuf_alloc(PBUF_LINK, IP_HLEN, PBUF_RAM); - if (rambuf == NULL) { - goto memerr; - } - LWIP_ASSERT("this needs a pbuf in one piece!", - (p->len >= (IP_HLEN))); - SMEMCPY(rambuf->payload, original_iphdr, IP_HLEN); - iphdr = (struct ip_hdr *)rambuf->payload; - - left_to_copy = fragsize; - while (left_to_copy) { - struct pbuf_custom_ref *pcr; - u16_t plen = p->len - poff; - newpbuflen = LWIP_MIN(left_to_copy, plen); - /* Is this pbuf already empty? */ - if (!newpbuflen) { - poff = 0; - p = p->next; - continue; - } - pcr = ip_frag_alloc_pbuf_custom_ref(); - if (pcr == NULL) { - pbuf_free(rambuf); - goto memerr; - } - /* Mirror this pbuf, although we might not need all of it. */ - newpbuf = pbuf_alloced_custom(PBUF_RAW, newpbuflen, PBUF_REF, &pcr->pc, - (u8_t*)p->payload + poff, newpbuflen); - if (newpbuf == NULL) { - ip_frag_free_pbuf_custom_ref(pcr); - pbuf_free(rambuf); - goto memerr; - } - pbuf_ref(p); - pcr->original = p; - pcr->pc.custom_free_function = ipfrag_free_pbuf_custom; - - /* Add it to end of rambuf's chain, but using pbuf_cat, not pbuf_chain - * so that it is removed when pbuf_dechain is later called on rambuf. - */ - pbuf_cat(rambuf, newpbuf); - left_to_copy -= newpbuflen; - if (left_to_copy) { - poff = 0; - p = p->next; - } - } - poff += newpbuflen; -#endif /* LWIP_NETIF_TX_SINGLE_PBUF */ - - /* Correct header */ - last = (left <= netif->mtu - IP_HLEN); - - /* Set new offset and MF flag */ - tmp = (IP_OFFMASK & (ofo)); - if (!last) { - tmp = tmp | IP_MF; - } - IPH_OFFSET_SET(iphdr, lwip_htons(tmp)); - IPH_LEN_SET(iphdr, lwip_htons(fragsize + IP_HLEN)); - IPH_CHKSUM_SET(iphdr, 0); -#if CHECKSUM_GEN_IP - IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_IP) { - IPH_CHKSUM_SET(iphdr, inet_chksum(iphdr, IP_HLEN)); - } -#endif /* CHECKSUM_GEN_IP */ - - /* No need for separate header pbuf - we allowed room for it in rambuf - * when allocated. - */ - netif->output(netif, rambuf, dest); - IPFRAG_STATS_INC(ip_frag.xmit); - - /* Unfortunately we can't reuse rambuf - the hardware may still be - * using the buffer. Instead we free it (and the ensuing chain) and - * recreate it next time round the loop. If we're lucky the hardware - * will have already sent the packet, the free will really free, and - * there will be zero memory penalty. - */ - - pbuf_free(rambuf); - left -= fragsize; - ofo += nfb; - } - MIB2_STATS_INC(mib2.ipfragoks); - return ERR_OK; -memerr: - MIB2_STATS_INC(mib2.ipfragfails); - return ERR_MEM; -} -#endif /* IP_FRAG */ - -#endif /* LWIP_IPV4 */ diff --git a/third_party/lwip/repo/lwip/src/core/ipv6/dhcp6.c b/third_party/lwip/repo/lwip/src/core/ipv6/dhcp6.c deleted file mode 100644 index f27a725e3af936..00000000000000 --- a/third_party/lwip/repo/lwip/src/core/ipv6/dhcp6.c +++ /dev/null @@ -1,50 +0,0 @@ -/** - * @file - * - * DHCPv6. - */ - -/* - * Copyright (c) 2010 Inico Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Ivan Delamer - * - * - * Please coordinate changes and requests with Ivan Delamer - * - */ - -#include "lwip/opt.h" - -#if LWIP_IPV6 && LWIP_IPV6_DHCP6 /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/ip6_addr.h" -#include "lwip/def.h" - - -#endif /* LWIP_IPV6 && LWIP_IPV6_DHCP6 */ diff --git a/third_party/lwip/repo/lwip/src/core/ipv6/ethip6.c b/third_party/lwip/repo/lwip/src/core/ipv6/ethip6.c deleted file mode 100644 index a340683f358ed6..00000000000000 --- a/third_party/lwip/repo/lwip/src/core/ipv6/ethip6.c +++ /dev/null @@ -1,137 +0,0 @@ -/** - * @file - * - * Ethernet output for IPv6. Uses ND tables for link-layer addressing. - */ - -/* - * Copyright (c) 2010 Inico Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Ivan Delamer - * - * - * Please coordinate changes and requests with Ivan Delamer - * - */ - -#include "lwip/opt.h" - -#if LWIP_IPV6 && LWIP_ETHERNET - -#include "lwip/ethip6.h" -#include "lwip/nd6.h" -#include "lwip/pbuf.h" -#include "lwip/ip6.h" -#include "lwip/ip6_addr.h" -#include "lwip/inet_chksum.h" -#include "lwip/netif.h" -#include "lwip/icmp6.h" -#include "lwip/prot/ethernet.h" -#include "netif/ethernet.h" -#if LWIP_IPV6_ROUTE_TABLE_SUPPORT -#include "lwip/ip6_route_table.h" -#endif - -#include - -/** - * Resolve and fill-in Ethernet address header for outgoing IPv6 packet. - * - * For IPv6 multicast, corresponding Ethernet addresses - * are selected and the packet is transmitted on the link. - * - * For unicast addresses, ask the ND6 module what to do. It will either let us - * send the the packet right away, or queue the packet for later itself, unless - * an error occurs. - * - * @todo anycast addresses - * - * @param netif The lwIP network interface which the IP packet will be sent on. - * @param q The pbuf(s) containing the IP packet to be sent. - * @param ip6addr The IP address of the packet destination. - * - * @return - * - ERR_OK or the return value of @ref nd6_get_next_hop_addr_or_queue. - */ -err_t -ethip6_output(struct netif *netif, struct pbuf *q, const ip6_addr_t *ip6addr) -{ - struct eth_addr dest; - const u8_t *hwaddr; - err_t result; -#if LWIP_IPV6_ROUTE_TABLE_SUPPORT - ip6_addr_t *gateway = NULL; -#endif - - /* multicast destination IP address? */ - if (ip6_addr_ismulticast(ip6addr)) { - /* Hash IP multicast address to MAC address.*/ - dest.addr[0] = 0x33; - dest.addr[1] = 0x33; - dest.addr[2] = ((const u8_t *)(&(ip6addr->addr[3])))[0]; - dest.addr[3] = ((const u8_t *)(&(ip6addr->addr[3])))[1]; - dest.addr[4] = ((const u8_t *)(&(ip6addr->addr[3])))[2]; - dest.addr[5] = ((const u8_t *)(&(ip6addr->addr[3])))[3]; - - /* Send out. */ - return ethernet_output(netif, q, (const struct eth_addr*)(netif->hwaddr), &dest, ETHTYPE_IPV6); - } - - /* We have a unicast destination IP address */ - /* @todo anycast? */ - -#if LWIP_IPV6_ROUTE_TABLE_SUPPORT - /* See if a gateway is present for the destination address in the static route table */ -#ifdef LWIP_HOOK_ETHIP6_GET_GW - gateway = LWIP_HOOK_ETHIP6_GET_GW(netif, ip6addr); -#endif - if (gateway != NULL) { - /* Replace the destination with the gateway. The gateway is - * assumed to be on-link. - */ - ip6addr = gateway; - } -#endif - - /* Ask ND6 what to do with the packet. */ - result = nd6_get_next_hop_addr_or_queue(netif, q, ip6addr, &hwaddr); - if (result != ERR_OK) { - return result; - } - - /* If no hardware address is returned, nd6 has queued the packet for later. */ - if (hwaddr == NULL) { - return ERR_OK; - } - - /* Send out the packet using the returned hardware address. */ - SMEMCPY(dest.addr, hwaddr, 6); - return ethernet_output(netif, q, (const struct eth_addr*)(netif->hwaddr), &dest, ETHTYPE_IPV6); -} - -#endif /* LWIP_IPV6 && LWIP_ETHERNET */ diff --git a/third_party/lwip/repo/lwip/src/core/ipv6/icmp6.c b/third_party/lwip/repo/lwip/src/core/ipv6/icmp6.c deleted file mode 100644 index d170a39a06aa61..00000000000000 --- a/third_party/lwip/repo/lwip/src/core/ipv6/icmp6.c +++ /dev/null @@ -1,352 +0,0 @@ -/** - * @file - * - * IPv6 version of ICMP, as per RFC 4443. - */ - -/* - * Copyright (c) 2010 Inico Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Ivan Delamer - * - * - * Please coordinate changes and requests with Ivan Delamer - * - */ - -#include "lwip/opt.h" - -#if LWIP_ICMP6 && LWIP_IPV6 /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/icmp6.h" -#include "lwip/prot/icmp6.h" -#include "lwip/ip6.h" -#include "lwip/ip6_addr.h" -#include "lwip/inet_chksum.h" -#include "lwip/pbuf.h" -#include "lwip/netif.h" -#include "lwip/nd6.h" -#include "lwip/mld6.h" -#include "lwip/ip.h" -#include "lwip/stats.h" - -#include - -#ifndef LWIP_ICMP6_DATASIZE -#define LWIP_ICMP6_DATASIZE 8 -#endif -#if LWIP_ICMP6_DATASIZE == 0 -#define LWIP_ICMP6_DATASIZE 8 -#endif - -/* Forward declarations */ -static void icmp6_send_response(struct pbuf *p, u8_t code, u32_t data, u8_t type); - - -/** - * Process an input ICMPv6 message. Called by ip6_input. - * - * Will generate a reply for echo requests. Other messages are forwarded - * to nd6_input, or mld6_input. - * - * @param p the mld packet, p->payload pointing to the icmpv6 header - * @param inp the netif on which this packet was received - */ -void -icmp6_input(struct pbuf *p, struct netif *inp) -{ - struct icmp6_hdr *icmp6hdr; - struct pbuf *r; - const ip6_addr_t *reply_src; - - ICMP6_STATS_INC(icmp6.recv); - - /* Check that ICMPv6 header fits in payload */ - if (p->len < sizeof(struct icmp6_hdr)) { - /* drop short packets */ - pbuf_free(p); - ICMP6_STATS_INC(icmp6.lenerr); - ICMP6_STATS_INC(icmp6.drop); - return; - } - - icmp6hdr = (struct icmp6_hdr *)p->payload; - -#if CHECKSUM_CHECK_ICMP6 - IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_CHECK_ICMP6) { - if (ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->tot_len, ip6_current_src_addr(), - ip6_current_dest_addr()) != 0) { - /* Checksum failed */ - pbuf_free(p); - ICMP6_STATS_INC(icmp6.chkerr); - ICMP6_STATS_INC(icmp6.drop); - return; - } - } -#endif /* CHECKSUM_CHECK_ICMP6 */ - - switch (icmp6hdr->type) { -#if LWIP_IPV6_ND - case ICMP6_TYPE_NA: /* Neighbor advertisement */ - case ICMP6_TYPE_NS: /* Neighbor solicitation */ - case ICMP6_TYPE_RA: /* Router advertisement */ - case ICMP6_TYPE_RD: /* Redirect */ - case ICMP6_TYPE_PTB: /* Packet too big */ - nd6_input(p, inp); - return; - break; - case ICMP6_TYPE_RS: -#if LWIP_IPV6_FORWARD - /* @todo implement router functionality */ -#endif - break; -#if LWIP_IPV6_MLD - case ICMP6_TYPE_MLQ: - case ICMP6_TYPE_MLR: - case ICMP6_TYPE_MLD: - mld6_input(p, inp); - return; - break; -#endif /* LWIP_IPV6_MLD */ -#endif /* LWIP_IPV6_ND */ - case ICMP6_TYPE_EREQ: -#if !LWIP_MULTICAST_PING - /* multicast destination address? */ - if (ip6_addr_ismulticast(ip6_current_dest_addr())) { - /* drop */ - pbuf_free(p); - ICMP6_STATS_INC(icmp6.drop); - return; - } -#endif /* LWIP_MULTICAST_PING */ - - /* Allocate reply. */ - r = pbuf_alloc(PBUF_IP, p->tot_len, PBUF_RAM); - if (r == NULL) { - /* drop */ - pbuf_free(p); - ICMP6_STATS_INC(icmp6.memerr); - return; - } - - /* Copy echo request. */ - if (pbuf_copy(r, p) != ERR_OK) { - /* drop */ - pbuf_free(p); - pbuf_free(r); - ICMP6_STATS_INC(icmp6.err); - return; - } - - /* Determine reply source IPv6 address. */ -#if LWIP_MULTICAST_PING - if (ip6_addr_ismulticast(ip6_current_dest_addr())) { - reply_src = ip_2_ip6(ip6_select_source_address(inp, ip6_current_src_addr())); - if (reply_src == NULL) { - /* drop */ - pbuf_free(p); - pbuf_free(r); - ICMP6_STATS_INC(icmp6.rterr); - return; - } - } - else -#endif /* LWIP_MULTICAST_PING */ - { - reply_src = ip6_current_dest_addr(); - } - - /* Set fields in reply. */ - ((struct icmp6_echo_hdr *)(r->payload))->type = ICMP6_TYPE_EREP; - ((struct icmp6_echo_hdr *)(r->payload))->chksum = 0; -#if CHECKSUM_GEN_ICMP6 - IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_GEN_ICMP6) { - ((struct icmp6_echo_hdr *)(r->payload))->chksum = ip6_chksum_pseudo(r, - IP6_NEXTH_ICMP6, r->tot_len, reply_src, ip6_current_src_addr()); - } -#endif /* CHECKSUM_GEN_ICMP6 */ - - /* Send reply. */ - ICMP6_STATS_INC(icmp6.xmit); - ip6_output_if(r, reply_src, ip6_current_src_addr(), - LWIP_ICMP6_HL, 0, IP6_NEXTH_ICMP6, inp); - pbuf_free(r); - - break; - default: - ICMP6_STATS_INC(icmp6.proterr); - ICMP6_STATS_INC(icmp6.drop); - break; - } - - pbuf_free(p); -} - - -/** - * Send an icmpv6 'destination unreachable' packet. - * - * @param p the input packet for which the 'unreachable' should be sent, - * p->payload pointing to the IPv6 header - * @param c ICMPv6 code for the unreachable type - */ -void -icmp6_dest_unreach(struct pbuf *p, enum icmp6_dur_code c) -{ - icmp6_send_response(p, c, 0, ICMP6_TYPE_DUR); -} - -/** - * Send an icmpv6 'packet too big' packet. - * - * @param p the input packet for which the 'packet too big' should be sent, - * p->payload pointing to the IPv6 header - * @param mtu the maximum mtu that we can accept - */ -void -icmp6_packet_too_big(struct pbuf *p, u32_t mtu) -{ - icmp6_send_response(p, 0, mtu, ICMP6_TYPE_PTB); -} - -/** - * Send an icmpv6 'time exceeded' packet. - * - * @param p the input packet for which the 'unreachable' should be sent, - * p->payload pointing to the IPv6 header - * @param c ICMPv6 code for the time exceeded type - */ -void -icmp6_time_exceeded(struct pbuf *p, enum icmp6_te_code c) -{ - icmp6_send_response(p, c, 0, ICMP6_TYPE_TE); -} - -/** - * Send an icmpv6 'parameter problem' packet. - * - * @param p the input packet for which the 'param problem' should be sent, - * p->payload pointing to the IP header - * @param c ICMPv6 code for the param problem type - * @param pointer the pointer to the byte where the parameter is found - */ -void -icmp6_param_problem(struct pbuf *p, enum icmp6_pp_code c, u32_t pointer) -{ - icmp6_send_response(p, c, pointer, ICMP6_TYPE_PP); -} - -/** - * Send an ICMPv6 packet in response to an incoming packet. - * - * @param p the input packet for which the response should be sent, - * p->payload pointing to the IPv6 header - * @param code Code of the ICMPv6 header - * @param data Additional 32-bit parameter in the ICMPv6 header - * @param type Type of the ICMPv6 header - */ -static void -icmp6_send_response(struct pbuf *p, u8_t code, u32_t data, u8_t type) -{ - struct pbuf *q; - struct icmp6_hdr *icmp6hdr; - const ip6_addr_t *reply_src; - ip6_addr_t *reply_dest; - ip6_addr_t reply_src_local, reply_dest_local; - struct ip6_hdr *ip6hdr; - struct netif *netif; - - /* ICMPv6 header + IPv6 header + data */ - q = pbuf_alloc(PBUF_IP, sizeof(struct icmp6_hdr) + IP6_HLEN + LWIP_ICMP6_DATASIZE, - PBUF_RAM); - if (q == NULL) { - LWIP_DEBUGF(ICMP_DEBUG, ("icmp_time_exceeded: failed to allocate pbuf for ICMPv6 packet.\n")); - ICMP6_STATS_INC(icmp6.memerr); - return; - } - LWIP_ASSERT("check that first pbuf can hold icmp 6message", - (q->len >= (sizeof(struct icmp6_hdr) + IP6_HLEN + LWIP_ICMP6_DATASIZE))); - - icmp6hdr = (struct icmp6_hdr *)q->payload; - icmp6hdr->type = type; - icmp6hdr->code = code; - icmp6hdr->data = data; - - /* copy fields from original packet */ - SMEMCPY((u8_t *)q->payload + sizeof(struct icmp6_hdr), (u8_t *)p->payload, - IP6_HLEN + LWIP_ICMP6_DATASIZE); - - /* Get the destination address and netif for this ICMP message. */ - if ((ip_current_netif() == NULL) || - ((code == ICMP6_TE_FRAG) && (type == ICMP6_TYPE_TE))) { - /* Special case, as ip6_current_xxx is either NULL, or points - * to a different packet than the one that expired. - * We must use the addresses that are stored in the expired packet. */ - ip6hdr = (struct ip6_hdr *)p->payload; - /* copy from packed address to aligned address */ - ip6_addr_copy(reply_dest_local, ip6hdr->src); - ip6_addr_copy(reply_src_local, ip6hdr->dest); - reply_dest = &reply_dest_local; - reply_src = &reply_src_local; - netif = ip6_route(reply_src, reply_dest); - if (netif == NULL) { - /* drop */ - pbuf_free(q); - ICMP6_STATS_INC(icmp6.rterr); - return; - } - } - else { - netif = ip_current_netif(); - reply_dest = ip6_current_src_addr(); - - /* Select an address to use as source. */ - reply_src = ip_2_ip6(ip6_select_source_address(netif, reply_dest)); - if (reply_src == NULL) { - /* drop */ - pbuf_free(q); - ICMP6_STATS_INC(icmp6.rterr); - return; - } - } - - /* calculate checksum */ - icmp6hdr->chksum = 0; -#if CHECKSUM_GEN_ICMP6 - IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_ICMP6) { - icmp6hdr->chksum = ip6_chksum_pseudo(q, IP6_NEXTH_ICMP6, q->tot_len, - reply_src, reply_dest); - } -#endif /* CHECKSUM_GEN_ICMP6 */ - - ICMP6_STATS_INC(icmp6.xmit); - ip6_output_if(q, reply_src, reply_dest, LWIP_ICMP6_HL, 0, IP6_NEXTH_ICMP6, netif); - pbuf_free(q); -} - -#endif /* LWIP_ICMP6 && LWIP_IPV6 */ diff --git a/third_party/lwip/repo/lwip/src/core/ipv6/inet6.c b/third_party/lwip/repo/lwip/src/core/ipv6/inet6.c deleted file mode 100644 index d9a992c22ae5d7..00000000000000 --- a/third_party/lwip/repo/lwip/src/core/ipv6/inet6.c +++ /dev/null @@ -1,53 +0,0 @@ -/** - * @file - * - * INET v6 addresses. - */ - -/* - * Copyright (c) 2010 Inico Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Ivan Delamer - * - * - * Please coordinate changes and requests with Ivan Delamer - * - */ - -#include "lwip/opt.h" - -#if LWIP_IPV6 && LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/def.h" -#include "lwip/inet.h" - -/** This variable is initialized by the system to contain the wildcard IPv6 address. - */ -const struct in6_addr in6addr_any = IN6ADDR_ANY_INIT; - -#endif /* LWIP_IPV6 */ diff --git a/third_party/lwip/repo/lwip/src/core/ipv6/ip6.c b/third_party/lwip/repo/lwip/src/core/ipv6/ip6.c deleted file mode 100644 index 1a2a61bb42465e..00000000000000 --- a/third_party/lwip/repo/lwip/src/core/ipv6/ip6.c +++ /dev/null @@ -1,1201 +0,0 @@ -/** - * @file - * - * IPv6 layer. - */ - -/* - * Copyright (c) 2010 Inico Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Ivan Delamer - * - * - * Please coordinate changes and requests with Ivan Delamer - * - */ - -#include "lwip/opt.h" - -#if LWIP_IPV6 /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/def.h" -#include "lwip/mem.h" -#include "lwip/netif.h" -#include "lwip/ip.h" -#include "lwip/ip6.h" -#include "lwip/ip6_addr.h" -#include "lwip/ip6_frag.h" -#include "lwip/icmp6.h" -#include "lwip/raw.h" -#include "lwip/udp.h" -#include "lwip/priv/tcp_priv.h" -#include "lwip/dhcp6.h" -#include "lwip/nd6.h" -#include "lwip/mld6.h" -#include "lwip/debug.h" -#include "lwip/stats.h" - -#if LWIP_IPV6_ROUTE_TABLE_SUPPORT -#include "lwip/ip6_route_table.h" -#endif - -#ifdef LWIP_HOOK_FILENAME -#include LWIP_HOOK_FILENAME -#endif - -#if LWIP_IP_DEBUG_TARGET -extern int debug_target_match(int is_ipv6, ipX_addr_t *src, ipX_addr_t *dest); -#endif - -/** - * Finds the appropriate network interface for a given IPv6 address. It tries to select - * a netif following a sequence of heuristics: - * 1) if there is only 1 netif, return it - * 2) if the destination is a link-local address, try to match the src address to a netif. - * this is a tricky case because with multiple netifs, link-local addresses only have - * meaning within a particular subnet/link. - * #if LWIP_IPV6_ROUTE_TABLE_SUPPORT - * 3) tries to find a netif with a configured address matching the destination or look up - * a route table for potential matching routes. - * #else - * 3) tries to match the destination subnet to a configured address - * #endif - * 4) tries to find a router-announced route - * #if !LWIP_IPV6_ROUTE_TABLE_SUPPORT - * 5) tries to match the source address to the netif - * #endif - * 6) returns the default netif, if configured - * - * @param src the source IPv6 address, if known - * @param dest the destination IPv6 address for which to find the route - * @return the netif on which to send to reach dest - */ -struct netif * -ip6_route(const ip6_addr_t *src, const ip6_addr_t *dest) -{ - struct netif *netif = NULL; - s8_t i; - - /* If single netif configuration, fast return. */ - if ((netif_list != NULL) && (netif_list->next == NULL)) { - if (!netif_is_up(netif_list) || !netif_is_link_up(netif_list)) { - return NULL; - } - return netif_list; - } - - /* Special processing for link-local addresses. */ - if (ip6_addr_islinklocal(dest)) { - if (ip6_addr_isany(src)) { - /* Use default netif, if Up. */ - if (netif_default == NULL || !netif_is_up(netif_default) || - !netif_is_link_up(netif_default)) { - return NULL; - } - return netif_default; - } - - /* Try to find the netif for the source address. */ - for (netif = netif_list; netif != NULL; netif = netif->next) { - for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { - if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) && - ip6_addr_cmp(src, netif_ip6_addr(netif, i))) { - return netif; - } - } - } - - /* netif not found, use default netif, if up */ - if (netif_default == NULL || !netif_is_up(netif_default) || - !netif_is_link_up(netif_default)) { - return NULL; - } - return netif_default; - } - - /* we come here for non-link-local addresses */ -#ifdef LWIP_HOOK_IP6_ROUTE - netif = LWIP_HOOK_IP6_ROUTE(src, dest); - if (netif != NULL) { - return netif; - } -#endif - -#if LWIP_IPV6_ROUTE_TABLE_SUPPORT - /* See if the destination subnet matches a configured address. In accordance - * with RFC 5942, dynamically configured addresses do not have an implied - * local subnet, and thus should be considered /128 assignments. However, as - * such, the destination address may still match a local address, and so we - * still need to check for exact matches here. By (lwIP) policy, statically - * configured addresses do always have an implied local /64 subnet. */ - for (netif = netif_list; netif != NULL; netif = netif->next) { - if (!netif_is_up(netif) || !netif_is_link_up(netif)) { - continue; - } - for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { - if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) && - ip6_addr_netcmp(dest, netif_ip6_addr(netif, i)) && - (netif_ip6_addr_isstatic(netif, i) || - ip6_addr_nethostcmp(dest, netif_ip6_addr(netif, i)))) { - return netif; - } - } - } - - /* Lookup route table */ - if ((netif = ip6_static_route(src, dest)) != NULL) - { - return netif; - } -#endif /* LWIP_IPV6_ROUTE_TABLE_SUPPORT */ - -#if LWIP_IPV6_ROUTER_SUPPORT - /* Get the netif for a suitable router-announced route. */ - netif = nd6_find_route(dest); - if (netif != NULL) { - return netif; - } -#endif /* LWIP_IPV6_ROUTER_SUPPORT */ - -#if !LWIP_IPV6_ROUTE_TABLE_SUPPORT - /* try with the netif that matches the source address. */ - if (!ip6_addr_isany(src)) { - for (netif = netif_list; netif != NULL; netif = netif->next) { - if (!netif_is_up(netif) || !netif_is_link_up(netif)) { - continue; - } - for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { - if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) && - ip6_addr_cmp(src, netif_ip6_addr(netif, i))) { - return netif; - } - } - } - } -#endif /* !LWIP_IPV6_ROUTE_TABLE_SUPPORT */ - -#if LWIP_NETIF_LOOPBACK && !LWIP_HAVE_LOOPIF - /* loopif is disabled, loopback traffic is passed through any netif */ - if (ip6_addr_isloopback(dest)) { - /* don't check for link on loopback traffic */ - if (netif_default != NULL && netif_is_up(netif_default)) { - return netif_default; - } - /* default netif is not up, just use any netif for loopback traffic */ - for (netif = netif_list; netif != NULL; netif = netif->next) { - if (netif_is_up(netif)) { - return netif; - } - } - return NULL; - } -#endif /* LWIP_NETIF_LOOPBACK && !LWIP_HAVE_LOOPIF */ - - /* no matching netif found, use default netif, if up */ - if ((netif_default == NULL) || !netif_is_up(netif_default) || !netif_is_link_up(netif_default)) { - return NULL; - } - return netif_default; -} - -/** - * @ingroup ip6 - * Select the best IPv6 source address for a given destination IPv6 address. - * - * This implementation follows RFC 6724 Sec. 5 to the following extent: - * - Rules 1, 2, 3: fully implemented - * - Rules 4, 5, 5.5: not applicable - * - Rule 6: not implemented - * - Rule 7: not applicable - * - Rule 8: limited to "prefer /64 subnet match over non-match" - * - * For Rule 2, we deliberately deviate from RFC 6724 Sec. 3.1 by considering - * ULAs to be of smaller scope than global addresses, to avoid that a preferred - * ULA is picked over a deprecated global address when given a global address - * as destination, as that would likely result in broken two-way communication. - * - * As long as temporary addresses are not supported (as used in Rule 7), a - * proper implementation of Rule 8 would obviate the need to implement Rule 6. - * - * @param netif the netif on which to send a packet - * @param dest the destination we are trying to reach - * @return the most suitable source address to use, or NULL if no suitable - * source address is found - */ -const ip_addr_t * -ip6_select_source_address(struct netif *netif, const ip6_addr_t *dest) -{ - const ip_addr_t *best_addr; - const ip6_addr_t *cand_addr; - s8_t dest_scope, cand_scope, best_scope; - u8_t i, cand_pref, best_pref, cand_bits, best_bits; - - /* Start by determining the scope of the given destination address. These - * tests are hopefully (roughly) in order of likeliness to match. */ - if (ip6_addr_isglobal(dest)) { - dest_scope = IP6_MULTICAST_SCOPE_GLOBAL; - } else if (ip6_addr_islinklocal(dest) || ip6_addr_isloopback(dest)) { - dest_scope = IP6_MULTICAST_SCOPE_LINK_LOCAL; - } else if (ip6_addr_isuniquelocal(dest)) { - dest_scope = IP6_MULTICAST_SCOPE_ORGANIZATION_LOCAL; - } else if (ip6_addr_ismulticast(dest)) { - dest_scope = ip6_addr_multicast_scope(dest); - } else if (ip6_addr_issitelocal(dest)) { - dest_scope = IP6_MULTICAST_SCOPE_SITE_LOCAL; - } else { - /* no match, consider scope global */ - dest_scope = IP6_MULTICAST_SCOPE_GLOBAL; - } - - best_addr = NULL; - - for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { - /* Consider only valid (= preferred and deprecated) addresses. */ - if (!ip6_addr_isvalid(netif_ip6_addr_state(netif, i))) { - continue; - } - /* Determine the scope of this candidate address. Same ordering idea. */ - cand_addr = netif_ip6_addr(netif, i); - - if (ip6_addr_isany(cand_addr) || ip6_addr_ismulticast(cand_addr)) { - LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_WARNING, ("unspecified / multicast address assigned as unicast address on %c%c%u\n", netif->name[0], netif->name[1], netif->num)); - continue; - } - - if (ip6_addr_isglobal(cand_addr)) { - cand_scope = IP6_MULTICAST_SCOPE_GLOBAL; - } else if (ip6_addr_islinklocal(cand_addr)) { - cand_scope = IP6_MULTICAST_SCOPE_LINK_LOCAL; - } else if (ip6_addr_isuniquelocal(cand_addr)) { - cand_scope = IP6_MULTICAST_SCOPE_ORGANIZATION_LOCAL; - } else if (ip6_addr_issitelocal(cand_addr)) { - cand_scope = IP6_MULTICAST_SCOPE_SITE_LOCAL; - } else { - /* no match, treat as low-priority global scope */ - cand_scope = IP6_MULTICAST_SCOPE_RESERVEDF; - } - cand_pref = ip6_addr_ispreferred(netif_ip6_addr_state(netif, i)); - /* @todo compute the actual common bits, for longest matching prefix. */ - if (ip6_addr_netcmp(cand_addr, dest)) { - cand_bits = 64; - } - else if (ip6_addr_net48cmp(cand_addr, dest)) { - cand_bits = 48; - } - else { - cand_bits = 0; - } - if (cand_bits == 64 && ip6_addr_nethostcmp(cand_addr, dest)) { - return netif_ip_addr6(netif, i); /* Rule 1 */ - } - if ((best_addr == NULL) || /* no alternative yet */ - ((cand_scope < best_scope) && (cand_scope >= dest_scope)) || - ((cand_scope > best_scope) && (best_scope < dest_scope)) || /* Rule 2 */ - ((cand_scope == best_scope) && ((cand_pref > best_pref) || /* Rule 3 */ - ((cand_pref == best_pref) && (cand_bits > best_bits))))) { /* Rule 8 */ - /* We found a new "winning" candidate. */ - best_addr = netif_ip_addr6(netif, i); - best_scope = cand_scope; - best_pref = cand_pref; - best_bits = cand_bits; - } - } - - return best_addr; /* may be NULL */ -} - -#if LWIP_IPV6_FORWARD -/** - * Forwards an IPv6 packet. It finds an appropriate route for the - * packet, decrements the HL value of the packet, and outputs - * the packet on the appropriate interface. - * - * @param p the packet to forward (p->payload points to IP header) - * @param iphdr the IPv6 header of the input packet - * @param inp the netif on which this packet was received - */ -static void -ip6_forward(struct pbuf *p, struct ip6_hdr *iphdr, struct netif *inp) -{ - struct netif *netif; - - /* do not forward link-local or loopback addresses */ - if (ip6_addr_islinklocal(ip6_current_dest_addr()) || - ip6_addr_isloopback(ip6_current_dest_addr())) { - LWIP_DEBUGF(IP6_DEBUG, ("ip6_forward: not forwarding link-local address.\n")); - IP6_STATS_INC(ip6.rterr); - IP6_STATS_INC(ip6.drop); - return; - } - - /* Find network interface where to forward this IP packet to. */ - netif = ip6_route(IP6_ADDR_ANY6, ip6_current_dest_addr()); - if (netif == NULL) { - LWIP_DEBUGF(IP6_DEBUG, ("ip6_forward: no route for %"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F"\n", - IP6_ADDR_BLOCK1(ip6_current_dest_addr()), - IP6_ADDR_BLOCK2(ip6_current_dest_addr()), - IP6_ADDR_BLOCK3(ip6_current_dest_addr()), - IP6_ADDR_BLOCK4(ip6_current_dest_addr()), - IP6_ADDR_BLOCK5(ip6_current_dest_addr()), - IP6_ADDR_BLOCK6(ip6_current_dest_addr()), - IP6_ADDR_BLOCK7(ip6_current_dest_addr()), - IP6_ADDR_BLOCK8(ip6_current_dest_addr()))); -#if LWIP_ICMP6 - /* Don't send ICMP messages in response to ICMP messages */ - if (IP6H_NEXTH(iphdr) != IP6_NEXTH_ICMP6) { - icmp6_dest_unreach(p, ICMP6_DUR_NO_ROUTE); - } -#endif /* LWIP_ICMP6 */ - IP6_STATS_INC(ip6.rterr); - IP6_STATS_INC(ip6.drop); - return; - } - /* Do not forward packets onto the same network interface on which - * they arrived. */ - if (netif == inp) { - LWIP_DEBUGF(IP6_DEBUG, ("ip6_forward: not bouncing packets back on incoming interface.\n")); - IP6_STATS_INC(ip6.rterr); - IP6_STATS_INC(ip6.drop); - return; - } - - /* decrement HL */ - IP6H_HOPLIM_SET(iphdr, IP6H_HOPLIM(iphdr) - 1); - /* send ICMP6 if HL == 0 */ - if (IP6H_HOPLIM(iphdr) == 0) { -#if LWIP_ICMP6 - /* Don't send ICMP messages in response to ICMP messages */ - if (IP6H_NEXTH(iphdr) != IP6_NEXTH_ICMP6) { - icmp6_time_exceeded(p, ICMP6_TE_HL); - } -#endif /* LWIP_ICMP6 */ - IP6_STATS_INC(ip6.drop); - return; - } - - if (netif->mtu && (p->tot_len > netif->mtu)) { -#if LWIP_ICMP6 - /* Don't send ICMP messages in response to ICMP messages */ - if (IP6H_NEXTH(iphdr) != IP6_NEXTH_ICMP6) { - icmp6_packet_too_big(p, netif->mtu); - } -#endif /* LWIP_ICMP6 */ - IP6_STATS_INC(ip6.drop); - return; - } - - LWIP_DEBUGF(IP6_DEBUG, ("ip6_forward: forwarding packet to %"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F"\n", - IP6_ADDR_BLOCK1(ip6_current_dest_addr()), - IP6_ADDR_BLOCK2(ip6_current_dest_addr()), - IP6_ADDR_BLOCK3(ip6_current_dest_addr()), - IP6_ADDR_BLOCK4(ip6_current_dest_addr()), - IP6_ADDR_BLOCK5(ip6_current_dest_addr()), - IP6_ADDR_BLOCK6(ip6_current_dest_addr()), - IP6_ADDR_BLOCK7(ip6_current_dest_addr()), - IP6_ADDR_BLOCK8(ip6_current_dest_addr()))); - - /* transmit pbuf on chosen interface */ - netif->output_ip6(netif, p, ip6_current_dest_addr()); - IP6_STATS_INC(ip6.fw); - IP6_STATS_INC(ip6.xmit); - return; -} -#endif /* LWIP_IPV6_FORWARD */ - -/** - * This function is called by the network interface device driver when - * an IPv6 packet is received. The function does the basic checks of the - * IP header such as packet size being at least larger than the header - * size etc. If the packet was not destined for us, the packet is - * forwarded (using ip6_forward). - * - * Finally, the packet is sent to the upper layer protocol input function. - * - * @param p the received IPv6 packet (p->payload points to IPv6 header) - * @param inp the netif on which this packet was received - * @return ERR_OK if the packet was processed (could return ERR_* if it wasn't - * processed, but currently always returns ERR_OK) - */ -err_t -ip6_input(struct pbuf *p, struct netif *inp) -{ - struct ip6_hdr *ip6hdr; - struct netif *netif; - u8_t nexth; - u16_t hlen; /* the current header length */ - u8_t i; -#if 0 /*IP_ACCEPT_LINK_LAYER_ADDRESSING*/ - @todo - int check_ip_src=1; -#endif /* IP_ACCEPT_LINK_LAYER_ADDRESSING */ - - LWIP_ASSERT_CORE_LOCKED(); - - IP6_STATS_INC(ip6.recv); - - /* identify the IP header */ - ip6hdr = (struct ip6_hdr *)p->payload; - if (IP6H_V(ip6hdr) != 6) { - LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_WARNING, ("IPv6 packet dropped due to bad version number %"U32_F"\n", - IP6H_V(ip6hdr))); - pbuf_free(p); - IP6_STATS_INC(ip6.err); - IP6_STATS_INC(ip6.drop); - return ERR_OK; - } - -#ifdef LWIP_HOOK_IP6_INPUT - if (LWIP_HOOK_IP6_INPUT(p, inp)) { - /* the packet has been eaten */ - return ERR_OK; - } -#endif - - /* header length exceeds first pbuf length, or ip length exceeds total pbuf length? */ - if ((IP6_HLEN > p->len) || ((IP6H_PLEN(ip6hdr) + IP6_HLEN) > p->tot_len)) { - if (IP6_HLEN > p->len) { - LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, - ("IPv6 header (len %"U16_F") does not fit in first pbuf (len %"U16_F"), IP packet dropped.\n", - (u16_t)IP6_HLEN, p->len)); - } - if ((IP6H_PLEN(ip6hdr) + IP6_HLEN) > p->tot_len) { - LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, - ("IPv6 (plen %"U16_F") is longer than pbuf (len %"U16_F"), IP packet dropped.\n", - (u16_t)(IP6H_PLEN(ip6hdr) + IP6_HLEN), p->tot_len)); - } - /* free (drop) packet pbufs */ - pbuf_free(p); - IP6_STATS_INC(ip6.lenerr); - IP6_STATS_INC(ip6.drop); - return ERR_OK; - } - - /* Trim pbuf. This should have been done at the netif layer, - * but we'll do it anyway just to be sure that its done. */ - pbuf_realloc(p, IP6_HLEN + IP6H_PLEN(ip6hdr)); - - /* copy IP addresses to aligned ip6_addr_t */ - ip_addr_copy_from_ip6(ip_data.current_iphdr_dest, ip6hdr->dest); - ip_addr_copy_from_ip6(ip_data.current_iphdr_src, ip6hdr->src); - - /* Don't accept virtual IPv4 mapped IPv6 addresses. - * Don't accept multicast source addresses. */ - if (ip6_addr_isipv4mappedipv6(ip_2_ip6(&ip_data.current_iphdr_dest)) || - ip6_addr_isipv4mappedipv6(ip_2_ip6(&ip_data.current_iphdr_src)) || - ip6_addr_ismulticast(ip_2_ip6(&ip_data.current_iphdr_src))) { - IP6_STATS_INC(ip6.err); - IP6_STATS_INC(ip6.drop); - return ERR_OK; - } - - /* current header pointer. */ - ip_data.current_ip6_header = ip6hdr; - - /* In netif, used in case we need to send ICMPv6 packets back. */ - ip_data.current_netif = inp; - ip_data.current_input_netif = inp; - - /* match packet against an interface, i.e. is this packet for us? */ - if (ip6_addr_ismulticast(ip6_current_dest_addr())) { - /* Always joined to multicast if-local and link-local all-nodes group. */ - if (ip6_addr_isallnodes_iflocal(ip6_current_dest_addr()) || - ip6_addr_isallnodes_linklocal(ip6_current_dest_addr()) || - ip6_addr_isallnodes_networklocal(ip6_current_dest_addr()) || - ip6_addr_isallrouters_linklocal(ip6_current_dest_addr())) { - netif = inp; - } -#if LWIP_IPV6_MLD - else if (mld6_lookfor_group(inp, ip6_current_dest_addr())) { - netif = inp; - } -#else /* LWIP_IPV6_MLD */ - else if (ip6_addr_issolicitednode(ip6_current_dest_addr())) { - /* Filter solicited node packets when MLD is not enabled - * (for Neighbor discovery). */ - netif = NULL; - for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { - if (ip6_addr_isvalid(netif_ip6_addr_state(inp, i)) && - ip6_addr_cmp_solicitednode(ip6_current_dest_addr(), netif_ip6_addr(inp, i))) { - netif = inp; - LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: solicited node packet accepted on interface %c%c%"U16_F"\n", - netif->name[0], netif->name[1], netif->num)); - break; - } - } - } -#endif /* LWIP_IPV6_MLD */ - else { - netif = NULL; - } - } else { - /* start trying with inp. if that's not acceptable, start walking the - list of configured netifs. - 'first' is used as a boolean to mark whether we started walking the list */ - int first = 1; - netif = inp; - do { - /* interface is up? */ - if (netif_is_up(netif)) { - /* unicast to this interface address? address configured? */ - for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { - if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) && - ip6_addr_cmp(ip6_current_dest_addr(), netif_ip6_addr(netif, i))) { - /* exit outer loop */ - goto netif_found; - } - } - } - if (first) { - if (ip6_addr_islinklocal(ip6_current_dest_addr()) -#if !LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF - || ip6_addr_isloopback(ip6_current_dest_addr()) -#endif /* !LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF */ - ) { - /* Do not match link-local addresses to other netifs. The loopback - * address is to be considered link-local and packets to it should be - * dropped on other interfaces, as per RFC 4291 Sec. 2.5.3. This - * requirement cannot be implemented in the case that loopback - * traffic is sent across a non-loopback interface, however. - */ - netif = NULL; - break; - } - first = 0; - netif = netif_list; - } else { - netif = netif->next; - } - if (netif == inp) { - netif = netif->next; - } - } while (netif != NULL); -netif_found: - LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet accepted on interface %c%c%"U16_F"\n", - netif ? netif->name[0] : 'X', netif? netif->name[1] : 'X', netif ? netif->num : 0)); - } - - /* "::" packet source address? (used in duplicate address detection) */ - if (ip6_addr_isany(ip6_current_src_addr()) && - (!ip6_addr_issolicitednode(ip6_current_dest_addr()))) { - /* packet source is not valid */ - /* free (drop) packet pbufs */ - LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with src ANY_ADDRESS dropped\n")); - pbuf_free(p); - IP6_STATS_INC(ip6.drop); - goto ip6_input_cleanup; - } - - /* packet not for us? */ - if (netif == NULL) { - /* packet not for us, route or discard */ - LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_TRACE, ("ip6_input: packet not for us.\n")); -#if LWIP_IPV6_FORWARD - /* non-multicast packet? */ - if (!ip6_addr_ismulticast(ip6_current_dest_addr())) { - /* try to forward IP packet on (other) interfaces */ - ip6_forward(p, ip6hdr, inp); - } -#endif /* LWIP_IPV6_FORWARD */ - pbuf_free(p); - goto ip6_input_cleanup; - } - - /* current netif pointer. */ - ip_data.current_netif = netif; - - /* Save next header type. */ - nexth = IP6H_NEXTH(ip6hdr); - - /* Init header length. */ - hlen = ip_data.current_ip_header_tot_len = IP6_HLEN; - - /* Move to payload. */ - pbuf_header(p, -IP6_HLEN); - - /* Process known option extension headers, if present. */ - while (nexth != IP6_NEXTH_NONE) - { - switch (nexth) { - case IP6_NEXTH_HOPBYHOP: - LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with Hop-by-Hop options header\n")); - /* Get next header type. */ - nexth = *((u8_t *)p->payload); - - /* Get the header length. */ - hlen = 8 * (1 + *((u8_t *)p->payload + 1)); - ip_data.current_ip_header_tot_len += hlen; - - /* Skip over this header. */ - if (hlen > p->len) { - LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, - ("IPv6 options header (hlen %"U16_F") does not fit in first pbuf (len %"U16_F"), IPv6 packet dropped.\n", - hlen, p->len)); - /* free (drop) packet pbufs */ - pbuf_free(p); - IP6_STATS_INC(ip6.lenerr); - IP6_STATS_INC(ip6.drop); - goto ip6_input_cleanup; - } - - pbuf_header(p, -(s16_t)hlen); - break; - case IP6_NEXTH_DESTOPTS: - LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with Destination options header\n")); - /* Get next header type. */ - nexth = *((u8_t *)p->payload); - - /* Get the header length. */ - hlen = 8 * (1 + *((u8_t *)p->payload + 1)); - ip_data.current_ip_header_tot_len += hlen; - - /* Skip over this header. */ - if (hlen > p->len) { - LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, - ("IPv6 options header (hlen %"U16_F") does not fit in first pbuf (len %"U16_F"), IPv6 packet dropped.\n", - hlen, p->len)); - /* free (drop) packet pbufs */ - pbuf_free(p); - IP6_STATS_INC(ip6.lenerr); - IP6_STATS_INC(ip6.drop); - goto ip6_input_cleanup; - } - - pbuf_header(p, -(s16_t)hlen); - break; - case IP6_NEXTH_ROUTING: - LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with Routing header\n")); - /* Get next header type. */ - nexth = *((u8_t *)p->payload); - - /* Get the header length. */ - hlen = 8 * (1 + *((u8_t *)p->payload + 1)); - ip_data.current_ip_header_tot_len += hlen; - - /* Skip over this header. */ - if (hlen > p->len) { - LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, - ("IPv6 options header (hlen %"U16_F") does not fit in first pbuf (len %"U16_F"), IPv6 packet dropped.\n", - hlen, p->len)); - /* free (drop) packet pbufs */ - pbuf_free(p); - IP6_STATS_INC(ip6.lenerr); - IP6_STATS_INC(ip6.drop); - goto ip6_input_cleanup; - } - - pbuf_header(p, -(s16_t)hlen); - break; - - case IP6_NEXTH_FRAGMENT: - { - struct ip6_frag_hdr *frag_hdr; - LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with Fragment header\n")); - - frag_hdr = (struct ip6_frag_hdr *)p->payload; - - /* Get next header type. */ - nexth = frag_hdr->_nexth; - - /* Fragment Header length. */ - hlen = 8; - ip_data.current_ip_header_tot_len += hlen; - - /* Make sure this header fits in current pbuf. */ - if (hlen > p->len) { - LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, - ("IPv6 options header (hlen %"U16_F") does not fit in first pbuf (len %"U16_F"), IPv6 packet dropped.\n", - hlen, p->len)); - /* free (drop) packet pbufs */ - pbuf_free(p); - IP6_FRAG_STATS_INC(ip6_frag.lenerr); - IP6_FRAG_STATS_INC(ip6_frag.drop); - goto ip6_input_cleanup; - } - - /* Offset == 0 and more_fragments == 0? */ - if ((frag_hdr->_fragment_offset & - PP_HTONS(IP6_FRAG_OFFSET_MASK | IP6_FRAG_MORE_FLAG)) == 0) { - /* This is a 1-fragment packet, usually a packet that we have - * already reassembled. Skip this header anc continue. */ - pbuf_header(p, -(s16_t)hlen); - } else { -#if LWIP_IPV6_REASS - - /* reassemble the packet */ - p = ip6_reass(p); - /* packet not fully reassembled yet? */ - if (p == NULL) { - goto ip6_input_cleanup; - } - - /* Returned p point to IPv6 header. - * Update all our variables and pointers and continue. */ - ip6hdr = (struct ip6_hdr *)p->payload; - nexth = IP6H_NEXTH(ip6hdr); - hlen = ip_data.current_ip_header_tot_len = IP6_HLEN; - pbuf_header(p, -IP6_HLEN); - -#else /* LWIP_IPV6_REASS */ - /* free (drop) packet pbufs */ - LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: packet with Fragment header dropped (with LWIP_IPV6_REASS==0)\n")); - pbuf_free(p); - IP6_STATS_INC(ip6.opterr); - IP6_STATS_INC(ip6.drop); - goto ip6_input_cleanup; -#endif /* LWIP_IPV6_REASS */ - } - break; - } - default: - goto options_done; - break; - } - } -options_done: - - /* p points to IPv6 header again. */ - pbuf_header_force(p, (s16_t)ip_data.current_ip_header_tot_len); - - /* send to upper layers */ -#if IP_DEBUG && LWIP_IP_DEBUG_TARGET - if (debug_target_match(1, ip6_2_ipX(&ip_data.current_iphdr_src.ip6), ip6_2_ipX(&ip_data.current_iphdr_dest.ip6))) - { -#endif - LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: \n")); - ip6_debug_print(p); - LWIP_DEBUGF(IP6_DEBUG, ("ip6_input: p->len %"U16_F" p->tot_len %"U16_F"\n", p->len, p->tot_len)); -#if IP_DEBUG && LWIP_IP_DEBUG_TARGET - } -#endif - -#if LWIP_RAW - /* raw input did not eat the packet? */ - if (raw_input(p, inp) == 0) -#endif /* LWIP_RAW */ - { - switch (nexth) { - case IP6_NEXTH_NONE: - pbuf_free(p); - break; -#if LWIP_UDP - case IP6_NEXTH_UDP: -#if LWIP_UDPLITE - case IP6_NEXTH_UDPLITE: -#endif /* LWIP_UDPLITE */ - /* Point to payload. */ - pbuf_header(p, -(s16_t)ip_data.current_ip_header_tot_len); - udp_input(p, inp); - break; -#endif /* LWIP_UDP */ -#if LWIP_TCP - case IP6_NEXTH_TCP: - /* Point to payload. */ - pbuf_header(p, -(s16_t)ip_data.current_ip_header_tot_len); - tcp_input(p, inp); - break; -#endif /* LWIP_TCP */ -#if LWIP_ICMP6 - case IP6_NEXTH_ICMP6: - /* Point to payload. */ - pbuf_header(p, -(s16_t)ip_data.current_ip_header_tot_len); - icmp6_input(p, inp); - break; -#endif /* LWIP_ICMP */ - default: -#if LWIP_ICMP6 - /* send ICMP parameter problem unless it was a multicast or ICMPv6 */ - if ((!ip6_addr_ismulticast(ip6_current_dest_addr())) && - (IP6H_NEXTH(ip6hdr) != IP6_NEXTH_ICMP6)) { - icmp6_param_problem(p, ICMP6_PP_HEADER, ip_data.current_ip_header_tot_len - hlen); - } -#endif /* LWIP_ICMP */ - LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip6_input: Unsupported transport protocol %"U16_F"\n", (u16_t)IP6H_NEXTH(ip6hdr))); - pbuf_free(p); - IP6_STATS_INC(ip6.proterr); - IP6_STATS_INC(ip6.drop); - break; - } - } - -ip6_input_cleanup: - ip_data.current_netif = NULL; - ip_data.current_input_netif = NULL; - ip_data.current_ip6_header = NULL; - ip_data.current_ip_header_tot_len = 0; - ip6_addr_set_zero(ip6_current_src_addr()); - ip6_addr_set_zero(ip6_current_dest_addr()); - - return ERR_OK; -} - - -/** - * Sends an IPv6 packet on a network interface. This function constructs - * the IPv6 header. If the source IPv6 address is NULL, the IPv6 "ANY" address is - * used as source (usually during network startup). If the source IPv6 address it - * IP6_ADDR_ANY, the most appropriate IPv6 address of the outgoing network - * interface is filled in as source address. If the destination IPv6 address is - * LWIP_IP_HDRINCL, p is assumed to already include an IPv6 header and - * p->payload points to it instead of the data. - * - * @param p the packet to send (p->payload points to the data, e.g. next - protocol header; if dest == LWIP_IP_HDRINCL, p already includes an - IPv6 header and p->payload points to that IPv6 header) - * @param src the source IPv6 address to send from (if src == IP6_ADDR_ANY, an - * IP address of the netif is selected and used as source address. - * if src == NULL, IP6_ADDR_ANY is used as source) - * @param dest the destination IPv6 address to send the packet to - * @param hl the Hop Limit value to be set in the IPv6 header - * @param tc the Traffic Class value to be set in the IPv6 header - * @param nexth the Next Header to be set in the IPv6 header - * @param netif the netif on which to send this packet - * @return ERR_OK if the packet was sent OK - * ERR_BUF if p doesn't have enough space for IPv6/LINK headers - * returns errors returned by netif->output - */ -err_t -ip6_output_if(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest, - u8_t hl, u8_t tc, - u8_t nexth, struct netif *netif) -{ - const ip6_addr_t *src_used = src; - if (dest != LWIP_IP_HDRINCL) { - if (src != NULL && ip6_addr_isany(src)) { - src_used = ip_2_ip6(ip6_select_source_address(netif, dest)); - if ((src_used == NULL) || ip6_addr_isany(src_used)) { - /* No appropriate source address was found for this packet. */ - LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip6_output: No suitable source address for packet.\n")); - IP6_STATS_INC(ip6.rterr); - return ERR_RTE; - } - } - } - return ip6_output_if_src(p, src_used, dest, hl, tc, nexth, netif); -} - -/** - * Same as ip6_output_if() but 'src' address is not replaced by netif address - * when it is 'any'. - */ -err_t -ip6_output_if_src(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest, - u8_t hl, u8_t tc, - u8_t nexth, struct netif *netif) -{ - struct ip6_hdr *ip6hdr; - ip6_addr_t dest_addr; - - LWIP_IP_CHECK_PBUF_REF_COUNT_FOR_TX(p); - - /* Should the IPv6 header be generated or is it already included in p? */ - if (dest != LWIP_IP_HDRINCL) { - /* generate IPv6 header */ - if (pbuf_header(p, IP6_HLEN)) { - LWIP_DEBUGF(IP6_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("ip6_output: not enough room for IPv6 header in pbuf\n")); - IP6_STATS_INC(ip6.err); - return ERR_BUF; - } - - ip6hdr = (struct ip6_hdr *)p->payload; - LWIP_ASSERT("check that first pbuf can hold struct ip6_hdr", - (p->len >= sizeof(struct ip6_hdr))); - - IP6H_HOPLIM_SET(ip6hdr, hl); - IP6H_NEXTH_SET(ip6hdr, nexth); - - /* dest cannot be NULL here */ - ip6_addr_copy(ip6hdr->dest, *dest); - - IP6H_VTCFL_SET(ip6hdr, 6, tc, 0); - IP6H_PLEN_SET(ip6hdr, p->tot_len - IP6_HLEN); - - if (src == NULL) { - src = IP6_ADDR_ANY6; - } - /* src cannot be NULL here */ - ip6_addr_copy(ip6hdr->src, *src); - - } else { - /* IP header already included in p */ - ip6hdr = (struct ip6_hdr *)p->payload; - ip6_addr_copy(dest_addr, ip6hdr->dest); - dest = &dest_addr; - } - - IP6_STATS_INC(ip6.xmit); - -#if IP_DEBUG && LWIP_IP_DEBUG_TARGET - if (debug_target_match(1, ip6_2_ipX(src), ip6_2_ipX(dest))) - { -#endif - LWIP_DEBUGF(IP6_DEBUG, ("ip6_output_if: %c%c%"U16_F"\n", netif->name[0], netif->name[1], (u16_t)netif->num)); - ip6_debug_print(p); -#if IP_DEBUG && LWIP_IP_DEBUG_TARGET - } -#endif - -#if ENABLE_LOOPBACK - { - int i; - for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { - if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) && - ip6_addr_cmp(dest, netif_ip6_addr(netif, i))) { - /* Packet to self, enqueue it for loopback */ - LWIP_DEBUGF(IP6_DEBUG, ("netif_loop_output()\n")); - return netif_loop_output(netif, p); - } - } - } -#if LWIP_MULTICAST_TX_OPTIONS - if ((p->flags & PBUF_FLAG_MCASTLOOP) != 0) { - netif_loop_output(netif, p); - } -#endif /* LWIP_MULTICAST_TX_OPTIONS */ -#endif /* ENABLE_LOOPBACK */ -#if LWIP_IPV6_FRAG - /* don't fragment if interface has mtu set to 0 [loopif] */ - if (netif->mtu && (p->tot_len > nd6_get_destination_mtu(dest, netif))) { - return ip6_frag(p, netif, dest); - } -#endif /* LWIP_IPV6_FRAG */ - - LWIP_DEBUGF(IP6_DEBUG, ("netif->output_ip6()\n")); - return netif->output_ip6(netif, p, dest); -} - -/** - * Simple interface to ip6_output_if. It finds the outgoing network - * interface and calls upon ip6_output_if to do the actual work. - * - * @param p the packet to send (p->payload points to the data, e.g. next - protocol header; if dest == LWIP_IP_HDRINCL, p already includes an - IPv6 header and p->payload points to that IPv6 header) - * @param src the source IPv6 address to send from (if src == IP6_ADDR_ANY, an - * IP address of the netif is selected and used as source address. - * if src == NULL, IP6_ADDR_ANY is used as source) - * @param dest the destination IPv6 address to send the packet to - * @param hl the Hop Limit value to be set in the IPv6 header - * @param tc the Traffic Class value to be set in the IPv6 header - * @param nexth the Next Header to be set in the IPv6 header - * @param pcb the management channel - * - * @return ERR_RTE if no route is found - * see ip_output_if() for more return values - */ -err_t -ip6_output(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest, - u8_t hl, u8_t tc, u8_t nexth, struct ip_pcb *pcb) - -{ - err_t ret; - struct netif *netif; - struct ip6_hdr *ip6hdr; - ip6_addr_t src_addr, dest_addr; - - LWIP_IP_CHECK_PBUF_REF_COUNT_FOR_TX(p); - - if (dest != LWIP_IP_HDRINCL) { - netif = ip6_route(src, dest); - } else { - /* IP header included in p, read addresses. */ - ip6hdr = (struct ip6_hdr *)p->payload; - ip6_addr_copy(src_addr, ip6hdr->src); - ip6_addr_copy(dest_addr, ip6hdr->dest); - netif = ip6_route(&src_addr, &dest_addr); - } - - if (netif == NULL) { - LWIP_DEBUGF(IP6_DEBUG, ("ip6_output: no route for %"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F"\n", - IP6_ADDR_BLOCK1(dest), - IP6_ADDR_BLOCK2(dest), - IP6_ADDR_BLOCK3(dest), - IP6_ADDR_BLOCK4(dest), - IP6_ADDR_BLOCK5(dest), - IP6_ADDR_BLOCK6(dest), - IP6_ADDR_BLOCK7(dest), - IP6_ADDR_BLOCK8(dest))); - IP6_STATS_INC(ip6.rterr); - return ERR_RTE; - } - - if (pcb) netif_apply_pcb(netif, pcb); - ret = ip6_output_if(p, src, dest, hl, tc, nexth, netif); - if (pcb) netif_apply_pcb(netif, NULL); - - return ret; -} - - -#if LWIP_NETIF_HWADDRHINT -/** Like ip6_output, but takes and addr_hint pointer that is passed on to netif->addr_hint - * before calling ip6_output_if. - * - * @param p the packet to send (p->payload points to the data, e.g. next - protocol header; if dest == LWIP_IP_HDRINCL, p already includes an - IPv6 header and p->payload points to that IPv6 header) - * @param src the source IPv6 address to send from (if src == IP6_ADDR_ANY, an - * IP address of the netif is selected and used as source address. - * if src == NULL, IP6_ADDR_ANY is used as source) - * @param dest the destination IPv6 address to send the packet to - * @param hl the Hop Limit value to be set in the IPv6 header - * @param tc the Traffic Class value to be set in the IPv6 header - * @param nexth the Next Header to be set in the IPv6 header - * @param addr_hint address hint pointer set to netif->addr_hint before - * calling ip_output_if() - * - * @return ERR_RTE if no route is found - * see ip_output_if() for more return values - */ -err_t -ip6_output_hinted(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest, - u8_t hl, u8_t tc, u8_t nexth, u8_t *addr_hint) -{ - struct netif *netif; - struct ip6_hdr *ip6hdr; - ip6_addr_t src_addr, dest_addr; - err_t err; - - LWIP_IP_CHECK_PBUF_REF_COUNT_FOR_TX(p); - - if (dest != LWIP_IP_HDRINCL) { - netif = ip6_route(src, dest); - } else { - /* IP header included in p, read addresses. */ - ip6hdr = (struct ip6_hdr *)p->payload; - ip6_addr_copy(src_addr, ip6hdr->src); - ip6_addr_copy(dest_addr, ip6hdr->dest); - netif = ip6_route(&src_addr, &dest_addr); - } - - if (netif == NULL) { - LWIP_DEBUGF(IP6_DEBUG, ("ip6_output: no route for %"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F":%"X16_F"\n", - IP6_ADDR_BLOCK1(dest), - IP6_ADDR_BLOCK2(dest), - IP6_ADDR_BLOCK3(dest), - IP6_ADDR_BLOCK4(dest), - IP6_ADDR_BLOCK5(dest), - IP6_ADDR_BLOCK6(dest), - IP6_ADDR_BLOCK7(dest), - IP6_ADDR_BLOCK8(dest))); - IP6_STATS_INC(ip6.rterr); - return ERR_RTE; - } - - NETIF_SET_HWADDRHINT(netif, addr_hint); - err = ip6_output_if(p, src, dest, hl, tc, nexth, netif); - NETIF_SET_HWADDRHINT(netif, NULL); - - return err; -} -#endif /* LWIP_NETIF_HWADDRHINT*/ - -#if LWIP_IPV6_MLD -/** - * Add a hop-by-hop options header with a router alert option and padding. - * - * Used by MLD when sending a Multicast listener report/done message. - * - * @param p the packet to which we will prepend the options header - * @param nexth the next header protocol number (e.g. IP6_NEXTH_ICMP6) - * @param value the value of the router alert option data (e.g. IP6_ROUTER_ALERT_VALUE_MLD) - * @return ERR_OK if hop-by-hop header was added, ERR_* otherwise - */ -err_t -ip6_options_add_hbh_ra(struct pbuf *p, u8_t nexth, u8_t value) -{ - struct ip6_hbh_hdr *hbh_hdr; - - /* Move pointer to make room for hop-by-hop options header. */ - if (pbuf_header(p, sizeof(struct ip6_hbh_hdr))) { - LWIP_DEBUGF(IP6_DEBUG, ("ip6_options: no space for options header\n")); - IP6_STATS_INC(ip6.err); - return ERR_BUF; - } - - hbh_hdr = (struct ip6_hbh_hdr *)p->payload; - - /* Set fields. */ - hbh_hdr->_nexth = nexth; - hbh_hdr->_hlen = 0; - hbh_hdr->_ra_opt_type = IP6_ROUTER_ALERT_OPTION; - hbh_hdr->_ra_opt_dlen = 2; - hbh_hdr->_ra_opt_data = value; - hbh_hdr->_padn_opt_type = IP6_PADN_ALERT_OPTION; - hbh_hdr->_padn_opt_dlen = 0; - - return ERR_OK; -} -#endif /* LWIP_IPV6_MLD */ - -#if IP6_DEBUG -/* Print an IPv6 header by using LWIP_DEBUGF - * @param p an IPv6 packet, p->payload pointing to the IPv6 header - */ -void -ip6_debug_print(struct pbuf *p) -{ - struct ip6_hdr *ip6hdr = (struct ip6_hdr *)p->payload; - - LWIP_DEBUGF(IP6_DEBUG, ("IPv6 header:\n")); - LWIP_DEBUGF(IP6_DEBUG, ("+-------------------------------+\n")); - LWIP_DEBUGF(IP6_DEBUG, ("| %2"U16_F" | %3"U16_F" | %7"U32_F" | (ver, class, flow)\n", - IP6H_V(ip6hdr), - IP6H_TC(ip6hdr), - IP6H_FL(ip6hdr))); - LWIP_DEBUGF(IP6_DEBUG, ("+-------------------------------+\n")); - LWIP_DEBUGF(IP6_DEBUG, ("| %5"U16_F" | %3"U16_F" | %3"U16_F" | (plen, nexth, hopl)\n", - IP6H_PLEN(ip6hdr), - IP6H_NEXTH(ip6hdr), - IP6H_HOPLIM(ip6hdr))); - LWIP_DEBUGF(IP6_DEBUG, ("+-------------------------------+\n")); - LWIP_DEBUGF(IP6_DEBUG, ("| %4"X32_F" | %4"X32_F" | %4"X32_F" | %4"X32_F" | (src)\n", - IP6_ADDR_BLOCK1(&(ip6hdr->src)), - IP6_ADDR_BLOCK2(&(ip6hdr->src)), - IP6_ADDR_BLOCK3(&(ip6hdr->src)), - IP6_ADDR_BLOCK4(&(ip6hdr->src)))); - LWIP_DEBUGF(IP6_DEBUG, ("| %4"X32_F" | %4"X32_F" | %4"X32_F" | %4"X32_F" |\n", - IP6_ADDR_BLOCK5(&(ip6hdr->src)), - IP6_ADDR_BLOCK6(&(ip6hdr->src)), - IP6_ADDR_BLOCK7(&(ip6hdr->src)), - IP6_ADDR_BLOCK8(&(ip6hdr->src)))); - LWIP_DEBUGF(IP6_DEBUG, ("+-------------------------------+\n")); - LWIP_DEBUGF(IP6_DEBUG, ("| %4"X32_F" | %4"X32_F" | %4"X32_F" | %4"X32_F" | (dest)\n", - IP6_ADDR_BLOCK1(&(ip6hdr->dest)), - IP6_ADDR_BLOCK2(&(ip6hdr->dest)), - IP6_ADDR_BLOCK3(&(ip6hdr->dest)), - IP6_ADDR_BLOCK4(&(ip6hdr->dest)))); - LWIP_DEBUGF(IP6_DEBUG, ("| %4"X32_F" | %4"X32_F" | %4"X32_F" | %4"X32_F" |\n", - IP6_ADDR_BLOCK5(&(ip6hdr->dest)), - IP6_ADDR_BLOCK6(&(ip6hdr->dest)), - IP6_ADDR_BLOCK7(&(ip6hdr->dest)), - IP6_ADDR_BLOCK8(&(ip6hdr->dest)))); - LWIP_DEBUGF(IP6_DEBUG, ("+-------------------------------+\n")); -} -#endif /* IP6_DEBUG */ - -#endif /* LWIP_IPV6 */ diff --git a/third_party/lwip/repo/lwip/src/core/ipv6/ip6_addr.c b/third_party/lwip/repo/lwip/src/core/ipv6/ip6_addr.c deleted file mode 100644 index aa06659a0287c3..00000000000000 --- a/third_party/lwip/repo/lwip/src/core/ipv6/ip6_addr.c +++ /dev/null @@ -1,292 +0,0 @@ -/** - * @file - * - * IPv6 addresses. - */ - -/* - * Copyright (c) 2010 Inico Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Ivan Delamer - * - * Functions for handling IPv6 addresses. - * - * Please coordinate changes and requests with Ivan Delamer - * - */ - -#include "lwip/opt.h" - -#if LWIP_IPV6 /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/ip_addr.h" -#include "lwip/def.h" - -/* used by IP6_ADDR_ANY(6) in ip6_addr.h */ -const ip_addr_t ip6_addr_any = IPADDR6_INIT(0ul, 0ul, 0ul, 0ul); - -#ifndef isprint -#define in_range(c, lo, up) ((u8_t)c >= lo && (u8_t)c <= up) -#define isprint(c) in_range(c, 0x20, 0x7f) -#define isdigit(c) in_range(c, '0', '9') -#define isxdigit(c) (isdigit(c) || in_range(c, 'a', 'f') || in_range(c, 'A', 'F')) -#define islower(c) in_range(c, 'a', 'z') -#define isspace(c) (c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v') -#define xchar(i) ((i) < 10 ? '0' + (i) : 'A' + (i) - 10) -#endif - -/** - * Check whether "cp" is a valid ascii representation - * of an IPv6 address and convert to a binary address. - * Returns 1 if the address is valid, 0 if not. - * - * @param cp IPv6 address in ascii representation (e.g. "FF01::1") - * @param addr pointer to which to save the ip address in network order - * @return 1 if cp could be converted to addr, 0 on failure - */ -int -ip6addr_aton(const char *cp, ip6_addr_t *addr) -{ - u32_t addr_index, zero_blocks, current_block_index, current_block_value; - const char *s; - - /* Count the number of colons, to count the number of blocks in a "::" sequence - zero_blocks may be 1 even if there are no :: sequences */ - zero_blocks = 8; - for (s = cp; *s != 0; s++) { - if (*s == ':') { - zero_blocks--; - } else if (!isxdigit(*s)) { - break; - } - } - - /* parse each block */ - addr_index = 0; - current_block_index = 0; - current_block_value = 0; - for (s = cp; *s != 0; s++) { - if (*s == ':') { - if (addr) { - if (current_block_index & 0x1) { - addr->addr[addr_index++] |= current_block_value; - } - else { - addr->addr[addr_index] = current_block_value << 16; - } - } - current_block_index++; - current_block_value = 0; - if (current_block_index > 7) { - /* address too long! */ - return 0; - } - if (s[1] == ':') { - if (s[2] == ':') { - /* invalid format: three successive colons */ - return 0; - } - s++; - /* "::" found, set zeros */ - while (zero_blocks > 0) { - zero_blocks--; - if (current_block_index & 0x1) { - addr_index++; - } else { - if (addr) { - addr->addr[addr_index] = 0; - } - } - current_block_index++; - if (current_block_index > 7) { - /* address too long! */ - return 0; - } - } - } - } else if (isxdigit(*s)) { - /* add current digit */ - current_block_value = (current_block_value << 4) + - (isdigit(*s) ? (u32_t)(*s - '0') : - (u32_t)(10 + (islower(*s) ? *s - 'a' : *s - 'A'))); - } else { - /* unexpected digit, space? CRLF? */ - break; - } - } - - if (addr) { - if (current_block_index & 0x1) { - addr->addr[addr_index++] |= current_block_value; - } - else { - addr->addr[addr_index] = current_block_value << 16; - } - } - - /* convert to network byte order. */ - if (addr) { - for (addr_index = 0; addr_index < 4; addr_index++) { - addr->addr[addr_index] = lwip_htonl(addr->addr[addr_index]); - } - } - - if (current_block_index != 7) { - return 0; - } - - return 1; -} - -/** - * Convert numeric IPv6 address into ASCII representation. - * returns ptr to static buffer; not reentrant! - * - * @param addr ip6 address in network order to convert - * @return pointer to a global static (!) buffer that holds the ASCII - * representation of addr - */ -char * -ip6addr_ntoa(const ip6_addr_t *addr) -{ - static char str[40]; - return ip6addr_ntoa_r(addr, str, 40); -} - -/** - * Same as ipaddr_ntoa, but reentrant since a user-supplied buffer is used. - * - * @param addr ip6 address in network order to convert - * @param buf target buffer where the string is stored - * @param buflen length of buf - * @return either pointer to buf which now holds the ASCII - * representation of addr or NULL if buf was too small - */ -char * -ip6addr_ntoa_r(const ip6_addr_t *addr, char *buf, int buflen) -{ - u32_t current_block_index, current_block_value, next_block_value; - s32_t i; - u8_t zero_flag, empty_block_flag; - - i = 0; - empty_block_flag = 0; /* used to indicate a zero chain for "::' */ - - for (current_block_index = 0; current_block_index < 8; current_block_index++) { - /* get the current 16-bit block */ - current_block_value = lwip_htonl(addr->addr[current_block_index >> 1]); - if ((current_block_index & 0x1) == 0) { - current_block_value = current_block_value >> 16; - } - current_block_value &= 0xffff; - - /* Check for empty block. */ - if (current_block_value == 0) { - if (current_block_index == 7 && empty_block_flag == 1) { - /* special case, we must render a ':' for the last block. */ - buf[i++] = ':'; - if (i >= buflen) { - return NULL; - } - break; - } - if (empty_block_flag == 0) { - /* generate empty block "::", but only if more than one contiguous zero block, - * according to current formatting suggestions RFC 5952. */ - next_block_value = lwip_htonl(addr->addr[(current_block_index + 1) >> 1]); - if ((current_block_index & 0x1) == 0x01) { - next_block_value = next_block_value >> 16; - } - next_block_value &= 0xffff; - if (next_block_value == 0) { - empty_block_flag = 1; - buf[i++] = ':'; - if (i >= buflen) { - return NULL; - } - continue; /* move on to next block. */ - } - } else if (empty_block_flag == 1) { - /* move on to next block. */ - continue; - } - } else if (empty_block_flag == 1) { - /* Set this flag value so we don't produce multiple empty blocks. */ - empty_block_flag = 2; - } - - if (current_block_index > 0) { - buf[i++] = ':'; - if (i >= buflen) { - return NULL; - } - } - - if ((current_block_value & 0xf000) == 0) { - zero_flag = 1; - } else { - buf[i++] = xchar(((current_block_value & 0xf000) >> 12)); - zero_flag = 0; - if (i >= buflen) { - return NULL; - } - } - - if (((current_block_value & 0xf00) == 0) && (zero_flag)) { - /* do nothing */ - } else { - buf[i++] = xchar(((current_block_value & 0xf00) >> 8)); - zero_flag = 0; - if (i >= buflen) { - return NULL; - } - } - - if (((current_block_value & 0xf0) == 0) && (zero_flag)) { - /* do nothing */ - } - else { - buf[i++] = xchar(((current_block_value & 0xf0) >> 4)); - zero_flag = 0; - if (i >= buflen) { - return NULL; - } - } - - buf[i++] = xchar((current_block_value & 0xf)); - if (i >= buflen) { - return NULL; - } - } - - buf[i] = 0; - - return buf; -} - -#endif /* LWIP_IPV6 */ diff --git a/third_party/lwip/repo/lwip/src/core/ipv6/ip6_frag.c b/third_party/lwip/repo/lwip/src/core/ipv6/ip6_frag.c deleted file mode 100644 index 863a70e7a3369a..00000000000000 --- a/third_party/lwip/repo/lwip/src/core/ipv6/ip6_frag.c +++ /dev/null @@ -1,805 +0,0 @@ -/** - * @file - * - * IPv6 fragmentation and reassembly. - */ - -/* - * Copyright (c) 2010 Inico Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Ivan Delamer - * - * - * Please coordinate changes and requests with Ivan Delamer - * - */ - -#include "lwip/opt.h" -#include "lwip/ip6_frag.h" -#include "lwip/ip6.h" -#include "lwip/icmp6.h" -#include "lwip/nd6.h" -#include "lwip/ip.h" - -#include "lwip/pbuf.h" -#include "lwip/memp.h" -#include "lwip/stats.h" - -#include - -#if LWIP_IPV6 && LWIP_IPV6_REASS /* don't build if not configured for use in lwipopts.h */ - - -/** Setting this to 0, you can turn off checking the fragments for overlapping - * regions. The code gets a little smaller. Only use this if you know that - * overlapping won't occur on your network! */ -#ifndef IP_REASS_CHECK_OVERLAP -#define IP_REASS_CHECK_OVERLAP 1 -#endif /* IP_REASS_CHECK_OVERLAP */ - -/** Set to 0 to prevent freeing the oldest datagram when the reassembly buffer is - * full (IP_REASS_MAX_PBUFS pbufs are enqueued). The code gets a little smaller. - * Datagrams will be freed by timeout only. Especially useful when MEMP_NUM_REASSDATA - * is set to 1, so one datagram can be reassembled at a time, only. */ -#ifndef IP_REASS_FREE_OLDEST -#define IP_REASS_FREE_OLDEST 1 -#endif /* IP_REASS_FREE_OLDEST */ - -#if IPV6_FRAG_COPYHEADER -#define IPV6_FRAG_REQROOM ((s16_t)(sizeof(struct ip6_reass_helper) - IP6_FRAG_HLEN)) -#endif - -#define IP_REASS_FLAG_LASTFRAG 0x01 - -/** This is a helper struct which holds the starting - * offset and the ending offset of this fragment to - * easily chain the fragments. - * It has the same packing requirements as the IPv6 header, since it replaces - * the Fragment Header in memory in incoming fragments to keep - * track of the various fragments. - */ -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct ip6_reass_helper { - PACK_STRUCT_FIELD(struct pbuf *next_pbuf); - PACK_STRUCT_FIELD(u16_t start); - PACK_STRUCT_FIELD(u16_t end); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -/* static variables */ -static struct ip6_reassdata *reassdatagrams; -static u16_t ip6_reass_pbufcount; - -/* Forward declarations. */ -static void ip6_reass_free_complete_datagram(struct ip6_reassdata *ipr); -#if IP_REASS_FREE_OLDEST -static void ip6_reass_remove_oldest_datagram(struct ip6_reassdata *ipr, int pbufs_needed); -#endif /* IP_REASS_FREE_OLDEST */ - -void -ip6_reass_tmr(void) -{ - struct ip6_reassdata *r, *tmp; - -#if !IPV6_FRAG_COPYHEADER - LWIP_ASSERT("sizeof(struct ip6_reass_helper) <= IP6_FRAG_HLEN, set IPV6_FRAG_COPYHEADER to 1", - sizeof(struct ip6_reass_helper) <= IP6_FRAG_HLEN); -#endif /* !IPV6_FRAG_COPYHEADER */ - - r = reassdatagrams; - while (r != NULL) { - /* Decrement the timer. Once it reaches 0, - * clean up the incomplete fragment assembly */ - if (r->timer > 0) { - r->timer--; - r = r->next; - } else { - /* reassembly timed out */ - tmp = r; - /* get the next pointer before freeing */ - r = r->next; - /* free the helper struct and all enqueued pbufs */ - ip6_reass_free_complete_datagram(tmp); - } - } -} - -/** - * Free a datagram (struct ip6_reassdata) and all its pbufs. - * Updates the total count of enqueued pbufs (ip6_reass_pbufcount), - * sends an ICMP time exceeded packet. - * - * @param ipr datagram to free - */ -static void -ip6_reass_free_complete_datagram(struct ip6_reassdata *ipr) -{ - struct ip6_reassdata *prev; - u16_t pbufs_freed = 0; - u16_t clen; - struct pbuf *p; - struct ip6_reass_helper *iprh; - -#if LWIP_ICMP6 - iprh = (struct ip6_reass_helper *)ipr->p->payload; - if (iprh->start == 0) { - /* The first fragment was received, send ICMP time exceeded. */ - /* First, de-queue the first pbuf from r->p. */ - p = ipr->p; - ipr->p = iprh->next_pbuf; - /* Then, move back to the original ipv6 header (we are now pointing to Fragment header). - This cannot fail since we already checked when receiving this fragment. */ - if (pbuf_header_force(p, (s16_t)((u8_t*)p->payload - (u8_t*)IPV6_FRAG_HDRREF(ipr->iphdr)))) { - LWIP_ASSERT("ip6_reass_free: moving p->payload to ip6 header failed\n", 0); - } - else { - icmp6_time_exceeded(p, ICMP6_TE_FRAG); - } - clen = pbuf_clen(p); - LWIP_ASSERT("pbufs_freed + clen <= 0xffff", pbufs_freed + clen <= 0xffff); - pbufs_freed += clen; - pbuf_free(p); - } -#endif /* LWIP_ICMP6 */ - - /* First, free all received pbufs. The individual pbufs need to be released - separately as they have not yet been chained */ - p = ipr->p; - while (p != NULL) { - struct pbuf *pcur; - iprh = (struct ip6_reass_helper *)p->payload; - pcur = p; - /* get the next pointer before freeing */ - p = iprh->next_pbuf; - clen = pbuf_clen(pcur); - LWIP_ASSERT("pbufs_freed + clen <= 0xffff", pbufs_freed + clen <= 0xffff); - pbufs_freed += clen; - pbuf_free(pcur); - } - - /* Then, unchain the struct ip6_reassdata from the list and free it. */ - if (ipr == reassdatagrams) { - reassdatagrams = ipr->next; - } else { - prev = reassdatagrams; - while (prev != NULL) { - if (prev->next == ipr) { - break; - } - prev = prev->next; - } - if (prev != NULL) { - prev->next = ipr->next; - } - } - memp_free(MEMP_IP6_REASSDATA, ipr); - - /* Finally, update number of pbufs in reassembly queue */ - LWIP_ASSERT("ip_reass_pbufcount >= clen", ip6_reass_pbufcount >= pbufs_freed); - ip6_reass_pbufcount -= pbufs_freed; -} - -#if IP_REASS_FREE_OLDEST -/** - * Free the oldest datagram to make room for enqueueing new fragments. - * The datagram ipr is not freed! - * - * @param ipr ip6_reassdata for the current fragment - * @param pbufs_needed number of pbufs needed to enqueue - * (used for freeing other datagrams if not enough space) - */ -static void -ip6_reass_remove_oldest_datagram(struct ip6_reassdata *ipr, int pbufs_needed) -{ - struct ip6_reassdata *r, *oldest; - - /* Free datagrams until being allowed to enqueue 'pbufs_needed' pbufs, - * but don't free the current datagram! */ - do { - r = oldest = reassdatagrams; - while (r != NULL) { - if (r != ipr) { - if (r->timer <= oldest->timer) { - /* older than the previous oldest */ - oldest = r; - } - } - r = r->next; - } - if (oldest == ipr) { - /* nothing to free, ipr is the only element on the list */ - return; - } - if (oldest != NULL) { - ip6_reass_free_complete_datagram(oldest); - } - } while (((ip6_reass_pbufcount + pbufs_needed) > IP_REASS_MAX_PBUFS) && (reassdatagrams != NULL)); -} -#endif /* IP_REASS_FREE_OLDEST */ - -/** - * Reassembles incoming IPv6 fragments into an IPv6 datagram. - * - * @param p points to the IPv6 Fragment Header - * @return NULL if reassembly is incomplete, pbuf pointing to - * IPv6 Header if reassembly is complete - */ -struct pbuf * -ip6_reass(struct pbuf *p) -{ - struct ip6_reassdata *ipr, *ipr_prev; - struct ip6_reass_helper *iprh, *iprh_tmp, *iprh_prev=NULL; - struct ip6_frag_hdr *frag_hdr; - u16_t offset, len; - u16_t clen; - u8_t valid = 1; - struct pbuf *q; - - IP6_FRAG_STATS_INC(ip6_frag.recv); - - if ((const void*)ip6_current_header() != ((u8_t*)p->payload) - IP6_HLEN) { - /* ip6_frag_hdr must be in the first pbuf, not chained */ - IP6_FRAG_STATS_INC(ip6_frag.proterr); - IP6_FRAG_STATS_INC(ip6_frag.drop); - goto nullreturn; - } - - frag_hdr = (struct ip6_frag_hdr *) p->payload; - - clen = pbuf_clen(p); - - offset = lwip_ntohs(frag_hdr->_fragment_offset); - - /* Calculate fragment length from IPv6 payload length. - * Adjust for headers before Fragment Header. - * And finally adjust by Fragment Header length. */ - len = lwip_ntohs(ip6_current_header()->_plen); - len -= (u16_t)(((u8_t*)p->payload - (const u8_t*)ip6_current_header()) - IP6_HLEN); - len -= IP6_FRAG_HLEN; - - /* Look for the datagram the fragment belongs to in the current datagram queue, - * remembering the previous in the queue for later dequeueing. */ - for (ipr = reassdatagrams, ipr_prev = NULL; ipr != NULL; ipr = ipr->next) { - /* Check if the incoming fragment matches the one currently present - in the reassembly buffer. If so, we proceed with copying the - fragment into the buffer. */ - if ((frag_hdr->_identification == ipr->identification) && - ip6_addr_cmp(ip6_current_src_addr(), &(IPV6_FRAG_HDRREF(ipr->iphdr)->src)) && - ip6_addr_cmp(ip6_current_dest_addr(), &(IPV6_FRAG_HDRREF(ipr->iphdr)->dest))) { - IP6_FRAG_STATS_INC(ip6_frag.cachehit); - break; - } - ipr_prev = ipr; - } - - if (ipr == NULL) { - /* Enqueue a new datagram into the datagram queue */ - ipr = (struct ip6_reassdata *)memp_malloc(MEMP_IP6_REASSDATA); - if (ipr == NULL) { -#if IP_REASS_FREE_OLDEST - /* Make room and try again. */ - ip6_reass_remove_oldest_datagram(ipr, clen); - ipr = (struct ip6_reassdata *)memp_malloc(MEMP_IP6_REASSDATA); - if (ipr != NULL) { - /* re-search ipr_prev since it might have been removed */ - for (ipr_prev = reassdatagrams; ipr_prev != NULL; ipr_prev = ipr_prev->next) { - if (ipr_prev->next == ipr) { - break; - } - } - } else -#endif /* IP_REASS_FREE_OLDEST */ - { - IP6_FRAG_STATS_INC(ip6_frag.memerr); - IP6_FRAG_STATS_INC(ip6_frag.drop); - goto nullreturn; - } - } - - memset(ipr, 0, sizeof(struct ip6_reassdata)); - ipr->timer = IP_REASS_MAXAGE; - - /* enqueue the new structure to the front of the list */ - ipr->next = reassdatagrams; - reassdatagrams = ipr; - - /* Use the current IPv6 header for src/dest address reference. - * Eventually, we will replace it when we get the first fragment - * (it might be this one, in any case, it is done later). */ -#if IPV6_FRAG_COPYHEADER - MEMCPY(&ipr->iphdr, ip6_current_header(), IP6_HLEN); -#else /* IPV6_FRAG_COPYHEADER */ - /* need to use the none-const pointer here: */ - ipr->iphdr = ip_data.current_ip6_header; -#endif /* IPV6_FRAG_COPYHEADER */ - - /* copy the fragmented packet id. */ - ipr->identification = frag_hdr->_identification; - - /* copy the nexth field */ - ipr->nexth = frag_hdr->_nexth; - } - - /* Check if we are allowed to enqueue more datagrams. */ - if ((ip6_reass_pbufcount + clen) > IP_REASS_MAX_PBUFS) { -#if IP_REASS_FREE_OLDEST - ip6_reass_remove_oldest_datagram(ipr, clen); - if ((ip6_reass_pbufcount + clen) <= IP_REASS_MAX_PBUFS) { - /* re-search ipr_prev since it might have been removed */ - for (ipr_prev = reassdatagrams; ipr_prev != NULL; ipr_prev = ipr_prev->next) { - if (ipr_prev->next == ipr) { - break; - } - } - } else -#endif /* IP_REASS_FREE_OLDEST */ - { - /* @todo: send ICMPv6 time exceeded here? */ - /* drop this pbuf */ - IP6_FRAG_STATS_INC(ip6_frag.memerr); - IP6_FRAG_STATS_INC(ip6_frag.drop); - goto nullreturn; - } - } - - /* Overwrite Fragment Header with our own helper struct. */ -#if IPV6_FRAG_COPYHEADER - if (IPV6_FRAG_REQROOM > 0) { - /* Make room for struct ip6_reass_helper (only required if sizeof(void*) > 4). - This cannot fail since we already checked when receiving this fragment. */ - u8_t hdrerr = pbuf_header_force(p, IPV6_FRAG_REQROOM); - LWIP_UNUSED_ARG(hdrerr); /* in case of LWIP_NOASSERT */ - LWIP_ASSERT("no room for struct ip6_reass_helper", hdrerr == 0); - } -#else /* IPV6_FRAG_COPYHEADER */ - LWIP_ASSERT("sizeof(struct ip6_reass_helper) <= IP6_FRAG_HLEN, set IPV6_FRAG_COPYHEADER to 1", - sizeof(struct ip6_reass_helper) <= IP6_FRAG_HLEN); -#endif /* IPV6_FRAG_COPYHEADER */ - iprh = (struct ip6_reass_helper *)p->payload; - iprh->next_pbuf = NULL; - iprh->start = (offset & IP6_FRAG_OFFSET_MASK); - iprh->end = (offset & IP6_FRAG_OFFSET_MASK) + len; - - /* find the right place to insert this pbuf */ - /* Iterate through until we either get to the end of the list (append), - * or we find on with a larger offset (insert). */ - for (q = ipr->p; q != NULL;) { - iprh_tmp = (struct ip6_reass_helper*)q->payload; - if (iprh->start < iprh_tmp->start) { -#if IP_REASS_CHECK_OVERLAP - if (iprh->end > iprh_tmp->start) { - /* fragment overlaps with following, throw away */ - IP6_FRAG_STATS_INC(ip6_frag.proterr); - IP6_FRAG_STATS_INC(ip6_frag.drop); - goto nullreturn; - } - if (iprh_prev != NULL) { - if (iprh->start < iprh_prev->end) { - /* fragment overlaps with previous, throw away */ - IP6_FRAG_STATS_INC(ip6_frag.proterr); - IP6_FRAG_STATS_INC(ip6_frag.drop); - goto nullreturn; - } - } -#endif /* IP_REASS_CHECK_OVERLAP */ - /* the new pbuf should be inserted before this */ - iprh->next_pbuf = q; - if (iprh_prev != NULL) { - /* not the fragment with the lowest offset */ - iprh_prev->next_pbuf = p; - } else { - /* fragment with the lowest offset */ - ipr->p = p; - } - break; - } else if (iprh->start == iprh_tmp->start) { - /* received the same datagram twice: no need to keep the datagram */ - IP6_FRAG_STATS_INC(ip6_frag.drop); - goto nullreturn; -#if IP_REASS_CHECK_OVERLAP - } else if (iprh->start < iprh_tmp->end) { - /* overlap: no need to keep the new datagram */ - IP6_FRAG_STATS_INC(ip6_frag.proterr); - IP6_FRAG_STATS_INC(ip6_frag.drop); - goto nullreturn; -#endif /* IP_REASS_CHECK_OVERLAP */ - } else { - /* Check if the fragments received so far have no gaps. */ - if (iprh_prev != NULL) { - if (iprh_prev->end != iprh_tmp->start) { - /* There is a fragment missing between the current - * and the previous fragment */ - valid = 0; - } - } - } - q = iprh_tmp->next_pbuf; - iprh_prev = iprh_tmp; - } - - /* If q is NULL, then we made it to the end of the list. Determine what to do now */ - if (q == NULL) { - if (iprh_prev != NULL) { - /* this is (for now), the fragment with the highest offset: - * chain it to the last fragment */ -#if IP_REASS_CHECK_OVERLAP - LWIP_ASSERT("check fragments don't overlap", iprh_prev->end <= iprh->start); -#endif /* IP_REASS_CHECK_OVERLAP */ - iprh_prev->next_pbuf = p; - if (iprh_prev->end != iprh->start) { - valid = 0; - } - } else { -#if IP_REASS_CHECK_OVERLAP - LWIP_ASSERT("no previous fragment, this must be the first fragment!", - ipr->p == NULL); -#endif /* IP_REASS_CHECK_OVERLAP */ - /* this is the first fragment we ever received for this ip datagram */ - ipr->p = p; - } - } - - /* Track the current number of pbufs current 'in-flight', in order to limit - the number of fragments that may be enqueued at any one time */ - ip6_reass_pbufcount += clen; - - /* Remember IPv6 header if this is the first fragment. */ - if (iprh->start == 0) { -#if IPV6_FRAG_COPYHEADER - if (iprh->next_pbuf != NULL) { - MEMCPY(&ipr->iphdr, ip6_current_header(), IP6_HLEN); - } -#else /* IPV6_FRAG_COPYHEADER */ - /* need to use the none-const pointer here: */ - ipr->iphdr = ip_data.current_ip6_header; -#endif /* IPV6_FRAG_COPYHEADER */ - } - - /* If this is the last fragment, calculate total packet length. */ - if ((offset & IP6_FRAG_MORE_FLAG) == 0) { - ipr->datagram_len = iprh->end; - } - - /* Additional validity tests: we have received first and last fragment. */ - iprh_tmp = (struct ip6_reass_helper*)ipr->p->payload; - if (iprh_tmp->start != 0) { - valid = 0; - } - if (ipr->datagram_len == 0) { - valid = 0; - } - - /* Final validity test: no gaps between current and last fragment. */ - iprh_prev = iprh; - q = iprh->next_pbuf; - while ((q != NULL) && valid) { - iprh = (struct ip6_reass_helper*)q->payload; - if (iprh_prev->end != iprh->start) { - valid = 0; - break; - } - iprh_prev = iprh; - q = iprh->next_pbuf; - } - - if (valid) { - /* All fragments have been received */ - struct ip6_hdr* iphdr_ptr; - - /* chain together the pbufs contained within the ip6_reassdata list. */ - iprh = (struct ip6_reass_helper*) ipr->p->payload; - while (iprh != NULL) { - struct pbuf* next_pbuf = iprh->next_pbuf; - if (next_pbuf != NULL) { - /* Save next helper struct (will be hidden in next step). */ - iprh_tmp = (struct ip6_reass_helper*)next_pbuf->payload; - - /* hide the fragment header for every succeeding fragment */ - pbuf_header(next_pbuf, -IP6_FRAG_HLEN); -#if IPV6_FRAG_COPYHEADER - if (IPV6_FRAG_REQROOM > 0) { - /* hide the extra bytes borrowed from ip6_hdr for struct ip6_reass_helper */ - u8_t hdrerr = pbuf_header(next_pbuf, -(IPV6_FRAG_REQROOM)); - LWIP_UNUSED_ARG(hdrerr); /* in case of LWIP_NOASSERT */ - LWIP_ASSERT("no room for struct ip6_reass_helper", hdrerr == 0); - } -#endif - pbuf_cat(ipr->p, next_pbuf); - } - else { - iprh_tmp = NULL; - } - - iprh = iprh_tmp; - } - -#if IPV6_FRAG_COPYHEADER - if (IPV6_FRAG_REQROOM > 0) { - /* get back room for struct ip6_reass_helper (only required if sizeof(void*) > 4) */ - u8_t hdrerr = pbuf_header(ipr->p, -(IPV6_FRAG_REQROOM)); - LWIP_UNUSED_ARG(hdrerr); /* in case of LWIP_NOASSERT */ - LWIP_ASSERT("no room for struct ip6_reass_helper", hdrerr == 0); - } - iphdr_ptr = (struct ip6_hdr*)((u8_t*)ipr->p->payload - IP6_HLEN); - MEMCPY(iphdr_ptr, &ipr->iphdr, IP6_HLEN); -#else - iphdr_ptr = ipr->iphdr; -#endif - - /* Adjust datagram length by adding header lengths. */ - ipr->datagram_len += (u16_t)(((u8_t*)ipr->p->payload - (u8_t*)iphdr_ptr) - + IP6_FRAG_HLEN - - IP6_HLEN); - - /* Set payload length in ip header. */ - iphdr_ptr->_plen = lwip_htons(ipr->datagram_len); - - /* Get the first pbuf. */ - p = ipr->p; - - /* Restore Fragment Header in first pbuf. Mark as "single fragment" - * packet. Restore nexth. */ - frag_hdr = (struct ip6_frag_hdr *) p->payload; - frag_hdr->_nexth = ipr->nexth; - frag_hdr->reserved = 0; - frag_hdr->_fragment_offset = 0; - frag_hdr->_identification = 0; - - /* release the sources allocate for the fragment queue entry */ - if (reassdatagrams == ipr) { - /* it was the first in the list */ - reassdatagrams = ipr->next; - } else { - /* it wasn't the first, so it must have a valid 'prev' */ - LWIP_ASSERT("sanity check linked list", ipr_prev != NULL); - ipr_prev->next = ipr->next; - } - memp_free(MEMP_IP6_REASSDATA, ipr); - - /* adjust the number of pbufs currently queued for reassembly. */ - ip6_reass_pbufcount -= pbuf_clen(p); - - /* Move pbuf back to IPv6 header. - This cannot fail since we already checked when receiving this fragment. */ - if (pbuf_header_force(p, (s16_t)((u8_t*)p->payload - (u8_t*)iphdr_ptr))) { - LWIP_ASSERT("ip6_reass: moving p->payload to ip6 header failed\n", 0); - pbuf_free(p); - return NULL; - } - - /* Return the pbuf chain */ - return p; - } - /* the datagram is not (yet?) reassembled completely */ - return NULL; - -nullreturn: - pbuf_free(p); - return NULL; -} - -#endif /* LWIP_IPV6 && LWIP_IPV6_REASS */ - -#if LWIP_IPV6 && LWIP_IPV6_FRAG - -#if !LWIP_NETIF_TX_SINGLE_PBUF -/** Allocate a new struct pbuf_custom_ref */ -static struct pbuf_custom_ref* -ip6_frag_alloc_pbuf_custom_ref(void) -{ - return (struct pbuf_custom_ref*)memp_malloc(MEMP_FRAG_PBUF); -} - -/** Free a struct pbuf_custom_ref */ -static void -ip6_frag_free_pbuf_custom_ref(struct pbuf_custom_ref* p) -{ - LWIP_ASSERT("p != NULL", p != NULL); - memp_free(MEMP_FRAG_PBUF, p); -} - -/** Free-callback function to free a 'struct pbuf_custom_ref', called by - * pbuf_free. */ -static void -ip6_frag_free_pbuf_custom(struct pbuf *p) -{ - struct pbuf_custom_ref *pcr = (struct pbuf_custom_ref*)p; - LWIP_ASSERT("pcr != NULL", pcr != NULL); - LWIP_ASSERT("pcr == p", (void*)pcr == (void*)p); - if (pcr->original != NULL) { - pbuf_free(pcr->original); - } - ip6_frag_free_pbuf_custom_ref(pcr); -} -#endif /* !LWIP_NETIF_TX_SINGLE_PBUF */ - -/** - * Fragment an IPv6 datagram if too large for the netif or path MTU. - * - * Chop the datagram in MTU sized chunks and send them in order - * by pointing PBUF_REFs into p - * - * @param p ipv6 packet to send - * @param netif the netif on which to send - * @param dest destination ipv6 address to which to send - * - * @return ERR_OK if sent successfully, err_t otherwise - */ -err_t -ip6_frag(struct pbuf *p, struct netif *netif, const ip6_addr_t *dest) -{ - struct ip6_hdr *original_ip6hdr; - struct ip6_hdr *ip6hdr; - struct ip6_frag_hdr *frag_hdr; - struct pbuf *rambuf; -#if !LWIP_NETIF_TX_SINGLE_PBUF - struct pbuf *newpbuf; - u16_t newpbuflen = 0; - u16_t left_to_copy; -#endif - static u32_t identification; - u16_t nfb; - u16_t left, cop; - u16_t mtu; - u16_t fragment_offset = 0; - u16_t last; - u16_t poff = IP6_HLEN; - - identification++; - - original_ip6hdr = (struct ip6_hdr *)p->payload; - - mtu = nd6_get_destination_mtu(dest, netif); - - /* @todo we assume there are no options in the unfragmentable part (IPv6 header). */ - left = p->tot_len - IP6_HLEN; - - nfb = (mtu - (IP6_HLEN + IP6_FRAG_HLEN)) & IP6_FRAG_OFFSET_MASK; - - while (left) { - last = (left <= nfb); - - /* Fill this fragment */ - cop = last ? left : nfb; - -#if LWIP_NETIF_TX_SINGLE_PBUF - rambuf = pbuf_alloc(PBUF_IP, cop + IP6_FRAG_HLEN, PBUF_RAM); - if (rambuf == NULL) { - IP6_FRAG_STATS_INC(ip6_frag.memerr); - return ERR_MEM; - } - LWIP_ASSERT("this needs a pbuf in one piece!", - (rambuf->len == rambuf->tot_len) && (rambuf->next == NULL)); - poff += pbuf_copy_partial(p, (u8_t*)rambuf->payload + IP6_FRAG_HLEN, cop, poff); - /* make room for the IP header */ - if (pbuf_header(rambuf, IP6_HLEN)) { - pbuf_free(rambuf); - IP6_FRAG_STATS_INC(ip6_frag.memerr); - return ERR_MEM; - } - /* fill in the IP header */ - SMEMCPY(rambuf->payload, original_ip6hdr, IP6_HLEN); - ip6hdr = (struct ip6_hdr *)rambuf->payload; - frag_hdr = (struct ip6_frag_hdr *)((u8_t*)rambuf->payload + IP6_HLEN); -#else - /* When not using a static buffer, create a chain of pbufs. - * The first will be a PBUF_RAM holding the link, IPv6, and Fragment header. - * The rest will be PBUF_REFs mirroring the pbuf chain to be fragged, - * but limited to the size of an mtu. - */ - rambuf = pbuf_alloc(PBUF_LINK, IP6_HLEN + IP6_FRAG_HLEN, PBUF_RAM); - if (rambuf == NULL) { - IP6_FRAG_STATS_INC(ip6_frag.memerr); - return ERR_MEM; - } - LWIP_ASSERT("this needs a pbuf in one piece!", - (p->len >= (IP6_HLEN))); - SMEMCPY(rambuf->payload, original_ip6hdr, IP6_HLEN); - ip6hdr = (struct ip6_hdr *)rambuf->payload; - frag_hdr = (struct ip6_frag_hdr *)((u8_t*)rambuf->payload + IP6_HLEN); - - /* Can just adjust p directly for needed offset. */ - p->payload = (u8_t *)p->payload + poff; - p->len -= poff; - p->tot_len -= poff; - - left_to_copy = cop; - while (left_to_copy) { - struct pbuf_custom_ref *pcr; - newpbuflen = (left_to_copy < p->len) ? left_to_copy : p->len; - /* Is this pbuf already empty? */ - if (!newpbuflen) { - p = p->next; - continue; - } - pcr = ip6_frag_alloc_pbuf_custom_ref(); - if (pcr == NULL) { - pbuf_free(rambuf); - IP6_FRAG_STATS_INC(ip6_frag.memerr); - return ERR_MEM; - } - /* Mirror this pbuf, although we might not need all of it. */ - newpbuf = pbuf_alloced_custom(PBUF_RAW, newpbuflen, PBUF_REF, &pcr->pc, p->payload, newpbuflen); - if (newpbuf == NULL) { - ip6_frag_free_pbuf_custom_ref(pcr); - pbuf_free(rambuf); - IP6_FRAG_STATS_INC(ip6_frag.memerr); - return ERR_MEM; - } - pbuf_ref(p); - pcr->original = p; - pcr->pc.custom_free_function = ip6_frag_free_pbuf_custom; - - /* Add it to end of rambuf's chain, but using pbuf_cat, not pbuf_chain - * so that it is removed when pbuf_dechain is later called on rambuf. - */ - pbuf_cat(rambuf, newpbuf); - left_to_copy -= newpbuflen; - if (left_to_copy) { - p = p->next; - } - } - poff = newpbuflen; -#endif /* LWIP_NETIF_TX_SINGLE_PBUF */ - - /* Set headers */ - frag_hdr->_nexth = original_ip6hdr->_nexth; - frag_hdr->reserved = 0; - frag_hdr->_fragment_offset = lwip_htons((fragment_offset & IP6_FRAG_OFFSET_MASK) | (last ? 0 : IP6_FRAG_MORE_FLAG)); - frag_hdr->_identification = lwip_htonl(identification); - - IP6H_NEXTH_SET(ip6hdr, IP6_NEXTH_FRAGMENT); - IP6H_PLEN_SET(ip6hdr, cop + IP6_FRAG_HLEN); - - /* No need for separate header pbuf - we allowed room for it in rambuf - * when allocated. - */ - IP6_FRAG_STATS_INC(ip6_frag.xmit); - netif->output_ip6(netif, rambuf, dest); - - /* Unfortunately we can't reuse rambuf - the hardware may still be - * using the buffer. Instead we free it (and the ensuing chain) and - * recreate it next time round the loop. If we're lucky the hardware - * will have already sent the packet, the free will really free, and - * there will be zero memory penalty. - */ - - pbuf_free(rambuf); - left -= cop; - fragment_offset += cop; - } - return ERR_OK; -} - -#endif /* LWIP_IPV6 && LWIP_IPV6_FRAG */ diff --git a/third_party/lwip/repo/lwip/src/core/ipv6/ip6_route_table.c b/third_party/lwip/repo/lwip/src/core/ipv6/ip6_route_table.c deleted file mode 100644 index ff1b176e038b8b..00000000000000 --- a/third_party/lwip/repo/lwip/src/core/ipv6/ip6_route_table.c +++ /dev/null @@ -1,252 +0,0 @@ -/** - * @file - * - * IPv6 static route table. - */ - -/* - * Copyright (c) 2015 Nest Labs, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * Author: Pradip De - * - * - * Please coordinate changes and requests with Pradip De - * - */ - -#include "lwip/opt.h" - -#if LWIP_IPV6 /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/def.h" -#include "lwip/mem.h" -#include "lwip/netif.h" -#include "lwip/ip6.h" -#include "lwip/ip6_route_table.h" -#include "lwip/ip6_addr.h" -#include "lwip/nd6.h" -#include "lwip/debug.h" -#include "lwip/stats.h" - -#include "string.h" - -#if LWIP_IPV6_ROUTE_TABLE_SUPPORT - -static struct ip6_route_entry static_route_table[LWIP_IPV6_NUM_ROUTE_ENTRIES]; - -/** - * Add the ip6 prefix route and target netif into the static route table while - * keeping all entries sorted in decreasing order of prefix length. - * 1. Search from the last entry up to find the correct slot to insert while - * moving entries one position down to create room. - * 2. Insert into empty slot created. - * - * Subsequently, a linear search down the list can be performed to retrieve a - * matching route entry for a Longest Prefix Match. - * - * @param ip6_prefix the route prefix entry to add. - * @param netif pointer to target netif. - * @param gateway the gateway address to use to send through. Has to be link local. - * @param index return value argument of index where route entry was added in table. - * @return ERR_OK if addition was successful. - * ERR_MEM if table is already full. - * ERR_ARG if passed argument is bad or route already exists in table. - */ -err_t -ip6_add_route_entry(struct ip6_prefix *ip6_prefix, struct netif *netif, ip6_addr_t *gateway, s8_t *index) -{ - int i = -1; - err_t retval = ERR_OK; - - if (!ip6_prefix_valid(ip6_prefix->prefix_len) || (netif == NULL)) { - retval = ERR_ARG; - goto exit; - } - - /* Check if an entry already exists with matching prefix; If so, replace it. */ - for (i = 0; i < LWIP_IPV6_NUM_ROUTE_ENTRIES; i++) { - if ((ip6_prefix->prefix_len == static_route_table[i].prefix.prefix_len) && - memcmp(&ip6_prefix->addr, &static_route_table[i].prefix.addr, - ip6_prefix->prefix_len / 8) == 0) { - //Prefix matches; replace the netif with the one being added. - goto insert; - } - } - - /* Check if the table is full */ - if (static_route_table[LWIP_IPV6_NUM_ROUTE_ENTRIES - 1].netif != NULL) { - retval = ERR_MEM; - goto exit; - } - - /* Shift all entries down the table until slot is found */ - for (i = LWIP_IPV6_NUM_ROUTE_ENTRIES - 1; - i > 0 && (ip6_prefix->prefix_len > static_route_table[i - 1].prefix.prefix_len); i--) { - SMEMCPY(&static_route_table[i], &static_route_table[i - 1], sizeof(struct ip6_route_entry)); - } - -insert: - /* Insert into the slot selected */ - SMEMCPY(&static_route_table[i].prefix, ip6_prefix, sizeof(struct ip6_prefix)); - static_route_table[i].netif = netif; - - /* Add gateway to route table */ - static_route_table[i].gateway = gateway; - - if (index != NULL) { - *index = i; - } - -exit: - return retval; -} - -/** - * Removes the route entry from the static route table. - * - * @param ip6_prefix the route prefix entry to delete. - */ -void -ip6_remove_route_entry(struct ip6_prefix *ip6_prefix) -{ - int i, pos = -1; - - for (i = 0; i < LWIP_IPV6_NUM_ROUTE_ENTRIES; i++) { - /* compare prefix to find position to delete */ - if (ip6_prefix->prefix_len == static_route_table[i].prefix.prefix_len && - memcmp(&ip6_prefix->addr, &static_route_table[i].prefix.addr, - ip6_prefix->prefix_len / 8) == 0) { - pos = i; - break; - } - } - - if (pos >= 0) { - /* Shift everything beyond pos one slot up */ - for (i = pos; i < LWIP_IPV6_NUM_ROUTE_ENTRIES - 1; i++) { - SMEMCPY(&static_route_table[i], &static_route_table[i+1], sizeof(struct ip6_route_entry)); - if (static_route_table[i].netif == NULL) { - break; - } - } - /* Zero the remaining entries */ - for (; i < LWIP_IPV6_NUM_ROUTE_ENTRIES; i++) { - ip6_addr_set_zero((&static_route_table[i].prefix.addr)); - static_route_table[i].netif = NULL; - } - } - - return; -} - -/** - * Finds the appropriate route entry in the static route table corresponding to the given - * destination IPv6 address. Since the entries in the route table are kept sorted in decreasing - * order of prefix length, a linear search down the list is performed to retrieve a matching - * index. - * - * @param ip6_dest_addr the destination address to match - * @return the index of the found route entry; -1 if not found. - */ -s8_t -ip6_find_route_entry(const ip6_addr_t *ip6_dest_addr) -{ - int i, index = -1; - - /* Search prefix in the sorted(decreasing order of prefix length) list */ - for(i = 0; i < LWIP_IPV6_NUM_ROUTE_ENTRIES; i++) { - if (memcmp(ip6_dest_addr, &static_route_table[i].prefix.addr, - static_route_table[i].prefix.prefix_len / 8) == 0) { - index = i; - break; - } - } - - return index; -} - -/** - * Finds the appropriate network interface for a given IPv6 address from a routing table with - * static IPv6 routes. - * - * @param src the source IPv6 address, if known - * @param dest the destination IPv6 address for which to find the route - * @return the netif on which to send to reach dest - */ -struct netif * -ip6_static_route(const ip6_addr_t *src, const ip6_addr_t *dest) -{ - - int i; - /* Perform table lookup */ - i = ip6_find_route_entry(dest); - - if (i >= 0) { - return static_route_table[i].netif; - } - else { - return NULL; - } -} - -/** - * Finds the gateway IP6 address for a given destination IPv6 address and target netif - * from a routing table with static IPv6 routes. - * - * @param netif the netif used for sending - * @param dest the destination IPv6 address - * @return the ip6 address of the gateway to forward packet to - */ -ip6_addr_t * -ip6_get_gateway(struct netif *netif, const ip6_addr_t *dest) -{ - ip6_addr_t *ret_gw = NULL; - const int i = ip6_find_route_entry(dest); - - if (i >= 0) { - if (static_route_table[i].gateway != NULL) { - ret_gw = static_route_table[i].gateway; - } - } - - return ret_gw; -} - -/** - * Returns the top of the route table. - * This should be used for debug printing only. - * - * @return the top of the route table. - */ -struct ip6_route_entry * -ip6_get_route_table(void) -{ - return static_route_table; -} - -#endif /* LWIP_IPV6_ROUTE_TABLE_SUPPORT */ - -#endif /* LWIP_IPV6 */ diff --git a/third_party/lwip/repo/lwip/src/core/ipv6/mld6.c b/third_party/lwip/repo/lwip/src/core/ipv6/mld6.c deleted file mode 100644 index 3c98baa6d473bc..00000000000000 --- a/third_party/lwip/repo/lwip/src/core/ipv6/mld6.c +++ /dev/null @@ -1,623 +0,0 @@ -/** - * @file - * Multicast listener discovery - * - * @defgroup mld6 MLD6 - * @ingroup ip6 - * Multicast listener discovery for IPv6. Aims to be compliant with RFC 2710. - * No support for MLDv2.\n - * To be called from TCPIP thread - */ - -/* - * Copyright (c) 2010 Inico Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Ivan Delamer - * - * - * Please coordinate changes and requests with Ivan Delamer - * - */ - -/* Based on igmp.c implementation of igmp v2 protocol */ - -#include "lwip/opt.h" - -/* don't build if not configured for use in lwipopts.h */ -#if LWIP_IPV6 && LWIP_IPV6_ND && LWIP_IPV6_MLD - -#include "lwip/mld6.h" -#include "lwip/prot/mld6.h" -#include "lwip/icmp6.h" -#include "lwip/ip6.h" -#include "lwip/ip6_addr.h" -#include "lwip/ip.h" -#include "lwip/inet_chksum.h" -#include "lwip/pbuf.h" -#include "lwip/netif.h" -#include "lwip/memp.h" -#include "lwip/stats.h" -#include "lwip/timeouts.h" - -#include - - -/* - * MLD constants - */ -#define MLD6_HL 1 -#define MLD6_TMR_INTERVAL 100 /* Milliseconds */ -#define MLD6_JOIN_DELAYING_MEMBER_TMR_MS 500 /* Milliseconds */ - -#define MLD6_GROUP_NON_MEMBER 0 -#define MLD6_GROUP_DELAYING_MEMBER 1 -#define MLD6_GROUP_IDLE_MEMBER 2 - -/* Forward declarations. */ -static struct mld_group *mld6_new_group(struct netif *ifp, const ip6_addr_t *addr); -static err_t mld6_remove_group(struct netif *netif, struct mld_group *group); -static void mld6_delayed_report(struct mld_group *group, u16_t maxresp); -static void mld6_send(struct netif *netif, struct mld_group *group, u8_t type); - -/* Local variables. */ -static int mld6_tmr_active; - -/** - * Stop MLD processing on interface - * - * @param netif network interface on which stop MLD processing - */ -err_t -mld6_stop(struct netif *netif) -{ - err_t err = ERR_OK; - struct mld_group *group = netif_mld6_data(netif); - - netif_set_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_MLD6, NULL); - - while (group != NULL) { - struct mld_group *next = group->next; /* avoid use-after-free below */ - - /* disable the group at the MAC level */ - if (netif->mld_mac_filter != NULL) { - err_t res = netif->mld_mac_filter(netif, &(group->group_address), NETIF_DEL_MAC_FILTER); - /* If there was an error, don't overwrite it */ - if (res != ERR_OK) { - err = res; - } - } - - /* free group */ - memp_free(MEMP_MLD6_GROUP, group); - - /* move to "next" */ - group = next; - } - return err; -} - -/** - * Report MLD memberships for this interface - * - * @param netif network interface on which report MLD memberships - */ -void -mld6_report_groups(struct netif *netif) -{ - struct mld_group *group = netif_mld6_data(netif); - - while (group != NULL) { - mld6_delayed_report(group, MLD6_JOIN_DELAYING_MEMBER_TMR_MS); - group = group->next; - } -} - -/** - * Search for a group that is joined on a netif - * - * @param ifp the network interface for which to look - * @param addr the group ipv6 address to search for - * @return a struct mld_group* if the group has been found, - * NULL if the group wasn't found. - */ -struct mld_group * -mld6_lookfor_group(struct netif *ifp, const ip6_addr_t *addr) -{ - struct mld_group *group = netif_mld6_data(ifp); - - while (group != NULL) { - if (ip6_addr_cmp(&(group->group_address), addr)) { - return group; - } - group = group->next; - } - - return NULL; -} - -/** - * create a new group - * - * @param ifp the network interface for which to create - * @param addr the new group ipv6 - * @return a struct mld_group*, - * NULL on memory error. - */ -static struct mld_group * -mld6_new_group(struct netif *ifp, const ip6_addr_t *addr) -{ - struct mld_group *group; - - group = (struct mld_group *)memp_malloc(MEMP_MLD6_GROUP); - if (group != NULL) { - ip6_addr_set(&(group->group_address), addr); - group->timer = 0; /* Not running */ - group->group_state = MLD6_GROUP_IDLE_MEMBER; - group->last_reporter_flag = 0; - group->use = 0; - group->next = netif_mld6_data(ifp); - - netif_set_client_data(ifp, LWIP_NETIF_CLIENT_DATA_INDEX_MLD6, group); - } - - return group; -} - -/** - * Remove a group from the mld_group_list, but do not free it yet - * - * @param group the group to remove - * @return ERR_OK if group was removed from the list, an err_t otherwise - */ -static err_t -mld6_remove_group(struct netif *netif, struct mld_group *group) -{ - err_t err = ERR_OK; - - /* Is it the first group? */ - if (netif_mld6_data(netif) == group) { - netif_set_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_MLD6, group->next); - } else { - /* look for group further down the list */ - struct mld_group *tmpGroup; - for (tmpGroup = netif_mld6_data(netif); tmpGroup != NULL; tmpGroup = tmpGroup->next) { - if (tmpGroup->next == group) { - tmpGroup->next = group->next; - break; - } - } - /* Group not find group */ - if (tmpGroup == NULL) { - err = ERR_ARG; - } - } - - return err; -} - - -/** - * Process an input MLD message. Called by icmp6_input. - * - * @param p the mld packet, p->payload pointing to the icmpv6 header - * @param inp the netif on which this packet was received - */ -void -mld6_input(struct pbuf *p, struct netif *inp) -{ - struct mld_header *mld_hdr; - struct mld_group *group; - - MLD6_STATS_INC(mld6.recv); - - /* Check that mld header fits in packet. */ - if (p->len < sizeof(struct mld_header)) { - /* @todo debug message */ - pbuf_free(p); - MLD6_STATS_INC(mld6.lenerr); - MLD6_STATS_INC(mld6.drop); - return; - } - - mld_hdr = (struct mld_header *)p->payload; - - switch (mld_hdr->type) { - case ICMP6_TYPE_MLQ: /* Multicast listener query. */ - /* Is it a general query? */ - if (ip6_addr_isallnodes_linklocal(ip6_current_dest_addr()) && - ip6_addr_isany(&(mld_hdr->multicast_address))) { - MLD6_STATS_INC(mld6.rx_general); - /* Report all groups, except all nodes group, and if-local groups. */ - group = netif_mld6_data(inp); - while (group != NULL) { - if ((!(ip6_addr_ismulticast_iflocal(&(group->group_address)))) && - (!(ip6_addr_isallnodes_linklocal(&(group->group_address))))) { - mld6_delayed_report(group, mld_hdr->max_resp_delay); - } - group = group->next; - } - } else { - /* Have we joined this group? - * We use IP6 destination address to have a memory aligned copy. - * mld_hdr->multicast_address should be the same. */ - MLD6_STATS_INC(mld6.rx_group); - group = mld6_lookfor_group(inp, ip6_current_dest_addr()); - if (group != NULL) { - /* Schedule a report. */ - mld6_delayed_report(group, mld_hdr->max_resp_delay); - } - } - break; /* ICMP6_TYPE_MLQ */ - case ICMP6_TYPE_MLR: /* Multicast listener report. */ - /* Have we joined this group? - * We use IP6 destination address to have a memory aligned copy. - * mld_hdr->multicast_address should be the same. */ - MLD6_STATS_INC(mld6.rx_report); - group = mld6_lookfor_group(inp, ip6_current_dest_addr()); - if (group != NULL) { - /* If we are waiting to report, cancel it. */ - if (group->group_state == MLD6_GROUP_DELAYING_MEMBER) { - group->timer = 0; /* stopped */ - group->group_state = MLD6_GROUP_IDLE_MEMBER; - group->last_reporter_flag = 0; - } - } - break; /* ICMP6_TYPE_MLR */ - case ICMP6_TYPE_MLD: /* Multicast listener done. */ - /* Do nothing, router will query us. */ - break; /* ICMP6_TYPE_MLD */ - default: - MLD6_STATS_INC(mld6.proterr); - MLD6_STATS_INC(mld6.drop); - break; - } - - pbuf_free(p); -} - -/** - * @ingroup mld6 - * Join a group on a network interface. - * - * @param srcaddr ipv6 address of the network interface which should - * join a new group. If IP6_ADDR_ANY, join on all netifs - * @param groupaddr the ipv6 address of the group to join - * @return ERR_OK if group was joined on the netif(s), an err_t otherwise - */ -err_t -mld6_joingroup(const ip6_addr_t *srcaddr, const ip6_addr_t *groupaddr) -{ - err_t err = ERR_VAL; /* no matching interface */ - struct netif *netif; - - /* loop through netif's */ - netif = netif_list; - while (netif != NULL) { - /* Should we join this interface ? */ - if (ip6_addr_isany(srcaddr) || - netif_get_ip6_addr_match(netif, srcaddr) >= 0) { - err = mld6_joingroup_netif(netif, groupaddr); - if (err != ERR_OK) { - return err; - } - } - - /* proceed to next network interface */ - netif = netif->next; - } - - return err; -} - -/** - * @ingroup mld6 - * Join a group on a network interface. - * - * @param netif the network interface which should join a new group. - * @param groupaddr the ipv6 address of the group to join - * @return ERR_OK if group was joined on the netif, an err_t otherwise - */ -err_t -mld6_joingroup_netif(struct netif *netif, const ip6_addr_t *groupaddr) -{ - err_t err = ERR_OK; - struct mld_group *group; - - /* find group or create a new one if not found */ - group = mld6_lookfor_group(netif, groupaddr); - - if (group == NULL) { - /* Joining a new group. Create a new group entry. */ - group = mld6_new_group(netif, groupaddr); - if (group == NULL) { - return ERR_MEM; - } - - /* Activate this address on the MAC layer. */ - if (netif->mld_mac_filter != NULL) { - err_t res = netif->mld_mac_filter(netif, groupaddr, NETIF_ADD_MAC_FILTER); - /* If there was an error, don't overwrite it */ - if (res != ERR_OK) { - err = res; - } - } - - /* Report our membership. */ - MLD6_STATS_INC(mld6.tx_report); - mld6_send(netif, group, ICMP6_TYPE_MLR); - mld6_delayed_report(group, MLD6_JOIN_DELAYING_MEMBER_TMR_MS); - } - - /* Increment group use */ - group->use++; - return err; -} - -/** - * @ingroup mld6 - * Leave a group on a network interface. - * - * @param srcaddr ipv6 address of the network interface which should - * leave the group. If IP6_ISANY, leave on all netifs - * @param groupaddr the ipv6 address of the group to leave - * @return ERR_OK if group was left on the netif(s), an err_t otherwise - */ -err_t -mld6_leavegroup(const ip6_addr_t *srcaddr, const ip6_addr_t *groupaddr) -{ - err_t err = ERR_VAL; /* no matching interface */ - struct netif *netif; - - /* loop through netif's */ - netif = netif_list; - while (netif != NULL) { - /* Should we leave this interface ? */ - if (ip6_addr_isany(srcaddr) || - netif_get_ip6_addr_match(netif, srcaddr) >= 0) { - err_t res = mld6_leavegroup_netif(netif, groupaddr); - if (err != ERR_OK) { - /* Store this result if we have not yet gotten a success */ - err = res; - } - } - /* proceed to next network interface */ - netif = netif->next; - } - - return err; -} - -/** - * @ingroup mld6 - * Leave a group on a network interface. - * - * @param netif the network interface which should leave the group. - * @param groupaddr the ipv6 address of the group to leave - * @return ERR_OK if group was left on the netif, an err_t otherwise - */ -err_t -mld6_leavegroup_netif(struct netif *netif, const ip6_addr_t *groupaddr) -{ - struct mld_group *group; - - /* find group */ - group = mld6_lookfor_group(netif, groupaddr); - - if (group != NULL) { - err_t err = ERR_OK; - - /* Leave if there is no other use of the group */ - if (group->use <= 1) { - /* Remove the group from the list */ - mld6_remove_group(netif, group); - - /* If we are the last reporter for this group */ - if (group->last_reporter_flag) { - MLD6_STATS_INC(mld6.tx_leave); - mld6_send(netif, group, ICMP6_TYPE_MLD); - } - - /* Disable the group at the MAC level */ - if (netif->mld_mac_filter != NULL) { - err_t res = netif->mld_mac_filter(netif, groupaddr, NETIF_DEL_MAC_FILTER); - /* If there was an error, don't overwrite it */ - if (res != ERR_OK) { - err = res; - } - } - - /* free group struct */ - memp_free(MEMP_MLD6_GROUP, group); - } else { - /* Decrement group use */ - group->use--; - } - - /* Left group */ - return err; - } - - /* Group not found */ - return ERR_VAL; -} - - -/** - * Periodic timer for mld processing, scheduled while at least one group has a - * delayed membership report pending. - * - * When a delaying member expires, a membership report is sent. - */ -void -mld6_tmr(void *none) -{ - int again = 0; - struct netif *netif = netif_list; - -#if LWIP_DEBUG_TIMERNAMES - LWIP_DEBUGF(TIMERS_DEBUG, ("tcpip: mld6_tmr()\n")); -#endif - - while (netif != NULL) { - struct mld_group *group = netif_mld6_data(netif); - - while (group != NULL) { - if (group->group_state == MLD6_GROUP_DELAYING_MEMBER) { - LWIP_ASSERT("group->timer > 0", group->timer > 0); - if (--group->timer > 0) { - again = 1; - } else { - MLD6_STATS_INC(mld6.tx_report); - mld6_send(netif, group, ICMP6_TYPE_MLR); - group->group_state = MLD6_GROUP_IDLE_MEMBER; - } - } - group = group->next; - } - netif = netif->next; - } - - if (again) { - sys_timeout(MLD6_TMR_INTERVAL, mld6_tmr, NULL); - } else { - mld6_tmr_active = 0; - } -} - -/** - * Schedule a delayed membership report for a group - * - * @param group the mld_group for which "delaying" membership report - * should be sent - * @param maxresp the max resp delay provided in the query - */ -static void -mld6_delayed_report(struct mld_group *group, u16_t maxresp) -{ - /* Convert maxresp from milliseconds to tmr ticks */ - maxresp = maxresp / MLD6_TMR_INTERVAL; - if (maxresp == 0) { - maxresp = 1; - } - -#ifdef LWIP_RAND - /* Randomize maxresp. (if LWIP_RAND is supported) */ - maxresp = LWIP_RAND() % maxresp; - if (maxresp == 0) { - maxresp = 1; - } -#endif /* LWIP_RAND */ - - /* Apply timer value if no report has been scheduled already. */ - if ((group->group_state == MLD6_GROUP_IDLE_MEMBER) || - ((group->group_state == MLD6_GROUP_DELAYING_MEMBER) && - (group->timer > maxresp))) { - group->group_state = MLD6_GROUP_DELAYING_MEMBER; - group->timer = maxresp; - - if (!mld6_tmr_active) { - mld6_tmr_active = 1; - sys_timeout(MLD6_TMR_INTERVAL, mld6_tmr, NULL); - } - } -} - -/** - * Send a MLD message (report or done). - * - * An IPv6 hop-by-hop options header with a router alert option - * is prepended. - * - * @param group the group to report or quit - * @param type ICMP6_TYPE_MLR (report) or ICMP6_TYPE_MLD (done) - */ -static void -mld6_send(struct netif *netif, struct mld_group *group, u8_t type) -{ - struct mld_header *mld_hdr; - struct pbuf *p; - const ip6_addr_t *src_addr; - - /* Allocate a packet. Size is MLD header + IPv6 Hop-by-hop options header. */ - p = pbuf_alloc(PBUF_IP, sizeof(struct mld_header) + sizeof(struct ip6_hbh_hdr), PBUF_RAM); - if (p == NULL) { - MLD6_STATS_INC(mld6.memerr); - return; - } - - /* Move to make room for Hop-by-hop options header. */ - if (pbuf_header(p, -IP6_HBH_HLEN)) { - pbuf_free(p); - MLD6_STATS_INC(mld6.lenerr); - return; - } - - /* Select our source address. */ - if (!ip6_addr_isvalid(netif_ip6_addr_state(netif, 0))) { - /* This is a special case, when we are performing duplicate address detection. - * We must join the multicast group, but we don't have a valid address yet. */ - src_addr = IP6_ADDR_ANY6; - } else { - /* Use link-local address as source address. */ - src_addr = netif_ip6_addr(netif, 0); - } - - /* MLD message header pointer. */ - mld_hdr = (struct mld_header *)p->payload; - - /* Set fields. */ - mld_hdr->type = type; - mld_hdr->code = 0; - mld_hdr->chksum = 0; - mld_hdr->max_resp_delay = 0; - mld_hdr->reserved = 0; - ip6_addr_set(&(mld_hdr->multicast_address), &(group->group_address)); - -#if CHECKSUM_GEN_ICMP6 - IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_ICMP6) { - mld_hdr->chksum = ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->len, - src_addr, &(group->group_address)); - } -#endif /* CHECKSUM_GEN_ICMP6 */ - - /* Add hop-by-hop headers options: router alert with MLD value. */ - ip6_options_add_hbh_ra(p, IP6_NEXTH_ICMP6, IP6_ROUTER_ALERT_VALUE_MLD); - - if (type == ICMP6_TYPE_MLR) { - /* Remember we were the last to report */ - group->last_reporter_flag = 1; - } - - /* Send the packet out. */ - MLD6_STATS_INC(mld6.xmit); - ip6_output_if(p, (ip6_addr_isany(src_addr)) ? NULL : src_addr, &(group->group_address), - MLD6_HL, 0, IP6_NEXTH_HOPBYHOP, netif); - pbuf_free(p); -} - -#endif /* LWIP_IPV6 && LWIP_IPV6_ND && LWIP_IPV6_MLD */ diff --git a/third_party/lwip/repo/lwip/src/core/ipv6/nd6.c b/third_party/lwip/repo/lwip/src/core/ipv6/nd6.c deleted file mode 100644 index 4e2718544458fd..00000000000000 --- a/third_party/lwip/repo/lwip/src/core/ipv6/nd6.c +++ /dev/null @@ -1,2341 +0,0 @@ -/** - * @file - * - * Neighbor discovery and stateless address autoconfiguration for IPv6. - * Aims to be compliant with RFC 4861 (Neighbor discovery) and RFC 4862 - * (Address autoconfiguration). - */ - -/* - * Copyright (c) 2010 Inico Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Ivan Delamer - * - * - * Please coordinate changes and requests with Ivan Delamer - * - */ - -#include "lwip/opt.h" - -/* don't build if not configured for use in lwipopts.h */ -#if LWIP_IPV6 && LWIP_IPV6_ND - -#include "lwip/nd6.h" -#include "lwip/priv/nd6_priv.h" -#include "lwip/prot/nd6.h" -#include "lwip/prot/icmp6.h" -#include "lwip/pbuf.h" -#include "lwip/mem.h" -#include "lwip/memp.h" -#include "lwip/ip6.h" -#include "lwip/ip6_addr.h" -#include "lwip/inet_chksum.h" -#include "lwip/netif.h" -#include "lwip/icmp6.h" -#include "lwip/mld6.h" -#include "lwip/ip.h" -#include "lwip/stats.h" -#include "lwip/dns.h" - -#include - -#ifdef LWIP_HOOK_FILENAME -#include LWIP_HOOK_FILENAME -#endif - -#if LWIP_IPV6_DUP_DETECT_ATTEMPTS > IP6_ADDR_TENTATIVE_COUNT_MASK -#error LWIP_IPV6_DUP_DETECT_ATTEMPTS > IP6_ADDR_TENTATIVE_COUNT_MASK -#endif - -/* Router tables. */ -struct nd6_neighbor_cache_entry neighbor_cache[LWIP_ND6_NUM_NEIGHBORS]; -struct nd6_destination_cache_entry destination_cache[LWIP_ND6_NUM_DESTINATIONS]; -#if LWIP_ND6_LISTEN_RA -struct nd6_prefix_list_entry prefix_list[LWIP_ND6_NUM_PREFIXES]; -#endif -#if LWIP_IPV6_ROUTER_SUPPORT -struct nd6_router_list_entry default_router_list[LWIP_ND6_NUM_ROUTERS]; -#endif /* LWIP_IPV6_ROUTER_SUPPORT */ - -/* Default values, can be updated by a RA message. */ -u32_t reachable_time = LWIP_ND6_REACHABLE_TIME; -u32_t retrans_timer = LWIP_ND6_RETRANS_TIMER; /* @todo implement this value in timer */ - -/* Index for cache entries. */ -static u8_t nd6_cached_neighbor_index; -static u8_t nd6_cached_destination_index; - -/* Multicast address holder. */ -static ip6_addr_t multicast_address; - -/* Static buffer to parse RA packet options (size of a prefix option, biggest option) */ -#if LWIP_IPV6_ROUTER_SUPPORT && LWIP_ND6_LISTEN_RA -static u8_t nd6_ra_buffer[sizeof(struct prefix_option)]; -#endif - -/* Forward declarations. */ -static s8_t nd6_find_neighbor_cache_entry(const ip6_addr_t *ip6addr); -static s8_t nd6_new_neighbor_cache_entry(void); -static void nd6_free_neighbor_cache_entry(s8_t i); -static s8_t nd6_find_destination_cache_entry(const ip6_addr_t *ip6addr); -static s8_t nd6_new_destination_cache_entry(void); -static s8_t nd6_is_prefix_in_netif(const ip6_addr_t *ip6addr, struct netif *netif); -#if LWIP_IPV6_ROUTER_SUPPORT -static s8_t nd6_select_router(const ip6_addr_t *ip6addr, struct netif *netif); -#endif /* LWIP_IPV6_ROUTER_SUPPORT */ -#if LWIP_ND6_LISTEN_RA -static s8_t nd6_get_router(const ip6_addr_t *router_addr, struct netif *netif); -static s8_t nd6_new_router(const ip6_addr_t *router_addr, struct netif *netif); -static s8_t nd6_get_onlink_prefix(const ip6_addr_t *prefix, struct netif *netif); -static s8_t nd6_new_onlink_prefix(const ip6_addr_t *prefix, struct netif *netif); -#endif /* LWIP_ND6_LISTEN_RA */ -static s8_t nd6_get_next_hop_entry(const ip6_addr_t *ip6addr, struct netif *netif); -static err_t nd6_queue_packet(s8_t neighbor_index, struct pbuf *q); - -#define ND6_SEND_FLAG_MULTICAST_DEST 0x01 -#define ND6_SEND_FLAG_ALLNODES_DEST 0x02 -#define ND6_SEND_FLAG_ANY_SRC 0x04 -static void nd6_send_ns(struct netif *netif, const ip6_addr_t *target_addr, u8_t flags); -static void nd6_send_na(struct netif *netif, const ip6_addr_t *target_addr, u8_t flags); -static void nd6_send_neighbor_cache_probe(struct nd6_neighbor_cache_entry *entry, u8_t flags); -#if LWIP_IPV6_SEND_ROUTER_SOLICIT -static err_t nd6_send_rs(struct netif *netif); -#endif /* LWIP_IPV6_SEND_ROUTER_SOLICIT */ - -#if LWIP_ND6_QUEUEING -static void nd6_free_q(struct nd6_q_entry *q); -#else /* LWIP_ND6_QUEUEING */ -#define nd6_free_q(q) pbuf_free(q) -#endif /* LWIP_ND6_QUEUEING */ -static void nd6_send_q(s8_t i); - - -/** - * A local address has been determined to be a duplicate. Take the appropriate - * action(s) on the address and the interface as a whole. - * - * @param netif the netif that owns the address - * @param addr_idx the index of the address detected to be a duplicate - */ -static void -nd6_duplicate_addr_detected(struct netif *netif, s8_t addr_idx) -{ - - /* Mark the address as duplicate, but leave its lifetimes alone. If this was - * a manually assigned address, it will remain in existence as duplicate, and - * as such be unusable for any practical purposes until manual intervention. - * If this was an autogenerated address, the address will follow normal - * expiration rules, and thus disappear once its valid lifetime expires. */ - netif_ip6_addr_set_state(netif, addr_idx, IP6_ADDR_DUPLICATED); - -#if LWIP_IPV6_AUTOCONFIG - /* If the affected address was the link-local address that we use to generate - * all other addresses, then we should not continue to use those derived - * addresses either, so mark them as duplicate as well. For autoconfig-only - * setups, this will make the interface effectively unusable, approaching the - * intention of RFC 4862 Sec. 5.4.5. @todo implement the full requirements */ - if (addr_idx == 0) { - s8_t i; - for (i = 1; i < LWIP_IPV6_NUM_ADDRESSES; i++) { - if (!ip6_addr_isinvalid(netif_ip6_addr_state(netif, i)) && - !netif_ip6_addr_isstatic(netif, i)) { - netif_ip6_addr_set_state(netif, i, IP6_ADDR_DUPLICATED); - } - } - } -#endif /* LWIP_IPV6_AUTOCONFIG */ -} - -#if LWIP_IPV6_AUTOCONFIG -/** - * We received a router advertisement that contains a prefix with the - * autoconfiguration flag set. Add or update an associated autogenerated - * address. - * - * @param netif the netif on which the router advertisement arrived - * @param prefix_opt a pointer to the prefix option data - * @param prefix_addr an aligned copy of the prefix address - */ -static void -nd6_process_autoconfig_prefix(struct netif *netif, - struct prefix_option *prefix_opt, const ip6_addr_t *prefix_addr) -{ - ip6_addr_t ip6addr; - u32_t valid_life, pref_life; - u8_t addr_state; - s8_t i, free_idx; - - /* The caller already checks RFC 4862 Sec. 5.5.3 points (a) and (b). We do - * the rest, starting with checks for (c) and (d) here. */ - valid_life = lwip_htonl(prefix_opt->valid_lifetime); - pref_life = lwip_htonl(prefix_opt->preferred_lifetime); - if (pref_life > valid_life || prefix_opt->prefix_length != 64) { - return; /* silently ignore this prefix for autoconfiguration purposes */ - } - - /* If an autogenerated address already exists for this prefix, update its - * lifetimes. An address is considered autogenerated if 1) it is not static - * (i.e., manually assigned), and 2) there is an advertised autoconfiguration - * prefix for it (the one we are processing here). This does not necessarily - * exclude the possibility that the address was actually assigned by, say, - * DHCPv6. If that distinction becomes important in the future, more state - * must be kept. As explained elsewhere we also update lifetimes of tentative - * and duplicate addresses. Skip address slot 0 (the link-local address). */ - for (i = 1; i < LWIP_IPV6_NUM_ADDRESSES; i++) { - addr_state = netif_ip6_addr_state(netif, i); - if (!ip6_addr_isinvalid(addr_state) && !netif_ip6_addr_isstatic(netif, i) && - ip6_addr_netcmp(prefix_addr, netif_ip6_addr(netif, i))) { - /* Update the valid lifetime, as per RFC 4862 Sec. 5.5.3 point (e). - * The valid lifetime will never drop to zero as a result of this. */ - u32_t remaining_life = netif_ip6_addr_valid_life(netif, i); - if (valid_life > ND6_2HRS || valid_life > remaining_life) { - netif_ip6_addr_set_valid_life(netif, i, valid_life); - } else if (remaining_life > ND6_2HRS) { - netif_ip6_addr_set_valid_life(netif, i, ND6_2HRS); - } - LWIP_ASSERT("bad valid lifetime", !netif_ip6_addr_isstatic(netif, i)); - /* Update the preferred lifetime. No bounds checks are needed here. In - * rare cases the advertisement may un-deprecate the address, though. - * Deprecation is left to the timer code where it is handled anyway. */ - if (pref_life > 0 && addr_state == IP6_ADDR_DEPRECATED) { - netif_ip6_addr_set_state(netif, i, IP6_ADDR_PREFERRED); - } - netif_ip6_addr_set_pref_life(netif, i, pref_life); - return; /* there should be at most one matching address */ - } - } - - /* No autogenerated address exists for this prefix yet. See if we can add a - * new one. However, if IPv6 autoconfiguration is administratively disabled, - * do not generate new addresses, but do keep updating lifetimes for existing - * addresses. Also, when adding new addresses, we must protect explicitly - * against a valid lifetime of zero, because again, we use that as a special - * value. The generated address would otherwise expire immediately anyway. - * Finally, the original link-local address must be usable at all. We start - * creating addresses even if the link-local address is still in tentative - * state though, and deal with the fallout of that upon DAD collision. */ - addr_state = netif_ip6_addr_state(netif, 0); - if (!netif->ip6_autoconfig_enabled || valid_life == IP6_ADDR_LIFE_STATIC || - ip6_addr_isinvalid(addr_state) || ip6_addr_isduplicated(addr_state)) { - return; - } - - /* Construct the new address that we intend to use, and then see if that - * address really does not exist. It might have been added manually, after - * all. As a side effect, find a free slot. Note that we cannot use - * netif_add_ip6_address() here, as it would return ERR_OK if the address - * already did exist, resulting in that address being given lifetimes. */ - IP6_ADDR(&ip6addr, prefix_addr->addr[0], prefix_addr->addr[1], - netif_ip6_addr(netif, 0)->addr[2], netif_ip6_addr(netif, 0)->addr[3]); - - free_idx = 0; - for (i = 1; i < LWIP_IPV6_NUM_ADDRESSES; i++) { - if (!ip6_addr_isinvalid(netif_ip6_addr_state(netif, i))) { - if (ip6_addr_cmp(&ip6addr, netif_ip6_addr(netif, i))) { - return; /* formed address already exists */ - } - } else if (free_idx == 0) { - free_idx = i; - } - } - if (free_idx == 0) { - return; /* no address slots available, try again on next advertisement */ - } - - /* Assign the new address to the interface. */ - ip_addr_copy_from_ip6(netif->ip6_addr[free_idx], ip6addr); - netif_ip6_addr_set_valid_life(netif, free_idx, valid_life); - netif_ip6_addr_set_pref_life(netif, free_idx, pref_life); - netif_ip6_addr_set_state(netif, free_idx, IP6_ADDR_TENTATIVE); -} -#endif /* LWIP_IPV6_AUTOCONFIG */ - -/** - * Process an incoming neighbor discovery message - * - * @param p the nd packet, p->payload pointing to the icmpv6 header - * @param inp the netif on which this packet was received - */ -void -nd6_input(struct pbuf *p, struct netif *inp) -{ - u8_t msg_type; - s8_t i; - - ND6_STATS_INC(nd6.recv); - - msg_type = *((u8_t *)p->payload); - switch (msg_type) { - case ICMP6_TYPE_NA: /* Neighbor Advertisement. */ - { - struct na_header *na_hdr; - struct lladdr_option *lladdr_opt; - - /* Check that na header fits in packet. */ - if (p->len < (sizeof(struct na_header))) { - /* @todo debug message */ - pbuf_free(p); - ND6_STATS_INC(nd6.lenerr); - ND6_STATS_INC(nd6.drop); - return; - } - - na_hdr = (struct na_header *)p->payload; - - /* Unsolicited NA?*/ - if (ip6_addr_ismulticast(ip6_current_dest_addr())) { - ip6_addr_t target_address; - - /* This is an unsolicited NA. - * link-layer changed? - * part of DAD mechanism? */ - - /* Check that link-layer address option also fits in packet. */ - if (p->len < (sizeof(struct na_header) + ND6_LLADDR_OPTION_SIZE(inp->hwaddr_len))) { - /* TODO debug message */ - pbuf_free(p); - ND6_STATS_INC(nd6.lenerr); - ND6_STATS_INC(nd6.drop); - return; - } - - lladdr_opt = (struct lladdr_option *)((u8_t*)p->payload + sizeof(struct na_header)); - - /* Override ip6_current_dest_addr() so that we have an aligned copy. */ - ip6_addr_set(ip6_current_dest_addr(), &(na_hdr->target_address)); - -#if LWIP_IPV6_DUP_DETECT_ATTEMPTS - /* If the target address matches this netif, it is a DAD response. */ - for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { - if (!ip6_addr_isinvalid(netif_ip6_addr_state(inp, i)) && - !ip6_addr_isduplicated(netif_ip6_addr_state(inp, i)) && - ip6_addr_cmp(&target_address, netif_ip6_addr(inp, i))) { - /* We are using a duplicate address. */ - nd6_duplicate_addr_detected(inp, i); - - pbuf_free(p); - return; - } - } -#endif /* LWIP_IPV6_DUP_DETECT_ATTEMPTS */ - - /* Check that link-layer address option also fits in packet. */ - if (p->len < (sizeof(struct na_header) + 2)) { - /* @todo debug message */ - pbuf_free(p); - ND6_STATS_INC(nd6.lenerr); - ND6_STATS_INC(nd6.drop); - return; - } - - lladdr_opt = (struct lladdr_option *)((u8_t*)p->payload + sizeof(struct na_header)); - - if (p->len < (sizeof(struct na_header) + (lladdr_opt->length << 3))) { - /* @todo debug message */ - pbuf_free(p); - ND6_STATS_INC(nd6.lenerr); - ND6_STATS_INC(nd6.drop); - return; - } - - /* This is an unsolicited NA, most likely there was a LLADDR change. */ - i = nd6_find_neighbor_cache_entry(&target_address); - if (i >= 0) { - if (na_hdr->flags & ND6_FLAG_OVERRIDE) { - MEMCPY(neighbor_cache[i].lladdr, lladdr_opt->addr, inp->hwaddr_len); - } - } - } else { - ip6_addr_t target_address; - - /* This is a solicited NA. - * neighbor address resolution response? - * neighbor unreachability detection response? */ - - /* Create an aligned copy. */ - ip6_addr_set(&target_address, &(na_hdr->target_address)); - - /* Find the cache entry corresponding to this na. */ - i = nd6_find_neighbor_cache_entry(&target_address); - if (i < 0) { - /* We no longer care about this target address. drop it. */ - pbuf_free(p); - return; - } - - /* Update cache entry. */ - if ((na_hdr->flags & ND6_FLAG_OVERRIDE) || - (neighbor_cache[i].state == ND6_INCOMPLETE)) { - /* Check that link-layer address option also fits in packet. */ - if (p->len < (sizeof(struct na_header) + ND6_LLADDR_OPTION_SIZE(inp->hwaddr_len))) { - /* @todo debug message */ - pbuf_free(p); - ND6_STATS_INC(nd6.lenerr); - ND6_STATS_INC(nd6.drop); - return; - } - - lladdr_opt = (struct lladdr_option *)((u8_t*)p->payload + sizeof(struct na_header)); - - if (p->len < (sizeof(struct na_header) + (lladdr_opt->length << 3))) { - /* @todo debug message */ - pbuf_free(p); - ND6_STATS_INC(nd6.lenerr); - ND6_STATS_INC(nd6.drop); - return; - } - - MEMCPY(neighbor_cache[i].lladdr, lladdr_opt->addr, inp->hwaddr_len); - } - - neighbor_cache[i].netif = inp; - neighbor_cache[i].state = ND6_REACHABLE; - neighbor_cache[i].counter.reachable_time = reachable_time; - - /* Send queued packets, if any. */ - if (neighbor_cache[i].q != NULL) { - nd6_send_q(i); - } - } - - break; /* ICMP6_TYPE_NA */ - } - case ICMP6_TYPE_NS: /* Neighbor solicitation. */ - { - struct ns_header *ns_hdr; - struct lladdr_option *lladdr_opt; - u8_t accepted; - - /* Check that ns header fits in packet. */ - if (p->len < sizeof(struct ns_header)) { - /* @todo debug message */ - pbuf_free(p); - ND6_STATS_INC(nd6.lenerr); - ND6_STATS_INC(nd6.drop); - return; - } - - ns_hdr = (struct ns_header *)p->payload; - - /* Check if there is a link-layer address provided. Only point to it if in this buffer. */ - lladdr_opt = NULL; - if (p->len >= (sizeof(struct ns_header) + ND6_LLADDR_OPTION_SIZE(inp->hwaddr_len))) { - lladdr_opt = (struct lladdr_option *)((u8_t*)p->payload + sizeof(struct ns_header)); - if (p->len < (sizeof(struct ns_header) + (lladdr_opt->length << 3))) { - lladdr_opt = NULL; - } - } else { - lladdr_opt = NULL; - } - - /* Check if the target address is configured on the receiving netif. */ - accepted = 0; - for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; ++i) { - if ((ip6_addr_isvalid(netif_ip6_addr_state(inp, i)) || - (ip6_addr_istentative(netif_ip6_addr_state(inp, i)) && - ip6_addr_isany(ip6_current_src_addr()))) && - ip6_addr_cmp(&(ns_hdr->target_address), netif_ip6_addr(inp, i))) { - accepted = 1; - break; - } - } - - /* NS not for us? */ - if (!accepted) { - pbuf_free(p); - return; - } - - /* Check for ANY address in src (DAD algorithm). */ - if (ip6_addr_isany(ip6_current_src_addr())) { - /* Sender is validating this address. */ - for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; ++i) { - if (!ip6_addr_isinvalid(netif_ip6_addr_state(inp, i)) && - ip6_addr_cmp(&(ns_hdr->target_address), netif_ip6_addr(inp, i))) { - /* Send a NA back so that the sender does not use this address. */ - nd6_send_na(inp, netif_ip6_addr(inp, i), ND6_FLAG_OVERRIDE | ND6_SEND_FLAG_ALLNODES_DEST); - if (ip6_addr_istentative(netif_ip6_addr_state(inp, i))) { - /* We shouldn't use this address either. */ - nd6_duplicate_addr_detected(inp, i); - } - } - } - } else { - ip6_addr_t target_address; - - /* Sender is trying to resolve our address. */ - /* Verify that they included their own link-layer address. */ - if (lladdr_opt == NULL) { - /* Not a valid message. */ - pbuf_free(p); - ND6_STATS_INC(nd6.proterr); - ND6_STATS_INC(nd6.drop); - return; - } - - i = nd6_find_neighbor_cache_entry(ip6_current_src_addr()); - if (i>= 0) { - /* We already have a record for the solicitor. */ - if (neighbor_cache[i].state == ND6_INCOMPLETE) { - neighbor_cache[i].netif = inp; - MEMCPY(neighbor_cache[i].lladdr, lladdr_opt->addr, inp->hwaddr_len); - - /* Delay probe in case we get confirmation of reachability from upper layer (TCP). */ - neighbor_cache[i].state = ND6_DELAY; - neighbor_cache[i].counter.delay_time = LWIP_ND6_DELAY_FIRST_PROBE_TIME / ND6_TMR_INTERVAL; - } - } else { - /* Add their IPv6 address and link-layer address to neighbor cache. - * We will need it at least to send a unicast NA message, but most - * likely we will also be communicating with this node soon. */ - i = nd6_new_neighbor_cache_entry(); - if (i < 0) { - /* We couldn't assign a cache entry for this neighbor. - * we won't be able to reply. drop it. */ - pbuf_free(p); - ND6_STATS_INC(nd6.memerr); - return; - } - neighbor_cache[i].netif = inp; - MEMCPY(neighbor_cache[i].lladdr, lladdr_opt->addr, inp->hwaddr_len); - ip6_addr_set(&(neighbor_cache[i].next_hop_address), ip6_current_src_addr()); - - /* Receiving a message does not prove reachability: only in one direction. - * Delay probe in case we get confirmation of reachability from upper layer (TCP). */ - neighbor_cache[i].state = ND6_DELAY; - neighbor_cache[i].counter.delay_time = LWIP_ND6_DELAY_FIRST_PROBE_TIME / ND6_TMR_INTERVAL; - } - - /* Create an aligned copy. */ - ip6_addr_set(&target_address, &(ns_hdr->target_address)); - - /* Send back a NA for us. Allocate the reply pbuf. */ - nd6_send_na(inp, &target_address, ND6_FLAG_SOLICITED | ND6_FLAG_OVERRIDE); - } - - break; /* ICMP6_TYPE_NS */ - } -#if LWIP_IPV6_ROUTER_SUPPORT && LWIP_ND6_LISTEN_RA - case ICMP6_TYPE_RA: /* Router Advertisement. */ - { - struct ra_header *ra_hdr; - u8_t *buffer; /* Used to copy options. */ - u16_t offset; -#if LWIP_ND6_RDNSS_MAX_DNS_SERVERS - /* There can by multiple RDNSS options per RA */ - u8_t rdnss_server_idx = 0; -#endif /* LWIP_ND6_RDNSS_MAX_DNS_SERVERS */ - - /* Check that RA header fits in packet. */ - if (p->len < sizeof(struct ra_header)) { - /* @todo debug message */ - pbuf_free(p); - ND6_STATS_INC(nd6.lenerr); - ND6_STATS_INC(nd6.drop); - return; - } - - ra_hdr = (struct ra_header *)p->payload; - - /* If we are sending RS messages, stop. */ -#if LWIP_IPV6_SEND_ROUTER_SOLICIT - /* ensure at least one solicitation is sent */ - if ((inp->rs_count < LWIP_ND6_MAX_MULTICAST_SOLICIT) || - (nd6_send_rs(inp) == ERR_OK)) { - inp->rs_count = 0; - } -#endif /* LWIP_IPV6_SEND_ROUTER_SOLICIT */ - - /* Get the matching default router entry. */ - i = nd6_get_router(ip6_current_src_addr(), inp); - if (i < 0) { - /* Create a new router entry. */ - i = nd6_new_router(ip6_current_src_addr(), inp); - } - - if (i < 0) { - /* Could not create a new router entry. */ - pbuf_free(p); - ND6_STATS_INC(nd6.memerr); - return; - } - - /* Re-set invalidation timer. */ - default_router_list[i].invalidation_timer = lwip_htons(ra_hdr->router_lifetime); - - /* Re-set default timer values. */ -#if LWIP_ND6_ALLOW_RA_UPDATES - if (ra_hdr->retrans_timer > 0) { - retrans_timer = lwip_htonl(ra_hdr->retrans_timer); - } - if (ra_hdr->reachable_time > 0) { - reachable_time = lwip_htonl(ra_hdr->reachable_time); - } -#endif /* LWIP_ND6_ALLOW_RA_UPDATES */ - - /* @todo set default hop limit... */ - /* ra_hdr->current_hop_limit;*/ - - /* Update flags in local entry (incl. preference). */ - default_router_list[i].flags = ra_hdr->flags; - - /* Offset to options. */ - offset = sizeof(struct ra_header); - - /* Process each option. */ - while ((p->tot_len - offset) > 0) { - if (p->len == p->tot_len) { - /* no need to copy from contiguous pbuf */ - buffer = &((u8_t*)p->payload)[offset]; - } else { - buffer = nd6_ra_buffer; - if (pbuf_copy_partial(p, buffer, sizeof(struct prefix_option), offset) != sizeof(struct prefix_option)) { - pbuf_free(p); - ND6_STATS_INC(nd6.lenerr); - ND6_STATS_INC(nd6.drop); - return; - } - } - if (buffer[1] == 0) { - /* zero-length extension. drop packet */ - pbuf_free(p); - ND6_STATS_INC(nd6.lenerr); - ND6_STATS_INC(nd6.drop); - return; - } - switch (buffer[0]) { - case ND6_OPTION_TYPE_SOURCE_LLADDR: - { - struct lladdr_option *lladdr_opt; - lladdr_opt = (struct lladdr_option *)buffer; - if ((default_router_list[i].neighbor_entry != NULL) && - (default_router_list[i].neighbor_entry->state == ND6_INCOMPLETE)) { - SMEMCPY(default_router_list[i].neighbor_entry->lladdr, lladdr_opt->addr, inp->hwaddr_len); - default_router_list[i].neighbor_entry->state = ND6_REACHABLE; - default_router_list[i].neighbor_entry->counter.reachable_time = reachable_time; - } - break; - } - case ND6_OPTION_TYPE_MTU: - { - struct mtu_option *mtu_opt; - mtu_opt = (struct mtu_option *)buffer; - if (lwip_htonl(mtu_opt->mtu) >= IP6_MIN_MTU) { -#if LWIP_ND6_ALLOW_RA_UPDATES - inp->mtu = (u16_t)lwip_htonl(mtu_opt->mtu); -#endif /* LWIP_ND6_ALLOW_RA_UPDATES */ - } - break; - } - case ND6_OPTION_TYPE_PREFIX_INFO: - { - struct prefix_option *prefix_opt; - ip6_addr_t prefix_addr; - - prefix_opt = (struct prefix_option *)buffer; - - /* Get a memory-aligned copy of the prefix. */ - ip6_addr_set(&prefix_addr, &(prefix_opt->prefix)); - - if (!ip6_addr_islinklocal(&prefix_addr)) { - if ((prefix_opt->flags & ND6_PREFIX_FLAG_ON_LINK) && - (prefix_opt->prefix_length == 64)) { - /* Add to on-link prefix list. */ - u32_t valid_life; - s8_t prefix; - - valid_life = lwip_htonl(prefix_opt->valid_lifetime); - - /* find cache entry for this prefix. */ - prefix = nd6_get_onlink_prefix(&prefix_addr, inp); - if (prefix < 0 && valid_life > 0) { - /* Create a new cache entry. */ - prefix = nd6_new_onlink_prefix(&prefix_addr, inp); - } - if (prefix >= 0) { - prefix_list[prefix].invalidation_timer = valid_life; - } - } -#if LWIP_IPV6_AUTOCONFIG - if (prefix_opt->flags & ND6_PREFIX_FLAG_AUTONOMOUS) { - /* Perform processing for autoconfiguration. */ - nd6_process_autoconfig_prefix(inp, prefix_opt, &prefix_addr); - } -#endif /* LWIP_IPV6_AUTOCONFIG */ - } - - break; - } - case ND6_OPTION_TYPE_ROUTE_INFO: - /* @todo implement preferred routes. - struct route_option * route_opt; - route_opt = (struct route_option *)buffer;*/ - - break; -#if LWIP_ND6_RDNSS_MAX_DNS_SERVERS - case ND6_OPTION_TYPE_RDNSS: - { - u8_t num, n; - struct rdnss_option * rdnss_opt; - - rdnss_opt = (struct rdnss_option *)buffer; - num = (rdnss_opt->length - 1) / 2; - for (n = 0; (rdnss_server_idx < DNS_MAX_SERVERS) && (n < num); n++) { - ip_addr_t rdnss_address; - - /* Get a memory-aligned copy of the prefix. */ - ip_addr_copy_from_ip6(rdnss_address, rdnss_opt->rdnss_address[n]); - - if (htonl(rdnss_opt->lifetime) > 0) { - /* TODO implement Lifetime > 0 */ - dns_setserver(rdnss_server_idx++, &rdnss_address); - } else { - /* TODO implement DNS removal in dns.c */ - u8_t s; - for (s = 0; s < DNS_MAX_SERVERS; s++) { - const ip_addr_t *addr = dns_getserver(s); - if(ip_addr_cmp(addr, &rdnss_address)) { - dns_setserver(s, NULL); - } - } - } - } - break; - } -#endif /* LWIP_ND6_RDNSS_MAX_DNS_SERVERS */ - default: - /* Unrecognized option, abort. */ - ND6_STATS_INC(nd6.proterr); - break; - } - /* option length is checked earlier to be non-zero to make sure loop ends */ - offset += 8 * ((u16_t)buffer[1]); - } - - break; /* ICMP6_TYPE_RA */ - } -#endif /* LWIP_IPV6_ROUTER_SUPPORT && LWIP_ND6_LISTEN_RA */ - case ICMP6_TYPE_RD: /* Redirect */ - { - struct redirect_header *redir_hdr; - struct lladdr_option *lladdr_opt; - ip6_addr_t tmp; - - /* Check that Redir header fits in packet. */ - if (p->len < sizeof(struct redirect_header)) { - /* @todo debug message */ - pbuf_free(p); - ND6_STATS_INC(nd6.lenerr); - ND6_STATS_INC(nd6.drop); - return; - } - - redir_hdr = (struct redirect_header *)p->payload; - - lladdr_opt = NULL; - if (p->len >= (sizeof(struct redirect_header) + ND6_LLADDR_OPTION_SIZE(inp->hwaddr_len))) { - lladdr_opt = (struct lladdr_option *)((u8_t*)p->payload + sizeof(struct redirect_header)); - if (p->len < (sizeof(struct redirect_header) + (lladdr_opt->length << 3))) { - lladdr_opt = NULL; - } - } else { - lladdr_opt = NULL; - } - - /* Copy original destination address to current source address, to have an aligned copy. */ - ip6_addr_set(&tmp, &(redir_hdr->destination_address)); - - /* Find dest address in cache */ - i = nd6_find_destination_cache_entry(&tmp); - if (i < 0) { - /* Destination not in cache, drop packet. */ - pbuf_free(p); - return; - } - - /* Set the new target address. */ - ip6_addr_set(&(destination_cache[i].next_hop_addr), &(redir_hdr->target_address)); - - /* If Link-layer address of other router is given, try to add to neighbor cache. */ - if (lladdr_opt != NULL) { - if (lladdr_opt->type == ND6_OPTION_TYPE_TARGET_LLADDR) { - /* Copy target address to current source address, to have an aligned copy. */ - ip6_addr_set(&tmp, &(redir_hdr->target_address)); - - i = nd6_find_neighbor_cache_entry(&tmp); - if (i < 0) { - i = nd6_new_neighbor_cache_entry(); - if (i >= 0) { - neighbor_cache[i].netif = inp; - MEMCPY(neighbor_cache[i].lladdr, lladdr_opt->addr, inp->hwaddr_len); - ip6_addr_set(&(neighbor_cache[i].next_hop_address), &tmp); - - /* Receiving a message does not prove reachability: only in one direction. - * Delay probe in case we get confirmation of reachability from upper layer (TCP). */ - neighbor_cache[i].state = ND6_DELAY; - neighbor_cache[i].counter.delay_time = LWIP_ND6_DELAY_FIRST_PROBE_TIME / ND6_TMR_INTERVAL; - } - } - if (i >= 0) { - if (neighbor_cache[i].state == ND6_INCOMPLETE) { - MEMCPY(neighbor_cache[i].lladdr, lladdr_opt->addr, inp->hwaddr_len); - /* Receiving a message does not prove reachability: only in one direction. - * Delay probe in case we get confirmation of reachability from upper layer (TCP). */ - neighbor_cache[i].state = ND6_DELAY; - neighbor_cache[i].counter.delay_time = LWIP_ND6_DELAY_FIRST_PROBE_TIME / ND6_TMR_INTERVAL; - } - } - } - } - break; /* ICMP6_TYPE_RD */ - } - case ICMP6_TYPE_PTB: /* Packet too big */ - { - struct icmp6_hdr *icmp6hdr; /* Packet too big message */ - struct ip6_hdr *ip6hdr; /* IPv6 header of the packet which caused the error */ - u32_t pmtu; - ip6_addr_t tmp; - - /* Check that ICMPv6 header + IPv6 header fit in payload */ - if (p->len < (sizeof(struct icmp6_hdr) + IP6_HLEN)) { - /* drop short packets */ - pbuf_free(p); - ND6_STATS_INC(nd6.lenerr); - ND6_STATS_INC(nd6.drop); - return; - } - - icmp6hdr = (struct icmp6_hdr *)p->payload; - ip6hdr = (struct ip6_hdr *)((u8_t*)p->payload + sizeof(struct icmp6_hdr)); - - /* Copy original destination address to current source address, to have an aligned copy. */ - ip6_addr_set(&tmp, &(ip6hdr->dest)); - - /* Look for entry in destination cache. */ - i = nd6_find_destination_cache_entry(&tmp); - if (i < 0) { - /* Destination not in cache, drop packet. */ - pbuf_free(p); - return; - } - - /* Change the Path MTU. */ - pmtu = lwip_htonl(icmp6hdr->data); - destination_cache[i].pmtu = (u16_t)LWIP_MIN(pmtu, 0xFFFF); - - break; /* ICMP6_TYPE_PTB */ - } - - default: - ND6_STATS_INC(nd6.proterr); - ND6_STATS_INC(nd6.drop); - break; /* default */ - } - - pbuf_free(p); -} - - -/** - * Periodic timer for Neighbor discovery functions: - * - * - Update neighbor reachability states - * - Update destination cache entries age - * - Update invalidation timers of default routers and on-link prefixes - * - Update lifetimes of our addresses - * - Perform duplicate address detection (DAD) for our addresses - * - Send router solicitations - */ -void -nd6_tmr(void) -{ - s8_t i; - struct netif *netif; - - /* Process neighbor entries. */ - for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) { - switch (neighbor_cache[i].state) { - case ND6_INCOMPLETE: - if ((neighbor_cache[i].counter.probes_sent >= LWIP_ND6_MAX_MULTICAST_SOLICIT) && - (!neighbor_cache[i].isrouter)) { - /* Retries exceeded. */ - nd6_free_neighbor_cache_entry(i); - } else { - /* Send a NS for this entry. */ - neighbor_cache[i].counter.probes_sent++; - nd6_send_neighbor_cache_probe(&neighbor_cache[i], ND6_SEND_FLAG_MULTICAST_DEST); - } - break; - case ND6_REACHABLE: - /* Send queued packets, if any are left. Should have been sent already. */ - if (neighbor_cache[i].q != NULL) { - nd6_send_q(i); - } - if (neighbor_cache[i].counter.reachable_time <= ND6_TMR_INTERVAL) { - /* Change to stale state. */ - neighbor_cache[i].state = ND6_STALE; - neighbor_cache[i].counter.stale_time = 0; - } else { - neighbor_cache[i].counter.reachable_time -= ND6_TMR_INTERVAL; - } - break; - case ND6_STALE: - neighbor_cache[i].counter.stale_time++; - break; - case ND6_DELAY: - if (neighbor_cache[i].counter.delay_time <= 1) { - /* Change to PROBE state. */ - neighbor_cache[i].state = ND6_PROBE; - neighbor_cache[i].counter.probes_sent = 0; - } else { - neighbor_cache[i].counter.delay_time--; - } - break; - case ND6_PROBE: - if ((neighbor_cache[i].counter.probes_sent >= LWIP_ND6_MAX_MULTICAST_SOLICIT) && - (!neighbor_cache[i].isrouter)) { - /* Retries exceeded. */ - nd6_free_neighbor_cache_entry(i); - } else { - /* Send a NS for this entry. */ - neighbor_cache[i].counter.probes_sent++; - nd6_send_neighbor_cache_probe(&neighbor_cache[i], 0); - } - break; - case ND6_NO_ENTRY: - default: - /* Do nothing. */ - break; - } - } - - /* Process destination entries. */ - for (i = 0; i < LWIP_ND6_NUM_DESTINATIONS; i++) { - destination_cache[i].age++; - } - -#if LWIP_IPV6_ROUTER_SUPPORT - - /* Process router entries. */ - for (i = 0; i < LWIP_ND6_NUM_ROUTERS; i++) { - if (default_router_list[i].neighbor_entry != NULL) { - /* Active entry. */ - if (default_router_list[i].invalidation_timer > 0) { - default_router_list[i].invalidation_timer -= ND6_TMR_INTERVAL / 1000; - } - if (default_router_list[i].invalidation_timer < ND6_TMR_INTERVAL / 1000) { - /* Less than 1 second remaining. Clear this entry. */ - default_router_list[i].neighbor_entry->isrouter = 0; - default_router_list[i].neighbor_entry = NULL; - default_router_list[i].invalidation_timer = 0; - default_router_list[i].flags = 0; - } - } - } - -#endif /* LWIP_IPV6_ROUTER_SUPPORT */ - -#if LWIP_ND6_LISTEN_RA - - /* Process prefix entries. */ - for (i = 0; i < LWIP_ND6_NUM_PREFIXES; i++) { - if (prefix_list[i].netif != NULL) { - if (prefix_list[i].invalidation_timer <= ND6_TMR_INTERVAL / 1000) { - /* Entry timed out, remove it */ - prefix_list[i].invalidation_timer = 0; - prefix_list[i].netif = NULL; - } else { - prefix_list[i].invalidation_timer -= ND6_TMR_INTERVAL / 1000; - } - } - } - -#endif /* LWIP_ND6_LISTEN_RA */ - - /* Process our own addresses, updating address lifetimes and/or DAD state. */ - for (netif = netif_list; netif != NULL; netif = netif->next) { - for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; ++i) { - u8_t addr_state; -#if LWIP_IPV6_ADDRESS_LIFETIMES - /* Step 1: update address lifetimes (valid and preferred). */ - addr_state = netif_ip6_addr_state(netif, i); - /* RFC 4862 is not entirely clear as to whether address lifetimes affect - * tentative addresses, and is even less clear as to what should happen - * with duplicate addresses. We choose to track and update lifetimes for - * both those types, although for different reasons: - * - for tentative addresses, the line of thought of Sec. 5.7 combined - * with the potentially long period that an address may be in tentative - * state (due to the interface being down) suggests that lifetimes - * should be independent of external factors which would include DAD; - * - for duplicate addresses, retiring them early could result in a new - * but unwanted attempt at marking them as valid, while retiring them - * late/never could clog up address slots on the netif. - * As a result, we may end up expiring addresses of either type here. - */ - if (!ip6_addr_isinvalid(addr_state) && - !netif_ip6_addr_isstatic(netif, i)) { - u32_t life = netif_ip6_addr_valid_life(netif, i); - if (life <= ND6_TMR_INTERVAL / 1000) { - /* The address has expired. */ - netif_ip6_addr_set_valid_life(netif, i, 0); - netif_ip6_addr_set_pref_life(netif, i, 0); - netif_ip6_addr_set_state(netif, i, IP6_ADDR_INVALID); - } else { - if (!ip6_addr_life_isinfinite(life)) { - life -= ND6_TMR_INTERVAL / 1000; - LWIP_ASSERT("bad valid lifetime", life != IP6_ADDR_LIFE_STATIC); - netif_ip6_addr_set_valid_life(netif, i, life); - } - /* The address is still here. Update the preferred lifetime too. */ - life = netif_ip6_addr_pref_life(netif, i); - if (life <= ND6_TMR_INTERVAL / 1000) { - /* This case must also trigger if 'life' was already zero, so as to - * deal correctly with advertised preferred-lifetime reductions. */ - netif_ip6_addr_set_pref_life(netif, i, 0); - if (addr_state == IP6_ADDR_PREFERRED) - netif_ip6_addr_set_state(netif, i, IP6_ADDR_DEPRECATED); - } else if (!ip6_addr_life_isinfinite(life)) { - life -= ND6_TMR_INTERVAL / 1000; - netif_ip6_addr_set_pref_life(netif, i, life); - } - } - } - /* The address state may now have changed, so reobtain it next. */ -#endif /* LWIP_IPV6_ADDRESS_LIFETIMES */ - /* Step 2: update DAD state. */ - addr_state = netif_ip6_addr_state(netif, i); - if (ip6_addr_istentative(addr_state)) { - if ((addr_state & IP6_ADDR_TENTATIVE_COUNT_MASK) >= LWIP_IPV6_DUP_DETECT_ATTEMPTS) { - /* No NA received in response. Mark address as valid. For dynamic - * addresses with an expired preferred lifetime, the state is set to - * deprecated right away. That should almost never happen, though. */ - addr_state = IP6_ADDR_PREFERRED; -#if LWIP_IPV6_ADDRESS_LIFETIMES - if (!netif_ip6_addr_isstatic(netif, i) && - netif_ip6_addr_pref_life(netif, i) == 0) { - addr_state = IP6_ADDR_DEPRECATED; - } -#endif /* LWIP_IPV6_ADDRESS_LIFETIMES */ - netif_ip6_addr_set_state(netif, i, addr_state); - } else if (netif_is_up(netif) && netif_is_link_up(netif)) { - /* tentative: set next state by increasing by one */ - netif_ip6_addr_set_state(netif, i, addr_state + 1); - /* Send a NS for this address. Use the unspecified address as source - * address in all cases (RFC 4862 Sec. 5.4.2), not in the least - * because as it is, we only consider multicast replies for DAD. */ - nd6_send_ns(netif, netif_ip6_addr(netif, i), - ND6_SEND_FLAG_MULTICAST_DEST | ND6_SEND_FLAG_ANY_SRC); - } - } - } - } - -#if LWIP_IPV6_SEND_ROUTER_SOLICIT - /* Send router solicitation messages, if necessary. */ - for (netif = netif_list; netif != NULL; netif = netif->next) { - if ((netif->rs_count > 0) && netif_is_up(netif) && - netif_is_link_up(netif) && - !ip6_addr_isinvalid(netif_ip6_addr_state(netif, 0)) && - !ip6_addr_isduplicated(netif_ip6_addr_state(netif, 0))) { - if (nd6_send_rs(netif) == ERR_OK) { - netif->rs_count--; - } - } - } -#endif /* LWIP_IPV6_SEND_ROUTER_SOLICIT */ - -} - -/** Send a neighbor solicitation message for a specific neighbor cache entry - * - * @param entry the neightbor cache entry for wich to send the message - * @param flags one of ND6_SEND_FLAG_* - */ -static void -nd6_send_neighbor_cache_probe(struct nd6_neighbor_cache_entry *entry, u8_t flags) -{ - nd6_send_ns(entry->netif, &entry->next_hop_address, flags); -} - -/** - * Send a neighbor solicitation message - * - * @param netif the netif on which to send the message - * @param target_addr the IPv6 target address for the ND message - * @param flags one of ND6_SEND_FLAG_* - */ -static void -nd6_send_ns(struct netif *netif, const ip6_addr_t *target_addr, u8_t flags) -{ - struct ns_header *ns_hdr; - struct pbuf *p; - const ip6_addr_t *src_addr; - u16_t lladdr_opt_len; - - if (!(flags & ND6_SEND_FLAG_ANY_SRC) && - ip6_addr_isvalid(netif_ip6_addr_state(netif,0))) { - /* Use link-local address as source address. */ - src_addr = netif_ip6_addr(netif, 0); - /* calculate option length (in 8-byte-blocks) */ - lladdr_opt_len = ((netif->hwaddr_len + 2) + 7) >> 3; - } else { - src_addr = IP6_ADDR_ANY6; - /* Option "MUST NOT be included when the source IP address is the unspecified address." */ - lladdr_opt_len = 0; - } - - /* Allocate a packet. */ - p = pbuf_alloc(PBUF_IP, sizeof(struct ns_header) + (lladdr_opt_len << 3), PBUF_RAM); - if ((p == NULL) || (p->len < (sizeof(struct ns_header) + (lladdr_opt_len << 3)))) { - /* We couldn't allocate a suitable pbuf for the ns. drop it. */ - if (p != NULL) { - pbuf_free(p); - } - ND6_STATS_INC(nd6.memerr); - return; - } - - /* Set fields. */ - ns_hdr = (struct ns_header *)p->payload; - - ns_hdr->type = ICMP6_TYPE_NS; - ns_hdr->code = 0; - ns_hdr->chksum = 0; - ns_hdr->reserved = 0; - ip6_addr_set(&(ns_hdr->target_address), target_addr); - - if (lladdr_opt_len != 0) { - struct lladdr_option *lladdr_opt = (struct lladdr_option *)((u8_t*)p->payload + sizeof(struct ns_header)); - lladdr_opt->type = ND6_OPTION_TYPE_SOURCE_LLADDR; - lladdr_opt->length = ND6_LLADDR_OPTION_LENGTH_ENCODE(netif->hwaddr_len); - SMEMCPY(lladdr_opt->addr, netif->hwaddr, netif->hwaddr_len); - } - - /* Generate the solicited node address for the target address. */ - if (flags & ND6_SEND_FLAG_MULTICAST_DEST) { - ip6_addr_set_solicitednode(&multicast_address, target_addr->addr[3]); - target_addr = &multicast_address; - } - -#if CHECKSUM_GEN_ICMP6 - IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_ICMP6) { - ns_hdr->chksum = ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->len, src_addr, - target_addr); - } -#endif /* CHECKSUM_GEN_ICMP6 */ - - /* Send the packet out. */ - ND6_STATS_INC(nd6.xmit); - ip6_output_if(p, (src_addr == IP6_ADDR_ANY6) ? NULL : src_addr, target_addr, - LWIP_ICMP6_HL, 0, IP6_NEXTH_ICMP6, netif); - pbuf_free(p); -} - -/** - * Send a neighbor advertisement message - * - * @param netif the netif on which to send the message - * @param target_addr the IPv6 target address for the ND message - * @param flags one of ND6_SEND_FLAG_* - */ -static void -nd6_send_na(struct netif *netif, const ip6_addr_t *target_addr, u8_t flags) -{ - struct na_header *na_hdr; - struct lladdr_option *lladdr_opt; - struct pbuf *p; - const ip6_addr_t *src_addr; - const ip6_addr_t *dest_addr; - - /* Use link-local address as source address. */ - /* src_addr = netif_ip6_addr(netif, 0); */ - /* Use target address as source address. */ - src_addr = target_addr; - - /* Allocate a packet. */ - p = pbuf_alloc(PBUF_IP, sizeof(struct na_header) + ND6_LLADDR_OPTION_SIZE(netif->hwaddr_len), PBUF_RAM); - if ((p == NULL) || (p->len < (sizeof(struct na_header) + ND6_LLADDR_OPTION_SIZE(netif->hwaddr_len)))) { - /* We couldn't allocate a suitable pbuf for the ns. drop it. */ - if (p != NULL) { - pbuf_free(p); - } - ND6_STATS_INC(nd6.memerr); - return; - } - - /* Set fields. */ - na_hdr = (struct na_header *)p->payload; - lladdr_opt = (struct lladdr_option *)((u8_t*)p->payload + sizeof(struct na_header)); - - na_hdr->type = ICMP6_TYPE_NA; - na_hdr->code = 0; - na_hdr->chksum = 0; - na_hdr->flags = flags & 0xf0; - na_hdr->reserved[0] = 0; - na_hdr->reserved[1] = 0; - na_hdr->reserved[2] = 0; - ip6_addr_set(&(na_hdr->target_address), target_addr); - - lladdr_opt->type = ND6_OPTION_TYPE_TARGET_LLADDR; - lladdr_opt->length = ((netif->hwaddr_len + 2) >> 3) + (((netif->hwaddr_len + 2) & 0x07) ? 1 : 0); - SMEMCPY(lladdr_opt->addr, netif->hwaddr, netif->hwaddr_len); - - /* Generate the solicited node address for the target address. */ - if (flags & ND6_SEND_FLAG_MULTICAST_DEST) { - ip6_addr_set_solicitednode(&multicast_address, target_addr->addr[3]); - dest_addr = &multicast_address; - } else if (flags & ND6_SEND_FLAG_ALLNODES_DEST) { - ip6_addr_set_allnodes_linklocal(&multicast_address); - dest_addr = &multicast_address; - } else { - dest_addr = ip6_current_src_addr(); - } - -#if CHECKSUM_GEN_ICMP6 - IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_ICMP6) { - na_hdr->chksum = ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->len, src_addr, - dest_addr); - } -#endif /* CHECKSUM_GEN_ICMP6 */ - - /* Send the packet out. */ - ND6_STATS_INC(nd6.xmit); - ip6_output_if(p, src_addr, dest_addr, - LWIP_ICMP6_HL, 0, IP6_NEXTH_ICMP6, netif); - pbuf_free(p); -} - -#if LWIP_IPV6_SEND_ROUTER_SOLICIT -/** - * Send a router solicitation message - * - * @param netif the netif on which to send the message - */ -static err_t -nd6_send_rs(struct netif *netif) -{ - struct rs_header *rs_hdr; - struct lladdr_option *lladdr_opt; - struct pbuf *p; - const ip6_addr_t *src_addr; - err_t err; - u16_t lladdr_opt_len = 0; - - /* Link-local source address, or unspecified address? */ - if (ip6_addr_isvalid(netif_ip6_addr_state(netif, 0))) { - src_addr = netif_ip6_addr(netif, 0); - } else { - src_addr = IP6_ADDR_ANY6; - } - - /* Generate the all routers target address. */ - ip6_addr_set_allrouters_linklocal(&multicast_address); - - /* Allocate a packet. */ - if (src_addr != IP6_ADDR_ANY6) { - lladdr_opt_len = ((netif->hwaddr_len + 2) >> 3) + (((netif->hwaddr_len + 2) & 0x07) ? 1 : 0); - } - p = pbuf_alloc(PBUF_IP, sizeof(struct rs_header) + (lladdr_opt_len << 3), PBUF_RAM); - if (p == NULL) { - ND6_STATS_INC(nd6.memerr); - return ERR_BUF; - } - - /* Set fields. */ - rs_hdr = (struct rs_header *)p->payload; - - rs_hdr->type = ICMP6_TYPE_RS; - rs_hdr->code = 0; - rs_hdr->chksum = 0; - rs_hdr->reserved = 0; - - if (src_addr != IP6_ADDR_ANY6) { - /* Include our hw address. */ - lladdr_opt = (struct lladdr_option *)((u8_t*)p->payload + sizeof(struct rs_header)); - lladdr_opt->type = ND6_OPTION_TYPE_SOURCE_LLADDR; - lladdr_opt->length = ((netif->hwaddr_len + 2) >> 3) + (((netif->hwaddr_len + 2) & 0x07) ? 1 : 0); - SMEMCPY(lladdr_opt->addr, netif->hwaddr, netif->hwaddr_len); - } - -#if CHECKSUM_GEN_ICMP6 - IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_ICMP6) { - rs_hdr->chksum = ip6_chksum_pseudo(p, IP6_NEXTH_ICMP6, p->len, src_addr, - &multicast_address); - } -#endif /* CHECKSUM_GEN_ICMP6 */ - - /* Send the packet out. */ - ND6_STATS_INC(nd6.xmit); - - err = ip6_output_if(p, (src_addr == IP6_ADDR_ANY6) ? NULL : src_addr, &multicast_address, - LWIP_ICMP6_HL, 0, IP6_NEXTH_ICMP6, netif); - pbuf_free(p); - - return err; -} -#endif /* LWIP_IPV6_SEND_ROUTER_SOLICIT */ - -/** - * Search for a neighbor cache entry - * - * @param ip6addr the IPv6 address of the neighbor - * @return The neighbor cache entry index that matched, -1 if no - * entry is found - */ -static s8_t -nd6_find_neighbor_cache_entry(const ip6_addr_t *ip6addr) -{ - s8_t i; - for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) { - if (ip6_addr_cmp(ip6addr, &(neighbor_cache[i].next_hop_address))) { - return i; - } - } - return -1; -} - -/** - * Create a new neighbor cache entry. - * - * If no unused entry is found, will try to recycle an old entry - * according to ad-hoc "age" heuristic. - * - * @return The neighbor cache entry index that was created, -1 if no - * entry could be created - */ -static s8_t -nd6_new_neighbor_cache_entry(void) -{ - s8_t i; - s8_t j; - u32_t time; - - - /* First, try to find an empty entry. */ - for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) { - if (neighbor_cache[i].state == ND6_NO_ENTRY) { - return i; - } - } - - /* We need to recycle an entry. in general, do not recycle if it is a router. */ - - /* Next, try to find a Stale entry. */ - for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) { - if ((neighbor_cache[i].state == ND6_STALE) && - (!neighbor_cache[i].isrouter)) { - nd6_free_neighbor_cache_entry(i); - return i; - } - } - - /* Next, try to find a Probe entry. */ - for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) { - if ((neighbor_cache[i].state == ND6_PROBE) && - (!neighbor_cache[i].isrouter)) { - nd6_free_neighbor_cache_entry(i); - return i; - } - } - - /* Next, try to find a Delayed entry. */ - for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) { - if ((neighbor_cache[i].state == ND6_DELAY) && - (!neighbor_cache[i].isrouter)) { - nd6_free_neighbor_cache_entry(i); - return i; - } - } - - /* Next, try to find the oldest reachable entry. */ - time = 0xfffffffful; - j = -1; - for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) { - if ((neighbor_cache[i].state == ND6_REACHABLE) && - (!neighbor_cache[i].isrouter)) { - if (neighbor_cache[i].counter.reachable_time < time) { - j = i; - time = neighbor_cache[i].counter.reachable_time; - } - } - } - if (j >= 0) { - nd6_free_neighbor_cache_entry(j); - return j; - } - - /* Next, find oldest incomplete entry without queued packets. */ - time = 0; - j = -1; - for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) { - if ( - (neighbor_cache[i].q == NULL) && - (neighbor_cache[i].state == ND6_INCOMPLETE) && - (!neighbor_cache[i].isrouter)) { - if (neighbor_cache[i].counter.probes_sent >= time) { - j = i; - time = neighbor_cache[i].counter.probes_sent; - } - } - } - if (j >= 0) { - nd6_free_neighbor_cache_entry(j); - return j; - } - - /* Next, find oldest incomplete entry with queued packets. */ - time = 0; - j = -1; - for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) { - if ((neighbor_cache[i].state == ND6_INCOMPLETE) && - (!neighbor_cache[i].isrouter)) { - if (neighbor_cache[i].counter.probes_sent >= time) { - j = i; - time = neighbor_cache[i].counter.probes_sent; - } - } - } - if (j >= 0) { - nd6_free_neighbor_cache_entry(j); - return j; - } - - /* No more entries to try. */ - return -1; -} - -/** - * Will free any resources associated with a neighbor cache - * entry, and will mark it as unused. - * - * @param i the neighbor cache entry index to free - */ -static void -nd6_free_neighbor_cache_entry(s8_t i) -{ - if ((i < 0) || (i >= LWIP_ND6_NUM_NEIGHBORS)) { - return; - } - if (neighbor_cache[i].isrouter) { - /* isrouter needs to be cleared before deleting a neighbor cache entry */ - return; - } - - /* Free any queued packets. */ - if (neighbor_cache[i].q != NULL) { - nd6_free_q(neighbor_cache[i].q); - neighbor_cache[i].q = NULL; - } - - neighbor_cache[i].state = ND6_NO_ENTRY; - neighbor_cache[i].isrouter = 0; - neighbor_cache[i].netif = NULL; - neighbor_cache[i].counter.reachable_time = 0; - ip6_addr_set_zero(&(neighbor_cache[i].next_hop_address)); -} - -/** - * Search for a destination cache entry - * - * @param ip6addr the IPv6 address of the destination - * @return The destination cache entry index that matched, -1 if no - * entry is found - */ -static s8_t -nd6_find_destination_cache_entry(const ip6_addr_t *ip6addr) -{ - s8_t i; - for (i = 0; i < LWIP_ND6_NUM_DESTINATIONS; i++) { - if (ip6_addr_cmp(ip6addr, &(destination_cache[i].destination_addr))) { - return i; - } - } - return -1; -} - -/** - * Create a new destination cache entry. If no unused entry is found, - * will recycle oldest entry. - * - * @return The destination cache entry index that was created, -1 if no - * entry was created - */ -static s8_t -nd6_new_destination_cache_entry(void) -{ - s8_t i, j; - u32_t age; - - /* Find an empty entry. */ - for (i = 0; i < LWIP_ND6_NUM_DESTINATIONS; i++) { - if (ip6_addr_isany(&(destination_cache[i].destination_addr))) { - return i; - } - } - - /* Find oldest entry. */ - age = 0; - j = LWIP_ND6_NUM_DESTINATIONS - 1; - for (i = 0; i < LWIP_ND6_NUM_DESTINATIONS; i++) { - if (destination_cache[i].age > age) { - j = i; - } - } - - return j; -} - -/** - * Clear the destination cache. - * - * This operation may be necessary for consistency in the light of changing - * local addresses and/or use of the gateway hook. - */ -void -nd6_clear_destination_cache(void) -{ - int i; - - for (i = 0; i < LWIP_ND6_NUM_DESTINATIONS; i++) { - ip6_addr_set_any(&destination_cache[i].destination_addr); - } -} - -/** - * Determine whether an address matches an on-link prefix or the subnet of a - * statically assigned address. - * - * @param ip6addr the IPv6 address to match - * @return 1 if the address is on-link, 0 otherwise - */ -static s8_t -nd6_is_prefix_in_netif(const ip6_addr_t *ip6addr, struct netif *netif) -{ - s8_t i; - -#if LWIP_ND6_LISTEN_RA - /* Check to see if the address matches an on-link prefix. */ - for (i = 0; i < LWIP_ND6_NUM_PREFIXES; i++) { - if ((prefix_list[i].netif == netif) && - (prefix_list[i].invalidation_timer > 0) && - ip6_addr_netcmp(ip6addr, &(prefix_list[i].prefix))) { - return 1; - } - } -#endif /* LWIP_ND6_LISTEN_RA */ - - /* Check to see if address prefix matches a manually configured (= static) - * address. Static addresses have an implied /64 subnet assignment. Dynamic - * addresses (from autoconfiguration) have no implied subnet assignment, and - * are thus effectively /128 assignments. See RFC 5942 for more on this. */ - for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { - if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i)) && - netif_ip6_addr_isstatic(netif, i) && - ip6_addr_netcmp(ip6addr, netif_ip6_addr(netif, i))) { - return 1; - } - } - return 0; -} - -#if LWIP_IPV6_ROUTER_SUPPORT -/** - * Select a default router for a destination. - * - * This function is used both for routing and for finding a next-hop target for - * a packet. In the former case, the given netif is NULL, and the returned - * router entry must be for a netif suitable for sending packets (up, link up). - * In the latter case, the given netif is not NULL and restricts router choice. - * - * @param ip6addr the destination address - * @param netif the netif for the outgoing packet, if known - * @return the default router entry index, or -1 if no suitable - * router is found - */ -static s8_t -nd6_select_router(const ip6_addr_t *ip6addr, struct netif *netif) -{ - struct netif *router_netif; - s8_t i, j, valid_router; - static s8_t last_router; - - LWIP_UNUSED_ARG(ip6addr); /* @todo match preferred routes!! (must implement ND6_OPTION_TYPE_ROUTE_INFO) */ - - /* @todo: implement default router preference */ - - /* Look for valid routers. A reachable router is preferred. */ - valid_router = -1; - for (i = 0; i < LWIP_ND6_NUM_ROUTERS; i++) { - /* Is the router netif both set and apppropriate? */ - if (default_router_list[i].neighbor_entry != NULL) { - router_netif = default_router_list[i].neighbor_entry->netif; - if ((router_netif != NULL) && (netif != NULL ? netif == router_netif : - (netif_is_up(router_netif) && netif_is_link_up(router_netif)))) { - /* Is the router valid, i.e., reachable or probably reachable as per - * RFC 4861 Sec. 6.3.6? Note that we will never return a router that - * has no neighbor cache entry, due to the netif association tests. */ - if (default_router_list[i].neighbor_entry->state != ND6_INCOMPLETE) { - /* Is the router known to be reachable? */ - if (default_router_list[i].neighbor_entry->state == ND6_REACHABLE) { - return i; /* valid and reachable - done! */ - } else if (valid_router < 0) { - valid_router = i; /* valid but not known to be reachable */ - } - } - } - } - } - if (valid_router >= 0) { - return valid_router; - } - - /* Look for any router for which we have any information at all. */ - /* last_router is used for round-robin selection of incomplete routers, as - * recommended in RFC 4861 Sec. 6.3.6 point (2). Advance only when picking a - * route, to select the same router as next-hop target in the common case. */ - if ((netif == NULL) && (++last_router >= LWIP_ND6_NUM_ROUTERS)) { - last_router = 0; - } - i = last_router; - for (j = 0; j < LWIP_ND6_NUM_ROUTERS; j++) { - if (default_router_list[i].neighbor_entry != NULL) { - router_netif = default_router_list[i].neighbor_entry->netif; - if ((router_netif != NULL) && (netif != NULL ? netif == router_netif : - (netif_is_up(router_netif) && netif_is_link_up(router_netif)))) { - return i; - } - } - if (++i >= LWIP_ND6_NUM_ROUTERS) { - i = 0; - } - } - - /* no suitable router found. */ - return -1; -} - -#endif /* LWIP_IPV6_ROUTER_SUPPORT */ - - -#if LWIP_ND6_LISTEN_RA - -/** - * Find a router-announced route to the given destination. This route may be - * based on an on-link prefix or a default router. - * - * If a suitable route is found, the returned netif is guaranteed to be in a - * suitable state (up, link up) to be used for packet transmission. - * - * @param ip6addr the destination IPv6 address - * @return the netif to use for the destination, or NULL if none found - */ -struct netif * -nd6_find_route(const ip6_addr_t *ip6addr) -{ - struct netif *netif; - s8_t i; - - /* @todo decide if it makes sense to check the destination cache first */ - - /* Check if there is a matching on-link prefix. There may be multiple - * matches. Pick the first one that is associated with a suitable netif. */ - for (i = 0; i < LWIP_ND6_NUM_PREFIXES; ++i) { - netif = prefix_list[i].netif; - if ((netif != NULL) && ip6_addr_netcmp(&prefix_list[i].prefix, ip6addr) && - netif_is_up(netif) && netif_is_link_up(netif)) { - return netif; - } - } - - /* No on-link prefix match. Find a router that can forward the packet. */ - i = nd6_select_router(ip6addr, NULL); - if (i >= 0) { - LWIP_ASSERT("selected router must have a neighbor entry", - default_router_list[i].neighbor_entry != NULL); - return default_router_list[i].neighbor_entry->netif; - } - - return NULL; -} - -/** - * Find an entry for a default router. - * - * @param router_addr the IPv6 address of the router - * @param netif the netif on which the router is found, if known - * @return the index of the router entry, or -1 if not found - */ -static s8_t -nd6_get_router(const ip6_addr_t *router_addr, struct netif *netif) -{ - s8_t i; - - /* Look for router. */ - for (i = 0; i < LWIP_ND6_NUM_ROUTERS; i++) { - if ((default_router_list[i].neighbor_entry != NULL) && - ((netif != NULL) ? netif == default_router_list[i].neighbor_entry->netif : 1) && - ip6_addr_cmp(router_addr, &(default_router_list[i].neighbor_entry->next_hop_address))) { - return i; - } - } - - /* router not found. */ - return -1; -} - -/** - * Create a new entry for a default router. - * - * @param router_addr the IPv6 address of the router - * @param netif the netif on which the router is connected, if known - * @return the index on the router table, or -1 if could not be created - */ -static s8_t -nd6_new_router(const ip6_addr_t *router_addr, struct netif *netif) -{ - s8_t router_index; - s8_t free_router_index; - s8_t neighbor_index; - - /* Do we have a neighbor entry for this router? */ - neighbor_index = nd6_find_neighbor_cache_entry(router_addr); - if (neighbor_index < 0) { - /* Create a neighbor entry for this router. */ - neighbor_index = nd6_new_neighbor_cache_entry(); - if (neighbor_index < 0) { - /* Could not create neighbor entry for this router. */ - return -1; - } - ip6_addr_set(&(neighbor_cache[neighbor_index].next_hop_address), router_addr); - neighbor_cache[neighbor_index].netif = netif; - neighbor_cache[neighbor_index].q = NULL; - neighbor_cache[neighbor_index].state = ND6_INCOMPLETE; - neighbor_cache[neighbor_index].counter.probes_sent = 1; - nd6_send_neighbor_cache_probe(&neighbor_cache[neighbor_index], ND6_SEND_FLAG_MULTICAST_DEST); - } - - /* Mark neighbor as router. */ - neighbor_cache[neighbor_index].isrouter = 1; - - /* Look for empty entry. */ - free_router_index = LWIP_ND6_NUM_ROUTERS; - for (router_index = LWIP_ND6_NUM_ROUTERS - 1; router_index >= 0; router_index--) { - /* check if router already exists (this is a special case for 2 netifs on the same subnet - - e.g. wifi and cable) */ - if(default_router_list[router_index].neighbor_entry == &(neighbor_cache[neighbor_index])){ - return router_index; - } - if (default_router_list[router_index].neighbor_entry == NULL) { - /* remember lowest free index to create a new entry */ - free_router_index = router_index; - } - } - if (free_router_index < LWIP_ND6_NUM_ROUTERS) { - default_router_list[free_router_index].neighbor_entry = &(neighbor_cache[neighbor_index]); - return free_router_index; - } - - /* Could not create a router entry. */ - - /* Mark neighbor entry as not-router. Entry might be useful as neighbor still. */ - neighbor_cache[neighbor_index].isrouter = 0; - - /* router not found. */ - return -1; -} - -#endif /* LWIP_ND6_LISTEN_RA */ - -#if LWIP_ND6_LISTEN_RA - -/** - * Find the cached entry for an on-link prefix. - * - * @param prefix the IPv6 prefix that is on-link - * @param netif the netif on which the prefix is on-link - * @return the index on the prefix table, or -1 if not found - */ -static s8_t -nd6_get_onlink_prefix(const ip6_addr_t *prefix, struct netif *netif) -{ - s8_t i; - - /* Look for prefix in list. */ - for (i = 0; i < LWIP_ND6_NUM_PREFIXES; ++i) { - if ((ip6_addr_netcmp(&(prefix_list[i].prefix), prefix)) && - (prefix_list[i].netif == netif)) { - return i; - } - } - - /* Entry not available. */ - return -1; -} - -/** - * Creates a new entry for an on-link prefix. - * - * @param prefix the IPv6 prefix that is on-link - * @param netif the netif on which the prefix is on-link - * @return the index on the prefix table, or -1 if not created - */ -static s8_t -nd6_new_onlink_prefix(const ip6_addr_t *prefix, struct netif *netif) -{ - s8_t i; - - /* Create new entry. */ - for (i = 0; i < LWIP_ND6_NUM_PREFIXES; ++i) { - if ((prefix_list[i].netif == NULL) || - (prefix_list[i].invalidation_timer == 0)) { - /* Found empty prefix entry. */ - prefix_list[i].netif = netif; - ip6_addr_set(&(prefix_list[i].prefix), prefix); - return i; - } - } - - /* Entry not available. */ - return -1; -} - -#endif /* LWIP_ND6_LISTEN_RA */ - -/** - * Determine the next hop for a destination. Will determine if the - * destination is on-link, else a suitable on-link router is selected. - * - * The last entry index is cached for fast entry search. - * - * @param ip6addr the destination address - * @param netif the netif on which the packet will be sent - * @return the neighbor cache entry for the next hop, ERR_RTE if no - * suitable next hop was found, ERR_MEM if no cache entry - * could be created - */ -static s8_t -nd6_get_next_hop_entry(const ip6_addr_t *ip6addr, struct netif *netif) -{ -#ifdef LWIP_HOOK_ND6_GET_GW - const ip6_addr_t *next_hop_addr; -#endif /* LWIP_HOOK_ND6_GET_GW */ - s8_t i; - -#if LWIP_NETIF_HWADDRHINT - if (netif->addr_hint != NULL) { - /* per-pcb cached entry was given */ - u8_t addr_hint = *(netif->addr_hint); - if (addr_hint < LWIP_ND6_NUM_DESTINATIONS) { - nd6_cached_destination_index = addr_hint; - } - } -#endif /* LWIP_NETIF_HWADDRHINT */ - - /* Look for ip6addr in destination cache. */ - if (ip6_addr_cmp(ip6addr, &(destination_cache[nd6_cached_destination_index].destination_addr))) { - /* the cached entry index is the right one! */ - /* do nothing. */ - ND6_STATS_INC(nd6.cachehit); - } else { - /* Search destination cache. */ - i = nd6_find_destination_cache_entry(ip6addr); - if (i >= 0) { - /* found destination entry. make it our new cached index. */ - nd6_cached_destination_index = i; - } else { - /* Not found. Create a new destination entry. */ - i = nd6_new_destination_cache_entry(); - if (i >= 0) { - /* got new destination entry. make it our new cached index. */ - nd6_cached_destination_index = i; - } else { - /* Could not create a destination cache entry. */ - return ERR_MEM; - } - - /* Copy dest address to destination cache. */ - ip6_addr_set(&(destination_cache[nd6_cached_destination_index].destination_addr), ip6addr); - - /* Now find the next hop. is it a neighbor? */ - if (ip6_addr_islinklocal(ip6addr) || - nd6_is_prefix_in_netif(ip6addr, netif)) { - /* Destination in local link. */ - destination_cache[nd6_cached_destination_index].pmtu = netif->mtu; - ip6_addr_copy(destination_cache[nd6_cached_destination_index].next_hop_addr, destination_cache[nd6_cached_destination_index].destination_addr); - } - else { -#if LWIP_IPV6_ROUTER_SUPPORT - /* We need to select a router. */ - i = nd6_select_router(ip6addr, netif); - if (i < 0) { - /* No router found. */ - ip6_addr_set_any(&(destination_cache[nd6_cached_destination_index].destination_addr)); - return ERR_RTE; - } - destination_cache[nd6_cached_destination_index].pmtu = netif->mtu; /* Start with netif mtu, correct through ICMPv6 if necessary */ - ip6_addr_copy(destination_cache[nd6_cached_destination_index].next_hop_addr, default_router_list[i].neighbor_entry->next_hop_address); -#else - ip6_addr_set_any(&(destination_cache[nd6_cached_destination_index].destination_addr)); - return ERR_RTE; -#endif /* LWIP_IPV6_ROUTER_SUPPORT */ - } - } - } - -#if LWIP_NETIF_HWADDRHINT - if (netif->addr_hint != NULL) { - /* per-pcb cached entry was given */ - *(netif->addr_hint) = nd6_cached_destination_index; - } -#endif /* LWIP_NETIF_HWADDRHINT */ - - /* Look in neighbor cache for the next-hop address. */ - if (ip6_addr_cmp(&(destination_cache[nd6_cached_destination_index].next_hop_addr), - &(neighbor_cache[nd6_cached_neighbor_index].next_hop_address))) { - /* Cache hit. */ - /* Do nothing. */ - ND6_STATS_INC(nd6.cachehit); - } else { - i = nd6_find_neighbor_cache_entry(&(destination_cache[nd6_cached_destination_index].next_hop_addr)); - if (i >= 0) { - /* Found a matching record, make it new cached entry. */ - nd6_cached_neighbor_index = i; - } else { - /* Neighbor not in cache. Make a new entry. */ - i = nd6_new_neighbor_cache_entry(); - if (i >= 0) { - /* got new neighbor entry. make it our new cached index. */ - nd6_cached_neighbor_index = i; - } else { - /* Could not create a neighbor cache entry. */ - return ERR_MEM; - } - - /* Initialize fields. */ - ip6_addr_copy(neighbor_cache[i].next_hop_address, - destination_cache[nd6_cached_destination_index].next_hop_addr); - neighbor_cache[i].isrouter = 0; - neighbor_cache[i].netif = netif; - neighbor_cache[i].state = ND6_INCOMPLETE; - neighbor_cache[i].counter.probes_sent = 1; - nd6_send_neighbor_cache_probe(&neighbor_cache[i], ND6_SEND_FLAG_MULTICAST_DEST); - } - } - - /* Reset this destination's age. */ - destination_cache[nd6_cached_destination_index].age = 0; - - return nd6_cached_neighbor_index; -} - -/** - * Queue a packet for a neighbor. - * - * @param neighbor_index the index in the neighbor cache table - * @param q packet to be queued - * @return ERR_OK if succeeded, ERR_MEM if out of memory - */ -static err_t -nd6_queue_packet(s8_t neighbor_index, struct pbuf *q) -{ - err_t result = ERR_MEM; - struct pbuf *p; - int copy_needed = 0; -#if LWIP_ND6_QUEUEING - struct nd6_q_entry *new_entry, *r; -#endif /* LWIP_ND6_QUEUEING */ - - if ((neighbor_index < 0) || (neighbor_index >= LWIP_ND6_NUM_NEIGHBORS)) { - return ERR_ARG; - } - - /* IF q includes a PBUF_REF, PBUF_POOL or PBUF_RAM, we have no choice but - * to copy the whole queue into a new PBUF_RAM (see bug #11400) - * PBUF_ROMs can be left as they are, since ROM must not get changed. */ - p = q; - while (p) { - if (p->type != PBUF_ROM) { - copy_needed = 1; - break; - } - p = p->next; - } - if (copy_needed) { - /* copy the whole packet into new pbufs */ - p = pbuf_alloc(PBUF_LINK, q->tot_len, PBUF_RAM); - while ((p == NULL) && (neighbor_cache[neighbor_index].q != NULL)) { - /* Free oldest packet (as per RFC recommendation) */ -#if LWIP_ND6_QUEUEING - r = neighbor_cache[neighbor_index].q; - neighbor_cache[neighbor_index].q = r->next; - r->next = NULL; - nd6_free_q(r); -#else /* LWIP_ND6_QUEUEING */ - pbuf_free(neighbor_cache[neighbor_index].q); - neighbor_cache[neighbor_index].q = NULL; -#endif /* LWIP_ND6_QUEUEING */ - p = pbuf_alloc(PBUF_LINK, q->tot_len, PBUF_RAM); - } - if (p != NULL) { - if (pbuf_copy(p, q) != ERR_OK) { - pbuf_free(p); - p = NULL; - } - } - } else { - /* referencing the old pbuf is enough */ - p = q; - pbuf_ref(p); - } - /* packet was copied/ref'd? */ - if (p != NULL) { - /* queue packet ... */ -#if LWIP_ND6_QUEUEING - /* allocate a new nd6 queue entry */ - new_entry = (struct nd6_q_entry *)memp_malloc(MEMP_ND6_QUEUE); - if ((new_entry == NULL) && (neighbor_cache[neighbor_index].q != NULL)) { - /* Free oldest packet (as per RFC recommendation) */ - r = neighbor_cache[neighbor_index].q; - neighbor_cache[neighbor_index].q = r->next; - r->next = NULL; - nd6_free_q(r); - new_entry = (struct nd6_q_entry *)memp_malloc(MEMP_ND6_QUEUE); - } - if (new_entry != NULL) { - new_entry->next = NULL; - new_entry->p = p; - if (neighbor_cache[neighbor_index].q != NULL) { - /* queue was already existent, append the new entry to the end */ - r = neighbor_cache[neighbor_index].q; - while (r->next != NULL) { - r = r->next; - } - r->next = new_entry; - } else { - /* queue did not exist, first item in queue */ - neighbor_cache[neighbor_index].q = new_entry; - } - LWIP_DEBUGF(LWIP_DBG_TRACE, ("ipv6: queued packet %p on neighbor entry %"S16_F"\n", (void *)p, (s16_t)neighbor_index)); - result = ERR_OK; - } else { - /* the pool MEMP_ND6_QUEUE is empty */ - pbuf_free(p); - LWIP_DEBUGF(LWIP_DBG_TRACE, ("ipv6: could not queue a copy of packet %p (out of memory)\n", (void *)p)); - /* { result == ERR_MEM } through initialization */ - } -#else /* LWIP_ND6_QUEUEING */ - /* Queue a single packet. If an older packet is already queued, free it as per RFC. */ - if (neighbor_cache[neighbor_index].q != NULL) { - pbuf_free(neighbor_cache[neighbor_index].q); - } - neighbor_cache[neighbor_index].q = p; - LWIP_DEBUGF(LWIP_DBG_TRACE, ("ipv6: queued packet %p on neighbor entry %"S16_F"\n", (void *)p, (s16_t)neighbor_index)); - result = ERR_OK; -#endif /* LWIP_ND6_QUEUEING */ - } else { - LWIP_DEBUGF(LWIP_DBG_TRACE, ("ipv6: could not queue a copy of packet %p (out of memory)\n", (void *)q)); - /* { result == ERR_MEM } through initialization */ - } - - return result; -} - -#if LWIP_ND6_QUEUEING -/** - * Free a complete queue of nd6 q entries - * - * @param q a queue of nd6_q_entry to free - */ -static void -nd6_free_q(struct nd6_q_entry *q) -{ - struct nd6_q_entry *r; - LWIP_ASSERT("q != NULL", q != NULL); - LWIP_ASSERT("q->p != NULL", q->p != NULL); - while (q) { - r = q; - q = q->next; - LWIP_ASSERT("r->p != NULL", (r->p != NULL)); - pbuf_free(r->p); - memp_free(MEMP_ND6_QUEUE, r); - } -} -#endif /* LWIP_ND6_QUEUEING */ - -/** - * Send queued packets for a neighbor - * - * @param i the neighbor to send packets to - */ -static void -nd6_send_q(s8_t i) -{ - struct ip6_hdr *ip6hdr; - ip6_addr_t dest; -#if LWIP_ND6_QUEUEING - struct nd6_q_entry *q; -#endif /* LWIP_ND6_QUEUEING */ - - if ((i < 0) || (i >= LWIP_ND6_NUM_NEIGHBORS)) { - return; - } - -#if LWIP_ND6_QUEUEING - while (neighbor_cache[i].q != NULL) { - /* remember first in queue */ - q = neighbor_cache[i].q; - /* pop first item off the queue */ - neighbor_cache[i].q = q->next; - /* Get ipv6 header. */ - ip6hdr = (struct ip6_hdr *)(q->p->payload); - /* Create an aligned copy. */ - ip6_addr_set(&dest, &(ip6hdr->dest)); - /* send the queued IPv6 packet */ - (neighbor_cache[i].netif)->output_ip6(neighbor_cache[i].netif, q->p, &dest); - /* free the queued IP packet */ - pbuf_free(q->p); - /* now queue entry can be freed */ - memp_free(MEMP_ND6_QUEUE, q); - } -#else /* LWIP_ND6_QUEUEING */ - if (neighbor_cache[i].q != NULL) { - /* Get ipv6 header. */ - ip6hdr = (struct ip6_hdr *)(neighbor_cache[i].q->payload); - /* Create an aligned copy. */ - ip6_addr_set(&dest, &(ip6hdr->dest)); - /* send the queued IPv6 packet */ - (neighbor_cache[i].netif)->output_ip6(neighbor_cache[i].netif, neighbor_cache[i].q, &dest); - /* free the queued IP packet */ - pbuf_free(neighbor_cache[i].q); - neighbor_cache[i].q = NULL; - } -#endif /* LWIP_ND6_QUEUEING */ -} - -/** - * A packet is to be transmitted to a specific IPv6 destination on a specific - * interface. Check if we can find the hardware address of the next hop to use - * for the packet. If so, give the hardware address to the caller, which should - * use it to send the packet right away. Otherwise, enqueue the packet for - * later transmission while looking up the hardware address, if possible. - * - * As such, this function returns one of three different possible results: - * - * - ERR_OK with a non-NULL 'hwaddrp': the caller should send the packet now. - * - ERR_OK with a NULL 'hwaddrp': the packet has been enqueued for later. - * - not ERR_OK: something went wrong; forward the error upward in the stack. - * - * @param netif The lwIP network interface on which the IP packet will be sent. - * @param q The pbuf(s) containing the IP packet to be sent. - * @param ip6addr The destination IPv6 address of the packet. - * @param hwaddrp On success, filled with a pointer to a HW address or NULL (meaning - * the packet has been queued). - * @return - * - ERR_OK on success, ERR_RTE if no route was found for the packet, - * or ERR_MEM if low memory conditions prohibit sending the packet at all. - */ -err_t -nd6_get_next_hop_addr_or_queue(struct netif *netif, struct pbuf *q, const ip6_addr_t *ip6addr, const u8_t **hwaddrp) -{ - s8_t i; - - /* Get next hop record. */ - i = nd6_get_next_hop_entry(ip6addr, netif); - if (i < 0) { - /* failed to get a next hop neighbor record. */ - return i; - } - - /* Now that we have a destination record, send or queue the packet. */ - if (neighbor_cache[i].state == ND6_STALE) { - /* Switch to delay state. */ - neighbor_cache[i].state = ND6_DELAY; - neighbor_cache[i].counter.delay_time = LWIP_ND6_DELAY_FIRST_PROBE_TIME / ND6_TMR_INTERVAL; - } - /* @todo should we send or queue if PROBE? send for now, to let unicast NS pass. */ - if ((neighbor_cache[i].state == ND6_REACHABLE) || - (neighbor_cache[i].state == ND6_DELAY) || - (neighbor_cache[i].state == ND6_PROBE)) { - - /* Tell the caller to send out the packet now. */ - *hwaddrp = neighbor_cache[i].lladdr; - return ERR_OK; - } - - /* We should queue packet on this interface. */ - *hwaddrp = NULL; - return nd6_queue_packet(i, q); -} - - -/** - * Get the Path MTU for a destination. - * - * @param ip6addr the destination address - * @param netif the netif on which the packet will be sent - * @return the Path MTU, if known, or the netif default MTU - */ -u16_t -nd6_get_destination_mtu(const ip6_addr_t *ip6addr, struct netif *netif) -{ - s8_t i; - - i = nd6_find_destination_cache_entry(ip6addr); - if (i >= 0) { - if (destination_cache[i].pmtu > 0) { - return destination_cache[i].pmtu; - } - } - - if (netif != NULL) { - return netif->mtu; - } - - return IP6_MIN_MTU; -} - - -#if LWIP_ND6_TCP_REACHABILITY_HINTS -/** - * Provide the Neighbor discovery process with a hint that a - * destination is reachable. Called by tcp_receive when ACKs are - * received or sent (as per RFC). This is useful to avoid sending - * NS messages every 30 seconds. - * - * @param ip6addr the destination address which is know to be reachable - * by an upper layer protocol (TCP) - */ -void -nd6_reachability_hint(const ip6_addr_t *ip6addr) -{ - s8_t i; - - /* Find destination in cache. */ - if (ip6_addr_cmp(ip6addr, &(destination_cache[nd6_cached_destination_index].destination_addr))) { - i = nd6_cached_destination_index; - ND6_STATS_INC(nd6.cachehit); - } else { - i = nd6_find_destination_cache_entry(ip6addr); - } - if (i < 0) { - return; - } - - /* Find next hop neighbor in cache. */ - if (ip6_addr_cmp(&(destination_cache[i].next_hop_addr), &(neighbor_cache[nd6_cached_neighbor_index].next_hop_address))) { - i = nd6_cached_neighbor_index; - ND6_STATS_INC(nd6.cachehit); - } else { - i = nd6_find_neighbor_cache_entry(&(destination_cache[i].next_hop_addr)); - } - if (i < 0) { - return; - } - - /* For safety: don't set as reachable if we don't have a LL address yet. Misuse protection. */ - if (neighbor_cache[i].state == ND6_INCOMPLETE || neighbor_cache[i].state == ND6_NO_ENTRY) { - return; - } - - /* Set reachability state. */ - neighbor_cache[i].state = ND6_REACHABLE; - neighbor_cache[i].counter.reachable_time = reachable_time; -} -#endif /* LWIP_ND6_TCP_REACHABILITY_HINTS */ - -/** - * Remove all prefix, neighbor_cache and router entries of the specified netif. - * - * @param netif points to a network interface - */ -void -nd6_cleanup_netif(struct netif *netif) -{ - u8_t i; -#if LWIP_IPV6_ROUTER_SUPPORT - s8_t router_index; -#endif -#if LWIP_ND6_LISTEN_RA - for (i = 0; i < LWIP_ND6_NUM_PREFIXES; i++) { - if (prefix_list[i].netif == netif) { - prefix_list[i].netif = NULL; - } - } -#endif - for (i = 0; i < LWIP_ND6_NUM_NEIGHBORS; i++) { - if (neighbor_cache[i].netif == netif) { -#if LWIP_IPV6_ROUTER_SUPPORT - for (router_index = 0; router_index < LWIP_ND6_NUM_ROUTERS; router_index++) { - if (default_router_list[router_index].neighbor_entry == &neighbor_cache[i]) { - default_router_list[router_index].neighbor_entry = NULL; - default_router_list[router_index].flags = 0; - } - } -#endif - neighbor_cache[i].isrouter = 0; - nd6_free_neighbor_cache_entry(i); - } - } -} - -#if LWIP_IPV6_MLD -/** - * The state of a local IPv6 address entry is about to change. If needed, join - * or leave the solicited-node multicast group for the address. - * - * @param netif The netif that owns the address. - * @param addr_idx The index of the address. - * @param new_state The new (IP6_ADDR_) state for the address. - */ -void -nd6_adjust_mld_membership(struct netif *netif, s8_t addr_idx, u8_t new_state) -{ - u8_t old_state, old_member, new_member; - - old_state = netif_ip6_addr_state(netif, addr_idx); - - /* Determine whether we were, and should be, a member of the solicited-node - * multicast group for this address. For tentative addresses, the group is - * not joined until the address enters the TENTATIVE_1 (or VALID) state. */ - old_member = (old_state != IP6_ADDR_INVALID && old_state != IP6_ADDR_DUPLICATED && old_state != IP6_ADDR_TENTATIVE); - new_member = (new_state != IP6_ADDR_INVALID && new_state != IP6_ADDR_DUPLICATED && new_state != IP6_ADDR_TENTATIVE); - - if (old_member != new_member) { - ip6_addr_set_solicitednode(&multicast_address, netif_ip6_addr(netif, addr_idx)->addr[3]); - - if (new_member) { - mld6_joingroup_netif(netif, &multicast_address); - } else { - mld6_leavegroup_netif(netif, &multicast_address); - } - } -} -#endif /* LWIP_IPV6_MLD */ - -#endif /* LWIP_IPV6 && LWIP_IPV6_ND */ diff --git a/third_party/lwip/repo/lwip/src/core/mem.c b/third_party/lwip/repo/lwip/src/core/mem.c deleted file mode 100644 index dc06e0505facdb..00000000000000 --- a/third_party/lwip/repo/lwip/src/core/mem.c +++ /dev/null @@ -1,778 +0,0 @@ -/** - * @file - * Dynamic memory manager - * - * This is a lightweight replacement for the standard C library malloc(). - * - * If you want to use the standard C library malloc() instead, define - * MEM_LIBC_MALLOC to 1 in your lwipopts.h - * - * To let mem_malloc() use pools (prevents fragmentation and is much faster than - * a heap but might waste some memory), define MEM_USE_POOLS to 1, define - * MEMP_USE_CUSTOM_POOLS to 1 and create a file "lwippools.h" that includes a list - * of pools like this (more pools can be added between _START and _END): - * - * Define three pools with sizes 256, 512, and 1512 bytes - * LWIP_MALLOC_MEMPOOL_START - * LWIP_MALLOC_MEMPOOL(20, 256) - * LWIP_MALLOC_MEMPOOL(10, 512) - * LWIP_MALLOC_MEMPOOL(5, 1512) - * LWIP_MALLOC_MEMPOOL_END - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * Simon Goldschmidt - * - */ - -#include "lwip/opt.h" -#include "lwip/mem.h" -#include "lwip/def.h" -#include "lwip/sys.h" -#include "lwip/stats.h" -#include "lwip/err.h" - -#include - -#if MEM_LIBC_MALLOC -#include /* for malloc()/free() */ -#endif - -#if MEM_LIBC_MALLOC || MEM_USE_POOLS - -/** mem_init is not used when using pools instead of a heap or using - * C library malloc(). - */ -void -mem_init(void) -{ -} - -/** mem_trim is not used when using pools instead of a heap or using - * C library malloc(): we can't free part of a pool element and the stack - * support mem_trim() to return a different pointer - */ -void* -mem_trim(void *mem, mem_size_t size) -{ - LWIP_UNUSED_ARG(size); - return mem; -} -#endif /* MEM_LIBC_MALLOC || MEM_USE_POOLS */ - -#if MEM_LIBC_MALLOC -/* lwIP heap implemented using C library malloc() */ - -/* in case C library malloc() needs extra protection, - * allow these defines to be overridden. - */ -#ifndef mem_clib_free -#define mem_clib_free free -#endif -#ifndef mem_clib_malloc -#define mem_clib_malloc malloc -#endif -#ifndef mem_clib_calloc -#define mem_clib_calloc calloc -#endif - -#if LWIP_STATS && MEM_STATS -#define MEM_LIBC_STATSHELPER_SIZE LWIP_MEM_ALIGN_SIZE(sizeof(mem_size_t)) -#else -#define MEM_LIBC_STATSHELPER_SIZE 0 -#endif - -/** - * Allocate a block of memory with a minimum of 'size' bytes. - * - * @param size is the minimum size of the requested block in bytes. - * @return pointer to allocated memory or NULL if no free memory was found. - * - * Note that the returned value must always be aligned (as defined by MEM_ALIGNMENT). - */ -void * -mem_malloc(mem_size_t size) -{ - void* ret = mem_clib_malloc(size + MEM_LIBC_STATSHELPER_SIZE); - if (ret == NULL) { - MEM_STATS_INC(err); - } else { - LWIP_ASSERT("malloc() must return aligned memory", LWIP_MEM_ALIGN(ret) == ret); -#if LWIP_STATS && MEM_STATS - *(mem_size_t*)ret = size; - ret = (u8_t*)ret + MEM_LIBC_STATSHELPER_SIZE; - MEM_STATS_INC_USED(used, size); -#endif - } - return ret; -} - -/** Put memory back on the heap - * - * @param rmem is the pointer as returned by a previous call to mem_malloc() - */ -void -mem_free(void *rmem) -{ - LWIP_ASSERT("rmem != NULL", (rmem != NULL)); - LWIP_ASSERT("rmem == MEM_ALIGN(rmem)", (rmem == LWIP_MEM_ALIGN(rmem))); -#if LWIP_STATS && MEM_STATS - rmem = (u8_t*)rmem - MEM_LIBC_STATSHELPER_SIZE; - MEM_STATS_DEC_USED(used, *(mem_size_t*)rmem); -#endif - mem_clib_free(rmem); -} - -#elif MEM_USE_POOLS - -/* lwIP heap implemented with different sized pools */ - -/** - * Allocate memory: determine the smallest pool that is big enough - * to contain an element of 'size' and get an element from that pool. - * - * @param size the size in bytes of the memory needed - * @return a pointer to the allocated memory or NULL if the pool is empty - */ -void * -mem_malloc(mem_size_t size) -{ - void *ret; - struct memp_malloc_helper *element = NULL; - memp_t poolnr; - mem_size_t required_size = size + LWIP_MEM_ALIGN_SIZE(sizeof(struct memp_malloc_helper)); - - for (poolnr = MEMP_POOL_FIRST; poolnr <= MEMP_POOL_LAST; poolnr = (memp_t)(poolnr + 1)) { - /* is this pool big enough to hold an element of the required size - plus a struct memp_malloc_helper that saves the pool this element came from? */ - if (required_size <= memp_pools[poolnr]->size) { - element = (struct memp_malloc_helper*)memp_malloc(poolnr); - if (element == NULL) { - /* No need to DEBUGF or ASSERT: This error is already taken care of in memp.c */ -#if MEM_USE_POOLS_TRY_BIGGER_POOL - /** Try a bigger pool if this one is empty! */ - if (poolnr < MEMP_POOL_LAST) { - continue; - } -#endif /* MEM_USE_POOLS_TRY_BIGGER_POOL */ - MEM_STATS_INC(err); - return NULL; - } - break; - } - } - if (poolnr > MEMP_POOL_LAST) { - LWIP_ASSERT("mem_malloc(): no pool is that big!", 0); - MEM_STATS_INC(err); - return NULL; - } - - /* save the pool number this element came from */ - element->poolnr = poolnr; - /* and return a pointer to the memory directly after the struct memp_malloc_helper */ - ret = (u8_t*)element + LWIP_MEM_ALIGN_SIZE(sizeof(struct memp_malloc_helper)); - -#if MEMP_OVERFLOW_CHECK || (LWIP_STATS && MEM_STATS) - /* truncating to u16_t is safe because struct memp_desc::size is u16_t */ - element->size = (u16_t)size; - MEM_STATS_INC_USED(used, element->size); -#endif /* MEMP_OVERFLOW_CHECK || (LWIP_STATS && MEM_STATS) */ -#if MEMP_OVERFLOW_CHECK - /* initialize unused memory (diff between requested size and selected pool's size) */ - memset((u8_t*)ret + size, 0xcd, memp_pools[poolnr]->size - size); -#endif /* MEMP_OVERFLOW_CHECK */ - return ret; -} - -/** - * Free memory previously allocated by mem_malloc. Loads the pool number - * and calls memp_free with that pool number to put the element back into - * its pool - * - * @param rmem the memory element to free - */ -void -mem_free(void *rmem) -{ - struct memp_malloc_helper *hmem; - - LWIP_ASSERT("rmem != NULL", (rmem != NULL)); - LWIP_ASSERT("rmem == MEM_ALIGN(rmem)", (rmem == LWIP_MEM_ALIGN(rmem))); - - /* get the original struct memp_malloc_helper */ - /* cast through void* to get rid of alignment warnings */ - hmem = (struct memp_malloc_helper*)(void*)((u8_t*)rmem - LWIP_MEM_ALIGN_SIZE(sizeof(struct memp_malloc_helper))); - - LWIP_ASSERT("hmem != NULL", (hmem != NULL)); - LWIP_ASSERT("hmem == MEM_ALIGN(hmem)", (hmem == LWIP_MEM_ALIGN(hmem))); - LWIP_ASSERT("hmem->poolnr < MEMP_MAX", (hmem->poolnr < MEMP_MAX)); - - MEM_STATS_DEC_USED(used, hmem->size); -#if MEMP_OVERFLOW_CHECK - { - u16_t i; - LWIP_ASSERT("MEM_USE_POOLS: invalid chunk size", - hmem->size <= memp_pools[hmem->poolnr]->size); - /* check that unused memory remained untouched (diff between requested size and selected pool's size) */ - for (i = hmem->size; i < memp_pools[hmem->poolnr]->size; i++) { - u8_t data = *((u8_t*)rmem + i); - LWIP_ASSERT("MEM_USE_POOLS: mem overflow detected", data == 0xcd); - } - } -#endif /* MEMP_OVERFLOW_CHECK */ - - /* and put it in the pool we saved earlier */ - memp_free(hmem->poolnr, hmem); -} - -#else /* MEM_USE_POOLS */ -/* lwIP replacement for your libc malloc() */ - -/** - * The heap is made up as a list of structs of this type. - * This does not have to be aligned since for getting its size, - * we only use the macro SIZEOF_STRUCT_MEM, which automatically aligns. - */ -struct mem { - /** index (-> ram[next]) of the next struct */ - mem_size_t next; - /** index (-> ram[prev]) of the previous struct */ - mem_size_t prev; - /** 1: this area is used; 0: this area is unused */ - u8_t used; -}; - -/** All allocated blocks will be MIN_SIZE bytes big, at least! - * MIN_SIZE can be overridden to suit your needs. Smaller values save space, - * larger values could prevent too small blocks to fragment the RAM too much. */ -#ifndef MIN_SIZE -#define MIN_SIZE 12 -#endif /* MIN_SIZE */ -/* some alignment macros: we define them here for better source code layout */ -#define MIN_SIZE_ALIGNED LWIP_MEM_ALIGN_SIZE(MIN_SIZE) -#define SIZEOF_STRUCT_MEM LWIP_MEM_ALIGN_SIZE(sizeof(struct mem)) -#define MEM_SIZE_ALIGNED LWIP_MEM_ALIGN_SIZE(MEM_SIZE) - -/** If you want to relocate the heap to external memory, simply define - * LWIP_RAM_HEAP_POINTER as a void-pointer to that location. - * If so, make sure the memory at that location is big enough (see below on - * how that space is calculated). */ -#ifndef LWIP_RAM_HEAP_POINTER -/** the heap. we need one struct mem at the end and some room for alignment */ -LWIP_DECLARE_MEMORY_ALIGNED(ram_heap, MEM_SIZE_ALIGNED + (2U*SIZEOF_STRUCT_MEM)); -#define LWIP_RAM_HEAP_POINTER ram_heap -#endif /* LWIP_RAM_HEAP_POINTER */ - -/** pointer to the heap (ram_heap): for alignment, ram is now a pointer instead of an array */ -static u8_t *ram; -/** the last entry, always unused! */ -static struct mem *ram_end; -/** pointer to the lowest free block, this is used for faster search */ -static struct mem *lfree; - -/** concurrent access protection */ -#if !NO_SYS -static sys_mutex_t mem_mutex; -#endif - -#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT - -static volatile u8_t mem_free_count; - -/* Allow mem_free from other (e.g. interrupt) context */ -#define LWIP_MEM_FREE_DECL_PROTECT() SYS_ARCH_DECL_PROTECT(lev_free) -#define LWIP_MEM_FREE_PROTECT() SYS_ARCH_PROTECT(lev_free) -#define LWIP_MEM_FREE_UNPROTECT() SYS_ARCH_UNPROTECT(lev_free) -#define LWIP_MEM_ALLOC_DECL_PROTECT() SYS_ARCH_DECL_PROTECT(lev_alloc) -#define LWIP_MEM_ALLOC_PROTECT() SYS_ARCH_PROTECT(lev_alloc) -#define LWIP_MEM_ALLOC_UNPROTECT() SYS_ARCH_UNPROTECT(lev_alloc) - -#else /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ - -/* Protect the heap only by using a semaphore */ -#define LWIP_MEM_FREE_DECL_PROTECT() -#define LWIP_MEM_FREE_PROTECT() sys_mutex_lock(&mem_mutex) -#define LWIP_MEM_FREE_UNPROTECT() sys_mutex_unlock(&mem_mutex) -/* mem_malloc is protected using semaphore AND LWIP_MEM_ALLOC_PROTECT */ -#define LWIP_MEM_ALLOC_DECL_PROTECT() -#define LWIP_MEM_ALLOC_PROTECT() -#define LWIP_MEM_ALLOC_UNPROTECT() - -#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ - - -/** - * "Plug holes" by combining adjacent empty struct mems. - * After this function is through, there should not exist - * one empty struct mem pointing to another empty struct mem. - * - * @param mem this points to a struct mem which just has been freed - * @internal this function is only called by mem_free() and mem_trim() - * - * This assumes access to the heap is protected by the calling function - * already. - */ -static void -plug_holes(struct mem *mem) -{ - struct mem *nmem; - struct mem *pmem; - - LWIP_ASSERT("plug_holes: mem >= ram", (u8_t *)mem >= ram); - LWIP_ASSERT("plug_holes: mem < ram_end", (u8_t *)mem < (u8_t *)ram_end); - LWIP_ASSERT("plug_holes: mem->used == 0", mem->used == 0); - - /* plug hole forward */ - LWIP_ASSERT("plug_holes: mem->next <= MEM_SIZE_ALIGNED", mem->next <= MEM_SIZE_ALIGNED); - - nmem = (struct mem *)(void *)&ram[mem->next]; - if (mem != nmem && nmem->used == 0 && (u8_t *)nmem != (u8_t *)ram_end) { - /* if mem->next is unused and not end of ram, combine mem and mem->next */ - if (lfree == nmem) { - lfree = mem; - } - mem->next = nmem->next; - ((struct mem *)(void *)&ram[nmem->next])->prev = (mem_size_t)((u8_t *)mem - ram); - } - - /* plug hole backward */ - pmem = (struct mem *)(void *)&ram[mem->prev]; - if (pmem != mem && pmem->used == 0) { - /* if mem->prev is unused, combine mem and mem->prev */ - if (lfree == mem) { - lfree = pmem; - } - pmem->next = mem->next; - ((struct mem *)(void *)&ram[mem->next])->prev = (mem_size_t)((u8_t *)pmem - ram); - } -} - -/** - * Zero the heap and initialize start, end and lowest-free - */ -void -mem_init(void) -{ - struct mem *mem; - - LWIP_ASSERT("Sanity check alignment", - (SIZEOF_STRUCT_MEM & (MEM_ALIGNMENT-1)) == 0); - - /* align the heap */ - ram = (u8_t *)LWIP_MEM_ALIGN(LWIP_RAM_HEAP_POINTER); - /* initialize the start of the heap */ - mem = (struct mem *)(void *)ram; - mem->next = MEM_SIZE_ALIGNED; - mem->prev = 0; - mem->used = 0; - /* initialize the end of the heap */ - ram_end = (struct mem *)(void *)&ram[MEM_SIZE_ALIGNED]; - ram_end->used = 1; - ram_end->next = MEM_SIZE_ALIGNED; - ram_end->prev = MEM_SIZE_ALIGNED; - - /* initialize the lowest-free pointer to the start of the heap */ - lfree = (struct mem *)(void *)ram; - - MEM_STATS_AVAIL(avail, MEM_SIZE_ALIGNED); - - if (sys_mutex_new(&mem_mutex) != ERR_OK) { - LWIP_ASSERT("failed to create mem_mutex", 0); - } -} - -/** - * Put a struct mem back on the heap - * - * @param rmem is the data portion of a struct mem as returned by a previous - * call to mem_malloc() - */ -void -mem_free(void *rmem) -{ - struct mem *mem; - LWIP_MEM_FREE_DECL_PROTECT(); - - if (rmem == NULL) { - LWIP_DEBUGF(MEM_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("mem_free(p == NULL) was called.\n")); - return; - } - LWIP_ASSERT("mem_free: sanity check alignment", (((mem_ptr_t)rmem) & (MEM_ALIGNMENT-1)) == 0); - - LWIP_ASSERT("mem_free: legal memory", (u8_t *)rmem >= (u8_t *)ram && - (u8_t *)rmem < (u8_t *)ram_end); - - if ((u8_t *) rmem < ram || (u8_t *) rmem >= (u8_t *) ram_end) - { - SYS_ARCH_DECL_PROTECT(lev); - LWIP_DEBUGF(MEM_DEBUG | LWIP_DBG_LEVEL_SEVERE, ("mem_free: illegal memory\n")); - /* protect mem stats from concurrent access */ - SYS_ARCH_PROTECT(lev); - MEM_STATS_INC(illegal); - SYS_ARCH_UNPROTECT(lev); - return; - } - /* protect the heap from concurrent access */ - LWIP_MEM_FREE_PROTECT(); - /* Get the corresponding struct mem ... */ - /* cast through void* to get rid of alignment warnings */ - mem = (struct mem *)(void *)((u8_t *)rmem - SIZEOF_STRUCT_MEM); - /* ... which has to be in a used state ... */ - LWIP_ASSERT("mem_free: mem->used", mem->used); - /* ... and is now unused. */ - mem->used = 0; - - if (mem < lfree) { - /* the newly freed struct is now the lowest */ - lfree = mem; - } - - MEM_STATS_DEC_USED(used, mem->next - (mem_size_t)(((u8_t *)mem - ram))); - - /* finally, see if prev or next are free also */ - plug_holes(mem); -#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT - mem_free_count = 1; -#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ - LWIP_MEM_FREE_UNPROTECT(); -} - -/** - * Shrink memory returned by mem_malloc(). - * - * @param rmem pointer to memory allocated by mem_malloc the is to be shrinked - * @param new_size required size after shrinking (needs to be smaller than or - * equal to the previous size) - * @return for compatibility reasons: is always == rmem, at the moment - * or NULL if newsize is > old size, in which case rmem is NOT touched - * or freed! - */ -void * -mem_trim(void *rmem, mem_size_t new_size) -{ - mem_size_t size, newsize; - mem_size_t ptr, ptr2; - struct mem *mem, *mem2; - /* use the FREE_PROTECT here: it protects with sem OR SYS_ARCH_PROTECT */ - LWIP_MEM_FREE_DECL_PROTECT(); - - /* Expand the size of the allocated memory region so that we can - adjust for alignment. */ - newsize = (mem_size_t)LWIP_MEM_ALIGN_SIZE(new_size); - if ((newsize > MEM_SIZE_ALIGNED) || (newsize < new_size)) { - return NULL; - } - - if (newsize < MIN_SIZE_ALIGNED) { - /* every data block must be at least MIN_SIZE_ALIGNED long */ - newsize = MIN_SIZE_ALIGNED; - } - - LWIP_ASSERT("mem_trim: legal memory", (u8_t *)rmem >= (u8_t *)ram && - (u8_t *)rmem < (u8_t *)ram_end); - - if ((u8_t *) rmem < ram || (u8_t *) rmem >= (u8_t *) ram_end) - { - SYS_ARCH_DECL_PROTECT(lev); - LWIP_DEBUGF(MEM_DEBUG | LWIP_DBG_LEVEL_SEVERE, ("mem_trim: illegal memory\n")); - /* protect mem stats from concurrent access */ - SYS_ARCH_PROTECT(lev); - MEM_STATS_INC(illegal); - SYS_ARCH_UNPROTECT(lev); - return rmem; - } - /* Get the corresponding struct mem ... */ - /* cast through void* to get rid of alignment warnings */ - mem = (struct mem *)(void *)((u8_t *)rmem - SIZEOF_STRUCT_MEM); - /* ... and its offset pointer */ - ptr = (mem_size_t)((u8_t *)mem - ram); - - size = (mem_size_t)((mem_size_t)(mem->next - ptr) - SIZEOF_STRUCT_MEM); - LWIP_ASSERT("mem_trim can only shrink memory", newsize <= size); - if (newsize > size) { - /* not supported */ - return NULL; - } - if (newsize == size) { - /* No change in size, simply return */ - return rmem; - } - - /* protect the heap from concurrent access */ - LWIP_MEM_FREE_PROTECT(); - - mem2 = (struct mem *)(void *)&ram[mem->next]; - if (mem2->used == 0) { - /* The next struct is unused, we can simply move it at little */ - mem_size_t next; - /* remember the old next pointer */ - next = mem2->next; - /* create new struct mem which is moved directly after the shrinked mem */ - ptr2 = (mem_size_t)(ptr + SIZEOF_STRUCT_MEM + newsize); - if (lfree == mem2) { - lfree = (struct mem *)(void *)&ram[ptr2]; - } - mem2 = (struct mem *)(void *)&ram[ptr2]; - mem2->used = 0; - /* restore the next pointer */ - mem2->next = next; - /* link it back to mem */ - mem2->prev = ptr; - /* link mem to it */ - mem->next = ptr2; - /* last thing to restore linked list: as we have moved mem2, - * let 'mem2->next->prev' point to mem2 again. but only if mem2->next is not - * the end of the heap */ - if (mem2->next != MEM_SIZE_ALIGNED) { - ((struct mem *)(void *)&ram[mem2->next])->prev = ptr2; - } - MEM_STATS_DEC_USED(used, (size - newsize)); - /* no need to plug holes, we've already done that */ - } else if (newsize + SIZEOF_STRUCT_MEM + MIN_SIZE_ALIGNED <= size) { - /* Next struct is used but there's room for another struct mem with - * at least MIN_SIZE_ALIGNED of data. - * Old size ('size') must be big enough to contain at least 'newsize' plus a struct mem - * ('SIZEOF_STRUCT_MEM') with some data ('MIN_SIZE_ALIGNED'). - * @todo we could leave out MIN_SIZE_ALIGNED. We would create an empty - * region that couldn't hold data, but when mem->next gets freed, - * the 2 regions would be combined, resulting in more free memory */ - ptr2 = (mem_size_t)(ptr + SIZEOF_STRUCT_MEM + newsize); - mem2 = (struct mem *)(void *)&ram[ptr2]; - if (mem2 < lfree) { - lfree = mem2; - } - mem2->used = 0; - mem2->next = mem->next; - mem2->prev = ptr; - mem->next = ptr2; - if (mem2->next != MEM_SIZE_ALIGNED) { - ((struct mem *)(void *)&ram[mem2->next])->prev = ptr2; - } - MEM_STATS_DEC_USED(used, (size - newsize)); - /* the original mem->next is used, so no need to plug holes! */ - } - /* else { - next struct mem is used but size between mem and mem2 is not big enough - to create another struct mem - -> don't do anyhting. - -> the remaining space stays unused since it is too small - } */ -#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT - mem_free_count = 1; -#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ - LWIP_MEM_FREE_UNPROTECT(); - return rmem; -} - -/** - * Allocate a block of memory with a minimum of 'size' bytes. - * - * @param size_in is the minimum size of the requested block in bytes. - * @return pointer to allocated memory or NULL if no free memory was found. - * - * Note that the returned value will always be aligned (as defined by MEM_ALIGNMENT). - */ -void * -mem_malloc(mem_size_t size_in) -{ - mem_size_t ptr, ptr2, size; - struct mem *mem, *mem2; -#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT - u8_t local_mem_free_count = 0; -#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ - LWIP_MEM_ALLOC_DECL_PROTECT(); - - if (size_in == 0) { - return NULL; - } - - /* Expand the size of the allocated memory region so that we can - adjust for alignment. */ - size = (mem_size_t)LWIP_MEM_ALIGN_SIZE(size_in); - if ((size > MEM_SIZE_ALIGNED) || - (size < size_in)) { - return NULL; - } - - if (size < MIN_SIZE_ALIGNED) { - /* every data block must be at least MIN_SIZE_ALIGNED long */ - size = MIN_SIZE_ALIGNED; - } - - /* protect the heap from concurrent access */ - sys_mutex_lock(&mem_mutex); - LWIP_MEM_ALLOC_PROTECT(); -#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT - /* run as long as a mem_free disturbed mem_malloc or mem_trim */ - do { - local_mem_free_count = 0; -#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ - - /* Scan through the heap searching for a free block that is big enough, - * beginning with the lowest free block. - */ - for (ptr = (mem_size_t)((u8_t *)lfree - ram); ptr < MEM_SIZE_ALIGNED - size; - ptr = ((struct mem *)(void *)&ram[ptr])->next) { - mem = (struct mem *)(void *)&ram[ptr]; -#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT - mem_free_count = 0; - LWIP_MEM_ALLOC_UNPROTECT(); - /* allow mem_free or mem_trim to run */ - LWIP_MEM_ALLOC_PROTECT(); - if (mem_free_count != 0) { - /* If mem_free or mem_trim have run, we have to restart since they - could have altered our current struct mem. */ - local_mem_free_count = 1; - break; - } -#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ - - if ((!mem->used) && - (mem->next - (ptr + SIZEOF_STRUCT_MEM)) >= size) { - /* mem is not used and at least perfect fit is possible: - * mem->next - (ptr + SIZEOF_STRUCT_MEM) gives us the 'user data size' of mem */ - - if (mem->next - (ptr + SIZEOF_STRUCT_MEM) >= (size + SIZEOF_STRUCT_MEM + MIN_SIZE_ALIGNED)) { - /* (in addition to the above, we test if another struct mem (SIZEOF_STRUCT_MEM) containing - * at least MIN_SIZE_ALIGNED of data also fits in the 'user data space' of 'mem') - * -> split large block, create empty remainder, - * remainder must be large enough to contain MIN_SIZE_ALIGNED data: if - * mem->next - (ptr + (2*SIZEOF_STRUCT_MEM)) == size, - * struct mem would fit in but no data between mem2 and mem2->next - * @todo we could leave out MIN_SIZE_ALIGNED. We would create an empty - * region that couldn't hold data, but when mem->next gets freed, - * the 2 regions would be combined, resulting in more free memory - */ - ptr2 = (mem_size_t)(ptr + SIZEOF_STRUCT_MEM + size); - /* create mem2 struct */ - mem2 = (struct mem *)(void *)&ram[ptr2]; - mem2->used = 0; - mem2->next = mem->next; - mem2->prev = ptr; - /* and insert it between mem and mem->next */ - mem->next = ptr2; - mem->used = 1; - - if (mem2->next != MEM_SIZE_ALIGNED) { - ((struct mem *)(void *)&ram[mem2->next])->prev = ptr2; - } - MEM_STATS_INC_USED(used, (size + SIZEOF_STRUCT_MEM)); - } else { - /* (a mem2 struct does no fit into the user data space of mem and mem->next will always - * be used at this point: if not we have 2 unused structs in a row, plug_holes should have - * take care of this). - * -> near fit or exact fit: do not split, no mem2 creation - * also can't move mem->next directly behind mem, since mem->next - * will always be used at this point! - */ - mem->used = 1; - MEM_STATS_INC_USED(used, mem->next - (mem_size_t)((u8_t *)mem - ram)); - } -#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT -mem_malloc_adjust_lfree: -#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ - if (mem == lfree) { - struct mem *cur = lfree; - /* Find next free block after mem and update lowest free pointer */ - while (cur->used && cur != ram_end) { -#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT - mem_free_count = 0; - LWIP_MEM_ALLOC_UNPROTECT(); - /* prevent high interrupt latency... */ - LWIP_MEM_ALLOC_PROTECT(); - if (mem_free_count != 0) { - /* If mem_free or mem_trim have run, we have to restart since they - could have altered our current struct mem or lfree. */ - goto mem_malloc_adjust_lfree; - } -#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ - cur = (struct mem *)(void *)&ram[cur->next]; - } - lfree = cur; - LWIP_ASSERT("mem_malloc: !lfree->used", ((lfree == ram_end) || (!lfree->used))); - } - LWIP_MEM_ALLOC_UNPROTECT(); - sys_mutex_unlock(&mem_mutex); - LWIP_ASSERT("mem_malloc: allocated memory not above ram_end.", - (mem_ptr_t)mem + SIZEOF_STRUCT_MEM + size <= (mem_ptr_t)ram_end); - LWIP_ASSERT("mem_malloc: allocated memory properly aligned.", - ((mem_ptr_t)mem + SIZEOF_STRUCT_MEM) % MEM_ALIGNMENT == 0); - LWIP_ASSERT("mem_malloc: sanity check alignment", - (((mem_ptr_t)mem) & (MEM_ALIGNMENT-1)) == 0); - - return (u8_t *)mem + SIZEOF_STRUCT_MEM; - } - } -#if LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT - /* if we got interrupted by a mem_free, try again */ - } while (local_mem_free_count != 0); -#endif /* LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT */ - LWIP_DEBUGF(MEM_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("mem_malloc: could not allocate %"S16_F" bytes\n", (s16_t)size)); - MEM_STATS_INC(err); - LWIP_MEM_ALLOC_UNPROTECT(); - sys_mutex_unlock(&mem_mutex); - return NULL; -} - -#endif /* MEM_USE_POOLS */ - -#if MEM_LIBC_MALLOC && (!LWIP_STATS || !MEM_STATS) -void * -mem_calloc(mem_size_t count, mem_size_t size) -{ - return mem_clib_calloc(count, size); -} - -#else /* MEM_LIBC_MALLOC && (!LWIP_STATS || !MEM_STATS) */ -/** - * Contiguously allocates enough space for count objects that are size bytes - * of memory each and returns a pointer to the allocated memory. - * - * The allocated memory is filled with bytes of value zero. - * - * @param count number of objects to allocate - * @param size size of the objects to allocate - * @return pointer to allocated memory / NULL pointer if there is an error - */ -void * -mem_calloc(mem_size_t count, mem_size_t size) -{ - void *p; - - /* allocate 'count' objects of size 'size' */ - p = mem_malloc(count * size); - if (p) { - /* zero the memory */ - memset(p, 0, (size_t)count * (size_t)size); - } - return p; -} -#endif /* MEM_LIBC_MALLOC && (!LWIP_STATS || !MEM_STATS) */ diff --git a/third_party/lwip/repo/lwip/src/core/memp.c b/third_party/lwip/repo/lwip/src/core/memp.c deleted file mode 100644 index b6d266a379f111..00000000000000 --- a/third_party/lwip/repo/lwip/src/core/memp.c +++ /dev/null @@ -1,636 +0,0 @@ -/** - * @file - * Dynamic pool memory manager - * - * lwIP has dedicated pools for many structures (netconn, protocol control blocks, - * packet buffers, ...). All these pools are managed here. - * - * @defgroup mempool Memory pools - * @ingroup infrastructure - * Custom memory pools - - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ - -#include "lwip/opt.h" - -#include "lwip/memp.h" -#include "lwip/sys.h" -#include "lwip/stats.h" - -#include - -/* Make sure we include everything we need for size calculation required by memp_std.h */ -#include "lwip/pbuf.h" -#include "lwip/raw.h" -#include "lwip/udp.h" -#include "lwip/tcp.h" -#include "lwip/priv/tcp_priv.h" -#include "lwip/ip4_frag.h" -#include "lwip/netbuf.h" -#include "lwip/api.h" -#include "lwip/priv/tcpip_priv.h" -#include "lwip/priv/api_msg.h" -#include "lwip/sockets.h" -#include "lwip/netifapi.h" -#include "lwip/etharp.h" -#include "lwip/igmp.h" -#include "lwip/timeouts.h" -/* needed by default MEMP_NUM_SYS_TIMEOUT */ -#include "netif/ppp/ppp_opts.h" -#include "lwip/netdb.h" -#include "lwip/dns.h" -#include "lwip/priv/nd6_priv.h" -#include "lwip/ip6_frag.h" -#include "lwip/mld6.h" - -#define LWIP_MEMPOOL(name,num,size,desc) LWIP_MEMPOOL_DECLARE(name,num,size,desc) -#include "lwip/priv/memp_std.h" - -const struct memp_desc* const memp_pools[MEMP_MAX] = { -#define LWIP_MEMPOOL(name,num,size,desc) &memp_ ## name, -#include "lwip/priv/memp_std.h" -}; - -#ifdef LWIP_HOOK_FILENAME -#include LWIP_HOOK_FILENAME -#endif - -#if MEMP_MEM_MALLOC && MEMP_OVERFLOW_CHECK >= 2 -#undef MEMP_OVERFLOW_CHECK -/* MEMP_OVERFLOW_CHECK >= 2 does not work with MEMP_MEM_MALLOC, use 1 instead */ -#define MEMP_OVERFLOW_CHECK 1 -#endif - -/** This array holds the element sizes of each pool. */ -#if !MEM_USE_POOLS && !MEMP_MEM_MALLOC && !LWIP_PBUF_FROM_CUSTOM_POOLS -static -#endif -const u16_t memp_sizes[MEMP_MAX] = { -#define LWIP_MEMPOOL(name,num,size,desc) LWIP_MEM_ALIGN_SIZE(size), -#include "lwip/priv/memp_std.h" -}; - -#if !MEMP_MEM_MALLOC /* don't build if not configured for use in lwipopts.h */ - -/** When using variable pbuf pools, pbuf_alloc will start scanning for pbufs at the - * highest indexed pbuf pool (PBUF_CUSTOM_POOL_IDX_START), which holds the smallest pbufs. - * It will look through the list of pbuf pools for a suitable pool to draw from that has a free - * pbuf until it passes MEMP_PBUF_POOL, which holds the largest pbufs. - **/ -#if LWIP_PBUF_FROM_CUSTOM_POOLS -_Static_assert ((PBUF_CUSTOM_POOL_IDX_START > PBUF_CUSTOM_POOL_IDX_END), "PBUF_CUSTOM_POOL_IDX_START must be greater than PBUF_CUSTOM_POOL_IDX_END"); -#define MEMP_IS_PBUF_POOL(type) (type <= PBUF_CUSTOM_POOL_IDX_START && type >= PBUF_CUSTOM_POOL_IDX_END) -#define MEMP_PBUF_POOL_HIGHWATERMARK(type) (PBUF_CUSTOM_POOL_IDX_START - type) -#else -#define MEMP_IS_PBUF_POOL(type) (type == MEMP_PBUF_POOL) -#define MEMP_PBUF_POOL_HIGHWATERMARK(type) (type) -#endif - -#define sys_profile_interval_set_pbuf_highwatermark(...) - -#if MEMP_SANITY_CHECK && !MEMP_MEM_MALLOC -/** - * Check that memp-lists don't form a circle, using "Floyd's cycle-finding algorithm". - */ -static int -memp_sanity(const struct memp_desc *desc) -{ - struct memp *t, *h; - - t = *desc->tab; - if (t != NULL) { - for (h = t->next; (t != NULL) && (h != NULL); t = t->next, - h = ((h->next != NULL) ? h->next->next : NULL)) { - if (t == h) { - return 0; - } - } - } - - return 1; -} -#endif /* MEMP_SANITY_CHECK && !MEMP_MEM_MALLOC */ - -#if MEMP_OVERFLOW_CHECK -/** - * Check if a memp element was victim of an overflow - * (e.g. the restricted area after it has been altered) - * - * @param p the memp element to check - * @param desc the pool p comes from - */ -static void -memp_overflow_check_element_overflow(struct memp *p, const struct memp_desc *desc) -{ -#if MEMP_SANITY_REGION_AFTER_ALIGNED > 0 - u16_t k; - u8_t *m; - m = (u8_t*)p + MEMP_SIZE + desc->size; - for (k = 0; k < MEMP_SANITY_REGION_AFTER_ALIGNED; k++) { - if (m[k] != 0xcd) { - char errstr[128] = "detected memp overflow in pool "; - strcat(errstr, desc->desc); - LWIP_ASSERT(errstr, 0); - } - } -#else /* MEMP_SANITY_REGION_AFTER_ALIGNED > 0 */ - LWIP_UNUSED_ARG(p); - LWIP_UNUSED_ARG(desc); -#endif /* MEMP_SANITY_REGION_AFTER_ALIGNED > 0 */ -} - -/** - * Check if a memp element was victim of an underflow - * (e.g. the restricted area before it has been altered) - * - * @param p the memp element to check - * @param desc the pool p comes from - */ -static void -memp_overflow_check_element_underflow(struct memp *p, const struct memp_desc *desc) -{ -#if MEMP_SANITY_REGION_BEFORE_ALIGNED > 0 - u16_t k; - u8_t *m; - m = (u8_t*)p + MEMP_SIZE - MEMP_SANITY_REGION_BEFORE_ALIGNED; - for (k = 0; k < MEMP_SANITY_REGION_BEFORE_ALIGNED; k++) { - if (m[k] != 0xcd) { - char errstr[128] = "detected memp underflow in pool "; - strcat(errstr, desc->desc); - LWIP_ASSERT(errstr, 0); - } - } -#else /* MEMP_SANITY_REGION_BEFORE_ALIGNED > 0 */ - LWIP_UNUSED_ARG(p); - LWIP_UNUSED_ARG(desc); -#endif /* MEMP_SANITY_REGION_BEFORE_ALIGNED > 0 */ -} - -/** - * Initialize the restricted area of on memp element. - */ -static void -memp_overflow_init_element(struct memp *p, const struct memp_desc *desc) -{ -#if MEMP_SANITY_REGION_BEFORE_ALIGNED > 0 || MEMP_SANITY_REGION_AFTER_ALIGNED > 0 - u8_t *m; -#if MEMP_SANITY_REGION_BEFORE_ALIGNED > 0 - m = (u8_t*)p + MEMP_SIZE - MEMP_SANITY_REGION_BEFORE_ALIGNED; - memset(m, 0xcd, MEMP_SANITY_REGION_BEFORE_ALIGNED); -#endif -#if MEMP_SANITY_REGION_AFTER_ALIGNED > 0 - m = (u8_t*)p + MEMP_SIZE + desc->size; - memset(m, 0xcd, MEMP_SANITY_REGION_AFTER_ALIGNED); -#endif -#else /* MEMP_SANITY_REGION_BEFORE_ALIGNED > 0 || MEMP_SANITY_REGION_AFTER_ALIGNED > 0 */ - LWIP_UNUSED_ARG(p); - LWIP_UNUSED_ARG(desc); -#endif /* MEMP_SANITY_REGION_BEFORE_ALIGNED > 0 || MEMP_SANITY_REGION_AFTER_ALIGNED > 0 */ -} - -#if MEMP_OVERFLOW_CHECK >= 2 -/** - * Do an overflow check for all elements in every pool. - * - * @see memp_overflow_check_element for a description of the check - */ -static void -memp_overflow_check_all(void) -{ - u16_t i, j; - struct memp *p; - SYS_ARCH_DECL_PROTECT(old_level); - SYS_ARCH_PROTECT(old_level); - - for (i = 0; i < MEMP_MAX; ++i) { - p = (struct memp*)LWIP_MEM_ALIGN(memp_pools[i]->base); - for (j = 0; j < memp_pools[i]->num; ++j) { - memp_overflow_check_element_overflow(p, memp_pools[i]); - memp_overflow_check_element_underflow(p, memp_pools[i]); - p = LWIP_ALIGNMENT_CAST(struct memp*, ((u8_t*)p + MEMP_SIZE + memp_pools[i]->size + MEMP_SANITY_REGION_AFTER_ALIGNED)); - } - } - SYS_ARCH_UNPROTECT(old_level); -} -#endif /* MEMP_OVERFLOW_CHECK >= 2 */ -#endif /* MEMP_OVERFLOW_CHECK */ - -/** - * Initialize custom memory pool. - * Related functions: memp_malloc_pool, memp_free_pool - * - * @param desc pool to initialize - */ -void -memp_init_pool(const struct memp_desc *desc) -{ -#if MEMP_MEM_MALLOC - LWIP_UNUSED_ARG(desc); -#else - int i; - struct memp *memp; - - *desc->tab = NULL; - memp = (struct memp*)LWIP_MEM_ALIGN(desc->base); - /* create a linked list of memp elements */ - for (i = 0; i < desc->num; ++i) { - memp->next = *desc->tab; - *desc->tab = memp; -#if MEMP_OVERFLOW_CHECK - memp_overflow_init_element(memp, desc); -#endif /* MEMP_OVERFLOW_CHECK */ - /* cast through void* to get rid of alignment warnings */ - memp = (struct memp *)(void *)((u8_t *)memp + MEMP_SIZE + desc->size -#if MEMP_OVERFLOW_CHECK - + MEMP_SANITY_REGION_AFTER_ALIGNED -#endif - ); - } -#if MEMP_STATS - desc->stats->avail = desc->num; -#endif /* MEMP_STATS */ -#endif /* !MEMP_MEM_MALLOC */ - -#if MEMP_STATS && (defined(LWIP_DEBUG) || LWIP_STATS_DISPLAY) - desc->stats->name = desc->desc; -#endif /* MEMP_STATS && (defined(LWIP_DEBUG) || LWIP_STATS_DISPLAY) */ -} - -/** - * Check if the pool is not empty - */ -u8_t memp_is_not_empty (memp_t type) -{ - return (memp_pools[type]->tab != NULL); -} - -/** - * Initializes lwIP built-in pools. - * Related functions: memp_malloc, memp_free - * - * Carves out memp_memory into linked lists for each pool-type. - */ -void -memp_init(void) -{ - u16_t i; -#if LWIP_PBUF_FROM_CUSTOM_POOLS - u16_t j; -#endif // LWIP_PBUF_FROM_CUSTOM_POOLS - - /* for every pool: */ - for (i = 0; i < LWIP_ARRAYSIZE(memp_pools); i++) { - memp_init_pool(memp_pools[i]); - -#if LWIP_STATS && MEMP_STATS - lwip_stats.memp[i] = memp_pools[i]->stats; -#endif - } - -#if MEMP_OVERFLOW_CHECK >= 2 - /* check everything a first time to see if it worked */ - memp_overflow_check_all(); -#endif /* MEMP_OVERFLOW_CHECK >= 2 */ - -#if LWIP_PBUF_FROM_CUSTOM_POOLS - /* Verify that custom pools that contain PBUFs are laid out - * in decreasing order by size */ - j = 0; - i = PBUF_CUSTOM_POOL_IDX_START; - while (1) { - LWIP_ASSERT("memp_init: PBUF pool size ordering incorrect", - memp_sizes[i] > j); - j = memp_sizes[i]; - if (i == PBUF_CUSTOM_POOL_IDX_END) { - break; - } - i--; - } -#endif - -#if MEMP_OVERFLOW_CHECK >= 2 - /* check everything a first time to see if it worked */ - memp_overflow_check_all(); -#endif /* MEMP_OVERFLOW_CHECK >= 2 */ -} - -static void* -#if !MEMP_OVERFLOW_CHECK -do_memp_malloc_pool(const struct memp_desc *desc) -#else -do_memp_malloc_pool_fn(const struct memp_desc *desc, const char* file, const int line) -#endif -{ - struct memp *memp; - SYS_ARCH_DECL_PROTECT(old_level); - -#if MEMP_MEM_MALLOC - memp = (struct memp *)mem_malloc(MEMP_SIZE + MEMP_ALIGN_SIZE(desc->size)); - SYS_ARCH_PROTECT(old_level); -#else /* MEMP_MEM_MALLOC */ - SYS_ARCH_PROTECT(old_level); - - memp = *desc->tab; -#endif /* MEMP_MEM_MALLOC */ - - if (memp != NULL) { -#if !MEMP_MEM_MALLOC -#if MEMP_OVERFLOW_CHECK == 1 - memp_overflow_check_element_overflow(memp, desc); - memp_overflow_check_element_underflow(memp, desc); -#endif /* MEMP_OVERFLOW_CHECK */ - - *desc->tab = memp->next; -#if MEMP_OVERFLOW_CHECK - memp->next = NULL; -#endif /* MEMP_OVERFLOW_CHECK */ -#endif /* !MEMP_MEM_MALLOC */ -#if MEMP_OVERFLOW_CHECK - memp->file = file; - memp->line = line; -#if MEMP_MEM_MALLOC - memp_overflow_init_element(memp, desc); -#endif /* MEMP_MEM_MALLOC */ -#endif /* MEMP_OVERFLOW_CHECK */ - LWIP_ASSERT("memp_malloc: memp properly aligned", - ((mem_ptr_t)memp % MEM_ALIGNMENT) == 0); -#if MEMP_STATS - desc->stats->used++; - if (desc->stats->used > desc->stats->max) { - desc->stats->max = desc->stats->used; - } -#endif - - SYS_ARCH_UNPROTECT(old_level); - /* cast through u8_t* to get rid of alignment warnings */ - return ((u8_t*)memp + MEMP_SIZE); - } else { - LWIP_DEBUGF(MEMP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("memp_malloc: out of memory in pool %s\n", desc->desc)); -#if MEMP_STATS - desc->stats->err++; -#endif - } - - SYS_ARCH_UNPROTECT(old_level); - return NULL; -} - -/** - * Get an element from a custom pool. - * - * @param desc the pool to get an element from - * - * @return a pointer to the allocated memory or a NULL pointer on error - */ -void * -#if !MEMP_OVERFLOW_CHECK -memp_malloc_pool(const struct memp_desc *desc) -#else -memp_malloc_pool_fn(const struct memp_desc *desc, const char* file, const int line) -#endif -{ - LWIP_ASSERT("invalid pool desc", desc != NULL); - if (desc == NULL) { - return NULL; - } - -#if !MEMP_OVERFLOW_CHECK - return do_memp_malloc_pool(desc); -#else - return do_memp_malloc_pool_fn(desc, file, line); -#endif -} - -#if (MEMP_DEBUG | LWIP_DBG_TRACE) -#if LWIP_PBUF_FROM_CUSTOM_POOLS -int num_used_pool[PBUF_CUSTOM_POOL_IDX_START - PBUF_CUSTOM_POOL_IDX_END + 1] = {0}; -#else -int num_used_pool = 0; -#endif - -static int *get_num_used_pool_ptr(memp_t type) -{ - if (MEMP_IS_PBUF_POOL(type)) { -#if LWIP_PBUF_FROM_CUSTOM_POOLS - return &num_used_pool[PBUF_CUSTOM_POOL_IDX_START - type]; -#else - return &num_used_pool; -#endif - } - return NULL; -} -#endif /* (MEMP_DEBUG | LWIP_DBG_TRACE) */ - -/** - * Get an element from a specific pool. - * - * @param type the pool to get an element from - * - * @return a pointer to the allocated memory or a NULL pointer on error - */ -void * -#if !MEMP_OVERFLOW_CHECK -memp_malloc(memp_t type) -#else -memp_malloc_fn(memp_t type, const char* file, const int line) -#endif -{ - void *memp; -#if (MEMP_DEBUG | LWIP_DBG_TRACE) - int *num_used_pool_ptr = get_num_used_pool_ptr(type); -#endif - - LWIP_ERROR("memp_malloc: type < MEMP_MAX", (type < MEMP_MAX), return NULL;); - -#if MEMP_OVERFLOW_CHECK >= 2 - memp_overflow_check_all(); -#endif /* MEMP_OVERFLOW_CHECK >= 2 */ - -#if !MEMP_OVERFLOW_CHECK - memp = do_memp_malloc_pool(memp_pools[type]); -#else - memp = do_memp_malloc_pool_fn(memp_pools[type], file, line); -#endif - -#if (MEMP_DEBUG | LWIP_DBG_TRACE) - if (!memp) { - LWIP_DEBUGF(MEMP_DEBUG | LWIP_DBG_TRACE, ("mm: out-of-mem in %s\n", memp_pools[type]->desc)); - if (LWIP_PERF && MEMP_IS_PBUF_POOL(type)) { - sys_profile_interval_set_pbuf_highwatermark((u32_t)(*num_used_pool_ptr), MEMP_PBUF_POOL_HIGHWATERMARK(type)); - } - } - else { - if (MEMP_IS_PBUF_POOL(type)) { - (*num_used_pool_ptr)++; - - if (LWIP_PERF) { - LWIP_DEBUGF(MEMP_DEBUG | LWIP_DBG_TRACE, ("mm:p++ = %d (%p) (%s)\n", *num_used_pool_ptr, memp, memp_pools[type]->desc)); - sys_profile_interval_set_pbuf_highwatermark((u32_t)(*num_used_pool_ptr), MEMP_PBUF_POOL_HIGHWATERMARK(type)); - } - } - } -#endif - - return memp; -} - -static void -do_memp_free_pool(const struct memp_desc* desc, void *mem) -{ - struct memp *memp; - SYS_ARCH_DECL_PROTECT(old_level); - - LWIP_ASSERT("memp_free: mem properly aligned", - ((mem_ptr_t)mem % MEM_ALIGNMENT) == 0); - - /* cast through void* to get rid of alignment warnings */ - memp = (struct memp *)(void *)((u8_t*)mem - MEMP_SIZE); - - SYS_ARCH_PROTECT(old_level); - -#if MEMP_OVERFLOW_CHECK == 1 - memp_overflow_check_element_overflow(memp, desc); - memp_overflow_check_element_underflow(memp, desc); -#endif /* MEMP_OVERFLOW_CHECK */ - -#if MEMP_STATS - desc->stats->used--; -#endif - -#if MEMP_MEM_MALLOC - LWIP_UNUSED_ARG(desc); - SYS_ARCH_UNPROTECT(old_level); - mem_free(memp); -#else /* MEMP_MEM_MALLOC */ - memp->next = *desc->tab; - *desc->tab = memp; - -#if MEMP_SANITY_CHECK - LWIP_ASSERT("memp sanity", memp_sanity(desc)); -#endif /* MEMP_SANITY_CHECK */ - - SYS_ARCH_UNPROTECT(old_level); -#endif /* !MEMP_MEM_MALLOC */ -} - -/** - * Put a custom pool element back into its pool. - * - * @param desc the pool where to put mem - * @param mem the memp element to free - */ -void -memp_free_pool(const struct memp_desc* desc, void *mem) -{ - LWIP_ASSERT("invalid pool desc", desc != NULL); - if ((desc == NULL) || (mem == NULL)) { - return; - } - - do_memp_free_pool(desc, mem); -} - -/** - * Put an element back into its pool. - * - * @param type the pool where to put mem - * @param mem the memp element to free - */ -void -memp_free(memp_t type, void *mem) -{ -#ifdef LWIP_HOOK_MEMP_AVAILABLE - struct memp *old_first; -#endif - -#if (MEMP_DEBUG | LWIP_DBG_TRACE) - int *num_used_pool_ptr = get_num_used_pool_ptr(type); -#endif - - LWIP_ERROR("memp_free: type < MEMP_MAX", (type < MEMP_MAX), return;); - - if (mem == NULL) { - return; - } - -#if MEMP_OVERFLOW_CHECK >= 2 - memp_overflow_check_all(); -#endif /* MEMP_OVERFLOW_CHECK >= 2 */ - -#ifdef LWIP_HOOK_MEMP_AVAILABLE - old_first = *memp_pools[type]->tab; -#endif - -#if (MEMP_DEBUG | LWIP_DBG_TRACE) - if (MEMP_IS_PBUF_POOL(type)) { - (*num_used_pool_ptr)--; - } -#endif - - do_memp_free_pool(memp_pools[type], mem); - -#ifdef LWIP_HOOK_MEMP_AVAILABLE - if (old_first == NULL) { - LWIP_HOOK_MEMP_AVAILABLE(type); - } -#endif - -#if (MEMP_DEBUG | LWIP_DBG_TRACE) - if (LWIP_PERF && MEMP_IS_PBUF_POOL(type)) { - LWIP_DEBUGF(MEMP_DEBUG | LWIP_DBG_TRACE, ("mf:p-- = %d (%p) (%s)\n", *num_used_pool_ptr, mem, memp_pools[type]->desc)); - sys_profile_interval_set_pbuf_highwatermark((u32_t)(*num_used_pool_ptr), MEMP_PBUF_POOL_HIGHWATERMARK(type)); - } -#endif -} - -#if MEMP_SEPARATE_POOLS -u16_t -memp_pbuf_index(memp_t type, const void *mem) -{ - if (MEMP_IS_PBUF_POOL(type)) { - size_t buf_size = MEMP_SIZE + MEMP_ALIGN_SIZE(memp_sizes[type]); - return ((u8_t *)mem - (u8_t *)LWIP_MEM_ALIGN(memp_pools[type]->base)) / buf_size; - } - return ~0; -} - -u16_t -memp_num_pbufs(memp_t type) -{ - return memp_pools[type]->num; -} -#endif /* MEMP_SEPARATE_POOLS */ - -#endif /* MEMP_MEM_MALLOC */ diff --git a/third_party/lwip/repo/lwip/src/core/netif.c b/third_party/lwip/repo/lwip/src/core/netif.c deleted file mode 100644 index 367ca8804578a7..00000000000000 --- a/third_party/lwip/repo/lwip/src/core/netif.c +++ /dev/null @@ -1,1517 +0,0 @@ -/** - * @file - * lwIP network interface abstraction - * - * @defgroup netif Network interface (NETIF) - * @ingroup callbackstyle_api - * - * @defgroup netif_ip4 IPv4 address handling - * @ingroup netif - * - * @defgroup netif_ip6 IPv6 address handling - * @ingroup netif - * - * @defgroup netif_cd Client data handling - * Store data (void*) on a netif for application usage. - * @see @ref LWIP_NUM_NETIF_CLIENT_DATA - * @ingroup netif - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - */ - -#include "lwip/opt.h" - -#include - -#include "lwip/def.h" -#include "lwip/ip_addr.h" -#include "lwip/ip6_addr.h" -#include "lwip/netif.h" -#include "lwip/priv/tcp_priv.h" -#include "lwip/udp.h" -#include "lwip/raw.h" -#include "lwip/snmp.h" -#include "lwip/igmp.h" -#include "lwip/etharp.h" -#include "lwip/stats.h" -#include "lwip/sys.h" -#include "lwip/ip.h" -#include "lwip/if.h" -#if ENABLE_LOOPBACK -#if LWIP_NETIF_LOOPBACK_MULTITHREADING -#include "lwip/tcpip.h" -#endif /* LWIP_NETIF_LOOPBACK_MULTITHREADING */ -#endif /* ENABLE_LOOPBACK */ - -#include "netif/ethernet.h" - -#if LWIP_AUTOIP -#include "lwip/autoip.h" -#endif /* LWIP_AUTOIP */ -#if LWIP_DHCP -#include "lwip/dhcp.h" -#endif /* LWIP_DHCP */ -#if LWIP_IPV6_DHCP6 -#include "lwip/dhcp6.h" -#endif /* LWIP_IPV6_DHCP6 */ -#if LWIP_IPV6_MLD -#include "lwip/mld6.h" -#endif /* LWIP_IPV6_MLD */ -#if LWIP_IPV6 -#include "lwip/nd6.h" -#endif - -#if LWIP_IPV6_ROUTE_TABLE_SUPPORT -#include "lwip/ip6_route_table.h" -#endif /* LWIP_IPV6_ROUTE_TABLE_SUPPORT */ - -#if LWIP_NETIF_STATUS_CALLBACK -#define NETIF_STATUS_CALLBACK(n) do{ if (n->status_callback) { (n->status_callback)(n); }}while(0) -#else -#define NETIF_STATUS_CALLBACK(n) -#endif /* LWIP_NETIF_STATUS_CALLBACK */ - -#if LWIP_NETIF_LINK_CALLBACK -#define NETIF_LINK_CALLBACK(n) do{ if (n->link_callback) { (n->link_callback)(n); }}while(0) -#else -#define NETIF_LINK_CALLBACK(n) -#endif /* LWIP_NETIF_LINK_CALLBACK */ - -struct netif *netif_list; -struct netif *netif_default; - -#define netif_index_to_num(index) ((index) - 1) -static u8_t netif_num; - -#if LWIP_NUM_NETIF_CLIENT_DATA > 0 -static u8_t netif_client_id; -#endif - -#define NETIF_REPORT_TYPE_IPV4 0x01 -#define NETIF_REPORT_TYPE_IPV6 0x02 -static void netif_issue_reports(struct netif* netif, u8_t report_type); - -#if LWIP_IPV6 -static err_t netif_null_output_ip6(struct netif *netif, struct pbuf *p, const ip6_addr_t *ipaddr); -#endif /* LWIP_IPV6 */ - -#if LWIP_HAVE_LOOPIF -#if LWIP_IPV4 -static err_t netif_loop_output_ipv4(struct netif *netif, struct pbuf *p, const ip4_addr_t* addr); -#endif -#if LWIP_IPV6 -static err_t netif_loop_output_ipv6(struct netif *netif, struct pbuf *p, const ip6_addr_t* addr); -#endif - - -static struct netif loop_netif; - -/** - * Initialize a lwip network interface structure for a loopback interface - * - * @param netif the lwip network interface structure for this loopif - * @return ERR_OK if the loopif is initialized - * ERR_MEM if private data couldn't be allocated - */ -static err_t -netif_loopif_init(struct netif *netif) -{ - /* initialize the snmp variables and counters inside the struct netif - * ifSpeed: no assumption can be made! - */ - MIB2_INIT_NETIF(netif, snmp_ifType_softwareLoopback, 0); - - netif->name[0] = 'l'; - netif->name[1] = 'o'; -#if LWIP_IPV4 - netif->output = netif_loop_output_ipv4; -#endif -#if LWIP_IPV6 - netif->output_ip6 = netif_loop_output_ipv6; -#endif -#if LWIP_LOOPIF_MULTICAST - netif->flags |= NETIF_FLAG_IGMP; -#endif - return ERR_OK; -} -#endif /* LWIP_HAVE_LOOPIF */ - -void -netif_init(void) -{ -#if LWIP_HAVE_LOOPIF -#if LWIP_IPV4 -#define LOOPIF_ADDRINIT &loop_ipaddr, &loop_netmask, &loop_gw, - ip4_addr_t loop_ipaddr, loop_netmask, loop_gw; - IP4_ADDR(&loop_gw, 127,0,0,1); - IP4_ADDR(&loop_ipaddr, 127,0,0,1); - IP4_ADDR(&loop_netmask, 255,0,0,0); -#else /* LWIP_IPV4 */ -#define LOOPIF_ADDRINIT -#endif /* LWIP_IPV4 */ - -#if NO_SYS - netif_add(&loop_netif, LOOPIF_ADDRINIT NULL, netif_loopif_init, ip_input); -#else /* NO_SYS */ - netif_add(&loop_netif, LOOPIF_ADDRINIT NULL, netif_loopif_init, tcpip_input); -#endif /* NO_SYS */ - -#if LWIP_IPV6 - IP_ADDR6_HOST(loop_netif.ip6_addr, 0, 0, 0, 0x00000001UL); - loop_netif.ip6_addr_state[0] = IP6_ADDR_VALID; -#endif /* LWIP_IPV6 */ - - netif_set_link_up(&loop_netif); - netif_set_up(&loop_netif); - -#endif /* LWIP_HAVE_LOOPIF */ -} - -void -netif_apply_pcb(struct netif *netif, struct ip_pcb *pcb) -{ - NETIF_SET_HWADDRHINT(netif, pcb?&(pcb->addr_hint)?NULL); -#if LWIP_MANAGEMENT_CHANNEL - netif->using_management_channel = pcb?!!ip_get_option(pcb,SOF_MANAGEMENT):0; -#endif -} - -/** - * @ingroup lwip_nosys - * Forwards a received packet for input processing with - * ethernet_input() or ip_input() depending on netif flags. - * Don't call directly, pass to netif_add() and call - * netif->input(). - * Only works if the netif driver correctly sets - * NETIF_FLAG_ETHARP and/or NETIF_FLAG_ETHERNET flag! - */ -err_t -netif_input(struct pbuf *p, struct netif *inp) -{ - LWIP_ASSERT_CORE_LOCKED(); - -#if LWIP_ETHERNET - if (inp->flags & (NETIF_FLAG_ETHARP | NETIF_FLAG_ETHERNET)) { - return ethernet_input(p, inp); - } else -#endif /* LWIP_ETHERNET */ - return ip_input(p, inp); -} - -/** - * @ingroup netif - * Add a network interface to the list of lwIP netifs. - * - * @param netif a pre-allocated netif structure - * @param ipaddr IP address for the new netif - * @param netmask network mask for the new netif - * @param gw default gateway IP address for the new netif - * @param state opaque data passed to the new netif - * @param init callback function that initializes the interface - * @param input callback function that is called to pass - * ingress packets up in the protocol layer stack.\n - * It is recommended to use a function that passes the input directly - * to the stack (netif_input(), NO_SYS=1 mode) or via sending a - * message to TCPIP thread (tcpip_input(), NO_SYS=0 mode).\n - * These functions use netif flags NETIF_FLAG_ETHARP and NETIF_FLAG_ETHERNET - * to decide whether to forward to ethernet_input() or ip_input(). - * In other words, the functions only work when the netif - * driver is implemented correctly!\n - * Most members of struct netif should be be initialized by the - * netif init function = netif driver (init parameter of this function).\n - * IPv6: Don't forget to call netif_create_ip6_linklocal_address() after - * setting the MAC address in struct netif.hwaddr - * (IPv6 requires a link-local address). - * - * @return netif, or NULL if failed. - */ -struct netif * -netif_add(struct netif *netif, -#if LWIP_IPV4 - const ip4_addr_t *ipaddr, const ip4_addr_t *netmask, const ip4_addr_t *gw, -#endif /* LWIP_IPV4 */ - void *state, netif_init_fn init, netif_input_fn input) -{ -#if LWIP_IPV6 - s8_t i; -#endif - - LWIP_ASSERT_CORE_LOCKED(); - - LWIP_ASSERT("No init function given", init != NULL); - - /* reset new interface configuration state */ -#if LWIP_IPV4 - ip_addr_set_zero_ip4(&netif->ip_addr); - ip_addr_set_zero_ip4(&netif->netmask); - ip_addr_set_zero_ip4(&netif->gw); -#endif /* LWIP_IPV4 */ -#if LWIP_IPV6 - for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { - ip_addr_set_zero_ip6(&netif->ip6_addr[i]); - netif->ip6_addr_state[i] = IP6_ADDR_INVALID; -#if LWIP_IPV6_ADDRESS_LIFETIMES - netif->ip6_addr_valid_life[i] = IP6_ADDR_LIFE_STATIC; - netif->ip6_addr_pref_life[i] = IP6_ADDR_LIFE_STATIC; -#endif /* LWIP_IPV6_ADDRESS_LIFETIMES */ - } - netif->output_ip6 = netif_null_output_ip6; -#endif /* LWIP_IPV6 */ - NETIF_SET_CHECKSUM_CTRL(netif, NETIF_CHECKSUM_ENABLE_ALL); - netif->flags = 0; -#ifdef netif_get_client_data - memset(netif->client_data, 0, sizeof(netif->client_data)); -#endif /* LWIP_NUM_NETIF_CLIENT_DATA */ -#if LWIP_IPV6_AUTOCONFIG - /* IPv6 address autoconfiguration not enabled by default */ - netif->ip6_autoconfig_enabled = 0; -#endif /* LWIP_IPV6_AUTOCONFIG */ -#if LWIP_IPV6_SEND_ROUTER_SOLICIT - netif->rs_count = LWIP_ND6_MAX_MULTICAST_SOLICIT; -#endif /* LWIP_IPV6_SEND_ROUTER_SOLICIT */ -#if LWIP_NETIF_STATUS_CALLBACK - netif->status_callback = NULL; -#endif /* LWIP_NETIF_STATUS_CALLBACK */ -#if LWIP_NETIF_LINK_CALLBACK - netif->link_callback = NULL; -#endif /* LWIP_NETIF_LINK_CALLBACK */ -#if LWIP_IGMP - netif->igmp_mac_filter = NULL; -#endif /* LWIP_IGMP */ -#if LWIP_IPV6 && LWIP_IPV6_MLD - netif->mld_mac_filter = NULL; -#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */ -#if ENABLE_LOOPBACK - netif->loop_first = NULL; - netif->loop_last = NULL; -#endif /* ENABLE_LOOPBACK */ - - /* remember netif specific state information data */ - netif->state = state; - netif->num = netif_num++; - netif->input = input; - - NETIF_SET_HWADDRHINT(netif, NULL); -#if ENABLE_LOOPBACK && LWIP_LOOPBACK_MAX_PBUFS - netif->loop_cnt_current = 0; -#endif /* ENABLE_LOOPBACK && LWIP_LOOPBACK_MAX_PBUFS */ - -#if LWIP_IPV4 - netif_set_addr(netif, ipaddr, netmask, gw); -#endif /* LWIP_IPV4 */ - - /* call user specified initialization function for netif */ - if (init(netif) != ERR_OK) { - return NULL; - } - - /* add this netif to the list */ - netif->next = netif_list; - netif_list = netif; - mib2_netif_added(netif); - -#if LWIP_IGMP - /* start IGMP processing */ - if (netif->flags & NETIF_FLAG_IGMP) { - igmp_start(netif); - } -#endif /* LWIP_IGMP */ - - LWIP_DEBUGF(NETIF_DEBUG, ("netif: added interface %c%c IP", - netif->name[0], netif->name[1])); -#if LWIP_IPV4 - LWIP_DEBUGF(NETIF_DEBUG, (" addr ")); - ip4_addr_debug_print(NETIF_DEBUG, ipaddr); - LWIP_DEBUGF(NETIF_DEBUG, (" netmask ")); - ip4_addr_debug_print(NETIF_DEBUG, netmask); - LWIP_DEBUGF(NETIF_DEBUG, (" gw ")); - ip4_addr_debug_print(NETIF_DEBUG, gw); -#endif /* LWIP_IPV4 */ - LWIP_DEBUGF(NETIF_DEBUG, ("\n")); - return netif; -} - -#if LWIP_IPV4 -/** - * @ingroup netif_ip4 - * Change IP address configuration for a network interface (including netmask - * and default gateway). - * - * @param netif the network interface to change - * @param ipaddr the new IP address - * @param netmask the new netmask - * @param gw the new default gateway - */ -void -netif_set_addr(struct netif *netif, const ip4_addr_t *ipaddr, const ip4_addr_t *netmask, - const ip4_addr_t *gw) -{ - LWIP_ASSERT_CORE_LOCKED(); - - if (ip4_addr_isany(ipaddr)) { - /* when removing an address, we have to remove it *before* changing netmask/gw - to ensure that tcp RST segment can be sent correctly */ - netif_set_ipaddr(netif, ipaddr); - netif_set_netmask(netif, netmask); - netif_set_gw(netif, gw); - } else { - netif_set_netmask(netif, netmask); - netif_set_gw(netif, gw); - /* set ipaddr last to ensure netmask/gw have been set when status callback is called */ - netif_set_ipaddr(netif, ipaddr); - } -} -#endif /* LWIP_IPV4*/ - -/** - * @ingroup netif - * Remove a network interface from the list of lwIP netifs. - * - * @param netif the network interface to remove - */ -void -netif_remove(struct netif *netif) -{ -#if LWIP_IPV6 - int i; -#endif - - LWIP_ASSERT_CORE_LOCKED(); - - if (netif == NULL) { - return; - } - -#if LWIP_IPV4 - if (!ip4_addr_isany_val(*netif_ip4_addr(netif))) { -#if LWIP_TCP - tcp_netif_ip_addr_changed(netif_ip_addr4(netif), NULL); -#endif /* LWIP_TCP */ -#if LWIP_UDP - udp_netif_ip_addr_changed(netif_ip_addr4(netif), NULL); -#endif /* LWIP_UDP */ -#if LWIP_RAW - raw_netif_ip_addr_changed(netif_ip_addr4(netif), NULL); -#endif /* LWIP_RAW */ - } - -#if LWIP_IGMP - /* stop IGMP processing */ - if (netif->flags & NETIF_FLAG_IGMP) { - igmp_stop(netif); - } -#endif /* LWIP_IGMP */ -#endif /* LWIP_IPV4*/ - -#if LWIP_IPV6 - for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { - if (ip6_addr_isvalid(netif_ip6_addr_state(netif, i))) { -#if LWIP_TCP - tcp_netif_ip_addr_changed(netif_ip_addr6(netif, i), NULL); -#endif /* LWIP_TCP */ -#if LWIP_UDP - udp_netif_ip_addr_changed(netif_ip_addr6(netif, i), NULL); -#endif /* LWIP_UDP */ -#if LWIP_RAW - raw_netif_ip_addr_changed(netif_ip_addr6(netif, i), NULL); -#endif /* LWIP_RAW */ - } - } -#if LWIP_IPV6_MLD - /* stop MLD processing */ - mld6_stop(netif); -#endif /* LWIP_IPV6_MLD */ -#endif /* LWIP_IPV6 */ - if (netif_is_up(netif)) { - /* set netif down before removing (call callback function) */ - netif_set_down(netif); - } - - mib2_remove_ip4(netif); - - /* this netif is default? */ - if (netif_default == netif) { - /* reset default netif */ - netif_set_default(NULL); - } - /* is it the first netif? */ - if (netif_list == netif) { - netif_list = netif->next; - } else { - /* look for netif further down the list */ - struct netif * tmp_netif; - for (tmp_netif = netif_list; tmp_netif != NULL; tmp_netif = tmp_netif->next) { - if (tmp_netif->next == netif) { - tmp_netif->next = netif->next; - break; - } - } - if (tmp_netif == NULL) { - return; /* netif is not on the list */ - } - } - mib2_netif_removed(netif); -#if LWIP_NETIF_REMOVE_CALLBACK - if (netif->remove_callback) { - netif->remove_callback(netif); - } -#endif /* LWIP_NETIF_REMOVE_CALLBACK */ - LWIP_DEBUGF( NETIF_DEBUG, ("netif_remove: removed netif\n") ); -} - -/** - * @ingroup netif - * Find a network interface by searching for its name - * - * @param name the name of the netif (like netif->name) plus concatenated number - * in ascii representation (e.g. 'en0') - */ -struct netif * -netif_find(const char *name) -{ - struct netif *netif; - u8_t num; - - if (name == NULL) { - return NULL; - } - - num = (u8_t)(name[2] - '0'); - - for (netif = netif_list; netif != NULL; netif = netif->next) { - if (num == netif->num && - name[0] == netif->name[0] && - name[1] == netif->name[1]) { - LWIP_DEBUGF(NETIF_DEBUG, ("netif_find: found %c%c\n", name[0], name[1])); - return netif; - } - } - LWIP_DEBUGF(NETIF_DEBUG, ("netif_find: didn't find %c%c\n", name[0], name[1])); - return NULL; -} - -#if LWIP_IPV4 -/** - * @ingroup netif_ip4 - * Change the IP address of a network interface - * - * @param netif the network interface to change - * @param ipaddr the new IP address - * - * @note call netif_set_addr() if you also want to change netmask and - * default gateway - */ -void -netif_set_ipaddr(struct netif *netif, const ip4_addr_t *ipaddr) -{ - ip_addr_t new_addr; - - LWIP_ASSERT_CORE_LOCKED(); - - *ip_2_ip4(&new_addr) = (ipaddr ? *ipaddr : *IP4_ADDR_ANY4); - IP_SET_TYPE_VAL(new_addr, IPADDR_TYPE_V4); - - /* address is actually being changed? */ - if (ip4_addr_cmp(ip_2_ip4(&new_addr), netif_ip4_addr(netif)) == 0) { - LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_STATE, ("netif_set_ipaddr: netif address being changed\n")); -#if LWIP_TCP - tcp_netif_ip_addr_changed(netif_ip_addr4(netif), &new_addr); -#endif /* LWIP_TCP */ -#if LWIP_UDP - udp_netif_ip_addr_changed(netif_ip_addr4(netif), &new_addr); -#endif /* LWIP_UDP */ -#if LWIP_RAW - raw_netif_ip_addr_changed(netif_ip_addr4(netif), &new_addr); -#endif /* LWIP_RAW */ - - mib2_remove_ip4(netif); - mib2_remove_route_ip4(0, netif); - /* set new IP address to netif */ - ip4_addr_set(ip_2_ip4(&netif->ip_addr), ipaddr); - IP_SET_TYPE_VAL(netif->ip_addr, IPADDR_TYPE_V4); - mib2_add_ip4(netif); - mib2_add_route_ip4(0, netif); - - netif_issue_reports(netif, NETIF_REPORT_TYPE_IPV4); - - NETIF_STATUS_CALLBACK(netif); - } - - LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("netif: IP address of interface %c%c set to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", - netif->name[0], netif->name[1], - ip4_addr1_16(netif_ip4_addr(netif)), - ip4_addr2_16(netif_ip4_addr(netif)), - ip4_addr3_16(netif_ip4_addr(netif)), - ip4_addr4_16(netif_ip4_addr(netif)))); -} - -/** - * @ingroup netif_ip4 - * Change the default gateway for a network interface - * - * @param netif the network interface to change - * @param gw the new default gateway - * - * @note call netif_set_addr() if you also want to change ip address and netmask - */ -void -netif_set_gw(struct netif *netif, const ip4_addr_t *gw) -{ - LWIP_ASSERT_CORE_LOCKED(); - - ip4_addr_set(ip_2_ip4(&netif->gw), gw); - IP_SET_TYPE_VAL(netif->gw, IPADDR_TYPE_V4); - LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("netif: GW address of interface %c%c set to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", - netif->name[0], netif->name[1], - ip4_addr1_16(netif_ip4_gw(netif)), - ip4_addr2_16(netif_ip4_gw(netif)), - ip4_addr3_16(netif_ip4_gw(netif)), - ip4_addr4_16(netif_ip4_gw(netif)))); -} - -/** - * @ingroup netif_ip4 - * Change the netmask of a network interface - * - * @param netif the network interface to change - * @param netmask the new netmask - * - * @note call netif_set_addr() if you also want to change ip address and - * default gateway - */ -void -netif_set_netmask(struct netif *netif, const ip4_addr_t *netmask) -{ - LWIP_ASSERT_CORE_LOCKED(); - - mib2_remove_route_ip4(0, netif); - /* set new netmask to netif */ - ip4_addr_set(ip_2_ip4(&netif->netmask), netmask); - IP_SET_TYPE_VAL(netif->netmask, IPADDR_TYPE_V4); - mib2_add_route_ip4(0, netif); - LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("netif: netmask of interface %c%c set to %"U16_F".%"U16_F".%"U16_F".%"U16_F"\n", - netif->name[0], netif->name[1], - ip4_addr1_16(netif_ip4_netmask(netif)), - ip4_addr2_16(netif_ip4_netmask(netif)), - ip4_addr3_16(netif_ip4_netmask(netif)), - ip4_addr4_16(netif_ip4_netmask(netif)))); -} -#endif /* LWIP_IPV4 */ - -/** - * @ingroup netif - * Set a network interface as the default network interface - * (used to output all packets for which no specific route is found) - * - * @param netif the default network interface - */ -void -netif_set_default(struct netif *netif) -{ - LWIP_ASSERT_CORE_LOCKED(); - - if (netif == NULL) { - /* remove default route */ - mib2_remove_route_ip4(1, netif); - } else { - /* install default route */ - mib2_add_route_ip4(1, netif); - } - netif_default = netif; - LWIP_DEBUGF(NETIF_DEBUG, ("netif: setting default interface %c%c\n", - netif ? netif->name[0] : '\'', netif ? netif->name[1] : '\'')); -} - -/** - * @ingroup netif - * Bring an interface up, available for processing - * traffic. - */ -void -netif_set_up(struct netif *netif) -{ - LWIP_ASSERT_CORE_LOCKED(); - - if (!(netif->flags & NETIF_FLAG_UP)) { - netif->flags |= NETIF_FLAG_UP; - - MIB2_COPY_SYSUPTIME_TO(&netif->ts); - - NETIF_STATUS_CALLBACK(netif); - - if (netif->flags & NETIF_FLAG_LINK_UP) { - netif_issue_reports(netif, NETIF_REPORT_TYPE_IPV4|NETIF_REPORT_TYPE_IPV6); - } - } -} - -/** Send ARP/IGMP/MLD/RS events, e.g. on link-up/netif-up or addr-change - */ -static void -netif_issue_reports(struct netif* netif, u8_t report_type) -{ -#if LWIP_IPV4 - if ((report_type & NETIF_REPORT_TYPE_IPV4) && - !ip4_addr_isany_val(*netif_ip4_addr(netif))) { -#if LWIP_ARP - /* For Ethernet network interfaces, we would like to send a "gratuitous ARP" */ - if (netif->flags & (NETIF_FLAG_ETHARP)) { - etharp_gratuitous(netif); - } -#endif /* LWIP_ARP */ - -#if LWIP_IGMP - /* resend IGMP memberships */ - if (netif->flags & NETIF_FLAG_IGMP) { - igmp_report_groups(netif); - } -#endif /* LWIP_IGMP */ - } -#endif /* LWIP_IPV4 */ - -#if LWIP_IPV6 - if (report_type & NETIF_REPORT_TYPE_IPV6) { -#if LWIP_IPV6_MLD - /* send mld memberships */ - mld6_report_groups(netif); -#endif /* LWIP_IPV6_MLD */ -#if LWIP_IPV6_SEND_ROUTER_SOLICIT - /* Send Router Solicitation messages. */ - netif->rs_count = LWIP_ND6_MAX_MULTICAST_SOLICIT; -#endif /* LWIP_IPV6_SEND_ROUTER_SOLICIT */ - } -#endif /* LWIP_IPV6 */ -} - -/** - * @ingroup netif - * Bring an interface down, disabling any traffic processing. - */ -void -netif_set_down(struct netif *netif) -{ - LWIP_ASSERT_CORE_LOCKED(); - - if (netif->flags & NETIF_FLAG_UP) { - netif->flags &= ~NETIF_FLAG_UP; - MIB2_COPY_SYSUPTIME_TO(&netif->ts); - -#if LWIP_IPV4 && LWIP_ARP - if (netif->flags & NETIF_FLAG_ETHARP) { - etharp_cleanup_netif(netif); - } -#endif /* LWIP_IPV4 && LWIP_ARP */ - -#if LWIP_IPV6 && LWIP_IPV6_ND - nd6_cleanup_netif(netif); -#endif /* LWIP_IPV6 && LWIP_IPV6_ND */ - - NETIF_STATUS_CALLBACK(netif); - } -} - -#if LWIP_NETIF_STATUS_CALLBACK -/** - * @ingroup netif - * Set callback to be called when interface is brought up/down or address is changed while up - */ -void -netif_set_status_callback(struct netif *netif, netif_status_callback_fn status_callback) -{ - LWIP_ASSERT_CORE_LOCKED(); - - if (netif) { - netif->status_callback = status_callback; - } -} -#endif /* LWIP_NETIF_STATUS_CALLBACK */ - -#if LWIP_NETIF_REMOVE_CALLBACK -/** - * @ingroup netif - * Set callback to be called when the interface has been removed - */ -void -netif_set_remove_callback(struct netif *netif, netif_status_callback_fn remove_callback) -{ - if (netif) { - netif->remove_callback = remove_callback; - } -} -#endif /* LWIP_NETIF_REMOVE_CALLBACK */ - -/** - * @ingroup netif - * Called by a driver when its link goes up - */ -void -netif_set_link_up(struct netif *netif) -{ - LWIP_ASSERT_CORE_LOCKED(); - - if (!(netif->flags & NETIF_FLAG_LINK_UP)) { - netif->flags |= NETIF_FLAG_LINK_UP; - -#if LWIP_DHCP - dhcp_network_changed(netif); -#endif /* LWIP_DHCP */ - -#if LWIP_AUTOIP - autoip_network_changed(netif); -#endif /* LWIP_AUTOIP */ - - if (netif->flags & NETIF_FLAG_UP) { - netif_issue_reports(netif, NETIF_REPORT_TYPE_IPV4|NETIF_REPORT_TYPE_IPV6); - } - NETIF_LINK_CALLBACK(netif); - } -} - -/** - * @ingroup netif - * Called by a driver when its link goes down - */ -void -netif_set_link_down(struct netif *netif ) -{ - LWIP_ASSERT_CORE_LOCKED(); - - if (netif->flags & NETIF_FLAG_LINK_UP) { - netif->flags &= ~NETIF_FLAG_LINK_UP; - NETIF_LINK_CALLBACK(netif); - } -} - -#if LWIP_NETIF_LINK_CALLBACK -/** - * @ingroup netif - * Set callback to be called when link is brought up/down - */ -void -netif_set_link_callback(struct netif *netif, netif_status_callback_fn link_callback) -{ - LWIP_ASSERT_CORE_LOCKED(); - - if (netif) { - netif->link_callback = link_callback; - } -} -#endif /* LWIP_NETIF_LINK_CALLBACK */ - -#if ENABLE_LOOPBACK -/** - * @ingroup netif - * Send an IP packet to be received on the same netif (loopif-like). - * The pbuf is simply copied and handed back to netif->input. - * In multithreaded mode, this is done directly since netif->input must put - * the packet on a queue. - * In callback mode, the packet is put on an internal queue and is fed to - * netif->input by netif_poll(). - * - * @param netif the lwip network interface structure - * @param p the (IP) packet to 'send' - * @return ERR_OK if the packet has been sent - * ERR_MEM if the pbuf used to copy the packet couldn't be allocated - */ -err_t -netif_loop_output(struct netif *netif, struct pbuf *p) -{ - struct pbuf *r; - err_t err; - struct pbuf *last; -#if LWIP_LOOPBACK_MAX_PBUFS - u16_t clen = 0; -#endif /* LWIP_LOOPBACK_MAX_PBUFS */ - /* If we have a loopif, SNMP counters are adjusted for it, - * if not they are adjusted for 'netif'. */ -#if MIB2_STATS -#if LWIP_HAVE_LOOPIF - struct netif *stats_if = &loop_netif; -#else /* LWIP_HAVE_LOOPIF */ - struct netif *stats_if = netif; -#endif /* LWIP_HAVE_LOOPIF */ -#endif /* MIB2_STATS */ - SYS_ARCH_DECL_PROTECT(lev); - - /* Allocate a new pbuf */ - r = pbuf_alloc(PBUF_LINK, p->tot_len, PBUF_RAM); - if (r == NULL) { - LINK_STATS_INC(link.memerr); - LINK_STATS_INC(link.drop); - MIB2_STATS_NETIF_INC(stats_if, ifoutdiscards); - return ERR_MEM; - } -#if LWIP_LOOPBACK_MAX_PBUFS - clen = pbuf_clen(r); - /* check for overflow or too many pbuf on queue */ - if (((netif->loop_cnt_current + clen) < netif->loop_cnt_current) || - ((netif->loop_cnt_current + clen) > LWIP_LOOPBACK_MAX_PBUFS)) { - pbuf_free(r); - LINK_STATS_INC(link.memerr); - LINK_STATS_INC(link.drop); - MIB2_STATS_NETIF_INC(stats_if, ifoutdiscards); - return ERR_MEM; - } - netif->loop_cnt_current += clen; -#endif /* LWIP_LOOPBACK_MAX_PBUFS */ - - /* Copy the whole pbuf queue p into the single pbuf r */ - if ((err = pbuf_copy(r, p)) != ERR_OK) { - pbuf_free(r); - LINK_STATS_INC(link.memerr); - LINK_STATS_INC(link.drop); - MIB2_STATS_NETIF_INC(stats_if, ifoutdiscards); - return err; - } - - /* Put the packet on a linked list which gets emptied through calling - netif_poll(). */ - - /* let last point to the last pbuf in chain r */ - for (last = r; last->next != NULL; last = last->next) { - /* nothing to do here, just get to the last pbuf */ - } - - SYS_ARCH_PROTECT(lev); - if (netif->loop_first != NULL) { - LWIP_ASSERT("if first != NULL, last must also be != NULL", netif->loop_last != NULL); - netif->loop_last->next = r; - netif->loop_last = last; - } else { - netif->loop_first = r; - netif->loop_last = last; - } - SYS_ARCH_UNPROTECT(lev); - - LINK_STATS_INC(link.xmit); - MIB2_STATS_NETIF_ADD(stats_if, ifoutoctets, p->tot_len); - MIB2_STATS_NETIF_INC(stats_if, ifoutucastpkts); - -#if LWIP_NETIF_LOOPBACK_MULTITHREADING - /* For multithreading environment, schedule a call to netif_poll */ - tcpip_callback_with_block((tcpip_callback_fn)netif_poll, netif, 0); -#endif /* LWIP_NETIF_LOOPBACK_MULTITHREADING */ - - return ERR_OK; -} - -#if LWIP_HAVE_LOOPIF -#if LWIP_IPV4 -static err_t -netif_loop_output_ipv4(struct netif *netif, struct pbuf *p, const ip4_addr_t* addr) -{ - LWIP_UNUSED_ARG(addr); - return netif_loop_output(netif, p); -} -#endif /* LWIP_IPV4 */ - -#if LWIP_IPV6 -static err_t -netif_loop_output_ipv6(struct netif *netif, struct pbuf *p, const ip6_addr_t* addr) -{ - LWIP_UNUSED_ARG(addr); - return netif_loop_output(netif, p); -} -#endif /* LWIP_IPV6 */ -#endif /* LWIP_HAVE_LOOPIF */ - - -/** - * Call netif_poll() in the main loop of your application. This is to prevent - * reentering non-reentrant functions like tcp_input(). Packets passed to - * netif_loop_output() are put on a list that is passed to netif->input() by - * netif_poll(). - */ -void -netif_poll(struct netif *netif) -{ - /* If we have a loopif, SNMP counters are adjusted for it, - * if not they are adjusted for 'netif'. */ -#if MIB2_STATS -#if LWIP_HAVE_LOOPIF - struct netif *stats_if = &loop_netif; -#else /* LWIP_HAVE_LOOPIF */ - struct netif *stats_if = netif; -#endif /* LWIP_HAVE_LOOPIF */ -#endif /* MIB2_STATS */ - SYS_ARCH_DECL_PROTECT(lev); - - /* Get a packet from the list. With SYS_LIGHTWEIGHT_PROT=1, this is protected */ - SYS_ARCH_PROTECT(lev); - while (netif->loop_first != NULL) { - struct pbuf *in, *in_end; -#if LWIP_LOOPBACK_MAX_PBUFS - u8_t clen = 1; -#endif /* LWIP_LOOPBACK_MAX_PBUFS */ - - in = in_end = netif->loop_first; - while (in_end->len != in_end->tot_len) { - LWIP_ASSERT("bogus pbuf: len != tot_len but next == NULL!", in_end->next != NULL); - in_end = in_end->next; -#if LWIP_LOOPBACK_MAX_PBUFS - clen++; -#endif /* LWIP_LOOPBACK_MAX_PBUFS */ - } -#if LWIP_LOOPBACK_MAX_PBUFS - /* adjust the number of pbufs on queue */ - LWIP_ASSERT("netif->loop_cnt_current underflow", - ((netif->loop_cnt_current - clen) < netif->loop_cnt_current)); - netif->loop_cnt_current -= clen; -#endif /* LWIP_LOOPBACK_MAX_PBUFS */ - - /* 'in_end' now points to the last pbuf from 'in' */ - if (in_end == netif->loop_last) { - /* this was the last pbuf in the list */ - netif->loop_first = netif->loop_last = NULL; - } else { - /* pop the pbuf off the list */ - netif->loop_first = in_end->next; - LWIP_ASSERT("should not be null since first != last!", netif->loop_first != NULL); - } - /* De-queue the pbuf from its successors on the 'loop_' list. */ - in_end->next = NULL; - SYS_ARCH_UNPROTECT(lev); - - LINK_STATS_INC(link.recv); - MIB2_STATS_NETIF_ADD(stats_if, ifinoctets, in->tot_len); - MIB2_STATS_NETIF_INC(stats_if, ifinucastpkts); - /* loopback packets are always IP packets! */ - if (ip_input(in, netif) != ERR_OK) { - pbuf_free(in); - } - SYS_ARCH_PROTECT(lev); - } - SYS_ARCH_UNPROTECT(lev); -} - -#if !LWIP_NETIF_LOOPBACK_MULTITHREADING -/** - * Calls netif_poll() for every netif on the netif_list. - */ -void -netif_poll_all(void) -{ - struct netif *netif = netif_list; - /* loop through netifs */ - while (netif != NULL) { - netif_poll(netif); - /* proceed to next network interface */ - netif = netif->next; - } -} -#endif /* !LWIP_NETIF_LOOPBACK_MULTITHREADING */ -#endif /* ENABLE_LOOPBACK */ - -#if LWIP_NUM_NETIF_CLIENT_DATA > 0 -/** - * @ingroup netif_cd - * Allocate an index to store data in client_data member of struct netif. - * Returned value is an index in mentioned array. - * @see LWIP_NUM_NETIF_CLIENT_DATA - */ -u8_t -netif_alloc_client_data_id(void) -{ - u8_t result = netif_client_id; - netif_client_id++; - - LWIP_ASSERT_CORE_LOCKED(); - - LWIP_ASSERT("Increase LWIP_NUM_NETIF_CLIENT_DATA in lwipopts.h", result < LWIP_NUM_NETIF_CLIENT_DATA); - return result + LWIP_NETIF_CLIENT_DATA_INDEX_MAX; -} -#endif - -#if LWIP_IPV6 -/** - * @ingroup netif_ip6 - * Change an IPv6 address of a network interface - * - * @param netif the network interface to change - * @param addr_idx index of the IPv6 address - * @param addr6 the new IPv6 address - * - * @note call netif_ip6_addr_set_state() to set the address valid/temptative - */ -void -netif_ip6_addr_set(struct netif *netif, s8_t addr_idx, const ip6_addr_t *addr6) -{ - LWIP_ASSERT("addr6 != NULL", addr6 != NULL); - - LWIP_ASSERT_CORE_LOCKED(); - - netif_ip6_addr_set_parts(netif, addr_idx, addr6->addr[0], addr6->addr[1], - addr6->addr[2], addr6->addr[3]); -} - -/* - * Change an IPv6 address of a network interface (internal version taking 4 * u32_t) - * - * @param netif the network interface to change - * @param addr_idx index of the IPv6 address - * @param i0 word0 of the new IPv6 address - * @param i1 word1 of the new IPv6 address - * @param i2 word2 of the new IPv6 address - * @param i3 word3 of the new IPv6 address - */ -void -netif_ip6_addr_set_parts(struct netif *netif, s8_t addr_idx, u32_t i0, u32_t i1, u32_t i2, u32_t i3) -{ - const ip6_addr_t *old_addr; - LWIP_ASSERT_CORE_LOCKED(); - LWIP_ASSERT("netif != NULL", netif != NULL); - LWIP_ASSERT("invalid index", addr_idx < LWIP_IPV6_NUM_ADDRESSES); - - old_addr = netif_ip6_addr(netif, addr_idx); - /* address is actually being changed? */ - if ((old_addr->addr[0] != i0) || (old_addr->addr[1] != i1) || - (old_addr->addr[2] != i2) || (old_addr->addr[3] != i3)) { - LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_STATE, ("netif_ip6_addr_set: netif address being changed\n")); - - if (netif_ip6_addr_state(netif, addr_idx) & IP6_ADDR_VALID) { -#if LWIP_TCP || LWIP_UDP - ip_addr_t new_ipaddr; - IP_ADDR6(&new_ipaddr, i0, i1, i2, i3); -#endif /* LWIP_TCP || LWIP_UDP */ -#if LWIP_TCP - tcp_netif_ip_addr_changed(netif_ip_addr6(netif, addr_idx), &new_ipaddr); -#endif /* LWIP_TCP */ -#if LWIP_UDP - udp_netif_ip_addr_changed(netif_ip_addr6(netif, addr_idx), &new_ipaddr); -#endif /* LWIP_UDP */ -#if LWIP_RAW - raw_netif_ip_addr_changed(netif_ip_addr6(netif, addr_idx), &new_ipaddr); -#endif /* LWIP_RAW */ - } - /* @todo: remove/readd mib2 ip6 entries? */ - - IP6_ADDR(ip_2_ip6(&(netif->ip6_addr[addr_idx])), i0, i1, i2, i3); - IP_SET_TYPE_VAL(netif->ip6_addr[addr_idx], IPADDR_TYPE_V6); - - if (netif_ip6_addr_state(netif, addr_idx) & IP6_ADDR_VALID) { - netif_issue_reports(netif, NETIF_REPORT_TYPE_IPV6); - NETIF_STATUS_CALLBACK(netif); - } - } - - LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("netif: IPv6 address %d of interface %c%c set to %s/0x%"X8_F"\n", - addr_idx, netif->name[0], netif->name[1], ip6addr_ntoa(netif_ip6_addr(netif, addr_idx)), - netif_ip6_addr_state(netif, addr_idx))); -} - -/** - * @ingroup netif_ip6 - * Change the state of an IPv6 address of a network interface - * (INVALID, TEMPTATIVE, PREFERRED, DEPRECATED, where TEMPTATIVE - * includes the number of checks done, see ip6_addr.h) - * - * @param netif the network interface to change - * @param addr_idx index of the IPv6 address - * @param state the new IPv6 address state - */ -void -netif_ip6_addr_set_state(struct netif* netif, s8_t addr_idx, u8_t state) -{ - u8_t old_state; - LWIP_ASSERT_CORE_LOCKED(); - LWIP_ASSERT("netif != NULL", netif != NULL); - LWIP_ASSERT("invalid index", addr_idx < LWIP_IPV6_NUM_ADDRESSES); - - old_state = netif_ip6_addr_state(netif, addr_idx); - /* state is actually being changed? */ - if (old_state != state) { - u8_t old_valid = old_state & IP6_ADDR_VALID; - u8_t new_valid = state & IP6_ADDR_VALID; - LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_STATE, ("netif_ip6_addr_set_state: netif address state being changed\n")); - -#if LWIP_IPV6_MLD - /* Reevaluate solicited-node multicast group membership. */ - if (netif->flags & NETIF_FLAG_MLD6) { - nd6_adjust_mld_membership(netif, addr_idx, state); - } -#endif /* LWIP_IPV6_MLD */ - - if (old_valid && !new_valid) { - /* address about to be removed by setting invalid */ -#if LWIP_TCP - tcp_netif_ip_addr_changed(netif_ip_addr6(netif, addr_idx), NULL); -#endif /* LWIP_TCP */ -#if LWIP_UDP - udp_netif_ip_addr_changed(netif_ip_addr6(netif, addr_idx), NULL); -#endif /* LWIP_UDP */ -#if LWIP_RAW - raw_netif_ip_addr_changed(netif_ip_addr6(netif, addr_idx), NULL); -#endif /* LWIP_RAW */ - /* @todo: remove mib2 ip6 entries? */ - } - netif->ip6_addr_state[addr_idx] = state; - - if (!old_valid && new_valid) { - /* address added by setting valid */ - /* @todo: add mib2 ip6 entries? */ - netif_issue_reports(netif, NETIF_REPORT_TYPE_IPV6); - } - if ((old_state & IP6_ADDR_PREFERRED) != (state & IP6_ADDR_PREFERRED)) { - /* address state has changed (valid flag changed or switched between - preferred and deprecated) -> call the callback function */ - NETIF_STATUS_CALLBACK(netif); - } - } - - LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("netif: IPv6 address %d of interface %c%c set to %s/0x%"X8_F"\n", - addr_idx, netif->name[0], netif->name[1], ip6addr_ntoa(netif_ip6_addr(netif, addr_idx)), - netif_ip6_addr_state(netif, addr_idx))); -} - -/** - * Checks if a specific local address is present on the netif and returns its - * index. Depending on its state, it may or may not be assigned to the - * interface (as per RFC terminology). - * - * @param netif the netif to check - * @param ip6addr the IPv6 address to find - * @return >= 0: address found, this is its index - * -1: address not found on this netif - */ -s8_t -netif_get_ip6_addr_match(struct netif *netif, const ip6_addr_t *ip6addr) -{ - s8_t i; - - LWIP_ASSERT_CORE_LOCKED(); - - for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) { - if (!ip6_addr_isinvalid(netif_ip6_addr_state(netif, i)) && - ip6_addr_cmp(netif_ip6_addr(netif, i), ip6addr)) { - return i; - } - } - return -1; -} - -/** - * @ingroup netif_ip6 - * Create a link-local IPv6 address on a netif (stored in slot 0) - * - * @param netif the netif to create the address on - * @param from_mac_48bit if != 0, assume hwadr is a 48-bit MAC address (std conversion) - * if == 0, use hwaddr directly as interface ID - * - * @note - * Nest has changed this interface so that if from_mac_48bit == 0, then it means the - * hwaddr is an EUI64 that is to be subject to the standard conversion. - */ -void -netif_create_ip6_linklocal_address(struct netif *netif, u8_t from_mac_48bit) -{ - u8_t i, addr_index; - - LWIP_ASSERT_CORE_LOCKED(); - - /* Link-local prefix. */ - ip_2_ip6(&netif->ip6_addr[0])->addr[0] = PP_HTONL(0xfe800000ul); - ip_2_ip6(&netif->ip6_addr[0])->addr[1] = 0; - - /* Generate interface ID. */ - if (from_mac_48bit) { - /* Assume hwaddr is a 48-bit IEEE 802 MAC. Convert to EUI-64 address. Complement Group bit. */ - ip_2_ip6(&netif->ip6_addr[0])->addr[2] = lwip_htonl((((u32_t)(netif->hwaddr[0] ^ 0x02)) << 24) | - ((u32_t)(netif->hwaddr[1]) << 16) | - ((u32_t)(netif->hwaddr[2]) << 8) | - (0xff)); - ip_2_ip6(&netif->ip6_addr[0])->addr[3] = lwip_htonl((0xfeul << 24) | - ((u32_t)(netif->hwaddr[3]) << 16) | - ((u32_t)(netif->hwaddr[4]) << 8) | - (netif->hwaddr[5])); - } else { - /* Use hwaddr directly as interface ID. */ - ip_2_ip6(&netif->ip6_addr[0])->addr[2] = 0; - ip_2_ip6(&netif->ip6_addr[0])->addr[3] = 0; - - memcpy((void*)&ip_2_ip6(&netif->ip6_addr[0])->addr[2], netif->hwaddr, netif->hwaddr_len); - ip_2_ip6(&netif->ip6_addr[0])->addr[2] ^= PP_HTONL(0x02000000ul); - } - - /* Set address state. */ -#if LWIP_IPV6_DUP_DETECT_ATTEMPTS - /* Will perform duplicate address detection (DAD). */ - netif_ip6_addr_set_state(netif, 0, IP6_ADDR_TENTATIVE); -#else /* !LWIP_IPV6_DUP_DETECT_ATTEMPTS */ - /* Consider address valid. */ - netif_ip6_addr_set_state(netif, 0, IP6_ADDR_PREFERRED); -#endif /* !LWIP_IPV6_DUP_DETECT_ATTEMPTS */ -} - -/** - * This function allows for the addition of a new IPv6 address to an interface - * along with a prefix len to add a route to the routing table. - * - * @param netif netif to add the address on - * @param ip6addr address to add - * @prefix_len the prefix length for the route corresponding to the address - * @param chosen_idx if != NULL, the chosen IPv6 address index will be stored here - */ -err_t -netif_add_ip6_address_with_route(struct netif *netif, ip6_addr_t *ip6addr, - u8_t prefix_len, s8_t *chosen_idx) -{ - s8_t retval = ERR_OK; -#if LWIP_IPV6_ROUTE_TABLE_SUPPORT - struct ip6_prefix ip6_pref; - - if (!ip6_prefix_valid(prefix_len)) { - retval = ERR_ARG; - goto fail; - } -#else - if (prefix_len != 64 && prefix_len != 128) { - retval = ERR_ARG; - goto fail; - } -#endif - - if ((retval = netif_add_ip6_address(netif, ip6addr, chosen_idx)) != - ERR_OK) { - goto fail; - } - -#if LWIP_IPV6_ROUTE_TABLE_SUPPORT - /* Add a route in routing table for the prefix len. Ignore adding route if - * prefix_len is zero(default route) or prefix_len is 128(host route) - */ - if (prefix_len > 0 && prefix_len < IP6_MAX_PREFIX_LEN) { - ip6_addr_copy(ip6_pref.addr, *ip6addr); - ip6_pref.prefix_len = prefix_len; - if ((retval = ip6_add_route_entry(&ip6_pref, netif, NULL, NULL)) != - ERR_OK) { - goto fail; - } - } -#endif /* LWIP_IPV6_ROUTE_TABLE_SUPPORT */ - -fail: - return retval; -} - -/** - * This function allows for the removal of an IPv6 address from an interface - * as well as any routes associated with it. - * - * @param netif netif on which the address is assigned - * @param ip6addr address to remove - * @prefix_len the prefix length for the route corresponding to the address - */ -err_t -netif_remove_ip6_address_with_route(struct netif *netif, ip6_addr_t *ip6addr, - u8_t prefix_len) -{ - s8_t retval = ERR_OK; -#if LWIP_IPV6_ROUTE_TABLE_SUPPORT - struct ip6_prefix ip6_pref; - - if (!ip6_prefix_valid(prefix_len)) { - retval = ERR_ARG; - goto fail; - } -#else - if (prefix_len != 64 && prefix_len != 128) { - retval = ERR_ARG; - goto fail; - } -#endif /* LWIP_IPV6_ROUTE_TABLE_SUPPORT */ - - if ((retval = netif_remove_ip6_address(netif, ip6addr)) != ERR_OK) { - goto fail; - } - -#if LWIP_IPV6_ROUTE_TABLE_SUPPORT - /* Remove the route in routing table for the prefix len */ - ip6_addr_copy(ip6_pref.addr, *ip6addr); - ip6_pref.prefix_len = prefix_len; - ip6_remove_route_entry(&ip6_pref); -#endif /* LWIP_IPV6_ROUTE_TABLE_SUPPORT */ - -fail: - return retval; -} - -/** - * @ingroup netif_ip6 - * This function allows for the easy addition of a new IPv6 address to an interface. - * It takes care of finding an empty slot and then sets the address tentative - * (to make sure that all the subsequent processing happens). - * - * @param netif netif to add the address on - * @param ip6addr address to add - * @param chosen_idx if != NULL, the chosen IPv6 address index will be stored here - */ -err_t -netif_add_ip6_address(struct netif *netif, const ip6_addr_t *ip6addr, s8_t *chosen_idx) -{ - s8_t i; - - LWIP_ASSERT_CORE_LOCKED(); - - i = netif_get_ip6_addr_match(netif, ip6addr); - if (i >= 0) { - /* Address already added */ - if (chosen_idx != NULL) { - *chosen_idx = i; - } - return ERR_OK; - } - - /* Find a free slot -- musn't be the first one (reserved for link local) */ - for (i = 1; i < LWIP_IPV6_NUM_ADDRESSES; i++) { - if (ip6_addr_isinvalid(netif_ip6_addr_state(netif, i))) { - ip_addr_copy_from_ip6(netif->ip6_addr[i], *ip6addr); - netif_ip6_addr_set_state(netif, i, IP6_ADDR_TENTATIVE); - if (chosen_idx != NULL) { - *chosen_idx = i; - } - return ERR_OK; - } - } - - if (chosen_idx != NULL) { - *chosen_idx = -1; - } - return ERR_VAL; -} - -/** This function allows for the easy removal of an IPv6 address from an interface. - * - * @param netif netif on which the address is assigned - * @param ip6addr address to remove - */ -err_t -netif_remove_ip6_address(struct netif *netif, ip6_addr_t *ip6addr) -{ - s8_t i; - - i = netif_get_ip6_addr_match(netif, ip6addr); - if (i >= 0) { - ip6_addr_set_zero(ip_2_ip6(&netif->ip6_addr[i])); - netif_ip6_addr_set_state(netif, i, IP6_ADDR_INVALID); - return ERR_OK; - } - - return ERR_VAL; -} - -static err_t -netif_null_output_ip6(struct netif *netif, struct pbuf *p, const ip6_addr_t *ipaddr) -{ - LWIP_UNUSED_ARG(netif); - LWIP_UNUSED_ARG(p); - LWIP_UNUSED_ARG(ipaddr); - - return ERR_IF; -} -#endif /* LWIP_IPV6 */ - -/** -* @ingroup netif_if -* Return the interface index for the netif with name -* or 0 (invalid interface) if not found/on error -* -* @param name the name of the netif -*/ -u8_t -netif_name_to_index(const char *name) -{ - struct netif *netif = netif_find(name); - if (netif != NULL) { - return netif_get_index(netif); - } - /* No name found, return invalid index */ - return 0; -} - -/** -* @ingroup netif_if -* Return the interface name for the netif matching index -* or NULL if not found/on error -* -* @param index the interface index of the netif -* @param name char buffer of at least IF_NAMESIZE bytes -*/ -char * -netif_index_to_name(u8_t index, char *name) -{ - struct netif *curif = netif_list; - - LWIP_ASSERT_CORE_LOCKED(); - - u8_t num; - - LWIP_ASSERT_CORE_LOCKED(); - - if (index == 0) { - return NULL; /* indexes start at 1 */ - } - num = netif_index_to_num(index); - - /* find netif from num */ - while (curif != NULL) { - if (curif->num == num) { - name[0] = curif->name[0]; - name[1] = curif->name[1]; - lwip_itoa(&name[2], IF_NAMESIZE - 2, num); - return name; - } - curif = curif->next; - } - return NULL; -} - -/** -* @ingroup netif -* Return the interface for the netif index -* -* @param index index of netif to find -*/ -struct netif* -netif_get_by_index(u8_t index) -{ - struct netif* netif; - - if (index != NETIF_NO_INDEX) { - for (netif = netif_list; netif != NULL; netif = netif->next) { - if (index == netif_get_index(netif)) { - return netif; /* found! */ - } - } - } - - return NULL; -} diff --git a/third_party/lwip/repo/lwip/src/core/pbuf.c b/third_party/lwip/repo/lwip/src/core/pbuf.c deleted file mode 100644 index 86b098de5d4121..00000000000000 --- a/third_party/lwip/repo/lwip/src/core/pbuf.c +++ /dev/null @@ -1,1599 +0,0 @@ -/** - * @file - * Packet buffer management - */ - -/** - * @defgroup pbuf Packet buffers (PBUF) - * @ingroup infrastructure - * - * Packets are built from the pbuf data structure. It supports dynamic - * memory allocation for packet contents or can reference externally - * managed packet contents both in RAM and ROM. Quick allocation for - * incoming packets is provided through pools with fixed sized pbufs. - * - * A packet may span over multiple pbufs, chained as a singly linked - * list. This is called a "pbuf chain". - * - * Multiple packets may be queued, also using this singly linked list. - * This is called a "packet queue". - * - * So, a packet queue consists of one or more pbuf chains, each of - * which consist of one or more pbufs. CURRENTLY, PACKET QUEUES ARE - * NOT SUPPORTED!!! Use helper structs to queue multiple packets. - * - * The differences between a pbuf chain and a packet queue are very - * precise but subtle. - * - * The last pbuf of a packet has a ->tot_len field that equals the - * ->len field. It can be found by traversing the list. If the last - * pbuf of a packet has a ->next field other than NULL, more packets - * are on the queue. - * - * Therefore, looping through a pbuf of a single packet, has an - * loop end condition (tot_len == p->len), NOT (next == NULL). - * - * Example of custom pbuf usage for zero-copy RX: - @code{.c} -typedef struct my_custom_pbuf -{ - struct pbuf_custom p; - void* dma_descriptor; -} my_custom_pbuf_t; - -LWIP_MEMPOOL_DECLARE(RX_POOL, 10, sizeof(my_custom_pbuf_t), "Zero-copy RX PBUF pool"); - -void my_pbuf_free_custom(void* p) -{ - my_custom_pbuf_t* my_puf = (my_custom_pbuf_t*)p; - - LOCK_INTERRUPTS(); - free_rx_dma_descriptor(my_pbuf->dma_descriptor); - LWIP_MEMPOOL_FREE(RX_POOL, my_pbuf); - UNLOCK_INTERRUPTS(); -} - -void eth_rx_irq() -{ - dma_descriptor* dma_desc = get_RX_DMA_descriptor_from_ethernet(); - my_custom_pbuf_t* my_pbuf = (my_custom_pbuf_t*)LWIP_MEMPOOL_ALLOC(RX_POOL); - - my_pbuf->p.custom_free_function = my_pbuf_free_custom; - my_pbuf->dma_descriptor = dma_desc; - - invalidate_cpu_cache(dma_desc->rx_data, dma_desc->rx_length); - - struct pbuf* p = pbuf_alloced_custom(PBUF_RAW, - dma_desc->rx_length, - PBUF_REF, - &my_pbuf->p, - dma_desc->rx_data, - dma_desc->max_buffer_size); - - if(netif->input(p, netif) != ERR_OK) { - pbuf_free(p); - } -} - @endcode - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ - -#include "lwip/opt.h" - -#include "lwip/stats.h" -#include "lwip/def.h" -#include "lwip/mem.h" -#include "lwip/memp.h" -#include "lwip/pbuf.h" -#include "lwip/sys.h" -#if LWIP_PERF || LWIP_PBUF_CALLOUTS -#include "arch/perf.h" -#endif -#if LWIP_TCP && TCP_QUEUE_OOSEQ -#include "lwip/priv/tcp_priv.h" -#endif -#if LWIP_CHECKSUM_ON_COPY -#include "lwip/inet_chksum.h" -#endif - -#include - -#define SIZEOF_STRUCT_PBUF LWIP_MEM_ALIGN_SIZE(sizeof(struct pbuf)) - -#if LWIP_PBUF_FROM_CUSTOM_POOLS -#define GET_ALIGNED_PBUF_POOL_SIZE(x) (LWIP_MEM_ALIGN_SIZE(memp_sizes[x]) - SIZEOF_STRUCT_PBUF) -#else -#define GET_ALIGNED_PBUF_POOL_SIZE(x) LWIP_MEM_ALIGN_SIZE(PBUF_POOL_BUFSIZE) -#endif - -#if !LWIP_TCP || !TCP_QUEUE_OOSEQ || !PBUF_POOL_FREE_OOSEQ -#define PBUF_POOL_IS_EMPTY() -#else /* !LWIP_TCP || !TCP_QUEUE_OOSEQ || !PBUF_POOL_FREE_OOSEQ */ - -#if !NO_SYS -#ifndef PBUF_POOL_FREE_OOSEQ_QUEUE_CALL -#include "lwip/tcpip.h" -#define PBUF_POOL_FREE_OOSEQ_QUEUE_CALL() do { \ - if (tcpip_callback_with_block(pbuf_free_ooseq_callback, NULL, 0) != ERR_OK) { \ - SYS_ARCH_PROTECT(old_level); \ - pbuf_free_ooseq_pending = 0; \ - SYS_ARCH_UNPROTECT(old_level); \ - } } while(0) -#endif /* PBUF_POOL_FREE_OOSEQ_QUEUE_CALL */ -#endif /* !NO_SYS */ - -volatile u8_t pbuf_free_ooseq_pending; -#define PBUF_POOL_IS_EMPTY() pbuf_pool_is_empty() - -/** - * Attempt to reclaim some memory from queued out-of-sequence TCP segments - * if we run out of pool pbufs. It's better to give priority to new packets - * if we're running out. - * - * This must be done in the correct thread context therefore this function - * can only be used with NO_SYS=0 and through tcpip_callback. - */ -#if !NO_SYS -static -#endif /* !NO_SYS */ -void -pbuf_free_ooseq(void) -{ - struct tcp_pcb* pcb; - SYS_ARCH_SET(pbuf_free_ooseq_pending, 0); - - for (pcb = tcp_active_pcbs; NULL != pcb; pcb = pcb->next) { - if (NULL != pcb->ooseq) { - /** Free the ooseq pbufs of one PCB only */ - LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_free_ooseq: freeing out-of-sequence pbufs\n")); - tcp_segs_free(pcb->ooseq); - pcb->ooseq = NULL; - return; - } - } -} - -#if !NO_SYS -/** - * Just a callback function for tcpip_callback() that calls pbuf_free_ooseq(). - */ -static void -pbuf_free_ooseq_callback(void *arg) -{ - LWIP_UNUSED_ARG(arg); - pbuf_free_ooseq(); -} -#endif /* !NO_SYS */ - -/** Queue a call to pbuf_free_ooseq if not already queued. */ -static void -pbuf_pool_is_empty(void) -{ -#ifndef PBUF_POOL_FREE_OOSEQ_QUEUE_CALL - SYS_ARCH_SET(pbuf_free_ooseq_pending, 1); -#else /* PBUF_POOL_FREE_OOSEQ_QUEUE_CALL */ - u8_t queued; - SYS_ARCH_DECL_PROTECT(old_level); - SYS_ARCH_PROTECT(old_level); - queued = pbuf_free_ooseq_pending; - pbuf_free_ooseq_pending = 1; - SYS_ARCH_UNPROTECT(old_level); - - if (!queued) { - /* queue a call to pbuf_free_ooseq if not already queued */ - PBUF_POOL_FREE_OOSEQ_QUEUE_CALL(); - } -#endif /* PBUF_POOL_FREE_OOSEQ_QUEUE_CALL */ -} -#endif /* !LWIP_TCP || !TCP_QUEUE_OOSEQ || !PBUF_POOL_FREE_OOSEQ */ - -/** - * Decide which pbuf pool to draw from - */ -memp_t -pbuf_get_target_pool(u16_t length, u16_t offset) -{ - memp_t target_pool; -#if LWIP_PBUF_FROM_CUSTOM_POOLS - u32_t total_length; - target_pool = PBUF_CUSTOM_POOL_IDX_START; - total_length = (u32_t)LWIP_MEM_ALIGN(length + offset + SIZEOF_STRUCT_PBUF); - - /* Start at smallest pool, try to find a pbuf pool whose - * pbufs will accommodate the requested size. Stop when we - * find a pool or when we reach the largest pool */ - while (1) { - if (total_length <= memp_sizes[target_pool] || target_pool == PBUF_CUSTOM_POOL_IDX_END) { - LWIP_DEBUGF(PBUF_DEBUG| LWIP_DBG_TRACE, ("pbuf_get_target_pool: total_len %u memp_sizes %u\n", total_length, memp_sizes[target_pool])); - break; - } - target_pool--; - } -#else - target_pool = MEMP_PBUF_POOL; -#endif - return target_pool; -} - -static struct pbuf * -pbuf_allocate_from_target_pool(memp_t *target_pool) -{ - struct pbuf *p; -#if LWIP_PBUF_FROM_CUSTOM_POOLS - while (1) { - /* allocate head of pbuf chain into p, - * if allocation fails, scan all pbuf pools - * for a suitable pool to use instead */ - p = (struct pbuf *)memp_malloc(*target_pool); - LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_alloc: allocated pbuf %p (%u)\n", (void *)p, *target_pool)); - - /* We have successfully allocated, or we have no more - * pools to try if we failed */ - if (p != NULL) { - p->pool = *target_pool; -#if LWIP_PERF - sys_profile_pbuf_allocate(p); -#endif - break; - } - - if(*target_pool == PBUF_CUSTOM_POOL_IDX_END) { - break; - } - - (*target_pool)--; - } -#else - p = (struct pbuf *)memp_malloc(*target_pool); -#endif - return p; -} - -/** - * @ingroup pbuf - * Allocates a pbuf of the given type (possibly a chain for PBUF_POOL type). - * - * The actual memory allocated for the pbuf is determined by the - * layer at which the pbuf is allocated and the requested size - * (from the size parameter). - * - * @param layer flag to define header size - * @param length size of the pbuf's payload - * @param type this parameter decides how and where the pbuf - * should be allocated as follows: - * - * - PBUF_RAM: buffer memory for pbuf is allocated as one large - * chunk. This includes protocol headers as well. - * - PBUF_ROM: no buffer memory is allocated for the pbuf, even for - * protocol headers. Additional headers must be prepended - * by allocating another pbuf and chain in to the front of - * the ROM pbuf. It is assumed that the memory used is really - * similar to ROM in that it is immutable and will not be - * changed. Memory which is dynamic should generally not - * be attached to PBUF_ROM pbufs. Use PBUF_REF instead. - * - PBUF_REF: no buffer memory is allocated for the pbuf, even for - * protocol headers. It is assumed that the pbuf is only - * being used in a single thread. If the pbuf gets queued, - * then pbuf_take should be called to copy the buffer. - * - PBUF_POOL: the pbuf is allocated as a pbuf chain, with pbufs from - * the pbuf pool that is allocated during pbuf_init(). - * - * @return the allocated pbuf. If multiple pbufs where allocated, this - * is the first pbuf of a pbuf chain. - */ -struct pbuf * -pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type) -{ - struct pbuf *p, *q, *r; - u16_t offset; - s32_t rem_len; /* remaining length */ - LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_alloc(length=%"U16_F")\n", length)); - u32_t aligned_size; - memp_t target_pool; - - /* determine header offset */ - switch (layer) { - case PBUF_TRANSPORT: - /* add room for transport (often TCP) layer header */ - offset = PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN; - break; - case PBUF_IP: - /* add room for IP layer header */ - offset = PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN + PBUF_IP_HLEN; - break; - case PBUF_LINK: - /* add room for link layer header */ - offset = PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN; - break; - case PBUF_RAW_TX: - /* add room for encapsulating link layer headers (e.g. 802.11) */ - offset = PBUF_LINK_ENCAPSULATION_HLEN; - break; - case PBUF_RAW: - /* no offset (e.g. RX buffers or chain successors) */ - offset = 0; - break; - default: - LWIP_ASSERT("pbuf_alloc: bad pbuf layer", 0); - return NULL; - } - - switch (type) { - case PBUF_POOL: - target_pool = pbuf_get_target_pool(length, offset); - p = pbuf_allocate_from_target_pool(&target_pool); - - if (p == NULL) { - PBUF_POOL_IS_EMPTY(); - return NULL; - } - - aligned_size = GET_ALIGNED_PBUF_POOL_SIZE(target_pool); - p->type = type; - p->next = NULL; - - /* make the payload pointer point 'offset' bytes into pbuf data memory */ - p->payload = LWIP_MEM_ALIGN((void *)((u8_t *)p + (SIZEOF_STRUCT_PBUF + offset))); - LWIP_ASSERT("pbuf_alloc: pbuf p->payload properly aligned", - ((mem_ptr_t)p->payload % MEM_ALIGNMENT) == 0); - /* the total length of the pbuf chain is the requested size */ - p->tot_len = length; - /* set the length of the first pbuf in the chain */ - p->len = LWIP_MIN(length, aligned_size - LWIP_MEM_ALIGN_SIZE(offset)); - LWIP_ASSERT("check p->payload + p->len does not overflow pbuf", - ((u8_t*)p->payload + p->len <= - (u8_t*)p + SIZEOF_STRUCT_PBUF + aligned_size)); - LWIP_ASSERT("PBUF_POOL_BUFSIZE must be bigger than MEM_ALIGNMENT", - (aligned_size - LWIP_MEM_ALIGN_SIZE(offset)) > 0 ); - /* set reference count (needed here in case we fail) */ - p->ref = 1; - /* set flags */ - p->flags = 0; - - /* now allocate the tail of the pbuf chain */ - - /* remember first pbuf for linkage in next iteration */ - r = p; - /* remaining length to be allocated */ - rem_len = length - p->len; - /* any remaining pbufs to be allocated? */ - while (rem_len > 0) { - target_pool = pbuf_get_target_pool(rem_len, 0); - q = pbuf_allocate_from_target_pool(&target_pool); - if (q == NULL) { - PBUF_POOL_IS_EMPTY(); - /* free chain so far allocated */ - pbuf_free(p); - /* bail out unsuccessfully */ - return NULL; - } - aligned_size = GET_ALIGNED_PBUF_POOL_SIZE(target_pool); - q->type = type; - q->flags = 0; - q->next = NULL; - /* make previous pbuf point to this pbuf */ - r->next = q; - /* set total length of this pbuf and next in chain */ - LWIP_ASSERT("rem_len < max_u16_t", rem_len < 0xffff); - q->tot_len = (u16_t)rem_len; - /* this pbuf length is pool size, unless smaller sized tail */ - q->len = LWIP_MIN((u16_t)rem_len, aligned_size); - q->payload = (void *)((u8_t *)q + SIZEOF_STRUCT_PBUF); - LWIP_ASSERT("pbuf_alloc: pbuf q->payload properly aligned", - ((mem_ptr_t)q->payload % MEM_ALIGNMENT) == 0); - LWIP_ASSERT("check p->payload + p->len does not overflow pbuf", - ((u8_t*)p->payload + p->len <= - (u8_t*)p + SIZEOF_STRUCT_PBUF + aligned_size)); - q->ref = 1; - /* calculate remaining length to be allocated */ - rem_len -= q->len; - /* remember this pbuf for linkage in next iteration */ - r = q; - } - /* end of chain */ - /*r->next = NULL;*/ - - break; - case PBUF_RAM: - { - u16_t payload_len = (u16_t)(LWIP_MEM_ALIGN_SIZE(offset) + LWIP_MEM_ALIGN_SIZE(length)); - mem_size_t alloc_len = (mem_size_t)(LWIP_MEM_ALIGN_SIZE(SIZEOF_STRUCT_PBUF) + payload_len); - - /* bug #50040: Check for integer overflow when calculating alloc_len */ - if ((payload_len < LWIP_MEM_ALIGN_SIZE(length)) || - (alloc_len < LWIP_MEM_ALIGN_SIZE(length))) { - return NULL; - } - - /* If pbuf is to be allocated in RAM, allocate memory for it. */ - p = (struct pbuf*)mem_malloc(alloc_len); - } - - if (p == NULL) { - return NULL; - } - /* Set up internal structure of the pbuf. */ - p->payload = LWIP_MEM_ALIGN((void *)((u8_t *)p + SIZEOF_STRUCT_PBUF + offset)); - p->len = p->tot_len = length; - p->next = NULL; - p->type = type; - - LWIP_ASSERT("pbuf_alloc: pbuf->payload properly aligned", - ((mem_ptr_t)p->payload % MEM_ALIGNMENT) == 0); - break; - /* pbuf references existing (non-volatile static constant) ROM payload? */ - case PBUF_ROM: - /* pbuf references existing (externally allocated) RAM payload? */ - case PBUF_REF: - /* only allocate memory for the pbuf structure */ - p = (struct pbuf *)memp_malloc(MEMP_PBUF); - if (p == NULL) { - LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_LEVEL_SERIOUS, - ("pbuf_alloc: Could not allocate MEMP_PBUF for PBUF_%s.\n", - (type == PBUF_ROM) ? "ROM" : "REF")); - return NULL; - } - /* caller must set this field properly, afterwards */ - p->payload = NULL; - p->len = p->tot_len = length; - p->next = NULL; - p->type = type; - break; - default: - LWIP_ASSERT("pbuf_alloc: erroneous type", 0); - return NULL; - } - /* set reference count */ - p->ref = 1; - /* set flags */ - p->flags = 0; - LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_alloc(length=%"U16_F") == %p\n", length, (void *)p)); - return p; -} - -#if LWIP_SUPPORT_CUSTOM_PBUF -/** - * @ingroup pbuf - * Initialize a custom pbuf (already allocated). - * - * @param l flag to define header size - * @param length size of the pbuf's payload - * @param type type of the pbuf (only used to treat the pbuf accordingly, as - * this function allocates no memory) - * @param p pointer to the custom pbuf to initialize (already allocated) - * @param payload_mem pointer to the buffer that is used for payload and headers, - * must be at least big enough to hold 'length' plus the header size, - * may be NULL if set later. - * ATTENTION: The caller is responsible for correct alignment of this buffer!! - * @param payload_mem_len the size of the 'payload_mem' buffer, must be at least - * big enough to hold 'length' plus the header size - */ -struct pbuf* -pbuf_alloced_custom(pbuf_layer l, u16_t length, pbuf_type type, struct pbuf_custom *p, - void *payload_mem, u16_t payload_mem_len) -{ - u16_t offset; - LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_alloced_custom(length=%"U16_F")\n", length)); - - /* determine header offset */ - switch (l) { - case PBUF_TRANSPORT: - /* add room for transport (often TCP) layer header */ - offset = PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN + PBUF_IP_HLEN + PBUF_TRANSPORT_HLEN; - break; - case PBUF_IP: - /* add room for IP layer header */ - offset = PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN + PBUF_IP_HLEN; - break; - case PBUF_LINK: - /* add room for link layer header */ - offset = PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN; - break; - case PBUF_RAW_TX: - /* add room for encapsulating link layer headers (e.g. 802.11) */ - offset = PBUF_LINK_ENCAPSULATION_HLEN; - break; - case PBUF_RAW: - offset = 0; - break; - default: - LWIP_ASSERT("pbuf_alloced_custom: bad pbuf layer", 0); - return NULL; - } - - if (LWIP_MEM_ALIGN_SIZE(offset) + length > payload_mem_len) { - LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_LEVEL_WARNING, ("pbuf_alloced_custom(length=%"U16_F") buffer too short\n", length)); - return NULL; - } - - p->pbuf.next = NULL; - if (payload_mem != NULL) { - p->pbuf.payload = (u8_t *)payload_mem + LWIP_MEM_ALIGN_SIZE(offset); - } else { - p->pbuf.payload = NULL; - } - p->pbuf.flags = PBUF_FLAG_IS_CUSTOM; - p->pbuf.len = p->pbuf.tot_len = length; - p->pbuf.type = type; - p->pbuf.ref = 1; - return &p->pbuf; -} -#endif /* LWIP_SUPPORT_CUSTOM_PBUF */ - -/** - * @ingroup pbuf - * Shrink a pbuf chain to a desired length. - * - * @param p pbuf to shrink. - * @param new_len desired new length of pbuf chain - * - * Depending on the desired length, the first few pbufs in a chain might - * be skipped and left unchanged. The new last pbuf in the chain will be - * resized, and any remaining pbufs will be freed. - * - * @note If the pbuf is ROM/REF, only the ->tot_len and ->len fields are adjusted. - * @note May not be called on a packet queue. - * - * @note Despite its name, pbuf_realloc cannot grow the size of a pbuf (chain). - */ -void -pbuf_realloc(struct pbuf *p, u16_t new_len) -{ - struct pbuf *q; - u16_t rem_len; /* remaining length */ - s32_t grow; - - LWIP_ASSERT("pbuf_realloc: p != NULL", p != NULL); - LWIP_ASSERT("pbuf_realloc: sane p->type", p->type == PBUF_POOL || - p->type == PBUF_ROM || - p->type == PBUF_RAM || - p->type == PBUF_REF); - - /* desired length larger than current length? */ - if (new_len >= p->tot_len) { - /* enlarging not yet supported */ - return; - } - - /* the pbuf chain grows by (new_len - p->tot_len) bytes - * (which may be negative in case of shrinking) */ - grow = new_len - p->tot_len; - - /* first, step over any pbufs that should remain in the chain */ - rem_len = new_len; - q = p; - /* should this pbuf be kept? */ - while (rem_len > q->len) { - /* decrease remaining length by pbuf length */ - rem_len -= q->len; - /* decrease total length indicator */ - LWIP_ASSERT("grow < max_u16_t", grow < 0xffff); - q->tot_len += (u16_t)grow; - /* proceed to next pbuf in chain */ - q = q->next; - LWIP_ASSERT("pbuf_realloc: q != NULL", q != NULL); - } - /* we have now reached the new last pbuf (in q) */ - /* rem_len == desired length for pbuf q */ - - /* shrink allocated memory for PBUF_RAM */ - /* (other types merely adjust their length fields */ - if ((q->type == PBUF_RAM) && (rem_len != q->len) -#if LWIP_SUPPORT_CUSTOM_PBUF - && ((q->flags & PBUF_FLAG_IS_CUSTOM) == 0) -#endif /* LWIP_SUPPORT_CUSTOM_PBUF */ - ) { - /* reallocate and adjust the length of the pbuf that will be split */ - q = (struct pbuf *)mem_trim(q, (u16_t)((u8_t *)q->payload - (u8_t *)q) + rem_len); - LWIP_ASSERT("mem_trim returned q == NULL", q != NULL); - } - /* adjust length fields for new last pbuf */ - q->len = rem_len; - q->tot_len = q->len; - - /* any remaining pbufs in chain? */ - if (q->next != NULL) { - /* free remaining pbufs in chain */ - pbuf_free(q->next); - } - /* q is last packet in chain */ - q->next = NULL; - -} - -/** - * Adjusts the payload pointer to hide or reveal headers in the payload. - * @see pbuf_header. - * - * @param p pbuf to change the header size. - * @param header_size_increment Number of bytes to increment header size. - * @param force Allow 'header_size_increment > 0' for PBUF_REF/PBUF_ROM types - * - * @return non-zero on failure, zero on success. - * - */ -static u8_t -pbuf_header_impl(struct pbuf *p, s16_t header_size_increment, u8_t force) -{ - u16_t type; - void *payload; - u16_t increment_magnitude; - - LWIP_ASSERT("p != NULL", p != NULL); - if ((header_size_increment == 0) || (p == NULL)) { - return 0; - } - - if (header_size_increment < 0) { - increment_magnitude = (u16_t)-header_size_increment; - /* Check that we aren't going to move off the end of the pbuf */ - LWIP_ERROR("increment_magnitude <= p->len", (increment_magnitude <= p->len), return 1;); - } else { - increment_magnitude = (u16_t)header_size_increment; -#if 0 - /* Can't assert these as some callers speculatively call - pbuf_header() to see if it's OK. Will return 1 below instead. */ - /* Check that we've got the correct type of pbuf to work with */ - LWIP_ASSERT("p->type == PBUF_RAM || p->type == PBUF_POOL", - p->type == PBUF_RAM || p->type == PBUF_POOL); - /* Check that we aren't going to move off the beginning of the pbuf */ - LWIP_ASSERT("p->payload - increment_magnitude >= p + SIZEOF_STRUCT_PBUF", - (u8_t *)p->payload - increment_magnitude >= (u8_t *)p + SIZEOF_STRUCT_PBUF); -#endif - } - - type = p->type; - /* remember current payload pointer */ - payload = p->payload; - - /* pbuf types containing payloads? */ - if (type == PBUF_RAM || type == PBUF_POOL) { - /* set new payload pointer */ - p->payload = (u8_t *)p->payload - header_size_increment; - /* boundary check fails? */ - if ((u8_t *)p->payload < (u8_t *)p + SIZEOF_STRUCT_PBUF) { - LWIP_DEBUGF( PBUF_DEBUG | LWIP_DBG_TRACE, - ("pbuf_header: failed as %p < %p (not enough space for new header size)\n", - (void *)p->payload, (void *)((u8_t *)p + SIZEOF_STRUCT_PBUF))); - /* restore old payload pointer */ - p->payload = payload; - /* bail out unsuccessfully */ - return 1; - } - /* pbuf types referring to external payloads? */ - } else if (type == PBUF_REF || type == PBUF_ROM) { - /* hide a header in the payload? */ - if ((header_size_increment < 0) && (increment_magnitude <= p->len)) { - /* increase payload pointer */ - p->payload = (u8_t *)p->payload - header_size_increment; - } else if ((header_size_increment > 0) && force) { - p->payload = (u8_t *)p->payload - header_size_increment; - } else { - /* cannot expand payload to front (yet!) - * bail out unsuccessfully */ - return 1; - } - } else { - /* Unknown type */ - LWIP_ASSERT("bad pbuf type", 0); - return 1; - } - /* modify pbuf length fields */ - p->len += header_size_increment; - p->tot_len += header_size_increment; - - LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_header: old %p new %p (%"S16_F")\n", - (void *)payload, (void *)p->payload, header_size_increment)); - - return 0; -} - -/** - * Adjusts the payload pointer to hide or reveal headers in the payload. - * - * Adjusts the ->payload pointer so that space for a header - * (dis)appears in the pbuf payload. - * - * The ->payload, ->tot_len and ->len fields are adjusted. - * - * @param p pbuf to change the header size. - * @param header_size_increment Number of bytes to increment header size which - * increases the size of the pbuf. New space is on the front. - * (Using a negative value decreases the header size.) - * If hdr_size_inc is 0, this function does nothing and returns successful. - * - * PBUF_ROM and PBUF_REF type buffers cannot have their sizes increased, so - * the call will fail. A check is made that the increase in header size does - * not move the payload pointer in front of the start of the buffer. - * @return non-zero on failure, zero on success. - * - */ -u8_t -pbuf_header(struct pbuf *p, s16_t header_size_increment) -{ - return pbuf_header_impl(p, header_size_increment, 0); -} - -/** - * Same as pbuf_header but does not check if 'header_size > 0' is allowed. - * This is used internally only, to allow PBUF_REF for RX. - */ -u8_t -pbuf_header_force(struct pbuf *p, s16_t header_size_increment) -{ - return pbuf_header_impl(p, header_size_increment, 1); -} - -/** - * @ingroup pbuf - * Dereference a pbuf chain or queue and deallocate any no-longer-used - * pbufs at the head of this chain or queue. - * - * Decrements the pbuf reference count. If it reaches zero, the pbuf is - * deallocated. - * - * For a pbuf chain, this is repeated for each pbuf in the chain, - * up to the first pbuf which has a non-zero reference count after - * decrementing. So, when all reference counts are one, the whole - * chain is free'd. - * - * @param p The pbuf (chain) to be dereferenced. - * - * @return the number of pbufs that were de-allocated - * from the head of the chain. - * - * @note MUST NOT be called on a packet queue (Not verified to work yet). - * @note the reference counter of a pbuf equals the number of pointers - * that refer to the pbuf (or into the pbuf). - * - * @internal examples: - * - * Assuming existing chains a->b->c with the following reference - * counts, calling pbuf_free(a) results in: - * - * 1->2->3 becomes ...1->3 - * 3->3->3 becomes 2->3->3 - * 1->1->2 becomes ......1 - * 2->1->1 becomes 1->1->1 - * 1->1->1 becomes ....... - * - */ -u8_t -pbuf_free(struct pbuf *p) -{ - u16_t type; - struct pbuf *q; - u8_t count; - memp_t target_pool; - - if (p == NULL) { - LWIP_ASSERT("p != NULL", p != NULL); - /* if assertions are disabled, proceed with debug output */ - LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_LEVEL_SERIOUS, - ("pbuf_free(p == NULL) was called.\n")); - return 0; - } - LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_free(%p)\n", (void *)p)); - - PERF_START; - - LWIP_ASSERT("pbuf_free: sane type", - p->type == PBUF_RAM || p->type == PBUF_ROM || - p->type == PBUF_REF || p->type == PBUF_POOL); - - count = 0; - /* de-allocate all consecutive pbufs from the head of the chain that - * obtain a zero reference count after decrementing*/ - while (p != NULL) { - u16_t ref; - SYS_ARCH_DECL_PROTECT(old_level); - /* Since decrementing ref cannot be guaranteed to be a single machine operation - * we must protect it. We put the new ref into a local variable to prevent - * further protection. */ - SYS_ARCH_PROTECT(old_level); - /* all pbufs in a chain are referenced at least once */ - LWIP_ASSERT("pbuf_free: p->ref > 0", p->ref > 0); -#if LWIP_PBUF_CALLOUTS - sys_pbuf_free_callout(p); -#endif /* LWIP_PBUF_CALLOUTS */ - /* decrease reference count (number of pointers to pbuf) */ - ref = --(p->ref); - SYS_ARCH_UNPROTECT(old_level); - /* this pbuf is no longer referenced to? */ - if (ref == 0) { - /* remember next pbuf in chain for next iteration */ - q = p->next; - LWIP_DEBUGF( PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_free: deallocating %p\n", (void *)p)); - type = p->type; -#if LWIP_SUPPORT_CUSTOM_PBUF - /* is this a custom pbuf? */ - if ((p->flags & PBUF_FLAG_IS_CUSTOM) != 0) { - struct pbuf_custom *pc = (struct pbuf_custom*)p; - LWIP_ASSERT("pc->custom_free_function != NULL", pc->custom_free_function != NULL); - pc->custom_free_function(p); - } else -#endif /* LWIP_SUPPORT_CUSTOM_PBUF */ - { - /* is this a pbuf from the pool? */ - if (type == PBUF_POOL) { -#if LWIP_PBUF_FROM_CUSTOM_POOLS - target_pool = p->pool; -#if LWIP_PERF - // Record free of buffer before actually freeing for 2 reasons: - // - Pool pointer still valid - // - Prevent buf from being re-allocated before recording free - sys_profile_pbuf_free(p); -#endif -#else - target_pool = MEMP_PBUF_POOL; -#endif - - memp_free(target_pool, p); - /* is this a ROM or RAM referencing pbuf? */ - } else if (type == PBUF_ROM || type == PBUF_REF) { - memp_free(MEMP_PBUF, p); - /* type == PBUF_RAM */ - } else { - mem_free(p); - } - } - count++; - /* proceed to next pbuf */ - p = q; - /* p->ref > 0, this pbuf is still referenced to */ - /* (and so the remaining pbufs in chain as well) */ - } else { - LWIP_DEBUGF( PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_free: %p has ref %"U16_F", ending here.\n", (void *)p, ref)); - /* stop walking through the chain */ - p = NULL; - } - } - PERF_STOP("pbuf_free"); - /* return number of de-allocated pbufs */ - return count; -} - -/** - * Count number of pbufs in a chain - * - * @param p first pbuf of chain - * @return the number of pbufs in a chain - */ -u16_t -pbuf_clen(const struct pbuf *p) -{ - u16_t len; - - len = 0; - while (p != NULL) { - ++len; - p = p->next; - } - return len; -} - -/** - * @ingroup pbuf - * Increment the reference count of the pbuf. - * - * @param p pbuf to increase reference counter of - * - */ -void -pbuf_ref(struct pbuf *p) -{ - /* pbuf given? */ - if (p != NULL) { - SYS_ARCH_INC(p->ref, 1); - LWIP_ASSERT("pbuf ref overflow", p->ref > 0); - } -} - -/** - * @ingroup pbuf - * Concatenate two pbufs (each may be a pbuf chain) and take over - * the caller's reference of the tail pbuf. - * - * @note The caller MAY NOT reference the tail pbuf afterwards. - * Use pbuf_chain() for that purpose. - * - * @see pbuf_chain() - */ -void -pbuf_cat(struct pbuf *h, struct pbuf *t) -{ - struct pbuf *p; - - LWIP_ERROR("(h != NULL) && (t != NULL) (programmer violates API)", - ((h != NULL) && (t != NULL)), return;); - - /* proceed to last pbuf of chain */ - for (p = h; p->next != NULL; p = p->next) { - /* add total length of second chain to all totals of first chain */ - p->tot_len += t->tot_len; - } - /* { p is last pbuf of first h chain, p->next == NULL } */ - LWIP_ASSERT("p->tot_len == p->len (of last pbuf in chain)", p->tot_len == p->len); - LWIP_ASSERT("p->next == NULL", p->next == NULL); - /* add total length of second chain to last pbuf total of first chain */ - p->tot_len += t->tot_len; - /* chain last pbuf of head (p) with first of tail (t) */ - p->next = t; - /* p->next now references t, but the caller will drop its reference to t, - * so netto there is no change to the reference count of t. - */ -} - -/** - * @ingroup pbuf - * Chain two pbufs (or pbuf chains) together. - * - * The caller MUST call pbuf_free(t) once it has stopped - * using it. Use pbuf_cat() instead if you no longer use t. - * - * @param h head pbuf (chain) - * @param t tail pbuf (chain) - * @note The pbufs MUST belong to the same packet. - * @note MAY NOT be called on a packet queue. - * - * The ->tot_len fields of all pbufs of the head chain are adjusted. - * The ->next field of the last pbuf of the head chain is adjusted. - * The ->ref field of the first pbuf of the tail chain is adjusted. - * - */ -void -pbuf_chain(struct pbuf *h, struct pbuf *t) -{ - pbuf_cat(h, t); - /* t is now referenced by h */ - pbuf_ref(t); - LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_chain: %p references %p\n", (void *)h, (void *)t)); -} - -/** - * Dechains the first pbuf from its succeeding pbufs in the chain. - * - * Makes p->tot_len field equal to p->len. - * @param p pbuf to dechain - * @return remainder of the pbuf chain, or NULL if it was de-allocated. - * @note May not be called on a packet queue. - */ -struct pbuf * -pbuf_dechain(struct pbuf *p) -{ - struct pbuf *q; - u8_t tail_gone = 1; - /* tail */ - q = p->next; - /* pbuf has successor in chain? */ - if (q != NULL) { - /* assert tot_len invariant: (p->tot_len == p->len + (p->next? p->next->tot_len: 0) */ - LWIP_ASSERT("p->tot_len == p->len + q->tot_len", q->tot_len == p->tot_len - p->len); - /* enforce invariant if assertion is disabled */ - q->tot_len = p->tot_len - p->len; - /* decouple pbuf from remainder */ - p->next = NULL; - /* total length of pbuf p is its own length only */ - p->tot_len = p->len; - /* q is no longer referenced by p, free it */ - LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_dechain: unreferencing %p\n", (void *)q)); - tail_gone = pbuf_free(q); - if (tail_gone > 0) { - LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, - ("pbuf_dechain: deallocated %p (as it is no longer referenced)\n", (void *)q)); - } - /* return remaining tail or NULL if deallocated */ - } - /* assert tot_len invariant: (p->tot_len == p->len + (p->next? p->next->tot_len: 0) */ - LWIP_ASSERT("p->tot_len == p->len", p->tot_len == p->len); - return ((tail_gone > 0) ? NULL : q); -} - -/** - * @ingroup pbuf - * Create PBUF_RAM copies of pbufs. - * - * Used to queue packets on behalf of the lwIP stack, such as - * ARP based queueing. - * - * @note You MUST explicitly use p = pbuf_take(p); - * - * @note Only one packet is copied, no packet queue! - * - * @param p_to pbuf destination of the copy - * @param p_from pbuf source of the copy - * - * @return ERR_OK if pbuf was copied - * ERR_ARG if one of the pbufs is NULL or p_to is not big - * enough to hold p_from - */ -err_t -pbuf_copy(struct pbuf *p_to, const struct pbuf *p_from) -{ - u16_t offset_to=0, offset_from=0, len; - - LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_copy(%p, %p)\n", - (const void*)p_to, (const void*)p_from)); - - /* is the target big enough to hold the source? */ - LWIP_ERROR("pbuf_copy: target not big enough to hold source", ((p_to != NULL) && - (p_from != NULL) && (p_to->tot_len >= p_from->tot_len)), return ERR_ARG;); - - /* iterate through pbuf chain */ - do - { - /* copy one part of the original chain */ - if ((p_to->len - offset_to) >= (p_from->len - offset_from)) { - /* complete current p_from fits into current p_to */ - len = p_from->len - offset_from; - } else { - /* current p_from does not fit into current p_to */ - len = p_to->len - offset_to; - } - MEMCPY((u8_t*)p_to->payload + offset_to, (u8_t*)p_from->payload + offset_from, len); - offset_to += len; - offset_from += len; - LWIP_ASSERT("offset_to <= p_to->len", offset_to <= p_to->len); - LWIP_ASSERT("offset_from <= p_from->len", offset_from <= p_from->len); - if (offset_from >= p_from->len) { - /* on to next p_from (if any) */ - offset_from = 0; - p_from = p_from->next; - } - if (offset_to == p_to->len) { - /* on to next p_to (if any) */ - offset_to = 0; - p_to = p_to->next; - LWIP_ERROR("p_to != NULL", (p_to != NULL) || (p_from == NULL) , return ERR_ARG;); - } - - if ((p_from != NULL) && (p_from->len == p_from->tot_len)) { - /* don't copy more than one packet! */ - LWIP_ERROR("pbuf_copy() does not allow packet queues!", - (p_from->next == NULL), return ERR_VAL;); - } - if ((p_to != NULL) && (p_to->len == p_to->tot_len)) { - /* don't copy more than one packet! */ - LWIP_ERROR("pbuf_copy() does not allow packet queues!", - (p_to->next == NULL), return ERR_VAL;); - } - } while (p_from); - LWIP_DEBUGF(PBUF_DEBUG | LWIP_DBG_TRACE, ("pbuf_copy: end of chain reached.\n")); - return ERR_OK; -} - -/** - * @ingroup pbuf - * Copy (part of) the contents of a packet buffer - * to an application supplied buffer. - * - * @param buf the pbuf from which to copy data - * @param dataptr the application supplied buffer - * @param len length of data to copy (dataptr must be big enough). No more - * than buf->tot_len will be copied, irrespective of len - * @param offset offset into the packet buffer from where to begin copying len bytes - * @return the number of bytes copied, or 0 on failure - */ -u16_t -pbuf_copy_partial(const struct pbuf *buf, void *dataptr, u16_t len, u16_t offset) -{ - const struct pbuf *p; - u16_t left; - u16_t buf_copy_len; - u16_t copied_total = 0; - - LWIP_ERROR("pbuf_copy_partial: invalid buf", (buf != NULL), return 0;); - LWIP_ERROR("pbuf_copy_partial: invalid dataptr", (dataptr != NULL), return 0;); - - left = 0; - - if ((buf == NULL) || (dataptr == NULL)) { - return 0; - } - - /* Note some systems use byte copy if dataptr or one of the pbuf payload pointers are unaligned. */ - for (p = buf; len != 0 && p != NULL; p = p->next) { - if ((offset != 0) && (offset >= p->len)) { - /* don't copy from this buffer -> on to the next */ - offset -= p->len; - } else { - /* copy from this buffer. maybe only partially. */ - buf_copy_len = p->len - offset; - if (buf_copy_len > len) { - buf_copy_len = len; - } - /* copy the necessary parts of the buffer */ - MEMCPY(&((char*)dataptr)[left], &((char*)p->payload)[offset], buf_copy_len); - copied_total += buf_copy_len; - left += buf_copy_len; - len -= buf_copy_len; - offset = 0; - } - } - return copied_total; -} - -#if LWIP_TCP && TCP_QUEUE_OOSEQ && LWIP_WND_SCALE -/** - * This method modifies a 'pbuf chain', so that its total length is - * smaller than 64K. The remainder of the original pbuf chain is stored - * in *rest. - * This function never creates new pbufs, but splits an existing chain - * in two parts. The tot_len of the modified packet queue will likely be - * smaller than 64K. - * 'packet queues' are not supported by this function. - * - * @param p the pbuf queue to be split - * @param rest pointer to store the remainder (after the first 64K) - */ -void pbuf_split_64k(struct pbuf *p, struct pbuf **rest) -{ - *rest = NULL; - if ((p != NULL) && (p->next != NULL)) { - u16_t tot_len_front = p->len; - struct pbuf *i = p; - struct pbuf *r = p->next; - - /* continue until the total length (summed up as u16_t) overflows */ - while ((r != NULL) && ((u16_t)(tot_len_front + r->len) > tot_len_front)) { - tot_len_front = (u16_t)(tot_len_front + r->len); - i = r; - r = r->next; - } - /* i now points to last packet of the first segment. Set next - pointer to NULL */ - i->next = NULL; - - if (r != NULL) { - /* Update the tot_len field in the first part */ - for (i = p; i != NULL; i = i->next) { - i->tot_len = (u16_t)(i->tot_len - r->tot_len); - LWIP_ASSERT("tot_len/len mismatch in last pbuf", - (i->next != NULL) || (i->tot_len == i->len)); - } - if (p->flags & PBUF_FLAG_TCP_FIN) { - r->flags |= PBUF_FLAG_TCP_FIN; - } - - /* tot_len field in rest does not need modifications */ - /* reference counters do not need modifications */ - *rest = r; - } - } -} -#endif /* LWIP_TCP && TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */ - -/* Actual implementation of pbuf_skip() but returning const pointer... */ -static const struct pbuf* -pbuf_skip_const(const struct pbuf* in, u16_t in_offset, u16_t* out_offset) -{ - u16_t offset_left = in_offset; - const struct pbuf* q = in; - - /* get the correct pbuf */ - while ((q != NULL) && (q->len <= offset_left)) { - offset_left -= q->len; - q = q->next; - } - if (out_offset != NULL) { - *out_offset = offset_left; - } - return q; -} - -/** - * @ingroup pbuf - * Skip a number of bytes at the start of a pbuf - * - * @param in input pbuf - * @param in_offset offset to skip - * @param out_offset resulting offset in the returned pbuf - * @return the pbuf in the queue where the offset is - */ -struct pbuf* -pbuf_skip(struct pbuf* in, u16_t in_offset, u16_t* out_offset) -{ - const struct pbuf* out = pbuf_skip_const(in, in_offset, out_offset); - return LWIP_CONST_CAST(struct pbuf*, out); -} - -/** - * @ingroup pbuf - * Copy application supplied data into a pbuf. - * This function can only be used to copy the equivalent of buf->tot_len data. - * - * @param buf pbuf to fill with data - * @param dataptr application supplied data buffer - * @param len length of the application supplied data buffer - * - * @return ERR_OK if successful, ERR_MEM if the pbuf is not big enough - */ -err_t -pbuf_take(struct pbuf *buf, const void *dataptr, u16_t len) -{ - struct pbuf *p; - u16_t buf_copy_len; - u16_t total_copy_len = len; - u16_t copied_total = 0; - - LWIP_ERROR("pbuf_take: invalid buf", (buf != NULL), return ERR_ARG;); - LWIP_ERROR("pbuf_take: invalid dataptr", (dataptr != NULL), return ERR_ARG;); - LWIP_ERROR("pbuf_take: buf not large enough", (buf->tot_len >= len), return ERR_MEM;); - - if ((buf == NULL) || (dataptr == NULL) || (buf->tot_len < len)) { - return ERR_ARG; - } - - /* Note some systems use byte copy if dataptr or one of the pbuf payload pointers are unaligned. */ - for (p = buf; total_copy_len != 0; p = p->next) { - LWIP_ASSERT("pbuf_take: invalid pbuf", p != NULL); - buf_copy_len = total_copy_len; - if (buf_copy_len > p->len) { - /* this pbuf cannot hold all remaining data */ - buf_copy_len = p->len; - } - /* copy the necessary parts of the buffer */ - MEMCPY(p->payload, &((const char*)dataptr)[copied_total], buf_copy_len); - total_copy_len -= buf_copy_len; - copied_total += buf_copy_len; - } - LWIP_ASSERT("did not copy all data", total_copy_len == 0 && copied_total == len); - return ERR_OK; -} - -/** - * @ingroup pbuf - * Same as pbuf_take() but puts data at an offset - * - * @param buf pbuf to fill with data - * @param dataptr application supplied data buffer - * @param len length of the application supplied data buffer - * @param offset offset in pbuf where to copy dataptr to - * - * @return ERR_OK if successful, ERR_MEM if the pbuf is not big enough - */ -err_t -pbuf_take_at(struct pbuf *buf, const void *dataptr, u16_t len, u16_t offset) -{ - u16_t target_offset; - struct pbuf* q = pbuf_skip(buf, offset, &target_offset); - - /* return requested data if pbuf is OK */ - if ((q != NULL) && (q->tot_len >= target_offset + len)) { - u16_t remaining_len = len; - const u8_t* src_ptr = (const u8_t*)dataptr; - /* copy the part that goes into the first pbuf */ - u16_t first_copy_len = LWIP_MIN(q->len - target_offset, len); - MEMCPY(((u8_t*)q->payload) + target_offset, dataptr, first_copy_len); - remaining_len -= first_copy_len; - src_ptr += first_copy_len; - if (remaining_len > 0) { - return pbuf_take(q->next, src_ptr, remaining_len); - } - return ERR_OK; - } - return ERR_MEM; -} - -/** - * @ingroup pbuf - * Creates a single pbuf out of a queue of pbufs. - * - * @remark: Either the source pbuf 'p' is freed by this function or the original - * pbuf 'p' is returned, therefore the caller has to check the result! - * - * @param p the source pbuf - * @param layer pbuf_layer of the new pbuf - * - * @return a new, single pbuf (p->next is NULL) - * or the old pbuf if allocation fails - */ -struct pbuf* -pbuf_coalesce(struct pbuf *p, pbuf_layer layer) -{ - struct pbuf *q; - err_t err; - if (p->next == NULL) { - return p; - } - q = pbuf_alloc(layer, p->tot_len, PBUF_RAM); - if (q == NULL) { - /* @todo: what do we do now? */ - return p; - } - err = pbuf_copy(q, p); - LWIP_UNUSED_ARG(err); /* in case of LWIP_NOASSERT */ - LWIP_ASSERT("pbuf_copy failed", err == ERR_OK); - pbuf_free(p); - return q; -} - -#if LWIP_CHECKSUM_ON_COPY -/** - * Copies data into a single pbuf (*not* into a pbuf queue!) and updates - * the checksum while copying - * - * @param p the pbuf to copy data into - * @param start_offset offset of p->payload where to copy the data to - * @param dataptr data to copy into the pbuf - * @param len length of data to copy into the pbuf - * @param chksum pointer to the checksum which is updated - * @return ERR_OK if successful, another error if the data does not fit - * within the (first) pbuf (no pbuf queues!) - */ -err_t -pbuf_fill_chksum(struct pbuf *p, u16_t start_offset, const void *dataptr, - u16_t len, u16_t *chksum) -{ - u32_t acc; - u16_t copy_chksum; - char *dst_ptr; - LWIP_ASSERT("p != NULL", p != NULL); - LWIP_ASSERT("dataptr != NULL", dataptr != NULL); - LWIP_ASSERT("chksum != NULL", chksum != NULL); - LWIP_ASSERT("len != 0", len != 0); - - if ((start_offset >= p->len) || (start_offset + len > p->len)) { - return ERR_ARG; - } - - dst_ptr = ((char*)p->payload) + start_offset; - copy_chksum = LWIP_CHKSUM_COPY(dst_ptr, dataptr, len); - if ((start_offset & 1) != 0) { - copy_chksum = SWAP_BYTES_IN_WORD(copy_chksum); - } - acc = *chksum; - acc += copy_chksum; - *chksum = FOLD_U32T(acc); - return ERR_OK; -} -#endif /* LWIP_CHECKSUM_ON_COPY */ - -/** - * @ingroup pbuf - * Get one byte from the specified position in a pbuf - * WARNING: returns zero for offset >= p->tot_len - * - * @param p pbuf to parse - * @param offset offset into p of the byte to return - * @return byte at an offset into p OR ZERO IF 'offset' >= p->tot_len - */ -u8_t -pbuf_get_at(const struct pbuf* p, u16_t offset) -{ - int ret = pbuf_try_get_at(p, offset); - if (ret >= 0) { - return (u8_t)ret; - } - return 0; -} - -/** - * @ingroup pbuf - * Get one byte from the specified position in a pbuf - * - * @param p pbuf to parse - * @param offset offset into p of the byte to return - * @return byte at an offset into p [0..0xFF] OR negative if 'offset' >= p->tot_len - */ -int -pbuf_try_get_at(const struct pbuf* p, u16_t offset) -{ - u16_t q_idx; - const struct pbuf* q = pbuf_skip_const(p, offset, &q_idx); - - /* return requested data if pbuf is OK */ - if ((q != NULL) && (q->len > q_idx)) { - return ((u8_t*)q->payload)[q_idx]; - } - return -1; -} - -/** - * @ingroup pbuf - * Put one byte to the specified position in a pbuf - * WARNING: silently ignores offset >= p->tot_len - * - * @param p pbuf to fill - * @param offset offset into p of the byte to write - * @param data byte to write at an offset into p - */ -void -pbuf_put_at(struct pbuf* p, u16_t offset, u8_t data) -{ - u16_t q_idx; - struct pbuf* q = pbuf_skip(p, offset, &q_idx); - - /* write requested data if pbuf is OK */ - if ((q != NULL) && (q->len > q_idx)) { - ((u8_t*)q->payload)[q_idx] = data; - } -} - -/** - * @ingroup pbuf - * Compare pbuf contents at specified offset with memory s2, both of length n - * - * @param p pbuf to compare - * @param offset offset into p at which to start comparing - * @param s2 buffer to compare - * @param n length of buffer to compare - * @return zero if equal, nonzero otherwise - * (0xffff if p is too short, diffoffset+1 otherwise) - */ -u16_t -pbuf_memcmp(const struct pbuf* p, u16_t offset, const void* s2, u16_t n) -{ - u16_t start = offset; - const struct pbuf* q = p; - u16_t i; - - /* pbuf long enough to perform check? */ - if(p->tot_len < (offset + n)) { - return 0xffff; - } - - /* get the correct pbuf from chain. We know it succeeds because of p->tot_len check above. */ - while ((q != NULL) && (q->len <= start)) { - start -= q->len; - q = q->next; - } - - /* return requested data if pbuf is OK */ - for (i = 0; i < n; i++) { - /* We know pbuf_get_at() succeeds because of p->tot_len check above. */ - u8_t a = pbuf_get_at(q, start + i); - u8_t b = ((const u8_t*)s2)[i]; - if (a != b) { - return i+1; - } - } - return 0; -} - -/** - * @ingroup pbuf - * Find occurrence of mem (with length mem_len) in pbuf p, starting at offset - * start_offset. - * - * @param p pbuf to search, maximum length is 0xFFFE since 0xFFFF is used as - * return value 'not found' - * @param mem search for the contents of this buffer - * @param mem_len length of 'mem' - * @param start_offset offset into p at which to start searching - * @return 0xFFFF if substr was not found in p or the index where it was found - */ -u16_t -pbuf_memfind(const struct pbuf* p, const void* mem, u16_t mem_len, u16_t start_offset) -{ - u16_t i; - u16_t max = p->tot_len - mem_len; - if (p->tot_len >= mem_len + start_offset) { - for (i = start_offset; i <= max; i++) { - u16_t plus = pbuf_memcmp(p, i, mem, mem_len); - if (plus == 0) { - return i; - } - } - } - return 0xFFFF; -} - -/** - * Find occurrence of substr with length substr_len in pbuf p, start at offset - * start_offset - * WARNING: in contrast to strstr(), this one does not stop at the first \0 in - * the pbuf/source string! - * - * @param p pbuf to search, maximum length is 0xFFFE since 0xFFFF is used as - * return value 'not found' - * @param substr string to search for in p, maximum length is 0xFFFE - * @return 0xFFFF if substr was not found in p or the index where it was found - */ -u16_t -pbuf_strstr(const struct pbuf* p, const char* substr) -{ - size_t substr_len; - if ((substr == NULL) || (substr[0] == 0) || (p->tot_len == 0xFFFF)) { - return 0xFFFF; - } - substr_len = strlen(substr); - if (substr_len >= 0xFFFF) { - return 0xFFFF; - } - return pbuf_memfind(p, substr, (u16_t)substr_len, 0); -} - -/** Check if the passed pbuf is allocated from the target pool. - * If not, check for availability of pbuf in the target or a larger pool - * that is smaller than the passed pbuf. - * If available, allocate the new pbuf, copy the contents and free the - * passed pbuf. If there is a valid offset passed, make the 'payload' - * pointer offset bytes from start. - * - * @param p pbuf to evaluate - * @param offset number of bytes to offset the payload pointer. If negative, - * use same offset as in the passed pbuf - * @return the new pbuf if allocated, or passed pbuf otherwise - */ -struct pbuf * -pbuf_rightsize(struct pbuf *p, s16_t offset) -{ -#if LWIP_PBUF_FROM_CUSTOM_POOLS - struct pbuf* q = NULL; - - /* Allow right-sizing only if given pbuf is not chained and - * its reference count is 1*/ - if ((p != NULL) && (p->type == PBUF_POOL) && - (p->len == p->tot_len) && (p->ref == 1)) { - memp_t target_pool; - - if (offset < 0) { - offset = ((u8_t*)p->payload - ((u8_t*)p + SIZEOF_STRUCT_PBUF)); - } - target_pool = pbuf_get_target_pool(p->len, offset); - /* check if p is drawn from the target pool */ - while ((p->pool < target_pool) && (target_pool > PBUF_CUSTOM_POOL_IDX_END)) { - /* check if there is room in the target pool */ - if (memp_is_not_empty(target_pool)) { - q = pbuf_allocate_from_target_pool(&target_pool); - if (q != NULL) { - q->type = PBUF_POOL; - q->next = NULL; - q->ref = 1; - q->flags = p->flags; - /* make the payload pointer point 'offset' bytes into pbuf data memory */ - q->payload = (void *)((u8_t *)q + (SIZEOF_STRUCT_PBUF + offset)); - /* copy payload bytes*/ - MEMCPY((u8_t*)(q->payload), (u8_t*)(p->payload), p->len); - /* set the len */ - q->len = q->tot_len = p->len; -#if LWIP_PERF - /* record transfer of pbuf */ - sys_profile_pbuf_transfer(q, p); -#endif - /* free the passed pbuf */ - pbuf_free(p); - p = NULL; - break; - } - } - target_pool--; - } - } - if (p == NULL) - p = q; -#endif - return p; -} diff --git a/third_party/lwip/repo/lwip/src/core/raw.c b/third_party/lwip/repo/lwip/src/core/raw.c deleted file mode 100644 index 16d484f7bc7402..00000000000000 --- a/third_party/lwip/repo/lwip/src/core/raw.c +++ /dev/null @@ -1,645 +0,0 @@ -/** - * @file - * Implementation of raw protocol PCBs for low-level handling of - * different types of protocols besides (or overriding) those - * already available in lwIP.\n - * See also @ref raw_raw - * - * @defgroup raw_raw RAW - * @ingroup callbackstyle_api - * Implementation of raw protocol PCBs for low-level handling of - * different types of protocols besides (or overriding) those - * already available in lwIP.\n - * @see @ref raw_api - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ - -#include "lwip/opt.h" - -#if LWIP_RAW /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/def.h" -#include "lwip/memp.h" -#include "lwip/ip_addr.h" -#include "lwip/netif.h" -#include "lwip/raw.h" -#include "lwip/stats.h" -#include "lwip/ip6.h" -#include "lwip/ip6_addr.h" -#include "lwip/inet_chksum.h" - -#include - -/** The list of RAW PCBs */ -static struct raw_pcb *raw_pcbs; - -static u8_t -raw_input_local_match(struct raw_pcb *pcb, u8_t broadcast) -{ - LWIP_UNUSED_ARG(broadcast); /* in IPv6 only case */ - - /* check if PCB is bound to specific netif */ - if ((pcb->netif_idx != NETIF_NO_INDEX) && - (pcb->netif_idx != netif_get_index(ip_data.current_input_netif))) { - return 0; - } - -#if LWIP_IPV4 && LWIP_IPV6 - /* Dual-stack: PCBs listening to any IP type also listen to any IP address */ - if (IP_IS_ANY_TYPE_VAL(pcb->local_ip)) { -#if IP_SOF_BROADCAST_RECV - if ((broadcast != 0) && !ip_get_option(pcb, SOF_BROADCAST)) { - return 0; - } -#endif /* IP_SOF_BROADCAST_RECV */ - return 1; - } -#endif /* LWIP_IPV4 && LWIP_IPV6 */ - - /* Only need to check PCB if incoming IP version matches PCB IP version */ - if (IP_ADDR_PCB_VERSION_MATCH_EXACT(pcb, ip_current_dest_addr())) { -#if LWIP_IPV4 - /* Special case: IPv4 broadcast: receive all broadcasts - * Note: broadcast variable can only be 1 if it is an IPv4 broadcast */ - if (broadcast != 0) { -#if IP_SOF_BROADCAST_RECV - if (ip_get_option(pcb, SOF_BROADCAST)) -#endif /* IP_SOF_BROADCAST_RECV */ - { - if (ip4_addr_isany(ip_2_ip4(&pcb->local_ip))) { - return 1; - } - } - } else -#endif /* LWIP_IPV4 */ - /* Handle IPv4 and IPv6: catch all or exact match */ - if (ip_addr_isany(&pcb->local_ip) || - ip_addr_cmp(&pcb->local_ip, ip_current_dest_addr())) { - return 1; - } - } - - return 0; -} - -/** - * Determine if in incoming IP packet is covered by a RAW PCB - * and if so, pass it to a user-provided receive callback function. - * - * Given an incoming IP datagram (as a chain of pbufs) this function - * finds a corresponding RAW PCB and calls the corresponding receive - * callback function. - * - * @param p pbuf to be demultiplexed to a RAW PCB. - * @param inp network interface on which the datagram was received. - * @return - 1 if the packet has been eaten by a RAW PCB receive - * callback function. The caller MAY NOT not reference the - * packet any longer, and MAY NOT call pbuf_free(). - * @return - 0 if packet is not eaten (pbuf is still referenced by the - * caller). - * - */ -u8_t -raw_input(struct pbuf *p, struct netif *inp) -{ - struct raw_pcb *pcb, *prev; - s16_t proto; - u8_t eaten = 0; - u8_t broadcast = ip_addr_isbroadcast(ip_current_dest_addr(), ip_current_netif()); - - LWIP_UNUSED_ARG(inp); - -#if LWIP_IPV6 -#if LWIP_IPV4 - if (IP_HDR_GET_VERSION(p->payload) == 6) -#endif /* LWIP_IPV4 */ - { - struct ip6_hdr *ip6hdr = (struct ip6_hdr *)p->payload; - proto = IP6H_NEXTH(ip6hdr); - } -#if LWIP_IPV4 - else -#endif /* LWIP_IPV4 */ -#endif /* LWIP_IPV6 */ -#if LWIP_IPV4 - { - proto = IPH_PROTO((struct ip_hdr *)p->payload); - } -#endif /* LWIP_IPV4 */ - - prev = NULL; - pcb = raw_pcbs; - /* loop through all raw pcbs until the packet is eaten by one */ - /* this allows multiple pcbs to match against the packet by design */ - while ((eaten == 0) && (pcb != NULL)) { - - if ((pcb->protocol == proto) && raw_input_local_match(pcb, broadcast) && - (((pcb->intf_filter == NULL || pcb->intf_filter == inp) && - (ip_addr_isany(&pcb->local_ip) || - ip_addr_cmp(&(pcb->local_ip), ip_current_dest_addr()))) || - (((pcb->flags & RAW_FLAGS_CONNECTED) == 0) || - ip_addr_cmp(&pcb->remote_ip, ip_current_src_addr()))) - ) { - /* receive callback function available? */ -#if IP_SOF_BROADCAST_RECV - /* broadcast filter? */ - if ((ip_get_option(pcb, SOF_BROADCAST) || !ip_addr_isbroadcast(ip_current_dest_addr(), inp)) -#if LWIP_IPV6 - && !PCB_ISIPV6(pcb) -#endif /* LWIP_IPV6 */ - ) -#endif /* IP_SOF_BROADCAST_RECV */ - { -#ifndef LWIP_NOASSERT - void* old_payload = p->payload; -#endif - /* receive callback function available? */ - if (pcb->recv != NULL) { - /* the receive callback function did not eat the packet? */ - eaten = pcb->recv(pcb->recv_arg, pcb, p, ip_current_src_addr()); - if (eaten != 0) { - /* receive function ate the packet */ - p = NULL; - eaten = 1; - if (prev != NULL) { - /* move the pcb to the front of raw_pcbs so that is - found faster next time */ - prev->next = pcb->next; - pcb->next = raw_pcbs; - raw_pcbs = pcb; - } - } - } else { - /* sanity-check that the receive callback did not alter the pbuf */ - LWIP_ASSERT("raw pcb recv callback altered pbuf payload pointer without eating packet", - p->payload == old_payload); - } - } - /* no receive callback function was set for this raw PCB */ - } - /* drop the packet */ - prev = pcb; - pcb = pcb->next; - } - return eaten; -} - -/** - * @ingroup raw_raw - * Bind a RAW PCB. - * - * @param pcb RAW PCB to be bound with a local address ipaddr. - * @param ipaddr local IP address to bind with. Use IP4_ADDR_ANY to - * bind to all local interfaces. - * - * @return lwIP error code. - * - ERR_OK. Successful. No error occurred. - * - ERR_USE. The specified IP address is already bound to by - * another RAW PCB. - * - * @see raw_disconnect() - */ -err_t -raw_bind(struct raw_pcb *pcb, const ip_addr_t *ipaddr) -{ - LWIP_ASSERT_CORE_LOCKED(); - if ((pcb == NULL) || (ipaddr == NULL)) { - return ERR_VAL; - } - ip_addr_set_ipaddr(&pcb->local_ip, ipaddr); - return ERR_OK; -} - -/** - * @ingroup raw_raw - * Bind a RAW PCB. - * - * @param pcb RAW PCB to be bound with netif. - * @param netif netif to bind to. Can be NULL. - * - * @see raw_disconnect() - */ -void -raw_bind_netif(struct raw_pcb *pcb, const struct netif *netif) -{ - if (netif != NULL) { - pcb->netif_idx = netif_get_index(netif); - } else { - pcb->netif_idx = NETIF_NO_INDEX; - } -} - -/** - * @ingroup raw_raw - * Connect an RAW PCB. This function is required by upper layers - * of lwip. Using the raw api you could use raw_sendto() instead - * - * This will associate the RAW PCB with the remote address. - * - * @param pcb RAW PCB to be connected with remote address ipaddr and port. - * @param ipaddr remote IP address to connect with. - * - * @return lwIP error code - * - * @see raw_disconnect() and raw_sendto() - */ -err_t -raw_connect(struct raw_pcb *pcb, const ip_addr_t *ipaddr) -{ - LWIP_ASSERT_CORE_LOCKED(); - if ((pcb == NULL) || (ipaddr == NULL)) { - return ERR_VAL; - } - ip_addr_set_ipaddr(&pcb->remote_ip, ipaddr); - raw_set_flags(pcb, RAW_FLAGS_CONNECTED); - return ERR_OK; -} - -/** - * @ingroup raw_raw - * Disconnect a RAW PCB. - * - * @param pcb the raw pcb to disconnect. - */ -void -raw_disconnect(struct raw_pcb *pcb) -{ - LWIP_ASSERT_CORE_LOCKED(); - /* reset remote address association */ -#if LWIP_IPV4 && LWIP_IPV6 - if (IP_IS_ANY_TYPE_VAL(pcb->local_ip)) { - ip_addr_copy(pcb->remote_ip, *IP_ANY_TYPE); - } else { -#endif - ip_addr_set_any(IP_IS_V6_VAL(pcb->remote_ip), &pcb->remote_ip); -#if LWIP_IPV4 && LWIP_IPV6 - } -#endif - pcb->netif_idx = NETIF_NO_INDEX; - /* mark PCB as unconnected */ - raw_clear_flags(pcb, RAW_FLAGS_CONNECTED); -} - -/** - * @ingroup raw_raw - * Set the callback function for received packets that match the - * raw PCB's protocol and binding. - * - * The callback function MUST either - * - eat the packet by calling pbuf_free() and returning non-zero. The - * packet will not be passed to other raw PCBs or other protocol layers. - * - not free the packet, and return zero. The packet will be matched - * against further PCBs and/or forwarded to another protocol layers. - */ -void -raw_recv(struct raw_pcb *pcb, raw_recv_fn recv, void *recv_arg) -{ - LWIP_ASSERT_CORE_LOCKED(); - /* remember recv() callback and user data */ - pcb->recv = recv; - pcb->recv_arg = recv_arg; -} - -/** - * @ingroup raw_raw - * Send the raw IP packet to the given address. Note that actually you cannot - * modify the IP headers (this is inconsistent with the receive callback where - * you actually get the IP headers), you can only specify the IP payload here. - * It requires some more changes in lwIP. (there will be a raw_send() function - * then.) - * - * @param pcb the raw pcb which to send - * @param p the IP payload to send - * @param ipaddr the destination address of the IP packet - * - */ -err_t -raw_sendto(struct raw_pcb *pcb, struct pbuf *p, const ip_addr_t *ipaddr) -{ - struct netif *netif; - const ip_addr_t *src_ip; - - if ((pcb == NULL) || (ipaddr == NULL) || !IP_ADDR_PCB_VERSION_MATCH(pcb, ipaddr)) { - return ERR_VAL; - } - - LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_TRACE, ("raw_sendto\n")); - - if (pcb->intf_filter != NULL) { - netif = pcb->intf_filter; - } else if (pcb->netif_idx != NETIF_NO_INDEX) { - netif = netif_get_by_index(pcb->netif_idx); - } else { -#if LWIP_MULTICAST_TX_OPTIONS - netif = NULL; - if (ip_addr_ismulticast(ipaddr)) { - /* For multicast-destined packets, use the user-provided interface index to - * determine the outgoing interface, if an interface index is set and a - * matching netif can be found. Otherwise, fall back to regular routing. */ - netif = netif_get_by_index(pcb->mcast_ifindex); - } - - if (netif == NULL) -#endif /* LWIP_MULTICAST_TX_OPTIONS */ - { - netif = ip_route(&pcb->local_ip, ipaddr); - } - } - - if (netif == NULL) { - LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_LEVEL_WARNING, ("raw_sendto: No route to ")); - ip_addr_debug_print(RAW_DEBUG | LWIP_DBG_LEVEL_WARNING, ipaddr); - return ERR_RTE; - } - - if (ip_addr_isany(&pcb->local_ip) || ip_addr_ismulticast(&pcb->local_ip)) { - /* use outgoing network interface IP address as source address */ - src_ip = ip_netif_get_local_ip(netif, ipaddr); -#if LWIP_IPV6 - if (src_ip == NULL) { - return ERR_RTE; - } -#endif /* LWIP_IPV6 */ - } else { - /* use RAW PCB local IP address as source address */ - src_ip = &pcb->local_ip; - } - - return raw_sendto_if_src(pcb, p, ipaddr, netif, src_ip); -} - -/** - * @ingroup raw_raw - * Send the raw IP packet to the given address, using a particular outgoing - * netif and source IP address. An IP header will be prepended to the packet. - * - * @param pcb RAW PCB used to send the data - * @param p chain of pbufs to be sent - * @param dst_ip destination IP address - * @param netif the netif used for sending - * @param src_ip source IP address - */ -err_t -raw_sendto_if_src(struct raw_pcb *pcb, struct pbuf *p, const ip_addr_t *dst_ip, - struct netif *netif, const ip_addr_t *src_ip) -{ - err_t err; - struct pbuf *q; /* q will be sent down the stack */ - s16_t header_size; - u8_t ttl; - - if ((pcb == NULL) || (dst_ip == NULL) || (netif == NULL) || (src_ip == NULL) || - !IP_ADDR_PCB_VERSION_MATCH(pcb, src_ip) || !IP_ADDR_PCB_VERSION_MATCH(pcb, dst_ip)) { - return ERR_VAL; - } - - header_size = ( -#if LWIP_IPV4 && LWIP_IPV6 - IP_IS_V6(dst_ip) ? IP6_HLEN : IP_HLEN); -#elif LWIP_IPV4 - IP_HLEN); -#else - IP6_HLEN); -#endif - - /* not enough space to add an IP header to first pbuf in given p chain? */ - if (pbuf_header(p, header_size)) { - /* allocate header in new pbuf */ - q = pbuf_alloc(PBUF_IP, 0, PBUF_RAM); - /* new header pbuf could not be allocated? */ - if (q == NULL) { - LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("raw_sendto: could not allocate header\n")); - return ERR_MEM; - } - if (p->tot_len != 0) { - /* chain header q in front of given pbuf p */ - pbuf_chain(q, p); - } - /* { first pbuf q points to header pbuf } */ - LWIP_DEBUGF(RAW_DEBUG, ("raw_sendto: added header pbuf %p before given pbuf %p\n", (void *)q, (void *)p)); - } else { - /* first pbuf q equals given pbuf */ - q = p; - if (pbuf_header(q, (s16_t)-header_size)) { - LWIP_ASSERT("Can't restore header we just removed!", 0); - return ERR_MEM; - } - } - -#if IP_SOF_BROADCAST - if (IP_IS_V4(dst_ip)) - { - /* broadcast filter? */ - if (!ip_get_option(pcb, SOF_BROADCAST) && ip_addr_isbroadcast(dst_ip, netif)) { - LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_LEVEL_WARNING, ("raw_sendto: SOF_BROADCAST not enabled on pcb %p\n", (void *)pcb)); - /* free any temporary header pbuf allocated by pbuf_header() */ - if (q != p) { - pbuf_free(q); - } - return ERR_VAL; - } - } -#endif /* IP_SOF_BROADCAST */ - - /* Multicast Loop? */ -#if LWIP_MULTICAST_TX_OPTIONS - if (((pcb->flags & RAW_FLAGS_MULTICAST_LOOP) != 0) && ip_addr_ismulticast(dst_ip)) { - q->flags |= PBUF_FLAG_MCASTLOOP; - } -#endif /* LWIP_MULTICAST_TX_OPTIONS */ - -#if LWIP_IPV6 - /* If requested, based on the IPV6_CHECKSUM socket option per RFC3542, - compute the checksum and update the checksum in the payload. */ - if (IP_IS_V6(dst_ip) && pcb->chksum_reqd) { - u16_t chksum = ip6_chksum_pseudo(p, pcb->protocol, p->tot_len, ip_2_ip6(src_ip), ip_2_ip6(dst_ip)); - LWIP_ASSERT("Checksum must fit into first pbuf", p->len >= (pcb->chksum_offset + 2)); - SMEMCPY(((u8_t *)p->payload) + pcb->chksum_offset, &chksum, sizeof(u16_t)); - } -#endif - - /* Determine TTL to use */ -#if LWIP_MULTICAST_TX_OPTIONS - ttl = (ip_addr_ismulticast(dst_ip) ? raw_get_multicast_ttl(pcb) : pcb->ttl); -#else /* LWIP_MULTICAST_TX_OPTIONS */ - ttl = pcb->ttl; -#endif /* LWIP_MULTICAST_TX_OPTIONS */ - - netif_apply_pcb(netif, (struct ip_pcb *)pcb); - err = ip_output_if(q, src_ip, dst_ip, ttl, pcb->tos, pcb->protocol, netif); - netif_apply_pcb(netif, NULL); - - /* did we chain a header earlier? */ - if (q != p) { - /* free the header */ - pbuf_free(q); - } - return err; -} - -/** - * @ingroup raw_raw - * Send the raw IP packet to the address given by raw_connect() - * - * @param pcb the raw pcb which to send - * @param p the IP payload to send - * - */ -err_t -raw_send(struct raw_pcb *pcb, struct pbuf *p) -{ - return raw_sendto(pcb, p, &pcb->remote_ip); -} - -/** - * @ingroup raw_raw - * Remove an RAW PCB. - * - * @param pcb RAW PCB to be removed. The PCB is removed from the list of - * RAW PCB's and the data structure is freed from memory. - * - * @see raw_new() - */ -void -raw_remove(struct raw_pcb *pcb) -{ - struct raw_pcb *pcb2; - LWIP_ASSERT_CORE_LOCKED(); - /* pcb to be removed is first in list? */ - if (raw_pcbs == pcb) { - /* make list start at 2nd pcb */ - raw_pcbs = raw_pcbs->next; - /* pcb not 1st in list */ - } else { - for (pcb2 = raw_pcbs; pcb2 != NULL; pcb2 = pcb2->next) { - /* find pcb in raw_pcbs list */ - if (pcb2->next != NULL && pcb2->next == pcb) { - /* remove pcb from list */ - pcb2->next = pcb->next; - break; - } - } - } - memp_free(MEMP_RAW_PCB, pcb); -} - -/** - * @ingroup raw_raw - * Create a RAW PCB. - * - * @return The RAW PCB which was created. NULL if the PCB data structure - * could not be allocated. - * - * @param proto the protocol number of the IPs payload (e.g. IP_PROTO_ICMP) - * - * @see raw_remove() - */ -struct raw_pcb * -raw_new(u8_t proto) -{ - struct raw_pcb *pcb; - - LWIP_DEBUGF(RAW_DEBUG | LWIP_DBG_TRACE, ("raw_new\n")); - LWIP_ASSERT_CORE_LOCKED(); - - pcb = (struct raw_pcb *)memp_malloc(MEMP_RAW_PCB); - /* could allocate RAW PCB? */ - if (pcb != NULL) { - /* initialize PCB to all zeroes */ - memset(pcb, 0, sizeof(struct raw_pcb)); - pcb->protocol = proto; - pcb->ttl = RAW_TTL; -#if LWIP_MULTICAST_TX_OPTIONS - raw_set_multicast_ttl(pcb, RAW_TTL); -#endif /* LWIP_MULTICAST_TX_OPTIONS */ - pcb->next = raw_pcbs; - raw_pcbs = pcb; - } - return pcb; -} - -/** - * @ingroup raw_raw - * Create a RAW PCB for specific IP type. - * - * @return The RAW PCB which was created. NULL if the PCB data structure - * could not be allocated. - * - * @param type IP address type, see @ref lwip_ip_addr_type definitions. - * If you want to listen to IPv4 and IPv6 (dual-stack) packets, - * supply @ref IPADDR_TYPE_ANY as argument and bind to @ref IP_ANY_TYPE. - * @param proto the protocol number (next header) of the IPv6 packet payload - * (e.g. IP6_NEXTH_ICMP6) - * - * @see raw_remove() - */ -struct raw_pcb * -raw_new_ip_type(u8_t type, u8_t proto) -{ - struct raw_pcb *pcb; - LWIP_ASSERT_CORE_LOCKED(); - pcb = raw_new(proto); -#if LWIP_IPV4 && LWIP_IPV6 - if (pcb != NULL) { - IP_SET_TYPE_VAL(pcb->local_ip, type); - IP_SET_TYPE_VAL(pcb->remote_ip, type); - } -#else /* LWIP_IPV4 && LWIP_IPV6 */ - LWIP_UNUSED_ARG(type); -#endif /* LWIP_IPV4 && LWIP_IPV6 */ - return pcb; -} - -/** This function is called from netif.c when address is changed - * - * @param old_addr IP address of the netif before change - * @param new_addr IP address of the netif after change - */ -void raw_netif_ip_addr_changed(const ip_addr_t* old_addr, const ip_addr_t* new_addr) -{ - struct raw_pcb* rpcb; - - if (!ip_addr_isany(old_addr) && !ip_addr_isany(new_addr)) { - for (rpcb = raw_pcbs; rpcb != NULL; rpcb = rpcb->next) { - /* PCB bound to current local interface address? */ - if (ip_addr_cmp(&rpcb->local_ip, old_addr)) { - /* The PCB is bound to the old ipaddr and - * is set to bound to the new one instead */ - ip_addr_copy(rpcb->local_ip, *new_addr); - } - } - } -} - -#endif /* LWIP_RAW */ diff --git a/third_party/lwip/repo/lwip/src/core/stats.c b/third_party/lwip/repo/lwip/src/core/stats.c deleted file mode 100644 index 893d199c0447ab..00000000000000 --- a/third_party/lwip/repo/lwip/src/core/stats.c +++ /dev/null @@ -1,169 +0,0 @@ -/** - * @file - * Statistics module - * - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ - -#include "lwip/opt.h" - -#if LWIP_STATS /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/def.h" -#include "lwip/stats.h" -#include "lwip/mem.h" -#include "lwip/debug.h" - -#include - -struct stats_ lwip_stats; - -void -stats_init(void) -{ -#ifdef LWIP_DEBUG -#if MEM_STATS - lwip_stats.mem.name = "MEM"; -#endif /* MEM_STATS */ -#endif /* LWIP_DEBUG */ -} - -#if LWIP_STATS_DISPLAY -void -stats_display_proto(struct stats_proto *proto, const char *name) -{ - LWIP_PLATFORM_DIAG(("\n%s\n\t", name)); - LWIP_PLATFORM_DIAG(("xmit: %"STAT_COUNTER_F"\n\t", proto->xmit)); - LWIP_PLATFORM_DIAG(("recv: %"STAT_COUNTER_F"\n\t", proto->recv)); - LWIP_PLATFORM_DIAG(("fw: %"STAT_COUNTER_F"\n\t", proto->fw)); - LWIP_PLATFORM_DIAG(("drop: %"STAT_COUNTER_F"\n\t", proto->drop)); - LWIP_PLATFORM_DIAG(("chkerr: %"STAT_COUNTER_F"\n\t", proto->chkerr)); - LWIP_PLATFORM_DIAG(("lenerr: %"STAT_COUNTER_F"\n\t", proto->lenerr)); - LWIP_PLATFORM_DIAG(("memerr: %"STAT_COUNTER_F"\n\t", proto->memerr)); - LWIP_PLATFORM_DIAG(("rterr: %"STAT_COUNTER_F"\n\t", proto->rterr)); - LWIP_PLATFORM_DIAG(("proterr: %"STAT_COUNTER_F"\n\t", proto->proterr)); - LWIP_PLATFORM_DIAG(("opterr: %"STAT_COUNTER_F"\n\t", proto->opterr)); - LWIP_PLATFORM_DIAG(("err: %"STAT_COUNTER_F"\n\t", proto->err)); - LWIP_PLATFORM_DIAG(("cachehit: %"STAT_COUNTER_F"\n", proto->cachehit)); -} - -#if IGMP_STATS || MLD6_STATS -void -stats_display_igmp(struct stats_igmp *igmp, const char *name) -{ - LWIP_PLATFORM_DIAG(("\n%s\n\t", name)); - LWIP_PLATFORM_DIAG(("xmit: %"STAT_COUNTER_F"\n\t", igmp->xmit)); - LWIP_PLATFORM_DIAG(("recv: %"STAT_COUNTER_F"\n\t", igmp->recv)); - LWIP_PLATFORM_DIAG(("drop: %"STAT_COUNTER_F"\n\t", igmp->drop)); - LWIP_PLATFORM_DIAG(("chkerr: %"STAT_COUNTER_F"\n\t", igmp->chkerr)); - LWIP_PLATFORM_DIAG(("lenerr: %"STAT_COUNTER_F"\n\t", igmp->lenerr)); - LWIP_PLATFORM_DIAG(("memerr: %"STAT_COUNTER_F"\n\t", igmp->memerr)); - LWIP_PLATFORM_DIAG(("proterr: %"STAT_COUNTER_F"\n\t", igmp->proterr)); - LWIP_PLATFORM_DIAG(("rx_v1: %"STAT_COUNTER_F"\n\t", igmp->rx_v1)); - LWIP_PLATFORM_DIAG(("rx_group: %"STAT_COUNTER_F"\n\t", igmp->rx_group)); - LWIP_PLATFORM_DIAG(("rx_general: %"STAT_COUNTER_F"\n\t", igmp->rx_general)); - LWIP_PLATFORM_DIAG(("rx_report: %"STAT_COUNTER_F"\n\t", igmp->rx_report)); - LWIP_PLATFORM_DIAG(("tx_join: %"STAT_COUNTER_F"\n\t", igmp->tx_join)); - LWIP_PLATFORM_DIAG(("tx_leave: %"STAT_COUNTER_F"\n\t", igmp->tx_leave)); - LWIP_PLATFORM_DIAG(("tx_report: %"STAT_COUNTER_F"\n", igmp->tx_report)); -} -#endif /* IGMP_STATS || MLD6_STATS */ - -#if MEM_STATS || MEMP_STATS -void -stats_display_mem(struct stats_mem *mem, const char *name) -{ - LWIP_PLATFORM_DIAG(("\nMEM %s\n\t", name)); - LWIP_PLATFORM_DIAG(("avail: %"U32_F"\n\t", (u32_t)mem->avail)); - LWIP_PLATFORM_DIAG(("used: %"U32_F"\n\t", (u32_t)mem->used)); - LWIP_PLATFORM_DIAG(("max: %"U32_F"\n\t", (u32_t)mem->max)); - LWIP_PLATFORM_DIAG(("err: %"U32_F"\n", (u32_t)mem->err)); -} - -#if MEMP_STATS -void -stats_display_memp(struct stats_mem *mem, int index) -{ - if (index < MEMP_MAX) { - stats_display_mem(mem, mem->name); - } -} -#endif /* MEMP_STATS */ -#endif /* MEM_STATS || MEMP_STATS */ - -#if SYS_STATS -void -stats_display_sys(struct stats_sys *sys) -{ - LWIP_PLATFORM_DIAG(("\nSYS\n\t")); - LWIP_PLATFORM_DIAG(("sem.used: %"U32_F"\n\t", (u32_t)sys->sem.used)); - LWIP_PLATFORM_DIAG(("sem.max: %"U32_F"\n\t", (u32_t)sys->sem.max)); - LWIP_PLATFORM_DIAG(("sem.err: %"U32_F"\n\t", (u32_t)sys->sem.err)); - LWIP_PLATFORM_DIAG(("mutex.used: %"U32_F"\n\t", (u32_t)sys->mutex.used)); - LWIP_PLATFORM_DIAG(("mutex.max: %"U32_F"\n\t", (u32_t)sys->mutex.max)); - LWIP_PLATFORM_DIAG(("mutex.err: %"U32_F"\n\t", (u32_t)sys->mutex.err)); - LWIP_PLATFORM_DIAG(("mbox.used: %"U32_F"\n\t", (u32_t)sys->mbox.used)); - LWIP_PLATFORM_DIAG(("mbox.max: %"U32_F"\n\t", (u32_t)sys->mbox.max)); - LWIP_PLATFORM_DIAG(("mbox.err: %"U32_F"\n", (u32_t)sys->mbox.err)); -} -#endif /* SYS_STATS */ - -void -stats_display(void) -{ - s16_t i; - - LINK_STATS_DISPLAY(); - ETHARP_STATS_DISPLAY(); - IPFRAG_STATS_DISPLAY(); - IP6_FRAG_STATS_DISPLAY(); - IP_STATS_DISPLAY(); - ND6_STATS_DISPLAY(); - IP6_STATS_DISPLAY(); - IGMP_STATS_DISPLAY(); - MLD6_STATS_DISPLAY(); - ICMP_STATS_DISPLAY(); - ICMP6_STATS_DISPLAY(); - UDP_STATS_DISPLAY(); - TCP_STATS_DISPLAY(); - MEM_STATS_DISPLAY(); - for (i = 0; i < MEMP_MAX; i++) { - MEMP_STATS_DISPLAY(i); - } - SYS_STATS_DISPLAY(); -} -#endif /* LWIP_STATS_DISPLAY */ - -#endif /* LWIP_STATS */ - diff --git a/third_party/lwip/repo/lwip/src/core/sys.c b/third_party/lwip/repo/lwip/src/core/sys.c deleted file mode 100644 index 7059b4de5be9be..00000000000000 --- a/third_party/lwip/repo/lwip/src/core/sys.c +++ /dev/null @@ -1,106 +0,0 @@ -/** - * @file - * lwIP Operating System abstraction - * - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ - -/** - * @defgroup sys_layer Porting (system abstraction layer) - * @ingroup lwip - * @verbinclude "sys_arch.txt" - * - * @defgroup sys_os OS abstraction layer - * @ingroup sys_layer - * No need to implement functions in this section in NO_SYS mode. - * - * @defgroup sys_sem Semaphores - * @ingroup sys_os - * - * @defgroup sys_mutex Mutexes - * @ingroup sys_os - * Mutexes are recommended to correctly handle priority inversion, - * especially if you use LWIP_CORE_LOCKING . - * - * @defgroup sys_mbox Mailboxes - * @ingroup sys_os - * - * @defgroup sys_time Time - * @ingroup sys_layer - * - * @defgroup sys_prot Critical sections - * @ingroup sys_layer - * Used to protect short regions of code against concurrent access. - * - Your system is a bare-metal system (probably with an RTOS) - * and interrupts are under your control: - * Implement this as LockInterrupts() / UnlockInterrupts() - * - Your system uses an RTOS with deferred interrupt handling from a - * worker thread: Implement as a global mutex or lock/unlock scheduler - * - Your system uses a high-level OS with e.g. POSIX signals: - * Implement as a global mutex - * - * @defgroup sys_misc Misc - * @ingroup sys_os - */ - -#include "lwip/opt.h" - -#include "lwip/sys.h" - -/* Most of the functions defined in sys.h must be implemented in the - * architecture-dependent file sys_arch.c */ - -#if !NO_SYS - -#ifndef sys_msleep -/** - * Sleep for some ms. Timeouts are NOT processed while sleeping. - * - * @param ms number of milliseconds to sleep - */ -void -sys_msleep(u32_t ms) -{ - if (ms > 0) { - sys_sem_t delaysem; - err_t err = sys_sem_new(&delaysem, 0); - if (err == ERR_OK) { - sys_arch_sem_wait(&delaysem, ms); - sys_sem_free(&delaysem); - } - } -} -#endif /* sys_msleep */ - -#endif /* !NO_SYS */ diff --git a/third_party/lwip/repo/lwip/src/core/tcp.c b/third_party/lwip/repo/lwip/src/core/tcp.c deleted file mode 100644 index 1c44f0075471fe..00000000000000 --- a/third_party/lwip/repo/lwip/src/core/tcp.c +++ /dev/null @@ -1,2214 +0,0 @@ -/** - * @file - * Transmission Control Protocol for IP - * See also @ref tcp_raw - * - * @defgroup tcp_raw TCP - * @ingroup callbackstyle_api - * Transmission Control Protocol for IP\n - * @see @ref raw_api and @ref netconn - * - * Common functions for the TCP implementation, such as functinos - * for manipulating the data structures and the TCP timer functions. TCP functions - * related to input and output is found in tcp_in.c and tcp_out.c respectively.\n - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ - -#include "lwip/opt.h" - -#if LWIP_TCP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/def.h" -#include "lwip/mem.h" -#include "lwip/memp.h" -#include "lwip/tcp.h" -#include "lwip/priv/tcp_priv.h" -#include "lwip/debug.h" -#include "lwip/stats.h" -#include "lwip/ip6.h" -#include "lwip/ip6_addr.h" -#include "lwip/nd6.h" - -#include - -#ifdef LWIP_HOOK_FILENAME -#include LWIP_HOOK_FILENAME -#endif - -#ifndef TCP_LOCAL_PORT_RANGE_START -/* From http://www.iana.org/assignments/port-numbers: - "The Dynamic and/or Private Ports are those from 49152 through 65535" */ -#define TCP_LOCAL_PORT_RANGE_START 0xc000 -#define TCP_LOCAL_PORT_RANGE_END 0xffff -#define TCP_ENSURE_LOCAL_PORT_RANGE(port) ((u16_t)(((port) & (u16_t)~TCP_LOCAL_PORT_RANGE_START) + TCP_LOCAL_PORT_RANGE_START)) -#endif - -#if LWIP_TCP_KEEPALIVE -#define TCP_KEEP_DUR(pcb) ((pcb)->keep_cnt * (pcb)->keep_intvl) -#define TCP_KEEP_INTVL(pcb) ((pcb)->keep_intvl) -#else /* LWIP_TCP_KEEPALIVE */ -#define TCP_KEEP_DUR(pcb) TCP_MAXIDLE -#define TCP_KEEP_INTVL(pcb) TCP_KEEPINTVL_DEFAULT -#endif /* LWIP_TCP_KEEPALIVE */ - -/* As initial send MSS, we use TCP_MSS but limit it to 536. */ -#if TCP_MSS > 536 -#define INITIAL_MSS 536 -#else -#define INITIAL_MSS TCP_MSS -#endif - -static const char * const tcp_state_str[] = { - "CLOSED", - "LISTEN", - "SYN_SENT", - "SYN_RCVD", - "ESTABLISHED", - "FIN_WAIT_1", - "FIN_WAIT_2", - "CLOSE_WAIT", - "CLOSING", - "LAST_ACK", - "TIME_WAIT" -}; - -/* last local TCP port */ -static u16_t tcp_port = TCP_LOCAL_PORT_RANGE_START; - -/* Incremented every coarse grained timer shot (typically every 500 ms). */ -u32_t tcp_ticks; -static const u8_t tcp_backoff[13] = - { 1, 2, 3, 4, 5, 6, 7, 7, 7, 7, 7, 7, 7}; - /* Times per slowtmr hits */ -static const u8_t tcp_persist_backoff[7] = { 3, 6, 12, 24, 48, 96, 120 }; - -/* The TCP PCB lists. */ - -/** List of all TCP PCBs bound but not yet (connected || listening) */ -struct tcp_pcb *tcp_bound_pcbs; -/** List of all TCP PCBs in LISTEN state */ -union tcp_listen_pcbs_t tcp_listen_pcbs; -/** List of all TCP PCBs that are in a state in which - * they accept or send data. */ -struct tcp_pcb *tcp_active_pcbs; -/** List of all TCP PCBs in TIME-WAIT state */ -struct tcp_pcb *tcp_tw_pcbs; - -/** An array with all (non-temporary) PCB lists, mainly used for smaller code size */ -struct tcp_pcb ** const tcp_pcb_lists[] = {&tcp_listen_pcbs.pcbs, &tcp_bound_pcbs, - &tcp_active_pcbs, &tcp_tw_pcbs}; - -u8_t tcp_active_pcbs_changed; - -/** Timer counter to handle calling slow-timer from tcp_tmr() */ -static u8_t tcp_timer; -static u8_t tcp_timer_ctr; -static u16_t tcp_new_port(void); - -static err_t tcp_close_shutdown_fin(struct tcp_pcb *pcb); - -/** - * Initialize this module. - */ -void -tcp_init(void) -{ -#if LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS && defined(LWIP_RAND) - tcp_port = TCP_ENSURE_LOCAL_PORT_RANGE(LWIP_RAND()); -#endif /* LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS && defined(LWIP_RAND) */ -} - -/** - * Called periodically to dispatch TCP timers. - */ -void -tcp_tmr(void) -{ - /* Call tcp_fasttmr() every 250 ms */ - tcp_fasttmr(); - - if (++tcp_timer & 1) { - /* Call tcp_slowtmr() every 500 ms, i.e., every other timer - tcp_tmr() is called. */ - tcp_slowtmr(); - } -} - -#if LWIP_CALLBACK_API || TCP_LISTEN_BACKLOG -/** Called when a listen pcb is closed. Iterates one pcb list and removes the - * closed listener pcb from pcb->listener if matching. - */ -static void -tcp_remove_listener(struct tcp_pcb *list, struct tcp_pcb_listen *lpcb) -{ - struct tcp_pcb *pcb; - for (pcb = list; pcb != NULL; pcb = pcb->next) { - if (pcb->listener == lpcb) { - pcb->listener = NULL; - } - } -} -#endif - -/** Called when a listen pcb is closed. Iterates all pcb lists and removes the - * closed listener pcb from pcb->listener if matching. - */ -static void -tcp_listen_closed(struct tcp_pcb *pcb) -{ -#if LWIP_CALLBACK_API || TCP_LISTEN_BACKLOG - size_t i; - LWIP_ASSERT("pcb != NULL", pcb != NULL); - LWIP_ASSERT("pcb->state == LISTEN", pcb->state == LISTEN); - for (i = 1; i < LWIP_ARRAYSIZE(tcp_pcb_lists); i++) { - tcp_remove_listener(*tcp_pcb_lists[i], (struct tcp_pcb_listen*)pcb); - } -#endif - LWIP_UNUSED_ARG(pcb); -} - -#if TCP_LISTEN_BACKLOG -/** @ingroup tcp_raw - * Delay accepting a connection in respect to the listen backlog: - * the number of outstanding connections is increased until - * tcp_backlog_accepted() is called. - * - * ATTENTION: the caller is responsible for calling tcp_backlog_accepted() - * or else the backlog feature will get out of sync! - * - * @param pcb the connection pcb which is not fully accepted yet - */ -void -tcp_backlog_delayed(struct tcp_pcb* pcb) -{ - LWIP_ASSERT("pcb != NULL", pcb != NULL); - LWIP_ASSERT_CORE_LOCKED(); - if ((pcb->flags & TF_BACKLOGPEND) == 0) { - if (pcb->listener != NULL) { - pcb->listener->accepts_pending++; - LWIP_ASSERT("accepts_pending != 0", pcb->listener->accepts_pending != 0); - pcb->flags |= TF_BACKLOGPEND; - } - } -} - -/** @ingroup tcp_raw - * A delayed-accept a connection is accepted (or closed/aborted): decreases - * the number of outstanding connections after calling tcp_backlog_delayed(). - * - * ATTENTION: the caller is responsible for calling tcp_backlog_accepted() - * or else the backlog feature will get out of sync! - * - * @param pcb the connection pcb which is now fully accepted (or closed/aborted) - */ -void -tcp_backlog_accepted(struct tcp_pcb* pcb) -{ - LWIP_ASSERT("pcb != NULL", pcb != NULL); - LWIP_ASSERT_CORE_LOCKED(); - if ((pcb->flags & TF_BACKLOGPEND) != 0) { - if (pcb->listener != NULL) { - LWIP_ASSERT("accepts_pending != 0", pcb->listener->accepts_pending != 0); - pcb->listener->accepts_pending--; - tcp_clear_flags(pcb, TF_BACKLOGPEND); - } - } -} -#endif /* TCP_LISTEN_BACKLOG */ - -/** - * Closes the TX side of a connection held by the PCB. - * For tcp_close(), a RST is sent if the application didn't receive all data - * (tcp_recved() not called for all data passed to recv callback). - * - * Listening pcbs are freed and may not be referenced any more. - * Connection pcbs are freed if not yet connected and may not be referenced - * any more. If a connection is established (at least SYN received or in - * a closing state), the connection is closed, and put in a closing state. - * The pcb is then automatically freed in tcp_slowtmr(). It is therefore - * unsafe to reference it. - * - * @param pcb the tcp_pcb to close - * @return ERR_OK if connection has been closed - * another err_t if closing failed and pcb is not freed - */ -static err_t -tcp_close_shutdown(struct tcp_pcb *pcb, u8_t rst_on_unacked_data) -{ - if (rst_on_unacked_data && ((pcb->state == ESTABLISHED) || (pcb->state == CLOSE_WAIT))) { - if ((pcb->refused_data != NULL) || (pcb->rcv_wnd != TCP_WND_MAX(pcb))) { - /* Not all data received by application, send RST to tell the remote - side about this. */ - LWIP_ASSERT("pcb->flags & TF_RXCLOSED", pcb->flags & TF_RXCLOSED); - - /* don't call tcp_abort here: we must not deallocate the pcb since - that might not be expected when calling tcp_close */ - tcp_rst(pcb->snd_nxt, pcb->rcv_nxt, &pcb->local_ip, &pcb->remote_ip, - pcb->local_port, pcb->remote_port); - - tcp_pcb_purge(pcb); - TCP_RMV_ACTIVE(pcb); - if (pcb->state == ESTABLISHED) { - /* move to TIME_WAIT since we close actively */ - pcb->state = TIME_WAIT; - TCP_REG(&tcp_tw_pcbs, pcb); - } else { - /* CLOSE_WAIT: deallocate the pcb since we already sent a RST for it */ - if (tcp_input_pcb == pcb) { - /* prevent using a deallocated pcb: free it from tcp_input later */ - tcp_trigger_input_pcb_close(); - } else { - memp_free(MEMP_TCP_PCB, pcb); - } - } - return ERR_OK; - } - } - - /* - states which free the pcb are handled here, - - states which send FIN and change state are handled in tcp_close_shutdown_fin() */ - switch (pcb->state) { - case CLOSED: - /* Closing a pcb in the CLOSED state might seem erroneous, - * however, it is in this state once allocated and as yet unused - * and the user needs some way to free it should the need arise. - * Calling tcp_close() with a pcb that has already been closed, (i.e. twice) - * or for a pcb that has been used and then entered the CLOSED state - * is erroneous, but this should never happen as the pcb has in those cases - * been freed, and so any remaining handles are bogus. */ - if (pcb->local_port != 0) { - TCP_RMV(&tcp_bound_pcbs, pcb); - } - memp_free(MEMP_TCP_PCB, pcb); - break; - case LISTEN: - tcp_listen_closed(pcb); - tcp_pcb_remove(&tcp_listen_pcbs.pcbs, pcb); - memp_free(MEMP_TCP_PCB_LISTEN, pcb); - break; - case SYN_SENT: - TCP_PCB_REMOVE_ACTIVE(pcb); - memp_free(MEMP_TCP_PCB, pcb); - MIB2_STATS_INC(mib2.tcpattemptfails); - break; - default: - return tcp_close_shutdown_fin(pcb); - } - return ERR_OK; -} - -static err_t -tcp_close_shutdown_fin(struct tcp_pcb *pcb) -{ - err_t err; - LWIP_ASSERT("pcb != NULL", pcb != NULL); - - switch (pcb->state) { - case SYN_RCVD: - err = tcp_send_fin(pcb); - if (err == ERR_OK) { - tcp_backlog_accepted(pcb); - MIB2_STATS_INC(mib2.tcpattemptfails); - pcb->state = FIN_WAIT_1; - } - break; - case ESTABLISHED: - err = tcp_send_fin(pcb); - if (err == ERR_OK) { - MIB2_STATS_INC(mib2.tcpestabresets); - pcb->state = FIN_WAIT_1; - } - break; - case CLOSE_WAIT: - err = tcp_send_fin(pcb); - if (err == ERR_OK) { - MIB2_STATS_INC(mib2.tcpestabresets); - pcb->state = LAST_ACK; - } - break; - default: - /* Has already been closed, do nothing. */ - return ERR_OK; - } - - if (err == ERR_OK) { - /* To ensure all data has been sent when tcp_close returns, we have - to make sure tcp_output doesn't fail. - Since we don't really have to ensure all data has been sent when tcp_close - returns (unsent data is sent from tcp timer functions, also), we don't care - for the return value of tcp_output for now. */ - tcp_output(pcb); - } else if (err == ERR_MEM) { - /* Mark this pcb for closing. Closing is retried from tcp_tmr. */ - pcb->flags |= TF_CLOSEPEND; - /* We have to return ERR_OK from here to indicate to the callers that this - pcb should not be used any more as it will be freed soon via tcp_tmr. - This is OK here since sending FIN does not guarantee a time frime for - actually freeing the pcb, either (it is left in closure states for - remote ACK or timeout) */ - return ERR_OK; - } - return err; -} - -/** - * @ingroup tcp_raw - * Closes the connection held by the PCB. - * - * Listening pcbs are freed and may not be referenced any more. - * Connection pcbs are freed if not yet connected and may not be referenced - * any more. If a connection is established (at least SYN received or in - * a closing state), the connection is closed, and put in a closing state. - * The pcb is then automatically freed in tcp_slowtmr(). It is therefore - * unsafe to reference it (unless an error is returned). - * - * @param pcb the tcp_pcb to close - * @return ERR_OK if connection has been closed - * another err_t if closing failed and pcb is not freed - */ -err_t -tcp_close(struct tcp_pcb *pcb) -{ - LWIP_DEBUGF(TCP_DEBUG, ("tcp_close: closing in ")); - LWIP_ASSERT_CORE_LOCKED(); - tcp_debug_print_state(pcb->state); - - if (pcb->state != LISTEN) { - /* Set a flag not to receive any more data... */ - pcb->flags |= TF_RXCLOSED; - } - /* ... and close */ - return tcp_close_shutdown(pcb, 1); -} - -/** - * @ingroup tcp_raw - * Causes all or part of a full-duplex connection of this PCB to be shut down. - * This doesn't deallocate the PCB unless shutting down both sides! - * Shutting down both sides is the same as calling tcp_close, so if it succeds - * (i.e. returns ER_OK), the PCB must not be referenced any more! - * - * @param pcb PCB to shutdown - * @param shut_rx shut down receive side if this is != 0 - * @param shut_tx shut down send side if this is != 0 - * @return ERR_OK if shutdown succeeded (or the PCB has already been shut down) - * another err_t on error. - */ -err_t -tcp_shutdown(struct tcp_pcb *pcb, int shut_rx, int shut_tx) -{ - LWIP_ASSERT_CORE_LOCKED(); - if (pcb->state == LISTEN) { - return ERR_CONN; - } - if (shut_rx) { - /* shut down the receive side: set a flag not to receive any more data... */ - pcb->flags |= TF_RXCLOSED; - if (shut_tx) { - /* shutting down the tx AND rx side is the same as closing for the raw API */ - return tcp_close_shutdown(pcb, 1); - } - /* ... and free buffered data */ - if (pcb->refused_data != NULL) { - pbuf_free(pcb->refused_data); - pcb->refused_data = NULL; - } - } - if (shut_tx) { - /* This can't happen twice since if it succeeds, the pcb's state is changed. - Only close in these states as the others directly deallocate the PCB */ - switch (pcb->state) { - case SYN_RCVD: - case ESTABLISHED: - case CLOSE_WAIT: - return tcp_close_shutdown(pcb, (u8_t)shut_rx); - default: - /* Not (yet?) connected, cannot shutdown the TX side as that would bring us - into CLOSED state, where the PCB is deallocated. */ - return ERR_CONN; - } - } - return ERR_OK; -} - -/** - * Abandons a connection and optionally sends a RST to the remote - * host. Deletes the local protocol control block. This is done when - * a connection is killed because of shortage of memory. - * - * @param pcb the tcp_pcb to abort - * @param reset boolean to indicate whether a reset should be sent - */ -void -tcp_abandon(struct tcp_pcb *pcb, int reset) -{ - u32_t seqno, ackno; -#if LWIP_CALLBACK_API - tcp_err_fn errf; -#endif /* LWIP_CALLBACK_API */ - void *errf_arg; - - LWIP_ASSERT_CORE_LOCKED(); - /* pcb->state LISTEN not allowed here */ - LWIP_ASSERT("don't call tcp_abort/tcp_abandon for listen-pcbs", - pcb->state != LISTEN); - /* Figure out on which TCP PCB list we are, and remove us. If we - are in an active state, call the receive function associated with - the PCB with a NULL argument, and send an RST to the remote end. */ - if (pcb->state == TIME_WAIT) { - tcp_pcb_remove(&tcp_tw_pcbs, pcb); - memp_free(MEMP_TCP_PCB, pcb); - } else { - int send_rst = 0; - u16_t local_port = 0; - enum tcp_state last_state; - seqno = pcb->snd_nxt; - ackno = pcb->rcv_nxt; -#if LWIP_CALLBACK_API - errf = pcb->errf; -#endif /* LWIP_CALLBACK_API */ - errf_arg = pcb->callback_arg; - if (pcb->state == CLOSED) { - if (pcb->local_port != 0) { - /* bound, not yet opened */ - TCP_RMV(&tcp_bound_pcbs, pcb); - } - } else { - send_rst = reset; - local_port = pcb->local_port; - TCP_PCB_REMOVE_ACTIVE(pcb); - } - if (pcb->unacked != NULL) { - tcp_segs_free(pcb->unacked); - } - if (pcb->unsent != NULL) { - tcp_segs_free(pcb->unsent); - } -#if TCP_QUEUE_OOSEQ - if (pcb->ooseq != NULL) { - tcp_segs_free(pcb->ooseq); - } -#endif /* TCP_QUEUE_OOSEQ */ - tcp_backlog_accepted(pcb); - if (send_rst) { - LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_abandon: sending RST\n")); - tcp_rst(seqno, ackno, &pcb->local_ip, &pcb->remote_ip, local_port, pcb->remote_port); - } - last_state = pcb->state; - memp_free(MEMP_TCP_PCB, pcb); - TCP_EVENT_ERR(last_state, errf, errf_arg, ERR_ABRT); - } -} - -/** - * @ingroup tcp_raw - * Aborts the connection by sending a RST (reset) segment to the remote - * host. The pcb is deallocated. This function never fails. - * - * ATTENTION: When calling this from one of the TCP callbacks, make - * sure you always return ERR_ABRT (and never return ERR_ABRT otherwise - * or you will risk accessing deallocated memory or memory leaks! - * - * @param pcb the tcp pcb to abort - */ -void -tcp_abort(struct tcp_pcb *pcb) -{ - tcp_abandon(pcb, 1); -} - -/** - * @ingroup tcp_raw - * Binds the connection to a local port number and IP address. If the - * IP address is not given (i.e., ipaddr == NULL), the IP address of - * the outgoing network interface is used instead. - * - * @param pcb the tcp_pcb to bind (no check is done whether this pcb is - * already bound!) - * @param ipaddr the local ip address to bind to (use IPx_ADDR_ANY to bind - * to any local address - * @param port the local port to bind to - * @return ERR_USE if the port is already in use - * ERR_VAL if bind failed because the PCB is not in a valid state - * ERR_OK if bound - */ -err_t -tcp_bind(struct tcp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port) -{ - int i; - int max_pcb_list = NUM_TCP_PCB_LISTS; - struct tcp_pcb *cpcb; - - LWIP_ASSERT_CORE_LOCKED(); - -#if LWIP_IPV4 - /* Don't propagate NULL pointer (IPv4 ANY) to subsequent functions */ - if (ipaddr == NULL) { - ipaddr = IP4_ADDR_ANY; - } -#endif /* LWIP_IPV4 */ - - /* still need to check for ipaddr == NULL in IPv6 only case */ - if ((pcb == NULL) || (ipaddr == NULL)) { - return ERR_VAL; - } - - LWIP_ERROR("tcp_bind: can only bind in state CLOSED", pcb->state == CLOSED, return ERR_VAL); - -#if SO_REUSE - /* Unless the REUSEADDR flag is set, - we have to check the pcbs in TIME-WAIT state, also. - We do not dump TIME_WAIT pcb's; they can still be matched by incoming - packets using both local and remote IP addresses and ports to distinguish. - */ - if (ip_get_option(pcb, SOF_REUSEADDR)) { - max_pcb_list = NUM_TCP_PCB_LISTS_NO_TIME_WAIT; - } -#endif /* SO_REUSE */ - - if (port == 0) { - port = tcp_new_port(); - if (port == 0) { - return ERR_BUF; - } - } else { - /* Check if the address already is in use (on all lists) */ - for (i = 0; i < max_pcb_list; i++) { - for (cpcb = *tcp_pcb_lists[i]; cpcb != NULL; cpcb = cpcb->next) { - if (cpcb->local_port == port) { -#if SO_REUSE - /* Omit checking for the same port if both pcbs have REUSEADDR set. - For SO_REUSEADDR, the duplicate-check for a 5-tuple is done in - tcp_connect. */ - if (!ip_get_option(pcb, SOF_REUSEADDR) || - !ip_get_option(cpcb, SOF_REUSEADDR)) -#endif /* SO_REUSE */ - { - /* @todo: check accept_any_ip_version */ - if ((IP_IS_V6(ipaddr) == IP_IS_V6_VAL(cpcb->local_ip)) && - (ip_addr_isany(&cpcb->local_ip) || - ip_addr_isany(ipaddr) || - ip_addr_cmp(&cpcb->local_ip, ipaddr))) { - return ERR_USE; - } - } - } - } - } - } - - if (!ip_addr_isany(ipaddr)) { - ip_addr_set(&pcb->local_ip, ipaddr); - } - pcb->local_port = port; - TCP_REG(&tcp_bound_pcbs, pcb); - LWIP_DEBUGF(TCP_DEBUG, ("tcp_bind: bind to port %"U16_F"\n", port)); - return ERR_OK; -} - -/** - * @ingroup tcp_raw - * Binds the connection to a netif and IP address. - * - * @param pcb the tcp_pcb to bind. - * @param netif the netif to bind to. Can be NULL. - */ -void -tcp_bind_netif(struct tcp_pcb *pcb, const struct netif *netif) -{ - if (netif != NULL) { - pcb->netif_idx = netif_get_index(netif); - } else { - pcb->netif_idx = NETIF_NO_INDEX; - } -} - -#if LWIP_CALLBACK_API -/** - * Default accept callback if no accept callback is specified by the user. - */ -static err_t -tcp_accept_null(void *arg, struct tcp_pcb *pcb, err_t err) -{ - LWIP_UNUSED_ARG(arg); - LWIP_UNUSED_ARG(err); - - tcp_abort(pcb); - - return ERR_ABRT; -} -#endif /* LWIP_CALLBACK_API */ - -/** - * @ingroup tcp_raw - * Set the state of the connection to be LISTEN, which means that it - * is able to accept incoming connections. The protocol control block - * is reallocated in order to consume less memory. Setting the - * connection to LISTEN is an irreversible process. - * - * @param pcb the original tcp_pcb - * @param backlog the incoming connections queue limit - * @return tcp_pcb used for listening, consumes less memory. - * - * @note The original tcp_pcb is freed. This function therefore has to be - * called like this: - * tpcb = tcp_listen_with_backlog(tpcb, backlog); - */ -struct tcp_pcb * -tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog) -{ - LWIP_ASSERT_CORE_LOCKED(); - return tcp_listen_with_backlog_and_err(pcb, backlog, NULL); -} - -/** - * @ingroup tcp_raw - * Set the state of the connection to be LISTEN, which means that it - * is able to accept incoming connections. The protocol control block - * is reallocated in order to consume less memory. Setting the - * connection to LISTEN is an irreversible process. - * - * @param pcb the original tcp_pcb - * @param backlog the incoming connections queue limit - * @param err when NULL is returned, this contains the error reason - * @return tcp_pcb used for listening, consumes less memory. - * - * @note The original tcp_pcb is freed. This function therefore has to be - * called like this: - * tpcb = tcp_listen_with_backlog_and_err(tpcb, backlog, &err); - */ -struct tcp_pcb * -tcp_listen_with_backlog_and_err(struct tcp_pcb *pcb, u8_t backlog, err_t *err) -{ - struct tcp_pcb_listen *lpcb = NULL; - err_t res; - - LWIP_UNUSED_ARG(backlog); - LWIP_ASSERT_CORE_LOCKED(); - LWIP_ERROR("tcp_listen: pcb already connected", pcb->state == CLOSED, res = ERR_CLSD; goto done); - - /* already listening? */ - if (pcb->state == LISTEN) { - lpcb = (struct tcp_pcb_listen*)pcb; - res = ERR_ALREADY; - goto done; - } -#if SO_REUSE - if (ip_get_option(pcb, SOF_REUSEADDR)) { - /* Since SOF_REUSEADDR allows reusing a local address before the pcb's usage - is declared (listen-/connection-pcb), we have to make sure now that - this port is only used once for every local IP. */ - for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) { - if ((lpcb->local_port == pcb->local_port) && - ip_addr_cmp(&lpcb->local_ip, &pcb->local_ip)) { - /* this address/port is already used */ - lpcb = NULL; - res = ERR_USE; - goto done; - } - } - } -#endif /* SO_REUSE */ - lpcb = (struct tcp_pcb_listen *)memp_malloc(MEMP_TCP_PCB_LISTEN); - if (lpcb == NULL) { - res = ERR_MEM; - goto done; - } - lpcb->callback_arg = pcb->callback_arg; - lpcb->local_port = pcb->local_port; - lpcb->state = LISTEN; - lpcb->prio = pcb->prio; - lpcb->so_options = pcb->so_options; - lpcb->ttl = pcb->ttl; - lpcb->tos = pcb->tos; -#if LWIP_IPV4 && LWIP_IPV6 - IP_SET_TYPE_VAL(lpcb->remote_ip, pcb->local_ip.type); -#endif /* LWIP_IPV4 && LWIP_IPV6 */ - ip_addr_copy(lpcb->local_ip, pcb->local_ip); - if (pcb->local_port != 0) { - TCP_RMV(&tcp_bound_pcbs, pcb); - } - memp_free(MEMP_TCP_PCB, pcb); -#if LWIP_CALLBACK_API - lpcb->accept = tcp_accept_null; -#endif /* LWIP_CALLBACK_API */ -#if TCP_LISTEN_BACKLOG - lpcb->accepts_pending = 0; - tcp_backlog_set(lpcb, backlog); -#endif /* TCP_LISTEN_BACKLOG */ - TCP_REG(&tcp_listen_pcbs.pcbs, (struct tcp_pcb *)lpcb); - res = ERR_OK; -done: - if (err != NULL) { - *err = res; - } - return (struct tcp_pcb *)lpcb; -} - -/** - * Update the state that tracks the available window space to advertise. - * - * Returns how much extra window would be advertised if we sent an - * update now. - */ -u32_t -tcp_update_rcv_ann_wnd(struct tcp_pcb *pcb) -{ - u32_t new_right_edge = pcb->rcv_nxt + pcb->rcv_wnd; - - if (TCP_SEQ_GEQ(new_right_edge, pcb->rcv_ann_right_edge + LWIP_MIN((TCP_WND / 2), pcb->mss))) { - /* we can advertise more window */ - pcb->rcv_ann_wnd = pcb->rcv_wnd; - return new_right_edge - pcb->rcv_ann_right_edge; - } else { - if (TCP_SEQ_GT(pcb->rcv_nxt, pcb->rcv_ann_right_edge)) { - /* Can happen due to other end sending out of advertised window, - * but within actual available (but not yet advertised) window */ - pcb->rcv_ann_wnd = 0; - } else { - /* keep the right edge of window constant */ - u32_t new_rcv_ann_wnd = pcb->rcv_ann_right_edge - pcb->rcv_nxt; -#if !LWIP_WND_SCALE - LWIP_ASSERT("new_rcv_ann_wnd <= 0xffff", new_rcv_ann_wnd <= 0xffff); -#endif - pcb->rcv_ann_wnd = (tcpwnd_size_t)new_rcv_ann_wnd; - } - return 0; - } -} - -/** - * @ingroup tcp_raw - * This function should be called by the application when it has - * processed the data. The purpose is to advertise a larger window - * when the data has been processed. - * - * @param pcb the tcp_pcb for which data is read - * @param len the amount of bytes that have been read by the application - */ -void -tcp_recved(struct tcp_pcb *pcb, u16_t len) -{ - uint32_t wnd_inflation; - - LWIP_ASSERT_CORE_LOCKED(); - /* pcb->state LISTEN not allowed here */ - LWIP_ASSERT("don't call tcp_recved for listen-pcbs", - pcb->state != LISTEN); - - pcb->rcv_wnd = (tcpwnd_size_t)(pcb->rcv_wnd + len); - if (pcb->rcv_wnd > TCP_WND_MAX(pcb)) { - pcb->rcv_wnd = TCP_WND_MAX(pcb); - } else if (pcb->rcv_wnd == 0) { - /* rcv_wnd overflowed */ - if ((pcb->state == CLOSE_WAIT) || (pcb->state == LAST_ACK)) { - /* In passive close, we allow this, since the FIN bit is added to rcv_wnd - by the stack itself, since it is not mandatory for an application - to call tcp_recved() for the FIN bit, but e.g. the netconn API does so. */ - pcb->rcv_wnd = TCP_WND_MAX(pcb); - } else { - LWIP_ASSERT("tcp_recved: len wrapped rcv_wnd\n", 0); - } - } - - wnd_inflation = tcp_update_rcv_ann_wnd(pcb); - - /* If the change in the right edge of window is significant (default - * watermark is TCP_WND/4), then send an explicit update now. - * Otherwise wait for a packet to be sent in the normal course of - * events (or more window to be available later) */ - if (wnd_inflation >= TCP_WND_UPDATE_THRESHOLD) { - tcp_ack_now(pcb); - tcp_output(pcb); - } - - LWIP_DEBUGF(TCP_DEBUG, ("tcp_recved: received %"U16_F" bytes, wnd %"TCPWNDSIZE_F" (%"TCPWNDSIZE_F").\n", - len, pcb->rcv_wnd, (u16_t)(TCP_WND_MAX(pcb) - pcb->rcv_wnd))); -} - -/** - * Allocate a new local TCP port. - * - * @return a new (free) local TCP port number - */ -static u16_t -tcp_new_port(void) -{ - u8_t i; - u16_t n = 0; - struct tcp_pcb *pcb; - -again: - if (tcp_port++ == TCP_LOCAL_PORT_RANGE_END) { - tcp_port = TCP_LOCAL_PORT_RANGE_START; - } - /* Check all PCB lists. */ - for (i = 0; i < NUM_TCP_PCB_LISTS; i++) { - for (pcb = *tcp_pcb_lists[i]; pcb != NULL; pcb = pcb->next) { - if (pcb->local_port == tcp_port) { - if (++n > (TCP_LOCAL_PORT_RANGE_END - TCP_LOCAL_PORT_RANGE_START)) { - return 0; - } - goto again; - } - } - } - return tcp_port; -} - -/** - * @ingroup tcp_raw - * Connects to another host. The function given as the "connected" - * argument will be called when the connection has been established. - * - * @param pcb the tcp_pcb used to establish the connection - * @param ipaddr the remote ip address to connect to - * @param port the remote tcp port to connect to - * @param connected callback function to call when connected (on error, - the err calback will be called) - * @return ERR_VAL if invalid arguments are given - * ERR_OK if connect request has been sent - * other err_t values if connect request couldn't be sent - */ -err_t -tcp_connect(struct tcp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port, - tcp_connected_fn connected) -{ - err_t ret; - u32_t iss; - u16_t old_local_port; - - LWIP_ASSERT_CORE_LOCKED(); - - if ((pcb == NULL) || (ipaddr == NULL)) { - return ERR_VAL; - } - - LWIP_ERROR("tcp_connect: can only connect from state CLOSED", pcb->state == CLOSED, return ERR_ISCONN); - - LWIP_DEBUGF(TCP_DEBUG, ("tcp_connect to port %"U16_F"\n", port)); - ip_addr_set(&pcb->remote_ip, ipaddr); - pcb->remote_port = port; - - /* check if we have a route to the remote host */ - if (ip_addr_isany(&pcb->local_ip)) { - /* no local IP address set, yet. */ - struct netif *netif; - const ip_addr_t *local_ip; - ip_route_get_local_ip(&pcb->local_ip, &pcb->remote_ip, netif, local_ip); - if ((netif == NULL) || (local_ip == NULL)) { - /* Don't even try to send a SYN packet if we have no route - since that will fail. */ - return ERR_RTE; - } - /* Use the address as local address of the pcb. */ - ip_addr_copy(pcb->local_ip, *local_ip); - } - - old_local_port = pcb->local_port; - if (pcb->local_port == 0) { - pcb->local_port = tcp_new_port(); - if (pcb->local_port == 0) { - return ERR_BUF; - } - } else { -#if SO_REUSE - if (ip_get_option(pcb, SOF_REUSEADDR)) { - /* Since SOF_REUSEADDR allows reusing a local address, we have to make sure - now that the 5-tuple is unique. */ - struct tcp_pcb *cpcb; - int i; - /* Don't check listen- and bound-PCBs, check active- and TIME-WAIT PCBs. */ - for (i = 2; i < NUM_TCP_PCB_LISTS; i++) { - for (cpcb = *tcp_pcb_lists[i]; cpcb != NULL; cpcb = cpcb->next) { - if ((cpcb->local_port == pcb->local_port) && - (cpcb->remote_port == port) && - ip_addr_cmp(&cpcb->local_ip, &pcb->local_ip) && - ip_addr_cmp(&cpcb->remote_ip, ipaddr)) { - /* linux returns EISCONN here, but ERR_USE should be OK for us */ - return ERR_USE; - } - } - } - } -#endif /* SO_REUSE */ - } - - iss = tcp_next_iss(pcb); - pcb->rcv_nxt = 0; - pcb->snd_nxt = iss; - pcb->lastack = iss - 1; - pcb->snd_wl2 = iss - 1; - pcb->snd_lbb = iss - 1; - /* Start with a window that does not need scaling. When window scaling is - enabled and used, the window is enlarged when both sides agree on scaling. */ - pcb->rcv_wnd = pcb->rcv_ann_wnd = TCPWND_MIN16(TCP_WND); - pcb->rcv_ann_right_edge = pcb->rcv_nxt; - pcb->snd_wnd = TCP_WND; - /* As initial send MSS, we use TCP_MSS but limit it to 536. - The send MSS is updated when an MSS option is received. */ - pcb->mss = INITIAL_MSS; -#if TCP_CALCULATE_EFF_SEND_MSS - pcb->mss = tcp_eff_send_mss(pcb->mss, &pcb->local_ip, &pcb->remote_ip); -#endif /* TCP_CALCULATE_EFF_SEND_MSS */ - pcb->cwnd = 1; -#if LWIP_CALLBACK_API - pcb->connected = connected; -#else /* LWIP_CALLBACK_API */ - LWIP_UNUSED_ARG(connected); -#endif /* LWIP_CALLBACK_API */ - - /* Send a SYN together with the MSS option. */ - ret = tcp_enqueue_flags(pcb, TCP_SYN); - if (ret == ERR_OK) { - /* SYN segment was enqueued, changed the pcbs state now */ - pcb->state = SYN_SENT; - if (old_local_port != 0) { - TCP_RMV(&tcp_bound_pcbs, pcb); - } - TCP_REG_ACTIVE(pcb); - MIB2_STATS_INC(mib2.tcpactiveopens); - - tcp_output(pcb); - } - return ret; -} - -/** - * Called every 500 ms and implements the retransmission timer and the timer that - * removes PCBs that have been in TIME-WAIT for enough time. It also increments - * various timers such as the inactivity timer in each PCB. - * - * Automatically called from tcp_tmr(). - */ -void -tcp_slowtmr(void) -{ - struct tcp_pcb *pcb, *prev; - tcpwnd_size_t eff_wnd; - u8_t pcb_remove; /* flag if a PCB should be removed */ - u8_t pcb_reset; /* flag if a RST should be sent when removing */ - err_t err; - - err = ERR_OK; - - ++tcp_ticks; - ++tcp_timer_ctr; - -tcp_slowtmr_start: - /* Steps through all of the active PCBs. */ - prev = NULL; - pcb = tcp_active_pcbs; - if (pcb == NULL) { - LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: no active pcbs\n")); - } - while (pcb != NULL) { - LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: processing active pcb\n")); - LWIP_ASSERT("tcp_slowtmr: active pcb->state != CLOSED\n", pcb->state != CLOSED); - LWIP_ASSERT("tcp_slowtmr: active pcb->state != LISTEN\n", pcb->state != LISTEN); - LWIP_ASSERT("tcp_slowtmr: active pcb->state != TIME-WAIT\n", pcb->state != TIME_WAIT); - if (pcb->last_timer == tcp_timer_ctr) { - /* skip this pcb, we have already processed it */ - pcb = pcb->next; - continue; - } - pcb->last_timer = tcp_timer_ctr; - - pcb_remove = 0; - pcb_reset = 0; - - if (pcb->state == SYN_SENT && pcb->nrtx >= TCP_SYNMAXRTX) { - ++pcb_remove; - LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: max SYN retries reached\n")); - } - else if (pcb->nrtx >= TCP_MAXRTX) { - ++pcb_remove; - LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: max DATA retries reached\n")); - } else { - if (pcb->persist_backoff > 0) { - /* If snd_wnd is zero, use persist timer to send 1 byte probes - * instead of using the standard retransmission mechanism. */ - u8_t backoff_cnt = tcp_persist_backoff[pcb->persist_backoff-1]; - if (pcb->persist_cnt < backoff_cnt) { - pcb->persist_cnt++; - } - if (pcb->persist_cnt >= backoff_cnt) { - if (tcp_zero_window_probe(pcb) == ERR_OK) { - pcb->persist_cnt = 0; - if (pcb->persist_backoff < sizeof(tcp_persist_backoff)) { - pcb->persist_backoff++; - } - } - } - } else { - /* Increase the retransmission timer if it is running */ - if (pcb->rtime >= 0) { - ++pcb->rtime; - } - - if (pcb->unacked != NULL && pcb->rtime >= pcb->rto) { - /* Time for a retransmission. */ - LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_slowtmr: rtime %"S16_F - " pcb->rto %"S16_F"\n", - pcb->rtime, pcb->rto)); - - /* Double retransmission time-out unless we are trying to - * connect to somebody (i.e., we are in SYN_SENT). */ - if (pcb->state != SYN_SENT) { - u8_t backoff_idx = LWIP_MIN(pcb->nrtx, sizeof(tcp_backoff)-1); - int calc_rto = ((pcb->sa >> 3) + pcb->sv) << tcp_backoff[backoff_idx]; - pcb->rto = (s16_t)LWIP_MIN(calc_rto, 0x7FFF); - } - - /* Reset the retransmission timer. */ - pcb->rtime = 0; - - /* Reduce congestion window and ssthresh. */ - eff_wnd = LWIP_MIN(pcb->cwnd, pcb->snd_wnd); - pcb->ssthresh = eff_wnd >> 1; - if (pcb->ssthresh < (tcpwnd_size_t)(pcb->mss << 1)) { - pcb->ssthresh = (tcpwnd_size_t)(pcb->mss << 1); - } - pcb->cwnd = pcb->mss; - LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_slowtmr: cwnd %"TCPWNDSIZE_F - " ssthresh %"TCPWNDSIZE_F"\n", - pcb->cwnd, pcb->ssthresh)); - - /* The following needs to be called AFTER cwnd is set to one - mss - STJ */ - tcp_rexmit_rto(pcb); - } - } - } - /* Check if this PCB has stayed too long in FIN-WAIT-2 */ - if (pcb->state == FIN_WAIT_2) { - /* If this PCB is in FIN_WAIT_2 because of SHUT_WR don't let it time out. */ - if (pcb->flags & TF_RXCLOSED) { - /* PCB was fully closed (either through close() or SHUT_RDWR): - normal FIN-WAIT timeout handling. */ - if ((u32_t)(tcp_ticks - pcb->tmr) > - TCP_FIN_WAIT_TIMEOUT / TCP_SLOW_INTERVAL) { - ++pcb_remove; - LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in FIN-WAIT-2\n")); - } - } - } - - /* Check if KEEPALIVE should be sent */ - if (ip_get_option(pcb, SOF_KEEPALIVE) && - ((pcb->state == ESTABLISHED) || - (pcb->state == CLOSE_WAIT))) { - if ((u32_t)(tcp_ticks - pcb->tmr) > - (pcb->keep_idle + TCP_KEEP_DUR(pcb)) / TCP_SLOW_INTERVAL) - { - LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: KEEPALIVE timeout. Aborting connection to ")); - ip_addr_debug_print(TCP_DEBUG, &pcb->remote_ip); - LWIP_DEBUGF(TCP_DEBUG, ("\n")); - - ++pcb_remove; - ++pcb_reset; - } else if ((u32_t)(tcp_ticks - pcb->tmr) > - (pcb->keep_idle + pcb->keep_cnt_sent * TCP_KEEP_INTVL(pcb)) - / TCP_SLOW_INTERVAL) - { - err = tcp_keepalive(pcb); - if (err == ERR_OK) { - pcb->keep_cnt_sent++; - } - } - } - - /* If this PCB has queued out of sequence data, but has been - inactive for too long, will drop the data (it will eventually - be retransmitted). */ -#if TCP_QUEUE_OOSEQ - if (pcb->ooseq != NULL && - (tcp_ticks - pcb->tmr >= (u32_t)pcb->rto * TCP_OOSEQ_TIMEOUT)) { - tcp_segs_free(pcb->ooseq); - pcb->ooseq = NULL; - LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_slowtmr: dropping OOSEQ queued data\n")); - } -#endif /* TCP_QUEUE_OOSEQ */ - - /* Check if this PCB has stayed too long in SYN-RCVD */ - if (pcb->state == SYN_RCVD) { - if ((u32_t)(tcp_ticks - pcb->tmr) > - TCP_SYN_RCVD_TIMEOUT / TCP_SLOW_INTERVAL) { - ++pcb_remove; - LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in SYN-RCVD\n")); - } - } - - /* Check if this PCB has stayed too long in LAST-ACK */ - if (pcb->state == LAST_ACK) { - if ((u32_t)(tcp_ticks - pcb->tmr) > 2 * TCP_MSL / TCP_SLOW_INTERVAL) { - ++pcb_remove; - LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: removing pcb stuck in LAST-ACK\n")); - } - } - - /* If the PCB should be removed, do it. */ - if (pcb_remove) { - struct tcp_pcb *pcb2; -#if LWIP_CALLBACK_API - tcp_err_fn err_fn = pcb->errf; -#endif /* LWIP_CALLBACK_API */ - void *err_arg; - enum tcp_state last_state; - tcp_pcb_purge(pcb); - /* Remove PCB from tcp_active_pcbs list. */ - if (prev != NULL) { - LWIP_ASSERT("tcp_slowtmr: middle tcp != tcp_active_pcbs", pcb != tcp_active_pcbs); - prev->next = pcb->next; - } else { - /* This PCB was the first. */ - LWIP_ASSERT("tcp_slowtmr: first pcb == tcp_active_pcbs", tcp_active_pcbs == pcb); - tcp_active_pcbs = pcb->next; - } - - if (pcb_reset) { - tcp_rst(pcb->snd_nxt, pcb->rcv_nxt, &pcb->local_ip, &pcb->remote_ip, - pcb->local_port, pcb->remote_port); - } - - err_arg = pcb->callback_arg; - last_state = pcb->state; - pcb2 = pcb; - pcb = pcb->next; - memp_free(MEMP_TCP_PCB, pcb2); - - tcp_active_pcbs_changed = 0; - TCP_EVENT_ERR(last_state, err_fn, err_arg, ERR_ABRT); - if (tcp_active_pcbs_changed) { - goto tcp_slowtmr_start; - } - } else { - /* get the 'next' element now and work with 'prev' below (in case of abort) */ - prev = pcb; - pcb = pcb->next; - - /* We check if we should poll the connection. */ - ++prev->polltmr; - if (prev->polltmr >= prev->pollinterval) { - prev->polltmr = 0; - LWIP_DEBUGF(TCP_DEBUG, ("tcp_slowtmr: polling application\n")); - tcp_active_pcbs_changed = 0; - TCP_EVENT_POLL(prev, err); - if (tcp_active_pcbs_changed) { - goto tcp_slowtmr_start; - } - /* if err == ERR_ABRT, 'prev' is already deallocated */ - if (err == ERR_OK) { - tcp_output(prev); - } - } - } - } - - - /* Steps through all of the TIME-WAIT PCBs. */ - prev = NULL; - pcb = tcp_tw_pcbs; - while (pcb != NULL) { - LWIP_ASSERT("tcp_slowtmr: TIME-WAIT pcb->state == TIME-WAIT", pcb->state == TIME_WAIT); - pcb_remove = 0; - - /* Check if this PCB has stayed long enough in TIME-WAIT */ - if ((u32_t)(tcp_ticks - pcb->tmr) > 2 * TCP_MSL / TCP_SLOW_INTERVAL) { - ++pcb_remove; - } - - /* If the PCB should be removed, do it. */ - if (pcb_remove) { - struct tcp_pcb *pcb2; - tcp_pcb_purge(pcb); - /* Remove PCB from tcp_tw_pcbs list. */ - if (prev != NULL) { - LWIP_ASSERT("tcp_slowtmr: middle tcp != tcp_tw_pcbs", pcb != tcp_tw_pcbs); - prev->next = pcb->next; - } else { - /* This PCB was the first. */ - LWIP_ASSERT("tcp_slowtmr: first pcb == tcp_tw_pcbs", tcp_tw_pcbs == pcb); - tcp_tw_pcbs = pcb->next; - } - pcb2 = pcb; - pcb = pcb->next; - memp_free(MEMP_TCP_PCB, pcb2); - } else { - prev = pcb; - pcb = pcb->next; - } - } -} - -/** - * Is called every TCP_FAST_INTERVAL (250 ms) and process data previously - * "refused" by upper layer (application) and sends delayed ACKs. - * - * Automatically called from tcp_tmr(). - */ -void -tcp_fasttmr(void) -{ - struct tcp_pcb *pcb; - - ++tcp_timer_ctr; - -tcp_fasttmr_start: - pcb = tcp_active_pcbs; - - while (pcb != NULL) { - if (pcb->last_timer != tcp_timer_ctr) { - struct tcp_pcb *next; - pcb->last_timer = tcp_timer_ctr; - /* send delayed ACKs */ - if (pcb->flags & TF_ACK_DELAY) { - LWIP_DEBUGF(TCP_DEBUG, ("tcp_fasttmr: delayed ACK\n")); - tcp_ack_now(pcb); - tcp_output(pcb); - tcp_clear_flags(pcb, TF_ACK_DELAY | TF_ACK_NOW); - } - /* send pending FIN */ - if (pcb->flags & TF_CLOSEPEND) { - LWIP_DEBUGF(TCP_DEBUG, ("tcp_fasttmr: pending FIN\n")); - tcp_clear_flags(pcb, TF_CLOSEPEND); - tcp_close_shutdown_fin(pcb); - } - - next = pcb->next; - - /* If there is data which was previously "refused" by upper layer */ - if (pcb->refused_data != NULL) { - tcp_active_pcbs_changed = 0; - tcp_process_refused_data(pcb); - if (tcp_active_pcbs_changed) { - /* application callback has changed the pcb list: restart the loop */ - goto tcp_fasttmr_start; - } - } - pcb = next; - } else { - pcb = pcb->next; - } - } -} - -/** Call tcp_output for all active pcbs that have TF_NAGLEMEMERR set */ -void -tcp_txnow(void) -{ - struct tcp_pcb *pcb; - - for (pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { - if (pcb->flags & TF_NAGLEMEMERR) { - tcp_output(pcb); - } - } -} - -/** Pass pcb->refused_data to the recv callback */ -err_t -tcp_process_refused_data(struct tcp_pcb *pcb) -{ -#if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE - struct pbuf *rest; - while (pcb->refused_data != NULL) -#endif /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */ - { - err_t err; - u8_t refused_flags = pcb->refused_data->flags; - /* set pcb->refused_data to NULL in case the callback frees it and then - closes the pcb */ - struct pbuf *refused_data = pcb->refused_data; -#if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE - pbuf_split_64k(refused_data, &rest); - pcb->refused_data = rest; -#else /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */ - pcb->refused_data = NULL; -#endif /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */ - /* Notify again application with data previously received. */ - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: notify kept packet\n")); - TCP_EVENT_RECV(pcb, refused_data, ERR_OK, err); - if (err == ERR_OK) { - /* did refused_data include a FIN? */ - if (refused_flags & PBUF_FLAG_TCP_FIN -#if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE - && (rest == NULL) -#endif /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */ - ) { - /* correct rcv_wnd as the application won't call tcp_recved() - for the FIN's seqno */ - if (pcb->rcv_wnd != TCP_WND_MAX(pcb)) { - pcb->rcv_wnd++; - } - TCP_EVENT_CLOSED(pcb, err); - if (err == ERR_ABRT) { - return ERR_ABRT; - } - } - } else if (err == ERR_ABRT) { - /* if err == ERR_ABRT, 'pcb' is already deallocated */ - /* Drop incoming packets because pcb is "full" (only if the incoming - segment contains data). */ - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: drop incoming packets, because pcb is \"full\"\n")); - return ERR_ABRT; - } else { - /* data is still refused, pbuf is still valid (go on for ACK-only packets) */ -#if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE - if (rest != NULL) { - pbuf_cat(refused_data, rest); - } -#endif /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */ - pcb->refused_data = refused_data; - return ERR_INPROGRESS; - } - } - return ERR_OK; -} - -/** - * Deallocates a list of TCP segments (tcp_seg structures). - * - * @param seg tcp_seg list of TCP segments to free - */ -void -tcp_segs_free(struct tcp_seg *seg) -{ - while (seg != NULL) { - struct tcp_seg *next = seg->next; - tcp_seg_free(seg); - seg = next; - } -} - -/** - * Frees a TCP segment (tcp_seg structure). - * - * @param seg single tcp_seg to free - */ -void -tcp_seg_free(struct tcp_seg *seg) -{ - if (seg != NULL) { - if (seg->p != NULL) { - pbuf_free(seg->p); -#if TCP_DEBUG - seg->p = NULL; -#endif /* TCP_DEBUG */ - } - memp_free(MEMP_TCP_SEG, seg); - } -} - -/** - * Sets the priority of a connection. - * - * @param pcb the tcp_pcb to manipulate - * @param prio new priority - */ -void -tcp_setprio(struct tcp_pcb *pcb, u8_t prio) -{ - LWIP_ASSERT_CORE_LOCKED(); - pcb->prio = prio; -} - -#if TCP_QUEUE_OOSEQ -/** - * Returns a copy of the given TCP segment. - * The pbuf and data are not copied, only the pointers - * - * @param seg the old tcp_seg - * @return a copy of seg - */ -struct tcp_seg * -tcp_seg_copy(struct tcp_seg *seg) -{ - struct tcp_seg *cseg; - - cseg = (struct tcp_seg *)memp_malloc(MEMP_TCP_SEG); - if (cseg == NULL) { - return NULL; - } - SMEMCPY((u8_t *)cseg, (const u8_t *)seg, sizeof(struct tcp_seg)); - pbuf_ref(cseg->p); - return cseg; -} -#endif /* TCP_QUEUE_OOSEQ */ - -#if LWIP_CALLBACK_API -/** - * Default receive callback that is called if the user didn't register - * a recv callback for the pcb. - */ -err_t -tcp_recv_null(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err) -{ - LWIP_UNUSED_ARG(arg); - if (p != NULL) { - tcp_recved(pcb, p->tot_len); - pbuf_free(p); - } else if (err == ERR_OK) { - return tcp_close(pcb); - } - return ERR_OK; -} -#endif /* LWIP_CALLBACK_API */ - -/** - * Kills the oldest active connection that has the same or lower priority than - * 'prio'. - * - * @param prio minimum priority - */ -static void -tcp_kill_prio(u8_t prio) -{ - struct tcp_pcb *pcb, *inactive; - u32_t inactivity; - u8_t mprio; - - mprio = LWIP_MIN(TCP_PRIO_MAX, prio); - - /* We kill the oldest active connection that has lower priority than prio. */ - inactivity = 0; - inactive = NULL; - for (pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { - if (pcb->prio <= mprio && - (u32_t)(tcp_ticks - pcb->tmr) >= inactivity) { - inactivity = tcp_ticks - pcb->tmr; - inactive = pcb; - mprio = pcb->prio; - } - } - if (inactive != NULL) { - LWIP_DEBUGF(TCP_DEBUG, ("tcp_kill_prio: killing oldest PCB %p (%"S32_F")\n", - (void *)inactive, inactivity)); - tcp_abort(inactive); - } -} - -/** - * Kills the oldest connection that is in specific state. - * Called from tcp_alloc() for LAST_ACK and CLOSING if no more connections are available. - */ -static void -tcp_kill_state(enum tcp_state state) -{ - struct tcp_pcb *pcb, *inactive; - u32_t inactivity; - - LWIP_ASSERT("invalid state", (state == CLOSING) || (state == LAST_ACK)); - - inactivity = 0; - inactive = NULL; - /* Go through the list of active pcbs and get the oldest pcb that is in state - CLOSING/LAST_ACK. */ - for (pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { - if (pcb->state == state) { - if ((u32_t)(tcp_ticks - pcb->tmr) >= inactivity) { - inactivity = tcp_ticks - pcb->tmr; - inactive = pcb; - } - } - } - if (inactive != NULL) { - LWIP_DEBUGF(TCP_DEBUG, ("tcp_kill_closing: killing oldest %s PCB %p (%"S32_F")\n", - tcp_state_str[state], (void *)inactive, inactivity)); - /* Don't send a RST, since no data is lost. */ - tcp_abandon(inactive, 0); - } -} - -/** - * Kills the oldest connection that is in TIME_WAIT state. - * Called from tcp_alloc() if no more connections are available. - */ -static void -tcp_kill_timewait(void) -{ - struct tcp_pcb *pcb, *inactive; - u32_t inactivity; - - inactivity = 0; - inactive = NULL; - /* Go through the list of TIME_WAIT pcbs and get the oldest pcb. */ - for (pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) { - if ((u32_t)(tcp_ticks - pcb->tmr) >= inactivity) { - inactivity = tcp_ticks - pcb->tmr; - inactive = pcb; - } - } - if (inactive != NULL) { - LWIP_DEBUGF(TCP_DEBUG, ("tcp_kill_timewait: killing oldest TIME-WAIT PCB %p (%"S32_F")\n", - (void *)inactive, inactivity)); - tcp_abort(inactive); - } -} - -/** - * Allocate a new tcp_pcb structure. - * - * @param prio priority for the new pcb - * @return a new tcp_pcb that initially is in state CLOSED - */ -struct tcp_pcb * -tcp_alloc(u8_t prio) -{ - struct tcp_pcb *pcb; - - LWIP_ASSERT_CORE_LOCKED(); - - pcb = (struct tcp_pcb *)memp_malloc(MEMP_TCP_PCB); - if (pcb == NULL) { - /* Try killing oldest connection in TIME-WAIT. */ - LWIP_DEBUGF(TCP_DEBUG, ("tcp_alloc: killing off oldest TIME-WAIT connection\n")); - tcp_kill_timewait(); - /* Try to allocate a tcp_pcb again. */ - pcb = (struct tcp_pcb *)memp_malloc(MEMP_TCP_PCB); - if (pcb == NULL) { - /* Try killing oldest connection in LAST-ACK (these wouldn't go to TIME-WAIT). */ - LWIP_DEBUGF(TCP_DEBUG, ("tcp_alloc: killing off oldest LAST-ACK connection\n")); - tcp_kill_state(LAST_ACK); - /* Try to allocate a tcp_pcb again. */ - pcb = (struct tcp_pcb *)memp_malloc(MEMP_TCP_PCB); - if (pcb == NULL) { - /* Try killing oldest connection in CLOSING. */ - LWIP_DEBUGF(TCP_DEBUG, ("tcp_alloc: killing off oldest CLOSING connection\n")); - tcp_kill_state(CLOSING); - /* Try to allocate a tcp_pcb again. */ - pcb = (struct tcp_pcb *)memp_malloc(MEMP_TCP_PCB); - if (pcb == NULL) { - /* Try killing active connections with lower priority than the new one. */ - LWIP_DEBUGF(TCP_DEBUG, ("tcp_alloc: killing connection with prio lower than %d\n", prio)); - tcp_kill_prio(prio); - /* Try to allocate a tcp_pcb again. */ - pcb = (struct tcp_pcb *)memp_malloc(MEMP_TCP_PCB); - if (pcb != NULL) { - /* adjust err stats: memp_malloc failed multiple times before */ - MEMP_STATS_DEC(err, MEMP_TCP_PCB); - } - } - if (pcb != NULL) { - /* adjust err stats: memp_malloc failed multiple times before */ - MEMP_STATS_DEC(err, MEMP_TCP_PCB); - } - } - if (pcb != NULL) { - /* adjust err stats: memp_malloc failed multiple times before */ - MEMP_STATS_DEC(err, MEMP_TCP_PCB); - } - } - if (pcb != NULL) { - /* adjust err stats: memp_malloc failed above */ - MEMP_STATS_DEC(err, MEMP_TCP_PCB); - } - } - if (pcb != NULL) { - /* zero out the whole pcb, so there is no need to initialize members to zero */ - memset(pcb, 0, sizeof(struct tcp_pcb)); - pcb->prio = prio; - pcb->snd_buf = TCP_SND_BUF; - /* Start with a window that does not need scaling. When window scaling is - enabled and used, the window is enlarged when both sides agree on scaling. */ - pcb->rcv_wnd = pcb->rcv_ann_wnd = TCPWND_MIN16(TCP_WND); - pcb->ttl = TCP_TTL; - /* As initial send MSS, we use TCP_MSS but limit it to 536. - The send MSS is updated when an MSS option is received. */ - pcb->mss = INITIAL_MSS; - pcb->rto = 3000 / TCP_SLOW_INTERVAL; - pcb->sv = 3000 / TCP_SLOW_INTERVAL; - pcb->rtime = -1; - pcb->cwnd = 1; - pcb->tmr = tcp_ticks; - pcb->last_timer = tcp_timer_ctr; - - /* RFC 5681 recommends setting ssthresh abritrarily high and gives an example - of using the largest advertised receive window. We've seen complications with - receiving TCPs that use window scaling and/or window auto-tuning where the - initial advertised window is very small and then grows rapidly once the - connection is established. To avoid these complications, we set ssthresh to the - largest effective cwnd (amount of in-flight data) that the sender can have. */ - pcb->ssthresh = TCP_SND_BUF; - -#if LWIP_CALLBACK_API - pcb->recv = tcp_recv_null; -#endif /* LWIP_CALLBACK_API */ - - /* Init KEEPALIVE timer */ - pcb->keep_idle = TCP_KEEPIDLE_DEFAULT; - -#if LWIP_TCP_KEEPALIVE - pcb->keep_intvl = TCP_KEEPINTVL_DEFAULT; - pcb->keep_cnt = TCP_KEEPCNT_DEFAULT; -#endif /* LWIP_TCP_KEEPALIVE */ - } - return pcb; -} - -/** - * @ingroup tcp_raw - * Creates a new TCP protocol control block but doesn't place it on - * any of the TCP PCB lists. - * The pcb is not put on any list until binding using tcp_bind(). - * - * @internal: Maybe there should be a idle TCP PCB list where these - * PCBs are put on. Port reservation using tcp_bind() is implemented but - * allocated pcbs that are not bound can't be killed automatically if wanting - * to allocate a pcb with higher prio (@see tcp_kill_prio()) - * - * @return a new tcp_pcb that initially is in state CLOSED - */ -struct tcp_pcb * -tcp_new(void) -{ - return tcp_alloc(TCP_PRIO_NORMAL); -} - -/** - * @ingroup tcp_raw - * Creates a new TCP protocol control block but doesn't - * place it on any of the TCP PCB lists. - * The pcb is not put on any list until binding using tcp_bind(). - * - * @param type IP address type, see @ref lwip_ip_addr_type definitions. - * If you want to listen to IPv4 and IPv6 (dual-stack) connections, - * supply @ref IPADDR_TYPE_ANY as argument and bind to @ref IP_ANY_TYPE. - * @return a new tcp_pcb that initially is in state CLOSED - */ -struct tcp_pcb * -tcp_new_ip_type(u8_t type) -{ - struct tcp_pcb * pcb; - pcb = tcp_alloc(TCP_PRIO_NORMAL); -#if LWIP_IPV4 && LWIP_IPV6 - if (pcb != NULL) { - IP_SET_TYPE_VAL(pcb->local_ip, type); - IP_SET_TYPE_VAL(pcb->remote_ip, type); - } -#else - LWIP_UNUSED_ARG(type); -#endif /* LWIP_IPV4 && LWIP_IPV6 */ - return pcb; -} - -/** - * @ingroup tcp_raw - * Used to specify the argument that should be passed callback - * functions. - * - * @param pcb tcp_pcb to set the callback argument - * @param arg void pointer argument to pass to callback functions - */ -void -tcp_arg(struct tcp_pcb *pcb, void *arg) -{ - LWIP_ASSERT_CORE_LOCKED(); - /* This function is allowed to be called for both listen pcbs and - connection pcbs. */ - if (pcb != NULL) { - pcb->callback_arg = arg; - } -} -#if LWIP_CALLBACK_API - -/** - * @ingroup tcp_raw - * Used to specify the function that should be called when a TCP - * connection receives data. - * - * @param pcb tcp_pcb to set the recv callback - * @param recv callback function to call for this pcb when data is received - */ -void -tcp_recv(struct tcp_pcb *pcb, tcp_recv_fn recv) -{ - LWIP_ASSERT_CORE_LOCKED(); - if (pcb != NULL) { - LWIP_ASSERT("invalid socket state for recv callback", pcb->state != LISTEN); - pcb->recv = recv; - } -} - -/** - * @ingroup tcp_raw - * Used to specify the function that should be called when TCP data - * has been successfully delivered to the remote host. - * - * @param pcb tcp_pcb to set the sent callback - * @param sent callback function to call for this pcb when data is successfully sent - */ -void -tcp_sent(struct tcp_pcb *pcb, tcp_sent_fn sent) -{ - LWIP_ASSERT_CORE_LOCKED(); - if (pcb != NULL) { - LWIP_ASSERT("invalid socket state for sent callback", pcb->state != LISTEN); - pcb->sent = sent; - } -} - -/** - * @ingroup tcp_raw - * Used to specify the function that should be called when a fatal error - * has occurred on the connection. - * - * @note The corresponding pcb is already freed when this callback is called! - * - * @param pcb tcp_pcb to set the err callback - * @param err callback function to call for this pcb when a fatal error - * has occurred on the connection - */ -void -tcp_err(struct tcp_pcb *pcb, tcp_err_fn err) -{ - LWIP_ASSERT_CORE_LOCKED(); - if (pcb != NULL) { - LWIP_ASSERT("invalid socket state for err callback", pcb->state != LISTEN); - pcb->errf = err; - } -} - -/** - * @ingroup tcp_raw - * Used for specifying the function that should be called when a - * LISTENing connection has been connected to another host. - * - * @param pcb tcp_pcb to set the accept callback - * @param accept callback function to call for this pcb when LISTENing - * connection has been connected to another host - */ -void -tcp_accept(struct tcp_pcb *pcb, tcp_accept_fn accept) -{ - LWIP_ASSERT_CORE_LOCKED(); - if ((pcb != NULL) && (pcb->state == LISTEN)) { - struct tcp_pcb_listen *lpcb = (struct tcp_pcb_listen*)pcb; - lpcb->accept = accept; - } -} -#endif /* LWIP_CALLBACK_API */ - - -/** - * @ingroup tcp_raw - * Used to specify the function that should be called periodically - * from TCP. The interval is specified in terms of the TCP coarse - * timer interval, which is called twice a second. - * - */ -void -tcp_poll(struct tcp_pcb *pcb, tcp_poll_fn poll, u8_t interval) -{ - LWIP_ASSERT_CORE_LOCKED(); - LWIP_ASSERT("invalid socket state for poll", pcb->state != LISTEN); -#if LWIP_CALLBACK_API - pcb->poll = poll; -#else /* LWIP_CALLBACK_API */ - LWIP_UNUSED_ARG(poll); -#endif /* LWIP_CALLBACK_API */ - pcb->pollinterval = interval; -} - -/** - * Purges a TCP PCB. Removes any buffered data and frees the buffer memory - * (pcb->ooseq, pcb->unsent and pcb->unacked are freed). - * - * @param pcb tcp_pcb to purge. The pcb itself is not deallocated! - */ -void -tcp_pcb_purge(struct tcp_pcb *pcb) -{ - if (pcb->state != CLOSED && - pcb->state != TIME_WAIT && - pcb->state != LISTEN) { - - LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge\n")); - - tcp_backlog_accepted(pcb); - - if (pcb->refused_data != NULL) { - LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->refused_data\n")); - pbuf_free(pcb->refused_data); - pcb->refused_data = NULL; - } - if (pcb->unsent != NULL) { - LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: not all data sent\n")); - } - if (pcb->unacked != NULL) { - LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->unacked\n")); - } -#if TCP_QUEUE_OOSEQ - if (pcb->ooseq != NULL) { - LWIP_DEBUGF(TCP_DEBUG, ("tcp_pcb_purge: data left on ->ooseq\n")); - } - tcp_segs_free(pcb->ooseq); - pcb->ooseq = NULL; -#endif /* TCP_QUEUE_OOSEQ */ - - /* Stop the retransmission timer as it will expect data on unacked - queue if it fires */ - pcb->rtime = -1; - - tcp_segs_free(pcb->unsent); - tcp_segs_free(pcb->unacked); - pcb->unacked = pcb->unsent = NULL; -#if TCP_OVERSIZE - pcb->unsent_oversize = 0; -#endif /* TCP_OVERSIZE */ - } -} - -/** - * Purges the PCB and removes it from a PCB list. Any delayed ACKs are sent first. - * - * @param pcblist PCB list to purge. - * @param pcb tcp_pcb to purge. The pcb itself is NOT deallocated! - */ -void -tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb) -{ - TCP_RMV(pcblist, pcb); - - tcp_pcb_purge(pcb); - - /* if there is an outstanding delayed ACKs, send it */ - if (pcb->state != TIME_WAIT && - pcb->state != LISTEN && - pcb->flags & TF_ACK_DELAY) { - pcb->flags |= TF_ACK_NOW; - tcp_output(pcb); - } - - if (pcb->state != LISTEN) { - LWIP_ASSERT("unsent segments leaking", pcb->unsent == NULL); - LWIP_ASSERT("unacked segments leaking", pcb->unacked == NULL); -#if TCP_QUEUE_OOSEQ - LWIP_ASSERT("ooseq segments leaking", pcb->ooseq == NULL); -#endif /* TCP_QUEUE_OOSEQ */ - } - - pcb->state = CLOSED; - /* reset the local port to prevent the pcb from being 'bound' */ - pcb->local_port = 0; - - LWIP_ASSERT("tcp_pcb_remove: tcp_pcbs_sane()", tcp_pcbs_sane()); -} - -/** - * Calculates a new initial sequence number for new connections. - * - * @return u32_t pseudo random sequence number - */ -u32_t -tcp_next_iss(struct tcp_pcb *pcb) -{ -#ifdef LWIP_HOOK_TCP_ISN - return LWIP_HOOK_TCP_ISN(&pcb->local_ip, pcb->local_port, &pcb->remote_ip, pcb->remote_port); -#else /* LWIP_HOOK_TCP_ISN */ - static u32_t iss = 6510; - - LWIP_UNUSED_ARG(pcb); - - iss += tcp_ticks; /* XXX */ - return iss; -#endif /* LWIP_HOOK_TCP_ISN */ -} - -#if TCP_CALCULATE_EFF_SEND_MSS -/** - * Calculates the effective send mss that can be used for a specific IP address - * by using ip_route to determine the netif used to send to the address and - * calculating the minimum of TCP_MSS and that netif's mtu (if set). - */ -u16_t -tcp_eff_send_mss_impl(u16_t sendmss, const ip_addr_t *dest -#if LWIP_IPV6 || LWIP_IPV4_SRC_ROUTING - , const ip_addr_t *src -#endif /* LWIP_IPV6 || LWIP_IPV4_SRC_ROUTING */ - ) -{ - u16_t mss_s; - struct netif *outif; - u16_t mtu; - - outif = ip_route(src, dest); -#if LWIP_IPV6 -#if LWIP_IPV4 - if (IP_IS_V6(dest)) -#endif /* LWIP_IPV4 */ - { -#if LWIP_IPV6_ND - /* First look in destination cache, to see if there is a Path MTU. */ - mtu = nd6_get_destination_mtu(ip_2_ip6(dest), outif); -#else - mtu = (outif != NULL) ? outif->mtu : IP6_MIN_MTU; -#endif - } -#if LWIP_IPV4 - else -#endif /* LWIP_IPV4 */ -#endif /* LWIP_IPV6 */ -#if LWIP_IPV4 - { - if (outif == NULL) { - return sendmss; - } - mtu = outif->mtu; - } -#endif /* LWIP_IPV4 */ - - if (mtu != 0) { - u16_t offset; -#if LWIP_IPV6 -#if LWIP_IPV4 - if (IP_IS_V6(dest)) -#endif /* LWIP_IPV4 */ - { - offset = IP6_HLEN + TCP_HLEN; - } -#if LWIP_IPV4 - else -#endif /* LWIP_IPV4 */ -#endif /* LWIP_IPV6 */ -#if LWIP_IPV4 - { - offset = IP_HLEN + TCP_HLEN; - } -#endif /* LWIP_IPV4 */ - mss_s = (mtu > offset) ? (u16_t)(mtu - offset) : 0; - /* RFC 1122, chap 4.2.2.6: - * Eff.snd.MSS = min(SendMSS+20, MMS_S) - TCPhdrsize - IPoptionsize - * We correct for TCP options in tcp_write(), and don't support IP options. - */ - sendmss = LWIP_MIN(sendmss, mss_s); - } - return sendmss; -} -#endif /* TCP_CALCULATE_EFF_SEND_MSS */ - -/** Helper function for tcp_netif_ip_addr_changed() that iterates a pcb list */ -static void -tcp_netif_ip_addr_changed_pcblist(const ip_addr_t* old_addr, struct tcp_pcb* pcb_list) -{ - struct tcp_pcb *pcb; - pcb = pcb_list; - while (pcb != NULL) { - /* PCB bound to current local interface address? */ - if (ip_addr_cmp(&pcb->local_ip, old_addr) -#if LWIP_AUTOIP - /* connections to link-local addresses must persist (RFC3927 ch. 1.9) */ - && (!IP_IS_V4_VAL(pcb->local_ip) || !ip4_addr_islinklocal(ip_2_ip4(&pcb->local_ip))) -#endif /* LWIP_AUTOIP */ - ) { - /* this connection must be aborted */ - struct tcp_pcb *next = pcb->next; - LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_STATE, ("netif_set_ipaddr: aborting TCP pcb %p\n", (void *)pcb)); - tcp_abort(pcb); - pcb = next; - } else { - pcb = pcb->next; - } - } -} - -/** This function is called from netif.c when address is changed or netif is removed - * - * @param old_addr IP address of the netif before change - * @param new_addr IP address of the netif after change or NULL if netif has been removed - */ -void -tcp_netif_ip_addr_changed(const ip_addr_t* old_addr, const ip_addr_t* new_addr) -{ - struct tcp_pcb_listen *lpcb, *next; - - if (!ip_addr_isany(old_addr)) { - tcp_netif_ip_addr_changed_pcblist(old_addr, tcp_active_pcbs); - tcp_netif_ip_addr_changed_pcblist(old_addr, tcp_bound_pcbs); - - if (!ip_addr_isany(new_addr)) { - /* PCB bound to current local interface address? */ - for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = next) { - next = lpcb->next; - /* PCB bound to current local interface address? */ - if (ip_addr_cmp(&lpcb->local_ip, old_addr)) { - /* The PCB is listening to the old ipaddr and - * is set to listen to the new one instead */ - ip_addr_copy(lpcb->local_ip, *new_addr); - } - } - } - } -} - -const char* -tcp_debug_state_str(enum tcp_state s) -{ - return tcp_state_str[s]; -} - -#if TCP_DEBUG || TCP_INPUT_DEBUG || TCP_OUTPUT_DEBUG -/** - * Print a tcp header for debugging purposes. - * - * @param tcphdr pointer to a struct tcp_hdr - */ -void -tcp_debug_print(struct tcp_hdr *tcphdr) -{ - LWIP_DEBUGF(TCP_DEBUG, ("TCP header:\n")); - LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n")); - LWIP_DEBUGF(TCP_DEBUG, ("| %5"U16_F" | %5"U16_F" | (src port, dest port)\n", - lwip_ntohs(tcphdr->src), lwip_ntohs(tcphdr->dest))); - LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n")); - LWIP_DEBUGF(TCP_DEBUG, ("| %010"U32_F" | (seq no)\n", - lwip_ntohl(tcphdr->seqno))); - LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n")); - LWIP_DEBUGF(TCP_DEBUG, ("| %010"U32_F" | (ack no)\n", - lwip_ntohl(tcphdr->ackno))); - LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n")); - LWIP_DEBUGF(TCP_DEBUG, ("| %2"U16_F" | |%"U16_F"%"U16_F"%"U16_F"%"U16_F"%"U16_F"%"U16_F"| %5"U16_F" | (hdrlen, flags (", - TCPH_HDRLEN(tcphdr), - (u16_t)(TCPH_FLAGS(tcphdr) >> 5 & 1), - (u16_t)(TCPH_FLAGS(tcphdr) >> 4 & 1), - (u16_t)(TCPH_FLAGS(tcphdr) >> 3 & 1), - (u16_t)(TCPH_FLAGS(tcphdr) >> 2 & 1), - (u16_t)(TCPH_FLAGS(tcphdr) >> 1 & 1), - (u16_t)(TCPH_FLAGS(tcphdr) & 1), - lwip_ntohs(tcphdr->wnd))); - tcp_debug_print_flags(TCPH_FLAGS(tcphdr)); - LWIP_DEBUGF(TCP_DEBUG, ("), win)\n")); - LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n")); - LWIP_DEBUGF(TCP_DEBUG, ("| 0x%04"X16_F" | %5"U16_F" | (chksum, urgp)\n", - lwip_ntohs(tcphdr->chksum), lwip_ntohs(tcphdr->urgp))); - LWIP_DEBUGF(TCP_DEBUG, ("+-------------------------------+\n")); -} - -/** - * Print a tcp state for debugging purposes. - * - * @param s enum tcp_state to print - */ -void -tcp_debug_print_state(enum tcp_state s) -{ - LWIP_DEBUGF(TCP_DEBUG, ("TCP State: %s\n", tcp_state_str[s])); -} - -/** - * Print tcp flags for debugging purposes. - * - * @param flags tcp flags, all active flags are printed - */ -void -tcp_debug_print_flags(u8_t flags) -{ - if (flags & TCP_FIN) { - LWIP_DEBUGF(TCP_DEBUG, ("FIN ")); - } - if (flags & TCP_SYN) { - LWIP_DEBUGF(TCP_DEBUG, ("SYN ")); - } - if (flags & TCP_RST) { - LWIP_DEBUGF(TCP_DEBUG, ("RST ")); - } - if (flags & TCP_PSH) { - LWIP_DEBUGF(TCP_DEBUG, ("PSH ")); - } - if (flags & TCP_ACK) { - LWIP_DEBUGF(TCP_DEBUG, ("ACK ")); - } - if (flags & TCP_URG) { - LWIP_DEBUGF(TCP_DEBUG, ("URG ")); - } - if (flags & TCP_ECE) { - LWIP_DEBUGF(TCP_DEBUG, ("ECE ")); - } - if (flags & TCP_CWR) { - LWIP_DEBUGF(TCP_DEBUG, ("CWR ")); - } -} - -/** - * Print all tcp_pcbs in every list for debugging purposes. - */ -void -tcp_debug_print_pcbs(void) -{ - struct tcp_pcb *pcb; - struct tcp_pcb_listen *pcbl; - - LWIP_DEBUGF(TCP_DEBUG, ("Active PCB states:\n")); - for (pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { - LWIP_DEBUGF(TCP_DEBUG, ("Local port %"U16_F", foreign port %"U16_F" snd_nxt %"U32_F" rcv_nxt %"U32_F" ", - pcb->local_port, pcb->remote_port, - pcb->snd_nxt, pcb->rcv_nxt)); - tcp_debug_print_state(pcb->state); - } - - LWIP_DEBUGF(TCP_DEBUG, ("Listen PCB states:\n")); - for (pcbl = tcp_listen_pcbs.listen_pcbs; pcbl != NULL; pcbl = pcbl->next) { - LWIP_DEBUGF(TCP_DEBUG, ("Local port %"U16_F" ", pcbl->local_port)); - tcp_debug_print_state(pcbl->state); - } - - LWIP_DEBUGF(TCP_DEBUG, ("TIME-WAIT PCB states:\n")); - for (pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) { - LWIP_DEBUGF(TCP_DEBUG, ("Local port %"U16_F", foreign port %"U16_F" snd_nxt %"U32_F" rcv_nxt %"U32_F" ", - pcb->local_port, pcb->remote_port, - pcb->snd_nxt, pcb->rcv_nxt)); - tcp_debug_print_state(pcb->state); - } -} - -/** - * Check state consistency of the tcp_pcb lists. - */ -s16_t -tcp_pcbs_sane(void) -{ - struct tcp_pcb *pcb; - for (pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { - LWIP_ASSERT("tcp_pcbs_sane: active pcb->state != CLOSED", pcb->state != CLOSED); - LWIP_ASSERT("tcp_pcbs_sane: active pcb->state != LISTEN", pcb->state != LISTEN); - LWIP_ASSERT("tcp_pcbs_sane: active pcb->state != TIME-WAIT", pcb->state != TIME_WAIT); - } - for (pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) { - LWIP_ASSERT("tcp_pcbs_sane: tw pcb->state == TIME-WAIT", pcb->state == TIME_WAIT); - } - return 1; -} -#endif /* TCP_DEBUG */ - -#endif /* LWIP_TCP */ diff --git a/third_party/lwip/repo/lwip/src/core/tcp_in.c b/third_party/lwip/repo/lwip/src/core/tcp_in.c deleted file mode 100644 index dacb49f9a68f75..00000000000000 --- a/third_party/lwip/repo/lwip/src/core/tcp_in.c +++ /dev/null @@ -1,1859 +0,0 @@ -/** - * @file - * Transmission Control Protocol, incoming traffic - * - * The input processing functions of the TCP layer. - * - * These functions are generally called in the order (ip_input() ->) - * tcp_input() -> * tcp_process() -> tcp_receive() (-> application). - * - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ - -#include "lwip/opt.h" - -#if LWIP_TCP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/priv/tcp_priv.h" -#include "lwip/def.h" -#include "lwip/ip_addr.h" -#include "lwip/netif.h" -#include "lwip/mem.h" -#include "lwip/memp.h" -#include "lwip/inet_chksum.h" -#include "lwip/stats.h" -#include "lwip/ip6.h" -#include "lwip/ip6_addr.h" -#if LWIP_ND6_TCP_REACHABILITY_HINTS -#include "lwip/nd6.h" -#endif /* LWIP_ND6_TCP_REACHABILITY_HINTS */ - -/** Initial CWND calculation as defined RFC 2581 */ -#define LWIP_TCP_CALC_INITIAL_CWND(mss) LWIP_MIN((4U * (mss)), LWIP_MAX((2U * (mss)), 4380U)); - -/* These variables are global to all functions involved in the input - processing of TCP segments. They are set by the tcp_input() - function. */ -static struct tcp_seg inseg; -static struct tcp_hdr *tcphdr; -static u16_t tcphdr_optlen; -static u16_t tcphdr_opt1len; -static u8_t* tcphdr_opt2; -static u16_t tcp_optidx; -static u32_t seqno, ackno; -static tcpwnd_size_t recv_acked; -static u16_t tcplen; -static u8_t flags; - -static u8_t recv_flags; -static struct pbuf *recv_data; - -struct tcp_pcb *tcp_input_pcb; - -/* Forward declarations. */ -static err_t tcp_process(struct tcp_pcb *pcb); -static void tcp_receive(struct tcp_pcb *pcb); -static void tcp_parseopt(struct tcp_pcb *pcb); - -static void tcp_listen_input(struct tcp_pcb_listen *pcb, struct netif *inp); -static void tcp_timewait_input(struct tcp_pcb *pcb); - -static int tcp_input_delayed_close(struct tcp_pcb *pcb); - -/** - * The initial input processing of TCP. It verifies the TCP header, demultiplexes - * the segment between the PCBs and passes it on to tcp_process(), which implements - * the TCP finite state machine. This function is called by the IP layer (in - * ip_input()). - * - * @param p received TCP segment to process (p->payload pointing to the TCP header) - * @param inp network interface on which this segment was received - */ -void -tcp_input(struct pbuf *p, struct netif *inp) -{ - struct tcp_pcb *pcb, *prev; - struct tcp_pcb_listen *lpcb; -#if SO_REUSE - struct tcp_pcb *lpcb_prev = NULL; - struct tcp_pcb_listen *lpcb_any = NULL; -#endif /* SO_REUSE */ - u8_t hdrlen_bytes; - err_t err; - - LWIP_UNUSED_ARG(inp); - LWIP_ASSERT_CORE_LOCKED(); - - PERF_START; - - TCP_STATS_INC(tcp.recv); - MIB2_STATS_INC(mib2.tcpinsegs); - - tcphdr = (struct tcp_hdr *)p->payload; - -#if TCP_INPUT_DEBUG -#if LWIP_IP_DEBUG_TARGET - if (debug_target_match(ip_current_is_v6(), ipX_current_src_addr(), ipX_current_dest_addr())) - { -#endif - tcp_debug_print(tcphdr); -#if LWIP_IP_DEBUG_TARGET - } -#endif -#endif - - /* Check that TCP header fits in payload */ - if (p->len < TCP_HLEN) { - /* drop short packets */ - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: short packet (%"U16_F" bytes) discarded\n", p->tot_len)); - TCP_STATS_INC(tcp.lenerr); - goto dropped; - } - - /* Don't even process incoming broadcasts/multicasts. */ - if (ip_addr_isbroadcast(ip_current_dest_addr(), ip_current_netif()) || - ip_addr_ismulticast(ip_current_dest_addr())) { - TCP_STATS_INC(tcp.proterr); - goto dropped; - } - -#if CHECKSUM_CHECK_TCP - IF__NETIF_CHECKSUM_ENABLED(inp, NETIF_CHECKSUM_CHECK_TCP) { - /* Verify TCP checksum. */ - u16_t chksum = ip_chksum_pseudo(p, IP_PROTO_TCP, p->tot_len, - ip_current_src_addr(), ip_current_dest_addr()); - if (chksum != 0) { - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packet discarded due to failing checksum 0x%04"X16_F"\n", - chksum)); - tcp_debug_print(tcphdr); - TCP_STATS_INC(tcp.chkerr); - goto dropped; - } - } -#endif /* CHECKSUM_CHECK_TCP */ - - /* sanity-check header length */ - hdrlen_bytes = TCPH_HDRLEN(tcphdr) * 4; - if ((hdrlen_bytes < TCP_HLEN) || (hdrlen_bytes > p->tot_len)) { - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: invalid header length (%"U16_F")\n", (u16_t)hdrlen_bytes)); - TCP_STATS_INC(tcp.lenerr); - goto dropped; - } - - /* Move the payload pointer in the pbuf so that it points to the - TCP data instead of the TCP header. */ - tcphdr_optlen = hdrlen_bytes - TCP_HLEN; - tcphdr_opt2 = NULL; - if (p->len >= hdrlen_bytes) { - /* all options are in the first pbuf */ - tcphdr_opt1len = tcphdr_optlen; - pbuf_header(p, -(s16_t)hdrlen_bytes); /* cannot fail */ - } else { - u16_t opt2len; - /* TCP header fits into first pbuf, options don't - data is in the next pbuf */ - /* there must be a next pbuf, due to hdrlen_bytes sanity check above */ - LWIP_ASSERT("p->next != NULL", p->next != NULL); - - /* advance over the TCP header (cannot fail) */ - pbuf_header(p, -TCP_HLEN); - - /* determine how long the first and second parts of the options are */ - tcphdr_opt1len = p->len; - opt2len = tcphdr_optlen - tcphdr_opt1len; - - /* options continue in the next pbuf: set p to zero length and hide the - options in the next pbuf (adjusting p->tot_len) */ - pbuf_header(p, -(s16_t)tcphdr_opt1len); - - /* check that the options fit in the second pbuf */ - if (opt2len > p->next->len) { - /* drop short packets */ - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: options overflow second pbuf (%"U16_F" bytes)\n", p->next->len)); - TCP_STATS_INC(tcp.lenerr); - goto dropped; - } - - /* remember the pointer to the second part of the options */ - tcphdr_opt2 = (u8_t*)p->next->payload; - - /* advance p->next to point after the options, and manually - adjust p->tot_len to keep it consistent with the changed p->next */ - pbuf_header(p->next, -(s16_t)opt2len); - p->tot_len -= opt2len; - - LWIP_ASSERT("p->len == 0", p->len == 0); - LWIP_ASSERT("p->tot_len == p->next->tot_len", p->tot_len == p->next->tot_len); - } - - /* Convert fields in TCP header to host byte order. */ - tcphdr->src = lwip_ntohs(tcphdr->src); - tcphdr->dest = lwip_ntohs(tcphdr->dest); - seqno = tcphdr->seqno = lwip_ntohl(tcphdr->seqno); - ackno = tcphdr->ackno = lwip_ntohl(tcphdr->ackno); - tcphdr->wnd = lwip_ntohs(tcphdr->wnd); - - flags = TCPH_FLAGS(tcphdr); - tcplen = p->tot_len + ((flags & (TCP_FIN | TCP_SYN)) ? 1 : 0); - - /* Demultiplex an incoming segment. First, we check if it is destined - for an active connection. */ - prev = NULL; - - for (pcb = tcp_active_pcbs; pcb != NULL; pcb = pcb->next) { - LWIP_ASSERT("tcp_input: active pcb->state != CLOSED", pcb->state != CLOSED); - LWIP_ASSERT("tcp_input: active pcb->state != TIME-WAIT", pcb->state != TIME_WAIT); - LWIP_ASSERT("tcp_input: active pcb->state != LISTEN", pcb->state != LISTEN); - if (pcb->remote_port == tcphdr->src && - pcb->local_port == tcphdr->dest && -#if LWIP_MANAGEMENT_CHANNEL - (!inp->using_management_channel || ip_get_option(pcb,SOF_MANAGEMENT)) && -#endif - ip_addr_cmp(&pcb->remote_ip, ip_current_src_addr()) && - ip_addr_cmp(&pcb->local_ip, ip_current_dest_addr())) { - /* Move this PCB to the front of the list so that subsequent - lookups will be faster (we exploit locality in TCP segment - arrivals). */ - LWIP_ASSERT("tcp_input: pcb->next != pcb (before cache)", pcb->next != pcb); - if (prev != NULL) { - prev->next = pcb->next; - pcb->next = tcp_active_pcbs; - tcp_active_pcbs = pcb; - } else { - TCP_STATS_INC(tcp.cachehit); - } - LWIP_ASSERT("tcp_input: pcb->next != pcb (after cache)", pcb->next != pcb); - break; - } - prev = pcb; - } - - if (pcb == NULL) { - /* If it did not go to an active connection, we check the connections - in the TIME-WAIT state. */ - for (pcb = tcp_tw_pcbs; pcb != NULL; pcb = pcb->next) { - LWIP_ASSERT("tcp_input: TIME-WAIT pcb->state == TIME-WAIT", pcb->state == TIME_WAIT); - if (pcb->remote_port == tcphdr->src && - pcb->local_port == tcphdr->dest && -#if LWIP_MANAGEMENT_CHANNEL - (!inp->using_management_channel || ip_get_option(pcb,SOF_MANAGEMENT)) && -#endif - ip_addr_cmp(&pcb->remote_ip, ip_current_src_addr()) && - ip_addr_cmp(&pcb->local_ip, ip_current_dest_addr())) { - /* We don't really care enough to move this PCB to the front - of the list since we are not very likely to receive that - many segments for connections in TIME-WAIT. */ - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packed for TIME_WAITing connection.\n")); - tcp_timewait_input(pcb); - pbuf_free(p); - return; - } - } - - /* Finally, if we still did not get a match, we check all PCBs that - are LISTENing for incoming connections. */ - prev = NULL; - for (lpcb = tcp_listen_pcbs.listen_pcbs; lpcb != NULL; lpcb = lpcb->next) { -#if LWIP_MANAGEMENT_CHANNEL - if (inp->using_management_channel && !ip_get_option(lpcb,SOF_MANAGEMENT)) - continue; -#endif - /* check if PCB is bound to specific netif */ - if ((lpcb->netif_idx != NETIF_NO_INDEX) && - (lpcb->netif_idx != netif_get_index(ip_data.current_input_netif))) { - continue; - } - - if (lpcb->local_port == tcphdr->dest) { - if (IP_IS_ANY_TYPE_VAL(lpcb->local_ip)) { - /* found an ANY TYPE (IPv4/IPv6) match */ -#if SO_REUSE - lpcb_any = lpcb; - lpcb_prev = prev; -#else /* SO_REUSE */ - break; -#endif /* SO_REUSE */ - } else if (IP_ADDR_PCB_VERSION_MATCH_EXACT(lpcb, ip_current_dest_addr())) { - if (ip_addr_cmp(&lpcb->local_ip, ip_current_dest_addr())) { - /* found an exact match */ - break; - } else if (ip_addr_isany(&lpcb->local_ip)) { - /* found an ANY-match */ -#if SO_REUSE - lpcb_any = lpcb; - lpcb_prev = prev; -#else /* SO_REUSE */ - break; - #endif /* SO_REUSE */ - } - } - } - prev = (struct tcp_pcb *)lpcb; - } -#if SO_REUSE - /* first try specific local IP */ - if (lpcb == NULL) { - /* only pass to ANY if no specific local IP has been found */ - lpcb = lpcb_any; - prev = lpcb_prev; - } -#endif /* SO_REUSE */ - if (lpcb != NULL) { - /* Move this PCB to the front of the list so that subsequent - lookups will be faster (we exploit locality in TCP segment - arrivals). */ - if (prev != NULL) { - ((struct tcp_pcb_listen *)prev)->next = lpcb->next; - /* our successor is the remainder of the listening list */ - lpcb->next = tcp_listen_pcbs.listen_pcbs; - /* put this listening pcb at the head of the listening list */ - tcp_listen_pcbs.listen_pcbs = lpcb; - } else { - TCP_STATS_INC(tcp.cachehit); - } - - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: packed for LISTENing connection.\n")); - tcp_listen_input(lpcb, inp); - pbuf_free(p); - return; - } - } - - if (pcb != NULL) { - /* The incoming segment belongs to a connection. */ -#if TCP_INPUT_DEBUG - tcp_debug_print_state(pcb->state); -#endif /* TCP_INPUT_DEBUG */ - - /* Set up a tcp_seg structure. */ - inseg.next = NULL; - inseg.len = p->tot_len; - inseg.p = p; - inseg.tcphdr = tcphdr; - - recv_data = NULL; - recv_flags = 0; - recv_acked = 0; - - if (flags & TCP_PSH) { - p->flags |= PBUF_FLAG_PUSH; - } - - /* If there is data which was previously "refused" by upper layer */ - if (pcb->refused_data != NULL) { - if ((tcp_process_refused_data(pcb) == ERR_ABRT) || - ((pcb->refused_data != NULL) && (tcplen > 0))) { - /* pcb has been aborted or refused data is still refused and the new - segment contains data */ - if (pcb->rcv_ann_wnd == 0) { - /* this is a zero-window probe, we respond to it with current RCV.NXT - and drop the data segment */ - tcp_send_empty_ack(pcb); - } - TCP_STATS_INC(tcp.drop); - MIB2_STATS_INC(mib2.tcpinerrs); - goto aborted; - } - } - tcp_input_pcb = pcb; - err = tcp_process(pcb); - /* A return value of ERR_ABRT means that tcp_abort() was called - and that the pcb has been freed. If so, we don't do anything. */ - if (err != ERR_ABRT) { - if (recv_flags & TF_RESET) { - /* TF_RESET means that the connection was reset by the other - end. We then call the error callback to inform the - application that the connection is dead before we - deallocate the PCB. */ - TCP_EVENT_ERR(pcb->state, pcb->errf, pcb->callback_arg, ERR_RST); - tcp_pcb_remove(&tcp_active_pcbs, pcb); - memp_free(MEMP_TCP_PCB, pcb); - } else { - err = ERR_OK; - /* If the application has registered a "sent" function to be - called when new send buffer space is available, we call it - now. */ - if (recv_acked > 0) { - u16_t acked16; -#if LWIP_WND_SCALE - /* recv_acked is u32_t but the sent callback only takes a u16_t, - so we might have to call it multiple times. */ - u32_t acked = recv_acked; - while (acked > 0) { - acked16 = (u16_t)LWIP_MIN(acked, 0xffffu); - acked -= acked16; -#else - { - acked16 = recv_acked; -#endif - TCP_EVENT_SENT(pcb, (u16_t)acked16, err); - if (err == ERR_ABRT) { - goto aborted; - } - } - recv_acked = 0; - } - if (tcp_input_delayed_close(pcb)) { - goto aborted; - } -#if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE - while (recv_data != NULL) { - struct pbuf *rest = NULL; - pbuf_split_64k(recv_data, &rest); -#else /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */ - if (recv_data != NULL) { -#endif /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */ - - LWIP_ASSERT("pcb->refused_data == NULL", pcb->refused_data == NULL); - if (pcb->flags & TF_RXCLOSED) { - /* received data although already closed -> abort (send RST) to - notify the remote host that not all data has been processed */ - pbuf_free(recv_data); -#if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE - if (rest != NULL) { - pbuf_free(rest); - } -#endif /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */ - tcp_abort(pcb); - goto aborted; - } - - /* Notify application that data has been received. */ - TCP_EVENT_RECV(pcb, recv_data, ERR_OK, err); - if (err == ERR_ABRT) { -#if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE - if (rest != NULL) { - pbuf_free(rest); - } -#endif /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */ - goto aborted; - } - - /* If the upper layer can't receive this data, store it */ - if (err != ERR_OK) { -#if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE - if (rest != NULL) { - pbuf_cat(recv_data, rest); - } -#endif /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */ - pcb->refused_data = recv_data; - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_input: keep incoming packet, because pcb is \"full\"\n")); -#if TCP_QUEUE_OOSEQ && LWIP_WND_SCALE - break; - } else { - /* Upper layer received the data, go on with the rest if > 64K */ - recv_data = rest; -#endif /* TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */ - } - } - - /* If a FIN segment was received, we call the callback - function with a NULL buffer to indicate EOF. */ - if (recv_flags & TF_GOT_FIN) { - if (pcb->refused_data != NULL) { - /* Delay this if we have refused data. */ - pcb->refused_data->flags |= PBUF_FLAG_TCP_FIN; - } else { - /* correct rcv_wnd as the application won't call tcp_recved() - for the FIN's seqno */ - if (pcb->rcv_wnd != TCP_WND_MAX(pcb)) { - pcb->rcv_wnd++; - } - TCP_EVENT_CLOSED(pcb, err); - if (err == ERR_ABRT) { - goto aborted; - } - } - } - - tcp_input_pcb = NULL; - if (tcp_input_delayed_close(pcb)) { - goto aborted; - } - /* Try to send something out. */ - tcp_output(pcb); -#if TCP_INPUT_DEBUG -#if TCP_DEBUG - tcp_debug_print_state(pcb->state); -#endif /* TCP_DEBUG */ -#endif /* TCP_INPUT_DEBUG */ - } - } - /* Jump target if pcb has been aborted in a callback (by calling tcp_abort()). - Below this line, 'pcb' may not be dereferenced! */ -aborted: - tcp_input_pcb = NULL; - recv_data = NULL; - - /* give up our reference to inseg.p */ - if (inseg.p != NULL) - { - pbuf_free(inseg.p); - inseg.p = NULL; - } - } else { - - /* If no matching PCB was found, send a TCP RST (reset) to the - sender. */ - LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_input: no PCB match found, resetting.\n")); - if (!(TCPH_FLAGS(tcphdr) & TCP_RST)) { - TCP_STATS_INC(tcp.proterr); - TCP_STATS_INC(tcp.drop); - tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(), - ip_current_src_addr(), tcphdr->dest, tcphdr->src); - } - pbuf_free(p); - } - - LWIP_ASSERT("tcp_input: tcp_pcbs_sane()", tcp_pcbs_sane()); - PERF_STOP("tcp_input"); - return; -dropped: - TCP_STATS_INC(tcp.drop); - MIB2_STATS_INC(mib2.tcpinerrs); - pbuf_free(p); -} - -/** Called from tcp_input to check for TF_CLOSED flag. This results in closing - * and deallocating a pcb at the correct place to ensure noone references it - * any more. - * @returns 1 if the pcb has been closed and deallocated, 0 otherwise - */ -static int -tcp_input_delayed_close(struct tcp_pcb *pcb) -{ - if (recv_flags & TF_CLOSED) { - /* The connection has been closed and we will deallocate the - PCB. */ - if (!(pcb->flags & TF_RXCLOSED)) { - /* Connection closed although the application has only shut down the - tx side: call the PCB's err callback and indicate the closure to - ensure the application doesn't continue using the PCB. */ - TCP_EVENT_ERR(pcb->state, pcb->errf, pcb->callback_arg, ERR_CLSD); - } - tcp_pcb_remove(&tcp_active_pcbs, pcb); - memp_free(MEMP_TCP_PCB, pcb); - return 1; - } - return 0; -} - -/** - * Called by tcp_input() when a segment arrives for a listening - * connection (from tcp_input()). - * - * @param pcb the tcp_pcb_listen for which a segment arrived - * - * @note the segment which arrived is saved in global variables, therefore only the pcb - * involved is passed as a parameter to this function - */ -static void -tcp_listen_input(struct tcp_pcb_listen *pcb, struct netif *inp) -{ - struct tcp_pcb *npcb; - u32_t iss; - err_t rc; - - if (flags & TCP_RST) { - /* An incoming RST should be ignored. Return. */ - return; - } - - /* In the LISTEN state, we check for incoming SYN segments, - creates a new PCB, and responds with a SYN|ACK. */ - if (flags & TCP_ACK) { - /* For incoming segments with the ACK flag set, respond with a - RST. */ - LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_listen_input: ACK in LISTEN, sending reset\n")); - tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(), - ip_current_src_addr(), tcphdr->dest, tcphdr->src); - } else if (flags & TCP_SYN) { - LWIP_DEBUGF(TCP_DEBUG, ("TCP connection request %"U16_F" -> %"U16_F".\n", tcphdr->src, tcphdr->dest)); -#if TCP_LISTEN_BACKLOG - if (pcb->accepts_pending >= pcb->backlog) { - LWIP_DEBUGF(TCP_DEBUG, ("tcp_listen_input: listen backlog exceeded for port %"U16_F"\n", tcphdr->dest)); - return; - } -#endif /* TCP_LISTEN_BACKLOG */ - npcb = tcp_alloc(pcb->prio); - /* If a new PCB could not be created (probably due to lack of memory), - we don't do anything, but rely on the sender will retransmit the - SYN at a time when we have more memory available. */ - if (npcb == NULL) { - err_t err; - LWIP_DEBUGF(TCP_DEBUG, ("tcp_listen_input: could not allocate PCB\n")); - TCP_STATS_INC(tcp.memerr); - TCP_EVENT_ACCEPT(pcb, NULL, pcb->callback_arg, ERR_MEM, err); - LWIP_UNUSED_ARG(err); /* err not useful here */ - return; - } -#if TCP_LISTEN_BACKLOG - pcb->accepts_pending++; - npcb->flags |= TF_BACKLOGPEND; -#endif /* TCP_LISTEN_BACKLOG */ - /* Set up the new PCB. */ - ip_addr_copy(npcb->local_ip, *ip_current_dest_addr()); - ip_addr_copy(npcb->remote_ip, *ip_current_src_addr()); - npcb->local_port = pcb->local_port; - npcb->remote_port = tcphdr->src; - npcb->state = SYN_RCVD; - npcb->rcv_nxt = seqno + 1; - npcb->rcv_ann_right_edge = npcb->rcv_nxt; - iss = tcp_next_iss(npcb); - npcb->snd_wl2 = iss; - npcb->snd_nxt = iss; - npcb->lastack = iss; - npcb->snd_lbb = iss; - npcb->snd_wl1 = seqno - 1;/* initialise to seqno-1 to force window update */ - npcb->callback_arg = pcb->callback_arg; -#if LWIP_CALLBACK_API || TCP_LISTEN_BACKLOG - npcb->listener = pcb; -#endif /* LWIP_CALLBACK_API || TCP_LISTEN_BACKLOG */ - /* inherit socket options */ - npcb->so_options = pcb->so_options & SOF_INHERITED; -#if LWIP_MANAGEMENT_CHANNEL - if( inp->using_management_channel ) - ip_set_option(npcb, SOF_MANAGEMENT); -#endif - - /* Register the new PCB so that we can begin receiving segments - for it. */ - TCP_REG_ACTIVE(npcb); - - /* Parse any options in the SYN. */ - tcp_parseopt(npcb); - npcb->snd_wnd = tcphdr->wnd; - npcb->snd_wnd_max = npcb->snd_wnd; - -#if TCP_CALCULATE_EFF_SEND_MSS - npcb->mss = tcp_eff_send_mss(npcb->mss, &npcb->local_ip, &npcb->remote_ip); -#endif /* TCP_CALCULATE_EFF_SEND_MSS */ - - MIB2_STATS_INC(mib2.tcppassiveopens); - - /* Send a SYN|ACK together with the MSS option. */ - rc = tcp_enqueue_flags(npcb, TCP_SYN | TCP_ACK); - if (rc != ERR_OK) { - tcp_abandon(npcb, 0); - return; - } - tcp_output(npcb); - } - return; -} - -/** - * Called by tcp_input() when a segment arrives for a connection in - * TIME_WAIT. - * - * @param pcb the tcp_pcb for which a segment arrived - * - * @note the segment which arrived is saved in global variables, therefore only the pcb - * involved is passed as a parameter to this function - */ -static void -tcp_timewait_input(struct tcp_pcb *pcb) -{ - /* RFC 1337: in TIME_WAIT, ignore RST and ACK FINs + any 'acceptable' segments */ - /* RFC 793 3.9 Event Processing - Segment Arrives: - * - first check sequence number - we skip that one in TIME_WAIT (always - * acceptable since we only send ACKs) - * - second check the RST bit (... return) */ - if (flags & TCP_RST) { - return; - } - /* - fourth, check the SYN bit, */ - if (flags & TCP_SYN) { - /* If an incoming segment is not acceptable, an acknowledgment - should be sent in reply */ - if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, pcb->rcv_nxt + pcb->rcv_wnd)) { - /* If the SYN is in the window it is an error, send a reset */ - tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(), - ip_current_src_addr(), tcphdr->dest, tcphdr->src); - return; - } - } else if (flags & TCP_FIN) { - /* - eighth, check the FIN bit: Remain in the TIME-WAIT state. - Restart the 2 MSL time-wait timeout.*/ - pcb->tmr = tcp_ticks; - } - - if ((tcplen > 0)) { - /* Acknowledge data, FIN or out-of-window SYN */ - pcb->flags |= TF_ACK_NOW; - tcp_output(pcb); - } - return; -} - -/** - * Implements the TCP state machine. Called by tcp_input. In some - * states tcp_receive() is called to receive data. The tcp_seg - * argument will be freed by the caller (tcp_input()) unless the - * recv_data pointer in the pcb is set. - * - * @param pcb the tcp_pcb for which a segment arrived - * - * @note the segment which arrived is saved in global variables, therefore only the pcb - * involved is passed as a parameter to this function - */ -static err_t -tcp_process(struct tcp_pcb *pcb) -{ - struct tcp_seg *rseg; - u8_t acceptable = 0; - err_t err; - - err = ERR_OK; - - /* Process incoming RST segments. */ - if (flags & TCP_RST) { - /* First, determine if the reset is acceptable. */ - if (pcb->state == SYN_SENT) { - /* "In the SYN-SENT state (a RST received in response to an initial SYN), - the RST is acceptable if the ACK field acknowledges the SYN." */ - if (ackno == pcb->snd_nxt) { - acceptable = 1; - } - } else { - /* "In all states except SYN-SENT, all reset (RST) segments are validated - by checking their SEQ-fields." */ - if (seqno == pcb->rcv_nxt) { - acceptable = 1; - } else if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, - pcb->rcv_nxt + pcb->rcv_wnd)) { - /* If the sequence number is inside the window, we only send an ACK - and wait for a re-send with matching sequence number. - This violates RFC 793, but is required to protection against - CVE-2004-0230 (RST spoofing attack). */ - tcp_ack_now(pcb); - } - } - - if (acceptable) { - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_process: Connection RESET\n")); - LWIP_ASSERT("tcp_input: pcb->state != CLOSED", pcb->state != CLOSED); - recv_flags |= TF_RESET; - pcb->flags &= ~TF_ACK_DELAY; - return ERR_RST; - } else { - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_process: unacceptable reset seqno %"U32_F" rcv_nxt %"U32_F"\n", - seqno, pcb->rcv_nxt)); - LWIP_DEBUGF(TCP_DEBUG, ("tcp_process: unacceptable reset seqno %"U32_F" rcv_nxt %"U32_F"\n", - seqno, pcb->rcv_nxt)); - return ERR_OK; - } - } - - if ((flags & TCP_SYN) && (pcb->state != SYN_SENT && pcb->state != SYN_RCVD)) { - /* Cope with new connection attempt after remote end crashed */ - tcp_ack_now(pcb); - return ERR_OK; - } - - if ((pcb->flags & TF_RXCLOSED) == 0) { - /* Update the PCB (in)activity timer unless rx is closed (see tcp_shutdown) */ - pcb->tmr = tcp_ticks; - } - pcb->keep_cnt_sent = 0; - - tcp_parseopt(pcb); - - /* Do different things depending on the TCP state. */ - switch (pcb->state) { - case SYN_SENT: - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("SYN-SENT: ackno %"U32_F" pcb->snd_nxt %"U32_F" unacked %"U32_F"\n", ackno, - pcb->snd_nxt, lwip_ntohl(pcb->unacked->tcphdr->seqno))); - /* received SYN ACK with expected sequence number? */ - if ((flags & TCP_ACK) && (flags & TCP_SYN) - && (ackno == pcb->lastack + 1)) { - pcb->rcv_nxt = seqno + 1; - pcb->rcv_ann_right_edge = pcb->rcv_nxt; - pcb->lastack = ackno; - pcb->snd_wnd = tcphdr->wnd; - pcb->snd_wnd_max = pcb->snd_wnd; - pcb->snd_wl1 = seqno - 1; /* initialise to seqno - 1 to force window update */ - pcb->state = ESTABLISHED; - -#if TCP_CALCULATE_EFF_SEND_MSS - pcb->mss = tcp_eff_send_mss(pcb->mss, &pcb->local_ip, &pcb->remote_ip); -#endif /* TCP_CALCULATE_EFF_SEND_MSS */ - - pcb->cwnd = LWIP_TCP_CALC_INITIAL_CWND(pcb->mss); - LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_process (SENT): cwnd %"TCPWNDSIZE_F - " ssthresh %"TCPWNDSIZE_F"\n", - pcb->cwnd, pcb->ssthresh)); - LWIP_ASSERT("pcb->snd_queuelen > 0", (pcb->snd_queuelen > 0)); - --pcb->snd_queuelen; - LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_process: SYN-SENT --queuelen %"TCPWNDSIZE_F"\n", (tcpwnd_size_t)pcb->snd_queuelen)); - rseg = pcb->unacked; - if (rseg == NULL) { - /* might happen if tcp_output fails in tcp_rexmit_rto() - in which case the segment is on the unsent list */ - rseg = pcb->unsent; - LWIP_ASSERT("no segment to free", rseg != NULL); - pcb->unsent = rseg->next; - } else { - pcb->unacked = rseg->next; - } - tcp_seg_free(rseg); - - /* If there's nothing left to acknowledge, stop the retransmit - timer, otherwise reset it to start again */ - if (pcb->unacked == NULL) { - pcb->rtime = -1; - } else { - pcb->rtime = 0; - pcb->nrtx = 0; - } - - /* Call the user specified function to call when successfully - * connected. */ - TCP_EVENT_CONNECTED(pcb, ERR_OK, err); - if (err == ERR_ABRT) { - return ERR_ABRT; - } - tcp_ack_now(pcb); - } - /* received ACK? possibly a half-open connection */ - else if (flags & TCP_ACK) { - /* send a RST to bring the other side in a non-synchronized state. */ - tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(), - ip_current_src_addr(), tcphdr->dest, tcphdr->src); - /* Resend SYN immediately (don't wait for rto timeout) to establish - connection faster, but do not send more SYNs than we otherwise would - have, or we might get caught in a loop on loopback interfaces. */ - if (pcb->nrtx < TCP_SYNMAXRTX) { - pcb->rtime = 0; - tcp_rexmit_rto(pcb); - } - } - break; - case SYN_RCVD: - if (flags & TCP_ACK) { - /* expected ACK number? */ - if (TCP_SEQ_BETWEEN(ackno, pcb->lastack+1, pcb->snd_nxt)) { - pcb->state = ESTABLISHED; - LWIP_DEBUGF(TCP_DEBUG, ("TCP connection established %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); -#if LWIP_CALLBACK_API || TCP_LISTEN_BACKLOG -#if LWIP_CALLBACK_API - LWIP_ASSERT("pcb->listener->accept != NULL", - (pcb->listener == NULL) || (pcb->listener->accept != NULL)); -#endif - if (pcb->listener == NULL) { - /* listen pcb might be closed by now */ - err = ERR_VAL; - } else -#endif /* LWIP_CALLBACK_API || TCP_LISTEN_BACKLOG */ - { - tcp_backlog_accepted(pcb); - /* Call the accept function. */ - TCP_EVENT_ACCEPT(pcb->listener, pcb, pcb->callback_arg, ERR_OK, err); - } - if (err != ERR_OK) { - /* If the accept function returns with an error, we abort - * the connection. */ - /* Already aborted? */ - if (err != ERR_ABRT) { - tcp_abort(pcb); - } - return ERR_ABRT; - } - /* If there was any data contained within this ACK, - * we'd better pass it on to the application as well. */ - tcp_receive(pcb); - - /* Prevent ACK for SYN to generate a sent event */ - if (recv_acked != 0) { - recv_acked--; - } - - pcb->cwnd = LWIP_TCP_CALC_INITIAL_CWND(pcb->mss); - LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_process (SYN_RCVD): cwnd %"TCPWNDSIZE_F - " ssthresh %"TCPWNDSIZE_F"\n", - pcb->cwnd, pcb->ssthresh)); - - if (recv_flags & TF_GOT_FIN) { - tcp_ack_now(pcb); - pcb->state = CLOSE_WAIT; - } - } else { - /* incorrect ACK number, send RST */ - tcp_rst(ackno, seqno + tcplen, ip_current_dest_addr(), - ip_current_src_addr(), tcphdr->dest, tcphdr->src); - } - } else if ((flags & TCP_SYN) && (seqno == pcb->rcv_nxt - 1)) { - /* Looks like another copy of the SYN - retransmit our SYN-ACK */ - tcp_rexmit(pcb); - } - break; - case CLOSE_WAIT: - /* FALLTHROUGH */ - case ESTABLISHED: - tcp_receive(pcb); - if (recv_flags & TF_GOT_FIN) { /* passive close */ - tcp_ack_now(pcb); - pcb->state = CLOSE_WAIT; - } - break; - case FIN_WAIT_1: - tcp_receive(pcb); - if (recv_flags & TF_GOT_FIN) { - if ((flags & TCP_ACK) && (ackno == pcb->snd_nxt) && - pcb->unsent == NULL) { - LWIP_DEBUGF(TCP_DEBUG, - ("TCP connection closed: FIN_WAIT_1 %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); - tcp_ack_now(pcb); - tcp_pcb_purge(pcb); - TCP_RMV_ACTIVE(pcb); - pcb->state = TIME_WAIT; - TCP_REG(&tcp_tw_pcbs, pcb); - } else { - tcp_ack_now(pcb); - pcb->state = CLOSING; - } - } else if ((flags & TCP_ACK) && (ackno == pcb->snd_nxt) && - pcb->unsent == NULL) { - pcb->state = FIN_WAIT_2; - } - break; - case FIN_WAIT_2: - tcp_receive(pcb); - if (recv_flags & TF_GOT_FIN) { - LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: FIN_WAIT_2 %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); - tcp_ack_now(pcb); - tcp_pcb_purge(pcb); - TCP_RMV_ACTIVE(pcb); - pcb->state = TIME_WAIT; - TCP_REG(&tcp_tw_pcbs, pcb); - } - break; - case CLOSING: - tcp_receive(pcb); - if ((flags & TCP_ACK) && ackno == pcb->snd_nxt && pcb->unsent == NULL) { - LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: CLOSING %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); - tcp_pcb_purge(pcb); - TCP_RMV_ACTIVE(pcb); - pcb->state = TIME_WAIT; - TCP_REG(&tcp_tw_pcbs, pcb); - } - break; - case LAST_ACK: - tcp_receive(pcb); - if ((flags & TCP_ACK) && ackno == pcb->snd_nxt && pcb->unsent == NULL) { - LWIP_DEBUGF(TCP_DEBUG, ("TCP connection closed: LAST_ACK %"U16_F" -> %"U16_F".\n", inseg.tcphdr->src, inseg.tcphdr->dest)); - /* bugfix #21699: don't set pcb->state to CLOSED here or we risk leaking segments */ - recv_flags |= TF_CLOSED; - } - break; - default: - break; - } - return ERR_OK; -} - -#if TCP_QUEUE_OOSEQ -/** - * Insert segment into the list (segments covered with new one will be deleted) - * - * Called from tcp_receive() - */ -static void -tcp_oos_insert_segment(struct tcp_seg *cseg, struct tcp_seg *next) -{ - struct tcp_seg *old_seg; - - if (TCPH_FLAGS(cseg->tcphdr) & TCP_FIN) { - /* received segment overlaps all following segments */ - tcp_segs_free(next); - next = NULL; - } else { - /* delete some following segments - oos queue may have segments with FIN flag */ - while (next && - TCP_SEQ_GEQ((seqno + cseg->len), - (next->tcphdr->seqno + next->len))) { - /* cseg with FIN already processed */ - if (TCPH_FLAGS(next->tcphdr) & TCP_FIN) { - TCPH_SET_FLAG(cseg->tcphdr, TCP_FIN); - } - old_seg = next; - next = next->next; - tcp_seg_free(old_seg); - } - if (next && - TCP_SEQ_GT(seqno + cseg->len, next->tcphdr->seqno)) { - /* We need to trim the incoming segment. */ - cseg->len = (u16_t)(next->tcphdr->seqno - seqno); - pbuf_realloc(cseg->p, cseg->len); - } - } - cseg->next = next; -} -#endif /* TCP_QUEUE_OOSEQ */ - -/** - * Called by tcp_process. Checks if the given segment is an ACK for outstanding - * data, and if so frees the memory of the buffered data. Next, it places the - * segment on any of the receive queues (pcb->recved or pcb->ooseq). If the segment - * is buffered, the pbuf is referenced by pbuf_ref so that it will not be freed until - * it has been removed from the buffer. - * - * If the incoming segment constitutes an ACK for a segment that was used for RTT - * estimation, the RTT is estimated here as well. - * - * Called from tcp_process(). - */ -static void -tcp_receive(struct tcp_pcb *pcb) -{ - struct tcp_seg *next; -#if TCP_QUEUE_OOSEQ - struct tcp_seg *prev, *cseg; -#endif /* TCP_QUEUE_OOSEQ */ - s32_t off; - s16_t m; - u32_t right_wnd_edge; - u16_t new_tot_len; - int found_dupack = 0; -#if TCP_OOSEQ_MAX_BYTES || TCP_OOSEQ_MAX_PBUFS - u32_t ooseq_blen; - u16_t ooseq_qlen; -#endif /* TCP_OOSEQ_MAX_BYTES || TCP_OOSEQ_MAX_PBUFS */ - - LWIP_ASSERT("tcp_receive: wrong state", pcb->state >= ESTABLISHED); - - if (flags & TCP_ACK) { - right_wnd_edge = pcb->snd_wnd + pcb->snd_wl2; - - /* Update window. */ - if (TCP_SEQ_LT(pcb->snd_wl1, seqno) || - (pcb->snd_wl1 == seqno && TCP_SEQ_LT(pcb->snd_wl2, ackno)) || - (pcb->snd_wl2 == ackno && (u32_t)SND_WND_SCALE(pcb, tcphdr->wnd) > pcb->snd_wnd)) { - pcb->snd_wnd = SND_WND_SCALE(pcb, tcphdr->wnd); - /* keep track of the biggest window announced by the remote host to calculate - the maximum segment size */ - if (pcb->snd_wnd_max < pcb->snd_wnd) { - pcb->snd_wnd_max = pcb->snd_wnd; - } - pcb->snd_wl1 = seqno; - pcb->snd_wl2 = ackno; - if (pcb->snd_wnd == 0) { - if (pcb->persist_backoff == 0) { - /* start persist timer */ - pcb->persist_cnt = 0; - pcb->persist_backoff = 1; - } - } else if (pcb->persist_backoff > 0) { - /* stop persist timer */ - pcb->persist_backoff = 0; - } - LWIP_DEBUGF(TCP_WND_DEBUG, ("tcp_receive: window update %"TCPWNDSIZE_F"\n", pcb->snd_wnd)); -#if TCP_WND_DEBUG - } else { - if (pcb->snd_wnd != (tcpwnd_size_t)SND_WND_SCALE(pcb, tcphdr->wnd)) { - LWIP_DEBUGF(TCP_WND_DEBUG, - ("tcp_receive: no window update lastack %"U32_F" ackno %" - U32_F" wl1 %"U32_F" seqno %"U32_F" wl2 %"U32_F"\n", - pcb->lastack, ackno, pcb->snd_wl1, seqno, pcb->snd_wl2)); - } -#endif /* TCP_WND_DEBUG */ - } - - /* (From Stevens TCP/IP Illustrated Vol II, p970.) Its only a - * duplicate ack if: - * 1) It doesn't ACK new data - * 2) length of received packet is zero (i.e. no payload) - * 3) the advertised window hasn't changed - * 4) There is outstanding unacknowledged data (retransmission timer running) - * 5) The ACK is == biggest ACK sequence number so far seen (snd_una) - * - * If it passes all five, should process as a dupack: - * a) dupacks < 3: do nothing - * b) dupacks == 3: fast retransmit - * c) dupacks > 3: increase cwnd - * - * If it only passes 1-3, should reset dupack counter (and add to - * stats, which we don't do in lwIP) - * - * If it only passes 1, should reset dupack counter - * - */ - - /* Clause 1 */ - if (TCP_SEQ_LEQ(ackno, pcb->lastack)) { - /* Clause 2 */ - if (tcplen == 0) { - /* Clause 3 */ - if (pcb->snd_wl2 + pcb->snd_wnd == right_wnd_edge) { - /* Clause 4 */ - if (pcb->rtime >= 0) { - /* Clause 5 */ - if (pcb->lastack == ackno) { - found_dupack = 1; - if ((u8_t)(pcb->dupacks + 1) > pcb->dupacks) { - ++pcb->dupacks; - } - if (pcb->dupacks > 3) { - /* Inflate the congestion window, but not if it means that - the value overflows. */ - if ((tcpwnd_size_t)(pcb->cwnd + pcb->mss) > pcb->cwnd) { - pcb->cwnd += pcb->mss; - } - } else if (pcb->dupacks == 3) { - /* Do fast retransmit */ - tcp_rexmit_fast(pcb); - } - } - } - } - } - /* If Clause (1) or more is true, but not a duplicate ack, reset - * count of consecutive duplicate acks */ - if (!found_dupack) { - pcb->dupacks = 0; - } - } else if (TCP_SEQ_BETWEEN(ackno, pcb->lastack+1, pcb->snd_nxt)) { - /* We come here when the ACK acknowledges new data. */ - - /* Reset the "IN Fast Retransmit" flag, since we are no longer - in fast retransmit. Also reset the congestion window to the - slow start threshold. */ - if (pcb->flags & TF_INFR) { - pcb->flags &= ~TF_INFR; - pcb->cwnd = pcb->ssthresh; - } - - /* Reset the number of retransmissions. */ - pcb->nrtx = 0; - - /* Reset the retransmission time-out. */ - pcb->rto = (pcb->sa >> 3) + pcb->sv; - - /* Reset the fast retransmit variables. */ - pcb->dupacks = 0; - pcb->lastack = ackno; - - /* Update the congestion control variables (cwnd and - ssthresh). */ - if (pcb->state >= ESTABLISHED) { - if (pcb->cwnd < pcb->ssthresh) { - if ((tcpwnd_size_t)(pcb->cwnd + pcb->mss) > pcb->cwnd) { - pcb->cwnd += pcb->mss; - } - LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: slow start cwnd %"TCPWNDSIZE_F"\n", pcb->cwnd)); - } else { - tcpwnd_size_t new_cwnd = (pcb->cwnd + pcb->mss * pcb->mss / pcb->cwnd); - if (new_cwnd > pcb->cwnd) { - pcb->cwnd = new_cwnd; - } - LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_receive: congestion avoidance cwnd %"TCPWNDSIZE_F"\n", pcb->cwnd)); - } - } - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: ACK for %"U32_F", unacked->seqno %"U32_F":%"U32_F"\n", - ackno, - pcb->unacked != NULL? - lwip_ntohl(pcb->unacked->tcphdr->seqno): 0, - pcb->unacked != NULL? - lwip_ntohl(pcb->unacked->tcphdr->seqno) + TCP_TCPLEN(pcb->unacked): 0)); - - /* Remove segment from the unacknowledged list if the incoming - ACK acknowledges them. */ - while (pcb->unacked != NULL && - TCP_SEQ_LEQ(lwip_ntohl(pcb->unacked->tcphdr->seqno) + - TCP_TCPLEN(pcb->unacked), ackno)) { - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: removing %"U32_F":%"U32_F" from pcb->unacked\n", - lwip_ntohl(pcb->unacked->tcphdr->seqno), - lwip_ntohl(pcb->unacked->tcphdr->seqno) + - TCP_TCPLEN(pcb->unacked))); - - next = pcb->unacked; - pcb->unacked = pcb->unacked->next; - - LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %"TCPWNDSIZE_F" ... ", (tcpwnd_size_t)pcb->snd_queuelen)); - LWIP_ASSERT("pcb->snd_queuelen >= pbuf_clen(next->p)", (pcb->snd_queuelen >= pbuf_clen(next->p))); - - pcb->snd_queuelen -= pbuf_clen(next->p); - recv_acked += next->len; - tcp_seg_free(next); - - LWIP_DEBUGF(TCP_QLEN_DEBUG, ("%"TCPWNDSIZE_F" (after freeing unacked)\n", (tcpwnd_size_t)pcb->snd_queuelen)); - if (pcb->snd_queuelen != 0) { - LWIP_ASSERT("tcp_receive: valid queue length", pcb->unacked != NULL || - pcb->unsent != NULL); - } - } - - /* If there's nothing left to acknowledge, stop the retransmit - timer, otherwise reset it to start again */ - if (pcb->unacked == NULL) { - pcb->rtime = -1; - } else { - pcb->rtime = 0; - } - - pcb->polltmr = 0; - -#if LWIP_IPV6 && LWIP_ND6_TCP_REACHABILITY_HINTS - if (ip_current_is_v6()) { - /* Inform neighbor reachability of forward progress. */ - nd6_reachability_hint(ip6_current_src_addr()); - } -#endif /* LWIP_IPV6 && LWIP_ND6_TCP_REACHABILITY_HINTS*/ - } else { - /* Out of sequence ACK, didn't really ack anything */ - tcp_send_empty_ack(pcb); - } - - /* We go through the ->unsent list to see if any of the segments - on the list are acknowledged by the ACK. This may seem - strange since an "unsent" segment shouldn't be acked. The - rationale is that lwIP puts all outstanding segments on the - ->unsent list after a retransmission, so these segments may - in fact have been sent once. */ - while (pcb->unsent != NULL && - TCP_SEQ_BETWEEN(ackno, lwip_ntohl(pcb->unsent->tcphdr->seqno) + - TCP_TCPLEN(pcb->unsent), pcb->snd_nxt)) { - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: removing %"U32_F":%"U32_F" from pcb->unsent\n", - lwip_ntohl(pcb->unsent->tcphdr->seqno), lwip_ntohl(pcb->unsent->tcphdr->seqno) + - TCP_TCPLEN(pcb->unsent))); - - next = pcb->unsent; - pcb->unsent = pcb->unsent->next; -#if TCP_OVERSIZE - if (pcb->unsent == NULL) { - pcb->unsent_oversize = 0; - } -#endif /* TCP_OVERSIZE */ - LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_receive: queuelen %"TCPWNDSIZE_F" ... ", (tcpwnd_size_t)pcb->snd_queuelen)); - LWIP_ASSERT("pcb->snd_queuelen >= pbuf_clen(next->p)", (pcb->snd_queuelen >= pbuf_clen(next->p))); - /* Prevent ACK for FIN to generate a sent event */ - pcb->snd_queuelen -= pbuf_clen(next->p); - recv_acked += next->len; - tcp_seg_free(next); - LWIP_DEBUGF(TCP_QLEN_DEBUG, ("%"TCPWNDSIZE_F" (after freeing unsent)\n", (tcpwnd_size_t)pcb->snd_queuelen)); - if (pcb->snd_queuelen != 0) { - LWIP_ASSERT("tcp_receive: valid queue length", - pcb->unacked != NULL || pcb->unsent != NULL); - } - } - pcb->snd_buf += recv_acked; - /* End of ACK for new data processing. */ - - LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: pcb->rttest %"U32_F" rtseq %"U32_F" ackno %"U32_F"\n", - pcb->rttest, pcb->rtseq, ackno)); - - /* RTT estimation calculations. This is done by checking if the - incoming segment acknowledges the segment we use to take a - round-trip time measurement. */ - if (pcb->rttest && TCP_SEQ_LT(pcb->rtseq, ackno)) { - /* diff between this shouldn't exceed 32K since this are tcp timer ticks - and a round-trip shouldn't be that long... */ - m = (s16_t)(tcp_ticks - pcb->rttest); - - LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: experienced rtt %"U16_F" ticks (%"U16_F" msec).\n", - m, (u16_t)(m * TCP_SLOW_INTERVAL))); - - /* This is taken directly from VJs original code in his paper */ - m = m - (pcb->sa >> 3); - pcb->sa += m; - if (m < 0) { - m = -m; - } - m = m - (pcb->sv >> 2); - pcb->sv += m; - pcb->rto = (pcb->sa >> 3) + pcb->sv; - - LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_receive: RTO %"U16_F" (%"U16_F" milliseconds)\n", - pcb->rto, (u16_t)(pcb->rto * TCP_SLOW_INTERVAL))); - - pcb->rttest = 0; - } - } - - /* If the incoming segment contains data, we must process it - further unless the pcb already received a FIN. - (RFC 793, chapter 3.9, "SEGMENT ARRIVES" in states CLOSE-WAIT, CLOSING, - LAST-ACK and TIME-WAIT: "Ignore the segment text.") */ - if ((tcplen > 0) && (pcb->state < CLOSE_WAIT)) { - /* This code basically does three things: - - +) If the incoming segment contains data that is the next - in-sequence data, this data is passed to the application. This - might involve trimming the first edge of the data. The rcv_nxt - variable and the advertised window are adjusted. - - +) If the incoming segment has data that is above the next - sequence number expected (->rcv_nxt), the segment is placed on - the ->ooseq queue. This is done by finding the appropriate - place in the ->ooseq queue (which is ordered by sequence - number) and trim the segment in both ends if needed. An - immediate ACK is sent to indicate that we received an - out-of-sequence segment. - - +) Finally, we check if the first segment on the ->ooseq queue - now is in sequence (i.e., if rcv_nxt >= ooseq->seqno). If - rcv_nxt > ooseq->seqno, we must trim the first edge of the - segment on ->ooseq before we adjust rcv_nxt. The data in the - segments that are now on sequence are chained onto the - incoming segment so that we only need to call the application - once. - */ - - /* First, we check if we must trim the first edge. We have to do - this if the sequence number of the incoming segment is less - than rcv_nxt, and the sequence number plus the length of the - segment is larger than rcv_nxt. */ - /* if (TCP_SEQ_LT(seqno, pcb->rcv_nxt)) { - if (TCP_SEQ_LT(pcb->rcv_nxt, seqno + tcplen)) {*/ - if (TCP_SEQ_BETWEEN(pcb->rcv_nxt, seqno + 1, seqno + tcplen - 1)) { - /* Trimming the first edge is done by pushing the payload - pointer in the pbuf downwards. This is somewhat tricky since - we do not want to discard the full contents of the pbuf up to - the new starting point of the data since we have to keep the - TCP header which is present in the first pbuf in the chain. - - What is done is really quite a nasty hack: the first pbuf in - the pbuf chain is pointed to by inseg.p. Since we need to be - able to deallocate the whole pbuf, we cannot change this - inseg.p pointer to point to any of the later pbufs in the - chain. Instead, we point the ->payload pointer in the first - pbuf to data in one of the later pbufs. We also set the - inseg.data pointer to point to the right place. This way, the - ->p pointer will still point to the first pbuf, but the - ->p->payload pointer will point to data in another pbuf. - - After we are done with adjusting the pbuf pointers we must - adjust the ->data pointer in the seg and the segment - length.*/ - - struct pbuf *p = inseg.p; - off = pcb->rcv_nxt - seqno; - LWIP_ASSERT("inseg.p != NULL", inseg.p); - LWIP_ASSERT("insane offset!", (off < 0x7fff)); - if (inseg.p->len < off) { - LWIP_ASSERT("pbuf too short!", (((s32_t)inseg.p->tot_len) >= off)); - new_tot_len = (u16_t)(inseg.p->tot_len - off); - while (p->len < off) { - off -= p->len; - /* KJM following line changed (with addition of new_tot_len var) - to fix bug #9076 - inseg.p->tot_len -= p->len; */ - p->tot_len = new_tot_len; - p->len = 0; - p = p->next; - } - if (pbuf_header(p, (s16_t)-off)) { - /* Do we need to cope with this failing? Assert for now */ - LWIP_ASSERT("pbuf_header failed", 0); - } - } else { - if (pbuf_header(inseg.p, (s16_t)-off)) { - /* Do we need to cope with this failing? Assert for now */ - LWIP_ASSERT("pbuf_header failed", 0); - } - } - inseg.len -= (u16_t)(pcb->rcv_nxt - seqno); - inseg.tcphdr->seqno = seqno = pcb->rcv_nxt; - } - else { - if (TCP_SEQ_LT(seqno, pcb->rcv_nxt)) { - /* the whole segment is < rcv_nxt */ - /* must be a duplicate of a packet that has already been correctly handled */ - - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: duplicate seqno %"U32_F"\n", seqno)); - tcp_ack_now(pcb); - } - } - - /* The sequence number must be within the window (above rcv_nxt - and below rcv_nxt + rcv_wnd) in order to be further - processed. */ - if (TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, - pcb->rcv_nxt + pcb->rcv_wnd - 1)) { - if (pcb->rcv_nxt == seqno) { - /* The incoming segment is the next in sequence. We check if - we have to trim the end of the segment and update rcv_nxt - and pass the data to the application. */ - tcplen = TCP_TCPLEN(&inseg); - - if (tcplen > pcb->rcv_wnd) { - LWIP_DEBUGF(TCP_INPUT_DEBUG, - ("tcp_receive: other end overran receive window" - "seqno %"U32_F" len %"U16_F" right edge %"U32_F"\n", - seqno, tcplen, pcb->rcv_nxt + pcb->rcv_wnd)); - if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) { - /* Must remove the FIN from the header as we're trimming - * that byte of sequence-space from the packet */ - TCPH_FLAGS_SET(inseg.tcphdr, TCPH_FLAGS(inseg.tcphdr) & ~(unsigned int)TCP_FIN); - } - /* Adjust length of segment to fit in the window. */ - TCPWND_CHECK16(pcb->rcv_wnd); - inseg.len = (u16_t)pcb->rcv_wnd; - if (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) { - inseg.len -= 1; - } - pbuf_realloc(inseg.p, inseg.len); - tcplen = TCP_TCPLEN(&inseg); - LWIP_ASSERT("tcp_receive: segment not trimmed correctly to rcv_wnd\n", - (seqno + tcplen) == (pcb->rcv_nxt + pcb->rcv_wnd)); - } -#if TCP_QUEUE_OOSEQ - /* Received in-sequence data, adjust ooseq data if: - - FIN has been received or - - inseq overlaps with ooseq */ - if (pcb->ooseq != NULL) { - if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) { - LWIP_DEBUGF(TCP_INPUT_DEBUG, - ("tcp_receive: received in-order FIN, binning ooseq queue\n")); - /* Received in-order FIN means anything that was received - * out of order must now have been received in-order, so - * bin the ooseq queue */ - while (pcb->ooseq != NULL) { - struct tcp_seg *old_ooseq = pcb->ooseq; - pcb->ooseq = pcb->ooseq->next; - tcp_seg_free(old_ooseq); - } - } else { - next = pcb->ooseq; - /* Remove all segments on ooseq that are covered by inseg already. - * FIN is copied from ooseq to inseg if present. */ - while (next && - TCP_SEQ_GEQ(seqno + tcplen, - next->tcphdr->seqno + next->len)) { - /* inseg cannot have FIN here (already processed above) */ - if ((TCPH_FLAGS(next->tcphdr) & TCP_FIN) != 0 && - (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) == 0) { - TCPH_SET_FLAG(inseg.tcphdr, TCP_FIN); - tcplen = TCP_TCPLEN(&inseg); - } - prev = next; - next = next->next; - tcp_seg_free(prev); - } - /* Now trim right side of inseg if it overlaps with the first - * segment on ooseq */ - if (next && - TCP_SEQ_GT(seqno + tcplen, - next->tcphdr->seqno)) { - /* inseg cannot have FIN here (already processed above) */ - inseg.len = (u16_t)(next->tcphdr->seqno - seqno); - if (TCPH_FLAGS(inseg.tcphdr) & TCP_SYN) { - inseg.len -= 1; - } - pbuf_realloc(inseg.p, inseg.len); - tcplen = TCP_TCPLEN(&inseg); - LWIP_ASSERT("tcp_receive: segment not trimmed correctly to ooseq queue\n", - (seqno + tcplen) == next->tcphdr->seqno); - } - pcb->ooseq = next; - } - } -#endif /* TCP_QUEUE_OOSEQ */ - - pcb->rcv_nxt = seqno + tcplen; - - /* Update the receiver's (our) window. */ - LWIP_ASSERT("tcp_receive: tcplen > rcv_wnd\n", pcb->rcv_wnd >= tcplen); - pcb->rcv_wnd -= tcplen; - - tcp_update_rcv_ann_wnd(pcb); - - /* If there is data in the segment, we make preparations to - pass this up to the application. The ->recv_data variable - is used for holding the pbuf that goes to the - application. The code for reassembling out-of-sequence data - chains its data on this pbuf as well. - - If the segment was a FIN, we set the TF_GOT_FIN flag that will - be used to indicate to the application that the remote side has - closed its end of the connection. */ - if (inseg.p->tot_len > 0) { - recv_data = inseg.p; - /* Since this pbuf now is the responsibility of the - application, we delete our reference to it so that we won't - (mistakingly) deallocate it. */ - inseg.p = NULL; - } - if (TCPH_FLAGS(inseg.tcphdr) & TCP_FIN) { - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: received FIN.\n")); - recv_flags |= TF_GOT_FIN; - } - -#if TCP_QUEUE_OOSEQ - /* We now check if we have segments on the ->ooseq queue that - are now in sequence. */ - while (pcb->ooseq != NULL && - pcb->ooseq->tcphdr->seqno == pcb->rcv_nxt) { - - cseg = pcb->ooseq; - seqno = pcb->ooseq->tcphdr->seqno; - - pcb->rcv_nxt += TCP_TCPLEN(cseg); - LWIP_ASSERT("tcp_receive: ooseq tcplen > rcv_wnd\n", - pcb->rcv_wnd >= TCP_TCPLEN(cseg)); - pcb->rcv_wnd -= TCP_TCPLEN(cseg); - - tcp_update_rcv_ann_wnd(pcb); - - if (cseg->p->tot_len > 0) { - /* Chain this pbuf onto the pbuf that we will pass to - the application. */ - /* With window scaling, this can overflow recv_data->tot_len, but - that's not a problem since we explicitly fix that before passing - recv_data to the application. */ - if (recv_data) { - pbuf_cat(recv_data, cseg->p); - } else { - recv_data = cseg->p; - } - cseg->p = NULL; - } - if (TCPH_FLAGS(cseg->tcphdr) & TCP_FIN) { - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_receive: dequeued FIN.\n")); - recv_flags |= TF_GOT_FIN; - if (pcb->state == ESTABLISHED) { /* force passive close or we can move to active close */ - pcb->state = CLOSE_WAIT; - } - } - - pcb->ooseq = cseg->next; - tcp_seg_free(cseg); - } -#endif /* TCP_QUEUE_OOSEQ */ - - - /* Acknowledge the segment(s). */ - tcp_ack(pcb); - -#if LWIP_IPV6 && LWIP_ND6_TCP_REACHABILITY_HINTS - if (ip_current_is_v6()) { - /* Inform neighbor reachability of forward progress. */ - nd6_reachability_hint(ip6_current_src_addr()); - } -#endif /* LWIP_IPV6 && LWIP_ND6_TCP_REACHABILITY_HINTS*/ - - } else { - /* We get here if the incoming segment is out-of-sequence. */ - tcp_send_empty_ack(pcb); -#if TCP_QUEUE_OOSEQ - /* We queue the segment on the ->ooseq queue. */ - if (pcb->ooseq == NULL) { - pcb->ooseq = tcp_seg_copy(&inseg); - } else { - /* If the queue is not empty, we walk through the queue and - try to find a place where the sequence number of the - incoming segment is between the sequence numbers of the - previous and the next segment on the ->ooseq queue. That is - the place where we put the incoming segment. If needed, we - trim the second edges of the previous and the incoming - segment so that it will fit into the sequence. - - If the incoming segment has the same sequence number as a - segment on the ->ooseq queue, we discard the segment that - contains less data. */ - - prev = NULL; - for (next = pcb->ooseq; next != NULL; next = next->next) { - if (seqno == next->tcphdr->seqno) { - /* The sequence number of the incoming segment is the - same as the sequence number of the segment on - ->ooseq. We check the lengths to see which one to - discard. */ - if (inseg.len > next->len) { - /* The incoming segment is larger than the old - segment. We replace some segments with the new - one. */ - cseg = tcp_seg_copy(&inseg); - if (cseg != NULL) { - if (prev != NULL) { - prev->next = cseg; - } else { - pcb->ooseq = cseg; - } - tcp_oos_insert_segment(cseg, next); - } - break; - } else { - /* Either the lengths are the same or the incoming - segment was smaller than the old one; in either - case, we ditch the incoming segment. */ - break; - } - } else { - if (prev == NULL) { - if (TCP_SEQ_LT(seqno, next->tcphdr->seqno)) { - /* The sequence number of the incoming segment is lower - than the sequence number of the first segment on the - queue. We put the incoming segment first on the - queue. */ - cseg = tcp_seg_copy(&inseg); - if (cseg != NULL) { - pcb->ooseq = cseg; - tcp_oos_insert_segment(cseg, next); - } - break; - } - } else { - /*if (TCP_SEQ_LT(prev->tcphdr->seqno, seqno) && - TCP_SEQ_LT(seqno, next->tcphdr->seqno)) {*/ - if (TCP_SEQ_BETWEEN(seqno, prev->tcphdr->seqno+1, next->tcphdr->seqno-1)) { - /* The sequence number of the incoming segment is in - between the sequence numbers of the previous and - the next segment on ->ooseq. We trim trim the previous - segment, delete next segments that included in received segment - and trim received, if needed. */ - cseg = tcp_seg_copy(&inseg); - if (cseg != NULL) { - if (TCP_SEQ_GT(prev->tcphdr->seqno + prev->len, seqno)) { - /* We need to trim the prev segment. */ - prev->len = (u16_t)(seqno - prev->tcphdr->seqno); - pbuf_realloc(prev->p, prev->len); - } - prev->next = cseg; - tcp_oos_insert_segment(cseg, next); - } - break; - } - } - /* If the "next" segment is the last segment on the - ooseq queue, we add the incoming segment to the end - of the list. */ - if (next->next == NULL && - TCP_SEQ_GT(seqno, next->tcphdr->seqno)) { - if (TCPH_FLAGS(next->tcphdr) & TCP_FIN) { - /* segment "next" already contains all data */ - break; - } - next->next = tcp_seg_copy(&inseg); - if (next->next != NULL) { - if (TCP_SEQ_GT(next->tcphdr->seqno + next->len, seqno)) { - /* We need to trim the last segment. */ - next->len = (u16_t)(seqno - next->tcphdr->seqno); - pbuf_realloc(next->p, next->len); - } - /* check if the remote side overruns our receive window */ - if (TCP_SEQ_GT((u32_t)tcplen + seqno, pcb->rcv_nxt + (u32_t)pcb->rcv_wnd)) { - LWIP_DEBUGF(TCP_INPUT_DEBUG, - ("tcp_receive: other end overran receive window" - "seqno %"U32_F" len %"U16_F" right edge %"U32_F"\n", - seqno, tcplen, pcb->rcv_nxt + pcb->rcv_wnd)); - if (TCPH_FLAGS(next->next->tcphdr) & TCP_FIN) { - /* Must remove the FIN from the header as we're trimming - * that byte of sequence-space from the packet */ - TCPH_FLAGS_SET(next->next->tcphdr, TCPH_FLAGS(next->next->tcphdr) & ~TCP_FIN); - } - /* Adjust length of segment to fit in the window. */ - next->next->len = (u16_t)(pcb->rcv_nxt + pcb->rcv_wnd - seqno); - pbuf_realloc(next->next->p, next->next->len); - tcplen = TCP_TCPLEN(next->next); - LWIP_ASSERT("tcp_receive: segment not trimmed correctly to rcv_wnd\n", - (seqno + tcplen) == (pcb->rcv_nxt + pcb->rcv_wnd)); - } - } - break; - } - } - prev = next; - } - } -#if TCP_OOSEQ_MAX_BYTES || TCP_OOSEQ_MAX_PBUFS - /* Check that the data on ooseq doesn't exceed one of the limits - and throw away everything above that limit. */ - ooseq_blen = 0; - ooseq_qlen = 0; - prev = NULL; - for (next = pcb->ooseq; next != NULL; prev = next, next = next->next) { - struct pbuf *p = next->p; - ooseq_blen += p->tot_len; - ooseq_qlen += pbuf_clen(p); - if ((ooseq_blen > TCP_OOSEQ_MAX_BYTES) || - (ooseq_qlen > TCP_OOSEQ_MAX_PBUFS)) { - /* too much ooseq data, dump this and everything after it */ - tcp_segs_free(next); - if (prev == NULL) { - /* first ooseq segment is too much, dump the whole queue */ - pcb->ooseq = NULL; - } else { - /* just dump 'next' and everything after it */ - prev->next = NULL; - } - break; - } - } -#endif /* TCP_OOSEQ_MAX_BYTES || TCP_OOSEQ_MAX_PBUFS */ -#endif /* TCP_QUEUE_OOSEQ */ - } - } else { - /* The incoming segment is not within the window. */ - tcp_send_empty_ack(pcb); - } - } else { - /* Segments with length 0 is taken care of here. Segments that - fall out of the window are ACKed. */ - if (!TCP_SEQ_BETWEEN(seqno, pcb->rcv_nxt, pcb->rcv_nxt + pcb->rcv_wnd - 1)) { - tcp_ack_now(pcb); - } - } -} - -static u8_t -tcp_getoptbyte(void) -{ - if ((tcphdr_opt2 == NULL) || (tcp_optidx < tcphdr_opt1len)) { - u8_t* opts = (u8_t *)tcphdr + TCP_HLEN; - return opts[tcp_optidx++]; - } else { - u8_t idx = (u8_t)(tcp_optidx++ - tcphdr_opt1len); - return tcphdr_opt2[idx]; - } -} - -/** - * Parses the options contained in the incoming segment. - * - * Called from tcp_listen_input() and tcp_process(). - * Currently, only the MSS option is supported! - * - * @param pcb the tcp_pcb for which a segment arrived - */ -static void -tcp_parseopt(struct tcp_pcb *pcb) -{ - u8_t data; - u16_t mss; -#if LWIP_TCP_TIMESTAMPS - u32_t tsval; -#endif - - /* Parse the TCP MSS option, if present. */ - if (tcphdr_optlen != 0) { - for (tcp_optidx = 0; tcp_optidx < tcphdr_optlen; ) { - u8_t opt = tcp_getoptbyte(); - switch (opt) { - case LWIP_TCP_OPT_EOL: - /* End of options. */ - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: EOL\n")); - return; - case LWIP_TCP_OPT_NOP: - /* NOP option. */ - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: NOP\n")); - break; - case LWIP_TCP_OPT_MSS: - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: MSS\n")); - if (tcp_getoptbyte() != LWIP_TCP_OPT_LEN_MSS || (tcp_optidx - 2 + LWIP_TCP_OPT_LEN_MSS) > tcphdr_optlen) { - /* Bad length */ - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n")); - return; - } - /* An MSS option with the right option length. */ - mss = (tcp_getoptbyte() << 8); - mss |= tcp_getoptbyte(); - /* Limit the mss to the configured TCP_MSS and prevent division by zero */ - pcb->mss = ((mss > TCP_MSS) || (mss == 0)) ? TCP_MSS : mss; - break; -#if LWIP_WND_SCALE - case LWIP_TCP_OPT_WS: - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: WND_SCALE\n")); - if (tcp_getoptbyte() != LWIP_TCP_OPT_LEN_WS || (tcp_optidx - 2 + LWIP_TCP_OPT_LEN_WS) > tcphdr_optlen) { - /* Bad length */ - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n")); - return; - } - /* An WND_SCALE option with the right option length. */ - data = tcp_getoptbyte(); - /* If syn was received with wnd scale option, - activate wnd scale opt, but only if this is not a retransmission */ - if ((flags & TCP_SYN) && !(pcb->flags & TF_WND_SCALE)) { - pcb->snd_scale = data; - if (pcb->snd_scale > 14U) { - pcb->snd_scale = 14U; - } - pcb->rcv_scale = TCP_RCV_SCALE; - pcb->flags |= TF_WND_SCALE; - /* window scaling is enabled, we can use the full receive window */ - LWIP_ASSERT("window not at default value", pcb->rcv_wnd == TCPWND_MIN16(TCP_WND)); - LWIP_ASSERT("window not at default value", pcb->rcv_ann_wnd == TCPWND_MIN16(TCP_WND)); - pcb->rcv_wnd = pcb->rcv_ann_wnd = TCP_WND; - } - break; -#endif -#if LWIP_TCP_TIMESTAMPS - case LWIP_TCP_OPT_TS: - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: TS\n")); - if (tcp_getoptbyte() != LWIP_TCP_OPT_LEN_TS || (tcp_optidx - 2 + LWIP_TCP_OPT_LEN_TS) > tcphdr_optlen) { - /* Bad length */ - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n")); - return; - } - /* TCP timestamp option with valid length */ - tsval = tcp_getoptbyte(); - tsval |= (tcp_getoptbyte() << 8); - tsval |= (tcp_getoptbyte() << 16); - tsval |= (tcp_getoptbyte() << 24); - if (flags & TCP_SYN) { - pcb->ts_recent = lwip_ntohl(tsval); - /* Enable sending timestamps in every segment now that we know - the remote host supports it. */ - pcb->flags |= TF_TIMESTAMP; - } else if (TCP_SEQ_BETWEEN(pcb->ts_lastacksent, seqno, seqno+tcplen)) { - pcb->ts_recent = lwip_ntohl(tsval); - } - /* Advance to next option (6 bytes already read) */ - tcp_optidx += LWIP_TCP_OPT_LEN_TS - 6; - break; -#endif - default: - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: other\n")); - data = tcp_getoptbyte(); - if (data < 2) { - LWIP_DEBUGF(TCP_INPUT_DEBUG, ("tcp_parseopt: bad length\n")); - /* If the length field is zero, the options are malformed - and we don't process them further. */ - return; - } - /* All other options have a length field, so that we easily - can skip past them. */ - tcp_optidx += data - 2; - } - } - } -} - -void -tcp_trigger_input_pcb_close(void) -{ - recv_flags |= TF_CLOSED; -} - -#endif /* LWIP_TCP */ diff --git a/third_party/lwip/repo/lwip/src/core/tcp_out.c b/third_party/lwip/repo/lwip/src/core/tcp_out.c deleted file mode 100644 index 6e0331c9eb0fb5..00000000000000 --- a/third_party/lwip/repo/lwip/src/core/tcp_out.c +++ /dev/null @@ -1,1685 +0,0 @@ -/** - * @file - * Transmission Control Protocol, outgoing traffic - * - * The output functions of TCP. - * - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ - -#include "lwip/opt.h" - -#if LWIP_TCP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/priv/tcp_priv.h" -#include "lwip/def.h" -#include "lwip/mem.h" -#include "lwip/memp.h" -#include "lwip/ip_addr.h" -#include "lwip/netif.h" -#include "lwip/inet_chksum.h" -#include "lwip/stats.h" -#include "lwip/ip6.h" -#include "lwip/ip6_addr.h" -#if LWIP_TCP_TIMESTAMPS -#include "lwip/sys.h" -#endif - -#include - -/* Define some copy-macros for checksum-on-copy so that the code looks - nicer by preventing too many ifdef's. */ -#if TCP_CHECKSUM_ON_COPY -#define TCP_DATA_COPY(dst, src, len, seg) do { \ - tcp_seg_add_chksum(LWIP_CHKSUM_COPY(dst, src, len), \ - len, &seg->chksum, &seg->chksum_swapped); \ - seg->flags |= TF_SEG_DATA_CHECKSUMMED; } while(0) -#define TCP_DATA_COPY2(dst, src, len, chksum, chksum_swapped) \ - tcp_seg_add_chksum(LWIP_CHKSUM_COPY(dst, src, len), len, chksum, chksum_swapped); -#else /* TCP_CHECKSUM_ON_COPY*/ -#define TCP_DATA_COPY(dst, src, len, seg) MEMCPY(dst, src, len) -#define TCP_DATA_COPY2(dst, src, len, chksum, chksum_swapped) MEMCPY(dst, src, len) -#endif /* TCP_CHECKSUM_ON_COPY*/ - -/** Define this to 1 for an extra check that the output checksum is valid - * (usefule when the checksum is generated by the application, not the stack) */ -#ifndef TCP_CHECKSUM_ON_COPY_SANITY_CHECK -#define TCP_CHECKSUM_ON_COPY_SANITY_CHECK 0 -#endif -/* Allow to override the failure of sanity check from warning to e.g. hard failure */ -#if TCP_CHECKSUM_ON_COPY_SANITY_CHECK -#ifndef TCP_CHECKSUM_ON_COPY_SANITY_CHECK_FAIL -#define TCP_CHECKSUM_ON_COPY_SANITY_CHECK_FAIL(msg) LWIP_DEBUGF(TCP_DEBUG | LWIP_DBG_LEVEL_WARNING, msg) -#endif -#endif - -#if TCP_OVERSIZE -/** The size of segment pbufs created when TCP_OVERSIZE is enabled */ -#ifndef TCP_OVERSIZE_CALC_LENGTH -#define TCP_OVERSIZE_CALC_LENGTH(length) ((length) + TCP_OVERSIZE) -#endif -#endif - -/* Forward declarations.*/ -static err_t tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb, struct netif *netif); - -/** Allocate a pbuf and create a tcphdr at p->payload, used for output - * functions other than the default tcp_output -> tcp_output_segment - * (e.g. tcp_send_empty_ack, etc.) - * - * @param pcb tcp pcb for which to send a packet (used to initialize tcp_hdr) - * @param optlen length of header-options - * @param datalen length of tcp data to reserve in pbuf - * @param seqno_be seqno in network byte order (big-endian) - * @return pbuf with p->payload being the tcp_hdr - */ -static struct pbuf * -tcp_output_alloc_header(struct tcp_pcb *pcb, u16_t optlen, u16_t datalen, - u32_t seqno_be /* already in network byte order */) -{ - struct tcp_hdr *tcphdr; - struct pbuf *p = pbuf_alloc(PBUF_IP, TCP_HLEN + optlen + datalen, PBUF_RAM); - if (p != NULL) { - LWIP_ASSERT("check that first pbuf can hold struct tcp_hdr", - (p->len >= TCP_HLEN + optlen)); - tcphdr = (struct tcp_hdr *)p->payload; - tcphdr->src = lwip_htons(pcb->local_port); - tcphdr->dest = lwip_htons(pcb->remote_port); - tcphdr->seqno = seqno_be; - tcphdr->ackno = lwip_htonl(pcb->rcv_nxt); - TCPH_HDRLEN_FLAGS_SET(tcphdr, (5 + optlen / 4), TCP_ACK); - tcphdr->wnd = lwip_htons(TCPWND_MIN16(RCV_WND_SCALE(pcb, pcb->rcv_ann_wnd))); - tcphdr->chksum = 0; - tcphdr->urgp = 0; - - /* If we're sending a packet, update the announced right window edge */ - pcb->rcv_ann_right_edge = pcb->rcv_nxt + pcb->rcv_ann_wnd; - } - return p; -} - -/** - * Called by tcp_close() to send a segment including FIN flag but not data. - * - * @param pcb the tcp_pcb over which to send a segment - * @return ERR_OK if sent, another err_t otherwise - */ -err_t -tcp_send_fin(struct tcp_pcb *pcb) -{ - /* first, try to add the fin to the last unsent segment */ - if (pcb->unsent != NULL) { - struct tcp_seg *last_unsent; - for (last_unsent = pcb->unsent; last_unsent->next != NULL; - last_unsent = last_unsent->next); - - if ((TCPH_FLAGS(last_unsent->tcphdr) & (TCP_SYN | TCP_FIN | TCP_RST)) == 0) { - /* no SYN/FIN/RST flag in the header, we can add the FIN flag */ - TCPH_SET_FLAG(last_unsent->tcphdr, TCP_FIN); - pcb->flags |= TF_FIN; - return ERR_OK; - } - } - /* no data, no length, flags, copy=1, no optdata */ - return tcp_enqueue_flags(pcb, TCP_FIN); -} - -/** - * Create a TCP segment with prefilled header. - * - * Called by tcp_write and tcp_enqueue_flags. - * - * @param pcb Protocol control block for the TCP connection. - * @param p pbuf that is used to hold the TCP header. - * @param flags TCP flags for header. - * @param seqno TCP sequence number of this packet - * @param optflags options to include in TCP header - * @return a new tcp_seg pointing to p, or NULL. - * The TCP header is filled in except ackno and wnd. - * p is freed on failure. - */ -static struct tcp_seg * -tcp_create_segment(struct tcp_pcb *pcb, struct pbuf *p, u8_t flags, u32_t seqno, u8_t optflags) -{ - struct tcp_seg *seg; - u8_t optlen = LWIP_TCP_OPT_LENGTH(optflags); - - if ((seg = (struct tcp_seg *)memp_malloc(MEMP_TCP_SEG)) == NULL) { - LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("tcp_create_segment: no memory.\n")); - pbuf_free(p); - return NULL; - } - seg->flags = optflags; - seg->next = NULL; - seg->p = p; - LWIP_ASSERT("p->tot_len >= optlen", p->tot_len >= optlen); - seg->len = p->tot_len - optlen; -#if TCP_OVERSIZE_DBGCHECK - seg->oversize_left = 0; -#endif /* TCP_OVERSIZE_DBGCHECK */ -#if TCP_CHECKSUM_ON_COPY - seg->chksum = 0; - seg->chksum_swapped = 0; - /* check optflags */ - LWIP_ASSERT("invalid optflags passed: TF_SEG_DATA_CHECKSUMMED", - (optflags & TF_SEG_DATA_CHECKSUMMED) == 0); -#endif /* TCP_CHECKSUM_ON_COPY */ - - /* build TCP header */ - if (pbuf_header(p, TCP_HLEN)) { - LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("tcp_create_segment: no room for TCP header in pbuf.\n")); - TCP_STATS_INC(tcp.err); - tcp_seg_free(seg); - return NULL; - } - seg->tcphdr = (struct tcp_hdr *)seg->p->payload; - seg->tcphdr->src = lwip_htons(pcb->local_port); - seg->tcphdr->dest = lwip_htons(pcb->remote_port); - seg->tcphdr->seqno = lwip_htonl(seqno); - /* ackno is set in tcp_output */ - TCPH_HDRLEN_FLAGS_SET(seg->tcphdr, (5 + optlen / 4), flags); - /* wnd and chksum are set in tcp_output */ - seg->tcphdr->urgp = 0; - return seg; -} - -/** - * Allocate a PBUF_RAM pbuf, perhaps with extra space at the end. - * - * This function is like pbuf_alloc(layer, length, PBUF_RAM) except - * there may be extra bytes available at the end. - * - * @param layer flag to define header size. - * @param length size of the pbuf's payload. - * @param max_length maximum usable size of payload+oversize. - * @param oversize pointer to a u16_t that will receive the number of usable tail bytes. - * @param pcb The TCP connection that will enqueue the pbuf. - * @param apiflags API flags given to tcp_write. - * @param first_seg true when this pbuf will be used in the first enqueued segment. - */ -#if TCP_OVERSIZE -static struct pbuf * -tcp_pbuf_prealloc(pbuf_layer layer, u16_t length, u16_t max_length, - u16_t *oversize, struct tcp_pcb *pcb, u8_t apiflags, - u8_t first_seg) -{ - struct pbuf *p; - u16_t alloc = length; - -#if LWIP_NETIF_TX_SINGLE_PBUF - LWIP_UNUSED_ARG(max_length); - LWIP_UNUSED_ARG(pcb); - LWIP_UNUSED_ARG(apiflags); - LWIP_UNUSED_ARG(first_seg); - alloc = max_length; -#else /* LWIP_NETIF_TX_SINGLE_PBUF */ - if (length < max_length) { - /* Should we allocate an oversized pbuf, or just the minimum - * length required? If tcp_write is going to be called again - * before this segment is transmitted, we want the oversized - * buffer. If the segment will be transmitted immediately, we can - * save memory by allocating only length. We use a simple - * heuristic based on the following information: - * - * Did the user set TCP_WRITE_FLAG_MORE? - * - * Will the Nagle algorithm defer transmission of this segment? - */ - if ((apiflags & TCP_WRITE_FLAG_MORE) || - (!(pcb->flags & TF_NODELAY) && - (!first_seg || - pcb->unsent != NULL || - pcb->unacked != NULL))) { - alloc = LWIP_MIN(max_length, LWIP_MEM_ALIGN_SIZE(TCP_OVERSIZE_CALC_LENGTH(length))); - } - } -#endif /* LWIP_NETIF_TX_SINGLE_PBUF */ - p = pbuf_alloc(layer, alloc, PBUF_RAM); - if (p == NULL) { - return NULL; - } - LWIP_ASSERT("need unchained pbuf", p->next == NULL); - *oversize = p->len - length; - /* trim p->len to the currently used size */ - p->len = p->tot_len = length; - return p; -} -#else /* TCP_OVERSIZE */ -#define tcp_pbuf_prealloc(layer, length, mx, os, pcb, api, fst) pbuf_alloc((layer), (length), PBUF_RAM) -#endif /* TCP_OVERSIZE */ - -#if TCP_CHECKSUM_ON_COPY -/** Add a checksum of newly added data to the segment */ -static void -tcp_seg_add_chksum(u16_t chksum, u16_t len, u16_t *seg_chksum, - u8_t *seg_chksum_swapped) -{ - u32_t helper; - /* add chksum to old chksum and fold to u16_t */ - helper = chksum + *seg_chksum; - chksum = FOLD_U32T(helper); - if ((len & 1) != 0) { - *seg_chksum_swapped = 1 - *seg_chksum_swapped; - chksum = SWAP_BYTES_IN_WORD(chksum); - } - *seg_chksum = chksum; -} -#endif /* TCP_CHECKSUM_ON_COPY */ - -/** Checks if tcp_write is allowed or not (checks state, snd_buf and snd_queuelen). - * - * @param pcb the tcp pcb to check for - * @param len length of data to send (checked agains snd_buf) - * @return ERR_OK if tcp_write is allowed to proceed, another err_t otherwise - */ -static err_t -tcp_write_checks(struct tcp_pcb *pcb, u16_t len) -{ - /* connection is in invalid state for data transmission? */ - if ((pcb->state != ESTABLISHED) && - (pcb->state != CLOSE_WAIT) && - (pcb->state != SYN_SENT) && - (pcb->state != SYN_RCVD)) { - LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_STATE | LWIP_DBG_LEVEL_SEVERE, ("tcp_write() called in invalid state\n")); - return ERR_CONN; - } else if (len == 0) { - return ERR_OK; - } - - /* fail on too much data */ - if (len > pcb->snd_buf) { - LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SEVERE, ("tcp_write: too much data (len=%"U16_F" > snd_buf=%"TCPWNDSIZE_F")\n", - len, pcb->snd_buf)); - pcb->flags |= TF_NAGLEMEMERR; - return ERR_MEM; - } - - LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_write: queuelen: %"TCPWNDSIZE_F"\n", (tcpwnd_size_t)pcb->snd_queuelen)); - - /* If total number of pbufs on the unsent/unacked queues exceeds the - * configured maximum, return an error */ - /* check for configured max queuelen and possible overflow */ - if ((pcb->snd_queuelen >= TCP_SND_QUEUELEN) || (pcb->snd_queuelen > TCP_SNDQUEUELEN_OVERFLOW)) { - LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SEVERE, ("tcp_write: too long queue %"U16_F" (max %"U16_F")\n", - pcb->snd_queuelen, (u16_t)TCP_SND_QUEUELEN)); - TCP_STATS_INC(tcp.memerr); - pcb->flags |= TF_NAGLEMEMERR; - return ERR_MEM; - } - if (pcb->snd_queuelen != 0) { - LWIP_ASSERT("tcp_write: pbufs on queue => at least one queue non-empty", - pcb->unacked != NULL || pcb->unsent != NULL); - } else { - LWIP_ASSERT("tcp_write: no pbufs on queue => both queues empty", - pcb->unacked == NULL && pcb->unsent == NULL); - } - return ERR_OK; -} - -/** - * @ingroup tcp_raw - * Write data for sending (but does not send it immediately). - * - * It waits in the expectation of more data being sent soon (as - * it can send them more efficiently by combining them together). - * To prompt the system to send data now, call tcp_output() after - * calling tcp_write(). - * - * @param pcb Protocol control block for the TCP connection to enqueue data for. - * @param arg Pointer to the data to be enqueued for sending. - * @param len Data length in bytes - * @param apiflags combination of following flags : - * - TCP_WRITE_FLAG_COPY (0x01) data will be copied into memory belonging to the stack - * - TCP_WRITE_FLAG_MORE (0x02) for TCP connection, PSH flag will not be set on last segment sent, - * @return ERR_OK if enqueued, another err_t on error - */ -err_t -tcp_write(struct tcp_pcb *pcb, const void *arg, u16_t len, u8_t apiflags) -{ - struct pbuf *concat_p = NULL; - struct tcp_seg *last_unsent = NULL, *seg = NULL, *prev_seg = NULL, *queue = NULL; - u16_t pos = 0; /* position in 'arg' data */ - u16_t queuelen; - u8_t optlen = 0; - u8_t optflags = 0; -#if TCP_OVERSIZE - u16_t oversize = 0; - u16_t oversize_used = 0; -#if TCP_OVERSIZE_DBGCHECK - u16_t oversize_add = 0; -#endif /* TCP_OVERSIZE_DBGCHECK*/ -#endif /* TCP_OVERSIZE */ - u16_t extendlen = 0; -#if TCP_CHECKSUM_ON_COPY - u16_t concat_chksum = 0; - u8_t concat_chksum_swapped = 0; - u16_t concat_chksummed = 0; -#endif /* TCP_CHECKSUM_ON_COPY */ - err_t err; - /* don't allocate segments bigger than half the maximum window we ever received */ - u16_t mss_local = LWIP_MIN(pcb->mss, TCPWND_MIN16(pcb->snd_wnd_max/2)); - mss_local = mss_local ? mss_local : pcb->mss; - - LWIP_ASSERT_CORE_LOCKED(); - -#if LWIP_NETIF_TX_SINGLE_PBUF - /* Always copy to try to create single pbufs for TX */ - apiflags |= TCP_WRITE_FLAG_COPY; -#endif /* LWIP_NETIF_TX_SINGLE_PBUF */ - - LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_write(pcb=%p, data=%p, len=%"U16_F", apiflags=%"U16_F")\n", - (void *)pcb, arg, len, (u16_t)apiflags)); - LWIP_ERROR("tcp_write: arg == NULL (programmer violates API)", - arg != NULL, return ERR_ARG;); - - err = tcp_write_checks(pcb, len); - if (err != ERR_OK) { - return err; - } - queuelen = pcb->snd_queuelen; - -#if LWIP_TCP_TIMESTAMPS - if ((pcb->flags & TF_TIMESTAMP)) { - /* Make sure the timestamp option is only included in data segments if we - agreed about it with the remote host. */ - optflags = TF_SEG_OPTS_TS; - optlen = LWIP_TCP_OPT_LENGTH(TF_SEG_OPTS_TS); - /* ensure that segments can hold at least one data byte... */ - mss_local = LWIP_MAX(mss_local, LWIP_TCP_OPT_LEN_TS + 1); - } -#endif /* LWIP_TCP_TIMESTAMPS */ - - - /* - * TCP segmentation is done in three phases with increasing complexity: - * - * 1. Copy data directly into an oversized pbuf. - * 2. Chain a new pbuf to the end of pcb->unsent. - * 3. Create new segments. - * - * We may run out of memory at any point. In that case we must - * return ERR_MEM and not change anything in pcb. Therefore, all - * changes are recorded in local variables and committed at the end - * of the function. Some pcb fields are maintained in local copies: - * - * queuelen = pcb->snd_queuelen - * oversize = pcb->unsent_oversize - * - * These variables are set consistently by the phases: - * - * seg points to the last segment tampered with. - * - * pos records progress as data is segmented. - */ - - /* Find the tail of the unsent queue. */ - if (pcb->unsent != NULL) { - u16_t space; - u16_t unsent_optlen; - - /* @todo: this could be sped up by keeping last_unsent in the pcb */ - for (last_unsent = pcb->unsent; last_unsent->next != NULL; - last_unsent = last_unsent->next); - - /* Usable space at the end of the last unsent segment */ - unsent_optlen = LWIP_TCP_OPT_LENGTH(last_unsent->flags); - LWIP_ASSERT("mss_local is too small", mss_local >= last_unsent->len + unsent_optlen); - space = mss_local - (last_unsent->len + unsent_optlen); - - /* - * Phase 1: Copy data directly into an oversized pbuf. - * - * The number of bytes copied is recorded in the oversize_used - * variable. The actual copying is done at the bottom of the - * function. - */ -#if TCP_OVERSIZE -#if TCP_OVERSIZE_DBGCHECK - /* check that pcb->unsent_oversize matches last_unsent->oversize_left */ - LWIP_ASSERT("unsent_oversize mismatch (pcb vs. last_unsent)", - pcb->unsent_oversize == last_unsent->oversize_left); -#endif /* TCP_OVERSIZE_DBGCHECK */ - oversize = pcb->unsent_oversize; - if (oversize > 0) { - LWIP_ASSERT("inconsistent oversize vs. space", oversize <= space); - seg = last_unsent; - oversize_used = LWIP_MIN(space, LWIP_MIN(oversize, len)); - pos += oversize_used; - oversize -= oversize_used; - space -= oversize_used; - } - /* now we are either finished or oversize is zero */ - LWIP_ASSERT("inconsistent oversize vs. len", (oversize == 0) || (pos == len)); -#endif /* TCP_OVERSIZE */ - - /* - * Phase 2: Chain a new pbuf to the end of pcb->unsent. - * - * As an exception when NOT copying the data, if the given data buffer - * directly follows the last unsent data buffer in memory, extend the last - * ROM pbuf reference to the buffer, thus saving a ROM pbuf allocation. - * - * We don't extend segments containing SYN/FIN flags or options - * (len==0). The new pbuf is kept in concat_p and pbuf_cat'ed at - * the end. - */ - if ((pos < len) && (space > 0) && (last_unsent->len > 0)) { - u16_t seglen = LWIP_MIN(space, len - pos); - seg = last_unsent; - - /* Create a pbuf with a copy or reference to seglen bytes. We - * can use PBUF_RAW here since the data appears in the middle of - * a segment. A header will never be prepended. */ - if (apiflags & TCP_WRITE_FLAG_COPY) { - /* Data is copied */ - if ((concat_p = tcp_pbuf_prealloc(PBUF_RAW, seglen, space, &oversize, pcb, apiflags, 1)) == NULL) { - LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS, - ("tcp_write : could not allocate memory for pbuf copy size %"U16_F"\n", - seglen)); - goto memerr; - } -#if TCP_OVERSIZE_DBGCHECK - oversize_add = oversize; -#endif /* TCP_OVERSIZE_DBGCHECK */ - TCP_DATA_COPY2(concat_p->payload, (const u8_t*)arg + pos, seglen, &concat_chksum, &concat_chksum_swapped); -#if TCP_CHECKSUM_ON_COPY - concat_chksummed += seglen; -#endif /* TCP_CHECKSUM_ON_COPY */ - queuelen += pbuf_clen(concat_p); - } else { - /* Data is not copied */ - /* If the last unsent pbuf is of type PBUF_ROM, try to extend it. */ - struct pbuf *p; - for (p = last_unsent->p; p->next != NULL; p = p->next); - if (p->type == PBUF_ROM && (const u8_t *)p->payload + p->len == (const u8_t *)arg) { - LWIP_ASSERT("tcp_write: ROM pbufs cannot be oversized", pos == 0); - extendlen = seglen; - } else { - if ((concat_p = pbuf_alloc(PBUF_RAW, seglen, PBUF_ROM)) == NULL) { - LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS, - ("tcp_write: could not allocate memory for zero-copy pbuf\n")); - goto memerr; - } - /* reference the non-volatile payload data */ - ((struct pbuf_rom*)concat_p)->payload = (const u8_t*)arg + pos; - queuelen += pbuf_clen(concat_p); - } -#if TCP_CHECKSUM_ON_COPY - /* calculate the checksum of nocopy-data */ - tcp_seg_add_chksum(~inet_chksum((const u8_t*)arg + pos, seglen), seglen, - &concat_chksum, &concat_chksum_swapped); - concat_chksummed += seglen; -#endif /* TCP_CHECKSUM_ON_COPY */ - } - - pos += seglen; - } - } else { -#if TCP_OVERSIZE - LWIP_ASSERT("unsent_oversize mismatch (pcb->unsent is NULL)", - pcb->unsent_oversize == 0); -#endif /* TCP_OVERSIZE */ - } - - /* - * Phase 3: Create new segments. - * - * The new segments are chained together in the local 'queue' - * variable, ready to be appended to pcb->unsent. - */ - while (pos < len) { - struct pbuf *p; - u16_t left = len - pos; - u16_t max_len = mss_local - optlen; - u16_t seglen = LWIP_MIN(left, max_len); -#if TCP_CHECKSUM_ON_COPY - u16_t chksum = 0; - u8_t chksum_swapped = 0; -#endif /* TCP_CHECKSUM_ON_COPY */ - - if (apiflags & TCP_WRITE_FLAG_COPY) { - /* If copy is set, memory should be allocated and data copied - * into pbuf */ - if ((p = tcp_pbuf_prealloc(PBUF_TRANSPORT, seglen + optlen, mss_local, &oversize, pcb, apiflags, queue == NULL)) == NULL) { - LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("tcp_write : could not allocate memory for pbuf copy size %"U16_F"\n", seglen)); - goto memerr; - } - LWIP_ASSERT("tcp_write: check that first pbuf can hold the complete seglen", - (p->len >= seglen)); - TCP_DATA_COPY2((char *)p->payload + optlen, (const u8_t*)arg + pos, seglen, &chksum, &chksum_swapped); - } else { - /* Copy is not set: First allocate a pbuf for holding the data. - * Since the referenced data is available at least until it is - * sent out on the link (as it has to be ACKed by the remote - * party) we can safely use PBUF_ROM instead of PBUF_REF here. - */ - struct pbuf *p2; -#if TCP_OVERSIZE - LWIP_ASSERT("oversize == 0", oversize == 0); -#endif /* TCP_OVERSIZE */ - if ((p2 = pbuf_alloc(PBUF_TRANSPORT, seglen, PBUF_ROM)) == NULL) { - LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("tcp_write: could not allocate memory for zero-copy pbuf\n")); - goto memerr; - } -#if TCP_CHECKSUM_ON_COPY - /* calculate the checksum of nocopy-data */ - chksum = ~inet_chksum((const u8_t*)arg + pos, seglen); - if (seglen & 1) { - chksum_swapped = 1; - chksum = SWAP_BYTES_IN_WORD(chksum); - } -#endif /* TCP_CHECKSUM_ON_COPY */ - /* reference the non-volatile payload data */ - ((struct pbuf_rom*)p2)->payload = (const u8_t*)arg + pos; - - /* Second, allocate a pbuf for the headers. */ - if ((p = pbuf_alloc(PBUF_TRANSPORT, optlen, PBUF_RAM)) == NULL) { - /* If allocation fails, we have to deallocate the data pbuf as - * well. */ - pbuf_free(p2); - LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("tcp_write: could not allocate memory for header pbuf\n")); - goto memerr; - } - /* Concatenate the headers and data pbufs together. */ - pbuf_cat(p/*header*/, p2/*data*/); - } - - queuelen += pbuf_clen(p); - - /* Now that there are more segments queued, we check again if the - * length of the queue exceeds the configured maximum or - * overflows. */ - if ((queuelen > TCP_SND_QUEUELEN) || (queuelen > TCP_SNDQUEUELEN_OVERFLOW)) { - LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("tcp_write: queue too long %"U16_F" (%d)\n", - queuelen, (int)TCP_SND_QUEUELEN)); - pbuf_free(p); - goto memerr; - } - - if ((seg = tcp_create_segment(pcb, p, 0, pcb->snd_lbb + pos, optflags)) == NULL) { - goto memerr; - } -#if TCP_OVERSIZE_DBGCHECK - seg->oversize_left = oversize; -#endif /* TCP_OVERSIZE_DBGCHECK */ -#if TCP_CHECKSUM_ON_COPY - seg->chksum = chksum; - seg->chksum_swapped = chksum_swapped; - seg->flags |= TF_SEG_DATA_CHECKSUMMED; -#endif /* TCP_CHECKSUM_ON_COPY */ - - /* first segment of to-be-queued data? */ - if (queue == NULL) { - queue = seg; - } else { - /* Attach the segment to the end of the queued segments */ - LWIP_ASSERT("prev_seg != NULL", prev_seg != NULL); - prev_seg->next = seg; - } - /* remember last segment of to-be-queued data for next iteration */ - prev_seg = seg; - - LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_TRACE, ("tcp_write: queueing %"U32_F":%"U32_F"\n", - lwip_ntohl(seg->tcphdr->seqno), - lwip_ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg))); - - pos += seglen; - } - - /* - * All three segmentation phases were successful. We can commit the - * transaction. - */ -#if TCP_OVERSIZE_DBGCHECK - if ((last_unsent != NULL) && (oversize_add != 0)) { - last_unsent->oversize_left += oversize_add; - } -#endif /* TCP_OVERSIZE_DBGCHECK */ - - /* - * Phase 1: If data has been added to the preallocated tail of - * last_unsent, we update the length fields of the pbuf chain. - */ -#if TCP_OVERSIZE - if (oversize_used > 0) { - struct pbuf *p; - /* Bump tot_len of whole chain, len of tail */ - for (p = last_unsent->p; p; p = p->next) { - p->tot_len += oversize_used; - if (p->next == NULL) { - TCP_DATA_COPY((char *)p->payload + p->len, arg, oversize_used, last_unsent); - p->len += oversize_used; - } - } - last_unsent->len += oversize_used; -#if TCP_OVERSIZE_DBGCHECK - LWIP_ASSERT("last_unsent->oversize_left >= oversize_used", - last_unsent->oversize_left >= oversize_used); - last_unsent->oversize_left -= oversize_used; -#endif /* TCP_OVERSIZE_DBGCHECK */ - } - pcb->unsent_oversize = oversize; -#endif /* TCP_OVERSIZE */ - - /* - * Phase 2: concat_p can be concatenated onto last_unsent->p, unless we - * determined that the last ROM pbuf can be extended to include the new data. - */ - if (concat_p != NULL) { - LWIP_ASSERT("tcp_write: cannot concatenate when pcb->unsent is empty", - (last_unsent != NULL)); - pbuf_cat(last_unsent->p, concat_p); - last_unsent->len += concat_p->tot_len; - } else if (extendlen > 0) { - struct pbuf *p; - LWIP_ASSERT("tcp_write: extension of reference requires reference", - last_unsent != NULL && last_unsent->p != NULL); - for (p = last_unsent->p; p->next != NULL; p = p->next) { - p->tot_len += extendlen; - } - p->tot_len += extendlen; - p->len += extendlen; - last_unsent->len += extendlen; - } - -#if TCP_CHECKSUM_ON_COPY - if (concat_chksummed) { - LWIP_ASSERT("tcp_write: concat checksum needs concatenated data", - concat_p != NULL || extendlen > 0); - /*if concat checksumm swapped - swap it back */ - if (concat_chksum_swapped) { - concat_chksum = SWAP_BYTES_IN_WORD(concat_chksum); - } - tcp_seg_add_chksum(concat_chksum, concat_chksummed, &last_unsent->chksum, - &last_unsent->chksum_swapped); - last_unsent->flags |= TF_SEG_DATA_CHECKSUMMED; - } -#endif /* TCP_CHECKSUM_ON_COPY */ - - /* - * Phase 3: Append queue to pcb->unsent. Queue may be NULL, but that - * is harmless - */ - if (last_unsent == NULL) { - pcb->unsent = queue; - } else { - last_unsent->next = queue; - } - - /* - * Finally update the pcb state. - */ - pcb->snd_lbb += len; - pcb->snd_buf -= len; - pcb->snd_queuelen = queuelen; - - LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_write: %"S16_F" (after enqueued)\n", - pcb->snd_queuelen)); - if (pcb->snd_queuelen != 0) { - LWIP_ASSERT("tcp_write: valid queue length", - pcb->unacked != NULL || pcb->unsent != NULL); - } - - /* Set the PSH flag in the last segment that we enqueued. */ - if (seg != NULL && seg->tcphdr != NULL && ((apiflags & TCP_WRITE_FLAG_MORE)==0)) { - TCPH_SET_FLAG(seg->tcphdr, TCP_PSH); - } - - return ERR_OK; -memerr: - pcb->flags |= TF_NAGLEMEMERR; - TCP_STATS_INC(tcp.memerr); - - if (concat_p != NULL) { - pbuf_free(concat_p); - } - if (queue != NULL) { - tcp_segs_free(queue); - } - if (pcb->snd_queuelen != 0) { - LWIP_ASSERT("tcp_write: valid queue length", pcb->unacked != NULL || - pcb->unsent != NULL); - } - LWIP_DEBUGF(TCP_QLEN_DEBUG | LWIP_DBG_STATE, ("tcp_write: %"S16_F" (with mem err)\n", pcb->snd_queuelen)); - return ERR_MEM; -} - -/** - * Enqueue TCP options for transmission. - * - * Called by tcp_connect(), tcp_listen_input(), and tcp_send_ctrl(). - * - * @param pcb Protocol control block for the TCP connection. - * @param flags TCP header flags to set in the outgoing segment. - */ -err_t -tcp_enqueue_flags(struct tcp_pcb *pcb, u8_t flags) -{ - struct pbuf *p; - struct tcp_seg *seg; - u8_t optflags = 0; - u8_t optlen = 0; - - LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_enqueue_flags: queuelen: %"U16_F"\n", (u16_t)pcb->snd_queuelen)); - - LWIP_ASSERT("tcp_enqueue_flags: need either TCP_SYN or TCP_FIN in flags (programmer violates API)", - (flags & (TCP_SYN | TCP_FIN)) != 0); - - /* check for configured max queuelen and possible overflow (FIN flag should always come through!) */ - if (((pcb->snd_queuelen >= TCP_SND_QUEUELEN) || (pcb->snd_queuelen > TCP_SNDQUEUELEN_OVERFLOW)) && - ((flags & TCP_FIN) == 0)) { - LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_LEVEL_SEVERE, ("tcp_enqueue_flags: too long queue %"U16_F" (max %"U16_F")\n", - pcb->snd_queuelen, (u16_t)TCP_SND_QUEUELEN)); - TCP_STATS_INC(tcp.memerr); - pcb->flags |= TF_NAGLEMEMERR; - return ERR_MEM; - } - - if (flags & TCP_SYN) { - optflags = TF_SEG_OPTS_MSS; -#if LWIP_WND_SCALE - if ((pcb->state != SYN_RCVD) || (pcb->flags & TF_WND_SCALE)) { - /* In a (sent in state SYN_RCVD), the window scale option may only - be sent if we received a window scale option from the remote host. */ - optflags |= TF_SEG_OPTS_WND_SCALE; - } -#endif /* LWIP_WND_SCALE */ - } -#if LWIP_TCP_TIMESTAMPS - if ((pcb->flags & TF_TIMESTAMP)) { - /* Make sure the timestamp option is only included in data segments if we - agreed about it with the remote host. */ - optflags |= TF_SEG_OPTS_TS; - } -#endif /* LWIP_TCP_TIMESTAMPS */ - optlen = LWIP_TCP_OPT_LENGTH(optflags); - - /* Allocate pbuf with room for TCP header + options */ - if ((p = pbuf_alloc(PBUF_TRANSPORT, optlen, PBUF_RAM)) == NULL) { - pcb->flags |= TF_NAGLEMEMERR; - TCP_STATS_INC(tcp.memerr); - return ERR_MEM; - } - LWIP_ASSERT("tcp_enqueue_flags: check that first pbuf can hold optlen", - (p->len >= optlen)); - - /* Allocate memory for tcp_seg, and fill in fields. */ - if ((seg = tcp_create_segment(pcb, p, flags, pcb->snd_lbb, optflags)) == NULL) { - pcb->flags |= TF_NAGLEMEMERR; - TCP_STATS_INC(tcp.memerr); - return ERR_MEM; - } - LWIP_ASSERT("seg->tcphdr not aligned", ((mem_ptr_t)seg->tcphdr % LWIP_MIN(MEM_ALIGNMENT, 4)) == 0); - LWIP_ASSERT("tcp_enqueue_flags: invalid segment length", seg->len == 0); - - LWIP_DEBUGF(TCP_OUTPUT_DEBUG | LWIP_DBG_TRACE, - ("tcp_enqueue_flags: queueing %"U32_F":%"U32_F" (0x%"X16_F")\n", - lwip_ntohl(seg->tcphdr->seqno), - lwip_ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg), - (u16_t)flags)); - - /* Now append seg to pcb->unsent queue */ - if (pcb->unsent == NULL) { - pcb->unsent = seg; - } else { - struct tcp_seg *useg; - for (useg = pcb->unsent; useg->next != NULL; useg = useg->next); - useg->next = seg; - } -#if TCP_OVERSIZE - /* The new unsent tail has no space */ - pcb->unsent_oversize = 0; -#endif /* TCP_OVERSIZE */ - - /* SYN and FIN bump the sequence number */ - if ((flags & TCP_SYN) || (flags & TCP_FIN)) { - pcb->snd_lbb++; - /* optlen does not influence snd_buf */ - } - if (flags & TCP_FIN) { - pcb->flags |= TF_FIN; - } - - /* update number of segments on the queues */ - pcb->snd_queuelen += pbuf_clen(seg->p); - LWIP_DEBUGF(TCP_QLEN_DEBUG, ("tcp_enqueue_flags: %"S16_F" (after enqueued)\n", pcb->snd_queuelen)); - if (pcb->snd_queuelen != 0) { - LWIP_ASSERT("tcp_enqueue_flags: invalid queue length", - pcb->unacked != NULL || pcb->unsent != NULL); - } - - return ERR_OK; -} - -#if LWIP_TCP_TIMESTAMPS -/* Build a timestamp option (12 bytes long) at the specified options pointer) - * - * @param pcb tcp_pcb - * @param opts option pointer where to store the timestamp option - */ -static void -tcp_build_timestamp_option(struct tcp_pcb *pcb, u32_t *opts) -{ - /* Pad with two NOP options to make everything nicely aligned */ - opts[0] = PP_HTONL(0x0101080A); - opts[1] = lwip_htonl(sys_now()); - opts[2] = lwip_htonl(pcb->ts_recent); -} -#endif - -#if LWIP_WND_SCALE -/** Build a window scale option (3 bytes long) at the specified options pointer) - * - * @param opts option pointer where to store the window scale option - */ -static void -tcp_build_wnd_scale_option(u32_t *opts) -{ - /* Pad with one NOP option to make everything nicely aligned */ - opts[0] = PP_HTONL(0x01030300 | TCP_RCV_SCALE); -} -#endif - -/** - * Send an ACK without data. - * - * @param pcb Protocol control block for the TCP connection to send the ACK - */ -err_t -tcp_send_empty_ack(struct tcp_pcb *pcb) -{ - err_t err; - struct pbuf *p; - u8_t optlen = 0; - struct netif *netif; -#if LWIP_TCP_TIMESTAMPS || CHECKSUM_GEN_TCP - struct tcp_hdr *tcphdr; -#endif /* LWIP_TCP_TIMESTAMPS || CHECKSUM_GEN_TCP */ - -#if LWIP_TCP_TIMESTAMPS - if (pcb->flags & TF_TIMESTAMP) { - optlen = LWIP_TCP_OPT_LENGTH(TF_SEG_OPTS_TS); - } -#endif - - p = tcp_output_alloc_header(pcb, optlen, 0, lwip_htonl(pcb->snd_nxt)); - if (p == NULL) { - /* let tcp_fasttmr retry sending this ACK */ - pcb->flags |= (TF_ACK_DELAY | TF_ACK_NOW); - LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output: (ACK) could not allocate pbuf\n")); - return ERR_BUF; - } -#if LWIP_TCP_TIMESTAMPS || CHECKSUM_GEN_TCP - tcphdr = (struct tcp_hdr *)p->payload; -#endif /* LWIP_TCP_TIMESTAMPS || CHECKSUM_GEN_TCP */ - LWIP_DEBUGF(TCP_OUTPUT_DEBUG, - ("tcp_output: sending ACK for %"U32_F"\n", pcb->rcv_nxt)); - - /* NB. MSS and window scale options are only sent on SYNs, so ignore them here */ -#if LWIP_TCP_TIMESTAMPS - pcb->ts_lastacksent = pcb->rcv_nxt; - - if (pcb->flags & TF_TIMESTAMP) { - tcp_build_timestamp_option(pcb, (u32_t *)(tcphdr + 1)); - } -#endif - - netif = ip_route(&pcb->local_ip, &pcb->remote_ip); - if (netif == NULL) { - err = ERR_RTE; - } else { -#if CHECKSUM_GEN_TCP - IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_TCP) { - tcphdr->chksum = ip_chksum_pseudo(p, IP_PROTO_TCP, p->tot_len, - &pcb->local_ip, &pcb->remote_ip); - } -#endif - netif_apply_pcb(netif, (struct ip_pcb *)pcb); - err = ip_output_if(p, &pcb->local_ip, &pcb->remote_ip, - pcb->ttl, pcb->tos, IP_PROTO_TCP, netif); - netif_apply_pcb(netif, NULL); - } - pbuf_free(p); - - if (err != ERR_OK) { - /* let tcp_fasttmr retry sending this ACK */ - pcb->flags |= (TF_ACK_DELAY | TF_ACK_NOW); - } else { - /* remove ACK flags from the PCB, as we sent an empty ACK now */ - pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW); - } - - return err; -} - -/** - * @ingroup tcp_raw - * Find out what we can send and send it - * - * @param pcb Protocol control block for the TCP connection to send data - * @return ERR_OK if data has been sent or nothing to send - * another err_t on error - */ -err_t -tcp_output(struct tcp_pcb *pcb) -{ - struct tcp_seg *seg, *useg; - u32_t wnd, snd_nxt; - err_t err; - struct netif *netif; -#if TCP_CWND_DEBUG - s16_t i = 0; -#endif /* TCP_CWND_DEBUG */ - - LWIP_ASSERT_CORE_LOCKED(); - /* pcb->state LISTEN not allowed here */ - LWIP_ASSERT("don't call tcp_output for listen-pcbs", - pcb->state != LISTEN); - - /* First, check if we are invoked by the TCP input processing - code. If so, we do not output anything. Instead, we rely on the - input processing code to call us when input processing is done - with. */ - if (tcp_input_pcb == pcb) { - return ERR_OK; - } - - wnd = LWIP_MIN(pcb->snd_wnd, pcb->cwnd); - - seg = pcb->unsent; - - /* If the TF_ACK_NOW flag is set and no data will be sent (either - * because the ->unsent queue is empty or because the window does - * not allow it), construct an empty ACK segment and send it. - * - * If data is to be sent, we will just piggyback the ACK (see below). - */ - if (pcb->flags & TF_ACK_NOW && - (seg == NULL || - lwip_ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len > wnd)) { - return tcp_send_empty_ack(pcb); - } - - /* useg should point to last segment on unacked queue */ - useg = pcb->unacked; - if (useg != NULL) { - for (; useg->next != NULL; useg = useg->next); - } - - netif = ip_route(&pcb->local_ip, &pcb->remote_ip); - if (netif == NULL) { - return ERR_RTE; - } - - /* If we don't have a local IP address, we get one from netif */ - if (ip_addr_isany(&pcb->local_ip)) { - const ip_addr_t *local_ip = ip_netif_get_local_ip(netif, &pcb->remote_ip); - if (local_ip == NULL) { - return ERR_RTE; - } - ip_addr_copy(pcb->local_ip, *local_ip); - } - -#if TCP_OUTPUT_DEBUG - if (seg == NULL) { - LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output: nothing to send (%p)\n", - (void*)pcb->unsent)); - } -#endif /* TCP_OUTPUT_DEBUG */ -#if TCP_CWND_DEBUG - if (seg == NULL) { - LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_output: snd_wnd %"TCPWNDSIZE_F - ", cwnd %"TCPWNDSIZE_F", wnd %"U32_F - ", seg == NULL, ack %"U32_F"\n", - pcb->snd_wnd, pcb->cwnd, wnd, pcb->lastack)); - } else { - LWIP_DEBUGF(TCP_CWND_DEBUG, - ("tcp_output: snd_wnd %"TCPWNDSIZE_F", cwnd %"TCPWNDSIZE_F", wnd %"U32_F - ", effwnd %"U32_F", seq %"U32_F", ack %"U32_F"\n", - pcb->snd_wnd, pcb->cwnd, wnd, - lwip_ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len, - lwip_ntohl(seg->tcphdr->seqno), pcb->lastack)); - } -#endif /* TCP_CWND_DEBUG */ - /* Check if we need to start the persistent timer when the next unsent segment - * does not fit within the remaining send window and RTO timer is not running (we - * have no in-flight data). A traditional approach would fill the remaining window - * with part of the unsent segment (which will engage zero-window probing upon - * reception of the zero window update from the receiver). This ensures the - * subsequent window update is reliably received. With the goal of being lightweight, - * we avoid splitting the unsent segment and treat the window as already zero. - */ - if (seg != NULL && - lwip_ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len > wnd && - wnd > 0 && wnd == pcb->snd_wnd && pcb->unacked == NULL) { - /* Start the persist timer */ - if (pcb->persist_backoff == 0) { - pcb->persist_cnt = 0; - pcb->persist_backoff = 1; - } - goto output_done; - } - /* data available and window allows it to be sent? */ - while (seg != NULL && - lwip_ntohl(seg->tcphdr->seqno) - pcb->lastack + seg->len <= wnd) { - LWIP_ASSERT("RST not expected here!", - (TCPH_FLAGS(seg->tcphdr) & TCP_RST) == 0); - /* Stop sending if the nagle algorithm would prevent it - * Don't stop: - * - if tcp_write had a memory error before (prevent delayed ACK timeout) or - * - if FIN was already enqueued for this PCB (SYN is always alone in a segment - - * either seg->next != NULL or pcb->unacked == NULL; - * RST is no sent using tcp_write/tcp_output. - */ - if ((tcp_do_output_nagle(pcb) == 0) && - ((pcb->flags & (TF_NAGLEMEMERR | TF_FIN)) == 0)) { - break; - } -#if TCP_CWND_DEBUG - LWIP_DEBUGF(TCP_CWND_DEBUG, ("tcp_output: snd_wnd %"TCPWNDSIZE_F", cwnd %"TCPWNDSIZE_F", wnd %"U32_F", effwnd %"U32_F", seq %"U32_F", ack %"U32_F", i %"S16_F"\n", - pcb->snd_wnd, pcb->cwnd, wnd, - lwip_ntohl(seg->tcphdr->seqno) + seg->len - - pcb->lastack, - lwip_ntohl(seg->tcphdr->seqno), pcb->lastack, i)); - ++i; -#endif /* TCP_CWND_DEBUG */ - - if (pcb->state != SYN_SENT) { - TCPH_SET_FLAG(seg->tcphdr, TCP_ACK); - } - -#if TCP_OVERSIZE_DBGCHECK - seg->oversize_left = 0; -#endif /* TCP_OVERSIZE_DBGCHECK */ - err = tcp_output_segment(seg, pcb, netif); - if (err != ERR_OK) { - /* segment could not be sent, for whatever reason */ - pcb->flags |= TF_NAGLEMEMERR; - return err; - } - pcb->unsent = seg->next; - if (pcb->state != SYN_SENT) { - pcb->flags &= ~(TF_ACK_DELAY | TF_ACK_NOW); - } - snd_nxt = lwip_ntohl(seg->tcphdr->seqno) + TCP_TCPLEN(seg); - if (TCP_SEQ_LT(pcb->snd_nxt, snd_nxt)) { - pcb->snd_nxt = snd_nxt; - } - /* put segment on unacknowledged list if length > 0 */ - if (TCP_TCPLEN(seg) > 0) { - seg->next = NULL; - /* unacked list is empty? */ - if (pcb->unacked == NULL) { - pcb->unacked = seg; - useg = seg; - /* unacked list is not empty? */ - } else { - /* In the case of fast retransmit, the packet should not go to the tail - * of the unacked queue, but rather somewhere before it. We need to check for - * this case. -STJ Jul 27, 2004 */ - if (TCP_SEQ_LT(lwip_ntohl(seg->tcphdr->seqno), lwip_ntohl(useg->tcphdr->seqno))) { - /* add segment to before tail of unacked list, keeping the list sorted */ - struct tcp_seg **cur_seg = &(pcb->unacked); - while (*cur_seg && - TCP_SEQ_LT(lwip_ntohl((*cur_seg)->tcphdr->seqno), lwip_ntohl(seg->tcphdr->seqno))) { - cur_seg = &((*cur_seg)->next ); - } - seg->next = (*cur_seg); - (*cur_seg) = seg; - } else { - /* add segment to tail of unacked list */ - useg->next = seg; - useg = useg->next; - } - } - /* do not queue empty segments on the unacked list */ - } else { - tcp_seg_free(seg); - } - seg = pcb->unsent; - } -output_done: -#if TCP_OVERSIZE - if (pcb->unsent == NULL) { - /* last unsent has been removed, reset unsent_oversize */ - pcb->unsent_oversize = 0; - } -#endif /* TCP_OVERSIZE */ - - pcb->flags &= ~TF_NAGLEMEMERR; - return ERR_OK; -} - -/** - * Called by tcp_output() to actually send a TCP segment over IP. - * - * @param seg the tcp_seg to send - * @param pcb the tcp_pcb for the TCP connection used to send the segment - * @param netif the netif used to send the segment - */ -static err_t -tcp_output_segment(struct tcp_seg *seg, struct tcp_pcb *pcb, struct netif *netif) -{ - err_t err; - u16_t len; - u32_t *opts; - - if (seg->p->ref != 1) { - /* This can happen if the pbuf of this segment is still referenced by the - netif driver due to deferred transmission. Since this function modifies - p->len, we must not continue in this case. */ - return ERR_OK; - } - - /* The TCP header has already been constructed, but the ackno and - wnd fields remain. */ - seg->tcphdr->ackno = lwip_htonl(pcb->rcv_nxt); - - /* advertise our receive window size in this TCP segment */ -#if LWIP_WND_SCALE - if (seg->flags & TF_SEG_OPTS_WND_SCALE) { - /* The Window field in a SYN segment itself (the only type where we send - the window scale option) is never scaled. */ - seg->tcphdr->wnd = lwip_htons(TCPWND_MIN16(pcb->rcv_ann_wnd)); - } else -#endif /* LWIP_WND_SCALE */ - { - seg->tcphdr->wnd = lwip_htons(TCPWND_MIN16(RCV_WND_SCALE(pcb, pcb->rcv_ann_wnd))); - } - - pcb->rcv_ann_right_edge = pcb->rcv_nxt + pcb->rcv_ann_wnd; - - /* Add any requested options. NB MSS option is only set on SYN - packets, so ignore it here */ - /* cast through void* to get rid of alignment warnings */ - opts = (u32_t *)(void *)(seg->tcphdr + 1); - if (seg->flags & TF_SEG_OPTS_MSS) { - u16_t mss; -#if TCP_CALCULATE_EFF_SEND_MSS - mss = tcp_eff_send_mss(TCP_MSS, &pcb->local_ip, &pcb->remote_ip); -#else /* TCP_CALCULATE_EFF_SEND_MSS */ - mss = TCP_MSS; -#endif /* TCP_CALCULATE_EFF_SEND_MSS */ - *opts = TCP_BUILD_MSS_OPTION(mss); - opts += 1; - } -#if LWIP_TCP_TIMESTAMPS - pcb->ts_lastacksent = pcb->rcv_nxt; - - if (seg->flags & TF_SEG_OPTS_TS) { - tcp_build_timestamp_option(pcb, opts); - opts += 3; - } -#endif -#if LWIP_WND_SCALE - if (seg->flags & TF_SEG_OPTS_WND_SCALE) { - tcp_build_wnd_scale_option(opts); - opts += 1; - } -#endif - - /* Set retransmission timer running if it is not currently enabled - This must be set before checking the route. */ - if (pcb->rtime < 0) { - pcb->rtime = 0; - } - - if (pcb->rttest == 0) { - pcb->rttest = tcp_ticks; - pcb->rtseq = lwip_ntohl(seg->tcphdr->seqno); - - LWIP_DEBUGF(TCP_RTO_DEBUG, ("tcp_output_segment: rtseq %"U32_F"\n", pcb->rtseq)); - } - LWIP_DEBUGF(TCP_OUTPUT_DEBUG, ("tcp_output_segment: %"U32_F":%"U32_F"\n", - lwip_htonl(seg->tcphdr->seqno), lwip_htonl(seg->tcphdr->seqno) + - seg->len)); - - len = (u16_t)((u8_t *)seg->tcphdr - (u8_t *)seg->p->payload); - if (len == 0) { - /** Exclude retransmitted segments from this count. */ - MIB2_STATS_INC(mib2.tcpoutsegs); - } - - seg->p->len -= len; - seg->p->tot_len -= len; - - seg->p->payload = seg->tcphdr; - - seg->tcphdr->chksum = 0; -#if CHECKSUM_GEN_TCP - IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_TCP) { -#if TCP_CHECKSUM_ON_COPY - u32_t acc; -#if TCP_CHECKSUM_ON_COPY_SANITY_CHECK - u16_t chksum_slow = ip_chksum_pseudo(seg->p, IP_PROTO_TCP, - seg->p->tot_len, &pcb->local_ip, &pcb->remote_ip); -#endif /* TCP_CHECKSUM_ON_COPY_SANITY_CHECK */ - if ((seg->flags & TF_SEG_DATA_CHECKSUMMED) == 0) { - LWIP_ASSERT("data included but not checksummed", - seg->p->tot_len == (TCPH_HDRLEN(seg->tcphdr) * 4)); - } - - /* rebuild TCP header checksum (TCP header changes for retransmissions!) */ - acc = ip_chksum_pseudo_partial(seg->p, IP_PROTO_TCP, - seg->p->tot_len, TCPH_HDRLEN(seg->tcphdr) * 4, &pcb->local_ip, &pcb->remote_ip); - /* add payload checksum */ - if (seg->chksum_swapped) { - seg->chksum = SWAP_BYTES_IN_WORD(seg->chksum); - seg->chksum_swapped = 0; - } - acc += (u16_t)~(seg->chksum); - seg->tcphdr->chksum = FOLD_U32T(acc); -#if TCP_CHECKSUM_ON_COPY_SANITY_CHECK - if (chksum_slow != seg->tcphdr->chksum) { - TCP_CHECKSUM_ON_COPY_SANITY_CHECK_FAIL( - ("tcp_output_segment: calculated checksum is %"X16_F" instead of %"X16_F"\n", - seg->tcphdr->chksum, chksum_slow)); - seg->tcphdr->chksum = chksum_slow; - } -#endif /* TCP_CHECKSUM_ON_COPY_SANITY_CHECK */ -#else /* TCP_CHECKSUM_ON_COPY */ - seg->tcphdr->chksum = ip_chksum_pseudo(seg->p, IP_PROTO_TCP, - seg->p->tot_len, &pcb->local_ip, &pcb->remote_ip); -#endif /* TCP_CHECKSUM_ON_COPY */ - } -#endif /* CHECKSUM_GEN_TCP */ - TCP_STATS_INC(tcp.xmit); - -#if TCP_OUTPUT_DEBUG -#if LWIP_IP_DEBUG_TARGET - if (debug_target_match(PCB_ISIPV6(pcb), &pcb->local_ip, &pcb->remote_ip)) - { -#endif - tcp_debug_print(seg->tcphdr); -#if LWIP_IP_DEBUG_TARGET - } -#endif -#endif - - netif_apply_pcb(netif, (struct ip_pcb *)pcb); - err = ip_output_if(seg->p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, - pcb->tos, IP_PROTO_TCP, netif); - netif_apply_pcb(netif, NULL); - return err; -} - -/** - * Send a TCP RESET packet (empty segment with RST flag set) either to - * abort a connection or to show that there is no matching local connection - * for a received segment. - * - * Called by tcp_abort() (to abort a local connection), tcp_input() (if no - * matching local pcb was found), tcp_listen_input() (if incoming segment - * has ACK flag set) and tcp_process() (received segment in the wrong state) - * - * Since a RST segment is in most cases not sent for an active connection, - * tcp_rst() has a number of arguments that are taken from a tcp_pcb for - * most other segment output functions. - * - * @param seqno the sequence number to use for the outgoing segment - * @param ackno the acknowledge number to use for the outgoing segment - * @param local_ip the local IP address to send the segment from - * @param remote_ip the remote IP address to send the segment to - * @param local_port the local TCP port to send the segment from - * @param remote_port the remote TCP port to send the segment to - */ -void -tcp_rst(u32_t seqno, u32_t ackno, - const ip_addr_t *local_ip, const ip_addr_t *remote_ip, - u16_t local_port, u16_t remote_port) -{ - struct pbuf *p; - struct tcp_hdr *tcphdr; - struct netif *netif; - p = pbuf_alloc(PBUF_IP, TCP_HLEN, PBUF_RAM); - if (p == NULL) { - LWIP_DEBUGF(TCP_DEBUG, ("tcp_rst: could not allocate memory for pbuf\n")); - return; - } - LWIP_ASSERT("check that first pbuf can hold struct tcp_hdr", - (p->len >= sizeof(struct tcp_hdr))); - - tcphdr = (struct tcp_hdr *)p->payload; - tcphdr->src = lwip_htons(local_port); - tcphdr->dest = lwip_htons(remote_port); - tcphdr->seqno = lwip_htonl(seqno); - tcphdr->ackno = lwip_htonl(ackno); - TCPH_HDRLEN_FLAGS_SET(tcphdr, TCP_HLEN/4, TCP_RST | TCP_ACK); -#if LWIP_WND_SCALE - tcphdr->wnd = PP_HTONS(((TCP_WND >> TCP_RCV_SCALE) & 0xFFFF)); -#else - tcphdr->wnd = PP_HTONS(TCP_WND); -#endif - tcphdr->chksum = 0; - tcphdr->urgp = 0; - - TCP_STATS_INC(tcp.xmit); - MIB2_STATS_INC(mib2.tcpoutrsts); - - netif = ip_route(local_ip, remote_ip); - if (netif != NULL) { -#if CHECKSUM_GEN_TCP - IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_TCP) { - tcphdr->chksum = ip_chksum_pseudo(p, IP_PROTO_TCP, p->tot_len, - local_ip, remote_ip); - } -#endif - /* Send output with hardcoded TTL/HL since we have no access to the pcb */ - ip_output_if(p, local_ip, remote_ip, TCP_TTL, 0, IP_PROTO_TCP, netif); - } - pbuf_free(p); - LWIP_DEBUGF(TCP_RST_DEBUG, ("tcp_rst: seqno %"U32_F" ackno %"U32_F".\n", seqno, ackno)); -} - -/** - * Requeue all unacked segments for retransmission - * - * Called by tcp_slowtmr() for slow retransmission. - * - * @param pcb the tcp_pcb for which to re-enqueue all unacked segments - */ -void -tcp_rexmit_rto(struct tcp_pcb *pcb) -{ - struct tcp_seg *seg; - - if (pcb->unacked == NULL) { - return; - } - - /* Move all unacked segments to the head of the unsent queue */ - for (seg = pcb->unacked; seg->next != NULL; seg = seg->next); - /* concatenate unsent queue after unacked queue */ - seg->next = pcb->unsent; -#if TCP_OVERSIZE_DBGCHECK - /* if last unsent changed, we need to update unsent_oversize */ - if (pcb->unsent == NULL) { - pcb->unsent_oversize = seg->oversize_left; - } -#endif /* TCP_OVERSIZE_DBGCHECK */ - /* unsent queue is the concatenated queue (of unacked, unsent) */ - pcb->unsent = pcb->unacked; - /* unacked queue is now empty */ - pcb->unacked = NULL; - - /* increment number of retransmissions */ - if (pcb->nrtx < 0xFF) { - ++pcb->nrtx; - } - - /* Don't take any RTT measurements after retransmitting. */ - pcb->rttest = 0; - - /* Do the actual retransmission */ - tcp_output(pcb); -} - -/** - * Requeue the first unacked segment for retransmission - * - * Called by tcp_receive() for fast retransmit. - * - * @param pcb the tcp_pcb for which to retransmit the first unacked segment - */ -void -tcp_rexmit(struct tcp_pcb *pcb) -{ - struct tcp_seg *seg; - struct tcp_seg **cur_seg; - - if (pcb->unacked == NULL) { - return; - } - - /* Move the first unacked segment to the unsent queue */ - /* Keep the unsent queue sorted. */ - seg = pcb->unacked; - pcb->unacked = seg->next; - - cur_seg = &(pcb->unsent); - while (*cur_seg && - TCP_SEQ_LT(lwip_ntohl((*cur_seg)->tcphdr->seqno), lwip_ntohl(seg->tcphdr->seqno))) { - cur_seg = &((*cur_seg)->next ); - } - seg->next = *cur_seg; - *cur_seg = seg; -#if TCP_OVERSIZE - if (seg->next == NULL) { - /* the retransmitted segment is last in unsent, so reset unsent_oversize */ - pcb->unsent_oversize = 0; - } -#endif /* TCP_OVERSIZE */ - - if (pcb->nrtx < 0xFF) { - ++pcb->nrtx; - } - - /* Don't take any rtt measurements after retransmitting. */ - pcb->rttest = 0; - - /* Do the actual retransmission. */ - MIB2_STATS_INC(mib2.tcpretranssegs); - /* No need to call tcp_output: we are always called from tcp_input() - and thus tcp_output directly returns. */ -} - - -/** - * Handle retransmission after three dupacks received - * - * @param pcb the tcp_pcb for which to retransmit the first unacked segment - */ -void -tcp_rexmit_fast(struct tcp_pcb *pcb) -{ - if (pcb->unacked != NULL && !(pcb->flags & TF_INFR)) { - /* This is fast retransmit. Retransmit the first unacked segment. */ - LWIP_DEBUGF(TCP_FR_DEBUG, - ("tcp_receive: dupacks %"U16_F" (%"U32_F - "), fast retransmit %"U32_F"\n", - (u16_t)pcb->dupacks, pcb->lastack, - lwip_ntohl(pcb->unacked->tcphdr->seqno))); - tcp_rexmit(pcb); - - /* Set ssthresh to half of the minimum of the current - * cwnd and the advertised window */ - pcb->ssthresh = LWIP_MIN(pcb->cwnd, pcb->snd_wnd) / 2; - - /* The minimum value for ssthresh should be 2 MSS */ - if (pcb->ssthresh < (2U * pcb->mss)) { - LWIP_DEBUGF(TCP_FR_DEBUG, - ("tcp_receive: The minimum value for ssthresh %"TCPWNDSIZE_F - " should be min 2 mss %"U16_F"...\n", - pcb->ssthresh, (u16_t)(2*pcb->mss))); - pcb->ssthresh = 2*pcb->mss; - } - - pcb->cwnd = pcb->ssthresh + 3 * pcb->mss; - pcb->flags |= TF_INFR; - - /* Reset the retransmission timer to prevent immediate rto retransmissions */ - pcb->rtime = 0; - } -} - - -/** - * Send keepalive packets to keep a connection active although - * no data is sent over it. - * - * Called by tcp_slowtmr() - * - * @param pcb the tcp_pcb for which to send a keepalive packet - */ -err_t -tcp_keepalive(struct tcp_pcb *pcb) -{ - err_t err; - struct pbuf *p; - struct netif *netif; - - LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: sending KEEPALIVE probe to ")); - ip_addr_debug_print(TCP_DEBUG, &pcb->remote_ip); - LWIP_DEBUGF(TCP_DEBUG, ("\n")); - - LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: tcp_ticks %"U32_F" pcb->tmr %"U32_F" pcb->keep_cnt_sent %"U16_F"\n", - tcp_ticks, pcb->tmr, (u16_t)pcb->keep_cnt_sent)); - - p = tcp_output_alloc_header(pcb, 0, 0, lwip_htonl(pcb->snd_nxt - 1)); - if (p == NULL) { - LWIP_DEBUGF(TCP_DEBUG, - ("tcp_keepalive: could not allocate memory for pbuf\n")); - return ERR_MEM; - } - netif = ip_route(&pcb->local_ip, &pcb->remote_ip); - if (netif == NULL) { - err = ERR_RTE; - } else { -#if CHECKSUM_GEN_TCP - IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_TCP) { - struct tcp_hdr *tcphdr = (struct tcp_hdr *)p->payload; - tcphdr->chksum = ip_chksum_pseudo(p, IP_PROTO_TCP, p->tot_len, - &pcb->local_ip, &pcb->remote_ip); - } -#endif /* CHECKSUM_GEN_TCP */ - TCP_STATS_INC(tcp.xmit); - - /* Send output to IP */ - netif_apply_pcb(netif, (struct ip_pcb *)pcb); - err = ip_output_if(p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, 0, IP_PROTO_TCP, netif); - netif_apply_pcb(netif, NULL); - } - pbuf_free(p); - - LWIP_DEBUGF(TCP_DEBUG, ("tcp_keepalive: seqno %"U32_F" ackno %"U32_F" err %d.\n", - pcb->snd_nxt - 1, pcb->rcv_nxt, (int)err)); - return err; -} - - -/** - * Send persist timer zero-window probes to keep a connection active - * when a window update is lost. - * - * Called by tcp_slowtmr() - * - * @param pcb the tcp_pcb for which to send a zero-window probe packet - */ -err_t -tcp_zero_window_probe(struct tcp_pcb *pcb) -{ - err_t err; - struct pbuf *p; - struct tcp_hdr *tcphdr; - struct tcp_seg *seg; - u16_t len; - u8_t is_fin; - u32_t snd_nxt; - struct netif *netif; - - LWIP_DEBUGF(TCP_DEBUG, ("tcp_zero_window_probe: sending ZERO WINDOW probe to ")); - ip_addr_debug_print(TCP_DEBUG, &pcb->remote_ip); - LWIP_DEBUGF(TCP_DEBUG, ("\n")); - - LWIP_DEBUGF(TCP_DEBUG, - ("tcp_zero_window_probe: tcp_ticks %"U32_F - " pcb->tmr %"U32_F" pcb->keep_cnt_sent %"U16_F"\n", - tcp_ticks, pcb->tmr, (u16_t)pcb->keep_cnt_sent)); - - seg = pcb->unacked; - - if (seg == NULL) { - seg = pcb->unsent; - } - if (seg == NULL) { - /* nothing to send, zero window probe not needed */ - return ERR_OK; - } - - is_fin = ((TCPH_FLAGS(seg->tcphdr) & TCP_FIN) != 0) && (seg->len == 0); - /* we want to send one seqno: either FIN or data (no options) */ - len = is_fin ? 0 : 1; - - p = tcp_output_alloc_header(pcb, 0, len, seg->tcphdr->seqno); - if (p == NULL) { - LWIP_DEBUGF(TCP_DEBUG, ("tcp_zero_window_probe: no memory for pbuf\n")); - return ERR_MEM; - } - tcphdr = (struct tcp_hdr *)p->payload; - - if (is_fin) { - /* FIN segment, no data */ - TCPH_FLAGS_SET(tcphdr, TCP_ACK | TCP_FIN); - } else { - /* Data segment, copy in one byte from the head of the unacked queue */ - char *d = ((char *)p->payload + TCP_HLEN); - /* Depending on whether the segment has already been sent (unacked) or not - (unsent), seg->p->payload points to the IP header or TCP header. - Ensure we copy the first TCP data byte: */ - pbuf_copy_partial(seg->p, d, 1, seg->p->tot_len - seg->len); - } - - /* The byte may be acknowledged without the window being opened. */ - snd_nxt = lwip_ntohl(seg->tcphdr->seqno) + 1; - if (TCP_SEQ_LT(pcb->snd_nxt, snd_nxt)) { - pcb->snd_nxt = snd_nxt; - } - - netif = ip_route(&pcb->local_ip, &pcb->remote_ip); - if (netif == NULL) { - err = ERR_RTE; - } else { -#if CHECKSUM_GEN_TCP - IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_TCP) { - tcphdr->chksum = ip_chksum_pseudo(p, IP_PROTO_TCP, p->tot_len, - &pcb->local_ip, &pcb->remote_ip); - } -#endif - TCP_STATS_INC(tcp.xmit); - - /* Send output to IP */ - netif_apply_pcb(netif, (struct ip_pcb *)pcb); - err = ip_output_if(p, &pcb->local_ip, &pcb->remote_ip, pcb->ttl, - 0, IP_PROTO_TCP, netif); - netif_apply_pcb(netif, NULL); - } - - pbuf_free(p); - - LWIP_DEBUGF(TCP_DEBUG, ("tcp_zero_window_probe: seqno %"U32_F - " ackno %"U32_F" err %d.\n", - pcb->snd_nxt - 1, pcb->rcv_nxt, (int)err)); - return err; -} -#endif /* LWIP_TCP */ diff --git a/third_party/lwip/repo/lwip/src/core/timeouts.c b/third_party/lwip/repo/lwip/src/core/timeouts.c deleted file mode 100644 index 4e3caa01e76d21..00000000000000 --- a/third_party/lwip/repo/lwip/src/core/timeouts.c +++ /dev/null @@ -1,451 +0,0 @@ -/** - * @file - * Stack-internal timers implementation. - * This file includes timer callbacks for stack-internal timers as well as - * functions to set up or stop timers and check for expired timers. - * - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * Simon Goldschmidt - * - */ - -#include "lwip/opt.h" - -#include "lwip/timeouts.h" -#include "lwip/priv/tcp_priv.h" - -#include "lwip/def.h" -#include "lwip/memp.h" -#include "lwip/priv/tcpip_priv.h" - -#include "lwip/ip4_frag.h" -#include "lwip/etharp.h" -#include "lwip/dhcp.h" -#include "lwip/autoip.h" -#include "lwip/igmp.h" -#include "lwip/dns.h" -#include "lwip/nd6.h" -#include "lwip/ip6_frag.h" -#include "lwip/mld6.h" -#include "lwip/sys.h" -#include "lwip/pbuf.h" - -#if LWIP_DEBUG_TIMERNAMES -#define HANDLER(x) x, #x -#else /* LWIP_DEBUG_TIMERNAMES */ -#define HANDLER(x) x -#endif /* LWIP_DEBUG_TIMERNAMES */ - -/** This array contains all stack-internal cyclic timers. To get the number of - * timers, use LWIP_ARRAYSIZE() */ -const struct lwip_cyclic_timer lwip_cyclic_timers[] = { -#if LWIP_IPV4 -#if IP_REASSEMBLY - {IP_TMR_INTERVAL, HANDLER(ip_reass_tmr)}, -#endif /* IP_REASSEMBLY */ -#if LWIP_ARP - {ARP_TMR_INTERVAL, HANDLER(etharp_tmr)}, -#endif /* LWIP_ARP */ -#if LWIP_DHCP - {DHCP_COARSE_TIMER_MSECS, HANDLER(dhcp_coarse_tmr)}, - {DHCP_FINE_TIMER_MSECS, HANDLER(dhcp_fine_tmr)}, -#endif /* LWIP_DHCP */ -#if LWIP_AUTOIP - {AUTOIP_TMR_INTERVAL, HANDLER(autoip_tmr)}, -#endif /* LWIP_AUTOIP */ -#if LWIP_IGMP - {IGMP_TMR_INTERVAL, HANDLER(igmp_tmr)}, -#endif /* LWIP_IGMP */ -#endif /* LWIP_IPV4 */ -#if LWIP_DNS - {DNS_TMR_INTERVAL, HANDLER(dns_tmr)}, -#endif /* LWIP_DNS */ -#if LWIP_IPV6 -#if LWIP_IPV6_REASS - {IP6_REASS_TMR_INTERVAL, HANDLER(ip6_reass_tmr)}, -#endif /* LWIP_IPV6_REASS */ -#if LWIP_IPV6_ND - {ND6_TMR_INTERVAL, HANDLER(nd6_tmr)}, -#endif /* LWIP_IPV6_ND */ -#endif /* LWIP_IPV6 */ -}; - -#if LWIP_TIMERS && !LWIP_TIMERS_CUSTOM - -/** The one and only timeout list */ -static struct sys_timeo *next_timeout; -static u32_t timeouts_last_time; - -#if LWIP_TCP -/** global variable that shows if the tcp timer is currently scheduled or not */ -static int tcpip_tcp_timer_active; - -/** - * Timer callback function that calls tcp_tmr() and reschedules itself. - * - * @param arg unused argument - */ -static void -tcpip_tcp_timer(void *arg) -{ - LWIP_UNUSED_ARG(arg); - - /* call TCP timer handler */ - tcp_tmr(); - /* timer still needed? */ - if (tcp_active_pcbs || tcp_tw_pcbs) { - /* restart timer */ - sys_timeout(TCP_TMR_INTERVAL, tcpip_tcp_timer, NULL); - } else { - /* disable timer */ - tcpip_tcp_timer_active = 0; - } -} - -/** - * Called from TCP_REG when registering a new PCB: - * the reason is to have the TCP timer only running when - * there are active (or time-wait) PCBs. - */ -void -tcp_timer_needed(void) -{ - /* timer is off but needed again? */ - if (!tcpip_tcp_timer_active && (tcp_active_pcbs || tcp_tw_pcbs)) { - /* enable and start timer */ - tcpip_tcp_timer_active = 1; - -#if LWIP_TCPIP_TIMEOUT - // When tcp_connect is called from a different thread, it is - // possible that the tcp timers do not get started properly. This - // happens when there are no TCP timers active and the SYN packet - // is lost (or not responded to). We gate the different code - // paths based on LWIP_TCPIP_CORE_LOCKING, which is a prerequisite - // to attempt to call the raw api from multiple threads. - // Submitted as LwIP patch 8737 - - tcpip_timeout(TCP_TMR_INTERVAL, tcpip_tcp_timer, NULL); -#else - sys_timeout(TCP_TMR_INTERVAL, tcpip_tcp_timer, NULL); -#endif //LWIP_TCPIP_CORE_LOCKING - } -} -#endif /* LWIP_TCP */ - -/** - * Timer callback function that calls mld6_tmr() and reschedules itself. - * - * @param arg unused argument - */ -static void -cyclic_timer(void *arg) -{ - const struct lwip_cyclic_timer* cyclic = (const struct lwip_cyclic_timer*)arg; -#if LWIP_DEBUG_TIMERNAMES - LWIP_DEBUGF(TIMERS_DEBUG, ("tcpip: %s()\n", cyclic->handler_name)); -#endif - cyclic->handler(); - sys_timeout(cyclic->interval_ms, cyclic_timer, arg); -} - -/** Initialize this module */ -void sys_timeouts_init(void) -{ - size_t i; - /* tcp_tmr() at index 0 is started on demand */ - for (i = (LWIP_TCP ? 1 : 0); i < LWIP_ARRAYSIZE(lwip_cyclic_timers); i++) { - /* we have to cast via size_t to get rid of const warning - (this is OK as cyclic_timer() casts back to const* */ - sys_timeout(lwip_cyclic_timers[i].interval_ms, cyclic_timer, LWIP_CONST_CAST(void*, &lwip_cyclic_timers[i])); - } - - /* Initialise timestamp for sys_check_timeouts */ - timeouts_last_time = sys_now(); -} - -/** - * Create a one-shot timer (aka timeout). Timeouts are processed in the - * following cases: - * - while waiting for a message using sys_timeouts_mbox_fetch() - * - by calling sys_check_timeouts() (NO_SYS==1 only) - * - * @param msecs time in milliseconds after that the timer should expire - * @param handler callback function to call when msecs have elapsed - * @param arg argument to pass to the callback function - */ -#if LWIP_DEBUG_TIMERNAMES -void -sys_timeout_debug(u32_t msecs, sys_timeout_handler handler, void *arg, const char* handler_name) -#else /* LWIP_DEBUG_TIMERNAMES */ -void -sys_timeout(u32_t msecs, sys_timeout_handler handler, void *arg) -#endif /* LWIP_DEBUG_TIMERNAMES */ -{ - struct sys_timeo *timeout, *t; - u32_t now, diff; - - LWIP_ASSERT_CORE_LOCKED(); - - timeout = (struct sys_timeo *)memp_malloc(MEMP_SYS_TIMEOUT); - if (timeout == NULL) { - LWIP_ASSERT("sys_timeout: timeout != NULL, pool MEMP_SYS_TIMEOUT is empty", timeout != NULL); - return; - } - - now = sys_now(); - if (next_timeout == NULL) { - diff = 0; - timeouts_last_time = now; - } else { - diff = now - timeouts_last_time; - } - - timeout->next = NULL; - timeout->h = handler; - timeout->arg = arg; - timeout->time = msecs + diff; -#if LWIP_DEBUG_TIMERNAMES - timeout->handler_name = handler_name; - LWIP_DEBUGF(TIMERS_DEBUG, ("sys_timeout: %p msecs=%"U32_F" handler=%s arg=%p\n", - (void *)timeout, msecs, handler_name, (void *)arg)); -#endif /* LWIP_DEBUG_TIMERNAMES */ - - if (next_timeout == NULL) { - next_timeout = timeout; - return; - } - - if (next_timeout->time > msecs) { - next_timeout->time -= msecs; - timeout->next = next_timeout; - next_timeout = timeout; - } else { - for (t = next_timeout; t != NULL; t = t->next) { - timeout->time -= t->time; - if (t->next == NULL || t->next->time > timeout->time) { - if (t->next != NULL) { - t->next->time -= timeout->time; - } else if (timeout->time > msecs) { - /* If this is the case, 'timeouts_last_time' and 'now' differs too much. - This can be due to sys_check_timeouts() not being called at the right - times, but also when stopping in a breakpoint. Anyway, let's assume - this is not wanted, so add the first timer's time instead of 'diff' */ - timeout->time = msecs + next_timeout->time; - } - timeout->next = t->next; - t->next = timeout; - break; - } - } - } -} - -/** - * Go through timeout list (for this task only) and remove the first matching - * entry (subsequent entries remain untouched), even though the timeout has not - * triggered yet. - * - * @param handler callback function that would be called by the timeout - * @param arg callback argument that would be passed to handler -*/ -void -sys_untimeout(sys_timeout_handler handler, void *arg) -{ - struct sys_timeo *prev_t, *t; - - LWIP_ASSERT_CORE_LOCKED(); - - if (next_timeout == NULL) { - return; - } - - for (t = next_timeout, prev_t = NULL; t != NULL; prev_t = t, t = t->next) { - if ((t->h == handler) && (t->arg == arg)) { - /* We have a match */ - /* Unlink from previous in list */ - if (prev_t == NULL) { - next_timeout = t->next; - } else { - prev_t->next = t->next; - } - /* If not the last one, add time of this one back to next */ - if (t->next != NULL) { - t->next->time += t->time; - } - memp_free(MEMP_SYS_TIMEOUT, t); - return; - } - } - return; -} - -/** - * @ingroup lwip_nosys - * Handle timeouts for NO_SYS==1 (i.e. without using - * tcpip_thread/sys_timeouts_mbox_fetch(). Uses sys_now() to call timeout - * handler functions when timeouts expire. - * - * Must be called periodically from your main loop. - */ -#if !NO_SYS && !defined __DOXYGEN__ -static -#endif /* !NO_SYS */ -void -sys_check_timeouts(void) -{ - LWIP_ASSERT_CORE_LOCKED(); - - if (next_timeout) { - struct sys_timeo *tmptimeout; - u32_t diff; - sys_timeout_handler handler; - void *arg; - u8_t had_one; - u32_t now; - - now = sys_now(); - /* this cares for wraparounds */ - diff = now - timeouts_last_time; - do { - PBUF_CHECK_FREE_OOSEQ(); - had_one = 0; - tmptimeout = next_timeout; - if (tmptimeout && (tmptimeout->time <= diff)) { - /* timeout has expired */ - had_one = 1; - timeouts_last_time += tmptimeout->time; - diff -= tmptimeout->time; - next_timeout = tmptimeout->next; - handler = tmptimeout->h; - arg = tmptimeout->arg; -#if LWIP_DEBUG_TIMERNAMES - if (handler != NULL) { - LWIP_DEBUGF(TIMERS_DEBUG, ("sct calling h=%s arg=%p\n", - tmptimeout->handler_name, arg)); - } -#endif /* LWIP_DEBUG_TIMERNAMES */ - memp_free(MEMP_SYS_TIMEOUT, tmptimeout); - if (handler != NULL) { -#if !NO_SYS - /* For LWIP_TCPIP_CORE_LOCKING, lock the core before calling the - timeout handler function. */ - LOCK_TCPIP_CORE(); -#endif /* !NO_SYS */ - handler(arg); -#if !NO_SYS - UNLOCK_TCPIP_CORE(); -#endif /* !NO_SYS */ - } - LWIP_TCPIP_THREAD_ALIVE(); - } - /* repeat until all expired timers have been called */ - } while (had_one); - } -} - -/** Set back the timestamp of the last call to sys_check_timeouts() - * This is necessary if sys_check_timeouts() hasn't been called for a long - * time (e.g. while saving energy) to prevent all timer functions of that - * period being called. - */ -void -sys_restart_timeouts(void) -{ - LWIP_ASSERT_CORE_LOCKED(); - - timeouts_last_time = sys_now(); -} - -/** Return the time left before the next timeout is due. If no timeouts are - * enqueued, returns 0xffffffff - */ -#if !NO_SYS -static -#endif /* !NO_SYS */ -u32_t -sys_timeouts_sleeptime(void) -{ - u32_t diff; - - LWIP_ASSERT_CORE_LOCKED(); - - if (next_timeout == NULL) { - return 0xffffffff; - } - diff = sys_now() - timeouts_last_time; - if (diff > next_timeout->time) { - return 0; - } else { - return next_timeout->time - diff; - } -} - -#if !NO_SYS - -/** - * Wait (forever) for a message to arrive in an mbox. - * While waiting, timeouts are processed. - * - * @param mbox the mbox to fetch the message from - * @param msg the place to store the message - */ -void -sys_timeouts_mbox_fetch(sys_mbox_t *mbox, void **msg) -{ - u32_t sleeptime; - -again: - if (!next_timeout) { - sys_arch_mbox_fetch(mbox, msg, 0); - return; - } - - sleeptime = sys_timeouts_sleeptime(); - if (sleeptime == 0 || sys_arch_mbox_fetch(mbox, msg, sleeptime) == SYS_ARCH_TIMEOUT) { - /* If a SYS_ARCH_TIMEOUT value is returned, a timeout occurred - before a message could be fetched. */ - sys_check_timeouts(); - /* We try again to fetch a message from the mbox. */ - goto again; - } -} - -#endif /* NO_SYS */ - -#else /* LWIP_TIMERS && !LWIP_TIMERS_CUSTOM */ -/* Satisfy the TCP code which calls this function */ -void -tcp_timer_needed(void) -{ -} -#endif /* LWIP_TIMERS && !LWIP_TIMERS_CUSTOM */ diff --git a/third_party/lwip/repo/lwip/src/core/udp.c b/third_party/lwip/repo/lwip/src/core/udp.c deleted file mode 100644 index 4969eb3e8243b5..00000000000000 --- a/third_party/lwip/repo/lwip/src/core/udp.c +++ /dev/null @@ -1,1257 +0,0 @@ -/** - * @file - * User Datagram Protocol module\n - * The code for the User Datagram Protocol UDP & UDPLite (RFC 3828).\n - * See also @ref udp_raw - * - * @defgroup udp_raw UDP - * @ingroup callbackstyle_api - * User Datagram Protocol module\n - * @see @ref raw_api and @ref netconn - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ - -/* @todo Check the use of '(struct udp_pcb).chksum_len_rx'! - */ - -#include "lwip/opt.h" - -#if LWIP_UDP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/udp.h" -#include "lwip/def.h" -#include "lwip/memp.h" -#include "lwip/inet_chksum.h" -#include "lwip/ip_addr.h" -#include "lwip/ip6.h" -#include "lwip/ip6_addr.h" -#include "lwip/netif.h" -#include "lwip/icmp.h" -#include "lwip/icmp6.h" -#include "lwip/stats.h" -#include "lwip/snmp.h" -#include "lwip/dhcp.h" - -#include - -#ifndef UDP_LOCAL_PORT_RANGE_START -/* From http://www.iana.org/assignments/port-numbers: - "The Dynamic and/or Private Ports are those from 49152 through 65535" */ -#define UDP_LOCAL_PORT_RANGE_START 0xc000 -#define UDP_LOCAL_PORT_RANGE_END 0xffff -#define UDP_ENSURE_LOCAL_PORT_RANGE(port) ((u16_t)(((port) & (u16_t)~UDP_LOCAL_PORT_RANGE_START) + UDP_LOCAL_PORT_RANGE_START)) -#endif - -/* last local UDP port */ -static u16_t udp_port = UDP_LOCAL_PORT_RANGE_START; - -/* The list of UDP PCBs */ -/* exported in udp.h (was static) */ -struct udp_pcb *udp_pcbs; - -/** - * Initialize this module. - */ -void -udp_init(void) -{ -#if LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS && defined(LWIP_RAND) - udp_port = UDP_ENSURE_LOCAL_PORT_RANGE(LWIP_RAND()); -#endif /* LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS && defined(LWIP_RAND) */ -} - -/** - * Allocate a new local UDP port. - * - * @return a new (free) local UDP port number - */ -static u16_t -udp_new_port(void) -{ - u16_t n = 0; - struct udp_pcb *pcb; - -again: - if (udp_port++ == UDP_LOCAL_PORT_RANGE_END) { - udp_port = UDP_LOCAL_PORT_RANGE_START; - } - /* Check all PCBs. */ - for (pcb = udp_pcbs; pcb != NULL; pcb = pcb->next) { - if (pcb->local_port == udp_port) { - if (++n > (UDP_LOCAL_PORT_RANGE_END - UDP_LOCAL_PORT_RANGE_START)) { - return 0; - } - goto again; - } - } - return udp_port; -} - -/** Common code to see if the current input packet matches the pcb - * (current input packet is accessed via ip(4/6)_current_* macros) - * - * @param pcb pcb to check - * @param inp network interface on which the datagram was received (only used for IPv4) - * @param broadcast 1 if his is an IPv4 broadcast (global or subnet-only), 0 otherwise (only used for IPv4) - * @return 1 on match, 0 otherwise - */ -static u8_t -udp_input_local_match(struct udp_pcb *pcb, struct netif *inp, u8_t broadcast) -{ - LWIP_UNUSED_ARG(broadcast); /* in IPv6 only case */ - - /* check if PCB is bound to specific netif */ - if ((pcb->netif_idx != NETIF_NO_INDEX) && - (pcb->netif_idx != netif_get_index(ip_data.current_input_netif))) { - return 0; - } - - /* Dual-stack: PCBs listening to any IP type also listen to any IP address */ - if (IP_IS_ANY_TYPE_VAL(pcb->local_ip)) { -#if LWIP_IPV4 && IP_SOF_BROADCAST_RECV - if ((broadcast != 0) && !ip_get_option(pcb, SOF_BROADCAST)) { - return 0; - } -#endif /* LWIP_IPV4 && IP_SOF_BROADCAST_RECV */ - return 1; - } - - /* Only need to check PCB if incoming IP version matches PCB IP version */ - if (IP_ADDR_PCB_VERSION_MATCH_EXACT(pcb, ip_current_dest_addr())) { -#if LWIP_IPV4 - /* Special case: IPv4 broadcast: all or broadcasts in my subnet - * Note: broadcast variable can only be 1 if it is an IPv4 broadcast */ - if (broadcast != 0) { -#if IP_SOF_BROADCAST_RECV - if (ip_get_option(pcb, SOF_BROADCAST)) -#endif /* IP_SOF_BROADCAST_RECV */ - { - if (ip4_addr_isany(ip_2_ip4(&pcb->local_ip)) || - ((ip4_current_dest_addr()->addr == IPADDR_BROADCAST)) || - ip4_addr_netcmp(ip_2_ip4(&pcb->local_ip), ip4_current_dest_addr(), netif_ip4_netmask(inp))) { - return 1; - } - } - } else -#endif /* LWIP_IPV4 */ - /* Handle IPv4 and IPv6: all or exact match */ - if (ip_addr_isany(&pcb->local_ip) || ip_addr_cmp(&pcb->local_ip, ip_current_dest_addr())) { - return 1; - } - } - - return 0; -} - -/** - * Process an incoming UDP datagram. - * - * Given an incoming UDP datagram (as a chain of pbufs) this function - * finds a corresponding UDP PCB and hands over the pbuf to the pcbs - * recv function. If no pcb is found or the datagram is incorrect, the - * pbuf is freed. - * - * @param p pbuf to be demultiplexed to a UDP PCB (p->payload pointing to the UDP header) - * @param inp network interface on which the datagram was received. - * - */ -void -udp_input(struct pbuf *p, struct netif *inp) -{ - struct udp_hdr *udphdr; - struct udp_pcb *pcb, *prev; - struct udp_pcb *uncon_pcb; - u16_t src, dest; - u8_t broadcast; - u8_t for_us = 0; - - LWIP_UNUSED_ARG(inp); - LWIP_ASSERT_CORE_LOCKED(); - - PERF_START; - - UDP_STATS_INC(udp.recv); - - /* Check minimum length (UDP header) */ - if (p->len < UDP_HLEN) { - /* drop short packets */ - LWIP_DEBUGF(UDP_DEBUG, - ("udp_input: short UDP datagram (%"U16_F" bytes) discarded\n", p->tot_len)); - UDP_STATS_INC(udp.lenerr); - UDP_STATS_INC(udp.drop); - MIB2_STATS_INC(mib2.udpinerrors); - pbuf_free(p); - goto end; - } - - udphdr = (struct udp_hdr *)p->payload; - - /* is broadcast packet ? */ - broadcast = ip_addr_isbroadcast(ip_current_dest_addr(), ip_current_netif()); - - LWIP_DEBUGF(UDP_DEBUG, ("udp_input: received datagram of length %"U16_F"\n", p->tot_len)); - - /* convert src and dest ports to host byte order */ - src = lwip_ntohs(udphdr->src); - dest = lwip_ntohs(udphdr->dest); - - udp_debug_print(udphdr); - - /* print the UDP source and destination */ - LWIP_DEBUGF(UDP_DEBUG, ("udp (")); - ip_addr_debug_print(UDP_DEBUG, ip_current_dest_addr()); - LWIP_DEBUGF(UDP_DEBUG, (", %"U16_F") <-- (", lwip_ntohs(udphdr->dest))); - ip_addr_debug_print(UDP_DEBUG, ip_current_src_addr()); - LWIP_DEBUGF(UDP_DEBUG, (", %"U16_F")\n", lwip_ntohs(udphdr->src))); - - pcb = NULL; - prev = NULL; - uncon_pcb = NULL; - /* Iterate through the UDP pcb list for a matching pcb. - * 'Perfect match' pcbs (connected to the remote port & ip address) are - * preferred. If no perfect match is found, the first unconnected pcb that - * matches the local port and ip address gets the datagram. */ - for (pcb = udp_pcbs; pcb != NULL; pcb = pcb->next) { - /* print the PCB local and remote address */ - LWIP_DEBUGF(UDP_DEBUG, ("pcb (")); - ip_addr_debug_print(UDP_DEBUG, &pcb->local_ip); - LWIP_DEBUGF(UDP_DEBUG, (", %"U16_F") <-- (", pcb->local_port)); - ip_addr_debug_print(UDP_DEBUG, &pcb->remote_ip); - LWIP_DEBUGF(UDP_DEBUG, (", %"U16_F")\n", pcb->remote_port)); - - if (!(pcb->intf_filter == NULL || pcb->intf_filter == inp)) - continue; - -#if LWIP_MANAGEMENT_CHANNEL - if (inp->using_management_channel && !ip_get_option(pcb,SOF_MANAGEMENT)) - continue; -#endif - - /* compare PCB local addr+port to UDP destination addr+port */ - if ((pcb->local_port == dest) && - (udp_input_local_match(pcb, inp, broadcast) != 0)) { - if (((pcb->flags & UDP_FLAGS_CONNECTED) == 0) && - ((uncon_pcb == NULL) -#if SO_REUSE - /* prefer specific IPs over cath-all */ - || !ip_addr_isany(&pcb->local_ip) -#endif /* SO_REUSE */ - )) { - /* the first unconnected matching PCB */ - uncon_pcb = pcb; - } - - /* compare PCB remote addr+port to UDP source addr+port */ - if ((pcb->remote_port == src) && - (ip_addr_isany_val(pcb->remote_ip) || - ip_addr_cmp(&pcb->remote_ip, ip_current_src_addr()))) { - /* the first fully matching PCB */ - if (prev != NULL) { - /* move the pcb to the front of udp_pcbs so that is - found faster next time */ - prev->next = pcb->next; - pcb->next = udp_pcbs; - udp_pcbs = pcb; - } else { - UDP_STATS_INC(udp.cachehit); - } - break; - } - } - - prev = pcb; - } - /* no fully matching pcb found? then look for an unconnected pcb */ - if (pcb == NULL) { - pcb = uncon_pcb; - } - - /* Check checksum if this is a match or if it was directed at us. */ - if (pcb != NULL) { - for_us = 1; - } else { -#if LWIP_IPV6 - if (ip_current_is_v6()) { - for_us = netif_get_ip6_addr_match(inp, ip6_current_dest_addr()) >= 0; - } -#endif /* LWIP_IPV6 */ -#if LWIP_IPV4 - if (!ip_current_is_v6()) { - for_us = ip4_addr_cmp(netif_ip4_addr(inp), ip4_current_dest_addr()); - } -#endif /* LWIP_IPV4 */ - } - - if (for_us) { - LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_input: calculating checksum\n")); -#if CHECKSUM_CHECK_UDP - IF__NETIF_CHECKSUM_ENABLED(inp, CHECKSUM_CHECK_UDP) { -#if LWIP_UDPLITE - if (ip_current_header_proto() == IP_PROTO_UDPLITE) { - /* Do the UDP Lite checksum */ - u16_t chklen = lwip_ntohs(udphdr->len); - if (chklen < sizeof(struct udp_hdr)) { - if (chklen == 0) { - /* For UDP-Lite, checksum length of 0 means checksum - over the complete packet (See RFC 3828 chap. 3.1) */ - chklen = p->tot_len; - } else { - /* At least the UDP-Lite header must be covered by the - checksum! (Again, see RFC 3828 chap. 3.1) */ - goto chkerr; - } - } - if (ip_chksum_pseudo_partial(p, IP_PROTO_UDPLITE, - p->tot_len, chklen, - ip_current_src_addr(), ip_current_dest_addr()) != 0) { - goto chkerr; - } - } else -#endif /* LWIP_UDPLITE */ - { - if (udphdr->chksum != 0) { - if (ip_chksum_pseudo(p, IP_PROTO_UDP, p->tot_len, - ip_current_src_addr(), - ip_current_dest_addr()) != 0) { - goto chkerr; - } - } - } - } -#endif /* CHECKSUM_CHECK_UDP */ - if (pbuf_header(p, -UDP_HLEN)) { - /* Can we cope with this failing? Just assert for now */ - LWIP_ASSERT("pbuf_header failed\n", 0); - UDP_STATS_INC(udp.drop); - MIB2_STATS_INC(mib2.udpinerrors); - pbuf_free(p); - goto end; - } - - if (pcb != NULL) { - MIB2_STATS_INC(mib2.udpindatagrams); -#if SO_REUSE && SO_REUSE_RXTOALL - if (ip_get_option(pcb, SOF_REUSEADDR) && - (broadcast || ip_addr_ismulticast(ip_current_dest_addr()))) { - /* pass broadcast- or multicast packets to all multicast pcbs - if SOF_REUSEADDR is set on the first match */ - struct udp_pcb *mpcb; - u8_t p_header_changed = 0; - s16_t hdrs_len = (s16_t)(ip_current_header_tot_len() + UDP_HLEN); - for (mpcb = udp_pcbs; mpcb != NULL; mpcb = mpcb->next) { - if (mpcb != pcb) { - /* compare PCB local addr+port to UDP destination addr+port */ - if ((mpcb->local_port == dest) && - (udp_input_local_match(mpcb, inp, broadcast) != 0)) { - /* pass a copy of the packet to all local matches */ - if (mpcb->recv != NULL) { - struct pbuf *q; - /* for that, move payload to IP header again */ - if (p_header_changed == 0) { - pbuf_header_force(p, hdrs_len); - p_header_changed = 1; - } - q = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_POOL); - if (q != NULL) { - err_t err = pbuf_copy(q, p); - if (err == ERR_OK) { - /* move payload to UDP data */ - pbuf_header(q, -hdrs_len); - mpcb->recv(mpcb->recv_arg, mpcb, q, ip_current_src_addr(), src); - } - } - } - } - } - } - if (p_header_changed) { - /* and move payload to UDP data again */ - pbuf_header(p, -hdrs_len); - } - } -#endif /* SO_REUSE && SO_REUSE_RXTOALL */ - /* callback */ - if (pcb->recv != NULL) { - /* now the recv function is responsible for freeing p */ - pcb->recv(pcb->recv_arg, pcb, p, ip_current_src_addr(), src); - } else { - /* no recv function registered? then we have to free the pbuf! */ - pbuf_free(p); - goto end; - } - } else { - LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_input: not for us.\n")); - -#if LWIP_ICMP || LWIP_ICMP6 - /* No match was found, send ICMP destination port unreachable unless - destination address was broadcast/multicast. */ - if (!broadcast && !ip_addr_ismulticast(ip_current_dest_addr())) { - /* move payload pointer back to ip header */ - pbuf_header_force(p, (s16_t)(ip_current_header_tot_len() + UDP_HLEN)); - icmp_port_unreach(ip_current_is_v6(), p); - } -#endif /* LWIP_ICMP || LWIP_ICMP6 */ - UDP_STATS_INC(udp.proterr); - UDP_STATS_INC(udp.drop); - MIB2_STATS_INC(mib2.udpnoports); - pbuf_free(p); - } - } else { - pbuf_free(p); - } -end: - PERF_STOP("udp_input"); - return; -#if CHECKSUM_CHECK_UDP -chkerr: - LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, - ("udp_input: UDP (or UDP Lite) datagram discarded due to failing checksum\n")); - UDP_STATS_INC(udp.chkerr); - UDP_STATS_INC(udp.drop); - MIB2_STATS_INC(mib2.udpinerrors); - pbuf_free(p); - PERF_STOP("udp_input"); -#endif /* CHECKSUM_CHECK_UDP */ -} - -/** - * @ingroup udp_raw - * Send data using UDP. - * - * @param pcb UDP PCB used to send the data. - * @param p chain of pbuf's to be sent. - * - * The datagram will be sent to the current remote_ip & remote_port - * stored in pcb. If the pcb is not bound to a port, it will - * automatically be bound to a random port. - * - * @return lwIP error code. - * - ERR_OK. Successful. No error occurred. - * - ERR_MEM. Out of memory. - * - ERR_RTE. Could not find route to destination address. - * - ERR_VAL. No PCB or PCB is dual-stack - * - More errors could be returned by lower protocol layers. - * - * @see udp_disconnect() udp_sendto() - */ -err_t -udp_send(struct udp_pcb *pcb, struct pbuf *p) -{ - if ((pcb == NULL) || IP_IS_ANY_TYPE_VAL(pcb->remote_ip)) { - return ERR_VAL; - } - - /* send to the packet using remote ip and port stored in the pcb */ - return udp_sendto(pcb, p, &pcb->remote_ip, pcb->remote_port); -} - -#if LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP -/** @ingroup udp_raw - * Same as udp_send() but with checksum - */ -err_t -udp_send_chksum(struct udp_pcb *pcb, struct pbuf *p, - u8_t have_chksum, u16_t chksum) -{ - if ((pcb == NULL) || IP_IS_ANY_TYPE_VAL(pcb->remote_ip)) { - return ERR_VAL; - } - - /* send to the packet using remote ip and port stored in the pcb */ - return udp_sendto_chksum(pcb, p, &pcb->remote_ip, pcb->remote_port, - have_chksum, chksum); -} -#endif /* LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP */ - -/** - * @ingroup udp_raw - * Send data to a specified address using UDP. - * - * @param pcb UDP PCB used to send the data. - * @param p chain of pbuf's to be sent. - * @param dst_ip Destination IP address. - * @param dst_port Destination UDP port. - * - * dst_ip & dst_port are expected to be in the same byte order as in the pcb. - * - * If the PCB already has a remote address association, it will - * be restored after the data is sent. - * - * @return lwIP error code (@see udp_send for possible error codes) - * - * @see udp_disconnect() udp_send() - */ -err_t -udp_sendto(struct udp_pcb *pcb, struct pbuf *p, - const ip_addr_t *dst_ip, u16_t dst_port) -{ -#if LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP - return udp_sendto_chksum(pcb, p, dst_ip, dst_port, 0, 0); -} - -/** @ingroup udp_raw - * Same as udp_sendto(), but with checksum */ -err_t -udp_sendto_chksum(struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *dst_ip, - u16_t dst_port, u8_t have_chksum, u16_t chksum) -{ -#endif /* LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP */ - struct netif *netif; - - if ((pcb == NULL) || (dst_ip == NULL) || !IP_ADDR_PCB_VERSION_MATCH(pcb, dst_ip)) { - return ERR_VAL; - } - - LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_send\n")); - - if (pcb->netif_idx != NETIF_NO_INDEX) { - netif = netif_get_by_index(pcb->netif_idx); - } else { -#if LWIP_MULTICAST_TX_OPTIONS - netif = NULL; - if (ip_addr_ismulticast(dst_ip)) { - /* For IPv6, the interface to use for packets with a multicast destination - * is specified using an interface index. The same approach may be used for - * IPv4 as well, in which case it overrides the IPv4 multicast override - * address below. Here we have to look up the netif by going through the - * list, but by doing so we skip a route lookup. If the interface index has - * gone stale, we fall through and do the regular route lookup after all. */ - if (pcb->mcast_ifindex != NETIF_NO_INDEX) { - netif = netif_get_by_index(pcb->mcast_ifindex); - } -#if LWIP_IPV4 - else -#if LWIP_IPV6 - if (IP_IS_V4(dst_ip)) -#endif /* LWIP_IPV6 */ - { - /* IPv4 does not use source-based routing by default, so we use an - administratively selected interface for multicast by default. - However, this can be overridden by setting an interface address - in pcb->mcast_ip4 that is used for routing. If this routing lookup - fails, we try regular routing as though no override was set. */ - if (!ip4_addr_isany_val(pcb->mcast_ip4) && - !ip4_addr_cmp(&pcb->mcast_ip4, IP4_ADDR_BROADCAST)) { - netif = ip4_route_src(ip_2_ip4(&pcb->local_ip), &pcb->mcast_ip4); - } - } -#endif /* LWIP_IPV4 */ - } - - if (netif == NULL) -#endif /* LWIP_MULTICAST_TX_OPTIONS */ - { - /* find the outgoing network interface for this packet */ - netif = ip_route(&pcb->local_ip, dst_ip); - } - } - - /* no outgoing network interface could be found? */ - if (netif == NULL) { - LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, ("udp_send: No route to ")); - ip_addr_debug_print(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, dst_ip); - LWIP_DEBUGF(UDP_DEBUG, ("\n")); - UDP_STATS_INC(udp.rterr); - return ERR_RTE; - } -#if LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP - return udp_sendto_if_chksum(pcb, p, dst_ip, dst_port, netif, have_chksum, chksum); -#else /* LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP */ - return udp_sendto_if(pcb, p, dst_ip, dst_port, netif); -#endif /* LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP */ -} - -/** - * @ingroup udp_raw - * Send data to a specified address using UDP. - * The netif used for sending can be specified. - * - * This function exists mainly for DHCP, to be able to send UDP packets - * on a netif that is still down. - * - * @param pcb UDP PCB used to send the data. - * @param p chain of pbuf's to be sent. - * @param dst_ip Destination IP address. - * @param dst_port Destination UDP port. - * @param netif the netif used for sending. - * - * dst_ip & dst_port are expected to be in the same byte order as in the pcb. - * - * @return lwIP error code (@see udp_send for possible error codes) - * - * @see udp_disconnect() udp_send() - */ -err_t -udp_sendto_if(struct udp_pcb *pcb, struct pbuf *p, - const ip_addr_t *dst_ip, u16_t dst_port, struct netif *netif) -{ -#if LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP - return udp_sendto_if_chksum(pcb, p, dst_ip, dst_port, netif, 0, 0); -} - -/** Same as udp_sendto_if(), but with checksum */ -err_t -udp_sendto_if_chksum(struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *dst_ip, - u16_t dst_port, struct netif *netif, u8_t have_chksum, - u16_t chksum) -{ -#endif /* LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP */ - const ip_addr_t *src_ip; - - if ((pcb == NULL) || (dst_ip == NULL) || !IP_ADDR_PCB_VERSION_MATCH(pcb, dst_ip)) { - return ERR_VAL; - } - - /* PCB local address is IP_ANY_ADDR or multicast? */ -#if LWIP_IPV6 - if (IP_IS_V6(dst_ip)) { - if (ip6_addr_isany(ip_2_ip6(&pcb->local_ip)) || - ip6_addr_ismulticast(ip_2_ip6(&pcb->local_ip))) { - src_ip = ip6_select_source_address(netif, ip_2_ip6(dst_ip)); - if (src_ip == NULL) { - /* No suitable source address was found. */ - return ERR_RTE; - } - } else { - /* use UDP PCB local IPv6 address as source address, if still valid. */ - if (netif_get_ip6_addr_match(netif, ip_2_ip6(&pcb->local_ip)) < 0) { - /* Address isn't valid anymore. */ - return ERR_RTE; - } - src_ip = &pcb->local_ip; - } - } -#endif /* LWIP_IPV6 */ -#if LWIP_IPV4 && LWIP_IPV6 - else -#endif /* LWIP_IPV4 && LWIP_IPV6 */ -#if LWIP_IPV4 - if (ip4_addr_isany(ip_2_ip4(&pcb->local_ip)) || - ip4_addr_ismulticast(ip_2_ip4(&pcb->local_ip))) { - /* if the local_ip is any or multicast - * use the outgoing network interface IP address as source address */ - src_ip = netif_ip_addr4(netif); - } else { - /* check if UDP PCB local IP address is correct - * this could be an old address if netif->ip_addr has changed */ - if (!ip4_addr_cmp(ip_2_ip4(&(pcb->local_ip)), netif_ip4_addr(netif))) { - /* local_ip doesn't match, drop the packet */ - return ERR_RTE; - } - /* use UDP PCB local IP address as source address */ - src_ip = &pcb->local_ip; - } -#endif /* LWIP_IPV4 */ -#if LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP - return udp_sendto_if_src_chksum(pcb, p, dst_ip, dst_port, netif, have_chksum, chksum, src_ip); -#else /* LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP */ - return udp_sendto_if_src(pcb, p, dst_ip, dst_port, netif, src_ip); -#endif /* LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP */ -} - -/** @ingroup udp_raw - * Same as @ref udp_sendto_if, but with source address */ -err_t -udp_sendto_if_src(struct udp_pcb *pcb, struct pbuf *p, - const ip_addr_t *dst_ip, u16_t dst_port, struct netif *netif, const ip_addr_t *src_ip) -{ -#if LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP - return udp_sendto_if_src_chksum(pcb, p, dst_ip, dst_port, netif, 0, 0, src_ip); -} - -/** Same as udp_sendto_if_src(), but with checksum */ -err_t -udp_sendto_if_src_chksum(struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *dst_ip, - u16_t dst_port, struct netif *netif, u8_t have_chksum, - u16_t chksum, const ip_addr_t *src_ip) -{ -#endif /* LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP */ - struct udp_hdr *udphdr; - err_t err; - struct pbuf *q; /* q will be sent down the stack */ - u8_t ip_proto; - u8_t ttl; - - LWIP_ASSERT_CORE_LOCKED(); - - if ((pcb == NULL) || (dst_ip == NULL) || !IP_ADDR_PCB_VERSION_MATCH(pcb, src_ip) || - !IP_ADDR_PCB_VERSION_MATCH(pcb, dst_ip)) { - return ERR_VAL; - } - -#if LWIP_IPV4 && IP_SOF_BROADCAST - /* broadcast filter? */ - if (!ip_get_option(pcb, SOF_BROADCAST) && -#if LWIP_IPV6 - IP_IS_V4(dst_ip) && -#endif /* LWIP_IPV6 */ - ip_addr_isbroadcast(dst_ip, netif)) { - LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_LEVEL_SERIOUS, - ("udp_sendto_if: SOF_BROADCAST not enabled on pcb %p\n", (void *)pcb)); - return ERR_VAL; - } -#endif /* LWIP_IPV4 && IP_SOF_BROADCAST */ - - /* if the PCB is not yet bound to a port, bind it here */ - if (pcb->local_port == 0) { - LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_send: not yet bound to a port, binding now\n")); - err = udp_bind(pcb, &pcb->local_ip, pcb->local_port); - if (err != ERR_OK) { - LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("udp_send: forced port bind failed\n")); - return err; - } - } - - /* not enough space to add an UDP header to first pbuf in given p chain? */ - if (pbuf_header(p, UDP_HLEN)) { - /* allocate header in a separate new pbuf */ - q = pbuf_alloc(PBUF_IP, UDP_HLEN, PBUF_RAM); - /* new header pbuf could not be allocated? */ - if (q == NULL) { - LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, ("udp_send: could not allocate header\n")); - return ERR_MEM; - } - if (p->tot_len != 0) { - /* chain header q in front of given pbuf p (only if p contains data) */ - pbuf_chain(q, p); - } - /* first pbuf q points to header pbuf */ - LWIP_DEBUGF(UDP_DEBUG, - ("udp_send: added header pbuf %p before given pbuf %p\n", (void *)q, (void *)p)); - } else { - /* adding space for header within p succeeded */ - /* first pbuf q equals given pbuf */ - q = p; - LWIP_DEBUGF(UDP_DEBUG, ("udp_send: added header in given pbuf %p\n", (void *)p)); - } - LWIP_ASSERT("check that first pbuf can hold struct udp_hdr", - (q->len >= sizeof(struct udp_hdr))); - /* q now represents the packet to be sent */ - udphdr = (struct udp_hdr *)q->payload; - udphdr->src = lwip_htons(pcb->local_port); - udphdr->dest = lwip_htons(dst_port); - /* in UDP, 0 checksum means 'no checksum' */ - udphdr->chksum = 0x0000; - - /* Multicast Loop? */ -#if LWIP_MULTICAST_TX_OPTIONS - if (((pcb->flags & UDP_FLAGS_MULTICAST_LOOP) != 0) && ip_addr_ismulticast(dst_ip)) { - q->flags |= PBUF_FLAG_MCASTLOOP; - } -#endif /* LWIP_MULTICAST_TX_OPTIONS */ - - LWIP_DEBUGF(UDP_DEBUG, ("udp_send: sending datagram of length %"U16_F"\n", q->tot_len)); - -#if LWIP_UDPLITE - /* UDP Lite protocol? */ - if (pcb->flags & UDP_FLAGS_UDPLITE) { - u16_t chklen, chklen_hdr; - LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP LITE packet length %"U16_F"\n", q->tot_len)); - /* set UDP message length in UDP header */ - chklen_hdr = chklen = pcb->chksum_len_tx; - if ((chklen < sizeof(struct udp_hdr)) || (chklen > q->tot_len)) { - if (chklen != 0) { - LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP LITE pcb->chksum_len is illegal: %"U16_F"\n", chklen)); - } - /* For UDP-Lite, checksum length of 0 means checksum - over the complete packet. (See RFC 3828 chap. 3.1) - At least the UDP-Lite header must be covered by the - checksum, therefore, if chksum_len has an illegal - value, we generate the checksum over the complete - packet to be safe. */ - chklen_hdr = 0; - chklen = q->tot_len; - } - udphdr->len = lwip_htons(chklen_hdr); - /* calculate checksum */ -#if CHECKSUM_GEN_UDP - IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_UDP) { -#if LWIP_CHECKSUM_ON_COPY - if (have_chksum) { - chklen = UDP_HLEN; - } -#endif /* LWIP_CHECKSUM_ON_COPY */ - udphdr->chksum = ip_chksum_pseudo_partial(q, IP_PROTO_UDPLITE, - q->tot_len, chklen, src_ip, dst_ip); -#if LWIP_CHECKSUM_ON_COPY - if (have_chksum) { - u32_t acc; - acc = udphdr->chksum + (u16_t)~(chksum); - udphdr->chksum = FOLD_U32T(acc); - } -#endif /* LWIP_CHECKSUM_ON_COPY */ - - /* chksum zero must become 0xffff, as zero means 'no checksum' */ - if (udphdr->chksum == 0x0000) { - udphdr->chksum = 0xffff; - } - } -#endif /* CHECKSUM_GEN_UDP */ - - ip_proto = IP_PROTO_UDPLITE; - } else -#endif /* LWIP_UDPLITE */ - { /* UDP */ - LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP packet length %"U16_F"\n", q->tot_len)); - udphdr->len = lwip_htons(q->tot_len); - /* calculate checksum */ -#if CHECKSUM_GEN_UDP - IF__NETIF_CHECKSUM_ENABLED(netif, NETIF_CHECKSUM_GEN_UDP) { - /* Checksum is mandatory over IPv6. */ - if (IP_IS_V6(dst_ip) || (pcb->flags & UDP_FLAGS_NOCHKSUM) == 0) { - u16_t udpchksum; -#if LWIP_CHECKSUM_ON_COPY - if (have_chksum) { - u32_t acc; - udpchksum = ip_chksum_pseudo_partial(q, IP_PROTO_UDP, - q->tot_len, UDP_HLEN, src_ip, dst_ip); - acc = udpchksum + (u16_t)~(chksum); - udpchksum = FOLD_U32T(acc); - } else -#endif /* LWIP_CHECKSUM_ON_COPY */ - { - udpchksum = ip_chksum_pseudo(q, IP_PROTO_UDP, q->tot_len, - src_ip, dst_ip); - } - - /* chksum zero must become 0xffff, as zero means 'no checksum' */ - if (udpchksum == 0x0000) { - udpchksum = 0xffff; - } - udphdr->chksum = udpchksum; - } - } -#endif /* CHECKSUM_GEN_UDP */ - ip_proto = IP_PROTO_UDP; - } - - /* Determine TTL to use */ -#if LWIP_MULTICAST_TX_OPTIONS - ttl = (ip_addr_ismulticast(dst_ip) ? udp_get_multicast_ttl(pcb) : pcb->ttl); -#else /* LWIP_MULTICAST_TX_OPTIONS */ - ttl = pcb->ttl; -#endif /* LWIP_MULTICAST_TX_OPTIONS */ - - LWIP_DEBUGF(UDP_DEBUG, ("udp_send: UDP checksum 0x%04"X16_F"\n", lwip_ntohs(udphdr->chksum))); - LWIP_DEBUGF(UDP_DEBUG, ("udp_send: ip_output_if (,,,,0x%02"X16_F",)\n", (u16_t)ip_proto)); - /* output to IP */ - netif_apply_pcb(netif, (struct ip_pcb*) pcb); - err = ip_output_if_src(q, src_ip, dst_ip, ttl, pcb->tos, ip_proto, netif); - netif_apply_pcb(netif, NULL); -#if LWIP_MANAGEMENT_CHANNEL - netif->using_management_channel = 0; -#endif - - /* @todo: must this be increased even if error occurred? */ - MIB2_STATS_INC(mib2.udpoutdatagrams); - - /* did we chain a separate header pbuf earlier? */ - if (q != p) { - /* free the header pbuf */ - pbuf_free(q); - q = NULL; - /* p is still referenced by the caller, and will live on */ - } - - UDP_STATS_INC(udp.xmit); - return err; -} - -/** - * @ingroup udp_raw - * Bind an UDP PCB. - * - * @param pcb UDP PCB to be bound with a local address ipaddr and port. - * @param ipaddr local IP address to bind with. Use IP4_ADDR_ANY to - * bind to all local interfaces. - * @param port local UDP port to bind with. Use 0 to automatically bind - * to a random port between UDP_LOCAL_PORT_RANGE_START and - * UDP_LOCAL_PORT_RANGE_END. - * - * ipaddr & port are expected to be in the same byte order as in the pcb. - * - * @return lwIP error code. - * - ERR_OK. Successful. No error occurred. - * - ERR_USE. The specified ipaddr and port are already bound to by - * another UDP PCB. - * - * @see udp_disconnect() - */ -err_t -udp_bind(struct udp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port) -{ - struct udp_pcb *ipcb; - u8_t rebind; - - LWIP_ASSERT_CORE_LOCKED(); - -#if LWIP_IPV4 - /* Don't propagate NULL pointer (IPv4 ANY) to subsequent functions */ - if (ipaddr == NULL) { - ipaddr = IP4_ADDR_ANY; - } -#endif /* LWIP_IPV4 */ - - /* still need to check for ipaddr == NULL in IPv6 only case */ - if ((pcb == NULL) || (ipaddr == NULL)) { - return ERR_VAL; - } - - LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, ("udp_bind(ipaddr = ")); - ip_addr_debug_print(UDP_DEBUG | LWIP_DBG_TRACE, ipaddr); - LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE, (", port = %"U16_F")\n", port)); - - rebind = 0; - /* Check for double bind and rebind of the same pcb */ - for (ipcb = udp_pcbs; ipcb != NULL; ipcb = ipcb->next) { - /* is this UDP PCB already on active list? */ - if (pcb == ipcb) { - rebind = 1; - break; - } - } - - /* no port specified? */ - if (port == 0) { - port = udp_new_port(); - if (port == 0) { - /* no more ports available in local range */ - LWIP_DEBUGF(UDP_DEBUG, ("udp_bind: out of free UDP ports\n")); - return ERR_USE; - } - } else { - for (ipcb = udp_pcbs; ipcb != NULL; ipcb = ipcb->next) { - if (pcb != ipcb) { - /* By default, we don't allow to bind to a port that any other udp - PCB is already bound to, unless *all* PCBs with that port have tha - REUSEADDR flag set. */ -#if SO_REUSE - if (!ip_get_option(pcb, SOF_REUSEADDR) || - !ip_get_option(ipcb, SOF_REUSEADDR)) -#endif /* SO_REUSE */ - { - /* port matches that of PCB in list and REUSEADDR not set -> reject */ - if ((ipcb->local_port == port) && - /* IP address matches? */ - ip_addr_cmp(&ipcb->local_ip, ipaddr)) { - /* other PCB already binds to this local IP and port */ - LWIP_DEBUGF(UDP_DEBUG, - ("udp_bind: local port %"U16_F" already bound by another pcb\n", port)); - return ERR_USE; - } - } - } - } - } - - ip_addr_set_ipaddr(&pcb->local_ip, ipaddr); - - pcb->local_port = port; - mib2_udp_bind(pcb); - /* pcb not active yet? */ - if (rebind == 0) { - /* place the PCB on the active list if not already there */ - pcb->next = udp_pcbs; - udp_pcbs = pcb; - } - LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("udp_bind: bound to ")); - ip_addr_debug_print(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, &pcb->local_ip); - LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, (", port %"U16_F")\n", pcb->local_port)); - return ERR_OK; -} - -/** - * @ingroup udp_raw - * Bind an UDP PCB to a specific netif. - * - * @param pcb UDP PCB to be bound. - * @param netif netif to bind udp pcb to. Can be NULL. - * - * @see udp_disconnect() - */ -void -udp_bind_netif(struct udp_pcb *pcb, const struct netif *netif) -{ - if (netif != NULL) { - pcb->netif_idx = netif_get_index(netif); - } else { - pcb->netif_idx = NETIF_NO_INDEX; - } -} - -/** - * @ingroup udp_raw - * Connect an UDP PCB. - * - * This will associate the UDP PCB with the remote address. - * - * @param pcb UDP PCB to be connected with remote address ipaddr and port. - * @param ipaddr remote IP address to connect with. - * @param port remote UDP port to connect with. - * - * @return lwIP error code - * - * ipaddr & port are expected to be in the same byte order as in the pcb. - * - * The udp pcb is bound to a random local port if not already bound. - * - * @see udp_disconnect() - */ -err_t -udp_connect(struct udp_pcb *pcb, const ip_addr_t *ipaddr, u16_t port) -{ - struct udp_pcb *ipcb; - - LWIP_ASSERT_CORE_LOCKED(); - - if ((pcb == NULL) || (ipaddr == NULL)) { - return ERR_VAL; - } - - if (pcb->local_port == 0) { - err_t err = udp_bind(pcb, &pcb->local_ip, pcb->local_port); - if (err != ERR_OK) { - return err; - } - } - - ip_addr_set_ipaddr(&pcb->remote_ip, ipaddr); - pcb->remote_port = port; - pcb->flags |= UDP_FLAGS_CONNECTED; - - LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, ("udp_connect: connected to ")); - ip_addr_debug_print(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, - &pcb->remote_ip); - LWIP_DEBUGF(UDP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_STATE, (", port %"U16_F")\n", pcb->remote_port)); - - /* Insert UDP PCB into the list of active UDP PCBs. */ - for (ipcb = udp_pcbs; ipcb != NULL; ipcb = ipcb->next) { - if (pcb == ipcb) { - /* already on the list, just return */ - return ERR_OK; - } - } - /* PCB not yet on the list, add PCB now */ - pcb->next = udp_pcbs; - udp_pcbs = pcb; - return ERR_OK; -} - -/** - * @ingroup udp_raw - * Disconnect a UDP PCB - * - * @param pcb the udp pcb to disconnect. - */ -void -udp_disconnect(struct udp_pcb *pcb) -{ - LWIP_ASSERT_CORE_LOCKED(); - - /* reset remote address association */ -#if LWIP_IPV4 && LWIP_IPV6 - if (IP_IS_ANY_TYPE_VAL(pcb->local_ip)) { - ip_addr_copy(pcb->remote_ip, *IP_ANY_TYPE); - } else { -#endif - ip_addr_set_any(IP_IS_V6_VAL(pcb->remote_ip), &pcb->remote_ip); -#if LWIP_IPV4 && LWIP_IPV6 - } -#endif - pcb->remote_port = 0; - pcb->netif_idx = NETIF_NO_INDEX; - /* mark PCB as unconnected */ - udp_clear_flags(pcb, UDP_FLAGS_CONNECTED); -} - -/** - * @ingroup udp_raw - * Set a receive callback for a UDP PCB - * - * This callback will be called when receiving a datagram for the pcb. - * - * @param pcb the pcb for which to set the recv callback - * @param recv function pointer of the callback function - * @param recv_arg additional argument to pass to the callback function - */ -void -udp_recv(struct udp_pcb *pcb, udp_recv_fn recv, void *recv_arg) -{ - LWIP_ASSERT_CORE_LOCKED(); - - /* remember recv() callback and user data */ - pcb->recv = recv; - pcb->recv_arg = recv_arg; -} - -/** - * @ingroup udp_raw - * Remove an UDP PCB. - * - * @param pcb UDP PCB to be removed. The PCB is removed from the list of - * UDP PCB's and the data structure is freed from memory. - * - * @see udp_new() - */ -void -udp_remove(struct udp_pcb *pcb) -{ - struct udp_pcb *pcb2; - - LWIP_ASSERT_CORE_LOCKED(); - - mib2_udp_unbind(pcb); - /* pcb to be removed is first in list? */ - if (udp_pcbs == pcb) { - /* make list start at 2nd pcb */ - udp_pcbs = udp_pcbs->next; - /* pcb not 1st in list */ - } else { - for (pcb2 = udp_pcbs; pcb2 != NULL; pcb2 = pcb2->next) { - /* find pcb in udp_pcbs list */ - if (pcb2->next != NULL && pcb2->next == pcb) { - /* remove pcb from list */ - pcb2->next = pcb->next; - break; - } - } - } - memp_free(MEMP_UDP_PCB, pcb); -} - -/** - * @ingroup udp_raw - * Create a UDP PCB. - * - * @return The UDP PCB which was created. NULL if the PCB data structure - * could not be allocated. - * - * @see udp_remove() - */ -struct udp_pcb * -udp_new(void) -{ - struct udp_pcb *pcb; - - LWIP_ASSERT_CORE_LOCKED(); - - pcb = (struct udp_pcb *)memp_malloc(MEMP_UDP_PCB); - /* could allocate UDP PCB? */ - if (pcb != NULL) { - /* UDP Lite: by initializing to all zeroes, chksum_len is set to 0 - * which means checksum is generated over the whole datagram per default - * (recommended as default by RFC 3828). */ - /* initialize PCB to all zeroes */ - memset(pcb, 0, sizeof(struct udp_pcb)); - pcb->ttl = UDP_TTL; -#if LWIP_MULTICAST_TX_OPTIONS - udp_set_multicast_ttl(pcb, UDP_TTL); -#endif /* LWIP_MULTICAST_TX_OPTIONS */ - } - return pcb; -} - -/** - * @ingroup udp_raw - * Create a UDP PCB for specific IP type. - * - * @param type IP address type, see @ref lwip_ip_addr_type definitions. - * If you want to listen to IPv4 and IPv6 (dual-stack) packets, - * supply @ref IPADDR_TYPE_ANY as argument and bind to @ref IP_ANY_TYPE. - * @return The UDP PCB which was created. NULL if the PCB data structure - * could not be allocated. - * - * @see udp_remove() - */ -struct udp_pcb * -udp_new_ip_type(u8_t type) -{ - struct udp_pcb *pcb; - - LWIP_ASSERT_CORE_LOCKED(); - - pcb = udp_new(); -#if LWIP_IPV4 && LWIP_IPV6 - if (pcb != NULL) { - IP_SET_TYPE_VAL(pcb->local_ip, type); - IP_SET_TYPE_VAL(pcb->remote_ip, type); - } -#else - LWIP_UNUSED_ARG(type); -#endif /* LWIP_IPV4 && LWIP_IPV6 */ - return pcb; -} - -/** This function is called from netif.c when address is changed - * - * @param old_addr IP address of the netif before change - * @param new_addr IP address of the netif after change - */ -void udp_netif_ip_addr_changed(const ip_addr_t* old_addr, const ip_addr_t* new_addr) -{ - struct udp_pcb* upcb; - - if (!ip_addr_isany(old_addr) && !ip_addr_isany(new_addr)) { - for (upcb = udp_pcbs; upcb != NULL; upcb = upcb->next) { - /* PCB bound to current local interface address? */ - if (ip_addr_cmp(&upcb->local_ip, old_addr)) { - /* The PCB is bound to the old ipaddr and - * is set to bound to the new one instead */ - ip_addr_copy(upcb->local_ip, *new_addr); - } - } - } -} - -#if UDP_DEBUG -/** - * Print UDP header information for debug purposes. - * - * @param udphdr pointer to the udp header in memory. - */ -void -udp_debug_print(struct udp_hdr *udphdr) -{ - LWIP_DEBUGF(UDP_DEBUG, ("UDP header:\n")); - LWIP_DEBUGF(UDP_DEBUG, ("+-------------------------------+\n")); - LWIP_DEBUGF(UDP_DEBUG, ("| %5"U16_F" | %5"U16_F" | (src port, dest port)\n", - lwip_ntohs(udphdr->src), lwip_ntohs(udphdr->dest))); - LWIP_DEBUGF(UDP_DEBUG, ("+-------------------------------+\n")); - LWIP_DEBUGF(UDP_DEBUG, ("| %5"U16_F" | 0x%04"X16_F" | (len, chksum)\n", - lwip_ntohs(udphdr->len), lwip_ntohs(udphdr->chksum))); - LWIP_DEBUGF(UDP_DEBUG, ("+-------------------------------+\n")); -} -#endif /* UDP_DEBUG */ - -#endif /* LWIP_UDP */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/api.h b/third_party/lwip/repo/lwip/src/include/lwip/api.h deleted file mode 100644 index 516bd163dd1454..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/api.h +++ /dev/null @@ -1,400 +0,0 @@ -/** - * @file - * netconn API (to be used from non-TCPIP threads) - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_API_H -#define LWIP_HDR_API_H - -#include "lwip/opt.h" - -#if LWIP_NETCONN || LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */ -/* Note: Netconn API is always available when sockets are enabled - - * sockets are implemented on top of them */ - -#include "lwip/arch.h" -#include "lwip/netbuf.h" -#include "lwip/sys.h" -#include "lwip/ip_addr.h" -#include "lwip/err.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* Throughout this file, IP addresses and port numbers are expected to be in - * the same byte order as in the corresponding pcb. - */ - -/* Flags for netconn_write (u8_t) */ -#define NETCONN_NOFLAG 0x00 -#define NETCONN_NOCOPY 0x00 /* Only for source code compatibility */ -#define NETCONN_COPY 0x01 -#define NETCONN_MORE 0x02 -#define NETCONN_DONTBLOCK 0x04 - -/* Flags for struct netconn.flags (u8_t) */ -/** Should this netconn avoid blocking? */ -#define NETCONN_FLAG_NON_BLOCKING 0x02 -/** Was the last connect action a non-blocking one? */ -#define NETCONN_FLAG_IN_NONBLOCKING_CONNECT 0x04 -/** If a nonblocking write has been rejected before, poll_tcp needs to - check if the netconn is writable again */ -#define NETCONN_FLAG_CHECK_WRITESPACE 0x10 -#if LWIP_IPV6 -/** If this flag is set then only IPv6 communication is allowed on the - netconn. As per RFC#3493 this features defaults to OFF allowing - dual-stack usage by default. */ -#define NETCONN_FLAG_IPV6_V6ONLY 0x20 -#endif /* LWIP_IPV6 */ - - -/* Helpers to process several netconn_types by the same code */ -#define NETCONNTYPE_GROUP(t) ((t)&0xF0) -#define NETCONNTYPE_DATAGRAM(t) ((t)&0xE0) -#if LWIP_IPV6 -#define NETCONN_TYPE_IPV6 0x08 -#define NETCONNTYPE_ISIPV6(t) (((t)&NETCONN_TYPE_IPV6) != 0) -#define NETCONNTYPE_ISUDPLITE(t) (((t)&0xF3) == NETCONN_UDPLITE) -#define NETCONNTYPE_ISUDPNOCHKSUM(t) (((t)&0xF3) == NETCONN_UDPNOCHKSUM) -#else /* LWIP_IPV6 */ -#define NETCONNTYPE_ISIPV6(t) (0) -#define NETCONNTYPE_ISUDPLITE(t) ((t) == NETCONN_UDPLITE) -#define NETCONNTYPE_ISUDPNOCHKSUM(t) ((t) == NETCONN_UDPNOCHKSUM) -#endif /* LWIP_IPV6 */ - -/** @ingroup netconn_common - * Protocol family and type of the netconn - */ -enum netconn_type { - NETCONN_INVALID = 0, - /** TCP IPv4 */ - NETCONN_TCP = 0x10, -#if LWIP_IPV6 - /** TCP IPv6 */ - NETCONN_TCP_IPV6 = NETCONN_TCP | NETCONN_TYPE_IPV6 /* 0x18 */, -#endif /* LWIP_IPV6 */ - /** UDP IPv4 */ - NETCONN_UDP = 0x20, - /** UDP IPv4 lite */ - NETCONN_UDPLITE = 0x21, - /** UDP IPv4 no checksum */ - NETCONN_UDPNOCHKSUM = 0x22, - -#if LWIP_IPV6 - /** UDP IPv6 (dual-stack by default, unless you call @ref netconn_set_ipv6only) */ - NETCONN_UDP_IPV6 = NETCONN_UDP | NETCONN_TYPE_IPV6 /* 0x28 */, - /** UDP IPv6 lite (dual-stack by default, unless you call @ref netconn_set_ipv6only) */ - NETCONN_UDPLITE_IPV6 = NETCONN_UDPLITE | NETCONN_TYPE_IPV6 /* 0x29 */, - /** UDP IPv6 no checksum (dual-stack by default, unless you call @ref netconn_set_ipv6only) */ - NETCONN_UDPNOCHKSUM_IPV6 = NETCONN_UDPNOCHKSUM | NETCONN_TYPE_IPV6 /* 0x2a */, -#endif /* LWIP_IPV6 */ - - /** Raw connection IPv4 */ - NETCONN_RAW = 0x40 -#if LWIP_IPV6 - /** Raw connection IPv6 (dual-stack by default, unless you call @ref netconn_set_ipv6only) */ - , NETCONN_RAW_IPV6 = NETCONN_RAW | NETCONN_TYPE_IPV6 /* 0x48 */ -#endif /* LWIP_IPV6 */ -}; - -/** Current state of the netconn. Non-TCP netconns are always - * in state NETCONN_NONE! */ -enum netconn_state { - NETCONN_NONE, - NETCONN_WRITE, - NETCONN_LISTEN, - NETCONN_CONNECT, - NETCONN_CLOSE -}; - -/** Used to inform the callback function about changes - * - * Event explanation: - * - * In the netconn implementation, there are three ways to block a client: - * - * - accept mbox (sys_arch_mbox_fetch(&conn->acceptmbox, &accept_ptr, 0); in netconn_accept()) - * - receive mbox (sys_arch_mbox_fetch(&conn->recvmbox, &buf, 0); in netconn_recv_data()) - * - send queue is full (sys_arch_sem_wait(LWIP_API_MSG_SEM(msg), 0); in lwip_netconn_do_write()) - * - * The events have to be seen as events signaling the state of these mboxes/semaphores. For non-blocking - * connections, you need to know in advance whether a call to a netconn function call would block or not, - * and these events tell you about that. - * - * RCVPLUS events say: Safe to perform a potentially blocking call call once more. - * They are counted in sockets - three RCVPLUS events for accept mbox means you are safe - * to call netconn_accept 3 times without being blocked. - * Same thing for receive mbox. - * - * RCVMINUS events say: Your call to to a possibly blocking function is "acknowledged". - * Socket implementation decrements the counter. - * - * For TX, there is no need to count, its merely a flag. SENDPLUS means you may send something. - * SENDPLUS occurs when enough data was delivered to peer so netconn_send() can be called again. - * A SENDMINUS event occurs when the next call to a netconn_send() would be blocking. - */ -enum netconn_evt { - NETCONN_EVT_RCVPLUS, - NETCONN_EVT_RCVMINUS, - NETCONN_EVT_SENDPLUS, - NETCONN_EVT_SENDMINUS, - NETCONN_EVT_ERROR -}; - -#if LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) -/** Used for netconn_join_leave_group() */ -enum netconn_igmp { - NETCONN_JOIN, - NETCONN_LEAVE -}; -#endif /* LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) */ - -#if LWIP_DNS -/* Used for netconn_gethostbyname_addrtype(), these should match the DNS_ADDRTYPE defines in dns.h */ -#define NETCONN_DNS_DEFAULT NETCONN_DNS_IPV4_IPV6 -#define NETCONN_DNS_IPV4 0 -#define NETCONN_DNS_IPV6 1 -#define NETCONN_DNS_IPV4_IPV6 2 /* try to resolve IPv4 first, try IPv6 if IPv4 fails only */ -#define NETCONN_DNS_IPV6_IPV4 3 /* try to resolve IPv6 first, try IPv4 if IPv6 fails only */ -#endif /* LWIP_DNS */ - -/* forward-declare some structs to avoid to include their headers */ -struct ip_pcb; -struct tcp_pcb; -struct udp_pcb; -struct raw_pcb; -struct netconn; -struct api_msg; - -/** A callback prototype to inform about events for a netconn */ -typedef void (* netconn_callback)(struct netconn *, enum netconn_evt, u16_t len); - -/** A netconn descriptor */ -struct netconn { - /** type of the netconn (TCP, UDP or RAW) */ - enum netconn_type type; - /** current state of the netconn */ - enum netconn_state state; - /** the lwIP internal protocol control block */ - union { - struct ip_pcb *ip; - struct tcp_pcb *tcp; - struct udp_pcb *udp; - struct raw_pcb *raw; - } pcb; - /** the last error this netconn had */ - err_t last_err; -#if !LWIP_NETCONN_SEM_PER_THREAD - /** sem that is used to synchronously execute functions in the core context */ - sys_sem_t op_completed; -#endif - /** mbox where received packets are stored until they are fetched - by the netconn application thread (can grow quite big) */ - sys_mbox_t recvmbox; -#if LWIP_TCP - /** mbox where new connections are stored until processed - by the application thread */ - sys_mbox_t acceptmbox; -#endif /* LWIP_TCP */ - /** only used for socket layer */ -#if LWIP_SOCKET - int socket; -#endif /* LWIP_SOCKET */ -#if LWIP_SO_SNDTIMEO - /** timeout to wait for sending data (which means enqueueing data for sending - in internal buffers) in milliseconds */ - s32_t send_timeout; -#endif /* LWIP_SO_RCVTIMEO */ -#if LWIP_SO_RCVTIMEO - /** timeout in milliseconds to wait for new data to be received - (or connections to arrive for listening netconns) */ - int recv_timeout; -#endif /* LWIP_SO_RCVTIMEO */ -#if LWIP_SO_RCVBUF - /** maximum amount of bytes queued in recvmbox - not used for TCP: adjust TCP_WND instead! */ - int recv_bufsize; - /** number of bytes currently in recvmbox to be received, - tested against recv_bufsize to limit bytes on recvmbox - for UDP and RAW, used for FIONREAD */ - int recv_avail; -#endif /* LWIP_SO_RCVBUF */ -#if LWIP_SO_LINGER - /** values <0 mean linger is disabled, values > 0 are seconds to linger */ - s16_t linger; -#endif /* LWIP_SO_LINGER */ - /** flags holding more netconn-internal state, see NETCONN_FLAG_* defines */ - u8_t flags; -#if LWIP_TCP - /** TCP: when data passed to netconn_write doesn't fit into the send buffer, - this temporarily stores how much is already sent. */ - size_t write_offset; - /** TCP: when data passed to netconn_write doesn't fit into the send buffer, - this temporarily stores the message. - Also used during connect and close. */ - struct api_msg *current_msg; -#endif /* LWIP_TCP */ - /** A callback function that is informed about events for this netconn */ - netconn_callback callback; -}; - -/** Register an Network connection event */ -#define API_EVENT(c,e,l) if (c->callback) { \ - (*c->callback)(c, e, l); \ - } - -/** Set conn->last_err to err but don't overwrite fatal errors */ -#define NETCONN_SET_SAFE_ERR(conn, err) do { if ((conn) != NULL) { \ - SYS_ARCH_DECL_PROTECT(netconn_set_safe_err_lev); \ - SYS_ARCH_PROTECT(netconn_set_safe_err_lev); \ - if (!ERR_IS_FATAL((conn)->last_err)) { \ - (conn)->last_err = err; \ - } \ - SYS_ARCH_UNPROTECT(netconn_set_safe_err_lev); \ -}} while(0); - -/* Network connection functions: */ - -/** @ingroup netconn_common - * Create new netconn connection - * @param t @ref netconn_type */ -#define netconn_new(t) netconn_new_with_proto_and_callback(t, 0, NULL) -#define netconn_new_with_callback(t, c) netconn_new_with_proto_and_callback(t, 0, c) -struct netconn *netconn_new_with_proto_and_callback(enum netconn_type t, u8_t proto, - netconn_callback callback); -err_t netconn_delete(struct netconn *conn); -/** Get the type of a netconn (as enum netconn_type). */ -#define netconn_type(conn) (conn->type) - -err_t netconn_getaddr(struct netconn *conn, ip_addr_t *addr, - u16_t *port, u8_t local); -/** @ingroup netconn_common */ -#define netconn_peer(c,i,p) netconn_getaddr(c,i,p,0) -/** @ingroup netconn_common */ -#define netconn_addr(c,i,p) netconn_getaddr(c,i,p,1) - -err_t netconn_bind(struct netconn *conn, const ip_addr_t *addr, u16_t port); -err_t netconn_connect(struct netconn *conn, const ip_addr_t *addr, u16_t port); -err_t netconn_disconnect (struct netconn *conn); -err_t netconn_listen_with_backlog(struct netconn *conn, u8_t backlog); -/** @ingroup netconn_tcp */ -#define netconn_listen(conn) netconn_listen_with_backlog(conn, TCP_DEFAULT_LISTEN_BACKLOG) -err_t netconn_accept(struct netconn *conn, struct netconn **new_conn); -err_t netconn_recv(struct netconn *conn, struct netbuf **new_buf); -err_t netconn_recv_tcp_pbuf(struct netconn *conn, struct pbuf **new_buf); -err_t netconn_sendto(struct netconn *conn, struct netbuf *buf, - const ip_addr_t *addr, u16_t port); -err_t netconn_send(struct netconn *conn, struct netbuf *buf); -err_t netconn_write_partly(struct netconn *conn, const void *dataptr, size_t size, - u8_t apiflags, size_t *bytes_written); -/** @ingroup netconn_tcp */ -#define netconn_write(conn, dataptr, size, apiflags) \ - netconn_write_partly(conn, dataptr, size, apiflags, NULL) -err_t netconn_close(struct netconn *conn); -err_t netconn_shutdown(struct netconn *conn, u8_t shut_rx, u8_t shut_tx); - -#if LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) -err_t netconn_join_leave_group(struct netconn *conn, const ip_addr_t *multiaddr, - const ip_addr_t *netif_addr, enum netconn_igmp join_or_leave); -#endif /* LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) */ -#if LWIP_DNS -#if LWIP_IPV4 && LWIP_IPV6 -err_t netconn_gethostbyname_addrtype(const char *name, ip_addr_t *addr, u8_t dns_addrtype); -#define netconn_gethostbyname(name, addr) netconn_gethostbyname_addrtype(name, addr, NETCONN_DNS_DEFAULT) -#else /* LWIP_IPV4 && LWIP_IPV6 */ -err_t netconn_gethostbyname(const char *name, ip_addr_t *addr); -#define netconn_gethostbyname_addrtype(name, addr, dns_addrtype) netconn_gethostbyname(name, addr) -#endif /* LWIP_IPV4 && LWIP_IPV6 */ -#endif /* LWIP_DNS */ - -#define netconn_err(conn) ((conn)->last_err) -#define netconn_recv_bufsize(conn) ((conn)->recv_bufsize) - -/** Set the blocking status of netconn calls (@todo: write/send is missing) */ -#define netconn_set_nonblocking(conn, val) do { if(val) { \ - (conn)->flags |= NETCONN_FLAG_NON_BLOCKING; \ -} else { \ - (conn)->flags &= ~ NETCONN_FLAG_NON_BLOCKING; }} while(0) -/** Get the blocking status of netconn calls (@todo: write/send is missing) */ -#define netconn_is_nonblocking(conn) (((conn)->flags & NETCONN_FLAG_NON_BLOCKING) != 0) - -#if LWIP_IPV6 -/** @ingroup netconn_common - * TCP: Set the IPv6 ONLY status of netconn calls (see NETCONN_FLAG_IPV6_V6ONLY) - */ -#define netconn_set_ipv6only(conn, val) do { if(val) { \ - (conn)->flags |= NETCONN_FLAG_IPV6_V6ONLY; \ -} else { \ - (conn)->flags &= ~ NETCONN_FLAG_IPV6_V6ONLY; }} while(0) -/** @ingroup netconn_common - * TCP: Get the IPv6 ONLY status of netconn calls (see NETCONN_FLAG_IPV6_V6ONLY) - */ -#define netconn_get_ipv6only(conn) (((conn)->flags & NETCONN_FLAG_IPV6_V6ONLY) != 0) -#endif /* LWIP_IPV6 */ - -#if LWIP_SO_SNDTIMEO -/** Set the send timeout in milliseconds */ -#define netconn_set_sendtimeout(conn, timeout) ((conn)->send_timeout = (timeout)) -/** Get the send timeout in milliseconds */ -#define netconn_get_sendtimeout(conn) ((conn)->send_timeout) -#endif /* LWIP_SO_SNDTIMEO */ -#if LWIP_SO_RCVTIMEO -/** Set the receive timeout in milliseconds */ -#define netconn_set_recvtimeout(conn, timeout) ((conn)->recv_timeout = (timeout)) -/** Get the receive timeout in milliseconds */ -#define netconn_get_recvtimeout(conn) ((conn)->recv_timeout) -#endif /* LWIP_SO_RCVTIMEO */ -#if LWIP_SO_RCVBUF -/** Set the receive buffer in bytes */ -#define netconn_set_recvbufsize(conn, recvbufsize) ((conn)->recv_bufsize = (recvbufsize)) -/** Get the receive buffer in bytes */ -#define netconn_get_recvbufsize(conn) ((conn)->recv_bufsize) -#endif /* LWIP_SO_RCVBUF*/ - -#if LWIP_NETCONN_SEM_PER_THREAD -void netconn_thread_init(void); -void netconn_thread_cleanup(void); -#else /* LWIP_NETCONN_SEM_PER_THREAD */ -#define netconn_thread_init() -#define netconn_thread_cleanup() -#endif /* LWIP_NETCONN_SEM_PER_THREAD */ - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_NETCONN || LWIP_SOCKET */ - -#endif /* LWIP_HDR_API_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/apps/FILES b/third_party/lwip/repo/lwip/src/include/lwip/apps/FILES deleted file mode 100644 index adfc0f33450c6b..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/apps/FILES +++ /dev/null @@ -1,2 +0,0 @@ -This directory contains application headers. -Every application shall provide one api file APP.h and optionally one options file APP_opts.h diff --git a/third_party/lwip/repo/lwip/src/include/lwip/apps/fs.h b/third_party/lwip/repo/lwip/src/include/lwip/apps/fs.h deleted file mode 100644 index bb176fa010716f..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/apps/fs.h +++ /dev/null @@ -1,103 +0,0 @@ -/* - * Copyright (c) 2001-2003 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_APPS_FS_H -#define LWIP_HDR_APPS_FS_H - -#include "httpd_opts.h" -#include "lwip/err.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define FS_READ_EOF -1 -#define FS_READ_DELAYED -2 - -#if HTTPD_PRECALCULATED_CHECKSUM -struct fsdata_chksum { - u32_t offset; - u16_t chksum; - u16_t len; -}; -#endif /* HTTPD_PRECALCULATED_CHECKSUM */ - -#define FS_FILE_FLAGS_HEADER_INCLUDED 0x01 -#define FS_FILE_FLAGS_HEADER_PERSISTENT 0x02 - -struct fs_file { - const char *data; - int len; - int index; - void *pextension; -#if HTTPD_PRECALCULATED_CHECKSUM - const struct fsdata_chksum *chksum; - u16_t chksum_count; -#endif /* HTTPD_PRECALCULATED_CHECKSUM */ - u8_t flags; -#if LWIP_HTTPD_CUSTOM_FILES - u8_t is_custom_file; -#endif /* LWIP_HTTPD_CUSTOM_FILES */ -#if LWIP_HTTPD_FILE_STATE - void *state; -#endif /* LWIP_HTTPD_FILE_STATE */ -}; - -#if LWIP_HTTPD_FS_ASYNC_READ -typedef void (*fs_wait_cb)(void *arg); -#endif /* LWIP_HTTPD_FS_ASYNC_READ */ - -err_t fs_open(struct fs_file *file, const char *name); -void fs_close(struct fs_file *file); -#if LWIP_HTTPD_DYNAMIC_FILE_READ -#if LWIP_HTTPD_FS_ASYNC_READ -int fs_read_async(struct fs_file *file, char *buffer, int count, fs_wait_cb callback_fn, void *callback_arg); -#else /* LWIP_HTTPD_FS_ASYNC_READ */ -int fs_read(struct fs_file *file, char *buffer, int count); -#endif /* LWIP_HTTPD_FS_ASYNC_READ */ -#endif /* LWIP_HTTPD_DYNAMIC_FILE_READ */ -#if LWIP_HTTPD_FS_ASYNC_READ -int fs_is_file_ready(struct fs_file *file, fs_wait_cb callback_fn, void *callback_arg); -#endif /* LWIP_HTTPD_FS_ASYNC_READ */ -int fs_bytes_left(struct fs_file *file); - -#if LWIP_HTTPD_FILE_STATE -/** This user-defined function is called when a file is opened. */ -void *fs_state_init(struct fs_file *file, const char *name); -/** This user-defined function is called when a file is closed. */ -void fs_state_free(struct fs_file *file, void *state); -#endif /* #if LWIP_HTTPD_FILE_STATE */ - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_APPS_FS_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/apps/httpd.h b/third_party/lwip/repo/lwip/src/include/lwip/apps/httpd.h deleted file mode 100644 index 40f1811e574bc5..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/apps/httpd.h +++ /dev/null @@ -1,236 +0,0 @@ -/** - * @file - * HTTP server - */ - -/* - * Copyright (c) 2001-2003 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - * This version of the file has been modified by Texas Instruments to offer - * simple server-side-include (SSI) and Common Gateway Interface (CGI) - * capability. - */ - -#ifndef LWIP_HDR_APPS_HTTPD_H -#define LWIP_HDR_APPS_HTTPD_H - -#include "httpd_opts.h" -#include "lwip/err.h" -#include "lwip/pbuf.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#if LWIP_HTTPD_CGI - -/* - * Function pointer for a CGI script handler. - * - * This function is called each time the HTTPD server is asked for a file - * whose name was previously registered as a CGI function using a call to - * http_set_cgi_handler. The iIndex parameter provides the index of the - * CGI within the ppcURLs array passed to http_set_cgi_handler. Parameters - * pcParam and pcValue provide access to the parameters provided along with - * the URI. iNumParams provides a count of the entries in the pcParam and - * pcValue arrays. Each entry in the pcParam array contains the name of a - * parameter with the corresponding entry in the pcValue array containing the - * value for that parameter. Note that pcParam may contain multiple elements - * with the same name if, for example, a multi-selection list control is used - * in the form generating the data. - * - * The function should return a pointer to a character string which is the - * path and filename of the response that is to be sent to the connected - * browser, for example "/thanks.htm" or "/response/error.ssi". - * - * The maximum number of parameters that will be passed to this function via - * iNumParams is defined by LWIP_HTTPD_MAX_CGI_PARAMETERS. Any parameters in the incoming - * HTTP request above this number will be discarded. - * - * Requests intended for use by this CGI mechanism must be sent using the GET - * method (which encodes all parameters within the URI rather than in a block - * later in the request). Attempts to use the POST method will result in the - * request being ignored. - * - */ -typedef const char *(*tCGIHandler)(int iIndex, int iNumParams, char *pcParam[], - char *pcValue[]); - -/* - * Structure defining the base filename (URL) of a CGI and the associated - * function which is to be called when that URL is requested. - */ -typedef struct -{ - const char *pcCGIName; - tCGIHandler pfnCGIHandler; -} tCGI; - -void http_set_cgi_handlers(const tCGI *pCGIs, int iNumHandlers); - -#endif /* LWIP_HTTPD_CGI */ - -#if LWIP_HTTPD_CGI || LWIP_HTTPD_CGI_SSI - -#if LWIP_HTTPD_CGI_SSI -/** Define this generic CGI handler in your application. - * It is called once for every URI with parameters. - * The parameters can be stored to - */ -extern void httpd_cgi_handler(const char* uri, int iNumParams, char **pcParam, char **pcValue -#if defined(LWIP_HTTPD_FILE_STATE) && LWIP_HTTPD_FILE_STATE - , void *connection_state -#endif /* LWIP_HTTPD_FILE_STATE */ - ); -#endif /* LWIP_HTTPD_CGI_SSI */ - -#endif /* LWIP_HTTPD_CGI || LWIP_HTTPD_CGI_SSI */ - -#if LWIP_HTTPD_SSI - -/* - * Function pointer for the SSI tag handler callback. - * - * This function will be called each time the HTTPD server detects a tag of the - * form in a .shtml, .ssi or .shtm file where "name" appears as - * one of the tags supplied to http_set_ssi_handler in the ppcTags array. The - * returned insert string, which will be appended after the the string - * "" in file sent back to the client,should be written to pointer - * pcInsert. iInsertLen contains the size of the buffer pointed to by - * pcInsert. The iIndex parameter provides the zero-based index of the tag as - * found in the ppcTags array and identifies the tag that is to be processed. - * - * The handler returns the number of characters written to pcInsert excluding - * any terminating NULL or a negative number to indicate a failure (tag not - * recognized, for example). - * - * Note that the behavior of this SSI mechanism is somewhat different from the - * "normal" SSI processing as found in, for example, the Apache web server. In - * this case, the inserted text is appended following the SSI tag rather than - * replacing the tag entirely. This allows for an implementation that does not - * require significant additional buffering of output data yet which will still - * offer usable SSI functionality. One downside to this approach is when - * attempting to use SSI within JavaScript. The SSI tag is structured to - * resemble an HTML comment but this syntax does not constitute a comment - * within JavaScript and, hence, leaving the tag in place will result in - * problems in these cases. To work around this, any SSI tag which needs to - * output JavaScript code must do so in an encapsulated way, sending the whole - * HTML section as a single include. - */ -typedef u16_t (*tSSIHandler)( -#if LWIP_HTTPD_SSI_RAW - const char* ssi_tag_name, -#else /* LWIP_HTTPD_SSI_RAW */ - int iIndex, -#endif /* LWIP_HTTPD_SSI_RAW */ - char *pcInsert, int iInsertLen -#if LWIP_HTTPD_SSI_MULTIPART - , u16_t current_tag_part, u16_t *next_tag_part -#endif /* LWIP_HTTPD_SSI_MULTIPART */ -#if defined(LWIP_HTTPD_FILE_STATE) && LWIP_HTTPD_FILE_STATE - , void *connection_state -#endif /* LWIP_HTTPD_FILE_STATE */ - ); - -/** Set the SSI handler function - * (if LWIP_HTTPD_SSI_RAW==1, only the first argument is used) - */ -void http_set_ssi_handler(tSSIHandler pfnSSIHandler, - const char **ppcTags, int iNumTags); - -/** For LWIP_HTTPD_SSI_RAW==1, return this to indicate the tag is unknown. - * In this case, the webserver writes a warning into the page. - * You can also just return 0 to write nothing for unknown tags. - */ -#define HTTPD_SSI_TAG_UNKNOWN 0xFFFF - -#endif /* LWIP_HTTPD_SSI */ - -#if LWIP_HTTPD_SUPPORT_POST - -/* These functions must be implemented by the application */ - -/** Called when a POST request has been received. The application can decide - * whether to accept it or not. - * - * @param connection Unique connection identifier, valid until httpd_post_end - * is called. - * @param uri The HTTP header URI receiving the POST request. - * @param http_request The raw HTTP request (the first packet, normally). - * @param http_request_len Size of 'http_request'. - * @param content_len Content-Length from HTTP header. - * @param response_uri Filename of response file, to be filled when denying the - * request - * @param response_uri_len Size of the 'response_uri' buffer. - * @param post_auto_wnd Set this to 0 to let the callback code handle window - * updates by calling 'httpd_post_data_recved' (to throttle rx speed) - * default is 1 (httpd handles window updates automatically) - * @return ERR_OK: Accept the POST request, data may be passed in - * another err_t: Deny the POST request, send back 'bad request'. - */ -err_t httpd_post_begin(void *connection, const char *uri, const char *http_request, - u16_t http_request_len, int content_len, char *response_uri, - u16_t response_uri_len, u8_t *post_auto_wnd); - -/** Called for each pbuf of data that has been received for a POST. - * ATTENTION: The application is responsible for freeing the pbufs passed in! - * - * @param connection Unique connection identifier. - * @param p Received data. - * @return ERR_OK: Data accepted. - * another err_t: Data denied, http_post_get_response_uri will be called. - */ -err_t httpd_post_receive_data(void *connection, struct pbuf *p); - -/** Called when all data is received or when the connection is closed. - * The application must return the filename/URI of a file to send in response - * to this POST request. If the response_uri buffer is untouched, a 404 - * response is returned. - * - * @param connection Unique connection identifier. - * @param response_uri Filename of response file, to be filled when denying the request - * @param response_uri_len Size of the 'response_uri' buffer. - */ -void httpd_post_finished(void *connection, char *response_uri, u16_t response_uri_len); - -#if LWIP_HTTPD_POST_MANUAL_WND -void httpd_post_data_recved(void *connection, u16_t recved_len); -#endif /* LWIP_HTTPD_POST_MANUAL_WND */ - -#endif /* LWIP_HTTPD_SUPPORT_POST */ - -void httpd_init(void); - - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HTTPD_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/apps/httpd_opts.h b/third_party/lwip/repo/lwip/src/include/lwip/apps/httpd_opts.h deleted file mode 100644 index 340db15f6630f2..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/apps/httpd_opts.h +++ /dev/null @@ -1,323 +0,0 @@ -/** - * @file - * HTTP server options list - */ - -/* - * Copyright (c) 2001-2003 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - * This version of the file has been modified by Texas Instruments to offer - * simple server-side-include (SSI) and Common Gateway Interface (CGI) - * capability. - */ - -#ifndef LWIP_HDR_APPS_HTTPD_OPTS_H -#define LWIP_HDR_APPS_HTTPD_OPTS_H - -#include "lwip/opt.h" - -/** - * @defgroup httpd_opts Options - * @ingroup httpd - * @{ - */ - -/** Set this to 1 to support CGI (old style) */ -#if !defined LWIP_HTTPD_CGI || defined __DOXYGEN__ -#define LWIP_HTTPD_CGI 0 -#endif - -/** Set this to 1 to support CGI (new style) */ -#if !defined LWIP_HTTPD_CGI_SSI || defined __DOXYGEN__ -#define LWIP_HTTPD_CGI_SSI 0 -#endif - -/** Set this to 1 to support SSI (Server-Side-Includes) */ -#if !defined LWIP_HTTPD_SSI || defined __DOXYGEN__ -#define LWIP_HTTPD_SSI 0 -#endif - -/** Set this to 1 to implement an SSI tag handler callback that gets a const char* - * to the tag (instead of an index into a pre-registered array of known tags) */ -#if !defined LWIP_HTTPD_SSI_RAW || defined __DOXYGEN__ -#define LWIP_HTTPD_SSI_RAW 0 -#endif - -/** Set this to 1 to support HTTP POST */ -#if !defined LWIP_HTTPD_SUPPORT_POST || defined __DOXYGEN__ -#define LWIP_HTTPD_SUPPORT_POST 0 -#endif - -/* The maximum number of parameters that the CGI handler can be sent. */ -#if !defined LWIP_HTTPD_MAX_CGI_PARAMETERS || defined __DOXYGEN__ -#define LWIP_HTTPD_MAX_CGI_PARAMETERS 16 -#endif - -/** LWIP_HTTPD_SSI_MULTIPART==1: SSI handler function is called with 2 more - * arguments indicating a counter for insert string that are too long to be - * inserted at once: the SSI handler function must then set 'next_tag_part' - * which will be passed back to it in the next call. */ -#if !defined LWIP_HTTPD_SSI_MULTIPART || defined __DOXYGEN__ -#define LWIP_HTTPD_SSI_MULTIPART 0 -#endif - -/* The maximum length of the string comprising the tag name */ -#if !defined LWIP_HTTPD_MAX_TAG_NAME_LEN || defined __DOXYGEN__ -#define LWIP_HTTPD_MAX_TAG_NAME_LEN 8 -#endif - -/* The maximum length of string that can be returned to replace any given tag */ -#if !defined LWIP_HTTPD_MAX_TAG_INSERT_LEN || defined __DOXYGEN__ -#define LWIP_HTTPD_MAX_TAG_INSERT_LEN 192 -#endif - -#if !defined LWIP_HTTPD_POST_MANUAL_WND || defined __DOXYGEN__ -#define LWIP_HTTPD_POST_MANUAL_WND 0 -#endif - -/** This string is passed in the HTTP header as "Server: " */ -#if !defined HTTPD_SERVER_AGENT || defined __DOXYGEN__ -#define HTTPD_SERVER_AGENT "lwIP/" LWIP_VERSION_STRING " (http://savannah.nongnu.org/projects/lwip)" -#endif - -/** Set this to 1 if you want to include code that creates HTTP headers - * at runtime. Default is off: HTTP headers are then created statically - * by the makefsdata tool. Static headers mean smaller code size, but - * the (readonly) fsdata will grow a bit as every file includes the HTTP - * header. */ -#if !defined LWIP_HTTPD_DYNAMIC_HEADERS || defined __DOXYGEN__ -#define LWIP_HTTPD_DYNAMIC_HEADERS 0 -#endif - -#if !defined HTTPD_DEBUG || defined __DOXYGEN__ -#define HTTPD_DEBUG LWIP_DBG_OFF -#endif - -/** Set this to 1 to use a memp pool for allocating - * struct http_state instead of the heap. - */ -#if !defined HTTPD_USE_MEM_POOL || defined __DOXYGEN__ -#define HTTPD_USE_MEM_POOL 0 -#endif - -/** The server port for HTTPD to use */ -#if !defined HTTPD_SERVER_PORT || defined __DOXYGEN__ -#define HTTPD_SERVER_PORT 80 -#endif - -/** Maximum retries before the connection is aborted/closed. - * - number of times pcb->poll is called -> default is 4*500ms = 2s; - * - reset when pcb->sent is called - */ -#if !defined HTTPD_MAX_RETRIES || defined __DOXYGEN__ -#define HTTPD_MAX_RETRIES 4 -#endif - -/** The poll delay is X*500ms */ -#if !defined HTTPD_POLL_INTERVAL || defined __DOXYGEN__ -#define HTTPD_POLL_INTERVAL 4 -#endif - -/** Priority for tcp pcbs created by HTTPD (very low by default). - * Lower priorities get killed first when running out of memory. - */ -#if !defined HTTPD_TCP_PRIO || defined __DOXYGEN__ -#define HTTPD_TCP_PRIO TCP_PRIO_MIN -#endif - -/** Set this to 1 to enable timing each file sent */ -#if !defined LWIP_HTTPD_TIMING || defined __DOXYGEN__ -#define LWIP_HTTPD_TIMING 0 -#endif -/** Set this to 1 to enable timing each file sent */ -#if !defined HTTPD_DEBUG_TIMING || defined __DOXYGEN__ -#define HTTPD_DEBUG_TIMING LWIP_DBG_OFF -#endif - -/** Set this to one to show error pages when parsing a request fails instead - of simply closing the connection. */ -#if !defined LWIP_HTTPD_SUPPORT_EXTSTATUS || defined __DOXYGEN__ -#define LWIP_HTTPD_SUPPORT_EXTSTATUS 0 -#endif - -/** Set this to 0 to drop support for HTTP/0.9 clients (to save some bytes) */ -#if !defined LWIP_HTTPD_SUPPORT_V09 || defined __DOXYGEN__ -#define LWIP_HTTPD_SUPPORT_V09 1 -#endif - -/** Set this to 1 to enable HTTP/1.1 persistent connections. - * ATTENTION: If the generated file system includes HTTP headers, these must - * include the "Connection: keep-alive" header (pass argument "-11" to makefsdata). - */ -#if !defined LWIP_HTTPD_SUPPORT_11_KEEPALIVE || defined __DOXYGEN__ -#define LWIP_HTTPD_SUPPORT_11_KEEPALIVE 0 -#endif - -/** Set this to 1 to support HTTP request coming in in multiple packets/pbufs */ -#if !defined LWIP_HTTPD_SUPPORT_REQUESTLIST || defined __DOXYGEN__ -#define LWIP_HTTPD_SUPPORT_REQUESTLIST 1 -#endif - -#if LWIP_HTTPD_SUPPORT_REQUESTLIST -/** Number of rx pbufs to enqueue to parse an incoming request (up to the first - newline) */ -#if !defined LWIP_HTTPD_REQ_QUEUELEN || defined __DOXYGEN__ -#define LWIP_HTTPD_REQ_QUEUELEN 5 -#endif - -/** Number of (TCP payload-) bytes (in pbufs) to enqueue to parse and incoming - request (up to the first double-newline) */ -#if !defined LWIP_HTTPD_REQ_BUFSIZE || defined __DOXYGEN__ -#define LWIP_HTTPD_REQ_BUFSIZE LWIP_HTTPD_MAX_REQ_LENGTH -#endif - -/** Defines the maximum length of a HTTP request line (up to the first CRLF, - copied from pbuf into this a global buffer when pbuf- or packet-queues - are received - otherwise the input pbuf is used directly) */ -#if !defined LWIP_HTTPD_MAX_REQ_LENGTH || defined __DOXYGEN__ -#define LWIP_HTTPD_MAX_REQ_LENGTH LWIP_MIN(1023, (LWIP_HTTPD_REQ_QUEUELEN * PBUF_POOL_BUFSIZE)) -#endif -#endif /* LWIP_HTTPD_SUPPORT_REQUESTLIST */ - -/** This is the size of a static buffer used when URIs end with '/'. - * In this buffer, the directory requested is concatenated with all the - * configured default file names. - * Set to 0 to disable checking default filenames on non-root directories. - */ -#if !defined LWIP_HTTPD_MAX_REQUEST_URI_LEN || defined __DOXYGEN__ -#define LWIP_HTTPD_MAX_REQUEST_URI_LEN 63 -#endif - -/** Maximum length of the filename to send as response to a POST request, - * filled in by the application when a POST is finished. - */ -#if !defined LWIP_HTTPD_POST_MAX_RESPONSE_URI_LEN || defined __DOXYGEN__ -#define LWIP_HTTPD_POST_MAX_RESPONSE_URI_LEN 63 -#endif - -/** Set this to 0 to not send the SSI tag (default is on, so the tag will - * be sent in the HTML page */ -#if !defined LWIP_HTTPD_SSI_INCLUDE_TAG || defined __DOXYGEN__ -#define LWIP_HTTPD_SSI_INCLUDE_TAG 1 -#endif - -/** Set this to 1 to call tcp_abort when tcp_close fails with memory error. - * This can be used to prevent consuming all memory in situations where the - * HTTP server has low priority compared to other communication. */ -#if !defined LWIP_HTTPD_ABORT_ON_CLOSE_MEM_ERROR || defined __DOXYGEN__ -#define LWIP_HTTPD_ABORT_ON_CLOSE_MEM_ERROR 0 -#endif - -/** Set this to 1 to kill the oldest connection when running out of - * memory for 'struct http_state' or 'struct http_ssi_state'. - * ATTENTION: This puts all connections on a linked list, so may be kind of slow. - */ -#if !defined LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED || defined __DOXYGEN__ -#define LWIP_HTTPD_KILL_OLD_ON_CONNECTIONS_EXCEEDED 0 -#endif - -/** Set this to 1 to send URIs without extension without headers - * (who uses this at all??) */ -#if !defined LWIP_HTTPD_OMIT_HEADER_FOR_EXTENSIONLESS_URI || defined __DOXYGEN__ -#define LWIP_HTTPD_OMIT_HEADER_FOR_EXTENSIONLESS_URI 0 -#endif - -/** Default: Tags are sent from struct http_state and are therefore volatile */ -#if !defined HTTP_IS_TAG_VOLATILE || defined __DOXYGEN__ -#define HTTP_IS_TAG_VOLATILE(ptr) TCP_WRITE_FLAG_COPY -#endif - -/* By default, the httpd is limited to send 2*pcb->mss to keep resource usage low - when http is not an important protocol in the device. */ -#if !defined HTTPD_LIMIT_SENDING_TO_2MSS || defined __DOXYGEN__ -#define HTTPD_LIMIT_SENDING_TO_2MSS 1 -#endif - -/* Define this to a function that returns the maximum amount of data to enqueue. - The function have this signature: u16_t fn(struct tcp_pcb* pcb); */ -#if !defined HTTPD_MAX_WRITE_LEN || defined __DOXYGEN__ -#if HTTPD_LIMIT_SENDING_TO_2MSS -#define HTTPD_MAX_WRITE_LEN(pcb) (2 * tcp_mss(pcb)) -#endif -#endif - -/*------------------- FS OPTIONS -------------------*/ - -/** Set this to 1 and provide the functions: - * - "int fs_open_custom(struct fs_file *file, const char *name)" - * Called first for every opened file to allow opening files - * that are not included in fsdata(_custom).c - * - "void fs_close_custom(struct fs_file *file)" - * Called to free resources allocated by fs_open_custom(). - */ -#if !defined LWIP_HTTPD_CUSTOM_FILES || defined __DOXYGEN__ -#define LWIP_HTTPD_CUSTOM_FILES 0 -#endif - -/** Set this to 1 to support fs_read() to dynamically read file data. - * Without this (default=off), only one-block files are supported, - * and the contents must be ready after fs_open(). - */ -#if !defined LWIP_HTTPD_DYNAMIC_FILE_READ || defined __DOXYGEN__ -#define LWIP_HTTPD_DYNAMIC_FILE_READ 0 -#endif - -/** Set this to 1 to include an application state argument per file - * that is opened. This allows to keep a state per connection/file. - */ -#if !defined LWIP_HTTPD_FILE_STATE || defined __DOXYGEN__ -#define LWIP_HTTPD_FILE_STATE 0 -#endif - -/** HTTPD_PRECALCULATED_CHECKSUM==1: include precompiled checksums for - * predefined (MSS-sized) chunks of the files to prevent having to calculate - * the checksums at runtime. */ -#if !defined HTTPD_PRECALCULATED_CHECKSUM || defined __DOXYGEN__ -#define HTTPD_PRECALCULATED_CHECKSUM 0 -#endif - -/** LWIP_HTTPD_FS_ASYNC_READ==1: support asynchronous read operations - * (fs_read_async returns FS_READ_DELAYED and calls a callback when finished). - */ -#if !defined LWIP_HTTPD_FS_ASYNC_READ || defined __DOXYGEN__ -#define LWIP_HTTPD_FS_ASYNC_READ 0 -#endif - -/** Set this to 1 to include "fsdata_custom.c" instead of "fsdata.c" for the - * file system (to prevent changing the file included in CVS) */ -#if !defined HTTPD_USE_CUSTOM_FSDATA || defined __DOXYGEN__ -#define HTTPD_USE_CUSTOM_FSDATA 0 -#endif - -/** - * @} - */ - -#endif /* LWIP_HDR_APPS_HTTPD_OPTS_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/apps/lwiperf.h b/third_party/lwip/repo/lwip/src/include/lwip/apps/lwiperf.h deleted file mode 100644 index 7dbebb08264d89..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/apps/lwiperf.h +++ /dev/null @@ -1,84 +0,0 @@ -/** - * @file - * lwIP iPerf server implementation - */ - -/* - * Copyright (c) 2014 Simon Goldschmidt - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Simon Goldschmidt - * - */ -#ifndef LWIP_HDR_APPS_LWIPERF_H -#define LWIP_HDR_APPS_LWIPERF_H - -#include "lwip/opt.h" -#include "lwip/ip_addr.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define LWIPERF_TCP_PORT_DEFAULT 5001 - -/** lwIPerf test results */ -enum lwiperf_report_type -{ - /** The server side test is done */ - LWIPERF_TCP_DONE_SERVER, - /** The client side test is done */ - LWIPERF_TCP_DONE_CLIENT, - /** Local error lead to test abort */ - LWIPERF_TCP_ABORTED_LOCAL, - /** Data check error lead to test abort */ - LWIPERF_TCP_ABORTED_LOCAL_DATAERROR, - /** Transmit error lead to test abort */ - LWIPERF_TCP_ABORTED_LOCAL_TXERROR, - /** Remote side aborted the test */ - LWIPERF_TCP_ABORTED_REMOTE -}; - -/** Prototype of a report function that is called when a session is finished. - This report function can show the test results. - @param report_type contains the test result */ -typedef void (*lwiperf_report_fn)(void *arg, enum lwiperf_report_type report_type, - const ip_addr_t* local_addr, u16_t local_port, const ip_addr_t* remote_addr, u16_t remote_port, - u32_t bytes_transferred, u32_t ms_duration, u32_t bandwidth_kbitpsec); - - -void* lwiperf_start_tcp_server(const ip_addr_t* local_addr, u16_t local_port, - lwiperf_report_fn report_fn, void* report_arg); -void* lwiperf_start_tcp_server_default(lwiperf_report_fn report_fn, void* report_arg); -void lwiperf_abort(void* lwiperf_session); - - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_APPS_LWIPERF_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/apps/mdns.h b/third_party/lwip/repo/lwip/src/include/lwip/apps/mdns.h deleted file mode 100644 index d036816115d5e5..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/apps/mdns.h +++ /dev/null @@ -1,69 +0,0 @@ -/** - * @file - * MDNS responder - */ - - /* - * Copyright (c) 2015 Verisure Innovation AB - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Erik Ekman - * - */ -#ifndef LWIP_HDR_MDNS_H -#define LWIP_HDR_MDNS_H - -#include "lwip/apps/mdns_opts.h" -#include "lwip/netif.h" - -#if LWIP_MDNS_RESPONDER - -enum mdns_sd_proto { - DNSSD_PROTO_UDP = 0, - DNSSD_PROTO_TCP = 1 -}; - -#define MDNS_LABEL_MAXLEN 63 - -struct mdns_host; -struct mdns_service; - -/** Callback function to add text to a reply, called when generating the reply */ -typedef void (*service_get_txt_fn_t)(struct mdns_service *service, void *txt_userdata); - -void mdns_resp_init(void); - -err_t mdns_resp_add_netif(struct netif *netif, const char *hostname, u32_t dns_ttl); -err_t mdns_resp_remove_netif(struct netif *netif); - -err_t mdns_resp_add_service(struct netif *netif, const char *name, const char *service, enum mdns_sd_proto proto, u16_t port, u32_t dns_ttl, service_get_txt_fn_t txt_fn, void *txt_userdata); -err_t mdns_resp_add_service_txtitem(struct mdns_service *service, const char *txt, u8_t txt_len); -void mdns_resp_netif_settings_changed(struct netif *netif); - -#endif /* LWIP_MDNS_RESPONDER */ - -#endif /* LWIP_HDR_MDNS_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/apps/mdns_opts.h b/third_party/lwip/repo/lwip/src/include/lwip/apps/mdns_opts.h deleted file mode 100644 index bf186bcce17396..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/apps/mdns_opts.h +++ /dev/null @@ -1,74 +0,0 @@ -/** - * @file - * MDNS responder - */ - - /* - * Copyright (c) 2015 Verisure Innovation AB - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Erik Ekman - * - */ - -#ifndef LWIP_HDR_APPS_MDNS_OPTS_H -#define LWIP_HDR_APPS_MDNS_OPTS_H - -#include "lwip/opt.h" - -/** - * @defgroup mdns_opts Options - * @ingroup mdns - * @{ - */ - -/** - * LWIP_MDNS_RESPONDER==1: Turn on multicast DNS module. UDP must be available for MDNS - * transport. IGMP is needed for IPv4 multicast. - */ -#ifndef LWIP_MDNS_RESPONDER -#define LWIP_MDNS_RESPONDER 0 -#endif /* LWIP_MDNS_RESPONDER */ - -/** The maximum number of services per netif */ -#ifndef MDNS_MAX_SERVICES -#define MDNS_MAX_SERVICES 1 -#endif - -/** - * MDNS_DEBUG: Enable debugging for multicast DNS. - */ -#ifndef MDNS_DEBUG -#define MDNS_DEBUG LWIP_DBG_OFF -#endif - -/** - * @} - */ - -#endif /* LWIP_HDR_APPS_MDNS_OPTS_H */ - diff --git a/third_party/lwip/repo/lwip/src/include/lwip/apps/mdns_priv.h b/third_party/lwip/repo/lwip/src/include/lwip/apps/mdns_priv.h deleted file mode 100644 index 8ee6db86af4ccb..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/apps/mdns_priv.h +++ /dev/null @@ -1,66 +0,0 @@ -/** - * @file - * MDNS responder private definitions - */ - - /* - * Copyright (c) 2015 Verisure Innovation AB - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Erik Ekman - * - */ -#ifndef LWIP_HDR_MDNS_PRIV_H -#define LWIP_HDR_MDNS_PRIV_H - -#include "lwip/apps/mdns_opts.h" -#include "lwip/pbuf.h" - -#if LWIP_MDNS_RESPONDER - -/* Domain struct and methods - visible for unit tests */ - -#define MDNS_DOMAIN_MAXLEN 256 -#define MDNS_READNAME_ERROR 0xFFFF - -struct mdns_domain { - /* Encoded domain name */ - u8_t name[MDNS_DOMAIN_MAXLEN]; - /* Total length of domain name, including zero */ - u16_t length; - /* Set if compression of this domain is not allowed */ - u8_t skip_compression; -}; - -err_t mdns_domain_add_label(struct mdns_domain *domain, const char *label, u8_t len); -u16_t mdns_readname(struct pbuf *p, u16_t offset, struct mdns_domain *domain); -int mdns_domain_eq(struct mdns_domain *a, struct mdns_domain *b); -u16_t mdns_compress_domain(struct pbuf *pbuf, u16_t *offset, struct mdns_domain *domain); - -#endif /* LWIP_MDNS_RESPONDER */ - -#endif /* LWIP_HDR_MDNS_PRIV_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/apps/mqtt.h b/third_party/lwip/repo/lwip/src/include/lwip/apps/mqtt.h deleted file mode 100644 index 34b230b888b79a..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/apps/mqtt.h +++ /dev/null @@ -1,244 +0,0 @@ -/** - * @file - * MQTT client - */ - -/* - * Copyright (c) 2016 Erik Andersson - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Erik Andersson - * - */ -#ifndef LWIP_HDR_APPS_MQTT_CLIENT_H -#define LWIP_HDR_APPS_MQTT_CLIENT_H - -#include "lwip/apps/mqtt_opts.h" -#include "lwip/err.h" -#include "lwip/ip_addr.h" - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct mqtt_client_t mqtt_client_t; - -/** @ingroup mqtt - * Default MQTT port */ -#define MQTT_PORT 1883 - -/*---------------------------------------------------------------------------------------------- */ -/* Connection with server */ - -/** - * @ingroup mqtt - * Client information and connection parameters */ -struct mqtt_connect_client_info_t { - /** Client identifier, must be set by caller */ - const char *client_id; - /** User name and password, set to NULL if not used */ - const char* client_user; - const char* client_pass; - /** keep alive time in seconds, 0 to disable keep alive functionality*/ - u16_t keep_alive; - /** will topic, set to NULL if will is not to be used, - will_msg, will_qos and will retain are then ignored */ - const char* will_topic; - const char* will_msg; - u8_t will_qos; - u8_t will_retain; -}; - -/** - * @ingroup mqtt - * Connection status codes */ -typedef enum -{ - MQTT_CONNECT_ACCEPTED = 0, - MQTT_CONNECT_REFUSED_PROTOCOL_VERSION = 1, - MQTT_CONNECT_REFUSED_IDENTIFIER = 2, - MQTT_CONNECT_REFUSED_SERVER = 3, - MQTT_CONNECT_REFUSED_USERNAME_PASS = 4, - MQTT_CONNECT_REFUSED_NOT_AUTHORIZED_ = 5, - MQTT_CONNECT_DISCONNECTED = 256, - MQTT_CONNECT_TIMEOUT = 257 -} mqtt_connection_status_t; - -/** - * @ingroup mqtt - * Function prototype for mqtt connection status callback. Called when - * client has connected to the server after initiating a mqtt connection attempt by - * calling mqtt_connect() or when connection is closed by server or an error - * - * @param client MQTT client itself - * @param arg Additional argument to pass to the callback function - * @param status Connect result code or disconnection notification @see mqtt_connection_status_t - * - */ -typedef void (*mqtt_connection_cb_t)(mqtt_client_t *client, void *arg, mqtt_connection_status_t status); - - -/** - * @ingroup mqtt - * Data callback flags */ -enum { - /** Flag set when last fragment of data arrives in data callback */ - MQTT_DATA_FLAG_LAST = 1 -}; - -/** - * @ingroup mqtt - * Function prototype for MQTT incoming publish data callback function. Called when data - * arrives to a subscribed topic @see mqtt_subscribe - * - * @param arg Additional argument to pass to the callback function - * @param data User data, pointed object, data may not be referenced after callback return, - NULL is passed when all publish data are delivered - * @param len Length of publish data fragment - * @param flags MQTT_DATA_FLAG_LAST set when this call contains the last part of data from publish message - * - */ -typedef void (*mqtt_incoming_data_cb_t)(void *arg, const u8_t *data, u16_t len, u8_t flags); - - -/** - * @ingroup mqtt - * Function prototype for MQTT incoming publish function. Called when an incoming publish - * arrives to a subscribed topic @see mqtt_subscribe - * - * @param arg Additional argument to pass to the callback function - * @param topic Zero terminated Topic text string, topic may not be referenced after callback return - * @param tot_len Total length of publish data, if set to 0 (no publish payload) data callback will not be invoked - */ -typedef void (*mqtt_incoming_publish_cb_t)(void *arg, const char *topic, u32_t tot_len); - - -/** - * @ingroup mqtt - * Function prototype for mqtt request callback. Called when a subscribe, unsubscribe - * or publish request has completed - * @param arg Pointer to user data supplied when invoking request - * @param err ERR_OK on success - * ERR_TIMEOUT if no response was received within timeout, - * ERR_ABRT if (un)subscribe was denied - */ -typedef void (*mqtt_request_cb_t)(void *arg, err_t err); - - -/** - * Pending request item, binds application callback to pending server requests - */ -struct mqtt_request_t -{ - /** Next item in list, NULL means this is the last in chain, - next pointing at itself means request is unallocated */ - struct mqtt_request_t *next; - /** Callback to upper layer */ - mqtt_request_cb_t cb; - void *arg; - /** MQTT packet identifier */ - u16_t pkt_id; - /** Expire time relative to element before this */ - u16_t timeout_diff; -}; - -/** Ring buffer */ -struct mqtt_ringbuf_t { - u16_t put; - u16_t get; - u8_t buf[MQTT_OUTPUT_RINGBUF_SIZE]; -}; - -/** MQTT client */ -struct mqtt_client_t -{ - /** Timers and timeouts */ - u16_t cyclic_tick; - u16_t keep_alive; - u16_t server_watchdog; - /** Packet identifier generator*/ - u16_t pkt_id_seq; - /** Packet identifier of pending incoming publish */ - u16_t inpub_pkt_id; - /** Connection state */ - u8_t conn_state; - struct tcp_pcb *conn; - /** Connection callback */ - void *connect_arg; - mqtt_connection_cb_t connect_cb; - /** Pending requests to server */ - struct mqtt_request_t *pend_req_queue; - struct mqtt_request_t req_list[MQTT_REQ_MAX_IN_FLIGHT]; - void *inpub_arg; - /** Incoming data callback */ - mqtt_incoming_data_cb_t data_cb; - mqtt_incoming_publish_cb_t pub_cb; - /** Input */ - u32_t msg_idx; - u8_t rx_buffer[MQTT_VAR_HEADER_BUFFER_LEN]; - /** Output ring-buffer */ - struct mqtt_ringbuf_t output; -}; - - -/** Connect to server */ -err_t mqtt_client_connect(mqtt_client_t *client, const ip_addr_t *ipaddr, u16_t port, mqtt_connection_cb_t cb, void *arg, - const struct mqtt_connect_client_info_t *client_info); - -/** Disconnect from server */ -void mqtt_disconnect(mqtt_client_t *client); - -/** Create new client */ -mqtt_client_t *mqtt_client_new(void); - -/** Check connection status */ -u8_t mqtt_client_is_connected(mqtt_client_t *client); - -/** Set callback to call for incoming publish */ -void mqtt_set_inpub_callback(mqtt_client_t *client, mqtt_incoming_publish_cb_t, - mqtt_incoming_data_cb_t data_cb, void *arg); - -/** Common function for subscribe and unsubscribe */ -err_t mqtt_sub_unsub(mqtt_client_t *client, const char *topic, u8_t qos, mqtt_request_cb_t cb, void *arg, u8_t sub); - -/** @ingroup mqtt - *Subscribe to topic */ -#define mqtt_subscribe(client, topic, qos, cb, arg) mqtt_sub_unsub(client, topic, qos, cb, arg, 1) -/** @ingroup mqtt - * Unsubscribe to topic */ -#define mqtt_unsubscribe(client, topic, cb, arg) mqtt_sub_unsub(client, topic, 0, cb, arg, 0) - - -/** Publish data to topic */ -err_t mqtt_publish(mqtt_client_t *client, const char *topic, const void *payload, u16_t payload_length, u8_t qos, u8_t retain, - mqtt_request_cb_t cb, void *arg); - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_APPS_MQTT_CLIENT_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/apps/mqtt_opts.h b/third_party/lwip/repo/lwip/src/include/lwip/apps/mqtt_opts.h deleted file mode 100644 index ffefacd2595173..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/apps/mqtt_opts.h +++ /dev/null @@ -1,103 +0,0 @@ -/** - * @file - * MQTT client options - */ - -/* - * Copyright (c) 2016 Erik Andersson - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Erik Andersson - * - */ -#ifndef LWIP_HDR_APPS_MQTT_OPTS_H -#define LWIP_HDR_APPS_MQTT_OPTS_H - -#include "lwip/opt.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @defgroup mqtt_opts Options - * @ingroup mqtt - * @{ - */ - -/** - * Output ring-buffer size, must be able to fit largest outgoing publish message topic+payloads - */ -#ifndef MQTT_OUTPUT_RINGBUF_SIZE -#define MQTT_OUTPUT_RINGBUF_SIZE 256 -#endif - -/** - * Number of bytes in receive buffer, must be at least the size of the longest incoming topic + 8 - * If one wants to avoid fragmented incoming publish, set length to max incoming topic length + max payload length + 8 - */ -#ifndef MQTT_VAR_HEADER_BUFFER_LEN -#define MQTT_VAR_HEADER_BUFFER_LEN 128 -#endif - -/** - * Maximum number of pending subscribe, unsubscribe and publish requests to server . - */ -#ifndef MQTT_REQ_MAX_IN_FLIGHT -#define MQTT_REQ_MAX_IN_FLIGHT 4 -#endif - -/** - * Seconds between each cyclic timer call. - */ -#ifndef MQTT_CYCLIC_TIMER_INTERVAL -#define MQTT_CYCLIC_TIMER_INTERVAL 5 -#endif - -/** - * Publish, subscribe and unsubscribe request timeout in seconds. - */ -#ifndef MQTT_REQ_TIMEOUT -#define MQTT_REQ_TIMEOUT 30 -#endif - -/** - * Seconds for MQTT connect response timeout after sending connect request - */ -#ifndef MQTT_CONNECT_TIMOUT -#define MQTT_CONNECT_TIMOUT 100 -#endif - -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_APPS_MQTT_OPTS_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/apps/netbiosns.h b/third_party/lwip/repo/lwip/src/include/lwip/apps/netbiosns.h deleted file mode 100644 index c9f68d8d12c64b..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/apps/netbiosns.h +++ /dev/null @@ -1,43 +0,0 @@ -/** - * @file - * NETBIOS name service responder - */ - -/* - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - */ -#ifndef LWIP_HDR_APPS_NETBIOS_H -#define LWIP_HDR_APPS_NETBIOS_H - -#include "lwip/apps/netbiosns_opts.h" - -void netbiosns_init(void); -#ifndef NETBIOS_LWIP_NAME -void netbiosns_set_name(const char* hostname); -#endif -void netbiosns_stop(void); - -#endif /* LWIP_HDR_APPS_NETBIOS_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/apps/netbiosns_opts.h b/third_party/lwip/repo/lwip/src/include/lwip/apps/netbiosns_opts.h deleted file mode 100644 index 0909ef7b94ef6a..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/apps/netbiosns_opts.h +++ /dev/null @@ -1,59 +0,0 @@ -/** - * @file - * NETBIOS name service responder options - */ - -/* - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - */ -#ifndef LWIP_HDR_APPS_NETBIOS_OPTS_H -#define LWIP_HDR_APPS_NETBIOS_OPTS_H - -#include "lwip/opt.h" - -/** - * @defgroup netbiosns_opts Options - * @ingroup netbiosns - * @{ - */ - -/** NetBIOS name of lwip device - * This must be uppercase until NETBIOS_STRCMP() is defined to a string - * comparision function that is case insensitive. - * If you want to use the netif's hostname, use this (with LWIP_NETIF_HOSTNAME): - * (ip_current_netif() != NULL ? ip_current_netif()->hostname != NULL ? ip_current_netif()->hostname : "" : "") - * - * If this is not defined, netbiosns_set_name() can be called at runtime to change the name. - */ -#ifdef __DOXYGEN__ -#define NETBIOS_LWIP_NAME "NETBIOSLWIPDEV" -#endif - -/** - * @} - */ - -#endif /* LWIP_HDR_APPS_NETBIOS_OPTS_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/apps/snmp.h b/third_party/lwip/repo/lwip/src/include/lwip/apps/snmp.h deleted file mode 100644 index 10e8ff434bb8f2..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/apps/snmp.h +++ /dev/null @@ -1,128 +0,0 @@ -/** - * @file - * SNMP server main API - start and basic configuration - */ - -/* - * Copyright (c) 2001, 2002 Leon Woestenberg - * Copyright (c) 2001, 2002 Axon Digital Design B.V., The Netherlands. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Leon Woestenberg - * Martin Hentschel - * - */ -#ifndef LWIP_HDR_APPS_SNMP_H -#define LWIP_HDR_APPS_SNMP_H - -#include "lwip/apps/snmp_opts.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/err.h" -#include "lwip/apps/snmp_core.h" - -/** SNMP variable binding descriptor (publically needed for traps) */ -struct snmp_varbind -{ - /** pointer to next varbind, NULL for last in list */ - struct snmp_varbind *next; - /** pointer to previous varbind, NULL for first in list */ - struct snmp_varbind *prev; - - /** object identifier */ - struct snmp_obj_id oid; - - /** value ASN1 type */ - u8_t type; - /** object value length */ - u16_t value_len; - /** object value */ - void *value; -}; - -/** - * @ingroup snmp_core - * Agent setup, start listening to port 161. - */ -void snmp_init(void); -void snmp_set_mibs(const struct snmp_mib **mibs, u8_t num_mibs); - -void snmp_set_device_enterprise_oid(const struct snmp_obj_id* device_enterprise_oid); -const struct snmp_obj_id* snmp_get_device_enterprise_oid(void); - -void snmp_trap_dst_enable(u8_t dst_idx, u8_t enable); -void snmp_trap_dst_ip_set(u8_t dst_idx, const ip_addr_t *dst); - -/** Generic trap: cold start */ -#define SNMP_GENTRAP_COLDSTART 0 -/** Generic trap: warm start */ -#define SNMP_GENTRAP_WARMSTART 1 -/** Generic trap: link down */ -#define SNMP_GENTRAP_LINKDOWN 2 -/** Generic trap: link up */ -#define SNMP_GENTRAP_LINKUP 3 -/** Generic trap: authentication failure */ -#define SNMP_GENTRAP_AUTH_FAILURE 4 -/** Generic trap: EGP neighbor lost */ -#define SNMP_GENTRAP_EGP_NEIGHBOR_LOSS 5 -/** Generic trap: enterprise specific */ -#define SNMP_GENTRAP_ENTERPRISE_SPECIFIC 6 - -err_t snmp_send_trap_generic(s32_t generic_trap); -err_t snmp_send_trap_specific(s32_t specific_trap, struct snmp_varbind *varbinds); -err_t snmp_send_trap(const struct snmp_obj_id* oid, s32_t generic_trap, s32_t specific_trap, struct snmp_varbind *varbinds); - -#define SNMP_AUTH_TRAPS_DISABLED 0 -#define SNMP_AUTH_TRAPS_ENABLED 1 -void snmp_set_auth_traps_enabled(u8_t enable); -u8_t snmp_get_auth_traps_enabled(void); - -const char * snmp_get_community(void); -const char * snmp_get_community_write(void); -const char * snmp_get_community_trap(void); -void snmp_set_community(const char * const community); -void snmp_set_community_write(const char * const community); -void snmp_set_community_trap(const char * const community); - -void snmp_coldstart_trap(void); -void snmp_authfail_trap(void); - -typedef void (*snmp_write_callback_fct)(const u32_t* oid, u8_t oid_len, void* callback_arg); -void snmp_set_write_callback(snmp_write_callback_fct write_callback, void* callback_arg); - -#endif /* LWIP_SNMP */ - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_APPS_SNMP_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/apps/snmp_core.h b/third_party/lwip/repo/lwip/src/include/lwip/apps/snmp_core.h deleted file mode 100644 index e781c532b38e7e..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/apps/snmp_core.h +++ /dev/null @@ -1,364 +0,0 @@ -/** - * @file - * SNMP core API for implementing MIBs - */ - -/* - * Copyright (c) 2006 Axon Digital Design B.V., The Netherlands. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * Author: Christiaan Simons - * Martin Hentschel - */ - -#ifndef LWIP_HDR_APPS_SNMP_CORE_H -#define LWIP_HDR_APPS_SNMP_CORE_H - -#include "lwip/apps/snmp_opts.h" - -#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/ip_addr.h" -#include "lwip/err.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* basic ASN1 defines */ -#define SNMP_ASN1_CLASS_UNIVERSAL 0x00 -#define SNMP_ASN1_CLASS_APPLICATION 0x40 -#define SNMP_ASN1_CLASS_CONTEXT 0x80 -#define SNMP_ASN1_CLASS_PRIVATE 0xC0 - -#define SNMP_ASN1_CONTENTTYPE_PRIMITIVE 0x00 -#define SNMP_ASN1_CONTENTTYPE_CONSTRUCTED 0x20 - -/* universal tags (from ASN.1 spec.) */ -#define SNMP_ASN1_UNIVERSAL_END_OF_CONTENT 0 -#define SNMP_ASN1_UNIVERSAL_INTEGER 2 -#define SNMP_ASN1_UNIVERSAL_OCTET_STRING 4 -#define SNMP_ASN1_UNIVERSAL_NULL 5 -#define SNMP_ASN1_UNIVERSAL_OBJECT_ID 6 -#define SNMP_ASN1_UNIVERSAL_SEQUENCE_OF 16 - -/* application specific (SNMP) tags (from SNMPv2-SMI) */ -#define SNMP_ASN1_APPLICATION_IPADDR 0 /* [APPLICATION 0] IMPLICIT OCTET STRING (SIZE (4)) */ -#define SNMP_ASN1_APPLICATION_COUNTER 1 /* [APPLICATION 1] IMPLICIT INTEGER (0..4294967295) => u32_t */ -#define SNMP_ASN1_APPLICATION_GAUGE 2 /* [APPLICATION 2] IMPLICIT INTEGER (0..4294967295) => u32_t */ -#define SNMP_ASN1_APPLICATION_TIMETICKS 3 /* [APPLICATION 3] IMPLICIT INTEGER (0..4294967295) => u32_t */ -#define SNMP_ASN1_APPLICATION_OPAQUE 4 /* [APPLICATION 4] IMPLICIT OCTET STRING */ -#define SNMP_ASN1_APPLICATION_COUNTER64 6 /* [APPLICATION 6] IMPLICIT INTEGER (0..18446744073709551615) */ - -/* context specific (SNMP) tags (from RFC 1905) */ -#define SNMP_ASN1_CONTEXT_VARBIND_NO_SUCH_INSTANCE 1 - -/* full ASN1 type defines */ -#define SNMP_ASN1_TYPE_END_OF_CONTENT (SNMP_ASN1_CLASS_UNIVERSAL | SNMP_ASN1_CONTENTTYPE_PRIMITIVE | SNMP_ASN1_UNIVERSAL_END_OF_CONTENT) -#define SNMP_ASN1_TYPE_INTEGER (SNMP_ASN1_CLASS_UNIVERSAL | SNMP_ASN1_CONTENTTYPE_PRIMITIVE | SNMP_ASN1_UNIVERSAL_INTEGER) -#define SNMP_ASN1_TYPE_OCTET_STRING (SNMP_ASN1_CLASS_UNIVERSAL | SNMP_ASN1_CONTENTTYPE_PRIMITIVE | SNMP_ASN1_UNIVERSAL_OCTET_STRING) -#define SNMP_ASN1_TYPE_NULL (SNMP_ASN1_CLASS_UNIVERSAL | SNMP_ASN1_CONTENTTYPE_PRIMITIVE | SNMP_ASN1_UNIVERSAL_NULL) -#define SNMP_ASN1_TYPE_OBJECT_ID (SNMP_ASN1_CLASS_UNIVERSAL | SNMP_ASN1_CONTENTTYPE_PRIMITIVE | SNMP_ASN1_UNIVERSAL_OBJECT_ID) -#define SNMP_ASN1_TYPE_SEQUENCE (SNMP_ASN1_CLASS_UNIVERSAL | SNMP_ASN1_CONTENTTYPE_CONSTRUCTED | SNMP_ASN1_UNIVERSAL_SEQUENCE_OF) -#define SNMP_ASN1_TYPE_IPADDR (SNMP_ASN1_CLASS_APPLICATION | SNMP_ASN1_CONTENTTYPE_PRIMITIVE | SNMP_ASN1_APPLICATION_IPADDR) -#define SNMP_ASN1_TYPE_IPADDRESS SNMP_ASN1_TYPE_IPADDR -#define SNMP_ASN1_TYPE_COUNTER (SNMP_ASN1_CLASS_APPLICATION | SNMP_ASN1_CONTENTTYPE_PRIMITIVE | SNMP_ASN1_APPLICATION_COUNTER) -#define SNMP_ASN1_TYPE_COUNTER32 SNMP_ASN1_TYPE_COUNTER -#define SNMP_ASN1_TYPE_GAUGE (SNMP_ASN1_CLASS_APPLICATION | SNMP_ASN1_CONTENTTYPE_PRIMITIVE | SNMP_ASN1_APPLICATION_GAUGE) -#define SNMP_ASN1_TYPE_GAUGE32 SNMP_ASN1_TYPE_GAUGE -#define SNMP_ASN1_TYPE_UNSIGNED32 SNMP_ASN1_TYPE_GAUGE -#define SNMP_ASN1_TYPE_TIMETICKS (SNMP_ASN1_CLASS_APPLICATION | SNMP_ASN1_CONTENTTYPE_PRIMITIVE | SNMP_ASN1_APPLICATION_TIMETICKS) -#define SNMP_ASN1_TYPE_OPAQUE (SNMP_ASN1_CLASS_APPLICATION | SNMP_ASN1_CONTENTTYPE_PRIMITIVE | SNMP_ASN1_APPLICATION_OPAQUE) -#define SNMP_ASN1_TYPE_COUNTER64 (SNMP_ASN1_CLASS_APPLICATION | SNMP_ASN1_CONTENTTYPE_PRIMITIVE | SNMP_ASN1_APPLICATION_COUNTER64) - -#define SNMP_VARBIND_EXCEPTION_OFFSET 0xF0 -#define SNMP_VARBIND_EXCEPTION_MASK 0x0F - -/** error codes predefined by SNMP prot. */ -typedef enum { - SNMP_ERR_NOERROR = 0, -/* -outdated v1 error codes. do not use anmore! -#define SNMP_ERR_NOSUCHNAME 2 use SNMP_ERR_NOSUCHINSTANCE instead -#define SNMP_ERR_BADVALUE 3 use SNMP_ERR_WRONGTYPE,SNMP_ERR_WRONGLENGTH,SNMP_ERR_WRONGENCODING or SNMP_ERR_WRONGVALUE instead -#define SNMP_ERR_READONLY 4 use SNMP_ERR_NOTWRITABLE instead -*/ - SNMP_ERR_GENERROR = 5, - SNMP_ERR_NOACCESS = 6, - SNMP_ERR_WRONGTYPE = 7, - SNMP_ERR_WRONGLENGTH = 8, - SNMP_ERR_WRONGENCODING = 9, - SNMP_ERR_WRONGVALUE = 10, - SNMP_ERR_NOCREATION = 11, - SNMP_ERR_INCONSISTENTVALUE = 12, - SNMP_ERR_RESOURCEUNAVAILABLE = 13, - SNMP_ERR_COMMITFAILED = 14, - SNMP_ERR_UNDOFAILED = 15, - SNMP_ERR_NOTWRITABLE = 17, - SNMP_ERR_INCONSISTENTNAME = 18, - - SNMP_ERR_NOSUCHINSTANCE = SNMP_VARBIND_EXCEPTION_OFFSET + SNMP_ASN1_CONTEXT_VARBIND_NO_SUCH_INSTANCE -} snmp_err_t; - -/** internal object identifier representation */ -struct snmp_obj_id -{ - u8_t len; - u32_t id[SNMP_MAX_OBJ_ID_LEN]; -}; - -struct snmp_obj_id_const_ref -{ - u8_t len; - const u32_t* id; -}; - -extern const struct snmp_obj_id_const_ref snmp_zero_dot_zero; /* administrative identifier from SNMPv2-SMI */ - -/** SNMP variant value, used as reference in struct snmp_node_instance and table implementation */ -union snmp_variant_value -{ - void* ptr; - const void* const_ptr; - u32_t u32; - s32_t s32; -}; - - -/** -SNMP MIB node types - tree node is the only node the stack can process in order to walk the tree, - all other nodes are assumed to be leaf nodes. - This cannot be an enum because users may want to define their own node types. -*/ -#define SNMP_NODE_TREE 0x00 -/* predefined leaf node types */ -#define SNMP_NODE_SCALAR 0x01 -#define SNMP_NODE_SCALAR_ARRAY 0x02 -#define SNMP_NODE_TABLE 0x03 -#define SNMP_NODE_THREADSYNC 0x04 - -/** node "base class" layout, the mandatory fields for a node */ -struct snmp_node -{ - /** one out of SNMP_NODE_TREE or any leaf node type (like SNMP_NODE_SCALAR) */ - u8_t node_type; - /** the number assigned to this node which used as part of the full OID */ - u32_t oid; -}; - -/** SNMP node instance access types */ -typedef enum { - SNMP_NODE_INSTANCE_ACCESS_READ = 1, - SNMP_NODE_INSTANCE_ACCESS_WRITE = 2, - SNMP_NODE_INSTANCE_READ_ONLY = SNMP_NODE_INSTANCE_ACCESS_READ, - SNMP_NODE_INSTANCE_READ_WRITE = (SNMP_NODE_INSTANCE_ACCESS_READ | SNMP_NODE_INSTANCE_ACCESS_WRITE), - SNMP_NODE_INSTANCE_WRITE_ONLY = SNMP_NODE_INSTANCE_ACCESS_WRITE, - SNMP_NODE_INSTANCE_NOT_ACCESSIBLE = 0 -} snmp_access_t; - -struct snmp_node_instance; - -typedef s16_t (*node_instance_get_value_method)(struct snmp_node_instance*, void*); -typedef snmp_err_t (*node_instance_set_test_method)(struct snmp_node_instance*, u16_t, void*); -typedef snmp_err_t (*node_instance_set_value_method)(struct snmp_node_instance*, u16_t, void*); -typedef void (*node_instance_release_method)(struct snmp_node_instance*); - -#define SNMP_GET_VALUE_RAW_DATA 0x8000 - -/** SNMP node instance */ -struct snmp_node_instance -{ - /** prefilled with the node, get_instance() is called on; may be changed by user to any value to pass an arbitrary node between calls to get_instance() and get_value/test_value/set_value */ - const struct snmp_node* node; - /** prefilled with the instance id requested; for get_instance() this is the exact oid requested; for get_next_instance() this is the relative starting point, stack expects relative oid of next node here */ - struct snmp_obj_id instance_oid; - - /** ASN type for this object (see snmp_asn1.h for definitions) */ - u8_t asn1_type; - /** one out of instance access types defined above (SNMP_NODE_INSTANCE_READ_ONLY,...) */ - snmp_access_t access; - - /** returns object value for the given object identifier. Return values <0 to indicate an error */ - node_instance_get_value_method get_value; - /** tests length and/or range BEFORE setting */ - node_instance_set_test_method set_test; - /** sets object value, only called when set_test() was successful */ - node_instance_set_value_method set_value; - /** called in any case when the instance is not required anymore by stack (useful for freeing memory allocated in get_instance/get_next_instance methods) */ - node_instance_release_method release_instance; - - /** reference to pass arbitrary value between calls to get_instance() and get_value/test_value/set_value */ - union snmp_variant_value reference; - /** see reference (if reference is a pointer, the length of underlying data may be stored here or anything else) */ - u32_t reference_len; -}; - - -/** SNMP tree node */ -struct snmp_tree_node -{ - /** inherited "base class" members */ - struct snmp_node node; - u16_t subnode_count; - const struct snmp_node* const *subnodes; -}; - -#define SNMP_CREATE_TREE_NODE(oid, subnodes) \ - {{ SNMP_NODE_TREE, (oid) }, \ - (u16_t)LWIP_ARRAYSIZE(subnodes), (subnodes) } - -#define SNMP_CREATE_EMPTY_TREE_NODE(oid) \ - {{ SNMP_NODE_TREE, (oid) }, \ - 0, NULL } - -/** SNMP leaf node */ -struct snmp_leaf_node -{ - /** inherited "base class" members */ - struct snmp_node node; - snmp_err_t (*get_instance)(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance); - snmp_err_t (*get_next_instance)(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance); -}; - -/** represents a single mib with its base oid and root node */ -struct snmp_mib -{ - const u32_t *base_oid; - u8_t base_oid_len; - const struct snmp_node *root_node; -}; - -#define SNMP_MIB_CREATE(oid_list, root_node) { (oid_list), (u8_t)LWIP_ARRAYSIZE(oid_list), root_node } - -/** OID range structure */ -struct snmp_oid_range -{ - u32_t min; - u32_t max; -}; - -/** checks if incoming OID length and values are in allowed ranges */ -u8_t snmp_oid_in_range(const u32_t *oid_in, u8_t oid_len, const struct snmp_oid_range *oid_ranges, u8_t oid_ranges_len); - -typedef enum { - SNMP_NEXT_OID_STATUS_SUCCESS, - SNMP_NEXT_OID_STATUS_NO_MATCH, - SNMP_NEXT_OID_STATUS_BUF_TO_SMALL -} snmp_next_oid_status_t; - -/** state for next_oid_init / next_oid_check functions */ -struct snmp_next_oid_state -{ - const u32_t* start_oid; - u8_t start_oid_len; - - u32_t* next_oid; - u8_t next_oid_len; - u8_t next_oid_max_len; - - snmp_next_oid_status_t status; - void* reference; -}; - -void snmp_next_oid_init(struct snmp_next_oid_state *state, - const u32_t *start_oid, u8_t start_oid_len, - u32_t *next_oid_buf, u8_t next_oid_max_len); -u8_t snmp_next_oid_precheck(struct snmp_next_oid_state *state, const u32_t *oid, const u8_t oid_len); -u8_t snmp_next_oid_check(struct snmp_next_oid_state *state, const u32_t *oid, const u8_t oid_len, void* reference); - -void snmp_oid_assign(struct snmp_obj_id* target, const u32_t *oid, u8_t oid_len); -void snmp_oid_combine(struct snmp_obj_id* target, const u32_t *oid1, u8_t oid1_len, const u32_t *oid2, u8_t oid2_len); -void snmp_oid_prefix(struct snmp_obj_id* target, const u32_t *oid, u8_t oid_len); -void snmp_oid_append(struct snmp_obj_id* target, const u32_t *oid, u8_t oid_len); -u8_t snmp_oid_equal(const u32_t *oid1, u8_t oid1_len, const u32_t *oid2, u8_t oid2_len); -s8_t snmp_oid_compare(const u32_t *oid1, u8_t oid1_len, const u32_t *oid2, u8_t oid2_len); - -#if LWIP_IPV4 -u8_t snmp_oid_to_ip4(const u32_t *oid, ip4_addr_t *ip); -void snmp_ip4_to_oid(const ip4_addr_t *ip, u32_t *oid); -#endif /* LWIP_IPV4 */ -#if LWIP_IPV6 -u8_t snmp_oid_to_ip6(const u32_t *oid, ip6_addr_t *ip); -void snmp_ip6_to_oid(const ip6_addr_t *ip, u32_t *oid); -#endif /* LWIP_IPV6 */ -#if LWIP_IPV4 || LWIP_IPV6 -u8_t snmp_ip_to_oid(const ip_addr_t *ip, u32_t *oid); -u8_t snmp_ip_port_to_oid(const ip_addr_t *ip, u16_t port, u32_t *oid); - -u8_t snmp_oid_to_ip(const u32_t *oid, u8_t oid_len, ip_addr_t *ip); -u8_t snmp_oid_to_ip_port(const u32_t *oid, u8_t oid_len, ip_addr_t *ip, u16_t *port); -#endif /* LWIP_IPV4 || LWIP_IPV6 */ - -struct netif; -u8_t netif_to_num(const struct netif *netif); - -snmp_err_t snmp_set_test_ok(struct snmp_node_instance* instance, u16_t value_len, void* value); /* generic function which can be used if test is always successful */ - -err_t snmp_decode_bits(const u8_t *buf, u32_t buf_len, u32_t *bit_value); -err_t snmp_decode_truthvalue(const s32_t *asn1_value, u8_t *bool_value); -u8_t snmp_encode_bits(u8_t *buf, u32_t buf_len, u32_t bit_value, u8_t bit_count); -u8_t snmp_encode_truthvalue(s32_t *asn1_value, u32_t bool_value); - -struct snmp_statistics -{ - u32_t inpkts; - u32_t outpkts; - u32_t inbadversions; - u32_t inbadcommunitynames; - u32_t inbadcommunityuses; - u32_t inasnparseerrs; - u32_t intoobigs; - u32_t innosuchnames; - u32_t inbadvalues; - u32_t inreadonlys; - u32_t ingenerrs; - u32_t intotalreqvars; - u32_t intotalsetvars; - u32_t ingetrequests; - u32_t ingetnexts; - u32_t insetrequests; - u32_t ingetresponses; - u32_t intraps; - u32_t outtoobigs; - u32_t outnosuchnames; - u32_t outbadvalues; - u32_t outgenerrs; - u32_t outgetrequests; - u32_t outgetnexts; - u32_t outsetrequests; - u32_t outgetresponses; - u32_t outtraps; -}; - -extern struct snmp_statistics snmp_stats; - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_SNMP */ - -#endif /* LWIP_HDR_APPS_SNMP_CORE_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/apps/snmp_mib2.h b/third_party/lwip/repo/lwip/src/include/lwip/apps/snmp_mib2.h deleted file mode 100644 index 2f4a68935e2a78..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/apps/snmp_mib2.h +++ /dev/null @@ -1,78 +0,0 @@ -/** - * @file - * SNMP MIB2 API - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Dirk Ziegelmeier - * - */ -#ifndef LWIP_HDR_APPS_SNMP_MIB2_H -#define LWIP_HDR_APPS_SNMP_MIB2_H - -#include "lwip/apps/snmp_opts.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */ -#if SNMP_LWIP_MIB2 - -#include "lwip/apps/snmp_core.h" - -extern const struct snmp_mib mib2; - -#if SNMP_USE_NETCONN -#include "lwip/apps/snmp_threadsync.h" -void snmp_mib2_lwip_synchronizer(snmp_threadsync_called_fn fn, void* arg); -extern struct snmp_threadsync_instance snmp_mib2_lwip_locks; -#endif - -#ifndef SNMP_SYSSERVICES -#define SNMP_SYSSERVICES ((1 << 6) | (1 << 3) | ((IP_FORWARD) << 2)) -#endif - -void snmp_mib2_set_sysdescr(const u8_t* str, const u16_t* len); /* read-only be defintion */ -void snmp_mib2_set_syscontact(u8_t *ocstr, u16_t *ocstrlen, u16_t bufsize); -void snmp_mib2_set_syscontact_readonly(const u8_t *ocstr, const u16_t *ocstrlen); -void snmp_mib2_set_sysname(u8_t *ocstr, u16_t *ocstrlen, u16_t bufsize); -void snmp_mib2_set_sysname_readonly(const u8_t *ocstr, const u16_t *ocstrlen); -void snmp_mib2_set_syslocation(u8_t *ocstr, u16_t *ocstrlen, u16_t bufsize); -void snmp_mib2_set_syslocation_readonly(const u8_t *ocstr, const u16_t *ocstrlen); - -#endif /* SNMP_LWIP_MIB2 */ -#endif /* LWIP_SNMP */ - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_APPS_SNMP_MIB2_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/apps/snmp_opts.h b/third_party/lwip/repo/lwip/src/include/lwip/apps/snmp_opts.h deleted file mode 100644 index 6c9ba7beb3321c..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/apps/snmp_opts.h +++ /dev/null @@ -1,293 +0,0 @@ -/** - * @file - * SNMP server options list - */ - -/* - * Copyright (c) 2015 Dirk Ziegelmeier - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Dirk Ziegelmeier - * - */ -#ifndef LWIP_HDR_SNMP_OPTS_H -#define LWIP_HDR_SNMP_OPTS_H - -#include "lwip/opt.h" - -/** - * @defgroup snmp_opts Options - * @ingroup snmp - * @{ - */ - -/** - * LWIP_SNMP==1: This enables the lwIP SNMP agent. UDP must be available - * for SNMP transport. - * If you want to use your own SNMP agent, leave this disabled. - * To integrate MIB2 of an external agent, you need to enable - * LWIP_MIB2_CALLBACKS and MIB2_STATS. This will give you the callbacks - * and statistics counters you need to get MIB2 working. - */ -#if !defined LWIP_SNMP || defined __DOXYGEN__ -#define LWIP_SNMP 0 -#endif - -/** - * SNMP_USE_NETCONN: Use netconn API instead of raw API. - * Makes SNMP agent run in a worker thread, so blocking operations - * can be done in MIB calls. - */ -#if !defined SNMP_USE_NETCONN || defined __DOXYGEN__ -#define SNMP_USE_NETCONN 0 -#endif - -/** - * SNMP_USE_RAW: Use raw API. - * SNMP agent does not run in a worker thread, so blocking operations - * should not be done in MIB calls. - */ -#if !defined SNMP_USE_RAW || defined __DOXYGEN__ -#define SNMP_USE_RAW 1 -#endif - -#if SNMP_USE_NETCONN && SNMP_USE_RAW -#error SNMP stack can use only one of the APIs {raw, netconn} -#endif - -#if LWIP_SNMP && !SNMP_USE_NETCONN && !SNMP_USE_RAW -#error SNMP stack needs a receive API and UDP {raw, netconn} -#endif - -#if SNMP_USE_NETCONN -/** - * SNMP_STACK_SIZE: Stack size of SNMP netconn worker thread - */ -#if !defined SNMP_STACK_SIZE || defined __DOXYGEN__ -#define SNMP_STACK_SIZE DEFAULT_THREAD_STACKSIZE -#endif - -/** - * SNMP_THREAD_PRIO: SNMP netconn worker thread priority - */ -#if !defined SNMP_THREAD_PRIO || defined __DOXYGEN__ -#define SNMP_THREAD_PRIO DEFAULT_THREAD_PRIO -#endif -#endif /* SNMP_USE_NETCONN */ - -/** - * SNMP_TRAP_DESTINATIONS: Number of trap destinations. At least one trap - * destination is required - */ -#if !defined SNMP_TRAP_DESTINATIONS || defined __DOXYGEN__ -#define SNMP_TRAP_DESTINATIONS 1 -#endif - -/** - * Only allow SNMP write actions that are 'safe' (e.g. disabling netifs is not - * a safe action and disabled when SNMP_SAFE_REQUESTS = 1). - * Unsafe requests are disabled by default! - */ -#if !defined SNMP_SAFE_REQUESTS || defined __DOXYGEN__ -#define SNMP_SAFE_REQUESTS 1 -#endif - -/** - * The maximum length of strings used. - */ -#if !defined SNMP_MAX_OCTET_STRING_LEN || defined __DOXYGEN__ -#define SNMP_MAX_OCTET_STRING_LEN 127 -#endif - -/** - * The maximum number of Sub ID's inside an object identifier. - * Indirectly this also limits the maximum depth of SNMP tree. - */ -#if !defined SNMP_MAX_OBJ_ID_LEN || defined __DOXYGEN__ -#define SNMP_MAX_OBJ_ID_LEN 50 -#endif - -#if !defined SNMP_MAX_VALUE_SIZE || defined __DOXYGEN__ -/** - * The maximum size of a value. - */ -#define SNMP_MIN_VALUE_SIZE (2 * sizeof(u32_t*)) /* size required to store the basic types (8 bytes for counter64) */ -/** - * The minimum size of a value. - */ -#define SNMP_MAX_VALUE_SIZE LWIP_MAX(LWIP_MAX((SNMP_MAX_OCTET_STRING_LEN), sizeof(u32_t)*(SNMP_MAX_OBJ_ID_LEN)), SNMP_MIN_VALUE_SIZE) -#endif - -/** - * The snmp read-access community. Used for write-access and traps, too - * unless SNMP_COMMUNITY_WRITE or SNMP_COMMUNITY_TRAP are enabled, respectively. - */ -#if !defined SNMP_COMMUNITY || defined __DOXYGEN__ -#define SNMP_COMMUNITY "public" -#endif - -/** - * The snmp write-access community. - * Set this community to "" in order to disallow any write access. - */ -#if !defined SNMP_COMMUNITY_WRITE || defined __DOXYGEN__ -#define SNMP_COMMUNITY_WRITE "private" -#endif - -/** - * The snmp community used for sending traps. - */ -#if !defined SNMP_COMMUNITY_TRAP || defined __DOXYGEN__ -#define SNMP_COMMUNITY_TRAP "public" -#endif - -/** - * The maximum length of community string. - * If community names shall be adjusted at runtime via snmp_set_community() calls, - * enter here the possible maximum length (+1 for terminating null character). - */ -#if !defined SNMP_MAX_COMMUNITY_STR_LEN || defined __DOXYGEN__ -#define SNMP_MAX_COMMUNITY_STR_LEN LWIP_MAX(LWIP_MAX(sizeof(SNMP_COMMUNITY), sizeof(SNMP_COMMUNITY_WRITE)), sizeof(SNMP_COMMUNITY_TRAP)) -#endif - -/** - * The OID identifiying the device. This may be the enterprise OID itself or any OID located below it in tree. - */ -#if !defined SNMP_DEVICE_ENTERPRISE_OID || defined __DOXYGEN__ -#define SNMP_LWIP_ENTERPRISE_OID 26381 -/** - * IANA assigned enterprise ID for lwIP is 26381 - * @see http://www.iana.org/assignments/enterprise-numbers - * - * @note this enterprise ID is assigned to the lwIP project, - * all object identifiers living under this ID are assigned - * by the lwIP maintainers! - * @note don't change this define, use snmp_set_device_enterprise_oid() - * - * If you need to create your own private MIB you'll need - * to apply for your own enterprise ID with IANA: - * http://www.iana.org/numbers.html - */ -#define SNMP_DEVICE_ENTERPRISE_OID {1, 3, 6, 1, 4, 1, SNMP_LWIP_ENTERPRISE_OID} -/** - * Length of SNMP_DEVICE_ENTERPRISE_OID - */ -#define SNMP_DEVICE_ENTERPRISE_OID_LEN 7 -#endif - -/** - * SNMP_DEBUG: Enable debugging for SNMP messages. - */ -#if !defined SNMP_DEBUG || defined __DOXYGEN__ -#define SNMP_DEBUG LWIP_DBG_OFF -#endif - -/** - * SNMP_MIB_DEBUG: Enable debugging for SNMP MIBs. - */ -#if !defined SNMP_MIB_DEBUG || defined __DOXYGEN__ -#define SNMP_MIB_DEBUG LWIP_DBG_OFF -#endif - -/** - * Indicates if the MIB2 implementation of LWIP SNMP stack is used. - */ -#if !defined SNMP_LWIP_MIB2 || defined __DOXYGEN__ -#define SNMP_LWIP_MIB2 LWIP_SNMP -#endif - -/** - * Value return for sysDesc field of MIB2. - */ -#if !defined SNMP_LWIP_MIB2_SYSDESC || defined __DOXYGEN__ -#define SNMP_LWIP_MIB2_SYSDESC "lwIP" -#endif - -/** - * Value return for sysName field of MIB2. - * To make sysName field settable, call snmp_mib2_set_sysname() to provide the necessary buffers. - */ -#if !defined SNMP_LWIP_MIB2_SYSNAME || defined __DOXYGEN__ -#define SNMP_LWIP_MIB2_SYSNAME "FQDN-unk" -#endif - -/** - * Value return for sysContact field of MIB2. - * To make sysContact field settable, call snmp_mib2_set_syscontact() to provide the necessary buffers. - */ -#if !defined SNMP_LWIP_MIB2_SYSCONTACT || defined __DOXYGEN__ -#define SNMP_LWIP_MIB2_SYSCONTACT "" -#endif - -/** - * Value return for sysLocation field of MIB2. - * To make sysLocation field settable, call snmp_mib2_set_syslocation() to provide the necessary buffers. - */ -#if !defined SNMP_LWIP_MIB2_SYSLOCATION || defined __DOXYGEN__ -#define SNMP_LWIP_MIB2_SYSLOCATION "" -#endif - -/** - * This value is used to limit the repetitions processed in GetBulk requests (value == 0 means no limitation). - * This may be useful to limit the load for a single request. - * According to SNMP RFC 1905 it is allowed to not return all requested variables from a GetBulk request if system load would be too high. - * so the effect is that the client will do more requests to gather all data. - * For the stack this could be useful in case that SNMP processing is done in TCP/IP thread. In this situation a request with many - * repetitions could block the thread for a longer time. Setting limit here will keep the stack more responsive. - */ -#if !defined SNMP_LWIP_GETBULK_MAX_REPETITIONS || defined __DOXYGEN__ -#define SNMP_LWIP_GETBULK_MAX_REPETITIONS 0 -#endif - -/** - * @} - */ - -/* - ------------------------------------ - ---------- SNMPv3 options ---------- - ------------------------------------ -*/ - -/** - * LWIP_SNMP_V3==1: This enables EXPERIMENTAL SNMPv3 support. LWIP_SNMP must - * also be enabled. - * THIS IS UNDER DEVELOPMENT AND SHOULD NOT BE ENABLED IN PRODUCTS. - */ -#ifndef LWIP_SNMP_V3 -#define LWIP_SNMP_V3 0 -#endif - -#ifndef LWIP_SNMP_V3_CRYPTO -#define LWIP_SNMP_V3_CRYPTO LWIP_SNMP_V3 -#endif - -#ifndef LWIP_SNMP_V3_MBEDTLS -#define LWIP_SNMP_V3_MBEDTLS LWIP_SNMP_V3 -#endif - -#endif /* LWIP_HDR_SNMP_OPTS_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/apps/snmp_scalar.h b/third_party/lwip/repo/lwip/src/include/lwip/apps/snmp_scalar.h deleted file mode 100644 index 40a060c640483a..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/apps/snmp_scalar.h +++ /dev/null @@ -1,113 +0,0 @@ -/** - * @file - * SNMP server MIB API to implement scalar nodes - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Martin Hentschel - * - */ - -#ifndef LWIP_HDR_APPS_SNMP_SCALAR_H -#define LWIP_HDR_APPS_SNMP_SCALAR_H - -#include "lwip/apps/snmp_opts.h" -#include "lwip/apps/snmp_core.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */ - -/** basic scalar node */ -struct snmp_scalar_node -{ - /** inherited "base class" members */ - struct snmp_leaf_node node; - u8_t asn1_type; - snmp_access_t access; - node_instance_get_value_method get_value; - node_instance_set_test_method set_test; - node_instance_set_value_method set_value; -}; - - -snmp_err_t snmp_scalar_get_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance); -snmp_err_t snmp_scalar_get_next_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance); - -#define SNMP_SCALAR_CREATE_NODE(oid, access, asn1_type, get_value_method, set_test_method, set_value_method) \ - {{{ SNMP_NODE_SCALAR, (oid) }, \ - snmp_scalar_get_instance, \ - snmp_scalar_get_next_instance }, \ - (asn1_type), (access), (get_value_method), (set_test_method), (set_value_method) } - -#define SNMP_SCALAR_CREATE_NODE_READONLY(oid, asn1_type, get_value_method) SNMP_SCALAR_CREATE_NODE(oid, SNMP_NODE_INSTANCE_READ_ONLY, asn1_type, get_value_method, NULL, NULL) - -/** scalar array node - a tree node which contains scalars only as children */ -struct snmp_scalar_array_node_def -{ - u32_t oid; - u8_t asn1_type; - snmp_access_t access; -}; - -typedef s16_t (*snmp_scalar_array_get_value_method)(const struct snmp_scalar_array_node_def*, void*); -typedef snmp_err_t (*snmp_scalar_array_set_test_method)(const struct snmp_scalar_array_node_def*, u16_t, void*); -typedef snmp_err_t (*snmp_scalar_array_set_value_method)(const struct snmp_scalar_array_node_def*, u16_t, void*); - -/** basic scalar array node */ -struct snmp_scalar_array_node -{ - /** inherited "base class" members */ - struct snmp_leaf_node node; - u16_t array_node_count; - const struct snmp_scalar_array_node_def* array_nodes; - snmp_scalar_array_get_value_method get_value; - snmp_scalar_array_set_test_method set_test; - snmp_scalar_array_set_value_method set_value; -}; - -snmp_err_t snmp_scalar_array_get_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance); -snmp_err_t snmp_scalar_array_get_next_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance); - -#define SNMP_SCALAR_CREATE_ARRAY_NODE(oid, array_nodes, get_value_method, set_test_method, set_value_method) \ - {{{ SNMP_NODE_SCALAR_ARRAY, (oid) }, \ - snmp_scalar_array_get_instance, \ - snmp_scalar_array_get_next_instance }, \ - (u16_t)LWIP_ARRAYSIZE(array_nodes), (array_nodes), (get_value_method), (set_test_method), (set_value_method) } - -#endif /* LWIP_SNMP */ - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_APPS_SNMP_SCALAR_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/apps/snmp_table.h b/third_party/lwip/repo/lwip/src/include/lwip/apps/snmp_table.h deleted file mode 100644 index 4988b51c2502ea..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/apps/snmp_table.h +++ /dev/null @@ -1,134 +0,0 @@ -/** - * @file - * SNMP server MIB API to implement table nodes - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Martin Hentschel - * - */ - -#ifndef LWIP_HDR_APPS_SNMP_TABLE_H -#define LWIP_HDR_APPS_SNMP_TABLE_H - -#include "lwip/apps/snmp_opts.h" -#include "lwip/apps/snmp_core.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */ - -/** default (customizable) read/write table */ -struct snmp_table_col_def -{ - u32_t index; - u8_t asn1_type; - snmp_access_t access; -}; - -/** table node */ -struct snmp_table_node -{ - /** inherited "base class" members */ - struct snmp_leaf_node node; - u16_t column_count; - const struct snmp_table_col_def* columns; - snmp_err_t (*get_cell_instance)(const u32_t* column, const u32_t* row_oid, u8_t row_oid_len, struct snmp_node_instance* cell_instance); - snmp_err_t (*get_next_cell_instance)(const u32_t* column, struct snmp_obj_id* row_oid, struct snmp_node_instance* cell_instance); - /** returns object value for the given object identifier */ - node_instance_get_value_method get_value; - /** tests length and/or range BEFORE setting */ - node_instance_set_test_method set_test; - /** sets object value, only called when set_test() was successful */ - node_instance_set_value_method set_value; -}; - -snmp_err_t snmp_table_get_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance); -snmp_err_t snmp_table_get_next_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance); - -#define SNMP_TABLE_CREATE(oid, columns, get_cell_instance_method, get_next_cell_instance_method, get_value_method, set_test_method, set_value_method) \ - {{{ SNMP_NODE_TABLE, (oid) }, \ - snmp_table_get_instance, \ - snmp_table_get_next_instance }, \ - (u16_t)LWIP_ARRAYSIZE(columns), (columns), \ - (get_cell_instance_method), (get_next_cell_instance_method), \ - (get_value_method), (set_test_method), (set_value_method)} - -#define SNMP_TABLE_GET_COLUMN_FROM_OID(oid) ((oid)[1]) /* first array value is (fixed) row entry (fixed to 1) and 2nd value is column, follow3ed by instance */ - - -/** simple read-only table */ -typedef enum { - SNMP_VARIANT_VALUE_TYPE_U32, - SNMP_VARIANT_VALUE_TYPE_S32, - SNMP_VARIANT_VALUE_TYPE_PTR, - SNMP_VARIANT_VALUE_TYPE_CONST_PTR -} snmp_table_column_data_type_t; - -struct snmp_table_simple_col_def -{ - u32_t index; - u8_t asn1_type; - snmp_table_column_data_type_t data_type; /* depending of what union member is used to store the value*/ -}; - -/** simple read-only table node */ -struct snmp_table_simple_node -{ - /* inherited "base class" members */ - struct snmp_leaf_node node; - u16_t column_count; - const struct snmp_table_simple_col_def* columns; - snmp_err_t (*get_cell_value)(const u32_t* column, const u32_t* row_oid, u8_t row_oid_len, union snmp_variant_value* value, u32_t* value_len); - snmp_err_t (*get_next_cell_instance_and_value)(const u32_t* column, struct snmp_obj_id* row_oid, union snmp_variant_value* value, u32_t* value_len); -}; - -snmp_err_t snmp_table_simple_get_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance); -snmp_err_t snmp_table_simple_get_next_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance); - -#define SNMP_TABLE_CREATE_SIMPLE(oid, columns, get_cell_value_method, get_next_cell_instance_and_value_method) \ - {{{ SNMP_NODE_TABLE, (oid) }, \ - snmp_table_simple_get_instance, \ - snmp_table_simple_get_next_instance }, \ - (u16_t)LWIP_ARRAYSIZE(columns), (columns), (get_cell_value_method), (get_next_cell_instance_and_value_method) } - -s16_t snmp_table_extract_value_from_s32ref(struct snmp_node_instance* instance, void* value); -s16_t snmp_table_extract_value_from_u32ref(struct snmp_node_instance* instance, void* value); -s16_t snmp_table_extract_value_from_refconstptr(struct snmp_node_instance* instance, void* value); - -#endif /* LWIP_SNMP */ - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_APPS_SNMP_TABLE_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/apps/snmp_threadsync.h b/third_party/lwip/repo/lwip/src/include/lwip/apps/snmp_threadsync.h deleted file mode 100644 index a25dbf2d0f05ce..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/apps/snmp_threadsync.h +++ /dev/null @@ -1,114 +0,0 @@ -/** - * @file - * SNMP server MIB API to implement thread synchronization - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Dirk Ziegelmeier - * - */ - -#ifndef LWIP_HDR_APPS_SNMP_THREADSYNC_H -#define LWIP_HDR_APPS_SNMP_THREADSYNC_H - -#include "lwip/apps/snmp_opts.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#if LWIP_SNMP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/apps/snmp_core.h" -#include "lwip/sys.h" - -typedef void (*snmp_threadsync_called_fn)(void* arg); -typedef void (*snmp_threadsync_synchronizer_fn)(snmp_threadsync_called_fn fn, void* arg); - - -/** Thread sync runtime data. For internal usage only. */ -struct threadsync_data -{ - union { - snmp_err_t err; - s16_t s16; - } retval; - union { - const u32_t *root_oid; - void *value; - } arg1; - union { - u8_t root_oid_len; - u16_t len; - } arg2; - const struct snmp_threadsync_node *threadsync_node; - struct snmp_node_instance proxy_instance; -}; - -/** Thread sync instance. Needed EXCATLY once for every thread to be synced into. */ -struct snmp_threadsync_instance -{ - sys_sem_t sem; - sys_mutex_t sem_usage_mutex; - snmp_threadsync_synchronizer_fn sync_fn; - struct threadsync_data data; -}; - -/** SNMP thread sync proxy leaf node */ -struct snmp_threadsync_node -{ - /* inherited "base class" members */ - struct snmp_leaf_node node; - - const struct snmp_leaf_node *target; - struct snmp_threadsync_instance *instance; -}; - -snmp_err_t snmp_threadsync_get_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance); -snmp_err_t snmp_threadsync_get_next_instance(const u32_t *root_oid, u8_t root_oid_len, struct snmp_node_instance* instance); - -/** Create thread sync proxy node */ -#define SNMP_CREATE_THREAD_SYNC_NODE(oid, target_leaf_node, threadsync_instance) \ - {{{ SNMP_NODE_THREADSYNC, (oid) }, \ - snmp_threadsync_get_instance, \ - snmp_threadsync_get_next_instance }, \ - (target_leaf_node), \ - (threadsync_instance) } - -/** Create thread sync instance data */ -void snmp_threadsync_init(struct snmp_threadsync_instance *instance, snmp_threadsync_synchronizer_fn sync_fn); - -#endif /* LWIP_SNMP */ - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_APPS_SNMP_THREADSYNC_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/apps/snmpv3.h b/third_party/lwip/repo/lwip/src/include/lwip/apps/snmpv3.h deleted file mode 100644 index c99fed4e101aa5..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/apps/snmpv3.h +++ /dev/null @@ -1,90 +0,0 @@ -/** - * @file - * Additional SNMPv3 functionality RFC3414 and RFC3826. - */ - -/* - * Copyright (c) 2016 Elias Oenal. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * Author: Elias Oenal - */ - -#ifndef LWIP_HDR_APPS_SNMP_V3_H -#define LWIP_HDR_APPS_SNMP_V3_H - -#include "lwip/apps/snmp_opts.h" -#include "lwip/err.h" - -#if LWIP_SNMP && LWIP_SNMP_V3 - -#define SNMP_V3_AUTH_ALGO_INVAL 0 -#define SNMP_V3_AUTH_ALGO_MD5 1 -#define SNMP_V3_AUTH_ALGO_SHA 2 - -#define SNMP_V3_PRIV_ALGO_INVAL 0 -#define SNMP_V3_PRIV_ALGO_DES 1 -#define SNMP_V3_PRIV_ALGO_AES 2 - -#define SNMP_V3_PRIV_MODE_DECRYPT 0 -#define SNMP_V3_PRIV_MODE_ENCRYPT 1 - -/* - * The following callback functions must be implemented by the application. - * There is a dummy implementation in snmpv3_dummy.c. - */ - -void snmpv3_get_engine_id(const char **id, u8_t *len); -err_t snmpv3_set_engine_id(const char* id, u8_t len); - -u32_t snmpv3_get_engine_boots(void); -void snmpv3_set_engine_boots(u32_t boots); - -u32_t snmpv3_get_engine_time(void); -void snmpv3_reset_engine_time(void); - -err_t snmpv3_get_user(const char* username, u8_t *auth_algo, u8_t *auth_key, u8_t *priv_algo, u8_t *priv_key); - -/* The following functions are provided by the SNMPv3 agent */ - -void snmpv3_engine_id_changed(void); - -void snmpv3_password_to_key_md5( - const u8_t *password, /* IN */ - u8_t passwordlen, /* IN */ - const u8_t *engineID, /* IN - pointer to snmpEngineID */ - u8_t engineLength, /* IN - length of snmpEngineID */ - u8_t *key); /* OUT - pointer to caller 16-octet buffer */ - -void snmpv3_password_to_key_sha( - const u8_t *password, /* IN */ - u8_t passwordlen, /* IN */ - const u8_t *engineID, /* IN - pointer to snmpEngineID */ - u8_t engineLength, /* IN - length of snmpEngineID */ - u8_t *key); /* OUT - pointer to caller 20-octet buffer */ - -#endif - -#endif /* LWIP_HDR_APPS_SNMP_V3_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/apps/sntp.h b/third_party/lwip/repo/lwip/src/include/lwip/apps/sntp.h deleted file mode 100644 index 40df9cc590fc95..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/apps/sntp.h +++ /dev/null @@ -1,76 +0,0 @@ -/** - * @file - * SNTP client API - */ - -/* - * Copyright (c) 2007-2009 Frédéric Bernon, Simon Goldschmidt - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Frédéric Bernon, Simon Goldschmidt - * - */ -#ifndef LWIP_HDR_APPS_SNTP_H -#define LWIP_HDR_APPS_SNTP_H - -#include "lwip/apps/sntp_opts.h" -#include "lwip/ip_addr.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* SNTP operating modes: default is to poll using unicast. - The mode has to be set before calling sntp_init(). */ -#define SNTP_OPMODE_POLL 0 -#define SNTP_OPMODE_LISTENONLY 1 -void sntp_setoperatingmode(u8_t operating_mode); -u8_t sntp_getoperatingmode(void); - -void sntp_init(void); -void sntp_stop(void); -u8_t sntp_enabled(void); - -void sntp_setserver(u8_t idx, const ip_addr_t *addr); -const ip_addr_t* sntp_getserver(u8_t idx); - -#if SNTP_SERVER_DNS -void sntp_setservername(u8_t idx, char *server); -char *sntp_getservername(u8_t idx); -#endif /* SNTP_SERVER_DNS */ - -#if SNTP_GET_SERVERS_FROM_DHCP -void sntp_servermode_dhcp(int set_servers_from_dhcp); -#else /* SNTP_GET_SERVERS_FROM_DHCP */ -#define sntp_servermode_dhcp(x) -#endif /* SNTP_GET_SERVERS_FROM_DHCP */ - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_APPS_SNTP_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/apps/sntp_opts.h b/third_party/lwip/repo/lwip/src/include/lwip/apps/sntp_opts.h deleted file mode 100644 index f3651f90e6d040..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/apps/sntp_opts.h +++ /dev/null @@ -1,173 +0,0 @@ -/** - * @file - * SNTP client options list - */ - -/* - * Copyright (c) 2007-2009 Frédéric Bernon, Simon Goldschmidt - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Frédéric Bernon, Simon Goldschmidt - * - */ -#ifndef LWIP_HDR_APPS_SNTP_OPTS_H -#define LWIP_HDR_APPS_SNTP_OPTS_H - -#include "lwip/opt.h" - -/** - * @defgroup sntp_opts Options - * @ingroup sntp - * @{ - */ - -/** SNTP macro to change system time in seconds - * Define SNTP_SET_SYSTEM_TIME_US(sec, us) to set the time in microseconds instead of this one - * if you need the additional precision. - */ -#if !defined SNTP_SET_SYSTEM_TIME || defined __DOXYGEN__ -#define SNTP_SET_SYSTEM_TIME(sec) LWIP_UNUSED_ARG(sec) -#endif - -/** The maximum number of SNTP servers that can be set */ -#if !defined SNTP_MAX_SERVERS || defined __DOXYGEN__ -#define SNTP_MAX_SERVERS LWIP_DHCP_MAX_NTP_SERVERS -#endif - -/** Set this to 1 to implement the callback function called by dhcp when - * NTP servers are received. */ -#if !defined SNTP_GET_SERVERS_FROM_DHCP || defined __DOXYGEN__ -#define SNTP_GET_SERVERS_FROM_DHCP LWIP_DHCP_GET_NTP_SRV -#endif - -/** Set this to 1 to support DNS names (or IP address strings) to set sntp servers - * One server address/name can be defined as default if SNTP_SERVER_DNS == 1: - * \#define SNTP_SERVER_ADDRESS "pool.ntp.org" - */ -#if !defined SNTP_SERVER_DNS || defined __DOXYGEN__ -#define SNTP_SERVER_DNS 0 -#endif - -/** - * SNTP_DEBUG: Enable debugging for SNTP. - */ -#if !defined SNTP_DEBUG || defined __DOXYGEN__ -#define SNTP_DEBUG LWIP_DBG_OFF -#endif - -/** SNTP server port */ -#if !defined SNTP_PORT || defined __DOXYGEN__ -#define SNTP_PORT 123 -#endif - -/** Set this to 1 to allow config of SNTP server(s) by DNS name */ -#if !defined SNTP_SERVER_DNS || defined __DOXYGEN__ -#define SNTP_SERVER_DNS 0 -#endif - -/** Sanity check: - * Define this to - * - 0 to turn off sanity checks (default; smaller code) - * - >= 1 to check address and port of the response packet to ensure the - * response comes from the server we sent the request to. - * - >= 2 to check returned Originate Timestamp against Transmit Timestamp - * sent to the server (to ensure response to older request). - * - >= 3 @todo: discard reply if any of the LI, Stratum, or Transmit Timestamp - * fields is 0 or the Mode field is not 4 (unicast) or 5 (broadcast). - * - >= 4 @todo: to check that the Root Delay and Root Dispersion fields are each - * greater than or equal to 0 and less than infinity, where infinity is - * currently a cozy number like one second. This check avoids using a - * server whose synchronization source has expired for a very long time. - */ -#if !defined SNTP_CHECK_RESPONSE || defined __DOXYGEN__ -#define SNTP_CHECK_RESPONSE 0 -#endif - -/** According to the RFC, this shall be a random delay - * between 1 and 5 minutes (in milliseconds) to prevent load peaks. - * This can be defined to a random generation function, - * which must return the delay in milliseconds as u32_t. - * Turned off by default. - */ -#if !defined SNTP_STARTUP_DELAY || defined __DOXYGEN__ -#define SNTP_STARTUP_DELAY 0 -#endif - -/** If you want the startup delay to be a function, define this - * to a function (including the brackets) and define SNTP_STARTUP_DELAY to 1. - */ -#if !defined SNTP_STARTUP_DELAY_FUNC || defined __DOXYGEN__ -#define SNTP_STARTUP_DELAY_FUNC SNTP_STARTUP_DELAY -#endif - -/** SNTP receive timeout - in milliseconds - * Also used as retry timeout - this shouldn't be too low. - * Default is 3 seconds. - */ -#if !defined SNTP_RECV_TIMEOUT || defined __DOXYGEN__ -#define SNTP_RECV_TIMEOUT 3000 -#endif - -/** SNTP update delay - in milliseconds - * Default is 1 hour. Must not be beolw 15 seconds by specification (i.e. 15000) - */ -#if !defined SNTP_UPDATE_DELAY || defined __DOXYGEN__ -#define SNTP_UPDATE_DELAY 3600000 -#endif - -/** SNTP macro to get system time, used with SNTP_CHECK_RESPONSE >= 2 - * to send in request and compare in response. - */ -#if !defined SNTP_GET_SYSTEM_TIME || defined __DOXYGEN__ -#define SNTP_GET_SYSTEM_TIME(sec, us) do { (sec) = 0; (us) = 0; } while(0) -#endif - -/** Default retry timeout (in milliseconds) if the response - * received is invalid. - * This is doubled with each retry until SNTP_RETRY_TIMEOUT_MAX is reached. - */ -#if !defined SNTP_RETRY_TIMEOUT || defined __DOXYGEN__ -#define SNTP_RETRY_TIMEOUT SNTP_RECV_TIMEOUT -#endif - -/** Maximum retry timeout (in milliseconds). */ -#if !defined SNTP_RETRY_TIMEOUT_MAX || defined __DOXYGEN__ -#define SNTP_RETRY_TIMEOUT_MAX (SNTP_RETRY_TIMEOUT * 10) -#endif - -/** Increase retry timeout with every retry sent - * Default is on to conform to RFC. - */ -#if !defined SNTP_RETRY_TIMEOUT_EXP || defined __DOXYGEN__ -#define SNTP_RETRY_TIMEOUT_EXP 1 -#endif - -/** - * @} - */ - -#endif /* LWIP_HDR_APPS_SNTP_OPTS_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/apps/tftp_opts.h b/third_party/lwip/repo/lwip/src/include/lwip/apps/tftp_opts.h deleted file mode 100644 index 6968a803b439fe..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/apps/tftp_opts.h +++ /dev/null @@ -1,105 +0,0 @@ -/****************************************************************//** - * - * @file tftp_opts.h - * - * @author Logan Gunthorpe - * - * @brief Trivial File Transfer Protocol (RFC 1350) implementation options - * - * Copyright (c) Deltatee Enterprises Ltd. 2013 - * All rights reserved. - * - ********************************************************************/ - -/* - * Redistribution and use in source and binary forms, with or without - * modification,are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO - * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Author: Logan Gunthorpe - * - */ - -#ifndef LWIP_HDR_APPS_TFTP_OPTS_H -#define LWIP_HDR_APPS_TFTP_OPTS_H - -#include "lwip/opt.h" - -/** - * @defgroup tftp_opts Options - * @ingroup tftp - * @{ - */ - -/** - * Enable TFTP debug messages - */ -#if !defined TFTP_DEBUG || defined __DOXYGEN__ -#define TFTP_DEBUG LWIP_DBG_ON -#endif - -/** - * TFTP server port - */ -#if !defined TFTP_PORT || defined __DOXYGEN__ -#define TFTP_PORT 69 -#endif - -/** - * TFTP timeout - */ -#if !defined TFTP_TIMEOUT_MSECS || defined __DOXYGEN__ -#define TFTP_TIMEOUT_MSECS 10000 -#endif - -/** - * Max. number of retries when a file is read from server - */ -#if !defined TFTP_MAX_RETRIES || defined __DOXYGEN__ -#define TFTP_MAX_RETRIES 5 -#endif - -/** - * TFTP timer cyclic interval - */ -#if !defined TFTP_TIMER_MSECS || defined __DOXYGEN__ -#define TFTP_TIMER_MSECS 50 -#endif - -/** - * Max. length of TFTP filename - */ -#if !defined TFTP_MAX_FILENAME_LEN || defined __DOXYGEN__ -#define TFTP_MAX_FILENAME_LEN 20 -#endif - -/** - * Max. length of TFTP mode - */ -#if !defined TFTP_MAX_MODE_LEN || defined __DOXYGEN__ -#define TFTP_MAX_MODE_LEN 7 -#endif - -/** - * @} - */ - -#endif /* LWIP_HDR_APPS_TFTP_OPTS_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/apps/tftp_server.h b/third_party/lwip/repo/lwip/src/include/lwip/apps/tftp_server.h deleted file mode 100644 index 3fbe701e0a23dc..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/apps/tftp_server.h +++ /dev/null @@ -1,94 +0,0 @@ -/****************************************************************//** - * - * @file tftp_server.h - * - * @author Logan Gunthorpe - * - * @brief Trivial File Transfer Protocol (RFC 1350) - * - * Copyright (c) Deltatee Enterprises Ltd. 2013 - * All rights reserved. - * - ********************************************************************/ - -/* - * Redistribution and use in source and binary forms, with or without - * modification,are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO - * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * - * Author: Logan Gunthorpe - * - */ - -#ifndef LWIP_HDR_APPS_TFTP_SERVER_H -#define LWIP_HDR_APPS_TFTP_SERVER_H - -#include "lwip/apps/tftp_opts.h" -#include "lwip/err.h" -#include "lwip/pbuf.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** @ingroup tftp - * TFTP context containing callback functions for TFTP transfers - */ -struct tftp_context { - /** - * Open file for read/write. - * @param fname Filename - * @param mode Mode string from TFTP RFC 1350 (netascii, octet, mail) - * @param write Flag indicating read (0) or write (!= 0) access - * @returns File handle supplied to other functions - */ - void* (*open)(const char* fname, const char* mode, u8_t write); - /** - * Close file handle - * @param handle File handle returned by open() - */ - void (*close)(void* handle); - /** - * Read from file - * @param handle File handle returned by open() - * @param buf Target buffer to copy read data to - * @param bytes Number of bytes to copy to buf - * @returns >= 0: Success; < 0: Error - */ - int (*read)(void* handle, void* buf, int bytes); - /** - * Write to file - * @param handle File handle returned by open() - * @param pbuf PBUF adjusted such that payload pointer points - * to the beginning of write data. In other words, - * TFTP headers are stripped off. - * @returns >= 0: Success; < 0: Error - */ - int (*write)(void* handle, struct pbuf* p); -}; - -err_t tftp_init(const struct tftp_context* ctx); - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_APPS_TFTP_SERVER_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/arch.h b/third_party/lwip/repo/lwip/src/include/lwip/arch.h deleted file mode 100644 index 1ab171ba60e6ab..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/arch.h +++ /dev/null @@ -1,323 +0,0 @@ -/** - * @file - * Support for different processor and compiler architectures - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_ARCH_H -#define LWIP_HDR_ARCH_H - -#if CHIP_HAVE_CONFIG_H -#include -#endif - -#ifndef LITTLE_ENDIAN -#define LITTLE_ENDIAN 1234 -#endif - -#ifndef BIG_ENDIAN -#define BIG_ENDIAN 4321 -#endif - -#include "arch/cc.h" - -/** - * @defgroup compiler_abstraction Compiler/platform abstraction - * @ingroup sys_layer - * All defines related to this section must not be placed in lwipopts.h, - * but in arch/cc.h! - * These options cannot be \#defined in lwipopts.h since they are not options - * of lwIP itself, but options of the lwIP port to your system. - * @{ - */ - -/** Define the byte order of the system. - * Needed for conversion of network data to host byte order. - * Allowed values: LITTLE_ENDIAN and BIG_ENDIAN - */ -#ifndef BYTE_ORDER -#define BYTE_ORDER LITTLE_ENDIAN -#endif - -/** Define random number generator function of your system */ -#ifdef __DOXYGEN__ -#define LWIP_RAND() ((u32_t)rand()) -#endif - -/** Platform specific diagnostic output.\n - * Note the default implementation pulls in printf, which may - * in turn pull in a lot of standard libary code. In resource-constrained - * systems, this should be defined to something less resource-consuming. - */ -#ifndef LWIP_PLATFORM_DIAG -#define LWIP_PLATFORM_DIAG(x) do {printf x;} while(0) -#include -#include -#endif - -/** Platform specific assertion handling.\n - * Note the default implementation pulls in printf, fflush and abort, which may - * in turn pull in a lot of standard libary code. In resource-constrained - * systems, this should be defined to something less resource-consuming. - */ -#ifndef LWIP_PLATFORM_ASSERT -#define LWIP_PLATFORM_ASSERT(x) do {printf("Assertion \"%s\" failed at line %d in %s\n", \ - x, __LINE__, __FILE__); fflush(NULL); abort();} while(0) -#include -#include -#endif - -/** Define this to 1 in arch/cc.h of your port if you do not want to - * include stddef.h header to get size_t. You need to typedef size_t - * by yourself in this case. - */ -#ifndef LWIP_NO_STDDEF_H -#define LWIP_NO_STDDEF_H 0 -#endif - -#if !LWIP_NO_STDDEF_H -#include /* for size_t */ -#endif - -/** Define this to 1 in arch/cc.h of your port if your compiler does not provide - * the stdint.h header. You need to typedef the generic types listed in - * lwip/arch.h yourself in this case (u8_t, u16_t...). - */ -#ifndef LWIP_NO_STDINT_H -#define LWIP_NO_STDINT_H 0 -#endif - -/* Define generic types used in lwIP */ -#if !LWIP_NO_STDINT_H -#include -typedef uint8_t u8_t; -typedef int8_t s8_t; -typedef uint16_t u16_t; -typedef int16_t s16_t; -typedef uint32_t u32_t; -typedef int32_t s32_t; -typedef uintptr_t mem_ptr_t; -#endif - -/** Define this to 1 in arch/cc.h of your port if your compiler does not provide - * the inttypes.h header. You need to define the format strings listed in - * lwip/arch.h yourself in this case (X8_F, U16_F...). - */ -#ifndef LWIP_NO_INTTYPES_H -#define LWIP_NO_INTTYPES_H 0 -#endif - -/* Define (sn)printf formatters for these lwIP types */ -#if !LWIP_NO_INTTYPES_H -#include -#ifndef X8_F -#define X8_F "02" PRIx8 -#endif -#ifndef U16_F -#define U16_F PRIu16 -#endif -#ifndef S16_F -#define S16_F PRId16 -#endif -#ifndef X16_F -#define X16_F PRIx16 -#endif -#ifndef U32_F -#define U32_F PRIu32 -#endif -#ifndef S32_F -#define S32_F PRId32 -#endif -#ifndef X32_F -#define X32_F PRIx32 -#endif -#ifndef SZT_F -#define SZT_F PRIuPTR -#endif -#endif - -/** Define this to 1 in arch/cc.h of your port if your compiler does not provide - * the limits.h header. You need to define the type limits yourself in this case - * (e.g. INT_MAX). - */ -#ifndef LWIP_NO_LIMITS_H -#define LWIP_NO_LIMITS_H 0 -#endif - -/* Include limits.h? */ -#if !LWIP_NO_LIMITS_H -#include -#endif - -/** C++ const_cast(val) equivalent to remove constness from a value (GCC -Wcast-qual) */ -#ifndef LWIP_CONST_CAST -#define LWIP_CONST_CAST(target_type, val) ((target_type)((ptrdiff_t)val)) -#endif - -/** Get rid of alignment cast warnings (GCC -Wcast-align) */ -#ifndef LWIP_ALIGNMENT_CAST -#define LWIP_ALIGNMENT_CAST(target_type, val) LWIP_CONST_CAST(target_type, val) -#endif - -/** Get rid of warnings related to pointer-to-numeric and vice-versa casts, - * e.g. "conversion from 'u8_t' to 'void *' of greater size" - */ -#ifndef LWIP_PTR_NUMERIC_CAST -#define LWIP_PTR_NUMERIC_CAST(target_type, val) LWIP_CONST_CAST(target_type, val) -#endif - -/** Allocates a memory buffer of specified size that is of sufficient size to align - * its start address using LWIP_MEM_ALIGN. - * You can declare your own version here e.g. to enforce alignment without adding - * trailing padding bytes (see LWIP_MEM_ALIGN_BUFFER) or your own section placement - * requirements.\n - * e.g. if you use gcc and need 32 bit alignment:\n - * \#define LWIP_DECLARE_MEMORY_ALIGNED(variable_name, size) u8_t variable_name[size] \_\_attribute\_\_((aligned(4)))\n - * or more portable:\n - * \#define LWIP_DECLARE_MEMORY_ALIGNED(variable_name, size) u32_t variable_name[(size + sizeof(u32_t) - 1) / sizeof(u32_t)] - */ -#ifndef LWIP_DECLARE_MEMORY_ALIGNED -#define LWIP_DECLARE_MEMORY_ALIGNED(variable_name, size) u8_t variable_name[LWIP_MEM_ALIGN_BUFFER(size)] -#endif - -/** Calculate memory size for an aligned buffer - returns the next highest - * multiple of MEM_ALIGNMENT (e.g. LWIP_MEM_ALIGN_SIZE(3) and - * LWIP_MEM_ALIGN_SIZE(4) will both yield 4 for MEM_ALIGNMENT == 4). - */ -#ifndef LWIP_MEM_ALIGN_SIZE -#define LWIP_MEM_ALIGN_SIZE(size) (((size) + MEM_ALIGNMENT - 1U) & ~(MEM_ALIGNMENT-1U)) -#endif - -/** Calculate safe memory size for an aligned buffer when using an unaligned - * type as storage. This includes a safety-margin on (MEM_ALIGNMENT - 1) at the - * start (e.g. if buffer is u8_t[] and actual data will be u32_t*) - */ -#ifndef LWIP_MEM_ALIGN_BUFFER -#define LWIP_MEM_ALIGN_BUFFER(size) (((size) + MEM_ALIGNMENT - 1U)) -#endif - -/** Align a memory pointer to the alignment defined by MEM_ALIGNMENT - * so that ADDR % MEM_ALIGNMENT == 0 - */ -#ifndef LWIP_MEM_ALIGN -#define LWIP_MEM_ALIGN(addr) ((void *)(((mem_ptr_t)(addr) + MEM_ALIGNMENT - 1) & ~(mem_ptr_t)(MEM_ALIGNMENT-1))) -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/** Packed structs support. - * Placed BEFORE declaration of a packed struct.\n - * For examples of packed struct declarations, see include/lwip/prot/ subfolder.\n - * A port to GCC/clang is included in lwIP, if you use these compilers there is nothing to do here. - */ -#ifndef PACK_STRUCT_BEGIN -#define PACK_STRUCT_BEGIN -#endif /* PACK_STRUCT_BEGIN */ - -/** Packed structs support. - * Placed AFTER declaration of a packed struct.\n - * For examples of packed struct declarations, see include/lwip/prot/ subfolder.\n - * A port to GCC/clang is included in lwIP, if you use these compilers there is nothing to do here. - */ -#ifndef PACK_STRUCT_END -#define PACK_STRUCT_END -#endif /* PACK_STRUCT_END */ - -/** Packed structs support. - * Placed between end of declaration of a packed struct and trailing semicolon.\n - * For examples of packed struct declarations, see include/lwip/prot/ subfolder.\n - * A port to GCC/clang is included in lwIP, if you use these compilers there is nothing to do here. - */ -#ifndef PACK_STRUCT_STRUCT -#if defined(__GNUC__) || defined(__clang__) -#define PACK_STRUCT_STRUCT __attribute__((packed)) -#else -#define PACK_STRUCT_STRUCT -#endif -#endif /* PACK_STRUCT_STRUCT */ - -/** Packed structs support. - * Wraps u32_t and u16_t members.\n - * For examples of packed struct declarations, see include/lwip/prot/ subfolder.\n - * A port to GCC/clang is included in lwIP, if you use these compilers there is nothing to do here. - */ -#ifndef PACK_STRUCT_FIELD -#define PACK_STRUCT_FIELD(x) x -#endif /* PACK_STRUCT_FIELD */ - -/** Packed structs support. - * Wraps u8_t members, where some compilers warn that packing is not necessary.\n - * For examples of packed struct declarations, see include/lwip/prot/ subfolder.\n - * A port to GCC/clang is included in lwIP, if you use these compilers there is nothing to do here. - */ -#ifndef PACK_STRUCT_FLD_8 -#define PACK_STRUCT_FLD_8(x) PACK_STRUCT_FIELD(x) -#endif /* PACK_STRUCT_FLD_8 */ - -/** Packed structs support. - * Wraps members that are packed structs themselves, where some compilers warn that packing is not necessary.\n - * For examples of packed struct declarations, see include/lwip/prot/ subfolder.\n - * A port to GCC/clang is included in lwIP, if you use these compilers there is nothing to do here. - */ -#ifndef PACK_STRUCT_FLD_S -#define PACK_STRUCT_FLD_S(x) PACK_STRUCT_FIELD(x) -#endif /* PACK_STRUCT_FLD_S */ - -/** Packed structs support using \#include files before and after struct to be packed.\n - * The file included BEFORE the struct is "arch/bpstruct.h".\n - * The file included AFTER the struct is "arch/epstruct.h".\n - * This can be used to implement struct packing on MS Visual C compilers, see - * the Win32 port in the lwIP contrib repository for reference. - * For examples of packed struct declarations, see include/lwip/prot/ subfolder.\n - * A port to GCC/clang is included in lwIP, if you use these compilers there is nothing to do here. - */ -#ifdef __DOXYGEN__ -#define PACK_STRUCT_USE_INCLUDES -#endif - -/** Eliminates compiler warning about unused arguments (GCC -Wextra -Wunused). */ -#ifndef LWIP_UNUSED_ARG -#define LWIP_UNUSED_ARG(x) (void)x -#endif /* LWIP_UNUSED_ARG */ - -/** - * @} - */ - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_ARCH_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/autoip.h b/third_party/lwip/repo/lwip/src/include/lwip/autoip.h deleted file mode 100644 index 3a8ca35f89c483..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/autoip.h +++ /dev/null @@ -1,99 +0,0 @@ -/** - * @file - * - * AutoIP Automatic LinkLocal IP Configuration - */ - -/* - * - * Copyright (c) 2007 Dominik Spies - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * Author: Dominik Spies - * - * This is a AutoIP implementation for the lwIP TCP/IP stack. It aims to conform - * with RFC 3927. - * - */ - -#ifndef LWIP_HDR_AUTOIP_H -#define LWIP_HDR_AUTOIP_H - -#include "lwip/opt.h" - -#if LWIP_IPV4 && LWIP_AUTOIP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/netif.h" -/* #include "lwip/udp.h" */ -#include "lwip/etharp.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** AutoIP Timing */ -#define AUTOIP_TMR_INTERVAL 100 -#define AUTOIP_TICKS_PER_SECOND (1000 / AUTOIP_TMR_INTERVAL) - -/** AutoIP state information per netif */ -struct autoip -{ - /** the currently selected, probed, announced or used LL IP-Address */ - ip4_addr_t llipaddr; - /** current AutoIP state machine state */ - u8_t state; - /** sent number of probes or announces, dependent on state */ - u8_t sent_num; - /** ticks to wait, tick is AUTOIP_TMR_INTERVAL long */ - u16_t ttw; - /** ticks until a conflict can be solved by defending */ - u8_t lastconflict; - /** total number of probed/used Link Local IP-Addresses */ - u8_t tried_llipaddr; -}; - - -void autoip_set_struct(struct netif *netif, struct autoip *autoip); -/** Remove a struct autoip previously set to the netif using autoip_set_struct() */ -#define autoip_remove_struct(netif) netif_set_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_AUTOIP, NULL) -err_t autoip_start(struct netif *netif); -err_t autoip_stop(struct netif *netif); -void autoip_arp_reply(struct netif *netif, struct etharp_hdr *hdr); -void autoip_tmr(void); -void autoip_network_changed(struct netif *netif); -u8_t autoip_supplied_address(const struct netif *netif); - -/* for lwIP internal use by ip4.c */ -u8_t autoip_accept_packet(struct netif *netif, const ip4_addr_t *addr); - -#define netif_autoip_data(netif) ((struct autoip*)netif_get_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_AUTOIP)) - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_IPV4 && LWIP_AUTOIP */ - -#endif /* LWIP_HDR_AUTOIP_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/debug.h b/third_party/lwip/repo/lwip/src/include/lwip/debug.h deleted file mode 100644 index a142f1cff3c9aa..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/debug.h +++ /dev/null @@ -1,167 +0,0 @@ -/** - * @file - * Debug messages infrastructure - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_DEBUG_H -#define LWIP_HDR_DEBUG_H - -#include "lwip/arch.h" -#include "lwip/opt.h" - -/** - * @defgroup debugging_levels LWIP_DBG_MIN_LEVEL and LWIP_DBG_TYPES_ON values - * @ingroup lwip_opts_debugmsg - * @{ - */ - -/** @name Debug level (LWIP_DBG_MIN_LEVEL) - * @{ - */ -/** Debug level: ALL messages*/ -#define LWIP_DBG_LEVEL_ALL 0x00 -/** Debug level: Warnings. bad checksums, dropped packets, ... */ -#define LWIP_DBG_LEVEL_WARNING 0x01 -/** Debug level: Serious. memory allocation failures, ... */ -#define LWIP_DBG_LEVEL_SERIOUS 0x02 -/** Debug level: Severe */ -#define LWIP_DBG_LEVEL_SEVERE 0x03 -/** - * @} - */ - -#define LWIP_DBG_MASK_LEVEL 0x03 -/* compatibility define only */ -#define LWIP_DBG_LEVEL_OFF LWIP_DBG_LEVEL_ALL - -/** @name Enable/disable debug messages completely (LWIP_DBG_TYPES_ON) - * @{ - */ -/** flag for LWIP_DEBUGF to enable that debug message */ -#define LWIP_DBG_ON 0x80U -/** flag for LWIP_DEBUGF to disable that debug message */ -#define LWIP_DBG_OFF 0x00U -/** - * @} - */ - -/** @name Debug message types (LWIP_DBG_TYPES_ON) - * @{ - */ -/** flag for LWIP_DEBUGF indicating a tracing message (to follow program flow) */ -#define LWIP_DBG_TRACE 0x40U -/** flag for LWIP_DEBUGF indicating a state debug message (to follow module states) */ -#define LWIP_DBG_STATE 0x20U -/** flag for LWIP_DEBUGF indicating newly added code, not thoroughly tested yet */ -#define LWIP_DBG_FRESH 0x10U -/** flag for LWIP_DEBUGF to halt after printing this debug message */ -#define LWIP_DBG_HALT 0x08U -/** - * @} - */ - -/** - * @} - */ - -/** - * @defgroup lwip_assertions Assertion handling - * @ingroup lwip_opts_debug - * @{ - */ -/** - * LWIP_NOASSERT: Disable LWIP_ASSERT checks: - * To disable assertions define LWIP_NOASSERT in arch/cc.h. - */ -#ifdef __DOXYGEN__ -#define LWIP_NOASSERT -#undef LWIP_NOASSERT -#endif -/** - * @} - */ - -#ifndef LWIP_NOASSERT -#define LWIP_ASSERT(message, assertion) do { if (!(assertion)) { \ - LWIP_PLATFORM_ASSERT(message); }} while(0) -#ifndef LWIP_PLATFORM_ASSERT -#error "If you want to use LWIP_ASSERT, LWIP_PLATFORM_ASSERT(message) needs to be defined in your arch/cc.h" -#endif -#else /* LWIP_NOASSERT */ -#define LWIP_ASSERT(message, assertion) -#endif /* LWIP_NOASSERT */ - -#ifndef LWIP_ERROR -#ifndef LWIP_NOASSERT -#define LWIP_PLATFORM_ERROR(message) LWIP_PLATFORM_ASSERT(message) -#elif defined LWIP_DEBUG -#define LWIP_PLATFORM_ERROR(message) LWIP_PLATFORM_DIAG((message)) -#else -#define LWIP_PLATFORM_ERROR(message) -#endif - -/* if "expression" isn't true, then print "message" and execute "handler" expression */ -#define LWIP_ERROR(message, expression, handler) do { if (!(expression)) { \ - LWIP_PLATFORM_ERROR(message); handler;}} while(0) -#endif /* LWIP_ERROR */ - -/** Enable debug message printing, but only if debug message type is enabled - * AND is of correct type AND is at least LWIP_DBG_LEVEL. - */ -#ifdef __DOXYGEN__ -#define LWIP_DEBUG -#undef LWIP_DEBUG -#endif - -#ifdef LWIP_DEBUG -#ifndef LWIP_PLATFORM_DIAG -#error "If you want to use LWIP_DEBUG, LWIP_PLATFORM_DIAG(message) needs to be defined in your arch/cc.h" -#endif -#define LWIP_DEBUGF(debug, message) do { \ - if ( \ - ((debug) & LWIP_DBG_ON) && \ - ((debug) & LWIP_DBG_TYPES_ON) && \ - ((s16_t)((debug) & LWIP_DBG_MASK_LEVEL) >= LWIP_DBG_MIN_LEVEL)) { \ - LWIP_PLATFORM_DIAG(message); \ - if ((debug) & LWIP_DBG_HALT) { \ - while(1); \ - } \ - } \ - } while(0) - -#else /* LWIP_DEBUG */ -#define LWIP_DEBUGF(debug, message) -#endif /* LWIP_DEBUG */ - -#endif /* LWIP_HDR_DEBUG_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/def.h b/third_party/lwip/repo/lwip/src/include/lwip/def.h deleted file mode 100644 index 82a9d896f0fc98..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/def.h +++ /dev/null @@ -1,141 +0,0 @@ -/** - * @file - * various utility macros - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_DEF_H -#define LWIP_HDR_DEF_H - -/* arch.h might define NULL already */ -#include "lwip/arch.h" -#include "lwip/opt.h" -#if LWIP_PERF -#include "arch/perf.h" -#else /* LWIP_PERF */ -#define PERF_START /* null definition */ -#define PERF_STOP(x) /* null definition */ -#endif /* LWIP_PERF */ - -#ifdef __cplusplus -extern "C" { -#endif - -#define LWIP_MAX(x , y) (((x) > (y)) ? (x) : (y)) -#define LWIP_MIN(x , y) (((x) < (y)) ? (x) : (y)) - -/* Get the number of entries in an array ('x' must NOT be a pointer!) */ -#define LWIP_ARRAYSIZE(x) (sizeof(x)/sizeof((x)[0])) - -/** Create u32_t value from bytes */ -#define LWIP_MAKEU32(a,b,c,d) (((u32_t)((a) & 0xff) << 24) | \ - ((u32_t)((b) & 0xff) << 16) | \ - ((u32_t)((c) & 0xff) << 8) | \ - (u32_t)((d) & 0xff)) - -#ifndef NULL -#ifdef __cplusplus -#define NULL 0 -#else -#define NULL ((void *)0) -#endif -#endif - -#if BYTE_ORDER == BIG_ENDIAN -#define lwip_htons(x) (x) -#define lwip_ntohs(x) (x) -#define lwip_htonl(x) (x) -#define lwip_ntohl(x) (x) -#define PP_HTONS(x) (x) -#define PP_NTOHS(x) (x) -#define PP_HTONL(x) (x) -#define PP_NTOHL(x) (x) -#else /* BYTE_ORDER != BIG_ENDIAN */ -#ifndef lwip_htons -u16_t lwip_htons(u16_t x); -#endif -#define lwip_ntohs(x) lwip_htons(x) - -#ifndef lwip_htonl -u32_t lwip_htonl(u32_t x); -#endif -#define lwip_ntohl(x) lwip_htonl(x) - -/* These macros should be calculated by the preprocessor and are used - with compile-time constants only (so that there is no little-endian - overhead at runtime). */ -#define PP_HTONS(x) ((((x) & 0x00ffUL) << 8) | (((x) & 0xff00UL) >> 8)) -#define PP_NTOHS(x) PP_HTONS(x) -#define PP_HTONL(x) ((((x) & 0x000000ffUL) << 24) | \ - (((x) & 0x0000ff00UL) << 8) | \ - (((x) & 0x00ff0000UL) >> 8) | \ - (((x) & 0xff000000UL) >> 24)) -#define PP_NTOHL(x) PP_HTONL(x) -#endif /* BYTE_ORDER == BIG_ENDIAN */ - -/* Provide usual function names as macros for users, but this can be turned off */ -#ifndef LWIP_DONT_PROVIDE_BYTEORDER_FUNCTIONS -#define htons(x) lwip_htons(x) -#define ntohs(x) lwip_ntohs(x) -#define htonl(x) lwip_htonl(x) -#define ntohl(x) lwip_ntohl(x) -#endif - -/* Functions that are not available as standard implementations. - * In cc.h, you can #define these to implementations available on - * your platform to save some code bytes if you use these functions - * in your application, too. - */ - -#ifndef lwip_itoa -/* This can be #defined to itoa() or snprintf(result, bufsize, "%d", number) depending on your platform */ -void lwip_itoa(char* result, size_t bufsize, int number); -#endif -#ifndef lwip_strnicmp -/* This can be #defined to strnicmp() or strncasecmp() depending on your platform */ -int lwip_strnicmp(const char* str1, const char* str2, size_t len); -#endif -#ifndef lwip_stricmp -/* This can be #defined to stricmp() or strcasecmp() depending on your platform */ -int lwip_stricmp(const char* str1, const char* str2); -#endif -#ifndef lwip_strnstr -/* This can be #defined to strnstr() depending on your platform */ -char* lwip_strnstr(const char* buffer, const char* token, size_t n); -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_DEF_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/dhcp.h b/third_party/lwip/repo/lwip/src/include/lwip/dhcp.h deleted file mode 100644 index df932afb521129..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/dhcp.h +++ /dev/null @@ -1,143 +0,0 @@ -/** - * @file - * DHCP client API - */ - -/* - * Copyright (c) 2001-2004 Leon Woestenberg - * Copyright (c) 2001-2004 Axon Digital Design B.V., The Netherlands. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Leon Woestenberg - * - */ -#ifndef LWIP_HDR_DHCP_H -#define LWIP_HDR_DHCP_H - -#include "lwip/opt.h" - -#if LWIP_DHCP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/netif.h" -#include "lwip/udp.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** period (in seconds) of the application calling dhcp_coarse_tmr() */ -#define DHCP_COARSE_TIMER_SECS 60 -/** period (in milliseconds) of the application calling dhcp_coarse_tmr() */ -#define DHCP_COARSE_TIMER_MSECS (DHCP_COARSE_TIMER_SECS * 1000UL) -/** period (in milliseconds) of the application calling dhcp_fine_tmr() */ -#define DHCP_FINE_TIMER_MSECS 500 - -#define DHCP_BOOT_FILE_LEN 128U - -/* AutoIP cooperation flags (struct dhcp.autoip_coop_state) */ -typedef enum { - DHCP_AUTOIP_COOP_STATE_OFF = 0, - DHCP_AUTOIP_COOP_STATE_ON = 1 -} dhcp_autoip_coop_state_enum_t; - -struct dhcp -{ - /** transaction identifier of last sent request */ - u32_t xid; - /** incoming msg */ - struct dhcp_msg *msg_in; - /** track PCB allocation state */ - u8_t pcb_allocated; - /** current DHCP state machine state */ - u8_t state; - /** retries of current request */ - u8_t tries; -#if LWIP_DHCP_AUTOIP_COOP - u8_t autoip_coop_state; -#endif - u8_t subnet_mask_given; - - struct pbuf *p_out; /* pbuf of outcoming msg */ - struct dhcp_msg *msg_out; /* outgoing msg */ - u16_t options_out_len; /* outgoing msg options length */ - u16_t request_timeout; /* #ticks with period DHCP_FINE_TIMER_SECS for request timeout */ - u16_t t1_timeout; /* #ticks with period DHCP_COARSE_TIMER_SECS for renewal time */ - u16_t t2_timeout; /* #ticks with period DHCP_COARSE_TIMER_SECS for rebind time */ - u16_t t1_renew_time; /* #ticks with period DHCP_COARSE_TIMER_SECS until next renew try */ - u16_t t2_rebind_time; /* #ticks with period DHCP_COARSE_TIMER_SECS until next rebind try */ - u16_t lease_used; /* #ticks with period DHCP_COARSE_TIMER_SECS since last received DHCP ack */ - u16_t t0_timeout; /* #ticks with period DHCP_COARSE_TIMER_SECS for lease time */ - ip_addr_t server_ip_addr; /* dhcp server address that offered this lease (ip_addr_t because passed to UDP) */ - ip4_addr_t offered_ip_addr; - ip4_addr_t offered_sn_mask; - ip4_addr_t offered_gw_addr; - - u32_t offered_t0_lease; /* lease period (in seconds) */ - u32_t offered_t1_renew; /* recommended renew time (usually 50% of lease period) */ - u32_t offered_t2_rebind; /* recommended rebind time (usually 87.5 of lease period) */ -#if LWIP_DHCP_BOOTP_FILE - ip4_addr_t offered_si_addr; - char boot_file_name[DHCP_BOOT_FILE_LEN]; -#endif /* LWIP_DHCP_BOOTPFILE */ -}; - - -void dhcp_set_struct(struct netif *netif, struct dhcp *dhcp); -/** Remove a struct dhcp previously set to the netif using dhcp_set_struct() */ -#define dhcp_remove_struct(netif) netif_set_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_DHCP, NULL) -void dhcp_cleanup(struct netif *netif); -err_t dhcp_start(struct netif *netif); -err_t dhcp_renew(struct netif *netif); -err_t dhcp_release(struct netif *netif); -void dhcp_stop(struct netif *netif); -void dhcp_inform(struct netif *netif); -void dhcp_network_changed(struct netif *netif); -#if DHCP_DOES_ARP_CHECK -void dhcp_arp_reply(struct netif *netif, const ip4_addr_t *addr); -#endif -u8_t dhcp_supplied_address(const struct netif *netif); -/* to be called every minute */ -void dhcp_coarse_tmr(void); -/* to be called every half second */ -void dhcp_fine_tmr(void); - -#if LWIP_DHCP_GET_NTP_SRV -/** This function must exist, in other to add offered NTP servers to - * the NTP (or SNTP) engine. - * See LWIP_DHCP_MAX_NTP_SERVERS */ -extern void dhcp_set_ntp_servers(u8_t num_ntp_servers, const ip4_addr_t* ntp_server_addrs); -#endif /* LWIP_DHCP_GET_NTP_SRV */ - -#define netif_dhcp_data(netif) ((struct dhcp*)netif_get_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_DHCP)) - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_DHCP */ - -#endif /*LWIP_HDR_DHCP_H*/ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/dhcp6.h b/third_party/lwip/repo/lwip/src/include/lwip/dhcp6.h deleted file mode 100644 index 455336d37dc2e6..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/dhcp6.h +++ /dev/null @@ -1,58 +0,0 @@ -/** - * @file - * - * IPv6 address autoconfiguration as per RFC 4862. - */ - -/* - * Copyright (c) 2010 Inico Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Ivan Delamer - * - * IPv6 address autoconfiguration as per RFC 4862. - * - * Please coordinate changes and requests with Ivan Delamer - * - */ - -#ifndef LWIP_HDR_IP6_DHCP6_H -#define LWIP_HDR_IP6_DHCP6_H - -#include "lwip/opt.h" - -#if LWIP_IPV6_DHCP6 /* don't build if not configured for use in lwipopts.h */ - - -struct dhcp6 -{ - /*@todo: implement DHCP6*/ -}; - -#endif /* LWIP_IPV6_DHCP6 */ - -#endif /* LWIP_HDR_IP6_DHCP6_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/dns.h b/third_party/lwip/repo/lwip/src/include/lwip/dns.h deleted file mode 100644 index 96d417b0548cb2..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/dns.h +++ /dev/null @@ -1,169 +0,0 @@ -/** - * @file - * DNS API - */ - -/** - * lwip DNS resolver header file. - - * Author: Jim Pettinato - * April 2007 - - * ported from uIP resolv.c Copyright (c) 2002-2003, Adam Dunkels. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef LWIP_HDR_DNS_H -#define LWIP_HDR_DNS_H - -#include "lwip/opt.h" - -#if LWIP_DNS - -#include "lwip/ip_addr.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** DNS timer period */ -#define DNS_TMR_INTERVAL 1000 - -/* DNS resolve types: */ -#define LWIP_DNS_ADDRTYPE_IPV4 0 -#define LWIP_DNS_ADDRTYPE_IPV6 1 -#define LWIP_DNS_ADDRTYPE_IPV4_IPV6 2 /* try to resolve IPv4 first, try IPv6 if IPv4 fails only */ -#define LWIP_DNS_ADDRTYPE_IPV6_IPV4 3 /* try to resolve IPv6 first, try IPv4 if IPv6 fails only */ -#if LWIP_IPV4 && LWIP_IPV6 -#ifndef LWIP_DNS_ADDRTYPE_DEFAULT -#define LWIP_DNS_ADDRTYPE_DEFAULT LWIP_DNS_ADDRTYPE_IPV4_IPV6 -#endif -#elif LWIP_IPV4 -#define LWIP_DNS_ADDRTYPE_DEFAULT LWIP_DNS_ADDRTYPE_IPV4 -#else -#define LWIP_DNS_ADDRTYPE_DEFAULT LWIP_DNS_ADDRTYPE_IPV6 -#endif - -#if DNS_LOCAL_HOSTLIST -/** struct used for local host-list */ -struct local_hostlist_entry { - /** static hostname */ - const char *name; - /** static host address in network byteorder */ - ip_addr_t addr; - struct local_hostlist_entry *next; -}; -#define DNS_LOCAL_HOSTLIST_ELEM(name, addr_init) {name, addr_init, NULL} -#if DNS_LOCAL_HOSTLIST_IS_DYNAMIC -#ifndef DNS_LOCAL_HOSTLIST_MAX_NAMELEN -#define DNS_LOCAL_HOSTLIST_MAX_NAMELEN DNS_MAX_NAME_LENGTH -#endif -#define LOCALHOSTLIST_ELEM_SIZE ((sizeof(struct local_hostlist_entry) + DNS_LOCAL_HOSTLIST_MAX_NAMELEN + 1)) -#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ -#endif /* DNS_LOCAL_HOSTLIST */ - -#if LWIP_IPV4 -extern const ip_addr_t dns_mquery_v4group; -#endif /* LWIP_IPV4 */ -#if LWIP_IPV6 -extern const ip_addr_t dns_mquery_v6group; -#endif /* LWIP_IPV6 */ - -/** Callback which is invoked when a hostname is found. - * A function of this type must be implemented by the application using the DNS resolver. - * There is support for two types of callbacks, invoked when a hostname is found. - * @note dns_found_callbackX type is used as a catch-all type, that needs to be cast - * to either dns_found_callback or dns_found_callback_multi. - * - * dns_found_callback returns at most a single IP address, even if the DNS server response contained several addresses - * (this callback is used to maintain backward compatibility with dns_gethostbyname) - * @param name pointer to the name that was looked up. - * @param ipaddr pointer to an ip_addr_t containing the IP address of the hostname, - * or NULL if the name could not be found (or on any other error). - * @param callback_arg a user-specified callback argument passed to dns_gethostbyname. - * - * dns_found_callback_multi returns up to numipaddrs of all the IP addresses returned by the DSN server - * (this callback is invoked by calling dns_gethostbyname_multi) - * @param name pointer to the name that was looked up. - * @param ipaddrs pointer to an ip_addr_t array containing the IP addresses of the hostname - * @note This pointer is never NULL, instead numipaddrs is set to zero. - * @param numipaddrs size of the ipaddrs array. - * @param callback_arg a user-specified callback argument passed to dns_gethostbyname_multi. -*/ - -typedef void (*dns_found_callback)(const char *name, const ip_addr_t *ipaddr, void *callback_arg); - -#if DNS_MAX_ADDRS_PER_NAME > 1 -typedef void (*dns_found_callbackX)(void); -typedef void (*dns_found_callback_multi)(const char *name, const ip_addr_t *ipaddrs, u8_t numipaddrs, void *callback_arg); -#define LWIP_DNS_FOUND_CALLBACK_TYPE dns_found_callbackX -#else // DNS_MAX_ADDRS_PER_NAME <= 1 -#define LWIP_DNS_FOUND_CALLBACK_TYPE dns_found_callback -#endif // DNS_MAX_ADDRS_PER_NAME <= 1 - -void dns_init(void); -void dns_tmr(void); -void dns_setserver(u8_t numdns, const ip_addr_t *dnsserver); -const ip_addr_t* dns_getserver(u8_t numdns); -err_t dns_gethostbyname(const char *hostname, ip_addr_t *addr, - LWIP_DNS_FOUND_CALLBACK_TYPE found, void *callback_arg); -err_t dns_gethostbyname_addrtype(const char *hostname, ip_addr_t *addr, - LWIP_DNS_FOUND_CALLBACK_TYPE found, void *callback_arg, - u8_t dns_addrtype); - -#if DNS_LOCAL_HOSTLIST -size_t dns_local_iterate(dns_found_callback iterator_fn, void *iterator_arg); -err_t dns_local_lookup(const char *hostname, ip_addr_t *addr, u8_t dns_addrtype); -#if DNS_LOCAL_HOSTLIST_IS_DYNAMIC - -void dns_init(void); -void dns_tmr(void); -void dns_setserver(u8_t numdns, ip_addr_t *dnsserver); -ip_addr_t dns_getserver(u8_t numdns); - -#if DNS_MAX_ADDRS_PER_NAME > 1 -err_t dns_gethostbyname_multi(const char *hostname, ip_addr_t *ipaddrs, u8_t *numipaddrs, - dns_found_callback_multi found, void *callback_arg); -#endif // DNS_MAX_ADDRS_PER_NAME > 1 - -int dns_local_removehost(const char *hostname, const ip_addr_t *addr); -err_t dns_local_addhost(const char *hostname, const ip_addr_t *addr); -#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ -#endif /* DNS_LOCAL_HOSTLIST */ - -u8_t dns_cancel(LWIP_DNS_FOUND_CALLBACK_TYPE found, void *callback_arg); - -#if LWIP_TEST_CODE -u8_t dns_expire_asking_entries(void); -u8_t dns_flush_cache(void); -#endif // LWIP_TEST_CODE - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_DNS */ -#endif /* LWIP_HDR_DNS_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/err.h b/third_party/lwip/repo/lwip/src/include/lwip/err.h deleted file mode 100644 index 84e528d1ed8e87..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/err.h +++ /dev/null @@ -1,119 +0,0 @@ -/** - * @file - * lwIP Error codes - */ -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_ERR_H -#define LWIP_HDR_ERR_H - -#include "lwip/opt.h" -#include "lwip/arch.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @defgroup infrastructure_errors Error codes - * @ingroup infrastructure - * @{ - */ - -/** Define LWIP_ERR_T in cc.h if you want to use - * a different type for your platform (must be signed). */ -#ifdef LWIP_ERR_T -typedef LWIP_ERR_T err_t; -#else /* LWIP_ERR_T */ -typedef s8_t err_t; -#endif /* LWIP_ERR_T*/ - -/** Definitions for error constants. */ -typedef enum { -/** No error, everything OK. */ - ERR_OK = 0, -/** Out of memory error. */ - ERR_MEM = -1, -/** Buffer error. */ - ERR_BUF = -2, -/** Timeout. */ - ERR_TIMEOUT = -3, -/** Routing problem. */ - ERR_RTE = -4, -/** Operation in progress */ - ERR_INPROGRESS = -5, -/** Illegal value. */ - ERR_VAL = -6, -/** Operation would block. */ - ERR_WOULDBLOCK = -7, -/** Address in use. */ - ERR_USE = -8, -/** Already connecting. */ - ERR_ALREADY = -9, -/** Conn already established.*/ - ERR_ISCONN = -10, -/** Not connected. */ - ERR_CONN = -11, -/** Low-level netif error */ - ERR_IF = -12, - -/** Connection aborted. */ - ERR_ABRT = -13, -/** Connection reset. */ - ERR_RST = -14, -/** Connection closed. */ - ERR_CLSD = -15, -/** Illegal argument. */ - ERR_ARG = -16 -} err_enum_t; - -#define ERR_IS_FATAL(e) ((e) <= ERR_ABRT) - -/** - * @} - */ - -#ifdef LWIP_DEBUG -extern const char *lwip_strerr(err_t err); -#else -#define lwip_strerr(x) "" -#endif /* LWIP_DEBUG */ - -#if !NO_SYS -int err_to_errno(err_t err); -#endif /* !NO_SYS */ - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_ERR_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/errno.h b/third_party/lwip/repo/lwip/src/include/lwip/errno.h deleted file mode 100644 index 641cffb09cc003..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/errno.h +++ /dev/null @@ -1,193 +0,0 @@ -/** - * @file - * Posix Errno defines - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_ERRNO_H -#define LWIP_HDR_ERRNO_H - -#include "lwip/opt.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef LWIP_PROVIDE_ERRNO - -#define EPERM 1 /* Operation not permitted */ -#define ENOENT 2 /* No such file or directory */ -#define ESRCH 3 /* No such process */ -#define EINTR 4 /* Interrupted system call */ -#define EIO 5 /* I/O error */ -#define ENXIO 6 /* No such device or address */ -#define E2BIG 7 /* Arg list too long */ -#define ENOEXEC 8 /* Exec format error */ -#define EBADF 9 /* Bad file number */ -#define ECHILD 10 /* No child processes */ -#define EAGAIN 11 /* Try again */ -#define ENOMEM 12 /* Out of memory */ -#define EACCES 13 /* Permission denied */ -#define EFAULT 14 /* Bad address */ -#define ENOTBLK 15 /* Block device required */ -#define EBUSY 16 /* Device or resource busy */ -#define EEXIST 17 /* File exists */ -#define EXDEV 18 /* Cross-device link */ -#define ENODEV 19 /* No such device */ -#define ENOTDIR 20 /* Not a directory */ -#define EISDIR 21 /* Is a directory */ -#define EINVAL 22 /* Invalid argument */ -#define ENFILE 23 /* File table overflow */ -#define EMFILE 24 /* Too many open files */ -#define ENOTTY 25 /* Not a typewriter */ -#define ETXTBSY 26 /* Text file busy */ -#define EFBIG 27 /* File too large */ -#define ENOSPC 28 /* No space left on device */ -#define ESPIPE 29 /* Illegal seek */ -#define EROFS 30 /* Read-only file system */ -#define EMLINK 31 /* Too many links */ -#define EPIPE 32 /* Broken pipe */ -#define EDOM 33 /* Math argument out of domain of func */ -#define ERANGE 34 /* Math result not representable */ -#define EDEADLK 35 /* Resource deadlock would occur */ -#define ENAMETOOLONG 36 /* File name too long */ -#define ENOLCK 37 /* No record locks available */ -#define ENOSYS 38 /* Function not implemented */ -#define ENOTEMPTY 39 /* Directory not empty */ -#define ELOOP 40 /* Too many symbolic links encountered */ -#define EWOULDBLOCK EAGAIN /* Operation would block */ -#define ENOMSG 42 /* No message of desired type */ -#define EIDRM 43 /* Identifier removed */ -#define ECHRNG 44 /* Channel number out of range */ -#define EL2NSYNC 45 /* Level 2 not synchronized */ -#define EL3HLT 46 /* Level 3 halted */ -#define EL3RST 47 /* Level 3 reset */ -#define ELNRNG 48 /* Link number out of range */ -#define EUNATCH 49 /* Protocol driver not attached */ -#define ENOCSI 50 /* No CSI structure available */ -#define EL2HLT 51 /* Level 2 halted */ -#define EBADE 52 /* Invalid exchange */ -#define EBADR 53 /* Invalid request descriptor */ -#define EXFULL 54 /* Exchange full */ -#define ENOANO 55 /* No anode */ -#define EBADRQC 56 /* Invalid request code */ -#define EBADSLT 57 /* Invalid slot */ - -#define EDEADLOCK EDEADLK - -#define EBFONT 59 /* Bad font file format */ -#define ENOSTR 60 /* Device not a stream */ -#define ENODATA 61 /* No data available */ -#define ETIME 62 /* Timer expired */ -#define ENOSR 63 /* Out of streams resources */ -#define ENONET 64 /* Machine is not on the network */ -#define ENOPKG 65 /* Package not installed */ -#define EREMOTE 66 /* Object is remote */ -#define ENOLINK 67 /* Link has been severed */ -#define EADV 68 /* Advertise error */ -#define ESRMNT 69 /* Srmount error */ -#define ECOMM 70 /* Communication error on send */ -#define EPROTO 71 /* Protocol error */ -#define EMULTIHOP 72 /* Multihop attempted */ -#define EDOTDOT 73 /* RFS specific error */ -#define EBADMSG 74 /* Not a data message */ -#define EOVERFLOW 75 /* Value too large for defined data type */ -#define ENOTUNIQ 76 /* Name not unique on network */ -#define EBADFD 77 /* File descriptor in bad state */ -#define EREMCHG 78 /* Remote address changed */ -#define ELIBACC 79 /* Can not access a needed shared library */ -#define ELIBBAD 80 /* Accessing a corrupted shared library */ -#define ELIBSCN 81 /* .lib section in a.out corrupted */ -#define ELIBMAX 82 /* Attempting to link in too many shared libraries */ -#define ELIBEXEC 83 /* Cannot exec a shared library directly */ -#define EILSEQ 84 /* Illegal byte sequence */ -#define ERESTART 85 /* Interrupted system call should be restarted */ -#define ESTRPIPE 86 /* Streams pipe error */ -#define EUSERS 87 /* Too many users */ -#define ENOTSOCK 88 /* Socket operation on non-socket */ -#define EDESTADDRREQ 89 /* Destination address required */ -#define EMSGSIZE 90 /* Message too long */ -#define EPROTOTYPE 91 /* Protocol wrong type for socket */ -#define ENOPROTOOPT 92 /* Protocol not available */ -#define EPROTONOSUPPORT 93 /* Protocol not supported */ -#define ESOCKTNOSUPPORT 94 /* Socket type not supported */ -#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */ -#define EPFNOSUPPORT 96 /* Protocol family not supported */ -#define EAFNOSUPPORT 97 /* Address family not supported by protocol */ -#define EADDRINUSE 98 /* Address already in use */ -#define EADDRNOTAVAIL 99 /* Cannot assign requested address */ -#define ENETDOWN 100 /* Network is down */ -#define ENETUNREACH 101 /* Network is unreachable */ -#define ENETRESET 102 /* Network dropped connection because of reset */ -#define ECONNABORTED 103 /* Software caused connection abort */ -#define ECONNRESET 104 /* Connection reset by peer */ -#define ENOBUFS 105 /* No buffer space available */ -#define EISCONN 106 /* Transport endpoint is already connected */ -#define ENOTCONN 107 /* Transport endpoint is not connected */ -#define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */ -#define ETOOMANYREFS 109 /* Too many references: cannot splice */ -#define ETIMEDOUT 110 /* Connection timed out */ -#define ECONNREFUSED 111 /* Connection refused */ -#define EHOSTDOWN 112 /* Host is down */ -#define EHOSTUNREACH 113 /* No route to host */ -#define EALREADY 114 /* Operation already in progress */ -#define EINPROGRESS 115 /* Operation now in progress */ -#define ESTALE 116 /* Stale NFS file handle */ -#define EUCLEAN 117 /* Structure needs cleaning */ -#define ENOTNAM 118 /* Not a XENIX named type file */ -#define ENAVAIL 119 /* No XENIX semaphores available */ -#define EISNAM 120 /* Is a named type file */ -#define EREMOTEIO 121 /* Remote I/O error */ -#define EDQUOT 122 /* Quota exceeded */ - -#define ENOMEDIUM 123 /* No medium found */ -#define EMEDIUMTYPE 124 /* Wrong medium type */ - -#ifndef errno -extern int errno; -#endif - -#else /* LWIP_PROVIDE_ERRNO */ - -/* Define LWIP_ERRNO_INCLUDE to to include the error defines here */ -#ifdef LWIP_ERRNO_INCLUDE -#include LWIP_ERRNO_INCLUDE -#endif /* LWIP_ERRNO_INCLUDE */ - -#endif /* LWIP_PROVIDE_ERRNO */ - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_ERRNO_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/etharp.h b/third_party/lwip/repo/lwip/src/include/lwip/etharp.h deleted file mode 100644 index 7080a19d058880..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/etharp.h +++ /dev/null @@ -1,106 +0,0 @@ -/** - * @file - * Ethernet output function - handles OUTGOING ethernet level traffic, implements - * ARP resolving. - * To be used in most low-level netif implementations - */ - -/* - * Copyright (c) 2001-2003 Swedish Institute of Computer Science. - * Copyright (c) 2003-2004 Leon Woestenberg - * Copyright (c) 2003-2004 Axon Digital Design B.V., The Netherlands. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ - -#ifndef LWIP_HDR_NETIF_ETHARP_H -#define LWIP_HDR_NETIF_ETHARP_H - -#include "lwip/opt.h" - -#if LWIP_ARP || LWIP_ETHERNET /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/pbuf.h" -#include "lwip/ip4_addr.h" -#include "lwip/netif.h" -#include "lwip/ip4.h" -#include "lwip/prot/ethernet.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#if LWIP_IPV4 && LWIP_ARP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/prot/etharp.h" - -/** 1 seconds period */ -#define ARP_TMR_INTERVAL 1000 - -#if ARP_QUEUEING -/** struct for queueing outgoing packets for unknown address - * defined here to be accessed by memp.h - */ -struct etharp_q_entry { - struct etharp_q_entry *next; - struct pbuf *p; -}; -#endif /* ARP_QUEUEING */ - -#define etharp_init() /* Compatibility define, no init needed. */ -void etharp_tmr(void); -s8_t etharp_find_addr(struct netif *netif, const ip4_addr_t *ipaddr, - struct eth_addr **eth_ret, const ip4_addr_t **ip_ret); -u8_t etharp_get_entry(u8_t i, ip4_addr_t **ipaddr, struct netif **netif, struct eth_addr **eth_ret); -err_t etharp_output(struct netif *netif, struct pbuf *q, const ip4_addr_t *ipaddr); -err_t etharp_query(struct netif *netif, const ip4_addr_t *ipaddr, struct pbuf *q); -err_t etharp_request(struct netif *netif, const ip4_addr_t *ipaddr); -/** For Ethernet network interfaces, we might want to send "gratuitous ARP"; - * this is an ARP packet sent by a node in order to spontaneously cause other - * nodes to update an entry in their ARP cache. - * From RFC 3220 "IP Mobility Support for IPv4" section 4.6. */ -#define etharp_gratuitous(netif) etharp_request((netif), netif_ip4_addr(netif)) -void etharp_cleanup_netif(struct netif *netif); - -#if ETHARP_SUPPORT_STATIC_ENTRIES -err_t etharp_add_static_entry(const ip4_addr_t *ipaddr, struct eth_addr *ethaddr); -err_t etharp_remove_static_entry(const ip4_addr_t *ipaddr); -#endif /* ETHARP_SUPPORT_STATIC_ENTRIES */ - -#endif /* LWIP_IPV4 && LWIP_ARP */ - -void etharp_input(struct pbuf *p, struct netif *netif); - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_ARP || LWIP_ETHERNET */ - -#endif /* LWIP_HDR_NETIF_ETHARP_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/ethip6.h b/third_party/lwip/repo/lwip/src/include/lwip/ethip6.h deleted file mode 100644 index 5e88dffd05f1b1..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/ethip6.h +++ /dev/null @@ -1,68 +0,0 @@ -/** - * @file - * - * Ethernet output for IPv6. Uses ND tables for link-layer addressing. - */ - -/* - * Copyright (c) 2010 Inico Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Ivan Delamer - * - * - * Please coordinate changes and requests with Ivan Delamer - * - */ - -#ifndef LWIP_HDR_ETHIP6_H -#define LWIP_HDR_ETHIP6_H - -#include "lwip/opt.h" - -#if LWIP_IPV6 && LWIP_ETHERNET /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/pbuf.h" -#include "lwip/ip6.h" -#include "lwip/ip6_addr.h" -#include "lwip/netif.h" - - -#ifdef __cplusplus -extern "C" { -#endif - - -err_t ethip6_output(struct netif *netif, struct pbuf *q, const ip6_addr_t *ip6addr); - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_IPV6 && LWIP_ETHERNET */ - -#endif /* LWIP_HDR_ETHIP6_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/icmp.h b/third_party/lwip/repo/lwip/src/include/lwip/icmp.h deleted file mode 100644 index f5a31fd4c07098..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/icmp.h +++ /dev/null @@ -1,110 +0,0 @@ -/** - * @file - * ICMP API - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_ICMP_H -#define LWIP_HDR_ICMP_H - -#include "lwip/opt.h" -#include "lwip/pbuf.h" -#include "lwip/ip_addr.h" -#include "lwip/netif.h" -#include "lwip/prot/icmp.h" - -#if LWIP_IPV6 && LWIP_ICMP6 -#include "lwip/icmp6.h" -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -/** ICMP destination unreachable codes */ -enum icmp_dur_type { - /** net unreachable */ - ICMP_DUR_NET = 0, - /** host unreachable */ - ICMP_DUR_HOST = 1, - /** protocol unreachable */ - ICMP_DUR_PROTO = 2, - /** port unreachable */ - ICMP_DUR_PORT = 3, - /** fragmentation needed and DF set */ - ICMP_DUR_FRAG = 4, - /** source route failed */ - ICMP_DUR_SR = 5 -}; - -/** ICMP time exceeded codes */ -enum icmp_te_type { - /** time to live exceeded in transit */ - ICMP_TE_TTL = 0, - /** fragment reassembly time exceeded */ - ICMP_TE_FRAG = 1 -}; - -#if LWIP_IPV4 && LWIP_ICMP /* don't build if not configured for use in lwipopts.h */ - -void icmp_input(struct pbuf *p, struct netif *inp); -void icmp_dest_unreach(struct pbuf *p, enum icmp_dur_type t); -void icmp_time_exceeded(struct pbuf *p, enum icmp_te_type t); - -#endif /* LWIP_IPV4 && LWIP_ICMP */ - -#if LWIP_IPV4 && LWIP_IPV6 -#if LWIP_ICMP && LWIP_ICMP6 -#define icmp_port_unreach(isipv6, pbuf) ((isipv6) ? \ - icmp6_dest_unreach(pbuf, ICMP6_DUR_PORT) : \ - icmp_dest_unreach(pbuf, ICMP_DUR_PORT)) -#elif LWIP_ICMP -#define icmp_port_unreach(isipv6, pbuf) do{ if(!(isipv6)) { icmp_dest_unreach(pbuf, ICMP_DUR_PORT);}}while(0) -#elif LWIP_ICMP6 -#define icmp_port_unreach(isipv6, pbuf) do{ if(isipv6) { icmp6_dest_unreach(pbuf, ICMP6_DUR_PORT);}}while(0) -#else -#define icmp_port_unreach(isipv6, pbuf) -#endif -#elif LWIP_IPV6 && LWIP_ICMP6 -#define icmp_port_unreach(isipv6, pbuf) icmp6_dest_unreach(pbuf, ICMP6_DUR_PORT) -#elif LWIP_IPV4 && LWIP_ICMP -#define icmp_port_unreach(isipv6, pbuf) icmp_dest_unreach(pbuf, ICMP_DUR_PORT) -#else /* (LWIP_IPV6 && LWIP_ICMP6) || (LWIP_IPV4 && LWIP_ICMP) */ -#define icmp_port_unreach(isipv6, pbuf) -#endif /* (LWIP_IPV6 && LWIP_ICMP6) || (LWIP_IPV4 && LWIP_ICMP) LWIP_IPV4*/ - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_ICMP_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/icmp6.h b/third_party/lwip/repo/lwip/src/include/lwip/icmp6.h deleted file mode 100644 index a29dc8c1c235c8..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/icmp6.h +++ /dev/null @@ -1,70 +0,0 @@ -/** - * @file - * - * IPv6 version of ICMP, as per RFC 4443. - */ - -/* - * Copyright (c) 2010 Inico Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Ivan Delamer - * - * - * Please coordinate changes and requests with Ivan Delamer - * - */ -#ifndef LWIP_HDR_ICMP6_H -#define LWIP_HDR_ICMP6_H - -#include "lwip/opt.h" -#include "lwip/pbuf.h" -#include "lwip/ip6_addr.h" -#include "lwip/netif.h" -#include "lwip/prot/icmp6.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#if LWIP_ICMP6 && LWIP_IPV6 /* don't build if not configured for use in lwipopts.h */ - -void icmp6_input(struct pbuf *p, struct netif *inp); -void icmp6_dest_unreach(struct pbuf *p, enum icmp6_dur_code c); -void icmp6_packet_too_big(struct pbuf *p, u32_t mtu); -void icmp6_time_exceeded(struct pbuf *p, enum icmp6_te_code c); -void icmp6_param_problem(struct pbuf *p, enum icmp6_pp_code c, u32_t pointer); - -#endif /* LWIP_ICMP6 && LWIP_IPV6 */ - - -#ifdef __cplusplus -} -#endif - - -#endif /* LWIP_HDR_ICMP6_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/if.h b/third_party/lwip/repo/lwip/src/include/lwip/if.h deleted file mode 100644 index 5600479d88962d..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/if.h +++ /dev/null @@ -1,59 +0,0 @@ -/** - * @file - * Interface Identification APIs from: - * RFC 3493: Basic Socket Interface Extensions for IPv6 - * Section 4: Interface Identification - */ - -/* - * Copyright (c) 2017 Joel Cunningham - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modificat -ion, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO E -VENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREM -ENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARIS -ING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILI -TY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Joel Cunningham - * - */ -#ifndef LWIP_HDR_IF_H -#define LWIP_HDR_IF_H - -#include "lwip/opt.h" - -#define IF_NAMESIZE 6 /* 2 chars, 3 nums, 1 \0 */ - -char * lwip_if_indextoname(unsigned ifindex, char *ifname); -unsigned int lwip_if_nametoindex(const char *ifname); - -#if LWIP_COMPAT_SOCKETS -#define if_indextoname(ifindex, ifname) lwip_if_indextoname(ifindex,ifname) -#define if_nametoindex(ifname) lwip_if_nametoindex(ifname) -#endif /* LWIP_COMPAT_SOCKETS */ - -#endif /* LWIP_HDR_IF_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/igmp.h b/third_party/lwip/repo/lwip/src/include/lwip/igmp.h deleted file mode 100644 index 9e3cb36c3de6e9..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/igmp.h +++ /dev/null @@ -1,118 +0,0 @@ -/** - * @file - * IGMP API - */ - -/* - * Copyright (c) 2002 CITEL Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of CITEL Technologies Ltd nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY CITEL TECHNOLOGIES AND CONTRIBUTORS ``AS IS'' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL CITEL TECHNOLOGIES OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is a contribution to the lwIP TCP/IP stack. - * The Swedish Institute of Computer Science and Adam Dunkels - * are specifically granted permission to redistribute this - * source code. -*/ - -#ifndef LWIP_HDR_IGMP_H -#define LWIP_HDR_IGMP_H - -#include "lwip/opt.h" -#include "lwip/ip_addr.h" -#include "lwip/netif.h" -#include "lwip/pbuf.h" - -#if LWIP_IPV4 && LWIP_IGMP /* don't build if not configured for use in lwipopts.h */ - -#ifdef __cplusplus -extern "C" { -#endif - -/* IGMP timer */ -#define IGMP_TMR_INTERVAL 100 /* Milliseconds */ -#define IGMP_V1_DELAYING_MEMBER_TMR (1000/IGMP_TMR_INTERVAL) -#define IGMP_JOIN_DELAYING_MEMBER_TMR (500 /IGMP_TMR_INTERVAL) - -/* Compatibility defines (don't use for new code) */ -#define IGMP_DEL_MAC_FILTER NETIF_DEL_MAC_FILTER -#define IGMP_ADD_MAC_FILTER NETIF_ADD_MAC_FILTER - -/** - * igmp group structure - there is - * a list of groups for each interface - * these should really be linked from the interface, but - * if we keep them separate we will not affect the lwip original code - * too much - * - * There will be a group for the all systems group address but this - * will not run the state machine as it is used to kick off reports - * from all the other groups - */ -struct igmp_group { - /** next link */ - struct igmp_group *next; - /** multicast address */ - ip4_addr_t group_address; - /** signifies we were the last person to report */ - u8_t last_reporter_flag; - /** current state of the group */ - u8_t group_state; - /** timer for reporting, negative is OFF */ - u16_t timer; - /** counter of simultaneous uses */ - u8_t use; -}; - -/* Prototypes */ -void igmp_init(void); -#ifdef LWIP_DEBUG -void igmp_dump_group_list(void); -#endif -err_t igmp_start(struct netif *netif); -err_t igmp_stop(struct netif *netif); -void igmp_report_groups(struct netif *netif); -struct igmp_group *igmp_lookfor_group(struct netif *ifp, const ip4_addr_t *addr); -void igmp_input(struct pbuf *p, struct netif *inp, const ip4_addr_t *dest); -err_t igmp_joingroup(const ip4_addr_t *ifaddr, const ip4_addr_t *groupaddr); -err_t igmp_joingroup_netif(struct netif *netif, const ip4_addr_t *groupaddr); -err_t igmp_leavegroup(const ip4_addr_t *ifaddr, const ip4_addr_t *groupaddr); -err_t igmp_leavegroup_netif(struct netif *netif, const ip4_addr_t *groupaddr); -void igmp_tmr(void); - -/** @ingroup igmp - * Get list head of IGMP groups for netif. - * Note: The allsystems group IP is contained in the list as first entry. - * @see @ref netif_set_igmp_mac_filter() - */ -#define netif_igmp_data(netif) ((struct igmp_group *)netif_get_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_IGMP)) - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_IPV4 && LWIP_IGMP */ - -#endif /* LWIP_HDR_IGMP_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/inet.h b/third_party/lwip/repo/lwip/src/include/lwip/inet.h deleted file mode 100644 index 4a34f026533880..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/inet.h +++ /dev/null @@ -1,172 +0,0 @@ -/** - * @file - * This file (together with sockets.h) aims to provide structs and functions from - * - arpa/inet.h - * - netinet/in.h - * - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_INET_H -#define LWIP_HDR_INET_H - -#include "lwip/opt.h" -#include "lwip/def.h" -#include "lwip/ip_addr.h" -#include "lwip/ip6_addr.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* If your port already typedef's in_addr_t, define IN_ADDR_T_DEFINED - to prevent this code from redefining it. */ -#if !defined(in_addr_t) && !defined(IN_ADDR_T_DEFINED) -typedef u32_t in_addr_t; -#endif - -struct in_addr { - in_addr_t s_addr; -}; - -struct in6_addr { - union { - u32_t u32_addr[4]; - u8_t u8_addr[16]; - } un; -#define s6_addr un.u8_addr -}; - -/** 255.255.255.255 */ -#define INADDR_NONE IPADDR_NONE -/** 127.0.0.1 */ -#define INADDR_LOOPBACK IPADDR_LOOPBACK -/** 0.0.0.0 */ -#define INADDR_ANY IPADDR_ANY -/** 255.255.255.255 */ -#define INADDR_BROADCAST IPADDR_BROADCAST - -/** This macro can be used to initialize a variable of type struct in6_addr - to the IPv6 wildcard address. */ -#define IN6ADDR_ANY_INIT {{{0,0,0,0}}} -/** This macro can be used to initialize a variable of type struct in6_addr - to the IPv6 loopback address. */ -#define IN6ADDR_LOOPBACK_INIT {{{0,0,0,PP_HTONL(1)}}} -/** This variable is initialized by the system to contain the wildcard IPv6 address. */ -extern const struct in6_addr in6addr_any; - -/* Definitions of the bits in an (IPv4) Internet address integer. - - On subnets, host and network parts are found according to - the subnet mask, not these masks. */ -#define IN_CLASSA(a) IP_CLASSA(a) -#define IN_CLASSA_NET IP_CLASSA_NET -#define IN_CLASSA_NSHIFT IP_CLASSA_NSHIFT -#define IN_CLASSA_HOST IP_CLASSA_HOST -#define IN_CLASSA_MAX IP_CLASSA_MAX - -#define IN_CLASSB(b) IP_CLASSB(b) -#define IN_CLASSB_NET IP_CLASSB_NET -#define IN_CLASSB_NSHIFT IP_CLASSB_NSHIFT -#define IN_CLASSB_HOST IP_CLASSB_HOST -#define IN_CLASSB_MAX IP_CLASSB_MAX - -#define IN_CLASSC(c) IP_CLASSC(c) -#define IN_CLASSC_NET IP_CLASSC_NET -#define IN_CLASSC_NSHIFT IP_CLASSC_NSHIFT -#define IN_CLASSC_HOST IP_CLASSC_HOST -#define IN_CLASSC_MAX IP_CLASSC_MAX - -#define IN_CLASSD(d) IP_CLASSD(d) -#define IN_CLASSD_NET IP_CLASSD_NET /* These ones aren't really */ -#define IN_CLASSD_NSHIFT IP_CLASSD_NSHIFT /* net and host fields, but */ -#define IN_CLASSD_HOST IP_CLASSD_HOST /* routing needn't know. */ -#define IN_CLASSD_MAX IP_CLASSD_MAX - -#define IN_MULTICAST(a) IP_MULTICAST(a) - -#define IN_EXPERIMENTAL(a) IP_EXPERIMENTAL(a) -#define IN_BADCLASS(a) IP_BADCLASS(a) - -#define IN_LOOPBACKNET IP_LOOPBACKNET - - -#ifndef INET_ADDRSTRLEN -#define INET_ADDRSTRLEN IP4ADDR_STRLEN_MAX -#endif -#if LWIP_IPV6 -#ifndef INET6_ADDRSTRLEN -#define INET6_ADDRSTRLEN IP6ADDR_STRLEN_MAX -#endif -#endif - -#if LWIP_IPV4 - -#define inet_addr_from_ip4addr(target_inaddr, source_ipaddr) ((target_inaddr)->s_addr = ip4_addr_get_u32(source_ipaddr)) -#define inet_addr_to_ip4addr(target_ipaddr, source_inaddr) (ip4_addr_set_u32(target_ipaddr, (source_inaddr)->s_addr)) -/* ATTENTION: the next define only works because both s_addr and ip4_addr_t are an u32_t effectively! */ -#define inet_addr_to_ip4addr_p(target_ip4addr_p, source_inaddr) ((target_ip4addr_p) = (ip4_addr_t*)&((source_inaddr)->s_addr)) - -/* directly map this to the lwip internal functions */ -#define inet_addr(cp) ipaddr_addr(cp) -#define inet_aton(cp, addr) ip4addr_aton(cp, (ip4_addr_t*)addr) -#define inet_ntoa(addr) ip4addr_ntoa((const ip4_addr_t*)&(addr)) -#define inet_ntoa_r(addr, buf, buflen) ip4addr_ntoa_r((const ip4_addr_t*)&(addr), buf, buflen) - -#endif /* LWIP_IPV4 */ - -#if LWIP_IPV6 -#define inet6_addr_from_ip6addr(target_in6addr, source_ip6addr) {(target_in6addr)->un.u32_addr[0] = (source_ip6addr)->addr[0]; \ - (target_in6addr)->un.u32_addr[1] = (source_ip6addr)->addr[1]; \ - (target_in6addr)->un.u32_addr[2] = (source_ip6addr)->addr[2]; \ - (target_in6addr)->un.u32_addr[3] = (source_ip6addr)->addr[3];} -#define inet6_addr_to_ip6addr(target_ip6addr, source_in6addr) {(target_ip6addr)->addr[0] = (source_in6addr)->un.u32_addr[0]; \ - (target_ip6addr)->addr[1] = (source_in6addr)->un.u32_addr[1]; \ - (target_ip6addr)->addr[2] = (source_in6addr)->un.u32_addr[2]; \ - (target_ip6addr)->addr[3] = (source_in6addr)->un.u32_addr[3];} -/* ATTENTION: the next define only works because both in6_addr and ip6_addr_t are an u32_t[4] effectively! */ -#define inet6_addr_to_ip6addr_p(target_ip6addr_p, source_in6addr) ((target_ip6addr_p) = (ip6_addr_t*)(source_in6addr)) - -/* directly map this to the lwip internal functions */ -#define inet6_aton(cp, addr) ip6addr_aton(cp, (ip6_addr_t*)addr) -#define inet6_ntoa(addr) ip6addr_ntoa((const ip6_addr_t*)&(addr)) -#define inet6_ntoa_r(addr, buf, buflen) ip6addr_ntoa_r((const ip6_addr_t*)&(addr), buf, buflen) - -#endif /* LWIP_IPV6 */ - - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_INET_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/inet_chksum.h b/third_party/lwip/repo/lwip/src/include/lwip/inet_chksum.h deleted file mode 100644 index 4e23d7f1944614..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/inet_chksum.h +++ /dev/null @@ -1,105 +0,0 @@ -/** - * @file - * IP checksum calculation functions - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_INET_CHKSUM_H -#define LWIP_HDR_INET_CHKSUM_H - -#include "lwip/opt.h" - -#include "lwip/pbuf.h" -#include "lwip/ip_addr.h" - -/** Swap the bytes in an u16_t: much like lwip_htons() for little-endian */ -#ifndef SWAP_BYTES_IN_WORD -#define SWAP_BYTES_IN_WORD(w) (((w) & 0xff) << 8) | (((w) & 0xff00) >> 8) -#endif /* SWAP_BYTES_IN_WORD */ - -/** Split an u32_t in two u16_ts and add them up */ -#ifndef FOLD_U32T -#define FOLD_U32T(u) (((u) >> 16) + ((u) & 0x0000ffffUL)) -#endif - -#if LWIP_CHECKSUM_ON_COPY -/** Function-like macro: same as MEMCPY but returns the checksum of copied data - as u16_t */ -# ifndef LWIP_CHKSUM_COPY -# define LWIP_CHKSUM_COPY(dst, src, len) lwip_chksum_copy(dst, src, len) -# ifndef LWIP_CHKSUM_COPY_ALGORITHM -# define LWIP_CHKSUM_COPY_ALGORITHM 1 -# endif /* LWIP_CHKSUM_COPY_ALGORITHM */ -# else /* LWIP_CHKSUM_COPY */ -# define LWIP_CHKSUM_COPY_ALGORITHM 0 -# endif /* LWIP_CHKSUM_COPY */ -#else /* LWIP_CHECKSUM_ON_COPY */ -# define LWIP_CHKSUM_COPY_ALGORITHM 0 -#endif /* LWIP_CHECKSUM_ON_COPY */ - -#ifdef __cplusplus -extern "C" { -#endif - -u16_t inet_chksum(const void *dataptr, u16_t len); -u16_t inet_chksum_pbuf(struct pbuf *p); -#if LWIP_CHKSUM_COPY_ALGORITHM -u16_t lwip_chksum_copy(void *dst, const void *src, u16_t len); -#endif /* LWIP_CHKSUM_COPY_ALGORITHM */ - -#if LWIP_IPV4 -u16_t inet_chksum_pseudo(struct pbuf *p, u8_t proto, u16_t proto_len, - const ip4_addr_t *src, const ip4_addr_t *dest); -u16_t inet_chksum_pseudo_partial(struct pbuf *p, u8_t proto, - u16_t proto_len, u16_t chksum_len, const ip4_addr_t *src, const ip4_addr_t *dest); -#endif /* LWIP_IPV4 */ - -#if LWIP_IPV6 -u16_t ip6_chksum_pseudo(struct pbuf *p, u8_t proto, u16_t proto_len, - const ip6_addr_t *src, const ip6_addr_t *dest); -u16_t ip6_chksum_pseudo_partial(struct pbuf *p, u8_t proto, u16_t proto_len, - u16_t chksum_len, const ip6_addr_t *src, const ip6_addr_t *dest); -#endif /* LWIP_IPV6 */ - - -u16_t ip_chksum_pseudo(struct pbuf *p, u8_t proto, u16_t proto_len, - const ip_addr_t *src, const ip_addr_t *dest); -u16_t ip_chksum_pseudo_partial(struct pbuf *p, u8_t proto, u16_t proto_len, - u16_t chksum_len, const ip_addr_t *src, const ip_addr_t *dest); - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_INET_H */ - diff --git a/third_party/lwip/repo/lwip/src/include/lwip/init.h b/third_party/lwip/repo/lwip/src/include/lwip/init.h deleted file mode 100644 index 3c234cb58ded5b..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/init.h +++ /dev/null @@ -1,100 +0,0 @@ -/** - * @file - * lwIP initialization API - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_INIT_H -#define LWIP_HDR_INIT_H - -#include "lwip/opt.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @defgroup lwip_version Version - * @ingroup lwip - * @{ - */ - -/** X.x.x: Major version of the stack */ -#define LWIP_VERSION_MAJOR 2 -/** x.X.x: Minor version of the stack */ -#define LWIP_VERSION_MINOR 0 -/** x.x.X: Revision of the stack */ -#define LWIP_VERSION_REVISION 3 -/** For release candidates, this is set to 1..254 - * For official releases, this is set to 255 (LWIP_RC_RELEASE) - * For development versions (Git), this is set to 0 (LWIP_RC_DEVELOPMENT) */ -#define LWIP_VERSION_RC LWIP_RC_RELEASE - -/** LWIP_VERSION_RC is set to LWIP_RC_RELEASE for official releases */ -#define LWIP_RC_RELEASE 255 -/** LWIP_VERSION_RC is set to LWIP_RC_DEVELOPMENT for Git versions */ -#define LWIP_RC_DEVELOPMENT 0 - -#define LWIP_VERSION_IS_RELEASE (LWIP_VERSION_RC == LWIP_RC_RELEASE) -#define LWIP_VERSION_IS_DEVELOPMENT (LWIP_VERSION_RC == LWIP_RC_DEVELOPMENT) -#define LWIP_VERSION_IS_RC ((LWIP_VERSION_RC != LWIP_RC_RELEASE) && (LWIP_VERSION_RC != LWIP_RC_DEVELOPMENT)) - -/* Some helper defines to get a version string */ -#define LWIP_VERSTR2(x) #x -#define LWIP_VERSTR(x) LWIP_VERSTR2(x) -#if LWIP_VERSION_IS_RELEASE -#define LWIP_VERSION_STRING_SUFFIX "" -#elif LWIP_VERSION_IS_DEVELOPMENT -#define LWIP_VERSION_STRING_SUFFIX "d" -#else -#define LWIP_VERSION_STRING_SUFFIX "rc" LWIP_VERSTR(LWIP_VERSION_RC) -#endif - -/** Provides the version of the stack */ -#define LWIP_VERSION (((u32_t)LWIP_VERSION_MAJOR) << 24 | ((u32_t)LWIP_VERSION_MINOR) << 16 | \ - ((u32_t)LWIP_VERSION_REVISION) << 8 | ((u32_t)LWIP_VERSION_RC)) -/** Provides the version of the stack as string */ -#define LWIP_VERSION_STRING LWIP_VERSTR(LWIP_VERSION_MAJOR) "." LWIP_VERSTR(LWIP_VERSION_MINOR) "." LWIP_VERSTR(LWIP_VERSION_REVISION) LWIP_VERSION_STRING_SUFFIX - -/** - * @} - */ - -/* Modules initialization */ -void lwip_init(void); - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_INIT_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/ip.h b/third_party/lwip/repo/lwip/src/include/lwip/ip.h deleted file mode 100644 index 0413d541fe02d9..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/ip.h +++ /dev/null @@ -1,325 +0,0 @@ -/** - * @file - * IP API - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_IP_H -#define LWIP_HDR_IP_H - -#include "lwip/opt.h" - -#include "lwip/def.h" -#include "lwip/pbuf.h" -#include "lwip/ip_addr.h" -#include "lwip/err.h" -#include "lwip/netif.h" -#include "lwip/ip4.h" -#include "lwip/ip6.h" -#include "lwip/prot/ip.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* This is passed as the destination address to ip_output_if (not - to ip_output), meaning that an IP header already is constructed - in the pbuf. This is used when TCP retransmits. */ -#define LWIP_IP_HDRINCL NULL - -/** pbufs passed to IP must have a ref-count of 1 as their payload pointer - gets altered as the packet is passed down the stack */ -#ifndef LWIP_IP_CHECK_PBUF_REF_COUNT_FOR_TX -#define LWIP_IP_CHECK_PBUF_REF_COUNT_FOR_TX(p) LWIP_ASSERT("p->ref == 1", (p)->ref == 1) -#endif - -#if LWIP_NETIF_HWADDRHINT -#define IP_PCB_ADDRHINT ;u8_t addr_hint -#else -#define IP_PCB_ADDRHINT -#endif /* LWIP_NETIF_HWADDRHINT */ - -/** This is the common part of all PCB types. It needs to be at the - beginning of a PCB type definition. It is located here so that - changes to this common part are made in one location instead of - having to change all PCB structs. */ -#define IP_PCB \ - /* ip addresses in network byte order */ \ - ip_addr_t local_ip; \ - ip_addr_t remote_ip; \ - /* Bound netif index */ \ - u8_t netif_idx; \ - /* Socket options */ \ - u8_t so_options; \ - /* Type Of Service */ \ - u8_t tos; \ - /* Time To Live */ \ - u8_t ttl \ - /* link layer address resolution hint */ \ - IP_PCB_ADDRHINT - -struct ip_pcb { -/* Common members of all PCB types */ - IP_PCB; -}; - -/* - * Option flags per-socket. These are the same like SO_XXX in sockets.h - */ -#define SOF_REUSEADDR 0x04U /* allow local address reuse */ -#define SOF_KEEPALIVE 0x08U /* keep connections alive */ -#define SOF_BROADCAST 0x20U /* permit to send and to receive broadcast messages (see IP_SOF_BROADCAST option) */ - -#if LWIP_MANAGEMENT_CHANNEL -#define SOF_MANAGEMENT 0x40U /* Indicates this socket is for management channel. */ -#endif - -/* These flags are inherited (e.g. from a listen-pcb to a connection-pcb): */ -#define SOF_INHERITED (SOF_REUSEADDR|SOF_KEEPALIVE) - -/** Global variables of this module, kept in a struct for efficient access using base+index. */ -struct ip_globals -{ - /** The interface that accepted the packet for the current callback invocation. */ - struct netif *current_netif; - /** The interface that received the packet for the current callback invocation. */ - struct netif *current_input_netif; -#if LWIP_IPV4 - /** Header of the input packet currently being processed. */ - struct ip_hdr *current_ip4_header; -#endif /* LWIP_IPV4 */ -#if LWIP_IPV6 - /** Header of the input IPv6 packet currently being processed. */ - struct ip6_hdr *current_ip6_header; -#endif /* LWIP_IPV6 */ - /** Total header length of current_ip4/6_header (i.e. after this, the UDP/TCP header starts) */ - u16_t current_ip_header_tot_len; - /** Source IP address of current_header */ - ip_addr_t current_iphdr_src; - /** Destination IP address of current_header */ - ip_addr_t current_iphdr_dest; -}; -extern struct ip_globals ip_data; - - -/** Get the interface that accepted the current packet. - * This may or may not be the receiving netif, depending on your netif/network setup. - * This function must only be called from a receive callback (udp_recv, - * raw_recv, tcp_accept). It will return NULL otherwise. */ -#define ip_current_netif() (ip_data.current_netif) -/** Get the interface that received the current packet. - * This function must only be called from a receive callback (udp_recv, - * raw_recv, tcp_accept). It will return NULL otherwise. */ -#define ip_current_input_netif() (ip_data.current_input_netif) -/** Total header length of ip(6)_current_header() (i.e. after this, the UDP/TCP header starts) */ -#define ip_current_header_tot_len() (ip_data.current_ip_header_tot_len) -/** Source IP address of current_header */ -#define ip_current_src_addr() (&ip_data.current_iphdr_src) -/** Destination IP address of current_header */ -#define ip_current_dest_addr() (&ip_data.current_iphdr_dest) - -#if LWIP_IPV4 && LWIP_IPV6 -/** Get the IPv4 header of the current packet. - * This function must only be called from a receive callback (udp_recv, - * raw_recv, tcp_accept). It will return NULL otherwise. */ -#define ip4_current_header() ((const struct ip_hdr*)(ip_data.current_ip4_header)) -/** Get the IPv6 header of the current packet. - * This function must only be called from a receive callback (udp_recv, - * raw_recv, tcp_accept). It will return NULL otherwise. */ -#define ip6_current_header() ((const struct ip6_hdr*)(ip_data.current_ip6_header)) -/** Returns TRUE if the current IP input packet is IPv6, FALSE if it is IPv4 */ -#define ip_current_is_v6() (ip6_current_header() != NULL) -/** Source IPv6 address of current_header */ -#define ip6_current_src_addr() (ip_2_ip6(&ip_data.current_iphdr_src)) -/** Destination IPv6 address of current_header */ -#define ip6_current_dest_addr() (ip_2_ip6(&ip_data.current_iphdr_dest)) -/** Get the transport layer protocol */ -#define ip_current_header_proto() (ip_current_is_v6() ? \ - IP6H_NEXTH(ip6_current_header()) :\ - IPH_PROTO(ip4_current_header())) -/** Get the transport layer header */ -#define ip_next_header_ptr() ((const void*)((ip_current_is_v6() ? \ - (const u8_t*)ip6_current_header() : (const u8_t*)ip4_current_header()) + ip_current_header_tot_len())) - -/** Source IP4 address of current_header */ -#define ip4_current_src_addr() (ip_2_ip4(&ip_data.current_iphdr_src)) -/** Destination IP4 address of current_header */ -#define ip4_current_dest_addr() (ip_2_ip4(&ip_data.current_iphdr_dest)) - -#elif LWIP_IPV4 /* LWIP_IPV4 && LWIP_IPV6 */ - -/** Get the IPv4 header of the current packet. - * This function must only be called from a receive callback (udp_recv, - * raw_recv, tcp_accept). It will return NULL otherwise. */ -#define ip4_current_header() ((const struct ip_hdr*)(ip_data.current_ip4_header)) -/** Always returns FALSE when only supporting IPv4 only */ -#define ip_current_is_v6() 0 -/** Get the transport layer protocol */ -#define ip_current_header_proto() IPH_PROTO(ip4_current_header()) -/** Get the transport layer header */ -#define ip_next_header_ptr() ((const void*)((const u8_t*)ip4_current_header() + ip_current_header_tot_len())) -/** Source IP4 address of current_header */ -#define ip4_current_src_addr() (&ip_data.current_iphdr_src) -/** Destination IP4 address of current_header */ -#define ip4_current_dest_addr() (&ip_data.current_iphdr_dest) - -#elif LWIP_IPV6 /* LWIP_IPV4 && LWIP_IPV6 */ - -/** Get the IPv6 header of the current packet. - * This function must only be called from a receive callback (udp_recv, - * raw_recv, tcp_accept). It will return NULL otherwise. */ -#define ip6_current_header() ((const struct ip6_hdr*)(ip_data.current_ip6_header)) -/** Always returns TRUE when only supporting IPv6 only */ -#define ip_current_is_v6() 1 -/** Get the transport layer protocol */ -#define ip_current_header_proto() IP6H_NEXTH(ip6_current_header()) -/** Get the transport layer header */ -#define ip_next_header_ptr() ((const void*)((const u8_t*)ip6_current_header())) -/** Source IP6 address of current_header */ -#define ip6_current_src_addr() (&ip_data.current_iphdr_src) -/** Destination IP6 address of current_header */ -#define ip6_current_dest_addr() (&ip_data.current_iphdr_dest) - -#endif /* LWIP_IPV6 */ - -/** Union source address of current_header */ -#define ip_current_src_addr() (&ip_data.current_iphdr_src) -/** Union destination address of current_header */ -#define ip_current_dest_addr() (&ip_data.current_iphdr_dest) - -/** Gets an IP pcb option (SOF_* flags) */ -#define ip_get_option(pcb, opt) ((pcb)->so_options & (opt)) -/** Sets an IP pcb option (SOF_* flags) */ -#define ip_set_option(pcb, opt) ((pcb)->so_options |= (opt)) -/** Resets an IP pcb option (SOF_* flags) */ -#define ip_reset_option(pcb, opt) ((pcb)->so_options &= ~(opt)) - -#if LWIP_IPV4 && LWIP_IPV6 -/** - * @ingroup ip - * Output IP packet, netif is selected by source address - */ -#define ip_output(p, src, dest, ttl, tos, proto, pcb) \ - (IP_IS_V6(dest) ? \ - ip6_output(p, ip_2_ip6(src), ip_2_ip6(dest), ttl, tos, proto, pcb) : \ - ip4_output(p, ip_2_ip4(src), ip_2_ip4(dest), ttl, tos, proto, pcb)) -/** - * @ingroup ip - * Output IP packet to specified interface - */ -#define ip_output_if(p, src, dest, ttl, tos, proto, netif) \ - (IP_IS_V6(dest) ? \ - ip6_output_if(p, ip_2_ip6(src), ip_2_ip6(dest), ttl, tos, proto, netif) : \ - ip4_output_if(p, ip_2_ip4(src), ip_2_ip4(dest), ttl, tos, proto, netif)) -/** - * @ingroup ip - * Output IP packet to interface specifying source address - */ -#define ip_output_if_src(p, src, dest, ttl, tos, proto, netif) \ - (IP_IS_V6(dest) ? \ - ip6_output_if_src(p, ip_2_ip6(src), ip_2_ip6(dest), ttl, tos, proto, netif) : \ - ip4_output_if_src(p, ip_2_ip4(src), ip_2_ip4(dest), ttl, tos, proto, netif)) -/** Output IP packet with addr_hint */ -#define ip_output_hinted(p, src, dest, ttl, tos, proto, addr_hint) \ - (IP_IS_V6(dest) ? \ - ip6_output_hinted(p, ip_2_ip6(src), ip_2_ip6(dest), ttl, tos, proto, addr_hint) : \ - ip4_output_hinted(p, ip_2_ip4(src), ip_2_ip4(dest), ttl, tos, proto, addr_hint)) -/** - * @ingroup ip - * Get netif for address combination. See \ref ip6_route and \ref ip4_route - */ -#define ip_route(src, dest) \ - (IP_IS_V6(dest) ? \ - ip6_route(ip_2_ip6(src), ip_2_ip6(dest)) : \ - ip4_route_src(ip_2_ip4(dest), ip_2_ip4(src))) -/** - * @ingroup ip - * Get netif for IP. - */ -#define ip_netif_get_local_ip(netif, dest) (IP_IS_V6(dest) ? \ - ip6_netif_get_local_ip(netif, ip_2_ip6(dest)) : \ - ip4_netif_get_local_ip(netif)) -#define ip_debug_print(is_ipv6, p) ((is_ipv6) ? ip6_debug_print(p) : ip4_debug_print(p)) - -err_t ip_input(struct pbuf *p, struct netif *inp); - -#elif LWIP_IPV4 /* LWIP_IPV4 && LWIP_IPV6 */ - -#define ip_output(p, src, dest, ttl, tos, proto, pcb) \ - ip4_output(p, src, dest, ttl, tos, proto, pcb) -#define ip_output_if(p, src, dest, ttl, tos, proto, netif) \ - ip4_output_if(p, src, dest, ttl, tos, proto, netif) -#define ip_output_if_src(p, src, dest, ttl, tos, proto, netif) \ - ip4_output_if_src(p, src, dest, ttl, tos, proto, netif) -#define ip_output_hinted(p, src, dest, ttl, tos, proto, addr_hint) \ - ip4_output_hinted(p, src, dest, ttl, tos, proto, addr_hint) -#define ip_route(src, dest) \ - ip4_route_src(dest, src) -#define ip_netif_get_local_ip(netif, dest) \ - ip4_netif_get_local_ip(netif) -#define ip_debug_print(is_ipv6, p) ip4_debug_print(p) - -#define ip_input ip4_input - -#elif LWIP_IPV6 /* LWIP_IPV4 && LWIP_IPV6 */ - -#define ip_output(p, src, dest, ttl, tos, proto, pcb) \ - ip6_output(p, src, dest, ttl, tos, proto, pcb) -#define ip_output_if(p, src, dest, ttl, tos, proto, netif) \ - ip6_output_if(p, src, dest, ttl, tos, proto, netif) -#define ip_output_if_src(p, src, dest, ttl, tos, proto, netif) \ - ip6_output_if_src(p, src, dest, ttl, tos, proto, netif) -#define ip_output_hinted(p, src, dest, ttl, tos, proto, addr_hint) \ - ip6_output_hinted(p, src, dest, ttl, tos, proto, addr_hint) -#define ip_route(src, dest) \ - ip6_route(src, dest) -#define ip_netif_get_local_ip(netif, dest) \ - ip6_netif_get_local_ip(netif, dest) -#define ip_debug_print(is_ipv6, p) ip6_debug_print(p) - -#define ip_input ip6_input - -#endif /* LWIP_IPV6 */ - -#define ip_route_get_local_ip(src, dest, netif, ipaddr) do { \ - (netif) = ip_route(src, dest); \ - (ipaddr) = ip_netif_get_local_ip(netif, dest); \ -}while(0) - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_IP_H */ - - diff --git a/third_party/lwip/repo/lwip/src/include/lwip/ip4.h b/third_party/lwip/repo/lwip/src/include/lwip/ip4.h deleted file mode 100644 index d7f84aafbee53c..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/ip4.h +++ /dev/null @@ -1,111 +0,0 @@ -/** - * @file - * IPv4 API - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_IP4_H -#define LWIP_HDR_IP4_H - -#include "lwip/opt.h" - -#if LWIP_IPV4 - -#include "lwip/def.h" -#include "lwip/pbuf.h" -#include "lwip/ip4_addr.h" -#include "lwip/err.h" -#include "lwip/netif.h" -#include "lwip/prot/ip4.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef LWIP_HOOK_IP4_ROUTE_SRC -#define LWIP_IPV4_SRC_ROUTING 1 -#else -#define LWIP_IPV4_SRC_ROUTING 0 -#endif - -/** Currently, the function ip_output_if_opt() is only used with IGMP */ -#define IP_OPTIONS_SEND (LWIP_IPV4 && LWIP_IGMP) - -#define ip_init() /* Compatibility define, no init needed. */ -struct netif *ip4_route(const ip4_addr_t *dest); -#if LWIP_IPV4_SRC_ROUTING -struct netif *ip4_route_src(const ip4_addr_t *dest, const ip4_addr_t *src); -#else /* LWIP_IPV4_SRC_ROUTING */ -#define ip4_route_src(dest, src) ip4_route(dest) -#endif /* LWIP_IPV4_SRC_ROUTING */ -err_t ip4_input(struct pbuf *p, struct netif *inp); -err_t ip4_output(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest, - u8_t ttl, u8_t tos, u8_t proto, struct ip_pcb *pcb); -err_t ip4_output_if(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest, - u8_t ttl, u8_t tos, u8_t proto, struct netif *netif); -err_t ip4_output_if_src(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest, - u8_t ttl, u8_t tos, u8_t proto, struct netif *netif); -#if LWIP_NETIF_HWADDRHINT -err_t ip4_output_hinted(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest, - u8_t ttl, u8_t tos, u8_t proto, u8_t *addr_hint); -#endif /* LWIP_NETIF_HWADDRHINT */ -#if IP_OPTIONS_SEND -err_t ip4_output_if_opt(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest, - u8_t ttl, u8_t tos, u8_t proto, struct netif *netif, void *ip_options, - u16_t optlen); -err_t ip4_output_if_opt_src(struct pbuf *p, const ip4_addr_t *src, const ip4_addr_t *dest, - u8_t ttl, u8_t tos, u8_t proto, struct netif *netif, void *ip_options, - u16_t optlen); -#endif /* IP_OPTIONS_SEND */ - -#if LWIP_MULTICAST_TX_OPTIONS -void ip4_set_default_multicast_netif(struct netif* default_multicast_netif); -#endif /* LWIP_MULTICAST_TX_OPTIONS */ - -#define ip4_netif_get_local_ip(netif) (((netif) != NULL) ? netif_ip_addr4(netif) : NULL) - -#if IP_DEBUG -void ip4_debug_print(struct pbuf *p); -#else -#define ip4_debug_print(p) -#endif /* IP_DEBUG */ - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_IPV4 */ - -#endif /* LWIP_HDR_IP_H */ - - diff --git a/third_party/lwip/repo/lwip/src/include/lwip/ip4_addr.h b/third_party/lwip/repo/lwip/src/include/lwip/ip4_addr.h deleted file mode 100644 index 51b46b8d4c654b..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/ip4_addr.h +++ /dev/null @@ -1,227 +0,0 @@ -/** - * @file - * IPv4 address API - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_IP4_ADDR_H -#define LWIP_HDR_IP4_ADDR_H - -#include "lwip/opt.h" -#include "lwip/def.h" - -#if LWIP_IPV4 - -#ifdef __cplusplus -extern "C" { -#endif - -/** This is the aligned version of ip4_addr_t, - used as local variable, on the stack, etc. */ -struct ip4_addr { - u32_t addr; -}; - -/** ip4_addr_t uses a struct for convenience only, so that the same defines can - * operate both on ip4_addr_t as well as on ip4_addr_p_t. */ -typedef struct ip4_addr ip4_addr_t; - -/** - * struct ipaddr2 is used in the definition of the ARP packet format in - * order to support compilers that don't have structure packing. - */ -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct ip4_addr2 { - PACK_STRUCT_FIELD(u16_t addrw[2]); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -/* Forward declaration to not include netif.h */ -struct netif; - -/** 255.255.255.255 */ -#define IPADDR_NONE ((u32_t)0xffffffffUL) -/** 127.0.0.1 */ -#define IPADDR_LOOPBACK ((u32_t)0x7f000001UL) -/** 0.0.0.0 */ -#define IPADDR_ANY ((u32_t)0x00000000UL) -/** 255.255.255.255 */ -#define IPADDR_BROADCAST ((u32_t)0xffffffffUL) - -/* Definitions of the bits in an Internet address integer. - - On subnets, host and network parts are found according to - the subnet mask, not these masks. */ -#define IP_CLASSA(a) ((((u32_t)(a)) & 0x80000000UL) == 0) -#define IP_CLASSA_NET 0xff000000 -#define IP_CLASSA_NSHIFT 24 -#define IP_CLASSA_HOST (0xffffffff & ~IP_CLASSA_NET) -#define IP_CLASSA_MAX 128 - -#define IP_CLASSB(a) ((((u32_t)(a)) & 0xc0000000UL) == 0x80000000UL) -#define IP_CLASSB_NET 0xffff0000 -#define IP_CLASSB_NSHIFT 16 -#define IP_CLASSB_HOST (0xffffffff & ~IP_CLASSB_NET) -#define IP_CLASSB_MAX 65536 - -#define IP_CLASSC(a) ((((u32_t)(a)) & 0xe0000000UL) == 0xc0000000UL) -#define IP_CLASSC_NET 0xffffff00 -#define IP_CLASSC_NSHIFT 8 -#define IP_CLASSC_HOST (0xffffffff & ~IP_CLASSC_NET) - -#define IP_CLASSD(a) (((u32_t)(a) & 0xf0000000UL) == 0xe0000000UL) -#define IP_CLASSD_NET 0xf0000000 /* These ones aren't really */ -#define IP_CLASSD_NSHIFT 28 /* net and host fields, but */ -#define IP_CLASSD_HOST 0x0fffffff /* routing needn't know. */ -#define IP_MULTICAST(a) IP_CLASSD(a) - -#define IP_EXPERIMENTAL(a) (((u32_t)(a) & 0xf0000000UL) == 0xf0000000UL) -#define IP_BADCLASS(a) (((u32_t)(a) & 0xf0000000UL) == 0xf0000000UL) - -#define IP_LOOPBACKNET 127 /* official! */ - -/** Set an IP address given by the four byte-parts */ -#define IP4_ADDR(ipaddr, a,b,c,d) (ipaddr)->addr = PP_HTONL(LWIP_MAKEU32(a,b,c,d)) - -/** MEMCPY-like copying of IP addresses where addresses are known to be - * 16-bit-aligned if the port is correctly configured (so a port could define - * this to copying 2 u16_t's) - no NULL-pointer-checking needed. */ -#ifndef IPADDR2_COPY -#define IPADDR2_COPY(dest, src) SMEMCPY(dest, src, sizeof(ip4_addr_t)) -#endif - -/** Copy IP address - faster than ip4_addr_set: no NULL check */ -#define ip4_addr_copy(dest, src) ((dest).addr = (src).addr) -/** Safely copy one IP address to another (src may be NULL) */ -#define ip4_addr_set(dest, src) ((dest)->addr = \ - ((src) == NULL ? 0 : \ - (src)->addr)) -/** Set complete address to zero */ -#define ip4_addr_set_zero(ipaddr) ((ipaddr)->addr = 0) -/** Set address to IPADDR_ANY (no need for lwip_htonl()) */ -#define ip4_addr_set_any(ipaddr) ((ipaddr)->addr = IPADDR_ANY) -/** Set address to loopback address */ -#define ip4_addr_set_loopback(ipaddr) ((ipaddr)->addr = PP_HTONL(IPADDR_LOOPBACK)) -/** Check if an address is in the loopback region */ -#define ip4_addr_isloopback(ipaddr) (((ipaddr)->addr & PP_HTONL(IP_CLASSA_NET)) == PP_HTONL(((u32_t)IP_LOOPBACKNET) << 24)) -/** Safely copy one IP address to another and change byte order - * from host- to network-order. */ -#define ip4_addr_set_hton(dest, src) ((dest)->addr = \ - ((src) == NULL ? 0:\ - lwip_htonl((src)->addr))) -/** IPv4 only: set the IP address given as an u32_t */ -#define ip4_addr_set_u32(dest_ipaddr, src_u32) ((dest_ipaddr)->addr = (src_u32)) -/** IPv4 only: get the IP address as an u32_t */ -#define ip4_addr_get_u32(src_ipaddr) ((src_ipaddr)->addr) - -/** Get the network address by combining host address with netmask */ -#define ip4_addr_get_network(target, host, netmask) do { ((target)->addr = ((host)->addr) & ((netmask)->addr)); } while(0) - -/** - * Determine if two address are on the same network. - * - * @arg addr1 IP address 1 - * @arg addr2 IP address 2 - * @arg mask network identifier mask - * @return !0 if the network identifiers of both address match - */ -#define ip4_addr_netcmp(addr1, addr2, mask) (((addr1)->addr & \ - (mask)->addr) == \ - ((addr2)->addr & \ - (mask)->addr)) -#define ip4_addr_cmp(addr1, addr2) ((addr1)->addr == (addr2)->addr) - -#define ip4_addr_isany_val(addr1) ((addr1).addr == IPADDR_ANY) -#define ip4_addr_isany(addr1) ((addr1) == NULL || ip4_addr_isany_val(*(addr1))) - -#define ip4_addr_isbroadcast(addr1, netif) ip4_addr_isbroadcast_u32((addr1)->addr, netif) -u8_t ip4_addr_isbroadcast_u32(u32_t addr, const struct netif *netif); - -#define ip_addr_netmask_valid(netmask) ip4_addr_netmask_valid((netmask)->addr) -u8_t ip4_addr_netmask_valid(u32_t netmask); - -#define ip4_addr_ismulticast(addr1) (((addr1)->addr & PP_HTONL(0xf0000000UL)) == PP_HTONL(0xe0000000UL)) - -#define ip4_addr_islinklocal(addr1) (((addr1)->addr & PP_HTONL(0xffff0000UL)) == PP_HTONL(0xa9fe0000UL)) - -#define ip4_addr_debug_print_parts(debug, a, b, c, d) \ - LWIP_DEBUGF(debug, ("%" U16_F ".%" U16_F ".%" U16_F ".%" U16_F, a, b, c, d)) -#define ip4_addr_debug_print(debug, ipaddr) \ - ip4_addr_debug_print_parts(debug, \ - (u16_t)((ipaddr) != NULL ? ip4_addr1_16(ipaddr) : 0), \ - (u16_t)((ipaddr) != NULL ? ip4_addr2_16(ipaddr) : 0), \ - (u16_t)((ipaddr) != NULL ? ip4_addr3_16(ipaddr) : 0), \ - (u16_t)((ipaddr) != NULL ? ip4_addr4_16(ipaddr) : 0)) -#define ip4_addr_debug_print_val(debug, ipaddr) \ - ip4_addr_debug_print_parts(debug, \ - ip4_addr1_16(&(ipaddr)), \ - ip4_addr2_16(&(ipaddr)), \ - ip4_addr3_16(&(ipaddr)), \ - ip4_addr4_16(&(ipaddr))) - -/* Get one byte from the 4-byte address */ -#define ip4_addr1(ipaddr) (((const u8_t*)(&(ipaddr)->addr))[0]) -#define ip4_addr2(ipaddr) (((const u8_t*)(&(ipaddr)->addr))[1]) -#define ip4_addr3(ipaddr) (((const u8_t*)(&(ipaddr)->addr))[2]) -#define ip4_addr4(ipaddr) (((const u8_t*)(&(ipaddr)->addr))[3]) -/* These are cast to u16_t, with the intent that they are often arguments - * to printf using the U16_F format from cc.h. */ -#define ip4_addr1_16(ipaddr) ((u16_t)ip4_addr1(ipaddr)) -#define ip4_addr2_16(ipaddr) ((u16_t)ip4_addr2(ipaddr)) -#define ip4_addr3_16(ipaddr) ((u16_t)ip4_addr3(ipaddr)) -#define ip4_addr4_16(ipaddr) ((u16_t)ip4_addr4(ipaddr)) - -#define IP4ADDR_STRLEN_MAX 16 - -/** For backwards compatibility */ -#define ip_ntoa(ipaddr) ipaddr_ntoa(ipaddr) - -u32_t ipaddr_addr(const char *cp); -int ip4addr_aton(const char *cp, ip4_addr_t *addr); -/** returns ptr to static buffer; not reentrant! */ -char *ip4addr_ntoa(const ip4_addr_t *addr); -char *ip4addr_ntoa_r(const ip4_addr_t *addr, char *buf, int buflen); - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_IPV4 */ - -#endif /* LWIP_HDR_IP_ADDR_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/ip4_frag.h b/third_party/lwip/repo/lwip/src/include/lwip/ip4_frag.h deleted file mode 100644 index ed5bf14a31c338..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/ip4_frag.h +++ /dev/null @@ -1,100 +0,0 @@ -/** - * @file - * IP fragmentation/reassembly - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Jani Monoses - * - */ - -#ifndef LWIP_HDR_IP4_FRAG_H -#define LWIP_HDR_IP4_FRAG_H - -#include "lwip/opt.h" -#include "lwip/err.h" -#include "lwip/pbuf.h" -#include "lwip/netif.h" -#include "lwip/ip_addr.h" -#include "lwip/ip.h" - -#if LWIP_IPV4 - -#ifdef __cplusplus -extern "C" { -#endif - -#if IP_REASSEMBLY -/* The IP reassembly timer interval in milliseconds. */ -#define IP_TMR_INTERVAL 1000 - -/** IP reassembly helper struct. - * This is exported because memp needs to know the size. - */ -struct ip_reassdata { - struct ip_reassdata *next; - struct pbuf *p; - struct ip_hdr iphdr; - u16_t datagram_len; - u8_t flags; - u8_t timer; -}; - -void ip_reass_init(void); -void ip_reass_tmr(void); -struct pbuf * ip4_reass(struct pbuf *p); -#endif /* IP_REASSEMBLY */ - -#if IP_FRAG -#if !LWIP_NETIF_TX_SINGLE_PBUF -#ifndef LWIP_PBUF_CUSTOM_REF_DEFINED -#define LWIP_PBUF_CUSTOM_REF_DEFINED -/** A custom pbuf that holds a reference to another pbuf, which is freed - * when this custom pbuf is freed. This is used to create a custom PBUF_REF - * that points into the original pbuf. */ -struct pbuf_custom_ref { - /** 'base class' */ - struct pbuf_custom pc; - /** pointer to the original pbuf that is referenced */ - struct pbuf *original; -}; -#endif /* LWIP_PBUF_CUSTOM_REF_DEFINED */ -#endif /* !LWIP_NETIF_TX_SINGLE_PBUF */ - -err_t ip4_frag(struct pbuf *p, struct netif *netif, const ip4_addr_t *dest); -#endif /* IP_FRAG */ - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_IPV4 */ - -#endif /* LWIP_HDR_IP4_FRAG_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/ip6.h b/third_party/lwip/repo/lwip/src/include/lwip/ip6.h deleted file mode 100644 index 9cadabe44944b3..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/ip6.h +++ /dev/null @@ -1,93 +0,0 @@ -/** - * @file - * - * IPv6 layer. - */ - -/* - * Copyright (c) 2010 Inico Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Ivan Delamer - * - * - * Please coordinate changes and requests with Ivan Delamer - * - */ -#ifndef LWIP_HDR_IP6_H -#define LWIP_HDR_IP6_H - -#include "lwip/opt.h" - -#if LWIP_IPV6 /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/ip6_addr.h" -#include "lwip/prot/ip6.h" -#include "lwip/def.h" -#include "lwip/pbuf.h" -#include "lwip/netif.h" - -#include "lwip/err.h" - -#ifdef __cplusplus -extern "C" { -#endif - -struct netif *ip6_route(const ip6_addr_t *src, const ip6_addr_t *dest); -const ip_addr_t *ip6_select_source_address(struct netif *netif, const ip6_addr_t * dest); -err_t ip6_input(struct pbuf *p, struct netif *inp); -err_t ip6_output(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest, - u8_t hl, u8_t tc, u8_t nexth, struct ip_pcb *pcb); -err_t ip6_output_if(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest, - u8_t hl, u8_t tc, u8_t nexth, struct netif *netif); -err_t ip6_output_if_src(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest, - u8_t hl, u8_t tc, u8_t nexth, struct netif *netif); -#if LWIP_NETIF_HWADDRHINT -err_t ip6_output_hinted(struct pbuf *p, const ip6_addr_t *src, const ip6_addr_t *dest, - u8_t hl, u8_t tc, u8_t nexth, u8_t *addr_hint); -#endif /* LWIP_NETIF_HWADDRHINT */ -#if LWIP_IPV6_MLD -err_t ip6_options_add_hbh_ra(struct pbuf * p, u8_t nexth, u8_t value); -#endif /* LWIP_IPV6_MLD */ - -#define ip6_netif_get_local_ip(netif, dest) (((netif) != NULL) ? \ - ip6_select_source_address(netif, dest) : NULL) - -#if IP6_DEBUG -void ip6_debug_print(struct pbuf *p); -#else -#define ip6_debug_print(p) -#endif /* IP6_DEBUG */ - - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_IPV6 */ - -#endif /* LWIP_HDR_IP6_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/ip6_addr.h b/third_party/lwip/repo/lwip/src/include/lwip/ip6_addr.h deleted file mode 100644 index 0175022005a7fb..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/ip6_addr.h +++ /dev/null @@ -1,306 +0,0 @@ -/** - * @file - * - * IPv6 addresses. - */ - -/* - * Copyright (c) 2010 Inico Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Ivan Delamer - * - * Structs and macros for handling IPv6 addresses. - * - * Please coordinate changes and requests with Ivan Delamer - * - */ -#ifndef LWIP_HDR_IP6_ADDR_H -#define LWIP_HDR_IP6_ADDR_H - -#include "lwip/opt.h" -#include "def.h" - -#if LWIP_IPV6 /* don't build if not configured for use in lwipopts.h */ - - -#ifdef __cplusplus -extern "C" { -#endif - - -/** This is the aligned version of ip6_addr_t, - used as local variable, on the stack, etc. */ -struct ip6_addr { - u32_t addr[4]; -}; - -/** IPv6 address */ -typedef struct ip6_addr ip6_addr_t; - -/** Set an IPv6 partial address given by byte-parts */ -#define IP6_ADDR_PART(ip6addr, index, a,b,c,d) \ - (ip6addr)->addr[index] = PP_HTONL(LWIP_MAKEU32(a,b,c,d)) - -/** Set a full IPv6 address by passing the 4 u32_t indices in network byte order - (use PP_HTONL() for constants) */ -#define IP6_ADDR(ip6addr, idx0, idx1, idx2, idx3) do { \ - (ip6addr)->addr[0] = idx0; \ - (ip6addr)->addr[1] = idx1; \ - (ip6addr)->addr[2] = idx2; \ - (ip6addr)->addr[3] = idx3; } while(0) - -/** Access address in 16-bit block */ -#define IP6_ADDR_BLOCK1(ip6addr) ((u16_t)((lwip_htonl((ip6addr)->addr[0]) >> 16) & 0xffff)) -/** Access address in 16-bit block */ -#define IP6_ADDR_BLOCK2(ip6addr) ((u16_t)((lwip_htonl((ip6addr)->addr[0])) & 0xffff)) -/** Access address in 16-bit block */ -#define IP6_ADDR_BLOCK3(ip6addr) ((u16_t)((lwip_htonl((ip6addr)->addr[1]) >> 16) & 0xffff)) -/** Access address in 16-bit block */ -#define IP6_ADDR_BLOCK4(ip6addr) ((u16_t)((lwip_htonl((ip6addr)->addr[1])) & 0xffff)) -/** Access address in 16-bit block */ -#define IP6_ADDR_BLOCK5(ip6addr) ((u16_t)((lwip_htonl((ip6addr)->addr[2]) >> 16) & 0xffff)) -/** Access address in 16-bit block */ -#define IP6_ADDR_BLOCK6(ip6addr) ((u16_t)((lwip_htonl((ip6addr)->addr[2])) & 0xffff)) -/** Access address in 16-bit block */ -#define IP6_ADDR_BLOCK7(ip6addr) ((u16_t)((lwip_htonl((ip6addr)->addr[3]) >> 16) & 0xffff)) -/** Access address in 16-bit block */ -#define IP6_ADDR_BLOCK8(ip6addr) ((u16_t)((lwip_htonl((ip6addr)->addr[3])) & 0xffff)) - -/** Copy IPv6 address - faster than ip6_addr_set: no NULL check */ -#define ip6_addr_copy(dest, src) do{(dest).addr[0] = (src).addr[0]; \ - (dest).addr[1] = (src).addr[1]; \ - (dest).addr[2] = (src).addr[2]; \ - (dest).addr[3] = (src).addr[3];}while(0) -/** Safely copy one IPv6 address to another (src may be NULL) */ -#define ip6_addr_set(dest, src) do{(dest)->addr[0] = (src) == NULL ? 0 : (src)->addr[0]; \ - (dest)->addr[1] = (src) == NULL ? 0 : (src)->addr[1]; \ - (dest)->addr[2] = (src) == NULL ? 0 : (src)->addr[2]; \ - (dest)->addr[3] = (src) == NULL ? 0 : (src)->addr[3];}while(0) - -/** Set complete address to zero */ -#define ip6_addr_set_zero(ip6addr) do{(ip6addr)->addr[0] = 0; \ - (ip6addr)->addr[1] = 0; \ - (ip6addr)->addr[2] = 0; \ - (ip6addr)->addr[3] = 0;}while(0) - -/** Set address to ipv6 'any' (no need for lwip_htonl()) */ -#define ip6_addr_set_any(ip6addr) ip6_addr_set_zero(ip6addr) -/** Set address to ipv6 loopback address */ -#define ip6_addr_set_loopback(ip6addr) do{(ip6addr)->addr[0] = 0; \ - (ip6addr)->addr[1] = 0; \ - (ip6addr)->addr[2] = 0; \ - (ip6addr)->addr[3] = PP_HTONL(0x00000001UL);}while(0) -/** Safely copy one IPv6 address to another and change byte order - * from host- to network-order. */ -#define ip6_addr_set_hton(dest, src) do{(dest)->addr[0] = (src) == NULL ? 0 : lwip_htonl((src)->addr[0]); \ - (dest)->addr[1] = (src) == NULL ? 0 : lwip_htonl((src)->addr[1]); \ - (dest)->addr[2] = (src) == NULL ? 0 : lwip_htonl((src)->addr[2]); \ - (dest)->addr[3] = (src) == NULL ? 0 : lwip_htonl((src)->addr[3]);}while(0) - - -/** - * Determine if two IPv6 address are on the same network. - * - * @arg addr1 IPv6 address 1 - * @arg addr2 IPv6 address 2 - * @return !0 if the network identifiers of both address match - */ -#define ip6_addr_netcmp(addr1, addr2) (((addr1)->addr[0] == (addr2)->addr[0]) && \ - ((addr1)->addr[1] == (addr2)->addr[1])) - -#define ip6_addr_net48cmp(addr1, addr2) (((addr1)->addr[0] == (addr2)->addr[0]) && \ - (((addr1)->addr[1] & PP_HTONL(0xffff0000UL)) == \ - ((addr2)->addr[1] & PP_HTONL(0xffff0000UL)))) - -/* Exact-host comparison *after* ip6_addr_netcmp() succeeded, for efficiency. */ -#define ip6_addr_nethostcmp(addr1, addr2) (((addr1)->addr[2] == (addr2)->addr[2]) && \ - ((addr1)->addr[3] == (addr2)->addr[3])) - -#define ip6_addr_cmp(addr1, addr2) (((addr1)->addr[0] == (addr2)->addr[0]) && \ - ((addr1)->addr[1] == (addr2)->addr[1]) && \ - ((addr1)->addr[2] == (addr2)->addr[2]) && \ - ((addr1)->addr[3] == (addr2)->addr[3])) - -#define ip6_get_subnet_id(ip6addr) (lwip_htonl((ip6addr)->addr[1]) & 0x0000ffffUL) - -#define ip6_addr_isany_val(ip6addr) (((ip6addr).addr[0] == 0) && \ - ((ip6addr).addr[1] == 0) && \ - ((ip6addr).addr[2] == 0) && \ - ((ip6addr).addr[3] == 0)) -#define ip6_addr_isany(ip6addr) (((ip6addr) == NULL) || ip6_addr_isany_val(*(ip6addr))) - -#define ip6_addr_isloopback(ip6addr) (((ip6addr)->addr[0] == 0UL) && \ - ((ip6addr)->addr[1] == 0UL) && \ - ((ip6addr)->addr[2] == 0UL) && \ - ((ip6addr)->addr[3] == PP_HTONL(0x00000001UL))) - -#define ip6_addr_isglobal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xe0000000UL)) == PP_HTONL(0x20000000UL)) - -#define ip6_addr_islinklocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xffc00000UL)) == PP_HTONL(0xfe800000UL)) - -#define ip6_addr_issitelocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xffc00000UL)) == PP_HTONL(0xfec00000UL)) - -#define ip6_addr_isuniquelocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xfe000000UL)) == PP_HTONL(0xfc000000UL)) - -#define ip6_addr_isipv4mappedipv6(ip6addr) (((ip6addr)->addr[0] == 0) && ((ip6addr)->addr[1] == 0) && (((ip6addr)->addr[2]) == PP_HTONL(0x0000FFFFUL))) - -#define ip6_addr_ismulticast(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xff000000UL)) == PP_HTONL(0xff000000UL)) -#define ip6_addr_multicast_transient_flag(ip6addr) ((ip6addr)->addr[0] & PP_HTONL(0x00100000UL)) -#define ip6_addr_multicast_prefix_flag(ip6addr) ((ip6addr)->addr[0] & PP_HTONL(0x00200000UL)) -#define ip6_addr_multicast_rendezvous_flag(ip6addr) ((ip6addr)->addr[0] & PP_HTONL(0x00400000UL)) -#define ip6_addr_multicast_scope(ip6addr) ((lwip_htonl((ip6addr)->addr[0]) >> 16) & 0xf) -#define IP6_MULTICAST_SCOPE_RESERVED 0x0 -#define IP6_MULTICAST_SCOPE_RESERVED0 0x0 -#define IP6_MULTICAST_SCOPE_INTERFACE_LOCAL 0x1 -#define IP6_MULTICAST_SCOPE_LINK_LOCAL 0x2 -#define IP6_MULTICAST_SCOPE_RESERVED3 0x3 -#define IP6_MULTICAST_SCOPE_ADMIN_LOCAL 0x4 -#define IP6_MULTICAST_SCOPE_SITE_LOCAL 0x5 -#define IP6_MULTICAST_SCOPE_ORGANIZATION_LOCAL 0x8 -#define IP6_MULTICAST_SCOPE_GLOBAL 0xe -#define IP6_MULTICAST_SCOPE_RESERVEDF 0xf -#define ip6_addr_ismulticast_iflocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xff8f0000UL)) == PP_HTONL(0xff010000UL)) -#define ip6_addr_ismulticast_linklocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xff8f0000UL)) == PP_HTONL(0xff020000UL)) -#define ip6_addr_ismulticast_adminlocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xff8f0000UL)) == PP_HTONL(0xff040000UL)) -#define ip6_addr_ismulticast_sitelocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xff8f0000UL)) == PP_HTONL(0xff050000UL)) -#define ip6_addr_ismulticast_orglocal(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xff8f0000UL)) == PP_HTONL(0xff080000UL)) -#define ip6_addr_ismulticast_global(ip6addr) (((ip6addr)->addr[0] & PP_HTONL(0xff8f0000UL)) == PP_HTONL(0xff0e0000UL)) - -/* @todo define get/set for well-know multicast addresses, e.g. ff02::1 */ -#define ip6_addr_isallnodes_iflocal(ip6addr) (((ip6addr)->addr[0] == PP_HTONL(0xff010000UL)) && \ - ((ip6addr)->addr[1] == 0UL) && \ - ((ip6addr)->addr[2] == 0UL) && \ - ((ip6addr)->addr[3] == PP_HTONL(0x00000001UL))) - -#define ip6_addr_isallnodes_linklocal(ip6addr) (((ip6addr)->addr[0] == PP_HTONL(0xff020000UL)) && \ - ((ip6addr)->addr[1] == 0UL) && \ - ((ip6addr)->addr[2] == 0UL) && \ - ((ip6addr)->addr[3] == PP_HTONL(0x00000001UL))) -#define ip6_addr_isallnodes_networklocal(ip6addr) (((ip6addr)->addr[0] == PP_HTONL(0xff030000UL)) && \ - ((ip6addr)->addr[1] == 0UL) && \ - ((ip6addr)->addr[2] == 0UL) && \ - ((ip6addr)->addr[3] == PP_HTONL(0x00000001UL))) -#define ip6_addr_set_allnodes_linklocal(ip6addr) do{(ip6addr)->addr[0] = PP_HTONL(0xff020000UL); \ - (ip6addr)->addr[1] = 0; \ - (ip6addr)->addr[2] = 0; \ - (ip6addr)->addr[3] = PP_HTONL(0x00000001UL);}while(0) - -#define ip6_addr_isallrouters_linklocal(ip6addr) (((ip6addr)->addr[0] == PP_HTONL(0xff020000UL)) && \ - ((ip6addr)->addr[1] == 0UL) && \ - ((ip6addr)->addr[2] == 0UL) && \ - ((ip6addr)->addr[3] == PP_HTONL(0x00000002UL))) -#define ip6_addr_set_allrouters_linklocal(ip6addr) do{(ip6addr)->addr[0] = PP_HTONL(0xff020000UL); \ - (ip6addr)->addr[1] = 0; \ - (ip6addr)->addr[2] = 0; \ - (ip6addr)->addr[3] = PP_HTONL(0x00000002UL);}while(0) - -#define ip6_addr_issolicitednode(ip6addr) ( ((ip6addr)->addr[0] == PP_HTONL(0xff020000UL)) && \ - ((ip6addr)->addr[2] == PP_HTONL(0x00000001UL)) && \ - (((ip6addr)->addr[3] & PP_HTONL(0xff000000UL)) == PP_HTONL(0xff000000UL)) ) - -#define ip6_addr_set_solicitednode(ip6addr, if_id) do{(ip6addr)->addr[0] = PP_HTONL(0xff020000UL); \ - (ip6addr)->addr[1] = 0; \ - (ip6addr)->addr[2] = PP_HTONL(0x00000001UL); \ - (ip6addr)->addr[3] = (PP_HTONL(0xff000000UL) | (if_id));}while(0) - -#define ip6_addr_cmp_solicitednode(ip6addr, sn_addr) (((ip6addr)->addr[0] == PP_HTONL(0xff020000UL)) && \ - ((ip6addr)->addr[1] == 0) && \ - ((ip6addr)->addr[2] == PP_HTONL(0x00000001UL)) && \ - ((ip6addr)->addr[3] == (PP_HTONL(0xff000000UL) | (sn_addr)->addr[3]))) - -/* IPv6 address states. */ -#define IP6_ADDR_INVALID 0x00 -#define IP6_ADDR_TENTATIVE 0x08 -#define IP6_ADDR_TENTATIVE_1 0x09 /* 1 probe sent */ -#define IP6_ADDR_TENTATIVE_2 0x0a /* 2 probes sent */ -#define IP6_ADDR_TENTATIVE_3 0x0b /* 3 probes sent */ -#define IP6_ADDR_TENTATIVE_4 0x0c /* 4 probes sent */ -#define IP6_ADDR_TENTATIVE_5 0x0d /* 5 probes sent */ -#define IP6_ADDR_TENTATIVE_6 0x0e /* 6 probes sent */ -#define IP6_ADDR_TENTATIVE_7 0x0f /* 7 probes sent */ -#define IP6_ADDR_VALID 0x10 /* This bit marks an address as valid (preferred or deprecated) */ -#define IP6_ADDR_PREFERRED 0x30 -#define IP6_ADDR_DEPRECATED 0x10 /* Same as VALID (valid but not preferred) */ -#define IP6_ADDR_DUPLICATED 0x40 /* Failed DAD test, not valid */ - -#define IP6_ADDR_TENTATIVE_COUNT_MASK 0x07 /* 1-7 probes sent */ - -#define ip6_addr_isinvalid(addr_state) (addr_state == IP6_ADDR_INVALID) -#define ip6_addr_istentative(addr_state) (addr_state & IP6_ADDR_TENTATIVE) -#define ip6_addr_isvalid(addr_state) (addr_state & IP6_ADDR_VALID) /* Include valid, preferred, and deprecated. */ -#define ip6_addr_ispreferred(addr_state) (addr_state == IP6_ADDR_PREFERRED) -#define ip6_addr_isdeprecated(addr_state) (addr_state == IP6_ADDR_DEPRECATED) -#define ip6_addr_isduplicated(addr_state) (addr_state == IP6_ADDR_DUPLICATED) - -#if LWIP_IPV6_ADDRESS_LIFETIMES -#define IP6_ADDR_LIFE_STATIC (0) -#define IP6_ADDR_LIFE_INFINITE (0xffffffffUL) -#define ip6_addr_life_isstatic(addr_life) ((addr_life) == IP6_ADDR_LIFE_STATIC) -#define ip6_addr_life_isinfinite(addr_life) ((addr_life) == IP6_ADDR_LIFE_INFINITE) -#endif /* LWIP_IPV6_ADDRESS_LIFETIMES */ - -#define ip6_addr_debug_print_parts(debug, a, b, c, d, e, f, g, h) \ - LWIP_DEBUGF(debug, ("%" X16_F ":%" X16_F ":%" X16_F ":%" X16_F ":%" X16_F ":%" X16_F ":%" X16_F ":%" X16_F, \ - a, b, c, d, e, f, g, h)) -#define ip6_addr_debug_print(debug, ipaddr) \ - ip6_addr_debug_print_parts(debug, \ - (u16_t)((ipaddr) != NULL ? IP6_ADDR_BLOCK1(ipaddr) : 0), \ - (u16_t)((ipaddr) != NULL ? IP6_ADDR_BLOCK2(ipaddr) : 0), \ - (u16_t)((ipaddr) != NULL ? IP6_ADDR_BLOCK3(ipaddr) : 0), \ - (u16_t)((ipaddr) != NULL ? IP6_ADDR_BLOCK4(ipaddr) : 0), \ - (u16_t)((ipaddr) != NULL ? IP6_ADDR_BLOCK5(ipaddr) : 0), \ - (u16_t)((ipaddr) != NULL ? IP6_ADDR_BLOCK6(ipaddr) : 0), \ - (u16_t)((ipaddr) != NULL ? IP6_ADDR_BLOCK7(ipaddr) : 0), \ - (u16_t)((ipaddr) != NULL ? IP6_ADDR_BLOCK8(ipaddr) : 0)) -#define ip6_addr_debug_print_val(debug, ipaddr) \ - ip6_addr_debug_print_parts(debug, \ - IP6_ADDR_BLOCK1(&(ipaddr)), \ - IP6_ADDR_BLOCK2(&(ipaddr)), \ - IP6_ADDR_BLOCK3(&(ipaddr)), \ - IP6_ADDR_BLOCK4(&(ipaddr)), \ - IP6_ADDR_BLOCK5(&(ipaddr)), \ - IP6_ADDR_BLOCK6(&(ipaddr)), \ - IP6_ADDR_BLOCK7(&(ipaddr)), \ - IP6_ADDR_BLOCK8(&(ipaddr))) - -#define IP6ADDR_STRLEN_MAX 46 - -int ip6addr_aton(const char *cp, ip6_addr_t *addr); -/** returns ptr to static buffer; not reentrant! */ -char *ip6addr_ntoa(const ip6_addr_t *addr); -char *ip6addr_ntoa_r(const ip6_addr_t *addr, char *buf, int buflen); - - - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_IPV6 */ - -#endif /* LWIP_HDR_IP6_ADDR_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/ip6_frag.h b/third_party/lwip/repo/lwip/src/include/lwip/ip6_frag.h deleted file mode 100644 index 6be274734b2198..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/ip6_frag.h +++ /dev/null @@ -1,120 +0,0 @@ -/** - * @file - * - * IPv6 fragmentation and reassembly. - */ - -/* - * Copyright (c) 2010 Inico Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Ivan Delamer - * - * - * Please coordinate changes and requests with Ivan Delamer - * - */ -#ifndef LWIP_HDR_IP6_FRAG_H -#define LWIP_HDR_IP6_FRAG_H - -#include "lwip/opt.h" -#include "lwip/pbuf.h" -#include "lwip/ip6_addr.h" -#include "lwip/ip6.h" -#include "lwip/netif.h" - -#ifdef __cplusplus -extern "C" { -#endif - - -#if LWIP_IPV6 && LWIP_IPV6_REASS /* don't build if not configured for use in lwipopts.h */ - -/** IP6_FRAG_COPYHEADER==1: for platforms where sizeof(void*) > 4, this needs to - * be enabled (to not overwrite part of the data). When enabled, the IPv6 header - * is copied instead of referencing it, which gives more room for struct ip6_reass_helper */ -#ifndef IPV6_FRAG_COPYHEADER -#define IPV6_FRAG_COPYHEADER 0 -#endif - -/** The IPv6 reassembly timer interval in milliseconds. */ -#define IP6_REASS_TMR_INTERVAL 1000 - -/* Copy the complete header of the first fragment to struct ip6_reassdata - or just point to its original location in the first pbuf? */ -#if IPV6_FRAG_COPYHEADER -#define IPV6_FRAG_HDRPTR -#define IPV6_FRAG_HDRREF(hdr) (&(hdr)) -#else /* IPV6_FRAG_COPYHEADER */ -#define IPV6_FRAG_HDRPTR * -#define IPV6_FRAG_HDRREF(hdr) (hdr) -#endif /* IPV6_FRAG_COPYHEADER */ - -/** IPv6 reassembly helper struct. - * This is exported because memp needs to know the size. - */ -struct ip6_reassdata { - struct ip6_reassdata *next; - struct pbuf *p; - struct ip6_hdr IPV6_FRAG_HDRPTR iphdr; - u32_t identification; - u16_t datagram_len; - u8_t nexth; - u8_t timer; -}; - -#define ip6_reass_init() /* Compatibility define */ -void ip6_reass_tmr(void); -struct pbuf *ip6_reass(struct pbuf *p); - -#endif /* LWIP_IPV6 && LWIP_IPV6_REASS */ - -#if LWIP_IPV6 && LWIP_IPV6_FRAG /* don't build if not configured for use in lwipopts.h */ - -#ifndef LWIP_PBUF_CUSTOM_REF_DEFINED -#define LWIP_PBUF_CUSTOM_REF_DEFINED -/** A custom pbuf that holds a reference to another pbuf, which is freed - * when this custom pbuf is freed. This is used to create a custom PBUF_REF - * that points into the original pbuf. */ -struct pbuf_custom_ref { - /** 'base class' */ - struct pbuf_custom pc; - /** pointer to the original pbuf that is referenced */ - struct pbuf *original; -}; -#endif /* LWIP_PBUF_CUSTOM_REF_DEFINED */ - -err_t ip6_frag(struct pbuf *p, struct netif *netif, const ip6_addr_t *dest); - -#endif /* LWIP_IPV6 && LWIP_IPV6_FRAG */ - - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_IP6_FRAG_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/ip6_route_table.h b/third_party/lwip/repo/lwip/src/include/lwip/ip6_route_table.h deleted file mode 100644 index c11b54344ddd75..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/ip6_route_table.h +++ /dev/null @@ -1,90 +0,0 @@ -/** - * @file - * - * IPv6 static route table. - */ - -/* - * Copyright (c) 2015 Nest Labs, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * Author: Pradip De - * - * - * Please coordinate changes and requests with Pradip De - * - */ - -#ifndef __LWIP_IP6_ROUTE_TABLE_H__ -#define __LWIP_IP6_ROUTE_TABLE_H__ - -#include "lwip/opt.h" - -#if LWIP_IPV6 /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/ip.h" -#include "lwip/ip6_addr.h" -#include "lwip/def.h" -#include "lwip/netif.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#if LWIP_IPV6_ROUTE_TABLE_SUPPORT - -#define IP6_MAX_PREFIX_LEN (128) -#define IP6_PREFIX_ALLOWED_GRANULARITY (8) -/* Prefix length cannot be greater than 128 bits and needs to be at a byte boundary */ -#define ip6_prefix_valid(prefix_len) (((prefix_len) <= IP6_MAX_PREFIX_LEN) && \ - (((prefix_len) % IP6_PREFIX_ALLOWED_GRANULARITY) == 0)) - -struct ip6_prefix { - ip6_addr_t addr; - u8_t prefix_len; /* prefix length in bits at byte boundaries */ -}; - -struct ip6_route_entry { - struct ip6_prefix prefix; - struct netif *netif; - ip6_addr_t *gateway; -}; - -err_t ip6_add_route_entry(struct ip6_prefix *ip6_prefix, struct netif *netif, - ip6_addr_t *gateway, s8_t *index); -void ip6_remove_route_entry(struct ip6_prefix *ip6_prefix); -s8_t ip6_find_route_entry(const ip6_addr_t *ip6_dest_addr); -struct netif *ip6_static_route(const ip6_addr_t *src, const ip6_addr_t *dest); -ip6_addr_t *ip6_get_gateway(struct netif *netif, const ip6_addr_t *dest); -struct ip6_route_entry *ip6_get_route_table(void); -#endif /* LWIP_IPV6_ROUTE_TABLE_SUPPORT */ - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_IPV6 */ - -#endif /* __LWIP_IP6_ROUTE_TABLE_H__ */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/ip_addr.h b/third_party/lwip/repo/lwip/src/include/lwip/ip_addr.h deleted file mode 100644 index 11f65d25bde7ae..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/ip_addr.h +++ /dev/null @@ -1,407 +0,0 @@ -/** - * @file - * IP address API (common IPv4 and IPv6) - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_IP_ADDR_H -#define LWIP_HDR_IP_ADDR_H - -#include "lwip/opt.h" -#include "lwip/def.h" - -#include "lwip/ip4_addr.h" -#include "lwip/ip6_addr.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** @ingroup ipaddr - * IP address types for use in ip_addr_t.type member. - * @see tcp_new_ip_type(), udp_new_ip_type(), raw_new_ip_type(). - */ -enum lwip_ip_addr_type { - /** IPv4 */ - IPADDR_TYPE_V4 = 0U, - /** IPv6 */ - IPADDR_TYPE_V6 = 6U, - /** IPv4+IPv6 ("dual-stack") */ - IPADDR_TYPE_ANY = 46U -}; - -#if LWIP_IPV4 && LWIP_IPV6 -/** - * @ingroup ipaddr - * A union struct for both IP version's addresses. - * ATTENTION: watch out for its size when adding IPv6 address scope! - */ -typedef struct ip_addr { - union { - ip6_addr_t ip6; - ip4_addr_t ip4; - } u_addr; - /** @ref lwip_ip_addr_type */ - u8_t type; -} ip_addr_t; - -extern const ip_addr_t ip_addr_any_type; - -/** @ingroup ip4addr */ -#define IPADDR4_INIT(u32val) { { { { u32val, 0ul, 0ul, 0ul } } }, IPADDR_TYPE_V4 } -/** @ingroup ip4addr */ -#define IPADDR4_INIT_BYTES(a,b,c,d) IPADDR4_INIT(PP_HTONL(LWIP_MAKEU32(a,b,c,d))) -/** @ingroup ip6addr */ -#define IPADDR6_INIT(a, b, c, d) { { { { a, b, c, d } } }, IPADDR_TYPE_V6 } -/** @ingroup ip6addr */ -#define IPADDR6_INIT_HOST(a, b, c, d) { { { { PP_HTONL(a), PP_HTONL(b), PP_HTONL(c), PP_HTONL(d) } } }, IPADDR_TYPE_V6 } - -/** @ingroup ipaddr */ -#define IP_IS_ANY_TYPE_VAL(ipaddr) (IP_GET_TYPE(&ipaddr) == IPADDR_TYPE_ANY) -/** @ingroup ipaddr */ -#define IPADDR_ANY_TYPE_INIT { { { { 0ul, 0ul, 0ul, 0ul } } }, IPADDR_TYPE_ANY } - -/** @ingroup ip4addr */ -#define IP_IS_V4_VAL(ipaddr) (IP_GET_TYPE(&ipaddr) == IPADDR_TYPE_V4) -/** @ingroup ip6addr */ -#define IP_IS_V6_VAL(ipaddr) (IP_GET_TYPE(&ipaddr) == IPADDR_TYPE_V6) -/** @ingroup ip4addr */ -#define IP_IS_V4(ipaddr) (((ipaddr) == NULL) || IP_IS_V4_VAL(*(ipaddr))) -/** @ingroup ip6addr */ -#define IP_IS_V6(ipaddr) (((ipaddr) != NULL) && IP_IS_V6_VAL(*(ipaddr))) - -#define IP_SET_TYPE_VAL(ipaddr, iptype) do { (ipaddr).type = (iptype); }while(0) -#define IP_SET_TYPE(ipaddr, iptype) do { if((ipaddr) != NULL) { IP_SET_TYPE_VAL(*(ipaddr), iptype); }}while(0) -#define IP_GET_TYPE(ipaddr) ((ipaddr)->type) - -#define IP_ADDR_PCB_VERSION_MATCH_EXACT(pcb, ipaddr) (IP_GET_TYPE(&pcb->local_ip) == IP_GET_TYPE(ipaddr)) -#define IP_ADDR_PCB_VERSION_MATCH(pcb, ipaddr) (IP_IS_ANY_TYPE_VAL(pcb->local_ip) || IP_ADDR_PCB_VERSION_MATCH_EXACT(pcb, ipaddr)) - -/** @ingroup ip6addr - * Convert generic ip address to specific protocol version - */ -#define ip_2_ip6(ipaddr) (&((ipaddr)->u_addr.ip6)) -/** @ingroup ip4addr - * Convert generic ip address to specific protocol version - */ -#define ip_2_ip4(ipaddr) (&((ipaddr)->u_addr.ip4)) - -/** @ingroup ip4addr */ -#define IP_ADDR4(ipaddr,a,b,c,d) do { IP4_ADDR(ip_2_ip4(ipaddr),a,b,c,d); \ - IP_SET_TYPE_VAL(*(ipaddr), IPADDR_TYPE_V4); } while(0) -/** @ingroup ip6addr */ -#define IP_ADDR6(ipaddr,i0,i1,i2,i3) do { IP6_ADDR(ip_2_ip6(ipaddr),i0,i1,i2,i3); \ - IP_SET_TYPE_VAL(*(ipaddr), IPADDR_TYPE_V6); } while(0) -/** @ingroup ip6addr */ -#define IP_ADDR6_HOST(ipaddr,i0,i1,i2,i3) IP_ADDR6(ipaddr,PP_HTONL(i0),PP_HTONL(i1),PP_HTONL(i2),PP_HTONL(i3)) - -/** @ingroup ipaddr */ -#define ip_addr_copy(dest, src) do{ IP_SET_TYPE_VAL(dest, IP_GET_TYPE(&src)); if(IP_IS_V6_VAL(src)){ \ - ip6_addr_copy(*ip_2_ip6(&(dest)), *ip_2_ip6(&(src))); }else{ \ - ip4_addr_copy(*ip_2_ip4(&(dest)), *ip_2_ip4(&(src))); }}while(0) -/** @ingroup ip6addr */ -#define ip_addr_copy_from_ip6(dest, src) do{ \ - ip6_addr_copy(*ip_2_ip6(&(dest)), src); IP_SET_TYPE_VAL(dest, IPADDR_TYPE_V6); }while(0) -/** @ingroup ip4addr */ -#define ip_addr_copy_from_ip4(dest, src) do{ \ - ip4_addr_copy(*ip_2_ip4(&(dest)), src); IP_SET_TYPE_VAL(dest, IPADDR_TYPE_V4); }while(0) -/** @ingroup ip4addr */ -#define ip_addr_set_ip4_u32(ipaddr, val) do{if(ipaddr){ip4_addr_set_u32(ip_2_ip4(ipaddr), val); \ - IP_SET_TYPE(ipaddr, IPADDR_TYPE_V4); }}while(0) -/** @ingroup ip4addr */ -#define ip_addr_get_ip4_u32(ipaddr) (((ipaddr) && IP_IS_V4(ipaddr)) ? \ - ip4_addr_get_u32(ip_2_ip4(ipaddr)) : 0) -/** @ingroup ipaddr */ -#define ip_addr_set(dest, src) do{ IP_SET_TYPE(dest, IP_GET_TYPE(src)); if(IP_IS_V6(src)){ \ - ip6_addr_set(ip_2_ip6(dest), ip_2_ip6(src)); }else{ \ - ip4_addr_set(ip_2_ip4(dest), ip_2_ip4(src)); }}while(0) -/** @ingroup ipaddr */ -#define ip_addr_set_ipaddr(dest, src) ip_addr_set(dest, src) -/** @ingroup ipaddr */ -#define ip_addr_set_zero(ipaddr) do{ \ - ip6_addr_set_zero(ip_2_ip6(ipaddr)); IP_SET_TYPE(ipaddr, 0); }while(0) -/** @ingroup ip5addr */ -#define ip_addr_set_zero_ip4(ipaddr) do{ \ - ip6_addr_set_zero(ip_2_ip6(ipaddr)); IP_SET_TYPE(ipaddr, IPADDR_TYPE_V4); }while(0) -/** @ingroup ip6addr */ -#define ip_addr_set_zero_ip6(ipaddr) do{ \ - ip6_addr_set_zero(ip_2_ip6(ipaddr)); IP_SET_TYPE(ipaddr, IPADDR_TYPE_V6); }while(0) -/** @ingroup ipaddr */ -#define ip_addr_set_any(is_ipv6, ipaddr) do{if(is_ipv6){ \ - ip6_addr_set_any(ip_2_ip6(ipaddr)); IP_SET_TYPE(ipaddr, IPADDR_TYPE_V6); }else{ \ - ip4_addr_set_any(ip_2_ip4(ipaddr)); IP_SET_TYPE(ipaddr, IPADDR_TYPE_V4); }}while(0) -/** @ingroup ipaddr */ -#define ip_addr_set_loopback(is_ipv6, ipaddr) do{if(is_ipv6){ \ - ip6_addr_set_loopback(ip_2_ip6(ipaddr)); IP_SET_TYPE(ipaddr, IPADDR_TYPE_V6); }else{ \ - ip4_addr_set_loopback(ip_2_ip4(ipaddr)); IP_SET_TYPE(ipaddr, IPADDR_TYPE_V4); }}while(0) -/** @ingroup ipaddr */ -#define ip_addr_set_hton(dest, src) do{if(IP_IS_V6(src)){ \ - ip6_addr_set_hton(ip_2_ip6(ipaddr), (src)); IP_SET_TYPE(dest, IPADDR_TYPE_V6); }else{ \ - ip4_addr_set_hton(ip_2_ip4(ipaddr), (src)); IP_SET_TYPE(dest, IPADDR_TYPE_V4); }}while(0) -/** @ingroup ipaddr */ -#define ip_addr_get_network(target, host, netmask) do{if(IP_IS_V6(host)){ \ - ip4_addr_set_zero(ip_2_ip4(target)); IP_SET_TYPE(target, IPADDR_TYPE_V6); } else { \ - ip4_addr_get_network(ip_2_ip4(target), ip_2_ip4(host), ip_2_ip4(netmask)); IP_SET_TYPE(target, IPADDR_TYPE_V4); }}while(0) -/** @ingroup ipaddr */ -#define ip_addr_netcmp(addr1, addr2, mask) ((IP_IS_V6(addr1) && IP_IS_V6(addr2)) ? \ - 0 : \ - ip4_addr_netcmp(ip_2_ip4(addr1), ip_2_ip4(addr2), mask)) -/** @ingroup ipaddr */ -#define ip_addr_cmp(addr1, addr2) ((IP_GET_TYPE(addr1) != IP_GET_TYPE(addr2)) ? 0 : (IP_IS_V6_VAL(*(addr1)) ? \ - ip6_addr_cmp(ip_2_ip6(addr1), ip_2_ip6(addr2)) : \ - ip4_addr_cmp(ip_2_ip4(addr1), ip_2_ip4(addr2)))) -/** @ingroup ipaddr */ -#define ip_addr_isany(ipaddr) ((IP_IS_V6(ipaddr)) ? \ - ip6_addr_isany(ip_2_ip6(ipaddr)) : \ - ip4_addr_isany(ip_2_ip4(ipaddr))) -/** @ingroup ipaddr */ -#define ip_addr_isany_val(ipaddr) ((IP_IS_V6_VAL(ipaddr)) ? \ - ip6_addr_isany_val(*ip_2_ip6(&(ipaddr))) : \ - ip4_addr_isany_val(*ip_2_ip4(&(ipaddr)))) -/** @ingroup ipaddr */ -#define ip_addr_isbroadcast(ipaddr, netif) ((IP_IS_V6(ipaddr)) ? \ - 0 : \ - ip4_addr_isbroadcast(ip_2_ip4(ipaddr), netif)) -/** @ingroup ipaddr */ -#define ip_addr_ismulticast(ipaddr) ((IP_IS_V6(ipaddr)) ? \ - ip6_addr_ismulticast(ip_2_ip6(ipaddr)) : \ - ip4_addr_ismulticast(ip_2_ip4(ipaddr))) -/** @ingroup ipaddr */ -#define ip_addr_isloopback(ipaddr) ((IP_IS_V6(ipaddr)) ? \ - ip6_addr_isloopback(ip_2_ip6(ipaddr)) : \ - ip4_addr_isloopback(ip_2_ip4(ipaddr))) -/** @ingroup ipaddr */ -#define ip_addr_islinklocal(ipaddr) ((IP_IS_V6(ipaddr)) ? \ - ip6_addr_islinklocal(ip_2_ip6(ipaddr)) : \ - ip4_addr_islinklocal(ip_2_ip4(ipaddr))) -#define ip_addr_debug_print(debug, ipaddr) do { if(IP_IS_V6(ipaddr)) { \ - ip6_addr_debug_print(debug, ip_2_ip6(ipaddr)); } else { \ - ip4_addr_debug_print(debug, ip_2_ip4(ipaddr)); }}while(0) -#define ip_addr_debug_print_val(debug, ipaddr) do { if(IP_IS_V6_VAL(ipaddr)) { \ - ip6_addr_debug_print_val(debug, *ip_2_ip6(&(ipaddr))); } else { \ - ip4_addr_debug_print_val(debug, *ip_2_ip4(&(ipaddr))); }}while(0) -/** @ingroup ipaddr */ -#define ipaddr_ntoa(addr) (((addr) == NULL) ? "NULL" : \ - ((IP_IS_V6(addr)) ? ip6addr_ntoa(ip_2_ip6(addr)) : ip4addr_ntoa(ip_2_ip4(addr)))) -/** @ingroup ipaddr */ -#define ipaddr_ntoa_r(addr, buf, buflen) (((addr) == NULL) ? "NULL" : \ - ((IP_IS_V6(addr)) ? ip6addr_ntoa_r(ip_2_ip6(addr), buf, buflen) : ip4addr_ntoa_r(ip_2_ip4(addr), buf, buflen))) -int ipaddr_aton(const char *cp, ip_addr_t *addr); - -/** @ingroup ipaddr */ -#define IPADDR_STRLEN_MAX IP6ADDR_STRLEN_MAX - -/** @ingroup ipaddr */ -#define ip4_2_ipv4_mapped_ipv6(ip6addr, ip4addr) do { \ - (ip6addr)->addr[3] = (ip4addr)->addr; \ - (ip6addr)->addr[2] = PP_HTONL(0x0000FFFFUL); \ - (ip6addr)->addr[1] = 0; \ - (ip6addr)->addr[0] = 0; } while(0); - -/** @ingroup ipaddr */ -#define unmap_ipv4_mapped_ipv6(ip4addr, ip6addr) \ - (ip4addr)->addr = (ip6addr)->addr[3]; - -#define IP46_ADDR_ANY(type) (((type) == IPADDR_TYPE_V6)? IP6_ADDR_ANY : IP4_ADDR_ANY) - -#else /* LWIP_IPV4 && LWIP_IPV6 */ - -#define IP_ADDR_PCB_VERSION_MATCH(addr, pcb) 1 -#define IP_ADDR_PCB_VERSION_MATCH_EXACT(pcb, ipaddr) 1 - -#if LWIP_IPV4 - -typedef ip4_addr_t ip_addr_t; -#define IPADDR4_INIT(u32val) { u32val } -#define IPADDR4_INIT_BYTES(a,b,c,d) IPADDR4_INIT(PP_HTONL(LWIP_MAKEU32(a,b,c,d))) -#define IP_IS_V4_VAL(ipaddr) 1 -#define IP_IS_V6_VAL(ipaddr) 0 -#define IP_IS_V4(ipaddr) 1 -#define IP_IS_V6(ipaddr) 0 -#define IP_IS_ANY_TYPE_VAL(ipaddr) 0 -#define IP_SET_TYPE_VAL(ipaddr, iptype) -#define IP_SET_TYPE(ipaddr, iptype) -#define IP_GET_TYPE(ipaddr) IPADDR_TYPE_V4 -#define ip_2_ip4(ipaddr) (ipaddr) -#define IP_ADDR4(ipaddr,a,b,c,d) IP4_ADDR(ipaddr,a,b,c,d) - -#define ip_addr_copy(dest, src) ip4_addr_copy(dest, src) -#define ip_addr_copy_from_ip4(dest, src) ip4_addr_copy(dest, src) -#define ip_addr_set_ip4_u32(ipaddr, val) ip4_addr_set_u32(ip_2_ip4(ipaddr), val) -#define ip_addr_get_ip4_u32(ipaddr) ip4_addr_get_u32(ip_2_ip4(ipaddr)) -#define ip_addr_set(dest, src) ip4_addr_set(dest, src) -#define ip_addr_set_ipaddr(dest, src) ip4_addr_set(dest, src) -#define ip_addr_set_zero(ipaddr) ip4_addr_set_zero(ipaddr) -#define ip_addr_set_zero_ip4(ipaddr) ip4_addr_set_zero(ipaddr) -#define ip_addr_set_any(is_ipv6, ipaddr) ip4_addr_set_any(ipaddr) -#define ip_addr_set_loopback(is_ipv6, ipaddr) ip4_addr_set_loopback(ipaddr) -#define ip_addr_set_hton(dest, src) ip4_addr_set_hton(dest, src) -#define ip_addr_get_network(target, host, mask) ip4_addr_get_network(target, host, mask) -#define ip_addr_netcmp(addr1, addr2, mask) ip4_addr_netcmp(addr1, addr2, mask) -#define ip_addr_cmp(addr1, addr2) ip4_addr_cmp(addr1, addr2) -#define ip_addr_isany(ipaddr) ip4_addr_isany(ipaddr) -#define ip_addr_isany_val(ipaddr) ip4_addr_isany_val(ipaddr) -#define ip_addr_isloopback(ipaddr) ip4_addr_isloopback(ipaddr) -#define ip_addr_islinklocal(ipaddr) ip4_addr_islinklocal(ipaddr) -#define ip_addr_isbroadcast(addr, netif) ip4_addr_isbroadcast(addr, netif) -#define ip_addr_ismulticast(ipaddr) ip4_addr_ismulticast(ipaddr) -#define ip_addr_debug_print(debug, ipaddr) ip4_addr_debug_print(debug, ipaddr) -#define ip_addr_debug_print_val(debug, ipaddr) ip4_addr_debug_print_val(debug, ipaddr) -#define ipaddr_ntoa(ipaddr) ip4addr_ntoa(ipaddr) -#define ipaddr_ntoa_r(ipaddr, buf, buflen) ip4addr_ntoa_r(ipaddr, buf, buflen) -#define ipaddr_aton(cp, addr) ip4addr_aton(cp, addr) - -#define IPADDR_STRLEN_MAX IP4ADDR_STRLEN_MAX - -#define IP46_ADDR_ANY(type) (IP4_ADDR_ANY) - -#else /* LWIP_IPV4 */ - -typedef ip6_addr_t ip_addr_t; -#define IPADDR6_INIT(a, b, c, d) { { a, b, c, d } } -#define IPADDR6_INIT_HOST(a, b, c, d) { { PP_HTONL(a), PP_HTONL(b), PP_HTONL(c), PP_HTONL(d) } } -#define IP_IS_V4_VAL(ipaddr) 0 -#define IP_IS_V6_VAL(ipaddr) 1 -#define IP_IS_V4(ipaddr) 0 -#define IP_IS_V6(ipaddr) 1 -#define IP_IS_ANY_TYPE_VAL(ipaddr) 0 -#define IP_SET_TYPE_VAL(ipaddr, iptype) -#define IP_SET_TYPE(ipaddr, iptype) -#define IP_GET_TYPE(ipaddr) IPADDR_TYPE_V6 -#define ip_2_ip6(ipaddr) (ipaddr) -#define IP_ADDR6(ipaddr,i0,i1,i2,i3) IP6_ADDR(ipaddr,i0,i1,i2,i3) -#define IP_ADDR6_HOST(ipaddr,i0,i1,i2,i3) IP_ADDR6(ipaddr,PP_HTONL(i0),PP_HTONL(i1),PP_HTONL(i2),PP_HTONL(i3)) - -#define ip_addr_copy(dest, src) ip6_addr_copy(dest, src) -#define ip_addr_copy_from_ip6(dest, src) ip6_addr_copy(dest, src) -#define ip_addr_set(dest, src) ip6_addr_set(dest, src) -#define ip_addr_set_ipaddr(dest, src) ip6_addr_set(dest, src) -#define ip_addr_set_zero(ipaddr) ip6_addr_set_zero(ipaddr) -#define ip_addr_set_zero_ip6(ipaddr) ip6_addr_set_zero(ipaddr) -#define ip_addr_set_any(is_ipv6, ipaddr) ip6_addr_set_any(ipaddr) -#define ip_addr_set_loopback(is_ipv6, ipaddr) ip6_addr_set_loopback(ipaddr) -#define ip_addr_set_hton(dest, src) ip6_addr_set_hton(dest, src) -#define ip_addr_get_network(target, host, mask) ip6_addr_set_zero(target) -#define ip_addr_netcmp(addr1, addr2, mask) 0 -#define ip_addr_cmp(addr1, addr2) ip6_addr_cmp(addr1, addr2) -#define ip_addr_isany(ipaddr) ip6_addr_isany(ipaddr) -#define ip_addr_isany_val(ipaddr) ip6_addr_isany_val(ipaddr) -#define ip_addr_isloopback(ipaddr) ip6_addr_isloopback(ipaddr) -#define ip_addr_islinklocal(ipaddr) ip6_addr_islinklocal(ipaddr) -#define ip_addr_isbroadcast(addr, netif) 0 -#define ip_addr_ismulticast(ipaddr) ip6_addr_ismulticast(ipaddr) -#define ip_addr_debug_print(debug, ipaddr) ip6_addr_debug_print(debug, ipaddr) -#define ip_addr_debug_print_val(debug, ipaddr) ip6_addr_debug_print_val(debug, ipaddr) -#define ipaddr_ntoa(ipaddr) ip6addr_ntoa(ipaddr) -#define ipaddr_ntoa_r(ipaddr, buf, buflen) ip6addr_ntoa_r(ipaddr, buf, buflen) -#define ipaddr_aton(cp, addr) ip6addr_aton(cp, addr) - -#define IPADDR_STRLEN_MAX IP6ADDR_STRLEN_MAX - -#define IP46_ADDR_ANY(type) (IP6_ADDR_ANY) - -#endif /* LWIP_IPV4 */ -#endif /* LWIP_IPV4 && LWIP_IPV6 */ - -#if LWIP_IPV4 - -extern const ip_addr_t ip_addr_any; -extern const ip_addr_t ip_addr_broadcast; - -/** - * @ingroup ip4addr - * Can be used as a fixed/const ip_addr_t - * for the IP wildcard. - * Defined to @ref IP4_ADDR_ANY when IPv4 is enabled. - * Defined to @ref IP6_ADDR_ANY in IPv6 only systems. - * Use this if you can handle IPv4 _AND_ IPv6 addresses. - * Use @ref IP4_ADDR_ANY or @ref IP6_ADDR_ANY when the IP - * type matters. - */ -#define IP_ADDR_ANY IP4_ADDR_ANY -/** - * @ingroup ip4addr - * Can be used as a fixed/const ip_addr_t - * for the IPv4 wildcard and the broadcast address - */ -#define IP4_ADDR_ANY (&ip_addr_any) -/** - * @ingroup ip4addr - * Can be used as a fixed/const ip4_addr_t - * for the wildcard and the broadcast address - */ -#define IP4_ADDR_ANY4 (ip_2_ip4(&ip_addr_any)) - -/** @ingroup ip4addr */ -#define IP_ADDR_BROADCAST (&ip_addr_broadcast) -/** @ingroup ip4addr */ -#define IP4_ADDR_BROADCAST (ip_2_ip4(&ip_addr_broadcast)) - -#endif /* LWIP_IPV4*/ - -#if LWIP_IPV6 - -extern const ip_addr_t ip6_addr_any; - -/** - * @ingroup ip6addr - * IP6_ADDR_ANY can be used as a fixed ip_addr_t - * for the IPv6 wildcard address - */ -#define IP6_ADDR_ANY (&ip6_addr_any) -/** - * @ingroup ip6addr - * IP6_ADDR_ANY6 can be used as a fixed ip6_addr_t - * for the IPv6 wildcard address - */ -#define IP6_ADDR_ANY6 (ip_2_ip6(&ip6_addr_any)) - -#if !LWIP_IPV4 -/** IPv6-only configurations */ -#define IP_ADDR_ANY IP6_ADDR_ANY -#endif /* !LWIP_IPV4 */ - -#endif - -#if LWIP_IPV4 && LWIP_IPV6 -/** @ingroup ipaddr */ -#define IP_ANY_TYPE (&ip_addr_any_type) -#else -#define IP_ANY_TYPE IP_ADDR_ANY -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_IP_ADDR_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/mem.h b/third_party/lwip/repo/lwip/src/include/lwip/mem.h deleted file mode 100644 index ff208d25c327f7..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/mem.h +++ /dev/null @@ -1,82 +0,0 @@ -/** - * @file - * Heap API - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_MEM_H -#define LWIP_HDR_MEM_H - -#include "lwip/opt.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#if MEM_LIBC_MALLOC - -#include "lwip/arch.h" - -typedef size_t mem_size_t; -#define MEM_SIZE_F SZT_F - -#elif MEM_USE_POOLS - -typedef u16_t mem_size_t; -#define MEM_SIZE_F U16_F - -#else - -/* MEM_SIZE would have to be aligned, but using 64000 here instead of - * 65535 leaves some room for alignment... - */ -#if MEM_SIZE > 64000L -typedef u32_t mem_size_t; -#define MEM_SIZE_F U32_F -#else -typedef u16_t mem_size_t; -#define MEM_SIZE_F U16_F -#endif /* MEM_SIZE > 64000 */ -#endif - -void mem_init(void); -void *mem_trim(void *mem, mem_size_t size); -void *mem_malloc(mem_size_t size); -void *mem_calloc(mem_size_t count, mem_size_t size); -void mem_free(void *mem); - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_MEM_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/memp.h b/third_party/lwip/repo/lwip/src/include/lwip/memp.h deleted file mode 100644 index cd30996de7fd21..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/memp.h +++ /dev/null @@ -1,164 +0,0 @@ -/** - * @file - * Memory pool API - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ - -#ifndef LWIP_HDR_MEMP_H -#define LWIP_HDR_MEMP_H - -#include "lwip/opt.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* run once with empty definition to handle all custom includes in lwippools.h */ -#define LWIP_MEMPOOL(name,num,size,desc) -#include "lwip/priv/memp_std.h" - -/** Create the list of all memory pools managed by memp. MEMP_MAX represents a NULL pool at the end */ -typedef enum { -#define LWIP_MEMPOOL(name,num,size,desc) MEMP_##name, -#include "lwip/priv/memp_std.h" - MEMP_MAX -} memp_t; - -#include "lwip/priv/memp_priv.h" -#include "lwip/stats.h" - -extern const struct memp_desc* const memp_pools[MEMP_MAX]; - -#if MEMP_MEM_MALLOC || MEM_USE_POOLS || LWIP_PBUF_FROM_CUSTOM_POOLS -extern const u16_t memp_sizes[MEMP_MAX]; -#endif /* MEMP_MEM_MALLOC || MEM_USE_POOLS */ - -/** - * @ingroup mempool - * Declare prototype for private memory pool if it is used in multiple files - */ -#define LWIP_MEMPOOL_PROTOTYPE(name) extern const struct memp_desc memp_ ## name - -#if MEMP_MEM_MALLOC - -#define LWIP_MEMPOOL_DECLARE(name,num,size,desc) \ - LWIP_MEMPOOL_DECLARE_STATS_INSTANCE(memp_stats_ ## name) \ - const struct memp_desc memp_ ## name = { \ - DECLARE_LWIP_MEMPOOL_DESC(desc) \ - LWIP_MEMPOOL_DECLARE_STATS_REFERENCE(memp_stats_ ## name) \ - LWIP_MEM_ALIGN_SIZE(size) \ - }; - -#else /* MEMP_MEM_MALLOC */ - -/** - * @ingroup mempool - * Declare a private memory pool - * Private mempools example: - * .h: only when pool is used in multiple .c files: LWIP_MEMPOOL_PROTOTYPE(my_private_pool); - * .c: - * - in global variables section: LWIP_MEMPOOL_DECLARE(my_private_pool, 10, sizeof(foo), "Some description") - * - call ONCE before using pool (e.g. in some init() function): LWIP_MEMPOOL_INIT(my_private_pool); - * - allocate: void* my_new_mem = LWIP_MEMPOOL_ALLOC(my_private_pool); - * - free: LWIP_MEMPOOL_FREE(my_private_pool, my_new_mem); - * - * To relocate a pool, declare it as extern in cc.h. Example for GCC: - * extern u8_t __attribute__((section(".onchip_mem"))) memp_memory_my_private_pool[]; - */ -#define LWIP_MEMPOOL_DECLARE(name,num,size,desc) \ - LWIP_DECLARE_MEMORY_ALIGNED(memp_memory_ ## name ## _base, ((num) * (MEMP_SIZE + MEMP_ALIGN_SIZE(size)))); \ - \ - LWIP_MEMPOOL_DECLARE_STATS_INSTANCE(memp_stats_ ## name) \ - \ - static struct memp *memp_tab_ ## name; \ - \ - const struct memp_desc memp_ ## name = { \ - DECLARE_LWIP_MEMPOOL_DESC(desc) \ - LWIP_MEMPOOL_DECLARE_STATS_REFERENCE(memp_stats_ ## name) \ - LWIP_MEM_ALIGN_SIZE(size), \ - (num), \ - memp_memory_ ## name ## _base, \ - &memp_tab_ ## name \ - }; - -#endif /* MEMP_MEM_MALLOC */ - -/** - * @ingroup mempool - * Initialize a private memory pool - */ -#define LWIP_MEMPOOL_INIT(name) memp_init_pool(&memp_ ## name) -/** - * @ingroup mempool - * Allocate from a private memory pool - */ -#define LWIP_MEMPOOL_ALLOC(name) memp_malloc_pool(&memp_ ## name) -/** - * @ingroup mempool - * Free element from a private memory pool - */ -#define LWIP_MEMPOOL_FREE(name, x) memp_free_pool(&memp_ ## name, (x)) - -#if MEM_USE_POOLS -/** This structure is used to save the pool one element came from. - * This has to be defined here as it is required for pool size calculation. */ -struct memp_malloc_helper -{ - memp_t poolnr; -#if MEMP_OVERFLOW_CHECK || (LWIP_STATS && MEM_STATS) - u16_t size; -#endif /* MEMP_OVERFLOW_CHECK || (LWIP_STATS && MEM_STATS) */ -}; -#endif /* MEM_USE_POOLS */ - -void memp_init(void); - -#if MEMP_OVERFLOW_CHECK -void *memp_malloc_fn(memp_t type, const char* file, const int line); -#define memp_malloc(t) memp_malloc_fn((t), __FILE__, __LINE__) -#else -void *memp_malloc(memp_t type); -#endif -void memp_free(memp_t type, void *mem); -#if MEMP_SEPARATE_POOLS -u16_t memp_pbuf_index(memp_t type, const void *mem); -u16_t memp_num_pbufs(memp_t type); -#endif -u8_t memp_is_not_empty (memp_t type); - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_MEMP_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/mld6.h b/third_party/lwip/repo/lwip/src/include/lwip/mld6.h deleted file mode 100644 index 7219beb6f27358..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/mld6.h +++ /dev/null @@ -1,97 +0,0 @@ -/** - * @file - * - * Multicast listener discovery for IPv6. Aims to be compliant with RFC 2710. - * No support for MLDv2. - */ - -/* - * Copyright (c) 2010 Inico Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Ivan Delamer - * - * - * Please coordinate changes and requests with Ivan Delamer - * - */ - -#ifndef LWIP_HDR_MLD6_H -#define LWIP_HDR_MLD6_H - -#include "lwip/opt.h" - - /* don't build if not configured for use in lwipopts.h */ - #if LWIP_IPV6_MLD && LWIP_IPV6_ND && LWIP_IPV6 - -#include "lwip/pbuf.h" -#include "lwip/netif.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** MLD group */ -struct mld_group { - /** next link */ - struct mld_group *next; - /** multicast address */ - ip6_addr_t group_address; - /** signifies we were the last person to report */ - u8_t last_reporter_flag; - /** current state of the group */ - u8_t group_state; - /** timer for reporting */ - u16_t timer; - /** counter of simultaneous uses */ - u8_t use; -}; - -err_t mld6_stop(struct netif *netif); -void mld6_report_groups(struct netif *netif); -struct mld_group *mld6_lookfor_group(struct netif *ifp, const ip6_addr_t *addr); -void mld6_input(struct pbuf *p, struct netif *inp); -err_t mld6_joingroup(const ip6_addr_t *srcaddr, const ip6_addr_t *groupaddr); -err_t mld6_joingroup_netif(struct netif *netif, const ip6_addr_t *groupaddr); -err_t mld6_leavegroup(const ip6_addr_t *srcaddr, const ip6_addr_t *groupaddr); -err_t mld6_leavegroup_netif(struct netif *netif, const ip6_addr_t *groupaddr); - -/** @ingroup mld6 - * Get list head of MLD6 groups for netif. - * Note: The allnodes group IP is NOT in the list, since it must always - * be received for correct IPv6 operation. - * @see @ref netif_set_mld_mac_filter() - */ -#define netif_mld6_data(netif) ((struct mld_group *)netif_get_client_data(netif, LWIP_NETIF_CLIENT_DATA_INDEX_MLD6)) - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_IPV6_MLD && LWIP_IPV6_ND && LWIP_IPV6 */ - -#endif /* LWIP_HDR_MLD6_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/nd6.h b/third_party/lwip/repo/lwip/src/include/lwip/nd6.h deleted file mode 100644 index e68eb357341b6d..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/nd6.h +++ /dev/null @@ -1,85 +0,0 @@ -/** - * @file - * - * Neighbor discovery and stateless address autoconfiguration for IPv6. - * Aims to be compliant with RFC 4861 (Neighbor discovery) and RFC 4862 - * (Address autoconfiguration). - */ - -/* - * Copyright (c) 2010 Inico Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Ivan Delamer - * - * - * Please coordinate changes and requests with Ivan Delamer - * - */ - -#ifndef LWIP_HDR_ND6_H -#define LWIP_HDR_ND6_H - -#include "lwip/opt.h" - -/* don't build if not configured for use in lwipopts.h */ -#if LWIP_IPV6 && LWIP_IPV6_ND - -#include "lwip/ip6_addr.h" -#include "lwip/err.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** 1 second period */ -#define ND6_TMR_INTERVAL 1000 - -struct pbuf; -struct netif; - -void nd6_tmr(void); -void nd6_input(struct pbuf *p, struct netif *inp); -void nd6_clear_destination_cache(void); -struct netif *nd6_find_route(const ip6_addr_t *ip6addr); -err_t nd6_get_next_hop_addr_or_queue(struct netif *netif, struct pbuf *q, const ip6_addr_t *ip6addr, const u8_t **hwaddrp); -u16_t nd6_get_destination_mtu(const ip6_addr_t *ip6addr, struct netif *netif); -#if LWIP_ND6_TCP_REACHABILITY_HINTS -void nd6_reachability_hint(const ip6_addr_t *ip6addr); -#endif /* LWIP_ND6_TCP_REACHABILITY_HINTS */ -void nd6_cleanup_netif(struct netif *netif); -#if LWIP_IPV6_MLD -void nd6_adjust_mld_membership(struct netif *netif, s8_t addr_idx, u8_t new_state); -#endif /* LWIP_IPV6_MLD */ - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_IPV6 && LWIP_IPV6_ND */ - -#endif /* LWIP_HDR_ND6_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/netbuf.h b/third_party/lwip/repo/lwip/src/include/lwip/netbuf.h deleted file mode 100644 index e6865f80f94d3f..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/netbuf.h +++ /dev/null @@ -1,118 +0,0 @@ -/** - * @file - * netbuf API (for netconn API) - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_NETBUF_H -#define LWIP_HDR_NETBUF_H - -#include "lwip/opt.h" - -#if LWIP_NETCONN || LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */ -/* Note: Netconn API is always available when sockets are enabled - - * sockets are implemented on top of them */ - -#include "lwip/pbuf.h" -#include "lwip/ip_addr.h" -#include "lwip/ip6_addr.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** This netbuf has dest-addr/port set */ -#define NETBUF_FLAG_DESTADDR 0x01 -/** This netbuf includes a checksum */ -#define NETBUF_FLAG_CHKSUM 0x02 - -/** "Network buffer" - contains data and addressing info */ -struct netbuf { - struct pbuf *p, *ptr; - ip_addr_t addr; - u16_t port; -#if LWIP_NETBUF_RECVINFO || LWIP_CHECKSUM_ON_COPY -#if LWIP_CHECKSUM_ON_COPY - u8_t flags; -#endif /* LWIP_CHECKSUM_ON_COPY */ - u16_t toport_chksum; -#if LWIP_NETBUF_RECVINFO - ip_addr_t toaddr; -#endif /* LWIP_NETBUF_RECVINFO */ -#endif /* LWIP_NETBUF_RECVINFO || LWIP_CHECKSUM_ON_COPY */ -}; - -/* Network buffer functions: */ -struct netbuf * netbuf_new (void); -void netbuf_delete (struct netbuf *buf); -void * netbuf_alloc (struct netbuf *buf, u16_t size); -void netbuf_free (struct netbuf *buf); -err_t netbuf_ref (struct netbuf *buf, - const void *dataptr, u16_t size); -void netbuf_chain (struct netbuf *head, struct netbuf *tail); - -err_t netbuf_data (struct netbuf *buf, - void **dataptr, u16_t *len); -s8_t netbuf_next (struct netbuf *buf); -void netbuf_first (struct netbuf *buf); - - -#define netbuf_copy_partial(buf, dataptr, len, offset) \ - pbuf_copy_partial((buf)->p, (dataptr), (len), (offset)) -#define netbuf_copy(buf,dataptr,len) netbuf_copy_partial(buf, dataptr, len, 0) -#define netbuf_take(buf, dataptr, len) pbuf_take((buf)->p, dataptr, len) -#define netbuf_len(buf) ((buf)->p->tot_len) -#define netbuf_fromaddr(buf) (&((buf)->addr)) -#define netbuf_set_fromaddr(buf, fromaddr) ip_addr_set(&((buf)->addr), fromaddr) -#define netbuf_fromport(buf) ((buf)->port) -#if LWIP_NETBUF_RECVINFO -#define netbuf_destaddr(buf) (&((buf)->toaddr)) -#define netbuf_set_destaddr(buf, destaddr) ip_addr_set(&((buf)->toaddr), destaddr) -#if LWIP_CHECKSUM_ON_COPY -#define netbuf_destport(buf) (((buf)->flags & NETBUF_FLAG_DESTADDR) ? (buf)->toport_chksum : 0) -#else /* LWIP_CHECKSUM_ON_COPY */ -#define netbuf_destport(buf) ((buf)->toport_chksum) -#endif /* LWIP_CHECKSUM_ON_COPY */ -#endif /* LWIP_NETBUF_RECVINFO */ -#if LWIP_CHECKSUM_ON_COPY -#define netbuf_set_chksum(buf, chksum) do { (buf)->flags = NETBUF_FLAG_CHKSUM; \ - (buf)->toport_chksum = chksum; } while(0) -#endif /* LWIP_CHECKSUM_ON_COPY */ - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_NETCONN || LWIP_SOCKET */ - -#endif /* LWIP_HDR_NETBUF_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/netdb.h b/third_party/lwip/repo/lwip/src/include/lwip/netdb.h deleted file mode 100644 index d3d15dfac5ad0b..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/netdb.h +++ /dev/null @@ -1,150 +0,0 @@ -/** - * @file - * NETDB API (sockets) - */ - -/* - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Simon Goldschmidt - * - */ -#ifndef LWIP_HDR_NETDB_H -#define LWIP_HDR_NETDB_H - -#include "lwip/opt.h" - -#if LWIP_DNS && LWIP_SOCKET - -#include "lwip/arch.h" -#include "lwip/inet.h" -#include "lwip/sockets.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* some rarely used options */ -#ifndef LWIP_DNS_API_DECLARE_H_ERRNO -#define LWIP_DNS_API_DECLARE_H_ERRNO 1 -#endif - -#ifndef LWIP_DNS_API_DEFINE_ERRORS -#define LWIP_DNS_API_DEFINE_ERRORS 1 -#endif - -#ifndef LWIP_DNS_API_DEFINE_FLAGS -#define LWIP_DNS_API_DEFINE_FLAGS 1 -#endif - -#ifndef LWIP_DNS_API_DECLARE_STRUCTS -#define LWIP_DNS_API_DECLARE_STRUCTS 1 -#endif - -#if LWIP_DNS_API_DEFINE_ERRORS -/** Errors used by the DNS API functions, h_errno can be one of them */ -#define EAI_NONAME 200 -#define EAI_SERVICE 201 -#define EAI_FAIL 202 -#define EAI_MEMORY 203 -#define EAI_FAMILY 204 - -#define HOST_NOT_FOUND 210 -#define NO_DATA 211 -#define NO_RECOVERY 212 -#define TRY_AGAIN 213 -#endif /* LWIP_DNS_API_DEFINE_ERRORS */ - -#if LWIP_DNS_API_DEFINE_FLAGS -/* input flags for struct addrinfo */ -#define AI_PASSIVE 0x01 -#define AI_CANONNAME 0x02 -#define AI_NUMERICHOST 0x04 -#define AI_NUMERICSERV 0x08 -#define AI_V4MAPPED 0x10 -#define AI_ALL 0x20 -#define AI_ADDRCONFIG 0x40 -#endif /* LWIP_DNS_API_DEFINE_FLAGS */ - -#if LWIP_DNS_API_DECLARE_STRUCTS -struct hostent { - char *h_name; /* Official name of the host. */ - char **h_aliases; /* A pointer to an array of pointers to alternative host names, - terminated by a null pointer. */ - int h_addrtype; /* Address type. */ - int h_length; /* The length, in bytes, of the address. */ - char **h_addr_list; /* A pointer to an array of pointers to network addresses (in - network byte order) for the host, terminated by a null pointer. */ -#define h_addr h_addr_list[0] /* for backward compatibility */ -}; - -struct addrinfo { - int ai_flags; /* Input flags. */ - int ai_family; /* Address family of socket. */ - int ai_socktype; /* Socket type. */ - int ai_protocol; /* Protocol of socket. */ - socklen_t ai_addrlen; /* Length of socket address. */ - struct sockaddr *ai_addr; /* Socket address of socket. */ - char *ai_canonname; /* Canonical name of service location. */ - struct addrinfo *ai_next; /* Pointer to next in list. */ -}; -#endif /* LWIP_DNS_API_DECLARE_STRUCTS */ - -#define NETDB_ELEM_SIZE (sizeof(struct addrinfo) + sizeof(struct sockaddr_storage) + DNS_MAX_NAME_LENGTH + 1) - -#if LWIP_DNS_API_DECLARE_H_ERRNO -/* application accessible error code set by the DNS API functions */ -extern int h_errno; -#endif /* LWIP_DNS_API_DECLARE_H_ERRNO*/ - -struct hostent *lwip_gethostbyname(const char *name); -int lwip_gethostbyname_r(const char *name, struct hostent *ret, char *buf, - size_t buflen, struct hostent **result, int *h_errnop); -void lwip_freeaddrinfo(struct addrinfo *ai); -int lwip_getaddrinfo(const char *nodename, - const char *servname, - const struct addrinfo *hints, - struct addrinfo **res); - -#if LWIP_COMPAT_SOCKETS -/** @ingroup netdbapi */ -#define gethostbyname(name) lwip_gethostbyname(name) -/** @ingroup netdbapi */ -#define gethostbyname_r(name, ret, buf, buflen, result, h_errnop) \ - lwip_gethostbyname_r(name, ret, buf, buflen, result, h_errnop) -/** @ingroup netdbapi */ -#define freeaddrinfo(addrinfo) lwip_freeaddrinfo(addrinfo) -/** @ingroup netdbapi */ -#define getaddrinfo(nodname, servname, hints, res) \ - lwip_getaddrinfo(nodname, servname, hints, res) -#endif /* LWIP_COMPAT_SOCKETS */ - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_DNS && LWIP_SOCKET */ - -#endif /* LWIP_HDR_NETDB_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/netif.h b/third_party/lwip/repo/lwip/src/include/lwip/netif.h deleted file mode 100644 index 9f4ee1ff2dee80..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/netif.h +++ /dev/null @@ -1,515 +0,0 @@ -/** - * @file - * netif API (to be used from TCPIP thread) - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_NETIF_H -#define LWIP_HDR_NETIF_H - -#include "lwip/opt.h" - -#define ENABLE_LOOPBACK (LWIP_NETIF_LOOPBACK || LWIP_HAVE_LOOPIF) - -#include "lwip/err.h" - -#include "lwip/ip_addr.h" - -#include "lwip/def.h" -#include "lwip/pbuf.h" -#include "lwip/stats.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* Throughout this file, IP addresses are expected to be in - * the same byte order as in IP_PCB. */ - -/** Must be the maximum of all used hardware address lengths - across all types of interfaces in use. - This does not have to be changed, normally. */ -#ifndef NETIF_MAX_HWADDR_LEN -#define NETIF_MAX_HWADDR_LEN 6U -#endif - -/** - * @defgroup netif_flags Flags - * @ingroup netif - * @{ - */ - -/** Whether the network interface is 'up'. This is - * a software flag used to control whether this network - * interface is enabled and processes traffic. - * It must be set by the startup code before this netif can be used - * (also for dhcp/autoip). - */ -#define NETIF_FLAG_UP 0x01U -/** If set, the netif has broadcast capability. - * Set by the netif driver in its init function. */ -#define NETIF_FLAG_BROADCAST 0x02U -/** If set, the interface has an active link - * (set by the network interface driver). - * Either set by the netif driver in its init function (if the link - * is up at that time) or at a later point once the link comes up - * (if link detection is supported by the hardware). */ -#define NETIF_FLAG_LINK_UP 0x04U -/** If set, the netif is an ethernet device using ARP. - * Set by the netif driver in its init function. - * Used to check input packet types and use of DHCP. */ -#define NETIF_FLAG_ETHARP 0x08U -/** If set, the netif is an ethernet device. It might not use - * ARP or TCP/IP if it is used for PPPoE only. - */ -#define NETIF_FLAG_ETHERNET 0x10U -/** If set, the netif has IGMP capability. - * Set by the netif driver in its init function. */ -#define NETIF_FLAG_IGMP 0x20U -/** If set, the netif has MLD6 capability. - * Set by the netif driver in its init function. */ -#define NETIF_FLAG_MLD6 0x40U - -/** - * @} - */ - -enum lwip_internal_netif_client_data_index -{ -#if LWIP_DHCP - LWIP_NETIF_CLIENT_DATA_INDEX_DHCP, -#endif -#if LWIP_AUTOIP - LWIP_NETIF_CLIENT_DATA_INDEX_AUTOIP, -#endif -#if LWIP_IGMP - LWIP_NETIF_CLIENT_DATA_INDEX_IGMP, -#endif -#if LWIP_IPV6_MLD - LWIP_NETIF_CLIENT_DATA_INDEX_MLD6, -#endif - LWIP_NETIF_CLIENT_DATA_INDEX_MAX -}; - -#if LWIP_CHECKSUM_CTRL_PER_NETIF -#define NETIF_CHECKSUM_GEN_IP 0x0001 -#define NETIF_CHECKSUM_GEN_UDP 0x0002 -#define NETIF_CHECKSUM_GEN_TCP 0x0004 -#define NETIF_CHECKSUM_GEN_ICMP 0x0008 -#define NETIF_CHECKSUM_GEN_ICMP6 0x0010 -#define NETIF_CHECKSUM_CHECK_IP 0x0100 -#define NETIF_CHECKSUM_CHECK_UDP 0x0200 -#define NETIF_CHECKSUM_CHECK_TCP 0x0400 -#define NETIF_CHECKSUM_CHECK_ICMP 0x0800 -#define NETIF_CHECKSUM_CHECK_ICMP6 0x1000 -#define NETIF_CHECKSUM_ENABLE_ALL 0xFFFF -#define NETIF_CHECKSUM_DISABLE_ALL 0x0000 -#endif /* LWIP_CHECKSUM_CTRL_PER_NETIF */ - -struct netif; - -/** MAC Filter Actions, these are passed to a netif's igmp_mac_filter or - * mld_mac_filter callback function. */ -enum netif_mac_filter_action { - /** Delete a filter entry */ - NETIF_DEL_MAC_FILTER = 0, - /** Add a filter entry */ - NETIF_ADD_MAC_FILTER = 1 -}; - -/** Function prototype for netif init functions. Set up flags and output/linkoutput - * callback functions in this function. - * - * @param netif The netif to initialize - */ -typedef err_t (*netif_init_fn)(struct netif *netif); -/** Function prototype for netif->input functions. This function is saved as 'input' - * callback function in the netif struct. Call it when a packet has been received. - * - * @param p The received packet, copied into a pbuf - * @param inp The netif which received the packet - */ -typedef err_t (*netif_input_fn)(struct pbuf *p, struct netif *inp); - -#if LWIP_IPV4 -/** Function prototype for netif->output functions. Called by lwIP when a packet - * shall be sent. For ethernet netif, set this to 'etharp_output' and set - * 'linkoutput'. - * - * @param netif The netif which shall send a packet - * @param p The packet to send (p->payload points to IP header) - * @param ipaddr The IP address to which the packet shall be sent - */ -typedef err_t (*netif_output_fn)(struct netif *netif, struct pbuf *p, - const ip4_addr_t *ipaddr); -#endif /* LWIP_IPV4*/ - -#if LWIP_IPV6 -/** Function prototype for netif->output_ip6 functions. Called by lwIP when a packet - * shall be sent. For ethernet netif, set this to 'ethip6_output' and set - * 'linkoutput'. - * - * @param netif The netif which shall send a packet - * @param p The packet to send (p->payload points to IP header) - * @param ipaddr The IPv6 address to which the packet shall be sent - */ -typedef err_t (*netif_output_ip6_fn)(struct netif *netif, struct pbuf *p, - const ip6_addr_t *ipaddr); -#endif /* LWIP_IPV6 */ - -/** Function prototype for netif->linkoutput functions. Only used for ethernet - * netifs. This function is called by ARP when a packet shall be sent. - * - * @param netif The netif which shall send a packet - * @param p The packet to send (raw ethernet packet) - */ -typedef err_t (*netif_linkoutput_fn)(struct netif *netif, struct pbuf *p); -/** Function prototype for netif status- or link-callback functions. */ -typedef void (*netif_status_callback_fn)(struct netif *netif); -#if LWIP_IPV4 && LWIP_IGMP -/** Function prototype for netif igmp_mac_filter functions */ -typedef err_t (*netif_igmp_mac_filter_fn)(struct netif *netif, - const ip4_addr_t *group, enum netif_mac_filter_action action); -#endif /* LWIP_IPV4 && LWIP_IGMP */ -#if LWIP_IPV6 && LWIP_IPV6_MLD -/** Function prototype for netif mld_mac_filter functions */ -typedef err_t (*netif_mld_mac_filter_fn)(struct netif *netif, - const ip6_addr_t *group, enum netif_mac_filter_action action); -#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */ - -#if LWIP_DHCP || LWIP_AUTOIP || LWIP_IGMP || LWIP_IPV6_MLD || (LWIP_NUM_NETIF_CLIENT_DATA > 0) -u8_t netif_alloc_client_data_id(void); -/** @ingroup netif_cd - * Set client data. Obtain ID from netif_alloc_client_data_id(). - */ -#define netif_set_client_data(netif, id, data) netif_get_client_data(netif, id) = (data) -/** @ingroup netif_cd - * Get client data. Obtain ID from netif_alloc_client_data_id(). - */ -#define netif_get_client_data(netif, id) (netif)->client_data[(id)] -#endif /* LWIP_DHCP || LWIP_AUTOIP || (LWIP_NUM_NETIF_CLIENT_DATA > 0) */ - -/** Generic data structure used for all lwIP network interfaces. - * The following fields should be filled in by the initialization - * function for the device driver: hwaddr_len, hwaddr[], mtu, flags */ -struct netif { - /** pointer to next in linked list */ - struct netif *next; - -#if LWIP_IPV4 - /** IP address configuration in network byte order */ - ip_addr_t ip_addr; - ip_addr_t netmask; - ip_addr_t gw; -#endif /* LWIP_IPV4 */ -#if LWIP_IPV6 - /** Array of IPv6 addresses for this netif. */ - ip_addr_t ip6_addr[LWIP_IPV6_NUM_ADDRESSES]; - /** The state of each IPv6 address (Tentative, Preferred, etc). - * @see ip6_addr.h */ - u8_t ip6_addr_state[LWIP_IPV6_NUM_ADDRESSES]; -#if LWIP_IPV6_ADDRESS_LIFETIMES - /** Remaining valid and preferred lifetime of each IPv6 address, in seconds. - * For valid lifetimes, the special value of IP6_ADDR_LIFE_STATIC (0) - * indicates the address is static and has no lifetimes. */ - u32_t ip6_addr_valid_life[LWIP_IPV6_NUM_ADDRESSES]; - u32_t ip6_addr_pref_life[LWIP_IPV6_NUM_ADDRESSES]; -#endif /* LWIP_IPV6_ADDRESS_LIFETIMES */ -#endif /* LWIP_IPV6 */ - /** This function is called by the network device driver - * to pass a packet up the TCP/IP stack. */ - netif_input_fn input; -#if LWIP_IPV4 - /** This function is called by the IP module when it wants - * to send a packet on the interface. This function typically - * first resolves the hardware address, then sends the packet. - * For ethernet physical layer, this is usually etharp_output() */ - netif_output_fn output; -#endif /* LWIP_IPV4 */ - /** This function is called by ethernet_output() when it wants - * to send a packet on the interface. This function outputs - * the pbuf as-is on the link medium. */ - netif_linkoutput_fn linkoutput; -#if LWIP_IPV6 - /** This function is called by the IPv6 module when it wants - * to send a packet on the interface. This function typically - * first resolves the hardware address, then sends the packet. - * For ethernet physical layer, this is usually ethip6_output() */ - netif_output_ip6_fn output_ip6; -#endif /* LWIP_IPV6 */ -#if LWIP_NETIF_STATUS_CALLBACK - /** This function is called when the netif state is set to up or down - */ - netif_status_callback_fn status_callback; -#endif /* LWIP_NETIF_STATUS_CALLBACK */ -#if LWIP_NETIF_LINK_CALLBACK - /** This function is called when the netif link is set to up or down - */ - netif_status_callback_fn link_callback; -#endif /* LWIP_NETIF_LINK_CALLBACK */ -#if LWIP_NETIF_REMOVE_CALLBACK - /** This function is called when the netif has been removed */ - netif_status_callback_fn remove_callback; -#endif /* LWIP_NETIF_REMOVE_CALLBACK */ - /** This field can be set by the device driver and could point - * to state information for the device. */ - void *state; -#ifdef netif_get_client_data - void* client_data[LWIP_NETIF_CLIENT_DATA_INDEX_MAX + LWIP_NUM_NETIF_CLIENT_DATA]; -#endif -#if LWIP_IPV6_AUTOCONFIG - /** is this netif enabled for IPv6 autoconfiguration */ - u8_t ip6_autoconfig_enabled; -#endif /* LWIP_IPV6_AUTOCONFIG */ -#if LWIP_IPV6_SEND_ROUTER_SOLICIT - /** Number of Router Solicitation messages that remain to be sent. */ - u8_t rs_count; -#endif /* LWIP_IPV6_SEND_ROUTER_SOLICIT */ -#if LWIP_NETIF_HOSTNAME - /* the hostname for this netif, NULL is a valid value */ - const char* hostname; -#endif /* LWIP_NETIF_HOSTNAME */ -#if LWIP_CHECKSUM_CTRL_PER_NETIF - u16_t chksum_flags; -#endif /* LWIP_CHECKSUM_CTRL_PER_NETIF*/ - /** maximum transfer unit (in bytes) */ - u16_t mtu; - /** number of bytes used in hwaddr */ - u8_t hwaddr_len; - /** link level hardware address of this interface */ - u8_t hwaddr[NETIF_MAX_HWADDR_LEN]; - /** flags (@see @ref netif_flags) */ - u8_t flags; -#if LWIP_MANAGEMENT_CHANNEL - u8_t using_management_channel:1; -#endif - /** descriptive abbreviation */ - char name[2]; - /** number of this interface */ - u8_t num; -#if MIB2_STATS - /** link type (from "snmp_ifType" enum from snmp_mib2.h) */ - u8_t link_type; - /** (estimate) link speed */ - u32_t link_speed; - /** timestamp at last change made (up/down) */ - u32_t ts; - /** counters */ - struct stats_mib2_netif_ctrs mib2_counters; -#endif /* MIB2_STATS */ -#if LWIP_IPV4 && LWIP_IGMP - /** This function could be called to add or delete an entry in the multicast - filter table of the ethernet MAC.*/ - netif_igmp_mac_filter_fn igmp_mac_filter; -#endif /* LWIP_IPV4 && LWIP_IGMP */ -#if LWIP_IPV6 && LWIP_IPV6_MLD - /** This function could be called to add or delete an entry in the IPv6 multicast - filter table of the ethernet MAC. */ - netif_mld_mac_filter_fn mld_mac_filter; -#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */ -#if LWIP_NETIF_HWADDRHINT - u8_t *addr_hint; -#endif /* LWIP_NETIF_HWADDRHINT */ -#if ENABLE_LOOPBACK - /* List of packets to be queued for ourselves. */ - struct pbuf *loop_first; - struct pbuf *loop_last; -#if LWIP_LOOPBACK_MAX_PBUFS - u16_t loop_cnt_current; -#endif /* LWIP_LOOPBACK_MAX_PBUFS */ -#endif /* ENABLE_LOOPBACK */ -}; - -#if LWIP_CHECKSUM_CTRL_PER_NETIF -#define NETIF_SET_CHECKSUM_CTRL(netif, chksumflags) do { \ - (netif)->chksum_flags = chksumflags; } while(0) -#define IF__NETIF_CHECKSUM_ENABLED(netif, chksumflag) if (((netif) == NULL) || (((netif)->chksum_flags & (chksumflag)) != 0)) -#else /* LWIP_CHECKSUM_CTRL_PER_NETIF */ -#define NETIF_SET_CHECKSUM_CTRL(netif, chksumflags) -#define IF__NETIF_CHECKSUM_ENABLED(netif, chksumflag) -#endif /* LWIP_CHECKSUM_CTRL_PER_NETIF */ - -/** The list of network interfaces. */ -extern struct netif *netif_list; -/** The default network interface. */ -extern struct netif *netif_default; - -void netif_init(void); - -struct ip_pcb; - -void netif_apply_pcb(struct netif *netif, struct ip_pcb *pcb); - -struct netif *netif_add(struct netif *netif, -#if LWIP_IPV4 - const ip4_addr_t *ipaddr, const ip4_addr_t *netmask, const ip4_addr_t *gw, -#endif /* LWIP_IPV4 */ - void *state, netif_init_fn init, netif_input_fn input); -#if LWIP_IPV4 -void netif_set_addr(struct netif *netif, const ip4_addr_t *ipaddr, const ip4_addr_t *netmask, - const ip4_addr_t *gw); -#endif /* LWIP_IPV4 */ -void netif_remove(struct netif * netif); - -/* Returns a network interface given its name. The name is of the form - "et0", where the first two letters are the "name" field in the - netif structure, and the digit is in the num field in the same - structure. */ -struct netif *netif_find(const char *name); - -void netif_set_default(struct netif *netif); - -#if LWIP_IPV4 -void netif_set_ipaddr(struct netif *netif, const ip4_addr_t *ipaddr); -void netif_set_netmask(struct netif *netif, const ip4_addr_t *netmask); -void netif_set_gw(struct netif *netif, const ip4_addr_t *gw); -/** @ingroup netif_ip4 */ -#define netif_ip4_addr(netif) ((const ip4_addr_t*)ip_2_ip4(&((netif)->ip_addr))) -/** @ingroup netif_ip4 */ -#define netif_ip4_netmask(netif) ((const ip4_addr_t*)ip_2_ip4(&((netif)->netmask))) -/** @ingroup netif_ip4 */ -#define netif_ip4_gw(netif) ((const ip4_addr_t*)ip_2_ip4(&((netif)->gw))) -/** @ingroup netif_ip4 */ -#define netif_ip_addr4(netif) ((const ip_addr_t*)&((netif)->ip_addr)) -/** @ingroup netif_ip4 */ -#define netif_ip_netmask4(netif) ((const ip_addr_t*)&((netif)->netmask)) -/** @ingroup netif_ip4 */ -#define netif_ip_gw4(netif) ((const ip_addr_t*)&((netif)->gw)) -#endif /* LWIP_IPV4 */ - -void netif_set_up(struct netif *netif); -void netif_set_down(struct netif *netif); -/** @ingroup netif - * Ask if an interface is up - */ -#define netif_is_up(netif) (((netif)->flags & NETIF_FLAG_UP) ? (u8_t)1 : (u8_t)0) - -#if LWIP_NETIF_STATUS_CALLBACK -void netif_set_status_callback(struct netif *netif, netif_status_callback_fn status_callback); -#endif /* LWIP_NETIF_STATUS_CALLBACK */ -#if LWIP_NETIF_REMOVE_CALLBACK -void netif_set_remove_callback(struct netif *netif, netif_status_callback_fn remove_callback); -#endif /* LWIP_NETIF_REMOVE_CALLBACK */ - -void netif_set_link_up(struct netif *netif); -void netif_set_link_down(struct netif *netif); -/** Ask if a link is up */ -#define netif_is_link_up(netif) (((netif)->flags & NETIF_FLAG_LINK_UP) ? (u8_t)1 : (u8_t)0) - -#if LWIP_NETIF_LINK_CALLBACK -void netif_set_link_callback(struct netif *netif, netif_status_callback_fn link_callback); -#endif /* LWIP_NETIF_LINK_CALLBACK */ - -#if LWIP_NETIF_HOSTNAME -/** @ingroup netif */ -#define netif_set_hostname(netif, name) do { if((netif) != NULL) { (netif)->hostname = name; }}while(0) -/** @ingroup netif */ -#define netif_get_hostname(netif) (((netif) != NULL) ? ((netif)->hostname) : NULL) -#endif /* LWIP_NETIF_HOSTNAME */ - -#if LWIP_IGMP -/** @ingroup netif */ -#define netif_set_igmp_mac_filter(netif, function) do { if((netif) != NULL) { (netif)->igmp_mac_filter = function; }}while(0) -#define netif_get_igmp_mac_filter(netif) (((netif) != NULL) ? ((netif)->igmp_mac_filter) : NULL) -#endif /* LWIP_IGMP */ - -#if LWIP_IPV6 && LWIP_IPV6_MLD -/** @ingroup netif */ -#define netif_set_mld_mac_filter(netif, function) do { if((netif) != NULL) { (netif)->mld_mac_filter = function; }}while(0) -#define netif_get_mld_mac_filter(netif) (((netif) != NULL) ? ((netif)->mld_mac_filter) : NULL) -#define netif_mld_mac_filter(netif, addr, action) do { if((netif) && (netif)->mld_mac_filter) { (netif)->mld_mac_filter((netif), (addr), (action)); }}while(0) -#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */ - -#if ENABLE_LOOPBACK -err_t netif_loop_output(struct netif *netif, struct pbuf *p); -void netif_poll(struct netif *netif); -#if !LWIP_NETIF_LOOPBACK_MULTITHREADING -void netif_poll_all(void); -#endif /* !LWIP_NETIF_LOOPBACK_MULTITHREADING */ -#endif /* ENABLE_LOOPBACK */ - -err_t netif_input(struct pbuf *p, struct netif *inp); - -#if LWIP_IPV6 -/** @ingroup netif_ip6 */ -#define netif_ip_addr6(netif, i) ((const ip_addr_t*)(&((netif)->ip6_addr[i]))) -/** @ingroup netif_ip6 */ -#define netif_ip6_addr(netif, i) ((const ip6_addr_t*)ip_2_ip6(&((netif)->ip6_addr[i]))) -void netif_ip6_addr_set(struct netif *netif, s8_t addr_idx, const ip6_addr_t *addr6); -void netif_ip6_addr_set_parts(struct netif *netif, s8_t addr_idx, u32_t i0, u32_t i1, u32_t i2, u32_t i3); -#define netif_ip6_addr_state(netif, i) ((netif)->ip6_addr_state[i]) -void netif_ip6_addr_set_state(struct netif* netif, s8_t addr_idx, u8_t state); -s8_t netif_get_ip6_addr_match(struct netif *netif, const ip6_addr_t *ip6addr); -void netif_create_ip6_linklocal_address(struct netif *netif, u8_t from_mac_48bit); -err_t netif_add_ip6_address(struct netif *netif, const ip6_addr_t *ip6addr, s8_t *chosen_idx); -err_t netif_add_ip6_address_with_route(struct netif *netif, ip6_addr_t *ip6addr, - u8_t prefix_len, s8_t *chosen_idx); -err_t netif_remove_ip6_address(struct netif *netif, ip6_addr_t *ip6addr); -err_t netif_remove_ip6_address_with_route(struct netif *netif, ip6_addr_t *ip6addr, - u8_t prefix_len); -#define netif_set_ip6_autoconfig_enabled(netif, action) do { if(netif) { (netif)->ip6_autoconfig_enabled = (action); }}while(0) -#if LWIP_IPV6_ADDRESS_LIFETIMES -#define netif_ip6_addr_valid_life(netif, i) \ - (((netif) != NULL) ? ((netif)->ip6_addr_valid_life[i]) : IP6_ADDR_LIFE_STATIC) -#define netif_ip6_addr_set_valid_life(netif, i, secs) \ - do { if (netif != NULL) { (netif)->ip6_addr_valid_life[i] = (secs); }} while (0) -#define netif_ip6_addr_pref_life(netif, i) \ - (((netif) != NULL) ? ((netif)->ip6_addr_pref_life[i]) : IP6_ADDR_LIFE_STATIC) -#define netif_ip6_addr_set_pref_life(netif, i, secs) \ - do { if (netif != NULL) { (netif)->ip6_addr_pref_life[i] = (secs); }} while (0) -#define netif_ip6_addr_isstatic(netif, i) \ - (netif_ip6_addr_valid_life((netif), (i)) == IP6_ADDR_LIFE_STATIC) -#else /* !LWIP_IPV6_ADDRESS_LIFETIMES */ -#define netif_ip6_addr_isstatic(netif, i) (1) /* all addresses are static */ -#endif /* !LWIP_IPV6_ADDRESS_LIFETIMES */ -#endif /* LWIP_IPV6 */ - -#if LWIP_NETIF_HWADDRHINT -#define NETIF_SET_HWADDRHINT(netif, hint) ((netif)->addr_hint = (hint)) -#else /* LWIP_NETIF_HWADDRHINT */ -#define NETIF_SET_HWADDRHINT(netif, hint) -#endif /* LWIP_NETIF_HWADDRHINT */ - -u8_t netif_name_to_index(const char *name); -char * netif_index_to_name(u8_t idx, char *name); -struct netif* netif_get_by_index(u8_t index); - -/* Interface indexes always start at 1 per RFC 3493, section 4, num starts at 0 */ -#define netif_get_index(netif) ((netif)->num + 1) -#define NETIF_NO_INDEX (0) - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_NETIF_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/netifapi.h b/third_party/lwip/repo/lwip/src/include/lwip/netifapi.h deleted file mode 100644 index 79369c281cf704..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/netifapi.h +++ /dev/null @@ -1,154 +0,0 @@ -/** - * @file - * netif API (to be used from non-TCPIP threads) - */ - -/* - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - */ -#ifndef LWIP_HDR_NETIFAPI_H -#define LWIP_HDR_NETIFAPI_H - -#include "lwip/opt.h" - -#if LWIP_NETIF_API /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/sys.h" -#include "lwip/netif.h" -#include "lwip/dhcp.h" -#include "lwip/autoip.h" -#include "lwip/if.h" -#include "lwip/priv/tcpip_priv.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#if LWIP_MPU_COMPATIBLE -#define NETIFAPI_IPADDR_DEF(type, m) type m -#else /* LWIP_MPU_COMPATIBLE */ -#define NETIFAPI_IPADDR_DEF(type, m) const type * m -#endif /* LWIP_MPU_COMPATIBLE */ - -typedef void (*netifapi_void_fn)(struct netif *netif); -typedef err_t (*netifapi_errt_fn)(struct netif *netif); - -struct netifapi_msg { - struct tcpip_api_call_data call; - struct netif *netif; - union { - struct { -#if LWIP_IPV4 - NETIFAPI_IPADDR_DEF(ip4_addr_t, ipaddr); - NETIFAPI_IPADDR_DEF(ip4_addr_t, netmask); - NETIFAPI_IPADDR_DEF(ip4_addr_t, gw); -#endif /* LWIP_IPV4 */ - void *state; - netif_init_fn init; - netif_input_fn input; - } add; - struct { - netifapi_void_fn voidfunc; - netifapi_errt_fn errtfunc; - } common; - struct { -#if LWIP_MPU_COMPATIBLE - char name[IF_NAMESIZE]; -#else /* LWIP_MPU_COMPATIBLE */ - char *name; -#endif /* LWIP_MPU_COMPATIBLE */ - u8_t index; - } ifs; - } msg; -}; - - -/* API for application */ -err_t netifapi_netif_add(struct netif *netif, -#if LWIP_IPV4 - const ip4_addr_t *ipaddr, const ip4_addr_t *netmask, const ip4_addr_t *gw, -#endif /* LWIP_IPV4 */ - void *state, netif_init_fn init, netif_input_fn input); - -#if LWIP_IPV4 -err_t netifapi_netif_set_addr(struct netif *netif, const ip4_addr_t *ipaddr, - const ip4_addr_t *netmask, const ip4_addr_t *gw); -#endif /* LWIP_IPV4*/ - -err_t netifapi_netif_common(struct netif *netif, netifapi_void_fn voidfunc, - netifapi_errt_fn errtfunc); - -/** @ingroup netifapi_netif */ -err_t netifapi_netif_name_to_index(const char *name, u8_t *index); -/** @ingroup netifapi_netif */ -err_t netifapi_netif_index_to_name(u8_t index, char *name); - -/** @ingroup netifapi_netif */ -#define netifapi_netif_remove(n) netifapi_netif_common(n, netif_remove, NULL) -/** @ingroup netifapi_netif */ -#define netifapi_netif_set_up(n) netifapi_netif_common(n, netif_set_up, NULL) -/** @ingroup netifapi_netif */ -#define netifapi_netif_set_down(n) netifapi_netif_common(n, netif_set_down, NULL) -/** @ingroup netifapi_netif */ -#define netifapi_netif_set_default(n) netifapi_netif_common(n, netif_set_default, NULL) -/** @ingroup netifapi_netif */ -#define netifapi_netif_set_link_up(n) netifapi_netif_common(n, netif_set_link_up, NULL) -/** @ingroup netifapi_netif */ -#define netifapi_netif_set_link_down(n) netifapi_netif_common(n, netif_set_link_down, NULL) - -/** - * @defgroup netifapi_dhcp4 DHCPv4 - * @ingroup netifapi - * To be called from non-TCPIP threads - */ -/** @ingroup netifapi_dhcp4 */ -#define netifapi_dhcp_start(n) netifapi_netif_common(n, NULL, dhcp_start) -/** @ingroup netifapi_dhcp4 */ -#define netifapi_dhcp_stop(n) netifapi_netif_common(n, dhcp_stop, NULL) -/** @ingroup netifapi_dhcp4 */ -#define netifapi_dhcp_inform(n) netifapi_netif_common(n, dhcp_inform, NULL) -/** @ingroup netifapi_dhcp4 */ -#define netifapi_dhcp_renew(n) netifapi_netif_common(n, NULL, dhcp_renew) -/** @ingroup netifapi_dhcp4 */ -#define netifapi_dhcp_release(n) netifapi_netif_common(n, NULL, dhcp_release) - -/** - * @defgroup netifapi_autoip AUTOIP - * @ingroup netifapi - * To be called from non-TCPIP threads - */ -/** @ingroup netifapi_autoip */ -#define netifapi_autoip_start(n) netifapi_netif_common(n, NULL, autoip_start) -/** @ingroup netifapi_autoip */ -#define netifapi_autoip_stop(n) netifapi_netif_common(n, NULL, autoip_stop) - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_NETIF_API */ - -#endif /* LWIP_HDR_NETIFAPI_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/opt.h b/third_party/lwip/repo/lwip/src/include/lwip/opt.h deleted file mode 100644 index 0c97ebd0cd2fa2..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/opt.h +++ /dev/null @@ -1,3014 +0,0 @@ -/** - * @file - * - * lwIP Options Configuration - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ - -/* - * NOTE: || defined __DOXYGEN__ is a workaround for doxygen bug - - * without this, doxygen does not see the actual #define - */ - -#if !defined LWIP_HDR_OPT_H -#define LWIP_HDR_OPT_H - -/* - * Include user defined options first. Anything not defined in these files - * will be set to standard values. Override anything you don't like! - */ -#include "lwipopts.h" -#include "lwip/debug.h" - -/** - * @defgroup lwip_opts Options (lwipopts.h) - * @ingroup lwip - * - * @defgroup lwip_opts_debug Debugging - * @ingroup lwip_opts - * - * @defgroup lwip_opts_infrastructure Infrastructure - * @ingroup lwip_opts - * - * @defgroup lwip_opts_callback Callback-style APIs - * @ingroup lwip_opts - * - * @defgroup lwip_opts_threadsafe_apis Thread-safe APIs - * @ingroup lwip_opts - */ - - /* - ------------------------------------ - -------------- NO SYS -------------- - ------------------------------------ -*/ -/** - * @defgroup lwip_opts_nosys NO_SYS - * @ingroup lwip_opts_infrastructure - * @{ - */ -/** - * NO_SYS==1: Use lwIP without OS-awareness (no thread, semaphores, mutexes or - * mboxes). This means threaded APIs cannot be used (socket, netconn, - * i.e. everything in the 'api' folder), only the callback-style raw API is - * available (and you have to watch out for yourself that you don't access - * lwIP functions/structures from more than one context at a time!) - */ -#if !defined NO_SYS || defined __DOXYGEN__ -#define NO_SYS 0 -#endif -/** - * @} - */ - -/** - * @defgroup lwip_opts_timers Timers - * @ingroup lwip_opts_infrastructure - * @{ - */ -/** - * LWIP_TIMERS==0: Drop support for sys_timeout and lwip-internal cyclic timers. - * (the array of lwip-internal cyclic timers is still provided) - * (check NO_SYS_NO_TIMERS for compatibility to old versions) - */ -#if !defined LWIP_TIMERS || defined __DOXYGEN__ -#ifdef NO_SYS_NO_TIMERS -#define LWIP_TIMERS (!NO_SYS || (NO_SYS && !NO_SYS_NO_TIMERS)) -#else -#define LWIP_TIMERS 1 -#endif -#endif - -/** - * LWIP_TIMERS_CUSTOM==1: Provide your own timer implementation. - * Function prototypes in timeouts.h and the array of lwip-internal cyclic timers - * are still included, but the implementation is not. The following functions - * will be required: sys_timeouts_init(), sys_timeout(), sys_untimeout(), - * sys_timeouts_mbox_fetch() - */ -#if !defined LWIP_TIMERS_CUSTOM || defined __DOXYGEN__ -#define LWIP_TIMERS_CUSTOM 0 -#endif -/** - * @} - */ - -/** - * @defgroup lwip_opts_memcpy memcpy - * @ingroup lwip_opts_infrastructure - * @{ - */ -/** - * MEMCPY: override this if you have a faster implementation at hand than the - * one included in your C library - */ -#if !defined MEMCPY || defined __DOXYGEN__ -#define MEMCPY(dst,src,len) memcpy(dst,src,len) -#endif - -/** - * SMEMCPY: override this with care! Some compilers (e.g. gcc) can inline a - * call to memcpy() if the length is known at compile time and is small. - */ -#if !defined SMEMCPY || defined __DOXYGEN__ -#define SMEMCPY(dst,src,len) memcpy(dst,src,len) -#endif -/** - * @} - */ - -/* - ------------------------------------ - ----------- Core locking ----------- - ------------------------------------ -*/ -/** - * @defgroup lwip_opts_lock Core locking and MPU - * @ingroup lwip_opts_infrastructure - * @{ - */ -/** - * LWIP_MPU_COMPATIBLE: enables special memory management mechanism - * which makes lwip able to work on MPU (Memory Protection Unit) system - * by not passing stack-pointers to other threads - * (this decreases performance as memory is allocated from pools instead - * of keeping it on the stack) - */ -#if !defined LWIP_MPU_COMPATIBLE || defined __DOXYGEN__ -#define LWIP_MPU_COMPATIBLE 0 -#endif - -/** - * LWIP_TCPIP_CORE_LOCKING - * Creates a global mutex that is held during TCPIP thread operations. - * Can be locked by client code to perform lwIP operations without changing - * into TCPIP thread using callbacks. See LOCK_TCPIP_CORE() and - * UNLOCK_TCPIP_CORE(). - * Your system should provide mutexes supporting priority inversion to use this. - */ -#if !defined LWIP_TCPIP_CORE_LOCKING || defined __DOXYGEN__ -#define LWIP_TCPIP_CORE_LOCKING 1 -#endif - -/** - * LWIP_TCPIP_CORE_LOCKING_INPUT: when LWIP_TCPIP_CORE_LOCKING is enabled, - * this lets tcpip_input() grab the mutex for input packets as well, - * instead of allocating a message and passing it to tcpip_thread. - * - * ATTENTION: this does not work when tcpip_input() is called from - * interrupt context! - */ -#if !defined LWIP_TCPIP_CORE_LOCKING_INPUT || defined __DOXYGEN__ -#define LWIP_TCPIP_CORE_LOCKING_INPUT 0 -#endif - -/** - * SYS_LIGHTWEIGHT_PROT==1: enable inter-task protection (and task-vs-interrupt - * protection) for certain critical regions during buffer allocation, deallocation - * and memory allocation and deallocation. - * ATTENTION: This is required when using lwIP from more than one context! If - * you disable this, you must be sure what you are doing! - */ -#if !defined SYS_LIGHTWEIGHT_PROT || defined __DOXYGEN__ -#define SYS_LIGHTWEIGHT_PROT 1 -#endif - -/** - * LWIP_ASSERT_CORE_LOCKED: Macro to check whether lwIP's threading/locking - * requirements are satisfied during current function call. - * This macro usually calls a function that is implemented in the OS-dependent - * sys layer and performs the following checks: - * - Not in ISR - * - If LWIP_TCPIP_CORE_LOCKING=1: TCPIP core lock is held - * - If LWIP_TCPIP_CORE_LOCKING=0: function is called from TCPIP thread - */ -#if !defined LWIP_ASSERT_CORE_LOCKED || defined __DOXYGEN__ -#define LWIP_ASSERT_CORE_LOCKED() -#endif - -/** - * Called as first thing in the lwIP TCPIP thread. Can be used in conjunction - * with LWIP_ASSERT_CORE_LOCKED to check core locking. - */ -#if !defined LWIP_MARK_TCPIP_THREAD || defined __DOXYGEN__ -#define LWIP_MARK_TCPIP_THREAD() -#endif -/** - * @} - */ - -/* - ------------------------------------ - ---------- Memory options ---------- - ------------------------------------ -*/ -/** - * @defgroup lwip_opts_mem Heap and memory pools - * @ingroup lwip_opts_infrastructure - * @{ - */ -/** - * MEM_LIBC_MALLOC==1: Use malloc/free/realloc provided by your C-library - * instead of the lwip internal allocator. Can save code size if you - * already use it. - */ -#if !defined MEM_LIBC_MALLOC || defined __DOXYGEN__ -#define MEM_LIBC_MALLOC 0 -#endif - -/** - * MEMP_MEM_MALLOC==1: Use mem_malloc/mem_free instead of the lwip pool allocator. - * Especially useful with MEM_LIBC_MALLOC but handle with care regarding execution - * speed (heap alloc can be much slower than pool alloc) and usage from interrupts - * (especially if your netif driver allocates PBUF_POOL pbufs for received frames - * from interrupt)! - * ATTENTION: Currently, this uses the heap for ALL pools (also for private pools, - * not only for internal pools defined in memp_std.h)! - */ -#if !defined MEMP_MEM_MALLOC || defined __DOXYGEN__ -#define MEMP_MEM_MALLOC 0 -#endif - -/** - * MEM_ALIGNMENT: should be set to the alignment of the CPU - * 4 byte alignment -> \#define MEM_ALIGNMENT 4 - * 2 byte alignment -> \#define MEM_ALIGNMENT 2 - */ -#if !defined MEM_ALIGNMENT || defined __DOXYGEN__ -#define MEM_ALIGNMENT 1 -#endif - -/** - * MEM_SIZE: the size of the heap memory. If the application will send - * a lot of data that needs to be copied, this should be set high. - */ -#if !defined MEM_SIZE || defined __DOXYGEN__ -#define MEM_SIZE 1600 -#endif - -/** - * MEMP_OVERFLOW_CHECK: memp overflow protection reserves a configurable - * amount of bytes before and after each memp element in every pool and fills - * it with a prominent default value. - * MEMP_OVERFLOW_CHECK == 0 no checking - * MEMP_OVERFLOW_CHECK == 1 checks each element when it is freed - * MEMP_OVERFLOW_CHECK >= 2 checks each element in every pool every time - * memp_malloc() or memp_free() is called (useful but slow!) - */ -#if !defined MEMP_OVERFLOW_CHECK || defined __DOXYGEN__ -#define MEMP_OVERFLOW_CHECK 0 -#endif - -/** - * MEMP_SANITY_CHECK==1: run a sanity check after each memp_free() to make - * sure that there are no cycles in the linked lists. - */ -#if !defined MEMP_SANITY_CHECK || defined __DOXYGEN__ -#define MEMP_SANITY_CHECK 0 -#endif - -/** - * MEM_USE_POOLS==1: Use an alternative to malloc() by allocating from a set - * of memory pools of various sizes. When mem_malloc is called, an element of - * the smallest pool that can provide the length needed is returned. - * To use this, MEMP_USE_CUSTOM_POOLS also has to be enabled. - */ -#if !defined MEM_USE_POOLS || defined __DOXYGEN__ -#define MEM_USE_POOLS 0 -#endif - -/** - * MEM_USE_POOLS_TRY_BIGGER_POOL==1: if one malloc-pool is empty, try the next - * bigger pool - WARNING: THIS MIGHT WASTE MEMORY but it can make a system more - * reliable. */ -#if !defined MEM_USE_POOLS_TRY_BIGGER_POOL || defined __DOXYGEN__ -#define MEM_USE_POOLS_TRY_BIGGER_POOL 0 -#endif - -/** - * MEMP_USE_CUSTOM_POOLS==1: whether to include a user file lwippools.h - * that defines additional pools beyond the "standard" ones required - * by lwIP. If you set this to 1, you must have lwippools.h in your - * include path somewhere. - */ -#if !defined MEMP_USE_CUSTOM_POOLS || defined __DOXYGEN__ -#define MEMP_USE_CUSTOM_POOLS 0 -#endif - -/** - * Set this to 1 if you want to free PBUF_RAM pbufs (or call mem_free()) from - * interrupt context (or another context that doesn't allow waiting for a - * semaphore). - * If set to 1, mem_malloc will be protected by a semaphore and SYS_ARCH_PROTECT, - * while mem_free will only use SYS_ARCH_PROTECT. mem_malloc SYS_ARCH_UNPROTECTs - * with each loop so that mem_free can run. - * - * ATTENTION: As you can see from the above description, this leads to dis-/ - * enabling interrupts often, which can be slow! Also, on low memory, mem_malloc - * can need longer. - * - * If you don't want that, at least for NO_SYS=0, you can still use the following - * functions to enqueue a deallocation call which then runs in the tcpip_thread - * context: - * - pbuf_free_callback(p); - * - mem_free_callback(m); - */ -#if !defined LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT || defined __DOXYGEN__ -#define LWIP_ALLOW_MEM_FREE_FROM_OTHER_CONTEXT 0 -#endif -/** - * @} - */ - -/* - ------------------------------------------------ - ---------- Internal Memory Pool Sizes ---------- - ------------------------------------------------ -*/ -/** - * @defgroup lwip_opts_memp Internal memory pools - * @ingroup lwip_opts_infrastructure - * @{ - */ -/** - * MEMP_NUM_PBUF: the number of memp struct pbufs (used for PBUF_ROM and PBUF_REF). - * If the application sends a lot of data out of ROM (or other static memory), - * this should be set high. - */ -#if !defined MEMP_NUM_PBUF || defined __DOXYGEN__ -#define MEMP_NUM_PBUF 16 -#endif - -/** - * MEMP_NUM_RAW_PCB: Number of raw connection PCBs - * (requires the LWIP_RAW option) - */ -#if !defined MEMP_NUM_RAW_PCB || defined __DOXYGEN__ -#define MEMP_NUM_RAW_PCB 4 -#endif - -/** - * MEMP_NUM_UDP_PCB: the number of UDP protocol control blocks. One - * per active UDP "connection". - * (requires the LWIP_UDP option) - */ -#if !defined MEMP_NUM_UDP_PCB || defined __DOXYGEN__ -#define MEMP_NUM_UDP_PCB 4 -#endif - -/** - * MEMP_NUM_TCP_PCB: the number of simultaneously active TCP connections. - * (requires the LWIP_TCP option) - */ -#if !defined MEMP_NUM_TCP_PCB || defined __DOXYGEN__ -#define MEMP_NUM_TCP_PCB 5 -#endif - -/** - * MEMP_NUM_TCP_PCB_LISTEN: the number of listening TCP connections. - * (requires the LWIP_TCP option) - */ -#if !defined MEMP_NUM_TCP_PCB_LISTEN || defined __DOXYGEN__ -#define MEMP_NUM_TCP_PCB_LISTEN 8 -#endif - -/** - * MEMP_NUM_TCP_SEG: the number of simultaneously queued TCP segments. - * (requires the LWIP_TCP option) - */ -#if !defined MEMP_NUM_TCP_SEG || defined __DOXYGEN__ -#define MEMP_NUM_TCP_SEG 16 -#endif - -/** - * MEMP_NUM_REASSDATA: the number of IP packets simultaneously queued for - * reassembly (whole packets, not fragments!) - */ -#if !defined MEMP_NUM_REASSDATA || defined __DOXYGEN__ -#define MEMP_NUM_REASSDATA 5 -#endif - -/** - * MEMP_NUM_FRAG_PBUF: the number of IP fragments simultaneously sent - * (fragments, not whole packets!). - * This is only used with LWIP_NETIF_TX_SINGLE_PBUF==0 and only has to be > 1 - * with DMA-enabled MACs where the packet is not yet sent when netif->output - * returns. - */ -#if !defined MEMP_NUM_FRAG_PBUF || defined __DOXYGEN__ -#define MEMP_NUM_FRAG_PBUF 15 -#endif - -/** - * MEMP_NUM_ARP_QUEUE: the number of simultaneously queued outgoing - * packets (pbufs) that are waiting for an ARP request (to resolve - * their destination address) to finish. - * (requires the ARP_QUEUEING option) - */ -#if !defined MEMP_NUM_ARP_QUEUE || defined __DOXYGEN__ -#define MEMP_NUM_ARP_QUEUE 30 -#endif - -/** - * MEMP_NUM_IGMP_GROUP: The number of multicast groups whose network interfaces - * can be members at the same time (one per netif - allsystems group -, plus one - * per netif membership). - * (requires the LWIP_IGMP option) - */ -#if !defined MEMP_NUM_IGMP_GROUP || defined __DOXYGEN__ -#define MEMP_NUM_IGMP_GROUP 8 -#endif - -/** - * MEMP_NUM_SYS_TIMEOUT: the number of simultaneously active timeouts. - * The default number of timeouts is calculated here for all enabled modules. - * The formula expects settings to be either '0' or '1'. - */ -#if !defined MEMP_NUM_SYS_TIMEOUT || defined __DOXYGEN__ -#define MEMP_NUM_SYS_TIMEOUT (LWIP_TCP + IP_REASSEMBLY + LWIP_ARP + (2*LWIP_DHCP) + LWIP_AUTOIP + LWIP_IGMP + LWIP_DNS + (PPP_SUPPORT*6*MEMP_NUM_PPP_PCB) + (LWIP_IPV6 ? (1 + LWIP_IPV6_REASS + LWIP_IPV6_MLD) : 0)) -#endif - -/** - * MEMP_NUM_NETBUF: the number of struct netbufs. - * (only needed if you use the sequential API, like api_lib.c) - */ -#if !defined MEMP_NUM_NETBUF || defined __DOXYGEN__ -#define MEMP_NUM_NETBUF 2 -#endif - -/** - * MEMP_NUM_NETCONN: the number of struct netconns. - * (only needed if you use the sequential API, like api_lib.c) - */ -#if !defined MEMP_NUM_NETCONN || defined __DOXYGEN__ -#define MEMP_NUM_NETCONN 4 -#endif - -/** - * MEMP_NUM_TCPIP_MSG_API: the number of struct tcpip_msg, which are used - * for callback/timeout API communication. - * (only needed if you use tcpip.c) - */ -#if !defined MEMP_NUM_TCPIP_MSG_API || defined __DOXYGEN__ -#define MEMP_NUM_TCPIP_MSG_API 8 -#endif - -/** - * MEMP_NUM_TCPIP_MSG_INPKT: the number of struct tcpip_msg, which are used - * for incoming packets. - * (only needed if you use tcpip.c) - */ -#if !defined MEMP_NUM_TCPIP_MSG_INPKT || defined __DOXYGEN__ -#define MEMP_NUM_TCPIP_MSG_INPKT 8 -#endif - -/** - * MEMP_NUM_NETDB: the number of concurrently running lwip_addrinfo() calls - * (before freeing the corresponding memory using lwip_freeaddrinfo()). - */ -#if !defined MEMP_NUM_NETDB || defined __DOXYGEN__ -#define MEMP_NUM_NETDB 1 -#endif - -/** - * MEMP_NUM_LOCALHOSTLIST: the number of host entries in the local host list - * if DNS_LOCAL_HOSTLIST_IS_DYNAMIC==1. - */ -#if !defined MEMP_NUM_LOCALHOSTLIST || defined __DOXYGEN__ -#define MEMP_NUM_LOCALHOSTLIST 1 -#endif - -/** - * PBUF_POOL_SIZE: the number of buffers in the pbuf pool. - */ -#if !defined PBUF_POOL_SIZE || defined __DOXYGEN__ -#define PBUF_POOL_SIZE 16 -#endif - -/** MEMP_NUM_API_MSG: the number of concurrently active calls to various - * socket, netconn, and tcpip functions - */ -#if !defined MEMP_NUM_API_MSG || defined __DOXYGEN__ -#define MEMP_NUM_API_MSG MEMP_NUM_TCPIP_MSG_API -#endif - -/** MEMP_NUM_DNS_API_MSG: the number of concurrently active calls to netconn_gethostbyname - */ -#if !defined MEMP_NUM_DNS_API_MSG || defined __DOXYGEN__ -#define MEMP_NUM_DNS_API_MSG MEMP_NUM_TCPIP_MSG_API -#endif - -/** MEMP_NUM_SOCKET_SETGETSOCKOPT_DATA: the number of concurrently active calls - * to getsockopt/setsockopt - */ -#if !defined MEMP_NUM_SOCKET_SETGETSOCKOPT_DATA || defined __DOXYGEN__ -#define MEMP_NUM_SOCKET_SETGETSOCKOPT_DATA MEMP_NUM_TCPIP_MSG_API -#endif - -/** MEMP_NUM_NETIFAPI_MSG: the number of concurrently active calls to the - * netifapi functions - */ -#if !defined MEMP_NUM_NETIFAPI_MSG || defined __DOXYGEN__ -#define MEMP_NUM_NETIFAPI_MSG MEMP_NUM_TCPIP_MSG_API -#endif -/** - * @} - */ - -/* - --------------------------------- - ---------- ARP options ---------- - --------------------------------- -*/ -/** - * @defgroup lwip_opts_arp ARP - * @ingroup lwip_opts_ipv4 - * @{ - */ -/** - * LWIP_ARP==1: Enable ARP functionality. - */ -#if !defined LWIP_ARP || defined __DOXYGEN__ -#define LWIP_ARP 1 -#endif - -/** - * ARP_TABLE_SIZE: Number of active MAC-IP address pairs cached. - */ -#if !defined ARP_TABLE_SIZE || defined __DOXYGEN__ -#define ARP_TABLE_SIZE 10 -#endif - -/** the time an ARP entry stays valid after its last update, - * for ARP_TMR_INTERVAL = 1000, this is - * (60 * 5) seconds = 5 minutes. - */ -#if !defined ARP_MAXAGE || defined __DOXYGEN__ -#define ARP_MAXAGE 300 -#endif - -/** - * ARP_QUEUEING==1: Multiple outgoing packets are queued during hardware address - * resolution. By default, only the most recent packet is queued per IP address. - * This is sufficient for most protocols and mainly reduces TCP connection - * startup time. Set this to 1 if you know your application sends more than one - * packet in a row to an IP address that is not in the ARP cache. - */ -#if !defined ARP_QUEUEING || defined __DOXYGEN__ -#define ARP_QUEUEING 0 -#endif - -/** The maximum number of packets which may be queued for each - * unresolved address by other network layers. Defaults to 3, 0 means disabled. - * Old packets are dropped, new packets are queued. - */ -#if !defined ARP_QUEUE_LEN || defined __DOXYGEN__ -#define ARP_QUEUE_LEN 3 -#endif - -/** - * ETHARP_SUPPORT_VLAN==1: support receiving and sending ethernet packets with - * VLAN header. See the description of LWIP_HOOK_VLAN_CHECK and - * LWIP_HOOK_VLAN_SET hooks to check/set VLAN headers. - * Additionally, you can define ETHARP_VLAN_CHECK to an u16_t VLAN ID to check. - * If ETHARP_VLAN_CHECK is defined, only VLAN-traffic for this VLAN is accepted. - * If ETHARP_VLAN_CHECK is not defined, all traffic is accepted. - * Alternatively, define a function/define ETHARP_VLAN_CHECK_FN(eth_hdr, vlan) - * that returns 1 to accept a packet or 0 to drop a packet. - */ -#if !defined ETHARP_SUPPORT_VLAN || defined __DOXYGEN__ -#define ETHARP_SUPPORT_VLAN 0 -#endif - -/** LWIP_ETHERNET==1: enable ethernet support even though ARP might be disabled - */ -#if !defined LWIP_ETHERNET || defined __DOXYGEN__ -#define LWIP_ETHERNET LWIP_ARP -#endif - -/** ETH_PAD_SIZE: number of bytes added before the ethernet header to ensure - * alignment of payload after that header. Since the header is 14 bytes long, - * without this padding e.g. addresses in the IP header will not be aligned - * on a 32-bit boundary, so setting this to 2 can speed up 32-bit-platforms. - */ -#if !defined ETH_PAD_SIZE || defined __DOXYGEN__ -#define ETH_PAD_SIZE 0 -#endif - -/** ETHARP_SUPPORT_STATIC_ENTRIES==1: enable code to support static ARP table - * entries (using etharp_add_static_entry/etharp_remove_static_entry). - */ -#if !defined ETHARP_SUPPORT_STATIC_ENTRIES || defined __DOXYGEN__ -#define ETHARP_SUPPORT_STATIC_ENTRIES 0 -#endif - -/** ETHARP_TABLE_MATCH_NETIF==1: Match netif for ARP table entries. - * If disabled, duplicate IP address on multiple netifs are not supported - * (but this should only occur for AutoIP). - */ -#if !defined ETHARP_TABLE_MATCH_NETIF || defined __DOXYGEN__ -#define ETHARP_TABLE_MATCH_NETIF 0 -#endif -/** - * @} - */ - -/* - -------------------------------- - ---------- IP options ---------- - -------------------------------- -*/ -/** - * @defgroup lwip_opts_ipv4 IPv4 - * @ingroup lwip_opts - * @{ - */ -/** - * LWIP_IPV4==1: Enable IPv4 - */ -#if !defined LWIP_IPV4 || defined __DOXYGEN__ -#define LWIP_IPV4 1 -#endif - -/** - * IP_FORWARD==1: Enables the ability to forward IP packets across network - * interfaces. If you are going to run lwIP on a device with only one network - * interface, define this to 0. - */ -#if !defined IP_FORWARD || defined __DOXYGEN__ -#define IP_FORWARD 0 -#endif - -/** - * IP_REASSEMBLY==1: Reassemble incoming fragmented IP packets. Note that - * this option does not affect outgoing packet sizes, which can be controlled - * via IP_FRAG. - */ -#if !defined IP_REASSEMBLY || defined __DOXYGEN__ -#define IP_REASSEMBLY 1 -#endif - -/** - * IP_FRAG==1: Fragment outgoing IP packets if their size exceeds MTU. Note - * that this option does not affect incoming packet sizes, which can be - * controlled via IP_REASSEMBLY. - */ -#if !defined IP_FRAG || defined __DOXYGEN__ -#define IP_FRAG 1 -#endif - -#if !LWIP_IPV4 -/* disable IPv4 extensions when IPv4 is disabled */ -#undef IP_FORWARD -#define IP_FORWARD 0 -#undef IP_REASSEMBLY -#define IP_REASSEMBLY 0 -#undef IP_FRAG -#define IP_FRAG 0 -#endif /* !LWIP_IPV4 */ - -/** - * IP_OPTIONS_ALLOWED: Defines the behavior for IP options. - * IP_OPTIONS_ALLOWED==0: All packets with IP options are dropped. - * IP_OPTIONS_ALLOWED==1: IP options are allowed (but not parsed). - */ -#if !defined IP_OPTIONS_ALLOWED || defined __DOXYGEN__ -#define IP_OPTIONS_ALLOWED 1 -#endif - -/** - * IP_REASS_MAXAGE: Maximum time (in multiples of IP_TMR_INTERVAL - so seconds, normally) - * a fragmented IP packet waits for all fragments to arrive. If not all fragments arrived - * in this time, the whole packet is discarded. - */ -#if !defined IP_REASS_MAXAGE || defined __DOXYGEN__ -#define IP_REASS_MAXAGE 3 -#endif - -/** - * IP_REASS_MAX_PBUFS: Total maximum amount of pbufs waiting to be reassembled. - * Since the received pbufs are enqueued, be sure to configure - * PBUF_POOL_SIZE > IP_REASS_MAX_PBUFS so that the stack is still able to receive - * packets even if the maximum amount of fragments is enqueued for reassembly! - */ -#if !defined IP_REASS_MAX_PBUFS || defined __DOXYGEN__ -#define IP_REASS_MAX_PBUFS 10 -#endif - -/** - * IP_DEFAULT_TTL: Default value for Time-To-Live used by transport layers. - */ -#if !defined IP_DEFAULT_TTL || defined __DOXYGEN__ -#define IP_DEFAULT_TTL 255 -#endif - -/** - * IP_SOF_BROADCAST=1: Use the SOF_BROADCAST field to enable broadcast - * filter per pcb on udp and raw send operations. To enable broadcast filter - * on recv operations, you also have to set IP_SOF_BROADCAST_RECV=1. - */ -#if !defined IP_SOF_BROADCAST || defined __DOXYGEN__ -#define IP_SOF_BROADCAST 0 -#endif - -/** - * IP_SOF_BROADCAST_RECV (requires IP_SOF_BROADCAST=1) enable the broadcast - * filter on recv operations. - */ -#if !defined IP_SOF_BROADCAST_RECV || defined __DOXYGEN__ -#define IP_SOF_BROADCAST_RECV 0 -#endif - -/** - * IP_FORWARD_ALLOW_TX_ON_RX_NETIF==1: allow ip_forward() to send packets back - * out on the netif where it was received. This should only be used for - * wireless networks. - * ATTENTION: When this is 1, make sure your netif driver correctly marks incoming - * link-layer-broadcast/multicast packets as such using the corresponding pbuf flags! - */ -#if !defined IP_FORWARD_ALLOW_TX_ON_RX_NETIF || defined __DOXYGEN__ -#define IP_FORWARD_ALLOW_TX_ON_RX_NETIF 0 -#endif - -/** - * LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS==1: randomize the local port for the first - * local TCP/UDP pcb (default==0). This can prevent creating predictable port - * numbers after booting a device. - */ -#if !defined LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS || defined __DOXYGEN__ -#define LWIP_RANDOMIZE_INITIAL_LOCAL_PORTS 0 -#endif -/** - * @} - */ - -/* - ---------------------------------- - ---------- ICMP options ---------- - ---------------------------------- -*/ -/** - * @defgroup lwip_opts_icmp ICMP - * @ingroup lwip_opts_ipv4 - * @{ - */ -/** - * LWIP_ICMP==1: Enable ICMP module inside the IP stack. - * Be careful, disable that make your product non-compliant to RFC1122 - */ -#if !defined LWIP_ICMP || defined __DOXYGEN__ -#define LWIP_ICMP 1 -#endif - -/** - * ICMP_TTL: Default value for Time-To-Live used by ICMP packets. - */ -#if !defined ICMP_TTL || defined __DOXYGEN__ -#define ICMP_TTL (IP_DEFAULT_TTL) -#endif - -/** - * LWIP_BROADCAST_PING==1: respond to broadcast pings (default is unicast only) - */ -#if !defined LWIP_BROADCAST_PING || defined __DOXYGEN__ -#define LWIP_BROADCAST_PING 0 -#endif - -/** - * LWIP_MULTICAST_PING==1: respond to multicast pings (default is unicast only) - */ -#if !defined LWIP_MULTICAST_PING || defined __DOXYGEN__ -#define LWIP_MULTICAST_PING 0 -#endif -/** - * @} - */ - -/* - --------------------------------- - ---------- RAW options ---------- - --------------------------------- -*/ -/** - * @defgroup lwip_opts_raw RAW - * @ingroup lwip_opts_callback - * @{ - */ -/** - * LWIP_RAW==1: Enable application layer to hook into the IP layer itself. - */ -#if !defined LWIP_RAW || defined __DOXYGEN__ -#define LWIP_RAW 0 -#endif - -/** - * LWIP_RAW==1: Enable application layer to hook into the IP layer itself. - */ -#if !defined RAW_TTL || defined __DOXYGEN__ -#define RAW_TTL (IP_DEFAULT_TTL) -#endif -/** - * @} - */ - -/* - ---------------------------------- - ---------- DHCP options ---------- - ---------------------------------- -*/ -/** - * @defgroup lwip_opts_dhcp DHCP - * @ingroup lwip_opts_ipv4 - * @{ - */ -/** - * LWIP_DHCP==1: Enable DHCP module. - */ -#if !defined LWIP_DHCP || defined __DOXYGEN__ -#define LWIP_DHCP 0 -#endif -#if !LWIP_IPV4 -/* disable DHCP when IPv4 is disabled */ -#undef LWIP_DHCP -#define LWIP_DHCP 0 -#endif /* !LWIP_IPV4 */ - -/** - * DHCP_DOES_ARP_CHECK==1: Do an ARP check on the offered address. - */ -#if !defined DHCP_DOES_ARP_CHECK || defined __DOXYGEN__ -#define DHCP_DOES_ARP_CHECK ((LWIP_DHCP) && (LWIP_ARP)) -#endif - -/** - * LWIP_DHCP_CHECK_LINK_UP==1: dhcp_start() only really starts if the netif has - * NETIF_FLAG_LINK_UP set in its flags. As this is only an optimization and - * netif drivers might not set this flag, the default is off. If enabled, - * netif_set_link_up() must be called to continue dhcp starting. - */ -#if !defined LWIP_DHCP_CHECK_LINK_UP -#define LWIP_DHCP_CHECK_LINK_UP 0 -#endif - -/** - * LWIP_DHCP_BOOTP_FILE==1: Store offered_si_addr and boot_file_name. - */ -#if !defined LWIP_DHCP_BOOTP_FILE || defined __DOXYGEN__ -#define LWIP_DHCP_BOOTP_FILE 0 -#endif - -/** - * LWIP_DHCP_GETS_NTP==1: Request NTP servers with discover/select. For each - * response packet, an callback is called, which has to be provided by the port: - * void dhcp_set_ntp_servers(u8_t num_ntp_servers, ip_addr_t* ntp_server_addrs); -*/ -#if !defined LWIP_DHCP_GET_NTP_SRV || defined __DOXYGEN__ -#define LWIP_DHCP_GET_NTP_SRV 0 -#endif - -/** - * The maximum of NTP servers requested - */ -#if !defined LWIP_DHCP_MAX_NTP_SERVERS || defined __DOXYGEN__ -#define LWIP_DHCP_MAX_NTP_SERVERS 1 -#endif - -/** - * LWIP_DHCP_MAX_DNS_SERVERS > 0: Request DNS servers with discover/select. - * DHCP servers received in the response are passed to DNS via @ref dns_setserver() - * (up to the maximum limit defined here). - */ -#if !defined LWIP_DHCP_MAX_DNS_SERVERS || defined __DOXYGEN__ -#define LWIP_DHCP_MAX_DNS_SERVERS DNS_MAX_SERVERS -#endif -/** - * @} - */ - -/* - ------------------------------------ - ---------- AUTOIP options ---------- - ------------------------------------ -*/ -/** - * @defgroup lwip_opts_autoip AUTOIP - * @ingroup lwip_opts_ipv4 - * @{ - */ -/** - * LWIP_AUTOIP==1: Enable AUTOIP module. - */ -#if !defined LWIP_AUTOIP || defined __DOXYGEN__ -#define LWIP_AUTOIP 0 -#endif -#if !LWIP_IPV4 -/* disable AUTOIP when IPv4 is disabled */ -#undef LWIP_AUTOIP -#define LWIP_AUTOIP 0 -#endif /* !LWIP_IPV4 */ - -/** - * LWIP_DHCP_AUTOIP_COOP==1: Allow DHCP and AUTOIP to be both enabled on - * the same interface at the same time. - */ -#if !defined LWIP_DHCP_AUTOIP_COOP || defined __DOXYGEN__ -#define LWIP_DHCP_AUTOIP_COOP 0 -#endif - -/** - * LWIP_DHCP_AUTOIP_COOP_TRIES: Set to the number of DHCP DISCOVER probes - * that should be sent before falling back on AUTOIP (the DHCP client keeps - * running in this case). This can be set as low as 1 to get an AutoIP address - * very quickly, but you should be prepared to handle a changing IP address - * when DHCP overrides AutoIP. - */ -#if !defined LWIP_DHCP_AUTOIP_COOP_TRIES || defined __DOXYGEN__ -#define LWIP_DHCP_AUTOIP_COOP_TRIES 9 -#endif -/** - * @} - */ - -/* - ---------------------------------- - ----- SNMP MIB2 support ----- - ---------------------------------- -*/ -/** - * @defgroup lwip_opts_mib2 SNMP MIB2 callbacks - * @ingroup lwip_opts_infrastructure - * @{ - */ -/** - * LWIP_MIB2_CALLBACKS==1: Turn on SNMP MIB2 callbacks. - * Turn this on to get callbacks needed to implement MIB2. - * Usually MIB2_STATS should be enabled, too. - */ -#if !defined LWIP_MIB2_CALLBACKS || defined __DOXYGEN__ -#define LWIP_MIB2_CALLBACKS 0 -#endif -/** - * @} - */ - -/* - ---------------------------------- - -------- Multicast options ------- - ---------------------------------- -*/ -/** - * @defgroup lwip_opts_multicast Multicast - * @ingroup lwip_opts_infrastructure - * @{ - */ -/** - * LWIP_MULTICAST_TX_OPTIONS==1: Enable multicast TX support like the socket options - * IP_MULTICAST_TTL/IP_MULTICAST_IF/IP_MULTICAST_LOOP, as well as (currently only) - * core support for the corresponding IPv6 options. - */ -#if !defined LWIP_MULTICAST_TX_OPTIONS || defined __DOXYGEN__ -#define LWIP_MULTICAST_TX_OPTIONS ((LWIP_IGMP || LWIP_IPV6_MLD) && (LWIP_UDP || LWIP_RAW)) -#endif -/** - * @} - */ - -/* - ---------------------------------- - ---------- IGMP options ---------- - ---------------------------------- -*/ -/** - * @defgroup lwip_opts_igmp IGMP - * @ingroup lwip_opts_ipv4 - * @{ - */ -/** - * LWIP_IGMP==1: Turn on IGMP module. - */ -#if !defined LWIP_IGMP || defined __DOXYGEN__ -#define LWIP_IGMP 0 -#endif -#if !LWIP_IPV4 -#undef LWIP_IGMP -#define LWIP_IGMP 0 -#endif -/** - * @} - */ - -/* - ---------------------------------- - ---------- DNS options ----------- - ---------------------------------- -*/ -/** - * @defgroup lwip_opts_dns DNS - * @ingroup lwip_opts_callback - * @{ - */ -/** - * LWIP_DNS==1: Turn on DNS module. UDP must be available for DNS - * transport. - */ -#if !defined LWIP_DNS || defined __DOXYGEN__ -#define LWIP_DNS 0 -#endif - -/** - * LWIP_DNS_RAND_ID==1: Runs on the fix for CVE-2014-4883 - * Randomizes the id of dns requests. - * This should be on for security purposes - */ -#ifndef LWIP_DNS_RAND_ID -#define LWIP_DNS_RAND_ID 1 -#endif - -/** DNS maximum number of entries to maintain locally. */ -#if !defined DNS_TABLE_SIZE || defined __DOXYGEN__ -#define DNS_TABLE_SIZE 4 -#endif - -/** DNS maximum host name length supported in the name table. */ -#if !defined DNS_MAX_NAME_LENGTH || defined __DOXYGEN__ -#define DNS_MAX_NAME_LENGTH 256 -#endif - -/** The maximum of DNS servers - * The first server can be initialized automatically by defining - * DNS_SERVER_ADDRESS(ipaddr), where 'ipaddr' is an 'ip_addr_t*' - */ -#if !defined DNS_MAX_SERVERS || defined __DOXYGEN__ -#define DNS_MAX_SERVERS 2 -#endif - -/** DNS do a name checking between the query and the response. */ -#if !defined DNS_DOES_NAME_CHECK || defined __DOXYGEN__ -#define DNS_DOES_NAME_CHECK 1 -#endif - -/** LWIP_DNS_SECURE: controls the security level of the DNS implementation - * Use all DNS security features by default. - * This is overridable but should only be needed by very small targets - * or when using against non standard DNS servers. */ -#if !defined LWIP_DNS_SECURE || defined __DOXYGEN__ -#define LWIP_DNS_SECURE (LWIP_DNS_SECURE_RAND_XID | LWIP_DNS_SECURE_NO_MULTIPLE_OUTSTANDING | LWIP_DNS_SECURE_RAND_SRC_PORT) -#endif - -/* A list of DNS security features follows */ -#define LWIP_DNS_SECURE_RAND_XID 1 -#define LWIP_DNS_SECURE_NO_MULTIPLE_OUTSTANDING 2 -#define LWIP_DNS_SECURE_RAND_SRC_PORT 4 - -/** DNS_LOCAL_HOSTLIST: Implements a local host-to-address list. If enabled, you have to define an initializer: - * \#define DNS_LOCAL_HOSTLIST_INIT {DNS_LOCAL_HOSTLIST_ELEM("host_ip4", IPADDR4_INIT_BYTES(1,2,3,4)), \ - * DNS_LOCAL_HOSTLIST_ELEM("host_ip6", IPADDR6_INIT_HOST(123, 234, 345, 456)} - * - * Instead, you can also use an external function: - * \#define DNS_LOOKUP_LOCAL_EXTERN(x) extern err_t my_lookup_function(const char *name, ip_addr_t *addr, u8_t dns_addrtype) - * that looks up the IP address and returns ERR_OK if found (LWIP_DNS_ADDRTYPE_xxx is passed in dns_addrtype). - */ -#if !defined DNS_LOCAL_HOSTLIST || defined __DOXYGEN__ -#define DNS_LOCAL_HOSTLIST 0 -#endif /* DNS_LOCAL_HOSTLIST */ - -/** If this is turned on, the local host-list can be dynamically changed - * at runtime. */ -#if !defined DNS_LOCAL_HOSTLIST_IS_DYNAMIC || defined __DOXYGEN__ -#define DNS_LOCAL_HOSTLIST_IS_DYNAMIC 0 -#endif /* DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ - -/** Set this to 1 to enable querying ".local" names via mDNS - * using a One-Shot Multicast DNS Query */ -#if !defined LWIP_DNS_SUPPORT_MDNS_QUERIES || defined __DOXYGEN__ -#define LWIP_DNS_SUPPORT_MDNS_QUERIES 0 -#endif - -/** DNS message max. size. Default value is RFC compliant. */ -#ifndef DNS_MSG_SIZE -#define DNS_MSG_SIZE 512 -#endif - -/** DNS maximum addresses per host name supported in the name table. */ -#if !defined DNS_MAX_ADDRS_PER_NAME || defined __DOXYGEN__ -#define DNS_MAX_ADDRS_PER_NAME 4 -#endif -/** - * @} - */ - -/* - --------------------------------- - ---------- UDP options ---------- - --------------------------------- -*/ -/** - * @defgroup lwip_opts_udp UDP - * @ingroup lwip_opts_callback - * @{ - */ -/** - * LWIP_UDP==1: Turn on UDP. - */ -#if !defined LWIP_UDP || defined __DOXYGEN__ -#define LWIP_UDP 1 -#endif - -/** - * LWIP_UDPLITE==1: Turn on UDP-Lite. (Requires LWIP_UDP) - */ -#if !defined LWIP_UDPLITE || defined __DOXYGEN__ -#define LWIP_UDPLITE 0 -#endif - -/** - * UDP_TTL: Default Time-To-Live value. - */ -#if !defined UDP_TTL || defined __DOXYGEN__ -#define UDP_TTL (IP_DEFAULT_TTL) -#endif - -/** - * LWIP_NETBUF_RECVINFO==1: append destination addr and port to every netbuf. - */ -#if !defined LWIP_NETBUF_RECVINFO || defined __DOXYGEN__ -#define LWIP_NETBUF_RECVINFO 0 -#endif -/** - * @} - */ - -/* - --------------------------------- - ---------- TCP options ---------- - --------------------------------- -*/ -/** - * @defgroup lwip_opts_tcp TCP - * @ingroup lwip_opts_callback - * @{ - */ -/** - * LWIP_TCP==1: Turn on TCP. - */ -#if !defined LWIP_TCP || defined __DOXYGEN__ -#define LWIP_TCP 1 -#endif - -/** - * TCP_TTL: Default Time-To-Live value. - */ -#if !defined TCP_TTL || defined __DOXYGEN__ -#define TCP_TTL (IP_DEFAULT_TTL) -#endif - -/** - * TCP_WND: The size of a TCP window. This must be at least - * (2 * TCP_MSS) for things to work well. - * ATTENTION: when using TCP_RCV_SCALE, TCP_WND is the total size - * with scaling applied. Maximum window value in the TCP header - * will be TCP_WND >> TCP_RCV_SCALE - */ -#if !defined TCP_WND || defined __DOXYGEN__ -#define TCP_WND (4 * TCP_MSS) -#endif - -/** - * TCP_MAXRTX: Maximum number of retransmissions of data segments. - */ -#if !defined TCP_MAXRTX || defined __DOXYGEN__ -#define TCP_MAXRTX 12 -#endif - -/** - * TCP_SYNMAXRTX: Maximum number of retransmissions of SYN segments. - */ -#if !defined TCP_SYNMAXRTX || defined __DOXYGEN__ -#define TCP_SYNMAXRTX 6 -#endif - -/** - * TCP_QUEUE_OOSEQ==1: TCP will queue segments that arrive out of order. - * Define to 0 if your device is low on memory. - */ -#if !defined TCP_QUEUE_OOSEQ || defined __DOXYGEN__ -#define TCP_QUEUE_OOSEQ (LWIP_TCP) -#endif - -/** - * TCP_MSS: TCP Maximum segment size. (default is 536, a conservative default, - * you might want to increase this.) - * For the receive side, this MSS is advertised to the remote side - * when opening a connection. For the transmit size, this MSS sets - * an upper limit on the MSS advertised by the remote host. - */ -#if !defined TCP_MSS || defined __DOXYGEN__ -#define TCP_MSS 536 -#endif - -/** - * TCP_CALCULATE_EFF_SEND_MSS: "The maximum size of a segment that TCP really - * sends, the 'effective send MSS,' MUST be the smaller of the send MSS (which - * reflects the available reassembly buffer size at the remote host) and the - * largest size permitted by the IP layer" (RFC 1122) - * Setting this to 1 enables code that checks TCP_MSS against the MTU of the - * netif used for a connection and limits the MSS if it would be too big otherwise. - */ -#if !defined TCP_CALCULATE_EFF_SEND_MSS || defined __DOXYGEN__ -#define TCP_CALCULATE_EFF_SEND_MSS 1 -#endif - - -/** - * TCP_SND_BUF: TCP sender buffer space (bytes). - * To achieve good performance, this should be at least 2 * TCP_MSS. - */ -#if !defined TCP_SND_BUF || defined __DOXYGEN__ -#define TCP_SND_BUF (2 * TCP_MSS) -#endif - -/** - * TCP_SND_QUEUELEN: TCP sender buffer space (pbufs). This must be at least - * as much as (2 * TCP_SND_BUF/TCP_MSS) for things to work. - */ -#if !defined TCP_SND_QUEUELEN || defined __DOXYGEN__ -#define TCP_SND_QUEUELEN ((4 * (TCP_SND_BUF) + (TCP_MSS - 1))/(TCP_MSS)) -#endif - -/** - * TCP_SNDLOWAT: TCP writable space (bytes). This must be less than - * TCP_SND_BUF. It is the amount of space which must be available in the - * TCP snd_buf for select to return writable (combined with TCP_SNDQUEUELOWAT). - */ -#if !defined TCP_SNDLOWAT || defined __DOXYGEN__ -#define TCP_SNDLOWAT LWIP_MIN(LWIP_MAX(((TCP_SND_BUF)/2), (2 * TCP_MSS) + 1), (TCP_SND_BUF) - 1) -#endif - -/** - * TCP_SNDQUEUELOWAT: TCP writable bufs (pbuf count). This must be less - * than TCP_SND_QUEUELEN. If the number of pbufs queued on a pcb drops below - * this number, select returns writable (combined with TCP_SNDLOWAT). - */ -#if !defined TCP_SNDQUEUELOWAT || defined __DOXYGEN__ -#define TCP_SNDQUEUELOWAT LWIP_MAX(((TCP_SND_QUEUELEN)/2), 5) -#endif - -/** - * TCP_OOSEQ_MAX_BYTES: The maximum number of bytes queued on ooseq per pcb. - * Default is 0 (no limit). Only valid for TCP_QUEUE_OOSEQ==1. - */ -#if !defined TCP_OOSEQ_MAX_BYTES || defined __DOXYGEN__ -#define TCP_OOSEQ_MAX_BYTES 0 -#endif - -/** - * TCP_OOSEQ_MAX_PBUFS: The maximum number of pbufs queued on ooseq per pcb. - * Default is 0 (no limit). Only valid for TCP_QUEUE_OOSEQ==1. - */ -#if !defined TCP_OOSEQ_MAX_PBUFS || defined __DOXYGEN__ -#define TCP_OOSEQ_MAX_PBUFS 0 -#endif - -/** - * TCP_LISTEN_BACKLOG: Enable the backlog option for tcp listen pcb. - */ -#if !defined TCP_LISTEN_BACKLOG || defined __DOXYGEN__ -#define TCP_LISTEN_BACKLOG 0 -#endif - -/** - * The maximum allowed backlog for TCP listen netconns. - * This backlog is used unless another is explicitly specified. - * 0xff is the maximum (u8_t). - */ -#if !defined TCP_DEFAULT_LISTEN_BACKLOG || defined __DOXYGEN__ -#define TCP_DEFAULT_LISTEN_BACKLOG 0xff -#endif - -/** - * TCP_OVERSIZE: The maximum number of bytes that tcp_write may - * allocate ahead of time in an attempt to create shorter pbuf chains - * for transmission. The meaningful range is 0 to TCP_MSS. Some - * suggested values are: - * - * 0: Disable oversized allocation. Each tcp_write() allocates a new - pbuf (old behaviour). - * 1: Allocate size-aligned pbufs with minimal excess. Use this if your - * scatter-gather DMA requires aligned fragments. - * 128: Limit the pbuf/memory overhead to 20%. - * TCP_MSS: Try to create unfragmented TCP packets. - * TCP_MSS/4: Try to create 4 fragments or less per TCP packet. - */ -#if !defined TCP_OVERSIZE || defined __DOXYGEN__ -#define TCP_OVERSIZE TCP_MSS -#endif - -/** - * LWIP_TCP_TIMESTAMPS==1: support the TCP timestamp option. - * The timestamp option is currently only used to help remote hosts, it is not - * really used locally. Therefore, it is only enabled when a TS option is - * received in the initial SYN packet from a remote host. - */ -#if !defined LWIP_TCP_TIMESTAMPS || defined __DOXYGEN__ -#define LWIP_TCP_TIMESTAMPS 0 -#endif - -/** - * TCP_WND_UPDATE_THRESHOLD: difference in window to trigger an - * explicit window update - */ -#if !defined TCP_WND_UPDATE_THRESHOLD || defined __DOXYGEN__ -#define TCP_WND_UPDATE_THRESHOLD LWIP_MIN((TCP_WND / 4), (TCP_MSS * 4)) -#endif - -/** - * LWIP_EVENT_API and LWIP_CALLBACK_API: Only one of these should be set to 1. - * LWIP_EVENT_API==1: The user defines lwip_tcp_event() to receive all - * events (accept, sent, etc) that happen in the system. - * LWIP_CALLBACK_API==1: The PCB callback function is called directly - * for the event. This is the default. - */ -#if !defined(LWIP_EVENT_API) && !defined(LWIP_CALLBACK_API) || defined __DOXYGEN__ -#define LWIP_EVENT_API 0 -#define LWIP_CALLBACK_API 1 -#else -#ifndef LWIP_EVENT_API -#define LWIP_EVENT_API 0 -#endif -#ifndef LWIP_CALLBACK_API -#define LWIP_CALLBACK_API 0 -#endif -#endif - -/** - * LWIP_WND_SCALE and TCP_RCV_SCALE: - * Set LWIP_WND_SCALE to 1 to enable window scaling. - * Set TCP_RCV_SCALE to the desired scaling factor (shift count in the - * range of [0..14]). - * When LWIP_WND_SCALE is enabled but TCP_RCV_SCALE is 0, we can use a large - * send window while having a small receive window only. - */ -#if !defined LWIP_WND_SCALE || defined __DOXYGEN__ -#define LWIP_WND_SCALE 0 -#define TCP_RCV_SCALE 0 -#endif -/** - * @} - */ - -/* - ---------------------------------- - ---------- Pbuf options ---------- - ---------------------------------- -*/ -/** - * @defgroup lwip_opts_pbuf PBUF - * @ingroup lwip_opts - * @{ - */ -/** - * PBUF_LINK_HLEN: the number of bytes that should be allocated for a - * link level header. The default is 14, the standard value for - * Ethernet. - */ -#if !defined PBUF_LINK_HLEN || defined __DOXYGEN__ -#if defined LWIP_HOOK_VLAN_SET && !defined __DOXYGEN__ -#define PBUF_LINK_HLEN (18 + ETH_PAD_SIZE) -#else /* LWIP_HOOK_VLAN_SET */ -#define PBUF_LINK_HLEN (14 + ETH_PAD_SIZE) -#endif /* LWIP_HOOK_VLAN_SET */ -#endif - -/** - * PBUF_LINK_ENCAPSULATION_HLEN: the number of bytes that should be allocated - * for an additional encapsulation header before ethernet headers (e.g. 802.11) - */ -#if !defined PBUF_LINK_ENCAPSULATION_HLEN || defined __DOXYGEN__ -#define PBUF_LINK_ENCAPSULATION_HLEN 0u -#endif - -/** - * PBUF_POOL_BUFSIZE: the size of each pbuf in the pbuf pool. The default is - * designed to accommodate single full size TCP frame in one pbuf, including - * TCP_MSS, IP header, and link header. - */ -#if !defined PBUF_POOL_BUFSIZE || defined __DOXYGEN__ -#define PBUF_POOL_BUFSIZE LWIP_MEM_ALIGN_SIZE(TCP_MSS+40+PBUF_LINK_ENCAPSULATION_HLEN+PBUF_LINK_HLEN) -#endif -/** - * @} - */ - -/* - ------------------------------------------------ - ---------- Network Interfaces options ---------- - ------------------------------------------------ -*/ -/** - * @defgroup lwip_opts_netif NETIF - * @ingroup lwip_opts - * @{ - */ -/** - * LWIP_NETIF_HOSTNAME==1: use DHCP_OPTION_HOSTNAME with netif's hostname - * field. - */ -#if !defined LWIP_NETIF_HOSTNAME || defined __DOXYGEN__ -#define LWIP_NETIF_HOSTNAME 0 -#endif - -/** - * LWIP_NETIF_API==1: Support netif api (in netifapi.c) - */ -#if !defined LWIP_NETIF_API || defined __DOXYGEN__ -#define LWIP_NETIF_API 0 -#endif - -/** - * LWIP_NETIF_STATUS_CALLBACK==1: Support a callback function whenever an interface - * changes its up/down status (i.e., due to DHCP IP acquisition) - */ -#if !defined LWIP_NETIF_STATUS_CALLBACK || defined __DOXYGEN__ -#define LWIP_NETIF_STATUS_CALLBACK 0 -#endif - -/** - * LWIP_NETIF_LINK_CALLBACK==1: Support a callback function from an interface - * whenever the link changes (i.e., link down) - */ -#if !defined LWIP_NETIF_LINK_CALLBACK || defined __DOXYGEN__ -#define LWIP_NETIF_LINK_CALLBACK 0 -#endif - -/** - * LWIP_NETIF_REMOVE_CALLBACK==1: Support a callback function that is called - * when a netif has been removed - */ -#if !defined LWIP_NETIF_REMOVE_CALLBACK || defined __DOXYGEN__ -#define LWIP_NETIF_REMOVE_CALLBACK 0 -#endif - -/** - * LWIP_NETIF_HWADDRHINT==1: Cache link-layer-address hints (e.g. table - * indices) in struct netif. TCP and UDP can make use of this to prevent - * scanning the ARP table for every sent packet. While this is faster for big - * ARP tables or many concurrent connections, it might be counterproductive - * if you have a tiny ARP table or if there never are concurrent connections. - */ -#if !defined LWIP_NETIF_HWADDRHINT || defined __DOXYGEN__ -#define LWIP_NETIF_HWADDRHINT 0 -#endif - -/** - * LWIP_NETIF_TX_SINGLE_PBUF: if this is set to 1, lwIP tries to put all data - * to be sent into one single pbuf. This is for compatibility with DMA-enabled - * MACs that do not support scatter-gather. - * Beware that this might involve CPU-memcpy before transmitting that would not - * be needed without this flag! Use this only if you need to! - * - * @todo: TCP and IP-frag do not work with this, yet: - */ -#if !defined LWIP_NETIF_TX_SINGLE_PBUF || defined __DOXYGEN__ -#define LWIP_NETIF_TX_SINGLE_PBUF 0 -#endif /* LWIP_NETIF_TX_SINGLE_PBUF */ - -/** - * LWIP_NUM_NETIF_CLIENT_DATA: Number of clients that may store - * data in client_data member array of struct netif. - */ -#if !defined LWIP_NUM_NETIF_CLIENT_DATA || defined __DOXYGEN__ -#define LWIP_NUM_NETIF_CLIENT_DATA 0 -#endif -/** - * @} - */ - -#ifndef LWIP_MANAGEMENT_CHANNEL -#define LWIP_MANAGEMENT_CHANNEL 0 -#endif - -/* - ------------------------------------ - ---------- LOOPIF options ---------- - ------------------------------------ -*/ -/** - * @defgroup lwip_opts_loop Loopback interface - * @ingroup lwip_opts_netif - * @{ - */ -/** - * LWIP_HAVE_LOOPIF==1: Support loop interface (127.0.0.1). - * This is only needed when no real netifs are available. If at least one other - * netif is available, loopback traffic uses this netif. - */ -#if !defined LWIP_HAVE_LOOPIF || defined __DOXYGEN__ -#define LWIP_HAVE_LOOPIF LWIP_NETIF_LOOPBACK -#endif - -/** - * LWIP_LOOPIF_MULTICAST==1: Support multicast/IGMP on loop interface (127.0.0.1). - */ -#if !defined LWIP_LOOPIF_MULTICAST || defined __DOXYGEN__ -#define LWIP_LOOPIF_MULTICAST 0 -#endif - -/** - * LWIP_NETIF_LOOPBACK==1: Support sending packets with a destination IP - * address equal to the netif IP address, looping them back up the stack. - */ -#if !defined LWIP_NETIF_LOOPBACK || defined __DOXYGEN__ -#define LWIP_NETIF_LOOPBACK 0 -#endif - -/** - * LWIP_LOOPBACK_MAX_PBUFS: Maximum number of pbufs on queue for loopback - * sending for each netif (0 = disabled) - */ -#if !defined LWIP_LOOPBACK_MAX_PBUFS || defined __DOXYGEN__ -#define LWIP_LOOPBACK_MAX_PBUFS 0 -#endif - -/** - * LWIP_NETIF_LOOPBACK_MULTITHREADING: Indicates whether threading is enabled in - * the system, as netifs must change how they behave depending on this setting - * for the LWIP_NETIF_LOOPBACK option to work. - * Setting this is needed to avoid reentering non-reentrant functions like - * tcp_input(). - * LWIP_NETIF_LOOPBACK_MULTITHREADING==1: Indicates that the user is using a - * multithreaded environment like tcpip.c. In this case, netif->input() - * is called directly. - * LWIP_NETIF_LOOPBACK_MULTITHREADING==0: Indicates a polling (or NO_SYS) setup. - * The packets are put on a list and netif_poll() must be called in - * the main application loop. - */ -#if !defined LWIP_NETIF_LOOPBACK_MULTITHREADING || defined __DOXYGEN__ -#define LWIP_NETIF_LOOPBACK_MULTITHREADING (!NO_SYS) -#endif -/** - * @} - */ - -/* - ------------------------------------ - ---------- Thread options ---------- - ------------------------------------ -*/ -/** - * @defgroup lwip_opts_thread Threading - * @ingroup lwip_opts_infrastructure - * @{ - */ -/** - * TCPIP_THREAD_NAME: The name assigned to the main tcpip thread. - */ -#if !defined TCPIP_THREAD_NAME || defined __DOXYGEN__ -#define TCPIP_THREAD_NAME "tcpip_thread" -#endif - -/** - * TCPIP_THREAD_STACKSIZE: The stack size used by the main tcpip thread. - * The stack size value itself is platform-dependent, but is passed to - * sys_thread_new() when the thread is created. - */ -#if !defined TCPIP_THREAD_STACKSIZE || defined __DOXYGEN__ -#define TCPIP_THREAD_STACKSIZE 0 -#endif - -/** - * TCPIP_THREAD_PRIO: The priority assigned to the main tcpip thread. - * The priority value itself is platform-dependent, but is passed to - * sys_thread_new() when the thread is created. - */ -#if !defined TCPIP_THREAD_PRIO || defined __DOXYGEN__ -#define TCPIP_THREAD_PRIO 1 -#endif - -/** - * TCPIP_MBOX_SIZE: The mailbox size for the tcpip thread messages - * The queue size value itself is platform-dependent, but is passed to - * sys_mbox_new() when tcpip_init is called. - */ -#if !defined TCPIP_MBOX_SIZE || defined __DOXYGEN__ -#define TCPIP_MBOX_SIZE 0 -#endif - -/** - * Define this to something that triggers a watchdog. This is called from - * tcpip_thread after processing a message. - */ -#if !defined LWIP_TCPIP_THREAD_ALIVE || defined __DOXYGEN__ -#define LWIP_TCPIP_THREAD_ALIVE() -#endif - -/** - * SLIPIF_THREAD_NAME: The name assigned to the slipif_loop thread. - */ -#if !defined SLIPIF_THREAD_NAME || defined __DOXYGEN__ -#define SLIPIF_THREAD_NAME "slipif_loop" -#endif - -/** - * SLIP_THREAD_STACKSIZE: The stack size used by the slipif_loop thread. - * The stack size value itself is platform-dependent, but is passed to - * sys_thread_new() when the thread is created. - */ -#if !defined SLIPIF_THREAD_STACKSIZE || defined __DOXYGEN__ -#define SLIPIF_THREAD_STACKSIZE 0 -#endif - -/** - * SLIPIF_THREAD_PRIO: The priority assigned to the slipif_loop thread. - * The priority value itself is platform-dependent, but is passed to - * sys_thread_new() when the thread is created. - */ -#if !defined SLIPIF_THREAD_PRIO || defined __DOXYGEN__ -#define SLIPIF_THREAD_PRIO 1 -#endif - -/** - * DEFAULT_THREAD_NAME: The name assigned to any other lwIP thread. - */ -#if !defined DEFAULT_THREAD_NAME || defined __DOXYGEN__ -#define DEFAULT_THREAD_NAME "lwIP" -#endif - -/** - * DEFAULT_THREAD_STACKSIZE: The stack size used by any other lwIP thread. - * The stack size value itself is platform-dependent, but is passed to - * sys_thread_new() when the thread is created. - */ -#if !defined DEFAULT_THREAD_STACKSIZE || defined __DOXYGEN__ -#define DEFAULT_THREAD_STACKSIZE 0 -#endif - -/** - * DEFAULT_THREAD_PRIO: The priority assigned to any other lwIP thread. - * The priority value itself is platform-dependent, but is passed to - * sys_thread_new() when the thread is created. - */ -#if !defined DEFAULT_THREAD_PRIO || defined __DOXYGEN__ -#define DEFAULT_THREAD_PRIO 1 -#endif - -/** - * DEFAULT_RAW_RECVMBOX_SIZE: The mailbox size for the incoming packets on a - * NETCONN_RAW. The queue size value itself is platform-dependent, but is passed - * to sys_mbox_new() when the recvmbox is created. - */ -#if !defined DEFAULT_RAW_RECVMBOX_SIZE || defined __DOXYGEN__ -#define DEFAULT_RAW_RECVMBOX_SIZE 0 -#endif - -/** - * DEFAULT_UDP_RECVMBOX_SIZE: The mailbox size for the incoming packets on a - * NETCONN_UDP. The queue size value itself is platform-dependent, but is passed - * to sys_mbox_new() when the recvmbox is created. - */ -#if !defined DEFAULT_UDP_RECVMBOX_SIZE || defined __DOXYGEN__ -#define DEFAULT_UDP_RECVMBOX_SIZE 0 -#endif - -/** - * DEFAULT_TCP_RECVMBOX_SIZE: The mailbox size for the incoming packets on a - * NETCONN_TCP. The queue size value itself is platform-dependent, but is passed - * to sys_mbox_new() when the recvmbox is created. - */ -#if !defined DEFAULT_TCP_RECVMBOX_SIZE || defined __DOXYGEN__ -#define DEFAULT_TCP_RECVMBOX_SIZE 0 -#endif - -/** - * DEFAULT_ACCEPTMBOX_SIZE: The mailbox size for the incoming connections. - * The queue size value itself is platform-dependent, but is passed to - * sys_mbox_new() when the acceptmbox is created. - */ -#if !defined DEFAULT_ACCEPTMBOX_SIZE || defined __DOXYGEN__ -#define DEFAULT_ACCEPTMBOX_SIZE 0 -#endif -/** - * @} - */ - -/* - ---------------------------------------------- - ---------- Sequential layer options ---------- - ---------------------------------------------- -*/ -/** - * @defgroup lwip_opts_netconn Netconn - * @ingroup lwip_opts_threadsafe_apis - * @{ - */ -/** - * LWIP_NETCONN==1: Enable Netconn API (require to use api_lib.c) - */ -#if !defined LWIP_NETCONN || defined __DOXYGEN__ -#define LWIP_NETCONN 1 -#endif - -/** LWIP_TCPIP_TIMEOUT==1: Enable tcpip_timeout/tcpip_untimeout to create - * timers running in tcpip_thread from another thread. - */ -#if !defined LWIP_TCPIP_TIMEOUT || defined __DOXYGEN__ -#define LWIP_TCPIP_TIMEOUT 0 -#endif - -/** LWIP_NETCONN_SEM_PER_THREAD==1: Use one (thread-local) semaphore per - * thread calling socket/netconn functions instead of allocating one - * semaphore per netconn (and per select etc.) - * ATTENTION: a thread-local semaphore for API calls is needed: - * - LWIP_NETCONN_THREAD_SEM_GET() returning a sys_sem_t* - * - LWIP_NETCONN_THREAD_SEM_ALLOC() creating the semaphore - * - LWIP_NETCONN_THREAD_SEM_FREE() freeing the semaphore - * The latter 2 can be invoked up by calling netconn_thread_init()/netconn_thread_cleanup(). - * Ports may call these for threads created with sys_thread_new(). - */ -#if !defined LWIP_NETCONN_SEM_PER_THREAD || defined __DOXYGEN__ -#define LWIP_NETCONN_SEM_PER_THREAD 0 -#endif - -/** LWIP_NETCONN_FULLDUPLEX==1: Enable code that allows reading from one thread, - * writing from a 2nd thread and closing from a 3rd thread at the same time. - * ATTENTION: This is currently really alpha! Some requirements: - * - LWIP_NETCONN_SEM_PER_THREAD==1 is required to use one socket/netconn from - * multiple threads at once - * - sys_mbox_free() has to unblock receive tasks waiting on recvmbox/acceptmbox - * and prevent a task pending on this during/after deletion - */ -#if !defined LWIP_NETCONN_FULLDUPLEX || defined __DOXYGEN__ -#define LWIP_NETCONN_FULLDUPLEX 0 -#endif -/** - * @} - */ - -/* - ------------------------------------ - ---------- Socket options ---------- - ------------------------------------ -*/ -/** - * @defgroup lwip_opts_socket Sockets - * @ingroup lwip_opts_threadsafe_apis - * @{ - */ -/** - * LWIP_SOCKET==1: Enable Socket API (require to use sockets.c) - */ -#if !defined LWIP_SOCKET || defined __DOXYGEN__ -#define LWIP_SOCKET 1 -#endif - -/* LWIP_SOCKET_SET_ERRNO==1: Set errno when socket functions cannot complete - * successfully, as required by POSIX. Default is POSIX-compliant. - */ -#if !defined LWIP_SOCKET_SET_ERRNO || defined __DOXYGEN__ -#define LWIP_SOCKET_SET_ERRNO 1 -#endif - -/** - * LWIP_COMPAT_SOCKETS==1: Enable BSD-style sockets functions names through defines. - * LWIP_COMPAT_SOCKETS==2: Same as ==1 but correctly named functions are created. - * While this helps code completion, it might conflict with existing libraries. - * (only used if you use sockets.c) - */ -#if !defined LWIP_COMPAT_SOCKETS || defined __DOXYGEN__ -#define LWIP_COMPAT_SOCKETS 1 -#endif - -/** - * LWIP_POSIX_SOCKETS_IO_NAMES==1: Enable POSIX-style sockets functions names. - * Disable this option if you use a POSIX operating system that uses the same - * names (read, write & close). (only used if you use sockets.c) - */ -#if !defined LWIP_POSIX_SOCKETS_IO_NAMES || defined __DOXYGEN__ -#define LWIP_POSIX_SOCKETS_IO_NAMES 1 -#endif - -/** - * LWIP_SOCKET_OFFSET==n: Increases the file descriptor number created by LwIP with n. - * This can be useful when there are multiple APIs which create file descriptors. - * When they all start with a different offset and you won't make them overlap you can - * re implement read/write/close/ioctl/fnctl to send the requested action to the right - * library (sharing select will need more work though). - */ -#if !defined LWIP_SOCKET_OFFSET || defined __DOXYGEN__ -#define LWIP_SOCKET_OFFSET 0 -#endif - -/** - * LWIP_TCP_KEEPALIVE==1: Enable TCP_KEEPIDLE, TCP_KEEPINTVL and TCP_KEEPCNT - * options processing. Note that TCP_KEEPIDLE and TCP_KEEPINTVL have to be set - * in seconds. (does not require sockets.c, and will affect tcp.c) - */ -#if !defined LWIP_TCP_KEEPALIVE || defined __DOXYGEN__ -#define LWIP_TCP_KEEPALIVE 0 -#endif - -/** - * LWIP_SO_SNDTIMEO==1: Enable send timeout for sockets/netconns and - * SO_SNDTIMEO processing. - */ -#if !defined LWIP_SO_SNDTIMEO || defined __DOXYGEN__ -#define LWIP_SO_SNDTIMEO 0 -#endif - -/** - * LWIP_SO_RCVTIMEO==1: Enable receive timeout for sockets/netconns and - * SO_RCVTIMEO processing. - */ -#if !defined LWIP_SO_RCVTIMEO || defined __DOXYGEN__ -#define LWIP_SO_RCVTIMEO 0 -#endif - -/** - * LWIP_SO_SNDRCVTIMEO_NONSTANDARD==1: SO_RCVTIMEO/SO_SNDTIMEO take an int - * (milliseconds, much like winsock does) instead of a struct timeval (default). - */ -#if !defined LWIP_SO_SNDRCVTIMEO_NONSTANDARD || defined __DOXYGEN__ -#define LWIP_SO_SNDRCVTIMEO_NONSTANDARD 0 -#endif - -/** - * LWIP_SO_RCVBUF==1: Enable SO_RCVBUF processing. - */ -#if !defined LWIP_SO_RCVBUF || defined __DOXYGEN__ -#define LWIP_SO_RCVBUF 0 -#endif - -/** - * LWIP_SO_LINGER==1: Enable SO_LINGER processing. - */ -#if !defined LWIP_SO_LINGER || defined __DOXYGEN__ -#define LWIP_SO_LINGER 0 -#endif - -/** - * If LWIP_SO_RCVBUF is used, this is the default value for recv_bufsize. - */ -#if !defined RECV_BUFSIZE_DEFAULT || defined __DOXYGEN__ -#define RECV_BUFSIZE_DEFAULT INT_MAX -#endif - -/** - * By default, TCP socket/netconn close waits 20 seconds max to send the FIN - */ -#if !defined LWIP_TCP_CLOSE_TIMEOUT_MS_DEFAULT || defined __DOXYGEN__ -#define LWIP_TCP_CLOSE_TIMEOUT_MS_DEFAULT 20000 -#endif - -/** - * SO_REUSE==1: Enable SO_REUSEADDR option. - */ -#if !defined SO_REUSE || defined __DOXYGEN__ -#define SO_REUSE 0 -#endif - -/** - * SO_REUSE_RXTOALL==1: Pass a copy of incoming broadcast/multicast packets - * to all local matches if SO_REUSEADDR is turned on. - * WARNING: Adds a memcpy for every packet if passing to more than one pcb! - */ -#if !defined SO_REUSE_RXTOALL || defined __DOXYGEN__ -#define SO_REUSE_RXTOALL 0 -#endif - -/** - * LWIP_FIONREAD_LINUXMODE==0 (default): ioctl/FIONREAD returns the amount of - * pending data in the network buffer. This is the way windows does it. It's - * the default for lwIP since it is smaller. - * LWIP_FIONREAD_LINUXMODE==1: ioctl/FIONREAD returns the size of the next - * pending datagram in bytes. This is the way linux does it. This code is only - * here for compatibility. - */ -#if !defined LWIP_FIONREAD_LINUXMODE || defined __DOXYGEN__ -#define LWIP_FIONREAD_LINUXMODE 0 -#endif -/** - * @} - */ - -/* - ---------------------------------------- - ---------- Statistics options ---------- - ---------------------------------------- -*/ -/** - * @defgroup lwip_opts_stats Statistics - * @ingroup lwip_opts_debug - * @{ - */ -/** - * LWIP_STATS==1: Enable statistics collection in lwip_stats. - */ -#if !defined LWIP_STATS || defined __DOXYGEN__ -#define LWIP_STATS 1 -#endif - -#if LWIP_STATS - -/** - * LWIP_STATS_DISPLAY==1: Compile in the statistics output functions. - */ -#if !defined LWIP_STATS_DISPLAY || defined __DOXYGEN__ -#define LWIP_STATS_DISPLAY 0 -#endif - -/** - * LINK_STATS==1: Enable link stats. - */ -#if !defined LINK_STATS || defined __DOXYGEN__ -#define LINK_STATS 1 -#endif - -/** - * ETHARP_STATS==1: Enable etharp stats. - */ -#if !defined ETHARP_STATS || defined __DOXYGEN__ -#define ETHARP_STATS (LWIP_ARP) -#endif - -/** - * IP_STATS==1: Enable IP stats. - */ -#if !defined IP_STATS || defined __DOXYGEN__ -#define IP_STATS 1 -#endif - -/** - * IPFRAG_STATS==1: Enable IP fragmentation stats. Default is - * on if using either frag or reass. - */ -#if !defined IPFRAG_STATS || defined __DOXYGEN__ -#define IPFRAG_STATS (IP_REASSEMBLY || IP_FRAG) -#endif - -/** - * ICMP_STATS==1: Enable ICMP stats. - */ -#if !defined ICMP_STATS || defined __DOXYGEN__ -#define ICMP_STATS 1 -#endif - -/** - * IGMP_STATS==1: Enable IGMP stats. - */ -#if !defined IGMP_STATS || defined __DOXYGEN__ -#define IGMP_STATS (LWIP_IGMP) -#endif - -/** - * UDP_STATS==1: Enable UDP stats. Default is on if - * UDP enabled, otherwise off. - */ -#if !defined UDP_STATS || defined __DOXYGEN__ -#define UDP_STATS (LWIP_UDP) -#endif - -/** - * TCP_STATS==1: Enable TCP stats. Default is on if TCP - * enabled, otherwise off. - */ -#if !defined TCP_STATS || defined __DOXYGEN__ -#define TCP_STATS (LWIP_TCP) -#endif - -/** - * MEM_STATS==1: Enable mem.c stats. - */ -#if !defined MEM_STATS || defined __DOXYGEN__ -#define MEM_STATS ((MEM_LIBC_MALLOC == 0) && (MEM_USE_POOLS == 0)) -#endif - -/** - * MEMP_STATS==1: Enable memp.c pool stats. - */ -#if !defined MEMP_STATS || defined __DOXYGEN__ -#define MEMP_STATS (MEMP_MEM_MALLOC == 0) -#endif - -/** - * SYS_STATS==1: Enable system stats (sem and mbox counts, etc). - */ -#if !defined SYS_STATS || defined __DOXYGEN__ -#define SYS_STATS (NO_SYS == 0) -#endif - -/** - * IP6_STATS==1: Enable IPv6 stats. - */ -#if !defined IP6_STATS || defined __DOXYGEN__ -#define IP6_STATS (LWIP_IPV6) -#endif - -/** - * ICMP6_STATS==1: Enable ICMP for IPv6 stats. - */ -#if !defined ICMP6_STATS || defined __DOXYGEN__ -#define ICMP6_STATS (LWIP_IPV6 && LWIP_ICMP6) -#endif - -/** - * IP6_FRAG_STATS==1: Enable IPv6 fragmentation stats. - */ -#if !defined IP6_FRAG_STATS || defined __DOXYGEN__ -#define IP6_FRAG_STATS (LWIP_IPV6 && (LWIP_IPV6_FRAG || LWIP_IPV6_REASS)) -#endif - -/** - * MLD6_STATS==1: Enable MLD for IPv6 stats. - */ -#if !defined MLD6_STATS || defined __DOXYGEN__ -#define MLD6_STATS (LWIP_IPV6 && LWIP_IPV6_MLD) -#endif - -/** - * ND6_STATS==1: Enable Neighbor discovery for IPv6 stats. - */ -#if !defined ND6_STATS || defined __DOXYGEN__ -#define ND6_STATS (LWIP_IPV6_ND) -#endif - -/** - * MIB2_STATS==1: Stats for SNMP MIB2. - */ -#if !defined MIB2_STATS || defined __DOXYGEN__ -#define MIB2_STATS 0 -#endif - -#else - -#define LINK_STATS 0 -#define ETHARP_STATS 0 -#define IP_STATS 0 -#define IPFRAG_STATS 0 -#define ICMP_STATS 0 -#define IGMP_STATS 0 -#define UDP_STATS 0 -#define TCP_STATS 0 -#define MEM_STATS 0 -#define MEMP_STATS 0 -#define SYS_STATS 0 -#define LWIP_STATS_DISPLAY 0 -#define IP6_STATS 0 -#define ICMP6_STATS 0 -#define IP6_FRAG_STATS 0 -#define MLD6_STATS 0 -#define ND6_STATS 0 -#define MIB2_STATS 0 - -#endif /* LWIP_STATS */ -/** - * @} - */ - -/* - -------------------------------------- - ---------- Checksum options ---------- - -------------------------------------- -*/ -/** - * @defgroup lwip_opts_checksum Checksum - * @ingroup lwip_opts_infrastructure - * @{ - */ -/** - * LWIP_CHECKSUM_CTRL_PER_NETIF==1: Checksum generation/check can be enabled/disabled - * per netif. - * ATTENTION: if enabled, the CHECKSUM_GEN_* and CHECKSUM_CHECK_* defines must be enabled! - */ -#if !defined LWIP_CHECKSUM_CTRL_PER_NETIF || defined __DOXYGEN__ -#define LWIP_CHECKSUM_CTRL_PER_NETIF 0 -#endif - -/** - * CHECKSUM_GEN_IP==1: Generate checksums in software for outgoing IP packets. - */ -#if !defined CHECKSUM_GEN_IP || defined __DOXYGEN__ -#define CHECKSUM_GEN_IP 1 -#endif - -/** - * CHECKSUM_GEN_UDP==1: Generate checksums in software for outgoing UDP packets. - */ -#if !defined CHECKSUM_GEN_UDP || defined __DOXYGEN__ -#define CHECKSUM_GEN_UDP 1 -#endif - -/** - * CHECKSUM_GEN_TCP==1: Generate checksums in software for outgoing TCP packets. - */ -#if !defined CHECKSUM_GEN_TCP || defined __DOXYGEN__ -#define CHECKSUM_GEN_TCP 1 -#endif - -/** - * CHECKSUM_GEN_ICMP==1: Generate checksums in software for outgoing ICMP packets. - */ -#if !defined CHECKSUM_GEN_ICMP || defined __DOXYGEN__ -#define CHECKSUM_GEN_ICMP 1 -#endif - -/** - * CHECKSUM_GEN_ICMP6==1: Generate checksums in software for outgoing ICMP6 packets. - */ -#if !defined CHECKSUM_GEN_ICMP6 || defined __DOXYGEN__ -#define CHECKSUM_GEN_ICMP6 1 -#endif - -/** - * CHECKSUM_CHECK_IP==1: Check checksums in software for incoming IP packets. - */ -#if !defined CHECKSUM_CHECK_IP || defined __DOXYGEN__ -#define CHECKSUM_CHECK_IP 1 -#endif - -/** - * CHECKSUM_CHECK_UDP==1: Check checksums in software for incoming UDP packets. - */ -#if !defined CHECKSUM_CHECK_UDP || defined __DOXYGEN__ -#define CHECKSUM_CHECK_UDP 1 -#endif - -/** - * CHECKSUM_CHECK_TCP==1: Check checksums in software for incoming TCP packets. - */ -#if !defined CHECKSUM_CHECK_TCP || defined __DOXYGEN__ -#define CHECKSUM_CHECK_TCP 1 -#endif - -/** - * CHECKSUM_CHECK_ICMP==1: Check checksums in software for incoming ICMP packets. - */ -#if !defined CHECKSUM_CHECK_ICMP || defined __DOXYGEN__ -#define CHECKSUM_CHECK_ICMP 1 -#endif - -/** - * CHECKSUM_CHECK_ICMP6==1: Check checksums in software for incoming ICMPv6 packets - */ -#if !defined CHECKSUM_CHECK_ICMP6 || defined __DOXYGEN__ -#define CHECKSUM_CHECK_ICMP6 1 -#endif - -/** - * LWIP_CHECKSUM_ON_COPY==1: Calculate checksum when copying data from - * application buffers to pbufs. - */ -#if !defined LWIP_CHECKSUM_ON_COPY || defined __DOXYGEN__ -#define LWIP_CHECKSUM_ON_COPY 0 -#endif -/** - * @} - */ - -/* - --------------------------------------- - ---------- IPv6 options --------------- - --------------------------------------- -*/ -/** - * @defgroup lwip_opts_ipv6 IPv6 - * @ingroup lwip_opts - * @{ - */ -/** - * LWIP_IPV6==1: Enable IPv6 - */ -#if !defined LWIP_IPV6 || defined __DOXYGEN__ -#define LWIP_IPV6 0 -#endif - -/** - * LWIP_IPV6_NUM_ADDRESSES: Number of IPv6 addresses per netif. - */ -#if !defined LWIP_IPV6_NUM_ADDRESSES || defined __DOXYGEN__ -#define LWIP_IPV6_NUM_ADDRESSES 3 -#endif - -/** - * LWIP_IPV6_FORWARD==1: Forward IPv6 packets across netifs - */ -#if !defined LWIP_IPV6_FORWARD || defined __DOXYGEN__ -#define LWIP_IPV6_FORWARD 0 -#endif - -/** - * LWIP_IPV6_FRAG==1: Fragment outgoing IPv6 packets that are too big. - */ -#if !defined LWIP_IPV6_FRAG || defined __DOXYGEN__ -#define LWIP_IPV6_FRAG 0 -#endif - -/** - * LWIP_IPV6_REASS==1: reassemble incoming IPv6 packets that fragmented - */ -#if !defined LWIP_IPV6_REASS || defined __DOXYGEN__ -#define LWIP_IPV6_REASS (LWIP_IPV6) -#endif - -/** - * LWIP_IPV6_SEND_ROUTER_SOLICIT==1: Send router solicitation messages during - * network startup. - */ -#if !defined LWIP_IPV6_SEND_ROUTER_SOLICIT || defined __DOXYGEN__ -#define LWIP_IPV6_SEND_ROUTER_SOLICIT 1 -#endif - -/** - * LWIP_IPV6_ADDRESS_LIFETIMES==1: Keep valid and preferred lifetimes for each - * IPv6 address. Required for LWIP_IPV6_AUTOCONFIG. May still be enabled - * otherwise, in which case the application may assign address lifetimes with - * the appropriate macros. Addresses with no lifetime are assumed to be static. - * If this option is disabled, all addresses are assumed to be static. - */ -#if !defined LWIP_IPV6_ADDRESS_LIFETIMES || defined __DOXYGEN__ -#define LWIP_IPV6_ADDRESS_LIFETIMES (LWIP_IPV6_AUTOCONFIG) -#endif - -/** - * LWIP_IPV6_DUP_DETECT_ATTEMPTS=[0..7]: Number of duplicate address detection attempts. - */ -#if !defined LWIP_IPV6_DUP_DETECT_ATTEMPTS || defined __DOXYGEN__ -#define LWIP_IPV6_DUP_DETECT_ATTEMPTS 1 -#endif -/** - * @} - */ - -/** - * @defgroup lwip_opts_icmp6 ICMP6 - * @ingroup lwip_opts_ipv6 - * @{ - */ -/** - * LWIP_ICMP6==1: Enable ICMPv6 (mandatory per RFC) - */ -#if !defined LWIP_ICMP6 || defined __DOXYGEN__ -#define LWIP_ICMP6 (LWIP_IPV6) -#endif - -/** - * LWIP_ICMP6_DATASIZE: bytes from original packet to send back in - * ICMPv6 error messages. - */ -#if !defined LWIP_ICMP6_DATASIZE || defined __DOXYGEN__ -#define LWIP_ICMP6_DATASIZE 8 -#endif - -/** - * LWIP_ICMP6_HL: default hop limit for ICMPv6 messages - */ -#if !defined LWIP_ICMP6_HL || defined __DOXYGEN__ -#define LWIP_ICMP6_HL 255 -#endif -/** - * @} - */ - -/** - * @defgroup lwip_opts_nd6 Neighbor discovery - * @ingroup lwip_opts_ipv6 - * @{ - */ - -/** - * LWIP_IPV6_ND==1: Enable neighbor discovery protocol. - * If LWIP_IPV6 is enabled but this setting is disabled, then neighbor and - * destination caches, duplicate address detection, neighbor unreachability - * detection, multicast listener discovery and router discovery are delegated - * entirely to the sub-IP layer. - */ -#if !defined LWIP_IPV6_ND || defined __DOXYGEN__ -#define LWIP_IPV6_ND (LWIP_IPV6) -#endif - -/** - * LWIP_IPV6_AUTOCONFIG==1: Enable stateless address autoconfiguration as per RFC 4862. - */ -#if !defined LWIP_IPV6_AUTOCONFIG || defined __DOXYGEN__ -#define LWIP_IPV6_AUTOCONFIG (LWIP_IPV6_ND) -#endif - -/** - * @defgroup lwip_opts_mld6 Multicast listener discovery - * @ingroup lwip_opts_ipv6 - * @{ - */ -/** - * LWIP_IPV6_MLD==1: Enable multicast listener discovery protocol. - * If LWIP_IPV6_ND is enabled but this setting is disabled, the MAC layer must - * indiscriminately pass all inbound IPv6 multicast traffic to lwIP. - */ -#if !defined LWIP_IPV6_MLD || defined __DOXYGEN__ -#define LWIP_IPV6_MLD (LWIP_IPV6_ND) -#endif - -/** - * MEMP_NUM_MLD6_GROUP: Max number of IPv6 multicast groups that can be joined. - * There must be enough groups so that each netif can join the solicited-node - * multicast group for each of its local addresses, plus one for MDNS if - * applicable, plus any number of groups to be joined on UDP sockets. - */ -#if !defined MEMP_NUM_MLD6_GROUP || defined __DOXYGEN__ -#define MEMP_NUM_MLD6_GROUP 4 -#endif -/** - * @} - */ - -/** - * @defgroup lwip_opts_nd6 Neighbor discovery - * @ingroup lwip_opts_ipv6 - * @{ - */ -/** - * LWIP_ND6_QUEUEING==1: queue outgoing IPv6 packets while MAC address - * is being resolved. - */ -#if !defined LWIP_ND6_QUEUEING || defined __DOXYGEN__ -#define LWIP_ND6_QUEUEING (LWIP_IPV6_ND) -#endif - -/** - * MEMP_NUM_ND6_QUEUE: Max number of IPv6 packets to queue during MAC resolution. - */ -#if !defined MEMP_NUM_ND6_QUEUE || defined __DOXYGEN__ -#define MEMP_NUM_ND6_QUEUE 20 -#endif - -/** - * LWIP_ND6_NUM_NEIGHBORS: Number of entries in IPv6 neighbor cache - */ -#if !defined LWIP_ND6_NUM_NEIGHBORS || defined __DOXYGEN__ -#define LWIP_ND6_NUM_NEIGHBORS 10 -#endif - -/** - * LWIP_ND6_NUM_DESTINATIONS: number of entries in IPv6 destination cache - */ -#if !defined LWIP_ND6_NUM_DESTINATIONS || defined __DOXYGEN__ -#define LWIP_ND6_NUM_DESTINATIONS 10 -#endif - -/** - * LWIP_ND6_NUM_PREFIXES: number of entries in IPv6 on-link prefixes cache - */ -#if !defined LWIP_ND6_NUM_PREFIXES || defined __DOXYGEN__ -#define LWIP_ND6_NUM_PREFIXES 5 -#endif - -/** - * LWIP_ND6_NUM_ROUTERS: number of entries in IPv6 default router cache - */ -#if !defined LWIP_ND6_NUM_ROUTERS || defined __DOXYGEN__ -#define LWIP_ND6_NUM_ROUTERS 3 -#endif - -/** - * LWIP_ND6_MAX_MULTICAST_SOLICIT: max number of multicast solicit messages to send - * (neighbor solicit and router solicit) - */ -#if !defined LWIP_ND6_MAX_MULTICAST_SOLICIT || defined __DOXYGEN__ -#define LWIP_ND6_MAX_MULTICAST_SOLICIT 3 -#endif - -/** - * LWIP_ND6_MAX_UNICAST_SOLICIT: max number of unicast neighbor solicitation messages - * to send during neighbor reachability detection. - */ -#if !defined LWIP_ND6_MAX_UNICAST_SOLICIT || defined __DOXYGEN__ -#define LWIP_ND6_MAX_UNICAST_SOLICIT 3 -#endif - -/** - * Unused: See ND RFC (time in milliseconds). - */ -#if !defined LWIP_ND6_MAX_ANYCAST_DELAY_TIME || defined __DOXYGEN__ -#define LWIP_ND6_MAX_ANYCAST_DELAY_TIME 1000 -#endif - -/** - * Unused: See ND RFC - */ -#if !defined LWIP_ND6_MAX_NEIGHBOR_ADVERTISEMENT || defined __DOXYGEN__ -#define LWIP_ND6_MAX_NEIGHBOR_ADVERTISEMENT 3 -#endif - -/** - * LWIP_ND6_REACHABLE_TIME: default neighbor reachable time (in milliseconds). - * May be updated by router advertisement messages. - */ -#if !defined LWIP_ND6_REACHABLE_TIME || defined __DOXYGEN__ -#define LWIP_ND6_REACHABLE_TIME 30000 -#endif - -/** - * LWIP_ND6_RETRANS_TIMER: default retransmission timer for solicitation messages - */ -#if !defined LWIP_ND6_RETRANS_TIMER || defined __DOXYGEN__ -#define LWIP_ND6_RETRANS_TIMER 1000 -#endif - -/** - * LWIP_ND6_DELAY_FIRST_PROBE_TIME: Delay before first unicast neighbor solicitation - * message is sent, during neighbor reachability detection. - */ -#if !defined LWIP_ND6_DELAY_FIRST_PROBE_TIME || defined __DOXYGEN__ -#define LWIP_ND6_DELAY_FIRST_PROBE_TIME 5000 -#endif - -/** - * LWIP_ND6_ALLOW_RA_UPDATES==1: Allow Router Advertisement messages to update - * Reachable time and retransmission timers, and netif MTU. - */ -#if !defined LWIP_ND6_ALLOW_RA_UPDATES || defined __DOXYGEN__ -#define LWIP_ND6_ALLOW_RA_UPDATES 1 -#endif - -/** - * LWIP_ND6_TCP_REACHABILITY_HINTS==1: Allow TCP to provide Neighbor Discovery - * with reachability hints for connected destinations. This helps avoid sending - * unicast neighbor solicitation messages. - */ -#if !defined LWIP_ND6_TCP_REACHABILITY_HINTS || defined __DOXYGEN__ -#define LWIP_ND6_TCP_REACHABILITY_HINTS 1 -#endif - -/** - * LWIP_ND6_RDNSS_MAX_DNS_SERVERS > 0: Use IPv6 Router Advertisement Recursive - * DNS Server Option (as per RFC 6106) to copy a defined maximum number of DNS - * servers to the DNS module. - */ -#if !defined LWIP_ND6_RDNSS_MAX_DNS_SERVERS || defined __DOXYGEN__ -#define LWIP_ND6_RDNSS_MAX_DNS_SERVERS 0 -#endif -/** - * @} - */ - -/** - * LWIP_IPV6_DHCP6==1: enable DHCPv6 stateful address autoconfiguration. - */ -#if !defined LWIP_IPV6_DHCP6 || defined __DOXYGEN__ -#define LWIP_IPV6_DHCP6 0 -#endif - -/** - * LWIP_ND6_LISTEN_RA==1: Enable listening and processing incoming Router Advertisements. - */ -#ifndef LWIP_ND6_LISTEN_RA -#define LWIP_ND6_LISTEN_RA 1 -#endif - -/** - * LWIP_IPV6_ROUTER_SUPPORT==1: Maintain a list of IPV6 routers dynamically discovered via Router Advertisements. - */ -#ifndef LWIP_IPV6_ROUTER_SUPPORT -#define LWIP_IPV6_ROUTER_SUPPORT 1 -#endif - -/** - * LWIP_IPV6_ROUTE_TABLE_SUPPORT==1: Enable support for adding static routes and referring to these during forwarding. - */ -#ifndef LWIP_IPV6_ROUTE_TABLE_SUPPORT -#define LWIP_IPV6_ROUTE_TABLE_SUPPORT 0 -#endif - -/** - * LWIP_IPV6_NUM_ROUTES: Number of IPV6 routes that can be kept in the static route table. - */ -#ifndef LWIP_IPV6_NUM_ROUTE_ENTRIES -#define LWIP_IPV6_NUM_ROUTE_ENTRIES 8 -#endif - - -/* - --------------------------------------- - ---------- Hook options --------------- - --------------------------------------- -*/ - -/** - * @defgroup lwip_opts_hooks Hooks - * @ingroup lwip_opts_infrastructure - * Hooks are undefined by default, define them to a function if you need them. - * @{ - */ - -/** - * LWIP_HOOK_FILENAME: Custom filename to #include in files that provide hooks. - * Declare your hook function prototypes in there, you may also #include all headers - * providing data types that are need in this file. - */ -#ifdef __DOXYGEN__ -#define LWIP_HOOK_FILENAME "path/to/my/lwip_hooks.h" -#endif - -/** - * LWIP_HOOK_TCP_ISN: - * Hook for generation of the Initial Sequence Number (ISN) for a new TCP - * connection. The default lwIP ISN generation algorithm is very basic and may - * allow for TCP spoofing attacks. This hook provides the means to implement - * the standardized ISN generation algorithm from RFC 6528 (see contrib/adons/tcp_isn), - * or any other desired algorithm as a replacement. - * Called from tcp_connect() and tcp_listen_input() when an ISN is needed for - * a new TCP connection, if TCP support (@ref LWIP_TCP) is enabled.\n - * Signature: u32_t my_hook_tcp_isn(const ip_addr_t* local_ip, u16_t local_port, const ip_addr_t* remote_ip, u16_t remote_port); - * - it may be necessary to use "struct ip_addr" (ip4_addr, ip6_addr) instead of "ip_addr_t" in function declarations\n - * Arguments: - * - local_ip: pointer to the local IP address of the connection - * - local_port: local port number of the connection (host-byte order) - * - remote_ip: pointer to the remote IP address of the connection - * - remote_port: remote port number of the connection (host-byte order)\n - * Return value: - * - the 32-bit Initial Sequence Number to use for the new TCP connection. - */ -#ifdef __DOXYGEN__ -#define LWIP_HOOK_TCP_ISN(local_ip, local_port, remote_ip, remote_port) -#endif - -/** - * LWIP_HOOK_IP4_INPUT(pbuf, input_netif): - * - called from ip_input() (IPv4) - * - pbuf: received struct pbuf passed to ip_input() - * - input_netif: struct netif on which the packet has been received - * Return values: - * - 0: Hook has not consumed the packet, packet is processed as normal - * - != 0: Hook has consumed the packet. - * If the hook consumed the packet, 'pbuf' is in the responsibility of the hook - * (i.e. free it when done). - */ -#ifdef __DOXYGEN__ -#define LWIP_HOOK_IP4_INPUT(pbuf, input_netif) -#endif - -/** - * LWIP_HOOK_IP4_ROUTE(dest): - * - called from ip_route() (IPv4) - * - dest: destination IPv4 address - * Returns the destination netif or NULL if no destination netif is found. In - * that case, ip_route() continues as normal. - */ -#ifdef __DOXYGEN__ -#define LWIP_HOOK_IP4_ROUTE() -#endif - -/** - * LWIP_HOOK_IP4_ROUTE_SRC(dest, src): - * - source-based routing for IPv4 (see LWIP_HOOK_IP4_ROUTE(), src may be NULL) - */ -#ifdef __DOXYGEN__ -#define LWIP_HOOK_IP4_ROUTE_SRC(dest, src) -#endif - -/** - * LWIP_HOOK_ETHARP_GET_GW(netif, dest): - * - called from etharp_output() (IPv4) - * - netif: the netif used for sending - * - dest: the destination IPv4 address - * Returns the IPv4 address of the gateway to handle the specified destination - * IPv4 address. If NULL is returned, the netif's default gateway is used. - * The returned address MUST be directly reachable on the specified netif! - * This function is meant to implement advanced IPv4 routing together with - * LWIP_HOOK_IP4_ROUTE(). The actual routing/gateway table implementation is - * not part of lwIP but can e.g. be hidden in the netif's state argument. -*/ -#ifdef __DOXYGEN__ -#define LWIP_HOOK_ETHARP_GET_GW(netif, dest) -#endif - -/** - * LWIP_HOOK_IP6_INPUT(pbuf, input_netif): - * - called from ip6_input() (IPv6) - * - pbuf: received struct pbuf passed to ip6_input() - * - input_netif: struct netif on which the packet has been received - * Return values: - * - 0: Hook has not consumed the packet, packet is processed as normal - * - != 0: Hook has consumed the packet. - * If the hook consumed the packet, 'pbuf' is in the responsibility of the hook - * (i.e. free it when done). - */ -#ifdef __DOXYGEN__ -#define LWIP_HOOK_IP6_INPUT(pbuf, input_netif) -#endif - -/** - * LWIP_HOOK_IP6_ROUTE(src, dest): - * - called from ip6_route() (IPv6) - * - src: sourc IPv6 address - * - dest: destination IPv6 address - * Returns the destination netif or NULL if no destination netif is found. In - * that case, ip6_route() continues as normal. - */ -#ifdef __DOXYGEN__ -#define LWIP_HOOK_IP6_ROUTE(src, dest) -#endif - -/** - * LWIP_HOOK_ND6_GET_GW(netif, dest): - * - called from nd6_get_next_hop_entry() (IPv6) - * - netif: the netif used for sending - * - dest: the destination IPv6 address - * Returns the IPv6 address of the next hop to handle the specified destination - * IPv6 address. If NULL is returned, a NDP-discovered router is used instead. - * The returned address MUST be directly reachable on the specified netif! - * This function is meant to implement advanced IPv6 routing together with - * LWIP_HOOK_IP6_ROUTE(). The actual routing/gateway table implementation is - * not part of lwIP but can e.g. be hidden in the netif's state argument. -*/ -#ifdef __DOXYGEN__ -#define LWIP_HOOK_ND6_GET_GW(netif, dest) -#endif - -/** - * LWIP_HOOK_VLAN_CHECK(netif, eth_hdr, vlan_hdr): - * - called from ethernet_input() if VLAN support is enabled - * - netif: struct netif on which the packet has been received - * - eth_hdr: struct eth_hdr of the packet - * - vlan_hdr: struct eth_vlan_hdr of the packet - * Return values: - * - 0: Packet must be dropped. - * - != 0: Packet must be accepted. - */ -#ifdef __DOXYGEN__ -#define LWIP_HOOK_VLAN_CHECK(netif, eth_hdr, vlan_hdr) -#endif - -/** - * LWIP_HOOK_VLAN_SET: - * Hook can be used to set prio_vid field of vlan_hdr. If you need to store data - * on per-netif basis to implement this callback, see @ref netif_cd. - * Called from ethernet_output() if VLAN support (@ref ETHARP_SUPPORT_VLAN) is enabled.\n - * Signature: s32_t my_hook_vlan_set(struct netif* netif, struct pbuf* pbuf, const struct eth_addr* src, const struct eth_addr* dst, u16_t eth_type);\n - * Arguments: - * - netif: struct netif that the packet will be sent through - * - p: struct pbuf packet to be sent - * - src: source eth address - * - dst: destination eth address - * - eth_type: ethernet type to packet to be sent\n - * - * - * Return values: - * - <0: Packet shall not contain VLAN header. - * - 0 <= return value <= 0xFFFF: Packet shall contain VLAN header. Return value is prio_vid in host byte order. - */ -#ifdef __DOXYGEN__ -#define LWIP_HOOK_VLAN_SET(netif, p, src, dst, eth_type) -#endif - -/** - * LWIP_HOOK_MEMP_AVAILABLE(memp_t_type): - * - called from memp_free() when a memp pool was empty and an item is now available - */ -#ifdef __DOXYGEN__ -#define LWIP_HOOK_MEMP_AVAILABLE(memp_t_type) -#endif - -/** - * LWIP_HOOK_UNKNOWN_ETH_PROTOCOL(pbuf, netif): - * Called from ethernet_input() when an unknown eth type is encountered. - * Return ERR_OK if packet is accepted, any error code otherwise. - * Payload points to ethernet header! - */ -#ifdef __DOXYGEN__ -#define LWIP_HOOK_UNKNOWN_ETH_PROTOCOL(pbuf, netif) -#endif -/** - * @} - */ - -/** -* LWIP_HOOK_ETHIP6_GET_GW(netif, dest): -* - called from ethip6_output() (IPv6) -* - netif: the netif used for sending -* - dest: the destination IPv6 address -* Returns the IPv6 address of the gateway to handle the specified destination -* IPv6 address. If NULL is returned, the netif's default gateway is used. -* The returned address MUST be reachable on the specified netif! -*/ -#if LWIP_IPV6_ROUTE_TABLE_SUPPORT -#define LWIP_HOOK_ETHIP6_GET_GW(netif, dest) ip6_get_gateway(netif, dest) -#endif - - -/* - --------------------------------------- - ---------- Debugging options ---------- - --------------------------------------- -*/ -/** - * @defgroup lwip_opts_debugmsg Debug messages - * @ingroup lwip_opts_debug - * @{ - */ -/** - * LWIP_DBG_MIN_LEVEL: After masking, the value of the debug is - * compared against this value. If it is smaller, then debugging - * messages are written. - * @see debugging_levels - */ -#if !defined LWIP_DBG_MIN_LEVEL || defined __DOXYGEN__ -#define LWIP_DBG_MIN_LEVEL LWIP_DBG_LEVEL_ALL -#endif - -/** - * LWIP_DBG_TYPES_ON: A mask that can be used to globally enable/disable - * debug messages of certain types. - * @see debugging_levels - */ -#if !defined LWIP_DBG_TYPES_ON || defined __DOXYGEN__ -#define LWIP_DBG_TYPES_ON LWIP_DBG_ON -#endif - -/** - * ETHARP_DEBUG: Enable debugging in etharp.c. - */ -#if !defined ETHARP_DEBUG || defined __DOXYGEN__ -#define ETHARP_DEBUG LWIP_DBG_OFF -#endif - -/** - * NETIF_DEBUG: Enable debugging in netif.c. - */ -#if !defined NETIF_DEBUG || defined __DOXYGEN__ -#define NETIF_DEBUG LWIP_DBG_OFF -#endif - -/** - * PBUF_DEBUG: Enable debugging in pbuf.c. - */ -#if !defined PBUF_DEBUG || defined __DOXYGEN__ -#define PBUF_DEBUG LWIP_DBG_OFF -#endif - -/** - * API_LIB_DEBUG: Enable debugging in api_lib.c. - */ -#if !defined API_LIB_DEBUG || defined __DOXYGEN__ -#define API_LIB_DEBUG LWIP_DBG_OFF -#endif - -/** - * API_MSG_DEBUG: Enable debugging in api_msg.c. - */ -#if !defined API_MSG_DEBUG || defined __DOXYGEN__ -#define API_MSG_DEBUG LWIP_DBG_OFF -#endif - -/** - * SOCKETS_DEBUG: Enable debugging in sockets.c. - */ -#if !defined SOCKETS_DEBUG || defined __DOXYGEN__ -#define SOCKETS_DEBUG LWIP_DBG_OFF -#endif - -/** - * ICMP_DEBUG: Enable debugging in icmp.c. - */ -#if !defined ICMP_DEBUG || defined __DOXYGEN__ -#define ICMP_DEBUG LWIP_DBG_OFF -#endif - -/** - * IGMP_DEBUG: Enable debugging in igmp.c. - */ -#if !defined IGMP_DEBUG || defined __DOXYGEN__ -#define IGMP_DEBUG LWIP_DBG_OFF -#endif - -/** - * INET_DEBUG: Enable debugging in inet.c. - */ -#if !defined INET_DEBUG || defined __DOXYGEN__ -#define INET_DEBUG LWIP_DBG_OFF -#endif - -/** - * IP_DEBUG: Enable debugging for IP. - */ -#if !defined IP_DEBUG || defined __DOXYGEN__ -#define IP_DEBUG LWIP_DBG_OFF -#endif - -/** - * IP_REASS_DEBUG: Enable debugging in ip_frag.c for both frag & reass. - */ -#if !defined IP_REASS_DEBUG || defined __DOXYGEN__ -#define IP_REASS_DEBUG LWIP_DBG_OFF -#endif - -/** - * RAW_DEBUG: Enable debugging in raw.c. - */ -#if !defined RAW_DEBUG || defined __DOXYGEN__ -#define RAW_DEBUG LWIP_DBG_OFF -#endif - -/** - * MEM_DEBUG: Enable debugging in mem.c. - */ -#if !defined MEM_DEBUG || defined __DOXYGEN__ -#define MEM_DEBUG LWIP_DBG_OFF -#endif - -/** - * MEMP_DEBUG: Enable debugging in memp.c. - */ -#if !defined MEMP_DEBUG || defined __DOXYGEN__ -#define MEMP_DEBUG LWIP_DBG_OFF -#endif - -/** - * SYS_DEBUG: Enable debugging in sys.c. - */ -#if !defined SYS_DEBUG || defined __DOXYGEN__ -#define SYS_DEBUG LWIP_DBG_OFF -#endif - -/** - * TIMERS_DEBUG: Enable debugging in timers.c. - */ -#if !defined TIMERS_DEBUG || defined __DOXYGEN__ -#define TIMERS_DEBUG LWIP_DBG_OFF -#endif - -/** - * TCP_DEBUG: Enable debugging for TCP. - */ -#if !defined TCP_DEBUG || defined __DOXYGEN__ -#define TCP_DEBUG LWIP_DBG_OFF -#endif - -/** - * TCP_INPUT_DEBUG: Enable debugging in tcp_in.c for incoming debug. - */ -#if !defined TCP_INPUT_DEBUG || defined __DOXYGEN__ -#define TCP_INPUT_DEBUG LWIP_DBG_OFF -#endif - -/** - * TCP_FR_DEBUG: Enable debugging in tcp_in.c for fast retransmit. - */ -#if !defined TCP_FR_DEBUG || defined __DOXYGEN__ -#define TCP_FR_DEBUG LWIP_DBG_OFF -#endif - -/** - * TCP_RTO_DEBUG: Enable debugging in TCP for retransmit - * timeout. - */ -#if !defined TCP_RTO_DEBUG || defined __DOXYGEN__ -#define TCP_RTO_DEBUG LWIP_DBG_OFF -#endif - -/** - * TCP_CWND_DEBUG: Enable debugging for TCP congestion window. - */ -#if !defined TCP_CWND_DEBUG || defined __DOXYGEN__ -#define TCP_CWND_DEBUG LWIP_DBG_OFF -#endif - -/** - * TCP_WND_DEBUG: Enable debugging in tcp_in.c for window updating. - */ -#if !defined TCP_WND_DEBUG || defined __DOXYGEN__ -#define TCP_WND_DEBUG LWIP_DBG_OFF -#endif - -/** - * TCP_OUTPUT_DEBUG: Enable debugging in tcp_out.c output functions. - */ -#if !defined TCP_OUTPUT_DEBUG || defined __DOXYGEN__ -#define TCP_OUTPUT_DEBUG LWIP_DBG_OFF -#endif - -/** - * TCP_RST_DEBUG: Enable debugging for TCP with the RST message. - */ -#if !defined TCP_RST_DEBUG || defined __DOXYGEN__ -#define TCP_RST_DEBUG LWIP_DBG_OFF -#endif - -/** - * TCP_QLEN_DEBUG: Enable debugging for TCP queue lengths. - */ -#if !defined TCP_QLEN_DEBUG || defined __DOXYGEN__ -#define TCP_QLEN_DEBUG LWIP_DBG_OFF -#endif - -/** - * UDP_DEBUG: Enable debugging in UDP. - */ -#if !defined UDP_DEBUG || defined __DOXYGEN__ -#define UDP_DEBUG LWIP_DBG_OFF -#endif - -/** - * TCPIP_DEBUG: Enable debugging in tcpip.c. - */ -#if !defined TCPIP_DEBUG || defined __DOXYGEN__ -#define TCPIP_DEBUG LWIP_DBG_OFF -#endif - -/** - * SLIP_DEBUG: Enable debugging in slipif.c. - */ -#if !defined SLIP_DEBUG || defined __DOXYGEN__ -#define SLIP_DEBUG LWIP_DBG_OFF -#endif - -/** - * DHCP_DEBUG: Enable debugging in dhcp.c. - */ -#if !defined DHCP_DEBUG || defined __DOXYGEN__ -#define DHCP_DEBUG LWIP_DBG_OFF -#endif - -/** - * AUTOIP_DEBUG: Enable debugging in autoip.c. - */ -#if !defined AUTOIP_DEBUG || defined __DOXYGEN__ -#define AUTOIP_DEBUG LWIP_DBG_OFF -#endif - -/** - * DNS_DEBUG: Enable debugging for DNS. - */ -#if !defined DNS_DEBUG || defined __DOXYGEN__ -#define DNS_DEBUG LWIP_DBG_OFF -#endif - -/** - * IP6_DEBUG: Enable debugging for IPv6. - */ -#if !defined IP6_DEBUG || defined __DOXYGEN__ -#define IP6_DEBUG LWIP_DBG_OFF -#endif - -/** - * LWIP_IP_DEBUG_TARGET: Enable selective output of IP-level debug for - * a particular IP address. - */ -#ifndef LWIP_IP_DEBUG_TARGET -#define LWIP_IP_DEBUG_TARGET 0 -#endif - -/** - * @} - */ - -/* - -------------------------------------------------- - ---------- Performance tracking options ---------- - -------------------------------------------------- -*/ -/** - * @defgroup lwip_opts_perf Performance - * @ingroup lwip_opts_debug - * @{ - */ -/** - * LWIP_PERF: Enable performance testing for lwIP - * (if enabled, arch/perf.h is included) - */ -#if !defined LWIP_PERF || defined __DOXYGEN__ -#define LWIP_PERF 0 -#endif -/** - * @} - */ - -#endif /* LWIP_HDR_OPT_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/pbuf.h b/third_party/lwip/repo/lwip/src/include/lwip/pbuf.h deleted file mode 100644 index 9996770dfb074f..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/pbuf.h +++ /dev/null @@ -1,269 +0,0 @@ -/** - * @file - * pbuf API - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ - -#ifndef LWIP_HDR_PBUF_H -#define LWIP_HDR_PBUF_H - -#include "lwip/opt.h" -#include "lwip/err.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** LWIP_SUPPORT_CUSTOM_PBUF==1: Custom pbufs behave much like their pbuf type - * but they are allocated by external code (initialised by calling - * pbuf_alloced_custom()) and when pbuf_free gives up their last reference, they - * are freed by calling pbuf_custom->custom_free_function(). - * Currently, the pbuf_custom code is only needed for one specific configuration - * of IP_FRAG, unless required by external driver/application code. */ -#ifndef LWIP_SUPPORT_CUSTOM_PBUF -#define LWIP_SUPPORT_CUSTOM_PBUF ((IP_FRAG && !LWIP_NETIF_TX_SINGLE_PBUF) || (LWIP_IPV6 && LWIP_IPV6_FRAG)) -#endif - -/* @todo: We need a mechanism to prevent wasting memory in every pbuf - (TCP vs. UDP, IPv4 vs. IPv6: UDP/IPv4 packets may waste up to 28 bytes) */ - -#define PBUF_TRANSPORT_HLEN 20 -#if LWIP_IPV6 -#define PBUF_IP_HLEN 40 -#else -#define PBUF_IP_HLEN 20 -#endif - -/** - * @ingroup pbuf - * Enumeration of pbuf layers - */ -typedef enum { - /** Includes spare room for transport layer header, e.g. UDP header. - * Use this if you intend to pass the pbuf to functions like udp_send(). - */ - PBUF_TRANSPORT, - /** Includes spare room for IP header. - * Use this if you intend to pass the pbuf to functions like raw_send(). - */ - PBUF_IP, - /** Includes spare room for link layer header (ethernet header). - * Use this if you intend to pass the pbuf to functions like ethernet_output(). - * @see PBUF_LINK_HLEN - */ - PBUF_LINK, - /** Includes spare room for additional encapsulation header before ethernet - * headers (e.g. 802.11). - * Use this if you intend to pass the pbuf to functions like netif->linkoutput(). - * @see PBUF_LINK_ENCAPSULATION_HLEN - */ - PBUF_RAW_TX, - /** Use this for input packets in a netif driver when calling netif->input() - * in the most common case - ethernet-layer netif driver. */ - PBUF_RAW -} pbuf_layer; - -/** - * @ingroup pbuf - * Enumeration of pbuf types - */ -typedef enum { - /** pbuf data is stored in RAM, used for TX mostly, struct pbuf and its payload - are allocated in one piece of contiguous memory (so the first payload byte - can be calculated from struct pbuf). - pbuf_alloc() allocates PBUF_RAM pbufs as unchained pbufs (although that might - change in future versions). - This should be used for all OUTGOING packets (TX).*/ - PBUF_RAM, - /** pbuf data is stored in ROM, i.e. struct pbuf and its payload are located in - totally different memory areas. Since it points to ROM, payload does not - have to be copied when queued for transmission. */ - PBUF_ROM, - /** pbuf comes from the pbuf pool. Much like PBUF_ROM but payload might change - so it has to be duplicated when queued before transmitting, depending on - who has a 'ref' to it. */ - PBUF_REF, - /** pbuf payload refers to RAM. This one comes from a pool and should be used - for RX. Payload can be chained (scatter-gather RX) but like PBUF_RAM, struct - pbuf and its payload are allocated in one piece of contiguous memory (so - the first payload byte can be calculated from struct pbuf). - Don't use this for TX, if the pool becomes empty e.g. because of TCP queuing, - you are unable to receive TCP acks! */ - PBUF_POOL -} pbuf_type; - - -/** indicates this packet's data should be immediately passed to the application */ -#define PBUF_FLAG_PUSH 0x01U -/** indicates this is a custom pbuf: pbuf_free calls pbuf_custom->custom_free_function() - when the last reference is released (plus custom PBUF_RAM cannot be trimmed) */ -#define PBUF_FLAG_IS_CUSTOM 0x02U -/** indicates this pbuf is UDP multicast to be looped back */ -#define PBUF_FLAG_MCASTLOOP 0x04U -/** indicates this pbuf was received as link-level broadcast */ -#define PBUF_FLAG_LLBCAST 0x08U -/** indicates this pbuf was received as link-level multicast */ -#define PBUF_FLAG_LLMCAST 0x10U -/** indicates this pbuf includes a TCP FIN flag */ -#define PBUF_FLAG_TCP_FIN 0x20U - -/** Main packet buffer struct */ -struct pbuf { - /** next pbuf in singly linked pbuf chain */ - struct pbuf *next; - - /** pointer to the actual data in the buffer */ - void *payload; - - /** - * total length of this buffer and all next buffers in chain - * belonging to the same packet. - * - * For non-queue packet chains this is the invariant: - * p->tot_len == p->len + (p->next? p->next->tot_len: 0) - */ - u16_t tot_len; - - /** length of this buffer */ - u16_t len; - - /** pbuf_type as u8_t instead of enum to save space */ - u8_t /*pbuf_type*/ type; - - /** misc flags */ - u8_t flags; - - /** - * the reference count always equals the number of pointers - * that refer to this pbuf. This can be pointers from an application, - * the stack itself, or pbuf->next pointers from a chain. - */ - u16_t ref; - -#if LWIP_PBUF_FROM_CUSTOM_POOLS - /** Pool from which pbuf was allocated */ - u16_t pool; -#endif -}; - - -/** Helper struct for const-correctness only. - * The only meaning of this one is to provide a const payload pointer - * for PBUF_ROM type. - */ -struct pbuf_rom { - /** next pbuf in singly linked pbuf chain */ - struct pbuf *next; - - /** pointer to the actual data in the buffer */ - const void *payload; -}; - -#if LWIP_SUPPORT_CUSTOM_PBUF -/** Prototype for a function to free a custom pbuf */ -typedef void (*pbuf_free_custom_fn)(struct pbuf *p); - -/** A custom pbuf: like a pbuf, but following a function pointer to free it. */ -struct pbuf_custom { - /** The actual pbuf */ - struct pbuf pbuf; - /** This function is called when pbuf_free deallocates this pbuf(_custom) */ - pbuf_free_custom_fn custom_free_function; -}; -#endif /* LWIP_SUPPORT_CUSTOM_PBUF */ - -/** Define this to 0 to prevent freeing ooseq pbufs when the PBUF_POOL is empty */ -#ifndef PBUF_POOL_FREE_OOSEQ -#define PBUF_POOL_FREE_OOSEQ 1 -#endif /* PBUF_POOL_FREE_OOSEQ */ -#if LWIP_TCP && TCP_QUEUE_OOSEQ && NO_SYS && PBUF_POOL_FREE_OOSEQ -extern volatile u8_t pbuf_free_ooseq_pending; -void pbuf_free_ooseq(void); -/** When not using sys_check_timeouts(), call PBUF_CHECK_FREE_OOSEQ() - at regular intervals from main level to check if ooseq pbufs need to be - freed! */ -#define PBUF_CHECK_FREE_OOSEQ() do { if(pbuf_free_ooseq_pending) { \ - /* pbuf_alloc() reported PBUF_POOL to be empty -> try to free some \ - ooseq queued pbufs now */ \ - pbuf_free_ooseq(); }}while(0) -#else /* LWIP_TCP && TCP_QUEUE_OOSEQ && NO_SYS && PBUF_POOL_FREE_OOSEQ */ - /* Otherwise declare an empty PBUF_CHECK_FREE_OOSEQ */ - #define PBUF_CHECK_FREE_OOSEQ() -#endif /* LWIP_TCP && TCP_QUEUE_OOSEQ && NO_SYS && PBUF_POOL_FREE_OOSEQ*/ - -/* Initializes the pbuf module. This call is empty for now, but may not be in future. */ -#define pbuf_init() - -struct pbuf *pbuf_alloc(pbuf_layer l, u16_t length, pbuf_type type); -#if LWIP_SUPPORT_CUSTOM_PBUF -struct pbuf *pbuf_alloced_custom(pbuf_layer l, u16_t length, pbuf_type type, - struct pbuf_custom *p, void *payload_mem, - u16_t payload_mem_len); -#endif /* LWIP_SUPPORT_CUSTOM_PBUF */ -struct pbuf *pbuf_rightsize(struct pbuf *p, s16_t offset); -void pbuf_realloc(struct pbuf *p, u16_t size); -u8_t pbuf_header(struct pbuf *p, s16_t header_size); -u8_t pbuf_header_force(struct pbuf *p, s16_t header_size); -void pbuf_ref(struct pbuf *p); -u8_t pbuf_free(struct pbuf *p); -u16_t pbuf_clen(const struct pbuf *p); -void pbuf_cat(struct pbuf *head, struct pbuf *tail); -void pbuf_chain(struct pbuf *head, struct pbuf *tail); -struct pbuf *pbuf_dechain(struct pbuf *p); -err_t pbuf_copy(struct pbuf *p_to, const struct pbuf *p_from); -u16_t pbuf_copy_partial(const struct pbuf *p, void *dataptr, u16_t len, u16_t offset); -err_t pbuf_take(struct pbuf *buf, const void *dataptr, u16_t len); -err_t pbuf_take_at(struct pbuf *buf, const void *dataptr, u16_t len, u16_t offset); -struct pbuf *pbuf_skip(struct pbuf* in, u16_t in_offset, u16_t* out_offset); -struct pbuf *pbuf_coalesce(struct pbuf *p, pbuf_layer layer); -#if LWIP_CHECKSUM_ON_COPY -err_t pbuf_fill_chksum(struct pbuf *p, u16_t start_offset, const void *dataptr, - u16_t len, u16_t *chksum); -#endif /* LWIP_CHECKSUM_ON_COPY */ -#if LWIP_TCP && TCP_QUEUE_OOSEQ && LWIP_WND_SCALE -void pbuf_split_64k(struct pbuf *p, struct pbuf **rest); -#endif /* LWIP_TCP && TCP_QUEUE_OOSEQ && LWIP_WND_SCALE */ - -u8_t pbuf_get_at(const struct pbuf* p, u16_t offset); -int pbuf_try_get_at(const struct pbuf* p, u16_t offset); -void pbuf_put_at(struct pbuf* p, u16_t offset, u8_t data); -u16_t pbuf_memcmp(const struct pbuf* p, u16_t offset, const void* s2, u16_t n); -u16_t pbuf_memfind(const struct pbuf* p, const void* mem, u16_t mem_len, u16_t start_offset); -u16_t pbuf_strstr(const struct pbuf* p, const char* substr); - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_PBUF_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/priv/api_msg.h b/third_party/lwip/repo/lwip/src/include/lwip/priv/api_msg.h deleted file mode 100644 index f12b8b7d4f732a..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/priv/api_msg.h +++ /dev/null @@ -1,216 +0,0 @@ -/** - * @file - * netconn API lwIP internal implementations (do not use in application code) - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_API_MSG_H -#define LWIP_HDR_API_MSG_H - -#include "lwip/opt.h" - -#if LWIP_NETCONN || LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */ -/* Note: Netconn API is always available when sockets are enabled - - * sockets are implemented on top of them */ - -#include "lwip/arch.h" -#include "lwip/ip_addr.h" -#include "lwip/err.h" -#include "lwip/sys.h" -#include "lwip/igmp.h" -#include "lwip/api.h" -#include "lwip/priv/tcpip_priv.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#if LWIP_MPU_COMPATIBLE -#if LWIP_NETCONN_SEM_PER_THREAD -#define API_MSG_M_DEF_SEM(m) *m -#else -#define API_MSG_M_DEF_SEM(m) API_MSG_M_DEF(m) -#endif -#else /* LWIP_MPU_COMPATIBLE */ -#define API_MSG_M_DEF_SEM(m) API_MSG_M_DEF(m) -#endif /* LWIP_MPU_COMPATIBLE */ - -/* For the netconn API, these values are use as a bitmask! */ -#define NETCONN_SHUT_RD 1 -#define NETCONN_SHUT_WR 2 -#define NETCONN_SHUT_RDWR (NETCONN_SHUT_RD | NETCONN_SHUT_WR) - -/* IP addresses and port numbers are expected to be in - * the same byte order as in the corresponding pcb. - */ -/** This struct includes everything that is necessary to execute a function - for a netconn in another thread context (mainly used to process netconns - in the tcpip_thread context to be thread safe). */ -struct api_msg { - /** The netconn which to process - always needed: it includes the semaphore - which is used to block the application thread until the function finished. */ - struct netconn *conn; - /** The return value of the function executed in tcpip_thread. */ - err_t err; - /** Depending on the executed function, one of these union members is used */ - union { - /** used for lwip_netconn_do_send */ - struct netbuf *b; - /** used for lwip_netconn_do_newconn */ - struct { - u8_t proto; - } n; - /** used for lwip_netconn_do_bind and lwip_netconn_do_connect */ - struct { - API_MSG_M_DEF_C(ip_addr_t, ipaddr); - u16_t port; - } bc; - /** used for lwip_netconn_do_getaddr */ - struct { - ip_addr_t API_MSG_M_DEF(ipaddr); - u16_t API_MSG_M_DEF(port); - u8_t local; - } ad; - /** used for lwip_netconn_do_write */ - struct { - const void *dataptr; - size_t len; - u8_t apiflags; -#if LWIP_SO_SNDTIMEO - u32_t time_started; -#endif /* LWIP_SO_SNDTIMEO */ - } w; - /** used for lwip_netconn_do_recv */ - struct { - u32_t len; - } r; -#if LWIP_TCP - /** used for lwip_netconn_do_close (/shutdown) */ - struct { - u8_t shut; -#if LWIP_SO_SNDTIMEO || LWIP_SO_LINGER - u32_t time_started; -#else /* LWIP_SO_SNDTIMEO || LWIP_SO_LINGER */ - u8_t polls_left; -#endif /* LWIP_SO_SNDTIMEO || LWIP_SO_LINGER */ - } sd; -#endif /* LWIP_TCP */ -#if LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) - /** used for lwip_netconn_do_join_leave_group */ - struct { - API_MSG_M_DEF_C(ip_addr_t, multiaddr); - API_MSG_M_DEF_C(ip_addr_t, netif_addr); - enum netconn_igmp join_or_leave; - } jl; -#endif /* LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) */ -#if TCP_LISTEN_BACKLOG - struct { - u8_t backlog; - } lb; -#endif /* TCP_LISTEN_BACKLOG */ - } msg; -#if LWIP_NETCONN_SEM_PER_THREAD - sys_sem_t* op_completed_sem; -#endif /* LWIP_NETCONN_SEM_PER_THREAD */ -}; - -#if LWIP_NETCONN_SEM_PER_THREAD -#define LWIP_API_MSG_SEM(msg) ((msg)->op_completed_sem) -#else /* LWIP_NETCONN_SEM_PER_THREAD */ -#define LWIP_API_MSG_SEM(msg) (&(msg)->conn->op_completed) -#endif /* LWIP_NETCONN_SEM_PER_THREAD */ - - -#if LWIP_DNS -/** As lwip_netconn_do_gethostbyname requires more arguments but doesn't require a netconn, - it has its own struct (to avoid struct api_msg getting bigger than necessary). - lwip_netconn_do_gethostbyname must be called using tcpip_callback instead of tcpip_apimsg - (see netconn_gethostbyname). */ -struct dns_api_msg { - /** Hostname to query or dotted IP address string */ -#if LWIP_MPU_COMPATIBLE - char name[DNS_MAX_NAME_LENGTH]; -#else /* LWIP_MPU_COMPATIBLE */ - const char *name; -#endif /* LWIP_MPU_COMPATIBLE */ - /** The resolved address is stored here */ - ip_addr_t API_MSG_M_DEF(addr); -#if LWIP_IPV4 && LWIP_IPV6 - /** Type of resolve call */ - u8_t dns_addrtype; -#endif /* LWIP_IPV4 && LWIP_IPV6 */ - /** This semaphore is posted when the name is resolved, the application thread - should wait on it. */ - sys_sem_t API_MSG_M_DEF_SEM(sem); - /** Errors are given back here */ - err_t API_MSG_M_DEF(err); -}; -#endif /* LWIP_DNS */ - -#if LWIP_TCP -extern u8_t netconn_aborted; -#endif /* LWIP_TCP */ - -void lwip_netconn_do_newconn (void *m); -void lwip_netconn_do_delconn (void *m); -void lwip_netconn_do_bind (void *m); -void lwip_netconn_do_connect (void *m); -void lwip_netconn_do_disconnect (void *m); -void lwip_netconn_do_listen (void *m); -void lwip_netconn_do_send (void *m); -void lwip_netconn_do_recv (void *m); -#if TCP_LISTEN_BACKLOG -void lwip_netconn_do_accepted (void *m); -#endif /* TCP_LISTEN_BACKLOG */ -void lwip_netconn_do_write (void *m); -void lwip_netconn_do_getaddr (void *m); -void lwip_netconn_do_close (void *m); -void lwip_netconn_do_shutdown (void *m); -#if LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) -void lwip_netconn_do_join_leave_group(void *m); -#endif /* LWIP_IGMP || (LWIP_IPV6 && LWIP_IPV6_MLD) */ - -#if LWIP_DNS -void lwip_netconn_do_gethostbyname(void *arg); -#endif /* LWIP_DNS */ - -struct netconn* netconn_alloc(enum netconn_type t, netconn_callback callback); -void netconn_free(struct netconn *conn); - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_NETCONN || LWIP_SOCKET */ - -#endif /* LWIP_HDR_API_MSG_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/priv/memp_priv.h b/third_party/lwip/repo/lwip/src/include/lwip/priv/memp_priv.h deleted file mode 100644 index f246061dadff8c..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/priv/memp_priv.h +++ /dev/null @@ -1,183 +0,0 @@ -/** - * @file - * memory pools lwIP internal implementations (do not use in application code) - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ - -#ifndef LWIP_HDR_MEMP_PRIV_H -#define LWIP_HDR_MEMP_PRIV_H - -#include "lwip/opt.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#include "lwip/mem.h" - -#if MEMP_OVERFLOW_CHECK -/* if MEMP_OVERFLOW_CHECK is turned on, we reserve some bytes at the beginning - * and at the end of each element, initialize them as 0xcd and check - * them later. */ -/* If MEMP_OVERFLOW_CHECK is >= 2, on every call to memp_malloc or memp_free, - * every single element in each pool is checked! - * This is VERY SLOW but also very helpful. */ -/* MEMP_SANITY_REGION_BEFORE and MEMP_SANITY_REGION_AFTER can be overridden in - * lwipopts.h to change the amount reserved for checking. */ -#ifndef MEMP_SANITY_REGION_BEFORE -#define MEMP_SANITY_REGION_BEFORE 16 -#endif /* MEMP_SANITY_REGION_BEFORE*/ -#if MEMP_SANITY_REGION_BEFORE > 0 -#define MEMP_SANITY_REGION_BEFORE_ALIGNED LWIP_MEM_ALIGN_SIZE(MEMP_SANITY_REGION_BEFORE) -#else -#define MEMP_SANITY_REGION_BEFORE_ALIGNED 0 -#endif /* MEMP_SANITY_REGION_BEFORE*/ -#ifndef MEMP_SANITY_REGION_AFTER -#define MEMP_SANITY_REGION_AFTER 16 -#endif /* MEMP_SANITY_REGION_AFTER*/ -#if MEMP_SANITY_REGION_AFTER > 0 -#define MEMP_SANITY_REGION_AFTER_ALIGNED LWIP_MEM_ALIGN_SIZE(MEMP_SANITY_REGION_AFTER) -#else -#define MEMP_SANITY_REGION_AFTER_ALIGNED 0 -#endif /* MEMP_SANITY_REGION_AFTER*/ - -/* MEMP_SIZE: save space for struct memp and for sanity check */ -#define MEMP_SIZE (LWIP_MEM_ALIGN_SIZE(sizeof(struct memp)) + MEMP_SANITY_REGION_BEFORE_ALIGNED) -#define MEMP_ALIGN_SIZE(x) (LWIP_MEM_ALIGN_SIZE(x) + MEMP_SANITY_REGION_AFTER_ALIGNED) - -#else /* MEMP_OVERFLOW_CHECK */ - -/* No sanity checks - * We don't need to preserve the struct memp while not allocated, so we - * can save a little space and set MEMP_SIZE to 0. - */ -#define MEMP_SIZE 0 -#define MEMP_ALIGN_SIZE(x) (LWIP_MEM_ALIGN_SIZE(x)) - -#endif /* MEMP_OVERFLOW_CHECK */ - -#if !MEMP_MEM_MALLOC || MEMP_OVERFLOW_CHECK -struct memp { - struct memp *next; -#if MEMP_OVERFLOW_CHECK - const char *file; - int line; -#endif /* MEMP_OVERFLOW_CHECK */ -}; -#endif /* !MEMP_MEM_MALLOC || MEMP_OVERFLOW_CHECK */ - -#if MEM_USE_POOLS && MEMP_USE_CUSTOM_POOLS -/* Use a helper type to get the start and end of the user "memory pools" for mem_malloc */ -typedef enum { - /* Get the first (via: - MEMP_POOL_HELPER_START = ((u8_t) 1*MEMP_POOL_A + 0*MEMP_POOL_B + 0*MEMP_POOL_C + 0)*/ - MEMP_POOL_HELPER_FIRST = ((u8_t) -#define LWIP_MEMPOOL(name,num,size,desc) -#define LWIP_MALLOC_MEMPOOL_START 1 -#define LWIP_MALLOC_MEMPOOL(num, size) * MEMP_POOL_##size + 0 -#define LWIP_MALLOC_MEMPOOL_END -#include "lwip/priv/memp_std.h" - ) , - /* Get the last (via: - MEMP_POOL_HELPER_END = ((u8_t) 0 + MEMP_POOL_A*0 + MEMP_POOL_B*0 + MEMP_POOL_C*1) */ - MEMP_POOL_HELPER_LAST = ((u8_t) -#define LWIP_MEMPOOL(name,num,size,desc) -#define LWIP_MALLOC_MEMPOOL_START -#define LWIP_MALLOC_MEMPOOL(num, size) 0 + MEMP_POOL_##size * -#define LWIP_MALLOC_MEMPOOL_END 1 -#include "lwip/priv/memp_std.h" - ) -} memp_pool_helper_t; - -/* The actual start and stop values are here (cast them over) - We use this helper type and these defines so we can avoid using const memp_t values */ -#define MEMP_POOL_FIRST ((memp_t) MEMP_POOL_HELPER_FIRST) -#define MEMP_POOL_LAST ((memp_t) MEMP_POOL_HELPER_LAST) -#endif /* MEM_USE_POOLS && MEMP_USE_CUSTOM_POOLS */ - -/** Memory pool descriptor */ -struct memp_desc { -#if defined(LWIP_DEBUG) || MEMP_OVERFLOW_CHECK || LWIP_STATS_DISPLAY - /** Textual description */ - const char *desc; -#endif /* LWIP_DEBUG || MEMP_OVERFLOW_CHECK || LWIP_STATS_DISPLAY */ -#if MEMP_STATS - /** Statistics */ - struct stats_mem *stats; -#endif - - /** Element size */ - u16_t size; - -#if !MEMP_MEM_MALLOC - /** Number of elements */ - u16_t num; - - /** Base address */ - u8_t *base; - - /** First free element of each pool. Elements form a linked list. */ - struct memp **tab; -#endif /* MEMP_MEM_MALLOC */ -}; - -#if defined(LWIP_DEBUG) || MEMP_OVERFLOW_CHECK || LWIP_STATS_DISPLAY -#define DECLARE_LWIP_MEMPOOL_DESC(desc) (desc), -#else -#define DECLARE_LWIP_MEMPOOL_DESC(desc) -#endif - -#if MEMP_STATS -#define LWIP_MEMPOOL_DECLARE_STATS_INSTANCE(name) static struct stats_mem name; -#define LWIP_MEMPOOL_DECLARE_STATS_REFERENCE(name) &name, -#else -#define LWIP_MEMPOOL_DECLARE_STATS_INSTANCE(name) -#define LWIP_MEMPOOL_DECLARE_STATS_REFERENCE(name) -#endif - -void memp_init_pool(const struct memp_desc *desc); - -#if MEMP_OVERFLOW_CHECK -void *memp_malloc_pool_fn(const struct memp_desc* desc, const char* file, const int line); -#define memp_malloc_pool(d) memp_malloc_pool_fn((d), __FILE__, __LINE__) -#else -void *memp_malloc_pool(const struct memp_desc *desc); -#endif -void memp_free_pool(const struct memp_desc* desc, void *mem); - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_MEMP_PRIV_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/priv/memp_std.h b/third_party/lwip/repo/lwip/src/include/lwip/priv/memp_std.h deleted file mode 100644 index d3910674446cf6..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/priv/memp_std.h +++ /dev/null @@ -1,146 +0,0 @@ -/** - * @file - * lwIP internal memory pools (do not use in application code) - * This file is deliberately included multiple times: once with empty - * definition of LWIP_MEMPOOL() to handle all includes and multiple times - * to build up various lists of mem pools. - */ - -/* - * SETUP: Make sure we define everything we will need. - * - * We have create three types of pools: - * 1) MEMPOOL - standard pools - * 2) MALLOC_MEMPOOL - to be used by mem_malloc in mem.c - * 3) PBUF_MEMPOOL - a mempool of pbuf's, so include space for the pbuf struct - * - * If the include'r doesn't require any special treatment of each of the types - * above, then will declare #2 & #3 to be just standard mempools. - */ -#ifndef LWIP_MALLOC_MEMPOOL -/* This treats "malloc pools" just like any other pool. - The pools are a little bigger to provide 'size' as the amount of user data. */ -#define LWIP_MALLOC_MEMPOOL(num, size) LWIP_MEMPOOL(POOL_##size, num, (size + LWIP_MEM_ALIGN_SIZE(sizeof(struct memp_malloc_helper))), "MALLOC_"#size) -#define LWIP_MALLOC_MEMPOOL_START -#define LWIP_MALLOC_MEMPOOL_END -#endif /* LWIP_MALLOC_MEMPOOL */ - -#ifndef LWIP_PBUF_MEMPOOL -/* This treats "pbuf pools" just like any other pool. - * Allocates buffers for a pbuf struct AND a payload size */ -#define LWIP_PBUF_MEMPOOL(name, num, payload, desc) LWIP_MEMPOOL(name, num, (MEMP_ALIGN_SIZE(sizeof(struct pbuf)) + MEMP_ALIGN_SIZE(payload)), desc) -#endif /* LWIP_PBUF_MEMPOOL */ - - -/* - * A list of internal pools used by LWIP. - * - * LWIP_MEMPOOL(pool_name, number_elements, element_size, pool_description) - * creates a pool name MEMP_pool_name. description is used in stats.c - */ -#if LWIP_RAW -LWIP_MEMPOOL(RAW_PCB, MEMP_NUM_RAW_PCB, sizeof(struct raw_pcb), "RAW_PCB") -#endif /* LWIP_RAW */ - -#if LWIP_UDP -LWIP_MEMPOOL(UDP_PCB, MEMP_NUM_UDP_PCB, sizeof(struct udp_pcb), "UDP_PCB") -#endif /* LWIP_UDP */ - -#if LWIP_TCP -LWIP_MEMPOOL(TCP_PCB, MEMP_NUM_TCP_PCB, sizeof(struct tcp_pcb), "TCP_PCB") -LWIP_MEMPOOL(TCP_PCB_LISTEN, MEMP_NUM_TCP_PCB_LISTEN, sizeof(struct tcp_pcb_listen), "TCP_PCB_LISTEN") -LWIP_MEMPOOL(TCP_SEG, MEMP_NUM_TCP_SEG, sizeof(struct tcp_seg), "TCP_SEG") -#endif /* LWIP_TCP */ - -#if LWIP_IPV4 && IP_REASSEMBLY -LWIP_MEMPOOL(REASSDATA, MEMP_NUM_REASSDATA, sizeof(struct ip_reassdata), "REASSDATA") -#endif /* LWIP_IPV4 && IP_REASSEMBLY */ -#if (IP_FRAG && !LWIP_NETIF_TX_SINGLE_PBUF) || (LWIP_IPV6 && LWIP_IPV6_FRAG) -LWIP_MEMPOOL(FRAG_PBUF, MEMP_NUM_FRAG_PBUF, sizeof(struct pbuf_custom_ref),"FRAG_PBUF") -#endif /* IP_FRAG && !LWIP_NETIF_TX_SINGLE_PBUF || (LWIP_IPV6 && LWIP_IPV6_FRAG) */ - -#if LWIP_NETCONN || LWIP_SOCKET -LWIP_MEMPOOL(NETBUF, MEMP_NUM_NETBUF, sizeof(struct netbuf), "NETBUF") -LWIP_MEMPOOL(NETCONN, MEMP_NUM_NETCONN, sizeof(struct netconn), "NETCONN") -#endif /* LWIP_NETCONN || LWIP_SOCKET */ - -#if NO_SYS==0 -LWIP_MEMPOOL(TCPIP_MSG_API, MEMP_NUM_TCPIP_MSG_API, sizeof(struct tcpip_msg), "TCPIP_MSG_API") -#if LWIP_MPU_COMPATIBLE -LWIP_MEMPOOL(API_MSG, MEMP_NUM_API_MSG, sizeof(struct api_msg), "API_MSG") -#if LWIP_DNS -LWIP_MEMPOOL(DNS_API_MSG, MEMP_NUM_DNS_API_MSG, sizeof(struct dns_api_msg), "DNS_API_MSG") -#endif -#if LWIP_SOCKET && !LWIP_TCPIP_CORE_LOCKING -LWIP_MEMPOOL(SOCKET_SETGETSOCKOPT_DATA, MEMP_NUM_SOCKET_SETGETSOCKOPT_DATA, sizeof(struct lwip_setgetsockopt_data), "SOCKET_SETGETSOCKOPT_DATA") -#endif -#if LWIP_NETIF_API -LWIP_MEMPOOL(NETIFAPI_MSG, MEMP_NUM_NETIFAPI_MSG, sizeof(struct netifapi_msg), "NETIFAPI_MSG") -#endif -#endif /* LWIP_MPU_COMPATIBLE */ -#if !LWIP_TCPIP_CORE_LOCKING_INPUT -LWIP_MEMPOOL(TCPIP_MSG_INPKT,MEMP_NUM_TCPIP_MSG_INPKT, sizeof(struct tcpip_msg), "TCPIP_MSG_INPKT") -#endif /* !LWIP_TCPIP_CORE_LOCKING_INPUT */ -#endif /* NO_SYS==0 */ - -#if LWIP_IPV4 && LWIP_ARP && ARP_QUEUEING -LWIP_MEMPOOL(ARP_QUEUE, MEMP_NUM_ARP_QUEUE, sizeof(struct etharp_q_entry), "ARP_QUEUE") -#endif /* LWIP_IPV4 && LWIP_ARP && ARP_QUEUEING */ - -#if LWIP_IGMP -LWIP_MEMPOOL(IGMP_GROUP, MEMP_NUM_IGMP_GROUP, sizeof(struct igmp_group), "IGMP_GROUP") -#endif /* LWIP_IGMP */ - -#if LWIP_TIMERS && !LWIP_TIMERS_CUSTOM -LWIP_MEMPOOL(SYS_TIMEOUT, MEMP_NUM_SYS_TIMEOUT, sizeof(struct sys_timeo), "SYS_TIMEOUT") -#endif /* LWIP_TIMERS && !LWIP_TIMERS_CUSTOM */ - -#if LWIP_DNS && LWIP_SOCKET -LWIP_MEMPOOL(NETDB, MEMP_NUM_NETDB, NETDB_ELEM_SIZE, "NETDB") -#endif /* LWIP_DNS && LWIP_SOCKET */ -#if LWIP_DNS && DNS_LOCAL_HOSTLIST && DNS_LOCAL_HOSTLIST_IS_DYNAMIC -LWIP_MEMPOOL(LOCALHOSTLIST, MEMP_NUM_LOCALHOSTLIST, LOCALHOSTLIST_ELEM_SIZE, "LOCALHOSTLIST") -#endif /* LWIP_DNS && DNS_LOCAL_HOSTLIST && DNS_LOCAL_HOSTLIST_IS_DYNAMIC */ - -#if LWIP_IPV6 && LWIP_ND6_QUEUEING -LWIP_MEMPOOL(ND6_QUEUE, MEMP_NUM_ND6_QUEUE, sizeof(struct nd6_q_entry), "ND6_QUEUE") -#endif /* LWIP_IPV6 && LWIP_ND6_QUEUEING */ - -#if LWIP_IPV6 && LWIP_IPV6_REASS -LWIP_MEMPOOL(IP6_REASSDATA, MEMP_NUM_REASSDATA, sizeof(struct ip6_reassdata), "IP6_REASSDATA") -#endif /* LWIP_IPV6 && LWIP_IPV6_REASS */ - -#if LWIP_IPV6 && LWIP_IPV6_ND && LWIP_IPV6_MLD -LWIP_MEMPOOL(MLD6_GROUP, MEMP_NUM_MLD6_GROUP, sizeof(struct mld_group), "MLD6_GROUP") -#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */ - - -/* - * A list of pools of pbuf's used by LWIP. - * - * LWIP_PBUF_MEMPOOL(pool_name, number_elements, pbuf_payload_size, pool_description) - * creates a pool name MEMP_pool_name. description is used in stats.c - * This allocates enough space for the pbuf struct and a payload. - * (Example: pbuf_payload_size=0 allocates only size for the struct) - */ -LWIP_PBUF_MEMPOOL(PBUF, MEMP_NUM_PBUF, 0, "PBUF_REF/ROM") -LWIP_PBUF_MEMPOOL(PBUF_POOL, PBUF_POOL_SIZE, PBUF_POOL_BUFSIZE, "PBUF_POOL") - - -/* - * Allow for user-defined pools; this must be explicitly set in lwipopts.h - * since the default is to NOT look for lwippools.h - */ -#if MEMP_USE_CUSTOM_POOLS -#include "lwippools.h" -#endif /* MEMP_USE_CUSTOM_POOLS */ - -/* - * REQUIRED CLEANUP: Clear up so we don't get "multiply defined" error later - * (#undef is ignored for something that is not defined) - */ -#undef LWIP_MEMPOOL -#undef LWIP_MALLOC_MEMPOOL -#undef LWIP_MALLOC_MEMPOOL_START -#undef LWIP_MALLOC_MEMPOOL_END -#undef LWIP_PBUF_MEMPOOL diff --git a/third_party/lwip/repo/lwip/src/include/lwip/priv/nd6_priv.h b/third_party/lwip/repo/lwip/src/include/lwip/priv/nd6_priv.h deleted file mode 100644 index 5d7731ca9f9b14..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/priv/nd6_priv.h +++ /dev/null @@ -1,140 +0,0 @@ -/** - * @file - * - * Neighbor discovery and stateless address autoconfiguration for IPv6. - * Aims to be compliant with RFC 4861 (Neighbor discovery) and RFC 4862 - * (Address autoconfiguration). - */ - -/* - * Copyright (c) 2010 Inico Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Ivan Delamer - * - * - * Please coordinate changes and requests with Ivan Delamer - * - */ - -#ifndef LWIP_HDR_ND6_PRIV_H -#define LWIP_HDR_ND6_PRIV_H - -#include "lwip/opt.h" - -#if LWIP_IPV6 /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/pbuf.h" -#include "lwip/ip6_addr.h" -#include "lwip/netif.h" - - -#ifdef __cplusplus -extern "C" { -#endif - -#if LWIP_ND6_QUEUEING -/** struct for queueing outgoing packets for unknown address - * defined here to be accessed by memp.h - */ -struct nd6_q_entry { - struct nd6_q_entry *next; - struct pbuf *p; -}; -#endif /* LWIP_ND6_QUEUEING */ - -/** Struct for tables. */ -struct nd6_neighbor_cache_entry { - ip6_addr_t next_hop_address; - struct netif *netif; - u8_t lladdr[NETIF_MAX_HWADDR_LEN]; - /*u32_t pmtu;*/ -#if LWIP_ND6_QUEUEING - /** Pointer to queue of pending outgoing packets on this entry. */ - struct nd6_q_entry *q; -#else /* LWIP_ND6_QUEUEING */ - /** Pointer to a single pending outgoing packet on this entry. */ - struct pbuf *q; -#endif /* LWIP_ND6_QUEUEING */ - u8_t state; - u8_t isrouter; - union { - u32_t reachable_time; /* in seconds */ - u32_t delay_time; /* ticks (ND6_TMR_INTERVAL) */ - u32_t probes_sent; - u32_t stale_time; /* ticks (ND6_TMR_INTERVAL) */ - } counter; -}; - -struct nd6_destination_cache_entry { - ip6_addr_t destination_addr; - ip6_addr_t next_hop_addr; - u16_t pmtu; - u32_t age; -}; - -struct nd6_prefix_list_entry { - ip6_addr_t prefix; - struct netif *netif; - u32_t invalidation_timer; /* in seconds */ -}; - -struct nd6_router_list_entry { - struct nd6_neighbor_cache_entry *neighbor_entry; - u32_t invalidation_timer; /* in seconds */ - u8_t flags; -}; - -enum nd6_neighbor_cache_entry_state { - ND6_NO_ENTRY = 0, - ND6_INCOMPLETE, - ND6_REACHABLE, - ND6_STALE, - ND6_DELAY, - ND6_PROBE -}; - -#define ND6_2HRS 7200 /* two hours, expressed in number of seconds */ - -/* Router tables. */ -/* @todo make these static? and entries accessible through API? */ -extern struct nd6_neighbor_cache_entry neighbor_cache[]; -extern struct nd6_destination_cache_entry destination_cache[]; -extern struct nd6_prefix_list_entry prefix_list[]; -extern struct nd6_router_list_entry default_router_list[]; - -/* Default values, can be updated by a RA message. */ -extern u32_t reachable_time; -extern u32_t retrans_timer; - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_IPV6 */ - -#endif /* LWIP_HDR_ND6_PRIV_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/priv/tcp_priv.h b/third_party/lwip/repo/lwip/src/include/lwip/priv/tcp_priv.h deleted file mode 100644 index 73e8967e47d747..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/priv/tcp_priv.h +++ /dev/null @@ -1,507 +0,0 @@ -/** - * @file - * TCP internal implementations (do not use in application code) - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_TCP_PRIV_H -#define LWIP_HDR_TCP_PRIV_H - -#include "lwip/opt.h" - -#if LWIP_TCP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/tcp.h" -#include "lwip/mem.h" -#include "lwip/pbuf.h" -#include "lwip/ip.h" -#include "lwip/icmp.h" -#include "lwip/err.h" -#include "lwip/ip6.h" -#include "lwip/ip6_addr.h" -#include "lwip/prot/tcp.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* Functions for interfacing with TCP: */ - -/* Lower layer interface to TCP: */ -void tcp_init (void); /* Initialize this module. */ -void tcp_tmr (void); /* Must be called every - TCP_TMR_INTERVAL - ms. (Typically 250 ms). */ -/* It is also possible to call these two functions at the right - intervals (instead of calling tcp_tmr()). */ -void tcp_slowtmr (void); -void tcp_fasttmr (void); - -/* Call this from a netif driver (watch out for threading issues!) that has - returned a memory error on transmit and now has free buffers to send more. - This iterates all active pcbs that had an error and tries to call - tcp_output, so use this with care as it might slow down the system. */ -void tcp_txnow (void); - -/* Only used by IP to pass a TCP segment to TCP: */ -void tcp_input (struct pbuf *p, struct netif *inp); -/* Used within the TCP code only: */ -struct tcp_pcb * tcp_alloc (u8_t prio); -void tcp_abandon (struct tcp_pcb *pcb, int reset); -err_t tcp_send_empty_ack(struct tcp_pcb *pcb); -void tcp_rexmit (struct tcp_pcb *pcb); -void tcp_rexmit_rto (struct tcp_pcb *pcb); -void tcp_rexmit_fast (struct tcp_pcb *pcb); -u32_t tcp_update_rcv_ann_wnd(struct tcp_pcb *pcb); -err_t tcp_process_refused_data(struct tcp_pcb *pcb); - -/** - * This is the Nagle algorithm: try to combine user data to send as few TCP - * segments as possible. Only send if - * - no previously transmitted data on the connection remains unacknowledged or - * - the TF_NODELAY flag is set (nagle algorithm turned off for this pcb) or - * - the only unsent segment is at least pcb->mss bytes long (or there is more - * than one unsent segment - with lwIP, this can happen although unsent->len < mss) - * - or if we are in fast-retransmit (TF_INFR) - */ -#define tcp_do_output_nagle(tpcb) ((((tpcb)->unacked == NULL) || \ - ((tpcb)->flags & (TF_NODELAY | TF_INFR)) || \ - (((tpcb)->unsent != NULL) && (((tpcb)->unsent->next != NULL) || \ - ((tpcb)->unsent->len >= (tpcb)->mss))) || \ - ((tcp_sndbuf(tpcb) == 0) || (tcp_sndqueuelen(tpcb) >= TCP_SND_QUEUELEN)) \ - ) ? 1 : 0) -#define tcp_output_nagle(tpcb) (tcp_do_output_nagle(tpcb) ? tcp_output(tpcb) : ERR_OK) - - -#define TCP_SEQ_LT(a,b) ((s32_t)((u32_t)(a) - (u32_t)(b)) < 0) -#define TCP_SEQ_LEQ(a,b) ((s32_t)((u32_t)(a) - (u32_t)(b)) <= 0) -#define TCP_SEQ_GT(a,b) ((s32_t)((u32_t)(a) - (u32_t)(b)) > 0) -#define TCP_SEQ_GEQ(a,b) ((s32_t)((u32_t)(a) - (u32_t)(b)) >= 0) -/* is b<=a<=c? */ -#if 0 /* see bug #10548 */ -#define TCP_SEQ_BETWEEN(a,b,c) ((c)-(b) >= (a)-(b)) -#endif -#define TCP_SEQ_BETWEEN(a,b,c) (TCP_SEQ_GEQ(a,b) && TCP_SEQ_LEQ(a,c)) - -#ifndef TCP_TMR_INTERVAL -#define TCP_TMR_INTERVAL 250 /* The TCP timer interval in milliseconds. */ -#endif /* TCP_TMR_INTERVAL */ - -#ifndef TCP_FAST_INTERVAL -#define TCP_FAST_INTERVAL TCP_TMR_INTERVAL /* the fine grained timeout in milliseconds */ -#endif /* TCP_FAST_INTERVAL */ - -#ifndef TCP_SLOW_INTERVAL -#define TCP_SLOW_INTERVAL (2*TCP_TMR_INTERVAL) /* the coarse grained timeout in milliseconds */ -#endif /* TCP_SLOW_INTERVAL */ - -#define TCP_FIN_WAIT_TIMEOUT 20000 /* milliseconds */ -#define TCP_SYN_RCVD_TIMEOUT 20000 /* milliseconds */ - -#define TCP_OOSEQ_TIMEOUT 6U /* x RTO */ - -#ifndef TCP_MSL -#define TCP_MSL 60000UL /* The maximum segment lifetime in milliseconds */ -#endif - -/* Keepalive values, compliant with RFC 1122. Don't change this unless you know what you're doing */ -#ifndef TCP_KEEPIDLE_DEFAULT -#define TCP_KEEPIDLE_DEFAULT 7200000UL /* Default KEEPALIVE timer in milliseconds */ -#endif - -#ifndef TCP_KEEPINTVL_DEFAULT -#define TCP_KEEPINTVL_DEFAULT 75000UL /* Default Time between KEEPALIVE probes in milliseconds */ -#endif - -#ifndef TCP_KEEPCNT_DEFAULT -#define TCP_KEEPCNT_DEFAULT 9U /* Default Counter for KEEPALIVE probes */ -#endif - -#define TCP_MAXIDLE TCP_KEEPCNT_DEFAULT * TCP_KEEPINTVL_DEFAULT /* Maximum KEEPALIVE probe time */ - -#define TCP_TCPLEN(seg) ((seg)->len + (((TCPH_FLAGS((seg)->tcphdr) & (TCP_FIN | TCP_SYN)) != 0) ? 1U : 0U)) - -/** Flags used on input processing, not on pcb->flags -*/ -#define TF_RESET (u8_t)0x08U /* Connection was reset. */ -#define TF_CLOSED (u8_t)0x10U /* Connection was successfully closed. */ -#define TF_GOT_FIN (u8_t)0x20U /* Connection was closed by the remote end. */ - - -#if LWIP_EVENT_API - -#define TCP_EVENT_ACCEPT(lpcb,pcb,arg,err,ret) ret = lwip_tcp_event(arg, (pcb),\ - LWIP_EVENT_ACCEPT, NULL, 0, err) -#define TCP_EVENT_SENT(pcb,space,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\ - LWIP_EVENT_SENT, NULL, space, ERR_OK) -#define TCP_EVENT_RECV(pcb,p,err,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\ - LWIP_EVENT_RECV, (p), 0, (err)) -#define TCP_EVENT_CLOSED(pcb,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\ - LWIP_EVENT_RECV, NULL, 0, ERR_OK) -#define TCP_EVENT_CONNECTED(pcb,err,ret) ret = lwip_tcp_event((pcb)->callback_arg, (pcb),\ - LWIP_EVENT_CONNECTED, NULL, 0, (err)) -#define TCP_EVENT_POLL(pcb,ret) do { if ((pcb)->state != SYN_RCVD) { \ - ret = lwip_tcp_event((pcb)->callback_arg, (pcb), LWIP_EVENT_POLL, NULL, 0, ERR_OK); \ - } else { \ - ret = ERR_ARG; } } while(0) -#define TCP_EVENT_ERR(last_state,errf,arg,err) do { if (last_state != SYN_RCVD) { \ - lwip_tcp_event((arg), NULL, LWIP_EVENT_ERR, NULL, 0, (err)); } } while(0) - -#else /* LWIP_EVENT_API */ - -#define TCP_EVENT_ACCEPT(lpcb,pcb,arg,err,ret) \ - do { \ - if((lpcb)->accept != NULL) \ - (ret) = (lpcb)->accept((arg),(pcb),(err)); \ - else (ret) = ERR_ARG; \ - } while (0) - -#define TCP_EVENT_SENT(pcb,space,ret) \ - do { \ - if((pcb)->sent != NULL) \ - (ret) = (pcb)->sent((pcb)->callback_arg,(pcb),(space)); \ - else (ret) = ERR_OK; \ - } while (0) - -#define TCP_EVENT_RECV(pcb,p,err,ret) \ - do { \ - if((pcb)->recv != NULL) { \ - (ret) = (pcb)->recv((pcb)->callback_arg,(pcb),(p),(err));\ - } else { \ - (ret) = tcp_recv_null(NULL, (pcb), (p), (err)); \ - } \ - } while (0) - -#define TCP_EVENT_CLOSED(pcb,ret) \ - do { \ - if(((pcb)->recv != NULL)) { \ - (ret) = (pcb)->recv((pcb)->callback_arg,(pcb),NULL,ERR_OK);\ - } else { \ - (ret) = ERR_OK; \ - } \ - } while (0) - -#define TCP_EVENT_CONNECTED(pcb,err,ret) \ - do { \ - if((pcb)->connected != NULL) \ - (ret) = (pcb)->connected((pcb)->callback_arg,(pcb),(err)); \ - else (ret) = ERR_OK; \ - } while (0) - -#define TCP_EVENT_POLL(pcb,ret) \ - do { \ - if((pcb)->poll != NULL) \ - (ret) = (pcb)->poll((pcb)->callback_arg,(pcb)); \ - else (ret) = ERR_OK; \ - } while (0) - -#define TCP_EVENT_ERR(last_state,errf,arg,err) \ - do { \ - LWIP_UNUSED_ARG(last_state); \ - if((errf) != NULL) \ - (errf)((arg),(err)); \ - } while (0) - -#endif /* LWIP_EVENT_API */ - -/** Enabled extra-check for TCP_OVERSIZE if LWIP_DEBUG is enabled */ -#if TCP_OVERSIZE && defined(LWIP_DEBUG) -#define TCP_OVERSIZE_DBGCHECK 1 -#else -#define TCP_OVERSIZE_DBGCHECK 0 -#endif - -/** Don't generate checksum on copy if CHECKSUM_GEN_TCP is disabled */ -#define TCP_CHECKSUM_ON_COPY (LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_TCP) - -/* This structure represents a TCP segment on the unsent, unacked and ooseq queues */ -struct tcp_seg { - struct tcp_seg *next; /* used when putting segments on a queue */ - struct pbuf *p; /* buffer containing data + TCP header */ - u16_t len; /* the TCP length of this segment */ -#if TCP_OVERSIZE_DBGCHECK - u16_t oversize_left; /* Extra bytes available at the end of the last - pbuf in unsent (used for asserting vs. - tcp_pcb.unsent_oversize only) */ -#endif /* TCP_OVERSIZE_DBGCHECK */ -#if TCP_CHECKSUM_ON_COPY - u16_t chksum; - u8_t chksum_swapped; -#endif /* TCP_CHECKSUM_ON_COPY */ - u8_t flags; -#define TF_SEG_OPTS_MSS (u8_t)0x01U /* Include MSS option. */ -#define TF_SEG_OPTS_TS (u8_t)0x02U /* Include timestamp option. */ -#define TF_SEG_DATA_CHECKSUMMED (u8_t)0x04U /* ALL data (not the header) is - checksummed into 'chksum' */ -#define TF_SEG_OPTS_WND_SCALE (u8_t)0x08U /* Include WND SCALE option */ - struct tcp_hdr *tcphdr; /* the TCP header */ -}; - -#define LWIP_TCP_OPT_EOL 0 -#define LWIP_TCP_OPT_NOP 1 -#define LWIP_TCP_OPT_MSS 2 -#define LWIP_TCP_OPT_WS 3 -#define LWIP_TCP_OPT_TS 8 - -#define LWIP_TCP_OPT_LEN_MSS 4 -#if LWIP_TCP_TIMESTAMPS -#define LWIP_TCP_OPT_LEN_TS 10 -#define LWIP_TCP_OPT_LEN_TS_OUT 12 /* aligned for output (includes NOP padding) */ -#else -#define LWIP_TCP_OPT_LEN_TS_OUT 0 -#endif -#if LWIP_WND_SCALE -#define LWIP_TCP_OPT_LEN_WS 3 -#define LWIP_TCP_OPT_LEN_WS_OUT 4 /* aligned for output (includes NOP padding) */ -#else -#define LWIP_TCP_OPT_LEN_WS_OUT 0 -#endif - -#define LWIP_TCP_OPT_LENGTH(flags) \ - (flags & TF_SEG_OPTS_MSS ? LWIP_TCP_OPT_LEN_MSS : 0) + \ - (flags & TF_SEG_OPTS_TS ? LWIP_TCP_OPT_LEN_TS_OUT : 0) + \ - (flags & TF_SEG_OPTS_WND_SCALE ? LWIP_TCP_OPT_LEN_WS_OUT : 0) - -/** This returns a TCP header option for MSS in an u32_t */ -#define TCP_BUILD_MSS_OPTION(mss) lwip_htonl(0x02040000 | ((mss) & 0xFFFF)) - -#if LWIP_WND_SCALE -#define TCPWNDSIZE_F U32_F -#define TCPWND_MAX 0xFFFFFFFFU -#define TCPWND_CHECK16(x) LWIP_ASSERT("window size > 0xFFFF", (x) <= 0xFFFF) -#define TCPWND_MIN16(x) ((u16_t)LWIP_MIN((x), 0xFFFF)) -#else /* LWIP_WND_SCALE */ -#define TCPWNDSIZE_F U16_F -#define TCPWND_MAX 0xFFFFU -#define TCPWND_CHECK16(x) -#define TCPWND_MIN16(x) x -#endif /* LWIP_WND_SCALE */ - -/* Global variables: */ -extern struct tcp_pcb *tcp_input_pcb; -extern u32_t tcp_ticks; -extern u8_t tcp_active_pcbs_changed; - -/* The TCP PCB lists. */ -union tcp_listen_pcbs_t { /* List of all TCP PCBs in LISTEN state. */ - struct tcp_pcb_listen *listen_pcbs; - struct tcp_pcb *pcbs; -}; -extern struct tcp_pcb *tcp_bound_pcbs; -extern union tcp_listen_pcbs_t tcp_listen_pcbs; -extern struct tcp_pcb *tcp_active_pcbs; /* List of all TCP PCBs that are in a - state in which they accept or send - data. */ -extern struct tcp_pcb *tcp_tw_pcbs; /* List of all TCP PCBs in TIME-WAIT. */ - -#define NUM_TCP_PCB_LISTS_NO_TIME_WAIT 3 -#define NUM_TCP_PCB_LISTS 4 -extern struct tcp_pcb ** const tcp_pcb_lists[NUM_TCP_PCB_LISTS]; - -/* Axioms about the above lists: - 1) Every TCP PCB that is not CLOSED is in one of the lists. - 2) A PCB is only in one of the lists. - 3) All PCBs in the tcp_listen_pcbs list is in LISTEN state. - 4) All PCBs in the tcp_tw_pcbs list is in TIME-WAIT state. -*/ -/* Define two macros, TCP_REG and TCP_RMV that registers a TCP PCB - with a PCB list or removes a PCB from a list, respectively. */ -#ifndef TCP_DEBUG_PCB_LISTS -#define TCP_DEBUG_PCB_LISTS 0 -#endif -#if TCP_DEBUG_PCB_LISTS -#define TCP_REG(pcbs, npcb) do {\ - struct tcp_pcb *tcp_tmp_pcb; \ - LWIP_DEBUGF(TCP_DEBUG, ("TCP_REG %p local port %d\n", (npcb), (npcb)->local_port)); \ - for (tcp_tmp_pcb = *(pcbs); \ - tcp_tmp_pcb != NULL; \ - tcp_tmp_pcb = tcp_tmp_pcb->next) { \ - LWIP_ASSERT("TCP_REG: already registered\n", tcp_tmp_pcb != (npcb)); \ - } \ - LWIP_ASSERT("TCP_REG: pcb->state != CLOSED", ((pcbs) == &tcp_bound_pcbs) || ((npcb)->state != CLOSED)); \ - (npcb)->next = *(pcbs); \ - LWIP_ASSERT("TCP_REG: npcb->next != npcb", (npcb)->next != (npcb)); \ - *(pcbs) = (npcb); \ - LWIP_ASSERT("TCP_RMV: tcp_pcbs sane", tcp_pcbs_sane()); \ - tcp_timer_needed(); \ - } while(0) -#define TCP_RMV(pcbs, npcb) do { \ - struct tcp_pcb *tcp_tmp_pcb; \ - LWIP_ASSERT("TCP_RMV: pcbs != NULL", *(pcbs) != NULL); \ - LWIP_DEBUGF(TCP_DEBUG, ("TCP_RMV: removing %p from %p\n", (npcb), *(pcbs))); \ - if(*(pcbs) == (npcb)) { \ - *(pcbs) = (*pcbs)->next; \ - } else for (tcp_tmp_pcb = *(pcbs); tcp_tmp_pcb != NULL; tcp_tmp_pcb = tcp_tmp_pcb->next) { \ - if(tcp_tmp_pcb->next == (npcb)) { \ - tcp_tmp_pcb->next = (npcb)->next; \ - break; \ - } \ - } \ - (npcb)->next = NULL; \ - LWIP_ASSERT("TCP_RMV: tcp_pcbs sane", tcp_pcbs_sane()); \ - LWIP_DEBUGF(TCP_DEBUG, ("TCP_RMV: removed %p from %p\n", (npcb), *(pcbs))); \ - } while(0) - -#else /* LWIP_DEBUG */ - -#define TCP_REG(pcbs, npcb) \ - do { \ - (npcb)->next = *pcbs; \ - *(pcbs) = (npcb); \ - tcp_timer_needed(); \ - } while (0) - -#define TCP_RMV(pcbs, npcb) \ - do { \ - if(*(pcbs) == (npcb)) { \ - (*(pcbs)) = (*pcbs)->next; \ - } \ - else { \ - struct tcp_pcb *tcp_tmp_pcb; \ - for (tcp_tmp_pcb = *pcbs; \ - tcp_tmp_pcb != NULL; \ - tcp_tmp_pcb = tcp_tmp_pcb->next) { \ - if(tcp_tmp_pcb->next == (npcb)) { \ - tcp_tmp_pcb->next = (npcb)->next; \ - break; \ - } \ - } \ - } \ - (npcb)->next = NULL; \ - } while(0) - -#endif /* LWIP_DEBUG */ - -#define TCP_REG_ACTIVE(npcb) \ - do { \ - TCP_REG(&tcp_active_pcbs, npcb); \ - tcp_active_pcbs_changed = 1; \ - } while (0) - -#define TCP_RMV_ACTIVE(npcb) \ - do { \ - TCP_RMV(&tcp_active_pcbs, npcb); \ - tcp_active_pcbs_changed = 1; \ - } while (0) - -#define TCP_PCB_REMOVE_ACTIVE(pcb) \ - do { \ - tcp_pcb_remove(&tcp_active_pcbs, pcb); \ - tcp_active_pcbs_changed = 1; \ - } while (0) - - -/* Internal functions: */ -struct tcp_pcb *tcp_pcb_copy(struct tcp_pcb *pcb); -void tcp_pcb_purge(struct tcp_pcb *pcb); -void tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb); - -void tcp_segs_free(struct tcp_seg *seg); -void tcp_seg_free(struct tcp_seg *seg); -struct tcp_seg *tcp_seg_copy(struct tcp_seg *seg); - -#define tcp_ack(pcb) \ - do { \ - if((pcb)->flags & TF_ACK_DELAY) { \ - (pcb)->flags &= ~TF_ACK_DELAY; \ - (pcb)->flags |= TF_ACK_NOW; \ - } \ - else { \ - (pcb)->flags |= TF_ACK_DELAY; \ - } \ - } while (0) - -#define tcp_ack_now(pcb) \ - do { \ - (pcb)->flags |= TF_ACK_NOW; \ - } while (0) - -err_t tcp_send_fin(struct tcp_pcb *pcb); -err_t tcp_enqueue_flags(struct tcp_pcb *pcb, u8_t flags); - -void tcp_rexmit_seg(struct tcp_pcb *pcb, struct tcp_seg *seg); - -void tcp_rst(u32_t seqno, u32_t ackno, - const ip_addr_t *local_ip, const ip_addr_t *remote_ip, - u16_t local_port, u16_t remote_port); - -u32_t tcp_next_iss(struct tcp_pcb *pcb); - -err_t tcp_keepalive(struct tcp_pcb *pcb); -err_t tcp_zero_window_probe(struct tcp_pcb *pcb); -void tcp_trigger_input_pcb_close(void); - -#if TCP_CALCULATE_EFF_SEND_MSS -u16_t tcp_eff_send_mss_impl(u16_t sendmss, const ip_addr_t *dest -#if LWIP_IPV6 || LWIP_IPV4_SRC_ROUTING - , const ip_addr_t *src -#endif /* LWIP_IPV6 || LWIP_IPV4_SRC_ROUTING */ - ); -#if LWIP_IPV6 || LWIP_IPV4_SRC_ROUTING -#define tcp_eff_send_mss(sendmss, src, dest) tcp_eff_send_mss_impl(sendmss, dest, src) -#else /* LWIP_IPV6 || LWIP_IPV4_SRC_ROUTING */ -#define tcp_eff_send_mss(sendmss, src, dest) tcp_eff_send_mss_impl(sendmss, dest) -#endif /* LWIP_IPV6 || LWIP_IPV4_SRC_ROUTING */ -#endif /* TCP_CALCULATE_EFF_SEND_MSS */ - -#if LWIP_CALLBACK_API -err_t tcp_recv_null(void *arg, struct tcp_pcb *pcb, struct pbuf *p, err_t err); -#endif /* LWIP_CALLBACK_API */ - -#if TCP_DEBUG || TCP_INPUT_DEBUG || TCP_OUTPUT_DEBUG -void tcp_debug_print(struct tcp_hdr *tcphdr); -void tcp_debug_print_flags(u8_t flags); -void tcp_debug_print_state(enum tcp_state s); -void tcp_debug_print_pcbs(void); -s16_t tcp_pcbs_sane(void); -#else -# define tcp_debug_print(tcphdr) -# define tcp_debug_print_flags(flags) -# define tcp_debug_print_state(s) -# define tcp_debug_print_pcbs() -# define tcp_pcbs_sane() 1 -#endif /* TCP_DEBUG */ - -/** External function (implemented in timers.c), called when TCP detects - * that a timer is needed (i.e. active- or time-wait-pcb found). */ -void tcp_timer_needed(void); - -void tcp_netif_ip_addr_changed(const ip_addr_t* old_addr, const ip_addr_t* new_addr); - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_TCP */ - -#endif /* LWIP_HDR_TCP_PRIV_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/priv/tcpip_priv.h b/third_party/lwip/repo/lwip/src/include/lwip/priv/tcpip_priv.h deleted file mode 100644 index 127eae542f1a95..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/priv/tcpip_priv.h +++ /dev/null @@ -1,161 +0,0 @@ -/** - * @file - * TCPIP API internal implementations (do not use in application code) - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_TCPIP_PRIV_H -#define LWIP_HDR_TCPIP_PRIV_H - -#include "lwip/opt.h" - -#if !NO_SYS /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/tcpip.h" -#include "lwip/sys.h" -#include "lwip/timeouts.h" - -#ifdef __cplusplus -extern "C" { -#endif - -struct pbuf; -struct netif; - -#if LWIP_MPU_COMPATIBLE -#define API_VAR_REF(name) (*(name)) -#define API_VAR_DECLARE(type, name) type * name -#define API_VAR_ALLOC(type, pool, name, errorval) do { \ - name = (type *)memp_malloc(pool); \ - if (name == NULL) { \ - return errorval; \ - } \ - } while(0) -#define API_VAR_ALLOC_POOL(type, pool, name, errorval) do { \ - name = (type *)LWIP_MEMPOOL_ALLOC(pool); \ - if (name == NULL) { \ - return errorval; \ - } \ - } while(0) -#define API_VAR_FREE(pool, name) memp_free(pool, name) -#define API_VAR_FREE_POOL(pool, name) LWIP_MEMPOOL_FREE(pool, name) -#define API_EXPR_REF(expr) (&(expr)) -#if LWIP_NETCONN_SEM_PER_THREAD -#define API_EXPR_REF_SEM(expr) (expr) -#else -#define API_EXPR_REF_SEM(expr) API_EXPR_REF(expr) -#endif -#define API_EXPR_DEREF(expr) expr -#define API_MSG_M_DEF(m) m -#define API_MSG_M_DEF_C(t, m) t m -#else /* LWIP_MPU_COMPATIBLE */ -#define API_VAR_REF(name) name -#define API_VAR_DECLARE(type, name) type name -#define API_VAR_ALLOC(type, pool, name, errorval) -#define API_VAR_ALLOC_POOL(type, pool, name, errorval) -#define API_VAR_FREE(pool, name) -#define API_VAR_FREE_POOL(pool, name) -#define API_EXPR_REF(expr) expr -#define API_EXPR_REF_SEM(expr) API_EXPR_REF(expr) -#define API_EXPR_DEREF(expr) (*(expr)) -#define API_MSG_M_DEF(m) *m -#define API_MSG_M_DEF_C(t, m) const t * m -#endif /* LWIP_MPU_COMPATIBLE */ - -err_t tcpip_send_msg_wait_sem(tcpip_callback_fn fn, void *apimsg, sys_sem_t* sem); - -struct tcpip_api_call_data -{ -#if !LWIP_TCPIP_CORE_LOCKING - err_t err; -#if !LWIP_NETCONN_SEM_PER_THREAD - sys_sem_t sem; -#endif /* LWIP_NETCONN_SEM_PER_THREAD */ -#else /* !LWIP_TCPIP_CORE_LOCKING */ - u8_t dummy; /* avoid empty struct :-( */ -#endif /* !LWIP_TCPIP_CORE_LOCKING */ -}; -typedef err_t (*tcpip_api_call_fn)(struct tcpip_api_call_data* call); -err_t tcpip_api_call(tcpip_api_call_fn fn, struct tcpip_api_call_data *call); - -enum tcpip_msg_type { - TCPIP_MSG_API, - TCPIP_MSG_API_CALL, - TCPIP_MSG_INPKT, -#if LWIP_TCPIP_TIMEOUT && LWIP_TIMERS - TCPIP_MSG_TIMEOUT, - TCPIP_MSG_UNTIMEOUT, -#endif /* LWIP_TCPIP_TIMEOUT && LWIP_TIMERS */ - TCPIP_MSG_CALLBACK, - TCPIP_MSG_CALLBACK_STATIC, - TCPIP_MSG_FINISH -}; - -struct tcpip_msg { - enum tcpip_msg_type type; - union { - struct { - tcpip_callback_fn function; - void* msg; - } api_msg; - struct { - tcpip_api_call_fn function; - struct tcpip_api_call_data *arg; - sys_sem_t *sem; - } api_call; - struct { - struct pbuf *p; - struct netif *netif; - netif_input_fn input_fn; - } inp; - struct { - tcpip_callback_fn function; - void *ctx; - } cb; -#if LWIP_TCPIP_TIMEOUT && LWIP_TIMERS - struct { - u32_t msecs; - sys_timeout_handler h; - void *arg; - } tmo; -#endif /* LWIP_TCPIP_TIMEOUT && LWIP_TIMERS */ - } msg; -}; - -#ifdef __cplusplus -} -#endif - -#endif /* !NO_SYS */ - -#endif /* LWIP_HDR_TCPIP_PRIV_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/prot/autoip.h b/third_party/lwip/repo/lwip/src/include/lwip/prot/autoip.h deleted file mode 100644 index fd3af8a9fc5f0d..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/prot/autoip.h +++ /dev/null @@ -1,78 +0,0 @@ -/** - * @file - * AutoIP protocol definitions - */ - -/* - * - * Copyright (c) 2007 Dominik Spies - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * Author: Dominik Spies - * - * This is a AutoIP implementation for the lwIP TCP/IP stack. It aims to conform - * with RFC 3927. - * - */ - -#ifndef LWIP_HDR_PROT_AUTOIP_H -#define LWIP_HDR_PROT_AUTOIP_H - -#ifdef __cplusplus -extern "C" { -#endif - -/* 169.254.0.0 */ -#define AUTOIP_NET 0xA9FE0000 -/* 169.254.1.0 */ -#define AUTOIP_RANGE_START (AUTOIP_NET | 0x0100) -/* 169.254.254.255 */ -#define AUTOIP_RANGE_END (AUTOIP_NET | 0xFEFF) - -/* RFC 3927 Constants */ -#define PROBE_WAIT 1 /* second (initial random delay) */ -#define PROBE_MIN 1 /* second (minimum delay till repeated probe) */ -#define PROBE_MAX 2 /* seconds (maximum delay till repeated probe) */ -#define PROBE_NUM 3 /* (number of probe packets) */ -#define ANNOUNCE_NUM 2 /* (number of announcement packets) */ -#define ANNOUNCE_INTERVAL 2 /* seconds (time between announcement packets) */ -#define ANNOUNCE_WAIT 2 /* seconds (delay before announcing) */ -#define MAX_CONFLICTS 10 /* (max conflicts before rate limiting) */ -#define RATE_LIMIT_INTERVAL 60 /* seconds (delay between successive attempts) */ -#define DEFEND_INTERVAL 10 /* seconds (min. wait between defensive ARPs) */ - -/* AutoIP client states */ -typedef enum { - AUTOIP_STATE_OFF = 0, - AUTOIP_STATE_PROBING = 1, - AUTOIP_STATE_ANNOUNCING = 2, - AUTOIP_STATE_BOUND = 3 -} autoip_state_enum_t; - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_PROT_AUTOIP_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/prot/dhcp.h b/third_party/lwip/repo/lwip/src/include/lwip/prot/dhcp.h deleted file mode 100644 index 112953cb8bfa2f..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/prot/dhcp.h +++ /dev/null @@ -1,183 +0,0 @@ -/** - * @file - * DHCP protocol definitions - */ - -/* - * Copyright (c) 2001-2004 Leon Woestenberg - * Copyright (c) 2001-2004 Axon Digital Design B.V., The Netherlands. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Leon Woestenberg - * - */ -#ifndef LWIP_HDR_PROT_DHCP_H -#define LWIP_HDR_PROT_DHCP_H - -#include "lwip/opt.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define DHCP_CLIENT_PORT 68 -#define DHCP_SERVER_PORT 67 - - - /* DHCP message item offsets and length */ -#define DHCP_CHADDR_LEN 16U -#define DHCP_SNAME_OFS 44U -#define DHCP_SNAME_LEN 64U -#define DHCP_FILE_OFS 108U -#define DHCP_FILE_LEN 128U -#define DHCP_MSG_LEN 236U -#define DHCP_OPTIONS_OFS (DHCP_MSG_LEN + 4U) /* 4 byte: cookie */ - -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -/** minimum set of fields of any DHCP message */ -struct dhcp_msg -{ - PACK_STRUCT_FLD_8(u8_t op); - PACK_STRUCT_FLD_8(u8_t htype); - PACK_STRUCT_FLD_8(u8_t hlen); - PACK_STRUCT_FLD_8(u8_t hops); - PACK_STRUCT_FIELD(u32_t xid); - PACK_STRUCT_FIELD(u16_t secs); - PACK_STRUCT_FIELD(u16_t flags); - PACK_STRUCT_FLD_S(ip4_addr_p_t ciaddr); - PACK_STRUCT_FLD_S(ip4_addr_p_t yiaddr); - PACK_STRUCT_FLD_S(ip4_addr_p_t siaddr); - PACK_STRUCT_FLD_S(ip4_addr_p_t giaddr); - PACK_STRUCT_FLD_8(u8_t chaddr[DHCP_CHADDR_LEN]); - PACK_STRUCT_FLD_8(u8_t sname[DHCP_SNAME_LEN]); - PACK_STRUCT_FLD_8(u8_t file[DHCP_FILE_LEN]); - PACK_STRUCT_FIELD(u32_t cookie); -#define DHCP_MIN_OPTIONS_LEN 68U -/** make sure user does not configure this too small */ -#if ((defined(DHCP_OPTIONS_LEN)) && (DHCP_OPTIONS_LEN < DHCP_MIN_OPTIONS_LEN)) -# undef DHCP_OPTIONS_LEN -#endif -/** allow this to be configured in lwipopts.h, but not too small */ -#if (!defined(DHCP_OPTIONS_LEN)) -/** set this to be sufficient for your options in outgoing DHCP msgs */ -# define DHCP_OPTIONS_LEN DHCP_MIN_OPTIONS_LEN -#endif - PACK_STRUCT_FLD_8(u8_t options[DHCP_OPTIONS_LEN]); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - - -/* DHCP client states */ -typedef enum { - DHCP_STATE_OFF = 0, - DHCP_STATE_REQUESTING = 1, - DHCP_STATE_INIT = 2, - DHCP_STATE_REBOOTING = 3, - DHCP_STATE_REBINDING = 4, - DHCP_STATE_RENEWING = 5, - DHCP_STATE_SELECTING = 6, - DHCP_STATE_INFORMING = 7, - DHCP_STATE_CHECKING = 8, - DHCP_STATE_PERMANENT = 9, /* not yet implemented */ - DHCP_STATE_BOUND = 10, - DHCP_STATE_RELEASING = 11, /* not yet implemented */ - DHCP_STATE_BACKING_OFF = 12 -} dhcp_state_enum_t; - -/* DHCP op codes */ -#define DHCP_BOOTREQUEST 1 -#define DHCP_BOOTREPLY 2 - -/* DHCP message types */ -#define DHCP_DISCOVER 1 -#define DHCP_OFFER 2 -#define DHCP_REQUEST 3 -#define DHCP_DECLINE 4 -#define DHCP_ACK 5 -#define DHCP_NAK 6 -#define DHCP_RELEASE 7 -#define DHCP_INFORM 8 - -/** DHCP hardware type, currently only ethernet is supported */ -#define DHCP_HTYPE_ETH 1 - -#define DHCP_MAGIC_COOKIE 0x63825363UL - -/* This is a list of options for BOOTP and DHCP, see RFC 2132 for descriptions */ - -/* BootP options */ -#define DHCP_OPTION_PAD 0 -#define DHCP_OPTION_SUBNET_MASK 1 /* RFC 2132 3.3 */ -#define DHCP_OPTION_ROUTER 3 -#define DHCP_OPTION_DNS_SERVER 6 -#define DHCP_OPTION_HOSTNAME 12 -#define DHCP_OPTION_IP_TTL 23 -#define DHCP_OPTION_MTU 26 -#define DHCP_OPTION_BROADCAST 28 -#define DHCP_OPTION_TCP_TTL 37 -#define DHCP_OPTION_NTP 42 -#define DHCP_OPTION_END 255 - -/* DHCP options */ -#define DHCP_OPTION_REQUESTED_IP 50 /* RFC 2132 9.1, requested IP address */ -#define DHCP_OPTION_LEASE_TIME 51 /* RFC 2132 9.2, time in seconds, in 4 bytes */ -#define DHCP_OPTION_OVERLOAD 52 /* RFC2132 9.3, use file and/or sname field for options */ - -#define DHCP_OPTION_MESSAGE_TYPE 53 /* RFC 2132 9.6, important for DHCP */ -#define DHCP_OPTION_MESSAGE_TYPE_LEN 1 - -#define DHCP_OPTION_SERVER_ID 54 /* RFC 2132 9.7, server IP address */ -#define DHCP_OPTION_PARAMETER_REQUEST_LIST 55 /* RFC 2132 9.8, requested option types */ - -#define DHCP_OPTION_MAX_MSG_SIZE 57 /* RFC 2132 9.10, message size accepted >= 576 */ -#define DHCP_OPTION_MAX_MSG_SIZE_LEN 2 - -#define DHCP_OPTION_T1 58 /* T1 renewal time */ -#define DHCP_OPTION_T2 59 /* T2 rebinding time */ -#define DHCP_OPTION_US 60 -#define DHCP_OPTION_CLIENT_ID 61 -#define DHCP_OPTION_TFTP_SERVERNAME 66 -#define DHCP_OPTION_BOOTFILE 67 - -/* possible combinations of overloading the file and sname fields with options */ -#define DHCP_OVERLOAD_NONE 0 -#define DHCP_OVERLOAD_FILE 1 -#define DHCP_OVERLOAD_SNAME 2 -#define DHCP_OVERLOAD_SNAME_FILE 3 - - -#ifdef __cplusplus -} -#endif - -#endif /*LWIP_HDR_PROT_DHCP_H*/ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/prot/dns.h b/third_party/lwip/repo/lwip/src/include/lwip/prot/dns.h deleted file mode 100644 index 94782d6e9c1e2c..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/prot/dns.h +++ /dev/null @@ -1,140 +0,0 @@ -/** - * @file - * DNS - host name to IP address resolver. - */ - -/* - * Port to lwIP from uIP - * by Jim Pettinato April 2007 - * - * security fixes and more by Simon Goldschmidt - * - * uIP version Copyright (c) 2002-2003, Adam Dunkels. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE - * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef LWIP_HDR_PROT_DNS_H -#define LWIP_HDR_PROT_DNS_H - -#include "lwip/arch.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** DNS server port address */ -#ifndef DNS_SERVER_PORT -#define DNS_SERVER_PORT 53 -#endif - -/* DNS field TYPE used for "Resource Records" */ -#define DNS_RRTYPE_A 1 /* a host address */ -#define DNS_RRTYPE_NS 2 /* an authoritative name server */ -#define DNS_RRTYPE_MD 3 /* a mail destination (Obsolete - use MX) */ -#define DNS_RRTYPE_MF 4 /* a mail forwarder (Obsolete - use MX) */ -#define DNS_RRTYPE_CNAME 5 /* the canonical name for an alias */ -#define DNS_RRTYPE_SOA 6 /* marks the start of a zone of authority */ -#define DNS_RRTYPE_MB 7 /* a mailbox domain name (EXPERIMENTAL) */ -#define DNS_RRTYPE_MG 8 /* a mail group member (EXPERIMENTAL) */ -#define DNS_RRTYPE_MR 9 /* a mail rename domain name (EXPERIMENTAL) */ -#define DNS_RRTYPE_NULL 10 /* a null RR (EXPERIMENTAL) */ -#define DNS_RRTYPE_WKS 11 /* a well known service description */ -#define DNS_RRTYPE_PTR 12 /* a domain name pointer */ -#define DNS_RRTYPE_HINFO 13 /* host information */ -#define DNS_RRTYPE_MINFO 14 /* mailbox or mail list information */ -#define DNS_RRTYPE_MX 15 /* mail exchange */ -#define DNS_RRTYPE_TXT 16 /* text strings */ -#define DNS_RRTYPE_AAAA 28 /* IPv6 address */ -#define DNS_RRTYPE_SRV 33 /* service location */ -#define DNS_RRTYPE_ANY 255 /* any type */ - -/* DNS field CLASS used for "Resource Records" */ -#define DNS_RRCLASS_IN 1 /* the Internet */ -#define DNS_RRCLASS_CS 2 /* the CSNET class (Obsolete - used only for examples in some obsolete RFCs) */ -#define DNS_RRCLASS_CH 3 /* the CHAOS class */ -#define DNS_RRCLASS_HS 4 /* Hesiod [Dyer 87] */ -#define DNS_RRCLASS_ANY 255 /* any class */ -#define DNS_RRCLASS_FLUSH 0x800 /* Flush bit */ - -/* DNS protocol flags */ -#define DNS_FLAG1_RESPONSE 0x80 -#define DNS_FLAG1_OPCODE_STATUS 0x10 -#define DNS_FLAG1_OPCODE_INVERSE 0x08 -#define DNS_FLAG1_OPCODE_STANDARD 0x00 -#define DNS_FLAG1_AUTHORATIVE 0x04 -#define DNS_FLAG1_TRUNC 0x02 -#define DNS_FLAG1_RD 0x01 -#define DNS_FLAG2_RA 0x80 -#define DNS_FLAG2_ERR_MASK 0x0f -#define DNS_FLAG2_ERR_NONE 0x00 -#define DNS_FLAG2_ERR_NAME 0x03 - -#define DNS_HDR_GET_OPCODE(hdr) ((((hdr)->flags1) >> 3) & 0xF) - -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -/** DNS message header */ -struct dns_hdr { - PACK_STRUCT_FIELD(u16_t id); - PACK_STRUCT_FLD_8(u8_t flags1); - PACK_STRUCT_FLD_8(u8_t flags2); - PACK_STRUCT_FIELD(u16_t numquestions); - PACK_STRUCT_FIELD(u16_t numanswers); - PACK_STRUCT_FIELD(u16_t numauthrr); - PACK_STRUCT_FIELD(u16_t numextrarr); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif -#define SIZEOF_DNS_HDR 12 - - -/* Multicast DNS definitions */ - -/** UDP port for multicast DNS queries */ -#ifndef DNS_MQUERY_PORT -#define DNS_MQUERY_PORT 5353 -#endif - -/* IPv4 group for multicast DNS queries: 224.0.0.251 */ -#ifndef DNS_MQUERY_IPV4_GROUP_INIT -#define DNS_MQUERY_IPV4_GROUP_INIT IPADDR4_INIT_BYTES(224,0,0,251) -#endif - -/* IPv6 group for multicast DNS queries: FF02::FB */ -#ifndef DNS_MQUERY_IPV6_GROUP_INIT -#define DNS_MQUERY_IPV6_GROUP_INIT IPADDR6_INIT_HOST(0xFF020000,0,0,0xFB) -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_PROT_DNS_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/prot/etharp.h b/third_party/lwip/repo/lwip/src/include/lwip/prot/etharp.h deleted file mode 100644 index ec78305b822471..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/prot/etharp.h +++ /dev/null @@ -1,91 +0,0 @@ -/** - * @file - * ARP protocol definitions - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_PROT_ETHARP_H -#define LWIP_HDR_PROT_ETHARP_H - -#include "lwip/arch.h" -#include "lwip/prot/ethernet.h" -#include "lwip/ip4_addr.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef ETHARP_HWADDR_LEN -#define ETHARP_HWADDR_LEN ETH_HWADDR_LEN -#endif - -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -/** the ARP message, see RFC 826 ("Packet format") */ -struct etharp_hdr { - PACK_STRUCT_FIELD(u16_t hwtype); - PACK_STRUCT_FIELD(u16_t proto); - PACK_STRUCT_FLD_8(u8_t hwlen); - PACK_STRUCT_FLD_8(u8_t protolen); - PACK_STRUCT_FIELD(u16_t opcode); - PACK_STRUCT_FLD_S(struct eth_addr shwaddr); - PACK_STRUCT_FLD_S(struct ip4_addr2 sipaddr); - PACK_STRUCT_FLD_S(struct eth_addr dhwaddr); - PACK_STRUCT_FLD_S(struct ip4_addr2 dipaddr); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -#define SIZEOF_ETHARP_HDR 28 - -/* ARP hwtype values */ -enum etharp_hwtype { - HWTYPE_ETHERNET = 1 - /* others not used */ -}; - -/* ARP message types (opcodes) */ -enum etharp_opcode { - ARP_REQUEST = 1, - ARP_REPLY = 2 -}; - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_PROT_ETHARP_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/prot/ethernet.h b/third_party/lwip/repo/lwip/src/include/lwip/prot/ethernet.h deleted file mode 100644 index e4baa29dc4d74a..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/prot/ethernet.h +++ /dev/null @@ -1,170 +0,0 @@ -/** - * @file - * Ethernet protocol definitions - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_PROT_ETHERNET_H -#define LWIP_HDR_PROT_ETHERNET_H - -#include "lwip/arch.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef ETH_HWADDR_LEN -#ifdef ETHARP_HWADDR_LEN -#define ETH_HWADDR_LEN ETHARP_HWADDR_LEN /* compatibility mode */ -#else -#define ETH_HWADDR_LEN 6 -#endif -#endif - -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct eth_addr { - PACK_STRUCT_FLD_8(u8_t addr[ETH_HWADDR_LEN]); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -/** Ethernet header */ -struct eth_hdr { -#if ETH_PAD_SIZE - PACK_STRUCT_FLD_8(u8_t padding[ETH_PAD_SIZE]); -#endif - PACK_STRUCT_FLD_S(struct eth_addr dest); - PACK_STRUCT_FLD_S(struct eth_addr src); - PACK_STRUCT_FIELD(u16_t type); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -#define SIZEOF_ETH_HDR (14 + ETH_PAD_SIZE) - -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -/** VLAN header inserted between ethernet header and payload - * if 'type' in ethernet header is ETHTYPE_VLAN. - * See IEEE802.Q */ -struct eth_vlan_hdr { - PACK_STRUCT_FIELD(u16_t prio_vid); - PACK_STRUCT_FIELD(u16_t tpid); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -#define SIZEOF_VLAN_HDR 4 -#define VLAN_ID(vlan_hdr) (lwip_htons((vlan_hdr)->prio_vid) & 0xFFF) - -/** - * @ingroup ethernet - * A list of often ethtypes (although lwIP does not use all of them): */ -enum eth_type { - /** Internet protocol v4 */ - ETHTYPE_IP = 0x0800U, - /** Address resolution protocol */ - ETHTYPE_ARP = 0x0806U, - /** Wake on lan */ - ETHTYPE_WOL = 0x0842U, - /** RARP */ - ETHTYPE_RARP = 0x8035U, - /** Virtual local area network */ - ETHTYPE_VLAN = 0x8100U, - /** Internet protocol v6 */ - ETHTYPE_IPV6 = 0x86DDU, - /** PPP Over Ethernet Discovery Stage */ - ETHTYPE_PPPOEDISC = 0x8863U, - /** PPP Over Ethernet Session Stage */ - ETHTYPE_PPPOE = 0x8864U, - /** Jumbo Frames */ - ETHTYPE_JUMBO = 0x8870U, - /** Process field network */ - ETHTYPE_PROFINET = 0x8892U, - /** Ethernet for control automation technology */ - ETHTYPE_ETHERCAT = 0x88A4U, - /** Link layer discovery protocol */ - ETHTYPE_LLDP = 0x88CCU, - /** Serial real-time communication system */ - ETHTYPE_SERCOS = 0x88CDU, - /** Media redundancy protocol */ - ETHTYPE_MRP = 0x88E3U, - /** Precision time protocol */ - ETHTYPE_PTP = 0x88F7U, - /** Q-in-Q, 802.1ad */ - ETHTYPE_QINQ = 0x9100U -}; - -/** The 24-bit IANA IPv4-multicast OUI is 01-00-5e: */ -#define LL_IP4_MULTICAST_ADDR_0 0x01 -#define LL_IP4_MULTICAST_ADDR_1 0x00 -#define LL_IP4_MULTICAST_ADDR_2 0x5e - -/** IPv6 multicast uses this prefix */ -#define LL_IP6_MULTICAST_ADDR_0 0x33 -#define LL_IP6_MULTICAST_ADDR_1 0x33 - -/** MEMCPY-like macro to copy to/from struct eth_addr's that are local variables - * or known to be 32-bit aligned within the protocol header. */ -#ifndef ETHADDR32_COPY -#define ETHADDR32_COPY(dst, src) SMEMCPY(dst, src, ETH_HWADDR_LEN) -#endif - -/** MEMCPY-like macro to copy to/from struct eth_addr's that are no local - * variables and known to be 16-bit aligned within the protocol header. */ -#ifndef ETHADDR16_COPY -#define ETHADDR16_COPY(dst, src) SMEMCPY(dst, src, ETH_HWADDR_LEN) -#endif - -#define eth_addr_cmp(addr1, addr2) (memcmp((addr1)->addr, (addr2)->addr, ETH_HWADDR_LEN) == 0) - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_PROT_ETHERNET_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/prot/icmp.h b/third_party/lwip/repo/lwip/src/include/lwip/prot/icmp.h deleted file mode 100644 index 7d19385c7296eb..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/prot/icmp.h +++ /dev/null @@ -1,91 +0,0 @@ -/** - * @file - * ICMP protocol definitions - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_PROT_ICMP_H -#define LWIP_HDR_PROT_ICMP_H - -#include "lwip/arch.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define ICMP_ER 0 /* echo reply */ -#define ICMP_DUR 3 /* destination unreachable */ -#define ICMP_SQ 4 /* source quench */ -#define ICMP_RD 5 /* redirect */ -#define ICMP_ECHO 8 /* echo */ -#define ICMP_TE 11 /* time exceeded */ -#define ICMP_PP 12 /* parameter problem */ -#define ICMP_TS 13 /* timestamp */ -#define ICMP_TSR 14 /* timestamp reply */ -#define ICMP_IRQ 15 /* information request */ -#define ICMP_IR 16 /* information reply */ -#define ICMP_AM 17 /* address mask request */ -#define ICMP_AMR 18 /* address mask reply */ - -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -/** This is the standard ICMP header only that the u32_t data - * is split to two u16_t like ICMP echo needs it. - * This header is also used for other ICMP types that do not - * use the data part. - */ -PACK_STRUCT_BEGIN -struct icmp_echo_hdr { - PACK_STRUCT_FLD_8(u8_t type); - PACK_STRUCT_FLD_8(u8_t code); - PACK_STRUCT_FIELD(u16_t chksum); - PACK_STRUCT_FIELD(u16_t id); - PACK_STRUCT_FIELD(u16_t seqno); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -/* Compatibility defines, old versions used to combine type and code to an u16_t */ -#define ICMPH_TYPE(hdr) ((hdr)->type) -#define ICMPH_CODE(hdr) ((hdr)->code) -#define ICMPH_TYPE_SET(hdr, t) ((hdr)->type = (t)) -#define ICMPH_CODE_SET(hdr, c) ((hdr)->code = (c)) - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_PROT_ICMP_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/prot/icmp6.h b/third_party/lwip/repo/lwip/src/include/lwip/prot/icmp6.h deleted file mode 100644 index 3461120421e44a..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/prot/icmp6.h +++ /dev/null @@ -1,170 +0,0 @@ -/** - * @file - * ICMP6 protocol definitions - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_PROT_ICMP6_H -#define LWIP_HDR_PROT_ICMP6_H - -#include "lwip/arch.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** ICMP type */ -enum icmp6_type { - /** Destination unreachable */ - ICMP6_TYPE_DUR = 1, - /** Packet too big */ - ICMP6_TYPE_PTB = 2, - /** Time exceeded */ - ICMP6_TYPE_TE = 3, - /** Parameter problem */ - ICMP6_TYPE_PP = 4, - /** Private experimentation */ - ICMP6_TYPE_PE1 = 100, - /** Private experimentation */ - ICMP6_TYPE_PE2 = 101, - /** Reserved for expansion of error messages */ - ICMP6_TYPE_RSV_ERR = 127, - - /** Echo request */ - ICMP6_TYPE_EREQ = 128, - /** Echo reply */ - ICMP6_TYPE_EREP = 129, - /** Multicast listener query */ - ICMP6_TYPE_MLQ = 130, - /** Multicast listener report */ - ICMP6_TYPE_MLR = 131, - /** Multicast listener done */ - ICMP6_TYPE_MLD = 132, - /** Router solicitation */ - ICMP6_TYPE_RS = 133, - /** Router advertisement */ - ICMP6_TYPE_RA = 134, - /** Neighbor solicitation */ - ICMP6_TYPE_NS = 135, - /** Neighbor advertisement */ - ICMP6_TYPE_NA = 136, - /** Redirect */ - ICMP6_TYPE_RD = 137, - /** Multicast router advertisement */ - ICMP6_TYPE_MRA = 151, - /** Multicast router solicitation */ - ICMP6_TYPE_MRS = 152, - /** Multicast router termination */ - ICMP6_TYPE_MRT = 153, - /** Private experimentation */ - ICMP6_TYPE_PE3 = 200, - /** Private experimentation */ - ICMP6_TYPE_PE4 = 201, - /** Reserved for expansion of informational messages */ - ICMP6_TYPE_RSV_INF = 255 -}; - -/** ICMP destination unreachable codes */ -enum icmp6_dur_code { - /** No route to destination */ - ICMP6_DUR_NO_ROUTE = 0, - /** Communication with destination administratively prohibited */ - ICMP6_DUR_PROHIBITED = 1, - /** Beyond scope of source address */ - ICMP6_DUR_SCOPE = 2, - /** Address unreachable */ - ICMP6_DUR_ADDRESS = 3, - /** Port unreachable */ - ICMP6_DUR_PORT = 4, - /** Source address failed ingress/egress policy */ - ICMP6_DUR_POLICY = 5, - /** Reject route to destination */ - ICMP6_DUR_REJECT_ROUTE = 6 -}; - -/** ICMP time exceeded codes */ -enum icmp6_te_code { - /** Hop limit exceeded in transit */ - ICMP6_TE_HL = 0, - /** Fragment reassembly time exceeded */ - ICMP6_TE_FRAG = 1 -}; - -/** ICMP parameter code */ -enum icmp6_pp_code { - /** Erroneous header field encountered */ - ICMP6_PP_FIELD = 0, - /** Unrecognized next header type encountered */ - ICMP6_PP_HEADER = 1, - /** Unrecognized IPv6 option encountered */ - ICMP6_PP_OPTION = 2 -}; - -/** This is the standard ICMP6 header. */ -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct icmp6_hdr { - PACK_STRUCT_FLD_8(u8_t type); - PACK_STRUCT_FLD_8(u8_t code); - PACK_STRUCT_FIELD(u16_t chksum); - PACK_STRUCT_FIELD(u32_t data); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -/** This is the ICMP6 header adapted for echo req/resp. */ -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct icmp6_echo_hdr { - PACK_STRUCT_FLD_8(u8_t type); - PACK_STRUCT_FLD_8(u8_t code); - PACK_STRUCT_FIELD(u16_t chksum); - PACK_STRUCT_FIELD(u16_t id); - PACK_STRUCT_FIELD(u16_t seqno); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_PROT_ICMP6_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/prot/igmp.h b/third_party/lwip/repo/lwip/src/include/lwip/prot/igmp.h deleted file mode 100644 index d60cb31ee7ccfd..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/prot/igmp.h +++ /dev/null @@ -1,90 +0,0 @@ -/** - * @file - * IGMP protocol definitions - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_PROT_IGMP_H -#define LWIP_HDR_PROT_IGMP_H - -#include "lwip/arch.h" -#include "lwip/ip4_addr.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * IGMP constants - */ -#define IGMP_TTL 1 -#define IGMP_MINLEN 8 -#define ROUTER_ALERT 0x9404U -#define ROUTER_ALERTLEN 4 - -/* - * IGMP message types, including version number. - */ -#define IGMP_MEMB_QUERY 0x11 /* Membership query */ -#define IGMP_V1_MEMB_REPORT 0x12 /* Ver. 1 membership report */ -#define IGMP_V2_MEMB_REPORT 0x16 /* Ver. 2 membership report */ -#define IGMP_LEAVE_GROUP 0x17 /* Leave-group message */ - -/* Group membership states */ -#define IGMP_GROUP_NON_MEMBER 0 -#define IGMP_GROUP_DELAYING_MEMBER 1 -#define IGMP_GROUP_IDLE_MEMBER 2 - -/** - * IGMP packet format. - */ -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct igmp_msg { - PACK_STRUCT_FLD_8(u8_t igmp_msgtype); - PACK_STRUCT_FLD_8(u8_t igmp_maxresp); - PACK_STRUCT_FIELD(u16_t igmp_checksum); - PACK_STRUCT_FLD_S(ip4_addr_p_t igmp_group_address); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_PROT_IGMP_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/prot/ip.h b/third_party/lwip/repo/lwip/src/include/lwip/prot/ip.h deleted file mode 100644 index bbfae367527515..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/prot/ip.h +++ /dev/null @@ -1,51 +0,0 @@ -/** - * @file - * IP protocol definitions - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_PROT_IP_H -#define LWIP_HDR_PROT_IP_H - -#include "lwip/arch.h" - -#define IP_PROTO_ICMP 1 -#define IP_PROTO_IGMP 2 -#define IP_PROTO_UDP 17 -#define IP_PROTO_UDPLITE 136 -#define IP_PROTO_TCP 6 - -/** This operates on a void* by loading the first byte */ -#define IP_HDR_GET_VERSION(ptr) ((*(u8_t*)(ptr)) >> 4) - -#endif /* LWIP_HDR_PROT_IP_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/prot/ip4.h b/third_party/lwip/repo/lwip/src/include/lwip/prot/ip4.h deleted file mode 100644 index bd442c6892ce5a..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/prot/ip4.h +++ /dev/null @@ -1,127 +0,0 @@ -/** - * @file - * IPv4 protocol definitions - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_PROT_IP4_H -#define LWIP_HDR_PROT_IP4_H - -#include "lwip/arch.h" -#include "lwip/ip4_addr.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** This is the packed version of ip4_addr_t, - used in network headers that are itself packed */ -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct ip4_addr_packed { - PACK_STRUCT_FIELD(u32_t addr); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -typedef struct ip4_addr_packed ip4_addr_p_t; - -/* Size of the IPv4 header. Same as 'sizeof(struct ip_hdr)'. */ -#define IP_HLEN 20 - -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -/* The IPv4 header */ -struct ip_hdr { - /* version / header length */ - PACK_STRUCT_FLD_8(u8_t _v_hl); - /* type of service */ - PACK_STRUCT_FLD_8(u8_t _tos); - /* total length */ - PACK_STRUCT_FIELD(u16_t _len); - /* identification */ - PACK_STRUCT_FIELD(u16_t _id); - /* fragment offset field */ - PACK_STRUCT_FIELD(u16_t _offset); -#define IP_RF 0x8000U /* reserved fragment flag */ -#define IP_DF 0x4000U /* don't fragment flag */ -#define IP_MF 0x2000U /* more fragments flag */ -#define IP_OFFMASK 0x1fffU /* mask for fragmenting bits */ - /* time to live */ - PACK_STRUCT_FLD_8(u8_t _ttl); - /* protocol*/ - PACK_STRUCT_FLD_8(u8_t _proto); - /* checksum */ - PACK_STRUCT_FIELD(u16_t _chksum); - /* source and destination IP addresses */ - PACK_STRUCT_FLD_S(ip4_addr_p_t src); - PACK_STRUCT_FLD_S(ip4_addr_p_t dest); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -/* Macros to get struct ip_hdr fields: */ -#define IPH_V(hdr) ((hdr)->_v_hl >> 4) -#define IPH_HL(hdr) ((hdr)->_v_hl & 0x0f) -#define IPH_TOS(hdr) ((hdr)->_tos) -#define IPH_LEN(hdr) ((hdr)->_len) -#define IPH_ID(hdr) ((hdr)->_id) -#define IPH_OFFSET(hdr) ((hdr)->_offset) -#define IPH_TTL(hdr) ((hdr)->_ttl) -#define IPH_PROTO(hdr) ((hdr)->_proto) -#define IPH_CHKSUM(hdr) ((hdr)->_chksum) - -/* Macros to set struct ip_hdr fields: */ -#define IPH_VHL_SET(hdr, v, hl) (hdr)->_v_hl = (u8_t)((((v) << 4) | (hl))) -#define IPH_TOS_SET(hdr, tos) (hdr)->_tos = (tos) -#define IPH_LEN_SET(hdr, len) (hdr)->_len = (len) -#define IPH_ID_SET(hdr, id) (hdr)->_id = (id) -#define IPH_OFFSET_SET(hdr, off) (hdr)->_offset = (off) -#define IPH_TTL_SET(hdr, ttl) (hdr)->_ttl = (u8_t)(ttl) -#define IPH_PROTO_SET(hdr, proto) (hdr)->_proto = (u8_t)(proto) -#define IPH_CHKSUM_SET(hdr, chksum) (hdr)->_chksum = (chksum) - - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_PROT_IP4_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/prot/ip6.h b/third_party/lwip/repo/lwip/src/include/lwip/prot/ip6.h deleted file mode 100644 index 61a553d101fd13..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/prot/ip6.h +++ /dev/null @@ -1,171 +0,0 @@ -/** - * @file - * IPv6 protocol definitions - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_PROT_IP6_H -#define LWIP_HDR_PROT_IP6_H - -#include "lwip/arch.h" -#include "lwip/ip6_addr.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define IP6_MIN_MTU 1280 - -/** This is the packed version of ip6_addr_t, - used in network headers that are itself packed */ -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct ip6_addr_packed { - PACK_STRUCT_FIELD(u32_t addr[4]); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif -typedef struct ip6_addr_packed ip6_addr_p_t; - -#define IP6_HLEN 40 - -#define IP6_NEXTH_HOPBYHOP 0 -#define IP6_NEXTH_TCP 6 -#define IP6_NEXTH_UDP 17 -#define IP6_NEXTH_ENCAPS 41 -#define IP6_NEXTH_ROUTING 43 -#define IP6_NEXTH_FRAGMENT 44 -#define IP6_NEXTH_ICMP6 58 -#define IP6_NEXTH_NONE 59 -#define IP6_NEXTH_DESTOPTS 60 -#define IP6_NEXTH_UDPLITE 136 - -/** The IPv6 header. */ -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct ip6_hdr { - /** version / traffic class / flow label */ - PACK_STRUCT_FIELD(u32_t _v_tc_fl); - /** payload length */ - PACK_STRUCT_FIELD(u16_t _plen); - /** next header */ - PACK_STRUCT_FLD_8(u8_t _nexth); - /** hop limit */ - PACK_STRUCT_FLD_8(u8_t _hoplim); - /** source and destination IP addresses */ - PACK_STRUCT_FLD_S(ip6_addr_p_t src); - PACK_STRUCT_FLD_S(ip6_addr_p_t dest); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -/* Hop-by-hop router alert option. */ -#define IP6_HBH_HLEN 8 -#define IP6_PAD1_OPTION 0 -#define IP6_PADN_ALERT_OPTION 1 -#define IP6_ROUTER_ALERT_OPTION 5 -#define IP6_ROUTER_ALERT_VALUE_MLD 0 -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct ip6_hbh_hdr { - /* next header */ - PACK_STRUCT_FLD_8(u8_t _nexth); - /* header length */ - PACK_STRUCT_FLD_8(u8_t _hlen); - /* router alert option type */ - PACK_STRUCT_FLD_8(u8_t _ra_opt_type); - /* router alert option data len */ - PACK_STRUCT_FLD_8(u8_t _ra_opt_dlen); - /* router alert option data */ - PACK_STRUCT_FIELD(u16_t _ra_opt_data); - /* PadN option type */ - PACK_STRUCT_FLD_8(u8_t _padn_opt_type); - /* PadN option data len */ - PACK_STRUCT_FLD_8(u8_t _padn_opt_dlen); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -/* Fragment header. */ -#define IP6_FRAG_HLEN 8 -#define IP6_FRAG_OFFSET_MASK 0xfff8 -#define IP6_FRAG_MORE_FLAG 0x0001 -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct ip6_frag_hdr { - /* next header */ - PACK_STRUCT_FLD_8(u8_t _nexth); - /* reserved */ - PACK_STRUCT_FLD_8(u8_t reserved); - /* fragment offset */ - PACK_STRUCT_FIELD(u16_t _fragment_offset); - /* fragmented packet identification */ - PACK_STRUCT_FIELD(u32_t _identification); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -#define IP6H_V(hdr) ((lwip_ntohl((hdr)->_v_tc_fl) >> 28) & 0x0f) -#define IP6H_TC(hdr) ((lwip_ntohl((hdr)->_v_tc_fl) >> 20) & 0xff) -#define IP6H_FL(hdr) (lwip_ntohl((hdr)->_v_tc_fl) & 0x000fffff) -#define IP6H_PLEN(hdr) (lwip_ntohs((hdr)->_plen)) -#define IP6H_NEXTH(hdr) ((hdr)->_nexth) -#define IP6H_NEXTH_P(hdr) ((u8_t *)(hdr) + 6) -#define IP6H_HOPLIM(hdr) ((hdr)->_hoplim) - -#define IP6H_VTCFL_SET(hdr, v, tc, fl) (hdr)->_v_tc_fl = (lwip_htonl((((u32_t)(v)) << 28) | (((u32_t)(tc)) << 20) | (fl))) -#define IP6H_PLEN_SET(hdr, plen) (hdr)->_plen = lwip_htons(plen) -#define IP6H_NEXTH_SET(hdr, nexth) (hdr)->_nexth = (nexth) -#define IP6H_HOPLIM_SET(hdr, hl) (hdr)->_hoplim = (u8_t)(hl) - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_PROT_IP6_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/prot/mld6.h b/third_party/lwip/repo/lwip/src/include/lwip/prot/mld6.h deleted file mode 100644 index be3a006af25baa..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/prot/mld6.h +++ /dev/null @@ -1,70 +0,0 @@ -/** - * @file - * MLD6 protocol definitions - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_PROT_MLD6_H -#define LWIP_HDR_PROT_MLD6_H - -#include "lwip/arch.h" -#include "lwip/prot/ip6.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** Multicast listener report/query/done message header. */ -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct mld_header { - PACK_STRUCT_FLD_8(u8_t type); - PACK_STRUCT_FLD_8(u8_t code); - PACK_STRUCT_FIELD(u16_t chksum); - PACK_STRUCT_FIELD(u16_t max_resp_delay); - PACK_STRUCT_FIELD(u16_t reserved); - PACK_STRUCT_FLD_S(ip6_addr_p_t multicast_address); - /* Options follow. */ -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_PROT_MLD6_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/prot/nd6.h b/third_party/lwip/repo/lwip/src/include/lwip/prot/nd6.h deleted file mode 100644 index 4455066d547632..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/prot/nd6.h +++ /dev/null @@ -1,290 +0,0 @@ -/** - * @file - * ND6 protocol definitions - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_PROT_ND6_H -#define LWIP_HDR_PROT_ND6_H - -#include "lwip/arch.h" -#include "lwip/ip6_addr.h" -#include "lwip/prot/ip6.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** Neighbor solicitation message header. */ -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct ns_header { - PACK_STRUCT_FLD_8(u8_t type); - PACK_STRUCT_FLD_8(u8_t code); - PACK_STRUCT_FIELD(u16_t chksum); - PACK_STRUCT_FIELD(u32_t reserved); - PACK_STRUCT_FLD_S(ip6_addr_p_t target_address); - /* Options follow. */ -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -/** Neighbor advertisement message header. */ -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct na_header { - PACK_STRUCT_FLD_8(u8_t type); - PACK_STRUCT_FLD_8(u8_t code); - PACK_STRUCT_FIELD(u16_t chksum); - PACK_STRUCT_FLD_8(u8_t flags); - PACK_STRUCT_FLD_8(u8_t reserved[3]); - PACK_STRUCT_FLD_S(ip6_addr_p_t target_address); - /* Options follow. */ -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif -#define ND6_FLAG_ROUTER (0x80) -#define ND6_FLAG_SOLICITED (0x40) -#define ND6_FLAG_OVERRIDE (0x20) - -/** Router solicitation message header. */ -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct rs_header { - PACK_STRUCT_FLD_8(u8_t type); - PACK_STRUCT_FLD_8(u8_t code); - PACK_STRUCT_FIELD(u16_t chksum); - PACK_STRUCT_FIELD(u32_t reserved); - /* Options follow. */ -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -/** Router advertisement message header. */ -#define ND6_RA_FLAG_MANAGED_ADDR_CONFIG (0x80) -#define ND6_RA_FLAG_OTHER_CONFIG (0x40) -#define ND6_RA_FLAG_HOME_AGENT (0x20) -#define ND6_RA_PREFERENCE_MASK (0x18) -#define ND6_RA_PREFERENCE_HIGH (0x08) -#define ND6_RA_PREFERENCE_MEDIUM (0x00) -#define ND6_RA_PREFERENCE_LOW (0x18) -#define ND6_RA_PREFERENCE_DISABLED (0x10) -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct ra_header { - PACK_STRUCT_FLD_8(u8_t type); - PACK_STRUCT_FLD_8(u8_t code); - PACK_STRUCT_FIELD(u16_t chksum); - PACK_STRUCT_FLD_8(u8_t current_hop_limit); - PACK_STRUCT_FLD_8(u8_t flags); - PACK_STRUCT_FIELD(u16_t router_lifetime); - PACK_STRUCT_FIELD(u32_t reachable_time); - PACK_STRUCT_FIELD(u32_t retrans_timer); - /* Options follow. */ -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -/** Redirect message header. */ -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct redirect_header { - PACK_STRUCT_FLD_8(u8_t type); - PACK_STRUCT_FLD_8(u8_t code); - PACK_STRUCT_FIELD(u16_t chksum); - PACK_STRUCT_FIELD(u32_t reserved); - PACK_STRUCT_FLD_S(ip6_addr_p_t target_address); - PACK_STRUCT_FLD_S(ip6_addr_p_t destination_address); - /* Options follow. */ -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -/** Link-layer address option. */ -#define ND6_OPTION_TYPE_SOURCE_LLADDR (0x01) -#define ND6_OPTION_TYPE_TARGET_LLADDR (0x02) -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct lladdr_option { - PACK_STRUCT_FLD_8(u8_t type); - PACK_STRUCT_FLD_8(u8_t length); - PACK_STRUCT_FLD_8(u8_t addr[NETIF_MAX_HWADDR_LEN]); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -/** The address field is variable and not fixed in length, use the - * appropriate macros when accessing the length field or calculating - * the option size. - */ -#define __OFFSETOF(t, m) ((size_t)(&(((t *)0)->m))) -#define __ROUND_UP(n, m) ((((n) + ((m) - 1)) / (m)) * (m)) -#define ND6_LLADDR_OPTION_LENGTH_SHIFT 3 -#define ND6_LLADDR_OPTION_LENGTH_SIZE (1 << ND6_LLADDR_OPTION_LENGTH_SHIFT) -#define ND6_LLADDR_OPTION_LENGTH_MASK (ND6_LLADDR_OPTION_LENGTH_SIZE - 1) -#define ND6_LLADDR_OPTION_LENGTH_ENCODE(hwlen) (__ROUND_UP(hwlen, ND6_LLADDR_OPTION_LENGTH_SIZE) >> ND6_LLADDR_OPTION_LENGTH_SHIFT) -#define ND6_LLADDR_OPTION_LENGTH_DECODE(value) ((value) << ND6_LLADDR_OPTION_LENGTH_SHIFT) -#define ND6_LLADDR_OPTION_SIZE(hwlen) (__OFFSETOF(struct lladdr_option, addr) + (hwlen)) - -/** Prefix information option. */ -#define ND6_OPTION_TYPE_PREFIX_INFO (0x03) -#define ND6_PREFIX_FLAG_ON_LINK (0x80) -#define ND6_PREFIX_FLAG_AUTONOMOUS (0x40) -#define ND6_PREFIX_FLAG_ROUTER_ADDRESS (0x20) -#define ND6_PREFIX_FLAG_SITE_PREFIX (0x10) -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct prefix_option { - PACK_STRUCT_FLD_8(u8_t type); - PACK_STRUCT_FLD_8(u8_t length); - PACK_STRUCT_FLD_8(u8_t prefix_length); - PACK_STRUCT_FLD_8(u8_t flags); - PACK_STRUCT_FIELD(u32_t valid_lifetime); - PACK_STRUCT_FIELD(u32_t preferred_lifetime); - PACK_STRUCT_FLD_8(u8_t reserved2[3]); - PACK_STRUCT_FLD_8(u8_t site_prefix_length); - PACK_STRUCT_FLD_S(ip6_addr_p_t prefix); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -/** Redirected header option. */ -#define ND6_OPTION_TYPE_REDIR_HDR (0x04) -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct redirected_header_option { - PACK_STRUCT_FLD_8(u8_t type); - PACK_STRUCT_FLD_8(u8_t length); - PACK_STRUCT_FLD_8(u8_t reserved[6]); - /* Portion of redirected packet follows. */ - /* PACK_STRUCT_FLD_8(u8_t redirected[8]); */ -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -/** MTU option. */ -#define ND6_OPTION_TYPE_MTU (0x05) -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct mtu_option { - PACK_STRUCT_FLD_8(u8_t type); - PACK_STRUCT_FLD_8(u8_t length); - PACK_STRUCT_FIELD(u16_t reserved); - PACK_STRUCT_FIELD(u32_t mtu); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -/** Route information option. */ -#define ND6_OPTION_TYPE_ROUTE_INFO (24) -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct route_option { - PACK_STRUCT_FLD_8(u8_t type); - PACK_STRUCT_FLD_8(u8_t length); - PACK_STRUCT_FLD_8(u8_t prefix_length); - PACK_STRUCT_FLD_8(u8_t preference); - PACK_STRUCT_FIELD(u32_t route_lifetime); - PACK_STRUCT_FLD_S(ip6_addr_p_t prefix); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -/** Recursive DNS Server Option. */ -#if LWIP_ND6_RDNSS_MAX_DNS_SERVERS -#define LWIP_RDNSS_OPTION_MAX_SERVERS LWIP_ND6_RDNSS_MAX_DNS_SERVERS -#else -#define LWIP_RDNSS_OPTION_MAX_SERVERS 1 -#endif -#define ND6_OPTION_TYPE_RDNSS (25) -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct rdnss_option { - PACK_STRUCT_FLD_8(u8_t type); - PACK_STRUCT_FLD_8(u8_t length); - PACK_STRUCT_FIELD(u16_t reserved); - PACK_STRUCT_FIELD(u32_t lifetime); - PACK_STRUCT_FLD_S(ip6_addr_p_t rdnss_address[LWIP_RDNSS_OPTION_MAX_SERVERS]); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_PROT_ND6_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/prot/tcp.h b/third_party/lwip/repo/lwip/src/include/lwip/prot/tcp.h deleted file mode 100644 index b251b80a88dc01..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/prot/tcp.h +++ /dev/null @@ -1,98 +0,0 @@ -/** - * @file - * TCP protocol definitions - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_PROT_TCP_H -#define LWIP_HDR_PROT_TCP_H - -#include "lwip/arch.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* Length of the TCP header, excluding options. */ -#define TCP_HLEN 20 - -/* Fields are (of course) in network byte order. - * Some fields are converted to host byte order in tcp_input(). - */ -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct tcp_hdr { - PACK_STRUCT_FIELD(u16_t src); - PACK_STRUCT_FIELD(u16_t dest); - PACK_STRUCT_FIELD(u32_t seqno); - PACK_STRUCT_FIELD(u32_t ackno); - PACK_STRUCT_FIELD(u16_t _hdrlen_rsvd_flags); - PACK_STRUCT_FIELD(u16_t wnd); - PACK_STRUCT_FIELD(u16_t chksum); - PACK_STRUCT_FIELD(u16_t urgp); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -/* TCP header flags bits */ -#define TCP_FIN 0x01U -#define TCP_SYN 0x02U -#define TCP_RST 0x04U -#define TCP_PSH 0x08U -#define TCP_ACK 0x10U -#define TCP_URG 0x20U -#define TCP_ECE 0x40U -#define TCP_CWR 0x80U -/* Valid TCP header flags */ -#define TCP_FLAGS 0x3fU - -#define TCPH_HDRLEN(phdr) ((u16_t)(lwip_ntohs((phdr)->_hdrlen_rsvd_flags) >> 12)) -#define TCPH_HDRLEN_BYTES(phdr) ((u8_t)(TCPH_HDRLEN(phdr) << 2)) -#define TCPH_FLAGS(phdr) ((u16_t)(lwip_ntohs((phdr)->_hdrlen_rsvd_flags) & TCP_FLAGS)) - -#define TCPH_HDRLEN_SET(phdr, len) (phdr)->_hdrlen_rsvd_flags = lwip_htons(((len) << 12) | TCPH_FLAGS(phdr)) -#define TCPH_FLAGS_SET(phdr, flags) (phdr)->_hdrlen_rsvd_flags = (((phdr)->_hdrlen_rsvd_flags & PP_HTONS(~TCP_FLAGS)) | lwip_htons(flags)) -#define TCPH_HDRLEN_FLAGS_SET(phdr, len, flags) (phdr)->_hdrlen_rsvd_flags = (u16_t)(lwip_htons((u16_t)((len) << 12) | (flags))) - -#define TCPH_SET_FLAG(phdr, flags ) (phdr)->_hdrlen_rsvd_flags = ((phdr)->_hdrlen_rsvd_flags | lwip_htons(flags)) -#define TCPH_UNSET_FLAG(phdr, flags) (phdr)->_hdrlen_rsvd_flags = ((phdr)->_hdrlen_rsvd_flags & ~lwip_htons(flags)) - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_PROT_TCP_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/prot/udp.h b/third_party/lwip/repo/lwip/src/include/lwip/prot/udp.h deleted file mode 100644 index 664f19a3e7bd7b..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/prot/udp.h +++ /dev/null @@ -1,68 +0,0 @@ -/** - * @file - * UDP protocol definitions - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_PROT_UDP_H -#define LWIP_HDR_PROT_UDP_H - -#include "lwip/arch.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define UDP_HLEN 8 - -/* Fields are (of course) in network byte order. */ -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct udp_hdr { - PACK_STRUCT_FIELD(u16_t src); - PACK_STRUCT_FIELD(u16_t dest); /* src/dest UDP ports */ - PACK_STRUCT_FIELD(u16_t len); - PACK_STRUCT_FIELD(u16_t chksum); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_PROT_UDP_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/raw.h b/third_party/lwip/repo/lwip/src/include/lwip/raw.h deleted file mode 100644 index 787d918027c536..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/raw.h +++ /dev/null @@ -1,147 +0,0 @@ -/** - * @file - * raw API (to be used from TCPIP thread)\n - * See also @ref raw_raw - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_RAW_H -#define LWIP_HDR_RAW_H - -#include "lwip/opt.h" - -#if LWIP_RAW /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/pbuf.h" -#include "lwip/def.h" -#include "lwip/ip.h" -#include "lwip/ip_addr.h" -#include "lwip/ip6_addr.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define RAW_FLAGS_CONNECTED 0x01U -#define RAW_FLAGS_MULTICAST_LOOP 0x04U - -struct raw_pcb; - -/** Function prototype for raw pcb receive callback functions. - * @param arg user supplied argument (raw_pcb.recv_arg) - * @param pcb the raw_pcb which received data - * @param p the packet buffer that was received - * @param addr the remote IP address from which the packet was received - * @return 1 if the packet was 'eaten' (aka. deleted), - * 0 if the packet lives on - * If returning 1, the callback is responsible for freeing the pbuf - * if it's not used any more. - */ -typedef u8_t (*raw_recv_fn)(void *arg, struct raw_pcb *pcb, struct pbuf *p, - const ip_addr_t *addr); - -/** the RAW protocol control block */ -struct raw_pcb { - /* Common members of all PCB types */ - IP_PCB; - - struct raw_pcb *next; - struct netif *intf_filter; - - u8_t protocol; - u8_t flags; - -#if LWIP_MULTICAST_TX_OPTIONS - /** outgoing network interface for multicast packets, by interface index (if nonzero) */ - u8_t mcast_ifindex; - /** TTL for outgoing multicast packets */ - u8_t mcast_ttl; -#endif /* LWIP_MULTICAST_TX_OPTIONS */ - - /** receive callback function */ - raw_recv_fn recv; - /* user-supplied argument for the recv callback */ - void *recv_arg; -#if LWIP_IPV6 - /* fields for handling checksum computations as per RFC3542. */ - u16_t chksum_offset; - u8_t chksum_reqd; -#endif -}; - -/* The following functions is the application layer interface to the - RAW code. */ -struct raw_pcb * raw_new (u8_t proto); -struct raw_pcb * raw_new_ip_type(u8_t type, u8_t proto); -void raw_remove (struct raw_pcb *pcb); -err_t raw_bind (struct raw_pcb *pcb, const ip_addr_t *ipaddr); -void raw_bind_netif (struct raw_pcb *pcb, const struct netif *netif); -err_t raw_connect (struct raw_pcb *pcb, const ip_addr_t *ipaddr); -void raw_disconnect (struct raw_pcb *pcb); - -err_t raw_sendto (struct raw_pcb *pcb, struct pbuf *p, const ip_addr_t *ipaddr); -err_t raw_sendto_if_src(struct raw_pcb *pcb, struct pbuf *p, const ip_addr_t *dst_ip, struct netif *netif, const ip_addr_t *src_ip); -err_t raw_send (struct raw_pcb *pcb, struct pbuf *p); - -void raw_recv (struct raw_pcb *pcb, raw_recv_fn recv, void *recv_arg); - -#define raw_flags(pcb) ((pcb)->flags) -#define raw_setflags(pcb,f) ((pcb)->flags = (f)) - -#define raw_set_flags(pcb, set_flags) do { (pcb)->flags = (u8_t)((pcb)->flags | (set_flags)); } while(0) -#define raw_clear_flags(pcb, clr_flags) do { (pcb)->flags = (u8_t)((pcb)->flags & ~(clr_flags)); } while(0) -#define raw_is_flag_set(pcb, flag) (((pcb)->flags & (flag)) != 0) - -/* The following functions are the lower layer interface to RAW. */ -u8_t raw_input (struct pbuf *p, struct netif *inp); -#define raw_init() /* Compatibility define, no init needed. */ - -void raw_netif_ip_addr_changed(const ip_addr_t* old_addr, const ip_addr_t* new_addr); - -/* for compatibility with older implementation */ -#define raw_new_ip6(proto) raw_new_ip_type(IPADDR_TYPE_V6, proto) - -#if LWIP_MULTICAST_TX_OPTIONS -#define raw_set_multicast_netif_index(pcb, idx) ((pcb)->mcast_ifindex = (idx)) -#define raw_get_multicast_netif_index(pcb) ((pcb)->mcast_ifindex) -#define raw_set_multicast_ttl(pcb, value) ((pcb)->mcast_ttl = (value)) -#define raw_get_multicast_ttl(pcb) ((pcb)->mcast_ttl) -#endif /* LWIP_MULTICAST_TX_OPTIONS */ - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_RAW */ - -#endif /* LWIP_HDR_RAW_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/sio.h b/third_party/lwip/repo/lwip/src/include/lwip/sio.h deleted file mode 100644 index 7643e195697e2c..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/sio.h +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - */ - -/* - * This is the interface to the platform specific serial IO module - * It needs to be implemented by those platforms which need SLIP or PPP - */ - -#ifndef SIO_H -#define SIO_H - -#include "lwip/arch.h" -#include "lwip/opt.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* If you want to define sio_fd_t elsewhere or differently, - define this in your cc.h file. */ -#ifndef __sio_fd_t_defined -typedef void * sio_fd_t; -#endif - -/* The following functions can be defined to something else in your cc.h file - or be implemented in your custom sio.c file. */ - -#ifndef sio_open -/** - * Opens a serial device for communication. - * - * @param devnum device number - * @return handle to serial device if successful, NULL otherwise - */ -sio_fd_t sio_open(u8_t devnum); -#endif - -#ifndef sio_send -/** - * Sends a single character to the serial device. - * - * @param c character to send - * @param fd serial device handle - * - * @note This function will block until the character can be sent. - */ -void sio_send(u8_t c, sio_fd_t fd); -#endif - -#ifndef sio_recv -/** - * Receives a single character from the serial device. - * - * @param fd serial device handle - * - * @note This function will block until a character is received. - */ -u8_t sio_recv(sio_fd_t fd); -#endif - -#ifndef sio_read -/** - * Reads from the serial device. - * - * @param fd serial device handle - * @param data pointer to data buffer for receiving - * @param len maximum length (in bytes) of data to receive - * @return number of bytes actually received - may be 0 if aborted by sio_read_abort - * - * @note This function will block until data can be received. The blocking - * can be cancelled by calling sio_read_abort(). - */ -u32_t sio_read(sio_fd_t fd, u8_t *data, u32_t len); -#endif - -#ifndef sio_tryread -/** - * Tries to read from the serial device. Same as sio_read but returns - * immediately if no data is available and never blocks. - * - * @param fd serial device handle - * @param data pointer to data buffer for receiving - * @param len maximum length (in bytes) of data to receive - * @return number of bytes actually received - */ -u32_t sio_tryread(sio_fd_t fd, u8_t *data, u32_t len); -#endif - -#ifndef sio_write -/** - * Writes to the serial device. - * - * @param fd serial device handle - * @param data pointer to data to send - * @param len length (in bytes) of data to send - * @return number of bytes actually sent - * - * @note This function will block until all data can be sent. - */ -u32_t sio_write(sio_fd_t fd, u8_t *data, u32_t len); -#endif - -#ifndef sio_read_abort -/** - * Aborts a blocking sio_read() call. - * - * @param fd serial device handle - */ -void sio_read_abort(sio_fd_t fd); -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* SIO_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/snmp.h b/third_party/lwip/repo/lwip/src/include/lwip/snmp.h deleted file mode 100644 index 8704d0b4d2955b..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/snmp.h +++ /dev/null @@ -1,213 +0,0 @@ -/** - * @file - * SNMP support API for implementing netifs and statitics for MIB2 - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Dirk Ziegelmeier - * - */ -#ifndef LWIP_HDR_SNMP_H -#define LWIP_HDR_SNMP_H - -#include "lwip/opt.h" -#include "lwip/ip_addr.h" - -#ifdef __cplusplus -extern "C" { -#endif - -struct udp_pcb; -struct netif; - -/** - * @defgroup netif_mib2 MIB2 statistics - * @ingroup netif - */ - -/* MIB2 statistics functions */ -#if MIB2_STATS /* don't build if not configured for use in lwipopts.h */ -/** - * @ingroup netif_mib2 - * @see RFC1213, "MIB-II, 6. Definitions" - */ -enum snmp_ifType { - snmp_ifType_other=1, /* none of the following */ - snmp_ifType_regular1822, - snmp_ifType_hdh1822, - snmp_ifType_ddn_x25, - snmp_ifType_rfc877_x25, - snmp_ifType_ethernet_csmacd, - snmp_ifType_iso88023_csmacd, - snmp_ifType_iso88024_tokenBus, - snmp_ifType_iso88025_tokenRing, - snmp_ifType_iso88026_man, - snmp_ifType_starLan, - snmp_ifType_proteon_10Mbit, - snmp_ifType_proteon_80Mbit, - snmp_ifType_hyperchannel, - snmp_ifType_fddi, - snmp_ifType_lapb, - snmp_ifType_sdlc, - snmp_ifType_ds1, /* T-1 */ - snmp_ifType_e1, /* european equiv. of T-1 */ - snmp_ifType_basicISDN, - snmp_ifType_primaryISDN, /* proprietary serial */ - snmp_ifType_propPointToPointSerial, - snmp_ifType_ppp, - snmp_ifType_softwareLoopback, - snmp_ifType_eon, /* CLNP over IP [11] */ - snmp_ifType_ethernet_3Mbit, - snmp_ifType_nsip, /* XNS over IP */ - snmp_ifType_slip, /* generic SLIP */ - snmp_ifType_ultra, /* ULTRA technologies */ - snmp_ifType_ds3, /* T-3 */ - snmp_ifType_sip, /* SMDS */ - snmp_ifType_frame_relay -}; - -/** This macro has a precision of ~49 days because sys_now returns u32_t. \#define your own if you want ~490 days. */ -#ifndef MIB2_COPY_SYSUPTIME_TO -#define MIB2_COPY_SYSUPTIME_TO(ptrToVal) (*(ptrToVal) = (sys_now() / 10)) -#endif - -/** - * @ingroup netif_mib2 - * Increment stats member for SNMP MIB2 stats (struct stats_mib2_netif_ctrs) - */ -#define MIB2_STATS_NETIF_INC(n, x) do { ++(n)->mib2_counters.x; } while(0) -/** - * @ingroup netif_mib2 - * Add value to stats member for SNMP MIB2 stats (struct stats_mib2_netif_ctrs) - */ -#define MIB2_STATS_NETIF_ADD(n, x, val) do { (n)->mib2_counters.x += (val); } while(0) - -/** - * @ingroup netif_mib2 - * Init MIB2 statistic counters in netif - * @param netif Netif to init - * @param type one of enum @ref snmp_ifType - * @param speed your link speed here (units: bits per second) - */ -#define MIB2_INIT_NETIF(netif, type, speed) do { \ - (netif)->link_type = (type); \ - (netif)->link_speed = (speed);\ - (netif)->ts = 0; \ - (netif)->mib2_counters.ifinoctets = 0; \ - (netif)->mib2_counters.ifinucastpkts = 0; \ - (netif)->mib2_counters.ifinnucastpkts = 0; \ - (netif)->mib2_counters.ifindiscards = 0; \ - (netif)->mib2_counters.ifinerrors = 0; \ - (netif)->mib2_counters.ifinunknownprotos = 0; \ - (netif)->mib2_counters.ifoutoctets = 0; \ - (netif)->mib2_counters.ifoutucastpkts = 0; \ - (netif)->mib2_counters.ifoutnucastpkts = 0; \ - (netif)->mib2_counters.ifoutdiscards = 0; \ - (netif)->mib2_counters.ifouterrors = 0; } while(0) -#else /* MIB2_STATS */ -#ifndef MIB2_COPY_SYSUPTIME_TO -#define MIB2_COPY_SYSUPTIME_TO(ptrToVal) -#endif -#define MIB2_INIT_NETIF(netif, type, speed) -#define MIB2_STATS_NETIF_INC(n, x) -#define MIB2_STATS_NETIF_ADD(n, x, val) -#endif /* MIB2_STATS */ - -/* LWIP MIB2 callbacks */ -#if LWIP_MIB2_CALLBACKS /* don't build if not configured for use in lwipopts.h */ -/* network interface */ -void mib2_netif_added(struct netif *ni); -void mib2_netif_removed(struct netif *ni); - -#if LWIP_IPV4 && LWIP_ARP -/* ARP (for atTable and ipNetToMediaTable) */ -void mib2_add_arp_entry(struct netif *ni, ip4_addr_t *ip); -void mib2_remove_arp_entry(struct netif *ni, ip4_addr_t *ip); -#else /* LWIP_IPV4 && LWIP_ARP */ -#define mib2_add_arp_entry(ni,ip) -#define mib2_remove_arp_entry(ni,ip) -#endif /* LWIP_IPV4 && LWIP_ARP */ - -/* IP */ -#if LWIP_IPV4 -void mib2_add_ip4(struct netif *ni); -void mib2_remove_ip4(struct netif *ni); -void mib2_add_route_ip4(u8_t dflt, struct netif *ni); -void mib2_remove_route_ip4(u8_t dflt, struct netif *ni); -#endif /* LWIP_IPV4 */ - -/* UDP */ -#if LWIP_UDP -void mib2_udp_bind(struct udp_pcb *pcb); -void mib2_udp_unbind(struct udp_pcb *pcb); -#endif /* LWIP_UDP */ - -#else /* LWIP_MIB2_CALLBACKS */ -/* LWIP_MIB2_CALLBACKS support not available */ -/* define everything to be empty */ - -/* network interface */ -#define mib2_netif_added(ni) -#define mib2_netif_removed(ni) - -/* ARP */ -#define mib2_add_arp_entry(ni,ip) -#define mib2_remove_arp_entry(ni,ip) - -/* IP */ -#define mib2_add_ip4(ni) -#define mib2_remove_ip4(ni) -#define mib2_add_route_ip4(dflt, ni) -#define mib2_remove_route_ip4(dflt, ni) - -/* UDP */ -#define mib2_udp_bind(pcb) -#define mib2_udp_unbind(pcb) -#endif /* LWIP_MIB2_CALLBACKS */ - -/* for source-code compatibility reasons only, can be removed (not used internally) */ -#define NETIF_INIT_SNMP MIB2_INIT_NETIF -#define snmp_add_ifinoctets(ni,value) MIB2_STATS_NETIF_ADD(ni, ifinoctets, value) -#define snmp_inc_ifinucastpkts(ni) MIB2_STATS_NETIF_INC(ni, ifinucastpkts) -#define snmp_inc_ifinnucastpkts(ni) MIB2_STATS_NETIF_INC(ni, ifinnucastpkts) -#define snmp_inc_ifindiscards(ni) MIB2_STATS_NETIF_INC(ni, ifindiscards) -#define snmp_inc_ifinerrors(ni) MIB2_STATS_NETIF_INC(ni, ifinerrors) -#define snmp_inc_ifinunknownprotos(ni) MIB2_STATS_NETIF_INC(ni, ifinunknownprotos) -#define snmp_add_ifoutoctets(ni,value) MIB2_STATS_NETIF_ADD(ni, ifoutoctets, value) -#define snmp_inc_ifoutucastpkts(ni) MIB2_STATS_NETIF_INC(ni, ifoutucastpkts) -#define snmp_inc_ifoutnucastpkts(ni) MIB2_STATS_NETIF_INC(ni, ifoutnucastpkts) -#define snmp_inc_ifoutdiscards(ni) MIB2_STATS_NETIF_INC(ni, ifoutdiscards) -#define snmp_inc_ifouterrors(ni) MIB2_STATS_NETIF_INC(ni, ifouterrors) - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_SNMP_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/sockets.h b/third_party/lwip/repo/lwip/src/include/lwip/sockets.h deleted file mode 100644 index 2522056dba4284..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/sockets.h +++ /dev/null @@ -1,593 +0,0 @@ -/** - * @file - * Socket API (to be used from non-TCPIP threads) - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ - - -#ifndef LWIP_HDR_SOCKETS_H -#define LWIP_HDR_SOCKETS_H - -#include "lwip/opt.h" - -#if LWIP_SOCKET /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/ip_addr.h" -#include "lwip/err.h" -#include "lwip/inet.h" -#include "lwip/errno.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* If your port already typedef's sa_family_t, define SA_FAMILY_T_DEFINED - to prevent this code from redefining it. */ -#if !defined(sa_family_t) && !defined(SA_FAMILY_T_DEFINED) -typedef u8_t sa_family_t; -#endif -/* If your port already typedef's in_port_t, define IN_PORT_T_DEFINED - to prevent this code from redefining it. */ -#if !defined(in_port_t) && !defined(IN_PORT_T_DEFINED) -typedef u16_t in_port_t; -#endif - -#if LWIP_IPV4 -/* members are in network byte order */ -struct sockaddr_in { - u8_t sin_len; - sa_family_t sin_family; - in_port_t sin_port; - struct in_addr sin_addr; -#define SIN_ZERO_LEN 8 - char sin_zero[SIN_ZERO_LEN]; -}; -#endif /* LWIP_IPV4 */ - -#if LWIP_IPV6 -struct sockaddr_in6 { - u8_t sin6_len; /* length of this structure */ - sa_family_t sin6_family; /* AF_INET6 */ - in_port_t sin6_port; /* Transport layer port # */ - u32_t sin6_flowinfo; /* IPv6 flow information */ - struct in6_addr sin6_addr; /* IPv6 address */ - u32_t sin6_scope_id; /* Set of interfaces for scope */ -}; -#endif /* LWIP_IPV6 */ - -struct sockaddr { - u8_t sa_len; - sa_family_t sa_family; - char sa_data[14]; -}; - -struct sockaddr_storage { - u8_t s2_len; - sa_family_t ss_family; - char s2_data1[2]; - u32_t s2_data2[3]; -#if LWIP_IPV6 - u32_t s2_data3[3]; -#endif /* LWIP_IPV6 */ -}; - -/* If your port already typedef's socklen_t, define SOCKLEN_T_DEFINED - to prevent this code from redefining it. */ -#if !defined(socklen_t) && !defined(SOCKLEN_T_DEFINED) -typedef u32_t socklen_t; -#endif - -struct lwip_sock; - -#if !LWIP_TCPIP_CORE_LOCKING -/** Maximum optlen used by setsockopt/getsockopt */ -#define LWIP_SETGETSOCKOPT_MAXOPTLEN 16 - -/** This struct is used to pass data to the set/getsockopt_internal - * functions running in tcpip_thread context (only a void* is allowed) */ -struct lwip_setgetsockopt_data { - /** socket index for which to change options */ - int s; - /** level of the option to process */ - int level; - /** name of the option to process */ - int optname; - /** set: value to set the option to - * get: value of the option is stored here */ -#if LWIP_MPU_COMPATIBLE - u8_t optval[LWIP_SETGETSOCKOPT_MAXOPTLEN]; -#else - union { - void *p; - const void *pc; - } optval; -#endif - /** size of *optval */ - socklen_t optlen; - /** if an error occurs, it is temporarily stored here */ - err_t err; - /** semaphore to wake up the calling task */ - void* completed_sem; -}; -#endif /* !LWIP_TCPIP_CORE_LOCKING */ - -#if !defined(iovec) -struct iovec { - void *iov_base; - size_t iov_len; -}; -#endif - -struct msghdr { - void *msg_name; - socklen_t msg_namelen; - struct iovec *msg_iov; - int msg_iovlen; - void *msg_control; - socklen_t msg_controllen; - int msg_flags; -}; - -/* Socket protocol types (TCP/UDP/RAW) */ -#define SOCK_STREAM 1 -#define SOCK_DGRAM 2 -#define SOCK_RAW 3 - -/* - * Option flags per-socket. These must match the SOF_ flags in ip.h (checked in init.c) - */ -#define SO_REUSEADDR 0x0004 /* Allow local address reuse */ -#define SO_KEEPALIVE 0x0008 /* keep connections alive */ -#define SO_BROADCAST 0x0020 /* permit to send and to receive broadcast messages (see IP_SOF_BROADCAST option) */ - - -/* - * Additional options, not kept in so_options. - */ -#define SO_DEBUG 0x0001 /* Unimplemented: turn on debugging info recording */ -#define SO_ACCEPTCONN 0x0002 /* socket has had listen() */ -#define SO_DONTROUTE 0x0010 /* Unimplemented: just use interface addresses */ -#define SO_USELOOPBACK 0x0040 /* Unimplemented: bypass hardware when possible */ -#define SO_LINGER 0x0080 /* linger on close if data present */ -#define SO_DONTLINGER ((int)(~SO_LINGER)) -#define SO_OOBINLINE 0x0100 /* Unimplemented: leave received OOB data in line */ -#define SO_REUSEPORT 0x0200 /* Unimplemented: allow local address & port reuse */ -#define SO_SNDBUF 0x1001 /* Unimplemented: send buffer size */ -#define SO_RCVBUF 0x1002 /* receive buffer size */ -#define SO_SNDLOWAT 0x1003 /* Unimplemented: send low-water mark */ -#define SO_RCVLOWAT 0x1004 /* Unimplemented: receive low-water mark */ -#define SO_SNDTIMEO 0x1005 /* send timeout */ -#define SO_RCVTIMEO 0x1006 /* receive timeout */ -#define SO_ERROR 0x1007 /* get error status and clear */ -#define SO_TYPE 0x1008 /* get socket type */ -#define SO_CONTIMEO 0x1009 /* Unimplemented: connect timeout */ -#define SO_NO_CHECK 0x100a /* don't create UDP checksum */ - - -/* - * Structure used for manipulating linger option. - */ -struct linger { - int l_onoff; /* option on/off */ - int l_linger; /* linger time in seconds */ -}; - -/* - * Level number for (get/set)sockopt() to apply to socket itself. - */ -#define SOL_SOCKET 0xfff /* options for socket level */ - - -#define AF_UNSPEC 0 -#define AF_INET 2 -#if LWIP_IPV6 -#define AF_INET6 10 -#else /* LWIP_IPV6 */ -#define AF_INET6 AF_UNSPEC -#endif /* LWIP_IPV6 */ -#define PF_INET AF_INET -#define PF_INET6 AF_INET6 -#define PF_UNSPEC AF_UNSPEC - -#define IPPROTO_IP 0 -#define IPPROTO_ICMP 1 -#define IPPROTO_TCP 6 -#define IPPROTO_UDP 17 -#if LWIP_IPV6 -#define IPPROTO_IPV6 41 -#define IPPROTO_ICMPV6 58 -#endif /* LWIP_IPV6 */ -#define IPPROTO_UDPLITE 136 -#define IPPROTO_RAW 255 - -/* Flags we can use with send and recv. */ -#define MSG_PEEK 0x01 /* Peeks at an incoming message */ -#define MSG_WAITALL 0x02 /* Unimplemented: Requests that the function block until the full amount of data requested can be returned */ -#define MSG_OOB 0x04 /* Unimplemented: Requests out-of-band data. The significance and semantics of out-of-band data are protocol-specific */ -#define MSG_DONTWAIT 0x08 /* Nonblocking i/o for this operation only */ -#define MSG_MORE 0x10 /* Sender will send more */ - - -/* - * Options for level IPPROTO_IP - */ -#define IP_TOS 1 -#define IP_TTL 2 - -#if LWIP_TCP -/* - * Options for level IPPROTO_TCP - */ -#define TCP_NODELAY 0x01 /* don't delay send to coalesce packets */ -#define TCP_KEEPALIVE 0x02 /* send KEEPALIVE probes when idle for pcb->keep_idle milliseconds */ -#define TCP_KEEPIDLE 0x03 /* set pcb->keep_idle - Same as TCP_KEEPALIVE, but use seconds for get/setsockopt */ -#define TCP_KEEPINTVL 0x04 /* set pcb->keep_intvl - Use seconds for get/setsockopt */ -#define TCP_KEEPCNT 0x05 /* set pcb->keep_cnt - Use number of probes sent for get/setsockopt */ -#endif /* LWIP_TCP */ - -#if LWIP_IPV6 -/* - * Options for level IPPROTO_IPV6 - */ -#define IPV6_CHECKSUM 7 /* RFC3542: calculate and insert the ICMPv6 checksum for raw sockets. */ -#define IPV6_V6ONLY 27 /* RFC3493: boolean control to restrict AF_INET6 sockets to IPv6 communications only. */ -#endif /* LWIP_IPV6 */ - -#if LWIP_UDP && LWIP_UDPLITE -/* - * Options for level IPPROTO_UDPLITE - */ -#define UDPLITE_SEND_CSCOV 0x01 /* sender checksum coverage */ -#define UDPLITE_RECV_CSCOV 0x02 /* minimal receiver checksum coverage */ -#endif /* LWIP_UDP && LWIP_UDPLITE*/ - - -#if LWIP_MULTICAST_TX_OPTIONS -/* - * Options and types for UDP multicast traffic handling - */ -#define IP_MULTICAST_TTL 5 -#define IP_MULTICAST_IF 6 -#define IP_MULTICAST_LOOP 7 -#endif /* LWIP_MULTICAST_TX_OPTIONS */ - -#if LWIP_IGMP -/* - * Options and types related to multicast membership - */ -#define IP_ADD_MEMBERSHIP 3 -#define IP_DROP_MEMBERSHIP 4 - -typedef struct ip_mreq { - struct in_addr imr_multiaddr; /* IP multicast address of group */ - struct in_addr imr_interface; /* local IP address of interface */ -} ip_mreq; -#endif /* LWIP_IGMP */ - -/* - * The Type of Service provides an indication of the abstract - * parameters of the quality of service desired. These parameters are - * to be used to guide the selection of the actual service parameters - * when transmitting a datagram through a particular network. Several - * networks offer service precedence, which somehow treats high - * precedence traffic as more important than other traffic (generally - * by accepting only traffic above a certain precedence at time of high - * load). The major choice is a three way tradeoff between low-delay, - * high-reliability, and high-throughput. - * The use of the Delay, Throughput, and Reliability indications may - * increase the cost (in some sense) of the service. In many networks - * better performance for one of these parameters is coupled with worse - * performance on another. Except for very unusual cases at most two - * of these three indications should be set. - */ -#define IPTOS_TOS_MASK 0x1E -#define IPTOS_TOS(tos) ((tos) & IPTOS_TOS_MASK) -#define IPTOS_LOWDELAY 0x10 -#define IPTOS_THROUGHPUT 0x08 -#define IPTOS_RELIABILITY 0x04 -#define IPTOS_LOWCOST 0x02 -#define IPTOS_MINCOST IPTOS_LOWCOST - -/* - * The Network Control precedence designation is intended to be used - * within a network only. The actual use and control of that - * designation is up to each network. The Internetwork Control - * designation is intended for use by gateway control originators only. - * If the actual use of these precedence designations is of concern to - * a particular network, it is the responsibility of that network to - * control the access to, and use of, those precedence designations. - */ -#define IPTOS_PREC_MASK 0xe0 -#define IPTOS_PREC(tos) ((tos) & IPTOS_PREC_MASK) -#define IPTOS_PREC_NETCONTROL 0xe0 -#define IPTOS_PREC_INTERNETCONTROL 0xc0 -#define IPTOS_PREC_CRITIC_ECP 0xa0 -#define IPTOS_PREC_FLASHOVERRIDE 0x80 -#define IPTOS_PREC_FLASH 0x60 -#define IPTOS_PREC_IMMEDIATE 0x40 -#define IPTOS_PREC_PRIORITY 0x20 -#define IPTOS_PREC_ROUTINE 0x00 - - -/* - * Commands for ioctlsocket(), taken from the BSD file fcntl.h. - * lwip_ioctl only supports FIONREAD and FIONBIO, for now - * - * Ioctl's have the command encoded in the lower word, - * and the size of any in or out parameters in the upper - * word. The high 2 bits of the upper word are used - * to encode the in/out status of the parameter; for now - * we restrict parameters to at most 128 bytes. - */ -#if !defined(FIONREAD) || !defined(FIONBIO) -#define IOCPARM_MASK 0x7fU /* parameters must be < 128 bytes */ -#define IOC_VOID 0x20000000UL /* no parameters */ -#define IOC_OUT 0x40000000UL /* copy out parameters */ -#define IOC_IN 0x80000000UL /* copy in parameters */ -#define IOC_INOUT (IOC_IN|IOC_OUT) - /* 0x20000000 distinguishes new & - old ioctl's */ -#define _IO(x,y) (IOC_VOID|((x)<<8)|(y)) - -#define _IOR(x,y,t) (IOC_OUT|(((long)sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y)) - -#define _IOW(x,y,t) (IOC_IN|(((long)sizeof(t)&IOCPARM_MASK)<<16)|((x)<<8)|(y)) -#endif /* !defined(FIONREAD) || !defined(FIONBIO) */ - -#ifndef FIONREAD -#define FIONREAD _IOR('f', 127, unsigned long) /* get # bytes to read */ -#endif -#ifndef FIONBIO -#define FIONBIO _IOW('f', 126, unsigned long) /* set/clear non-blocking i/o */ -#endif - -/* Socket I/O Controls: unimplemented */ -#ifndef SIOCSHIWAT -#define SIOCSHIWAT _IOW('s', 0, unsigned long) /* set high watermark */ -#define SIOCGHIWAT _IOR('s', 1, unsigned long) /* get high watermark */ -#define SIOCSLOWAT _IOW('s', 2, unsigned long) /* set low watermark */ -#define SIOCGLOWAT _IOR('s', 3, unsigned long) /* get low watermark */ -#define SIOCATMARK _IOR('s', 7, unsigned long) /* at oob mark? */ -#endif - -/* commands for fnctl */ -#ifndef F_GETFL -#define F_GETFL 3 -#endif -#ifndef F_SETFL -#define F_SETFL 4 -#endif - -/* File status flags and file access modes for fnctl, - these are bits in an int. */ -#ifndef O_NONBLOCK -#define O_NONBLOCK 1 /* nonblocking I/O */ -#endif -#ifndef O_NDELAY -#define O_NDELAY 1 /* same as O_NONBLOCK, for compatibility */ -#endif - -#ifndef SHUT_RD - #define SHUT_RD 0 - #define SHUT_WR 1 - #define SHUT_RDWR 2 -#endif - -/* FD_SET used for lwip_select */ -#ifndef FD_SET -#undef FD_SETSIZE -/* Make FD_SETSIZE match NUM_SOCKETS in socket.c */ -#define FD_SETSIZE MEMP_NUM_NETCONN -#define FDSETSAFESET(n, code) do { \ - if (((n) - LWIP_SOCKET_OFFSET < MEMP_NUM_NETCONN) && (((int)(n) - LWIP_SOCKET_OFFSET) >= 0)) { \ - code; }} while(0) -#define FDSETSAFEGET(n, code) (((n) - LWIP_SOCKET_OFFSET < MEMP_NUM_NETCONN) && (((int)(n) - LWIP_SOCKET_OFFSET) >= 0) ?\ - (code) : 0) -#define FD_SET(n, p) FDSETSAFESET(n, (p)->fd_bits[((n)-LWIP_SOCKET_OFFSET)/8] |= (1 << (((n)-LWIP_SOCKET_OFFSET) & 7))) -#define FD_CLR(n, p) FDSETSAFESET(n, (p)->fd_bits[((n)-LWIP_SOCKET_OFFSET)/8] &= ~(1 << (((n)-LWIP_SOCKET_OFFSET) & 7))) -#define FD_ISSET(n,p) FDSETSAFEGET(n, (p)->fd_bits[((n)-LWIP_SOCKET_OFFSET)/8] & (1 << (((n)-LWIP_SOCKET_OFFSET) & 7))) -#define FD_ZERO(p) memset((void*)(p), 0, sizeof(*(p))) - -typedef struct fd_set -{ - unsigned char fd_bits [(FD_SETSIZE+7)/8]; -} fd_set; - -#elif LWIP_SOCKET_OFFSET -#error LWIP_SOCKET_OFFSET does not work with external FD_SET! -#elif FD_SETSIZE < MEMP_NUM_NETCONN -#error "external FD_SETSIZE too small for number of sockets" -#endif /* FD_SET */ - -/** LWIP_TIMEVAL_PRIVATE: if you want to use the struct timeval provided - * by your system, set this to 0 and include in cc.h */ -#ifndef LWIP_TIMEVAL_PRIVATE -#define LWIP_TIMEVAL_PRIVATE 1 -#endif - -#if LWIP_TIMEVAL_PRIVATE -struct timeval { - long tv_sec; /* seconds */ - long tv_usec; /* and microseconds */ -}; -#endif /* LWIP_TIMEVAL_PRIVATE */ - -#define lwip_socket_init() /* Compatibility define, no init needed. */ -void lwip_socket_thread_init(void); /* LWIP_NETCONN_SEM_PER_THREAD==1: initialize thread-local semaphore */ -void lwip_socket_thread_cleanup(void); /* LWIP_NETCONN_SEM_PER_THREAD==1: destroy thread-local semaphore */ - -#if LWIP_COMPAT_SOCKETS == 2 -/* This helps code parsers/code completion by not having the COMPAT functions as defines */ -#define lwip_accept accept -#define lwip_bind bind -#define lwip_shutdown shutdown -#define lwip_getpeername getpeername -#define lwip_getsockname getsockname -#define lwip_setsockopt setsockopt -#define lwip_getsockopt getsockopt -#define lwip_close closesocket -#define lwip_connect connect -#define lwip_listen listen -#define lwip_recv recv -#define lwip_recvfrom recvfrom -#define lwip_send send -#define lwip_sendmsg sendmsg -#define lwip_sendto sendto -#define lwip_socket socket -#define lwip_select select -#define lwip_ioctlsocket ioctl - -#if LWIP_POSIX_SOCKETS_IO_NAMES -#define lwip_read read -#define lwip_write write -#define lwip_writev writev -#undef lwip_close -#define lwip_close close -#define closesocket(s) close(s) -#define lwip_fcntl fcntl -#define lwip_ioctl ioctl -#endif /* LWIP_POSIX_SOCKETS_IO_NAMES */ -#endif /* LWIP_COMPAT_SOCKETS == 2 */ - -int lwip_accept(int s, struct sockaddr *addr, socklen_t *addrlen); -int lwip_bind(int s, const struct sockaddr *name, socklen_t namelen); -int lwip_shutdown(int s, int how); -int lwip_getpeername (int s, struct sockaddr *name, socklen_t *namelen); -int lwip_getsockname (int s, struct sockaddr *name, socklen_t *namelen); -int lwip_getsockopt (int s, int level, int optname, void *optval, socklen_t *optlen); -int lwip_setsockopt (int s, int level, int optname, const void *optval, socklen_t optlen); -int lwip_close(int s); -int lwip_connect(int s, const struct sockaddr *name, socklen_t namelen); -int lwip_listen(int s, int backlog); -int lwip_recv(int s, void *mem, size_t len, int flags); -int lwip_read(int s, void *mem, size_t len); -int lwip_recvfrom(int s, void *mem, size_t len, int flags, - struct sockaddr *from, socklen_t *fromlen); -int lwip_send(int s, const void *dataptr, size_t size, int flags); -int lwip_sendmsg(int s, const struct msghdr *message, int flags); -int lwip_sendto(int s, const void *dataptr, size_t size, int flags, - const struct sockaddr *to, socklen_t tolen); -int lwip_socket(int domain, int type, int protocol); -int lwip_write(int s, const void *dataptr, size_t size); -int lwip_writev(int s, const struct iovec *iov, int iovcnt); -int lwip_select(int maxfdp1, fd_set *readset, fd_set *writeset, fd_set *exceptset, - struct timeval *timeout); -int lwip_ioctl(int s, long cmd, void *argp); -int lwip_fcntl(int s, int cmd, int val); - -#if LWIP_COMPAT_SOCKETS -#if LWIP_COMPAT_SOCKETS != 2 -/** @ingroup socket */ -#define accept(s,addr,addrlen) lwip_accept(s,addr,addrlen) -/** @ingroup socket */ -#define bind(s,name,namelen) lwip_bind(s,name,namelen) -/** @ingroup socket */ -#define shutdown(s,how) lwip_shutdown(s,how) -/** @ingroup socket */ -#define getpeername(s,name,namelen) lwip_getpeername(s,name,namelen) -/** @ingroup socket */ -#define getsockname(s,name,namelen) lwip_getsockname(s,name,namelen) -/** @ingroup socket */ -#define setsockopt(s,level,optname,opval,optlen) lwip_setsockopt(s,level,optname,opval,optlen) -/** @ingroup socket */ -#define getsockopt(s,level,optname,opval,optlen) lwip_getsockopt(s,level,optname,opval,optlen) -/** @ingroup socket */ -#define closesocket(s) lwip_close(s) -/** @ingroup socket */ -#define connect(s,name,namelen) lwip_connect(s,name,namelen) -/** @ingroup socket */ -#define listen(s,backlog) lwip_listen(s,backlog) -/** @ingroup socket */ -#define recv(s,mem,len,flags) lwip_recv(s,mem,len,flags) -/** @ingroup socket */ -#define recvfrom(s,mem,len,flags,from,fromlen) lwip_recvfrom(s,mem,len,flags,from,fromlen) -/** @ingroup socket */ -#define send(s,dataptr,size,flags) lwip_send(s,dataptr,size,flags) -/** @ingroup socket */ -#define sendmsg(s,message,flags) lwip_sendmsg(s,message,flags) -/** @ingroup socket */ -#define sendto(s,dataptr,size,flags,to,tolen) lwip_sendto(s,dataptr,size,flags,to,tolen) -/** @ingroup socket */ -#define socket(domain,type,protocol) lwip_socket(domain,type,protocol) -/** @ingroup socket */ -#define select(maxfdp1,readset,writeset,exceptset,timeout) lwip_select(maxfdp1,readset,writeset,exceptset,timeout) -/** @ingroup socket */ -#define ioctlsocket(s,cmd,argp) lwip_ioctl(s,cmd,argp) - -#if LWIP_POSIX_SOCKETS_IO_NAMES -/** @ingroup socket */ -#define read(s,mem,len) lwip_read(s,mem,len) -/** @ingroup socket */ -#define write(s,dataptr,len) lwip_write(s,dataptr,len) -/** @ingroup socket */ -#define writev(s,iov,iovcnt) lwip_writev(s,iov,iovcnt) -/** @ingroup socket */ -#define close(s) lwip_close(s) -/** @ingroup socket */ -#define fcntl(s,cmd,val) lwip_fcntl(s,cmd,val) -/** @ingroup socket */ -#define ioctl(s,cmd,argp) lwip_ioctl(s,cmd,argp) -#endif /* LWIP_POSIX_SOCKETS_IO_NAMES */ -#endif /* LWIP_COMPAT_SOCKETS != 2 */ - -#if LWIP_IPV4 && LWIP_IPV6 -/** @ingroup socket */ -#define inet_ntop(af,src,dst,size) \ - (((af) == AF_INET6) ? ip6addr_ntoa_r((const ip6_addr_t*)(src),(dst),(size)) \ - : (((af) == AF_INET) ? ip4addr_ntoa_r((const ip4_addr_t*)(src),(dst),(size)) : NULL)) -/** @ingroup socket */ -#define inet_pton(af,src,dst) \ - (((af) == AF_INET6) ? ip6addr_aton((src),(ip6_addr_t*)(dst)) \ - : (((af) == AF_INET) ? ip4addr_aton((src),(ip4_addr_t*)(dst)) : 0)) -#elif LWIP_IPV4 /* LWIP_IPV4 && LWIP_IPV6 */ -#define inet_ntop(af,src,dst,size) \ - (((af) == AF_INET) ? ip4addr_ntoa_r((const ip4_addr_t*)(src),(dst),(size)) : NULL) -#define inet_pton(af,src,dst) \ - (((af) == AF_INET) ? ip4addr_aton((src),(ip4_addr_t*)(dst)) : 0) -#else /* LWIP_IPV4 && LWIP_IPV6 */ -#define inet_ntop(af,src,dst,size) \ - (((af) == AF_INET6) ? ip6addr_ntoa_r((const ip6_addr_t*)(src),(dst),(size)) : NULL) -#define inet_pton(af,src,dst) \ - (((af) == AF_INET6) ? ip6addr_aton((src),(ip6_addr_t*)(dst)) : 0) -#endif /* LWIP_IPV4 && LWIP_IPV6 */ - -#endif /* LWIP_COMPAT_SOCKETS */ - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_SOCKET */ - -#endif /* LWIP_HDR_SOCKETS_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/stats.h b/third_party/lwip/repo/lwip/src/include/lwip/stats.h deleted file mode 100644 index b570dbacf589d0..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/stats.h +++ /dev/null @@ -1,491 +0,0 @@ -/** - * @file - * Statistics API (to be used from TCPIP thread) - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_STATS_H -#define LWIP_HDR_STATS_H - -#include "lwip/opt.h" - -#include "lwip/mem.h" -#include "lwip/memp.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#if LWIP_STATS - -#ifndef LWIP_STATS_LARGE -#define LWIP_STATS_LARGE 0 -#endif - -#if LWIP_STATS_LARGE -#define STAT_COUNTER u32_t -#define STAT_COUNTER_F U32_F -#else -#define STAT_COUNTER u16_t -#define STAT_COUNTER_F U16_F -#endif - -/** Protocol related stats */ -struct stats_proto { - STAT_COUNTER xmit; /* Transmitted packets. */ - STAT_COUNTER recv; /* Received packets. */ - STAT_COUNTER fw; /* Forwarded packets. */ - STAT_COUNTER drop; /* Dropped packets. */ - STAT_COUNTER chkerr; /* Checksum error. */ - STAT_COUNTER lenerr; /* Invalid length error. */ - STAT_COUNTER memerr; /* Out of memory error. */ - STAT_COUNTER rterr; /* Routing error. */ - STAT_COUNTER proterr; /* Protocol error. */ - STAT_COUNTER opterr; /* Error in options. */ - STAT_COUNTER err; /* Misc error. */ - STAT_COUNTER cachehit; -}; - -/** IGMP stats */ -struct stats_igmp { - STAT_COUNTER xmit; /* Transmitted packets. */ - STAT_COUNTER recv; /* Received packets. */ - STAT_COUNTER drop; /* Dropped packets. */ - STAT_COUNTER chkerr; /* Checksum error. */ - STAT_COUNTER lenerr; /* Invalid length error. */ - STAT_COUNTER memerr; /* Out of memory error. */ - STAT_COUNTER proterr; /* Protocol error. */ - STAT_COUNTER rx_v1; /* Received v1 frames. */ - STAT_COUNTER rx_group; /* Received group-specific queries. */ - STAT_COUNTER rx_general; /* Received general queries. */ - STAT_COUNTER rx_report; /* Received reports. */ - STAT_COUNTER tx_join; /* Sent joins. */ - STAT_COUNTER tx_leave; /* Sent leaves. */ - STAT_COUNTER tx_report; /* Sent reports. */ -}; - -/** Memory stats */ -struct stats_mem { -#if defined(LWIP_DEBUG) || LWIP_STATS_DISPLAY - const char *name; -#endif /* defined(LWIP_DEBUG) || LWIP_STATS_DISPLAY */ - STAT_COUNTER err; - mem_size_t avail; - mem_size_t used; - mem_size_t max; - STAT_COUNTER illegal; -}; - -/** System element stats */ -struct stats_syselem { - STAT_COUNTER used; - STAT_COUNTER max; - STAT_COUNTER err; -}; - -/** System stats */ -struct stats_sys { - struct stats_syselem sem; - struct stats_syselem mutex; - struct stats_syselem mbox; -}; - -/** SNMP MIB2 stats */ -struct stats_mib2 { - /* IP */ - u32_t ipinhdrerrors; - u32_t ipinaddrerrors; - u32_t ipinunknownprotos; - u32_t ipindiscards; - u32_t ipindelivers; - u32_t ipoutrequests; - u32_t ipoutdiscards; - u32_t ipoutnoroutes; - u32_t ipreasmoks; - u32_t ipreasmfails; - u32_t ipfragoks; - u32_t ipfragfails; - u32_t ipfragcreates; - u32_t ipreasmreqds; - u32_t ipforwdatagrams; - u32_t ipinreceives; - - /* TCP */ - u32_t tcpactiveopens; - u32_t tcppassiveopens; - u32_t tcpattemptfails; - u32_t tcpestabresets; - u32_t tcpoutsegs; - u32_t tcpretranssegs; - u32_t tcpinsegs; - u32_t tcpinerrs; - u32_t tcpoutrsts; - - /* UDP */ - u32_t udpindatagrams; - u32_t udpnoports; - u32_t udpinerrors; - u32_t udpoutdatagrams; - - /* ICMP */ - u32_t icmpinmsgs; - u32_t icmpinerrors; - u32_t icmpindestunreachs; - u32_t icmpintimeexcds; - u32_t icmpinparmprobs; - u32_t icmpinsrcquenchs; - u32_t icmpinredirects; - u32_t icmpinechos; - u32_t icmpinechoreps; - u32_t icmpintimestamps; - u32_t icmpintimestampreps; - u32_t icmpinaddrmasks; - u32_t icmpinaddrmaskreps; - u32_t icmpoutmsgs; - u32_t icmpouterrors; - u32_t icmpoutdestunreachs; - u32_t icmpouttimeexcds; - u32_t icmpoutechos; /* can be incremented by user application ('ping') */ - u32_t icmpoutechoreps; -}; - -/** - * @ingroup netif_mib2 - * SNMP MIB2 interface stats - */ -struct stats_mib2_netif_ctrs { - /** The total number of octets received on the interface, including framing characters */ - u32_t ifinoctets; - /** The number of packets, delivered by this sub-layer to a higher (sub-)layer, which were - * not addressed to a multicast or broadcast address at this sub-layer */ - u32_t ifinucastpkts; - /** The number of packets, delivered by this sub-layer to a higher (sub-)layer, which were - * addressed to a multicast or broadcast address at this sub-layer */ - u32_t ifinnucastpkts; - /** The number of inbound packets which were chosen to be discarded even though no errors had - * been detected to prevent their being deliverable to a higher-layer protocol. One possible - * reason for discarding such a packet could be to free up buffer space */ - u32_t ifindiscards; - /** For packet-oriented interfaces, the number of inbound packets that contained errors - * preventing them from being deliverable to a higher-layer protocol. For character- - * oriented or fixed-length interfaces, the number of inbound transmission units that - * contained errors preventing them from being deliverable to a higher-layer protocol. */ - u32_t ifinerrors; - /** For packet-oriented interfaces, the number of packets received via the interface which - * were discarded because of an unknown or unsupported protocol. For character-oriented - * or fixed-length interfaces that support protocol multiplexing the number of transmission - * units received via the interface which were discarded because of an unknown or unsupported - * protocol. For any interface that does not support protocol multiplexing, this counter will - * always be 0 */ - u32_t ifinunknownprotos; - /** The total number of octets transmitted out of the interface, including framing characters. */ - u32_t ifoutoctets; - /** The total number of packets that higher-level protocols requested be transmitted, and - * which were not addressed to a multicast or broadcast address at this sub-layer, including - * those that were discarded or not sent. */ - u32_t ifoutucastpkts; - /** The total number of packets that higher-level protocols requested be transmitted, and which - * were addressed to a multicast or broadcast address at this sub-layer, including - * those that were discarded or not sent. */ - u32_t ifoutnucastpkts; - /** The number of outbound packets which were chosen to be discarded even though no errors had - * been detected to prevent their being transmitted. One possible reason for discarding - * such a packet could be to free up buffer space. */ - u32_t ifoutdiscards; - /** For packet-oriented interfaces, the number of outbound packets that could not be transmitted - * because of errors. For character-oriented or fixed-length interfaces, the number of outbound - * transmission units that could not be transmitted because of errors. */ - u32_t ifouterrors; -}; - -/** lwIP stats container */ -struct stats_ { -#if LINK_STATS - /** Link level */ - struct stats_proto link; -#endif -#if ETHARP_STATS - /** ARP */ - struct stats_proto etharp; -#endif -#if IPFRAG_STATS - /** Fragmentation */ - struct stats_proto ip_frag; -#endif -#if IP_STATS - /** IP */ - struct stats_proto ip; -#endif -#if ICMP_STATS - /** ICMP */ - struct stats_proto icmp; -#endif -#if IGMP_STATS - /** IGMP */ - struct stats_igmp igmp; -#endif -#if UDP_STATS - /** UDP */ - struct stats_proto udp; -#endif -#if TCP_STATS - /** TCP */ - struct stats_proto tcp; -#endif -#if MEM_STATS - /** Heap */ - struct stats_mem mem; -#endif -#if MEMP_STATS - /** Internal memory pools */ - struct stats_mem *memp[MEMP_MAX]; -#endif -#if SYS_STATS - /** System */ - struct stats_sys sys; -#endif -#if IP6_STATS - /** IPv6 */ - struct stats_proto ip6; -#endif -#if ICMP6_STATS - /** ICMP6 */ - struct stats_proto icmp6; -#endif -#if IP6_FRAG_STATS - /** IPv6 fragmentation */ - struct stats_proto ip6_frag; -#endif -#if MLD6_STATS - /** Multicast listener discovery */ - struct stats_igmp mld6; -#endif -#if ND6_STATS - /** Neighbor discovery */ - struct stats_proto nd6; -#endif -#if MIB2_STATS - /** SNMP MIB2 */ - struct stats_mib2 mib2; -#endif -}; - -/** Global variable containing lwIP internal statistics. Add this to your debugger's watchlist. */ -extern struct stats_ lwip_stats; - -/** Init statistics */ -void stats_init(void); - -#define STATS_INC(x) ++lwip_stats.x -#define STATS_DEC(x) --lwip_stats.x -#define STATS_INC_USED(x, y, type) do { lwip_stats.x.used = (type)(lwip_stats.x.used + y); \ - if (lwip_stats.x.max < lwip_stats.x.used) { \ - lwip_stats.x.max = lwip_stats.x.used; \ - } \ - } while(0) -#define STATS_GET(x) lwip_stats.x -#else /* LWIP_STATS */ -#define stats_init() -#define STATS_INC(x) -#define STATS_DEC(x) -#define STATS_INC_USED(x, y, type) -#endif /* LWIP_STATS */ - -#if TCP_STATS -#define TCP_STATS_INC(x) STATS_INC(x) -#define TCP_STATS_DISPLAY() stats_display_proto(&lwip_stats.tcp, "TCP") -#else -#define TCP_STATS_INC(x) -#define TCP_STATS_DISPLAY() -#endif - -#if UDP_STATS -#define UDP_STATS_INC(x) STATS_INC(x) -#define UDP_STATS_DISPLAY() stats_display_proto(&lwip_stats.udp, "UDP") -#else -#define UDP_STATS_INC(x) -#define UDP_STATS_DISPLAY() -#endif - -#if ICMP_STATS -#define ICMP_STATS_INC(x) STATS_INC(x) -#define ICMP_STATS_DISPLAY() stats_display_proto(&lwip_stats.icmp, "ICMP") -#else -#define ICMP_STATS_INC(x) -#define ICMP_STATS_DISPLAY() -#endif - -#if IGMP_STATS -#define IGMP_STATS_INC(x) STATS_INC(x) -#define IGMP_STATS_DISPLAY() stats_display_igmp(&lwip_stats.igmp, "IGMP") -#else -#define IGMP_STATS_INC(x) -#define IGMP_STATS_DISPLAY() -#endif - -#if IP_STATS -#define IP_STATS_INC(x) STATS_INC(x) -#define IP_STATS_DISPLAY() stats_display_proto(&lwip_stats.ip, "IP") -#else -#define IP_STATS_INC(x) -#define IP_STATS_DISPLAY() -#endif - -#if IPFRAG_STATS -#define IPFRAG_STATS_INC(x) STATS_INC(x) -#define IPFRAG_STATS_DISPLAY() stats_display_proto(&lwip_stats.ip_frag, "IP_FRAG") -#else -#define IPFRAG_STATS_INC(x) -#define IPFRAG_STATS_DISPLAY() -#endif - -#if ETHARP_STATS -#define ETHARP_STATS_INC(x) STATS_INC(x) -#define ETHARP_STATS_DISPLAY() stats_display_proto(&lwip_stats.etharp, "ETHARP") -#else -#define ETHARP_STATS_INC(x) -#define ETHARP_STATS_DISPLAY() -#endif - -#if LINK_STATS -#define LINK_STATS_INC(x) STATS_INC(x) -#define LINK_STATS_DISPLAY() stats_display_proto(&lwip_stats.link, "LINK") -#else -#define LINK_STATS_INC(x) -#define LINK_STATS_DISPLAY() -#endif - -#if MEM_STATS -#define MEM_STATS_AVAIL(x, y) lwip_stats.mem.x = y -#define MEM_STATS_INC(x) STATS_INC(mem.x) -#define MEM_STATS_INC_USED(x, y) STATS_INC_USED(mem, y, mem_size_t) -#define MEM_STATS_DEC_USED(x, y) lwip_stats.mem.x = (mem_size_t)((lwip_stats.mem.x) - (y)) -#define MEM_STATS_DISPLAY() stats_display_mem(&lwip_stats.mem, "HEAP") -#else -#define MEM_STATS_AVAIL(x, y) -#define MEM_STATS_INC(x) -#define MEM_STATS_INC_USED(x, y) -#define MEM_STATS_DEC_USED(x, y) -#define MEM_STATS_DISPLAY() -#endif - - #if MEMP_STATS -#define MEMP_STATS_DEC(x, i) STATS_DEC(memp[i]->x) -#define MEMP_STATS_DISPLAY(i) stats_display_memp(lwip_stats.memp[i], i) -#define MEMP_STATS_GET(x, i) STATS_GET(memp[i]->x) - #else -#define MEMP_STATS_DEC(x, i) -#define MEMP_STATS_DISPLAY(i) -#define MEMP_STATS_GET(x, i) 0 -#endif - -#if SYS_STATS -#define SYS_STATS_INC(x) STATS_INC(sys.x) -#define SYS_STATS_DEC(x) STATS_DEC(sys.x) -#define SYS_STATS_INC_USED(x) STATS_INC_USED(sys.x, 1, STAT_COUNTER) -#define SYS_STATS_DISPLAY() stats_display_sys(&lwip_stats.sys) -#else -#define SYS_STATS_INC(x) -#define SYS_STATS_DEC(x) -#define SYS_STATS_INC_USED(x) -#define SYS_STATS_DISPLAY() -#endif - -#if IP6_STATS -#define IP6_STATS_INC(x) STATS_INC(x) -#define IP6_STATS_DISPLAY() stats_display_proto(&lwip_stats.ip6, "IPv6") -#else -#define IP6_STATS_INC(x) -#define IP6_STATS_DISPLAY() -#endif - -#if ICMP6_STATS -#define ICMP6_STATS_INC(x) STATS_INC(x) -#define ICMP6_STATS_DISPLAY() stats_display_proto(&lwip_stats.icmp6, "ICMPv6") -#else -#define ICMP6_STATS_INC(x) -#define ICMP6_STATS_DISPLAY() -#endif - -#if IP6_FRAG_STATS -#define IP6_FRAG_STATS_INC(x) STATS_INC(x) -#define IP6_FRAG_STATS_DISPLAY() stats_display_proto(&lwip_stats.ip6_frag, "IPv6 FRAG") -#else -#define IP6_FRAG_STATS_INC(x) -#define IP6_FRAG_STATS_DISPLAY() -#endif - -#if MLD6_STATS -#define MLD6_STATS_INC(x) STATS_INC(x) -#define MLD6_STATS_DISPLAY() stats_display_igmp(&lwip_stats.mld6, "MLDv1") -#else -#define MLD6_STATS_INC(x) -#define MLD6_STATS_DISPLAY() -#endif - -#if ND6_STATS -#define ND6_STATS_INC(x) STATS_INC(x) -#define ND6_STATS_DISPLAY() stats_display_proto(&lwip_stats.nd6, "ND") -#else -#define ND6_STATS_INC(x) -#define ND6_STATS_DISPLAY() -#endif - -#if MIB2_STATS -#define MIB2_STATS_INC(x) STATS_INC(x) -#else -#define MIB2_STATS_INC(x) -#endif - -/* Display of statistics */ -#if LWIP_STATS_DISPLAY -void stats_display(void); -void stats_display_proto(struct stats_proto *proto, const char *name); -void stats_display_igmp(struct stats_igmp *igmp, const char *name); -void stats_display_mem(struct stats_mem *mem, const char *name); -void stats_display_memp(struct stats_mem *mem, int index); -void stats_display_sys(struct stats_sys *sys); -#else /* LWIP_STATS_DISPLAY */ -#define stats_display() -#define stats_display_proto(proto, name) -#define stats_display_igmp(igmp, name) -#define stats_display_mem(mem, name) -#define stats_display_memp(mem, index) -#define stats_display_sys(sys) -#endif /* LWIP_STATS_DISPLAY */ - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_STATS_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/sys.h b/third_party/lwip/repo/lwip/src/include/lwip/sys.h deleted file mode 100644 index bb4b96061a7c5c..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/sys.h +++ /dev/null @@ -1,462 +0,0 @@ -/** - * @file - * OS abstraction layer - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - */ - -#ifndef LWIP_HDR_SYS_H -#define LWIP_HDR_SYS_H - -#include "lwip/opt.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#if NO_SYS - -/* For a totally minimal and standalone system, we provide null - definitions of the sys_ functions. */ -typedef u8_t sys_sem_t; -typedef u8_t sys_mutex_t; -typedef u8_t sys_mbox_t; - -#define sys_sem_new(s, c) ERR_OK -#define sys_sem_signal(s) -#define sys_sem_wait(s) -#define sys_arch_sem_wait(s,t) -#define sys_sem_free(s) -#define sys_sem_valid(s) 0 -#define sys_sem_valid_val(s) 0 -#define sys_sem_set_invalid(s) -#define sys_sem_set_invalid_val(s) -#define sys_mutex_new(mu) ERR_OK -#define sys_mutex_lock(mu) -#define sys_mutex_unlock(mu) -#define sys_mutex_free(mu) -#define sys_mutex_valid(mu) 0 -#define sys_mutex_set_invalid(mu) -#define sys_mbox_new(m, s) ERR_OK -#define sys_mbox_fetch(m,d) -#define sys_mbox_tryfetch(m,d) -#define sys_mbox_post(m,d) -#define sys_mbox_trypost(m,d) -#define sys_mbox_free(m) -#define sys_mbox_valid(m) -#define sys_mbox_valid_val(m) -#define sys_mbox_set_invalid(m) -#define sys_mbox_set_invalid_val(m) - -#define sys_thread_new(n,t,a,s,p) -#define sys_thread_finish(a,b) - -#define sys_msleep(t) - -#else /* NO_SYS */ - -/** Return code for timeouts from sys_arch_mbox_fetch and sys_arch_sem_wait */ -#define SYS_ARCH_TIMEOUT 0xffffffffUL - -/** sys_mbox_tryfetch() returns SYS_MBOX_EMPTY if appropriate. - * For now we use the same magic value, but we allow this to change in future. - */ -#define SYS_MBOX_EMPTY SYS_ARCH_TIMEOUT - -#include "lwip/err.h" -#include "arch/sys_arch.h" - -/** Function prototype for thread functions */ -typedef void (*lwip_thread_fn)(void *arg); - -/* Function prototypes for functions to be implemented by platform ports - (in sys_arch.c) */ - -/* Mutex functions: */ - -/** Define LWIP_COMPAT_MUTEX if the port has no mutexes and binary semaphores - should be used instead */ -#ifndef LWIP_COMPAT_MUTEX -#define LWIP_COMPAT_MUTEX 0 -#endif - -#if LWIP_COMPAT_MUTEX -/* for old ports that don't have mutexes: define them to binary semaphores */ -#define sys_mutex_t sys_sem_t -#define sys_mutex_new(mutex) sys_sem_new(mutex, 1) -#define sys_mutex_lock(mutex) sys_sem_wait(mutex) -#define sys_mutex_unlock(mutex) sys_sem_signal(mutex) -#define sys_mutex_free(mutex) sys_sem_free(mutex) -#define sys_mutex_valid(mutex) sys_sem_valid(mutex) -#define sys_mutex_set_invalid(mutex) sys_sem_set_invalid(mutex) - -#else /* LWIP_COMPAT_MUTEX */ - -/** - * @ingroup sys_mutex - * Create a new mutex. - * Note that mutexes are expected to not be taken recursively by the lwIP code, - * so both implementation types (recursive or non-recursive) should work. - * @param mutex pointer to the mutex to create - * @return ERR_OK if successful, another err_t otherwise - */ -err_t sys_mutex_new(sys_mutex_t *mutex); -/** - * @ingroup sys_mutex - * Lock a mutex - * @param mutex the mutex to lock - */ -void sys_mutex_lock(sys_mutex_t *mutex); -/** - * @ingroup sys_mutex - * Unlock a mutex - * @param mutex the mutex to unlock - */ -void sys_mutex_unlock(sys_mutex_t *mutex); -/** - * @ingroup sys_mutex - * Delete a semaphore - * @param mutex the mutex to delete - */ -void sys_mutex_free(sys_mutex_t *mutex); -#ifndef sys_mutex_valid -/** - * @ingroup sys_mutex - * Check if a mutex is valid/allocated: return 1 for valid, 0 for invalid - */ -int sys_mutex_valid(sys_mutex_t *mutex); -#endif -#ifndef sys_mutex_set_invalid -/** - * @ingroup sys_mutex - * Set a mutex invalid so that sys_mutex_valid returns 0 - */ -void sys_mutex_set_invalid(sys_mutex_t *mutex); -#endif -#endif /* LWIP_COMPAT_MUTEX */ - -/* Semaphore functions: */ - -/** - * @ingroup sys_sem - * Create a new semaphore - * @param sem pointer to the semaphore to create - * @param count initial count of the semaphore - * @return ERR_OK if successful, another err_t otherwise - */ -err_t sys_sem_new(sys_sem_t *sem, u8_t count); -/** - * @ingroup sys_sem - * Signals a semaphore - * @param sem the semaphore to signal - */ -void sys_sem_signal(sys_sem_t *sem); -/** - * @ingroup sys_sem - * Wait for a semaphore for the specified timeout - * @param sem the semaphore to wait for - * @param timeout timeout in milliseconds to wait (0 = wait forever) - * @return time (in milliseconds) waited for the semaphore - * or SYS_ARCH_TIMEOUT on timeout - */ -u32_t sys_arch_sem_wait(sys_sem_t *sem, u32_t timeout); -/** - * @ingroup sys_sem - * Delete a semaphore - * @param sem semaphore to delete - */ -void sys_sem_free(sys_sem_t *sem); -/** Wait for a semaphore - forever/no timeout */ -#define sys_sem_wait(sem) sys_arch_sem_wait(sem, 0) -#ifndef sys_sem_valid -/** - * @ingroup sys_sem - * Check if a semaphore is valid/allocated: return 1 for valid, 0 for invalid - */ -int sys_sem_valid(sys_sem_t *sem); -#endif -#ifndef sys_sem_set_invalid -/** - * @ingroup sys_sem - * Set a semaphore invalid so that sys_sem_valid returns 0 - */ -void sys_sem_set_invalid(sys_sem_t *sem); -#endif -#ifndef sys_sem_valid_val -/** - * Same as sys_sem_valid() but taking a value, not a pointer - */ -#define sys_sem_valid_val(sem) sys_sem_valid(&(sem)) -#endif -#ifndef sys_sem_set_invalid_val -/** - * Same as sys_sem_set_invalid() but taking a value, not a pointer - */ -#define sys_sem_set_invalid_val(sem) sys_sem_set_invalid(&(sem)) -#endif - -#ifndef sys_msleep -/** - * @ingroup sys_misc - * Sleep for specified number of ms - */ -void sys_msleep(u32_t ms); /* only has a (close to) 1 ms resolution. */ -#endif - -/* Mailbox functions. */ - -/** - * @ingroup sys_mbox - * Create a new mbox of specified size - * @param mbox pointer to the mbox to create - * @param size (minimum) number of messages in this mbox - * @return ERR_OK if successful, another err_t otherwise - */ -err_t sys_mbox_new(sys_mbox_t *mbox, int size); -/** - * @ingroup sys_mbox - * Post a message to an mbox - may not fail - * -> blocks if full, only used from tasks not from ISR - * @param mbox mbox to posts the message - * @param msg message to post (ATTENTION: can be NULL) - */ -void sys_mbox_post(sys_mbox_t *mbox, void *msg); -/** - * @ingroup sys_mbox - * Try to post a message to an mbox - may fail if full or ISR - * @param mbox mbox to posts the message - * @param msg message to post (ATTENTION: can be NULL) - */ -err_t sys_mbox_trypost(sys_mbox_t *mbox, void *msg); -/** - * @ingroup sys_mbox - * Wait for a new message to arrive in the mbox - * @param mbox mbox to get a message from - * @param msg pointer where the message is stored - * @param timeout maximum time (in milliseconds) to wait for a message (0 = wait forever) - * @return time (in milliseconds) waited for a message, may be 0 if not waited - or SYS_ARCH_TIMEOUT on timeout - * The returned time has to be accurate to prevent timer jitter! - */ -u32_t sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout); -/* Allow port to override with a macro, e.g. special timeout for sys_arch_mbox_fetch() */ -#ifndef sys_arch_mbox_tryfetch -/** - * @ingroup sys_mbox - * Wait for a new message to arrive in the mbox - * @param mbox mbox to get a message from - * @param msg pointer where the message is stored - * @return 0 (milliseconds) if a message has been received - * or SYS_MBOX_EMPTY if the mailbox is empty - */ -u32_t sys_arch_mbox_tryfetch(sys_mbox_t *mbox, void **msg); -#endif -/** - * For now, we map straight to sys_arch implementation. - */ -#define sys_mbox_tryfetch(mbox, msg) sys_arch_mbox_tryfetch(mbox, msg) -/** - * @ingroup sys_mbox - * Delete an mbox - * @param mbox mbox to delete - */ -void sys_mbox_free(sys_mbox_t *mbox); -#define sys_mbox_fetch(mbox, msg) sys_arch_mbox_fetch(mbox, msg, 0) -#ifndef sys_mbox_valid -/** - * @ingroup sys_mbox - * Check if an mbox is valid/allocated: return 1 for valid, 0 for invalid - */ -int sys_mbox_valid(sys_mbox_t *mbox); -#endif -#ifndef sys_mbox_set_invalid -/** - * @ingroup sys_mbox - * Set an mbox invalid so that sys_mbox_valid returns 0 - */ -void sys_mbox_set_invalid(sys_mbox_t *mbox); -#endif -#ifndef sys_mbox_valid_val -/** - * Same as sys_mbox_valid() but taking a value, not a pointer - */ -#define sys_mbox_valid_val(mbox) sys_mbox_valid(&(mbox)) -#endif -#ifndef sys_mbox_set_invalid_val -/** - * Same as sys_mbox_set_invalid() but taking a value, not a pointer - */ -#define sys_mbox_set_invalid_val(mbox) sys_mbox_set_invalid(&(mbox)) -#endif - - -/** - * @ingroup sys_misc - * The only thread function: - * Creates a new thread - * ATTENTION: although this function returns a value, it MUST NOT FAIL (ports have to assert this!) - * @param name human-readable name for the thread (used for debugging purposes) - * @param thread thread-function - * @param arg parameter passed to 'thread' - * @param stacksize stack size in bytes for the new thread (may be ignored by ports) - * @param prio priority of the new thread (may be ignored by ports) */ -sys_thread_t sys_thread_new(const char *name, lwip_thread_fn thread, void *arg, int stacksize, int prio); - -/** - * Finishes an existing thread - * @param thread identifier returned by sys_thread_new - */ -err_t sys_thread_finish(sys_thread_t t); - -#endif /* NO_SYS */ - -/* sys_init() must be called before anything else. */ -void sys_init(void); - -#ifndef sys_jiffies -/** - * Ticks/jiffies since power up. - */ -u32_t sys_jiffies(void); -#endif - -/** - * @ingroup sys_time - * Returns the current time in milliseconds, - * may be the same as sys_jiffies or at least based on it. - */ -u32_t sys_now(void); - -/* Critical Region Protection */ -/* These functions must be implemented in the sys_arch.c file. - In some implementations they can provide a more light-weight protection - mechanism than using semaphores. Otherwise semaphores can be used for - implementation */ -#ifndef SYS_ARCH_PROTECT -/** SYS_LIGHTWEIGHT_PROT - * define SYS_LIGHTWEIGHT_PROT in lwipopts.h if you want inter-task protection - * for certain critical regions during buffer allocation, deallocation and memory - * allocation and deallocation. - */ -#if SYS_LIGHTWEIGHT_PROT - -/** - * @ingroup sys_prot - * SYS_ARCH_DECL_PROTECT - * declare a protection variable. This macro will default to defining a variable of - * type sys_prot_t. If a particular port needs a different implementation, then - * this macro may be defined in sys_arch.h. - */ -#define SYS_ARCH_DECL_PROTECT(lev) sys_prot_t lev -/** - * @ingroup sys_prot - * SYS_ARCH_PROTECT - * Perform a "fast" protect. This could be implemented by - * disabling interrupts for an embedded system or by using a semaphore or - * mutex. The implementation should allow calling SYS_ARCH_PROTECT when - * already protected. The old protection level is returned in the variable - * "lev". This macro will default to calling the sys_arch_protect() function - * which should be implemented in sys_arch.c. If a particular port needs a - * different implementation, then this macro may be defined in sys_arch.h - */ -#define SYS_ARCH_PROTECT(lev) lev = sys_arch_protect() -/** - * @ingroup sys_prot - * SYS_ARCH_UNPROTECT - * Perform a "fast" set of the protection level to "lev". This could be - * implemented by setting the interrupt level to "lev" within the MACRO or by - * using a semaphore or mutex. This macro will default to calling the - * sys_arch_unprotect() function which should be implemented in - * sys_arch.c. If a particular port needs a different implementation, then - * this macro may be defined in sys_arch.h - */ -#define SYS_ARCH_UNPROTECT(lev) sys_arch_unprotect(lev) -sys_prot_t sys_arch_protect(void); -void sys_arch_unprotect(sys_prot_t pval); - -#else - -#define SYS_ARCH_DECL_PROTECT(lev) -#define SYS_ARCH_PROTECT(lev) -#define SYS_ARCH_UNPROTECT(lev) - -#endif /* SYS_LIGHTWEIGHT_PROT */ - -#endif /* SYS_ARCH_PROTECT */ - -/* - * Macros to set/get and increase/decrease variables in a thread-safe way. - * Use these for accessing variable that are used from more than one thread. - */ - -#ifndef SYS_ARCH_INC -#define SYS_ARCH_INC(var, val) do { \ - SYS_ARCH_DECL_PROTECT(old_level); \ - SYS_ARCH_PROTECT(old_level); \ - var += val; \ - SYS_ARCH_UNPROTECT(old_level); \ - } while(0) -#endif /* SYS_ARCH_INC */ - -#ifndef SYS_ARCH_DEC -#define SYS_ARCH_DEC(var, val) do { \ - SYS_ARCH_DECL_PROTECT(old_level); \ - SYS_ARCH_PROTECT(old_level); \ - var -= val; \ - SYS_ARCH_UNPROTECT(old_level); \ - } while(0) -#endif /* SYS_ARCH_DEC */ - -#ifndef SYS_ARCH_GET -#define SYS_ARCH_GET(var, ret) do { \ - SYS_ARCH_DECL_PROTECT(old_level); \ - SYS_ARCH_PROTECT(old_level); \ - ret = var; \ - SYS_ARCH_UNPROTECT(old_level); \ - } while(0) -#endif /* SYS_ARCH_GET */ - -#ifndef SYS_ARCH_SET -#define SYS_ARCH_SET(var, val) do { \ - SYS_ARCH_DECL_PROTECT(old_level); \ - SYS_ARCH_PROTECT(old_level); \ - var = val; \ - SYS_ARCH_UNPROTECT(old_level); \ - } while(0) -#endif /* SYS_ARCH_SET */ - - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_SYS_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/tcp.h b/third_party/lwip/repo/lwip/src/include/lwip/tcp.h deleted file mode 100644 index 91dc6eeaaf999b..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/tcp.h +++ /dev/null @@ -1,438 +0,0 @@ -/** - * @file - * TCP API (to be used from TCPIP thread)\n - * See also @ref tcp_raw - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_TCP_H -#define LWIP_HDR_TCP_H - -#include "lwip/opt.h" - -#if LWIP_TCP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/mem.h" -#include "lwip/pbuf.h" -#include "lwip/ip.h" -#include "lwip/icmp.h" -#include "lwip/err.h" -#include "lwip/ip6.h" -#include "lwip/ip6_addr.h" - -#ifdef __cplusplus -extern "C" { -#endif - -struct tcp_pcb; - -/** Function prototype for tcp accept callback functions. Called when a new - * connection can be accepted on a listening pcb. - * - * @param arg Additional argument to pass to the callback function (@see tcp_arg()) - * @param newpcb The new connection pcb - * @param err An error code if there has been an error accepting. - * Only return ERR_ABRT if you have called tcp_abort from within the - * callback function! - */ -typedef err_t (*tcp_accept_fn)(void *arg, struct tcp_pcb *newpcb, err_t err); - -/** Function prototype for tcp receive callback functions. Called when data has - * been received. - * - * @param arg Additional argument to pass to the callback function (@see tcp_arg()) - * @param tpcb The connection pcb which received data - * @param p The received data (or NULL when the connection has been closed!) - * @param err An error code if there has been an error receiving - * Only return ERR_ABRT if you have called tcp_abort from within the - * callback function! - */ -typedef err_t (*tcp_recv_fn)(void *arg, struct tcp_pcb *tpcb, - struct pbuf *p, err_t err); - -/** Function prototype for tcp sent callback functions. Called when sent data has - * been acknowledged by the remote side. Use it to free corresponding resources. - * This also means that the pcb has now space available to send new data. - * - * @param arg Additional argument to pass to the callback function (@see tcp_arg()) - * @param tpcb The connection pcb for which data has been acknowledged - * @param len The amount of bytes acknowledged - * @return ERR_OK: try to send some data by calling tcp_output - * Only return ERR_ABRT if you have called tcp_abort from within the - * callback function! - */ -typedef err_t (*tcp_sent_fn)(void *arg, struct tcp_pcb *tpcb, - u16_t len); - -/** Function prototype for tcp poll callback functions. Called periodically as - * specified by @see tcp_poll. - * - * @param arg Additional argument to pass to the callback function (@see tcp_arg()) - * @param tpcb tcp pcb - * @return ERR_OK: try to send some data by calling tcp_output - * Only return ERR_ABRT if you have called tcp_abort from within the - * callback function! - */ -typedef err_t (*tcp_poll_fn)(void *arg, struct tcp_pcb *tpcb); - -/** Function prototype for tcp error callback functions. Called when the pcb - * receives a RST or is unexpectedly closed for any other reason. - * - * @note The corresponding pcb is already freed when this callback is called! - * - * @param arg Additional argument to pass to the callback function (@see tcp_arg()) - * @param err Error code to indicate why the pcb has been closed - * ERR_ABRT: aborted through tcp_abort or by a TCP timer - * ERR_RST: the connection was reset by the remote host - */ -typedef void (*tcp_err_fn)(void *arg, err_t err); - -/** Function prototype for tcp connected callback functions. Called when a pcb - * is connected to the remote side after initiating a connection attempt by - * calling tcp_connect(). - * - * @param arg Additional argument to pass to the callback function (@see tcp_arg()) - * @param tpcb The connection pcb which is connected - * @param err An unused error code, always ERR_OK currently ;-) @todo! - * Only return ERR_ABRT if you have called tcp_abort from within the - * callback function! - * - * @note When a connection attempt fails, the error callback is currently called! - */ -typedef err_t (*tcp_connected_fn)(void *arg, struct tcp_pcb *tpcb, err_t err); - -#if LWIP_WND_SCALE -#define RCV_WND_SCALE(pcb, wnd) (((wnd) >> (pcb)->rcv_scale)) -#define SND_WND_SCALE(pcb, wnd) (((wnd) << (pcb)->snd_scale)) -#define TCPWND16(x) ((u16_t)LWIP_MIN((x), 0xFFFF)) -#define TCP_WND_MAX(pcb) ((tcpwnd_size_t)(((pcb)->flags & TF_WND_SCALE) ? TCP_WND : TCPWND16(TCP_WND))) -typedef u32_t tcpwnd_size_t; -#else -#define RCV_WND_SCALE(pcb, wnd) (wnd) -#define SND_WND_SCALE(pcb, wnd) (wnd) -#define TCPWND16(x) (x) -#define TCP_WND_MAX(pcb) TCP_WND -typedef u16_t tcpwnd_size_t; -#endif - -#if LWIP_WND_SCALE || TCP_LISTEN_BACKLOG || LWIP_TCP_TIMESTAMPS -typedef u16_t tcpflags_t; -#else -typedef u8_t tcpflags_t; -#endif - -enum tcp_state { - CLOSED = 0, - LISTEN = 1, - SYN_SENT = 2, - SYN_RCVD = 3, - ESTABLISHED = 4, - FIN_WAIT_1 = 5, - FIN_WAIT_2 = 6, - CLOSE_WAIT = 7, - CLOSING = 8, - LAST_ACK = 9, - TIME_WAIT = 10 -}; - -/** - * members common to struct tcp_pcb and struct tcp_listen_pcb - */ -#define TCP_PCB_COMMON(type) \ - type *next; /* for the linked list */ \ - void *callback_arg; \ - enum tcp_state state; /* TCP state */ \ - u8_t prio; \ - /* ports are in host byte order */ \ - u16_t local_port - - -/** the TCP protocol control block for listening pcbs */ -struct tcp_pcb_listen { -/** Common members of all PCB types */ - IP_PCB; -/** Protocol specific PCB members */ - TCP_PCB_COMMON(struct tcp_pcb_listen); - -#if LWIP_CALLBACK_API - /* Function to call when a listener has been connected. */ - tcp_accept_fn accept; -#endif /* LWIP_CALLBACK_API */ - -#if TCP_LISTEN_BACKLOG - u8_t backlog; - u8_t accepts_pending; -#endif /* TCP_LISTEN_BACKLOG */ -}; - - -/** the TCP protocol control block */ -struct tcp_pcb { -/** common PCB members */ - IP_PCB; -/** protocol specific PCB members */ - TCP_PCB_COMMON(struct tcp_pcb); - - /* ports are in host byte order */ - u16_t remote_port; - - tcpflags_t flags; -#define TF_ACK_DELAY 0x01U /* Delayed ACK. */ -#define TF_ACK_NOW 0x02U /* Immediate ACK. */ -#define TF_INFR 0x04U /* In fast recovery. */ -#define TF_CLOSEPEND 0x08U /* If this is set, tcp_close failed to enqueue the FIN (retried in tcp_tmr) */ -#define TF_RXCLOSED 0x10U /* rx closed by tcp_shutdown */ -#define TF_FIN 0x20U /* Connection was closed locally (FIN segment enqueued). */ -#define TF_NODELAY 0x40U /* Disable Nagle algorithm */ -#define TF_NAGLEMEMERR 0x80U /* nagle enabled, memerr, try to output to prevent delayed ACK to happen */ -#if LWIP_WND_SCALE -#define TF_WND_SCALE 0x0100U /* Window Scale option enabled */ -#endif -#if TCP_LISTEN_BACKLOG -#define TF_BACKLOGPEND 0x0200U /* If this is set, a connection pcb has increased the backlog on its listener */ -#endif -#if LWIP_TCP_TIMESTAMPS -#define TF_TIMESTAMP 0x0400U /* Timestamp option enabled */ -#endif - - /* the rest of the fields are in host byte order - as we have to do some math with them */ - - /* Timers */ - u8_t polltmr, pollinterval; - u8_t last_timer; - u32_t tmr; - - /* receiver variables */ - u32_t rcv_nxt; /* next seqno expected */ - tcpwnd_size_t rcv_wnd; /* receiver window available */ - tcpwnd_size_t rcv_ann_wnd; /* receiver window to announce */ - u32_t rcv_ann_right_edge; /* announced right edge of window */ - - /* Retransmission timer. */ - s16_t rtime; - - u16_t mss; /* maximum segment size */ - - /* RTT (round trip time) estimation variables */ - u32_t rttest; /* RTT estimate in 500ms ticks */ - u32_t rtseq; /* sequence number being timed */ - s16_t sa, sv; /* @todo document this */ - - s16_t rto; /* retransmission time-out */ - u8_t nrtx; /* number of retransmissions */ - - /* fast retransmit/recovery */ - u8_t dupacks; - u32_t lastack; /* Highest acknowledged seqno. */ - - /* congestion avoidance/control variables */ - tcpwnd_size_t cwnd; - tcpwnd_size_t ssthresh; - - /* sender variables */ - u32_t snd_nxt; /* next new seqno to be sent */ - u32_t snd_wl1, snd_wl2; /* Sequence and acknowledgement numbers of last - window update. */ - u32_t snd_lbb; /* Sequence number of next byte to be buffered. */ - tcpwnd_size_t snd_wnd; /* sender window */ - tcpwnd_size_t snd_wnd_max; /* the maximum sender window announced by the remote host */ - - tcpwnd_size_t snd_buf; /* Available buffer space for sending (in bytes). */ -#define TCP_SNDQUEUELEN_OVERFLOW (0xffffU-3) - u16_t snd_queuelen; /* Number of pbufs currently in the send buffer. */ - -#if TCP_OVERSIZE - /* Extra bytes available at the end of the last pbuf in unsent. */ - u16_t unsent_oversize; -#endif /* TCP_OVERSIZE */ - - /* These are ordered by sequence number: */ - struct tcp_seg *unsent; /* Unsent (queued) segments. */ - struct tcp_seg *unacked; /* Sent but unacknowledged segments. */ -#if TCP_QUEUE_OOSEQ - struct tcp_seg *ooseq; /* Received out of sequence segments. */ -#endif /* TCP_QUEUE_OOSEQ */ - - struct pbuf *refused_data; /* Data previously received but not yet taken by upper layer */ - -#if LWIP_CALLBACK_API || TCP_LISTEN_BACKLOG - struct tcp_pcb_listen* listener; -#endif /* LWIP_CALLBACK_API || TCP_LISTEN_BACKLOG */ - -#if LWIP_CALLBACK_API - /* Function to be called when more send buffer space is available. */ - tcp_sent_fn sent; - /* Function to be called when (in-sequence) data has arrived. */ - tcp_recv_fn recv; - /* Function to be called when a connection has been set up. */ - tcp_connected_fn connected; - /* Function which is called periodically. */ - tcp_poll_fn poll; - /* Function to be called whenever a fatal error occurs. */ - tcp_err_fn errf; -#endif /* LWIP_CALLBACK_API */ - -#if LWIP_TCP_TIMESTAMPS - u32_t ts_lastacksent; - u32_t ts_recent; -#endif /* LWIP_TCP_TIMESTAMPS */ - - /* idle time before KEEPALIVE is sent */ - u32_t keep_idle; -#if LWIP_TCP_KEEPALIVE - u32_t keep_intvl; - u32_t keep_cnt; -#endif /* LWIP_TCP_KEEPALIVE */ - - /* Persist timer counter */ - u8_t persist_cnt; - /* Persist timer back-off */ - u8_t persist_backoff; - - /* KEEPALIVE counter */ - u8_t keep_cnt_sent; - -#if LWIP_WND_SCALE - u8_t snd_scale; - u8_t rcv_scale; -#endif -}; - -#if LWIP_EVENT_API - -enum lwip_event { - LWIP_EVENT_ACCEPT, - LWIP_EVENT_SENT, - LWIP_EVENT_RECV, - LWIP_EVENT_CONNECTED, - LWIP_EVENT_POLL, - LWIP_EVENT_ERR -}; - -err_t lwip_tcp_event(void *arg, struct tcp_pcb *pcb, - enum lwip_event, - struct pbuf *p, - u16_t size, - err_t err); - -#endif /* LWIP_EVENT_API */ - -/* Application program's interface: */ -struct tcp_pcb * tcp_new (void); -struct tcp_pcb * tcp_new_ip_type (u8_t type); - -void tcp_arg (struct tcp_pcb *pcb, void *arg); -#if LWIP_CALLBACK_API -void tcp_recv (struct tcp_pcb *pcb, tcp_recv_fn recv); -void tcp_sent (struct tcp_pcb *pcb, tcp_sent_fn sent); -void tcp_err (struct tcp_pcb *pcb, tcp_err_fn err); -void tcp_accept (struct tcp_pcb *pcb, tcp_accept_fn accept); -#endif /* LWIP_CALLBACK_API */ -void tcp_poll (struct tcp_pcb *pcb, tcp_poll_fn poll, u8_t interval); - -#define tcp_set_flags(pcb, set_flags) do { (pcb)->flags = (tcpflags_t)((pcb)->flags | (set_flags)); } while(0) -#define tcp_clear_flags(pcb, clr_flags) do { (pcb)->flags = (tcpflags_t)((pcb)->flags & ~(clr_flags)); } while(0) -#define tcp_is_flag_set(pcb, flag) (((pcb)->flags & (flag)) != 0) - -#if LWIP_TCP_TIMESTAMPS -#define tcp_mss(pcb) (((pcb)->flags & TF_TIMESTAMP) ? ((pcb)->mss - 12) : (pcb)->mss) -#else /* LWIP_TCP_TIMESTAMPS */ -#define tcp_mss(pcb) ((pcb)->mss) -#endif /* LWIP_TCP_TIMESTAMPS */ -#define tcp_sndbuf(pcb) (TCPWND16((pcb)->snd_buf)) -#define tcp_sndqueuelen(pcb) ((pcb)->snd_queuelen) -/** @ingroup tcp_raw */ -#define tcp_nagle_disable(pcb) tcp_set_flags(pcb, TF_NODELAY) -/** @ingroup tcp_raw */ -#define tcp_nagle_enable(pcb) tcp_clear_flags(pcb, TF_NODELAY) -/** @ingroup tcp_raw */ -#define tcp_nagle_disabled(pcb) tcp_is_flag_set(pcb, TF_NODELAY) - -#if TCP_LISTEN_BACKLOG -#define tcp_backlog_set(pcb, new_backlog) do { \ - LWIP_ASSERT("pcb->state == LISTEN (called for wrong pcb?)", (pcb)->state == LISTEN); \ - ((struct tcp_pcb_listen *)(pcb))->backlog = ((new_backlog) ? (new_backlog) : 1); } while(0) -void tcp_backlog_delayed(struct tcp_pcb* pcb); -void tcp_backlog_accepted(struct tcp_pcb* pcb); -#else /* TCP_LISTEN_BACKLOG */ -#define tcp_backlog_set(pcb, new_backlog) -#define tcp_backlog_delayed(pcb) -#define tcp_backlog_accepted(pcb) -#endif /* TCP_LISTEN_BACKLOG */ -#define tcp_accepted(pcb) /* compatibility define, not needed any more */ - -void tcp_recved (struct tcp_pcb *pcb, u16_t len); -err_t tcp_bind (struct tcp_pcb *pcb, const ip_addr_t *ipaddr, - u16_t port); -void tcp_bind_netif(struct tcp_pcb *pcb, const struct netif *netif); -err_t tcp_connect (struct tcp_pcb *pcb, const ip_addr_t *ipaddr, - u16_t port, tcp_connected_fn connected); - -struct tcp_pcb * tcp_listen_with_backlog_and_err(struct tcp_pcb *pcb, u8_t backlog, err_t *err); -struct tcp_pcb * tcp_listen_with_backlog(struct tcp_pcb *pcb, u8_t backlog); -/** @ingroup tcp_raw */ -#define tcp_listen(pcb) tcp_listen_with_backlog(pcb, TCP_DEFAULT_LISTEN_BACKLOG) - -void tcp_abort (struct tcp_pcb *pcb); -err_t tcp_close (struct tcp_pcb *pcb); -err_t tcp_shutdown(struct tcp_pcb *pcb, int shut_rx, int shut_tx); - -/* Flags for "apiflags" parameter in tcp_write */ -#define TCP_WRITE_FLAG_COPY 0x01 -#define TCP_WRITE_FLAG_MORE 0x02 - -err_t tcp_write (struct tcp_pcb *pcb, const void *dataptr, u16_t len, - u8_t apiflags); - -void tcp_setprio (struct tcp_pcb *pcb, u8_t prio); - -#define TCP_PRIO_MIN 1 -#define TCP_PRIO_NORMAL 64 -#define TCP_PRIO_MAX 127 - -err_t tcp_output (struct tcp_pcb *pcb); - - -const char* tcp_debug_state_str(enum tcp_state s); - -/* for compatibility with older implementation */ -#define tcp_new_ip6() tcp_new_ip_type(IPADDR_TYPE_V6) - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_TCP */ - -#endif /* LWIP_HDR_TCP_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/tcpip.h b/third_party/lwip/repo/lwip/src/include/lwip/tcpip.h deleted file mode 100644 index 3ebf18df7384f6..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/tcpip.h +++ /dev/null @@ -1,116 +0,0 @@ -/** - * @file - * Functions to sync with TCPIP thread - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_TCPIP_H -#define LWIP_HDR_TCPIP_H - -#include "lwip/opt.h" - -#if !NO_SYS /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/err.h" -#include "lwip/timeouts.h" -#include "lwip/netif.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#if LWIP_TCPIP_CORE_LOCKING -/** The global semaphore to lock the stack. */ -extern sys_mutex_t lock_tcpip_core; -/** Lock lwIP core mutex (needs @ref LWIP_TCPIP_CORE_LOCKING 1) */ -#define LOCK_TCPIP_CORE() sys_mutex_lock(&lock_tcpip_core) -/** Unlock lwIP core mutex (needs @ref LWIP_TCPIP_CORE_LOCKING 1) */ -#define UNLOCK_TCPIP_CORE() sys_mutex_unlock(&lock_tcpip_core) -#else /* LWIP_TCPIP_CORE_LOCKING */ -#define LOCK_TCPIP_CORE() -#define UNLOCK_TCPIP_CORE() -#endif /* LWIP_TCPIP_CORE_LOCKING */ - -struct pbuf; -struct netif; - -#if LWIP_NETCONN -struct api_msg; -#endif /* LWIP_NETCONN */ - -/** Function prototype for the init_done function passed to tcpip_init */ -typedef void (*tcpip_init_done_fn)(void *arg); -typedef void (*tcpip_will_finish_fn)(void *arg); -/** Function prototype for functions passed to tcpip_callback() */ -typedef void (*tcpip_callback_fn)(void *ctx); - -/* Forward declarations */ -struct tcpip_callback_msg; - -void tcpip_init(tcpip_init_done_fn tcpip_init_done, void *arg); -err_t tcpip_finish(tcpip_will_finish_fn tcpip_will_finish, void *arg); - -#if LWIP_NETCONN -err_t tcpip_apimsg(struct api_msg *apimsg); -#endif /* LWIP_NETCONN */ - -err_t tcpip_inpkt(struct pbuf *p, struct netif *inp, netif_input_fn input_fn); -err_t tcpip_input(struct pbuf *p, struct netif *inp); - -err_t tcpip_callback_with_block(tcpip_callback_fn function, void *ctx, u8_t block); -/** - * @ingroup lwip_os - * @see tcpip_callback_with_block - */ -#define tcpip_callback(f, ctx) tcpip_callback_with_block(f, ctx, 1) - -struct tcpip_callback_msg* tcpip_callbackmsg_new(tcpip_callback_fn function, void *ctx); -void tcpip_callbackmsg_delete(struct tcpip_callback_msg* msg); -err_t tcpip_trycallback(struct tcpip_callback_msg* msg); - -/* free pbufs or heap memory from another context without blocking */ -err_t pbuf_free_callback(struct pbuf *p); -err_t mem_free_callback(void *m); - -#if LWIP_TCPIP_TIMEOUT && LWIP_TIMERS -err_t tcpip_timeout(u32_t msecs, sys_timeout_handler h, void *arg); -err_t tcpip_untimeout(sys_timeout_handler h, void *arg); -#endif /* LWIP_TCPIP_TIMEOUT && LWIP_TIMERS */ - -#ifdef __cplusplus -} -#endif - -#endif /* !NO_SYS */ - -#endif /* LWIP_HDR_TCPIP_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/timeouts.h b/third_party/lwip/repo/lwip/src/include/lwip/timeouts.h deleted file mode 100644 index c9b93aa02ace45..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/timeouts.h +++ /dev/null @@ -1,121 +0,0 @@ -/** - * @file - * Timer implementations - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * Simon Goldschmidt - * - */ -#ifndef LWIP_HDR_TIMEOUTS_H -#define LWIP_HDR_TIMEOUTS_H - -#include "lwip/opt.h" -#include "lwip/err.h" -#if !NO_SYS -#include "lwip/sys.h" -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -#ifndef LWIP_DEBUG_TIMERNAMES -#ifdef LWIP_DEBUG -#define LWIP_DEBUG_TIMERNAMES SYS_DEBUG -#else /* LWIP_DEBUG */ -#define LWIP_DEBUG_TIMERNAMES 0 -#endif /* LWIP_DEBUG*/ -#endif - -/** Function prototype for a stack-internal timer function that has to be - * called at a defined interval */ -typedef void (* lwip_cyclic_timer_handler)(void); - -/** This struct contains information about a stack-internal timer function - that has to be called at a defined interval */ -struct lwip_cyclic_timer { - u32_t interval_ms; - lwip_cyclic_timer_handler handler; -#if LWIP_DEBUG_TIMERNAMES - const char* handler_name; -#endif /* LWIP_DEBUG_TIMERNAMES */ -}; - -/** This array contains all stack-internal cyclic timers. To get the number of - * timers, use LWIP_ARRAYSIZE() */ -extern const struct lwip_cyclic_timer lwip_cyclic_timers[]; - -#if LWIP_TIMERS - -/** Function prototype for a timeout callback function. Register such a function - * using sys_timeout(). - * - * @param arg Additional argument to pass to the function - set up by sys_timeout() - */ -typedef void (* sys_timeout_handler)(void *arg); - -struct sys_timeo { - struct sys_timeo *next; - u32_t time; - sys_timeout_handler h; - void *arg; -#if LWIP_DEBUG_TIMERNAMES - const char* handler_name; -#endif /* LWIP_DEBUG_TIMERNAMES */ -}; - -void sys_timeouts_init(void); - -#if LWIP_DEBUG_TIMERNAMES -void sys_timeout_debug(u32_t msecs, sys_timeout_handler handler, void *arg, const char* handler_name); -#define sys_timeout(msecs, handler, arg) sys_timeout_debug(msecs, handler, arg, #handler) -#else /* LWIP_DEBUG_TIMERNAMES */ -void sys_timeout(u32_t msecs, sys_timeout_handler handler, void *arg); -#endif /* LWIP_DEBUG_TIMERNAMES */ - -void sys_untimeout(sys_timeout_handler handler, void *arg); -void sys_restart_timeouts(void); -#if NO_SYS -void sys_check_timeouts(void); -u32_t sys_timeouts_sleeptime(void); -#else /* NO_SYS */ -void sys_timeouts_mbox_fetch(sys_mbox_t *mbox, void **msg); -#endif /* NO_SYS */ - - -#endif /* LWIP_TIMERS */ - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_TIMEOUTS_H */ diff --git a/third_party/lwip/repo/lwip/src/include/lwip/udp.h b/third_party/lwip/repo/lwip/src/include/lwip/udp.h deleted file mode 100644 index 85fdd3947552ef..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/lwip/udp.h +++ /dev/null @@ -1,196 +0,0 @@ -/** - * @file - * UDP API (to be used from TCPIP thread)\n - * See also @ref udp_raw - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_UDP_H -#define LWIP_HDR_UDP_H - -#include "lwip/opt.h" - -#if LWIP_UDP /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/pbuf.h" -#include "lwip/netif.h" -#include "lwip/ip_addr.h" -#include "lwip/ip.h" -#include "lwip/ip6_addr.h" -#include "lwip/prot/udp.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#define UDP_FLAGS_NOCHKSUM 0x01U -#define UDP_FLAGS_UDPLITE 0x02U -#define UDP_FLAGS_CONNECTED 0x04U -#define UDP_FLAGS_MULTICAST_LOOP 0x08U - -struct udp_pcb; - -/** Function prototype for udp pcb receive callback functions - * addr and port are in same byte order as in the pcb - * The callback is responsible for freeing the pbuf - * if it's not used any more. - * - * ATTENTION: Be aware that 'addr' might point into the pbuf 'p' so freeing this pbuf - * can make 'addr' invalid, too. - * - * @param arg user supplied argument (udp_pcb.recv_arg) - * @param pcb the udp_pcb which received data - * @param p the packet buffer that was received - * @param addr the remote IP address from which the packet was received - * @param port the remote port from which the packet was received - */ -typedef void (*udp_recv_fn)(void *arg, struct udp_pcb *pcb, struct pbuf *p, - const ip_addr_t *addr, u16_t port); - -/** the UDP protocol control block */ -struct udp_pcb { -/** Common members of all PCB types */ - IP_PCB; - -/* Protocol specific PCB members */ - - struct udp_pcb *next; - struct netif *intf_filter; - - u8_t flags; - /** ports are in host byte order */ - u16_t local_port, remote_port; - -#if LWIP_MULTICAST_TX_OPTIONS -#if LWIP_IPV4 - /** outgoing network interface for multicast packets, by IPv4 address (if not 'any') */ - ip4_addr_t mcast_ip4; -#endif /* LWIP_IPV4 */ - /** outgoing network interface for multicast packets, by interface index (if nonzero) */ - u8_t mcast_ifindex; - /** TTL for outgoing multicast packets */ - u8_t mcast_ttl; -#endif /* LWIP_MULTICAST_TX_OPTIONS */ - -#if LWIP_UDPLITE - /** used for UDP_LITE only */ - u16_t chksum_len_rx, chksum_len_tx; -#endif /* LWIP_UDPLITE */ - - /** receive callback function */ - udp_recv_fn recv; - /** user-supplied argument for the recv callback */ - void *recv_arg; -}; -/* udp_pcbs export for external reference (e.g. SNMP agent) */ -extern struct udp_pcb *udp_pcbs; - -/* The following functions is the application layer interface to the - UDP code. */ -struct udp_pcb * udp_new (void); -struct udp_pcb * udp_new_ip_type(u8_t type); -void udp_remove (struct udp_pcb *pcb); -err_t udp_bind (struct udp_pcb *pcb, const ip_addr_t *ipaddr, - u16_t port); -void udp_bind_netif (struct udp_pcb *pcb, const struct netif* netif); -err_t udp_connect (struct udp_pcb *pcb, const ip_addr_t *ipaddr, - u16_t port); -void udp_disconnect (struct udp_pcb *pcb); -void udp_recv (struct udp_pcb *pcb, udp_recv_fn recv, - void *recv_arg); -err_t udp_sendto_if (struct udp_pcb *pcb, struct pbuf *p, - const ip_addr_t *dst_ip, u16_t dst_port, - struct netif *netif); -err_t udp_sendto_if_src(struct udp_pcb *pcb, struct pbuf *p, - const ip_addr_t *dst_ip, u16_t dst_port, - struct netif *netif, const ip_addr_t *src_ip); -err_t udp_sendto (struct udp_pcb *pcb, struct pbuf *p, - const ip_addr_t *dst_ip, u16_t dst_port); -err_t udp_send (struct udp_pcb *pcb, struct pbuf *p); - -#if LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP -err_t udp_sendto_if_chksum(struct udp_pcb *pcb, struct pbuf *p, - const ip_addr_t *dst_ip, u16_t dst_port, - struct netif *netif, u8_t have_chksum, - u16_t chksum); -err_t udp_sendto_chksum(struct udp_pcb *pcb, struct pbuf *p, - const ip_addr_t *dst_ip, u16_t dst_port, - u8_t have_chksum, u16_t chksum); -err_t udp_send_chksum(struct udp_pcb *pcb, struct pbuf *p, - u8_t have_chksum, u16_t chksum); -err_t udp_sendto_if_src_chksum(struct udp_pcb *pcb, struct pbuf *p, - const ip_addr_t *dst_ip, u16_t dst_port, struct netif *netif, - u8_t have_chksum, u16_t chksum, const ip_addr_t *src_ip); -#endif /* LWIP_CHECKSUM_ON_COPY && CHECKSUM_GEN_UDP */ - -#define udp_flags(pcb) ((pcb)->flags) -#define udp_setflags(pcb, f) ((pcb)->flags = (f)) - -#define udp_set_flags(pcb, set_flags) do { (pcb)->flags = (u8_t)((pcb)->flags | (set_flags)); } while(0) -#define udp_clear_flags(pcb, clr_flags) do { (pcb)->flags = (u8_t)((pcb)->flags & ~(clr_flags)); } while(0) -#define udp_is_flag_set(pcb, flag) (((pcb)->flags & (flag)) != 0) - -/* The following functions are the lower layer interface to UDP. */ -void udp_input (struct pbuf *p, struct netif *inp); - -void udp_init (void); - -/* for compatibility with older implementation */ -#define udp_new_ip6() udp_new_ip_type(IPADDR_TYPE_V6) - -#if LWIP_MULTICAST_TX_OPTIONS -#if LWIP_IPV4 -#define udp_set_multicast_netif_addr(pcb, ip4addr) ip4_addr_copy((pcb)->mcast_ip4, *(ip4addr)) -#define udp_get_multicast_netif_addr(pcb) (&(pcb)->mcast_ip4) -#endif /* LWIP_IPV4 */ -#define udp_set_multicast_netif_index(pcb, idx) ((pcb)->mcast_ifindex = (idx)) -#define udp_get_multicast_netif_index(pcb) ((pcb)->mcast_ifindex) -#define udp_set_multicast_ttl(pcb, value) ((pcb)->mcast_ttl = (value)) -#define udp_get_multicast_ttl(pcb) ((pcb)->mcast_ttl) -#endif /* LWIP_MULTICAST_TX_OPTIONS */ - -#if UDP_DEBUG -void udp_debug_print(struct udp_hdr *udphdr); -#else -#define udp_debug_print(udphdr) -#endif - -void udp_netif_ip_addr_changed(const ip_addr_t* old_addr, const ip_addr_t* new_addr); - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_UDP */ - -#endif /* LWIP_HDR_UDP_H */ diff --git a/third_party/lwip/repo/lwip/src/include/netif/etharp.h b/third_party/lwip/repo/lwip/src/include/netif/etharp.h deleted file mode 100644 index b9cbb8a95023c9..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/netif/etharp.h +++ /dev/null @@ -1,4 +0,0 @@ -/* ARP has been moved to core/ipv4, provide this #include for compatibility only */ -#include "lwip/etharp.h" -#include "netif/ethernet.h" - diff --git a/third_party/lwip/repo/lwip/src/include/netif/ethernet.h b/third_party/lwip/repo/lwip/src/include/netif/ethernet.h deleted file mode 100644 index 49649cbf8b2a71..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/netif/ethernet.h +++ /dev/null @@ -1,77 +0,0 @@ -/** - * @file - * Ethernet input function - handles INCOMING ethernet level traffic - * To be used in most low-level netif implementations - */ - -/* - * Copyright (c) 2001-2003 Swedish Institute of Computer Science. - * Copyright (c) 2003-2004 Leon Woestenberg - * Copyright (c) 2003-2004 Axon Digital Design B.V., The Netherlands. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ - -#ifndef LWIP_HDR_NETIF_ETHERNET_H -#define LWIP_HDR_NETIF_ETHERNET_H - -#include "lwip/opt.h" - -#include "lwip/pbuf.h" -#include "lwip/netif.h" -#include "lwip/prot/ethernet.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#if LWIP_ARP || LWIP_ETHERNET - -/** Define this to 1 and define LWIP_ARP_FILTER_NETIF_FN(pbuf, netif, type) - * to a filter function that returns the correct netif when using multiple - * netifs on one hardware interface where the netif's low-level receive - * routine cannot decide for the correct netif (e.g. when mapping multiple - * IP addresses to one hardware interface). - */ -#ifndef LWIP_ARP_FILTER_NETIF -#define LWIP_ARP_FILTER_NETIF 0 -#endif - -err_t ethernet_input(struct pbuf *p, struct netif *netif); -err_t ethernet_output(struct netif* netif, struct pbuf* p, const struct eth_addr* src, const struct eth_addr* dst, u16_t eth_type); - -extern const struct eth_addr ethbroadcast, ethzero; - -#endif /* LWIP_ARP || LWIP_ETHERNET */ - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_NETIF_ETHERNET_H */ diff --git a/third_party/lwip/repo/lwip/src/include/netif/lowpan6.h b/third_party/lwip/repo/lwip/src/include/netif/lowpan6.h deleted file mode 100644 index 4174644bb369a7..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/netif/lowpan6.h +++ /dev/null @@ -1,86 +0,0 @@ -/** - * @file - * - * 6LowPAN output for IPv6. Uses ND tables for link-layer addressing. Fragments packets to 6LowPAN units. - */ - -/* - * Copyright (c) 2015 Inico Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Ivan Delamer - * - * - * Please coordinate changes and requests with Ivan Delamer - * - */ - -#ifndef LWIP_HDR_LOWPAN6_H -#define LWIP_HDR_LOWPAN6_H - -#include "netif/lowpan6_opts.h" - -#if LWIP_IPV6 && LWIP_6LOWPAN /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/pbuf.h" -#include "lwip/ip.h" -#include "lwip/ip_addr.h" -#include "lwip/netif.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/** 1 second period */ -#define LOWPAN6_TMR_INTERVAL 1000 - -void lowpan6_tmr(void); - -err_t lowpan6_set_context(u8_t index, const ip6_addr_t * context); -err_t lowpan6_set_short_addr(u8_t addr_high, u8_t addr_low); - -#if LWIP_IPV4 -err_t lowpan4_output(struct netif *netif, struct pbuf *q, const ip4_addr_t *ipaddr); -#endif /* LWIP_IPV4 */ -err_t lowpan6_output(struct netif *netif, struct pbuf *q, const ip6_addr_t *ip6addr); -err_t lowpan6_input(struct pbuf * p, struct netif *netif); -err_t lowpan6_if_init(struct netif *netif); - -/* pan_id in network byte order. */ -err_t lowpan6_set_pan_id(u16_t pan_id); - -#if !NO_SYS -err_t tcpip_6lowpan_input(struct pbuf *p, struct netif *inp); -#endif /* !NO_SYS */ - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_IPV6 && LWIP_6LOWPAN */ - -#endif /* LWIP_HDR_LOWPAN6_H */ diff --git a/third_party/lwip/repo/lwip/src/include/netif/lowpan6_opts.h b/third_party/lwip/repo/lwip/src/include/netif/lowpan6_opts.h deleted file mode 100644 index fb93ea05de6098..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/netif/lowpan6_opts.h +++ /dev/null @@ -1,70 +0,0 @@ -/** - * @file - * 6LowPAN options list - */ - -/* - * Copyright (c) 2015 Inico Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Ivan Delamer - * - * - * Please coordinate changes and requests with Ivan Delamer - * - */ - -#ifndef LWIP_HDR_LOWPAN6_OPTS_H -#define LWIP_HDR_LOWPAN6_OPTS_H - -#include "lwip/opt.h" - -#ifndef LWIP_6LOWPAN -#define LWIP_6LOWPAN 0 -#endif - -#ifndef LWIP_6LOWPAN_NUM_CONTEXTS -#define LWIP_6LOWPAN_NUM_CONTEXTS 10 -#endif - -#ifndef LWIP_6LOWPAN_INFER_SHORT_ADDRESS -#define LWIP_6LOWPAN_INFER_SHORT_ADDRESS 1 -#endif - -#ifndef LWIP_6LOWPAN_IPHC -#define LWIP_6LOWPAN_IPHC 1 -#endif - -#ifndef LWIP_6LOWPAN_HW_CRC -#define LWIP_6LOWPAN_HW_CRC 1 -#endif - -#ifndef LOWPAN6_DEBUG -#define LOWPAN6_DEBUG LWIP_DBG_OFF -#endif - -#endif /* LWIP_HDR_LOWPAN6_OPTS_H */ diff --git a/third_party/lwip/repo/lwip/src/include/netif/ppp/ccp.h b/third_party/lwip/repo/lwip/src/include/netif/ppp/ccp.h deleted file mode 100644 index 14dd65962c763d..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/netif/ppp/ccp.h +++ /dev/null @@ -1,156 +0,0 @@ -/* - * ccp.h - Definitions for PPP Compression Control Protocol. - * - * Copyright (c) 1994-2002 Paul Mackerras. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. The name(s) of the authors of this software must not be used to - * endorse or promote products derived from this software without - * prior written permission. - * - * 3. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Paul Mackerras - * ". - * - * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * $Id: ccp.h,v 1.12 2004/11/04 10:02:26 paulus Exp $ - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT && CCP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#ifndef CCP_H -#define CCP_H - -/* - * CCP codes. - */ - -#define CCP_CONFREQ 1 -#define CCP_CONFACK 2 -#define CCP_TERMREQ 5 -#define CCP_TERMACK 6 -#define CCP_RESETREQ 14 -#define CCP_RESETACK 15 - -/* - * Max # bytes for a CCP option - */ - -#define CCP_MAX_OPTION_LENGTH 32 - -/* - * Parts of a CCP packet. - */ - -#define CCP_CODE(dp) ((dp)[0]) -#define CCP_ID(dp) ((dp)[1]) -#define CCP_LENGTH(dp) (((dp)[2] << 8) + (dp)[3]) -#define CCP_HDRLEN 4 - -#define CCP_OPT_CODE(dp) ((dp)[0]) -#define CCP_OPT_LENGTH(dp) ((dp)[1]) -#define CCP_OPT_MINLEN 2 - -#if BSDCOMPRESS_SUPPORT -/* - * Definitions for BSD-Compress. - */ - -#define CI_BSD_COMPRESS 21 /* config. option for BSD-Compress */ -#define CILEN_BSD_COMPRESS 3 /* length of config. option */ - -/* Macros for handling the 3rd byte of the BSD-Compress config option. */ -#define BSD_NBITS(x) ((x) & 0x1F) /* number of bits requested */ -#define BSD_VERSION(x) ((x) >> 5) /* version of option format */ -#define BSD_CURRENT_VERSION 1 /* current version number */ -#define BSD_MAKE_OPT(v, n) (((v) << 5) | (n)) - -#define BSD_MIN_BITS 9 /* smallest code size supported */ -#define BSD_MAX_BITS 15 /* largest code size supported */ -#endif /* BSDCOMPRESS_SUPPORT */ - -#if DEFLATE_SUPPORT -/* - * Definitions for Deflate. - */ - -#define CI_DEFLATE 26 /* config option for Deflate */ -#define CI_DEFLATE_DRAFT 24 /* value used in original draft RFC */ -#define CILEN_DEFLATE 4 /* length of its config option */ - -#define DEFLATE_MIN_SIZE 9 -#define DEFLATE_MAX_SIZE 15 -#define DEFLATE_METHOD_VAL 8 -#define DEFLATE_SIZE(x) (((x) >> 4) + 8) -#define DEFLATE_METHOD(x) ((x) & 0x0F) -#define DEFLATE_MAKE_OPT(w) ((((w) - 8) << 4) + DEFLATE_METHOD_VAL) -#define DEFLATE_CHK_SEQUENCE 0 -#endif /* DEFLATE_SUPPORT */ - -#if MPPE_SUPPORT -/* - * Definitions for MPPE. - */ - -#define CI_MPPE 18 /* config option for MPPE */ -#define CILEN_MPPE 6 /* length of config option */ -#endif /* MPPE_SUPPORT */ - -#if PREDICTOR_SUPPORT -/* - * Definitions for other, as yet unsupported, compression methods. - */ - -#define CI_PREDICTOR_1 1 /* config option for Predictor-1 */ -#define CILEN_PREDICTOR_1 2 /* length of its config option */ -#define CI_PREDICTOR_2 2 /* config option for Predictor-2 */ -#define CILEN_PREDICTOR_2 2 /* length of its config option */ -#endif /* PREDICTOR_SUPPORT */ - -typedef struct ccp_options { -#if DEFLATE_SUPPORT - unsigned int deflate :1; /* do Deflate? */ - unsigned int deflate_correct :1; /* use correct code for deflate? */ - unsigned int deflate_draft :1; /* use draft RFC code for deflate? */ -#endif /* DEFLATE_SUPPORT */ -#if BSDCOMPRESS_SUPPORT - unsigned int bsd_compress :1; /* do BSD Compress? */ -#endif /* BSDCOMPRESS_SUPPORT */ -#if PREDICTOR_SUPPORT - unsigned int predictor_1 :1; /* do Predictor-1? */ - unsigned int predictor_2 :1; /* do Predictor-2? */ -#endif /* PREDICTOR_SUPPORT */ - -#if MPPE_SUPPORT - u8_t mppe; /* MPPE bitfield */ -#endif /* MPPE_SUPPORT */ -#if BSDCOMPRESS_SUPPORT - u_short bsd_bits; /* # bits/code for BSD Compress */ -#endif /* BSDCOMPRESS_SUPPORT */ -#if DEFLATE_SUPPORT - u_short deflate_size; /* lg(window size) for Deflate */ -#endif /* DEFLATE_SUPPORT */ - u8_t method; /* code for chosen compression method */ -} ccp_options; - -extern const struct protent ccp_protent; - -void ccp_resetrequest(ppp_pcb *pcb); /* Issue a reset-request. */ - -#endif /* CCP_H */ -#endif /* PPP_SUPPORT && CCP_SUPPORT */ diff --git a/third_party/lwip/repo/lwip/src/include/netif/ppp/chap-md5.h b/third_party/lwip/repo/lwip/src/include/netif/ppp/chap-md5.h deleted file mode 100644 index eb0269fe5086dc..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/netif/ppp/chap-md5.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * chap-md5.h - New CHAP/MD5 implementation. - * - * Copyright (c) 2003 Paul Mackerras. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. The name(s) of the authors of this software must not be used to - * endorse or promote products derived from this software without - * prior written permission. - * - * 3. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Paul Mackerras - * ". - * - * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT && CHAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -extern const struct chap_digest_type md5_digest; - -#endif /* PPP_SUPPORT && CHAP_SUPPORT */ diff --git a/third_party/lwip/repo/lwip/src/include/netif/ppp/chap-new.h b/third_party/lwip/repo/lwip/src/include/netif/ppp/chap-new.h deleted file mode 100644 index 64eae32202941a..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/netif/ppp/chap-new.h +++ /dev/null @@ -1,192 +0,0 @@ -/* - * chap-new.c - New CHAP implementation. - * - * Copyright (c) 2003 Paul Mackerras. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. The name(s) of the authors of this software must not be used to - * endorse or promote products derived from this software without - * prior written permission. - * - * 3. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Paul Mackerras - * ". - * - * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT && CHAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#ifndef CHAP_H -#define CHAP_H - -#include "ppp.h" - -/* - * CHAP packets begin with a standard header with code, id, len (2 bytes). - */ -#define CHAP_HDRLEN 4 - -/* - * Values for the code field. - */ -#define CHAP_CHALLENGE 1 -#define CHAP_RESPONSE 2 -#define CHAP_SUCCESS 3 -#define CHAP_FAILURE 4 - -/* - * CHAP digest codes. - */ -#define CHAP_MD5 5 -#if MSCHAP_SUPPORT -#define CHAP_MICROSOFT 0x80 -#define CHAP_MICROSOFT_V2 0x81 -#endif /* MSCHAP_SUPPORT */ - -/* - * Semi-arbitrary limits on challenge and response fields. - */ -#define MAX_CHALLENGE_LEN 64 -#define MAX_RESPONSE_LEN 64 - -/* - * These limits apply to challenge and response packets we send. - * The +4 is the +1 that we actually need rounded up. - */ -#define CHAL_MAX_PKTLEN (PPP_HDRLEN + CHAP_HDRLEN + 4 + MAX_CHALLENGE_LEN + MAXNAMELEN) -#define RESP_MAX_PKTLEN (PPP_HDRLEN + CHAP_HDRLEN + 4 + MAX_RESPONSE_LEN + MAXNAMELEN) - -/* bitmask of supported algorithms */ -#if MSCHAP_SUPPORT -#define MDTYPE_MICROSOFT_V2 0x1 -#define MDTYPE_MICROSOFT 0x2 -#endif /* MSCHAP_SUPPORT */ -#define MDTYPE_MD5 0x4 -#define MDTYPE_NONE 0 - -#if MSCHAP_SUPPORT -/* Return the digest alg. ID for the most preferred digest type. */ -#define CHAP_DIGEST(mdtype) \ - ((mdtype) & MDTYPE_MD5)? CHAP_MD5: \ - ((mdtype) & MDTYPE_MICROSOFT_V2)? CHAP_MICROSOFT_V2: \ - ((mdtype) & MDTYPE_MICROSOFT)? CHAP_MICROSOFT: \ - 0 -#else /* !MSCHAP_SUPPORT */ -#define CHAP_DIGEST(mdtype) \ - ((mdtype) & MDTYPE_MD5)? CHAP_MD5: \ - 0 -#endif /* MSCHAP_SUPPORT */ - -/* Return the bit flag (lsb set) for our most preferred digest type. */ -#define CHAP_MDTYPE(mdtype) ((mdtype) ^ ((mdtype) - 1)) & (mdtype) - -/* Return the bit flag for a given digest algorithm ID. */ -#if MSCHAP_SUPPORT -#define CHAP_MDTYPE_D(digest) \ - ((digest) == CHAP_MICROSOFT_V2)? MDTYPE_MICROSOFT_V2: \ - ((digest) == CHAP_MICROSOFT)? MDTYPE_MICROSOFT: \ - ((digest) == CHAP_MD5)? MDTYPE_MD5: \ - 0 -#else /* !MSCHAP_SUPPORT */ -#define CHAP_MDTYPE_D(digest) \ - ((digest) == CHAP_MD5)? MDTYPE_MD5: \ - 0 -#endif /* MSCHAP_SUPPORT */ - -/* Can we do the requested digest? */ -#if MSCHAP_SUPPORT -#define CHAP_CANDIGEST(mdtype, digest) \ - ((digest) == CHAP_MICROSOFT_V2)? (mdtype) & MDTYPE_MICROSOFT_V2: \ - ((digest) == CHAP_MICROSOFT)? (mdtype) & MDTYPE_MICROSOFT: \ - ((digest) == CHAP_MD5)? (mdtype) & MDTYPE_MD5: \ - 0 -#else /* !MSCHAP_SUPPORT */ -#define CHAP_CANDIGEST(mdtype, digest) \ - ((digest) == CHAP_MD5)? (mdtype) & MDTYPE_MD5: \ - 0 -#endif /* MSCHAP_SUPPORT */ - -/* - * The code for each digest type has to supply one of these. - */ -struct chap_digest_type { - int code; - -#if PPP_SERVER - /* - * Note: challenge and response arguments below are formatted as - * a length byte followed by the actual challenge/response data. - */ - void (*generate_challenge)(ppp_pcb *pcb, unsigned char *challenge); - int (*verify_response)(ppp_pcb *pcb, int id, const char *name, - const unsigned char *secret, int secret_len, - const unsigned char *challenge, const unsigned char *response, - char *message, int message_space); -#endif /* PPP_SERVER */ - void (*make_response)(ppp_pcb *pcb, unsigned char *response, int id, const char *our_name, - const unsigned char *challenge, const char *secret, int secret_len, - unsigned char *priv); - int (*check_success)(ppp_pcb *pcb, unsigned char *pkt, int len, unsigned char *priv); - void (*handle_failure)(ppp_pcb *pcb, unsigned char *pkt, int len); -}; - -/* - * Each interface is described by chap structure. - */ -#if CHAP_SUPPORT -typedef struct chap_client_state { - u8_t flags; - const char *name; - const struct chap_digest_type *digest; - unsigned char priv[64]; /* private area for digest's use */ -} chap_client_state; - -#if PPP_SERVER -typedef struct chap_server_state { - u8_t flags; - u8_t id; - const char *name; - const struct chap_digest_type *digest; - int challenge_xmits; - int challenge_pktlen; - unsigned char challenge[CHAL_MAX_PKTLEN]; -} chap_server_state; -#endif /* PPP_SERVER */ -#endif /* CHAP_SUPPORT */ - -#if 0 /* UNUSED */ -/* Hook for a plugin to validate CHAP challenge */ -extern int (*chap_verify_hook)(char *name, char *ourname, int id, - const struct chap_digest_type *digest, - unsigned char *challenge, unsigned char *response, - char *message, int message_space); -#endif /* UNUSED */ - -#if PPP_SERVER -/* Called by authentication code to start authenticating the peer. */ -extern void chap_auth_peer(ppp_pcb *pcb, const char *our_name, int digest_code); -#endif /* PPP_SERVER */ - -/* Called by auth. code to start authenticating us to the peer. */ -extern void chap_auth_with_peer(ppp_pcb *pcb, const char *our_name, int digest_code); - -/* Represents the CHAP protocol to the main pppd code */ -extern const struct protent chap_protent; - -#endif /* CHAP_H */ -#endif /* PPP_SUPPORT && CHAP_SUPPORT */ diff --git a/third_party/lwip/repo/lwip/src/include/netif/ppp/chap_ms.h b/third_party/lwip/repo/lwip/src/include/netif/ppp/chap_ms.h deleted file mode 100644 index 0795291158fd9b..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/netif/ppp/chap_ms.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * chap_ms.h - Challenge Handshake Authentication Protocol definitions. - * - * Copyright (c) 1995 Eric Rosenquist. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name(s) of the authors of this software must not be used to - * endorse or promote products derived from this software without - * prior written permission. - * - * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * $Id: chap_ms.h,v 1.13 2004/11/15 22:13:26 paulus Exp $ - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT && MSCHAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#ifndef CHAPMS_INCLUDE -#define CHAPMS_INCLUDE - -extern const struct chap_digest_type chapms_digest; -extern const struct chap_digest_type chapms2_digest; - -#endif /* CHAPMS_INCLUDE */ - -#endif /* PPP_SUPPORT && MSCHAP_SUPPORT */ diff --git a/third_party/lwip/repo/lwip/src/include/netif/ppp/eap.h b/third_party/lwip/repo/lwip/src/include/netif/ppp/eap.h deleted file mode 100644 index 3ee9aaf81ae660..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/netif/ppp/eap.h +++ /dev/null @@ -1,169 +0,0 @@ -/* - * eap.h - Extensible Authentication Protocol for PPP (RFC 2284) - * - * Copyright (c) 2001 by Sun Microsystems, Inc. - * All rights reserved. - * - * Non-exclusive rights to redistribute, modify, translate, and use - * this software in source and binary forms, in whole or in part, is - * hereby granted, provided that the above copyright notice is - * duplicated in any source form, and that neither the name of the - * copyright holder nor the author is used to endorse or promote - * products derived from this software. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * Original version by James Carlson - * - * $Id: eap.h,v 1.2 2003/06/11 23:56:26 paulus Exp $ - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT && EAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#ifndef PPP_EAP_H -#define PPP_EAP_H - -#include "ppp.h" - -#ifdef __cplusplus -extern "C" { -#endif - -/* - * Packet header = Code, id, length. - */ -#define EAP_HEADERLEN 4 - - -/* EAP message codes. */ -#define EAP_REQUEST 1 -#define EAP_RESPONSE 2 -#define EAP_SUCCESS 3 -#define EAP_FAILURE 4 - -/* EAP types */ -#define EAPT_IDENTITY 1 -#define EAPT_NOTIFICATION 2 -#define EAPT_NAK 3 /* (response only) */ -#define EAPT_MD5CHAP 4 -#define EAPT_OTP 5 /* One-Time Password; RFC 1938 */ -#define EAPT_TOKEN 6 /* Generic Token Card */ -/* 7 and 8 are unassigned. */ -#define EAPT_RSA 9 /* RSA Public Key Authentication */ -#define EAPT_DSS 10 /* DSS Unilateral */ -#define EAPT_KEA 11 /* KEA */ -#define EAPT_KEA_VALIDATE 12 /* KEA-VALIDATE */ -#define EAPT_TLS 13 /* EAP-TLS */ -#define EAPT_DEFENDER 14 /* Defender Token (AXENT) */ -#define EAPT_W2K 15 /* Windows 2000 EAP */ -#define EAPT_ARCOT 16 /* Arcot Systems */ -#define EAPT_CISCOWIRELESS 17 /* Cisco Wireless */ -#define EAPT_NOKIACARD 18 /* Nokia IP smart card */ -#define EAPT_SRP 19 /* Secure Remote Password */ -/* 20 is deprecated */ - -/* EAP SRP-SHA1 Subtypes */ -#define EAPSRP_CHALLENGE 1 /* Request 1 - Challenge */ -#define EAPSRP_CKEY 1 /* Response 1 - Client Key */ -#define EAPSRP_SKEY 2 /* Request 2 - Server Key */ -#define EAPSRP_CVALIDATOR 2 /* Response 2 - Client Validator */ -#define EAPSRP_SVALIDATOR 3 /* Request 3 - Server Validator */ -#define EAPSRP_ACK 3 /* Response 3 - final ack */ -#define EAPSRP_LWRECHALLENGE 4 /* Req/resp 4 - Lightweight rechal */ - -#define SRPVAL_EBIT 0x00000001 /* Use shared key for ECP */ - -#define SRP_PSEUDO_ID "pseudo_" -#define SRP_PSEUDO_LEN 7 - -#define MD5_SIGNATURE_SIZE 16 -#define EAP_MIN_CHALLENGE_LENGTH 17 -#define EAP_MAX_CHALLENGE_LENGTH 24 -#define EAP_MIN_MAX_POWER_OF_TWO_CHALLENGE_LENGTH 3 /* 2^3-1 = 7, 17+7 = 24 */ - -#define EAP_STATES \ - "Initial", "Pending", "Closed", "Listen", "Identify", \ - "SRP1", "SRP2", "SRP3", "MD5Chall", "Open", "SRP4", "BadAuth" - -#define eap_client_active(pcb) ((pcb)->eap.es_client.ea_state == eapListen) -#if PPP_SERVER -#define eap_server_active(pcb) \ - ((pcb)->eap.es_server.ea_state >= eapIdentify && \ - (pcb)->eap.es_server.ea_state <= eapMD5Chall) -#endif /* PPP_SERVER */ - -/* - * Complete EAP state for one PPP session. - */ -enum eap_state_code { - eapInitial = 0, /* No EAP authentication yet requested */ - eapPending, /* Waiting for LCP (no timer) */ - eapClosed, /* Authentication not in use */ - eapListen, /* Client ready (and timer running) */ - eapIdentify, /* EAP Identify sent */ - eapSRP1, /* Sent EAP SRP-SHA1 Subtype 1 */ - eapSRP2, /* Sent EAP SRP-SHA1 Subtype 2 */ - eapSRP3, /* Sent EAP SRP-SHA1 Subtype 3 */ - eapMD5Chall, /* Sent MD5-Challenge */ - eapOpen, /* Completed authentication */ - eapSRP4, /* Sent EAP SRP-SHA1 Subtype 4 */ - eapBadAuth /* Failed authentication */ -}; - -struct eap_auth { - const char *ea_name; /* Our name */ - char ea_peer[MAXNAMELEN +1]; /* Peer's name */ - void *ea_session; /* Authentication library linkage */ - u_char *ea_skey; /* Shared encryption key */ - u_short ea_namelen; /* Length of our name */ - u_short ea_peerlen; /* Length of peer's name */ - enum eap_state_code ea_state; - u_char ea_id; /* Current id */ - u_char ea_requests; /* Number of Requests sent/received */ - u_char ea_responses; /* Number of Responses */ - u_char ea_type; /* One of EAPT_* */ - u32_t ea_keyflags; /* SRP shared key usage flags */ -}; - -#ifndef EAP_MAX_CHALLENGE_LENGTH -#define EAP_MAX_CHALLENGE_LENGTH 24 -#endif -typedef struct eap_state { - struct eap_auth es_client; /* Client (authenticatee) data */ -#if PPP_SERVER - struct eap_auth es_server; /* Server (authenticator) data */ -#endif /* PPP_SERVER */ - int es_savedtime; /* Saved timeout */ - int es_rechallenge; /* EAP rechallenge interval */ - int es_lwrechallenge; /* SRP lightweight rechallenge inter */ - u8_t es_usepseudo; /* Use SRP Pseudonym if offered one */ - int es_usedpseudo; /* Set if we already sent PN */ - int es_challen; /* Length of challenge string */ - u_char es_challenge[EAP_MAX_CHALLENGE_LENGTH]; -} eap_state; - -/* - * Timeouts. - */ -#if 0 /* moved to ppp_opts.h */ -#define EAP_DEFTIMEOUT 3 /* Timeout (seconds) for rexmit */ -#define EAP_DEFTRANSMITS 10 /* max # times to transmit */ -#define EAP_DEFREQTIME 20 /* Time to wait for peer request */ -#define EAP_DEFALLOWREQ 20 /* max # times to accept requests */ -#endif /* moved to ppp_opts.h */ - -void eap_authwithpeer(ppp_pcb *pcb, const char *localname); -void eap_authpeer(ppp_pcb *pcb, const char *localname); - -extern const struct protent eap_protent; - -#ifdef __cplusplus -} -#endif - -#endif /* PPP_EAP_H */ - -#endif /* PPP_SUPPORT && EAP_SUPPORT */ diff --git a/third_party/lwip/repo/lwip/src/include/netif/ppp/ecp.h b/third_party/lwip/repo/lwip/src/include/netif/ppp/ecp.h deleted file mode 100644 index 5cdce29d5b2903..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/netif/ppp/ecp.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * ecp.h - Definitions for PPP Encryption Control Protocol. - * - * Copyright (c) 2002 Google, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name(s) of the authors of this software must not be used to - * endorse or promote products derived from this software without - * prior written permission. - * - * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * $Id: ecp.h,v 1.2 2003/01/10 07:12:36 fcusack Exp $ - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT && ECP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -typedef struct ecp_options { - bool required; /* Is ECP required? */ - unsigned enctype; /* Encryption type */ -} ecp_options; - -extern fsm ecp_fsm[]; -extern ecp_options ecp_wantoptions[]; -extern ecp_options ecp_gotoptions[]; -extern ecp_options ecp_allowoptions[]; -extern ecp_options ecp_hisoptions[]; - -extern const struct protent ecp_protent; - -#endif /* PPP_SUPPORT && ECP_SUPPORT */ diff --git a/third_party/lwip/repo/lwip/src/include/netif/ppp/eui64.h b/third_party/lwip/repo/lwip/src/include/netif/ppp/eui64.h deleted file mode 100644 index 20ac22eede72a8..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/netif/ppp/eui64.h +++ /dev/null @@ -1,94 +0,0 @@ -/* - * eui64.h - EUI64 routines for IPv6CP. - * - * Copyright (c) 1999 Tommi Komulainen. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name(s) of the authors of this software must not be used to - * endorse or promote products derived from this software without - * prior written permission. - * - * 4. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Tommi Komulainen - * ". - * - * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * $Id: eui64.h,v 1.6 2002/12/04 23:03:32 paulus Exp $ -*/ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT && PPP_IPV6_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#ifndef EUI64_H -#define EUI64_H - -/* - * @todo: - * - * Maybe this should be done by processing struct in6_addr directly... - */ -typedef union -{ - u8_t e8[8]; - u16_t e16[4]; - u32_t e32[2]; -} eui64_t; - -#define eui64_iszero(e) (((e).e32[0] | (e).e32[1]) == 0) -#define eui64_equals(e, o) (((e).e32[0] == (o).e32[0]) && \ - ((e).e32[1] == (o).e32[1])) -#define eui64_zero(e) (e).e32[0] = (e).e32[1] = 0; - -#define eui64_copy(s, d) memcpy(&(d), &(s), sizeof(eui64_t)) - -#define eui64_magic(e) do { \ - (e).e32[0] = magic(); \ - (e).e32[1] = magic(); \ - (e).e8[0] &= ~2; \ - } while (0) -#define eui64_magic_nz(x) do { \ - eui64_magic(x); \ - } while (eui64_iszero(x)) -#define eui64_magic_ne(x, y) do { \ - eui64_magic(x); \ - } while (eui64_equals(x, y)) - -#define eui64_get(ll, cp) do { \ - eui64_copy((*cp), (ll)); \ - (cp) += sizeof(eui64_t); \ - } while (0) - -#define eui64_put(ll, cp) do { \ - eui64_copy((ll), (*cp)); \ - (cp) += sizeof(eui64_t); \ - } while (0) - -#define eui64_set32(e, l) do { \ - (e).e32[0] = 0; \ - (e).e32[1] = lwip_htonl(l); \ - } while (0) -#define eui64_setlo32(e, l) eui64_set32(e, l) - -char *eui64_ntoa(eui64_t); /* Returns ascii representation of id */ - -#endif /* EUI64_H */ -#endif /* PPP_SUPPORT && PPP_IPV6_SUPPORT */ diff --git a/third_party/lwip/repo/lwip/src/include/netif/ppp/fsm.h b/third_party/lwip/repo/lwip/src/include/netif/ppp/fsm.h deleted file mode 100644 index b6915d3b807e59..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/netif/ppp/fsm.h +++ /dev/null @@ -1,175 +0,0 @@ -/* - * fsm.h - {Link, IP} Control Protocol Finite State Machine definitions. - * - * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name "Carnegie Mellon University" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For permission or any legal - * details, please contact - * Office of Technology Transfer - * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu - * - * 4. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Computing Services - * at Carnegie Mellon University (http://www.cmu.edu/computing/)." - * - * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE - * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * $Id: fsm.h,v 1.10 2004/11/13 02:28:15 paulus Exp $ - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#ifndef FSM_H -#define FSM_H - -#include "ppp.h" - -/* - * Packet header = Code, id, length. - */ -#define HEADERLEN 4 - - -/* - * CP (LCP, IPCP, etc.) codes. - */ -#define CONFREQ 1 /* Configuration Request */ -#define CONFACK 2 /* Configuration Ack */ -#define CONFNAK 3 /* Configuration Nak */ -#define CONFREJ 4 /* Configuration Reject */ -#define TERMREQ 5 /* Termination Request */ -#define TERMACK 6 /* Termination Ack */ -#define CODEREJ 7 /* Code Reject */ - - -/* - * Each FSM is described by an fsm structure and fsm callbacks. - */ -typedef struct fsm { - ppp_pcb *pcb; /* PPP Interface */ - const struct fsm_callbacks *callbacks; /* Callback routines */ - const char *term_reason; /* Reason for closing protocol */ - u8_t seen_ack; /* Have received valid Ack/Nak/Rej to Req */ - /* -- This is our only flag, we might use u_int :1 if we have more flags */ - u16_t protocol; /* Data Link Layer Protocol field value */ - u8_t state; /* State */ - u8_t flags; /* Contains option bits */ - u8_t id; /* Current id */ - u8_t reqid; /* Current request id */ - u8_t retransmits; /* Number of retransmissions left */ - u8_t nakloops; /* Number of nak loops since last ack */ - u8_t rnakloops; /* Number of naks received */ - u8_t maxnakloops; /* Maximum number of nak loops tolerated - (necessary because IPCP require a custom large max nak loops value) */ - u8_t term_reason_len; /* Length of term_reason */ -} fsm; - - -typedef struct fsm_callbacks { - void (*resetci) /* Reset our Configuration Information */ - (fsm *); - int (*cilen) /* Length of our Configuration Information */ - (fsm *); - void (*addci) /* Add our Configuration Information */ - (fsm *, u_char *, int *); - int (*ackci) /* ACK our Configuration Information */ - (fsm *, u_char *, int); - int (*nakci) /* NAK our Configuration Information */ - (fsm *, u_char *, int, int); - int (*rejci) /* Reject our Configuration Information */ - (fsm *, u_char *, int); - int (*reqci) /* Request peer's Configuration Information */ - (fsm *, u_char *, int *, int); - void (*up) /* Called when fsm reaches PPP_FSM_OPENED state */ - (fsm *); - void (*down) /* Called when fsm leaves PPP_FSM_OPENED state */ - (fsm *); - void (*starting) /* Called when we want the lower layer */ - (fsm *); - void (*finished) /* Called when we don't want the lower layer */ - (fsm *); - void (*protreject) /* Called when Protocol-Reject received */ - (int); - void (*retransmit) /* Retransmission is necessary */ - (fsm *); - int (*extcode) /* Called when unknown code received */ - (fsm *, int, int, u_char *, int); - const char *proto_name; /* String name for protocol (for messages) */ -} fsm_callbacks; - - -/* - * Link states. - */ -#define PPP_FSM_INITIAL 0 /* Down, hasn't been opened */ -#define PPP_FSM_STARTING 1 /* Down, been opened */ -#define PPP_FSM_CLOSED 2 /* Up, hasn't been opened */ -#define PPP_FSM_STOPPED 3 /* Open, waiting for down event */ -#define PPP_FSM_CLOSING 4 /* Terminating the connection, not open */ -#define PPP_FSM_STOPPING 5 /* Terminating, but open */ -#define PPP_FSM_REQSENT 6 /* We've sent a Config Request */ -#define PPP_FSM_ACKRCVD 7 /* We've received a Config Ack */ -#define PPP_FSM_ACKSENT 8 /* We've sent a Config Ack */ -#define PPP_FSM_OPENED 9 /* Connection available */ - - -/* - * Flags - indicate options controlling FSM operation - */ -#define OPT_PASSIVE 1 /* Don't die if we don't get a response */ -#define OPT_RESTART 2 /* Treat 2nd OPEN as DOWN, UP */ -#define OPT_SILENT 4 /* Wait for peer to speak first */ - - -/* - * Timeouts. - */ -#if 0 /* moved to ppp_opts.h */ -#define DEFTIMEOUT 3 /* Timeout time in seconds */ -#define DEFMAXTERMREQS 2 /* Maximum Terminate-Request transmissions */ -#define DEFMAXCONFREQS 10 /* Maximum Configure-Request transmissions */ -#define DEFMAXNAKLOOPS 5 /* Maximum number of nak loops */ -#endif /* moved to ppp_opts.h */ - - -/* - * Prototypes - */ -void fsm_init(fsm *f); -void fsm_lowerup(fsm *f); -void fsm_lowerdown(fsm *f); -void fsm_open(fsm *f); -void fsm_close(fsm *f, const char *reason); -void fsm_input(fsm *f, u_char *inpacket, int l); -void fsm_protreject(fsm *f); -void fsm_sdata(fsm *f, u_char code, u_char id, const u_char *data, int datalen); - - -#endif /* FSM_H */ -#endif /* PPP_SUPPORT */ diff --git a/third_party/lwip/repo/lwip/src/include/netif/ppp/ipcp.h b/third_party/lwip/repo/lwip/src/include/netif/ppp/ipcp.h deleted file mode 100644 index 45f46b31ff6259..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/netif/ppp/ipcp.h +++ /dev/null @@ -1,126 +0,0 @@ -/* - * ipcp.h - IP Control Protocol definitions. - * - * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name "Carnegie Mellon University" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For permission or any legal - * details, please contact - * Office of Technology Transfer - * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu - * - * 4. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Computing Services - * at Carnegie Mellon University (http://www.cmu.edu/computing/)." - * - * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE - * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * $Id: ipcp.h,v 1.14 2002/12/04 23:03:32 paulus Exp $ - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT && PPP_IPV4_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#ifndef IPCP_H -#define IPCP_H - -/* - * Options. - */ -#define CI_ADDRS 1 /* IP Addresses */ -#if VJ_SUPPORT -#define CI_COMPRESSTYPE 2 /* Compression Type */ -#endif /* VJ_SUPPORT */ -#define CI_ADDR 3 - -#if LWIP_DNS -#define CI_MS_DNS1 129 /* Primary DNS value */ -#define CI_MS_DNS2 131 /* Secondary DNS value */ -#endif /* LWIP_DNS */ -#if 0 /* UNUSED - WINS */ -#define CI_MS_WINS1 130 /* Primary WINS value */ -#define CI_MS_WINS2 132 /* Secondary WINS value */ -#endif /* UNUSED - WINS */ - -#if VJ_SUPPORT -#define MAX_STATES 16 /* from slcompress.h */ - -#define IPCP_VJMODE_OLD 1 /* "old" mode (option # = 0x0037) */ -#define IPCP_VJMODE_RFC1172 2 /* "old-rfc"mode (option # = 0x002d) */ -#define IPCP_VJMODE_RFC1332 3 /* "new-rfc"mode (option # = 0x002d, */ - /* maxslot and slot number compression) */ - -#define IPCP_VJ_COMP 0x002d /* current value for VJ compression option*/ -#define IPCP_VJ_COMP_OLD 0x0037 /* "old" (i.e, broken) value for VJ */ - /* compression option*/ -#endif /* VJ_SUPPORT */ - -typedef struct ipcp_options { - unsigned int neg_addr :1; /* Negotiate IP Address? */ - unsigned int old_addrs :1; /* Use old (IP-Addresses) option? */ - unsigned int req_addr :1; /* Ask peer to send IP address? */ -#if 0 /* UNUSED */ - unsigned int default_route :1; /* Assign default route through interface? */ - unsigned int replace_default_route :1; /* Replace default route through interface? */ -#endif /* UNUSED */ -#if 0 /* UNUSED - PROXY ARP */ - unsigned int proxy_arp :1; /* Make proxy ARP entry for peer? */ -#endif /* UNUSED - PROXY ARP */ -#if VJ_SUPPORT - unsigned int neg_vj :1; /* Van Jacobson Compression? */ - unsigned int old_vj :1; /* use old (short) form of VJ option? */ - unsigned int cflag :1; -#endif /* VJ_SUPPORT */ - unsigned int accept_local :1; /* accept peer's value for ouraddr */ - unsigned int accept_remote :1; /* accept peer's value for hisaddr */ -#if LWIP_DNS - unsigned int req_dns1 :1; /* Ask peer to send primary DNS address? */ - unsigned int req_dns2 :1; /* Ask peer to send secondary DNS address? */ -#endif /* LWIP_DNS */ - - u32_t ouraddr, hisaddr; /* Addresses in NETWORK BYTE ORDER */ -#if LWIP_DNS - u32_t dnsaddr[2]; /* Primary and secondary MS DNS entries */ -#endif /* LWIP_DNS */ -#if 0 /* UNUSED - WINS */ - u32_t winsaddr[2]; /* Primary and secondary MS WINS entries */ -#endif /* UNUSED - WINS */ - -#if VJ_SUPPORT - u16_t vj_protocol; /* protocol value to use in VJ option */ - u8_t maxslotindex; /* values for RFC1332 VJ compression neg. */ -#endif /* VJ_SUPPORT */ -} ipcp_options; - -#if 0 /* UNUSED, already defined by lwIP */ -char *ip_ntoa (u32_t); -#endif /* UNUSED, already defined by lwIP */ - -extern const struct protent ipcp_protent; - -#endif /* IPCP_H */ -#endif /* PPP_SUPPORT && PPP_IPV4_SUPPORT */ diff --git a/third_party/lwip/repo/lwip/src/include/netif/ppp/ipv6cp.h b/third_party/lwip/repo/lwip/src/include/netif/ppp/ipv6cp.h deleted file mode 100644 index 07d1ae31867ae5..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/netif/ppp/ipv6cp.h +++ /dev/null @@ -1,183 +0,0 @@ -/* - * ipv6cp.h - PPP IPV6 Control Protocol. - * - * Copyright (c) 1999 Tommi Komulainen. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name(s) of the authors of this software must not be used to - * endorse or promote products derived from this software without - * prior written permission. - * - * 4. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Tommi Komulainen - * ". - * - * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - */ - -/* Original version, based on RFC2023 : - - Copyright (c) 1995, 1996, 1997 Francis.Dupont@inria.fr, INRIA Rocquencourt, - Alain.Durand@imag.fr, IMAG, - Jean-Luc.Richier@imag.fr, IMAG-LSR. - - Copyright (c) 1998, 1999 Francis.Dupont@inria.fr, GIE DYADE, - Alain.Durand@imag.fr, IMAG, - Jean-Luc.Richier@imag.fr, IMAG-LSR. - - Ce travail a été fait au sein du GIE DYADE (Groupement d'Intérêt - Économique ayant pour membres BULL S.A. et l'INRIA). - - Ce logiciel informatique est disponible aux conditions - usuelles dans la recherche, c'est-à-dire qu'il peut - être utilisé, copié, modifié, distribué à l'unique - condition que ce texte soit conservé afin que - l'origine de ce logiciel soit reconnue. - - Le nom de l'Institut National de Recherche en Informatique - et en Automatique (INRIA), de l'IMAG, ou d'une personne morale - ou physique ayant participé à l'élaboration de ce logiciel ne peut - être utilisé sans son accord préalable explicite. - - Ce logiciel est fourni tel quel sans aucune garantie, - support ou responsabilité d'aucune sorte. - Ce logiciel est dérivé de sources d'origine - "University of California at Berkeley" et - "Digital Equipment Corporation" couvertes par des copyrights. - - L'Institut d'Informatique et de Mathématiques Appliquées de Grenoble (IMAG) - est une fédération d'unités mixtes de recherche du CNRS, de l'Institut National - Polytechnique de Grenoble et de l'Université Joseph Fourier regroupant - sept laboratoires dont le laboratoire Logiciels, Systèmes, Réseaux (LSR). - - This work has been done in the context of GIE DYADE (joint R & D venture - between BULL S.A. and INRIA). - - This software is available with usual "research" terms - with the aim of retain credits of the software. - Permission to use, copy, modify and distribute this software for any - purpose and without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies, - and the name of INRIA, IMAG, or any contributor not be used in advertising - or publicity pertaining to this material without the prior explicit - permission. The software is provided "as is" without any - warranties, support or liabilities of any kind. - This software is derived from source code from - "University of California at Berkeley" and - "Digital Equipment Corporation" protected by copyrights. - - Grenoble's Institute of Computer Science and Applied Mathematics (IMAG) - is a federation of seven research units funded by the CNRS, National - Polytechnic Institute of Grenoble and University Joseph Fourier. - The research unit in Software, Systems, Networks (LSR) is member of IMAG. -*/ - -/* - * Derived from : - * - * - * ipcp.h - IP Control Protocol definitions. - * - * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name "Carnegie Mellon University" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For permission or any legal - * details, please contact - * Office of Technology Transfer - * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu - * - * 4. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Computing Services - * at Carnegie Mellon University (http://www.cmu.edu/computing/)." - * - * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE - * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * $Id: ipv6cp.h,v 1.7 2002/12/04 23:03:32 paulus Exp $ - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT && PPP_IPV6_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#ifndef IPV6CP_H -#define IPV6CP_H - -#include "eui64.h" - -/* - * Options. - */ -#define CI_IFACEID 1 /* Interface Identifier */ -#ifdef IPV6CP_COMP -#define CI_COMPRESSTYPE 2 /* Compression Type */ -#endif /* IPV6CP_COMP */ - -/* No compression types yet defined. - *#define IPV6CP_COMP 0x004f - */ -typedef struct ipv6cp_options { - unsigned int neg_ifaceid :1; /* Negotiate interface identifier? */ - unsigned int req_ifaceid :1; /* Ask peer to send interface identifier? */ - unsigned int accept_local :1; /* accept peer's value for iface id? */ - unsigned int opt_local :1; /* ourtoken set by option */ - unsigned int opt_remote :1; /* histoken set by option */ - unsigned int use_ip :1; /* use IP as interface identifier */ -#if 0 - unsigned int use_persistent :1; /* use uniquely persistent value for address */ -#endif -#ifdef IPV6CP_COMP - unsigned int neg_vj :1; /* Van Jacobson Compression? */ -#endif /* IPV6CP_COMP */ - -#ifdef IPV6CP_COMP - u_short vj_protocol; /* protocol value to use in VJ option */ -#endif /* IPV6CP_COMP */ - eui64_t ourid, hisid; /* Interface identifiers */ -} ipv6cp_options; - -extern const struct protent ipv6cp_protent; - -#endif /* IPV6CP_H */ -#endif /* PPP_SUPPORT && PPP_IPV6_SUPPORT */ diff --git a/third_party/lwip/repo/lwip/src/include/netif/ppp/lcp.h b/third_party/lwip/repo/lwip/src/include/netif/ppp/lcp.h deleted file mode 100644 index 12e2a05fc90d1f..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/netif/ppp/lcp.h +++ /dev/null @@ -1,171 +0,0 @@ -/* - * lcp.h - Link Control Protocol definitions. - * - * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name "Carnegie Mellon University" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For permission or any legal - * details, please contact - * Office of Technology Transfer - * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu - * - * 4. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Computing Services - * at Carnegie Mellon University (http://www.cmu.edu/computing/)." - * - * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE - * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * $Id: lcp.h,v 1.20 2004/11/14 22:53:42 carlsonj Exp $ - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#ifndef LCP_H -#define LCP_H - -#include "ppp.h" - -/* - * Options. - */ -#define CI_VENDOR 0 /* Vendor Specific */ -#define CI_MRU 1 /* Maximum Receive Unit */ -#define CI_ASYNCMAP 2 /* Async Control Character Map */ -#define CI_AUTHTYPE 3 /* Authentication Type */ -#define CI_QUALITY 4 /* Quality Protocol */ -#define CI_MAGICNUMBER 5 /* Magic Number */ -#define CI_PCOMPRESSION 7 /* Protocol Field Compression */ -#define CI_ACCOMPRESSION 8 /* Address/Control Field Compression */ -#define CI_FCSALTERN 9 /* FCS-Alternatives */ -#define CI_SDP 10 /* Self-Describing-Pad */ -#define CI_NUMBERED 11 /* Numbered-Mode */ -#define CI_CALLBACK 13 /* callback */ -#define CI_MRRU 17 /* max reconstructed receive unit; multilink */ -#define CI_SSNHF 18 /* short sequence numbers for multilink */ -#define CI_EPDISC 19 /* endpoint discriminator */ -#define CI_MPPLUS 22 /* Multi-Link-Plus-Procedure */ -#define CI_LDISC 23 /* Link-Discriminator */ -#define CI_LCPAUTH 24 /* LCP Authentication */ -#define CI_COBS 25 /* Consistent Overhead Byte Stuffing */ -#define CI_PREFELIS 26 /* Prefix Elision */ -#define CI_MPHDRFMT 27 /* MP Header Format */ -#define CI_I18N 28 /* Internationalization */ -#define CI_SDL 29 /* Simple Data Link */ - -/* - * LCP-specific packet types (code numbers). - */ -#define PROTREJ 8 /* Protocol Reject */ -#define ECHOREQ 9 /* Echo Request */ -#define ECHOREP 10 /* Echo Reply */ -#define DISCREQ 11 /* Discard Request */ -#define IDENTIF 12 /* Identification */ -#define TIMEREM 13 /* Time Remaining */ - -/* Value used as data for CI_CALLBACK option */ -#define CBCP_OPT 6 /* Use callback control protocol */ - -#if 0 /* moved to ppp_opts.h */ -#define DEFMRU 1500 /* Try for this */ -#define MINMRU 128 /* No MRUs below this */ -#define MAXMRU 16384 /* Normally limit MRU to this */ -#endif /* moved to ppp_opts.h */ - -/* An endpoint discriminator, used with multilink. */ -#define MAX_ENDP_LEN 20 /* maximum length of discriminator value */ -struct epdisc { - unsigned char class_; /* -- The word "class" is reserved in C++. */ - unsigned char length; - unsigned char value[MAX_ENDP_LEN]; -}; - -/* - * The state of options is described by an lcp_options structure. - */ -typedef struct lcp_options { - unsigned int passive :1; /* Don't die if we don't get a response */ - unsigned int silent :1; /* Wait for the other end to start first */ -#if 0 /* UNUSED */ - unsigned int restart :1; /* Restart vs. exit after close */ -#endif /* UNUSED */ - unsigned int neg_mru :1; /* Negotiate the MRU? */ - unsigned int neg_asyncmap :1; /* Negotiate the async map? */ -#if PAP_SUPPORT - unsigned int neg_upap :1; /* Ask for UPAP authentication? */ -#endif /* PAP_SUPPORT */ -#if CHAP_SUPPORT - unsigned int neg_chap :1; /* Ask for CHAP authentication? */ -#endif /* CHAP_SUPPORT */ -#if EAP_SUPPORT - unsigned int neg_eap :1; /* Ask for EAP authentication? */ -#endif /* EAP_SUPPORT */ - unsigned int neg_magicnumber :1; /* Ask for magic number? */ - unsigned int neg_pcompression :1; /* HDLC Protocol Field Compression? */ - unsigned int neg_accompression :1; /* HDLC Address/Control Field Compression? */ -#if LQR_SUPPORT - unsigned int neg_lqr :1; /* Negotiate use of Link Quality Reports */ -#endif /* LQR_SUPPORT */ - unsigned int neg_cbcp :1; /* Negotiate use of CBCP */ -#ifdef HAVE_MULTILINK - unsigned int neg_mrru :1; /* negotiate multilink MRRU */ -#endif /* HAVE_MULTILINK */ - unsigned int neg_ssnhf :1; /* negotiate short sequence numbers */ - unsigned int neg_endpoint :1; /* negotiate endpoint discriminator */ - - u16_t mru; /* Value of MRU */ -#ifdef HAVE_MULTILINK - u16_t mrru; /* Value of MRRU, and multilink enable */ -#endif /* MULTILINK */ -#if CHAP_SUPPORT - u8_t chap_mdtype; /* which MD types (hashing algorithm) */ -#endif /* CHAP_SUPPORT */ - u32_t asyncmap; /* Value of async map */ - u32_t magicnumber; - u8_t numloops; /* Number of loops during magic number neg. */ -#if LQR_SUPPORT - u32_t lqr_period; /* Reporting period for LQR 1/100ths second */ -#endif /* LQR_SUPPORT */ - struct epdisc endpoint; /* endpoint discriminator */ -} lcp_options; - -void lcp_open(ppp_pcb *pcb); -void lcp_close(ppp_pcb *pcb, const char *reason); -void lcp_lowerup(ppp_pcb *pcb); -void lcp_lowerdown(ppp_pcb *pcb); -void lcp_sprotrej(ppp_pcb *pcb, u_char *p, int len); /* send protocol reject */ - -extern const struct protent lcp_protent; - -#if 0 /* moved to ppp_opts.h */ -/* Default number of times we receive our magic number from the peer - before deciding the link is looped-back. */ -#define DEFLOOPBACKFAIL 10 -#endif /* moved to ppp_opts.h */ - -#endif /* LCP_H */ -#endif /* PPP_SUPPORT */ diff --git a/third_party/lwip/repo/lwip/src/include/netif/ppp/magic.h b/third_party/lwip/repo/lwip/src/include/netif/ppp/magic.h deleted file mode 100644 index a2a9b530e5815f..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/netif/ppp/magic.h +++ /dev/null @@ -1,122 +0,0 @@ -/* - * magic.h - PPP Magic Number definitions. - * - * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name "Carnegie Mellon University" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For permission or any legal - * details, please contact - * Office of Technology Transfer - * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu - * - * 4. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Computing Services - * at Carnegie Mellon University (http://www.cmu.edu/computing/)." - * - * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE - * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * $Id: magic.h,v 1.5 2003/06/11 23:56:26 paulus Exp $ - */ -/***************************************************************************** -* randm.h - Random number generator header file. -* -* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. -* Copyright (c) 1998 Global Election Systems Inc. -* -* The authors hereby grant permission to use, copy, modify, distribute, -* and license this software and its documentation for any purpose, provided -* that existing copyright notices are retained in all copies and that this -* notice and the following disclaimer are included verbatim in any -* distributions. No written agreement, license, or royalty fee is required -* for any of the authorized uses. -* -* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR -* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -****************************************************************************** -* REVISION HISTORY -* -* 03-01-01 Marc Boucher -* Ported to lwIP. -* 98-05-29 Guy Lancaster , Global Election Systems Inc. -* Extracted from avos. -*****************************************************************************/ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#ifndef MAGIC_H -#define MAGIC_H - -/*********************** -*** PUBLIC FUNCTIONS *** -***********************/ - -/* - * Initialize the random number generator. - */ -void magic_init(void); - -/* - * Randomize our random seed value. To be called for truely random events - * such as user operations and network traffic. - */ -void magic_randomize(void); - -/* - * Return a new random number. - */ -u32_t magic(void); /* Returns the next magic number */ - -/* - * Fill buffer with random bytes - * - * Use the random pool to generate random data. This degrades to pseudo - * random when used faster than randomness is supplied using magic_churnrand(). - * Thus it's important to make sure that the results of this are not - * published directly because one could predict the next result to at - * least some degree. Also, it's important to get a good seed before - * the first use. - */ -void magic_random_bytes(unsigned char *buf, u32_t buf_len); - -/* - * Return a new random number between 0 and (2^pow)-1 included. - */ -u32_t magic_pow(u8_t pow); - -#endif /* MAGIC_H */ - -#endif /* PPP_SUPPORT */ diff --git a/third_party/lwip/repo/lwip/src/include/netif/ppp/mppe.h b/third_party/lwip/repo/lwip/src/include/netif/ppp/mppe.h deleted file mode 100644 index 1ae8a5d9247df9..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/netif/ppp/mppe.h +++ /dev/null @@ -1,173 +0,0 @@ -/* - * mppe.h - Definitions for MPPE - * - * Copyright (c) 2008 Paul Mackerras. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name(s) of the authors of this software must not be used to - * endorse or promote products derived from this software without - * prior written permission. - * - * 4. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Paul Mackerras - * ". - * - * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT && MPPE_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#ifndef MPPE_H -#define MPPE_H - -#include "netif/ppp/pppcrypt.h" - -#define MPPE_PAD 4 /* MPPE growth per frame */ -#define MPPE_MAX_KEY_LEN 16 /* largest key length (128-bit) */ - -/* option bits for ccp_options.mppe */ -#define MPPE_OPT_40 0x01 /* 40 bit */ -#define MPPE_OPT_128 0x02 /* 128 bit */ -#define MPPE_OPT_STATEFUL 0x04 /* stateful mode */ -/* unsupported opts */ -#define MPPE_OPT_56 0x08 /* 56 bit */ -#define MPPE_OPT_MPPC 0x10 /* MPPC compression */ -#define MPPE_OPT_D 0x20 /* Unknown */ -#define MPPE_OPT_UNSUPPORTED (MPPE_OPT_56|MPPE_OPT_MPPC|MPPE_OPT_D) -#define MPPE_OPT_UNKNOWN 0x40 /* Bits !defined in RFC 3078 were set */ - -/* - * This is not nice ... the alternative is a bitfield struct though. - * And unfortunately, we cannot share the same bits for the option - * names above since C and H are the same bit. We could do a u_int32 - * but then we have to do a lwip_htonl() all the time and/or we still need - * to know which octet is which. - */ -#define MPPE_C_BIT 0x01 /* MPPC */ -#define MPPE_D_BIT 0x10 /* Obsolete, usage unknown */ -#define MPPE_L_BIT 0x20 /* 40-bit */ -#define MPPE_S_BIT 0x40 /* 128-bit */ -#define MPPE_M_BIT 0x80 /* 56-bit, not supported */ -#define MPPE_H_BIT 0x01 /* Stateless (in a different byte) */ - -/* Does not include H bit; used for least significant octet only. */ -#define MPPE_ALL_BITS (MPPE_D_BIT|MPPE_L_BIT|MPPE_S_BIT|MPPE_M_BIT|MPPE_H_BIT) - -/* Build a CI from mppe opts (see RFC 3078) */ -#define MPPE_OPTS_TO_CI(opts, ci) \ - do { \ - u_char *ptr = ci; /* u_char[4] */ \ - \ - /* H bit */ \ - if (opts & MPPE_OPT_STATEFUL) \ - *ptr++ = 0x0; \ - else \ - *ptr++ = MPPE_H_BIT; \ - *ptr++ = 0; \ - *ptr++ = 0; \ - \ - /* S,L bits */ \ - *ptr = 0; \ - if (opts & MPPE_OPT_128) \ - *ptr |= MPPE_S_BIT; \ - if (opts & MPPE_OPT_40) \ - *ptr |= MPPE_L_BIT; \ - /* M,D,C bits not supported */ \ - } while (/* CONSTCOND */ 0) - -/* The reverse of the above */ -#define MPPE_CI_TO_OPTS(ci, opts) \ - do { \ - const u_char *ptr = ci; /* u_char[4] */ \ - \ - opts = 0; \ - \ - /* H bit */ \ - if (!(ptr[0] & MPPE_H_BIT)) \ - opts |= MPPE_OPT_STATEFUL; \ - \ - /* S,L bits */ \ - if (ptr[3] & MPPE_S_BIT) \ - opts |= MPPE_OPT_128; \ - if (ptr[3] & MPPE_L_BIT) \ - opts |= MPPE_OPT_40; \ - \ - /* M,D,C bits */ \ - if (ptr[3] & MPPE_M_BIT) \ - opts |= MPPE_OPT_56; \ - if (ptr[3] & MPPE_D_BIT) \ - opts |= MPPE_OPT_D; \ - if (ptr[3] & MPPE_C_BIT) \ - opts |= MPPE_OPT_MPPC; \ - \ - /* Other bits */ \ - if (ptr[0] & ~MPPE_H_BIT) \ - opts |= MPPE_OPT_UNKNOWN; \ - if (ptr[1] || ptr[2]) \ - opts |= MPPE_OPT_UNKNOWN; \ - if (ptr[3] & ~MPPE_ALL_BITS) \ - opts |= MPPE_OPT_UNKNOWN; \ - } while (/* CONSTCOND */ 0) - -/* Shared MPPE padding between MSCHAP and MPPE */ -#define SHA1_PAD_SIZE 40 - -static const u8_t mppe_sha1_pad1[SHA1_PAD_SIZE] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 -}; -static const u8_t mppe_sha1_pad2[SHA1_PAD_SIZE] = { - 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, - 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, - 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, - 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2, 0xf2 -}; - -/* - * State for an MPPE (de)compressor. - */ -typedef struct ppp_mppe_state { - lwip_arc4_context arc4; - u8_t master_key[MPPE_MAX_KEY_LEN]; - u8_t session_key[MPPE_MAX_KEY_LEN]; - u8_t keylen; /* key length in bytes */ - /* NB: 128-bit == 16, 40-bit == 8! - * If we want to support 56-bit, the unit has to change to bits - */ - u8_t bits; /* MPPE control bits */ - u16_t ccount; /* 12-bit coherency count (seqno) */ - u16_t sanity_errors; /* take down LCP if too many */ - unsigned int stateful :1; /* stateful mode flag */ - unsigned int discard :1; /* stateful mode packet loss flag */ -} ppp_mppe_state; - -void mppe_set_key(ppp_pcb *pcb, ppp_mppe_state *state, u8_t *key); -void mppe_init(ppp_pcb *pcb, ppp_mppe_state *state, u8_t options); -void mppe_comp_reset(ppp_pcb *pcb, ppp_mppe_state *state); -err_t mppe_compress(ppp_pcb *pcb, ppp_mppe_state *state, struct pbuf **pb, u16_t protocol); -void mppe_decomp_reset(ppp_pcb *pcb, ppp_mppe_state *state); -err_t mppe_decompress(ppp_pcb *pcb, ppp_mppe_state *state, struct pbuf **pb); - -#endif /* MPPE_H */ -#endif /* PPP_SUPPORT && MPPE_SUPPORT */ diff --git a/third_party/lwip/repo/lwip/src/include/netif/ppp/polarssl/arc4.h b/third_party/lwip/repo/lwip/src/include/netif/ppp/polarssl/arc4.h deleted file mode 100644 index 4af724cd900bd1..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/netif/ppp/polarssl/arc4.h +++ /dev/null @@ -1,81 +0,0 @@ -/** - * \file arc4.h - * - * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine - * - * Copyright (C) 2009 Paul Bakker - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the names of PolarSSL or XySSL nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "netif/ppp/ppp_opts.h" -#if LWIP_INCLUDED_POLARSSL_ARC4 - -#ifndef LWIP_INCLUDED_POLARSSL_ARC4_H -#define LWIP_INCLUDED_POLARSSL_ARC4_H - -/** - * \brief ARC4 context structure - */ -typedef struct -{ - int x; /*!< permutation index */ - int y; /*!< permutation index */ - unsigned char m[256]; /*!< permutation table */ -} -arc4_context; - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief ARC4 key schedule - * - * \param ctx ARC4 context to be initialized - * \param key the secret key - * \param keylen length of the key - */ -void arc4_setup( arc4_context *ctx, unsigned char *key, int keylen ); - -/** - * \brief ARC4 cipher function - * - * \param ctx ARC4 context - * \param buf buffer to be processed - * \param buflen amount of data in buf - */ -void arc4_crypt( arc4_context *ctx, unsigned char *buf, int buflen ); - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_INCLUDED_POLARSSL_ARC4_H */ - -#endif /* LWIP_INCLUDED_POLARSSL_ARC4 */ diff --git a/third_party/lwip/repo/lwip/src/include/netif/ppp/polarssl/des.h b/third_party/lwip/repo/lwip/src/include/netif/ppp/polarssl/des.h deleted file mode 100644 index e893890ed76269..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/netif/ppp/polarssl/des.h +++ /dev/null @@ -1,92 +0,0 @@ -/** - * \file des.h - * - * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine - * - * Copyright (C) 2009 Paul Bakker - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the names of PolarSSL or XySSL nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "netif/ppp/ppp_opts.h" -#if LWIP_INCLUDED_POLARSSL_DES - -#ifndef LWIP_INCLUDED_POLARSSL_DES_H -#define LWIP_INCLUDED_POLARSSL_DES_H - -#define DES_ENCRYPT 1 -#define DES_DECRYPT 0 - -/** - * \brief DES context structure - */ -typedef struct -{ - int mode; /*!< encrypt/decrypt */ - unsigned long sk[32]; /*!< DES subkeys */ -} -des_context; - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief DES key schedule (56-bit, encryption) - * - * \param ctx DES context to be initialized - * \param key 8-byte secret key - */ -void des_setkey_enc( des_context *ctx, unsigned char key[8] ); - -/** - * \brief DES key schedule (56-bit, decryption) - * - * \param ctx DES context to be initialized - * \param key 8-byte secret key - */ -void des_setkey_dec( des_context *ctx, unsigned char key[8] ); - -/** - * \brief DES-ECB block encryption/decryption - * - * \param ctx DES context - * \param input 64-bit input block - * \param output 64-bit output block - */ -void des_crypt_ecb( des_context *ctx, - const unsigned char input[8], - unsigned char output[8] ); - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_INCLUDED_POLARSSL_DES_H */ - -#endif /* LWIP_INCLUDED_POLARSSL_DES */ diff --git a/third_party/lwip/repo/lwip/src/include/netif/ppp/polarssl/md4.h b/third_party/lwip/repo/lwip/src/include/netif/ppp/polarssl/md4.h deleted file mode 100644 index 570445687e142e..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/netif/ppp/polarssl/md4.h +++ /dev/null @@ -1,97 +0,0 @@ -/** - * \file md4.h - * - * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine - * - * Copyright (C) 2009 Paul Bakker - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the names of PolarSSL or XySSL nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "netif/ppp/ppp_opts.h" -#if LWIP_INCLUDED_POLARSSL_MD4 - -#ifndef LWIP_INCLUDED_POLARSSL_MD4_H -#define LWIP_INCLUDED_POLARSSL_MD4_H - -/** - * \brief MD4 context structure - */ -typedef struct -{ - unsigned long total[2]; /*!< number of bytes processed */ - unsigned long state[4]; /*!< intermediate digest state */ - unsigned char buffer[64]; /*!< data block being processed */ -} -md4_context; - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief MD4 context setup - * - * \param ctx context to be initialized - */ -void md4_starts( md4_context *ctx ); - -/** - * \brief MD4 process buffer - * - * \param ctx MD4 context - * \param input buffer holding the data - * \param ilen length of the input data - */ -void md4_update( md4_context *ctx, const unsigned char *input, int ilen ); - -/** - * \brief MD4 final digest - * - * \param ctx MD4 context - * \param output MD4 checksum result - */ -void md4_finish( md4_context *ctx, unsigned char output[16] ); - -/** - * \brief Output = MD4( input buffer ) - * - * \param input buffer holding the data - * \param ilen length of the input data - * \param output MD4 checksum result - */ -void md4( unsigned char *input, int ilen, unsigned char output[16] ); - - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_INCLUDED_POLARSSL_MD4_H */ - -#endif /* LWIP_INCLUDED_POLARSSL_MD4 */ diff --git a/third_party/lwip/repo/lwip/src/include/netif/ppp/polarssl/md5.h b/third_party/lwip/repo/lwip/src/include/netif/ppp/polarssl/md5.h deleted file mode 100644 index 12440118906f4c..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/netif/ppp/polarssl/md5.h +++ /dev/null @@ -1,96 +0,0 @@ -/** - * \file md5.h - * - * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine - * - * Copyright (C) 2009 Paul Bakker - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the names of PolarSSL or XySSL nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "netif/ppp/ppp_opts.h" -#if LWIP_INCLUDED_POLARSSL_MD5 - -#ifndef LWIP_INCLUDED_POLARSSL_MD5_H -#define LWIP_INCLUDED_POLARSSL_MD5_H - -/** - * \brief MD5 context structure - */ -typedef struct -{ - unsigned long total[2]; /*!< number of bytes processed */ - unsigned long state[4]; /*!< intermediate digest state */ - unsigned char buffer[64]; /*!< data block being processed */ -} -md5_context; - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief MD5 context setup - * - * \param ctx context to be initialized - */ -void md5_starts( md5_context *ctx ); - -/** - * \brief MD5 process buffer - * - * \param ctx MD5 context - * \param input buffer holding the data - * \param ilen length of the input data - */ -void md5_update( md5_context *ctx, const unsigned char *input, int ilen ); - -/** - * \brief MD5 final digest - * - * \param ctx MD5 context - * \param output MD5 checksum result - */ -void md5_finish( md5_context *ctx, unsigned char output[16] ); - -/** - * \brief Output = MD5( input buffer ) - * - * \param input buffer holding the data - * \param ilen length of the input data - * \param output MD5 checksum result - */ -void md5( unsigned char *input, int ilen, unsigned char output[16] ); - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_INCLUDED_POLARSSL_MD5_H */ - -#endif /* LWIP_INCLUDED_POLARSSL_MD5 */ diff --git a/third_party/lwip/repo/lwip/src/include/netif/ppp/polarssl/sha1.h b/third_party/lwip/repo/lwip/src/include/netif/ppp/polarssl/sha1.h deleted file mode 100644 index a4c53e07c50904..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/netif/ppp/polarssl/sha1.h +++ /dev/null @@ -1,96 +0,0 @@ -/** - * \file sha1.h - * - * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine - * - * Copyright (C) 2009 Paul Bakker - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the names of PolarSSL or XySSL nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "netif/ppp/ppp_opts.h" -#if LWIP_INCLUDED_POLARSSL_SHA1 - -#ifndef LWIP_INCLUDED_POLARSSL_SHA1_H -#define LWIP_INCLUDED_POLARSSL_SHA1_H - -/** - * \brief SHA-1 context structure - */ -typedef struct -{ - unsigned long total[2]; /*!< number of bytes processed */ - unsigned long state[5]; /*!< intermediate digest state */ - unsigned char buffer[64]; /*!< data block being processed */ -} -sha1_context; - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * \brief SHA-1 context setup - * - * \param ctx context to be initialized - */ -void sha1_starts( sha1_context *ctx ); - -/** - * \brief SHA-1 process buffer - * - * \param ctx SHA-1 context - * \param input buffer holding the data - * \param ilen length of the input data - */ -void sha1_update( sha1_context *ctx, const unsigned char *input, int ilen ); - -/** - * \brief SHA-1 final digest - * - * \param ctx SHA-1 context - * \param output SHA-1 checksum result - */ -void sha1_finish( sha1_context *ctx, unsigned char output[20] ); - -/** - * \brief Output = SHA-1( input buffer ) - * - * \param input buffer holding the data - * \param ilen length of the input data - * \param output SHA-1 checksum result - */ -void sha1( unsigned char *input, int ilen, unsigned char output[20] ); - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_INCLUDED_POLARSSL_SHA1_H */ - -#endif /* LWIP_INCLUDED_POLARSSL_SHA1 */ diff --git a/third_party/lwip/repo/lwip/src/include/netif/ppp/ppp.h b/third_party/lwip/repo/lwip/src/include/netif/ppp/ppp.h deleted file mode 100644 index d9ea097efdbfb7..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/netif/ppp/ppp.h +++ /dev/null @@ -1,690 +0,0 @@ -/***************************************************************************** -* ppp.h - Network Point to Point Protocol header file. -* -* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. -* portions Copyright (c) 1997 Global Election Systems Inc. -* -* The authors hereby grant permission to use, copy, modify, distribute, -* and license this software and its documentation for any purpose, provided -* that existing copyright notices are retained in all copies and that this -* notice and the following disclaimer are included verbatim in any -* distributions. No written agreement, license, or royalty fee is required -* for any of the authorized uses. -* -* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR -* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -****************************************************************************** -* REVISION HISTORY -* -* 03-01-01 Marc Boucher -* Ported to lwIP. -* 97-11-05 Guy Lancaster , Global Election Systems Inc. -* Original derived from BSD codes. -*****************************************************************************/ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#ifndef PPP_H -#define PPP_H - -#include "lwip/def.h" -#include "lwip/stats.h" -#include "lwip/mem.h" -#include "lwip/netif.h" -#include "lwip/sys.h" -#include "lwip/timeouts.h" -#if PPP_IPV6_SUPPORT -#include "lwip/ip6_addr.h" -#endif /* PPP_IPV6_SUPPORT */ - -/* Disable non-working or rarely used PPP feature, so rarely that we don't want to bloat ppp_opts.h with them */ -#ifndef PPP_OPTIONS -#define PPP_OPTIONS 0 -#endif - -#ifndef PPP_NOTIFY -#define PPP_NOTIFY 0 -#endif - -#ifndef PPP_REMOTENAME -#define PPP_REMOTENAME 0 -#endif - -#ifndef PPP_IDLETIMELIMIT -#define PPP_IDLETIMELIMIT 0 -#endif - -#ifndef PPP_LCP_ADAPTIVE -#define PPP_LCP_ADAPTIVE 0 -#endif - -#ifndef PPP_MAXCONNECT -#define PPP_MAXCONNECT 0 -#endif - -#ifndef PPP_ALLOWED_ADDRS -#define PPP_ALLOWED_ADDRS 0 -#endif - -#ifndef PPP_PROTOCOLNAME -#define PPP_PROTOCOLNAME 0 -#endif - -#ifndef PPP_STATS_SUPPORT -#define PPP_STATS_SUPPORT 0 -#endif - -#ifndef DEFLATE_SUPPORT -#define DEFLATE_SUPPORT 0 -#endif - -#ifndef BSDCOMPRESS_SUPPORT -#define BSDCOMPRESS_SUPPORT 0 -#endif - -#ifndef PREDICTOR_SUPPORT -#define PREDICTOR_SUPPORT 0 -#endif - -/************************* -*** PUBLIC DEFINITIONS *** -*************************/ - -/* - * The basic PPP frame. - */ -#define PPP_HDRLEN 4 /* octets for standard ppp header */ -#define PPP_FCSLEN 2 /* octets for FCS */ - -/* - * Values for phase. - */ -#define PPP_PHASE_DEAD 0 -#define PPP_PHASE_MASTER 1 -#define PPP_PHASE_HOLDOFF 2 -#define PPP_PHASE_INITIALIZE 3 -#define PPP_PHASE_SERIALCONN 4 -#define PPP_PHASE_DORMANT 5 -#define PPP_PHASE_ESTABLISH 6 -#define PPP_PHASE_AUTHENTICATE 7 -#define PPP_PHASE_CALLBACK 8 -#define PPP_PHASE_NETWORK 9 -#define PPP_PHASE_RUNNING 10 -#define PPP_PHASE_TERMINATE 11 -#define PPP_PHASE_DISCONNECT 12 - -/* Error codes. */ -#define PPPERR_NONE 0 /* No error. */ -#define PPPERR_PARAM 1 /* Invalid parameter. */ -#define PPPERR_OPEN 2 /* Unable to open PPP session. */ -#define PPPERR_DEVICE 3 /* Invalid I/O device for PPP. */ -#define PPPERR_ALLOC 4 /* Unable to allocate resources. */ -#define PPPERR_USER 5 /* User interrupt. */ -#define PPPERR_CONNECT 6 /* Connection lost. */ -#define PPPERR_AUTHFAIL 7 /* Failed authentication challenge. */ -#define PPPERR_PROTOCOL 8 /* Failed to meet protocol. */ -#define PPPERR_PEERDEAD 9 /* Connection timeout */ -#define PPPERR_IDLETIMEOUT 10 /* Idle Timeout */ -#define PPPERR_CONNECTTIME 11 /* Max connect time reached */ -#define PPPERR_LOOPBACK 12 /* Loopback detected */ - -/* Whether auth support is enabled at all */ -#define PPP_AUTH_SUPPORT (PAP_SUPPORT || CHAP_SUPPORT || EAP_SUPPORT) - -/************************ -*** PUBLIC DATA TYPES *** -************************/ - -/* - * Other headers require ppp_pcb definition for prototypes, but ppp_pcb - * require some structure definition from other headers as well, we are - * fixing the dependency loop here by declaring the ppp_pcb type then - * by including headers containing necessary struct definition for ppp_pcb - */ -typedef struct ppp_pcb_s ppp_pcb; - -/* Type definitions for BSD code. */ -#ifndef __u_char_defined -typedef unsigned long u_long; -typedef unsigned int u_int; -typedef unsigned short u_short; -typedef unsigned char u_char; -#endif - -#include "fsm.h" -#include "lcp.h" -#if CCP_SUPPORT -#include "ccp.h" -#endif /* CCP_SUPPORT */ -#if MPPE_SUPPORT -#include "mppe.h" -#endif /* MPPE_SUPPORT */ -#if PPP_IPV4_SUPPORT -#include "ipcp.h" -#endif /* PPP_IPV4_SUPPORT */ -#if PPP_IPV6_SUPPORT -#include "ipv6cp.h" -#endif /* PPP_IPV6_SUPPORT */ -#if PAP_SUPPORT -#include "upap.h" -#endif /* PAP_SUPPORT */ -#if CHAP_SUPPORT -#include "chap-new.h" -#endif /* CHAP_SUPPORT */ -#if EAP_SUPPORT -#include "eap.h" -#endif /* EAP_SUPPORT */ -#if VJ_SUPPORT -#include "vj.h" -#endif /* VJ_SUPPORT */ - -/* Link status callback function prototype */ -typedef void (*ppp_link_status_cb_fn)(ppp_pcb *pcb, int err_code, void *ctx); - -/* - * PPP configuration. - */ -typedef struct ppp_settings_s { - -#if PPP_SERVER && PPP_AUTH_SUPPORT - unsigned int auth_required :1; /* Peer is required to authenticate */ - unsigned int null_login :1; /* Username of "" and a password of "" are acceptable */ -#endif /* PPP_SERVER && PPP_AUTH_SUPPORT */ -#if PPP_REMOTENAME - unsigned int explicit_remote :1; /* remote_name specified with remotename opt */ -#endif /* PPP_REMOTENAME */ -#if PAP_SUPPORT - unsigned int refuse_pap :1; /* Don't proceed auth. with PAP */ -#endif /* PAP_SUPPORT */ -#if CHAP_SUPPORT - unsigned int refuse_chap :1; /* Don't proceed auth. with CHAP */ -#endif /* CHAP_SUPPORT */ -#if MSCHAP_SUPPORT - unsigned int refuse_mschap :1; /* Don't proceed auth. with MS-CHAP */ - unsigned int refuse_mschap_v2 :1; /* Don't proceed auth. with MS-CHAPv2 */ -#endif /* MSCHAP_SUPPORT */ -#if EAP_SUPPORT - unsigned int refuse_eap :1; /* Don't proceed auth. with EAP */ -#endif /* EAP_SUPPORT */ -#if LWIP_DNS - unsigned int usepeerdns :1; /* Ask peer for DNS adds */ -#endif /* LWIP_DNS */ - unsigned int persist :1; /* Persist mode, always try to open the connection */ -#if PRINTPKT_SUPPORT - unsigned int hide_password :1; /* Hide password in dumped packets */ -#endif /* PRINTPKT_SUPPORT */ - unsigned int noremoteip :1; /* Let him have no IP address */ - unsigned int lax_recv :1; /* accept control chars in asyncmap */ - unsigned int noendpoint :1; /* don't send/accept endpoint discriminator */ -#if PPP_LCP_ADAPTIVE - unsigned int lcp_echo_adaptive :1; /* request echo only if the link was idle */ -#endif /* PPP_LCP_ADAPTIVE */ -#if MPPE_SUPPORT - unsigned int require_mppe :1; /* Require MPPE (Microsoft Point to Point Encryption) */ - unsigned int refuse_mppe_40 :1; /* Allow MPPE 40-bit mode? */ - unsigned int refuse_mppe_128 :1; /* Allow MPPE 128-bit mode? */ - unsigned int refuse_mppe_stateful :1; /* Allow MPPE stateful mode? */ -#endif /* MPPE_SUPPORT */ - - u16_t listen_time; /* time to listen first (ms), waiting for peer to send LCP packet */ - -#if PPP_IDLETIMELIMIT - u16_t idle_time_limit; /* Disconnect if idle for this many seconds */ -#endif /* PPP_IDLETIMELIMIT */ -#if PPP_MAXCONNECT - u32_t maxconnect; /* Maximum connect time (seconds) */ -#endif /* PPP_MAXCONNECT */ - -#if PPP_AUTH_SUPPORT - /* auth data */ - const char *user; /* Username for PAP */ - const char *passwd; /* Password for PAP, secret for CHAP */ -#if PPP_REMOTENAME - char remote_name[MAXNAMELEN + 1]; /* Peer's name for authentication */ -#endif /* PPP_REMOTENAME */ - -#if PAP_SUPPORT - u8_t pap_timeout_time; /* Timeout (seconds) for auth-req retrans. */ - u8_t pap_max_transmits; /* Number of auth-reqs sent */ -#if PPP_SERVER - u8_t pap_req_timeout; /* Time to wait for auth-req from peer */ -#endif /* PPP_SERVER */ -#endif /* PAP_SUPPPORT */ - -#if CHAP_SUPPORT - u8_t chap_timeout_time; /* Timeout (seconds) for retransmitting req */ - u8_t chap_max_transmits; /* max # times to send challenge */ -#if PPP_SERVER - u8_t chap_rechallenge_time; /* Time to wait for auth-req from peer */ -#endif /* PPP_SERVER */ -#endif /* CHAP_SUPPPORT */ - -#if EAP_SUPPORT - u8_t eap_req_time; /* Time to wait (for retransmit/fail) */ - u8_t eap_allow_req; /* Max Requests allowed */ -#if PPP_SERVER - u8_t eap_timeout_time; /* Time to wait (for retransmit/fail) */ - u8_t eap_max_transmits; /* Max Requests allowed */ -#endif /* PPP_SERVER */ -#endif /* EAP_SUPPORT */ - -#endif /* PPP_AUTH_SUPPORT */ - - u8_t fsm_timeout_time; /* Timeout time in seconds */ - u8_t fsm_max_conf_req_transmits; /* Maximum Configure-Request transmissions */ - u8_t fsm_max_term_transmits; /* Maximum Terminate-Request transmissions */ - u8_t fsm_max_nak_loops; /* Maximum number of nak loops tolerated */ - - u8_t lcp_loopbackfail; /* Number of times we receive our magic number from the peer - before deciding the link is looped-back. */ - u8_t lcp_echo_interval; /* Interval between LCP echo-requests */ - u8_t lcp_echo_fails; /* Tolerance to unanswered echo-requests */ - -} ppp_settings; - -#if PPP_SERVER -struct ppp_addrs { -#if PPP_IPV4_SUPPORT - ip4_addr_t our_ipaddr, his_ipaddr, netmask; -#if LWIP_DNS - ip4_addr_t dns1, dns2; -#endif /* LWIP_DNS */ -#endif /* PPP_IPV4_SUPPORT */ -#if PPP_IPV6_SUPPORT - ip6_addr_t our6_ipaddr, his6_ipaddr; -#endif /* PPP_IPV6_SUPPORT */ -}; -#endif /* PPP_SERVER */ - -/* - * PPP interface control block. - */ -struct ppp_pcb_s { - ppp_settings settings; - const struct link_callbacks *link_cb; - void *link_ctx_cb; - void (*link_status_cb)(ppp_pcb *pcb, int err_code, void *ctx); /* Status change callback */ -#if PPP_NOTIFY_PHASE - void (*notify_phase_cb)(ppp_pcb *pcb, u8_t phase, void *ctx); /* Notify phase callback */ -#endif /* PPP_NOTIFY_PHASE */ - void *ctx_cb; /* Callbacks optional pointer */ - struct netif *netif; /* PPP interface */ - u8_t phase; /* where the link is at */ - u8_t err_code; /* Code indicating why interface is down. */ - - /* flags */ -#if PPP_IPV4_SUPPORT - unsigned int ask_for_local :1; /* request our address from peer */ - unsigned int ipcp_is_open :1; /* haven't called np_finished() */ - unsigned int ipcp_is_up :1; /* have called ipcp_up() */ - unsigned int if4_up :1; /* True when the IPv4 interface is up. */ -#if 0 /* UNUSED - PROXY ARP */ - unsigned int proxy_arp_set :1; /* Have created proxy arp entry */ -#endif /* UNUSED - PROXY ARP */ -#endif /* PPP_IPV4_SUPPORT */ -#if PPP_IPV6_SUPPORT - unsigned int ipv6cp_is_up :1; /* have called ip6cp_up() */ - unsigned int if6_up :1; /* True when the IPv6 interface is up. */ -#endif /* PPP_IPV6_SUPPORT */ - unsigned int lcp_echo_timer_running :1; /* set if a timer is running */ -#if VJ_SUPPORT - unsigned int vj_enabled :1; /* Flag indicating VJ compression enabled. */ -#endif /* VJ_SUPPORT */ -#if CCP_SUPPORT - unsigned int ccp_all_rejected :1; /* we rejected all peer's options */ -#endif /* CCP_SUPPORT */ -#if MPPE_SUPPORT - unsigned int mppe_keys_set :1; /* Have the MPPE keys been set? */ -#endif /* MPPE_SUPPORT */ - -#if PPP_AUTH_SUPPORT - /* auth data */ -#if PPP_SERVER && defined(HAVE_MULTILINK) - char peer_authname[MAXNAMELEN + 1]; /* The name by which the peer authenticated itself to us. */ -#endif /* PPP_SERVER && defined(HAVE_MULTILINK) */ - u16_t auth_pending; /* Records which authentication operations haven't completed yet. */ - u16_t auth_done; /* Records which authentication operations have been completed. */ - -#if PAP_SUPPORT - upap_state upap; /* PAP data */ -#endif /* PAP_SUPPORT */ - -#if CHAP_SUPPORT - chap_client_state chap_client; /* CHAP client data */ -#if PPP_SERVER - chap_server_state chap_server; /* CHAP server data */ -#endif /* PPP_SERVER */ -#endif /* CHAP_SUPPORT */ - -#if EAP_SUPPORT - eap_state eap; /* EAP data */ -#endif /* EAP_SUPPORT */ -#endif /* PPP_AUTH_SUPPORT */ - - fsm lcp_fsm; /* LCP fsm structure */ - lcp_options lcp_wantoptions; /* Options that we want to request */ - lcp_options lcp_gotoptions; /* Options that peer ack'd */ - lcp_options lcp_allowoptions; /* Options we allow peer to request */ - lcp_options lcp_hisoptions; /* Options that we ack'd */ - u16_t peer_mru; /* currently negotiated peer MRU */ - u8_t lcp_echos_pending; /* Number of outstanding echo msgs */ - u8_t lcp_echo_number; /* ID number of next echo frame */ - - u8_t num_np_open; /* Number of network protocols which we have opened. */ - u8_t num_np_up; /* Number of network protocols which have come up. */ - -#if VJ_SUPPORT - struct vjcompress vj_comp; /* Van Jacobson compression header. */ -#endif /* VJ_SUPPORT */ - -#if CCP_SUPPORT - fsm ccp_fsm; /* CCP fsm structure */ - ccp_options ccp_wantoptions; /* what to request the peer to use */ - ccp_options ccp_gotoptions; /* what the peer agreed to do */ - ccp_options ccp_allowoptions; /* what we'll agree to do */ - ccp_options ccp_hisoptions; /* what we agreed to do */ - u8_t ccp_localstate; /* Local state (mainly for handling reset-reqs and reset-acks). */ - u8_t ccp_receive_method; /* Method chosen on receive path */ - u8_t ccp_transmit_method; /* Method chosen on transmit path */ -#if MPPE_SUPPORT - ppp_mppe_state mppe_comp; /* MPPE "compressor" structure */ - ppp_mppe_state mppe_decomp; /* MPPE "decompressor" structure */ -#endif /* MPPE_SUPPORT */ -#endif /* CCP_SUPPORT */ - -#if PPP_IPV4_SUPPORT - fsm ipcp_fsm; /* IPCP fsm structure */ - ipcp_options ipcp_wantoptions; /* Options that we want to request */ - ipcp_options ipcp_gotoptions; /* Options that peer ack'd */ - ipcp_options ipcp_allowoptions; /* Options we allow peer to request */ - ipcp_options ipcp_hisoptions; /* Options that we ack'd */ -#endif /* PPP_IPV4_SUPPORT */ - -#if PPP_IPV6_SUPPORT - fsm ipv6cp_fsm; /* IPV6CP fsm structure */ - ipv6cp_options ipv6cp_wantoptions; /* Options that we want to request */ - ipv6cp_options ipv6cp_gotoptions; /* Options that peer ack'd */ - ipv6cp_options ipv6cp_allowoptions; /* Options we allow peer to request */ - ipv6cp_options ipv6cp_hisoptions; /* Options that we ack'd */ -#endif /* PPP_IPV6_SUPPORT */ -}; - -/************************ - *** PUBLIC FUNCTIONS *** - ************************/ - -/* - * WARNING: For multi-threads environment, all ppp_set_* functions most - * only be called while the PPP is in the dead phase (i.e. disconnected). - */ - -#if PPP_AUTH_SUPPORT -/* - * Set PPP authentication. - * - * Warning: Using PPPAUTHTYPE_ANY might have security consequences. - * RFC 1994 says: - * - * In practice, within or associated with each PPP server, there is a - * database which associates "user" names with authentication - * information ("secrets"). It is not anticipated that a particular - * named user would be authenticated by multiple methods. This would - * make the user vulnerable to attacks which negotiate the least secure - * method from among a set (such as PAP rather than CHAP). If the same - * secret was used, PAP would reveal the secret to be used later with - * CHAP. - * - * Instead, for each user name there should be an indication of exactly - * one method used to authenticate that user name. If a user needs to - * make use of different authentication methods under different - * circumstances, then distinct user names SHOULD be employed, each of - * which identifies exactly one authentication method. - * - * Default is none auth type, unset (NULL) user and passwd. - */ -#define PPPAUTHTYPE_NONE 0x00 -#define PPPAUTHTYPE_PAP 0x01 -#define PPPAUTHTYPE_CHAP 0x02 -#define PPPAUTHTYPE_MSCHAP 0x04 -#define PPPAUTHTYPE_MSCHAP_V2 0x08 -#define PPPAUTHTYPE_EAP 0x10 -#define PPPAUTHTYPE_ANY 0xff -void ppp_set_auth(ppp_pcb *pcb, u8_t authtype, const char *user, const char *passwd); - -/* - * If set, peer is required to authenticate. This is mostly necessary for PPP server support. - * - * Default is false. - */ -#define ppp_set_auth_required(ppp, boolval) (ppp->settings.auth_required = boolval) -#endif /* PPP_AUTH_SUPPORT */ - -#if PPP_IPV4_SUPPORT -/* - * Set PPP interface "our" and "his" IPv4 addresses. This is mostly necessary for PPP server - * support but it can also be used on a PPP link where each side choose its own IP address. - * - * Default is unset (0.0.0.0). - */ -#define ppp_set_ipcp_ouraddr(ppp, addr) do { ppp->ipcp_wantoptions.ouraddr = ip4_addr_get_u32(addr); \ - ppp->ask_for_local = ppp->ipcp_wantoptions.ouraddr != 0; } while(0) -#define ppp_set_ipcp_hisaddr(ppp, addr) (ppp->ipcp_wantoptions.hisaddr = ip4_addr_get_u32(addr)) -#if LWIP_DNS -/* - * Set DNS server addresses that are sent if the peer asks for them. This is mostly necessary - * for PPP server support. - * - * Default is unset (0.0.0.0). - */ -#define ppp_set_ipcp_dnsaddr(ppp, index, addr) (ppp->ipcp_allowoptions.dnsaddr[index] = ip4_addr_get_u32(addr)) - -/* - * If set, we ask the peer for up to 2 DNS server addresses. Received DNS server addresses are - * registered using the dns_setserver() function. - * - * Default is false. - */ -#define ppp_set_usepeerdns(ppp, boolval) (ppp->settings.usepeerdns = boolval) -#endif /* LWIP_DNS */ -#endif /* PPP_IPV4_SUPPORT */ - -#if MPPE_SUPPORT -/* Disable MPPE (Microsoft Point to Point Encryption). This parameter is exclusive. */ -#define PPP_MPPE_DISABLE 0x00 -/* Require the use of MPPE (Microsoft Point to Point Encryption). */ -#define PPP_MPPE_ENABLE 0x01 -/* Allow MPPE to use stateful mode. Stateless mode is still attempted first. */ -#define PPP_MPPE_ALLOW_STATEFUL 0x02 -/* Refuse the use of MPPE with 40-bit encryption. Conflict with PPP_MPPE_REFUSE_128. */ -#define PPP_MPPE_REFUSE_40 0x04 -/* Refuse the use of MPPE with 128-bit encryption. Conflict with PPP_MPPE_REFUSE_40. */ -#define PPP_MPPE_REFUSE_128 0x08 -/* - * Set MPPE configuration - * - * Default is disabled. - */ -void ppp_set_mppe(ppp_pcb *pcb, u8_t flags); -#endif /* MPPE_SUPPORT */ - -/* - * Wait for up to intval milliseconds for a valid PPP packet from the peer. - * At the end of this time, or when a valid PPP packet is received from the - * peer, we commence negotiation by sending our first LCP packet. - * - * Default is 0. - */ -#define ppp_set_listen_time(ppp, intval) (ppp->settings.listen_time = intval) - -/* - * If set, we will attempt to initiate a connection but if no reply is received from - * the peer, we will then just wait passively for a valid LCP packet from the peer. - * - * Default is false. - */ -#define ppp_set_passive(ppp, boolval) (ppp->lcp_wantoptions.passive = boolval) - -/* - * If set, we will not transmit LCP packets to initiate a connection until a valid - * LCP packet is received from the peer. This is what we usually call the server mode. - * - * Default is false. - */ -#define ppp_set_silent(ppp, boolval) (ppp->lcp_wantoptions.silent = boolval) - -/* - * If set, enable protocol field compression negotiation in both the receive and - * the transmit direction. - * - * Default is true. - */ -#define ppp_set_neg_pcomp(ppp, boolval) (ppp->lcp_wantoptions.neg_pcompression = \ - ppp->lcp_allowoptions.neg_pcompression = boolval) - -/* - * If set, enable Address/Control compression in both the receive and the transmit - * direction. - * - * Default is true. - */ -#define ppp_set_neg_accomp(ppp, boolval) (ppp->lcp_wantoptions.neg_accompression = \ - ppp->lcp_allowoptions.neg_accompression = boolval) - -/* - * If set, enable asyncmap negotiation. Otherwise forcing all control characters to - * be escaped for both the transmit and the receive direction. - * - * Default is true. - */ -#define ppp_set_neg_asyncmap(ppp, boolval) (ppp->lcp_wantoptions.neg_asyncmap = \ - ppp->lcp_allowoptions.neg_asyncmap = boolval) - -/* - * This option sets the Async-Control-Character-Map (ACCM) for this end of the link. - * The ACCM is a set of 32 bits, one for each of the ASCII control characters with - * values from 0 to 31, where a 1 bit indicates that the corresponding control - * character should not be used in PPP packets sent to this system. The map is - * an unsigned 32 bits integer where the least significant bit (00000001) represents - * character 0 and the most significant bit (80000000) represents character 31. - * We will then ask the peer to send these characters as a 2-byte escape sequence. - * - * Default is 0. - */ -#define ppp_set_asyncmap(ppp, intval) (ppp->lcp_wantoptions.asyncmap = intval) - -/* - * Set a PPP interface as the default network interface - * (used to output all packets for which no specific route is found). - */ -#define ppp_set_default(ppp) netif_set_default(ppp->netif) - -#if PPP_NOTIFY_PHASE -/* - * Set a PPP notify phase callback. - * - * This can be used for example to set a LED pattern depending on the - * current phase of the PPP session. - */ -typedef void (*ppp_notify_phase_cb_fn)(ppp_pcb *pcb, u8_t phase, void *ctx); -void ppp_set_notify_phase_callback(ppp_pcb *pcb, ppp_notify_phase_cb_fn notify_phase_cb); -#endif /* PPP_NOTIFY_PHASE */ - -/* - * Initiate a PPP connection. - * - * This can only be called if PPP is in the dead phase. - * - * Holdoff is the time to wait (in seconds) before initiating - * the connection. - * - * If this port connects to a modem, the modem connection must be - * established before calling this. - */ -err_t ppp_connect(ppp_pcb *pcb, u16_t holdoff); - -#if PPP_SERVER -/* - * Listen for an incoming PPP connection. - * - * This can only be called if PPP is in the dead phase. - * - * If this port connects to a modem, the modem connection must be - * established before calling this. - */ -err_t ppp_listen(ppp_pcb *pcb); -#endif /* PPP_SERVER */ - -/* - * Initiate the end of a PPP connection. - * Any outstanding packets in the queues are dropped. - * - * Setting nocarrier to 1 close the PPP connection without initiating the - * shutdown procedure. Always using nocarrier = 0 is still recommended, - * this is going to take a little longer time if your link is down, but - * is a safer choice for the PPP state machine. - * - * Return 0 on success, an error code on failure. - */ -err_t ppp_close(ppp_pcb *pcb, u8_t nocarrier); - -/* - * Release the control block. - * - * This can only be called if PPP is in the dead phase. - * - * You must use ppp_close() before if you wish to terminate - * an established PPP session. - * - * Return 0 on success, an error code on failure. - */ -err_t ppp_free(ppp_pcb *pcb); - -/* - * PPP IOCTL commands. - * - * Get the up status - 0 for down, non-zero for up. The argument must - * point to an int. - */ -#define PPPCTLG_UPSTATUS 0 - -/* - * Get the PPP error code. The argument must point to an int. - * Returns a PPPERR_* value. - */ -#define PPPCTLG_ERRCODE 1 - -/* - * Get the fd associated with a PPP over serial - */ -#define PPPCTLG_FD 2 - -/* - * Get and set parameters for the given connection. - * Return 0 on success, an error code on failure. - */ -err_t ppp_ioctl(ppp_pcb *pcb, u8_t cmd, void *arg); - -/* Get the PPP netif interface */ -#define ppp_netif(ppp) (ppp->netif) - -/* Set an lwIP-style status-callback for the selected PPP device */ -#define ppp_set_netif_statuscallback(ppp, status_cb) \ - netif_set_status_callback(ppp->netif, status_cb); - -/* Set an lwIP-style link-callback for the selected PPP device */ -#define ppp_set_netif_linkcallback(ppp, link_cb) \ - netif_set_link_callback(ppp->netif, link_cb); - -#endif /* PPP_H */ - -#endif /* PPP_SUPPORT */ diff --git a/third_party/lwip/repo/lwip/src/include/netif/ppp/ppp_impl.h b/third_party/lwip/repo/lwip/src/include/netif/ppp/ppp_impl.h deleted file mode 100644 index 1d4c7742f35c11..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/netif/ppp/ppp_impl.h +++ /dev/null @@ -1,629 +0,0 @@ -/***************************************************************************** -* ppp.h - Network Point to Point Protocol header file. -* -* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. -* portions Copyright (c) 1997 Global Election Systems Inc. -* -* The authors hereby grant permission to use, copy, modify, distribute, -* and license this software and its documentation for any purpose, provided -* that existing copyright notices are retained in all copies and that this -* notice and the following disclaimer are included verbatim in any -* distributions. No written agreement, license, or royalty fee is required -* for any of the authorized uses. -* -* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR -* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -****************************************************************************** -* REVISION HISTORY -* -* 03-01-01 Marc Boucher -* Ported to lwIP. -* 97-11-05 Guy Lancaster , Global Election Systems Inc. -* Original derived from BSD codes. -*****************************************************************************/ -#ifndef LWIP_HDR_PPP_IMPL_H -#define LWIP_HDR_PPP_IMPL_H - -#include "netif/ppp/ppp_opts.h" - -#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#ifdef PPP_INCLUDE_SETTINGS_HEADER -#include "ppp_settings.h" -#endif - -#include /* formats */ -#include -#include -#include /* strtol() */ - -#include "lwip/netif.h" -#include "lwip/def.h" -#include "lwip/timeouts.h" - -#include "ppp.h" -#include "pppdebug.h" - -/* - * Memory used for control packets. - * - * PPP_CTRL_PBUF_MAX_SIZE is the amount of memory we allocate when we - * cannot figure out how much we are going to use before filling the buffer. - */ -#if PPP_USE_PBUF_RAM -#define PPP_CTRL_PBUF_TYPE PBUF_RAM -#define PPP_CTRL_PBUF_MAX_SIZE 512 -#else /* PPP_USE_PBUF_RAM */ -#define PPP_CTRL_PBUF_TYPE PBUF_POOL -#define PPP_CTRL_PBUF_MAX_SIZE PBUF_POOL_BUFSIZE -#endif /* PPP_USE_PBUF_RAM */ - -/* - * The basic PPP frame. - */ -#define PPP_ADDRESS(p) (((u_char *)(p))[0]) -#define PPP_CONTROL(p) (((u_char *)(p))[1]) -#define PPP_PROTOCOL(p) ((((u_char *)(p))[2] << 8) + ((u_char *)(p))[3]) - -/* - * Significant octet values. - */ -#define PPP_ALLSTATIONS 0xff /* All-Stations broadcast address */ -#define PPP_UI 0x03 /* Unnumbered Information */ -#define PPP_FLAG 0x7e /* Flag Sequence */ -#define PPP_ESCAPE 0x7d /* Asynchronous Control Escape */ -#define PPP_TRANS 0x20 /* Asynchronous transparency modifier */ - -/* - * Protocol field values. - */ -#define PPP_IP 0x21 /* Internet Protocol */ -#if 0 /* UNUSED */ -#define PPP_AT 0x29 /* AppleTalk Protocol */ -#define PPP_IPX 0x2b /* IPX protocol */ -#endif /* UNUSED */ -#if VJ_SUPPORT -#define PPP_VJC_COMP 0x2d /* VJ compressed TCP */ -#define PPP_VJC_UNCOMP 0x2f /* VJ uncompressed TCP */ -#endif /* VJ_SUPPORT */ -#if PPP_IPV6_SUPPORT -#define PPP_IPV6 0x57 /* Internet Protocol Version 6 */ -#endif /* PPP_IPV6_SUPPORT */ -#if CCP_SUPPORT -#define PPP_COMP 0xfd /* compressed packet */ -#endif /* CCP_SUPPORT */ -#define PPP_IPCP 0x8021 /* IP Control Protocol */ -#if 0 /* UNUSED */ -#define PPP_ATCP 0x8029 /* AppleTalk Control Protocol */ -#define PPP_IPXCP 0x802b /* IPX Control Protocol */ -#endif /* UNUSED */ -#if PPP_IPV6_SUPPORT -#define PPP_IPV6CP 0x8057 /* IPv6 Control Protocol */ -#endif /* PPP_IPV6_SUPPORT */ -#if CCP_SUPPORT -#define PPP_CCP 0x80fd /* Compression Control Protocol */ -#endif /* CCP_SUPPORT */ -#if ECP_SUPPORT -#define PPP_ECP 0x8053 /* Encryption Control Protocol */ -#endif /* ECP_SUPPORT */ -#define PPP_LCP 0xc021 /* Link Control Protocol */ -#if PAP_SUPPORT -#define PPP_PAP 0xc023 /* Password Authentication Protocol */ -#endif /* PAP_SUPPORT */ -#if LQR_SUPPORT -#define PPP_LQR 0xc025 /* Link Quality Report protocol */ -#endif /* LQR_SUPPORT */ -#if CHAP_SUPPORT -#define PPP_CHAP 0xc223 /* Cryptographic Handshake Auth. Protocol */ -#endif /* CHAP_SUPPORT */ -#if CBCP_SUPPORT -#define PPP_CBCP 0xc029 /* Callback Control Protocol */ -#endif /* CBCP_SUPPORT */ -#if EAP_SUPPORT -#define PPP_EAP 0xc227 /* Extensible Authentication Protocol */ -#endif /* EAP_SUPPORT */ - -/* - * The following struct gives the addresses of procedures to call - * for a particular lower link level protocol. - */ -struct link_callbacks { - /* Start a connection (e.g. Initiate discovery phase) */ - void (*connect) (ppp_pcb *pcb, void *ctx); -#if PPP_SERVER - /* Listen for an incoming connection (Passive mode) */ - void (*listen) (ppp_pcb *pcb, void *ctx); -#endif /* PPP_SERVER */ - /* End a connection (i.e. initiate disconnect phase) */ - void (*disconnect) (ppp_pcb *pcb, void *ctx); - /* Free lower protocol control block */ - err_t (*free) (ppp_pcb *pcb, void *ctx); - /* Write a pbuf to a ppp link, only used from PPP functions to send PPP packets. */ - err_t (*write)(ppp_pcb *pcb, void *ctx, struct pbuf *p); - /* Send a packet from lwIP core (IPv4 or IPv6) */ - err_t (*netif_output)(ppp_pcb *pcb, void *ctx, struct pbuf *p, u_short protocol); - /* configure the transmit-side characteristics of the PPP interface */ - void (*send_config)(ppp_pcb *pcb, void *ctx, u32_t accm, int pcomp, int accomp); - /* confire the receive-side characteristics of the PPP interface */ - void (*recv_config)(ppp_pcb *pcb, void *ctx, u32_t accm, int pcomp, int accomp); -}; - -/* - * What to do with network protocol (NP) packets. - */ -enum NPmode { - NPMODE_PASS, /* pass the packet through */ - NPMODE_DROP, /* silently drop the packet */ - NPMODE_ERROR, /* return an error */ - NPMODE_QUEUE /* save it up for later. */ -}; - -/* - * Statistics. - */ -#if PPP_STATS_SUPPORT -struct pppstat { - unsigned int ppp_ibytes; /* bytes received */ - unsigned int ppp_ipackets; /* packets received */ - unsigned int ppp_ierrors; /* receive errors */ - unsigned int ppp_obytes; /* bytes sent */ - unsigned int ppp_opackets; /* packets sent */ - unsigned int ppp_oerrors; /* transmit errors */ -}; - -#if VJ_SUPPORT -struct vjstat { - unsigned int vjs_packets; /* outbound packets */ - unsigned int vjs_compressed; /* outbound compressed packets */ - unsigned int vjs_searches; /* searches for connection state */ - unsigned int vjs_misses; /* times couldn't find conn. state */ - unsigned int vjs_uncompressedin; /* inbound uncompressed packets */ - unsigned int vjs_compressedin; /* inbound compressed packets */ - unsigned int vjs_errorin; /* inbound unknown type packets */ - unsigned int vjs_tossed; /* inbound packets tossed because of error */ -}; -#endif /* VJ_SUPPORT */ - -struct ppp_stats { - struct pppstat p; /* basic PPP statistics */ -#if VJ_SUPPORT - struct vjstat vj; /* VJ header compression statistics */ -#endif /* VJ_SUPPORT */ -}; - -#if CCP_SUPPORT -struct compstat { - unsigned int unc_bytes; /* total uncompressed bytes */ - unsigned int unc_packets; /* total uncompressed packets */ - unsigned int comp_bytes; /* compressed bytes */ - unsigned int comp_packets; /* compressed packets */ - unsigned int inc_bytes; /* incompressible bytes */ - unsigned int inc_packets; /* incompressible packets */ - unsigned int ratio; /* recent compression ratio << 8 */ -}; - -struct ppp_comp_stats { - struct compstat c; /* packet compression statistics */ - struct compstat d; /* packet decompression statistics */ -}; -#endif /* CCP_SUPPORT */ - -#endif /* PPP_STATS_SUPPORT */ - -#if PPP_IDLETIMELIMIT -/* - * The following structure records the time in seconds since - * the last NP packet was sent or received. - */ -struct ppp_idle { - time_t xmit_idle; /* time since last NP packet sent */ - time_t recv_idle; /* time since last NP packet received */ -}; -#endif /* PPP_IDLETIMELIMIT */ - -/* values for epdisc.class */ -#define EPD_NULL 0 /* null discriminator, no data */ -#define EPD_LOCAL 1 -#define EPD_IP 2 -#define EPD_MAC 3 -#define EPD_MAGIC 4 -#define EPD_PHONENUM 5 - -/* - * Global variables. - */ -#ifdef HAVE_MULTILINK -extern u8_t multilink; /* enable multilink operation */ -extern u8_t doing_multilink; -extern u8_t multilink_master; -extern u8_t bundle_eof; -extern u8_t bundle_terminating; -#endif - -#ifdef MAXOCTETS -extern unsigned int maxoctets; /* Maximum octetes per session (in bytes) */ -extern int maxoctets_dir; /* Direction : - 0 - in+out (default) - 1 - in - 2 - out - 3 - max(in,out) */ -extern int maxoctets_timeout; /* Timeout for check of octets limit */ -#define PPP_OCTETS_DIRECTION_SUM 0 -#define PPP_OCTETS_DIRECTION_IN 1 -#define PPP_OCTETS_DIRECTION_OUT 2 -#define PPP_OCTETS_DIRECTION_MAXOVERAL 3 -/* same as previos, but little different on RADIUS side */ -#define PPP_OCTETS_DIRECTION_MAXSESSION 4 -#endif - -/* Data input may be used by CCP and ECP, remove this entry - * from struct protent to save some flash - */ -#define PPP_DATAINPUT 0 - -/* - * The following struct gives the addresses of procedures to call - * for a particular protocol. - */ -struct protent { - u_short protocol; /* PPP protocol number */ - /* Initialization procedure */ - void (*init) (ppp_pcb *pcb); - /* Process a received packet */ - void (*input) (ppp_pcb *pcb, u_char *pkt, int len); - /* Process a received protocol-reject */ - void (*protrej) (ppp_pcb *pcb); - /* Lower layer has come up */ - void (*lowerup) (ppp_pcb *pcb); - /* Lower layer has gone down */ - void (*lowerdown) (ppp_pcb *pcb); - /* Open the protocol */ - void (*open) (ppp_pcb *pcb); - /* Close the protocol */ - void (*close) (ppp_pcb *pcb, const char *reason); -#if PRINTPKT_SUPPORT - /* Print a packet in readable form */ - int (*printpkt) (const u_char *pkt, int len, - void (*printer) (void *, const char *, ...), - void *arg); -#endif /* PRINTPKT_SUPPORT */ -#if PPP_DATAINPUT - /* Process a received data packet */ - void (*datainput) (ppp_pcb *pcb, u_char *pkt, int len); -#endif /* PPP_DATAINPUT */ -#if PRINTPKT_SUPPORT - const char *name; /* Text name of protocol */ - const char *data_name; /* Text name of corresponding data protocol */ -#endif /* PRINTPKT_SUPPORT */ -#if PPP_OPTIONS - option_t *options; /* List of command-line options */ - /* Check requested options, assign defaults */ - void (*check_options) (void); -#endif /* PPP_OPTIONS */ -#if DEMAND_SUPPORT - /* Configure interface for demand-dial */ - int (*demand_conf) (int unit); - /* Say whether to bring up link for this pkt */ - int (*active_pkt) (u_char *pkt, int len); -#endif /* DEMAND_SUPPORT */ -}; - -/* Table of pointers to supported protocols */ -extern const struct protent* const protocols[]; - - -/* Values for auth_pending, auth_done */ -#if PAP_SUPPORT -#define PAP_WITHPEER 0x1 -#define PAP_PEER 0x2 -#endif /* PAP_SUPPORT */ -#if CHAP_SUPPORT -#define CHAP_WITHPEER 0x4 -#define CHAP_PEER 0x8 -#endif /* CHAP_SUPPORT */ -#if EAP_SUPPORT -#define EAP_WITHPEER 0x10 -#define EAP_PEER 0x20 -#endif /* EAP_SUPPORT */ - -/* Values for auth_done only */ -#if CHAP_SUPPORT -#define CHAP_MD5_WITHPEER 0x40 -#define CHAP_MD5_PEER 0x80 -#if MSCHAP_SUPPORT -#define CHAP_MS_SHIFT 8 /* LSB position for MS auths */ -#define CHAP_MS_WITHPEER 0x100 -#define CHAP_MS_PEER 0x200 -#define CHAP_MS2_WITHPEER 0x400 -#define CHAP_MS2_PEER 0x800 -#endif /* MSCHAP_SUPPORT */ -#endif /* CHAP_SUPPORT */ - -/* Supported CHAP protocols */ -#if CHAP_SUPPORT - -#if MSCHAP_SUPPORT -#define CHAP_MDTYPE_SUPPORTED (MDTYPE_MICROSOFT_V2 | MDTYPE_MICROSOFT | MDTYPE_MD5) -#else /* MSCHAP_SUPPORT */ -#define CHAP_MDTYPE_SUPPORTED (MDTYPE_MD5) -#endif /* MSCHAP_SUPPORT */ - -#else /* CHAP_SUPPORT */ -#define CHAP_MDTYPE_SUPPORTED (MDTYPE_NONE) -#endif /* CHAP_SUPPORT */ - -#if PPP_STATS_SUPPORT -/* - * PPP statistics structure - */ -struct pppd_stats { - unsigned int bytes_in; - unsigned int bytes_out; - unsigned int pkts_in; - unsigned int pkts_out; -}; -#endif /* PPP_STATS_SUPPORT */ - - -/* - * PPP private functions - */ - - -/* - * Functions called from lwIP core. - */ - -/* initialize the PPP subsystem */ -int ppp_init(void); - -/* - * Functions called from PPP link protocols. - */ - -/* Create a new PPP control block */ -ppp_pcb *ppp_new(struct netif *pppif, const struct link_callbacks *callbacks, void *link_ctx_cb, - ppp_link_status_cb_fn link_status_cb, void *ctx_cb); - -/* Initiate LCP open request */ -void ppp_start(ppp_pcb *pcb); - -/* Called when link failed to setup */ -void ppp_link_failed(ppp_pcb *pcb); - -/* Called when link is normally down (i.e. it was asked to end) */ -void ppp_link_end(ppp_pcb *pcb); - -/* function called to process input packet */ -void ppp_input(ppp_pcb *pcb, struct pbuf *pb); - -/* helper function, merge a pbuf chain into one pbuf */ -struct pbuf *ppp_singlebuf(struct pbuf *p); - - -/* - * Functions called by PPP protocols. - */ - -/* function called by all PPP subsystems to send packets */ -err_t ppp_write(ppp_pcb *pcb, struct pbuf *p); - -/* functions called by auth.c link_terminated() */ -void ppp_link_terminated(ppp_pcb *pcb); - -void new_phase(ppp_pcb *pcb, int p); - -int ppp_send_config(ppp_pcb *pcb, int mtu, u32_t accm, int pcomp, int accomp); -int ppp_recv_config(ppp_pcb *pcb, int mru, u32_t accm, int pcomp, int accomp); - -#if PPP_IPV4_SUPPORT -int sifaddr(ppp_pcb *pcb, u32_t our_adr, u32_t his_adr, u32_t netmask); -int cifaddr(ppp_pcb *pcb, u32_t our_adr, u32_t his_adr); -#if 0 /* UNUSED - PROXY ARP */ -int sifproxyarp(ppp_pcb *pcb, u32_t his_adr); -int cifproxyarp(ppp_pcb *pcb, u32_t his_adr); -#endif /* UNUSED - PROXY ARP */ -#if LWIP_DNS -int sdns(ppp_pcb *pcb, u32_t ns1, u32_t ns2); -int cdns(ppp_pcb *pcb, u32_t ns1, u32_t ns2); -#endif /* LWIP_DNS */ -#if VJ_SUPPORT -int sifvjcomp(ppp_pcb *pcb, int vjcomp, int cidcomp, int maxcid); -#endif /* VJ_SUPPORT */ -int sifup(ppp_pcb *pcb); -int sifdown (ppp_pcb *pcb); -u32_t get_mask(u32_t addr); -#endif /* PPP_IPV4_SUPPORT */ - -#if PPP_IPV6_SUPPORT -int sif6addr(ppp_pcb *pcb, eui64_t our_eui64, eui64_t his_eui64); -int cif6addr(ppp_pcb *pcb, eui64_t our_eui64, eui64_t his_eui64); -int sif6up(ppp_pcb *pcb); -int sif6down (ppp_pcb *pcb); -#endif /* PPP_IPV6_SUPPORT */ - -#if DEMAND_SUPPORT -int sifnpmode(ppp_pcb *pcb, int proto, enum NPmode mode); -#endif /* DEMAND_SUPPORt */ - -void netif_set_mtu(ppp_pcb *pcb, int mtu); -int netif_get_mtu(ppp_pcb *pcb); - -#if CCP_SUPPORT -#if 0 /* unused */ -int ccp_test(ppp_pcb *pcb, u_char *opt_ptr, int opt_len, int for_transmit); -#endif /* unused */ -void ccp_set(ppp_pcb *pcb, u8_t isopen, u8_t isup, u8_t receive_method, u8_t transmit_method); -void ccp_reset_comp(ppp_pcb *pcb); -void ccp_reset_decomp(ppp_pcb *pcb); -#if 0 /* unused */ -int ccp_fatal_error(ppp_pcb *pcb); -#endif /* unused */ -#endif /* CCP_SUPPORT */ - -#if PPP_IDLETIMELIMIT -int get_idle_time(ppp_pcb *pcb, struct ppp_idle *ip); -#endif /* PPP_IDLETIMELIMIT */ - -#if DEMAND_SUPPORT -int get_loop_output(void); -#endif /* DEMAND_SUPPORT */ - -/* Optional protocol names list, to make our messages a little more informative. */ -#if PPP_PROTOCOLNAME -const char * protocol_name(int proto); -#endif /* PPP_PROTOCOLNAME */ - -/* Optional stats support, to get some statistics on the PPP interface */ -#if PPP_STATS_SUPPORT -void print_link_stats(void); /* Print stats, if available */ -void reset_link_stats(int u); /* Reset (init) stats when link goes up */ -void update_link_stats(int u); /* Get stats at link termination */ -#endif /* PPP_STATS_SUPPORT */ - - - -/* - * Inline versions of get/put char/short/long. - * Pointer is advanced; we assume that both arguments - * are lvalues and will already be in registers. - * cp MUST be u_char *. - */ -#define GETCHAR(c, cp) { \ - (c) = *(cp)++; \ -} -#define PUTCHAR(c, cp) { \ - *(cp)++ = (u_char) (c); \ -} -#define GETSHORT(s, cp) { \ - (s) = *(cp)++ << 8; \ - (s) |= *(cp)++; \ -} -#define PUTSHORT(s, cp) { \ - *(cp)++ = (u_char) ((s) >> 8); \ - *(cp)++ = (u_char) (s); \ -} -#define GETLONG(l, cp) { \ - (l) = *(cp)++ << 8; \ - (l) |= *(cp)++; (l) <<= 8; \ - (l) |= *(cp)++; (l) <<= 8; \ - (l) |= *(cp)++; \ -} -#define PUTLONG(l, cp) { \ - *(cp)++ = (u_char) ((l) >> 24); \ - *(cp)++ = (u_char) ((l) >> 16); \ - *(cp)++ = (u_char) ((l) >> 8); \ - *(cp)++ = (u_char) (l); \ -} - -#define INCPTR(n, cp) ((cp) += (n)) -#define DECPTR(n, cp) ((cp) -= (n)) - -/* - * System dependent definitions for user-level 4.3BSD UNIX implementation. - */ -#define TIMEOUT(f, a, t) do { sys_untimeout((f), (a)); sys_timeout((t)*1000, (f), (a)); } while(0) -#define TIMEOUTMS(f, a, t) do { sys_untimeout((f), (a)); sys_timeout((t), (f), (a)); } while(0) -#define UNTIMEOUT(f, a) sys_untimeout((f), (a)) - -#define BZERO(s, n) memset(s, 0, n) -#define BCMP(s1, s2, l) memcmp(s1, s2, l) - -#define PRINTMSG(m, l) { ppp_info("Remote message: %0.*v", l, m); } - -/* - * MAKEHEADER - Add Header fields to a packet. - */ -#define MAKEHEADER(p, t) { \ - PUTCHAR(PPP_ALLSTATIONS, p); \ - PUTCHAR(PPP_UI, p); \ - PUTSHORT(t, p); } - -/* Procedures exported from auth.c */ -void link_required(ppp_pcb *pcb); /* we are starting to use the link */ -void link_terminated(ppp_pcb *pcb); /* we are finished with the link */ -void link_down(ppp_pcb *pcb); /* the LCP layer has left the Opened state */ -void upper_layers_down(ppp_pcb *pcb); /* take all NCPs down */ -void link_established(ppp_pcb *pcb); /* the link is up; authenticate now */ -void start_networks(ppp_pcb *pcb); /* start all the network control protos */ -void continue_networks(ppp_pcb *pcb); /* start network [ip, etc] control protos */ -#if PPP_AUTH_SUPPORT -#if PPP_SERVER -int auth_check_passwd(ppp_pcb *pcb, char *auser, int userlen, char *apasswd, int passwdlen, const char **msg, int *msglen); - /* check the user name and passwd against configuration */ -void auth_peer_fail(ppp_pcb *pcb, int protocol); - /* peer failed to authenticate itself */ -void auth_peer_success(ppp_pcb *pcb, int protocol, int prot_flavor, const char *name, int namelen); - /* peer successfully authenticated itself */ -#endif /* PPP_SERVER */ -void auth_withpeer_fail(ppp_pcb *pcb, int protocol); - /* we failed to authenticate ourselves */ -void auth_withpeer_success(ppp_pcb *pcb, int protocol, int prot_flavor); - /* we successfully authenticated ourselves */ -#endif /* PPP_AUTH_SUPPORT */ -void np_up(ppp_pcb *pcb, int proto); /* a network protocol has come up */ -void np_down(ppp_pcb *pcb, int proto); /* a network protocol has gone down */ -void np_finished(ppp_pcb *pcb, int proto); /* a network protocol no longer needs link */ -#if PPP_AUTH_SUPPORT -int get_secret(ppp_pcb *pcb, const char *client, const char *server, char *secret, int *secret_len, int am_server); - /* get "secret" for chap */ -#endif /* PPP_AUTH_SUPPORT */ - -/* Procedures exported from ipcp.c */ -/* int parse_dotted_ip (char *, u32_t *); */ - -/* Procedures exported from demand.c */ -#if DEMAND_SUPPORT -void demand_conf (void); /* config interface(s) for demand-dial */ -void demand_block (void); /* set all NPs to queue up packets */ -void demand_unblock (void); /* set all NPs to pass packets */ -void demand_discard (void); /* set all NPs to discard packets */ -void demand_rexmit (int, u32_t); /* retransmit saved frames for an NP*/ -int loop_chars (unsigned char *, int); /* process chars from loopback */ -int loop_frame (unsigned char *, int); /* should we bring link up? */ -#endif /* DEMAND_SUPPORT */ - -/* Procedures exported from multilink.c */ -#ifdef HAVE_MULTILINK -void mp_check_options (void); /* Check multilink-related options */ -int mp_join_bundle (void); /* join our link to an appropriate bundle */ -void mp_exit_bundle (void); /* have disconnected our link from bundle */ -void mp_bundle_terminated (void); -char *epdisc_to_str (struct epdisc *); /* string from endpoint discrim. */ -int str_to_epdisc (struct epdisc *, char *); /* endpt disc. from str */ -#else -#define mp_bundle_terminated() /* nothing */ -#define mp_exit_bundle() /* nothing */ -#define doing_multilink 0 -#define multilink_master 0 -#endif - -/* Procedures exported from utils.c. */ -void ppp_print_string(const u_char *p, int len, void (*printer) (void *, const char *, ...), void *arg); /* Format a string for output */ -int ppp_slprintf(char *buf, int buflen, const char *fmt, ...); /* sprintf++ */ -int ppp_vslprintf(char *buf, int buflen, const char *fmt, va_list args); /* vsprintf++ */ -size_t ppp_strlcpy(char *dest, const char *src, size_t len); /* safe strcpy */ -size_t ppp_strlcat(char *dest, const char *src, size_t len); /* safe strncpy */ -void ppp_dbglog(const char *fmt, ...); /* log a debug message */ -void ppp_info(const char *fmt, ...); /* log an informational message */ -void ppp_notice(const char *fmt, ...); /* log a notice-level message */ -void ppp_warn(const char *fmt, ...); /* log a warning message */ -void ppp_error(const char *fmt, ...); /* log an error message */ -void ppp_fatal(const char *fmt, ...); /* log an error message and die(1) */ -#if PRINTPKT_SUPPORT -void ppp_dump_packet(ppp_pcb *pcb, const char *tag, unsigned char *p, int len); - /* dump packet to debug log if interesting */ -#endif /* PRINTPKT_SUPPORT */ - - -#endif /* PPP_SUPPORT */ -#endif /* LWIP_HDR_PPP_IMPL_H */ diff --git a/third_party/lwip/repo/lwip/src/include/netif/ppp/ppp_opts.h b/third_party/lwip/repo/lwip/src/include/netif/ppp/ppp_opts.h deleted file mode 100644 index fa79c090f2570d..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/netif/ppp/ppp_opts.h +++ /dev/null @@ -1,593 +0,0 @@ -/* - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - */ - -#ifndef LWIP_PPP_OPTS_H -#define LWIP_PPP_OPTS_H - -#include "lwip/opt.h" - -/** - * PPP_SUPPORT==1: Enable PPP. - */ -#ifndef PPP_SUPPORT -#define PPP_SUPPORT 0 -#endif - -/** - * PPPOE_SUPPORT==1: Enable PPP Over Ethernet - */ -#ifndef PPPOE_SUPPORT -#define PPPOE_SUPPORT 0 -#endif - -/** - * PPPOL2TP_SUPPORT==1: Enable PPP Over L2TP - */ -#ifndef PPPOL2TP_SUPPORT -#define PPPOL2TP_SUPPORT 0 -#endif - -/** - * PPPOL2TP_AUTH_SUPPORT==1: Enable PPP Over L2TP Auth (enable MD5 support) - */ -#ifndef PPPOL2TP_AUTH_SUPPORT -#define PPPOL2TP_AUTH_SUPPORT PPPOL2TP_SUPPORT -#endif - -/** - * PPPOS_SUPPORT==1: Enable PPP Over Serial - */ -#ifndef PPPOS_SUPPORT -#define PPPOS_SUPPORT PPP_SUPPORT -#endif - -/** - * LWIP_PPP_API==1: Enable PPP API (in pppapi.c) - */ -#ifndef LWIP_PPP_API -#define LWIP_PPP_API (PPP_SUPPORT && (NO_SYS == 0)) -#endif - -/** - * MEMP_NUM_PPP_PCB: the number of simultaneously active PPP - * connections (requires the PPP_SUPPORT option) - */ -#ifndef MEMP_NUM_PPP_PCB -#define MEMP_NUM_PPP_PCB 1 -#endif - -#if PPP_SUPPORT - -/** - * MEMP_NUM_PPPOS_INTERFACES: the number of concurrently active PPPoS - * interfaces (only used with PPPOS_SUPPORT==1) - */ -#ifndef MEMP_NUM_PPPOS_INTERFACES -#define MEMP_NUM_PPPOS_INTERFACES MEMP_NUM_PPP_PCB -#endif - -/** - * MEMP_NUM_PPPOE_INTERFACES: the number of concurrently active PPPoE - * interfaces (only used with PPPOE_SUPPORT==1) - */ -#ifndef MEMP_NUM_PPPOE_INTERFACES -#define MEMP_NUM_PPPOE_INTERFACES 1 -#endif - -/** - * MEMP_NUM_PPPOL2TP_INTERFACES: the number of concurrently active PPPoL2TP - * interfaces (only used with PPPOL2TP_SUPPORT==1) - */ -#ifndef MEMP_NUM_PPPOL2TP_INTERFACES -#define MEMP_NUM_PPPOL2TP_INTERFACES 1 -#endif - -/** - * MEMP_NUM_PPP_API_MSG: Number of concurrent PPP API messages (in pppapi.c) - */ -#ifndef MEMP_NUM_PPP_API_MSG -#define MEMP_NUM_PPP_API_MSG 5 -#endif - -/** - * PPP_DEBUG: Enable debugging for PPP. - */ -#ifndef PPP_DEBUG -#define PPP_DEBUG LWIP_DBG_OFF -#endif - -/** - * PPP_INPROC_IRQ_SAFE==1 call pppos_input() using tcpip_callback(). - * - * Please read the "PPPoS input path" chapter in the PPP documentation about this option. - */ -#ifndef PPP_INPROC_IRQ_SAFE -#define PPP_INPROC_IRQ_SAFE 0 -#endif - -/** - * PRINTPKT_SUPPORT==1: Enable PPP print packet support - * - * Mandatory for debugging, it displays exchanged packet content in debug trace. - */ -#ifndef PRINTPKT_SUPPORT -#define PRINTPKT_SUPPORT 0 -#endif - -/** - * PPP_IPV4_SUPPORT==1: Enable PPP IPv4 support - */ -#ifndef PPP_IPV4_SUPPORT -#define PPP_IPV4_SUPPORT (LWIP_IPV4) -#endif - -/** - * PPP_IPV6_SUPPORT==1: Enable PPP IPv6 support - */ -#ifndef PPP_IPV6_SUPPORT -#define PPP_IPV6_SUPPORT (LWIP_IPV6) -#endif - -/** - * PPP_NOTIFY_PHASE==1: Support PPP notify phase support - * - * PPP notify phase support allows you to set a callback which is - * called on change of the internal PPP state machine. - * - * This can be used for example to set a LED pattern depending on the - * current phase of the PPP session. - */ -#ifndef PPP_NOTIFY_PHASE -#define PPP_NOTIFY_PHASE 0 -#endif - -/** - * pbuf_type PPP is using for LCP, PAP, CHAP, EAP, CCP, IPCP and IP6CP packets. - * - * Memory allocated must be single buffered for PPP to works, it requires pbuf - * that are not going to be chained when allocated. This requires setting - * PBUF_POOL_BUFSIZE to at least 512 bytes, which is quite huge for small systems. - * - * Setting PPP_USE_PBUF_RAM to 1 makes PPP use memory from heap where continuous - * buffers are required, allowing you to use a smaller PBUF_POOL_BUFSIZE. - */ -#ifndef PPP_USE_PBUF_RAM -#define PPP_USE_PBUF_RAM 0 -#endif - -/** - * PPP_FCS_TABLE: Keep a 256*2 byte table to speed up FCS calculation for PPPoS - */ -#ifndef PPP_FCS_TABLE -#define PPP_FCS_TABLE 1 -#endif - -/** - * PAP_SUPPORT==1: Support PAP. - */ -#ifndef PAP_SUPPORT -#define PAP_SUPPORT 0 -#endif - -/** - * CHAP_SUPPORT==1: Support CHAP. - */ -#ifndef CHAP_SUPPORT -#define CHAP_SUPPORT 0 -#endif - -/** - * MSCHAP_SUPPORT==1: Support MSCHAP. - */ -#ifndef MSCHAP_SUPPORT -#define MSCHAP_SUPPORT 0 -#endif -#if MSCHAP_SUPPORT -/* MSCHAP requires CHAP support */ -#undef CHAP_SUPPORT -#define CHAP_SUPPORT 1 -#endif /* MSCHAP_SUPPORT */ - -/** - * EAP_SUPPORT==1: Support EAP. - */ -#ifndef EAP_SUPPORT -#define EAP_SUPPORT 0 -#endif - -/** - * CCP_SUPPORT==1: Support CCP. - */ -#ifndef CCP_SUPPORT -#define CCP_SUPPORT 0 -#endif - -/** - * MPPE_SUPPORT==1: Support MPPE. - */ -#ifndef MPPE_SUPPORT -#define MPPE_SUPPORT 0 -#endif -#if MPPE_SUPPORT -/* MPPE requires CCP support */ -#undef CCP_SUPPORT -#define CCP_SUPPORT 1 -/* MPPE requires MSCHAP support */ -#undef MSCHAP_SUPPORT -#define MSCHAP_SUPPORT 1 -/* MSCHAP requires CHAP support */ -#undef CHAP_SUPPORT -#define CHAP_SUPPORT 1 -#endif /* MPPE_SUPPORT */ - -/** - * CBCP_SUPPORT==1: Support CBCP. CURRENTLY NOT SUPPORTED! DO NOT SET! - */ -#ifndef CBCP_SUPPORT -#define CBCP_SUPPORT 0 -#endif - -/** - * ECP_SUPPORT==1: Support ECP. CURRENTLY NOT SUPPORTED! DO NOT SET! - */ -#ifndef ECP_SUPPORT -#define ECP_SUPPORT 0 -#endif - -/** - * DEMAND_SUPPORT==1: Support dial on demand. CURRENTLY NOT SUPPORTED! DO NOT SET! - */ -#ifndef DEMAND_SUPPORT -#define DEMAND_SUPPORT 0 -#endif - -/** - * LQR_SUPPORT==1: Support Link Quality Report. Do nothing except exchanging some LCP packets. - */ -#ifndef LQR_SUPPORT -#define LQR_SUPPORT 0 -#endif - -/** - * PPP_SERVER==1: Enable PPP server support (waiting for incoming PPP session). - * - * Currently only supported for PPPoS. - */ -#ifndef PPP_SERVER -#define PPP_SERVER 0 -#endif - -#if PPP_SERVER -/* - * PPP_OUR_NAME: Our name for authentication purposes - */ -#ifndef PPP_OUR_NAME -#define PPP_OUR_NAME "lwIP" -#endif -#endif /* PPP_SERVER */ - -/** - * VJ_SUPPORT==1: Support VJ header compression. - */ -#ifndef VJ_SUPPORT -#define VJ_SUPPORT 1 -#endif -/* VJ compression is only supported for TCP over IPv4 over PPPoS. */ -#if !PPPOS_SUPPORT || !PPP_IPV4_SUPPORT || !LWIP_TCP -#undef VJ_SUPPORT -#define VJ_SUPPORT 0 -#endif /* !PPPOS_SUPPORT */ - -/** - * PPP_MD5_RANDM==1: Use MD5 for better randomness. - * Enabled by default if CHAP, EAP, or L2TP AUTH support is enabled. - */ -#ifndef PPP_MD5_RANDM -#define PPP_MD5_RANDM (CHAP_SUPPORT || EAP_SUPPORT || PPPOL2TP_AUTH_SUPPORT) -#endif - -/** - * PolarSSL embedded library - * - * - * lwIP contains some files fetched from the latest BSD release of - * the PolarSSL project (PolarSSL 0.10.1-bsd) for ciphers and encryption - * methods we need for lwIP PPP support. - * - * The PolarSSL files were cleaned to contain only the necessary struct - * fields and functions needed for lwIP. - * - * The PolarSSL API was not changed at all, so if you are already using - * PolarSSL you can choose to skip the compilation of the included PolarSSL - * library into lwIP. - * - * If you are not using the embedded copy you must include external - * libraries into your arch/cc.h port file. - * - * Beware of the stack requirements which can be a lot larger if you are not - * using our cleaned PolarSSL library. - */ - -/** - * LWIP_USE_EXTERNAL_POLARSSL: Use external PolarSSL library - */ -#ifndef LWIP_USE_EXTERNAL_POLARSSL -#define LWIP_USE_EXTERNAL_POLARSSL 0 -#endif - -/** - * LWIP_USE_EXTERNAL_MBEDTLS: Use external mbed TLS library - */ -#ifndef LWIP_USE_EXTERNAL_MBEDTLS -#define LWIP_USE_EXTERNAL_MBEDTLS 0 -#endif - -/* - * PPP Timeouts - */ - -/** - * FSM_DEFTIMEOUT: Timeout time in seconds - */ -#ifndef FSM_DEFTIMEOUT -#define FSM_DEFTIMEOUT 6 -#endif - -/** - * FSM_DEFMAXTERMREQS: Maximum Terminate-Request transmissions - */ -#ifndef FSM_DEFMAXTERMREQS -#define FSM_DEFMAXTERMREQS 2 -#endif - -/** - * FSM_DEFMAXCONFREQS: Maximum Configure-Request transmissions - */ -#ifndef FSM_DEFMAXCONFREQS -#define FSM_DEFMAXCONFREQS 10 -#endif - -/** - * FSM_DEFMAXNAKLOOPS: Maximum number of nak loops - */ -#ifndef FSM_DEFMAXNAKLOOPS -#define FSM_DEFMAXNAKLOOPS 5 -#endif - -/** - * UPAP_DEFTIMEOUT: Timeout (seconds) for retransmitting req - */ -#ifndef UPAP_DEFTIMEOUT -#define UPAP_DEFTIMEOUT 6 -#endif - -/** - * UPAP_DEFTRANSMITS: Maximum number of auth-reqs to send - */ -#ifndef UPAP_DEFTRANSMITS -#define UPAP_DEFTRANSMITS 10 -#endif - -#if PPP_SERVER -/** - * UPAP_DEFREQTIME: Time to wait for auth-req from peer - */ -#ifndef UPAP_DEFREQTIME -#define UPAP_DEFREQTIME 30 -#endif -#endif /* PPP_SERVER */ - -/** - * CHAP_DEFTIMEOUT: Timeout (seconds) for retransmitting req - */ -#ifndef CHAP_DEFTIMEOUT -#define CHAP_DEFTIMEOUT 6 -#endif - -/** - * CHAP_DEFTRANSMITS: max # times to send challenge - */ -#ifndef CHAP_DEFTRANSMITS -#define CHAP_DEFTRANSMITS 10 -#endif - -#if PPP_SERVER -/** - * CHAP_DEFRECHALLENGETIME: If this option is > 0, rechallenge the peer every n seconds - */ -#ifndef CHAP_DEFRECHALLENGETIME -#define CHAP_DEFRECHALLENGETIME 0 -#endif -#endif /* PPP_SERVER */ - -/** - * EAP_DEFREQTIME: Time to wait for peer request - */ -#ifndef EAP_DEFREQTIME -#define EAP_DEFREQTIME 6 -#endif - -/** - * EAP_DEFALLOWREQ: max # times to accept requests - */ -#ifndef EAP_DEFALLOWREQ -#define EAP_DEFALLOWREQ 10 -#endif - -#if PPP_SERVER -/** - * EAP_DEFTIMEOUT: Timeout (seconds) for rexmit - */ -#ifndef EAP_DEFTIMEOUT -#define EAP_DEFTIMEOUT 6 -#endif - -/** - * EAP_DEFTRANSMITS: max # times to transmit - */ -#ifndef EAP_DEFTRANSMITS -#define EAP_DEFTRANSMITS 10 -#endif -#endif /* PPP_SERVER */ - -/** - * LCP_DEFLOOPBACKFAIL: Default number of times we receive our magic number from the peer - * before deciding the link is looped-back. - */ -#ifndef LCP_DEFLOOPBACKFAIL -#define LCP_DEFLOOPBACKFAIL 10 -#endif - -/** - * LCP_ECHOINTERVAL: Interval in seconds between keepalive echo requests, 0 to disable. - */ -#ifndef LCP_ECHOINTERVAL -#define LCP_ECHOINTERVAL 0 -#endif - -/** - * LCP_MAXECHOFAILS: Number of unanswered echo requests before failure. - */ -#ifndef LCP_MAXECHOFAILS -#define LCP_MAXECHOFAILS 3 -#endif - -/** - * PPP_MAXIDLEFLAG: Max Xmit idle time (in ms) before resend flag char. - */ -#ifndef PPP_MAXIDLEFLAG -#define PPP_MAXIDLEFLAG 100 -#endif - -/** - * PPP Packet sizes - */ - -/** - * PPP_MRU: Default MRU - */ -#ifndef PPP_MRU -#define PPP_MRU 1500 -#endif - -/** - * PPP_DEFMRU: Default MRU to try - */ -#ifndef PPP_DEFMRU -#define PPP_DEFMRU 1500 -#endif - -/** - * PPP_MAXMRU: Normally limit MRU to this (pppd default = 16384) - */ -#ifndef PPP_MAXMRU -#define PPP_MAXMRU 1500 -#endif - -/** - * PPP_MINMRU: No MRUs below this - */ -#ifndef PPP_MINMRU -#define PPP_MINMRU 128 -#endif - -/** - * PPPOL2TP_DEFMRU: Default MTU and MRU for L2TP - * Default = 1500 - PPPoE(6) - PPP Protocol(2) - IPv4 header(20) - UDP Header(8) - * - L2TP Header(6) - HDLC Header(2) - PPP Protocol(2) - MPPE Header(2) - PPP Protocol(2) - */ -#if PPPOL2TP_SUPPORT -#ifndef PPPOL2TP_DEFMRU -#define PPPOL2TP_DEFMRU 1450 -#endif -#endif /* PPPOL2TP_SUPPORT */ - -/** - * MAXNAMELEN: max length of hostname or name for auth - */ -#ifndef MAXNAMELEN -#define MAXNAMELEN 256 -#endif - -/** - * MAXSECRETLEN: max length of password or secret - */ -#ifndef MAXSECRETLEN -#define MAXSECRETLEN 256 -#endif - -/* ------------------------------------------------------------------------- */ - -/* - * Build triggers for embedded PolarSSL - */ -#if !LWIP_USE_EXTERNAL_POLARSSL && !LWIP_USE_EXTERNAL_MBEDTLS - -/* CHAP, EAP, L2TP AUTH and MD5 Random require MD5 support */ -#if CHAP_SUPPORT || EAP_SUPPORT || PPPOL2TP_AUTH_SUPPORT || PPP_MD5_RANDM -#define LWIP_INCLUDED_POLARSSL_MD5 1 -#endif /* CHAP_SUPPORT || EAP_SUPPORT || PPPOL2TP_AUTH_SUPPORT || PPP_MD5_RANDM */ - -#if MSCHAP_SUPPORT - -/* MSCHAP require MD4 support */ -#define LWIP_INCLUDED_POLARSSL_MD4 1 -/* MSCHAP require SHA1 support */ -#define LWIP_INCLUDED_POLARSSL_SHA1 1 -/* MSCHAP require DES support */ -#define LWIP_INCLUDED_POLARSSL_DES 1 - -/* MS-CHAP support is required for MPPE */ -#if MPPE_SUPPORT -/* MPPE require ARC4 support */ -#define LWIP_INCLUDED_POLARSSL_ARC4 1 -#endif /* MPPE_SUPPORT */ - -#endif /* MSCHAP_SUPPORT */ - -#endif /* !LWIP_USE_EXTERNAL_POLARSSL && !LWIP_USE_EXTERNAL_MBEDTLS */ - -/* Default value if unset */ -#ifndef LWIP_INCLUDED_POLARSSL_MD4 -#define LWIP_INCLUDED_POLARSSL_MD4 0 -#endif /* LWIP_INCLUDED_POLARSSL_MD4 */ -#ifndef LWIP_INCLUDED_POLARSSL_MD5 -#define LWIP_INCLUDED_POLARSSL_MD5 0 -#endif /* LWIP_INCLUDED_POLARSSL_MD5 */ -#ifndef LWIP_INCLUDED_POLARSSL_SHA1 -#define LWIP_INCLUDED_POLARSSL_SHA1 0 -#endif /* LWIP_INCLUDED_POLARSSL_SHA1 */ -#ifndef LWIP_INCLUDED_POLARSSL_DES -#define LWIP_INCLUDED_POLARSSL_DES 0 -#endif /* LWIP_INCLUDED_POLARSSL_DES */ -#ifndef LWIP_INCLUDED_POLARSSL_ARC4 -#define LWIP_INCLUDED_POLARSSL_ARC4 0 -#endif /* LWIP_INCLUDED_POLARSSL_ARC4 */ - -#endif /* PPP_SUPPORT */ - -#endif /* LWIP_PPP_OPTS_H */ diff --git a/third_party/lwip/repo/lwip/src/include/netif/ppp/pppapi.h b/third_party/lwip/repo/lwip/src/include/netif/ppp/pppapi.h deleted file mode 100644 index 913d93f749501d..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/netif/ppp/pppapi.h +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - */ - -#ifndef LWIP_PPPAPI_H -#define LWIP_PPPAPI_H - -#include "netif/ppp/ppp_opts.h" - -#if LWIP_PPP_API /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/sys.h" -#include "lwip/netif.h" -#include "lwip/priv/tcpip_priv.h" -#include "netif/ppp/ppp.h" -#if PPPOS_SUPPORT -#include "netif/ppp/pppos.h" -#endif /* PPPOS_SUPPORT */ - -#ifdef __cplusplus -extern "C" { -#endif - -struct pppapi_msg_msg { - ppp_pcb *ppp; - union { -#if PPP_NOTIFY_PHASE - struct { - ppp_notify_phase_cb_fn notify_phase_cb; - } setnotifyphasecb; -#endif /* PPP_NOTIFY_PHASE */ -#if PPPOS_SUPPORT - struct { - struct netif *pppif; - pppos_output_cb_fn output_cb; - ppp_link_status_cb_fn link_status_cb; - void *ctx_cb; - } serialcreate; -#endif /* PPPOS_SUPPORT */ -#if PPPOE_SUPPORT - struct { - struct netif *pppif; - struct netif *ethif; - const char *service_name; - const char *concentrator_name; - ppp_link_status_cb_fn link_status_cb; - void *ctx_cb; - } ethernetcreate; -#endif /* PPPOE_SUPPORT */ -#if PPPOL2TP_SUPPORT - struct { - struct netif *pppif; - struct netif *netif; - API_MSG_M_DEF_C(ip_addr_t, ipaddr); - u16_t port; -#if PPPOL2TP_AUTH_SUPPORT - const u8_t *secret; - u8_t secret_len; -#endif /* PPPOL2TP_AUTH_SUPPORT */ - ppp_link_status_cb_fn link_status_cb; - void *ctx_cb; - } l2tpcreate; -#endif /* PPPOL2TP_SUPPORT */ - struct { - u16_t holdoff; - } connect; - struct { - u8_t nocarrier; - } close; - struct { - u8_t cmd; - void *arg; - } ioctl; - } msg; -}; - -struct pppapi_msg { - struct tcpip_api_call_data call; - struct pppapi_msg_msg msg; -}; - -/* API for application */ -err_t pppapi_set_default(ppp_pcb *pcb); -#if PPP_NOTIFY_PHASE -err_t pppapi_set_notify_phase_callback(ppp_pcb *pcb, ppp_notify_phase_cb_fn notify_phase_cb); -#endif /* PPP_NOTIFY_PHASE */ -#if PPPOS_SUPPORT -ppp_pcb *pppapi_pppos_create(struct netif *pppif, pppos_output_cb_fn output_cb, ppp_link_status_cb_fn link_status_cb, void *ctx_cb); -#endif /* PPPOS_SUPPORT */ -#if PPPOE_SUPPORT -ppp_pcb *pppapi_pppoe_create(struct netif *pppif, struct netif *ethif, const char *service_name, - const char *concentrator_name, ppp_link_status_cb_fn link_status_cb, - void *ctx_cb); -#endif /* PPPOE_SUPPORT */ -#if PPPOL2TP_SUPPORT -ppp_pcb *pppapi_pppol2tp_create(struct netif *pppif, struct netif *netif, ip_addr_t *ipaddr, u16_t port, - const u8_t *secret, u8_t secret_len, - ppp_link_status_cb_fn link_status_cb, void *ctx_cb); -#endif /* PPPOL2TP_SUPPORT */ -err_t pppapi_connect(ppp_pcb *pcb, u16_t holdoff); -#if PPP_SERVER -err_t pppapi_listen(ppp_pcb *pcb); -#endif /* PPP_SERVER */ -err_t pppapi_close(ppp_pcb *pcb, u8_t nocarrier); -err_t pppapi_free(ppp_pcb *pcb); -err_t pppapi_ioctl(ppp_pcb *pcb, u8_t cmd, void *arg); - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_PPP_API */ - -#endif /* LWIP_PPPAPI_H */ diff --git a/third_party/lwip/repo/lwip/src/include/netif/ppp/pppcrypt.h b/third_party/lwip/repo/lwip/src/include/netif/ppp/pppcrypt.h deleted file mode 100644 index a7b2099f25e9b3..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/netif/ppp/pppcrypt.h +++ /dev/null @@ -1,136 +0,0 @@ -/* - * pppcrypt.c - PPP/DES linkage for MS-CHAP and EAP SRP-SHA1 - * - * Extracted from chap_ms.c by James Carlson. - * - * Copyright (c) 1995 Eric Rosenquist. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name(s) of the authors of this software must not be used to - * endorse or promote products derived from this software without - * prior written permission. - * - * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -/* This header file is included in all PPP modules needing hashes and/or ciphers */ - -#ifndef PPPCRYPT_H -#define PPPCRYPT_H - -/* - * If included PolarSSL copy is not used, user is expected to include - * external libraries in arch/cc.h (which is included by lwip/arch.h). - */ -#include "lwip/arch.h" - -/* - * Map hashes and ciphers functions to PolarSSL - */ -#if !LWIP_USE_EXTERNAL_MBEDTLS - -#include "netif/ppp/polarssl/md4.h" -#define lwip_md4_context md4_context -#define lwip_md4_init(context) -#define lwip_md4_starts md4_starts -#define lwip_md4_update md4_update -#define lwip_md4_finish md4_finish -#define lwip_md4_free(context) - -#include "netif/ppp/polarssl/md5.h" -#define lwip_md5_context md5_context -#define lwip_md5_init(context) -#define lwip_md5_starts md5_starts -#define lwip_md5_update md5_update -#define lwip_md5_finish md5_finish -#define lwip_md5_free(context) - -#include "netif/ppp/polarssl/sha1.h" -#define lwip_sha1_context sha1_context -#define lwip_sha1_init(context) -#define lwip_sha1_starts sha1_starts -#define lwip_sha1_update sha1_update -#define lwip_sha1_finish sha1_finish -#define lwip_sha1_free(context) - -#include "netif/ppp/polarssl/des.h" -#define lwip_des_context des_context -#define lwip_des_init(context) -#define lwip_des_setkey_enc des_setkey_enc -#define lwip_des_crypt_ecb des_crypt_ecb -#define lwip_des_free(context) - -#include "netif/ppp/polarssl/arc4.h" -#define lwip_arc4_context arc4_context -#define lwip_arc4_init(context) -#define lwip_arc4_setup arc4_setup -#define lwip_arc4_crypt arc4_crypt -#define lwip_arc4_free(context) - -#endif /* !LWIP_USE_EXTERNAL_MBEDTLS */ - -/* - * Map hashes and ciphers functions to mbed TLS - */ -#if LWIP_USE_EXTERNAL_MBEDTLS - -#define lwip_md4_context mbedtls_md4_context -#define lwip_md4_init mbedtls_md4_init -#define lwip_md4_starts mbedtls_md4_starts -#define lwip_md4_update mbedtls_md4_update -#define lwip_md4_finish mbedtls_md4_finish -#define lwip_md4_free mbedtls_md4_free - -#define lwip_md5_context mbedtls_md5_context -#define lwip_md5_init mbedtls_md5_init -#define lwip_md5_starts mbedtls_md5_starts -#define lwip_md5_update mbedtls_md5_update -#define lwip_md5_finish mbedtls_md5_finish -#define lwip_md5_free mbedtls_md5_free - -#define lwip_sha1_context mbedtls_sha1_context -#define lwip_sha1_init mbedtls_sha1_init -#define lwip_sha1_starts mbedtls_sha1_starts -#define lwip_sha1_update mbedtls_sha1_update -#define lwip_sha1_finish mbedtls_sha1_finish -#define lwip_sha1_free mbedtls_sha1_free - -#define lwip_des_context mbedtls_des_context -#define lwip_des_init mbedtls_des_init -#define lwip_des_setkey_enc mbedtls_des_setkey_enc -#define lwip_des_crypt_ecb mbedtls_des_crypt_ecb -#define lwip_des_free mbedtls_des_free - -#define lwip_arc4_context mbedtls_arc4_context -#define lwip_arc4_init mbedtls_arc4_init -#define lwip_arc4_setup mbedtls_arc4_setup -#define lwip_arc4_crypt(context, buffer, length) mbedtls_arc4_crypt(context, length, buffer, buffer) -#define lwip_arc4_free mbedtls_arc4_free - -#endif /* LWIP_USE_EXTERNAL_MBEDTLS */ - -void pppcrypt_56_to_64_bit_key(u_char *key, u_char *des_key); - -#endif /* PPPCRYPT_H */ - -#endif /* PPP_SUPPORT */ diff --git a/third_party/lwip/repo/lwip/src/include/netif/ppp/pppdebug.h b/third_party/lwip/repo/lwip/src/include/netif/ppp/pppdebug.h deleted file mode 100644 index 7ead0459104454..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/netif/ppp/pppdebug.h +++ /dev/null @@ -1,80 +0,0 @@ -/***************************************************************************** -* pppdebug.h - System debugging utilities. -* -* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. -* portions Copyright (c) 1998 Global Election Systems Inc. -* portions Copyright (c) 2001 by Cognizant Pty Ltd. -* -* The authors hereby grant permission to use, copy, modify, distribute, -* and license this software and its documentation for any purpose, provided -* that existing copyright notices are retained in all copies and that this -* notice and the following disclaimer are included verbatim in any -* distributions. No written agreement, license, or royalty fee is required -* for any of the authorized uses. -* -* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR -* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -****************************************************************************** -* REVISION HISTORY (please don't use tabs!) -* -* 03-01-01 Marc Boucher -* Ported to lwIP. -* 98-07-29 Guy Lancaster , Global Election Systems Inc. -* Original. -* -***************************************************************************** -*/ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#ifndef PPPDEBUG_H -#define PPPDEBUG_H - -/* Trace levels. */ -#define LOG_CRITICAL (PPP_DEBUG | LWIP_DBG_LEVEL_SEVERE) -#define LOG_ERR (PPP_DEBUG | LWIP_DBG_LEVEL_SEVERE) -#define LOG_NOTICE (PPP_DEBUG | LWIP_DBG_LEVEL_WARNING) -#define LOG_WARNING (PPP_DEBUG | LWIP_DBG_LEVEL_WARNING) -#define LOG_INFO (PPP_DEBUG) -#define LOG_DETAIL (PPP_DEBUG) -#define LOG_DEBUG (PPP_DEBUG) - -#if PPP_DEBUG - -#define MAINDEBUG(a) LWIP_DEBUGF(LWIP_DBG_LEVEL_WARNING, a) -#define SYSDEBUG(a) LWIP_DEBUGF(LWIP_DBG_LEVEL_WARNING, a) -#define FSMDEBUG(a) LWIP_DEBUGF(LWIP_DBG_LEVEL_WARNING, a) -#define LCPDEBUG(a) LWIP_DEBUGF(LWIP_DBG_LEVEL_WARNING, a) -#define IPCPDEBUG(a) LWIP_DEBUGF(LWIP_DBG_LEVEL_WARNING, a) -#define IPV6CPDEBUG(a) LWIP_DEBUGF(LWIP_DBG_LEVEL_WARNING, a) -#define UPAPDEBUG(a) LWIP_DEBUGF(LWIP_DBG_LEVEL_WARNING, a) -#define CHAPDEBUG(a) LWIP_DEBUGF(LWIP_DBG_LEVEL_WARNING, a) -#define PPPDEBUG(a, b) LWIP_DEBUGF(a, b) - -#else /* PPP_DEBUG */ - -#define MAINDEBUG(a) -#define SYSDEBUG(a) -#define FSMDEBUG(a) -#define LCPDEBUG(a) -#define IPCPDEBUG(a) -#define IPV6CPDEBUG(a) -#define UPAPDEBUG(a) -#define CHAPDEBUG(a) -#define PPPDEBUG(a, b) - -#endif /* PPP_DEBUG */ - -#endif /* PPPDEBUG_H */ - -#endif /* PPP_SUPPORT */ diff --git a/third_party/lwip/repo/lwip/src/include/netif/ppp/pppoe.h b/third_party/lwip/repo/lwip/src/include/netif/ppp/pppoe.h deleted file mode 100644 index 9f8f2892b4362b..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/netif/ppp/pppoe.h +++ /dev/null @@ -1,179 +0,0 @@ -/***************************************************************************** -* pppoe.h - PPP Over Ethernet implementation for lwIP. -* -* Copyright (c) 2006 by Marc Boucher, Services Informatiques (MBSI) inc. -* -* The authors hereby grant permission to use, copy, modify, distribute, -* and license this software and its documentation for any purpose, provided -* that existing copyright notices are retained in all copies and that this -* notice and the following disclaimer are included verbatim in any -* distributions. No written agreement, license, or royalty fee is required -* for any of the authorized uses. -* -* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR -* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -****************************************************************************** -* REVISION HISTORY -* -* 06-01-01 Marc Boucher -* Ported to lwIP. -*****************************************************************************/ - - - -/* based on NetBSD: if_pppoe.c,v 1.64 2006/01/31 23:50:15 martin Exp */ - -/*- - * Copyright (c) 2002 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Martin Husemann . - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT && PPPOE_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#ifndef PPP_OE_H -#define PPP_OE_H - -#include "ppp.h" -#include "lwip/etharp.h" - -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct pppoehdr { - PACK_STRUCT_FLD_8(u8_t vertype); - PACK_STRUCT_FLD_8(u8_t code); - PACK_STRUCT_FIELD(u16_t session); - PACK_STRUCT_FIELD(u16_t plen); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct pppoetag { - PACK_STRUCT_FIELD(u16_t tag); - PACK_STRUCT_FIELD(u16_t len); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - - -#define PPPOE_STATE_INITIAL 0 -#define PPPOE_STATE_PADI_SENT 1 -#define PPPOE_STATE_PADR_SENT 2 -#define PPPOE_STATE_SESSION 3 -/* passive */ -#define PPPOE_STATE_PADO_SENT 1 - -#define PPPOE_HEADERLEN sizeof(struct pppoehdr) -#define PPPOE_VERTYPE 0x11 /* VER=1, TYPE = 1 */ - -#define PPPOE_TAG_EOL 0x0000 /* end of list */ -#define PPPOE_TAG_SNAME 0x0101 /* service name */ -#define PPPOE_TAG_ACNAME 0x0102 /* access concentrator name */ -#define PPPOE_TAG_HUNIQUE 0x0103 /* host unique */ -#define PPPOE_TAG_ACCOOKIE 0x0104 /* AC cookie */ -#define PPPOE_TAG_VENDOR 0x0105 /* vendor specific */ -#define PPPOE_TAG_RELAYSID 0x0110 /* relay session id */ -#define PPPOE_TAG_SNAME_ERR 0x0201 /* service name error */ -#define PPPOE_TAG_ACSYS_ERR 0x0202 /* AC system error */ -#define PPPOE_TAG_GENERIC_ERR 0x0203 /* gerneric error */ - -#define PPPOE_CODE_PADI 0x09 /* Active Discovery Initiation */ -#define PPPOE_CODE_PADO 0x07 /* Active Discovery Offer */ -#define PPPOE_CODE_PADR 0x19 /* Active Discovery Request */ -#define PPPOE_CODE_PADS 0x65 /* Active Discovery Session confirmation */ -#define PPPOE_CODE_PADT 0xA7 /* Active Discovery Terminate */ - -#ifndef PPPOE_MAX_AC_COOKIE_LEN -#define PPPOE_MAX_AC_COOKIE_LEN 64 -#endif - -struct pppoe_softc { - struct pppoe_softc *next; - struct netif *sc_ethif; /* ethernet interface we are using */ - ppp_pcb *pcb; /* PPP PCB */ - - struct eth_addr sc_dest; /* hardware address of concentrator */ - u16_t sc_session; /* PPPoE session id */ - u8_t sc_state; /* discovery phase or session connected */ - -#ifdef PPPOE_TODO - u8_t *sc_service_name; /* if != NULL: requested name of service */ - u8_t *sc_concentrator_name; /* if != NULL: requested concentrator id */ -#endif /* PPPOE_TODO */ - u8_t sc_ac_cookie[PPPOE_MAX_AC_COOKIE_LEN]; /* content of AC cookie we must echo back */ - u8_t sc_ac_cookie_len; /* length of cookie data */ -#ifdef PPPOE_SERVER - u8_t *sc_hunique; /* content of host unique we must echo back */ - u8_t sc_hunique_len; /* length of host unique */ -#endif - u8_t sc_padi_retried; /* number of PADI retries already done */ - u8_t sc_padr_retried; /* number of PADR retries already done */ -}; - - -#define pppoe_init() /* compatibility define, no initialization needed */ - -ppp_pcb *pppoe_create(struct netif *pppif, - struct netif *ethif, - const char *service_name, const char *concentrator_name, - ppp_link_status_cb_fn link_status_cb, void *ctx_cb); - -/* - * Functions called from lwIP - * DO NOT CALL FROM lwIP USER APPLICATION. - */ -void pppoe_disc_input(struct netif *netif, struct pbuf *p); -void pppoe_data_input(struct netif *netif, struct pbuf *p); - -#endif /* PPP_OE_H */ - -#endif /* PPP_SUPPORT && PPPOE_SUPPORT */ diff --git a/third_party/lwip/repo/lwip/src/include/netif/ppp/pppol2tp.h b/third_party/lwip/repo/lwip/src/include/netif/ppp/pppol2tp.h deleted file mode 100644 index f03950e65dfebb..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/netif/ppp/pppol2tp.h +++ /dev/null @@ -1,201 +0,0 @@ -/** - * @file - * Network Point to Point Protocol over Layer 2 Tunneling Protocol header file. - * - */ - -/* - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT && PPPOL2TP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#ifndef PPPOL2TP_H -#define PPPOL2TP_H - -#include "ppp.h" - -/* Timeout */ -#define PPPOL2TP_CONTROL_TIMEOUT (5*1000) /* base for quick timeout calculation */ -#define PPPOL2TP_SLOW_RETRY (60*1000) /* persistent retry interval */ - -#define PPPOL2TP_MAXSCCRQ 4 /* retry SCCRQ four times (quickly) */ -#define PPPOL2TP_MAXICRQ 4 /* retry IRCQ four times */ -#define PPPOL2TP_MAXICCN 4 /* retry ICCN four times */ - -/* L2TP header flags */ -#define PPPOL2TP_HEADERFLAG_CONTROL 0x8000 -#define PPPOL2TP_HEADERFLAG_LENGTH 0x4000 -#define PPPOL2TP_HEADERFLAG_SEQUENCE 0x0800 -#define PPPOL2TP_HEADERFLAG_OFFSET 0x0200 -#define PPPOL2TP_HEADERFLAG_PRIORITY 0x0100 -#define PPPOL2TP_HEADERFLAG_VERSION 0x0002 - -/* Mandatory bits for control: Control, Length, Sequence, Version 2 */ -#define PPPOL2TP_HEADERFLAG_CONTROL_MANDATORY (PPPOL2TP_HEADERFLAG_CONTROL|PPPOL2TP_HEADERFLAG_LENGTH|PPPOL2TP_HEADERFLAG_SEQUENCE|PPPOL2TP_HEADERFLAG_VERSION) -/* Forbidden bits for control: Offset, Priority */ -#define PPPOL2TP_HEADERFLAG_CONTROL_FORBIDDEN (PPPOL2TP_HEADERFLAG_OFFSET|PPPOL2TP_HEADERFLAG_PRIORITY) - -/* Mandatory bits for data: Version 2 */ -#define PPPOL2TP_HEADERFLAG_DATA_MANDATORY (PPPOL2TP_HEADERFLAG_VERSION) - -/* AVP (Attribute Value Pair) header */ -#define PPPOL2TP_AVPHEADERFLAG_MANDATORY 0x8000 -#define PPPOL2TP_AVPHEADERFLAG_HIDDEN 0x4000 -#define PPPOL2TP_AVPHEADERFLAG_LENGTHMASK 0x03ff - -/* -- AVP - Message type */ -#define PPPOL2TP_AVPTYPE_MESSAGE 0 /* Message type */ - -/* Control Connection Management */ -#define PPPOL2TP_MESSAGETYPE_SCCRQ 1 /* Start Control Connection Request */ -#define PPPOL2TP_MESSAGETYPE_SCCRP 2 /* Start Control Connection Reply */ -#define PPPOL2TP_MESSAGETYPE_SCCCN 3 /* Start Control Connection Connected */ -#define PPPOL2TP_MESSAGETYPE_STOPCCN 4 /* Stop Control Connection Notification */ -#define PPPOL2TP_MESSAGETYPE_HELLO 6 /* Hello */ -/* Call Management */ -#define PPPOL2TP_MESSAGETYPE_OCRQ 7 /* Outgoing Call Request */ -#define PPPOL2TP_MESSAGETYPE_OCRP 8 /* Outgoing Call Reply */ -#define PPPOL2TP_MESSAGETYPE_OCCN 9 /* Outgoing Call Connected */ -#define PPPOL2TP_MESSAGETYPE_ICRQ 10 /* Incoming Call Request */ -#define PPPOL2TP_MESSAGETYPE_ICRP 11 /* Incoming Call Reply */ -#define PPPOL2TP_MESSAGETYPE_ICCN 12 /* Incoming Call Connected */ -#define PPPOL2TP_MESSAGETYPE_CDN 14 /* Call Disconnect Notify */ -/* Error reporting */ -#define PPPOL2TP_MESSAGETYPE_WEN 15 /* WAN Error Notify */ -/* PPP Session Control */ -#define PPPOL2TP_MESSAGETYPE_SLI 16 /* Set Link Info */ - -/* -- AVP - Result code */ -#define PPPOL2TP_AVPTYPE_RESULTCODE 1 /* Result code */ -#define PPPOL2TP_RESULTCODE 1 /* General request to clear control connection */ - -/* -- AVP - Protocol version (!= L2TP Header version) */ -#define PPPOL2TP_AVPTYPE_VERSION 2 -#define PPPOL2TP_VERSION 0x0100 /* L2TP Protocol version 1, revision 0 */ - -/* -- AVP - Framing capabilities */ -#define PPPOL2TP_AVPTYPE_FRAMINGCAPABILITIES 3 /* Bearer capabilities */ -#define PPPOL2TP_FRAMINGCAPABILITIES 0x00000003 /* Async + Sync framing */ - -/* -- AVP - Bearer capabilities */ -#define PPPOL2TP_AVPTYPE_BEARERCAPABILITIES 4 /* Bearer capabilities */ -#define PPPOL2TP_BEARERCAPABILITIES 0x00000003 /* Analog + Digital Access */ - -/* -- AVP - Tie breaker */ -#define PPPOL2TP_AVPTYPE_TIEBREAKER 5 - -/* -- AVP - Host name */ -#define PPPOL2TP_AVPTYPE_HOSTNAME 7 /* Host name */ -#define PPPOL2TP_HOSTNAME "lwIP" /* FIXME: make it configurable */ - -/* -- AVP - Vendor name */ -#define PPPOL2TP_AVPTYPE_VENDORNAME 8 /* Vendor name */ -#define PPPOL2TP_VENDORNAME "lwIP" /* FIXME: make it configurable */ - -/* -- AVP - Assign tunnel ID */ -#define PPPOL2TP_AVPTYPE_TUNNELID 9 /* Assign Tunnel ID */ - -/* -- AVP - Receive window size */ -#define PPPOL2TP_AVPTYPE_RECEIVEWINDOWSIZE 10 /* Receive window size */ -#define PPPOL2TP_RECEIVEWINDOWSIZE 8 /* FIXME: make it configurable */ - -/* -- AVP - Challenge */ -#define PPPOL2TP_AVPTYPE_CHALLENGE 11 /* Challenge */ - -/* -- AVP - Cause code */ -#define PPPOL2TP_AVPTYPE_CAUSECODE 12 /* Cause code*/ - -/* -- AVP - Challenge response */ -#define PPPOL2TP_AVPTYPE_CHALLENGERESPONSE 13 /* Challenge response */ -#define PPPOL2TP_AVPTYPE_CHALLENGERESPONSE_SIZE 16 - -/* -- AVP - Assign session ID */ -#define PPPOL2TP_AVPTYPE_SESSIONID 14 /* Assign Session ID */ - -/* -- AVP - Call serial number */ -#define PPPOL2TP_AVPTYPE_CALLSERIALNUMBER 15 /* Call Serial Number */ - -/* -- AVP - Framing type */ -#define PPPOL2TP_AVPTYPE_FRAMINGTYPE 19 /* Framing Type */ -#define PPPOL2TP_FRAMINGTYPE 0x00000001 /* Sync framing */ - -/* -- AVP - TX Connect Speed */ -#define PPPOL2TP_AVPTYPE_TXCONNECTSPEED 24 /* TX Connect Speed */ -#define PPPOL2TP_TXCONNECTSPEED 100000000 /* Connect speed: 100 Mbits/s */ - -/* L2TP Session state */ -#define PPPOL2TP_STATE_INITIAL 0 -#define PPPOL2TP_STATE_SCCRQ_SENT 1 -#define PPPOL2TP_STATE_ICRQ_SENT 2 -#define PPPOL2TP_STATE_ICCN_SENT 3 -#define PPPOL2TP_STATE_DATA 4 - -#define PPPOL2TP_OUTPUT_DATA_HEADER_LEN 6 /* Our data header len */ - -/* - * PPPoL2TP interface control block. - */ -typedef struct pppol2tp_pcb_s pppol2tp_pcb; -struct pppol2tp_pcb_s { - ppp_pcb *ppp; /* PPP PCB */ - u8_t phase; /* L2TP phase */ - struct udp_pcb *udp; /* UDP L2TP Socket */ - struct netif *netif; /* Output interface, used as a default route */ - ip_addr_t remote_ip; /* LNS IP Address */ - u16_t remote_port; /* LNS port */ -#if PPPOL2TP_AUTH_SUPPORT - const u8_t *secret; /* Secret string */ - u8_t secret_len; /* Secret string length */ - u8_t secret_rv[16]; /* Random vector */ - u8_t challenge_hash[16]; /* Challenge response */ - u8_t send_challenge; /* Boolean whether the next sent packet should contains a challenge response */ -#endif /* PPPOL2TP_AUTH_SUPPORT */ - - u16_t tunnel_port; /* Tunnel port */ - u16_t our_ns; /* NS to peer */ - u16_t peer_nr; /* NR from peer */ - u16_t peer_ns; /* NS from peer */ - u16_t source_tunnel_id; /* Tunnel ID assigned by peer */ - u16_t remote_tunnel_id; /* Tunnel ID assigned to peer */ - u16_t source_session_id; /* Session ID assigned by peer */ - u16_t remote_session_id; /* Session ID assigned to peer */ - - u8_t sccrq_retried; /* number of SCCRQ retries already done */ - u8_t icrq_retried; /* number of ICRQ retries already done */ - u8_t iccn_retried; /* number of ICCN retries already done */ -}; - - -/* Create a new L2TP session. */ -ppp_pcb *pppol2tp_create(struct netif *pppif, - struct netif *netif, const ip_addr_t *ipaddr, u16_t port, - const u8_t *secret, u8_t secret_len, - ppp_link_status_cb_fn link_status_cb, void *ctx_cb); - -#endif /* PPPOL2TP_H */ -#endif /* PPP_SUPPORT && PPPOL2TP_SUPPORT */ diff --git a/third_party/lwip/repo/lwip/src/include/netif/ppp/pppos.h b/third_party/lwip/repo/lwip/src/include/netif/ppp/pppos.h deleted file mode 100644 index d924a9fc7ea917..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/netif/ppp/pppos.h +++ /dev/null @@ -1,118 +0,0 @@ -/** - * @file - * Network Point to Point Protocol over Serial header file. - * - */ - -/* - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT && PPPOS_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#ifndef PPPOS_H -#define PPPOS_H - -#include "lwip/sys.h" - -#include "ppp.h" -#include "vj.h" - -/* PPP packet parser states. Current state indicates operation yet to be - * completed. */ -enum { - PDIDLE = 0, /* Idle state - waiting. */ - PDSTART, /* Process start flag. */ - PDADDRESS, /* Process address field. */ - PDCONTROL, /* Process control field. */ - PDPROTOCOL1, /* Process protocol field 1. */ - PDPROTOCOL2, /* Process protocol field 2. */ - PDDATA /* Process data byte. */ -}; - -/* PPPoS serial output callback function prototype */ -typedef u32_t (*pppos_output_cb_fn)(ppp_pcb *pcb, u8_t *data, u32_t len, void *ctx); - -/* - * Extended asyncmap - allows any character to be escaped. - */ -typedef u8_t ext_accm[32]; - -/* - * PPPoS interface control block. - */ -typedef struct pppos_pcb_s pppos_pcb; -struct pppos_pcb_s { - /* -- below are data that will NOT be cleared between two sessions */ - ppp_pcb *ppp; /* PPP PCB */ - pppos_output_cb_fn output_cb; /* PPP serial output callback */ - - /* -- below are data that will be cleared between two sessions - * - * last_xmit must be the first member of cleared members, because it is - * used to know which part must not be cleared. - */ - u32_t last_xmit; /* Time of last transmission. */ - ext_accm out_accm; /* Async-Ctl-Char-Map for output. */ - - /* flags */ - unsigned int open :1; /* Set if PPPoS is open */ - unsigned int pcomp :1; /* Does peer accept protocol compression? */ - unsigned int accomp :1; /* Does peer accept addr/ctl compression? */ - - /* PPPoS rx */ - ext_accm in_accm; /* Async-Ctl-Char-Map for input. */ - struct pbuf *in_head, *in_tail; /* The input packet. */ - u16_t in_protocol; /* The input protocol code. */ - u16_t in_fcs; /* Input Frame Check Sequence value. */ - u8_t in_state; /* The input process state. */ - u8_t in_escaped; /* Escape next character. */ -}; - -/* Create a new PPPoS session. */ -ppp_pcb *pppos_create(struct netif *pppif, pppos_output_cb_fn output_cb, - ppp_link_status_cb_fn link_status_cb, void *ctx_cb); - -#if !NO_SYS && !PPP_INPROC_IRQ_SAFE -/* Pass received raw characters to PPPoS to be decoded through lwIP TCPIP thread. */ -err_t pppos_input_tcpip(ppp_pcb *ppp, u8_t *s, int l); -#endif /* !NO_SYS && !PPP_INPROC_IRQ_SAFE */ - -/* PPP over Serial: this is the input function to be called for received data. */ -void pppos_input(ppp_pcb *ppp, u8_t* data, int len); - - -/* - * Functions called from lwIP - * DO NOT CALL FROM lwIP USER APPLICATION. - */ -#if !NO_SYS && !PPP_INPROC_IRQ_SAFE -err_t pppos_input_sys(struct pbuf *p, struct netif *inp); -#endif /* !NO_SYS && !PPP_INPROC_IRQ_SAFE */ - -#endif /* PPPOS_H */ -#endif /* PPP_SUPPORT && PPPOL2TP_SUPPORT */ diff --git a/third_party/lwip/repo/lwip/src/include/netif/ppp/upap.h b/third_party/lwip/repo/lwip/src/include/netif/ppp/upap.h deleted file mode 100644 index 7da792ecc7253f..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/netif/ppp/upap.h +++ /dev/null @@ -1,123 +0,0 @@ -/* - * upap.h - User/Password Authentication Protocol definitions. - * - * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name "Carnegie Mellon University" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For permission or any legal - * details, please contact - * Office of Technology Transfer - * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu - * - * 4. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Computing Services - * at Carnegie Mellon University (http://www.cmu.edu/computing/)." - * - * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE - * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * $Id: upap.h,v 1.8 2002/12/04 23:03:33 paulus Exp $ - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT && PAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#ifndef UPAP_H -#define UPAP_H - -#include "ppp.h" - -/* - * Packet header = Code, id, length. - */ -#define UPAP_HEADERLEN 4 - - -/* - * UPAP codes. - */ -#define UPAP_AUTHREQ 1 /* Authenticate-Request */ -#define UPAP_AUTHACK 2 /* Authenticate-Ack */ -#define UPAP_AUTHNAK 3 /* Authenticate-Nak */ - - -/* - * Client states. - */ -#define UPAPCS_INITIAL 0 /* Connection down */ -#define UPAPCS_CLOSED 1 /* Connection up, haven't requested auth */ -#define UPAPCS_PENDING 2 /* Connection down, have requested auth */ -#define UPAPCS_AUTHREQ 3 /* We've sent an Authenticate-Request */ -#define UPAPCS_OPEN 4 /* We've received an Ack */ -#define UPAPCS_BADAUTH 5 /* We've received a Nak */ - -/* - * Server states. - */ -#define UPAPSS_INITIAL 0 /* Connection down */ -#define UPAPSS_CLOSED 1 /* Connection up, haven't requested auth */ -#define UPAPSS_PENDING 2 /* Connection down, have requested auth */ -#define UPAPSS_LISTEN 3 /* Listening for an Authenticate */ -#define UPAPSS_OPEN 4 /* We've sent an Ack */ -#define UPAPSS_BADAUTH 5 /* We've sent a Nak */ - - -/* - * Timeouts. - */ -#if 0 /* moved to ppp_opts.h */ -#define UPAP_DEFTIMEOUT 3 /* Timeout (seconds) for retransmitting req */ -#define UPAP_DEFREQTIME 30 /* Time to wait for auth-req from peer */ -#endif /* moved to ppp_opts.h */ - -/* - * Each interface is described by upap structure. - */ -#if PAP_SUPPORT -typedef struct upap_state { - const char *us_user; /* User */ - u8_t us_userlen; /* User length */ - const char *us_passwd; /* Password */ - u8_t us_passwdlen; /* Password length */ - u8_t us_clientstate; /* Client state */ -#if PPP_SERVER - u8_t us_serverstate; /* Server state */ -#endif /* PPP_SERVER */ - u8_t us_id; /* Current id */ - u8_t us_transmits; /* Number of auth-reqs sent */ -} upap_state; -#endif /* PAP_SUPPORT */ - - -void upap_authwithpeer(ppp_pcb *pcb, const char *user, const char *password); -#if PPP_SERVER -void upap_authpeer(ppp_pcb *pcb); -#endif /* PPP_SERVER */ - -extern const struct protent pap_protent; - -#endif /* UPAP_H */ -#endif /* PPP_SUPPORT && PAP_SUPPORT */ diff --git a/third_party/lwip/repo/lwip/src/include/netif/ppp/vj.h b/third_party/lwip/repo/lwip/src/include/netif/ppp/vj.h deleted file mode 100644 index 7f389c846f7c6e..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/netif/ppp/vj.h +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Definitions for tcp compression routines. - * - * $Id: vj.h,v 1.7 2010/02/22 17:52:09 goldsimon Exp $ - * - * Copyright (c) 1989 Regents of the University of California. - * All rights reserved. - * - * Redistribution and use in source and binary forms are permitted - * provided that the above copyright notice and this paragraph are - * duplicated in all such forms and that any documentation, - * advertising materials, and other materials related to such - * distribution and use acknowledge that the software was developed - * by the University of California, Berkeley. The name of the - * University may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989: - * - Initial distribution. - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT && VJ_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#ifndef VJ_H -#define VJ_H - -#include "lwip/ip.h" -#include "lwip/priv/tcp_priv.h" - -#define MAX_SLOTS 16 /* must be > 2 and < 256 */ -#define MAX_HDR 128 - -/* - * Compressed packet format: - * - * The first octet contains the packet type (top 3 bits), TCP - * 'push' bit, and flags that indicate which of the 4 TCP sequence - * numbers have changed (bottom 5 bits). The next octet is a - * conversation number that associates a saved IP/TCP header with - * the compressed packet. The next two octets are the TCP checksum - * from the original datagram. The next 0 to 15 octets are - * sequence number changes, one change per bit set in the header - * (there may be no changes and there are two special cases where - * the receiver implicitly knows what changed -- see below). - * - * There are 5 numbers which can change (they are always inserted - * in the following order): TCP urgent pointer, window, - * acknowlegement, sequence number and IP ID. (The urgent pointer - * is different from the others in that its value is sent, not the - * change in value.) Since typical use of SLIP links is biased - * toward small packets (see comments on MTU/MSS below), changes - * use a variable length coding with one octet for numbers in the - * range 1 - 255 and 3 octets (0, MSB, LSB) for numbers in the - * range 256 - 65535 or 0. (If the change in sequence number or - * ack is more than 65535, an uncompressed packet is sent.) - */ - -/* - * Packet types (must not conflict with IP protocol version) - * - * The top nibble of the first octet is the packet type. There are - * three possible types: IP (not proto TCP or tcp with one of the - * control flags set); uncompressed TCP (a normal IP/TCP packet but - * with the 8-bit protocol field replaced by an 8-bit connection id -- - * this type of packet syncs the sender & receiver); and compressed - * TCP (described above). - * - * LSB of 4-bit field is TCP "PUSH" bit (a worthless anachronism) and - * is logically part of the 4-bit "changes" field that follows. Top - * three bits are actual packet type. For backward compatibility - * and in the interest of conserving bits, numbers are chosen so the - * IP protocol version number (4) which normally appears in this nibble - * means "IP packet". - */ - -/* packet types */ -#define TYPE_IP 0x40 -#define TYPE_UNCOMPRESSED_TCP 0x70 -#define TYPE_COMPRESSED_TCP 0x80 -#define TYPE_ERROR 0x00 - -/* Bits in first octet of compressed packet */ -#define NEW_C 0x40 /* flag bits for what changed in a packet */ -#define NEW_I 0x20 -#define NEW_S 0x08 -#define NEW_A 0x04 -#define NEW_W 0x02 -#define NEW_U 0x01 - -/* reserved, special-case values of above */ -#define SPECIAL_I (NEW_S|NEW_W|NEW_U) /* echoed interactive traffic */ -#define SPECIAL_D (NEW_S|NEW_A|NEW_W|NEW_U) /* unidirectional data */ -#define SPECIALS_MASK (NEW_S|NEW_A|NEW_W|NEW_U) - -#define TCP_PUSH_BIT 0x10 - - -/* - * "state" data for each active tcp conversation on the wire. This is - * basically a copy of the entire IP/TCP header from the last packet - * we saw from the conversation together with a small identifier - * the transmit & receive ends of the line use to locate saved header. - */ -struct cstate { - struct cstate *cs_next; /* next most recently used state (xmit only) */ - u16_t cs_hlen; /* size of hdr (receive only) */ - u8_t cs_id; /* connection # associated with this state */ - u8_t cs_filler; - union { - char csu_hdr[MAX_HDR]; - struct ip_hdr csu_ip; /* ip/tcp hdr from most recent packet */ - } vjcs_u; -}; -#define cs_ip vjcs_u.csu_ip -#define cs_hdr vjcs_u.csu_hdr - - -struct vjstat { - u32_t vjs_packets; /* outbound packets */ - u32_t vjs_compressed; /* outbound compressed packets */ - u32_t vjs_searches; /* searches for connection state */ - u32_t vjs_misses; /* times couldn't find conn. state */ - u32_t vjs_uncompressedin; /* inbound uncompressed packets */ - u32_t vjs_compressedin; /* inbound compressed packets */ - u32_t vjs_errorin; /* inbound unknown type packets */ - u32_t vjs_tossed; /* inbound packets tossed because of error */ -}; - -/* - * all the state data for one serial line (we need one of these per line). - */ -struct vjcompress { - struct cstate *last_cs; /* most recently used tstate */ - u8_t last_recv; /* last rcvd conn. id */ - u8_t last_xmit; /* last sent conn. id */ - u16_t flags; - u8_t maxSlotIndex; - u8_t compressSlot; /* Flag indicating OK to compress slot ID. */ -#if LINK_STATS - struct vjstat stats; -#endif - struct cstate tstate[MAX_SLOTS]; /* xmit connection states */ - struct cstate rstate[MAX_SLOTS]; /* receive connection states */ -}; - -/* flag values */ -#define VJF_TOSS 1U /* tossing rcvd frames because of input err */ - -extern void vj_compress_init (struct vjcompress *comp); -extern u8_t vj_compress_tcp (struct vjcompress *comp, struct pbuf **pb); -extern void vj_uncompress_err (struct vjcompress *comp); -extern int vj_uncompress_uncomp(struct pbuf *nb, struct vjcompress *comp); -extern int vj_uncompress_tcp (struct pbuf **nb, struct vjcompress *comp); - -#endif /* VJ_H */ - -#endif /* PPP_SUPPORT && VJ_SUPPORT */ diff --git a/third_party/lwip/repo/lwip/src/include/netif/slipif.h b/third_party/lwip/repo/lwip/src/include/netif/slipif.h deleted file mode 100644 index 65ba31f835b577..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/netif/slipif.h +++ /dev/null @@ -1,87 +0,0 @@ -/** - * @file - * - * SLIP netif API - */ - -/* - * Copyright (c) 2001, Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ -#ifndef LWIP_HDR_NETIF_SLIPIF_H -#define LWIP_HDR_NETIF_SLIPIF_H - -#include "lwip/opt.h" -#include "lwip/netif.h" - -/** Set this to 1 to start a thread that blocks reading on the serial line - * (using sio_read()). - */ -#ifndef SLIP_USE_RX_THREAD -#define SLIP_USE_RX_THREAD !NO_SYS -#endif - -/** Set this to 1 to enable functions to pass in RX bytes from ISR context. - * If enabled, slipif_received_byte[s]() process incoming bytes and put assembled - * packets on a queue, which is fed into lwIP from slipif_poll(). - * If disabled, slipif_poll() polls the serial line (using sio_tryread()). - */ -#ifndef SLIP_RX_FROM_ISR -#define SLIP_RX_FROM_ISR 0 -#endif - -/** Set this to 1 (default for SLIP_RX_FROM_ISR) to queue incoming packets - * received by slipif_received_byte[s]() as long as PBUF_POOL pbufs are available. - * If disabled, packets will be dropped if more than one packet is received. - */ -#ifndef SLIP_RX_QUEUE -#define SLIP_RX_QUEUE SLIP_RX_FROM_ISR -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -err_t slipif_init(struct netif * netif); -void slipif_poll(struct netif *netif); -#if SLIP_RX_FROM_ISR -void slipif_process_rxqueue(struct netif *netif); -void slipif_received_byte(struct netif *netif, u8_t data); -void slipif_received_bytes(struct netif *netif, u8_t *data, u8_t len); -#endif /* SLIP_RX_FROM_ISR */ - -#ifdef __cplusplus -} -#endif - -#endif /* LWIP_HDR_NETIF_SLIPIF_H */ - diff --git a/third_party/lwip/repo/lwip/src/include/posix/errno.h b/third_party/lwip/repo/lwip/src/include/posix/errno.h deleted file mode 100644 index 5917c75e24a8e0..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/posix/errno.h +++ /dev/null @@ -1,33 +0,0 @@ -/** - * @file - * This file is a posix wrapper for lwip/errno.h. - */ - -/* - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - */ - -#include "lwip/errno.h" diff --git a/third_party/lwip/repo/lwip/src/include/posix/net/if.h b/third_party/lwip/repo/lwip/src/include/posix/net/if.h deleted file mode 100644 index cf7df7ed92c9b1..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/posix/net/if.h +++ /dev/null @@ -1,33 +0,0 @@ -/** - * @file - * This file is a posix wrapper for lwip/if.h. - */ - -/* - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - */ - -#include "lwip/if.h" diff --git a/third_party/lwip/repo/lwip/src/include/posix/netdb.h b/third_party/lwip/repo/lwip/src/include/posix/netdb.h deleted file mode 100644 index 12d4c7f566c77f..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/posix/netdb.h +++ /dev/null @@ -1,33 +0,0 @@ -/** - * @file - * This file is a posix wrapper for lwip/netdb.h. - */ - -/* - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - */ - -#include "lwip/netdb.h" diff --git a/third_party/lwip/repo/lwip/src/include/posix/sys/socket.h b/third_party/lwip/repo/lwip/src/include/posix/sys/socket.h deleted file mode 100644 index 0ed9baf3d9f2e5..00000000000000 --- a/third_party/lwip/repo/lwip/src/include/posix/sys/socket.h +++ /dev/null @@ -1,33 +0,0 @@ -/** - * @file - * This file is a posix wrapper for lwip/sockets.h. - */ - -/* - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - */ - -#include "lwip/sockets.h" diff --git a/third_party/lwip/repo/lwip/src/netif/FILES b/third_party/lwip/repo/lwip/src/netif/FILES deleted file mode 100644 index a3ff431d4252ee..00000000000000 --- a/third_party/lwip/repo/lwip/src/netif/FILES +++ /dev/null @@ -1,24 +0,0 @@ -This directory contains generic network interface device drivers that -do not contain any hardware or architecture specific code. The files -are: - -ethernet.c - Shared code for Ethernet based interfaces. - -ethernetif.c - An example of how an Ethernet device driver could look. This - file can be used as a "skeleton" for developing new Ethernet - network device drivers. It uses the etharp.c ARP code. - -lowpan6.c - A 6LoWPAN implementation as a netif. - -slipif.c - A generic implementation of the SLIP (Serial Line IP) - protocol. It requires a sio (serial I/O) module to work. - -ppp/ Point-to-Point Protocol stack - The lwIP PPP support is based from pppd (http://ppp.samba.org) with - huge changes to match code size and memory requirements for embedded - devices. Please read /doc/ppp.txt and ppp/PPPD_FOLLOWUP for a detailed - explanation. diff --git a/third_party/lwip/repo/lwip/src/netif/ethernet.c b/third_party/lwip/repo/lwip/src/netif/ethernet.c deleted file mode 100644 index 52ea4236d5d100..00000000000000 --- a/third_party/lwip/repo/lwip/src/netif/ethernet.c +++ /dev/null @@ -1,314 +0,0 @@ -/** - * @file - * Ethernet common functions - * - * @defgroup ethernet Ethernet - * @ingroup callbackstyle_api - */ - -/* - * Copyright (c) 2001-2003 Swedish Institute of Computer Science. - * Copyright (c) 2003-2004 Leon Woestenberg - * Copyright (c) 2003-2004 Axon Digital Design B.V., The Netherlands. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - */ - -#include "lwip/opt.h" - -#if LWIP_ARP || LWIP_ETHERNET - -#include "netif/ethernet.h" -#include "lwip/def.h" -#include "lwip/stats.h" -#include "lwip/etharp.h" -#include "lwip/ip.h" -#include "lwip/snmp.h" - -#include - -#include "netif/ppp/ppp_opts.h" -#if PPPOE_SUPPORT -#include "netif/ppp/pppoe.h" -#endif /* PPPOE_SUPPORT */ - -#ifdef LWIP_HOOK_FILENAME -#include LWIP_HOOK_FILENAME -#endif - -const struct eth_addr ethbroadcast = {{0xff,0xff,0xff,0xff,0xff,0xff}}; -const struct eth_addr ethzero = {{0,0,0,0,0,0}}; - -/** - * @ingroup lwip_nosys - * Process received ethernet frames. Using this function instead of directly - * calling ip_input and passing ARP frames through etharp in ethernetif_input, - * the ARP cache is protected from concurrent access.\n - * Don't call directly, pass to netif_add() and call netif->input(). - * - * @param p the received packet, p->payload pointing to the ethernet header - * @param netif the network interface on which the packet was received - * - * @see LWIP_HOOK_UNKNOWN_ETH_PROTOCOL - * @see ETHARP_SUPPORT_VLAN - * @see LWIP_HOOK_VLAN_CHECK - */ -err_t -ethernet_input(struct pbuf *p, struct netif *netif) -{ - struct eth_hdr* ethhdr; - u16_t type; -#if LWIP_ARP || ETHARP_SUPPORT_VLAN || LWIP_IPV6 - s16_t ip_hdr_offset = SIZEOF_ETH_HDR; -#endif /* LWIP_ARP || ETHARP_SUPPORT_VLAN */ - - if (p->len <= SIZEOF_ETH_HDR) { - /* a packet with only an ethernet header (or less) is not valid for us */ - ETHARP_STATS_INC(etharp.proterr); - ETHARP_STATS_INC(etharp.drop); - MIB2_STATS_NETIF_INC(netif, ifinerrors); - goto free_and_return; - } - - /* points to packet payload, which starts with an Ethernet header */ - ethhdr = (struct eth_hdr *)p->payload; - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, - ("ethernet_input: dest:%"X8_F":%"X8_F":%"X8_F":%"X8_F":%"X8_F":%"X8_F", src:%"X8_F":%"X8_F":%"X8_F":%"X8_F":%"X8_F":%"X8_F", type:%"X16_F"\n", - (unsigned)ethhdr->dest.addr[0], (unsigned)ethhdr->dest.addr[1], (unsigned)ethhdr->dest.addr[2], - (unsigned)ethhdr->dest.addr[3], (unsigned)ethhdr->dest.addr[4], (unsigned)ethhdr->dest.addr[5], - (unsigned)ethhdr->src.addr[0], (unsigned)ethhdr->src.addr[1], (unsigned)ethhdr->src.addr[2], - (unsigned)ethhdr->src.addr[3], (unsigned)ethhdr->src.addr[4], (unsigned)ethhdr->src.addr[5], - lwip_htons(ethhdr->type))); - - type = ethhdr->type; -#if ETHARP_SUPPORT_VLAN - if (type == PP_HTONS(ETHTYPE_VLAN)) { - struct eth_vlan_hdr *vlan = (struct eth_vlan_hdr*)(((char*)ethhdr) + SIZEOF_ETH_HDR); - if (p->len <= SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR) { - /* a packet with only an ethernet/vlan header (or less) is not valid for us */ - ETHARP_STATS_INC(etharp.proterr); - ETHARP_STATS_INC(etharp.drop); - MIB2_STATS_NETIF_INC(netif, ifinerrors); - goto free_and_return; - } -#if defined(LWIP_HOOK_VLAN_CHECK) || defined(ETHARP_VLAN_CHECK) || defined(ETHARP_VLAN_CHECK_FN) /* if not, allow all VLANs */ -#ifdef LWIP_HOOK_VLAN_CHECK - if (!LWIP_HOOK_VLAN_CHECK(netif, ethhdr, vlan)) { -#elif defined(ETHARP_VLAN_CHECK_FN) - if (!ETHARP_VLAN_CHECK_FN(ethhdr, vlan)) { -#elif defined(ETHARP_VLAN_CHECK) - if (VLAN_ID(vlan) != ETHARP_VLAN_CHECK) { -#endif - /* silently ignore this packet: not for our VLAN */ - pbuf_free(p); - return ERR_OK; - } -#endif /* defined(LWIP_HOOK_VLAN_CHECK) || defined(ETHARP_VLAN_CHECK) || defined(ETHARP_VLAN_CHECK_FN) */ - type = vlan->tpid; - ip_hdr_offset = SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR; - } -#endif /* ETHARP_SUPPORT_VLAN */ - -#if LWIP_ARP_FILTER_NETIF - netif = LWIP_ARP_FILTER_NETIF_FN(p, netif, lwip_htons(type)); -#endif /* LWIP_ARP_FILTER_NETIF*/ - - if (ethhdr->dest.addr[0] & 1) { - /* this might be a multicast or broadcast packet */ - if (ethhdr->dest.addr[0] == LL_IP4_MULTICAST_ADDR_0) { -#if LWIP_IPV4 - if ((ethhdr->dest.addr[1] == LL_IP4_MULTICAST_ADDR_1) && - (ethhdr->dest.addr[2] == LL_IP4_MULTICAST_ADDR_2)) { - /* mark the pbuf as link-layer multicast */ - p->flags |= PBUF_FLAG_LLMCAST; - } -#endif /* LWIP_IPV4 */ - } -#if LWIP_IPV6 - else if ((ethhdr->dest.addr[0] == LL_IP6_MULTICAST_ADDR_0) && - (ethhdr->dest.addr[1] == LL_IP6_MULTICAST_ADDR_1)) { - /* mark the pbuf as link-layer multicast */ - p->flags |= PBUF_FLAG_LLMCAST; - } -#endif /* LWIP_IPV6 */ - else if (eth_addr_cmp(ðhdr->dest, ðbroadcast)) { - /* mark the pbuf as link-layer broadcast */ - p->flags |= PBUF_FLAG_LLBCAST; - } - } - - switch (type) { -#if LWIP_IPV4 && LWIP_ARP - /* IP packet? */ - case PP_HTONS(ETHTYPE_IP): - if (!(netif->flags & NETIF_FLAG_ETHARP)) { - goto free_and_return; - } - /* skip Ethernet header */ - if ((p->len < ip_hdr_offset) || pbuf_header(p, (s16_t)-ip_hdr_offset)) { - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, - ("ethernet_input: IPv4 packet dropped, too short (%"S16_F"/%"S16_F")\n", - p->tot_len, ip_hdr_offset)); - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("Can't move over header in packet")); - goto free_and_return; - } else { - /* pass to IP layer */ - ip4_input(p, netif); - } - break; - - case PP_HTONS(ETHTYPE_ARP): - if (!(netif->flags & NETIF_FLAG_ETHARP)) { - goto free_and_return; - } - /* skip Ethernet header */ - if ((p->len < ip_hdr_offset) || pbuf_header(p, (s16_t)-ip_hdr_offset)) { - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, - ("ethernet_input: ARP response packet dropped, too short (%"S16_F"/%"S16_F")\n", - p->tot_len, ip_hdr_offset)); - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("Can't move over header in packet")); - ETHARP_STATS_INC(etharp.lenerr); - ETHARP_STATS_INC(etharp.drop); - goto free_and_return; - } else { - /* pass p to ARP module */ - etharp_input(p, netif); - } - break; -#endif /* LWIP_IPV4 && LWIP_ARP */ -#if PPPOE_SUPPORT - case PP_HTONS(ETHTYPE_PPPOEDISC): /* PPP Over Ethernet Discovery Stage */ - pppoe_disc_input(netif, p); - break; - - case PP_HTONS(ETHTYPE_PPPOE): /* PPP Over Ethernet Session Stage */ - pppoe_data_input(netif, p); - break; -#endif /* PPPOE_SUPPORT */ - -#if LWIP_IPV6 - case PP_HTONS(ETHTYPE_IPV6): /* IPv6 */ - /* skip Ethernet header */ - if ((p->len < ip_hdr_offset) || pbuf_header(p, (s16_t)-ip_hdr_offset)) { - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, - ("ethernet_input: IPv6 packet dropped, too short (%"S16_F"/%"S16_F")\n", - p->tot_len, ip_hdr_offset)); - goto free_and_return; - } else { - /* pass to IPv6 layer */ - ip6_input(p, netif); - } - break; -#endif /* LWIP_IPV6 */ - - default: -#ifdef LWIP_HOOK_UNKNOWN_ETH_PROTOCOL - if(LWIP_HOOK_UNKNOWN_ETH_PROTOCOL(p, netif) == ERR_OK) { - break; - } -#endif - ETHARP_STATS_INC(etharp.proterr); - ETHARP_STATS_INC(etharp.drop); - MIB2_STATS_NETIF_INC(netif, ifinunknownprotos); - goto free_and_return; - } - - /* This means the pbuf is freed or consumed, - so the caller doesn't have to free it again */ - return ERR_OK; - -free_and_return: - pbuf_free(p); - return ERR_OK; -} - -/** - * @ingroup ethernet - * Send an ethernet packet on the network using netif->linkoutput(). - * The ethernet header is filled in before sending. - * - * @see LWIP_HOOK_VLAN_SET - * - * @param netif the lwIP network interface on which to send the packet - * @param p the packet to send. pbuf layer must be @ref PBUF_LINK. - * @param src the source MAC address to be copied into the ethernet header - * @param dst the destination MAC address to be copied into the ethernet header - * @param eth_type ethernet type (@ref eth_type) - * @return ERR_OK if the packet was sent, any other err_t on failure - */ -err_t -ethernet_output(struct netif* netif, struct pbuf* p, - const struct eth_addr* src, const struct eth_addr* dst, - u16_t eth_type) -{ - struct eth_hdr* ethhdr; - u16_t eth_type_be = lwip_htons(eth_type); - -#if ETHARP_SUPPORT_VLAN && defined(LWIP_HOOK_VLAN_SET) - s32_t vlan_prio_vid = LWIP_HOOK_VLAN_SET(netif, p, src, dst, eth_type); - if (vlan_prio_vid >= 0) { - struct eth_vlan_hdr* vlanhdr; - - LWIP_ASSERT("prio_vid must be <= 0xFFFF", vlan_prio_vid <= 0xFFFF); - - if (pbuf_header(p, SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR) != 0) { - goto pbuf_header_failed; - } - vlanhdr = (struct eth_vlan_hdr*)(((u8_t*)p->payload) + SIZEOF_ETH_HDR); - vlanhdr->tpid = eth_type_be; - vlanhdr->prio_vid = lwip_htons((u16_t)vlan_prio_vid); - - eth_type_be = PP_HTONS(ETHTYPE_VLAN); - } else -#endif /* ETHARP_SUPPORT_VLAN && defined(LWIP_HOOK_VLAN_SET) */ - { - if (pbuf_header(p, SIZEOF_ETH_HDR) != 0) { - goto pbuf_header_failed; - } - } - - ethhdr = (struct eth_hdr*)p->payload; - ethhdr->type = eth_type_be; - ETHADDR32_COPY(ðhdr->dest, dst); - ETHADDR16_COPY(ðhdr->src, src); - - LWIP_ASSERT("netif->hwaddr_len must be 6 for ethernet_output!", - (netif->hwaddr_len == ETH_HWADDR_LEN)); - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, - ("ethernet_output: sending packet %p\n", (void *)p)); - - /* send the packet */ - return netif->linkoutput(netif, p); - -pbuf_header_failed: - LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS, - ("ethernet_output: could not allocate room for header.\n")); - LINK_STATS_INC(link.lenerr); - return ERR_BUF; -} - -#endif /* LWIP_ARP || LWIP_ETHERNET */ diff --git a/third_party/lwip/repo/lwip/src/netif/ethernetif.c b/third_party/lwip/repo/lwip/src/netif/ethernetif.c deleted file mode 100644 index dc8ae6c42aa0fd..00000000000000 --- a/third_party/lwip/repo/lwip/src/netif/ethernetif.c +++ /dev/null @@ -1,335 +0,0 @@ -/** - * @file - * Ethernet Interface Skeleton - * - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Adam Dunkels - * - */ - -/* - * This file is a skeleton for developing Ethernet network interface - * drivers for lwIP. Add code to the low_level functions and do a - * search-and-replace for the word "ethernetif" to replace it with - * something that better describes your network interface. - */ - -#include "lwip/opt.h" - -#if 0 /* don't build, this is only a skeleton, see previous comment */ - -#include "lwip/def.h" -#include "lwip/mem.h" -#include "lwip/pbuf.h" -#include "lwip/stats.h" -#include "lwip/snmp.h" -#include "lwip/ethip6.h" -#include "lwip/etharp.h" -#include "netif/ppp/pppoe.h" - -/* Define those to better describe your network interface. */ -#define IFNAME0 'e' -#define IFNAME1 'n' - -/** - * Helper struct to hold private data used to operate your ethernet interface. - * Keeping the ethernet address of the MAC in this struct is not necessary - * as it is already kept in the struct netif. - * But this is only an example, anyway... - */ -struct ethernetif { - struct eth_addr *ethaddr; - /* Add whatever per-interface state that is needed here. */ -}; - -/* Forward declarations. */ -static void ethernetif_input(struct netif *netif); - -/** - * In this function, the hardware should be initialized. - * Called from ethernetif_init(). - * - * @param netif the already initialized lwip network interface structure - * for this ethernetif - */ -static void -low_level_init(struct netif *netif) -{ - struct ethernetif *ethernetif = netif->state; - - /* set MAC hardware address length */ - netif->hwaddr_len = ETHARP_HWADDR_LEN; - - /* set MAC hardware address */ - netif->hwaddr[0] = ; - ... - netif->hwaddr[5] = ; - - /* maximum transfer unit */ - netif->mtu = 1500; - - /* device capabilities */ - /* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */ - netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP; - -#if LWIP_IPV6 && LWIP_IPV6_MLD - /* - * For hardware/netifs that implement MAC filtering. - * All-nodes link-local is handled by default, so we must let the hardware know - * to allow multicast packets in. - * Should set mld_mac_filter previously. */ - if (netif->mld_mac_filter != NULL) { - ip6_addr_t ip6_allnodes_ll; - ip6_addr_set_allnodes_linklocal(&ip6_allnodes_ll); - netif->mld_mac_filter(netif, &ip6_allnodes_ll, NETIF_ADD_MAC_FILTER); - } -#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */ - - /* Do whatever else is needed to initialize interface. */ -} - -/** - * This function should do the actual transmission of the packet. The packet is - * contained in the pbuf that is passed to the function. This pbuf - * might be chained. - * - * @param netif the lwip network interface structure for this ethernetif - * @param p the MAC packet to send (e.g. IP packet including MAC addresses and type) - * @return ERR_OK if the packet could be sent - * an err_t value if the packet couldn't be sent - * - * @note Returning ERR_MEM here if a DMA queue of your MAC is full can lead to - * strange results. You might consider waiting for space in the DMA queue - * to become available since the stack doesn't retry to send a packet - * dropped because of memory failure (except for the TCP timers). - */ - -static err_t -low_level_output(struct netif *netif, struct pbuf *p) -{ - struct ethernetif *ethernetif = netif->state; - struct pbuf *q; - - initiate transfer(); - -#if ETH_PAD_SIZE - pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */ -#endif - - for (q = p; q != NULL; q = q->next) { - /* Send the data from the pbuf to the interface, one pbuf at a - time. The size of the data in each pbuf is kept in the ->len - variable. */ - send data from(q->payload, q->len); - } - - signal that packet should be sent(); - - MIB2_STATS_NETIF_ADD(netif, ifoutoctets, p->tot_len); - if (((u8_t*)p->payload)[0] & 1) { - /* broadcast or multicast packet*/ - MIB2_STATS_NETIF_INC(netif, ifoutnucastpkts); - } else { - /* unicast packet */ - MIB2_STATS_NETIF_INC(netif, ifoutucastpkts); - } - /* increase ifoutdiscards or ifouterrors on error */ - -#if ETH_PAD_SIZE - pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */ -#endif - - LINK_STATS_INC(link.xmit); - - return ERR_OK; -} - -/** - * Should allocate a pbuf and transfer the bytes of the incoming - * packet from the interface into the pbuf. - * - * @param netif the lwip network interface structure for this ethernetif - * @return a pbuf filled with the received packet (including MAC header) - * NULL on memory error - */ -static struct pbuf * -low_level_input(struct netif *netif) -{ - struct ethernetif *ethernetif = netif->state; - struct pbuf *p, *q; - u16_t len; - - /* Obtain the size of the packet and put it into the "len" - variable. */ - len = ; - -#if ETH_PAD_SIZE - len += ETH_PAD_SIZE; /* allow room for Ethernet padding */ -#endif - - /* We allocate a pbuf chain of pbufs from the pool. */ - p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL); - - if (p != NULL) { - -#if ETH_PAD_SIZE - pbuf_header(p, -ETH_PAD_SIZE); /* drop the padding word */ -#endif - - /* We iterate over the pbuf chain until we have read the entire - * packet into the pbuf. */ - for (q = p; q != NULL; q = q->next) { - /* Read enough bytes to fill this pbuf in the chain. The - * available data in the pbuf is given by the q->len - * variable. - * This does not necessarily have to be a memcpy, you can also preallocate - * pbufs for a DMA-enabled MAC and after receiving truncate it to the - * actually received size. In this case, ensure the tot_len member of the - * pbuf is the sum of the chained pbuf len members. - */ - read data into(q->payload, q->len); - } - acknowledge that packet has been read(); - - MIB2_STATS_NETIF_ADD(netif, ifinoctets, p->tot_len); - if (((u8_t*)p->payload)[0] & 1) { - /* broadcast or multicast packet*/ - MIB2_STATS_NETIF_INC(netif, ifinnucastpkts); - } else { - /* unicast packet*/ - MIB2_STATS_NETIF_INC(netif, ifinucastpkts); - } -#if ETH_PAD_SIZE - pbuf_header(p, ETH_PAD_SIZE); /* reclaim the padding word */ -#endif - - LINK_STATS_INC(link.recv); - } else { - drop packet(); - LINK_STATS_INC(link.memerr); - LINK_STATS_INC(link.drop); - MIB2_STATS_NETIF_INC(netif, ifindiscards); - } - - return p; -} - -/** - * This function should be called when a packet is ready to be read - * from the interface. It uses the function low_level_input() that - * should handle the actual reception of bytes from the network - * interface. Then the type of the received packet is determined and - * the appropriate input function is called. - * - * @param netif the lwip network interface structure for this ethernetif - */ -static void -ethernetif_input(struct netif *netif) -{ - struct ethernetif *ethernetif; - struct eth_hdr *ethhdr; - struct pbuf *p; - - ethernetif = netif->state; - - /* move received packet into a new pbuf */ - p = low_level_input(netif); - /* if no packet could be read, silently ignore this */ - if (p != NULL) { - /* pass all packets to ethernet_input, which decides what packets it supports */ - if (netif->input(p, netif) != ERR_OK) { - LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n")); - pbuf_free(p); - p = NULL; - } - } -} - -/** - * Should be called at the beginning of the program to set up the - * network interface. It calls the function low_level_init() to do the - * actual setup of the hardware. - * - * This function should be passed as a parameter to netif_add(). - * - * @param netif the lwip network interface structure for this ethernetif - * @return ERR_OK if the loopif is initialized - * ERR_MEM if private data couldn't be allocated - * any other err_t on error - */ -err_t -ethernetif_init(struct netif *netif) -{ - struct ethernetif *ethernetif; - - LWIP_ASSERT("netif != NULL", (netif != NULL)); - - ethernetif = mem_malloc(sizeof(struct ethernetif)); - if (ethernetif == NULL) { - LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_init: out of memory\n")); - return ERR_MEM; - } - -#if LWIP_NETIF_HOSTNAME - /* Initialize interface hostname */ - netif->hostname = "lwip"; -#endif /* LWIP_NETIF_HOSTNAME */ - - /* - * Initialize the snmp variables and counters inside the struct netif. - * The last argument should be replaced with your link speed, in units - * of bits per second. - */ - MIB2_INIT_NETIF(netif, snmp_ifType_ethernet_csmacd, LINK_SPEED_OF_YOUR_NETIF_IN_BPS); - - netif->state = ethernetif; - netif->name[0] = IFNAME0; - netif->name[1] = IFNAME1; - /* We directly use etharp_output() here to save a function call. - * You can instead declare your own function an call etharp_output() - * from it if you have to do some checks before sending (e.g. if link - * is available...) */ - netif->output = etharp_output; -#if LWIP_IPV6 - netif->output_ip6 = ethip6_output; -#endif /* LWIP_IPV6 */ - netif->linkoutput = low_level_output; - - ethernetif->ethaddr = (struct eth_addr *)&(netif->hwaddr[0]); - - /* initialize the hardware */ - low_level_init(netif); - - return ERR_OK; -} - -#endif /* 0 */ diff --git a/third_party/lwip/repo/lwip/src/netif/lowpan6.c b/third_party/lwip/repo/lwip/src/netif/lowpan6.c deleted file mode 100644 index 9a84cbccc785b5..00000000000000 --- a/third_party/lwip/repo/lwip/src/netif/lowpan6.c +++ /dev/null @@ -1,1193 +0,0 @@ -/** - * @file - * - * 6LowPAN output for IPv6. Uses ND tables for link-layer addressing. Fragments packets to 6LowPAN units. - */ - -/* - * Copyright (c) 2015 Inico Technologies Ltd. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - * Author: Ivan Delamer - * - * - * Please coordinate changes and requests with Ivan Delamer - * - */ - -/** - * @defgroup sixlowpan 6LowPAN netif - * @ingroup addons - * 6LowPAN netif implementation - */ - -#include "netif/lowpan6.h" - -#if LWIP_IPV6 && LWIP_6LOWPAN - -#include "lwip/ip.h" -#include "lwip/pbuf.h" -#include "lwip/ip_addr.h" -#include "lwip/netif.h" -#include "lwip/nd6.h" -#include "lwip/mem.h" -#include "lwip/udp.h" -#include "lwip/tcpip.h" -#include "lwip/snmp.h" - -#include - -struct ieee_802154_addr { - u8_t addr_len; - u8_t addr[8]; -}; - -/** This is a helper struct. - */ -struct lowpan6_reass_helper { - struct pbuf *pbuf; - struct lowpan6_reass_helper *next_packet; - u8_t timer; - struct ieee_802154_addr sender_addr; - u16_t datagram_size; - u16_t datagram_tag; -}; - -static struct lowpan6_reass_helper * reass_list; - -#if LWIP_6LOWPAN_NUM_CONTEXTS > 0 -static ip6_addr_t lowpan6_context[LWIP_6LOWPAN_NUM_CONTEXTS]; -#endif - -static u16_t ieee_802154_pan_id; - -static const struct ieee_802154_addr ieee_802154_broadcast = {2, {0xff, 0xff}}; - -#if LWIP_6LOWPAN_INFER_SHORT_ADDRESS -static struct ieee_802154_addr short_mac_addr = {2, {0,0}}; -#endif /* LWIP_6LOWPAN_INFER_SHORT_ADDRESS */ - -static err_t dequeue_datagram(struct lowpan6_reass_helper *lrh); - -/** - * Periodic timer for 6LowPAN functions: - * - * - Remove incomplete/old packets - */ -void -lowpan6_tmr(void) -{ - struct lowpan6_reass_helper *lrh, *lrh_temp; - - lrh = reass_list; - while (lrh != NULL) { - lrh_temp = lrh->next_packet; - if ((--lrh->timer) == 0) { - dequeue_datagram(lrh); - pbuf_free(lrh->pbuf); - mem_free(lrh); - } - lrh = lrh_temp; - } -} - -/** - * Removes a datagram from the reassembly queue. - **/ -static err_t -dequeue_datagram(struct lowpan6_reass_helper *lrh) -{ - struct lowpan6_reass_helper *lrh_temp; - - if (reass_list == lrh) { - reass_list = reass_list->next_packet; - } else { - lrh_temp = reass_list; - while (lrh_temp != NULL) { - if (lrh_temp->next_packet == lrh) { - lrh_temp->next_packet = lrh->next_packet; - break; - } - lrh_temp = lrh_temp->next_packet; - } - } - - return ERR_OK; -} - -static s8_t -lowpan6_context_lookup(const ip6_addr_t *ip6addr) -{ - s8_t i; - - for (i = 0; i < LWIP_6LOWPAN_NUM_CONTEXTS; i++) { - if (ip6_addr_netcmp(&lowpan6_context[i], ip6addr)) { - return i; - } - } - - return -1; -} - -/* Determine compression mode for unicast address. */ -static s8_t -lowpan6_get_address_mode(const ip6_addr_t *ip6addr, const struct ieee_802154_addr *mac_addr) -{ - if (mac_addr->addr_len == 2) { - if ((ip6addr->addr[2] == (u32_t)PP_HTONL(0x000000ff)) && - ((ip6addr->addr[3] & PP_HTONL(0xffff0000)) == PP_NTOHL(0xfe000000))) { - if ((ip6addr->addr[3] & PP_HTONL(0x0000ffff)) == lwip_ntohl((mac_addr->addr[0] << 8) | mac_addr->addr[1])) { - return 3; - } - } - } else if (mac_addr->addr_len == 8) { - if ((ip6addr->addr[2] == lwip_ntohl(((mac_addr->addr[0] ^ 2) << 24) | (mac_addr->addr[1] << 16) | mac_addr->addr[2] << 8 | mac_addr->addr[3])) && - (ip6addr->addr[3] == lwip_ntohl((mac_addr->addr[4] << 24) | (mac_addr->addr[5] << 16) | mac_addr->addr[6] << 8 | mac_addr->addr[7]))) { - return 3; - } - } - - if ((ip6addr->addr[2] == PP_HTONL(0x000000ffUL)) && - ((ip6addr->addr[3] & PP_HTONL(0xffff0000)) == PP_NTOHL(0xfe000000UL))) { - return 2; - } - - return 1; -} - -/* Determine compression mode for multicast address. */ -static s8_t -lowpan6_get_address_mode_mc(const ip6_addr_t *ip6addr) -{ - if ((ip6addr->addr[0] == PP_HTONL(0xff020000)) && - (ip6addr->addr[1] == 0) && - (ip6addr->addr[2] == 0) && - ((ip6addr->addr[3] & PP_HTONL(0xffffff00)) == 0)) { - return 3; - } else if (((ip6addr->addr[0] & PP_HTONL(0xff00ffff)) == PP_HTONL(0xff000000)) && - (ip6addr->addr[1] == 0)) { - if ((ip6addr->addr[2] == 0) && - ((ip6addr->addr[3] & PP_HTONL(0xff000000)) == 0)) { - return 2; - } else if ((ip6addr->addr[2] & PP_HTONL(0xffffff00)) == 0) { - return 1; - } - } - - return 0; -} - -/* - * Encapsulates data into IEEE 802.15.4 frames. - * Fragments an IPv6 datagram into 6LowPAN units, which fit into IEEE 802.15.4 frames. - * If configured, will compress IPv6 and or UDP headers. - * */ -static err_t -lowpan6_frag(struct netif *netif, struct pbuf *p, const struct ieee_802154_addr *src, const struct ieee_802154_addr *dst) -{ - struct pbuf * p_frag; - u16_t frag_len, remaining_len; - u8_t * buffer; - u8_t ieee_header_len; - u8_t lowpan6_header_len; - s8_t i; - static u8_t frame_seq_num; - static u16_t datagram_tag; - u16_t datagram_offset; - err_t err = ERR_IF; - - /* We'll use a dedicated pbuf for building 6LowPAN fragments. */ - p_frag = pbuf_alloc(PBUF_RAW, 127, PBUF_RAM); - if (p_frag == NULL) { - MIB2_STATS_NETIF_INC(netif, ifoutdiscards); - return ERR_MEM; - } - - /* Write IEEE 802.15.4 header. */ - buffer = (u8_t*)p_frag->payload; - ieee_header_len = 0; - if (dst == &ieee_802154_broadcast) { - buffer[ieee_header_len++] = 0x01; /* data packet, no ack required. */ - } else { - buffer[ieee_header_len++] = 0x21; /* data packet, ack required. */ - } - buffer[ieee_header_len] = (0x00 << 4); /* 2003 frame version */ - buffer[ieee_header_len] |= (dst->addr_len == 2) ? (0x02 << 2) : (0x03 << 2); /* destination addressing mode */ - buffer[ieee_header_len] |= (src->addr_len == 2) ? (0x02 << 6) : (0x03 << 6); /* source addressing mode */ - ieee_header_len++; - buffer[ieee_header_len++] = frame_seq_num++; - - buffer[ieee_header_len++] = ieee_802154_pan_id & 0xff; /* pan id */ - buffer[ieee_header_len++] = (ieee_802154_pan_id >> 8) & 0xff; /* pan id */ - i = dst->addr_len; - while (i-- > 0) { - buffer[ieee_header_len++] = dst->addr[i]; - } - - buffer[ieee_header_len++] = ieee_802154_pan_id & 0xff; /* pan id */ - buffer[ieee_header_len++] = (ieee_802154_pan_id >> 8) & 0xff; /* pan id */ - i = src->addr_len; - while (i-- > 0) { - buffer[ieee_header_len++] = src->addr[i]; - } - -#if LWIP_6LOWPAN_IPHC - /* Perform 6LowPAN IPv6 header compression according to RFC 6282 */ - { - struct ip6_hdr *ip6hdr; - - /* Point to ip6 header and align copies of src/dest addresses. */ - ip6hdr = (struct ip6_hdr *)p->payload; - ip_addr_copy_from_ip6(ip_data.current_iphdr_dest, ip6hdr->dest); - ip_addr_copy_from_ip6(ip_data.current_iphdr_src, ip6hdr->src); - - /* Basic length of 6LowPAN header, set dispatch and clear fields. */ - lowpan6_header_len = 2; - buffer[ieee_header_len] = 0x60; - buffer[ieee_header_len + 1] = 0; - - /* Determine whether there will be a Context Identifier Extension byte or not. - * If so, set it already. */ -#if LWIP_6LOWPAN_NUM_CONTEXTS > 0 - buffer[ieee_header_len + 2] = 0; - - i = lowpan6_context_lookup(ip_2_ip6(&ip_data.current_iphdr_src)); - if (i >= 0) { - /* Stateful source address compression. */ - buffer[ieee_header_len + 1] |= 0x40; - buffer[ieee_header_len + 2] |= (i & 0x0f) << 4; - } - - i = lowpan6_context_lookup(ip_2_ip6(&ip_data.current_iphdr_dest)); - if (i >= 0) { - /* Stateful destination address compression. */ - buffer[ieee_header_len + 1] |= 0x04; - buffer[ieee_header_len + 2] |= i & 0x0f; - } - - if (buffer[ieee_header_len + 2] != 0x00) { - /* Context identifier extension byte is appended. */ - buffer[ieee_header_len + 1] |= 0x80; - lowpan6_header_len++; - } -#endif /* LWIP_6LOWPAN_NUM_CONTEXTS > 0 */ - - /* Determine TF field: Traffic Class, Flow Label */ - if (IP6H_FL(ip6hdr) == 0) { - /* Flow label is elided. */ - buffer[ieee_header_len] |= 0x10; - if (IP6H_TC(ip6hdr) == 0) { - /* Traffic class (ECN+DSCP) elided too. */ - buffer[ieee_header_len] |= 0x08; - } else { - /* Traffic class (ECN+DSCP) appended. */ - buffer[ieee_header_len + lowpan6_header_len++] = IP6H_TC(ip6hdr); - } - } else { - if (((IP6H_TC(ip6hdr) & 0x3f) == 0)) { - /* DSCP portion of Traffic Class is elided, ECN and FL are appended (3 bytes) */ - buffer[ieee_header_len] |= 0x08; - - buffer[ieee_header_len + lowpan6_header_len] = IP6H_TC(ip6hdr) & 0xc0; - buffer[ieee_header_len + lowpan6_header_len++] |= (IP6H_FL(ip6hdr) >> 16) & 0x0f; - buffer[ieee_header_len + lowpan6_header_len++] = (IP6H_FL(ip6hdr) >> 8) & 0xff; - buffer[ieee_header_len + lowpan6_header_len++] = IP6H_FL(ip6hdr) & 0xff; - } else { - /* Traffic class and flow label are appended (4 bytes) */ - buffer[ieee_header_len + lowpan6_header_len++] = IP6H_TC(ip6hdr); - buffer[ieee_header_len + lowpan6_header_len++] = (IP6H_FL(ip6hdr) >> 16) & 0x0f; - buffer[ieee_header_len + lowpan6_header_len++] = (IP6H_FL(ip6hdr) >> 8) & 0xff; - buffer[ieee_header_len + lowpan6_header_len++] = IP6H_FL(ip6hdr) & 0xff; - } - } - - /* Compress NH? - * Only if UDP for now. @todo support other NH compression. */ - if (IP6H_NEXTH(ip6hdr) == IP6_NEXTH_UDP) { - buffer[ieee_header_len] |= 0x04; - } else { - /* append nexth. */ - buffer[ieee_header_len + lowpan6_header_len++] = IP6H_NEXTH(ip6hdr); - } - - /* Compress hop limit? */ - if (IP6H_HOPLIM(ip6hdr) == 255) { - buffer[ieee_header_len] |= 0x03; - } else if (IP6H_HOPLIM(ip6hdr) == 64) { - buffer[ieee_header_len] |= 0x02; - } else if (IP6H_HOPLIM(ip6hdr) == 1) { - buffer[ieee_header_len] |= 0x01; - } else { - /* append hop limit */ - buffer[ieee_header_len + lowpan6_header_len++] = IP6H_HOPLIM(ip6hdr); - } - - /* Compress source address */ - if (((buffer[ieee_header_len + 1] & 0x40) != 0) || - (ip6_addr_islinklocal(ip_2_ip6(&ip_data.current_iphdr_src)))) { - /* Context-based or link-local source address compression. */ - i = lowpan6_get_address_mode(ip_2_ip6(&ip_data.current_iphdr_src), src); - buffer[ieee_header_len + 1] |= (i & 0x03) << 4; - if (i == 1) { - MEMCPY(buffer + ieee_header_len + lowpan6_header_len, (u8_t*)p->payload + 16, 8); - lowpan6_header_len += 8; - } else if (i == 2) { - MEMCPY(buffer + ieee_header_len + lowpan6_header_len, (u8_t*)p->payload + 22, 2); - lowpan6_header_len += 2; - } - } else if (ip6_addr_isany(ip_2_ip6(&ip_data.current_iphdr_src))) { - /* Special case: mark SAC and leave SAM=0 */ - buffer[ieee_header_len + 1] |= 0x40; - } else { - /* Append full address. */ - MEMCPY(buffer + ieee_header_len + lowpan6_header_len, (u8_t*)p->payload + 8, 16); - lowpan6_header_len += 16; - } - - /* Compress destination address */ - if (ip6_addr_ismulticast(ip_2_ip6(&ip_data.current_iphdr_dest))) { - /* @todo support stateful multicast address compression */ - - buffer[ieee_header_len + 1] |= 0x08; - - i = lowpan6_get_address_mode_mc(ip_2_ip6(&ip_data.current_iphdr_dest)); - buffer[ieee_header_len + 1] |= i & 0x03; - if (i == 0) { - MEMCPY(buffer + ieee_header_len + lowpan6_header_len, (u8_t*)p->payload + 24, 16); - lowpan6_header_len += 16; - } else if (i == 1) { - buffer[ieee_header_len + lowpan6_header_len++] = ((u8_t *)p->payload)[25]; - MEMCPY(buffer + ieee_header_len + lowpan6_header_len, (u8_t*)p->payload + 35, 5); - lowpan6_header_len += 5; - } else if (i == 2) { - buffer[ieee_header_len + lowpan6_header_len++] = ((u8_t *)p->payload)[25]; - MEMCPY(buffer + ieee_header_len + lowpan6_header_len, (u8_t*)p->payload + 37, 3); - lowpan6_header_len += 3; - } else if (i == 3) { - buffer[ieee_header_len + lowpan6_header_len++] = ((u8_t *)p->payload)[39]; - } - } else if (((buffer[ieee_header_len + 1] & 0x04) != 0) || - (ip6_addr_islinklocal(ip_2_ip6(&ip_data.current_iphdr_dest)))) { - /* Context-based or link-local destination address compression. */ - i = lowpan6_get_address_mode(ip_2_ip6(&ip_data.current_iphdr_dest), dst); - buffer[ieee_header_len + 1] |= i & 0x03; - if (i == 1) { - MEMCPY(buffer + ieee_header_len + lowpan6_header_len, (u8_t*)p->payload + 32, 8); - lowpan6_header_len += 8; - } else if (i == 2) { - MEMCPY(buffer + ieee_header_len + lowpan6_header_len, (u8_t*)p->payload + 38, 2); - lowpan6_header_len += 2; - } - } else { - /* Append full address. */ - MEMCPY(buffer + ieee_header_len + lowpan6_header_len, (u8_t*)p->payload + 24, 16); - lowpan6_header_len += 16; - } - - /* Move to payload. */ - pbuf_header(p, -IP6_HLEN); - - /* Compress UDP header? */ - if (IP6H_NEXTH(ip6hdr) == IP6_NEXTH_UDP) { - /* @todo support optional checksum compression */ - - buffer[ieee_header_len + lowpan6_header_len] = 0xf0; - - /* determine port compression mode. */ - if ((((u8_t *)p->payload)[0] == 0xf0) && ((((u8_t *)p->payload)[1] & 0xf0) == 0xb0) && - (((u8_t *)p->payload)[2] == 0xf0) && ((((u8_t *)p->payload)[3] & 0xf0) == 0xb0)) { - /* Compress source and dest ports. */ - buffer[ieee_header_len + lowpan6_header_len++] |= 0x03; - buffer[ieee_header_len + lowpan6_header_len++] = ((((u8_t *)p->payload)[1] & 0x0f) << 4) | (((u8_t *)p->payload)[3] & 0x0f); - } else if (((u8_t *)p->payload)[0] == 0xf0) { - /* Compress source port. */ - buffer[ieee_header_len + lowpan6_header_len++] |= 0x02; - buffer[ieee_header_len + lowpan6_header_len++] = ((u8_t *)p->payload)[1]; - buffer[ieee_header_len + lowpan6_header_len++] = ((u8_t *)p->payload)[2]; - buffer[ieee_header_len + lowpan6_header_len++] = ((u8_t *)p->payload)[3]; - } else if (((u8_t *)p->payload)[2] == 0xf0) { - /* Compress dest port. */ - buffer[ieee_header_len + lowpan6_header_len++] |= 0x01; - buffer[ieee_header_len + lowpan6_header_len++] = ((u8_t *)p->payload)[0]; - buffer[ieee_header_len + lowpan6_header_len++] = ((u8_t *)p->payload)[1]; - buffer[ieee_header_len + lowpan6_header_len++] = ((u8_t *)p->payload)[3]; - } else { - /* append full ports. */ - lowpan6_header_len++; - buffer[ieee_header_len + lowpan6_header_len++] = ((u8_t *)p->payload)[0]; - buffer[ieee_header_len + lowpan6_header_len++] = ((u8_t *)p->payload)[1]; - buffer[ieee_header_len + lowpan6_header_len++] = ((u8_t *)p->payload)[2]; - buffer[ieee_header_len + lowpan6_header_len++] = ((u8_t *)p->payload)[3]; - } - - /* elide length and copy checksum */ - buffer[ieee_header_len + lowpan6_header_len++] = ((u8_t *)p->payload)[6]; - buffer[ieee_header_len + lowpan6_header_len++] = ((u8_t *)p->payload)[7]; - - pbuf_header(p, -UDP_HLEN); - } - } - -#else /* LWIP_6LOWPAN_HC */ - /* Send uncompressed IPv6 header with appropriate dispatch byte. */ - lowpan6_header_len = 1; - buffer[ieee_header_len] = 0x41; /* IPv6 dispatch */ -#endif /* LWIP_6LOWPAN_HC */ - - /* Calculate remaining packet length */ - remaining_len = p->tot_len; - - if (remaining_len > 0x7FF) { - MIB2_STATS_NETIF_INC(netif, ifoutdiscards); - /* datagram_size must fit into 11 bit */ - pbuf_free(p_frag); - return ERR_VAL; - } - - /* Fragment, or 1 packet? */ - if (remaining_len > (127 - ieee_header_len - lowpan6_header_len - 3)) { /* 127 - header - 1 byte dispatch - 2 bytes CRC */ - /* We must move the 6LowPAN header to make room for the FRAG header. */ - i = lowpan6_header_len; - while (i-- != 0) { - buffer[ieee_header_len + i + 4] = buffer[ieee_header_len + i]; - } - - /* Now we need to fragment the packet. FRAG1 header first */ - buffer[ieee_header_len] = 0xc0 | (((p->tot_len + lowpan6_header_len) >> 8) & 0x7); - buffer[ieee_header_len + 1] = (p->tot_len + lowpan6_header_len) & 0xff; - - datagram_tag++; - buffer[ieee_header_len + 2] = datagram_tag & 0xff; - buffer[ieee_header_len + 3] = (datagram_tag >> 8) & 0xff; - - /* Fragment follows. */ - frag_len = (127 - ieee_header_len - 4 - 2) & 0xf8; - - pbuf_copy_partial(p, buffer + ieee_header_len + lowpan6_header_len + 4, frag_len - lowpan6_header_len, 0); - remaining_len -= frag_len - lowpan6_header_len; - datagram_offset = frag_len; - - /* 2 bytes CRC */ -#if LWIP_6LOWPAN_HW_CRC - /* Leave blank, will be filled by HW. */ -#else /* LWIP_6LOWPAN_HW_CRC */ - /* @todo calculate CRC */ -#endif /* LWIP_6LOWPAN_HW_CRC */ - - /* Calculate frame length */ - p_frag->len = p_frag->tot_len = ieee_header_len + 4 + frag_len + 2; /* add 2 dummy bytes for crc*/ - - /* send the packet */ - MIB2_STATS_NETIF_ADD(netif, ifoutoctets, p_frag->tot_len); - LWIP_DEBUGF(LOWPAN6_DEBUG | LWIP_DBG_TRACE, ("lowpan6_send: sending packet %p\n", (void *)p)); - err = netif->linkoutput(netif, p_frag); - - while ((remaining_len > 0) && (err == ERR_OK)) { - /* new frame, new seq num for ACK */ - buffer[2] = frame_seq_num++; - - buffer[ieee_header_len] |= 0x20; /* Change FRAG1 to FRAGN */ - - buffer[ieee_header_len + 4] = (u8_t)(datagram_offset >> 3); /* datagram offset in FRAGN header (datagram_offset is max. 11 bit) */ - - frag_len = (127 - ieee_header_len - 5 - 2) & 0xf8; - if (frag_len > remaining_len) { - frag_len = remaining_len; - } - - pbuf_copy_partial(p, buffer + ieee_header_len + 5, frag_len, p->tot_len - remaining_len); - remaining_len -= frag_len; - datagram_offset += frag_len; - - /* 2 bytes CRC */ -#if LWIP_6LOWPAN_HW_CRC - /* Leave blank, will be filled by HW. */ -#else /* LWIP_6LOWPAN_HW_CRC */ - /* @todo calculate CRC */ -#endif /* LWIP_6LOWPAN_HW_CRC */ - - /* Calculate frame length */ - p_frag->len = p_frag->tot_len = frag_len + 5 + ieee_header_len + 2; - - /* send the packet */ - MIB2_STATS_NETIF_ADD(netif, ifoutoctets, p_frag->tot_len); - LWIP_DEBUGF(LOWPAN6_DEBUG | LWIP_DBG_TRACE, ("lowpan6_send: sending packet %p\n", (void *)p)); - err = netif->linkoutput(netif, p_frag); - } - } else { - /* It fits in one frame. */ - frag_len = remaining_len; - - /* Copy IPv6 packet */ - pbuf_copy_partial(p, buffer + ieee_header_len + lowpan6_header_len, frag_len, 0); - remaining_len = 0; - - /* 2 bytes CRC */ -#if LWIP_6LOWPAN_HW_CRC - /* Leave blank, will be filled by HW. */ -#else /* LWIP_6LOWPAN_HW_CRC */ - /* @todo calculate CRC */ -#endif /* LWIP_6LOWPAN_HW_CRC */ - - /* Calculate frame length */ - p_frag->len = p_frag->tot_len = frag_len + lowpan6_header_len + ieee_header_len + 2; - - /* send the packet */ - MIB2_STATS_NETIF_ADD(netif, ifoutoctets, p_frag->tot_len); - LWIP_DEBUGF(LOWPAN6_DEBUG | LWIP_DBG_TRACE, ("lowpan6_send: sending packet %p\n", (void *)p)); - err = netif->linkoutput(netif, p_frag); - } - - pbuf_free(p_frag); - - return err; -} - -err_t -lowpan6_set_context(u8_t idx, const ip6_addr_t * context) -{ - if (idx >= LWIP_6LOWPAN_NUM_CONTEXTS) { - return ERR_ARG; - } - - ip6_addr_set(&lowpan6_context[idx], context); - - return ERR_OK; -} - -#if LWIP_6LOWPAN_INFER_SHORT_ADDRESS -err_t -lowpan6_set_short_addr(u8_t addr_high, u8_t addr_low) -{ - short_mac_addr.addr[0] = addr_high; - short_mac_addr.addr[1] = addr_low; - - return ERR_OK; -} -#endif /* LWIP_6LOWPAN_INFER_SHORT_ADDRESS */ - -#if LWIP_IPV4 -err_t -lowpan4_output(struct netif *netif, struct pbuf *q, const ip4_addr_t *ipaddr) -{ - (void)netif; - (void)q; - (void)ipaddr; - - return ERR_IF; -} -#endif /* LWIP_IPV4 */ - -/** - * Resolve and fill-in IEEE 802.15.4 address header for outgoing IPv6 packet. - * - * Perform Header Compression and fragment if necessary. - * - * @param netif The lwIP network interface which the IP packet will be sent on. - * @param q The pbuf(s) containing the IP packet to be sent. - * @param ip6addr The IP address of the packet destination. - * - * @return err_t - */ -err_t -lowpan6_output(struct netif *netif, struct pbuf *q, const ip6_addr_t *ip6addr) -{ - err_t result; - const u8_t *hwaddr; - struct ieee_802154_addr src, dest; -#if LWIP_6LOWPAN_INFER_SHORT_ADDRESS - ip6_addr_t ip6_src; - struct ip6_hdr * ip6_hdr; -#endif /* LWIP_6LOWPAN_INFER_SHORT_ADDRESS */ - -#if LWIP_6LOWPAN_INFER_SHORT_ADDRESS - /* Check if we can compress source address (use aligned copy) */ - ip6_hdr = (struct ip6_hdr *)q->payload; - ip6_addr_set(&ip6_src, &ip6_hdr->src); - if (lowpan6_get_address_mode(&ip6_src, &short_mac_addr) == 3) { - src.addr_len = 2; - src.addr[0] = short_mac_addr.addr[0]; - src.addr[1] = short_mac_addr.addr[1]; - } else -#endif /* LWIP_6LOWPAN_INFER_SHORT_ADDRESS */ - { - src.addr_len = netif->hwaddr_len; - SMEMCPY(src.addr, netif->hwaddr, netif->hwaddr_len); - } - - /* multicast destination IP address? */ - if (ip6_addr_ismulticast(ip6addr)) { - MIB2_STATS_NETIF_INC(netif, ifoutnucastpkts); - /* We need to send to the broadcast address.*/ - return lowpan6_frag(netif, q, &src, &ieee_802154_broadcast); - } - - /* We have a unicast destination IP address */ - /* @todo anycast? */ - -#if LWIP_6LOWPAN_INFER_SHORT_ADDRESS - if (src.addr_len == 2) { - /* If source address was compressable to short_mac_addr, and dest has same subnet and - * is also compressable to 2-bytes, assume we can infer dest as a short address too. */ - dest.addr_len = 2; - dest.addr[0] = ((u8_t *)q->payload)[38]; - dest.addr[1] = ((u8_t *)q->payload)[39]; - if ((src.addr_len == 2) && (ip6_addr_netcmp(&ip6_hdr->src, &ip6_hdr->dest)) && - (lowpan6_get_address_mode(ip6addr, &dest) == 3)) { - MIB2_STATS_NETIF_INC(netif, ifoutucastpkts); - return lowpan6_frag(netif, q, &src, &dest); - } - } -#endif /* LWIP_6LOWPAN_INFER_SHORT_ADDRESS */ - - /* Ask ND6 what to do with the packet. */ - result = nd6_get_next_hop_addr_or_queue(netif, q, ip6addr, &hwaddr); - if (result != ERR_OK) { - MIB2_STATS_NETIF_INC(netif, ifoutdiscards); - return result; - } - - /* If no hardware address is returned, nd6 has queued the packet for later. */ - if (hwaddr == NULL) { - return ERR_OK; - } - - /* Send out the packet using the returned hardware address. */ - dest.addr_len = netif->hwaddr_len; - SMEMCPY(dest.addr, hwaddr, netif->hwaddr_len); - MIB2_STATS_NETIF_INC(netif, ifoutucastpkts); - return lowpan6_frag(netif, q, &src, &dest); -} - -static struct pbuf * -lowpan6_decompress(struct pbuf * p, struct ieee_802154_addr * src, struct ieee_802154_addr * dest) -{ - struct pbuf * q; - u8_t * lowpan6_buffer; - s8_t lowpan6_offset; - struct ip6_hdr *ip6hdr; - s8_t i; - s8_t ip6_offset = IP6_HLEN; - - - q = pbuf_alloc(PBUF_IP, p->len + IP6_HLEN + UDP_HLEN, PBUF_POOL); - if (q == NULL) { - pbuf_free(p); - return NULL; - } - - lowpan6_buffer = (u8_t *)p->payload; - ip6hdr = (struct ip6_hdr *)q->payload; - - lowpan6_offset = 2; - if (lowpan6_buffer[1] & 0x80) { - lowpan6_offset++; - } - - /* Set IPv6 version, traffic class and flow label. */ - if ((lowpan6_buffer[0] & 0x18) == 0x00) { - IP6H_VTCFL_SET(ip6hdr, 6, lowpan6_buffer[lowpan6_offset], ((lowpan6_buffer[lowpan6_offset+1] & 0x0f) << 16) | (lowpan6_buffer[lowpan6_offset + 2] << 8) | lowpan6_buffer[lowpan6_offset+3]); - lowpan6_offset += 4; - } else if ((lowpan6_buffer[0] & 0x18) == 0x08) { - IP6H_VTCFL_SET(ip6hdr, 6, lowpan6_buffer[lowpan6_offset] & 0xc0, ((lowpan6_buffer[lowpan6_offset] & 0x0f) << 16) | (lowpan6_buffer[lowpan6_offset + 1] << 8) | lowpan6_buffer[lowpan6_offset+2]); - lowpan6_offset += 3; - } else if ((lowpan6_buffer[0] & 0x18) == 0x10) { - IP6H_VTCFL_SET(ip6hdr, 6, lowpan6_buffer[lowpan6_offset],0); - lowpan6_offset += 1; - } else if ((lowpan6_buffer[0] & 0x18) == 0x18) { - IP6H_VTCFL_SET(ip6hdr, 6, 0, 0); - } - - /* Set Next Header */ - if ((lowpan6_buffer[0] & 0x04) == 0x00) { - IP6H_NEXTH_SET(ip6hdr, lowpan6_buffer[lowpan6_offset++]); - } else { - /* We should fill this later with NHC decoding */ - IP6H_NEXTH_SET(ip6hdr, 0); - } - - /* Set Hop Limit */ - if ((lowpan6_buffer[0] & 0x03) == 0x00) { - IP6H_HOPLIM_SET(ip6hdr, lowpan6_buffer[lowpan6_offset++]); - } else if ((lowpan6_buffer[0] & 0x03) == 0x01) { - IP6H_HOPLIM_SET(ip6hdr, 1); - } else if ((lowpan6_buffer[0] & 0x03) == 0x02) { - IP6H_HOPLIM_SET(ip6hdr, 64); - } else if ((lowpan6_buffer[0] & 0x03) == 0x03) { - IP6H_HOPLIM_SET(ip6hdr, 255); - } - - /* Source address decoding. */ - if ((lowpan6_buffer[1] & 0x40) == 0x00) { - /* Stateless compression */ - if ((lowpan6_buffer[1] & 0x30) == 0x00) { - /* copy full address */ - MEMCPY(&ip6hdr->src.addr[0], lowpan6_buffer + lowpan6_offset, 16); - lowpan6_offset += 16; - } else if ((lowpan6_buffer[1] & 0x30) == 0x10) { - ip6hdr->src.addr[0] = PP_HTONL(0xfe800000UL); - ip6hdr->src.addr[1] = 0; - MEMCPY(&ip6hdr->src.addr[2], lowpan6_buffer + lowpan6_offset, 8); - lowpan6_offset += 8; - } else if ((lowpan6_buffer[1] & 0x30) == 0x20) { - ip6hdr->src.addr[0] = PP_HTONL(0xfe800000UL); - ip6hdr->src.addr[1] = 0; - ip6hdr->src.addr[2] = PP_HTONL(0x000000ffUL); - ip6hdr->src.addr[3] = lwip_htonl(0xfe000000UL | (lowpan6_buffer[lowpan6_offset] << 8) | - lowpan6_buffer[lowpan6_offset+1]); - lowpan6_offset += 2; - } else if ((lowpan6_buffer[1] & 0x30) == 0x30) { - ip6hdr->src.addr[0] = PP_HTONL(0xfe800000UL); - ip6hdr->src.addr[1] = 0; - if (src->addr_len == 2) { - ip6hdr->src.addr[2] = PP_HTONL(0x000000ffUL); - ip6hdr->src.addr[3] = lwip_htonl(0xfe000000UL | (src->addr[0] << 8) | src->addr[1]); - } else { - ip6hdr->src.addr[2] = lwip_htonl(((src->addr[0] ^ 2) << 24) | (src->addr[1] << 16) | - (src->addr[2] << 8) | src->addr[3]); - ip6hdr->src.addr[3] = lwip_htonl((src->addr[4] << 24) | (src->addr[5] << 16) | - (src->addr[6] << 8) | src->addr[7]); - } - } - } else { - /* Stateful compression */ - if ((lowpan6_buffer[1] & 0x30) == 0x00) { - /* ANY address */ - ip6hdr->src.addr[0] = 0; - ip6hdr->src.addr[1] = 0; - ip6hdr->src.addr[2] = 0; - ip6hdr->src.addr[3] = 0; - } else { - /* Set prefix from context info */ - if (lowpan6_buffer[1] & 0x80) { - i = (lowpan6_buffer[2] >> 4) & 0x0f; - } else { - i = 0; - } - if (i >= LWIP_6LOWPAN_NUM_CONTEXTS) { - /* Error */ - pbuf_free(p); - pbuf_free(q); - return NULL; - } - - ip6hdr->src.addr[0] = lowpan6_context[i].addr[0]; - ip6hdr->src.addr[1] = lowpan6_context[i].addr[1]; - } - - if ((lowpan6_buffer[1] & 0x30) == 0x10) { - MEMCPY(&ip6hdr->src.addr[2], lowpan6_buffer + lowpan6_offset, 8); - lowpan6_offset += 8; - } else if ((lowpan6_buffer[1] & 0x30) == 0x20) { - ip6hdr->src.addr[2] = PP_HTONL(0x000000ffUL); - ip6hdr->src.addr[3] = lwip_htonl(0xfe000000UL | (lowpan6_buffer[lowpan6_offset] << 8) | lowpan6_buffer[lowpan6_offset+1]); - lowpan6_offset += 2; - } else if ((lowpan6_buffer[1] & 0x30) == 0x30) { - if (src->addr_len == 2) { - ip6hdr->src.addr[2] = PP_HTONL(0x000000ffUL); - ip6hdr->src.addr[3] = lwip_htonl(0xfe000000UL | (src->addr[0] << 8) | src->addr[1]); - } else { - ip6hdr->src.addr[2] = lwip_htonl(((src->addr[0] ^ 2) << 24) | (src->addr[1] << 16) | (src->addr[2] << 8) | src->addr[3]); - ip6hdr->src.addr[3] = lwip_htonl((src->addr[4] << 24) | (src->addr[5] << 16) | (src->addr[6] << 8) | src->addr[7]); - } - } - } - - /* Destination address decoding. */ - if (lowpan6_buffer[1] & 0x08) { - /* Multicast destination */ - if (lowpan6_buffer[1] & 0x04) { - /* @todo support stateful multicast addressing */ - pbuf_free(p); - pbuf_free(q); - return NULL; - } - - if ((lowpan6_buffer[1] & 0x03) == 0x00) { - /* copy full address */ - MEMCPY(&ip6hdr->dest.addr[0], lowpan6_buffer + lowpan6_offset, 16); - lowpan6_offset += 16; - } else if ((lowpan6_buffer[1] & 0x03) == 0x01) { - ip6hdr->dest.addr[0] = lwip_htonl(0xff000000UL | (lowpan6_buffer[lowpan6_offset++] << 16)); - ip6hdr->dest.addr[1] = 0; - ip6hdr->dest.addr[2] = lwip_htonl(lowpan6_buffer[lowpan6_offset++]); - ip6hdr->dest.addr[3] = lwip_htonl((lowpan6_buffer[lowpan6_offset] << 24) | (lowpan6_buffer[lowpan6_offset + 1] << 16) | (lowpan6_buffer[lowpan6_offset + 2] << 8) | lowpan6_buffer[lowpan6_offset + 3]); - lowpan6_offset += 4; - } else if ((lowpan6_buffer[1] & 0x03) == 0x02) { - ip6hdr->dest.addr[0] = lwip_htonl(0xff000000UL | lowpan6_buffer[lowpan6_offset++]); - ip6hdr->dest.addr[1] = 0; - ip6hdr->dest.addr[2] = 0; - ip6hdr->dest.addr[3] = lwip_htonl((lowpan6_buffer[lowpan6_offset] << 16) | (lowpan6_buffer[lowpan6_offset + 1] << 8) | lowpan6_buffer[lowpan6_offset + 2]); - lowpan6_offset += 3; - } else if ((lowpan6_buffer[1] & 0x03) == 0x03) { - ip6hdr->dest.addr[0] = PP_HTONL(0xff020000UL); - ip6hdr->dest.addr[1] = 0; - ip6hdr->dest.addr[2] = 0; - ip6hdr->dest.addr[3] = lwip_htonl(lowpan6_buffer[lowpan6_offset++]); - } - - } else { - if (lowpan6_buffer[1] & 0x04) { - /* Stateful destination compression */ - /* Set prefix from context info */ - if (lowpan6_buffer[1] & 0x80) { - i = lowpan6_buffer[2] & 0x0f; - } else { - i = 0; - } - if (i >= LWIP_6LOWPAN_NUM_CONTEXTS) { - /* Error */ - pbuf_free(p); - pbuf_free(q); - return NULL; - } - - ip6hdr->dest.addr[0] = lowpan6_context[i].addr[0]; - ip6hdr->dest.addr[1] = lowpan6_context[i].addr[1]; - } else { - /* Link local address compression */ - ip6hdr->dest.addr[0] = PP_HTONL(0xfe800000UL); - ip6hdr->dest.addr[1] = 0; - } - - if ((lowpan6_buffer[1] & 0x03) == 0x00) { - /* copy full address */ - MEMCPY(&ip6hdr->dest.addr[0], lowpan6_buffer + lowpan6_offset, 16); - lowpan6_offset += 16; - } else if ((lowpan6_buffer[1] & 0x03) == 0x01) { - MEMCPY(&ip6hdr->dest.addr[2], lowpan6_buffer + lowpan6_offset, 8); - lowpan6_offset += 8; - } else if ((lowpan6_buffer[1] & 0x03) == 0x02) { - ip6hdr->dest.addr[2] = PP_HTONL(0x000000ffUL); - ip6hdr->dest.addr[3] = lwip_htonl(0xfe000000UL | (lowpan6_buffer[lowpan6_offset] << 8) | lowpan6_buffer[lowpan6_offset + 1]); - lowpan6_offset += 2; - } else if ((lowpan6_buffer[1] & 0x03) == 0x03) { - if (dest->addr_len == 2) { - ip6hdr->dest.addr[2] = PP_HTONL(0x000000ffUL); - ip6hdr->dest.addr[3] = lwip_htonl(0xfe000000UL | (dest->addr[0] << 8) | dest->addr[1]); - } else { - ip6hdr->dest.addr[2] = lwip_htonl(((dest->addr[0] ^ 2) << 24) | (dest->addr[1] << 16) | dest->addr[2] << 8 | dest->addr[3]); - ip6hdr->dest.addr[3] = lwip_htonl((dest->addr[4] << 24) | (dest->addr[5] << 16) | dest->addr[6] << 8 | dest->addr[7]); - } - } - } - - - /* Next Header Compression (NHC) decoding? */ - if (lowpan6_buffer[0] & 0x04) { - if ((lowpan6_buffer[lowpan6_offset] & 0xf8) == 0xf0) { - struct udp_hdr *udphdr; - - /* UDP compression */ - IP6H_NEXTH_SET(ip6hdr, IP6_NEXTH_UDP); - udphdr = (struct udp_hdr *)((u8_t *)q->payload + ip6_offset); - - if (lowpan6_buffer[lowpan6_offset] & 0x04) { - /* @todo support checksum decompress */ - pbuf_free(p); - pbuf_free(q); - return NULL; - } - - /* Decompress ports */ - i = lowpan6_buffer[lowpan6_offset++] & 0x03; - if (i == 0) { - udphdr->src = lwip_htons(lowpan6_buffer[lowpan6_offset] << 8 | lowpan6_buffer[lowpan6_offset + 1]); - udphdr->dest = lwip_htons(lowpan6_buffer[lowpan6_offset + 2] << 8 | lowpan6_buffer[lowpan6_offset + 3]); - lowpan6_offset += 4; - } else if (i == 0x01) { - udphdr->src = lwip_htons(lowpan6_buffer[lowpan6_offset] << 8 | lowpan6_buffer[lowpan6_offset + 1]); - udphdr->dest = lwip_htons(0xf000 | lowpan6_buffer[lowpan6_offset + 2]); - lowpan6_offset += 3; - } else if (i == 0x02) { - udphdr->src = lwip_htons(0xf000 | lowpan6_buffer[lowpan6_offset]); - udphdr->dest = lwip_htons(lowpan6_buffer[lowpan6_offset + 1] << 8 | lowpan6_buffer[lowpan6_offset + 2]); - lowpan6_offset += 3; - } else if (i == 0x03) { - udphdr->src = lwip_htons(0xf0b0 | ((lowpan6_buffer[lowpan6_offset] >> 4) & 0x0f)); - udphdr->dest = lwip_htons(0xf0b0 | (lowpan6_buffer[lowpan6_offset] & 0x0f)); - lowpan6_offset += 1; - } - - udphdr->chksum = lwip_htons(lowpan6_buffer[lowpan6_offset] << 8 | lowpan6_buffer[lowpan6_offset + 1]); - lowpan6_offset += 2; - udphdr->len = lwip_htons(p->tot_len - lowpan6_offset + UDP_HLEN); - - ip6_offset += UDP_HLEN; - } else { - /* @todo support NHC other than UDP */ - pbuf_free(p); - pbuf_free(q); - return NULL; - } - } - - /* Now we copy leftover contents from p to q, so we have all L2 and L3 headers (and L4?) in a single PBUF. - * Replace p with q, and free p */ - pbuf_header(p, -lowpan6_offset); - MEMCPY((u8_t*)q->payload + ip6_offset, p->payload, p->len); - q->len = q->tot_len = ip6_offset + p->len; - if (p->next != NULL) { - pbuf_cat(q, p->next); - } - p->next = NULL; - pbuf_free(p); - - /* Infer IPv6 payload length for header */ - IP6H_PLEN_SET(ip6hdr, q->tot_len - IP6_HLEN); - - /* all done */ - return q; -} - -err_t -lowpan6_input(struct pbuf * p, struct netif *netif) -{ - u8_t * puc; - s8_t i; - struct ieee_802154_addr src, dest; - u16_t datagram_size, datagram_offset, datagram_tag; - struct lowpan6_reass_helper *lrh, *lrh_temp; - - MIB2_STATS_NETIF_ADD(netif, ifinoctets, p->tot_len); - - /* Analyze header. @todo validate. */ - puc = (u8_t*)p->payload; - datagram_offset = 5; - if ((puc[1] & 0x0c) == 0x0c) { - dest.addr_len = 8; - for (i = 0; i < 8; i++) { - dest.addr[i] = puc[datagram_offset + 7 - i]; - } - datagram_offset += 8; - } else { - dest.addr_len = 2; - dest.addr[0] = puc[datagram_offset + 1]; - dest.addr[1] = puc[datagram_offset]; - datagram_offset += 2; - } - - datagram_offset += 2; /* skip PAN ID. */ - - if ((puc[1] & 0xc0) == 0xc0) { - src.addr_len = 8; - for (i = 0; i < 8; i++) { - src.addr[i] = puc[datagram_offset + 7 - i]; - } - datagram_offset += 8; - } else { - src.addr_len = 2; - src.addr[0] = puc[datagram_offset + 1]; - src.addr[1] = puc[datagram_offset]; - datagram_offset += 2; - } - - pbuf_header(p, -datagram_offset); /* hide IEEE802.15.4 header. */ - - /* Check dispatch. */ - puc = (u8_t*)p->payload; - - if ((*puc & 0xf8) == 0xc0) { - /* FRAG1 dispatch. add this packet to reassembly list. */ - datagram_size = ((u16_t)(puc[0] & 0x07) << 8) | (u16_t)puc[1]; - datagram_tag = ((u16_t)puc[2] << 8) | (u16_t)puc[3]; - - /* check for duplicate */ - lrh = reass_list; - while (lrh != NULL) { - if ((lrh->sender_addr.addr_len == src.addr_len) && - (memcmp(lrh->sender_addr.addr, src.addr, src.addr_len) == 0)) { - /* address match with packet in reassembly. */ - if ((datagram_tag == lrh->datagram_tag) && (datagram_size == lrh->datagram_size)) { - MIB2_STATS_NETIF_INC(netif, ifindiscards); - /* duplicate fragment. */ - pbuf_free(p); - return ERR_OK; - } else { - /* We are receiving the start of a new datagram. Discard old one (incomplete). */ - lrh_temp = lrh->next_packet; - dequeue_datagram(lrh); - pbuf_free(lrh->pbuf); - mem_free(lrh); - - /* Check next datagram in queue. */ - lrh = lrh_temp; - } - } else { - /* Check next datagram in queue. */ - lrh = lrh->next_packet; - } - } - - pbuf_header(p, -4); /* hide frag1 dispatch */ - - lrh = (struct lowpan6_reass_helper *) mem_malloc(sizeof(struct lowpan6_reass_helper)); - if (lrh == NULL) { - MIB2_STATS_NETIF_INC(netif, ifindiscards); - pbuf_free(p); - return ERR_MEM; - } - - lrh->sender_addr.addr_len = src.addr_len; - for (i = 0; i < src.addr_len; i++) { - lrh->sender_addr.addr[i] = src.addr[i]; - } - lrh->datagram_size = datagram_size; - lrh->datagram_tag = datagram_tag; - lrh->pbuf = p; - lrh->next_packet = reass_list; - lrh->timer = 2; - reass_list = lrh; - - return ERR_OK; - } else if ((*puc & 0xf8) == 0xe0) { - /* FRAGN dispatch, find packet being reassembled. */ - datagram_size = ((u16_t)(puc[0] & 0x07) << 8) | (u16_t)puc[1]; - datagram_tag = ((u16_t)puc[2] << 8) | (u16_t)puc[3]; - datagram_offset = (u16_t)puc[4] << 3; - pbuf_header(p, -5); /* hide frag1 dispatch */ - - for (lrh = reass_list; lrh != NULL; lrh = lrh->next_packet) { - if ((lrh->sender_addr.addr_len == src.addr_len) && - (memcmp(lrh->sender_addr.addr, src.addr, src.addr_len) == 0) && - (datagram_tag == lrh->datagram_tag) && - (datagram_size == lrh->datagram_size)) { - break; - } - } - if (lrh == NULL) { - /* rogue fragment */ - MIB2_STATS_NETIF_INC(netif, ifindiscards); - pbuf_free(p); - return ERR_OK; - } - - if (lrh->pbuf->tot_len < datagram_offset) { - /* duplicate, ignore. */ - pbuf_free(p); - return ERR_OK; - } else if (lrh->pbuf->tot_len > datagram_offset) { - MIB2_STATS_NETIF_INC(netif, ifindiscards); - /* We have missed a fragment. Delete whole reassembly. */ - dequeue_datagram(lrh); - pbuf_free(lrh->pbuf); - mem_free(lrh); - pbuf_free(p); - return ERR_OK; - } - pbuf_cat(lrh->pbuf, p); - p = NULL; - - /* is packet now complete?*/ - if (lrh->pbuf->tot_len >= lrh->datagram_size) { - /* dequeue from reass list. */ - dequeue_datagram(lrh); - - /* get pbuf */ - p = lrh->pbuf; - - /* release helper */ - mem_free(lrh); - } else { - return ERR_OK; - } - } - - if (p == NULL) { - return ERR_OK; - } - - /* We have a complete packet, check dispatch for headers. */ - puc = (u8_t*)p->payload; - - if (*puc == 0x41) { - /* This is a complete IPv6 packet, just skip dispatch byte. */ - pbuf_header(p, -1); /* hide dispatch byte. */ - } else if ((*puc & 0xe0 )== 0x60) { - /* IPv6 headers are compressed using IPHC. */ - p = lowpan6_decompress(p, &src, &dest); - if (p == NULL) { - MIB2_STATS_NETIF_INC(netif, ifindiscards); - return ERR_OK; - } - } else { - MIB2_STATS_NETIF_INC(netif, ifindiscards); - pbuf_free(p); - return ERR_OK; - } - - /* @todo: distinguish unicast/multicast */ - MIB2_STATS_NETIF_INC(netif, ifinucastpkts); - - return ip6_input(p, netif); -} - -err_t -lowpan6_if_init(struct netif *netif) -{ - netif->name[0] = 'L'; - netif->name[1] = '6'; -#if LWIP_IPV4 - netif->output = lowpan4_output; -#endif /* LWIP_IPV4 */ - netif->output_ip6 = lowpan6_output; - - MIB2_INIT_NETIF(netif, snmp_ifType_other, 0); - - /* maximum transfer unit */ - netif->mtu = 1280; - - /* broadcast capability */ - netif->flags = NETIF_FLAG_BROADCAST /* | NETIF_FLAG_LOWPAN6 */; - - return ERR_OK; -} - -err_t -lowpan6_set_pan_id(u16_t pan_id) -{ - ieee_802154_pan_id = pan_id; - - return ERR_OK; -} - -#if !NO_SYS -/** - * Pass a received packet to tcpip_thread for input processing - * - * @param p the received packet, p->payload pointing to the - * IEEE 802.15.4 header. - * @param inp the network interface on which the packet was received - */ -err_t -tcpip_6lowpan_input(struct pbuf *p, struct netif *inp) -{ - return tcpip_inpkt(p, inp, lowpan6_input); -} -#endif /* !NO_SYS */ - -#endif /* LWIP_IPV6 && LWIP_6LOWPAN */ diff --git a/third_party/lwip/repo/lwip/src/netif/ppp/PPPD_FOLLOWUP b/third_party/lwip/repo/lwip/src/netif/ppp/PPPD_FOLLOWUP deleted file mode 100644 index c231982ae7ae97..00000000000000 --- a/third_party/lwip/repo/lwip/src/netif/ppp/PPPD_FOLLOWUP +++ /dev/null @@ -1,473 +0,0 @@ -The lwIP PPP support is based from pppd 2.4.5 (http://ppp.samba.org) with -huge changes to match code size and memory requirements for embedded devices. - -Anyway, pppd has a mature codebase for years and the average commit count -is getting low on their Git repository, meaning that we can follow what -is happening on their side and merge what is relevant for lwIP. - -So, here is the pppd follow up, so that we don't get away too far from pppd. - - -== Patch fetched from from pppd Debian packages == - -This has nothing to do with pppd, but we merged some good patch from -Debian and this is a good place to be. - -- LCP adaptive echo, so that we don't send LCP echo request if we - are receiving data from peer, can be enabled by setting PPP_LCP_ADAPTIVE - to true. - -- IPCP no/replace default route option, were added in the early stage of - the ppp port, but it wasn't really helpful and was disabled when adding - the new API ppp_set_default() call, which gives the lwIP user control over - which one is the default interface, it was actually a requirement if you - are doing PPP over PPP (i.e. PPPoL2TP, VPN link, over PPPoE, ADSL link). - -- using rp-pppoe pppd exits with EXIT_OK after receiving a timeout waiting - for PADO due to no modem attached, bug reported to pppd bug tracker, fixed - in Debian but not in the latest (at the time when the port were started) - pppd release. - - -== Commits on pppd == - -2010-03-06 - Document +ipv6 and ipv6cp-accept-local - e7537958aee79b3f653c601e903cb31d78fb7dcc - -Don't care. - - -2010-03-06 - Install pppol2tp plugins with sane permissions - 406215672cfadc03017341fe03802d1c7294b903 - -Don't care. - - -2010-03-07 - pppd: Terminate correctly if lcp_lowerup delayed calling - fsm_lowerup - 3eb9e810cfa515543655659b72dde30c54fea0a5 - -Merged 2012-05-17. - - -2010-03-07 - rp_pppoe: Copy acName and pppd_pppoe_service after option parsing - cab58617fd9d328029fffabc788020264b4fa91f - -Don't care, is a patch for pppd/plugins/rp-pppoe/plugin.c which is not part -of the port. - - -2010-08-23 - set and reset options to control environment variables - for scripts. - 2b6310fd24dba8e0fca8999916a162f0a1842a84 - -We can't fork processes in embedded, therefore all the pppd process run -feature is disabled in the port, so we don't care about the new -"environment variables" pppd feature. - - -2010-08-23 - Nit: use _exit when exec fails and restrict values to 0-255 - per POSIX. - 2b4ea140432eeba5a007c0d4e6236bd0e0c12ba4 - -Again, we are not running as a heavy process, so all exit() or _exit() calls -were removed. - - -2010-08-23 - Fix quote handling in configuration files to be more like shell - quoting. - 3089132cdf5b58dbdfc2daf08ec5c08eb47f8aca - -We are not parsing config file, all the filesystem I/O stuff were disabled -in our port. - - -2010-08-24 - rp-pppoe: allow MTU to be increased up to 1500 - fd1dcdf758418f040da3ed801ab001b5e46854e7 - -Only concern changes on RP-PPPoE plugin, which we don't use. - - -2010-09-11 - chat: Allow TIMEOUT value to come from environment variable - ae80bf833e48a6202f44a935a68083ae52ad3824 - -See 2b6310fd24dba8e0fca8999916a162f0a1842a84. - - -2011-03-05 - pppdump: Fix printfs with insufficient arguments - 7b8db569642c83ba3283745034f2e2c95e459423 - -pppdump is a ppp tool outside pppd source tree. - - -2012-05-06 - pppd: Don't unconditionally disable VJ compression under Linux - d8a66adf98a0e525cf38031b42098d539da6eeb6 - -Patch for sys-linux.c, which we don't use. - - -2012-05-20 - Remove old version of Linux if_pppol2tp.h - c41092dd4c49267f232f6cba3d31c6c68bfdf68d - -Not in the port. - - -2012-05-20 - pppd: Make MSCHAP-v2 cope better with packet loss - 08ef47ca532294eb428238c831616748940e24a2 - -This is an interesting patch. However it consumes much more memory for -MSCHAP and I am not sure if the benefit worth it. The PPP client can -always start the authentication again if it failed for whatever reason. - - -2012-05-20 - scripts: Make poff ignore extra arguments to pppd - 18f515f32c9f5723a9c2c912601e04335106534b - -Again, we are not running scripts. - - -2012-05-20 - rp-pppoe plugin: Print leading zeros in MAC address - f5dda0cfc220c4b52e26144096d729e27b30f0f7 - -Again, we are not using the RP-PPPoE plugin. - - -2012-05-20 - pppd: Notify IPv6 up/down as we do for IPv4 - 845cda8fa18939cf56e60b073f63a7efa65336fc - -This is just a patch that adds plugins hooks for IPv6, the plugin interface -was disabled because we don't have .so plugins in embedded. - - -2012-05-20 - pppd: Enable IPV6 by default and fix some warnings - 0b6118239615e98959f7e0b4e746bdd197533248 - -Change on Makefile for IPv6, warnings were already cleared during port. - - -2012-05-20 - contrib: Fix pppgetpass.gtk compilation - 80a8e2ce257ca12cce723519a0f20ea1d663b14a - -Change on Makefile, don't care. - - -2012-05-20 - pppd: Don't crash if crypt() returns NULL - 04c4348108d847e034dd91066cc6843f60d71731 - -We are using the PolarSSL DES implementation that does not return NULL. - - -2012-05-20 - pppd: Eliminate some warnings - c44ae5e6a7338c96eb463881fe709b2dfaffe568 - -Again, we are handling compilation warnings on our own. - - -2012-05-20 - rp-pppoe plugin: Import some fixes from rp-pppoe-3.10 - 1817d83e51a411044e730ba89ebdb0480e1c8cd4 - -Once more, we are not using the RP-PPPoE plugin. - - -2013-01-23 - pppd: Clarify circumstances where DNS1/DNS2 environment variables are set - cf2f5c9538b9400ade23446a194729b0a4113b3a - -Documentation only. - - -2013-02-03 - ppp: ignore unrecognised radiusclient configuration directives - 7f736dde0da3c19855997d9e67370e351e15e923 - -Radius plugin, not in the port. - - -2013-02-03 - pppd: Take out unused %r conversion completely - 356d8d558d844412119aa18c8e5a113bc6459c7b - -Merged 2014-04-15. - - -2013-02-03 - pppd: Arrange to use logwtmp from libutil on Linux - 9617a7eb137f4fee62799a677a9ecf8d834db3f5 - -Patch for sys-linux.c, which we don't use. - - -2013-02-03 - pppdump: Eliminate some compiler warnings - 3e3acf1ba2b3046c072a42c19164788a9e419bd1 - -pppdump is a ppp tool outside pppd source tree. - - -2013-02-03 - chat: Correct spelling errors in the man page - 8dea1b969d266ccbf6f3a8c5474eb6dcd8838e3b - -Documentation only. - - -2013-02-03 - pppd: Fix spelling errors in man page - 9e05a25d76b3f83096c661678010320df673df6b - -Documentation only. - - -2013-02-03 - plugins/passprompt: Fix potential out-of-bounds array reference - 8edb889b753056a691a3e4b217a110a35f9fdedb - -Plugin patch, we do not have plugins. - - -2013-02-03 - chat: Fix *roff errors in the man page - a7c3489eeaf44e83ce592143c7c8a5b5c29f4c48 - -Documentation only. - - -2013-03-02 - pppd: Fix man page description of case when remote IP address isn't known - 224841f4799f4f1e2e71bc490c54448d66740f4f - -Documentation only. - - -2013-03-02 - pppd: Add master_detach option - 398ed2585640d198c53e736ee5bbd67f7ce8168e - -Option for multilink support, we do not support multilink and this option -is about detaching from the terminal, which is out of the embedded scope. - - -2013-03-11 - pppd: Default exit status to EXIT_CONNECT_FAILED during connection phase - 225361d64ae737afdc8cb57579a2f33525461bc9 - -Commented out in our port, and already fixed by a previously applied Debian patch. - - -2013-03-11 - pppstats: Fix undefined macro in man page - d16a3985eade5280b8e171f5dd0670a91cba0d39 - -Documentation only. - - -2013-05-11 - plugins/radius: Handle bindaddr keyword in radiusclient.conf - d883b2dbafeed3ebd9d7a56ab1469373bd001a3b - -Radius plugin, not in the port. - - -2013-06-09 - pppoatm: Remove explicit loading of pppoatm kernel module - 52cd43a84bea524033b918b603698104f221bbb7 - -PPPoATM plugin, not in the port. - - -2013-06-09 - pppd: Fix segfault in update_db_entry() - 37476164f15a45015310b9d4b197c2d7db1f7f8f - -We do not use the samba db. - - -2013-06-09 - chat: Fix some text that was intended to be literal - cd9683676618adcee8add2c3cfa3382341b5a1f6 - -Documentation only. - - -2013-06-09 - README.pppoe: Minor semantic fix - b5b8898af6fd3d44e873cfc66810ace5f1f47e17 - -Documentation only. - - -2013-06-10 - radius: Handle additional attributes - 2f581cd986a56f2ec4a95abad4f8297a1b10d7e2 - -Radius plugin, not in the port. - - -2013-06-10 - chat, pppd: Use \e instead of \\ in man pages - 8d6942415d22f6ca4377340ca26e345c3f5fa5db - -Documentation only. - - -2014-01-02 - pppd: Don't crash if NULL pointer passed to vslprintf for %q or %v - 906814431bddeb2061825fa1ebad1a967b6d87a9 - -Merged 2014-04-15. - - -2014-01-02 - pppd: Accept IPCP ConfAck packets containing MS-WINS options - a243f217f1c6ac1aa7793806bc88590d077f490a - -Merged 2014-04-15. - - -2014-01-02 - config: Update Solaris compiler options and enable CHAPMS and IPV6 - 99c46caaed01b7edba87962aa52b77fad61bfd7b - -Solaris port, don't care. - - -2014-01-02 - Update README and patchlevel for 2.4.6 release - 4043750fca36e7e0eb90d702e048ad1da4929418 - -Just release stuff. - - -2014-02-18 - pppd: Add option "stop-bits" to set number of serial port stop bits. - ad993a20ee485f0d0e2ac4105221641b200da6e2 - -Low level serial port, not in the port. - - -2014-03-09 - pppd: Separate IPv6 handling for sifup/sifdown - b04d2dc6df5c6b5650fea44250d58757ee3dac4a - -Reimplemented. - - -2014-03-09 - pppol2tp: Connect up/down events to notifiers and add IPv6 ones - fafbe50251efc7d6b4a8be652d085316e112b34f - -Not in the port. - - -2014-03-09 - pppd: Add declarations to eliminate compile warnings - 50967962addebe15c7a7e63116ff46a0441dc464 - -We are handling compilation warnings on our own - - -2014-03-09 - pppd: Eliminate some unnecessary ifdefs - de8da14d845ee6db9236ccfddabf1d8ebf045ddb - -We mostly did that previously. Anyway, merged 2014-12-24. - - -2014-08-01 - radius: Fix realms-config-file option - 880a81be7c8e0fe8567227bc17a1bff3ea035943 - -Radius plugin, not in the port. - - -2014-08-01 - pppd: Eliminate potential integer overflow in option parsing - 7658e8257183f062dc01f87969c140707c7e52cb - -pppd config file parser, not in the port. - - -2014-08-01 - pppd: Eliminate memory leak with multiple instances of a string option - b94b7fbbaa0589aa6ec5fdc733aeb9ff294d2656 - -pppd config file parser, not in the port. - - -2014-08-01 - pppd: Fix a stack variable overflow in MSCHAP-v2 - 36733a891fb56594fcee580f667b33a64b990981 - -This fixes a bug introduced in 08ef47ca ("pppd: Make MSCHAP-v2 cope better with packet loss"). - -We didn't merge 08ef47ca ;-) - - -2014-08-01 - winbind plugin: Add -DMPPE=1 to eliminate compiler warnings - 2b05e22c62095e97dd0a97e4b5588402c2185071 - -Linux plugin, not in the port. - - -2014-08-09 - Update README and patchlevel for 2.4.7 release - 6e8eaa7a78b31cdab2edf140a9c8afdb02ffaca5 - -Just release stuff. - - -2014-08-10 - abort on errors in subdir builds - 5e90783d11a59268e05f4cfb29ce2343b13e8ab2 - -Linux Makefile, not in the port. - - -2014-06-03 - pppd: add support for defaultroute-metric option - 35e5a569c988b1ff865b02a24d9a727a00db4da9 - -Only necessary for Linux, lwIP does not support route metrics. - - -2014-12-13 - scripts: Avoid killing wrong pppd - 67811a647d399db5d188a242827760615a0f86b5 - -pppd helper script, not in the port. - - -2014-12-20 - pppd: Fix sign-extension when displaying bytes in octal - 5e8c3cb256a7e86e3572a82a75d51c6850efdbdc - -Merged 2016-07-02. - - -2015-03-01 - Suppress false error message on PPPoE disconnect - 219aac3b53d0827549377f1bfe22853ee52d4405 - -PPPoE plugin, not in the port. - - -2015-03-01 - Send PADT on PPPoE disconnect - cd2c14f998c57bbe6a01dc5854f2763c0d7f31fb - -PPPoE plugin, not in the port. And our PPPoE implementation already does -that: pppoe_disconnect() calls pppoe_send_padt(). - - -2015-08-14 - pppd: ipxcp: Prevent buffer overrun on remote router name - fe149de624f96629a7f46732055d8f718c74b856 - -We never ported IPX support. lwIP does not support IPX. - - -2015-03-25 - pppd: Fix ccp_options.mppe type - 234edab99a6bb250cc9ecd384cca27b0c8b475ce - -We found that while working on MPPE support in lwIP, that's our patch ;-) - - -2015-03-24 - pppd: Fix ccp_cilen calculated size if both deflate_correct and deflate_draft are enabled - 094cb8ae4c61db225e67fedadb4964f846dd0c27 - -We found that while working on MPPE support in lwIP, that's our patch ;-) - - -2015-08-14 - Merge branch 'master' of https://github.com/ncopa/ppp - 3a5c9a8fbc8970375cd881151d44e4b6fe249c6a - -Merge commit, we don't care. - - -2015-08-14 - Merge branch 'master' of git://github.com/vapier/ppp - 912e4fc6665aca188dced7ea7fdc663ce5a2dd24 - -Merge commit, we don't care. - - -2015-08-14 - Merge branch 'bug_fix' of git://github.com/radaiming/ppp - dfd33d7f526ecd7b39dd1bba8101260d02af5ebb - -Merge commit, we don't care. - - -2015-08-14 - Merge branch 'master' of git://github.com/pprindeville/ppp - aa4a985f6114d08cf4e47634fb6325da71016473 - -Merge commit, we don't care. - - -2015-08-14 - Merge branch 'no-error-on-already-closed' of git://github.com/farnz/ppp - 6edf252483b30dbcdcc5059f01831455365d5b6e - -Merge commit, we don't care. - - -2015-08-14 - Merge branch 'send-padt-on-disconnect' of git://github.com/farnz/ppp - 84684243d651f55f6df69d2a6707b52fbbe62bb9 - -Merge commit, we don't care. diff --git a/third_party/lwip/repo/lwip/src/netif/ppp/auth.c b/third_party/lwip/repo/lwip/src/netif/ppp/auth.c deleted file mode 100644 index c8673ad0fb7cdc..00000000000000 --- a/third_party/lwip/repo/lwip/src/netif/ppp/auth.c +++ /dev/null @@ -1,2510 +0,0 @@ -/* - * auth.c - PPP authentication and phase control. - * - * Copyright (c) 1993-2002 Paul Mackerras. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. The name(s) of the authors of this software must not be used to - * endorse or promote products derived from this software without - * prior written permission. - * - * 3. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Paul Mackerras - * ". - * - * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * Derived from main.c, which is: - * - * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name "Carnegie Mellon University" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For permission or any legal - * details, please contact - * Office of Technology Transfer - * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu - * - * 4. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Computing Services - * at Carnegie Mellon University (http://www.cmu.edu/computing/)." - * - * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE - * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#if 0 /* UNUSED */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#if defined(_PATH_LASTLOG) && defined(__linux__) -#include -#endif - -#include -#include -#include - -#ifdef HAS_SHADOW -#include -#ifndef PW_PPP -#define PW_PPP PW_LOGIN -#endif -#endif - -#include -#endif /* UNUSED */ - -#include "netif/ppp/ppp_impl.h" - -#include "netif/ppp/fsm.h" -#include "netif/ppp/lcp.h" -#if CCP_SUPPORT -#include "netif/ppp/ccp.h" -#endif /* CCP_SUPPORT */ -#if ECP_SUPPORT -#include "netif/ppp/ecp.h" -#endif /* ECP_SUPPORT */ -#include "netif/ppp/ipcp.h" -#if PAP_SUPPORT -#include "netif/ppp/upap.h" -#endif /* PAP_SUPPORT */ -#if CHAP_SUPPORT -#include "netif/ppp/chap-new.h" -#endif /* CHAP_SUPPORT */ -#if EAP_SUPPORT -#include "netif/ppp/eap.h" -#endif /* EAP_SUPPORT */ -#if CBCP_SUPPORT -#include "netif/ppp/cbcp.h" -#endif - -#if 0 /* UNUSED */ -#include "session.h" -#endif /* UNUSED */ - -#if 0 /* UNUSED */ -/* Bits in scan_authfile return value */ -#define NONWILD_SERVER 1 -#define NONWILD_CLIENT 2 - -#define ISWILD(word) (word[0] == '*' && word[1] == 0) -#endif /* UNUSED */ - -#if 0 /* UNUSED */ -/* List of addresses which the peer may use. */ -static struct permitted_ip *addresses[NUM_PPP]; - -/* Wordlist giving addresses which the peer may use - without authenticating itself. */ -static struct wordlist *noauth_addrs; - -/* Remote telephone number, if available */ -char remote_number[MAXNAMELEN]; - -/* Wordlist giving remote telephone numbers which may connect. */ -static struct wordlist *permitted_numbers; - -/* Extra options to apply, from the secrets file entry for the peer. */ -static struct wordlist *extra_options; -#endif /* UNUSED */ - -#if 0 /* UNUSED */ -/* Set if we require authentication only because we have a default route. */ -static bool default_auth; - -/* Hook to enable a plugin to control the idle time limit */ -int (*idle_time_hook) (struct ppp_idle *) = NULL; - -/* Hook for a plugin to say whether we can possibly authenticate any peer */ -int (*pap_check_hook) (void) = NULL; - -/* Hook for a plugin to check the PAP user and password */ -int (*pap_auth_hook) (char *user, char *passwd, char **msgp, - struct wordlist **paddrs, - struct wordlist **popts) = NULL; - -/* Hook for a plugin to know about the PAP user logout */ -void (*pap_logout_hook) (void) = NULL; - -/* Hook for a plugin to get the PAP password for authenticating us */ -int (*pap_passwd_hook) (char *user, char *passwd) = NULL; - -/* Hook for a plugin to say if we can possibly authenticate a peer using CHAP */ -int (*chap_check_hook) (void) = NULL; - -/* Hook for a plugin to get the CHAP password for authenticating us */ -int (*chap_passwd_hook) (char *user, char *passwd) = NULL; - -/* Hook for a plugin to say whether it is OK if the peer - refuses to authenticate. */ -int (*null_auth_hook) (struct wordlist **paddrs, - struct wordlist **popts) = NULL; - -int (*allowed_address_hook) (u32_t addr) = NULL; -#endif /* UNUSED */ - -#ifdef HAVE_MULTILINK -/* Hook for plugin to hear when an interface joins a multilink bundle */ -void (*multilink_join_hook) (void) = NULL; -#endif - -#if PPP_NOTIFY -/* A notifier for when the peer has authenticated itself, - and we are proceeding to the network phase. */ -struct notifier *auth_up_notifier = NULL; - -/* A notifier for when the link goes down. */ -struct notifier *link_down_notifier = NULL; -#endif /* PPP_NOTIFY */ - -/* - * Option variables. - */ -#if 0 /* MOVED TO ppp_settings */ -bool uselogin = 0; /* Use /etc/passwd for checking PAP */ -bool session_mgmt = 0; /* Do session management (login records) */ -bool cryptpap = 0; /* Passwords in pap-secrets are encrypted */ -bool refuse_pap = 0; /* Don't wanna auth. ourselves with PAP */ -bool refuse_chap = 0; /* Don't wanna auth. ourselves with CHAP */ -bool refuse_eap = 0; /* Don't wanna auth. ourselves with EAP */ -#if MSCHAP_SUPPORT -bool refuse_mschap = 0; /* Don't wanna auth. ourselves with MS-CHAP */ -bool refuse_mschap_v2 = 0; /* Don't wanna auth. ourselves with MS-CHAPv2 */ -#else /* MSCHAP_SUPPORT */ -bool refuse_mschap = 1; /* Don't wanna auth. ourselves with MS-CHAP */ -bool refuse_mschap_v2 = 1; /* Don't wanna auth. ourselves with MS-CHAPv2 */ -#endif /* MSCHAP_SUPPORT */ -bool usehostname = 0; /* Use hostname for our_name */ -bool auth_required = 0; /* Always require authentication from peer */ -bool allow_any_ip = 0; /* Allow peer to use any IP address */ -bool explicit_remote = 0; /* User specified explicit remote name */ -bool explicit_user = 0; /* Set if "user" option supplied */ -bool explicit_passwd = 0; /* Set if "password" option supplied */ -char remote_name[MAXNAMELEN]; /* Peer's name for authentication */ -static char *uafname; /* name of most recent +ua file */ - -extern char *crypt (const char *, const char *); -#endif /* UNUSED */ -/* Prototypes for procedures local to this file. */ - -static void network_phase(ppp_pcb *pcb); -#if PPP_IDLETIMELIMIT -static void check_idle(void *arg); -#endif /* PPP_IDLETIMELIMIT */ -#if PPP_MAXCONNECT -static void connect_time_expired(void *arg); -#endif /* PPP_MAXCONNECT */ -#if 0 /* UNUSED */ -static int null_login (int); -/* static int get_pap_passwd (char *); */ -static int have_pap_secret (int *); -static int have_chap_secret (char *, char *, int, int *); -static int have_srp_secret (char *client, char *server, int need_ip, - int *lacks_ipp); -static int ip_addr_check (u32_t, struct permitted_ip *); -static int scan_authfile (FILE *, char *, char *, char *, - struct wordlist **, struct wordlist **, - char *, int); -static void free_wordlist (struct wordlist *); -static void set_allowed_addrs (int, struct wordlist *, struct wordlist *); -static int some_ip_ok (struct wordlist *); -static int setupapfile (char **); -static int privgroup (char **); -static int set_noauth_addr (char **); -static int set_permitted_number (char **); -static void check_access (FILE *, char *); -static int wordlist_count (struct wordlist *); -#endif /* UNUSED */ - -#ifdef MAXOCTETS -static void check_maxoctets (void *); -#endif - -#if PPP_OPTIONS -/* - * Authentication-related options. - */ -option_t auth_options[] = { - { "auth", o_bool, &auth_required, - "Require authentication from peer", OPT_PRIO | 1 }, - { "noauth", o_bool, &auth_required, - "Don't require peer to authenticate", OPT_PRIOSUB | OPT_PRIV, - &allow_any_ip }, - { "require-pap", o_bool, &lcp_wantoptions[0].neg_upap, - "Require PAP authentication from peer", - OPT_PRIOSUB | 1, &auth_required }, - { "+pap", o_bool, &lcp_wantoptions[0].neg_upap, - "Require PAP authentication from peer", - OPT_ALIAS | OPT_PRIOSUB | 1, &auth_required }, - { "require-chap", o_bool, &auth_required, - "Require CHAP authentication from peer", - OPT_PRIOSUB | OPT_A2OR | MDTYPE_MD5, - &lcp_wantoptions[0].chap_mdtype }, - { "+chap", o_bool, &auth_required, - "Require CHAP authentication from peer", - OPT_ALIAS | OPT_PRIOSUB | OPT_A2OR | MDTYPE_MD5, - &lcp_wantoptions[0].chap_mdtype }, -#if MSCHAP_SUPPORT - { "require-mschap", o_bool, &auth_required, - "Require MS-CHAP authentication from peer", - OPT_PRIOSUB | OPT_A2OR | MDTYPE_MICROSOFT, - &lcp_wantoptions[0].chap_mdtype }, - { "+mschap", o_bool, &auth_required, - "Require MS-CHAP authentication from peer", - OPT_ALIAS | OPT_PRIOSUB | OPT_A2OR | MDTYPE_MICROSOFT, - &lcp_wantoptions[0].chap_mdtype }, - { "require-mschap-v2", o_bool, &auth_required, - "Require MS-CHAPv2 authentication from peer", - OPT_PRIOSUB | OPT_A2OR | MDTYPE_MICROSOFT_V2, - &lcp_wantoptions[0].chap_mdtype }, - { "+mschap-v2", o_bool, &auth_required, - "Require MS-CHAPv2 authentication from peer", - OPT_ALIAS | OPT_PRIOSUB | OPT_A2OR | MDTYPE_MICROSOFT_V2, - &lcp_wantoptions[0].chap_mdtype }, -#endif /* MSCHAP_SUPPORT */ -#if 0 - { "refuse-pap", o_bool, &refuse_pap, - "Don't agree to auth to peer with PAP", 1 }, - { "-pap", o_bool, &refuse_pap, - "Don't allow PAP authentication with peer", OPT_ALIAS | 1 }, - { "refuse-chap", o_bool, &refuse_chap, - "Don't agree to auth to peer with CHAP", - OPT_A2CLRB | MDTYPE_MD5, - &lcp_allowoptions[0].chap_mdtype }, - { "-chap", o_bool, &refuse_chap, - "Don't allow CHAP authentication with peer", - OPT_ALIAS | OPT_A2CLRB | MDTYPE_MD5, - &lcp_allowoptions[0].chap_mdtype }, -#endif -#if MSCHAP_SUPPORT -#if 0 - { "refuse-mschap", o_bool, &refuse_mschap, - "Don't agree to auth to peer with MS-CHAP", - OPT_A2CLRB | MDTYPE_MICROSOFT, - &lcp_allowoptions[0].chap_mdtype }, - { "-mschap", o_bool, &refuse_mschap, - "Don't allow MS-CHAP authentication with peer", - OPT_ALIAS | OPT_A2CLRB | MDTYPE_MICROSOFT, - &lcp_allowoptions[0].chap_mdtype }, - { "refuse-mschap-v2", o_bool, &refuse_mschap_v2, - "Don't agree to auth to peer with MS-CHAPv2", - OPT_A2CLRB | MDTYPE_MICROSOFT_V2, - &lcp_allowoptions[0].chap_mdtype }, - { "-mschap-v2", o_bool, &refuse_mschap_v2, - "Don't allow MS-CHAPv2 authentication with peer", - OPT_ALIAS | OPT_A2CLRB | MDTYPE_MICROSOFT_V2, - &lcp_allowoptions[0].chap_mdtype }, -#endif -#endif /* MSCHAP_SUPPORT*/ -#if EAP_SUPPORT - { "require-eap", o_bool, &lcp_wantoptions[0].neg_eap, - "Require EAP authentication from peer", OPT_PRIOSUB | 1, - &auth_required }, -#if 0 - { "refuse-eap", o_bool, &refuse_eap, - "Don't agree to authenticate to peer with EAP", 1 }, -#endif -#endif /* EAP_SUPPORT */ - { "name", o_string, our_name, - "Set local name for authentication", - OPT_PRIO | OPT_PRIV | OPT_STATIC, NULL, MAXNAMELEN }, - - { "+ua", o_special, (void *)setupapfile, - "Get PAP user and password from file", - OPT_PRIO | OPT_A2STRVAL, &uafname }, - -#if 0 - { "user", o_string, user, - "Set name for auth with peer", OPT_PRIO | OPT_STATIC, - &explicit_user, MAXNAMELEN }, - - { "password", o_string, passwd, - "Password for authenticating us to the peer", - OPT_PRIO | OPT_STATIC | OPT_HIDE, - &explicit_passwd, MAXSECRETLEN }, -#endif - - { "usehostname", o_bool, &usehostname, - "Must use hostname for authentication", 1 }, - - { "remotename", o_string, remote_name, - "Set remote name for authentication", OPT_PRIO | OPT_STATIC, - &explicit_remote, MAXNAMELEN }, - - { "login", o_bool, &uselogin, - "Use system password database for PAP", OPT_A2COPY | 1 , - &session_mgmt }, - { "enable-session", o_bool, &session_mgmt, - "Enable session accounting for remote peers", OPT_PRIV | 1 }, - - { "papcrypt", o_bool, &cryptpap, - "PAP passwords are encrypted", 1 }, - - { "privgroup", o_special, (void *)privgroup, - "Allow group members to use privileged options", OPT_PRIV | OPT_A2LIST }, - - { "allow-ip", o_special, (void *)set_noauth_addr, - "Set IP address(es) which can be used without authentication", - OPT_PRIV | OPT_A2LIST }, - - { "remotenumber", o_string, remote_number, - "Set remote telephone number for authentication", OPT_PRIO | OPT_STATIC, - NULL, MAXNAMELEN }, - - { "allow-number", o_special, (void *)set_permitted_number, - "Set telephone number(s) which are allowed to connect", - OPT_PRIV | OPT_A2LIST }, - - { NULL } -}; -#endif /* PPP_OPTIONS */ - -#if 0 /* UNUSED */ -/* - * setupapfile - specifies UPAP info for authenticating with peer. - */ -static int -setupapfile(argv) - char **argv; -{ - FILE *ufile; - int l; - uid_t euid; - char u[MAXNAMELEN], p[MAXSECRETLEN]; - char *fname; - - lcp_allowoptions[0].neg_upap = 1; - - /* open user info file */ - fname = strdup(*argv); - if (fname == NULL) - novm("+ua file name"); - euid = geteuid(); - if (seteuid(getuid()) == -1) { - option_error("unable to reset uid before opening %s: %m", fname); - return 0; - } - ufile = fopen(fname, "r"); - if (seteuid(euid) == -1) - fatal("unable to regain privileges: %m"); - if (ufile == NULL) { - option_error("unable to open user login data file %s", fname); - return 0; - } - check_access(ufile, fname); - uafname = fname; - - /* get username */ - if (fgets(u, MAXNAMELEN - 1, ufile) == NULL - || fgets(p, MAXSECRETLEN - 1, ufile) == NULL) { - fclose(ufile); - option_error("unable to read user login data file %s", fname); - return 0; - } - fclose(ufile); - - /* get rid of newlines */ - l = strlen(u); - if (l > 0 && u[l-1] == '\n') - u[l-1] = 0; - l = strlen(p); - if (l > 0 && p[l-1] == '\n') - p[l-1] = 0; - - if (override_value("user", option_priority, fname)) { - strlcpy(ppp_settings.user, u, sizeof(ppp_settings.user)); - explicit_user = 1; - } - if (override_value("passwd", option_priority, fname)) { - strlcpy(ppp_settings.passwd, p, sizeof(ppp_settings.passwd)); - explicit_passwd = 1; - } - - return (1); -} - -/* - * privgroup - allow members of the group to have privileged access. - */ -static int -privgroup(argv) - char **argv; -{ - struct group *g; - int i; - - g = getgrnam(*argv); - if (g == 0) { - option_error("group %s is unknown", *argv); - return 0; - } - for (i = 0; i < ngroups; ++i) { - if (groups[i] == g->gr_gid) { - privileged = 1; - break; - } - } - return 1; -} - - -/* - * set_noauth_addr - set address(es) that can be used without authentication. - * Equivalent to specifying an entry like `"" * "" addr' in pap-secrets. - */ -static int -set_noauth_addr(argv) - char **argv; -{ - char *addr = *argv; - int l = strlen(addr) + 1; - struct wordlist *wp; - - wp = (struct wordlist *) malloc(sizeof(struct wordlist) + l); - if (wp == NULL) - novm("allow-ip argument"); - wp->word = (char *) (wp + 1); - wp->next = noauth_addrs; - MEMCPY(wp->word, addr, l); - noauth_addrs = wp; - return 1; -} - - -/* - * set_permitted_number - set remote telephone number(s) that may connect. - */ -static int -set_permitted_number(argv) - char **argv; -{ - char *number = *argv; - int l = strlen(number) + 1; - struct wordlist *wp; - - wp = (struct wordlist *) malloc(sizeof(struct wordlist) + l); - if (wp == NULL) - novm("allow-number argument"); - wp->word = (char *) (wp + 1); - wp->next = permitted_numbers; - MEMCPY(wp->word, number, l); - permitted_numbers = wp; - return 1; -} -#endif - -/* - * An Open on LCP has requested a change from Dead to Establish phase. - */ -void link_required(ppp_pcb *pcb) { - LWIP_UNUSED_ARG(pcb); -} - -#if 0 -/* - * Bring the link up to the point of being able to do ppp. - */ -void start_link(unit) - int unit; -{ - ppp_pcb *pcb = &ppp_pcb_list[unit]; - char *msg; - - status = EXIT_NEGOTIATION_FAILED; - new_phase(pcb, PPP_PHASE_SERIALCONN); - - hungup = 0; - devfd = the_channel->connect(); - msg = "Connect script failed"; - if (devfd < 0) - goto fail; - - /* set up the serial device as a ppp interface */ - /* - * N.B. we used to do tdb_writelock/tdb_writeunlock around this - * (from establish_ppp to set_ifunit). However, we won't be - * doing the set_ifunit in multilink mode, which is the only time - * we need the atomicity that the tdb_writelock/tdb_writeunlock - * gives us. Thus we don't need the tdb_writelock/tdb_writeunlock. - */ - fd_ppp = the_channel->establish_ppp(devfd); - msg = "ppp establishment failed"; - if (fd_ppp < 0) { - status = EXIT_FATAL_ERROR; - goto disconnect; - } - - if (!demand && ifunit >= 0) - set_ifunit(1); - - /* - * Start opening the connection and wait for - * incoming events (reply, timeout, etc.). - */ - if (ifunit >= 0) - ppp_notice("Connect: %s <--> %s", ifname, ppp_devnam); - else - ppp_notice("Starting negotiation on %s", ppp_devnam); - add_fd(fd_ppp); - - new_phase(pcb, PPP_PHASE_ESTABLISH); - - lcp_lowerup(pcb); - return; - - disconnect: - new_phase(pcb, PPP_PHASE_DISCONNECT); - if (the_channel->disconnect) - the_channel->disconnect(); - - fail: - new_phase(pcb, PPP_PHASE_DEAD); - if (the_channel->cleanup) - (*the_channel->cleanup)(); -} -#endif - -/* - * LCP has terminated the link; go to the Dead phase and take the - * physical layer down. - */ -void link_terminated(ppp_pcb *pcb) { - if (pcb->phase == PPP_PHASE_DEAD -#ifdef HAVE_MULTILINK - || pcb->phase == PPP_PHASE_MASTER -#endif /* HAVE_MULTILINK */ - ) - return; - new_phase(pcb, PPP_PHASE_DISCONNECT); - -#if 0 /* UNUSED */ - if (pap_logout_hook) { - pap_logout_hook(); - } - session_end(devnam); -#endif /* UNUSED */ - - if (!doing_multilink) { - ppp_notice("Connection terminated."); -#if PPP_STATS_SUPPORT - print_link_stats(); -#endif /* PPP_STATS_SUPPORT */ - } else - ppp_notice("Link terminated."); - - lcp_lowerdown(pcb); - - ppp_link_terminated(pcb); -#if 0 - /* - * Delete pid files before disestablishing ppp. Otherwise it - * can happen that another pppd gets the same unit and then - * we delete its pid file. - */ - if (!doing_multilink && !demand) - remove_pidfiles(); - - /* - * If we may want to bring the link up again, transfer - * the ppp unit back to the loopback. Set the - * real serial device back to its normal mode of operation. - */ - if (fd_ppp >= 0) { - remove_fd(fd_ppp); - clean_check(); - the_channel->disestablish_ppp(devfd); - if (doing_multilink) - mp_exit_bundle(); - fd_ppp = -1; - } - if (!hungup) - lcp_lowerdown(pcb); - if (!doing_multilink && !demand) - script_unsetenv("IFNAME"); - - /* - * Run disconnector script, if requested. - * XXX we may not be able to do this if the line has hung up! - */ - if (devfd >= 0 && the_channel->disconnect) { - the_channel->disconnect(); - devfd = -1; - } - if (the_channel->cleanup) - (*the_channel->cleanup)(); - - if (doing_multilink && multilink_master) { - if (!bundle_terminating) - new_phase(pcb, PPP_PHASE_MASTER); - else - mp_bundle_terminated(); - } else - new_phase(pcb, PPP_PHASE_DEAD); -#endif -} - -/* - * LCP has gone down; it will either die or try to re-establish. - */ -void link_down(ppp_pcb *pcb) { -#if PPP_NOTIFY - notify(link_down_notifier, 0); -#endif /* PPP_NOTIFY */ - - if (!doing_multilink) { - upper_layers_down(pcb); - if (pcb->phase != PPP_PHASE_DEAD -#ifdef HAVE_MULTILINK - && pcb->phase != PPP_PHASE_MASTER -#endif /* HAVE_MULTILINK */ - ) - new_phase(pcb, PPP_PHASE_ESTABLISH); - } - /* XXX if doing_multilink, should do something to stop - network-layer traffic on the link */ -} - -void upper_layers_down(ppp_pcb *pcb) { - int i; - const struct protent *protp; - - for (i = 0; (protp = protocols[i]) != NULL; ++i) { - if (protp->protocol != PPP_LCP && protp->lowerdown != NULL) - (*protp->lowerdown)(pcb); - if (protp->protocol < 0xC000 && protp->close != NULL) - (*protp->close)(pcb, "LCP down"); - } - pcb->num_np_open = 0; - pcb->num_np_up = 0; -} - -/* - * The link is established. - * Proceed to the Dead, Authenticate or Network phase as appropriate. - */ -void link_established(ppp_pcb *pcb) { -#if PPP_AUTH_SUPPORT - int auth; -#if PPP_SERVER -#if PAP_SUPPORT - lcp_options *wo = &pcb->lcp_wantoptions; -#endif /* PAP_SUPPORT */ - lcp_options *go = &pcb->lcp_gotoptions; -#endif /* PPP_SERVER */ - lcp_options *ho = &pcb->lcp_hisoptions; -#endif /* PPP_AUTH_SUPPORT */ - int i; - const struct protent *protp; - - /* - * Tell higher-level protocols that LCP is up. - */ - if (!doing_multilink) { - for (i = 0; (protp = protocols[i]) != NULL; ++i) - if (protp->protocol != PPP_LCP - && protp->lowerup != NULL) - (*protp->lowerup)(pcb); - } - -#if PPP_AUTH_SUPPORT -#if PPP_SERVER -#if PPP_ALLOWED_ADDRS - if (!auth_required && noauth_addrs != NULL) - set_allowed_addrs(unit, NULL, NULL); -#endif /* PPP_ALLOWED_ADDRS */ - - if (pcb->settings.auth_required && !(0 -#if PAP_SUPPORT - || go->neg_upap -#endif /* PAP_SUPPORT */ -#if CHAP_SUPPORT - || go->neg_chap -#endif /* CHAP_SUPPORT */ -#if EAP_SUPPORT - || go->neg_eap -#endif /* EAP_SUPPORT */ - )) { - -#if PPP_ALLOWED_ADDRS - /* - * We wanted the peer to authenticate itself, and it refused: - * if we have some address(es) it can use without auth, fine, - * otherwise treat it as though it authenticated with PAP using - * a username of "" and a password of "". If that's not OK, - * boot it out. - */ - if (noauth_addrs != NULL) { - set_allowed_addrs(unit, NULL, NULL); - } else -#endif /* PPP_ALLOWED_ADDRS */ - if (!pcb->settings.null_login -#if PAP_SUPPORT - || !wo->neg_upap -#endif /* PAP_SUPPORT */ - ) { - ppp_warn("peer refused to authenticate: terminating link"); -#if 0 /* UNUSED */ - status = EXIT_PEER_AUTH_FAILED; -#endif /* UNUSED */ - pcb->err_code = PPPERR_AUTHFAIL; - lcp_close(pcb, "peer refused to authenticate"); - return; - } - } -#endif /* PPP_SERVER */ - - new_phase(pcb, PPP_PHASE_AUTHENTICATE); - auth = 0; -#if PPP_SERVER -#if EAP_SUPPORT - if (go->neg_eap) { - eap_authpeer(pcb, PPP_OUR_NAME); - auth |= EAP_PEER; - } else -#endif /* EAP_SUPPORT */ -#if CHAP_SUPPORT - if (go->neg_chap) { - chap_auth_peer(pcb, PPP_OUR_NAME, CHAP_DIGEST(go->chap_mdtype)); - auth |= CHAP_PEER; - } else -#endif /* CHAP_SUPPORT */ -#if PAP_SUPPORT - if (go->neg_upap) { - upap_authpeer(pcb); - auth |= PAP_PEER; - } else -#endif /* PAP_SUPPORT */ - {} -#endif /* PPP_SERVER */ - -#if EAP_SUPPORT - if (ho->neg_eap) { - eap_authwithpeer(pcb, pcb->settings.user); - auth |= EAP_WITHPEER; - } else -#endif /* EAP_SUPPORT */ -#if CHAP_SUPPORT - if (ho->neg_chap) { - chap_auth_with_peer(pcb, pcb->settings.user, CHAP_DIGEST(ho->chap_mdtype)); - auth |= CHAP_WITHPEER; - } else -#endif /* CHAP_SUPPORT */ -#if PAP_SUPPORT - if (ho->neg_upap) { - upap_authwithpeer(pcb, pcb->settings.user, pcb->settings.passwd); - auth |= PAP_WITHPEER; - } else -#endif /* PAP_SUPPORT */ - {} - - pcb->auth_pending = auth; - pcb->auth_done = 0; - - if (!auth) -#endif /* PPP_AUTH_SUPPORT */ - network_phase(pcb); -} - -/* - * Proceed to the network phase. - */ -static void network_phase(ppp_pcb *pcb) { -#if CBCP_SUPPORT - ppp_pcb *pcb = &ppp_pcb_list[unit]; -#endif -#if 0 /* UNUSED */ - lcp_options *go = &lcp_gotoptions[unit]; -#endif /* UNUSED */ - -#if 0 /* UNUSED */ - /* Log calling number. */ - if (*remote_number) - ppp_notice("peer from calling number %q authorized", remote_number); -#endif /* UNUSED */ - -#if PPP_NOTIFY - /* - * If the peer had to authenticate, notify it now. - */ - if (0 -#if CHAP_SUPPORT - || go->neg_chap -#endif /* CHAP_SUPPORT */ -#if PAP_SUPPORT - || go->neg_upap -#endif /* PAP_SUPPORT */ -#if EAP_SUPPORT - || go->neg_eap -#endif /* EAP_SUPPORT */ - ) { - notify(auth_up_notifier, 0); - } -#endif /* PPP_NOTIFY */ - -#if CBCP_SUPPORT - /* - * If we negotiated callback, do it now. - */ - if (go->neg_cbcp) { - new_phase(pcb, PPP_PHASE_CALLBACK); - (*cbcp_protent.open)(pcb); - return; - } -#endif - -#if PPP_OPTIONS - /* - * Process extra options from the secrets file - */ - if (extra_options) { - options_from_list(extra_options, 1); - free_wordlist(extra_options); - extra_options = 0; - } -#endif /* PPP_OPTIONS */ - start_networks(pcb); -} - -void start_networks(ppp_pcb *pcb) { -#if CCP_SUPPORT || ECP_SUPPORT - int i; - const struct protent *protp; -#endif /* CCP_SUPPORT || ECP_SUPPORT */ - - new_phase(pcb, PPP_PHASE_NETWORK); - -#ifdef HAVE_MULTILINK - if (multilink) { - if (mp_join_bundle()) { - if (multilink_join_hook) - (*multilink_join_hook)(); - if (updetach && !nodetach) - detach(); - return; - } - } -#endif /* HAVE_MULTILINK */ - -#ifdef PPP_FILTER - if (!demand) - set_filters(&pass_filter, &active_filter); -#endif -#if CCP_SUPPORT || ECP_SUPPORT - /* Start CCP and ECP */ - for (i = 0; (protp = protocols[i]) != NULL; ++i) - if ( - (0 -#if ECP_SUPPORT - || protp->protocol == PPP_ECP -#endif /* ECP_SUPPORT */ -#if CCP_SUPPORT - || protp->protocol == PPP_CCP -#endif /* CCP_SUPPORT */ - ) - && protp->open != NULL) - (*protp->open)(pcb); -#endif /* CCP_SUPPORT || ECP_SUPPORT */ - - /* - * Bring up other network protocols iff encryption is not required. - */ - if (1 -#if ECP_SUPPORT - && !ecp_gotoptions[unit].required -#endif /* ECP_SUPPORT */ -#if MPPE_SUPPORT - && !pcb->ccp_gotoptions.mppe -#endif /* MPPE_SUPPORT */ - ) - continue_networks(pcb); -} - -void continue_networks(ppp_pcb *pcb) { - int i; - const struct protent *protp; - - /* - * Start the "real" network protocols. - */ - for (i = 0; (protp = protocols[i]) != NULL; ++i) - if (protp->protocol < 0xC000 -#if CCP_SUPPORT - && protp->protocol != PPP_CCP -#endif /* CCP_SUPPORT */ -#if ECP_SUPPORT - && protp->protocol != PPP_ECP -#endif /* ECP_SUPPORT */ - && protp->open != NULL) { - (*protp->open)(pcb); - ++pcb->num_np_open; - } - - if (pcb->num_np_open == 0) - /* nothing to do */ - lcp_close(pcb, "No network protocols running"); -} - -#if PPP_AUTH_SUPPORT -#if PPP_SERVER -/* - * auth_check_passwd - Check the user name and passwd against configuration. - * - * returns: - * 0: Authentication failed. - * 1: Authentication succeeded. - * In either case, msg points to an appropriate message and msglen to the message len. - */ -int auth_check_passwd(ppp_pcb *pcb, char *auser, int userlen, char *apasswd, int passwdlen, const char **msg, int *msglen) { - int secretuserlen; - int secretpasswdlen; - - if (pcb->settings.user && pcb->settings.passwd) { - secretuserlen = (int)strlen(pcb->settings.user); - secretpasswdlen = (int)strlen(pcb->settings.passwd); - if (secretuserlen == userlen - && secretpasswdlen == passwdlen - && !memcmp(auser, pcb->settings.user, userlen) - && !memcmp(apasswd, pcb->settings.passwd, passwdlen) ) { - *msg = "Login ok"; - *msglen = sizeof("Login ok")-1; - return 1; - } - } - - *msg = "Login incorrect"; - *msglen = sizeof("Login incorrect")-1; - return 0; -} - -/* - * The peer has failed to authenticate himself using `protocol'. - */ -void auth_peer_fail(ppp_pcb *pcb, int protocol) { - LWIP_UNUSED_ARG(protocol); - /* - * Authentication failure: take the link down - */ -#if 0 /* UNUSED */ - status = EXIT_PEER_AUTH_FAILED; -#endif /* UNUSED */ - pcb->err_code = PPPERR_AUTHFAIL; - lcp_close(pcb, "Authentication failed"); -} - -/* - * The peer has been successfully authenticated using `protocol'. - */ -void auth_peer_success(ppp_pcb *pcb, int protocol, int prot_flavor, const char *name, int namelen) { - int bit; -#ifndef HAVE_MULTILINK - LWIP_UNUSED_ARG(name); - LWIP_UNUSED_ARG(namelen); -#endif /* HAVE_MULTILINK */ - - switch (protocol) { -#if CHAP_SUPPORT - case PPP_CHAP: - bit = CHAP_PEER; - switch (prot_flavor) { - case CHAP_MD5: - bit |= CHAP_MD5_PEER; - break; -#if MSCHAP_SUPPORT - case CHAP_MICROSOFT: - bit |= CHAP_MS_PEER; - break; - case CHAP_MICROSOFT_V2: - bit |= CHAP_MS2_PEER; - break; -#endif /* MSCHAP_SUPPORT */ - default: - break; - } - break; -#endif /* CHAP_SUPPORT */ -#if PAP_SUPPORT - case PPP_PAP: - bit = PAP_PEER; - break; -#endif /* PAP_SUPPORT */ -#if EAP_SUPPORT - case PPP_EAP: - bit = EAP_PEER; - break; -#endif /* EAP_SUPPORT */ - default: - ppp_warn("auth_peer_success: unknown protocol %x", protocol); - return; - } - -#ifdef HAVE_MULTILINK - /* - * Save the authenticated name of the peer for later. - */ - if (namelen > (int)sizeof(pcb->peer_authname) - 1) - namelen = (int)sizeof(pcb->peer_authname) - 1; - MEMCPY(pcb->peer_authname, name, namelen); - pcb->peer_authname[namelen] = 0; -#endif /* HAVE_MULTILINK */ -#if 0 /* UNUSED */ - script_setenv("PEERNAME", , 0); -#endif /* UNUSED */ - - /* Save the authentication method for later. */ - pcb->auth_done |= bit; - - /* - * If there is no more authentication still to be done, - * proceed to the network (or callback) phase. - */ - if ((pcb->auth_pending &= ~bit) == 0) - network_phase(pcb); -} -#endif /* PPP_SERVER */ - -/* - * We have failed to authenticate ourselves to the peer using `protocol'. - */ -void auth_withpeer_fail(ppp_pcb *pcb, int protocol) { - LWIP_UNUSED_ARG(protocol); - /* - * We've failed to authenticate ourselves to our peer. - * - * Some servers keep sending CHAP challenges, but there - * is no point in persisting without any way to get updated - * authentication secrets. - * - * He'll probably take the link down, and there's not much - * we can do except wait for that. - */ - pcb->err_code = PPPERR_AUTHFAIL; - lcp_close(pcb, "Failed to authenticate ourselves to peer"); -} - -/* - * We have successfully authenticated ourselves with the peer using `protocol'. - */ -void auth_withpeer_success(ppp_pcb *pcb, int protocol, int prot_flavor) { - int bit; - const char *prot = ""; - - switch (protocol) { -#if CHAP_SUPPORT - case PPP_CHAP: - bit = CHAP_WITHPEER; - prot = "CHAP"; - switch (prot_flavor) { - case CHAP_MD5: - bit |= CHAP_MD5_WITHPEER; - break; -#if MSCHAP_SUPPORT - case CHAP_MICROSOFT: - bit |= CHAP_MS_WITHPEER; - break; - case CHAP_MICROSOFT_V2: - bit |= CHAP_MS2_WITHPEER; - break; -#endif /* MSCHAP_SUPPORT */ - default: - break; - } - break; -#endif /* CHAP_SUPPORT */ -#if PAP_SUPPORT - case PPP_PAP: - bit = PAP_WITHPEER; - prot = "PAP"; - break; -#endif /* PAP_SUPPORT */ -#if EAP_SUPPORT - case PPP_EAP: - bit = EAP_WITHPEER; - prot = "EAP"; - break; -#endif /* EAP_SUPPORT */ - default: - ppp_warn("auth_withpeer_success: unknown protocol %x", protocol); - bit = 0; - /* no break */ - } - - ppp_notice("%s authentication succeeded", prot); - - /* Save the authentication method for later. */ - pcb->auth_done |= bit; - - /* - * If there is no more authentication still being done, - * proceed to the network (or callback) phase. - */ - if ((pcb->auth_pending &= ~bit) == 0) - network_phase(pcb); -} -#endif /* PPP_AUTH_SUPPORT */ - - -/* - * np_up - a network protocol has come up. - */ -void np_up(ppp_pcb *pcb, int proto) { -#if PPP_IDLETIMELIMIT - int tlim; -#endif /* PPP_IDLETIMELIMIT */ - LWIP_UNUSED_ARG(proto); - - if (pcb->num_np_up == 0) { - /* - * At this point we consider that the link has come up successfully. - */ - new_phase(pcb, PPP_PHASE_RUNNING); - -#if PPP_IDLETIMELIMIT -#if 0 /* UNUSED */ - if (idle_time_hook != 0) - tlim = (*idle_time_hook)(NULL); - else -#endif /* UNUSED */ - tlim = pcb->settings.idle_time_limit; - if (tlim > 0) - TIMEOUT(check_idle, (void*)pcb, tlim); -#endif /* PPP_IDLETIMELIMIT */ - -#if PPP_MAXCONNECT - /* - * Set a timeout to close the connection once the maximum - * connect time has expired. - */ - if (pcb->settings.maxconnect > 0) - TIMEOUT(connect_time_expired, (void*)pcb, pcb->settings.maxconnect); -#endif /* PPP_MAXCONNECT */ - -#ifdef MAXOCTETS - if (maxoctets > 0) - TIMEOUT(check_maxoctets, NULL, maxoctets_timeout); -#endif - -#if 0 /* Unused */ - /* - * Detach now, if the updetach option was given. - */ - if (updetach && !nodetach) - detach(); -#endif /* Unused */ - } - ++pcb->num_np_up; -} - -/* - * np_down - a network protocol has gone down. - */ -void np_down(ppp_pcb *pcb, int proto) { - LWIP_UNUSED_ARG(proto); - if (--pcb->num_np_up == 0) { -#if PPP_IDLETIMELIMIT - UNTIMEOUT(check_idle, (void*)pcb); -#endif /* PPP_IDLETIMELIMIT */ -#if PPP_MAXCONNECT - UNTIMEOUT(connect_time_expired, NULL); -#endif /* PPP_MAXCONNECT */ -#ifdef MAXOCTETS - UNTIMEOUT(check_maxoctets, NULL); -#endif - new_phase(pcb, PPP_PHASE_NETWORK); - } -} - -/* - * np_finished - a network protocol has finished using the link. - */ -void np_finished(ppp_pcb *pcb, int proto) { - LWIP_UNUSED_ARG(proto); - if (--pcb->num_np_open <= 0) { - /* no further use for the link: shut up shop. */ - lcp_close(pcb, "No network protocols running"); - } -} - -#ifdef MAXOCTETS -static void -check_maxoctets(arg) - void *arg; -{ -#if PPP_STATS_SUPPORT - unsigned int used; - - update_link_stats(ifunit); - link_stats_valid=0; - - switch(maxoctets_dir) { - case PPP_OCTETS_DIRECTION_IN: - used = link_stats.bytes_in; - break; - case PPP_OCTETS_DIRECTION_OUT: - used = link_stats.bytes_out; - break; - case PPP_OCTETS_DIRECTION_MAXOVERAL: - case PPP_OCTETS_DIRECTION_MAXSESSION: - used = (link_stats.bytes_in > link_stats.bytes_out) ? link_stats.bytes_in : link_stats.bytes_out; - break; - default: - used = link_stats.bytes_in+link_stats.bytes_out; - break; - } - if (used > maxoctets) { - ppp_notice("Traffic limit reached. Limit: %u Used: %u", maxoctets, used); - status = EXIT_TRAFFIC_LIMIT; - lcp_close(pcb, "Traffic limit"); -#if 0 /* UNUSED */ - need_holdoff = 0; -#endif /* UNUSED */ - } else { - TIMEOUT(check_maxoctets, NULL, maxoctets_timeout); - } -#endif /* PPP_STATS_SUPPORT */ -} -#endif /* MAXOCTETS */ - -#if PPP_IDLETIMELIMIT -/* - * check_idle - check whether the link has been idle for long - * enough that we can shut it down. - */ -static void check_idle(void *arg) { - ppp_pcb *pcb = (ppp_pcb*)arg; - struct ppp_idle idle; - time_t itime; - int tlim; - - if (!get_idle_time(pcb, &idle)) - return; -#if 0 /* UNUSED */ - if (idle_time_hook != 0) { - tlim = idle_time_hook(&idle); - } else { -#endif /* UNUSED */ - itime = LWIP_MIN(idle.xmit_idle, idle.recv_idle); - tlim = pcb->settings.idle_time_limit - itime; -#if 0 /* UNUSED */ - } -#endif /* UNUSED */ - if (tlim <= 0) { - /* link is idle: shut it down. */ - ppp_notice("Terminating connection due to lack of activity."); - pcb->err_code = PPPERR_IDLETIMEOUT; - lcp_close(pcb, "Link inactive"); -#if 0 /* UNUSED */ - need_holdoff = 0; -#endif /* UNUSED */ - } else { - TIMEOUT(check_idle, (void*)pcb, tlim); - } -} -#endif /* PPP_IDLETIMELIMIT */ - -#if PPP_MAXCONNECT -/* - * connect_time_expired - log a message and close the connection. - */ -static void connect_time_expired(void *arg) { - ppp_pcb *pcb = (ppp_pcb*)arg; - ppp_info("Connect time expired"); - pcb->err_code = PPPERR_CONNECTTIME; - lcp_close(pcb, "Connect time expired"); /* Close connection */ -} -#endif /* PPP_MAXCONNECT */ - -#if PPP_OPTIONS -/* - * auth_check_options - called to check authentication options. - */ -void -auth_check_options() -{ - lcp_options *wo = &lcp_wantoptions[0]; - int can_auth; - int lacks_ip; - - /* Default our_name to hostname, and user to our_name */ - if (our_name[0] == 0 || usehostname) - strlcpy(our_name, hostname, sizeof(our_name)); - /* If a blank username was explicitly given as an option, trust - the user and don't use our_name */ - if (ppp_settings.user[0] == 0 && !explicit_user) - strlcpy(ppp_settings.user, our_name, sizeof(ppp_settings.user)); - - /* - * If we have a default route, require the peer to authenticate - * unless the noauth option was given or the real user is root. - */ - if (!auth_required && !allow_any_ip && have_route_to(0) && !privileged) { - auth_required = 1; - default_auth = 1; - } - -#if CHAP_SUPPORT - /* If we selected any CHAP flavors, we should probably negotiate it. :-) */ - if (wo->chap_mdtype) - wo->neg_chap = 1; -#endif /* CHAP_SUPPORT */ - - /* If authentication is required, ask peer for CHAP, PAP, or EAP. */ - if (auth_required) { - allow_any_ip = 0; - if (1 -#if CHAP_SUPPORT - && !wo->neg_chap -#endif /* CHAP_SUPPORT */ -#if PAP_SUPPORT - && !wo->neg_upap -#endif /* PAP_SUPPORT */ -#if EAP_SUPPORT - && !wo->neg_eap -#endif /* EAP_SUPPORT */ - ) { -#if CHAP_SUPPORT - wo->neg_chap = CHAP_MDTYPE_SUPPORTED != MDTYPE_NONE; - wo->chap_mdtype = CHAP_MDTYPE_SUPPORTED; -#endif /* CHAP_SUPPORT */ -#if PAP_SUPPORT - wo->neg_upap = 1; -#endif /* PAP_SUPPORT */ -#if EAP_SUPPORT - wo->neg_eap = 1; -#endif /* EAP_SUPPORT */ - } - } else { -#if CHAP_SUPPORT - wo->neg_chap = 0; - wo->chap_mdtype = MDTYPE_NONE; -#endif /* CHAP_SUPPORT */ -#if PAP_SUPPORT - wo->neg_upap = 0; -#endif /* PAP_SUPPORT */ -#if EAP_SUPPORT - wo->neg_eap = 0; -#endif /* EAP_SUPPORT */ - } - - /* - * Check whether we have appropriate secrets to use - * to authenticate the peer. Note that EAP can authenticate by way - * of a CHAP-like exchanges as well as SRP. - */ - lacks_ip = 0; -#if PAP_SUPPORT - can_auth = wo->neg_upap && (uselogin || have_pap_secret(&lacks_ip)); -#else - can_auth = 0; -#endif /* PAP_SUPPORT */ - if (!can_auth && (0 -#if CHAP_SUPPORT - || wo->neg_chap -#endif /* CHAP_SUPPORT */ -#if EAP_SUPPORT - || wo->neg_eap -#endif /* EAP_SUPPORT */ - )) { -#if CHAP_SUPPORT - can_auth = have_chap_secret((explicit_remote? remote_name: NULL), - our_name, 1, &lacks_ip); -#else - can_auth = 0; -#endif - } - if (!can_auth -#if EAP_SUPPORT - && wo->neg_eap -#endif /* EAP_SUPPORT */ - ) { - can_auth = have_srp_secret((explicit_remote? remote_name: NULL), - our_name, 1, &lacks_ip); - } - - if (auth_required && !can_auth && noauth_addrs == NULL) { - if (default_auth) { - option_error( -"By default the remote system is required to authenticate itself"); - option_error( -"(because this system has a default route to the internet)"); - } else if (explicit_remote) - option_error( -"The remote system (%s) is required to authenticate itself", - remote_name); - else - option_error( -"The remote system is required to authenticate itself"); - option_error( -"but I couldn't find any suitable secret (password) for it to use to do so."); - if (lacks_ip) - option_error( -"(None of the available passwords would let it use an IP address.)"); - - exit(1); - } - - /* - * Early check for remote number authorization. - */ - if (!auth_number()) { - ppp_warn("calling number %q is not authorized", remote_number); - exit(EXIT_CNID_AUTH_FAILED); - } -} -#endif /* PPP_OPTIONS */ - -#if 0 /* UNUSED */ -/* - * auth_reset - called when LCP is starting negotiations to recheck - * authentication options, i.e. whether we have appropriate secrets - * to use for authenticating ourselves and/or the peer. - */ -void -auth_reset(unit) - int unit; -{ - lcp_options *go = &lcp_gotoptions[unit]; - lcp_options *ao = &lcp_allowoptions[unit]; - int hadchap; - - hadchap = -1; - ao->neg_upap = !refuse_pap && (passwd[0] != 0 || get_pap_passwd(NULL)); - ao->neg_chap = (!refuse_chap || !refuse_mschap || !refuse_mschap_v2) - && (passwd[0] != 0 || - (hadchap = have_chap_secret(user, (explicit_remote? remote_name: - NULL), 0, NULL))); - ao->neg_eap = !refuse_eap && ( - passwd[0] != 0 || - (hadchap == 1 || (hadchap == -1 && have_chap_secret(user, - (explicit_remote? remote_name: NULL), 0, NULL))) || - have_srp_secret(user, (explicit_remote? remote_name: NULL), 0, NULL)); - - hadchap = -1; - if (go->neg_upap && !uselogin && !have_pap_secret(NULL)) - go->neg_upap = 0; - if (go->neg_chap) { - if (!(hadchap = have_chap_secret((explicit_remote? remote_name: NULL), - our_name, 1, NULL))) - go->neg_chap = 0; - } - if (go->neg_eap && - (hadchap == 0 || (hadchap == -1 && - !have_chap_secret((explicit_remote? remote_name: NULL), our_name, - 1, NULL))) && - !have_srp_secret((explicit_remote? remote_name: NULL), our_name, 1, - NULL)) - go->neg_eap = 0; -} - -/* - * check_passwd - Check the user name and passwd against the PAP secrets - * file. If requested, also check against the system password database, - * and login the user if OK. - * - * returns: - * UPAP_AUTHNAK: Authentication failed. - * UPAP_AUTHACK: Authentication succeeded. - * In either case, msg points to an appropriate message. - */ -int -check_passwd(unit, auser, userlen, apasswd, passwdlen, msg) - int unit; - char *auser; - int userlen; - char *apasswd; - int passwdlen; - char **msg; -{ - return UPAP_AUTHNAK; - int ret; - char *filename; - FILE *f; - struct wordlist *addrs = NULL, *opts = NULL; - char passwd[256], user[256]; - char secret[MAXWORDLEN]; - static int attempts = 0; - - /* - * Make copies of apasswd and auser, then null-terminate them. - * If there are unprintable characters in the password, make - * them visible. - */ - slprintf(ppp_settings.passwd, sizeof(ppp_settings.passwd), "%.*v", passwdlen, apasswd); - slprintf(ppp_settings.user, sizeof(ppp_settings.user), "%.*v", userlen, auser); - *msg = ""; - - /* - * Check if a plugin wants to handle this. - */ - if (pap_auth_hook) { - ret = (*pap_auth_hook)(ppp_settings.user, ppp_settings.passwd, msg, &addrs, &opts); - if (ret >= 0) { - /* note: set_allowed_addrs() saves opts (but not addrs): - don't free it! */ - if (ret) - set_allowed_addrs(unit, addrs, opts); - else if (opts != 0) - free_wordlist(opts); - if (addrs != 0) - free_wordlist(addrs); - BZERO(ppp_settings.passwd, sizeof(ppp_settings.passwd)); - return ret? UPAP_AUTHACK: UPAP_AUTHNAK; - } - } - - /* - * Open the file of pap secrets and scan for a suitable secret - * for authenticating this user. - */ - filename = _PATH_UPAPFILE; - addrs = opts = NULL; - ret = UPAP_AUTHNAK; - f = fopen(filename, "r"); - if (f == NULL) { - ppp_error("Can't open PAP password file %s: %m", filename); - - } else { - check_access(f, filename); - if (scan_authfile(f, ppp_settings.user, our_name, secret, &addrs, &opts, filename, 0) < 0) { - ppp_warn("no PAP secret found for %s", user); - } else { - /* - * If the secret is "@login", it means to check - * the password against the login database. - */ - int login_secret = strcmp(secret, "@login") == 0; - ret = UPAP_AUTHACK; - if (uselogin || login_secret) { - /* login option or secret is @login */ - if (session_full(ppp_settings.user, ppp_settings.passwd, devnam, msg) == 0) { - ret = UPAP_AUTHNAK; - } - } else if (session_mgmt) { - if (session_check(ppp_settings.user, NULL, devnam, NULL) == 0) { - ppp_warn("Peer %q failed PAP Session verification", user); - ret = UPAP_AUTHNAK; - } - } - if (secret[0] != 0 && !login_secret) { - /* password given in pap-secrets - must match */ - if ((cryptpap || strcmp(ppp_settings.passwd, secret) != 0) - && strcmp(crypt(ppp_settings.passwd, secret), secret) != 0) - ret = UPAP_AUTHNAK; - } - } - fclose(f); - } - - if (ret == UPAP_AUTHNAK) { - if (**msg == 0) - *msg = "Login incorrect"; - /* - * XXX can we ever get here more than once?? - * Frustrate passwd stealer programs. - * Allow 10 tries, but start backing off after 3 (stolen from login). - * On 10'th, drop the connection. - */ - if (attempts++ >= 10) { - ppp_warn("%d LOGIN FAILURES ON %s, %s", attempts, devnam, user); - lcp_close(pcb, "login failed"); - } - if (attempts > 3) - sleep((u_int) (attempts - 3) * 5); - if (opts != NULL) - free_wordlist(opts); - - } else { - attempts = 0; /* Reset count */ - if (**msg == 0) - *msg = "Login ok"; - set_allowed_addrs(unit, addrs, opts); - } - - if (addrs != NULL) - free_wordlist(addrs); - BZERO(ppp_settings.passwd, sizeof(ppp_settings.passwd)); - BZERO(secret, sizeof(secret)); - - return ret; -} - -/* - * null_login - Check if a username of "" and a password of "" are - * acceptable, and iff so, set the list of acceptable IP addresses - * and return 1. - */ -static int -null_login(unit) - int unit; -{ - char *filename; - FILE *f; - int i, ret; - struct wordlist *addrs, *opts; - char secret[MAXWORDLEN]; - - /* - * Check if a plugin wants to handle this. - */ - ret = -1; - if (null_auth_hook) - ret = (*null_auth_hook)(&addrs, &opts); - - /* - * Open the file of pap secrets and scan for a suitable secret. - */ - if (ret <= 0) { - filename = _PATH_UPAPFILE; - addrs = NULL; - f = fopen(filename, "r"); - if (f == NULL) - return 0; - check_access(f, filename); - - i = scan_authfile(f, "", our_name, secret, &addrs, &opts, filename, 0); - ret = i >= 0 && secret[0] == 0; - BZERO(secret, sizeof(secret)); - fclose(f); - } - - if (ret) - set_allowed_addrs(unit, addrs, opts); - else if (opts != 0) - free_wordlist(opts); - if (addrs != 0) - free_wordlist(addrs); - - return ret; -} - -/* - * get_pap_passwd - get a password for authenticating ourselves with - * our peer using PAP. Returns 1 on success, 0 if no suitable password - * could be found. - * Assumes passwd points to MAXSECRETLEN bytes of space (if non-null). - */ -static int -get_pap_passwd(passwd) - char *passwd; -{ - char *filename; - FILE *f; - int ret; - char secret[MAXWORDLEN]; - - /* - * Check whether a plugin wants to supply this. - */ - if (pap_passwd_hook) { - ret = (*pap_passwd_hook)(ppp_settings,user, ppp_settings.passwd); - if (ret >= 0) - return ret; - } - - filename = _PATH_UPAPFILE; - f = fopen(filename, "r"); - if (f == NULL) - return 0; - check_access(f, filename); - ret = scan_authfile(f, user, - (remote_name[0]? remote_name: NULL), - secret, NULL, NULL, filename, 0); - fclose(f); - if (ret < 0) - return 0; - if (passwd != NULL) - strlcpy(passwd, secret, MAXSECRETLEN); - BZERO(secret, sizeof(secret)); - return 1; -} - -/* - * have_pap_secret - check whether we have a PAP file with any - * secrets that we could possibly use for authenticating the peer. - */ -static int -have_pap_secret(lacks_ipp) - int *lacks_ipp; -{ - FILE *f; - int ret; - char *filename; - struct wordlist *addrs; - - /* let the plugin decide, if there is one */ - if (pap_check_hook) { - ret = (*pap_check_hook)(); - if (ret >= 0) - return ret; - } - - filename = _PATH_UPAPFILE; - f = fopen(filename, "r"); - if (f == NULL) - return 0; - - ret = scan_authfile(f, (explicit_remote? remote_name: NULL), our_name, - NULL, &addrs, NULL, filename, 0); - fclose(f); - if (ret >= 0 && !some_ip_ok(addrs)) { - if (lacks_ipp != 0) - *lacks_ipp = 1; - ret = -1; - } - if (addrs != 0) - free_wordlist(addrs); - - return ret >= 0; -} - -/* - * have_chap_secret - check whether we have a CHAP file with a - * secret that we could possibly use for authenticating `client' - * on `server'. Either can be the null string, meaning we don't - * know the identity yet. - */ -static int -have_chap_secret(client, server, need_ip, lacks_ipp) - char *client; - char *server; - int need_ip; - int *lacks_ipp; -{ - FILE *f; - int ret; - char *filename; - struct wordlist *addrs; - - if (chap_check_hook) { - ret = (*chap_check_hook)(); - if (ret >= 0) { - return ret; - } - } - - filename = _PATH_CHAPFILE; - f = fopen(filename, "r"); - if (f == NULL) - return 0; - - if (client != NULL && client[0] == 0) - client = NULL; - else if (server != NULL && server[0] == 0) - server = NULL; - - ret = scan_authfile(f, client, server, NULL, &addrs, NULL, filename, 0); - fclose(f); - if (ret >= 0 && need_ip && !some_ip_ok(addrs)) { - if (lacks_ipp != 0) - *lacks_ipp = 1; - ret = -1; - } - if (addrs != 0) - free_wordlist(addrs); - - return ret >= 0; -} - -/* - * have_srp_secret - check whether we have a SRP file with a - * secret that we could possibly use for authenticating `client' - * on `server'. Either can be the null string, meaning we don't - * know the identity yet. - */ -static int -have_srp_secret(client, server, need_ip, lacks_ipp) - char *client; - char *server; - int need_ip; - int *lacks_ipp; -{ - FILE *f; - int ret; - char *filename; - struct wordlist *addrs; - - filename = _PATH_SRPFILE; - f = fopen(filename, "r"); - if (f == NULL) - return 0; - - if (client != NULL && client[0] == 0) - client = NULL; - else if (server != NULL && server[0] == 0) - server = NULL; - - ret = scan_authfile(f, client, server, NULL, &addrs, NULL, filename, 0); - fclose(f); - if (ret >= 0 && need_ip && !some_ip_ok(addrs)) { - if (lacks_ipp != 0) - *lacks_ipp = 1; - ret = -1; - } - if (addrs != 0) - free_wordlist(addrs); - - return ret >= 0; -} -#endif /* UNUSED */ - -#if PPP_AUTH_SUPPORT -/* - * get_secret - open the CHAP secret file and return the secret - * for authenticating the given client on the given server. - * (We could be either client or server). - */ -int get_secret(ppp_pcb *pcb, const char *client, const char *server, char *secret, int *secret_len, int am_server) { - int len; - LWIP_UNUSED_ARG(server); - LWIP_UNUSED_ARG(am_server); - - if (!client || !client[0] || !pcb->settings.user || !pcb->settings.passwd || strcmp(client, pcb->settings.user)) { - return 0; - } - - len = (int)strlen(pcb->settings.passwd); - if (len > MAXSECRETLEN) { - ppp_error("Secret for %s on %s is too long", client, server); - len = MAXSECRETLEN; - } - - MEMCPY(secret, pcb->settings.passwd, len); - *secret_len = len; - return 1; - -#if 0 /* UNUSED */ - FILE *f; - int ret, len; - char *filename; - struct wordlist *addrs, *opts; - char secbuf[MAXWORDLEN]; - struct wordlist *addrs; - addrs = NULL; - - if (!am_server && ppp_settings.passwd[0] != 0) { - strlcpy(secbuf, ppp_settings.passwd, sizeof(secbuf)); - } else if (!am_server && chap_passwd_hook) { - if ( (*chap_passwd_hook)(client, secbuf) < 0) { - ppp_error("Unable to obtain CHAP password for %s on %s from plugin", - client, server); - return 0; - } - } else { - filename = _PATH_CHAPFILE; - addrs = NULL; - secbuf[0] = 0; - - f = fopen(filename, "r"); - if (f == NULL) { - ppp_error("Can't open chap secret file %s: %m", filename); - return 0; - } - check_access(f, filename); - - ret = scan_authfile(f, client, server, secbuf, &addrs, &opts, filename, 0); - fclose(f); - if (ret < 0) - return 0; - - if (am_server) - set_allowed_addrs(unit, addrs, opts); - else if (opts != 0) - free_wordlist(opts); - if (addrs != 0) - free_wordlist(addrs); - } - - len = strlen(secbuf); - if (len > MAXSECRETLEN) { - ppp_error("Secret for %s on %s is too long", client, server); - len = MAXSECRETLEN; - } - MEMCPY(secret, secbuf, len); - BZERO(secbuf, sizeof(secbuf)); - *secret_len = len; - - return 1; -#endif /* UNUSED */ -} -#endif /* PPP_AUTH_SUPPORT */ - - -#if 0 /* UNUSED */ -/* - * get_srp_secret - open the SRP secret file and return the secret - * for authenticating the given client on the given server. - * (We could be either client or server). - */ -int -get_srp_secret(unit, client, server, secret, am_server) - int unit; - char *client; - char *server; - char *secret; - int am_server; -{ - FILE *fp; - int ret; - char *filename; - struct wordlist *addrs, *opts; - - if (!am_server && ppp_settings.passwd[0] != '\0') { - strlcpy(secret, ppp_settings.passwd, MAXWORDLEN); - } else { - filename = _PATH_SRPFILE; - addrs = NULL; - - fp = fopen(filename, "r"); - if (fp == NULL) { - ppp_error("Can't open srp secret file %s: %m", filename); - return 0; - } - check_access(fp, filename); - - secret[0] = '\0'; - ret = scan_authfile(fp, client, server, secret, &addrs, &opts, - filename, am_server); - fclose(fp); - if (ret < 0) - return 0; - - if (am_server) - set_allowed_addrs(unit, addrs, opts); - else if (opts != NULL) - free_wordlist(opts); - if (addrs != NULL) - free_wordlist(addrs); - } - - return 1; -} - -/* - * set_allowed_addrs() - set the list of allowed addresses. - * Also looks for `--' indicating options to apply for this peer - * and leaves the following words in extra_options. - */ -static void -set_allowed_addrs(unit, addrs, opts) - int unit; - struct wordlist *addrs; - struct wordlist *opts; -{ - int n; - struct wordlist *ap, **plink; - struct permitted_ip *ip; - char *ptr_word, *ptr_mask; - struct hostent *hp; - struct netent *np; - u32_t a, mask, ah, offset; - struct ipcp_options *wo = &ipcp_wantoptions[unit]; - u32_t suggested_ip = 0; - - if (addresses[unit] != NULL) - free(addresses[unit]); - addresses[unit] = NULL; - if (extra_options != NULL) - free_wordlist(extra_options); - extra_options = opts; - - /* - * Count the number of IP addresses given. - */ - n = wordlist_count(addrs) + wordlist_count(noauth_addrs); - if (n == 0) - return; - ip = (struct permitted_ip *) malloc((n + 1) * sizeof(struct permitted_ip)); - if (ip == 0) - return; - - /* temporarily append the noauth_addrs list to addrs */ - for (plink = &addrs; *plink != NULL; plink = &(*plink)->next) - ; - *plink = noauth_addrs; - - n = 0; - for (ap = addrs; ap != NULL; ap = ap->next) { - /* "-" means no addresses authorized, "*" means any address allowed */ - ptr_word = ap->word; - if (strcmp(ptr_word, "-") == 0) - break; - if (strcmp(ptr_word, "*") == 0) { - ip[n].permit = 1; - ip[n].base = ip[n].mask = 0; - ++n; - break; - } - - ip[n].permit = 1; - if (*ptr_word == '!') { - ip[n].permit = 0; - ++ptr_word; - } - - mask = ~ (u32_t) 0; - offset = 0; - ptr_mask = strchr (ptr_word, '/'); - if (ptr_mask != NULL) { - int bit_count; - char *endp; - - bit_count = (int) strtol (ptr_mask+1, &endp, 10); - if (bit_count <= 0 || bit_count > 32) { - ppp_warn("invalid address length %v in auth. address list", - ptr_mask+1); - continue; - } - bit_count = 32 - bit_count; /* # bits in host part */ - if (*endp == '+') { - offset = ifunit + 1; - ++endp; - } - if (*endp != 0) { - ppp_warn("invalid address length syntax: %v", ptr_mask+1); - continue; - } - *ptr_mask = '\0'; - mask <<= bit_count; - } - - hp = gethostbyname(ptr_word); - if (hp != NULL && hp->h_addrtype == AF_INET) { - a = *(u32_t *)hp->h_addr; - } else { - np = getnetbyname (ptr_word); - if (np != NULL && np->n_addrtype == AF_INET) { - a = lwip_htonl ((u32_t)np->n_net); - if (ptr_mask == NULL) { - /* calculate appropriate mask for net */ - ah = lwip_ntohl(a); - if (IN_CLASSA(ah)) - mask = IN_CLASSA_NET; - else if (IN_CLASSB(ah)) - mask = IN_CLASSB_NET; - else if (IN_CLASSC(ah)) - mask = IN_CLASSC_NET; - } - } else { - a = inet_addr (ptr_word); - } - } - - if (ptr_mask != NULL) - *ptr_mask = '/'; - - if (a == (u32_t)-1L) { - ppp_warn("unknown host %s in auth. address list", ap->word); - continue; - } - if (offset != 0) { - if (offset >= ~mask) { - ppp_warn("interface unit %d too large for subnet %v", - ifunit, ptr_word); - continue; - } - a = lwip_htonl((lwip_ntohl(a) & mask) + offset); - mask = ~(u32_t)0; - } - ip[n].mask = lwip_htonl(mask); - ip[n].base = a & ip[n].mask; - ++n; - if (~mask == 0 && suggested_ip == 0) - suggested_ip = a; - } - *plink = NULL; - - ip[n].permit = 0; /* make the last entry forbid all addresses */ - ip[n].base = 0; /* to terminate the list */ - ip[n].mask = 0; - - addresses[unit] = ip; - - /* - * If the address given for the peer isn't authorized, or if - * the user hasn't given one, AND there is an authorized address - * which is a single host, then use that if we find one. - */ - if (suggested_ip != 0 - && (wo->hisaddr == 0 || !auth_ip_addr(unit, wo->hisaddr))) { - wo->hisaddr = suggested_ip; - /* - * Do we insist on this address? No, if there are other - * addresses authorized than the suggested one. - */ - if (n > 1) - wo->accept_remote = 1; - } -} - -/* - * auth_ip_addr - check whether the peer is authorized to use - * a given IP address. Returns 1 if authorized, 0 otherwise. - */ -int -auth_ip_addr(unit, addr) - int unit; - u32_t addr; -{ - int ok; - - /* don't allow loopback or multicast address */ - if (bad_ip_adrs(addr)) - return 0; - - if (allowed_address_hook) { - ok = allowed_address_hook(addr); - if (ok >= 0) return ok; - } - - if (addresses[unit] != NULL) { - ok = ip_addr_check(addr, addresses[unit]); - if (ok >= 0) - return ok; - } - - if (auth_required) - return 0; /* no addresses authorized */ - return allow_any_ip || privileged || !have_route_to(addr); -} - -static int -ip_addr_check(addr, addrs) - u32_t addr; - struct permitted_ip *addrs; -{ - for (; ; ++addrs) - if ((addr & addrs->mask) == addrs->base) - return addrs->permit; -} - -/* - * bad_ip_adrs - return 1 if the IP address is one we don't want - * to use, such as an address in the loopback net or a multicast address. - * addr is in network byte order. - */ -int -bad_ip_adrs(addr) - u32_t addr; -{ - addr = lwip_ntohl(addr); - return (addr >> IN_CLASSA_NSHIFT) == IN_LOOPBACKNET - || IN_MULTICAST(addr) || IN_BADCLASS(addr); -} - -/* - * some_ip_ok - check a wordlist to see if it authorizes any - * IP address(es). - */ -static int -some_ip_ok(addrs) - struct wordlist *addrs; -{ - for (; addrs != 0; addrs = addrs->next) { - if (addrs->word[0] == '-') - break; - if (addrs->word[0] != '!') - return 1; /* some IP address is allowed */ - } - return 0; -} - -/* - * auth_number - check whether the remote number is allowed to connect. - * Returns 1 if authorized, 0 otherwise. - */ -int -auth_number() -{ - struct wordlist *wp = permitted_numbers; - int l; - - /* Allow all if no authorization list. */ - if (!wp) - return 1; - - /* Allow if we have a match in the authorization list. */ - while (wp) { - /* trailing '*' wildcard */ - l = strlen(wp->word); - if ((wp->word)[l - 1] == '*') - l--; - if (!strncasecmp(wp->word, remote_number, l)) - return 1; - wp = wp->next; - } - - return 0; -} - -/* - * check_access - complain if a secret file has too-liberal permissions. - */ -static void -check_access(f, filename) - FILE *f; - char *filename; -{ - struct stat sbuf; - - if (fstat(fileno(f), &sbuf) < 0) { - ppp_warn("cannot stat secret file %s: %m", filename); - } else if ((sbuf.st_mode & (S_IRWXG | S_IRWXO)) != 0) { - ppp_warn("Warning - secret file %s has world and/or group access", - filename); - } -} - -/* - * scan_authfile - Scan an authorization file for a secret suitable - * for authenticating `client' on `server'. The return value is -1 - * if no secret is found, otherwise >= 0. The return value has - * NONWILD_CLIENT set if the secret didn't have "*" for the client, and - * NONWILD_SERVER set if the secret didn't have "*" for the server. - * Any following words on the line up to a "--" (i.e. address authorization - * info) are placed in a wordlist and returned in *addrs. Any - * following words (extra options) are placed in a wordlist and - * returned in *opts. - * We assume secret is NULL or points to MAXWORDLEN bytes of space. - * Flags are non-zero if we need two colons in the secret in order to - * match. - */ -static int -scan_authfile(f, client, server, secret, addrs, opts, filename, flags) - FILE *f; - char *client; - char *server; - char *secret; - struct wordlist **addrs; - struct wordlist **opts; - char *filename; - int flags; -{ - int newline, xxx; - int got_flag, best_flag; - FILE *sf; - struct wordlist *ap, *addr_list, *alist, **app; - char word[MAXWORDLEN]; - char atfile[MAXWORDLEN]; - char lsecret[MAXWORDLEN]; - char *cp; - - if (addrs != NULL) - *addrs = NULL; - if (opts != NULL) - *opts = NULL; - addr_list = NULL; - if (!getword(f, word, &newline, filename)) - return -1; /* file is empty??? */ - newline = 1; - best_flag = -1; - for (;;) { - /* - * Skip until we find a word at the start of a line. - */ - while (!newline && getword(f, word, &newline, filename)) - ; - if (!newline) - break; /* got to end of file */ - - /* - * Got a client - check if it's a match or a wildcard. - */ - got_flag = 0; - if (client != NULL && strcmp(word, client) != 0 && !ISWILD(word)) { - newline = 0; - continue; - } - if (!ISWILD(word)) - got_flag = NONWILD_CLIENT; - - /* - * Now get a server and check if it matches. - */ - if (!getword(f, word, &newline, filename)) - break; - if (newline) - continue; - if (!ISWILD(word)) { - if (server != NULL && strcmp(word, server) != 0) - continue; - got_flag |= NONWILD_SERVER; - } - - /* - * Got some sort of a match - see if it's better than what - * we have already. - */ - if (got_flag <= best_flag) - continue; - - /* - * Get the secret. - */ - if (!getword(f, word, &newline, filename)) - break; - if (newline) - continue; - - /* - * SRP-SHA1 authenticator should never be reading secrets from - * a file. (Authenticatee may, though.) - */ - if (flags && ((cp = strchr(word, ':')) == NULL || - strchr(cp + 1, ':') == NULL)) - continue; - - if (secret != NULL) { - /* - * Special syntax: @/pathname means read secret from file. - */ - if (word[0] == '@' && word[1] == '/') { - strlcpy(atfile, word+1, sizeof(atfile)); - if ((sf = fopen(atfile, "r")) == NULL) { - ppp_warn("can't open indirect secret file %s", atfile); - continue; - } - check_access(sf, atfile); - if (!getword(sf, word, &xxx, atfile)) { - ppp_warn("no secret in indirect secret file %s", atfile); - fclose(sf); - continue; - } - fclose(sf); - } - strlcpy(lsecret, word, sizeof(lsecret)); - } - - /* - * Now read address authorization info and make a wordlist. - */ - app = &alist; - for (;;) { - if (!getword(f, word, &newline, filename) || newline) - break; - ap = (struct wordlist *) - malloc(sizeof(struct wordlist) + strlen(word) + 1); - if (ap == NULL) - novm("authorized addresses"); - ap->word = (char *) (ap + 1); - strcpy(ap->word, word); - *app = ap; - app = &ap->next; - } - *app = NULL; - - /* - * This is the best so far; remember it. - */ - best_flag = got_flag; - if (addr_list) - free_wordlist(addr_list); - addr_list = alist; - if (secret != NULL) - strlcpy(secret, lsecret, MAXWORDLEN); - - if (!newline) - break; - } - - /* scan for a -- word indicating the start of options */ - for (app = &addr_list; (ap = *app) != NULL; app = &ap->next) - if (strcmp(ap->word, "--") == 0) - break; - /* ap = start of options */ - if (ap != NULL) { - ap = ap->next; /* first option */ - free(*app); /* free the "--" word */ - *app = NULL; /* terminate addr list */ - } - if (opts != NULL) - *opts = ap; - else if (ap != NULL) - free_wordlist(ap); - if (addrs != NULL) - *addrs = addr_list; - else if (addr_list != NULL) - free_wordlist(addr_list); - - return best_flag; -} - -/* - * wordlist_count - return the number of items in a wordlist - */ -static int -wordlist_count(wp) - struct wordlist *wp; -{ - int n; - - for (n = 0; wp != NULL; wp = wp->next) - ++n; - return n; -} - -/* - * free_wordlist - release memory allocated for a wordlist. - */ -static void -free_wordlist(wp) - struct wordlist *wp; -{ - struct wordlist *next; - - while (wp != NULL) { - next = wp->next; - free(wp); - wp = next; - } -} -#endif /* UNUSED */ - -#endif /* PPP_SUPPORT */ diff --git a/third_party/lwip/repo/lwip/src/netif/ppp/ccp.c b/third_party/lwip/repo/lwip/src/netif/ppp/ccp.c deleted file mode 100644 index f8519ebece7b10..00000000000000 --- a/third_party/lwip/repo/lwip/src/netif/ppp/ccp.c +++ /dev/null @@ -1,1740 +0,0 @@ -/* - * ccp.c - PPP Compression Control Protocol. - * - * Copyright (c) 1994-2002 Paul Mackerras. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. The name(s) of the authors of this software must not be used to - * endorse or promote products derived from this software without - * prior written permission. - * - * 3. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Paul Mackerras - * ". - * - * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT && CCP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#include -#include - -#include "netif/ppp/ppp_impl.h" - -#include "netif/ppp/fsm.h" -#include "netif/ppp/ccp.h" - -#if MPPE_SUPPORT -#include "netif/ppp/lcp.h" /* lcp_close(), lcp_fsm */ -#include "netif/ppp/mppe.h" /* mppe_init() */ -#endif /* MPPE_SUPPORT */ - -/* - * Unfortunately there is a bug in zlib which means that using a - * size of 8 (window size = 256) for Deflate compression will cause - * buffer overruns and kernel crashes in the deflate module. - * Until this is fixed we only accept sizes in the range 9 .. 15. - * Thanks to James Carlson for pointing this out. - */ -#define DEFLATE_MIN_WORKS 9 - -/* - * Command-line options. - */ -#if PPP_OPTIONS -static int setbsdcomp (char **); -static int setdeflate (char **); -static char bsd_value[8]; -static char deflate_value[8]; - -/* - * Option variables. - */ -#if MPPE_SUPPORT -bool refuse_mppe_stateful = 1; /* Allow stateful mode? */ -#endif /* MPPE_SUPPORT */ - -static option_t ccp_option_list[] = { - { "noccp", o_bool, &ccp_protent.enabled_flag, - "Disable CCP negotiation" }, - { "-ccp", o_bool, &ccp_protent.enabled_flag, - "Disable CCP negotiation", OPT_ALIAS }, - - { "bsdcomp", o_special, (void *)setbsdcomp, - "Request BSD-Compress packet compression", - OPT_PRIO | OPT_A2STRVAL | OPT_STATIC, bsd_value }, - { "nobsdcomp", o_bool, &ccp_wantoptions[0].bsd_compress, - "don't allow BSD-Compress", OPT_PRIOSUB | OPT_A2CLR, - &ccp_allowoptions[0].bsd_compress }, - { "-bsdcomp", o_bool, &ccp_wantoptions[0].bsd_compress, - "don't allow BSD-Compress", OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLR, - &ccp_allowoptions[0].bsd_compress }, - - { "deflate", o_special, (void *)setdeflate, - "request Deflate compression", - OPT_PRIO | OPT_A2STRVAL | OPT_STATIC, deflate_value }, - { "nodeflate", o_bool, &ccp_wantoptions[0].deflate, - "don't allow Deflate compression", OPT_PRIOSUB | OPT_A2CLR, - &ccp_allowoptions[0].deflate }, - { "-deflate", o_bool, &ccp_wantoptions[0].deflate, - "don't allow Deflate compression", OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLR, - &ccp_allowoptions[0].deflate }, - - { "nodeflatedraft", o_bool, &ccp_wantoptions[0].deflate_draft, - "don't use draft deflate #", OPT_A2COPY, - &ccp_allowoptions[0].deflate_draft }, - - { "predictor1", o_bool, &ccp_wantoptions[0].predictor_1, - "request Predictor-1", OPT_PRIO | 1 }, - { "nopredictor1", o_bool, &ccp_wantoptions[0].predictor_1, - "don't allow Predictor-1", OPT_PRIOSUB | OPT_A2CLR, - &ccp_allowoptions[0].predictor_1 }, - { "-predictor1", o_bool, &ccp_wantoptions[0].predictor_1, - "don't allow Predictor-1", OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLR, - &ccp_allowoptions[0].predictor_1 }, - -#if MPPE_SUPPORT - /* MPPE options are symmetrical ... we only set wantoptions here */ - { "require-mppe", o_bool, &ccp_wantoptions[0].mppe, - "require MPPE encryption", - OPT_PRIO | MPPE_OPT_40 | MPPE_OPT_128 }, - { "+mppe", o_bool, &ccp_wantoptions[0].mppe, - "require MPPE encryption", - OPT_ALIAS | OPT_PRIO | MPPE_OPT_40 | MPPE_OPT_128 }, - { "nomppe", o_bool, &ccp_wantoptions[0].mppe, - "don't allow MPPE encryption", OPT_PRIO }, - { "-mppe", o_bool, &ccp_wantoptions[0].mppe, - "don't allow MPPE encryption", OPT_ALIAS | OPT_PRIO }, - - /* We use ccp_allowoptions[0].mppe as a junk var ... it is reset later */ - { "require-mppe-40", o_bool, &ccp_allowoptions[0].mppe, - "require MPPE 40-bit encryption", OPT_PRIO | OPT_A2OR | MPPE_OPT_40, - &ccp_wantoptions[0].mppe }, - { "+mppe-40", o_bool, &ccp_allowoptions[0].mppe, - "require MPPE 40-bit encryption", OPT_PRIO | OPT_A2OR | MPPE_OPT_40, - &ccp_wantoptions[0].mppe }, - { "nomppe-40", o_bool, &ccp_allowoptions[0].mppe, - "don't allow MPPE 40-bit encryption", - OPT_PRIOSUB | OPT_A2CLRB | MPPE_OPT_40, &ccp_wantoptions[0].mppe }, - { "-mppe-40", o_bool, &ccp_allowoptions[0].mppe, - "don't allow MPPE 40-bit encryption", - OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLRB | MPPE_OPT_40, - &ccp_wantoptions[0].mppe }, - - { "require-mppe-128", o_bool, &ccp_allowoptions[0].mppe, - "require MPPE 128-bit encryption", OPT_PRIO | OPT_A2OR | MPPE_OPT_128, - &ccp_wantoptions[0].mppe }, - { "+mppe-128", o_bool, &ccp_allowoptions[0].mppe, - "require MPPE 128-bit encryption", - OPT_ALIAS | OPT_PRIO | OPT_A2OR | MPPE_OPT_128, - &ccp_wantoptions[0].mppe }, - { "nomppe-128", o_bool, &ccp_allowoptions[0].mppe, - "don't allow MPPE 128-bit encryption", - OPT_PRIOSUB | OPT_A2CLRB | MPPE_OPT_128, &ccp_wantoptions[0].mppe }, - { "-mppe-128", o_bool, &ccp_allowoptions[0].mppe, - "don't allow MPPE 128-bit encryption", - OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLRB | MPPE_OPT_128, - &ccp_wantoptions[0].mppe }, - - /* strange one; we always request stateless, but will we allow stateful? */ - { "mppe-stateful", o_bool, &refuse_mppe_stateful, - "allow MPPE stateful mode", OPT_PRIO }, - { "nomppe-stateful", o_bool, &refuse_mppe_stateful, - "disallow MPPE stateful mode", OPT_PRIO | 1 }, -#endif /* MPPE_SUPPORT */ - - { NULL } -}; -#endif /* PPP_OPTIONS */ - -/* - * Protocol entry points from main code. - */ -static void ccp_init(ppp_pcb *pcb); -static void ccp_open(ppp_pcb *pcb); -static void ccp_close(ppp_pcb *pcb, const char *reason); -static void ccp_lowerup(ppp_pcb *pcb); -static void ccp_lowerdown(ppp_pcb *pcb); -static void ccp_input(ppp_pcb *pcb, u_char *pkt, int len); -static void ccp_protrej(ppp_pcb *pcb); -#if PRINTPKT_SUPPORT -static int ccp_printpkt(const u_char *p, int plen, void (*printer) (void *, const char *, ...), void *arg); -#endif /* PRINTPKT_SUPPORT */ -#if PPP_DATAINPUT -static void ccp_datainput(ppp_pcb *pcb, u_char *pkt, int len); -#endif /* PPP_DATAINPUT */ - -const struct protent ccp_protent = { - PPP_CCP, - ccp_init, - ccp_input, - ccp_protrej, - ccp_lowerup, - ccp_lowerdown, - ccp_open, - ccp_close, -#if PRINTPKT_SUPPORT - ccp_printpkt, -#endif /* PRINTPKT_SUPPORT */ -#if PPP_DATAINPUT - ccp_datainput, -#endif /* PPP_DATAINPUT */ -#if PRINTPKT_SUPPORT - "CCP", - "Compressed", -#endif /* PRINTPKT_SUPPORT */ -#if PPP_OPTIONS - ccp_option_list, - NULL, -#endif /* PPP_OPTIONS */ -#if DEMAND_SUPPORT - NULL, - NULL -#endif /* DEMAND_SUPPORT */ -}; - -/* - * Callbacks for fsm code. - */ -static void ccp_resetci (fsm *); -static int ccp_cilen (fsm *); -static void ccp_addci (fsm *, u_char *, int *); -static int ccp_ackci (fsm *, u_char *, int); -static int ccp_nakci (fsm *, u_char *, int, int); -static int ccp_rejci (fsm *, u_char *, int); -static int ccp_reqci (fsm *, u_char *, int *, int); -static void ccp_up (fsm *); -static void ccp_down (fsm *); -static int ccp_extcode (fsm *, int, int, u_char *, int); -static void ccp_rack_timeout (void *); -static const char *method_name (ccp_options *, ccp_options *); - -static const fsm_callbacks ccp_callbacks = { - ccp_resetci, - ccp_cilen, - ccp_addci, - ccp_ackci, - ccp_nakci, - ccp_rejci, - ccp_reqci, - ccp_up, - ccp_down, - NULL, - NULL, - NULL, - NULL, - ccp_extcode, - "CCP" -}; - -/* - * Do we want / did we get any compression? - */ -static int ccp_anycompress(ccp_options *opt) { - return (0 -#if DEFLATE_SUPPORT - || (opt)->deflate -#endif /* DEFLATE_SUPPORT */ -#if BSDCOMPRESS_SUPPORT - || (opt)->bsd_compress -#endif /* BSDCOMPRESS_SUPPORT */ -#if PREDICTOR_SUPPORT - || (opt)->predictor_1 || (opt)->predictor_2 -#endif /* PREDICTOR_SUPPORT */ -#if MPPE_SUPPORT - || (opt)->mppe -#endif /* MPPE_SUPPORT */ - ); -} - -/* - * Local state (mainly for handling reset-reqs and reset-acks). - */ -#define RACK_PENDING 1 /* waiting for reset-ack */ -#define RREQ_REPEAT 2 /* send another reset-req if no reset-ack */ - -#define RACKTIMEOUT 1 /* second */ - -#if PPP_OPTIONS -/* - * Option parsing - */ -static int -setbsdcomp(argv) - char **argv; -{ - int rbits, abits; - char *str, *endp; - - str = *argv; - abits = rbits = strtol(str, &endp, 0); - if (endp != str && *endp == ',') { - str = endp + 1; - abits = strtol(str, &endp, 0); - } - if (*endp != 0 || endp == str) { - option_error("invalid parameter '%s' for bsdcomp option", *argv); - return 0; - } - if ((rbits != 0 && (rbits < BSD_MIN_BITS || rbits > BSD_MAX_BITS)) - || (abits != 0 && (abits < BSD_MIN_BITS || abits > BSD_MAX_BITS))) { - option_error("bsdcomp option values must be 0 or %d .. %d", - BSD_MIN_BITS, BSD_MAX_BITS); - return 0; - } - if (rbits > 0) { - ccp_wantoptions[0].bsd_compress = 1; - ccp_wantoptions[0].bsd_bits = rbits; - } else - ccp_wantoptions[0].bsd_compress = 0; - if (abits > 0) { - ccp_allowoptions[0].bsd_compress = 1; - ccp_allowoptions[0].bsd_bits = abits; - } else - ccp_allowoptions[0].bsd_compress = 0; - ppp_slprintf(bsd_value, sizeof(bsd_value), - rbits == abits? "%d": "%d,%d", rbits, abits); - - return 1; -} - -static int -setdeflate(argv) - char **argv; -{ - int rbits, abits; - char *str, *endp; - - str = *argv; - abits = rbits = strtol(str, &endp, 0); - if (endp != str && *endp == ',') { - str = endp + 1; - abits = strtol(str, &endp, 0); - } - if (*endp != 0 || endp == str) { - option_error("invalid parameter '%s' for deflate option", *argv); - return 0; - } - if ((rbits != 0 && (rbits < DEFLATE_MIN_SIZE || rbits > DEFLATE_MAX_SIZE)) - || (abits != 0 && (abits < DEFLATE_MIN_SIZE - || abits > DEFLATE_MAX_SIZE))) { - option_error("deflate option values must be 0 or %d .. %d", - DEFLATE_MIN_SIZE, DEFLATE_MAX_SIZE); - return 0; - } - if (rbits == DEFLATE_MIN_SIZE || abits == DEFLATE_MIN_SIZE) { - if (rbits == DEFLATE_MIN_SIZE) - rbits = DEFLATE_MIN_WORKS; - if (abits == DEFLATE_MIN_SIZE) - abits = DEFLATE_MIN_WORKS; - warn("deflate option value of %d changed to %d to avoid zlib bug", - DEFLATE_MIN_SIZE, DEFLATE_MIN_WORKS); - } - if (rbits > 0) { - ccp_wantoptions[0].deflate = 1; - ccp_wantoptions[0].deflate_size = rbits; - } else - ccp_wantoptions[0].deflate = 0; - if (abits > 0) { - ccp_allowoptions[0].deflate = 1; - ccp_allowoptions[0].deflate_size = abits; - } else - ccp_allowoptions[0].deflate = 0; - ppp_slprintf(deflate_value, sizeof(deflate_value), - rbits == abits? "%d": "%d,%d", rbits, abits); - - return 1; -} -#endif /* PPP_OPTIONS */ - -/* - * ccp_init - initialize CCP. - */ -static void ccp_init(ppp_pcb *pcb) { - fsm *f = &pcb->ccp_fsm; - - f->pcb = pcb; - f->protocol = PPP_CCP; - f->callbacks = &ccp_callbacks; - fsm_init(f); - -#if 0 /* Not necessary, everything is cleared in ppp_new() */ - memset(wo, 0, sizeof(*wo)); - memset(go, 0, sizeof(*go)); - memset(ao, 0, sizeof(*ao)); - memset(ho, 0, sizeof(*ho)); -#endif /* 0 */ - -#if DEFLATE_SUPPORT - wo->deflate = 1; - wo->deflate_size = DEFLATE_MAX_SIZE; - wo->deflate_correct = 1; - wo->deflate_draft = 1; - ao->deflate = 1; - ao->deflate_size = DEFLATE_MAX_SIZE; - ao->deflate_correct = 1; - ao->deflate_draft = 1; -#endif /* DEFLATE_SUPPORT */ - -#if BSDCOMPRESS_SUPPORT - wo->bsd_compress = 1; - wo->bsd_bits = BSD_MAX_BITS; - ao->bsd_compress = 1; - ao->bsd_bits = BSD_MAX_BITS; -#endif /* BSDCOMPRESS_SUPPORT */ - -#if PREDICTOR_SUPPORT - ao->predictor_1 = 1; -#endif /* PREDICTOR_SUPPORT */ -} - -/* - * ccp_open - CCP is allowed to come up. - */ -static void ccp_open(ppp_pcb *pcb) { - fsm *f = &pcb->ccp_fsm; - ccp_options *go = &pcb->ccp_gotoptions; - - if (f->state != PPP_FSM_OPENED) - ccp_set(pcb, 1, 0, 0, 0); - - /* - * Find out which compressors the kernel supports before - * deciding whether to open in silent mode. - */ - ccp_resetci(f); - if (!ccp_anycompress(go)) - f->flags |= OPT_SILENT; - - fsm_open(f); -} - -/* - * ccp_close - Terminate CCP. - */ -static void ccp_close(ppp_pcb *pcb, const char *reason) { - fsm *f = &pcb->ccp_fsm; - ccp_set(pcb, 0, 0, 0, 0); - fsm_close(f, reason); -} - -/* - * ccp_lowerup - we may now transmit CCP packets. - */ -static void ccp_lowerup(ppp_pcb *pcb) { - fsm *f = &pcb->ccp_fsm; - fsm_lowerup(f); -} - -/* - * ccp_lowerdown - we may not transmit CCP packets. - */ -static void ccp_lowerdown(ppp_pcb *pcb) { - fsm *f = &pcb->ccp_fsm; - fsm_lowerdown(f); -} - -/* - * ccp_input - process a received CCP packet. - */ -static void ccp_input(ppp_pcb *pcb, u_char *p, int len) { - fsm *f = &pcb->ccp_fsm; - ccp_options *go = &pcb->ccp_gotoptions; - int oldstate; - - /* - * Check for a terminate-request so we can print a message. - */ - oldstate = f->state; - fsm_input(f, p, len); - if (oldstate == PPP_FSM_OPENED && p[0] == TERMREQ && f->state != PPP_FSM_OPENED) { - ppp_notice("Compression disabled by peer."); -#if MPPE_SUPPORT - if (go->mppe) { - ppp_error("MPPE disabled, closing LCP"); - lcp_close(pcb, "MPPE disabled by peer"); - } -#endif /* MPPE_SUPPORT */ - } - - /* - * If we get a terminate-ack and we're not asking for compression, - * close CCP. - */ - if (oldstate == PPP_FSM_REQSENT && p[0] == TERMACK - && !ccp_anycompress(go)) - ccp_close(pcb, "No compression negotiated"); -} - -/* - * Handle a CCP-specific code. - */ -static int ccp_extcode(fsm *f, int code, int id, u_char *p, int len) { - ppp_pcb *pcb = f->pcb; - LWIP_UNUSED_ARG(p); - LWIP_UNUSED_ARG(len); - - switch (code) { - case CCP_RESETREQ: - if (f->state != PPP_FSM_OPENED) - break; - ccp_reset_comp(pcb); - /* send a reset-ack, which the transmitter will see and - reset its compression state. */ - fsm_sdata(f, CCP_RESETACK, id, NULL, 0); - break; - - case CCP_RESETACK: - if ((pcb->ccp_localstate & RACK_PENDING) && id == f->reqid) { - pcb->ccp_localstate &= ~(RACK_PENDING | RREQ_REPEAT); - UNTIMEOUT(ccp_rack_timeout, f); - ccp_reset_decomp(pcb); - } - break; - - default: - return 0; - } - - return 1; -} - -/* - * ccp_protrej - peer doesn't talk CCP. - */ -static void ccp_protrej(ppp_pcb *pcb) { - fsm *f = &pcb->ccp_fsm; -#if MPPE_SUPPORT - ccp_options *go = &pcb->ccp_gotoptions; -#endif /* MPPE_SUPPORT */ - - ccp_set(pcb, 0, 0, 0, 0); - fsm_lowerdown(f); - -#if MPPE_SUPPORT - if (go->mppe) { - ppp_error("MPPE required but peer negotiation failed"); - lcp_close(pcb, "MPPE required but peer negotiation failed"); - } -#endif /* MPPE_SUPPORT */ - -} - -/* - * ccp_resetci - initialize at start of negotiation. - */ -static void ccp_resetci(fsm *f) { - ppp_pcb *pcb = f->pcb; - ccp_options *go = &pcb->ccp_gotoptions; - ccp_options *wo = &pcb->ccp_wantoptions; -#if MPPE_SUPPORT - ccp_options *ao = &pcb->ccp_allowoptions; -#endif /* MPPE_SUPPORT */ -#if DEFLATE_SUPPORT || BSDCOMPRESS_SUPPORT || PREDICTOR_SUPPORT - u_char opt_buf[CCP_MAX_OPTION_LENGTH]; -#endif /* DEFLATE_SUPPORT || BSDCOMPRESS_SUPPORT || PREDICTOR_SUPPORT */ -#if DEFLATE_SUPPORT || BSDCOMPRESS_SUPPORT - int res; -#endif /* DEFLATE_SUPPORT || BSDCOMPRESS_SUPPORT */ - -#if MPPE_SUPPORT - if (pcb->settings.require_mppe) { - wo->mppe = ao->mppe = - (pcb->settings.refuse_mppe_40 ? 0 : MPPE_OPT_40) - | (pcb->settings.refuse_mppe_128 ? 0 : MPPE_OPT_128); - } -#endif /* MPPE_SUPPORT */ - - *go = *wo; - pcb->ccp_all_rejected = 0; - -#if MPPE_SUPPORT - if (go->mppe) { - int auth_mschap_bits = pcb->auth_done; - int numbits; - - /* - * Start with a basic sanity check: mschap[v2] auth must be in - * exactly one direction. RFC 3079 says that the keys are - * 'derived from the credentials of the peer that initiated the call', - * however the PPP protocol doesn't have such a concept, and pppd - * cannot get this info externally. Instead we do the best we can. - * NB: If MPPE is required, all other compression opts are invalid. - * So, we return right away if we can't do it. - */ - - /* Leave only the mschap auth bits set */ - auth_mschap_bits &= (CHAP_MS_WITHPEER | CHAP_MS_PEER | - CHAP_MS2_WITHPEER | CHAP_MS2_PEER); - /* Count the mschap auths */ - auth_mschap_bits >>= CHAP_MS_SHIFT; - numbits = 0; - do { - numbits += auth_mschap_bits & 1; - auth_mschap_bits >>= 1; - } while (auth_mschap_bits); - if (numbits > 1) { - ppp_error("MPPE required, but auth done in both directions."); - lcp_close(pcb, "MPPE required but not available"); - return; - } - if (!numbits) { - ppp_error("MPPE required, but MS-CHAP[v2] auth not performed."); - lcp_close(pcb, "MPPE required but not available"); - return; - } - - /* A plugin (eg radius) may not have obtained key material. */ - if (!pcb->mppe_keys_set) { - ppp_error("MPPE required, but keys are not available. " - "Possible plugin problem?"); - lcp_close(pcb, "MPPE required but not available"); - return; - } - - /* LM auth not supported for MPPE */ - if (pcb->auth_done & (CHAP_MS_WITHPEER | CHAP_MS_PEER)) { - /* This might be noise */ - if (go->mppe & MPPE_OPT_40) { - ppp_notice("Disabling 40-bit MPPE; MS-CHAP LM not supported"); - go->mppe &= ~MPPE_OPT_40; - wo->mppe &= ~MPPE_OPT_40; - } - } - - /* Last check: can we actually negotiate something? */ - if (!(go->mppe & (MPPE_OPT_40 | MPPE_OPT_128))) { - /* Could be misconfig, could be 40-bit disabled above. */ - ppp_error("MPPE required, but both 40-bit and 128-bit disabled."); - lcp_close(pcb, "MPPE required but not available"); - return; - } - - /* sync options */ - ao->mppe = go->mppe; - /* MPPE is not compatible with other compression types */ -#if BSDCOMPRESS_SUPPORT - ao->bsd_compress = go->bsd_compress = 0; -#endif /* BSDCOMPRESS_SUPPORT */ -#if PREDICTOR_SUPPORT - ao->predictor_1 = go->predictor_1 = 0; - ao->predictor_2 = go->predictor_2 = 0; -#endif /* PREDICTOR_SUPPORT */ -#if DEFLATE_SUPPORT - ao->deflate = go->deflate = 0; -#endif /* DEFLATE_SUPPORT */ - } -#endif /* MPPE_SUPPORT */ - - /* - * Check whether the kernel knows about the various - * compression methods we might request. - */ -#if BSDCOMPRESS_SUPPORT - /* FIXME: we don't need to test if BSD compress is available - * if BSDCOMPRESS_SUPPORT is set, it is. - */ - if (go->bsd_compress) { - opt_buf[0] = CI_BSD_COMPRESS; - opt_buf[1] = CILEN_BSD_COMPRESS; - for (;;) { - if (go->bsd_bits < BSD_MIN_BITS) { - go->bsd_compress = 0; - break; - } - opt_buf[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, go->bsd_bits); - res = ccp_test(pcb, opt_buf, CILEN_BSD_COMPRESS, 0); - if (res > 0) { - break; - } else if (res < 0) { - go->bsd_compress = 0; - break; - } - go->bsd_bits--; - } - } -#endif /* BSDCOMPRESS_SUPPORT */ -#if DEFLATE_SUPPORT - /* FIXME: we don't need to test if deflate is available - * if DEFLATE_SUPPORT is set, it is. - */ - if (go->deflate) { - if (go->deflate_correct) { - opt_buf[0] = CI_DEFLATE; - opt_buf[1] = CILEN_DEFLATE; - opt_buf[3] = DEFLATE_CHK_SEQUENCE; - for (;;) { - if (go->deflate_size < DEFLATE_MIN_WORKS) { - go->deflate_correct = 0; - break; - } - opt_buf[2] = DEFLATE_MAKE_OPT(go->deflate_size); - res = ccp_test(pcb, opt_buf, CILEN_DEFLATE, 0); - if (res > 0) { - break; - } else if (res < 0) { - go->deflate_correct = 0; - break; - } - go->deflate_size--; - } - } - if (go->deflate_draft) { - opt_buf[0] = CI_DEFLATE_DRAFT; - opt_buf[1] = CILEN_DEFLATE; - opt_buf[3] = DEFLATE_CHK_SEQUENCE; - for (;;) { - if (go->deflate_size < DEFLATE_MIN_WORKS) { - go->deflate_draft = 0; - break; - } - opt_buf[2] = DEFLATE_MAKE_OPT(go->deflate_size); - res = ccp_test(pcb, opt_buf, CILEN_DEFLATE, 0); - if (res > 0) { - break; - } else if (res < 0) { - go->deflate_draft = 0; - break; - } - go->deflate_size--; - } - } - if (!go->deflate_correct && !go->deflate_draft) - go->deflate = 0; - } -#endif /* DEFLATE_SUPPORT */ -#if PREDICTOR_SUPPORT - /* FIXME: we don't need to test if predictor is available, - * if PREDICTOR_SUPPORT is set, it is. - */ - if (go->predictor_1) { - opt_buf[0] = CI_PREDICTOR_1; - opt_buf[1] = CILEN_PREDICTOR_1; - if (ccp_test(pcb, opt_buf, CILEN_PREDICTOR_1, 0) <= 0) - go->predictor_1 = 0; - } - if (go->predictor_2) { - opt_buf[0] = CI_PREDICTOR_2; - opt_buf[1] = CILEN_PREDICTOR_2; - if (ccp_test(pcb, opt_buf, CILEN_PREDICTOR_2, 0) <= 0) - go->predictor_2 = 0; - } -#endif /* PREDICTOR_SUPPORT */ -} - -/* - * ccp_cilen - Return total length of our configuration info. - */ -static int ccp_cilen(fsm *f) { - ppp_pcb *pcb = f->pcb; - ccp_options *go = &pcb->ccp_gotoptions; - - return 0 -#if BSDCOMPRESS_SUPPORT - + (go->bsd_compress? CILEN_BSD_COMPRESS: 0) -#endif /* BSDCOMPRESS_SUPPORT */ -#if DEFLATE_SUPPORT - + (go->deflate && go->deflate_correct? CILEN_DEFLATE: 0) - + (go->deflate && go->deflate_draft? CILEN_DEFLATE: 0) -#endif /* DEFLATE_SUPPORT */ -#if PREDICTOR_SUPPORT - + (go->predictor_1? CILEN_PREDICTOR_1: 0) - + (go->predictor_2? CILEN_PREDICTOR_2: 0) -#endif /* PREDICTOR_SUPPORT */ -#if MPPE_SUPPORT - + (go->mppe? CILEN_MPPE: 0) -#endif /* MPPE_SUPPORT */ - ; -} - -/* - * ccp_addci - put our requests in a packet. - */ -static void ccp_addci(fsm *f, u_char *p, int *lenp) { - ppp_pcb *pcb = f->pcb; - ccp_options *go = &pcb->ccp_gotoptions; - u_char *p0 = p; - - /* - * Add the compression types that we can receive, in decreasing - * preference order. - */ -#if MPPE_SUPPORT - if (go->mppe) { - p[0] = CI_MPPE; - p[1] = CILEN_MPPE; - MPPE_OPTS_TO_CI(go->mppe, &p[2]); - mppe_init(pcb, &pcb->mppe_decomp, go->mppe); - p += CILEN_MPPE; - } -#endif /* MPPE_SUPPORT */ -#if DEFLATE_SUPPORT - if (go->deflate) { - if (go->deflate_correct) { - p[0] = CI_DEFLATE; - p[1] = CILEN_DEFLATE; - p[2] = DEFLATE_MAKE_OPT(go->deflate_size); - p[3] = DEFLATE_CHK_SEQUENCE; - p += CILEN_DEFLATE; - } - if (go->deflate_draft) { - p[0] = CI_DEFLATE_DRAFT; - p[1] = CILEN_DEFLATE; - p[2] = p[2 - CILEN_DEFLATE]; - p[3] = DEFLATE_CHK_SEQUENCE; - p += CILEN_DEFLATE; - } - } -#endif /* DEFLATE_SUPPORT */ -#if BSDCOMPRESS_SUPPORT - if (go->bsd_compress) { - p[0] = CI_BSD_COMPRESS; - p[1] = CILEN_BSD_COMPRESS; - p[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, go->bsd_bits); - p += CILEN_BSD_COMPRESS; - } -#endif /* BSDCOMPRESS_SUPPORT */ -#if PREDICTOR_SUPPORT - /* XXX Should Predictor 2 be preferable to Predictor 1? */ - if (go->predictor_1) { - p[0] = CI_PREDICTOR_1; - p[1] = CILEN_PREDICTOR_1; - p += CILEN_PREDICTOR_1; - } - if (go->predictor_2) { - p[0] = CI_PREDICTOR_2; - p[1] = CILEN_PREDICTOR_2; - p += CILEN_PREDICTOR_2; - } -#endif /* PREDICTOR_SUPPORT */ - - go->method = (p > p0)? p0[0]: 0; - - *lenp = p - p0; -} - -/* - * ccp_ackci - process a received configure-ack, and return - * 1 iff the packet was OK. - */ -static int ccp_ackci(fsm *f, u_char *p, int len) { - ppp_pcb *pcb = f->pcb; - ccp_options *go = &pcb->ccp_gotoptions; -#if BSDCOMPRESS_SUPPORT || PREDICTOR_SUPPORT - u_char *p0 = p; -#endif /* BSDCOMPRESS_SUPPORT || PREDICTOR_SUPPORT */ - -#if MPPE_SUPPORT - if (go->mppe) { - u_char opt_buf[CILEN_MPPE]; - - opt_buf[0] = CI_MPPE; - opt_buf[1] = CILEN_MPPE; - MPPE_OPTS_TO_CI(go->mppe, &opt_buf[2]); - if (len < CILEN_MPPE || memcmp(opt_buf, p, CILEN_MPPE)) - return 0; - p += CILEN_MPPE; - len -= CILEN_MPPE; - /* XXX Cope with first/fast ack */ - if (len == 0) - return 1; - } -#endif /* MPPE_SUPPORT */ -#if DEFLATE_SUPPORT - if (go->deflate) { - if (len < CILEN_DEFLATE - || p[0] != (go->deflate_correct? CI_DEFLATE: CI_DEFLATE_DRAFT) - || p[1] != CILEN_DEFLATE - || p[2] != DEFLATE_MAKE_OPT(go->deflate_size) - || p[3] != DEFLATE_CHK_SEQUENCE) - return 0; - p += CILEN_DEFLATE; - len -= CILEN_DEFLATE; - /* XXX Cope with first/fast ack */ - if (len == 0) - return 1; - if (go->deflate_correct && go->deflate_draft) { - if (len < CILEN_DEFLATE - || p[0] != CI_DEFLATE_DRAFT - || p[1] != CILEN_DEFLATE - || p[2] != DEFLATE_MAKE_OPT(go->deflate_size) - || p[3] != DEFLATE_CHK_SEQUENCE) - return 0; - p += CILEN_DEFLATE; - len -= CILEN_DEFLATE; - } - } -#endif /* DEFLATE_SUPPORT */ -#if BSDCOMPRESS_SUPPORT - if (go->bsd_compress) { - if (len < CILEN_BSD_COMPRESS - || p[0] != CI_BSD_COMPRESS || p[1] != CILEN_BSD_COMPRESS - || p[2] != BSD_MAKE_OPT(BSD_CURRENT_VERSION, go->bsd_bits)) - return 0; - p += CILEN_BSD_COMPRESS; - len -= CILEN_BSD_COMPRESS; - /* XXX Cope with first/fast ack */ - if (p == p0 && len == 0) - return 1; - } -#endif /* BSDCOMPRESS_SUPPORT */ -#if PREDICTOR_SUPPORT - if (go->predictor_1) { - if (len < CILEN_PREDICTOR_1 - || p[0] != CI_PREDICTOR_1 || p[1] != CILEN_PREDICTOR_1) - return 0; - p += CILEN_PREDICTOR_1; - len -= CILEN_PREDICTOR_1; - /* XXX Cope with first/fast ack */ - if (p == p0 && len == 0) - return 1; - } - if (go->predictor_2) { - if (len < CILEN_PREDICTOR_2 - || p[0] != CI_PREDICTOR_2 || p[1] != CILEN_PREDICTOR_2) - return 0; - p += CILEN_PREDICTOR_2; - len -= CILEN_PREDICTOR_2; - /* XXX Cope with first/fast ack */ - if (p == p0 && len == 0) - return 1; - } -#endif /* PREDICTOR_SUPPORT */ - - if (len != 0) - return 0; - return 1; -} - -/* - * ccp_nakci - process received configure-nak. - * Returns 1 iff the nak was OK. - */ -static int ccp_nakci(fsm *f, u_char *p, int len, int treat_as_reject) { - ppp_pcb *pcb = f->pcb; - ccp_options *go = &pcb->ccp_gotoptions; - ccp_options no; /* options we've seen already */ - ccp_options try_; /* options to ask for next time */ - LWIP_UNUSED_ARG(treat_as_reject); -#if !MPPE_SUPPORT && !DEFLATE_SUPPORT && !BSDCOMPRESS_SUPPORT - LWIP_UNUSED_ARG(p); - LWIP_UNUSED_ARG(len); -#endif /* !MPPE_SUPPORT && !DEFLATE_SUPPORT && !BSDCOMPRESS_SUPPORT */ - - memset(&no, 0, sizeof(no)); - try_ = *go; - -#if MPPE_SUPPORT - if (go->mppe && len >= CILEN_MPPE - && p[0] == CI_MPPE && p[1] == CILEN_MPPE) { - no.mppe = 1; - /* - * Peer wants us to use a different strength or other setting. - * Fail if we aren't willing to use his suggestion. - */ - MPPE_CI_TO_OPTS(&p[2], try_.mppe); - if ((try_.mppe & MPPE_OPT_STATEFUL) && pcb->settings.refuse_mppe_stateful) { - ppp_error("Refusing MPPE stateful mode offered by peer"); - try_.mppe = 0; - } else if (((go->mppe | MPPE_OPT_STATEFUL) & try_.mppe) != try_.mppe) { - /* Peer must have set options we didn't request (suggest) */ - try_.mppe = 0; - } - - if (!try_.mppe) { - ppp_error("MPPE required but peer negotiation failed"); - lcp_close(pcb, "MPPE required but peer negotiation failed"); - } - } -#endif /* MPPE_SUPPORT */ -#if DEFLATE_SUPPORT - if (go->deflate && len >= CILEN_DEFLATE - && p[0] == (go->deflate_correct? CI_DEFLATE: CI_DEFLATE_DRAFT) - && p[1] == CILEN_DEFLATE) { - no.deflate = 1; - /* - * Peer wants us to use a different code size or something. - * Stop asking for Deflate if we don't understand his suggestion. - */ - if (DEFLATE_METHOD(p[2]) != DEFLATE_METHOD_VAL - || DEFLATE_SIZE(p[2]) < DEFLATE_MIN_WORKS - || p[3] != DEFLATE_CHK_SEQUENCE) - try_.deflate = 0; - else if (DEFLATE_SIZE(p[2]) < go->deflate_size) - try_.deflate_size = DEFLATE_SIZE(p[2]); - p += CILEN_DEFLATE; - len -= CILEN_DEFLATE; - if (go->deflate_correct && go->deflate_draft - && len >= CILEN_DEFLATE && p[0] == CI_DEFLATE_DRAFT - && p[1] == CILEN_DEFLATE) { - p += CILEN_DEFLATE; - len -= CILEN_DEFLATE; - } - } -#endif /* DEFLATE_SUPPORT */ -#if BSDCOMPRESS_SUPPORT - if (go->bsd_compress && len >= CILEN_BSD_COMPRESS - && p[0] == CI_BSD_COMPRESS && p[1] == CILEN_BSD_COMPRESS) { - no.bsd_compress = 1; - /* - * Peer wants us to use a different number of bits - * or a different version. - */ - if (BSD_VERSION(p[2]) != BSD_CURRENT_VERSION) - try_.bsd_compress = 0; - else if (BSD_NBITS(p[2]) < go->bsd_bits) - try_.bsd_bits = BSD_NBITS(p[2]); - p += CILEN_BSD_COMPRESS; - len -= CILEN_BSD_COMPRESS; - } -#endif /* BSDCOMPRESS_SUPPORT */ - - /* - * Predictor-1 and 2 have no options, so they can't be Naked. - * - * There may be remaining options but we ignore them. - */ - - if (f->state != PPP_FSM_OPENED) - *go = try_; - return 1; -} - -/* - * ccp_rejci - reject some of our suggested compression methods. - */ -static int ccp_rejci(fsm *f, u_char *p, int len) { - ppp_pcb *pcb = f->pcb; - ccp_options *go = &pcb->ccp_gotoptions; - ccp_options try_; /* options to request next time */ - - try_ = *go; - - /* - * Cope with empty configure-rejects by ceasing to send - * configure-requests. - */ - if (len == 0 && pcb->ccp_all_rejected) - return -1; - -#if MPPE_SUPPORT - if (go->mppe && len >= CILEN_MPPE - && p[0] == CI_MPPE && p[1] == CILEN_MPPE) { - ppp_error("MPPE required but peer refused"); - lcp_close(pcb, "MPPE required but peer refused"); - p += CILEN_MPPE; - len -= CILEN_MPPE; - } -#endif /* MPPE_SUPPORT */ -#if DEFLATE_SUPPORT - if (go->deflate_correct && len >= CILEN_DEFLATE - && p[0] == CI_DEFLATE && p[1] == CILEN_DEFLATE) { - if (p[2] != DEFLATE_MAKE_OPT(go->deflate_size) - || p[3] != DEFLATE_CHK_SEQUENCE) - return 0; /* Rej is bad */ - try_.deflate_correct = 0; - p += CILEN_DEFLATE; - len -= CILEN_DEFLATE; - } - if (go->deflate_draft && len >= CILEN_DEFLATE - && p[0] == CI_DEFLATE_DRAFT && p[1] == CILEN_DEFLATE) { - if (p[2] != DEFLATE_MAKE_OPT(go->deflate_size) - || p[3] != DEFLATE_CHK_SEQUENCE) - return 0; /* Rej is bad */ - try_.deflate_draft = 0; - p += CILEN_DEFLATE; - len -= CILEN_DEFLATE; - } - if (!try_.deflate_correct && !try_.deflate_draft) - try_.deflate = 0; -#endif /* DEFLATE_SUPPORT */ -#if BSDCOMPRESS_SUPPORT - if (go->bsd_compress && len >= CILEN_BSD_COMPRESS - && p[0] == CI_BSD_COMPRESS && p[1] == CILEN_BSD_COMPRESS) { - if (p[2] != BSD_MAKE_OPT(BSD_CURRENT_VERSION, go->bsd_bits)) - return 0; - try_.bsd_compress = 0; - p += CILEN_BSD_COMPRESS; - len -= CILEN_BSD_COMPRESS; - } -#endif /* BSDCOMPRESS_SUPPORT */ -#if PREDICTOR_SUPPORT - if (go->predictor_1 && len >= CILEN_PREDICTOR_1 - && p[0] == CI_PREDICTOR_1 && p[1] == CILEN_PREDICTOR_1) { - try_.predictor_1 = 0; - p += CILEN_PREDICTOR_1; - len -= CILEN_PREDICTOR_1; - } - if (go->predictor_2 && len >= CILEN_PREDICTOR_2 - && p[0] == CI_PREDICTOR_2 && p[1] == CILEN_PREDICTOR_2) { - try_.predictor_2 = 0; - p += CILEN_PREDICTOR_2; - len -= CILEN_PREDICTOR_2; - } -#endif /* PREDICTOR_SUPPORT */ - - if (len != 0) - return 0; - - if (f->state != PPP_FSM_OPENED) - *go = try_; - - return 1; -} - -/* - * ccp_reqci - processed a received configure-request. - * Returns CONFACK, CONFNAK or CONFREJ and the packet modified - * appropriately. - */ -static int ccp_reqci(fsm *f, u_char *p, int *lenp, int dont_nak) { - ppp_pcb *pcb = f->pcb; - ccp_options *ho = &pcb->ccp_hisoptions; - ccp_options *ao = &pcb->ccp_allowoptions; - int ret, newret; -#if DEFLATE_SUPPORT || BSDCOMPRESS_SUPPORT - int res; - int nb; -#endif /* DEFLATE_SUPPORT || BSDCOMPRESS_SUPPORT */ - u_char *p0, *retp; - int len, clen, type; -#if MPPE_SUPPORT - u8_t rej_for_ci_mppe = 1; /* Are we rejecting based on a bad/missing */ - /* CI_MPPE, or due to other options? */ -#endif /* MPPE_SUPPORT */ - - ret = CONFACK; - retp = p0 = p; - len = *lenp; - - memset(ho, 0, sizeof(ccp_options)); - ho->method = (len > 0)? p[0]: 0; - - while (len > 0) { - newret = CONFACK; - if (len < 2 || p[1] < 2 || p[1] > len) { - /* length is bad */ - clen = len; - newret = CONFREJ; - - } else { - type = p[0]; - clen = p[1]; - - switch (type) { -#if MPPE_SUPPORT - case CI_MPPE: - if (!ao->mppe || clen != CILEN_MPPE) { - newret = CONFREJ; - break; - } - MPPE_CI_TO_OPTS(&p[2], ho->mppe); - - /* Nak if anything unsupported or unknown are set. */ - if (ho->mppe & MPPE_OPT_UNSUPPORTED) { - newret = CONFNAK; - ho->mppe &= ~MPPE_OPT_UNSUPPORTED; - } - if (ho->mppe & MPPE_OPT_UNKNOWN) { - newret = CONFNAK; - ho->mppe &= ~MPPE_OPT_UNKNOWN; - } - - /* Check state opt */ - if (ho->mppe & MPPE_OPT_STATEFUL) { - /* - * We can Nak and request stateless, but it's a - * lot easier to just assume the peer will request - * it if he can do it; stateful mode is bad over - * the Internet -- which is where we expect MPPE. - */ - if (pcb->settings.refuse_mppe_stateful) { - ppp_error("Refusing MPPE stateful mode offered by peer"); - newret = CONFREJ; - break; - } - } - - /* Find out which of {S,L} are set. */ - if ((ho->mppe & MPPE_OPT_128) - && (ho->mppe & MPPE_OPT_40)) { - /* Both are set, negotiate the strongest. */ - newret = CONFNAK; - if (ao->mppe & MPPE_OPT_128) - ho->mppe &= ~MPPE_OPT_40; - else if (ao->mppe & MPPE_OPT_40) - ho->mppe &= ~MPPE_OPT_128; - else { - newret = CONFREJ; - break; - } - } else if (ho->mppe & MPPE_OPT_128) { - if (!(ao->mppe & MPPE_OPT_128)) { - newret = CONFREJ; - break; - } - } else if (ho->mppe & MPPE_OPT_40) { - if (!(ao->mppe & MPPE_OPT_40)) { - newret = CONFREJ; - break; - } - } else { - /* Neither are set. */ - /* We cannot accept this. */ - newret = CONFNAK; - /* Give the peer our idea of what can be used, - so it can choose and confirm */ - ho->mppe = ao->mppe; - } - - /* rebuild the opts */ - MPPE_OPTS_TO_CI(ho->mppe, &p[2]); - if (newret == CONFACK) { - int mtu; - - mppe_init(pcb, &pcb->mppe_comp, ho->mppe); - /* - * We need to decrease the interface MTU by MPPE_PAD - * because MPPE frames **grow**. The kernel [must] - * allocate MPPE_PAD extra bytes in xmit buffers. - */ - mtu = netif_get_mtu(pcb); - if (mtu) - netif_set_mtu(pcb, mtu - MPPE_PAD); - else - newret = CONFREJ; - } - - /* - * We have accepted MPPE or are willing to negotiate - * MPPE parameters. A CONFREJ is due to subsequent - * (non-MPPE) processing. - */ - rej_for_ci_mppe = 0; - break; -#endif /* MPPE_SUPPORT */ -#if DEFLATE_SUPPORT - case CI_DEFLATE: - case CI_DEFLATE_DRAFT: - if (!ao->deflate || clen != CILEN_DEFLATE - || (!ao->deflate_correct && type == CI_DEFLATE) - || (!ao->deflate_draft && type == CI_DEFLATE_DRAFT)) { - newret = CONFREJ; - break; - } - - ho->deflate = 1; - ho->deflate_size = nb = DEFLATE_SIZE(p[2]); - if (DEFLATE_METHOD(p[2]) != DEFLATE_METHOD_VAL - || p[3] != DEFLATE_CHK_SEQUENCE - || nb > ao->deflate_size || nb < DEFLATE_MIN_WORKS) { - newret = CONFNAK; - if (!dont_nak) { - p[2] = DEFLATE_MAKE_OPT(ao->deflate_size); - p[3] = DEFLATE_CHK_SEQUENCE; - /* fall through to test this #bits below */ - } else - break; - } - - /* - * Check whether we can do Deflate with the window - * size they want. If the window is too big, reduce - * it until the kernel can cope and nak with that. - * We only check this for the first option. - */ - if (p == p0) { - for (;;) { - res = ccp_test(pcb, p, CILEN_DEFLATE, 1); - if (res > 0) - break; /* it's OK now */ - if (res < 0 || nb == DEFLATE_MIN_WORKS || dont_nak) { - newret = CONFREJ; - p[2] = DEFLATE_MAKE_OPT(ho->deflate_size); - break; - } - newret = CONFNAK; - --nb; - p[2] = DEFLATE_MAKE_OPT(nb); - } - } - break; -#endif /* DEFLATE_SUPPORT */ -#if BSDCOMPRESS_SUPPORT - case CI_BSD_COMPRESS: - if (!ao->bsd_compress || clen != CILEN_BSD_COMPRESS) { - newret = CONFREJ; - break; - } - - ho->bsd_compress = 1; - ho->bsd_bits = nb = BSD_NBITS(p[2]); - if (BSD_VERSION(p[2]) != BSD_CURRENT_VERSION - || nb > ao->bsd_bits || nb < BSD_MIN_BITS) { - newret = CONFNAK; - if (!dont_nak) { - p[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, ao->bsd_bits); - /* fall through to test this #bits below */ - } else - break; - } - - /* - * Check whether we can do BSD-Compress with the code - * size they want. If the code size is too big, reduce - * it until the kernel can cope and nak with that. - * We only check this for the first option. - */ - if (p == p0) { - for (;;) { - res = ccp_test(pcb, p, CILEN_BSD_COMPRESS, 1); - if (res > 0) - break; - if (res < 0 || nb == BSD_MIN_BITS || dont_nak) { - newret = CONFREJ; - p[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, - ho->bsd_bits); - break; - } - newret = CONFNAK; - --nb; - p[2] = BSD_MAKE_OPT(BSD_CURRENT_VERSION, nb); - } - } - break; -#endif /* BSDCOMPRESS_SUPPORT */ -#if PREDICTOR_SUPPORT - case CI_PREDICTOR_1: - if (!ao->predictor_1 || clen != CILEN_PREDICTOR_1) { - newret = CONFREJ; - break; - } - - ho->predictor_1 = 1; - if (p == p0 - && ccp_test(pcb, p, CILEN_PREDICTOR_1, 1) <= 0) { - newret = CONFREJ; - } - break; - - case CI_PREDICTOR_2: - if (!ao->predictor_2 || clen != CILEN_PREDICTOR_2) { - newret = CONFREJ; - break; - } - - ho->predictor_2 = 1; - if (p == p0 - && ccp_test(pcb, p, CILEN_PREDICTOR_2, 1) <= 0) { - newret = CONFREJ; - } - break; -#endif /* PREDICTOR_SUPPORT */ - - default: - newret = CONFREJ; - } - } - - if (newret == CONFNAK && dont_nak) - newret = CONFREJ; - if (!(newret == CONFACK || (newret == CONFNAK && ret == CONFREJ))) { - /* we're returning this option */ - if (newret == CONFREJ && ret == CONFNAK) - retp = p0; - ret = newret; - if (p != retp) - MEMCPY(retp, p, clen); - retp += clen; - } - - p += clen; - len -= clen; - } - - if (ret != CONFACK) { - if (ret == CONFREJ && *lenp == retp - p0) - pcb->ccp_all_rejected = 1; - else - *lenp = retp - p0; - } -#if MPPE_SUPPORT - if (ret == CONFREJ && ao->mppe && rej_for_ci_mppe) { - ppp_error("MPPE required but peer negotiation failed"); - lcp_close(pcb, "MPPE required but peer negotiation failed"); - } -#endif /* MPPE_SUPPORT */ - return ret; -} - -/* - * Make a string name for a compression method (or 2). - */ -static const char *method_name(ccp_options *opt, ccp_options *opt2) { - static char result[64]; -#if !DEFLATE_SUPPORT && !BSDCOMPRESS_SUPPORT - LWIP_UNUSED_ARG(opt2); -#endif /* !DEFLATE_SUPPORT && !BSDCOMPRESS_SUPPORT */ - - if (!ccp_anycompress(opt)) - return "(none)"; - switch (opt->method) { -#if MPPE_SUPPORT - case CI_MPPE: - { - char *p = result; - char *q = result + sizeof(result); /* 1 past result */ - - ppp_slprintf(p, q - p, "MPPE "); - p += 5; - if (opt->mppe & MPPE_OPT_128) { - ppp_slprintf(p, q - p, "128-bit "); - p += 8; - } - if (opt->mppe & MPPE_OPT_40) { - ppp_slprintf(p, q - p, "40-bit "); - p += 7; - } - if (opt->mppe & MPPE_OPT_STATEFUL) - ppp_slprintf(p, q - p, "stateful"); - else - ppp_slprintf(p, q - p, "stateless"); - - break; - } -#endif /* MPPE_SUPPORT */ -#if DEFLATE_SUPPORT - case CI_DEFLATE: - case CI_DEFLATE_DRAFT: - if (opt2 != NULL && opt2->deflate_size != opt->deflate_size) - ppp_slprintf(result, sizeof(result), "Deflate%s (%d/%d)", - (opt->method == CI_DEFLATE_DRAFT? "(old#)": ""), - opt->deflate_size, opt2->deflate_size); - else - ppp_slprintf(result, sizeof(result), "Deflate%s (%d)", - (opt->method == CI_DEFLATE_DRAFT? "(old#)": ""), - opt->deflate_size); - break; -#endif /* DEFLATE_SUPPORT */ -#if BSDCOMPRESS_SUPPORT - case CI_BSD_COMPRESS: - if (opt2 != NULL && opt2->bsd_bits != opt->bsd_bits) - ppp_slprintf(result, sizeof(result), "BSD-Compress (%d/%d)", - opt->bsd_bits, opt2->bsd_bits); - else - ppp_slprintf(result, sizeof(result), "BSD-Compress (%d)", - opt->bsd_bits); - break; -#endif /* BSDCOMPRESS_SUPPORT */ -#if PREDICTOR_SUPPORT - case CI_PREDICTOR_1: - return "Predictor 1"; - case CI_PREDICTOR_2: - return "Predictor 2"; -#endif /* PREDICTOR_SUPPORT */ - default: - ppp_slprintf(result, sizeof(result), "Method %d", opt->method); - } - return result; -} - -/* - * CCP has come up - inform the kernel driver and log a message. - */ -static void ccp_up(fsm *f) { - ppp_pcb *pcb = f->pcb; - ccp_options *go = &pcb->ccp_gotoptions; - ccp_options *ho = &pcb->ccp_hisoptions; - char method1[64]; - - ccp_set(pcb, 1, 1, go->method, ho->method); - if (ccp_anycompress(go)) { - if (ccp_anycompress(ho)) { - if (go->method == ho->method) { - ppp_notice("%s compression enabled", method_name(go, ho)); - } else { - ppp_strlcpy(method1, method_name(go, NULL), sizeof(method1)); - ppp_notice("%s / %s compression enabled", - method1, method_name(ho, NULL)); - } - } else - ppp_notice("%s receive compression enabled", method_name(go, NULL)); - } else if (ccp_anycompress(ho)) - ppp_notice("%s transmit compression enabled", method_name(ho, NULL)); -#if MPPE_SUPPORT - if (go->mppe) { - continue_networks(pcb); /* Bring up IP et al */ - } -#endif /* MPPE_SUPPORT */ -} - -/* - * CCP has gone down - inform the kernel driver. - */ -static void ccp_down(fsm *f) { - ppp_pcb *pcb = f->pcb; -#if MPPE_SUPPORT - ccp_options *go = &pcb->ccp_gotoptions; -#endif /* MPPE_SUPPORT */ - - if (pcb->ccp_localstate & RACK_PENDING) - UNTIMEOUT(ccp_rack_timeout, f); - pcb->ccp_localstate = 0; - ccp_set(pcb, 1, 0, 0, 0); -#if MPPE_SUPPORT - if (go->mppe) { - go->mppe = 0; - if (pcb->lcp_fsm.state == PPP_FSM_OPENED) { - /* If LCP is not already going down, make sure it does. */ - ppp_error("MPPE disabled"); - lcp_close(pcb, "MPPE disabled"); - } - } -#endif /* MPPE_SUPPORT */ -} - -#if PRINTPKT_SUPPORT -/* - * Print the contents of a CCP packet. - */ -static const char* const ccp_codenames[] = { - "ConfReq", "ConfAck", "ConfNak", "ConfRej", - "TermReq", "TermAck", "CodeRej", - NULL, NULL, NULL, NULL, NULL, NULL, - "ResetReq", "ResetAck", -}; - -static int ccp_printpkt(const u_char *p, int plen, void (*printer) (void *, const char *, ...), void *arg) { - const u_char *p0, *optend; - int code, id, len; - int optlen; - - p0 = p; - if (plen < HEADERLEN) - return 0; - code = p[0]; - id = p[1]; - len = (p[2] << 8) + p[3]; - if (len < HEADERLEN || len > plen) - return 0; - - if (code >= 1 && code <= (int)LWIP_ARRAYSIZE(ccp_codenames) && ccp_codenames[code-1] != NULL) - printer(arg, " %s", ccp_codenames[code-1]); - else - printer(arg, " code=0x%x", code); - printer(arg, " id=0x%x", id); - len -= HEADERLEN; - p += HEADERLEN; - - switch (code) { - case CONFREQ: - case CONFACK: - case CONFNAK: - case CONFREJ: - /* print list of possible compression methods */ - while (len >= 2) { - code = p[0]; - optlen = p[1]; - if (optlen < 2 || optlen > len) - break; - printer(arg, " <"); - len -= optlen; - optend = p + optlen; - switch (code) { -#if MPPE_SUPPORT - case CI_MPPE: - if (optlen >= CILEN_MPPE) { - u_char mppe_opts; - - MPPE_CI_TO_OPTS(&p[2], mppe_opts); - printer(arg, "mppe %s %s %s %s %s %s%s", - (p[2] & MPPE_H_BIT)? "+H": "-H", - (p[5] & MPPE_M_BIT)? "+M": "-M", - (p[5] & MPPE_S_BIT)? "+S": "-S", - (p[5] & MPPE_L_BIT)? "+L": "-L", - (p[5] & MPPE_D_BIT)? "+D": "-D", - (p[5] & MPPE_C_BIT)? "+C": "-C", - (mppe_opts & MPPE_OPT_UNKNOWN)? " +U": ""); - if (mppe_opts & MPPE_OPT_UNKNOWN) - printer(arg, " (%.2x %.2x %.2x %.2x)", - p[2], p[3], p[4], p[5]); - p += CILEN_MPPE; - } - break; -#endif /* MPPE_SUPPORT */ -#if DEFLATE_SUPPORT - case CI_DEFLATE: - case CI_DEFLATE_DRAFT: - if (optlen >= CILEN_DEFLATE) { - printer(arg, "deflate%s %d", - (code == CI_DEFLATE_DRAFT? "(old#)": ""), - DEFLATE_SIZE(p[2])); - if (DEFLATE_METHOD(p[2]) != DEFLATE_METHOD_VAL) - printer(arg, " method %d", DEFLATE_METHOD(p[2])); - if (p[3] != DEFLATE_CHK_SEQUENCE) - printer(arg, " check %d", p[3]); - p += CILEN_DEFLATE; - } - break; -#endif /* DEFLATE_SUPPORT */ -#if BSDCOMPRESS_SUPPORT - case CI_BSD_COMPRESS: - if (optlen >= CILEN_BSD_COMPRESS) { - printer(arg, "bsd v%d %d", BSD_VERSION(p[2]), - BSD_NBITS(p[2])); - p += CILEN_BSD_COMPRESS; - } - break; -#endif /* BSDCOMPRESS_SUPPORT */ -#if PREDICTOR_SUPPORT - case CI_PREDICTOR_1: - if (optlen >= CILEN_PREDICTOR_1) { - printer(arg, "predictor 1"); - p += CILEN_PREDICTOR_1; - } - break; - case CI_PREDICTOR_2: - if (optlen >= CILEN_PREDICTOR_2) { - printer(arg, "predictor 2"); - p += CILEN_PREDICTOR_2; - } - break; -#endif /* PREDICTOR_SUPPORT */ - default: - break; - } - while (p < optend) - printer(arg, " %.2x", *p++); - printer(arg, ">"); - } - break; - - case TERMACK: - case TERMREQ: - if (len > 0 && *p >= ' ' && *p < 0x7f) { - ppp_print_string(p, len, printer, arg); - p += len; - len = 0; - } - break; - default: - break; - } - - /* dump out the rest of the packet in hex */ - while (--len >= 0) - printer(arg, " %.2x", *p++); - - return p - p0; -} -#endif /* PRINTPKT_SUPPORT */ - -#if PPP_DATAINPUT -/* - * We have received a packet that the decompressor failed to - * decompress. Here we would expect to issue a reset-request, but - * Motorola has a patent on resetting the compressor as a result of - * detecting an error in the decompressed data after decompression. - * (See US patent 5,130,993; international patent publication number - * WO 91/10289; Australian patent 73296/91.) - * - * So we ask the kernel whether the error was detected after - * decompression; if it was, we take CCP down, thus disabling - * compression :-(, otherwise we issue the reset-request. - */ -static void ccp_datainput(ppp_pcb *pcb, u_char *pkt, int len) { - fsm *f; -#if MPPE_SUPPORT - ccp_options *go = &pcb->ccp_gotoptions; -#endif /* MPPE_SUPPORT */ - LWIP_UNUSED_ARG(pkt); - LWIP_UNUSED_ARG(len); - - f = &pcb->ccp_fsm; - if (f->state == PPP_FSM_OPENED) { - if (ccp_fatal_error(pcb)) { - /* - * Disable compression by taking CCP down. - */ - ppp_error("Lost compression sync: disabling compression"); - ccp_close(pcb, "Lost compression sync"); -#if MPPE_SUPPORT - /* - * If we were doing MPPE, we must also take the link down. - */ - if (go->mppe) { - ppp_error("Too many MPPE errors, closing LCP"); - lcp_close(pcb, "Too many MPPE errors"); - } -#endif /* MPPE_SUPPORT */ - } else { - /* - * Send a reset-request to reset the peer's compressor. - * We don't do that if we are still waiting for an - * acknowledgement to a previous reset-request. - */ - if (!(pcb->ccp_localstate & RACK_PENDING)) { - fsm_sdata(f, CCP_RESETREQ, f->reqid = ++f->id, NULL, 0); - TIMEOUT(ccp_rack_timeout, f, RACKTIMEOUT); - pcb->ccp_localstate |= RACK_PENDING; - } else - pcb->ccp_localstate |= RREQ_REPEAT; - } - } -} -#endif /* PPP_DATAINPUT */ - -/* - * We have received a packet that the decompressor failed to - * decompress. Issue a reset-request. - */ -void ccp_resetrequest(ppp_pcb *pcb) { - fsm *f = &pcb->ccp_fsm; - - if (f->state != PPP_FSM_OPENED) - return; - - /* - * Send a reset-request to reset the peer's compressor. - * We don't do that if we are still waiting for an - * acknowledgement to a previous reset-request. - */ - if (!(pcb->ccp_localstate & RACK_PENDING)) { - fsm_sdata(f, CCP_RESETREQ, f->reqid = ++f->id, NULL, 0); - TIMEOUT(ccp_rack_timeout, f, RACKTIMEOUT); - pcb->ccp_localstate |= RACK_PENDING; - } else - pcb->ccp_localstate |= RREQ_REPEAT; -} - -/* - * Timeout waiting for reset-ack. - */ -static void ccp_rack_timeout(void *arg) { - fsm *f = (fsm*)arg; - ppp_pcb *pcb = f->pcb; - - if (f->state == PPP_FSM_OPENED && (pcb->ccp_localstate & RREQ_REPEAT)) { - fsm_sdata(f, CCP_RESETREQ, f->reqid, NULL, 0); - TIMEOUT(ccp_rack_timeout, f, RACKTIMEOUT); - pcb->ccp_localstate &= ~RREQ_REPEAT; - } else - pcb->ccp_localstate &= ~RACK_PENDING; -} - -#endif /* PPP_SUPPORT && CCP_SUPPORT */ diff --git a/third_party/lwip/repo/lwip/src/netif/ppp/chap-md5.c b/third_party/lwip/repo/lwip/src/netif/ppp/chap-md5.c deleted file mode 100644 index 88f069f032cd5b..00000000000000 --- a/third_party/lwip/repo/lwip/src/netif/ppp/chap-md5.c +++ /dev/null @@ -1,126 +0,0 @@ -/* - * chap-md5.c - New CHAP/MD5 implementation. - * - * Copyright (c) 2003 Paul Mackerras. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. The name(s) of the authors of this software must not be used to - * endorse or promote products derived from this software without - * prior written permission. - * - * 3. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Paul Mackerras - * ". - * - * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT && CHAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#if 0 /* UNUSED */ -#include -#include -#endif /* UNUSED */ - -#include "netif/ppp/ppp_impl.h" - -#include "netif/ppp/chap-new.h" -#include "netif/ppp/chap-md5.h" -#include "netif/ppp/magic.h" -#include "netif/ppp/pppcrypt.h" - -#define MD5_HASH_SIZE 16 -#define MD5_MIN_CHALLENGE 17 -#define MD5_MAX_CHALLENGE 24 -#define MD5_MIN_MAX_POWER_OF_TWO_CHALLENGE 3 /* 2^3-1 = 7, 17+7 = 24 */ - -#if PPP_SERVER -static void chap_md5_generate_challenge(ppp_pcb *pcb, unsigned char *cp) { - int clen; - LWIP_UNUSED_ARG(pcb); - - clen = MD5_MIN_CHALLENGE + magic_pow(MD5_MIN_MAX_POWER_OF_TWO_CHALLENGE); - *cp++ = clen; - magic_random_bytes(cp, clen); -} - -static int chap_md5_verify_response(ppp_pcb *pcb, int id, const char *name, - const unsigned char *secret, int secret_len, - const unsigned char *challenge, const unsigned char *response, - char *message, int message_space) { - lwip_md5_context ctx; - unsigned char idbyte = id; - unsigned char hash[MD5_HASH_SIZE]; - int challenge_len, response_len; - LWIP_UNUSED_ARG(name); - LWIP_UNUSED_ARG(pcb); - - challenge_len = *challenge++; - response_len = *response++; - if (response_len == MD5_HASH_SIZE) { - /* Generate hash of ID, secret, challenge */ - lwip_md5_init(&ctx); - lwip_md5_starts(&ctx); - lwip_md5_update(&ctx, &idbyte, 1); - lwip_md5_update(&ctx, secret, secret_len); - lwip_md5_update(&ctx, challenge, challenge_len); - lwip_md5_finish(&ctx, hash); - lwip_md5_free(&ctx); - - /* Test if our hash matches the peer's response */ - if (memcmp(hash, response, MD5_HASH_SIZE) == 0) { - ppp_slprintf(message, message_space, "Access granted"); - return 1; - } - } - ppp_slprintf(message, message_space, "Access denied"); - return 0; -} -#endif /* PPP_SERVER */ - -static void chap_md5_make_response(ppp_pcb *pcb, unsigned char *response, int id, const char *our_name, - const unsigned char *challenge, const char *secret, int secret_len, - unsigned char *private_) { - lwip_md5_context ctx; - unsigned char idbyte = id; - int challenge_len = *challenge++; - LWIP_UNUSED_ARG(our_name); - LWIP_UNUSED_ARG(private_); - LWIP_UNUSED_ARG(pcb); - - lwip_md5_init(&ctx); - lwip_md5_starts(&ctx); - lwip_md5_update(&ctx, &idbyte, 1); - lwip_md5_update(&ctx, (const u_char *)secret, secret_len); - lwip_md5_update(&ctx, challenge, challenge_len); - lwip_md5_finish(&ctx, &response[1]); - lwip_md5_free(&ctx); - response[0] = MD5_HASH_SIZE; -} - -const struct chap_digest_type md5_digest = { - CHAP_MD5, /* code */ -#if PPP_SERVER - chap_md5_generate_challenge, - chap_md5_verify_response, -#endif /* PPP_SERVER */ - chap_md5_make_response, - NULL, /* check_success */ - NULL, /* handle_failure */ -}; - -#endif /* PPP_SUPPORT && CHAP_SUPPORT */ diff --git a/third_party/lwip/repo/lwip/src/netif/ppp/chap-new.c b/third_party/lwip/repo/lwip/src/netif/ppp/chap-new.c deleted file mode 100644 index 485122d272aad4..00000000000000 --- a/third_party/lwip/repo/lwip/src/netif/ppp/chap-new.c +++ /dev/null @@ -1,677 +0,0 @@ -/* - * chap-new.c - New CHAP implementation. - * - * Copyright (c) 2003 Paul Mackerras. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. The name(s) of the authors of this software must not be used to - * endorse or promote products derived from this software without - * prior written permission. - * - * 3. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Paul Mackerras - * ". - * - * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT && CHAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#if 0 /* UNUSED */ -#include -#include -#endif /* UNUSED */ - -#include "netif/ppp/ppp_impl.h" - -#if 0 /* UNUSED */ -#include "session.h" -#endif /* UNUSED */ - -#include "netif/ppp/chap-new.h" -#include "netif/ppp/chap-md5.h" -#if MSCHAP_SUPPORT -#include "netif/ppp/chap_ms.h" -#endif -#include "netif/ppp/magic.h" - -#if 0 /* UNUSED */ -/* Hook for a plugin to validate CHAP challenge */ -int (*chap_verify_hook)(const char *name, const char *ourname, int id, - const struct chap_digest_type *digest, - const unsigned char *challenge, const unsigned char *response, - char *message, int message_space) = NULL; -#endif /* UNUSED */ - -#if PPP_OPTIONS -/* - * Command-line options. - */ -static option_t chap_option_list[] = { - { "chap-restart", o_int, &chap_timeout_time, - "Set timeout for CHAP", OPT_PRIO }, - { "chap-max-challenge", o_int, &pcb->settings.chap_max_transmits, - "Set max #xmits for challenge", OPT_PRIO }, - { "chap-interval", o_int, &pcb->settings.chap_rechallenge_time, - "Set interval for rechallenge", OPT_PRIO }, - { NULL } -}; -#endif /* PPP_OPTIONS */ - - -/* Values for flags in chap_client_state and chap_server_state */ -#define LOWERUP 1 -#define AUTH_STARTED 2 -#define AUTH_DONE 4 -#define AUTH_FAILED 8 -#define TIMEOUT_PENDING 0x10 -#define CHALLENGE_VALID 0x20 - -/* - * Prototypes. - */ -static void chap_init(ppp_pcb *pcb); -static void chap_lowerup(ppp_pcb *pcb); -static void chap_lowerdown(ppp_pcb *pcb); -#if PPP_SERVER -static void chap_timeout(void *arg); -static void chap_generate_challenge(ppp_pcb *pcb); -static void chap_handle_response(ppp_pcb *pcb, int code, - unsigned char *pkt, int len); -static int chap_verify_response(ppp_pcb *pcb, const char *name, const char *ourname, int id, - const struct chap_digest_type *digest, - const unsigned char *challenge, const unsigned char *response, - char *message, int message_space); -#endif /* PPP_SERVER */ -static void chap_respond(ppp_pcb *pcb, int id, - unsigned char *pkt, int len); -static void chap_handle_status(ppp_pcb *pcb, int code, int id, - unsigned char *pkt, int len); -static void chap_protrej(ppp_pcb *pcb); -static void chap_input(ppp_pcb *pcb, unsigned char *pkt, int pktlen); -#if PRINTPKT_SUPPORT -static int chap_print_pkt(const unsigned char *p, int plen, - void (*printer) (void *, const char *, ...), void *arg); -#endif /* PRINTPKT_SUPPORT */ - -/* List of digest types that we know about */ -static const struct chap_digest_type* const chap_digests[] = { - &md5_digest, -#if MSCHAP_SUPPORT - &chapms_digest, - &chapms2_digest, -#endif /* MSCHAP_SUPPORT */ - NULL -}; - -/* - * chap_init - reset to initial state. - */ -static void chap_init(ppp_pcb *pcb) { - LWIP_UNUSED_ARG(pcb); - -#if 0 /* Not necessary, everything is cleared in ppp_new() */ - memset(&pcb->chap_client, 0, sizeof(chap_client_state)); -#if PPP_SERVER - memset(&pcb->chap_server, 0, sizeof(chap_server_state)); -#endif /* PPP_SERVER */ -#endif /* 0 */ -} - -/* - * chap_lowerup - we can start doing stuff now. - */ -static void chap_lowerup(ppp_pcb *pcb) { - - pcb->chap_client.flags |= LOWERUP; -#if PPP_SERVER - pcb->chap_server.flags |= LOWERUP; - if (pcb->chap_server.flags & AUTH_STARTED) - chap_timeout(pcb); -#endif /* PPP_SERVER */ -} - -static void chap_lowerdown(ppp_pcb *pcb) { - - pcb->chap_client.flags = 0; -#if PPP_SERVER - if (pcb->chap_server.flags & TIMEOUT_PENDING) - UNTIMEOUT(chap_timeout, pcb); - pcb->chap_server.flags = 0; -#endif /* PPP_SERVER */ -} - -#if PPP_SERVER -/* - * chap_auth_peer - Start authenticating the peer. - * If the lower layer is already up, we start sending challenges, - * otherwise we wait for the lower layer to come up. - */ -void chap_auth_peer(ppp_pcb *pcb, const char *our_name, int digest_code) { - const struct chap_digest_type *dp; - int i; - - if (pcb->chap_server.flags & AUTH_STARTED) { - ppp_error("CHAP: peer authentication already started!"); - return; - } - for (i = 0; (dp = chap_digests[i]) != NULL; ++i) - if (dp->code == digest_code) - break; - if (dp == NULL) - ppp_fatal("CHAP digest 0x%x requested but not available", - digest_code); - - pcb->chap_server.digest = dp; - pcb->chap_server.name = our_name; - /* Start with a random ID value */ - pcb->chap_server.id = magic(); - pcb->chap_server.flags |= AUTH_STARTED; - if (pcb->chap_server.flags & LOWERUP) - chap_timeout(pcb); -} -#endif /* PPP_SERVER */ - -/* - * chap_auth_with_peer - Prepare to authenticate ourselves to the peer. - * There isn't much to do until we receive a challenge. - */ -void chap_auth_with_peer(ppp_pcb *pcb, const char *our_name, int digest_code) { - const struct chap_digest_type *dp; - int i; - - if(NULL == our_name) - return; - - if (pcb->chap_client.flags & AUTH_STARTED) { - ppp_error("CHAP: authentication with peer already started!"); - return; - } - for (i = 0; (dp = chap_digests[i]) != NULL; ++i) - if (dp->code == digest_code) - break; - - if (dp == NULL) - ppp_fatal("CHAP digest 0x%x requested but not available", - digest_code); - - pcb->chap_client.digest = dp; - pcb->chap_client.name = our_name; - pcb->chap_client.flags |= AUTH_STARTED; -} - -#if PPP_SERVER -/* - * chap_timeout - It's time to send another challenge to the peer. - * This could be either a retransmission of a previous challenge, - * or a new challenge to start re-authentication. - */ -static void chap_timeout(void *arg) { - ppp_pcb *pcb = (ppp_pcb*)arg; - struct pbuf *p; - - pcb->chap_server.flags &= ~TIMEOUT_PENDING; - if ((pcb->chap_server.flags & CHALLENGE_VALID) == 0) { - pcb->chap_server.challenge_xmits = 0; - chap_generate_challenge(pcb); - pcb->chap_server.flags |= CHALLENGE_VALID; - } else if (pcb->chap_server.challenge_xmits >= pcb->settings.chap_max_transmits) { - pcb->chap_server.flags &= ~CHALLENGE_VALID; - pcb->chap_server.flags |= AUTH_DONE | AUTH_FAILED; - auth_peer_fail(pcb, PPP_CHAP); - return; - } - - p = pbuf_alloc(PBUF_RAW, (u16_t)(pcb->chap_server.challenge_pktlen), PPP_CTRL_PBUF_TYPE); - if(NULL == p) - return; - if(p->tot_len != p->len) { - pbuf_free(p); - return; - } - MEMCPY(p->payload, pcb->chap_server.challenge, pcb->chap_server.challenge_pktlen); - ppp_write(pcb, p); - ++pcb->chap_server.challenge_xmits; - pcb->chap_server.flags |= TIMEOUT_PENDING; - TIMEOUT(chap_timeout, arg, pcb->settings.chap_timeout_time); -} - -/* - * chap_generate_challenge - generate a challenge string and format - * the challenge packet in pcb->chap_server.challenge_pkt. - */ -static void chap_generate_challenge(ppp_pcb *pcb) { - int clen = 1, nlen, len; - unsigned char *p; - - p = pcb->chap_server.challenge; - MAKEHEADER(p, PPP_CHAP); - p += CHAP_HDRLEN; - pcb->chap_server.digest->generate_challenge(pcb, p); - clen = *p; - nlen = strlen(pcb->chap_server.name); - memcpy(p + 1 + clen, pcb->chap_server.name, nlen); - - len = CHAP_HDRLEN + 1 + clen + nlen; - pcb->chap_server.challenge_pktlen = PPP_HDRLEN + len; - - p = pcb->chap_server.challenge + PPP_HDRLEN; - p[0] = CHAP_CHALLENGE; - p[1] = ++pcb->chap_server.id; - p[2] = len >> 8; - p[3] = len; -} - -/* - * chap_handle_response - check the response to our challenge. - */ -static void chap_handle_response(ppp_pcb *pcb, int id, - unsigned char *pkt, int len) { - int response_len, ok, mlen; - const unsigned char *response; - unsigned char *outp; - struct pbuf *p; - const char *name = NULL; /* initialized to shut gcc up */ -#if 0 /* UNUSED */ - int (*verifier)(const char *, const char *, int, const struct chap_digest_type *, - const unsigned char *, const unsigned char *, char *, int); -#endif /* UNUSED */ - char rname[MAXNAMELEN+1]; - char message[256]; - - if ((pcb->chap_server.flags & LOWERUP) == 0) - return; - if (id != pcb->chap_server.challenge[PPP_HDRLEN+1] || len < 2) - return; - if (pcb->chap_server.flags & CHALLENGE_VALID) { - response = pkt; - GETCHAR(response_len, pkt); - len -= response_len + 1; /* length of name */ - name = (char *)pkt + response_len; - if (len < 0) - return; - - if (pcb->chap_server.flags & TIMEOUT_PENDING) { - pcb->chap_server.flags &= ~TIMEOUT_PENDING; - UNTIMEOUT(chap_timeout, pcb); - } -#if PPP_REMOTENAME - if (pcb->settings.explicit_remote) { - name = pcb->remote_name; - } else -#endif /* PPP_REMOTENAME */ - { - /* Null terminate and clean remote name. */ - ppp_slprintf(rname, sizeof(rname), "%.*v", len, name); - name = rname; - } - -#if 0 /* UNUSED */ - if (chap_verify_hook) - verifier = chap_verify_hook; - else - verifier = chap_verify_response; - ok = (*verifier)(name, pcb->chap_server.name, id, pcb->chap_server.digest, - pcb->chap_server.challenge + PPP_HDRLEN + CHAP_HDRLEN, - response, pcb->chap_server.message, sizeof(pcb->chap_server.message)); -#endif /* UNUSED */ - ok = chap_verify_response(pcb, name, pcb->chap_server.name, id, pcb->chap_server.digest, - pcb->chap_server.challenge + PPP_HDRLEN + CHAP_HDRLEN, - response, message, sizeof(message)); -#if 0 /* UNUSED */ - if (!ok || !auth_number()) { -#endif /* UNUSED */ - if (!ok) { - pcb->chap_server.flags |= AUTH_FAILED; - ppp_warn("Peer %q failed CHAP authentication", name); - } - } else if ((pcb->chap_server.flags & AUTH_DONE) == 0) - return; - - /* send the response */ - mlen = strlen(message); - len = CHAP_HDRLEN + mlen; - p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN +len), PPP_CTRL_PBUF_TYPE); - if(NULL == p) - return; - if(p->tot_len != p->len) { - pbuf_free(p); - return; - } - - outp = (unsigned char *)p->payload; - MAKEHEADER(outp, PPP_CHAP); - - outp[0] = (pcb->chap_server.flags & AUTH_FAILED)? CHAP_FAILURE: CHAP_SUCCESS; - outp[1] = id; - outp[2] = len >> 8; - outp[3] = len; - if (mlen > 0) - memcpy(outp + CHAP_HDRLEN, message, mlen); - ppp_write(pcb, p); - - if (pcb->chap_server.flags & CHALLENGE_VALID) { - pcb->chap_server.flags &= ~CHALLENGE_VALID; - if (!(pcb->chap_server.flags & AUTH_DONE) && !(pcb->chap_server.flags & AUTH_FAILED)) { - -#if 0 /* UNUSED */ - /* - * Auth is OK, so now we need to check session restrictions - * to ensure everything is OK, but only if we used a - * plugin, and only if we're configured to check. This - * allows us to do PAM checks on PPP servers that - * authenticate against ActiveDirectory, and use AD for - * account info (like when using Winbind integrated with - * PAM). - */ - if (session_mgmt && - session_check(name, NULL, devnam, NULL) == 0) { - pcb->chap_server.flags |= AUTH_FAILED; - ppp_warn("Peer %q failed CHAP Session verification", name); - } -#endif /* UNUSED */ - - } - if (pcb->chap_server.flags & AUTH_FAILED) { - auth_peer_fail(pcb, PPP_CHAP); - } else { - if ((pcb->chap_server.flags & AUTH_DONE) == 0) - auth_peer_success(pcb, PPP_CHAP, - pcb->chap_server.digest->code, - name, strlen(name)); - if (pcb->settings.chap_rechallenge_time) { - pcb->chap_server.flags |= TIMEOUT_PENDING; - TIMEOUT(chap_timeout, pcb, - pcb->settings.chap_rechallenge_time); - } - } - pcb->chap_server.flags |= AUTH_DONE; - } -} - -/* - * chap_verify_response - check whether the peer's response matches - * what we think it should be. Returns 1 if it does (authentication - * succeeded), or 0 if it doesn't. - */ -static int chap_verify_response(ppp_pcb *pcb, const char *name, const char *ourname, int id, - const struct chap_digest_type *digest, - const unsigned char *challenge, const unsigned char *response, - char *message, int message_space) { - int ok; - unsigned char secret[MAXSECRETLEN]; - int secret_len; - - /* Get the secret that the peer is supposed to know */ - if (!get_secret(pcb, name, ourname, (char *)secret, &secret_len, 1)) { - ppp_error("No CHAP secret found for authenticating %q", name); - return 0; - } - ok = digest->verify_response(pcb, id, name, secret, secret_len, challenge, - response, message, message_space); - memset(secret, 0, sizeof(secret)); - - return ok; -} -#endif /* PPP_SERVER */ - -/* - * chap_respond - Generate and send a response to a challenge. - */ -static void chap_respond(ppp_pcb *pcb, int id, - unsigned char *pkt, int len) { - int clen, nlen; - int secret_len; - struct pbuf *p; - u_char *outp; - char rname[MAXNAMELEN+1]; - char secret[MAXSECRETLEN+1]; - - p = pbuf_alloc(PBUF_RAW, (u16_t)(RESP_MAX_PKTLEN), PPP_CTRL_PBUF_TYPE); - if(NULL == p) - return; - if(p->tot_len != p->len) { - pbuf_free(p); - return; - } - - if ((pcb->chap_client.flags & (LOWERUP | AUTH_STARTED)) != (LOWERUP | AUTH_STARTED)) - return; /* not ready */ - if (len < 2 || len < pkt[0] + 1) - return; /* too short */ - clen = pkt[0]; - nlen = len - (clen + 1); - - /* Null terminate and clean remote name. */ - ppp_slprintf(rname, sizeof(rname), "%.*v", nlen, pkt + clen + 1); - -#if PPP_REMOTENAME - /* Microsoft doesn't send their name back in the PPP packet */ - if (pcb->settings.explicit_remote || (pcb->settings.remote_name[0] != 0 && rname[0] == 0)) - strlcpy(rname, pcb->settings.remote_name, sizeof(rname)); -#endif /* PPP_REMOTENAME */ - - /* get secret for authenticating ourselves with the specified host */ - if (!get_secret(pcb, pcb->chap_client.name, rname, secret, &secret_len, 0)) { - secret_len = 0; /* assume null secret if can't find one */ - ppp_warn("No CHAP secret found for authenticating us to %q", rname); - } - - outp = (u_char*)p->payload; - MAKEHEADER(outp, PPP_CHAP); - outp += CHAP_HDRLEN; - - pcb->chap_client.digest->make_response(pcb, outp, id, pcb->chap_client.name, pkt, - secret, secret_len, pcb->chap_client.priv); - memset(secret, 0, secret_len); - - clen = *outp; - nlen = strlen(pcb->chap_client.name); - memcpy(outp + clen + 1, pcb->chap_client.name, nlen); - - outp = (u_char*)p->payload + PPP_HDRLEN; - len = CHAP_HDRLEN + clen + 1 + nlen; - outp[0] = CHAP_RESPONSE; - outp[1] = id; - outp[2] = len >> 8; - outp[3] = len; - - pbuf_realloc(p, PPP_HDRLEN + len); - ppp_write(pcb, p); -} - -static void chap_handle_status(ppp_pcb *pcb, int code, int id, - unsigned char *pkt, int len) { - const char *msg = NULL; - LWIP_UNUSED_ARG(id); - - if ((pcb->chap_client.flags & (AUTH_DONE|AUTH_STARTED|LOWERUP)) - != (AUTH_STARTED|LOWERUP)) - return; - pcb->chap_client.flags |= AUTH_DONE; - - if (code == CHAP_SUCCESS) { - /* used for MS-CHAP v2 mutual auth, yuck */ - if (pcb->chap_client.digest->check_success != NULL) { - if (!(*pcb->chap_client.digest->check_success)(pcb, pkt, len, pcb->chap_client.priv)) - code = CHAP_FAILURE; - } else - msg = "CHAP authentication succeeded"; - } else { - if (pcb->chap_client.digest->handle_failure != NULL) - (*pcb->chap_client.digest->handle_failure)(pcb, pkt, len); - else - msg = "CHAP authentication failed"; - } - if (msg) { - if (len > 0) - ppp_info("%s: %.*v", msg, len, pkt); - else - ppp_info("%s", msg); - } - if (code == CHAP_SUCCESS) - auth_withpeer_success(pcb, PPP_CHAP, pcb->chap_client.digest->code); - else { - pcb->chap_client.flags |= AUTH_FAILED; - ppp_error("CHAP authentication failed"); - auth_withpeer_fail(pcb, PPP_CHAP); - } -} - -static void chap_input(ppp_pcb *pcb, unsigned char *pkt, int pktlen) { - unsigned char code, id; - int len; - - if (pktlen < CHAP_HDRLEN) - return; - GETCHAR(code, pkt); - GETCHAR(id, pkt); - GETSHORT(len, pkt); - if (len < CHAP_HDRLEN || len > pktlen) - return; - len -= CHAP_HDRLEN; - - switch (code) { - case CHAP_CHALLENGE: - chap_respond(pcb, id, pkt, len); - break; -#if PPP_SERVER - case CHAP_RESPONSE: - chap_handle_response(pcb, id, pkt, len); - break; -#endif /* PPP_SERVER */ - case CHAP_FAILURE: - case CHAP_SUCCESS: - chap_handle_status(pcb, code, id, pkt, len); - break; - default: - break; - } -} - -static void chap_protrej(ppp_pcb *pcb) { - -#if PPP_SERVER - if (pcb->chap_server.flags & TIMEOUT_PENDING) { - pcb->chap_server.flags &= ~TIMEOUT_PENDING; - UNTIMEOUT(chap_timeout, pcb); - } - if (pcb->chap_server.flags & AUTH_STARTED) { - pcb->chap_server.flags = 0; - auth_peer_fail(pcb, PPP_CHAP); - } -#endif /* PPP_SERVER */ - if ((pcb->chap_client.flags & (AUTH_STARTED|AUTH_DONE)) == AUTH_STARTED) { - pcb->chap_client.flags &= ~AUTH_STARTED; - ppp_error("CHAP authentication failed due to protocol-reject"); - auth_withpeer_fail(pcb, PPP_CHAP); - } -} - -#if PRINTPKT_SUPPORT -/* - * chap_print_pkt - print the contents of a CHAP packet. - */ -static const char* const chap_code_names[] = { - "Challenge", "Response", "Success", "Failure" -}; - -static int chap_print_pkt(const unsigned char *p, int plen, - void (*printer) (void *, const char *, ...), void *arg) { - int code, id, len; - int clen, nlen; - unsigned char x; - - if (plen < CHAP_HDRLEN) - return 0; - GETCHAR(code, p); - GETCHAR(id, p); - GETSHORT(len, p); - if (len < CHAP_HDRLEN || len > plen) - return 0; - - if (code >= 1 && code <= (int)LWIP_ARRAYSIZE(chap_code_names)) - printer(arg, " %s", chap_code_names[code-1]); - else - printer(arg, " code=0x%x", code); - printer(arg, " id=0x%x", id); - len -= CHAP_HDRLEN; - switch (code) { - case CHAP_CHALLENGE: - case CHAP_RESPONSE: - if (len < 1) - break; - clen = p[0]; - if (len < clen + 1) - break; - ++p; - nlen = len - clen - 1; - printer(arg, " <"); - for (; clen > 0; --clen) { - GETCHAR(x, p); - printer(arg, "%.2x", x); - } - printer(arg, ">, name = "); - ppp_print_string(p, nlen, printer, arg); - break; - case CHAP_FAILURE: - case CHAP_SUCCESS: - printer(arg, " "); - ppp_print_string(p, len, printer, arg); - break; - default: - for (clen = len; clen > 0; --clen) { - GETCHAR(x, p); - printer(arg, " %.2x", x); - } - /* no break */ - } - - return len + CHAP_HDRLEN; -} -#endif /* PRINTPKT_SUPPORT */ - -const struct protent chap_protent = { - PPP_CHAP, - chap_init, - chap_input, - chap_protrej, - chap_lowerup, - chap_lowerdown, - NULL, /* open */ - NULL, /* close */ -#if PRINTPKT_SUPPORT - chap_print_pkt, -#endif /* PRINTPKT_SUPPORT */ -#if PPP_DATAINPUT - NULL, /* datainput */ -#endif /* PPP_DATAINPUT */ -#if PRINTPKT_SUPPORT - "CHAP", /* name */ - NULL, /* data_name */ -#endif /* PRINTPKT_SUPPORT */ -#if PPP_OPTIONS - chap_option_list, - NULL, /* check_options */ -#endif /* PPP_OPTIONS */ -#if DEMAND_SUPPORT - NULL, - NULL -#endif /* DEMAND_SUPPORT */ -}; - -#endif /* PPP_SUPPORT && CHAP_SUPPORT */ diff --git a/third_party/lwip/repo/lwip/src/netif/ppp/chap_ms.c b/third_party/lwip/repo/lwip/src/netif/ppp/chap_ms.c deleted file mode 100644 index 5a989c9b7eb4fd..00000000000000 --- a/third_party/lwip/repo/lwip/src/netif/ppp/chap_ms.c +++ /dev/null @@ -1,962 +0,0 @@ -/* - * chap_ms.c - Microsoft MS-CHAP compatible implementation. - * - * Copyright (c) 1995 Eric Rosenquist. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name(s) of the authors of this software must not be used to - * endorse or promote products derived from this software without - * prior written permission. - * - * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -/* - * Modifications by Lauri Pesonen / lpesonen@clinet.fi, april 1997 - * - * Implemented LANManager type password response to MS-CHAP challenges. - * Now pppd provides both NT style and LANMan style blocks, and the - * prefered is set by option "ms-lanman". Default is to use NT. - * The hash text (StdText) was taken from Win95 RASAPI32.DLL. - * - * You should also use DOMAIN\\USERNAME as described in README.MSCHAP80 - */ - -/* - * Modifications by Frank Cusack, frank@google.com, March 2002. - * - * Implemented MS-CHAPv2 functionality, heavily based on sample - * implementation in RFC 2759. Implemented MPPE functionality, - * heavily based on sample implementation in RFC 3079. - * - * Copyright (c) 2002 Google, Inc. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name(s) of the authors of this software must not be used to - * endorse or promote products derived from this software without - * prior written permission. - * - * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT && MSCHAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#if 0 /* UNUSED */ -#include -#include -#include -#include -#include -#include -#include -#endif /* UNUSED */ - -#include "netif/ppp/ppp_impl.h" - -#include "netif/ppp/chap-new.h" -#include "netif/ppp/chap_ms.h" -#include "netif/ppp/pppcrypt.h" -#include "netif/ppp/magic.h" -#if MPPE_SUPPORT -#include "netif/ppp/mppe.h" /* For mppe_sha1_pad*, mppe_set_key() */ -#endif /* MPPE_SUPPORT */ - -#define SHA1_SIGNATURE_SIZE 20 -#define MD4_SIGNATURE_SIZE 16 /* 16 bytes in a MD4 message digest */ -#define MAX_NT_PASSWORD 256 /* Max (Unicode) chars in an NT pass */ - -#define MS_CHAP_RESPONSE_LEN 49 /* Response length for MS-CHAP */ -#define MS_CHAP2_RESPONSE_LEN 49 /* Response length for MS-CHAPv2 */ -#define MS_AUTH_RESPONSE_LENGTH 40 /* MS-CHAPv2 authenticator response, */ - /* as ASCII */ - -/* Error codes for MS-CHAP failure messages. */ -#define MS_CHAP_ERROR_RESTRICTED_LOGON_HOURS 646 -#define MS_CHAP_ERROR_ACCT_DISABLED 647 -#define MS_CHAP_ERROR_PASSWD_EXPIRED 648 -#define MS_CHAP_ERROR_NO_DIALIN_PERMISSION 649 -#define MS_CHAP_ERROR_AUTHENTICATION_FAILURE 691 -#define MS_CHAP_ERROR_CHANGING_PASSWORD 709 - -/* - * Offsets within the response field for MS-CHAP - */ -#define MS_CHAP_LANMANRESP 0 -#define MS_CHAP_LANMANRESP_LEN 24 -#define MS_CHAP_NTRESP 24 -#define MS_CHAP_NTRESP_LEN 24 -#define MS_CHAP_USENT 48 - -/* - * Offsets within the response field for MS-CHAP2 - */ -#define MS_CHAP2_PEER_CHALLENGE 0 -#define MS_CHAP2_PEER_CHAL_LEN 16 -#define MS_CHAP2_RESERVED_LEN 8 -#define MS_CHAP2_NTRESP 24 -#define MS_CHAP2_NTRESP_LEN 24 -#define MS_CHAP2_FLAGS 48 - -#if MPPE_SUPPORT -#if 0 /* UNUSED */ -/* These values are the RADIUS attribute values--see RFC 2548. */ -#define MPPE_ENC_POL_ENC_ALLOWED 1 -#define MPPE_ENC_POL_ENC_REQUIRED 2 -#define MPPE_ENC_TYPES_RC4_40 2 -#define MPPE_ENC_TYPES_RC4_128 4 - -/* used by plugins (using above values) */ -extern void set_mppe_enc_types(int, int); -#endif /* UNUSED */ -#endif /* MPPE_SUPPORT */ - -/* Are we the authenticator or authenticatee? For MS-CHAPv2 key derivation. */ -#define MS_CHAP2_AUTHENTICATEE 0 -#define MS_CHAP2_AUTHENTICATOR 1 - -static void ascii2unicode (const char[], int, u_char[]); -static void NTPasswordHash (u_char *, int, u_char[MD4_SIGNATURE_SIZE]); -static void ChallengeResponse (const u_char *, const u_char *, u_char[24]); -static void ChallengeHash (const u_char[16], const u_char *, const char *, u_char[8]); -static void ChapMS_NT (const u_char *, const char *, int, u_char[24]); -static void ChapMS2_NT (const u_char *, const u_char[16], const char *, const char *, int, - u_char[24]); -static void GenerateAuthenticatorResponsePlain - (const char*, int, u_char[24], const u_char[16], const u_char *, - const char *, u_char[41]); -#ifdef MSLANMAN -static void ChapMS_LANMan (u_char *, char *, int, u_char *); -#endif - -static void GenerateAuthenticatorResponse(const u_char PasswordHashHash[MD4_SIGNATURE_SIZE], - u_char NTResponse[24], const u_char PeerChallenge[16], - const u_char *rchallenge, const char *username, - u_char authResponse[MS_AUTH_RESPONSE_LENGTH+1]); - -#if MPPE_SUPPORT -static void Set_Start_Key (ppp_pcb *pcb, const u_char *, const char *, int); -static void SetMasterKeys (ppp_pcb *pcb, const char *, int, u_char[24], int); -#endif /* MPPE_SUPPORT */ - -static void ChapMS (ppp_pcb *pcb, const u_char *, const char *, int, u_char *); -static void ChapMS2 (ppp_pcb *pcb, const u_char *, const u_char *, const char *, const char *, int, - u_char *, u_char[MS_AUTH_RESPONSE_LENGTH+1], int); - -#ifdef MSLANMAN -bool ms_lanman = 0; /* Use LanMan password instead of NT */ - /* Has meaning only with MS-CHAP challenges */ -#endif - -#if MPPE_SUPPORT -#ifdef DEBUGMPPEKEY -/* For MPPE debug */ -/* Use "[]|}{?/><,`!2&&(" (sans quotes) for RFC 3079 MS-CHAPv2 test value */ -static char *mschap_challenge = NULL; -/* Use "!@\#$%^&*()_+:3|~" (sans quotes, backslash is to escape #) for ... */ -static char *mschap2_peer_challenge = NULL; -#endif - -#include "netif/ppp/fsm.h" /* Need to poke MPPE options */ -#include "netif/ppp/ccp.h" -#endif /* MPPE_SUPPORT */ - -#if PPP_OPTIONS -/* - * Command-line options. - */ -static option_t chapms_option_list[] = { -#ifdef MSLANMAN - { "ms-lanman", o_bool, &ms_lanman, - "Use LanMan passwd when using MS-CHAP", 1 }, -#endif -#ifdef DEBUGMPPEKEY - { "mschap-challenge", o_string, &mschap_challenge, - "specify CHAP challenge" }, - { "mschap2-peer-challenge", o_string, &mschap2_peer_challenge, - "specify CHAP peer challenge" }, -#endif - { NULL } -}; -#endif /* PPP_OPTIONS */ - -#if PPP_SERVER -/* - * chapms_generate_challenge - generate a challenge for MS-CHAP. - * For MS-CHAP the challenge length is fixed at 8 bytes. - * The length goes in challenge[0] and the actual challenge starts - * at challenge[1]. - */ -static void chapms_generate_challenge(ppp_pcb *pcb, unsigned char *challenge) { - LWIP_UNUSED_ARG(pcb); - - *challenge++ = 8; -#ifdef DEBUGMPPEKEY - if (mschap_challenge && strlen(mschap_challenge) == 8) - memcpy(challenge, mschap_challenge, 8); - else -#endif - magic_random_bytes(challenge, 8); -} - -static void chapms2_generate_challenge(ppp_pcb *pcb, unsigned char *challenge) { - LWIP_UNUSED_ARG(pcb); - - *challenge++ = 16; -#ifdef DEBUGMPPEKEY - if (mschap_challenge && strlen(mschap_challenge) == 16) - memcpy(challenge, mschap_challenge, 16); - else -#endif - magic_random_bytes(challenge, 16); -} - -static int chapms_verify_response(ppp_pcb *pcb, int id, const char *name, - const unsigned char *secret, int secret_len, - const unsigned char *challenge, const unsigned char *response, - char *message, int message_space) { - unsigned char md[MS_CHAP_RESPONSE_LEN]; - int diff; - int challenge_len, response_len; - LWIP_UNUSED_ARG(id); - LWIP_UNUSED_ARG(name); - - challenge_len = *challenge++; /* skip length, is 8 */ - response_len = *response++; - if (response_len != MS_CHAP_RESPONSE_LEN) - goto bad; - -#ifndef MSLANMAN - if (!response[MS_CHAP_USENT]) { - /* Should really propagate this into the error packet. */ - ppp_notice("Peer request for LANMAN auth not supported"); - goto bad; - } -#endif - - /* Generate the expected response. */ - ChapMS(pcb, (const u_char *)challenge, (const char *)secret, secret_len, md); - -#ifdef MSLANMAN - /* Determine which part of response to verify against */ - if (!response[MS_CHAP_USENT]) - diff = memcmp(&response[MS_CHAP_LANMANRESP], - &md[MS_CHAP_LANMANRESP], MS_CHAP_LANMANRESP_LEN); - else -#endif - diff = memcmp(&response[MS_CHAP_NTRESP], &md[MS_CHAP_NTRESP], - MS_CHAP_NTRESP_LEN); - - if (diff == 0) { - ppp_slprintf(message, message_space, "Access granted"); - return 1; - } - - bad: - /* See comments below for MS-CHAP V2 */ - ppp_slprintf(message, message_space, "E=691 R=1 C=%0.*B V=0", - challenge_len, challenge); - return 0; -} - -static int chapms2_verify_response(ppp_pcb *pcb, int id, const char *name, - const unsigned char *secret, int secret_len, - const unsigned char *challenge, const unsigned char *response, - char *message, int message_space) { - unsigned char md[MS_CHAP2_RESPONSE_LEN]; - char saresponse[MS_AUTH_RESPONSE_LENGTH+1]; - int challenge_len, response_len; - LWIP_UNUSED_ARG(id); - - challenge_len = *challenge++; /* skip length, is 16 */ - response_len = *response++; - if (response_len != MS_CHAP2_RESPONSE_LEN) - goto bad; /* not even the right length */ - - /* Generate the expected response and our mutual auth. */ - ChapMS2(pcb, (const u_char*)challenge, (const u_char*)&response[MS_CHAP2_PEER_CHALLENGE], name, - (const char *)secret, secret_len, md, - (unsigned char *)saresponse, MS_CHAP2_AUTHENTICATOR); - - /* compare MDs and send the appropriate status */ - /* - * Per RFC 2759, success message must be formatted as - * "S= M=" - * where - * is the Authenticator Response (mutual auth) - * is a text message - * - * However, some versions of Windows (win98 tested) do not know - * about the M= part (required per RFC 2759) and flag - * it as an error (reported incorrectly as an encryption error - * to the user). Since the RFC requires it, and it can be - * useful information, we supply it if the peer is a conforming - * system. Luckily (?), win98 sets the Flags field to 0x04 - * (contrary to RFC requirements) so we can use that to - * distinguish between conforming and non-conforming systems. - * - * Special thanks to Alex Swiridov for - * help debugging this. - */ - if (memcmp(&md[MS_CHAP2_NTRESP], &response[MS_CHAP2_NTRESP], - MS_CHAP2_NTRESP_LEN) == 0) { - if (response[MS_CHAP2_FLAGS]) - ppp_slprintf(message, message_space, "S=%s", saresponse); - else - ppp_slprintf(message, message_space, "S=%s M=%s", - saresponse, "Access granted"); - return 1; - } - - bad: - /* - * Failure message must be formatted as - * "E=e R=r C=c V=v M=m" - * where - * e = error code (we use 691, ERROR_AUTHENTICATION_FAILURE) - * r = retry (we use 1, ok to retry) - * c = challenge to use for next response, we reuse previous - * v = Change Password version supported, we use 0 - * m = text message - * - * The M=m part is only for MS-CHAPv2. Neither win2k nor - * win98 (others untested) display the message to the user anyway. - * They also both ignore the E=e code. - * - * Note that it's safe to reuse the same challenge as we don't - * actually accept another response based on the error message - * (and no clients try to resend a response anyway). - * - * Basically, this whole bit is useless code, even the small - * implementation here is only because of overspecification. - */ - ppp_slprintf(message, message_space, "E=691 R=1 C=%0.*B V=0 M=%s", - challenge_len, challenge, "Access denied"); - return 0; -} -#endif /* PPP_SERVER */ - -static void chapms_make_response(ppp_pcb *pcb, unsigned char *response, int id, const char *our_name, - const unsigned char *challenge, const char *secret, int secret_len, - unsigned char *private_) { - LWIP_UNUSED_ARG(id); - LWIP_UNUSED_ARG(our_name); - LWIP_UNUSED_ARG(private_); - challenge++; /* skip length, should be 8 */ - *response++ = MS_CHAP_RESPONSE_LEN; - ChapMS(pcb, challenge, secret, secret_len, response); -} - -static void chapms2_make_response(ppp_pcb *pcb, unsigned char *response, int id, const char *our_name, - const unsigned char *challenge, const char *secret, int secret_len, - unsigned char *private_) { - LWIP_UNUSED_ARG(id); - challenge++; /* skip length, should be 16 */ - *response++ = MS_CHAP2_RESPONSE_LEN; - ChapMS2(pcb, challenge, -#ifdef DEBUGMPPEKEY - mschap2_peer_challenge, -#else - NULL, -#endif - our_name, secret, secret_len, response, private_, - MS_CHAP2_AUTHENTICATEE); -} - -static int chapms2_check_success(ppp_pcb *pcb, unsigned char *msg, int len, unsigned char *private_) { - LWIP_UNUSED_ARG(pcb); - - if ((len < MS_AUTH_RESPONSE_LENGTH + 2) || - strncmp((char *)msg, "S=", 2) != 0) { - /* Packet does not start with "S=" */ - ppp_error("MS-CHAPv2 Success packet is badly formed."); - return 0; - } - msg += 2; - len -= 2; - if (len < MS_AUTH_RESPONSE_LENGTH - || memcmp(msg, private_, MS_AUTH_RESPONSE_LENGTH)) { - /* Authenticator Response did not match expected. */ - ppp_error("MS-CHAPv2 mutual authentication failed."); - return 0; - } - /* Authenticator Response matches. */ - msg += MS_AUTH_RESPONSE_LENGTH; /* Eat it */ - len -= MS_AUTH_RESPONSE_LENGTH; - if ((len >= 3) && !strncmp((char *)msg, " M=", 3)) { - msg += 3; /* Eat the delimiter */ - } else if (len) { - /* Packet has extra text which does not begin " M=" */ - ppp_error("MS-CHAPv2 Success packet is badly formed."); - return 0; - } - return 1; -} - -static void chapms_handle_failure(ppp_pcb *pcb, unsigned char *inp, int len) { - int err; - const char *p; - char msg[64]; - LWIP_UNUSED_ARG(pcb); - - /* We want a null-terminated string for strxxx(). */ - len = LWIP_MIN(len, 63); - MEMCPY(msg, inp, len); - msg[len] = 0; - p = msg; - - /* - * Deal with MS-CHAP formatted failure messages; just print the - * M= part (if any). For MS-CHAP we're not really supposed - * to use M=, but it shouldn't hurt. See - * chapms[2]_verify_response. - */ - if (!strncmp(p, "E=", 2)) - err = strtol(p+2, NULL, 10); /* Remember the error code. */ - else - goto print_msg; /* Message is badly formatted. */ - - if (len && ((p = strstr(p, " M=")) != NULL)) { - /* M= field found. */ - p += 3; - } else { - /* No M=; use the error code. */ - switch (err) { - case MS_CHAP_ERROR_RESTRICTED_LOGON_HOURS: - p = "E=646 Restricted logon hours"; - break; - - case MS_CHAP_ERROR_ACCT_DISABLED: - p = "E=647 Account disabled"; - break; - - case MS_CHAP_ERROR_PASSWD_EXPIRED: - p = "E=648 Password expired"; - break; - - case MS_CHAP_ERROR_NO_DIALIN_PERMISSION: - p = "E=649 No dialin permission"; - break; - - case MS_CHAP_ERROR_AUTHENTICATION_FAILURE: - p = "E=691 Authentication failure"; - break; - - case MS_CHAP_ERROR_CHANGING_PASSWORD: - /* Should never see this, we don't support Change Password. */ - p = "E=709 Error changing password"; - break; - - default: - ppp_error("Unknown MS-CHAP authentication failure: %.*v", - len, inp); - return; - } - } -print_msg: - if (p != NULL) - ppp_error("MS-CHAP authentication failed: %v", p); -} - -static void ChallengeResponse(const u_char *challenge, - const u_char PasswordHash[MD4_SIGNATURE_SIZE], - u_char response[24]) { - u_char ZPasswordHash[21]; - lwip_des_context des; - u_char des_key[8]; - - BZERO(ZPasswordHash, sizeof(ZPasswordHash)); - MEMCPY(ZPasswordHash, PasswordHash, MD4_SIGNATURE_SIZE); - -#if 0 - dbglog("ChallengeResponse - ZPasswordHash %.*B", - sizeof(ZPasswordHash), ZPasswordHash); -#endif - - pppcrypt_56_to_64_bit_key(ZPasswordHash + 0, des_key); - lwip_des_init(&des); - lwip_des_setkey_enc(&des, des_key); - lwip_des_crypt_ecb(&des, challenge, response +0); - lwip_des_free(&des); - - pppcrypt_56_to_64_bit_key(ZPasswordHash + 7, des_key); - lwip_des_init(&des); - lwip_des_setkey_enc(&des, des_key); - lwip_des_crypt_ecb(&des, challenge, response +8); - lwip_des_free(&des); - - pppcrypt_56_to_64_bit_key(ZPasswordHash + 14, des_key); - lwip_des_init(&des); - lwip_des_setkey_enc(&des, des_key); - lwip_des_crypt_ecb(&des, challenge, response +16); - lwip_des_free(&des); - -#if 0 - dbglog("ChallengeResponse - response %.24B", response); -#endif -} - -static void ChallengeHash(const u_char PeerChallenge[16], const u_char *rchallenge, - const char *username, u_char Challenge[8]) { - lwip_sha1_context sha1Context; - u_char sha1Hash[SHA1_SIGNATURE_SIZE]; - const char *user; - - /* remove domain from "domain\username" */ - if ((user = strrchr(username, '\\')) != NULL) - ++user; - else - user = username; - - lwip_sha1_init(&sha1Context); - lwip_sha1_starts(&sha1Context); - lwip_sha1_update(&sha1Context, PeerChallenge, 16); - lwip_sha1_update(&sha1Context, rchallenge, 16); - lwip_sha1_update(&sha1Context, (const unsigned char*)user, strlen(user)); - lwip_sha1_finish(&sha1Context, sha1Hash); - lwip_sha1_free(&sha1Context); - - MEMCPY(Challenge, sha1Hash, 8); -} - -/* - * Convert the ASCII version of the password to Unicode. - * This implicitly supports 8-bit ISO8859/1 characters. - * This gives us the little-endian representation, which - * is assumed by all M$ CHAP RFCs. (Unicode byte ordering - * is machine-dependent.) - */ -static void ascii2unicode(const char ascii[], int ascii_len, u_char unicode[]) { - int i; - - BZERO(unicode, ascii_len * 2); - for (i = 0; i < ascii_len; i++) - unicode[i * 2] = (u_char) ascii[i]; -} - -static void NTPasswordHash(u_char *secret, int secret_len, u_char hash[MD4_SIGNATURE_SIZE]) { - lwip_md4_context md4Context; - - lwip_md4_init(&md4Context); - lwip_md4_starts(&md4Context); - lwip_md4_update(&md4Context, secret, secret_len); - lwip_md4_finish(&md4Context, hash); - lwip_md4_free(&md4Context); -} - -static void ChapMS_NT(const u_char *rchallenge, const char *secret, int secret_len, - u_char NTResponse[24]) { - u_char unicodePassword[MAX_NT_PASSWORD * 2]; - u_char PasswordHash[MD4_SIGNATURE_SIZE]; - - /* Hash the Unicode version of the secret (== password). */ - ascii2unicode(secret, secret_len, unicodePassword); - NTPasswordHash(unicodePassword, secret_len * 2, PasswordHash); - - ChallengeResponse(rchallenge, PasswordHash, NTResponse); -} - -static void ChapMS2_NT(const u_char *rchallenge, const u_char PeerChallenge[16], const char *username, - const char *secret, int secret_len, u_char NTResponse[24]) { - u_char unicodePassword[MAX_NT_PASSWORD * 2]; - u_char PasswordHash[MD4_SIGNATURE_SIZE]; - u_char Challenge[8]; - - ChallengeHash(PeerChallenge, rchallenge, username, Challenge); - - /* Hash the Unicode version of the secret (== password). */ - ascii2unicode(secret, secret_len, unicodePassword); - NTPasswordHash(unicodePassword, secret_len * 2, PasswordHash); - - ChallengeResponse(Challenge, PasswordHash, NTResponse); -} - -#ifdef MSLANMAN -static u_char *StdText = (u_char *)"KGS!@#$%"; /* key from rasapi32.dll */ - -static void ChapMS_LANMan(u_char *rchallenge, char *secret, int secret_len, - unsigned char *response) { - int i; - u_char UcasePassword[MAX_NT_PASSWORD]; /* max is actually 14 */ - u_char PasswordHash[MD4_SIGNATURE_SIZE]; - lwip_des_context des; - u_char des_key[8]; - - /* LANMan password is case insensitive */ - BZERO(UcasePassword, sizeof(UcasePassword)); - for (i = 0; i < secret_len; i++) - UcasePassword[i] = (u_char)toupper(secret[i]); - - pppcrypt_56_to_64_bit_key(UcasePassword +0, des_key); - lwip_des_init(&des); - lwip_des_setkey_enc(&des, des_key); - lwip_des_crypt_ecb(&des, StdText, PasswordHash +0); - lwip_des_free(&des); - - pppcrypt_56_to_64_bit_key(UcasePassword +7, des_key); - lwip_des_init(&des); - lwip_des_setkey_enc(&des, des_key); - lwip_des_crypt_ecb(&des, StdText, PasswordHash +8); - lwip_des_free(&des); - - ChallengeResponse(rchallenge, PasswordHash, &response[MS_CHAP_LANMANRESP]); -} -#endif - - -static void GenerateAuthenticatorResponse(const u_char PasswordHashHash[MD4_SIGNATURE_SIZE], - u_char NTResponse[24], const u_char PeerChallenge[16], - const u_char *rchallenge, const char *username, - u_char authResponse[MS_AUTH_RESPONSE_LENGTH+1]) { - /* - * "Magic" constants used in response generation, from RFC 2759. - */ - static const u_char Magic1[39] = /* "Magic server to client signing constant" */ - { 0x4D, 0x61, 0x67, 0x69, 0x63, 0x20, 0x73, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x20, 0x74, 0x6F, 0x20, 0x63, 0x6C, 0x69, 0x65, - 0x6E, 0x74, 0x20, 0x73, 0x69, 0x67, 0x6E, 0x69, 0x6E, 0x67, - 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x74 }; - static const u_char Magic2[41] = /* "Pad to make it do more than one iteration" */ - { 0x50, 0x61, 0x64, 0x20, 0x74, 0x6F, 0x20, 0x6D, 0x61, 0x6B, - 0x65, 0x20, 0x69, 0x74, 0x20, 0x64, 0x6F, 0x20, 0x6D, 0x6F, - 0x72, 0x65, 0x20, 0x74, 0x68, 0x61, 0x6E, 0x20, 0x6F, 0x6E, - 0x65, 0x20, 0x69, 0x74, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6F, - 0x6E }; - - int i; - lwip_sha1_context sha1Context; - u_char Digest[SHA1_SIGNATURE_SIZE]; - u_char Challenge[8]; - - lwip_sha1_init(&sha1Context); - lwip_sha1_starts(&sha1Context); - lwip_sha1_update(&sha1Context, PasswordHashHash, MD4_SIGNATURE_SIZE); - lwip_sha1_update(&sha1Context, NTResponse, 24); - lwip_sha1_update(&sha1Context, Magic1, sizeof(Magic1)); - lwip_sha1_finish(&sha1Context, Digest); - lwip_sha1_free(&sha1Context); - - ChallengeHash(PeerChallenge, rchallenge, username, Challenge); - - lwip_sha1_init(&sha1Context); - lwip_sha1_starts(&sha1Context); - lwip_sha1_update(&sha1Context, Digest, sizeof(Digest)); - lwip_sha1_update(&sha1Context, Challenge, sizeof(Challenge)); - lwip_sha1_update(&sha1Context, Magic2, sizeof(Magic2)); - lwip_sha1_finish(&sha1Context, Digest); - lwip_sha1_free(&sha1Context); - - /* Convert to ASCII hex string. */ - for (i = 0; i < LWIP_MAX((MS_AUTH_RESPONSE_LENGTH / 2), (int)sizeof(Digest)); i++) - sprintf((char *)&authResponse[i * 2], "%02X", Digest[i]); -} - - -static void GenerateAuthenticatorResponsePlain( - const char *secret, int secret_len, - u_char NTResponse[24], const u_char PeerChallenge[16], - const u_char *rchallenge, const char *username, - u_char authResponse[MS_AUTH_RESPONSE_LENGTH+1]) { - u_char unicodePassword[MAX_NT_PASSWORD * 2]; - u_char PasswordHash[MD4_SIGNATURE_SIZE]; - u_char PasswordHashHash[MD4_SIGNATURE_SIZE]; - - /* Hash (x2) the Unicode version of the secret (== password). */ - ascii2unicode(secret, secret_len, unicodePassword); - NTPasswordHash(unicodePassword, secret_len * 2, PasswordHash); - NTPasswordHash(PasswordHash, sizeof(PasswordHash), - PasswordHashHash); - - GenerateAuthenticatorResponse(PasswordHashHash, NTResponse, PeerChallenge, - rchallenge, username, authResponse); -} - - -#if MPPE_SUPPORT -/* - * Set mppe_xxxx_key from MS-CHAP credentials. (see RFC 3079) - */ -static void Set_Start_Key(ppp_pcb *pcb, const u_char *rchallenge, const char *secret, int secret_len) { - u_char unicodePassword[MAX_NT_PASSWORD * 2]; - u_char PasswordHash[MD4_SIGNATURE_SIZE]; - u_char PasswordHashHash[MD4_SIGNATURE_SIZE]; - lwip_sha1_context sha1Context; - u_char Digest[SHA1_SIGNATURE_SIZE]; /* >= MPPE_MAX_KEY_LEN */ - - /* Hash (x2) the Unicode version of the secret (== password). */ - ascii2unicode(secret, secret_len, unicodePassword); - NTPasswordHash(unicodePassword, secret_len * 2, PasswordHash); - NTPasswordHash(PasswordHash, sizeof(PasswordHash), PasswordHashHash); - - lwip_sha1_init(&sha1Context); - lwip_sha1_starts(&sha1Context); - lwip_sha1_update(&sha1Context, PasswordHashHash, MD4_SIGNATURE_SIZE); - lwip_sha1_update(&sha1Context, PasswordHashHash, MD4_SIGNATURE_SIZE); - lwip_sha1_update(&sha1Context, rchallenge, 8); - lwip_sha1_finish(&sha1Context, Digest); - lwip_sha1_free(&sha1Context); - - /* Same key in both directions. */ - mppe_set_key(pcb, &pcb->mppe_comp, Digest); - mppe_set_key(pcb, &pcb->mppe_decomp, Digest); - - pcb->mppe_keys_set = 1; -} - -/* - * Set mppe_xxxx_key from MS-CHAPv2 credentials. (see RFC 3079) - */ -static void SetMasterKeys(ppp_pcb *pcb, const char *secret, int secret_len, u_char NTResponse[24], int IsServer) { - u_char unicodePassword[MAX_NT_PASSWORD * 2]; - u_char PasswordHash[MD4_SIGNATURE_SIZE]; - u_char PasswordHashHash[MD4_SIGNATURE_SIZE]; - lwip_sha1_context sha1Context; - u_char MasterKey[SHA1_SIGNATURE_SIZE]; /* >= MPPE_MAX_KEY_LEN */ - u_char Digest[SHA1_SIGNATURE_SIZE]; /* >= MPPE_MAX_KEY_LEN */ - const u_char *s; - - /* "This is the MPPE Master Key" */ - static const u_char Magic1[27] = - { 0x54, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, - 0x68, 0x65, 0x20, 0x4d, 0x50, 0x50, 0x45, 0x20, 0x4d, - 0x61, 0x73, 0x74, 0x65, 0x72, 0x20, 0x4b, 0x65, 0x79 }; - /* "On the client side, this is the send key; " - "on the server side, it is the receive key." */ - static const u_char Magic2[84] = - { 0x4f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x69, - 0x65, 0x6e, 0x74, 0x20, 0x73, 0x69, 0x64, 0x65, 0x2c, 0x20, - 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, - 0x65, 0x20, 0x73, 0x65, 0x6e, 0x64, 0x20, 0x6b, 0x65, 0x79, - 0x3b, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x73, 0x69, 0x64, 0x65, - 0x2c, 0x20, 0x69, 0x74, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, - 0x65, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x20, - 0x6b, 0x65, 0x79, 0x2e }; - /* "On the client side, this is the receive key; " - "on the server side, it is the send key." */ - static const u_char Magic3[84] = - { 0x4f, 0x6e, 0x20, 0x74, 0x68, 0x65, 0x20, 0x63, 0x6c, 0x69, - 0x65, 0x6e, 0x74, 0x20, 0x73, 0x69, 0x64, 0x65, 0x2c, 0x20, - 0x74, 0x68, 0x69, 0x73, 0x20, 0x69, 0x73, 0x20, 0x74, 0x68, - 0x65, 0x20, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x20, - 0x6b, 0x65, 0x79, 0x3b, 0x20, 0x6f, 0x6e, 0x20, 0x74, 0x68, - 0x65, 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x73, - 0x69, 0x64, 0x65, 0x2c, 0x20, 0x69, 0x74, 0x20, 0x69, 0x73, - 0x20, 0x74, 0x68, 0x65, 0x20, 0x73, 0x65, 0x6e, 0x64, 0x20, - 0x6b, 0x65, 0x79, 0x2e }; - - /* Hash (x2) the Unicode version of the secret (== password). */ - ascii2unicode(secret, secret_len, unicodePassword); - NTPasswordHash(unicodePassword, secret_len * 2, PasswordHash); - NTPasswordHash(PasswordHash, sizeof(PasswordHash), PasswordHashHash); - - lwip_sha1_init(&sha1Context); - lwip_sha1_starts(&sha1Context); - lwip_sha1_update(&sha1Context, PasswordHashHash, MD4_SIGNATURE_SIZE); - lwip_sha1_update(&sha1Context, NTResponse, 24); - lwip_sha1_update(&sha1Context, Magic1, sizeof(Magic1)); - lwip_sha1_finish(&sha1Context, MasterKey); - lwip_sha1_free(&sha1Context); - - /* - * generate send key - */ - if (IsServer) - s = Magic3; - else - s = Magic2; - lwip_sha1_init(&sha1Context); - lwip_sha1_starts(&sha1Context); - lwip_sha1_update(&sha1Context, MasterKey, 16); - lwip_sha1_update(&sha1Context, mppe_sha1_pad1, SHA1_PAD_SIZE); - lwip_sha1_update(&sha1Context, s, 84); - lwip_sha1_update(&sha1Context, mppe_sha1_pad2, SHA1_PAD_SIZE); - lwip_sha1_finish(&sha1Context, Digest); - lwip_sha1_free(&sha1Context); - - mppe_set_key(pcb, &pcb->mppe_comp, Digest); - - /* - * generate recv key - */ - if (IsServer) - s = Magic2; - else - s = Magic3; - lwip_sha1_init(&sha1Context); - lwip_sha1_starts(&sha1Context); - lwip_sha1_update(&sha1Context, MasterKey, 16); - lwip_sha1_update(&sha1Context, mppe_sha1_pad1, SHA1_PAD_SIZE); - lwip_sha1_update(&sha1Context, s, 84); - lwip_sha1_update(&sha1Context, mppe_sha1_pad2, SHA1_PAD_SIZE); - lwip_sha1_finish(&sha1Context, Digest); - lwip_sha1_free(&sha1Context); - - mppe_set_key(pcb, &pcb->mppe_decomp, Digest); - - pcb->mppe_keys_set = 1; -} - -#endif /* MPPE_SUPPORT */ - - -static void ChapMS(ppp_pcb *pcb, const u_char *rchallenge, const char *secret, int secret_len, - unsigned char *response) { -#if !MPPE_SUPPORT - LWIP_UNUSED_ARG(pcb); -#endif /* !MPPE_SUPPORT */ - BZERO(response, MS_CHAP_RESPONSE_LEN); - - ChapMS_NT(rchallenge, secret, secret_len, &response[MS_CHAP_NTRESP]); - -#ifdef MSLANMAN - ChapMS_LANMan(rchallenge, secret, secret_len, - &response[MS_CHAP_LANMANRESP]); - - /* preferred method is set by option */ - response[MS_CHAP_USENT] = !ms_lanman; -#else - response[MS_CHAP_USENT] = 1; -#endif - -#if MPPE_SUPPORT - Set_Start_Key(pcb, rchallenge, secret, secret_len); -#endif /* MPPE_SUPPORT */ -} - - -/* - * If PeerChallenge is NULL, one is generated and the PeerChallenge - * field of response is filled in. Call this way when generating a response. - * If PeerChallenge is supplied, it is copied into the PeerChallenge field. - * Call this way when verifying a response (or debugging). - * Do not call with PeerChallenge = response. - * - * The PeerChallenge field of response is then used for calculation of the - * Authenticator Response. - */ -static void ChapMS2(ppp_pcb *pcb, const u_char *rchallenge, const u_char *PeerChallenge, - const char *user, const char *secret, int secret_len, unsigned char *response, - u_char authResponse[], int authenticator) { - /* ARGSUSED */ - LWIP_UNUSED_ARG(authenticator); -#if !MPPE_SUPPORT - LWIP_UNUSED_ARG(pcb); -#endif /* !MPPE_SUPPORT */ - - BZERO(response, MS_CHAP2_RESPONSE_LEN); - - /* Generate the Peer-Challenge if requested, or copy it if supplied. */ - if (!PeerChallenge) - magic_random_bytes(&response[MS_CHAP2_PEER_CHALLENGE], MS_CHAP2_PEER_CHAL_LEN); - else - MEMCPY(&response[MS_CHAP2_PEER_CHALLENGE], PeerChallenge, - MS_CHAP2_PEER_CHAL_LEN); - - /* Generate the NT-Response */ - ChapMS2_NT(rchallenge, &response[MS_CHAP2_PEER_CHALLENGE], user, - secret, secret_len, &response[MS_CHAP2_NTRESP]); - - /* Generate the Authenticator Response. */ - GenerateAuthenticatorResponsePlain(secret, secret_len, - &response[MS_CHAP2_NTRESP], - &response[MS_CHAP2_PEER_CHALLENGE], - rchallenge, user, authResponse); - -#if MPPE_SUPPORT - SetMasterKeys(pcb, secret, secret_len, - &response[MS_CHAP2_NTRESP], authenticator); -#endif /* MPPE_SUPPORT */ -} - -#if 0 /* UNUSED */ -#if MPPE_SUPPORT -/* - * Set MPPE options from plugins. - */ -void set_mppe_enc_types(int policy, int types) { - /* Early exit for unknown policies. */ - if (policy != MPPE_ENC_POL_ENC_ALLOWED || - policy != MPPE_ENC_POL_ENC_REQUIRED) - return; - - /* Don't modify MPPE if it's optional and wasn't already configured. */ - if (policy == MPPE_ENC_POL_ENC_ALLOWED && !ccp_wantoptions[0].mppe) - return; - - /* - * Disable undesirable encryption types. Note that we don't ENABLE - * any encryption types, to avoid overriding manual configuration. - */ - switch(types) { - case MPPE_ENC_TYPES_RC4_40: - ccp_wantoptions[0].mppe &= ~MPPE_OPT_128; /* disable 128-bit */ - break; - case MPPE_ENC_TYPES_RC4_128: - ccp_wantoptions[0].mppe &= ~MPPE_OPT_40; /* disable 40-bit */ - break; - default: - break; - } -} -#endif /* MPPE_SUPPORT */ -#endif /* UNUSED */ - -const struct chap_digest_type chapms_digest = { - CHAP_MICROSOFT, /* code */ -#if PPP_SERVER - chapms_generate_challenge, - chapms_verify_response, -#endif /* PPP_SERVER */ - chapms_make_response, - NULL, /* check_success */ - chapms_handle_failure, -}; - -const struct chap_digest_type chapms2_digest = { - CHAP_MICROSOFT_V2, /* code */ -#if PPP_SERVER - chapms2_generate_challenge, - chapms2_verify_response, -#endif /* PPP_SERVER */ - chapms2_make_response, - chapms2_check_success, - chapms_handle_failure, -}; - -#endif /* PPP_SUPPORT && MSCHAP_SUPPORT */ diff --git a/third_party/lwip/repo/lwip/src/netif/ppp/demand.c b/third_party/lwip/repo/lwip/src/netif/ppp/demand.c deleted file mode 100644 index 26c6c30db1a1a6..00000000000000 --- a/third_party/lwip/repo/lwip/src/netif/ppp/demand.c +++ /dev/null @@ -1,465 +0,0 @@ -/* - * demand.c - Support routines for demand-dialling. - * - * Copyright (c) 1996-2002 Paul Mackerras. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. The name(s) of the authors of this software must not be used to - * endorse or promote products derived from this software without - * prior written permission. - * - * 3. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Paul Mackerras - * ". - * - * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT && DEMAND_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef PPP_FILTER -#include -#endif - -#include "netif/ppp/ppp_impl.h" - -#include "netif/ppp/fsm.h" -#include "netif/ppp/ipcp.h" -#include "netif/ppp/lcp.h" - -char *frame; -int framelen; -int framemax; -int escape_flag; -int flush_flag; -int fcs; - -struct packet { - int length; - struct packet *next; - unsigned char data[1]; -}; - -struct packet *pend_q; -struct packet *pend_qtail; - -static int active_packet (unsigned char *, int); - -/* - * demand_conf - configure the interface for doing dial-on-demand. - */ -void -demand_conf() -{ - int i; - const struct protent *protp; - -/* framemax = lcp_allowoptions[0].mru; - if (framemax < PPP_MRU) */ - framemax = PPP_MRU; - framemax += PPP_HDRLEN + PPP_FCSLEN; - frame = malloc(framemax); - if (frame == NULL) - novm("demand frame"); - framelen = 0; - pend_q = NULL; - escape_flag = 0; - flush_flag = 0; - fcs = PPP_INITFCS; - - netif_set_mtu(pcb, LWIP_MIN(lcp_allowoptions[0].mru, PPP_MRU)); - if (ppp_send_config(pcb, PPP_MRU, (u32_t) 0, 0, 0) < 0 - || ppp_recv_config(pcb, PPP_MRU, (u32_t) 0, 0, 0) < 0) - fatal("Couldn't set up demand-dialled PPP interface: %m"); - -#ifdef PPP_FILTER - set_filters(&pass_filter, &active_filter); -#endif - - /* - * Call the demand_conf procedure for each protocol that's got one. - */ - for (i = 0; (protp = protocols[i]) != NULL; ++i) - if (protp->demand_conf != NULL) - ((*protp->demand_conf)(pcb)); -/* FIXME: find a way to die() here */ -#if 0 - if (!((*protp->demand_conf)(pcb))) - die(1); -#endif -} - - -/* - * demand_block - set each network protocol to block further packets. - */ -void -demand_block() -{ - int i; - const struct protent *protp; - - for (i = 0; (protp = protocols[i]) != NULL; ++i) - if (protp->demand_conf != NULL) - sifnpmode(pcb, protp->protocol & ~0x8000, NPMODE_QUEUE); - get_loop_output(); -} - -/* - * demand_discard - set each network protocol to discard packets - * with an error. - */ -void -demand_discard() -{ - struct packet *pkt, *nextpkt; - int i; - const struct protent *protp; - - for (i = 0; (protp = protocols[i]) != NULL; ++i) - if (protp->demand_conf != NULL) - sifnpmode(pcb, protp->protocol & ~0x8000, NPMODE_ERROR); - get_loop_output(); - - /* discard all saved packets */ - for (pkt = pend_q; pkt != NULL; pkt = nextpkt) { - nextpkt = pkt->next; - free(pkt); - } - pend_q = NULL; - framelen = 0; - flush_flag = 0; - escape_flag = 0; - fcs = PPP_INITFCS; -} - -/* - * demand_unblock - set each enabled network protocol to pass packets. - */ -void -demand_unblock() -{ - int i; - const struct protent *protp; - - for (i = 0; (protp = protocols[i]) != NULL; ++i) - if (protp->demand_conf != NULL) - sifnpmode(pcb, protp->protocol & ~0x8000, NPMODE_PASS); -} - -/* - * FCS lookup table as calculated by genfcstab. - */ -static u_short fcstab[256] = { - 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, - 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, - 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, - 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, - 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, - 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, - 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, - 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, - 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, - 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, - 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, - 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, - 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, - 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, - 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, - 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, - 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, - 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, - 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, - 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, - 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, - 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, - 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, - 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, - 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, - 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, - 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, - 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, - 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, - 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, - 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, - 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78 -}; - -/* - * loop_chars - process characters received from the loopback. - * Calls loop_frame when a complete frame has been accumulated. - * Return value is 1 if we need to bring up the link, 0 otherwise. - */ -int -loop_chars(p, n) - unsigned char *p; - int n; -{ - int c, rv; - - rv = 0; - -/* check for synchronous connection... */ - - if ( (p[0] == 0xFF) && (p[1] == 0x03) ) { - rv = loop_frame(p,n); - return rv; - } - - for (; n > 0; --n) { - c = *p++; - if (c == PPP_FLAG) { - if (!escape_flag && !flush_flag - && framelen > 2 && fcs == PPP_GOODFCS) { - framelen -= 2; - if (loop_frame((unsigned char *)frame, framelen)) - rv = 1; - } - framelen = 0; - flush_flag = 0; - escape_flag = 0; - fcs = PPP_INITFCS; - continue; - } - if (flush_flag) - continue; - if (escape_flag) { - c ^= PPP_TRANS; - escape_flag = 0; - } else if (c == PPP_ESCAPE) { - escape_flag = 1; - continue; - } - if (framelen >= framemax) { - flush_flag = 1; - continue; - } - frame[framelen++] = c; - fcs = PPP_FCS(fcs, c); - } - return rv; -} - -/* - * loop_frame - given a frame obtained from the loopback, - * decide whether to bring up the link or not, and, if we want - * to transmit this frame later, put it on the pending queue. - * Return value is 1 if we need to bring up the link, 0 otherwise. - * We assume that the kernel driver has already applied the - * pass_filter, so we won't get packets it rejected. - * We apply the active_filter to see if we want this packet to - * bring up the link. - */ -int -loop_frame(frame, len) - unsigned char *frame; - int len; -{ - struct packet *pkt; - - /* dbglog("from loop: %P", frame, len); */ - if (len < PPP_HDRLEN) - return 0; - if ((PPP_PROTOCOL(frame) & 0x8000) != 0) - return 0; /* shouldn't get any of these anyway */ - if (!active_packet(frame, len)) - return 0; - - pkt = (struct packet *) malloc(sizeof(struct packet) + len); - if (pkt != NULL) { - pkt->length = len; - pkt->next = NULL; - memcpy(pkt->data, frame, len); - if (pend_q == NULL) - pend_q = pkt; - else - pend_qtail->next = pkt; - pend_qtail = pkt; - } - return 1; -} - -/* - * demand_rexmit - Resend all those frames which we got via the - * loopback, now that the real serial link is up. - */ -void -demand_rexmit(proto, newip) - int proto; - u32_t newip; -{ - struct packet *pkt, *prev, *nextpkt; - unsigned short checksum; - unsigned short pkt_checksum = 0; - unsigned iphdr; - struct timeval tv; - char cv = 0; - char ipstr[16]; - - prev = NULL; - pkt = pend_q; - pend_q = NULL; - tv.tv_sec = 1; - tv.tv_usec = 0; - select(0,NULL,NULL,NULL,&tv); /* Sleep for 1 Seconds */ - for (; pkt != NULL; pkt = nextpkt) { - nextpkt = pkt->next; - if (PPP_PROTOCOL(pkt->data) == proto) { - if ( (proto == PPP_IP) && newip ) { - /* Get old checksum */ - - iphdr = (pkt->data[4] & 15) << 2; - checksum = *((unsigned short *) (pkt->data+14)); - if (checksum == 0xFFFF) { - checksum = 0; - } - - - if (pkt->data[13] == 17) { - pkt_checksum = *((unsigned short *) (pkt->data+10+iphdr)); - if (pkt_checksum) { - cv = 1; - if (pkt_checksum == 0xFFFF) { - pkt_checksum = 0; - } - } - else { - cv = 0; - } - } - - if (pkt->data[13] == 6) { - pkt_checksum = *((unsigned short *) (pkt->data+20+iphdr)); - cv = 1; - if (pkt_checksum == 0xFFFF) { - pkt_checksum = 0; - } - } - - /* Delete old Source-IP-Address */ - checksum -= *((unsigned short *) (pkt->data+16)) ^ 0xFFFF; - checksum -= *((unsigned short *) (pkt->data+18)) ^ 0xFFFF; - - pkt_checksum -= *((unsigned short *) (pkt->data+16)) ^ 0xFFFF; - pkt_checksum -= *((unsigned short *) (pkt->data+18)) ^ 0xFFFF; - - /* Change Source-IP-Address */ - * ((u32_t *) (pkt->data + 16)) = newip; - - /* Add new Source-IP-Address */ - checksum += *((unsigned short *) (pkt->data+16)) ^ 0xFFFF; - checksum += *((unsigned short *) (pkt->data+18)) ^ 0xFFFF; - - pkt_checksum += *((unsigned short *) (pkt->data+16)) ^ 0xFFFF; - pkt_checksum += *((unsigned short *) (pkt->data+18)) ^ 0xFFFF; - - /* Write new checksum */ - if (!checksum) { - checksum = 0xFFFF; - } - *((unsigned short *) (pkt->data+14)) = checksum; - if (pkt->data[13] == 6) { - *((unsigned short *) (pkt->data+20+iphdr)) = pkt_checksum; - } - if (cv && (pkt->data[13] == 17) ) { - *((unsigned short *) (pkt->data+10+iphdr)) = pkt_checksum; - } - - /* Log Packet */ - strcpy(ipstr,inet_ntoa(*( (struct in_addr *) (pkt->data+16)))); - if (pkt->data[13] == 1) { - syslog(LOG_INFO,"Open ICMP %s -> %s\n", - ipstr, - inet_ntoa(*( (struct in_addr *) (pkt->data+20)))); - } else { - syslog(LOG_INFO,"Open %s %s:%d -> %s:%d\n", - pkt->data[13] == 6 ? "TCP" : "UDP", - ipstr, - ntohs(*( (short *) (pkt->data+iphdr+4))), - inet_ntoa(*( (struct in_addr *) (pkt->data+20))), - ntohs(*( (short *) (pkt->data+iphdr+6)))); - } - } - output(pcb, pkt->data, pkt->length); - free(pkt); - } else { - if (prev == NULL) - pend_q = pkt; - else - prev->next = pkt; - prev = pkt; - } - } - pend_qtail = prev; - if (prev != NULL) - prev->next = NULL; -} - -/* - * Scan a packet to decide whether it is an "active" packet, - * that is, whether it is worth bringing up the link for. - */ -static int -active_packet(p, len) - unsigned char *p; - int len; -{ - int proto, i; - const struct protent *protp; - - if (len < PPP_HDRLEN) - return 0; - proto = PPP_PROTOCOL(p); -#ifdef PPP_FILTER - p[0] = 1; /* outbound packet indicator */ - if ((pass_filter.bf_len != 0 - && bpf_filter(pass_filter.bf_insns, p, len, len) == 0) - || (active_filter.bf_len != 0 - && bpf_filter(active_filter.bf_insns, p, len, len) == 0)) { - p[0] = 0xff; - return 0; - } - p[0] = 0xff; -#endif - for (i = 0; (protp = protocols[i]) != NULL; ++i) { - if (protp->protocol < 0xC000 && (protp->protocol & ~0x8000) == proto) { - if (protp->active_pkt == NULL) - return 1; - return (*protp->active_pkt)(p, len); - } - } - return 0; /* not a supported protocol !!?? */ -} - -#endif /* PPP_SUPPORT && DEMAND_SUPPORT */ diff --git a/third_party/lwip/repo/lwip/src/netif/ppp/eap.c b/third_party/lwip/repo/lwip/src/netif/ppp/eap.c deleted file mode 100644 index 8fb56368e7178f..00000000000000 --- a/third_party/lwip/repo/lwip/src/netif/ppp/eap.c +++ /dev/null @@ -1,2423 +0,0 @@ -/* - * eap.c - Extensible Authentication Protocol for PPP (RFC 2284) - * - * Copyright (c) 2001 by Sun Microsystems, Inc. - * All rights reserved. - * - * Non-exclusive rights to redistribute, modify, translate, and use - * this software in source and binary forms, in whole or in part, is - * hereby granted, provided that the above copyright notice is - * duplicated in any source form, and that neither the name of the - * copyright holder nor the author is used to endorse or promote - * products derived from this software. - * - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * Original version by James Carlson - * - * This implementation of EAP supports MD5-Challenge and SRP-SHA1 - * authentication styles. Note that support of MD5-Challenge is a - * requirement of RFC 2284, and that it's essentially just a - * reimplementation of regular RFC 1994 CHAP using EAP messages. - * - * As an authenticator ("server"), there are multiple phases for each - * style. In the first phase of each style, the unauthenticated peer - * name is queried using the EAP Identity request type. If the - * "remotename" option is used, then this phase is skipped, because - * the peer's name is presumed to be known. - * - * For MD5-Challenge, there are two phases, and the second phase - * consists of sending the challenge itself and handling the - * associated response. - * - * For SRP-SHA1, there are four phases. The second sends 's', 'N', - * and 'g'. The reply contains 'A'. The third sends 'B', and the - * reply contains 'M1'. The forth sends the 'M2' value. - * - * As an authenticatee ("client"), there's just a single phase -- - * responding to the queries generated by the peer. EAP is an - * authenticator-driven protocol. - * - * Based on draft-ietf-pppext-eap-srp-03.txt. - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT && EAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#include "netif/ppp/ppp_impl.h" -#include "netif/ppp/eap.h" -#include "netif/ppp/magic.h" -#include "netif/ppp/pppcrypt.h" - -#ifdef USE_SRP -#include -#include -#include -#endif /* USE_SRP */ - -#ifndef SHA_DIGESTSIZE -#define SHA_DIGESTSIZE 20 -#endif - -#ifdef USE_SRP -static char *pn_secret = NULL; /* Pseudonym generating secret */ -#endif - -#if PPP_OPTIONS -/* - * Command-line options. - */ -static option_t eap_option_list[] = { - { "eap-restart", o_int, &eap_states[0].es_server.ea_timeout, - "Set retransmit timeout for EAP Requests (server)" }, - { "eap-max-sreq", o_int, &eap_states[0].es_server.ea_maxrequests, - "Set max number of EAP Requests sent (server)" }, - { "eap-timeout", o_int, &eap_states[0].es_client.ea_timeout, - "Set time limit for peer EAP authentication" }, - { "eap-max-rreq", o_int, &eap_states[0].es_client.ea_maxrequests, - "Set max number of EAP Requests allows (client)" }, - { "eap-interval", o_int, &eap_states[0].es_rechallenge, - "Set interval for EAP rechallenge" }, -#ifdef USE_SRP - { "srp-interval", o_int, &eap_states[0].es_lwrechallenge, - "Set interval for SRP lightweight rechallenge" }, - { "srp-pn-secret", o_string, &pn_secret, - "Long term pseudonym generation secret" }, - { "srp-use-pseudonym", o_bool, &eap_states[0].es_usepseudo, - "Use pseudonym if offered one by server", 1 }, -#endif - { NULL } -}; -#endif /* PPP_OPTIONS */ - -/* - * Protocol entry points. - */ -static void eap_init(ppp_pcb *pcb); -static void eap_input(ppp_pcb *pcb, u_char *inp, int inlen); -static void eap_protrej(ppp_pcb *pcb); -static void eap_lowerup(ppp_pcb *pcb); -static void eap_lowerdown(ppp_pcb *pcb); -#if PRINTPKT_SUPPORT -static int eap_printpkt(const u_char *inp, int inlen, - void (*)(void *arg, const char *fmt, ...), void *arg); -#endif /* PRINTPKT_SUPPORT */ - -const struct protent eap_protent = { - PPP_EAP, /* protocol number */ - eap_init, /* initialization procedure */ - eap_input, /* process a received packet */ - eap_protrej, /* process a received protocol-reject */ - eap_lowerup, /* lower layer has gone up */ - eap_lowerdown, /* lower layer has gone down */ - NULL, /* open the protocol */ - NULL, /* close the protocol */ -#if PRINTPKT_SUPPORT - eap_printpkt, /* print a packet in readable form */ -#endif /* PRINTPKT_SUPPORT */ -#if PPP_DATAINPUT - NULL, /* process a received data packet */ -#endif /* PPP_DATAINPUT */ -#if PRINTPKT_SUPPORT - "EAP", /* text name of protocol */ - NULL, /* text name of corresponding data protocol */ -#endif /* PRINTPKT_SUPPORT */ -#if PPP_OPTIONS - eap_option_list, /* list of command-line options */ - NULL, /* check requested options; assign defaults */ -#endif /* PPP_OPTIONS */ -#if DEMAND_SUPPORT - NULL, /* configure interface for demand-dial */ - NULL /* say whether to bring up link for this pkt */ -#endif /* DEMAND_SUPPORT */ -}; - -#ifdef USE_SRP -/* - * A well-known 2048 bit modulus. - */ -static const u_char wkmodulus[] = { - 0xAC, 0x6B, 0xDB, 0x41, 0x32, 0x4A, 0x9A, 0x9B, - 0xF1, 0x66, 0xDE, 0x5E, 0x13, 0x89, 0x58, 0x2F, - 0xAF, 0x72, 0xB6, 0x65, 0x19, 0x87, 0xEE, 0x07, - 0xFC, 0x31, 0x92, 0x94, 0x3D, 0xB5, 0x60, 0x50, - 0xA3, 0x73, 0x29, 0xCB, 0xB4, 0xA0, 0x99, 0xED, - 0x81, 0x93, 0xE0, 0x75, 0x77, 0x67, 0xA1, 0x3D, - 0xD5, 0x23, 0x12, 0xAB, 0x4B, 0x03, 0x31, 0x0D, - 0xCD, 0x7F, 0x48, 0xA9, 0xDA, 0x04, 0xFD, 0x50, - 0xE8, 0x08, 0x39, 0x69, 0xED, 0xB7, 0x67, 0xB0, - 0xCF, 0x60, 0x95, 0x17, 0x9A, 0x16, 0x3A, 0xB3, - 0x66, 0x1A, 0x05, 0xFB, 0xD5, 0xFA, 0xAA, 0xE8, - 0x29, 0x18, 0xA9, 0x96, 0x2F, 0x0B, 0x93, 0xB8, - 0x55, 0xF9, 0x79, 0x93, 0xEC, 0x97, 0x5E, 0xEA, - 0xA8, 0x0D, 0x74, 0x0A, 0xDB, 0xF4, 0xFF, 0x74, - 0x73, 0x59, 0xD0, 0x41, 0xD5, 0xC3, 0x3E, 0xA7, - 0x1D, 0x28, 0x1E, 0x44, 0x6B, 0x14, 0x77, 0x3B, - 0xCA, 0x97, 0xB4, 0x3A, 0x23, 0xFB, 0x80, 0x16, - 0x76, 0xBD, 0x20, 0x7A, 0x43, 0x6C, 0x64, 0x81, - 0xF1, 0xD2, 0xB9, 0x07, 0x87, 0x17, 0x46, 0x1A, - 0x5B, 0x9D, 0x32, 0xE6, 0x88, 0xF8, 0x77, 0x48, - 0x54, 0x45, 0x23, 0xB5, 0x24, 0xB0, 0xD5, 0x7D, - 0x5E, 0xA7, 0x7A, 0x27, 0x75, 0xD2, 0xEC, 0xFA, - 0x03, 0x2C, 0xFB, 0xDB, 0xF5, 0x2F, 0xB3, 0x78, - 0x61, 0x60, 0x27, 0x90, 0x04, 0xE5, 0x7A, 0xE6, - 0xAF, 0x87, 0x4E, 0x73, 0x03, 0xCE, 0x53, 0x29, - 0x9C, 0xCC, 0x04, 0x1C, 0x7B, 0xC3, 0x08, 0xD8, - 0x2A, 0x56, 0x98, 0xF3, 0xA8, 0xD0, 0xC3, 0x82, - 0x71, 0xAE, 0x35, 0xF8, 0xE9, 0xDB, 0xFB, 0xB6, - 0x94, 0xB5, 0xC8, 0x03, 0xD8, 0x9F, 0x7A, 0xE4, - 0x35, 0xDE, 0x23, 0x6D, 0x52, 0x5F, 0x54, 0x75, - 0x9B, 0x65, 0xE3, 0x72, 0xFC, 0xD6, 0x8E, 0xF2, - 0x0F, 0xA7, 0x11, 0x1F, 0x9E, 0x4A, 0xFF, 0x73 -}; -#endif - -#if PPP_SERVER -/* Local forward declarations. */ -static void eap_server_timeout(void *arg); -#endif /* PPP_SERVER */ - -/* - * Convert EAP state code to printable string for debug. - */ -static const char * eap_state_name(enum eap_state_code esc) -{ - static const char *state_names[] = { EAP_STATES }; - - return (state_names[(int)esc]); -} - -/* - * eap_init - Initialize state for an EAP user. This is currently - * called once by main() during start-up. - */ -static void eap_init(ppp_pcb *pcb) { - - BZERO(&pcb->eap, sizeof(eap_state)); -#if PPP_SERVER - pcb->eap.es_server.ea_id = magic(); -#endif /* PPP_SERVER */ -} - -/* - * eap_client_timeout - Give up waiting for the peer to send any - * Request messages. - */ -static void eap_client_timeout(void *arg) { - ppp_pcb *pcb = (ppp_pcb*)arg; - - if (!eap_client_active(pcb)) - return; - - ppp_error("EAP: timeout waiting for Request from peer"); - auth_withpeer_fail(pcb, PPP_EAP); - pcb->eap.es_client.ea_state = eapBadAuth; -} - -/* - * eap_authwithpeer - Authenticate to our peer (behave as client). - * - * Start client state and wait for requests. This is called only - * after eap_lowerup. - */ -void eap_authwithpeer(ppp_pcb *pcb, const char *localname) { - - if(NULL == localname) - return; - - /* Save the peer name we're given */ - pcb->eap.es_client.ea_name = localname; - pcb->eap.es_client.ea_namelen = strlen(localname); - - pcb->eap.es_client.ea_state = eapListen; - - /* - * Start a timer so that if the other end just goes - * silent, we don't sit here waiting forever. - */ - if (pcb->settings.eap_req_time > 0) - TIMEOUT(eap_client_timeout, pcb, - pcb->settings.eap_req_time); -} - -#if PPP_SERVER -/* - * Format a standard EAP Failure message and send it to the peer. - * (Server operation) - */ -static void eap_send_failure(ppp_pcb *pcb) { - struct pbuf *p; - u_char *outp; - - p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN + EAP_HEADERLEN), PPP_CTRL_PBUF_TYPE); - if(NULL == p) - return; - if(p->tot_len != p->len) { - pbuf_free(p); - return; - } - - outp = (u_char*)p->payload; - - MAKEHEADER(outp, PPP_EAP); - - PUTCHAR(EAP_FAILURE, outp); - pcb->eap.es_server.ea_id++; - PUTCHAR(pcb->eap.es_server.ea_id, outp); - PUTSHORT(EAP_HEADERLEN, outp); - - ppp_write(pcb, p); - - pcb->eap.es_server.ea_state = eapBadAuth; - auth_peer_fail(pcb, PPP_EAP); -} - -/* - * Format a standard EAP Success message and send it to the peer. - * (Server operation) - */ -static void eap_send_success(ppp_pcb *pcb) { - struct pbuf *p; - u_char *outp; - - p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN + EAP_HEADERLEN), PPP_CTRL_PBUF_TYPE); - if(NULL == p) - return; - if(p->tot_len != p->len) { - pbuf_free(p); - return; - } - - outp = (u_char*)p->payload; - - MAKEHEADER(outp, PPP_EAP); - - PUTCHAR(EAP_SUCCESS, outp); - pcb->eap.es_server.ea_id++; - PUTCHAR(pcb->eap.es_server.ea_id, outp); - PUTSHORT(EAP_HEADERLEN, outp); - - ppp_write(pcb, p); - - auth_peer_success(pcb, PPP_EAP, 0, - pcb->eap.es_server.ea_peer, pcb->eap.es_server.ea_peerlen); -} -#endif /* PPP_SERVER */ - -#ifdef USE_SRP -/* - * Set DES key according to pseudonym-generating secret and current - * date. - */ -static bool -pncrypt_setkey(int timeoffs) -{ - struct tm *tp; - char tbuf[9]; - SHA1_CTX ctxt; - u_char dig[SHA_DIGESTSIZE]; - time_t reftime; - - if (pn_secret == NULL) - return (0); - reftime = time(NULL) + timeoffs; - tp = localtime(&reftime); - SHA1Init(&ctxt); - SHA1Update(&ctxt, pn_secret, strlen(pn_secret)); - strftime(tbuf, sizeof (tbuf), "%Y%m%d", tp); - SHA1Update(&ctxt, tbuf, strlen(tbuf)); - SHA1Final(dig, &ctxt); - /* FIXME: if we want to do SRP, we need to find a way to pass the PolarSSL des_context instead of using static memory */ - return (DesSetkey(dig)); -} - -static char base64[] = -"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - -struct b64state { - u32_t bs_bits; - int bs_offs; -}; - -static int -b64enc(bs, inp, inlen, outp) -struct b64state *bs; -u_char *inp; -int inlen; -u_char *outp; -{ - int outlen = 0; - - while (inlen > 0) { - bs->bs_bits = (bs->bs_bits << 8) | *inp++; - inlen--; - bs->bs_offs += 8; - if (bs->bs_offs >= 24) { - *outp++ = base64[(bs->bs_bits >> 18) & 0x3F]; - *outp++ = base64[(bs->bs_bits >> 12) & 0x3F]; - *outp++ = base64[(bs->bs_bits >> 6) & 0x3F]; - *outp++ = base64[bs->bs_bits & 0x3F]; - outlen += 4; - bs->bs_offs = 0; - bs->bs_bits = 0; - } - } - return (outlen); -} - -static int -b64flush(bs, outp) -struct b64state *bs; -u_char *outp; -{ - int outlen = 0; - - if (bs->bs_offs == 8) { - *outp++ = base64[(bs->bs_bits >> 2) & 0x3F]; - *outp++ = base64[(bs->bs_bits << 4) & 0x3F]; - outlen = 2; - } else if (bs->bs_offs == 16) { - *outp++ = base64[(bs->bs_bits >> 10) & 0x3F]; - *outp++ = base64[(bs->bs_bits >> 4) & 0x3F]; - *outp++ = base64[(bs->bs_bits << 2) & 0x3F]; - outlen = 3; - } - bs->bs_offs = 0; - bs->bs_bits = 0; - return (outlen); -} - -static int -b64dec(bs, inp, inlen, outp) -struct b64state *bs; -u_char *inp; -int inlen; -u_char *outp; -{ - int outlen = 0; - char *cp; - - while (inlen > 0) { - if ((cp = strchr(base64, *inp++)) == NULL) - break; - bs->bs_bits = (bs->bs_bits << 6) | (cp - base64); - inlen--; - bs->bs_offs += 6; - if (bs->bs_offs >= 8) { - *outp++ = bs->bs_bits >> (bs->bs_offs - 8); - outlen++; - bs->bs_offs -= 8; - } - } - return (outlen); -} -#endif /* USE_SRP */ - -#if PPP_SERVER -/* - * Assume that current waiting server state is complete and figure - * next state to use based on available authentication data. 'status' - * indicates if there was an error in handling the last query. It is - * 0 for success and non-zero for failure. - */ -static void eap_figure_next_state(ppp_pcb *pcb, int status) { -#ifdef USE_SRP - unsigned char secbuf[MAXSECRETLEN], clear[8], *sp, *dp; - struct t_pw tpw; - struct t_confent *tce, mytce; - char *cp, *cp2; - struct t_server *ts; - int id, i, plen, toffs; - u_char vals[2]; - struct b64state bs; -#endif /* USE_SRP */ - - pcb->settings.eap_timeout_time = pcb->eap.es_savedtime; - switch (pcb->eap.es_server.ea_state) { - case eapBadAuth: - return; - - case eapIdentify: -#ifdef USE_SRP - /* Discard any previous session. */ - ts = (struct t_server *)pcb->eap.es_server.ea_session; - if (ts != NULL) { - t_serverclose(ts); - pcb->eap.es_server.ea_session = NULL; - pcb->eap.es_server.ea_skey = NULL; - } -#endif /* USE_SRP */ - if (status != 0) { - pcb->eap.es_server.ea_state = eapBadAuth; - break; - } -#ifdef USE_SRP - /* If we've got a pseudonym, try to decode to real name. */ - if (pcb->eap.es_server.ea_peerlen > SRP_PSEUDO_LEN && - strncmp(pcb->eap.es_server.ea_peer, SRP_PSEUDO_ID, - SRP_PSEUDO_LEN) == 0 && - (pcb->eap.es_server.ea_peerlen - SRP_PSEUDO_LEN) * 3 / 4 < - sizeof (secbuf)) { - BZERO(&bs, sizeof (bs)); - plen = b64dec(&bs, - pcb->eap.es_server.ea_peer + SRP_PSEUDO_LEN, - pcb->eap.es_server.ea_peerlen - SRP_PSEUDO_LEN, - secbuf); - toffs = 0; - for (i = 0; i < 5; i++) { - pncrypt_setkey(toffs); - toffs -= 86400; - /* FIXME: if we want to do SRP, we need to find a way to pass the PolarSSL des_context instead of using static memory */ - if (!DesDecrypt(secbuf, clear)) { - ppp_dbglog("no DES here; cannot decode " - "pseudonym"); - return; - } - id = *(unsigned char *)clear; - if (id + 1 <= plen && id + 9 > plen) - break; - } - if (plen % 8 == 0 && i < 5) { - /* - * Note that this is always shorter than the - * original stored string, so there's no need - * to realloc. - */ - if ((i = plen = *(unsigned char *)clear) > 7) - i = 7; - pcb->eap.es_server.ea_peerlen = plen; - dp = (unsigned char *)pcb->eap.es_server.ea_peer; - MEMCPY(dp, clear + 1, i); - plen -= i; - dp += i; - sp = secbuf + 8; - while (plen > 0) { - /* FIXME: if we want to do SRP, we need to find a way to pass the PolarSSL des_context instead of using static memory */ - (void) DesDecrypt(sp, dp); - sp += 8; - dp += 8; - plen -= 8; - } - pcb->eap.es_server.ea_peer[ - pcb->eap.es_server.ea_peerlen] = '\0'; - ppp_dbglog("decoded pseudonym to \"%.*q\"", - pcb->eap.es_server.ea_peerlen, - pcb->eap.es_server.ea_peer); - } else { - ppp_dbglog("failed to decode real name"); - /* Stay in eapIdentfy state; requery */ - break; - } - } - /* Look up user in secrets database. */ - if (get_srp_secret(pcb->eap.es_unit, pcb->eap.es_server.ea_peer, - pcb->eap.es_server.ea_name, (char *)secbuf, 1) != 0) { - /* Set up default in case SRP entry is bad */ - pcb->eap.es_server.ea_state = eapMD5Chall; - /* Get t_confent based on index in srp-secrets */ - id = strtol((char *)secbuf, &cp, 10); - if (*cp++ != ':' || id < 0) - break; - if (id == 0) { - mytce.index = 0; - mytce.modulus.data = (u_char *)wkmodulus; - mytce.modulus.len = sizeof (wkmodulus); - mytce.generator.data = (u_char *)"\002"; - mytce.generator.len = 1; - tce = &mytce; - } else if ((tce = gettcid(id)) != NULL) { - /* - * Client will have to verify this modulus/ - * generator combination, and that will take - * a while. Lengthen the timeout here. - */ - if (pcb->settings.eap_timeout_time > 0 && - pcb->settings.eap_timeout_time < 30) - pcb->settings.eap_timeout_time = 30; - } else { - break; - } - if ((cp2 = strchr(cp, ':')) == NULL) - break; - *cp2++ = '\0'; - tpw.pebuf.name = pcb->eap.es_server.ea_peer; - tpw.pebuf.password.len = t_fromb64((char *)tpw.pwbuf, - cp); - tpw.pebuf.password.data = tpw.pwbuf; - tpw.pebuf.salt.len = t_fromb64((char *)tpw.saltbuf, - cp2); - tpw.pebuf.salt.data = tpw.saltbuf; - if ((ts = t_serveropenraw(&tpw.pebuf, tce)) == NULL) - break; - pcb->eap.es_server.ea_session = (void *)ts; - pcb->eap.es_server.ea_state = eapSRP1; - vals[0] = pcb->eap.es_server.ea_id + 1; - vals[1] = EAPT_SRP; - t_serveraddexdata(ts, vals, 2); - /* Generate B; must call before t_servergetkey() */ - t_servergenexp(ts); - break; - } -#endif /* USE_SRP */ - pcb->eap.es_server.ea_state = eapMD5Chall; - break; - - case eapSRP1: -#ifdef USE_SRP - ts = (struct t_server *)pcb->eap.es_server.ea_session; - if (ts != NULL && status != 0) { - t_serverclose(ts); - pcb->eap.es_server.ea_session = NULL; - pcb->eap.es_server.ea_skey = NULL; - } -#endif /* USE_SRP */ - if (status == 1) { - pcb->eap.es_server.ea_state = eapMD5Chall; - } else if (status != 0 || pcb->eap.es_server.ea_session == NULL) { - pcb->eap.es_server.ea_state = eapBadAuth; - } else { - pcb->eap.es_server.ea_state = eapSRP2; - } - break; - - case eapSRP2: -#ifdef USE_SRP - ts = (struct t_server *)pcb->eap.es_server.ea_session; - if (ts != NULL && status != 0) { - t_serverclose(ts); - pcb->eap.es_server.ea_session = NULL; - pcb->eap.es_server.ea_skey = NULL; - } -#endif /* USE_SRP */ - if (status != 0 || pcb->eap.es_server.ea_session == NULL) { - pcb->eap.es_server.ea_state = eapBadAuth; - } else { - pcb->eap.es_server.ea_state = eapSRP3; - } - break; - - case eapSRP3: - case eapSRP4: -#ifdef USE_SRP - ts = (struct t_server *)pcb->eap.es_server.ea_session; - if (ts != NULL && status != 0) { - t_serverclose(ts); - pcb->eap.es_server.ea_session = NULL; - pcb->eap.es_server.ea_skey = NULL; - } -#endif /* USE_SRP */ - if (status != 0 || pcb->eap.es_server.ea_session == NULL) { - pcb->eap.es_server.ea_state = eapBadAuth; - } else { - pcb->eap.es_server.ea_state = eapOpen; - } - break; - - case eapMD5Chall: - if (status != 0) { - pcb->eap.es_server.ea_state = eapBadAuth; - } else { - pcb->eap.es_server.ea_state = eapOpen; - } - break; - - default: - pcb->eap.es_server.ea_state = eapBadAuth; - break; - } - if (pcb->eap.es_server.ea_state == eapBadAuth) - eap_send_failure(pcb); -} - -/* - * Format an EAP Request message and send it to the peer. Message - * type depends on current state. (Server operation) - */ -static void eap_send_request(ppp_pcb *pcb) { - struct pbuf *p; - u_char *outp; - u_char *lenloc; - int outlen; - int len; - const char *str; -#ifdef USE_SRP - struct t_server *ts; - u_char clear[8], cipher[8], dig[SHA_DIGESTSIZE], *optr, *cp; - int i, j; - struct b64state b64; - SHA1_CTX ctxt; -#endif /* USE_SRP */ - - /* Handle both initial auth and restart */ - if (pcb->eap.es_server.ea_state < eapIdentify && - pcb->eap.es_server.ea_state != eapInitial) { - pcb->eap.es_server.ea_state = eapIdentify; -#if PPP_REMOTENAME - if (pcb->settings.explicit_remote && pcb->remote_name) { - /* - * If we already know the peer's - * unauthenticated name, then there's no - * reason to ask. Go to next state instead. - */ - int len = (int)strlen(pcb->remote_name); - if (len > MAXNAMELEN) { - len = MAXNAMELEN; - } - MEMCPY(pcb->eap.es_server.ea_peer, pcb->remote_name, len); - pcb->eap.es_server.ea_peer[len] = '\0'; - pcb->eap.es_server.ea_peerlen = len; - eap_figure_next_state(pcb, 0); - } -#endif /* PPP_REMOTENAME */ - } - - if (pcb->settings.eap_max_transmits > 0 && - pcb->eap.es_server.ea_requests >= pcb->settings.eap_max_transmits) { - if (pcb->eap.es_server.ea_responses > 0) - ppp_error("EAP: too many Requests sent"); - else - ppp_error("EAP: no response to Requests"); - eap_send_failure(pcb); - return; - } - - p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_CTRL_PBUF_MAX_SIZE), PPP_CTRL_PBUF_TYPE); - if(NULL == p) - return; - if(p->tot_len != p->len) { - pbuf_free(p); - return; - } - - outp = (u_char*)p->payload; - - MAKEHEADER(outp, PPP_EAP); - - PUTCHAR(EAP_REQUEST, outp); - PUTCHAR(pcb->eap.es_server.ea_id, outp); - lenloc = outp; - INCPTR(2, outp); - - switch (pcb->eap.es_server.ea_state) { - case eapIdentify: - PUTCHAR(EAPT_IDENTITY, outp); - str = "Name"; - len = strlen(str); - MEMCPY(outp, str, len); - INCPTR(len, outp); - break; - - case eapMD5Chall: - PUTCHAR(EAPT_MD5CHAP, outp); - /* - * pick a random challenge length between - * EAP_MIN_CHALLENGE_LENGTH and EAP_MAX_CHALLENGE_LENGTH - */ - pcb->eap.es_challen = EAP_MIN_CHALLENGE_LENGTH + - magic_pow(EAP_MIN_MAX_POWER_OF_TWO_CHALLENGE_LENGTH); - PUTCHAR(pcb->eap.es_challen, outp); - magic_random_bytes(pcb->eap.es_challenge, pcb->eap.es_challen); - MEMCPY(outp, pcb->eap.es_challenge, pcb->eap.es_challen); - INCPTR(pcb->eap.es_challen, outp); - MEMCPY(outp, pcb->eap.es_server.ea_name, pcb->eap.es_server.ea_namelen); - INCPTR(pcb->eap.es_server.ea_namelen, outp); - break; - -#ifdef USE_SRP - case eapSRP1: - PUTCHAR(EAPT_SRP, outp); - PUTCHAR(EAPSRP_CHALLENGE, outp); - - PUTCHAR(pcb->eap.es_server.ea_namelen, outp); - MEMCPY(outp, pcb->eap.es_server.ea_name, pcb->eap.es_server.ea_namelen); - INCPTR(pcb->eap.es_server.ea_namelen, outp); - - ts = (struct t_server *)pcb->eap.es_server.ea_session; - assert(ts != NULL); - PUTCHAR(ts->s.len, outp); - MEMCPY(outp, ts->s.data, ts->s.len); - INCPTR(ts->s.len, outp); - - if (ts->g.len == 1 && ts->g.data[0] == 2) { - PUTCHAR(0, outp); - } else { - PUTCHAR(ts->g.len, outp); - MEMCPY(outp, ts->g.data, ts->g.len); - INCPTR(ts->g.len, outp); - } - - if (ts->n.len != sizeof (wkmodulus) || - BCMP(ts->n.data, wkmodulus, sizeof (wkmodulus)) != 0) { - MEMCPY(outp, ts->n.data, ts->n.len); - INCPTR(ts->n.len, outp); - } - break; - - case eapSRP2: - PUTCHAR(EAPT_SRP, outp); - PUTCHAR(EAPSRP_SKEY, outp); - - ts = (struct t_server *)pcb->eap.es_server.ea_session; - assert(ts != NULL); - MEMCPY(outp, ts->B.data, ts->B.len); - INCPTR(ts->B.len, outp); - break; - - case eapSRP3: - PUTCHAR(EAPT_SRP, outp); - PUTCHAR(EAPSRP_SVALIDATOR, outp); - PUTLONG(SRPVAL_EBIT, outp); - ts = (struct t_server *)pcb->eap.es_server.ea_session; - assert(ts != NULL); - MEMCPY(outp, t_serverresponse(ts), SHA_DIGESTSIZE); - INCPTR(SHA_DIGESTSIZE, outp); - - if (pncrypt_setkey(0)) { - /* Generate pseudonym */ - optr = outp; - cp = (unsigned char *)pcb->eap.es_server.ea_peer; - if ((j = i = pcb->eap.es_server.ea_peerlen) > 7) - j = 7; - clear[0] = i; - MEMCPY(clear + 1, cp, j); - i -= j; - cp += j; - /* FIXME: if we want to do SRP, we need to find a way to pass the PolarSSL des_context instead of using static memory */ - if (!DesEncrypt(clear, cipher)) { - ppp_dbglog("no DES here; not generating pseudonym"); - break; - } - BZERO(&b64, sizeof (b64)); - outp++; /* space for pseudonym length */ - outp += b64enc(&b64, cipher, 8, outp); - while (i >= 8) { - /* FIXME: if we want to do SRP, we need to find a way to pass the PolarSSL des_context instead of using static memory */ - (void) DesEncrypt(cp, cipher); - outp += b64enc(&b64, cipher, 8, outp); - cp += 8; - i -= 8; - } - if (i > 0) { - MEMCPY(clear, cp, i); - cp += i; - magic_random_bytes(cp, 8-i); - /* FIXME: if we want to do SRP, we need to find a way to pass the PolarSSL des_context instead of using static memory */ - (void) DesEncrypt(clear, cipher); - outp += b64enc(&b64, cipher, 8, outp); - } - outp += b64flush(&b64, outp); - - /* Set length and pad out to next 20 octet boundary */ - i = outp - optr - 1; - *optr = i; - i %= SHA_DIGESTSIZE; - if (i != 0) { - magic_random_bytes(outp, SHA_DIGESTSIZE-i); - INCPTR(SHA_DIGESTSIZE-i, outp); - } - - /* Obscure the pseudonym with SHA1 hash */ - SHA1Init(&ctxt); - SHA1Update(&ctxt, &pcb->eap.es_server.ea_id, 1); - SHA1Update(&ctxt, pcb->eap.es_server.ea_skey, - SESSION_KEY_LEN); - SHA1Update(&ctxt, pcb->eap.es_server.ea_peer, - pcb->eap.es_server.ea_peerlen); - while (optr < outp) { - SHA1Final(dig, &ctxt); - cp = dig; - while (cp < dig + SHA_DIGESTSIZE) - *optr++ ^= *cp++; - SHA1Init(&ctxt); - SHA1Update(&ctxt, &pcb->eap.es_server.ea_id, 1); - SHA1Update(&ctxt, pcb->eap.es_server.ea_skey, - SESSION_KEY_LEN); - SHA1Update(&ctxt, optr - SHA_DIGESTSIZE, - SHA_DIGESTSIZE); - } - } - break; - - case eapSRP4: - PUTCHAR(EAPT_SRP, outp); - PUTCHAR(EAPSRP_LWRECHALLENGE, outp); - pcb->eap.es_challen = EAP_MIN_CHALLENGE_LENGTH + - magic_pow(EAP_MIN_MAX_POWER_OF_TWO_CHALLENGE_LENGTH); - magic_random_bytes(pcb->eap.es_challenge, pcb->eap.es_challen); - MEMCPY(outp, pcb->eap.es_challenge, pcb->eap.es_challen); - INCPTR(pcb->eap.es_challen, outp); - break; -#endif /* USE_SRP */ - - default: - return; - } - - outlen = (outp - (unsigned char*)p->payload) - PPP_HDRLEN; - PUTSHORT(outlen, lenloc); - - pbuf_realloc(p, outlen + PPP_HDRLEN); - ppp_write(pcb, p); - - pcb->eap.es_server.ea_requests++; - - if (pcb->settings.eap_timeout_time > 0) - TIMEOUT(eap_server_timeout, pcb, pcb->settings.eap_timeout_time); -} - -/* - * eap_authpeer - Authenticate our peer (behave as server). - * - * Start server state and send first request. This is called only - * after eap_lowerup. - */ -void eap_authpeer(ppp_pcb *pcb, const char *localname) { - - /* Save the name we're given. */ - pcb->eap.es_server.ea_name = localname; - pcb->eap.es_server.ea_namelen = strlen(localname); - - pcb->eap.es_savedtime = pcb->settings.eap_timeout_time; - - /* Lower layer up yet? */ - if (pcb->eap.es_server.ea_state == eapInitial || - pcb->eap.es_server.ea_state == eapPending) { - pcb->eap.es_server.ea_state = eapPending; - return; - } - - pcb->eap.es_server.ea_state = eapPending; - - /* ID number not updated here intentionally; hashed into M1 */ - eap_send_request(pcb); -} - -/* - * eap_server_timeout - Retransmission timer for sending Requests - * expired. - */ -static void eap_server_timeout(void *arg) { - ppp_pcb *pcb = (ppp_pcb*)arg; - - if (!eap_server_active(pcb)) - return; - - /* EAP ID number must not change on timeout. */ - eap_send_request(pcb); -} - -/* - * When it's time to send rechallenge the peer, this timeout is - * called. Once the rechallenge is successful, the response handler - * will restart the timer. If it fails, then the link is dropped. - */ -static void eap_rechallenge(void *arg) { - ppp_pcb *pcb = (ppp_pcb*)arg; - - if (pcb->eap.es_server.ea_state != eapOpen && - pcb->eap.es_server.ea_state != eapSRP4) - return; - - pcb->eap.es_server.ea_requests = 0; - pcb->eap.es_server.ea_state = eapIdentify; - eap_figure_next_state(pcb, 0); - pcb->eap.es_server.ea_id++; - eap_send_request(pcb); -} - -static void srp_lwrechallenge(void *arg) { - ppp_pcb *pcb = (ppp_pcb*)arg; - - if (pcb->eap.es_server.ea_state != eapOpen || - pcb->eap.es_server.ea_type != EAPT_SRP) - return; - - pcb->eap.es_server.ea_requests = 0; - pcb->eap.es_server.ea_state = eapSRP4; - pcb->eap.es_server.ea_id++; - eap_send_request(pcb); -} -#endif /* PPP_SERVER */ - -/* - * eap_lowerup - The lower layer is now up. - * - * This is called before either eap_authpeer or eap_authwithpeer. See - * link_established() in auth.c. All that's necessary here is to - * return to closed state so that those two routines will do the right - * thing. - */ -static void eap_lowerup(ppp_pcb *pcb) { - pcb->eap.es_client.ea_state = eapClosed; -#if PPP_SERVER - pcb->eap.es_server.ea_state = eapClosed; -#endif /* PPP_SERVER */ -} - -/* - * eap_lowerdown - The lower layer is now down. - * - * Cancel all timeouts and return to initial state. - */ -static void eap_lowerdown(ppp_pcb *pcb) { - - if (eap_client_active(pcb) && pcb->settings.eap_req_time > 0) { - UNTIMEOUT(eap_client_timeout, pcb); - } -#if PPP_SERVER - if (eap_server_active(pcb)) { - if (pcb->settings.eap_timeout_time > 0) { - UNTIMEOUT(eap_server_timeout, pcb); - } - } else { - if ((pcb->eap.es_server.ea_state == eapOpen || - pcb->eap.es_server.ea_state == eapSRP4) && - pcb->eap.es_rechallenge > 0) { - UNTIMEOUT(eap_rechallenge, (void *)pcb); - } - if (pcb->eap.es_server.ea_state == eapOpen && - pcb->eap.es_lwrechallenge > 0) { - UNTIMEOUT(srp_lwrechallenge, (void *)pcb); - } - } - - pcb->eap.es_client.ea_state = pcb->eap.es_server.ea_state = eapInitial; - pcb->eap.es_client.ea_requests = pcb->eap.es_server.ea_requests = 0; -#endif /* PPP_SERVER */ -} - -/* - * eap_protrej - Peer doesn't speak this protocol. - * - * This shouldn't happen. If it does, it represents authentication - * failure. - */ -static void eap_protrej(ppp_pcb *pcb) { - - if (eap_client_active(pcb)) { - ppp_error("EAP authentication failed due to Protocol-Reject"); - auth_withpeer_fail(pcb, PPP_EAP); - } -#if PPP_SERVER - if (eap_server_active(pcb)) { - ppp_error("EAP authentication of peer failed on Protocol-Reject"); - auth_peer_fail(pcb, PPP_EAP); - } -#endif /* PPP_SERVER */ - eap_lowerdown(pcb); -} - -/* - * Format and send a regular EAP Response message. - */ -static void eap_send_response(ppp_pcb *pcb, u_char id, u_char typenum, const u_char *str, int lenstr) { - struct pbuf *p; - u_char *outp; - int msglen; - - msglen = EAP_HEADERLEN + sizeof (u_char) + lenstr; - p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN + msglen), PPP_CTRL_PBUF_TYPE); - if(NULL == p) - return; - if(p->tot_len != p->len) { - pbuf_free(p); - return; - } - - outp = (u_char*)p->payload; - - MAKEHEADER(outp, PPP_EAP); - - PUTCHAR(EAP_RESPONSE, outp); - PUTCHAR(id, outp); - pcb->eap.es_client.ea_id = id; - PUTSHORT(msglen, outp); - PUTCHAR(typenum, outp); - if (lenstr > 0) { - MEMCPY(outp, str, lenstr); - } - - ppp_write(pcb, p); -} - -/* - * Format and send an MD5-Challenge EAP Response message. - */ -static void eap_chap_response(ppp_pcb *pcb, u_char id, u_char *hash, const char *name, int namelen) { - struct pbuf *p; - u_char *outp; - int msglen; - - msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + MD5_SIGNATURE_SIZE + - namelen; - p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN + msglen), PPP_CTRL_PBUF_TYPE); - if(NULL == p) - return; - if(p->tot_len != p->len) { - pbuf_free(p); - return; - } - - outp = (u_char*)p->payload; - - MAKEHEADER(outp, PPP_EAP); - - PUTCHAR(EAP_RESPONSE, outp); - PUTCHAR(id, outp); - pcb->eap.es_client.ea_id = id; - PUTSHORT(msglen, outp); - PUTCHAR(EAPT_MD5CHAP, outp); - PUTCHAR(MD5_SIGNATURE_SIZE, outp); - MEMCPY(outp, hash, MD5_SIGNATURE_SIZE); - INCPTR(MD5_SIGNATURE_SIZE, outp); - if (namelen > 0) { - MEMCPY(outp, name, namelen); - } - - ppp_write(pcb, p); -} - -#ifdef USE_SRP -/* - * Format and send a SRP EAP Response message. - */ -static void -eap_srp_response(esp, id, subtypenum, str, lenstr) -eap_state *esp; -u_char id; -u_char subtypenum; -u_char *str; -int lenstr; -{ - ppp_pcb *pcb = &ppp_pcb_list[pcb->eap.es_unit]; - struct pbuf *p; - u_char *outp; - int msglen; - - msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + lenstr; - p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN + msglen), PPP_CTRL_PBUF_TYPE); - if(NULL == p) - return; - if(p->tot_len != p->len) { - pbuf_free(p); - return; - } - - outp = p->payload; - - MAKEHEADER(outp, PPP_EAP); - - PUTCHAR(EAP_RESPONSE, outp); - PUTCHAR(id, outp); - pcb->eap.es_client.ea_id = id; - PUTSHORT(msglen, outp); - PUTCHAR(EAPT_SRP, outp); - PUTCHAR(subtypenum, outp); - if (lenstr > 0) { - MEMCPY(outp, str, lenstr); - } - - ppp_write(pcb, p); -} - -/* - * Format and send a SRP EAP Client Validator Response message. - */ -static void -eap_srpval_response(esp, id, flags, str) -eap_state *esp; -u_char id; -u32_t flags; -u_char *str; -{ - ppp_pcb *pcb = &ppp_pcb_list[pcb->eap.es_unit]; - struct pbuf *p; - u_char *outp; - int msglen; - - msglen = EAP_HEADERLEN + 2 * sizeof (u_char) + sizeof (u32_t) + - SHA_DIGESTSIZE; - p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN + msglen), PPP_CTRL_PBUF_TYPE); - if(NULL == p) - return; - if(p->tot_len != p->len) { - pbuf_free(p); - return; - } - - outp = p->payload; - - MAKEHEADER(outp, PPP_EAP); - - PUTCHAR(EAP_RESPONSE, outp); - PUTCHAR(id, outp); - pcb->eap.es_client.ea_id = id; - PUTSHORT(msglen, outp); - PUTCHAR(EAPT_SRP, outp); - PUTCHAR(EAPSRP_CVALIDATOR, outp); - PUTLONG(flags, outp); - MEMCPY(outp, str, SHA_DIGESTSIZE); - - ppp_write(pcb, p); -} -#endif /* USE_SRP */ - -static void eap_send_nak(ppp_pcb *pcb, u_char id, u_char type) { - struct pbuf *p; - u_char *outp; - int msglen; - - msglen = EAP_HEADERLEN + 2 * sizeof (u_char); - p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN + msglen), PPP_CTRL_PBUF_TYPE); - if(NULL == p) - return; - if(p->tot_len != p->len) { - pbuf_free(p); - return; - } - - outp = (u_char*)p->payload; - - MAKEHEADER(outp, PPP_EAP); - - PUTCHAR(EAP_RESPONSE, outp); - PUTCHAR(id, outp); - pcb->eap.es_client.ea_id = id; - PUTSHORT(msglen, outp); - PUTCHAR(EAPT_NAK, outp); - PUTCHAR(type, outp); - - ppp_write(pcb, p); -} - -#ifdef USE_SRP -static char * -name_of_pn_file() -{ - char *user, *path, *file; - struct passwd *pw; - size_t pl; - static bool pnlogged = 0; - - pw = getpwuid(getuid()); - if (pw == NULL || (user = pw->pw_dir) == NULL || user[0] == 0) { - errno = EINVAL; - return (NULL); - } - file = _PATH_PSEUDONYM; - pl = strlen(user) + strlen(file) + 2; - path = malloc(pl); - if (path == NULL) - return (NULL); - (void) slprintf(path, pl, "%s/%s", user, file); - if (!pnlogged) { - ppp_dbglog("pseudonym file: %s", path); - pnlogged = 1; - } - return (path); -} - -static int -open_pn_file(modebits) -mode_t modebits; -{ - char *path; - int fd, err; - - if ((path = name_of_pn_file()) == NULL) - return (-1); - fd = open(path, modebits, S_IRUSR | S_IWUSR); - err = errno; - free(path); - errno = err; - return (fd); -} - -static void -remove_pn_file() -{ - char *path; - - if ((path = name_of_pn_file()) != NULL) { - (void) unlink(path); - (void) free(path); - } -} - -static void -write_pseudonym(esp, inp, len, id) -eap_state *esp; -u_char *inp; -int len, id; -{ - u_char val; - u_char *datp, *digp; - SHA1_CTX ctxt; - u_char dig[SHA_DIGESTSIZE]; - int dsize, fd, olen = len; - - /* - * Do the decoding by working backwards. This eliminates the need - * to save the decoded output in a separate buffer. - */ - val = id; - while (len > 0) { - if ((dsize = len % SHA_DIGESTSIZE) == 0) - dsize = SHA_DIGESTSIZE; - len -= dsize; - datp = inp + len; - SHA1Init(&ctxt); - SHA1Update(&ctxt, &val, 1); - SHA1Update(&ctxt, pcb->eap.es_client.ea_skey, SESSION_KEY_LEN); - if (len > 0) { - SHA1Update(&ctxt, datp, SHA_DIGESTSIZE); - } else { - SHA1Update(&ctxt, pcb->eap.es_client.ea_name, - pcb->eap.es_client.ea_namelen); - } - SHA1Final(dig, &ctxt); - for (digp = dig; digp < dig + SHA_DIGESTSIZE; digp++) - *datp++ ^= *digp; - } - - /* Now check that the result is sane */ - if (olen <= 0 || *inp + 1 > olen) { - ppp_dbglog("EAP: decoded pseudonym is unusable <%.*B>", olen, inp); - return; - } - - /* Save it away */ - fd = open_pn_file(O_WRONLY | O_CREAT | O_TRUNC); - if (fd < 0) { - ppp_dbglog("EAP: error saving pseudonym: %m"); - return; - } - len = write(fd, inp + 1, *inp); - if (close(fd) != -1 && len == *inp) { - ppp_dbglog("EAP: saved pseudonym"); - pcb->eap.es_usedpseudo = 0; - } else { - ppp_dbglog("EAP: failed to save pseudonym"); - remove_pn_file(); - } -} -#endif /* USE_SRP */ - -/* - * eap_request - Receive EAP Request message (client mode). - */ -static void eap_request(ppp_pcb *pcb, u_char *inp, int id, int len) { - u_char typenum; - u_char vallen; - int secret_len; - char secret[MAXSECRETLEN]; - char rhostname[MAXNAMELEN]; - lwip_md5_context mdContext; - u_char hash[MD5_SIGNATURE_SIZE]; -#ifdef USE_SRP - struct t_client *tc; - struct t_num sval, gval, Nval, *Ap, Bval; - u_char vals[2]; - SHA1_CTX ctxt; - u_char dig[SHA_DIGESTSIZE]; - int fd; -#endif /* USE_SRP */ - - /* - * Note: we update es_client.ea_id *only if* a Response - * message is being generated. Otherwise, we leave it the - * same for duplicate detection purposes. - */ - - pcb->eap.es_client.ea_requests++; - if (pcb->settings.eap_allow_req != 0 && - pcb->eap.es_client.ea_requests > pcb->settings.eap_allow_req) { - ppp_info("EAP: received too many Request messages"); - if (pcb->settings.eap_req_time > 0) { - UNTIMEOUT(eap_client_timeout, pcb); - } - auth_withpeer_fail(pcb, PPP_EAP); - return; - } - - if (len <= 0) { - ppp_error("EAP: empty Request message discarded"); - return; - } - - GETCHAR(typenum, inp); - len--; - - switch (typenum) { - case EAPT_IDENTITY: - if (len > 0) - ppp_info("EAP: Identity prompt \"%.*q\"", len, inp); -#ifdef USE_SRP - if (pcb->eap.es_usepseudo && - (pcb->eap.es_usedpseudo == 0 || - (pcb->eap.es_usedpseudo == 1 && - id == pcb->eap.es_client.ea_id))) { - pcb->eap.es_usedpseudo = 1; - /* Try to get a pseudonym */ - if ((fd = open_pn_file(O_RDONLY)) >= 0) { - strcpy(rhostname, SRP_PSEUDO_ID); - len = read(fd, rhostname + SRP_PSEUDO_LEN, - sizeof (rhostname) - SRP_PSEUDO_LEN); - /* XXX NAI unsupported */ - if (len > 0) { - eap_send_response(pcb, id, typenum, - rhostname, len + SRP_PSEUDO_LEN); - } - (void) close(fd); - if (len > 0) - break; - } - } - /* Stop using pseudonym now. */ - if (pcb->eap.es_usepseudo && pcb->eap.es_usedpseudo != 2) { - remove_pn_file(); - pcb->eap.es_usedpseudo = 2; - } -#endif /* USE_SRP */ - eap_send_response(pcb, id, typenum, (const u_char*)pcb->eap.es_client.ea_name, - pcb->eap.es_client.ea_namelen); - break; - - case EAPT_NOTIFICATION: - if (len > 0) - ppp_info("EAP: Notification \"%.*q\"", len, inp); - eap_send_response(pcb, id, typenum, NULL, 0); - break; - - case EAPT_NAK: - /* - * Avoid the temptation to send Response Nak in reply - * to Request Nak here. It can only lead to trouble. - */ - ppp_warn("EAP: unexpected Nak in Request; ignored"); - /* Return because we're waiting for something real. */ - return; - - case EAPT_MD5CHAP: - if (len < 1) { - ppp_error("EAP: received MD5-Challenge with no data"); - /* Bogus request; wait for something real. */ - return; - } - GETCHAR(vallen, inp); - len--; - if (vallen < 8 || vallen > len) { - ppp_error("EAP: MD5-Challenge with bad length %d (8..%d)", - vallen, len); - /* Try something better. */ - eap_send_nak(pcb, id, EAPT_SRP); - break; - } - - /* Not so likely to happen. */ - if (vallen >= len + sizeof (rhostname)) { - ppp_dbglog("EAP: trimming really long peer name down"); - MEMCPY(rhostname, inp + vallen, sizeof (rhostname) - 1); - rhostname[sizeof (rhostname) - 1] = '\0'; - } else { - MEMCPY(rhostname, inp + vallen, len - vallen); - rhostname[len - vallen] = '\0'; - } - -#if PPP_REMOTENAME - /* In case the remote doesn't give us his name. */ - if (pcb->settings.explicit_remote || - (pcb->settings.remote_name[0] != '\0' && vallen == len)) - strlcpy(rhostname, pcb->settings.remote_name, sizeof (rhostname)); -#endif /* PPP_REMOTENAME */ - - /* - * Get the secret for authenticating ourselves with - * the specified host. - */ - if (!get_secret(pcb, pcb->eap.es_client.ea_name, - rhostname, secret, &secret_len, 0)) { - ppp_dbglog("EAP: no MD5 secret for auth to %q", rhostname); - eap_send_nak(pcb, id, EAPT_SRP); - break; - } - lwip_md5_init(&mdContext); - lwip_md5_starts(&mdContext); - typenum = id; - lwip_md5_update(&mdContext, &typenum, 1); - lwip_md5_update(&mdContext, (u_char *)secret, secret_len); - BZERO(secret, sizeof (secret)); - lwip_md5_update(&mdContext, inp, vallen); - lwip_md5_finish(&mdContext, hash); - lwip_md5_free(&mdContext); - eap_chap_response(pcb, id, hash, pcb->eap.es_client.ea_name, - pcb->eap.es_client.ea_namelen); - break; - -#ifdef USE_SRP - case EAPT_SRP: - if (len < 1) { - ppp_error("EAP: received empty SRP Request"); - /* Bogus request; wait for something real. */ - return; - } - - /* Get subtype */ - GETCHAR(vallen, inp); - len--; - switch (vallen) { - case EAPSRP_CHALLENGE: - tc = NULL; - if (pcb->eap.es_client.ea_session != NULL) { - tc = (struct t_client *)pcb->eap.es_client. - ea_session; - /* - * If this is a new challenge, then start - * over with a new client session context. - * Otherwise, just resend last response. - */ - if (id != pcb->eap.es_client.ea_id) { - t_clientclose(tc); - pcb->eap.es_client.ea_session = NULL; - tc = NULL; - } - } - /* No session key just yet */ - pcb->eap.es_client.ea_skey = NULL; - if (tc == NULL) { - int rhostnamelen; - - GETCHAR(vallen, inp); - len--; - if (vallen >= len) { - ppp_error("EAP: badly-formed SRP Challenge" - " (name)"); - /* Ignore badly-formed messages */ - return; - } - MEMCPY(rhostname, inp, vallen); - rhostname[vallen] = '\0'; - INCPTR(vallen, inp); - len -= vallen; - - /* - * In case the remote doesn't give us his name, - * use configured name. - */ - if (explicit_remote || - (remote_name[0] != '\0' && vallen == 0)) { - strlcpy(rhostname, remote_name, - sizeof (rhostname)); - } - - rhostnamelen = (int)strlen(rhostname); - if (rhostnamelen > MAXNAMELEN) { - rhostnamelen = MAXNAMELEN; - } - MEMCPY(pcb->eap.es_client.ea_peer, rhostname, rhostnamelen); - pcb->eap.es_client.ea_peer[rhostnamelen] = '\0'; - pcb->eap.es_client.ea_peerlen = rhostnamelen; - - GETCHAR(vallen, inp); - len--; - if (vallen >= len) { - ppp_error("EAP: badly-formed SRP Challenge" - " (s)"); - /* Ignore badly-formed messages */ - return; - } - sval.data = inp; - sval.len = vallen; - INCPTR(vallen, inp); - len -= vallen; - - GETCHAR(vallen, inp); - len--; - if (vallen > len) { - ppp_error("EAP: badly-formed SRP Challenge" - " (g)"); - /* Ignore badly-formed messages */ - return; - } - /* If no generator present, then use value 2 */ - if (vallen == 0) { - gval.data = (u_char *)"\002"; - gval.len = 1; - } else { - gval.data = inp; - gval.len = vallen; - } - INCPTR(vallen, inp); - len -= vallen; - - /* - * If no modulus present, then use well-known - * value. - */ - if (len == 0) { - Nval.data = (u_char *)wkmodulus; - Nval.len = sizeof (wkmodulus); - } else { - Nval.data = inp; - Nval.len = len; - } - tc = t_clientopen(pcb->eap.es_client.ea_name, - &Nval, &gval, &sval); - if (tc == NULL) { - eap_send_nak(pcb, id, EAPT_MD5CHAP); - break; - } - pcb->eap.es_client.ea_session = (void *)tc; - - /* Add Challenge ID & type to verifier */ - vals[0] = id; - vals[1] = EAPT_SRP; - t_clientaddexdata(tc, vals, 2); - } - Ap = t_clientgenexp(tc); - eap_srp_response(esp, id, EAPSRP_CKEY, Ap->data, - Ap->len); - break; - - case EAPSRP_SKEY: - tc = (struct t_client *)pcb->eap.es_client.ea_session; - if (tc == NULL) { - ppp_warn("EAP: peer sent Subtype 2 without 1"); - eap_send_nak(pcb, id, EAPT_MD5CHAP); - break; - } - if (pcb->eap.es_client.ea_skey != NULL) { - /* - * ID number should not change here. Warn - * if it does (but otherwise ignore). - */ - if (id != pcb->eap.es_client.ea_id) { - ppp_warn("EAP: ID changed from %d to %d " - "in SRP Subtype 2 rexmit", - pcb->eap.es_client.ea_id, id); - } - } else { - if (get_srp_secret(pcb->eap.es_unit, - pcb->eap.es_client.ea_name, - pcb->eap.es_client.ea_peer, secret, 0) == 0) { - /* - * Can't work with this peer because - * the secret is missing. Just give - * up. - */ - eap_send_nak(pcb, id, EAPT_MD5CHAP); - break; - } - Bval.data = inp; - Bval.len = len; - t_clientpasswd(tc, secret); - BZERO(secret, sizeof (secret)); - pcb->eap.es_client.ea_skey = - t_clientgetkey(tc, &Bval); - if (pcb->eap.es_client.ea_skey == NULL) { - /* Server is rogue; stop now */ - ppp_error("EAP: SRP server is rogue"); - goto client_failure; - } - } - eap_srpval_response(esp, id, SRPVAL_EBIT, - t_clientresponse(tc)); - break; - - case EAPSRP_SVALIDATOR: - tc = (struct t_client *)pcb->eap.es_client.ea_session; - if (tc == NULL || pcb->eap.es_client.ea_skey == NULL) { - ppp_warn("EAP: peer sent Subtype 3 without 1/2"); - eap_send_nak(pcb, id, EAPT_MD5CHAP); - break; - } - /* - * If we're already open, then this ought to be a - * duplicate. Otherwise, check that the server is - * who we think it is. - */ - if (pcb->eap.es_client.ea_state == eapOpen) { - if (id != pcb->eap.es_client.ea_id) { - ppp_warn("EAP: ID changed from %d to %d " - "in SRP Subtype 3 rexmit", - pcb->eap.es_client.ea_id, id); - } - } else { - len -= sizeof (u32_t) + SHA_DIGESTSIZE; - if (len < 0 || t_clientverify(tc, inp + - sizeof (u32_t)) != 0) { - ppp_error("EAP: SRP server verification " - "failed"); - goto client_failure; - } - GETLONG(pcb->eap.es_client.ea_keyflags, inp); - /* Save pseudonym if user wants it. */ - if (len > 0 && pcb->eap.es_usepseudo) { - INCPTR(SHA_DIGESTSIZE, inp); - write_pseudonym(esp, inp, len, id); - } - } - /* - * We've verified our peer. We're now mostly done, - * except for waiting on the regular EAP Success - * message. - */ - eap_srp_response(esp, id, EAPSRP_ACK, NULL, 0); - break; - - case EAPSRP_LWRECHALLENGE: - if (len < 4) { - ppp_warn("EAP: malformed Lightweight rechallenge"); - return; - } - SHA1Init(&ctxt); - vals[0] = id; - SHA1Update(&ctxt, vals, 1); - SHA1Update(&ctxt, pcb->eap.es_client.ea_skey, - SESSION_KEY_LEN); - SHA1Update(&ctxt, inp, len); - SHA1Update(&ctxt, pcb->eap.es_client.ea_name, - pcb->eap.es_client.ea_namelen); - SHA1Final(dig, &ctxt); - eap_srp_response(esp, id, EAPSRP_LWRECHALLENGE, dig, - SHA_DIGESTSIZE); - break; - - default: - ppp_error("EAP: unknown SRP Subtype %d", vallen); - eap_send_nak(pcb, id, EAPT_MD5CHAP); - break; - } - break; -#endif /* USE_SRP */ - - default: - ppp_info("EAP: unknown authentication type %d; Naking", typenum); - eap_send_nak(pcb, id, EAPT_SRP); - break; - } - - if (pcb->settings.eap_req_time > 0) { - UNTIMEOUT(eap_client_timeout, pcb); - TIMEOUT(eap_client_timeout, pcb, - pcb->settings.eap_req_time); - } - return; - -#ifdef USE_SRP -client_failure: - pcb->eap.es_client.ea_state = eapBadAuth; - if (pcb->settings.eap_req_time > 0) { - UNTIMEOUT(eap_client_timeout, (void *)esp); - } - pcb->eap.es_client.ea_session = NULL; - t_clientclose(tc); - auth_withpeer_fail(pcb, PPP_EAP); -#endif /* USE_SRP */ -} - -#if PPP_SERVER -/* - * eap_response - Receive EAP Response message (server mode). - */ -static void eap_response(ppp_pcb *pcb, u_char *inp, int id, int len) { - u_char typenum; - u_char vallen; - int secret_len; - char secret[MAXSECRETLEN]; - char rhostname[MAXNAMELEN]; - lwip_md5_context mdContext; - u_char hash[MD5_SIGNATURE_SIZE]; -#ifdef USE_SRP - struct t_server *ts; - struct t_num A; - SHA1_CTX ctxt; - u_char dig[SHA_DIGESTSIZE]; -#endif /* USE_SRP */ - - if (pcb->eap.es_server.ea_id != id) { - ppp_dbglog("EAP: discarding Response %d; expected ID %d", id, - pcb->eap.es_server.ea_id); - return; - } - - pcb->eap.es_server.ea_responses++; - - if (len <= 0) { - ppp_error("EAP: empty Response message discarded"); - return; - } - - GETCHAR(typenum, inp); - len--; - - switch (typenum) { - case EAPT_IDENTITY: - if (pcb->eap.es_server.ea_state != eapIdentify) { - ppp_dbglog("EAP discarding unwanted Identify \"%.q\"", len, - inp); - break; - } - ppp_info("EAP: unauthenticated peer name \"%.*q\"", len, inp); - if (len > MAXNAMELEN) { - len = MAXNAMELEN; - } - MEMCPY(pcb->eap.es_server.ea_peer, inp, len); - pcb->eap.es_server.ea_peer[len] = '\0'; - pcb->eap.es_server.ea_peerlen = len; - eap_figure_next_state(pcb, 0); - break; - - case EAPT_NOTIFICATION: - ppp_dbglog("EAP unexpected Notification; response discarded"); - break; - - case EAPT_NAK: - if (len < 1) { - ppp_info("EAP: Nak Response with no suggested protocol"); - eap_figure_next_state(pcb, 1); - break; - } - - GETCHAR(vallen, inp); - len--; - - if ( -#if PPP_REMOTENAME - !pcb->explicit_remote && -#endif /* PPP_REMOTENAME */ - pcb->eap.es_server.ea_state == eapIdentify){ - /* Peer cannot Nak Identify Request */ - eap_figure_next_state(pcb, 1); - break; - } - - switch (vallen) { - case EAPT_SRP: - /* Run through SRP validator selection again. */ - pcb->eap.es_server.ea_state = eapIdentify; - eap_figure_next_state(pcb, 0); - break; - - case EAPT_MD5CHAP: - pcb->eap.es_server.ea_state = eapMD5Chall; - break; - - default: - ppp_dbglog("EAP: peer requesting unknown Type %d", vallen); - switch (pcb->eap.es_server.ea_state) { - case eapSRP1: - case eapSRP2: - case eapSRP3: - pcb->eap.es_server.ea_state = eapMD5Chall; - break; - case eapMD5Chall: - case eapSRP4: - pcb->eap.es_server.ea_state = eapIdentify; - eap_figure_next_state(pcb, 0); - break; - default: - break; - } - break; - } - break; - - case EAPT_MD5CHAP: - if (pcb->eap.es_server.ea_state != eapMD5Chall) { - ppp_error("EAP: unexpected MD5-Response"); - eap_figure_next_state(pcb, 1); - break; - } - if (len < 1) { - ppp_error("EAP: received MD5-Response with no data"); - eap_figure_next_state(pcb, 1); - break; - } - GETCHAR(vallen, inp); - len--; - if (vallen != 16 || vallen > len) { - ppp_error("EAP: MD5-Response with bad length %d", vallen); - eap_figure_next_state(pcb, 1); - break; - } - - /* Not so likely to happen. */ - if (vallen >= len + sizeof (rhostname)) { - ppp_dbglog("EAP: trimming really long peer name down"); - MEMCPY(rhostname, inp + vallen, sizeof (rhostname) - 1); - rhostname[sizeof (rhostname) - 1] = '\0'; - } else { - MEMCPY(rhostname, inp + vallen, len - vallen); - rhostname[len - vallen] = '\0'; - } - -#if PPP_REMOTENAME - /* In case the remote doesn't give us his name. */ - if (explicit_remote || - (remote_name[0] != '\0' && vallen == len)) - strlcpy(rhostname, remote_name, sizeof (rhostname)); -#endif /* PPP_REMOTENAME */ - - /* - * Get the secret for authenticating the specified - * host. - */ - if (!get_secret(pcb, rhostname, - pcb->eap.es_server.ea_name, secret, &secret_len, 1)) { - ppp_dbglog("EAP: no MD5 secret for auth of %q", rhostname); - eap_send_failure(pcb); - break; - } - lwip_md5_init(&mdContext); - lwip_md5_starts(&mdContext); - lwip_md5_update(&mdContext, &pcb->eap.es_server.ea_id, 1); - lwip_md5_update(&mdContext, (u_char *)secret, secret_len); - BZERO(secret, sizeof (secret)); - lwip_md5_update(&mdContext, pcb->eap.es_challenge, pcb->eap.es_challen); - lwip_md5_finish(&mdContext, hash); - lwip_md5_free(&mdContext); - if (BCMP(hash, inp, MD5_SIGNATURE_SIZE) != 0) { - eap_send_failure(pcb); - break; - } - pcb->eap.es_server.ea_type = EAPT_MD5CHAP; - eap_send_success(pcb); - eap_figure_next_state(pcb, 0); - if (pcb->eap.es_rechallenge != 0) - TIMEOUT(eap_rechallenge, pcb, pcb->eap.es_rechallenge); - break; - -#ifdef USE_SRP - case EAPT_SRP: - if (len < 1) { - ppp_error("EAP: empty SRP Response"); - eap_figure_next_state(pcb, 1); - break; - } - GETCHAR(typenum, inp); - len--; - switch (typenum) { - case EAPSRP_CKEY: - if (pcb->eap.es_server.ea_state != eapSRP1) { - ppp_error("EAP: unexpected SRP Subtype 1 Response"); - eap_figure_next_state(pcb, 1); - break; - } - A.data = inp; - A.len = len; - ts = (struct t_server *)pcb->eap.es_server.ea_session; - assert(ts != NULL); - pcb->eap.es_server.ea_skey = t_servergetkey(ts, &A); - if (pcb->eap.es_server.ea_skey == NULL) { - /* Client's A value is bogus; terminate now */ - ppp_error("EAP: bogus A value from client"); - eap_send_failure(pcb); - } else { - eap_figure_next_state(pcb, 0); - } - break; - - case EAPSRP_CVALIDATOR: - if (pcb->eap.es_server.ea_state != eapSRP2) { - ppp_error("EAP: unexpected SRP Subtype 2 Response"); - eap_figure_next_state(pcb, 1); - break; - } - if (len < sizeof (u32_t) + SHA_DIGESTSIZE) { - ppp_error("EAP: M1 length %d < %d", len, - sizeof (u32_t) + SHA_DIGESTSIZE); - eap_figure_next_state(pcb, 1); - break; - } - GETLONG(pcb->eap.es_server.ea_keyflags, inp); - ts = (struct t_server *)pcb->eap.es_server.ea_session; - assert(ts != NULL); - if (t_serververify(ts, inp)) { - ppp_info("EAP: unable to validate client identity"); - eap_send_failure(pcb); - break; - } - eap_figure_next_state(pcb, 0); - break; - - case EAPSRP_ACK: - if (pcb->eap.es_server.ea_state != eapSRP3) { - ppp_error("EAP: unexpected SRP Subtype 3 Response"); - eap_send_failure(esp); - break; - } - pcb->eap.es_server.ea_type = EAPT_SRP; - eap_send_success(pcb, esp); - eap_figure_next_state(pcb, 0); - if (pcb->eap.es_rechallenge != 0) - TIMEOUT(eap_rechallenge, pcb, - pcb->eap.es_rechallenge); - if (pcb->eap.es_lwrechallenge != 0) - TIMEOUT(srp_lwrechallenge, pcb, - pcb->eap.es_lwrechallenge); - break; - - case EAPSRP_LWRECHALLENGE: - if (pcb->eap.es_server.ea_state != eapSRP4) { - ppp_info("EAP: unexpected SRP Subtype 4 Response"); - return; - } - if (len != SHA_DIGESTSIZE) { - ppp_error("EAP: bad Lightweight rechallenge " - "response"); - return; - } - SHA1Init(&ctxt); - vallen = id; - SHA1Update(&ctxt, &vallen, 1); - SHA1Update(&ctxt, pcb->eap.es_server.ea_skey, - SESSION_KEY_LEN); - SHA1Update(&ctxt, pcb->eap.es_challenge, pcb->eap.es_challen); - SHA1Update(&ctxt, pcb->eap.es_server.ea_peer, - pcb->eap.es_server.ea_peerlen); - SHA1Final(dig, &ctxt); - if (BCMP(dig, inp, SHA_DIGESTSIZE) != 0) { - ppp_error("EAP: failed Lightweight rechallenge"); - eap_send_failure(pcb); - break; - } - pcb->eap.es_server.ea_state = eapOpen; - if (pcb->eap.es_lwrechallenge != 0) - TIMEOUT(srp_lwrechallenge, esp, - pcb->eap.es_lwrechallenge); - break; - } - break; -#endif /* USE_SRP */ - - default: - /* This can't happen. */ - ppp_error("EAP: unknown Response type %d; ignored", typenum); - return; - } - - if (pcb->settings.eap_timeout_time > 0) { - UNTIMEOUT(eap_server_timeout, pcb); - } - - if (pcb->eap.es_server.ea_state != eapBadAuth && - pcb->eap.es_server.ea_state != eapOpen) { - pcb->eap.es_server.ea_id++; - eap_send_request(pcb); - } -} -#endif /* PPP_SERVER */ - -/* - * eap_success - Receive EAP Success message (client mode). - */ -static void eap_success(ppp_pcb *pcb, u_char *inp, int id, int len) { - LWIP_UNUSED_ARG(id); - - if (pcb->eap.es_client.ea_state != eapOpen && !eap_client_active(pcb)) { - ppp_dbglog("EAP unexpected success message in state %s (%d)", - eap_state_name(pcb->eap.es_client.ea_state), - pcb->eap.es_client.ea_state); - return; - } - - if (pcb->settings.eap_req_time > 0) { - UNTIMEOUT(eap_client_timeout, pcb); - } - - if (len > 0) { - /* This is odd. The spec doesn't allow for this. */ - PRINTMSG(inp, len); - } - - pcb->eap.es_client.ea_state = eapOpen; - auth_withpeer_success(pcb, PPP_EAP, 0); -} - -/* - * eap_failure - Receive EAP Failure message (client mode). - */ -static void eap_failure(ppp_pcb *pcb, u_char *inp, int id, int len) { - LWIP_UNUSED_ARG(id); - - if (!eap_client_active(pcb)) { - ppp_dbglog("EAP unexpected failure message in state %s (%d)", - eap_state_name(pcb->eap.es_client.ea_state), - pcb->eap.es_client.ea_state); - } - - if (pcb->settings.eap_req_time > 0) { - UNTIMEOUT(eap_client_timeout, pcb); - } - - if (len > 0) { - /* This is odd. The spec doesn't allow for this. */ - PRINTMSG(inp, len); - } - - pcb->eap.es_client.ea_state = eapBadAuth; - - ppp_error("EAP: peer reports authentication failure"); - auth_withpeer_fail(pcb, PPP_EAP); -} - -/* - * eap_input - Handle received EAP message. - */ -static void eap_input(ppp_pcb *pcb, u_char *inp, int inlen) { - u_char code, id; - int len; - - /* - * Parse header (code, id and length). If packet too short, - * drop it. - */ - if (inlen < EAP_HEADERLEN) { - ppp_error("EAP: packet too short: %d < %d", inlen, EAP_HEADERLEN); - return; - } - GETCHAR(code, inp); - GETCHAR(id, inp); - GETSHORT(len, inp); - if (len < EAP_HEADERLEN || len > inlen) { - ppp_error("EAP: packet has illegal length field %d (%d..%d)", len, - EAP_HEADERLEN, inlen); - return; - } - len -= EAP_HEADERLEN; - - /* Dispatch based on message code */ - switch (code) { - case EAP_REQUEST: - eap_request(pcb, inp, id, len); - break; - -#if PPP_SERVER - case EAP_RESPONSE: - eap_response(pcb, inp, id, len); - break; -#endif /* PPP_SERVER */ - - case EAP_SUCCESS: - eap_success(pcb, inp, id, len); - break; - - case EAP_FAILURE: - eap_failure(pcb, inp, id, len); - break; - - default: /* XXX Need code reject */ - /* Note: it's not legal to send EAP Nak here. */ - ppp_warn("EAP: unknown code %d received", code); - break; - } -} - -#if PRINTPKT_SUPPORT -/* - * eap_printpkt - print the contents of an EAP packet. - */ -static const char* const eap_codenames[] = { - "Request", "Response", "Success", "Failure" -}; - -static const char* const eap_typenames[] = { - "Identity", "Notification", "Nak", "MD5-Challenge", - "OTP", "Generic-Token", NULL, NULL, - "RSA", "DSS", "KEA", "KEA-Validate", - "TLS", "Defender", "Windows 2000", "Arcot", - "Cisco", "Nokia", "SRP" -}; - -static int eap_printpkt(const u_char *inp, int inlen, void (*printer) (void *, const char *, ...), void *arg) { - int code, id, len, rtype, vallen; - const u_char *pstart; - u32_t uval; - - if (inlen < EAP_HEADERLEN) - return (0); - pstart = inp; - GETCHAR(code, inp); - GETCHAR(id, inp); - GETSHORT(len, inp); - if (len < EAP_HEADERLEN || len > inlen) - return (0); - - if (code >= 1 && code <= (int)LWIP_ARRAYSIZE(eap_codenames)) - printer(arg, " %s", eap_codenames[code-1]); - else - printer(arg, " code=0x%x", code); - printer(arg, " id=0x%x", id); - len -= EAP_HEADERLEN; - switch (code) { - case EAP_REQUEST: - if (len < 1) { - printer(arg, " "); - break; - } - GETCHAR(rtype, inp); - len--; - if (rtype >= 1 && rtype <= (int)LWIP_ARRAYSIZE(eap_typenames)) - printer(arg, " %s", eap_typenames[rtype-1]); - else - printer(arg, " type=0x%x", rtype); - switch (rtype) { - case EAPT_IDENTITY: - case EAPT_NOTIFICATION: - if (len > 0) { - printer(arg, " "); - INCPTR(len, inp); - len = 0; - } else { - printer(arg, " "); - } - break; - - case EAPT_MD5CHAP: - if (len <= 0) - break; - GETCHAR(vallen, inp); - len--; - if (vallen > len) - goto truncated; - printer(arg, " ", vallen, inp); - INCPTR(vallen, inp); - len -= vallen; - if (len > 0) { - printer(arg, " "); - INCPTR(len, inp); - len = 0; - } else { - printer(arg, " "); - } - break; - - case EAPT_SRP: - if (len < 3) - goto truncated; - GETCHAR(vallen, inp); - len--; - printer(arg, "-%d", vallen); - switch (vallen) { - case EAPSRP_CHALLENGE: - GETCHAR(vallen, inp); - len--; - if (vallen >= len) - goto truncated; - if (vallen > 0) { - printer(arg, " "); - } else { - printer(arg, " "); - } - INCPTR(vallen, inp); - len -= vallen; - GETCHAR(vallen, inp); - len--; - if (vallen >= len) - goto truncated; - printer(arg, " ", vallen, inp); - INCPTR(vallen, inp); - len -= vallen; - GETCHAR(vallen, inp); - len--; - if (vallen > len) - goto truncated; - if (vallen == 0) { - printer(arg, " "); - } else { - printer(arg, " ", vallen, inp); - } - INCPTR(vallen, inp); - len -= vallen; - if (len == 0) { - printer(arg, " "); - } else { - printer(arg, " ", len, inp); - INCPTR(len, inp); - len = 0; - } - break; - - case EAPSRP_SKEY: - printer(arg, " ", len, inp); - INCPTR(len, inp); - len = 0; - break; - - case EAPSRP_SVALIDATOR: - if (len < (int)sizeof (u32_t)) - break; - GETLONG(uval, inp); - len -= sizeof (u32_t); - if (uval & SRPVAL_EBIT) { - printer(arg, " E"); - uval &= ~SRPVAL_EBIT; - } - if (uval != 0) { - printer(arg, " f<%X>", uval); - } - if ((vallen = len) > SHA_DIGESTSIZE) - vallen = SHA_DIGESTSIZE; - printer(arg, " ", len, inp, - len < SHA_DIGESTSIZE ? "?" : ""); - INCPTR(vallen, inp); - len -= vallen; - if (len > 0) { - printer(arg, " ", len, inp); - INCPTR(len, inp); - len = 0; - } - break; - - case EAPSRP_LWRECHALLENGE: - printer(arg, " ", len, inp); - INCPTR(len, inp); - len = 0; - break; - default: - break; - } - break; - default: - break; - } - break; - - case EAP_RESPONSE: - if (len < 1) - break; - GETCHAR(rtype, inp); - len--; - if (rtype >= 1 && rtype <= (int)LWIP_ARRAYSIZE(eap_typenames)) - printer(arg, " %s", eap_typenames[rtype-1]); - else - printer(arg, " type=0x%x", rtype); - switch (rtype) { - case EAPT_IDENTITY: - if (len > 0) { - printer(arg, " "); - INCPTR(len, inp); - len = 0; - } - break; - - case EAPT_NAK: - if (len <= 0) { - printer(arg, " "); - break; - } - GETCHAR(rtype, inp); - len--; - printer(arg, " = 1 && rtype < (int)LWIP_ARRAYSIZE(eap_typenames)) - printer(arg, " (%s)", eap_typenames[rtype-1]); - printer(arg, ">"); - break; - - case EAPT_MD5CHAP: - if (len <= 0) { - printer(arg, " "); - break; - } - GETCHAR(vallen, inp); - len--; - if (vallen > len) - goto truncated; - printer(arg, " ", vallen, inp); - INCPTR(vallen, inp); - len -= vallen; - if (len > 0) { - printer(arg, " "); - INCPTR(len, inp); - len = 0; - } else { - printer(arg, " "); - } - break; - - case EAPT_SRP: - if (len < 1) - goto truncated; - GETCHAR(vallen, inp); - len--; - printer(arg, "-%d", vallen); - switch (vallen) { - case EAPSRP_CKEY: - printer(arg, " ", len, inp); - INCPTR(len, inp); - len = 0; - break; - - case EAPSRP_CVALIDATOR: - if (len < (int)sizeof (u32_t)) - break; - GETLONG(uval, inp); - len -= sizeof (u32_t); - if (uval & SRPVAL_EBIT) { - printer(arg, " E"); - uval &= ~SRPVAL_EBIT; - } - if (uval != 0) { - printer(arg, " f<%X>", uval); - } - printer(arg, " ", len, inp, - len == SHA_DIGESTSIZE ? "" : "?"); - INCPTR(len, inp); - len = 0; - break; - - case EAPSRP_ACK: - break; - - case EAPSRP_LWRECHALLENGE: - printer(arg, " ", len, inp, - len == SHA_DIGESTSIZE ? "" : "?"); - if ((vallen = len) > SHA_DIGESTSIZE) - vallen = SHA_DIGESTSIZE; - INCPTR(vallen, inp); - len -= vallen; - break; - default: - break; - } - break; - default: - break; - } - break; - - case EAP_SUCCESS: /* No payload expected for these! */ - case EAP_FAILURE: - default: - break; - - truncated: - printer(arg, " "); - break; - } - - if (len > 8) - printer(arg, "%8B...", inp); - else if (len > 0) - printer(arg, "%.*B", len, inp); - INCPTR(len, inp); - - return (inp - pstart); -} -#endif /* PRINTPKT_SUPPORT */ - -#endif /* PPP_SUPPORT && EAP_SUPPORT */ diff --git a/third_party/lwip/repo/lwip/src/netif/ppp/ecp.c b/third_party/lwip/repo/lwip/src/netif/ppp/ecp.c deleted file mode 100644 index 4d84f609311c65..00000000000000 --- a/third_party/lwip/repo/lwip/src/netif/ppp/ecp.c +++ /dev/null @@ -1,191 +0,0 @@ -/* - * ecp.c - PPP Encryption Control Protocol. - * - * Copyright (c) 2002 Google, Inc. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name(s) of the authors of this software must not be used to - * endorse or promote products derived from this software without - * prior written permission. - * - * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * Derived from ccp.c, which is: - * - * Copyright (c) 1994-2002 Paul Mackerras. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. The name(s) of the authors of this software must not be used to - * endorse or promote products derived from this software without - * prior written permission. - * - * 3. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Paul Mackerras - * ". - * - * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT && ECP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#include - -#include "netif/ppp/ppp_impl.h" - -#include "netif/ppp/fsm.h" -#include "netif/ppp/ecp.h" - -#if PPP_OPTIONS -static option_t ecp_option_list[] = { - { "noecp", o_bool, &ecp_protent.enabled_flag, - "Disable ECP negotiation" }, - { "-ecp", o_bool, &ecp_protent.enabled_flag, - "Disable ECP negotiation", OPT_ALIAS }, - - { NULL } -}; -#endif /* PPP_OPTIONS */ - -/* - * Protocol entry points from main code. - */ -static void ecp_init (int unit); -/* -static void ecp_open (int unit); -static void ecp_close (int unit, char *); -static void ecp_lowerup (int unit); -static void ecp_lowerdown (int); -static void ecp_input (int unit, u_char *pkt, int len); -static void ecp_protrej (int unit); -*/ -#if PRINTPKT_SUPPORT -static int ecp_printpkt (const u_char *pkt, int len, - void (*printer) (void *, char *, ...), - void *arg); -#endif /* PRINTPKT_SUPPORT */ -/* -static void ecp_datainput (int unit, u_char *pkt, int len); -*/ - -const struct protent ecp_protent = { - PPP_ECP, - ecp_init, - NULL, /* ecp_input, */ - NULL, /* ecp_protrej, */ - NULL, /* ecp_lowerup, */ - NULL, /* ecp_lowerdown, */ - NULL, /* ecp_open, */ - NULL, /* ecp_close, */ -#if PRINTPKT_SUPPORT - ecp_printpkt, -#endif /* PRINTPKT_SUPPORT */ -#if PPP_DATAINPUT - NULL, /* ecp_datainput, */ -#endif /* PPP_DATAINPUT */ -#if PRINTPKT_SUPPORT - "ECP", - "Encrypted", -#endif /* PRINTPKT_SUPPORT */ -#if PPP_OPTIONS - ecp_option_list, - NULL, -#endif /* PPP_OPTIONS */ -#if DEMAND_SUPPORT - NULL, - NULL -#endif /* DEMAND_SUPPORT */ -}; - -fsm ecp_fsm[NUM_PPP]; -ecp_options ecp_wantoptions[NUM_PPP]; /* what to request the peer to use */ -ecp_options ecp_gotoptions[NUM_PPP]; /* what the peer agreed to do */ -ecp_options ecp_allowoptions[NUM_PPP]; /* what we'll agree to do */ -ecp_options ecp_hisoptions[NUM_PPP]; /* what we agreed to do */ - -static const fsm_callbacks ecp_callbacks = { - NULL, /* ecp_resetci, */ - NULL, /* ecp_cilen, */ - NULL, /* ecp_addci, */ - NULL, /* ecp_ackci, */ - NULL, /* ecp_nakci, */ - NULL, /* ecp_rejci, */ - NULL, /* ecp_reqci, */ - NULL, /* ecp_up, */ - NULL, /* ecp_down, */ - NULL, - NULL, - NULL, - NULL, - NULL, /* ecp_extcode, */ - "ECP" -}; - -/* - * ecp_init - initialize ECP. - */ -static void -ecp_init(unit) - int unit; -{ - fsm *f = &ecp_fsm[unit]; - - f->unit = unit; - f->protocol = PPP_ECP; - f->callbacks = &ecp_callbacks; - fsm_init(f); - -#if 0 /* Not necessary, everything is cleared in ppp_new() */ - memset(&ecp_wantoptions[unit], 0, sizeof(ecp_options)); - memset(&ecp_gotoptions[unit], 0, sizeof(ecp_options)); - memset(&ecp_allowoptions[unit], 0, sizeof(ecp_options)); - memset(&ecp_hisoptions[unit], 0, sizeof(ecp_options)); -#endif /* 0 */ - -} - - -#if PRINTPKT_SUPPORT -static int -ecp_printpkt(p, plen, printer, arg) - const u_char *p; - int plen; - void (*printer) (void *, char *, ...); - void *arg; -{ - return 0; -} -#endif /* PRINTPKT_SUPPORT */ - -#endif /* PPP_SUPPORT && ECP_SUPPORT */ diff --git a/third_party/lwip/repo/lwip/src/netif/ppp/eui64.c b/third_party/lwip/repo/lwip/src/netif/ppp/eui64.c deleted file mode 100644 index 01493bc1f800d7..00000000000000 --- a/third_party/lwip/repo/lwip/src/netif/ppp/eui64.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * eui64.c - EUI64 routines for IPv6CP. - * - * Copyright (c) 1999 Tommi Komulainen. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name(s) of the authors of this software must not be used to - * endorse or promote products derived from this software without - * prior written permission. - * - * 4. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Tommi Komulainen - * ". - * - * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * $Id: eui64.c,v 1.6 2002/12/04 23:03:32 paulus Exp $ - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT && PPP_IPV6_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#include "netif/ppp/ppp_impl.h" -#include "netif/ppp/eui64.h" - -/* - * eui64_ntoa - Make an ascii representation of an interface identifier - */ -char *eui64_ntoa(eui64_t e) { - static char buf[20]; - - sprintf(buf, "%02x%02x:%02x%02x:%02x%02x:%02x%02x", - e.e8[0], e.e8[1], e.e8[2], e.e8[3], - e.e8[4], e.e8[5], e.e8[6], e.e8[7]); - return buf; -} - -#endif /* PPP_SUPPORT && PPP_IPV6_SUPPORT */ diff --git a/third_party/lwip/repo/lwip/src/netif/ppp/fsm.c b/third_party/lwip/repo/lwip/src/netif/ppp/fsm.c deleted file mode 100644 index 81eba11602ba96..00000000000000 --- a/third_party/lwip/repo/lwip/src/netif/ppp/fsm.c +++ /dev/null @@ -1,799 +0,0 @@ -/* - * fsm.c - {Link, IP} Control Protocol Finite State Machine. - * - * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name "Carnegie Mellon University" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For permission or any legal - * details, please contact - * Office of Technology Transfer - * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu - * - * 4. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Computing Services - * at Carnegie Mellon University (http://www.cmu.edu/computing/)." - * - * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE - * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -/* - * @todo: - * Randomize fsm id on link/init. - * Deal with variable outgoing MTU. - */ - -#if 0 /* UNUSED */ -#include -#include -#include -#endif /* UNUSED */ - -#include "netif/ppp/ppp_impl.h" - -#include "netif/ppp/fsm.h" - -static void fsm_timeout (void *); -static void fsm_rconfreq(fsm *f, u_char id, u_char *inp, int len); -static void fsm_rconfack(fsm *f, int id, u_char *inp, int len); -static void fsm_rconfnakrej(fsm *f, int code, int id, u_char *inp, int len); -static void fsm_rtermreq(fsm *f, int id, u_char *p, int len); -static void fsm_rtermack(fsm *f); -static void fsm_rcoderej(fsm *f, u_char *inp, int len); -static void fsm_sconfreq(fsm *f, int retransmit); - -#define PROTO_NAME(f) ((f)->callbacks->proto_name) - -/* - * fsm_init - Initialize fsm. - * - * Initialize fsm state. - */ -void fsm_init(fsm *f) { - ppp_pcb *pcb = f->pcb; - f->state = PPP_FSM_INITIAL; - f->flags = 0; - f->id = 0; /* XXX Start with random id? */ - f->maxnakloops = pcb->settings.fsm_max_nak_loops; - f->term_reason_len = 0; -} - - -/* - * fsm_lowerup - The lower layer is up. - */ -void fsm_lowerup(fsm *f) { - switch( f->state ){ - case PPP_FSM_INITIAL: - f->state = PPP_FSM_CLOSED; - break; - - case PPP_FSM_STARTING: - if( f->flags & OPT_SILENT ) - f->state = PPP_FSM_STOPPED; - else { - /* Send an initial configure-request */ - fsm_sconfreq(f, 0); - f->state = PPP_FSM_REQSENT; - } - break; - - default: - FSMDEBUG(("%s: Up event in state %d!", PROTO_NAME(f), f->state)); - /* no break */ - } -} - - -/* - * fsm_lowerdown - The lower layer is down. - * - * Cancel all timeouts and inform upper layers. - */ -void fsm_lowerdown(fsm *f) { - switch( f->state ){ - case PPP_FSM_CLOSED: - f->state = PPP_FSM_INITIAL; - break; - - case PPP_FSM_STOPPED: - f->state = PPP_FSM_STARTING; - if( f->callbacks->starting ) - (*f->callbacks->starting)(f); - break; - - case PPP_FSM_CLOSING: - f->state = PPP_FSM_INITIAL; - UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ - break; - - case PPP_FSM_STOPPING: - case PPP_FSM_REQSENT: - case PPP_FSM_ACKRCVD: - case PPP_FSM_ACKSENT: - f->state = PPP_FSM_STARTING; - UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ - break; - - case PPP_FSM_OPENED: - if( f->callbacks->down ) - (*f->callbacks->down)(f); - f->state = PPP_FSM_STARTING; - break; - - default: - FSMDEBUG(("%s: Down event in state %d!", PROTO_NAME(f), f->state)); - /* no break */ - } -} - - -/* - * fsm_open - Link is allowed to come up. - */ -void fsm_open(fsm *f) { - switch( f->state ){ - case PPP_FSM_INITIAL: - f->state = PPP_FSM_STARTING; - if( f->callbacks->starting ) - (*f->callbacks->starting)(f); - break; - - case PPP_FSM_CLOSED: - if( f->flags & OPT_SILENT ) - f->state = PPP_FSM_STOPPED; - else { - /* Send an initial configure-request */ - fsm_sconfreq(f, 0); - f->state = PPP_FSM_REQSENT; - } - break; - - case PPP_FSM_CLOSING: - f->state = PPP_FSM_STOPPING; - /* fall through */ - /* no break */ - case PPP_FSM_STOPPED: - case PPP_FSM_OPENED: - if( f->flags & OPT_RESTART ){ - fsm_lowerdown(f); - fsm_lowerup(f); - } - break; - default: - break; - } -} - -/* - * terminate_layer - Start process of shutting down the FSM - * - * Cancel any timeout running, notify upper layers we're done, and - * send a terminate-request message as configured. - */ -static void terminate_layer(fsm *f, int nextstate) { - ppp_pcb *pcb = f->pcb; - - if( f->state != PPP_FSM_OPENED ) - UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ - else if( f->callbacks->down ) - (*f->callbacks->down)(f); /* Inform upper layers we're down */ - - /* Init restart counter and send Terminate-Request */ - f->retransmits = pcb->settings.fsm_max_term_transmits; - fsm_sdata(f, TERMREQ, f->reqid = ++f->id, - (const u_char *) f->term_reason, f->term_reason_len); - - if (f->retransmits == 0) { - /* - * User asked for no terminate requests at all; just close it. - * We've already fired off one Terminate-Request just to be nice - * to the peer, but we're not going to wait for a reply. - */ - f->state = nextstate == PPP_FSM_CLOSING ? PPP_FSM_CLOSED : PPP_FSM_STOPPED; - if( f->callbacks->finished ) - (*f->callbacks->finished)(f); - return; - } - - TIMEOUT(fsm_timeout, f, pcb->settings.fsm_timeout_time); - --f->retransmits; - - f->state = nextstate; -} - -/* - * fsm_close - Start closing connection. - * - * Cancel timeouts and either initiate close or possibly go directly to - * the PPP_FSM_CLOSED state. - */ -void fsm_close(fsm *f, const char *reason) { - f->term_reason = reason; - f->term_reason_len = (reason == NULL? 0: LWIP_MIN(strlen(reason), 0xFF) ); - switch( f->state ){ - case PPP_FSM_STARTING: - f->state = PPP_FSM_INITIAL; - break; - case PPP_FSM_STOPPED: - f->state = PPP_FSM_CLOSED; - break; - case PPP_FSM_STOPPING: - f->state = PPP_FSM_CLOSING; - break; - - case PPP_FSM_REQSENT: - case PPP_FSM_ACKRCVD: - case PPP_FSM_ACKSENT: - case PPP_FSM_OPENED: - terminate_layer(f, PPP_FSM_CLOSING); - break; - default: - break; - } -} - - -/* - * fsm_timeout - Timeout expired. - */ -static void fsm_timeout(void *arg) { - fsm *f = (fsm *) arg; - ppp_pcb *pcb = f->pcb; - - switch (f->state) { - case PPP_FSM_CLOSING: - case PPP_FSM_STOPPING: - if( f->retransmits <= 0 ){ - /* - * We've waited for an ack long enough. Peer probably heard us. - */ - f->state = (f->state == PPP_FSM_CLOSING)? PPP_FSM_CLOSED: PPP_FSM_STOPPED; - if( f->callbacks->finished ) - (*f->callbacks->finished)(f); - } else { - /* Send Terminate-Request */ - fsm_sdata(f, TERMREQ, f->reqid = ++f->id, - (const u_char *) f->term_reason, f->term_reason_len); - TIMEOUT(fsm_timeout, f, pcb->settings.fsm_timeout_time); - --f->retransmits; - } - break; - - case PPP_FSM_REQSENT: - case PPP_FSM_ACKRCVD: - case PPP_FSM_ACKSENT: - if (f->retransmits <= 0) { - ppp_warn("%s: timeout sending Config-Requests", PROTO_NAME(f)); - f->state = PPP_FSM_STOPPED; - if( (f->flags & OPT_PASSIVE) == 0 && f->callbacks->finished ) - (*f->callbacks->finished)(f); - - } else { - /* Retransmit the configure-request */ - if (f->callbacks->retransmit) - (*f->callbacks->retransmit)(f); - fsm_sconfreq(f, 1); /* Re-send Configure-Request */ - if( f->state == PPP_FSM_ACKRCVD ) - f->state = PPP_FSM_REQSENT; - } - break; - - default: - FSMDEBUG(("%s: Timeout event in state %d!", PROTO_NAME(f), f->state)); - /* no break */ - } -} - - -/* - * fsm_input - Input packet. - */ -void fsm_input(fsm *f, u_char *inpacket, int l) { - u_char *inp; - u_char code, id; - int len; - - /* - * Parse header (code, id and length). - * If packet too short, drop it. - */ - inp = inpacket; - if (l < HEADERLEN) { - FSMDEBUG(("fsm_input(%x): Rcvd short header.", f->protocol)); - return; - } - GETCHAR(code, inp); - GETCHAR(id, inp); - GETSHORT(len, inp); - if (len < HEADERLEN) { - FSMDEBUG(("fsm_input(%x): Rcvd illegal length.", f->protocol)); - return; - } - if (len > l) { - FSMDEBUG(("fsm_input(%x): Rcvd short packet.", f->protocol)); - return; - } - len -= HEADERLEN; /* subtract header length */ - - if( f->state == PPP_FSM_INITIAL || f->state == PPP_FSM_STARTING ){ - FSMDEBUG(("fsm_input(%x): Rcvd packet in state %d.", - f->protocol, f->state)); - return; - } - - /* - * Action depends on code. - */ - switch (code) { - case CONFREQ: - fsm_rconfreq(f, id, inp, len); - break; - - case CONFACK: - fsm_rconfack(f, id, inp, len); - break; - - case CONFNAK: - case CONFREJ: - fsm_rconfnakrej(f, code, id, inp, len); - break; - - case TERMREQ: - fsm_rtermreq(f, id, inp, len); - break; - - case TERMACK: - fsm_rtermack(f); - break; - - case CODEREJ: - fsm_rcoderej(f, inp, len); - break; - - default: - if( !f->callbacks->extcode - || !(*f->callbacks->extcode)(f, code, id, inp, len) ) - fsm_sdata(f, CODEREJ, ++f->id, inpacket, len + HEADERLEN); - break; - } -} - - -/* - * fsm_rconfreq - Receive Configure-Request. - */ -static void fsm_rconfreq(fsm *f, u_char id, u_char *inp, int len) { - int code, reject_if_disagree; - - switch( f->state ){ - case PPP_FSM_CLOSED: - /* Go away, we're closed */ - fsm_sdata(f, TERMACK, id, NULL, 0); - return; - case PPP_FSM_CLOSING: - case PPP_FSM_STOPPING: - return; - - case PPP_FSM_OPENED: - /* Go down and restart negotiation */ - if( f->callbacks->down ) - (*f->callbacks->down)(f); /* Inform upper layers */ - fsm_sconfreq(f, 0); /* Send initial Configure-Request */ - f->state = PPP_FSM_REQSENT; - break; - - case PPP_FSM_STOPPED: - /* Negotiation started by our peer */ - fsm_sconfreq(f, 0); /* Send initial Configure-Request */ - f->state = PPP_FSM_REQSENT; - break; - default: - break; - } - - /* - * Pass the requested configuration options - * to protocol-specific code for checking. - */ - if (f->callbacks->reqci){ /* Check CI */ - reject_if_disagree = (f->nakloops >= f->maxnakloops); - code = (*f->callbacks->reqci)(f, inp, &len, reject_if_disagree); - } else if (len) - code = CONFREJ; /* Reject all CI */ - else - code = CONFACK; - - /* send the Ack, Nak or Rej to the peer */ - fsm_sdata(f, code, id, inp, len); - - if (code == CONFACK) { - if (f->state == PPP_FSM_ACKRCVD) { - UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ - f->state = PPP_FSM_OPENED; - if (f->callbacks->up) - (*f->callbacks->up)(f); /* Inform upper layers */ - } else - f->state = PPP_FSM_ACKSENT; - f->nakloops = 0; - - } else { - /* we sent CONFACK or CONFREJ */ - if (f->state != PPP_FSM_ACKRCVD) - f->state = PPP_FSM_REQSENT; - if( code == CONFNAK ) - ++f->nakloops; - } -} - - -/* - * fsm_rconfack - Receive Configure-Ack. - */ -static void fsm_rconfack(fsm *f, int id, u_char *inp, int len) { - ppp_pcb *pcb = f->pcb; - - if (id != f->reqid || f->seen_ack) /* Expected id? */ - return; /* Nope, toss... */ - if( !(f->callbacks->ackci? (*f->callbacks->ackci)(f, inp, len): - (len == 0)) ){ - /* Ack is bad - ignore it */ - ppp_error("Received bad configure-ack: %P", inp, len); - return; - } - f->seen_ack = 1; - f->rnakloops = 0; - - switch (f->state) { - case PPP_FSM_CLOSED: - case PPP_FSM_STOPPED: - fsm_sdata(f, TERMACK, id, NULL, 0); - break; - - case PPP_FSM_REQSENT: - f->state = PPP_FSM_ACKRCVD; - f->retransmits = pcb->settings.fsm_max_conf_req_transmits; - break; - - case PPP_FSM_ACKRCVD: - /* Huh? an extra valid Ack? oh well... */ - UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ - fsm_sconfreq(f, 0); - f->state = PPP_FSM_REQSENT; - break; - - case PPP_FSM_ACKSENT: - UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ - f->state = PPP_FSM_OPENED; - f->retransmits = pcb->settings.fsm_max_conf_req_transmits; - if (f->callbacks->up) - (*f->callbacks->up)(f); /* Inform upper layers */ - break; - - case PPP_FSM_OPENED: - /* Go down and restart negotiation */ - if (f->callbacks->down) - (*f->callbacks->down)(f); /* Inform upper layers */ - fsm_sconfreq(f, 0); /* Send initial Configure-Request */ - f->state = PPP_FSM_REQSENT; - break; - default: - break; - } -} - - -/* - * fsm_rconfnakrej - Receive Configure-Nak or Configure-Reject. - */ -static void fsm_rconfnakrej(fsm *f, int code, int id, u_char *inp, int len) { - int ret; - int treat_as_reject; - - if (id != f->reqid || f->seen_ack) /* Expected id? */ - return; /* Nope, toss... */ - - if (code == CONFNAK) { - ++f->rnakloops; - treat_as_reject = (f->rnakloops >= f->maxnakloops); - if (f->callbacks->nakci == NULL - || !(ret = f->callbacks->nakci(f, inp, len, treat_as_reject))) { - ppp_error("Received bad configure-nak: %P", inp, len); - return; - } - } else { - f->rnakloops = 0; - if (f->callbacks->rejci == NULL - || !(ret = f->callbacks->rejci(f, inp, len))) { - ppp_error("Received bad configure-rej: %P", inp, len); - return; - } - } - - f->seen_ack = 1; - - switch (f->state) { - case PPP_FSM_CLOSED: - case PPP_FSM_STOPPED: - fsm_sdata(f, TERMACK, id, NULL, 0); - break; - - case PPP_FSM_REQSENT: - case PPP_FSM_ACKSENT: - /* They didn't agree to what we wanted - try another request */ - UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ - if (ret < 0) - f->state = PPP_FSM_STOPPED; /* kludge for stopping CCP */ - else - fsm_sconfreq(f, 0); /* Send Configure-Request */ - break; - - case PPP_FSM_ACKRCVD: - /* Got a Nak/reject when we had already had an Ack?? oh well... */ - UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ - fsm_sconfreq(f, 0); - f->state = PPP_FSM_REQSENT; - break; - - case PPP_FSM_OPENED: - /* Go down and restart negotiation */ - if (f->callbacks->down) - (*f->callbacks->down)(f); /* Inform upper layers */ - fsm_sconfreq(f, 0); /* Send initial Configure-Request */ - f->state = PPP_FSM_REQSENT; - break; - default: - break; - } -} - - -/* - * fsm_rtermreq - Receive Terminate-Req. - */ -static void fsm_rtermreq(fsm *f, int id, u_char *p, int len) { - ppp_pcb *pcb = f->pcb; - - switch (f->state) { - case PPP_FSM_ACKRCVD: - case PPP_FSM_ACKSENT: - f->state = PPP_FSM_REQSENT; /* Start over but keep trying */ - break; - - case PPP_FSM_OPENED: - if (len > 0) { - ppp_info("%s terminated by peer (%0.*v)", PROTO_NAME(f), len, p); - } else - ppp_info("%s terminated by peer", PROTO_NAME(f)); - f->retransmits = 0; - f->state = PPP_FSM_STOPPING; - if (f->callbacks->down) - (*f->callbacks->down)(f); /* Inform upper layers */ - TIMEOUT(fsm_timeout, f, pcb->settings.fsm_timeout_time); - break; - default: - break; - } - - fsm_sdata(f, TERMACK, id, NULL, 0); -} - - -/* - * fsm_rtermack - Receive Terminate-Ack. - */ -static void fsm_rtermack(fsm *f) { - switch (f->state) { - case PPP_FSM_CLOSING: - UNTIMEOUT(fsm_timeout, f); - f->state = PPP_FSM_CLOSED; - if( f->callbacks->finished ) - (*f->callbacks->finished)(f); - break; - case PPP_FSM_STOPPING: - UNTIMEOUT(fsm_timeout, f); - f->state = PPP_FSM_STOPPED; - if( f->callbacks->finished ) - (*f->callbacks->finished)(f); - break; - - case PPP_FSM_ACKRCVD: - f->state = PPP_FSM_REQSENT; - break; - - case PPP_FSM_OPENED: - if (f->callbacks->down) - (*f->callbacks->down)(f); /* Inform upper layers */ - fsm_sconfreq(f, 0); - f->state = PPP_FSM_REQSENT; - break; - default: - break; - } -} - - -/* - * fsm_rcoderej - Receive an Code-Reject. - */ -static void fsm_rcoderej(fsm *f, u_char *inp, int len) { - u_char code, id; - - if (len < HEADERLEN) { - FSMDEBUG(("fsm_rcoderej: Rcvd short Code-Reject packet!")); - return; - } - GETCHAR(code, inp); - GETCHAR(id, inp); - ppp_warn("%s: Rcvd Code-Reject for code %d, id %d", PROTO_NAME(f), code, id); - - if( f->state == PPP_FSM_ACKRCVD ) - f->state = PPP_FSM_REQSENT; -} - - -/* - * fsm_protreject - Peer doesn't speak this protocol. - * - * Treat this as a catastrophic error (RXJ-). - */ -void fsm_protreject(fsm *f) { - switch( f->state ){ - case PPP_FSM_CLOSING: - UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ - /* fall through */ - /* no break */ - case PPP_FSM_CLOSED: - f->state = PPP_FSM_CLOSED; - if( f->callbacks->finished ) - (*f->callbacks->finished)(f); - break; - - case PPP_FSM_STOPPING: - case PPP_FSM_REQSENT: - case PPP_FSM_ACKRCVD: - case PPP_FSM_ACKSENT: - UNTIMEOUT(fsm_timeout, f); /* Cancel timeout */ - /* fall through */ - /* no break */ - case PPP_FSM_STOPPED: - f->state = PPP_FSM_STOPPED; - if( f->callbacks->finished ) - (*f->callbacks->finished)(f); - break; - - case PPP_FSM_OPENED: - terminate_layer(f, PPP_FSM_STOPPING); - break; - - default: - FSMDEBUG(("%s: Protocol-reject event in state %d!", - PROTO_NAME(f), f->state)); - /* no break */ - } -} - - -/* - * fsm_sconfreq - Send a Configure-Request. - */ -static void fsm_sconfreq(fsm *f, int retransmit) { - ppp_pcb *pcb = f->pcb; - struct pbuf *p; - u_char *outp; - int cilen; - - if( f->state != PPP_FSM_REQSENT && f->state != PPP_FSM_ACKRCVD && f->state != PPP_FSM_ACKSENT ){ - /* Not currently negotiating - reset options */ - if( f->callbacks->resetci ) - (*f->callbacks->resetci)(f); - f->nakloops = 0; - f->rnakloops = 0; - } - - if( !retransmit ){ - /* New request - reset retransmission counter, use new ID */ - f->retransmits = pcb->settings.fsm_max_conf_req_transmits; - f->reqid = ++f->id; - } - - f->seen_ack = 0; - - /* - * Make up the request packet - */ - if( f->callbacks->cilen && f->callbacks->addci ){ - cilen = (*f->callbacks->cilen)(f); - if( cilen > pcb->peer_mru - HEADERLEN ) - cilen = pcb->peer_mru - HEADERLEN; - } else - cilen = 0; - - p = pbuf_alloc(PBUF_RAW, (u16_t)(cilen + HEADERLEN + PPP_HDRLEN), PPP_CTRL_PBUF_TYPE); - if(NULL == p) - return; - if(p->tot_len != p->len) { - pbuf_free(p); - return; - } - - /* send the request to our peer */ - outp = (u_char*)p->payload; - MAKEHEADER(outp, f->protocol); - PUTCHAR(CONFREQ, outp); - PUTCHAR(f->reqid, outp); - PUTSHORT(cilen + HEADERLEN, outp); - if (cilen != 0) { - (*f->callbacks->addci)(f, outp, &cilen); - LWIP_ASSERT("cilen == p->len - HEADERLEN - PPP_HDRLEN", cilen == p->len - HEADERLEN - PPP_HDRLEN); - } - - ppp_write(pcb, p); - - /* start the retransmit timer */ - --f->retransmits; - TIMEOUT(fsm_timeout, f, pcb->settings.fsm_timeout_time); -} - - -/* - * fsm_sdata - Send some data. - * - * Used for all packets sent to our peer by this module. - */ -void fsm_sdata(fsm *f, u_char code, u_char id, const u_char *data, int datalen) { - ppp_pcb *pcb = f->pcb; - struct pbuf *p; - u_char *outp; - int outlen; - - /* Adjust length to be smaller than MTU */ - if (datalen > pcb->peer_mru - HEADERLEN) - datalen = pcb->peer_mru - HEADERLEN; - outlen = datalen + HEADERLEN; - - p = pbuf_alloc(PBUF_RAW, (u16_t)(outlen + PPP_HDRLEN), PPP_CTRL_PBUF_TYPE); - if(NULL == p) - return; - if(p->tot_len != p->len) { - pbuf_free(p); - return; - } - - outp = (u_char*)p->payload; - if (datalen) /* && data != outp + PPP_HDRLEN + HEADERLEN) -- was only for fsm_sconfreq() */ - MEMCPY(outp + PPP_HDRLEN + HEADERLEN, data, datalen); - MAKEHEADER(outp, f->protocol); - PUTCHAR(code, outp); - PUTCHAR(id, outp); - PUTSHORT(outlen, outp); - ppp_write(pcb, p); -} - -#endif /* PPP_SUPPORT */ diff --git a/third_party/lwip/repo/lwip/src/netif/ppp/ipcp.c b/third_party/lwip/repo/lwip/src/netif/ppp/ipcp.c deleted file mode 100644 index b7c766eb0b224e..00000000000000 --- a/third_party/lwip/repo/lwip/src/netif/ppp/ipcp.c +++ /dev/null @@ -1,2418 +0,0 @@ -/* - * ipcp.c - PPP IP Control Protocol. - * - * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name "Carnegie Mellon University" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For permission or any legal - * details, please contact - * Office of Technology Transfer - * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu - * - * 4. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Computing Services - * at Carnegie Mellon University (http://www.cmu.edu/computing/)." - * - * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE - * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT && PPP_IPV4_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -/* - * @todo: - */ - -#if 0 /* UNUSED */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#endif /* UNUSED */ - -#include "netif/ppp/ppp_impl.h" - -#include "netif/ppp/fsm.h" -#include "netif/ppp/ipcp.h" - -#if 0 /* UNUSED */ -/* global vars */ -u32_t netmask = 0; /* IP netmask to set on interface */ -#endif /* UNUSED */ - -#if 0 /* UNUSED */ -bool disable_defaultip = 0; /* Don't use hostname for default IP adrs */ -#endif /* UNUSED */ - -#if 0 /* moved to ppp_settings */ -bool noremoteip = 0; /* Let him have no IP address */ -#endif /* moved to ppp_setting */ - -#if 0 /* UNUSED */ -/* Hook for a plugin to know when IP protocol has come up */ -void (*ip_up_hook) (void) = NULL; - -/* Hook for a plugin to know when IP protocol has come down */ -void (*ip_down_hook) (void) = NULL; - -/* Hook for a plugin to choose the remote IP address */ -void (*ip_choose_hook) (u32_t *) = NULL; -#endif /* UNUSED */ - -#if PPP_NOTIFY -/* Notifiers for when IPCP goes up and down */ -struct notifier *ip_up_notifier = NULL; -struct notifier *ip_down_notifier = NULL; -#endif /* PPP_NOTIFY */ - -/* local vars */ -#if 0 /* moved to ppp_pcb */ -static int default_route_set[NUM_PPP]; /* Have set up a default route */ -static int proxy_arp_set[NUM_PPP]; /* Have created proxy arp entry */ -static int ipcp_is_up; /* have called np_up() */ -static int ipcp_is_open; /* haven't called np_finished() */ -static bool ask_for_local; /* request our address from peer */ -#endif /* moved to ppp_pcb */ -#if 0 /* UNUSED */ -static char vj_value[8]; /* string form of vj option value */ -static char netmask_str[20]; /* string form of netmask value */ -#endif /* UNUSED */ - -/* - * Callbacks for fsm code. (CI = Configuration Information) - */ -static void ipcp_resetci(fsm *f); /* Reset our CI */ -static int ipcp_cilen(fsm *f); /* Return length of our CI */ -static void ipcp_addci(fsm *f, u_char *ucp, int *lenp); /* Add our CI */ -static int ipcp_ackci(fsm *f, u_char *p, int len); /* Peer ack'd our CI */ -static int ipcp_nakci(fsm *f, u_char *p, int len, int treat_as_reject);/* Peer nak'd our CI */ -static int ipcp_rejci(fsm *f, u_char *p, int len); /* Peer rej'd our CI */ -static int ipcp_reqci(fsm *f, u_char *inp, int *len, int reject_if_disagree); /* Rcv CI */ -static void ipcp_up(fsm *f); /* We're UP */ -static void ipcp_down(fsm *f); /* We're DOWN */ -static void ipcp_finished(fsm *f); /* Don't need lower layer */ - -static const fsm_callbacks ipcp_callbacks = { /* IPCP callback routines */ - ipcp_resetci, /* Reset our Configuration Information */ - ipcp_cilen, /* Length of our Configuration Information */ - ipcp_addci, /* Add our Configuration Information */ - ipcp_ackci, /* ACK our Configuration Information */ - ipcp_nakci, /* NAK our Configuration Information */ - ipcp_rejci, /* Reject our Configuration Information */ - ipcp_reqci, /* Request peer's Configuration Information */ - ipcp_up, /* Called when fsm reaches OPENED state */ - ipcp_down, /* Called when fsm leaves OPENED state */ - NULL, /* Called when we want the lower layer up */ - ipcp_finished, /* Called when we want the lower layer down */ - NULL, /* Called when Protocol-Reject received */ - NULL, /* Retransmission is necessary */ - NULL, /* Called to handle protocol-specific codes */ - "IPCP" /* String name of protocol */ -}; - -/* - * Command-line options. - */ -#if PPP_OPTIONS -static int setvjslots (char **); -static int setdnsaddr (char **); -static int setwinsaddr (char **); -static int setnetmask (char **); -int setipaddr (char *, char **, int); - -static void printipaddr (option_t *, void (*)(void *, char *,...),void *); - -static option_t ipcp_option_list[] = { - { "noip", o_bool, &ipcp_protent.enabled_flag, - "Disable IP and IPCP" }, - { "-ip", o_bool, &ipcp_protent.enabled_flag, - "Disable IP and IPCP", OPT_ALIAS }, - - { "novj", o_bool, &ipcp_wantoptions[0].neg_vj, - "Disable VJ compression", OPT_A2CLR, &ipcp_allowoptions[0].neg_vj }, - { "-vj", o_bool, &ipcp_wantoptions[0].neg_vj, - "Disable VJ compression", OPT_ALIAS | OPT_A2CLR, - &ipcp_allowoptions[0].neg_vj }, - - { "novjccomp", o_bool, &ipcp_wantoptions[0].cflag, - "Disable VJ connection-ID compression", OPT_A2CLR, - &ipcp_allowoptions[0].cflag }, - { "-vjccomp", o_bool, &ipcp_wantoptions[0].cflag, - "Disable VJ connection-ID compression", OPT_ALIAS | OPT_A2CLR, - &ipcp_allowoptions[0].cflag }, - - { "vj-max-slots", o_special, (void *)setvjslots, - "Set maximum VJ header slots", - OPT_PRIO | OPT_A2STRVAL | OPT_STATIC, vj_value }, - - { "ipcp-accept-local", o_bool, &ipcp_wantoptions[0].accept_local, - "Accept peer's address for us", 1 }, - { "ipcp-accept-remote", o_bool, &ipcp_wantoptions[0].accept_remote, - "Accept peer's address for it", 1 }, - - { "ipparam", o_string, &ipparam, - "Set ip script parameter", OPT_PRIO }, - - { "noipdefault", o_bool, &disable_defaultip, - "Don't use name for default IP adrs", 1 }, - - { "ms-dns", 1, (void *)setdnsaddr, - "DNS address for the peer's use" }, - { "ms-wins", 1, (void *)setwinsaddr, - "Nameserver for SMB over TCP/IP for peer" }, - - { "ipcp-restart", o_int, &ipcp_fsm[0].timeouttime, - "Set timeout for IPCP", OPT_PRIO }, - { "ipcp-max-terminate", o_int, &ipcp_fsm[0].maxtermtransmits, - "Set max #xmits for term-reqs", OPT_PRIO }, - { "ipcp-max-configure", o_int, &ipcp_fsm[0].maxconfreqtransmits, - "Set max #xmits for conf-reqs", OPT_PRIO }, - { "ipcp-max-failure", o_int, &ipcp_fsm[0].maxnakloops, - "Set max #conf-naks for IPCP", OPT_PRIO }, - - { "defaultroute", o_bool, &ipcp_wantoptions[0].default_route, - "Add default route", OPT_ENABLE|1, &ipcp_allowoptions[0].default_route }, - { "nodefaultroute", o_bool, &ipcp_allowoptions[0].default_route, - "disable defaultroute option", OPT_A2CLR, - &ipcp_wantoptions[0].default_route }, - { "-defaultroute", o_bool, &ipcp_allowoptions[0].default_route, - "disable defaultroute option", OPT_ALIAS | OPT_A2CLR, - &ipcp_wantoptions[0].default_route }, - - { "replacedefaultroute", o_bool, - &ipcp_wantoptions[0].replace_default_route, - "Replace default route", 1 - }, - { "noreplacedefaultroute", o_bool, - &ipcp_allowoptions[0].replace_default_route, - "Never replace default route", OPT_A2COPY, - &ipcp_wantoptions[0].replace_default_route }, - { "proxyarp", o_bool, &ipcp_wantoptions[0].proxy_arp, - "Add proxy ARP entry", OPT_ENABLE|1, &ipcp_allowoptions[0].proxy_arp }, - { "noproxyarp", o_bool, &ipcp_allowoptions[0].proxy_arp, - "disable proxyarp option", OPT_A2CLR, - &ipcp_wantoptions[0].proxy_arp }, - { "-proxyarp", o_bool, &ipcp_allowoptions[0].proxy_arp, - "disable proxyarp option", OPT_ALIAS | OPT_A2CLR, - &ipcp_wantoptions[0].proxy_arp }, - - { "usepeerdns", o_bool, &usepeerdns, - "Ask peer for DNS address(es)", 1 }, - - { "netmask", o_special, (void *)setnetmask, - "set netmask", OPT_PRIO | OPT_A2STRVAL | OPT_STATIC, netmask_str }, - - { "ipcp-no-addresses", o_bool, &ipcp_wantoptions[0].old_addrs, - "Disable old-style IP-Addresses usage", OPT_A2CLR, - &ipcp_allowoptions[0].old_addrs }, - { "ipcp-no-address", o_bool, &ipcp_wantoptions[0].neg_addr, - "Disable IP-Address usage", OPT_A2CLR, - &ipcp_allowoptions[0].neg_addr }, - - { "noremoteip", o_bool, &noremoteip, - "Allow peer to have no IP address", 1 }, - - { "nosendip", o_bool, &ipcp_wantoptions[0].neg_addr, - "Don't send our IP address to peer", OPT_A2CLR, - &ipcp_wantoptions[0].old_addrs}, - - { "IP addresses", o_wild, (void *) &setipaddr, - "set local and remote IP addresses", - OPT_NOARG | OPT_A2PRINTER, (void *) &printipaddr }, - - { NULL } -}; -#endif /* PPP_OPTIONS */ - -/* - * Protocol entry points from main code. - */ -static void ipcp_init(ppp_pcb *pcb); -static void ipcp_open(ppp_pcb *pcb); -static void ipcp_close(ppp_pcb *pcb, const char *reason); -static void ipcp_lowerup(ppp_pcb *pcb); -static void ipcp_lowerdown(ppp_pcb *pcb); -static void ipcp_input(ppp_pcb *pcb, u_char *p, int len); -static void ipcp_protrej(ppp_pcb *pcb); -#if PRINTPKT_SUPPORT -static int ipcp_printpkt(const u_char *p, int plen, - void (*printer) (void *, const char *, ...), void *arg); -#endif /* PRINTPKT_SUPPORT */ -#if PPP_OPTIONS -static void ip_check_options (void); -#endif /* PPP_OPTIONS */ -#if DEMAND_SUPPORT -static int ip_demand_conf (int); -static int ip_active_pkt (u_char *, int); -#endif /* DEMAND_SUPPORT */ -#if 0 /* UNUSED */ -static void create_resolv (u32_t, u32_t); -#endif /* UNUSED */ - -const struct protent ipcp_protent = { - PPP_IPCP, - ipcp_init, - ipcp_input, - ipcp_protrej, - ipcp_lowerup, - ipcp_lowerdown, - ipcp_open, - ipcp_close, -#if PRINTPKT_SUPPORT - ipcp_printpkt, -#endif /* PRINTPKT_SUPPORT */ -#if PPP_DATAINPUT - NULL, -#endif /* PPP_DATAINPUT */ -#if PRINTPKT_SUPPORT - "IPCP", - "IP", -#endif /* PRINTPKT_SUPPORT */ -#if PPP_OPTIONS - ipcp_option_list, - ip_check_options, -#endif /* PPP_OPTIONS */ -#if DEMAND_SUPPORT - ip_demand_conf, - ip_active_pkt -#endif /* DEMAND_SUPPORT */ -}; - -static void ipcp_clear_addrs(ppp_pcb *pcb, u32_t ouraddr, u32_t hisaddr, u8_t replacedefaultroute); - -/* - * Lengths of configuration options. - */ -#define CILEN_VOID 2 -#define CILEN_COMPRESS 4 /* min length for compression protocol opt. */ -#define CILEN_VJ 6 /* length for RFC1332 Van-Jacobson opt. */ -#define CILEN_ADDR 6 /* new-style single address option */ -#define CILEN_ADDRS 10 /* old-style dual address option */ - - -#define CODENAME(x) ((x) == CONFACK ? "ACK" : \ - (x) == CONFNAK ? "NAK" : "REJ") - -#if 0 /* UNUSED, already defined by lwIP */ -/* - * Make a string representation of a network IP address. - */ -char * -ip_ntoa(ipaddr) -u32_t ipaddr; -{ - static char b[64]; - - slprintf(b, sizeof(b), "%I", ipaddr); - return b; -} -#endif /* UNUSED, already defined by lwIP */ - -/* - * Option parsing. - */ -#if PPP_OPTIONS -/* - * setvjslots - set maximum number of connection slots for VJ compression - */ -static int -setvjslots(argv) - char **argv; -{ - int value; - - if (!int_option(*argv, &value)) - return 0; - - if (value < 2 || value > 16) { - option_error("vj-max-slots value must be between 2 and 16"); - return 0; - } - ipcp_wantoptions [0].maxslotindex = - ipcp_allowoptions[0].maxslotindex = value - 1; - slprintf(vj_value, sizeof(vj_value), "%d", value); - return 1; -} - -/* - * setdnsaddr - set the dns address(es) - */ -static int -setdnsaddr(argv) - char **argv; -{ - u32_t dns; - struct hostent *hp; - - dns = inet_addr(*argv); - if (dns == (u32_t) -1) { - if ((hp = gethostbyname(*argv)) == NULL) { - option_error("invalid address parameter '%s' for ms-dns option", - *argv); - return 0; - } - dns = *(u32_t *)hp->h_addr; - } - - /* We take the last 2 values given, the 2nd-last as the primary - and the last as the secondary. If only one is given it - becomes both primary and secondary. */ - if (ipcp_allowoptions[0].dnsaddr[1] == 0) - ipcp_allowoptions[0].dnsaddr[0] = dns; - else - ipcp_allowoptions[0].dnsaddr[0] = ipcp_allowoptions[0].dnsaddr[1]; - - /* always set the secondary address value. */ - ipcp_allowoptions[0].dnsaddr[1] = dns; - - return (1); -} - -/* - * setwinsaddr - set the wins address(es) - * This is primrarly used with the Samba package under UNIX or for pointing - * the caller to the existing WINS server on a Windows NT platform. - */ -static int -setwinsaddr(argv) - char **argv; -{ - u32_t wins; - struct hostent *hp; - - wins = inet_addr(*argv); - if (wins == (u32_t) -1) { - if ((hp = gethostbyname(*argv)) == NULL) { - option_error("invalid address parameter '%s' for ms-wins option", - *argv); - return 0; - } - wins = *(u32_t *)hp->h_addr; - } - - /* We take the last 2 values given, the 2nd-last as the primary - and the last as the secondary. If only one is given it - becomes both primary and secondary. */ - if (ipcp_allowoptions[0].winsaddr[1] == 0) - ipcp_allowoptions[0].winsaddr[0] = wins; - else - ipcp_allowoptions[0].winsaddr[0] = ipcp_allowoptions[0].winsaddr[1]; - - /* always set the secondary address value. */ - ipcp_allowoptions[0].winsaddr[1] = wins; - - return (1); -} - -/* - * setipaddr - Set the IP address - * If doit is 0, the call is to check whether this option is - * potentially an IP address specification. - * Not static so that plugins can call it to set the addresses - */ -int -setipaddr(arg, argv, doit) - char *arg; - char **argv; - int doit; -{ - struct hostent *hp; - char *colon; - u32_t local, remote; - ipcp_options *wo = &ipcp_wantoptions[0]; - static int prio_local = 0, prio_remote = 0; - - /* - * IP address pair separated by ":". - */ - if ((colon = strchr(arg, ':')) == NULL) - return 0; - if (!doit) - return 1; - - /* - * If colon first character, then no local addr. - */ - if (colon != arg && option_priority >= prio_local) { - *colon = '\0'; - if ((local = inet_addr(arg)) == (u32_t) -1) { - if ((hp = gethostbyname(arg)) == NULL) { - option_error("unknown host: %s", arg); - return 0; - } - local = *(u32_t *)hp->h_addr; - } - if (bad_ip_adrs(local)) { - option_error("bad local IP address %s", ip_ntoa(local)); - return 0; - } - if (local != 0) - wo->ouraddr = local; - *colon = ':'; - prio_local = option_priority; - } - - /* - * If colon last character, then no remote addr. - */ - if (*++colon != '\0' && option_priority >= prio_remote) { - if ((remote = inet_addr(colon)) == (u32_t) -1) { - if ((hp = gethostbyname(colon)) == NULL) { - option_error("unknown host: %s", colon); - return 0; - } - remote = *(u32_t *)hp->h_addr; - if (remote_name[0] == 0) - strlcpy(remote_name, colon, sizeof(remote_name)); - } - if (bad_ip_adrs(remote)) { - option_error("bad remote IP address %s", ip_ntoa(remote)); - return 0; - } - if (remote != 0) - wo->hisaddr = remote; - prio_remote = option_priority; - } - - return 1; -} - -static void -printipaddr(opt, printer, arg) - option_t *opt; - void (*printer) (void *, char *, ...); - void *arg; -{ - ipcp_options *wo = &ipcp_wantoptions[0]; - - if (wo->ouraddr != 0) - printer(arg, "%I", wo->ouraddr); - printer(arg, ":"); - if (wo->hisaddr != 0) - printer(arg, "%I", wo->hisaddr); -} - -/* - * setnetmask - set the netmask to be used on the interface. - */ -static int -setnetmask(argv) - char **argv; -{ - u32_t mask; - int n; - char *p; - - /* - * Unfortunately, if we use inet_addr, we can't tell whether - * a result of all 1s is an error or a valid 255.255.255.255. - */ - p = *argv; - n = parse_dotted_ip(p, &mask); - - mask = lwip_htonl(mask); - - if (n == 0 || p[n] != 0 || (netmask & ~mask) != 0) { - option_error("invalid netmask value '%s'", *argv); - return 0; - } - - netmask = mask; - slprintf(netmask_str, sizeof(netmask_str), "%I", mask); - - return (1); -} - -int -parse_dotted_ip(p, vp) - char *p; - u32_t *vp; -{ - int n; - u32_t v, b; - char *endp, *p0 = p; - - v = 0; - for (n = 3;; --n) { - b = strtoul(p, &endp, 0); - if (endp == p) - return 0; - if (b > 255) { - if (n < 3) - return 0; - /* accept e.g. 0xffffff00 */ - *vp = b; - return endp - p0; - } - v |= b << (n * 8); - p = endp; - if (n == 0) - break; - if (*p != '.') - return 0; - ++p; - } - *vp = v; - return p - p0; -} -#endif /* PPP_OPTIONS */ - -/* - * ipcp_init - Initialize IPCP. - */ -static void ipcp_init(ppp_pcb *pcb) { - fsm *f = &pcb->ipcp_fsm; - - ipcp_options *wo = &pcb->ipcp_wantoptions; - ipcp_options *ao = &pcb->ipcp_allowoptions; - - f->pcb = pcb; - f->protocol = PPP_IPCP; - f->callbacks = &ipcp_callbacks; - fsm_init(f); - - /* - * Some 3G modems use repeated IPCP NAKs as a way of stalling - * until they can contact a server on the network, so we increase - * the default number of NAKs we accept before we start treating - * them as rejects. - */ - f->maxnakloops = 100; - -#if 0 /* Not necessary, everything is cleared in ppp_new() */ - memset(wo, 0, sizeof(*wo)); - memset(ao, 0, sizeof(*ao)); -#endif /* 0 */ - - wo->neg_addr = wo->old_addrs = 1; -#if VJ_SUPPORT - wo->neg_vj = 1; - wo->vj_protocol = IPCP_VJ_COMP; - wo->maxslotindex = MAX_STATES - 1; /* really max index */ - wo->cflag = 1; -#endif /* VJ_SUPPORT */ - -#if 0 /* UNUSED */ - /* wanting default route by default */ - wo->default_route = 1; -#endif /* UNUSED */ - - ao->neg_addr = ao->old_addrs = 1; -#if VJ_SUPPORT - /* max slots and slot-id compression are currently hardwired in */ - /* ppp_if.c to 16 and 1, this needs to be changed (among other */ - /* things) gmc */ - - ao->neg_vj = 1; - ao->maxslotindex = MAX_STATES - 1; - ao->cflag = 1; -#endif /* #if VJ_SUPPORT */ - -#if 0 /* UNUSED */ - /* - * XXX These control whether the user may use the proxyarp - * and defaultroute options. - */ - ao->proxy_arp = 1; - ao->default_route = 1; -#endif /* UNUSED */ -} - - -/* - * ipcp_open - IPCP is allowed to come up. - */ -static void ipcp_open(ppp_pcb *pcb) { - fsm *f = &pcb->ipcp_fsm; - fsm_open(f); - pcb->ipcp_is_open = 1; -} - - -/* - * ipcp_close - Take IPCP down. - */ -static void ipcp_close(ppp_pcb *pcb, const char *reason) { - fsm *f = &pcb->ipcp_fsm; - fsm_close(f, reason); -} - - -/* - * ipcp_lowerup - The lower layer is up. - */ -static void ipcp_lowerup(ppp_pcb *pcb) { - fsm *f = &pcb->ipcp_fsm; - fsm_lowerup(f); -} - - -/* - * ipcp_lowerdown - The lower layer is down. - */ -static void ipcp_lowerdown(ppp_pcb *pcb) { - fsm *f = &pcb->ipcp_fsm; - fsm_lowerdown(f); -} - - -/* - * ipcp_input - Input IPCP packet. - */ -static void ipcp_input(ppp_pcb *pcb, u_char *p, int len) { - fsm *f = &pcb->ipcp_fsm; - fsm_input(f, p, len); -} - - -/* - * ipcp_protrej - A Protocol-Reject was received for IPCP. - * - * Pretend the lower layer went down, so we shut up. - */ -static void ipcp_protrej(ppp_pcb *pcb) { - fsm *f = &pcb->ipcp_fsm; - fsm_lowerdown(f); -} - - -/* - * ipcp_resetci - Reset our CI. - * Called by fsm_sconfreq, Send Configure Request. - */ -static void ipcp_resetci(fsm *f) { - ppp_pcb *pcb = f->pcb; - ipcp_options *wo = &pcb->ipcp_wantoptions; - ipcp_options *go = &pcb->ipcp_gotoptions; - ipcp_options *ao = &pcb->ipcp_allowoptions; - - wo->req_addr = (wo->neg_addr || wo->old_addrs) && - (ao->neg_addr || ao->old_addrs); - if (wo->ouraddr == 0) - wo->accept_local = 1; - if (wo->hisaddr == 0) - wo->accept_remote = 1; -#if LWIP_DNS - wo->req_dns1 = wo->req_dns2 = pcb->settings.usepeerdns; /* Request DNS addresses from the peer */ -#endif /* LWIP_DNS */ - *go = *wo; - if (!pcb->ask_for_local) - go->ouraddr = 0; -#if 0 /* UNUSED */ - if (ip_choose_hook) { - ip_choose_hook(&wo->hisaddr); - if (wo->hisaddr) { - wo->accept_remote = 0; - } - } -#endif /* UNUSED */ - BZERO(&pcb->ipcp_hisoptions, sizeof(ipcp_options)); -} - - -/* - * ipcp_cilen - Return length of our CI. - * Called by fsm_sconfreq, Send Configure Request. - */ -static int ipcp_cilen(fsm *f) { - ppp_pcb *pcb = f->pcb; - ipcp_options *go = &pcb->ipcp_gotoptions; -#if VJ_SUPPORT - ipcp_options *wo = &pcb->ipcp_wantoptions; -#endif /* VJ_SUPPORT */ - ipcp_options *ho = &pcb->ipcp_hisoptions; - -#define LENCIADDRS(neg) (neg ? CILEN_ADDRS : 0) -#if VJ_SUPPORT -#define LENCIVJ(neg, old) (neg ? (old? CILEN_COMPRESS : CILEN_VJ) : 0) -#endif /* VJ_SUPPORT */ -#define LENCIADDR(neg) (neg ? CILEN_ADDR : 0) -#if LWIP_DNS -#define LENCIDNS(neg) LENCIADDR(neg) -#endif /* LWIP_DNS */ -#if 0 /* UNUSED - WINS */ -#define LENCIWINS(neg) LENCIADDR(neg) -#endif /* UNUSED - WINS */ - - /* - * First see if we want to change our options to the old - * forms because we have received old forms from the peer. - */ - if (go->neg_addr && go->old_addrs && !ho->neg_addr && ho->old_addrs) - go->neg_addr = 0; - -#if VJ_SUPPORT - if (wo->neg_vj && !go->neg_vj && !go->old_vj) { - /* try an older style of VJ negotiation */ - /* use the old style only if the peer did */ - if (ho->neg_vj && ho->old_vj) { - go->neg_vj = 1; - go->old_vj = 1; - go->vj_protocol = ho->vj_protocol; - } - } -#endif /* VJ_SUPPORT */ - - return (LENCIADDRS(!go->neg_addr && go->old_addrs) + -#if VJ_SUPPORT - LENCIVJ(go->neg_vj, go->old_vj) + -#endif /* VJ_SUPPORT */ - LENCIADDR(go->neg_addr) + -#if LWIP_DNS - LENCIDNS(go->req_dns1) + - LENCIDNS(go->req_dns2) + -#endif /* LWIP_DNS */ -#if 0 /* UNUSED - WINS */ - LENCIWINS(go->winsaddr[0]) + - LENCIWINS(go->winsaddr[1]) + -#endif /* UNUSED - WINS */ - 0); -} - - -/* - * ipcp_addci - Add our desired CIs to a packet. - * Called by fsm_sconfreq, Send Configure Request. - */ -static void ipcp_addci(fsm *f, u_char *ucp, int *lenp) { - ppp_pcb *pcb = f->pcb; - ipcp_options *go = &pcb->ipcp_gotoptions; - int len = *lenp; - -#define ADDCIADDRS(opt, neg, val1, val2) \ - if (neg) { \ - if (len >= CILEN_ADDRS) { \ - u32_t l; \ - PUTCHAR(opt, ucp); \ - PUTCHAR(CILEN_ADDRS, ucp); \ - l = lwip_ntohl(val1); \ - PUTLONG(l, ucp); \ - l = lwip_ntohl(val2); \ - PUTLONG(l, ucp); \ - len -= CILEN_ADDRS; \ - } else \ - go->old_addrs = 0; \ - } - -#if VJ_SUPPORT -#define ADDCIVJ(opt, neg, val, old, maxslotindex, cflag) \ - if (neg) { \ - int vjlen = old? CILEN_COMPRESS : CILEN_VJ; \ - if (len >= vjlen) { \ - PUTCHAR(opt, ucp); \ - PUTCHAR(vjlen, ucp); \ - PUTSHORT(val, ucp); \ - if (!old) { \ - PUTCHAR(maxslotindex, ucp); \ - PUTCHAR(cflag, ucp); \ - } \ - len -= vjlen; \ - } else \ - neg = 0; \ - } -#endif /* VJ_SUPPORT */ - -#define ADDCIADDR(opt, neg, val) \ - if (neg) { \ - if (len >= CILEN_ADDR) { \ - u32_t l; \ - PUTCHAR(opt, ucp); \ - PUTCHAR(CILEN_ADDR, ucp); \ - l = lwip_ntohl(val); \ - PUTLONG(l, ucp); \ - len -= CILEN_ADDR; \ - } else \ - neg = 0; \ - } - -#if LWIP_DNS -#define ADDCIDNS(opt, neg, addr) \ - if (neg) { \ - if (len >= CILEN_ADDR) { \ - u32_t l; \ - PUTCHAR(opt, ucp); \ - PUTCHAR(CILEN_ADDR, ucp); \ - l = lwip_ntohl(addr); \ - PUTLONG(l, ucp); \ - len -= CILEN_ADDR; \ - } else \ - neg = 0; \ - } -#endif /* LWIP_DNS */ - -#if 0 /* UNUSED - WINS */ -#define ADDCIWINS(opt, addr) \ - if (addr) { \ - if (len >= CILEN_ADDR) { \ - u32_t l; \ - PUTCHAR(opt, ucp); \ - PUTCHAR(CILEN_ADDR, ucp); \ - l = lwip_ntohl(addr); \ - PUTLONG(l, ucp); \ - len -= CILEN_ADDR; \ - } else \ - addr = 0; \ - } -#endif /* UNUSED - WINS */ - - ADDCIADDRS(CI_ADDRS, !go->neg_addr && go->old_addrs, go->ouraddr, - go->hisaddr); - -#if VJ_SUPPORT - ADDCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol, go->old_vj, - go->maxslotindex, go->cflag); -#endif /* VJ_SUPPORT */ - - ADDCIADDR(CI_ADDR, go->neg_addr, go->ouraddr); - -#if LWIP_DNS - ADDCIDNS(CI_MS_DNS1, go->req_dns1, go->dnsaddr[0]); - - ADDCIDNS(CI_MS_DNS2, go->req_dns2, go->dnsaddr[1]); -#endif /* LWIP_DNS */ - -#if 0 /* UNUSED - WINS */ - ADDCIWINS(CI_MS_WINS1, go->winsaddr[0]); - - ADDCIWINS(CI_MS_WINS2, go->winsaddr[1]); -#endif /* UNUSED - WINS */ - - *lenp -= len; -} - - -/* - * ipcp_ackci - Ack our CIs. - * Called by fsm_rconfack, Receive Configure ACK. - * - * Returns: - * 0 - Ack was bad. - * 1 - Ack was good. - */ -static int ipcp_ackci(fsm *f, u_char *p, int len) { - ppp_pcb *pcb = f->pcb; - ipcp_options *go = &pcb->ipcp_gotoptions; - u_short cilen, citype; - u32_t cilong; -#if VJ_SUPPORT - u_short cishort; - u_char cimaxslotindex, cicflag; -#endif /* VJ_SUPPORT */ - - /* - * CIs must be in exactly the same order that we sent... - * Check packet length and CI length at each step. - * If we find any deviations, then this packet is bad. - */ - -#define ACKCIADDRS(opt, neg, val1, val2) \ - if (neg) { \ - u32_t l; \ - if ((len -= CILEN_ADDRS) < 0) \ - goto bad; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != CILEN_ADDRS || \ - citype != opt) \ - goto bad; \ - GETLONG(l, p); \ - cilong = lwip_htonl(l); \ - if (val1 != cilong) \ - goto bad; \ - GETLONG(l, p); \ - cilong = lwip_htonl(l); \ - if (val2 != cilong) \ - goto bad; \ - } - -#if VJ_SUPPORT -#define ACKCIVJ(opt, neg, val, old, maxslotindex, cflag) \ - if (neg) { \ - int vjlen = old? CILEN_COMPRESS : CILEN_VJ; \ - if ((len -= vjlen) < 0) \ - goto bad; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != vjlen || \ - citype != opt) \ - goto bad; \ - GETSHORT(cishort, p); \ - if (cishort != val) \ - goto bad; \ - if (!old) { \ - GETCHAR(cimaxslotindex, p); \ - if (cimaxslotindex != maxslotindex) \ - goto bad; \ - GETCHAR(cicflag, p); \ - if (cicflag != cflag) \ - goto bad; \ - } \ - } -#endif /* VJ_SUPPORT */ - -#define ACKCIADDR(opt, neg, val) \ - if (neg) { \ - u32_t l; \ - if ((len -= CILEN_ADDR) < 0) \ - goto bad; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != CILEN_ADDR || \ - citype != opt) \ - goto bad; \ - GETLONG(l, p); \ - cilong = lwip_htonl(l); \ - if (val != cilong) \ - goto bad; \ - } - -#if LWIP_DNS -#define ACKCIDNS(opt, neg, addr) \ - if (neg) { \ - u32_t l; \ - if ((len -= CILEN_ADDR) < 0) \ - goto bad; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != CILEN_ADDR || citype != opt) \ - goto bad; \ - GETLONG(l, p); \ - cilong = lwip_htonl(l); \ - if (addr != cilong) \ - goto bad; \ - } -#endif /* LWIP_DNS */ - -#if 0 /* UNUSED - WINS */ -#define ACKCIWINS(opt, addr) \ - if (addr) { \ - u32_t l; \ - if ((len -= CILEN_ADDR) < 0) \ - goto bad; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != CILEN_ADDR || citype != opt) \ - goto bad; \ - GETLONG(l, p); \ - cilong = lwip_htonl(l); \ - if (addr != cilong) \ - goto bad; \ - } -#endif /* UNUSED - WINS */ - - ACKCIADDRS(CI_ADDRS, !go->neg_addr && go->old_addrs, go->ouraddr, - go->hisaddr); - -#if VJ_SUPPORT - ACKCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol, go->old_vj, - go->maxslotindex, go->cflag); -#endif /* VJ_SUPPORT */ - - ACKCIADDR(CI_ADDR, go->neg_addr, go->ouraddr); - -#if LWIP_DNS - ACKCIDNS(CI_MS_DNS1, go->req_dns1, go->dnsaddr[0]); - - ACKCIDNS(CI_MS_DNS2, go->req_dns2, go->dnsaddr[1]); -#endif /* LWIP_DNS */ - -#if 0 /* UNUSED - WINS */ - ACKCIWINS(CI_MS_WINS1, go->winsaddr[0]); - - ACKCIWINS(CI_MS_WINS2, go->winsaddr[1]); -#endif /* UNUSED - WINS */ - - /* - * If there are any remaining CIs, then this packet is bad. - */ - if (len != 0) - goto bad; - return (1); - -bad: - IPCPDEBUG(("ipcp_ackci: received bad Ack!")); - return (0); -} - -/* - * ipcp_nakci - Peer has sent a NAK for some of our CIs. - * This should not modify any state if the Nak is bad - * or if IPCP is in the OPENED state. - * Calback from fsm_rconfnakrej - Receive Configure-Nak or Configure-Reject. - * - * Returns: - * 0 - Nak was bad. - * 1 - Nak was good. - */ -static int ipcp_nakci(fsm *f, u_char *p, int len, int treat_as_reject) { - ppp_pcb *pcb = f->pcb; - ipcp_options *go = &pcb->ipcp_gotoptions; - u_char citype, cilen, *next; -#if VJ_SUPPORT - u_char cimaxslotindex, cicflag; - u_short cishort; -#endif /* VJ_SUPPORT */ - u32_t ciaddr1, ciaddr2, l; -#if LWIP_DNS - u32_t cidnsaddr; -#endif /* LWIP_DNS */ - ipcp_options no; /* options we've seen Naks for */ - ipcp_options try_; /* options to request next time */ - - BZERO(&no, sizeof(no)); - try_ = *go; - - /* - * Any Nak'd CIs must be in exactly the same order that we sent. - * Check packet length and CI length at each step. - * If we find any deviations, then this packet is bad. - */ -#define NAKCIADDRS(opt, neg, code) \ - if ((neg) && \ - (cilen = p[1]) == CILEN_ADDRS && \ - len >= cilen && \ - p[0] == opt) { \ - len -= cilen; \ - INCPTR(2, p); \ - GETLONG(l, p); \ - ciaddr1 = lwip_htonl(l); \ - GETLONG(l, p); \ - ciaddr2 = lwip_htonl(l); \ - no.old_addrs = 1; \ - code \ - } - -#if VJ_SUPPORT -#define NAKCIVJ(opt, neg, code) \ - if (go->neg && \ - ((cilen = p[1]) == CILEN_COMPRESS || cilen == CILEN_VJ) && \ - len >= cilen && \ - p[0] == opt) { \ - len -= cilen; \ - INCPTR(2, p); \ - GETSHORT(cishort, p); \ - no.neg = 1; \ - code \ - } -#endif /* VJ_SUPPORT */ - -#define NAKCIADDR(opt, neg, code) \ - if (go->neg && \ - (cilen = p[1]) == CILEN_ADDR && \ - len >= cilen && \ - p[0] == opt) { \ - len -= cilen; \ - INCPTR(2, p); \ - GETLONG(l, p); \ - ciaddr1 = lwip_htonl(l); \ - no.neg = 1; \ - code \ - } - -#if LWIP_DNS -#define NAKCIDNS(opt, neg, code) \ - if (go->neg && \ - ((cilen = p[1]) == CILEN_ADDR) && \ - len >= cilen && \ - p[0] == opt) { \ - len -= cilen; \ - INCPTR(2, p); \ - GETLONG(l, p); \ - cidnsaddr = lwip_htonl(l); \ - no.neg = 1; \ - code \ - } -#endif /* LWIP_DNS */ - - /* - * Accept the peer's idea of {our,his} address, if different - * from our idea, only if the accept_{local,remote} flag is set. - */ - NAKCIADDRS(CI_ADDRS, !go->neg_addr && go->old_addrs, - if (treat_as_reject) { - try_.old_addrs = 0; - } else { - if (go->accept_local && ciaddr1) { - /* take his idea of our address */ - try_.ouraddr = ciaddr1; - } - if (go->accept_remote && ciaddr2) { - /* take his idea of his address */ - try_.hisaddr = ciaddr2; - } - } - ); - -#if VJ_SUPPORT - /* - * Accept the peer's value of maxslotindex provided that it - * is less than what we asked for. Turn off slot-ID compression - * if the peer wants. Send old-style compress-type option if - * the peer wants. - */ - NAKCIVJ(CI_COMPRESSTYPE, neg_vj, - if (treat_as_reject) { - try_.neg_vj = 0; - } else if (cilen == CILEN_VJ) { - GETCHAR(cimaxslotindex, p); - GETCHAR(cicflag, p); - if (cishort == IPCP_VJ_COMP) { - try_.old_vj = 0; - if (cimaxslotindex < go->maxslotindex) - try_.maxslotindex = cimaxslotindex; - if (!cicflag) - try_.cflag = 0; - } else { - try_.neg_vj = 0; - } - } else { - if (cishort == IPCP_VJ_COMP || cishort == IPCP_VJ_COMP_OLD) { - try_.old_vj = 1; - try_.vj_protocol = cishort; - } else { - try_.neg_vj = 0; - } - } - ); -#endif /* VJ_SUPPORT */ - - NAKCIADDR(CI_ADDR, neg_addr, - if (treat_as_reject) { - try_.neg_addr = 0; - try_.old_addrs = 0; - } else if (go->accept_local && ciaddr1) { - /* take his idea of our address */ - try_.ouraddr = ciaddr1; - } - ); - -#if LWIP_DNS - NAKCIDNS(CI_MS_DNS1, req_dns1, - if (treat_as_reject) { - try_.req_dns1 = 0; - } else { - try_.dnsaddr[0] = cidnsaddr; - } - ); - - NAKCIDNS(CI_MS_DNS2, req_dns2, - if (treat_as_reject) { - try_.req_dns2 = 0; - } else { - try_.dnsaddr[1] = cidnsaddr; - } - ); -#endif /* #if LWIP_DNS */ - - /* - * There may be remaining CIs, if the peer is requesting negotiation - * on an option that we didn't include in our request packet. - * If they want to negotiate about IP addresses, we comply. - * If they want us to ask for compression, we refuse. - * If they want us to ask for ms-dns, we do that, since some - * peers get huffy if we don't. - */ - while (len >= CILEN_VOID) { - GETCHAR(citype, p); - GETCHAR(cilen, p); - if ( cilen < CILEN_VOID || (len -= cilen) < 0 ) - goto bad; - next = p + cilen - 2; - - switch (citype) { -#if VJ_SUPPORT - case CI_COMPRESSTYPE: - if (go->neg_vj || no.neg_vj || - (cilen != CILEN_VJ && cilen != CILEN_COMPRESS)) - goto bad; - no.neg_vj = 1; - break; -#endif /* VJ_SUPPORT */ - case CI_ADDRS: - if ((!go->neg_addr && go->old_addrs) || no.old_addrs - || cilen != CILEN_ADDRS) - goto bad; - try_.neg_addr = 0; - GETLONG(l, p); - ciaddr1 = lwip_htonl(l); - if (ciaddr1 && go->accept_local) - try_.ouraddr = ciaddr1; - GETLONG(l, p); - ciaddr2 = lwip_htonl(l); - if (ciaddr2 && go->accept_remote) - try_.hisaddr = ciaddr2; - no.old_addrs = 1; - break; - case CI_ADDR: - if (go->neg_addr || no.neg_addr || cilen != CILEN_ADDR) - goto bad; - try_.old_addrs = 0; - GETLONG(l, p); - ciaddr1 = lwip_htonl(l); - if (ciaddr1 && go->accept_local) - try_.ouraddr = ciaddr1; - if (try_.ouraddr != 0) - try_.neg_addr = 1; - no.neg_addr = 1; - break; -#if LWIP_DNS - case CI_MS_DNS1: - if (go->req_dns1 || no.req_dns1 || cilen != CILEN_ADDR) - goto bad; - GETLONG(l, p); - try_.dnsaddr[0] = lwip_htonl(l); - try_.req_dns1 = 1; - no.req_dns1 = 1; - break; - case CI_MS_DNS2: - if (go->req_dns2 || no.req_dns2 || cilen != CILEN_ADDR) - goto bad; - GETLONG(l, p); - try_.dnsaddr[1] = lwip_htonl(l); - try_.req_dns2 = 1; - no.req_dns2 = 1; - break; -#endif /* LWIP_DNS */ -#if 0 /* UNUSED - WINS */ - case CI_MS_WINS1: - case CI_MS_WINS2: - if (cilen != CILEN_ADDR) - goto bad; - GETLONG(l, p); - ciaddr1 = lwip_htonl(l); - if (ciaddr1) - try_.winsaddr[citype == CI_MS_WINS2] = ciaddr1; - break; -#endif /* UNUSED - WINS */ - default: - break; - } - p = next; - } - - /* - * OK, the Nak is good. Now we can update state. - * If there are any remaining options, we ignore them. - */ - if (f->state != PPP_FSM_OPENED) - *go = try_; - - return 1; - -bad: - IPCPDEBUG(("ipcp_nakci: received bad Nak!")); - return 0; -} - - -/* - * ipcp_rejci - Reject some of our CIs. - * Callback from fsm_rconfnakrej. - */ -static int ipcp_rejci(fsm *f, u_char *p, int len) { - ppp_pcb *pcb = f->pcb; - ipcp_options *go = &pcb->ipcp_gotoptions; - u_char cilen; -#if VJ_SUPPORT - u_char cimaxslotindex, ciflag; - u_short cishort; -#endif /* VJ_SUPPORT */ - u32_t cilong; - ipcp_options try_; /* options to request next time */ - - try_ = *go; - /* - * Any Rejected CIs must be in exactly the same order that we sent. - * Check packet length and CI length at each step. - * If we find any deviations, then this packet is bad. - */ -#define REJCIADDRS(opt, neg, val1, val2) \ - if ((neg) && \ - (cilen = p[1]) == CILEN_ADDRS && \ - len >= cilen && \ - p[0] == opt) { \ - u32_t l; \ - len -= cilen; \ - INCPTR(2, p); \ - GETLONG(l, p); \ - cilong = lwip_htonl(l); \ - /* Check rejected value. */ \ - if (cilong != val1) \ - goto bad; \ - GETLONG(l, p); \ - cilong = lwip_htonl(l); \ - /* Check rejected value. */ \ - if (cilong != val2) \ - goto bad; \ - try_.old_addrs = 0; \ - } - -#if VJ_SUPPORT -#define REJCIVJ(opt, neg, val, old, maxslot, cflag) \ - if (go->neg && \ - p[1] == (old? CILEN_COMPRESS : CILEN_VJ) && \ - len >= p[1] && \ - p[0] == opt) { \ - len -= p[1]; \ - INCPTR(2, p); \ - GETSHORT(cishort, p); \ - /* Check rejected value. */ \ - if (cishort != val) \ - goto bad; \ - if (!old) { \ - GETCHAR(cimaxslotindex, p); \ - if (cimaxslotindex != maxslot) \ - goto bad; \ - GETCHAR(ciflag, p); \ - if (ciflag != cflag) \ - goto bad; \ - } \ - try_.neg = 0; \ - } -#endif /* VJ_SUPPORT */ - -#define REJCIADDR(opt, neg, val) \ - if (go->neg && \ - (cilen = p[1]) == CILEN_ADDR && \ - len >= cilen && \ - p[0] == opt) { \ - u32_t l; \ - len -= cilen; \ - INCPTR(2, p); \ - GETLONG(l, p); \ - cilong = lwip_htonl(l); \ - /* Check rejected value. */ \ - if (cilong != val) \ - goto bad; \ - try_.neg = 0; \ - } - -#if LWIP_DNS -#define REJCIDNS(opt, neg, dnsaddr) \ - if (go->neg && \ - ((cilen = p[1]) == CILEN_ADDR) && \ - len >= cilen && \ - p[0] == opt) { \ - u32_t l; \ - len -= cilen; \ - INCPTR(2, p); \ - GETLONG(l, p); \ - cilong = lwip_htonl(l); \ - /* Check rejected value. */ \ - if (cilong != dnsaddr) \ - goto bad; \ - try_.neg = 0; \ - } -#endif /* LWIP_DNS */ - -#if 0 /* UNUSED - WINS */ -#define REJCIWINS(opt, addr) \ - if (addr && \ - ((cilen = p[1]) == CILEN_ADDR) && \ - len >= cilen && \ - p[0] == opt) { \ - u32_t l; \ - len -= cilen; \ - INCPTR(2, p); \ - GETLONG(l, p); \ - cilong = lwip_htonl(l); \ - /* Check rejected value. */ \ - if (cilong != addr) \ - goto bad; \ - try_.winsaddr[opt == CI_MS_WINS2] = 0; \ - } -#endif /* UNUSED - WINS */ - - REJCIADDRS(CI_ADDRS, !go->neg_addr && go->old_addrs, - go->ouraddr, go->hisaddr); - -#if VJ_SUPPORT - REJCIVJ(CI_COMPRESSTYPE, neg_vj, go->vj_protocol, go->old_vj, - go->maxslotindex, go->cflag); -#endif /* VJ_SUPPORT */ - - REJCIADDR(CI_ADDR, neg_addr, go->ouraddr); - -#if LWIP_DNS - REJCIDNS(CI_MS_DNS1, req_dns1, go->dnsaddr[0]); - - REJCIDNS(CI_MS_DNS2, req_dns2, go->dnsaddr[1]); -#endif /* LWIP_DNS */ - -#if 0 /* UNUSED - WINS */ - REJCIWINS(CI_MS_WINS1, go->winsaddr[0]); - - REJCIWINS(CI_MS_WINS2, go->winsaddr[1]); -#endif /* UNUSED - WINS */ - - /* - * If there are any remaining CIs, then this packet is bad. - */ - if (len != 0) - goto bad; - /* - * Now we can update state. - */ - if (f->state != PPP_FSM_OPENED) - *go = try_; - return 1; - -bad: - IPCPDEBUG(("ipcp_rejci: received bad Reject!")); - return 0; -} - - -/* - * ipcp_reqci - Check the peer's requested CIs and send appropriate response. - * Callback from fsm_rconfreq, Receive Configure Request - * - * Returns: CONFACK, CONFNAK or CONFREJ and input packet modified - * appropriately. If reject_if_disagree is non-zero, doesn't return - * CONFNAK; returns CONFREJ if it can't return CONFACK. - * - * inp = Requested CIs - * len = Length of requested CIs - */ -static int ipcp_reqci(fsm *f, u_char *inp, int *len, int reject_if_disagree) { - ppp_pcb *pcb = f->pcb; - ipcp_options *wo = &pcb->ipcp_wantoptions; - ipcp_options *ho = &pcb->ipcp_hisoptions; - ipcp_options *ao = &pcb->ipcp_allowoptions; - u_char *cip, *next; /* Pointer to current and next CIs */ - u_short cilen, citype; /* Parsed len, type */ -#if VJ_SUPPORT - u_short cishort; /* Parsed short value */ -#endif /* VJ_SUPPORT */ - u32_t tl, ciaddr1, ciaddr2;/* Parsed address values */ - int rc = CONFACK; /* Final packet return code */ - int orc; /* Individual option return code */ - u_char *p; /* Pointer to next char to parse */ - u_char *ucp = inp; /* Pointer to current output char */ - int l = *len; /* Length left */ -#if VJ_SUPPORT - u_char maxslotindex, cflag; -#endif /* VJ_SUPPORT */ -#if LWIP_DNS - int d; -#endif /* LWIP_DNS */ - - /* - * Reset all his options. - */ - BZERO(ho, sizeof(*ho)); - - /* - * Process all his options. - */ - next = inp; - while (l) { - orc = CONFACK; /* Assume success */ - cip = p = next; /* Remember begining of CI */ - if (l < 2 || /* Not enough data for CI header or */ - p[1] < 2 || /* CI length too small or */ - p[1] > l) { /* CI length too big? */ - IPCPDEBUG(("ipcp_reqci: bad CI length!")); - orc = CONFREJ; /* Reject bad CI */ - cilen = l; /* Reject till end of packet */ - l = 0; /* Don't loop again */ - goto endswitch; - } - GETCHAR(citype, p); /* Parse CI type */ - GETCHAR(cilen, p); /* Parse CI length */ - l -= cilen; /* Adjust remaining length */ - next += cilen; /* Step to next CI */ - - switch (citype) { /* Check CI type */ - case CI_ADDRS: - if (!ao->old_addrs || ho->neg_addr || - cilen != CILEN_ADDRS) { /* Check CI length */ - orc = CONFREJ; /* Reject CI */ - break; - } - - /* - * If he has no address, or if we both have his address but - * disagree about it, then NAK it with our idea. - * In particular, if we don't know his address, but he does, - * then accept it. - */ - GETLONG(tl, p); /* Parse source address (his) */ - ciaddr1 = lwip_htonl(tl); - if (ciaddr1 != wo->hisaddr - && (ciaddr1 == 0 || !wo->accept_remote)) { - orc = CONFNAK; - if (!reject_if_disagree) { - DECPTR(sizeof(u32_t), p); - tl = lwip_ntohl(wo->hisaddr); - PUTLONG(tl, p); - } - } else if (ciaddr1 == 0 && wo->hisaddr == 0) { - /* - * If neither we nor he knows his address, reject the option. - */ - orc = CONFREJ; - wo->req_addr = 0; /* don't NAK with 0.0.0.0 later */ - break; - } - - /* - * If he doesn't know our address, or if we both have our address - * but disagree about it, then NAK it with our idea. - */ - GETLONG(tl, p); /* Parse desination address (ours) */ - ciaddr2 = lwip_htonl(tl); - if (ciaddr2 != wo->ouraddr) { - if (ciaddr2 == 0 || !wo->accept_local) { - orc = CONFNAK; - if (!reject_if_disagree) { - DECPTR(sizeof(u32_t), p); - tl = lwip_ntohl(wo->ouraddr); - PUTLONG(tl, p); - } - } else { - wo->ouraddr = ciaddr2; /* accept peer's idea */ - } - } - - ho->old_addrs = 1; - ho->hisaddr = ciaddr1; - ho->ouraddr = ciaddr2; - break; - - case CI_ADDR: - if (!ao->neg_addr || ho->old_addrs || - cilen != CILEN_ADDR) { /* Check CI length */ - orc = CONFREJ; /* Reject CI */ - break; - } - - /* - * If he has no address, or if we both have his address but - * disagree about it, then NAK it with our idea. - * In particular, if we don't know his address, but he does, - * then accept it. - */ - GETLONG(tl, p); /* Parse source address (his) */ - ciaddr1 = lwip_htonl(tl); - if (ciaddr1 != wo->hisaddr - && (ciaddr1 == 0 || !wo->accept_remote)) { - orc = CONFNAK; - if (!reject_if_disagree) { - DECPTR(sizeof(u32_t), p); - tl = lwip_ntohl(wo->hisaddr); - PUTLONG(tl, p); - } - } else if (ciaddr1 == 0 && wo->hisaddr == 0) { - /* - * Don't ACK an address of 0.0.0.0 - reject it instead. - */ - orc = CONFREJ; - wo->req_addr = 0; /* don't NAK with 0.0.0.0 later */ - break; - } - - ho->neg_addr = 1; - ho->hisaddr = ciaddr1; - break; - -#if LWIP_DNS - case CI_MS_DNS1: - case CI_MS_DNS2: - /* Microsoft primary or secondary DNS request */ - d = citype == CI_MS_DNS2; - - /* If we do not have a DNS address then we cannot send it */ - if (ao->dnsaddr[d] == 0 || - cilen != CILEN_ADDR) { /* Check CI length */ - orc = CONFREJ; /* Reject CI */ - break; - } - GETLONG(tl, p); - if (lwip_htonl(tl) != ao->dnsaddr[d]) { - DECPTR(sizeof(u32_t), p); - tl = lwip_ntohl(ao->dnsaddr[d]); - PUTLONG(tl, p); - orc = CONFNAK; - } - break; -#endif /* LWIP_DNS */ - -#if 0 /* UNUSED - WINS */ - case CI_MS_WINS1: - case CI_MS_WINS2: - /* Microsoft primary or secondary WINS request */ - d = citype == CI_MS_WINS2; - - /* If we do not have a DNS address then we cannot send it */ - if (ao->winsaddr[d] == 0 || - cilen != CILEN_ADDR) { /* Check CI length */ - orc = CONFREJ; /* Reject CI */ - break; - } - GETLONG(tl, p); - if (lwip_htonl(tl) != ao->winsaddr[d]) { - DECPTR(sizeof(u32_t), p); - tl = lwip_ntohl(ao->winsaddr[d]); - PUTLONG(tl, p); - orc = CONFNAK; - } - break; -#endif /* UNUSED - WINS */ - -#if VJ_SUPPORT - case CI_COMPRESSTYPE: - if (!ao->neg_vj || - (cilen != CILEN_VJ && cilen != CILEN_COMPRESS)) { - orc = CONFREJ; - break; - } - GETSHORT(cishort, p); - - if (!(cishort == IPCP_VJ_COMP || - (cishort == IPCP_VJ_COMP_OLD && cilen == CILEN_COMPRESS))) { - orc = CONFREJ; - break; - } - - ho->neg_vj = 1; - ho->vj_protocol = cishort; - if (cilen == CILEN_VJ) { - GETCHAR(maxslotindex, p); - if (maxslotindex > ao->maxslotindex) { - orc = CONFNAK; - if (!reject_if_disagree){ - DECPTR(1, p); - PUTCHAR(ao->maxslotindex, p); - } - } - GETCHAR(cflag, p); - if (cflag && !ao->cflag) { - orc = CONFNAK; - if (!reject_if_disagree){ - DECPTR(1, p); - PUTCHAR(wo->cflag, p); - } - } - ho->maxslotindex = maxslotindex; - ho->cflag = cflag; - } else { - ho->old_vj = 1; - ho->maxslotindex = MAX_STATES - 1; - ho->cflag = 1; - } - break; -#endif /* VJ_SUPPORT */ - - default: - orc = CONFREJ; - break; - } -endswitch: - if (orc == CONFACK && /* Good CI */ - rc != CONFACK) /* but prior CI wasnt? */ - continue; /* Don't send this one */ - - if (orc == CONFNAK) { /* Nak this CI? */ - if (reject_if_disagree) /* Getting fed up with sending NAKs? */ - orc = CONFREJ; /* Get tough if so */ - else { - if (rc == CONFREJ) /* Rejecting prior CI? */ - continue; /* Don't send this one */ - if (rc == CONFACK) { /* Ack'd all prior CIs? */ - rc = CONFNAK; /* Not anymore... */ - ucp = inp; /* Backup */ - } - } - } - - if (orc == CONFREJ && /* Reject this CI */ - rc != CONFREJ) { /* but no prior ones? */ - rc = CONFREJ; - ucp = inp; /* Backup */ - } - - /* Need to move CI? */ - if (ucp != cip) - MEMCPY(ucp, cip, cilen); /* Move it */ - - /* Update output pointer */ - INCPTR(cilen, ucp); - } - - /* - * If we aren't rejecting this packet, and we want to negotiate - * their address, and they didn't send their address, then we - * send a NAK with a CI_ADDR option appended. We assume the - * input buffer is long enough that we can append the extra - * option safely. - */ - if (rc != CONFREJ && !ho->neg_addr && !ho->old_addrs && - wo->req_addr && !reject_if_disagree && !pcb->settings.noremoteip) { - if (rc == CONFACK) { - rc = CONFNAK; - ucp = inp; /* reset pointer */ - wo->req_addr = 0; /* don't ask again */ - } - PUTCHAR(CI_ADDR, ucp); - PUTCHAR(CILEN_ADDR, ucp); - tl = lwip_ntohl(wo->hisaddr); - PUTLONG(tl, ucp); - } - - *len = ucp - inp; /* Compute output length */ - IPCPDEBUG(("ipcp: returning Configure-%s", CODENAME(rc))); - return (rc); /* Return final code */ -} - - -#if 0 /* UNUSED */ -/* - * ip_check_options - check that any IP-related options are OK, - * and assign appropriate defaults. - */ -static void -ip_check_options() -{ - struct hostent *hp; - u32_t local; - ipcp_options *wo = &ipcp_wantoptions[0]; - - /* - * Default our local IP address based on our hostname. - * If local IP address already given, don't bother. - */ - if (wo->ouraddr == 0 && !disable_defaultip) { - /* - * Look up our hostname (possibly with domain name appended) - * and take the first IP address as our local IP address. - * If there isn't an IP address for our hostname, too bad. - */ - wo->accept_local = 1; /* don't insist on this default value */ - if ((hp = gethostbyname(hostname)) != NULL) { - local = *(u32_t *)hp->h_addr; - if (local != 0 && !bad_ip_adrs(local)) - wo->ouraddr = local; - } - } - ask_for_local = wo->ouraddr != 0 || !disable_defaultip; -} -#endif /* UNUSED */ - -#if DEMAND_SUPPORT -/* - * ip_demand_conf - configure the interface as though - * IPCP were up, for use with dial-on-demand. - */ -static int -ip_demand_conf(u) - int u; -{ - ppp_pcb *pcb = &ppp_pcb_list[u]; - ipcp_options *wo = &ipcp_wantoptions[u]; - - if (wo->hisaddr == 0 && !pcb->settings.noremoteip) { - /* make up an arbitrary address for the peer */ - wo->hisaddr = lwip_htonl(0x0a707070 + ifunit); - wo->accept_remote = 1; - } - if (wo->ouraddr == 0) { - /* make up an arbitrary address for us */ - wo->ouraddr = lwip_htonl(0x0a404040 + ifunit); - wo->accept_local = 1; - ask_for_local = 0; /* don't tell the peer this address */ - } - if (!sifaddr(pcb, wo->ouraddr, wo->hisaddr, get_mask(wo->ouraddr))) - return 0; - if (!sifup(pcb)) - return 0; - if (!sifnpmode(pcb, PPP_IP, NPMODE_QUEUE)) - return 0; -#if 0 /* UNUSED */ - if (wo->default_route) - if (sifdefaultroute(pcb, wo->ouraddr, wo->hisaddr, - wo->replace_default_route)) - default_route_set[u] = 1; -#endif /* UNUSED */ -#if 0 /* UNUSED - PROXY ARP */ - if (wo->proxy_arp) - if (sifproxyarp(pcb, wo->hisaddr)) - proxy_arp_set[u] = 1; -#endif /* UNUSED - PROXY ARP */ - - ppp_notice("local IP address %I", wo->ouraddr); - if (wo->hisaddr) - ppp_notice("remote IP address %I", wo->hisaddr); - - return 1; -} -#endif /* DEMAND_SUPPORT */ - -/* - * ipcp_up - IPCP has come UP. - * - * Configure the IP network interface appropriately and bring it up. - */ -static void ipcp_up(fsm *f) { - ppp_pcb *pcb = f->pcb; - u32_t mask; - ipcp_options *ho = &pcb->ipcp_hisoptions; - ipcp_options *go = &pcb->ipcp_gotoptions; - ipcp_options *wo = &pcb->ipcp_wantoptions; - - IPCPDEBUG(("ipcp: up")); - - /* - * We must have a non-zero IP address for both ends of the link. - */ - if (!ho->neg_addr && !ho->old_addrs) - ho->hisaddr = wo->hisaddr; - - if (!(go->neg_addr || go->old_addrs) && (wo->neg_addr || wo->old_addrs) - && wo->ouraddr != 0) { - ppp_error("Peer refused to agree to our IP address"); - ipcp_close(f->pcb, "Refused our IP address"); - return; - } - if (go->ouraddr == 0) { - ppp_error("Could not determine local IP address"); - ipcp_close(f->pcb, "Could not determine local IP address"); - return; - } - if (ho->hisaddr == 0 && !pcb->settings.noremoteip) { - ho->hisaddr = lwip_htonl(0x0a404040); - ppp_warn("Could not determine remote IP address: defaulting to %I", - ho->hisaddr); - } -#if 0 /* UNUSED */ - script_setenv("IPLOCAL", ip_ntoa(go->ouraddr), 0); - if (ho->hisaddr != 0) - script_setenv("IPREMOTE", ip_ntoa(ho->hisaddr), 1); -#endif /* UNUSED */ - -#if LWIP_DNS - if (!go->req_dns1) - go->dnsaddr[0] = 0; - if (!go->req_dns2) - go->dnsaddr[1] = 0; -#if 0 /* UNUSED */ - if (go->dnsaddr[0]) - script_setenv("DNS1", ip_ntoa(go->dnsaddr[0]), 0); - if (go->dnsaddr[1]) - script_setenv("DNS2", ip_ntoa(go->dnsaddr[1]), 0); -#endif /* UNUSED */ - if (pcb->settings.usepeerdns && (go->dnsaddr[0] || go->dnsaddr[1])) { - sdns(pcb, go->dnsaddr[0], go->dnsaddr[1]); -#if 0 /* UNUSED */ - script_setenv("USEPEERDNS", "1", 0); - create_resolv(go->dnsaddr[0], go->dnsaddr[1]); -#endif /* UNUSED */ - } -#endif /* LWIP_DNS */ - - /* - * Check that the peer is allowed to use the IP address it wants. - */ - if (ho->hisaddr != 0) { - u32_t addr = lwip_ntohl(ho->hisaddr); - if ((addr >> IP_CLASSA_NSHIFT) == IP_LOOPBACKNET - || IP_MULTICAST(addr) || IP_BADCLASS(addr) - /* - * For now, consider that PPP in server mode with peer required - * to authenticate must provide the peer IP address, reject any - * IP address wanted by peer different than the one we wanted. - */ -#if PPP_SERVER && PPP_AUTH_SUPPORT - || (pcb->settings.auth_required && wo->hisaddr != ho->hisaddr) -#endif /* PPP_SERVER && PPP_AUTH_SUPPORT */ - ) { - ppp_error("Peer is not authorized to use remote address %I", ho->hisaddr); - ipcp_close(pcb, "Unauthorized remote IP address"); - return; - } - } -#if 0 /* Unused */ - /* Upstream checking code */ - if (ho->hisaddr != 0 && !auth_ip_addr(f->unit, ho->hisaddr)) { - ppp_error("Peer is not authorized to use remote address %I", ho->hisaddr); - ipcp_close(f->unit, "Unauthorized remote IP address"); - return; - } -#endif /* Unused */ - -#if VJ_SUPPORT - /* set tcp compression */ - sifvjcomp(pcb, ho->neg_vj, ho->cflag, ho->maxslotindex); -#endif /* VJ_SUPPORT */ - -#if DEMAND_SUPPORT - /* - * If we are doing dial-on-demand, the interface is already - * configured, so we put out any saved-up packets, then set the - * interface to pass IP packets. - */ - if (demand) { - if (go->ouraddr != wo->ouraddr || ho->hisaddr != wo->hisaddr) { - ipcp_clear_addrs(f->unit, wo->ouraddr, wo->hisaddr, - wo->replace_default_route); - if (go->ouraddr != wo->ouraddr) { - ppp_warn("Local IP address changed to %I", go->ouraddr); - script_setenv("OLDIPLOCAL", ip_ntoa(wo->ouraddr), 0); - wo->ouraddr = go->ouraddr; - } else - script_unsetenv("OLDIPLOCAL"); - if (ho->hisaddr != wo->hisaddr && wo->hisaddr != 0) { - ppp_warn("Remote IP address changed to %I", ho->hisaddr); - script_setenv("OLDIPREMOTE", ip_ntoa(wo->hisaddr), 0); - wo->hisaddr = ho->hisaddr; - } else - script_unsetenv("OLDIPREMOTE"); - - /* Set the interface to the new addresses */ - mask = get_mask(go->ouraddr); - if (!sifaddr(pcb, go->ouraddr, ho->hisaddr, mask)) { -#if PPP_DEBUG - ppp_warn("Interface configuration failed"); -#endif /* PPP_DEBUG */ - ipcp_close(f->unit, "Interface configuration failed"); - return; - } - - /* assign a default route through the interface if required */ - if (ipcp_wantoptions[f->unit].default_route) - if (sifdefaultroute(pcb, go->ouraddr, ho->hisaddr, - wo->replace_default_route)) - default_route_set[f->unit] = 1; - -#if 0 /* UNUSED - PROXY ARP */ - /* Make a proxy ARP entry if requested. */ - if (ho->hisaddr != 0 && ipcp_wantoptions[f->unit].proxy_arp) - if (sifproxyarp(pcb, ho->hisaddr)) - proxy_arp_set[f->unit] = 1; -#endif /* UNUSED - PROXY ARP */ - - } - demand_rexmit(PPP_IP,go->ouraddr); - sifnpmode(pcb, PPP_IP, NPMODE_PASS); - - } else -#endif /* DEMAND_SUPPORT */ - { - /* - * Set IP addresses and (if specified) netmask. - */ - mask = get_mask(go->ouraddr); - -#if !(defined(SVR4) && (defined(SNI) || defined(__USLC__))) - if (!sifaddr(pcb, go->ouraddr, ho->hisaddr, mask)) { -#if PPP_DEBUG - ppp_warn("Interface configuration failed"); -#endif /* PPP_DEBUG */ - ipcp_close(f->pcb, "Interface configuration failed"); - return; - } -#endif - - /* bring the interface up for IP */ - if (!sifup(pcb)) { -#if PPP_DEBUG - ppp_warn("Interface failed to come up"); -#endif /* PPP_DEBUG */ - ipcp_close(f->pcb, "Interface configuration failed"); - return; - } - -#if (defined(SVR4) && (defined(SNI) || defined(__USLC__))) - if (!sifaddr(pcb, go->ouraddr, ho->hisaddr, mask)) { -#if PPP_DEBUG - ppp_warn("Interface configuration failed"); -#endif /* PPP_DEBUG */ - ipcp_close(f->unit, "Interface configuration failed"); - return; - } -#endif -#if DEMAND_SUPPORT - sifnpmode(pcb, PPP_IP, NPMODE_PASS); -#endif /* DEMAND_SUPPORT */ - -#if 0 /* UNUSED */ - /* assign a default route through the interface if required */ - if (wo->default_route) - if (sifdefaultroute(pcb, go->ouraddr, ho->hisaddr, - wo->replace_default_route)) - pcb->default_route_set = 1; -#endif /* UNUSED */ - -#if 0 /* UNUSED - PROXY ARP */ - /* Make a proxy ARP entry if requested. */ - if (ho->hisaddr != 0 && wo->proxy_arp) - if (sifproxyarp(pcb, ho->hisaddr)) - pcb->proxy_arp_set = 1; -#endif /* UNUSED - PROXY ARP */ - - wo->ouraddr = go->ouraddr; - - ppp_notice("local IP address %I", go->ouraddr); - if (ho->hisaddr != 0) - ppp_notice("remote IP address %I", ho->hisaddr); -#if LWIP_DNS - if (go->dnsaddr[0]) - ppp_notice("primary DNS address %I", go->dnsaddr[0]); - if (go->dnsaddr[1]) - ppp_notice("secondary DNS address %I", go->dnsaddr[1]); -#endif /* LWIP_DNS */ - } - -#if PPP_STATS_SUPPORT - reset_link_stats(f->unit); -#endif /* PPP_STATS_SUPPORT */ - - np_up(pcb, PPP_IP); - pcb->ipcp_is_up = 1; - -#if PPP_NOTIFY - notify(ip_up_notifier, 0); -#endif /* PPP_NOTIFY */ -#if 0 /* UNUSED */ - if (ip_up_hook) - ip_up_hook(); -#endif /* UNUSED */ -} - - -/* - * ipcp_down - IPCP has gone DOWN. - * - * Take the IP network interface down, clear its addresses - * and delete routes through it. - */ -static void ipcp_down(fsm *f) { - ppp_pcb *pcb = f->pcb; - ipcp_options *ho = &pcb->ipcp_hisoptions; - ipcp_options *go = &pcb->ipcp_gotoptions; - - IPCPDEBUG(("ipcp: down")); -#if PPP_STATS_SUPPORT - /* XXX a bit IPv4-centric here, we only need to get the stats - * before the interface is marked down. */ - /* XXX more correct: we must get the stats before running the notifiers, - * at least for the radius plugin */ - update_link_stats(f->unit); -#endif /* PPP_STATS_SUPPORT */ -#if PPP_NOTIFY - notify(ip_down_notifier, 0); -#endif /* PPP_NOTIFY */ -#if 0 /* UNUSED */ - if (ip_down_hook) - ip_down_hook(); -#endif /* UNUSED */ - if (pcb->ipcp_is_up) { - pcb->ipcp_is_up = 0; - np_down(pcb, PPP_IP); - } -#if VJ_SUPPORT - sifvjcomp(pcb, 0, 0, 0); -#endif /* VJ_SUPPORT */ - -#if PPP_STATS_SUPPORT - print_link_stats(); /* _after_ running the notifiers and ip_down_hook(), - * because print_link_stats() sets link_stats_valid - * to 0 (zero) */ -#endif /* PPP_STATS_SUPPORT */ - -#if DEMAND_SUPPORT - /* - * If we are doing dial-on-demand, set the interface - * to queue up outgoing packets (for now). - */ - if (demand) { - sifnpmode(pcb, PPP_IP, NPMODE_QUEUE); - } else -#endif /* DEMAND_SUPPORT */ - { -#if DEMAND_SUPPORT - sifnpmode(pcb, PPP_IP, NPMODE_DROP); -#endif /* DEMAND_SUPPORT */ - sifdown(pcb); - ipcp_clear_addrs(pcb, go->ouraddr, - ho->hisaddr, 0); -#if LWIP_DNS - cdns(pcb, go->dnsaddr[0], go->dnsaddr[1]); -#endif /* LWIP_DNS */ - } -} - - -/* - * ipcp_clear_addrs() - clear the interface addresses, routes, - * proxy arp entries, etc. - */ -static void ipcp_clear_addrs(ppp_pcb *pcb, u32_t ouraddr, u32_t hisaddr, u8_t replacedefaultroute) { - LWIP_UNUSED_ARG(replacedefaultroute); - -#if 0 /* UNUSED - PROXY ARP */ - if (pcb->proxy_arp_set) { - cifproxyarp(pcb, hisaddr); - pcb->proxy_arp_set = 0; - } -#endif /* UNUSED - PROXY ARP */ -#if 0 /* UNUSED */ - /* If replacedefaultroute, sifdefaultroute will be called soon - * with replacedefaultroute set and that will overwrite the current - * default route. This is the case only when doing demand, otherwise - * during demand, this cifdefaultroute would restore the old default - * route which is not what we want in this case. In the non-demand - * case, we'll delete the default route and restore the old if there - * is one saved by an sifdefaultroute with replacedefaultroute. - */ - if (!replacedefaultroute && pcb->default_route_set) { - cifdefaultroute(pcb, ouraddr, hisaddr); - pcb->default_route_set = 0; - } -#endif /* UNUSED */ - cifaddr(pcb, ouraddr, hisaddr); -} - - -/* - * ipcp_finished - possibly shut down the lower layers. - */ -static void ipcp_finished(fsm *f) { - ppp_pcb *pcb = f->pcb; - if (pcb->ipcp_is_open) { - pcb->ipcp_is_open = 0; - np_finished(pcb, PPP_IP); - } -} - - -#if 0 /* UNUSED */ -/* - * create_resolv - create the replacement resolv.conf file - */ -static void -create_resolv(peerdns1, peerdns2) - u32_t peerdns1, peerdns2; -{ - -} -#endif /* UNUSED */ - -#if PRINTPKT_SUPPORT -/* - * ipcp_printpkt - print the contents of an IPCP packet. - */ -static const char* const ipcp_codenames[] = { - "ConfReq", "ConfAck", "ConfNak", "ConfRej", - "TermReq", "TermAck", "CodeRej" -}; - -static int ipcp_printpkt(const u_char *p, int plen, - void (*printer) (void *, const char *, ...), void *arg) { - int code, id, len, olen; - const u_char *pstart, *optend; -#if VJ_SUPPORT - u_short cishort; -#endif /* VJ_SUPPORT */ - u32_t cilong; - - if (plen < HEADERLEN) - return 0; - pstart = p; - GETCHAR(code, p); - GETCHAR(id, p); - GETSHORT(len, p); - if (len < HEADERLEN || len > plen) - return 0; - - if (code >= 1 && code <= (int)LWIP_ARRAYSIZE(ipcp_codenames)) - printer(arg, " %s", ipcp_codenames[code-1]); - else - printer(arg, " code=0x%x", code); - printer(arg, " id=0x%x", id); - len -= HEADERLEN; - switch (code) { - case CONFREQ: - case CONFACK: - case CONFNAK: - case CONFREJ: - /* print option list */ - while (len >= 2) { - GETCHAR(code, p); - GETCHAR(olen, p); - p -= 2; - if (olen < 2 || olen > len) { - break; - } - printer(arg, " <"); - len -= olen; - optend = p + olen; - switch (code) { - case CI_ADDRS: - if (olen == CILEN_ADDRS) { - p += 2; - GETLONG(cilong, p); - printer(arg, "addrs %I", lwip_htonl(cilong)); - GETLONG(cilong, p); - printer(arg, " %I", lwip_htonl(cilong)); - } - break; -#if VJ_SUPPORT - case CI_COMPRESSTYPE: - if (olen >= CILEN_COMPRESS) { - p += 2; - GETSHORT(cishort, p); - printer(arg, "compress "); - switch (cishort) { - case IPCP_VJ_COMP: - printer(arg, "VJ"); - break; - case IPCP_VJ_COMP_OLD: - printer(arg, "old-VJ"); - break; - default: - printer(arg, "0x%x", cishort); - } - } - break; -#endif /* VJ_SUPPORT */ - case CI_ADDR: - if (olen == CILEN_ADDR) { - p += 2; - GETLONG(cilong, p); - printer(arg, "addr %I", lwip_htonl(cilong)); - } - break; -#if LWIP_DNS - case CI_MS_DNS1: - case CI_MS_DNS2: - p += 2; - GETLONG(cilong, p); - printer(arg, "ms-dns%d %I", (code == CI_MS_DNS1? 1: 2), - htonl(cilong)); - break; -#endif /* LWIP_DNS */ -#if 0 /* UNUSED - WINS */ - case CI_MS_WINS1: - case CI_MS_WINS2: - p += 2; - GETLONG(cilong, p); - printer(arg, "ms-wins %I", lwip_htonl(cilong)); - break; -#endif /* UNUSED - WINS */ - default: - break; - } - while (p < optend) { - GETCHAR(code, p); - printer(arg, " %.2x", code); - } - printer(arg, ">"); - } - break; - - case TERMACK: - case TERMREQ: - if (len > 0 && *p >= ' ' && *p < 0x7f) { - printer(arg, " "); - ppp_print_string(p, len, printer, arg); - p += len; - len = 0; - } - break; - default: - break; - } - - /* print the rest of the bytes in the packet */ - for (; len > 0; --len) { - GETCHAR(code, p); - printer(arg, " %.2x", code); - } - - return p - pstart; -} -#endif /* PRINTPKT_SUPPORT */ - -#if DEMAND_SUPPORT -/* - * ip_active_pkt - see if this IP packet is worth bringing the link up for. - * We don't bring the link up for IP fragments or for TCP FIN packets - * with no data. - */ -#define IP_HDRLEN 20 /* bytes */ -#define IP_OFFMASK 0x1fff -#ifndef IPPROTO_TCP -#define IPPROTO_TCP 6 -#endif -#define TCP_HDRLEN 20 -#define TH_FIN 0x01 - -/* - * We use these macros because the IP header may be at an odd address, - * and some compilers might use word loads to get th_off or ip_hl. - */ - -#define net_short(x) (((x)[0] << 8) + (x)[1]) -#define get_iphl(x) (((unsigned char *)(x))[0] & 0xF) -#define get_ipoff(x) net_short((unsigned char *)(x) + 6) -#define get_ipproto(x) (((unsigned char *)(x))[9]) -#define get_tcpoff(x) (((unsigned char *)(x))[12] >> 4) -#define get_tcpflags(x) (((unsigned char *)(x))[13]) - -static int -ip_active_pkt(pkt, len) - u_char *pkt; - int len; -{ - u_char *tcp; - int hlen; - - len -= PPP_HDRLEN; - pkt += PPP_HDRLEN; - if (len < IP_HDRLEN) - return 0; - if ((get_ipoff(pkt) & IP_OFFMASK) != 0) - return 0; - if (get_ipproto(pkt) != IPPROTO_TCP) - return 1; - hlen = get_iphl(pkt) * 4; - if (len < hlen + TCP_HDRLEN) - return 0; - tcp = pkt + hlen; - if ((get_tcpflags(tcp) & TH_FIN) != 0 && len == hlen + get_tcpoff(tcp) * 4) - return 0; - return 1; -} -#endif /* DEMAND_SUPPORT */ - -#endif /* PPP_SUPPORT && PPP_IPV4_SUPPORT */ diff --git a/third_party/lwip/repo/lwip/src/netif/ppp/ipv6cp.c b/third_party/lwip/repo/lwip/src/netif/ppp/ipv6cp.c deleted file mode 100644 index 11c18df743b790..00000000000000 --- a/third_party/lwip/repo/lwip/src/netif/ppp/ipv6cp.c +++ /dev/null @@ -1,1533 +0,0 @@ -/* - * ipv6cp.c - PPP IPV6 Control Protocol. - * - * Copyright (c) 1999 Tommi Komulainen. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name(s) of the authors of this software must not be used to - * endorse or promote products derived from this software without - * prior written permission. - * - * 4. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Tommi Komulainen - * ". - * - * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - */ - -/* Original version, based on RFC2023 : - - Copyright (c) 1995, 1996, 1997 Francis.Dupont@inria.fr, INRIA Rocquencourt, - Alain.Durand@imag.fr, IMAG, - Jean-Luc.Richier@imag.fr, IMAG-LSR. - - Copyright (c) 1998, 1999 Francis.Dupont@inria.fr, GIE DYADE, - Alain.Durand@imag.fr, IMAG, - Jean-Luc.Richier@imag.fr, IMAG-LSR. - - Ce travail a été fait au sein du GIE DYADE (Groupement d'Intérêt - Économique ayant pour membres BULL S.A. et l'INRIA). - - Ce logiciel informatique est disponible aux conditions - usuelles dans la recherche, c'est-à-dire qu'il peut - être utilisé, copié, modifié, distribué à l'unique - condition que ce texte soit conservé afin que - l'origine de ce logiciel soit reconnue. - - Le nom de l'Institut National de Recherche en Informatique - et en Automatique (INRIA), de l'IMAG, ou d'une personne morale - ou physique ayant participé à l'élaboration de ce logiciel ne peut - être utilisé sans son accord préalable explicite. - - Ce logiciel est fourni tel quel sans aucune garantie, - support ou responsabilité d'aucune sorte. - Ce logiciel est dérivé de sources d'origine - "University of California at Berkeley" et - "Digital Equipment Corporation" couvertes par des copyrights. - - L'Institut d'Informatique et de Mathématiques Appliquées de Grenoble (IMAG) - est une fédération d'unités mixtes de recherche du CNRS, de l'Institut National - Polytechnique de Grenoble et de l'Université Joseph Fourier regroupant - sept laboratoires dont le laboratoire Logiciels, Systèmes, Réseaux (LSR). - - This work has been done in the context of GIE DYADE (joint R & D venture - between BULL S.A. and INRIA). - - This software is available with usual "research" terms - with the aim of retain credits of the software. - Permission to use, copy, modify and distribute this software for any - purpose and without fee is hereby granted, provided that the above - copyright notice and this permission notice appear in all copies, - and the name of INRIA, IMAG, or any contributor not be used in advertising - or publicity pertaining to this material without the prior explicit - permission. The software is provided "as is" without any - warranties, support or liabilities of any kind. - This software is derived from source code from - "University of California at Berkeley" and - "Digital Equipment Corporation" protected by copyrights. - - Grenoble's Institute of Computer Science and Applied Mathematics (IMAG) - is a federation of seven research units funded by the CNRS, National - Polytechnic Institute of Grenoble and University Joseph Fourier. - The research unit in Software, Systems, Networks (LSR) is member of IMAG. -*/ - -/* - * Derived from : - * - * - * ipcp.c - PPP IP Control Protocol. - * - * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name "Carnegie Mellon University" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For permission or any legal - * details, please contact - * Office of Technology Transfer - * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu - * - * 4. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Computing Services - * at Carnegie Mellon University (http://www.cmu.edu/computing/)." - * - * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE - * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * $Id: ipv6cp.c,v 1.21 2005/08/25 23:59:34 paulus Exp $ - */ - -/* - * @todo: - * - * Proxy Neighbour Discovery. - * - * Better defines for selecting the ordering of - * interface up / set address. - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT && PPP_IPV6_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#if 0 /* UNUSED */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#endif /* UNUSED */ - -#include "netif/ppp/ppp_impl.h" -#include "netif/ppp/fsm.h" -#include "netif/ppp/ipcp.h" -#include "netif/ppp/ipv6cp.h" -#include "netif/ppp/magic.h" - -/* global vars */ -#if 0 /* UNUSED */ -int no_ifaceid_neg = 0; -#endif /* UNUSED */ - -/* - * Callbacks for fsm code. (CI = Configuration Information) - */ -static void ipv6cp_resetci(fsm *f); /* Reset our CI */ -static int ipv6cp_cilen(fsm *f); /* Return length of our CI */ -static void ipv6cp_addci(fsm *f, u_char *ucp, int *lenp); /* Add our CI */ -static int ipv6cp_ackci(fsm *f, u_char *p, int len); /* Peer ack'd our CI */ -static int ipv6cp_nakci(fsm *f, u_char *p, int len, int treat_as_reject); /* Peer nak'd our CI */ -static int ipv6cp_rejci(fsm *f, u_char *p, int len); /* Peer rej'd our CI */ -static int ipv6cp_reqci(fsm *f, u_char *inp, int *len, int reject_if_disagree); /* Rcv CI */ -static void ipv6cp_up(fsm *f); /* We're UP */ -static void ipv6cp_down(fsm *f); /* We're DOWN */ -static void ipv6cp_finished(fsm *f); /* Don't need lower layer */ - -static const fsm_callbacks ipv6cp_callbacks = { /* IPV6CP callback routines */ - ipv6cp_resetci, /* Reset our Configuration Information */ - ipv6cp_cilen, /* Length of our Configuration Information */ - ipv6cp_addci, /* Add our Configuration Information */ - ipv6cp_ackci, /* ACK our Configuration Information */ - ipv6cp_nakci, /* NAK our Configuration Information */ - ipv6cp_rejci, /* Reject our Configuration Information */ - ipv6cp_reqci, /* Request peer's Configuration Information */ - ipv6cp_up, /* Called when fsm reaches OPENED state */ - ipv6cp_down, /* Called when fsm leaves OPENED state */ - NULL, /* Called when we want the lower layer up */ - ipv6cp_finished, /* Called when we want the lower layer down */ - NULL, /* Called when Protocol-Reject received */ - NULL, /* Retransmission is necessary */ - NULL, /* Called to handle protocol-specific codes */ - "IPV6CP" /* String name of protocol */ -}; - -#if PPP_OPTIONS -/* - * Command-line options. - */ -static int setifaceid(char **arg)); -static void printifaceid(option_t *, - void (*)(void *, char *, ...), void *)); - -static option_t ipv6cp_option_list[] = { - { "ipv6", o_special, (void *)setifaceid, - "Set interface identifiers for IPV6", - OPT_A2PRINTER, (void *)printifaceid }, - - { "+ipv6", o_bool, &ipv6cp_protent.enabled_flag, - "Enable IPv6 and IPv6CP", OPT_PRIO | 1 }, - { "noipv6", o_bool, &ipv6cp_protent.enabled_flag, - "Disable IPv6 and IPv6CP", OPT_PRIOSUB }, - { "-ipv6", o_bool, &ipv6cp_protent.enabled_flag, - "Disable IPv6 and IPv6CP", OPT_PRIOSUB | OPT_ALIAS }, - - { "ipv6cp-accept-local", o_bool, &ipv6cp_allowoptions[0].accept_local, - "Accept peer's interface identifier for us", 1 }, - - { "ipv6cp-use-ipaddr", o_bool, &ipv6cp_allowoptions[0].use_ip, - "Use (default) IPv4 address as interface identifier", 1 }, - - { "ipv6cp-use-persistent", o_bool, &ipv6cp_wantoptions[0].use_persistent, - "Use uniquely-available persistent value for link local address", 1 }, - - { "ipv6cp-restart", o_int, &ipv6cp_fsm[0].timeouttime, - "Set timeout for IPv6CP", OPT_PRIO }, - { "ipv6cp-max-terminate", o_int, &ipv6cp_fsm[0].maxtermtransmits, - "Set max #xmits for term-reqs", OPT_PRIO }, - { "ipv6cp-max-configure", o_int, &ipv6cp_fsm[0].maxconfreqtransmits, - "Set max #xmits for conf-reqs", OPT_PRIO }, - { "ipv6cp-max-failure", o_int, &ipv6cp_fsm[0].maxnakloops, - "Set max #conf-naks for IPv6CP", OPT_PRIO }, - - { NULL } -}; -#endif /* PPP_OPTIONS */ - -/* - * Protocol entry points from main code. - */ -static void ipv6cp_init(ppp_pcb *pcb); -static void ipv6cp_open(ppp_pcb *pcb); -static void ipv6cp_close(ppp_pcb *pcb, const char *reason); -static void ipv6cp_lowerup(ppp_pcb *pcb); -static void ipv6cp_lowerdown(ppp_pcb *pcb); -static void ipv6cp_input(ppp_pcb *pcb, u_char *p, int len); -static void ipv6cp_protrej(ppp_pcb *pcb); -#if PPP_OPTIONS -static void ipv6_check_options(void); -#endif /* PPP_OPTIONS */ -#if DEMAND_SUPPORT -static int ipv6_demand_conf(int u); -#endif /* DEMAND_SUPPORT */ -#if PRINTPKT_SUPPORT -static int ipv6cp_printpkt(const u_char *p, int plen, - void (*printer)(void *, const char *, ...), void *arg); -#endif /* PRINTPKT_SUPPORT */ -#if DEMAND_SUPPORT -static int ipv6_active_pkt(u_char *pkt, int len); -#endif /* DEMAND_SUPPORT */ - -const struct protent ipv6cp_protent = { - PPP_IPV6CP, - ipv6cp_init, - ipv6cp_input, - ipv6cp_protrej, - ipv6cp_lowerup, - ipv6cp_lowerdown, - ipv6cp_open, - ipv6cp_close, -#if PRINTPKT_SUPPORT - ipv6cp_printpkt, -#endif /* PRINTPKT_SUPPORT */ -#if PPP_DATAINPUT - NULL, -#endif /* PPP_DATAINPUT */ -#if PRINTPKT_SUPPORT - "IPV6CP", - "IPV6", -#endif /* PRINTPKT_SUPPORT */ -#if PPP_OPTIONS - ipv6cp_option_list, - ipv6_check_options, -#endif /* PPP_OPTIONS */ -#if DEMAND_SUPPORT - ipv6_demand_conf, - ipv6_active_pkt -#endif /* DEMAND_SUPPORT */ -}; - -static void ipv6cp_clear_addrs(ppp_pcb *pcb, eui64_t ourid, eui64_t hisid); -#if 0 /* UNUSED */ -static void ipv6cp_script(char *)); -static void ipv6cp_script_done(void *)); -#endif /* UNUSED */ - -/* - * Lengths of configuration options. - */ -#define CILEN_VOID 2 -#define CILEN_COMPRESS 4 /* length for RFC2023 compress opt. */ -#define CILEN_IFACEID 10 /* RFC2472, interface identifier */ - -#define CODENAME(x) ((x) == CONFACK ? "ACK" : \ - (x) == CONFNAK ? "NAK" : "REJ") - -#if 0 /* UNUSED */ -/* - * This state variable is used to ensure that we don't - * run an ipcp-up/down script while one is already running. - */ -static enum script_state { - s_down, - s_up, -} ipv6cp_script_state; -static pid_t ipv6cp_script_pid; -#endif /* UNUSED */ - -static char *llv6_ntoa(eui64_t ifaceid); - -#if PPP_OPTIONS -/* - * setifaceid - set the interface identifiers manually - */ -static int -setifaceid(argv) - char **argv; -{ - char *comma, *arg, c; - ipv6cp_options *wo = &ipv6cp_wantoptions[0]; - struct in6_addr addr; - static int prio_local, prio_remote; - -#define VALIDID(a) ( (((a).s6_addr32[0] == 0) && ((a).s6_addr32[1] == 0)) && \ - (((a).s6_addr32[2] != 0) || ((a).s6_addr32[3] != 0)) ) - - arg = *argv; - if ((comma = strchr(arg, ',')) == NULL) - comma = arg + strlen(arg); - - /* - * If comma first character, then no local identifier - */ - if (comma != arg) { - c = *comma; - *comma = '\0'; - - if (inet_pton(AF_INET6, arg, &addr) == 0 || !VALIDID(addr)) { - option_error("Illegal interface identifier (local): %s", arg); - return 0; - } - - if (option_priority >= prio_local) { - eui64_copy(addr.s6_addr32[2], wo->ourid); - wo->opt_local = 1; - prio_local = option_priority; - } - *comma = c; - } - - /* - * If comma last character, the no remote identifier - */ - if (*comma != 0 && *++comma != '\0') { - if (inet_pton(AF_INET6, comma, &addr) == 0 || !VALIDID(addr)) { - option_error("Illegal interface identifier (remote): %s", comma); - return 0; - } - if (option_priority >= prio_remote) { - eui64_copy(addr.s6_addr32[2], wo->hisid); - wo->opt_remote = 1; - prio_remote = option_priority; - } - } - - if (override_value("+ipv6", option_priority, option_source)) - ipv6cp_protent.enabled_flag = 1; - return 1; -} - -static void -printifaceid(opt, printer, arg) - option_t *opt; - void (*printer)(void *, char *, ...)); - void *arg; -{ - ipv6cp_options *wo = &ipv6cp_wantoptions[0]; - - if (wo->opt_local) - printer(arg, "%s", llv6_ntoa(wo->ourid)); - printer(arg, ","); - if (wo->opt_remote) - printer(arg, "%s", llv6_ntoa(wo->hisid)); -} -#endif /* PPP_OPTIONS */ - -/* - * Make a string representation of a network address. - */ -static char * -llv6_ntoa(eui64_t ifaceid) -{ - static char b[26]; - - sprintf(b, "fe80::%02x%02x:%02x%02x:%02x%02x:%02x%02x", - ifaceid.e8[0], ifaceid.e8[1], ifaceid.e8[2], ifaceid.e8[3], - ifaceid.e8[4], ifaceid.e8[5], ifaceid.e8[6], ifaceid.e8[7]); - - return b; -} - - -/* - * ipv6cp_init - Initialize IPV6CP. - */ -static void ipv6cp_init(ppp_pcb *pcb) { - fsm *f = &pcb->ipv6cp_fsm; - ipv6cp_options *wo = &pcb->ipv6cp_wantoptions; - ipv6cp_options *ao = &pcb->ipv6cp_allowoptions; - - f->pcb = pcb; - f->protocol = PPP_IPV6CP; - f->callbacks = &ipv6cp_callbacks; - fsm_init(f); - -#if 0 /* Not necessary, everything is cleared in ppp_new() */ - memset(wo, 0, sizeof(*wo)); - memset(ao, 0, sizeof(*ao)); -#endif /* 0 */ - - wo->accept_local = 1; - wo->neg_ifaceid = 1; - ao->neg_ifaceid = 1; - -#ifdef IPV6CP_COMP - wo->neg_vj = 1; - ao->neg_vj = 1; - wo->vj_protocol = IPV6CP_COMP; -#endif - -} - - -/* - * ipv6cp_open - IPV6CP is allowed to come up. - */ -static void ipv6cp_open(ppp_pcb *pcb) { - fsm_open(&pcb->ipv6cp_fsm); -} - - -/* - * ipv6cp_close - Take IPV6CP down. - */ -static void ipv6cp_close(ppp_pcb *pcb, const char *reason) { - fsm_close(&pcb->ipv6cp_fsm, reason); -} - - -/* - * ipv6cp_lowerup - The lower layer is up. - */ -static void ipv6cp_lowerup(ppp_pcb *pcb) { - fsm_lowerup(&pcb->ipv6cp_fsm); -} - - -/* - * ipv6cp_lowerdown - The lower layer is down. - */ -static void ipv6cp_lowerdown(ppp_pcb *pcb) { - fsm_lowerdown(&pcb->ipv6cp_fsm); -} - - -/* - * ipv6cp_input - Input IPV6CP packet. - */ -static void ipv6cp_input(ppp_pcb *pcb, u_char *p, int len) { - fsm_input(&pcb->ipv6cp_fsm, p, len); -} - - -/* - * ipv6cp_protrej - A Protocol-Reject was received for IPV6CP. - * - * Pretend the lower layer went down, so we shut up. - */ -static void ipv6cp_protrej(ppp_pcb *pcb) { - fsm_lowerdown(&pcb->ipv6cp_fsm); -} - - -/* - * ipv6cp_resetci - Reset our CI. - */ -static void ipv6cp_resetci(fsm *f) { - ppp_pcb *pcb = f->pcb; - ipv6cp_options *wo = &pcb->ipv6cp_wantoptions; - ipv6cp_options *go = &pcb->ipv6cp_gotoptions; - ipv6cp_options *ao = &pcb->ipv6cp_allowoptions; - - wo->req_ifaceid = wo->neg_ifaceid && ao->neg_ifaceid; - - if (!wo->opt_local) { - eui64_magic_nz(wo->ourid); - } - - *go = *wo; - eui64_zero(go->hisid); /* last proposed interface identifier */ -} - - -/* - * ipv6cp_cilen - Return length of our CI. - */ -static int ipv6cp_cilen(fsm *f) { - ppp_pcb *pcb = f->pcb; - ipv6cp_options *go = &pcb->ipv6cp_gotoptions; - -#ifdef IPV6CP_COMP -#define LENCIVJ(neg) (neg ? CILEN_COMPRESS : 0) -#endif /* IPV6CP_COMP */ -#define LENCIIFACEID(neg) (neg ? CILEN_IFACEID : 0) - - return (LENCIIFACEID(go->neg_ifaceid) + -#ifdef IPV6CP_COMP - LENCIVJ(go->neg_vj) + -#endif /* IPV6CP_COMP */ - 0); -} - - -/* - * ipv6cp_addci - Add our desired CIs to a packet. - */ -static void ipv6cp_addci(fsm *f, u_char *ucp, int *lenp) { - ppp_pcb *pcb = f->pcb; - ipv6cp_options *go = &pcb->ipv6cp_gotoptions; - int len = *lenp; - -#ifdef IPV6CP_COMP -#define ADDCIVJ(opt, neg, val) \ - if (neg) { \ - int vjlen = CILEN_COMPRESS; \ - if (len >= vjlen) { \ - PUTCHAR(opt, ucp); \ - PUTCHAR(vjlen, ucp); \ - PUTSHORT(val, ucp); \ - len -= vjlen; \ - } else \ - neg = 0; \ - } -#endif /* IPV6CP_COMP */ - -#define ADDCIIFACEID(opt, neg, val1) \ - if (neg) { \ - int idlen = CILEN_IFACEID; \ - if (len >= idlen) { \ - PUTCHAR(opt, ucp); \ - PUTCHAR(idlen, ucp); \ - eui64_put(val1, ucp); \ - len -= idlen; \ - } else \ - neg = 0; \ - } - - ADDCIIFACEID(CI_IFACEID, go->neg_ifaceid, go->ourid); - -#ifdef IPV6CP_COMP - ADDCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol); -#endif /* IPV6CP_COMP */ - - *lenp -= len; -} - - -/* - * ipv6cp_ackci - Ack our CIs. - * - * Returns: - * 0 - Ack was bad. - * 1 - Ack was good. - */ -static int ipv6cp_ackci(fsm *f, u_char *p, int len) { - ppp_pcb *pcb = f->pcb; - ipv6cp_options *go = &pcb->ipv6cp_gotoptions; - u_short cilen, citype; -#ifdef IPV6CP_COMP - u_short cishort; -#endif /* IPV6CP_COMP */ - eui64_t ifaceid; - - /* - * CIs must be in exactly the same order that we sent... - * Check packet length and CI length at each step. - * If we find any deviations, then this packet is bad. - */ - -#ifdef IPV6CP_COMP -#define ACKCIVJ(opt, neg, val) \ - if (neg) { \ - int vjlen = CILEN_COMPRESS; \ - if ((len -= vjlen) < 0) \ - goto bad; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != vjlen || \ - citype != opt) \ - goto bad; \ - GETSHORT(cishort, p); \ - if (cishort != val) \ - goto bad; \ - } -#endif /* IPV6CP_COMP */ - -#define ACKCIIFACEID(opt, neg, val1) \ - if (neg) { \ - int idlen = CILEN_IFACEID; \ - if ((len -= idlen) < 0) \ - goto bad; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != idlen || \ - citype != opt) \ - goto bad; \ - eui64_get(ifaceid, p); \ - if (! eui64_equals(val1, ifaceid)) \ - goto bad; \ - } - - ACKCIIFACEID(CI_IFACEID, go->neg_ifaceid, go->ourid); - -#ifdef IPV6CP_COMP - ACKCIVJ(CI_COMPRESSTYPE, go->neg_vj, go->vj_protocol); -#endif /* IPV6CP_COMP */ - - /* - * If there are any remaining CIs, then this packet is bad. - */ - if (len != 0) - goto bad; - return (1); - -bad: - IPV6CPDEBUG(("ipv6cp_ackci: received bad Ack!")); - return (0); -} - -/* - * ipv6cp_nakci - Peer has sent a NAK for some of our CIs. - * This should not modify any state if the Nak is bad - * or if IPV6CP is in the OPENED state. - * - * Returns: - * 0 - Nak was bad. - * 1 - Nak was good. - */ -static int ipv6cp_nakci(fsm *f, u_char *p, int len, int treat_as_reject) { - ppp_pcb *pcb = f->pcb; - ipv6cp_options *go = &pcb->ipv6cp_gotoptions; - u_char citype, cilen, *next; -#ifdef IPV6CP_COMP - u_short cishort; -#endif /* IPV6CP_COMP */ - eui64_t ifaceid; - ipv6cp_options no; /* options we've seen Naks for */ - ipv6cp_options try_; /* options to request next time */ - - BZERO(&no, sizeof(no)); - try_ = *go; - - /* - * Any Nak'd CIs must be in exactly the same order that we sent. - * Check packet length and CI length at each step. - * If we find any deviations, then this packet is bad. - */ -#define NAKCIIFACEID(opt, neg, code) \ - if (go->neg && \ - len >= (cilen = CILEN_IFACEID) && \ - p[1] == cilen && \ - p[0] == opt) { \ - len -= cilen; \ - INCPTR(2, p); \ - eui64_get(ifaceid, p); \ - no.neg = 1; \ - code \ - } - -#ifdef IPV6CP_COMP -#define NAKCIVJ(opt, neg, code) \ - if (go->neg && \ - ((cilen = p[1]) == CILEN_COMPRESS) && \ - len >= cilen && \ - p[0] == opt) { \ - len -= cilen; \ - INCPTR(2, p); \ - GETSHORT(cishort, p); \ - no.neg = 1; \ - code \ - } -#endif /* IPV6CP_COMP */ - - /* - * Accept the peer's idea of {our,his} interface identifier, if different - * from our idea, only if the accept_{local,remote} flag is set. - */ - NAKCIIFACEID(CI_IFACEID, neg_ifaceid, - if (treat_as_reject) { - try_.neg_ifaceid = 0; - } else if (go->accept_local) { - while (eui64_iszero(ifaceid) || - eui64_equals(ifaceid, go->hisid)) /* bad luck */ - eui64_magic(ifaceid); - try_.ourid = ifaceid; - IPV6CPDEBUG(("local LL address %s", llv6_ntoa(ifaceid))); - } - ); - -#ifdef IPV6CP_COMP - NAKCIVJ(CI_COMPRESSTYPE, neg_vj, - { - if (cishort == IPV6CP_COMP && !treat_as_reject) { - try_.vj_protocol = cishort; - } else { - try_.neg_vj = 0; - } - } - ); -#endif /* IPV6CP_COMP */ - - /* - * There may be remaining CIs, if the peer is requesting negotiation - * on an option that we didn't include in our request packet. - * If they want to negotiate about interface identifier, we comply. - * If they want us to ask for compression, we refuse. - */ - while (len >= CILEN_VOID) { - GETCHAR(citype, p); - GETCHAR(cilen, p); - if ( cilen < CILEN_VOID || (len -= cilen) < 0 ) - goto bad; - next = p + cilen - 2; - - switch (citype) { -#ifdef IPV6CP_COMP - case CI_COMPRESSTYPE: - if (go->neg_vj || no.neg_vj || - (cilen != CILEN_COMPRESS)) - goto bad; - no.neg_vj = 1; - break; -#endif /* IPV6CP_COMP */ - case CI_IFACEID: - if (go->neg_ifaceid || no.neg_ifaceid || cilen != CILEN_IFACEID) - goto bad; - try_.neg_ifaceid = 1; - eui64_get(ifaceid, p); - if (go->accept_local) { - while (eui64_iszero(ifaceid) || - eui64_equals(ifaceid, go->hisid)) /* bad luck */ - eui64_magic(ifaceid); - try_.ourid = ifaceid; - } - no.neg_ifaceid = 1; - break; - default: - break; - } - p = next; - } - - /* If there is still anything left, this packet is bad. */ - if (len != 0) - goto bad; - - /* - * OK, the Nak is good. Now we can update state. - */ - if (f->state != PPP_FSM_OPENED) - *go = try_; - - return 1; - -bad: - IPV6CPDEBUG(("ipv6cp_nakci: received bad Nak!")); - return 0; -} - - -/* - * ipv6cp_rejci - Reject some of our CIs. - */ -static int ipv6cp_rejci(fsm *f, u_char *p, int len) { - ppp_pcb *pcb = f->pcb; - ipv6cp_options *go = &pcb->ipv6cp_gotoptions; - u_char cilen; -#ifdef IPV6CP_COMP - u_short cishort; -#endif /* IPV6CP_COMP */ - eui64_t ifaceid; - ipv6cp_options try_; /* options to request next time */ - - try_ = *go; - /* - * Any Rejected CIs must be in exactly the same order that we sent. - * Check packet length and CI length at each step. - * If we find any deviations, then this packet is bad. - */ -#define REJCIIFACEID(opt, neg, val1) \ - if (go->neg && \ - len >= (cilen = CILEN_IFACEID) && \ - p[1] == cilen && \ - p[0] == opt) { \ - len -= cilen; \ - INCPTR(2, p); \ - eui64_get(ifaceid, p); \ - /* Check rejected value. */ \ - if (! eui64_equals(ifaceid, val1)) \ - goto bad; \ - try_.neg = 0; \ - } - -#ifdef IPV6CP_COMP -#define REJCIVJ(opt, neg, val) \ - if (go->neg && \ - p[1] == CILEN_COMPRESS && \ - len >= p[1] && \ - p[0] == opt) { \ - len -= p[1]; \ - INCPTR(2, p); \ - GETSHORT(cishort, p); \ - /* Check rejected value. */ \ - if (cishort != val) \ - goto bad; \ - try_.neg = 0; \ - } -#endif /* IPV6CP_COMP */ - - REJCIIFACEID(CI_IFACEID, neg_ifaceid, go->ourid); - -#ifdef IPV6CP_COMP - REJCIVJ(CI_COMPRESSTYPE, neg_vj, go->vj_protocol); -#endif /* IPV6CP_COMP */ - - /* - * If there are any remaining CIs, then this packet is bad. - */ - if (len != 0) - goto bad; - /* - * Now we can update state. - */ - if (f->state != PPP_FSM_OPENED) - *go = try_; - return 1; - -bad: - IPV6CPDEBUG(("ipv6cp_rejci: received bad Reject!")); - return 0; -} - - -/* - * ipv6cp_reqci - Check the peer's requested CIs and send appropriate response. - * - * Returns: CONFACK, CONFNAK or CONFREJ and input packet modified - * appropriately. If reject_if_disagree is non-zero, doesn't return - * CONFNAK; returns CONFREJ if it can't return CONFACK. - * - * inp = Requested CIs - * len = Length of requested CIs - * - */ -static int ipv6cp_reqci(fsm *f, u_char *inp, int *len, int reject_if_disagree) { - ppp_pcb *pcb = f->pcb; - ipv6cp_options *wo = &pcb->ipv6cp_wantoptions; - ipv6cp_options *ho = &pcb->ipv6cp_hisoptions; - ipv6cp_options *ao = &pcb->ipv6cp_allowoptions; - ipv6cp_options *go = &pcb->ipv6cp_gotoptions; - u_char *cip, *next; /* Pointer to current and next CIs */ - u_short cilen, citype; /* Parsed len, type */ -#ifdef IPV6CP_COMP - u_short cishort; /* Parsed short value */ -#endif /* IPV6CP_COMP */ - eui64_t ifaceid; /* Parsed interface identifier */ - int rc = CONFACK; /* Final packet return code */ - int orc; /* Individual option return code */ - u_char *p; /* Pointer to next char to parse */ - u_char *ucp = inp; /* Pointer to current output char */ - int l = *len; /* Length left */ - - /* - * Reset all his options. - */ - BZERO(ho, sizeof(*ho)); - - /* - * Process all his options. - */ - next = inp; - while (l) { - orc = CONFACK; /* Assume success */ - cip = p = next; /* Remember begining of CI */ - if (l < 2 || /* Not enough data for CI header or */ - p[1] < 2 || /* CI length too small or */ - p[1] > l) { /* CI length too big? */ - IPV6CPDEBUG(("ipv6cp_reqci: bad CI length!")); - orc = CONFREJ; /* Reject bad CI */ - cilen = l; /* Reject till end of packet */ - l = 0; /* Don't loop again */ - goto endswitch; - } - GETCHAR(citype, p); /* Parse CI type */ - GETCHAR(cilen, p); /* Parse CI length */ - l -= cilen; /* Adjust remaining length */ - next += cilen; /* Step to next CI */ - - switch (citype) { /* Check CI type */ - case CI_IFACEID: - IPV6CPDEBUG(("ipv6cp: received interface identifier ")); - - if (!ao->neg_ifaceid || - cilen != CILEN_IFACEID) { /* Check CI length */ - orc = CONFREJ; /* Reject CI */ - break; - } - - /* - * If he has no interface identifier, or if we both have same - * identifier then NAK it with new idea. - * In particular, if we don't know his identifier, but he does, - * then accept it. - */ - eui64_get(ifaceid, p); - IPV6CPDEBUG(("(%s)", llv6_ntoa(ifaceid))); - if (eui64_iszero(ifaceid) && eui64_iszero(go->ourid)) { - orc = CONFREJ; /* Reject CI */ - break; - } - if (!eui64_iszero(wo->hisid) && - !eui64_equals(ifaceid, wo->hisid) && - eui64_iszero(go->hisid)) { - - orc = CONFNAK; - ifaceid = wo->hisid; - go->hisid = ifaceid; - DECPTR(sizeof(ifaceid), p); - eui64_put(ifaceid, p); - } else - if (eui64_iszero(ifaceid) || eui64_equals(ifaceid, go->ourid)) { - orc = CONFNAK; - if (eui64_iszero(go->hisid)) /* first time, try option */ - ifaceid = wo->hisid; - while (eui64_iszero(ifaceid) || - eui64_equals(ifaceid, go->ourid)) /* bad luck */ - eui64_magic(ifaceid); - go->hisid = ifaceid; - DECPTR(sizeof(ifaceid), p); - eui64_put(ifaceid, p); - } - - ho->neg_ifaceid = 1; - ho->hisid = ifaceid; - break; - -#ifdef IPV6CP_COMP - case CI_COMPRESSTYPE: - IPV6CPDEBUG(("ipv6cp: received COMPRESSTYPE ")); - if (!ao->neg_vj || - (cilen != CILEN_COMPRESS)) { - orc = CONFREJ; - break; - } - GETSHORT(cishort, p); - IPV6CPDEBUG(("(%d)", cishort)); - - if (!(cishort == IPV6CP_COMP)) { - orc = CONFREJ; - break; - } - - ho->neg_vj = 1; - ho->vj_protocol = cishort; - break; -#endif /* IPV6CP_COMP */ - - default: - orc = CONFREJ; - break; - } - -endswitch: - IPV6CPDEBUG((" (%s)\n", CODENAME(orc))); - - if (orc == CONFACK && /* Good CI */ - rc != CONFACK) /* but prior CI wasnt? */ - continue; /* Don't send this one */ - - if (orc == CONFNAK) { /* Nak this CI? */ - if (reject_if_disagree) /* Getting fed up with sending NAKs? */ - orc = CONFREJ; /* Get tough if so */ - else { - if (rc == CONFREJ) /* Rejecting prior CI? */ - continue; /* Don't send this one */ - if (rc == CONFACK) { /* Ack'd all prior CIs? */ - rc = CONFNAK; /* Not anymore... */ - ucp = inp; /* Backup */ - } - } - } - - if (orc == CONFREJ && /* Reject this CI */ - rc != CONFREJ) { /* but no prior ones? */ - rc = CONFREJ; - ucp = inp; /* Backup */ - } - - /* Need to move CI? */ - if (ucp != cip) - MEMCPY(ucp, cip, cilen); /* Move it */ - - /* Update output pointer */ - INCPTR(cilen, ucp); - } - - /* - * If we aren't rejecting this packet, and we want to negotiate - * their identifier and they didn't send their identifier, then we - * send a NAK with a CI_IFACEID option appended. We assume the - * input buffer is long enough that we can append the extra - * option safely. - */ - if (rc != CONFREJ && !ho->neg_ifaceid && - wo->req_ifaceid && !reject_if_disagree) { - if (rc == CONFACK) { - rc = CONFNAK; - ucp = inp; /* reset pointer */ - wo->req_ifaceid = 0; /* don't ask again */ - } - PUTCHAR(CI_IFACEID, ucp); - PUTCHAR(CILEN_IFACEID, ucp); - eui64_put(wo->hisid, ucp); - } - - *len = ucp - inp; /* Compute output length */ - IPV6CPDEBUG(("ipv6cp: returning Configure-%s", CODENAME(rc))); - return (rc); /* Return final code */ -} - -#if PPP_OPTIONS -/* - * ipv6_check_options - check that any IP-related options are OK, - * and assign appropriate defaults. - */ -static void ipv6_check_options() { - ipv6cp_options *wo = &ipv6cp_wantoptions[0]; - - if (!ipv6cp_protent.enabled_flag) - return; - - /* - * Persistent link-local id is only used when user has not explicitly - * configure/hard-code the id - */ - if ((wo->use_persistent) && (!wo->opt_local) && (!wo->opt_remote)) { - - /* - * On systems where there are no Ethernet interfaces used, there - * may be other ways to obtain a persistent id. Right now, it - * will fall back to using magic [see eui64_magic] below when - * an EUI-48 from MAC address can't be obtained. Other possibilities - * include obtaining EEPROM serial numbers, or some other unique - * yet persistent number. On Sparc platforms, this is possible, - * but too bad there's no standards yet for x86 machines. - */ - if (ether_to_eui64(&wo->ourid)) { - wo->opt_local = 1; - } - } - - if (!wo->opt_local) { /* init interface identifier */ - if (wo->use_ip && eui64_iszero(wo->ourid)) { - eui64_setlo32(wo->ourid, lwip_ntohl(ipcp_wantoptions[0].ouraddr)); - if (!eui64_iszero(wo->ourid)) - wo->opt_local = 1; - } - - while (eui64_iszero(wo->ourid)) - eui64_magic(wo->ourid); - } - - if (!wo->opt_remote) { - if (wo->use_ip && eui64_iszero(wo->hisid)) { - eui64_setlo32(wo->hisid, lwip_ntohl(ipcp_wantoptions[0].hisaddr)); - if (!eui64_iszero(wo->hisid)) - wo->opt_remote = 1; - } - } - - if (demand && (eui64_iszero(wo->ourid) || eui64_iszero(wo->hisid))) { - option_error("local/remote LL address required for demand-dialling\n"); - exit(1); - } -} -#endif /* PPP_OPTIONS */ - -#if DEMAND_SUPPORT -/* - * ipv6_demand_conf - configure the interface as though - * IPV6CP were up, for use with dial-on-demand. - */ -static int ipv6_demand_conf(int u) { - ipv6cp_options *wo = &ipv6cp_wantoptions[u]; - - if (!sif6up(u)) - return 0; - - if (!sif6addr(u, wo->ourid, wo->hisid)) - return 0; - - if (!sifnpmode(u, PPP_IPV6, NPMODE_QUEUE)) - return 0; - - ppp_notice("ipv6_demand_conf"); - ppp_notice("local LL address %s", llv6_ntoa(wo->ourid)); - ppp_notice("remote LL address %s", llv6_ntoa(wo->hisid)); - - return 1; -} -#endif /* DEMAND_SUPPORT */ - - -/* - * ipv6cp_up - IPV6CP has come UP. - * - * Configure the IPv6 network interface appropriately and bring it up. - */ -static void ipv6cp_up(fsm *f) { - ppp_pcb *pcb = f->pcb; - ipv6cp_options *wo = &pcb->ipv6cp_wantoptions; - ipv6cp_options *ho = &pcb->ipv6cp_hisoptions; - ipv6cp_options *go = &pcb->ipv6cp_gotoptions; - - IPV6CPDEBUG(("ipv6cp: up")); - - /* - * We must have a non-zero LL address for both ends of the link. - */ - if (!ho->neg_ifaceid) - ho->hisid = wo->hisid; - -#if 0 /* UNUSED */ - if(!no_ifaceid_neg) { -#endif /* UNUSED */ - if (eui64_iszero(ho->hisid)) { - ppp_error("Could not determine remote LL address"); - ipv6cp_close(f->pcb, "Could not determine remote LL address"); - return; - } - if (eui64_iszero(go->ourid)) { - ppp_error("Could not determine local LL address"); - ipv6cp_close(f->pcb, "Could not determine local LL address"); - return; - } - if (eui64_equals(go->ourid, ho->hisid)) { - ppp_error("local and remote LL addresses are equal"); - ipv6cp_close(f->pcb, "local and remote LL addresses are equal"); - return; - } -#if 0 /* UNUSED */ - } -#endif /* UNUSED */ -#if 0 /* UNUSED */ - script_setenv("LLLOCAL", llv6_ntoa(go->ourid), 0); - script_setenv("LLREMOTE", llv6_ntoa(ho->hisid), 0); -#endif /* UNUSED */ - -#ifdef IPV6CP_COMP - /* set tcp compression */ - sif6comp(f->unit, ho->neg_vj); -#endif - -#if DEMAND_SUPPORT - /* - * If we are doing dial-on-demand, the interface is already - * configured, so we put out any saved-up packets, then set the - * interface to pass IPv6 packets. - */ - if (demand) { - if (! eui64_equals(go->ourid, wo->ourid) || - ! eui64_equals(ho->hisid, wo->hisid)) { - if (! eui64_equals(go->ourid, wo->ourid)) - warn("Local LL address changed to %s", - llv6_ntoa(go->ourid)); - if (! eui64_equals(ho->hisid, wo->hisid)) - warn("Remote LL address changed to %s", - llv6_ntoa(ho->hisid)); - ipv6cp_clear_addrs(f->pcb, go->ourid, ho->hisid); - - /* Set the interface to the new addresses */ - if (!sif6addr(f->pcb, go->ourid, ho->hisid)) { - if (debug) - warn("sif6addr failed"); - ipv6cp_close(f->unit, "Interface configuration failed"); - return; - } - - } - demand_rexmit(PPP_IPV6); - sifnpmode(f->unit, PPP_IPV6, NPMODE_PASS); - - } else -#endif /* DEMAND_SUPPORT */ - { - /* - * Set LL addresses - */ - if (!sif6addr(f->pcb, go->ourid, ho->hisid)) { - PPPDEBUG(LOG_DEBUG, ("sif6addr failed")); - ipv6cp_close(f->pcb, "Interface configuration failed"); - return; - } - - /* bring the interface up for IPv6 */ - if (!sif6up(f->pcb)) { - PPPDEBUG(LOG_DEBUG, ("sif6up failed (IPV6)")); - ipv6cp_close(f->pcb, "Interface configuration failed"); - return; - } -#if DEMAND_SUPPORT - sifnpmode(f->pcb, PPP_IPV6, NPMODE_PASS); -#endif /* DEMAND_SUPPORT */ - - ppp_notice("local LL address %s", llv6_ntoa(go->ourid)); - ppp_notice("remote LL address %s", llv6_ntoa(ho->hisid)); - } - - np_up(f->pcb, PPP_IPV6); - pcb->ipv6cp_is_up = 1; - -#if 0 /* UNUSED */ - /* - * Execute the ipv6-up script, like this: - * /etc/ppp/ipv6-up interface tty speed local-LL remote-LL - */ - if (ipv6cp_script_state == s_down && ipv6cp_script_pid == 0) { - ipv6cp_script_state = s_up; - ipv6cp_script(_PATH_IPV6UP); - } -#endif /* UNUSED */ -} - - -/* - * ipv6cp_down - IPV6CP has gone DOWN. - * - * Take the IPv6 network interface down, clear its addresses - * and delete routes through it. - */ -static void ipv6cp_down(fsm *f) { - ppp_pcb *pcb = f->pcb; - ipv6cp_options *go = &pcb->ipv6cp_gotoptions; - ipv6cp_options *ho = &pcb->ipv6cp_hisoptions; - - IPV6CPDEBUG(("ipv6cp: down")); -#if PPP_STATS_SUPPORT - update_link_stats(f->unit); -#endif /* PPP_STATS_SUPPORT */ - if (pcb->ipv6cp_is_up) { - pcb->ipv6cp_is_up = 0; - np_down(f->pcb, PPP_IPV6); - } -#ifdef IPV6CP_COMP - sif6comp(f->unit, 0); -#endif - -#if DEMAND_SUPPORT - /* - * If we are doing dial-on-demand, set the interface - * to queue up outgoing packets (for now). - */ - if (demand) { - sifnpmode(f->pcb, PPP_IPV6, NPMODE_QUEUE); - } else -#endif /* DEMAND_SUPPORT */ - { -#if DEMAND_SUPPORT - sifnpmode(f->pcb, PPP_IPV6, NPMODE_DROP); -#endif /* DEMAND_SUPPORT */ - ipv6cp_clear_addrs(f->pcb, - go->ourid, - ho->hisid); - sif6down(f->pcb); - } - -#if 0 /* UNUSED */ - /* Execute the ipv6-down script */ - if (ipv6cp_script_state == s_up && ipv6cp_script_pid == 0) { - ipv6cp_script_state = s_down; - ipv6cp_script(_PATH_IPV6DOWN); - } -#endif /* UNUSED */ -} - - -/* - * ipv6cp_clear_addrs() - clear the interface addresses, routes, - * proxy neighbour discovery entries, etc. - */ -static void ipv6cp_clear_addrs(ppp_pcb *pcb, eui64_t ourid, eui64_t hisid) { - cif6addr(pcb, ourid, hisid); -} - - -/* - * ipv6cp_finished - possibly shut down the lower layers. - */ -static void ipv6cp_finished(fsm *f) { - np_finished(f->pcb, PPP_IPV6); -} - - -#if 0 /* UNUSED */ -/* - * ipv6cp_script_done - called when the ipv6-up or ipv6-down script - * has finished. - */ -static void -ipv6cp_script_done(arg) - void *arg; -{ - ipv6cp_script_pid = 0; - switch (ipv6cp_script_state) { - case s_up: - if (ipv6cp_fsm[0].state != PPP_FSM_OPENED) { - ipv6cp_script_state = s_down; - ipv6cp_script(_PATH_IPV6DOWN); - } - break; - case s_down: - if (ipv6cp_fsm[0].state == PPP_FSM_OPENED) { - ipv6cp_script_state = s_up; - ipv6cp_script(_PATH_IPV6UP); - } - break; - } -} - - -/* - * ipv6cp_script - Execute a script with arguments - * interface-name tty-name speed local-LL remote-LL. - */ -static void -ipv6cp_script(script) - char *script; -{ - char strspeed[32], strlocal[32], strremote[32]; - char *argv[8]; - - sprintf(strspeed, "%d", baud_rate); - strcpy(strlocal, llv6_ntoa(ipv6cp_gotoptions[0].ourid)); - strcpy(strremote, llv6_ntoa(ipv6cp_hisoptions[0].hisid)); - - argv[0] = script; - argv[1] = ifname; - argv[2] = devnam; - argv[3] = strspeed; - argv[4] = strlocal; - argv[5] = strremote; - argv[6] = ipparam; - argv[7] = NULL; - - ipv6cp_script_pid = run_program(script, argv, 0, ipv6cp_script_done, - NULL, 0); -} -#endif /* UNUSED */ - -#if PRINTPKT_SUPPORT -/* - * ipv6cp_printpkt - print the contents of an IPV6CP packet. - */ -static const char* const ipv6cp_codenames[] = { - "ConfReq", "ConfAck", "ConfNak", "ConfRej", - "TermReq", "TermAck", "CodeRej" -}; - -static int ipv6cp_printpkt(const u_char *p, int plen, - void (*printer)(void *, const char *, ...), void *arg) { - int code, id, len, olen; - const u_char *pstart, *optend; -#ifdef IPV6CP_COMP - u_short cishort; -#endif /* IPV6CP_COMP */ - eui64_t ifaceid; - - if (plen < HEADERLEN) - return 0; - pstart = p; - GETCHAR(code, p); - GETCHAR(id, p); - GETSHORT(len, p); - if (len < HEADERLEN || len > plen) - return 0; - - if (code >= 1 && code <= (int)LWIP_ARRAYSIZE(ipv6cp_codenames)) - printer(arg, " %s", ipv6cp_codenames[code-1]); - else - printer(arg, " code=0x%x", code); - printer(arg, " id=0x%x", id); - len -= HEADERLEN; - switch (code) { - case CONFREQ: - case CONFACK: - case CONFNAK: - case CONFREJ: - /* print option list */ - while (len >= 2) { - GETCHAR(code, p); - GETCHAR(olen, p); - p -= 2; - if (olen < 2 || olen > len) { - break; - } - printer(arg, " <"); - len -= olen; - optend = p + olen; - switch (code) { -#ifdef IPV6CP_COMP - case CI_COMPRESSTYPE: - if (olen >= CILEN_COMPRESS) { - p += 2; - GETSHORT(cishort, p); - printer(arg, "compress "); - printer(arg, "0x%x", cishort); - } - break; -#endif /* IPV6CP_COMP */ - case CI_IFACEID: - if (olen == CILEN_IFACEID) { - p += 2; - eui64_get(ifaceid, p); - printer(arg, "addr %s", llv6_ntoa(ifaceid)); - } - break; - default: - break; - } - while (p < optend) { - GETCHAR(code, p); - printer(arg, " %.2x", code); - } - printer(arg, ">"); - } - break; - - case TERMACK: - case TERMREQ: - if (len > 0 && *p >= ' ' && *p < 0x7f) { - printer(arg, " "); - ppp_print_string(p, len, printer, arg); - p += len; - len = 0; - } - break; - default: - break; - } - - /* print the rest of the bytes in the packet */ - for (; len > 0; --len) { - GETCHAR(code, p); - printer(arg, " %.2x", code); - } - - return p - pstart; -} -#endif /* PRINTPKT_SUPPORT */ - -#if DEMAND_SUPPORT -/* - * ipv6_active_pkt - see if this IP packet is worth bringing the link up for. - * We don't bring the link up for IP fragments or for TCP FIN packets - * with no data. - */ -#define IP6_HDRLEN 40 /* bytes */ -#define IP6_NHDR_FRAG 44 /* fragment IPv6 header */ -#define TCP_HDRLEN 20 -#define TH_FIN 0x01 - -/* - * We use these macros because the IP header may be at an odd address, - * and some compilers might use word loads to get th_off or ip_hl. - */ - -#define get_ip6nh(x) (((unsigned char *)(x))[6]) -#define get_tcpoff(x) (((unsigned char *)(x))[12] >> 4) -#define get_tcpflags(x) (((unsigned char *)(x))[13]) - -static int ipv6_active_pkt(u_char *pkt, int len) { - u_char *tcp; - - len -= PPP_HDRLEN; - pkt += PPP_HDRLEN; - if (len < IP6_HDRLEN) - return 0; - if (get_ip6nh(pkt) == IP6_NHDR_FRAG) - return 0; - if (get_ip6nh(pkt) != IPPROTO_TCP) - return 1; - if (len < IP6_HDRLEN + TCP_HDRLEN) - return 0; - tcp = pkt + IP6_HDRLEN; - if ((get_tcpflags(tcp) & TH_FIN) != 0 && len == IP6_HDRLEN + get_tcpoff(tcp) * 4) - return 0; - return 1; -} -#endif /* DEMAND_SUPPORT */ - -#endif /* PPP_SUPPORT && PPP_IPV6_SUPPORT */ diff --git a/third_party/lwip/repo/lwip/src/netif/ppp/lcp.c b/third_party/lwip/repo/lwip/src/netif/ppp/lcp.c deleted file mode 100644 index 90ed183b758ea7..00000000000000 --- a/third_party/lwip/repo/lwip/src/netif/ppp/lcp.c +++ /dev/null @@ -1,2790 +0,0 @@ -/* - * lcp.c - PPP Link Control Protocol. - * - * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name "Carnegie Mellon University" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For permission or any legal - * details, please contact - * Office of Technology Transfer - * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu - * - * 4. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Computing Services - * at Carnegie Mellon University (http://www.cmu.edu/computing/)." - * - * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE - * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -/* - * @todo: - */ - -#if 0 /* UNUSED */ -#include -#include -#include -#endif /* UNUSED */ - -#include "netif/ppp/ppp_impl.h" - -#include "netif/ppp/fsm.h" -#include "netif/ppp/lcp.h" -#if CHAP_SUPPORT -#include "netif/ppp/chap-new.h" -#endif /* CHAP_SUPPORT */ -#include "netif/ppp/magic.h" - -/* - * When the link comes up we want to be able to wait for a short while, - * or until seeing some input from the peer, before starting to send - * configure-requests. We do this by delaying the fsm_lowerup call. - */ -/* steal a bit in fsm flags word */ -#define DELAYED_UP 0x80 - -static void lcp_delayed_up(void *arg); - -/* - * LCP-related command-line options. - */ -#if 0 /* UNUSED */ -int lcp_echo_interval = 0; /* Interval between LCP echo-requests */ -int lcp_echo_fails = 0; /* Tolerance to unanswered echo-requests */ -#endif /* UNUSED */ - -#if 0 /* UNUSED */ -/* options */ -static u_int lcp_echo_interval = LCP_ECHOINTERVAL; /* Interval between LCP echo-requests */ -static u_int lcp_echo_fails = LCP_MAXECHOFAILS; /* Tolerance to unanswered echo-requests */ -#endif /* UNUSED */ - -#if 0 /* UNUSED */ -#if PPP_LCP_ADAPTIVE -bool lcp_echo_adaptive = 0; /* request echo only if the link was idle */ -#endif -bool lax_recv = 0; /* accept control chars in asyncmap */ -bool noendpoint = 0; /* don't send/accept endpoint discriminator */ -#endif /* UNUSED */ - -#if PPP_OPTIONS -static int noopt (char **); -#endif /* PPP_OPTIONS */ - -#ifdef HAVE_MULTILINK -static int setendpoint (char **); -static void printendpoint (option_t *, void (*)(void *, char *, ...), - void *); -#endif /* HAVE_MULTILINK */ - -#if PPP_OPTIONS -static option_t lcp_option_list[] = { - /* LCP options */ - { "-all", o_special_noarg, (void *)noopt, - "Don't request/allow any LCP options" }, - - { "noaccomp", o_bool, &lcp_wantoptions[0].neg_accompression, - "Disable address/control compression", - OPT_A2CLR, &lcp_allowoptions[0].neg_accompression }, - { "-ac", o_bool, &lcp_wantoptions[0].neg_accompression, - "Disable address/control compression", - OPT_ALIAS | OPT_A2CLR, &lcp_allowoptions[0].neg_accompression }, - - { "asyncmap", o_uint32, &lcp_wantoptions[0].asyncmap, - "Set asyncmap (for received packets)", - OPT_OR, &lcp_wantoptions[0].neg_asyncmap }, - { "-as", o_uint32, &lcp_wantoptions[0].asyncmap, - "Set asyncmap (for received packets)", - OPT_ALIAS | OPT_OR, &lcp_wantoptions[0].neg_asyncmap }, - { "default-asyncmap", o_uint32, &lcp_wantoptions[0].asyncmap, - "Disable asyncmap negotiation", - OPT_OR | OPT_NOARG | OPT_VAL(~0U) | OPT_A2CLR, - &lcp_allowoptions[0].neg_asyncmap }, - { "-am", o_uint32, &lcp_wantoptions[0].asyncmap, - "Disable asyncmap negotiation", - OPT_ALIAS | OPT_OR | OPT_NOARG | OPT_VAL(~0U) | OPT_A2CLR, - &lcp_allowoptions[0].neg_asyncmap }, - - { "nomagic", o_bool, &lcp_wantoptions[0].neg_magicnumber, - "Disable magic number negotiation (looped-back line detection)", - OPT_A2CLR, &lcp_allowoptions[0].neg_magicnumber }, - { "-mn", o_bool, &lcp_wantoptions[0].neg_magicnumber, - "Disable magic number negotiation (looped-back line detection)", - OPT_ALIAS | OPT_A2CLR, &lcp_allowoptions[0].neg_magicnumber }, - - { "mru", o_int, &lcp_wantoptions[0].mru, - "Set MRU (maximum received packet size) for negotiation", - OPT_PRIO, &lcp_wantoptions[0].neg_mru }, - { "default-mru", o_bool, &lcp_wantoptions[0].neg_mru, - "Disable MRU negotiation (use default 1500)", - OPT_PRIOSUB | OPT_A2CLR, &lcp_allowoptions[0].neg_mru }, - { "-mru", o_bool, &lcp_wantoptions[0].neg_mru, - "Disable MRU negotiation (use default 1500)", - OPT_ALIAS | OPT_PRIOSUB | OPT_A2CLR, &lcp_allowoptions[0].neg_mru }, - - { "mtu", o_int, &lcp_allowoptions[0].mru, - "Set our MTU", OPT_LIMITS, NULL, MAXMRU, MINMRU }, - - { "nopcomp", o_bool, &lcp_wantoptions[0].neg_pcompression, - "Disable protocol field compression", - OPT_A2CLR, &lcp_allowoptions[0].neg_pcompression }, - { "-pc", o_bool, &lcp_wantoptions[0].neg_pcompression, - "Disable protocol field compression", - OPT_ALIAS | OPT_A2CLR, &lcp_allowoptions[0].neg_pcompression }, - - { "passive", o_bool, &lcp_wantoptions[0].passive, - "Set passive mode", 1 }, - { "-p", o_bool, &lcp_wantoptions[0].passive, - "Set passive mode", OPT_ALIAS | 1 }, - - { "silent", o_bool, &lcp_wantoptions[0].silent, - "Set silent mode", 1 }, - - { "lcp-echo-failure", o_int, &lcp_echo_fails, - "Set number of consecutive echo failures to indicate link failure", - OPT_PRIO }, - { "lcp-echo-interval", o_int, &lcp_echo_interval, - "Set time in seconds between LCP echo requests", OPT_PRIO }, -#if PPP_LCP_ADAPTIVE - { "lcp-echo-adaptive", o_bool, &lcp_echo_adaptive, - "Suppress LCP echo requests if traffic was received", 1 }, -#endif - { "lcp-restart", o_int, &lcp_fsm[0].timeouttime, - "Set time in seconds between LCP retransmissions", OPT_PRIO }, - { "lcp-max-terminate", o_int, &lcp_fsm[0].maxtermtransmits, - "Set maximum number of LCP terminate-request transmissions", OPT_PRIO }, - { "lcp-max-configure", o_int, &lcp_fsm[0].maxconfreqtransmits, - "Set maximum number of LCP configure-request transmissions", OPT_PRIO }, - { "lcp-max-failure", o_int, &lcp_fsm[0].maxnakloops, - "Set limit on number of LCP configure-naks", OPT_PRIO }, - - { "receive-all", o_bool, &lax_recv, - "Accept all received control characters", 1 }, - -#ifdef HAVE_MULTILINK - { "mrru", o_int, &lcp_wantoptions[0].mrru, - "Maximum received packet size for multilink bundle", - OPT_PRIO, &lcp_wantoptions[0].neg_mrru }, - - { "mpshortseq", o_bool, &lcp_wantoptions[0].neg_ssnhf, - "Use short sequence numbers in multilink headers", - OPT_PRIO | 1, &lcp_allowoptions[0].neg_ssnhf }, - { "nompshortseq", o_bool, &lcp_wantoptions[0].neg_ssnhf, - "Don't use short sequence numbers in multilink headers", - OPT_PRIOSUB | OPT_A2CLR, &lcp_allowoptions[0].neg_ssnhf }, - - { "endpoint", o_special, (void *) setendpoint, - "Endpoint discriminator for multilink", - OPT_PRIO | OPT_A2PRINTER, (void *) printendpoint }, -#endif /* HAVE_MULTILINK */ - - { "noendpoint", o_bool, &noendpoint, - "Don't send or accept multilink endpoint discriminator", 1 }, - - {NULL} -}; -#endif /* PPP_OPTIONS */ - -/* - * Callbacks for fsm code. (CI = Configuration Information) - */ -static void lcp_resetci(fsm *f); /* Reset our CI */ -static int lcp_cilen(fsm *f); /* Return length of our CI */ -static void lcp_addci(fsm *f, u_char *ucp, int *lenp); /* Add our CI to pkt */ -static int lcp_ackci(fsm *f, u_char *p, int len); /* Peer ack'd our CI */ -static int lcp_nakci(fsm *f, u_char *p, int len, int treat_as_reject); /* Peer nak'd our CI */ -static int lcp_rejci(fsm *f, u_char *p, int len); /* Peer rej'd our CI */ -static int lcp_reqci(fsm *f, u_char *inp, int *lenp, int reject_if_disagree); /* Rcv peer CI */ -static void lcp_up(fsm *f); /* We're UP */ -static void lcp_down(fsm *f); /* We're DOWN */ -static void lcp_starting (fsm *); /* We need lower layer up */ -static void lcp_finished (fsm *); /* We need lower layer down */ -static int lcp_extcode(fsm *f, int code, int id, u_char *inp, int len); -static void lcp_rprotrej(fsm *f, u_char *inp, int len); - -/* - * routines to send LCP echos to peer - */ - -static void lcp_echo_lowerup(ppp_pcb *pcb); -static void lcp_echo_lowerdown(ppp_pcb *pcb); -static void LcpEchoTimeout(void *arg); -static void lcp_received_echo_reply(fsm *f, int id, u_char *inp, int len); -static void LcpSendEchoRequest(fsm *f); -static void LcpLinkFailure(fsm *f); -static void LcpEchoCheck(fsm *f); - -static const fsm_callbacks lcp_callbacks = { /* LCP callback routines */ - lcp_resetci, /* Reset our Configuration Information */ - lcp_cilen, /* Length of our Configuration Information */ - lcp_addci, /* Add our Configuration Information */ - lcp_ackci, /* ACK our Configuration Information */ - lcp_nakci, /* NAK our Configuration Information */ - lcp_rejci, /* Reject our Configuration Information */ - lcp_reqci, /* Request peer's Configuration Information */ - lcp_up, /* Called when fsm reaches OPENED state */ - lcp_down, /* Called when fsm leaves OPENED state */ - lcp_starting, /* Called when we want the lower layer up */ - lcp_finished, /* Called when we want the lower layer down */ - NULL, /* Called when Protocol-Reject received */ - NULL, /* Retransmission is necessary */ - lcp_extcode, /* Called to handle LCP-specific codes */ - "LCP" /* String name of protocol */ -}; - -/* - * Protocol entry points. - * Some of these are called directly. - */ - -static void lcp_init(ppp_pcb *pcb); -static void lcp_input(ppp_pcb *pcb, u_char *p, int len); -static void lcp_protrej(ppp_pcb *pcb); -#if PRINTPKT_SUPPORT -static int lcp_printpkt(const u_char *p, int plen, - void (*printer) (void *, const char *, ...), void *arg); -#endif /* PRINTPKT_SUPPORT */ - -const struct protent lcp_protent = { - PPP_LCP, - lcp_init, - lcp_input, - lcp_protrej, - lcp_lowerup, - lcp_lowerdown, - lcp_open, - lcp_close, -#if PRINTPKT_SUPPORT - lcp_printpkt, -#endif /* PRINTPKT_SUPPORT */ -#if PPP_DATAINPUT - NULL, -#endif /* PPP_DATAINPUT */ -#if PRINTPKT_SUPPORT - "LCP", - NULL, -#endif /* PRINTPKT_SUPPORT */ -#if PPP_OPTIONS - lcp_option_list, - NULL, -#endif /* PPP_OPTIONS */ -#if DEMAND_SUPPORT - NULL, - NULL -#endif /* DEMAND_SUPPORT */ -}; - -/* - * Length of each type of configuration option (in octets) - */ -#define CILEN_VOID 2 -#define CILEN_CHAR 3 -#define CILEN_SHORT 4 /* CILEN_VOID + 2 */ -#if CHAP_SUPPORT -#define CILEN_CHAP 5 /* CILEN_VOID + 2 + 1 */ -#endif /* CHAP_SUPPORT */ -#define CILEN_LONG 6 /* CILEN_VOID + 4 */ -#if LQR_SUPPORT -#define CILEN_LQR 8 /* CILEN_VOID + 2 + 4 */ -#endif /* LQR_SUPPORT */ -#define CILEN_CBCP 3 - -#define CODENAME(x) ((x) == CONFACK ? "ACK" : \ - (x) == CONFNAK ? "NAK" : "REJ") - -#if PPP_OPTIONS -/* - * noopt - Disable all options (why?). - */ -static int -noopt(argv) - char **argv; -{ - BZERO((char *) &lcp_wantoptions[0], sizeof (struct lcp_options)); - BZERO((char *) &lcp_allowoptions[0], sizeof (struct lcp_options)); - - return (1); -} -#endif /* PPP_OPTIONS */ - -#ifdef HAVE_MULTILINK -static int -setendpoint(argv) - char **argv; -{ - if (str_to_epdisc(&lcp_wantoptions[0].endpoint, *argv)) { - lcp_wantoptions[0].neg_endpoint = 1; - return 1; - } - option_error("Can't parse '%s' as an endpoint discriminator", *argv); - return 0; -} - -static void -printendpoint(opt, printer, arg) - option_t *opt; - void (*printer) (void *, char *, ...); - void *arg; -{ - printer(arg, "%s", epdisc_to_str(&lcp_wantoptions[0].endpoint)); -} -#endif /* HAVE_MULTILINK */ - -/* - * lcp_init - Initialize LCP. - */ -static void lcp_init(ppp_pcb *pcb) { - fsm *f = &pcb->lcp_fsm; - lcp_options *wo = &pcb->lcp_wantoptions; - lcp_options *ao = &pcb->lcp_allowoptions; - - f->pcb = pcb; - f->protocol = PPP_LCP; - f->callbacks = &lcp_callbacks; - - fsm_init(f); - - BZERO(wo, sizeof(*wo)); - wo->neg_mru = 1; - wo->mru = PPP_DEFMRU; - wo->neg_asyncmap = 1; - wo->neg_magicnumber = 1; - wo->neg_pcompression = 1; - wo->neg_accompression = 1; - - BZERO(ao, sizeof(*ao)); - ao->neg_mru = 1; - ao->mru = PPP_MAXMRU; - ao->neg_asyncmap = 1; -#if CHAP_SUPPORT - ao->neg_chap = 1; - ao->chap_mdtype = CHAP_MDTYPE_SUPPORTED; -#endif /* CHAP_SUPPORT */ -#if PAP_SUPPORT - ao->neg_upap = 1; -#endif /* PAP_SUPPORT */ -#if EAP_SUPPORT - ao->neg_eap = 1; -#endif /* EAP_SUPPORT */ - ao->neg_magicnumber = 1; - ao->neg_pcompression = 1; - ao->neg_accompression = 1; - ao->neg_endpoint = 1; -} - - -/* - * lcp_open - LCP is allowed to come up. - */ -void lcp_open(ppp_pcb *pcb) { - fsm *f = &pcb->lcp_fsm; - lcp_options *wo = &pcb->lcp_wantoptions; - - f->flags &= ~(OPT_PASSIVE | OPT_SILENT); - if (wo->passive) - f->flags |= OPT_PASSIVE; - if (wo->silent) - f->flags |= OPT_SILENT; - fsm_open(f); -} - - -/* - * lcp_close - Take LCP down. - */ -void lcp_close(ppp_pcb *pcb, const char *reason) { - fsm *f = &pcb->lcp_fsm; - int oldstate; - - if (pcb->phase != PPP_PHASE_DEAD -#ifdef HAVE_MULTILINK - && pcb->phase != PPP_PHASE_MASTER -#endif /* HAVE_MULTILINK */ - ) - new_phase(pcb, PPP_PHASE_TERMINATE); - - if (f->flags & DELAYED_UP) { - UNTIMEOUT(lcp_delayed_up, f); - f->state = PPP_FSM_STOPPED; - } - oldstate = f->state; - - fsm_close(f, reason); - if (oldstate == PPP_FSM_STOPPED && (f->flags & (OPT_PASSIVE|OPT_SILENT|DELAYED_UP))) { - /* - * This action is not strictly according to the FSM in RFC1548, - * but it does mean that the program terminates if you do a - * lcp_close() when a connection hasn't been established - * because we are in passive/silent mode or because we have - * delayed the fsm_lowerup() call and it hasn't happened yet. - */ - f->flags &= ~DELAYED_UP; - lcp_finished(f); - } -} - - -/* - * lcp_lowerup - The lower layer is up. - */ -void lcp_lowerup(ppp_pcb *pcb) { - lcp_options *wo = &pcb->lcp_wantoptions; - fsm *f = &pcb->lcp_fsm; - /* - * Don't use A/C or protocol compression on transmission, - * but accept A/C and protocol compressed packets - * if we are going to ask for A/C and protocol compression. - */ - if (ppp_send_config(pcb, PPP_MRU, 0xffffffff, 0, 0) < 0 - || ppp_recv_config(pcb, PPP_MRU, (pcb->settings.lax_recv? 0: 0xffffffff), - wo->neg_pcompression, wo->neg_accompression) < 0) - return; - pcb->peer_mru = PPP_MRU; - - if (pcb->settings.listen_time != 0) { - f->flags |= DELAYED_UP; - TIMEOUTMS(lcp_delayed_up, f, pcb->settings.listen_time); - } else - fsm_lowerup(f); -} - - -/* - * lcp_lowerdown - The lower layer is down. - */ -void lcp_lowerdown(ppp_pcb *pcb) { - fsm *f = &pcb->lcp_fsm; - - if (f->flags & DELAYED_UP) { - f->flags &= ~DELAYED_UP; - UNTIMEOUT(lcp_delayed_up, f); - } else - fsm_lowerdown(f); -} - - -/* - * lcp_delayed_up - Bring the lower layer up now. - */ -static void lcp_delayed_up(void *arg) { - fsm *f = (fsm*)arg; - - if (f->flags & DELAYED_UP) { - f->flags &= ~DELAYED_UP; - fsm_lowerup(f); - } -} - - -/* - * lcp_input - Input LCP packet. - */ -static void lcp_input(ppp_pcb *pcb, u_char *p, int len) { - fsm *f = &pcb->lcp_fsm; - - if (f->flags & DELAYED_UP) { - f->flags &= ~DELAYED_UP; - UNTIMEOUT(lcp_delayed_up, f); - fsm_lowerup(f); - } - fsm_input(f, p, len); -} - -/* - * lcp_extcode - Handle a LCP-specific code. - */ -static int lcp_extcode(fsm *f, int code, int id, u_char *inp, int len) { - ppp_pcb *pcb = f->pcb; - lcp_options *go = &pcb->lcp_gotoptions; - u_char *magp; - - switch( code ){ - case PROTREJ: - lcp_rprotrej(f, inp, len); - break; - - case ECHOREQ: - if (f->state != PPP_FSM_OPENED) - break; - magp = inp; - PUTLONG(go->magicnumber, magp); - fsm_sdata(f, ECHOREP, id, inp, len); - break; - - case ECHOREP: - lcp_received_echo_reply(f, id, inp, len); - break; - - case DISCREQ: - case IDENTIF: - case TIMEREM: - break; - - default: - return 0; - } - return 1; -} - - -/* - * lcp_rprotrej - Receive an Protocol-Reject. - * - * Figure out which protocol is rejected and inform it. - */ -static void lcp_rprotrej(fsm *f, u_char *inp, int len) { - int i; - const struct protent *protp; - u_short prot; -#if PPP_PROTOCOLNAME - const char *pname; -#endif /* PPP_PROTOCOLNAME */ - - if (len < 2) { - LCPDEBUG(("lcp_rprotrej: Rcvd short Protocol-Reject packet!")); - return; - } - - GETSHORT(prot, inp); - - /* - * Protocol-Reject packets received in any state other than the LCP - * OPENED state SHOULD be silently discarded. - */ - if( f->state != PPP_FSM_OPENED ){ - LCPDEBUG(("Protocol-Reject discarded: LCP in state %d", f->state)); - return; - } - -#if PPP_PROTOCOLNAME - pname = protocol_name(prot); -#endif /* PPP_PROTOCOLNAME */ - - /* - * Upcall the proper Protocol-Reject routine. - */ - for (i = 0; (protp = protocols[i]) != NULL; ++i) - if (protp->protocol == prot) { -#if PPP_PROTOCOLNAME - if (pname != NULL) - ppp_dbglog("Protocol-Reject for '%s' (0x%x) received", pname, - prot); - else -#endif /* PPP_PROTOCOLNAME */ - ppp_dbglog("Protocol-Reject for 0x%x received", prot); - (*protp->protrej)(f->pcb); - return; - } - -#if PPP_PROTOCOLNAME - if (pname != NULL) - ppp_warn("Protocol-Reject for unsupported protocol '%s' (0x%x)", pname, - prot); - else -#endif /* #if PPP_PROTOCOLNAME */ - ppp_warn("Protocol-Reject for unsupported protocol 0x%x", prot); -} - - -/* - * lcp_protrej - A Protocol-Reject was received. - */ -/*ARGSUSED*/ -static void lcp_protrej(ppp_pcb *pcb) { - /* - * Can't reject LCP! - */ - ppp_error("Received Protocol-Reject for LCP!"); - fsm_protreject(&pcb->lcp_fsm); -} - - -/* - * lcp_sprotrej - Send a Protocol-Reject for some protocol. - */ -void lcp_sprotrej(ppp_pcb *pcb, u_char *p, int len) { - fsm *f = &pcb->lcp_fsm; - /* - * Send back the protocol and the information field of the - * rejected packet. We only get here if LCP is in the OPENED state. - */ -#if 0 - p += 2; - len -= 2; -#endif - - fsm_sdata(f, PROTREJ, ++f->id, - p, len); -} - - -/* - * lcp_resetci - Reset our CI. - */ -static void lcp_resetci(fsm *f) { - ppp_pcb *pcb = f->pcb; - lcp_options *wo = &pcb->lcp_wantoptions; - lcp_options *go = &pcb->lcp_gotoptions; - lcp_options *ao = &pcb->lcp_allowoptions; - -#if PPP_AUTH_SUPPORT - - /* note: default value is true for allow options */ - if (pcb->settings.user && pcb->settings.passwd) { -#if PAP_SUPPORT - if (pcb->settings.refuse_pap) { - ao->neg_upap = 0; - } -#endif /* PAP_SUPPORT */ -#if CHAP_SUPPORT - if (pcb->settings.refuse_chap) { - ao->chap_mdtype &= ~MDTYPE_MD5; - } -#if MSCHAP_SUPPORT - if (pcb->settings.refuse_mschap) { - ao->chap_mdtype &= ~MDTYPE_MICROSOFT; - } - if (pcb->settings.refuse_mschap_v2) { - ao->chap_mdtype &= ~MDTYPE_MICROSOFT_V2; - } -#endif /* MSCHAP_SUPPORT */ - ao->neg_chap = (ao->chap_mdtype != MDTYPE_NONE); -#endif /* CHAP_SUPPORT */ -#if EAP_SUPPORT - if (pcb->settings.refuse_eap) { - ao->neg_eap = 0; - } -#endif /* EAP_SUPPORT */ - -#if PPP_SERVER - /* note: default value is false for wanted options */ - if (pcb->settings.auth_required) { -#if PAP_SUPPORT - if (!pcb->settings.refuse_pap) { - wo->neg_upap = 1; - } -#endif /* PAP_SUPPORT */ -#if CHAP_SUPPORT - if (!pcb->settings.refuse_chap) { - wo->chap_mdtype |= MDTYPE_MD5; - } -#if MSCHAP_SUPPORT - if (!pcb->settings.refuse_mschap) { - wo->chap_mdtype |= MDTYPE_MICROSOFT; - } - if (!pcb->settings.refuse_mschap_v2) { - wo->chap_mdtype |= MDTYPE_MICROSOFT_V2; - } -#endif /* MSCHAP_SUPPORT */ - wo->neg_chap = (wo->chap_mdtype != MDTYPE_NONE); -#endif /* CHAP_SUPPORT */ -#if EAP_SUPPORT - if (!pcb->settings.refuse_eap) { - wo->neg_eap = 1; - } -#endif /* EAP_SUPPORT */ - } -#endif /* PPP_SERVER */ - - } else { -#if PAP_SUPPORT - ao->neg_upap = 0; -#endif /* PAP_SUPPORT */ -#if CHAP_SUPPORT - ao->neg_chap = 0; - ao->chap_mdtype = MDTYPE_NONE; -#endif /* CHAP_SUPPORT */ -#if EAP_SUPPORT - ao->neg_eap = 0; -#endif /* EAP_SUPPORT */ - } - - PPPDEBUG(LOG_DEBUG, ("ppp: auth protocols:")); -#if PAP_SUPPORT - PPPDEBUG(LOG_DEBUG, (" PAP=%d", ao->neg_upap)); -#endif /* PAP_SUPPORT */ -#if CHAP_SUPPORT - PPPDEBUG(LOG_DEBUG, (" CHAP=%d CHAP_MD5=%d", ao->neg_chap, !!(ao->chap_mdtype&MDTYPE_MD5))); -#if MSCHAP_SUPPORT - PPPDEBUG(LOG_DEBUG, (" CHAP_MS=%d CHAP_MS2=%d", !!(ao->chap_mdtype&MDTYPE_MICROSOFT), !!(ao->chap_mdtype&MDTYPE_MICROSOFT_V2))); -#endif /* MSCHAP_SUPPORT */ -#endif /* CHAP_SUPPORT */ -#if EAP_SUPPORT - PPPDEBUG(LOG_DEBUG, (" EAP=%d", ao->neg_eap)); -#endif /* EAP_SUPPORT */ - PPPDEBUG(LOG_DEBUG, ("\n")); - -#endif /* PPP_AUTH_SUPPORT */ - - wo->magicnumber = magic(); - wo->numloops = 0; - *go = *wo; -#ifdef HAVE_MULTILINK - if (!multilink) { - go->neg_mrru = 0; -#endif /* HAVE_MULTILINK */ - go->neg_ssnhf = 0; - go->neg_endpoint = 0; -#ifdef HAVE_MULTILINK - } -#endif /* HAVE_MULTILINK */ - if (pcb->settings.noendpoint) - ao->neg_endpoint = 0; - pcb->peer_mru = PPP_MRU; -#if 0 /* UNUSED */ - auth_reset(pcb); -#endif /* UNUSED */ -} - - -/* - * lcp_cilen - Return length of our CI. - */ -static int lcp_cilen(fsm *f) { - ppp_pcb *pcb = f->pcb; - lcp_options *go = &pcb->lcp_gotoptions; - -#define LENCIVOID(neg) ((neg) ? CILEN_VOID : 0) -#if CHAP_SUPPORT -#define LENCICHAP(neg) ((neg) ? CILEN_CHAP : 0) -#endif /* CHAP_SUPPORT */ -#define LENCISHORT(neg) ((neg) ? CILEN_SHORT : 0) -#define LENCILONG(neg) ((neg) ? CILEN_LONG : 0) -#if LQR_SUPPORT -#define LENCILQR(neg) ((neg) ? CILEN_LQR: 0) -#endif /* LQR_SUPPORT */ -#define LENCICBCP(neg) ((neg) ? CILEN_CBCP: 0) - /* - * NB: we only ask for one of CHAP, UPAP, or EAP, even if we will - * accept more than one. We prefer EAP first, then CHAP, then - * PAP. - */ - return (LENCISHORT(go->neg_mru && go->mru != PPP_DEFMRU) + - LENCILONG(go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF) + -#if EAP_SUPPORT - LENCISHORT(go->neg_eap) + -#endif /* EAP_SUPPORT */ -#if CHAP_SUPPORT /* cannot be improved, embedding a directive within macro arguments is not portable */ -#if EAP_SUPPORT - LENCICHAP(!go->neg_eap && go->neg_chap) + -#endif /* EAP_SUPPORT */ -#if !EAP_SUPPORT - LENCICHAP(go->neg_chap) + -#endif /* !EAP_SUPPORT */ -#endif /* CHAP_SUPPORT */ -#if PAP_SUPPORT /* cannot be improved, embedding a directive within macro arguments is not portable */ -#if EAP_SUPPORT && CHAP_SUPPORT - LENCISHORT(!go->neg_eap && !go->neg_chap && go->neg_upap) + -#endif /* EAP_SUPPORT && CHAP_SUPPORT */ -#if EAP_SUPPORT && !CHAP_SUPPORT - LENCISHORT(!go->neg_eap && go->neg_upap) + -#endif /* EAP_SUPPORT && !CHAP_SUPPORT */ -#if !EAP_SUPPORT && CHAP_SUPPORT - LENCISHORT(!go->neg_chap && go->neg_upap) + -#endif /* !EAP_SUPPORT && CHAP_SUPPORT */ -#if !EAP_SUPPORT && !CHAP_SUPPORT - LENCISHORT(go->neg_upap) + -#endif /* !EAP_SUPPORT && !CHAP_SUPPORT */ -#endif /* PAP_SUPPORT */ -#if LQR_SUPPORT - LENCILQR(go->neg_lqr) + -#endif /* LQR_SUPPORT */ - LENCICBCP(go->neg_cbcp) + - LENCILONG(go->neg_magicnumber) + - LENCIVOID(go->neg_pcompression) + - LENCIVOID(go->neg_accompression) + -#ifdef HAVE_MULTILINK - LENCISHORT(go->neg_mrru) + -#endif /* HAVE_MULTILINK */ - LENCIVOID(go->neg_ssnhf) + - (go->neg_endpoint? CILEN_CHAR + go->endpoint.length: 0)); -} - - -/* - * lcp_addci - Add our desired CIs to a packet. - */ -static void lcp_addci(fsm *f, u_char *ucp, int *lenp) { - ppp_pcb *pcb = f->pcb; - lcp_options *go = &pcb->lcp_gotoptions; - u_char *start_ucp = ucp; - -#define ADDCIVOID(opt, neg) \ - if (neg) { \ - PUTCHAR(opt, ucp); \ - PUTCHAR(CILEN_VOID, ucp); \ - } -#define ADDCISHORT(opt, neg, val) \ - if (neg) { \ - PUTCHAR(opt, ucp); \ - PUTCHAR(CILEN_SHORT, ucp); \ - PUTSHORT(val, ucp); \ - } -#if CHAP_SUPPORT -#define ADDCICHAP(opt, neg, val) \ - if (neg) { \ - PUTCHAR((opt), ucp); \ - PUTCHAR(CILEN_CHAP, ucp); \ - PUTSHORT(PPP_CHAP, ucp); \ - PUTCHAR((CHAP_DIGEST(val)), ucp); \ - } -#endif /* CHAP_SUPPORT */ -#define ADDCILONG(opt, neg, val) \ - if (neg) { \ - PUTCHAR(opt, ucp); \ - PUTCHAR(CILEN_LONG, ucp); \ - PUTLONG(val, ucp); \ - } -#if LQR_SUPPORT -#define ADDCILQR(opt, neg, val) \ - if (neg) { \ - PUTCHAR(opt, ucp); \ - PUTCHAR(CILEN_LQR, ucp); \ - PUTSHORT(PPP_LQR, ucp); \ - PUTLONG(val, ucp); \ - } -#endif /* LQR_SUPPORT */ -#define ADDCICHAR(opt, neg, val) \ - if (neg) { \ - PUTCHAR(opt, ucp); \ - PUTCHAR(CILEN_CHAR, ucp); \ - PUTCHAR(val, ucp); \ - } -#define ADDCIENDP(opt, neg, class, val, len) \ - if (neg) { \ - int i; \ - PUTCHAR(opt, ucp); \ - PUTCHAR(CILEN_CHAR + len, ucp); \ - PUTCHAR(class, ucp); \ - for (i = 0; i < len; ++i) \ - PUTCHAR(val[i], ucp); \ - } - - ADDCISHORT(CI_MRU, go->neg_mru && go->mru != PPP_DEFMRU, go->mru); - ADDCILONG(CI_ASYNCMAP, go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF, - go->asyncmap); -#if EAP_SUPPORT - ADDCISHORT(CI_AUTHTYPE, go->neg_eap, PPP_EAP); -#endif /* EAP_SUPPORT */ -#if CHAP_SUPPORT /* cannot be improved, embedding a directive within macro arguments is not portable */ -#if EAP_SUPPORT - ADDCICHAP(CI_AUTHTYPE, !go->neg_eap && go->neg_chap, go->chap_mdtype); -#endif /* EAP_SUPPORT */ -#if !EAP_SUPPORT - ADDCICHAP(CI_AUTHTYPE, go->neg_chap, go->chap_mdtype); -#endif /* !EAP_SUPPORT */ -#endif /* CHAP_SUPPORT */ -#if PAP_SUPPORT /* cannot be improved, embedding a directive within macro arguments is not portable */ -#if EAP_SUPPORT && CHAP_SUPPORT - ADDCISHORT(CI_AUTHTYPE, !go->neg_eap && !go->neg_chap && go->neg_upap, PPP_PAP); -#endif /* EAP_SUPPORT && CHAP_SUPPORT */ -#if EAP_SUPPORT && !CHAP_SUPPORT - ADDCISHORT(CI_AUTHTYPE, !go->neg_eap && go->neg_upap, PPP_PAP); -#endif /* EAP_SUPPORT && !CHAP_SUPPORT */ -#if !EAP_SUPPORT && CHAP_SUPPORT - ADDCISHORT(CI_AUTHTYPE, !go->neg_chap && go->neg_upap, PPP_PAP); -#endif /* !EAP_SUPPORT && CHAP_SUPPORT */ -#if !EAP_SUPPORT && !CHAP_SUPPORT - ADDCISHORT(CI_AUTHTYPE, go->neg_upap, PPP_PAP); -#endif /* !EAP_SUPPORT && !CHAP_SUPPORT */ -#endif /* PAP_SUPPORT */ -#if LQR_SUPPORT - ADDCILQR(CI_QUALITY, go->neg_lqr, go->lqr_period); -#endif /* LQR_SUPPORT */ - ADDCICHAR(CI_CALLBACK, go->neg_cbcp, CBCP_OPT); - ADDCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber); - ADDCIVOID(CI_PCOMPRESSION, go->neg_pcompression); - ADDCIVOID(CI_ACCOMPRESSION, go->neg_accompression); -#ifdef HAVE_MULTILINK - ADDCISHORT(CI_MRRU, go->neg_mrru, go->mrru); -#endif - ADDCIVOID(CI_SSNHF, go->neg_ssnhf); - ADDCIENDP(CI_EPDISC, go->neg_endpoint, go->endpoint.class_, - go->endpoint.value, go->endpoint.length); - - if (ucp - start_ucp != *lenp) { - /* this should never happen, because peer_mtu should be 1500 */ - ppp_error("Bug in lcp_addci: wrong length"); - } -} - - -/* - * lcp_ackci - Ack our CIs. - * This should not modify any state if the Ack is bad. - * - * Returns: - * 0 - Ack was bad. - * 1 - Ack was good. - */ -static int lcp_ackci(fsm *f, u_char *p, int len) { - ppp_pcb *pcb = f->pcb; - lcp_options *go = &pcb->lcp_gotoptions; - u_char cilen, citype, cichar; - u_short cishort; - u32_t cilong; - - /* - * CIs must be in exactly the same order that we sent. - * Check packet length and CI length at each step. - * If we find any deviations, then this packet is bad. - */ -#define ACKCIVOID(opt, neg) \ - if (neg) { \ - if ((len -= CILEN_VOID) < 0) \ - goto bad; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != CILEN_VOID || \ - citype != opt) \ - goto bad; \ - } -#define ACKCISHORT(opt, neg, val) \ - if (neg) { \ - if ((len -= CILEN_SHORT) < 0) \ - goto bad; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != CILEN_SHORT || \ - citype != opt) \ - goto bad; \ - GETSHORT(cishort, p); \ - if (cishort != val) \ - goto bad; \ - } -#define ACKCICHAR(opt, neg, val) \ - if (neg) { \ - if ((len -= CILEN_CHAR) < 0) \ - goto bad; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != CILEN_CHAR || \ - citype != opt) \ - goto bad; \ - GETCHAR(cichar, p); \ - if (cichar != val) \ - goto bad; \ - } -#if CHAP_SUPPORT -#define ACKCICHAP(opt, neg, val) \ - if (neg) { \ - if ((len -= CILEN_CHAP) < 0) \ - goto bad; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != CILEN_CHAP || \ - citype != (opt)) \ - goto bad; \ - GETSHORT(cishort, p); \ - if (cishort != PPP_CHAP) \ - goto bad; \ - GETCHAR(cichar, p); \ - if (cichar != (CHAP_DIGEST(val))) \ - goto bad; \ - } -#endif /* CHAP_SUPPORT */ -#define ACKCILONG(opt, neg, val) \ - if (neg) { \ - if ((len -= CILEN_LONG) < 0) \ - goto bad; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != CILEN_LONG || \ - citype != opt) \ - goto bad; \ - GETLONG(cilong, p); \ - if (cilong != val) \ - goto bad; \ - } -#if LQR_SUPPORT -#define ACKCILQR(opt, neg, val) \ - if (neg) { \ - if ((len -= CILEN_LQR) < 0) \ - goto bad; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != CILEN_LQR || \ - citype != opt) \ - goto bad; \ - GETSHORT(cishort, p); \ - if (cishort != PPP_LQR) \ - goto bad; \ - GETLONG(cilong, p); \ - if (cilong != val) \ - goto bad; \ - } -#endif /* LQR_SUPPORT */ -#define ACKCIENDP(opt, neg, class, val, vlen) \ - if (neg) { \ - int i; \ - if ((len -= CILEN_CHAR + vlen) < 0) \ - goto bad; \ - GETCHAR(citype, p); \ - GETCHAR(cilen, p); \ - if (cilen != CILEN_CHAR + vlen || \ - citype != opt) \ - goto bad; \ - GETCHAR(cichar, p); \ - if (cichar != class) \ - goto bad; \ - for (i = 0; i < vlen; ++i) { \ - GETCHAR(cichar, p); \ - if (cichar != val[i]) \ - goto bad; \ - } \ - } - - ACKCISHORT(CI_MRU, go->neg_mru && go->mru != PPP_DEFMRU, go->mru); - ACKCILONG(CI_ASYNCMAP, go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF, - go->asyncmap); -#if EAP_SUPPORT - ACKCISHORT(CI_AUTHTYPE, go->neg_eap, PPP_EAP); -#endif /* EAP_SUPPORT */ -#if CHAP_SUPPORT /* cannot be improved, embedding a directive within macro arguments is not portable */ -#if EAP_SUPPORT - ACKCICHAP(CI_AUTHTYPE, !go->neg_eap && go->neg_chap, go->chap_mdtype); -#endif /* EAP_SUPPORT */ -#if !EAP_SUPPORT - ACKCICHAP(CI_AUTHTYPE, go->neg_chap, go->chap_mdtype); -#endif /* !EAP_SUPPORT */ -#endif /* CHAP_SUPPORT */ -#if PAP_SUPPORT /* cannot be improved, embedding a directive within macro arguments is not portable */ -#if EAP_SUPPORT && CHAP_SUPPORT - ACKCISHORT(CI_AUTHTYPE, !go->neg_eap && !go->neg_chap && go->neg_upap, PPP_PAP); -#endif /* EAP_SUPPORT && CHAP_SUPPORT */ -#if EAP_SUPPORT && !CHAP_SUPPORT - ACKCISHORT(CI_AUTHTYPE, !go->neg_eap && go->neg_upap, PPP_PAP); -#endif /* EAP_SUPPORT && !CHAP_SUPPORT */ -#if !EAP_SUPPORT && CHAP_SUPPORT - ACKCISHORT(CI_AUTHTYPE, !go->neg_chap && go->neg_upap, PPP_PAP); -#endif /* !EAP_SUPPORT && CHAP_SUPPORT */ -#if !EAP_SUPPORT && !CHAP_SUPPORT - ACKCISHORT(CI_AUTHTYPE, go->neg_upap, PPP_PAP); -#endif /* !EAP_SUPPORT && !CHAP_SUPPORT */ -#endif /* PAP_SUPPORT */ -#if LQR_SUPPORT - ACKCILQR(CI_QUALITY, go->neg_lqr, go->lqr_period); -#endif /* LQR_SUPPORT */ - ACKCICHAR(CI_CALLBACK, go->neg_cbcp, CBCP_OPT); - ACKCILONG(CI_MAGICNUMBER, go->neg_magicnumber, go->magicnumber); - ACKCIVOID(CI_PCOMPRESSION, go->neg_pcompression); - ACKCIVOID(CI_ACCOMPRESSION, go->neg_accompression); -#ifdef HAVE_MULTILINK - ACKCISHORT(CI_MRRU, go->neg_mrru, go->mrru); -#endif /* HAVE_MULTILINK */ - ACKCIVOID(CI_SSNHF, go->neg_ssnhf); - ACKCIENDP(CI_EPDISC, go->neg_endpoint, go->endpoint.class_, - go->endpoint.value, go->endpoint.length); - - /* - * If there are any remaining CIs, then this packet is bad. - */ - if (len != 0) - goto bad; - return (1); -bad: - LCPDEBUG(("lcp_acki: received bad Ack!")); - return (0); -} - - -/* - * lcp_nakci - Peer has sent a NAK for some of our CIs. - * This should not modify any state if the Nak is bad - * or if LCP is in the OPENED state. - * - * Returns: - * 0 - Nak was bad. - * 1 - Nak was good. - */ -static int lcp_nakci(fsm *f, u_char *p, int len, int treat_as_reject) { - ppp_pcb *pcb = f->pcb; - lcp_options *go = &pcb->lcp_gotoptions; - lcp_options *wo = &pcb->lcp_wantoptions; - u_char citype, cichar, *next; - u_short cishort; - u32_t cilong; - lcp_options no; /* options we've seen Naks for */ - lcp_options try_; /* options to request next time */ - int looped_back = 0; - int cilen; - - BZERO(&no, sizeof(no)); - try_ = *go; - - /* - * Any Nak'd CIs must be in exactly the same order that we sent. - * Check packet length and CI length at each step. - * If we find any deviations, then this packet is bad. - */ -#define NAKCIVOID(opt, neg) \ - if (go->neg && \ - len >= CILEN_VOID && \ - p[1] == CILEN_VOID && \ - p[0] == opt) { \ - len -= CILEN_VOID; \ - INCPTR(CILEN_VOID, p); \ - no.neg = 1; \ - try_.neg = 0; \ - } -#if CHAP_SUPPORT -#define NAKCICHAP(opt, neg, code) \ - if (go->neg && \ - len >= CILEN_CHAP && \ - p[1] == CILEN_CHAP && \ - p[0] == opt) { \ - len -= CILEN_CHAP; \ - INCPTR(2, p); \ - GETSHORT(cishort, p); \ - GETCHAR(cichar, p); \ - no.neg = 1; \ - code \ - } -#endif /* CHAP_SUPPORT */ -#define NAKCICHAR(opt, neg, code) \ - if (go->neg && \ - len >= CILEN_CHAR && \ - p[1] == CILEN_CHAR && \ - p[0] == opt) { \ - len -= CILEN_CHAR; \ - INCPTR(2, p); \ - GETCHAR(cichar, p); \ - no.neg = 1; \ - code \ - } -#define NAKCISHORT(opt, neg, code) \ - if (go->neg && \ - len >= CILEN_SHORT && \ - p[1] == CILEN_SHORT && \ - p[0] == opt) { \ - len -= CILEN_SHORT; \ - INCPTR(2, p); \ - GETSHORT(cishort, p); \ - no.neg = 1; \ - code \ - } -#define NAKCILONG(opt, neg, code) \ - if (go->neg && \ - len >= CILEN_LONG && \ - p[1] == CILEN_LONG && \ - p[0] == opt) { \ - len -= CILEN_LONG; \ - INCPTR(2, p); \ - GETLONG(cilong, p); \ - no.neg = 1; \ - code \ - } -#if LQR_SUPPORT -#define NAKCILQR(opt, neg, code) \ - if (go->neg && \ - len >= CILEN_LQR && \ - p[1] == CILEN_LQR && \ - p[0] == opt) { \ - len -= CILEN_LQR; \ - INCPTR(2, p); \ - GETSHORT(cishort, p); \ - GETLONG(cilong, p); \ - no.neg = 1; \ - code \ - } -#endif /* LQR_SUPPORT */ -#define NAKCIENDP(opt, neg) \ - if (go->neg && \ - len >= CILEN_CHAR && \ - p[0] == opt && \ - p[1] >= CILEN_CHAR && \ - p[1] <= len) { \ - len -= p[1]; \ - INCPTR(p[1], p); \ - no.neg = 1; \ - try_.neg = 0; \ - } - - /* - * NOTE! There must be no assignments to individual fields of *go in - * the code below. Any such assignment is a BUG! - */ - /* - * We don't care if they want to send us smaller packets than - * we want. Therefore, accept any MRU less than what we asked for, - * but then ignore the new value when setting the MRU in the kernel. - * If they send us a bigger MRU than what we asked, accept it, up to - * the limit of the default MRU we'd get if we didn't negotiate. - */ - if (go->neg_mru && go->mru != PPP_DEFMRU) { - NAKCISHORT(CI_MRU, neg_mru, - if (cishort <= wo->mru || cishort <= PPP_DEFMRU) - try_.mru = cishort; - ); - } - - /* - * Add any characters they want to our (receive-side) asyncmap. - */ - if (go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF) { - NAKCILONG(CI_ASYNCMAP, neg_asyncmap, - try_.asyncmap = go->asyncmap | cilong; - ); - } - - /* - * If they've nak'd our authentication-protocol, check whether - * they are proposing a different protocol, or a different - * hash algorithm for CHAP. - */ - if ((0 -#if CHAP_SUPPORT - || go->neg_chap -#endif /* CHAP_SUPPORT */ -#if PAP_SUPPORT - || go->neg_upap -#endif /* PAP_SUPPORT */ -#if EAP_SUPPORT - || go->neg_eap -#endif /* EAP_SUPPORT */ - ) - && len >= CILEN_SHORT - && p[0] == CI_AUTHTYPE && p[1] >= CILEN_SHORT && p[1] <= len) { - cilen = p[1]; - len -= cilen; -#if CHAP_SUPPORT - no.neg_chap = go->neg_chap; -#endif /* CHAP_SUPPORT */ -#if PAP_SUPPORT - no.neg_upap = go->neg_upap; -#endif /* PAP_SUPPORT */ -#if EAP_SUPPORT - no.neg_eap = go->neg_eap; -#endif /* EAP_SUPPORT */ - INCPTR(2, p); - GETSHORT(cishort, p); - -#if PAP_SUPPORT - if (cishort == PPP_PAP && cilen == CILEN_SHORT) { -#if EAP_SUPPORT - /* If we were asking for EAP, then we need to stop that. */ - if (go->neg_eap) - try_.neg_eap = 0; - else -#endif /* EAP_SUPPORT */ - -#if CHAP_SUPPORT - /* If we were asking for CHAP, then we need to stop that. */ - if (go->neg_chap) - try_.neg_chap = 0; - else -#endif /* CHAP_SUPPORT */ - - /* - * If we weren't asking for CHAP or EAP, then we were asking for - * PAP, in which case this Nak is bad. - */ - goto bad; - } else -#endif /* PAP_SUPPORT */ - -#if CHAP_SUPPORT - if (cishort == PPP_CHAP && cilen == CILEN_CHAP) { - GETCHAR(cichar, p); -#if EAP_SUPPORT - /* Stop asking for EAP, if we were. */ - if (go->neg_eap) { - try_.neg_eap = 0; - /* Try to set up to use their suggestion, if possible */ - if (CHAP_CANDIGEST(go->chap_mdtype, cichar)) - try_.chap_mdtype = CHAP_MDTYPE_D(cichar); - } else -#endif /* EAP_SUPPORT */ - if (go->neg_chap) { - /* - * We were asking for our preferred algorithm, they must - * want something different. - */ - if (cichar != CHAP_DIGEST(go->chap_mdtype)) { - if (CHAP_CANDIGEST(go->chap_mdtype, cichar)) { - /* Use their suggestion if we support it ... */ - try_.chap_mdtype = CHAP_MDTYPE_D(cichar); - } else { - /* ... otherwise, try our next-preferred algorithm. */ - try_.chap_mdtype &= ~(CHAP_MDTYPE(try_.chap_mdtype)); - if (try_.chap_mdtype == MDTYPE_NONE) /* out of algos */ - try_.neg_chap = 0; - } - } else { - /* - * Whoops, they Nak'd our algorithm of choice - * but then suggested it back to us. - */ - goto bad; - } - } else { - /* - * Stop asking for PAP if we were asking for it. - */ -#if PAP_SUPPORT - try_.neg_upap = 0; -#endif /* PAP_SUPPORT */ - } - - } else -#endif /* CHAP_SUPPORT */ - { - -#if EAP_SUPPORT - /* - * If we were asking for EAP, and they're Conf-Naking EAP, - * well, that's just strange. Nobody should do that. - */ - if (cishort == PPP_EAP && cilen == CILEN_SHORT && go->neg_eap) - ppp_dbglog("Unexpected Conf-Nak for EAP"); - - /* - * We don't recognize what they're suggesting. - * Stop asking for what we were asking for. - */ - if (go->neg_eap) - try_.neg_eap = 0; - else -#endif /* EAP_SUPPORT */ - -#if CHAP_SUPPORT - if (go->neg_chap) - try_.neg_chap = 0; - else -#endif /* CHAP_SUPPORT */ - -#if PAP_SUPPORT - if(1) - try_.neg_upap = 0; - else -#endif /* PAP_SUPPORT */ - {} - - p += cilen - CILEN_SHORT; - } - } - -#if LQR_SUPPORT - /* - * If they can't cope with our link quality protocol, we'll have - * to stop asking for LQR. We haven't got any other protocol. - * If they Nak the reporting period, take their value XXX ? - */ - NAKCILQR(CI_QUALITY, neg_lqr, - if (cishort != PPP_LQR) - try_.neg_lqr = 0; - else - try_.lqr_period = cilong; - ); -#endif /* LQR_SUPPORT */ - - /* - * Only implementing CBCP...not the rest of the callback options - */ - NAKCICHAR(CI_CALLBACK, neg_cbcp, - try_.neg_cbcp = 0; - (void)cichar; /* if CHAP support is not compiled, cichar is set but not used, which makes some compilers complaining */ - ); - - /* - * Check for a looped-back line. - */ - NAKCILONG(CI_MAGICNUMBER, neg_magicnumber, - try_.magicnumber = magic(); - looped_back = 1; - ); - - /* - * Peer shouldn't send Nak for protocol compression or - * address/control compression requests; they should send - * a Reject instead. If they send a Nak, treat it as a Reject. - */ - NAKCIVOID(CI_PCOMPRESSION, neg_pcompression); - NAKCIVOID(CI_ACCOMPRESSION, neg_accompression); - -#ifdef HAVE_MULTILINK - /* - * Nak for MRRU option - accept their value if it is smaller - * than the one we want. - */ - if (go->neg_mrru) { - NAKCISHORT(CI_MRRU, neg_mrru, - if (treat_as_reject) - try_.neg_mrru = 0; - else if (cishort <= wo->mrru) - try_.mrru = cishort; - ); - } -#else /* HAVE_MULTILINK */ - LWIP_UNUSED_ARG(treat_as_reject); -#endif /* HAVE_MULTILINK */ - - /* - * Nak for short sequence numbers shouldn't be sent, treat it - * like a reject. - */ - NAKCIVOID(CI_SSNHF, neg_ssnhf); - - /* - * Nak of the endpoint discriminator option is not permitted, - * treat it like a reject. - */ - NAKCIENDP(CI_EPDISC, neg_endpoint); - - /* - * There may be remaining CIs, if the peer is requesting negotiation - * on an option that we didn't include in our request packet. - * If we see an option that we requested, or one we've already seen - * in this packet, then this packet is bad. - * If we wanted to respond by starting to negotiate on the requested - * option(s), we could, but we don't, because except for the - * authentication type and quality protocol, if we are not negotiating - * an option, it is because we were told not to. - * For the authentication type, the Nak from the peer means - * `let me authenticate myself with you' which is a bit pointless. - * For the quality protocol, the Nak means `ask me to send you quality - * reports', but if we didn't ask for them, we don't want them. - * An option we don't recognize represents the peer asking to - * negotiate some option we don't support, so ignore it. - */ - while (len >= CILEN_VOID) { - GETCHAR(citype, p); - GETCHAR(cilen, p); - if (cilen < CILEN_VOID || (len -= cilen) < 0) - goto bad; - next = p + cilen - 2; - - switch (citype) { - case CI_MRU: - if ((go->neg_mru && go->mru != PPP_DEFMRU) - || no.neg_mru || cilen != CILEN_SHORT) - goto bad; - GETSHORT(cishort, p); - if (cishort < PPP_DEFMRU) { - try_.neg_mru = 1; - try_.mru = cishort; - } - break; - case CI_ASYNCMAP: - if ((go->neg_asyncmap && go->asyncmap != 0xFFFFFFFF) - || no.neg_asyncmap || cilen != CILEN_LONG) - goto bad; - break; - case CI_AUTHTYPE: - if (0 -#if CHAP_SUPPORT - || go->neg_chap || no.neg_chap -#endif /* CHAP_SUPPORT */ -#if PAP_SUPPORT - || go->neg_upap || no.neg_upap -#endif /* PAP_SUPPORT */ -#if EAP_SUPPORT - || go->neg_eap || no.neg_eap -#endif /* EAP_SUPPORT */ - ) - goto bad; - break; - case CI_MAGICNUMBER: - if (go->neg_magicnumber || no.neg_magicnumber || - cilen != CILEN_LONG) - goto bad; - break; - case CI_PCOMPRESSION: - if (go->neg_pcompression || no.neg_pcompression - || cilen != CILEN_VOID) - goto bad; - break; - case CI_ACCOMPRESSION: - if (go->neg_accompression || no.neg_accompression - || cilen != CILEN_VOID) - goto bad; - break; -#if LQR_SUPPORT - case CI_QUALITY: - if (go->neg_lqr || no.neg_lqr || cilen != CILEN_LQR) - goto bad; - break; -#endif /* LQR_SUPPORT */ -#ifdef HAVE_MULTILINK - case CI_MRRU: - if (go->neg_mrru || no.neg_mrru || cilen != CILEN_SHORT) - goto bad; - break; -#endif /* HAVE_MULTILINK */ - case CI_SSNHF: - if (go->neg_ssnhf || no.neg_ssnhf || cilen != CILEN_VOID) - goto bad; - try_.neg_ssnhf = 1; - break; - case CI_EPDISC: - if (go->neg_endpoint || no.neg_endpoint || cilen < CILEN_CHAR) - goto bad; - break; - default: - break; - } - p = next; - } - - /* - * OK, the Nak is good. Now we can update state. - * If there are any options left we ignore them. - */ - if (f->state != PPP_FSM_OPENED) { - if (looped_back) { - if (++try_.numloops >= pcb->settings.lcp_loopbackfail) { - ppp_notice("Serial line is looped back."); - pcb->err_code = PPPERR_LOOPBACK; - lcp_close(f->pcb, "Loopback detected"); - } - } else - try_.numloops = 0; - *go = try_; - } - - return 1; - -bad: - LCPDEBUG(("lcp_nakci: received bad Nak!")); - return 0; -} - - -/* - * lcp_rejci - Peer has Rejected some of our CIs. - * This should not modify any state if the Reject is bad - * or if LCP is in the OPENED state. - * - * Returns: - * 0 - Reject was bad. - * 1 - Reject was good. - */ -static int lcp_rejci(fsm *f, u_char *p, int len) { - ppp_pcb *pcb = f->pcb; - lcp_options *go = &pcb->lcp_gotoptions; - u_char cichar; - u_short cishort; - u32_t cilong; - lcp_options try_; /* options to request next time */ - - try_ = *go; - - /* - * Any Rejected CIs must be in exactly the same order that we sent. - * Check packet length and CI length at each step. - * If we find any deviations, then this packet is bad. - */ -#define REJCIVOID(opt, neg) \ - if (go->neg && \ - len >= CILEN_VOID && \ - p[1] == CILEN_VOID && \ - p[0] == opt) { \ - len -= CILEN_VOID; \ - INCPTR(CILEN_VOID, p); \ - try_.neg = 0; \ - } -#define REJCISHORT(opt, neg, val) \ - if (go->neg && \ - len >= CILEN_SHORT && \ - p[1] == CILEN_SHORT && \ - p[0] == opt) { \ - len -= CILEN_SHORT; \ - INCPTR(2, p); \ - GETSHORT(cishort, p); \ - /* Check rejected value. */ \ - if (cishort != val) \ - goto bad; \ - try_.neg = 0; \ - } - -#if CHAP_SUPPORT && EAP_SUPPORT && PAP_SUPPORT -#define REJCICHAP(opt, neg, val) \ - if (go->neg && \ - len >= CILEN_CHAP && \ - p[1] == CILEN_CHAP && \ - p[0] == opt) { \ - len -= CILEN_CHAP; \ - INCPTR(2, p); \ - GETSHORT(cishort, p); \ - GETCHAR(cichar, p); \ - /* Check rejected value. */ \ - if ((cishort != PPP_CHAP) || (cichar != (CHAP_DIGEST(val)))) \ - goto bad; \ - try_.neg = 0; \ - try_.neg_eap = try_.neg_upap = 0; \ - } -#endif /* CHAP_SUPPORT && EAP_SUPPORT && PAP_SUPPORT */ - -#if CHAP_SUPPORT && !EAP_SUPPORT && PAP_SUPPORT -#define REJCICHAP(opt, neg, val) \ - if (go->neg && \ - len >= CILEN_CHAP && \ - p[1] == CILEN_CHAP && \ - p[0] == opt) { \ - len -= CILEN_CHAP; \ - INCPTR(2, p); \ - GETSHORT(cishort, p); \ - GETCHAR(cichar, p); \ - /* Check rejected value. */ \ - if ((cishort != PPP_CHAP) || (cichar != (CHAP_DIGEST(val)))) \ - goto bad; \ - try_.neg = 0; \ - try_.neg_upap = 0; \ - } -#endif /* CHAP_SUPPORT && !EAP_SUPPORT && PAP_SUPPORT */ - -#if CHAP_SUPPORT && EAP_SUPPORT && !PAP_SUPPORT -#define REJCICHAP(opt, neg, val) \ - if (go->neg && \ - len >= CILEN_CHAP && \ - p[1] == CILEN_CHAP && \ - p[0] == opt) { \ - len -= CILEN_CHAP; \ - INCPTR(2, p); \ - GETSHORT(cishort, p); \ - GETCHAR(cichar, p); \ - /* Check rejected value. */ \ - if ((cishort != PPP_CHAP) || (cichar != (CHAP_DIGEST(val)))) \ - goto bad; \ - try_.neg = 0; \ - try_.neg_eap = 0; \ - } -#endif /* CHAP_SUPPORT && EAP_SUPPORT && !PAP_SUPPORT */ - -#if CHAP_SUPPORT && !EAP_SUPPORT && !PAP_SUPPORT -#define REJCICHAP(opt, neg, val) \ - if (go->neg && \ - len >= CILEN_CHAP && \ - p[1] == CILEN_CHAP && \ - p[0] == opt) { \ - len -= CILEN_CHAP; \ - INCPTR(2, p); \ - GETSHORT(cishort, p); \ - GETCHAR(cichar, p); \ - /* Check rejected value. */ \ - if ((cishort != PPP_CHAP) || (cichar != (CHAP_DIGEST(val)))) \ - goto bad; \ - try_.neg = 0; \ - } -#endif /* CHAP_SUPPORT && !EAP_SUPPORT && !PAP_SUPPORT */ - -#define REJCILONG(opt, neg, val) \ - if (go->neg && \ - len >= CILEN_LONG && \ - p[1] == CILEN_LONG && \ - p[0] == opt) { \ - len -= CILEN_LONG; \ - INCPTR(2, p); \ - GETLONG(cilong, p); \ - /* Check rejected value. */ \ - if (cilong != val) \ - goto bad; \ - try_.neg = 0; \ - } -#if LQR_SUPPORT -#define REJCILQR(opt, neg, val) \ - if (go->neg && \ - len >= CILEN_LQR && \ - p[1] == CILEN_LQR && \ - p[0] == opt) { \ - len -= CILEN_LQR; \ - INCPTR(2, p); \ - GETSHORT(cishort, p); \ - GETLONG(cilong, p); \ - /* Check rejected value. */ \ - if (cishort != PPP_LQR || cilong != val) \ - goto bad; \ - try_.neg = 0; \ - } -#endif /* LQR_SUPPORT */ -#define REJCICBCP(opt, neg, val) \ - if (go->neg && \ - len >= CILEN_CBCP && \ - p[1] == CILEN_CBCP && \ - p[0] == opt) { \ - len -= CILEN_CBCP; \ - INCPTR(2, p); \ - GETCHAR(cichar, p); \ - /* Check rejected value. */ \ - if (cichar != val) \ - goto bad; \ - try_.neg = 0; \ - } -#define REJCIENDP(opt, neg, class, val, vlen) \ - if (go->neg && \ - len >= CILEN_CHAR + vlen && \ - p[0] == opt && \ - p[1] == CILEN_CHAR + vlen) { \ - int i; \ - len -= CILEN_CHAR + vlen; \ - INCPTR(2, p); \ - GETCHAR(cichar, p); \ - if (cichar != class) \ - goto bad; \ - for (i = 0; i < vlen; ++i) { \ - GETCHAR(cichar, p); \ - if (cichar != val[i]) \ - goto bad; \ - } \ - try_.neg = 0; \ - } - - REJCISHORT(CI_MRU, neg_mru, go->mru); - REJCILONG(CI_ASYNCMAP, neg_asyncmap, go->asyncmap); -#if EAP_SUPPORT - REJCISHORT(CI_AUTHTYPE, neg_eap, PPP_EAP); - if (!go->neg_eap) { -#endif /* EAP_SUPPORT */ -#if CHAP_SUPPORT - REJCICHAP(CI_AUTHTYPE, neg_chap, go->chap_mdtype); - if (!go->neg_chap) { -#endif /* CHAP_SUPPORT */ -#if PAP_SUPPORT - REJCISHORT(CI_AUTHTYPE, neg_upap, PPP_PAP); -#endif /* PAP_SUPPORT */ -#if CHAP_SUPPORT - } -#endif /* CHAP_SUPPORT */ -#if EAP_SUPPORT - } -#endif /* EAP_SUPPORT */ -#if LQR_SUPPORT - REJCILQR(CI_QUALITY, neg_lqr, go->lqr_period); -#endif /* LQR_SUPPORT */ - REJCICBCP(CI_CALLBACK, neg_cbcp, CBCP_OPT); - REJCILONG(CI_MAGICNUMBER, neg_magicnumber, go->magicnumber); - REJCIVOID(CI_PCOMPRESSION, neg_pcompression); - REJCIVOID(CI_ACCOMPRESSION, neg_accompression); -#ifdef HAVE_MULTILINK - REJCISHORT(CI_MRRU, neg_mrru, go->mrru); -#endif /* HAVE_MULTILINK */ - REJCIVOID(CI_SSNHF, neg_ssnhf); - REJCIENDP(CI_EPDISC, neg_endpoint, go->endpoint.class_, - go->endpoint.value, go->endpoint.length); - - /* - * If there are any remaining CIs, then this packet is bad. - */ - if (len != 0) - goto bad; - /* - * Now we can update state. - */ - if (f->state != PPP_FSM_OPENED) - *go = try_; - return 1; - -bad: - LCPDEBUG(("lcp_rejci: received bad Reject!")); - return 0; -} - - -/* - * lcp_reqci - Check the peer's requested CIs and send appropriate response. - * - * Returns: CONFACK, CONFNAK or CONFREJ and input packet modified - * appropriately. If reject_if_disagree is non-zero, doesn't return - * CONFNAK; returns CONFREJ if it can't return CONFACK. - * - * inp = Requested CIs - * lenp = Length of requested CIs - */ -static int lcp_reqci(fsm *f, u_char *inp, int *lenp, int reject_if_disagree) { - ppp_pcb *pcb = f->pcb; - lcp_options *go = &pcb->lcp_gotoptions; - lcp_options *ho = &pcb->lcp_hisoptions; - lcp_options *ao = &pcb->lcp_allowoptions; - u_char *cip, *next; /* Pointer to current and next CIs */ - int cilen, citype, cichar; /* Parsed len, type, char value */ - u_short cishort; /* Parsed short value */ - u32_t cilong; /* Parse long value */ - int rc = CONFACK; /* Final packet return code */ - int orc; /* Individual option return code */ - u_char *p; /* Pointer to next char to parse */ - u_char *rejp; /* Pointer to next char in reject frame */ - struct pbuf *nakp; /* Nak buffer */ - u_char *nakoutp; /* Pointer to next char in Nak frame */ - int l = *lenp; /* Length left */ - - /* - * Reset all his options. - */ - BZERO(ho, sizeof(*ho)); - - /* - * Process all his options. - */ - next = inp; - nakp = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_CTRL_PBUF_MAX_SIZE), PPP_CTRL_PBUF_TYPE); - if(NULL == nakp) - return 0; - if(nakp->tot_len != nakp->len) { - pbuf_free(nakp); - return 0; - } - - nakoutp = (u_char*)nakp->payload; - rejp = inp; - while (l) { - orc = CONFACK; /* Assume success */ - cip = p = next; /* Remember begining of CI */ - if (l < 2 || /* Not enough data for CI header or */ - p[1] < 2 || /* CI length too small or */ - p[1] > l) { /* CI length too big? */ - LCPDEBUG(("lcp_reqci: bad CI length!")); - orc = CONFREJ; /* Reject bad CI */ - cilen = l; /* Reject till end of packet */ - l = 0; /* Don't loop again */ - citype = 0; - goto endswitch; - } - GETCHAR(citype, p); /* Parse CI type */ - GETCHAR(cilen, p); /* Parse CI length */ - l -= cilen; /* Adjust remaining length */ - next += cilen; /* Step to next CI */ - - switch (citype) { /* Check CI type */ - case CI_MRU: - if (!ao->neg_mru || /* Allow option? */ - cilen != CILEN_SHORT) { /* Check CI length */ - orc = CONFREJ; /* Reject CI */ - break; - } - GETSHORT(cishort, p); /* Parse MRU */ - - /* - * He must be able to receive at least our minimum. - * No need to check a maximum. If he sends a large number, - * we'll just ignore it. - */ - if (cishort < PPP_MINMRU) { - orc = CONFNAK; /* Nak CI */ - PUTCHAR(CI_MRU, nakoutp); - PUTCHAR(CILEN_SHORT, nakoutp); - PUTSHORT(PPP_MINMRU, nakoutp); /* Give him a hint */ - break; - } - ho->neg_mru = 1; /* Remember he sent MRU */ - ho->mru = cishort; /* And remember value */ - break; - - case CI_ASYNCMAP: - if (!ao->neg_asyncmap || - cilen != CILEN_LONG) { - orc = CONFREJ; - break; - } - GETLONG(cilong, p); - - /* - * Asyncmap must have set at least the bits - * which are set in lcp_allowoptions[unit].asyncmap. - */ - if ((ao->asyncmap & ~cilong) != 0) { - orc = CONFNAK; - PUTCHAR(CI_ASYNCMAP, nakoutp); - PUTCHAR(CILEN_LONG, nakoutp); - PUTLONG(ao->asyncmap | cilong, nakoutp); - break; - } - ho->neg_asyncmap = 1; - ho->asyncmap = cilong; - break; - - case CI_AUTHTYPE: - if (cilen < CILEN_SHORT || - !(0 -#if PAP_SUPPORT - || ao->neg_upap -#endif /* PAP_SUPPORT */ -#if CHAP_SUPPORT - || ao->neg_chap -#endif /* CHAP_SUPPORT */ -#if EAP_SUPPORT - || ao->neg_eap -#endif /* EAP_SUPPORT */ - )) { - /* - * Reject the option if we're not willing to authenticate. - */ - ppp_dbglog("No auth is possible"); - orc = CONFREJ; - break; - } - GETSHORT(cishort, p); - - /* - * Authtype must be PAP, CHAP, or EAP. - * - * Note: if more than one of ao->neg_upap, ao->neg_chap, and - * ao->neg_eap are set, and the peer sends a Configure-Request - * with two or more authenticate-protocol requests, then we will - * reject the second request. - * Whether we end up doing CHAP, UPAP, or EAP depends then on - * the ordering of the CIs in the peer's Configure-Request. - */ - -#if PAP_SUPPORT - if (cishort == PPP_PAP) { - /* we've already accepted CHAP or EAP */ - if (0 -#if CHAP_SUPPORT - || ho->neg_chap -#endif /* CHAP_SUPPORT */ -#if EAP_SUPPORT - || ho->neg_eap -#endif /* EAP_SUPPORT */ - || cilen != CILEN_SHORT) { - LCPDEBUG(("lcp_reqci: rcvd AUTHTYPE PAP, rejecting...")); - orc = CONFREJ; - break; - } - if (!ao->neg_upap) { /* we don't want to do PAP */ - orc = CONFNAK; /* NAK it and suggest CHAP or EAP */ - PUTCHAR(CI_AUTHTYPE, nakoutp); -#if EAP_SUPPORT - if (ao->neg_eap) { - PUTCHAR(CILEN_SHORT, nakoutp); - PUTSHORT(PPP_EAP, nakoutp); - } else { -#endif /* EAP_SUPPORT */ -#if CHAP_SUPPORT - PUTCHAR(CILEN_CHAP, nakoutp); - PUTSHORT(PPP_CHAP, nakoutp); - PUTCHAR(CHAP_DIGEST(ao->chap_mdtype), nakoutp); -#endif /* CHAP_SUPPORT */ -#if EAP_SUPPORT - } -#endif /* EAP_SUPPORT */ - break; - } - ho->neg_upap = 1; - break; - } -#endif /* PAP_SUPPORT */ -#if CHAP_SUPPORT - if (cishort == PPP_CHAP) { - /* we've already accepted PAP or EAP */ - if ( -#if PAP_SUPPORT - ho->neg_upap || -#endif /* PAP_SUPPORT */ -#if EAP_SUPPORT - ho->neg_eap || -#endif /* EAP_SUPPORT */ - cilen != CILEN_CHAP) { - LCPDEBUG(("lcp_reqci: rcvd AUTHTYPE CHAP, rejecting...")); - orc = CONFREJ; - break; - } - if (!ao->neg_chap) { /* we don't want to do CHAP */ - orc = CONFNAK; /* NAK it and suggest EAP or PAP */ - PUTCHAR(CI_AUTHTYPE, nakoutp); - PUTCHAR(CILEN_SHORT, nakoutp); -#if EAP_SUPPORT - if (ao->neg_eap) { - PUTSHORT(PPP_EAP, nakoutp); - } else -#endif /* EAP_SUPPORT */ -#if PAP_SUPPORT - if(1) { - PUTSHORT(PPP_PAP, nakoutp); - } - else -#endif /* PAP_SUPPORT */ - {} - break; - } - GETCHAR(cichar, p); /* get digest type */ - if (!(CHAP_CANDIGEST(ao->chap_mdtype, cichar))) { - /* - * We can't/won't do the requested type, - * suggest something else. - */ - orc = CONFNAK; - PUTCHAR(CI_AUTHTYPE, nakoutp); - PUTCHAR(CILEN_CHAP, nakoutp); - PUTSHORT(PPP_CHAP, nakoutp); - PUTCHAR(CHAP_DIGEST(ao->chap_mdtype), nakoutp); - break; - } - ho->chap_mdtype = CHAP_MDTYPE_D(cichar); /* save md type */ - ho->neg_chap = 1; - break; - } -#endif /* CHAP_SUPPORT */ -#if EAP_SUPPORT - if (cishort == PPP_EAP) { - /* we've already accepted CHAP or PAP */ - if ( -#if CHAP_SUPPORT - ho->neg_chap || -#endif /* CHAP_SUPPORT */ -#if PAP_SUPPORT - ho->neg_upap || -#endif /* PAP_SUPPORT */ - cilen != CILEN_SHORT) { - LCPDEBUG(("lcp_reqci: rcvd AUTHTYPE EAP, rejecting...")); - orc = CONFREJ; - break; - } - if (!ao->neg_eap) { /* we don't want to do EAP */ - orc = CONFNAK; /* NAK it and suggest CHAP or PAP */ - PUTCHAR(CI_AUTHTYPE, nakoutp); -#if CHAP_SUPPORT - if (ao->neg_chap) { - PUTCHAR(CILEN_CHAP, nakoutp); - PUTSHORT(PPP_CHAP, nakoutp); - PUTCHAR(CHAP_DIGEST(ao->chap_mdtype), nakoutp); - } else -#endif /* CHAP_SUPPORT */ -#if PAP_SUPPORT - if(1) { - PUTCHAR(CILEN_SHORT, nakoutp); - PUTSHORT(PPP_PAP, nakoutp); - } else -#endif /* PAP_SUPPORT */ - {} - break; - } - ho->neg_eap = 1; - break; - } -#endif /* EAP_SUPPORT */ - - /* - * We don't recognize the protocol they're asking for. - * Nak it with something we're willing to do. - * (At this point we know ao->neg_upap || ao->neg_chap || - * ao->neg_eap.) - */ - orc = CONFNAK; - PUTCHAR(CI_AUTHTYPE, nakoutp); - -#if EAP_SUPPORT - if (ao->neg_eap) { - PUTCHAR(CILEN_SHORT, nakoutp); - PUTSHORT(PPP_EAP, nakoutp); - } else -#endif /* EAP_SUPPORT */ -#if CHAP_SUPPORT - if (ao->neg_chap) { - PUTCHAR(CILEN_CHAP, nakoutp); - PUTSHORT(PPP_CHAP, nakoutp); - PUTCHAR(CHAP_DIGEST(ao->chap_mdtype), nakoutp); - } else -#endif /* CHAP_SUPPORT */ -#if PAP_SUPPORT - if(1) { - PUTCHAR(CILEN_SHORT, nakoutp); - PUTSHORT(PPP_PAP, nakoutp); - } else -#endif /* PAP_SUPPORT */ - {} - break; - -#if LQR_SUPPORT - case CI_QUALITY: - if (!ao->neg_lqr || - cilen != CILEN_LQR) { - orc = CONFREJ; - break; - } - - GETSHORT(cishort, p); - GETLONG(cilong, p); - - /* - * Check the protocol and the reporting period. - * XXX When should we Nak this, and what with? - */ - if (cishort != PPP_LQR) { - orc = CONFNAK; - PUTCHAR(CI_QUALITY, nakoutp); - PUTCHAR(CILEN_LQR, nakoutp); - PUTSHORT(PPP_LQR, nakoutp); - PUTLONG(ao->lqr_period, nakoutp); - break; - } - break; -#endif /* LQR_SUPPORT */ - - case CI_MAGICNUMBER: - if (!(ao->neg_magicnumber || go->neg_magicnumber) || - cilen != CILEN_LONG) { - orc = CONFREJ; - break; - } - GETLONG(cilong, p); - - /* - * He must have a different magic number. - */ - if (go->neg_magicnumber && - cilong == go->magicnumber) { - cilong = magic(); /* Don't put magic() inside macro! */ - orc = CONFNAK; - PUTCHAR(CI_MAGICNUMBER, nakoutp); - PUTCHAR(CILEN_LONG, nakoutp); - PUTLONG(cilong, nakoutp); - break; - } - ho->neg_magicnumber = 1; - ho->magicnumber = cilong; - break; - - - case CI_PCOMPRESSION: - if (!ao->neg_pcompression || - cilen != CILEN_VOID) { - orc = CONFREJ; - break; - } - ho->neg_pcompression = 1; - break; - - case CI_ACCOMPRESSION: - if (!ao->neg_accompression || - cilen != CILEN_VOID) { - orc = CONFREJ; - break; - } - ho->neg_accompression = 1; - break; - -#ifdef HAVE_MULTILINK - case CI_MRRU: - if (!ao->neg_mrru - || !multilink - || cilen != CILEN_SHORT) { - orc = CONFREJ; - break; - } - - GETSHORT(cishort, p); - /* possibly should insist on a minimum/maximum MRRU here */ - ho->neg_mrru = 1; - ho->mrru = cishort; - break; -#endif /* HAVE_MULTILINK */ - - case CI_SSNHF: - if (!ao->neg_ssnhf -#ifdef HAVE_MULTILINK - || !multilink -#endif /* HAVE_MULTILINK */ - || cilen != CILEN_VOID) { - orc = CONFREJ; - break; - } - ho->neg_ssnhf = 1; - break; - - case CI_EPDISC: - if (!ao->neg_endpoint || - cilen < CILEN_CHAR || - cilen > CILEN_CHAR + MAX_ENDP_LEN) { - orc = CONFREJ; - break; - } - GETCHAR(cichar, p); - cilen -= CILEN_CHAR; - ho->neg_endpoint = 1; - ho->endpoint.class_ = cichar; - ho->endpoint.length = cilen; - MEMCPY(ho->endpoint.value, p, cilen); - INCPTR(cilen, p); - break; - - default: - LCPDEBUG(("lcp_reqci: rcvd unknown option %d", citype)); - orc = CONFREJ; - break; - } - -endswitch: - if (orc == CONFACK && /* Good CI */ - rc != CONFACK) /* but prior CI wasnt? */ - continue; /* Don't send this one */ - - if (orc == CONFNAK) { /* Nak this CI? */ - if (reject_if_disagree /* Getting fed up with sending NAKs? */ - && citype != CI_MAGICNUMBER) { - orc = CONFREJ; /* Get tough if so */ - } else { - if (rc == CONFREJ) /* Rejecting prior CI? */ - continue; /* Don't send this one */ - rc = CONFNAK; - } - } - if (orc == CONFREJ) { /* Reject this CI */ - rc = CONFREJ; - if (cip != rejp) /* Need to move rejected CI? */ - MEMCPY(rejp, cip, cilen); /* Move it */ - INCPTR(cilen, rejp); /* Update output pointer */ - } - } - - /* - * If we wanted to send additional NAKs (for unsent CIs), the - * code would go here. The extra NAKs would go at *nakoutp. - * At present there are no cases where we want to ask the - * peer to negotiate an option. - */ - - switch (rc) { - case CONFACK: - *lenp = next - inp; - break; - case CONFNAK: - /* - * Copy the Nak'd options from the nak buffer to the caller's buffer. - */ - *lenp = nakoutp - (u_char*)nakp->payload; - MEMCPY(inp, nakp->payload, *lenp); - break; - case CONFREJ: - *lenp = rejp - inp; - break; - default: - break; - } - - pbuf_free(nakp); - LCPDEBUG(("lcp_reqci: returning CONF%s.", CODENAME(rc))); - return (rc); /* Return final code */ -} - - -/* - * lcp_up - LCP has come UP. - */ -static void lcp_up(fsm *f) { - ppp_pcb *pcb = f->pcb; - lcp_options *wo = &pcb->lcp_wantoptions; - lcp_options *ho = &pcb->lcp_hisoptions; - lcp_options *go = &pcb->lcp_gotoptions; - lcp_options *ao = &pcb->lcp_allowoptions; - int mtu, mru; - - if (!go->neg_magicnumber) - go->magicnumber = 0; - if (!ho->neg_magicnumber) - ho->magicnumber = 0; - - /* - * Set our MTU to the smaller of the MTU we wanted and - * the MRU our peer wanted. If we negotiated an MRU, - * set our MRU to the larger of value we wanted and - * the value we got in the negotiation. - * Note on the MTU: the link MTU can be the MRU the peer wanted, - * the interface MTU is set to the lowest of that, the - * MTU we want to use, and our link MRU. - */ - mtu = ho->neg_mru? ho->mru: PPP_MRU; - mru = go->neg_mru? LWIP_MAX(wo->mru, go->mru): PPP_MRU; -#ifdef HAVE_MULTILINK - if (!(multilink && go->neg_mrru && ho->neg_mrru)) -#endif /* HAVE_MULTILINK */ - netif_set_mtu(pcb, LWIP_MIN(LWIP_MIN(mtu, mru), ao->mru)); - ppp_send_config(pcb, mtu, - (ho->neg_asyncmap? ho->asyncmap: 0xffffffff), - ho->neg_pcompression, ho->neg_accompression); - ppp_recv_config(pcb, mru, - (pcb->settings.lax_recv? 0: go->neg_asyncmap? go->asyncmap: 0xffffffff), - go->neg_pcompression, go->neg_accompression); - - if (ho->neg_mru) - pcb->peer_mru = ho->mru; - - lcp_echo_lowerup(f->pcb); /* Enable echo messages */ - - link_established(pcb); -} - - -/* - * lcp_down - LCP has gone DOWN. - * - * Alert other protocols. - */ -static void lcp_down(fsm *f) { - ppp_pcb *pcb = f->pcb; - lcp_options *go = &pcb->lcp_gotoptions; - - lcp_echo_lowerdown(f->pcb); - - link_down(pcb); - - ppp_send_config(pcb, PPP_MRU, 0xffffffff, 0, 0); - ppp_recv_config(pcb, PPP_MRU, - (go->neg_asyncmap? go->asyncmap: 0xffffffff), - go->neg_pcompression, go->neg_accompression); - pcb->peer_mru = PPP_MRU; -} - - -/* - * lcp_starting - LCP needs the lower layer up. - */ -static void lcp_starting(fsm *f) { - ppp_pcb *pcb = f->pcb; - link_required(pcb); -} - - -/* - * lcp_finished - LCP has finished with the lower layer. - */ -static void lcp_finished(fsm *f) { - ppp_pcb *pcb = f->pcb; - link_terminated(pcb); -} - - -#if PRINTPKT_SUPPORT -/* - * lcp_printpkt - print the contents of an LCP packet. - */ -static const char* const lcp_codenames[] = { - "ConfReq", "ConfAck", "ConfNak", "ConfRej", - "TermReq", "TermAck", "CodeRej", "ProtRej", - "EchoReq", "EchoRep", "DiscReq", "Ident", - "TimeRem" -}; - -static int lcp_printpkt(const u_char *p, int plen, - void (*printer) (void *, const char *, ...), void *arg) { - int code, id, len, olen, i; - const u_char *pstart, *optend; - u_short cishort; - u32_t cilong; - - if (plen < HEADERLEN) - return 0; - pstart = p; - GETCHAR(code, p); - GETCHAR(id, p); - GETSHORT(len, p); - if (len < HEADERLEN || len > plen) - return 0; - - if (code >= 1 && code <= (int)LWIP_ARRAYSIZE(lcp_codenames)) - printer(arg, " %s", lcp_codenames[code-1]); - else - printer(arg, " code=0x%x", code); - printer(arg, " id=0x%x", id); - len -= HEADERLEN; - switch (code) { - case CONFREQ: - case CONFACK: - case CONFNAK: - case CONFREJ: - /* print option list */ - while (len >= 2) { - GETCHAR(code, p); - GETCHAR(olen, p); - p -= 2; - if (olen < 2 || olen > len) { - break; - } - printer(arg, " <"); - len -= olen; - optend = p + olen; - switch (code) { - case CI_MRU: - if (olen == CILEN_SHORT) { - p += 2; - GETSHORT(cishort, p); - printer(arg, "mru %d", cishort); - } - break; - case CI_ASYNCMAP: - if (olen == CILEN_LONG) { - p += 2; - GETLONG(cilong, p); - printer(arg, "asyncmap 0x%x", cilong); - } - break; - case CI_AUTHTYPE: - if (olen >= CILEN_SHORT) { - p += 2; - printer(arg, "auth "); - GETSHORT(cishort, p); - switch (cishort) { -#if PAP_SUPPORT - case PPP_PAP: - printer(arg, "pap"); - break; -#endif /* PAP_SUPPORT */ -#if CHAP_SUPPORT - case PPP_CHAP: - printer(arg, "chap"); - if (p < optend) { - switch (*p) { - case CHAP_MD5: - printer(arg, " MD5"); - ++p; - break; -#if MSCHAP_SUPPORT - case CHAP_MICROSOFT: - printer(arg, " MS"); - ++p; - break; - - case CHAP_MICROSOFT_V2: - printer(arg, " MS-v2"); - ++p; - break; -#endif /* MSCHAP_SUPPORT */ - default: - break; - } - } - break; -#endif /* CHAP_SUPPORT */ -#if EAP_SUPPORT - case PPP_EAP: - printer(arg, "eap"); - break; -#endif /* EAP_SUPPORT */ - default: - printer(arg, "0x%x", cishort); - } - } - break; -#if LQR_SUPPORT - case CI_QUALITY: - if (olen >= CILEN_SHORT) { - p += 2; - printer(arg, "quality "); - GETSHORT(cishort, p); - switch (cishort) { - case PPP_LQR: - printer(arg, "lqr"); - break; - default: - printer(arg, "0x%x", cishort); - } - } - break; -#endif /* LQR_SUPPORT */ - case CI_CALLBACK: - if (olen >= CILEN_CHAR) { - p += 2; - printer(arg, "callback "); - GETCHAR(cishort, p); - switch (cishort) { - case CBCP_OPT: - printer(arg, "CBCP"); - break; - default: - printer(arg, "0x%x", cishort); - } - } - break; - case CI_MAGICNUMBER: - if (olen == CILEN_LONG) { - p += 2; - GETLONG(cilong, p); - printer(arg, "magic 0x%x", cilong); - } - break; - case CI_PCOMPRESSION: - if (olen == CILEN_VOID) { - p += 2; - printer(arg, "pcomp"); - } - break; - case CI_ACCOMPRESSION: - if (olen == CILEN_VOID) { - p += 2; - printer(arg, "accomp"); - } - break; - case CI_MRRU: - if (olen == CILEN_SHORT) { - p += 2; - GETSHORT(cishort, p); - printer(arg, "mrru %d", cishort); - } - break; - case CI_SSNHF: - if (olen == CILEN_VOID) { - p += 2; - printer(arg, "ssnhf"); - } - break; - case CI_EPDISC: -#ifdef HAVE_MULTILINK - if (olen >= CILEN_CHAR) { - struct epdisc epd; - p += 2; - GETCHAR(epd.class, p); - epd.length = olen - CILEN_CHAR; - if (epd.length > MAX_ENDP_LEN) - epd.length = MAX_ENDP_LEN; - if (epd.length > 0) { - MEMCPY(epd.value, p, epd.length); - p += epd.length; - } - printer(arg, "endpoint [%s]", epdisc_to_str(&epd)); - } -#else - printer(arg, "endpoint"); -#endif - break; - default: - break; - } - while (p < optend) { - GETCHAR(code, p); - printer(arg, " %.2x", code); - } - printer(arg, ">"); - } - break; - - case TERMACK: - case TERMREQ: - if (len > 0 && *p >= ' ' && *p < 0x7f) { - printer(arg, " "); - ppp_print_string(p, len, printer, arg); - p += len; - len = 0; - } - break; - - case ECHOREQ: - case ECHOREP: - case DISCREQ: - if (len >= 4) { - GETLONG(cilong, p); - printer(arg, " magic=0x%x", cilong); - len -= 4; - } - break; - - case IDENTIF: - case TIMEREM: - if (len >= 4) { - GETLONG(cilong, p); - printer(arg, " magic=0x%x", cilong); - len -= 4; - } - if (code == TIMEREM) { - if (len < 4) - break; - GETLONG(cilong, p); - printer(arg, " seconds=%u", cilong); - len -= 4; - } - if (len > 0) { - printer(arg, " "); - ppp_print_string(p, len, printer, arg); - p += len; - len = 0; - } - break; - default: - break; - } - - /* print the rest of the bytes in the packet */ - for (i = 0; i < len && i < 32; ++i) { - GETCHAR(code, p); - printer(arg, " %.2x", code); - } - if (i < len) { - printer(arg, " ..."); - p += len - i; - } - - return p - pstart; -} -#endif /* PRINTPKT_SUPPORT */ - -/* - * Time to shut down the link because there is nothing out there. - */ - -static void LcpLinkFailure(fsm *f) { - ppp_pcb *pcb = f->pcb; - if (f->state == PPP_FSM_OPENED) { - ppp_info("No response to %d echo-requests", pcb->lcp_echos_pending); - ppp_notice("Serial link appears to be disconnected."); - pcb->err_code = PPPERR_PEERDEAD; - lcp_close(pcb, "Peer not responding"); - } -} - -/* - * Timer expired for the LCP echo requests from this process. - */ - -static void LcpEchoCheck(fsm *f) { - ppp_pcb *pcb = f->pcb; - - LcpSendEchoRequest (f); - if (f->state != PPP_FSM_OPENED) - return; - - /* - * Start the timer for the next interval. - */ - if (pcb->lcp_echo_timer_running) - ppp_warn("assertion lcp_echo_timer_running==0 failed"); - TIMEOUT (LcpEchoTimeout, f, pcb->settings.lcp_echo_interval); - pcb->lcp_echo_timer_running = 1; -} - -/* - * LcpEchoTimeout - Timer expired on the LCP echo - */ - -static void LcpEchoTimeout(void *arg) { - fsm *f = (fsm*)arg; - ppp_pcb *pcb = f->pcb; - if (pcb->lcp_echo_timer_running != 0) { - pcb->lcp_echo_timer_running = 0; - LcpEchoCheck ((fsm *) arg); - } -} - -/* - * LcpEchoReply - LCP has received a reply to the echo - */ - -static void lcp_received_echo_reply(fsm *f, int id, u_char *inp, int len) { - ppp_pcb *pcb = f->pcb; - lcp_options *go = &pcb->lcp_gotoptions; - u32_t magic_val; - LWIP_UNUSED_ARG(id); - - /* Check the magic number - don't count replies from ourselves. */ - if (len < 4) { - ppp_dbglog("lcp: received short Echo-Reply, length %d", len); - return; - } - GETLONG(magic_val, inp); - if (go->neg_magicnumber - && magic_val == go->magicnumber) { - ppp_warn("appear to have received our own echo-reply!"); - return; - } - - /* Reset the number of outstanding echo frames */ - pcb->lcp_echos_pending = 0; -} - -/* - * LcpSendEchoRequest - Send an echo request frame to the peer - */ - -static void LcpSendEchoRequest(fsm *f) { - ppp_pcb *pcb = f->pcb; - lcp_options *go = &pcb->lcp_gotoptions; - u32_t lcp_magic; - u_char pkt[4], *pktp; - - /* - * Detect the failure of the peer at this point. - */ - if (pcb->settings.lcp_echo_fails != 0) { - if (pcb->lcp_echos_pending >= pcb->settings.lcp_echo_fails) { - LcpLinkFailure(f); - pcb->lcp_echos_pending = 0; - } - } - -#if PPP_LCP_ADAPTIVE - /* - * If adaptive echos have been enabled, only send the echo request if - * no traffic was received since the last one. - */ - if (pcb->settings.lcp_echo_adaptive) { - static unsigned int last_pkts_in = 0; - -#if PPP_STATS_SUPPORT - update_link_stats(f->unit); - link_stats_valid = 0; -#endif /* PPP_STATS_SUPPORT */ - - if (link_stats.pkts_in != last_pkts_in) { - last_pkts_in = link_stats.pkts_in; - return; - } - } -#endif - - /* - * Make and send the echo request frame. - */ - if (f->state == PPP_FSM_OPENED) { - lcp_magic = go->magicnumber; - pktp = pkt; - PUTLONG(lcp_magic, pktp); - fsm_sdata(f, ECHOREQ, pcb->lcp_echo_number++, pkt, pktp - pkt); - ++pcb->lcp_echos_pending; - } -} - -/* - * lcp_echo_lowerup - Start the timer for the LCP frame - */ - -static void lcp_echo_lowerup(ppp_pcb *pcb) { - fsm *f = &pcb->lcp_fsm; - - /* Clear the parameters for generating echo frames */ - pcb->lcp_echos_pending = 0; - pcb->lcp_echo_number = 0; - pcb->lcp_echo_timer_running = 0; - - /* If a timeout interval is specified then start the timer */ - if (pcb->settings.lcp_echo_interval != 0) - LcpEchoCheck (f); -} - -/* - * lcp_echo_lowerdown - Stop the timer for the LCP frame - */ - -static void lcp_echo_lowerdown(ppp_pcb *pcb) { - fsm *f = &pcb->lcp_fsm; - - if (pcb->lcp_echo_timer_running != 0) { - UNTIMEOUT (LcpEchoTimeout, f); - pcb->lcp_echo_timer_running = 0; - } -} - -#endif /* PPP_SUPPORT */ diff --git a/third_party/lwip/repo/lwip/src/netif/ppp/magic.c b/third_party/lwip/repo/lwip/src/netif/ppp/magic.c deleted file mode 100644 index d0d87c5e55df84..00000000000000 --- a/third_party/lwip/repo/lwip/src/netif/ppp/magic.c +++ /dev/null @@ -1,294 +0,0 @@ -/* - * magic.c - PPP Magic Number routines. - * - * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name "Carnegie Mellon University" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For permission or any legal - * details, please contact - * Office of Technology Transfer - * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu - * - * 4. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Computing Services - * at Carnegie Mellon University (http://www.cmu.edu/computing/)." - * - * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE - * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ -/***************************************************************************** -* randm.c - Random number generator program file. -* -* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. -* Copyright (c) 1998 by Global Election Systems Inc. -* -* The authors hereby grant permission to use, copy, modify, distribute, -* and license this software and its documentation for any purpose, provided -* that existing copyright notices are retained in all copies and that this -* notice and the following disclaimer are included verbatim in any -* distributions. No written agreement, license, or royalty fee is required -* for any of the authorized uses. -* -* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR -* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -****************************************************************************** -* REVISION HISTORY -* -* 03-01-01 Marc Boucher -* Ported to lwIP. -* 98-06-03 Guy Lancaster , Global Election Systems Inc. -* Extracted from avos. -*****************************************************************************/ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#include "netif/ppp/ppp_impl.h" -#include "netif/ppp/magic.h" - -#if PPP_MD5_RANDM /* Using MD5 for better randomness if enabled */ - -#include "netif/ppp/pppcrypt.h" - -#define MD5_HASH_SIZE 16 -static char magic_randpool[MD5_HASH_SIZE]; /* Pool of randomness. */ -static long magic_randcount; /* Pseudo-random incrementer */ -static u32_t magic_randomseed; /* Seed used for random number generation. */ - -/* - * Churn the randomness pool on a random event. Call this early and often - * on random and semi-random system events to build randomness in time for - * usage. For randomly timed events, pass a null pointer and a zero length - * and this will use the system timer and other sources to add randomness. - * If new random data is available, pass a pointer to that and it will be - * included. - * - * Ref: Applied Cryptography 2nd Ed. by Bruce Schneier p. 427 - */ -static void magic_churnrand(char *rand_data, u32_t rand_len) { - lwip_md5_context md5_ctx; - - /* LWIP_DEBUGF(LOG_INFO, ("magic_churnrand: %u@%P\n", rand_len, rand_data)); */ - lwip_md5_init(&md5_ctx); - lwip_md5_starts(&md5_ctx); - lwip_md5_update(&md5_ctx, (u_char *)magic_randpool, sizeof(magic_randpool)); - if (rand_data) { - lwip_md5_update(&md5_ctx, (u_char *)rand_data, rand_len); - } else { - struct { - /* INCLUDE fields for any system sources of randomness */ - u32_t jiffies; -#ifdef LWIP_RAND - u32_t rand; -#endif /* LWIP_RAND */ - } sys_data; - magic_randomseed += sys_jiffies(); - sys_data.jiffies = magic_randomseed; -#ifdef LWIP_RAND - sys_data.rand = LWIP_RAND(); -#endif /* LWIP_RAND */ - /* Load sys_data fields here. */ - lwip_md5_update(&md5_ctx, (u_char *)&sys_data, sizeof(sys_data)); - } - lwip_md5_finish(&md5_ctx, (u_char *)magic_randpool); - lwip_md5_free(&md5_ctx); -/* LWIP_DEBUGF(LOG_INFO, ("magic_churnrand: -> 0\n")); */ -} - -/* - * Initialize the random number generator. - */ -void magic_init(void) { - magic_churnrand(NULL, 0); -} - -/* - * Randomize our random seed value. - */ -void magic_randomize(void) { - magic_churnrand(NULL, 0); -} - -/* - * magic_random_bytes - Fill a buffer with random bytes. - * - * Use the random pool to generate random data. This degrades to pseudo - * random when used faster than randomness is supplied using magic_churnrand(). - * Note: It's important that there be sufficient randomness in magic_randpool - * before this is called for otherwise the range of the result may be - * narrow enough to make a search feasible. - * - * Ref: Applied Cryptography 2nd Ed. by Bruce Schneier p. 427 - * - * XXX Why does he not just call magic_churnrand() for each block? Probably - * so that you don't ever publish the seed which could possibly help - * predict future values. - * XXX Why don't we preserve md5 between blocks and just update it with - * magic_randcount each time? Probably there is a weakness but I wish that - * it was documented. - */ -void magic_random_bytes(unsigned char *buf, u32_t buf_len) { - lwip_md5_context md5_ctx; - u_char tmp[MD5_HASH_SIZE]; - u32_t n; - - while (buf_len > 0) { - lwip_md5_init(&md5_ctx); - lwip_md5_starts(&md5_ctx); - lwip_md5_update(&md5_ctx, (u_char *)magic_randpool, sizeof(magic_randpool)); - lwip_md5_update(&md5_ctx, (u_char *)&magic_randcount, sizeof(magic_randcount)); - lwip_md5_finish(&md5_ctx, tmp); - lwip_md5_free(&md5_ctx); - magic_randcount++; - n = LWIP_MIN(buf_len, MD5_HASH_SIZE); - MEMCPY(buf, tmp, n); - buf += n; - buf_len -= n; - } -} - -/* - * Return a new random number. - */ -u32_t magic(void) { - u32_t new_rand; - - magic_random_bytes((unsigned char *)&new_rand, sizeof(new_rand)); - - return new_rand; -} - -#else /* PPP_MD5_RANDM */ - -/*****************************/ -/*** LOCAL DATA STRUCTURES ***/ -/*****************************/ -#ifndef LWIP_RAND -static int magic_randomized; /* Set when truely randomized. */ -#endif /* LWIP_RAND */ -static u32_t magic_randomseed; /* Seed used for random number generation. */ - - -/***********************************/ -/*** PUBLIC FUNCTION DEFINITIONS ***/ -/***********************************/ - -/* - * Initialize the random number generator. - * - * Here we attempt to compute a random number seed but even if - * it isn't random, we'll randomize it later. - * - * The current method uses the fields from the real time clock, - * the idle process counter, the millisecond counter, and the - * hardware timer tick counter. When this is invoked - * in startup(), then the idle counter and timer values may - * repeat after each boot and the real time clock may not be - * operational. Thus we call it again on the first random - * event. - */ -void magic_init(void) { - magic_randomseed += sys_jiffies(); -#ifndef LWIP_RAND - /* Initialize the Borland random number generator. */ - srand((unsigned)magic_randomseed); -#endif /* LWIP_RAND */ -} - -/* - * magic_init - Initialize the magic number generator. - * - * Randomize our random seed value. Here we use the fact that - * this function is called at *truely random* times by the polling - * and network functions. Here we only get 16 bits of new random - * value but we use the previous value to randomize the other 16 - * bits. - */ -void magic_randomize(void) { -#ifndef LWIP_RAND - if (!magic_randomized) { - magic_randomized = !0; - magic_init(); - /* The initialization function also updates the seed. */ - } else { -#endif /* LWIP_RAND */ - magic_randomseed += sys_jiffies(); -#ifndef LWIP_RAND - } -#endif /* LWIP_RAND */ -} - -/* - * Return a new random number. - * - * Here we use the Borland rand() function to supply a pseudo random - * number which we make truely random by combining it with our own - * seed which is randomized by truely random events. - * Thus the numbers will be truely random unless there have been no - * operator or network events in which case it will be pseudo random - * seeded by the real time clock. - */ -u32_t magic(void) { -#ifdef LWIP_RAND - return LWIP_RAND() + magic_randomseed; -#else /* LWIP_RAND */ - return ((u32_t)rand() << 16) + (u32_t)rand() + magic_randomseed; -#endif /* LWIP_RAND */ -} - -/* - * magic_random_bytes - Fill a buffer with random bytes. - */ -void magic_random_bytes(unsigned char *buf, u32_t buf_len) { - u32_t new_rand, n; - - while (buf_len > 0) { - new_rand = magic(); - n = LWIP_MIN(buf_len, sizeof(new_rand)); - MEMCPY(buf, &new_rand, n); - buf += n; - buf_len -= n; - } -} -#endif /* PPP_MD5_RANDM */ - -/* - * Return a new random number between 0 and (2^pow)-1 included. - */ -u32_t magic_pow(u8_t pow) { - return magic() & ~(~0UL<. - * Copyright (c) 2002,2003,2004 Google, Inc. - * All rights reserved. - * - * License: - * Permission to use, copy, modify, and distribute this software and its - * documentation is hereby granted, provided that the above copyright - * notice appears in all copies. This software is provided without any - * warranty, express or implied. - * - * Changelog: - * 08/12/05 - Matt Domsch - * Only need extra skb padding on transmit, not receive. - * 06/18/04 - Matt Domsch , Oleg Makarenko - * Use Linux kernel 2.6 arc4 and sha1 routines rather than - * providing our own. - * 2/15/04 - TS: added #include and testing for Kernel - * version before using - * MOD_DEC_USAGE_COUNT/MOD_INC_USAGE_COUNT which are - * deprecated in 2.6 - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT && MPPE_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#include - -#include "lwip/err.h" - -#include "netif/ppp/ppp_impl.h" -#include "netif/ppp/ccp.h" -#include "netif/ppp/mppe.h" -#include "netif/ppp/pppdebug.h" -#include "netif/ppp/pppcrypt.h" - -#define SHA1_SIGNATURE_SIZE 20 - -/* ppp_mppe_state.bits definitions */ -#define MPPE_BIT_A 0x80 /* Encryption table were (re)inititalized */ -#define MPPE_BIT_B 0x40 /* MPPC only (not implemented) */ -#define MPPE_BIT_C 0x20 /* MPPC only (not implemented) */ -#define MPPE_BIT_D 0x10 /* This is an encrypted frame */ - -#define MPPE_BIT_FLUSHED MPPE_BIT_A -#define MPPE_BIT_ENCRYPTED MPPE_BIT_D - -#define MPPE_BITS(p) ((p)[0] & 0xf0) -#define MPPE_CCOUNT(p) ((((p)[0] & 0x0f) << 8) + (p)[1]) -#define MPPE_CCOUNT_SPACE 0x1000 /* The size of the ccount space */ - -#define MPPE_OVHD 2 /* MPPE overhead/packet */ -#define SANITY_MAX 1600 /* Max bogon factor we will tolerate */ - -/* - * Perform the MPPE rekey algorithm, from RFC 3078, sec. 7.3. - * Well, not what's written there, but rather what they meant. - */ -static void mppe_rekey(ppp_mppe_state * state, int initial_key) -{ - lwip_sha1_context sha1_ctx; - u8_t sha1_digest[SHA1_SIGNATURE_SIZE]; - - /* - * Key Derivation, from RFC 3078, RFC 3079. - * Equivalent to Get_Key() for MS-CHAP as described in RFC 3079. - */ - lwip_sha1_init(&sha1_ctx); - lwip_sha1_starts(&sha1_ctx); - lwip_sha1_update(&sha1_ctx, state->master_key, state->keylen); - lwip_sha1_update(&sha1_ctx, mppe_sha1_pad1, SHA1_PAD_SIZE); - lwip_sha1_update(&sha1_ctx, state->session_key, state->keylen); - lwip_sha1_update(&sha1_ctx, mppe_sha1_pad2, SHA1_PAD_SIZE); - lwip_sha1_finish(&sha1_ctx, sha1_digest); - lwip_sha1_free(&sha1_ctx); - MEMCPY(state->session_key, sha1_digest, state->keylen); - - if (!initial_key) { - lwip_arc4_init(&state->arc4); - lwip_arc4_setup(&state->arc4, sha1_digest, state->keylen); - lwip_arc4_crypt(&state->arc4, state->session_key, state->keylen); - lwip_arc4_free(&state->arc4); - } - if (state->keylen == 8) { - /* See RFC 3078 */ - state->session_key[0] = 0xd1; - state->session_key[1] = 0x26; - state->session_key[2] = 0x9e; - } - lwip_arc4_init(&state->arc4); - lwip_arc4_setup(&state->arc4, state->session_key, state->keylen); -} - -/* - * Set key, used by MSCHAP before mppe_init() is actually called by CCP so we - * don't have to keep multiple copies of keys. - */ -void mppe_set_key(ppp_pcb *pcb, ppp_mppe_state *state, u8_t *key) { - LWIP_UNUSED_ARG(pcb); - MEMCPY(state->master_key, key, MPPE_MAX_KEY_LEN); -} - -/* - * Initialize (de)compressor state. - */ -void -mppe_init(ppp_pcb *pcb, ppp_mppe_state *state, u8_t options) -{ -#if PPP_DEBUG - const u8_t *debugstr = (const u8_t*)"mppe_comp_init"; - if (&pcb->mppe_decomp == state) { - debugstr = (const u8_t*)"mppe_decomp_init"; - } -#endif /* PPP_DEBUG */ - - /* Save keys. */ - MEMCPY(state->session_key, state->master_key, sizeof(state->master_key)); - - if (options & MPPE_OPT_128) - state->keylen = 16; - else if (options & MPPE_OPT_40) - state->keylen = 8; - else { - PPPDEBUG(LOG_DEBUG, ("%s[%d]: unknown key length\n", debugstr, - pcb->netif->num)); - lcp_close(pcb, "MPPE required but peer negotiation failed"); - return; - } - if (options & MPPE_OPT_STATEFUL) - state->stateful = 1; - - /* Generate the initial session key. */ - mppe_rekey(state, 1); - -#if PPP_DEBUG - { - int i; - char mkey[sizeof(state->master_key) * 2 + 1]; - char skey[sizeof(state->session_key) * 2 + 1]; - - PPPDEBUG(LOG_DEBUG, ("%s[%d]: initialized with %d-bit %s mode\n", - debugstr, pcb->netif->num, (state->keylen == 16) ? 128 : 40, - (state->stateful) ? "stateful" : "stateless")); - - for (i = 0; i < (int)sizeof(state->master_key); i++) - sprintf(mkey + i * 2, "%02x", state->master_key[i]); - for (i = 0; i < (int)sizeof(state->session_key); i++) - sprintf(skey + i * 2, "%02x", state->session_key[i]); - PPPDEBUG(LOG_DEBUG, - ("%s[%d]: keys: master: %s initial session: %s\n", - debugstr, pcb->netif->num, mkey, skey)); - } -#endif /* PPP_DEBUG */ - - /* - * Initialize the coherency count. The initial value is not specified - * in RFC 3078, but we can make a reasonable assumption that it will - * start at 0. Setting it to the max here makes the comp/decomp code - * do the right thing (determined through experiment). - */ - state->ccount = MPPE_CCOUNT_SPACE - 1; - - /* - * Note that even though we have initialized the key table, we don't - * set the FLUSHED bit. This is contrary to RFC 3078, sec. 3.1. - */ - state->bits = MPPE_BIT_ENCRYPTED; -} - -/* - * We received a CCP Reset-Request (actually, we are sending a Reset-Ack), - * tell the compressor to rekey. Note that we MUST NOT rekey for - * every CCP Reset-Request; we only rekey on the next xmit packet. - * We might get multiple CCP Reset-Requests if our CCP Reset-Ack is lost. - * So, rekeying for every CCP Reset-Request is broken as the peer will not - * know how many times we've rekeyed. (If we rekey and THEN get another - * CCP Reset-Request, we must rekey again.) - */ -void mppe_comp_reset(ppp_pcb *pcb, ppp_mppe_state *state) -{ - LWIP_UNUSED_ARG(pcb); - state->bits |= MPPE_BIT_FLUSHED; -} - -/* - * Compress (encrypt) a packet. - * It's strange to call this a compressor, since the output is always - * MPPE_OVHD + 2 bytes larger than the input. - */ -err_t -mppe_compress(ppp_pcb *pcb, ppp_mppe_state *state, struct pbuf **pb, u16_t protocol) -{ - struct pbuf *n, *np; - u8_t *pl; - err_t err; - - LWIP_UNUSED_ARG(pcb); - - /* TCP stack requires that we don't change the packet payload, therefore we copy - * the whole packet before encryption. - */ - np = pbuf_alloc(PBUF_RAW, MPPE_OVHD + sizeof(protocol) + (*pb)->tot_len, PBUF_POOL); - if (!np) { - return ERR_MEM; - } - - /* Hide MPPE header + protocol */ - pbuf_header(np, -(s16_t)(MPPE_OVHD + sizeof(protocol))); - - if ((err = pbuf_copy(np, *pb)) != ERR_OK) { - pbuf_free(np); - return err; - } - - /* Reveal MPPE header + protocol */ - pbuf_header(np, (s16_t)(MPPE_OVHD + sizeof(protocol))); - - *pb = np; - pl = (u8_t*)np->payload; - - state->ccount = (state->ccount + 1) % MPPE_CCOUNT_SPACE; - PPPDEBUG(LOG_DEBUG, ("mppe_compress[%d]: ccount %d\n", pcb->netif->num, state->ccount)); - /* FIXME: use PUT* macros */ - pl[0] = state->ccount>>8; - pl[1] = state->ccount; - - if (!state->stateful || /* stateless mode */ - ((state->ccount & 0xff) == 0xff) || /* "flag" packet */ - (state->bits & MPPE_BIT_FLUSHED)) { /* CCP Reset-Request */ - /* We must rekey */ - if (state->stateful) { - PPPDEBUG(LOG_DEBUG, ("mppe_compress[%d]: rekeying\n", pcb->netif->num)); - } - mppe_rekey(state, 0); - state->bits |= MPPE_BIT_FLUSHED; - } - pl[0] |= state->bits; - state->bits &= ~MPPE_BIT_FLUSHED; /* reset for next xmit */ - pl += MPPE_OVHD; - - /* Add protocol */ - /* FIXME: add PFC support */ - pl[0] = protocol >> 8; - pl[1] = protocol; - - /* Hide MPPE header */ - pbuf_header(np, -(s16_t)MPPE_OVHD); - - /* Encrypt packet */ - for (n = np; n != NULL; n = n->next) { - lwip_arc4_crypt(&state->arc4, (u8_t*)n->payload, n->len); - if (n->tot_len == n->len) { - break; - } - } - - /* Reveal MPPE header */ - pbuf_header(np, (s16_t)MPPE_OVHD); - - return ERR_OK; -} - -/* - * We received a CCP Reset-Ack. Just ignore it. - */ -void mppe_decomp_reset(ppp_pcb *pcb, ppp_mppe_state *state) -{ - LWIP_UNUSED_ARG(pcb); - LWIP_UNUSED_ARG(state); - return; -} - -/* - * Decompress (decrypt) an MPPE packet. - */ -err_t -mppe_decompress(ppp_pcb *pcb, ppp_mppe_state *state, struct pbuf **pb) -{ - struct pbuf *n0 = *pb, *n; - u8_t *pl; - u16_t ccount; - u8_t flushed; - - /* MPPE Header */ - if (n0->len < MPPE_OVHD) { - PPPDEBUG(LOG_DEBUG, - ("mppe_decompress[%d]: short pkt (%d)\n", - pcb->netif->num, n0->len)); - state->sanity_errors += 100; - goto sanity_error; - } - - pl = (u8_t*)n0->payload; - flushed = MPPE_BITS(pl) & MPPE_BIT_FLUSHED; - ccount = MPPE_CCOUNT(pl); - PPPDEBUG(LOG_DEBUG, ("mppe_decompress[%d]: ccount %d\n", - pcb->netif->num, ccount)); - - /* sanity checks -- terminate with extreme prejudice */ - if (!(MPPE_BITS(pl) & MPPE_BIT_ENCRYPTED)) { - PPPDEBUG(LOG_DEBUG, - ("mppe_decompress[%d]: ENCRYPTED bit not set!\n", - pcb->netif->num)); - state->sanity_errors += 100; - goto sanity_error; - } - if (!state->stateful && !flushed) { - PPPDEBUG(LOG_DEBUG, ("mppe_decompress[%d]: FLUSHED bit not set in " - "stateless mode!\n", pcb->netif->num)); - state->sanity_errors += 100; - goto sanity_error; - } - if (state->stateful && ((ccount & 0xff) == 0xff) && !flushed) { - PPPDEBUG(LOG_DEBUG, ("mppe_decompress[%d]: FLUSHED bit not set on " - "flag packet!\n", pcb->netif->num)); - state->sanity_errors += 100; - goto sanity_error; - } - - /* - * Check the coherency count. - */ - - if (!state->stateful) { - /* Discard late packet */ - if ((ccount - state->ccount) % MPPE_CCOUNT_SPACE > MPPE_CCOUNT_SPACE / 2) { - state->sanity_errors++; - goto sanity_error; - } - - /* RFC 3078, sec 8.1. Rekey for every packet. */ - while (state->ccount != ccount) { - mppe_rekey(state, 0); - state->ccount = (state->ccount + 1) % MPPE_CCOUNT_SPACE; - } - } else { - /* RFC 3078, sec 8.2. */ - if (!state->discard) { - /* normal state */ - state->ccount = (state->ccount + 1) % MPPE_CCOUNT_SPACE; - if (ccount != state->ccount) { - /* - * (ccount > state->ccount) - * Packet loss detected, enter the discard state. - * Signal the peer to rekey (by sending a CCP Reset-Request). - */ - state->discard = 1; - ccp_resetrequest(pcb); - return ERR_BUF; - } - } else { - /* discard state */ - if (!flushed) { - /* ccp.c will be silent (no additional CCP Reset-Requests). */ - return ERR_BUF; - } else { - /* Rekey for every missed "flag" packet. */ - while ((ccount & ~0xff) != - (state->ccount & ~0xff)) { - mppe_rekey(state, 0); - state->ccount = - (state->ccount + - 256) % MPPE_CCOUNT_SPACE; - } - - /* reset */ - state->discard = 0; - state->ccount = ccount; - /* - * Another problem with RFC 3078 here. It implies that the - * peer need not send a Reset-Ack packet. But RFC 1962 - * requires it. Hopefully, M$ does send a Reset-Ack; even - * though it isn't required for MPPE synchronization, it is - * required to reset CCP state. - */ - } - } - if (flushed) - mppe_rekey(state, 0); - } - - /* Hide MPPE header */ - pbuf_header(n0, -(s16_t)(MPPE_OVHD)); - - /* Decrypt the packet. */ - for (n = n0; n != NULL; n = n->next) { - lwip_arc4_crypt(&state->arc4, (u8_t*)n->payload, n->len); - if (n->tot_len == n->len) { - break; - } - } - - /* good packet credit */ - state->sanity_errors >>= 1; - - return ERR_OK; - -sanity_error: - if (state->sanity_errors >= SANITY_MAX) { - /* - * Take LCP down if the peer is sending too many bogons. - * We don't want to do this for a single or just a few - * instances since it could just be due to packet corruption. - */ - lcp_close(pcb, "Too many MPPE errors"); - } - return ERR_BUF; -} - -#endif /* PPP_SUPPORT && MPPE_SUPPORT */ diff --git a/third_party/lwip/repo/lwip/src/netif/ppp/multilink.c b/third_party/lwip/repo/lwip/src/netif/ppp/multilink.c deleted file mode 100644 index 62014e8c87c3bd..00000000000000 --- a/third_party/lwip/repo/lwip/src/netif/ppp/multilink.c +++ /dev/null @@ -1,609 +0,0 @@ -/* - * multilink.c - support routines for multilink. - * - * Copyright (c) 2000-2002 Paul Mackerras. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. The name(s) of the authors of this software must not be used to - * endorse or promote products derived from this software without - * prior written permission. - * - * 3. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Paul Mackerras - * ". - * - * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT && defined(HAVE_MULTILINK) /* don't build if not configured for use in lwipopts.h */ - -/* Multilink support - * - * Multilink uses Samba TDB (Trivial Database Library), which - * we cannot port, because it needs a filesystem. - * - * We have to choose between doing a memory-shared TDB-clone, - * or dropping multilink support at all. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "netif/ppp/ppp_impl.h" - -#include "netif/ppp/fsm.h" -#include "netif/ppp/lcp.h" -#include "netif/ppp/tdb.h" - -bool endpoint_specified; /* user gave explicit endpoint discriminator */ -char *bundle_id; /* identifier for our bundle */ -char *blinks_id; /* key for the list of links */ -bool doing_multilink; /* multilink was enabled and agreed to */ -bool multilink_master; /* we own the multilink bundle */ - -extern TDB_CONTEXT *pppdb; -extern char db_key[]; - -static void make_bundle_links (int append); -static void remove_bundle_link (void); -static void iterate_bundle_links (void (*func) (char *)); - -static int get_default_epdisc (struct epdisc *); -static int parse_num (char *str, const char *key, int *valp); -static int owns_unit (TDB_DATA pid, int unit); - -#define set_ip_epdisc(ep, addr) do { \ - ep->length = 4; \ - ep->value[0] = addr >> 24; \ - ep->value[1] = addr >> 16; \ - ep->value[2] = addr >> 8; \ - ep->value[3] = addr; \ -} while (0) - -#define LOCAL_IP_ADDR(addr) \ - (((addr) & 0xff000000) == 0x0a000000 /* 10.x.x.x */ \ - || ((addr) & 0xfff00000) == 0xac100000 /* 172.16.x.x */ \ - || ((addr) & 0xffff0000) == 0xc0a80000) /* 192.168.x.x */ - -#define process_exists(n) (kill((n), 0) == 0 || errno != ESRCH) - -void -mp_check_options() -{ - lcp_options *wo = &lcp_wantoptions[0]; - lcp_options *ao = &lcp_allowoptions[0]; - - doing_multilink = 0; - if (!multilink) - return; - /* if we're doing multilink, we have to negotiate MRRU */ - if (!wo->neg_mrru) { - /* mrru not specified, default to mru */ - wo->mrru = wo->mru; - wo->neg_mrru = 1; - } - ao->mrru = ao->mru; - ao->neg_mrru = 1; - - if (!wo->neg_endpoint && !noendpoint) { - /* get a default endpoint value */ - wo->neg_endpoint = get_default_epdisc(&wo->endpoint); - } -} - -/* - * Make a new bundle or join us to an existing bundle - * if we are doing multilink. - */ -int -mp_join_bundle() -{ - lcp_options *go = &lcp_gotoptions[0]; - lcp_options *ho = &lcp_hisoptions[0]; - lcp_options *ao = &lcp_allowoptions[0]; - int unit, pppd_pid; - int l, mtu; - char *p; - TDB_DATA key, pid, rec; - - if (doing_multilink) { - /* have previously joined a bundle */ - if (!go->neg_mrru || !ho->neg_mrru) { - notice("oops, didn't get multilink on renegotiation"); - lcp_close(pcb, "multilink required"); - return 0; - } - /* XXX should check the peer_authname and ho->endpoint - are the same as previously */ - return 0; - } - - if (!go->neg_mrru || !ho->neg_mrru) { - /* not doing multilink */ - if (go->neg_mrru) - notice("oops, multilink negotiated only for receive"); - mtu = ho->neg_mru? ho->mru: PPP_MRU; - if (mtu > ao->mru) - mtu = ao->mru; - if (demand) { - /* already have a bundle */ - cfg_bundle(0, 0, 0, 0); - netif_set_mtu(pcb, mtu); - return 0; - } - make_new_bundle(0, 0, 0, 0); - set_ifunit(1); - netif_set_mtu(pcb, mtu); - return 0; - } - - doing_multilink = 1; - - /* - * Find the appropriate bundle or join a new one. - * First we make up a name for the bundle. - * The length estimate is worst-case assuming every - * character has to be quoted. - */ - l = 4 * strlen(peer_authname) + 10; - if (ho->neg_endpoint) - l += 3 * ho->endpoint.length + 8; - if (bundle_name) - l += 3 * strlen(bundle_name) + 2; - bundle_id = malloc(l); - if (bundle_id == 0) - novm("bundle identifier"); - - p = bundle_id; - p += slprintf(p, l-1, "BUNDLE=\"%q\"", peer_authname); - if (ho->neg_endpoint || bundle_name) - *p++ = '/'; - if (ho->neg_endpoint) - p += slprintf(p, bundle_id+l-p, "%s", - epdisc_to_str(&ho->endpoint)); - if (bundle_name) - p += slprintf(p, bundle_id+l-p, "/%v", bundle_name); - - /* Make the key for the list of links belonging to the bundle */ - l = p - bundle_id; - blinks_id = malloc(l + 7); - if (blinks_id == NULL) - novm("bundle links key"); - slprintf(blinks_id, l + 7, "BUNDLE_LINKS=%s", bundle_id + 7); - - /* - * For demand mode, we only need to configure the bundle - * and attach the link. - */ - mtu = LWIP_MIN(ho->mrru, ao->mru); - if (demand) { - cfg_bundle(go->mrru, ho->mrru, go->neg_ssnhf, ho->neg_ssnhf); - netif_set_mtu(pcb, mtu); - script_setenv("BUNDLE", bundle_id + 7, 1); - return 0; - } - - /* - * Check if the bundle ID is already in the database. - */ - unit = -1; - lock_db(); - key.dptr = bundle_id; - key.dsize = p - bundle_id; - pid = tdb_fetch(pppdb, key); - if (pid.dptr != NULL) { - /* bundle ID exists, see if the pppd record exists */ - rec = tdb_fetch(pppdb, pid); - if (rec.dptr != NULL && rec.dsize > 0) { - /* make sure the string is null-terminated */ - rec.dptr[rec.dsize-1] = 0; - /* parse the interface number */ - parse_num(rec.dptr, "IFNAME=ppp", &unit); - /* check the pid value */ - if (!parse_num(rec.dptr, "PPPD_PID=", &pppd_pid) - || !process_exists(pppd_pid) - || !owns_unit(pid, unit)) - unit = -1; - free(rec.dptr); - } - free(pid.dptr); - } - - if (unit >= 0) { - /* attach to existing unit */ - if (bundle_attach(unit)) { - set_ifunit(0); - script_setenv("BUNDLE", bundle_id + 7, 0); - make_bundle_links(1); - unlock_db(); - info("Link attached to %s", ifname); - return 1; - } - /* attach failed because bundle doesn't exist */ - } - - /* we have to make a new bundle */ - make_new_bundle(go->mrru, ho->mrru, go->neg_ssnhf, ho->neg_ssnhf); - set_ifunit(1); - netif_set_mtu(pcb, mtu); - script_setenv("BUNDLE", bundle_id + 7, 1); - make_bundle_links(pcb); - unlock_db(); - info("New bundle %s created", ifname); - multilink_master = 1; - return 0; -} - -void mp_exit_bundle() -{ - lock_db(); - remove_bundle_link(); - unlock_db(); -} - -static void sendhup(char *str) -{ - int pid; - - if (parse_num(str, "PPPD_PID=", &pid) && pid != getpid()) { - if (debug) - dbglog("sending SIGHUP to process %d", pid); - kill(pid, SIGHUP); - } -} - -void mp_bundle_terminated() -{ - TDB_DATA key; - - bundle_terminating = 1; - upper_layers_down(pcb); - notice("Connection terminated."); -#if PPP_STATS_SUPPORT - print_link_stats(); -#endif /* PPP_STATS_SUPPORT */ - if (!demand) { - remove_pidfiles(); - script_unsetenv("IFNAME"); - } - - lock_db(); - destroy_bundle(); - iterate_bundle_links(sendhup); - key.dptr = blinks_id; - key.dsize = strlen(blinks_id); - tdb_delete(pppdb, key); - unlock_db(); - - new_phase(PPP_PHASE_DEAD); - - doing_multilink = 0; - multilink_master = 0; -} - -static void make_bundle_links(int append) -{ - TDB_DATA key, rec; - char *p; - char entry[32]; - int l; - - key.dptr = blinks_id; - key.dsize = strlen(blinks_id); - slprintf(entry, sizeof(entry), "%s;", db_key); - p = entry; - if (append) { - rec = tdb_fetch(pppdb, key); - if (rec.dptr != NULL && rec.dsize > 0) { - rec.dptr[rec.dsize-1] = 0; - if (strstr(rec.dptr, db_key) != NULL) { - /* already in there? strange */ - warn("link entry already exists in tdb"); - return; - } - l = rec.dsize + strlen(entry); - p = malloc(l); - if (p == NULL) - novm("bundle link list"); - slprintf(p, l, "%s%s", rec.dptr, entry); - } else { - warn("bundle link list not found"); - } - if (rec.dptr != NULL) - free(rec.dptr); - } - rec.dptr = p; - rec.dsize = strlen(p) + 1; - if (tdb_store(pppdb, key, rec, TDB_REPLACE)) - error("couldn't %s bundle link list", - append? "update": "create"); - if (p != entry) - free(p); -} - -static void remove_bundle_link() -{ - TDB_DATA key, rec; - char entry[32]; - char *p, *q; - int l; - - key.dptr = blinks_id; - key.dsize = strlen(blinks_id); - slprintf(entry, sizeof(entry), "%s;", db_key); - - rec = tdb_fetch(pppdb, key); - if (rec.dptr == NULL || rec.dsize <= 0) { - if (rec.dptr != NULL) - free(rec.dptr); - return; - } - rec.dptr[rec.dsize-1] = 0; - p = strstr(rec.dptr, entry); - if (p != NULL) { - q = p + strlen(entry); - l = strlen(q) + 1; - memmove(p, q, l); - rec.dsize = p - rec.dptr + l; - if (tdb_store(pppdb, key, rec, TDB_REPLACE)) - error("couldn't update bundle link list (removal)"); - } - free(rec.dptr); -} - -static void iterate_bundle_links(void (*func)(char *)) -{ - TDB_DATA key, rec, pp; - char *p, *q; - - key.dptr = blinks_id; - key.dsize = strlen(blinks_id); - rec = tdb_fetch(pppdb, key); - if (rec.dptr == NULL || rec.dsize <= 0) { - error("bundle link list not found (iterating list)"); - if (rec.dptr != NULL) - free(rec.dptr); - return; - } - p = rec.dptr; - p[rec.dsize-1] = 0; - while ((q = strchr(p, ';')) != NULL) { - *q = 0; - key.dptr = p; - key.dsize = q - p; - pp = tdb_fetch(pppdb, key); - if (pp.dptr != NULL && pp.dsize > 0) { - pp.dptr[pp.dsize-1] = 0; - func(pp.dptr); - } - if (pp.dptr != NULL) - free(pp.dptr); - p = q + 1; - } - free(rec.dptr); -} - -static int -parse_num(str, key, valp) - char *str; - const char *key; - int *valp; -{ - char *p, *endp; - int i; - - p = strstr(str, key); - if (p != 0) { - p += strlen(key); - i = strtol(p, &endp, 10); - if (endp != p && (*endp == 0 || *endp == ';')) { - *valp = i; - return 1; - } - } - return 0; -} - -/* - * Check whether the pppd identified by `key' still owns ppp unit `unit'. - */ -static int -owns_unit(key, unit) - TDB_DATA key; - int unit; -{ - char ifkey[32]; - TDB_DATA kd, vd; - int ret = 0; - - slprintf(ifkey, sizeof(ifkey), "IFNAME=ppp%d", unit); - kd.dptr = ifkey; - kd.dsize = strlen(ifkey); - vd = tdb_fetch(pppdb, kd); - if (vd.dptr != NULL) { - ret = vd.dsize == key.dsize - && memcmp(vd.dptr, key.dptr, vd.dsize) == 0; - free(vd.dptr); - } - return ret; -} - -static int -get_default_epdisc(ep) - struct epdisc *ep; -{ - char *p; - struct hostent *hp; - u32_t addr; - - /* First try for an ethernet MAC address */ - p = get_first_ethernet(); - if (p != 0 && get_if_hwaddr(ep->value, p) >= 0) { - ep->class = EPD_MAC; - ep->length = 6; - return 1; - } - - /* see if our hostname corresponds to a reasonable IP address */ - hp = gethostbyname(hostname); - if (hp != NULL) { - addr = *(u32_t *)hp->h_addr; - if (!bad_ip_adrs(addr)) { - addr = lwip_ntohl(addr); - if (!LOCAL_IP_ADDR(addr)) { - ep->class = EPD_IP; - set_ip_epdisc(ep, addr); - return 1; - } - } - } - - return 0; -} - -/* - * epdisc_to_str - make a printable string from an endpoint discriminator. - */ - -static char *endp_class_names[] = { - "null", "local", "IP", "MAC", "magic", "phone" -}; - -char * -epdisc_to_str(ep) - struct epdisc *ep; -{ - static char str[MAX_ENDP_LEN*3+8]; - u_char *p = ep->value; - int i, mask = 0; - char *q, c, c2; - - if (ep->class == EPD_NULL && ep->length == 0) - return "null"; - if (ep->class == EPD_IP && ep->length == 4) { - u32_t addr; - - GETLONG(addr, p); - slprintf(str, sizeof(str), "IP:%I", lwip_htonl(addr)); - return str; - } - - c = ':'; - c2 = '.'; - if (ep->class == EPD_MAC && ep->length == 6) - c2 = ':'; - else if (ep->class == EPD_MAGIC && (ep->length % 4) == 0) - mask = 3; - q = str; - if (ep->class <= EPD_PHONENUM) - q += slprintf(q, sizeof(str)-1, "%s", - endp_class_names[ep->class]); - else - q += slprintf(q, sizeof(str)-1, "%d", ep->class); - c = ':'; - for (i = 0; i < ep->length && i < MAX_ENDP_LEN; ++i) { - if ((i & mask) == 0) { - *q++ = c; - c = c2; - } - q += slprintf(q, str + sizeof(str) - q, "%.2x", ep->value[i]); - } - return str; -} - -static int hexc_val(int c) -{ - if (c >= 'a') - return c - 'a' + 10; - if (c >= 'A') - return c - 'A' + 10; - return c - '0'; -} - -int -str_to_epdisc(ep, str) - struct epdisc *ep; - char *str; -{ - int i, l; - char *p, *endp; - - for (i = EPD_NULL; i <= EPD_PHONENUM; ++i) { - int sl = strlen(endp_class_names[i]); - if (strncasecmp(str, endp_class_names[i], sl) == 0) { - str += sl; - break; - } - } - if (i > EPD_PHONENUM) { - /* not a class name, try a decimal class number */ - i = strtol(str, &endp, 10); - if (endp == str) - return 0; /* can't parse class number */ - str = endp; - } - ep->class = i; - if (*str == 0) { - ep->length = 0; - return 1; - } - if (*str != ':' && *str != '.') - return 0; - ++str; - - if (i == EPD_IP) { - u32_t addr; - i = parse_dotted_ip(str, &addr); - if (i == 0 || str[i] != 0) - return 0; - set_ip_epdisc(ep, addr); - return 1; - } - if (i == EPD_MAC && get_if_hwaddr(ep->value, str) >= 0) { - ep->length = 6; - return 1; - } - - p = str; - for (l = 0; l < MAX_ENDP_LEN; ++l) { - if (*str == 0) - break; - if (p <= str) - for (p = str; isxdigit(*p); ++p) - ; - i = p - str; - if (i == 0) - return 0; - ep->value[l] = hexc_val(*str++); - if ((i & 1) == 0) - ep->value[l] = (ep->value[l] << 4) + hexc_val(*str++); - if (*str == ':' || *str == '.') - ++str; - } - if (*str != 0 || (ep->class == EPD_MAC && l != 6)) - return 0; - ep->length = l; - return 1; -} - -#endif /* PPP_SUPPORT && HAVE_MULTILINK */ diff --git a/third_party/lwip/repo/lwip/src/netif/ppp/polarssl/README b/third_party/lwip/repo/lwip/src/netif/ppp/polarssl/README deleted file mode 100644 index 3fdf159ec13606..00000000000000 --- a/third_party/lwip/repo/lwip/src/netif/ppp/polarssl/README +++ /dev/null @@ -1,22 +0,0 @@ -About PolarSSL files into lwIP PPP support ------------------------------------------- - -This folder contains some files fetched from the latest BSD release of -the PolarSSL project (PolarSSL 0.10.1-bsd) for ciphers and encryption -methods we need for lwIP PPP support. - -The PolarSSL files were cleaned to contain only the necessary struct -fields and functions needed for lwIP. - -The PolarSSL API was not changed at all, so if you are already using -PolarSSL you can choose to skip the compilation of the included PolarSSL -library into lwIP. - -If you are not using the embedded copy you must include external -libraries into your arch/cc.h port file. - -Beware of the stack requirements which can be a lot larger if you are not -using our cleaned PolarSSL library. - - -PolarSSL project website: http://polarssl.org/ diff --git a/third_party/lwip/repo/lwip/src/netif/ppp/polarssl/arc4.c b/third_party/lwip/repo/lwip/src/netif/ppp/polarssl/arc4.c deleted file mode 100644 index 6e17ec421bd81b..00000000000000 --- a/third_party/lwip/repo/lwip/src/netif/ppp/polarssl/arc4.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * An implementation of the ARCFOUR algorithm - * - * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine - * - * Copyright (C) 2009 Paul Bakker - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the names of PolarSSL or XySSL nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/* - * The ARCFOUR algorithm was publicly disclosed on 94/09. - * - * http://groups.google.com/group/sci.crypt/msg/10a300c9d21afca0 - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT && LWIP_INCLUDED_POLARSSL_ARC4 - -#include "netif/ppp/polarssl/arc4.h" -/* - * ARC4 key schedule - */ -void arc4_setup( arc4_context *ctx, unsigned char *key, int keylen ) -{ - int i, j, k, a; - unsigned char *m; - - ctx->x = 0; - ctx->y = 0; - m = ctx->m; - - for( i = 0; i < 256; i++ ) - m[i] = (unsigned char) i; - - j = k = 0; - - for( i = 0; i < 256; i++, k++ ) - { - if( k >= keylen ) k = 0; - - a = m[i]; - j = ( j + a + key[k] ) & 0xFF; - m[i] = m[j]; - m[j] = (unsigned char) a; - } -} - -/* - * ARC4 cipher function - */ -void arc4_crypt( arc4_context *ctx, unsigned char *buf, int buflen ) -{ - int i, x, y, a, b; - unsigned char *m; - - x = ctx->x; - y = ctx->y; - m = ctx->m; - - for( i = 0; i < buflen; i++ ) - { - x = ( x + 1 ) & 0xFF; a = m[x]; - y = ( y + a ) & 0xFF; b = m[y]; - - m[x] = (unsigned char) b; - m[y] = (unsigned char) a; - - buf[i] = (unsigned char) - ( buf[i] ^ m[(unsigned char)( a + b )] ); - } - - ctx->x = x; - ctx->y = y; -} - -#endif /* PPP_SUPPORT && LWIP_INCLUDED_POLARSSL_DES */ diff --git a/third_party/lwip/repo/lwip/src/netif/ppp/polarssl/des.c b/third_party/lwip/repo/lwip/src/netif/ppp/polarssl/des.c deleted file mode 100644 index 9a89d007bd2d5a..00000000000000 --- a/third_party/lwip/repo/lwip/src/netif/ppp/polarssl/des.c +++ /dev/null @@ -1,422 +0,0 @@ -/* - * FIPS-46-3 compliant Triple-DES implementation - * - * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine - * - * Copyright (C) 2009 Paul Bakker - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the names of PolarSSL or XySSL nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/* - * DES, on which TDES is based, was originally designed by Horst Feistel - * at IBM in 1974, and was adopted as a standard by NIST (formerly NBS). - * - * http://csrc.nist.gov/publications/fips/fips46-3/fips46-3.pdf - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT && LWIP_INCLUDED_POLARSSL_DES - -#include "netif/ppp/polarssl/des.h" - -/* - * 32-bit integer manipulation macros (big endian) - */ -#ifndef GET_ULONG_BE -#define GET_ULONG_BE(n,b,i) \ -{ \ - (n) = ( (unsigned long) (b)[(i) ] << 24 ) \ - | ( (unsigned long) (b)[(i) + 1] << 16 ) \ - | ( (unsigned long) (b)[(i) + 2] << 8 ) \ - | ( (unsigned long) (b)[(i) + 3] ); \ -} -#endif - -#ifndef PUT_ULONG_BE -#define PUT_ULONG_BE(n,b,i) \ -{ \ - (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ - (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ - (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ - (b)[(i) + 3] = (unsigned char) ( (n) ); \ -} -#endif - -/* - * Expanded DES S-boxes - */ -static const unsigned long SB1[64] = -{ - 0x01010400, 0x00000000, 0x00010000, 0x01010404, - 0x01010004, 0x00010404, 0x00000004, 0x00010000, - 0x00000400, 0x01010400, 0x01010404, 0x00000400, - 0x01000404, 0x01010004, 0x01000000, 0x00000004, - 0x00000404, 0x01000400, 0x01000400, 0x00010400, - 0x00010400, 0x01010000, 0x01010000, 0x01000404, - 0x00010004, 0x01000004, 0x01000004, 0x00010004, - 0x00000000, 0x00000404, 0x00010404, 0x01000000, - 0x00010000, 0x01010404, 0x00000004, 0x01010000, - 0x01010400, 0x01000000, 0x01000000, 0x00000400, - 0x01010004, 0x00010000, 0x00010400, 0x01000004, - 0x00000400, 0x00000004, 0x01000404, 0x00010404, - 0x01010404, 0x00010004, 0x01010000, 0x01000404, - 0x01000004, 0x00000404, 0x00010404, 0x01010400, - 0x00000404, 0x01000400, 0x01000400, 0x00000000, - 0x00010004, 0x00010400, 0x00000000, 0x01010004 -}; - -static const unsigned long SB2[64] = -{ - 0x80108020, 0x80008000, 0x00008000, 0x00108020, - 0x00100000, 0x00000020, 0x80100020, 0x80008020, - 0x80000020, 0x80108020, 0x80108000, 0x80000000, - 0x80008000, 0x00100000, 0x00000020, 0x80100020, - 0x00108000, 0x00100020, 0x80008020, 0x00000000, - 0x80000000, 0x00008000, 0x00108020, 0x80100000, - 0x00100020, 0x80000020, 0x00000000, 0x00108000, - 0x00008020, 0x80108000, 0x80100000, 0x00008020, - 0x00000000, 0x00108020, 0x80100020, 0x00100000, - 0x80008020, 0x80100000, 0x80108000, 0x00008000, - 0x80100000, 0x80008000, 0x00000020, 0x80108020, - 0x00108020, 0x00000020, 0x00008000, 0x80000000, - 0x00008020, 0x80108000, 0x00100000, 0x80000020, - 0x00100020, 0x80008020, 0x80000020, 0x00100020, - 0x00108000, 0x00000000, 0x80008000, 0x00008020, - 0x80000000, 0x80100020, 0x80108020, 0x00108000 -}; - -static const unsigned long SB3[64] = -{ - 0x00000208, 0x08020200, 0x00000000, 0x08020008, - 0x08000200, 0x00000000, 0x00020208, 0x08000200, - 0x00020008, 0x08000008, 0x08000008, 0x00020000, - 0x08020208, 0x00020008, 0x08020000, 0x00000208, - 0x08000000, 0x00000008, 0x08020200, 0x00000200, - 0x00020200, 0x08020000, 0x08020008, 0x00020208, - 0x08000208, 0x00020200, 0x00020000, 0x08000208, - 0x00000008, 0x08020208, 0x00000200, 0x08000000, - 0x08020200, 0x08000000, 0x00020008, 0x00000208, - 0x00020000, 0x08020200, 0x08000200, 0x00000000, - 0x00000200, 0x00020008, 0x08020208, 0x08000200, - 0x08000008, 0x00000200, 0x00000000, 0x08020008, - 0x08000208, 0x00020000, 0x08000000, 0x08020208, - 0x00000008, 0x00020208, 0x00020200, 0x08000008, - 0x08020000, 0x08000208, 0x00000208, 0x08020000, - 0x00020208, 0x00000008, 0x08020008, 0x00020200 -}; - -static const unsigned long SB4[64] = -{ - 0x00802001, 0x00002081, 0x00002081, 0x00000080, - 0x00802080, 0x00800081, 0x00800001, 0x00002001, - 0x00000000, 0x00802000, 0x00802000, 0x00802081, - 0x00000081, 0x00000000, 0x00800080, 0x00800001, - 0x00000001, 0x00002000, 0x00800000, 0x00802001, - 0x00000080, 0x00800000, 0x00002001, 0x00002080, - 0x00800081, 0x00000001, 0x00002080, 0x00800080, - 0x00002000, 0x00802080, 0x00802081, 0x00000081, - 0x00800080, 0x00800001, 0x00802000, 0x00802081, - 0x00000081, 0x00000000, 0x00000000, 0x00802000, - 0x00002080, 0x00800080, 0x00800081, 0x00000001, - 0x00802001, 0x00002081, 0x00002081, 0x00000080, - 0x00802081, 0x00000081, 0x00000001, 0x00002000, - 0x00800001, 0x00002001, 0x00802080, 0x00800081, - 0x00002001, 0x00002080, 0x00800000, 0x00802001, - 0x00000080, 0x00800000, 0x00002000, 0x00802080 -}; - -static const unsigned long SB5[64] = -{ - 0x00000100, 0x02080100, 0x02080000, 0x42000100, - 0x00080000, 0x00000100, 0x40000000, 0x02080000, - 0x40080100, 0x00080000, 0x02000100, 0x40080100, - 0x42000100, 0x42080000, 0x00080100, 0x40000000, - 0x02000000, 0x40080000, 0x40080000, 0x00000000, - 0x40000100, 0x42080100, 0x42080100, 0x02000100, - 0x42080000, 0x40000100, 0x00000000, 0x42000000, - 0x02080100, 0x02000000, 0x42000000, 0x00080100, - 0x00080000, 0x42000100, 0x00000100, 0x02000000, - 0x40000000, 0x02080000, 0x42000100, 0x40080100, - 0x02000100, 0x40000000, 0x42080000, 0x02080100, - 0x40080100, 0x00000100, 0x02000000, 0x42080000, - 0x42080100, 0x00080100, 0x42000000, 0x42080100, - 0x02080000, 0x00000000, 0x40080000, 0x42000000, - 0x00080100, 0x02000100, 0x40000100, 0x00080000, - 0x00000000, 0x40080000, 0x02080100, 0x40000100 -}; - -static const unsigned long SB6[64] = -{ - 0x20000010, 0x20400000, 0x00004000, 0x20404010, - 0x20400000, 0x00000010, 0x20404010, 0x00400000, - 0x20004000, 0x00404010, 0x00400000, 0x20000010, - 0x00400010, 0x20004000, 0x20000000, 0x00004010, - 0x00000000, 0x00400010, 0x20004010, 0x00004000, - 0x00404000, 0x20004010, 0x00000010, 0x20400010, - 0x20400010, 0x00000000, 0x00404010, 0x20404000, - 0x00004010, 0x00404000, 0x20404000, 0x20000000, - 0x20004000, 0x00000010, 0x20400010, 0x00404000, - 0x20404010, 0x00400000, 0x00004010, 0x20000010, - 0x00400000, 0x20004000, 0x20000000, 0x00004010, - 0x20000010, 0x20404010, 0x00404000, 0x20400000, - 0x00404010, 0x20404000, 0x00000000, 0x20400010, - 0x00000010, 0x00004000, 0x20400000, 0x00404010, - 0x00004000, 0x00400010, 0x20004010, 0x00000000, - 0x20404000, 0x20000000, 0x00400010, 0x20004010 -}; - -static const unsigned long SB7[64] = -{ - 0x00200000, 0x04200002, 0x04000802, 0x00000000, - 0x00000800, 0x04000802, 0x00200802, 0x04200800, - 0x04200802, 0x00200000, 0x00000000, 0x04000002, - 0x00000002, 0x04000000, 0x04200002, 0x00000802, - 0x04000800, 0x00200802, 0x00200002, 0x04000800, - 0x04000002, 0x04200000, 0x04200800, 0x00200002, - 0x04200000, 0x00000800, 0x00000802, 0x04200802, - 0x00200800, 0x00000002, 0x04000000, 0x00200800, - 0x04000000, 0x00200800, 0x00200000, 0x04000802, - 0x04000802, 0x04200002, 0x04200002, 0x00000002, - 0x00200002, 0x04000000, 0x04000800, 0x00200000, - 0x04200800, 0x00000802, 0x00200802, 0x04200800, - 0x00000802, 0x04000002, 0x04200802, 0x04200000, - 0x00200800, 0x00000000, 0x00000002, 0x04200802, - 0x00000000, 0x00200802, 0x04200000, 0x00000800, - 0x04000002, 0x04000800, 0x00000800, 0x00200002 -}; - -static const unsigned long SB8[64] = -{ - 0x10001040, 0x00001000, 0x00040000, 0x10041040, - 0x10000000, 0x10001040, 0x00000040, 0x10000000, - 0x00040040, 0x10040000, 0x10041040, 0x00041000, - 0x10041000, 0x00041040, 0x00001000, 0x00000040, - 0x10040000, 0x10000040, 0x10001000, 0x00001040, - 0x00041000, 0x00040040, 0x10040040, 0x10041000, - 0x00001040, 0x00000000, 0x00000000, 0x10040040, - 0x10000040, 0x10001000, 0x00041040, 0x00040000, - 0x00041040, 0x00040000, 0x10041000, 0x00001000, - 0x00000040, 0x10040040, 0x00001000, 0x00041040, - 0x10001000, 0x00000040, 0x10000040, 0x10040000, - 0x10040040, 0x10000000, 0x00040000, 0x10001040, - 0x00000000, 0x10041040, 0x00040040, 0x10000040, - 0x10040000, 0x10001000, 0x10001040, 0x00000000, - 0x10041040, 0x00041000, 0x00041000, 0x00001040, - 0x00001040, 0x00040040, 0x10000000, 0x10041000 -}; - -/* - * PC1: left and right halves bit-swap - */ -static const unsigned long LHs[16] = -{ - 0x00000000, 0x00000001, 0x00000100, 0x00000101, - 0x00010000, 0x00010001, 0x00010100, 0x00010101, - 0x01000000, 0x01000001, 0x01000100, 0x01000101, - 0x01010000, 0x01010001, 0x01010100, 0x01010101 -}; - -static const unsigned long RHs[16] = -{ - 0x00000000, 0x01000000, 0x00010000, 0x01010000, - 0x00000100, 0x01000100, 0x00010100, 0x01010100, - 0x00000001, 0x01000001, 0x00010001, 0x01010001, - 0x00000101, 0x01000101, 0x00010101, 0x01010101, -}; - -/* - * Initial Permutation macro - */ -#define DES_IP(X,Y) \ -{ \ - T = ((X >> 4) ^ Y) & 0x0F0F0F0F; Y ^= T; X ^= (T << 4); \ - T = ((X >> 16) ^ Y) & 0x0000FFFF; Y ^= T; X ^= (T << 16); \ - T = ((Y >> 2) ^ X) & 0x33333333; X ^= T; Y ^= (T << 2); \ - T = ((Y >> 8) ^ X) & 0x00FF00FF; X ^= T; Y ^= (T << 8); \ - Y = ((Y << 1) | (Y >> 31)) & 0xFFFFFFFF; \ - T = (X ^ Y) & 0xAAAAAAAA; Y ^= T; X ^= T; \ - X = ((X << 1) | (X >> 31)) & 0xFFFFFFFF; \ -} - -/* - * Final Permutation macro - */ -#define DES_FP(X,Y) \ -{ \ - X = ((X << 31) | (X >> 1)) & 0xFFFFFFFF; \ - T = (X ^ Y) & 0xAAAAAAAA; X ^= T; Y ^= T; \ - Y = ((Y << 31) | (Y >> 1)) & 0xFFFFFFFF; \ - T = ((Y >> 8) ^ X) & 0x00FF00FF; X ^= T; Y ^= (T << 8); \ - T = ((Y >> 2) ^ X) & 0x33333333; X ^= T; Y ^= (T << 2); \ - T = ((X >> 16) ^ Y) & 0x0000FFFF; Y ^= T; X ^= (T << 16); \ - T = ((X >> 4) ^ Y) & 0x0F0F0F0F; Y ^= T; X ^= (T << 4); \ -} - -/* - * DES round macro - */ -#define DES_ROUND(X,Y) \ -{ \ - T = *SK++ ^ X; \ - Y ^= SB8[ (T ) & 0x3F ] ^ \ - SB6[ (T >> 8) & 0x3F ] ^ \ - SB4[ (T >> 16) & 0x3F ] ^ \ - SB2[ (T >> 24) & 0x3F ]; \ - \ - T = *SK++ ^ ((X << 28) | (X >> 4)); \ - Y ^= SB7[ (T ) & 0x3F ] ^ \ - SB5[ (T >> 8) & 0x3F ] ^ \ - SB3[ (T >> 16) & 0x3F ] ^ \ - SB1[ (T >> 24) & 0x3F ]; \ -} - -#define SWAP(a,b) { unsigned long t = a; a = b; b = t; t = 0; } - -static void des_setkey( unsigned long SK[32], unsigned char key[8] ) -{ - int i; - unsigned long X, Y, T; - - GET_ULONG_BE( X, key, 0 ); - GET_ULONG_BE( Y, key, 4 ); - - /* - * Permuted Choice 1 - */ - T = ((Y >> 4) ^ X) & 0x0F0F0F0F; X ^= T; Y ^= (T << 4); - T = ((Y ) ^ X) & 0x10101010; X ^= T; Y ^= (T ); - - X = (LHs[ (X ) & 0xF] << 3) | (LHs[ (X >> 8) & 0xF ] << 2) - | (LHs[ (X >> 16) & 0xF] << 1) | (LHs[ (X >> 24) & 0xF ] ) - | (LHs[ (X >> 5) & 0xF] << 7) | (LHs[ (X >> 13) & 0xF ] << 6) - | (LHs[ (X >> 21) & 0xF] << 5) | (LHs[ (X >> 29) & 0xF ] << 4); - - Y = (RHs[ (Y >> 1) & 0xF] << 3) | (RHs[ (Y >> 9) & 0xF ] << 2) - | (RHs[ (Y >> 17) & 0xF] << 1) | (RHs[ (Y >> 25) & 0xF ] ) - | (RHs[ (Y >> 4) & 0xF] << 7) | (RHs[ (Y >> 12) & 0xF ] << 6) - | (RHs[ (Y >> 20) & 0xF] << 5) | (RHs[ (Y >> 28) & 0xF ] << 4); - - X &= 0x0FFFFFFF; - Y &= 0x0FFFFFFF; - - /* - * calculate subkeys - */ - for( i = 0; i < 16; i++ ) - { - if( i < 2 || i == 8 || i == 15 ) - { - X = ((X << 1) | (X >> 27)) & 0x0FFFFFFF; - Y = ((Y << 1) | (Y >> 27)) & 0x0FFFFFFF; - } - else - { - X = ((X << 2) | (X >> 26)) & 0x0FFFFFFF; - Y = ((Y << 2) | (Y >> 26)) & 0x0FFFFFFF; - } - - *SK++ = ((X << 4) & 0x24000000) | ((X << 28) & 0x10000000) - | ((X << 14) & 0x08000000) | ((X << 18) & 0x02080000) - | ((X << 6) & 0x01000000) | ((X << 9) & 0x00200000) - | ((X >> 1) & 0x00100000) | ((X << 10) & 0x00040000) - | ((X << 2) & 0x00020000) | ((X >> 10) & 0x00010000) - | ((Y >> 13) & 0x00002000) | ((Y >> 4) & 0x00001000) - | ((Y << 6) & 0x00000800) | ((Y >> 1) & 0x00000400) - | ((Y >> 14) & 0x00000200) | ((Y ) & 0x00000100) - | ((Y >> 5) & 0x00000020) | ((Y >> 10) & 0x00000010) - | ((Y >> 3) & 0x00000008) | ((Y >> 18) & 0x00000004) - | ((Y >> 26) & 0x00000002) | ((Y >> 24) & 0x00000001); - - *SK++ = ((X << 15) & 0x20000000) | ((X << 17) & 0x10000000) - | ((X << 10) & 0x08000000) | ((X << 22) & 0x04000000) - | ((X >> 2) & 0x02000000) | ((X << 1) & 0x01000000) - | ((X << 16) & 0x00200000) | ((X << 11) & 0x00100000) - | ((X << 3) & 0x00080000) | ((X >> 6) & 0x00040000) - | ((X << 15) & 0x00020000) | ((X >> 4) & 0x00010000) - | ((Y >> 2) & 0x00002000) | ((Y << 8) & 0x00001000) - | ((Y >> 14) & 0x00000808) | ((Y >> 9) & 0x00000400) - | ((Y ) & 0x00000200) | ((Y << 7) & 0x00000100) - | ((Y >> 7) & 0x00000020) | ((Y >> 3) & 0x00000011) - | ((Y << 2) & 0x00000004) | ((Y >> 21) & 0x00000002); - } -} - -/* - * DES key schedule (56-bit, encryption) - */ -void des_setkey_enc( des_context *ctx, unsigned char key[8] ) -{ - des_setkey( ctx->sk, key ); -} - -/* - * DES key schedule (56-bit, decryption) - */ -void des_setkey_dec( des_context *ctx, unsigned char key[8] ) -{ - int i; - - des_setkey( ctx->sk, key ); - - for( i = 0; i < 16; i += 2 ) - { - SWAP( ctx->sk[i ], ctx->sk[30 - i] ); - SWAP( ctx->sk[i + 1], ctx->sk[31 - i] ); - } -} - -/* - * DES-ECB block encryption/decryption - */ -void des_crypt_ecb( des_context *ctx, - const unsigned char input[8], - unsigned char output[8] ) -{ - int i; - unsigned long X, Y, T, *SK; - - SK = ctx->sk; - - GET_ULONG_BE( X, input, 0 ); - GET_ULONG_BE( Y, input, 4 ); - - DES_IP( X, Y ); - - for( i = 0; i < 8; i++ ) - { - DES_ROUND( Y, X ); - DES_ROUND( X, Y ); - } - - DES_FP( Y, X ); - - PUT_ULONG_BE( Y, output, 0 ); - PUT_ULONG_BE( X, output, 4 ); -} - -#endif /* PPP_SUPPORT && LWIP_INCLUDED_POLARSSL_DES */ diff --git a/third_party/lwip/repo/lwip/src/netif/ppp/polarssl/md4.c b/third_party/lwip/repo/lwip/src/netif/ppp/polarssl/md4.c deleted file mode 100644 index b1701a07b998a8..00000000000000 --- a/third_party/lwip/repo/lwip/src/netif/ppp/polarssl/md4.c +++ /dev/null @@ -1,281 +0,0 @@ -/* - * RFC 1186/1320 compliant MD4 implementation - * - * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine - * - * Copyright (C) 2009 Paul Bakker - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the names of PolarSSL or XySSL nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/* - * The MD4 algorithm was designed by Ron Rivest in 1990. - * - * http://www.ietf.org/rfc/rfc1186.txt - * http://www.ietf.org/rfc/rfc1320.txt - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT && LWIP_INCLUDED_POLARSSL_MD4 - -#include "netif/ppp/polarssl/md4.h" - -#include - -/* - * 32-bit integer manipulation macros (little endian) - */ -#ifndef GET_ULONG_LE -#define GET_ULONG_LE(n,b,i) \ -{ \ - (n) = ( (unsigned long) (b)[(i) ] ) \ - | ( (unsigned long) (b)[(i) + 1] << 8 ) \ - | ( (unsigned long) (b)[(i) + 2] << 16 ) \ - | ( (unsigned long) (b)[(i) + 3] << 24 ); \ -} -#endif - -#ifndef PUT_ULONG_LE -#define PUT_ULONG_LE(n,b,i) \ -{ \ - (b)[(i) ] = (unsigned char) ( (n) ); \ - (b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \ - (b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \ - (b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \ -} -#endif - -/* - * MD4 context setup - */ -void md4_starts( md4_context *ctx ) -{ - ctx->total[0] = 0; - ctx->total[1] = 0; - - ctx->state[0] = 0x67452301; - ctx->state[1] = 0xEFCDAB89; - ctx->state[2] = 0x98BADCFE; - ctx->state[3] = 0x10325476; -} - -static void md4_process( md4_context *ctx, const unsigned char data[64] ) -{ - unsigned long X[16], A, B, C, D; - - GET_ULONG_LE( X[ 0], data, 0 ); - GET_ULONG_LE( X[ 1], data, 4 ); - GET_ULONG_LE( X[ 2], data, 8 ); - GET_ULONG_LE( X[ 3], data, 12 ); - GET_ULONG_LE( X[ 4], data, 16 ); - GET_ULONG_LE( X[ 5], data, 20 ); - GET_ULONG_LE( X[ 6], data, 24 ); - GET_ULONG_LE( X[ 7], data, 28 ); - GET_ULONG_LE( X[ 8], data, 32 ); - GET_ULONG_LE( X[ 9], data, 36 ); - GET_ULONG_LE( X[10], data, 40 ); - GET_ULONG_LE( X[11], data, 44 ); - GET_ULONG_LE( X[12], data, 48 ); - GET_ULONG_LE( X[13], data, 52 ); - GET_ULONG_LE( X[14], data, 56 ); - GET_ULONG_LE( X[15], data, 60 ); - -#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) - - A = ctx->state[0]; - B = ctx->state[1]; - C = ctx->state[2]; - D = ctx->state[3]; - -#define F(x, y, z) ((x & y) | ((~x) & z)) -#define P(a,b,c,d,x,s) { a += F(b,c,d) + x; a = S(a,s); } - - P( A, B, C, D, X[ 0], 3 ); - P( D, A, B, C, X[ 1], 7 ); - P( C, D, A, B, X[ 2], 11 ); - P( B, C, D, A, X[ 3], 19 ); - P( A, B, C, D, X[ 4], 3 ); - P( D, A, B, C, X[ 5], 7 ); - P( C, D, A, B, X[ 6], 11 ); - P( B, C, D, A, X[ 7], 19 ); - P( A, B, C, D, X[ 8], 3 ); - P( D, A, B, C, X[ 9], 7 ); - P( C, D, A, B, X[10], 11 ); - P( B, C, D, A, X[11], 19 ); - P( A, B, C, D, X[12], 3 ); - P( D, A, B, C, X[13], 7 ); - P( C, D, A, B, X[14], 11 ); - P( B, C, D, A, X[15], 19 ); - -#undef P -#undef F - -#define F(x,y,z) ((x & y) | (x & z) | (y & z)) -#define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x5A827999; a = S(a,s); } - - P( A, B, C, D, X[ 0], 3 ); - P( D, A, B, C, X[ 4], 5 ); - P( C, D, A, B, X[ 8], 9 ); - P( B, C, D, A, X[12], 13 ); - P( A, B, C, D, X[ 1], 3 ); - P( D, A, B, C, X[ 5], 5 ); - P( C, D, A, B, X[ 9], 9 ); - P( B, C, D, A, X[13], 13 ); - P( A, B, C, D, X[ 2], 3 ); - P( D, A, B, C, X[ 6], 5 ); - P( C, D, A, B, X[10], 9 ); - P( B, C, D, A, X[14], 13 ); - P( A, B, C, D, X[ 3], 3 ); - P( D, A, B, C, X[ 7], 5 ); - P( C, D, A, B, X[11], 9 ); - P( B, C, D, A, X[15], 13 ); - -#undef P -#undef F - -#define F(x,y,z) (x ^ y ^ z) -#define P(a,b,c,d,x,s) { a += F(b,c,d) + x + 0x6ED9EBA1; a = S(a,s); } - - P( A, B, C, D, X[ 0], 3 ); - P( D, A, B, C, X[ 8], 9 ); - P( C, D, A, B, X[ 4], 11 ); - P( B, C, D, A, X[12], 15 ); - P( A, B, C, D, X[ 2], 3 ); - P( D, A, B, C, X[10], 9 ); - P( C, D, A, B, X[ 6], 11 ); - P( B, C, D, A, X[14], 15 ); - P( A, B, C, D, X[ 1], 3 ); - P( D, A, B, C, X[ 9], 9 ); - P( C, D, A, B, X[ 5], 11 ); - P( B, C, D, A, X[13], 15 ); - P( A, B, C, D, X[ 3], 3 ); - P( D, A, B, C, X[11], 9 ); - P( C, D, A, B, X[ 7], 11 ); - P( B, C, D, A, X[15], 15 ); - -#undef F -#undef P - - ctx->state[0] += A; - ctx->state[1] += B; - ctx->state[2] += C; - ctx->state[3] += D; -} - -/* - * MD4 process buffer - */ -void md4_update( md4_context *ctx, const unsigned char *input, int ilen ) -{ - int fill; - unsigned long left; - - if( ilen <= 0 ) - return; - - left = ctx->total[0] & 0x3F; - fill = 64 - left; - - ctx->total[0] += ilen; - ctx->total[0] &= 0xFFFFFFFF; - - if( ctx->total[0] < (unsigned long) ilen ) - ctx->total[1]++; - - if( left && ilen >= fill ) - { - MEMCPY( (void *) (ctx->buffer + left), - input, fill ); - md4_process( ctx, ctx->buffer ); - input += fill; - ilen -= fill; - left = 0; - } - - while( ilen >= 64 ) - { - md4_process( ctx, input ); - input += 64; - ilen -= 64; - } - - if( ilen > 0 ) - { - MEMCPY( (void *) (ctx->buffer + left), - input, ilen ); - } -} - -static const unsigned char md4_padding[64] = -{ - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -/* - * MD4 final digest - */ -void md4_finish( md4_context *ctx, unsigned char output[16] ) -{ - unsigned long last, padn; - unsigned long high, low; - unsigned char msglen[8]; - - high = ( ctx->total[0] >> 29 ) - | ( ctx->total[1] << 3 ); - low = ( ctx->total[0] << 3 ); - - PUT_ULONG_LE( low, msglen, 0 ); - PUT_ULONG_LE( high, msglen, 4 ); - - last = ctx->total[0] & 0x3F; - padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); - - md4_update( ctx, md4_padding, padn ); - md4_update( ctx, msglen, 8 ); - - PUT_ULONG_LE( ctx->state[0], output, 0 ); - PUT_ULONG_LE( ctx->state[1], output, 4 ); - PUT_ULONG_LE( ctx->state[2], output, 8 ); - PUT_ULONG_LE( ctx->state[3], output, 12 ); -} - -/* - * output = MD4( input buffer ) - */ -void md4( unsigned char *input, int ilen, unsigned char output[16] ) -{ - md4_context ctx; - - md4_starts( &ctx ); - md4_update( &ctx, input, ilen ); - md4_finish( &ctx, output ); -} - -#endif /* PPP_SUPPORT && LWIP_INCLUDED_POLARSSL_MD4 */ diff --git a/third_party/lwip/repo/lwip/src/netif/ppp/polarssl/md5.c b/third_party/lwip/repo/lwip/src/netif/ppp/polarssl/md5.c deleted file mode 100644 index 1ec4d81a694bf9..00000000000000 --- a/third_party/lwip/repo/lwip/src/netif/ppp/polarssl/md5.c +++ /dev/null @@ -1,300 +0,0 @@ -/* - * RFC 1321 compliant MD5 implementation - * - * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine - * - * Copyright (C) 2009 Paul Bakker - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the names of PolarSSL or XySSL nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/* - * The MD5 algorithm was designed by Ron Rivest in 1991. - * - * http://www.ietf.org/rfc/rfc1321.txt - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT && LWIP_INCLUDED_POLARSSL_MD5 - -#include "netif/ppp/polarssl/md5.h" - -#include - -/* - * 32-bit integer manipulation macros (little endian) - */ -#ifndef GET_ULONG_LE -#define GET_ULONG_LE(n,b,i) \ -{ \ - (n) = ( (unsigned long) (b)[(i) ] ) \ - | ( (unsigned long) (b)[(i) + 1] << 8 ) \ - | ( (unsigned long) (b)[(i) + 2] << 16 ) \ - | ( (unsigned long) (b)[(i) + 3] << 24 ); \ -} -#endif - -#ifndef PUT_ULONG_LE -#define PUT_ULONG_LE(n,b,i) \ -{ \ - (b)[(i) ] = (unsigned char) ( (n) ); \ - (b)[(i) + 1] = (unsigned char) ( (n) >> 8 ); \ - (b)[(i) + 2] = (unsigned char) ( (n) >> 16 ); \ - (b)[(i) + 3] = (unsigned char) ( (n) >> 24 ); \ -} -#endif - -/* - * MD5 context setup - */ -void md5_starts( md5_context *ctx ) -{ - ctx->total[0] = 0; - ctx->total[1] = 0; - - ctx->state[0] = 0x67452301; - ctx->state[1] = 0xEFCDAB89; - ctx->state[2] = 0x98BADCFE; - ctx->state[3] = 0x10325476; -} - -static void md5_process( md5_context *ctx, const unsigned char data[64] ) -{ - unsigned long X[16], A, B, C, D; - - GET_ULONG_LE( X[ 0], data, 0 ); - GET_ULONG_LE( X[ 1], data, 4 ); - GET_ULONG_LE( X[ 2], data, 8 ); - GET_ULONG_LE( X[ 3], data, 12 ); - GET_ULONG_LE( X[ 4], data, 16 ); - GET_ULONG_LE( X[ 5], data, 20 ); - GET_ULONG_LE( X[ 6], data, 24 ); - GET_ULONG_LE( X[ 7], data, 28 ); - GET_ULONG_LE( X[ 8], data, 32 ); - GET_ULONG_LE( X[ 9], data, 36 ); - GET_ULONG_LE( X[10], data, 40 ); - GET_ULONG_LE( X[11], data, 44 ); - GET_ULONG_LE( X[12], data, 48 ); - GET_ULONG_LE( X[13], data, 52 ); - GET_ULONG_LE( X[14], data, 56 ); - GET_ULONG_LE( X[15], data, 60 ); - -#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) - -#define P(a,b,c,d,k,s,t) \ -{ \ - a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \ -} - - A = ctx->state[0]; - B = ctx->state[1]; - C = ctx->state[2]; - D = ctx->state[3]; - -#define F(x,y,z) (z ^ (x & (y ^ z))) - - P( A, B, C, D, 0, 7, 0xD76AA478 ); - P( D, A, B, C, 1, 12, 0xE8C7B756 ); - P( C, D, A, B, 2, 17, 0x242070DB ); - P( B, C, D, A, 3, 22, 0xC1BDCEEE ); - P( A, B, C, D, 4, 7, 0xF57C0FAF ); - P( D, A, B, C, 5, 12, 0x4787C62A ); - P( C, D, A, B, 6, 17, 0xA8304613 ); - P( B, C, D, A, 7, 22, 0xFD469501 ); - P( A, B, C, D, 8, 7, 0x698098D8 ); - P( D, A, B, C, 9, 12, 0x8B44F7AF ); - P( C, D, A, B, 10, 17, 0xFFFF5BB1 ); - P( B, C, D, A, 11, 22, 0x895CD7BE ); - P( A, B, C, D, 12, 7, 0x6B901122 ); - P( D, A, B, C, 13, 12, 0xFD987193 ); - P( C, D, A, B, 14, 17, 0xA679438E ); - P( B, C, D, A, 15, 22, 0x49B40821 ); - -#undef F - -#define F(x,y,z) (y ^ (z & (x ^ y))) - - P( A, B, C, D, 1, 5, 0xF61E2562 ); - P( D, A, B, C, 6, 9, 0xC040B340 ); - P( C, D, A, B, 11, 14, 0x265E5A51 ); - P( B, C, D, A, 0, 20, 0xE9B6C7AA ); - P( A, B, C, D, 5, 5, 0xD62F105D ); - P( D, A, B, C, 10, 9, 0x02441453 ); - P( C, D, A, B, 15, 14, 0xD8A1E681 ); - P( B, C, D, A, 4, 20, 0xE7D3FBC8 ); - P( A, B, C, D, 9, 5, 0x21E1CDE6 ); - P( D, A, B, C, 14, 9, 0xC33707D6 ); - P( C, D, A, B, 3, 14, 0xF4D50D87 ); - P( B, C, D, A, 8, 20, 0x455A14ED ); - P( A, B, C, D, 13, 5, 0xA9E3E905 ); - P( D, A, B, C, 2, 9, 0xFCEFA3F8 ); - P( C, D, A, B, 7, 14, 0x676F02D9 ); - P( B, C, D, A, 12, 20, 0x8D2A4C8A ); - -#undef F - -#define F(x,y,z) (x ^ y ^ z) - - P( A, B, C, D, 5, 4, 0xFFFA3942 ); - P( D, A, B, C, 8, 11, 0x8771F681 ); - P( C, D, A, B, 11, 16, 0x6D9D6122 ); - P( B, C, D, A, 14, 23, 0xFDE5380C ); - P( A, B, C, D, 1, 4, 0xA4BEEA44 ); - P( D, A, B, C, 4, 11, 0x4BDECFA9 ); - P( C, D, A, B, 7, 16, 0xF6BB4B60 ); - P( B, C, D, A, 10, 23, 0xBEBFBC70 ); - P( A, B, C, D, 13, 4, 0x289B7EC6 ); - P( D, A, B, C, 0, 11, 0xEAA127FA ); - P( C, D, A, B, 3, 16, 0xD4EF3085 ); - P( B, C, D, A, 6, 23, 0x04881D05 ); - P( A, B, C, D, 9, 4, 0xD9D4D039 ); - P( D, A, B, C, 12, 11, 0xE6DB99E5 ); - P( C, D, A, B, 15, 16, 0x1FA27CF8 ); - P( B, C, D, A, 2, 23, 0xC4AC5665 ); - -#undef F - -#define F(x,y,z) (y ^ (x | ~z)) - - P( A, B, C, D, 0, 6, 0xF4292244 ); - P( D, A, B, C, 7, 10, 0x432AFF97 ); - P( C, D, A, B, 14, 15, 0xAB9423A7 ); - P( B, C, D, A, 5, 21, 0xFC93A039 ); - P( A, B, C, D, 12, 6, 0x655B59C3 ); - P( D, A, B, C, 3, 10, 0x8F0CCC92 ); - P( C, D, A, B, 10, 15, 0xFFEFF47D ); - P( B, C, D, A, 1, 21, 0x85845DD1 ); - P( A, B, C, D, 8, 6, 0x6FA87E4F ); - P( D, A, B, C, 15, 10, 0xFE2CE6E0 ); - P( C, D, A, B, 6, 15, 0xA3014314 ); - P( B, C, D, A, 13, 21, 0x4E0811A1 ); - P( A, B, C, D, 4, 6, 0xF7537E82 ); - P( D, A, B, C, 11, 10, 0xBD3AF235 ); - P( C, D, A, B, 2, 15, 0x2AD7D2BB ); - P( B, C, D, A, 9, 21, 0xEB86D391 ); - -#undef F - - ctx->state[0] += A; - ctx->state[1] += B; - ctx->state[2] += C; - ctx->state[3] += D; -} - -/* - * MD5 process buffer - */ -void md5_update( md5_context *ctx, const unsigned char *input, int ilen ) -{ - int fill; - unsigned long left; - - if( ilen <= 0 ) - return; - - left = ctx->total[0] & 0x3F; - fill = 64 - left; - - ctx->total[0] += ilen; - ctx->total[0] &= 0xFFFFFFFF; - - if( ctx->total[0] < (unsigned long) ilen ) - ctx->total[1]++; - - if( left && ilen >= fill ) - { - MEMCPY( (void *) (ctx->buffer + left), - input, fill ); - md5_process( ctx, ctx->buffer ); - input += fill; - ilen -= fill; - left = 0; - } - - while( ilen >= 64 ) - { - md5_process( ctx, input ); - input += 64; - ilen -= 64; - } - - if( ilen > 0 ) - { - MEMCPY( (void *) (ctx->buffer + left), - input, ilen ); - } -} - -static const unsigned char md5_padding[64] = -{ - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -/* - * MD5 final digest - */ -void md5_finish( md5_context *ctx, unsigned char output[16] ) -{ - unsigned long last, padn; - unsigned long high, low; - unsigned char msglen[8]; - - high = ( ctx->total[0] >> 29 ) - | ( ctx->total[1] << 3 ); - low = ( ctx->total[0] << 3 ); - - PUT_ULONG_LE( low, msglen, 0 ); - PUT_ULONG_LE( high, msglen, 4 ); - - last = ctx->total[0] & 0x3F; - padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); - - md5_update( ctx, md5_padding, padn ); - md5_update( ctx, msglen, 8 ); - - PUT_ULONG_LE( ctx->state[0], output, 0 ); - PUT_ULONG_LE( ctx->state[1], output, 4 ); - PUT_ULONG_LE( ctx->state[2], output, 8 ); - PUT_ULONG_LE( ctx->state[3], output, 12 ); -} - -/* - * output = MD5( input buffer ) - */ -void md5( unsigned char *input, int ilen, unsigned char output[16] ) -{ - md5_context ctx; - - md5_starts( &ctx ); - md5_update( &ctx, input, ilen ); - md5_finish( &ctx, output ); -} - -#endif /* PPP_SUPPORT && LWIP_INCLUDED_POLARSSL_MD5 */ diff --git a/third_party/lwip/repo/lwip/src/netif/ppp/polarssl/sha1.c b/third_party/lwip/repo/lwip/src/netif/ppp/polarssl/sha1.c deleted file mode 100644 index c2192eac542c60..00000000000000 --- a/third_party/lwip/repo/lwip/src/netif/ppp/polarssl/sha1.c +++ /dev/null @@ -1,335 +0,0 @@ -/* - * FIPS-180-1 compliant SHA-1 implementation - * - * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine - * - * Copyright (C) 2009 Paul Bakker - * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the names of PolarSSL or XySSL nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS - * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT - * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED - * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -/* - * The SHA-1 standard was published by NIST in 1993. - * - * http://www.itl.nist.gov/fipspubs/fip180-1.htm - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT && LWIP_INCLUDED_POLARSSL_SHA1 - -#include "netif/ppp/polarssl/sha1.h" - -#include - -/* - * 32-bit integer manipulation macros (big endian) - */ -#ifndef GET_ULONG_BE -#define GET_ULONG_BE(n,b,i) \ -{ \ - (n) = ( (unsigned long) (b)[(i) ] << 24 ) \ - | ( (unsigned long) (b)[(i) + 1] << 16 ) \ - | ( (unsigned long) (b)[(i) + 2] << 8 ) \ - | ( (unsigned long) (b)[(i) + 3] ); \ -} -#endif - -#ifndef PUT_ULONG_BE -#define PUT_ULONG_BE(n,b,i) \ -{ \ - (b)[(i) ] = (unsigned char) ( (n) >> 24 ); \ - (b)[(i) + 1] = (unsigned char) ( (n) >> 16 ); \ - (b)[(i) + 2] = (unsigned char) ( (n) >> 8 ); \ - (b)[(i) + 3] = (unsigned char) ( (n) ); \ -} -#endif - -/* - * SHA-1 context setup - */ -void sha1_starts( sha1_context *ctx ) -{ - ctx->total[0] = 0; - ctx->total[1] = 0; - - ctx->state[0] = 0x67452301; - ctx->state[1] = 0xEFCDAB89; - ctx->state[2] = 0x98BADCFE; - ctx->state[3] = 0x10325476; - ctx->state[4] = 0xC3D2E1F0; -} - -static void sha1_process( sha1_context *ctx, const unsigned char data[64] ) -{ - unsigned long temp, W[16], A, B, C, D, E; - - GET_ULONG_BE( W[ 0], data, 0 ); - GET_ULONG_BE( W[ 1], data, 4 ); - GET_ULONG_BE( W[ 2], data, 8 ); - GET_ULONG_BE( W[ 3], data, 12 ); - GET_ULONG_BE( W[ 4], data, 16 ); - GET_ULONG_BE( W[ 5], data, 20 ); - GET_ULONG_BE( W[ 6], data, 24 ); - GET_ULONG_BE( W[ 7], data, 28 ); - GET_ULONG_BE( W[ 8], data, 32 ); - GET_ULONG_BE( W[ 9], data, 36 ); - GET_ULONG_BE( W[10], data, 40 ); - GET_ULONG_BE( W[11], data, 44 ); - GET_ULONG_BE( W[12], data, 48 ); - GET_ULONG_BE( W[13], data, 52 ); - GET_ULONG_BE( W[14], data, 56 ); - GET_ULONG_BE( W[15], data, 60 ); - -#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) - -#define R(t) \ -( \ - temp = W[(t - 3) & 0x0F] ^ W[(t - 8) & 0x0F] ^ \ - W[(t - 14) & 0x0F] ^ W[ t & 0x0F], \ - ( W[t & 0x0F] = S(temp,1) ) \ -) - -#define P(a,b,c,d,e,x) \ -{ \ - e += S(a,5) + F(b,c,d) + K + x; b = S(b,30); \ -} - - A = ctx->state[0]; - B = ctx->state[1]; - C = ctx->state[2]; - D = ctx->state[3]; - E = ctx->state[4]; - -#define F(x,y,z) (z ^ (x & (y ^ z))) -#define K 0x5A827999 - - P( A, B, C, D, E, W[0] ); - P( E, A, B, C, D, W[1] ); - P( D, E, A, B, C, W[2] ); - P( C, D, E, A, B, W[3] ); - P( B, C, D, E, A, W[4] ); - P( A, B, C, D, E, W[5] ); - P( E, A, B, C, D, W[6] ); - P( D, E, A, B, C, W[7] ); - P( C, D, E, A, B, W[8] ); - P( B, C, D, E, A, W[9] ); - P( A, B, C, D, E, W[10] ); - P( E, A, B, C, D, W[11] ); - P( D, E, A, B, C, W[12] ); - P( C, D, E, A, B, W[13] ); - P( B, C, D, E, A, W[14] ); - P( A, B, C, D, E, W[15] ); - P( E, A, B, C, D, R(16) ); - P( D, E, A, B, C, R(17) ); - P( C, D, E, A, B, R(18) ); - P( B, C, D, E, A, R(19) ); - -#undef K -#undef F - -#define F(x,y,z) (x ^ y ^ z) -#define K 0x6ED9EBA1 - - P( A, B, C, D, E, R(20) ); - P( E, A, B, C, D, R(21) ); - P( D, E, A, B, C, R(22) ); - P( C, D, E, A, B, R(23) ); - P( B, C, D, E, A, R(24) ); - P( A, B, C, D, E, R(25) ); - P( E, A, B, C, D, R(26) ); - P( D, E, A, B, C, R(27) ); - P( C, D, E, A, B, R(28) ); - P( B, C, D, E, A, R(29) ); - P( A, B, C, D, E, R(30) ); - P( E, A, B, C, D, R(31) ); - P( D, E, A, B, C, R(32) ); - P( C, D, E, A, B, R(33) ); - P( B, C, D, E, A, R(34) ); - P( A, B, C, D, E, R(35) ); - P( E, A, B, C, D, R(36) ); - P( D, E, A, B, C, R(37) ); - P( C, D, E, A, B, R(38) ); - P( B, C, D, E, A, R(39) ); - -#undef K -#undef F - -#define F(x,y,z) ((x & y) | (z & (x | y))) -#define K 0x8F1BBCDC - - P( A, B, C, D, E, R(40) ); - P( E, A, B, C, D, R(41) ); - P( D, E, A, B, C, R(42) ); - P( C, D, E, A, B, R(43) ); - P( B, C, D, E, A, R(44) ); - P( A, B, C, D, E, R(45) ); - P( E, A, B, C, D, R(46) ); - P( D, E, A, B, C, R(47) ); - P( C, D, E, A, B, R(48) ); - P( B, C, D, E, A, R(49) ); - P( A, B, C, D, E, R(50) ); - P( E, A, B, C, D, R(51) ); - P( D, E, A, B, C, R(52) ); - P( C, D, E, A, B, R(53) ); - P( B, C, D, E, A, R(54) ); - P( A, B, C, D, E, R(55) ); - P( E, A, B, C, D, R(56) ); - P( D, E, A, B, C, R(57) ); - P( C, D, E, A, B, R(58) ); - P( B, C, D, E, A, R(59) ); - -#undef K -#undef F - -#define F(x,y,z) (x ^ y ^ z) -#define K 0xCA62C1D6 - - P( A, B, C, D, E, R(60) ); - P( E, A, B, C, D, R(61) ); - P( D, E, A, B, C, R(62) ); - P( C, D, E, A, B, R(63) ); - P( B, C, D, E, A, R(64) ); - P( A, B, C, D, E, R(65) ); - P( E, A, B, C, D, R(66) ); - P( D, E, A, B, C, R(67) ); - P( C, D, E, A, B, R(68) ); - P( B, C, D, E, A, R(69) ); - P( A, B, C, D, E, R(70) ); - P( E, A, B, C, D, R(71) ); - P( D, E, A, B, C, R(72) ); - P( C, D, E, A, B, R(73) ); - P( B, C, D, E, A, R(74) ); - P( A, B, C, D, E, R(75) ); - P( E, A, B, C, D, R(76) ); - P( D, E, A, B, C, R(77) ); - P( C, D, E, A, B, R(78) ); - P( B, C, D, E, A, R(79) ); - -#undef K -#undef F - - ctx->state[0] += A; - ctx->state[1] += B; - ctx->state[2] += C; - ctx->state[3] += D; - ctx->state[4] += E; -} - -/* - * SHA-1 process buffer - */ -void sha1_update( sha1_context *ctx, const unsigned char *input, int ilen ) -{ - int fill; - unsigned long left; - - if( ilen <= 0 ) - return; - - left = ctx->total[0] & 0x3F; - fill = 64 - left; - - ctx->total[0] += ilen; - ctx->total[0] &= 0xFFFFFFFF; - - if( ctx->total[0] < (unsigned long) ilen ) - ctx->total[1]++; - - if( left && ilen >= fill ) - { - MEMCPY( (void *) (ctx->buffer + left), - input, fill ); - sha1_process( ctx, ctx->buffer ); - input += fill; - ilen -= fill; - left = 0; - } - - while( ilen >= 64 ) - { - sha1_process( ctx, input ); - input += 64; - ilen -= 64; - } - - if( ilen > 0 ) - { - MEMCPY( (void *) (ctx->buffer + left), - input, ilen ); - } -} - -static const unsigned char sha1_padding[64] = -{ - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -/* - * SHA-1 final digest - */ -void sha1_finish( sha1_context *ctx, unsigned char output[20] ) -{ - unsigned long last, padn; - unsigned long high, low; - unsigned char msglen[8]; - - high = ( ctx->total[0] >> 29 ) - | ( ctx->total[1] << 3 ); - low = ( ctx->total[0] << 3 ); - - PUT_ULONG_BE( high, msglen, 0 ); - PUT_ULONG_BE( low, msglen, 4 ); - - last = ctx->total[0] & 0x3F; - padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); - - sha1_update( ctx, sha1_padding, padn ); - sha1_update( ctx, msglen, 8 ); - - PUT_ULONG_BE( ctx->state[0], output, 0 ); - PUT_ULONG_BE( ctx->state[1], output, 4 ); - PUT_ULONG_BE( ctx->state[2], output, 8 ); - PUT_ULONG_BE( ctx->state[3], output, 12 ); - PUT_ULONG_BE( ctx->state[4], output, 16 ); -} - -/* - * output = SHA-1( input buffer ) - */ -void sha1( unsigned char *input, int ilen, unsigned char output[20] ) -{ - sha1_context ctx; - - sha1_starts( &ctx ); - sha1_update( &ctx, input, ilen ); - sha1_finish( &ctx, output ); -} - -#endif /* PPP_SUPPORT && LWIP_INCLUDED_POLARSSL_SHA1 */ diff --git a/third_party/lwip/repo/lwip/src/netif/ppp/ppp.c b/third_party/lwip/repo/lwip/src/netif/ppp/ppp.c deleted file mode 100644 index 8b77765e5aada9..00000000000000 --- a/third_party/lwip/repo/lwip/src/netif/ppp/ppp.c +++ /dev/null @@ -1,1647 +0,0 @@ -/***************************************************************************** -* ppp.c - Network Point to Point Protocol program file. -* -* Copyright (c) 2003 by Marc Boucher, Services Informatiques (MBSI) inc. -* portions Copyright (c) 1997 by Global Election Systems Inc. -* -* The authors hereby grant permission to use, copy, modify, distribute, -* and license this software and its documentation for any purpose, provided -* that existing copyright notices are retained in all copies and that this -* notice and the following disclaimer are included verbatim in any -* distributions. No written agreement, license, or royalty fee is required -* for any of the authorized uses. -* -* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR -* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -****************************************************************************** -* REVISION HISTORY -* -* 03-01-01 Marc Boucher -* Ported to lwIP. -* 97-11-05 Guy Lancaster , Global Election Systems Inc. -* Original. -*****************************************************************************/ - -/* - * ppp_defs.h - PPP definitions. - * - * if_pppvar.h - private structures and declarations for PPP. - * - * Copyright (c) 1994 The Australian National University. - * All rights reserved. - * - * Permission to use, copy, modify, and distribute this software and its - * documentation is hereby granted, provided that the above copyright - * notice appears in all copies. This software is provided without any - * warranty, express or implied. The Australian National University - * makes no representations about the suitability of this software for - * any purpose. - * - * IN NO EVENT SHALL THE AUSTRALIAN NATIONAL UNIVERSITY BE LIABLE TO ANY - * PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES - * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF - * THE AUSTRALIAN NATIONAL UNIVERSITY HAVE BEEN ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * THE AUSTRALIAN NATIONAL UNIVERSITY SPECIFICALLY DISCLAIMS ANY WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS - * ON AN "AS IS" BASIS, AND THE AUSTRALIAN NATIONAL UNIVERSITY HAS NO - * OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, - * OR MODIFICATIONS. - */ - -/* - * if_ppp.h - Point-to-Point Protocol definitions. - * - * Copyright (c) 1989 Carnegie Mellon University. - * All rights reserved. - * - * Redistribution and use in source and binary forms are permitted - * provided that the above copyright notice and this paragraph are - * duplicated in all such forms and that any documentation, - * advertising materials, and other materials related to such - * distribution and use acknowledge that the software was developed - * by Carnegie Mellon University. The name of the - * University may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. - */ - -/** - * @defgroup ppp PPP netif - * @ingroup addons - * @verbinclude "ppp.txt" - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/pbuf.h" -#include "lwip/stats.h" -#include "lwip/sys.h" -#include "lwip/tcpip.h" -#include "lwip/api.h" -#include "lwip/snmp.h" -#include "lwip/ip4.h" /* for ip4_input() */ -#if PPP_IPV6_SUPPORT -#include "lwip/ip6.h" /* for ip6_input() */ -#endif /* PPP_IPV6_SUPPORT */ -#include "lwip/dns.h" - -#include "netif/ppp/ppp_impl.h" -#include "netif/ppp/pppos.h" - -#include "netif/ppp/fsm.h" -#include "netif/ppp/lcp.h" -#include "netif/ppp/magic.h" - -#if PAP_SUPPORT -#include "netif/ppp/upap.h" -#endif /* PAP_SUPPORT */ -#if CHAP_SUPPORT -#include "netif/ppp/chap-new.h" -#endif /* CHAP_SUPPORT */ -#if EAP_SUPPORT -#include "netif/ppp/eap.h" -#endif /* EAP_SUPPORT */ -#if CCP_SUPPORT -#include "netif/ppp/ccp.h" -#endif /* CCP_SUPPORT */ -#if MPPE_SUPPORT -#include "netif/ppp/mppe.h" -#endif /* MPPE_SUPPORT */ -#if ECP_SUPPORT -#include "netif/ppp/ecp.h" -#endif /* EAP_SUPPORT */ -#if VJ_SUPPORT -#include "netif/ppp/vj.h" -#endif /* VJ_SUPPORT */ -#if PPP_IPV4_SUPPORT -#include "netif/ppp/ipcp.h" -#endif /* PPP_IPV4_SUPPORT */ -#if PPP_IPV6_SUPPORT -#include "netif/ppp/ipv6cp.h" -#endif /* PPP_IPV6_SUPPORT */ - -/*************************/ -/*** LOCAL DEFINITIONS ***/ -/*************************/ - -/* Memory pools */ -#if PPPOS_SUPPORT -LWIP_MEMPOOL_PROTOTYPE(PPPOS_PCB); -#endif -#if PPPOE_SUPPORT -LWIP_MEMPOOL_PROTOTYPE(PPPOE_IF); -#endif -#if PPPOL2TP_SUPPORT -LWIP_MEMPOOL_PROTOTYPE(PPPOL2TP_PCB); -#endif -#if LWIP_PPP_API && LWIP_MPU_COMPATIBLE -LWIP_MEMPOOL_PROTOTYPE(PPPAPI_MSG); -#endif -LWIP_MEMPOOL_DECLARE(PPP_PCB, MEMP_NUM_PPP_PCB, sizeof(ppp_pcb), "PPP_PCB") - -/* FIXME: add stats per PPP session */ -#if PPP_STATS_SUPPORT -static struct timeval start_time; /* Time when link was started. */ -static struct pppd_stats old_link_stats; -struct pppd_stats link_stats; -unsigned link_connect_time; -int link_stats_valid; -#endif /* PPP_STATS_SUPPORT */ - -/* - * PPP Data Link Layer "protocol" table. - * One entry per supported protocol. - * The last entry must be NULL. - */ -const struct protent* const protocols[] = { - &lcp_protent, -#if PAP_SUPPORT - &pap_protent, -#endif /* PAP_SUPPORT */ -#if CHAP_SUPPORT - &chap_protent, -#endif /* CHAP_SUPPORT */ -#if CBCP_SUPPORT - &cbcp_protent, -#endif /* CBCP_SUPPORT */ -#if PPP_IPV4_SUPPORT - &ipcp_protent, -#endif /* PPP_IPV4_SUPPORT */ -#if PPP_IPV6_SUPPORT - &ipv6cp_protent, -#endif /* PPP_IPV6_SUPPORT */ -#if CCP_SUPPORT - &ccp_protent, -#endif /* CCP_SUPPORT */ -#if ECP_SUPPORT - &ecp_protent, -#endif /* ECP_SUPPORT */ -#ifdef AT_CHANGE - &atcp_protent, -#endif /* AT_CHANGE */ -#if EAP_SUPPORT - &eap_protent, -#endif /* EAP_SUPPORT */ - NULL -}; - -/* Prototypes for procedures local to this file. */ -static void ppp_do_connect(void *arg); -static err_t ppp_netif_init_cb(struct netif *netif); -#if LWIP_IPV4 -static err_t ppp_netif_output_ip4(struct netif *netif, struct pbuf *pb, const ip4_addr_t *ipaddr); -#endif /* LWIP_IPV4 */ -#if PPP_IPV6_SUPPORT -static err_t ppp_netif_output_ip6(struct netif *netif, struct pbuf *pb, const ip6_addr_t *ipaddr); -#endif /* PPP_IPV6_SUPPORT */ -static err_t ppp_netif_output(struct netif *netif, struct pbuf *pb, u16_t protocol); - -/***********************************/ -/*** PUBLIC FUNCTION DEFINITIONS ***/ -/***********************************/ -#if PPP_AUTH_SUPPORT -void ppp_set_auth(ppp_pcb *pcb, u8_t authtype, const char *user, const char *passwd) { -#if PAP_SUPPORT - pcb->settings.refuse_pap = !(authtype & PPPAUTHTYPE_PAP); -#endif /* PAP_SUPPORT */ -#if CHAP_SUPPORT - pcb->settings.refuse_chap = !(authtype & PPPAUTHTYPE_CHAP); -#if MSCHAP_SUPPORT - pcb->settings.refuse_mschap = !(authtype & PPPAUTHTYPE_MSCHAP); - pcb->settings.refuse_mschap_v2 = !(authtype & PPPAUTHTYPE_MSCHAP_V2); -#endif /* MSCHAP_SUPPORT */ -#endif /* CHAP_SUPPORT */ -#if EAP_SUPPORT - pcb->settings.refuse_eap = !(authtype & PPPAUTHTYPE_EAP); -#endif /* EAP_SUPPORT */ - pcb->settings.user = user; - pcb->settings.passwd = passwd; -} -#endif /* PPP_AUTH_SUPPORT */ - -#if MPPE_SUPPORT -/* Set MPPE configuration */ -void ppp_set_mppe(ppp_pcb *pcb, u8_t flags) { - if (flags == PPP_MPPE_DISABLE) { - pcb->settings.require_mppe = 0; - return; - } - - pcb->settings.require_mppe = 1; - pcb->settings.refuse_mppe_stateful = !(flags & PPP_MPPE_ALLOW_STATEFUL); - pcb->settings.refuse_mppe_40 = !!(flags & PPP_MPPE_REFUSE_40); - pcb->settings.refuse_mppe_128 = !!(flags & PPP_MPPE_REFUSE_128); -} -#endif /* MPPE_SUPPORT */ - -#if PPP_NOTIFY_PHASE -void ppp_set_notify_phase_callback(ppp_pcb *pcb, ppp_notify_phase_cb_fn notify_phase_cb) { - pcb->notify_phase_cb = notify_phase_cb; - notify_phase_cb(pcb, pcb->phase, pcb->ctx_cb); -} -#endif /* PPP_NOTIFY_PHASE */ - -/* - * Initiate a PPP connection. - * - * This can only be called if PPP is in the dead phase. - * - * Holdoff is the time to wait (in seconds) before initiating - * the connection. - * - * If this port connects to a modem, the modem connection must be - * established before calling this. - */ -err_t ppp_connect(ppp_pcb *pcb, u16_t holdoff) { - if (pcb->phase != PPP_PHASE_DEAD) { - return ERR_ALREADY; - } - - PPPDEBUG(LOG_DEBUG, ("ppp_connect[%d]: holdoff=%d\n", pcb->netif->num, holdoff)); - - if (holdoff == 0) { - ppp_do_connect(pcb); - return ERR_OK; - } - - new_phase(pcb, PPP_PHASE_HOLDOFF); - sys_timeout((u32_t)(holdoff*1000), ppp_do_connect, pcb); - return ERR_OK; -} - -#if PPP_SERVER -/* - * Listen for an incoming PPP connection. - * - * This can only be called if PPP is in the dead phase. - * - * If this port connects to a modem, the modem connection must be - * established before calling this. - */ -err_t ppp_listen(ppp_pcb *pcb) { - if (pcb->phase != PPP_PHASE_DEAD) { - return ERR_ALREADY; - } - - PPPDEBUG(LOG_DEBUG, ("ppp_listen[%d]\n", pcb->netif->num)); - - if (pcb->link_cb->listen) { - new_phase(pcb, PPP_PHASE_INITIALIZE); - pcb->link_cb->listen(pcb, pcb->link_ctx_cb); - return ERR_OK; - } - return ERR_IF; -} -#endif /* PPP_SERVER */ - -/* - * Initiate the end of a PPP connection. - * Any outstanding packets in the queues are dropped. - * - * Setting nocarrier to 1 close the PPP connection without initiating the - * shutdown procedure. Always using nocarrier = 0 is still recommended, - * this is going to take a little longer time if your link is down, but - * is a safer choice for the PPP state machine. - * - * Return 0 on success, an error code on failure. - */ -err_t -ppp_close(ppp_pcb *pcb, u8_t nocarrier) -{ - pcb->err_code = PPPERR_USER; - - /* holdoff phase, cancel the reconnection */ - if (pcb->phase == PPP_PHASE_HOLDOFF) { - sys_untimeout(ppp_do_connect, pcb); - new_phase(pcb, PPP_PHASE_DEAD); - } - - /* dead phase, nothing to do, call the status callback to be consistent */ - if (pcb->phase == PPP_PHASE_DEAD) { - pcb->link_status_cb(pcb, pcb->err_code, pcb->ctx_cb); - return ERR_OK; - } - - /* Already terminating, nothing to do */ - if (pcb->phase >= PPP_PHASE_TERMINATE) { - return ERR_INPROGRESS; - } - - /* LCP not open, close link protocol */ - if (pcb->phase < PPP_PHASE_ESTABLISH) { - new_phase(pcb, PPP_PHASE_DISCONNECT); - ppp_link_terminated(pcb); - return ERR_OK; - } - - /* - * Only accept carrier lost signal on the stable running phase in order - * to prevent changing the PPP phase FSM in transition phases. - * - * Always using nocarrier = 0 is still recommended, this is going to - * take a little longer time, but is a safer choice from FSM point of view. - */ - if (nocarrier && pcb->phase == PPP_PHASE_RUNNING) { - PPPDEBUG(LOG_DEBUG, ("ppp_close[%d]: carrier lost -> lcp_lowerdown\n", pcb->netif->num)); - lcp_lowerdown(pcb); - /* forced link termination, this will force link protocol to disconnect. */ - link_terminated(pcb); - return ERR_OK; - } - - /* Disconnect */ - PPPDEBUG(LOG_DEBUG, ("ppp_close[%d]: kill_link -> lcp_close\n", pcb->netif->num)); - /* LCP soft close request. */ - lcp_close(pcb, "User request"); - return ERR_OK; -} - -/* - * Release the control block. - * - * This can only be called if PPP is in the dead phase. - * - * You must use ppp_close() before if you wish to terminate - * an established PPP session. - * - * Return 0 on success, an error code on failure. - */ -err_t ppp_free(ppp_pcb *pcb) { - err_t err; - if (pcb->phase != PPP_PHASE_DEAD) { - return ERR_CONN; - } - - PPPDEBUG(LOG_DEBUG, ("ppp_free[%d]\n", pcb->netif->num)); - - netif_remove(pcb->netif); - - err = pcb->link_cb->free(pcb, pcb->link_ctx_cb); - - LWIP_MEMPOOL_FREE(PPP_PCB, pcb); - return err; -} - -/* Get and set parameters for the given connection. - * Return 0 on success, an error code on failure. */ -err_t -ppp_ioctl(ppp_pcb *pcb, u8_t cmd, void *arg) -{ - if (pcb == NULL) { - return ERR_VAL; - } - - switch(cmd) { - case PPPCTLG_UPSTATUS: /* Get the PPP up status. */ - if (!arg) { - goto fail; - } - *(int *)arg = (int)(0 -#if PPP_IPV4_SUPPORT - || pcb->if4_up -#endif /* PPP_IPV4_SUPPORT */ -#if PPP_IPV6_SUPPORT - || pcb->if6_up -#endif /* PPP_IPV6_SUPPORT */ - ); - return ERR_OK; - - case PPPCTLG_ERRCODE: /* Get the PPP error code. */ - if (!arg) { - goto fail; - } - *(int *)arg = (int)(pcb->err_code); - return ERR_OK; - - default: - goto fail; - } - -fail: - return ERR_VAL; -} - - -/**********************************/ -/*** LOCAL FUNCTION DEFINITIONS ***/ -/**********************************/ - -static void ppp_do_connect(void *arg) { - ppp_pcb *pcb = (ppp_pcb*)arg; - - LWIP_ASSERT("pcb->phase == PPP_PHASE_DEAD || pcb->phase == PPP_PHASE_HOLDOFF", pcb->phase == PPP_PHASE_DEAD || pcb->phase == PPP_PHASE_HOLDOFF); - - new_phase(pcb, PPP_PHASE_INITIALIZE); - pcb->link_cb->connect(pcb, pcb->link_ctx_cb); -} - -/* - * ppp_netif_init_cb - netif init callback - */ -static err_t ppp_netif_init_cb(struct netif *netif) { - netif->name[0] = 'p'; - netif->name[1] = 'p'; -#if LWIP_IPV4 - /* FIXME: change that when netif_null_output_ip4() will materialize */ - netif->output = ppp_netif_output_ip4; -#endif /* LWIP_IPV4 */ -#if PPP_IPV6_SUPPORT - netif->output_ip6 = ppp_netif_output_ip6; -#endif /* PPP_IPV6_SUPPORT */ - netif->flags = NETIF_FLAG_UP; -#if LWIP_NETIF_HOSTNAME - /* @todo: Initialize interface hostname */ - /* netif_set_hostname(netif, "lwip"); */ -#endif /* LWIP_NETIF_HOSTNAME */ - return ERR_OK; -} - -#if LWIP_IPV4 -/* - * Send an IPv4 packet on the given connection. - */ -static err_t ppp_netif_output_ip4(struct netif *netif, struct pbuf *pb, const ip4_addr_t *ipaddr) { - LWIP_UNUSED_ARG(ipaddr); -#if PPP_IPV4_SUPPORT - return ppp_netif_output(netif, pb, PPP_IP); -#else /* PPP_IPV4_SUPPORT */ - LWIP_UNUSED_ARG(netif); - LWIP_UNUSED_ARG(pb); - return ERR_IF; -#endif /* PPP_IPV4_SUPPORT */ -} -#endif /* LWIP_IPV4 */ - -#if PPP_IPV6_SUPPORT -/* - * Send an IPv6 packet on the given connection. - */ -static err_t ppp_netif_output_ip6(struct netif *netif, struct pbuf *pb, const ip6_addr_t *ipaddr) { - LWIP_UNUSED_ARG(ipaddr); - return ppp_netif_output(netif, pb, PPP_IPV6); -} -#endif /* PPP_IPV6_SUPPORT */ - -static err_t ppp_netif_output(struct netif *netif, struct pbuf *pb, u16_t protocol) { - ppp_pcb *pcb = (ppp_pcb*)netif->state; - err_t err; - struct pbuf *fpb = NULL; - - /* Check that the link is up. */ - if (0 -#if PPP_IPV4_SUPPORT - || (protocol == PPP_IP && !pcb->if4_up) -#endif /* PPP_IPV4_SUPPORT */ -#if PPP_IPV6_SUPPORT - || (protocol == PPP_IPV6 && !pcb->if6_up) -#endif /* PPP_IPV6_SUPPORT */ - ) { - PPPDEBUG(LOG_ERR, ("ppp_netif_output[%d]: link not up\n", pcb->netif->num)); - goto err_rte_drop; - } - -#if MPPE_SUPPORT - /* If MPPE is required, refuse any IP packet until we are able to crypt them. */ - if (pcb->settings.require_mppe && pcb->ccp_transmit_method != CI_MPPE) { - PPPDEBUG(LOG_ERR, ("ppp_netif_output[%d]: MPPE required, not up\n", pcb->netif->num)); - goto err_rte_drop; - } -#endif /* MPPE_SUPPORT */ - -#if VJ_SUPPORT - /* - * Attempt Van Jacobson header compression if VJ is configured and - * this is an IP packet. - */ - if (protocol == PPP_IP && pcb->vj_enabled) { - switch (vj_compress_tcp(&pcb->vj_comp, &pb)) { - case TYPE_IP: - /* No change... - protocol = PPP_IP; */ - break; - case TYPE_COMPRESSED_TCP: - /* vj_compress_tcp() returns a new allocated pbuf, indicate we should free - * our duplicated pbuf later */ - fpb = pb; - protocol = PPP_VJC_COMP; - break; - case TYPE_UNCOMPRESSED_TCP: - /* vj_compress_tcp() returns a new allocated pbuf, indicate we should free - * our duplicated pbuf later */ - fpb = pb; - protocol = PPP_VJC_UNCOMP; - break; - default: - PPPDEBUG(LOG_WARNING, ("ppp_netif_output[%d]: bad IP packet\n", pcb->netif->num)); - LINK_STATS_INC(link.proterr); - LINK_STATS_INC(link.drop); - MIB2_STATS_NETIF_INC(pcb->netif, ifoutdiscards); - return ERR_VAL; - } - } -#endif /* VJ_SUPPORT */ - -#if CCP_SUPPORT - switch (pcb->ccp_transmit_method) { - case 0: - break; /* Don't compress */ -#if MPPE_SUPPORT - case CI_MPPE: - if ((err = mppe_compress(pcb, &pcb->mppe_comp, &pb, protocol)) != ERR_OK) { - LINK_STATS_INC(link.memerr); - LINK_STATS_INC(link.drop); - MIB2_STATS_NETIF_INC(netif, ifoutdiscards); - goto err; - } - /* if VJ compressor returned a new allocated pbuf, free it */ - if (fpb) { - pbuf_free(fpb); - } - /* mppe_compress() returns a new allocated pbuf, indicate we should free - * our duplicated pbuf later */ - fpb = pb; - protocol = PPP_COMP; - break; -#endif /* MPPE_SUPPORT */ - default: - PPPDEBUG(LOG_ERR, ("ppp_netif_output[%d]: bad CCP transmit method\n", pcb->netif->num)); - goto err_rte_drop; /* Cannot really happen, we only negotiate what we are able to do */ - } -#endif /* CCP_SUPPORT */ - - err = pcb->link_cb->netif_output(pcb, pcb->link_ctx_cb, pb, protocol); - goto err; - -err_rte_drop: - err = ERR_RTE; - LINK_STATS_INC(link.rterr); - LINK_STATS_INC(link.drop); - MIB2_STATS_NETIF_INC(netif, ifoutdiscards); -err: - if (fpb) { - pbuf_free(fpb); - } - return err; -} - -/************************************/ -/*** PRIVATE FUNCTION DEFINITIONS ***/ -/************************************/ - -/* Initialize the PPP subsystem. */ -int ppp_init(void) -{ -#if PPPOS_SUPPORT - LWIP_MEMPOOL_INIT(PPPOS_PCB); -#endif -#if PPPOE_SUPPORT - LWIP_MEMPOOL_INIT(PPPOE_IF); -#endif -#if PPPOL2TP_SUPPORT - LWIP_MEMPOOL_INIT(PPPOL2TP_PCB); -#endif -#if LWIP_PPP_API && LWIP_MPU_COMPATIBLE - LWIP_MEMPOOL_INIT(PPPAPI_MSG); -#endif - - LWIP_MEMPOOL_INIT(PPP_PCB); - - /* - * Initialize magic number generator now so that protocols may - * use magic numbers in initialization. - */ - magic_init(); - - return 0; -} - -/* - * Create a new PPP control block. - * - * This initializes the PPP control block but does not - * attempt to negotiate the LCP session. - * - * Return a new PPP connection control block pointer - * on success or a null pointer on failure. - */ -ppp_pcb *ppp_new(struct netif *pppif, const struct link_callbacks *callbacks, void *link_ctx_cb, ppp_link_status_cb_fn link_status_cb, void *ctx_cb) { - ppp_pcb *pcb; - const struct protent *protp; - int i; - - /* PPP is single-threaded: without a callback, - * there is no way to know when the link is up. */ - if (link_status_cb == NULL) { - return NULL; - } - - pcb = (ppp_pcb*)LWIP_MEMPOOL_ALLOC(PPP_PCB); - if (pcb == NULL) { - return NULL; - } - - memset(pcb, 0, sizeof(ppp_pcb)); - - /* default configuration */ -#if PAP_SUPPORT - pcb->settings.pap_timeout_time = UPAP_DEFTIMEOUT; - pcb->settings.pap_max_transmits = UPAP_DEFTRANSMITS; -#if PPP_SERVER - pcb->settings.pap_req_timeout = UPAP_DEFREQTIME; -#endif /* PPP_SERVER */ -#endif /* PAP_SUPPORT */ - -#if CHAP_SUPPORT - pcb->settings.chap_timeout_time = CHAP_DEFTIMEOUT; - pcb->settings.chap_max_transmits = CHAP_DEFTRANSMITS; -#if PPP_SERVER - pcb->settings.chap_rechallenge_time = CHAP_DEFRECHALLENGETIME; -#endif /* PPP_SERVER */ -#endif /* CHAP_SUPPPORT */ - -#if EAP_SUPPORT - pcb->settings.eap_req_time = EAP_DEFREQTIME; - pcb->settings.eap_allow_req = EAP_DEFALLOWREQ; -#if PPP_SERVER - pcb->settings.eap_timeout_time = EAP_DEFTIMEOUT; - pcb->settings.eap_max_transmits = EAP_DEFTRANSMITS; -#endif /* PPP_SERVER */ -#endif /* EAP_SUPPORT */ - - pcb->settings.lcp_loopbackfail = LCP_DEFLOOPBACKFAIL; - pcb->settings.lcp_echo_interval = LCP_ECHOINTERVAL; - pcb->settings.lcp_echo_fails = LCP_MAXECHOFAILS; - - pcb->settings.fsm_timeout_time = FSM_DEFTIMEOUT; - pcb->settings.fsm_max_conf_req_transmits = FSM_DEFMAXCONFREQS; - pcb->settings.fsm_max_term_transmits = FSM_DEFMAXTERMREQS; - pcb->settings.fsm_max_nak_loops = FSM_DEFMAXNAKLOOPS; - - pcb->netif = pppif; - MIB2_INIT_NETIF(pppif, snmp_ifType_ppp, 0); - if (!netif_add(pcb->netif, -#if LWIP_IPV4 - IP4_ADDR_ANY4, IP4_ADDR_BROADCAST, IP4_ADDR_ANY4, -#endif /* LWIP_IPV4 */ - (void *)pcb, ppp_netif_init_cb, NULL)) { - LWIP_MEMPOOL_FREE(PPP_PCB, pcb); - PPPDEBUG(LOG_ERR, ("ppp_new: netif_add failed\n")); - return NULL; - } - - pcb->link_cb = callbacks; - pcb->link_ctx_cb = link_ctx_cb; - pcb->link_status_cb = link_status_cb; - pcb->ctx_cb = ctx_cb; - - /* - * Initialize each protocol. - */ - for (i = 0; (protp = protocols[i]) != NULL; ++i) { - (*protp->init)(pcb); - } - - new_phase(pcb, PPP_PHASE_DEAD); - return pcb; -} - -/** Initiate LCP open request */ -void ppp_start(ppp_pcb *pcb) { - PPPDEBUG(LOG_DEBUG, ("ppp_start[%d]\n", pcb->netif->num)); - - /* Clean data not taken care by anything else, mostly shared data. */ -#if PPP_STATS_SUPPORT - link_stats_valid = 0; -#endif /* PPP_STATS_SUPPORT */ -#if MPPE_SUPPORT - pcb->mppe_keys_set = 0; - memset(&pcb->mppe_comp, 0, sizeof(pcb->mppe_comp)); - memset(&pcb->mppe_decomp, 0, sizeof(pcb->mppe_decomp)); -#endif /* MPPE_SUPPORT */ -#if VJ_SUPPORT - vj_compress_init(&pcb->vj_comp); -#endif /* VJ_SUPPORT */ - - /* Start protocol */ - new_phase(pcb, PPP_PHASE_ESTABLISH); - lcp_open(pcb); - lcp_lowerup(pcb); - PPPDEBUG(LOG_DEBUG, ("ppp_start[%d]: finished\n", pcb->netif->num)); -} - -/** Called when link failed to setup */ -void ppp_link_failed(ppp_pcb *pcb) { - PPPDEBUG(LOG_DEBUG, ("ppp_link_failed[%d]\n", pcb->netif->num)); - new_phase(pcb, PPP_PHASE_DEAD); - pcb->err_code = PPPERR_OPEN; - pcb->link_status_cb(pcb, pcb->err_code, pcb->ctx_cb); -} - -/** Called when link is normally down (i.e. it was asked to end) */ -void ppp_link_end(ppp_pcb *pcb) { - PPPDEBUG(LOG_DEBUG, ("ppp_link_end[%d]\n", pcb->netif->num)); - new_phase(pcb, PPP_PHASE_DEAD); - if (pcb->err_code == PPPERR_NONE) { - pcb->err_code = PPPERR_CONNECT; - } - pcb->link_status_cb(pcb, pcb->err_code, pcb->ctx_cb); -} - -/* - * Pass the processed input packet to the appropriate handler. - * This function and all handlers run in the context of the tcpip_thread - */ -void ppp_input(ppp_pcb *pcb, struct pbuf *pb) { - u16_t protocol; -#if PPP_DEBUG && PPP_PROTOCOLNAME - const char *pname; -#endif /* PPP_DEBUG && PPP_PROTOCOLNAME */ - - magic_randomize(); - - if (pb->len < 2) { - PPPDEBUG(LOG_ERR, ("ppp_input[%d]: packet too short\n", pcb->netif->num)); - goto drop; - } - protocol = (((u8_t *)pb->payload)[0] << 8) | ((u8_t*)pb->payload)[1]; - -#if PRINTPKT_SUPPORT - ppp_dump_packet(pcb, "rcvd", (unsigned char *)pb->payload, pb->len); -#endif /* PRINTPKT_SUPPORT */ - - pbuf_header(pb, -(s16_t)sizeof(protocol)); - - LINK_STATS_INC(link.recv); - MIB2_STATS_NETIF_INC(pcb->netif, ifinucastpkts); - MIB2_STATS_NETIF_ADD(pcb->netif, ifinoctets, pb->tot_len); - - /* - * Toss all non-LCP packets unless LCP is OPEN. - */ - if (protocol != PPP_LCP && pcb->lcp_fsm.state != PPP_FSM_OPENED) { - ppp_dbglog("Discarded non-LCP packet when LCP not open"); - goto drop; - } - - /* - * Until we get past the authentication phase, toss all packets - * except LCP, LQR and authentication packets. - */ - if (pcb->phase <= PPP_PHASE_AUTHENTICATE - && !(protocol == PPP_LCP -#if LQR_SUPPORT - || protocol == PPP_LQR -#endif /* LQR_SUPPORT */ -#if PAP_SUPPORT - || protocol == PPP_PAP -#endif /* PAP_SUPPORT */ -#if CHAP_SUPPORT - || protocol == PPP_CHAP -#endif /* CHAP_SUPPORT */ -#if EAP_SUPPORT - || protocol == PPP_EAP -#endif /* EAP_SUPPORT */ - )) { - ppp_dbglog("discarding proto 0x%x in phase %d", protocol, pcb->phase); - goto drop; - } - -#if CCP_SUPPORT -#if MPPE_SUPPORT - /* - * MPPE is required and unencrypted data has arrived (this - * should never happen!). We should probably drop the link if - * the protocol is in the range of what should be encrypted. - * At the least, we drop this packet. - */ - if (pcb->settings.require_mppe && protocol != PPP_COMP && protocol < 0x8000) { - PPPDEBUG(LOG_ERR, ("ppp_input[%d]: MPPE required, received unencrypted data!\n", pcb->netif->num)); - goto drop; - } -#endif /* MPPE_SUPPORT */ - - if (protocol == PPP_COMP) { - u8_t *pl; - - switch (pcb->ccp_receive_method) { -#if MPPE_SUPPORT - case CI_MPPE: - if (mppe_decompress(pcb, &pcb->mppe_decomp, &pb) != ERR_OK) { - goto drop; - } - break; -#endif /* MPPE_SUPPORT */ - default: - PPPDEBUG(LOG_ERR, ("ppp_input[%d]: bad CCP receive method\n", pcb->netif->num)); - goto drop; /* Cannot really happen, we only negotiate what we are able to do */ - } - - /* Assume no PFC */ - if (pb->len < 2) { - goto drop; - } - - /* Extract and hide protocol (do PFC decompression if necessary) */ - pl = (u8_t*)pb->payload; - if (pl[0] & 0x01) { - protocol = pl[0]; - pbuf_header(pb, -(s16_t)1); - } else { - protocol = (pl[0] << 8) | pl[1]; - pbuf_header(pb, -(s16_t)2); - } - } -#endif /* CCP_SUPPORT */ - - switch(protocol) { - -#if PPP_IPV4_SUPPORT - case PPP_IP: /* Internet Protocol */ - PPPDEBUG(LOG_INFO, ("ppp_input[%d]: ip in pbuf len=%d\n", pcb->netif->num, pb->tot_len)); - ip4_input(pb, pcb->netif); - return; -#endif /* PPP_IPV4_SUPPORT */ - -#if PPP_IPV6_SUPPORT - case PPP_IPV6: /* Internet Protocol Version 6 */ - PPPDEBUG(LOG_INFO, ("ppp_input[%d]: ip6 in pbuf len=%d\n", pcb->netif->num, pb->tot_len)); - ip6_input(pb, pcb->netif); - return; -#endif /* PPP_IPV6_SUPPORT */ - -#if VJ_SUPPORT - case PPP_VJC_COMP: /* VJ compressed TCP */ - /* - * Clip off the VJ header and prepend the rebuilt TCP/IP header and - * pass the result to IP. - */ - PPPDEBUG(LOG_INFO, ("ppp_input[%d]: vj_comp in pbuf len=%d\n", pcb->netif->num, pb->tot_len)); - if (pcb->vj_enabled && vj_uncompress_tcp(&pb, &pcb->vj_comp) >= 0) { - ip4_input(pb, pcb->netif); - return; - } - /* Something's wrong so drop it. */ - PPPDEBUG(LOG_WARNING, ("ppp_input[%d]: Dropping VJ compressed\n", pcb->netif->num)); - break; - - case PPP_VJC_UNCOMP: /* VJ uncompressed TCP */ - /* - * Process the TCP/IP header for VJ header compression and then pass - * the packet to IP. - */ - PPPDEBUG(LOG_INFO, ("ppp_input[%d]: vj_un in pbuf len=%d\n", pcb->netif->num, pb->tot_len)); - if (pcb->vj_enabled && vj_uncompress_uncomp(pb, &pcb->vj_comp) >= 0) { - ip4_input(pb, pcb->netif); - return; - } - /* Something's wrong so drop it. */ - PPPDEBUG(LOG_WARNING, ("ppp_input[%d]: Dropping VJ uncompressed\n", pcb->netif->num)); - break; -#endif /* VJ_SUPPORT */ - - default: { - int i; - const struct protent *protp; - - /* - * Upcall the proper protocol input routine. - */ - for (i = 0; (protp = protocols[i]) != NULL; ++i) { - if (protp->protocol == protocol) { - pb = ppp_singlebuf(pb); - (*protp->input)(pcb, (u8_t*)pb->payload, pb->len); - goto out; - } -#if 0 /* UNUSED - * - * This is actually a (hacked?) way for the Linux kernel to pass a data - * packet to pppd. pppd in normal condition only do signaling - * (LCP, PAP, CHAP, IPCP, ...) and does not handle any data packet at all. - * - * We don't even need this interface, which is only there because of PPP - * interface limitation between Linux kernel and pppd. For MPPE, which uses - * CCP to negotiate although it is not really a (de)compressor, we added - * ccp_resetrequest() in CCP and MPPE input data flow is calling either - * ccp_resetrequest() or lcp_close() if the issue is, respectively, non-fatal - * or fatal, this is what ccp_datainput() really do. - */ - if (protocol == (protp->protocol & ~0x8000) - && protp->datainput != NULL) { - (*protp->datainput)(pcb, pb->payload, pb->len); - goto out; - } -#endif /* UNUSED */ - } - -#if PPP_DEBUG -#if PPP_PROTOCOLNAME - pname = protocol_name(protocol); - if (pname != NULL) { - ppp_warn("Unsupported protocol '%s' (0x%x) received", pname, protocol); - } else -#endif /* PPP_PROTOCOLNAME */ - ppp_warn("Unsupported protocol 0x%x received", protocol); -#endif /* PPP_DEBUG */ - pbuf_header(pb, (s16_t)sizeof(protocol)); - lcp_sprotrej(pcb, (u8_t*)pb->payload, pb->len); - } - break; - } - -drop: - LINK_STATS_INC(link.drop); - MIB2_STATS_NETIF_INC(pcb->netif, ifindiscards); - -out: - pbuf_free(pb); -} - -/* merge a pbuf chain into one pbuf */ -struct pbuf *ppp_singlebuf(struct pbuf *p) { - struct pbuf *q, *b; - u8_t *pl; - - if(p->tot_len == p->len) { - return p; - } - - q = pbuf_alloc(PBUF_RAW, p->tot_len, PBUF_RAM); - if(!q) { - PPPDEBUG(LOG_ERR, - ("ppp_singlebuf: unable to alloc new buf (%d)\n", p->tot_len)); - return p; /* live dangerously */ - } - - for(b = p, pl = (u8_t*)q->payload; b != NULL; b = b->next) { - MEMCPY(pl, b->payload, b->len); - pl += b->len; - } - - pbuf_free(p); - - return q; -} - -/* - * Write a pbuf to a ppp link, only used from PPP functions - * to send PPP packets. - * - * IPv4 and IPv6 packets from lwIP are sent, respectively, - * with ppp_netif_output_ip4() and ppp_netif_output_ip6() - * functions (which are callbacks of the netif PPP interface). - */ -err_t ppp_write(ppp_pcb *pcb, struct pbuf *p) { -#if PRINTPKT_SUPPORT - ppp_dump_packet(pcb, "sent", (unsigned char *)p->payload+2, p->len-2); -#endif /* PRINTPKT_SUPPORT */ - return pcb->link_cb->write(pcb, pcb->link_ctx_cb, p); -} - -void ppp_link_terminated(ppp_pcb *pcb) { - PPPDEBUG(LOG_DEBUG, ("ppp_link_terminated[%d]\n", pcb->netif->num)); - pcb->link_cb->disconnect(pcb, pcb->link_ctx_cb); - PPPDEBUG(LOG_DEBUG, ("ppp_link_terminated[%d]: finished.\n", pcb->netif->num)); -} - - -/************************************************************************ - * Functions called by various PPP subsystems to configure - * the PPP interface or change the PPP phase. - */ - -/* - * new_phase - signal the start of a new phase of pppd's operation. - */ -void new_phase(ppp_pcb *pcb, int p) { - pcb->phase = p; - PPPDEBUG(LOG_DEBUG, ("ppp phase changed[%d]: phase=%d\n", pcb->netif->num, pcb->phase)); -#if PPP_NOTIFY_PHASE - if (pcb->notify_phase_cb != NULL) { - pcb->notify_phase_cb(pcb, p, pcb->ctx_cb); - } -#endif /* PPP_NOTIFY_PHASE */ -} - -/* - * ppp_send_config - configure the transmit-side characteristics of - * the ppp interface. - */ -int ppp_send_config(ppp_pcb *pcb, int mtu, u32_t accm, int pcomp, int accomp) { - LWIP_UNUSED_ARG(mtu); - /* pcb->mtu = mtu; -- set correctly with netif_set_mtu */ - - if (pcb->link_cb->send_config) { - pcb->link_cb->send_config(pcb, pcb->link_ctx_cb, accm, pcomp, accomp); - } - - PPPDEBUG(LOG_INFO, ("ppp_send_config[%d]\n", pcb->netif->num) ); - return 0; -} - -/* - * ppp_recv_config - configure the receive-side characteristics of - * the ppp interface. - */ -int ppp_recv_config(ppp_pcb *pcb, int mru, u32_t accm, int pcomp, int accomp) { - LWIP_UNUSED_ARG(mru); - - if (pcb->link_cb->recv_config) { - pcb->link_cb->recv_config(pcb, pcb->link_ctx_cb, accm, pcomp, accomp); - } - - PPPDEBUG(LOG_INFO, ("ppp_recv_config[%d]\n", pcb->netif->num)); - return 0; -} - -#if PPP_IPV4_SUPPORT -/* - * sifaddr - Config the interface IP addresses and netmask. - */ -int sifaddr(ppp_pcb *pcb, u32_t our_adr, u32_t his_adr, u32_t netmask) { - ip4_addr_t ip, nm, gw; - - ip4_addr_set_u32(&ip, our_adr); - ip4_addr_set_u32(&nm, netmask); - ip4_addr_set_u32(&gw, his_adr); - netif_set_addr(pcb->netif, &ip, &nm, &gw); - return 1; -} - -/******************************************************************** - * - * cifaddr - Clear the interface IP addresses, and delete routes - * through the interface if possible. - */ -int cifaddr(ppp_pcb *pcb, u32_t our_adr, u32_t his_adr) { - LWIP_UNUSED_ARG(our_adr); - LWIP_UNUSED_ARG(his_adr); - - netif_set_addr(pcb->netif, IP4_ADDR_ANY4, IP4_ADDR_BROADCAST, IP4_ADDR_ANY4); - return 1; -} - -#if 0 /* UNUSED - PROXY ARP */ -/******************************************************************** - * - * sifproxyarp - Make a proxy ARP entry for the peer. - */ - -int sifproxyarp(ppp_pcb *pcb, u32_t his_adr) { - LWIP_UNUSED_ARG(pcb); - LWIP_UNUSED_ARG(his_adr); - return 0; -} - -/******************************************************************** - * - * cifproxyarp - Delete the proxy ARP entry for the peer. - */ - -int cifproxyarp(ppp_pcb *pcb, u32_t his_adr) { - LWIP_UNUSED_ARG(pcb); - LWIP_UNUSED_ARG(his_adr); - return 0; -} -#endif /* UNUSED - PROXY ARP */ - -#if LWIP_DNS -/* - * sdns - Config the DNS servers - */ -int sdns(ppp_pcb *pcb, u32_t ns1, u32_t ns2) { - ip_addr_t ns; - LWIP_UNUSED_ARG(pcb); - - ip_addr_set_ip4_u32(&ns, ns1); - dns_setserver(0, &ns); - ip_addr_set_ip4_u32(&ns, ns2); - dns_setserver(1, &ns); - return 1; -} - -/******************************************************************** - * - * cdns - Clear the DNS servers - */ -int cdns(ppp_pcb *pcb, u32_t ns1, u32_t ns2) { - const ip_addr_t *nsa; - ip_addr_t nsb; - LWIP_UNUSED_ARG(pcb); - - nsa = dns_getserver(0); - ip_addr_set_ip4_u32(&nsb, ns1); - if (ip_addr_cmp(nsa, &nsb)) { - dns_setserver(0, IP_ADDR_ANY); - } - nsa = dns_getserver(1); - ip_addr_set_ip4_u32(&nsb, ns2); - if (ip_addr_cmp(nsa, &nsb)) { - dns_setserver(1, IP_ADDR_ANY); - } - return 1; -} -#endif /* LWIP_DNS */ - -#if VJ_SUPPORT -/******************************************************************** - * - * sifvjcomp - config tcp header compression - */ -int sifvjcomp(ppp_pcb *pcb, int vjcomp, int cidcomp, int maxcid) { - pcb->vj_enabled = vjcomp; - pcb->vj_comp.compressSlot = cidcomp; - pcb->vj_comp.maxSlotIndex = maxcid; - PPPDEBUG(LOG_INFO, ("sifvjcomp[%d]: VJ compress enable=%d slot=%d max slot=%d\n", - pcb->netif->num, vjcomp, cidcomp, maxcid)); - return 0; -} -#endif /* VJ_SUPPORT */ - -/* - * sifup - Config the interface up and enable IP packets to pass. - */ -int sifup(ppp_pcb *pcb) { - pcb->if4_up = 1; - pcb->err_code = PPPERR_NONE; - netif_set_link_up(pcb->netif); - - PPPDEBUG(LOG_DEBUG, ("sifup[%d]: err_code=%d\n", pcb->netif->num, pcb->err_code)); - pcb->link_status_cb(pcb, pcb->err_code, pcb->ctx_cb); - return 1; -} - -/******************************************************************** - * - * sifdown - Disable the indicated protocol and config the interface - * down if there are no remaining protocols. - */ -int sifdown(ppp_pcb *pcb) { - - pcb->if4_up = 0; - - if (1 -#if PPP_IPV6_SUPPORT - /* set the interface down if IPv6 is down as well */ - && !pcb->if6_up -#endif /* PPP_IPV6_SUPPORT */ - ) { - /* make sure the netif link callback is called */ - netif_set_link_down(pcb->netif); - } - PPPDEBUG(LOG_DEBUG, ("sifdown[%d]: err_code=%d\n", pcb->netif->num, pcb->err_code)); - return 1; -} - -/******************************************************************** - * - * Return user specified netmask, modified by any mask we might determine - * for address `addr' (in network byte order). - * Here we scan through the system's list of interfaces, looking for - * any non-point-to-point interfaces which might appear to be on the same - * network as `addr'. If we find any, we OR in their netmask to the - * user-specified netmask. - */ -u32_t get_mask(u32_t addr) { -#if 0 - u32_t mask, nmask; - - addr = lwip_htonl(addr); - if (IP_CLASSA(addr)) { /* determine network mask for address class */ - nmask = IP_CLASSA_NET; - } else if (IP_CLASSB(addr)) { - nmask = IP_CLASSB_NET; - } else { - nmask = IP_CLASSC_NET; - } - - /* class D nets are disallowed by bad_ip_adrs */ - mask = PP_HTONL(0xffffff00UL) | lwip_htonl(nmask); - - /* XXX - * Scan through the system's network interfaces. - * Get each netmask and OR them into our mask. - */ - /* return mask; */ - return mask; -#endif /* 0 */ - LWIP_UNUSED_ARG(addr); - return IPADDR_BROADCAST; -} -#endif /* PPP_IPV4_SUPPORT */ - -#if PPP_IPV6_SUPPORT -#define IN6_LLADDR_FROM_EUI64(ip6, eui64) do { \ - ip6.addr[0] = PP_HTONL(0xfe800000); \ - ip6.addr[1] = 0; \ - eui64_copy(eui64, ip6.addr[2]); \ - } while (0) - -/******************************************************************** - * - * sif6addr - Config the interface with an IPv6 link-local address - */ -int sif6addr(ppp_pcb *pcb, eui64_t our_eui64, eui64_t his_eui64) { - ip6_addr_t ip6; - LWIP_UNUSED_ARG(his_eui64); - - IN6_LLADDR_FROM_EUI64(ip6, our_eui64); - netif_ip6_addr_set(pcb->netif, 0, &ip6); - netif_ip6_addr_set_state(pcb->netif, 0, IP6_ADDR_PREFERRED); - /* FIXME: should we add an IPv6 static neighbor using his_eui64 ? */ - return 1; -} - -/******************************************************************** - * - * cif6addr - Remove IPv6 address from interface - */ -int cif6addr(ppp_pcb *pcb, eui64_t our_eui64, eui64_t his_eui64) { - LWIP_UNUSED_ARG(our_eui64); - LWIP_UNUSED_ARG(his_eui64); - - netif_ip6_addr_set(pcb->netif, 0, IP6_ADDR_ANY6); - netif_ip6_addr_set_state(pcb->netif, 0, IP6_ADDR_INVALID); - return 1; -} - -/* - * sif6up - Config the interface up and enable IPv6 packets to pass. - */ -int sif6up(ppp_pcb *pcb) { - - pcb->if6_up = 1; - pcb->err_code = PPPERR_NONE; - netif_set_link_up(pcb->netif); - - PPPDEBUG(LOG_DEBUG, ("sif6up[%d]: err_code=%d\n", pcb->netif->num, pcb->err_code)); - pcb->link_status_cb(pcb, pcb->err_code, pcb->ctx_cb); - return 1; -} - -/******************************************************************** - * - * sif6down - Disable the indicated protocol and config the interface - * down if there are no remaining protocols. - */ -int sif6down(ppp_pcb *pcb) { - - pcb->if6_up = 0; - - if (1 -#if PPP_IPV4_SUPPORT - /* set the interface down if IPv4 is down as well */ - && !pcb->if4_up -#endif /* PPP_IPV4_SUPPORT */ - ) { - /* make sure the netif link callback is called */ - netif_set_link_down(pcb->netif); - } - PPPDEBUG(LOG_DEBUG, ("sif6down[%d]: err_code=%d\n", pcb->netif->num, pcb->err_code)); - return 1; -} -#endif /* PPP_IPV6_SUPPORT */ - -#if DEMAND_SUPPORT -/* - * sifnpmode - Set the mode for handling packets for a given NP. - */ -int sifnpmode(ppp_pcb *pcb, int proto, enum NPmode mode) { - LWIP_UNUSED_ARG(pcb); - LWIP_UNUSED_ARG(proto); - LWIP_UNUSED_ARG(mode); - return 0; -} -#endif /* DEMAND_SUPPORT */ - -/* - * netif_set_mtu - set the MTU on the PPP network interface. - */ -void netif_set_mtu(ppp_pcb *pcb, int mtu) { - - pcb->netif->mtu = mtu; - PPPDEBUG(LOG_INFO, ("netif_set_mtu[%d]: mtu=%d\n", pcb->netif->num, mtu)); -} - -/* - * netif_get_mtu - get PPP interface MTU - */ -int netif_get_mtu(ppp_pcb *pcb) { - - return pcb->netif->mtu; -} - -#if CCP_SUPPORT -#if 0 /* unused */ -/* - * ccp_test - whether a given compression method is acceptable for use. - */ -int -ccp_test(ppp_pcb *pcb, u_char *opt_ptr, int opt_len, int for_transmit) -{ - LWIP_UNUSED_ARG(pcb); - LWIP_UNUSED_ARG(opt_ptr); - LWIP_UNUSED_ARG(opt_len); - LWIP_UNUSED_ARG(for_transmit); - return -1; -} -#endif /* unused */ - -/* - * ccp_set - inform about the current state of CCP. - */ -void -ccp_set(ppp_pcb *pcb, u8_t isopen, u8_t isup, u8_t receive_method, u8_t transmit_method) -{ - LWIP_UNUSED_ARG(isopen); - LWIP_UNUSED_ARG(isup); - pcb->ccp_receive_method = receive_method; - pcb->ccp_transmit_method = transmit_method; - PPPDEBUG(LOG_DEBUG, ("ccp_set[%d]: is_open=%d, is_up=%d, receive_method=%u, transmit_method=%u\n", - pcb->netif->num, isopen, isup, receive_method, transmit_method)); -} - -void -ccp_reset_comp(ppp_pcb *pcb) -{ - switch (pcb->ccp_transmit_method) { -#if MPPE_SUPPORT - case CI_MPPE: - mppe_comp_reset(pcb, &pcb->mppe_comp); - break; -#endif /* MPPE_SUPPORT */ - default: - break; - } -} - -void -ccp_reset_decomp(ppp_pcb *pcb) -{ - switch (pcb->ccp_receive_method) { -#if MPPE_SUPPORT - case CI_MPPE: - mppe_decomp_reset(pcb, &pcb->mppe_decomp); - break; -#endif /* MPPE_SUPPORT */ - default: - break; - } -} - -#if 0 /* unused */ -/* - * ccp_fatal_error - returns 1 if decompression was disabled as a - * result of an error detected after decompression of a packet, - * 0 otherwise. This is necessary because of patent nonsense. - */ -int -ccp_fatal_error(ppp_pcb *pcb) -{ - LWIP_UNUSED_ARG(pcb); - return 1; -} -#endif /* unused */ -#endif /* CCP_SUPPORT */ - -#if PPP_IDLETIMELIMIT -/******************************************************************** - * - * get_idle_time - return how long the link has been idle. - */ -int get_idle_time(ppp_pcb *pcb, struct ppp_idle *ip) { - /* FIXME: add idle time support and make it optional */ - LWIP_UNUSED_ARG(pcb); - LWIP_UNUSED_ARG(ip); - return 1; -} -#endif /* PPP_IDLETIMELIMIT */ - -#if DEMAND_SUPPORT -/******************************************************************** - * - * get_loop_output - get outgoing packets from the ppp device, - * and detect when we want to bring the real link up. - * Return value is 1 if we need to bring up the link, 0 otherwise. - */ -int get_loop_output(void) { - return 0; -} -#endif /* DEMAND_SUPPORT */ - -#if PPP_PROTOCOLNAME -/* List of protocol names, to make our messages a little more informative. */ -struct protocol_list { - u_short proto; - const char *name; -} const protocol_list[] = { - { 0x21, "IP" }, - { 0x23, "OSI Network Layer" }, - { 0x25, "Xerox NS IDP" }, - { 0x27, "DECnet Phase IV" }, - { 0x29, "Appletalk" }, - { 0x2b, "Novell IPX" }, - { 0x2d, "VJ compressed TCP/IP" }, - { 0x2f, "VJ uncompressed TCP/IP" }, - { 0x31, "Bridging PDU" }, - { 0x33, "Stream Protocol ST-II" }, - { 0x35, "Banyan Vines" }, - { 0x39, "AppleTalk EDDP" }, - { 0x3b, "AppleTalk SmartBuffered" }, - { 0x3d, "Multi-Link" }, - { 0x3f, "NETBIOS Framing" }, - { 0x41, "Cisco Systems" }, - { 0x43, "Ascom Timeplex" }, - { 0x45, "Fujitsu Link Backup and Load Balancing (LBLB)" }, - { 0x47, "DCA Remote Lan" }, - { 0x49, "Serial Data Transport Protocol (PPP-SDTP)" }, - { 0x4b, "SNA over 802.2" }, - { 0x4d, "SNA" }, - { 0x4f, "IP6 Header Compression" }, - { 0x51, "KNX Bridging Data" }, - { 0x53, "Encryption" }, - { 0x55, "Individual Link Encryption" }, - { 0x57, "IPv6" }, - { 0x59, "PPP Muxing" }, - { 0x5b, "Vendor-Specific Network Protocol" }, - { 0x61, "RTP IPHC Full Header" }, - { 0x63, "RTP IPHC Compressed TCP" }, - { 0x65, "RTP IPHC Compressed non-TCP" }, - { 0x67, "RTP IPHC Compressed UDP 8" }, - { 0x69, "RTP IPHC Compressed RTP 8" }, - { 0x6f, "Stampede Bridging" }, - { 0x73, "MP+" }, - { 0xc1, "NTCITS IPI" }, - { 0xfb, "single-link compression" }, - { 0xfd, "Compressed Datagram" }, - { 0x0201, "802.1d Hello Packets" }, - { 0x0203, "IBM Source Routing BPDU" }, - { 0x0205, "DEC LANBridge100 Spanning Tree" }, - { 0x0207, "Cisco Discovery Protocol" }, - { 0x0209, "Netcs Twin Routing" }, - { 0x020b, "STP - Scheduled Transfer Protocol" }, - { 0x020d, "EDP - Extreme Discovery Protocol" }, - { 0x0211, "Optical Supervisory Channel Protocol" }, - { 0x0213, "Optical Supervisory Channel Protocol" }, - { 0x0231, "Luxcom" }, - { 0x0233, "Sigma Network Systems" }, - { 0x0235, "Apple Client Server Protocol" }, - { 0x0281, "MPLS Unicast" }, - { 0x0283, "MPLS Multicast" }, - { 0x0285, "IEEE p1284.4 standard - data packets" }, - { 0x0287, "ETSI TETRA Network Protocol Type 1" }, - { 0x0289, "Multichannel Flow Treatment Protocol" }, - { 0x2063, "RTP IPHC Compressed TCP No Delta" }, - { 0x2065, "RTP IPHC Context State" }, - { 0x2067, "RTP IPHC Compressed UDP 16" }, - { 0x2069, "RTP IPHC Compressed RTP 16" }, - { 0x4001, "Cray Communications Control Protocol" }, - { 0x4003, "CDPD Mobile Network Registration Protocol" }, - { 0x4005, "Expand accelerator protocol" }, - { 0x4007, "ODSICP NCP" }, - { 0x4009, "DOCSIS DLL" }, - { 0x400B, "Cetacean Network Detection Protocol" }, - { 0x4021, "Stacker LZS" }, - { 0x4023, "RefTek Protocol" }, - { 0x4025, "Fibre Channel" }, - { 0x4027, "EMIT Protocols" }, - { 0x405b, "Vendor-Specific Protocol (VSP)" }, - { 0x8021, "Internet Protocol Control Protocol" }, - { 0x8023, "OSI Network Layer Control Protocol" }, - { 0x8025, "Xerox NS IDP Control Protocol" }, - { 0x8027, "DECnet Phase IV Control Protocol" }, - { 0x8029, "Appletalk Control Protocol" }, - { 0x802b, "Novell IPX Control Protocol" }, - { 0x8031, "Bridging NCP" }, - { 0x8033, "Stream Protocol Control Protocol" }, - { 0x8035, "Banyan Vines Control Protocol" }, - { 0x803d, "Multi-Link Control Protocol" }, - { 0x803f, "NETBIOS Framing Control Protocol" }, - { 0x8041, "Cisco Systems Control Protocol" }, - { 0x8043, "Ascom Timeplex" }, - { 0x8045, "Fujitsu LBLB Control Protocol" }, - { 0x8047, "DCA Remote Lan Network Control Protocol (RLNCP)" }, - { 0x8049, "Serial Data Control Protocol (PPP-SDCP)" }, - { 0x804b, "SNA over 802.2 Control Protocol" }, - { 0x804d, "SNA Control Protocol" }, - { 0x804f, "IP6 Header Compression Control Protocol" }, - { 0x8051, "KNX Bridging Control Protocol" }, - { 0x8053, "Encryption Control Protocol" }, - { 0x8055, "Individual Link Encryption Control Protocol" }, - { 0x8057, "IPv6 Control Protocol" }, - { 0x8059, "PPP Muxing Control Protocol" }, - { 0x805b, "Vendor-Specific Network Control Protocol (VSNCP)" }, - { 0x806f, "Stampede Bridging Control Protocol" }, - { 0x8073, "MP+ Control Protocol" }, - { 0x80c1, "NTCITS IPI Control Protocol" }, - { 0x80fb, "Single Link Compression Control Protocol" }, - { 0x80fd, "Compression Control Protocol" }, - { 0x8207, "Cisco Discovery Protocol Control" }, - { 0x8209, "Netcs Twin Routing" }, - { 0x820b, "STP - Control Protocol" }, - { 0x820d, "EDPCP - Extreme Discovery Protocol Ctrl Prtcl" }, - { 0x8235, "Apple Client Server Protocol Control" }, - { 0x8281, "MPLSCP" }, - { 0x8285, "IEEE p1284.4 standard - Protocol Control" }, - { 0x8287, "ETSI TETRA TNP1 Control Protocol" }, - { 0x8289, "Multichannel Flow Treatment Protocol" }, - { 0xc021, "Link Control Protocol" }, - { 0xc023, "Password Authentication Protocol" }, - { 0xc025, "Link Quality Report" }, - { 0xc027, "Shiva Password Authentication Protocol" }, - { 0xc029, "CallBack Control Protocol (CBCP)" }, - { 0xc02b, "BACP Bandwidth Allocation Control Protocol" }, - { 0xc02d, "BAP" }, - { 0xc05b, "Vendor-Specific Authentication Protocol (VSAP)" }, - { 0xc081, "Container Control Protocol" }, - { 0xc223, "Challenge Handshake Authentication Protocol" }, - { 0xc225, "RSA Authentication Protocol" }, - { 0xc227, "Extensible Authentication Protocol" }, - { 0xc229, "Mitsubishi Security Info Exch Ptcl (SIEP)" }, - { 0xc26f, "Stampede Bridging Authorization Protocol" }, - { 0xc281, "Proprietary Authentication Protocol" }, - { 0xc283, "Proprietary Authentication Protocol" }, - { 0xc481, "Proprietary Node ID Authentication Protocol" }, - { 0, NULL }, -}; - -/* - * protocol_name - find a name for a PPP protocol. - */ -const char * protocol_name(int proto) { - const struct protocol_list *lp; - - for (lp = protocol_list; lp->proto != 0; ++lp) { - if (proto == lp->proto) { - return lp->name; - } - } - return NULL; -} -#endif /* PPP_PROTOCOLNAME */ - -#if PPP_STATS_SUPPORT - -/* ---- Note on PPP Stats support ---- - * - * The one willing link stats support should add the get_ppp_stats() - * to fetch statistics from lwIP. - */ - -/* - * reset_link_stats - "reset" stats when link goes up. - */ -void reset_link_stats(int u) { - if (!get_ppp_stats(u, &old_link_stats)) { - return; - } - gettimeofday(&start_time, NULL); -} - -/* - * update_link_stats - get stats at link termination. - */ -void update_link_stats(int u) { - struct timeval now; - char numbuf[32]; - - if (!get_ppp_stats(u, &link_stats) || gettimeofday(&now, NULL) < 0) { - return; - } - link_connect_time = now.tv_sec - start_time.tv_sec; - link_stats_valid = 1; - - link_stats.bytes_in -= old_link_stats.bytes_in; - link_stats.bytes_out -= old_link_stats.bytes_out; - link_stats.pkts_in -= old_link_stats.pkts_in; - link_stats.pkts_out -= old_link_stats.pkts_out; -} - -void print_link_stats() { - /* - * Print connect time and statistics. - */ - if (link_stats_valid) { - int t = (link_connect_time + 5) / 6; /* 1/10ths of minutes */ - info("Connect time %d.%d minutes.", t/10, t%10); - info("Sent %u bytes, received %u bytes.", link_stats.bytes_out, link_stats.bytes_in); - link_stats_valid = 0; - } -} -#endif /* PPP_STATS_SUPPORT */ - -#endif /* PPP_SUPPORT */ diff --git a/third_party/lwip/repo/lwip/src/netif/ppp/pppapi.c b/third_party/lwip/repo/lwip/src/netif/ppp/pppapi.c deleted file mode 100644 index 947f7ba8c14f98..00000000000000 --- a/third_party/lwip/repo/lwip/src/netif/ppp/pppapi.c +++ /dev/null @@ -1,427 +0,0 @@ -/** - * @file - * Point To Point Protocol Sequential API module - * - */ - -/* - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - */ - -#include "netif/ppp/ppp_opts.h" - -#if LWIP_PPP_API /* don't build if not configured for use in lwipopts.h */ - -#include "netif/ppp/pppapi.h" -#include "lwip/priv/tcpip_priv.h" -#include "netif/ppp/pppoe.h" -#include "netif/ppp/pppol2tp.h" -#include "netif/ppp/pppos.h" - -#if LWIP_MPU_COMPATIBLE -LWIP_MEMPOOL_DECLARE(PPPAPI_MSG, MEMP_NUM_PPP_API_MSG, sizeof(struct pppapi_msg), "PPPAPI_MSG") -#endif - -#define PPPAPI_VAR_REF(name) API_VAR_REF(name) -#define PPPAPI_VAR_DECLARE(name) API_VAR_DECLARE(struct pppapi_msg, name) -#define PPPAPI_VAR_ALLOC(name) API_VAR_ALLOC_POOL(struct pppapi_msg, PPPAPI_MSG, name, ERR_MEM) -#define PPPAPI_VAR_ALLOC_RETURN_NULL(name) API_VAR_ALLOC_POOL(struct pppapi_msg, PPPAPI_MSG, name, NULL) -#define PPPAPI_VAR_FREE(name) API_VAR_FREE_POOL(PPPAPI_MSG, name) - -/** - * Call ppp_set_default() inside the tcpip_thread context. - */ -static err_t -pppapi_do_ppp_set_default(struct tcpip_api_call_data *m) -{ - /* cast through void* to silence alignment warnings. - * We know it works because the structs have been instantiated as struct pppapi_msg */ - struct pppapi_msg *msg = (struct pppapi_msg *)(void*)m; - - ppp_set_default(msg->msg.ppp); - return ERR_OK; -} - -/** - * Call ppp_set_default() in a thread-safe way by running that function inside the - * tcpip_thread context. - */ -err_t -pppapi_set_default(ppp_pcb *pcb) -{ - err_t err; - PPPAPI_VAR_DECLARE(msg); - PPPAPI_VAR_ALLOC(msg); - - PPPAPI_VAR_REF(msg).msg.ppp = pcb; - err = tcpip_api_call(pppapi_do_ppp_set_default, &PPPAPI_VAR_REF(msg).call); - PPPAPI_VAR_FREE(msg); - return err; -} - - -#if PPP_NOTIFY_PHASE -/** - * Call ppp_set_notify_phase_callback() inside the tcpip_thread context. - */ -static err_t -pppapi_do_ppp_set_notify_phase_callback(struct tcpip_api_call_data *m) -{ - /* cast through void* to silence alignment warnings. - * We know it works because the structs have been instantiated as struct pppapi_msg */ - struct pppapi_msg *msg = (struct pppapi_msg *)(void*)m; - - ppp_set_notify_phase_callback(msg->msg.ppp, msg->msg.msg.setnotifyphasecb.notify_phase_cb); - return ERR_OK; -} - -/** - * Call ppp_set_notify_phase_callback() in a thread-safe way by running that function inside the - * tcpip_thread context. - */ -err_t -pppapi_set_notify_phase_callback(ppp_pcb *pcb, ppp_notify_phase_cb_fn notify_phase_cb) -{ - err_t err; - PPPAPI_VAR_DECLARE(msg); - PPPAPI_VAR_ALLOC(msg); - - PPPAPI_VAR_REF(msg).msg.ppp = pcb; - PPPAPI_VAR_REF(msg).msg.msg.setnotifyphasecb.notify_phase_cb = notify_phase_cb; - err = tcpip_api_call(pppapi_do_ppp_set_notify_phase_callback, &PPPAPI_VAR_REF(msg).call); - PPPAPI_VAR_FREE(msg); - return err; -} -#endif /* PPP_NOTIFY_PHASE */ - - -#if PPPOS_SUPPORT -/** - * Call pppos_create() inside the tcpip_thread context. - */ -static err_t -pppapi_do_pppos_create(struct tcpip_api_call_data *m) -{ - /* cast through void* to silence alignment warnings. - * We know it works because the structs have been instantiated as struct pppapi_msg */ - struct pppapi_msg *msg = (struct pppapi_msg *)(void*)m; - - msg->msg.ppp = pppos_create(msg->msg.msg.serialcreate.pppif, msg->msg.msg.serialcreate.output_cb, - msg->msg.msg.serialcreate.link_status_cb, msg->msg.msg.serialcreate.ctx_cb); - return ERR_OK; -} - -/** - * Call pppos_create() in a thread-safe way by running that function inside the - * tcpip_thread context. - */ -ppp_pcb* -pppapi_pppos_create(struct netif *pppif, pppos_output_cb_fn output_cb, - ppp_link_status_cb_fn link_status_cb, void *ctx_cb) -{ - ppp_pcb* result; - PPPAPI_VAR_DECLARE(msg); - PPPAPI_VAR_ALLOC_RETURN_NULL(msg); - - PPPAPI_VAR_REF(msg).msg.ppp = NULL; - PPPAPI_VAR_REF(msg).msg.msg.serialcreate.pppif = pppif; - PPPAPI_VAR_REF(msg).msg.msg.serialcreate.output_cb = output_cb; - PPPAPI_VAR_REF(msg).msg.msg.serialcreate.link_status_cb = link_status_cb; - PPPAPI_VAR_REF(msg).msg.msg.serialcreate.ctx_cb = ctx_cb; - tcpip_api_call(pppapi_do_pppos_create, &PPPAPI_VAR_REF(msg).call); - result = PPPAPI_VAR_REF(msg).msg.ppp; - PPPAPI_VAR_FREE(msg); - return result; -} -#endif /* PPPOS_SUPPORT */ - - -#if PPPOE_SUPPORT -/** - * Call pppoe_create() inside the tcpip_thread context. - */ -static err_t -pppapi_do_pppoe_create(struct tcpip_api_call_data *m) -{ - /* cast through void* to silence alignment warnings. - * We know it works because the structs have been instantiated as struct pppapi_msg */ - struct pppapi_msg *msg = (struct pppapi_msg *)(void*)m; - - msg->msg.ppp = pppoe_create(msg->msg.msg.ethernetcreate.pppif, msg->msg.msg.ethernetcreate.ethif, - msg->msg.msg.ethernetcreate.service_name, msg->msg.msg.ethernetcreate.concentrator_name, - msg->msg.msg.ethernetcreate.link_status_cb, msg->msg.msg.ethernetcreate.ctx_cb); - return ERR_OK; -} - -/** - * Call pppoe_create() in a thread-safe way by running that function inside the - * tcpip_thread context. - */ -ppp_pcb* -pppapi_pppoe_create(struct netif *pppif, struct netif *ethif, const char *service_name, - const char *concentrator_name, ppp_link_status_cb_fn link_status_cb, - void *ctx_cb) -{ - ppp_pcb* result; - PPPAPI_VAR_DECLARE(msg); - PPPAPI_VAR_ALLOC_RETURN_NULL(msg); - - PPPAPI_VAR_REF(msg).msg.ppp = NULL; - PPPAPI_VAR_REF(msg).msg.msg.ethernetcreate.pppif = pppif; - PPPAPI_VAR_REF(msg).msg.msg.ethernetcreate.ethif = ethif; - PPPAPI_VAR_REF(msg).msg.msg.ethernetcreate.service_name = service_name; - PPPAPI_VAR_REF(msg).msg.msg.ethernetcreate.concentrator_name = concentrator_name; - PPPAPI_VAR_REF(msg).msg.msg.ethernetcreate.link_status_cb = link_status_cb; - PPPAPI_VAR_REF(msg).msg.msg.ethernetcreate.ctx_cb = ctx_cb; - tcpip_api_call(pppapi_do_pppoe_create, &PPPAPI_VAR_REF(msg).call); - result = PPPAPI_VAR_REF(msg).msg.ppp; - PPPAPI_VAR_FREE(msg); - return result; -} -#endif /* PPPOE_SUPPORT */ - - -#if PPPOL2TP_SUPPORT -/** - * Call pppol2tp_create() inside the tcpip_thread context. - */ -static err_t -pppapi_do_pppol2tp_create(struct tcpip_api_call_data *m) -{ - /* cast through void* to silence alignment warnings. - * We know it works because the structs have been instantiated as struct pppapi_msg */ - struct pppapi_msg *msg = (struct pppapi_msg *)(void*)m; - - msg->msg.ppp = pppol2tp_create(msg->msg.msg.l2tpcreate.pppif, - msg->msg.msg.l2tpcreate.netif, API_EXPR_REF(msg->msg.msg.l2tpcreate.ipaddr), msg->msg.msg.l2tpcreate.port, -#if PPPOL2TP_AUTH_SUPPORT - msg->msg.msg.l2tpcreate.secret, - msg->msg.msg.l2tpcreate.secret_len, -#else /* PPPOL2TP_AUTH_SUPPORT */ - NULL, - 0, -#endif /* PPPOL2TP_AUTH_SUPPORT */ - msg->msg.msg.l2tpcreate.link_status_cb, msg->msg.msg.l2tpcreate.ctx_cb); - return ERR_OK; -} - -/** - * Call pppol2tp_create() in a thread-safe way by running that function inside the - * tcpip_thread context. - */ -ppp_pcb* -pppapi_pppol2tp_create(struct netif *pppif, struct netif *netif, ip_addr_t *ipaddr, u16_t port, - const u8_t *secret, u8_t secret_len, - ppp_link_status_cb_fn link_status_cb, void *ctx_cb) -{ - ppp_pcb* result; - PPPAPI_VAR_DECLARE(msg); - PPPAPI_VAR_ALLOC_RETURN_NULL(msg); -#if !PPPOL2TP_AUTH_SUPPORT - LWIP_UNUSED_ARG(secret); - LWIP_UNUSED_ARG(secret_len); -#endif /* !PPPOL2TP_AUTH_SUPPORT */ - - PPPAPI_VAR_REF(msg).msg.ppp = NULL; - PPPAPI_VAR_REF(msg).msg.msg.l2tpcreate.pppif = pppif; - PPPAPI_VAR_REF(msg).msg.msg.l2tpcreate.netif = netif; - PPPAPI_VAR_REF(msg).msg.msg.l2tpcreate.ipaddr = PPPAPI_VAR_REF(ipaddr); - PPPAPI_VAR_REF(msg).msg.msg.l2tpcreate.port = port; -#if PPPOL2TP_AUTH_SUPPORT - PPPAPI_VAR_REF(msg).msg.msg.l2tpcreate.secret = secret; - PPPAPI_VAR_REF(msg).msg.msg.l2tpcreate.secret_len = secret_len; -#endif /* PPPOL2TP_AUTH_SUPPORT */ - PPPAPI_VAR_REF(msg).msg.msg.l2tpcreate.link_status_cb = link_status_cb; - PPPAPI_VAR_REF(msg).msg.msg.l2tpcreate.ctx_cb = ctx_cb; - tcpip_api_call(pppapi_do_pppol2tp_create, &PPPAPI_VAR_REF(msg).call); - result = PPPAPI_VAR_REF(msg).msg.ppp; - PPPAPI_VAR_FREE(msg); - return result; -} -#endif /* PPPOL2TP_SUPPORT */ - - -/** - * Call ppp_connect() inside the tcpip_thread context. - */ -static err_t -pppapi_do_ppp_connect(struct tcpip_api_call_data *m) -{ - /* cast through void* to silence alignment warnings. - * We know it works because the structs have been instantiated as struct pppapi_msg */ - struct pppapi_msg *msg = (struct pppapi_msg *)(void*)m; - - return ppp_connect(msg->msg.ppp, msg->msg.msg.connect.holdoff); -} - -/** - * Call ppp_connect() in a thread-safe way by running that function inside the - * tcpip_thread context. - */ -err_t -pppapi_connect(ppp_pcb *pcb, u16_t holdoff) -{ - err_t err; - PPPAPI_VAR_DECLARE(msg); - PPPAPI_VAR_ALLOC(msg); - - PPPAPI_VAR_REF(msg).msg.ppp = pcb; - PPPAPI_VAR_REF(msg).msg.msg.connect.holdoff = holdoff; - err = tcpip_api_call(pppapi_do_ppp_connect, &PPPAPI_VAR_REF(msg).call); - PPPAPI_VAR_FREE(msg); - return err; -} - - -#if PPP_SERVER -/** - * Call ppp_listen() inside the tcpip_thread context. - */ -static err_t -pppapi_do_ppp_listen(struct tcpip_api_call_data *m) -{ - /* cast through void* to silence alignment warnings. - * We know it works because the structs have been instantiated as struct pppapi_msg */ - struct pppapi_msg *msg = (struct pppapi_msg *)(void*)m; - - return ppp_listen(msg->msg.ppp); -} - -/** - * Call ppp_listen() in a thread-safe way by running that function inside the - * tcpip_thread context. - */ -err_t -pppapi_listen(ppp_pcb *pcb) -{ - err_t err; - PPPAPI_VAR_DECLARE(msg); - PPPAPI_VAR_ALLOC(msg); - - PPPAPI_VAR_REF(msg).msg.ppp = pcb; - err = tcpip_api_call(pppapi_do_ppp_listen, &PPPAPI_VAR_REF(msg).call); - PPPAPI_VAR_FREE(msg); - return err; -} -#endif /* PPP_SERVER */ - - -/** - * Call ppp_close() inside the tcpip_thread context. - */ -static err_t -pppapi_do_ppp_close(struct tcpip_api_call_data *m) -{ - /* cast through void* to silence alignment warnings. - * We know it works because the structs have been instantiated as struct pppapi_msg */ - struct pppapi_msg *msg = (struct pppapi_msg *)(void*)m; - - return ppp_close(msg->msg.ppp, msg->msg.msg.close.nocarrier); -} - -/** - * Call ppp_close() in a thread-safe way by running that function inside the - * tcpip_thread context. - */ -err_t -pppapi_close(ppp_pcb *pcb, u8_t nocarrier) -{ - err_t err; - PPPAPI_VAR_DECLARE(msg); - PPPAPI_VAR_ALLOC(msg); - - PPPAPI_VAR_REF(msg).msg.ppp = pcb; - PPPAPI_VAR_REF(msg).msg.msg.close.nocarrier = nocarrier; - err = tcpip_api_call(pppapi_do_ppp_close, &PPPAPI_VAR_REF(msg).call); - PPPAPI_VAR_FREE(msg); - return err; -} - - -/** - * Call ppp_free() inside the tcpip_thread context. - */ -static err_t -pppapi_do_ppp_free(struct tcpip_api_call_data *m) -{ - /* cast through void* to silence alignment warnings. - * We know it works because the structs have been instantiated as struct pppapi_msg */ - struct pppapi_msg *msg = (struct pppapi_msg *)(void*)m; - - return ppp_free(msg->msg.ppp); -} - -/** - * Call ppp_free() in a thread-safe way by running that function inside the - * tcpip_thread context. - */ -err_t -pppapi_free(ppp_pcb *pcb) -{ - err_t err; - PPPAPI_VAR_DECLARE(msg); - PPPAPI_VAR_ALLOC(msg); - - PPPAPI_VAR_REF(msg).msg.ppp = pcb; - err = tcpip_api_call(pppapi_do_ppp_free, &PPPAPI_VAR_REF(msg).call); - PPPAPI_VAR_FREE(msg); - return err; -} - - -/** - * Call ppp_ioctl() inside the tcpip_thread context. - */ -static err_t -pppapi_do_ppp_ioctl(struct tcpip_api_call_data *m) -{ - /* cast through void* to silence alignment warnings. - * We know it works because the structs have been instantiated as struct pppapi_msg */ - struct pppapi_msg *msg = (struct pppapi_msg *)(void*)m; - - return ppp_ioctl(msg->msg.ppp, msg->msg.msg.ioctl.cmd, msg->msg.msg.ioctl.arg); -} - -/** - * Call ppp_ioctl() in a thread-safe way by running that function inside the - * tcpip_thread context. - */ -err_t -pppapi_ioctl(ppp_pcb *pcb, u8_t cmd, void *arg) -{ - err_t err; - PPPAPI_VAR_DECLARE(msg); - PPPAPI_VAR_ALLOC(msg); - - PPPAPI_VAR_REF(msg).msg.ppp = pcb; - PPPAPI_VAR_REF(msg).msg.msg.ioctl.cmd = cmd; - PPPAPI_VAR_REF(msg).msg.msg.ioctl.arg = arg; - err = tcpip_api_call(pppapi_do_ppp_ioctl, &PPPAPI_VAR_REF(msg).call); - PPPAPI_VAR_FREE(msg); - return err; -} - -#endif /* LWIP_PPP_API */ diff --git a/third_party/lwip/repo/lwip/src/netif/ppp/pppcrypt.c b/third_party/lwip/repo/lwip/src/netif/ppp/pppcrypt.c deleted file mode 100644 index 82d78c13ac31ed..00000000000000 --- a/third_party/lwip/repo/lwip/src/netif/ppp/pppcrypt.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - * pppcrypt.c - PPP/DES linkage for MS-CHAP and EAP SRP-SHA1 - * - * Extracted from chap_ms.c by James Carlson. - * - * Copyright (c) 1995 Eric Rosenquist. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name(s) of the authors of this software must not be used to - * endorse or promote products derived from this software without - * prior written permission. - * - * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT && MSCHAP_SUPPORT /* don't build if not necessary */ - -#include "netif/ppp/ppp_impl.h" - -#include "netif/ppp/pppcrypt.h" - - -static u_char pppcrypt_get_7bits(u_char *input, int startBit) { - unsigned int word; - - word = (unsigned)input[startBit / 8] << 8; - word |= (unsigned)input[startBit / 8 + 1]; - - word >>= 15 - (startBit % 8 + 7); - - return word & 0xFE; -} - -/* IN 56 bit DES key missing parity bits - * OUT 64 bit DES key with parity bits added - */ -void pppcrypt_56_to_64_bit_key(u_char *key, u_char * des_key) { - des_key[0] = pppcrypt_get_7bits(key, 0); - des_key[1] = pppcrypt_get_7bits(key, 7); - des_key[2] = pppcrypt_get_7bits(key, 14); - des_key[3] = pppcrypt_get_7bits(key, 21); - des_key[4] = pppcrypt_get_7bits(key, 28); - des_key[5] = pppcrypt_get_7bits(key, 35); - des_key[6] = pppcrypt_get_7bits(key, 42); - des_key[7] = pppcrypt_get_7bits(key, 49); -} - -#endif /* PPP_SUPPORT && MSCHAP_SUPPORT */ diff --git a/third_party/lwip/repo/lwip/src/netif/ppp/pppoe.c b/third_party/lwip/repo/lwip/src/netif/ppp/pppoe.c deleted file mode 100644 index eabfa4d0414003..00000000000000 --- a/third_party/lwip/repo/lwip/src/netif/ppp/pppoe.c +++ /dev/null @@ -1,1191 +0,0 @@ -/***************************************************************************** -* pppoe.c - PPP Over Ethernet implementation for lwIP. -* -* Copyright (c) 2006 by Marc Boucher, Services Informatiques (MBSI) inc. -* -* The authors hereby grant permission to use, copy, modify, distribute, -* and license this software and its documentation for any purpose, provided -* that existing copyright notices are retained in all copies and that this -* notice and the following disclaimer are included verbatim in any -* distributions. No written agreement, license, or royalty fee is required -* for any of the authorized uses. -* -* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS *AS IS* AND ANY EXPRESS OR -* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. -* IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, -* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT -* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF -* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -* -****************************************************************************** -* REVISION HISTORY -* -* 06-01-01 Marc Boucher -* Ported to lwIP. -*****************************************************************************/ - - - -/* based on NetBSD: if_pppoe.c,v 1.64 2006/01/31 23:50:15 martin Exp */ - -/*- - * Copyright (c) 2002 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Martin Husemann . - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT && PPPOE_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#if 0 /* UNUSED */ -#include -#include -#endif /* UNUSED */ - -#include "lwip/timeouts.h" -#include "lwip/memp.h" -#include "lwip/stats.h" -#include "lwip/snmp.h" - -#include "netif/ethernet.h" -#include "netif/ppp/ppp_impl.h" -#include "netif/ppp/lcp.h" -#include "netif/ppp/ipcp.h" -#include "netif/ppp/pppoe.h" - -/* Memory pool */ -LWIP_MEMPOOL_DECLARE(PPPOE_IF, MEMP_NUM_PPPOE_INTERFACES, sizeof(struct pppoe_softc), "PPPOE_IF") - -/* Add a 16 bit unsigned value to a buffer pointed to by PTR */ -#define PPPOE_ADD_16(PTR, VAL) \ - *(PTR)++ = (u8_t)((VAL) / 256); \ - *(PTR)++ = (u8_t)((VAL) % 256) - -/* Add a complete PPPoE header to the buffer pointed to by PTR */ -#define PPPOE_ADD_HEADER(PTR, CODE, SESS, LEN) \ - *(PTR)++ = PPPOE_VERTYPE; \ - *(PTR)++ = (CODE); \ - PPPOE_ADD_16(PTR, SESS); \ - PPPOE_ADD_16(PTR, LEN) - -#define PPPOE_DISC_TIMEOUT (5*1000) /* base for quick timeout calculation */ -#define PPPOE_SLOW_RETRY (60*1000) /* persistent retry interval */ -#define PPPOE_DISC_MAXPADI 4 /* retry PADI four times (quickly) */ -#define PPPOE_DISC_MAXPADR 2 /* retry PADR twice */ - -#ifdef PPPOE_SERVER -#error "PPPOE_SERVER is not yet supported under lwIP!" -/* from if_spppsubr.c */ -#define IFF_PASSIVE IFF_LINK0 /* wait passively for connection */ -#endif - -#define PPPOE_ERRORSTRING_LEN 64 - - -/* callbacks called from PPP core */ -static err_t pppoe_write(ppp_pcb *ppp, void *ctx, struct pbuf *p); -static err_t pppoe_netif_output(ppp_pcb *ppp, void *ctx, struct pbuf *p, u_short protocol); -static void pppoe_connect(ppp_pcb *ppp, void *ctx); -static void pppoe_disconnect(ppp_pcb *ppp, void *ctx); -static err_t pppoe_destroy(ppp_pcb *ppp, void *ctx); - -/* management routines */ -static void pppoe_abort_connect(struct pppoe_softc *); -#if 0 /* UNUSED */ -static void pppoe_clear_softc(struct pppoe_softc *, const char *); -#endif /* UNUSED */ - -/* internal timeout handling */ -static void pppoe_timeout(void *); - -/* sending actual protocol controll packets */ -static err_t pppoe_send_padi(struct pppoe_softc *); -static err_t pppoe_send_padr(struct pppoe_softc *); -#ifdef PPPOE_SERVER -static err_t pppoe_send_pado(struct pppoe_softc *); -static err_t pppoe_send_pads(struct pppoe_softc *); -#endif -static err_t pppoe_send_padt(struct netif *, u_int, const u8_t *); - -/* internal helper functions */ -static err_t pppoe_xmit(struct pppoe_softc *sc, struct pbuf *pb); -static struct pppoe_softc* pppoe_find_softc_by_session(u_int session, struct netif *rcvif); -static struct pppoe_softc* pppoe_find_softc_by_hunique(u8_t *token, size_t len, struct netif *rcvif); - -/** linked list of created pppoe interfaces */ -static struct pppoe_softc *pppoe_softc_list; - -/* Callbacks structure for PPP core */ -static const struct link_callbacks pppoe_callbacks = { - pppoe_connect, -#if PPP_SERVER - NULL, -#endif /* PPP_SERVER */ - pppoe_disconnect, - pppoe_destroy, - pppoe_write, - pppoe_netif_output, - NULL, - NULL -}; - -/* - * Create a new PPP Over Ethernet (PPPoE) connection. - * - * Return 0 on success, an error code on failure. - */ -ppp_pcb *pppoe_create(struct netif *pppif, - struct netif *ethif, - const char *service_name, const char *concentrator_name, - ppp_link_status_cb_fn link_status_cb, void *ctx_cb) -{ - ppp_pcb *ppp; - struct pppoe_softc *sc; - LWIP_UNUSED_ARG(service_name); - LWIP_UNUSED_ARG(concentrator_name); - - sc = (struct pppoe_softc *)LWIP_MEMPOOL_ALLOC(PPPOE_IF); - if (sc == NULL) { - return NULL; - } - - ppp = ppp_new(pppif, &pppoe_callbacks, sc, link_status_cb, ctx_cb); - if (ppp == NULL) { - LWIP_MEMPOOL_FREE(PPPOE_IF, sc); - return NULL; - } - - memset(sc, 0, sizeof(struct pppoe_softc)); - sc->pcb = ppp; - sc->sc_ethif = ethif; - /* put the new interface at the head of the list */ - sc->next = pppoe_softc_list; - pppoe_softc_list = sc; - return ppp; -} - -/* Called by PPP core */ -static err_t pppoe_write(ppp_pcb *ppp, void *ctx, struct pbuf *p) { - struct pppoe_softc *sc = (struct pppoe_softc *)ctx; - struct pbuf *ph; /* Ethernet + PPPoE header */ - err_t ret; -#if MIB2_STATS - u16_t tot_len; -#else /* MIB2_STATS */ - LWIP_UNUSED_ARG(ppp); -#endif /* MIB2_STATS */ - - /* skip address & flags */ - pbuf_header(p, -(s16_t)2); - - ph = pbuf_alloc(PBUF_LINK, (u16_t)(PPPOE_HEADERLEN), PBUF_RAM); - if(!ph) { - LINK_STATS_INC(link.memerr); - LINK_STATS_INC(link.proterr); - MIB2_STATS_NETIF_INC(ppp->netif, ifoutdiscards); - pbuf_free(p); - return ERR_MEM; - } - - pbuf_header(ph, -(s16_t)PPPOE_HEADERLEN); /* hide PPPoE header */ - pbuf_cat(ph, p); -#if MIB2_STATS - tot_len = ph->tot_len; -#endif /* MIB2_STATS */ - - ret = pppoe_xmit(sc, ph); - if (ret != ERR_OK) { - LINK_STATS_INC(link.err); - MIB2_STATS_NETIF_INC(ppp->netif, ifoutdiscards); - return ret; - } - - MIB2_STATS_NETIF_ADD(ppp->netif, ifoutoctets, (u16_t)tot_len); - MIB2_STATS_NETIF_INC(ppp->netif, ifoutucastpkts); - LINK_STATS_INC(link.xmit); - return ERR_OK; -} - -/* Called by PPP core */ -static err_t pppoe_netif_output(ppp_pcb *ppp, void *ctx, struct pbuf *p, u_short protocol) { - struct pppoe_softc *sc = (struct pppoe_softc *)ctx; - struct pbuf *pb; - u8_t *pl; - err_t err; -#if MIB2_STATS - u16_t tot_len; -#else /* MIB2_STATS */ - LWIP_UNUSED_ARG(ppp); -#endif /* MIB2_STATS */ - - /* @todo: try to use pbuf_header() here! */ - pb = pbuf_alloc(PBUF_LINK, PPPOE_HEADERLEN + sizeof(protocol), PBUF_RAM); - if(!pb) { - LINK_STATS_INC(link.memerr); - LINK_STATS_INC(link.proterr); - MIB2_STATS_NETIF_INC(ppp->netif, ifoutdiscards); - return ERR_MEM; - } - - pbuf_header(pb, -(s16_t)PPPOE_HEADERLEN); - - pl = (u8_t*)pb->payload; - PUTSHORT(protocol, pl); - - pbuf_chain(pb, p); -#if MIB2_STATS - tot_len = pb->tot_len; -#endif /* MIB2_STATS */ - - if( (err = pppoe_xmit(sc, pb)) != ERR_OK) { - LINK_STATS_INC(link.err); - MIB2_STATS_NETIF_INC(ppp->netif, ifoutdiscards); - return err; - } - - MIB2_STATS_NETIF_ADD(ppp->netif, ifoutoctets, tot_len); - MIB2_STATS_NETIF_INC(ppp->netif, ifoutucastpkts); - LINK_STATS_INC(link.xmit); - return ERR_OK; -} - -static err_t -pppoe_destroy(ppp_pcb *ppp, void *ctx) -{ - struct pppoe_softc *sc = (struct pppoe_softc *)ctx; - struct pppoe_softc **copp, *freep; - LWIP_UNUSED_ARG(ppp); - - sys_untimeout(pppoe_timeout, sc); - - /* remove interface from list */ - for (copp = &pppoe_softc_list; (freep = *copp); copp = &freep->next) { - if (freep == sc) { - *copp = freep->next; - break; - } - } - -#ifdef PPPOE_TODO - if (sc->sc_concentrator_name) { - mem_free(sc->sc_concentrator_name); - } - if (sc->sc_service_name) { - mem_free(sc->sc_service_name); - } -#endif /* PPPOE_TODO */ - LWIP_MEMPOOL_FREE(PPPOE_IF, sc); - - return ERR_OK; -} - -/* - * Find the interface handling the specified session. - * Note: O(number of sessions open), this is a client-side only, mean - * and lean implementation, so number of open sessions typically should - * be 1. - */ -static struct pppoe_softc* pppoe_find_softc_by_session(u_int session, struct netif *rcvif) { - struct pppoe_softc *sc; - - for (sc = pppoe_softc_list; sc != NULL; sc = sc->next) { - if (sc->sc_state == PPPOE_STATE_SESSION - && sc->sc_session == session - && sc->sc_ethif == rcvif) { - return sc; - } - } - return NULL; -} - -/* Check host unique token passed and return appropriate softc pointer, - * or NULL if token is bogus. */ -static struct pppoe_softc* pppoe_find_softc_by_hunique(u8_t *token, size_t len, struct netif *rcvif) { - struct pppoe_softc *sc, *t; - - if (len != sizeof sc) { - return NULL; - } - MEMCPY(&t, token, len); - - for (sc = pppoe_softc_list; sc != NULL; sc = sc->next) { - if (sc == t) { - break; - } - } - - if (sc == NULL) { - PPPDEBUG(LOG_DEBUG, ("pppoe: alien host unique tag, no session found\n")); - return NULL; - } - - /* should be safe to access *sc now */ - if (sc->sc_state < PPPOE_STATE_PADI_SENT || sc->sc_state >= PPPOE_STATE_SESSION) { - PPPDEBUG(LOG_DEBUG, ("%c%c%"U16_F": host unique tag found, but it belongs to a connection in state %d\n", - sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, sc->sc_state)); - return NULL; - } - if (sc->sc_ethif != rcvif) { - PPPDEBUG(LOG_DEBUG, ("%c%c%"U16_F": wrong interface, not accepting host unique\n", - sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num)); - return NULL; - } - return sc; -} - -/* analyze and handle a single received packet while not in session state */ -void -pppoe_disc_input(struct netif *netif, struct pbuf *pb) -{ - u16_t tag, len; - u16_t session, plen; - struct pppoe_softc *sc; -#if PPP_DEBUG - const char *err_msg = NULL; -#endif /* PPP_DEBUG */ - u8_t *ac_cookie; - u16_t ac_cookie_len; -#ifdef PPPOE_SERVER - u8_t *hunique; - size_t hunique_len; -#endif - struct pppoehdr *ph; - struct pppoetag pt; - int off, err; - struct eth_hdr *ethhdr; - - /* don't do anything if there is not a single PPPoE instance */ - if (pppoe_softc_list == NULL) { - pbuf_free(pb); - return; - } - - pb = ppp_singlebuf(pb); - - if (pb->len < sizeof(*ethhdr)) { - goto done; - } - ethhdr = (struct eth_hdr *)pb->payload; - off = sizeof(*ethhdr); - - ac_cookie = NULL; - ac_cookie_len = 0; -#ifdef PPPOE_SERVER - hunique = NULL; - hunique_len = 0; -#endif - session = 0; - if (pb->len - off < (u16_t)PPPOE_HEADERLEN) { - PPPDEBUG(LOG_DEBUG, ("pppoe: packet too short: %d\n", pb->len)); - goto done; - } - - ph = (struct pppoehdr *) (ethhdr + 1); - if (ph->vertype != PPPOE_VERTYPE) { - PPPDEBUG(LOG_DEBUG, ("pppoe: unknown version/type packet: 0x%x\n", ph->vertype)); - goto done; - } - session = lwip_ntohs(ph->session); - plen = lwip_ntohs(ph->plen); - off += sizeof(*ph); - - if (plen + off > pb->len) { - PPPDEBUG(LOG_DEBUG, ("pppoe: packet content does not fit: data available = %d, packet size = %u\n", - pb->len - off, plen)); - goto done; - } - if(pb->tot_len == pb->len) { - pb->tot_len = pb->len = (u16_t)off + plen; /* ignore trailing garbage */ - } - tag = 0; - len = 0; - sc = NULL; - while (off + sizeof(pt) <= pb->len) { - MEMCPY(&pt, (u8_t*)pb->payload + off, sizeof(pt)); - tag = lwip_ntohs(pt.tag); - len = lwip_ntohs(pt.len); - if (off + sizeof(pt) + len > pb->len) { - PPPDEBUG(LOG_DEBUG, ("pppoe: tag 0x%x len 0x%x is too long\n", tag, len)); - goto done; - } - switch (tag) { - case PPPOE_TAG_EOL: - goto breakbreak; - case PPPOE_TAG_SNAME: - break; /* ignored */ - case PPPOE_TAG_ACNAME: - break; /* ignored */ - case PPPOE_TAG_HUNIQUE: - if (sc != NULL) { - break; - } -#ifdef PPPOE_SERVER - hunique = (u8_t*)pb->payload + off + sizeof(pt); - hunique_len = len; -#endif - sc = pppoe_find_softc_by_hunique((u8_t*)pb->payload + off + sizeof(pt), len, netif); - break; - case PPPOE_TAG_ACCOOKIE: - if (ac_cookie == NULL) { - if (len > PPPOE_MAX_AC_COOKIE_LEN) { - PPPDEBUG(LOG_DEBUG, ("pppoe: AC cookie is too long: len = %d, max = %d\n", len, PPPOE_MAX_AC_COOKIE_LEN)); - goto done; - } - ac_cookie = (u8_t*)pb->payload + off + sizeof(pt); - ac_cookie_len = len; - } - break; -#if PPP_DEBUG - case PPPOE_TAG_SNAME_ERR: - err_msg = "SERVICE NAME ERROR"; - break; - case PPPOE_TAG_ACSYS_ERR: - err_msg = "AC SYSTEM ERROR"; - break; - case PPPOE_TAG_GENERIC_ERR: - err_msg = "GENERIC ERROR"; - break; -#endif /* PPP_DEBUG */ - default: - break; - } -#if PPP_DEBUG - if (err_msg != NULL) { - char error_tmp[PPPOE_ERRORSTRING_LEN]; - u16_t error_len = LWIP_MIN(len, sizeof(error_tmp)-1); - strncpy(error_tmp, (char*)pb->payload + off + sizeof(pt), error_len); - error_tmp[error_len] = '\0'; - if (sc) { - PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": %s: %s\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, err_msg, error_tmp)); - } else { - PPPDEBUG(LOG_DEBUG, ("pppoe: %s: %s\n", err_msg, error_tmp)); - } - } -#endif /* PPP_DEBUG */ - off += sizeof(pt) + len; - } - -breakbreak:; - switch (ph->code) { - case PPPOE_CODE_PADI: -#ifdef PPPOE_SERVER - /* - * got service name, concentrator name, and/or host unique. - * ignore if we have no interfaces with IFF_PASSIVE|IFF_UP. - */ - if (LIST_EMPTY(&pppoe_softc_list)) { - goto done; - } - LIST_FOREACH(sc, &pppoe_softc_list, sc_list) { - if (!(sc->sc_sppp.pp_if.if_flags & IFF_UP)) { - continue; - } - if (!(sc->sc_sppp.pp_if.if_flags & IFF_PASSIVE)) { - continue; - } - if (sc->sc_state == PPPOE_STATE_INITIAL) { - break; - } - } - if (sc == NULL) { - /* PPPDEBUG(LOG_DEBUG, ("pppoe: free passive interface is not found\n")); */ - goto done; - } - if (hunique) { - if (sc->sc_hunique) { - mem_free(sc->sc_hunique); - } - sc->sc_hunique = mem_malloc(hunique_len); - if (sc->sc_hunique == NULL) { - goto done; - } - sc->sc_hunique_len = hunique_len; - MEMCPY(sc->sc_hunique, hunique, hunique_len); - } - MEMCPY(&sc->sc_dest, eh->ether_shost, sizeof sc->sc_dest); - sc->sc_state = PPPOE_STATE_PADO_SENT; - pppoe_send_pado(sc); - break; -#endif /* PPPOE_SERVER */ - case PPPOE_CODE_PADR: -#ifdef PPPOE_SERVER - /* - * get sc from ac_cookie if IFF_PASSIVE - */ - if (ac_cookie == NULL) { - /* be quiet if there is not a single pppoe instance */ - PPPDEBUG(LOG_DEBUG, ("pppoe: received PADR but not includes ac_cookie\n")); - goto done; - } - sc = pppoe_find_softc_by_hunique(ac_cookie, ac_cookie_len, netif); - if (sc == NULL) { - /* be quiet if there is not a single pppoe instance */ - if (!LIST_EMPTY(&pppoe_softc_list)) { - PPPDEBUG(LOG_DEBUG, ("pppoe: received PADR but could not find request for it\n")); - } - goto done; - } - if (sc->sc_state != PPPOE_STATE_PADO_SENT) { - PPPDEBUG(LOG_DEBUG, ("%c%c%"U16_F": received unexpected PADR\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num)); - goto done; - } - if (hunique) { - if (sc->sc_hunique) { - mem_free(sc->sc_hunique); - } - sc->sc_hunique = mem_malloc(hunique_len); - if (sc->sc_hunique == NULL) { - goto done; - } - sc->sc_hunique_len = hunique_len; - MEMCPY(sc->sc_hunique, hunique, hunique_len); - } - pppoe_send_pads(sc); - sc->sc_state = PPPOE_STATE_SESSION; - ppp_start(sc->pcb); /* notify upper layers */ - break; -#else - /* ignore, we are no access concentrator */ - goto done; -#endif /* PPPOE_SERVER */ - case PPPOE_CODE_PADO: - if (sc == NULL) { - /* be quiet if there is not a single pppoe instance */ - if (pppoe_softc_list != NULL) { - PPPDEBUG(LOG_DEBUG, ("pppoe: received PADO but could not find request for it\n")); - } - goto done; - } - if (sc->sc_state != PPPOE_STATE_PADI_SENT) { - PPPDEBUG(LOG_DEBUG, ("%c%c%"U16_F": received unexpected PADO\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num)); - goto done; - } - if (ac_cookie) { - sc->sc_ac_cookie_len = ac_cookie_len; - MEMCPY(sc->sc_ac_cookie, ac_cookie, ac_cookie_len); - } - MEMCPY(&sc->sc_dest, ethhdr->src.addr, sizeof(sc->sc_dest.addr)); - sys_untimeout(pppoe_timeout, sc); - sc->sc_padr_retried = 0; - sc->sc_state = PPPOE_STATE_PADR_SENT; - if ((err = pppoe_send_padr(sc)) != 0) { - PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": failed to send PADR, error=%d\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, err)); - } - sys_timeout(PPPOE_DISC_TIMEOUT * (1 + sc->sc_padr_retried), pppoe_timeout, sc); - break; - case PPPOE_CODE_PADS: - if (sc == NULL) { - goto done; - } - sc->sc_session = session; - sys_untimeout(pppoe_timeout, sc); - PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": session 0x%x connected\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, session)); - sc->sc_state = PPPOE_STATE_SESSION; - ppp_start(sc->pcb); /* notify upper layers */ - break; - case PPPOE_CODE_PADT: - /* Don't disconnect here, we let the LCP Echo/Reply find the fact - * that PPP session is down. Asking the PPP stack to end the session - * require strict checking about the PPP phase to prevent endless - * disconnection loops. - */ -#if 0 /* UNUSED */ - if (sc == NULL) { /* PADT frames are rarely sent with a hunique tag, this is actually almost always true */ - goto done; - } - pppoe_clear_softc(sc, "received PADT"); -#endif /* UNUSED */ - break; - default: - if(sc) { - PPPDEBUG(LOG_DEBUG, ("%c%c%"U16_F": unknown code (0x%"X16_F") session = 0x%"X16_F"\n", - sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, - (u16_t)ph->code, session)); - } else { - PPPDEBUG(LOG_DEBUG, ("pppoe: unknown code (0x%"X16_F") session = 0x%"X16_F"\n", (u16_t)ph->code, session)); - } - break; - } - -done: - pbuf_free(pb); - return; -} - -void -pppoe_data_input(struct netif *netif, struct pbuf *pb) -{ - u16_t session, plen; - struct pppoe_softc *sc; - struct pppoehdr *ph; -#ifdef PPPOE_TERM_UNKNOWN_SESSIONS - u8_t shost[ETHER_ADDR_LEN]; -#endif - -#ifdef PPPOE_TERM_UNKNOWN_SESSIONS - MEMCPY(shost, ((struct eth_hdr *)pb->payload)->src.addr, sizeof(shost)); -#endif - if (pbuf_header(pb, -(s16_t)sizeof(struct eth_hdr)) != 0) { - /* bail out */ - PPPDEBUG(LOG_ERR, ("pppoe_data_input: pbuf_header failed\n")); - LINK_STATS_INC(link.lenerr); - goto drop; - } - - if (pb->len < sizeof(*ph)) { - PPPDEBUG(LOG_DEBUG, ("pppoe_data_input: could not get PPPoE header\n")); - goto drop; - } - ph = (struct pppoehdr *)pb->payload; - - if (ph->vertype != PPPOE_VERTYPE) { - PPPDEBUG(LOG_DEBUG, ("pppoe (data): unknown version/type packet: 0x%x\n", ph->vertype)); - goto drop; - } - if (ph->code != 0) { - goto drop; - } - - session = lwip_ntohs(ph->session); - sc = pppoe_find_softc_by_session(session, netif); - if (sc == NULL) { -#ifdef PPPOE_TERM_UNKNOWN_SESSIONS - PPPDEBUG(LOG_DEBUG, ("pppoe: input for unknown session 0x%x, sending PADT\n", session)); - pppoe_send_padt(netif, session, shost); -#endif - goto drop; - } - - plen = lwip_ntohs(ph->plen); - - if (pbuf_header(pb, -(s16_t)(PPPOE_HEADERLEN)) != 0) { - /* bail out */ - PPPDEBUG(LOG_ERR, ("pppoe_data_input: pbuf_header PPPOE_HEADERLEN failed\n")); - LINK_STATS_INC(link.lenerr); - goto drop; - } - - PPPDEBUG(LOG_DEBUG, ("pppoe_data_input: %c%c%"U16_F": pkthdr.len=%d, pppoe.len=%d\n", - sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, - pb->len, plen)); - - if (pb->tot_len < plen) { - goto drop; - } - - /* Dispatch the packet thereby consuming it. */ - ppp_input(sc->pcb, pb); - return; - -drop: - pbuf_free(pb); -} - -static err_t -pppoe_output(struct pppoe_softc *sc, struct pbuf *pb) -{ - struct eth_hdr *ethhdr; - u16_t etype; - err_t res; - - /* make room for Ethernet header - should not fail */ - if (pbuf_header(pb, (s16_t)(sizeof(struct eth_hdr))) != 0) { - /* bail out */ - PPPDEBUG(LOG_ERR, ("pppoe: %c%c%"U16_F": pppoe_output: could not allocate room for Ethernet header\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num)); - LINK_STATS_INC(link.lenerr); - pbuf_free(pb); - return ERR_BUF; - } - ethhdr = (struct eth_hdr *)pb->payload; - etype = sc->sc_state == PPPOE_STATE_SESSION ? ETHTYPE_PPPOE : ETHTYPE_PPPOEDISC; - ethhdr->type = lwip_htons(etype); - MEMCPY(ðhdr->dest.addr, &sc->sc_dest.addr, sizeof(ethhdr->dest.addr)); - MEMCPY(ðhdr->src.addr, &sc->sc_ethif->hwaddr, sizeof(ethhdr->src.addr)); - - PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F" (%x) state=%d, session=0x%x output -> %02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F":%02"X16_F", len=%d\n", - sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, etype, - sc->sc_state, sc->sc_session, - sc->sc_dest.addr[0], sc->sc_dest.addr[1], sc->sc_dest.addr[2], sc->sc_dest.addr[3], sc->sc_dest.addr[4], sc->sc_dest.addr[5], - pb->tot_len)); - - res = sc->sc_ethif->linkoutput(sc->sc_ethif, pb); - - pbuf_free(pb); - - return res; -} - -static err_t -pppoe_send_padi(struct pppoe_softc *sc) -{ - struct pbuf *pb; - u8_t *p; - int len; -#ifdef PPPOE_TODO - int l1 = 0, l2 = 0; /* XXX: gcc */ -#endif /* PPPOE_TODO */ - - /* calculate length of frame (excluding ethernet header + pppoe header) */ - len = 2 + 2 + 2 + 2 + sizeof sc; /* service name tag is required, host unique is send too */ -#ifdef PPPOE_TODO - if (sc->sc_service_name != NULL) { - l1 = (int)strlen(sc->sc_service_name); - len += l1; - } - if (sc->sc_concentrator_name != NULL) { - l2 = (int)strlen(sc->sc_concentrator_name); - len += 2 + 2 + l2; - } -#endif /* PPPOE_TODO */ - LWIP_ASSERT("sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len <= 0xffff", - sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len <= 0xffff); - - /* allocate a buffer */ - pb = pbuf_alloc(PBUF_LINK, (u16_t)(PPPOE_HEADERLEN + len), PBUF_RAM); - if (!pb) { - return ERR_MEM; - } - LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len); - - p = (u8_t*)pb->payload; - /* fill in pkt */ - PPPOE_ADD_HEADER(p, PPPOE_CODE_PADI, 0, (u16_t)len); - PPPOE_ADD_16(p, PPPOE_TAG_SNAME); -#ifdef PPPOE_TODO - if (sc->sc_service_name != NULL) { - PPPOE_ADD_16(p, l1); - MEMCPY(p, sc->sc_service_name, l1); - p += l1; - } else -#endif /* PPPOE_TODO */ - { - PPPOE_ADD_16(p, 0); - } -#ifdef PPPOE_TODO - if (sc->sc_concentrator_name != NULL) { - PPPOE_ADD_16(p, PPPOE_TAG_ACNAME); - PPPOE_ADD_16(p, l2); - MEMCPY(p, sc->sc_concentrator_name, l2); - p += l2; - } -#endif /* PPPOE_TODO */ - PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE); - PPPOE_ADD_16(p, sizeof(sc)); - MEMCPY(p, &sc, sizeof sc); - - /* send pkt */ - return pppoe_output(sc, pb); -} - -static void -pppoe_timeout(void *arg) -{ - u32_t retry_wait; - int err; - struct pppoe_softc *sc = (struct pppoe_softc*)arg; - - PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": timeout\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num)); - - switch (sc->sc_state) { - case PPPOE_STATE_PADI_SENT: - /* - * We have two basic ways of retrying: - * - Quick retry mode: try a few times in short sequence - * - Slow retry mode: we already had a connection successfully - * established and will try infinitely (without user - * intervention) - * We only enter slow retry mode if IFF_LINK1 (aka autodial) - * is not set. - */ - if (sc->sc_padi_retried < 0xff) { - sc->sc_padi_retried++; - } - if (!sc->pcb->settings.persist && sc->sc_padi_retried >= PPPOE_DISC_MAXPADI) { -#if 0 - if ((sc->sc_sppp.pp_if.if_flags & IFF_LINK1) == 0) { - /* slow retry mode */ - retry_wait = PPPOE_SLOW_RETRY; - } else -#endif - { - pppoe_abort_connect(sc); - return; - } - } - /* initialize for quick retry mode */ - retry_wait = LWIP_MIN(PPPOE_DISC_TIMEOUT * sc->sc_padi_retried, PPPOE_SLOW_RETRY); - if ((err = pppoe_send_padi(sc)) != 0) { - sc->sc_padi_retried--; - PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": failed to transmit PADI, error=%d\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, err)); - } - sys_timeout(retry_wait, pppoe_timeout, sc); - break; - - case PPPOE_STATE_PADR_SENT: - sc->sc_padr_retried++; - if (sc->sc_padr_retried >= PPPOE_DISC_MAXPADR) { - MEMCPY(&sc->sc_dest, ethbroadcast.addr, sizeof(sc->sc_dest)); - sc->sc_state = PPPOE_STATE_PADI_SENT; - sc->sc_padr_retried = 0; - if ((err = pppoe_send_padi(sc)) != 0) { - PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": failed to send PADI, error=%d\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, err)); - } - sys_timeout(PPPOE_DISC_TIMEOUT * (1 + sc->sc_padi_retried), pppoe_timeout, sc); - return; - } - if ((err = pppoe_send_padr(sc)) != 0) { - sc->sc_padr_retried--; - PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": failed to send PADR, error=%d\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, err)); - } - sys_timeout(PPPOE_DISC_TIMEOUT * (1 + sc->sc_padr_retried), pppoe_timeout, sc); - break; - default: - return; /* all done, work in peace */ - } -} - -/* Start a connection (i.e. initiate discovery phase) */ -static void -pppoe_connect(ppp_pcb *ppp, void *ctx) -{ - err_t err; - struct pppoe_softc *sc = (struct pppoe_softc *)ctx; - lcp_options *lcp_wo; - lcp_options *lcp_ao; -#if PPP_IPV4_SUPPORT && VJ_SUPPORT - ipcp_options *ipcp_wo; - ipcp_options *ipcp_ao; -#endif /* PPP_IPV4_SUPPORT && VJ_SUPPORT */ - - sc->sc_session = 0; - sc->sc_ac_cookie_len = 0; - sc->sc_padi_retried = 0; - sc->sc_padr_retried = 0; - /* changed to real address later */ - MEMCPY(&sc->sc_dest, ethbroadcast.addr, sizeof(sc->sc_dest)); -#ifdef PPPOE_SERVER - /* wait PADI if IFF_PASSIVE */ - if ((sc->sc_sppp.pp_if.if_flags & IFF_PASSIVE)) { - return 0; - } -#endif - - lcp_wo = &ppp->lcp_wantoptions; - lcp_wo->mru = sc->sc_ethif->mtu-PPPOE_HEADERLEN-2; /* two byte PPP protocol discriminator, then IP data */ - lcp_wo->neg_asyncmap = 0; - lcp_wo->neg_pcompression = 0; - lcp_wo->neg_accompression = 0; - lcp_wo->passive = 0; - lcp_wo->silent = 0; - - lcp_ao = &ppp->lcp_allowoptions; - lcp_ao->mru = sc->sc_ethif->mtu-PPPOE_HEADERLEN-2; /* two byte PPP protocol discriminator, then IP data */ - lcp_ao->neg_asyncmap = 0; - lcp_ao->neg_pcompression = 0; - lcp_ao->neg_accompression = 0; - -#if PPP_IPV4_SUPPORT && VJ_SUPPORT - ipcp_wo = &ppp->ipcp_wantoptions; - ipcp_wo->neg_vj = 0; - ipcp_wo->old_vj = 0; - - ipcp_ao = &ppp->ipcp_allowoptions; - ipcp_ao->neg_vj = 0; - ipcp_ao->old_vj = 0; -#endif /* PPP_IPV4_SUPPORT && VJ_SUPPORT */ - - /* save state, in case we fail to send PADI */ - sc->sc_state = PPPOE_STATE_PADI_SENT; - if ((err = pppoe_send_padi(sc)) != 0) { - PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": failed to send PADI, error=%d\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, err)); - } - sys_timeout(PPPOE_DISC_TIMEOUT, pppoe_timeout, sc); -} - -/* disconnect */ -static void -pppoe_disconnect(ppp_pcb *ppp, void *ctx) -{ - struct pppoe_softc *sc = (struct pppoe_softc *)ctx; - - PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": disconnecting\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num)); - if (sc->sc_state == PPPOE_STATE_SESSION) { - pppoe_send_padt(sc->sc_ethif, sc->sc_session, (const u8_t *)&sc->sc_dest); - } - - /* stop any timer, disconnect can be called while initiating is in progress */ - sys_untimeout(pppoe_timeout, sc); - sc->sc_state = PPPOE_STATE_INITIAL; -#ifdef PPPOE_SERVER - if (sc->sc_hunique) { - mem_free(sc->sc_hunique); - sc->sc_hunique = NULL; /* probably not necessary, if state is initial we shouldn't have to access hunique anyway */ - } - sc->sc_hunique_len = 0; /* probably not necessary, if state is initial we shouldn't have to access hunique anyway */ -#endif - ppp_link_end(ppp); /* notify upper layers */ - return; -} - -/* Connection attempt aborted */ -static void -pppoe_abort_connect(struct pppoe_softc *sc) -{ - PPPDEBUG(LOG_DEBUG, ("%c%c%"U16_F": could not establish connection\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num)); - sc->sc_state = PPPOE_STATE_INITIAL; - ppp_link_failed(sc->pcb); /* notify upper layers */ -} - -/* Send a PADR packet */ -static err_t -pppoe_send_padr(struct pppoe_softc *sc) -{ - struct pbuf *pb; - u8_t *p; - size_t len; -#ifdef PPPOE_TODO - size_t l1 = 0; /* XXX: gcc */ -#endif /* PPPOE_TODO */ - - len = 2 + 2 + 2 + 2 + sizeof(sc); /* service name, host unique */ -#ifdef PPPOE_TODO - if (sc->sc_service_name != NULL) { /* service name tag maybe empty */ - l1 = strlen(sc->sc_service_name); - len += l1; - } -#endif /* PPPOE_TODO */ - if (sc->sc_ac_cookie_len > 0) { - len += 2 + 2 + sc->sc_ac_cookie_len; /* AC cookie */ - } - LWIP_ASSERT("sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len <= 0xffff", - sizeof(struct eth_hdr) + PPPOE_HEADERLEN + len <= 0xffff); - pb = pbuf_alloc(PBUF_LINK, (u16_t)(PPPOE_HEADERLEN + len), PBUF_RAM); - if (!pb) { - return ERR_MEM; - } - LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len); - p = (u8_t*)pb->payload; - PPPOE_ADD_HEADER(p, PPPOE_CODE_PADR, 0, len); - PPPOE_ADD_16(p, PPPOE_TAG_SNAME); -#ifdef PPPOE_TODO - if (sc->sc_service_name != NULL) { - PPPOE_ADD_16(p, l1); - MEMCPY(p, sc->sc_service_name, l1); - p += l1; - } else -#endif /* PPPOE_TODO */ - { - PPPOE_ADD_16(p, 0); - } - if (sc->sc_ac_cookie_len > 0) { - PPPOE_ADD_16(p, PPPOE_TAG_ACCOOKIE); - PPPOE_ADD_16(p, sc->sc_ac_cookie_len); - MEMCPY(p, sc->sc_ac_cookie, sc->sc_ac_cookie_len); - p += sc->sc_ac_cookie_len; - } - PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE); - PPPOE_ADD_16(p, sizeof(sc)); - MEMCPY(p, &sc, sizeof sc); - - return pppoe_output(sc, pb); -} - -/* send a PADT packet */ -static err_t -pppoe_send_padt(struct netif *outgoing_if, u_int session, const u8_t *dest) -{ - struct pbuf *pb; - struct eth_hdr *ethhdr; - err_t res; - u8_t *p; - - pb = pbuf_alloc(PBUF_LINK, (u16_t)(PPPOE_HEADERLEN), PBUF_RAM); - if (!pb) { - return ERR_MEM; - } - LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len); - - pbuf_header(pb, (s16_t)sizeof(struct eth_hdr)); - ethhdr = (struct eth_hdr *)pb->payload; - ethhdr->type = PP_HTONS(ETHTYPE_PPPOEDISC); - MEMCPY(ðhdr->dest.addr, dest, sizeof(ethhdr->dest.addr)); - MEMCPY(ðhdr->src.addr, &outgoing_if->hwaddr, sizeof(ethhdr->src.addr)); - - p = (u8_t*)(ethhdr + 1); - PPPOE_ADD_HEADER(p, PPPOE_CODE_PADT, session, 0); - - res = outgoing_if->linkoutput(outgoing_if, pb); - - pbuf_free(pb); - - return res; -} - -#ifdef PPPOE_SERVER -static err_t -pppoe_send_pado(struct pppoe_softc *sc) -{ - struct pbuf *pb; - u8_t *p; - size_t len; - - /* calc length */ - len = 0; - /* include ac_cookie */ - len += 2 + 2 + sizeof(sc); - /* include hunique */ - len += 2 + 2 + sc->sc_hunique_len; - pb = pbuf_alloc(PBUF_LINK, (u16_t)(PPPOE_HEADERLEN + len), PBUF_RAM); - if (!pb) { - return ERR_MEM; - } - LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len); - p = (u8_t*)pb->payload; - PPPOE_ADD_HEADER(p, PPPOE_CODE_PADO, 0, len); - PPPOE_ADD_16(p, PPPOE_TAG_ACCOOKIE); - PPPOE_ADD_16(p, sizeof(sc)); - MEMCPY(p, &sc, sizeof(sc)); - p += sizeof(sc); - PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE); - PPPOE_ADD_16(p, sc->sc_hunique_len); - MEMCPY(p, sc->sc_hunique, sc->sc_hunique_len); - return pppoe_output(sc, pb); -} - -static err_t -pppoe_send_pads(struct pppoe_softc *sc) -{ - struct pbuf *pb; - u8_t *p; - size_t len, l1 = 0; /* XXX: gcc */ - - sc->sc_session = mono_time.tv_sec % 0xff + 1; - /* calc length */ - len = 0; - /* include hunique */ - len += 2 + 2 + 2 + 2 + sc->sc_hunique_len; /* service name, host unique*/ - if (sc->sc_service_name != NULL) { /* service name tag maybe empty */ - l1 = strlen(sc->sc_service_name); - len += l1; - } - pb = pbuf_alloc(PBUF_LINK, (u16_t)(PPPOE_HEADERLEN + len), PBUF_RAM); - if (!pb) { - return ERR_MEM; - } - LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len); - p = (u8_t*)pb->payload; - PPPOE_ADD_HEADER(p, PPPOE_CODE_PADS, sc->sc_session, len); - PPPOE_ADD_16(p, PPPOE_TAG_SNAME); - if (sc->sc_service_name != NULL) { - PPPOE_ADD_16(p, l1); - MEMCPY(p, sc->sc_service_name, l1); - p += l1; - } else { - PPPOE_ADD_16(p, 0); - } - PPPOE_ADD_16(p, PPPOE_TAG_HUNIQUE); - PPPOE_ADD_16(p, sc->sc_hunique_len); - MEMCPY(p, sc->sc_hunique, sc->sc_hunique_len); - return pppoe_output(sc, pb); -} -#endif - -static err_t -pppoe_xmit(struct pppoe_softc *sc, struct pbuf *pb) -{ - u8_t *p; - size_t len; - - len = pb->tot_len; - - /* make room for PPPoE header - should not fail */ - if (pbuf_header(pb, (s16_t)(PPPOE_HEADERLEN)) != 0) { - /* bail out */ - PPPDEBUG(LOG_ERR, ("pppoe: %c%c%"U16_F": pppoe_xmit: could not allocate room for PPPoE header\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num)); - LINK_STATS_INC(link.lenerr); - pbuf_free(pb); - return ERR_BUF; - } - - p = (u8_t*)pb->payload; - PPPOE_ADD_HEADER(p, 0, sc->sc_session, len); - - return pppoe_output(sc, pb); -} - -#if 0 /*def PFIL_HOOKS*/ -static int -pppoe_ifattach_hook(void *arg, struct pbuf **mp, struct netif *ifp, int dir) -{ - struct pppoe_softc *sc; - int s; - - if (mp != (struct pbuf **)PFIL_IFNET_DETACH) { - return 0; - } - - LIST_FOREACH(sc, &pppoe_softc_list, sc_list) { - if (sc->sc_ethif != ifp) { - continue; - } - if (sc->sc_sppp.pp_if.if_flags & IFF_UP) { - sc->sc_sppp.pp_if.if_flags &= ~(IFF_UP|IFF_RUNNING); - PPPDEBUG(LOG_DEBUG, ("%c%c%"U16_F": ethernet interface detached, going down\n", - sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num)); - } - sc->sc_ethif = NULL; - pppoe_clear_softc(sc, "ethernet interface detached"); - } - - return 0; -} -#endif - -#if 0 /* UNUSED */ -static void -pppoe_clear_softc(struct pppoe_softc *sc, const char *message) -{ - LWIP_UNUSED_ARG(message); - - /* stop timer */ - sys_untimeout(pppoe_timeout, sc); - PPPDEBUG(LOG_DEBUG, ("pppoe: %c%c%"U16_F": session 0x%x terminated, %s\n", sc->sc_ethif->name[0], sc->sc_ethif->name[1], sc->sc_ethif->num, sc->sc_session, message)); - sc->sc_state = PPPOE_STATE_INITIAL; - ppp_link_end(sc->pcb); /* notify upper layers - /!\ dangerous /!\ - see pppoe_disc_input() */ -} -#endif /* UNUSED */ -#endif /* PPP_SUPPORT && PPPOE_SUPPORT */ diff --git a/third_party/lwip/repo/lwip/src/netif/ppp/pppol2tp.c b/third_party/lwip/repo/lwip/src/netif/ppp/pppol2tp.c deleted file mode 100644 index d44471e25f9e96..00000000000000 --- a/third_party/lwip/repo/lwip/src/netif/ppp/pppol2tp.c +++ /dev/null @@ -1,1131 +0,0 @@ -/** - * @file - * Network Point to Point Protocol over Layer 2 Tunneling Protocol program file. - * - */ - -/* - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - */ - -/* - * L2TP Support status: - * - * Supported: - * - L2TPv2 (PPP over L2TP, a.k.a. UDP tunnels) - * - LAC - * - * Not supported: - * - LNS (require PPP server support) - * - L2TPv3 ethernet pseudowires - * - L2TPv3 VLAN pseudowire - * - L2TPv3 PPP pseudowires - * - L2TPv3 IP encapsulation - * - L2TPv3 IP pseudowire - * - L2TP tunnel switching - http://tools.ietf.org/html/draft-ietf-l2tpext-tunnel-switching-08 - * - Multiple tunnels per UDP socket, as well as multiple sessions per tunnel - * - Hidden AVPs - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT && PPPOL2TP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#include "lwip/err.h" -#include "lwip/memp.h" -#include "lwip/netif.h" -#include "lwip/udp.h" -#include "lwip/snmp.h" - -#include "netif/ppp/ppp_impl.h" -#include "netif/ppp/lcp.h" -#include "netif/ppp/ipcp.h" -#include "netif/ppp/pppol2tp.h" -#include "netif/ppp/pppcrypt.h" -#include "netif/ppp/magic.h" - -/* Memory pool */ -LWIP_MEMPOOL_DECLARE(PPPOL2TP_PCB, MEMP_NUM_PPPOL2TP_INTERFACES, sizeof(pppol2tp_pcb), "PPPOL2TP_PCB") - -/* callbacks called from PPP core */ -static err_t pppol2tp_write(ppp_pcb *ppp, void *ctx, struct pbuf *p); -static err_t pppol2tp_netif_output(ppp_pcb *ppp, void *ctx, struct pbuf *p, u_short protocol); -static err_t pppol2tp_destroy(ppp_pcb *ppp, void *ctx); /* Destroy a L2TP control block */ -static void pppol2tp_connect(ppp_pcb *ppp, void *ctx); /* Be a LAC, connect to a LNS. */ -static void pppol2tp_disconnect(ppp_pcb *ppp, void *ctx); /* Disconnect */ - - /* Prototypes for procedures local to this file. */ -static void pppol2tp_input(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port); -static void pppol2tp_dispatch_control_packet(pppol2tp_pcb *l2tp, u16_t port, struct pbuf *p, u16_t ns, u16_t nr); -static void pppol2tp_timeout(void *arg); -static void pppol2tp_abort_connect(pppol2tp_pcb *l2tp); -static err_t pppol2tp_send_sccrq(pppol2tp_pcb *l2tp); -static err_t pppol2tp_send_scccn(pppol2tp_pcb *l2tp, u16_t ns); -static err_t pppol2tp_send_icrq(pppol2tp_pcb *l2tp, u16_t ns); -static err_t pppol2tp_send_iccn(pppol2tp_pcb *l2tp, u16_t ns); -static err_t pppol2tp_send_zlb(pppol2tp_pcb *l2tp, u16_t ns); -static err_t pppol2tp_send_stopccn(pppol2tp_pcb *l2tp, u16_t ns); -static err_t pppol2tp_xmit(pppol2tp_pcb *l2tp, struct pbuf *pb); -static err_t pppol2tp_udp_send(pppol2tp_pcb *l2tp, struct pbuf *pb); - -/* Callbacks structure for PPP core */ -static const struct link_callbacks pppol2tp_callbacks = { - pppol2tp_connect, -#if PPP_SERVER - NULL, -#endif /* PPP_SERVER */ - pppol2tp_disconnect, - pppol2tp_destroy, - pppol2tp_write, - pppol2tp_netif_output, - NULL, - NULL -}; - - -/* Create a new L2TP session. */ -ppp_pcb *pppol2tp_create(struct netif *pppif, - struct netif *netif, const ip_addr_t *ipaddr, u16_t port, - const u8_t *secret, u8_t secret_len, - ppp_link_status_cb_fn link_status_cb, void *ctx_cb) { - ppp_pcb *ppp; - pppol2tp_pcb *l2tp; - struct udp_pcb *udp; -#if !PPPOL2TP_AUTH_SUPPORT - LWIP_UNUSED_ARG(secret); - LWIP_UNUSED_ARG(secret_len); -#endif /* !PPPOL2TP_AUTH_SUPPORT */ - - if (ipaddr == NULL) { - goto ipaddr_check_failed; - } - - l2tp = (pppol2tp_pcb *)LWIP_MEMPOOL_ALLOC(PPPOL2TP_PCB); - if (l2tp == NULL) { - goto memp_malloc_l2tp_failed; - } - - udp = udp_new_ip_type(IP_GET_TYPE(ipaddr)); - if (udp == NULL) { - goto udp_new_failed; - } - udp_recv(udp, pppol2tp_input, l2tp); - - ppp = ppp_new(pppif, &pppol2tp_callbacks, l2tp, link_status_cb, ctx_cb); - if (ppp == NULL) { - goto ppp_new_failed; - } - - memset(l2tp, 0, sizeof(pppol2tp_pcb)); - l2tp->phase = PPPOL2TP_STATE_INITIAL; - l2tp->ppp = ppp; - l2tp->udp = udp; - l2tp->netif = netif; - ip_addr_copy(l2tp->remote_ip, *ipaddr); - l2tp->remote_port = port; -#if PPPOL2TP_AUTH_SUPPORT - l2tp->secret = secret; - l2tp->secret_len = secret_len; -#endif /* PPPOL2TP_AUTH_SUPPORT */ - - return ppp; - -ppp_new_failed: - udp_remove(udp); -udp_new_failed: - LWIP_MEMPOOL_FREE(PPPOL2TP_PCB, l2tp); -memp_malloc_l2tp_failed: -ipaddr_check_failed: - return NULL; -} - -/* Called by PPP core */ -static err_t pppol2tp_write(ppp_pcb *ppp, void *ctx, struct pbuf *p) { - pppol2tp_pcb *l2tp = (pppol2tp_pcb *)ctx; - struct pbuf *ph; /* UDP + L2TP header */ - err_t ret; -#if MIB2_STATS - u16_t tot_len; -#else /* MIB2_STATS */ - LWIP_UNUSED_ARG(ppp); -#endif /* MIB2_STATS */ - - ph = pbuf_alloc(PBUF_TRANSPORT, (u16_t)(PPPOL2TP_OUTPUT_DATA_HEADER_LEN), PBUF_RAM); - if(!ph) { - LINK_STATS_INC(link.memerr); - LINK_STATS_INC(link.proterr); - MIB2_STATS_NETIF_INC(ppp->netif, ifoutdiscards); - pbuf_free(p); - return ERR_MEM; - } - - pbuf_header(ph, -(s16_t)PPPOL2TP_OUTPUT_DATA_HEADER_LEN); /* hide L2TP header */ - pbuf_cat(ph, p); -#if MIB2_STATS - tot_len = ph->tot_len; -#endif /* MIB2_STATS */ - - ret = pppol2tp_xmit(l2tp, ph); - if (ret != ERR_OK) { - LINK_STATS_INC(link.err); - MIB2_STATS_NETIF_INC(ppp->netif, ifoutdiscards); - return ret; - } - - MIB2_STATS_NETIF_ADD(ppp->netif, ifoutoctets, (u16_t)tot_len); - MIB2_STATS_NETIF_INC(ppp->netif, ifoutucastpkts); - LINK_STATS_INC(link.xmit); - return ERR_OK; -} - -/* Called by PPP core */ -static err_t pppol2tp_netif_output(ppp_pcb *ppp, void *ctx, struct pbuf *p, u_short protocol) { - pppol2tp_pcb *l2tp = (pppol2tp_pcb *)ctx; - struct pbuf *pb; - u8_t *pl; - err_t err; -#if MIB2_STATS - u16_t tot_len; -#else /* MIB2_STATS */ - LWIP_UNUSED_ARG(ppp); -#endif /* MIB2_STATS */ - - /* @todo: try to use pbuf_header() here! */ - pb = pbuf_alloc(PBUF_TRANSPORT, PPPOL2TP_OUTPUT_DATA_HEADER_LEN + sizeof(protocol), PBUF_RAM); - if(!pb) { - LINK_STATS_INC(link.memerr); - LINK_STATS_INC(link.proterr); - MIB2_STATS_NETIF_INC(ppp->netif, ifoutdiscards); - return ERR_MEM; - } - - pbuf_header(pb, -(s16_t)PPPOL2TP_OUTPUT_DATA_HEADER_LEN); - - pl = (u8_t*)pb->payload; - PUTSHORT(protocol, pl); - - pbuf_chain(pb, p); -#if MIB2_STATS - tot_len = pb->tot_len; -#endif /* MIB2_STATS */ - - if( (err = pppol2tp_xmit(l2tp, pb)) != ERR_OK) { - LINK_STATS_INC(link.err); - MIB2_STATS_NETIF_INC(ppp->netif, ifoutdiscards); - return err; - } - - MIB2_STATS_NETIF_ADD(ppp->netif, ifoutoctets, tot_len); - MIB2_STATS_NETIF_INC(ppp->netif, ifoutucastpkts); - LINK_STATS_INC(link.xmit); - return ERR_OK; -} - -/* Destroy a L2TP control block */ -static err_t pppol2tp_destroy(ppp_pcb *ppp, void *ctx) { - pppol2tp_pcb *l2tp = (pppol2tp_pcb *)ctx; - LWIP_UNUSED_ARG(ppp); - - sys_untimeout(pppol2tp_timeout, l2tp); - udp_remove(l2tp->udp); - LWIP_MEMPOOL_FREE(PPPOL2TP_PCB, l2tp); - return ERR_OK; -} - -/* Be a LAC, connect to a LNS. */ -static void pppol2tp_connect(ppp_pcb *ppp, void *ctx) { - err_t err; - pppol2tp_pcb *l2tp = (pppol2tp_pcb *)ctx; - lcp_options *lcp_wo; - lcp_options *lcp_ao; -#if PPP_IPV4_SUPPORT && VJ_SUPPORT - ipcp_options *ipcp_wo; - ipcp_options *ipcp_ao; -#endif /* PPP_IPV4_SUPPORT && VJ_SUPPORT */ - - l2tp->tunnel_port = l2tp->remote_port; - l2tp->our_ns = 0; - l2tp->peer_nr = 0; - l2tp->peer_ns = 0; - l2tp->source_tunnel_id = 0; - l2tp->remote_tunnel_id = 0; - l2tp->source_session_id = 0; - l2tp->remote_session_id = 0; - /* l2tp->*_retried are cleared when used */ - - lcp_wo = &ppp->lcp_wantoptions; - lcp_wo->mru = PPPOL2TP_DEFMRU; - lcp_wo->neg_asyncmap = 0; - lcp_wo->neg_pcompression = 0; - lcp_wo->neg_accompression = 0; - lcp_wo->passive = 0; - lcp_wo->silent = 0; - - lcp_ao = &ppp->lcp_allowoptions; - lcp_ao->mru = PPPOL2TP_DEFMRU; - lcp_ao->neg_asyncmap = 0; - lcp_ao->neg_pcompression = 0; - lcp_ao->neg_accompression = 0; - -#if PPP_IPV4_SUPPORT && VJ_SUPPORT - ipcp_wo = &ppp->ipcp_wantoptions; - ipcp_wo->neg_vj = 0; - ipcp_wo->old_vj = 0; - - ipcp_ao = &ppp->ipcp_allowoptions; - ipcp_ao->neg_vj = 0; - ipcp_ao->old_vj = 0; -#endif /* PPP_IPV4_SUPPORT && VJ_SUPPORT */ - - /* Listen to a random source port, we need to do that instead of using udp_connect() - * because the L2TP LNS might answer with its own random source port (!= 1701) - */ -#if LWIP_IPV6 - if (IP_IS_V6_VAL(l2tp->udp->local_ip)) { - udp_bind(l2tp->udp, IP6_ADDR_ANY, 0); - } else -#endif /* LWIP_IPV6 */ - udp_bind(l2tp->udp, IP_ADDR_ANY, 0); - -#if PPPOL2TP_AUTH_SUPPORT - /* Generate random vector */ - if (l2tp->secret != NULL) { - magic_random_bytes(l2tp->secret_rv, sizeof(l2tp->secret_rv)); - } -#endif /* PPPOL2TP_AUTH_SUPPORT */ - - do { - l2tp->remote_tunnel_id = magic(); - } while(l2tp->remote_tunnel_id == 0); - /* save state, in case we fail to send SCCRQ */ - l2tp->sccrq_retried = 0; - l2tp->phase = PPPOL2TP_STATE_SCCRQ_SENT; - if ((err = pppol2tp_send_sccrq(l2tp)) != 0) { - PPPDEBUG(LOG_DEBUG, ("pppol2tp: failed to send SCCRQ, error=%d\n", err)); - } - sys_timeout(PPPOL2TP_CONTROL_TIMEOUT, pppol2tp_timeout, l2tp); -} - -/* Disconnect */ -static void pppol2tp_disconnect(ppp_pcb *ppp, void *ctx) { - pppol2tp_pcb *l2tp = (pppol2tp_pcb *)ctx; - - l2tp->our_ns++; - pppol2tp_send_stopccn(l2tp, l2tp->our_ns); - - /* stop any timer, disconnect can be called while initiating is in progress */ - sys_untimeout(pppol2tp_timeout, l2tp); - l2tp->phase = PPPOL2TP_STATE_INITIAL; - ppp_link_end(ppp); /* notify upper layers */ -} - -/* UDP Callback for incoming IPv4 L2TP frames */ -static void pppol2tp_input(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *addr, u16_t port) { - pppol2tp_pcb *l2tp = (pppol2tp_pcb*)arg; - u16_t hflags, hlen, len=0, tunnel_id=0, session_id=0, ns=0, nr=0, offset=0; - u8_t *inp; - LWIP_UNUSED_ARG(pcb); - - /* we can't unbound a UDP pcb, thus we can still receive UDP frames after the link is closed */ - if (l2tp->phase < PPPOL2TP_STATE_SCCRQ_SENT) { - goto free_and_return; - } - - if (!ip_addr_cmp(&l2tp->remote_ip, addr)) { - goto free_and_return; - } - - /* discard packet if port mismatch, but only if we received a SCCRP */ - if (l2tp->phase > PPPOL2TP_STATE_SCCRQ_SENT && l2tp->tunnel_port != port) { - goto free_and_return; - } - - /* printf("-----------\nL2TP INPUT, %d\n", p->len); */ - - /* L2TP header */ - if (p->len < sizeof(hflags) + sizeof(tunnel_id) + sizeof(session_id) ) { - goto packet_too_short; - } - - inp = (u8_t*)p->payload; - GETSHORT(hflags, inp); - - if (hflags & PPPOL2TP_HEADERFLAG_CONTROL) { - /* check mandatory flags for a control packet */ - if ( (hflags & PPPOL2TP_HEADERFLAG_CONTROL_MANDATORY) != PPPOL2TP_HEADERFLAG_CONTROL_MANDATORY ) { - PPPDEBUG(LOG_DEBUG, ("pppol2tp: mandatory header flags for control packet not set\n")); - goto free_and_return; - } - /* check forbidden flags for a control packet */ - if (hflags & PPPOL2TP_HEADERFLAG_CONTROL_FORBIDDEN) { - PPPDEBUG(LOG_DEBUG, ("pppol2tp: forbidden header flags for control packet found\n")); - goto free_and_return; - } - } else { - /* check mandatory flags for a data packet */ - if ( (hflags & PPPOL2TP_HEADERFLAG_DATA_MANDATORY) != PPPOL2TP_HEADERFLAG_DATA_MANDATORY) { - PPPDEBUG(LOG_DEBUG, ("pppol2tp: mandatory header flags for data packet not set\n")); - goto free_and_return; - } - } - - /* Expected header size */ - hlen = sizeof(hflags) + sizeof(tunnel_id) + sizeof(session_id); - if (hflags & PPPOL2TP_HEADERFLAG_LENGTH) { - hlen += sizeof(len); - } - if (hflags & PPPOL2TP_HEADERFLAG_SEQUENCE) { - hlen += sizeof(ns) + sizeof(nr); - } - if (hflags & PPPOL2TP_HEADERFLAG_OFFSET) { - hlen += sizeof(offset); - } - if (p->len < hlen) { - goto packet_too_short; - } - - if (hflags & PPPOL2TP_HEADERFLAG_LENGTH) { - GETSHORT(len, inp); - if (p->len < len || len < hlen) { - goto packet_too_short; - } - } - GETSHORT(tunnel_id, inp); - GETSHORT(session_id, inp); - if (hflags & PPPOL2TP_HEADERFLAG_SEQUENCE) { - GETSHORT(ns, inp); - GETSHORT(nr, inp); - } - if (hflags & PPPOL2TP_HEADERFLAG_OFFSET) { - GETSHORT(offset, inp) - if (offset > 4096) { /* don't be fooled with large offset which might overflow hlen */ - PPPDEBUG(LOG_DEBUG, ("pppol2tp: strange packet received, offset=%d\n", offset)); - goto free_and_return; - } - hlen += offset; - if (p->len < hlen) { - goto packet_too_short; - } - INCPTR(offset, inp); - } - - /* printf("HLEN = %d\n", hlen); */ - - /* skip L2TP header */ - if (pbuf_header(p, -(s16_t)hlen) != 0) { - goto free_and_return; - } - - /* printf("LEN=%d, TUNNEL_ID=%d, SESSION_ID=%d, NS=%d, NR=%d, OFFSET=%d\n", len, tunnel_id, session_id, ns, nr, offset); */ - PPPDEBUG(LOG_DEBUG, ("pppol2tp: input packet, len=%"U16_F", tunnel=%"U16_F", session=%"U16_F", ns=%"U16_F", nr=%"U16_F"\n", - len, tunnel_id, session_id, ns, nr)); - - /* Control packet */ - if (hflags & PPPOL2TP_HEADERFLAG_CONTROL) { - pppol2tp_dispatch_control_packet(l2tp, port, p, ns, nr); - goto free_and_return; - } - - /* Data packet */ - if(l2tp->phase != PPPOL2TP_STATE_DATA) { - goto free_and_return; - } - if(tunnel_id != l2tp->remote_tunnel_id) { - PPPDEBUG(LOG_DEBUG, ("pppol2tp: tunnel ID mismatch, assigned=%d, received=%d\n", l2tp->remote_tunnel_id, tunnel_id)); - goto free_and_return; - } - if(session_id != l2tp->remote_session_id) { - PPPDEBUG(LOG_DEBUG, ("pppol2tp: session ID mismatch, assigned=%d, received=%d\n", l2tp->remote_session_id, session_id)); - goto free_and_return; - } - /* - * skip address & flags if necessary - * - * RFC 2661 does not specify whether the PPP frame in the L2TP payload should - * have a HDLC header or not. We handle both cases for compatibility. - */ - if (p->len >= 2) { - GETSHORT(hflags, inp); - if (hflags == 0xff03) { - pbuf_header(p, -(s16_t)2); - } - } - /* Dispatch the packet thereby consuming it. */ - ppp_input(l2tp->ppp, p); - return; - -packet_too_short: - PPPDEBUG(LOG_DEBUG, ("pppol2tp: packet too short: %d\n", p->len)); -free_and_return: - pbuf_free(p); -} - -/* L2TP Control packet entry point */ -static void pppol2tp_dispatch_control_packet(pppol2tp_pcb *l2tp, u16_t port, struct pbuf *p, u16_t ns, u16_t nr) { - u8_t *inp; - u16_t avplen, avpflags, vendorid, attributetype, messagetype=0; - err_t err; -#if PPPOL2TP_AUTH_SUPPORT - lwip_md5_context md5_ctx; - u8_t md5_hash[16]; - u8_t challenge_id = 0; -#endif /* PPPOL2TP_AUTH_SUPPORT */ - - l2tp->peer_nr = nr; - l2tp->peer_ns = ns; - /* printf("L2TP CTRL INPUT, ns=%d, nr=%d, len=%d\n", ns, nr, p->len); */ - - /* Handle the special case of the ICCN acknowledge */ - if (l2tp->phase == PPPOL2TP_STATE_ICCN_SENT && l2tp->peer_nr > l2tp->our_ns) { - l2tp->phase = PPPOL2TP_STATE_DATA; - } - - /* ZLB packets */ - if (p->tot_len == 0) { - return; - } - - p = ppp_singlebuf(p); - inp = (u8_t*)p->payload; - /* Decode AVPs */ - while (p->len > 0) { - if (p->len < sizeof(avpflags) + sizeof(vendorid) + sizeof(attributetype) ) { - goto packet_too_short; - } - GETSHORT(avpflags, inp); - avplen = avpflags & PPPOL2TP_AVPHEADERFLAG_LENGTHMASK; - /* printf("AVPLEN = %d\n", avplen); */ - if (p->len < avplen || avplen < sizeof(avpflags) + sizeof(vendorid) + sizeof(attributetype)) { - goto packet_too_short; - } - GETSHORT(vendorid, inp); - GETSHORT(attributetype, inp); - avplen -= sizeof(avpflags) + sizeof(vendorid) + sizeof(attributetype); - - /* Message type must be the first AVP */ - if (messagetype == 0) { - if (attributetype != 0 || vendorid != 0 || avplen != sizeof(messagetype) ) { - PPPDEBUG(LOG_DEBUG, ("pppol2tp: message type must be the first AVP\n")); - return; - } - GETSHORT(messagetype, inp); - /* printf("Message type = %d\n", messagetype); */ - switch(messagetype) { - /* Start Control Connection Reply */ - case PPPOL2TP_MESSAGETYPE_SCCRP: - /* Only accept SCCRP packet if we sent a SCCRQ */ - if (l2tp->phase != PPPOL2TP_STATE_SCCRQ_SENT) { - goto send_zlb; - } - break; - /* Incoming Call Reply */ - case PPPOL2TP_MESSAGETYPE_ICRP: - /* Only accept ICRP packet if we sent a IRCQ */ - if (l2tp->phase != PPPOL2TP_STATE_ICRQ_SENT) { - goto send_zlb; - } - break; - /* Stop Control Connection Notification */ - case PPPOL2TP_MESSAGETYPE_STOPCCN: - pppol2tp_send_zlb(l2tp, l2tp->our_ns); /* Ack the StopCCN before we switch to down state */ - if (l2tp->phase < PPPOL2TP_STATE_DATA) { - pppol2tp_abort_connect(l2tp); - } else if (l2tp->phase == PPPOL2TP_STATE_DATA) { - /* Don't disconnect here, we let the LCP Echo/Reply find the fact - * that PPP session is down. Asking the PPP stack to end the session - * require strict checking about the PPP phase to prevent endless - * disconnection loops. - */ - } - return; - default: - break; - } - goto nextavp; - } - - /* Skip proprietary L2TP extensions */ - if (vendorid != 0) { - goto skipavp; - } - - switch (messagetype) { - /* Start Control Connection Reply */ - case PPPOL2TP_MESSAGETYPE_SCCRP: - switch (attributetype) { - case PPPOL2TP_AVPTYPE_TUNNELID: - if (avplen != sizeof(l2tp->source_tunnel_id) ) { - PPPDEBUG(LOG_DEBUG, ("pppol2tp: AVP Assign tunnel ID length check failed\n")); - return; - } - GETSHORT(l2tp->source_tunnel_id, inp); - PPPDEBUG(LOG_DEBUG, ("pppol2tp: Assigned tunnel ID %"U16_F"\n", l2tp->source_tunnel_id)); - goto nextavp; -#if PPPOL2TP_AUTH_SUPPORT - case PPPOL2TP_AVPTYPE_CHALLENGE: - if (avplen == 0) { - PPPDEBUG(LOG_DEBUG, ("pppol2tp: Challenge length check failed\n")); - return; - } - if (l2tp->secret == NULL) { - PPPDEBUG(LOG_DEBUG, ("pppol2tp: Received challenge from peer and no secret key available\n")); - pppol2tp_abort_connect(l2tp); - return; - } - /* Generate hash of ID, secret, challenge */ - lwip_md5_init(&md5_ctx); - lwip_md5_starts(&md5_ctx); - challenge_id = PPPOL2TP_MESSAGETYPE_SCCCN; - lwip_md5_update(&md5_ctx, &challenge_id, 1); - lwip_md5_update(&md5_ctx, l2tp->secret, l2tp->secret_len); - lwip_md5_update(&md5_ctx, inp, avplen); - lwip_md5_finish(&md5_ctx, l2tp->challenge_hash); - lwip_md5_free(&md5_ctx); - l2tp->send_challenge = 1; - goto skipavp; - case PPPOL2TP_AVPTYPE_CHALLENGERESPONSE: - if (avplen != PPPOL2TP_AVPTYPE_CHALLENGERESPONSE_SIZE) { - PPPDEBUG(LOG_DEBUG, ("pppol2tp: AVP Challenge Response length check failed\n")); - return; - } - /* Generate hash of ID, secret, challenge */ - lwip_md5_init(&md5_ctx); - lwip_md5_starts(&md5_ctx); - challenge_id = PPPOL2TP_MESSAGETYPE_SCCRP; - lwip_md5_update(&md5_ctx, &challenge_id, 1); - lwip_md5_update(&md5_ctx, l2tp->secret, l2tp->secret_len); - lwip_md5_update(&md5_ctx, l2tp->secret_rv, sizeof(l2tp->secret_rv)); - lwip_md5_finish(&md5_ctx, md5_hash); - lwip_md5_free(&md5_ctx); - if ( memcmp(inp, md5_hash, sizeof(md5_hash)) ) { - PPPDEBUG(LOG_DEBUG, ("pppol2tp: Received challenge response from peer and secret key do not match\n")); - pppol2tp_abort_connect(l2tp); - return; - } - goto skipavp; -#endif /* PPPOL2TP_AUTH_SUPPORT */ - default: - break; - } - break; - /* Incoming Call Reply */ - case PPPOL2TP_MESSAGETYPE_ICRP: - switch (attributetype) { - case PPPOL2TP_AVPTYPE_SESSIONID: - if (avplen != sizeof(l2tp->source_session_id) ) { - PPPDEBUG(LOG_DEBUG, ("pppol2tp: AVP Assign session ID length check failed\n")); - return; - } - GETSHORT(l2tp->source_session_id, inp); - PPPDEBUG(LOG_DEBUG, ("pppol2tp: Assigned session ID %"U16_F"\n", l2tp->source_session_id)); - goto nextavp; - default: - break; - } - break; - default: - break; - } - -skipavp: - INCPTR(avplen, inp); -nextavp: - /* printf("AVP Found, vendor=%d, attribute=%d, len=%d\n", vendorid, attributetype, avplen); */ - /* next AVP */ - if (pbuf_header(p, -(s16_t)(avplen + sizeof(avpflags) + sizeof(vendorid) + sizeof(attributetype)) ) != 0) { - return; - } - } - - switch(messagetype) { - /* Start Control Connection Reply */ - case PPPOL2TP_MESSAGETYPE_SCCRP: - do { - l2tp->remote_session_id = magic(); - } while(l2tp->remote_session_id == 0); - l2tp->tunnel_port = port; /* LNS server might have chosen its own local port */ - l2tp->icrq_retried = 0; - l2tp->phase = PPPOL2TP_STATE_ICRQ_SENT; - l2tp->our_ns++; - if ((err = pppol2tp_send_scccn(l2tp, l2tp->our_ns)) != 0) { - PPPDEBUG(LOG_DEBUG, ("pppol2tp: failed to send SCCCN, error=%d\n", err)); - } - l2tp->our_ns++; - if ((err = pppol2tp_send_icrq(l2tp, l2tp->our_ns)) != 0) { - PPPDEBUG(LOG_DEBUG, ("pppol2tp: failed to send ICRQ, error=%d\n", err)); - } - sys_untimeout(pppol2tp_timeout, l2tp); - sys_timeout(PPPOL2TP_CONTROL_TIMEOUT, pppol2tp_timeout, l2tp); - break; - /* Incoming Call Reply */ - case PPPOL2TP_MESSAGETYPE_ICRP: - l2tp->iccn_retried = 0; - l2tp->phase = PPPOL2TP_STATE_ICCN_SENT; - l2tp->our_ns++; - ppp_start(l2tp->ppp); /* notify upper layers */ - if ((err = pppol2tp_send_iccn(l2tp, l2tp->our_ns)) != 0) { - PPPDEBUG(LOG_DEBUG, ("pppol2tp: failed to send ICCN, error=%d\n", err)); - } - sys_untimeout(pppol2tp_timeout, l2tp); - sys_timeout(PPPOL2TP_CONTROL_TIMEOUT, pppol2tp_timeout, l2tp); - break; - /* Unhandled packet, send ZLB ACK */ - default: - goto send_zlb; - } - return; - -send_zlb: - pppol2tp_send_zlb(l2tp, l2tp->our_ns); - return; -packet_too_short: - PPPDEBUG(LOG_DEBUG, ("pppol2tp: packet too short: %d\n", p->len)); -} - -/* L2TP Timeout handler */ -static void pppol2tp_timeout(void *arg) { - pppol2tp_pcb *l2tp = (pppol2tp_pcb*)arg; - err_t err; - u32_t retry_wait; - - PPPDEBUG(LOG_DEBUG, ("pppol2tp: timeout\n")); - - switch (l2tp->phase) { - case PPPOL2TP_STATE_SCCRQ_SENT: - /* backoff wait */ - if (l2tp->sccrq_retried < 0xff) { - l2tp->sccrq_retried++; - } - if (!l2tp->ppp->settings.persist && l2tp->sccrq_retried >= PPPOL2TP_MAXSCCRQ) { - pppol2tp_abort_connect(l2tp); - return; - } - retry_wait = LWIP_MIN(PPPOL2TP_CONTROL_TIMEOUT * l2tp->sccrq_retried, PPPOL2TP_SLOW_RETRY); - PPPDEBUG(LOG_DEBUG, ("pppol2tp: sccrq_retried=%d\n", l2tp->sccrq_retried)); - if ((err = pppol2tp_send_sccrq(l2tp)) != 0) { - l2tp->sccrq_retried--; - PPPDEBUG(LOG_DEBUG, ("pppol2tp: failed to send SCCRQ, error=%d\n", err)); - } - sys_timeout(retry_wait, pppol2tp_timeout, l2tp); - break; - - case PPPOL2TP_STATE_ICRQ_SENT: - l2tp->icrq_retried++; - if (l2tp->icrq_retried >= PPPOL2TP_MAXICRQ) { - pppol2tp_abort_connect(l2tp); - return; - } - PPPDEBUG(LOG_DEBUG, ("pppol2tp: icrq_retried=%d\n", l2tp->icrq_retried)); - if (l2tp->peer_nr <= l2tp->our_ns -1) { /* the SCCCN was not acknowledged */ - if ((err = pppol2tp_send_scccn(l2tp, l2tp->our_ns -1)) != 0) { - l2tp->icrq_retried--; - PPPDEBUG(LOG_DEBUG, ("pppol2tp: failed to send SCCCN, error=%d\n", err)); - sys_timeout(PPPOL2TP_CONTROL_TIMEOUT, pppol2tp_timeout, l2tp); - break; - } - } - if ((err = pppol2tp_send_icrq(l2tp, l2tp->our_ns)) != 0) { - l2tp->icrq_retried--; - PPPDEBUG(LOG_DEBUG, ("pppol2tp: failed to send ICRQ, error=%d\n", err)); - } - sys_timeout(PPPOL2TP_CONTROL_TIMEOUT, pppol2tp_timeout, l2tp); - break; - - case PPPOL2TP_STATE_ICCN_SENT: - l2tp->iccn_retried++; - if (l2tp->iccn_retried >= PPPOL2TP_MAXICCN) { - pppol2tp_abort_connect(l2tp); - return; - } - PPPDEBUG(LOG_DEBUG, ("pppol2tp: iccn_retried=%d\n", l2tp->iccn_retried)); - if ((err = pppol2tp_send_iccn(l2tp, l2tp->our_ns)) != 0) { - l2tp->iccn_retried--; - PPPDEBUG(LOG_DEBUG, ("pppol2tp: failed to send ICCN, error=%d\n", err)); - } - sys_timeout(PPPOL2TP_CONTROL_TIMEOUT, pppol2tp_timeout, l2tp); - break; - - default: - return; /* all done, work in peace */ - } -} - -/* Connection attempt aborted */ -static void pppol2tp_abort_connect(pppol2tp_pcb *l2tp) { - PPPDEBUG(LOG_DEBUG, ("pppol2tp: could not establish connection\n")); - l2tp->phase = PPPOL2TP_STATE_INITIAL; - ppp_link_failed(l2tp->ppp); /* notify upper layers */ -} - -/* Initiate a new tunnel */ -static err_t pppol2tp_send_sccrq(pppol2tp_pcb *l2tp) { - struct pbuf *pb; - u8_t *p; - u16_t len; - - /* calculate UDP packet length */ - len = 12 +8 +8 +10 +10 +6+sizeof(PPPOL2TP_HOSTNAME)-1 +6+sizeof(PPPOL2TP_VENDORNAME)-1 +8 +8; -#if PPPOL2TP_AUTH_SUPPORT - if (l2tp->secret != NULL) { - len += 6 + sizeof(l2tp->secret_rv); - } -#endif /* PPPOL2TP_AUTH_SUPPORT */ - - /* allocate a buffer */ - pb = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM); - if (pb == NULL) { - return ERR_MEM; - } - LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len); - - p = (u8_t*)pb->payload; - /* fill in pkt */ - /* L2TP control header */ - PUTSHORT(PPPOL2TP_HEADERFLAG_CONTROL_MANDATORY, p); - PUTSHORT(len, p); /* Length */ - PUTSHORT(0, p); /* Tunnel Id */ - PUTSHORT(0, p); /* Session Id */ - PUTSHORT(0, p); /* NS Sequence number - to peer */ - PUTSHORT(0, p); /* NR Sequence number - expected for peer */ - - /* AVP - Message type */ - PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 8, p); /* Mandatory flag + len field */ - PUTSHORT(0, p); /* Vendor ID */ - PUTSHORT(PPPOL2TP_AVPTYPE_MESSAGE, p); /* Attribute type: Message Type */ - PUTSHORT(PPPOL2TP_MESSAGETYPE_SCCRQ, p); /* Attribute value: Message type: SCCRQ */ - - /* AVP - L2TP Version */ - PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 8, p); /* Mandatory flag + len field */ - PUTSHORT(0, p); /* Vendor ID */ - PUTSHORT(PPPOL2TP_AVPTYPE_VERSION, p); /* Attribute type: Version */ - PUTSHORT(PPPOL2TP_VERSION, p); /* Attribute value: L2TP Version */ - - /* AVP - Framing capabilities */ - PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 10, p); /* Mandatory flag + len field */ - PUTSHORT(0, p); /* Vendor ID */ - PUTSHORT(PPPOL2TP_AVPTYPE_FRAMINGCAPABILITIES, p); /* Attribute type: Framing capabilities */ - PUTLONG(PPPOL2TP_FRAMINGCAPABILITIES, p); /* Attribute value: Framing capabilities */ - - /* AVP - Bearer capabilities */ - PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 10, p); /* Mandatory flag + len field */ - PUTSHORT(0, p); /* Vendor ID */ - PUTSHORT(PPPOL2TP_AVPTYPE_BEARERCAPABILITIES, p); /* Attribute type: Bearer capabilities */ - PUTLONG(PPPOL2TP_BEARERCAPABILITIES, p); /* Attribute value: Bearer capabilities */ - - /* AVP - Host name */ - PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 6+sizeof(PPPOL2TP_HOSTNAME)-1, p); /* Mandatory flag + len field */ - PUTSHORT(0, p); /* Vendor ID */ - PUTSHORT(PPPOL2TP_AVPTYPE_HOSTNAME, p); /* Attribute type: Hostname */ - MEMCPY(p, PPPOL2TP_HOSTNAME, sizeof(PPPOL2TP_HOSTNAME)-1); /* Attribute value: Hostname */ - INCPTR(sizeof(PPPOL2TP_HOSTNAME)-1, p); - - /* AVP - Vendor name */ - PUTSHORT(6+sizeof(PPPOL2TP_VENDORNAME)-1, p); /* len field */ - PUTSHORT(0, p); /* Vendor ID */ - PUTSHORT(PPPOL2TP_AVPTYPE_VENDORNAME, p); /* Attribute type: Vendor name */ - MEMCPY(p, PPPOL2TP_VENDORNAME, sizeof(PPPOL2TP_VENDORNAME)-1); /* Attribute value: Vendor name */ - INCPTR(sizeof(PPPOL2TP_VENDORNAME)-1, p); - - /* AVP - Assign tunnel ID */ - PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 8, p); /* Mandatory flag + len field */ - PUTSHORT(0, p); /* Vendor ID */ - PUTSHORT(PPPOL2TP_AVPTYPE_TUNNELID, p); /* Attribute type: Tunnel ID */ - PUTSHORT(l2tp->remote_tunnel_id, p); /* Attribute value: Tunnel ID */ - - /* AVP - Receive window size */ - PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 8, p); /* Mandatory flag + len field */ - PUTSHORT(0, p); /* Vendor ID */ - PUTSHORT(PPPOL2TP_AVPTYPE_RECEIVEWINDOWSIZE, p); /* Attribute type: Receive window size */ - PUTSHORT(PPPOL2TP_RECEIVEWINDOWSIZE, p); /* Attribute value: Receive window size */ - -#if PPPOL2TP_AUTH_SUPPORT - /* AVP - Challenge */ - if (l2tp->secret != NULL) { - PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 6 + sizeof(l2tp->secret_rv), p); /* Mandatory flag + len field */ - PUTSHORT(0, p); /* Vendor ID */ - PUTSHORT(PPPOL2TP_AVPTYPE_CHALLENGE, p); /* Attribute type: Challenge */ - MEMCPY(p, l2tp->secret_rv, sizeof(l2tp->secret_rv)); /* Attribute value: Random vector */ - INCPTR(sizeof(l2tp->secret_rv), p); - } -#endif /* PPPOL2TP_AUTH_SUPPORT */ - - return pppol2tp_udp_send(l2tp, pb); -} - -/* Complete tunnel establishment */ -static err_t pppol2tp_send_scccn(pppol2tp_pcb *l2tp, u16_t ns) { - struct pbuf *pb; - u8_t *p; - u16_t len; - - /* calculate UDP packet length */ - len = 12 +8; -#if PPPOL2TP_AUTH_SUPPORT - if (l2tp->send_challenge) { - len += 6 + sizeof(l2tp->challenge_hash); - } -#endif /* PPPOL2TP_AUTH_SUPPORT */ - - /* allocate a buffer */ - pb = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM); - if (pb == NULL) { - return ERR_MEM; - } - LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len); - - p = (u8_t*)pb->payload; - /* fill in pkt */ - /* L2TP control header */ - PUTSHORT(PPPOL2TP_HEADERFLAG_CONTROL_MANDATORY, p); - PUTSHORT(len, p); /* Length */ - PUTSHORT(l2tp->source_tunnel_id, p); /* Tunnel Id */ - PUTSHORT(0, p); /* Session Id */ - PUTSHORT(ns, p); /* NS Sequence number - to peer */ - PUTSHORT(l2tp->peer_ns+1, p); /* NR Sequence number - expected for peer */ - - /* AVP - Message type */ - PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 8, p); /* Mandatory flag + len field */ - PUTSHORT(0, p); /* Vendor ID */ - PUTSHORT(PPPOL2TP_AVPTYPE_MESSAGE, p); /* Attribute type: Message Type */ - PUTSHORT(PPPOL2TP_MESSAGETYPE_SCCCN, p); /* Attribute value: Message type: SCCCN */ - -#if PPPOL2TP_AUTH_SUPPORT - /* AVP - Challenge response */ - if (l2tp->send_challenge) { - PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 6 + sizeof(l2tp->challenge_hash), p); /* Mandatory flag + len field */ - PUTSHORT(0, p); /* Vendor ID */ - PUTSHORT(PPPOL2TP_AVPTYPE_CHALLENGERESPONSE, p); /* Attribute type: Challenge response */ - MEMCPY(p, l2tp->challenge_hash, sizeof(l2tp->challenge_hash)); /* Attribute value: Computed challenge */ - INCPTR(sizeof(l2tp->challenge_hash), p); - } -#endif /* PPPOL2TP_AUTH_SUPPORT */ - - return pppol2tp_udp_send(l2tp, pb); -} - -/* Initiate a new session */ -static err_t pppol2tp_send_icrq(pppol2tp_pcb *l2tp, u16_t ns) { - struct pbuf *pb; - u8_t *p; - u16_t len; - u32_t serialnumber; - - /* calculate UDP packet length */ - len = 12 +8 +8 +10; - - /* allocate a buffer */ - pb = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM); - if (pb == NULL) { - return ERR_MEM; - } - LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len); - - p = (u8_t*)pb->payload; - /* fill in pkt */ - /* L2TP control header */ - PUTSHORT(PPPOL2TP_HEADERFLAG_CONTROL_MANDATORY, p); - PUTSHORT(len, p); /* Length */ - PUTSHORT(l2tp->source_tunnel_id, p); /* Tunnel Id */ - PUTSHORT(0, p); /* Session Id */ - PUTSHORT(ns, p); /* NS Sequence number - to peer */ - PUTSHORT(l2tp->peer_ns+1, p); /* NR Sequence number - expected for peer */ - - /* AVP - Message type */ - PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 8, p); /* Mandatory flag + len field */ - PUTSHORT(0, p); /* Vendor ID */ - PUTSHORT(PPPOL2TP_AVPTYPE_MESSAGE, p); /* Attribute type: Message Type */ - PUTSHORT(PPPOL2TP_MESSAGETYPE_ICRQ, p); /* Attribute value: Message type: ICRQ */ - - /* AVP - Assign session ID */ - PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 8, p); /* Mandatory flag + len field */ - PUTSHORT(0, p); /* Vendor ID */ - PUTSHORT(PPPOL2TP_AVPTYPE_SESSIONID, p); /* Attribute type: Session ID */ - PUTSHORT(l2tp->remote_session_id, p); /* Attribute value: Session ID */ - - /* AVP - Call Serial Number */ - PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 10, p); /* Mandatory flag + len field */ - PUTSHORT(0, p); /* Vendor ID */ - PUTSHORT(PPPOL2TP_AVPTYPE_CALLSERIALNUMBER, p); /* Attribute type: Serial number */ - serialnumber = magic(); - PUTLONG(serialnumber, p); /* Attribute value: Serial number */ - - return pppol2tp_udp_send(l2tp, pb); -} - -/* Complete tunnel establishment */ -static err_t pppol2tp_send_iccn(pppol2tp_pcb *l2tp, u16_t ns) { - struct pbuf *pb; - u8_t *p; - u16_t len; - - /* calculate UDP packet length */ - len = 12 +8 +10 +10; - - /* allocate a buffer */ - pb = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM); - if (pb == NULL) { - return ERR_MEM; - } - LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len); - - p = (u8_t*)pb->payload; - /* fill in pkt */ - /* L2TP control header */ - PUTSHORT(PPPOL2TP_HEADERFLAG_CONTROL_MANDATORY, p); - PUTSHORT(len, p); /* Length */ - PUTSHORT(l2tp->source_tunnel_id, p); /* Tunnel Id */ - PUTSHORT(l2tp->source_session_id, p); /* Session Id */ - PUTSHORT(ns, p); /* NS Sequence number - to peer */ - PUTSHORT(l2tp->peer_ns+1, p); /* NR Sequence number - expected for peer */ - - /* AVP - Message type */ - PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 8, p); /* Mandatory flag + len field */ - PUTSHORT(0, p); /* Vendor ID */ - PUTSHORT(PPPOL2TP_AVPTYPE_MESSAGE, p); /* Attribute type: Message Type */ - PUTSHORT(PPPOL2TP_MESSAGETYPE_ICCN, p); /* Attribute value: Message type: ICCN */ - - /* AVP - Framing type */ - PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 10, p); /* Mandatory flag + len field */ - PUTSHORT(0, p); /* Vendor ID */ - PUTSHORT(PPPOL2TP_AVPTYPE_FRAMINGTYPE, p); /* Attribute type: Framing type */ - PUTLONG(PPPOL2TP_FRAMINGTYPE, p); /* Attribute value: Framing type */ - - /* AVP - TX Connect speed */ - PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 10, p); /* Mandatory flag + len field */ - PUTSHORT(0, p); /* Vendor ID */ - PUTSHORT(PPPOL2TP_AVPTYPE_TXCONNECTSPEED, p); /* Attribute type: TX Connect speed */ - PUTLONG(PPPOL2TP_TXCONNECTSPEED, p); /* Attribute value: TX Connect speed */ - - return pppol2tp_udp_send(l2tp, pb); -} - -/* Send a ZLB ACK packet */ -static err_t pppol2tp_send_zlb(pppol2tp_pcb *l2tp, u16_t ns) { - struct pbuf *pb; - u8_t *p; - u16_t len; - - /* calculate UDP packet length */ - len = 12; - - /* allocate a buffer */ - pb = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM); - if (pb == NULL) { - return ERR_MEM; - } - LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len); - - p = (u8_t*)pb->payload; - /* fill in pkt */ - /* L2TP control header */ - PUTSHORT(PPPOL2TP_HEADERFLAG_CONTROL_MANDATORY, p); - PUTSHORT(len, p); /* Length */ - PUTSHORT(l2tp->source_tunnel_id, p); /* Tunnel Id */ - PUTSHORT(0, p); /* Session Id */ - PUTSHORT(ns, p); /* NS Sequence number - to peer */ - PUTSHORT(l2tp->peer_ns+1, p); /* NR Sequence number - expected for peer */ - - return pppol2tp_udp_send(l2tp, pb); -} - -/* Send a StopCCN packet */ -static err_t pppol2tp_send_stopccn(pppol2tp_pcb *l2tp, u16_t ns) { - struct pbuf *pb; - u8_t *p; - u16_t len; - - /* calculate UDP packet length */ - len = 12 +8 +8 +8; - - /* allocate a buffer */ - pb = pbuf_alloc(PBUF_TRANSPORT, len, PBUF_RAM); - if (pb == NULL) { - return ERR_MEM; - } - LWIP_ASSERT("pb->tot_len == pb->len", pb->tot_len == pb->len); - - p = (u8_t*)pb->payload; - /* fill in pkt */ - /* L2TP control header */ - PUTSHORT(PPPOL2TP_HEADERFLAG_CONTROL_MANDATORY, p); - PUTSHORT(len, p); /* Length */ - PUTSHORT(l2tp->source_tunnel_id, p); /* Tunnel Id */ - PUTSHORT(0, p); /* Session Id */ - PUTSHORT(ns, p); /* NS Sequence number - to peer */ - PUTSHORT(l2tp->peer_ns+1, p); /* NR Sequence number - expected for peer */ - - /* AVP - Message type */ - PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 8, p); /* Mandatory flag + len field */ - PUTSHORT(0, p); /* Vendor ID */ - PUTSHORT(PPPOL2TP_AVPTYPE_MESSAGE, p); /* Attribute type: Message Type */ - PUTSHORT(PPPOL2TP_MESSAGETYPE_STOPCCN, p); /* Attribute value: Message type: StopCCN */ - - /* AVP - Assign tunnel ID */ - PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 8, p); /* Mandatory flag + len field */ - PUTSHORT(0, p); /* Vendor ID */ - PUTSHORT(PPPOL2TP_AVPTYPE_TUNNELID, p); /* Attribute type: Tunnel ID */ - PUTSHORT(l2tp->remote_tunnel_id, p); /* Attribute value: Tunnel ID */ - - /* AVP - Result code */ - PUTSHORT(PPPOL2TP_AVPHEADERFLAG_MANDATORY + 8, p); /* Mandatory flag + len field */ - PUTSHORT(0, p); /* Vendor ID */ - PUTSHORT(PPPOL2TP_AVPTYPE_RESULTCODE, p); /* Attribute type: Result code */ - PUTSHORT(PPPOL2TP_RESULTCODE, p); /* Attribute value: Result code */ - - return pppol2tp_udp_send(l2tp, pb); -} - -static err_t pppol2tp_xmit(pppol2tp_pcb *l2tp, struct pbuf *pb) { - u8_t *p; - - /* make room for L2TP header - should not fail */ - if (pbuf_header(pb, (s16_t)PPPOL2TP_OUTPUT_DATA_HEADER_LEN) != 0) { - /* bail out */ - PPPDEBUG(LOG_ERR, ("pppol2tp: pppol2tp_pcb: could not allocate room for L2TP header\n")); - LINK_STATS_INC(link.lenerr); - pbuf_free(pb); - return ERR_BUF; - } - - p = (u8_t*)pb->payload; - PUTSHORT(PPPOL2TP_HEADERFLAG_DATA_MANDATORY, p); - PUTSHORT(l2tp->source_tunnel_id, p); /* Tunnel Id */ - PUTSHORT(l2tp->source_session_id, p); /* Session Id */ - - return pppol2tp_udp_send(l2tp, pb); -} - -static err_t pppol2tp_udp_send(pppol2tp_pcb *l2tp, struct pbuf *pb) { - err_t err; - if (l2tp->netif) { - err = udp_sendto_if(l2tp->udp, pb, &l2tp->remote_ip, l2tp->tunnel_port, l2tp->netif); - } else { - err = udp_sendto(l2tp->udp, pb, &l2tp->remote_ip, l2tp->tunnel_port); - } - pbuf_free(pb); - return err; -} - -#endif /* PPP_SUPPORT && PPPOL2TP_SUPPORT */ diff --git a/third_party/lwip/repo/lwip/src/netif/ppp/pppos.c b/third_party/lwip/repo/lwip/src/netif/ppp/pppos.c deleted file mode 100644 index fb48df4eb8eb94..00000000000000 --- a/third_party/lwip/repo/lwip/src/netif/ppp/pppos.c +++ /dev/null @@ -1,875 +0,0 @@ -/** - * @file - * Network Point to Point Protocol over Serial file. - * - */ - -/* - * Redistribution and use in source and binary forms, with or without modification, - * are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT - * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT - * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * This file is part of the lwIP TCP/IP stack. - * - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT && PPPOS_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#include - -#include "lwip/arch.h" -#include "lwip/err.h" -#include "lwip/pbuf.h" -#include "lwip/sys.h" -#include "lwip/memp.h" -#include "lwip/netif.h" -#include "lwip/snmp.h" -#include "lwip/priv/tcpip_priv.h" -#include "lwip/api.h" -#include "lwip/ip4.h" /* for ip4_input() */ - -#include "netif/ppp/ppp_impl.h" -#include "netif/ppp/pppos.h" -#include "netif/ppp/vj.h" - -/* Memory pool */ -LWIP_MEMPOOL_DECLARE(PPPOS_PCB, MEMP_NUM_PPPOS_INTERFACES, sizeof(pppos_pcb), "PPPOS_PCB") - -/* callbacks called from PPP core */ -static err_t pppos_write(ppp_pcb *ppp, void *ctx, struct pbuf *p); -static err_t pppos_netif_output(ppp_pcb *ppp, void *ctx, struct pbuf *pb, u16_t protocol); -static void pppos_connect(ppp_pcb *ppp, void *ctx); -#if PPP_SERVER -static void pppos_listen(ppp_pcb *ppp, void *ctx); -#endif /* PPP_SERVER */ -static void pppos_disconnect(ppp_pcb *ppp, void *ctx); -static err_t pppos_destroy(ppp_pcb *ppp, void *ctx); -static void pppos_send_config(ppp_pcb *ppp, void *ctx, u32_t accm, int pcomp, int accomp); -static void pppos_recv_config(ppp_pcb *ppp, void *ctx, u32_t accm, int pcomp, int accomp); - -/* Prototypes for procedures local to this file. */ -#if PPP_INPROC_IRQ_SAFE -static void pppos_input_callback(void *arg); -#endif /* PPP_INPROC_IRQ_SAFE */ -static void pppos_input_free_current_packet(pppos_pcb *pppos); -static void pppos_input_drop(pppos_pcb *pppos); -static err_t pppos_output_append(pppos_pcb *pppos, err_t err, struct pbuf *nb, u8_t c, u8_t accm, u16_t *fcs); -static err_t pppos_output_last(pppos_pcb *pppos, err_t err, struct pbuf *nb, u16_t *fcs); - -/* Callbacks structure for PPP core */ -static const struct link_callbacks pppos_callbacks = { - pppos_connect, -#if PPP_SERVER - pppos_listen, -#endif /* PPP_SERVER */ - pppos_disconnect, - pppos_destroy, - pppos_write, - pppos_netif_output, - pppos_send_config, - pppos_recv_config -}; - -/* PPP's Asynchronous-Control-Character-Map. The mask array is used - * to select the specific bit for a character. */ -#define ESCAPE_P(accm, c) ((accm)[(c) >> 3] & 1 << (c & 0x07)) - -#if PPP_FCS_TABLE -/* - * FCS lookup table as calculated by genfcstab. - */ -static const u16_t fcstab[256] = { - 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, - 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, - 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, - 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, - 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, - 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, - 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, - 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, - 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, - 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, - 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, - 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, - 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, - 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, - 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, - 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, - 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, - 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, - 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, - 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, - 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, - 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, - 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, - 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, - 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, - 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, - 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, - 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, - 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, - 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, - 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, - 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78 -}; -#define PPP_FCS(fcs, c) (((fcs) >> 8) ^ fcstab[((fcs) ^ (c)) & 0xff]) -#else /* PPP_FCS_TABLE */ -/* The HDLC polynomial: X**0 + X**5 + X**12 + X**16 (0x8408) */ -#define PPP_FCS_POLYNOMIAL 0x8408 -static u16_t -ppp_get_fcs(u8_t byte) -{ - unsigned int octet; - int bit; - octet = byte; - for (bit = 8; bit-- > 0; ) { - octet = (octet & 0x01) ? ((octet >> 1) ^ PPP_FCS_POLYNOMIAL) : (octet >> 1); - } - return octet & 0xffff; -} -#define PPP_FCS(fcs, c) (((fcs) >> 8) ^ ppp_get_fcs(((fcs) ^ (c)) & 0xff)) -#endif /* PPP_FCS_TABLE */ - -/* - * Values for FCS calculations. - */ -#define PPP_INITFCS 0xffff /* Initial FCS value */ -#define PPP_GOODFCS 0xf0b8 /* Good final FCS value */ - -#if PPP_INPROC_IRQ_SAFE -#define PPPOS_DECL_PROTECT(lev) SYS_ARCH_DECL_PROTECT(lev) -#define PPPOS_PROTECT(lev) SYS_ARCH_PROTECT(lev) -#define PPPOS_UNPROTECT(lev) SYS_ARCH_UNPROTECT(lev) -#else -#define PPPOS_DECL_PROTECT(lev) -#define PPPOS_PROTECT(lev) -#define PPPOS_UNPROTECT(lev) -#endif /* PPP_INPROC_IRQ_SAFE */ - - -/* - * Create a new PPP connection using the given serial I/O device. - * - * Return 0 on success, an error code on failure. - */ -ppp_pcb *pppos_create(struct netif *pppif, pppos_output_cb_fn output_cb, - ppp_link_status_cb_fn link_status_cb, void *ctx_cb) -{ - pppos_pcb *pppos; - ppp_pcb *ppp; - - pppos = (pppos_pcb *)LWIP_MEMPOOL_ALLOC(PPPOS_PCB); - if (pppos == NULL) { - return NULL; - } - - ppp = ppp_new(pppif, &pppos_callbacks, pppos, link_status_cb, ctx_cb); - if (ppp == NULL) { - LWIP_MEMPOOL_FREE(PPPOS_PCB, pppos); - return NULL; - } - - memset(pppos, 0, sizeof(pppos_pcb)); - pppos->ppp = ppp; - pppos->output_cb = output_cb; - return ppp; -} - -/* Called by PPP core */ -static err_t -pppos_write(ppp_pcb *ppp, void *ctx, struct pbuf *p) -{ - pppos_pcb *pppos = (pppos_pcb *)ctx; - u8_t *s; - struct pbuf *nb; - u16_t n; - u16_t fcs_out; - err_t err; - LWIP_UNUSED_ARG(ppp); - - /* Grab an output buffer. */ - nb = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL); - if (nb == NULL) { - PPPDEBUG(LOG_WARNING, ("pppos_write[%d]: alloc fail\n", ppp->netif->num)); - LINK_STATS_INC(link.memerr); - LINK_STATS_INC(link.drop); - MIB2_STATS_NETIF_INC(ppp->netif, ifoutdiscards); - pbuf_free(p); - return ERR_MEM; - } - - /* If the link has been idle, we'll send a fresh flag character to - * flush any noise. */ - err = ERR_OK; - if ((sys_now() - pppos->last_xmit) >= PPP_MAXIDLEFLAG) { - err = pppos_output_append(pppos, err, nb, PPP_FLAG, 0, NULL); - } - - /* Load output buffer. */ - fcs_out = PPP_INITFCS; - s = (u8_t*)p->payload; - n = p->len; - while (n-- > 0) { - err = pppos_output_append(pppos, err, nb, *s++, 1, &fcs_out); - } - - err = pppos_output_last(pppos, err, nb, &fcs_out); - if (err == ERR_OK) { - PPPDEBUG(LOG_INFO, ("pppos_write[%d]: len=%d\n", ppp->netif->num, p->len)); - } else { - PPPDEBUG(LOG_WARNING, ("pppos_write[%d]: output failed len=%d\n", ppp->netif->num, p->len)); - } - pbuf_free(p); - return err; -} - -/* Called by PPP core */ -static err_t -pppos_netif_output(ppp_pcb *ppp, void *ctx, struct pbuf *pb, u16_t protocol) -{ - pppos_pcb *pppos = (pppos_pcb *)ctx; - struct pbuf *nb, *p; - u16_t fcs_out; - err_t err; - LWIP_UNUSED_ARG(ppp); - - /* Grab an output buffer. */ - nb = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL); - if (nb == NULL) { - PPPDEBUG(LOG_WARNING, ("pppos_netif_output[%d]: alloc fail\n", ppp->netif->num)); - LINK_STATS_INC(link.memerr); - LINK_STATS_INC(link.drop); - MIB2_STATS_NETIF_INC(ppp->netif, ifoutdiscards); - return ERR_MEM; - } - - /* If the link has been idle, we'll send a fresh flag character to - * flush any noise. */ - err = ERR_OK; - if ((sys_now() - pppos->last_xmit) >= PPP_MAXIDLEFLAG) { - err = pppos_output_append(pppos, err, nb, PPP_FLAG, 0, NULL); - } - - fcs_out = PPP_INITFCS; - if (!pppos->accomp) { - err = pppos_output_append(pppos, err, nb, PPP_ALLSTATIONS, 1, &fcs_out); - err = pppos_output_append(pppos, err, nb, PPP_UI, 1, &fcs_out); - } - if (!pppos->pcomp || protocol > 0xFF) { - err = pppos_output_append(pppos, err, nb, (protocol >> 8) & 0xFF, 1, &fcs_out); - } - err = pppos_output_append(pppos, err, nb, protocol & 0xFF, 1, &fcs_out); - - /* Load packet. */ - for(p = pb; p; p = p->next) { - u16_t n = p->len; - u8_t *s = (u8_t*)p->payload; - - while (n-- > 0) { - err = pppos_output_append(pppos, err, nb, *s++, 1, &fcs_out); - } - } - - err = pppos_output_last(pppos, err, nb, &fcs_out); - if (err == ERR_OK) { - PPPDEBUG(LOG_INFO, ("pppos_netif_output[%d]: proto=0x%"X16_F", len = %d\n", ppp->netif->num, protocol, pb->tot_len)); - } else { - PPPDEBUG(LOG_WARNING, ("pppos_netif_output[%d]: output failed proto=0x%"X16_F", len = %d\n", ppp->netif->num, protocol, pb->tot_len)); - } - return err; -} - -static void -pppos_connect(ppp_pcb *ppp, void *ctx) -{ - pppos_pcb *pppos = (pppos_pcb *)ctx; - PPPOS_DECL_PROTECT(lev); - -#if PPP_INPROC_IRQ_SAFE - /* input pbuf left over from last session? */ - pppos_input_free_current_packet(pppos); -#endif /* PPP_INPROC_IRQ_SAFE */ - - /* reset PPPoS control block to its initial state */ - memset(&pppos->last_xmit, 0, sizeof(pppos_pcb) - offsetof(pppos_pcb, last_xmit)); - - /* - * Default the in and out accm so that escape and flag characters - * are always escaped. - */ - pppos->in_accm[15] = 0x60; /* no need to protect since RX is not running */ - pppos->out_accm[15] = 0x60; - PPPOS_PROTECT(lev); - pppos->open = 1; - PPPOS_UNPROTECT(lev); - - /* - * Start the connection and handle incoming events (packet or timeout). - */ - PPPDEBUG(LOG_INFO, ("pppos_connect: unit %d: connecting\n", ppp->netif->num)); - ppp_start(ppp); /* notify upper layers */ -} - -#if PPP_SERVER -static void -pppos_listen(ppp_pcb *ppp, void *ctx) -{ - pppos_pcb *pppos = (pppos_pcb *)ctx; - PPPOS_DECL_PROTECT(lev); - -#if PPP_INPROC_IRQ_SAFE - /* input pbuf left over from last session? */ - pppos_input_free_current_packet(pppos); -#endif /* PPP_INPROC_IRQ_SAFE */ - - /* reset PPPoS control block to its initial state */ - memset(&pppos->last_xmit, 0, sizeof(pppos_pcb) - offsetof(pppos_pcb, last_xmit)); - - /* - * Default the in and out accm so that escape and flag characters - * are always escaped. - */ - pppos->in_accm[15] = 0x60; /* no need to protect since RX is not running */ - pppos->out_accm[15] = 0x60; - PPPOS_PROTECT(lev); - pppos->open = 1; - PPPOS_UNPROTECT(lev); - - /* - * Wait for something to happen. - */ - PPPDEBUG(LOG_INFO, ("pppos_listen: unit %d: listening\n", ppp->netif->num)); - ppp_start(ppp); /* notify upper layers */ -} -#endif /* PPP_SERVER */ - -static void -pppos_disconnect(ppp_pcb *ppp, void *ctx) -{ - pppos_pcb *pppos = (pppos_pcb *)ctx; - PPPOS_DECL_PROTECT(lev); - - PPPOS_PROTECT(lev); - pppos->open = 0; - PPPOS_UNPROTECT(lev); - - /* If PPP_INPROC_IRQ_SAFE is used we cannot call - * pppos_input_free_current_packet() here because - * rx IRQ might still call pppos_input(). - */ -#if !PPP_INPROC_IRQ_SAFE - /* input pbuf left ? */ - pppos_input_free_current_packet(pppos); -#endif /* !PPP_INPROC_IRQ_SAFE */ - - ppp_link_end(ppp); /* notify upper layers */ -} - -static err_t -pppos_destroy(ppp_pcb *ppp, void *ctx) -{ - pppos_pcb *pppos = (pppos_pcb *)ctx; - LWIP_UNUSED_ARG(ppp); - -#if PPP_INPROC_IRQ_SAFE - /* input pbuf left ? */ - pppos_input_free_current_packet(pppos); -#endif /* PPP_INPROC_IRQ_SAFE */ - - LWIP_MEMPOOL_FREE(PPPOS_PCB, pppos); - return ERR_OK; -} - -#if !NO_SYS && !PPP_INPROC_IRQ_SAFE -/** Pass received raw characters to PPPoS to be decoded through lwIP TCPIP thread. - * - * @param ppp PPP descriptor index, returned by pppos_create() - * @param s received data - * @param l length of received data - */ -err_t -pppos_input_tcpip(ppp_pcb *ppp, u8_t *s, int l) -{ - struct pbuf *p; - err_t err; - - p = pbuf_alloc(PBUF_RAW, l, PBUF_POOL); - if (!p) { - return ERR_MEM; - } - pbuf_take(p, s, l); - - err = tcpip_inpkt(p, ppp_netif(ppp), pppos_input_sys); - if (err != ERR_OK) { - pbuf_free(p); - } - return err; -} - -/* called from TCPIP thread */ -err_t pppos_input_sys(struct pbuf *p, struct netif *inp) { - ppp_pcb *ppp = (ppp_pcb*)inp->state; - struct pbuf *n; - - for (n = p; n; n = n->next) { - pppos_input(ppp, (u8_t*)n->payload, n->len); - } - pbuf_free(p); - return ERR_OK; -} -#endif /* !NO_SYS && !PPP_INPROC_IRQ_SAFE */ - -/** PPPoS input helper struct, must be packed since it is stored - * to pbuf->payload, which might be unaligned. */ -#if PPP_INPROC_IRQ_SAFE -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct pppos_input_header { - PACK_STRUCT_FIELD(ppp_pcb *ppp); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif -#endif /* PPP_INPROC_IRQ_SAFE */ - -/** Pass received raw characters to PPPoS to be decoded. - * - * @param ppp PPP descriptor index, returned by pppos_create() - * @param s received data - * @param l length of received data - */ -void -pppos_input(ppp_pcb *ppp, u8_t *s, int l) -{ - pppos_pcb *pppos = (pppos_pcb *)ppp->link_ctx_cb; - struct pbuf *next_pbuf; - u8_t cur_char; - u8_t escaped; - PPPOS_DECL_PROTECT(lev); - - PPPDEBUG(LOG_DEBUG, ("pppos_input[%d]: got %d bytes\n", ppp->netif->num, l)); - while (l-- > 0) { - cur_char = *s++; - - PPPOS_PROTECT(lev); - /* ppp_input can disconnect the interface, we need to abort to prevent a memory - * leak if there are remaining bytes because pppos_connect and pppos_listen - * functions expect input buffer to be free. Furthermore there are no real - * reason to continue reading bytes if we are disconnected. - */ - if (!pppos->open) { - PPPOS_UNPROTECT(lev); - return; - } - escaped = ESCAPE_P(pppos->in_accm, cur_char); - PPPOS_UNPROTECT(lev); - /* Handle special characters. */ - if (escaped) { - /* Check for escape sequences. */ - /* XXX Note that this does not handle an escaped 0x5d character which - * would appear as an escape character. Since this is an ASCII ']' - * and there is no reason that I know of to escape it, I won't complicate - * the code to handle this case. GLL */ - if (cur_char == PPP_ESCAPE) { - pppos->in_escaped = 1; - /* Check for the flag character. */ - } else if (cur_char == PPP_FLAG) { - /* If this is just an extra flag character, ignore it. */ - if (pppos->in_state <= PDADDRESS) { - /* ignore it */; - /* If we haven't received the packet header, drop what has come in. */ - } else if (pppos->in_state < PDDATA) { - PPPDEBUG(LOG_WARNING, - ("pppos_input[%d]: Dropping incomplete packet %d\n", - ppp->netif->num, pppos->in_state)); - LINK_STATS_INC(link.lenerr); - pppos_input_drop(pppos); - /* If the fcs is invalid, drop the packet. */ - } else if (pppos->in_fcs != PPP_GOODFCS) { - PPPDEBUG(LOG_INFO, - ("pppos_input[%d]: Dropping bad fcs 0x%"X16_F" proto=0x%"X16_F"\n", - ppp->netif->num, pppos->in_fcs, pppos->in_protocol)); - /* Note: If you get lots of these, check for UART frame errors or try different baud rate */ - LINK_STATS_INC(link.chkerr); - pppos_input_drop(pppos); - /* Otherwise it's a good packet so pass it on. */ - } else { - struct pbuf *inp; - /* Trim off the checksum. */ - if(pppos->in_tail->len > 2) { - pppos->in_tail->len -= 2; - - pppos->in_tail->tot_len = pppos->in_tail->len; - if (pppos->in_tail != pppos->in_head) { - pbuf_cat(pppos->in_head, pppos->in_tail); - } - } else { - pppos->in_tail->tot_len = pppos->in_tail->len; - if (pppos->in_tail != pppos->in_head) { - pbuf_cat(pppos->in_head, pppos->in_tail); - } - - pbuf_realloc(pppos->in_head, pppos->in_head->tot_len - 2); - } - - /* Dispatch the packet thereby consuming it. */ - inp = pppos->in_head; - /* Packet consumed, release our references. */ - pppos->in_head = NULL; - pppos->in_tail = NULL; -#if IP_FORWARD || LWIP_IPV6_FORWARD - /* hide the room for Ethernet forwarding header */ - pbuf_header(inp, -(s16_t)(PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN)); -#endif /* IP_FORWARD || LWIP_IPV6_FORWARD */ -#if PPP_INPROC_IRQ_SAFE - if(tcpip_callback_with_block(pppos_input_callback, inp, 0) != ERR_OK) { - PPPDEBUG(LOG_ERR, ("pppos_input[%d]: tcpip_callback() failed, dropping packet\n", ppp->netif->num)); - pbuf_free(inp); - LINK_STATS_INC(link.drop); - MIB2_STATS_NETIF_INC(ppp->netif, ifindiscards); - } -#else /* PPP_INPROC_IRQ_SAFE */ - ppp_input(ppp, inp); -#endif /* PPP_INPROC_IRQ_SAFE */ - } - - /* Prepare for a new packet. */ - pppos->in_fcs = PPP_INITFCS; - pppos->in_state = PDADDRESS; - pppos->in_escaped = 0; - /* Other characters are usually control characters that may have - * been inserted by the physical layer so here we just drop them. */ - } else { - PPPDEBUG(LOG_WARNING, - ("pppos_input[%d]: Dropping ACCM char <%d>\n", ppp->netif->num, cur_char)); - } - /* Process other characters. */ - } else { - /* Unencode escaped characters. */ - if (pppos->in_escaped) { - pppos->in_escaped = 0; - cur_char ^= PPP_TRANS; - } - - /* Process character relative to current state. */ - switch(pppos->in_state) { - case PDIDLE: /* Idle state - waiting. */ - /* Drop the character if it's not 0xff - * we would have processed a flag character above. */ - if (cur_char != PPP_ALLSTATIONS) { - break; - } - /* no break */ - /* Fall through */ - - case PDSTART: /* Process start flag. */ - /* Prepare for a new packet. */ - pppos->in_fcs = PPP_INITFCS; - /* no break */ - /* Fall through */ - - case PDADDRESS: /* Process address field. */ - if (cur_char == PPP_ALLSTATIONS) { - pppos->in_state = PDCONTROL; - break; - } - /* no break */ - - /* Else assume compressed address and control fields so - * fall through to get the protocol... */ - case PDCONTROL: /* Process control field. */ - /* If we don't get a valid control code, restart. */ - if (cur_char == PPP_UI) { - pppos->in_state = PDPROTOCOL1; - break; - } - /* no break */ - -#if 0 - else { - PPPDEBUG(LOG_WARNING, - ("pppos_input[%d]: Invalid control <%d>\n", ppp->netif->num, cur_char)); - pppos->in_state = PDSTART; - } -#endif - case PDPROTOCOL1: /* Process protocol field 1. */ - /* If the lower bit is set, this is the end of the protocol - * field. */ - if (cur_char & 1) { - pppos->in_protocol = cur_char; - pppos->in_state = PDDATA; - } else { - pppos->in_protocol = (u16_t)cur_char << 8; - pppos->in_state = PDPROTOCOL2; - } - break; - case PDPROTOCOL2: /* Process protocol field 2. */ - pppos->in_protocol |= cur_char; - pppos->in_state = PDDATA; - break; - case PDDATA: /* Process data byte. */ - /* Make space to receive processed data. */ - if (pppos->in_tail == NULL || pppos->in_tail->len == PBUF_POOL_BUFSIZE) { - u16_t pbuf_alloc_len; - if (pppos->in_tail != NULL) { - pppos->in_tail->tot_len = pppos->in_tail->len; - if (pppos->in_tail != pppos->in_head) { - pbuf_cat(pppos->in_head, pppos->in_tail); - /* give up the in_tail reference now */ - pppos->in_tail = NULL; - } - } - /* If we haven't started a packet, we need a packet header. */ - pbuf_alloc_len = 0; -#if IP_FORWARD || LWIP_IPV6_FORWARD - /* If IP forwarding is enabled we are reserving PBUF_LINK_ENCAPSULATION_HLEN - * + PBUF_LINK_HLEN bytes so the packet is being allocated with enough header - * space to be forwarded (to Ethernet for example). - */ - if (pppos->in_head == NULL) { - pbuf_alloc_len = PBUF_LINK_ENCAPSULATION_HLEN + PBUF_LINK_HLEN; - } -#endif /* IP_FORWARD || LWIP_IPV6_FORWARD */ - next_pbuf = pbuf_alloc(PBUF_RAW, pbuf_alloc_len, PBUF_POOL); - if (next_pbuf == NULL) { - /* No free buffers. Drop the input packet and let the - * higher layers deal with it. Continue processing - * the received pbuf chain in case a new packet starts. */ - PPPDEBUG(LOG_ERR, ("pppos_input[%d]: NO FREE PBUFS!\n", ppp->netif->num)); - LINK_STATS_INC(link.memerr); - pppos_input_drop(pppos); - pppos->in_state = PDSTART; /* Wait for flag sequence. */ - break; - } - if (pppos->in_head == NULL) { - u8_t *payload = ((u8_t*)next_pbuf->payload) + pbuf_alloc_len; -#if PPP_INPROC_IRQ_SAFE - ((struct pppos_input_header*)payload)->ppp = ppp; - payload += sizeof(struct pppos_input_header); - next_pbuf->len += sizeof(struct pppos_input_header); -#endif /* PPP_INPROC_IRQ_SAFE */ - next_pbuf->len += sizeof(pppos->in_protocol); - *(payload++) = pppos->in_protocol >> 8; - *(payload) = pppos->in_protocol & 0xFF; - pppos->in_head = next_pbuf; - } - pppos->in_tail = next_pbuf; - } - /* Load character into buffer. */ - ((u8_t*)pppos->in_tail->payload)[pppos->in_tail->len++] = cur_char; - break; - default: - break; - } - - /* update the frame check sequence number. */ - pppos->in_fcs = PPP_FCS(pppos->in_fcs, cur_char); - } - } /* while (l-- > 0), all bytes processed */ -} - -#if PPP_INPROC_IRQ_SAFE -/* PPPoS input callback using one input pointer - */ -static void pppos_input_callback(void *arg) { - struct pbuf *pb = (struct pbuf*)arg; - ppp_pcb *ppp; - - ppp = ((struct pppos_input_header*)pb->payload)->ppp; - if(pbuf_header(pb, -(s16_t)sizeof(struct pppos_input_header))) { - LWIP_ASSERT("pbuf_header failed\n", 0); - goto drop; - } - - /* Dispatch the packet thereby consuming it. */ - ppp_input(ppp, pb); - return; - -drop: - LINK_STATS_INC(link.drop); - MIB2_STATS_NETIF_INC(ppp->netif, ifindiscards); - pbuf_free(pb); -} -#endif /* PPP_INPROC_IRQ_SAFE */ - -static void -pppos_send_config(ppp_pcb *ppp, void *ctx, u32_t accm, int pcomp, int accomp) -{ - int i; - pppos_pcb *pppos = (pppos_pcb *)ctx; - LWIP_UNUSED_ARG(ppp); - - pppos->pcomp = pcomp; - pppos->accomp = accomp; - - /* Load the ACCM bits for the 32 control codes. */ - for (i = 0; i < 32/8; i++) { - pppos->out_accm[i] = (u8_t)((accm >> (8 * i)) & 0xFF); - } - - PPPDEBUG(LOG_INFO, ("pppos_send_config[%d]: out_accm=%X %X %X %X\n", - pppos->ppp->netif->num, - pppos->out_accm[0], pppos->out_accm[1], pppos->out_accm[2], pppos->out_accm[3])); -} - -static void -pppos_recv_config(ppp_pcb *ppp, void *ctx, u32_t accm, int pcomp, int accomp) -{ - int i; - pppos_pcb *pppos = (pppos_pcb *)ctx; - PPPOS_DECL_PROTECT(lev); - LWIP_UNUSED_ARG(ppp); - LWIP_UNUSED_ARG(pcomp); - LWIP_UNUSED_ARG(accomp); - - /* Load the ACCM bits for the 32 control codes. */ - PPPOS_PROTECT(lev); - for (i = 0; i < 32 / 8; i++) { - pppos->in_accm[i] = (u8_t)(accm >> (i * 8)); - } - PPPOS_UNPROTECT(lev); - - PPPDEBUG(LOG_INFO, ("pppos_recv_config[%d]: in_accm=%X %X %X %X\n", - pppos->ppp->netif->num, - pppos->in_accm[0], pppos->in_accm[1], pppos->in_accm[2], pppos->in_accm[3])); -} - -/* - * Drop the input packet. - */ -static void -pppos_input_free_current_packet(pppos_pcb *pppos) -{ - if (pppos->in_head != NULL) { - if (pppos->in_tail && (pppos->in_tail != pppos->in_head)) { - pbuf_free(pppos->in_tail); - } - pbuf_free(pppos->in_head); - pppos->in_head = NULL; - } - pppos->in_tail = NULL; -} - -/* - * Drop the input packet and increase error counters. - */ -static void -pppos_input_drop(pppos_pcb *pppos) -{ - if (pppos->in_head != NULL) { -#if 0 - PPPDEBUG(LOG_INFO, ("pppos_input_drop: %d:%.*H\n", pppos->in_head->len, min(60, pppos->in_head->len * 2), pppos->in_head->payload)); -#endif - PPPDEBUG(LOG_INFO, ("pppos_input_drop: pbuf len=%d, addr %p\n", pppos->in_head->len, (void*)pppos->in_head)); - } - pppos_input_free_current_packet(pppos); -#if VJ_SUPPORT - vj_uncompress_err(&pppos->ppp->vj_comp); -#endif /* VJ_SUPPORT */ - - LINK_STATS_INC(link.drop); - MIB2_STATS_NETIF_INC(pppos->ppp->netif, ifindiscards); -} - -/* - * pppos_output_append - append given character to end of given pbuf. - * If out_accm is not 0 and the character needs to be escaped, do so. - * If pbuf is full, send the pbuf and reuse it. - * Return the current pbuf. - */ -static err_t -pppos_output_append(pppos_pcb *pppos, err_t err, struct pbuf *nb, u8_t c, u8_t accm, u16_t *fcs) -{ - if (err != ERR_OK) { - return err; - } - - /* Make sure there is room for the character and an escape code. - * Sure we don't quite fill the buffer if the character doesn't - * get escaped but is one character worth complicating this? */ - if ((PBUF_POOL_BUFSIZE - nb->len) < 2) { - u32_t l = pppos->output_cb(pppos->ppp, (u8_t*)nb->payload, nb->len, pppos->ppp->ctx_cb); - if (l != nb->len) { - return ERR_IF; - } - nb->len = 0; - } - - /* Update FCS before checking for special characters. */ - if (fcs) { - *fcs = PPP_FCS(*fcs, c); - } - - /* Copy to output buffer escaping special characters. */ - if (accm && ESCAPE_P(pppos->out_accm, c)) { - *((u8_t*)nb->payload + nb->len++) = PPP_ESCAPE; - *((u8_t*)nb->payload + nb->len++) = c ^ PPP_TRANS; - } else { - *((u8_t*)nb->payload + nb->len++) = c; - } - - return ERR_OK; -} - -static err_t -pppos_output_last(pppos_pcb *pppos, err_t err, struct pbuf *nb, u16_t *fcs) -{ - ppp_pcb *ppp = pppos->ppp; - - /* Add FCS and trailing flag. */ - err = pppos_output_append(pppos, err, nb, ~(*fcs) & 0xFF, 1, NULL); - err = pppos_output_append(pppos, err, nb, (~(*fcs) >> 8) & 0xFF, 1, NULL); - err = pppos_output_append(pppos, err, nb, PPP_FLAG, 0, NULL); - - if (err != ERR_OK) { - goto failed; - } - - /* Send remaining buffer if not empty */ - if (nb->len > 0) { - u32_t l = pppos->output_cb(ppp, (u8_t*)nb->payload, nb->len, ppp->ctx_cb); - if (l != nb->len) { - err = ERR_IF; - goto failed; - } - } - - pppos->last_xmit = sys_now(); - MIB2_STATS_NETIF_ADD(ppp->netif, ifoutoctets, nb->tot_len); - MIB2_STATS_NETIF_INC(ppp->netif, ifoutucastpkts); - LINK_STATS_INC(link.xmit); - pbuf_free(nb); - return ERR_OK; - -failed: - pppos->last_xmit = 0; /* prepend PPP_FLAG to next packet */ - LINK_STATS_INC(link.err); - LINK_STATS_INC(link.drop); - MIB2_STATS_NETIF_INC(ppp->netif, ifoutdiscards); - pbuf_free(nb); - return err; -} - -#endif /* PPP_SUPPORT && PPPOS_SUPPORT */ diff --git a/third_party/lwip/repo/lwip/src/netif/ppp/upap.c b/third_party/lwip/repo/lwip/src/netif/ppp/upap.c deleted file mode 100644 index d00c2d76e57448..00000000000000 --- a/third_party/lwip/repo/lwip/src/netif/ppp/upap.c +++ /dev/null @@ -1,677 +0,0 @@ -/* - * upap.c - User/Password Authentication Protocol. - * - * Copyright (c) 1984-2000 Carnegie Mellon University. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in - * the documentation and/or other materials provided with the - * distribution. - * - * 3. The name "Carnegie Mellon University" must not be used to - * endorse or promote products derived from this software without - * prior written permission. For permission or any legal - * details, please contact - * Office of Technology Transfer - * Carnegie Mellon University - * 5000 Forbes Avenue - * Pittsburgh, PA 15213-3890 - * (412) 268-4387, fax: (412) 268-7395 - * tech-transfer@andrew.cmu.edu - * - * 4. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Computing Services - * at Carnegie Mellon University (http://www.cmu.edu/computing/)." - * - * CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE - * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT && PAP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -/* - * @todo: - */ - -#if 0 /* UNUSED */ -#include -#include -#endif /* UNUSED */ - -#include "netif/ppp/ppp_impl.h" - -#include "netif/ppp/upap.h" - -#if PPP_OPTIONS -/* - * Command-line options. - */ -static option_t pap_option_list[] = { - { "hide-password", o_bool, &hide_password, - "Don't output passwords to log", OPT_PRIO | 1 }, - { "show-password", o_bool, &hide_password, - "Show password string in debug log messages", OPT_PRIOSUB | 0 }, - - { "pap-restart", o_int, &upap[0].us_timeouttime, - "Set retransmit timeout for PAP", OPT_PRIO }, - { "pap-max-authreq", o_int, &upap[0].us_maxtransmits, - "Set max number of transmissions for auth-reqs", OPT_PRIO }, - { "pap-timeout", o_int, &upap[0].us_reqtimeout, - "Set time limit for peer PAP authentication", OPT_PRIO }, - - { NULL } -}; -#endif /* PPP_OPTIONS */ - -/* - * Protocol entry points. - */ -static void upap_init(ppp_pcb *pcb); -static void upap_lowerup(ppp_pcb *pcb); -static void upap_lowerdown(ppp_pcb *pcb); -static void upap_input(ppp_pcb *pcb, u_char *inpacket, int l); -static void upap_protrej(ppp_pcb *pcb); -#if PRINTPKT_SUPPORT -static int upap_printpkt(const u_char *p, int plen, void (*printer) (void *, const char *, ...), void *arg); -#endif /* PRINTPKT_SUPPORT */ - -const struct protent pap_protent = { - PPP_PAP, - upap_init, - upap_input, - upap_protrej, - upap_lowerup, - upap_lowerdown, - NULL, - NULL, -#if PRINTPKT_SUPPORT - upap_printpkt, -#endif /* PRINTPKT_SUPPORT */ -#if PPP_DATAINPUT - NULL, -#endif /* PPP_DATAINPUT */ -#if PRINTPKT_SUPPORT - "PAP", - NULL, -#endif /* PRINTPKT_SUPPORT */ -#if PPP_OPTIONS - pap_option_list, - NULL, -#endif /* PPP_OPTIONS */ -#if DEMAND_SUPPORT - NULL, - NULL -#endif /* DEMAND_SUPPORT */ -}; - -static void upap_timeout(void *arg); -#if PPP_SERVER -static void upap_reqtimeout(void *arg); -static void upap_rauthreq(ppp_pcb *pcb, u_char *inp, int id, int len); -#endif /* PPP_SERVER */ -static void upap_rauthack(ppp_pcb *pcb, u_char *inp, int id, int len); -static void upap_rauthnak(ppp_pcb *pcb, u_char *inp, int id, int len); -static void upap_sauthreq(ppp_pcb *pcb); -#if PPP_SERVER -static void upap_sresp(ppp_pcb *pcb, u_char code, u_char id, const char *msg, int msglen); -#endif /* PPP_SERVER */ - - -/* - * upap_init - Initialize a UPAP unit. - */ -static void upap_init(ppp_pcb *pcb) { - pcb->upap.us_user = NULL; - pcb->upap.us_userlen = 0; - pcb->upap.us_passwd = NULL; - pcb->upap.us_passwdlen = 0; - pcb->upap.us_clientstate = UPAPCS_INITIAL; -#if PPP_SERVER - pcb->upap.us_serverstate = UPAPSS_INITIAL; -#endif /* PPP_SERVER */ - pcb->upap.us_id = 0; -} - - -/* - * upap_authwithpeer - Authenticate us with our peer (start client). - * - * Set new state and send authenticate's. - */ -void upap_authwithpeer(ppp_pcb *pcb, const char *user, const char *password) { - - if(!user || !password) - return; - - /* Save the username and password we're given */ - pcb->upap.us_user = user; - pcb->upap.us_userlen = LWIP_MIN(strlen(user), 0xff); - pcb->upap.us_passwd = password; - pcb->upap.us_passwdlen = LWIP_MIN(strlen(password), 0xff); - pcb->upap.us_transmits = 0; - - /* Lower layer up yet? */ - if (pcb->upap.us_clientstate == UPAPCS_INITIAL || - pcb->upap.us_clientstate == UPAPCS_PENDING) { - pcb->upap.us_clientstate = UPAPCS_PENDING; - return; - } - - upap_sauthreq(pcb); /* Start protocol */ -} - -#if PPP_SERVER -/* - * upap_authpeer - Authenticate our peer (start server). - * - * Set new state. - */ -void upap_authpeer(ppp_pcb *pcb) { - - /* Lower layer up yet? */ - if (pcb->upap.us_serverstate == UPAPSS_INITIAL || - pcb->upap.us_serverstate == UPAPSS_PENDING) { - pcb->upap.us_serverstate = UPAPSS_PENDING; - return; - } - - pcb->upap.us_serverstate = UPAPSS_LISTEN; - if (pcb->settings.pap_req_timeout > 0) - TIMEOUT(upap_reqtimeout, pcb, pcb->settings.pap_req_timeout); -} -#endif /* PPP_SERVER */ - -/* - * upap_timeout - Retransmission timer for sending auth-reqs expired. - */ -static void upap_timeout(void *arg) { - ppp_pcb *pcb = (ppp_pcb*)arg; - - if (pcb->upap.us_clientstate != UPAPCS_AUTHREQ) - return; - - if (pcb->upap.us_transmits >= pcb->settings.pap_max_transmits) { - /* give up in disgust */ - ppp_error("No response to PAP authenticate-requests"); - pcb->upap.us_clientstate = UPAPCS_BADAUTH; - auth_withpeer_fail(pcb, PPP_PAP); - return; - } - - upap_sauthreq(pcb); /* Send Authenticate-Request */ -} - - -#if PPP_SERVER -/* - * upap_reqtimeout - Give up waiting for the peer to send an auth-req. - */ -static void upap_reqtimeout(void *arg) { - ppp_pcb *pcb = (ppp_pcb*)arg; - - if (pcb->upap.us_serverstate != UPAPSS_LISTEN) - return; /* huh?? */ - - auth_peer_fail(pcb, PPP_PAP); - pcb->upap.us_serverstate = UPAPSS_BADAUTH; -} -#endif /* PPP_SERVER */ - - -/* - * upap_lowerup - The lower layer is up. - * - * Start authenticating if pending. - */ -static void upap_lowerup(ppp_pcb *pcb) { - - if (pcb->upap.us_clientstate == UPAPCS_INITIAL) - pcb->upap.us_clientstate = UPAPCS_CLOSED; - else if (pcb->upap.us_clientstate == UPAPCS_PENDING) { - upap_sauthreq(pcb); /* send an auth-request */ - } - -#if PPP_SERVER - if (pcb->upap.us_serverstate == UPAPSS_INITIAL) - pcb->upap.us_serverstate = UPAPSS_CLOSED; - else if (pcb->upap.us_serverstate == UPAPSS_PENDING) { - pcb->upap.us_serverstate = UPAPSS_LISTEN; - if (pcb->settings.pap_req_timeout > 0) - TIMEOUT(upap_reqtimeout, pcb, pcb->settings.pap_req_timeout); - } -#endif /* PPP_SERVER */ -} - - -/* - * upap_lowerdown - The lower layer is down. - * - * Cancel all timeouts. - */ -static void upap_lowerdown(ppp_pcb *pcb) { - - if (pcb->upap.us_clientstate == UPAPCS_AUTHREQ) /* Timeout pending? */ - UNTIMEOUT(upap_timeout, pcb); /* Cancel timeout */ -#if PPP_SERVER - if (pcb->upap.us_serverstate == UPAPSS_LISTEN && pcb->settings.pap_req_timeout > 0) - UNTIMEOUT(upap_reqtimeout, pcb); -#endif /* PPP_SERVER */ - - pcb->upap.us_clientstate = UPAPCS_INITIAL; -#if PPP_SERVER - pcb->upap.us_serverstate = UPAPSS_INITIAL; -#endif /* PPP_SERVER */ -} - - -/* - * upap_protrej - Peer doesn't speak this protocol. - * - * This shouldn't happen. In any case, pretend lower layer went down. - */ -static void upap_protrej(ppp_pcb *pcb) { - - if (pcb->upap.us_clientstate == UPAPCS_AUTHREQ) { - ppp_error("PAP authentication failed due to protocol-reject"); - auth_withpeer_fail(pcb, PPP_PAP); - } -#if PPP_SERVER - if (pcb->upap.us_serverstate == UPAPSS_LISTEN) { - ppp_error("PAP authentication of peer failed (protocol-reject)"); - auth_peer_fail(pcb, PPP_PAP); - } -#endif /* PPP_SERVER */ - upap_lowerdown(pcb); -} - - -/* - * upap_input - Input UPAP packet. - */ -static void upap_input(ppp_pcb *pcb, u_char *inpacket, int l) { - u_char *inp; - u_char code, id; - int len; - - /* - * Parse header (code, id and length). - * If packet too short, drop it. - */ - inp = inpacket; - if (l < UPAP_HEADERLEN) { - UPAPDEBUG(("pap_input: rcvd short header.")); - return; - } - GETCHAR(code, inp); - GETCHAR(id, inp); - GETSHORT(len, inp); - if (len < UPAP_HEADERLEN) { - UPAPDEBUG(("pap_input: rcvd illegal length.")); - return; - } - if (len > l) { - UPAPDEBUG(("pap_input: rcvd short packet.")); - return; - } - len -= UPAP_HEADERLEN; - - /* - * Action depends on code. - */ - switch (code) { - case UPAP_AUTHREQ: -#if PPP_SERVER - upap_rauthreq(pcb, inp, id, len); -#endif /* PPP_SERVER */ - break; - - case UPAP_AUTHACK: - upap_rauthack(pcb, inp, id, len); - break; - - case UPAP_AUTHNAK: - upap_rauthnak(pcb, inp, id, len); - break; - - default: /* XXX Need code reject */ - break; - } -} - -#if PPP_SERVER -/* - * upap_rauth - Receive Authenticate. - */ -static void upap_rauthreq(ppp_pcb *pcb, u_char *inp, int id, int len) { - u_char ruserlen, rpasswdlen; - char *ruser; - char *rpasswd; - char rhostname[256]; - int retcode; - const char *msg; - int msglen; - - if (pcb->upap.us_serverstate < UPAPSS_LISTEN) - return; - - /* - * If we receive a duplicate authenticate-request, we are - * supposed to return the same status as for the first request. - */ - if (pcb->upap.us_serverstate == UPAPSS_OPEN) { - upap_sresp(pcb, UPAP_AUTHACK, id, "", 0); /* return auth-ack */ - return; - } - if (pcb->upap.us_serverstate == UPAPSS_BADAUTH) { - upap_sresp(pcb, UPAP_AUTHNAK, id, "", 0); /* return auth-nak */ - return; - } - - /* - * Parse user/passwd. - */ - if (len < 1) { - UPAPDEBUG(("pap_rauth: rcvd short packet.")); - return; - } - GETCHAR(ruserlen, inp); - len -= sizeof (u_char) + ruserlen + sizeof (u_char); - if (len < 0) { - UPAPDEBUG(("pap_rauth: rcvd short packet.")); - return; - } - ruser = (char *) inp; - INCPTR(ruserlen, inp); - GETCHAR(rpasswdlen, inp); - if (len < rpasswdlen) { - UPAPDEBUG(("pap_rauth: rcvd short packet.")); - return; - } - - rpasswd = (char *) inp; - - /* - * Check the username and password given. - */ - retcode = UPAP_AUTHNAK; - if (auth_check_passwd(pcb, ruser, ruserlen, rpasswd, rpasswdlen, &msg, &msglen)) { - retcode = UPAP_AUTHACK; - } - BZERO(rpasswd, rpasswdlen); - -#if 0 /* UNUSED */ - /* - * Check remote number authorization. A plugin may have filled in - * the remote number or added an allowed number, and rather than - * return an authenticate failure, is leaving it for us to verify. - */ - if (retcode == UPAP_AUTHACK) { - if (!auth_number()) { - /* We do not want to leak info about the pap result. */ - retcode = UPAP_AUTHNAK; /* XXX exit value will be "wrong" */ - warn("calling number %q is not authorized", remote_number); - } - } - - msglen = strlen(msg); - if (msglen > 255) - msglen = 255; -#endif /* UNUSED */ - - upap_sresp(pcb, retcode, id, msg, msglen); - - /* Null terminate and clean remote name. */ - ppp_slprintf(rhostname, sizeof(rhostname), "%.*v", ruserlen, ruser); - - if (retcode == UPAP_AUTHACK) { - pcb->upap.us_serverstate = UPAPSS_OPEN; - ppp_notice("PAP peer authentication succeeded for %q", rhostname); - auth_peer_success(pcb, PPP_PAP, 0, ruser, ruserlen); - } else { - pcb->upap.us_serverstate = UPAPSS_BADAUTH; - ppp_warn("PAP peer authentication failed for %q", rhostname); - auth_peer_fail(pcb, PPP_PAP); - } - - if (pcb->settings.pap_req_timeout > 0) - UNTIMEOUT(upap_reqtimeout, pcb); -} -#endif /* PPP_SERVER */ - -/* - * upap_rauthack - Receive Authenticate-Ack. - */ -static void upap_rauthack(ppp_pcb *pcb, u_char *inp, int id, int len) { - u_char msglen; - char *msg; - LWIP_UNUSED_ARG(id); - - if (pcb->upap.us_clientstate != UPAPCS_AUTHREQ) /* XXX */ - return; - - /* - * Parse message. - */ - if (len < 1) { - UPAPDEBUG(("pap_rauthack: ignoring missing msg-length.")); - } else { - GETCHAR(msglen, inp); - if (msglen > 0) { - len -= sizeof (u_char); - if (len < msglen) { - UPAPDEBUG(("pap_rauthack: rcvd short packet.")); - return; - } - msg = (char *) inp; - PRINTMSG(msg, msglen); - } - } - - pcb->upap.us_clientstate = UPAPCS_OPEN; - - auth_withpeer_success(pcb, PPP_PAP, 0); -} - - -/* - * upap_rauthnak - Receive Authenticate-Nak. - */ -static void upap_rauthnak(ppp_pcb *pcb, u_char *inp, int id, int len) { - u_char msglen; - char *msg; - LWIP_UNUSED_ARG(id); - - if (pcb->upap.us_clientstate != UPAPCS_AUTHREQ) /* XXX */ - return; - - /* - * Parse message. - */ - if (len < 1) { - UPAPDEBUG(("pap_rauthnak: ignoring missing msg-length.")); - } else { - GETCHAR(msglen, inp); - if (msglen > 0) { - len -= sizeof (u_char); - if (len < msglen) { - UPAPDEBUG(("pap_rauthnak: rcvd short packet.")); - return; - } - msg = (char *) inp; - PRINTMSG(msg, msglen); - } - } - - pcb->upap.us_clientstate = UPAPCS_BADAUTH; - - ppp_error("PAP authentication failed"); - auth_withpeer_fail(pcb, PPP_PAP); -} - - -/* - * upap_sauthreq - Send an Authenticate-Request. - */ -static void upap_sauthreq(ppp_pcb *pcb) { - struct pbuf *p; - u_char *outp; - int outlen; - - outlen = UPAP_HEADERLEN + 2 * sizeof (u_char) + - pcb->upap.us_userlen + pcb->upap.us_passwdlen; - p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN +outlen), PPP_CTRL_PBUF_TYPE); - if(NULL == p) - return; - if(p->tot_len != p->len) { - pbuf_free(p); - return; - } - - outp = (u_char*)p->payload; - MAKEHEADER(outp, PPP_PAP); - - PUTCHAR(UPAP_AUTHREQ, outp); - PUTCHAR(++pcb->upap.us_id, outp); - PUTSHORT(outlen, outp); - PUTCHAR(pcb->upap.us_userlen, outp); - MEMCPY(outp, pcb->upap.us_user, pcb->upap.us_userlen); - INCPTR(pcb->upap.us_userlen, outp); - PUTCHAR(pcb->upap.us_passwdlen, outp); - MEMCPY(outp, pcb->upap.us_passwd, pcb->upap.us_passwdlen); - - ppp_write(pcb, p); - - TIMEOUT(upap_timeout, pcb, pcb->settings.pap_timeout_time); - ++pcb->upap.us_transmits; - pcb->upap.us_clientstate = UPAPCS_AUTHREQ; -} - -#if PPP_SERVER -/* - * upap_sresp - Send a response (ack or nak). - */ -static void upap_sresp(ppp_pcb *pcb, u_char code, u_char id, const char *msg, int msglen) { - struct pbuf *p; - u_char *outp; - int outlen; - - outlen = UPAP_HEADERLEN + sizeof (u_char) + msglen; - p = pbuf_alloc(PBUF_RAW, (u16_t)(PPP_HDRLEN +outlen), PPP_CTRL_PBUF_TYPE); - if(NULL == p) - return; - if(p->tot_len != p->len) { - pbuf_free(p); - return; - } - - outp = (u_char*)p->payload; - MAKEHEADER(outp, PPP_PAP); - - PUTCHAR(code, outp); - PUTCHAR(id, outp); - PUTSHORT(outlen, outp); - PUTCHAR(msglen, outp); - MEMCPY(outp, msg, msglen); - - ppp_write(pcb, p); -} -#endif /* PPP_SERVER */ - -#if PRINTPKT_SUPPORT -/* - * upap_printpkt - print the contents of a PAP packet. - */ -static const char* const upap_codenames[] = { - "AuthReq", "AuthAck", "AuthNak" -}; - -static int upap_printpkt(const u_char *p, int plen, void (*printer) (void *, const char *, ...), void *arg) { - int code, id, len; - int mlen, ulen, wlen; - const u_char *user, *pwd, *msg; - const u_char *pstart; - - if (plen < UPAP_HEADERLEN) - return 0; - pstart = p; - GETCHAR(code, p); - GETCHAR(id, p); - GETSHORT(len, p); - if (len < UPAP_HEADERLEN || len > plen) - return 0; - - if (code >= 1 && code <= (int)LWIP_ARRAYSIZE(upap_codenames)) - printer(arg, " %s", upap_codenames[code-1]); - else - printer(arg, " code=0x%x", code); - printer(arg, " id=0x%x", id); - len -= UPAP_HEADERLEN; - switch (code) { - case UPAP_AUTHREQ: - if (len < 1) - break; - ulen = p[0]; - if (len < ulen + 2) - break; - wlen = p[ulen + 1]; - if (len < ulen + wlen + 2) - break; - user = (const u_char *) (p + 1); - pwd = (const u_char *) (p + ulen + 2); - p += ulen + wlen + 2; - len -= ulen + wlen + 2; - printer(arg, " user="); - ppp_print_string(user, ulen, printer, arg); - printer(arg, " password="); -/* FIXME: require ppp_pcb struct as printpkt() argument */ -#if 0 - if (!pcb->settings.hide_password) -#endif - ppp_print_string(pwd, wlen, printer, arg); -#if 0 - else - printer(arg, ""); -#endif - break; - case UPAP_AUTHACK: - case UPAP_AUTHNAK: - if (len < 1) - break; - mlen = p[0]; - if (len < mlen + 1) - break; - msg = (const u_char *) (p + 1); - p += mlen + 1; - len -= mlen + 1; - printer(arg, " "); - ppp_print_string(msg, mlen, printer, arg); - break; - default: - break; - } - - /* print the rest of the bytes in the packet */ - for (; len > 0; --len) { - GETCHAR(code, p); - printer(arg, " %.2x", code); - } - - return p - pstart; -} -#endif /* PRINTPKT_SUPPORT */ - -#endif /* PPP_SUPPORT && PAP_SUPPORT */ diff --git a/third_party/lwip/repo/lwip/src/netif/ppp/utils.c b/third_party/lwip/repo/lwip/src/netif/ppp/utils.c deleted file mode 100644 index 008c63375aa8e0..00000000000000 --- a/third_party/lwip/repo/lwip/src/netif/ppp/utils.c +++ /dev/null @@ -1,959 +0,0 @@ -/* - * utils.c - various utility functions used in pppd. - * - * Copyright (c) 1999-2002 Paul Mackerras. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * 2. The name(s) of the authors of this software must not be used to - * endorse or promote products derived from this software without - * prior written permission. - * - * 3. Redistributions of any form whatsoever must retain the following - * acknowledgment: - * "This product includes software developed by Paul Mackerras - * ". - * - * THE AUTHORS OF THIS SOFTWARE DISCLAIM ALL WARRANTIES WITH REGARD TO - * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS, IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#if 0 /* UNUSED */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#ifdef SVR4 -#include -#endif -#endif /* UNUSED */ - -#include /* isdigit() */ - -#include "netif/ppp/ppp_impl.h" - -#include "netif/ppp/fsm.h" -#include "netif/ppp/lcp.h" - -#if defined(SUNOS4) -extern char *strerror(); -#endif - -static void ppp_logit(int level, const char *fmt, va_list args); -static void ppp_log_write(int level, char *buf); -#if PRINTPKT_SUPPORT -static void ppp_vslp_printer(void *arg, const char *fmt, ...); -static void ppp_format_packet(const u_char *p, int len, - void (*printer) (void *, const char *, ...), void *arg); - -struct buffer_info { - char *ptr; - int len; -}; -#endif /* PRINTPKT_SUPPORT */ - -/* - * ppp_strlcpy - like strcpy/strncpy, doesn't overflow destination buffer, - * always leaves destination null-terminated (for len > 0). - */ -size_t ppp_strlcpy(char *dest, const char *src, size_t len) { - size_t ret = strlen(src); - - if (len != 0) { - if (ret < len) - strcpy(dest, src); - else { - strncpy(dest, src, len - 1); - dest[len-1] = 0; - } - } - return ret; -} - -/* - * ppp_strlcat - like strcat/strncat, doesn't overflow destination buffer, - * always leaves destination null-terminated (for len > 0). - */ -size_t ppp_strlcat(char *dest, const char *src, size_t len) { - size_t dlen = strlen(dest); - - return dlen + ppp_strlcpy(dest + dlen, src, (len > dlen? len - dlen: 0)); -} - - -/* - * ppp_slprintf - format a message into a buffer. Like sprintf except we - * also specify the length of the output buffer, and we handle - * %m (error message), %v (visible string), - * %q (quoted string), %t (current time) and %I (IP address) formats. - * Doesn't do floating-point formats. - * Returns the number of chars put into buf. - */ -int ppp_slprintf(char *buf, int buflen, const char *fmt, ...) { - va_list args; - int n; - - va_start(args, fmt); - n = ppp_vslprintf(buf, buflen, fmt, args); - va_end(args); - return n; -} - -/* - * ppp_vslprintf - like ppp_slprintf, takes a va_list instead of a list of args. - */ -#define OUTCHAR(c) (buflen > 0? (--buflen, *buf++ = (c)): 0) - -int ppp_vslprintf(char *buf, int buflen, const char *fmt, va_list args) { - int c, i, n; - int width, prec, fillch; - int base, len, neg, quoted; - unsigned long val = 0; - const char *f; - char *str, *buf0; - const unsigned char *p; - char num[32]; -#if 0 /* need port */ - time_t t; -#endif /* need port */ - u32_t ip; - static char hexchars[] = "0123456789abcdef"; -#if PRINTPKT_SUPPORT - struct buffer_info bufinfo; -#endif /* PRINTPKT_SUPPORT */ - - buf0 = buf; - --buflen; - while (buflen > 0) { - for (f = fmt; *f != '%' && *f != 0; ++f) - ; - if (f > fmt) { - len = f - fmt; - if (len > buflen) - len = buflen; - memcpy(buf, fmt, len); - buf += len; - buflen -= len; - fmt = f; - } - if (*fmt == 0) - break; - c = *++fmt; - width = 0; - prec = -1; - fillch = ' '; - if (c == '0') { - fillch = '0'; - c = *++fmt; - } - if (c == '*') { - width = va_arg(args, int); - c = *++fmt; - } else { - while (isdigit(c)) { - width = width * 10 + c - '0'; - c = *++fmt; - } - } - if (c == '.') { - c = *++fmt; - if (c == '*') { - prec = va_arg(args, int); - c = *++fmt; - } else { - prec = 0; - while (isdigit(c)) { - prec = prec * 10 + c - '0'; - c = *++fmt; - } - } - } - str = 0; - base = 0; - neg = 0; - ++fmt; - switch (c) { - case 'l': - c = *fmt++; - switch (c) { - case 'd': - val = va_arg(args, long); - if ((long)val < 0) { - neg = 1; - val = (unsigned long)-(long)val; - } - base = 10; - break; - case 'u': - val = va_arg(args, unsigned long); - base = 10; - break; - default: - OUTCHAR('%'); - OUTCHAR('l'); - --fmt; /* so %lz outputs %lz etc. */ - continue; - } - break; - case 'd': - i = va_arg(args, int); - if (i < 0) { - neg = 1; - val = -i; - } else - val = i; - base = 10; - break; - case 'u': - val = va_arg(args, unsigned int); - base = 10; - break; - case 'o': - val = va_arg(args, unsigned int); - base = 8; - break; - case 'x': - case 'X': - val = va_arg(args, unsigned int); - base = 16; - break; -#if 0 /* unused (and wrong on LLP64 systems) */ - case 'p': - val = (unsigned long) va_arg(args, void *); - base = 16; - neg = 2; - break; -#endif /* unused (and wrong on LLP64 systems) */ - case 's': - str = va_arg(args, char *); - break; - case 'c': - num[0] = va_arg(args, int); - num[1] = 0; - str = num; - break; -#if 0 /* do we always have strerror() in embedded ? */ - case 'm': - str = strerror(errno); - break; -#endif /* do we always have strerror() in embedded ? */ - case 'I': - ip = va_arg(args, u32_t); - ip = lwip_ntohl(ip); - ppp_slprintf(num, sizeof(num), "%d.%d.%d.%d", (ip >> 24) & 0xff, - (ip >> 16) & 0xff, (ip >> 8) & 0xff, ip & 0xff); - str = num; - break; -#if 0 /* need port */ - case 't': - time(&t); - str = ctime(&t); - str += 4; /* chop off the day name */ - str[15] = 0; /* chop off year and newline */ - break; -#endif /* need port */ - case 'v': /* "visible" string */ - case 'q': /* quoted string */ - quoted = c == 'q'; - p = va_arg(args, unsigned char *); - if (p == NULL) - p = (const unsigned char *)""; - if (fillch == '0' && prec >= 0) { - n = prec; - } else { - n = strlen((const char *)p); - if (prec >= 0 && n > prec) - n = prec; - } - while (n > 0 && buflen > 0) { - c = *p++; - --n; - if (!quoted && c >= 0x80) { - OUTCHAR('M'); - OUTCHAR('-'); - c -= 0x80; - } - if (quoted && (c == '"' || c == '\\')) - OUTCHAR('\\'); - if (c < 0x20 || (0x7f <= c && c < 0xa0)) { - if (quoted) { - OUTCHAR('\\'); - switch (c) { - case '\t': OUTCHAR('t'); break; - case '\n': OUTCHAR('n'); break; - case '\b': OUTCHAR('b'); break; - case '\f': OUTCHAR('f'); break; - default: - OUTCHAR('x'); - OUTCHAR(hexchars[c >> 4]); - OUTCHAR(hexchars[c & 0xf]); - } - } else { - if (c == '\t') - OUTCHAR(c); - else { - OUTCHAR('^'); - OUTCHAR(c ^ 0x40); - } - } - } else - OUTCHAR(c); - } - continue; -#if PRINTPKT_SUPPORT - case 'P': /* print PPP packet */ - bufinfo.ptr = buf; - bufinfo.len = buflen + 1; - p = va_arg(args, unsigned char *); - n = va_arg(args, int); - ppp_format_packet(p, n, ppp_vslp_printer, &bufinfo); - buf = bufinfo.ptr; - buflen = bufinfo.len - 1; - continue; -#endif /* PRINTPKT_SUPPORT */ - case 'B': - p = va_arg(args, unsigned char *); - for (n = prec; n > 0; --n) { - c = *p++; - if (fillch == ' ') - OUTCHAR(' '); - OUTCHAR(hexchars[(c >> 4) & 0xf]); - OUTCHAR(hexchars[c & 0xf]); - } - continue; - default: - *buf++ = '%'; - if (c != '%') - --fmt; /* so %z outputs %z etc. */ - --buflen; - continue; - } - if (base != 0) { - str = num + sizeof(num); - *--str = 0; - while (str > num + neg) { - *--str = hexchars[val % base]; - val = val / base; - if (--prec <= 0 && val == 0) - break; - } - switch (neg) { - case 1: - *--str = '-'; - break; - case 2: - *--str = 'x'; - *--str = '0'; - break; - default: - break; - } - len = num + sizeof(num) - 1 - str; - } else { - len = strlen(str); - if (prec >= 0 && len > prec) - len = prec; - } - if (width > 0) { - if (width > buflen) - width = buflen; - if ((n = width - len) > 0) { - buflen -= n; - for (; n > 0; --n) - *buf++ = fillch; - } - } - if (len > buflen) - len = buflen; - memcpy(buf, str, len); - buf += len; - buflen -= len; - } - *buf = 0; - return buf - buf0; -} - -#if PRINTPKT_SUPPORT -/* - * vslp_printer - used in processing a %P format - */ -static void ppp_vslp_printer(void *arg, const char *fmt, ...) { - int n; - va_list pvar; - struct buffer_info *bi; - - va_start(pvar, fmt); - bi = (struct buffer_info *) arg; - n = ppp_vslprintf(bi->ptr, bi->len, fmt, pvar); - va_end(pvar); - - bi->ptr += n; - bi->len -= n; -} -#endif /* PRINTPKT_SUPPORT */ - -#if 0 /* UNUSED */ -/* - * log_packet - format a packet and log it. - */ - -void -log_packet(p, len, prefix, level) - u_char *p; - int len; - char *prefix; - int level; -{ - init_pr_log(prefix, level); - ppp_format_packet(p, len, pr_log, &level); - end_pr_log(); -} -#endif /* UNUSED */ - -#if PRINTPKT_SUPPORT -/* - * ppp_format_packet - make a readable representation of a packet, - * calling `printer(arg, format, ...)' to output it. - */ -static void ppp_format_packet(const u_char *p, int len, - void (*printer) (void *, const char *, ...), void *arg) { - int i, n; - u_short proto; - const struct protent *protp; - - if (len >= 2) { - GETSHORT(proto, p); - len -= 2; - for (i = 0; (protp = protocols[i]) != NULL; ++i) - if (proto == protp->protocol) - break; - if (protp != NULL) { - printer(arg, "[%s", protp->name); - n = (*protp->printpkt)(p, len, printer, arg); - printer(arg, "]"); - p += n; - len -= n; - } else { - for (i = 0; (protp = protocols[i]) != NULL; ++i) - if (proto == (protp->protocol & ~0x8000)) - break; - if (protp != 0 && protp->data_name != 0) { - printer(arg, "[%s data]", protp->data_name); - if (len > 8) - printer(arg, "%.8B ...", p); - else - printer(arg, "%.*B", len, p); - len = 0; - } else - printer(arg, "[proto=0x%x]", proto); - } - } - - if (len > 32) - printer(arg, "%.32B ...", p); - else - printer(arg, "%.*B", len, p); -} -#endif /* PRINTPKT_SUPPORT */ - -#if 0 /* UNUSED */ -/* - * init_pr_log, end_pr_log - initialize and finish use of pr_log. - */ - -static char line[256]; /* line to be logged accumulated here */ -static char *linep; /* current pointer within line */ -static int llevel; /* level for logging */ - -void -init_pr_log(prefix, level) - const char *prefix; - int level; -{ - linep = line; - if (prefix != NULL) { - ppp_strlcpy(line, prefix, sizeof(line)); - linep = line + strlen(line); - } - llevel = level; -} - -void -end_pr_log() -{ - if (linep != line) { - *linep = 0; - ppp_log_write(llevel, line); - } -} - -/* - * pr_log - printer routine for outputting to log - */ -void -pr_log (void *arg, const char *fmt, ...) -{ - int l, n; - va_list pvar; - char *p, *eol; - char buf[256]; - - va_start(pvar, fmt); - n = ppp_vslprintf(buf, sizeof(buf), fmt, pvar); - va_end(pvar); - - p = buf; - eol = strchr(buf, '\n'); - if (linep != line) { - l = (eol == NULL)? n: eol - buf; - if (linep + l < line + sizeof(line)) { - if (l > 0) { - memcpy(linep, buf, l); - linep += l; - } - if (eol == NULL) - return; - p = eol + 1; - eol = strchr(p, '\n'); - } - *linep = 0; - ppp_log_write(llevel, line); - linep = line; - } - - while (eol != NULL) { - *eol = 0; - ppp_log_write(llevel, p); - p = eol + 1; - eol = strchr(p, '\n'); - } - - /* assumes sizeof(buf) <= sizeof(line) */ - l = buf + n - p; - if (l > 0) { - memcpy(line, p, n); - linep = line + l; - } -} -#endif /* UNUSED */ - -/* - * ppp_print_string - print a readable representation of a string using - * printer. - */ -void ppp_print_string(const u_char *p, int len, void (*printer) (void *, const char *, ...), void *arg) { - int c; - - printer(arg, "\""); - for (; len > 0; --len) { - c = *p++; - if (' ' <= c && c <= '~') { - if (c == '\\' || c == '"') - printer(arg, "\\"); - printer(arg, "%c", c); - } else { - switch (c) { - case '\n': - printer(arg, "\\n"); - break; - case '\r': - printer(arg, "\\r"); - break; - case '\t': - printer(arg, "\\t"); - break; - default: - printer(arg, "\\%.3o", (u8_t)c); - /* no break */ - } - } - } - printer(arg, "\""); -} - -/* - * ppp_logit - does the hard work for fatal et al. - */ -static void ppp_logit(int level, const char *fmt, va_list args) { - char buf[1024]; - - ppp_vslprintf(buf, sizeof(buf), fmt, args); - ppp_log_write(level, buf); -} - -static void ppp_log_write(int level, char *buf) { - LWIP_UNUSED_ARG(level); /* necessary if PPPDEBUG is defined to an empty function */ - LWIP_UNUSED_ARG(buf); - PPPDEBUG(level, ("%s\n", buf) ); -#if 0 - if (log_to_fd >= 0 && (level != LOG_DEBUG || debug)) { - int n = strlen(buf); - - if (n > 0 && buf[n-1] == '\n') - --n; - if (write(log_to_fd, buf, n) != n - || write(log_to_fd, "\n", 1) != 1) - log_to_fd = -1; - } -#endif -} - -/* - * ppp_fatal - log an error message and die horribly. - */ -void ppp_fatal(const char *fmt, ...) { - va_list pvar; - - va_start(pvar, fmt); - ppp_logit(LOG_ERR, fmt, pvar); - va_end(pvar); - - LWIP_ASSERT("ppp_fatal", 0); /* as promised */ -} - -/* - * ppp_error - log an error message. - */ -void ppp_error(const char *fmt, ...) { - va_list pvar; - - va_start(pvar, fmt); - ppp_logit(LOG_ERR, fmt, pvar); - va_end(pvar); -#if 0 /* UNUSED */ - ++error_count; -#endif /* UNUSED */ -} - -/* - * ppp_warn - log a warning message. - */ -void ppp_warn(const char *fmt, ...) { - va_list pvar; - - va_start(pvar, fmt); - ppp_logit(LOG_WARNING, fmt, pvar); - va_end(pvar); -} - -/* - * ppp_notice - log a notice-level message. - */ -void ppp_notice(const char *fmt, ...) { - va_list pvar; - - va_start(pvar, fmt); - ppp_logit(LOG_NOTICE, fmt, pvar); - va_end(pvar); -} - -/* - * ppp_info - log an informational message. - */ -void ppp_info(const char *fmt, ...) { - va_list pvar; - - va_start(pvar, fmt); - ppp_logit(LOG_INFO, fmt, pvar); - va_end(pvar); -} - -/* - * ppp_dbglog - log a debug message. - */ -void ppp_dbglog(const char *fmt, ...) { - va_list pvar; - - va_start(pvar, fmt); - ppp_logit(LOG_DEBUG, fmt, pvar); - va_end(pvar); -} - -#if PRINTPKT_SUPPORT -/* - * ppp_dump_packet - print out a packet in readable form if it is interesting. - * Assumes len >= PPP_HDRLEN. - */ -void ppp_dump_packet(ppp_pcb *pcb, const char *tag, unsigned char *p, int len) { - int proto; - - /* - * don't print data packets, i.e. IPv4, IPv6, VJ, and compressed packets. - */ - proto = (p[0] << 8) + p[1]; - if (proto < 0xC000 && (proto & ~0x8000) == proto) - return; - - /* - * don't print valid LCP echo request/reply packets if the link is up. - */ - if (proto == PPP_LCP && pcb->phase == PPP_PHASE_RUNNING && len >= 2 + HEADERLEN) { - unsigned char *lcp = p + 2; - int l = (lcp[2] << 8) + lcp[3]; - - if ((lcp[0] == ECHOREQ || lcp[0] == ECHOREP) - && l >= HEADERLEN && l <= len - 2) - return; - } - - ppp_dbglog("%s %P", tag, p, len); -} -#endif /* PRINTPKT_SUPPORT */ - -#if 0 /* Unused */ - -/* - * complete_read - read a full `count' bytes from fd, - * unless end-of-file or an error other than EINTR is encountered. - */ -ssize_t -complete_read(int fd, void *buf, size_t count) -{ - size_t done; - ssize_t nb; - char *ptr = buf; - - for (done = 0; done < count; ) { - nb = read(fd, ptr, count - done); - if (nb < 0) { - if (errno == EINTR) - continue; - return -1; - } - if (nb == 0) - break; - done += nb; - ptr += nb; - } - return done; -} - -/* Procedures for locking the serial device using a lock file. */ -#ifndef LOCK_DIR -#ifdef __linux__ -#define LOCK_DIR "/var/lock" -#else -#ifdef SVR4 -#define LOCK_DIR "/var/spool/locks" -#else -#define LOCK_DIR "/var/spool/lock" -#endif -#endif -#endif /* LOCK_DIR */ - -static char lock_file[MAXPATHLEN]; - -/* - * lock - create a lock file for the named device - */ -int -lock(dev) - char *dev; -{ -#ifdef LOCKLIB - int result; - - result = mklock (dev, (void *) 0); - if (result == 0) { - ppp_strlcpy(lock_file, dev, sizeof(lock_file)); - return 0; - } - - if (result > 0) - ppp_notice("Device %s is locked by pid %d", dev, result); - else - ppp_error("Can't create lock file %s", lock_file); - return -1; - -#else /* LOCKLIB */ - - char lock_buffer[12]; - int fd, pid, n; - -#ifdef SVR4 - struct stat sbuf; - - if (stat(dev, &sbuf) < 0) { - ppp_error("Can't get device number for %s: %m", dev); - return -1; - } - if ((sbuf.st_mode & S_IFMT) != S_IFCHR) { - ppp_error("Can't lock %s: not a character device", dev); - return -1; - } - ppp_slprintf(lock_file, sizeof(lock_file), "%s/LK.%03d.%03d.%03d", - LOCK_DIR, major(sbuf.st_dev), - major(sbuf.st_rdev), minor(sbuf.st_rdev)); -#else - char *p; - char lockdev[MAXPATHLEN]; - - if ((p = strstr(dev, "dev/")) != NULL) { - dev = p + 4; - strncpy(lockdev, dev, MAXPATHLEN-1); - lockdev[MAXPATHLEN-1] = 0; - while ((p = strrchr(lockdev, '/')) != NULL) { - *p = '_'; - } - dev = lockdev; - } else - if ((p = strrchr(dev, '/')) != NULL) - dev = p + 1; - - ppp_slprintf(lock_file, sizeof(lock_file), "%s/LCK..%s", LOCK_DIR, dev); -#endif - - while ((fd = open(lock_file, O_EXCL | O_CREAT | O_RDWR, 0644)) < 0) { - if (errno != EEXIST) { - ppp_error("Can't create lock file %s: %m", lock_file); - break; - } - - /* Read the lock file to find out who has the device locked. */ - fd = open(lock_file, O_RDONLY, 0); - if (fd < 0) { - if (errno == ENOENT) /* This is just a timing problem. */ - continue; - ppp_error("Can't open existing lock file %s: %m", lock_file); - break; - } -#ifndef LOCK_BINARY - n = read(fd, lock_buffer, 11); -#else - n = read(fd, &pid, sizeof(pid)); -#endif /* LOCK_BINARY */ - close(fd); - fd = -1; - if (n <= 0) { - ppp_error("Can't read pid from lock file %s", lock_file); - break; - } - - /* See if the process still exists. */ -#ifndef LOCK_BINARY - lock_buffer[n] = 0; - pid = atoi(lock_buffer); -#endif /* LOCK_BINARY */ - if (pid == getpid()) - return 1; /* somebody else locked it for us */ - if (pid == 0 - || (kill(pid, 0) == -1 && errno == ESRCH)) { - if (unlink (lock_file) == 0) { - ppp_notice("Removed stale lock on %s (pid %d)", dev, pid); - continue; - } - ppp_warn("Couldn't remove stale lock on %s", dev); - } else - ppp_notice("Device %s is locked by pid %d", dev, pid); - break; - } - - if (fd < 0) { - lock_file[0] = 0; - return -1; - } - - pid = getpid(); -#ifndef LOCK_BINARY - ppp_slprintf(lock_buffer, sizeof(lock_buffer), "%10d\n", pid); - write (fd, lock_buffer, 11); -#else - write(fd, &pid, sizeof (pid)); -#endif - close(fd); - return 0; - -#endif -} - -/* - * relock - called to update our lockfile when we are about to detach, - * thus changing our pid (we fork, the child carries on, and the parent dies). - * Note that this is called by the parent, with pid equal to the pid - * of the child. This avoids a potential race which would exist if - * we had the child rewrite the lockfile (the parent might die first, - * and another process could think the lock was stale if it checked - * between when the parent died and the child rewrote the lockfile). - */ -int -relock(pid) - int pid; -{ -#ifdef LOCKLIB - /* XXX is there a way to do this? */ - return -1; -#else /* LOCKLIB */ - - int fd; - char lock_buffer[12]; - - if (lock_file[0] == 0) - return -1; - fd = open(lock_file, O_WRONLY, 0); - if (fd < 0) { - ppp_error("Couldn't reopen lock file %s: %m", lock_file); - lock_file[0] = 0; - return -1; - } - -#ifndef LOCK_BINARY - ppp_slprintf(lock_buffer, sizeof(lock_buffer), "%10d\n", pid); - write (fd, lock_buffer, 11); -#else - write(fd, &pid, sizeof(pid)); -#endif /* LOCK_BINARY */ - close(fd); - return 0; - -#endif /* LOCKLIB */ -} - -/* - * unlock - remove our lockfile - */ -void -unlock() -{ - if (lock_file[0]) { -#ifdef LOCKLIB - (void) rmlock(lock_file, (void *) 0); -#else - unlink(lock_file); -#endif - lock_file[0] = 0; - } -} - -#endif /* Unused */ - -#endif /* PPP_SUPPORT */ diff --git a/third_party/lwip/repo/lwip/src/netif/ppp/vj.c b/third_party/lwip/repo/lwip/src/netif/ppp/vj.c deleted file mode 100644 index 3b3031487c385b..00000000000000 --- a/third_party/lwip/repo/lwip/src/netif/ppp/vj.c +++ /dev/null @@ -1,695 +0,0 @@ -/* - * Routines to compress and uncompess tcp packets (for transmission - * over low speed serial lines. - * - * Copyright (c) 1989 Regents of the University of California. - * All rights reserved. - * - * Redistribution and use in source and binary forms are permitted - * provided that the above copyright notice and this paragraph are - * duplicated in all such forms and that any documentation, - * advertising materials, and other materials related to such - * distribution and use acknowledge that the software was developed - * by the University of California, Berkeley. The name of the - * University may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED - * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. - * - * Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989: - * Initial distribution. - * - * Modified June 1993 by Paul Mackerras, paulus@cs.anu.edu.au, - * so that the entire packet being decompressed doesn't have - * to be in contiguous memory (just the compressed header). - * - * Modified March 1998 by Guy Lancaster, glanca@gesn.com, - * for a 16 bit processor. - */ - -#include "netif/ppp/ppp_opts.h" -#if PPP_SUPPORT && VJ_SUPPORT /* don't build if not configured for use in lwipopts.h */ - -#include "netif/ppp/ppp_impl.h" -#include "netif/ppp/pppdebug.h" - -#include "netif/ppp/vj.h" - -#include - -#if LINK_STATS -#define INCR(counter) ++comp->stats.counter -#else -#define INCR(counter) -#endif - -void -vj_compress_init(struct vjcompress *comp) -{ - u8_t i; - struct cstate *tstate = comp->tstate; - -#if MAX_SLOTS == 0 - memset((char *)comp, 0, sizeof(*comp)); -#endif - comp->maxSlotIndex = MAX_SLOTS - 1; - comp->compressSlot = 0; /* Disable slot ID compression by default. */ - for (i = MAX_SLOTS - 1; i > 0; --i) { - tstate[i].cs_id = i; - tstate[i].cs_next = &tstate[i - 1]; - } - tstate[0].cs_next = &tstate[MAX_SLOTS - 1]; - tstate[0].cs_id = 0; - comp->last_cs = &tstate[0]; - comp->last_recv = 255; - comp->last_xmit = 255; - comp->flags = VJF_TOSS; -} - - -/* ENCODE encodes a number that is known to be non-zero. ENCODEZ - * checks for zero (since zero has to be encoded in the long, 3 byte - * form). - */ -#define ENCODE(n) { \ - if ((u16_t)(n) >= 256) { \ - *cp++ = 0; \ - cp[1] = (u8_t)(n); \ - cp[0] = (u8_t)((n) >> 8); \ - cp += 2; \ - } else { \ - *cp++ = (u8_t)(n); \ - } \ -} -#define ENCODEZ(n) { \ - if ((u16_t)(n) >= 256 || (u16_t)(n) == 0) { \ - *cp++ = 0; \ - cp[1] = (u8_t)(n); \ - cp[0] = (u8_t)((n) >> 8); \ - cp += 2; \ - } else { \ - *cp++ = (u8_t)(n); \ - } \ -} - -#define DECODEL(f) { \ - if (*cp == 0) {\ - u32_t tmp_ = lwip_ntohl(f) + ((cp[1] << 8) | cp[2]); \ - (f) = lwip_htonl(tmp_); \ - cp += 3; \ - } else { \ - u32_t tmp_ = lwip_ntohl(f) + (u32_t)*cp++; \ - (f) = lwip_htonl(tmp_); \ - } \ -} - -#define DECODES(f) { \ - if (*cp == 0) {\ - u16_t tmp_ = lwip_ntohs(f) + (((u16_t)cp[1] << 8) | cp[2]); \ - (f) = lwip_htons(tmp_); \ - cp += 3; \ - } else { \ - u16_t tmp_ = lwip_ntohs(f) + (u16_t)*cp++; \ - (f) = lwip_htons(tmp_); \ - } \ -} - -#define DECODEU(f) { \ - if (*cp == 0) {\ - (f) = lwip_htons(((u16_t)cp[1] << 8) | cp[2]); \ - cp += 3; \ - } else { \ - (f) = lwip_htons((u16_t)*cp++); \ - } \ -} - -/* Helper structures for unaligned *u32_t and *u16_t accesses */ -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct vj_u32_t { - PACK_STRUCT_FIELD(u32_t v); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/bpstruct.h" -#endif -PACK_STRUCT_BEGIN -struct vj_u16_t { - PACK_STRUCT_FIELD(u16_t v); -} PACK_STRUCT_STRUCT; -PACK_STRUCT_END -#ifdef PACK_STRUCT_USE_INCLUDES -# include "arch/epstruct.h" -#endif - -/* - * vj_compress_tcp - Attempt to do Van Jacobson header compression on a - * packet. This assumes that nb and comp are not null and that the first - * buffer of the chain contains a valid IP header. - * Return the VJ type code indicating whether or not the packet was - * compressed. - */ -u8_t -vj_compress_tcp(struct vjcompress *comp, struct pbuf **pb) -{ - struct pbuf *np = *pb; - struct ip_hdr *ip = (struct ip_hdr *)np->payload; - struct cstate *cs = comp->last_cs->cs_next; - u16_t ilen = IPH_HL(ip); - u16_t hlen; - struct tcp_hdr *oth; - struct tcp_hdr *th; - u16_t deltaS, deltaA = 0; - u32_t deltaL; - u32_t changes = 0; - u8_t new_seq[16]; - u8_t *cp = new_seq; - - /* - * Check that the packet is IP proto TCP. - */ - if (IPH_PROTO(ip) != IP_PROTO_TCP) { - return (TYPE_IP); - } - - /* - * Bail if this is an IP fragment or if the TCP packet isn't - * `compressible' (i.e., ACK isn't set or some other control bit is - * set). - */ - if ((IPH_OFFSET(ip) & PP_HTONS(0x3fff)) || np->tot_len < 40) { - return (TYPE_IP); - } - th = (struct tcp_hdr *)&((struct vj_u32_t*)ip)[ilen]; - if ((TCPH_FLAGS(th) & (TCP_SYN|TCP_FIN|TCP_RST|TCP_ACK)) != TCP_ACK) { - return (TYPE_IP); - } - - /* Check that the TCP/IP headers are contained in the first buffer. */ - hlen = ilen + TCPH_HDRLEN(th); - hlen <<= 2; - if (np->len < hlen) { - PPPDEBUG(LOG_INFO, ("vj_compress_tcp: header len %d spans buffers\n", hlen)); - return (TYPE_IP); - } - - /* TCP stack requires that we don't change the packet payload, therefore we copy - * the whole packet before compression. */ - np = pbuf_alloc(PBUF_RAW, np->tot_len, PBUF_POOL); - if (!np) { - return (TYPE_IP); - } - - if (pbuf_copy(np, *pb) != ERR_OK) { - pbuf_free(np); - return (TYPE_IP); - } - - *pb = np; - ip = (struct ip_hdr *)np->payload; - - /* - * Packet is compressible -- we're going to send either a - * COMPRESSED_TCP or UNCOMPRESSED_TCP packet. Either way we need - * to locate (or create) the connection state. Special case the - * most recently used connection since it's most likely to be used - * again & we don't have to do any reordering if it's used. - */ - INCR(vjs_packets); - if (!ip4_addr_cmp(&ip->src, &cs->cs_ip.src) - || !ip4_addr_cmp(&ip->dest, &cs->cs_ip.dest) - || (*(struct vj_u32_t*)th).v != (((struct vj_u32_t*)&cs->cs_ip)[IPH_HL(&cs->cs_ip)]).v) { - /* - * Wasn't the first -- search for it. - * - * States are kept in a circularly linked list with - * last_cs pointing to the end of the list. The - * list is kept in lru order by moving a state to the - * head of the list whenever it is referenced. Since - * the list is short and, empirically, the connection - * we want is almost always near the front, we locate - * states via linear search. If we don't find a state - * for the datagram, the oldest state is (re-)used. - */ - struct cstate *lcs; - struct cstate *lastcs = comp->last_cs; - - do { - lcs = cs; cs = cs->cs_next; - INCR(vjs_searches); - if (ip4_addr_cmp(&ip->src, &cs->cs_ip.src) - && ip4_addr_cmp(&ip->dest, &cs->cs_ip.dest) - && (*(struct vj_u32_t*)th).v == (((struct vj_u32_t*)&cs->cs_ip)[IPH_HL(&cs->cs_ip)]).v) { - goto found; - } - } while (cs != lastcs); - - /* - * Didn't find it -- re-use oldest cstate. Send an - * uncompressed packet that tells the other side what - * connection number we're using for this conversation. - * Note that since the state list is circular, the oldest - * state points to the newest and we only need to set - * last_cs to update the lru linkage. - */ - INCR(vjs_misses); - comp->last_cs = lcs; - goto uncompressed; - - found: - /* - * Found it -- move to the front on the connection list. - */ - if (cs == lastcs) { - comp->last_cs = lcs; - } else { - lcs->cs_next = cs->cs_next; - cs->cs_next = lastcs->cs_next; - lastcs->cs_next = cs; - } - } - - oth = (struct tcp_hdr *)&((struct vj_u32_t*)&cs->cs_ip)[ilen]; - deltaS = ilen; - - /* - * Make sure that only what we expect to change changed. The first - * line of the `if' checks the IP protocol version, header length & - * type of service. The 2nd line checks the "Don't fragment" bit. - * The 3rd line checks the time-to-live and protocol (the protocol - * check is unnecessary but costless). The 4th line checks the TCP - * header length. The 5th line checks IP options, if any. The 6th - * line checks TCP options, if any. If any of these things are - * different between the previous & current datagram, we send the - * current datagram `uncompressed'. - */ - if ((((struct vj_u16_t*)ip)[0]).v != (((struct vj_u16_t*)&cs->cs_ip)[0]).v - || (((struct vj_u16_t*)ip)[3]).v != (((struct vj_u16_t*)&cs->cs_ip)[3]).v - || (((struct vj_u16_t*)ip)[4]).v != (((struct vj_u16_t*)&cs->cs_ip)[4]).v - || TCPH_HDRLEN(th) != TCPH_HDRLEN(oth) - || (deltaS > 5 && BCMP(ip + 1, &cs->cs_ip + 1, (deltaS - 5) << 2)) - || (TCPH_HDRLEN(th) > 5 && BCMP(th + 1, oth + 1, (TCPH_HDRLEN(th) - 5) << 2))) { - goto uncompressed; - } - - /* - * Figure out which of the changing fields changed. The - * receiver expects changes in the order: urgent, window, - * ack, seq (the order minimizes the number of temporaries - * needed in this section of code). - */ - if (TCPH_FLAGS(th) & TCP_URG) { - deltaS = lwip_ntohs(th->urgp); - ENCODEZ(deltaS); - changes |= NEW_U; - } else if (th->urgp != oth->urgp) { - /* argh! URG not set but urp changed -- a sensible - * implementation should never do this but RFC793 - * doesn't prohibit the change so we have to deal - * with it. */ - goto uncompressed; - } - - if ((deltaS = (u16_t)(lwip_ntohs(th->wnd) - lwip_ntohs(oth->wnd))) != 0) { - ENCODE(deltaS); - changes |= NEW_W; - } - - if ((deltaL = lwip_ntohl(th->ackno) - lwip_ntohl(oth->ackno)) != 0) { - if (deltaL > 0xffff) { - goto uncompressed; - } - deltaA = (u16_t)deltaL; - ENCODE(deltaA); - changes |= NEW_A; - } - - if ((deltaL = lwip_ntohl(th->seqno) - lwip_ntohl(oth->seqno)) != 0) { - if (deltaL > 0xffff) { - goto uncompressed; - } - deltaS = (u16_t)deltaL; - ENCODE(deltaS); - changes |= NEW_S; - } - - switch(changes) { - case 0: - /* - * Nothing changed. If this packet contains data and the - * last one didn't, this is probably a data packet following - * an ack (normal on an interactive connection) and we send - * it compressed. Otherwise it's probably a retransmit, - * retransmitted ack or window probe. Send it uncompressed - * in case the other side missed the compressed version. - */ - if (IPH_LEN(ip) != IPH_LEN(&cs->cs_ip) && - lwip_ntohs(IPH_LEN(&cs->cs_ip)) == hlen) { - break; - } - /* no break */ - /* fall through */ - - case SPECIAL_I: - case SPECIAL_D: - /* - * actual changes match one of our special case encodings -- - * send packet uncompressed. - */ - goto uncompressed; - - case NEW_S|NEW_A: - if (deltaS == deltaA && deltaS == lwip_ntohs(IPH_LEN(&cs->cs_ip)) - hlen) { - /* special case for echoed terminal traffic */ - changes = SPECIAL_I; - cp = new_seq; - } - break; - - case NEW_S: - if (deltaS == lwip_ntohs(IPH_LEN(&cs->cs_ip)) - hlen) { - /* special case for data xfer */ - changes = SPECIAL_D; - cp = new_seq; - } - break; - default: - break; - } - - deltaS = (u16_t)(lwip_ntohs(IPH_ID(ip)) - lwip_ntohs(IPH_ID(&cs->cs_ip))); - if (deltaS != 1) { - ENCODEZ(deltaS); - changes |= NEW_I; - } - if (TCPH_FLAGS(th) & TCP_PSH) { - changes |= TCP_PUSH_BIT; - } - /* - * Grab the cksum before we overwrite it below. Then update our - * state with this packet's header. - */ - deltaA = lwip_ntohs(th->chksum); - MEMCPY(&cs->cs_ip, ip, hlen); - - /* - * We want to use the original packet as our compressed packet. - * (cp - new_seq) is the number of bytes we need for compressed - * sequence numbers. In addition we need one byte for the change - * mask, one for the connection id and two for the tcp checksum. - * So, (cp - new_seq) + 4 bytes of header are needed. hlen is how - * many bytes of the original packet to toss so subtract the two to - * get the new packet size. - */ - deltaS = (u16_t)(cp - new_seq); - if (!comp->compressSlot || comp->last_xmit != cs->cs_id) { - comp->last_xmit = cs->cs_id; - hlen -= deltaS + 4; - if (pbuf_header(np, -(s16_t)hlen)){ - /* Can we cope with this failing? Just assert for now */ - LWIP_ASSERT("pbuf_header failed\n", 0); - } - cp = (u8_t*)np->payload; - *cp++ = (u8_t)(changes | NEW_C); - *cp++ = cs->cs_id; - } else { - hlen -= deltaS + 3; - if (pbuf_header(np, -(s16_t)hlen)) { - /* Can we cope with this failing? Just assert for now */ - LWIP_ASSERT("pbuf_header failed\n", 0); - } - cp = (u8_t*)np->payload; - *cp++ = (u8_t)changes; - } - *cp++ = (u8_t)(deltaA >> 8); - *cp++ = (u8_t)deltaA; - MEMCPY(cp, new_seq, deltaS); - INCR(vjs_compressed); - return (TYPE_COMPRESSED_TCP); - - /* - * Update connection state cs & send uncompressed packet (that is, - * a regular ip/tcp packet but with the 'conversation id' we hope - * to use on future compressed packets in the protocol field). - */ -uncompressed: - MEMCPY(&cs->cs_ip, ip, hlen); - IPH_PROTO_SET(ip, cs->cs_id); - comp->last_xmit = cs->cs_id; - return (TYPE_UNCOMPRESSED_TCP); -} - -/* - * Called when we may have missed a packet. - */ -void -vj_uncompress_err(struct vjcompress *comp) -{ - comp->flags |= VJF_TOSS; - INCR(vjs_errorin); -} - -/* - * "Uncompress" a packet of type TYPE_UNCOMPRESSED_TCP. - * Return 0 on success, -1 on failure. - */ -int -vj_uncompress_uncomp(struct pbuf *nb, struct vjcompress *comp) -{ - u32_t hlen; - struct cstate *cs; - struct ip_hdr *ip; - - ip = (struct ip_hdr *)nb->payload; - hlen = IPH_HL(ip) << 2; - if (IPH_PROTO(ip) >= MAX_SLOTS - || hlen + sizeof(struct tcp_hdr) > nb->len - || (hlen += TCPH_HDRLEN_BYTES((struct tcp_hdr *)&((char *)ip)[hlen])) - > nb->len - || hlen > MAX_HDR) { - PPPDEBUG(LOG_INFO, ("vj_uncompress_uncomp: bad cid=%d, hlen=%d buflen=%d\n", - IPH_PROTO(ip), hlen, nb->len)); - comp->flags |= VJF_TOSS; - INCR(vjs_errorin); - return -1; - } - cs = &comp->rstate[comp->last_recv = IPH_PROTO(ip)]; - comp->flags &=~ VJF_TOSS; - IPH_PROTO_SET(ip, IP_PROTO_TCP); - MEMCPY(&cs->cs_ip, ip, hlen); - cs->cs_hlen = (u16_t)hlen; - INCR(vjs_uncompressedin); - return 0; -} - -/* - * Uncompress a packet of type TYPE_COMPRESSED_TCP. - * The packet is composed of a buffer chain and the first buffer - * must contain an accurate chain length. - * The first buffer must include the entire compressed TCP/IP header. - * This procedure replaces the compressed header with the uncompressed - * header and returns the length of the VJ header. - */ -int -vj_uncompress_tcp(struct pbuf **nb, struct vjcompress *comp) -{ - u8_t *cp; - struct tcp_hdr *th; - struct cstate *cs; - struct vj_u16_t *bp; - struct pbuf *n0 = *nb; - u32_t tmp; - u32_t vjlen, hlen, changes; - - INCR(vjs_compressedin); - cp = (u8_t*)n0->payload; - changes = *cp++; - if (changes & NEW_C) { - /* - * Make sure the state index is in range, then grab the state. - * If we have a good state index, clear the 'discard' flag. - */ - if (*cp >= MAX_SLOTS) { - PPPDEBUG(LOG_INFO, ("vj_uncompress_tcp: bad cid=%d\n", *cp)); - goto bad; - } - - comp->flags &=~ VJF_TOSS; - comp->last_recv = *cp++; - } else { - /* - * this packet has an implicit state index. If we've - * had a line error since the last time we got an - * explicit state index, we have to toss the packet. - */ - if (comp->flags & VJF_TOSS) { - PPPDEBUG(LOG_INFO, ("vj_uncompress_tcp: tossing\n")); - INCR(vjs_tossed); - return (-1); - } - } - cs = &comp->rstate[comp->last_recv]; - hlen = IPH_HL(&cs->cs_ip) << 2; - th = (struct tcp_hdr *)&((u8_t*)&cs->cs_ip)[hlen]; - th->chksum = lwip_htons((*cp << 8) | cp[1]); - cp += 2; - if (changes & TCP_PUSH_BIT) { - TCPH_SET_FLAG(th, TCP_PSH); - } else { - TCPH_UNSET_FLAG(th, TCP_PSH); - } - - switch (changes & SPECIALS_MASK) { - case SPECIAL_I: - { - u32_t i = lwip_ntohs(IPH_LEN(&cs->cs_ip)) - cs->cs_hlen; - /* some compilers can't nest inline assembler.. */ - tmp = lwip_ntohl(th->ackno) + i; - th->ackno = lwip_htonl(tmp); - tmp = lwip_ntohl(th->seqno) + i; - th->seqno = lwip_htonl(tmp); - } - break; - - case SPECIAL_D: - /* some compilers can't nest inline assembler.. */ - tmp = lwip_ntohl(th->seqno) + lwip_ntohs(IPH_LEN(&cs->cs_ip)) - cs->cs_hlen; - th->seqno = lwip_htonl(tmp); - break; - - default: - if (changes & NEW_U) { - TCPH_SET_FLAG(th, TCP_URG); - DECODEU(th->urgp); - } else { - TCPH_UNSET_FLAG(th, TCP_URG); - } - if (changes & NEW_W) { - DECODES(th->wnd); - } - if (changes & NEW_A) { - DECODEL(th->ackno); - } - if (changes & NEW_S) { - DECODEL(th->seqno); - } - break; - } - if (changes & NEW_I) { - DECODES(cs->cs_ip._id); - } else { - IPH_ID_SET(&cs->cs_ip, lwip_ntohs(IPH_ID(&cs->cs_ip)) + 1); - IPH_ID_SET(&cs->cs_ip, lwip_htons(IPH_ID(&cs->cs_ip))); - } - - /* - * At this point, cp points to the first byte of data in the - * packet. Fill in the IP total length and update the IP - * header checksum. - */ - vjlen = (u16_t)(cp - (u8_t*)n0->payload); - if (n0->len < vjlen) { - /* - * We must have dropped some characters (crc should detect - * this but the old slip framing won't) - */ - PPPDEBUG(LOG_INFO, ("vj_uncompress_tcp: head buffer %d too short %d\n", - n0->len, vjlen)); - goto bad; - } - -#if BYTE_ORDER == LITTLE_ENDIAN - tmp = n0->tot_len - vjlen + cs->cs_hlen; - IPH_LEN_SET(&cs->cs_ip, lwip_htons((u16_t)tmp)); -#else - IPH_LEN_SET(&cs->cs_ip, lwip_htons(n0->tot_len - vjlen + cs->cs_hlen)); -#endif - - /* recompute the ip header checksum */ - bp = (struct vj_u16_t*) &cs->cs_ip; - IPH_CHKSUM_SET(&cs->cs_ip, 0); - for (tmp = 0; hlen > 0; hlen -= 2) { - tmp += (*bp++).v; - } - tmp = (tmp & 0xffff) + (tmp >> 16); - tmp = (tmp & 0xffff) + (tmp >> 16); - IPH_CHKSUM_SET(&cs->cs_ip, (u16_t)(~tmp)); - - /* Remove the compressed header and prepend the uncompressed header. */ - if (pbuf_header(n0, -(s16_t)vjlen)) { - /* Can we cope with this failing? Just assert for now */ - LWIP_ASSERT("pbuf_header failed\n", 0); - goto bad; - } - - if(LWIP_MEM_ALIGN(n0->payload) != n0->payload) { - struct pbuf *np, *q; - u8_t *bufptr; - -#if IP_FORWARD - /* If IP forwarding is enabled we are using a PBUF_LINK packet type so - * the packet is being allocated with enough header space to be - * forwarded (to Ethernet for example). - */ - np = pbuf_alloc(PBUF_LINK, n0->len + cs->cs_hlen, PBUF_POOL); -#else /* IP_FORWARD */ - np = pbuf_alloc(PBUF_RAW, n0->len + cs->cs_hlen, PBUF_POOL); -#endif /* IP_FORWARD */ - if(!np) { - PPPDEBUG(LOG_WARNING, ("vj_uncompress_tcp: realign failed\n")); - goto bad; - } - - if (pbuf_header(np, -(s16_t)cs->cs_hlen)) { - /* Can we cope with this failing? Just assert for now */ - LWIP_ASSERT("pbuf_header failed\n", 0); - goto bad; - } - - bufptr = (u8_t*)n0->payload; - for(q = np; q != NULL; q = q->next) { - MEMCPY(q->payload, bufptr, q->len); - bufptr += q->len; - } - - if(n0->next) { - pbuf_chain(np, n0->next); - pbuf_dechain(n0); - } - pbuf_free(n0); - n0 = np; - } - - if (pbuf_header(n0, (s16_t)cs->cs_hlen)) { - struct pbuf *np; - - LWIP_ASSERT("vj_uncompress_tcp: cs->cs_hlen <= PBUF_POOL_BUFSIZE", cs->cs_hlen <= PBUF_POOL_BUFSIZE); - np = pbuf_alloc(PBUF_RAW, cs->cs_hlen, PBUF_POOL); - if(!np) { - PPPDEBUG(LOG_WARNING, ("vj_uncompress_tcp: prepend failed\n")); - goto bad; - } - pbuf_cat(np, n0); - n0 = np; - } - LWIP_ASSERT("n0->len >= cs->cs_hlen", n0->len >= cs->cs_hlen); - MEMCPY(n0->payload, &cs->cs_ip, cs->cs_hlen); - - *nb = n0; - - return vjlen; - -bad: - comp->flags |= VJF_TOSS; - INCR(vjs_errorin); - return (-1); -} - -#endif /* PPP_SUPPORT && VJ_SUPPORT */ diff --git a/third_party/lwip/repo/lwip/src/netif/slipif.c b/third_party/lwip/repo/lwip/src/netif/slipif.c deleted file mode 100644 index 6eb83c35a4adff..00000000000000 --- a/third_party/lwip/repo/lwip/src/netif/slipif.c +++ /dev/null @@ -1,555 +0,0 @@ -/** - * @file - * SLIP Interface - * - */ - -/* - * Copyright (c) 2001-2004 Swedish Institute of Computer Science. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * This file is built upon the file: src/arch/rtxc/netif/sioslip.c - * - * Author: Magnus Ivarsson - * Simon Goldschmidt - */ - - -/** - * @defgroup slipif SLIP netif - * @ingroup addons - * - * This is an arch independent SLIP netif. The specific serial hooks must be - * provided by another file. They are sio_open, sio_read/sio_tryread and sio_send - * - * Usage: This netif can be used in three ways:\n - * 1) For NO_SYS==0, an RX thread can be used which blocks on sio_read() - * until data is received.\n - * 2) In your main loop, call slipif_poll() to check for new RX bytes, - * completed packets are fed into netif->input().\n - * 3) Call slipif_received_byte[s]() from your serial RX ISR and - * slipif_process_rxqueue() from your main loop. ISR level decodes - * packets and puts completed packets on a queue which is fed into - * the stack from the main loop (needs SYS_LIGHTWEIGHT_PROT for - * pbuf_alloc to work on ISR level!). - * - */ - -#include "netif/slipif.h" -#include "lwip/opt.h" - -#include "lwip/def.h" -#include "lwip/pbuf.h" -#include "lwip/stats.h" -#include "lwip/snmp.h" -#include "lwip/sys.h" -#include "lwip/sio.h" - -#define SLIP_END 0xC0 /* 0300: start and end of every packet */ -#define SLIP_ESC 0xDB /* 0333: escape start (one byte escaped data follows) */ -#define SLIP_ESC_END 0xDC /* 0334: following escape: original byte is 0xC0 (END) */ -#define SLIP_ESC_ESC 0xDD /* 0335: following escape: original byte is 0xDB (ESC) */ - -/** Maximum packet size that is received by this netif */ -#ifndef SLIP_MAX_SIZE -#define SLIP_MAX_SIZE 1500 -#endif - -/** Define this to the interface speed for SNMP - * (sio_fd is the sio_fd_t returned by sio_open). - * The default value of zero means 'unknown'. - */ -#ifndef SLIP_SIO_SPEED -#define SLIP_SIO_SPEED(sio_fd) 0 -#endif - -enum slipif_recv_state { - SLIP_RECV_NORMAL, - SLIP_RECV_ESCAPE -}; - -struct slipif_priv { - sio_fd_t sd; - /* q is the whole pbuf chain for a packet, p is the current pbuf in the chain */ - struct pbuf *p, *q; - u8_t state; - u16_t i, recved; -#if SLIP_RX_FROM_ISR - struct pbuf *rxpackets; -#endif -}; - -/** - * Send a pbuf doing the necessary SLIP encapsulation - * - * Uses the serial layer's sio_send() - * - * @param netif the lwip network interface structure for this slipif - * @param p the pbuf chain packet to send - * @return always returns ERR_OK since the serial layer does not provide return values - */ -static err_t -slipif_output(struct netif *netif, struct pbuf *p) -{ - struct slipif_priv *priv; - struct pbuf *q; - u16_t i; - u8_t c; - - LWIP_ASSERT("netif != NULL", (netif != NULL)); - LWIP_ASSERT("netif->state != NULL", (netif->state != NULL)); - LWIP_ASSERT("p != NULL", (p != NULL)); - - LWIP_DEBUGF(SLIP_DEBUG, ("slipif_output(%"U16_F"): sending %"U16_F" bytes\n", (u16_t)netif->num, p->tot_len)); - priv = (struct slipif_priv *)netif->state; - - /* Send pbuf out on the serial I/O device. */ - /* Start with packet delimiter. */ - sio_send(SLIP_END, priv->sd); - - for (q = p; q != NULL; q = q->next) { - for (i = 0; i < q->len; i++) { - c = ((u8_t *)q->payload)[i]; - switch (c) { - case SLIP_END: - /* need to escape this byte (0xC0 -> 0xDB, 0xDC) */ - sio_send(SLIP_ESC, priv->sd); - sio_send(SLIP_ESC_END, priv->sd); - break; - case SLIP_ESC: - /* need to escape this byte (0xDB -> 0xDB, 0xDD) */ - sio_send(SLIP_ESC, priv->sd); - sio_send(SLIP_ESC_ESC, priv->sd); - break; - default: - /* normal byte - no need for escaping */ - sio_send(c, priv->sd); - break; - } - } - } - /* End with packet delimiter. */ - sio_send(SLIP_END, priv->sd); - return ERR_OK; -} - -#if LWIP_IPV4 -/** - * Send a pbuf doing the necessary SLIP encapsulation - * - * Uses the serial layer's sio_send() - * - * @param netif the lwip network interface structure for this slipif - * @param p the pbuf chain packet to send - * @param ipaddr the ip address to send the packet to (not used for slipif) - * @return always returns ERR_OK since the serial layer does not provide return values - */ -static err_t -slipif_output_v4(struct netif *netif, struct pbuf *p, const ip4_addr_t *ipaddr) -{ - LWIP_UNUSED_ARG(ipaddr); - return slipif_output(netif, p); -} -#endif /* LWIP_IPV4 */ - -#if LWIP_IPV6 -/** - * Send a pbuf doing the necessary SLIP encapsulation - * - * Uses the serial layer's sio_send() - * - * @param netif the lwip network interface structure for this slipif - * @param p the pbuf chain packet to send - * @param ipaddr the ip address to send the packet to (not used for slipif) - * @return always returns ERR_OK since the serial layer does not provide return values - */ -static err_t -slipif_output_v6(struct netif *netif, struct pbuf *p, const ip6_addr_t *ipaddr) -{ - LWIP_UNUSED_ARG(ipaddr); - return slipif_output(netif, p); -} -#endif /* LWIP_IPV6 */ - -/** - * Handle the incoming SLIP stream character by character - * - * @param netif the lwip network interface structure for this slipif - * @param c received character (multiple calls to this function will - * return a complete packet, NULL is returned before - used for polling) - * @return The IP packet when SLIP_END is received - */ -static struct pbuf* -slipif_rxbyte(struct netif *netif, u8_t c) -{ - struct slipif_priv *priv; - struct pbuf *t; - - LWIP_ASSERT("netif != NULL", (netif != NULL)); - LWIP_ASSERT("netif->state != NULL", (netif->state != NULL)); - - priv = (struct slipif_priv *)netif->state; - - switch (priv->state) { - case SLIP_RECV_NORMAL: - switch (c) { - case SLIP_END: - if (priv->recved > 0) { - /* Received whole packet. */ - /* Trim the pbuf to the size of the received packet. */ - pbuf_realloc(priv->q, priv->recved); - - LINK_STATS_INC(link.recv); - - LWIP_DEBUGF(SLIP_DEBUG, ("slipif: Got packet (%"U16_F" bytes)\n", priv->recved)); - t = priv->q; - priv->p = priv->q = NULL; - priv->i = priv->recved = 0; - return t; - } - return NULL; - case SLIP_ESC: - priv->state = SLIP_RECV_ESCAPE; - return NULL; - default: - break; - } /* end switch (c) */ - break; - case SLIP_RECV_ESCAPE: - /* un-escape END or ESC bytes, leave other bytes - (although that would be a protocol error) */ - switch (c) { - case SLIP_ESC_END: - c = SLIP_END; - break; - case SLIP_ESC_ESC: - c = SLIP_ESC; - break; - default: - break; - } - priv->state = SLIP_RECV_NORMAL; - break; - default: - break; - } /* end switch (priv->state) */ - - /* byte received, packet not yet completely received */ - if (priv->p == NULL) { - /* allocate a new pbuf */ - LWIP_DEBUGF(SLIP_DEBUG, ("slipif_input: alloc\n")); - priv->p = pbuf_alloc(PBUF_LINK, (PBUF_POOL_BUFSIZE - PBUF_LINK_HLEN - PBUF_LINK_ENCAPSULATION_HLEN), PBUF_POOL); - - if (priv->p == NULL) { - LINK_STATS_INC(link.drop); - LWIP_DEBUGF(SLIP_DEBUG, ("slipif_input: no new pbuf! (DROP)\n")); - /* don't process any further since we got no pbuf to receive to */ - return NULL; - } - - if (priv->q != NULL) { - /* 'chain' the pbuf to the existing chain */ - pbuf_cat(priv->q, priv->p); - } else { - /* p is the first pbuf in the chain */ - priv->q = priv->p; - } - } - - /* this automatically drops bytes if > SLIP_MAX_SIZE */ - if ((priv->p != NULL) && (priv->recved <= SLIP_MAX_SIZE)) { - ((u8_t *)priv->p->payload)[priv->i] = c; - priv->recved++; - priv->i++; - if (priv->i >= priv->p->len) { - /* on to the next pbuf */ - priv->i = 0; - if (priv->p->next != NULL && priv->p->next->len > 0) { - /* p is a chain, on to the next in the chain */ - priv->p = priv->p->next; - } else { - /* p is a single pbuf, set it to NULL so next time a new - * pbuf is allocated */ - priv->p = NULL; - } - } - } - return NULL; -} - -/** Like slipif_rxbyte, but passes completed packets to netif->input - * - * @param netif The lwip network interface structure for this slipif - * @param c received character - */ -static void -slipif_rxbyte_input(struct netif *netif, u8_t c) -{ - struct pbuf *p; - p = slipif_rxbyte(netif, c); - if (p != NULL) { - if (netif->input(p, netif) != ERR_OK) { - pbuf_free(p); - } - } -} - -#if SLIP_USE_RX_THREAD -/** - * The SLIP input thread. - * - * Feed the IP layer with incoming packets - * - * @param nf the lwip network interface structure for this slipif - */ -static void -slipif_loop_thread(void *nf) -{ - u8_t c; - struct netif *netif = (struct netif *)nf; - struct slipif_priv *priv = (struct slipif_priv *)netif->state; - - while (1) { - if (sio_read(priv->sd, &c, 1) > 0) { - slipif_rxbyte_input(netif, c); - } - } -} -#endif /* SLIP_USE_RX_THREAD */ - -/** - * SLIP netif initialization - * - * Call the arch specific sio_open and remember - * the opened device in the state field of the netif. - * - * @param netif the lwip network interface structure for this slipif - * @return ERR_OK if serial line could be opened, - * ERR_MEM if no memory could be allocated, - * ERR_IF is serial line couldn't be opened - * - * @note netif->num must contain the number of the serial port to open - * (0 by default). If netif->state is != NULL, it is interpreted as an - * u8_t pointer pointing to the serial port number instead of netif->num. - * - */ -err_t -slipif_init(struct netif *netif) -{ - struct slipif_priv *priv; - u8_t sio_num; - - LWIP_DEBUGF(SLIP_DEBUG, ("slipif_init: netif->num=%"U16_F"\n", (u16_t)netif->num)); - - /* Allocate private data */ - priv = (struct slipif_priv *)mem_malloc(sizeof(struct slipif_priv)); - if (!priv) { - return ERR_MEM; - } - - netif->name[0] = 's'; - netif->name[1] = 'l'; -#if LWIP_IPV4 - netif->output = slipif_output_v4; -#endif /* LWIP_IPV4 */ -#if LWIP_IPV6 - netif->output_ip6 = slipif_output_v6; -#endif /* LWIP_IPV6 */ - netif->mtu = SLIP_MAX_SIZE; - - /* netif->state or netif->num contain the port number */ - if (netif->state != NULL) { - sio_num = *(u8_t*)netif->state; - } else { - sio_num = netif->num; - } - /* Try to open the serial port. */ - priv->sd = sio_open(sio_num); - if (!priv->sd) { - /* Opening the serial port failed. */ - mem_free(priv); - return ERR_IF; - } - - /* Initialize private data */ - priv->p = NULL; - priv->q = NULL; - priv->state = SLIP_RECV_NORMAL; - priv->i = 0; - priv->recved = 0; -#if SLIP_RX_FROM_ISR - priv->rxpackets = NULL; -#endif - - netif->state = priv; - - /* initialize the snmp variables and counters inside the struct netif */ - MIB2_INIT_NETIF(netif, snmp_ifType_slip, SLIP_SIO_SPEED(priv->sd)); - -#if SLIP_USE_RX_THREAD - /* Create a thread to poll the serial line. */ - sys_thread_new(SLIPIF_THREAD_NAME, slipif_loop_thread, netif, - SLIPIF_THREAD_STACKSIZE, SLIPIF_THREAD_PRIO); -#endif /* SLIP_USE_RX_THREAD */ - return ERR_OK; -} - -/** - * Polls the serial device and feeds the IP layer with incoming packets. - * - * @param netif The lwip network interface structure for this slipif - */ -void -slipif_poll(struct netif *netif) -{ - u8_t c; - struct slipif_priv *priv; - - LWIP_ASSERT("netif != NULL", (netif != NULL)); - LWIP_ASSERT("netif->state != NULL", (netif->state != NULL)); - - priv = (struct slipif_priv *)netif->state; - - while (sio_tryread(priv->sd, &c, 1) > 0) { - slipif_rxbyte_input(netif, c); - } -} - -#if SLIP_RX_FROM_ISR -/** - * Feeds the IP layer with incoming packets that were receive - * - * @param netif The lwip network interface structure for this slipif - */ -void -slipif_process_rxqueue(struct netif *netif) -{ - struct slipif_priv *priv; - SYS_ARCH_DECL_PROTECT(old_level); - - LWIP_ASSERT("netif != NULL", (netif != NULL)); - LWIP_ASSERT("netif->state != NULL", (netif->state != NULL)); - - priv = (struct slipif_priv *)netif->state; - - SYS_ARCH_PROTECT(old_level); - while (priv->rxpackets != NULL) { - struct pbuf *p = priv->rxpackets; -#if SLIP_RX_QUEUE - /* dequeue packet */ - struct pbuf *q = p; - while ((q->len != q->tot_len) && (q->next != NULL)) { - q = q->next; - } - priv->rxpackets = q->next; - q->next = NULL; -#else /* SLIP_RX_QUEUE */ - priv->rxpackets = NULL; -#endif /* SLIP_RX_QUEUE */ - SYS_ARCH_UNPROTECT(old_level); - if (netif->input(p, netif) != ERR_OK) { - pbuf_free(p); - } - SYS_ARCH_PROTECT(old_level); - } -} - -/** Like slipif_rxbyte, but queues completed packets. - * - * @param netif The lwip network interface structure for this slipif - * @param data Received serial byte - */ -static void -slipif_rxbyte_enqueue(struct netif *netif, u8_t data) -{ - struct pbuf *p; - struct slipif_priv *priv = (struct slipif_priv *)netif->state; - SYS_ARCH_DECL_PROTECT(old_level); - - p = slipif_rxbyte(netif, data); - if (p != NULL) { - SYS_ARCH_PROTECT(old_level); - if (priv->rxpackets != NULL) { -#if SLIP_RX_QUEUE - /* queue multiple pbufs */ - struct pbuf *q = p; - while (q->next != NULL) { - q = q->next; - } - q->next = p; - } else { -#else /* SLIP_RX_QUEUE */ - pbuf_free(priv->rxpackets); - } - { -#endif /* SLIP_RX_QUEUE */ - priv->rxpackets = p; - } - SYS_ARCH_UNPROTECT(old_level); - } -} - -/** - * Process a received byte, completed packets are put on a queue that is - * fed into IP through slipif_process_rxqueue(). - * - * This function can be called from ISR if SYS_LIGHTWEIGHT_PROT is enabled. - * - * @param netif The lwip network interface structure for this slipif - * @param data received character - */ -void -slipif_received_byte(struct netif *netif, u8_t data) -{ - LWIP_ASSERT("netif != NULL", (netif != NULL)); - LWIP_ASSERT("netif->state != NULL", (netif->state != NULL)); - slipif_rxbyte_enqueue(netif, data); -} - -/** - * Process multiple received byte, completed packets are put on a queue that is - * fed into IP through slipif_process_rxqueue(). - * - * This function can be called from ISR if SYS_LIGHTWEIGHT_PROT is enabled. - * - * @param netif The lwip network interface structure for this slipif - * @param data received character - * @param len Number of received characters - */ -void -slipif_received_bytes(struct netif *netif, u8_t *data, u8_t len) -{ - u8_t i; - u8_t *rxdata = data; - LWIP_ASSERT("netif != NULL", (netif != NULL)); - LWIP_ASSERT("netif->state != NULL", (netif->state != NULL)); - - for (i = 0; i < len; i++, rxdata++) { - slipif_rxbyte_enqueue(netif, *rxdata); - } -} -#endif /* SLIP_RX_FROM_ISR */ From 9423a8cd0d2ed729b524e86c5b61c292091eebd7 Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Thu, 24 Oct 2024 09:58:46 -0400 Subject: [PATCH 099/149] Use TLV-based encoding for ember data buffer. (#36172) * Use TLV-based encoding for ember data buffer. This saves 2K of flash on some test devices, being much more efficient in code size compared to using datamodel code. * Restyled by clang-format * Restyled by shfmt * Undo unrelated change * Add some casts to make android compiler happy * Updates based on code review * Added unit tests for min/max int64 values * Rename PascalString to PascalStringType * Fix rename * Restyle * Add helper methods inside odd sized integers to localize code logic * Restyled by clang-format * Fix up negative ranges * Fixed ranges * Fix signed max bug and update unit tests * Make android happy * Typo fix * Switch up unit tests * Update a nullable check to make use of ValueToNullValue * Add namespace prefix * Update src/app/codegen-data-model-provider/EmberDataBuffer.cpp Co-authored-by: Boris Zbarsky * Update src/app/codegen-data-model-provider/EmberDataBuffer.h Co-authored-by: Boris Zbarsky * Correct comments:signed, not unsigned * Use constructors for the buffer info * Rename things to EmberAttributeDataBuffer * Undo submodule updates * Restyled by clang-format --------- Co-authored-by: Restyled.io Co-authored-by: Andrei Litvin Co-authored-by: Boris Zbarsky --- scripts/build_coverage.sh | 12 +- src/app/codegen-data-model-provider/BUILD.gn | 2 + .../CodegenDataModelProvider_Write.cpp | 198 +----- .../EmberAttributeDataBuffer.cpp | 326 +++++++++ .../EmberAttributeDataBuffer.h | 101 +++ .../codegen-data-model-provider/model.cmake | 2 + src/app/codegen-data-model-provider/model.gni | 2 + .../tests/BUILD.gn | 5 +- .../tests/TestCodegenModelViaMocks.cpp | 10 +- .../tests/TestEmberAttributeDataBuffer.cpp | 616 ++++++++++++++++++ .../util/attribute-storage-null-handling.h | 1 - src/app/util/odd-sized-integers.h | 54 ++ 12 files changed, 1124 insertions(+), 205 deletions(-) create mode 100644 src/app/codegen-data-model-provider/EmberAttributeDataBuffer.cpp create mode 100644 src/app/codegen-data-model-provider/EmberAttributeDataBuffer.h create mode 100644 src/app/codegen-data-model-provider/tests/TestEmberAttributeDataBuffer.cpp diff --git a/scripts/build_coverage.sh b/scripts/build_coverage.sh index 9e7b4a0fe8a6d6..1bb68a2911c525 100755 --- a/scripts/build_coverage.sh +++ b/scripts/build_coverage.sh @@ -50,6 +50,7 @@ SUPPORTED_TESTS=(unit yaml all) CODE="core" TESTS="unit" skip_gn=false +TEST_TARGET=check help() { @@ -70,6 +71,7 @@ help() { 'unit': Run unit test to drive the coverage check. --default 'yaml': Run yaml test to drive the coverage check. 'all': Run unit & yaml test to drive the coverage check. + --target Specific test target to run (e.g. TestEmberAttributeBuffer.run) " } @@ -89,6 +91,9 @@ for i in "$@"; do TESTS="${i#*=}" shift ;; + --target=*) + TEST_TARGET="${i#*=}" + ;; -o=* | --output_root=*) OUTPUT_ROOT="${i#*=}" COVERAGE_ROOT="$OUTPUT_ROOT/coverage" @@ -121,20 +126,21 @@ if [ "$skip_gn" == false ]; then # Generates ninja files EXTRA_GN_ARGS="" if [[ "$TESTS" == "yaml" || "$TESTS" == "all" ]]; then - EXTRA_GN_ARGS="$EXTRA_GN_ARGS chip_build_all_clusters_app=true" + EXTRA_GN_ARGS="$EXTRA_GN_ARGS chip_build_all_clusters_app=true" else EXTRA_GN_ARGS="$EXTRA_GN_ARGS chip_build_tools=false" fi gn --root="$CHIP_ROOT" gen "$OUTPUT_ROOT" --args="use_coverage=true$EXTRA_GN_ARGS" - ninja -C "$OUTPUT_ROOT" # Run unit tests if [[ "$TESTS" == "unit" || "$TESTS" == "all" ]]; then - ninja -C "$OUTPUT_ROOT" check + ninja -C "$OUTPUT_ROOT" "$TEST_TARGET" fi # Run yaml tests if [[ "$TESTS" == "yaml" || "$TESTS" == "all" ]]; then + ninja -C "$OUTPUT_ROOT" + scripts/run_in_build_env.sh \ "./scripts/tests/run_test_suite.py \ --chip-tool ""$OUTPUT_ROOT/chip-tool \ diff --git a/src/app/codegen-data-model-provider/BUILD.gn b/src/app/codegen-data-model-provider/BUILD.gn index a3616b354c600e..3b414c595b9f67 100644 --- a/src/app/codegen-data-model-provider/BUILD.gn +++ b/src/app/codegen-data-model-provider/BUILD.gn @@ -24,6 +24,8 @@ import("//build_overrides/chip.gni") # CodegenDataModelProvider.h # CodegenDataModelProvider_Read.cpp # CodegenDataModelProvider_Write.cpp +# EmberAttributeDataBuffer.cpp +# EmberAttributeDataBuffer.h # EmberMetadata.cpp # EmberMetadata.h # Instance.cpp diff --git a/src/app/codegen-data-model-provider/CodegenDataModelProvider_Write.cpp b/src/app/codegen-data-model-provider/CodegenDataModelProvider_Write.cpp index 4c46a2a364d16b..51807fe98cf47d 100644 --- a/src/app/codegen-data-model-provider/CodegenDataModelProvider_Write.cpp +++ b/src/app/codegen-data-model-provider/CodegenDataModelProvider_Write.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -85,198 +86,6 @@ std::optional TryWriteViaAccessInterface(const ConcreteDataAttribute return decoder.TriedDecode() ? std::make_optional(CHIP_NO_ERROR) : std::nullopt; } -/// Metadata of what a ember/pascal short string means (prepended by a u8 length) -struct ShortPascalString -{ - using LengthType = uint8_t; - static constexpr LengthType kNullLength = 0xFF; - - static void SetLength(uint8_t * buffer, LengthType value) { *buffer = value; } -}; - -/// Metadata of what a ember/pascal LONG string means (prepended by a u16 length) -struct LongPascalString -{ - using LengthType = uint16_t; - static constexpr LengthType kNullLength = 0xFFFF; - - // Encoding for ember string lengths is little-endian (see ember-strings.cpp) - static void SetLength(uint8_t * buffer, LengthType value) { Encoding::LittleEndian::Put16(buffer, value); } -}; - -// ember assumptions ... should just work -static_assert(sizeof(ShortPascalString::LengthType) == 1); -static_assert(sizeof(LongPascalString::LengthType) == 2); - -/// Convert the value stored in 'decoder' into an ember format span 'out' -/// -/// The value converted will be of type T (e.g. CharSpan or ByteSpan) and it will be converted -/// via the given ENCODING (i.e. ShortPascalString or LongPascalString) -/// -/// isNullable defines if the value of NULL is allowed to be converted. -template -CHIP_ERROR DecodeStringLikeIntoEmberBuffer(AttributeValueDecoder decoder, bool isNullable, MutableByteSpan & out) -{ - T workingValue; - - if (isNullable) - { - typename DataModel::Nullable nullableWorkingValue; - ReturnErrorOnFailure(decoder.Decode(nullableWorkingValue)); - - if (nullableWorkingValue.IsNull()) - { - VerifyOrReturnError(out.size() >= sizeof(typename ENCODING::LengthType), CHIP_ERROR_BUFFER_TOO_SMALL); - ENCODING::SetLength(out.data(), ENCODING::kNullLength); - out.reduce_size(sizeof(typename ENCODING::LengthType)); - return CHIP_NO_ERROR; - } - - // continue encoding non-null value - workingValue = nullableWorkingValue.Value(); - } - else - { - ReturnErrorOnFailure(decoder.Decode(workingValue)); - } - - auto len = static_cast(workingValue.size()); - VerifyOrReturnError(out.size() >= sizeof(len) + len, CHIP_ERROR_BUFFER_TOO_SMALL); - - uint8_t * output_buffer = out.data(); - - ENCODING::SetLength(output_buffer, len); - output_buffer += sizeof(len); - - memcpy(output_buffer, workingValue.data(), workingValue.size()); - output_buffer += workingValue.size(); - - out.reduce_size(static_cast(output_buffer - out.data())); - return CHIP_NO_ERROR; -} - -/// Decodes a numeric data value of type T from the `decoder` into a ember-encoded buffer `out` -/// -/// isNullable defines if the value of NULL is allowed to be decoded. -template -CHIP_ERROR DecodeIntoEmberBuffer(AttributeValueDecoder & decoder, bool isNullable, MutableByteSpan & out) -{ - using Traits = NumericAttributeTraits; - typename Traits::StorageType storageValue; - - if (isNullable) - { - DataModel::Nullable workingValue; - ReturnErrorOnFailure(decoder.Decode(workingValue)); - - if (workingValue.IsNull()) - { - Traits::SetNull(storageValue); - } - else - { - // This guards against trying to decode something that overlaps nullable, for example - // Nullable(0xFF) is not representable because 0xFF is the encoding of NULL in ember - // as well as odd-sized integers (e.g. full 32-bit value like 0x11223344 cannot be written - // to a 3-byte odd-sized integger). - VerifyOrReturnError(Traits::CanRepresentValue(isNullable, workingValue.Value()), CHIP_ERROR_INVALID_ARGUMENT); - Traits::WorkingToStorage(workingValue.Value(), storageValue); - } - - VerifyOrReturnError(out.size() >= sizeof(storageValue), CHIP_ERROR_INVALID_ARGUMENT); - } - else - { - typename Traits::WorkingType workingValue; - ReturnErrorOnFailure(decoder.Decode(workingValue)); - - Traits::WorkingToStorage(workingValue, storageValue); - - VerifyOrReturnError(out.size() >= sizeof(storageValue), CHIP_ERROR_INVALID_ARGUMENT); - - // Even non-nullable values may be outside range: e.g. odd-sized integers have working values - // that are larger than the storage values (e.g. a uint32_t being stored as a 3-byte integer) - VerifyOrReturnError(Traits::CanRepresentValue(isNullable, workingValue), CHIP_ERROR_INVALID_ARGUMENT); - } - - const uint8_t * data = Traits::ToAttributeStoreRepresentation(storageValue); - - // The decoding + ToAttributeStoreRepresentation will result in data being - // stored in native format/byteorder, suitable to directly be stored in the data store - memcpy(out.data(), data, sizeof(storageValue)); - out.reduce_size(sizeof(storageValue)); - - return CHIP_NO_ERROR; -} - -/// Read the data from "decoder" into an ember-formatted buffer "out" -/// -/// `out` is a in/out buffer: -/// - its initial size determines the maximum size of the buffer -/// - its output size reflects the actual data size -/// -/// Uses the attribute `metadata` to determine how the data is to be encoded into out. -CHIP_ERROR DecodeValueIntoEmberBuffer(AttributeValueDecoder & decoder, const EmberAfAttributeMetadata * metadata, - MutableByteSpan & out) -{ - VerifyOrReturnError(metadata != nullptr, CHIP_ERROR_INVALID_ARGUMENT); - - const bool isNullable = metadata->IsNullable(); - - switch (AttributeBaseType(metadata->attributeType)) - { - case ZCL_BOOLEAN_ATTRIBUTE_TYPE: // Boolean - return DecodeIntoEmberBuffer(decoder, isNullable, out); - case ZCL_INT8U_ATTRIBUTE_TYPE: // Unsigned 8-bit integer - return DecodeIntoEmberBuffer(decoder, isNullable, out); - case ZCL_INT16U_ATTRIBUTE_TYPE: // Unsigned 16-bit integer - return DecodeIntoEmberBuffer(decoder, isNullable, out); - case ZCL_INT24U_ATTRIBUTE_TYPE: // Unsigned 24-bit integer - return DecodeIntoEmberBuffer>(decoder, isNullable, out); - case ZCL_INT32U_ATTRIBUTE_TYPE: // Unsigned 32-bit integer - return DecodeIntoEmberBuffer(decoder, isNullable, out); - case ZCL_INT40U_ATTRIBUTE_TYPE: // Unsigned 40-bit integer - return DecodeIntoEmberBuffer>(decoder, isNullable, out); - case ZCL_INT48U_ATTRIBUTE_TYPE: // Unsigned 48-bit integer - return DecodeIntoEmberBuffer>(decoder, isNullable, out); - case ZCL_INT56U_ATTRIBUTE_TYPE: // Unsigned 56-bit integer - return DecodeIntoEmberBuffer>(decoder, isNullable, out); - case ZCL_INT64U_ATTRIBUTE_TYPE: // Unsigned 64-bit integer - return DecodeIntoEmberBuffer(decoder, isNullable, out); - case ZCL_INT8S_ATTRIBUTE_TYPE: // Signed 8-bit integer - return DecodeIntoEmberBuffer(decoder, isNullable, out); - case ZCL_INT16S_ATTRIBUTE_TYPE: // Signed 16-bit integer - return DecodeIntoEmberBuffer(decoder, isNullable, out); - case ZCL_INT24S_ATTRIBUTE_TYPE: // Signed 24-bit integer - return DecodeIntoEmberBuffer>(decoder, isNullable, out); - case ZCL_INT32S_ATTRIBUTE_TYPE: // Signed 32-bit integer - return DecodeIntoEmberBuffer(decoder, isNullable, out); - case ZCL_INT40S_ATTRIBUTE_TYPE: // Signed 40-bit integer - return DecodeIntoEmberBuffer>(decoder, isNullable, out); - case ZCL_INT48S_ATTRIBUTE_TYPE: // Signed 48-bit integer - return DecodeIntoEmberBuffer>(decoder, isNullable, out); - case ZCL_INT56S_ATTRIBUTE_TYPE: // Signed 56-bit integer - return DecodeIntoEmberBuffer>(decoder, isNullable, out); - case ZCL_INT64S_ATTRIBUTE_TYPE: // Signed 64-bit integer - return DecodeIntoEmberBuffer(decoder, isNullable, out); - case ZCL_SINGLE_ATTRIBUTE_TYPE: // 32-bit float - return DecodeIntoEmberBuffer(decoder, isNullable, out); - case ZCL_DOUBLE_ATTRIBUTE_TYPE: // 64-bit float - return DecodeIntoEmberBuffer(decoder, isNullable, out); - case ZCL_CHAR_STRING_ATTRIBUTE_TYPE: // Char string - return DecodeStringLikeIntoEmberBuffer(decoder, isNullable, out); - case ZCL_LONG_CHAR_STRING_ATTRIBUTE_TYPE: - return DecodeStringLikeIntoEmberBuffer(decoder, isNullable, out); - case ZCL_OCTET_STRING_ATTRIBUTE_TYPE: // Octet string - return DecodeStringLikeIntoEmberBuffer(decoder, isNullable, out); - case ZCL_LONG_OCTET_STRING_ATTRIBUTE_TYPE: - return DecodeStringLikeIntoEmberBuffer(decoder, isNullable, out); - default: - ChipLogError(DataManagement, "Attribute type 0x%x not handled", static_cast(metadata->attributeType)); - return CHIP_IM_GLOBAL_STATUS(Failure); - } -} - } // namespace DataModel::ActionReturnStatus CodegenDataModelProvider::WriteAttribute(const DataModel::WriteAttributeRequest & request, @@ -414,7 +223,10 @@ DataModel::ActionReturnStatus CodegenDataModelProvider::WriteAttribute(const Dat } MutableByteSpan dataBuffer = gEmberAttributeIOBufferSpan; - ReturnErrorOnFailure(DecodeValueIntoEmberBuffer(decoder, *attributeMetadata, dataBuffer)); + { + Ember::EmberAttributeDataBuffer emberData(*attributeMetadata, dataBuffer); + ReturnErrorOnFailure(decoder.Decode(emberData)); + } Protocols::InteractionModel::Status status; diff --git a/src/app/codegen-data-model-provider/EmberAttributeDataBuffer.cpp b/src/app/codegen-data-model-provider/EmberAttributeDataBuffer.cpp new file mode 100644 index 00000000000000..ab8891657fde50 --- /dev/null +++ b/src/app/codegen-data-model-provider/EmberAttributeDataBuffer.cpp @@ -0,0 +1,326 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace chip { +namespace app { +namespace Ember { + +namespace { + +/// Maximum length of a string, inclusive +/// +/// the max size value (0xFF and 0xFFFF) is reserved for NULL representation so +/// it is not available +constexpr uint32_t MaxLength(EmberAttributeDataBuffer::PascalStringType s) +{ + if (s == EmberAttributeDataBuffer::PascalStringType::kShort) + { + return std::numeric_limits::max() - 1; + } + // EmberAttributeBuffer::PascalStringType::kLong: + return std::numeric_limits::max() - 1; +} + +struct UnsignedDecodeInfo +{ + unsigned byteCount; + uint64_t maxValue; + + constexpr UnsignedDecodeInfo(unsigned bytes) : byteCount(bytes), maxValue(NumericLimits::MaxUnsignedValue(bytes)) {} +}; + +constexpr UnsignedDecodeInfo GetUnsignedDecodeInfo(EmberAfAttributeType type) +{ + + switch (type) + { + case ZCL_INT8U_ATTRIBUTE_TYPE: // Unsigned 8-bit integer + return UnsignedDecodeInfo(1); + case ZCL_INT16U_ATTRIBUTE_TYPE: // Unsigned 16-bit integer + return UnsignedDecodeInfo(2); + case ZCL_INT24U_ATTRIBUTE_TYPE: // Unsigned 24-bit integer + return UnsignedDecodeInfo(3); + case ZCL_INT32U_ATTRIBUTE_TYPE: // Unsigned 32-bit integer + return UnsignedDecodeInfo(4); + case ZCL_INT40U_ATTRIBUTE_TYPE: // Unsigned 40-bit integer + return UnsignedDecodeInfo(5); + case ZCL_INT48U_ATTRIBUTE_TYPE: // Unsigned 48-bit integer + return UnsignedDecodeInfo(6); + case ZCL_INT56U_ATTRIBUTE_TYPE: // Unsigned 56-bit integer + return UnsignedDecodeInfo(7); + case ZCL_INT64U_ATTRIBUTE_TYPE: // Unsigned 64-bit integer + return UnsignedDecodeInfo(8); + } + chipDie(); +} + +struct SignedDecodeInfo +{ + unsigned byteCount; + int64_t minValue; + int64_t maxValue; + + constexpr SignedDecodeInfo(unsigned bytes) : + byteCount(bytes), minValue(NumericLimits::MinSignedValue(bytes)), maxValue(NumericLimits::MaxSignedValue(bytes)) + {} +}; + +constexpr SignedDecodeInfo GetSignedDecodeInfo(EmberAfAttributeType type) +{ + + switch (type) + { + case ZCL_INT8S_ATTRIBUTE_TYPE: // Signed 8-bit integer + return SignedDecodeInfo(1); + case ZCL_INT16S_ATTRIBUTE_TYPE: // Signed 16-bit integer + return SignedDecodeInfo(2); + case ZCL_INT24S_ATTRIBUTE_TYPE: // Signed 24-bit integer + return SignedDecodeInfo(3); + case ZCL_INT32S_ATTRIBUTE_TYPE: // Signed 32-bit integer + return SignedDecodeInfo(4); + case ZCL_INT40S_ATTRIBUTE_TYPE: // Signed 40-bit integer + return SignedDecodeInfo(5); + case ZCL_INT48S_ATTRIBUTE_TYPE: // Signed 48-bit integer + return SignedDecodeInfo(6); + case ZCL_INT56S_ATTRIBUTE_TYPE: // Signed 56-bit integer + return SignedDecodeInfo(7); + case ZCL_INT64S_ATTRIBUTE_TYPE: // Signed 64-bit integer + return SignedDecodeInfo(8); + } + chipDie(); +} + +} // namespace + +CHIP_ERROR EmberAttributeDataBuffer::DecodeUnsignedInteger(chip::TLV::TLVReader & reader, EndianWriter & writer) +{ + UnsignedDecodeInfo info = GetUnsignedDecodeInfo(mAttributeType); + + // Any size of integer can be read by TLV getting 64-bit integers + uint64_t value; + + if (reader.GetType() == TLV::kTLVType_Null) + { + // we know mIsNullable due to the check at the top of ::Decode + value = NumericLimits::UnsignedMaxValueToNullValue(info.maxValue); + } + else + { + ReturnErrorOnFailure(reader.Get(value)); + + bool valid = + // Value is in [0, max] RANGE + (value <= info.maxValue) + // Nullable values reserve a specific value to mean NULL + && !(mIsNullable && (value == NumericLimits::UnsignedMaxValueToNullValue(info.maxValue))); + + VerifyOrReturnError(valid, CHIP_IM_GLOBAL_STATUS(ConstraintError)); + } + + writer.EndianPut(value, info.byteCount); + return CHIP_NO_ERROR; +} + +CHIP_ERROR EmberAttributeDataBuffer::DecodeSignedInteger(chip::TLV::TLVReader & reader, EndianWriter & writer) +{ + SignedDecodeInfo info = GetSignedDecodeInfo(mAttributeType); + + // Any size of integer can be read by TLV getting 64-bit integers + int64_t value; + + if (reader.GetType() == TLV::kTLVType_Null) + { + // we know mIsNullable due to the check at the top of ::Decode + value = NumericLimits::SignedMinValueToNullValue(info.minValue); + } + else + { + ReturnErrorOnFailure(reader.Get(value)); + + bool valid = + // Value is in [min, max] RANGE + ((value >= info.minValue) && (value <= info.maxValue)) + // Nullable values reserve a specific value to mean NULL + && !(mIsNullable && (value == NumericLimits::SignedMinValueToNullValue(info.minValue))); + + VerifyOrReturnError(valid, CHIP_IM_GLOBAL_STATUS(ConstraintError)); + } + writer.EndianPutSigned(value, info.byteCount); + return CHIP_NO_ERROR; +} + +CHIP_ERROR EmberAttributeDataBuffer::DecodeAsString(chip::TLV::TLVReader & reader, PascalStringType stringType, + TLV::TLVType tlvType, EndianWriter & writer) +{ + // Handle null first, then the actual data + if (reader.GetType() == TLV::kTLVType_Null) + { + // we know mIsNullable due to the check at the top of ::Decode + switch (stringType) + { + case PascalStringType::kShort: + writer.Put8(NumericAttributeTraits::kNullValue); + break; + case PascalStringType::kLong: + writer.Put16(NumericAttributeTraits::kNullValue); + break; + } + return CHIP_NO_ERROR; + } + + const uint32_t stringLength = reader.GetLength(); + + VerifyOrReturnError(reader.GetType() == tlvType, CHIP_ERROR_WRONG_TLV_TYPE); + VerifyOrReturnError(stringLength <= MaxLength(stringType), CHIP_ERROR_INVALID_ARGUMENT); + + // Size is a prefix, where 0xFF/0xFFFF is the null marker (if applicable) + switch (stringType) + { + case PascalStringType::kShort: + writer.Put8(static_cast(stringLength)); + break; + case PascalStringType::kLong: + writer.Put16(static_cast(stringLength)); + break; + } + + // data copy + const uint8_t * tlvData; + ReturnErrorOnFailure(reader.GetDataPtr(tlvData)); + writer.Put(tlvData, stringLength); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR EmberAttributeDataBuffer::Decode(chip::TLV::TLVReader & reader) +{ + // all methods below assume that nullable setting matches (this is to reduce code size + // even though clarity suffers) + VerifyOrReturnError(mIsNullable || reader.GetType() != TLV::kTLVType_Null, CHIP_ERROR_WRONG_TLV_TYPE); + + EndianWriter endianWriter(mDataBuffer.data(), mDataBuffer.size()); + + switch (mAttributeType) + { + case ZCL_BOOLEAN_ATTRIBUTE_TYPE: // Boolean + // Boolean values: + // 0x00 is FALSE + // 0x01 is TRUE + // 0xFF is NULL + if (reader.GetType() == TLV::kTLVType_Null) + { + // we know mIsNullable due to the check at the top of ::Decode + endianWriter.Put8(NumericAttributeTraits::kNullValue); + } + else + { + bool value; + ReturnErrorOnFailure(reader.Get(value)); + endianWriter.Put8(value ? 1 : 0); + } + break; + case ZCL_INT8U_ATTRIBUTE_TYPE: // Unsigned 8-bit integer + case ZCL_INT16U_ATTRIBUTE_TYPE: // Unsigned 16-bit integer + case ZCL_INT24U_ATTRIBUTE_TYPE: // Unsigned 24-bit integer + case ZCL_INT32U_ATTRIBUTE_TYPE: // Unsigned 32-bit integer + case ZCL_INT40U_ATTRIBUTE_TYPE: // Unsigned 40-bit integer + case ZCL_INT48U_ATTRIBUTE_TYPE: // Unsigned 48-bit integer + case ZCL_INT56U_ATTRIBUTE_TYPE: // Unsigned 56-bit integer + case ZCL_INT64U_ATTRIBUTE_TYPE: // Unsigned 64-bit integer + ReturnErrorOnFailure(DecodeUnsignedInteger(reader, endianWriter)); + break; + case ZCL_INT8S_ATTRIBUTE_TYPE: // Signed 8-bit integer + case ZCL_INT16S_ATTRIBUTE_TYPE: // Signed 16-bit integer + case ZCL_INT24S_ATTRIBUTE_TYPE: // Signed 24-bit integer + case ZCL_INT32S_ATTRIBUTE_TYPE: // Signed 32-bit integer + case ZCL_INT40S_ATTRIBUTE_TYPE: // Signed 40-bit integer + case ZCL_INT48S_ATTRIBUTE_TYPE: // Signed 48-bit integer + case ZCL_INT56S_ATTRIBUTE_TYPE: // Signed 56-bit integer + case ZCL_INT64S_ATTRIBUTE_TYPE: // Signed 64-bit integer + ReturnErrorOnFailure(DecodeSignedInteger(reader, endianWriter)); + break; + case ZCL_SINGLE_ATTRIBUTE_TYPE: { // 32-bit float + float value; + if (reader.GetType() == TLV::kTLVType_Null) + { + // we know mIsNullable due to the check at the top of ::Decode + NumericAttributeTraits::SetNull(value); + } + else + { + + ReturnErrorOnFailure(reader.Get(value)); + } + endianWriter.Put(&value, sizeof(value)); + break; + } + case ZCL_DOUBLE_ATTRIBUTE_TYPE: { // 64-bit float + double value; + if (reader.GetType() == TLV::kTLVType_Null) + { + // we know mIsNullable due to the check at the top of ::Decode + NumericAttributeTraits::SetNull(value); + } + else + { + ReturnErrorOnFailure(reader.Get(value)); + } + endianWriter.Put(&value, sizeof(value)); + break; + } + case ZCL_CHAR_STRING_ATTRIBUTE_TYPE: // Char string + ReturnErrorOnFailure(DecodeAsString(reader, PascalStringType::kShort, TLV::kTLVType_UTF8String, endianWriter)); + break; + case ZCL_LONG_CHAR_STRING_ATTRIBUTE_TYPE: + ReturnErrorOnFailure(DecodeAsString(reader, PascalStringType::kLong, TLV::kTLVType_UTF8String, endianWriter)); + break; + case ZCL_OCTET_STRING_ATTRIBUTE_TYPE: // Octet string + ReturnErrorOnFailure(DecodeAsString(reader, PascalStringType::kShort, TLV::kTLVType_ByteString, endianWriter)); + break; + case ZCL_LONG_OCTET_STRING_ATTRIBUTE_TYPE: + ReturnErrorOnFailure(DecodeAsString(reader, PascalStringType::kLong, TLV::kTLVType_ByteString, endianWriter)); + break; + default: + ChipLogError(DataManagement, "Attribute type 0x%x not handled", mAttributeType); + return CHIP_IM_GLOBAL_STATUS(Failure); + } + + size_t written; + if (!endianWriter.Fit(written)) + { + return CHIP_ERROR_NO_MEMORY; + } + + mDataBuffer.reduce_size(written); + return CHIP_NO_ERROR; +} + +} // namespace Ember +} // namespace app +} // namespace chip diff --git a/src/app/codegen-data-model-provider/EmberAttributeDataBuffer.h b/src/app/codegen-data-model-provider/EmberAttributeDataBuffer.h new file mode 100644 index 00000000000000..a4f24c78c0476b --- /dev/null +++ b/src/app/codegen-data-model-provider/EmberAttributeDataBuffer.h @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#pragma once + +#include +#include +#include +#include +#include +#include + +namespace chip { +namespace app { +namespace Ember { + +/// This class represents a pointer to an ember-encoded attribute in a specific memory location. +/// +/// Ember attributes are stored as raw bytes for numeric types (i.e. memcpy-like storage except +/// unaligned) and strings are Pascal-like (short with 1-byte length prefix or long with 2-byte length +/// prefix). +/// +/// Class is to be used as a one-shot: +/// - create it out of metadata + data span +/// - call Decode (which modifies the input data span) +class EmberAttributeDataBuffer +{ +public: + enum class PascalStringType + { + kShort, + kLong, + }; + + static constexpr bool kIsFabricScoped = false; + + EmberAttributeDataBuffer(const EmberAfAttributeMetadata * meta, MutableByteSpan & data) : + mIsNullable(meta->IsNullable()), mAttributeType(chip::app::Compatibility::Internal::AttributeBaseType(meta->attributeType)), + mDataBuffer(data) + {} + + /// Reads the data pointed into by `reader` and updates the data + /// internally into mDataBuffer (which is then reflected outwards) + /// + /// Generally should be called ONLY ONCE as the internal mutable byte span gets + /// modified by this call. + CHIP_ERROR Decode(chip::TLV::TLVReader & reader); + +private: +#if CHIP_CONFIG_BIG_ENDIAN_TARGET + using EndianWriter = Encoding::BigEndian::BufferWriter; +#else + using EndianWriter = Encoding::LittleEndian::BufferWriter; +#endif + /// Decodes the UNSIGNED integer stored in `reader` and places its content into `writer` + /// Takes into account internal mIsNullable. + CHIP_ERROR DecodeUnsignedInteger(chip::TLV::TLVReader & reader, EndianWriter & writer); + + /// Decodes the SIGNED integer stored in `reader` and places its content into `writer` + /// Takes into account internal mIsNullable. + CHIP_ERROR DecodeSignedInteger(chip::TLV::TLVReader & reader, EndianWriter & writer); + + /// Decodes the string/byte string contained in `reader` and stores it into `writer`. + /// String is encoded using a pascal-prefix of size `stringType`. + /// Takes into account internal mIsNullable. + /// + /// The string in `reader` is expected to be of type `tlvType` + CHIP_ERROR DecodeAsString(chip::TLV::TLVReader & reader, PascalStringType stringType, TLV::TLVType tlvType, + EndianWriter & writer); + + const bool mIsNullable; // Contains if the attribute metadata marks the field as NULLABLE + const EmberAfAttributeType mAttributeType; // Initialized with the attribute type from the metadata + MutableByteSpan & mDataBuffer; // output buffer, modified by `Decode` +}; + +} // namespace Ember + +namespace DataModel { + +/// Helper method to forward the decode of this type to the class specific implementation +inline CHIP_ERROR Decode(TLV::TLVReader & reader, Ember::EmberAttributeDataBuffer & buffer) +{ + return buffer.Decode(reader); +} + +} // namespace DataModel +} // namespace app +} // namespace chip diff --git a/src/app/codegen-data-model-provider/model.cmake b/src/app/codegen-data-model-provider/model.cmake index 777219549e44eb..5ce4fbc84994ac 100644 --- a/src/app/codegen-data-model-provider/model.cmake +++ b/src/app/codegen-data-model-provider/model.cmake @@ -19,6 +19,8 @@ SET(CODEGEN_DATA_MODEL_SOURCES "${BASE_DIR}/CodegenDataModelProvider.h" "${BASE_DIR}/CodegenDataModelProvider_Read.cpp" "${BASE_DIR}/CodegenDataModelProvider_Write.cpp" + "${BASE_DIR}/EmberAttributeDataBuffer.cpp" + "${BASE_DIR}/EmberAttributeDataBuffer.h" "${BASE_DIR}/EmberMetadata.cpp" "${BASE_DIR}/EmberMetadata.h" "${BASE_DIR}/Instance.cpp" diff --git a/src/app/codegen-data-model-provider/model.gni b/src/app/codegen-data-model-provider/model.gni index b5909fb1c4f6f5..4205c6fcd73c25 100644 --- a/src/app/codegen-data-model-provider/model.gni +++ b/src/app/codegen-data-model-provider/model.gni @@ -29,6 +29,8 @@ codegen_data_model_SOURCES = [ "${chip_root}/src/app/codegen-data-model-provider/CodegenDataModelProvider.h", "${chip_root}/src/app/codegen-data-model-provider/CodegenDataModelProvider_Read.cpp", "${chip_root}/src/app/codegen-data-model-provider/CodegenDataModelProvider_Write.cpp", + "${chip_root}/src/app/codegen-data-model-provider/EmberAttributeDataBuffer.cpp", + "${chip_root}/src/app/codegen-data-model-provider/EmberAttributeDataBuffer.h", "${chip_root}/src/app/codegen-data-model-provider/EmberMetadata.cpp", "${chip_root}/src/app/codegen-data-model-provider/EmberMetadata.h", "${chip_root}/src/app/codegen-data-model-provider/Instance.cpp", diff --git a/src/app/codegen-data-model-provider/tests/BUILD.gn b/src/app/codegen-data-model-provider/tests/BUILD.gn index d8f82169b976a9..5bcfb9d911ab55 100644 --- a/src/app/codegen-data-model-provider/tests/BUILD.gn +++ b/src/app/codegen-data-model-provider/tests/BUILD.gn @@ -52,7 +52,10 @@ source_set("mock_model") { chip_test_suite("tests") { output_name = "libCodegenDataModelProviderTests" - test_sources = [ "TestCodegenModelViaMocks.cpp" ] + test_sources = [ + "TestCodegenModelViaMocks.cpp", + "TestEmberAttributeDataBuffer.cpp", + ] cflags = [ "-Wconversion" ] diff --git a/src/app/codegen-data-model-provider/tests/TestCodegenModelViaMocks.cpp b/src/app/codegen-data-model-provider/tests/TestCodegenModelViaMocks.cpp index 3840de9c8151dc..8ce369b7bd8220 100644 --- a/src/app/codegen-data-model-provider/tests/TestCodegenModelViaMocks.cpp +++ b/src/app/codegen-data-model-provider/tests/TestCodegenModelViaMocks.cpp @@ -2133,9 +2133,7 @@ TEST(TestCodegenModelViaMocks, EmberTestWriteOutOfRepresentableRangeOddIntegerNo using NullableType = chip::app::DataModel::Nullable; AttributeValueDecoder decoder = test.DecoderFor(0x1223344); - // write should fail: written value is not in range - // NOTE: this matches legacy behaviour, however realistically maybe ConstraintError would be more correct - ASSERT_EQ(model.WriteAttribute(test.GetRequest(), decoder), CHIP_ERROR_INVALID_ARGUMENT); + ASSERT_EQ(model.WriteAttribute(test.GetRequest(), decoder), CHIP_IM_GLOBAL_STATUS(ConstraintError)); } TEST(TestCodegenModelViaMocks, EmberTestWriteOutOfRepresentableRangeOddIntegerNullable) @@ -2151,12 +2149,10 @@ TEST(TestCodegenModelViaMocks, EmberTestWriteOutOfRepresentableRangeOddIntegerNu using NullableType = chip::app::DataModel::Nullable; AttributeValueDecoder decoder = test.DecoderFor(0x1223344); - // write should fail: written value is not in range - // NOTE: this matches legacy behaviour, however realistically maybe ConstraintError would be more correct - ASSERT_EQ(model.WriteAttribute(test.GetRequest(), decoder), CHIP_ERROR_INVALID_ARGUMENT); + ASSERT_EQ(model.WriteAttribute(test.GetRequest(), decoder), CHIP_IM_GLOBAL_STATUS(ConstraintError)); } -TEST(TestCodegenModelViaMoceNullValueToNullables, EmberAttributeWriteBasicTypesLowestValue) +TEST(TestCodegenModelViaMocksNullValueToNullables, EmberAttributeWriteBasicTypesLowestValue) { TestEmberScalarTypeWrite(-127); TestEmberScalarTypeWrite(-32767); diff --git a/src/app/codegen-data-model-provider/tests/TestEmberAttributeDataBuffer.cpp b/src/app/codegen-data-model-provider/tests/TestEmberAttributeDataBuffer.cpp new file mode 100644 index 00000000000000..bc089c8a798a6a --- /dev/null +++ b/src/app/codegen-data-model-provider/tests/TestEmberAttributeDataBuffer.cpp @@ -0,0 +1,616 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +using namespace chip; +using namespace chip::app; + +namespace { + +/// encodes a simple value in a TLV buffer +class TLVEncodedValue +{ +public: + TLVEncodedValue() = default; + ~TLVEncodedValue() = default; + + template + TLV::TLVReader EncodeValue(const T & value) + { + const auto kTag = TLV::ContextTag(AttributeDataIB::Tag::kData); + + TLV::TLVWriter writer; + writer.Init(mBuffer, sizeof(mBuffer)); + + TLV::TLVType outer; + + VerifyOrDie(writer.StartContainer(TLV::AnonymousTag(), TLV::kTLVType_Structure, outer) == CHIP_NO_ERROR); + VerifyOrDie(DataModel::Encode(writer, kTag, value) == CHIP_NO_ERROR); + VerifyOrDie(writer.EndContainer(outer) == CHIP_NO_ERROR); + + VerifyOrDie(writer.Finalize() == CHIP_NO_ERROR); + size_t fill = writer.GetLengthWritten(); + + TLV::TLVReader reader; + reader.Init(mBuffer, fill); + VerifyOrDie(reader.Next() == CHIP_NO_ERROR); + VerifyOrDie(reader.GetTag() == TLV::AnonymousTag()); + VerifyOrDie(reader.EnterContainer(outer) == CHIP_NO_ERROR); + VerifyOrDie(reader.Next() == CHIP_NO_ERROR); + VerifyOrDie(reader.GetTag() == kTag); + + return reader; + } + +private: + static constexpr size_t kMaxSize = 128; + uint8_t mBuffer[kMaxSize]; +}; + +class EncodeResult +{ +public: + explicit EncodeResult() = default; + EncodeResult(CHIP_ERROR error) : mResult(error) { VerifyOrDie(error != CHIP_NO_ERROR); } + + static EncodeResult Ok() { return EncodeResult(); } + + bool IsSuccess() const { return !mResult.has_value(); } + + bool operator==(const CHIP_ERROR & other) const { return mResult.has_value() && (*mResult == other); } + + const std::optional & Value() const { return mResult; } + +private: + std::optional mResult; +}; + +/// Validates that an encoded value in ember takes a specific format +template +class EncodeTester +{ +public: + EncodeTester(const EmberAfAttributeMetadata * meta) : mMetaData(meta) {} + ~EncodeTester() = default; + + template + EncodeResult TryEncode(const T & value, const uint8_t (&arr)[N]) + { + ByteSpan expected(arr); + MutableByteSpan out_span(mEmberAttributeDataBuffer); + Ember::EmberAttributeDataBuffer buffer(mMetaData, out_span); + + TLVEncodedValue tlvEncoded; + TLV::TLVReader reader = tlvEncoded.EncodeValue(value); + + CHIP_ERROR err = buffer.Decode(reader); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Test, "Decoding failed: %" CHIP_ERROR_FORMAT, err.Format()); + return err; + } + + if (expected.size() != out_span.size()) + { + ChipLogError(Test, "Decode mismatch in size: expected %u, got %u", static_cast(expected.size()), + static_cast(out_span.size())); + return CHIP_ERROR_INTERNAL; + } + + if (!expected.data_equal(out_span)) + { + ChipLogError(Test, "Decode mismatch in content for %u bytes", static_cast(expected.size())); + return CHIP_ERROR_INTERNAL; + } + + return EncodeResult::Ok(); + } + +private: + const EmberAfAttributeMetadata * mMetaData; + uint8_t mEmberAttributeDataBuffer[kMaxSize]; +}; + +const EmberAfAttributeMetadata * CreateFakeMeta(EmberAfAttributeType type, bool nullable) +{ + static EmberAfAttributeMetadata meta = { + .defaultValue = EmberAfDefaultOrMinMaxAttributeValue(static_cast(nullptr)), + .attributeId = 0, + .size = 0, // likely not valid, however not used for tests + .attributeType = ZCL_UNKNOWN_ATTRIBUTE_TYPE, + .mask = 0, + }; + + meta.attributeType = type; + meta.mask = nullable ? ATTRIBUTE_MASK_NULLABLE : 0; + + return &meta; +} + +} // namespace +// +namespace pw { + +// Pretty format in case of errors +template <> +StatusWithSize ToString(const EncodeResult & result, pw::span buffer) +{ + const std::optional & value = result.Value(); + + if (!value.has_value()) + { + return pw::string::Format(buffer, "SuccessResult"); + } + + return pw::string::Format(buffer, "FailureResult:CHIP_ERROR:<%" CHIP_ERROR_FORMAT ">", value->Format()); +} + +} // namespace pw + +// All the tests below assume buffer ordering in little endian format +// Since currently all chip platforms in CI are little endian, we just kept tests +// as-is +static_assert(!CHIP_CONFIG_BIG_ENDIAN_TARGET); + +TEST(TestEmberAttributeBuffer, TestEncodeUnsignedTypes) +{ + { + EncodeTester tester(CreateFakeMeta(ZCL_INT8U_ATTRIBUTE_TYPE, false /* nullable */)); + + EXPECT_TRUE(tester.TryEncode(0, { 0 }).IsSuccess()); + EXPECT_TRUE(tester.TryEncode(123, { 123 }).IsSuccess()); + EXPECT_TRUE(tester.TryEncode(0xFD, { 0xFD }).IsSuccess()); + EXPECT_TRUE(tester.TryEncode(255, { 0xFF }).IsSuccess()); + } + + { + EncodeTester tester(CreateFakeMeta(ZCL_INT8U_ATTRIBUTE_TYPE, true /* nullable */)); + + EXPECT_TRUE(tester.TryEncode(0, { 0 }).IsSuccess()); + EXPECT_TRUE(tester.TryEncode(123, { 123 }).IsSuccess()); + EXPECT_TRUE(tester.TryEncode(0xFD, { 0xFD }).IsSuccess()); + EXPECT_TRUE(tester.TryEncode>(DataModel::NullNullable, { 0xFF }).IsSuccess()); + + // Not allowed to encode null-equivalent + EXPECT_EQ(tester.TryEncode(0xFF, { 0xFF }), CHIP_IM_GLOBAL_STATUS(ConstraintError)); + } + + { + EncodeTester tester(CreateFakeMeta(ZCL_INT16U_ATTRIBUTE_TYPE, false /* nullable */)); + + EXPECT_TRUE(tester.TryEncode(0, { 0, 0 }).IsSuccess()); + EXPECT_TRUE(tester.TryEncode(123, { 123, 0 }).IsSuccess()); + EXPECT_TRUE(tester.TryEncode(0xFD, { 0xFD, 0 }).IsSuccess()); + EXPECT_TRUE(tester.TryEncode(255, { 0xFF, 0 }).IsSuccess()); + EXPECT_TRUE(tester.TryEncode(0xABCD, { 0xCD, 0xAB }).IsSuccess()); + EXPECT_TRUE(tester.TryEncode(0xFFFF, { 0xFF, 0xFF }).IsSuccess()); + } + + { + EncodeTester tester(CreateFakeMeta(ZCL_INT16U_ATTRIBUTE_TYPE, true /* nullable */)); + + EXPECT_TRUE(tester.TryEncode(0, { 0, 0 }).IsSuccess()); + EXPECT_TRUE(tester.TryEncode(123, { 123, 0 }).IsSuccess()); + EXPECT_TRUE(tester.TryEncode(0xFD, { 0xFD, 0 }).IsSuccess()); + EXPECT_TRUE(tester.TryEncode(255, { 0xFF, 0 }).IsSuccess()); + EXPECT_TRUE(tester.TryEncode(0xABCD, { 0xCD, 0xAB }).IsSuccess()); + EXPECT_TRUE(tester.TryEncode>(DataModel::NullNullable, { 0xFF, 0xFF }).IsSuccess()); + + // Not allowed to encode null-equivalent + EXPECT_EQ(tester.TryEncode(0xFFFF, { 0xFF, 0xFF }), CHIP_IM_GLOBAL_STATUS(ConstraintError)); + } + { + EncodeTester tester(CreateFakeMeta(ZCL_INT64U_ATTRIBUTE_TYPE, true /* nullable */)); + + EXPECT_TRUE(tester.TryEncode(0, { 0, 0, 0, 0, 0, 0, 0, 0 }).IsSuccess()); + EXPECT_TRUE(tester.TryEncode(0x1234567, { 0x67, 0x45, 0x23, 0x01, 0, 0, 0, 0 }).IsSuccess()); + EXPECT_TRUE(tester.TryEncode(0xAABBCCDDEEFF1122, { 0x22, 0x11, 0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA }).IsSuccess()); + EXPECT_TRUE( + tester.TryEncode(std::numeric_limits::max() - 1, { 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }) + .IsSuccess()); + + EXPECT_TRUE(tester + .TryEncode>(DataModel::NullNullable, + { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }) + .IsSuccess()); + + EXPECT_EQ( + tester.TryEncode(std::numeric_limits::max(), { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }), + CHIP_IM_GLOBAL_STATUS(ConstraintError)); + } + { + EncodeTester tester(CreateFakeMeta(ZCL_INT64U_ATTRIBUTE_TYPE, false /* nullable */)); + + // we should be able to encode the maximum value + EXPECT_TRUE( + tester.TryEncode(std::numeric_limits::max(), { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }) + .IsSuccess()); + } + + /// Odd sized integers + { + EncodeTester tester(CreateFakeMeta(ZCL_INT24U_ATTRIBUTE_TYPE, false /* nullable */)); + EXPECT_TRUE(tester.TryEncode(0, { 0, 0, 0 }).IsSuccess()); + EXPECT_TRUE(tester.TryEncode(0x123456, { 0x56, 0x34, 0x12 }).IsSuccess()); + EXPECT_TRUE(tester.TryEncode(0xFFFFFF, { 0xFF, 0xFF, 0xFF }).IsSuccess()); + + // Out of range + EXPECT_EQ(tester.TryEncode(0x1000000, { 0 }), CHIP_IM_GLOBAL_STATUS(ConstraintError)); + EXPECT_EQ(tester.TryEncode(0xFF000000, { 0 }), CHIP_IM_GLOBAL_STATUS(ConstraintError)); + } + { + EncodeTester tester(CreateFakeMeta(ZCL_INT24U_ATTRIBUTE_TYPE, true /* nullable */)); + EXPECT_TRUE(tester.TryEncode(0, { 0, 0, 0 }).IsSuccess()); + EXPECT_TRUE(tester.TryEncode(0x123456, { 0x56, 0x34, 0x12 }).IsSuccess()); + EXPECT_TRUE(tester.TryEncode>(DataModel::NullNullable, { 0xFF, 0xFF, 0xFF }).IsSuccess()); + + // Out of range + EXPECT_EQ(tester.TryEncode(0x1000000, { 0 }), CHIP_IM_GLOBAL_STATUS(ConstraintError)); + // cannot encode null equivalent value + EXPECT_EQ(tester.TryEncode(0xFFFFFF, { 0x56, 0x34, 0x12 }), CHIP_IM_GLOBAL_STATUS(ConstraintError)); + } + + { + EncodeTester tester(CreateFakeMeta(ZCL_INT40U_ATTRIBUTE_TYPE, true /* nullable */)); + EXPECT_TRUE(tester.TryEncode(0, { 0, 0, 0, 0, 0 }).IsSuccess()); + EXPECT_TRUE(tester.TryEncode(0x123456, { 0x56, 0x34, 0x12, 0, 0 }).IsSuccess()); + EXPECT_TRUE(tester.TryEncode(0x123456FFFF, { 0xFF, 0xFF, 0x56, 0x34, 0x12 }).IsSuccess()); + EXPECT_TRUE( + tester.TryEncode>(DataModel::NullNullable, { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }).IsSuccess()); + + // Out of range + EXPECT_EQ(tester.TryEncode(0x10011001100, { 0 }), CHIP_IM_GLOBAL_STATUS(ConstraintError)); + // cannot encode null equivalent value + EXPECT_EQ(tester.TryEncode(0xFFFFFFFFFF, { 0 }), CHIP_IM_GLOBAL_STATUS(ConstraintError)); + } + + // Double-check tests, not as exhaustive, to cover all other unsigned values and get + // more test line coverage + { + EncodeTester tester(CreateFakeMeta(ZCL_INT32U_ATTRIBUTE_TYPE, true /* nullable */)); + EXPECT_TRUE(tester.TryEncode(0x1234, { 0x34, 0x12, 0, 0 }).IsSuccess()); + } + { + EncodeTester tester(CreateFakeMeta(ZCL_INT48U_ATTRIBUTE_TYPE, true /* nullable */)); + EXPECT_TRUE(tester.TryEncode(0x1234, { 0x34, 0x12, 0, 0, 0, 0 }).IsSuccess()); + } + { + EncodeTester tester(CreateFakeMeta(ZCL_INT56U_ATTRIBUTE_TYPE, true /* nullable */)); + EXPECT_TRUE(tester.TryEncode(0x1234, { 0x34, 0x12, 0, 0, 0, 0, 0 }).IsSuccess()); + } +} + +TEST(TestEmberAttributeBuffer, TestEncodeSignedTypes) +{ + { + EncodeTester tester(CreateFakeMeta(ZCL_INT8S_ATTRIBUTE_TYPE, false /* nullable */)); + + EXPECT_TRUE(tester.TryEncode(0, { 0 }).IsSuccess()); + EXPECT_TRUE(tester.TryEncode(123, { 123 }).IsSuccess()); + EXPECT_TRUE(tester.TryEncode(127, { 127 }).IsSuccess()); + EXPECT_TRUE(tester.TryEncode(-10, { 0xF6 }).IsSuccess()); + EXPECT_TRUE(tester.TryEncode(-128, { 0x80 }).IsSuccess()); + } + + { + EncodeTester tester(CreateFakeMeta(ZCL_INT8S_ATTRIBUTE_TYPE, true /* nullable */)); + + EXPECT_TRUE(tester.TryEncode(0, { 0 }).IsSuccess()); + EXPECT_TRUE(tester.TryEncode(123, { 123 }).IsSuccess()); + EXPECT_TRUE(tester.TryEncode(127, { 127 }).IsSuccess()); + EXPECT_TRUE(tester.TryEncode(-10, { 0xF6 }).IsSuccess()); + EXPECT_TRUE(tester.TryEncode(-127, { 0x81 }).IsSuccess()); + + // NULL canot be encoded + EXPECT_EQ(tester.TryEncode(std::numeric_limits::min(), { 0x80 }), CHIP_IM_GLOBAL_STATUS(ConstraintError)); + } + { + + EncodeTester tester(CreateFakeMeta(ZCL_INT16S_ATTRIBUTE_TYPE, false /* nullable */)); + + EXPECT_TRUE(tester.TryEncode(0, { 0, 0 }).IsSuccess()); + EXPECT_TRUE(tester.TryEncode(123, { 123, 0 }).IsSuccess()); + EXPECT_TRUE(tester.TryEncode(127, { 127, 0 }).IsSuccess()); + EXPECT_TRUE(tester.TryEncode(-10, { 0xF6, 0xFF }).IsSuccess()); + EXPECT_TRUE(tester.TryEncode(-128, { 0x80, 0xFF }).IsSuccess()); + EXPECT_TRUE(tester.TryEncode(-1234, { 0x2E, 0xFB }).IsSuccess()); + EXPECT_TRUE(tester.TryEncode(std::numeric_limits::min(), { 0x0, 0x80 }).IsSuccess()); + } + + { + EncodeTester tester(CreateFakeMeta(ZCL_INT16S_ATTRIBUTE_TYPE, true /* nullable */)); + + EXPECT_TRUE(tester.TryEncode(0, { 0, 0 }).IsSuccess()); + EXPECT_TRUE(tester.TryEncode(123, { 123, 0 }).IsSuccess()); + EXPECT_TRUE(tester.TryEncode(127, { 127, 0 }).IsSuccess()); + EXPECT_TRUE(tester.TryEncode(-10, { 0xF6, 0xFF }).IsSuccess()); + + // NULL canot be encoded + EXPECT_EQ(tester.TryEncode(std::numeric_limits::min(), { 0x80 }), CHIP_IM_GLOBAL_STATUS(ConstraintError)); + } + + // Odd size integers + { + EncodeTester tester(CreateFakeMeta(ZCL_INT24S_ATTRIBUTE_TYPE, false /* nullable */)); + + EXPECT_TRUE(tester.TryEncode(0, { 0, 0, 0 }).IsSuccess()); + EXPECT_TRUE(tester.TryEncode(0x123456, { 0x56, 0x34, 0x12 }).IsSuccess()); + EXPECT_TRUE(tester.TryEncode(-1, { 0xFF, 0xFF, 0xFF }).IsSuccess()); + EXPECT_TRUE(tester.TryEncode(-10, { 0xF6, 0xFF, 0xFF }).IsSuccess()); + EXPECT_TRUE(tester.TryEncode(-1234, { 0x2E, 0xFB, 0xFF }).IsSuccess()); + + // Out of range + EXPECT_EQ(tester.TryEncode(0x1000000, { 0 }), CHIP_IM_GLOBAL_STATUS(ConstraintError)); + EXPECT_EQ(tester.TryEncode(0x0F000000, { 0 }), CHIP_IM_GLOBAL_STATUS(ConstraintError)); + EXPECT_EQ(tester.TryEncode(-0x1000000, { 0 }), CHIP_IM_GLOBAL_STATUS(ConstraintError)); + } + { + EncodeTester tester(CreateFakeMeta(ZCL_INT24S_ATTRIBUTE_TYPE, true /* nullable */)); + + EXPECT_TRUE(tester.TryEncode(0, { 0, 0, 0 }).IsSuccess()); + EXPECT_TRUE(tester.TryEncode(0x123456, { 0x56, 0x34, 0x12 }).IsSuccess()); + EXPECT_TRUE(tester.TryEncode(-1, { 0xFF, 0xFF, 0xFF }).IsSuccess()); + EXPECT_TRUE(tester.TryEncode(-10, { 0xF6, 0xFF, 0xFF }).IsSuccess()); + EXPECT_TRUE(tester.TryEncode(-1234, { 0x2E, 0xFB, 0xFF }).IsSuccess()); + + EXPECT_TRUE(tester.TryEncode>(DataModel::NullNullable, { 0x00, 0x00, 0x80 }).IsSuccess()); + + // Out of range + EXPECT_EQ(tester.TryEncode(0x1000000, { 0 }), CHIP_IM_GLOBAL_STATUS(ConstraintError)); + // cannot encode null equivalent value - this is the minimum negative value + // for 24-bit + EXPECT_EQ(tester.TryEncode(-(1 << 24) - 1, { 0x56, 0x34, 0x12 }), CHIP_IM_GLOBAL_STATUS(ConstraintError)); + + // Out of range for signed - these are unsigned values that are larger + EXPECT_EQ(tester.TryEncode(0xFFFFFF, { 0x56, 0x34, 0x12 }), CHIP_IM_GLOBAL_STATUS(ConstraintError)); + EXPECT_EQ(tester.TryEncode(0x800000, { 0x56, 0x34, 0x12 }), CHIP_IM_GLOBAL_STATUS(ConstraintError)); + } + + { + EncodeTester tester(CreateFakeMeta(ZCL_INT40S_ATTRIBUTE_TYPE, true /* nullable */)); + + // NOTE: to generate encoded values, you an use commands like: + // + // python -c 'import struct; print(", ".join(["0x%X" % v for v in struct.pack("(0, { 0, 0, 0, 0, 0 }).IsSuccess()); + EXPECT_TRUE(tester.TryEncode(0x123456, { 0x56, 0x34, 0x12, 0, 0 }).IsSuccess()); + EXPECT_TRUE(tester.TryEncode(-1234, { 0x2E, 0xFB, 0xFF, 0xFF, 0xFF }).IsSuccess()); + EXPECT_TRUE(tester.TryEncode(-123456789, { 0xeb, 0x32, 0xa4, 0xf8, 0xFF }).IsSuccess()); + EXPECT_TRUE(tester.TryEncode(-12345678910, { 0xc2, 0xe3, 0x23, 0x20, 0xfd }).IsSuccess()); + + EXPECT_TRUE( + tester.TryEncode>(DataModel::NullNullable, { 0x00, 0x00, 0x00, 0x00, 0x80 }).IsSuccess()); + + // Out of range + EXPECT_EQ(tester.TryEncode(0x10011001100, { 0 }), CHIP_IM_GLOBAL_STATUS(ConstraintError)); + // cannot encode null equivalent value + EXPECT_EQ(tester.TryEncode(-(1LL << 40) - 1, { 0 }), CHIP_IM_GLOBAL_STATUS(ConstraintError)); + // negative out of range + EXPECT_EQ(tester.TryEncode(-0x10000000000, { 0 }), CHIP_IM_GLOBAL_STATUS(ConstraintError)); + } + + // Double-check tests, not as exhaustive, to cover all other unsigned values and get + // more test line coverage + { + EncodeTester tester(CreateFakeMeta(ZCL_INT32S_ATTRIBUTE_TYPE, true /* nullable */)); + EXPECT_TRUE(tester.TryEncode(-1234, { 0x2E, 0xFB, 0xFF, 0xFF }).IsSuccess()); + } + { + EncodeTester tester(CreateFakeMeta(ZCL_INT48S_ATTRIBUTE_TYPE, true /* nullable */)); + EXPECT_TRUE(tester.TryEncode(-1234, { 0x2E, 0xFB, 0xFF, 0xFF, 0xFF, 0xFF }).IsSuccess()); + } + { + EncodeTester tester(CreateFakeMeta(ZCL_INT56S_ATTRIBUTE_TYPE, true /* nullable */)); + EXPECT_TRUE(tester.TryEncode(-1234, { 0x2E, 0xFB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }).IsSuccess()); + } + + { + EncodeTester tester(CreateFakeMeta(ZCL_INT64S_ATTRIBUTE_TYPE, true /* nullable */)); + EXPECT_TRUE(tester.TryEncode(-1234, { 0x2E, 0xFB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }).IsSuccess()); + + // min/max ranges too + EXPECT_TRUE( + tester.TryEncode(std::numeric_limits::min() + 1, { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80 }) + .IsSuccess()); + EXPECT_TRUE( + tester.TryEncode(std::numeric_limits::max(), { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F }) + .IsSuccess()); + + // Reserved value for NULL + EXPECT_EQ( + tester.TryEncode(std::numeric_limits::min(), { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80 }), + CHIP_IM_GLOBAL_STATUS(ConstraintError)); + } + + { + EncodeTester tester(CreateFakeMeta(ZCL_INT64S_ATTRIBUTE_TYPE, false /* nullable */)); + EXPECT_TRUE(tester.TryEncode(-1234, { 0x2E, 0xFB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }).IsSuccess()); + + EXPECT_TRUE( + tester.TryEncode(std::numeric_limits::min(), { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80 }) + .IsSuccess()); + EXPECT_TRUE( + tester.TryEncode(std::numeric_limits::min() + 1, { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80 }) + .IsSuccess()); + EXPECT_TRUE( + tester.TryEncode(std::numeric_limits::max(), { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F }) + .IsSuccess()); + } +} + +TEST(TestEmberAttributeBuffer, TestEncodeBool) +{ + { + EncodeTester tester(CreateFakeMeta(ZCL_BOOLEAN_ATTRIBUTE_TYPE, false /* nullable */)); + + EXPECT_TRUE(tester.TryEncode(true, { 1 }).IsSuccess()); + EXPECT_TRUE(tester.TryEncode(false, { 0 }).IsSuccess()); + } + + { + EncodeTester tester(CreateFakeMeta(ZCL_BOOLEAN_ATTRIBUTE_TYPE, true /* nullable */)); + + EXPECT_TRUE(tester.TryEncode(true, { 1 }).IsSuccess()); + EXPECT_TRUE(tester.TryEncode(false, { 0 }).IsSuccess()); + EXPECT_TRUE(tester.TryEncode>(DataModel::NullNullable, { 0xFF }).IsSuccess()); + } +} + +TEST(TestEmberAttributeBuffer, TestEncodeFloatingPoint) +{ + // NOTE: to generate encoded values, you an use commands like: + // + // python -c 'import struct; print(", ".join(["0x%X" % v for v in struct.pack("(123.55f, { 0x9A, 0x19, 0xF7, 0x42 }).IsSuccess()); + } + + { + EncodeTester tester(CreateFakeMeta(ZCL_SINGLE_ATTRIBUTE_TYPE, true /* nullable */)); + EXPECT_TRUE(tester.TryEncode(123.55f, { 0x9A, 0x19, 0xF7, 0x42 }).IsSuccess()); + EXPECT_TRUE(tester.TryEncode>(DataModel::NullNullable, { 0, 0, 0xC0, 0x7F }).IsSuccess()); + } + + { + EncodeTester tester(CreateFakeMeta(ZCL_DOUBLE_ATTRIBUTE_TYPE, false /* nullable */)); + EXPECT_TRUE(tester.TryEncode(123.55, { 0x33, 0x33, 0x33, 0x33, 0x33, 0xE3, 0x5E, 0x40 }).IsSuccess()); + } + + { + EncodeTester tester(CreateFakeMeta(ZCL_DOUBLE_ATTRIBUTE_TYPE, true /* nullable */)); + EXPECT_TRUE(tester.TryEncode(123.55, { 0x33, 0x33, 0x33, 0x33, 0x33, 0xE3, 0x5E, 0x40 }).IsSuccess()); + EXPECT_TRUE( + tester.TryEncode>(DataModel::NullNullable, { 0, 0, 0, 0, 0, 0, 0xF8, 0x7F }).IsSuccess()); + } +} + +TEST(TestEmberAttributeBuffer, TestEncodeStrings) +{ + { + EncodeTester tester(CreateFakeMeta(ZCL_CHAR_STRING_ATTRIBUTE_TYPE, false /* nullable */)); + EXPECT_TRUE(tester.TryEncode(""_span, { 0 }).IsSuccess()); + EXPECT_TRUE(tester.TryEncode("test"_span, { 4, 't', 'e', 's', 't' }).IsSuccess()); + EXPECT_TRUE(tester.TryEncode("foo"_span, { 3, 'f', 'o', 'o' }).IsSuccess()); + } + + { + EncodeTester tester(CreateFakeMeta(ZCL_CHAR_STRING_ATTRIBUTE_TYPE, true /* nullable */)); + EXPECT_TRUE(tester.TryEncode(""_span, { 0 }).IsSuccess()); + EXPECT_TRUE(tester.TryEncode("test"_span, { 4, 't', 'e', 's', 't' }).IsSuccess()); + EXPECT_TRUE(tester.TryEncode>(DataModel::NullNullable, { 0xFF }).IsSuccess()); + } + + { + EncodeTester tester(CreateFakeMeta(ZCL_LONG_CHAR_STRING_ATTRIBUTE_TYPE, false /* nullable */)); + EXPECT_TRUE(tester.TryEncode(""_span, { 0, 0 }).IsSuccess()); + EXPECT_TRUE(tester.TryEncode("test"_span, { 4, 0, 't', 'e', 's', 't' }).IsSuccess()); + EXPECT_TRUE(tester.TryEncode("foo"_span, { 3, 0, 'f', 'o', 'o' }).IsSuccess()); + } + + { + EncodeTester tester(CreateFakeMeta(ZCL_LONG_CHAR_STRING_ATTRIBUTE_TYPE, true /* nullable */)); + EXPECT_TRUE(tester.TryEncode("test"_span, { 4, 0, 't', 'e', 's', 't' }).IsSuccess()); + EXPECT_TRUE(tester.TryEncode>(DataModel::NullNullable, { 0xFF, 0xFF }).IsSuccess()); + } + + const uint8_t kOctetData[] = { 1, 2, 3 }; + + // Binary data + { + EncodeTester tester(CreateFakeMeta(ZCL_OCTET_STRING_ATTRIBUTE_TYPE, false /* nullable */)); + EXPECT_TRUE(tester.TryEncode(ByteSpan({}), { 0 }).IsSuccess()); + EXPECT_TRUE(tester.TryEncode(ByteSpan(kOctetData), { 3, 1, 2, 3 }).IsSuccess()); + } + + { + EncodeTester tester(CreateFakeMeta(ZCL_OCTET_STRING_ATTRIBUTE_TYPE, true /* nullable */)); + EXPECT_TRUE(tester.TryEncode(ByteSpan({}), { 0 }).IsSuccess()); + EXPECT_TRUE(tester.TryEncode(ByteSpan(kOctetData), { 3, 1, 2, 3 }).IsSuccess()); + EXPECT_TRUE(tester.TryEncode>(DataModel::NullNullable, { 0xFF }).IsSuccess()); + } + + { + EncodeTester tester(CreateFakeMeta(ZCL_LONG_OCTET_STRING_ATTRIBUTE_TYPE, false /* nullable */)); + EXPECT_TRUE(tester.TryEncode(ByteSpan({}), { 0, 0 }).IsSuccess()); + EXPECT_TRUE(tester.TryEncode(ByteSpan(kOctetData), { 3, 0, 1, 2, 3 }).IsSuccess()); + } + + { + EncodeTester tester(CreateFakeMeta(ZCL_LONG_OCTET_STRING_ATTRIBUTE_TYPE, true /* nullable */)); + EXPECT_TRUE(tester.TryEncode(ByteSpan({}), { 0, 0 }).IsSuccess()); + EXPECT_TRUE(tester.TryEncode(ByteSpan(kOctetData), { 3, 0, 1, 2, 3 }).IsSuccess()); + EXPECT_TRUE(tester.TryEncode>(DataModel::NullNullable, { 0xFF, 0xFF }).IsSuccess()); + } +} + +TEST(TestEmberAttributeBuffer, TestFailures) +{ + { + // attribute type that is not handled + EncodeTester tester(CreateFakeMeta(ZCL_UNKNOWN_ATTRIBUTE_TYPE, true /* nullable */)); + EXPECT_EQ(tester.TryEncode>(DataModel::NullNullable, { 0 }), CHIP_IM_GLOBAL_STATUS(Failure)); + } + + { + // Insufficient space + EncodeTester<3> tester(CreateFakeMeta(ZCL_CHAR_STRING_ATTRIBUTE_TYPE, true /* nullable */)); + EXPECT_TRUE(tester.TryEncode(""_span, { 0 }).IsSuccess()); + EXPECT_EQ(tester.TryEncode("test"_span, { 0 }), CHIP_ERROR_NO_MEMORY); + EXPECT_TRUE(tester.TryEncode>(DataModel::NullNullable, { 0xFF }).IsSuccess()); + } + + // bad type casts + { + EncodeTester tester(CreateFakeMeta(ZCL_CHAR_STRING_ATTRIBUTE_TYPE, false /* nullable */)); + EXPECT_EQ(tester.TryEncode(ByteSpan({}), { 0 }), CHIP_ERROR_WRONG_TLV_TYPE); + } + { + EncodeTester tester(CreateFakeMeta(ZCL_INT32U_ATTRIBUTE_TYPE, false /* nullable */)); + EXPECT_EQ(tester.TryEncode(true, { 0 }), CHIP_ERROR_WRONG_TLV_TYPE); + } +} diff --git a/src/app/util/attribute-storage-null-handling.h b/src/app/util/attribute-storage-null-handling.h index 826e5aff531a98..22dd0e6dab5ce3 100644 --- a/src/app/util/attribute-storage-null-handling.h +++ b/src/app/util/attribute-storage-null-handling.h @@ -246,7 +246,6 @@ struct NumericAttributeTraits static uint8_t MaxValue(bool isNullable) { return 1; } -private: static constexpr StorageType kNullValue = 0xFF; }; diff --git a/src/app/util/odd-sized-integers.h b/src/app/util/odd-sized-integers.h index 32f2c8793b2e71..447f56444c0bdb 100644 --- a/src/app/util/odd-sized-integers.h +++ b/src/app/util/odd-sized-integers.h @@ -20,6 +20,7 @@ #include #include +#include #include namespace chip { @@ -91,6 +92,59 @@ struct IntegerByteIndexing }; } // namespace detail +namespace NumericLimits { + +// Generic size information for unsigned values. +// +// Assumes non-nullable types. Nullable types reserve one of the values as NULL (the max) +inline constexpr uint64_t MaxUnsignedValue(unsigned ByteSize) +{ + if (ByteSize == 8) + { + return std::numeric_limits::max(); + } + return (1ULL << (8 * ByteSize)) - 1; +} + +/// Readability-method to express that the maximum unsigned value is a null value +/// +/// Our encoding states that max int value is the NULL value +inline constexpr uint64_t UnsignedMaxValueToNullValue(uint64_t value) +{ + return value; +} + +// Generic size information for signed values. +// +// Assumes non-nullable types. Nullable types reserve one of the values as NULL (the min) +inline constexpr int64_t MaxSignedValue(unsigned ByteSize) +{ + if (ByteSize == 8) + { + return std::numeric_limits::max(); + } + return (static_cast(1) << (8 * ByteSize - 1)) - 1; +} + +inline constexpr int64_t MinSignedValue(unsigned ByteSize) +{ + if (ByteSize == 8) + { + return std::numeric_limits::min(); + } + return -(static_cast(1) << (8 * ByteSize - 1)); +} + +/// Readability-method to express that the maximum signed value is a null value +/// +/// Our encoding states that min int value is the NULL value +inline constexpr int64_t SignedMinValueToNullValue(int64_t value) +{ + return value; +} + +} // namespace NumericLimits + template struct NumericAttributeTraits, IsBigEndian> : detail::IntegerByteIndexing { From 515bc3b8e036329bd78bef82c166c0b51e81cf73 Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Thu, 24 Oct 2024 10:31:01 -0400 Subject: [PATCH 100/149] Remove the ToString from pigweed as googletest complains (#36228) Co-authored-by: Andrei Litvin --- .../tests/TestEmberAttributeDataBuffer.cpp | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/src/app/codegen-data-model-provider/tests/TestEmberAttributeDataBuffer.cpp b/src/app/codegen-data-model-provider/tests/TestEmberAttributeDataBuffer.cpp index bc089c8a798a6a..7d46360029c529 100644 --- a/src/app/codegen-data-model-provider/tests/TestEmberAttributeDataBuffer.cpp +++ b/src/app/codegen-data-model-provider/tests/TestEmberAttributeDataBuffer.cpp @@ -164,24 +164,6 @@ const EmberAfAttributeMetadata * CreateFakeMeta(EmberAfAttributeType type, bool } } // namespace -// -namespace pw { - -// Pretty format in case of errors -template <> -StatusWithSize ToString(const EncodeResult & result, pw::span buffer) -{ - const std::optional & value = result.Value(); - - if (!value.has_value()) - { - return pw::string::Format(buffer, "SuccessResult"); - } - - return pw::string::Format(buffer, "FailureResult:CHIP_ERROR:<%" CHIP_ERROR_FORMAT ">", value->Format()); -} - -} // namespace pw // All the tests below assume buffer ordering in little endian format // Since currently all chip platforms in CI are little endian, we just kept tests From e0abf7a8bee418d39823c638cfa8929b5e7769ab Mon Sep 17 00:00:00 2001 From: Mathieu Kardous <84793247+mkardous-silabs@users.noreply.github.com> Date: Thu, 24 Oct 2024 11:05:34 -0400 Subject: [PATCH 101/149] [ICD] Set MaximumCheckInBackOff to external and fix define guards for unit test members (#36223) * Fix ICD manager and attributes * Generated files * zap regen --- src/app/icd/server/ICDManager.cpp | 10 ++-- src/app/icd/server/ICDManager.h | 6 +-- .../zcl/zcl-with-test-extensions.json | 3 +- src/app/zap-templates/zcl/zcl.json | 3 +- .../zap-generated/attributes/Accessors.cpp | 47 ------------------- .../zap-generated/attributes/Accessors.h | 6 --- 6 files changed, 12 insertions(+), 63 deletions(-) diff --git a/src/app/icd/server/ICDManager.cpp b/src/app/icd/server/ICDManager.cpp index ba349b22b972a5..6efa43875fdf46 100644 --- a/src/app/icd/server/ICDManager.cpp +++ b/src/app/icd/server/ICDManager.cpp @@ -117,13 +117,13 @@ void ICDManager::Shutdown() bool ICDManager::SupportsFeature(Feature feature) { // Can't use attribute accessors/Attributes::FeatureMap::Get in unit tests -#if !CONFIG_BUILD_FOR_HOST_UNIT_TEST +#if !(CONFIG_BUILD_FOR_HOST_UNIT_TEST) uint32_t featureMap = 0; bool success = (Attributes::FeatureMap::Get(kRootEndpointId, &featureMap) == Status::Success); return success ? ((featureMap & to_underlying(feature)) != 0) : false; #else return ((mFeatureMap & to_underlying(feature)) != 0); -#endif // !CONFIG_BUILD_FOR_HOST_UNIT_TEST +#endif // !(CONFIG_BUILD_FOR_HOST_UNIT_TEST) } uint32_t ICDManager::StayActiveRequest(uint32_t stayActiveDuration) @@ -145,7 +145,7 @@ uint32_t ICDManager::StayActiveRequest(uint32_t stayActiveDuration) #if CHIP_CONFIG_ENABLE_ICD_CIP void ICDManager::SendCheckInMsgs() { -#if !CONFIG_BUILD_FOR_HOST_UNIT_TEST +#if !(CONFIG_BUILD_FOR_HOST_UNIT_TEST) VerifyOrDie(mStorage != nullptr); VerifyOrDie(mFabricTable != nullptr); @@ -213,7 +213,7 @@ void ICDManager::SendCheckInMsgs() } } } -#endif // CONFIG_BUILD_FOR_HOST_UNIT_TEST +#endif // !(CONFIG_BUILD_FOR_HOST_UNIT_TEST) } bool ICDManager::CheckInMessagesWouldBeSent(const std::function & shouldCheckInMsgsBeSentFunction) @@ -396,7 +396,7 @@ void ICDManager::UpdateICDMode() ICDConfigurationData::GetInstance().SetICDMode(tempMode); // Can't use attribute accessors/Attributes::OperatingMode::Set in unit tests -#if !CONFIG_BUILD_FOR_HOST_UNIT_TEST +#if !(CONFIG_BUILD_FOR_HOST_UNIT_TEST) Attributes::OperatingMode::Set(kRootEndpointId, static_cast(tempMode)); #endif diff --git a/src/app/icd/server/ICDManager.h b/src/app/icd/server/ICDManager.h index dc516673df8d40..eae0adbc1a28de 100644 --- a/src/app/icd/server/ICDManager.h +++ b/src/app/icd/server/ICDManager.h @@ -233,7 +233,7 @@ class ICDManager : public ICDListener, public TestEventTriggerHandler #if CHIP_CONFIG_PERSIST_SUBSCRIPTIONS && !CHIP_CONFIG_SUBSCRIPTION_TIMEOUT_RESUMPTION bool GetIsBootUpResumeSubscriptionExecuted() { return mIsBootUpResumeSubscriptionExecuted; }; #endif // !CHIP_CONFIG_SUBSCRIPTION_TIMEOUT_RESUMPTION && CHIP_CONFIG_PERSIST_SUBSCRIPTIONS -#endif +#endif // CONFIG_BUILD_FOR_HOST_UNIT_TEST // Implementation of ICDListener functions. // Callers must origin from the chip task context or hold the ChipStack lock. @@ -382,10 +382,10 @@ class ICDManager : public ICDListener, public TestEventTriggerHandler ObjectPool mICDSenderPool; #endif // CHIP_CONFIG_ENABLE_ICD_CIP -#ifdef CONFIG_BUILD_FOR_HOST_UNIT_TEST +#if CONFIG_BUILD_FOR_HOST_UNIT_TEST // feature map that can be changed at runtime for testing purposes uint32_t mFeatureMap = 0; -#endif +#endif // CONFIG_BUILD_FOR_HOST_UNIT_TEST }; } // namespace app diff --git a/src/app/zap-templates/zcl/zcl-with-test-extensions.json b/src/app/zap-templates/zcl/zcl-with-test-extensions.json index 3ad401afb3e47a..0eba8fc692d6d8 100644 --- a/src/app/zap-templates/zcl/zcl-with-test-extensions.json +++ b/src/app/zap-templates/zcl/zcl-with-test-extensions.json @@ -290,7 +290,8 @@ "ActiveModeThreshold", "RegisteredClients", "ICDCounter", - "ClientsSupportedPerFabric" + "ClientsSupportedPerFabric", + "MaximumCheckInBackOff" ], "Occupancy Sensing": ["HoldTimeLimits", "HoldTime", "FeatureMap"], "Operational Credentials": [ diff --git a/src/app/zap-templates/zcl/zcl.json b/src/app/zap-templates/zcl/zcl.json index c291fc651f6aa0..6907cfea0eb19f 100644 --- a/src/app/zap-templates/zcl/zcl.json +++ b/src/app/zap-templates/zcl/zcl.json @@ -284,7 +284,8 @@ "ActiveModeThreshold", "RegisteredClients", "ICDCounter", - "ClientsSupportedPerFabric" + "ClientsSupportedPerFabric", + "MaximumCheckInBackOff" ], "Occupancy Sensing": ["HoldTimeLimits", "HoldTime", "FeatureMap"], "Operational Credentials": [ diff --git a/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp b/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp index 762cedbf1b5aa3..c23e0e252bbb99 100644 --- a/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp +++ b/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp @@ -9091,53 +9091,6 @@ Protocols::InteractionModel::Status Set(EndpointId endpoint, chip::app::Clusters } // namespace OperatingMode -namespace MaximumCheckInBackOff { - -Protocols::InteractionModel::Status Get(EndpointId endpoint, uint32_t * value) -{ - using Traits = NumericAttributeTraits; - Traits::StorageType temp; - uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); - Protocols::InteractionModel::Status status = - emberAfReadAttribute(endpoint, Clusters::IcdManagement::Id, Id, readable, sizeof(temp)); - VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); - if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - *value = Traits::StorageToWorking(temp); - return status; -} - -Protocols::InteractionModel::Status Set(EndpointId endpoint, uint32_t value, MarkAttributeDirty markDirty) -{ - using Traits = NumericAttributeTraits; - if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - Traits::StorageType storageValue; - Traits::WorkingToStorage(value, storageValue); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(ConcreteAttributePath(endpoint, Clusters::IcdManagement::Id, Id), - EmberAfWriteDataInput(writable, ZCL_INT32U_ATTRIBUTE_TYPE).SetMarkDirty(markDirty)); -} - -Protocols::InteractionModel::Status Set(EndpointId endpoint, uint32_t value) -{ - using Traits = NumericAttributeTraits; - if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - Traits::StorageType storageValue; - Traits::WorkingToStorage(value, storageValue); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::IcdManagement::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE); -} - -} // namespace MaximumCheckInBackOff - namespace FeatureMap { Protocols::InteractionModel::Status Get(EndpointId endpoint, uint32_t * value) diff --git a/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.h b/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.h index 98aebd50964980..11e2228564e6ab 100644 --- a/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.h +++ b/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.h @@ -1431,12 +1431,6 @@ Protocols::InteractionModel::Status Set(EndpointId endpoint, chip::app::Clusters MarkAttributeDirty markDirty); } // namespace OperatingMode -namespace MaximumCheckInBackOff { -Protocols::InteractionModel::Status Get(EndpointId endpoint, uint32_t * value); // int32u -Protocols::InteractionModel::Status Set(EndpointId endpoint, uint32_t value); -Protocols::InteractionModel::Status Set(EndpointId endpoint, uint32_t value, MarkAttributeDirty markDirty); -} // namespace MaximumCheckInBackOff - namespace FeatureMap { Protocols::InteractionModel::Status Get(EndpointId endpoint, uint32_t * value); // bitmap32 Protocols::InteractionModel::Status Set(EndpointId endpoint, uint32_t value); From 71170fe975f4c1a6b905430d9e333d31e7f44e41 Mon Sep 17 00:00:00 2001 From: dinabenamar <108664279+dinabenamar@users.noreply.github.com> Date: Thu, 24 Oct 2024 17:14:57 +0200 Subject: [PATCH 102/149] [NXP][platform][common] Set CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION to 1 by default if wifi is enabled (#36226) Signed-off-by: Dina Benamar --- src/platform/nxp/common/CHIPDeviceNXPPlatformDefaultConfig.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/platform/nxp/common/CHIPDeviceNXPPlatformDefaultConfig.h b/src/platform/nxp/common/CHIPDeviceNXPPlatformDefaultConfig.h index e8d392fb793604..c4e77e87b4b9ad 100644 --- a/src/platform/nxp/common/CHIPDeviceNXPPlatformDefaultConfig.h +++ b/src/platform/nxp/common/CHIPDeviceNXPPlatformDefaultConfig.h @@ -28,7 +28,11 @@ // ==================== Platform Adaptations ==================== #ifndef CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION +#if CONFIG_CHIP_WIFI || CHIP_DEVICE_CONFIG_ENABLE_WPA +#define CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION 1 +#else #define CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION 0 +#endif // CONFIG_CHIP_WIFI || CHIP_DEVICE_CONFIG_ENABLE_WPA #endif // CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION #ifndef CHIP_DEVICE_CONFIG_ENABLE_WIFI_AP From ec58aef67cf604e3b739d7d9a0fd3e2cd928b686 Mon Sep 17 00:00:00 2001 From: Marius Tache <102153746+marius-alex-tache@users.noreply.github.com> Date: Thu, 24 Oct 2024 18:24:45 +0300 Subject: [PATCH 103/149] [nxp][examples][k32w1_mcxw71] Disable DNS over TCP for OT config (#36190) Signed-off-by: marius-alex-tache --- .../app/project_include/openthread/OpenThreadConfig.h | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/platform/nxp/mcxw71_k32w1/app/project_include/openthread/OpenThreadConfig.h b/examples/platform/nxp/mcxw71_k32w1/app/project_include/openthread/OpenThreadConfig.h index 932812aa711659..a8890d9a0ed78e 100644 --- a/examples/platform/nxp/mcxw71_k32w1/app/project_include/openthread/OpenThreadConfig.h +++ b/examples/platform/nxp/mcxw71_k32w1/app/project_include/openthread/OpenThreadConfig.h @@ -53,6 +53,7 @@ #define OPENTHREAD_CONFIG_DHCP6_CLIENT_ENABLE 0 #define OPENTHREAD_CONFIG_DHCP6_SERVER_ENABLE 0 #define OPENTHREAD_CONFIG_TCP_ENABLE 0 +#define OPENTHREAD_CONFIG_DNS_CLIENT_OVER_TCP_ENABLE 0 #define OPENTHREAD_CONFIG_MLE_LINK_METRICS_INITIATOR_ENABLE 0 #define OPENTHREAD_CONFIG_MLE_LINK_METRICS_SUBJECT_ENABLE 0 From ec81c76a4e0fe3ff4dd296f4499a939f53d601a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=A9leste=20Cote?= <34518035+celestecote21@users.noreply.github.com> Date: Thu, 24 Oct 2024 17:34:11 +0200 Subject: [PATCH 104/149] Make bridge interface as Ethernet interface (#33236) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some devices neither have WAN nor eth interface but use a bridge interface. Consider bridge interface as Ethernet, so these devices can use bridge interface. Co-authored-by: Céleste Cote Co-authored-by: Andrei Litvin --- src/platform/Linux/ConnectivityUtils.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/platform/Linux/ConnectivityUtils.cpp b/src/platform/Linux/ConnectivityUtils.cpp index 8084ceca43b55a..1b12bf5edb3c0e 100644 --- a/src/platform/Linux/ConnectivityUtils.cpp +++ b/src/platform/Linux/ConnectivityUtils.cpp @@ -272,6 +272,10 @@ InterfaceTypeEnum ConnectivityUtils::GetInterfaceConnectionType(const char * ifn if (ioctl(sock, SIOCETHTOOL, &ifr) != -1) ret = InterfaceTypeEnum::kEthernet; } + else if (strncmp(ifname, "br", 2) == 0) + { + ret = InterfaceTypeEnum::kEthernet; + } close(sock); From 00890a6e3f07d17c2fb4324bc011953e08c6a80e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Szablowski?= <56074162+doublemis1@users.noreply.github.com> Date: Thu, 24 Oct 2024 18:13:53 +0200 Subject: [PATCH 105/149] DRLK-2.1: use correct PICS for prompt test steps (#34026) * DRLK-2.1: use correct PICS for prompt test steps The test case while defining the prompt usage test step, the incorrect PICS has been set PICS_SKIP_SAMPLE_APP instead of PICS_USER_PROMPT * Update Test_TC_DRLK_2_1.yaml - restyle changes --------- Co-authored-by: Andrei Litvin --- src/app/tests/suites/certification/Test_TC_DRLK_2_1.yaml | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/app/tests/suites/certification/Test_TC_DRLK_2_1.yaml b/src/app/tests/suites/certification/Test_TC_DRLK_2_1.yaml index 8954d44a658d97..47393f449386e8 100755 --- a/src/app/tests/suites/certification/Test_TC_DRLK_2_1.yaml +++ b/src/app/tests/suites/certification/Test_TC_DRLK_2_1.yaml @@ -194,9 +194,7 @@ tests: value: 2 - label: "Step 1j: Simulate a not fully locked scenario on the DUT." - PICS: - DRLK.S.A0000 && DRLK.S.M.SimulateNotFullyLocked && - PICS_SKIP_SAMPLE_APP + PICS: DRLK.S.A0000 && DRLK.S.M.SimulateNotFullyLocked && PICS_USER_PROMPT verification: | vendor will give instructions on how to simulate if applicable and if that is possible, then send the below command to read the lock state attribute. @@ -317,7 +315,7 @@ tests: #Test plan issue: https://github.com/CHIP-Specifications/chip-test-plans/issues/2863 - label: "Step 5c: TH reads DoorOpenEvents attribute from DUT" - PICS: DRLK.S.A0004 && PICS_SKIP_SAMPLE_APP + PICS: DRLK.S.A0004 && PICS_USER_PROMPT verification: | This is an Optional attribute, so its not compulsory to get the expected outcome @@ -371,7 +369,7 @@ tests: #Test plan issue: https://github.com/CHIP-Specifications/chip-test-plans/issues/2863 - label: "Step 6c: TH reads DoorOpenEvents attribute from DUT" - PICS: DRLK.S.A0005 && PICS_SKIP_SAMPLE_APP + PICS: DRLK.S.A0005 && PICS_USER_PROMPT verification: | This is an Optional attribute, so its not compulsory to get the expected outcome From 1febc9b6f6636ebc0fac2d769b5bf74e8440c798 Mon Sep 17 00:00:00 2001 From: jamesharrow <93921463+jamesharrow@users.noreply.github.com> Date: Thu, 24 Oct 2024 18:21:44 +0100 Subject: [PATCH 106/149] Add missing device types solar pv, battery storage, heat pump (#36147) * Added Heat Pump, Solar Power, Battery Storage to matter-devices.xml * Update after regen_all --- .../zcl/data-model/chip/matter-devices.xml | 72 +++++++++++++++++++ .../CHIP/zap-generated/MTRClusterConstants.h | 3 + .../zap-generated/MTRDeviceTypeMetadata.mm | 3 + .../cluster/logging/EntryToText.cpp | 6 ++ 4 files changed, 84 insertions(+) diff --git a/src/app/zap-templates/zcl/data-model/chip/matter-devices.xml b/src/app/zap-templates/zcl/data-model/chip/matter-devices.xml index ff485bbf6bba81..bdccfbe39e1582 100644 --- a/src/app/zap-templates/zcl/data-model/chip/matter-devices.xml +++ b/src/app/zap-templates/zcl/data-model/chip/matter-devices.xml @@ -2741,4 +2741,76 @@ limitations under the License. + + MA-heatpump + CHIP + Heat Pump + 0x0103 + 0x0309 + Simple + Endpoint + + + CLIENT_LIST + DEVICE_TYPE_LIST + PARTS_LIST + SERVER_LIST + + + IDENTIFY_TIME + IDENTIFY_TYPE + Identify + + + CONTROL_SEQUENCE_OF_OPERATION + LOCAL_TEMPERATURE + SYSTEM_MODE + SetpointRaiseLower + + + + + MA-solarpower + CHIP + Solar Power + 0x0103 + 0x0017 + Simple + Endpoint + + + CLIENT_LIST + DEVICE_TYPE_LIST + PARTS_LIST + SERVER_LIST + + + IDENTIFY_TIME + IDENTIFY_TYPE + Identify + + + + + MA-batterystorage + CHIP + Battery Storage + 0x0103 + 0x0018 + Simple + Endpoint + + + CLIENT_LIST + DEVICE_TYPE_LIST + PARTS_LIST + SERVER_LIST + + + IDENTIFY_TIME + IDENTIFY_TYPE + Identify + + + diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h b/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h index da2ce72f59373d..c44b789060f895 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h @@ -7572,6 +7572,8 @@ typedef NS_ENUM(uint32_t, MTRDeviceTypeIDType) { MTRDeviceTypeIDTypeOTAProviderID MTR_NEWLY_AVAILABLE = 0x00000014, MTRDeviceTypeIDTypeContactSensorID MTR_NEWLY_AVAILABLE = 0x00000015, MTRDeviceTypeIDTypeRootNodeID MTR_NEWLY_AVAILABLE = 0x00000016, + MTRDeviceTypeIDTypeSolarPowerID MTR_PROVISIONALLY_AVAILABLE = 0x00000017, + MTRDeviceTypeIDTypeBatteryStorageID MTR_PROVISIONALLY_AVAILABLE = 0x00000018, MTRDeviceTypeIDTypeSecondaryNetworkInterfaceID MTR_NEWLY_AVAILABLE = 0x00000019, MTRDeviceTypeIDTypeSpeakerID MTR_NEWLY_AVAILABLE = 0x00000022, MTRDeviceTypeIDTypeCastingVideoPlayerID MTR_NEWLY_AVAILABLE = 0x00000023, @@ -7623,6 +7625,7 @@ typedef NS_ENUM(uint32_t, MTRDeviceTypeIDType) { MTRDeviceTypeIDTypePressureSensorID MTR_NEWLY_AVAILABLE = 0x00000305, MTRDeviceTypeIDTypeFlowSensorID MTR_NEWLY_AVAILABLE = 0x00000306, MTRDeviceTypeIDTypeHumiditySensorID MTR_NEWLY_AVAILABLE = 0x00000307, + MTRDeviceTypeIDTypeHeatPumpID MTR_PROVISIONALLY_AVAILABLE = 0x00000309, MTRDeviceTypeIDTypeEVSEID MTR_NEWLY_AVAILABLE = 0x0000050C, MTRDeviceTypeIDTypeDeviceEnergyManagementID MTR_NEWLY_AVAILABLE = 0x0000050D, MTRDeviceTypeIDTypeWaterHeaterID MTR_PROVISIONALLY_AVAILABLE = 0x0000050F, diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRDeviceTypeMetadata.mm b/src/darwin/Framework/CHIP/zap-generated/MTRDeviceTypeMetadata.mm index b4ea67c2ed66fe..fc9d8c7d930d88 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRDeviceTypeMetadata.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRDeviceTypeMetadata.mm @@ -32,6 +32,8 @@ { 0x00000014, MTRDeviceTypeClass::Utility, "OTA Provider" }, { 0x00000015, MTRDeviceTypeClass::Simple, "Contact Sensor" }, { 0x00000016, MTRDeviceTypeClass::Node, "Root Node" }, + { 0x00000017, MTRDeviceTypeClass::Simple, "Solar Power" }, + { 0x00000018, MTRDeviceTypeClass::Simple, "Battery Storage" }, { 0x00000019, MTRDeviceTypeClass::Utility, "Secondary Network Interface" }, { 0x00000022, MTRDeviceTypeClass::Simple, "Speaker" }, { 0x00000023, MTRDeviceTypeClass::Simple, "Casting Video Player" }, @@ -83,6 +85,7 @@ { 0x00000305, MTRDeviceTypeClass::Simple, "Pressure Sensor" }, { 0x00000306, MTRDeviceTypeClass::Simple, "Flow Sensor" }, { 0x00000307, MTRDeviceTypeClass::Simple, "Humidity Sensor" }, + { 0x00000309, MTRDeviceTypeClass::Simple, "Heat Pump" }, { 0x0000050C, MTRDeviceTypeClass::Simple, "EVSE" }, { 0x0000050D, MTRDeviceTypeClass::Simple, "Device Energy Management" }, { 0x0000050F, MTRDeviceTypeClass::Simple, "Water Heater" }, diff --git a/zzz_generated/chip-tool/zap-generated/cluster/logging/EntryToText.cpp b/zzz_generated/chip-tool/zap-generated/cluster/logging/EntryToText.cpp index 7c4c38ae6cec3f..caa60d3532e401 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/logging/EntryToText.cpp +++ b/zzz_generated/chip-tool/zap-generated/cluster/logging/EntryToText.cpp @@ -6389,6 +6389,10 @@ char const * DeviceTypeIdToText(chip::DeviceTypeId id) return "Contact Sensor"; case 0x00000016: return "Root Node"; + case 0x00000017: + return "Solar Power"; + case 0x00000018: + return "Battery Storage"; case 0x00000019: return "Secondary Network Interface"; case 0x00000022: @@ -6491,6 +6495,8 @@ char const * DeviceTypeIdToText(chip::DeviceTypeId id) return "Flow Sensor"; case 0x00000307: return "Humidity Sensor"; + case 0x00000309: + return "Heat Pump"; case 0x0000050C: return "EVSE"; case 0x0000050D: From 692983ed56896b7465ba34aedf9a09f03a1cb4d5 Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Thu, 24 Oct 2024 14:49:12 -0400 Subject: [PATCH 107/149] Use custom ember-buffer decode on codegen data model Read as well. (#36229) * Use EmberAttributeDataBuffer for codegen provider _Read * Fix comments * Restyled by clang-format --------- Co-authored-by: Andrei Litvin Co-authored-by: Restyled.io --- .../CodegenDataModelProvider_Read.cpp | 175 +----- .../EmberAttributeDataBuffer.cpp | 250 +++++++- .../EmberAttributeDataBuffer.h | 31 +- .../tests/TestEmberAttributeDataBuffer.cpp | 542 +++++++++++++++++- 4 files changed, 822 insertions(+), 176 deletions(-) diff --git a/src/app/codegen-data-model-provider/CodegenDataModelProvider_Read.cpp b/src/app/codegen-data-model-provider/CodegenDataModelProvider_Read.cpp index 6ce5d282f89d30..ea35356391d63d 100644 --- a/src/app/codegen-data-model-provider/CodegenDataModelProvider_Read.cpp +++ b/src/app/codegen-data-model-provider/CodegenDataModelProvider_Read.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -41,6 +42,7 @@ #include #include #include +#include #include @@ -85,173 +87,6 @@ std::optional TryReadViaAccessInterface(const ConcreteAttributePath return encoder.TriedEncode() ? std::make_optional(CHIP_NO_ERROR) : std::nullopt; } -/// Metadata of what a ember/pascal short string means (prepended by a u8 length) -struct ShortPascalString -{ - using LengthType = uint8_t; - static constexpr LengthType kNullLength = 0xFF; - - static size_t GetLength(ByteSpan buffer) - { - VerifyOrDie(buffer.size() >= 1); - // NOTE: we do NOT use emberAfStringLength from ember-strings.h because that will result in 0 - // length for null sizes (i.e. 0xFF is translated to 0 and we do not want that here) - return buffer[0]; - } -}; - -/// Metadata of what a ember/pascal LONG string means (prepended by a u16 length) -struct LongPascalString -{ - using LengthType = uint16_t; - static constexpr LengthType kNullLength = 0xFFFF; - - static size_t GetLength(ByteSpan buffer) - { - // NOTE: we do NOT use emberAfLongStringLength from ember-strings.h because that will result in 0 - // length for null sizes (i.e. 0xFFFF is translated to 0 and we do not want that here) - VerifyOrDie(buffer.size() >= 2); - const uint8_t * data = buffer.data(); - return Encoding::LittleEndian::Read16(data); - } -}; - -// ember assumptions ... should just work -static_assert(sizeof(ShortPascalString::LengthType) == 1); -static_assert(sizeof(LongPascalString::LengthType) == 2); - -/// Given a ByteSpan containing data from ember, interpret it -/// as a span of type OUT (i.e. ByteSpan or CharSpan) given a ENCODING -/// where ENCODING is Short or Long pascal strings. -template -std::optional ExtractEmberString(ByteSpan data) -{ - constexpr size_t kLengthTypeSize = sizeof(typename ENCODING::LengthType); - VerifyOrDie(kLengthTypeSize <= data.size()); - auto len = ENCODING::GetLength(data); - - if (len == ENCODING::kNullLength) - { - return std::nullopt; - } - - VerifyOrDie(len + sizeof(len) <= data.size()); - return std::make_optional(reinterpret_cast(data.data() + kLengthTypeSize), len); -} - -/// Encode a value inside `encoder` -/// -/// The value encoded will be of type T (e.g. CharSpan or ByteSpan) and it will be decoded -/// via the given ENCODING (i.e. ShortPascalString or LongPascalString) -/// -/// isNullable defines if the value of NULL is allowed to be encoded. -template -CHIP_ERROR EncodeStringLike(ByteSpan data, bool isNullable, AttributeValueEncoder & encoder) -{ - std::optional value = ExtractEmberString(data); - if (!value.has_value()) - { - if (isNullable) - { - return encoder.EncodeNull(); - } - return CHIP_ERROR_INCORRECT_STATE; - } - - // encode value as-is - return encoder.Encode(*value); -} - -/// Encodes a numeric data value of type T from the given ember-encoded buffer `data`. -/// -/// isNullable defines if the value of NULL is allowed to be encoded. -template -CHIP_ERROR EncodeFromSpan(ByteSpan data, bool isNullable, AttributeValueEncoder & encoder) -{ - typename NumericAttributeTraits::StorageType value; - - VerifyOrReturnError(data.size() >= sizeof(value), CHIP_ERROR_INVALID_ARGUMENT); - memcpy(&value, data.data(), sizeof(value)); - - if (isNullable && NumericAttributeTraits::IsNullValue(value)) - { - return encoder.EncodeNull(); - } - - if (!NumericAttributeTraits::CanRepresentValue(isNullable, value)) - { - return CHIP_ERROR_INCORRECT_STATE; - } - - return encoder.Encode(NumericAttributeTraits::StorageToWorking(value)); -} - -/// Converts raw ember data from `data` into the encoder -/// -/// Uses the attribute `metadata` to determine how the data is encoded into `data` and -/// write a suitable value into `encoder`. -CHIP_ERROR EncodeEmberValue(ByteSpan data, const EmberAfAttributeMetadata * metadata, AttributeValueEncoder & encoder) -{ - VerifyOrReturnError(metadata != nullptr, CHIP_ERROR_INVALID_ARGUMENT); - - const bool isNullable = metadata->IsNullable(); - - switch (AttributeBaseType(metadata->attributeType)) - { - case ZCL_NO_DATA_ATTRIBUTE_TYPE: // No data - return encoder.EncodeNull(); - case ZCL_BOOLEAN_ATTRIBUTE_TYPE: // Boolean - return EncodeFromSpan(data, isNullable, encoder); - case ZCL_INT8U_ATTRIBUTE_TYPE: // Unsigned 8-bit integer - return EncodeFromSpan(data, isNullable, encoder); - case ZCL_INT16U_ATTRIBUTE_TYPE: // Unsigned 16-bit integer - return EncodeFromSpan(data, isNullable, encoder); - case ZCL_INT24U_ATTRIBUTE_TYPE: // Unsigned 24-bit integer - return EncodeFromSpan>(data, isNullable, encoder); - case ZCL_INT32U_ATTRIBUTE_TYPE: // Unsigned 32-bit integer - return EncodeFromSpan(data, isNullable, encoder); - case ZCL_INT40U_ATTRIBUTE_TYPE: // Unsigned 40-bit integer - return EncodeFromSpan>(data, isNullable, encoder); - case ZCL_INT48U_ATTRIBUTE_TYPE: // Unsigned 48-bit integer - return EncodeFromSpan>(data, isNullable, encoder); - case ZCL_INT56U_ATTRIBUTE_TYPE: // Unsigned 56-bit integer - return EncodeFromSpan>(data, isNullable, encoder); - case ZCL_INT64U_ATTRIBUTE_TYPE: // Unsigned 64-bit integer - return EncodeFromSpan(data, isNullable, encoder); - case ZCL_INT8S_ATTRIBUTE_TYPE: // Signed 8-bit integer - return EncodeFromSpan(data, isNullable, encoder); - case ZCL_INT16S_ATTRIBUTE_TYPE: // Signed 16-bit integer - return EncodeFromSpan(data, isNullable, encoder); - case ZCL_INT24S_ATTRIBUTE_TYPE: // Signed 24-bit integer - return EncodeFromSpan>(data, isNullable, encoder); - case ZCL_INT32S_ATTRIBUTE_TYPE: // Signed 32-bit integer - return EncodeFromSpan(data, isNullable, encoder); - case ZCL_INT40S_ATTRIBUTE_TYPE: // Signed 40-bit integer - return EncodeFromSpan>(data, isNullable, encoder); - case ZCL_INT48S_ATTRIBUTE_TYPE: // Signed 48-bit integer - return EncodeFromSpan>(data, isNullable, encoder); - case ZCL_INT56S_ATTRIBUTE_TYPE: // Signed 56-bit integer - return EncodeFromSpan>(data, isNullable, encoder); - case ZCL_INT64S_ATTRIBUTE_TYPE: // Signed 64-bit integer - return EncodeFromSpan(data, isNullable, encoder); - case ZCL_SINGLE_ATTRIBUTE_TYPE: // 32-bit float - return EncodeFromSpan(data, isNullable, encoder); - case ZCL_DOUBLE_ATTRIBUTE_TYPE: // 64-bit float - return EncodeFromSpan(data, isNullable, encoder); - case ZCL_CHAR_STRING_ATTRIBUTE_TYPE: // Char string - return EncodeStringLike(data, isNullable, encoder); - case ZCL_LONG_CHAR_STRING_ATTRIBUTE_TYPE: - return EncodeStringLike(data, isNullable, encoder); - case ZCL_OCTET_STRING_ATTRIBUTE_TYPE: // Octet string - return EncodeStringLike(data, isNullable, encoder); - case ZCL_LONG_OCTET_STRING_ATTRIBUTE_TYPE: - return EncodeStringLike(data, isNullable, encoder); - default: - ChipLogError(DataManagement, "Attribute type 0x%x not handled", static_cast(metadata->attributeType)); - return CHIP_IM_GLOBAL_STATUS(Failure); - } -} - } // namespace /// separated-out ReadAttribute implementation (given existing complexity) @@ -343,7 +178,11 @@ DataModel::ActionReturnStatus CodegenDataModelProvider::ReadAttribute(const Data return CHIP_ERROR_IM_GLOBAL_STATUS_VALUE(status); } - return EncodeEmberValue(gEmberAttributeIOBufferSpan, attributeMetadata, encoder); + VerifyOrReturnError(attributeMetadata != nullptr, CHIP_ERROR_INVALID_ARGUMENT); + + MutableByteSpan data = gEmberAttributeIOBufferSpan; + Ember::EmberAttributeDataBuffer emberData(attributeMetadata, data); + return encoder.Encode(emberData); } } // namespace app diff --git a/src/app/codegen-data-model-provider/EmberAttributeDataBuffer.cpp b/src/app/codegen-data-model-provider/EmberAttributeDataBuffer.cpp index ab8891657fde50..2c764241ebf3d8 100644 --- a/src/app/codegen-data-model-provider/EmberAttributeDataBuffer.cpp +++ b/src/app/codegen-data-model-provider/EmberAttributeDataBuffer.cpp @@ -17,14 +17,18 @@ #include #include +#include #include #include #include +#include #include +#include #include #include #include +#include #include namespace chip { @@ -43,7 +47,7 @@ constexpr uint32_t MaxLength(EmberAttributeDataBuffer::PascalStringType s) { return std::numeric_limits::max() - 1; } - // EmberAttributeBuffer::PascalStringType::kLong: + // EmberAttributeDataBuffer::PascalStringType::kLong: return std::numeric_limits::max() - 1; } @@ -116,6 +120,55 @@ constexpr SignedDecodeInfo GetSignedDecodeInfo(EmberAfAttributeType type) chipDie(); } +/// Encodes the string of type stringType pointed to by `reader` into the TLV `writer`. +/// Then encoded string will be at tag `tag` and of type `tlvType` +CHIP_ERROR EncodeString(EmberAttributeDataBuffer::PascalStringType stringType, TLV::TLVType tlvType, TLV::TLVWriter & writer, + TLV::Tag tag, EmberAttributeDataBuffer::EndianReader & reader, bool nullable) +{ + unsigned stringLen; + if (stringType == EmberAttributeDataBuffer::PascalStringType::kShort) + { + uint8_t len; + if (!reader.Read8(&len).IsSuccess()) + { + return reader.StatusCode(); + } + if (len == NumericAttributeTraits::kNullValue) + { + VerifyOrReturnError(nullable, CHIP_ERROR_INVALID_ARGUMENT); + return writer.PutNull(tag); + } + stringLen = len; + } + else + { + uint16_t len; + if (!reader.Read16(&len).IsSuccess()) + { + return reader.StatusCode(); + } + if (len == NumericAttributeTraits::kNullValue) + { + VerifyOrReturnError(nullable, CHIP_ERROR_INVALID_ARGUMENT); + return writer.PutNull(tag); + } + stringLen = len; + } + + const uint8_t * data; + if (!reader.ZeroCopyProcessBytes(stringLen, &data).IsSuccess()) + { + return reader.StatusCode(); + } + + if (tlvType == TLV::kTLVType_UTF8String) + { + return writer.PutString(tag, reinterpret_cast(data), stringLen); + } + + return writer.PutBytes(tag, data, stringLen); +} + } // namespace CHIP_ERROR EmberAttributeDataBuffer::DecodeUnsignedInteger(chip::TLV::TLVReader & reader, EndianWriter & writer) @@ -191,6 +244,7 @@ CHIP_ERROR EmberAttributeDataBuffer::DecodeAsString(chip::TLV::TLVReader & reade writer.Put16(NumericAttributeTraits::kNullValue); break; } + return CHIP_NO_ERROR; } @@ -321,6 +375,200 @@ CHIP_ERROR EmberAttributeDataBuffer::Decode(chip::TLV::TLVReader & reader) return CHIP_NO_ERROR; } +CHIP_ERROR EmberAttributeDataBuffer::EncodeInteger(chip::TLV::TLVWriter & writer, TLV::Tag tag, EndianReader & reader) const +{ + // Encodes an integer by first reading as raw bytes and then + // bitshift-convert + // + // This optimizes code size rather than readability at this point. + + uint8_t raw_bytes[8]; + + bool isSigned = (mAttributeType == ZCL_INT8S_ATTRIBUTE_TYPE) // + || (mAttributeType == ZCL_INT16S_ATTRIBUTE_TYPE) // + || (mAttributeType == ZCL_INT24S_ATTRIBUTE_TYPE) // + || (mAttributeType == ZCL_INT32S_ATTRIBUTE_TYPE) // + || (mAttributeType == ZCL_INT40S_ATTRIBUTE_TYPE) // + || (mAttributeType == ZCL_INT48S_ATTRIBUTE_TYPE) // + || (mAttributeType == ZCL_INT56S_ATTRIBUTE_TYPE) // + || (mAttributeType == ZCL_INT64S_ATTRIBUTE_TYPE); + + unsigned byteCount; + uint64_t nullValue; + + if (isSigned) + { + const SignedDecodeInfo info = GetSignedDecodeInfo(mAttributeType); + byteCount = info.byteCount; + nullValue = static_cast(info.minValue); // just a bit cast for easy compare + } + else + { + const UnsignedDecodeInfo info = GetUnsignedDecodeInfo(mAttributeType); + byteCount = info.byteCount; + nullValue = info.maxValue; + } + + VerifyOrDie(sizeof(raw_bytes) >= byteCount); + if (!reader.ReadBytes(raw_bytes, byteCount).IsSuccess()) + { + return reader.StatusCode(); + } + + // At this point, RAW_VALUE contains the actual value, need to make it "real" + union + { + int64_t int_value; + uint64_t uint_value; + } value; + + value.uint_value = 0; + +#if CHIP_CONFIG_BIG_ENDIAN_TARGET + bool isNegative = isSigned && (raw_bytes[0] >= 0x80); + if (isNegative) + { + value.int_value = -1; + } + for (int i = 0; i < static_cast(byteCount); i++) + { +#else + bool isNegative = isSigned && (raw_bytes[byteCount - 1] >= 0x80); + if (isNegative) + { + value.int_value = -1; + } + for (int i = static_cast(byteCount) - 1; i >= 0; i--) + { +#endif + value.uint_value <<= 8; + value.uint_value = (value.uint_value & ~0xFFULL) | raw_bytes[i]; + } + + if (mIsNullable && (value.uint_value == nullValue)) + { + // MaxValue is used for NULL setting + return writer.PutNull(tag); + } + + switch (mAttributeType) + { + case ZCL_INT8U_ATTRIBUTE_TYPE: // Unsigned 8-bit integer + return writer.Put(tag, static_cast(value.uint_value)); + case ZCL_INT16U_ATTRIBUTE_TYPE: // Unsigned 16-bit integer + return writer.Put(tag, static_cast(value.uint_value)); + case ZCL_INT24U_ATTRIBUTE_TYPE: // Unsigned 24-bit integer + case ZCL_INT32U_ATTRIBUTE_TYPE: // Unsigned 32-bit integer + return writer.Put(tag, static_cast(value.uint_value)); + case ZCL_INT40U_ATTRIBUTE_TYPE: // Unsigned 40-bit integer + case ZCL_INT48U_ATTRIBUTE_TYPE: // Unsigned 48-bit integer + case ZCL_INT56U_ATTRIBUTE_TYPE: // Signed 56-bit integer + case ZCL_INT64U_ATTRIBUTE_TYPE: // Signed 64-bit integer + return writer.Put(tag, static_cast(value.uint_value)); + case ZCL_INT8S_ATTRIBUTE_TYPE: // Signed 8-bit integer + return writer.Put(tag, static_cast(value.int_value)); + case ZCL_INT16S_ATTRIBUTE_TYPE: // Signed 16-bit integer + return writer.Put(tag, static_cast(value.int_value)); + case ZCL_INT24S_ATTRIBUTE_TYPE: // Signed 24-bit integer + case ZCL_INT32S_ATTRIBUTE_TYPE: // Signed 32-bit integer + return writer.Put(tag, static_cast(value.int_value)); + default: + return writer.Put(tag, static_cast(value.int_value)); + } +} + +CHIP_ERROR EmberAttributeDataBuffer::Encode(chip::TLV::TLVWriter & writer, TLV::Tag tag) const +{ + EndianReader endianReader(mDataBuffer.data(), mDataBuffer.size()); + + switch (mAttributeType) + { + case ZCL_NO_DATA_ATTRIBUTE_TYPE: // No data + return writer.PutNull(tag); + case ZCL_BOOLEAN_ATTRIBUTE_TYPE: { // Boolean + uint8_t value; + if (!endianReader.Read8(&value).IsSuccess()) + { + return endianReader.StatusCode(); + } + switch (value) + { + case 0: + case 1: + return writer.PutBoolean(tag, value != 0); + case 0xFF: + return writer.PutNull(tag); + default: + // Unknown types + return CHIP_ERROR_INCORRECT_STATE; + } + } + case ZCL_INT8U_ATTRIBUTE_TYPE: // Unsigned 8-bit integer + case ZCL_INT16U_ATTRIBUTE_TYPE: // Unsigned 16-bit integer + case ZCL_INT24U_ATTRIBUTE_TYPE: // Unsigned 24-bit integer + case ZCL_INT32U_ATTRIBUTE_TYPE: // Unsigned 32-bit integer + case ZCL_INT40U_ATTRIBUTE_TYPE: // Unsigned 40-bit integer + case ZCL_INT48U_ATTRIBUTE_TYPE: // Unsigned 48-bit integer + case ZCL_INT56U_ATTRIBUTE_TYPE: // Unsigned 56-bit integer + case ZCL_INT64U_ATTRIBUTE_TYPE: // Unsigned 64-bit integer + case ZCL_INT8S_ATTRIBUTE_TYPE: // Signed 8-bit integer + case ZCL_INT16S_ATTRIBUTE_TYPE: // Signed 16-bit integer + case ZCL_INT24S_ATTRIBUTE_TYPE: // Signed 24-bit integer + case ZCL_INT32S_ATTRIBUTE_TYPE: // Signed 32-bit integer + case ZCL_INT40S_ATTRIBUTE_TYPE: // Signed 40-bit integer + case ZCL_INT48S_ATTRIBUTE_TYPE: // Signed 48-bit integer + case ZCL_INT56S_ATTRIBUTE_TYPE: // Signed 56-bit integer + case ZCL_INT64S_ATTRIBUTE_TYPE: // Signed 64-bit integer + return EncodeInteger(writer, tag, endianReader); + case ZCL_SINGLE_ATTRIBUTE_TYPE: { // 32-bit float + union + { + uint8_t raw[sizeof(float)]; + float value; + } value; + + if (!endianReader.ReadBytes(value.raw, sizeof(value)).IsSuccess()) + { + return endianReader.StatusCode(); + } + if (NumericAttributeTraits::IsNullValue(value.value)) + { + return writer.PutNull(tag); + } + return writer.Put(tag, value.value); + } + case ZCL_DOUBLE_ATTRIBUTE_TYPE: { // 64-bit float + union + { + uint8_t raw[sizeof(double)]; + double value; + } value; + + if (!endianReader.ReadBytes(value.raw, sizeof(value)).IsSuccess()) + { + return endianReader.StatusCode(); + } + if (NumericAttributeTraits::IsNullValue(value.value)) + { + return writer.PutNull(tag); + } + return writer.Put(tag, value.value); + } + + case ZCL_CHAR_STRING_ATTRIBUTE_TYPE: // Char string + return EncodeString(PascalStringType::kShort, TLV::kTLVType_UTF8String, writer, tag, endianReader, mIsNullable); + case ZCL_LONG_CHAR_STRING_ATTRIBUTE_TYPE: + return EncodeString(PascalStringType::kLong, TLV::kTLVType_UTF8String, writer, tag, endianReader, mIsNullable); + case ZCL_OCTET_STRING_ATTRIBUTE_TYPE: // Octet string + return EncodeString(PascalStringType::kShort, TLV::kTLVType_ByteString, writer, tag, endianReader, mIsNullable); + case ZCL_LONG_OCTET_STRING_ATTRIBUTE_TYPE: + return EncodeString(PascalStringType::kLong, TLV::kTLVType_ByteString, writer, tag, endianReader, mIsNullable); + default: + ChipLogError(DataManagement, "Attribute type 0x%x not handled", static_cast(mAttributeType)); + return CHIP_IM_GLOBAL_STATUS(Failure); + } +} + } // namespace Ember } // namespace app } // namespace chip diff --git a/src/app/codegen-data-model-provider/EmberAttributeDataBuffer.h b/src/app/codegen-data-model-provider/EmberAttributeDataBuffer.h index a4f24c78c0476b..c3d7acfcafb72b 100644 --- a/src/app/codegen-data-model-provider/EmberAttributeDataBuffer.h +++ b/src/app/codegen-data-model-provider/EmberAttributeDataBuffer.h @@ -16,10 +16,12 @@ */ #pragma once +#include "lib/core/TLVWriter.h" #include #include #include #include +#include #include #include @@ -39,6 +41,14 @@ namespace Ember { class EmberAttributeDataBuffer { public: +#if CHIP_CONFIG_BIG_ENDIAN_TARGET + using EndianWriter = Encoding::BigEndian::BufferWriter; + using EndianReader = Encoding::BigEndian::Reader; +#else + using EndianWriter = Encoding::LittleEndian::BufferWriter; + using EndianReader = Encoding::LittleEndian::Reader; +#endif + enum class PascalStringType { kShort, @@ -59,12 +69,14 @@ class EmberAttributeDataBuffer /// modified by this call. CHIP_ERROR Decode(chip::TLV::TLVReader & reader); + /// Writes the data encoded in the underlying buffer into the given `writer` + /// + /// The data in the internal data buffer is assumed to be already formatted correctly + /// HOWEVER the size inside it will not be fully considered (i.e. encoding will use + /// the data encoding line integer or string sizes and NOT the databuffer max size) + CHIP_ERROR Encode(chip::TLV::TLVWriter & writer, TLV::Tag tag) const; + private: -#if CHIP_CONFIG_BIG_ENDIAN_TARGET - using EndianWriter = Encoding::BigEndian::BufferWriter; -#else - using EndianWriter = Encoding::LittleEndian::BufferWriter; -#endif /// Decodes the UNSIGNED integer stored in `reader` and places its content into `writer` /// Takes into account internal mIsNullable. CHIP_ERROR DecodeUnsignedInteger(chip::TLV::TLVReader & reader, EndianWriter & writer); @@ -73,6 +85,10 @@ class EmberAttributeDataBuffer /// Takes into account internal mIsNullable. CHIP_ERROR DecodeSignedInteger(chip::TLV::TLVReader & reader, EndianWriter & writer); + /// Encodes the UNSIGNED integer into `writer`. + /// Takes into account internal mIsNullable. + CHIP_ERROR EncodeInteger(chip::TLV::TLVWriter & writer, TLV::Tag tag, EndianReader & reader) const; + /// Decodes the string/byte string contained in `reader` and stores it into `writer`. /// String is encoded using a pascal-prefix of size `stringType`. /// Takes into account internal mIsNullable. @@ -96,6 +112,11 @@ inline CHIP_ERROR Decode(TLV::TLVReader & reader, Ember::EmberAttributeDataBuffe return buffer.Decode(reader); } +inline CHIP_ERROR Encode(TLV::TLVWriter & writer, TLV::Tag tag, Ember::EmberAttributeDataBuffer & buffer) +{ + return buffer.Encode(writer, tag); +} + } // namespace DataModel } // namespace app } // namespace chip diff --git a/src/app/codegen-data-model-provider/tests/TestEmberAttributeDataBuffer.cpp b/src/app/codegen-data-model-provider/tests/TestEmberAttributeDataBuffer.cpp index 7d46360029c529..dc83773454d1ff 100644 --- a/src/app/codegen-data-model-provider/tests/TestEmberAttributeDataBuffer.cpp +++ b/src/app/codegen-data-model-provider/tests/TestEmberAttributeDataBuffer.cpp @@ -101,6 +101,56 @@ class EncodeResult std::optional mResult; }; +template +bool IsEqual(const T & a, const T & b) +{ + return a == b; +} + +template <> +bool IsEqual(const ByteSpan & a, const ByteSpan & b) +{ + return a.data_equal(b); +} + +template <> +bool IsEqual(const CharSpan & a, const CharSpan & b) +{ + return a.data_equal(b); +} + +template +bool IsEqual(const std::optional & a, const std::optional & b) +{ + if (a.has_value() != b.has_value()) + { + return false; + } + + if (!a.has_value()) + { + return true; + } + + return IsEqual(*a, *b); +} + +template +bool IsEqual(const DataModel::Nullable & a, const DataModel::Nullable & b) +{ + if (a.IsNull() != b.IsNull()) + { + return false; + } + + if (a.IsNull()) + { + return true; + } + + return IsEqual(a.Value(), b.Value()); +} + /// Validates that an encoded value in ember takes a specific format template class EncodeTester @@ -122,7 +172,6 @@ class EncodeTester CHIP_ERROR err = buffer.Decode(reader); if (err != CHIP_NO_ERROR) { - ChipLogError(Test, "Decoding failed: %" CHIP_ERROR_FORMAT, err.Format()); return err; } @@ -142,6 +191,42 @@ class EncodeTester return EncodeResult::Ok(); } + template + EncodeResult TryDecode(const T & value, const uint8_t (&arr)[N]) + { + // Write data to TLV + { + uint8_t mutableBuffer[N]; + memcpy(mutableBuffer, arr, N); + + MutableByteSpan data_span(mutableBuffer); + Ember::EmberAttributeDataBuffer buffer(mMetaData, data_span); + + TLV::TLVWriter writer; + writer.Init(mEmberAttributeDataBuffer, sizeof(mEmberAttributeDataBuffer)); + ReturnErrorOnFailure(buffer.Encode(writer, TLV::AnonymousTag())); + ReturnErrorOnFailure(writer.Finalize()); + } + + // Data was written in TLV. Take it back out + + TLV::TLVReader reader; + reader.Init(mEmberAttributeDataBuffer, sizeof(mEmberAttributeDataBuffer)); + + ReturnErrorOnFailure(reader.Next()); + + T encodedValue; + ReturnErrorOnFailure(DataModel::Decode(reader, encodedValue)); + + if (!IsEqual(encodedValue, value)) + { + ChipLogError(Test, "Encode mismatch: different data"); + return CHIP_ERROR_INTERNAL; + } + + return EncodeResult::Ok(); + } + private: const EmberAfAttributeMetadata * mMetaData; uint8_t mEmberAttributeDataBuffer[kMaxSize]; @@ -570,7 +655,7 @@ TEST(TestEmberAttributeBuffer, TestEncodeStrings) } } -TEST(TestEmberAttributeBuffer, TestFailures) +TEST(TestEmberAttributeBuffer, TestEncodeFailures) { { // attribute type that is not handled @@ -581,11 +666,38 @@ TEST(TestEmberAttributeBuffer, TestFailures) { // Insufficient space EncodeTester<3> tester(CreateFakeMeta(ZCL_CHAR_STRING_ATTRIBUTE_TYPE, true /* nullable */)); + + // Empty is ok EXPECT_TRUE(tester.TryEncode(""_span, { 0 }).IsSuccess()); + + // Short strings (with and without count) is wrong. EXPECT_EQ(tester.TryEncode("test"_span, { 0 }), CHIP_ERROR_NO_MEMORY); + EXPECT_EQ(tester.TryEncode("foo"_span, { 3, 'f', 'o' }), CHIP_ERROR_NO_MEMORY); + EXPECT_TRUE(tester.TryEncode>(DataModel::NullNullable, { 0xFF }).IsSuccess()); } + { + // Insufficient space + EncodeTester<3> tester(CreateFakeMeta(ZCL_LONG_CHAR_STRING_ATTRIBUTE_TYPE, true /* nullable */)); + + // Empty is ok + EXPECT_TRUE(tester.TryEncode(""_span, { 0, 0 }).IsSuccess()); + + // Short strings (with and without count) is wrong. + EXPECT_EQ(tester.TryEncode("test"_span, { 0 }), CHIP_ERROR_NO_MEMORY); + EXPECT_EQ(tester.TryEncode("foo"_span, { 0, 3, 'f', 'o' }), CHIP_ERROR_NO_MEMORY); + EXPECT_EQ(tester.TryEncode("test"_span, { 0xFF }), CHIP_ERROR_NO_MEMORY); + + EXPECT_TRUE(tester.TryEncode>(DataModel::NullNullable, { 0xFF, 0xFF }).IsSuccess()); + } + + { + // Insufficient space even for length + EncodeTester<1> tester(CreateFakeMeta(ZCL_LONG_CHAR_STRING_ATTRIBUTE_TYPE, true /* nullable */)); + EXPECT_EQ(tester.TryEncode(""_span, { 0 }), CHIP_ERROR_NO_MEMORY); + } + // bad type casts { EncodeTester tester(CreateFakeMeta(ZCL_CHAR_STRING_ATTRIBUTE_TYPE, false /* nullable */)); @@ -596,3 +708,429 @@ TEST(TestEmberAttributeBuffer, TestFailures) EXPECT_EQ(tester.TryEncode(true, { 0 }), CHIP_ERROR_WRONG_TLV_TYPE); } } + +TEST(TestEmberAttributeBuffer, TestNoData) +{ + EncodeTester tester(CreateFakeMeta(ZCL_NO_DATA_ATTRIBUTE_TYPE, true /* nullable */)); + + // support a always-null type + EXPECT_TRUE(tester.TryDecode>(DataModel::NullNullable, { 0 }).IsSuccess()); + EXPECT_TRUE(tester.TryDecode>(DataModel::NullNullable, { 0 }).IsSuccess()); + EXPECT_TRUE(tester.TryDecode>(DataModel::NullNullable, { 0 }).IsSuccess()); +} + +TEST(TestEmberAttributeBuffer, TestDecodeFailures) +{ + { + // attribute type that is not handled + EncodeTester tester(CreateFakeMeta(ZCL_UNKNOWN_ATTRIBUTE_TYPE, true /* nullable */)); + EXPECT_EQ(tester.TryDecode>(DataModel::NullNullable, { 0 }), CHIP_IM_GLOBAL_STATUS(Failure)); + } + + { + // Insufficient input + EncodeTester<3> tester(CreateFakeMeta(ZCL_CHAR_STRING_ATTRIBUTE_TYPE, true /* nullable */)); + + EXPECT_EQ(tester.TryDecode("test"_span, { 10 }), CHIP_ERROR_BUFFER_TOO_SMALL); + EXPECT_EQ(tester.TryDecode("foo"_span, { 3, 'f', 'o' }), CHIP_ERROR_BUFFER_TOO_SMALL); + } + + { + // Insufficient data buffer - should never happen, but test that we will error out + EncodeTester tester(CreateFakeMeta(ZCL_INT32U_ATTRIBUTE_TYPE, false /* nullable */)); + EXPECT_EQ(tester.TryDecode(123, { 1, 2, 3 }), CHIP_ERROR_BUFFER_TOO_SMALL); + } + + { + // Insufficient data buffer - should never happen, but test that we will error out + EncodeTester tester(CreateFakeMeta(ZCL_SINGLE_ATTRIBUTE_TYPE, false /* nullable */)); + EXPECT_EQ(tester.TryDecode(1.5f, { 1, 2, 3 }), CHIP_ERROR_BUFFER_TOO_SMALL); + } + + { + // Insufficient data buffer - should never happen, but test that we will error out + EncodeTester tester(CreateFakeMeta(ZCL_DOUBLE_ATTRIBUTE_TYPE, false /* nullable */)); + EXPECT_EQ(tester.TryDecode(1.5, { 1, 2, 3 }), CHIP_ERROR_BUFFER_TOO_SMALL); + } + + { + // Bad boolean data + EncodeTester tester(CreateFakeMeta(ZCL_BOOLEAN_ATTRIBUTE_TYPE, false /* nullable */)); + EXPECT_EQ(tester.TryDecode(true, { 123 }), CHIP_ERROR_INCORRECT_STATE); + } +} + +TEST(TestEmberAttributeBuffer, TestDecodeSignedTypes) +{ + { + EncodeTester tester(CreateFakeMeta(ZCL_INT8S_ATTRIBUTE_TYPE, false /* nullable */)); + + EXPECT_TRUE(tester.TryDecode(0, { 0 }).IsSuccess()); + EXPECT_TRUE(tester.TryDecode(123, { 123 }).IsSuccess()); + EXPECT_TRUE(tester.TryDecode(127, { 127 }).IsSuccess()); + EXPECT_TRUE(tester.TryDecode(-10, { 0xF6 }).IsSuccess()); + EXPECT_TRUE(tester.TryDecode(-128, { 0x80 }).IsSuccess()); + + // longer data is ok + EXPECT_TRUE(tester.TryDecode(-128, { 0x80, 1, 2, 3, 4 }).IsSuccess()); + } + + { + EncodeTester tester(CreateFakeMeta(ZCL_INT8S_ATTRIBUTE_TYPE, true /* nullable */)); + + EXPECT_TRUE(tester.TryDecode(0, { 0 }).IsSuccess()); + EXPECT_TRUE(tester.TryDecode(123, { 123 }).IsSuccess()); + EXPECT_TRUE(tester.TryDecode(127, { 127 }).IsSuccess()); + EXPECT_TRUE(tester.TryDecode(-10, { 0xF6 }).IsSuccess()); + EXPECT_TRUE(tester.TryDecode(-127, { 0x81 }).IsSuccess()); + + // NULL can be decoded + EXPECT_TRUE(tester.TryDecode>(DataModel::NullNullable, { 0x80 }).IsSuccess()); + + // decoding as nullable proceeds as normal + EXPECT_TRUE(tester.TryDecode>(-127, { 0x81 }).IsSuccess()); + } + + { + + EncodeTester tester(CreateFakeMeta(ZCL_INT16S_ATTRIBUTE_TYPE, false /* nullable */)); + + EXPECT_TRUE(tester.TryDecode(0, { 0, 0 }).IsSuccess()); + EXPECT_TRUE(tester.TryDecode(123, { 123, 0 }).IsSuccess()); + EXPECT_TRUE(tester.TryDecode(127, { 127, 0 }).IsSuccess()); + EXPECT_TRUE(tester.TryDecode(-10, { 0xF6, 0xFF }).IsSuccess()); + EXPECT_TRUE(tester.TryDecode(-128, { 0x80, 0xFF }).IsSuccess()); + EXPECT_TRUE(tester.TryDecode(-1234, { 0x2E, 0xFB }).IsSuccess()); + EXPECT_TRUE(tester.TryDecode(std::numeric_limits::min(), { 0x0, 0x80 }).IsSuccess()); + } + + { + EncodeTester tester(CreateFakeMeta(ZCL_INT16S_ATTRIBUTE_TYPE, true /* nullable */)); + + EXPECT_TRUE(tester.TryDecode(0, { 0, 0 }).IsSuccess()); + EXPECT_TRUE(tester.TryDecode(123, { 123, 0 }).IsSuccess()); + EXPECT_TRUE(tester.TryDecode(127, { 127, 0 }).IsSuccess()); + EXPECT_TRUE(tester.TryDecode(-10, { 0xF6, 0xFF }).IsSuccess()); + + // NULL decoding + EXPECT_TRUE(tester.TryDecode>(DataModel::NullNullable, { 0x00, 0x80 }).IsSuccess()); + } + + // Odd size integers + { + EncodeTester tester(CreateFakeMeta(ZCL_INT24S_ATTRIBUTE_TYPE, false /* nullable */)); + + EXPECT_TRUE(tester.TryDecode(0, { 0, 0, 0 }).IsSuccess()); + EXPECT_TRUE(tester.TryDecode(0x123456, { 0x56, 0x34, 0x12 }).IsSuccess()); + EXPECT_TRUE(tester.TryDecode(-1, { 0xFF, 0xFF, 0xFF }).IsSuccess()); + EXPECT_TRUE(tester.TryDecode(-10, { 0xF6, 0xFF, 0xFF }).IsSuccess()); + EXPECT_TRUE(tester.TryDecode(-1234, { 0x2E, 0xFB, 0xFF }).IsSuccess()); + } + { + EncodeTester tester(CreateFakeMeta(ZCL_INT24S_ATTRIBUTE_TYPE, true /* nullable */)); + + EXPECT_TRUE(tester.TryDecode(0, { 0, 0, 0 }).IsSuccess()); + EXPECT_TRUE(tester.TryDecode(0x123456, { 0x56, 0x34, 0x12 }).IsSuccess()); + EXPECT_TRUE(tester.TryDecode(-1, { 0xFF, 0xFF, 0xFF }).IsSuccess()); + EXPECT_TRUE(tester.TryDecode(-10, { 0xF6, 0xFF, 0xFF }).IsSuccess()); + EXPECT_TRUE(tester.TryDecode(-1234, { 0x2E, 0xFB, 0xFF }).IsSuccess()); + + EXPECT_TRUE(tester.TryDecode>(DataModel::NullNullable, { 0x00, 0x00, 0x80 }).IsSuccess()); + } + + { + EncodeTester tester(CreateFakeMeta(ZCL_INT40S_ATTRIBUTE_TYPE, true /* nullable */)); + + // NOTE: to generate encoded values, you an use commands like: + // + // python -c 'import struct; print(", ".join(["0x%X" % v for v in struct.pack("(0, { 0, 0, 0, 0, 0 }).IsSuccess()); + EXPECT_TRUE(tester.TryDecode(0x123456, { 0x56, 0x34, 0x12, 0, 0 }).IsSuccess()); + EXPECT_TRUE(tester.TryDecode(-1234, { 0x2E, 0xFB, 0xFF, 0xFF, 0xFF }).IsSuccess()); + EXPECT_TRUE(tester.TryDecode(-123456789, { 0xeb, 0x32, 0xa4, 0xf8, 0xFF }).IsSuccess()); + EXPECT_TRUE(tester.TryDecode(-12345678910, { 0xc2, 0xe3, 0x23, 0x20, 0xfd }).IsSuccess()); + + EXPECT_TRUE( + tester.TryDecode>(DataModel::NullNullable, { 0x00, 0x00, 0x00, 0x00, 0x80 }).IsSuccess()); + } + + // Double-check tests, not as exhaustive, to cover all other unsigned values and get + // more test line coverage + { + EncodeTester tester(CreateFakeMeta(ZCL_INT32S_ATTRIBUTE_TYPE, true /* nullable */)); + EXPECT_TRUE(tester.TryDecode(-1234, { 0x2E, 0xFB, 0xFF, 0xFF }).IsSuccess()); + } + { + EncodeTester tester(CreateFakeMeta(ZCL_INT48S_ATTRIBUTE_TYPE, true /* nullable */)); + EXPECT_TRUE(tester.TryDecode(-1234, { 0x2E, 0xFB, 0xFF, 0xFF, 0xFF, 0xFF }).IsSuccess()); + } + { + EncodeTester tester(CreateFakeMeta(ZCL_INT56S_ATTRIBUTE_TYPE, true /* nullable */)); + EXPECT_TRUE(tester.TryDecode(-1234, { 0x2E, 0xFB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }).IsSuccess()); + } + + { + EncodeTester tester(CreateFakeMeta(ZCL_INT64S_ATTRIBUTE_TYPE, true /* nullable */)); + EXPECT_TRUE(tester.TryDecode(-1234, { 0x2E, 0xFB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }).IsSuccess()); + + // min/max ranges too + EXPECT_TRUE( + tester.TryDecode(std::numeric_limits::min() + 1, { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80 }) + .IsSuccess()); + EXPECT_TRUE( + tester.TryDecode(std::numeric_limits::max(), { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F }) + .IsSuccess()); + + EXPECT_TRUE(tester + .TryDecode>(DataModel::NullNullable, + { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80 }) + .IsSuccess()); + } + + { + EncodeTester tester(CreateFakeMeta(ZCL_INT64S_ATTRIBUTE_TYPE, false /* nullable */)); + EXPECT_TRUE(tester.TryDecode(-1234, { 0x2E, 0xFB, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }).IsSuccess()); + + EXPECT_TRUE( + tester.TryDecode(std::numeric_limits::min(), { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80 }) + .IsSuccess()); + EXPECT_TRUE( + tester.TryDecode(std::numeric_limits::min() + 1, { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80 }) + .IsSuccess()); + EXPECT_TRUE( + tester.TryDecode(std::numeric_limits::max(), { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F }) + .IsSuccess()); + } +} + +TEST(TestEmberAttributeBuffer, TestDecodeUnsignedTypes) +{ + { + EncodeTester tester(CreateFakeMeta(ZCL_INT8U_ATTRIBUTE_TYPE, false /* nullable */)); + + EXPECT_TRUE(tester.TryDecode(0, { 0 }).IsSuccess()); + EXPECT_TRUE(tester.TryDecode(123, { 123 }).IsSuccess()); + EXPECT_TRUE(tester.TryDecode(0xFD, { 0xFD }).IsSuccess()); + EXPECT_TRUE(tester.TryDecode(255, { 0xFF }).IsSuccess()); + } + + { + EncodeTester tester(CreateFakeMeta(ZCL_INT8U_ATTRIBUTE_TYPE, true /* nullable */)); + + EXPECT_TRUE(tester.TryDecode(0, { 0 }).IsSuccess()); + EXPECT_TRUE(tester.TryDecode(123, { 123 }).IsSuccess()); + EXPECT_TRUE(tester.TryDecode(0xFD, { 0xFD }).IsSuccess()); + EXPECT_TRUE(tester.TryDecode>(DataModel::NullNullable, { 0xFF }).IsSuccess()); + + // NULL decoding should work + EXPECT_TRUE(tester.TryDecode>(DataModel::NullNullable, { 0xFF }).IsSuccess()); + } + + { + EncodeTester tester(CreateFakeMeta(ZCL_INT16U_ATTRIBUTE_TYPE, false /* nullable */)); + + EXPECT_TRUE(tester.TryDecode(0, { 0, 0 }).IsSuccess()); + EXPECT_TRUE(tester.TryDecode(123, { 123, 0 }).IsSuccess()); + EXPECT_TRUE(tester.TryDecode(0xFD, { 0xFD, 0 }).IsSuccess()); + EXPECT_TRUE(tester.TryDecode(255, { 0xFF, 0 }).IsSuccess()); + EXPECT_TRUE(tester.TryDecode(0xABCD, { 0xCD, 0xAB }).IsSuccess()); + EXPECT_TRUE(tester.TryDecode(0xFFFF, { 0xFF, 0xFF }).IsSuccess()); + } + + { + EncodeTester tester(CreateFakeMeta(ZCL_INT16U_ATTRIBUTE_TYPE, true /* nullable */)); + + EXPECT_TRUE(tester.TryDecode(0, { 0, 0 }).IsSuccess()); + EXPECT_TRUE(tester.TryDecode(123, { 123, 0 }).IsSuccess()); + EXPECT_TRUE(tester.TryDecode(0xFD, { 0xFD, 0 }).IsSuccess()); + EXPECT_TRUE(tester.TryDecode(255, { 0xFF, 0 }).IsSuccess()); + EXPECT_TRUE(tester.TryDecode(0xABCD, { 0xCD, 0xAB }).IsSuccess()); + EXPECT_TRUE(tester.TryDecode>(DataModel::NullNullable, { 0xFF, 0xFF }).IsSuccess()); + + // NULL SUPPORT + EXPECT_TRUE(tester.TryDecode>(DataModel::NullNullable, { 0xFF, 0xFF }).IsSuccess()); + } + { + EncodeTester tester(CreateFakeMeta(ZCL_INT64U_ATTRIBUTE_TYPE, true /* nullable */)); + + EXPECT_TRUE(tester.TryDecode(0, { 0, 0, 0, 0, 0, 0, 0, 0 }).IsSuccess()); + EXPECT_TRUE(tester.TryDecode(0x1234567, { 0x67, 0x45, 0x23, 0x01, 0, 0, 0, 0 }).IsSuccess()); + EXPECT_TRUE(tester.TryDecode(0xAABBCCDDEEFF1122, { 0x22, 0x11, 0xFF, 0xEE, 0xDD, 0xCC, 0xBB, 0xAA }).IsSuccess()); + EXPECT_TRUE( + tester.TryDecode(std::numeric_limits::max() - 1, { 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }) + .IsSuccess()); + + EXPECT_TRUE(tester + .TryDecode>(DataModel::NullNullable, + { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }) + .IsSuccess()); + + EXPECT_TRUE(tester + .TryDecode>(DataModel::NullNullable, + { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }) + .IsSuccess()); + } + { + EncodeTester tester(CreateFakeMeta(ZCL_INT64U_ATTRIBUTE_TYPE, false /* nullable */)); + + // we should be able to encode the maximum value + EXPECT_TRUE( + tester.TryDecode(std::numeric_limits::max(), { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }) + .IsSuccess()); + } + + /// Odd sized integers + { + EncodeTester tester(CreateFakeMeta(ZCL_INT24U_ATTRIBUTE_TYPE, false /* nullable */)); + EXPECT_TRUE(tester.TryDecode(0, { 0, 0, 0 }).IsSuccess()); + EXPECT_TRUE(tester.TryDecode(0x123456, { 0x56, 0x34, 0x12 }).IsSuccess()); + EXPECT_TRUE(tester.TryDecode(0xFFFFFF, { 0xFF, 0xFF, 0xFF }).IsSuccess()); + } + { + EncodeTester tester(CreateFakeMeta(ZCL_INT24U_ATTRIBUTE_TYPE, true /* nullable */)); + EXPECT_TRUE(tester.TryDecode(0, { 0, 0, 0 }).IsSuccess()); + EXPECT_TRUE(tester.TryDecode(0x123456, { 0x56, 0x34, 0x12 }).IsSuccess()); + EXPECT_TRUE(tester.TryDecode>(DataModel::NullNullable, { 0xFF, 0xFF, 0xFF }).IsSuccess()); + EXPECT_TRUE(tester.TryDecode>(0x1234, { 0x34, 0x12, 0x00 }).IsSuccess()); + } + + { + EncodeTester tester(CreateFakeMeta(ZCL_INT40U_ATTRIBUTE_TYPE, true /* nullable */)); + EXPECT_TRUE(tester.TryDecode(0, { 0, 0, 0, 0, 0 }).IsSuccess()); + EXPECT_TRUE(tester.TryDecode(0x123456, { 0x56, 0x34, 0x12, 0, 0 }).IsSuccess()); + EXPECT_TRUE(tester.TryDecode(0x123456FFFF, { 0xFF, 0xFF, 0x56, 0x34, 0x12 }).IsSuccess()); + EXPECT_TRUE( + tester.TryDecode>(DataModel::NullNullable, { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }).IsSuccess()); + } + + // Double-check tests, not as exhaustive, to cover all other unsigned values and get + // more test line coverage + { + EncodeTester tester(CreateFakeMeta(ZCL_INT32U_ATTRIBUTE_TYPE, true /* nullable */)); + EXPECT_TRUE(tester.TryDecode(0x1234, { 0x34, 0x12, 0, 0 }).IsSuccess()); + } + { + EncodeTester tester(CreateFakeMeta(ZCL_INT48U_ATTRIBUTE_TYPE, true /* nullable */)); + EXPECT_TRUE(tester.TryDecode(0x1234, { 0x34, 0x12, 0, 0, 0, 0 }).IsSuccess()); + } + { + EncodeTester tester(CreateFakeMeta(ZCL_INT56U_ATTRIBUTE_TYPE, true /* nullable */)); + EXPECT_TRUE(tester.TryDecode(0x1234, { 0x34, 0x12, 0, 0, 0, 0, 0 }).IsSuccess()); + } +} + +TEST(TestEmberAttributeBuffer, TestDecodeStrings) +{ + { + EncodeTester tester(CreateFakeMeta(ZCL_CHAR_STRING_ATTRIBUTE_TYPE, false /* nullable */)); + EXPECT_TRUE(tester.TryDecode(""_span, { 0 }).IsSuccess()); + EXPECT_TRUE(tester.TryDecode("test"_span, { 4, 't', 'e', 's', 't' }).IsSuccess()); + EXPECT_TRUE(tester.TryDecode("foo"_span, { 3, 'f', 'o', 'o' }).IsSuccess()); + } + + { + EncodeTester tester(CreateFakeMeta(ZCL_CHAR_STRING_ATTRIBUTE_TYPE, true /* nullable */)); + EXPECT_TRUE(tester.TryDecode(""_span, { 0 }).IsSuccess()); + EXPECT_TRUE(tester.TryDecode("test"_span, { 4, 't', 'e', 's', 't' }).IsSuccess()); + EXPECT_TRUE(tester.TryDecode>(DataModel::NullNullable, { 0xFF }).IsSuccess()); + } + + { + EncodeTester tester(CreateFakeMeta(ZCL_LONG_CHAR_STRING_ATTRIBUTE_TYPE, false /* nullable */)); + EXPECT_TRUE(tester.TryDecode(""_span, { 0, 0 }).IsSuccess()); + EXPECT_TRUE(tester.TryDecode("test"_span, { 4, 0, 't', 'e', 's', 't' }).IsSuccess()); + EXPECT_TRUE(tester.TryDecode("foo"_span, { 3, 0, 'f', 'o', 'o' }).IsSuccess()); + } + + { + EncodeTester tester(CreateFakeMeta(ZCL_LONG_CHAR_STRING_ATTRIBUTE_TYPE, true /* nullable */)); + EXPECT_TRUE(tester.TryDecode("test"_span, { 4, 0, 't', 'e', 's', 't' }).IsSuccess()); + EXPECT_TRUE(tester.TryDecode>(DataModel::NullNullable, { 0xFF, 0xFF }).IsSuccess()); + } + + const uint8_t kOctetData[] = { 1, 2, 3 }; + + // Binary data + { + EncodeTester tester(CreateFakeMeta(ZCL_OCTET_STRING_ATTRIBUTE_TYPE, false /* nullable */)); + EXPECT_TRUE(tester.TryDecode(ByteSpan({}), { 0 }).IsSuccess()); + EXPECT_TRUE(tester.TryDecode(ByteSpan(kOctetData), { 3, 1, 2, 3 }).IsSuccess()); + } + + { + EncodeTester tester(CreateFakeMeta(ZCL_OCTET_STRING_ATTRIBUTE_TYPE, true /* nullable */)); + EXPECT_TRUE(tester.TryDecode(ByteSpan({}), { 0 }).IsSuccess()); + EXPECT_TRUE(tester.TryDecode(ByteSpan(kOctetData), { 3, 1, 2, 3 }).IsSuccess()); + EXPECT_TRUE(tester.TryDecode>(DataModel::NullNullable, { 0xFF }).IsSuccess()); + } + + { + EncodeTester tester(CreateFakeMeta(ZCL_LONG_OCTET_STRING_ATTRIBUTE_TYPE, false /* nullable */)); + EXPECT_TRUE(tester.TryDecode(ByteSpan({}), { 0, 0 }).IsSuccess()); + EXPECT_TRUE(tester.TryDecode(ByteSpan(kOctetData), { 3, 0, 1, 2, 3 }).IsSuccess()); + } + + { + EncodeTester tester(CreateFakeMeta(ZCL_LONG_OCTET_STRING_ATTRIBUTE_TYPE, true /* nullable */)); + EXPECT_TRUE(tester.TryDecode(ByteSpan({}), { 0, 0 }).IsSuccess()); + EXPECT_TRUE(tester.TryDecode(ByteSpan(kOctetData), { 3, 0, 1, 2, 3 }).IsSuccess()); + EXPECT_TRUE(tester.TryDecode>(DataModel::NullNullable, { 0xFF, 0xFF }).IsSuccess()); + } +} + +TEST(TestEmberAttributeBuffer, TestDecodeBool) +{ + { + EncodeTester tester(CreateFakeMeta(ZCL_BOOLEAN_ATTRIBUTE_TYPE, false /* nullable */)); + + EXPECT_TRUE(tester.TryDecode(true, { 1 }).IsSuccess()); + EXPECT_TRUE(tester.TryDecode(false, { 0 }).IsSuccess()); + } + + { + EncodeTester tester(CreateFakeMeta(ZCL_BOOLEAN_ATTRIBUTE_TYPE, true /* nullable */)); + + EXPECT_TRUE(tester.TryDecode>(true, { 1 }).IsSuccess()); + EXPECT_TRUE(tester.TryDecode>(false, { 0 }).IsSuccess()); + EXPECT_TRUE(tester.TryDecode>(DataModel::NullNullable, { 0xFF }).IsSuccess()); + } +} + +TEST(TestEmberAttributeBuffer, TestDecodeFloatingPoint) +{ + // NOTE: to generate encoded values, you an use commands like: + // + // python -c 'import struct; print(", ".join(["0x%X" % v for v in struct.pack("(123.55f, { 0x9A, 0x19, 0xF7, 0x42 }).IsSuccess()); + } + + { + EncodeTester tester(CreateFakeMeta(ZCL_SINGLE_ATTRIBUTE_TYPE, true /* nullable */)); + EXPECT_TRUE(tester.TryDecode(123.55f, { 0x9A, 0x19, 0xF7, 0x42 }).IsSuccess()); + EXPECT_TRUE(tester.TryDecode>(DataModel::NullNullable, { 0, 0, 0xC0, 0x7F }).IsSuccess()); + } + + { + EncodeTester tester(CreateFakeMeta(ZCL_DOUBLE_ATTRIBUTE_TYPE, false /* nullable */)); + EXPECT_TRUE(tester.TryDecode(123.55, { 0x33, 0x33, 0x33, 0x33, 0x33, 0xE3, 0x5E, 0x40 }).IsSuccess()); + } + + { + EncodeTester tester(CreateFakeMeta(ZCL_DOUBLE_ATTRIBUTE_TYPE, true /* nullable */)); + EXPECT_TRUE(tester.TryDecode(123.55, { 0x33, 0x33, 0x33, 0x33, 0x33, 0xE3, 0x5E, 0x40 }).IsSuccess()); + EXPECT_TRUE( + tester.TryDecode>(123.55, { 0x33, 0x33, 0x33, 0x33, 0x33, 0xE3, 0x5E, 0x40 }).IsSuccess()); + EXPECT_TRUE( + tester.TryDecode>(DataModel::NullNullable, { 0, 0, 0, 0, 0, 0, 0xF8, 0x7F }).IsSuccess()); + } +} From d814ce7073014aff5c812542a8500b6a34ad5a66 Mon Sep 17 00:00:00 2001 From: Vivien Nicolas Date: Thu, 24 Oct 2024 21:12:57 +0200 Subject: [PATCH 108/149] [chip-tool[darwin-framework-tool] Using ComplexArgument leaks on syntax failure and even on success (#36227) * [chip-tool[darwin-framework-tool] Using a malformed ComplexArgument may result into a leak * [chip-tool[darwin-framework-tool] Even on success the ComplexArgument may not be cleared properly --------- Co-authored-by: Andrei Litvin --- .../commands/clusters/ComplexArgument.h | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/examples/chip-tool/commands/clusters/ComplexArgument.h b/examples/chip-tool/commands/clusters/ComplexArgument.h index 6f92256ff735e4..695af2f764a9c1 100644 --- a/examples/chip-tool/commands/clusters/ComplexArgument.h +++ b/examples/chip-tool/commands/clusters/ComplexArgument.h @@ -181,7 +181,12 @@ class ComplexArgumentParser // - 11 is the maximum length of a %d (-2147483648, 2147483647) // - 2 is the length for the "[" and "]" characters. snprintf(labelWithIndex, sizeof(labelWithIndex), "%.241s[%d]", label, i); - ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithIndex, content[i], value[i])); + auto error = ComplexArgumentParser::Setup(labelWithIndex, content[i], value[i]); + if (CHIP_NO_ERROR != error) + { + chip::Platform::MemoryFree(content); + return error; + } } request = chip::app::DataModel::List(content, value.size()); @@ -415,7 +420,14 @@ class TypedComplexArgument : public ComplexArgument return ComplexArgumentParser::Setup(label, *mRequest, value); } - void Reset() { *mRequest = T(); } + void Reset() + { + if (mRequest != nullptr) + { + ComplexArgumentParser::Finalize(*mRequest); + *mRequest = T(); + } + } private: T * mRequest; From 4224d70393200ecf027c067788007cb63010a9ea Mon Sep 17 00:00:00 2001 From: Mathieu Kardous <84793247+mkardous-silabs@users.noreply.github.com> Date: Thu, 24 Oct 2024 15:16:27 -0400 Subject: [PATCH 109/149] delete unnecessary files from the docker image (#36237) --- integrations/docker/images/base/chip-build/version | 2 +- .../images/stage-2/chip-build-efr32/Dockerfile | 13 ++++++++++--- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/integrations/docker/images/base/chip-build/version b/integrations/docker/images/base/chip-build/version index f44401475bad25..081a6389d0be23 100644 --- a/integrations/docker/images/base/chip-build/version +++ b/integrations/docker/images/base/chip-build/version @@ -1 +1 @@ -86 : [Tizen] Pass runner's path as QEMU argument \ No newline at end of file +87 : [Silabs] Delete SDK files to reduce the amount of flash consummed diff --git a/integrations/docker/images/stage-2/chip-build-efr32/Dockerfile b/integrations/docker/images/stage-2/chip-build-efr32/Dockerfile index 3d65e2c52fa606..a202e835a78256 100644 --- a/integrations/docker/images/stage-2/chip-build-efr32/Dockerfile +++ b/integrations/docker/images/stage-2/chip-build-efr32/Dockerfile @@ -18,21 +18,28 @@ RUN wget https://github.com/SiliconLabs/simplicity_sdk/releases/download/v2024.6 && unzip /tmp/simplicity_sdk.zip -d /tmp/simplicity_sdk \ && rm -rf /tmp/simplicity_sdk.zip \ # Deleting files that are not needed to save space - && rm -rf /tmp/simplicity_sdk/protocol/flex /tmp/simplicity_sdk/protocol/z-wave /tmp/simplicity_sdk/protocol/zigbee /tmp/simplicity_sdk/protocol/wisun \ + && rm -rf /tmp/simplicity_sdk/protocol/flex /tmp/simplicity_sdk/protocol/z-wave /tmp/simplicity_sdk/protocol/zigbee /tmp/simplicity_sdk/protocol/wisun /tmp/simplicity_sdk/util/third_party/tensorflow_extra \ + /tmp/simplicity_sdk/util/third_party/sqlite /tmp/simplicity_sdk/util/third_party/ot-br-posix /tmp/simplicity_sdk/util/third_party/tflite-micro /tmp/simplicity_sdk/util/third_party/tflite-fatfs /tmp/simplicity_sdk/util/third_party/unity_test_framework \ + /tmp/simplicity_sdk/platform/radio/efr32_multiphy_configurator \ && find /tmp/simplicity_sdk/protocol/bluetooth /tmp/simplicity_sdk/platform -name "*.a" -type f -delete \ && find /tmp/simplicity_sdk/protocol/openthread -name "*efr32mg21*" -delete \ + && find /tmp/simplicity_sdk \( -name "libsl_platform_ftd_efr32mg2*" -o -name "libsl_ot_stack_mtd_efr32mg2*" \) -type f -delete \ + && find /tmp/simplicity_sdk/hardware/board/config -mindepth 1 -maxdepth 1 -type d ! \( -name '*brd4186c*' -o -name '*brd4187c*' -o -name '*brd4186a*' -o -name '*brd4187a*' -o -name '*brd2601b*' -o -name '*brd2703a*' -o -name '*brd2704a*' \ + -o -name '*brd4316a*' -o -name '*brd4317a*' -o -name '*brd4318a*' -o -name '*brd4319a*' -o -name '*brd4116a*' -o -name '*brd4117a*' -o -name '*brd4118a*' -o -name '*brd2608a*' \) -exec rm -rf {} + \ + && find /tmp/simplicity_sdk/platform/Device/SiliconLabs -mindepth 1 -maxdepth 1 -type d ! \( -name 'EFR32MG24' -o -name 'EFR32MG26' -o -name 'MGM24' \) -exec rm -rf {} + \ + && find /tmp/simplicity_sdk -name "*.slc*" -type f -delete \ && : # last line # Clone WiSeConnect Wi-Fi and Bluetooth Software 2.10.3 (b6d6cb5) RUN git clone --depth=1 --single-branch --branch=2.10.3 https://github.com/SiliconLabs/wiseconnect-wifi-bt-sdk.git /tmp/wiseconnect-wifi-bt-sdk && \ cd /tmp/wiseconnect-wifi-bt-sdk && \ - rm -rf .git \ + rm -rf .git examples \ && : # last line # Clone WiSeConnect SDK v3.3.3 (a6390dd) RUN git clone --depth=1 --single-branch --branch=v3.3.3 https://github.com/SiliconLabs/wiseconnect.git /tmp/wifi_sdk && \ cd /tmp/wifi_sdk && \ - rm -rf .git \ + rm -rf .git examples components/device/stm32 \ && : # last line # SLC-cli install From 8852bbeb47a83b384d251d90a8f59c2649f8f73c Mon Sep 17 00:00:00 2001 From: Raul Marquez <130402456+raul-marquez-csa@users.noreply.github.com> Date: Thu, 24 Oct 2024 12:37:56 -0700 Subject: [PATCH 110/149] Removes yaml script (#36212) --- .../certification/Test_TC_OPCREDS_3_2.yaml | 437 ------------------ src/app/tests/suites/manualTests.json | 1 - 2 files changed, 438 deletions(-) delete mode 100644 src/app/tests/suites/certification/Test_TC_OPCREDS_3_2.yaml diff --git a/src/app/tests/suites/certification/Test_TC_OPCREDS_3_2.yaml b/src/app/tests/suites/certification/Test_TC_OPCREDS_3_2.yaml deleted file mode 100644 index a4974d02df7e3d..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_OPCREDS_3_2.yaml +++ /dev/null @@ -1,437 +0,0 @@ -# Copyright (c) 2021 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. -# Auto-generated scripts for harness use only, please review before automation. The endpoints and cluster names are currently set to default - -name: - 15.2.2. [TC-OPCREDS-3.2] Attribute-CurrentFabricIndex validation - [DUT-Server] - -PICS: - - OPCREDS.S - -config: - nodeId: 0x12344321 - cluster: "Basic Information" - endpoint: 0 - -tests: - - label: "Precondition" - verification: | - This test case assumes that during Commissioning AddNOC will be sent with ICACValue - disabled: true - - - label: "Step 1: Factory Reset DUT" - verification: | - On both DUT and TH side use the below command - sudo rm -rf /tmp/chip_* - disabled: true - - - label: - "Step 2: Commission DUT to TH1s Fabric When DUT sends NOC response - save FabricIndex as FabricIndex_TH1" - verification: | - DUT side: - sudo ./chip-all-clusters-app --wifi - - TH side: - ./chip-tool pairing ble-wifi 1 zigbeehome matter123 20202021 3841 --trace_decode 1 - - [1650455358.501816][4366:4371] CHIP:TOO: Device commissioning completed with success" - - - After commissioning DUT to TH1's fabric read nocs - - Save the FabricIndex and NOC value during commissioning in TH Log - - [1673248033.951950][1706:1708] CHIP:CTL: OperationalSessionSetup[1:0000000000000001]: State change 2 --> 3 - [1673248033.952156][1706:1708] CHIP:IN: SecureSession[0xffffa803fa40]: Allocated Type:2 LSID:14065 - [1673248033.952247][1706:1708] CHIP:SC: Initiating session on local FabricIndex 1 from 0x000000000001B669 -> 0x0000000000000001 - [1673248033.954558][1706:1708] CHIP:EM: <<< [E:44273i M:220413667] (U) Msg TX to 0:0000000000000000 [0000] --- Type 0000:30 (SecureChannel:CASE_Sigma1) - [1673248033.954856][1706:1708] CHIP:IN: (U) Sending msg 220413667 to IP address 'UDP:[fe80::e65f:1ff:fe0e:be36%eth0]:5540' - [1673248033.955496][1706:1708] CHIP:DMG: >> to UDP:[fe80::e65f:1ff:fe0e:be36%eth0]:5540 | 220413667 | [Secure Channel (0) / Certificate Authenticated Session Establishment Sigma '1' (0x30) / Session = 0 / Exchange = 44273] - [1679562607.575771][126855:126857] CHIP:DMG: } - [1679562607.575776][126855:126857] CHIP:DMG: - [1679562607.575833][126855:126857] CHIP:DMG: NOCValue (241) = - [1679562607.575852][126855:126857] CHIP:DMG: { - FTABAQEkAgE3AyQTAhgmBIAigScmBYAlTTo3BiQVASQRARgkBwEkCAEwCUEECq7oyCv/0OLZ4DyFaO6+SuXasHNJcvBFGJcsjh7K/OU92vFP6+dVfa72+vn0Bj2zE2yEB/xGY6firv0ccIYCaDcKNQEoARgkAgE2AwQCBAEYMAQUyGYyV+0qHvlilDYdFF5//OTDeCcwBRSTcEvTAX3+cztsuvoZoqtHd61F3BgwC0BOygoI269loXpAssEaxpMPqplxS9GHmVhY04u/WVsNODFSFnzgBMd4Bd4yl75UoEIYkQ9SNMbuE6wMidFO1b8OGA== - [1679562607.575866][126855:126857] CHIP:DMG: } - [1679562607.575872][126855:126857] CHIP:DMG: - [1679562607.575878][126855:126857] CHIP:DMG: ICACValue (231) = - [1679562607.575893][126855:126857] CHIP:DMG: { - FTABAQEkAgE3AyQUARgmBIAigScmBYAlTTo3BiQTAhgkBwEkCAEwCUEE9/MhX0otpexJN0+X1TLOLaojJWg4sd+DU6GaVBPRmauhGVxJSCocNTl86dugdU9BNSyZ4YKvzTFNi9ahXKwboDcKNQEpARgkAmAwBBSTcEvTAX3+cztsuvoZoqtHd61F3DAFFOA5rOqBb2KMCwcU5FTt/zF2IvMBGDALQEUmrbTN1Y4du9eHicbE5iKphxlrBRyscULxD/ZfaWyN38XuXZKOGdkGhfLL1tYLjhc7wVd9mLLl3RtNJEUDBtgY - [1679562607.575908][126855:126857] CHIP:DMG: } - [1679562607.575914][126855:126857] CHIP:DMG: - [1679562607.575930][126855:126857] CHIP:DMG: InvokeRequestMessage = - [1679562607.575937][126855:126857] CHIP:DMG: { - [1679562607.575944][126855:126857] CHIP:DMG: suppressResponse = false, - [1679562607.575952][126855:126857] CHIP:DMG: timedRequest = false, - [1679562607.575958][126855:126857] CHIP:DMG: InvokeRequests = - [1679562607.575971][126855:126857] CHIP:DMG: [ - [1679562607.575978][126855:126857] CHIP:DMG: CommandDataIB = - [1679562607.575987][126855:126857] CHIP:DMG: { - [1679562607.575993][126855:126857] CHIP:DMG: CommandPathIB = - [1679562607.576002][126855:126857] CHIP:DMG: { - [1679562607.576011][126855:126857] CHIP:DMG: EndpointId = 0x0, - [1679562607.576020][126855:126857] CHIP:DMG: ClusterId = 0x3e, - [1679562607.576028][126855:126857] CHIP:DMG: CommandId = 0x6, - [1679562607.576039][126855:126857] CHIP:DMG: }, - [1679562607.576048][126855:126857] CHIP:DMG: - [1679562607.576055][126855:126857] CHIP:DMG: CommandFields = - [1679562607.576065][126855:126857] CHIP:DMG: { - [1679562607.576074][126855:126857] CHIP:DMG: 0x0 = [ - [1679562607.576127][126855:126857] CHIP:DMG: 0x15, 0x30, 0x1, 0x1, 0x1, 0x24, 0x2, 0x1, 0x37, 0x3, 0x24, 0x13, 0x1, 0x18, 0x26, 0x4, 0x80, 0x22, 0x81, 0x27, 0x26, 0x5, 0x80, 0x25, 0x4d, 0x3a, 0x37, 0x6, 0x24, 0x15, 0x1, 0x24, 0x11, 0x1, 0x18, 0x24, 0x7, 0x1, 0x24, 0x8, 0x1, 0x30, 0x9, 0x41, 0x4, 0x94, 0x5b, 0xb6, 0xd3, 0x14, 0x0, 0x45, 0x35, 0xf0, 0x64, 0x25, 0x7d, 0xb7, 0x8a, 0x56, 0x9d, 0x5, 0x0, 0x56, 0xec, 0xbc, 0xa9, 0xb5, 0xdc, 0xfa, 0xa4, 0x93, 0x28, 0x14, 0x1d, 0x7, 0x3a, 0xc9, 0x7d, 0x1c, 0x9d, 0x21, 0x56, 0xf4, 0xec, 0xc8, 0x7d, 0x3c, 0x87, 0x6f, 0x51, 0xa3, 0x65, 0x89, 0x92, 0x4d, 0xcf, 0xd9, 0x11, 0x71, 0xab, 0x4e, 0x99, 0xcb, 0x90, 0x72, 0xb5, 0x45, 0xa9, 0x37, 0xa, 0x35, 0x1, 0x28, 0x1, 0x18, 0x24, 0x2, 0x1, 0x36, 0x3, 0x4, 0x2, 0x4, 0x1, 0x18, 0x30, 0x4, 0x14, 0xf2, 0x2d, 0x91, 0xb, 0xf2, 0xb1, 0xce, 0xdb, 0x60, 0x10, 0x23, 0x97, 0x31, 0xfd, 0x43, 0xc4, 0x40, 0x46, 0x5a, 0x99, 0x30, 0x5, 0x14, 0xf9, 0x94, 0xad, 0x9e, 0x2b, 0x0, 0x6b, 0xa9, 0xc1, 0x27, 0x6d, 0x20, 0xcb, 0x27, 0xa4, 0xf1, 0x21, 0x2b, 0xc9, 0x8b, 0x18, 0x30, 0xb, 0x40, 0xa1, 0xd2, 0x49, 0x5c, 0xa, 0xc1, 0x58, 0x12, 0x71, 0xd, 0x1a, 0x37, 0xe4, 0x7b, 0x3d, 0xbd, 0x19, 0xe, 0xe8, 0x86, 0xa8, 0x49, 0x4, 0x8, 0x7b, 0x20, 0x94, 0xfa, 0x21, 0xe8, 0x5b, 0xbf, 0x58, 0xc, 0x7d, 0x93, 0x4b, 0x89, 0x88, 0x78, 0xeb, 0xf2, 0x9, 0xf9, 0x3e, 0x6, 0xf7, 0x85, 0xbe, 0xa2, 0xa1, 0xf, 0xc8, 0x40, 0x64, 0xd5, 0xdf, 0x97, 0x6f, 0xef, 0x2c, 0xad, 0xbc, 0xcc, 0x18, - [1679562607.576155][126855:126857] CHIP:DMG: ] (241 bytes) - disabled: true - - - label: "Step 3: Save TH1s Fabric ID as FabricID1" - verification: | - Refer the above step - disabled: true - - - label: - "Step 4: Commission DUT to TH2s Fabric When DUT sends NOC response - save FabricIndex as FabricIndex_TH2" - verification: | - To commission DUT to TH2 follow below procedure - - ./chip-tool pairing open-commissioning-window 1 1 400 2000 3841 - - Verify in TH1 Log: - - CHIP:IN: Sending encrypted msg 0xaaaad3464d10 with MessageCounter:0 to 0x0000000000000001 at monotonic time: 5805157 msec - [1635691999.946536][3822:3827] CHIP:DMG: ICR moving to [CommandSen] - [1635691999.946586][3822:3827] CHIP:CTL: Manual pairing code: [35407541839] - [1635691999.946650][3822:3827] CHIP:CTL: SetupQRCode: [MT:00000CQM00G6V851H10] - [1635691999.946802][3822:3827] CHIP:EM: Sending Standalone Ack for MessageCounter:3234931243 on exchange 35324i - [1635691999.946850][3822:3827] CHIP:IN: Prepared plaintext message 0xffffaa58a960 to 0x0000000000000000 of type 0x10 and protocolId (0, 0) on exchange 35324i with MessageCounter:1726016118. - [1635691999.946895][3822:3827] CHIP:IN: Sending plaintext msg 0xffffaa58a960 with MessageCounter:1726016118 to 0x0000000000000000 at monotonic time: 5805158 msec - [1635691999.946983][3822:3827] CHIP:EM: Flushed pending ack for MessageCounter:3234931243 on exchange 35324i - - 2. On 2nd controller, using chip-tool connect using manual code. - Below is the example when using chip tool as controller (considering 35998938564 as the manual code generated by 1st controller) - - - ./chip-tool pairing code 2 35407541839 --commissioner-name beta --trace_decode 1 - Verify whether you got below message in the log of TH - Device commissioning completed with success - - After commissioning DUT to TH2's fabric read nocs - - Save the the FabricIndex and NOC value during commissioning in TH2 Log - - - [1673249259.166158][1742:1744] CHIP:DIS: Keeping DNSSD lookup active - [1673249259.362947][1742:1744] CHIP:DIS: Checking node lookup status after 200 ms - [1673249259.363205][1742:1744] CHIP:DIS: OperationalSessionSetup[2:0000000000000002]: Updating device address to UDP:[fe80::e65f:1ff:fe0e:be37%eth0]:5540 while in state 2 - [1673249259.363267][1742:1744] CHIP:CTL: OperationalSessionSetup[2:0000000000000002]: State change 2 --> 3 - [1673249259.363467][1742:1744] CHIP:IN: SecureSession[0xffff98011400]: Allocated Type:2 LSID:60039 - [1673249259.363558][1742:1744] CHIP:SC: Initiating session on local FabricIndex 2 from 0x000000000001B669 -> 0x0000000000000002 - [1673249259.365555][1742:1744] CHIP:EM: <<< [E:13995i M:219921998] (U) Msg TX to 0:0000000000000000 [0000] --- Type 0000:30 (SecureChannel:CASE_Sigma1) - [1681213277.146543][2983:2985] CHIP:DMG: - [1681213277.146631][2983:2985] CHIP:DMG: NOCValue (241) = - [1681213277.146662][2983:2985] CHIP:DMG: { - FTABAQEkAgE3AyQTAhgmBIAigScmBYAlTTo3BiQVAiQRAhgkBwEkCAEwCUEEooiu0bizmyLUR9k8phgWrcsaLfWIrjF3MmJuMrM2rGsjl/k8nxqkNtfiVCPUbMfo+Z2vMByAa74UKVnvxz4a2DcKNQEoARgkAgE2AwQCBAEYMAQUmZjxv4X5S8T6+5BRACiWMwvb2hIwBRTzEAaDTxWHp9yNRa21A/LaQylK9BgwC0DyL4TkYg6tVc5DCXnE+ZXq6wRE1oCi72icy+9rcsptmfXdgWjew2uiEfQiJIQJdzM1mZN8OKLlJx8aY4CVsC/AGA== - [1681213277.146693][2983:2985] CHIP:DMG: } - [1681213277.146708][2983:2985] CHIP:DMG: - [1681213277.146725][2983:2985] CHIP:DMG: ICACValue (231) = - [1681213277.146748][2983:2985] CHIP:DMG: { - FTABAQEkAgE3AyQUARgmBIAigScmBYAlTTo3BiQTAhgkBwEkCAEwCUEEjjgt8C2SvzhTjCUn3polJfTxEfZhJ5Dg7B24NEfypWrVKu3MsEmx4eHexmohFV9+Najv+bp7ns53w6vakJqo7TcKNQEpARgkAmAwBBTzEAaDTxWHp9yNRa21A/LaQylK9DAFFJg1jJGztPg2TbeXsehGcGT67Ry2GDALQEZnfw7LkGjbDUPw8p0OReBz4hQAuVmQ7myxWcX0LPxsKm4lV0TC9bXnwmrQ8rMz0uY/gxdXfbWdd87SPbp2698Y - [1681213277.146780][2983:2985] CHIP:DMG: } - [1681213277.146795][2983:2985] CHIP:DMG: - [1681213277.146826][2983:2985] CHIP:DMG: InvokeRequestMessage = - [1681213277.146844][2983:2985] CHIP:DMG: { - [1681213277.146862][2983:2985] CHIP:DMG: suppressResponse = false, - [1681213277.146883][2983:2985] CHIP:DMG: timedRequest = false, - [1681213277.146902][2983:2985] CHIP:DMG: InvokeRequests = - [1681213277.146928][2983:2985] CHIP:DMG: [ - [1681213277.146947][2983:2985] CHIP:DMG: CommandDataIB = - [1681213277.146970][2983:2985] CHIP:DMG: { - [1681213277.146990][2983:2985] CHIP:DMG: CommandPathIB = - [1681213277.147013][2983:2985] CHIP:DMG: { - [1681213277.147037][2983:2985] CHIP:DMG: EndpointId = 0x0, - [1681213277.147063][2983:2985] CHIP:DMG: ClusterId = 0x3e, - [1681213277.147088][2983:2985] CHIP:DMG: CommandId = 0x6, - [1681213277.147111][2983:2985] CHIP:DMG: }, - [1681213277.147136][2983:2985] CHIP:DMG: - [1681213277.147156][2983:2985] CHIP:DMG: CommandFields = - [1681213277.147179][2983:2985] CHIP:DMG: { - [1681213277.147204][2983:2985] CHIP:DMG: 0x0 = [ - [1681213277.147296][2983:2985] CHIP:DMG: 0x15, 0x30, 0x01, 0x01, 0x01, 0x24, 0x02, 0x01, 0x37, 0x03, 0x24, 0x13, 0x02, 0x18, 0x26, 0x04, 0x80, 0x22, 0x81, 0x27, 0x26, 0x05, 0x80, 0x25, 0x4d, 0x3a, 0x37, 0x06, 0x24, 0x15, 0x02, 0x24, 0x11, 0x02, 0x18, 0x24, 0x07, 0x01, 0x24, 0x08, 0x01, 0x30, 0x09, 0x41, 0x04, 0xa2, 0x88, 0xae, 0xd1, 0xb8, 0xb3, 0x9b, 0x22, 0xd4, 0x47, 0xd9, 0x3c, 0xa6, 0x18, 0x16, 0xad, 0xcb, 0x1a, 0x2d, 0xf5, 0x88, 0xae, 0x31, 0x77, 0x32, 0x62, 0x6e, 0x32, 0xb3, 0x36, 0xac, 0x6b, 0x23, 0x97, 0xf9, 0x3c, 0x9f, 0x1a, 0xa4, 0x36, 0xd7, 0xe2, 0x54, 0x23, 0xd4, 0x6c, 0xc7, 0xe8, 0xf9, 0x9d, 0xaf, 0x30, 0x1c, 0x80, 0x6b, 0xbe, 0x14, 0x29, 0x59, 0xef, 0xc7, 0x3e, 0x1a, 0xd8, 0x37, 0x0a, 0x35, 0x01, 0x28, 0x01, 0x18, 0x24, 0x02, 0x01, 0x36, 0x03, 0x04, 0x02, 0x04, 0x01, 0x18, 0x30, 0x04, 0x14, 0x99, 0x98, 0xf1, 0xbf, 0x85, 0xf9, 0x4b, 0xc4, 0xfa, 0xfb, 0x90, 0x51, 0x00, 0x28, 0x96, 0x33, 0x0b, 0xdb, 0xda, 0x12, 0x30, 0x05, 0x14, 0xf3, 0x10, 0x06, 0x83, 0x4f, 0x15, 0x87, 0xa7, 0xdc, 0x8d, 0x45, 0xad, 0xb5, 0x03, 0xf2, 0xda, 0x43, 0x29, 0x4a, 0xf4, 0x18, 0x30, 0x0b, 0x40, 0xf2, 0x2f, 0x84, 0xe4, 0x62, 0x0e, 0xad, 0x55, 0xce, 0x43, 0x09, 0x79, 0xc4, 0xf9, 0x95, 0xea, 0xeb, 0x04, 0x44, 0xd6, 0x80, 0xa2, 0xef, 0x68, 0x9c, 0xcb, 0xef, 0x6b, 0x72, 0xca, 0x6d, 0x99, 0xf5, 0xdd, 0x81, 0x68, 0xde, 0xc3, 0x6b, 0xa2, 0x11, 0xf4, 0x22, 0x24, 0x84, 0x09, 0x77, 0x33, 0x35, 0x99, 0x93, 0x7c, 0x38, 0xa2, 0xe5, 0x27, 0x1f, 0x1a, 0x63, 0x80, 0x95, 0xb0, 0x2f, 0xc0, 0x18, - [1681213277.147347][2983:2985] CHIP:DMG: ] (241 bytes) - disabled: true - - - label: "Step 5: Save TH2s Fabric ID as FabricID2" - verification: | - Refer the above step - disabled: true - - - label: "Step 6: From TH1 read the CurrentFabricIndex" - verification: | - ./chip-tool operationalcredentials read current-fabric-index 1 0 - - Verify the current fabric index in TH1 Log - - CHIP:TOO: Endpoint: 0 Cluster: 0x0000_003E Attribute 0x0000_0005 DataVersion: 2445178920 - CHIP:TOO: CurrentFabricIndex: 1 - CHIP:EM: Sending Standalone Ack for MessageCounter:7141893 on exchange 26909i - disabled: true - - - label: "Step 7: Verify that CurrentFabricIndex = FabricIndex_TH1" - verification: | - Verify that CurrentFabricIndex = FabricIndex_TH1 - disabled: true - - - label: - "Step 8: From TH1 read the entire NOCs List attribute with a - non-fabric-filtered read" - verification: | - ./chip-tool operationalcredentials read nocs 1 0 - - Verify the NOCs List in TH1 Log - - [1658819541.245848][8318:8323] CHIP:TOO: Endpoint: 0 Cluster: 0x0000_003E Attribute 0x0000_0000 DataVersion: 2645922631 - [1658819541.245960][8318:8323] CHIP:TOO: NOCs: 1 entries - [1658819541.246062][8318:8323] CHIP:TOO: [1]: { - [1658819541.246104][8318:8323] CHIP:TOO: Noc: 1530010101240201370324130118260480228127260580254D3A37062415012411011824070124080130094104945BB6D314004535F064257DB78A569D050056ECBCA9B5DCFAA49328141D073AC97D1C9D2156F4ECC87D3C876F51A36589924DCFD91171AB4E99CB9072B545A9370A350128011824020136030402040118300414F22D910BF2B1CEDB6010239731FD43C440465A99300514F994AD9E2B006BA9C1276D20CB27A4F1212BC98B18300B40A1D2495C0AC15812710D1A37E47B3DBD190EE886A84904087B2094FA21E85BBF580C7D934B898878EBF209F93E06F785BEA2A10FC84064D5DF976FEF2CADBCCC18 - [1658819541.246163][8318:8323] CHIP:TOO: Icac: 1530010100240201370324140018260480228127260580254D3A370624130118240701240801300941045C9D561F53AAB6D9473DF2EE5170B03332BC38EF461842C37954CE99ADC4D55B272B3E545BB9FB2440CB712BA70BDDE27A318BEE1348D5F8C2D2C98CDBAD63C9370A3501290118240260300414F994AD9E2B006BA9C1276D20CB27A4F1212BC98B3005149040FBAF6F57D4E32188CD360DD4959272745D7618300B40C5EFCC41A18A4FAD6B1DAE6B12675D0C3FF1690728C31D1E95629511F23A4336DB5392E1FEF05EF1BA1DA46080A29BAB60EC613DEF031E2ED9850BB2E3B48B1118 - [1658819541.246198][8318:8323] CHIP:TOO: FabricIndex: 1 - [1658819541.246224][8318:8323] CHIP:TOO: } - disabled: true - - - label: - "Step 9: Verify that there is only data for the entry whose - FabricIndex field is equal to FabricIndex_TH1" - verification: | - Verify that Noc"s list has only data for FabricIndex_TH1 - - [1658819541.245848][8318:8323] CHIP:TOO: Endpoint: 0 Cluster: 0x0000_003E Attribute 0x0000_0000 DataVersion: 2645922631 - [1658819541.245960][8318:8323] CHIP:TOO: NOCs: 1 entries - [1658819541.246062][8318:8323] CHIP:TOO: [1]: { - [1658819541.246104][8318:8323] CHIP:TOO: Noc: 1530010101240201370324130118260480228127260580254D3A37062415012411011824070124080130094104945BB6D314004535F064257DB78A569D050056ECBCA9B5DCFAA49328141D073AC97D1C9D2156F4ECC87D3C876F51A36589924DCFD91171AB4E99CB9072B545A9370A350128011824020136030402040118300414F22D910BF2B1CEDB6010239731FD43C440465A99300514F994AD9E2B006BA9C1276D20CB27A4F1212BC98B18300B40A1D2495C0AC15812710D1A37E47B3DBD190EE886A84904087B2094FA21E85BBF580C7D934B898878EBF209F93E06F785BEA2A10FC84064D5DF976FEF2CADBCCC18 - [1658819541.246163][8318:8323] CHIP:TOO: Icac: 1530010100240201370324140018260480228127260580254D3A370624130118240701240801300941045C9D561F53AAB6D9473DF2EE5170B03332BC38EF461842C37954CE99ADC4D55B272B3E545BB9FB2440CB712BA70BDDE27A318BEE1348D5F8C2D2C98CDBAD63C9370A3501290118240260300414F994AD9E2B006BA9C1276D20CB27A4F1212BC98B3005149040FBAF6F57D4E32188CD360DD4959272745D7618300B40C5EFCC41A18A4FAD6B1DAE6B12675D0C3FF1690728C31D1E95629511F23A4336DB5392E1FEF05EF1BA1DA46080A29BAB60EC613DEF031E2ED9850BB2E3B48B1118 - [1658819541.246198][8318:8323] CHIP:TOO: FabricIndex: 1 - [1658819541.246224][8318:8323] CHIP:TOO: } - disabled: true - - - label: - "Step 10: From TH1 read the entire NOCs List attribute with a - fabric-filtered read" - verification: | - ./chip-tool operationalcredentials read nocs 1 0 --fabric-filtered 1 - - Verify the NOCs List in TH1 Log - - [1658819590.504973][8327:8332] CHIP:TOO: Endpoint: 0 Cluster: 0x0000_003E Attribute 0x0000_0000 DataVersion: 2645922631 - [1658819590.505058][8327:8332] CHIP:TOO: NOCs: 1 entries - [1658819590.505131][8327:8332] CHIP:TOO: [1]: { - [1658819590.505173][8327:8332] CHIP:TOO: Noc: 1530010101240201370324130118260480228127260580254D3A37062415012411011824070124080130094104945BB6D314004535F064257DB78A569D050056ECBCA9B5DCFAA49328141D073AC97D1C9D2156F4ECC87D3C876F51A36589924DCFD91171AB4E99CB9072B545A9370A350128011824020136030402040118300414F22D910BF2B1CEDB6010239731FD43C440465A99300514F994AD9E2B006BA9C1276D20CB27A4F1212BC98B18300B40A1D2495C0AC15812710D1A37E47B3DBD190EE886A84904087B2094FA21E85BBF580C7D934B898878EBF209F93E06F785BEA2A10FC84064D5DF976FEF2CADBCCC18 - [1658819590.505232][8327:8332] CHIP:TOO: Icac: 1530010100240201370324140018260480228127260580254D3A370624130118240701240801300941045C9D561F53AAB6D9473DF2EE5170B03332BC38EF461842C37954CE99ADC4D55B272B3E545BB9FB2440CB712BA70BDDE27A318BEE1348D5F8C2D2C98CDBAD63C9370A3501290118240260300414F994AD9E2B006BA9C1276D20CB27A4F1212BC98B3005149040FBAF6F57D4E32188CD360DD4959272745D7618300B40C5EFCC41A18A4FAD6B1DAE6B12675D0C3FF1690728C31D1E95629511F23A4336DB5392E1FEF05EF1BA1DA46080A29BAB60EC613DEF031E2ED9850BB2E3B48B1118 - [1658819590.505266][8327:8332] CHIP:TOO: FabricIndex: 1 - [1658819590.505292][8327:8332] CHIP:TOO: } - disabled: true - - - label: - "Step 11: Verify that there is only data for the entry whose - FabricIndex field is equal to FabricIndex_TH1" - verification: | - Verify that Noc"s list has only data for FabricIndex_TH1 - - [1658819590.504973][8327:8332] CHIP:TOO: Endpoint: 0 Cluster: 0x0000_003E Attribute 0x0000_0000 DataVersion: 2645922631 - [1658819590.505058][8327:8332] CHIP:TOO: NOCs: 1 entries - [1658819590.505131][8327:8332] CHIP:TOO: [1]: { - [1658819590.505173][8327:8332] CHIP:TOO: Noc: 1530010101240201370324130118260480228127260580254D3A37062415012411011824070124080130094104945BB6D314004535F064257DB78A569D050056ECBCA9B5DCFAA49328141D073AC97D1C9D2156F4ECC87D3C876F51A36589924DCFD91171AB4E99CB9072B545A9370A350128011824020136030402040118300414F22D910BF2B1CEDB6010239731FD43C440465A99300514F994AD9E2B006BA9C1276D20CB27A4F1212BC98B18300B40A1D2495C0AC15812710D1A37E47B3DBD190EE886A84904087B2094FA21E85BBF580C7D934B898878EBF209F93E06F785BEA2A10FC84064D5DF976FEF2CADBCCC18 - [1658819590.505232][8327:8332] CHIP:TOO: Icac: 1530010100240201370324140018260480228127260580254D3A370624130118240701240801300941045C9D561F53AAB6D9473DF2EE5170B03332BC38EF461842C37954CE99ADC4D55B272B3E545BB9FB2440CB712BA70BDDE27A318BEE1348D5F8C2D2C98CDBAD63C9370A3501290118240260300414F994AD9E2B006BA9C1276D20CB27A4F1212BC98B3005149040FBAF6F57D4E32188CD360DD4959272745D7618300B40C5EFCC41A18A4FAD6B1DAE6B12675D0C3FF1690728C31D1E95629511F23A4336DB5392E1FEF05EF1BA1DA46080A29BAB60EC613DEF031E2ED9850BB2E3B48B1118 - [1658819590.505266][8327:8332] CHIP:TOO: FabricIndex: 1 - [1658819590.505292][8327:8332] CHIP:TOO: } - disabled: true - - - label: "Step 12: Read NOCStruct values from entry at index 0" - verification: | - ./chip-tool operationalcredentials read nocs 1 0 --fabric-filtered 1 - - Verify FabricIndex field equal to FabricIndex_TH1 in TH1 Log - - [1658819590.504973][8327:8332] CHIP:TOO: Endpoint: 0 Cluster: 0x0000_003E Attribute 0x0000_0000 DataVersion: 2645922631 - [1658819590.505058][8327:8332] CHIP:TOO: NOCs: 1 entries - [1658819590.505131][8327:8332] CHIP:TOO: [1]: { - [1658819590.505173][8327:8332] CHIP:TOO: Noc: 1530010101240201370324130118260480228127260580254D3A37062415012411011824070124080130094104945BB6D314004535F064257DB78A569D050056ECBCA9B5DCFAA49328141D073AC97D1C9D2156F4ECC87D3C876F51A36589924DCFD91171AB4E99CB9072B545A9370A350128011824020136030402040118300414F22D910BF2B1CEDB6010239731FD43C440465A99300514F994AD9E2B006BA9C1276D20CB27A4F1212BC98B18300B40A1D2495C0AC15812710D1A37E47B3DBD190EE886A84904087B2094FA21E85BBF580C7D934B898878EBF209F93E06F785BEA2A10FC84064D5DF976FEF2CADBCCC18 - [1658819590.505232][8327:8332] CHIP:TOO: Icac: 1530010100240201370324140018260480228127260580254D3A370624130118240701240801300941045C9D561F53AAB6D9473DF2EE5170B03332BC38EF461842C37954CE99ADC4D55B272B3E545BB9FB2440CB712BA70BDDE27A318BEE1348D5F8C2D2C98CDBAD63C9370A3501290118240260300414F994AD9E2B006BA9C1276D20CB27A4F1212BC98B3005149040FBAF6F57D4E32188CD360DD4959272745D7618300B40C5EFCC41A18A4FAD6B1DAE6B12675D0C3FF1690728C31D1E95629511F23A4336DB5392E1FEF05EF1BA1DA46080A29BAB60EC613DEF031E2ED9850BB2E3B48B1118 - [1658819590.505266][8327:8332] CHIP:TOO: FabricIndex: 1 - [1658819590.505292][8327:8332] CHIP:TOO: } - disabled: true - - - label: - "Step 13: From the NOCStruct values verify the following: NOC matches - the NOC sent to the DUT during commissioning process ICAC matches the - ICAC sent to the DUT during commissioning process from AddNOC in - pre-condition" - verification: | - Verify NOC and ICAC value in step 12 and 2 matches - - NOC value of step 12 - Noc: 1530010101240201370324130118260480228127260580254D3A37062415012411011824070124080130094104945BB6D314004535F064257DB78A569D050056ECBCA9B5DCFAA49328141D073AC97D1C9D2156F4ECC87D3C876F51A36589924DCFD91171AB4E99CB9072B545A9370A350128011824020136030402040118300414F22D910BF2B1CEDB6010239731FD43C440465A99300514F994AD9E2B006BA9C1276D20CB27A4F1212BC98B18300B40A1D2495C0AC15812710D1A37E47B3DBD190EE886A84904087B2094FA21E85BBF580C7D934B898878EBF209F93E06F785BEA2A10FC84064D5DF976FEF2CADBCCC18 - - NOC value of Step 2 - - 0x15, 0x30, 0x1, 0x1, 0x1, 0x24, 0x2, 0x1, 0x37, 0x3, 0x24, 0x13, 0x1, 0x18, 0x26, 0x4, 0x80, 0x22, 0x81, 0x27, 0x26, 0x5, 0x80, 0x25, 0x4d, 0x3a, 0x37, 0x6, 0x24, 0x15, 0x1, 0x24, 0x11, 0x1, 0x18, 0x24, 0x7, 0x1, 0x24, 0x8, 0x1, 0x30, 0x9, 0x41, 0x4, 0x94, 0x5b, 0xb6, 0xd3, 0x14, 0x0, 0x45, 0x35, 0xf0, 0x64, 0x25, 0x7d, 0xb7, 0x8a, 0x56, 0x9d, 0x5, 0x0, 0x56, 0xec, 0xbc, 0xa9, 0xb5, 0xdc, 0xfa, 0xa4, 0x93, 0x28, 0x14, 0x1d, 0x7, 0x3a, 0xc9, 0x7d, 0x1c, 0x9d, 0x21, 0x56, 0xf4, 0xec, 0xc8, 0x7d, 0x3c, 0x87, 0x6f, 0x51, 0xa3, 0x65, 0x89, 0x92, 0x4d, 0xcf, 0xd9, 0x11, 0x71, 0xab, 0x4e, 0x99, 0xcb, 0x90, 0x72, 0xb5, 0x45, 0xa9, 0x37, 0xa, 0x35, 0x1, 0x28, 0x1, 0x18, 0x24, 0x2, 0x1, 0x36, 0x3, 0x4, 0x2, 0x4, 0x1, 0x18, 0x30, 0x4, 0x14, 0xf2, 0x2d, 0x91, 0xb, 0xf2, 0xb1, 0xce, 0xdb, 0x60, 0x10, 0x23, 0x97, 0x31, 0xfd, 0x43, 0xc4, 0x40, 0x46, 0x5a, 0x99, 0x30, 0x5, 0x14, 0xf9, 0x94, 0xad, 0x9e, 0x2b, 0x0, 0x6b, 0xa9, 0xc1, 0x27, 0x6d, 0x20, 0xcb, 0x27, 0xa4, 0xf1, 0x21, 0x2b, 0xc9, 0x8b, 0x18, 0x30, 0xb, 0x40, 0xa1, 0xd2, 0x49, 0x5c, 0xa, 0xc1, 0x58, 0x12, 0x71, 0xd, 0x1a, 0x37, 0xe4, 0x7b, 0x3d, 0xbd, 0x19, 0xe, 0xe8, 0x86, 0xa8, 0x49, 0x4, 0x8, 0x7b, 0x20, 0x94, 0xfa, 0x21, 0xe8, 0x5b, 0xbf, 0x58, 0xc, 0x7d, 0x93, 0x4b, 0x89, 0x88, 0x78, 0xeb, 0xf2, 0x9, 0xf9, 0x3e, 0x6, 0xf7, 0x85, 0xbe, 0xa2, 0xa1, 0xf, 0xc8, 0x40, 0x64, 0xd5, 0xdf, 0x97, 0x6f, 0xef, 0x2c, 0xad, 0xbc, 0xcc, 0x18, - disabled: true - - - label: - "Step 14: Read the Fabrics List and get the FabricDescriptorStruct for - the entry where FabricIndex = FabricIndex_TH1 from DUT" - verification: | - ./chip-tool operationalcredentials read fabrics 1 0 - - Verify FabricIndex = FabricIndex_TH1 in TH1 Log - - [1657693240.722099][15129:15134] CHIP:TOO: Endpoint: 0 Cluster: 0x0000_003E Attribute 0x0000_0001 DataVersion: 908345149 - [1657693240.722200][15129:15134] CHIP:TOO: Fabrics: 1 entries - [1657693240.722273][15129:15134] CHIP:TOO: [1]: { - [1657693240.722316][15129:15134] CHIP:TOO: RootPublicKey: 04038A93AE14428E9179C2ACC3BA1522D4D19BC20A3203BE97FEC0BE47EBC6CCCD4AD5F7B1CE0A02F85FF1B14216FAFCA034B3B312C16B0517267804D5B03582EF - [1657693240.722368][15129:15134] CHIP:TOO: VendorId: 65521 - [1657693240.722401][15129:15134] CHIP:TOO: FabricId: 1 - [1657693240.722431][15129:15134] CHIP:TOO: NodeId: 1 - [1657693240.722462][15129:15134] CHIP:TOO: Label: - [1657693240.722492][15129:15134] CHIP:TOO: FabricIndex: 1 - [1657693240.722522][15129:15134] CHIP:TOO: } - disabled: true - - - label: - "Step 15: Verify that TH1 is able to read the FabricDescriptorStruct - values Verify that Fabrics list does not have any entry as FabricID = - FabricID2" - verification: | - Verify the FabricDescriptorStruct values has no entry log FabricID2 on TH1 - - [1657693240.722099][15129:15134] CHIP:TOO: Endpoint: 0 Cluster: 0x0000_003E Attribute 0x0000_0001 DataVersion: 908345149 - [1657693240.722200][15129:15134] CHIP:TOO: Fabrics: 1 entries - [1657693240.722273][15129:15134] CHIP:TOO: [1]: { - [1657693240.722316][15129:15134] CHIP:TOO: RootPublicKey: 04038A93AE14428E9179C2ACC3BA1522D4D19BC20A3203BE97FEC0BE47EBC6CCCD4AD5F7B1CE0A02F85FF1B14216FAFCA034B3B312C16B0517267804D5B03582EF - [1657693240.722368][15129:15134] CHIP:TOO: VendorId: 65521 - [1657693240.722401][15129:15134] CHIP:TOO: FabricId: 1 - [1657693240.722431][15129:15134] CHIP:TOO: NodeId: 1 - [1657693240.722462][15129:15134] CHIP:TOO: Label: - [1657693240.722492][15129:15134] CHIP:TOO: FabricIndex: 1 - [1657693240.722522][15129:15134] CHIP:TOO: } - disabled: true - - - label: "Step 16: From TH2 read the CurrentFabricIndex" - verification: | - ./chip-tool operationalcredentials read current-fabric-index 2 0 --commissioner-name beta - - Verify current fabric index in TH2 Log - - CHIP:TOO: Endpoint: 0 Cluster: 0x0000_003E Attribute 0x0000_0005 DataVersion: 2445178920 - CHIP:TOO: CurrentFabricIndex: 2 - CHIP:EM: Sending Standalone Ack for MessageCounter:8900122 on exchange 26519i - disabled: true - - - label: "Step 17: Verify that CurrentFabricIndex = FabricIndex_TH2" - verification: | - Verify that CurrentFabricIndex = FabricIndex_TH2 - disabled: true - - - label: - "Step 18: From TH2 read the entire NOCs List attribute with a - non-fabric-filtered read" - verification: | - ./chip-tool operationalcredentials read nocs 2 0 --commissioner-name beta - - - Verify the NOCs List in TH2 Log - - [1658819643.546022][8397:8402] CHIP:TOO: Endpoint: 0 Cluster: 0x0000_003E Attribute 0x0000_0000 DataVersion: 2645922631 - [1658819643.546148][8397:8402] CHIP:TOO: NOCs: 1 entries - [1658819643.546258][8397:8402] CHIP:TOO: [1]: { - [1658819643.546307][8397:8402] CHIP:TOO: Noc: 1530010101240201370324130118260480228127260580254D3A37062415012411021824070124080130094104FF8D28DB36902F674F4BF312985CDEA52231E0B3C4795E54E3EFC0D6DE9AED140DEF653EDE9160B10BF446D6E2FAC5DBD38BF85597E095136A209F0990E54394370A3501280118240201360304020401183004144F0F08EA1F5414C324914019EB74CA31C9819AC6300514FF5D080583B5B132C45F800B8D2E184E7D599F5118300B40D434A0D9DA1C7D61784D8BCBEE3E7179A4818499442DD23919A81933C0170673FF33D0E8654312388EE717161DF5E1B6E14402380602B873D551174B2BA0D8E718 - [1658819643.546407][8397:8402] CHIP:TOO: Icac: 1530010100240201370324140018260480228127260580254D3A37062413011824070124080130094104A58C57E9D8919152DE03DAC991155D750A5D8C93093D75E166E1C5CF86381EA926E108BFE78DAD9FFFB4363A706DA88B9F3B8EF5D80F428F44EAE26472C81B47370A3501290118240260300414FF5D080583B5B132C45F800B8D2E184E7D599F513005143036AAD3B8EDBF6075364A85A96F9A0583EEC49718300B4014BEAF33C7B547857AC36A17AD1CDD4D90D7045889C5B576CA644C78F021B6C21498EDDC43730AFEAD6AF5A945728D1C4F7DF7EE37C313D5AE27E78F0509DB9918 - [1658819643.546447][8397:8402] CHIP:TOO: FabricIndex: 2 - [1658819643.546478][8397:8402] CHIP:TOO: } - disabled: true - - - label: - "Step 19: Verify that there is only data for the entry whose - FabricIndex field is equal to FabricIndex_TH2" - verification: | - ./chip-tool operationalcredentials read current-fabric-index 2 0 --commissioner-name beta - - Verify current fabric index in TH2 Log - - CHIP:TOO: Endpoint: 0 Cluster: 0x0000_003E Attribute 0x0000_0005 DataVersion: 2445178920 - CHIP:TOO: CurrentFabricIndex: 2 - CHIP:EM: Sending Standalone Ack for MessageCounter:8900122 on exchange 26519i - disabled: true - - - label: - "Step 20: From TH2 read the entire NOCs List attribute with a - fabric-filtered read" - verification: | - ./chip-tool operationalcredentials read nocs 2 0 --fabric-filtered 1 --commissioner-name beta - - - Verify the NOCs List in TH2 Log - - [1658819643.546022][8397:8402] CHIP:TOO: Endpoint: 0 Cluster: 0x0000_003E Attribute 0x0000_0000 DataVersion: 2645922631 - [1658819643.546148][8397:8402] CHIP:TOO: NOCs: 1 entries - [1658819643.546258][8397:8402] CHIP:TOO: [1]: { - [1658819643.546307][8397:8402] CHIP:TOO: Noc: 1530010101240201370324130118260480228127260580254D3A37062415012411021824070124080130094104FF8D28DB36902F674F4BF312985CDEA52231E0B3C4795E54E3EFC0D6DE9AED140DEF653EDE9160B10BF446D6E2FAC5DBD38BF85597E095136A209F0990E54394370A3501280118240201360304020401183004144F0F08EA1F5414C324914019EB74CA31C9819AC6300514FF5D080583B5B132C45F800B8D2E184E7D599F5118300B40D434A0D9DA1C7D61784D8BCBEE3E7179A4818499442DD23919A81933C0170673FF33D0E8654312388EE717161DF5E1B6E14402380602B873D551174B2BA0D8E718 - [1658819643.546407][8397:8402] CHIP:TOO: Icac: 1530010100240201370324140018260480228127260580254D3A37062413011824070124080130094104A58C57E9D8919152DE03DAC991155D750A5D8C93093D75E166E1C5CF86381EA926E108BFE78DAD9FFFB4363A706DA88B9F3B8EF5D80F428F44EAE26472C81B47370A3501290118240260300414FF5D080583B5B132C45F800B8D2E184E7D599F513005143036AAD3B8EDBF6075364A85A96F9A0583EEC49718300B4014BEAF33C7B547857AC36A17AD1CDD4D90D7045889C5B576CA644C78F021B6C21498EDDC43730AFEAD6AF5A945728D1C4F7DF7EE37C313D5AE27E78F0509DB9918 - [1658819643.546447][8397:8402] CHIP:TOO: FabricIndex: 2 - [1658819643.546478][8397:8402] CHIP:TOO: } - disabled: true - - - label: - "Step 21: Verify that there is only data for the entry whose - FabricIndex field is equal to FabricIndex_TH2" - verification: | - Verify that Noc"s list has only data for FabricIndex_TH2 - - [1658819643.546022][8397:8402] CHIP:TOO: Endpoint: 0 Cluster: 0x0000_003E Attribute 0x0000_0000 DataVersion: 2645922631 - [1658819643.546148][8397:8402] CHIP:TOO: NOCs: 1 entries - [1658819643.546258][8397:8402] CHIP:TOO: [1]: { - [1658819643.546307][8397:8402] CHIP:TOO: Noc: 1530010101240201370324130118260480228127260580254D3A37062415012411021824070124080130094104FF8D28DB36902F674F4BF312985CDEA52231E0B3C4795E54E3EFC0D6DE9AED140DEF653EDE9160B10BF446D6E2FAC5DBD38BF85597E095136A209F0990E54394370A3501280118240201360304020401183004144F0F08EA1F5414C324914019EB74CA31C9819AC6300514FF5D080583B5B132C45F800B8D2E184E7D599F5118300B40D434A0D9DA1C7D61784D8BCBEE3E7179A4818499442DD23919A81933C0170673FF33D0E8654312388EE717161DF5E1B6E14402380602B873D551174B2BA0D8E718 - [1658819643.546407][8397:8402] CHIP:TOO: Icac: 1530010100240201370324140018260480228127260580254D3A37062413011824070124080130094104A58C57E9D8919152DE03DAC991155D750A5D8C93093D75E166E1C5CF86381EA926E108BFE78DAD9FFFB4363A706DA88B9F3B8EF5D80F428F44EAE26472C81B47370A3501290118240260300414FF5D080583B5B132C45F800B8D2E184E7D599F513005143036AAD3B8EDBF6075364A85A96F9A0583EEC49718300B4014BEAF33C7B547857AC36A17AD1CDD4D90D7045889C5B576CA644C78F021B6C21498EDDC43730AFEAD6AF5A945728D1C4F7DF7EE37C313D5AE27E78F0509DB9918 - [1658819643.546447][8397:8402] CHIP:TOO: FabricIndex: 2 - [1658819643.546478][8397:8402] CHIP:TOO: } - disabled: true - - - label: "Step 22: Read NOCStruct values from entry at index 1" - verification: | - ./chip-tool operationalcredentials read nocs 2 0 --commissioner-name beta - - Verify FabricIndex = FabricIndex_TH2 in TH2 Log - - [1658819643.546022][8397:8402] CHIP:TOO: Endpoint: 0 Cluster: 0x0000_003E Attribute 0x0000_0000 DataVersion: 2645922631 - [1658819643.546148][8397:8402] CHIP:TOO: NOCs: 1 entries - [1658819643.546258][8397:8402] CHIP:TOO: [1]: { - [1658819643.546307][8397:8402] CHIP:TOO: Noc: 1530010101240201370324130118260480228127260580254D3A37062415012411021824070124080130094104FF8D28DB36902F674F4BF312985CDEA52231E0B3C4795E54E3EFC0D6DE9AED140DEF653EDE9160B10BF446D6E2FAC5DBD38BF85597E095136A209F0990E54394370A3501280118240201360304020401183004144F0F08EA1F5414C324914019EB74CA31C9819AC6300514FF5D080583B5B132C45F800B8D2E184E7D599F5118300B40D434A0D9DA1C7D61784D8BCBEE3E7179A4818499442DD23919A81933C0170673FF33D0E8654312388EE717161DF5E1B6E14402380602B873D551174B2BA0D8E718 - [1658819643.546407][8397:8402] CHIP:TOO: Icac: 1530010100240201370324140018260480228127260580254D3A37062413011824070124080130094104A58C57E9D8919152DE03DAC991155D750A5D8C93093D75E166E1C5CF86381EA926E108BFE78DAD9FFFB4363A706DA88B9F3B8EF5D80F428F44EAE26472C81B47370A3501290118240260300414FF5D080583B5B132C45F800B8D2E184E7D599F513005143036AAD3B8EDBF6075364A85A96F9A0583EEC49718300B4014BEAF33C7B547857AC36A17AD1CDD4D90D7045889C5B576CA644C78F021B6C21498EDDC43730AFEAD6AF5A945728D1C4F7DF7EE37C313D5AE27E78F0509DB9918 - [1658819643.546447][8397:8402] CHIP:TOO: FabricIndex: 2 - [1658819643.546478][8397:8402] CHIP:TOO: } - disabled: true - - - label: - "Step 23: From the NOCStruct values verify the following: NOC matches - the NOC sent to the DUT during commissioning process ICAC matches the - ICAC sent to the DUT during commissioning process from AddNOC in - pre-condition" - verification: | - Verify the value of NOC and ICAC are same in step 22 and 4 are same - - Step 22 Log: - Noc: 1530010101240201370324130118260480228127260580254D3A37062415012411021824070124080130094104FF8D28DB36902F674F4BF312985CDEA52231E0B3C4795E54E3EFC0D6DE9AED140DEF653EDE9160B10BF446D6E2FAC5DBD38BF85597E095136A209F0990E54394370A3501280118240201360304020401183004144F0F08EA1F5414C324914019EB74CA31C9819AC6300514FF5D080583B5B132C45F800B8D2E184E7D599F5118300B40D434A0D9DA1C7D61784D8BCBEE3E7179A4818499442DD23919A81933C0170673FF33D0E8654312388EE717161DF5E1B6E14402380602B873D551174B2BA0D8E718 - - Step 4 Log - 0x15, 0x30, 0x1, 0x1, 0x1, 0x24, 0x2, 0x1, 0x37, 0x3, 0x24, 0x13, 0x1, 0x18, 0x26, 0x4, 0x80, 0x22, 0x81, 0x27, 0x26, 0x5, 0x80, 0x25, 0x4d, 0x3a, 0x37, 0x6, 0x24, 0x15, 0x1, 0x24, 0x11, 0x2, 0x18, 0x24, 0x7, 0x1, 0x24, 0x8, 0x1, 0x30, 0x9, 0x41, 0x4, 0xff, 0x8d, 0x28, 0xdb, 0x36, 0x90, 0x2f, 0x67, 0x4f, 0x4b, 0xf3, 0x12, 0x98, 0x5c, 0xde, 0xa5, 0x22, 0x31, 0xe0, 0xb3, 0xc4, 0x79, 0x5e, 0x54, 0xe3, 0xef, 0xc0, 0xd6, 0xde, 0x9a, 0xed, 0x14, 0xd, 0xef, 0x65, 0x3e, 0xde, 0x91, 0x60, 0xb1, 0xb, 0xf4, 0x46, 0xd6, 0xe2, 0xfa, 0xc5, 0xdb, 0xd3, 0x8b, 0xf8, 0x55, 0x97, 0xe0, 0x95, 0x13, 0x6a, 0x20, 0x9f, 0x9, 0x90, 0xe5, 0x43, 0x94, 0x37, 0xa, 0x35, 0x1, 0x28, 0x1, 0x18, 0x24, 0x2, 0x1, 0x36, 0x3, 0x4, 0x2, 0x4, 0x1, 0x18, 0x30, 0x4, 0x14, 0x4f, 0xf, 0x8, 0xea, 0x1f, 0x54, 0x14, 0xc3, 0x24, 0x91, 0x40, 0x19, 0xeb, 0x74, 0xca, 0x31, 0xc9, 0x81, 0x9a, 0xc6, 0x30, 0x5, 0x14, 0xff, 0x5d, 0x8, 0x5, 0x83, 0xb5, 0xb1, 0x32, 0xc4, 0x5f, 0x80, 0xb, 0x8d, 0x2e, 0x18, 0x4e, 0x7d, 0x59, 0x9f, 0x51, 0x18, 0x30, 0xb, 0x40, 0xd4, 0x34, 0xa0, 0xd9, 0xda, 0x1c, 0x7d, 0x61, 0x78, 0x4d, 0x8b, 0xcb, 0xee, 0x3e, 0x71, 0x79, 0xa4, 0x81, 0x84, 0x99, 0x44, 0x2d, 0xd2, 0x39, 0x19, 0xa8, 0x19, 0x33, 0xc0, 0x17, 0x6, 0x73, 0xff, 0x33, 0xd0, 0xe8, 0x65, 0x43, 0x12, 0x38, 0x8e, 0xe7, 0x17, 0x16, 0x1d, 0xf5, 0xe1, 0xb6, 0xe1, 0x44, 0x2, 0x38, 0x6, 0x2, 0xb8, 0x73, 0xd5, 0x51, 0x17, 0x4b, 0x2b, 0xa0, 0xd8, 0xe7, 0x18, - disabled: true diff --git a/src/app/tests/suites/manualTests.json b/src/app/tests/suites/manualTests.json index 01d98213b3e279..5f7aa99f9b2952 100644 --- a/src/app/tests/suites/manualTests.json +++ b/src/app/tests/suites/manualTests.json @@ -82,7 +82,6 @@ "DeviceManagement": [ "Test_TC_BINFO_3_1", "Test_TC_OPCREDS_3_1", - "Test_TC_OPCREDS_3_2", "Test_TC_OPCREDS_3_3", "Test_TC_OPCREDS_3_4", "Test_TC_OPCREDS_3_5", From 6ee19136455da56d1f37f6ce4827f74e9cdcd273 Mon Sep 17 00:00:00 2001 From: arun-silabs <141724790+arun-silabs@users.noreply.github.com> Date: Fri, 25 Oct 2024 01:11:56 +0530 Subject: [PATCH 111/149] [Silabs] Fix for thermostat app hang issue on 917SoC (#35721) * Add ScheduleWork by removing LockChipStack and UnlockChipStack in SensorTimerEventHandler. * Restyled by clang-format * Modified the API name as suggested. * Posting SensorTimerEventHandler as an event to AppTask. --------- Co-authored-by: Restyled.io --- examples/thermostat/silabs/include/SensorManager.h | 3 ++- examples/thermostat/silabs/src/SensorManager.cpp | 9 +++++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/examples/thermostat/silabs/include/SensorManager.h b/examples/thermostat/silabs/include/SensorManager.h index 03b916de699d2b..8a88d775207fa1 100644 --- a/examples/thermostat/silabs/include/SensorManager.h +++ b/examples/thermostat/silabs/include/SensorManager.h @@ -37,8 +37,9 @@ class SensorManager osTimerId_t mSensorTimer; - // Reads new generated sensor value, stores it, and updates local temperature attribute static void SensorTimerEventHandler(void * arg); + // Reads new generated sensor value, stores it, and updates local temperature attribute + static void TemperatureUpdateEventHandler(AppEvent * aEvent); static SensorManager sSensorManager; }; diff --git a/examples/thermostat/silabs/src/SensorManager.cpp b/examples/thermostat/silabs/src/SensorManager.cpp index 3522e9f5a30d1d..e4186664c6f36e 100644 --- a/examples/thermostat/silabs/src/SensorManager.cpp +++ b/examples/thermostat/silabs/src/SensorManager.cpp @@ -78,6 +78,15 @@ CHIP_ERROR SensorManager::Init() } void SensorManager::SensorTimerEventHandler(void * arg) +{ + AppEvent event; + event.Type = AppEvent::kEventType_Timer; + event.Handler = TemperatureUpdateEventHandler; + + AppTask::GetAppTask().PostEvent(&event); +} + +void SensorManager::TemperatureUpdateEventHandler(AppEvent * aEvent) { int16_t temperature = 0; static int16_t lastTemperature = 0; From 019dcc7b8f21e952de99a0bbc3ef6e61537018be Mon Sep 17 00:00:00 2001 From: lpbeliveau-silabs <112982107+lpbeliveau-silabs@users.noreply.github.com> Date: Thu, 24 Oct 2024 16:29:48 -0400 Subject: [PATCH 112/149] Removed un-necessary check (#36234) --- .../dishwasher-app/silabs/src/ElectricalSensorManager.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/dishwasher-app/silabs/src/ElectricalSensorManager.cpp b/examples/dishwasher-app/silabs/src/ElectricalSensorManager.cpp index c751c71c268255..cf7e4806a7828a 100644 --- a/examples/dishwasher-app/silabs/src/ElectricalSensorManager.cpp +++ b/examples/dishwasher-app/silabs/src/ElectricalSensorManager.cpp @@ -196,12 +196,12 @@ void ElectricalSensorManager::UpdateEPMAttributes(OperationalStateEnum state) { if (gEPMDelegate) { - uint16_t updateState = to_underlying(state); - uint16_t ERROR_STATE_INDEX = ArraySize(kAttributes) - 1; + uint8_t updateState = to_underlying(state); + // Check state range - if ((updateState < 0) || (updateState > ERROR_STATE_INDEX)) + if (updateState >= ArraySize(kAttributes)) { - updateState = ERROR_STATE_INDEX; + updateState = ArraySize(kAttributes) - 1; } ChipLogDetail(AppServer, "UpdateAllAttributes to Operational State : %d", updateState); From 41b6830bced81976ecc8cd52c2889f448551055d Mon Sep 17 00:00:00 2001 From: lpbeliveau-silabs <112982107+lpbeliveau-silabs@users.noreply.github.com> Date: Thu, 24 Oct 2024 18:11:23 -0400 Subject: [PATCH 113/149] Fix missed discrepancy in TC_S_2_2 (#36235) --- src/app/tests/suites/certification/Test_TC_S_2_2.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/app/tests/suites/certification/Test_TC_S_2_2.yaml b/src/app/tests/suites/certification/Test_TC_S_2_2.yaml index 0d78bccbe64e05..abbc71a32afccc 100644 --- a/src/app/tests/suites/certification/Test_TC_S_2_2.yaml +++ b/src/app/tests/suites/certification/Test_TC_S_2_2.yaml @@ -874,7 +874,7 @@ tests: to 60 000 000 (60 000s) and a set of extension fields appropriate to AC1." verification: | - ./chip-tool scenesmanagement add-scene 0x0001 0x01 60000000 "scene name" '[{"clusterID": "0x0300", "attributeValueList":[{"attributeID": "0x4001", "ValueUnsigned8": "0x01"}]}]' 1 1 + ./chip-tool scenesmanagement add-scene 0x0001 0x01 60000000 "scene name" '[{"clusterID": "0x0300", "attributeValueList":[{"attributeID": "0x4000", "valueUnsigned16": "0x01"}]}]' 1 1 Verify DUT sends a AddSceneResponse command to TH with the Status field set to 0x00 (SUCCESS), the GroupID field set to G1 and the SceneID field set to 0x01 on the TH(Chip-tool) Log and below is the sample log provided for the raspi platform: From f1457a22845fb0c4414f8c89d0998a9041a4d58d Mon Sep 17 00:00:00 2001 From: Raul Marquez <130402456+raul-marquez-csa@users.noreply.github.com> Date: Fri, 25 Oct 2024 00:15:15 -0700 Subject: [PATCH 114/149] TC-OPCREDS-3.3 - Updates verification steps, removes pre-condition (#36211) * Updates verification steps, removes pre-condition * Fix restyle * Fix restyle * Fix restyle * Fix restyle * Restyled by prettier-yaml --------- Co-authored-by: Restyled.io --- .../certification/Test_TC_OPCREDS_3_3.yaml | 1448 +++++++---------- 1 file changed, 614 insertions(+), 834 deletions(-) diff --git a/src/app/tests/suites/certification/Test_TC_OPCREDS_3_3.yaml b/src/app/tests/suites/certification/Test_TC_OPCREDS_3_3.yaml index 8c6391cbd2aa14..7cd57ba2535c21 100644 --- a/src/app/tests/suites/certification/Test_TC_OPCREDS_3_3.yaml +++ b/src/app/tests/suites/certification/Test_TC_OPCREDS_3_3.yaml @@ -29,28 +29,22 @@ tests: Chip-tool command used below are an example to verify the DUT as client test cases. For certification test, we expect DUT should have a capability or way to run the equivalent command. disabled: true - - label: "Precondition" - verification: | - TH and DUT are commissioned - disabled: true - - label: "Step 1: Factory Reset TH (to ensure NOC list is empty at the beginning of the following steps)" verification: | - On Raspi factory reset with the below command. + On both DUT and TH side, on Raspi we do factory reset with the below command. The DUT for cert should follow vendor specific procedure for factory reset sudo rm -rf /tmp/chip_* disabled: true - label: "Step 2: Start the commissioning process of TH with DUT" verification: | On dut(chip-tool) side: - ./chip-tool pairing ble-wifi 1 GRLPrivate_EXT matter123 20202021 3840 --trace_decode 1 + ./chip-tool pairing ble-wifi 1 GRLPrivate_EXT matter123 20202021 3840 --trace_decode 1 [1641381202.376419][5628:5633] CHIP:CTL: Received success response 0x3df8 - On TH(all-clusters-app) - ./all-clusters-app --wifi + ./all-clusters-app --wifi --trace_decode 1 [1641381202.306840][4431:4431] CHIP:DL: NVS set: chip-config/regulatory-location = 0 (0x0) disabled: true @@ -58,210 +52,82 @@ tests: "Step 3: Verify that TH receives AttestationRequest Command from DUT" PICS: OPCREDS.C.C00.Tx verification: | - Verify that the TH(all-clusters-app) Receives AttestationRequest Command from DUT(chip-tool) in commissioning log - - Command=0x0000_0000 - [1689679303.594633][52705:52705] CHIP:ZCL: OpCreds: Received an AttestationRequest command - [1689679303.594696][52705:52705] CHIP:DMG: >> to UDP:[fe80::df9b:2ab4:71bf:d31b%wlp0s20f3]:33479 | 151581348 | [Secure Channel (0) / Standalone Ack (0x10) / Session = 47827 / Exchange = 36146] - [1689679303.594702][52705:52705] CHIP:DMG: Header Flags = - [1689679303.594704][52705:52705] CHIP:DMG: { - [1689679303.594708][52705:52705] CHIP:DMG: Exchange (0x02) = - [1689679303.594711][52705:52705] CHIP:DMG: { - [1689679303.594713][52705:52705] CHIP:DMG: AckMsg = 135880641 - [1689679303.594716][52705:52705] CHIP:DMG: } - [1689679303.594721][52705:52705] CHIP:DMG: } - [1689679303.594724][52705:52705] CHIP:DMG: - [1689679303.594731][52705:52705] CHIP:DMG: Additional Fields = - [1689679303.594733][52705:52705] CHIP:DMG: { - [1689679303.594737][52705:52705] CHIP:DMG: peer_address = UDP:[fe80::df9b:2ab4:71bf:d31b%wlp0s20f3]:33479 - [1689679303.594740][52705:52705] CHIP:DMG: } - [1689679303.594742][52705:52705] CHIP:DMG: - [1689679303.594752][52705:52705] CHIP:EM: <<< [E:36146r S:3817 M:151581348 (Ack:135880641)] (S) Msg TX to 0:FFFFFFFB00000000 [0000] --- Type 0000:10 (SecureChannel:StandaloneAck) - [1689679303.594758][52705:52705] CHIP:IN: (S) Sending msg 151581348 on secure session with LSID: 3817 - [1689679303.594776][52705:52705] CHIP:EM: Flushed pending ack for MessageCounter:135880641 on exchange 36146r - [1689679303.595410][52705:52705] CHIP:ZCL: OpCreds: AttestationRequest successful. - [1689679303.595420][52705:52705] CHIP:DMG: Command handler moving to [ Preparing] - [1689679303.595424][52705:52705] CHIP:DMG: Command handler moving to [AddingComm] - [1689679303.595430][52705:52705] CHIP:DMG: Command handler moving to [AddedComma] - [1689679303.595440][52705:52705] CHIP:DMG: Decreasing reference count for CommandHandler, remaining 0 - [1689679303.595540][52705:52705] CHIP:DMG: >> to UDP:[fe80::df9b:2ab4:71bf:d31b%wlp0s20f3]:33479 | 151581349 | [Interaction Model (1) / InvokeCommandResponse (0x09) / Session = 47827 / Exchange = 36146] - [1689679303.595546][52705:52705] CHIP:DMG: Header Flags = - [1689679303.595549][52705:52705] CHIP:DMG: { - [1689679303.595556][52705:52705] CHIP:DMG: Exchange (0x06) = - [1689679303.595559][52705:52705] CHIP:DMG: { - [1689679303.595563][52705:52705] CHIP:DMG: AckMsg = 135880641 - [1689679303.595566][52705:52705] CHIP:DMG: NeedsAck = true - [1689679303.595568][52705:52705] CHIP:DMG: } - [1689679303.595574][52705:52705] CHIP:DMG: } - [1689679303.595576][52705:52705] CHIP:DMG: - [1689679303.595579][52705:52705] CHIP:DMG: Decrypted Payload (684 bytes) = - [1689679303.595581][52705:52705] CHIP:DMG: { - [1689679303.595583][52705:52705] CHIP:DMG: data = 1528003601153500370024000024013e240201183501310047021531011b023082021706092a864886f70d010702a082020830820204020103310d300b06096086480165030402013082017006092a864886f70d010701a08201610482015d152400012501f1ff3602050080050180050280050380050480050580050680050780050880050980050a80050b80050c80050d80050e80050f80051080051180051280051380051480051580051680051780051880051980051a80051b80051c80051d80051e80051f80052080052180052280052380052480052580052680052780052880052980052a80052b80052c80052d80052e80052f80053080053180053280053380053480053580053680053780053880053980053a80053b80053c80053d80053e80053f80054080054180054280054380054480054580054680054780054880054980054a80054b80054c80054d80054e80054f80055080055180055280055380055480055580055680055780055880055980055a80055b80055c80055d80055e80055f80056080056180056280056380182403162c0413435341303030303053574330303030302d303024050024060024070124080018317c307a0201038014fe343f959947763b61ee4539131338494fe67d8e300b0609608648016503040201300a06082a8648ce3d0403020446304402204a12f8d42f90235c05a77121cbebae15d590146558e9c9b47a1a38f7a36a7dc5022020a4742897c30aeda0a56b36e14ebbc85bbdb74493f993581eb0444ed6ca940b3002200b26be8be08e49a87cd4a4f1af3f46185863568e60caab947202f2c01e4b25392403001830014062e6a464e67c20b4f666201c73e453d451d64cdaa6fa33c12f1c652570b95aa0ac4d43fcd279420a50e7ad596242491c94d750041ab65d9cdaf305483d164f2b1818181824ff0118 - [1689679303.595595][52705:52705] CHIP:DMG: } - [1689679303.595597][52705:52705] CHIP:DMG: - [1689679303.595624][52705:52705] CHIP:DMG: Attestation Elements (583 bytes) = - [1689679303.595626][52705:52705] CHIP:DMG: { - [1689679303.595628][52705:52705] CHIP:DMG: Certification Declaration = - [1689679303.595631][52705:52705] CHIP:DMG: { - [1689679303.595830][52705:52705] CHIP:DMG: Format Version = 1 - [1689679303.595836][52705:52705] CHIP:DMG: Vendor Id = 65521 - [1689679303.595839][52705:52705] CHIP:DMG: Product Ids = - [1689679303.595842][52705:52705] CHIP:DMG: { - [1689679303.595844][52705:52705] CHIP:DMG: Product Id = 32768 - [1689679303.595847][52705:52705] CHIP:DMG: Product Id = 32769 - [1689679303.595849][52705:52705] CHIP:DMG: Product Id = 32770 - [1689679303.595853][52705:52705] CHIP:DMG: Product Id = 32771 - [1689679303.595855][52705:52705] CHIP:DMG: Product Id = 32772 - [1689679303.595857][52705:52705] CHIP:DMG: Product Id = 32773 - [1689679303.595859][52705:52705] CHIP:DMG: Product Id = 32774 - [1689679303.595862][52705:52705] CHIP:DMG: Product Id = 32775 - [1689679303.595864][52705:52705] CHIP:DMG: Product Id = 32776 - [1689679303.595867][52705:52705] CHIP:DMG: Product Id = 32777 - [1689679303.595869][52705:52705] CHIP:DMG: Product Id = 32778 - [1689679303.595872][52705:52705] CHIP:DMG: Product Id = 32779 - [1689679303.595875][52705:52705] CHIP:DMG: Product Id = 32780 - [1689679303.595879][52705:52705] CHIP:DMG: Product Id = 32781 - [1689679303.595883][52705:52705] CHIP:DMG: Product Id = 32782 - [1689679303.595887][52705:52705] CHIP:DMG: Product Id = 32783 - [1689679303.595891][52705:52705] CHIP:DMG: Product Id = 32784 - [1689679303.595895][52705:52705] CHIP:DMG: Product Id = 32785 - [1689679303.595898][52705:52705] CHIP:DMG: Product Id = 32786 - [1689679303.595902][52705:52705] CHIP:DMG: Product Id = 32787 - [1689679303.595905][52705:52705] CHIP:DMG: Product Id = 32788 - [1689679303.595909][52705:52705] CHIP:DMG: Product Id = 32789 - [1689679303.595913][52705:52705] CHIP:DMG: Product Id = 32790 - [1689679303.595919][52705:52705] CHIP:DMG: Product Id = 32791 - [1689679303.595927][52705:52705] CHIP:DMG: Product Id = 32792 - [1689679303.595930][52705:52705] CHIP:DMG: Product Id = 32793 - [1689679303.595933][52705:52705] CHIP:DMG: Product Id = 32794 - [1689679303.595937][52705:52705] CHIP:DMG: Product Id = 32795 - [1689679303.595941][52705:52705] CHIP:DMG: Product Id = 32796 - [1689679303.595942][52705:52705] CHIP:DMG: Product Id = 32797 - [1689679303.595946][52705:52705] CHIP:DMG: Product Id = 32798 - [1689679303.595950][52705:52705] CHIP:DMG: Product Id = 32799 - [1689679303.595952][52705:52705] CHIP:DMG: Product Id = 32800 - [1689679303.595955][52705:52705] CHIP:DMG: Product Id = 32801 - [1689679303.595959][52705:52705] CHIP:DMG: Product Id = 32802 - [1689679303.595960][52705:52705] CHIP:DMG: Product Id = 32803 - [1689679303.595964][52705:52705] CHIP:DMG: Product Id = 32804 - [1689679303.595967][52705:52705] CHIP:DMG: Product Id = 32805 - [1689679303.595969][52705:52705] CHIP:DMG: Product Id = 32806 - [1689679303.595973][52705:52705] CHIP:DMG: Product Id = 32807 - [1689679303.595976][52705:52705] CHIP:DMG: Product Id = 32808 - [1689679303.595978][52705:52705] CHIP:DMG: Product Id = 32809 - [1689679303.595981][52705:52705] CHIP:DMG: Product Id = 32810 - [1689679303.595983][52705:52705] CHIP:DMG: Product Id = 32811 - [1689679303.595987][52705:52705] CHIP:DMG: Product Id = 32812 - [1689679303.595990][52705:52705] CHIP:DMG: Product Id = 32813 - [1689679303.595992][52705:52705] CHIP:DMG: Product Id = 32814 - [1689679303.595995][52705:52705] CHIP:DMG: Product Id = 32815 - [1689679303.595999][52705:52705] CHIP:DMG: Product Id = 32816 - [1689679303.596003][52705:52705] CHIP:DMG: Product Id = 32817 - [1689679303.596006][52705:52705] CHIP:DMG: Product Id = 32818 - [1689679303.596010][52705:52705] CHIP:DMG: Product Id = 32819 - [1689679303.596013][52705:52705] CHIP:DMG: Product Id = 32820 - [1689679303.596017][52705:52705] CHIP:DMG: Product Id = 32821 - [1689679303.596020][52705:52705] CHIP:DMG: Product Id = 32822 - [1689679303.596024][52705:52705] CHIP:DMG: Product Id = 32823 - [1689679303.596028][52705:52705] CHIP:DMG: Product Id = 32824 - [1689679303.596032][52705:52705] CHIP:DMG: Product Id = 32825 - [1689679303.596035][52705:52705] CHIP:DMG: Product Id = 32826 - [1689679303.596038][52705:52705] CHIP:DMG: Product Id = 32827 - [1689679303.596041][52705:52705] CHIP:DMG: Product Id = 32828 - [1689679303.596044][52705:52705] CHIP:DMG: Product Id = 32829 - [1689679303.596047][52705:52705] CHIP:DMG: Product Id = 32830 - [1689679303.596051][52705:52705] CHIP:DMG: Product Id = 32831 - [1689679303.596054][52705:52705] CHIP:DMG: Product Id = 32832 - [1689679303.596056][52705:52705] CHIP:DMG: Product Id = 32833 - [1689679303.596060][52705:52705] CHIP:DMG: Product Id = 32834 - [1689679303.596063][52705:52705] CHIP:DMG: Product Id = 32835 - [1689679303.596066][52705:52705] CHIP:DMG: Product Id = 32836 - [1689679303.596068][52705:52705] CHIP:DMG: Product Id = 32837 - [1689679303.596072][52705:52705] CHIP:DMG: Product Id = 32838 - [1689679303.596075][52705:52705] CHIP:DMG: Product Id = 32839 - [1689679303.596079][52705:52705] CHIP:DMG: Product Id = 32840 - [1689679303.596083][52705:52705] CHIP:DMG: Product Id = 32841 - [1689679303.596086][52705:52705] CHIP:DMG: Product Id = 32842 - [1689679303.596090][52705:52705] CHIP:DMG: Product Id = 32843 - [1689679303.596091][52705:52705] CHIP:DMG: Product Id = 32844 - [1689679303.596095][52705:52705] CHIP:DMG: Product Id = 32845 - [1689679303.596098][52705:52705] CHIP:DMG: Product Id = 32846 - [1689679303.596100][52705:52705] CHIP:DMG: Product Id = 32847 - [1689679303.596104][52705:52705] CHIP:DMG: Product Id = 32848 - [1689679303.596107][52705:52705] CHIP:DMG: Product Id = 32849 - [1689679303.596109][52705:52705] CHIP:DMG: Product Id = 32850 - [1689679303.596111][52705:52705] CHIP:DMG: Product Id = 32851 - [1689679303.596113][52705:52705] CHIP:DMG: Product Id = 32852 - [1689679303.596115][52705:52705] CHIP:DMG: Product Id = 32853 - [1689679303.596118][52705:52705] CHIP:DMG: Product Id = 32854 - [1689679303.596121][52705:52705] CHIP:DMG: Product Id = 32855 - [1689679303.596125][52705:52705] CHIP:DMG: Product Id = 32856 - [1689679303.596129][52705:52705] CHIP:DMG: Product Id = 32857 - [1689679303.596133][52705:52705] CHIP:DMG: Product Id = 32858 - [1689679303.596137][52705:52705] CHIP:DMG: Product Id = 32859 - [1689679303.596140][52705:52705] CHIP:DMG: Product Id = 32860 - [1689679303.596144][52705:52705] CHIP:DMG: Product Id = 32861 - [1689679303.596151][52705:52705] CHIP:DMG: Product Id = 32862 - [1689679303.596155][52705:52705] CHIP:DMG: Product Id = 32863 - [1689679303.596158][52705:52705] CHIP:DMG: Product Id = 32864 - [1689679303.596161][52705:52705] CHIP:DMG: Product Id = 32865 - [1689679303.596164][52705:52705] CHIP:DMG: Product Id = 32866 - [1689679303.596168][52705:52705] CHIP:DMG: Product Id = 32867 - [1689679303.596171][52705:52705] CHIP:DMG: } - [1689679303.596174][52705:52705] CHIP:DMG: Device Type Id = 22 - [1689679303.596178][52705:52705] CHIP:DMG: Certificate Id (19) = CSA00000SWC00000-00 - [1689679303.596182][52705:52705] CHIP:DMG: Security Level = 0 - [1689679303.596185][52705:52705] CHIP:DMG: Security Information = 0 - [1689679303.596188][52705:52705] CHIP:DMG: Version Number = 1 - [1689679303.596191][52705:52705] CHIP:DMG: Certification Type = 0 - [1689679303.596194][52705:52705] CHIP:DMG: } - [1689679303.596199][52705:52705] CHIP:DMG: Attestation Nonce (32) = 0B26BE8BE08E49A87CD4A4F1AF3F46185863568E60CAAB947202F2C01E4B2539 - [1689679303.596202][52705:52705] CHIP:DMG: Timestamp = 0 - [1689679303.596204][52705:52705] CHIP:DMG: } - [1689679303.596207][52705:52705] CHIP:DMG: - [1689679303.596216][52705:52705] CHIP:DMG: InvokeResponseMessage = - [1689679303.596220][52705:52705] CHIP:DMG: { - [1689679303.596222][52705:52705] CHIP:DMG: suppressResponse = false, - [1689679303.596225][52705:52705] CHIP:DMG: InvokeResponseIBs = - [1689679303.596231][52705:52705] CHIP:DMG: [ - [1689679303.596235][52705:52705] CHIP:DMG: InvokeResponseIB = - [1689679303.596241][52705:52705] CHIP:DMG: { - [1689679303.596244][52705:52705] CHIP:DMG: CommandDataIB = - [1689679303.596248][52705:52705] CHIP:DMG: { - [1689679303.596252][52705:52705] CHIP:DMG: CommandPathIB = - [1689679303.596256][52705:52705] CHIP:DMG: { - [1689679303.596260][52705:52705] CHIP:DMG: EndpointId = 0x0, - [1689679303.596265][52705:52705] CHIP:DMG: ClusterId = 0x3e, - [1689679303.596268][52705:52705] CHIP:DMG: CommandId = 0x1, - [1689679303.596270][52705:52705] CHIP:DMG: }, - [1689679303.596274][52705:52705] CHIP:DMG: - [1689679303.596277][52705:52705] CHIP:DMG: CommandFields = - [1689679303.596281][52705:52705] CHIP:DMG: { - [1689679303.596285][52705:52705] CHIP:DMG: 0x0 = [ - [1689679303.596311][52705:52705] CHIP:DMG: 0x15, 0x31, 0x01, 0x1b, 0x02, 0x30, 0x82, 0x02, 0x17, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x02, 0xa0, 0x82, 0x02, 0x08, 0x30, 0x82, 0x02, 0x04, 0x02, 0x01, 0x03, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01, 0x30, 0x82, 0x01, 0x70, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x07, 0x01, 0xa0, 0x82, 0x01, 0x61, 0x04, 0x82, 0x01, 0x5d, 0x15, 0x24, 0x00, 0x01, 0x25, 0x01, 0xf1, 0xff, 0x36, 0x02, 0x05, 0x00, 0x80, 0x05, 0x01, 0x80, 0x05, 0x02, 0x80, 0x05, 0x03, 0x80, 0x05, 0x04, 0x80, 0x05, 0x05, 0x80, 0x05, 0x06, 0x80, 0x05, 0x07, 0x80, 0x05, 0x08, 0x80, 0x05, 0x09, 0x80, 0x05, 0x0a, 0x80, 0x05, 0x0b, 0x80, 0x05, 0x0c, 0x80, 0x05, 0x0d, 0x80, 0x05, 0x0e, 0x80, 0x05, 0x0f, 0x80, 0x05, 0x10, 0x80, 0x05, 0x11, 0x80, 0x05, 0x12, 0x80, 0x05, 0x13, 0x80, 0x05, 0x14, 0x80, 0x05, 0x15, 0x80, 0x05, 0x16, 0x80, 0x05, 0x17, 0x80, 0x05, 0x18, 0x80, 0x05, 0x19, 0x80, 0x05, 0x1a, 0x80, 0x05, 0x1b, 0x80, 0x05, 0x1c, 0x80, 0x05, 0x1d, 0x80, 0x05, 0x1e, 0x80, 0x05, 0x1f, 0x80, 0x05, 0x20, 0x80, 0x05, 0x21, 0x80, 0x05, 0x22, 0x80, 0x05, 0x23, 0x80, 0x05, 0x24, 0x80, 0x05, 0x25, 0x80, 0x05, 0x26, 0x80, 0x05, 0x27, 0x80, 0x05, 0x28, 0x80, 0x05, 0x29, 0x80, 0x05, 0x2a, 0x80, 0x05, 0x2b, 0x80, 0x05, 0x2c, 0x80, 0x05, 0x2d, 0x80, 0x05, 0x2e, 0x80, 0x05, 0x2f, 0x80, 0x05, 0x30, 0x80, 0x05, 0x31, 0x80, 0x05, 0x32, 0x80, 0x05, 0x33, 0x80, 0x05, 0x34, 0x80, 0x05, 0x35, 0x80, 0x05, 0x36, 0x80, 0x05, 0x37, 0x80, 0x05, 0x38, 0x80, 0x05, 0x39, 0x80, 0x05, 0x3a, 0x80, 0x05, 0x3b, 0x80, 0x05, 0x3c, 0x80, 0x05, 0x3d, 0x80, 0x05, 0x3e, 0x80, 0x05, 0x3f, 0x80, 0x05, 0x40, 0x80, 0x05, 0x41, 0x80, 0x05, 0x42, 0x80, 0x05, 0x43, 0x80, 0x - [1689679303.596324][52705:52705] CHIP:DMG: ] (583 bytes) - [1689679303.596329][52705:52705] CHIP:DMG: 0x1 = [ - [1689679303.596346][52705:52705] CHIP:DMG: 0x62, 0xe6, 0xa4, 0x64, 0xe6, 0x7c, 0x20, 0xb4, 0xf6, 0x66, 0x20, 0x1c, 0x73, 0xe4, 0x53, 0xd4, 0x51, 0xd6, 0x4c, 0xda, 0xa6, 0xfa, 0x33, 0xc1, 0x2f, 0x1c, 0x65, 0x25, 0x70, 0xb9, 0x5a, 0xa0, 0xac, 0x4d, 0x43, 0xfc, 0xd2, 0x79, 0x42, 0x0a, 0x50, 0xe7, 0xad, 0x59, 0x62, 0x42, 0x49, 0x1c, 0x94, 0xd7, 0x50, 0x04, 0x1a, 0xb6, 0x5d, 0x9c, 0xda, 0xf3, 0x05, 0x48, 0x3d, 0x16, 0x4f, 0x2b, - [1689679303.596354][52705:52705] CHIP:DMG: ] (64 bytes) - [1689679303.596360][52705:52705] CHIP:DMG: }, - [1689679303.596363][52705:52705] CHIP:DMG: }, - [1689679303.596369][52705:52705] CHIP:DMG: - [1689679303.596372][52705:52705] CHIP:DMG: }, - [1689679303.596378][52705:52705] CHIP:DMG: - [1689679303.596381][52705:52705] CHIP:DMG: ], - [1689679303.596387][52705:52705] CHIP:DMG: - [1689679303.596390][52705:52705] CHIP:DMG: InteractionModelRevision = 1 - [1689679303.596393][52705:52705] CHIP:DMG: }, - [1689679303.596396][52705:52705] CHIP:DMG: - [1689679303.596406][52705:52705] CHIP:DMG: Additional Fields = - [1689679303.596408][52705:52705] CHIP:DMG: { - [1689679303.596412][52705:52705] CHIP:DMG: peer_address = UDP:[fe80::df9b:2ab4:71bf:d31b%wlp0s20f3]:33479 - [1689679303.596415][52705:52705] CHIP:DMG: } - [1689679303.596418][52705:52705] CHIP:DMG: - [1689679303.596432][52705:52705] CHIP:EM: <<< [E:36146r S:3817 M:151581349 (Ack:135880641)] (S) Msg TX to 0:FFFFFFFB00000000 [0000] --- Type 0001:09 (IM:InvokeCommandResponse) - [1689679303.596439][52705:52705] CHIP:IN: (S) Sending msg 151581349 on secure session with LSID: 3817 - [1689679303.596473][52705:52705] CHIP:DMG: Command handler moving to [CommandSen] - [1689679303.596477][52705:52705] CHIP:DMG: Command handler moving to [AwaitingDe] + Verify that the TH(all-clusters-app) Receives AttestationRequest Command from DUT(chip-tool) in commissioning log + + [1720691676.026] [2537:2537] [EM] >>> [E:41765r S:27758 M:74843053 (Ack:113637238)] (S) Msg RX from 0:FFFFFFFB00000000 [0000] --- Type 0000:10 (SecureChannel:StandaloneAck) + [1720691676.026] [2537:2537] [EM] Found matching exchange: 41765r, Delegate: (nil) + [1720691676.026] [2537:2537] [EM] Rxd Ack; Removing MessageCounter:113637238 from Retrans Table on exchange 41765r + [1720691676.031] [2537:2537] [DMG] << from UDP:[fe80::e65f:1ff:fe49:ae1a%eth0]:36167 | 74843054 | [Interaction Model (1) / InvokeCommandRequest (0x08) / Session = 27758 / Exchange = 41767] + [1720691676.031] [2537:2537] [DMG] Header Flags = + [1720691676.031] [2537:2537] [DMG] { + [1720691676.032] [2537:2537] [DMG] Exchange (0x05) = + [1720691676.032] [2537:2537] [DMG] { + [1720691676.032] [2537:2537] [DMG] Initiator = true + [1720691676.032] [2537:2537] [DMG] NeedsAck = true + [1720691676.032] [2537:2537] [DMG] } + [1720691676.032] [2537:2537] [DMG] } + [1720691676.032] [2537:2537] [DMG] + [1720691676.032] [2537:2537] [DMG] Decrypted Payload (64 bytes) = + [1720691676.032] [2537:2537] [DMG] { + [1720691676.032] [2537:2537] [DMG] data = 1528002801360215370024000024013e2402001835013000207c68d54ee8c0f3f8776e9ee70759635be542b72023c0709a5b88c6c8cb80b53918181824ff0b18 + [1720691676.032] [2537:2537] [DMG] } + [1720691676.032] [2537:2537] [DMG] + [1720691676.032] [2537:2537] [DMG] + [1720691676.032] [2537:2537] [DMG] Additional Fields = + [1720691676.032] [2537:2537] [DMG] { + [1720691676.032] [2537:2537] [DMG] peer_address = UDP:[fe80::e65f:1ff:fe49:ae1a%eth0]:36167 + [1720691676.032] [2537:2537] [DMG] } + [1720691676.032] [2537:2537] [DMG] + [1720691676.032] [2537:2537] [EM] >>> [E:41767r S:27758 M:74843054] (S) Msg RX from 0:FFFFFFFB00000000 [0000] --- Type 0001:08 (IM:InvokeCommandRequest) + [1720691676.032] [2537:2537] [EM] Handling via exchange: 41767r, Delegate: 0xaaaad99c9368 + [1720691676.032] [2537:2537] [DMG] InvokeRequestMessage = + [1720691676.032] [2537:2537] [DMG] { + [1720691676.032] [2537:2537] [DMG] suppressResponse = false, + [1720691676.032] [2537:2537] [DMG] timedRequest = false, + [1720691676.032] [2537:2537] [DMG] InvokeRequests = + [1720691676.032] [2537:2537] [DMG] [ + [1720691676.032] [2537:2537] [DMG] CommandDataIB = + [1720691676.032] [2537:2537] [DMG] { + [1720691676.032] [2537:2537] [DMG] CommandPathIB = + [1720691676.033] [2537:2537] [DMG] { + [1720691676.033] [2537:2537] [DMG] EndpointId = 0x0, + [1720691676.033] [2537:2537] [DMG] ClusterId = 0x3e, + [1720691676.033] [2537:2537] [DMG] CommandId = 0x0, + [1720691676.033] [2537:2537] [DMG] }, + [1720691676.033] [2537:2537] [DMG] + [1720691676.033] [2537:2537] [DMG] CommandFields = + [1720691676.033] [2537:2537] [DMG] { + [1720691676.033] [2537:2537] [DMG] 0x0 = [ + [1720691676.033] [2537:2537] [DMG] 0x7c, 0x68, 0xd5, 0x4e, 0xe8, 0xc0, 0xf3, 0xf8, 0x77, 0x6e, 0x9e, 0xe7, 0x07, 0x59, 0x63, 0x5b, 0xe5, 0x42, 0xb7, 0x20, 0x23, 0xc0, 0x70, 0x9a, 0x5b, 0x88, 0xc6, 0xc8, 0xcb, 0x80, 0xb5, 0x39, + [1720691676.033] [2537:2537] [DMG] ] (32 bytes) + [1720691676.033] [2537:2537] [DMG] }, + [1720691676.033] [2537:2537] [DMG] }, + [1720691676.033] [2537:2537] [DMG] + [1720691676.033] [2537:2537] [DMG] ], + [1720691676.033] [2537:2537] [DMG] + [1720691676.033] [2537:2537] [DMG] InteractionModelRevision = 11 + [1720691676.033] [2537:2537] [DMG] }, + [1720691676.033] [2537:2537] [DMG] AccessControl: checking f=0 a=p s=0xFFFFFFFB00000000 t= c=0x0000_003E e=0 p=a + [1720691676.033] [2537:2537] [DMG] AccessControl: implicit admin (PASE) + [1720691676.033] [2537:2537] [DMG] Received command for Endpoint=0 Cluster=0x0000_003E Command=0x0000_0000 + [1720691676.033] [2537:2537] [ZCL] OpCreds: Received an AttestationRequest command + [1720691676.034] [2537:2537] [DMG] >> to UDP:[fe80::e65f:1ff:fe49:ae1a%eth0]:36167 | 113637240 | [Secure Channel (0) / Standalone Ack (0x10) / Session = 38450 / Exchange = 41767] + [1720691676.034] [2537:2537] [DMG] Header Flags = + [1720691676.034] [2537:2537] [DMG] { + [1720691676.034] [2537:2537] [DMG] Exchange (0x02) = + [1720691676.034] [2537:2537] [DMG] { + [1720691676.034] [2537:2537] [DMG] AckMsg = 74843054 + [1720691676.034] [2537:2537] [DMG] } + [1720691676.034] [2537:2537] [DMG] } + [1720691676.034] [2537:2537] [DMG] + [1720691676.034] [2537:2537] [DMG] Additional Fields = + [1720691676.034] [2537:2537] [DMG] { + [1720691676.034] [2537:2537] [DMG] peer_address = UDP:[fe80::e65f:1ff:fe49:ae1a%eth0]:36167 + [1720691676.034] [2537:2537] [DMG] } + [1720691676.034] [2537:2537] [DMG] + [1720691676.034] [2537:2537] [EM] <<< [E:41767r S:27758 M:113637240 (Ack:74843054)] (S) Msg TX to 0:FFFFFFFB00000000 [0000] [UDP:[fe80::e65f:1ff:fe49:ae1a%eth0]:36167] --- Type 0000:10 (SecureChannel:StandaloneAck) + [1720691676.034] [2537:2537] [EM] Flushed pending ack for MessageCounter:74843054 on exchange 41767r + [1720691676.035] [2537:2537] [ZCL] OpCreds: AttestationRequest successful. disabled: true - label: @@ -271,100 +137,51 @@ tests: verification: | Verify that the TH (all-clusters-app) Receives CertificateChainRequest Command from DUT in commissioning log - [1689679303.591413][52705:52705] CHIP:ZCL: OpCreds: Certificate Chain request received for PAI - [1689679303.591421][52705:52705] CHIP:DMG: Command handler moving to [ Preparing] - [1689679303.591426][52705:52705] CHIP:DMG: Command handler moving to [AddingComm] - [1689679303.591432][52705:52705] CHIP:DMG: Command handler moving to [AddedComma] - [1689679303.591440][52705:52705] CHIP:DMG: Decreasing reference count for CommandHandler, remaining 0 - [1689679303.591524][52705:52705] CHIP:DMG: >> to UDP:[fe80::df9b:2ab4:71bf:d31b%wlp0s20f3]:33479 | 151581346 | [Interaction Model (1) / InvokeCommandResponse (0x09) / Session = 47827 / Exchange = 36144] - [1689679303.591532][52705:52705] CHIP:DMG: Header Flags = - [1689679303.591535][52705:52705] CHIP:DMG: { - [1689679303.591542][52705:52705] CHIP:DMG: Exchange (0x06) = - [1689679303.591545][52705:52705] CHIP:DMG: { - [1689679303.591550][52705:52705] CHIP:DMG: AckMsg = 135880637 - [1689679303.591553][52705:52705] CHIP:DMG: NeedsAck = true - [1689679303.591556][52705:52705] CHIP:DMG: } - [1689679303.591562][52705:52705] CHIP:DMG: } - [1689679303.591565][52705:52705] CHIP:DMG: - [1689679303.591569][52705:52705] CHIP:DMG: Decrypted Payload (497 bytes) = - [1689679303.591571][52705:52705] CHIP:DMG: { - [1689679303.591574][52705:52705] CHIP:DMG: data = 1528003601153500370024000024013e2402031835013100cf01308201cb30820171a003020102020856ad8222ad945b64300a06082a8648ce3d04030230303118301606035504030c0f4d617474657220546573742050414131143012060a2b0601040182a27c02010c04464646313020170d3232303230353030303030305a180f39393939313233313233353935395a303d3125302306035504030c1c4d6174746572204465762050414920307846464631206e6f2050494431143012060a2b0601040182a27c02010c04464646313059301306072a8648ce3d020106082a8648ce3d03010703420004419a9315c2173e0c8c876d03ccfc944852647f7fec5e5082f4059928eca894c594151309ac631e4cb03392af684b0bafb7e65b3b8162c2f52bf931b8e77aaa82a366306430120603551d130101ff040830060101ff020100300e0603551d0f0101ff040403020106301d0603551d0e0416041463540e47f64b1c38d13884a462d16c195d8ffb3c301f0603551d230418301680146afd22771f511fecbf1641976710dcdc31a1717e300a06082a8648ce3d0403020348003045022100b2ef27f49ae9b50fb91eeac94c4d0bdbb8d7929c6cb88face529368d12054c0c0220655dc92b86bd909882a6c62177b825d7d05edbe7c22f9fea71220e7ea703f8911818181824ff0118 - [1689679303.591583][52705:52705] CHIP:DMG: } - [1689679303.591586][52705:52705] CHIP:DMG: - [1689679303.591613][52705:52705] CHIP:DMG: DAC/PAI (463) = - [1689679303.591625][52705:52705] CHIP:DMG: { - -----BEGIN CERTIFICATE----- - MIIByzCCAXGgAwIBAgIIVq2CIq2UW2QwCgYIKoZIzj0EAwIwMDEYMBYGA1UEAwwP - TWF0dGVyIFRlc3QgUEFBMRQwEgYKKwYBBAGConwCAQwERkZGMTAgFw0yMjAyMDUw - MDAwMDBaGA85OTk5MTIzMTIzNTk1OVowPTElMCMGA1UEAwwcTWF0dGVyIERldiBQ - QUkgMHhGRkYxIG5vIFBJRDEUMBIGCisGAQQBgqJ8AgEMBEZGRjEwWTATBgcqhkjO - PQIBBggqhkjOPQMBBwNCAARBmpMVwhc+DIyHbQPM/JRIUmR/f+xeUIL0BZko7KiU - xZQVEwmsYx5MsDOSr2hLC6+35ls7gWLC9Sv5MbjneqqCo2YwZDASBgNVHRMBAf8E - CDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBBjAdBgNVHQ4EFgQUY1QOR/ZLHDjROISk - YtFsGV2P+zwwHwYDVR0jBBgwFoAUav0idx9RH+y/FkGXZxDc3DGhcX4wCgYIKoZI - zj0EAwIDSAAwRQIhALLvJ/Sa6bUPuR7qyUxNC9u415KcbLiPrOUpNo0SBUwMAiBl - Xckrhr2QmIKmxiF3uCXX0F7b58Ivn+pxIg5+pwP4kQ== - -----END CERTIFICATE----- - [1689679303.591637][52705:52705] CHIP:DMG: } - [1689679303.591638][52705:52705] CHIP:DMG: - [1689679303.591646][52705:52705] CHIP:DMG: InvokeResponseMessage = - [1689679303.591648][52705:52705] CHIP:DMG: { - [1689679303.591651][52705:52705] CHIP:DMG: suppressResponse = false, - [1689679303.591654][52705:52705] CHIP:DMG: InvokeResponseIBs = - [1689679303.591661][52705:52705] CHIP:DMG: [ - [1689679303.591664][52705:52705] CHIP:DMG: InvokeResponseIB = - [1689679303.591669][52705:52705] CHIP:DMG: { - [1689679303.591672][52705:52705] CHIP:DMG: CommandDataIB = - [1689679303.591676][52705:52705] CHIP:DMG: { - [1689679303.591679][52705:52705] CHIP:DMG: CommandPathIB = - [1689679303.591683][52705:52705] CHIP:DMG: { - [1689679303.591687][52705:52705] CHIP:DMG: EndpointId = 0x0, - [1689679303.591692][52705:52705] CHIP:DMG: ClusterId = 0x3e, - [1689679303.591695][52705:52705] CHIP:DMG: CommandId = 0x3, - [1689679303.591699][52705:52705] CHIP:DMG: }, - [1689679303.591704][52705:52705] CHIP:DMG: - [1689679303.591706][52705:52705] CHIP:DMG: CommandFields = - [1689679303.591711][52705:52705] CHIP:DMG: { - [1689679303.591714][52705:52705] CHIP:DMG: 0x0 = [ - [1689679303.591741][52705:52705] CHIP:DMG: 0x30, 0x82, 0x01, 0xcb, 0x30, 0x82, 0x01, 0x71, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x08, 0x56, 0xad, 0x82, 0x22, 0xad, 0x94, 0x5b, 0x64, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x30, 0x30, 0x31, 0x18, 0x30, 0x16, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x0f, 0x4d, 0x61, 0x74, 0x74, 0x65, 0x72, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x50, 0x41, 0x41, 0x31, 0x14, 0x30, 0x12, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0xa2, 0x7c, 0x02, 0x01, 0x0c, 0x04, 0x46, 0x46, 0x46, 0x31, 0x30, 0x20, 0x17, 0x0d, 0x32, 0x32, 0x30, 0x32, 0x30, 0x35, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 0x5a, 0x18, 0x0f, 0x39, 0x39, 0x39, 0x39, 0x31, 0x32, 0x33, 0x31, 0x32, 0x33, 0x35, 0x39, 0x35, 0x39, 0x5a, 0x30, 0x3d, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x1c, 0x4d, 0x61, 0x74, 0x74, 0x65, 0x72, 0x20, 0x44, 0x65, 0x76, 0x20, 0x50, 0x41, 0x49, 0x20, 0x30, 0x78, 0x46, 0x46, 0x46, 0x31, 0x20, 0x6e, 0x6f, 0x20, 0x50, 0x49, 0x44, 0x31, 0x14, 0x30, 0x12, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x82, 0xa2, 0x7c, 0x02, 0x01, 0x0c, 0x04, 0x46, 0x46, 0x46, 0x31, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x41, 0x9a, 0x93, 0x15, 0xc2, 0x17, 0x3e, 0x0c, 0x8c, 0x87, 0x6d, 0x03, 0xcc, 0xfc, 0x94, 0x48, 0x52, 0x64, 0x7f, 0x7f, 0xec, 0x5e, 0x50, 0x82, 0xf4, 0x05, 0x99, 0x28, 0xec, 0xa8, 0x94, 0xc5, 0x94, 0x15, 0x13, 0x09, 0xac, 0x63, 0x1e, 0x4c, 0xb0, 0x33, 0x92, 0xaf, 0x68, 0x4b, 0x0b, 0xaf, 0xb7, 0xe6, 0x5b, 0x3b, 0x81, 0x62, 0xc2, 0xf5, 0x2b, 0xf9, 0x31, 0xb8, 0xe7, 0x7a, 0xaa, 0x82, 0xa3, 0x66, 0x30, 0x64, 0x30, 0x12, 0x06, 0x03, 0x55, 0x1d, 0x - [1689679303.591755][52705:52705] CHIP:DMG: ] (463 bytes) - [1689679303.591759][52705:52705] CHIP:DMG: }, - [1689679303.591763][52705:52705] CHIP:DMG: }, - [1689679303.591769][52705:52705] CHIP:DMG: - [1689679303.591773][52705:52705] CHIP:DMG: }, - [1689679303.591779][52705:52705] CHIP:DMG: - [1689679303.591781][52705:52705] CHIP:DMG: ], - [1689679303.591787][52705:52705] CHIP:DMG: - [1689679303.591790][52705:52705] CHIP:DMG: InteractionModelRevision = 1 - [1689679303.591794][52705:52705] CHIP:DMG: }, - [1689679303.591797][52705:52705] CHIP:DMG: - [1689679303.591804][52705:52705] CHIP:DMG: Additional Fields = - [1689679303.591806][52705:52705] CHIP:DMG: { - [1689679303.591810][52705:52705] CHIP:DMG: peer_address = UDP:[fe80::df9b:2ab4:71bf:d31b%wlp0s20f3]:33479 - [1689679303.591813][52705:52705] CHIP:DMG: } - [1689679303.591815][52705:52705] CHIP:DMG: - [1689679303.591827][52705:52705] CHIP:EM: <<< [E:36144r S:3817 M:151581346 (Ack:135880637)] (S) Msg TX to 0:FFFFFFFB00000000 [0000] --- Type 0001:09 (IM:InvokeCommandResponse) - [1689679303.591834][52705:52705] CHIP:IN: (S) Sending msg 151581346 on secure session with LSID: 3817 - [1689679303.591861][52705:52705] CHIP:DMG: Command handler moving to [CommandSen] - [1689679303.591864][52705:52705] CHIP:DMG: Command handler moving to [AwaitingDe] - [1689679303.591938][52705:52705] CHIP:DMG: << from UDP:[fe80::df9b:2ab4:71bf:d31b%wlp0s20f3]:33479 | 135880638 | [Secure Channel (0) / Standalone Ack (0x10) / Session = 3817 / Exchange = 36143] - [1689679303.591946][52705:52705] CHIP:DMG: Header Flags = - [1689679303.591949][52705:52705] CHIP:DMG: { - [1689679303.591955][52705:52705] CHIP:DMG: Exchange (0x03) = - [1689679303.591958][52705:52705] CHIP:DMG: { - [1689679303.591960][52705:52705] CHIP:DMG: Initiator = true - [1689679303.591964][52705:52705] CHIP:DMG: AckMsg = 151581345 - [1689679303.591967][52705:52705] CHIP:DMG: } - [1689679303.591971][52705:52705] CHIP:DMG: } - [1689679303.591973][52705:52705] CHIP:DMG: - [1689679303.591978][52705:52705] CHIP:DMG: Additional Fields = - [1689679303.591980][52705:52705] CHIP:DMG: { - [1689679303.591982][52705:52705] CHIP:DMG: peer_address = UDP:[fe80::df9b:2ab4:71bf:d31b%wlp0s20f3]:33479 - [1689679303.591986][52705:52705] CHIP:DMG: } - [1689679303.591989][52705:52705] CHIP:DMG: - [1689679303.591995][52705:52705] CHIP:EM: >>> [E:36143r S:3817 M:135880638 (Ack:151581345)] (S) Msg RX from 0:FFFFFFFB00000000 [0000] --- Type 0000:10 (SecureChannel:StandaloneAck) - [1689679303.591999][52705:52705] CHIP:EM: Found matching exchange: 36143r, Delegate: (nil) - [1689679303.592007][52705:52705] CHIP:EM: Rxd Ack; Removing MessageCounter:151581345 from Retrans Table on exchange 36143r + [1720691676.009] [2537:2537] [DMG] Decrypted Payload (32 bytes) = + [1720691676.009] [2537:2537] [DMG] { + [1720691676.009] [2537:2537] [DMG] data = 1528002801360215370024000024013e24020218350124000218181824ff0b18 + [1720691676.009] [2537:2537] [DMG] } + [1720691676.009] [2537:2537] [DMG] + [1720691676.009] [2537:2537] [DMG] + [1720691676.009] [2537:2537] [DMG] Additional Fields = + [1720691676.009] [2537:2537] [DMG] { + [1720691676.009] [2537:2537] [DMG] peer_address = UDP:[fe80::e65f:1ff:fe49:ae1a%eth0]:36167 + [1720691676.009] [2537:2537] [DMG] } + [1720691676.009] [2537:2537] [DMG] + [1720691676.010] [2537:2537] [EM] >>> [E:41765r S:27758 M:74843050] (S) Msg RX from 0:FFFFFFFB00000000 [0000] --- Type 0001:08 (IM:InvokeCommandRequest) + [1720691676.010] [2537:2537] [EM] Handling via exchange: 41765r, Delegate: 0xaaaad99c9368 + [1720691676.010] [2537:2537] [DMG] InvokeRequestMessage = + [1720691676.010] [2537:2537] [DMG] { + [1720691676.010] [2537:2537] [DMG] suppressResponse = false, + [1720691676.010] [2537:2537] [DMG] timedRequest = false, + [1720691676.010] [2537:2537] [DMG] InvokeRequests = + [1720691676.010] [2537:2537] [DMG] [ + [1720691676.010] [2537:2537] [DMG] CommandDataIB = + [1720691676.010] [2537:2537] [DMG] { + [1720691676.010] [2537:2537] [DMG] CommandPathIB = + [1720691676.010] [2537:2537] [DMG] { + [1720691676.010] [2537:2537] [DMG] EndpointId = 0x0, + [1720691676.010] [2537:2537] [DMG] ClusterId = 0x3e, + [1720691676.010] [2537:2537] [DMG] CommandId = 0x2, + [1720691676.010] [2537:2537] [DMG] }, + [1720691676.010] [2537:2537] [DMG] + [1720691676.010] [2537:2537] [DMG] CommandFields = + [1720691676.010] [2537:2537] [DMG] { + [1720691676.010] [2537:2537] [DMG] 0x0 = 2 (unsigned), + [1720691676.010] [2537:2537] [DMG] }, + [1720691676.010] [2537:2537] [DMG] }, + [1720691676.010] [2537:2537] [DMG] + [1720691676.010] [2537:2537] [DMG] ], + [1720691676.010] [2537:2537] [DMG] + [1720691676.010] [2537:2537] [DMG] InteractionModelRevision = 11 + [1720691676.010] [2537:2537] [DMG] }, + [1720691676.011] [2537:2537] [DMG] AccessControl: checking f=0 a=p s=0xFFFFFFFB00000000 t= c=0x0000_003E e=0 p=a + [1720691676.011] [2537:2537] [DMG] AccessControl: implicit admin (PASE) + [1720691676.011] [2537:2537] [DMG] Received command for Endpoint=0 Cluster=0x0000_003E Command=0x0000_0002 + [1720691676.011] [2537:2537] [ZCL] OpCreds: Certificate Chain request received for PAI + [1720691676.011] [2537:2537] [DMG] Command handler moving to [NewRespons] + [1720691676.011] [2537:2537] [DMG] Command handler moving to [ Preparing] + [1720691676.011] [2537:2537] [DMG] Command handler moving to [AddingComm] disabled: true - label: "Step 5a: Verify that the TH receives CSRRequest command from DUT" @@ -372,104 +189,75 @@ tests: verification: | Verify that the TH (all-clusters-app) Receives CSRRequest command from DUT in commissioning log - [1689679303.601215][52705:52705] CHIP:ZCL: OpCreds: Received a CSRRequest command - [1689679303.601220][52705:52705] CHIP:ZCL: OpCreds: Finding fabric with fabricIndex 0x0 - [1689679303.601291][52705:52705] CHIP:DMG: >> to UDP:[fe80::df9b:2ab4:71bf:d31b%wlp0s20f3]:33479 | 151581350 | [Secure Channel (0) / Standalone Ack (0x10) / Session = 47827 / Exchange = 36147] - [1689679303.601299][52705:52705] CHIP:DMG: Header Flags = - [1689679303.601302][52705:52705] CHIP:DMG: { - [1689679303.601309][52705:52705] CHIP:DMG: Exchange (0x02) = - [1689679303.601312][52705:52705] CHIP:DMG: { - [1689679303.601316][52705:52705] CHIP:DMG: AckMsg = 135880643 - [1689679303.601319][52705:52705] CHIP:DMG: } - [1689679303.601325][52705:52705] CHIP:DMG: } - [1689679303.601328][52705:52705] CHIP:DMG: - [1689679303.601335][52705:52705] CHIP:DMG: Additional Fields = - [1689679303.601338][52705:52705] CHIP:DMG: { - [1689679303.601342][52705:52705] CHIP:DMG: peer_address = UDP:[fe80::df9b:2ab4:71bf:d31b%wlp0s20f3]:33479 - [1689679303.601345][52705:52705] CHIP:DMG: } - [1689679303.601348][52705:52705] CHIP:DMG: - [1689679303.601360][52705:52705] CHIP:EM: <<< [E:36147r S:3817 M:151581350 (Ack:135880643)] (S) Msg TX to 0:FFFFFFFB00000000 [0000] --- Type 0000:10 (SecureChannel:StandaloneAck) - [1689679303.601367][52705:52705] CHIP:IN: (S) Sending msg 151581350 on secure session with LSID: 3817 - [1689679303.601389][52705:52705] CHIP:EM: Flushed pending ack for MessageCounter:135880643 on exchange 36147r - [1689679303.601653][52705:52705] CHIP:ZCL: OpCreds: AllocatePendingOperationalKey succeeded - [1689679303.601730][52705:52705] CHIP:ZCL: OpCreds: CSRRequest successful. - [1689679303.601738][52705:52705] CHIP:DMG: Command handler moving to [ Preparing] - [1689679303.601743][52705:52705] CHIP:DMG: Command handler moving to [AddingComm] - [1689679303.601753][52705:52705] CHIP:DMG: Command handler moving to [AddedComma] - [1689679303.601762][52705:52705] CHIP:DMG: Decreasing reference count for CommandHandler, remaining 0 - [1689679303.601845][52705:52705] CHIP:DMG: >> to UDP:[fe80::df9b:2ab4:71bf:d31b%wlp0s20f3]:33479 | 151581351 | [Interaction Model (1) / InvokeCommandResponse (0x09) / Session = 47827 / Exchange = 36147] - [1689679303.601853][52705:52705] CHIP:DMG: Header Flags = - [1689679303.601856][52705:52705] CHIP:DMG: { - [1689679303.601864][52705:52705] CHIP:DMG: Exchange (0x06) = - [1689679303.601866][52705:52705] CHIP:DMG: { - [1689679303.601870][52705:52705] CHIP:DMG: AckMsg = 135880643 - [1689679303.601874][52705:52705] CHIP:DMG: NeedsAck = true - [1689679303.601877][52705:52705] CHIP:DMG: } - [1689679303.601883][52705:52705] CHIP:DMG: } - [1689679303.601885][52705:52705] CHIP:DMG: - [1689679303.601889][52705:52705] CHIP:DMG: Decrypted Payload (342 bytes) = - [1689679303.601892][52705:52705] CHIP:DMG: { - [1689679303.601895][52705:52705] CHIP:DMG: data = 1528003601153500370024000024013e2402051835013000f2153001ca3081c73070020100300e310c300a060355040a0c034353523059301306072a8648ce3d020106082a8648ce3d03010703420004f294d4aa30dad41668bdb0e24ac0d830b0ba335c8877c5b60af62b985cff212395197314d3025963a4501b4acb8a2202eccc10ed657cff7fae8f9912b393c1cda000300a06082a8648ce3d040302034700304402207d0d5ec6c11550ce1eecd34804f76bc35c227f97452b711af1fa56ae402d1c73022075316e7e662f136e3b1538ebea710286029bcff9057d4858e042456988984a97300220173607ce4fb48e1db8f246f4bf61bc44bd92a69ebaf25139350f73d4db7e9b09183001402ee3db400d018543d99c5561a6f646eae5f8bebb4489740ff6982c7225397932f3737af0fdfbb763a073e4ad112da39ba6361d852bf2562a80b562f810a84a051818181824ff0118 - [1689679303.601900][52705:52705] CHIP:DMG: } - [1689679303.601902][52705:52705] CHIP:DMG: - [1689679303.601927][52705:52705] CHIP:DMG: NOCSR Elements = - [1689679303.601930][52705:52705] CHIP:DMG: { - [1689679303.601937][52705:52705] CHIP:DMG: CSR (202) = 3081C73070020100300E310C300A060355040A0C034353523059301306072A8648CE3D020106082A8648CE3D03010703420004F294D4AA30DAD41668BDB0E24AC0D830B0BA335C8877C5B60AF62B985CFF212395197314D3025963A4501B4ACB8A2202ECCC10ED657CFF7FAE8F9912B393C1CDA000300A06082A8648CE3D040302034700304402207D0D5EC6C11550CE1EECD34804F76BC35C227F97452B711AF1FA56AE402D1C73022075316E7E662F136E3B1538EBEA710286029BCFF9057D4858E042456988984A97 - [1689679303.601943][52705:52705] CHIP:DMG: CSRNonce (32) = 173607CE4FB48E1DB8F246F4BF61BC44BD92A69EBAF25139350F73D4DB7E9B09 - [1689679303.601946][52705:52705] CHIP:DMG: } - [1689679303.601949][52705:52705] CHIP:DMG: - [1689679303.601953][52705:52705] CHIP:DMG: CSR (202) = - [1689679303.601962][52705:52705] CHIP:DMG: { - -----BEGIN CERTIFICATE REQUEST----- - MIHHMHACAQAwDjEMMAoGA1UECgwDQ1NSMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcD - QgAE8pTUqjDa1BZovbDiSsDYMLC6M1yId8W2CvYrmFz/ISOVGXMU0wJZY6RQG0rL - iiIC7MwQ7WV8/3+uj5kSs5PBzaAAMAoGCCqGSM49BAMCA0cAMEQCIH0NXsbBFVDO - HuzTSAT3a8NcIn+XRStxGvH6Vq5ALRxzAiB1MW5+Zi8TbjsVOOvqcQKGApvP+QV9 - SFjgQkVpiJhKlw== - -----END CERTIFICATE REQUEST----- - [1689679303.601969][52705:52705] CHIP:DMG: } - [1689679303.601972][52705:52705] CHIP:DMG: - [1689679303.601978][52705:52705] CHIP:DMG: InvokeResponseMessage = - [1689679303.601981][52705:52705] CHIP:DMG: { - [1689679303.601983][52705:52705] CHIP:DMG: suppressResponse = false, - [1689679303.601986][52705:52705] CHIP:DMG: InvokeResponseIBs = - [1689679303.601990][52705:52705] CHIP:DMG: [ - [1689679303.601993][52705:52705] CHIP:DMG: InvokeResponseIB = - [1689679303.602000][52705:52705] CHIP:DMG: { - [1689679303.602003][52705:52705] CHIP:DMG: CommandDataIB = - [1689679303.602005][52705:52705] CHIP:DMG: { - [1689679303.602008][52705:52705] CHIP:DMG: CommandPathIB = - [1689679303.602010][52705:52705] CHIP:DMG: { - [1689679303.602013][52705:52705] CHIP:DMG: EndpointId = 0x0, - [1689679303.602017][52705:52705] CHIP:DMG: ClusterId = 0x3e, - [1689679303.602020][52705:52705] CHIP:DMG: CommandId = 0x5, - [1689679303.602023][52705:52705] CHIP:DMG: }, - [1689679303.602029][52705:52705] CHIP:DMG: - [1689679303.602031][52705:52705] CHIP:DMG: CommandFields = - [1689679303.602035][52705:52705] CHIP:DMG: { - [1689679303.602041][52705:52705] CHIP:DMG: 0x0 = [ - [1689679303.602061][52705:52705] CHIP:DMG: 0x15, 0x30, 0x01, 0xca, 0x30, 0x81, 0xc7, 0x30, 0x70, 0x02, 0x01, 0x00, 0x30, 0x0e, 0x31, 0x0c, 0x30, 0x0a, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x03, 0x43, 0x53, 0x52, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0xf2, 0x94, 0xd4, 0xaa, 0x30, 0xda, 0xd4, 0x16, 0x68, 0xbd, 0xb0, 0xe2, 0x4a, 0xc0, 0xd8, 0x30, 0xb0, 0xba, 0x33, 0x5c, 0x88, 0x77, 0xc5, 0xb6, 0x0a, 0xf6, 0x2b, 0x98, 0x5c, 0xff, 0x21, 0x23, 0x95, 0x19, 0x73, 0x14, 0xd3, 0x02, 0x59, 0x63, 0xa4, 0x50, 0x1b, 0x4a, 0xcb, 0x8a, 0x22, 0x02, 0xec, 0xcc, 0x10, 0xed, 0x65, 0x7c, 0xff, 0x7f, 0xae, 0x8f, 0x99, 0x12, 0xb3, 0x93, 0xc1, 0xcd, 0xa0, 0x00, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x03, 0x47, 0x00, 0x30, 0x44, 0x02, 0x20, 0x7d, 0x0d, 0x5e, 0xc6, 0xc1, 0x15, 0x50, 0xce, 0x1e, 0xec, 0xd3, 0x48, 0x04, 0xf7, 0x6b, 0xc3, 0x5c, 0x22, 0x7f, 0x97, 0x45, 0x2b, 0x71, 0x1a, 0xf1, 0xfa, 0x56, 0xae, 0x40, 0x2d, 0x1c, 0x73, 0x02, 0x20, 0x75, 0x31, 0x6e, 0x7e, 0x66, 0x2f, 0x13, 0x6e, 0x3b, 0x15, 0x38, 0xeb, 0xea, 0x71, 0x02, 0x86, 0x02, 0x9b, 0xcf, 0xf9, 0x05, 0x7d, 0x48, 0x58, 0xe0, 0x42, 0x45, 0x69, 0x88, 0x98, 0x4a, 0x97, 0x30, 0x02, 0x20, 0x17, 0x36, 0x07, 0xce, 0x4f, 0xb4, 0x8e, 0x1d, 0xb8, 0xf2, 0x46, 0xf4, 0xbf, 0x61, 0xbc, 0x44, 0xbd, 0x92, 0xa6, 0x9e, 0xba, 0xf2, 0x51, 0x39, 0x35, 0x0f, 0x73, 0xd4, 0xdb, 0x7e, 0x9b, 0x09, 0x18, - [1689679303.602072][52705:52705] CHIP:DMG: ] (242 bytes) - [1689679303.602075][52705:52705] CHIP:DMG: 0x1 = [ - [1689679303.602083][52705:52705] CHIP:DMG: 0x2e, 0xe3, 0xdb, 0x40, 0x0d, 0x01, 0x85, 0x43, 0xd9, 0x9c, 0x55, 0x61, 0xa6, 0xf6, 0x46, 0xea, 0xe5, 0xf8, 0xbe, 0xbb, 0x44, 0x89, 0x74, 0x0f, 0xf6, 0x98, 0x2c, 0x72, 0x25, 0x39, 0x79, 0x32, 0xf3, 0x73, 0x7a, 0xf0, 0xfd, 0xfb, 0xb7, 0x63, 0xa0, 0x73, 0xe4, 0xad, 0x11, 0x2d, 0xa3, 0x9b, 0xa6, 0x36, 0x1d, 0x85, 0x2b, 0xf2, 0x56, 0x2a, 0x80, 0xb5, 0x62, 0xf8, 0x10, 0xa8, 0x4a, 0x05, - [1689679303.602087][52705:52705] CHIP:DMG: ] (64 bytes) - [1689679303.602090][52705:52705] CHIP:DMG: }, - [1689679303.602095][52705:52705] CHIP:DMG: }, - [1689679303.602100][52705:52705] CHIP:DMG: - [1689679303.602102][52705:52705] CHIP:DMG: }, - [1689679303.602106][52705:52705] CHIP:DMG: - [1689679303.602108][52705:52705] CHIP:DMG: ], - [1689679303.602112][52705:52705] CHIP:DMG: - [1689679303.602114][52705:52705] CHIP:DMG: InteractionModelRevision = 1 - [1689679303.602116][52705:52705] CHIP:DMG: }, - [1689679303.602118][52705:52705] CHIP:DMG: - [1689679303.602124][52705:52705] CHIP:DMG: Additional Fields = - [1689679303.602126][52705:52705] CHIP:DMG: { - [1689679303.602128][52705:52705] CHIP:DMG: peer_address = UDP:[fe80::df9b:2ab4:71bf:d31b%wlp0s20f3]:33479 - [1689679303.602131][52705:52705] CHIP:DMG: } - [1689679303.602135][52705:52705] CHIP:DMG: - [1689679303.602146][52705:52705] CHIP:EM: <<< [E:36147r S:3817 M:151581351 (Ack:135880643)] (S) Msg TX to 0:FFFFFFFB00000000 [0000] --- Type 0001:09 (IM:InvokeCommandResponse) - [1689679303.602152][52705:52705] CHIP:IN: (S) Sending msg 151581351 on secure session with LSID: 3817 + [1720691676.043] [2537:2537] [EM] Rxd Ack; Removing MessageCounter:113637239 from Retrans Table on exchange 41766r + [1720691676.074] [2537:2537] [DMG] << from UDP:[fe80::e65f:1ff:fe49:ae1a%eth0]:36167 | 74843056 | [Interaction Model (1) / InvokeCommandRequest (0x08) / Session = 27758 / Exchange = 41768] + [1720691676.075] [2537:2537] [DMG] Header Flags = + [1720691676.075] [2537:2537] [DMG] { + [1720691676.075] [2537:2537] [DMG] Exchange (0x05) = + [1720691676.075] [2537:2537] [DMG] { + [1720691676.075] [2537:2537] [DMG] Initiator = true + [1720691676.075] [2537:2537] [DMG] NeedsAck = true + [1720691676.075] [2537:2537] [DMG] } + [1720691676.075] [2537:2537] [DMG] } + [1720691676.075] [2537:2537] [DMG] + [1720691676.075] [2537:2537] [DMG] Decrypted Payload (64 bytes) = + [1720691676.075] [2537:2537] [DMG] { + [1720691676.075] [2537:2537] [DMG] data = 1528002801360215370024000024013e24020418350130002037353c156dff31a01df3e159a0385de766d3fb980705918594edeb19f504124018181824ff0b18 + [1720691676.075] [2537:2537] [DMG] } + [1720691676.075] [2537:2537] [DMG] + [1720691676.075] [2537:2537] [DMG] + [1720691676.075] [2537:2537] [DMG] Additional Fields = + [1720691676.075] [2537:2537] [DMG] { + [1720691676.075] [2537:2537] [DMG] peer_address = UDP:[fe80::e65f:1ff:fe49:ae1a%eth0]:36167 + [1720691676.075] [2537:2537] [DMG] } + [1720691676.075] [2537:2537] [DMG] + [1720691676.075] [2537:2537] [EM] >>> [E:41768r S:27758 M:74843056] (S) Msg RX from 0:FFFFFFFB00000000 [0000] --- Type 0001:08 (IM:InvokeCommandRequest) + [1720691676.075] [2537:2537] [EM] Handling via exchange: 41768r, Delegate: 0xaaaad99c9368 + [1720691676.075] [2537:2537] [DMG] InvokeRequestMessage = + [1720691676.075] [2537:2537] [DMG] { + [1720691676.075] [2537:2537] [DMG] suppressResponse = false, + [1720691676.075] [2537:2537] [DMG] timedRequest = false, + [1720691676.075] [2537:2537] [DMG] InvokeRequests = + [1720691676.075] [2537:2537] [DMG] [ + [1720691676.075] [2537:2537] [DMG] CommandDataIB = + [1720691676.075] [2537:2537] [DMG] { + [1720691676.075] [2537:2537] [DMG] CommandPathIB = + [1720691676.075] [2537:2537] [DMG] { + [1720691676.075] [2537:2537] [DMG] EndpointId = 0x0, + [1720691676.076] [2537:2537] [DMG] ClusterId = 0x3e, + [1720691676.076] [2537:2537] [DMG] CommandId = 0x4, + [1720691676.076] [2537:2537] [DMG] }, + [1720691676.076] [2537:2537] [DMG] + [1720691676.076] [2537:2537] [DMG] CommandFields = + [1720691676.076] [2537:2537] [DMG] { + [1720691676.076] [2537:2537] [DMG] 0x0 = [ + [1720691676.076] [2537:2537] [DMG] 0x37, 0x35, 0x3c, 0x15, 0x6d, 0xff, 0x31, 0xa0, 0x1d, 0xf3, 0xe1, 0x59, 0xa0, 0x38, 0x5d, 0xe7, 0x66, 0xd3, 0xfb, 0x98, 0x07, 0x05, 0x91, 0x85, 0x94, 0xed, 0xeb, 0x19, 0xf5, 0x04, 0x12, 0x40, + [1720691676.076] [2537:2537] [DMG] ] (32 bytes) + [1720691676.076] [2537:2537] [DMG] }, + [1720691676.076] [2537:2537] [DMG] }, + [1720691676.076] [2537:2537] [DMG] + [1720691676.076] [2537:2537] [DMG] ], + [1720691676.076] [2537:2537] [DMG] + [1720691676.076] [2537:2537] [DMG] InteractionModelRevision = 11 + [1720691676.076] [2537:2537] [DMG] }, + [1720691676.076] [2537:2537] [DMG] AccessControl: checking f=0 a=p s=0xFFFFFFFB00000000 t= c=0x0000_003E e=0 p=a + [1720691676.076] [2537:2537] [DMG] AccessControl: implicit admin (PASE) + [1720691676.076] [2537:2537] [DMG] Received command for Endpoint=0 Cluster=0x0000_003E Command=0x0000_0004 + [1720691676.076] [2537:2537] [ZCL] OpCreds: Received a CSRRequest command + [1720691676.076] [2537:2537] [ZCL] OpCreds: Finding fabric with fabricIndex 0x0 + [1720691676.076] [2537:2537] [DMG] >> to UDP:[fe80::e65f:1ff:fe49:ae1a%eth0]:36167 | 113637242 | [Secure Channel (0) / Standalone Ack (0x10) / Session = 38450 / Exchange = 41768] + [1720691676.076] [2537:2537] [DMG] Header Flags = + [1720691676.077] [2537:2537] [DMG] { + [1720691676.077] [2537:2537] [DMG] Exchange (0x02) = + [1720691676.077] [2537:2537] [DMG] { + [1720691676.077] [2537:2537] [DMG] AckMsg = 74843056 + [1720691676.077] [2537:2537] [DMG] } + [1720691676.077] [2537:2537] [DMG] } + [1720691676.077] [2537:2537] [DMG] + [1720691676.077] [2537:2537] [DMG] Additional Fields = + [1720691676.077] [2537:2537] [DMG] { + [1720691676.077] [2537:2537] [DMG] peer_address = UDP:[fe80::e65f:1ff:fe49:ae1a%eth0]:36167 + [1720691676.077] [2537:2537] [DMG] } disabled: true - label: @@ -479,63 +267,78 @@ tests: verification: | Extract the CSRResponse and NOCSRElements values from TH (all-clusters-app) in commissioning log - [1689679303.601927][52705:52705] CHIP:DMG: NOCSR Elements = - [1689679303.601930][52705:52705] CHIP:DMG: { - [1689679303.601937][52705:52705] CHIP:DMG: CSR (202) = 3081C73070020100300E310C300A060355040A0C034353523059301306072A8648CE3D020106082A8648CE3D03010703420004F294D4AA30DAD41668BDB0E24AC0D830B0BA335C8877C5B60AF62B985CFF212395197314D3025963A4501B4ACB8A2202ECCC10ED657CFF7FAE8F9912B393C1CDA000300A06082A8648CE3D040302034700304402207D0D5EC6C11550CE1EECD34804F76BC35C227F97452B711AF1FA56AE402D1C73022075316E7E662F136E3B1538EBEA710286029BCFF9057D4858E042456988984A97 - [1689679303.601943][52705:52705] CHIP:DMG: CSRNonce (32) = 173607CE4FB48E1DB8F246F4BF61BC44BD92A69EBAF25139350F73D4DB7E9B09 - [1689679303.601946][52705:52705] CHIP:DMG: } - [1689679303.601949][52705:52705] CHIP:DMG: - [1689679303.601953][52705:52705] CHIP:DMG: CSR (202) = - [1689679303.601962][52705:52705] CHIP:DMG: { + [1720691676.079] [2537:2537] [DMG] >> to UDP:[fe80::e65f:1ff:fe49:ae1a%eth0]:36167 | 113637243 | [Interaction Model (1) / InvokeCommandResponse (0x09) / Session = 38450 / Exchange = 41768] + [1720691676.079] [2537:2537] [DMG] Header Flags = + [1720691676.079] [2537:2537] [DMG] { + [1720691676.079] [2537:2537] [DMG] Exchange (0x06) = + [1720691676.080] [2537:2537] [DMG] { + [1720691676.080] [2537:2537] [DMG] AckMsg = 74843056 + [1720691676.080] [2537:2537] [DMG] NeedsAck = true + [1720691676.080] [2537:2537] [DMG] } + [1720691676.080] [2537:2537] [DMG] } + [1720691676.080] [2537:2537] [DMG] + [1720691676.080] [2537:2537] [DMG] Decrypted Payload (343 bytes) = + [1720691676.080] [2537:2537] [DMG] { + [1720691676.080] [2537:2537] [DMG] data = 1528003601153500370024000024013e2402051835013000f3153001cb3081c83070020100300e310c300a060355040a0c034353523059301306072a8648ce3d020106082a8648ce3d030107034200044a270345ab219ad87b15d3019b537913f9b4141b65086f20310e9c6beb10e1d1bb6c38408a4e3060e521ec23d003223aaf91be2b0d4aba01d5936f28e4e472b0a000300a06082a8648ce3d0403020348003045022100c74c410513566f3079690fa1d8abe9df58c0fc60cfaf5d704dbdfd2a8db9ac4602206b31521e0840b2b23e2c36f15b6b2ca41c041e0217fd19b5f64f7870b241596d30022037353c156dff31a01df3e159a0385de766d3fb980705918594edeb19f50412401830014028810eea9532046bec7c1bb243bb72991d82cffd686e6eec5bb44e0b477d06df4abe6fd462fabd6d8a85e0e76b16a9f0e1aa9a96e31c3cd61ebf95c3d6aaa0191818181824ff0b18 + [1720691676.080] [2537:2537] [DMG] } + [1720691676.080] [2537:2537] [DMG] + [1720691676.080] [2537:2537] [DMG] NOCSR Elements = + [1720691676.080] [2537:2537] [DMG] { + [1720691676.080] [2537:2537] [DMG] CSR (203) = 3081C83070020100300E310C300A060355040A0C034353523059301306072A8648CE3D020106082A8648CE3D030107034200044A270345AB219AD87B15D3019B537913F9B4141B65086F20310E9C6BEB10E1D1BB6C38408A4E3060E521EC23D003223AAF91BE2B0D4ABA01D5936F28E4E472B0A000300A06082A8648CE3D0403020348003045022100C74C410513566F3079690FA1D8ABE9DF58C0FC60CFAF5D704DBDFD2A8DB9AC4602206B31521E0840B2B23E2C36F15B6B2CA41C041E0217FD19B5F64F7870B241596D + [1720691676.080] [2537:2537] [DMG] CSRNonce (32) = 37353C156DFF31A01DF3E159A0385DE766D3FB980705918594EDEB19F5041240 + [1720691676.080] [2537:2537] [DMG] } + [1720691676.080] [2537:2537] [DMG] + [1720691676.080] [2537:2537] [DMG] CSR (203) = + [1720691676.080] [2537:2537] [DMG] { -----BEGIN CERTIFICATE REQUEST----- - MIHHMHACAQAwDjEMMAoGA1UECgwDQ1NSMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcD - QgAE8pTUqjDa1BZovbDiSsDYMLC6M1yId8W2CvYrmFz/ISOVGXMU0wJZY6RQG0rL - iiIC7MwQ7WV8/3+uj5kSs5PBzaAAMAoGCCqGSM49BAMCA0cAMEQCIH0NXsbBFVDO - HuzTSAT3a8NcIn+XRStxGvH6Vq5ALRxzAiB1MW5+Zi8TbjsVOOvqcQKGApvP+QV9 - SFjgQkVpiJhKlw== + MIHIMHACAQAwDjEMMAoGA1UECgwDQ1NSMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcD + QgAESicDRashmth7FdMBm1N5E/m0FBtlCG8gMQ6ca+sQ4dG7bDhAik4wYOUh7CPQ + AyI6r5G+Kw1KugHVk28o5ORysKAAMAoGCCqGSM49BAMCA0gAMEUCIQDHTEEFE1Zv + MHlpD6HYq+nfWMD8YM+vXXBNvf0qjbmsRgIgazFSHghAsrI+LDbxW2sspBwEHgIX + /Rm19k94cLJBWW0= -----END CERTIFICATE REQUEST----- - [1689679303.601969][52705:52705] CHIP:DMG: } - [1689679303.601972][52705:52705] CHIP:DMG: - [1689679303.601978][52705:52705] CHIP:DMG: InvokeResponseMessage = - [1689679303.601981][52705:52705] CHIP:DMG: { - [1689679303.601983][52705:52705] CHIP:DMG: suppressResponse = false, - [1689679303.601986][52705:52705] CHIP:DMG: InvokeResponseIBs = - [1689679303.601990][52705:52705] CHIP:DMG: [ - [1689679303.601993][52705:52705] CHIP:DMG: InvokeResponseIB = - [1689679303.602000][52705:52705] CHIP:DMG: { - [1689679303.602003][52705:52705] CHIP:DMG: CommandDataIB = - [1689679303.602005][52705:52705] CHIP:DMG: { - [1689679303.602008][52705:52705] CHIP:DMG: CommandPathIB = - [1689679303.602010][52705:52705] CHIP:DMG: { - [1689679303.602013][52705:52705] CHIP:DMG: EndpointId = 0x0, - [1689679303.602017][52705:52705] CHIP:DMG: ClusterId = 0x3e, - [1689679303.602020][52705:52705] CHIP:DMG: CommandId = 0x5, - [1689679303.602023][52705:52705] CHIP:DMG: }, - [1689679303.602029][52705:52705] CHIP:DMG: - [1689679303.602031][52705:52705] CHIP:DMG: CommandFields = - [1689679303.602035][52705:52705] CHIP:DMG: { - [1689679303.602041][52705:52705] CHIP:DMG: 0x0 = [ - [1689679303.602061][52705:52705] CHIP:DMG: 0x15, 0x30, 0x01, 0xca, 0x30, 0x81, 0xc7, 0x30, 0x70, 0x02, 0x01, 0x00, 0x30, 0x0e, 0x31, 0x0c, 0x30, 0x0a, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x03, 0x43, 0x53, 0x52, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0xf2, 0x94, 0xd4, 0xaa, 0x30, 0xda, 0xd4, 0x16, 0x68, 0xbd, 0xb0, 0xe2, 0x4a, 0xc0, 0xd8, 0x30, 0xb0, 0xba, 0x33, 0x5c, 0x88, 0x77, 0xc5, 0xb6, 0x0a, 0xf6, 0x2b, 0x98, 0x5c, 0xff, 0x21, 0x23, 0x95, 0x19, 0x73, 0x14, 0xd3, 0x02, 0x59, 0x63, 0xa4, 0x50, 0x1b, 0x4a, 0xcb, 0x8a, 0x22, 0x02, 0xec, 0xcc, 0x10, 0xed, 0x65, 0x7c, 0xff, 0x7f, 0xae, 0x8f, 0x99, 0x12, 0xb3, 0x93, 0xc1, 0xcd, 0xa0, 0x00, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x03, 0x47, 0x00, 0x30, 0x44, 0x02, 0x20, 0x7d, 0x0d, 0x5e, 0xc6, 0xc1, 0x15, 0x50, 0xce, 0x1e, 0xec, 0xd3, 0x48, 0x04, 0xf7, 0x6b, 0xc3, 0x5c, 0x22, 0x7f, 0x97, 0x45, 0x2b, 0x71, 0x1a, 0xf1, 0xfa, 0x56, 0xae, 0x40, 0x2d, 0x1c, 0x73, 0x02, 0x20, 0x75, 0x31, 0x6e, 0x7e, 0x66, 0x2f, 0x13, 0x6e, 0x3b, 0x15, 0x38, 0xeb, 0xea, 0x71, 0x02, 0x86, 0x02, 0x9b, 0xcf, 0xf9, 0x05, 0x7d, 0x48, 0x58, 0xe0, 0x42, 0x45, 0x69, 0x88, 0x98, 0x4a, 0x97, 0x30, 0x02, 0x20, 0x17, 0x36, 0x07, 0xce, 0x4f, 0xb4, 0x8e, 0x1d, 0xb8, 0xf2, 0x46, 0xf4, 0xbf, 0x61, 0xbc, 0x44, 0xbd, 0x92, 0xa6, 0x9e, 0xba, 0xf2, 0x51, 0x39, 0x35, 0x0f, 0x73, 0xd4, 0xdb, 0x7e, 0x9b, 0x09, 0x18, - [1689679303.602072][52705:52705] CHIP:DMG: ] (242 bytes) - [1689679303.602075][52705:52705] CHIP:DMG: 0x1 = [ - [1689679303.602083][52705:52705] CHIP:DMG: 0x2e, 0xe3, 0xdb, 0x40, 0x0d, 0x01, 0x85, 0x43, 0xd9, 0x9c, 0x55, 0x61, 0xa6, 0xf6, 0x46, 0xea, 0xe5, 0xf8, 0xbe, 0xbb, 0x44, 0x89, 0x74, 0x0f, 0xf6, 0x98, 0x2c, 0x72, 0x25, 0x39, 0x79, 0x32, 0xf3, 0x73, 0x7a, 0xf0, 0xfd, 0xfb, 0xb7, 0x63, 0xa0, 0x73, 0xe4, 0xad, 0x11, 0x2d, 0xa3, 0x9b, 0xa6, 0x36, 0x1d, 0x85, 0x2b, 0xf2, 0x56, 0x2a, 0x80, 0xb5, 0x62, 0xf8, 0x10, 0xa8, 0x4a, 0x05, - [1689679303.602087][52705:52705] CHIP:DMG: ] (64 bytes) - [1689679303.602090][52705:52705] CHIP:DMG: }, - [1689679303.602095][52705:52705] CHIP:DMG: }, - [1689679303.602100][52705:52705] CHIP:DMG: - [1689679303.602102][52705:52705] CHIP:DMG: }, - [1689679303.602106][52705:52705] CHIP:DMG: - [1689679303.602108][52705:52705] CHIP:DMG: ], - [1689679303.602112][52705:52705] CHIP:DMG: - [1689679303.602114][52705:52705] CHIP:DMG: InteractionModelRevision = 1 - [1689679303.602116][52705:52705] CHIP:DMG: }, - [1689679303.602118][52705:52705] CHIP:DMG: - [1689679303.602124][52705:52705] CHIP:DMG: Additional Fields = - [1689679303.602126][52705:52705] CHIP:DMG: { - [1689679303.602128][52705:52705] CHIP:DMG: peer_address = UDP:[fe80::df9b:2ab4:71bf:d31b%wlp0s20f3]:33479 - [1689679303.602131][52705:52705] CHIP:DMG: } - [1689679303.602135][52705:52705] CHIP:DMG: - [1689679303.602146][52705:52705] CHIP:EM: <<< [E:36147r S:3817 M:151581351 (Ack:135880643)] (S) Msg TX to 0:FFFFFFFB00000000 [0000] --- Type 0001:09 (IM:InvokeCommandResponse) + [1720691676.080] [2537:2537] [DMG] } + [1720691676.080] [2537:2537] [DMG] + [1720691676.080] [2537:2537] [DMG] InvokeResponseMessage = + [1720691676.080] [2537:2537] [DMG] { + [1720691676.080] [2537:2537] [DMG] suppressResponse = false, + [1720691676.080] [2537:2537] [DMG] InvokeResponseIBs = + [1720691676.080] [2537:2537] [DMG] [ + [1720691676.080] [2537:2537] [DMG] InvokeResponseIB = + [1720691676.080] [2537:2537] [DMG] { + [1720691676.080] [2537:2537] [DMG] CommandDataIB = + [1720691676.080] [2537:2537] [DMG] { + [1720691676.080] [2537:2537] [DMG] CommandPathIB = + [1720691676.080] [2537:2537] [DMG] { + [1720691676.080] [2537:2537] [DMG] EndpointId = 0x0, + [1720691676.080] [2537:2537] [DMG] ClusterId = 0x3e, + [1720691676.080] [2537:2537] [DMG] CommandId = 0x5, + [1720691676.080] [2537:2537] [DMG] }, + [1720691676.080] [2537:2537] [DMG] + [1720691676.080] [2537:2537] [DMG] CommandFields = + [1720691676.080] [2537:2537] [DMG] { + [1720691676.080] [2537:2537] [DMG] 0x0 = [ + [1720691676.081] [2537:2537] [DMG] 0x15, 0x30, 0x01, 0xcb, 0x30, 0x81, 0xc8, 0x30, 0x70, 0x02, 0x01, 0x00, 0x30, 0x0e, 0x31, 0x0c, 0x30, 0x0a, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x03, 0x43, 0x53, 0x52, 0x30, 0x59, 0x30, 0x13, 0x06, 0x07, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x02, 0x01, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, 0x03, 0x42, 0x00, 0x04, 0x4a, 0x27, 0x03, 0x45, 0xab, 0x21, 0x9a, 0xd8, 0x7b, 0x15, 0xd3, 0x01, 0x9b, 0x53, 0x79, 0x13, 0xf9, 0xb4, 0x14, 0x1b, 0x65, 0x08, 0x6f, 0x20, 0x31, 0x0e, 0x9c, 0x6b, 0xeb, 0x10, 0xe1, 0xd1, 0xbb, 0x6c, 0x38, 0x40, 0x8a, 0x4e, 0x30, 0x60, 0xe5, 0x21, 0xec, 0x23, 0xd0, 0x03, 0x22, 0x3a, 0xaf, 0x91, 0xbe, 0x2b, 0x0d, 0x4a, 0xba, 0x01, 0xd5, 0x93, 0x6f, 0x28, 0xe4, 0xe4, 0x72, 0xb0, 0xa0, 0x00, 0x30, 0x0a, 0x06, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x04, 0x03, 0x02, 0x03, 0x48, 0x00, 0x30, 0x45, 0x02, 0x21, 0x00, 0xc7, 0x4c, 0x41, 0x05, 0x13, 0x56, 0x6f, 0x30, 0x79, 0x69, 0x0f, 0xa1, 0xd8, 0xab, 0xe9, 0xdf, 0x58, 0xc0, 0xfc, 0x60, 0xcf, 0xaf, 0x5d, 0x70, 0x4d, 0xbd, 0xfd, 0x2a, 0x8d, 0xb9, 0xac, 0x46, 0x02, 0x20, 0x6b, 0x31, 0x52, 0x1e, 0x08, 0x40, 0xb2, 0xb2, 0x3e, 0x2c, 0x36, 0xf1, 0x5b, 0x6b, 0x2c, 0xa4, 0x1c, 0x04, 0x1e, 0x02, 0x17, 0xfd, 0x19, 0xb5, 0xf6, 0x4f, 0x78, 0x70, 0xb2, 0x41, 0x59, 0x6d, 0x30, 0x02, 0x20, 0x37, 0x35, 0x3c, 0x15, 0x6d, 0xff, 0x31, 0xa0, 0x1d, 0xf3, 0xe1, 0x59, 0xa0, 0x38, 0x5d, 0xe7, 0x66, 0xd3, 0xfb, 0x98, 0x07, 0x05, 0x91, 0x85, 0x94, 0xed, 0xeb, 0x19, 0xf5, 0x04, 0x12, 0x40, 0x18, + [1720691676.081] [2537:2537] [DMG] ] (243 bytes) + [1720691676.081] [2537:2537] [DMG] 0x1 = [ + [1720691676.081] [2537:2537] [DMG] 0x28, 0x81, 0x0e, 0xea, 0x95, 0x32, 0x04, 0x6b, 0xec, 0x7c, 0x1b, 0xb2, 0x43, 0xbb, 0x72, 0x99, 0x1d, 0x82, 0xcf, 0xfd, 0x68, 0x6e, 0x6e, 0xec, 0x5b, 0xb4, 0x4e, 0x0b, 0x47, 0x7d, 0x06, 0xdf, 0x4a, 0xbe, 0x6f, 0xd4, 0x62, 0xfa, 0xbd, 0x6d, 0x8a, 0x85, 0xe0, 0xe7, 0x6b, 0x16, 0xa9, 0xf0, 0xe1, 0xaa, 0x9a, 0x96, 0xe3, 0x1c, 0x3c, 0xd6, 0x1e, 0xbf, 0x95, 0xc3, 0xd6, 0xaa, 0xa0, 0x19, + [1720691676.081] [2537:2537] [DMG] ] (64 bytes) + [1720691676.081] [2537:2537] [DMG] }, + [1720691676.081] [2537:2537] [DMG] }, + [1720691676.081] [2537:2537] [DMG] + [1720691676.081] [2537:2537] [DMG] }, + [1720691676.081] [2537:2537] [DMG] + [1720691676.081] [2537:2537] [DMG] ], + [1720691676.081] [2537:2537] [DMG] + [1720691676.081] [2537:2537] [DMG] InteractionModelRevision = 11 + [1720691676.081] [2537:2537] [DMG] }, + [1720691676.081] [2537:2537] [DMG] + [1720691676.081] [2537:2537] [DMG] Additional Fields = + [1720691676.081] [2537:2537] [DMG] { + [1720691676.081] [2537:2537] [DMG] peer_address = UDP:[fe80::e65f:1ff:fe49:ae1a%eth0]:36167 + [1720691676.081] [2537:2537] [DMG] } + [1720691676.081] [2537:2537] [DMG] + [1720691676.081] [2537:2537] [EM] <<< [E:41768r S:27758 M:113637243 (Ack:74843056)] (S) Msg TX to 0:FFFFFFFB00000000 [0000] [UDP:[fe80::e65f:1ff:fe49:ae1a%eth0]:36167] --- Type 0001 disabled: true - label: @@ -545,25 +348,46 @@ tests: verification: | Verify that the TH (all-clusters-app) receives AddTrustedRootCertificate command from DUT in commissioning log - [1689679303.611362][52705:52705] CHIP:ZCL: OpCreds: Received an AddTrustedRootCertificate command - [1689679303.611456][52705:52705] CHIP:DMG: >> to UDP:[fe80::df9b:2ab4:71bf:d31b%wlp0s20f3]:33479 | 151581352 | [Secure Channel (0) / Standalone Ack (0x10) / Session = 47827 / Exchange = 36148] - [1689679303.611465][52705:52705] CHIP:DMG: Header Flags = - [1689679303.611468][52705:52705] CHIP:DMG: { - [1689679303.611475][52705:52705] CHIP:DMG: Exchange (0x02) = - [1689679303.611478][52705:52705] CHIP:DMG: { - [1689679303.611482][52705:52705] CHIP:DMG: AckMsg = 135880645 - [1689679303.611486][52705:52705] CHIP:DMG: } - [1689679303.611492][52705:52705] CHIP:DMG: } - [1689679303.611496][52705:52705] CHIP:DMG: - [1689679303.611501][52705:52705] CHIP:DMG: Additional Fields = - [1689679303.611504][52705:52705] CHIP:DMG: { - [1689679303.611506][52705:52705] CHIP:DMG: peer_address = UDP:[fe80::df9b:2ab4:71bf:d31b%wlp0s20f3]:33479 - [1689679303.611509][52705:52705] CHIP:DMG: } - [1689679303.611512][52705:52705] CHIP:DMG: - [1689679303.611528][52705:52705] CHIP:EM: <<< [E:36148r S:3817 M:151581352 (Ack:135880645)] (S) Msg TX to 0:FFFFFFFB00000000 [0000] --- Type 0000:10 (SecureChannel:StandaloneAck) - [1689679303.611536][52705:52705] CHIP:IN: (S) Sending msg 151581352 on secure session with LSID: 3817 - [1689679303.611568][52705:52705] CHIP:EM: Flushed pending ack for MessageCounter:135880645 on exchange 36148r - [1689679303.611820][52705:52705] CHIP:ZCL: OpCreds: AddTrustedRootCertificate successful. + [1720691676.098] [2537:2537] [DMG] Additional Fields = + [1720691676.098] [2537:2537] [DMG] { + [1720691676.098] [2537:2537] [DMG] peer_address = UDP:[fe80::e65f:1ff:fe49:ae1a%eth0]:36167 + [1720691676.098] [2537:2537] [DMG] } + [1720691676.098] [2537:2537] [DMG] + [1720691676.098] [2537:2537] [EM] >>> [E:41769r S:27758 M:74843058] (S) Msg RX from 0:FFFFFFFB00000000 [0000] --- Type 0001:08 (IM:InvokeCommandRequest) + [1720691676.098] [2537:2537] [EM] Handling via exchange: 41769r, Delegate: 0xaaaad99c9368 + [1720691676.098] [2537:2537] [DMG] InvokeRequestMessage = + [1720691676.098] [2537:2537] [DMG] { + [1720691676.098] [2537:2537] [DMG] suppressResponse = false, + [1720691676.098] [2537:2537] [DMG] timedRequest = false, + [1720691676.098] [2537:2537] [DMG] InvokeRequests = + [1720691676.098] [2537:2537] [DMG] [ + [1720691676.098] [2537:2537] [DMG] CommandDataIB = + [1720691676.098] [2537:2537] [DMG] { + [1720691676.099] [2537:2537] [DMG] CommandPathIB = + [1720691676.099] [2537:2537] [DMG] { + [1720691676.099] [2537:2537] [DMG] EndpointId = 0x0, + [1720691676.099] [2537:2537] [DMG] ClusterId = 0x3e, + [1720691676.099] [2537:2537] [DMG] CommandId = 0xb, + [1720691676.099] [2537:2537] [DMG] }, + [1720691676.099] [2537:2537] [DMG] + [1720691676.099] [2537:2537] [DMG] CommandFields = + [1720691676.099] [2537:2537] [DMG] { + [1720691676.099] [2537:2537] [DMG] 0x0 = [ + [1720691676.099] [2537:2537] [DMG] 0x15, 0x30, 0x01, 0x01, 0x01, 0x24, 0x02, 0x01, 0x37, 0x03, 0x24, 0x14, 0x01, 0x18, 0x26, 0x04, 0x80, 0x22, 0x81, 0x27, 0x26, 0x05, 0x80, 0x25, 0x4d, 0x3a, 0x37, 0x06, 0x24, 0x14, 0x01, 0x18, 0x24, 0x07, 0x01, 0x24, 0x08, 0x01, 0x30, 0x09, 0x41, 0x04, 0x2b, 0xa1, 0xae, 0xdb, 0x8f, 0xcf, 0xbd, 0xfe, 0xb1, 0xeb, 0xd4, 0xb7, 0xe1, 0x77, 0xba, 0x69, 0x59, 0xaa, 0xc4, 0x26, 0xe4, 0x90, 0xe9, 0x40, 0xbb, 0xc0, 0x69, 0xab, 0x3e, 0xcb, 0x5f, 0x11, 0x97, 0xe4, 0x67, 0x75, 0x5d, 0x4a, 0x82, 0x8f, 0xc2, 0x50, 0x82, 0x34, 0xea, 0xbf, 0xc0, 0x46, 0x7f, 0x2d, 0x60, 0x22, 0x4d, 0x33, 0xa2, 0xde, 0x3f, 0xa3, 0x30, 0xba, 0x1f, 0x6c, 0xdf, 0x23, 0x37, 0x0a, 0x35, 0x01, 0x29, 0x01, 0x18, 0x24, 0x02, 0x60, 0x30, 0x04, 0x14, 0x24, 0x54, 0xc7, 0x22, 0x5b, 0x7e, 0x25, 0x9a, 0x9f, 0xee, 0x54, 0x91, 0x23, 0x43, 0x28, 0xfd, 0x15, 0x49, 0x0e, 0xa8, 0x30, 0x05, 0x14, 0x24, 0x54, 0xc7, 0x22, 0x5b, 0x7e, 0x25, 0x9a, 0x9f, 0xee, 0x54, 0x91, 0x23, 0x43, 0x28, 0xfd, 0x15, 0x49, 0x0e, 0xa8, 0x18, 0x30, 0x0b, 0x40, 0xcc, 0x32, 0x98, 0xc2, 0x30, 0xe6, 0x45, 0xf2, 0x1f, 0x51, 0x6c, 0xe1, 0xf5, 0xc0, 0x3e, 0xb1, 0x59, 0xd1, 0xf9, 0x5e, 0x64, 0x6f, 0xfd, 0x1f, 0xf8, 0x6d, 0x09, 0x7f, 0x7f, 0xc9, 0x48, 0xe8, 0xde, 0x72, 0x88, 0xd6, 0x6e, 0xe1, 0x74, 0x33, 0x76, 0xc4, 0x64, 0xfc, 0xb6, 0xbc, 0xd7, 0x73, 0xe1, 0xc4, 0x2f, 0x3a, 0xa6, 0xa5, 0xc3, 0x13, 0xbb, 0xdf, 0xfc, 0xe7, 0x92, 0xc6, 0x45, 0x0f, 0x18, + [1720691676.099] [2537:2537] [DMG] ] (231 bytes) + [1720691676.099] [2537:2537] [DMG] }, + [1720691676.099] [2537:2537] [DMG] }, + [1720691676.099] [2537:2537] [DMG] + [1720691676.099] [2537:2537] [DMG] ], + [1720691676.099] [2537:2537] [DMG] + [1720691676.099] [2537:2537] [DMG] InteractionModelRevision = 11 + [1720691676.099] [2537:2537] [DMG] }, + [1720691676.099] [2537:2537] [DMG] AccessControl: checking f=0 a=p s=0xFFFFFFFB00000000 t= c=0x0000_003E e=0 p=a + [1720691676.099] [2537:2537] [DMG] AccessControl: implicit admin (PASE) + [1720691676.099] [2537:2537] [DMG] Received command for Endpoint=0 Cluster=0x0000_003E Command=0x0000_000B + [1720691676.099] [2537:2537] [ZCL] OpCreds: Received an AddTrustedRootCertificate command + [1720691676.100] [2537:2537] [DMG] >> to UDP:[fe80::e65f:1ff:fe49:ae1a%eth0]:36167 | 113637244 | [Secure Channel (0) / Standalone Ack (0x10) / Session = 38450 / Exchange = 41769] + [1720691676.100] [2537:2537] [DMG] Header Flags = disabled: true - label: "Step 7a: Verify that TH receives AddNOC Command from DUT" @@ -571,26 +395,49 @@ tests: verification: | Verify that the TH (all-clusters-app) receives AddNOC command from DUT in commissioning log - [1689679303.613590][52705:52705] CHIP:ZCL: OpCreds: Received an AddNOC command - [1689679303.613687][52705:52705] CHIP:DMG: >> to UDP:[fe80::df9b:2ab4:71bf:d31b%wlp0s20f3]:33479 | 151581354 | [Secure Channel (0) / Standalone Ack (0x10) / Session = 47827 / Exchange = 36149] - [1689679303.613696][52705:52705] CHIP:DMG: Header Flags = - [1689679303.613699][52705:52705] CHIP:DMG: { - [1689679303.613707][52705:52705] CHIP:DMG: Exchange (0x02) = - [1689679303.613710][52705:52705] CHIP:DMG: { - [1689679303.613714][52705:52705] CHIP:DMG: AckMsg = 135880647 - [1689679303.613717][52705:52705] CHIP:DMG: } - [1689679303.613723][52705:52705] CHIP:DMG: } - [1689679303.613726][52705:52705] CHIP:DMG: - [1689679303.613733][52705:52705] CHIP:DMG: Additional Fields = - [1689679303.613737][52705:52705] CHIP:DMG: { - [1689679303.613741][52705:52705] CHIP:DMG: peer_address = UDP:[fe80::df9b:2ab4:71bf:d31b%wlp0s20f3]:33479 - [1689679303.613744][52705:52705] CHIP:DMG: } - [1689679303.613747][52705:52705] CHIP:DMG: - [1689679303.613760][52705:52705] CHIP:EM: <<< [E:36149r S:3817 M:151581354 (Ack:135880647)] (S) Msg TX to 0:FFFFFFFB00000000 [0000] --- Type 0000:10 (SecureChannel:StandaloneAck) - [1689679303.613767][52705:52705] CHIP:IN: (S) Sending msg 151581354 on secure session with LSID: 3817 - [1689679303.613791][52705:52705] CHIP:EM: Flushed pending ack for MessageCounter:135880647 on exchange 36149r - [1689679303.613883][52705:52705] CHIP:FP: Validating NOC chain - [1689679303.614555][52705:52705] CHIP:FP: NOC chain validation successful + [1720691676.111] [2537:2537] [EM] >>> [E:41770r S:27758 M:74843060] (S) Msg RX from 0:FFFFFFFB00000000 [0000] --- Type 0001:08 (IM:InvokeCommandRequest) + [1720691676.111] [2537:2537] [EM] Handling via exchange: 41770r, Delegate: 0xaaaad99c9368 + [1720691676.111] [2537:2537] [DMG] InvokeRequestMessage = + [1720691676.111] [2537:2537] [DMG] { + [1720691676.111] [2537:2537] [DMG] suppressResponse = false, + [1720691676.111] [2537:2537] [DMG] timedRequest = false, + [1720691676.111] [2537:2537] [DMG] InvokeRequests = + [1720691676.111] [2537:2537] [DMG] [ + [1720691676.111] [2537:2537] [DMG] CommandDataIB = + [1720691676.111] [2537:2537] [DMG] { + [1720691676.111] [2537:2537] [DMG] CommandPathIB = + [1720691676.111] [2537:2537] [DMG] { + [1720691676.111] [2537:2537] [DMG] EndpointId = 0x0, + [1720691676.111] [2537:2537] [DMG] ClusterId = 0x3e, + [1720691676.111] [2537:2537] [DMG] CommandId = 0x6, + [1720691676.111] [2537:2537] [DMG] }, + [1720691676.111] [2537:2537] [DMG] + [1720691676.111] [2537:2537] [DMG] CommandFields = + [1720691676.111] [2537:2537] [DMG] { + [1720691676.111] [2537:2537] [DMG] 0x0 = [ + [1720691676.111] [2537:2537] [DMG] 0x15, 0x30, 0x01, 0x01, 0x01, 0x24, 0x02, 0x01, 0x37, 0x03, 0x24, 0x13, 0x02, 0x18, 0x26, 0x04, 0x80, 0x22, 0x81, 0x27, 0x26, 0x05, 0x80, 0x25, 0x4d, 0x3a, 0x37, 0x06, 0x24, 0x15, 0x01, 0x24, 0x11, 0x01, 0x18, 0x24, 0x07, 0x01, 0x24, 0x08, 0x01, 0x30, 0x09, 0x41, 0x04, 0x4a, 0x27, 0x03, 0x45, 0xab, 0x21, 0x9a, 0xd8, 0x7b, 0x15, 0xd3, 0x01, 0x9b, 0x53, 0x79, 0x13, 0xf9, 0xb4, 0x14, 0x1b, 0x65, 0x08, 0x6f, 0x20, 0x31, 0x0e, 0x9c, 0x6b, 0xeb, 0x10, 0xe1, 0xd1, 0xbb, 0x6c, 0x38, 0x40, 0x8a, 0x4e, 0x30, 0x60, 0xe5, 0x21, 0xec, 0x23, 0xd0, 0x03, 0x22, 0x3a, 0xaf, 0x91, 0xbe, 0x2b, 0x0d, 0x4a, 0xba, 0x01, 0xd5, 0x93, 0x6f, 0x28, 0xe4, 0xe4, 0x72, 0xb0, 0x37, 0x0a, 0x35, 0x01, 0x28, 0x01, 0x18, 0x24, 0x02, 0x01, 0x36, 0x03, 0x04, 0x02, 0x04, 0x01, 0x18, 0x30, 0x04, 0x14, 0xc5, 0x8c, 0xaa, 0x91, 0x3e, 0x06, 0x86, 0xb4, 0x91, 0xd2, 0x34, 0x99, 0xeb, 0xe3, 0x8b, 0x10, 0x7f, 0xa1, 0x7d, 0x86, 0x30, 0x05, 0x14, 0x09, 0x03, 0x79, 0xf4, 0x13, 0xa2, 0xde, 0xe5, 0x49, 0x95, 0x8f, 0xd8, 0x79, 0x95, 0xea, 0xf9, 0xcf, 0xc6, 0x34, 0x24, 0x18, 0x30, 0x0b, 0x40, 0x17, 0x0c, 0x5f, 0x4f, 0xdb, 0x33, 0x79, 0x62, 0xd8, 0x53, 0x13, 0x84, 0x2e, 0xc8, 0xd6, 0x44, 0x62, 0x5a, 0x88, 0x16, 0x7d, 0xa9, 0xc8, 0xcb, 0x69, 0x58, 0xaa, 0x6d, 0x24, 0x37, 0x6e, 0xdf, 0x78, 0x73, 0x7f, 0x55, 0x41, 0xac, 0xe9, 0xff, 0x01, 0xe9, 0xcb, 0x94, 0xd4, 0xcf, 0x1f, 0x9a, 0x70, 0xc9, 0x42, 0xe6, 0xa9, 0x0a, 0x1a, 0xcb, 0x29, 0xb5, 0xf0, 0xab, 0x86, 0x19, 0xcf, 0xac, 0x18, + [1720691676.112] [2537:2537] [DMG] ] (241 bytes) + [1720691676.112] [2537:2537] [DMG] 0x1 = [ + [1720691676.112] [2537:2537] [DMG] 0x15, 0x30, 0x01, 0x01, 0x01, 0x24, 0x02, 0x01, 0x37, 0x03, 0x24, 0x14, 0x01, 0x18, 0x26, 0x04, 0x80, 0x22, 0x81, 0x27, 0x26, 0x05, 0x80, 0x25, 0x4d, 0x3a, 0x37, 0x06, 0x24, 0x13, 0x02, 0x18, 0x24, 0x07, 0x01, 0x24, 0x08, 0x01, 0x30, 0x09, 0x41, 0x04, 0x2a, 0xb1, 0xeb, 0xcb, 0xcc, 0x54, 0x41, 0xd4, 0xd9, 0xc6, 0x4e, 0x96, 0xe7, 0xa2, 0x2f, 0xd6, 0xd9, 0xa9, 0xdb, 0xd5, 0xdd, 0xb0, 0x41, 0xd5, 0x88, 0xc6, 0xd9, 0x2a, 0xd3, 0xe0, 0xbb, 0x20, 0x50, 0x77, 0x09, 0x9d, 0x77, 0x49, 0x5c, 0xa9, 0x6e, 0xae, 0x12, 0x61, 0x3f, 0x4a, 0x36, 0x74, 0x07, 0xfb, 0x71, 0xc9, 0x5f, 0x14, 0x10, 0x96, 0x53, 0xa1, 0xa1, 0x07, 0x67, 0x24, 0x9b, 0xfc, 0x37, 0x0a, 0x35, 0x01, 0x29, 0x01, 0x18, 0x24, 0x02, 0x60, 0x30, 0x04, 0x14, 0x09, 0x03, 0x79, 0xf4, 0x13, 0xa2, 0xde, 0xe5, 0x49, 0x95, 0x8f, 0xd8, 0x79, 0x95, 0xea, 0xf9, 0xcf, 0xc6, 0x34, 0x24, 0x30, 0x05, 0x14, 0x24, 0x54, 0xc7, 0x22, 0x5b, 0x7e, 0x25, 0x9a, 0x9f, 0xee, 0x54, 0x91, 0x23, 0x43, 0x28, 0xfd, 0x15, 0x49, 0x0e, 0xa8, 0x18, 0x30, 0x0b, 0x40, 0xde, 0xc8, 0x17, 0xaa, 0x07, 0xa8, 0x60, 0xdc, 0xfb, 0x62, 0xc2, 0xf4, 0x70, 0x05, 0x4d, 0xc0, 0xa5, 0x1a, 0xf3, 0xd0, 0xe6, 0x7e, 0xa4, 0x5d, 0x1e, 0x24, 0x83, 0x5c, 0xb6, 0x89, 0x5d, 0x77, 0x68, 0xef, 0x6e, 0xdf, 0xf8, 0xfb, 0x70, 0xa3, 0x84, 0xf1, 0x3d, 0xa5, 0x81, 0xb6, 0x83, 0x1b, 0x7c, 0x7f, 0x4f, 0x5d, 0x77, 0xfe, 0xc7, 0xd5, 0x29, 0x8a, 0xf0, 0x5b, 0xd6, 0x32, 0xf7, 0x76, 0x18, + [1720691676.112] [2537:2537] [DMG] ] (231 bytes) + [1720691676.112] [2537:2537] [DMG] 0x2 = [ + [1720691676.112] [2537:2537] [DMG] 0x74, 0x65, 0x6d, 0x70, 0x6f, 0x72, 0x61, 0x72, 0x79, 0x20, 0x69, 0x70, 0x6b, 0x20, 0x30, 0x31, + [1720691676.112] [2537:2537] [DMG] ] (16 bytes) + [1720691676.112] [2537:2537] [DMG] 0x3 = 112233 (unsigned), + [1720691676.112] [2537:2537] [DMG] 0x4 = 65521 (unsigned), + [1720691676.112] [2537:2537] [DMG] }, + [1720691676.112] [2537:2537] [DMG] }, + [1720691676.112] [2537:2537] [DMG] + [1720691676.112] [2537:2537] [DMG] ], + [1720691676.112] [2537:2537] [DMG] + [1720691676.112] [2537:2537] [DMG] InteractionModelRevision = 11 + [1720691676.112] [2537:2537] [DMG] }, + [1720691676.112] [2537:2537] [DMG] AccessControl: checking f=0 a=p s=0xFFFFFFFB00000000 t= c=0x0000_003E e=0 p=a + [1720691676.112] [2537:2537] [DMG] AccessControl: implicit admin (PASE) + [1720691676.112] [2537:2537] [DMG] Received command for Endpoint=0 Cluster=0x0000_003E Command=0x0000_0006 + [1720691676.112] [2537:2537] [ZCL] OpCreds: Received an AddNOC command + [1720691676.113] [2537:2537] [DMG] >> to UDP:[fe80::e65f:1ff:fe49:ae1a%eth0]:36167 | 113637246 | [Secure Channel (0) / Standalone Ack (0x10) / Session = 38450 / Exchange = 41770] + [1720691676.113] [2537:2537] [DMG] Header Flags = disabled: true - label: @@ -620,7 +467,7 @@ tests: Example: 0x2 = [ - [1689679303.613506][52705:52705] CHIP:DMG: 0x74, 0x65, 0x6d, 0x70, 0x6f, 0x72, 0x61, 0x72, 0x79, 0x20, 0x69, 0x70, 0x6b, 0x20, 0x30, 0x31, + [1689679303.613506][52705:52705] CHIP:DMG: 0x74, 0x65, 0x6d, 0x70, 0x6f, 0x72, 0x61, 0x72, 0x79, 0x20, 0x69, 0x70, 0x6b, 0x20, 0x30, 0x31, 4. CaseAdminSubject as caseadmin1 Example: @@ -646,43 +493,49 @@ tests: 4. NodeID 5. Label - [1689681605.068131][52705:52705] CHIP:DMG: ReportDataMessage = - [1689681605.068135][52705:52705] CHIP:DMG: { - [1689681605.068138][52705:52705] CHIP:DMG: AttributeReportIBs = - [1689681605.068146][52705:52705] CHIP:DMG: [ - [1689681605.068149][52705:52705] CHIP:DMG: AttributeReportIB = - [1689681605.068156][52705:52705] CHIP:DMG: { - [1689681605.068160][52705:52705] CHIP:DMG: AttributeDataIB = - [1689681605.068164][52705:52705] CHIP:DMG: { - [1689681605.068169][52705:52705] CHIP:DMG: DataVersion = 0x65bf1426, - [1689681605.068174][52705:52705] CHIP:DMG: AttributePathIB = - [1689681605.068178][52705:52705] CHIP:DMG: { - [1689681605.068183][52705:52705] CHIP:DMG: Endpoint = 0x0, - [1689681605.068188][52705:52705] CHIP:DMG: Cluster = 0x3e, - [1689681605.068193][52705:52705] CHIP:DMG: Attribute = 0x0000_0001, - [1689681605.068198][52705:52705] CHIP:DMG: } - [1689681605.068202][52705:52705] CHIP:DMG: - [1689681605.068207][52705:52705] CHIP:DMG: Data = [ - [1689681605.068211][52705:52705] CHIP:DMG: - [1689681605.068216][52705:52705] CHIP:DMG: { - [1689681605.068220][52705:52705] CHIP:DMG: 0x1 = [ - [1689681605.068229][52705:52705] CHIP:DMG: 0x04, 0x8e, 0x70, 0xf4, 0x2e, 0xcb, 0xad, 0x8a, 0xc7, 0x98, 0x04, 0xa7, 0x5e, 0x1e, 0xe8, 0x33, 0xc8, 0x33, 0xb0, 0x76, 0xd9, 0x02, 0x93, 0x0a, 0x79, 0xff, 0xc3, 0xcd, 0x26, 0x78, 0xa9, 0xf6, 0xe8, 0xfe, 0xe8, 0x8b, 0x72, 0x3e, 0x31, 0x4e, 0x8e, 0xd7, 0x63, 0x7d, 0x9e, 0x90, 0x73, 0x20, 0x71, 0x1b, 0xbf, 0xfd, 0x1c, 0xc0, 0x8c, 0x4d, 0x6f, 0xb8, 0x75, 0x5f, 0xcb, 0x41, 0xef, 0x96, 0xb9, - [1689681605.068235][52705:52705] CHIP:DMG: ] (65 bytes) - [1689681605.068239][52705:52705] CHIP:DMG: 0x2 = 65521, - [1689681605.068244][52705:52705] CHIP:DMG: 0x3 = 1, - [1689681605.068248][52705:52705] CHIP:DMG: 0x4 = 1, - [1689681605.068253][52705:52705] CHIP:DMG: 0x5 = "" (0 chars), - [1689681605.068257][52705:52705] CHIP:DMG: 0xfe = 1, - [1689681605.068263][52705:52705] CHIP:DMG: }, - [1689681605.068266][52705:52705] CHIP:DMG: ], - [1689681605.068270][52705:52705] CHIP:DMG: }, - [1689681605.068276][52705:52705] CHIP:DMG: - [1689681605.068279][52705:52705] CHIP:DMG: }, - [1689681605.068284][52705:52705] CHIP:DMG: - [1689681605.068287][52705:52705] CHIP:DMG: ], - [1689681605.068292][52705:52705] CHIP:DMG: - [1689681605.068295][52705:52705] CHIP:DMG: SuppressResponse = true, - [1689681605.068297][52705:52705] CHIP:DMG: InteractionModelRevision = 1 + [1720690525.192] [2401:2401] [DMG] + [1720690525.192] [2401:2401] [DMG] ReportDataMessage = + [1720690525.192] [2401:2401] [DMG] { + [1720690525.192] [2401:2401] [DMG] AttributeReportIBs = + [1720690525.192] [2401:2401] [DMG] [ + [1720690525.192] [2401:2401] [DMG] AttributeReportIB = + [1720690525.192] [2401:2401] [DMG] { + [1720690525.192] [2401:2401] [DMG] AttributeDataIB = + [1720690525.192] [2401:2401] [DMG] { + [1720690525.192] [2401:2401] [DMG] DataVersion = 0x3aff7739, + [1720690525.192] [2401:2401] [DMG] AttributePathIB = + [1720690525.192] [2401:2401] [DMG] { + [1720690525.192] [2401:2401] [DMG] Endpoint = 0x0, + [1720690525.192] [2401:2401] [DMG] Cluster = 0x3e, + [1720690525.192] [2401:2401] [DMG] Attribute = 0x0000_0001, + [1720690525.192] [2401:2401] [DMG] } + [1720690525.192] [2401:2401] [DMG] + [1720690525.192] [2401:2401] [DMG] Data = [ + [1720690525.192] [2401:2401] [DMG] + [1720690525.192] [2401:2401] [DMG] { + [1720690525.192] [2401:2401] [DMG] 0x1 = [ + [1720690525.193] [2401:2401] [DMG] 0x04, 0x6b, 0xc8, 0xe7, 0x50, 0x37, 0x5e, 0xb5, 0xc9, 0xc8, 0xf3, 0x0a, 0x8b, 0x1e, 0xcc, 0xc9, 0x97, 0xfe, 0x26, 0xec, 0xb6, 0x23, 0xa6, 0x04, 0xf0, 0xaa, 0x78, 0xd2, 0xc4, 0x40, 0x73, 0xc9, 0x3b, 0x21, 0xbd, 0xd9, 0x28, 0xb6, 0x09, 0x0b, 0xa9, 0x60, 0xa3, 0x7d, 0xe5, 0xa0, 0x63, 0x44, 0x2f, 0x37, 0xf3, 0x80, 0x1c, 0xea, 0xaf, 0x48, 0xb4, 0x87, 0x08, 0xf8, 0xee, 0x1f, 0x0f, 0xab, 0xab, + [1720690525.193] [2401:2401] [DMG] ] (65 bytes) + [1720690525.193] [2401:2401] [DMG] 0x2 = 65521 (unsigned), + [1720690525.193] [2401:2401] [DMG] 0x3 = 1 (unsigned), + [1720690525.193] [2401:2401] [DMG] 0x4 = 1 (unsigned), + [1720690525.193] [2401:2401] [DMG] 0x5 = "" (0 chars), + [1720690525.193] [2401:2401] [DMG] 0xfe = 1 (unsigned), + [1720690525.193] [2401:2401] [DMG] }, + [1720690525.193] [2401:2401] [DMG] ], + [1720690525.193] [2401:2401] [DMG] }, + [1720690525.193] [2401:2401] [DMG] + [1720690525.193] [2401:2401] [DMG] }, + [1720690525.193] [2401:2401] [DMG] + [1720690525.193] [2401:2401] [DMG] ], + [1720690525.193] [2401:2401] [DMG] + [1720690525.193] [2401:2401] [DMG] SuppressResponse = true, + [1720690525.193] [2401:2401] [DMG] InteractionModelRevision = 11 + [1720690525.193] [2401:2401] [DMG] } + [1720690525.193] [2401:2401] [DMG] + [1720690525.193] [2401:2401] [DMG] Additional Fields = + [1720690525.193] [2401:2401] [DMG] { + [1720690525.193] [2401:2401] [DMG] peer_address = UDP:[fe80::e65f:1ff:fe49:ae1a%eth0]:45224 disabled: true - label: @@ -702,43 +555,49 @@ tests: 4. Verify the FabricID (0x4) is same as matter-fabric-id 5. Verify the size of Label is maximum of 32 bytes - [1689681605.068131][52705:52705] CHIP:DMG: ReportDataMessage = - [1689681605.068135][52705:52705] CHIP:DMG: { - [1689681605.068138][52705:52705] CHIP:DMG: AttributeReportIBs = - [1689681605.068146][52705:52705] CHIP:DMG: [ - [1689681605.068149][52705:52705] CHIP:DMG: AttributeReportIB = - [1689681605.068156][52705:52705] CHIP:DMG: { - [1689681605.068160][52705:52705] CHIP:DMG: AttributeDataIB = - [1689681605.068164][52705:52705] CHIP:DMG: { - [1689681605.068169][52705:52705] CHIP:DMG: DataVersion = 0x65bf1426, - [1689681605.068174][52705:52705] CHIP:DMG: AttributePathIB = - [1689681605.068178][52705:52705] CHIP:DMG: { - [1689681605.068183][52705:52705] CHIP:DMG: Endpoint = 0x0, - [1689681605.068188][52705:52705] CHIP:DMG: Cluster = 0x3e, - [1689681605.068193][52705:52705] CHIP:DMG: Attribute = 0x0000_0001, - [1689681605.068198][52705:52705] CHIP:DMG: } - [1689681605.068202][52705:52705] CHIP:DMG: - [1689681605.068207][52705:52705] CHIP:DMG: Data = [ - [1689681605.068211][52705:52705] CHIP:DMG: - [1689681605.068216][52705:52705] CHIP:DMG: { - [1689681605.068220][52705:52705] CHIP:DMG: 0x1 = [ - [1689681605.068229][52705:52705] CHIP:DMG: 0x04, 0x8e, 0x70, 0xf4, 0x2e, 0xcb, 0xad, 0x8a, 0xc7, 0x98, 0x04, 0xa7, 0x5e, 0x1e, 0xe8, 0x33, 0xc8, 0x33, 0xb0, 0x76, 0xd9, 0x02, 0x93, 0x0a, 0x79, 0xff, 0xc3, 0xcd, 0x26, 0x78, 0xa9, 0xf6, 0xe8, 0xfe, 0xe8, 0x8b, 0x72, 0x3e, 0x31, 0x4e, 0x8e, 0xd7, 0x63, 0x7d, 0x9e, 0x90, 0x73, 0x20, 0x71, 0x1b, 0xbf, 0xfd, 0x1c, 0xc0, 0x8c, 0x4d, 0x6f, 0xb8, 0x75, 0x5f, 0xcb, 0x41, 0xef, 0x96, 0xb9, - [1689681605.068235][52705:52705] CHIP:DMG: ] (65 bytes) - [1689681605.068239][52705:52705] CHIP:DMG: 0x2 = 65521, - [1689681605.068244][52705:52705] CHIP:DMG: 0x3 = 1, - [1689681605.068248][52705:52705] CHIP:DMG: 0x4 = 1, - [1689681605.068253][52705:52705] CHIP:DMG: 0x5 = "" (0 chars), - [1689681605.068257][52705:52705] CHIP:DMG: 0xfe = 1, - [1689681605.068263][52705:52705] CHIP:DMG: }, - [1689681605.068266][52705:52705] CHIP:DMG: ], - [1689681605.068270][52705:52705] CHIP:DMG: }, - [1689681605.068276][52705:52705] CHIP:DMG: - [1689681605.068279][52705:52705] CHIP:DMG: }, - [1689681605.068284][52705:52705] CHIP:DMG: - [1689681605.068287][52705:52705] CHIP:DMG: ], - [1689681605.068292][52705:52705] CHIP:DMG: - [1689681605.068295][52705:52705] CHIP:DMG: SuppressResponse = true, - [1689681605.068297][52705:52705] CHIP:DMG: InteractionModelRevision = 1 + [1720690525.192] [2401:2401] [DMG] + [1720690525.192] [2401:2401] [DMG] ReportDataMessage = + [1720690525.192] [2401:2401] [DMG] { + [1720690525.192] [2401:2401] [DMG] AttributeReportIBs = + [1720690525.192] [2401:2401] [DMG] [ + [1720690525.192] [2401:2401] [DMG] AttributeReportIB = + [1720690525.192] [2401:2401] [DMG] { + [1720690525.192] [2401:2401] [DMG] AttributeDataIB = + [1720690525.192] [2401:2401] [DMG] { + [1720690525.192] [2401:2401] [DMG] DataVersion = 0x3aff7739, + [1720690525.192] [2401:2401] [DMG] AttributePathIB = + [1720690525.192] [2401:2401] [DMG] { + [1720690525.192] [2401:2401] [DMG] Endpoint = 0x0, + [1720690525.192] [2401:2401] [DMG] Cluster = 0x3e, + [1720690525.192] [2401:2401] [DMG] Attribute = 0x0000_0001, + [1720690525.192] [2401:2401] [DMG] } + [1720690525.192] [2401:2401] [DMG] + [1720690525.192] [2401:2401] [DMG] Data = [ + [1720690525.192] [2401:2401] [DMG] + [1720690525.192] [2401:2401] [DMG] { + [1720690525.192] [2401:2401] [DMG] 0x1 = [ + [1720690525.193] [2401:2401] [DMG] 0x04, 0x6b, 0xc8, 0xe7, 0x50, 0x37, 0x5e, 0xb5, 0xc9, 0xc8, 0xf3, 0x0a, 0x8b, 0x1e, 0xcc, 0xc9, 0x97, 0xfe, 0x26, 0xec, 0xb6, 0x23, 0xa6, 0x04, 0xf0, 0xaa, 0x78, 0xd2, 0xc4, 0x40, 0x73, 0xc9, 0x3b, 0x21, 0xbd, 0xd9, 0x28, 0xb6, 0x09, 0x0b, 0xa9, 0x60, 0xa3, 0x7d, 0xe5, 0xa0, 0x63, 0x44, 0x2f, 0x37, 0xf3, 0x80, 0x1c, 0xea, 0xaf, 0x48, 0xb4, 0x87, 0x08, 0xf8, 0xee, 0x1f, 0x0f, 0xab, 0xab, + [1720690525.193] [2401:2401] [DMG] ] (65 bytes) + [1720690525.193] [2401:2401] [DMG] 0x2 = 65521 (unsigned), + [1720690525.193] [2401:2401] [DMG] 0x3 = 1 (unsigned), + [1720690525.193] [2401:2401] [DMG] 0x4 = 1 (unsigned), + [1720690525.193] [2401:2401] [DMG] 0x5 = "" (0 chars), + [1720690525.193] [2401:2401] [DMG] 0xfe = 1 (unsigned), + [1720690525.193] [2401:2401] [DMG] }, + [1720690525.193] [2401:2401] [DMG] ], + [1720690525.193] [2401:2401] [DMG] }, + [1720690525.193] [2401:2401] [DMG] + [1720690525.193] [2401:2401] [DMG] }, + [1720690525.193] [2401:2401] [DMG] + [1720690525.193] [2401:2401] [DMG] ], + [1720690525.193] [2401:2401] [DMG] + [1720690525.193] [2401:2401] [DMG] SuppressResponse = true, + [1720690525.193] [2401:2401] [DMG] InteractionModelRevision = 11 + [1720690525.193] [2401:2401] [DMG] } + [1720690525.193] [2401:2401] [DMG] + [1720690525.193] [2401:2401] [DMG] Additional Fields = + [1720690525.193] [2401:2401] [DMG] { + [1720690525.193] [2401:2401] [DMG] peer_address = UDP:[fe80::e65f:1ff:fe49:ae1a%eth0]:45224 disabled: true - label: @@ -753,66 +612,32 @@ tests: verification: | During commissioning, Verify that UpdateNOC Command is received in TH (all-clusters-app) - [1689679303.613181][52705:52705] CHIP:DMG: { - [1689679303.613184][52705:52705] CHIP:DMG: data = 1528002801360215370024000024013e2402061835013000f11530010101240201370324130218260480228127260580254d3a37062415012411011824070124080130094104f294d4aa30dad41668bdb0e24ac0d830b0ba335c8877c5b60af62b985cff212395197314d3025963a4501b4acb8a2202eccc10ed657cff7fae8f9912b393c1cd370a350128011824020136030402040118300414b34d04681e4b091989a9a5f2bde11fdc5ecea94d300514c518cd9b17c67c4a0501f29e842d578a63d4c2be18300b4059ae97324240ad84e1aaf93ba0b0ec8e938b1408e8e4250ce53012dead0a7e9fc41c422b190ff18820d8440ba630e67c4ec9ddac66b10d723cbb5d050cb5256c183001e71530010101240201370324140118260480228127260580254d3a3706241302182407012408013009410450083b6a78969912e9b7ec753c00665af4231ee13e4362205dbc18f060654363fae48e0c5bd559809e2e083f54ba8a1ff6ab5ef1f8e07b55bde1be3de763efac370a3501290118240260300414c518cd9b17c67c4a0501f29e842d578a63d4c2be300514cf9b3f36437a3e7c8c8aeee80385260a4f4a6bf318300b408ab09e46ec4ab5e3c38af468366f0ce54517d33b7f23997dc6636271c31a5fde55f2de5f68613b6acc55ae0ea137b4f7e2b94e5e1a599eff5fa3b73a66dfdbd01830021074656d706f726172792069706b203031260369b601002504f1ff18181824ff0118 - [1689679303.613193][52705:52705] CHIP:DMG: } - [1689679303.613195][52705:52705] CHIP:DMG: - [1689679303.613238][52705:52705] CHIP:DMG: NOCValue (241) = - [1689679303.613248][52705:52705] CHIP:DMG: { - FTABAQEkAgE3AyQTAhgmBIAigScmBYAlTTo3BiQVASQRARgkBwEkCAEwCUEE8pTUqjDa1BZovbDiSsDYMLC6M1yId8W2CvYrmFz/ISOVGXMU0wJZY6RQG0rLiiIC7MwQ7WV8/3+uj5kSs5PBzTcKNQEoARgkAgE2AwQCBAEYMAQUs00EaB5LCRmJqaXyveEf3F7OqU0wBRTFGM2bF8Z8SgUB8p6ELVeKY9TCvhgwC0BZrpcyQkCthOGq+TugsOyOk4sUCOjkJQzlMBLerQp+n8QcQisZD/GIINhEC6Yw5nxOyd2sZrENcjy7XQUMtSVsGA== - [1689679303.613255][52705:52705] CHIP:DMG: } - [1689679303.613257][52705:52705] CHIP:DMG: - [1689679303.613261][52705:52705] CHIP:DMG: ICACValue (231) = - [1689679303.613269][52705:52705] CHIP:DMG: { - FTABAQEkAgE3AyQUARgmBIAigScmBYAlTTo3BiQTAhgkBwEkCAEwCUEEUAg7aniWmRLpt+x1PABmWvQjHuE+Q2IgXbwY8GBlQ2P65I4MW9VZgJ4uCD9Uuoof9qte8fjge1W94b4952PvrDcKNQEpARgkAmAwBBTFGM2bF8Z8SgUB8p6ELVeKY9TCvjAFFM+bPzZDej58jIru6AOFJgpPSmvzGDALQIqwnkbsSrXjw4r0aDZvDOVFF9M7fyOZfcZjYnHDGl/eVfLeX2hhO2rMVa4OoTe09+K5Tl4aWZ7/X6O3Ombf29AY - [1689679303.613277][52705:52705] CHIP:DMG: } - [1689679303.613280][52705:52705] CHIP:DMG: - [1689679303.613285][52705:52705] CHIP:DMG: - [1689679303.613293][52705:52705] CHIP:DMG: Additional Fields = - [1689679303.613295][52705:52705] CHIP:DMG: { - [1689679303.613299][52705:52705] CHIP:DMG: peer_address = UDP:[fe80::df9b:2ab4:71bf:d31b%wlp0s20f3]:33479 - [1689679303.613302][52705:52705] CHIP:DMG: } - [1689679303.613305][52705:52705] CHIP:DMG: - [1689679303.613312][52705:52705] CHIP:EM: >>> [E:36149r S:3817 M:135880647] (S) Msg RX from 0:FFFFFFFB00000000 [0000] --- Type 0001:08 (IM:InvokeCommandRequest) - [1689679303.613320][52705:52705] CHIP:EM: Handling via exchange: 36149r, Delegate: 0x55d103190208 - [1689679303.613338][52705:52705] CHIP:DMG: InvokeRequestMessage = - [1689679303.613342][52705:52705] CHIP:DMG: { - [1689679303.613345][52705:52705] CHIP:DMG: suppressResponse = false, - [1689679303.613349][52705:52705] CHIP:DMG: timedRequest = false, - [1689679303.613352][52705:52705] CHIP:DMG: InvokeRequests = - [1689679303.613359][52705:52705] CHIP:DMG: [ - [1689679303.613363][52705:52705] CHIP:DMG: CommandDataIB = - [1689679303.613367][52705:52705] CHIP:DMG: { - [1689679303.613370][52705:52705] CHIP:DMG: CommandPathIB = - [1689679303.613374][52705:52705] CHIP:DMG: { - [1689679303.613377][52705:52705] CHIP:DMG: EndpointId = 0x0, - [1689679303.613381][52705:52705] CHIP:DMG: ClusterId = 0x3e, - [1689679303.613385][52705:52705] CHIP:DMG: CommandId = 0x6, - [1689679303.613388][52705:52705] CHIP:DMG: }, - [1689679303.613393][52705:52705] CHIP:DMG: - [1689679303.613396][52705:52705] CHIP:DMG: CommandFields = - [1689679303.613400][52705:52705] CHIP:DMG: { - [1689679303.613404][52705:52705] CHIP:DMG: 0x0 = [ - [1689679303.613437][52705:52705] CHIP:DMG: 0x15, 0x30, 0x01, 0x01, 0x01, 0x24, 0x02, 0x01, 0x37, 0x03, 0x24, 0x13, 0x02, 0x18, 0x26, 0x04, 0x80, 0x22, 0x81, 0x27, 0x26, 0x05, 0x80, 0x25, 0x4d, 0x3a, 0x37, 0x06, 0x24, 0x15, 0x01, 0x24, 0x11, 0x01, 0x18, 0x24, 0x07, 0x01, 0x24, 0x08, 0x01, 0x30, 0x09, 0x41, 0x04, 0xf2, 0x94, 0xd4, 0xaa, 0x30, 0xda, 0xd4, 0x16, 0x68, 0xbd, 0xb0, 0xe2, 0x4a, 0xc0, 0xd8, 0x30, 0xb0, 0xba, 0x33, 0x5c, 0x88, 0x77, 0xc5, 0xb6, 0x0a, 0xf6, 0x2b, 0x98, 0x5c, 0xff, 0x21, 0x23, 0x95, 0x19, 0x73, 0x14, 0xd3, 0x02, 0x59, 0x63, 0xa4, 0x50, 0x1b, 0x4a, 0xcb, 0x8a, 0x22, 0x02, 0xec, 0xcc, 0x10, 0xed, 0x65, 0x7c, 0xff, 0x7f, 0xae, 0x8f, 0x99, 0x12, 0xb3, 0x93, 0xc1, 0xcd, 0x37, 0x0a, 0x35, 0x01, 0x28, 0x01, 0x18, 0x24, 0x02, 0x01, 0x36, 0x03, 0x04, 0x02, 0x04, 0x01, 0x18, 0x30, 0x04, 0x14, 0xb3, 0x4d, 0x04, 0x68, 0x1e, 0x4b, 0x09, 0x19, 0x89, 0xa9, 0xa5, 0xf2, 0xbd, 0xe1, 0x1f, 0xdc, 0x5e, 0xce, 0xa9, 0x4d, 0x30, 0x05, 0x14, 0xc5, 0x18, 0xcd, 0x9b, 0x17, 0xc6, 0x7c, 0x4a, 0x05, 0x01, 0xf2, 0x9e, 0x84, 0x2d, 0x57, 0x8a, 0x63, 0xd4, 0xc2, 0xbe, 0x18, 0x30, 0x0b, 0x40, 0x59, 0xae, 0x97, 0x32, 0x42, 0x40, 0xad, 0x84, 0xe1, 0xaa, 0xf9, 0x3b, 0xa0, 0xb0, 0xec, 0x8e, 0x93, 0x8b, 0x14, 0x08, 0xe8, 0xe4, 0x25, 0x0c, 0xe5, 0x30, 0x12, 0xde, 0xad, 0x0a, 0x7e, 0x9f, 0xc4, 0x1c, 0x42, 0x2b, 0x19, 0x0f, 0xf1, 0x88, 0x20, 0xd8, 0x44, 0x0b, 0xa6, 0x30, 0xe6, 0x7c, 0x4e, 0xc9, 0xdd, 0xac, 0x66, 0xb1, 0x0d, 0x72, 0x3c, 0xbb, 0x5d, 0x05, 0x0c, 0xb5, 0x25, 0x6c, 0x18, - [1689679303.613450][52705:52705] CHIP:DMG: ] (241 bytes) - [1689679303.613454][52705:52705] CHIP:DMG: 0x1 = [ - [1689679303.613484][52705:52705] CHIP:DMG: 0x15, 0x30, 0x01, 0x01, 0x01, 0x24, 0x02, 0x01, 0x37, 0x03, 0x24, 0x14, 0x01, 0x18, 0x26, 0x04, 0x80, 0x22, 0x81, 0x27, 0x26, 0x05, 0x80, 0x25, 0x4d, 0x3a, 0x37, 0x06, 0x24, 0x13, 0x02, 0x18, 0x24, 0x07, 0x01, 0x24, 0x08, 0x01, 0x30, 0x09, 0x41, 0x04, 0x50, 0x08, 0x3b, 0x6a, 0x78, 0x96, 0x99, 0x12, 0xe9, 0xb7, 0xec, 0x75, 0x3c, 0x00, 0x66, 0x5a, 0xf4, 0x23, 0x1e, 0xe1, 0x3e, 0x43, 0x62, 0x20, 0x5d, 0xbc, 0x18, 0xf0, 0x60, 0x65, 0x43, 0x63, 0xfa, 0xe4, 0x8e, 0x0c, 0x5b, 0xd5, 0x59, 0x80, 0x9e, 0x2e, 0x08, 0x3f, 0x54, 0xba, 0x8a, 0x1f, 0xf6, 0xab, 0x5e, 0xf1, 0xf8, 0xe0, 0x7b, 0x55, 0xbd, 0xe1, 0xbe, 0x3d, 0xe7, 0x63, 0xef, 0xac, 0x37, 0x0a, 0x35, 0x01, 0x29, 0x01, 0x18, 0x24, 0x02, 0x60, 0x30, 0x04, 0x14, 0xc5, 0x18, 0xcd, 0x9b, 0x17, 0xc6, 0x7c, 0x4a, 0x05, 0x01, 0xf2, 0x9e, 0x84, 0x2d, 0x57, 0x8a, 0x63, 0xd4, 0xc2, 0xbe, 0x30, 0x05, 0x14, 0xcf, 0x9b, 0x3f, 0x36, 0x43, 0x7a, 0x3e, 0x7c, 0x8c, 0x8a, 0xee, 0xe8, 0x03, 0x85, 0x26, 0x0a, 0x4f, 0x4a, 0x6b, 0xf3, 0x18, 0x30, 0x0b, 0x40, 0x8a, 0xb0, 0x9e, 0x46, 0xec, 0x4a, 0xb5, 0xe3, 0xc3, 0x8a, 0xf4, 0x68, 0x36, 0x6f, 0x0c, 0xe5, 0x45, 0x17, 0xd3, 0x3b, 0x7f, 0x23, 0x99, 0x7d, 0xc6, 0x63, 0x62, 0x71, 0xc3, 0x1a, 0x5f, 0xde, 0x55, 0xf2, 0xde, 0x5f, 0x68, 0x61, 0x3b, 0x6a, 0xcc, 0x55, 0xae, 0x0e, 0xa1, 0x37, 0xb4, 0xf7, 0xe2, 0xb9, 0x4e, 0x5e, 0x1a, 0x59, 0x9e, 0xff, 0x5f, 0xa3, 0xb7, 0x3a, 0x66, 0xdf, 0xdb, 0xd0, 0x18, - [1689679303.613497][52705:52705] CHIP:DMG: ] (231 bytes) - [1689679303.613501][52705:52705] CHIP:DMG: 0x2 = [ - [1689679303.613506][52705:52705] CHIP:DMG: 0x74, 0x65, 0x6d, 0x70, 0x6f, 0x72, 0x61, 0x72, 0x79, 0x20, 0x69, 0x70, 0x6b, 0x20, 0x30, 0x31, - [1689679303.613511][52705:52705] CHIP:DMG: ] (16 bytes) - [1689679303.613515][52705:52705] CHIP:DMG: 0x3 = 112233, - [1689679303.613519][52705:52705] CHIP:DMG: 0x4 = 65521, - [1689679303.613523][52705:52705] CHIP:DMG: }, - [1689679303.613526][52705:52705] CHIP:DMG: }, - [1689679303.613533][52705:52705] CHIP:DMG: - [1689679303.613535][52705:52705] CHIP:DMG: ], - [1689679303.613542][52705:52705] CHIP:DMG: - [1689679303.613545][52705:52705] CHIP:DMG: InteractionModelRevision = 1 - [1689679303.613548][52705:52705] CHIP:DMG: }, - [1689679303.613569][52705:52705] CHIP:DMG: AccessControl: checking f=0 a=p s=0xFFFFFFFB00000000 t= c=0x0000_003E e=0 p=a - [1689679303.613574][52705:52705] CHIP:DMG: AccessControl: implicit admin (PASE) - [1689679303.613579][52705:52705] CHIP:DMG: Received command for Endpoint=0 Cluster=0x0000_003E Command=0x0000_0006 + [1720691676.110] [2537:2537] [DMG] { + [1720691676.110] [2537:2537] [DMG] Exchange (0x05) = + [1720691676.110] [2537:2537] [DMG] { + [1720691676.110] [2537:2537] [DMG] Initiator = true + [1720691676.110] [2537:2537] [DMG] NeedsAck = true + [1720691676.110] [2537:2537] [DMG] } + [1720691676.110] [2537:2537] [DMG] } + [1720691676.110] [2537:2537] [DMG] + [1720691676.110] [2537:2537] [DMG] Decrypted Payload (536 bytes) = + [1720691676.110] [2537:2537] [DMG] { + [1720691676.110] [2537:2537] [DMG] data = 1528002801360215370024000024013e2402061835013000f11530010101240201370324130218260480228127260580254d3a370624150124110118240701240801300941044a270345ab219ad87b15d3019b537913f9b4141b65086f20310e9c6beb10e1d1bb6c38408a4e3060e521ec23d003223aaf91be2b0d4aba01d5936f28e4e472b0370a350128011824020136030402040118300414c58caa913e0686b491d23499ebe38b107fa17d86300514090379f413a2dee549958fd87995eaf9cfc6342418300b40170c5f4fdb337962d85313842ec8d644625a88167da9c8cb6958aa6d24376edf78737f5541ace9ff01e9cb94d4cf1f9a70c942e6a90a1acb29b5f0ab8619cfac183001e71530010101240201370324140118260480228127260580254d3a370624130218240701240801300941042ab1ebcbcc5441d4d9c64e96e7a22fd6d9a9dbd5ddb041d588c6d92ad3e0bb205077099d77495ca96eae12613f4a367407fb71c95f14109653a1a10767249bfc370a3501290118240260300414090379f413a2dee549958fd87995eaf9cfc634243005142454c7225b7e259a9fee5491234328fd15490ea818300b40dec817aa07a860dcfb62c2f470054dc0a51af3d0e67ea45d1e24835cb6895d7768ef6edff8fb70a384f13da581b6831b7c7f4f5d77fec7d5298af05bd632f7761830021074656d706f726172792069706b203031260369b601002504f1ff18181824ff0b18 + [1720691676.110] [2537:2537] [DMG] } + [1720691676.110] [2537:2537] [DMG] + [1720691676.110] [2537:2537] [DMG] NOCValue (241) = + [1720691676.110] [2537:2537] [DMG] { + FTABAQEkAgE3AyQTAhgmBIAigScmBYAlTTo3BiQVASQRARgkBwEkCAEwCUEESicDRashmth7FdMBm1N5E/m0FBtlCG8gMQ6ca+sQ4dG7bDhAik4wYOUh7CPQAyI6r5G+Kw1KugHVk28o5ORysDcKNQEoARgkAgE2AwQCBAEYMAQUxYyqkT4GhrSR0jSZ6+OLEH+hfYYwBRQJA3n0E6Le5UmVj9h5ler5z8Y0JBgwC0AXDF9P2zN5YthTE4QuyNZEYlqIFn2pyMtpWKptJDdu33hzf1VBrOn/AenLlNTPH5pwyULmqQoayym18KuGGc+sGA== + [1720691676.110] [2537:2537] [DMG] } + [1720691676.110] [2537:2537] [DMG] + [1720691676.110] [2537:2537] [DMG] ICACValue (231) = + [1720691676.110] [2537:2537] [DMG] { + FTABAQEkAgE3AyQUARgmBIAigScmBYAlTTo3BiQTAhgkBwEkCAEwCUEEKrHry8xUQdTZxk6W56Iv1tmp29XdsEHViMbZKtPguyBQdwmdd0lcqW6uEmE/SjZ0B/txyV8UEJZToaEHZySb/DcKNQEpARgkAmAwBBQJA3n0E6Le5UmVj9h5ler5z8Y0JDAFFCRUxyJbfiWan+5UkSNDKP0VSQ6oGDALQN7IF6oHqGDc+2LC9HAFTcClGvPQ5n6kXR4kg1y2iV13aO9u3/j7cKOE8T2lgbaDG3x/T113/sfVKYrwW9Yy93YY + [1720691676.110] [2537:2537] [DMG] } + [1720691676.110] [2537:2537] [DMG] + [1720691676.111] [2537:2537] [DMG] + [1720691676.111] [2537:2537] [DMG] Additional Fields = + [1720691676.111] [2537:2537] [DMG] { disabled: true - label: "Step 12: Trigger the DUT to send UpdateFabricLabel to TH" @@ -820,37 +645,35 @@ tests: verification: | ./chip-tool operationalcredentials update-fabric-label node1 1 0 - Verify UpdateFabricLabel in TH (all-clusters-app) - - [1689681999.862864][52705:52705] CHIP:DMG: InvokeResponseMessage = - [1689681999.862866][52705:52705] CHIP:DMG: { - [1689681999.862869][52705:52705] CHIP:DMG: suppressResponse = false, - [1689681999.862871][52705:52705] CHIP:DMG: InvokeResponseIBs = - [1689681999.862876][52705:52705] CHIP:DMG: [ - [1689681999.862878][52705:52705] CHIP:DMG: InvokeResponseIB = - [1689681999.862882][52705:52705] CHIP:DMG: { - [1689681999.862885][52705:52705] CHIP:DMG: CommandDataIB = - [1689681999.862887][52705:52705] CHIP:DMG: { - [1689681999.862890][52705:52705] CHIP:DMG: CommandPathIB = - [1689681999.862892][52705:52705] CHIP:DMG: { - [1689681999.862895][52705:52705] CHIP:DMG: EndpointId = 0x0, - [1689681999.862898][52705:52705] CHIP:DMG: ClusterId = 0x3e, - [1689681999.862901][52705:52705] CHIP:DMG: CommandId = 0x8, - [1689681999.862904][52705:52705] CHIP:DMG: }, - [1689681999.862907][52705:52705] CHIP:DMG: - [1689681999.862910][52705:52705] CHIP:DMG: CommandFields = - [1689681999.862913][52705:52705] CHIP:DMG: { - [1689681999.862916][52705:52705] CHIP:DMG: 0x0 = 0, - [1689681999.862919][52705:52705] CHIP:DMG: 0x1 = 1, - [1689681999.862922][52705:52705] CHIP:DMG: }, - [1689681999.862924][52705:52705] CHIP:DMG: }, - [1689681999.862928][52705:52705] CHIP:DMG: - [1689681999.862930][52705:52705] CHIP:DMG: }, - [1689681999.862934][52705:52705] CHIP:DMG: - [1689681999.862937][52705:52705] CHIP:DMG: ], - [1689681999.862941][52705:52705] CHIP:DMG: - [1689681999.862943][52705:52705] CHIP:DMG: InteractionModelRevision = 1 - [1689681999.862945][52705:52705] CHIP:DMG: }, + ON TH(all-clusters-app) Verify that TH receives UpdateFabricLabel Command from DUT successfully. + [1720690667.618] [2401:2401] [EM] Handling via exchange: 53457r, Delegate: 0xaaaaab219368 + [1720690667.618] [2401:2401] [DMG] InvokeRequestMessage = + [1720690667.618] [2401:2401] [DMG] { + [1720690667.618] [2401:2401] [DMG] suppressResponse = false, + [1720690667.618] [2401:2401] [DMG] timedRequest = false, + [1720690667.618] [2401:2401] [DMG] InvokeRequests = + [1720690667.618] [2401:2401] [DMG] [ + [1720690667.618] [2401:2401] [DMG] CommandDataIB = + [1720690667.618] [2401:2401] [DMG] { + [1720690667.618] [2401:2401] [DMG] CommandPathIB = + [1720690667.618] [2401:2401] [DMG] { + [1720690667.618] [2401:2401] [DMG] EndpointId = 0x0, + [1720690667.618] [2401:2401] [DMG] ClusterId = 0x3e, + [1720690667.618] [2401:2401] [DMG] CommandId = 0x9, + [1720690667.619] [2401:2401] [DMG] }, + [1720690667.619] [2401:2401] [DMG] + [1720690667.619] [2401:2401] [DMG] CommandFields = + [1720690667.619] [2401:2401] [DMG] { + [1720690667.619] [2401:2401] [DMG] 0x0 = "node1" (5 chars), + [1720690667.619] [2401:2401] [DMG] }, + [1720690667.619] [2401:2401] [DMG] }, + [1720690667.619] [2401:2401] [DMG] + [1720690667.619] [2401:2401] [DMG] ], + [1720690667.619] [2401:2401] [DMG] + [1720690667.619] [2401:2401] [DMG] InteractionModelRevision = 11 + [1720690667.619] [2401:2401] [DMG] }, + [1720690667.619] [2401:2401] [DMG] AccessControl: checking f=1 a=c s=0x000000000001B669 t= c=0x0000_003E e=0 p=a + [1720690667.619] [2401:2401] [DMG] AccessControl: allowed disabled: true - label: "Step 13: Trigger the DUT to Read SupportedFabrics from TH" @@ -858,35 +681,30 @@ tests: verification: | ./chip-tool operationalcredentials read supported-fabrics 1 0 - Verify that the DUT reads the SupportedFabrics from TH (all-clusters-app) successfully. - - [1689682043.096159][52705:52705] CHIP:DMG: ReportDataMessage = - [1689682043.096163][52705:52705] CHIP:DMG: { - [1689682043.096166][52705:52705] CHIP:DMG: AttributeReportIBs = - [1689682043.096172][52705:52705] CHIP:DMG: [ - [1689682043.096176][52705:52705] CHIP:DMG: AttributeReportIB = - [1689682043.096182][52705:52705] CHIP:DMG: { - [1689682043.096185][52705:52705] CHIP:DMG: AttributeDataIB = - [1689682043.096190][52705:52705] CHIP:DMG: { - [1689682043.096194][52705:52705] CHIP:DMG: DataVersion = 0x65bf1428, - [1689682043.096198][52705:52705] CHIP:DMG: AttributePathIB = - [1689682043.096202][52705:52705] CHIP:DMG: { - [1689682043.096206][52705:52705] CHIP:DMG: Endpoint = 0x0, - [1689682043.096211][52705:52705] CHIP:DMG: Cluster = 0x3e, - [1689682043.096215][52705:52705] CHIP:DMG: Attribute = 0x0000_0002, - [1689682043.096219][52705:52705] CHIP:DMG: } - [1689682043.096224][52705:52705] CHIP:DMG: - [1689682043.096229][52705:52705] CHIP:DMG: Data = 16, - [1689682043.096233][52705:52705] CHIP:DMG: }, - [1689682043.096239][52705:52705] CHIP:DMG: - [1689682043.096242][52705:52705] CHIP:DMG: }, - [1689682043.096248][52705:52705] CHIP:DMG: - [1689682043.096251][52705:52705] CHIP:DMG: ], - [1689682043.096257][52705:52705] CHIP:DMG: - [1689682043.096261][52705:52705] CHIP:DMG: SuppressResponse = true, - [1689682043.096264][52705:52705] CHIP:DMG: InteractionModelRevision = 1 - [1689682043.096267][52705:52705] CHIP:DMG: } - [1689682043.096270][52705:52705] CHIP:DMG: + On TH(all-clusters-app), Verify that TH receives read SupportedFabrics attribute from DUT successfully + + [1720690734.362] [2401:2401] [EM] Handling via exchange: 58383r, Delegate: 0xaaaaab219368 + [1720690734.362] [2401:2401] [IM] Received Read request + [1720690734.362] [2401:2401] [DMG] ReadRequestMessage = + [1720690734.362] [2401:2401] [DMG] { + [1720690734.362] [2401:2401] [DMG] AttributePathIBs = + [1720690734.362] [2401:2401] [DMG] [ + [1720690734.362] [2401:2401] [DMG] AttributePathIB = + [1720690734.362] [2401:2401] [DMG] { + [1720690734.362] [2401:2401] [DMG] Endpoint = 0x0, + [1720690734.362] [2401:2401] [DMG] Cluster = 0x3e, + [1720690734.362] [2401:2401] [DMG] Attribute = 0x0000_0002, + [1720690734.362] [2401:2401] [DMG] } + [1720690734.362] [2401:2401] [DMG] + [1720690734.362] [2401:2401] [DMG] ], + [1720690734.362] [2401:2401] [DMG] + [1720690734.362] [2401:2401] [DMG] isFabricFiltered = true, + [1720690734.362] [2401:2401] [DMG] InteractionModelRevision = 11 + [1720690734.362] [2401:2401] [DMG] }, + [1720690734.362] [2401:2401] [DMG] IM RH moving to [CanStartReporting] + [1720690734.362] [2401:2401] [DMG] Building Reports for ReadHandler with LastReportGeneration = 0x0000000000000000 DirtyGeneration = 0x0000000000000000 + [1720690734.362] [2401:2401] [DMG] Cluster 3e, Attribute 2 is dirty + [1720690734.362] [2401:2401] [DMG] Reading attribute: Cluster=0x0000_003E Endpoint=0 AttributeId=0x0000_0002 (expanded=0) disabled: true - label: @@ -896,39 +714,30 @@ tests: verification: | ./chip-tool operationalcredentials read commissioned-fabrics 1 0 - Verify that the DUT reads the CommissionedFabrics from TH (all-clusters-app) successfully. - - [1689682091.425466][52705:52705] CHIP:DMG: ReportDataMessage = - [1689682091.425468][52705:52705] CHIP:DMG: { - [1689682091.425471][52705:52705] CHIP:DMG: AttributeReportIBs = - [1689682091.425475][52705:52705] CHIP:DMG: [ - [1689682091.425477][52705:52705] CHIP:DMG: AttributeReportIB = - [1689682091.425481][52705:52705] CHIP:DMG: { - [1689682091.425484][52705:52705] CHIP:DMG: AttributeDataIB = - [1689682091.425487][52705:52705] CHIP:DMG: { - [1689682091.425490][52705:52705] CHIP:DMG: DataVersion = 0x65bf1428, - [1689682091.425492][52705:52705] CHIP:DMG: AttributePathIB = - [1689682091.425495][52705:52705] CHIP:DMG: { - [1689682091.425499][52705:52705] CHIP:DMG: Endpoint = 0x0, - [1689682091.425502][52705:52705] CHIP:DMG: Cluster = 0x3e, - [1689682091.425505][52705:52705] CHIP:DMG: Attribute = 0x0000_0003, - [1689682091.425507][52705:52705] CHIP:DMG: } - [1689682091.425512][52705:52705] CHIP:DMG: - [1689682091.425515][52705:52705] CHIP:DMG: Data = 1, - [1689682091.425518][52705:52705] CHIP:DMG: }, - [1689682091.425522][52705:52705] CHIP:DMG: - [1689682091.425524][52705:52705] CHIP:DMG: }, - [1689682091.425528][52705:52705] CHIP:DMG: - [1689682091.425531][52705:52705] CHIP:DMG: ], - [1689682091.425536][52705:52705] CHIP:DMG: - [1689682091.425538][52705:52705] CHIP:DMG: SuppressResponse = true, - [1689682091.425541][52705:52705] CHIP:DMG: InteractionModelRevision = 1 - [1689682091.425543][52705:52705] CHIP:DMG: } - [1689682091.425545][52705:52705] CHIP:DMG: - [1689682091.425550][52705:52705] CHIP:DMG: Additional Fields = - [1689682091.425552][52705:52705] CHIP:DMG: { - [1689682091.425555][52705:52705] CHIP:DMG: peer_address = UDP:[fe80::df9b:2ab4:71bf:d31b%wlp0s20f3]:60204 - [1689682091.425557][52705:52705] CHIP:DMG: } + On TH(all-clusters-app), Verify that TH receives read CommissionedFabrics attribute from DUT successfully. + + [1720690759.037] [2401:2401] [EM] Handling via exchange: 8730r, Delegate: 0xaaaaab219368 + [1720690759.037] [2401:2401] [IM] Received Read request + [1720690759.037] [2401:2401] [DMG] ReadRequestMessage = + [1720690759.037] [2401:2401] [DMG] { + [1720690759.037] [2401:2401] [DMG] AttributePathIBs = + [1720690759.037] [2401:2401] [DMG] [ + [1720690759.037] [2401:2401] [DMG] AttributePathIB = + [1720690759.037] [2401:2401] [DMG] { + [1720690759.037] [2401:2401] [DMG] Endpoint = 0x0, + [1720690759.037] [2401:2401] [DMG] Cluster = 0x3e, + [1720690759.037] [2401:2401] [DMG] Attribute = 0x0000_0003, + [1720690759.037] [2401:2401] [DMG] } + [1720690759.037] [2401:2401] [DMG] + [1720690759.037] [2401:2401] [DMG] ], + [1720690759.037] [2401:2401] [DMG] + [1720690759.037] [2401:2401] [DMG] isFabricFiltered = true, + [1720690759.037] [2401:2401] [DMG] InteractionModelRevision = 11 + [1720690759.037] [2401:2401] [DMG] }, + [1720690759.037] [2401:2401] [DMG] IM RH moving to [CanStartReporting] + [1720690759.037] [2401:2401] [DMG] Building Reports for ReadHandler with LastReportGeneration = 0x0000000000000000 DirtyGeneration = 0x0000000000000000 + [1720690759.037] [2401:2401] [DMG] Cluster 3e, Attribute 3 is dirty + [1720690759.037] [2401:2401] [DMG] Reading attribute: Cluster=0x0000_003E Endpoint=0 AttributeId=0x0000_0003 (expanded=0) disabled: true - label: @@ -938,43 +747,29 @@ tests: verification: | ./chip-tool operationalcredentials read trusted-root-certificates 1 0 - Verify that the DUT reads the TrustedRootCertificates from TH (all-clusters-app) successfully. - - [1689682131.190884][52705:52705] CHIP:DMG: ReportDataMessage = - [1689682131.190889][52705:52705] CHIP:DMG: { - [1689682131.190892][52705:52705] CHIP:DMG: AttributeReportIBs = - [1689682131.190901][52705:52705] CHIP:DMG: [ - [1689682131.190905][52705:52705] CHIP:DMG: AttributeReportIB = - [1689682131.190913][52705:52705] CHIP:DMG: { - [1689682131.190917][52705:52705] CHIP:DMG: AttributeDataIB = - [1689682131.190922][52705:52705] CHIP:DMG: { - [1689682131.190928][52705:52705] CHIP:DMG: DataVersion = 0x65bf1428, - [1689682131.190932][52705:52705] CHIP:DMG: AttributePathIB = - [1689682131.190937][52705:52705] CHIP:DMG: { - [1689682131.190943][52705:52705] CHIP:DMG: Endpoint = 0x0, - [1689682131.190948][52705:52705] CHIP:DMG: Cluster = 0x3e, - [1689682131.190953][52705:52705] CHIP:DMG: Attribute = 0x0000_0004, - [1689682131.190958][52705:52705] CHIP:DMG: } - [1689682131.190965][52705:52705] CHIP:DMG: - [1689682131.190970][52705:52705] CHIP:DMG: Data = [ - [1689682131.190976][52705:52705] CHIP:DMG: [ - [1689682131.191022][52705:52705] CHIP:DMG: 0x15, 0x30, 0x01, 0x01, 0x01, 0x24, 0x02, 0x01, 0x37, 0x03, 0x24, 0x14, 0x01, 0x18, 0x26, 0x04, 0x80, 0x22, 0x81, 0x27, 0x26, 0x05, 0x80, 0x25, 0x4d, 0x3a, 0x37, 0x06, 0x24, 0x14, 0x01, 0x18, 0x24, 0x07, 0x01, 0x24, 0x08, 0x01, 0x30, 0x09, 0x41, 0x04, 0x8e, 0x70, 0xf4, 0x2e, 0xcb, 0xad, 0x8a, 0xc7, 0x98, 0x04, 0xa7, 0x5e, 0x1e, 0xe8, 0x33, 0xc8, 0x33, 0xb0, 0x76, 0xd9, 0x02, 0x93, 0x0a, 0x79, 0xff, 0xc3, 0xcd, 0x26, 0x78, 0xa9, 0xf6, 0xe8, 0xfe, 0xe8, 0x8b, 0x72, 0x3e, 0x31, 0x4e, 0x8e, 0xd7, 0x63, 0x7d, 0x9e, 0x90, 0x73, 0x20, 0x71, 0x1b, 0xbf, 0xfd, 0x1c, 0xc0, 0x8c, 0x4d, 0x6f, 0xb8, 0x75, 0x5f, 0xcb, 0x41, 0xef, 0x96, 0xb9, 0x37, 0x0a, 0x35, 0x01, 0x29, 0x01, 0x18, 0x24, 0x02, 0x60, 0x30, 0x04, 0x14, 0xcf, 0x9b, 0x3f, 0x36, 0x43, 0x7a, 0x3e, 0x7c, 0x8c, 0x8a, 0xee, 0xe8, 0x03, 0x85, 0x26, 0x0a, 0x4f, 0x4a, 0x6b, 0xf3, 0x30, 0x05, 0x14, 0xcf, 0x9b, 0x3f, 0x36, 0x43, 0x7a, 0x3e, 0x7c, 0x8c, 0x8a, 0xee, 0xe8, 0x03, 0x85, 0x26, 0x0a, 0x4f, 0x4a, 0x6b, 0xf3, 0x18, 0x30, 0x0b, 0x40, 0x03, 0x3a, 0x99, 0xd5, 0xbd, 0x12, 0x8c, 0xdf, 0x45, 0xa2, 0x5b, 0x9c, 0xa1, 0x5d, 0xb0, 0x25, 0x43, 0xa2, 0x96, 0x17, 0x05, 0x18, 0x97, 0x7c, 0x64, 0x8a, 0xe2, 0xc4, 0x15, 0xeb, 0x7a, 0x4e, 0xe3, 0x4d, 0x42, 0x60, 0x78, 0x0d, 0x83, 0x32, 0x56, 0x26, 0xa7, 0xe5, 0x1d, 0x77, 0x4e, 0x71, 0x23, 0xe2, 0xac, 0x0a, 0x93, 0x7d, 0x53, 0x6d, 0xe3, 0xa4, 0x8b, 0xcc, 0xb7, 0x10, 0xd4, 0xc3, 0x18, - [1689682131.191039][52705:52705] CHIP:DMG: ] (231 bytes) - [1689682131.191045][52705:52705] CHIP:DMG: ], - [1689682131.191049][52705:52705] CHIP:DMG: }, - [1689682131.191056][52705:52705] CHIP:DMG: - [1689682131.191060][52705:52705] CHIP:DMG: }, - [1689682131.191068][52705:52705] CHIP:DMG: - [1689682131.191071][52705:52705] CHIP:DMG: ], - [1689682131.191079][52705:52705] CHIP:DMG: - [1689682131.191084][52705:52705] CHIP:DMG: SuppressResponse = true, - [1689682131.191089][52705:52705] CHIP:DMG: InteractionModelRevision = 1 - [1689682131.191092][52705:52705] CHIP:DMG: } - [1689682131.191096][52705:52705] CHIP:DMG: - [1689682131.191106][52705:52705] CHIP:DMG: Additional Fields = - [1689682131.191109][52705:52705] CHIP:DMG: { - [1689682131.191114][52705:52705] CHIP:DMG: peer_address = UDP:[fe80::df9b:2ab4:71bf:d31b%wlp0s20f3]:56707 - [1689682131.191118][52705:52705] CHIP:DMG: } + On TH(all-clusters-app), Verify that TH receives read TrustedRootCertificates from DUT successfully. + [1720690787.895] [2401:2401] [EM] Handling via exchange: 45935r, Delegate: 0xaaaaab219368 + [1720690787.895] [2401:2401] [IM] Received Read request + [1720690787.895] [2401:2401] [DMG] ReadRequestMessage = + [1720690787.895] [2401:2401] [DMG] { + [1720690787.895] [2401:2401] [DMG] AttributePathIBs = + [1720690787.895] [2401:2401] [DMG] [ + [1720690787.895] [2401:2401] [DMG] AttributePathIB = + [1720690787.895] [2401:2401] [DMG] { + [1720690787.895] [2401:2401] [DMG] Endpoint = 0x0, + [1720690787.895] [2401:2401] [DMG] Cluster = 0x3e, + [1720690787.895] [2401:2401] [DMG] Attribute = 0x0000_0004, + [1720690787.895] [2401:2401] [DMG] } + [1720690787.896] [2401:2401] [DMG] + [1720690787.896] [2401:2401] [DMG] ], + [1720690787.896] [2401:2401] [DMG] + [1720690787.896] [2401:2401] [DMG] isFabricFiltered = true, + [1720690787.896] [2401:2401] [DMG] InteractionModelRevision = 11 + [1720690787.896] [2401:2401] [DMG] }, + [1720690787.896] [2401:2401] [DMG] IM RH moving to [CanStartReporting] + [1720690787.896] [2401:2401] [DMG] Building Reports for ReadHandler with LastReportGeneration = 0x0000000000000000 DirtyGeneration = 0x0000000000000000 + [1720690787.896] [2401:2401] [DMG] Cluster 3e, Attribute 4 is dirty + [1720690787.896] [2401:2401] [DMG] Reading attribute: Cluster=0x0000_003E Endpoint=0 AttributeId=0x0000_0004 (expanded=0) disabled: true - label: @@ -983,39 +778,30 @@ tests: verification: | ./chip-tool operationalcredentials read current-fabric-index 1 0 - Verify that the DUT reads the CurrentFabricIndex from TH (all-clusters-app) successfully. - - [1689682171.239348][52705:52705] CHIP:DMG: ReportDataMessage = - [1689682171.239351][52705:52705] CHIP:DMG: { - [1689682171.239353][52705:52705] CHIP:DMG: AttributeReportIBs = - [1689682171.239359][52705:52705] CHIP:DMG: [ - [1689682171.239361][52705:52705] CHIP:DMG: AttributeReportIB = - [1689682171.239367][52705:52705] CHIP:DMG: { - [1689682171.239370][52705:52705] CHIP:DMG: AttributeDataIB = - [1689682171.239373][52705:52705] CHIP:DMG: { - [1689682171.239378][52705:52705] CHIP:DMG: DataVersion = 0x65bf1428, - [1689682171.239382][52705:52705] CHIP:DMG: AttributePathIB = - [1689682171.239387][52705:52705] CHIP:DMG: { - [1689682171.239391][52705:52705] CHIP:DMG: Endpoint = 0x0, - [1689682171.239396][52705:52705] CHIP:DMG: Cluster = 0x3e, - [1689682171.239400][52705:52705] CHIP:DMG: Attribute = 0x0000_0005, - [1689682171.239404][52705:52705] CHIP:DMG: } - [1689682171.239410][52705:52705] CHIP:DMG: - [1689682171.239415][52705:52705] CHIP:DMG: Data = 1, - [1689682171.239419][52705:52705] CHIP:DMG: }, - [1689682171.239424][52705:52705] CHIP:DMG: - [1689682171.239427][52705:52705] CHIP:DMG: }, - [1689682171.239432][52705:52705] CHIP:DMG: - [1689682171.239434][52705:52705] CHIP:DMG: ], - [1689682171.239440][52705:52705] CHIP:DMG: - [1689682171.239443][52705:52705] CHIP:DMG: SuppressResponse = true, - [1689682171.239447][52705:52705] CHIP:DMG: InteractionModelRevision = 1 - [1689682171.239450][52705:52705] CHIP:DMG: } - [1689682171.239453][52705:52705] CHIP:DMG: - [1689682171.239459][52705:52705] CHIP:DMG: Additional Fields = - [1689682171.239462][52705:52705] CHIP:DMG: { - [1689682171.239465][52705:52705] CHIP:DMG: peer_address = UDP:[fe80::df9b:2ab4:71bf:d31b%wlp0s20f3]:48841 - [1689682171.239468][52705:52705] CHIP:DMG: } + On TH(all-clusters-app), Verify that TH receives read CurrentFabricIndex from DUT successfully. + 00001B669 [2E0F] --- Type 0001:02 (IM:ReadRequest) + [1720690810.143] [2401:2401] [EM] Handling via exchange: 58403r, Delegate: 0xaaaaab219368 + [1720690810.143] [2401:2401] [IM] Received Read request + [1720690810.143] [2401:2401] [DMG] ReadRequestMessage = + [1720690810.143] [2401:2401] [DMG] { + [1720690810.143] [2401:2401] [DMG] AttributePathIBs = + [1720690810.143] [2401:2401] [DMG] [ + [1720690810.143] [2401:2401] [DMG] AttributePathIB = + [1720690810.143] [2401:2401] [DMG] { + [1720690810.143] [2401:2401] [DMG] Endpoint = 0x0, + [1720690810.143] [2401:2401] [DMG] Cluster = 0x3e, + [1720690810.143] [2401:2401] [DMG] Attribute = 0x0000_0005, + [1720690810.143] [2401:2401] [DMG] } + [1720690810.143] [2401:2401] [DMG] + [1720690810.143] [2401:2401] [DMG] ], + [1720690810.143] [2401:2401] [DMG] + [1720690810.143] [2401:2401] [DMG] isFabricFiltered = true, + [1720690810.143] [2401:2401] [DMG] InteractionModelRevision = 11 + [1720690810.143] [2401:2401] [DMG] }, + [1720690810.143] [2401:2401] [DMG] IM RH moving to [CanStartReporting] + [1720690810.144] [2401:2401] [DMG] Building Reports for ReadHandler with LastReportGeneration = 0x0000000000000000 DirtyGeneration = 0x0000000000000000 + [1720690810.144] [2401:2401] [DMG] Cluster 3e, Attribute 5 is dirty + [1720690810.144] [2401:2401] [DMG] Reading attribute: Cluster=0x000 disabled: true - label: "Step 17: Trigger the DUT to send RemoveFabric command to TH" @@ -1023,41 +809,35 @@ tests: verification: | ./chip-tool operationalcredentials remove-fabric 1 1 0 - Verify that the TH receives RemoveFabric Command on TH(all-clusters-app) Log - - [1689682243.817862][52705:52705] CHIP:DMG: InvokeResponseMessage = - [1689682243.817866][52705:52705] CHIP:DMG: { - [1689682243.817869][52705:52705] CHIP:DMG: suppressResponse = false, - [1689682243.817872][52705:52705] CHIP:DMG: InvokeResponseIBs = - [1689682243.817879][52705:52705] CHIP:DMG: [ - [1689682243.817882][52705:52705] CHIP:DMG: InvokeResponseIB = - [1689682243.817888][52705:52705] CHIP:DMG: { - [1689682243.817892][52705:52705] CHIP:DMG: CommandDataIB = - [1689682243.817895][52705:52705] CHIP:DMG: { - [1689682243.817899][52705:52705] CHIP:DMG: CommandPathIB = - [1689682243.817906][52705:52705] CHIP:DMG: { - [1689682243.817910][52705:52705] CHIP:DMG: EndpointId = 0x0, - [1689682243.817915][52705:52705] CHIP:DMG: ClusterId = 0x3e, - [1689682243.817919][52705:52705] CHIP:DMG: CommandId = 0x8, - [1689682243.817924][52705:52705] CHIP:DMG: }, - [1689682243.817930][52705:52705] CHIP:DMG: - [1689682243.817934][52705:52705] CHIP:DMG: CommandFields = - [1689682243.817938][52705:52705] CHIP:DMG: { - [1689682243.817944][52705:52705] CHIP:DMG: 0x0 = 0, - [1689682243.817949][52705:52705] CHIP:DMG: 0x1 = 1, - [1689682243.817954][52705:52705] CHIP:DMG: }, - [1689682243.817958][52705:52705] CHIP:DMG: }, - [1689682243.817965][52705:52705] CHIP:DMG: - [1689682243.817968][52705:52705] CHIP:DMG: }, - [1689682243.817976][52705:52705] CHIP:DMG: - [1689682243.817979][52705:52705] CHIP:DMG: ], - [1689682243.817986][52705:52705] CHIP:DMG: - [1689682243.817989][52705:52705] CHIP:DMG: InteractionModelRevision = 1 - [1689682243.817993][52705:52705] CHIP:DMG: }, - [1689682243.817997][52705:52705] CHIP:DMG: - [1689682243.818005][52705:52705] CHIP:DMG: Additional Fields = - [1689682243.818008][52705:52705] CHIP:DMG: { - [1689682243.818012][52705:52705] CHIP:DMG: peer_address = UDP:[fe80::df9b:2ab4:71bf:d31b%wlp0s20f3]:59605 - [1689682243.818016][52705:52705] CHIP:DMG: } - [1689682243.818019][52705:52705] CHIP:DMG: + On TH(all-clusters-app), Verify that TH receives RemoveFabric Command for the FabricID saved from FabricDescriptor + + [1720691521.510] [2497:2497] [EM] >>> [E:54592r S:29126 M:138609799] (S) Msg RX from 1:000000000001B669 [5C12] --- Type 0001:08 (IM:InvokeCommandRequest) + [1720691521.510] [2497:2497] [EM] Handling via exchange: 54592r, Delegate: 0xaaaae7e69368 + [1720691521.510] [2497:2497] [DMG] InvokeRequestMessage = + [1720691521.510] [2497:2497] [DMG] { + [1720691521.510] [2497:2497] [DMG] suppressResponse = false, + [1720691521.510] [2497:2497] [DMG] timedRequest = false, + [1720691521.510] [2497:2497] [DMG] InvokeRequests = + [1720691521.511] [2497:2497] [DMG] [ + [1720691521.511] [2497:2497] [DMG] CommandDataIB = + [1720691521.511] [2497:2497] [DMG] { + [1720691521.511] [2497:2497] [DMG] CommandPathIB = + [1720691521.511] [2497:2497] [DMG] { + [1720691521.511] [2497:2497] [DMG] EndpointId = 0x0, + [1720691521.511] [2497:2497] [DMG] ClusterId = 0x3e, + [1720691521.511] [2497:2497] [DMG] CommandId = 0xa, + [1720691521.511] [2497:2497] [DMG] }, + [1720691521.511] [2497:2497] [DMG] + [1720691521.511] [2497:2497] [DMG] CommandFields = + [1720691521.511] [2497:2497] [DMG] { + [1720691521.511] [2497:2497] [DMG] 0x0 = 1 (unsigned), + [1720691521.511] [2497:2497] [DMG] }, + [1720691521.511] [2497:2497] [DMG] }, + [1720691521.511] [2497:2497] [DMG] + [1720691521.511] [2497:2497] [DMG] ], + [1720691521.511] [2497:2497] [DMG] + [1720691521.511] [2497:2497] [DMG] InteractionModelRevision = 11 + [1720691521.511] [2497:2497] [DMG] }, + [1720691521.511] [2497:2497] [DMG] AccessControl: checking f=1 a=c s=0x000000000001B669 t= c=0x0000_003E e=0 p=a + [1720691521.511] [2497:2497] [DMG] AccessControl: allowed disabled: true From 5ea5c2a5df925ba5a5343ec7a9f1a592ece237c1 Mon Sep 17 00:00:00 2001 From: Sting Chang <33673360+stingchang@users.noreply.github.com> Date: Fri, 25 Oct 2024 12:27:56 +0000 Subject: [PATCH 115/149] Add temperature control cluster impl for laundry washer (#36105) * add temperature control cluster impl for laundry washer * add washer mode reader writer * remove extra import * fix style * Restyled by clang-format * update temperature level * string span; OnOff DF feature; * Restyled by clang-format * copyright year * static assert * Restyled by clang-format * return error * verify and return * Restyled by whitespace --------- Co-authored-by: Restyled.io --- ...-laundry-washer-controls-delegate-impl.cpp | 2 + .../chef/common/chef-laundry-washer-mode.cpp | 57 ++++ .../chef/common/chef-laundry-washer-mode.h | 9 + .../static-supported-temperature-levels.cpp | 78 +++++ .../static-supported-temperature-levels.h | 56 ++++ examples/chef/common/stubs.cpp | 20 ++ .../rootnode_laundrywasher_fb10d238c8.matter | 135 +++++++- .../rootnode_laundrywasher_fb10d238c8.zap | 312 ++++++++++++++++-- examples/chef/esp32/main/CMakeLists.txt | 1 + examples/chef/linux/BUILD.gn | 1 + examples/chef/nrfconnect/CMakeLists.txt | 1 + 11 files changed, 644 insertions(+), 28 deletions(-) create mode 100644 examples/chef/common/clusters/temperature-control/static-supported-temperature-levels.cpp create mode 100644 examples/chef/common/clusters/temperature-control/static-supported-temperature-levels.h diff --git a/examples/chef/common/chef-laundry-washer-controls-delegate-impl.cpp b/examples/chef/common/chef-laundry-washer-controls-delegate-impl.cpp index 4811b458fe8fc0..f63acf8938bb9f 100644 --- a/examples/chef/common/chef-laundry-washer-controls-delegate-impl.cpp +++ b/examples/chef/common/chef-laundry-washer-controls-delegate-impl.cpp @@ -30,8 +30,10 @@ const CharSpan LaundryWasherControlDelegate::spinSpeedsNameOptions[] = { }; const NumberOfRinsesEnum LaundryWasherControlDelegate::supportRinsesOptions[] = { + NumberOfRinsesEnum::kNone, NumberOfRinsesEnum::kNormal, NumberOfRinsesEnum::kExtra, + NumberOfRinsesEnum::kMax, }; LaundryWasherControlDelegate LaundryWasherControlDelegate::instance; diff --git a/examples/chef/common/chef-laundry-washer-mode.cpp b/examples/chef/common/chef-laundry-washer-mode.cpp index f24e1c6cbcfec6..8ca637ca29404a 100644 --- a/examples/chef/common/chef-laundry-washer-mode.cpp +++ b/examples/chef/common/chef-laundry-washer-mode.cpp @@ -25,6 +25,7 @@ template using List = chip::app::DataModel::List; using ModeTagStructType = chip::app::Clusters::detail::Structs::ModeTagStruct::Type; +#ifdef MATTER_DM_PLUGIN_LAUNDRY_WASHER_MODE_SERVER static LaundryWasherModeDelegate * gLaundryWasherModeDelegate = nullptr; static ModeBase::Instance * gLaundryWasherModeInstance = nullptr; @@ -94,6 +95,61 @@ void LaundryWasherMode::Shutdown() } } +chip::Protocols::InteractionModel::Status chefLaundryWasherModeWriteCallback(chip::EndpointId endpointId, chip::ClusterId clusterId, + const EmberAfAttributeMetadata * attributeMetadata, + uint8_t * buffer) +{ + VerifyOrReturnError(endpointId == 1 || gLaundryWasherModeInstance != nullptr, + chip::Protocols::InteractionModel::Status::Failure); + + chip::Protocols::InteractionModel::Status ret; + chip::AttributeId attributeId = attributeMetadata->attributeId; + + switch (attributeId) + { + case chip::app::Clusters::LaundryWasherMode::Attributes::CurrentMode::Id: { + uint8_t m = buffer[0]; + ret = gLaundryWasherModeInstance->UpdateCurrentMode(m); + if (chip::Protocols::InteractionModel::Status::Success != ret) + { + ChipLogError(DeviceLayer, "Invalid Attribute Update status: %d", static_cast(ret)); + } + } + break; + default: + ret = chip::Protocols::InteractionModel::Status::UnsupportedWrite; + ChipLogError(DeviceLayer, "Unsupported Attribute ID: %d", static_cast(attributeId)); + break; + } + + return ret; +} + +chip::Protocols::InteractionModel::Status chefLaundryWasherModeReadCallback(chip::EndpointId endpointId, chip::ClusterId clusterId, + const EmberAfAttributeMetadata * attributeMetadata, + uint8_t * buffer, uint16_t maxReadLength) +{ + VerifyOrReturnValue(maxReadLength > 0, chip::Protocols::InteractionModel::Status::ResourceExhausted); + + chip::Protocols::InteractionModel::Status ret = chip::Protocols::InteractionModel::Status::Success; + chip::AttributeId attributeId = attributeMetadata->attributeId; + + switch (attributeId) + { + case chip::app::Clusters::LaundryWasherMode::Attributes::CurrentMode::Id: { + *buffer = gLaundryWasherModeInstance->GetCurrentMode(); + ChipLogDetail(DeviceLayer, "Reading LaundryWasherMode CurrentMode : %d", static_cast(attributeId)); + } + break; + default: + ret = chip::Protocols::InteractionModel::Status::UnsupportedRead; + ChipLogDetail(DeviceLayer, "Unsupported attributeId %d from reading RvcCleanMode", static_cast(attributeId)); + break; + } + + return ret; +} + void emberAfLaundryWasherModeClusterInitCallback(chip::EndpointId endpointId) { VerifyOrDie(endpointId == 1); // this cluster is only enabled for endpoint 1. @@ -103,3 +159,4 @@ void emberAfLaundryWasherModeClusterInitCallback(chip::EndpointId endpointId) new ModeBase::Instance(gLaundryWasherModeDelegate, 0x1, LaundryWasherMode::Id, chip::to_underlying(Feature::kOnOff)); gLaundryWasherModeInstance->Init(); } +#endif // MATTER_DM_PLUGIN_LAUNDRY_WASHER_MODE_SERVER diff --git a/examples/chef/common/chef-laundry-washer-mode.h b/examples/chef/common/chef-laundry-washer-mode.h index 5d35c03d4e50cd..ffbcc453210f0c 100644 --- a/examples/chef/common/chef-laundry-washer-mode.h +++ b/examples/chef/common/chef-laundry-washer-mode.h @@ -82,3 +82,12 @@ void Shutdown(); } // namespace Clusters } // namespace app } // namespace chip + +#ifdef MATTER_DM_PLUGIN_LAUNDRY_WASHER_MODE_SERVER +chip::Protocols::InteractionModel::Status chefLaundryWasherModeWriteCallback(chip::EndpointId endpoint, chip::ClusterId clusterId, + const EmberAfAttributeMetadata * attributeMetadata, + uint8_t * buffer); +chip::Protocols::InteractionModel::Status chefLaundryWasherModeReadCallback(chip::EndpointId endpoint, chip::ClusterId clusterId, + const EmberAfAttributeMetadata * attributeMetadata, + uint8_t * buffer, uint16_t maxReadLength); +#endif // MATTER_DM_PLUGIN_LAUNDRY_WASHER_MODE_SERVER diff --git a/examples/chef/common/clusters/temperature-control/static-supported-temperature-levels.cpp b/examples/chef/common/clusters/temperature-control/static-supported-temperature-levels.cpp new file mode 100644 index 00000000000000..045825d8faf312 --- /dev/null +++ b/examples/chef/common/clusters/temperature-control/static-supported-temperature-levels.cpp @@ -0,0 +1,78 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include + +#ifdef MATTER_DM_PLUGIN_TEMPERATURE_CONTROL_SERVER +#include "static-supported-temperature-levels.h" +#include + +using namespace chip; +using namespace chip::app::Clusters; +using namespace chip::app::Clusters::TemperatureControl; +using chip::Protocols::InteractionModel::Status; + +app::Clusters::TemperatureControl::AppSupportedTemperatureLevelsDelegate sAppSupportedTemperatureLevelsDelegate; + +CharSpan AppSupportedTemperatureLevelsDelegate::temperatureLevelOptions[] = { "Low"_span, "Medium"_span, "High"_span }; + +const AppSupportedTemperatureLevelsDelegate::EndpointPair AppSupportedTemperatureLevelsDelegate::supportedOptionsByEndpoints + [MATTER_DM_TEMPERATURE_CONTROL_CLUSTER_SERVER_ENDPOINT_COUNT] = { EndpointPair( + 1 /* endpointId */, AppSupportedTemperatureLevelsDelegate::temperatureLevelOptions, + ArraySize(AppSupportedTemperatureLevelsDelegate::temperatureLevelOptions)) }; + +uint8_t AppSupportedTemperatureLevelsDelegate::Size() +{ + for (auto & endpointPair : AppSupportedTemperatureLevelsDelegate::supportedOptionsByEndpoints) + { + if (endpointPair.mEndpointId == mEndpoint) + { + return endpointPair.mSize; + } + } + return 0; +} + +CHIP_ERROR AppSupportedTemperatureLevelsDelegate::Next(MutableCharSpan & item) +{ + for (auto & endpointPair : AppSupportedTemperatureLevelsDelegate::supportedOptionsByEndpoints) + { + if (endpointPair.mEndpointId == mEndpoint) + { + if (endpointPair.mSize > mIndex) + { + CHIP_ERROR err = CopyCharSpanToMutableCharSpan(endpointPair.mTemperatureLevels[mIndex], item); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "Error copying char span to mutable char span %s", ErrorStr(err)); + return err; + } + mIndex++; + return CHIP_NO_ERROR; + } + } + } + return CHIP_ERROR_PROVIDER_LIST_EXHAUSTED; +} +void emberAfTemperatureControlClusterInitCallback(EndpointId endpoint) +{ + static_assert(MATTER_DM_TEMPERATURE_CONTROL_CLUSTER_SERVER_ENDPOINT_COUNT == 1, "This cluster is only enabled for endpoint 1"); + + chip::app::Clusters::TemperatureControl::SetInstance(&sAppSupportedTemperatureLevelsDelegate); +} +#endif // MATTER_DM_PLUGIN_TEMPERATURE_CONTROL_SERVER diff --git a/examples/chef/common/clusters/temperature-control/static-supported-temperature-levels.h b/examples/chef/common/clusters/temperature-control/static-supported-temperature-levels.h new file mode 100644 index 00000000000000..c39bb171c93c58 --- /dev/null +++ b/examples/chef/common/clusters/temperature-control/static-supported-temperature-levels.h @@ -0,0 +1,56 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include + +namespace chip { +namespace app { +namespace Clusters { +namespace TemperatureControl { + +class AppSupportedTemperatureLevelsDelegate : public SupportedTemperatureLevelsIteratorDelegate +{ + struct EndpointPair + { + EndpointId mEndpointId; + CharSpan * mTemperatureLevels; + uint8_t mSize; + + EndpointPair(EndpointId aEndpointId, CharSpan * TemperatureLevels, uint8_t size) : + mEndpointId(aEndpointId), mTemperatureLevels(TemperatureLevels), mSize(size) + {} + }; + + static CharSpan temperatureLevelOptions[3]; + static const EndpointPair supportedOptionsByEndpoints[MATTER_DM_TEMPERATURE_CONTROL_CLUSTER_SERVER_ENDPOINT_COUNT]; + +public: + uint8_t Size() override; + + CHIP_ERROR Next(MutableCharSpan & item) override; + + ~AppSupportedTemperatureLevelsDelegate() {} +}; + +} // namespace TemperatureControl +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/examples/chef/common/stubs.cpp b/examples/chef/common/stubs.cpp index 687b572a4ceefb..513bb412920d74 100644 --- a/examples/chef/common/stubs.cpp +++ b/examples/chef/common/stubs.cpp @@ -62,10 +62,22 @@ const Clusters::Descriptor::Structs::SemanticTagStruct::Type freezerTagList[] #include "chef-dishwasher-mode-delegate-impl.h" #endif // MATTER_DM_PLUGIN_DISHWASHER_MODE_SERVER +#ifdef MATTER_DM_PLUGIN_LAUNDRY_WASHER_MODE_SERVER +#include "chef-laundry-washer-mode.h" +#endif // MATTER_DM_PLUGIN_LAUNDRY_WASHER_MODE_SERVER + +#ifdef MATTER_DM_PLUGIN_LAUNDRY_WASHER_CONTROLS_SERVER +#include "chef-laundry-washer-controls-delegate-impl.h" +#endif // MATTER_DM_PLUGIN_LAUNDRY_WASHER_CONTROLS_SERVER + #ifdef MATTER_DM_PLUGIN_OPERATIONAL_STATE_SERVER #include "chef-operational-state-delegate-impl.h" #endif // MATTER_DM_PLUGIN_OPERATIONAL_STATE_SERVER +#ifdef MATTER_DM_PLUGIN_TEMPERATURE_CONTROL_SERVER +#include "temperature-control/static-supported-temperature-levels.h" +#endif // MATTER_DM_PLUGIN_TEMPERATURE_CONTROL_SERVER + Protocols::InteractionModel::Status emberAfExternalAttributeReadCallback(EndpointId endpoint, ClusterId clusterId, const EmberAfAttributeMetadata * attributeMetadata, uint8_t * buffer, uint16_t maxReadLength) @@ -124,6 +136,10 @@ Protocols::InteractionModel::Status emberAfExternalAttributeReadCallback(Endpoin case chip::app::Clusters::DishwasherMode::Id: return chefDishwasherModeReadCallback(endpoint, clusterId, attributeMetadata, buffer, maxReadLength); #endif // MATTER_DM_PLUGIN_DISHWASHER_MODE_SERVER +#ifdef MATTER_DM_PLUGIN_LAUNDRY_WASHER_MODE_SERVER + case chip::app::Clusters::LaundryWasherMode::Id: + return chefLaundryWasherModeReadCallback(endpoint, clusterId, attributeMetadata, buffer, maxReadLength); +#endif // MATTER_DM_PLUGIN_LAUNDRY_WASHER_MODE_SERVER #ifdef MATTER_DM_PLUGIN_OPERATIONAL_STATE_SERVER case chip::app::Clusters::OperationalState::Id: return chefOperationalStateReadCallback(endpoint, clusterId, attributeMetadata, buffer, maxReadLength); @@ -202,6 +218,10 @@ Protocols::InteractionModel::Status emberAfExternalAttributeWriteCallback(Endpoi case chip::app::Clusters::DishwasherMode::Id: return chefDishwasherModeWriteCallback(endpoint, clusterId, attributeMetadata, buffer); #endif // MATTER_DM_PLUGIN_DISHWASHER_MODE_SERVER +#ifdef MATTER_DM_PLUGIN_LAUNDRY_WASHER_MODE_SERVER + case chip::app::Clusters::LaundryWasherMode::Id: + return chefLaundryWasherModeWriteCallback(endpoint, clusterId, attributeMetadata, buffer); +#endif // MATTER_DM_PLUGIN_LAUNDRY_WASHER_MODE_SERVER #ifdef MATTER_DM_PLUGIN_OPERATIONAL_STATE_SERVER case chip::app::Clusters::OperationalState::Id: return chefOperationalStateWriteCallback(endpoint, clusterId, attributeMetadata, buffer); diff --git a/examples/chef/devices/rootnode_laundrywasher_fb10d238c8.matter b/examples/chef/devices/rootnode_laundrywasher_fb10d238c8.matter index f38dd8f3dfb7fd..2e76d3f34a3a85 100644 --- a/examples/chef/devices/rootnode_laundrywasher_fb10d238c8.matter +++ b/examples/chef/devices/rootnode_laundrywasher_fb10d238c8.matter @@ -241,6 +241,78 @@ struct AtomicAttributeStatusStruct { status statusCode = 1; } +/** Attributes and commands for switching devices between 'On' and 'Off' states. */ +cluster OnOff = 6 { + revision 6; + + enum DelayedAllOffEffectVariantEnum : enum8 { + kDelayedOffFastFade = 0; + kNoFade = 1; + kDelayedOffSlowFade = 2; + } + + enum DyingLightEffectVariantEnum : enum8 { + kDyingLightFadeOff = 0; + } + + enum EffectIdentifierEnum : enum8 { + kDelayedAllOff = 0; + kDyingLight = 1; + } + + enum StartUpOnOffEnum : enum8 { + kOff = 0; + kOn = 1; + kToggle = 2; + } + + bitmap Feature : bitmap32 { + kLighting = 0x1; + kDeadFrontBehavior = 0x2; + kOffOnly = 0x4; + } + + bitmap OnOffControlBitmap : bitmap8 { + kAcceptOnlyWhenOn = 0x1; + } + + readonly attribute boolean onOff = 0; + readonly attribute optional boolean globalSceneControl = 16384; + attribute optional int16u onTime = 16385; + attribute optional int16u offWaitTime = 16386; + attribute access(write: manage) optional nullable StartUpOnOffEnum startUpOnOff = 16387; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct OffWithEffectRequest { + EffectIdentifierEnum effectIdentifier = 0; + enum8 effectVariant = 1; + } + + request struct OnWithTimedOffRequest { + OnOffControlBitmap onOffControl = 0; + int16u onTime = 1; + int16u offWaitTime = 2; + } + + /** On receipt of this command, a device SHALL enter its ‘Off’ state. This state is device dependent, but it is recommended that it is used for power off or similar functions. On receipt of the Off command, the OnTime attribute SHALL be set to 0. */ + command Off(): DefaultSuccess = 0; + /** On receipt of this command, a device SHALL enter its ‘On’ state. This state is device dependent, but it is recommended that it is used for power on or similar functions. On receipt of the On command, if the value of the OnTime attribute is equal to 0, the device SHALL set the OffWaitTime attribute to 0. */ + command On(): DefaultSuccess = 1; + /** On receipt of this command, if a device is in its ‘Off’ state it SHALL enter its ‘On’ state. Otherwise, if it is in its ‘On’ state it SHALL enter its ‘Off’ state. On receipt of the Toggle command, if the value of the OnOff attribute is equal to FALSE and if the value of the OnTime attribute is equal to 0, the device SHALL set the OffWaitTime attribute to 0. If the value of the OnOff attribute is equal to TRUE, the OnTime attribute SHALL be set to 0. */ + command Toggle(): DefaultSuccess = 2; + /** The OffWithEffect command allows devices to be turned off using enhanced ways of fading. */ + command OffWithEffect(OffWithEffectRequest): DefaultSuccess = 64; + /** The OnWithRecallGlobalScene command allows the recall of the settings when the device was turned off. */ + command OnWithRecallGlobalScene(): DefaultSuccess = 65; + /** The OnWithTimedOff command allows devices to be turned on for a specific duration with a guarded off duration so that SHOULD the device be subsequently switched off, further OnWithTimedOff commands, received during this time, are prevented from turning the devices back on. */ + command OnWithTimedOff(OnWithTimedOffRequest): DefaultSuccess = 66; +} + /** The Descriptor Cluster is meant to replace the support from the Zigbee Device Object (ZDO) for describing a node, its endpoints and clusters. */ cluster Descriptor = 29 { revision 2; @@ -1345,6 +1417,38 @@ cluster LaundryWasherControls = 83 { readonly attribute int16u clusterRevision = 65533; } +/** Attributes and commands for configuring the temperature control, and reporting temperature. */ +cluster TemperatureControl = 86 { + revision 1; // NOTE: Default/not specifically set + + bitmap Feature : bitmap32 { + kTemperatureNumber = 0x1; + kTemperatureLevel = 0x2; + kTemperatureStep = 0x4; + } + + readonly attribute optional temperature temperatureSetpoint = 0; + readonly attribute optional temperature minTemperature = 1; + readonly attribute optional temperature maxTemperature = 2; + readonly attribute optional temperature step = 3; + readonly attribute optional int8u selectedTemperatureLevel = 4; + readonly attribute optional char_string supportedTemperatureLevels[] = 5; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct SetTemperatureRequest { + optional temperature targetTemperature = 0; + optional int8u targetTemperatureLevel = 1; + } + + /** Set Temperature */ + command SetTemperature(SetTemperatureRequest): DefaultSuccess = 0; +} + /** This cluster supports remotely monitoring and, where supported, changing the operational state of any device where a state machine is a part of the operation. */ cluster OperationalState = 96 { revision 1; @@ -1640,6 +1744,19 @@ endpoint 1 { device type ma_laundry_washer = 115, version 1; + server cluster OnOff { + ram attribute onOff default = 0; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute attributeList; + ram attribute featureMap default = 2; + ram attribute clusterRevision default = 6; + + handle command Off; + handle command On; + handle command Toggle; + } + server cluster Descriptor { callback attribute deviceTypeList; callback attribute serverList; @@ -1667,8 +1784,8 @@ endpoint 1 { server cluster LaundryWasherControls { callback attribute spinSpeeds; - ram attribute spinSpeedCurrent; - ram attribute numberOfRinses; + ram attribute spinSpeedCurrent default = 1; + ram attribute numberOfRinses default = 1; callback attribute supportedRinses; callback attribute generatedCommandList; callback attribute acceptedCommandList; @@ -1677,11 +1794,24 @@ endpoint 1 { ram attribute clusterRevision default = 1; } + server cluster TemperatureControl { + ram attribute selectedTemperatureLevel default = 0; + callback attribute supportedTemperatureLevels; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute attributeList; + ram attribute featureMap default = 2; + ram attribute clusterRevision default = 1; + + handle command SetTemperature; + } + server cluster OperationalState { emits event OperationalError; emits event OperationCompletion; callback attribute phaseList; callback attribute currentPhase; + callback attribute countdownTime; callback attribute operationalStateList; callback attribute operationalState; callback attribute operationalError; @@ -1694,6 +1824,7 @@ endpoint 1 { handle command Pause; handle command Stop; handle command Start; + handle command Resume; handle command OperationalCommandResponse; } } diff --git a/examples/chef/devices/rootnode_laundrywasher_fb10d238c8.zap b/examples/chef/devices/rootnode_laundrywasher_fb10d238c8.zap index 163f7e1b17ee79..4de60f90e7afa2 100644 --- a/examples/chef/devices/rootnode_laundrywasher_fb10d238c8.zap +++ b/examples/chef/devices/rootnode_laundrywasher_fb10d238c8.zap @@ -1,6 +1,6 @@ { "fileFormat": 2, - "featureLevel": 103, + "featureLevel": 104, "creator": "zap", "keyValuePairs": [ { @@ -41,14 +41,16 @@ "code": 22, "profileId": 259, "label": "MA-rootdevice", - "name": "MA-rootdevice" + "name": "MA-rootdevice", + "deviceTypeOrder": 0 }, "deviceTypes": [ { "code": 22, "profileId": 259, "label": "MA-rootdevice", - "name": "MA-rootdevice" + "name": "MA-rootdevice", + "deviceTypeOrder": 0 } ], "deviceVersions": [ @@ -2670,14 +2672,16 @@ "code": 115, "profileId": 259, "label": "MA-laundry-washer", - "name": "MA-laundry-washer" + "name": "MA-laundry-washer", + "deviceTypeOrder": 0 }, "deviceTypes": [ { "code": 115, "profileId": 259, "label": "MA-laundry-washer", - "name": "MA-laundry-washer" + "name": "MA-laundry-washer", + "deviceTypeOrder": 0 } ], "deviceVersions": [ @@ -2690,6 +2694,138 @@ "deviceTypeCode": 115, "deviceTypeProfileId": 259, "clusters": [ + { + "name": "On/Off", + "code": 6, + "mfgCode": null, + "define": "ON_OFF_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "Off", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "On", + "code": 1, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "Toggle", + "code": 2, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "OnOff", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "2", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "6", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, { "name": "Descriptor", "code": 29, @@ -2934,22 +3070,6 @@ "maxInterval": 65534, "reportableChange": 0 }, - { - "name": "EventList", - "code": 65530, - "mfgCode": null, - "side": "server", - "type": "array", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, { "name": "AttributeList", "code": 65531, @@ -3034,7 +3154,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "", + "defaultValue": "1", "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -3050,7 +3170,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "", + "defaultValue": "1", "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -3105,8 +3225,124 @@ "reportableChange": 0 }, { - "name": "EventList", - "code": 65530, + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "Temperature Control", + "code": 86, + "mfgCode": null, + "define": "TEMPERATURE_CONTROL_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "SetTemperature", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "SelectedTemperatureLevel", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "SupportedTemperatureLevels", + "code": 5, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, "mfgCode": null, "side": "server", "type": "array", @@ -3146,7 +3382,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "0", + "defaultValue": "2", "reportable": 1, "minInterval": 1, "maxInterval": 65534, @@ -3202,6 +3438,14 @@ "isIncoming": 1, "isEnabled": 1 }, + { + "name": "Resume", + "code": 3, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, { "name": "OperationalCommandResponse", "code": 4, @@ -3244,6 +3488,22 @@ "maxInterval": 65534, "reportableChange": 0 }, + { + "name": "CountdownTime", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "elapsed_s", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, { "name": "OperationalStateList", "code": 3, diff --git a/examples/chef/esp32/main/CMakeLists.txt b/examples/chef/esp32/main/CMakeLists.txt index 49f3fbabdc7113..5c8963f7735f6d 100644 --- a/examples/chef/esp32/main/CMakeLists.txt +++ b/examples/chef/esp32/main/CMakeLists.txt @@ -74,6 +74,7 @@ set(SRC_DIRS_LIST "${CMAKE_SOURCE_DIR}/../common/clusters/resource-monitoring/" "${CMAKE_SOURCE_DIR}/../common/clusters/switch/" "${CMAKE_SOURCE_DIR}/../common/clusters/target-navigator/" + "${CMAKE_SOURCE_DIR}/../common/clusters/temperature-control/" "${CMAKE_SOURCE_DIR}/../common/clusters/wake-on-lan/" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/zzz_generated/app-common/app-common/zap-generated/attributes" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/server" diff --git a/examples/chef/linux/BUILD.gn b/examples/chef/linux/BUILD.gn index a65e6e7b6ad3a0..360c5fb349d147 100644 --- a/examples/chef/linux/BUILD.gn +++ b/examples/chef/linux/BUILD.gn @@ -65,6 +65,7 @@ executable("${sample_name}") { "${project_dir}/common/clusters/switch/SwitchEventHandler.cpp", "${project_dir}/common/clusters/switch/SwitchManager.cpp", "${project_dir}/common/clusters/target-navigator/TargetNavigatorManager.cpp", + "${project_dir}/common/clusters/temperature-control/static-supported-temperature-levels.cpp", "${project_dir}/common/clusters/wake-on-lan/WakeOnLanManager.cpp", "${project_dir}/common/stubs.cpp", "${project_dir}/linux/main.cpp", diff --git a/examples/chef/nrfconnect/CMakeLists.txt b/examples/chef/nrfconnect/CMakeLists.txt index 732398cc1bf728..32def1dbf41445 100644 --- a/examples/chef/nrfconnect/CMakeLists.txt +++ b/examples/chef/nrfconnect/CMakeLists.txt @@ -101,6 +101,7 @@ target_sources(app PRIVATE ${CHEF}/common/clusters/resource-monitoring/chef-resource-monitoring-delegates.cpp ${CHEF}/common/clusters/switch/SwitchEventHandler.cpp ${CHEF}/common/clusters/switch/SwitchManager.cpp + ${CHEF}/common/clusters/temperature-control/static-supported-temperature-levels.cpp ${CHEF}/common/clusters/target-navigator/TargetNavigatorManager.cpp ${CHEF}/common/clusters/wake-on-lan/WakeOnLanManager.cpp ${CHEF}/common/stubs.cpp From 59ffe3357a433d505541ac2c9e445ca0f13f0a49 Mon Sep 17 00:00:00 2001 From: Mathieu Kardous <84793247+mkardous-silabs@users.noreply.github.com> Date: Fri, 25 Oct 2024 09:27:58 -0400 Subject: [PATCH 116/149] Don't delete components (#36238) --- integrations/docker/images/base/chip-build/version | 2 +- integrations/docker/images/stage-2/chip-build-efr32/Dockerfile | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/integrations/docker/images/base/chip-build/version b/integrations/docker/images/base/chip-build/version index 081a6389d0be23..66f5a92dc1a189 100644 --- a/integrations/docker/images/base/chip-build/version +++ b/integrations/docker/images/base/chip-build/version @@ -1 +1 @@ -87 : [Silabs] Delete SDK files to reduce the amount of flash consummed +88 : [Silabs] Leave Simplicity SDK components for SLC generation CI diff --git a/integrations/docker/images/stage-2/chip-build-efr32/Dockerfile b/integrations/docker/images/stage-2/chip-build-efr32/Dockerfile index a202e835a78256..1bb14cc56eb9b0 100644 --- a/integrations/docker/images/stage-2/chip-build-efr32/Dockerfile +++ b/integrations/docker/images/stage-2/chip-build-efr32/Dockerfile @@ -27,7 +27,6 @@ RUN wget https://github.com/SiliconLabs/simplicity_sdk/releases/download/v2024.6 && find /tmp/simplicity_sdk/hardware/board/config -mindepth 1 -maxdepth 1 -type d ! \( -name '*brd4186c*' -o -name '*brd4187c*' -o -name '*brd4186a*' -o -name '*brd4187a*' -o -name '*brd2601b*' -o -name '*brd2703a*' -o -name '*brd2704a*' \ -o -name '*brd4316a*' -o -name '*brd4317a*' -o -name '*brd4318a*' -o -name '*brd4319a*' -o -name '*brd4116a*' -o -name '*brd4117a*' -o -name '*brd4118a*' -o -name '*brd2608a*' \) -exec rm -rf {} + \ && find /tmp/simplicity_sdk/platform/Device/SiliconLabs -mindepth 1 -maxdepth 1 -type d ! \( -name 'EFR32MG24' -o -name 'EFR32MG26' -o -name 'MGM24' \) -exec rm -rf {} + \ - && find /tmp/simplicity_sdk -name "*.slc*" -type f -delete \ && : # last line # Clone WiSeConnect Wi-Fi and Bluetooth Software 2.10.3 (b6d6cb5) From 90052aaf26e1421ba756139c8590435493266bfd Mon Sep 17 00:00:00 2001 From: Mathieu Kardous <84793247+mkardous-silabs@users.noreply.github.com> Date: Fri, 25 Oct 2024 12:32:10 -0400 Subject: [PATCH 117/149] Fix docker file (#36248) --- integrations/docker/images/base/chip-build/version | 2 +- integrations/docker/images/stage-2/chip-build-efr32/Dockerfile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/integrations/docker/images/base/chip-build/version b/integrations/docker/images/base/chip-build/version index 66f5a92dc1a189..299a0b9cae5531 100644 --- a/integrations/docker/images/base/chip-build/version +++ b/integrations/docker/images/base/chip-build/version @@ -1 +1 @@ -88 : [Silabs] Leave Simplicity SDK components for SLC generation CI +89 : [Silabs] Leave Simplicity SDK components for SLC generation CI diff --git a/integrations/docker/images/stage-2/chip-build-efr32/Dockerfile b/integrations/docker/images/stage-2/chip-build-efr32/Dockerfile index 1bb14cc56eb9b0..3d8c0ae774c782 100644 --- a/integrations/docker/images/stage-2/chip-build-efr32/Dockerfile +++ b/integrations/docker/images/stage-2/chip-build-efr32/Dockerfile @@ -24,7 +24,7 @@ RUN wget https://github.com/SiliconLabs/simplicity_sdk/releases/download/v2024.6 && find /tmp/simplicity_sdk/protocol/bluetooth /tmp/simplicity_sdk/platform -name "*.a" -type f -delete \ && find /tmp/simplicity_sdk/protocol/openthread -name "*efr32mg21*" -delete \ && find /tmp/simplicity_sdk \( -name "libsl_platform_ftd_efr32mg2*" -o -name "libsl_ot_stack_mtd_efr32mg2*" \) -type f -delete \ - && find /tmp/simplicity_sdk/hardware/board/config -mindepth 1 -maxdepth 1 -type d ! \( -name '*brd4186c*' -o -name '*brd4187c*' -o -name '*brd4186a*' -o -name '*brd4187a*' -o -name '*brd2601b*' -o -name '*brd2703a*' -o -name '*brd2704a*' \ + && find /tmp/simplicity_sdk/hardware/board/config -mindepth 1 -maxdepth 1 -type d ! \( -name '*brd4186c*' -o -name '*brd4187c*' -o -name '*brd4186a*' -o -name '*brd4187a*' -o -name '*brd2601b*' -o -name '*brd2703a*' -o -name '*brd2704a*' -o -name '*component*' \ -o -name '*brd4316a*' -o -name '*brd4317a*' -o -name '*brd4318a*' -o -name '*brd4319a*' -o -name '*brd4116a*' -o -name '*brd4117a*' -o -name '*brd4118a*' -o -name '*brd2608a*' \) -exec rm -rf {} + \ && find /tmp/simplicity_sdk/platform/Device/SiliconLabs -mindepth 1 -maxdepth 1 -type d ! \( -name 'EFR32MG24' -o -name 'EFR32MG26' -o -name 'MGM24' \) -exec rm -rf {} + \ && : # last line From c7414a62643839a2b37eb63f153555720bb7ae22 Mon Sep 17 00:00:00 2001 From: Mathieu Kardous <84793247+mkardous-silabs@users.noreply.github.com> Date: Fri, 25 Oct 2024 14:34:50 -0400 Subject: [PATCH 118/149] [Silabs] Configure Light-Switch as a LIT ICD app (#36221) * Add ICD shell and make Light-switch LIT ICD * remove zcl changes * Move and rename shell files * Move ICD shells files * Start the shell structure refactor * Add lit-icd light-switch zap file * Add missing define guard * Add comment * Address review comments * remove empty change * fix gn file * Add missing include dir * zap generation * Update docker image version * restore zap templtes * Pull latest docker image * zap generation --- .github/workflows/examples-efr32.yaml | 2 +- .../light-switch-common/BUILD.gn | 7 +- .../icd-lit-light-switch-app.matter | 3244 +++++++++ .../icd-lit-light-switch-app.zap | 5812 +++++++++++++++++ .../light-switch-app/silabs/openthread.gni | 13 +- .../silabs/build_for_wifi_args.gni | 1 + examples/lit-icd-app/silabs/openthread.gni | 1 + .../lit-icd-app/silabs/src/ShellCommands.cpp | 48 - examples/platform/silabs/BaseApplication.cpp | 34 +- examples/platform/silabs/MatterConfig.cpp | 2 +- .../{matter_shell.cpp => MatterShell.cpp} | 2 +- .../silabs/{matter_shell.h => MatterShell.h} | 0 examples/platform/silabs/SiWx917/BUILD.gn | 32 +- examples/platform/silabs/efr32/BUILD.gn | 32 +- examples/platform/silabs/shell/BUILD.gn | 39 + .../silabs/shell/ICDShellCommands.cpp | 119 + .../silabs/shell/ICDShellCommands.h} | 11 +- examples/platform/silabs/uart.cpp | 4 +- integrations/cloudbuild/smoke-test.yaml | 14 +- src/lib/shell/MainLoopSilabs.cpp | 2 +- src/test_driver/efr32/BUILD.gn | 2 +- 21 files changed, 9304 insertions(+), 117 deletions(-) create mode 100644 examples/light-switch-app/light-switch-common/icd-lit-light-switch-app.matter create mode 100644 examples/light-switch-app/light-switch-common/icd-lit-light-switch-app.zap delete mode 100644 examples/lit-icd-app/silabs/src/ShellCommands.cpp rename examples/platform/silabs/{matter_shell.cpp => MatterShell.cpp} (99%) rename examples/platform/silabs/{matter_shell.h => MatterShell.h} (100%) create mode 100644 examples/platform/silabs/shell/BUILD.gn create mode 100644 examples/platform/silabs/shell/ICDShellCommands.cpp rename examples/{lit-icd-app/silabs/include/ShellCommands.h => platform/silabs/shell/ICDShellCommands.h} (82%) diff --git a/.github/workflows/examples-efr32.yaml b/.github/workflows/examples-efr32.yaml index b0b4fef50e15df..ab85bc1f6c9cdf 100644 --- a/.github/workflows/examples-efr32.yaml +++ b/.github/workflows/examples-efr32.yaml @@ -41,7 +41,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-efr32:85 + image: ghcr.io/project-chip/chip-build-efr32:89 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" steps: diff --git a/examples/light-switch-app/light-switch-common/BUILD.gn b/examples/light-switch-app/light-switch-common/BUILD.gn index 8ec49aac0fa870..e9ec438656e43d 100644 --- a/examples/light-switch-app/light-switch-common/BUILD.gn +++ b/examples/light-switch-app/light-switch-common/BUILD.gn @@ -14,8 +14,13 @@ import("//build_overrides/chip.gni") import("${chip_root}/src/app/chip_data_model.gni") +import("${chip_root}/src/app/icd/icd.gni") chip_data_model("light-switch-common") { - zap_file = "light-switch-app.zap" + if (chip_enable_icd_lit) { + zap_file = "icd-lit-light-switch-app.zap" + } else { + zap_file = "light-switch-app.zap" + } is_server = true } diff --git a/examples/light-switch-app/light-switch-common/icd-lit-light-switch-app.matter b/examples/light-switch-app/light-switch-common/icd-lit-light-switch-app.matter new file mode 100644 index 00000000000000..67ed0ab5715709 --- /dev/null +++ b/examples/light-switch-app/light-switch-common/icd-lit-light-switch-app.matter @@ -0,0 +1,3244 @@ +// This IDL was generated automatically by ZAP. +// It is for view/code review purposes only. + +enum AreaTypeTag : enum8 { + kAisle = 0; + kAttic = 1; + kBackDoor = 2; + kBackYard = 3; + kBalcony = 4; + kBallroom = 5; + kBathroom = 6; + kBedroom = 7; + kBorder = 8; + kBoxroom = 9; + kBreakfastRoom = 10; + kCarport = 11; + kCellar = 12; + kCloakroom = 13; + kCloset = 14; + kConservatory = 15; + kCorridor = 16; + kCraftRoom = 17; + kCupboard = 18; + kDeck = 19; + kDen = 20; + kDining = 21; + kDrawingRoom = 22; + kDressingRoom = 23; + kDriveway = 24; + kElevator = 25; + kEnsuite = 26; + kEntrance = 27; + kEntryway = 28; + kFamilyRoom = 29; + kFoyer = 30; + kFrontDoor = 31; + kFrontYard = 32; + kGameRoom = 33; + kGarage = 34; + kGarageDoor = 35; + kGarden = 36; + kGardenDoor = 37; + kGuestBathroom = 38; + kGuestBedroom = 39; + kGuestRestroom = 40; + kGuestRoom = 41; + kGym = 42; + kHallway = 43; + kHearthRoom = 44; + kKidsRoom = 45; + kKidsBedroom = 46; + kKitchen = 47; + kLarder = 48; + kLaundryRoom = 49; + kLawn = 50; + kLibrary = 51; + kLivingRoom = 52; + kLounge = 53; + kMediaTVRoom = 54; + kMudRoom = 55; + kMusicRoom = 56; + kNursery = 57; + kOffice = 58; + kOutdoorKitchen = 59; + kOutside = 60; + kPantry = 61; + kParkingLot = 62; + kParlor = 63; + kPatio = 64; + kPlayRoom = 65; + kPoolRoom = 66; + kPorch = 67; + kPrimaryBathroom = 68; + kPrimaryBedroom = 69; + kRamp = 70; + kReceptionRoom = 71; + kRecreationRoom = 72; + kRestroom = 73; + kRoof = 74; + kSauna = 75; + kScullery = 76; + kSewingRoom = 77; + kShed = 78; + kSideDoor = 79; + kSideYard = 80; + kSittingRoom = 81; + kSnug = 82; + kSpa = 83; + kStaircase = 84; + kSteamRoom = 85; + kStorageRoom = 86; + kStudio = 87; + kStudy = 88; + kSunRoom = 89; + kSwimmingPool = 90; + kTerrace = 91; + kUtilityRoom = 92; + kWard = 93; + kWorkshop = 94; +} + +enum AtomicRequestTypeEnum : enum8 { + kBeginWrite = 0; + kCommitWrite = 1; + kRollbackWrite = 2; +} + +enum FloorSurfaceTag : enum8 { + kCarpet = 0; + kCeramic = 1; + kConcrete = 2; + kCork = 3; + kDeepCarpet = 4; + kDirt = 5; + kEngineeredWood = 6; + kGlass = 7; + kGrass = 8; + kHardwood = 9; + kLaminate = 10; + kLinoleum = 11; + kMat = 12; + kMetal = 13; + kPlastic = 14; + kPolishedConcrete = 15; + kRubber = 16; + kRug = 17; + kSand = 18; + kStone = 19; + kTatami = 20; + kTerrazzo = 21; + kTile = 22; + kVinyl = 23; +} + +enum LandmarkTag : enum8 { + kAirConditioner = 0; + kAirPurifier = 1; + kBackDoor = 2; + kBarStool = 3; + kBathMat = 4; + kBathtub = 5; + kBed = 6; + kBookshelf = 7; + kChair = 8; + kChristmasTree = 9; + kCoatRack = 10; + kCoffeeTable = 11; + kCookingRange = 12; + kCouch = 13; + kCountertop = 14; + kCradle = 15; + kCrib = 16; + kDesk = 17; + kDiningTable = 18; + kDishwasher = 19; + kDoor = 20; + kDresser = 21; + kLaundryDryer = 22; + kFan = 23; + kFireplace = 24; + kFreezer = 25; + kFrontDoor = 26; + kHighChair = 27; + kKitchenIsland = 28; + kLamp = 29; + kLitterBox = 30; + kMirror = 31; + kNightstand = 32; + kOven = 33; + kPetBed = 34; + kPetBowl = 35; + kPetCrate = 36; + kRefrigerator = 37; + kScratchingPost = 38; + kShoeRack = 39; + kShower = 40; + kSideDoor = 41; + kSink = 42; + kSofa = 43; + kStove = 44; + kTable = 45; + kToilet = 46; + kTrashCan = 47; + kLaundryWasher = 48; + kWindow = 49; + kWineCooler = 50; +} + +enum PositionTag : enum8 { + kLeft = 0; + kRight = 1; + kTop = 2; + kBottom = 3; + kMiddle = 4; + kRow = 5; + kColumn = 6; +} + +enum RelativePositionTag : enum8 { + kUnder = 0; + kNextTo = 1; + kAround = 2; + kOn = 3; + kAbove = 4; + kFrontOf = 5; + kBehind = 6; +} + +enum TestGlobalEnum : enum8 { + kSomeValue = 0; + kSomeOtherValue = 1; + kFinalValue = 2; +} + +enum ThreeLevelAutoEnum : enum8 { + kLow = 0; + kMedium = 1; + kHigh = 2; + kAutomatic = 3; +} + +bitmap TestGlobalBitmap : bitmap32 { + kFirstBit = 0x1; + kSecondBit = 0x2; +} + +struct TestGlobalStruct { + char_string<128> name = 0; + nullable TestGlobalBitmap myBitmap = 1; + optional nullable TestGlobalEnum myEnum = 2; +} + +struct LocationDescriptorStruct { + char_string<128> locationName = 0; + nullable int16s floorNumber = 1; + nullable AreaTypeTag areaType = 2; +} + +struct AtomicAttributeStatusStruct { + attrib_id attributeID = 0; + status statusCode = 1; +} + +/** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ +cluster Identify = 3 { + revision 4; + + enum EffectIdentifierEnum : enum8 { + kBlink = 0; + kBreathe = 1; + kOkay = 2; + kChannelChange = 11; + kFinishEffect = 254; + kStopEffect = 255; + } + + enum EffectVariantEnum : enum8 { + kDefault = 0; + } + + enum IdentifyTypeEnum : enum8 { + kNone = 0; + kLightOutput = 1; + kVisibleIndicator = 2; + kAudibleBeep = 3; + kDisplay = 4; + kActuator = 5; + } + + attribute int16u identifyTime = 0; + readonly attribute IdentifyTypeEnum identifyType = 1; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct IdentifyRequest { + int16u identifyTime = 0; + } + + request struct TriggerEffectRequest { + EffectIdentifierEnum effectIdentifier = 0; + EffectVariantEnum effectVariant = 1; + } + + /** Command description for Identify */ + command access(invoke: manage) Identify(IdentifyRequest): DefaultSuccess = 0; + /** Command description for TriggerEffect */ + command access(invoke: manage) TriggerEffect(TriggerEffectRequest): DefaultSuccess = 64; +} + +/** Attributes and commands for putting a device into Identification mode (e.g. flashing a light). */ +cluster Identify = 3 { + revision 4; + + enum EffectIdentifierEnum : enum8 { + kBlink = 0; + kBreathe = 1; + kOkay = 2; + kChannelChange = 11; + kFinishEffect = 254; + kStopEffect = 255; + } + + enum EffectVariantEnum : enum8 { + kDefault = 0; + } + + enum IdentifyTypeEnum : enum8 { + kNone = 0; + kLightOutput = 1; + kVisibleIndicator = 2; + kAudibleBeep = 3; + kDisplay = 4; + kActuator = 5; + } + + attribute int16u identifyTime = 0; + readonly attribute IdentifyTypeEnum identifyType = 1; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct IdentifyRequest { + int16u identifyTime = 0; + } + + request struct TriggerEffectRequest { + EffectIdentifierEnum effectIdentifier = 0; + EffectVariantEnum effectVariant = 1; + } + + /** Command description for Identify */ + command access(invoke: manage) Identify(IdentifyRequest): DefaultSuccess = 0; + /** Command description for TriggerEffect */ + command access(invoke: manage) TriggerEffect(TriggerEffectRequest): DefaultSuccess = 64; +} + +/** Attributes and commands for group configuration and manipulation. */ +cluster Groups = 4 { + revision 4; + + bitmap Feature : bitmap32 { + kGroupNames = 0x1; + } + + bitmap NameSupportBitmap : bitmap8 { + kGroupNames = 0x80; + } + + readonly attribute NameSupportBitmap nameSupport = 0; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct AddGroupRequest { + group_id groupID = 0; + char_string<16> groupName = 1; + } + + response struct AddGroupResponse = 0 { + enum8 status = 0; + group_id groupID = 1; + } + + request struct ViewGroupRequest { + group_id groupID = 0; + } + + response struct ViewGroupResponse = 1 { + enum8 status = 0; + group_id groupID = 1; + char_string<16> groupName = 2; + } + + request struct GetGroupMembershipRequest { + group_id groupList[] = 0; + } + + response struct GetGroupMembershipResponse = 2 { + nullable int8u capacity = 0; + group_id groupList[] = 1; + } + + request struct RemoveGroupRequest { + group_id groupID = 0; + } + + response struct RemoveGroupResponse = 3 { + enum8 status = 0; + group_id groupID = 1; + } + + request struct AddGroupIfIdentifyingRequest { + group_id groupID = 0; + char_string<16> groupName = 1; + } + + /** Command description for AddGroup */ + fabric command access(invoke: manage) AddGroup(AddGroupRequest): AddGroupResponse = 0; + /** Command description for ViewGroup */ + fabric command ViewGroup(ViewGroupRequest): ViewGroupResponse = 1; + /** Command description for GetGroupMembership */ + fabric command GetGroupMembership(GetGroupMembershipRequest): GetGroupMembershipResponse = 2; + /** Command description for RemoveGroup */ + fabric command access(invoke: manage) RemoveGroup(RemoveGroupRequest): RemoveGroupResponse = 3; + /** Command description for RemoveAllGroups */ + fabric command access(invoke: manage) RemoveAllGroups(): DefaultSuccess = 4; + /** Command description for AddGroupIfIdentifying */ + fabric command access(invoke: manage) AddGroupIfIdentifying(AddGroupIfIdentifyingRequest): DefaultSuccess = 5; +} + +/** Attributes and commands for switching devices between 'On' and 'Off' states. */ +cluster OnOff = 6 { + revision 6; + + enum DelayedAllOffEffectVariantEnum : enum8 { + kDelayedOffFastFade = 0; + kNoFade = 1; + kDelayedOffSlowFade = 2; + } + + enum DyingLightEffectVariantEnum : enum8 { + kDyingLightFadeOff = 0; + } + + enum EffectIdentifierEnum : enum8 { + kDelayedAllOff = 0; + kDyingLight = 1; + } + + enum StartUpOnOffEnum : enum8 { + kOff = 0; + kOn = 1; + kToggle = 2; + } + + bitmap Feature : bitmap32 { + kLighting = 0x1; + kDeadFrontBehavior = 0x2; + kOffOnly = 0x4; + } + + bitmap OnOffControlBitmap : bitmap8 { + kAcceptOnlyWhenOn = 0x1; + } + + readonly attribute boolean onOff = 0; + readonly attribute optional boolean globalSceneControl = 16384; + attribute optional int16u onTime = 16385; + attribute optional int16u offWaitTime = 16386; + attribute access(write: manage) optional nullable StartUpOnOffEnum startUpOnOff = 16387; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct OffWithEffectRequest { + EffectIdentifierEnum effectIdentifier = 0; + enum8 effectVariant = 1; + } + + request struct OnWithTimedOffRequest { + OnOffControlBitmap onOffControl = 0; + int16u onTime = 1; + int16u offWaitTime = 2; + } + + /** On receipt of this command, a device SHALL enter its ‘Off’ state. This state is device dependent, but it is recommended that it is used for power off or similar functions. On receipt of the Off command, the OnTime attribute SHALL be set to 0. */ + command Off(): DefaultSuccess = 0; + /** On receipt of this command, a device SHALL enter its ‘On’ state. This state is device dependent, but it is recommended that it is used for power on or similar functions. On receipt of the On command, if the value of the OnTime attribute is equal to 0, the device SHALL set the OffWaitTime attribute to 0. */ + command On(): DefaultSuccess = 1; + /** On receipt of this command, if a device is in its ‘Off’ state it SHALL enter its ‘On’ state. Otherwise, if it is in its ‘On’ state it SHALL enter its ‘Off’ state. On receipt of the Toggle command, if the value of the OnOff attribute is equal to FALSE and if the value of the OnTime attribute is equal to 0, the device SHALL set the OffWaitTime attribute to 0. If the value of the OnOff attribute is equal to TRUE, the OnTime attribute SHALL be set to 0. */ + command Toggle(): DefaultSuccess = 2; + /** The OffWithEffect command allows devices to be turned off using enhanced ways of fading. */ + command OffWithEffect(OffWithEffectRequest): DefaultSuccess = 64; + /** The OnWithRecallGlobalScene command allows the recall of the settings when the device was turned off. */ + command OnWithRecallGlobalScene(): DefaultSuccess = 65; + /** The OnWithTimedOff command allows devices to be turned on for a specific duration with a guarded off duration so that SHOULD the device be subsequently switched off, further OnWithTimedOff commands, received during this time, are prevented from turning the devices back on. */ + command OnWithTimedOff(OnWithTimedOffRequest): DefaultSuccess = 66; +} + +/** The Descriptor Cluster is meant to replace the support from the Zigbee Device Object (ZDO) for describing a node, its endpoints and clusters. */ +cluster Descriptor = 29 { + revision 2; + + bitmap Feature : bitmap32 { + kTagList = 0x1; + } + + struct DeviceTypeStruct { + devtype_id deviceType = 0; + int16u revision = 1; + } + + struct SemanticTagStruct { + nullable vendor_id mfgCode = 0; + enum8 namespaceID = 1; + enum8 tag = 2; + optional nullable char_string label = 3; + } + + readonly attribute DeviceTypeStruct deviceTypeList[] = 0; + readonly attribute cluster_id serverList[] = 1; + readonly attribute cluster_id clientList[] = 2; + readonly attribute endpoint_no partsList[] = 3; + readonly attribute optional SemanticTagStruct tagList[] = 4; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; +} + +/** The Binding Cluster is meant to replace the support from the Zigbee Device Object (ZDO) for supporting the binding table. */ +cluster Binding = 30 { + revision 1; // NOTE: Default/not specifically set + + fabric_scoped struct TargetStruct { + optional node_id node = 1; + optional group_id group = 2; + optional endpoint_no endpoint = 3; + optional cluster_id cluster = 4; + fabric_idx fabricIndex = 254; + } + + attribute access(write: manage) TargetStruct binding[] = 0; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; +} + +/** The Access Control Cluster exposes a data model view of a + Node's Access Control List (ACL), which codifies the rules used to manage + and enforce Access Control for the Node's endpoints and their associated + cluster instances. */ +cluster AccessControl = 31 { + revision 2; + + enum AccessControlEntryAuthModeEnum : enum8 { + kPASE = 1; + kCASE = 2; + kGroup = 3; + } + + enum AccessControlEntryPrivilegeEnum : enum8 { + kView = 1; + kProxyView = 2; + kOperate = 3; + kManage = 4; + kAdminister = 5; + } + + enum AccessRestrictionTypeEnum : enum8 { + kAttributeAccessForbidden = 0; + kAttributeWriteForbidden = 1; + kCommandForbidden = 2; + kEventForbidden = 3; + } + + enum ChangeTypeEnum : enum8 { + kChanged = 0; + kAdded = 1; + kRemoved = 2; + } + + bitmap Feature : bitmap32 { + kExtension = 0x1; + kManagedDevice = 0x2; + } + + struct AccessRestrictionStruct { + AccessRestrictionTypeEnum type = 0; + nullable int32u id = 1; + } + + struct CommissioningAccessRestrictionEntryStruct { + endpoint_no endpoint = 0; + cluster_id cluster = 1; + AccessRestrictionStruct restrictions[] = 2; + } + + fabric_scoped struct AccessRestrictionEntryStruct { + fabric_sensitive endpoint_no endpoint = 0; + fabric_sensitive cluster_id cluster = 1; + fabric_sensitive AccessRestrictionStruct restrictions[] = 2; + fabric_idx fabricIndex = 254; + } + + struct AccessControlTargetStruct { + nullable cluster_id cluster = 0; + nullable endpoint_no endpoint = 1; + nullable devtype_id deviceType = 2; + } + + fabric_scoped struct AccessControlEntryStruct { + fabric_sensitive AccessControlEntryPrivilegeEnum privilege = 1; + fabric_sensitive AccessControlEntryAuthModeEnum authMode = 2; + nullable fabric_sensitive int64u subjects[] = 3; + nullable fabric_sensitive AccessControlTargetStruct targets[] = 4; + fabric_idx fabricIndex = 254; + } + + fabric_scoped struct AccessControlExtensionStruct { + fabric_sensitive octet_string<128> data = 1; + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) AccessControlEntryChanged = 0 { + nullable node_id adminNodeID = 1; + nullable int16u adminPasscodeID = 2; + ChangeTypeEnum changeType = 3; + nullable AccessControlEntryStruct latestValue = 4; + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) AccessControlExtensionChanged = 1 { + nullable node_id adminNodeID = 1; + nullable int16u adminPasscodeID = 2; + ChangeTypeEnum changeType = 3; + nullable AccessControlExtensionStruct latestValue = 4; + fabric_idx fabricIndex = 254; + } + + fabric_sensitive info event access(read: administer) FabricRestrictionReviewUpdate = 2 { + int64u token = 0; + optional long_char_string instruction = 1; + optional long_char_string ARLRequestFlowUrl = 2; + fabric_idx fabricIndex = 254; + } + + attribute access(read: administer, write: administer) AccessControlEntryStruct acl[] = 0; + attribute access(read: administer, write: administer) optional AccessControlExtensionStruct extension[] = 1; + readonly attribute int16u subjectsPerAccessControlEntry = 2; + readonly attribute int16u targetsPerAccessControlEntry = 3; + readonly attribute int16u accessControlEntriesPerFabric = 4; + readonly attribute optional CommissioningAccessRestrictionEntryStruct commissioningARL[] = 5; + readonly attribute optional AccessRestrictionEntryStruct arl[] = 6; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct ReviewFabricRestrictionsRequest { + CommissioningAccessRestrictionEntryStruct arl[] = 0; + } + + response struct ReviewFabricRestrictionsResponse = 1 { + int64u token = 0; + } + + /** This command signals to the service associated with the device vendor that the fabric administrator would like a review of the current restrictions on the accessing fabric. */ + fabric command access(invoke: administer) ReviewFabricRestrictions(ReviewFabricRestrictionsRequest): ReviewFabricRestrictionsResponse = 0; +} + +/** This cluster provides attributes and events for determining basic information about Nodes, which supports both + Commissioning and operational determination of Node characteristics, such as Vendor ID, Product ID and serial number, + which apply to the whole Node. Also allows setting user device information such as location. */ +cluster BasicInformation = 40 { + revision 3; + + enum ColorEnum : enum8 { + kBlack = 0; + kNavy = 1; + kGreen = 2; + kTeal = 3; + kMaroon = 4; + kPurple = 5; + kOlive = 6; + kGray = 7; + kBlue = 8; + kLime = 9; + kAqua = 10; + kRed = 11; + kFuchsia = 12; + kYellow = 13; + kWhite = 14; + kNickel = 15; + kChrome = 16; + kBrass = 17; + kCopper = 18; + kSilver = 19; + kGold = 20; + } + + enum ProductFinishEnum : enum8 { + kOther = 0; + kMatte = 1; + kSatin = 2; + kPolished = 3; + kRugged = 4; + kFabric = 5; + } + + struct CapabilityMinimaStruct { + int16u caseSessionsPerFabric = 0; + int16u subscriptionsPerFabric = 1; + } + + struct ProductAppearanceStruct { + ProductFinishEnum finish = 0; + nullable ColorEnum primaryColor = 1; + } + + critical event StartUp = 0 { + int32u softwareVersion = 0; + } + + critical event ShutDown = 1 { + } + + info event Leave = 2 { + fabric_idx fabricIndex = 0; + } + + info event ReachableChanged = 3 { + boolean reachableNewValue = 0; + } + + readonly attribute int16u dataModelRevision = 0; + readonly attribute char_string<32> vendorName = 1; + readonly attribute vendor_id vendorID = 2; + readonly attribute char_string<32> productName = 3; + readonly attribute int16u productID = 4; + attribute access(write: manage) char_string<32> nodeLabel = 5; + attribute access(write: administer) char_string<2> location = 6; + readonly attribute int16u hardwareVersion = 7; + readonly attribute char_string<64> hardwareVersionString = 8; + readonly attribute int32u softwareVersion = 9; + readonly attribute char_string<64> softwareVersionString = 10; + readonly attribute optional char_string<16> manufacturingDate = 11; + readonly attribute optional char_string<32> partNumber = 12; + readonly attribute optional long_char_string<256> productURL = 13; + readonly attribute optional char_string<64> productLabel = 14; + readonly attribute optional char_string<32> serialNumber = 15; + attribute access(write: manage) optional boolean localConfigDisabled = 16; + readonly attribute optional boolean reachable = 17; + readonly attribute char_string<32> uniqueID = 18; + readonly attribute CapabilityMinimaStruct capabilityMinima = 19; + readonly attribute optional ProductAppearanceStruct productAppearance = 20; + readonly attribute int32u specificationVersion = 21; + readonly attribute int16u maxPathsPerInvoke = 22; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + command MfgSpecificPing(): DefaultSuccess = 0; +} + +/** Provides an interface for providing OTA software updates */ +cluster OtaSoftwareUpdateProvider = 41 { + revision 1; // NOTE: Default/not specifically set + + enum ApplyUpdateActionEnum : enum8 { + kProceed = 0; + kAwaitNextAction = 1; + kDiscontinue = 2; + } + + enum DownloadProtocolEnum : enum8 { + kBDXSynchronous = 0; + kBDXAsynchronous = 1; + kHTTPS = 2; + kVendorSpecific = 3; + } + + enum StatusEnum : enum8 { + kUpdateAvailable = 0; + kBusy = 1; + kNotAvailable = 2; + kDownloadProtocolNotSupported = 3; + } + + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct QueryImageRequest { + vendor_id vendorID = 0; + int16u productID = 1; + int32u softwareVersion = 2; + DownloadProtocolEnum protocolsSupported[] = 3; + optional int16u hardwareVersion = 4; + optional char_string<2> location = 5; + optional boolean requestorCanConsent = 6; + optional octet_string<512> metadataForProvider = 7; + } + + response struct QueryImageResponse = 1 { + StatusEnum status = 0; + optional int32u delayedActionTime = 1; + optional char_string<256> imageURI = 2; + optional int32u softwareVersion = 3; + optional char_string<64> softwareVersionString = 4; + optional octet_string<32> updateToken = 5; + optional boolean userConsentNeeded = 6; + optional octet_string<512> metadataForRequestor = 7; + } + + request struct ApplyUpdateRequestRequest { + octet_string<32> updateToken = 0; + int32u newVersion = 1; + } + + response struct ApplyUpdateResponse = 3 { + ApplyUpdateActionEnum action = 0; + int32u delayedActionTime = 1; + } + + request struct NotifyUpdateAppliedRequest { + octet_string<32> updateToken = 0; + int32u softwareVersion = 1; + } + + /** Determine availability of a new Software Image */ + command QueryImage(QueryImageRequest): QueryImageResponse = 0; + /** Determine next action to take for a downloaded Software Image */ + command ApplyUpdateRequest(ApplyUpdateRequestRequest): ApplyUpdateResponse = 2; + /** Notify OTA Provider that an update was applied */ + command NotifyUpdateApplied(NotifyUpdateAppliedRequest): DefaultSuccess = 4; +} + +/** Provides an interface for downloading and applying OTA software updates */ +cluster OtaSoftwareUpdateRequestor = 42 { + revision 1; // NOTE: Default/not specifically set + + enum AnnouncementReasonEnum : enum8 { + kSimpleAnnouncement = 0; + kUpdateAvailable = 1; + kUrgentUpdateAvailable = 2; + } + + enum ChangeReasonEnum : enum8 { + kUnknown = 0; + kSuccess = 1; + kFailure = 2; + kTimeOut = 3; + kDelayByProvider = 4; + } + + enum UpdateStateEnum : enum8 { + kUnknown = 0; + kIdle = 1; + kQuerying = 2; + kDelayedOnQuery = 3; + kDownloading = 4; + kApplying = 5; + kDelayedOnApply = 6; + kRollingBack = 7; + kDelayedOnUserConsent = 8; + } + + fabric_scoped struct ProviderLocation { + node_id providerNodeID = 1; + endpoint_no endpoint = 2; + fabric_idx fabricIndex = 254; + } + + info event StateTransition = 0 { + UpdateStateEnum previousState = 0; + UpdateStateEnum newState = 1; + ChangeReasonEnum reason = 2; + nullable int32u targetSoftwareVersion = 3; + } + + critical event VersionApplied = 1 { + int32u softwareVersion = 0; + int16u productID = 1; + } + + info event DownloadError = 2 { + int32u softwareVersion = 0; + int64u bytesDownloaded = 1; + nullable int8u progressPercent = 2; + nullable int64s platformCode = 3; + } + + attribute access(write: administer) ProviderLocation defaultOTAProviders[] = 0; + readonly attribute boolean updatePossible = 1; + readonly attribute UpdateStateEnum updateState = 2; + readonly attribute nullable int8u updateStateProgress = 3; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct AnnounceOTAProviderRequest { + node_id providerNodeID = 0; + vendor_id vendorID = 1; + AnnouncementReasonEnum announcementReason = 2; + optional octet_string<512> metadataForNode = 3; + endpoint_no endpoint = 4; + } + + /** Announce the presence of an OTA Provider */ + command AnnounceOTAProvider(AnnounceOTAProviderRequest): DefaultSuccess = 0; +} + +/** This cluster is used to manage global aspects of the Commissioning flow. */ +cluster GeneralCommissioning = 48 { + revision 1; // NOTE: Default/not specifically set + + enum CommissioningErrorEnum : enum8 { + kOK = 0; + kValueOutsideRange = 1; + kInvalidAuthentication = 2; + kNoFailSafe = 3; + kBusyWithOtherAdmin = 4; + kRequiredTCNotAccepted = 5; + kTCAcknowledgementsNotReceived = 6; + kTCMinVersionNotMet = 7; + } + + enum RegulatoryLocationTypeEnum : enum8 { + kIndoor = 0; + kOutdoor = 1; + kIndoorOutdoor = 2; + } + + bitmap Feature : bitmap32 { + kTermsAndConditions = 0x1; + } + + struct BasicCommissioningInfo { + int16u failSafeExpiryLengthSeconds = 0; + int16u maxCumulativeFailsafeSeconds = 1; + } + + attribute access(write: administer) int64u breadcrumb = 0; + readonly attribute BasicCommissioningInfo basicCommissioningInfo = 1; + readonly attribute RegulatoryLocationTypeEnum regulatoryConfig = 2; + readonly attribute RegulatoryLocationTypeEnum locationCapability = 3; + readonly attribute boolean supportsConcurrentConnection = 4; + provisional readonly attribute access(read: administer) optional int16u TCAcceptedVersion = 5; + provisional readonly attribute access(read: administer) optional int16u TCMinRequiredVersion = 6; + provisional readonly attribute access(read: administer) optional bitmap16 TCAcknowledgements = 7; + provisional readonly attribute access(read: administer) optional boolean TCAcknowledgementsRequired = 8; + provisional readonly attribute access(read: administer) optional int32u TCUpdateDeadline = 9; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct ArmFailSafeRequest { + int16u expiryLengthSeconds = 0; + int64u breadcrumb = 1; + } + + response struct ArmFailSafeResponse = 1 { + CommissioningErrorEnum errorCode = 0; + char_string<128> debugText = 1; + } + + request struct SetRegulatoryConfigRequest { + RegulatoryLocationTypeEnum newRegulatoryConfig = 0; + char_string<2> countryCode = 1; + int64u breadcrumb = 2; + } + + response struct SetRegulatoryConfigResponse = 3 { + CommissioningErrorEnum errorCode = 0; + char_string debugText = 1; + } + + response struct CommissioningCompleteResponse = 5 { + CommissioningErrorEnum errorCode = 0; + char_string debugText = 1; + } + + request struct SetTCAcknowledgementsRequest { + int16u TCVersion = 0; + bitmap16 TCUserResponse = 1; + } + + response struct SetTCAcknowledgementsResponse = 7 { + CommissioningErrorEnum errorCode = 0; + } + + /** Arm the persistent fail-safe timer with an expiry time of now + ExpiryLengthSeconds using device clock */ + command access(invoke: administer) ArmFailSafe(ArmFailSafeRequest): ArmFailSafeResponse = 0; + /** Set the regulatory configuration to be used during commissioning */ + command access(invoke: administer) SetRegulatoryConfig(SetRegulatoryConfigRequest): SetRegulatoryConfigResponse = 2; + /** Signals the Server that the Client has successfully completed all steps of Commissioning/Recofiguration needed during fail-safe period. */ + fabric command access(invoke: administer) CommissioningComplete(): CommissioningCompleteResponse = 4; + /** This command sets the user acknowledgements received in the Enhanced Setup Flow Terms and Conditions into the node. */ + command access(invoke: administer) SetTCAcknowledgements(SetTCAcknowledgementsRequest): SetTCAcknowledgementsResponse = 6; +} + +/** Functionality to configure, enable, disable network credentials and access on a Matter device. */ +cluster NetworkCommissioning = 49 { + revision 1; // NOTE: Default/not specifically set + + enum NetworkCommissioningStatusEnum : enum8 { + kSuccess = 0; + kOutOfRange = 1; + kBoundsExceeded = 2; + kNetworkIDNotFound = 3; + kDuplicateNetworkID = 4; + kNetworkNotFound = 5; + kRegulatoryError = 6; + kAuthFailure = 7; + kUnsupportedSecurity = 8; + kOtherConnectionFailure = 9; + kIPV6Failed = 10; + kIPBindFailed = 11; + kUnknownError = 12; + } + + enum WiFiBandEnum : enum8 { + k2G4 = 0; + k3G65 = 1; + k5G = 2; + k6G = 3; + k60G = 4; + k1G = 5; + } + + bitmap Feature : bitmap32 { + kWiFiNetworkInterface = 0x1; + kThreadNetworkInterface = 0x2; + kEthernetNetworkInterface = 0x4; + kPerDeviceCredentials = 0x8; + } + + bitmap ThreadCapabilitiesBitmap : bitmap16 { + kIsBorderRouterCapable = 0x1; + kIsRouterCapable = 0x2; + kIsSleepyEndDeviceCapable = 0x4; + kIsFullThreadDevice = 0x8; + kIsSynchronizedSleepyEndDeviceCapable = 0x10; + } + + bitmap WiFiSecurityBitmap : bitmap8 { + kUnencrypted = 0x1; + kWEP = 0x2; + kWPAPersonal = 0x4; + kWPA2Personal = 0x8; + kWPA3Personal = 0x10; + kWPA3MatterPDC = 0x20; + } + + struct NetworkInfoStruct { + octet_string<32> networkID = 0; + boolean connected = 1; + optional nullable octet_string<20> networkIdentifier = 2; + optional nullable octet_string<20> clientIdentifier = 3; + } + + struct ThreadInterfaceScanResultStruct { + int16u panId = 0; + int64u extendedPanId = 1; + char_string<16> networkName = 2; + int16u channel = 3; + int8u version = 4; + octet_string<8> extendedAddress = 5; + int8s rssi = 6; + int8u lqi = 7; + } + + struct WiFiInterfaceScanResultStruct { + WiFiSecurityBitmap security = 0; + octet_string<32> ssid = 1; + octet_string<6> bssid = 2; + int16u channel = 3; + WiFiBandEnum wiFiBand = 4; + int8s rssi = 5; + } + + readonly attribute access(read: administer) int8u maxNetworks = 0; + readonly attribute access(read: administer) NetworkInfoStruct networks[] = 1; + readonly attribute optional int8u scanMaxTimeSeconds = 2; + readonly attribute optional int8u connectMaxTimeSeconds = 3; + attribute access(write: administer) boolean interfaceEnabled = 4; + readonly attribute access(read: administer) nullable NetworkCommissioningStatusEnum lastNetworkingStatus = 5; + readonly attribute access(read: administer) nullable octet_string<32> lastNetworkID = 6; + readonly attribute access(read: administer) nullable int32s lastConnectErrorValue = 7; + provisional readonly attribute optional WiFiBandEnum supportedWiFiBands[] = 8; + provisional readonly attribute optional ThreadCapabilitiesBitmap supportedThreadFeatures = 9; + provisional readonly attribute optional int16u threadVersion = 10; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct ScanNetworksRequest { + optional nullable octet_string<32> ssid = 0; + optional int64u breadcrumb = 1; + } + + response struct ScanNetworksResponse = 1 { + NetworkCommissioningStatusEnum networkingStatus = 0; + optional char_string debugText = 1; + optional WiFiInterfaceScanResultStruct wiFiScanResults[] = 2; + optional ThreadInterfaceScanResultStruct threadScanResults[] = 3; + } + + request struct AddOrUpdateWiFiNetworkRequest { + octet_string<32> ssid = 0; + octet_string<64> credentials = 1; + optional int64u breadcrumb = 2; + optional octet_string<140> networkIdentity = 3; + optional octet_string<20> clientIdentifier = 4; + optional octet_string<32> possessionNonce = 5; + } + + request struct AddOrUpdateThreadNetworkRequest { + octet_string<254> operationalDataset = 0; + optional int64u breadcrumb = 1; + } + + request struct RemoveNetworkRequest { + octet_string<32> networkID = 0; + optional int64u breadcrumb = 1; + } + + response struct NetworkConfigResponse = 5 { + NetworkCommissioningStatusEnum networkingStatus = 0; + optional char_string<512> debugText = 1; + optional int8u networkIndex = 2; + optional octet_string<140> clientIdentity = 3; + optional octet_string<64> possessionSignature = 4; + } + + request struct ConnectNetworkRequest { + octet_string<32> networkID = 0; + optional int64u breadcrumb = 1; + } + + response struct ConnectNetworkResponse = 7 { + NetworkCommissioningStatusEnum networkingStatus = 0; + optional char_string debugText = 1; + nullable int32s errorValue = 2; + } + + request struct ReorderNetworkRequest { + octet_string<32> networkID = 0; + int8u networkIndex = 1; + optional int64u breadcrumb = 2; + } + + request struct QueryIdentityRequest { + octet_string<20> keyIdentifier = 0; + optional octet_string<32> possessionNonce = 1; + } + + response struct QueryIdentityResponse = 10 { + octet_string<140> identity = 0; + optional octet_string<64> possessionSignature = 1; + } + + /** Detemine the set of networks the device sees as available. */ + command access(invoke: administer) ScanNetworks(ScanNetworksRequest): ScanNetworksResponse = 0; + /** Add or update the credentials for a given Wi-Fi network. */ + command access(invoke: administer) AddOrUpdateWiFiNetwork(AddOrUpdateWiFiNetworkRequest): NetworkConfigResponse = 2; + /** Add or update the credentials for a given Thread network. */ + command access(invoke: administer) AddOrUpdateThreadNetwork(AddOrUpdateThreadNetworkRequest): NetworkConfigResponse = 3; + /** Remove the definition of a given network (including its credentials). */ + command access(invoke: administer) RemoveNetwork(RemoveNetworkRequest): NetworkConfigResponse = 4; + /** Connect to the specified network, using previously-defined credentials. */ + command access(invoke: administer) ConnectNetwork(ConnectNetworkRequest): ConnectNetworkResponse = 6; + /** Modify the order in which networks will be presented in the Networks attribute. */ + command access(invoke: administer) ReorderNetwork(ReorderNetworkRequest): NetworkConfigResponse = 8; + /** Retrieve details about and optionally proof of possession of a network client identity. */ + command access(invoke: administer) QueryIdentity(QueryIdentityRequest): QueryIdentityResponse = 9; +} + +/** The cluster provides commands for retrieving unstructured diagnostic logs from a Node that may be used to aid in diagnostics. */ +cluster DiagnosticLogs = 50 { + revision 1; // NOTE: Default/not specifically set + + enum IntentEnum : enum8 { + kEndUserSupport = 0; + kNetworkDiag = 1; + kCrashLogs = 2; + } + + enum StatusEnum : enum8 { + kSuccess = 0; + kExhausted = 1; + kNoLogs = 2; + kBusy = 3; + kDenied = 4; + } + + enum TransferProtocolEnum : enum8 { + kResponsePayload = 0; + kBDX = 1; + } + + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct RetrieveLogsRequestRequest { + IntentEnum intent = 0; + TransferProtocolEnum requestedProtocol = 1; + optional char_string<32> transferFileDesignator = 2; + } + + response struct RetrieveLogsResponse = 1 { + StatusEnum status = 0; + long_octet_string logContent = 1; + optional epoch_us UTCTimeStamp = 2; + optional systime_us timeSinceBoot = 3; + } + + /** Retrieving diagnostic logs from a Node */ + command RetrieveLogsRequest(RetrieveLogsRequestRequest): RetrieveLogsResponse = 0; +} + +/** The General Diagnostics Cluster, along with other diagnostics clusters, provide a means to acquire standardized diagnostics metrics that MAY be used by a Node to assist a user or Administrative Node in diagnosing potential problems. */ +cluster GeneralDiagnostics = 51 { + revision 2; + + enum BootReasonEnum : enum8 { + kUnspecified = 0; + kPowerOnReboot = 1; + kBrownOutReset = 2; + kSoftwareWatchdogReset = 3; + kHardwareWatchdogReset = 4; + kSoftwareUpdateCompleted = 5; + kSoftwareReset = 6; + } + + enum HardwareFaultEnum : enum8 { + kUnspecified = 0; + kRadio = 1; + kSensor = 2; + kResettableOverTemp = 3; + kNonResettableOverTemp = 4; + kPowerSource = 5; + kVisualDisplayFault = 6; + kAudioOutputFault = 7; + kUserInterfaceFault = 8; + kNonVolatileMemoryError = 9; + kTamperDetected = 10; + } + + enum InterfaceTypeEnum : enum8 { + kUnspecified = 0; + kWiFi = 1; + kEthernet = 2; + kCellular = 3; + kThread = 4; + } + + enum NetworkFaultEnum : enum8 { + kUnspecified = 0; + kHardwareFailure = 1; + kNetworkJammed = 2; + kConnectionFailed = 3; + } + + enum RadioFaultEnum : enum8 { + kUnspecified = 0; + kWiFiFault = 1; + kCellularFault = 2; + kThreadFault = 3; + kNFCFault = 4; + kBLEFault = 5; + kEthernetFault = 6; + } + + bitmap Feature : bitmap32 { + kDataModelTest = 0x1; + } + + struct NetworkInterface { + char_string<32> name = 0; + boolean isOperational = 1; + nullable boolean offPremiseServicesReachableIPv4 = 2; + nullable boolean offPremiseServicesReachableIPv6 = 3; + octet_string<8> hardwareAddress = 4; + octet_string IPv4Addresses[] = 5; + octet_string IPv6Addresses[] = 6; + InterfaceTypeEnum type = 7; + } + + critical event HardwareFaultChange = 0 { + HardwareFaultEnum current[] = 0; + HardwareFaultEnum previous[] = 1; + } + + critical event RadioFaultChange = 1 { + RadioFaultEnum current[] = 0; + RadioFaultEnum previous[] = 1; + } + + critical event NetworkFaultChange = 2 { + NetworkFaultEnum current[] = 0; + NetworkFaultEnum previous[] = 1; + } + + critical event BootReason = 3 { + BootReasonEnum bootReason = 0; + } + + readonly attribute NetworkInterface networkInterfaces[] = 0; + readonly attribute int16u rebootCount = 1; + readonly attribute optional int64u upTime = 2; + readonly attribute optional int32u totalOperationalHours = 3; + readonly attribute optional BootReasonEnum bootReason = 4; + readonly attribute optional HardwareFaultEnum activeHardwareFaults[] = 5; + readonly attribute optional RadioFaultEnum activeRadioFaults[] = 6; + readonly attribute optional NetworkFaultEnum activeNetworkFaults[] = 7; + readonly attribute boolean testEventTriggersEnabled = 8; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct TestEventTriggerRequest { + octet_string<16> enableKey = 0; + int64u eventTrigger = 1; + } + + response struct TimeSnapshotResponse = 2 { + systime_ms systemTimeMs = 0; + nullable posix_ms posixTimeMs = 1; + } + + request struct PayloadTestRequestRequest { + octet_string<16> enableKey = 0; + int8u value = 1; + int16u count = 2; + } + + response struct PayloadTestResponse = 4 { + octet_string payload = 0; + } + + /** Provide a means for certification tests to trigger some test-plan-specific events */ + command access(invoke: manage) TestEventTrigger(TestEventTriggerRequest): DefaultSuccess = 0; + /** Take a snapshot of system time and epoch time. */ + command TimeSnapshot(): TimeSnapshotResponse = 1; + /** Request a variable length payload response. */ + command PayloadTestRequest(PayloadTestRequestRequest): PayloadTestResponse = 3; +} + +/** The Software Diagnostics Cluster provides a means to acquire standardized diagnostics metrics that MAY be used by a Node to assist a user or Administrative Node in diagnosing potential problems. */ +cluster SoftwareDiagnostics = 52 { + revision 1; // NOTE: Default/not specifically set + + bitmap Feature : bitmap32 { + kWatermarks = 0x1; + } + + struct ThreadMetricsStruct { + int64u id = 0; + optional char_string<8> name = 1; + optional int32u stackFreeCurrent = 2; + optional int32u stackFreeMinimum = 3; + optional int32u stackSize = 4; + } + + info event SoftwareFault = 0 { + int64u id = 0; + optional char_string name = 1; + optional octet_string faultRecording = 2; + } + + readonly attribute optional ThreadMetricsStruct threadMetrics[] = 0; + readonly attribute optional int64u currentHeapFree = 1; + readonly attribute optional int64u currentHeapUsed = 2; + readonly attribute optional int64u currentHeapHighWatermark = 3; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + /** Reception of this command SHALL reset the values: The StackFreeMinimum field of the ThreadMetrics attribute, CurrentHeapHighWaterMark attribute. */ + command access(invoke: manage) ResetWatermarks(): DefaultSuccess = 0; +} + +/** The Thread Network Diagnostics Cluster provides a means to acquire standardized diagnostics metrics that MAY be used by a Node to assist a user or Administrative Node in diagnosing potential problems */ +cluster ThreadNetworkDiagnostics = 53 { + revision 2; + + enum ConnectionStatusEnum : enum8 { + kConnected = 0; + kNotConnected = 1; + } + + enum NetworkFaultEnum : enum8 { + kUnspecified = 0; + kLinkDown = 1; + kHardwareFailure = 2; + kNetworkJammed = 3; + } + + enum RoutingRoleEnum : enum8 { + kUnspecified = 0; + kUnassigned = 1; + kSleepyEndDevice = 2; + kEndDevice = 3; + kREED = 4; + kRouter = 5; + kLeader = 6; + } + + bitmap Feature : bitmap32 { + kPacketCounts = 0x1; + kErrorCounts = 0x2; + kMLECounts = 0x4; + kMACCounts = 0x8; + } + + struct NeighborTableStruct { + int64u extAddress = 0; + int32u age = 1; + int16u rloc16 = 2; + int32u linkFrameCounter = 3; + int32u mleFrameCounter = 4; + int8u lqi = 5; + nullable int8s averageRssi = 6; + nullable int8s lastRssi = 7; + int8u frameErrorRate = 8; + int8u messageErrorRate = 9; + boolean rxOnWhenIdle = 10; + boolean fullThreadDevice = 11; + boolean fullNetworkData = 12; + boolean isChild = 13; + } + + struct OperationalDatasetComponents { + boolean activeTimestampPresent = 0; + boolean pendingTimestampPresent = 1; + boolean masterKeyPresent = 2; + boolean networkNamePresent = 3; + boolean extendedPanIdPresent = 4; + boolean meshLocalPrefixPresent = 5; + boolean delayPresent = 6; + boolean panIdPresent = 7; + boolean channelPresent = 8; + boolean pskcPresent = 9; + boolean securityPolicyPresent = 10; + boolean channelMaskPresent = 11; + } + + struct RouteTableStruct { + int64u extAddress = 0; + int16u rloc16 = 1; + int8u routerId = 2; + int8u nextHop = 3; + int8u pathCost = 4; + int8u LQIIn = 5; + int8u LQIOut = 6; + int8u age = 7; + boolean allocated = 8; + boolean linkEstablished = 9; + } + + struct SecurityPolicy { + int16u rotationTime = 0; + int16u flags = 1; + } + + info event ConnectionStatus = 0 { + ConnectionStatusEnum connectionStatus = 0; + } + + info event NetworkFaultChange = 1 { + NetworkFaultEnum current[] = 0; + NetworkFaultEnum previous[] = 1; + } + + readonly attribute nullable int16u channel = 0; + readonly attribute nullable RoutingRoleEnum routingRole = 1; + readonly attribute nullable char_string<16> networkName = 2; + readonly attribute nullable int16u panId = 3; + readonly attribute nullable int64u extendedPanId = 4; + readonly attribute nullable octet_string<17> meshLocalPrefix = 5; + readonly attribute optional int64u overrunCount = 6; + readonly attribute NeighborTableStruct neighborTable[] = 7; + readonly attribute RouteTableStruct routeTable[] = 8; + readonly attribute nullable int32u partitionId = 9; + readonly attribute nullable int16u weighting = 10; + readonly attribute nullable int16u dataVersion = 11; + readonly attribute nullable int16u stableDataVersion = 12; + readonly attribute nullable int8u leaderRouterId = 13; + readonly attribute optional int16u detachedRoleCount = 14; + readonly attribute optional int16u childRoleCount = 15; + readonly attribute optional int16u routerRoleCount = 16; + readonly attribute optional int16u leaderRoleCount = 17; + readonly attribute optional int16u attachAttemptCount = 18; + readonly attribute optional int16u partitionIdChangeCount = 19; + readonly attribute optional int16u betterPartitionAttachAttemptCount = 20; + readonly attribute optional int16u parentChangeCount = 21; + readonly attribute optional int32u txTotalCount = 22; + readonly attribute optional int32u txUnicastCount = 23; + readonly attribute optional int32u txBroadcastCount = 24; + readonly attribute optional int32u txAckRequestedCount = 25; + readonly attribute optional int32u txAckedCount = 26; + readonly attribute optional int32u txNoAckRequestedCount = 27; + readonly attribute optional int32u txDataCount = 28; + readonly attribute optional int32u txDataPollCount = 29; + readonly attribute optional int32u txBeaconCount = 30; + readonly attribute optional int32u txBeaconRequestCount = 31; + readonly attribute optional int32u txOtherCount = 32; + readonly attribute optional int32u txRetryCount = 33; + readonly attribute optional int32u txDirectMaxRetryExpiryCount = 34; + readonly attribute optional int32u txIndirectMaxRetryExpiryCount = 35; + readonly attribute optional int32u txErrCcaCount = 36; + readonly attribute optional int32u txErrAbortCount = 37; + readonly attribute optional int32u txErrBusyChannelCount = 38; + readonly attribute optional int32u rxTotalCount = 39; + readonly attribute optional int32u rxUnicastCount = 40; + readonly attribute optional int32u rxBroadcastCount = 41; + readonly attribute optional int32u rxDataCount = 42; + readonly attribute optional int32u rxDataPollCount = 43; + readonly attribute optional int32u rxBeaconCount = 44; + readonly attribute optional int32u rxBeaconRequestCount = 45; + readonly attribute optional int32u rxOtherCount = 46; + readonly attribute optional int32u rxAddressFilteredCount = 47; + readonly attribute optional int32u rxDestAddrFilteredCount = 48; + readonly attribute optional int32u rxDuplicatedCount = 49; + readonly attribute optional int32u rxErrNoFrameCount = 50; + readonly attribute optional int32u rxErrUnknownNeighborCount = 51; + readonly attribute optional int32u rxErrInvalidSrcAddrCount = 52; + readonly attribute optional int32u rxErrSecCount = 53; + readonly attribute optional int32u rxErrFcsCount = 54; + readonly attribute optional int32u rxErrOtherCount = 55; + readonly attribute optional nullable int64u activeTimestamp = 56; + readonly attribute optional nullable int64u pendingTimestamp = 57; + readonly attribute optional nullable int32u delay = 58; + readonly attribute nullable SecurityPolicy securityPolicy = 59; + readonly attribute nullable octet_string<4> channelPage0Mask = 60; + readonly attribute nullable OperationalDatasetComponents operationalDatasetComponents = 61; + readonly attribute NetworkFaultEnum activeNetworkFaultsList[] = 62; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + /** Reception of this command SHALL reset the OverrunCount attributes to 0 */ + command access(invoke: manage) ResetCounts(): DefaultSuccess = 0; +} + +/** The Wi-Fi Network Diagnostics Cluster provides a means to acquire standardized diagnostics metrics that MAY be used by a Node to assist a user or Administrative Node in diagnosing potential problems. */ +cluster WiFiNetworkDiagnostics = 54 { + revision 1; // NOTE: Default/not specifically set + + enum AssociationFailureCauseEnum : enum8 { + kUnknown = 0; + kAssociationFailed = 1; + kAuthenticationFailed = 2; + kSsidNotFound = 3; + } + + enum ConnectionStatusEnum : enum8 { + kConnected = 0; + kNotConnected = 1; + } + + enum SecurityTypeEnum : enum8 { + kUnspecified = 0; + kNone = 1; + kWEP = 2; + kWPA = 3; + kWPA2 = 4; + kWPA3 = 5; + } + + enum WiFiVersionEnum : enum8 { + kA = 0; + kB = 1; + kG = 2; + kN = 3; + kAc = 4; + kAx = 5; + kAh = 6; + } + + bitmap Feature : bitmap32 { + kPacketCounts = 0x1; + kErrorCounts = 0x2; + } + + info event Disconnection = 0 { + int16u reasonCode = 0; + } + + info event AssociationFailure = 1 { + AssociationFailureCauseEnum associationFailureCause = 0; + int16u status = 1; + } + + info event ConnectionStatus = 2 { + ConnectionStatusEnum connectionStatus = 0; + } + + readonly attribute nullable octet_string<6> bssid = 0; + readonly attribute nullable SecurityTypeEnum securityType = 1; + readonly attribute nullable WiFiVersionEnum wiFiVersion = 2; + readonly attribute nullable int16u channelNumber = 3; + readonly attribute nullable int8s rssi = 4; + readonly attribute optional nullable int32u beaconLostCount = 5; + readonly attribute optional nullable int32u beaconRxCount = 6; + readonly attribute optional nullable int32u packetMulticastRxCount = 7; + readonly attribute optional nullable int32u packetMulticastTxCount = 8; + readonly attribute optional nullable int32u packetUnicastRxCount = 9; + readonly attribute optional nullable int32u packetUnicastTxCount = 10; + readonly attribute optional nullable int64u currentMaxRate = 11; + readonly attribute optional nullable int64u overrunCount = 12; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + /** Reception of this command SHALL reset the Breacon and Packet related count attributes to 0 */ + command ResetCounts(): DefaultSuccess = 0; +} + +/** The Ethernet Network Diagnostics Cluster provides a means to acquire standardized diagnostics metrics that MAY be used by a Node to assist a user or Administrative Node in diagnosing potential problems. */ +cluster EthernetNetworkDiagnostics = 55 { + revision 1; // NOTE: Default/not specifically set + + enum PHYRateEnum : enum8 { + kRate10M = 0; + kRate100M = 1; + kRate1G = 2; + kRate25G = 3; + kRate5G = 4; + kRate10G = 5; + kRate40G = 6; + kRate100G = 7; + kRate200G = 8; + kRate400G = 9; + } + + bitmap Feature : bitmap32 { + kPacketCounts = 0x1; + kErrorCounts = 0x2; + } + + readonly attribute optional nullable PHYRateEnum PHYRate = 0; + readonly attribute optional nullable boolean fullDuplex = 1; + readonly attribute optional int64u packetRxCount = 2; + readonly attribute optional int64u packetTxCount = 3; + readonly attribute optional int64u txErrCount = 4; + readonly attribute optional int64u collisionCount = 5; + readonly attribute optional int64u overrunCount = 6; + readonly attribute optional nullable boolean carrierDetect = 7; + readonly attribute optional int64u timeSinceReset = 8; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + /** Reception of this command SHALL reset the attributes: PacketRxCount, PacketTxCount, TxErrCount, CollisionCount, OverrunCount to 0 */ + command access(invoke: manage) ResetCounts(): DefaultSuccess = 0; +} + +/** Accurate time is required for a number of reasons, including scheduling, display and validating security materials. */ +cluster TimeSynchronization = 56 { + revision 2; + + enum GranularityEnum : enum8 { + kNoTimeGranularity = 0; + kMinutesGranularity = 1; + kSecondsGranularity = 2; + kMillisecondsGranularity = 3; + kMicrosecondsGranularity = 4; + } + + enum StatusCode : enum8 { + kTimeNotAccepted = 2; + } + + enum TimeSourceEnum : enum8 { + kNone = 0; + kUnknown = 1; + kAdmin = 2; + kNodeTimeCluster = 3; + kNonMatterSNTP = 4; + kNonMatterNTP = 5; + kMatterSNTP = 6; + kMatterNTP = 7; + kMixedNTP = 8; + kNonMatterSNTPNTS = 9; + kNonMatterNTPNTS = 10; + kMatterSNTPNTS = 11; + kMatterNTPNTS = 12; + kMixedNTPNTS = 13; + kCloudSource = 14; + kPTP = 15; + kGNSS = 16; + } + + enum TimeZoneDatabaseEnum : enum8 { + kFull = 0; + kPartial = 1; + kNone = 2; + } + + bitmap Feature : bitmap32 { + kTimeZone = 0x1; + kNTPClient = 0x2; + kNTPServer = 0x4; + kTimeSyncClient = 0x8; + } + + struct DSTOffsetStruct { + int32s offset = 0; + epoch_us validStarting = 1; + nullable epoch_us validUntil = 2; + } + + struct FabricScopedTrustedTimeSourceStruct { + node_id nodeID = 0; + endpoint_no endpoint = 1; + } + + struct TimeZoneStruct { + int32s offset = 0; + epoch_us validAt = 1; + optional char_string<64> name = 2; + } + + struct TrustedTimeSourceStruct { + fabric_idx fabricIndex = 0; + node_id nodeID = 1; + endpoint_no endpoint = 2; + } + + info event DSTTableEmpty = 0 { + } + + info event DSTStatus = 1 { + boolean DSTOffsetActive = 0; + } + + info event TimeZoneStatus = 2 { + int32s offset = 0; + optional char_string name = 1; + } + + info event TimeFailure = 3 { + } + + info event MissingTrustedTimeSource = 4 { + } + + readonly attribute nullable epoch_us UTCTime = 0; + readonly attribute GranularityEnum granularity = 1; + readonly attribute optional TimeSourceEnum timeSource = 2; + readonly attribute optional nullable TrustedTimeSourceStruct trustedTimeSource = 3; + readonly attribute optional nullable char_string<128> defaultNTP = 4; + readonly attribute optional TimeZoneStruct timeZone[] = 5; + readonly attribute optional DSTOffsetStruct DSTOffset[] = 6; + readonly attribute optional nullable epoch_us localTime = 7; + readonly attribute optional TimeZoneDatabaseEnum timeZoneDatabase = 8; + readonly attribute optional boolean NTPServerAvailable = 9; + readonly attribute optional int8u timeZoneListMaxSize = 10; + readonly attribute optional int8u DSTOffsetListMaxSize = 11; + readonly attribute optional boolean supportsDNSResolve = 12; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct SetUTCTimeRequest { + epoch_us UTCTime = 0; + GranularityEnum granularity = 1; + optional TimeSourceEnum timeSource = 2; + } + + request struct SetTrustedTimeSourceRequest { + nullable FabricScopedTrustedTimeSourceStruct trustedTimeSource = 0; + } + + request struct SetTimeZoneRequest { + TimeZoneStruct timeZone[] = 0; + } + + response struct SetTimeZoneResponse = 3 { + boolean DSTOffsetRequired = 0; + } + + request struct SetDSTOffsetRequest { + DSTOffsetStruct DSTOffset[] = 0; + } + + request struct SetDefaultNTPRequest { + nullable char_string<128> defaultNTP = 0; + } + + /** This command MAY be issued by Administrator to set the time. */ + command access(invoke: administer) SetUTCTime(SetUTCTimeRequest): DefaultSuccess = 0; + /** This command SHALL set TrustedTimeSource. */ + fabric command access(invoke: administer) SetTrustedTimeSource(SetTrustedTimeSourceRequest): DefaultSuccess = 1; + /** This command SHALL set TimeZone. */ + command access(invoke: manage) SetTimeZone(SetTimeZoneRequest): SetTimeZoneResponse = 2; + /** This command SHALL set DSTOffset. */ + command access(invoke: manage) SetDSTOffset(SetDSTOffsetRequest): DefaultSuccess = 4; + /** This command is used to set DefaultNTP. */ + command access(invoke: administer) SetDefaultNTP(SetDefaultNTPRequest): DefaultSuccess = 5; +} + +/** This cluster exposes interactions with a switch device, for the purpose of using those interactions by other devices. +Two types of switch devices are supported: latching switch (e.g. rocker switch) and momentary switch (e.g. push button), distinguished with their feature flags. +Interactions with the switch device are exposed as attributes (for the latching switch) and as events (for both types of switches). An interested party MAY subscribe to these attributes/events and thus be informed of the interactions, and can perform actions based on this, for example by sending commands to perform an action such as controlling a light or a window shade. */ +cluster Switch = 59 { + revision 2; + + bitmap Feature : bitmap32 { + kLatchingSwitch = 0x1; + kMomentarySwitch = 0x2; + kMomentarySwitchRelease = 0x4; + kMomentarySwitchLongPress = 0x8; + kMomentarySwitchMultiPress = 0x10; + kActionSwitch = 0x20; + } + + info event SwitchLatched = 0 { + int8u newPosition = 0; + } + + info event InitialPress = 1 { + int8u newPosition = 0; + } + + info event LongPress = 2 { + int8u newPosition = 0; + } + + info event ShortRelease = 3 { + int8u previousPosition = 0; + } + + info event LongRelease = 4 { + int8u previousPosition = 0; + } + + info event MultiPressOngoing = 5 { + int8u newPosition = 0; + int8u currentNumberOfPressesCounted = 1; + } + + info event MultiPressComplete = 6 { + int8u previousPosition = 0; + int8u totalNumberOfPressesCounted = 1; + } + + readonly attribute int8u numberOfPositions = 0; + readonly attribute int8u currentPosition = 1; + readonly attribute optional int8u multiPressMax = 2; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; +} + +/** Commands to trigger a Node to allow a new Administrator to commission it. */ +cluster AdministratorCommissioning = 60 { + revision 1; // NOTE: Default/not specifically set + + enum CommissioningWindowStatusEnum : enum8 { + kWindowNotOpen = 0; + kEnhancedWindowOpen = 1; + kBasicWindowOpen = 2; + } + + enum StatusCode : enum8 { + kBusy = 2; + kPAKEParameterError = 3; + kWindowNotOpen = 4; + } + + bitmap Feature : bitmap32 { + kBasic = 0x1; + } + + readonly attribute CommissioningWindowStatusEnum windowStatus = 0; + readonly attribute nullable fabric_idx adminFabricIndex = 1; + readonly attribute nullable vendor_id adminVendorId = 2; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct OpenCommissioningWindowRequest { + int16u commissioningTimeout = 0; + octet_string PAKEPasscodeVerifier = 1; + int16u discriminator = 2; + int32u iterations = 3; + octet_string<32> salt = 4; + } + + request struct OpenBasicCommissioningWindowRequest { + int16u commissioningTimeout = 0; + } + + /** This command is used by a current Administrator to instruct a Node to go into commissioning mode using enhanced commissioning method. */ + timed command access(invoke: administer) OpenCommissioningWindow(OpenCommissioningWindowRequest): DefaultSuccess = 0; + /** This command is used by a current Administrator to instruct a Node to go into commissioning mode using basic commissioning method, if the node supports it. */ + timed command access(invoke: administer) OpenBasicCommissioningWindow(OpenBasicCommissioningWindowRequest): DefaultSuccess = 1; + /** This command is used by a current Administrator to instruct a Node to revoke any active Open Commissioning Window or Open Basic Commissioning Window command. */ + timed command access(invoke: administer) RevokeCommissioning(): DefaultSuccess = 2; +} + +/** This cluster is used to add or remove Operational Credentials on a Commissionee or Node, as well as manage the associated Fabrics. */ +cluster OperationalCredentials = 62 { + revision 1; // NOTE: Default/not specifically set + + enum CertificateChainTypeEnum : enum8 { + kDACCertificate = 1; + kPAICertificate = 2; + } + + enum NodeOperationalCertStatusEnum : enum8 { + kOK = 0; + kInvalidPublicKey = 1; + kInvalidNodeOpId = 2; + kInvalidNOC = 3; + kMissingCsr = 4; + kTableFull = 5; + kInvalidAdminSubject = 6; + kFabricConflict = 9; + kLabelConflict = 10; + kInvalidFabricIndex = 11; + } + + fabric_scoped struct FabricDescriptorStruct { + octet_string<65> rootPublicKey = 1; + vendor_id vendorID = 2; + fabric_id fabricID = 3; + node_id nodeID = 4; + char_string<32> label = 5; + fabric_idx fabricIndex = 254; + } + + fabric_scoped struct NOCStruct { + fabric_sensitive octet_string noc = 1; + nullable fabric_sensitive octet_string icac = 2; + fabric_idx fabricIndex = 254; + } + + readonly attribute access(read: administer) NOCStruct NOCs[] = 0; + readonly attribute FabricDescriptorStruct fabrics[] = 1; + readonly attribute int8u supportedFabrics = 2; + readonly attribute int8u commissionedFabrics = 3; + readonly attribute octet_string trustedRootCertificates[] = 4; + readonly attribute int8u currentFabricIndex = 5; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct AttestationRequestRequest { + octet_string<32> attestationNonce = 0; + } + + response struct AttestationResponse = 1 { + octet_string<900> attestationElements = 0; + octet_string<64> attestationSignature = 1; + } + + request struct CertificateChainRequestRequest { + CertificateChainTypeEnum certificateType = 0; + } + + response struct CertificateChainResponse = 3 { + octet_string<600> certificate = 0; + } + + request struct CSRRequestRequest { + octet_string<32> CSRNonce = 0; + optional boolean isForUpdateNOC = 1; + } + + response struct CSRResponse = 5 { + octet_string NOCSRElements = 0; + octet_string attestationSignature = 1; + } + + request struct AddNOCRequest { + octet_string<400> NOCValue = 0; + optional octet_string<400> ICACValue = 1; + octet_string<16> IPKValue = 2; + int64u caseAdminSubject = 3; + vendor_id adminVendorId = 4; + } + + request struct UpdateNOCRequest { + octet_string NOCValue = 0; + optional octet_string ICACValue = 1; + } + + response struct NOCResponse = 8 { + NodeOperationalCertStatusEnum statusCode = 0; + optional fabric_idx fabricIndex = 1; + optional char_string<128> debugText = 2; + } + + request struct UpdateFabricLabelRequest { + char_string<32> label = 0; + } + + request struct RemoveFabricRequest { + fabric_idx fabricIndex = 0; + } + + request struct AddTrustedRootCertificateRequest { + octet_string rootCACertificate = 0; + } + + /** Sender is requesting attestation information from the receiver. */ + command access(invoke: administer) AttestationRequest(AttestationRequestRequest): AttestationResponse = 0; + /** Sender is requesting a device attestation certificate from the receiver. */ + command access(invoke: administer) CertificateChainRequest(CertificateChainRequestRequest): CertificateChainResponse = 2; + /** Sender is requesting a certificate signing request (CSR) from the receiver. */ + command access(invoke: administer) CSRRequest(CSRRequestRequest): CSRResponse = 4; + /** Sender is requesting to add the new node operational certificates. */ + command access(invoke: administer) AddNOC(AddNOCRequest): NOCResponse = 6; + /** Sender is requesting to update the node operational certificates. */ + fabric command access(invoke: administer) UpdateNOC(UpdateNOCRequest): NOCResponse = 7; + /** This command SHALL be used by an Administrative Node to set the user-visible Label field for a given Fabric, as reflected by entries in the Fabrics attribute. */ + fabric command access(invoke: administer) UpdateFabricLabel(UpdateFabricLabelRequest): NOCResponse = 9; + /** This command is used by Administrative Nodes to remove a given fabric index and delete all associated fabric-scoped data. */ + command access(invoke: administer) RemoveFabric(RemoveFabricRequest): NOCResponse = 10; + /** This command SHALL add a Trusted Root CA Certificate, provided as its CHIP Certificate representation. */ + command access(invoke: administer) AddTrustedRootCertificate(AddTrustedRootCertificateRequest): DefaultSuccess = 11; +} + +/** The Group Key Management Cluster is the mechanism by which group keys are managed. */ +cluster GroupKeyManagement = 63 { + revision 1; // NOTE: Default/not specifically set + + enum GroupKeySecurityPolicyEnum : enum8 { + kTrustFirst = 0; + kCacheAndSync = 1; + } + + bitmap Feature : bitmap32 { + kCacheAndSync = 0x1; + } + + fabric_scoped struct GroupInfoMapStruct { + group_id groupId = 1; + endpoint_no endpoints[] = 2; + optional char_string<16> groupName = 3; + fabric_idx fabricIndex = 254; + } + + fabric_scoped struct GroupKeyMapStruct { + group_id groupId = 1; + int16u groupKeySetID = 2; + fabric_idx fabricIndex = 254; + } + + struct GroupKeySetStruct { + int16u groupKeySetID = 0; + GroupKeySecurityPolicyEnum groupKeySecurityPolicy = 1; + nullable octet_string<16> epochKey0 = 2; + nullable epoch_us epochStartTime0 = 3; + nullable octet_string<16> epochKey1 = 4; + nullable epoch_us epochStartTime1 = 5; + nullable octet_string<16> epochKey2 = 6; + nullable epoch_us epochStartTime2 = 7; + } + + attribute access(write: manage) GroupKeyMapStruct groupKeyMap[] = 0; + readonly attribute GroupInfoMapStruct groupTable[] = 1; + readonly attribute int16u maxGroupsPerFabric = 2; + readonly attribute int16u maxGroupKeysPerFabric = 3; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct KeySetWriteRequest { + GroupKeySetStruct groupKeySet = 0; + } + + request struct KeySetReadRequest { + int16u groupKeySetID = 0; + } + + response struct KeySetReadResponse = 2 { + GroupKeySetStruct groupKeySet = 0; + } + + request struct KeySetRemoveRequest { + int16u groupKeySetID = 0; + } + + response struct KeySetReadAllIndicesResponse = 5 { + int16u groupKeySetIDs[] = 0; + } + + /** Write a new set of keys for the given key set id. */ + fabric command access(invoke: administer) KeySetWrite(KeySetWriteRequest): DefaultSuccess = 0; + /** Read the keys for a given key set id. */ + fabric command access(invoke: administer) KeySetRead(KeySetReadRequest): KeySetReadResponse = 1; + /** Revoke a Root Key from a Group */ + fabric command access(invoke: administer) KeySetRemove(KeySetRemoveRequest): DefaultSuccess = 3; + /** Return the list of Group Key Sets associated with the accessing fabric */ + fabric command access(invoke: administer) KeySetReadAllIndices(): KeySetReadAllIndicesResponse = 4; +} + +/** The Fixed Label Cluster provides a feature for the device to tag an endpoint with zero or more read only +labels. */ +cluster FixedLabel = 64 { + revision 1; // NOTE: Default/not specifically set + + struct LabelStruct { + char_string<16> label = 0; + char_string<16> value = 1; + } + + readonly attribute LabelStruct labelList[] = 0; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; +} + +/** The User Label Cluster provides a feature to tag an endpoint with zero or more labels. */ +cluster UserLabel = 65 { + revision 1; // NOTE: Default/not specifically set + + struct LabelStruct { + char_string<16> label = 0; + char_string<16> value = 1; + } + + attribute access(write: manage) LabelStruct labelList[] = 0; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; +} + +/** Allows servers to ensure that listed clients are notified when a server is available for communication. */ +cluster IcdManagement = 70 { + revision 3; + + enum ClientTypeEnum : enum8 { + kPermanent = 0; + kEphemeral = 1; + } + + enum OperatingModeEnum : enum8 { + kSIT = 0; + kLIT = 1; + } + + bitmap Feature : bitmap32 { + kCheckInProtocolSupport = 0x1; + kUserActiveModeTrigger = 0x2; + kLongIdleTimeSupport = 0x4; + kDynamicSitLitSupport = 0x8; + } + + bitmap UserActiveModeTriggerBitmap : bitmap32 { + kPowerCycle = 0x1; + kSettingsMenu = 0x2; + kCustomInstruction = 0x4; + kDeviceManual = 0x8; + kActuateSensor = 0x10; + kActuateSensorSeconds = 0x20; + kActuateSensorTimes = 0x40; + kActuateSensorLightsBlink = 0x80; + kResetButton = 0x100; + kResetButtonLightsBlink = 0x200; + kResetButtonSeconds = 0x400; + kResetButtonTimes = 0x800; + kSetupButton = 0x1000; + kSetupButtonSeconds = 0x2000; + kSetupButtonLightsBlink = 0x4000; + kSetupButtonTimes = 0x8000; + kAppDefinedButton = 0x10000; + } + + fabric_scoped struct MonitoringRegistrationStruct { + fabric_sensitive node_id checkInNodeID = 1; + fabric_sensitive int64u monitoredSubject = 2; + fabric_sensitive ClientTypeEnum clientType = 4; + fabric_idx fabricIndex = 254; + } + + readonly attribute int32u idleModeDuration = 0; + readonly attribute int32u activeModeDuration = 1; + readonly attribute int16u activeModeThreshold = 2; + readonly attribute access(read: administer) optional MonitoringRegistrationStruct registeredClients[] = 3; + readonly attribute access(read: administer) optional int32u ICDCounter = 4; + readonly attribute optional int16u clientsSupportedPerFabric = 5; + provisional readonly attribute optional UserActiveModeTriggerBitmap userActiveModeTriggerHint = 6; + provisional readonly attribute optional char_string<128> userActiveModeTriggerInstruction = 7; + provisional readonly attribute optional OperatingModeEnum operatingMode = 8; + provisional readonly attribute optional int32u maximumCheckInBackOff = 9; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct RegisterClientRequest { + node_id checkInNodeID = 0; + int64u monitoredSubject = 1; + octet_string<16> key = 2; + optional octet_string<16> verificationKey = 3; + ClientTypeEnum clientType = 4; + } + + response struct RegisterClientResponse = 1 { + int32u ICDCounter = 0; + } + + request struct UnregisterClientRequest { + node_id checkInNodeID = 0; + optional octet_string<16> verificationKey = 1; + } + + request struct StayActiveRequestRequest { + int32u stayActiveDuration = 0; + } + + response struct StayActiveResponse = 4 { + int32u promisedActiveDuration = 0; + } + + /** Register a client to the end device */ + fabric command access(invoke: manage) RegisterClient(RegisterClientRequest): RegisterClientResponse = 0; + /** Unregister a client from an end device */ + fabric command access(invoke: manage) UnregisterClient(UnregisterClientRequest): DefaultSuccess = 2; + /** Request the end device to stay in Active Mode for an additional ActiveModeThreshold */ + command access(invoke: manage) StayActiveRequest(StayActiveRequestRequest): StayActiveResponse = 3; +} + +/** Attributes and commands for scene configuration and manipulation. */ +provisional cluster ScenesManagement = 98 { + revision 1; + + bitmap CopyModeBitmap : bitmap8 { + kCopyAllScenes = 0x1; + } + + bitmap Feature : bitmap32 { + kSceneNames = 0x1; + } + + struct AttributeValuePairStruct { + attrib_id attributeID = 0; + optional int8u valueUnsigned8 = 1; + optional int8s valueSigned8 = 2; + optional int16u valueUnsigned16 = 3; + optional int16s valueSigned16 = 4; + optional int32u valueUnsigned32 = 5; + optional int32s valueSigned32 = 6; + optional int64u valueUnsigned64 = 7; + optional int64s valueSigned64 = 8; + } + + struct ExtensionFieldSet { + cluster_id clusterID = 0; + AttributeValuePairStruct attributeValueList[] = 1; + } + + fabric_scoped struct SceneInfoStruct { + int8u sceneCount = 0; + fabric_sensitive int8u currentScene = 1; + fabric_sensitive group_id currentGroup = 2; + fabric_sensitive boolean sceneValid = 3; + int8u remainingCapacity = 4; + fabric_idx fabricIndex = 254; + } + + readonly attribute optional nullable node_id lastConfiguredBy = 0; + readonly attribute int16u sceneTableSize = 1; + readonly attribute SceneInfoStruct fabricSceneInfo[] = 2; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct AddSceneRequest { + group_id groupID = 0; + int8u sceneID = 1; + int32u transitionTime = 2; + char_string sceneName = 3; + ExtensionFieldSet extensionFieldSets[] = 4; + } + + response struct AddSceneResponse = 0 { + status status = 0; + group_id groupID = 1; + int8u sceneID = 2; + } + + request struct ViewSceneRequest { + group_id groupID = 0; + int8u sceneID = 1; + } + + response struct ViewSceneResponse = 1 { + status status = 0; + group_id groupID = 1; + int8u sceneID = 2; + optional int32u transitionTime = 3; + optional char_string sceneName = 4; + optional ExtensionFieldSet extensionFieldSets[] = 5; + } + + request struct RemoveSceneRequest { + group_id groupID = 0; + int8u sceneID = 1; + } + + response struct RemoveSceneResponse = 2 { + status status = 0; + group_id groupID = 1; + int8u sceneID = 2; + } + + request struct RemoveAllScenesRequest { + group_id groupID = 0; + } + + response struct RemoveAllScenesResponse = 3 { + status status = 0; + group_id groupID = 1; + } + + request struct StoreSceneRequest { + group_id groupID = 0; + int8u sceneID = 1; + } + + response struct StoreSceneResponse = 4 { + status status = 0; + group_id groupID = 1; + int8u sceneID = 2; + } + + request struct RecallSceneRequest { + group_id groupID = 0; + int8u sceneID = 1; + optional nullable int32u transitionTime = 2; + } + + request struct GetSceneMembershipRequest { + group_id groupID = 0; + } + + response struct GetSceneMembershipResponse = 6 { + status status = 0; + nullable int8u capacity = 1; + group_id groupID = 2; + optional int8u sceneList[] = 3; + } + + request struct CopySceneRequest { + CopyModeBitmap mode = 0; + group_id groupIdentifierFrom = 1; + int8u sceneIdentifierFrom = 2; + group_id groupIdentifierTo = 3; + int8u sceneIdentifierTo = 4; + } + + response struct CopySceneResponse = 64 { + status status = 0; + group_id groupIdentifierFrom = 1; + int8u sceneIdentifierFrom = 2; + } + + /** Add a scene to the scene table. Extension field sets are supported, and are inputed as '{"ClusterID": VALUE, "AttributeValueList":[{"AttributeID": VALUE, "Value*": VALUE}]}' */ + fabric command access(invoke: manage) AddScene(AddSceneRequest): AddSceneResponse = 0; + /** Retrieves the requested scene entry from its Scene table. */ + fabric command ViewScene(ViewSceneRequest): ViewSceneResponse = 1; + /** Removes the requested scene entry, corresponding to the value of the GroupID field, from its Scene Table */ + fabric command access(invoke: manage) RemoveScene(RemoveSceneRequest): RemoveSceneResponse = 2; + /** Remove all scenes, corresponding to the value of the GroupID field, from its Scene Table */ + fabric command access(invoke: manage) RemoveAllScenes(RemoveAllScenesRequest): RemoveAllScenesResponse = 3; + /** Adds the scene entry into its Scene Table along with all extension field sets corresponding to the current state of other clusters on the same endpoint */ + fabric command access(invoke: manage) StoreScene(StoreSceneRequest): StoreSceneResponse = 4; + /** Set the attributes and corresponding state for each other cluster implemented on the endpoint accordingly to the resquested scene entry in the Scene Table */ + fabric command RecallScene(RecallSceneRequest): DefaultSuccess = 5; + /** Get an unused scene identifier when no commissioning tool is in the network, or for a commissioning tool to get the used scene identifiers within a certain group */ + fabric command GetSceneMembership(GetSceneMembershipRequest): GetSceneMembershipResponse = 6; + /** Allows a client to efficiently copy scenes from one group/scene identifier pair to another group/scene identifier pair. */ + fabric command CopyScene(CopySceneRequest): CopySceneResponse = 64; +} + +/** Attributes and commands for controlling the color properties of a color-capable light. */ +cluster ColorControl = 768 { + revision 7; + + enum ColorLoopActionEnum : enum8 { + kDeactivate = 0; + kActivateFromColorLoopStartEnhancedHue = 1; + kActivateFromEnhancedCurrentHue = 2; + } + + enum ColorLoopDirectionEnum : enum8 { + kDecrement = 0; + kIncrement = 1; + } + + enum ColorModeEnum : enum8 { + kCurrentHueAndCurrentSaturation = 0; + kCurrentXAndCurrentY = 1; + kColorTemperatureMireds = 2; + } + + enum DirectionEnum : enum8 { + kShortest = 0; + kLongest = 1; + kUp = 2; + kDown = 3; + } + + enum DriftCompensationEnum : enum8 { + kNone = 0; + kOtherOrUnknown = 1; + kTemperatureMonitoring = 2; + kOpticalLuminanceMonitoringAndFeedback = 3; + kOpticalColorMonitoringAndFeedback = 4; + } + + enum EnhancedColorModeEnum : enum8 { + kCurrentHueAndCurrentSaturation = 0; + kCurrentXAndCurrentY = 1; + kColorTemperatureMireds = 2; + kEnhancedCurrentHueAndCurrentSaturation = 3; + } + + enum MoveModeEnum : enum8 { + kStop = 0; + kUp = 1; + kDown = 3; + } + + enum StepModeEnum : enum8 { + kUp = 1; + kDown = 3; + } + + bitmap ColorCapabilitiesBitmap : bitmap16 { + kHueSaturation = 0x1; + kEnhancedHue = 0x2; + kColorLoop = 0x4; + kXY = 0x8; + kColorTemperature = 0x10; + } + + bitmap Feature : bitmap32 { + kHueAndSaturation = 0x1; + kEnhancedHue = 0x2; + kColorLoop = 0x4; + kXY = 0x8; + kColorTemperature = 0x10; + } + + bitmap OptionsBitmap : bitmap8 { + kExecuteIfOff = 0x1; + } + + bitmap UpdateFlagsBitmap : bitmap8 { + kUpdateAction = 0x1; + kUpdateDirection = 0x2; + kUpdateTime = 0x4; + kUpdateStartHue = 0x8; + } + + readonly attribute optional int8u currentHue = 0; + readonly attribute optional int8u currentSaturation = 1; + readonly attribute optional int16u remainingTime = 2; + readonly attribute optional int16u currentX = 3; + readonly attribute optional int16u currentY = 4; + readonly attribute optional DriftCompensationEnum driftCompensation = 5; + readonly attribute optional char_string<254> compensationText = 6; + readonly attribute optional int16u colorTemperatureMireds = 7; + readonly attribute ColorModeEnum colorMode = 8; + attribute OptionsBitmap options = 15; + readonly attribute nullable int8u numberOfPrimaries = 16; + readonly attribute optional int16u primary1X = 17; + readonly attribute optional int16u primary1Y = 18; + readonly attribute optional nullable int8u primary1Intensity = 19; + readonly attribute optional int16u primary2X = 21; + readonly attribute optional int16u primary2Y = 22; + readonly attribute optional nullable int8u primary2Intensity = 23; + readonly attribute optional int16u primary3X = 25; + readonly attribute optional int16u primary3Y = 26; + readonly attribute optional nullable int8u primary3Intensity = 27; + readonly attribute optional int16u primary4X = 32; + readonly attribute optional int16u primary4Y = 33; + readonly attribute optional nullable int8u primary4Intensity = 34; + readonly attribute optional int16u primary5X = 36; + readonly attribute optional int16u primary5Y = 37; + readonly attribute optional nullable int8u primary5Intensity = 38; + readonly attribute optional int16u primary6X = 40; + readonly attribute optional int16u primary6Y = 41; + readonly attribute optional nullable int8u primary6Intensity = 42; + attribute access(write: manage) optional int16u whitePointX = 48; + attribute access(write: manage) optional int16u whitePointY = 49; + attribute access(write: manage) optional int16u colorPointRX = 50; + attribute access(write: manage) optional int16u colorPointRY = 51; + attribute access(write: manage) optional nullable int8u colorPointRIntensity = 52; + attribute access(write: manage) optional int16u colorPointGX = 54; + attribute access(write: manage) optional int16u colorPointGY = 55; + attribute access(write: manage) optional nullable int8u colorPointGIntensity = 56; + attribute access(write: manage) optional int16u colorPointBX = 58; + attribute access(write: manage) optional int16u colorPointBY = 59; + attribute access(write: manage) optional nullable int8u colorPointBIntensity = 60; + readonly attribute optional int16u enhancedCurrentHue = 16384; + readonly attribute EnhancedColorModeEnum enhancedColorMode = 16385; + readonly attribute optional int8u colorLoopActive = 16386; + readonly attribute optional int8u colorLoopDirection = 16387; + readonly attribute optional int16u colorLoopTime = 16388; + readonly attribute optional int16u colorLoopStartEnhancedHue = 16389; + readonly attribute optional int16u colorLoopStoredEnhancedHue = 16390; + readonly attribute ColorCapabilitiesBitmap colorCapabilities = 16394; + readonly attribute optional int16u colorTempPhysicalMinMireds = 16395; + readonly attribute optional int16u colorTempPhysicalMaxMireds = 16396; + readonly attribute optional int16u coupleColorTempToLevelMinMireds = 16397; + attribute access(write: manage) optional nullable int16u startUpColorTemperatureMireds = 16400; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct MoveToHueRequest { + int8u hue = 0; + DirectionEnum direction = 1; + int16u transitionTime = 2; + OptionsBitmap optionsMask = 3; + OptionsBitmap optionsOverride = 4; + } + + request struct MoveHueRequest { + MoveModeEnum moveMode = 0; + int8u rate = 1; + OptionsBitmap optionsMask = 2; + OptionsBitmap optionsOverride = 3; + } + + request struct StepHueRequest { + StepModeEnum stepMode = 0; + int8u stepSize = 1; + int8u transitionTime = 2; + OptionsBitmap optionsMask = 3; + OptionsBitmap optionsOverride = 4; + } + + request struct MoveToSaturationRequest { + int8u saturation = 0; + int16u transitionTime = 1; + OptionsBitmap optionsMask = 2; + OptionsBitmap optionsOverride = 3; + } + + request struct MoveSaturationRequest { + MoveModeEnum moveMode = 0; + int8u rate = 1; + OptionsBitmap optionsMask = 2; + OptionsBitmap optionsOverride = 3; + } + + request struct StepSaturationRequest { + StepModeEnum stepMode = 0; + int8u stepSize = 1; + int8u transitionTime = 2; + OptionsBitmap optionsMask = 3; + OptionsBitmap optionsOverride = 4; + } + + request struct MoveToHueAndSaturationRequest { + int8u hue = 0; + int8u saturation = 1; + int16u transitionTime = 2; + OptionsBitmap optionsMask = 3; + OptionsBitmap optionsOverride = 4; + } + + request struct MoveToColorRequest { + int16u colorX = 0; + int16u colorY = 1; + int16u transitionTime = 2; + OptionsBitmap optionsMask = 3; + OptionsBitmap optionsOverride = 4; + } + + request struct MoveColorRequest { + int16s rateX = 0; + int16s rateY = 1; + OptionsBitmap optionsMask = 2; + OptionsBitmap optionsOverride = 3; + } + + request struct StepColorRequest { + int16s stepX = 0; + int16s stepY = 1; + int16u transitionTime = 2; + OptionsBitmap optionsMask = 3; + OptionsBitmap optionsOverride = 4; + } + + request struct MoveToColorTemperatureRequest { + int16u colorTemperatureMireds = 0; + int16u transitionTime = 1; + OptionsBitmap optionsMask = 2; + OptionsBitmap optionsOverride = 3; + } + + request struct EnhancedMoveToHueRequest { + int16u enhancedHue = 0; + DirectionEnum direction = 1; + int16u transitionTime = 2; + OptionsBitmap optionsMask = 3; + OptionsBitmap optionsOverride = 4; + } + + request struct EnhancedMoveHueRequest { + MoveModeEnum moveMode = 0; + int16u rate = 1; + OptionsBitmap optionsMask = 2; + OptionsBitmap optionsOverride = 3; + } + + request struct EnhancedStepHueRequest { + StepModeEnum stepMode = 0; + int16u stepSize = 1; + int16u transitionTime = 2; + OptionsBitmap optionsMask = 3; + OptionsBitmap optionsOverride = 4; + } + + request struct EnhancedMoveToHueAndSaturationRequest { + int16u enhancedHue = 0; + int8u saturation = 1; + int16u transitionTime = 2; + OptionsBitmap optionsMask = 3; + OptionsBitmap optionsOverride = 4; + } + + request struct ColorLoopSetRequest { + UpdateFlagsBitmap updateFlags = 0; + ColorLoopActionEnum action = 1; + ColorLoopDirectionEnum direction = 2; + int16u time = 3; + int16u startHue = 4; + OptionsBitmap optionsMask = 5; + OptionsBitmap optionsOverride = 6; + } + + request struct StopMoveStepRequest { + OptionsBitmap optionsMask = 0; + OptionsBitmap optionsOverride = 1; + } + + request struct MoveColorTemperatureRequest { + MoveModeEnum moveMode = 0; + int16u rate = 1; + int16u colorTemperatureMinimumMireds = 2; + int16u colorTemperatureMaximumMireds = 3; + OptionsBitmap optionsMask = 4; + OptionsBitmap optionsOverride = 5; + } + + request struct StepColorTemperatureRequest { + StepModeEnum stepMode = 0; + int16u stepSize = 1; + int16u transitionTime = 2; + int16u colorTemperatureMinimumMireds = 3; + int16u colorTemperatureMaximumMireds = 4; + OptionsBitmap optionsMask = 5; + OptionsBitmap optionsOverride = 6; + } + + /** Move to specified hue. */ + command MoveToHue(MoveToHueRequest): DefaultSuccess = 0; + /** Move hue up or down at specified rate. */ + command MoveHue(MoveHueRequest): DefaultSuccess = 1; + /** Step hue up or down by specified size at specified rate. */ + command StepHue(StepHueRequest): DefaultSuccess = 2; + /** Move to specified saturation. */ + command MoveToSaturation(MoveToSaturationRequest): DefaultSuccess = 3; + /** Move saturation up or down at specified rate. */ + command MoveSaturation(MoveSaturationRequest): DefaultSuccess = 4; + /** Step saturation up or down by specified size at specified rate. */ + command StepSaturation(StepSaturationRequest): DefaultSuccess = 5; + /** Move to hue and saturation. */ + command MoveToHueAndSaturation(MoveToHueAndSaturationRequest): DefaultSuccess = 6; + /** Move to specified color. */ + command MoveToColor(MoveToColorRequest): DefaultSuccess = 7; + /** Moves the color. */ + command MoveColor(MoveColorRequest): DefaultSuccess = 8; + /** Steps the lighting to a specific color. */ + command StepColor(StepColorRequest): DefaultSuccess = 9; + /** Move to a specific color temperature. */ + command MoveToColorTemperature(MoveToColorTemperatureRequest): DefaultSuccess = 10; + /** Command description for EnhancedMoveToHue */ + command EnhancedMoveToHue(EnhancedMoveToHueRequest): DefaultSuccess = 64; + /** Command description for EnhancedMoveHue */ + command EnhancedMoveHue(EnhancedMoveHueRequest): DefaultSuccess = 65; + /** Command description for EnhancedStepHue */ + command EnhancedStepHue(EnhancedStepHueRequest): DefaultSuccess = 66; + /** Command description for EnhancedMoveToHueAndSaturation */ + command EnhancedMoveToHueAndSaturation(EnhancedMoveToHueAndSaturationRequest): DefaultSuccess = 67; + /** Command description for ColorLoopSet */ + command ColorLoopSet(ColorLoopSetRequest): DefaultSuccess = 68; + /** Command description for StopMoveStep */ + command StopMoveStep(StopMoveStepRequest): DefaultSuccess = 71; + /** Command description for MoveColorTemperature */ + command MoveColorTemperature(MoveColorTemperatureRequest): DefaultSuccess = 75; + /** Command description for StepColorTemperature */ + command StepColorTemperature(StepColorTemperatureRequest): DefaultSuccess = 76; +} + +endpoint 0 { + device type ma_rootdevice = 22, version 1; + + binding cluster OtaSoftwareUpdateProvider; + + server cluster Descriptor { + callback attribute deviceTypeList; + callback attribute serverList; + callback attribute clientList; + callback attribute partsList; + callback attribute featureMap; + callback attribute clusterRevision; + } + + server cluster Binding { + callback attribute binding; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + } + + server cluster AccessControl { + emits event AccessControlEntryChanged; + emits event AccessControlExtensionChanged; + callback attribute acl; + callback attribute extension; + callback attribute subjectsPerAccessControlEntry; + callback attribute targetsPerAccessControlEntry; + callback attribute accessControlEntriesPerFabric; + callback attribute attributeList; + ram attribute featureMap default = 0; + callback attribute clusterRevision; + } + + server cluster BasicInformation { + emits event StartUp; + emits event ShutDown; + emits event Leave; + callback attribute dataModelRevision; + callback attribute vendorName; + callback attribute vendorID; + callback attribute productName; + callback attribute productID; + persist attribute nodeLabel; + callback attribute location; + callback attribute hardwareVersion; + callback attribute hardwareVersionString; + callback attribute softwareVersion; + callback attribute softwareVersionString; + callback attribute manufacturingDate; + callback attribute partNumber; + callback attribute productURL; + callback attribute productLabel; + callback attribute serialNumber; + persist attribute localConfigDisabled default = 0; + callback attribute uniqueID; + callback attribute capabilityMinima; + callback attribute specificationVersion; + callback attribute maxPathsPerInvoke; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 3; + } + + server cluster OtaSoftwareUpdateRequestor { + emits event StateTransition; + emits event VersionApplied; + emits event DownloadError; + callback attribute defaultOTAProviders; + ram attribute updatePossible default = 1; + ram attribute updateState default = 0; + ram attribute updateStateProgress default = 0; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + + handle command AnnounceOTAProvider; + } + + server cluster GeneralCommissioning { + ram attribute breadcrumb default = 0x0000000000000000; + callback attribute basicCommissioningInfo; + callback attribute regulatoryConfig; + callback attribute locationCapability; + callback attribute supportsConcurrentConnection; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + + handle command ArmFailSafe; + handle command ArmFailSafeResponse; + handle command SetRegulatoryConfig; + handle command SetRegulatoryConfigResponse; + handle command CommissioningComplete; + handle command CommissioningCompleteResponse; + } + + server cluster NetworkCommissioning { + ram attribute maxNetworks; + callback attribute networks; + ram attribute scanMaxTimeSeconds; + ram attribute connectMaxTimeSeconds; + ram attribute interfaceEnabled; + ram attribute lastNetworkingStatus; + ram attribute lastNetworkID; + ram attribute lastConnectErrorValue; + ram attribute featureMap default = 2; + ram attribute clusterRevision default = 1; + + handle command ScanNetworks; + handle command ScanNetworksResponse; + handle command AddOrUpdateWiFiNetwork; + handle command AddOrUpdateThreadNetwork; + handle command RemoveNetwork; + handle command NetworkConfigResponse; + handle command ConnectNetwork; + handle command ConnectNetworkResponse; + handle command ReorderNetwork; + } + + server cluster DiagnosticLogs { + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + + handle command RetrieveLogsRequest; + handle command RetrieveLogsResponse; + } + + server cluster GeneralDiagnostics { + emits event BootReason; + callback attribute networkInterfaces; + callback attribute rebootCount; + callback attribute upTime; + callback attribute totalOperationalHours; + callback attribute bootReason; + callback attribute activeHardwareFaults; + callback attribute activeRadioFaults; + callback attribute activeNetworkFaults; + callback attribute testEventTriggersEnabled default = false; + callback attribute featureMap; + callback attribute clusterRevision; + + handle command TestEventTrigger; + handle command TimeSnapshot; + handle command TimeSnapshotResponse; + } + + server cluster SoftwareDiagnostics { + callback attribute threadMetrics; + callback attribute currentHeapFree; + callback attribute currentHeapUsed; + callback attribute currentHeapHighWatermark; + callback attribute featureMap; + ram attribute clusterRevision default = 1; + + handle command ResetWatermarks; + } + + server cluster ThreadNetworkDiagnostics { + callback attribute channel; + callback attribute routingRole; + callback attribute networkName; + callback attribute panId; + callback attribute extendedPanId; + callback attribute meshLocalPrefix; + callback attribute overrunCount; + callback attribute neighborTable; + callback attribute routeTable; + callback attribute partitionId; + callback attribute weighting; + callback attribute dataVersion; + callback attribute stableDataVersion; + callback attribute leaderRouterId; + callback attribute detachedRoleCount; + callback attribute childRoleCount; + callback attribute routerRoleCount; + callback attribute leaderRoleCount; + callback attribute attachAttemptCount; + callback attribute partitionIdChangeCount; + callback attribute betterPartitionAttachAttemptCount; + callback attribute parentChangeCount; + callback attribute txTotalCount; + callback attribute txUnicastCount; + callback attribute txBroadcastCount; + callback attribute txAckRequestedCount; + callback attribute txAckedCount; + callback attribute txNoAckRequestedCount; + callback attribute txDataCount; + callback attribute txDataPollCount; + callback attribute txBeaconCount; + callback attribute txBeaconRequestCount; + callback attribute txOtherCount; + callback attribute txRetryCount; + callback attribute txDirectMaxRetryExpiryCount; + callback attribute txIndirectMaxRetryExpiryCount; + callback attribute txErrCcaCount; + callback attribute txErrAbortCount; + callback attribute txErrBusyChannelCount; + callback attribute rxTotalCount; + callback attribute rxUnicastCount; + callback attribute rxBroadcastCount; + callback attribute rxDataCount; + callback attribute rxDataPollCount; + callback attribute rxBeaconCount; + callback attribute rxBeaconRequestCount; + callback attribute rxOtherCount; + callback attribute rxAddressFilteredCount; + callback attribute rxDestAddrFilteredCount; + callback attribute rxDuplicatedCount; + callback attribute rxErrNoFrameCount; + callback attribute rxErrUnknownNeighborCount; + callback attribute rxErrInvalidSrcAddrCount; + callback attribute rxErrSecCount; + callback attribute rxErrFcsCount; + callback attribute rxErrOtherCount; + callback attribute activeTimestamp; + callback attribute pendingTimestamp; + callback attribute delay; + callback attribute securityPolicy; + callback attribute channelPage0Mask; + callback attribute operationalDatasetComponents; + callback attribute activeNetworkFaultsList; + ram attribute featureMap default = 0x000F; + ram attribute clusterRevision default = 2; + + handle command ResetCounts; + } + + server cluster WiFiNetworkDiagnostics { + emits event Disconnection; + emits event AssociationFailure; + emits event ConnectionStatus; + callback attribute bssid; + callback attribute securityType; + callback attribute wiFiVersion; + callback attribute channelNumber; + callback attribute rssi; + callback attribute beaconLostCount; + callback attribute beaconRxCount; + callback attribute packetMulticastRxCount; + callback attribute packetMulticastTxCount; + callback attribute packetUnicastRxCount; + callback attribute packetUnicastTxCount; + callback attribute currentMaxRate; + callback attribute overrunCount; + ram attribute featureMap default = 3; + ram attribute clusterRevision default = 1; + + handle command ResetCounts; + } + + server cluster EthernetNetworkDiagnostics { + callback attribute PHYRate; + callback attribute fullDuplex; + callback attribute packetRxCount; + callback attribute packetTxCount; + callback attribute txErrCount; + callback attribute collisionCount; + callback attribute overrunCount; + callback attribute carrierDetect; + callback attribute timeSinceReset; + ram attribute featureMap default = 3; + ram attribute clusterRevision default = 1; + + handle command ResetCounts; + } + + server cluster TimeSynchronization { + emits event DSTTableEmpty; + emits event DSTStatus; + emits event TimeZoneStatus; + emits event TimeFailure; + emits event MissingTrustedTimeSource; + callback attribute UTCTime; + callback attribute granularity; + ram attribute timeSource default = 0x00; + callback attribute trustedTimeSource; + callback attribute defaultNTP; + callback attribute timeZone; + callback attribute DSTOffset; + callback attribute localTime; + ram attribute timeZoneDatabase default = 0; + callback attribute timeZoneListMaxSize; + callback attribute DSTOffsetListMaxSize; + ram attribute supportsDNSResolve default = false; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute attributeList; + ram attribute featureMap default = 0x0B; + ram attribute clusterRevision default = 2; + + handle command SetUTCTime; + handle command SetTrustedTimeSource; + handle command SetTimeZone; + handle command SetTimeZoneResponse; + handle command SetDSTOffset; + handle command SetDefaultNTP; + } + + server cluster AdministratorCommissioning { + callback attribute windowStatus; + callback attribute adminFabricIndex; + callback attribute adminVendorId; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + + handle command OpenCommissioningWindow; + handle command RevokeCommissioning; + } + + server cluster OperationalCredentials { + callback attribute NOCs; + callback attribute fabrics; + callback attribute supportedFabrics; + callback attribute commissionedFabrics; + callback attribute trustedRootCertificates; + callback attribute currentFabricIndex; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + + handle command AttestationRequest; + handle command AttestationResponse; + handle command CertificateChainRequest; + handle command CertificateChainResponse; + handle command CSRRequest; + handle command CSRResponse; + handle command AddNOC; + handle command UpdateNOC; + handle command NOCResponse; + handle command UpdateFabricLabel; + handle command RemoveFabric; + handle command AddTrustedRootCertificate; + } + + server cluster GroupKeyManagement { + callback attribute groupKeyMap; + callback attribute groupTable; + callback attribute maxGroupsPerFabric; + callback attribute maxGroupKeysPerFabric; + callback attribute featureMap; + callback attribute clusterRevision; + + handle command KeySetWrite; + handle command KeySetRead; + handle command KeySetReadResponse; + handle command KeySetRemove; + handle command KeySetReadAllIndices; + handle command KeySetReadAllIndicesResponse; + } + + server cluster FixedLabel { + callback attribute labelList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + } + + server cluster UserLabel { + callback attribute labelList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + } + + server cluster IcdManagement { + callback attribute idleModeDuration; + callback attribute activeModeDuration; + callback attribute activeModeThreshold; + callback attribute registeredClients; + callback attribute ICDCounter; + callback attribute clientsSupportedPerFabric; + ram attribute userActiveModeTriggerHint default = 0x1115; + ram attribute userActiveModeTriggerInstruction default = "Power Cycle"; + ram attribute operatingMode default = 0; + callback attribute maximumCheckInBackOff; + ram attribute featureMap default = 15; + ram attribute clusterRevision default = 3; + + handle command RegisterClient; + handle command RegisterClientResponse; + handle command UnregisterClient; + handle command StayActiveRequest; + handle command StayActiveResponse; + } +} +endpoint 1 { + device type ma_onofflightswitch = 259, version 1; + + binding cluster Identify; + binding cluster OnOff; + binding cluster ScenesManagement; + binding cluster ColorControl; + + server cluster Identify { + ram attribute identifyTime default = 0x0000; + ram attribute identifyType default = 0x0; + callback attribute attributeList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 4; + + handle command Identify; + handle command TriggerEffect; + } + + server cluster Groups { + ram attribute nameSupport; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 4; + + handle command AddGroup; + handle command AddGroupResponse; + handle command ViewGroup; + handle command ViewGroupResponse; + handle command GetGroupMembership; + handle command GetGroupMembershipResponse; + handle command RemoveGroup; + handle command RemoveGroupResponse; + handle command RemoveAllGroups; + handle command AddGroupIfIdentifying; + } + + server cluster Descriptor { + callback attribute deviceTypeList; + callback attribute serverList; + callback attribute clientList; + callback attribute partsList; + callback attribute attributeList; + callback attribute featureMap; + callback attribute clusterRevision; + } + + server cluster Binding { + callback attribute binding; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 1; + } +} +endpoint 2 { + device type ma_genericswitch = 15, version 1; + + + server cluster Identify { + ram attribute identifyTime default = 0x0; + ram attribute identifyType default = 0x0; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute attributeList; + ram attribute featureMap default = 0; + ram attribute clusterRevision default = 2; + + handle command Identify; + handle command TriggerEffect; + } + + server cluster Descriptor { + callback attribute deviceTypeList; + callback attribute serverList; + callback attribute clientList; + callback attribute partsList; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute attributeList; + callback attribute featureMap; + callback attribute clusterRevision; + } + + server cluster Switch { + emits event InitialPress; + ram attribute numberOfPositions default = 2; + ram attribute currentPosition default = 0; + callback attribute generatedCommandList; + callback attribute acceptedCommandList; + callback attribute attributeList; + ram attribute featureMap default = 6; + ram attribute clusterRevision default = 2; + } +} + + diff --git a/examples/light-switch-app/light-switch-common/icd-lit-light-switch-app.zap b/examples/light-switch-app/light-switch-common/icd-lit-light-switch-app.zap new file mode 100644 index 00000000000000..bc81c51ff705c8 --- /dev/null +++ b/examples/light-switch-app/light-switch-common/icd-lit-light-switch-app.zap @@ -0,0 +1,5812 @@ +{ + "fileFormat": 2, + "featureLevel": 104, + "creator": "zap", + "keyValuePairs": [ + { + "key": "commandDiscovery", + "value": "1" + }, + { + "key": "defaultResponsePolicy", + "value": "always" + }, + { + "key": "manufacturerCodes", + "value": "0x1002" + } + ], + "package": [ + { + "pathRelativity": "relativeToZap", + "path": "../../../src/app/zap-templates/zcl/zcl.json", + "type": "zcl-properties", + "category": "matter", + "version": 1, + "description": "Matter SDK ZCL data" + }, + { + "pathRelativity": "relativeToZap", + "path": "../../../src/app/zap-templates/app-templates.json", + "type": "gen-templates-json", + "category": "matter", + "version": "chip-v1" + } + ], + "endpointTypes": [ + { + "id": 1, + "name": "MA-rootdevice", + "deviceTypeRef": { + "code": 22, + "profileId": 259, + "label": "MA-rootdevice", + "name": "MA-rootdevice", + "deviceTypeOrder": 0 + }, + "deviceTypes": [ + { + "code": 22, + "profileId": 259, + "label": "MA-rootdevice", + "name": "MA-rootdevice", + "deviceTypeOrder": 0 + } + ], + "deviceVersions": [ + 1 + ], + "deviceIdentifiers": [ + 22 + ], + "deviceTypeName": "MA-rootdevice", + "deviceTypeCode": 22, + "deviceTypeProfileId": 259, + "clusters": [ + { + "name": "Descriptor", + "code": 29, + "mfgCode": null, + "define": "DESCRIPTOR_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "DeviceTypeList", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ServerList", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClientList", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "PartsList", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "Binding", + "code": 30, + "mfgCode": null, + "define": "BINDING_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "Binding", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "Access Control", + "code": 31, + "mfgCode": null, + "define": "ACCESS_CONTROL_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "ACL", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "Extension", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "SubjectsPerAccessControlEntry", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "TargetsPerAccessControlEntry", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AccessControlEntriesPerFabric", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ], + "events": [ + { + "name": "AccessControlEntryChanged", + "code": 0, + "mfgCode": null, + "side": "server", + "included": 1 + }, + { + "name": "AccessControlExtensionChanged", + "code": 1, + "mfgCode": null, + "side": "server", + "included": 1 + } + ] + }, + { + "name": "Basic Information", + "code": 40, + "mfgCode": null, + "define": "BASIC_INFORMATION_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "DataModelRevision", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "VendorName", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "VendorID", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "vendor_id", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ProductName", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ProductID", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "NodeLabel", + "code": 5, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "NVM", + "singleton": 1, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "Location", + "code": 6, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "HardwareVersion", + "code": 7, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "HardwareVersionString", + "code": 8, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "SoftwareVersion", + "code": 9, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "SoftwareVersionString", + "code": 10, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ManufacturingDate", + "code": 11, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "PartNumber", + "code": 12, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ProductURL", + "code": 13, + "mfgCode": null, + "side": "server", + "type": "long_char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ProductLabel", + "code": 14, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "SerialNumber", + "code": 15, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "LocalConfigDisabled", + "code": 16, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "NVM", + "singleton": 1, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "UniqueID", + "code": 18, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "CapabilityMinima", + "code": 19, + "mfgCode": null, + "side": "server", + "type": "CapabilityMinimaStruct", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "SpecificationVersion", + "code": 21, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "MaxPathsPerInvoke", + "code": 22, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 1, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 1, + "bounded": 0, + "defaultValue": "3", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ], + "events": [ + { + "name": "StartUp", + "code": 0, + "mfgCode": null, + "side": "server", + "included": 1 + }, + { + "name": "ShutDown", + "code": 1, + "mfgCode": null, + "side": "server", + "included": 1 + }, + { + "name": "Leave", + "code": 2, + "mfgCode": null, + "side": "server", + "included": 1 + } + ] + }, + { + "name": "OTA Software Update Provider", + "code": 41, + "mfgCode": null, + "define": "OTA_SOFTWARE_UPDATE_PROVIDER_CLUSTER", + "side": "client", + "enabled": 1, + "commands": [ + { + "name": "QueryImage", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "QueryImageResponse", + "code": 1, + "mfgCode": null, + "source": "server", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "ApplyUpdateRequest", + "code": 2, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "ApplyUpdateResponse", + "code": 3, + "mfgCode": null, + "source": "server", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "NotifyUpdateApplied", + "code": 4, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + } + ] + }, + { + "name": "OTA Software Update Requestor", + "code": 42, + "mfgCode": null, + "define": "OTA_SOFTWARE_UPDATE_REQUESTOR_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "AnnounceOTAProvider", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "DefaultOTAProviders", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "UpdatePossible", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "UpdateState", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "UpdateStateEnum", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "UpdateStateProgress", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ], + "events": [ + { + "name": "StateTransition", + "code": 0, + "mfgCode": null, + "side": "server", + "included": 1 + }, + { + "name": "VersionApplied", + "code": 1, + "mfgCode": null, + "side": "server", + "included": 1 + }, + { + "name": "DownloadError", + "code": 2, + "mfgCode": null, + "side": "server", + "included": 1 + } + ] + }, + { + "name": "General Commissioning", + "code": 48, + "mfgCode": null, + "define": "GENERAL_COMMISSIONING_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "ArmFailSafe", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "ArmFailSafeResponse", + "code": 1, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "SetRegulatoryConfig", + "code": 2, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "SetRegulatoryConfigResponse", + "code": 3, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "CommissioningComplete", + "code": 4, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "CommissioningCompleteResponse", + "code": 5, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "Breadcrumb", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000000000000000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "BasicCommissioningInfo", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "BasicCommissioningInfo", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RegulatoryConfig", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "RegulatoryLocationTypeEnum", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "LocationCapability", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "RegulatoryLocationTypeEnum", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "SupportsConcurrentConnection", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Network Commissioning", + "code": 49, + "mfgCode": null, + "define": "NETWORK_COMMISSIONING_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "ScanNetworks", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "ScanNetworksResponse", + "code": 1, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "AddOrUpdateWiFiNetwork", + "code": 2, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "AddOrUpdateThreadNetwork", + "code": 3, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "RemoveNetwork", + "code": 4, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "NetworkConfigResponse", + "code": 5, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "ConnectNetwork", + "code": 6, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "ConnectNetworkResponse", + "code": 7, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "ReorderNetwork", + "code": 8, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "MaxNetworks", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "Networks", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ScanMaxTimeSeconds", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ConnectMaxTimeSeconds", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "InterfaceEnabled", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "LastNetworkingStatus", + "code": 5, + "mfgCode": null, + "side": "server", + "type": "NetworkCommissioningStatusEnum", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "LastNetworkID", + "code": 6, + "mfgCode": null, + "side": "server", + "type": "octet_string", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "LastConnectErrorValue", + "code": 7, + "mfgCode": null, + "side": "server", + "type": "int32s", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "2", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Diagnostic Logs", + "code": 50, + "mfgCode": null, + "define": "DIAGNOSTIC_LOGS_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "RetrieveLogsRequest", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "RetrieveLogsResponse", + "code": 1, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "General Diagnostics", + "code": 51, + "mfgCode": null, + "define": "GENERAL_DIAGNOSTICS_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "TestEventTrigger", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "TimeSnapshot", + "code": 1, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "TimeSnapshotResponse", + "code": 2, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "NetworkInterfaces", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RebootCount", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "UpTime", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "TotalOperationalHours", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "BootReason", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "BootReasonEnum", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ActiveHardwareFaults", + "code": 5, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ActiveRadioFaults", + "code": 6, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ActiveNetworkFaults", + "code": 7, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "TestEventTriggersEnabled", + "code": 8, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": "false", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ], + "events": [ + { + "name": "BootReason", + "code": 3, + "mfgCode": null, + "side": "server", + "included": 1 + } + ] + }, + { + "name": "Software Diagnostics", + "code": 52, + "mfgCode": null, + "define": "SOFTWARE_DIAGNOSTICS_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "ResetWatermarks", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "ThreadMetrics", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "CurrentHeapFree", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "CurrentHeapUsed", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "CurrentHeapHighWatermark", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Thread Network Diagnostics", + "code": 53, + "mfgCode": null, + "define": "THREAD_NETWORK_DIAGNOSTICS_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "ResetCounts", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "Channel", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RoutingRole", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "RoutingRoleEnum", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "NetworkName", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "PanId", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ExtendedPanId", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "MeshLocalPrefix", + "code": 5, + "mfgCode": null, + "side": "server", + "type": "octet_string", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "OverrunCount", + "code": 6, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "NeighborTable", + "code": 7, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RouteTable", + "code": 8, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "PartitionId", + "code": 9, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "Weighting", + "code": 10, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "DataVersion", + "code": 11, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "StableDataVersion", + "code": 12, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "LeaderRouterId", + "code": 13, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "DetachedRoleCount", + "code": 14, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ChildRoleCount", + "code": 15, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RouterRoleCount", + "code": 16, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "LeaderRoleCount", + "code": 17, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "AttachAttemptCount", + "code": 18, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "PartitionIdChangeCount", + "code": 19, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "BetterPartitionAttachAttemptCount", + "code": 20, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ParentChangeCount", + "code": 21, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxTotalCount", + "code": 22, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxUnicastCount", + "code": 23, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxBroadcastCount", + "code": 24, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxAckRequestedCount", + "code": 25, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxAckedCount", + "code": 26, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxNoAckRequestedCount", + "code": 27, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxDataCount", + "code": 28, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxDataPollCount", + "code": 29, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxBeaconCount", + "code": 30, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxBeaconRequestCount", + "code": 31, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxOtherCount", + "code": 32, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxRetryCount", + "code": 33, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxDirectMaxRetryExpiryCount", + "code": 34, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxIndirectMaxRetryExpiryCount", + "code": 35, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxErrCcaCount", + "code": 36, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxErrAbortCount", + "code": 37, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxErrBusyChannelCount", + "code": 38, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxTotalCount", + "code": 39, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxUnicastCount", + "code": 40, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxBroadcastCount", + "code": 41, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxDataCount", + "code": 42, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxDataPollCount", + "code": 43, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxBeaconCount", + "code": 44, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxBeaconRequestCount", + "code": 45, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxOtherCount", + "code": 46, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxAddressFilteredCount", + "code": 47, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxDestAddrFilteredCount", + "code": 48, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxDuplicatedCount", + "code": 49, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxErrNoFrameCount", + "code": 50, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxErrUnknownNeighborCount", + "code": 51, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxErrInvalidSrcAddrCount", + "code": 52, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxErrSecCount", + "code": 53, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxErrFcsCount", + "code": 54, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RxErrOtherCount", + "code": 55, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ActiveTimestamp", + "code": 56, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "PendingTimestamp", + "code": 57, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "Delay", + "code": 58, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "SecurityPolicy", + "code": 59, + "mfgCode": null, + "side": "server", + "type": "SecurityPolicy", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ChannelPage0Mask", + "code": 60, + "mfgCode": null, + "side": "server", + "type": "octet_string", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "OperationalDatasetComponents", + "code": 61, + "mfgCode": null, + "side": "server", + "type": "OperationalDatasetComponents", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ActiveNetworkFaultsList", + "code": 62, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x000F", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "2", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Wi-Fi Network Diagnostics", + "code": 54, + "mfgCode": null, + "define": "WIFI_NETWORK_DIAGNOSTICS_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "ResetCounts", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "BSSID", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "octet_string", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "SecurityType", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "SecurityTypeEnum", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "WiFiVersion", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "WiFiVersionEnum", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "ChannelNumber", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "RSSI", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "int8s", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "BeaconLostCount", + "code": 5, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "BeaconRxCount", + "code": 6, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "PacketMulticastRxCount", + "code": 7, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "PacketMulticastTxCount", + "code": 8, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "PacketUnicastRxCount", + "code": 9, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "PacketUnicastTxCount", + "code": 10, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "CurrentMaxRate", + "code": 11, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "OverrunCount", + "code": 12, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "3", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ], + "events": [ + { + "name": "Disconnection", + "code": 0, + "mfgCode": null, + "side": "server", + "included": 1 + }, + { + "name": "AssociationFailure", + "code": 1, + "mfgCode": null, + "side": "server", + "included": 1 + }, + { + "name": "ConnectionStatus", + "code": 2, + "mfgCode": null, + "side": "server", + "included": 1 + } + ] + }, + { + "name": "Ethernet Network Diagnostics", + "code": 55, + "mfgCode": null, + "define": "ETHERNET_NETWORK_DIAGNOSTICS_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "ResetCounts", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "PHYRate", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "PHYRateEnum", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FullDuplex", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "PacketRxCount", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "PacketTxCount", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TxErrCount", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "CollisionCount", + "code": 5, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "OverrunCount", + "code": 6, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "CarrierDetect", + "code": 7, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "TimeSinceReset", + "code": 8, + "mfgCode": null, + "side": "server", + "type": "int64u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "3", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Time Synchronization", + "code": 56, + "mfgCode": null, + "define": "TIME_SYNCHRONIZATION_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "SetUTCTime", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "SetTrustedTimeSource", + "code": 1, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "SetTimeZone", + "code": 2, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "SetTimeZoneResponse", + "code": 3, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "SetDSTOffset", + "code": 4, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "SetDefaultNTP", + "code": 5, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "UTCTime", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "epoch_us", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "Granularity", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "GranularityEnum", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "TimeSource", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "TimeSourceEnum", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x00", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "TrustedTimeSource", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "TrustedTimeSourceStruct", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "DefaultNTP", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "TimeZone", + "code": 5, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "DSTOffset", + "code": 6, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "LocalTime", + "code": 7, + "mfgCode": null, + "side": "server", + "type": "epoch_us", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "TimeZoneDatabase", + "code": 8, + "mfgCode": null, + "side": "server", + "type": "TimeZoneDatabaseEnum", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "TimeZoneListMaxSize", + "code": 10, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "DSTOffsetListMaxSize", + "code": 11, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "SupportsDNSResolve", + "code": 12, + "mfgCode": null, + "side": "server", + "type": "boolean", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "false", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0B", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "2", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ], + "events": [ + { + "name": "DSTTableEmpty", + "code": 0, + "mfgCode": null, + "side": "server", + "included": 1 + }, + { + "name": "DSTStatus", + "code": 1, + "mfgCode": null, + "side": "server", + "included": 1 + }, + { + "name": "TimeZoneStatus", + "code": 2, + "mfgCode": null, + "side": "server", + "included": 1 + }, + { + "name": "TimeFailure", + "code": 3, + "mfgCode": null, + "side": "server", + "included": 1 + }, + { + "name": "MissingTrustedTimeSource", + "code": 4, + "mfgCode": null, + "side": "server", + "included": 1 + } + ] + }, + { + "name": "Administrator Commissioning", + "code": 60, + "mfgCode": null, + "define": "ADMINISTRATOR_COMMISSIONING_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "OpenCommissioningWindow", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "RevokeCommissioning", + "code": 2, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "WindowStatus", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "CommissioningWindowStatusEnum", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AdminFabricIndex", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "fabric_idx", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AdminVendorId", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "vendor_id", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Operational Credentials", + "code": 62, + "mfgCode": null, + "define": "OPERATIONAL_CREDENTIALS_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "AttestationRequest", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "AttestationResponse", + "code": 1, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "CertificateChainRequest", + "code": 2, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "CertificateChainResponse", + "code": 3, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "CSRRequest", + "code": 4, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "CSRResponse", + "code": 5, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "AddNOC", + "code": 6, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "UpdateNOC", + "code": 7, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "NOCResponse", + "code": 8, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "UpdateFabricLabel", + "code": 9, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "RemoveFabric", + "code": 10, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "AddTrustedRootCertificate", + "code": 11, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "NOCs", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "Fabrics", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "SupportedFabrics", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "CommissionedFabrics", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "TrustedRootCertificates", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "CurrentFabricIndex", + "code": 5, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Group Key Management", + "code": 63, + "mfgCode": null, + "define": "GROUP_KEY_MANAGEMENT_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "KeySetWrite", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "KeySetRead", + "code": 1, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "KeySetReadResponse", + "code": 2, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "KeySetRemove", + "code": 3, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "KeySetReadAllIndices", + "code": 4, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "KeySetReadAllIndicesResponse", + "code": 5, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "GroupKeyMap", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GroupTable", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "MaxGroupsPerFabric", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "MaxGroupKeysPerFabric", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "Fixed Label", + "code": 64, + "mfgCode": null, + "define": "FIXED_LABEL_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "LabelList", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "User Label", + "code": 65, + "mfgCode": null, + "define": "USER_LABEL_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "LabelList", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "ICD Management", + "code": 70, + "mfgCode": null, + "define": "ICD_MANAGEMENT_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "RegisterClient", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "RegisterClientResponse", + "code": 1, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "UnregisterClient", + "code": 2, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "StayActiveRequest", + "code": 3, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "StayActiveResponse", + "code": 4, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "IdleModeDuration", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ActiveModeDuration", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ActiveModeThreshold", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "RegisteredClients", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ICDCounter", + "code": 4, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClientsSupportedPerFabric", + "code": 5, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "UserActiveModeTriggerHint", + "code": 6, + "mfgCode": null, + "side": "server", + "type": "UserActiveModeTriggerBitmap", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x1115", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "UserActiveModeTriggerInstruction", + "code": 7, + "mfgCode": null, + "side": "server", + "type": "char_string", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "Power Cycle", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "OperatingMode", + "code": 8, + "mfgCode": null, + "side": "server", + "type": "OperatingModeEnum", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "MaximumCheckInBackOff", + "code": 9, + "mfgCode": null, + "side": "server", + "type": "int32u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "15", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "3", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + } + ] + }, + { + "id": 2, + "name": "MA-onofflightswitch", + "deviceTypeRef": { + "code": 259, + "profileId": 259, + "label": "MA-onofflightswitch", + "name": "MA-onofflightswitch", + "deviceTypeOrder": 0 + }, + "deviceTypes": [ + { + "code": 259, + "profileId": 259, + "label": "MA-onofflightswitch", + "name": "MA-onofflightswitch", + "deviceTypeOrder": 0 + } + ], + "deviceVersions": [ + 1 + ], + "deviceIdentifiers": [ + 259 + ], + "deviceTypeName": "MA-onofflightswitch", + "deviceTypeCode": 259, + "deviceTypeProfileId": 259, + "clusters": [ + { + "name": "Identify", + "code": 3, + "mfgCode": null, + "define": "IDENTIFY_CLUSTER", + "side": "client", + "enabled": 1, + "commands": [ + { + "name": "Identify", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "TriggerEffect", + "code": 64, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + } + ] + }, + { + "name": "Identify", + "code": 3, + "mfgCode": null, + "define": "IDENTIFY_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "Identify", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "TriggerEffect", + "code": 64, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "IdentifyTime", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0000", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "IdentifyType", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "IdentifyTypeEnum", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "4", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "Groups", + "code": 4, + "mfgCode": null, + "define": "GROUPS_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "AddGroup", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "AddGroupResponse", + "code": 0, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "ViewGroup", + "code": 1, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "ViewGroupResponse", + "code": 1, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "GetGroupMembership", + "code": 2, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "GetGroupMembershipResponse", + "code": 2, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "RemoveGroup", + "code": 3, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "RemoveGroupResponse", + "code": 3, + "mfgCode": null, + "source": "server", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "RemoveAllGroups", + "code": 4, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "AddGroupIfIdentifying", + "code": 5, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "NameSupport", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "NameSupportBitmap", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "4", + "reportable": 1, + "minInterval": 0, + "maxInterval": 65344, + "reportableChange": 0 + } + ] + }, + { + "name": "On/Off", + "code": 6, + "mfgCode": null, + "define": "ON_OFF_CLUSTER", + "side": "client", + "enabled": 1, + "commands": [ + { + "name": "Off", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "On", + "code": 1, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "Toggle", + "code": 2, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + } + ] + }, + { + "name": "Descriptor", + "code": 29, + "mfgCode": null, + "define": "DESCRIPTOR_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "DeviceTypeList", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ServerList", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClientList", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "PartsList", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "Binding", + "code": 30, + "mfgCode": null, + "define": "BINDING_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "Binding", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "1", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "Scenes Management", + "code": 98, + "mfgCode": null, + "define": "SCENES_CLUSTER", + "side": "client", + "enabled": 1, + "apiMaturity": "provisional", + "commands": [ + { + "name": "AddScene", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "AddSceneResponse", + "code": 0, + "mfgCode": null, + "source": "server", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "ViewScene", + "code": 1, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "ViewSceneResponse", + "code": 1, + "mfgCode": null, + "source": "server", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "RemoveScene", + "code": 2, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "RemoveSceneResponse", + "code": 2, + "mfgCode": null, + "source": "server", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "RemoveAllScenes", + "code": 3, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "RemoveAllScenesResponse", + "code": 3, + "mfgCode": null, + "source": "server", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "StoreScene", + "code": 4, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "StoreSceneResponse", + "code": 4, + "mfgCode": null, + "source": "server", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "RecallScene", + "code": 5, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "GetSceneMembership", + "code": 6, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "GetSceneMembershipResponse", + "code": 6, + "mfgCode": null, + "source": "server", + "isIncoming": 1, + "isEnabled": 1 + } + ] + }, + { + "name": "Color Control", + "code": 768, + "mfgCode": null, + "define": "COLOR_CONTROL_CLUSTER", + "side": "client", + "enabled": 1, + "commands": [ + { + "name": "MoveToHue", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "MoveHue", + "code": 1, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "StepHue", + "code": 2, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "MoveToSaturation", + "code": 3, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "MoveSaturation", + "code": 4, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "StepSaturation", + "code": 5, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "MoveToHueAndSaturation", + "code": 6, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "MoveToColor", + "code": 7, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "MoveColor", + "code": 8, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "StepColor", + "code": 9, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "MoveToColorTemperature", + "code": 10, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "EnhancedMoveToHue", + "code": 64, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "EnhancedMoveHue", + "code": 65, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "EnhancedStepHue", + "code": 66, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "EnhancedMoveToHueAndSaturation", + "code": 67, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + }, + { + "name": "ColorLoopSet", + "code": 68, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + } + ] + } + ] + }, + { + "id": 3, + "name": "MA-genericswitch", + "deviceTypeRef": { + "code": 15, + "profileId": 259, + "label": "MA-genericswitch", + "name": "MA-genericswitch", + "deviceTypeOrder": 0 + }, + "deviceTypes": [ + { + "code": 15, + "profileId": 259, + "label": "MA-genericswitch", + "name": "MA-genericswitch", + "deviceTypeOrder": 0 + } + ], + "deviceVersions": [ + 1 + ], + "deviceIdentifiers": [ + 15 + ], + "deviceTypeName": "MA-genericswitch", + "deviceTypeCode": 15, + "deviceTypeProfileId": 259, + "clusters": [ + { + "name": "Identify", + "code": 3, + "mfgCode": null, + "define": "IDENTIFY_CLUSTER", + "side": "server", + "enabled": 1, + "commands": [ + { + "name": "Identify", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + }, + { + "name": "TriggerEffect", + "code": 64, + "mfgCode": null, + "source": "client", + "isIncoming": 1, + "isEnabled": 1 + } + ], + "attributes": [ + { + "name": "IdentifyTime", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "IdentifyType", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "IdentifyTypeEnum", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0x0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "2", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "Descriptor", + "code": 29, + "mfgCode": null, + "define": "DESCRIPTOR_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "DeviceTypeList", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ServerList", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClientList", + "code": 2, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "PartsList", + "code": 3, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ] + }, + { + "name": "Switch", + "code": 59, + "mfgCode": null, + "define": "SWITCH_CLUSTER", + "side": "server", + "enabled": 1, + "attributes": [ + { + "name": "NumberOfPositions", + "code": 0, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "2", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "CurrentPosition", + "code": 1, + "mfgCode": null, + "side": "server", + "type": "int8u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "0", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "GeneratedCommandList", + "code": 65528, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AcceptedCommandList", + "code": 65529, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "AttributeList", + "code": 65531, + "mfgCode": null, + "side": "server", + "type": "array", + "included": 1, + "storageOption": "External", + "singleton": 0, + "bounded": 0, + "defaultValue": null, + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "FeatureMap", + "code": 65532, + "mfgCode": null, + "side": "server", + "type": "bitmap32", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "6", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + }, + { + "name": "ClusterRevision", + "code": 65533, + "mfgCode": null, + "side": "server", + "type": "int16u", + "included": 1, + "storageOption": "RAM", + "singleton": 0, + "bounded": 0, + "defaultValue": "2", + "reportable": 1, + "minInterval": 1, + "maxInterval": 65534, + "reportableChange": 0 + } + ], + "events": [ + { + "name": "InitialPress", + "code": 1, + "mfgCode": null, + "side": "server", + "included": 1 + } + ] + } + ] + } + ], + "endpoints": [ + { + "endpointTypeName": "MA-rootdevice", + "endpointTypeIndex": 0, + "profileId": 259, + "endpointId": 0, + "networkId": 0, + "parentEndpointIdentifier": null + }, + { + "endpointTypeName": "MA-onofflightswitch", + "endpointTypeIndex": 1, + "profileId": 259, + "endpointId": 1, + "networkId": 0, + "parentEndpointIdentifier": null + }, + { + "endpointTypeName": "MA-genericswitch", + "endpointTypeIndex": 2, + "profileId": 259, + "endpointId": 2, + "networkId": 0, + "parentEndpointIdentifier": null + } + ] +} \ No newline at end of file diff --git a/examples/light-switch-app/silabs/openthread.gni b/examples/light-switch-app/silabs/openthread.gni index 8dd097480220b0..4ec1c04a927404 100644 --- a/examples/light-switch-app/silabs/openthread.gni +++ b/examples/light-switch-app/silabs/openthread.gni @@ -29,14 +29,17 @@ sl_enable_test_event_trigger = true # ICD Default configurations chip_enable_icd_server = true +chip_enable_icd_lit = true +chip_enable_icd_dsls = true + chip_subscription_timeout_resumption = false sl_use_subscription_syncing = true # Openthread Configuration flags -sl_ot_idle_interval_ms = 15000 # 15s Idle Intervals -sl_ot_active_interval_ms = 500 # 500ms Active Intervals +sl_ot_idle_interval_ms = 2100000 # 35 minutes Idle Intervals +sl_ot_active_interval_ms = 1000 # 1000ms Active Intervals # ICD Matter Configuration flags -sl_idle_mode_duration_s = 3600 # 60min Idle Mode Duration -sl_active_mode_duration_ms = 60000 # 60s Active Mode Duration -sl_active_mode_threshold_ms = 1000 # 1s Active Mode Threshold +sl_idle_mode_duration_s = 1800 # 30min Idle Mode Duration +sl_active_mode_duration_ms = 0 # 0s Active Mode Duration +sl_active_mode_threshold_ms = 5000 # 5s Active Mode Threshold diff --git a/examples/lit-icd-app/silabs/build_for_wifi_args.gni b/examples/lit-icd-app/silabs/build_for_wifi_args.gni index 6ef009e9064d75..c8048dc71e3b4b 100644 --- a/examples/lit-icd-app/silabs/build_for_wifi_args.gni +++ b/examples/lit-icd-app/silabs/build_for_wifi_args.gni @@ -30,6 +30,7 @@ chip_enable_icd_server = true chip_subscription_timeout_resumption = false sl_use_subscription_syncing = true chip_enable_icd_lit = true +chip_enable_icd_dsls = true # ICD Matter Configuration flags sl_idle_mode_duration_s = 3600 # 60min Idle Mode Duration diff --git a/examples/lit-icd-app/silabs/openthread.gni b/examples/lit-icd-app/silabs/openthread.gni index e84e7be8ed1292..c09176354a3d76 100644 --- a/examples/lit-icd-app/silabs/openthread.gni +++ b/examples/lit-icd-app/silabs/openthread.gni @@ -34,6 +34,7 @@ chip_subscription_timeout_resumption = false sl_use_subscription_syncing = true chip_icd_report_on_active_mode = true chip_enable_icd_lit = true +chip_enable_icd_dsls = true # Openthread Configuration flags sl_ot_idle_interval_ms = 3600000 # 60mins Idle Polling Interval diff --git a/examples/lit-icd-app/silabs/src/ShellCommands.cpp b/examples/lit-icd-app/silabs/src/ShellCommands.cpp deleted file mode 100644 index 52f305eb275333..00000000000000 --- a/examples/lit-icd-app/silabs/src/ShellCommands.cpp +++ /dev/null @@ -1,48 +0,0 @@ -/* - * - * Copyright (c) 2023 Project CHIP Authors - * All rights reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -#if defined(ENABLE_CHIP_SHELL) - -#include "ShellCommands.h" -#include -#include -#include - -using namespace chip; -using namespace chip::app; - -namespace LitICDCommands { - -using Shell::Engine; -using Shell::shell_command_t; -using Shell::streamer_get; -using Shell::streamer_printf; - -/** - * @brief configures lit icd matter shell - */ -void RegisterSwitchCommands() -{ - // Blank structure for now - static const shell_command_t sLitICDCommand = {}; - - Engine::Root().RegisterCommands(&sLitICDCommand, 1); -} - -} // namespace LitICDCommands - -#endif // ENABLE_CHIP_SHELL diff --git a/examples/platform/silabs/BaseApplication.cpp b/examples/platform/silabs/BaseApplication.cpp index b7ce3e9fed8bdf..5de80c2d108549 100644 --- a/examples/platform/silabs/BaseApplication.cpp +++ b/examples/platform/silabs/BaseApplication.cpp @@ -37,9 +37,13 @@ #endif // QR_CODE_ENABLED #endif // DISPLAY_ENABLED -#if CHIP_CONFIG_ENABLE_ICD_SERVER == 1 +#if CHIP_CONFIG_ENABLE_ICD_SERVER #include // nogncheck -#endif +#ifdef ENABLE_CHIP_SHELL +#include +#endif // ENABLE_CHIP_SHELL +#endif // CHIP_CONFIG_ENABLE_ICD_SERVER + #include #include #include @@ -121,7 +125,7 @@ app::Clusters::NetworkCommissioning::Instance bool sIsEnabled = false; bool sIsAttached = false; -#if !(defined(CHIP_CONFIG_ENABLE_ICD_SERVER) && CHIP_CONFIG_ENABLE_ICD_SERVER) +#if !(CHIP_CONFIG_ENABLE_ICD_SERVER) bool sHaveBLEConnections = false; #endif // CHIP_CONFIG_ENABLE_ICD_SERVER @@ -305,6 +309,12 @@ CHIP_ERROR BaseApplication::Init() sStatusLED.Init(SYSTEM_STATE_LED); #endif // ENABLE_WSTK_LEDS +#ifdef ENABLE_CHIP_SHELL +#if CHIP_CONFIG_ENABLE_ICD_SERVER + ICDCommands::RegisterCommands(); +#endif // CHIP_CONFIG_ENABLE_ICD_SERVER +#endif // ENABLE_CHIP_SHELL + #ifdef PERFORMANCE_TEST_ENABLED RegisterPerfTestCommands(); #endif // PERFORMANCE_TEST_ENABLED @@ -342,7 +352,7 @@ void BaseApplication::FunctionEventHandler(AppEvent * aEvent) { // The factory reset sequence was in motion. The cancellation window expired. // Factory Reset the device now. -#if CHIP_CONFIG_ENABLE_ICD_SERVER == 1 +#if CHIP_CONFIG_ENABLE_ICD_SERVER StopStatusLEDTimer(); #endif // CHIP_CONFIG_ENABLE_ICD_SERVER @@ -400,7 +410,7 @@ bool BaseApplication::ActivateStatusLedPatterns() } #endif // MATTER_DM_PLUGIN_IDENTIFY_SERVER -#if !(defined(CHIP_CONFIG_ENABLE_ICD_SERVER) && CHIP_CONFIG_ENABLE_ICD_SERVER) +#if !(CHIP_CONFIG_ENABLE_ICD_SERVER) // Identify Patterns have priority over Status patterns if (!isPatternSet) { @@ -456,7 +466,7 @@ void BaseApplication::LightEventHandler() // locked while these values are queried. However we use a non-blocking // lock request (TryLockCHIPStack()) to avoid blocking other UI activities // when the CHIP task is busy (e.g. with a long crypto operation). -#if !(defined(CHIP_CONFIG_ENABLE_ICD_SERVER) && CHIP_CONFIG_ENABLE_ICD_SERVER) +#if !(CHIP_CONFIG_ENABLE_ICD_SERVER) if (PlatformMgr().TryLockChipStack()) { #ifdef SL_WIFI @@ -599,7 +609,7 @@ void BaseApplication::StartFactoryResetSequence() StartFunctionTimer(FACTORY_RESET_CANCEL_WINDOW_TIMEOUT); sIsFactoryResetTriggered = true; -#if CHIP_CONFIG_ENABLE_ICD_SERVER == 1 +#if CHIP_CONFIG_ENABLE_ICD_SERVER StartStatusLEDTimer(); #endif // CHIP_CONFIG_ENABLE_ICD_SERVER @@ -615,7 +625,7 @@ void BaseApplication::CancelFactoryResetSequence() { CancelFunctionTimer(); -#if CHIP_CONFIG_ENABLE_ICD_SERVER == 1 +#if CHIP_CONFIG_ENABLE_ICD_SERVER StopStatusLEDTimer(); #endif if (sIsFactoryResetTriggered) @@ -652,7 +662,7 @@ void BaseApplication::OnIdentifyStart(Identify * identify) { ChipLogProgress(Zcl, "onIdentifyStart"); -#if CHIP_CONFIG_ENABLE_ICD_SERVER == 1 +#if CHIP_CONFIG_ENABLE_ICD_SERVER StartStatusLEDTimer(); #endif } @@ -661,7 +671,7 @@ void BaseApplication::OnIdentifyStop(Identify * identify) { ChipLogProgress(Zcl, "onIdentifyStop"); -#if CHIP_CONFIG_ENABLE_ICD_SERVER == 1 +#if CHIP_CONFIG_ENABLE_ICD_SERVER StopStatusLEDTimer(); #endif } @@ -671,7 +681,7 @@ void BaseApplication::OnTriggerIdentifyEffectCompleted(chip::System::Layer * sys ChipLogProgress(Zcl, "Trigger Identify Complete"); sIdentifyEffect = Clusters::Identify::EffectIdentifierEnum::kStopEffect; -#if CHIP_CONFIG_ENABLE_ICD_SERVER == 1 +#if CHIP_CONFIG_ENABLE_ICD_SERVER StopStatusLEDTimer(); #endif } @@ -685,7 +695,7 @@ void BaseApplication::OnTriggerIdentifyEffect(Identify * identify) ChipLogDetail(AppServer, "Identify Effect Variant unsupported. Using default"); } -#if CHIP_CONFIG_ENABLE_ICD_SERVER == 1 +#if CHIP_CONFIG_ENABLE_ICD_SERVER StartStatusLEDTimer(); #endif diff --git a/examples/platform/silabs/MatterConfig.cpp b/examples/platform/silabs/MatterConfig.cpp index 20f73ab6811e58..4440fcf58444ca 100644 --- a/examples/platform/silabs/MatterConfig.cpp +++ b/examples/platform/silabs/MatterConfig.cpp @@ -33,7 +33,7 @@ #endif #ifdef ENABLE_CHIP_SHELL -#include "matter_shell.h" +#include "MatterShell.h" #endif #ifdef HEAP_MONITORING diff --git a/examples/platform/silabs/matter_shell.cpp b/examples/platform/silabs/MatterShell.cpp similarity index 99% rename from examples/platform/silabs/matter_shell.cpp rename to examples/platform/silabs/MatterShell.cpp index 3e70764a08a1d5..6088eeb2ca9404 100644 --- a/examples/platform/silabs/matter_shell.cpp +++ b/examples/platform/silabs/MatterShell.cpp @@ -15,7 +15,7 @@ * limitations under the License. */ -#include "matter_shell.h" +#include "MatterShell.h" #include "sl_component_catalog.h" #include #include diff --git a/examples/platform/silabs/matter_shell.h b/examples/platform/silabs/MatterShell.h similarity index 100% rename from examples/platform/silabs/matter_shell.h rename to examples/platform/silabs/MatterShell.h diff --git a/examples/platform/silabs/SiWx917/BUILD.gn b/examples/platform/silabs/SiWx917/BUILD.gn index cf7b7aedbf1cfa..6756cc28c726ce 100644 --- a/examples/platform/silabs/SiWx917/BUILD.gn +++ b/examples/platform/silabs/SiWx917/BUILD.gn @@ -91,22 +91,20 @@ source_set("test-event-trigger") { ] } -source_set("siwx917-matter-shell") { - if (chip_build_libshell) { - defines = [ "ENABLE_CHIP_SHELL" ] +source_set("matter-shell") { + defines = [ "ENABLE_CHIP_SHELL" ] - sources = [ "${silabs_common_plat_dir}/matter_shell.cpp" ] - include_dirs = [ - ".", - "${silabs_common_plat_dir}", - ] + sources = [ "${silabs_common_plat_dir}/MatterShell.cpp" ] + include_dirs = [ + ".", + "${silabs_common_plat_dir}", + ] - public_deps = [ - "${chip_root}/examples/shell/shell_common:shell_common", - "${chip_root}/src/lib/shell:shell", - "${chip_root}/src/lib/shell:shell_core", - ] - } + public_deps = [ + "${chip_root}/examples/shell/shell_common:shell_common", + "${chip_root}/src/lib/shell:shell", + "${chip_root}/src/lib/shell:shell_core", + ] } config("siwx917-common-config") { @@ -226,7 +224,11 @@ source_set("siwx917-common") { } if (chip_build_libshell) { - deps += [ ":siwx917-matter-shell" ] + deps += [ ":matter-shell" ] + + if (chip_enable_icd_server) { + deps += [ "${silabs_common_plat_dir}/shell:icd" ] + } } # DIC diff --git a/examples/platform/silabs/efr32/BUILD.gn b/examples/platform/silabs/efr32/BUILD.gn index f5c79a22524812..2d417c22c1a641 100644 --- a/examples/platform/silabs/efr32/BUILD.gn +++ b/examples/platform/silabs/efr32/BUILD.gn @@ -123,22 +123,20 @@ source_set("openthread_core_config_efr32_chip_examples") { } } -source_set("efr-matter-shell") { - if (chip_build_libshell) { - defines = [ "ENABLE_CHIP_SHELL" ] +source_set("matter-shell") { + defines = [ "ENABLE_CHIP_SHELL" ] - sources = [ "${silabs_common_plat_dir}/matter_shell.cpp" ] - include_dirs = [ - ".", - "${silabs_common_plat_dir}", - ] + sources = [ "${silabs_common_plat_dir}/MatterShell.cpp" ] + include_dirs = [ + ".", + "${silabs_common_plat_dir}", + ] - public_deps = [ - "${chip_root}/examples/shell/shell_common:shell_common", - "${chip_root}/src/lib/shell:shell", - "${chip_root}/src/lib/shell:shell_core", - ] - } + public_deps = [ + "${chip_root}/examples/shell/shell_common:shell_common", + "${chip_root}/src/lib/shell:shell", + "${chip_root}/src/lib/shell:shell_core", + ] } config("efr32-common-config") { @@ -294,7 +292,11 @@ source_set("efr32-common") { } if (chip_build_libshell) { - deps += [ ":efr-matter-shell" ] + deps += [ ":matter-shell" ] + + if (chip_enable_icd_server) { + deps += [ "${silabs_common_plat_dir}/shell:icd" ] + } } public_deps += [ diff --git a/examples/platform/silabs/shell/BUILD.gn b/examples/platform/silabs/shell/BUILD.gn new file mode 100644 index 00000000000000..74613aeac91031 --- /dev/null +++ b/examples/platform/silabs/shell/BUILD.gn @@ -0,0 +1,39 @@ +# Copyright (c) 2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build_overrides/chip.gni") +import("//build_overrides/efr32_sdk.gni") +import("${chip_root}/src/app/icd/icd.gni") +import("${chip_root}/third_party/silabs/silabs_board.gni") + +# This is necessary since the BUILD.gn for both platforms are still split +shell_dependency_path = "${chip_root}/examples/platform/silabs/efr32" +if (use_SiWx917) { + shell_dependency_path = "${chip_root}/examples/platform/silabs/SiWx917" +} + +config("shell-config") { + include_dirs = [ "." ] +} + +source_set("icd") { + sources = [ + "ICDShellCommands.cpp", + "ICDShellCommands.h", + ] + + public_configs = [ ":shell-config" ] + + deps = [ "${shell_dependency_path}:matter-shell" ] +} diff --git a/examples/platform/silabs/shell/ICDShellCommands.cpp b/examples/platform/silabs/shell/ICDShellCommands.cpp new file mode 100644 index 00000000000000..4bd3910634b6a1 --- /dev/null +++ b/examples/platform/silabs/shell/ICDShellCommands.cpp @@ -0,0 +1,119 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include +#include +#include +#include +#include + +using namespace chip; +using namespace chip::app; +using Shell::Engine; +using Shell::shell_command_t; +using Shell::streamer_get; +using Shell::streamer_printf; + +namespace { + +Engine sShellICDSubCommands; + +#if defined(CHIP_CONFIG_ENABLE_ICD_DSLS) && CHIP_CONFIG_ENABLE_ICD_DSLS +Engine sShellDynamicSitLitSubCommands; +#endif // defined(CHIP_CONFIG_ENABLE_ICD_DSLS) && CHIP_CONFIG_ENABLE_ICD_DSLS + +CHIP_ERROR HelpHandler(int argc, char ** argv) +{ + sShellICDSubCommands.ForEachCommand(Shell::PrintCommandHelp, nullptr); + return CHIP_NO_ERROR; +} + +CHIP_ERROR CommandHandler(int argc, char ** argv) +{ + if (argc == 0) + { + return HelpHandler(argc, argv); + } + + return sShellICDSubCommands.ExecCommand(argc, argv); +} + +#if defined(CHIP_CONFIG_ENABLE_ICD_DSLS) && CHIP_CONFIG_ENABLE_ICD_DSLS +namespace DynamicSitLit { + +CHIP_ERROR HelpHandler(int argc, char ** argv) +{ + sShellDynamicSitLitSubCommands.ForEachCommand(Shell::PrintCommandHelp, nullptr); + return CHIP_NO_ERROR; +} + +CHIP_ERROR CommandHandler(int argc, char ** argv) +{ + if (argc == 0) + { + return DynamicSitLit::HelpHandler(argc, argv); + } + + return sShellDynamicSitLitSubCommands.ExecCommand(argc, argv); +} + +CHIP_ERROR SetSitModeReq(int argc, char ** argv) +{ + return chip::DeviceLayer::PlatformMgr().ScheduleWork( + [](intptr_t arg) { chip::app::ICDNotifier::GetInstance().NotifySITModeRequestNotification(); }, 0); +} + +CHIP_ERROR RemoveSitModeReq(int argc, char ** argv) +{ + return chip::DeviceLayer::PlatformMgr().ScheduleWork( + [](intptr_t arg) { chip::app::ICDNotifier::GetInstance().NotifySITModeRequestWithdrawal(); }, 0); +} + +} // namespace DynamicSitLit +#endif // defined(CHIP_CONFIG_ENABLE_ICD_DSLS) && CHIP_CONFIG_ENABLE_ICD_DSLS + +} // namespace + +namespace ICDCommands { + +/** + * @brief configures ICD matter shell + */ +void RegisterCommands() +{ + static const shell_command_t sLitICDSubCommands[] = { +#if defined(CHIP_CONFIG_ENABLE_ICD_DSLS) && CHIP_CONFIG_ENABLE_ICD_DSLS + { DynamicSitLit::CommandHandler, "dsls", "Dynamic Sit/Lit commands. Usage: dsls " }, +#endif // defined(CHIP_CONFIG_ENABLE_ICD_DSLS) && CHIP_CONFIG_ENABLE_ICD_DSLS + { &HelpHandler, "help", "Usage: icd " } + }; + sShellICDSubCommands.RegisterCommands(sLitICDSubCommands, ArraySize(sLitICDSubCommands)); + +#if defined(CHIP_CONFIG_ENABLE_ICD_DSLS) && CHIP_CONFIG_ENABLE_ICD_DSLS + static const shell_command_t sDynamicSitLitSubCommands[] = { + { &DynamicSitLit::SetSitModeReq, "add", "Add SIT mode requirement." }, + { &DynamicSitLit::RemoveSitModeReq, "remove", "Removes SIT mode requirement." }, + { &DynamicSitLit::HelpHandler, "help", "Usage : icd dsls ." } + }; + sShellDynamicSitLitSubCommands.RegisterCommands(sDynamicSitLitSubCommands, ArraySize(sDynamicSitLitSubCommands)); +#endif // defined(CHIP_CONFIG_ENABLE_ICD_DSLS) && CHIP_CONFIG_ENABLE_ICD_DSLS + + static const shell_command_t sICDCommand = { &CommandHandler, "icd", "ICD commands. Usage: icd " }; + Engine::Root().RegisterCommands(&sICDCommand, 1); +} + +} // namespace ICDCommands diff --git a/examples/lit-icd-app/silabs/include/ShellCommands.h b/examples/platform/silabs/shell/ICDShellCommands.h similarity index 82% rename from examples/lit-icd-app/silabs/include/ShellCommands.h rename to examples/platform/silabs/shell/ICDShellCommands.h index 8817c41bfbf3a6..9c276f0e0a2cc9 100644 --- a/examples/lit-icd-app/silabs/include/ShellCommands.h +++ b/examples/platform/silabs/shell/ICDShellCommands.h @@ -15,15 +15,10 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - #pragma once -#ifdef ENABLE_CHIP_SHELL - -namespace LitICDCommands { - -void RegisterLitICDCommands(); +namespace ICDCommands { -} // namespace LitICDCommands +void RegisterCommands(); -#endif // ENABLE_CHIP_SHELL +} // namespace ICDCommands diff --git a/examples/platform/silabs/uart.cpp b/examples/platform/silabs/uart.cpp index 390e151cb7fbbf..6ef768ac652e19 100644 --- a/examples/platform/silabs/uart.cpp +++ b/examples/platform/silabs/uart.cpp @@ -16,7 +16,9 @@ * limitations under the License. */ #include "AppConfig.h" -#include "matter_shell.h" +#ifdef ENABLE_CHIP_SHELL +#include "MatterShell.h" // nogncheck +#endif #include #include #include diff --git a/integrations/cloudbuild/smoke-test.yaml b/integrations/cloudbuild/smoke-test.yaml index 824b79d6ce1a22..02e73512c43928 100644 --- a/integrations/cloudbuild/smoke-test.yaml +++ b/integrations/cloudbuild/smoke-test.yaml @@ -1,5 +1,5 @@ steps: - - name: "ghcr.io/project-chip/chip-build-vscode:85" + - name: "ghcr.io/project-chip/chip-build-vscode:89" entrypoint: "bash" args: - "-c" @@ -7,7 +7,7 @@ steps: git config --global --add safe.directory "*" python scripts/checkout_submodules.py --shallow --recursive --platform esp32 nrfconnect silabs linux android id: Submodules - - name: "ghcr.io/project-chip/chip-build-vscode:85" + - name: "ghcr.io/project-chip/chip-build-vscode:89" # NOTE: silabs boostrap is NOT done with the rest as it requests a conflicting # jinja2 version (asks for 3.1.3 when constraints.txt asks for 3.0.3) env: @@ -24,7 +24,7 @@ steps: path: /pwenv timeout: 900s - - name: "ghcr.io/project-chip/chip-build-vscode:85" + - name: "ghcr.io/project-chip/chip-build-vscode:89" id: ESP32 env: - PW_ENVIRONMENT_ROOT=/pwenv @@ -45,7 +45,7 @@ steps: volumes: - name: pwenv path: /pwenv - - name: "ghcr.io/project-chip/chip-build-vscode:85" + - name: "ghcr.io/project-chip/chip-build-vscode:89" id: NRFConnect env: - PW_ENVIRONMENT_ROOT=/pwenv @@ -66,7 +66,7 @@ steps: - name: pwenv path: /pwenv - - name: "ghcr.io/project-chip/chip-build-vscode:85" + - name: "ghcr.io/project-chip/chip-build-vscode:89" id: EFR32 env: - PW_ENVIRONMENT_ROOT=/pwenv @@ -88,7 +88,7 @@ steps: - name: pwenv path: /pwenv - - name: "ghcr.io/project-chip/chip-build-vscode:85" + - name: "ghcr.io/project-chip/chip-build-vscode:89" id: Linux env: - PW_ENVIRONMENT_ROOT=/pwenv @@ -141,7 +141,7 @@ steps: - name: pwenv path: /pwenv - - name: "ghcr.io/project-chip/chip-build-vscode:85" + - name: "ghcr.io/project-chip/chip-build-vscode:89" id: Android env: - PW_ENVIRONMENT_ROOT=/pwenv diff --git a/src/lib/shell/MainLoopSilabs.cpp b/src/lib/shell/MainLoopSilabs.cpp index 8a8d60af2d6716..8613c48b552f6f 100644 --- a/src/lib/shell/MainLoopSilabs.cpp +++ b/src/lib/shell/MainLoopSilabs.cpp @@ -15,7 +15,7 @@ * limitations under the License. */ -#include "matter_shell.h" +#include "MatterShell.h" #include "streamer.h" #include #include diff --git a/src/test_driver/efr32/BUILD.gn b/src/test_driver/efr32/BUILD.gn index 1fc16ed47f4d52..51fe90751ae219 100644 --- a/src/test_driver/efr32/BUILD.gn +++ b/src/test_driver/efr32/BUILD.gn @@ -102,7 +102,7 @@ source_set("efr32_test_main") { deps += [ "${chip_root}/third_party/openthread:openthread", "${chip_root}/third_party/openthread:openthread-platform", - "${examples_plat_dir}:efr-matter-shell", + "${examples_plat_dir}:matter-shell", ] } From 4b83b049fd9e0a0e93e03a716a3506571f68f790 Mon Sep 17 00:00:00 2001 From: Anush Nadathur Date: Fri, 25 Oct 2024 11:44:33 -0700 Subject: [PATCH 119/149] [Darwin] VID and PID accessors to MTRDevice (#36239) * [Darwin] VID and PID accessors to MTRDevice - Exposes VID/PID on MTRDevice as API * apply restyle suggestions --------- Co-authored-by: Kiel Oleson --- src/darwin/Framework/CHIP/MTRDevice.h | 14 ++++++++++++++ src/darwin/Framework/CHIP/MTRDevice_Concrete.mm | 12 ++++++++++++ src/darwin/Framework/CHIP/MTRDevice_XPC.mm | 10 ++++++++++ 3 files changed, 36 insertions(+) diff --git a/src/darwin/Framework/CHIP/MTRDevice.h b/src/darwin/Framework/CHIP/MTRDevice.h index 5a8dcb8de08355..5b19eb3bf434e4 100644 --- a/src/darwin/Framework/CHIP/MTRDevice.h +++ b/src/darwin/Framework/CHIP/MTRDevice.h @@ -107,6 +107,20 @@ MTR_AVAILABLE(ios(16.1), macos(13.0), watchos(9.1), tvos(16.1)) */ @property (nonatomic, readonly, nullable, copy) NSNumber * estimatedSubscriptionLatency MTR_AVAILABLE(ios(17.6), macos(14.6), watchos(10.6), tvos(17.6)); +/** + * The Vendor Identifier associated with the device. + * + * A non-nil value if the vendor identifier has been determined from the device, nil if unknown. + */ +@property (nonatomic, readonly, nullable, copy) NSNumber * vendorID MTR_NEWLY_AVAILABLE; + +/** + * The Product Identifier associated with the device. + * + * A non-nil value if the product identifier has been determined from the device, nil if unknown. + */ +@property (nonatomic, readonly, nullable, copy) NSNumber * productID MTR_NEWLY_AVAILABLE; + /** * Set the delegate to receive asynchronous callbacks about the device. * diff --git a/src/darwin/Framework/CHIP/MTRDevice_Concrete.mm b/src/darwin/Framework/CHIP/MTRDevice_Concrete.mm index 2423e4e8769c45..f8319f2636351e 100644 --- a/src/darwin/Framework/CHIP/MTRDevice_Concrete.mm +++ b/src/darwin/Framework/CHIP/MTRDevice_Concrete.mm @@ -488,6 +488,18 @@ - (NSDictionary *)_internalProperties return properties; } +- (nullable NSNumber *)vendorID +{ + std::lock_guard lock(_descriptionLock); + return [_vid copy]; +} + +- (nullable NSNumber *)productID +{ + std::lock_guard lock(_descriptionLock); + return [_pid copy]; +} + - (void)_notifyDelegateOfPrivateInternalPropertiesChanges { os_unfair_lock_assert_owner(&self->_lock); diff --git a/src/darwin/Framework/CHIP/MTRDevice_XPC.mm b/src/darwin/Framework/CHIP/MTRDevice_XPC.mm index 7782509fb79bcd..cee041afbd52cf 100644 --- a/src/darwin/Framework/CHIP/MTRDevice_XPC.mm +++ b/src/darwin/Framework/CHIP/MTRDevice_XPC.mm @@ -131,6 +131,16 @@ - (NSString *)description _deviceController.uniqueIdentifier]; } +- (nullable NSNumber *)vendorID +{ + return [[self._internalState objectForKey:kMTRDeviceInternalPropertyKeyVendorID] copy]; +} + +- (nullable NSNumber *)productID +{ + return [[self._internalState objectForKey:kMTRDeviceInternalPropertyKeyProductID] copy]; +} + #pragma mark - Client Callbacks (MTRDeviceDelegate) // required methods for MTRDeviceDelegates From e2ffa2d4a9f31125a2ccd110f1c44547f7274c2a Mon Sep 17 00:00:00 2001 From: Vivien Nicolas Date: Fri, 25 Oct 2024 20:45:05 +0200 Subject: [PATCH 120/149] [darwin-framework-tool] Add an optional -use-mtr-device argument to read-by-id and write-by-id commands (#36243) * [darwin-framework-tool][use-mtr-device] Add an option to send command using an MTRDevice instead of a MTRBaseDevice * [darwin-framework-tool][use-mtr-device] Add an implementation for reading attributes via an MTRDevice * [darwin-framework-tool][use-mtr-device] Add an implementation for writing attributes via an MTRDevice --- .../commands/clusters/ClusterCommandBridge.h | 2 + .../commands/clusters/ModelCommandBridge.h | 4 ++ .../commands/clusters/ModelCommandBridge.mm | 14 ++++-- .../commands/clusters/ReportCommandBridge.h | 43 +++++++++++++++++- .../clusters/WriteAttributeCommandBridge.h | 44 ++++++++++++++++++- .../commands/common/CHIPCommandBridge.h | 4 ++ .../commands/common/CHIPCommandBridge.mm | 11 +++++ 7 files changed, 115 insertions(+), 7 deletions(-) diff --git a/examples/darwin-framework-tool/commands/clusters/ClusterCommandBridge.h b/examples/darwin-framework-tool/commands/clusters/ClusterCommandBridge.h index 50b9cfed5d912b..c94d666de5fa6f 100644 --- a/examples/darwin-framework-tool/commands/clusters/ClusterCommandBridge.h +++ b/examples/darwin-framework-tool/commands/clusters/ClusterCommandBridge.h @@ -45,6 +45,8 @@ class ClusterCommand : public ModelCommand { ~ClusterCommand() {} + using ModelCommand::SendCommand; + CHIP_ERROR SendCommand(MTRBaseDevice * _Nonnull device, chip::EndpointId endpointId) override { id commandFields; diff --git a/examples/darwin-framework-tool/commands/clusters/ModelCommandBridge.h b/examples/darwin-framework-tool/commands/clusters/ModelCommandBridge.h index 8e5bb8f9842210..6f29bf165dcce5 100644 --- a/examples/darwin-framework-tool/commands/clusters/ModelCommandBridge.h +++ b/examples/darwin-framework-tool/commands/clusters/ModelCommandBridge.h @@ -52,6 +52,10 @@ class ModelCommand : public CHIPCommandBridge } virtual CHIP_ERROR SendCommand(MTRBaseDevice * _Nonnull device, chip::EndpointId endPointId) = 0; + virtual CHIP_ERROR SendCommand(MTRDevice * _Nonnull device, chip::EndpointId endPointId) { return CHIP_ERROR_NOT_IMPLEMENTED; } + +protected: + chip::Optional mUseMTRDevice; private: chip::NodeId mNodeId; diff --git a/examples/darwin-framework-tool/commands/clusters/ModelCommandBridge.mm b/examples/darwin-framework-tool/commands/clusters/ModelCommandBridge.mm index 47a29f80c3a4e5..c430364f53b96d 100644 --- a/examples/darwin-framework-tool/commands/clusters/ModelCommandBridge.mm +++ b/examples/darwin-framework-tool/commands/clusters/ModelCommandBridge.mm @@ -26,10 +26,18 @@ CHIP_ERROR ModelCommand::RunCommand() { ChipLogProgress(chipTool, "Sending command to node 0x" ChipLogFormatX64, ChipLogValueX64(mNodeId)); - auto * device = BaseDeviceWithNodeId(mNodeId); - VerifyOrReturnError(device != nil, CHIP_ERROR_INCORRECT_STATE); - CHIP_ERROR err = SendCommand(device, mEndPointId); + CHIP_ERROR err = CHIP_NO_ERROR; + + if (mUseMTRDevice.ValueOr(false)) { + auto * device = DeviceWithNodeId(mNodeId); + VerifyOrReturnError(device != nil, CHIP_ERROR_INCORRECT_STATE); + err = SendCommand(device, mEndPointId); + } else { + auto * device = BaseDeviceWithNodeId(mNodeId); + VerifyOrReturnError(device != nil, CHIP_ERROR_INCORRECT_STATE); + err = SendCommand(device, mEndPointId); + } if (err != CHIP_NO_ERROR) { ChipLogError(chipTool, "Error: %s", chip::ErrorStr(err)); diff --git a/examples/darwin-framework-tool/commands/clusters/ReportCommandBridge.h b/examples/darwin-framework-tool/commands/clusters/ReportCommandBridge.h index 1a2612b7e3b13d..cd8125e3b12273 100644 --- a/examples/darwin-framework-tool/commands/clusters/ReportCommandBridge.h +++ b/examples/darwin-framework-tool/commands/clusters/ReportCommandBridge.h @@ -28,7 +28,7 @@ class ReadAttribute : public ModelCommand { AddArgument("cluster-id", 0, UINT32_MAX, &mClusterId); AddArgument("attribute-id", 0, UINT32_MAX, &mAttributeId); AddArgument("fabric-filtered", 0, 1, &mFabricFiltered); - ModelCommand::AddArguments(); + AddCommonByIdArguments(); } ReadAttribute(chip::ClusterId clusterId) @@ -37,7 +37,7 @@ class ReadAttribute : public ModelCommand { { AddArgument("attribute-id", 0, UINT32_MAX, &mAttributeId); AddArgument("fabric-filtered", 0, 1, &mFabricFiltered); - ModelCommand::AddArguments(); + AddCommonByIdArguments(); } ReadAttribute(const char * _Nonnull attributeName) @@ -83,7 +83,46 @@ class ReadAttribute : public ModelCommand { return CHIP_NO_ERROR; } + CHIP_ERROR SendCommand(MTRDevice * _Nonnull device, chip::EndpointId endpointId) override + { + MTRReadParams * params = [[MTRReadParams alloc] init]; + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + + __auto_type * endpoint = @(endpointId); + __auto_type * cluster = @(mClusterId); + __auto_type * attribute = @(mAttributeId); + __auto_type values = [device readAttributeWithEndpointID:endpoint + clusterID:cluster + attributeID:attribute + params:params]; + + NSError * error = nil; + if (nil == values) { + __auto_type * userInfo = @ { @"reason" : @"No value available." }; + error = [NSError errorWithDomain:@"Error" code:0 userInfo:userInfo]; + LogNSError("Error reading attribute", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(endpoint, cluster, attribute, error); + } else { + for (id item in values) { + NSLog(@"Response Item: %@", [item description]); + } + RemoteDataModelLogger::LogAttributeAsJSON(endpoint, cluster, attribute, values); + } + + SetCommandExitStatus(error); + return CHIP_NO_ERROR; + } + protected: + void AddCommonByIdArguments() + { + AddArgument("use-mtr-device", 0, 1, &mUseMTRDevice, + "Use MTRDevice instead of MTRBaseDevice to send this command. Default is false."); + ModelCommand::AddArguments(); + } + chip::Optional mFabricFiltered; private: diff --git a/examples/darwin-framework-tool/commands/clusters/WriteAttributeCommandBridge.h b/examples/darwin-framework-tool/commands/clusters/WriteAttributeCommandBridge.h index f274ea21aa654b..0a779740b9dc05 100644 --- a/examples/darwin-framework-tool/commands/clusters/WriteAttributeCommandBridge.h +++ b/examples/darwin-framework-tool/commands/clusters/WriteAttributeCommandBridge.h @@ -25,6 +25,8 @@ #import "MTRError_Utils.h" #import +constexpr uint32_t kDefaultExpectedValueInterval = 60000; + class WriteAttribute : public ModelCommand { public: WriteAttribute() @@ -33,7 +35,7 @@ class WriteAttribute : public ModelCommand { AddArgument("cluster-id", 0, UINT32_MAX, &mClusterId); AddArgument("attribute-id", 0, UINT32_MAX, &mAttributeId); AddArgument("attribute-value", &mAttributeValue); - AddArguments(); + AddCommonByIdArguments(); } WriteAttribute(chip::ClusterId clusterId) @@ -42,7 +44,7 @@ class WriteAttribute : public ModelCommand { { AddArgument("attribute-id", 0, UINT32_MAX, &mAttributeId); AddArgument("attribute-value", &mAttributeValue); - AddArguments(); + AddCommonByIdArguments(); } ~WriteAttribute() {} @@ -54,6 +56,13 @@ class WriteAttribute : public ModelCommand { return WriteAttribute::SendCommand(device, endpointId, mClusterId, mAttributeId, value); } + CHIP_ERROR SendCommand(MTRDevice * _Nonnull device, chip::EndpointId endpointId) override + { + id value; + ReturnErrorOnFailure(GetValue(&value)); + return WriteAttribute::SendCommand(device, endpointId, mClusterId, mAttributeId, value); + } + CHIP_ERROR SendCommand(MTRBaseDevice * _Nonnull device, chip::EndpointId endpointId, chip::ClusterId clusterId, chip::AttributeId attributeId, id _Nonnull value) { @@ -87,6 +96,28 @@ class WriteAttribute : public ModelCommand { return CHIP_NO_ERROR; } + CHIP_ERROR SendCommand(MTRDevice * _Nonnull device, chip::EndpointId endpointId, chip::ClusterId clusterId, + chip::AttributeId attributeId, id _Nonnull value) + { + __auto_type * endpoint = @(endpointId); + __auto_type * cluster = @(mClusterId); + __auto_type * attribute = @(mAttributeId); + __auto_type * expectedValueInterval = @(mExpectedValueInterval.ValueOr(kDefaultExpectedValueInterval)); + __auto_type * timedWriteTimeout = mTimedInteractionTimeoutMs.HasValue() + ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] + : nil; + + [device writeAttributeWithEndpointID:endpoint + clusterID:cluster + attributeID:attribute + value:value + expectedValueInterval:expectedValueInterval + timedWriteTimeout:timedWriteTimeout]; + + SetCommandExitStatus(CHIP_NO_ERROR); + return CHIP_NO_ERROR; + } + protected: WriteAttribute(const char * _Nonnull attributeName) : ModelCommand("write") @@ -95,6 +126,14 @@ class WriteAttribute : public ModelCommand { // Subclasses are responsible for calling AddArguments. } + void AddCommonByIdArguments() + { + AddArgument("use-mtr-device", 0, 1, &mUseMTRDevice, + "Use MTRDevice instead of MTRBaseDevice to send this command. Default is false."); + AddArgument("expectedValueInterval", 0, UINT32_MAX, &mExpectedValueInterval, "When the write is issued using an MTRDevice (via –use-mtr-device), specify the maximum interval (in milliseconds) during which reads of the attribute will return the expected value. The default is 60000 milliseconds (60 seconds)."); + AddArguments(); + } + void AddArguments() { AddArgument("timedInteractionTimeoutMs", 0, UINT16_MAX, &mTimedInteractionTimeoutMs, @@ -104,6 +143,7 @@ class WriteAttribute : public ModelCommand { } chip::Optional mTimedInteractionTimeoutMs; + chip::Optional mExpectedValueInterval; chip::Optional mDataVersion; private: diff --git a/examples/darwin-framework-tool/commands/common/CHIPCommandBridge.h b/examples/darwin-framework-tool/commands/common/CHIPCommandBridge.h index f58251bff48dd0..3466972f1f6f25 100644 --- a/examples/darwin-framework-tool/commands/common/CHIPCommandBridge.h +++ b/examples/darwin-framework-tool/commands/common/CHIPCommandBridge.h @@ -97,6 +97,10 @@ class CHIPCommandBridge : public Command { // Will utilize an existing PASE connection if the device is being commissioned. MTRBaseDevice * BaseDeviceWithNodeId(chip::NodeId nodeId); + // Returns the MTRDevice for the specified node ID. + // Will utilize an existing PASE connection if the device is being commissioned. + MTRDevice * DeviceWithNodeId(chip::NodeId nodeId); + // Will log the given string and given error (as progress if success, error // if failure). void LogNSError(const char * logString, NSError * error); diff --git a/examples/darwin-framework-tool/commands/common/CHIPCommandBridge.mm b/examples/darwin-framework-tool/commands/common/CHIPCommandBridge.mm index 724a9a20c3a571..85ce8d8935bec0 100644 --- a/examples/darwin-framework-tool/commands/common/CHIPCommandBridge.mm +++ b/examples/darwin-framework-tool/commands/common/CHIPCommandBridge.mm @@ -285,6 +285,17 @@ ?: [MTRBaseDevice deviceWithNodeID:@(nodeId) controller:controller]; } +MTRDevice * CHIPCommandBridge::DeviceWithNodeId(chip::NodeId nodeId) +{ + __auto_type * controller = CurrentCommissioner(); + VerifyOrReturnValue(nil != controller, nil); + + __auto_type * device = [MTRDevice deviceWithNodeID:@(nodeId) controller:controller]; + VerifyOrReturnValue(nil != device, nil); + + return device; +} + void CHIPCommandBridge::StopCommissioners() { for (auto & pair : mControllers) { From 62d5be328fde7d5e7686717e1f223a1f7cabbd17 Mon Sep 17 00:00:00 2001 From: Raul Marquez <130402456+raul-marquez-csa@users.noreply.github.com> Date: Fri, 25 Oct 2024 13:52:38 -0700 Subject: [PATCH 121/149] Removes yaml script (#36210) --- .../suites/certification/Test_TC_ACE_1_5.yaml | 399 ------------------ 1 file changed, 399 deletions(-) delete mode 100644 src/app/tests/suites/certification/Test_TC_ACE_1_5.yaml diff --git a/src/app/tests/suites/certification/Test_TC_ACE_1_5.yaml b/src/app/tests/suites/certification/Test_TC_ACE_1_5.yaml deleted file mode 100644 index 34faee27709d22..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_ACE_1_5.yaml +++ /dev/null @@ -1,399 +0,0 @@ -# Copyright (c) 2021 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -name: 42.1.5. [TC-ACE-1.5] Multi-fabric - -PICS: - - MCORE.ROLE.COMMISSIONEE - - APPDEVICE.S - -config: - nodeId: 0x12344321 - cluster: "Access Control" - endpoint: 0 - payload: - type: char_string - defaultValue: "MT:-24J0AFN00KA0648G00" - discriminator: - type: int16u - defaultValue: 3840 - waitAfterCommissioning: - type: int16u - defaultValue: 5000 - PakeVerifier: - type: octet_string - defaultValue: "hex:b96170aae803346884724fe9a3b287c30330c2a660375d17bb205a8cf1aecb350457f8ab79ee253ab6a8e46bb09e543ae422736de501e3db37d441fe344920d09548e4c18240630c4ff4913c53513839b7c07fcc0627a1b8573a149fcd1fa466cf" - -tests: - - label: "Step 1: TH1 commissions DUT using admin node ID N1" - cluster: "DelayCommands" - command: "WaitForCommissionee" - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: "TH1 reads the fabric index" - cluster: "Operational Credentials" - command: "readAttribute" - attribute: "CurrentFabricIndex" - response: - saveAs: th1FabricIndex - - - label: - "Step 2 & 3: TH1 puts DUT into commissioning mode, TH2 commissions DUT - using admin node ID N2" - verification: | - ./chip-tool pairing open-commissioning-window 1 1 400 2000 3841 - - On TH1(chip-tool) note the manual pairing code for commissioning the TH2 - - [1684416077.831754][118314:118316] CHIP:CTL: Successfully opened pairing window on the device - [1684416077.831763][118314:118316] CHIP:CTL: Manual pairing code: [36283142515] - [1684416077.831771][118314:118316] CHIP:CTL: SetupQRCode: [MT:-24J0IRV010UJE7ZH10] - [1684416077.831791][118314:118316] CHIP:DMG: ICR moving to [AwaitingDe] - - ./chip-tool pairing code 2 36283142515 --commissioner-name beta - - On TH2 (chip-tool) verify the commissioning completed with success - - [1684416247.482777][118352:118354] CHIP:CTL: Successfully finished commissioning step 'Cleanup' - [1684416247.482789][118352:118354] CHIP:TOO: Device commissioning completed with success - [1684416247.482823][118352:118354] CHIP:DMG: ICR moving to [AwaitingDe] - cluster: "LogCommands" - command: "UserPrompt" - PICS: PICS_SKIP_SAMPLE_APP - arguments: - values: - - name: "message" - value: "Enter 'y' after success" - - name: "expectedValue" - value: "y" - - - label: "Step 2: TH1 opens the commissioning window on the DUT" - cluster: "Administrator Commissioning" - command: "OpenCommissioningWindow" - timedInteractionTimeoutMs: 10000 - PICS: PICS_SDK_CI_ONLY - arguments: - values: - - name: "CommissioningTimeout" - value: 180 - - name: "PAKEPasscodeVerifier" - value: PakeVerifier - - name: "Discriminator" - value: discriminator - - name: "Iterations" - value: 1000 - - name: "Salt" - value: "SPAKE2P Key Salt" - - - label: "Waiting after opening commissioning window" - cluster: "DelayCommands" - command: "WaitForMs" - PICS: PICS_SDK_CI_ONLY - arguments: - values: - - name: "ms" - value: waitAfterCommissioning - - - label: "Step 3: TH2 commissions DUT using admin node ID N2" - identity: "beta" - cluster: "CommissionerCommands" - command: "PairWithCode" - PICS: PICS_SDK_CI_ONLY - arguments: - values: - - name: "nodeId" - value: nodeId - - name: "payload" - value: payload - - - label: "Wait for the commissioned device to be retrieved for TH2" - identity: beta - cluster: "DelayCommands" - command: "WaitForCommissionee" - PICS: PICS_SDK_CI_ONLY - arguments: - values: - - name: "nodeId" - value: nodeId - - - label: - "Step 4: TH2 reads its fabric index from the Operational Credentials - cluster CurrentFabricIndex attribute" - identity: "beta" - PICS: PICS_SDK_CI_ONLY - cluster: "Operational Credentials" - command: "readAttribute" - attribute: "CurrentFabricIndex" - response: - saveAs: th2FabricIndex - - #Issue https://github.com/CHIP-Specifications/chip-certification-tool/issues/768 - - label: "Step 4: TH2 reads the fabric index" - verification: | - ./chip-tool operationalcredentials read current-fabric-index 2 0 --commissioner-name beta - - On TH2 (chip-tool) note the CurrentFabricIndex for the further use - - [1684416368.885484][118383:118385] CHIP:TOO: Endpoint: 0 Cluster: 0x0000_003E Attribute 0x0000_0005 DataVersion: 3654336520 - [1684416368.885511][118383:118385] CHIP:TOO: CurrentFabricIndex: 2 - [1684416368.885577][118383:118385] CHIP:EM: <<< [E:65212i S:18077 M:83303022 (Ack:184536262)] (S) Msg TX to 2:0000000000000002 [C33E] --- Type 0000:10 (SecureChannel:StandaloneAck) - cluster: "LogCommands" - command: "UserPrompt" - PICS: PICS_SKIP_SAMPLE_APP - arguments: - values: - - name: "message" - value: "Enter 'y' after success" - - name: "expectedValue" - value: "y" - - - label: "Read the commissioner node ID from the alpha fabric" - identity: "alpha" - cluster: "CommissionerCommands" - command: "GetCommissionerNodeId" - response: - values: - - name: "nodeId" - saveAs: commissionerNodeIdAlpha - - - label: - "Step 5: TH1 writes DUT Endpoint 0 AccessControl cluster ACL - attribute,value is list of AccessControlEntryStruct containing 2 - elements 1.Struct : a)Fabric Index: 1 b)Privilege field: Administer - (5) c)AuthMode field: CASE (2) d)Subjects field: [N1] e)Targets - field:[{Cluster: AccessControl (0x001f), Endpoint: 0}] 2.struct : - a)Fabric Index: 1 b)Privilege field: View (1) c)AuthMode field: CASE - (2) d)Subjects field: null e)Targets field: [{Cluster: Descriptor - (0x001d), Endpoint: 0}]" - command: "writeAttribute" - attribute: "ACL" - arguments: - value: [ - { - FabricIndex: th1FabricIndex, - Privilege: 5, # administer - AuthMode: 2, # case - Subjects: [commissionerNodeIdAlpha], - Targets: - [{ Cluster: 0x001f, Endpoint: 0, DeviceType: null }], - }, - { - FabricIndex: th1FabricIndex, - Privilege: 1, # view - AuthMode: 2, # case - Subjects: null, - Targets: - [{ Cluster: 0x001d, Endpoint: 0, DeviceType: null }], - }, - ] - - - label: "Read the commissioner node ID from the beta fabric" - PICS: PICS_SDK_CI_ONLY - identity: "beta" - cluster: "CommissionerCommands" - command: "GetCommissionerNodeId" - response: - values: - - name: "nodeId" - saveAs: commissionerNodeIdBeta - - - label: - "Step 6: TH2 writes DUT Endpoint 0 AccessControl cluster ACL - attribute,value is list of AccessControlEntryStruct containing 2 - elements 1.Struct : a)Fabric Index: th2FabricIndex b)Privilege field: - Administer (5) c)AuthMode field: CASE (2) d)Subjects field: [N2] - e)Targets field: [{Cluster: AccessControl (0x001f), Endpoint: 0}]" - identity: beta - PICS: PICS_SDK_CI_ONLY - command: "writeAttribute" - attribute: "ACL" - arguments: - value: [ - { - FabricIndex: th2FabricIndex, - Privilege: 5, # administer - AuthMode: 2, # case - Subjects: [commissionerNodeIdBeta], - Targets: - [{ Cluster: 0x001f, Endpoint: 0, DeviceType: null }], - }, - { - FabricIndex: th2FabricIndex, - Privilege: 1, # view - AuthMode: 2, # case - Subjects: null, - Targets: - [{ Cluster: 0x0028, Endpoint: 0, DeviceType: null }], - }, - ] - - #Issue https://github.com/CHIP-Specifications/chip-certification-tool/issues/768 - - label: "Step 6: TH2 writes ACL giving view privilge for basic cluster" - verification: | - ./chip-tool accesscontrol write acl '[{"fabricIndex": 2, "privilege": 5, "authMode": 2, "subjects": [223344], "targets": [{ "cluster": 31, "endpoint": 0, "deviceType": null }]}, {"fabricIndex": 2, "privilege": 1, "authMode": 2, "subjects": null, "targets": [{ "cluster": 40, "endpoint": 0, "deviceType": null }]}]' 2 0 --commissioner-name beta - - On TH2 (chip-tool) verify the success response for the write function - - [1684416510.660175][118418:118420] CHIP:DMG: StatusIB = - [1684416510.660184][118418:118420] CHIP:DMG: { - [1684416510.660192][118418:118420] CHIP:DMG: status = 0x00 (SUCCESS), - [1684416510.660201][118418:118420] CHIP:DMG: }, - [1684416510.660211][118418:118420] CHIP:DMG: - cluster: "LogCommands" - command: "UserPrompt" - PICS: PICS_SKIP_SAMPLE_APP - arguments: - values: - - name: "message" - value: "Enter 'y' after success" - - name: "expectedValue" - value: "y" - - - label: - "Step 7: TH1 reads DUT Endpoint 0 Descriptor cluster DeviceTypeList - attribute" - command: "readAttribute" - cluster: "Descriptor" - attribute: "DeviceTypeList" - - - label: - "Step 8: TH1 reads DUT Endpoint 0 Basic Information cluster VendorID - attribute" - command: "readAttribute" - cluster: "Basic Information" - attribute: "VendorID" - response: - error: UNSUPPORTED_ACCESS - - - label: - "Step 9: TH2 reads DUT Endpoint 0 Descriptor cluster DeviceTypeList - attribute" - identity: "beta" - PICS: PICS_SDK_CI_ONLY - command: "readAttribute" - cluster: "Descriptor" - attribute: "DeviceTypeList" - response: - error: UNSUPPORTED_ACCESS - - #Issue https://github.com/CHIP-Specifications/chip-certification-tool/issues/768 - - label: "Step 9: TH2 reads descriptor cluster - expect UNSUPPORTED_ACCESS" - verification: | - ./chip-tool descriptor read device-type-list 2 0 --commissioner-name beta - - On TH2(chip-tool) verify the UNSUPPORTED_ACCESS (0x7e) response - - [1684416700.274460][118482:118484] CHIP:DMG: StatusIB = - [1684416700.274467][118482:118484] CHIP:DMG: { - [1684416700.274475][118482:118484] CHIP:DMG: status = 0x7e (UNSUPPORTED_ACCESS), - [1684416700.274482][118482:118484] CHIP:DMG: }, - cluster: "LogCommands" - command: "UserPrompt" - PICS: PICS_SKIP_SAMPLE_APP - arguments: - values: - - name: "message" - value: "Enter 'y' after success" - - name: "expectedValue" - value: "y" - - - label: - "Step 10: TH2 reads DUT Endpoint 0 Basic Information cluster VendorID - attribute" - identity: "beta" - PICS: PICS_SDK_CI_ONLY - command: "readAttribute" - cluster: "Basic Information" - attribute: "VendorID" - - #Issue https://github.com/CHIP-Specifications/chip-certification-tool/issues/768 - - label: - "Step 10: TH2 reads DUT Endpoint 0 Basic Information cluster VendorID - attribute - expect SUCCESS" - verification: | - ./chip-tool basicinformation read vendor-id 2 0 --commissioner-name beta - - On TH2(chip-tool) verify the success with the Vendor-id - - [1684416789.682243][118505:118507] CHIP:TOO: Endpoint: 0 Cluster: 0x0000_0028 Attribute 0x0000_0002 DataVersion: 2033462723 - [1684416789.682271][118505:118507] CHIP:TOO: VendorID: 65521 - [1684416789.682327][118505:118507] CHIP:EM: <<< [E:11340i S:29188 M:208193949 (Ack:232576417)] (S) Msg TX to 2:0000000000000002 [C33E] --- Type 0000:10 (SecureChannel:StandaloneAck) - cluster: "LogCommands" - command: "UserPrompt" - PICS: PICS_SKIP_SAMPLE_APP - arguments: - values: - - name: "message" - value: "Enter 'y' after success" - - name: "expectedValue" - value: "y" - - - label: - "Step 11: TH1 resets the ACLs to the default value bywriting DUT - Endpoint 0 AccessControl cluster ACL attribute,value is list of - AccessControlEntryStruct containing 1 elements 1.Struct : a)Fabric - Index: 1 b)Privilege field: Administer (5) c)AuthMode field: CASE (2) - d)Subjects field: [N1] e)Targets field: null" - command: "writeAttribute" - attribute: "ACL" - arguments: - value: [ - { - FabricIndex: 1, - Privilege: 5, # administer - AuthMode: 2, # case - Subjects: [commissionerNodeIdAlpha], - Targets: null, - }, - ] - - - label: - "Step 12: TH1 removes the TH2 fabric by sending the RemoveFabric - command to the DUT with the FabricIndex set to th2FabricIndex" - cluster: "Operational Credentials" - PICS: PICS_SDK_CI_ONLY - command: "RemoveFabric" - arguments: - values: - - name: "FabricIndex" - value: th2FabricIndex - - #Issue https://github.com/CHIP-Specifications/chip-certification-tool/issues/768 - - label: - "Step 12: TH1 removes the TH2 fabric by sending the RemoveFabric - commandto the DUT with the FabricIndex set to th2FabricIndex" - verification: | - ./chip-tool operationalcredentials remove-fabric 2 1 0 - - On TH1(chip-tool) verify the success with the nocresponse with statuscode is success(0) - - [1684416866.004187][118527:118529] CHIP:DMG: Received Command Response Data, Endpoint=0 Cluster=0x0000_003E Command=0x0000_0008 - [1684416866.004214][118527:118529] CHIP:TOO: Endpoint: 0 Cluster: 0x0000_003E Command 0x0000_0008 - [1684416866.004236][118527:118529] CHIP:TOO: NOCResponse: { - [1684416866.004250][118527:118529] CHIP:TOO: statusCode: 0 - [1684416866.004255][118527:118529] CHIP:TOO: fabricIndex: 2 - [1684416866.004259][118527:118529] CHIP:TOO: } - [1684416866.004270][118527:118529] CHIP:DMG: ICR moving to [AwaitingDe] - cluster: "LogCommands" - command: "UserPrompt" - PICS: PICS_SKIP_SAMPLE_APP - arguments: - values: - - name: "message" - value: "Enter 'y' after success" - - name: "expectedValue" - value: "y" From dc52d9d321646f2ca5f2d4fea873bb921cbdcdec Mon Sep 17 00:00:00 2001 From: Raul Marquez <130402456+raul-marquez-csa@users.noreply.github.com> Date: Fri, 25 Oct 2024 13:53:19 -0700 Subject: [PATCH 122/149] TC-CNET-4.4 - Removes yaml script (#36209) * Removes yaml script * Fix restyle * Fix restyle --- .../certification/Test_TC_CNET_4_4.yaml | 147 ------------------ src/app/tests/suites/manualTests.json | 1 - 2 files changed, 148 deletions(-) delete mode 100644 src/app/tests/suites/certification/Test_TC_CNET_4_4.yaml diff --git a/src/app/tests/suites/certification/Test_TC_CNET_4_4.yaml b/src/app/tests/suites/certification/Test_TC_CNET_4_4.yaml deleted file mode 100644 index f020b75bee18dd..00000000000000 --- a/src/app/tests/suites/certification/Test_TC_CNET_4_4.yaml +++ /dev/null @@ -1,147 +0,0 @@ -# Copyright (c) 2023 Project CHIP Authors -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License atour sweet -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -name: - 12.4.4. [TC-CNET-4.4] [WiFi] Verification for ScanNetworks command - [DUT-Server] - -PICS: - - CNET.S.F00 - -config: - nodeId: 0x12344321 - cluster: "Network Commissioning" - #PIXIT.CNET.ENDPOINT_WIFI - endpoint: 0 - PIXIT.CNET.WIFI_1ST_ACCESSPOINT_SSID: - type: octet_string - defaultValue: "hex:47524C50726976617465" - -tests: - - label: "Precondition: TH reads FeatureMap attribute from the DUT" - command: "readAttribute" - attribute: "FeatureMap" - response: - value: 1 - constraints: - type: bitmap32 - - - label: - "Step 1a: TH sends ScanNetworks command to the DUT with the SSID field - set to 'null' and Breadcrumb field set to 1" - PICS: CNET.S.C00.Rsp && CNET.S.C01.Tx - command: "ScanNetworks" - arguments: - values: - - name: "SSID" - value: null - - name: "Breadcrumb" - value: 1 - response: - values: - - name: "NetworkingStatus" - constraints: - anyOf: [0, 1, 5, 6, 12] - - name: "DebugText" - constraints: - maxLength: 512 - - name: "WiFiScanResults" - constraints: - type: list - - - label: - "Step 1a: Verify each element in the WiFiScanResults list will have - the following fields:" - verification: | - Via the TH (chip-tool), verify: - -the Security value is in the type of map8 with length range 0 to 254. - -the SSID value is in the ype of octstr with length range 1 to 32. - -the BSSID value is in the type of octstr with length range of 6. - -the Channel is in the type of uint16 with range 0 to 65,535. - -the WiFi Band is in the of type enum8 with a range of -128 to 127. - -the RSSI is in the of type int8 with a range of -120 to 0. - cluster: "LogCommands" - command: "UserPrompt" - PICS: PICS_USER_PROMPT && CNET.S.C00.Rsp && CNET.S.C01.Tx - arguments: - values: - - name: "message" - value: "Please enter 'y' for success" - - name: "expectedValue" - value: "y" - - - label: - "Step 1b: TH reads Breadcrumb attribute from the General Commissioning - Cluster" - cluster: "General Commissioning" - command: "readAttribute" - attribute: "Breadcrumb" - response: - value: 1 - constraints: - type: int64u - - - label: - "Step 2a: TH sends ScanNetworks Command to the DUT with SSID field set - to PIXIT.CNET.WIFI_1ST_ACCESSPOINT_SSID and Breadcrumb field set to 2" - PICS: CNET.S.C00.Rsp && CNET.S.C01.Tx - command: "ScanNetworks" - arguments: - values: - - name: "SSID" - value: PIXIT.CNET.WIFI_1ST_ACCESSPOINT_SSID - - name: "Breadcrumb" - value: 2 - response: - values: - - name: "NetworkingStatus" - value: 0 - - name: "DebugText" - constraints: - maxLength: 512 - - name: "WiFiScanResults" - constraints: - type: list - - - label: - "Step 2a: Verify each element in the WiFiScanResults list will have - the following fields: " - verification: | - Via the TH (chip-tool), verify: - -the Security value is in the type of map8 with length range 0 to 254. - -the SSID value is in the ype of octstr with length range 1 to 32. - -the BSSID value is in the type of octstr with length range of 6. - -the Channel is in the type of uint16 with range 0 to 65,535. - -the WiFi Band is in the of type enum8 with a range of -128 to 127. - -the RSSI is in the of type int8 with a range of -120 to 0. - cluster: "LogCommands" - command: "UserPrompt" - PICS: PICS_USER_PROMPT && CNET.S.C00.Rsp && CNET.S.C01.Tx - arguments: - values: - - name: "message" - value: "Please enter 'y' for success" - - name: "expectedValue" - value: "y" - - - label: - "Step 2b: TH reads Breadcrumb attribute from the General Commissioning - Cluster" - cluster: "General Commissioning" - command: "readAttribute" - attribute: "Breadcrumb" - response: - value: 2 - constraints: - type: int64u diff --git a/src/app/tests/suites/manualTests.json b/src/app/tests/suites/manualTests.json index 5f7aa99f9b2952..bee33964dfac50 100644 --- a/src/app/tests/suites/manualTests.json +++ b/src/app/tests/suites/manualTests.json @@ -89,7 +89,6 @@ "Test_TC_CNET_4_1", "Test_TC_CNET_4_2", "Test_TC_CNET_4_3", - "Test_TC_CNET_4_4", "Test_TC_CNET_4_5", "Test_TC_CNET_4_6", "Test_TC_CNET_4_9", From b7aa537ee7dd3e56a3821cbba51c91445a0d953b Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Fri, 25 Oct 2024 17:15:45 -0400 Subject: [PATCH 123/149] Add some machinery for structural validation in MTRDevice_XPC and MTRDevice_Concrete. (#36224) * Add some machinery for structural validation in MTRDevice_XPC and MTRDevice_Concrete. Validate things that get injected (that we got from the XPC transport) as well as various bits in MTRDevice_XPC. * Address review comments. * Update src/darwin/Framework/CHIP/MTRDeviceDataValidation.mm --------- Co-authored-by: Justin Wood --- src/darwin/Framework/CHIP/MTRBaseDevice.mm | 1 + .../Framework/CHIP/MTRBaseDevice_Internal.h | 2 +- .../Framework/CHIP/MTRDefines_Internal.h | 17 + src/darwin/Framework/CHIP/MTRDevice.mm | 1 - .../Framework/CHIP/MTRDeviceClusterData.h | 1 - .../Framework/CHIP/MTRDeviceDataValidation.h | 42 +++ .../Framework/CHIP/MTRDeviceDataValidation.mm | 216 ++++++++++++ .../CHIP/MTRDeviceDataValueDictionary.h | 26 -- .../Framework/CHIP/MTRDevice_Concrete.mm | 16 +- .../Framework/CHIP/MTRDevice_Internal.h | 8 - src/darwin/Framework/CHIP/MTRDevice_XPC.mm | 116 ++++++- .../Framework/CHIPTests/MTRDeviceTests.m | 319 +++++++++++++++++- .../CHIPTests/MTRPerControllerStorageTests.m | 2 +- .../TestHelpers/MTRTestDeclarations.h | 2 +- .../Matter.xcodeproj/project.pbxproj | 12 +- 15 files changed, 729 insertions(+), 52 deletions(-) create mode 100644 src/darwin/Framework/CHIP/MTRDeviceDataValidation.h create mode 100644 src/darwin/Framework/CHIP/MTRDeviceDataValidation.mm delete mode 100644 src/darwin/Framework/CHIP/MTRDeviceDataValueDictionary.h diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice.mm b/src/darwin/Framework/CHIP/MTRBaseDevice.mm index 2f75038eda97a2..3868060175bb1b 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice.mm +++ b/src/darwin/Framework/CHIP/MTRBaseDevice.mm @@ -23,6 +23,7 @@ #import "MTRCluster.h" #import "MTRClusterStateCacheContainer_Internal.h" #import "MTRCluster_Internal.h" +#import "MTRDeviceDataValidation.h" #import "MTRDevice_Internal.h" #import "MTRError_Internal.h" #import "MTREventTLVValueDecoder_Internal.h" diff --git a/src/darwin/Framework/CHIP/MTRBaseDevice_Internal.h b/src/darwin/Framework/CHIP/MTRBaseDevice_Internal.h index 075ee99da20990..fa766463e3e025 100644 --- a/src/darwin/Framework/CHIP/MTRBaseDevice_Internal.h +++ b/src/darwin/Framework/CHIP/MTRBaseDevice_Internal.h @@ -18,7 +18,7 @@ #import "MTRBaseDevice.h" #import -#import "MTRDeviceDataValueDictionary.h" +#import "MTRDefines_Internal.h" #include #include diff --git a/src/darwin/Framework/CHIP/MTRDefines_Internal.h b/src/darwin/Framework/CHIP/MTRDefines_Internal.h index 71a03aa09184c5..ba7d6be51d61f5 100644 --- a/src/darwin/Framework/CHIP/MTRDefines_Internal.h +++ b/src/darwin/Framework/CHIP/MTRDefines_Internal.h @@ -65,6 +65,11 @@ typedef struct {} variable_hidden_by_mtr_hide; // Default timed interaction timeout, in ms, if another one is not provided. #define MTR_DEFAULT_TIMED_INTERACTION_TIMEOUT_MS 10000 +// Useful building block for type-checking machinery. Uses C-style cast so it +// can be used in .m files as well. +#define MTR_SAFE_CAST(object, classname) \ + ([object isKindOfClass:[classname class]] ? (classname *) (object) : nil) + #pragma mark - XPC Defines #define MTR_SIMPLE_REMOTE_XPC_GETTER(XPC_CONNECTION, NAME, TYPE, DEFAULT_VALUE, GETTER_NAME, PREFIX) \ @@ -179,3 +184,15 @@ typedef struct {} variable_hidden_by_mtr_hide; #define MTR_ABSTRACT_METHOD() \ _MTR_ABSTRACT_METHOD_IMPL("%@ or some ancestor must implement %@", self.class, NSStringFromSelector(_cmd)) + +#pragma mark - Typedefs for some commonly used types. + +/** + * A data-value as defined in MTRBaseDevice.h. + */ +typedef NSDictionary * MTRDeviceDataValueDictionary; + +/** + * A response-value as defined in MTRBaseDevice.h. + */ +typedef NSDictionary * MTRDeviceResponseValueDictionary; diff --git a/src/darwin/Framework/CHIP/MTRDevice.mm b/src/darwin/Framework/CHIP/MTRDevice.mm index 8e379980578f58..2337d0eae625f5 100644 --- a/src/darwin/Framework/CHIP/MTRDevice.mm +++ b/src/darwin/Framework/CHIP/MTRDevice.mm @@ -25,7 +25,6 @@ #import "MTRConversion.h" #import "MTRDefines_Internal.h" #import "MTRDeviceController_Internal.h" -#import "MTRDeviceDataValueDictionary.h" #import "MTRDevice_Internal.h" #import "MTRError_Internal.h" #import "MTRLogging_Internal.h" diff --git a/src/darwin/Framework/CHIP/MTRDeviceClusterData.h b/src/darwin/Framework/CHIP/MTRDeviceClusterData.h index d34ada90e9a7f2..2abdc6113b44af 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceClusterData.h +++ b/src/darwin/Framework/CHIP/MTRDeviceClusterData.h @@ -17,7 +17,6 @@ #import #import "MTRDefines_Internal.h" -#import "MTRDeviceDataValueDictionary.h" NS_ASSUME_NONNULL_BEGIN diff --git a/src/darwin/Framework/CHIP/MTRDeviceDataValidation.h b/src/darwin/Framework/CHIP/MTRDeviceDataValidation.h new file mode 100644 index 00000000000000..5d448d8aa4fcba --- /dev/null +++ b/src/darwin/Framework/CHIP/MTRDeviceDataValidation.h @@ -0,0 +1,42 @@ +/** + * Copyright (c) 2024 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +#import "MTRDefines_Internal.h" + +NS_ASSUME_NONNULL_BEGIN + +// Returns whether a data-value dictionary is well-formed (in the sense that all +// the types of the objects inside are as expected, so it's actually a valid +// representation of some TLV). Implemented in MTRBaseDevice.mm because that's +// where the pieces needed to implement it are, but declared here so our tests +// can see it. +MTR_EXTERN MTR_TESTABLE BOOL MTRDataValueDictionaryIsWellFormed(MTRDeviceDataValueDictionary value); + +// Returns whether the provided attribute report actually has the right sorts of +// objects in the right places. +MTR_EXTERN MTR_TESTABLE BOOL MTRAttributeReportIsWellFormed(NSArray * report); + +// Returns whether the provided event report actually has the right sorts of +// objects in the right places. +MTR_EXTERN MTR_TESTABLE BOOL MTREventReportIsWellFormed(NSArray * report); + +// Returns whether the provided invoke response actually has the right sorts of +// objects in the right places. +MTR_EXTERN MTR_TESTABLE BOOL MTRInvokeResponseIsWellFormed(NSArray * response); + +NS_ASSUME_NONNULL_END diff --git a/src/darwin/Framework/CHIP/MTRDeviceDataValidation.mm b/src/darwin/Framework/CHIP/MTRDeviceDataValidation.mm new file mode 100644 index 00000000000000..55014b453132a3 --- /dev/null +++ b/src/darwin/Framework/CHIP/MTRDeviceDataValidation.mm @@ -0,0 +1,216 @@ +/** + * Copyright (c) 2024 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "MTRDeviceDataValidation.h" + +#import "MTRBaseDevice.h" + +#import "MTRLogging_Internal.h" + +// MTRDataValueDictionaryIsWellFormed lives in MTRBaseDevice.mm, because it uses +// static functions defined in that file. + +#pragma mark - Helpers used by multiple validators + +#define MTR_CHECK_CLASS(className) \ + ^(className * arg) { return MTR_SAFE_CAST(arg, className) != nil; } + +// input is not known to be an NSDictionary yet on entry. +// +// expectedShape maps keys to value validator blocks. +static BOOL MTRDictionaryHasExpectedShape(NSDictionary * input, NSDictionary * expectedShape) +{ + if (!MTR_SAFE_CAST(input, NSDictionary)) { + return NO; + } + + for (id key in expectedShape) { + id value = input[key]; + if (!value) { + return NO; + } + auto validator = static_cast(expectedShape[key]); + if (!validator(value)) { + return NO; + } + } + + return YES; +} + +#pragma mark - Attribute report validation + +static const auto sAttributeDataShape = @{ + MTRAttributePathKey : MTR_CHECK_CLASS(MTRAttributePath), + MTRDataKey : (^(MTRDeviceDataValueDictionary arg) { + return MTRDataValueDictionaryIsWellFormed(arg); + }), +}; + +static const auto sAttributeErrorShape = @{ + MTRAttributePathKey : MTR_CHECK_CLASS(MTRAttributePath), + MTRErrorKey : MTR_CHECK_CLASS(NSError), +}; + +BOOL MTRAttributeReportIsWellFormed(NSArray * report) +{ + if (!MTR_SAFE_CAST(report, NSArray)) { + MTR_LOG_ERROR("Attribute report is not an array: %@", report); + return NO; + } + + for (MTRDeviceResponseValueDictionary item in report) { + // item can be a value report or an error report. + if (!MTRDictionaryHasExpectedShape(item, sAttributeDataShape) && !MTRDictionaryHasExpectedShape(item, sAttributeErrorShape)) { + MTR_LOG_ERROR("Attribute report contains a weird entry: %@", item); + return NO; + } + + // Now we know item is in fact a dictionary, and it has at least one of MTRDataKey and MTRErrorKey. Make sure it's + // not claiming both, which could confuse code that examines it. + if (item[MTRDataKey] != nil && item[MTRErrorKey] != nil) { + MTR_LOG_ERROR("Attribute report contains an entry that claims to be both data and error: %@", item); + return NO; + } + } + + return YES; +} + +#pragma mark - Event report validation + +// MTREventIsHistoricalKey is claimed to be present no matter what, as +// long as MTREventPathKey is present. +static const auto sEventDataShape = @{ + MTREventPathKey : MTR_CHECK_CLASS(MTREventPath), + MTRDataKey : (^(MTRDeviceDataValueDictionary arg) { + return MTRDataValueDictionaryIsWellFormed(arg); + }), + MTREventIsHistoricalKey : MTR_CHECK_CLASS(NSNumber), + MTREventNumberKey : MTR_CHECK_CLASS(NSNumber), + MTREventPriorityKey : MTR_CHECK_CLASS(NSNumber), + MTREventTimeTypeKey : MTR_CHECK_CLASS(NSNumber), +}; + +static const auto sEventErrorShape = @{ + MTREventPathKey : MTR_CHECK_CLASS(MTREventPath), + MTRErrorKey : MTR_CHECK_CLASS(NSError), + MTREventIsHistoricalKey : MTR_CHECK_CLASS(NSNumber), +}; + +BOOL MTREventReportIsWellFormed(NSArray * report) +{ + if (!MTR_SAFE_CAST(report, NSArray)) { + MTR_LOG_ERROR("Event report is not an array: %@", report); + return NO; + } + + for (MTRDeviceResponseValueDictionary item in report) { + // item can be a value report or an error report. + if (!MTRDictionaryHasExpectedShape(item, sEventDataShape) && !MTRDictionaryHasExpectedShape(item, sEventErrorShape)) { + MTR_LOG_ERROR("Event report contains a weird entry: %@", item); + return NO; + } + + // Now we know item is in fact a dictionary, and it has at least one of MTRDataKey and MTRErrorKey. Make sure it's + // not claiming both, which could confuse code that examines it. + if (item[MTRDataKey] != nil && item[MTRErrorKey] != nil) { + MTR_LOG_ERROR("Event report contains an entry that claims to be both data and error: %@", item); + return NO; + } + + if (item[MTRDataKey]) { + // Check well-formedness of our timestamps. Note that we have + // already validated the type of item[MTREventTimeTypeKey]. + uint64_t eventTimeType = [item[MTREventTimeTypeKey] unsignedLongLongValue]; + switch (eventTimeType) { + case MTREventTimeTypeSystemUpTime: { + if (!MTR_SAFE_CAST(item[MTREventSystemUpTimeKey], NSNumber)) { + MTR_LOG_ERROR("Event report claims system uptime timing but does not have the time: %@", item); + return NO; + } + break; + } + case MTREventTimeTypeTimestampDate: { + if (!MTR_SAFE_CAST(item[MTREventTimestampDateKey], NSDate)) { + MTR_LOG_ERROR("Event report claims epoch timing but does not have the time: %@", item); + return NO; + } + break; + } + default: + MTR_LOG_ERROR("Uknown time type for event report: %@", item); + return NO; + } + } + } + + return YES; +} + +#pragma mark - Invoke response validation + +BOOL MTRInvokeResponseIsWellFormed(NSArray * response) +{ + if (!MTR_SAFE_CAST(response, NSArray)) { + MTR_LOG_ERROR("Invoke response is not an array: %@", response); + return NO; + } + + // Input is an array with a single value that must have MTRCommandPathKey. + if (response.count != 1) { + MTR_LOG_ERROR("Invoke response is not an array with exactly one entry: %@", response); + return NO; + } + + MTRDeviceResponseValueDictionary responseValue = response[0]; + + if (!MTR_SAFE_CAST(responseValue, NSDictionary) || !MTR_SAFE_CAST(responseValue[MTRCommandPathKey], MTRCommandPath)) { + MTR_LOG_ERROR("Invoke response is not an array with the right things in it: %@", response); + return NO; + } + + MTRDeviceDataValueDictionary _Nullable data = responseValue[MTRDataKey]; + NSError * _Nullable error = responseValue[MTRErrorKey]; + + if (data != nil && error != nil) { + MTR_LOG_ERROR("Invoke response claims to have both data and error: %@", responseValue); + return NO; + } + + if (error != nil) { + return MTR_SAFE_CAST(error, NSError) != nil; + } + + if (data == nil) { + // This is valid: indicates a success status response. + return YES; + } + + if (!MTRDataValueDictionaryIsWellFormed(data)) { + MTR_LOG_ERROR("Invoke response claims to have data that is not a data-value: %@", data); + return NO; + } + + // Now we know data is a dictionary (in fact a data-value). The only thing + // we promise about it is that it has type MTRStructureValueType. + if (data[MTRTypeKey] != MTRStructureValueType) { + MTR_LOG_ERROR("Invoke response data is not of structure type: %@", data); + return NO; + } + + return YES; +} diff --git a/src/darwin/Framework/CHIP/MTRDeviceDataValueDictionary.h b/src/darwin/Framework/CHIP/MTRDeviceDataValueDictionary.h deleted file mode 100644 index 53a6b2e6f914b7..00000000000000 --- a/src/darwin/Framework/CHIP/MTRDeviceDataValueDictionary.h +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Copyright (c) 2024 Project CHIP Authors - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#import - -NS_ASSUME_NONNULL_BEGIN - -/** - * A data-value as defined in MTRBaseDevice.h. - */ -typedef NSDictionary * MTRDeviceDataValueDictionary; - -NS_ASSUME_NONNULL_END diff --git a/src/darwin/Framework/CHIP/MTRDevice_Concrete.mm b/src/darwin/Framework/CHIP/MTRDevice_Concrete.mm index f8319f2636351e..12b6250e0bcadb 100644 --- a/src/darwin/Framework/CHIP/MTRDevice_Concrete.mm +++ b/src/darwin/Framework/CHIP/MTRDevice_Concrete.mm @@ -31,7 +31,7 @@ #import "MTRDeviceConnectivityMonitor.h" #import "MTRDeviceControllerOverXPC.h" #import "MTRDeviceController_Internal.h" -#import "MTRDeviceDataValueDictionary.h" +#import "MTRDeviceDataValidation.h" #import "MTRDevice_Concrete.h" #import "MTRDevice_Internal.h" #import "MTRError_Internal.h" @@ -1899,8 +1899,13 @@ - (void)_handleAttributeReport:(NSArray *> *)attrib } // BEGIN DRAGON: This is used by the XPC Server to inject reports into local cache and broadcast them -- (void)_injectAttributeReport:(NSArray *> *)attributeReport fromSubscription:(BOOL)isFromSubscription +- (void)_injectAttributeReport:(NSArray *)attributeReport fromSubscription:(BOOL)isFromSubscription { + if (!MTRAttributeReportIsWellFormed(attributeReport)) { + MTR_LOG_ERROR("%@ injected attribute report is not well-formed: %@", self, attributeReport); + return; + } + [_deviceController asyncDispatchToMatterQueue:^{ MTR_LOG("%@ injected attribute report (%p) %@", self, attributeReport, attributeReport); [self _handleReportBegin]; @@ -1911,8 +1916,13 @@ - (void)_injectAttributeReport:(NSArray *> *)attrib } errorHandler:nil]; } -- (void)_injectEventReport:(NSArray *> *)eventReport +- (void)_injectEventReport:(NSArray *)eventReport { + if (!MTREventReportIsWellFormed(eventReport)) { + MTR_LOG_ERROR("%@ injected event report is not well-formed: %@", self, eventReport); + return; + } + // [_deviceController asyncDispatchToMatterQueue:^{ // TODO: This wasn't used previously, not sure why, so keeping it here for thought, but preserving existing behavior dispatch_async(self.queue, ^{ [self _handleEventReport:eventReport]; diff --git a/src/darwin/Framework/CHIP/MTRDevice_Internal.h b/src/darwin/Framework/CHIP/MTRDevice_Internal.h index 4414b3c6133b07..35cc25e26949da 100644 --- a/src/darwin/Framework/CHIP/MTRDevice_Internal.h +++ b/src/darwin/Framework/CHIP/MTRDevice_Internal.h @@ -22,7 +22,6 @@ #import "MTRAsyncWorkQueue.h" #import "MTRDefines_Internal.h" -#import "MTRDeviceDataValueDictionary.h" #import "MTRDeviceStorageBehaviorConfiguration_Internal.h" NS_ASSUME_NONNULL_BEGIN @@ -176,13 +175,6 @@ MTR_DIRECT_MEMBERS - (void)devicePrivateInternalStateChanged:(MTRDevice *)device internalState:(NSDictionary *)state; @end -// Returns whether a data-value dictionary is well-formed (in the sense that all -// the types of the objects inside are as expected, so it's actually a valid -// representation of some TLV). Implemented in MTRBaseDevice.mm because that's -// where the pieces needed to implement it are, but declared here so our tests -// can see it. -MTR_EXTERN MTR_TESTABLE BOOL MTRDataValueDictionaryIsWellFormed(MTRDeviceDataValueDictionary value); - #pragma mark - Constants static NSString * const kDefaultSubscriptionPoolSizeOverrideKey = @"subscriptionPoolSizeOverride"; diff --git a/src/darwin/Framework/CHIP/MTRDevice_XPC.mm b/src/darwin/Framework/CHIP/MTRDevice_XPC.mm index cee041afbd52cf..8a5f745a1dfc70 100644 --- a/src/darwin/Framework/CHIP/MTRDevice_XPC.mm +++ b/src/darwin/Framework/CHIP/MTRDevice_XPC.mm @@ -41,7 +41,7 @@ #import "MTRDeviceControllerStartupParams_Internal.h" #import "MTRDeviceController_Concrete.h" #import "MTRDeviceController_XPC.h" -#import "MTRDeviceDataValueDictionary.h" +#import "MTRDeviceDataValidation.h" #import "MTRDevice_Concrete.h" #import "MTRDevice_Internal.h" #import "MTRDevice_XPC_Internal.h" @@ -146,22 +146,47 @@ - (nullable NSNumber *)productID // required methods for MTRDeviceDelegates - (oneway void)device:(NSNumber *)nodeID stateChanged:(MTRDeviceState)state { + if (!MTR_SAFE_CAST(nodeID, NSNumber)) { + MTR_LOG_ERROR("%@ invalid device:stateChanged: nodeID: %@", self, nodeID); + return; + } + MTR_LOG("%s", __PRETTY_FUNCTION__); [self _lockAndCallDelegatesWithBlock:^(id delegate) { [delegate device:self stateChanged:state]; }]; } -- (oneway void)device:(NSNumber *)nodeID receivedAttributeReport:(NSArray *> *)attributeReport +- (oneway void)device:(NSNumber *)nodeID receivedAttributeReport:(NSArray *)attributeReport { + if (!MTR_SAFE_CAST(nodeID, NSNumber)) { + MTR_LOG_ERROR("%@ invalid device:receivedAttributeReport: nodeID: %@", self, nodeID); + return; + } + + if (!MTRAttributeReportIsWellFormed(attributeReport)) { + MTR_LOG_ERROR("%@ invalid device:receivedAttributeReport: attributeReport: %@", self, attributeReport); + return; + } + MTR_LOG("%s", __PRETTY_FUNCTION__); [self _lockAndCallDelegatesWithBlock:^(id delegate) { [delegate device:self receivedAttributeReport:attributeReport]; }]; } -- (oneway void)device:(NSNumber *)nodeID receivedEventReport:(NSArray *> *)eventReport +- (oneway void)device:(NSNumber *)nodeID receivedEventReport:(NSArray *)eventReport { + if (!MTR_SAFE_CAST(nodeID, NSNumber)) { + MTR_LOG_ERROR("%@ invalid device:receivedEventReport: nodeID: %@", self, nodeID); + return; + } + + if (!MTREventReportIsWellFormed(eventReport)) { + MTR_LOG_ERROR("%@ invalid device:receivedEventReport: eventReport: %@", self, eventReport); + return; + } + MTR_LOG("%s", __PRETTY_FUNCTION__); [self _lockAndCallDelegatesWithBlock:^(id delegate) { [delegate device:self receivedEventReport:eventReport]; @@ -171,6 +196,11 @@ - (oneway void)device:(NSNumber *)nodeID receivedEventReport:(NSArray delegate) { if ([delegate respondsToSelector:@selector(deviceBecameActive:)]) { @@ -181,6 +211,11 @@ - (oneway void)deviceBecameActive:(NSNumber *)nodeID - (oneway void)deviceCachePrimed:(NSNumber *)nodeID { + if (!MTR_SAFE_CAST(nodeID, NSNumber)) { + MTR_LOG_ERROR("%@ invalid deviceCachePrimed: nodeID: %@", self, nodeID); + return; + } + [self _lockAndCallDelegatesWithBlock:^(id delegate) { if ([delegate respondsToSelector:@selector(deviceCachePrimed:)]) { [delegate deviceCachePrimed:self]; @@ -190,6 +225,11 @@ - (oneway void)deviceCachePrimed:(NSNumber *)nodeID - (oneway void)deviceConfigurationChanged:(NSNumber *)nodeID { + if (!MTR_SAFE_CAST(nodeID, NSNumber)) { + MTR_LOG_ERROR("%@ invalid deviceConfigurationChanged: nodeID: %@", self, nodeID); + return; + } + [self _lockAndCallDelegatesWithBlock:^(id delegate) { if ([delegate respondsToSelector:@selector(deviceConfigurationChanged:)]) { [delegate deviceConfigurationChanged:self]; @@ -197,14 +237,55 @@ - (oneway void)deviceConfigurationChanged:(NSNumber *)nodeID }]; } +static const auto * requiredInternalStateKeys = @[ kMTRDeviceInternalPropertyDeviceState, kMTRDeviceInternalPropertyLastSubscriptionAttemptWait ]; +static const auto * optionalInternalStateKeys = @[ kMTRDeviceInternalPropertyKeyVendorID, kMTRDeviceInternalPropertyKeyProductID, kMTRDeviceInternalPropertyNetworkFeatures, kMTRDeviceInternalPropertyMostRecentReportTime, kMTRDeviceInternalPropertyLastSubscriptionFailureTime ]; + +- (BOOL)_internalState:(NSDictionary *)dictionary hasValidValuesForKeys:(const NSArray *)keys valueRequired:(BOOL)required +{ + // All the keys are NSNumber-valued. + for (NSString * key in keys) { + id value = dictionary[key]; + if (!value) { + if (required) { + MTR_LOG_ERROR("%@ device:internalStateUpdated: handed state with no value for \"%@\": %@", self, key, value); + return NO; + } + + continue; + } + if (!MTR_SAFE_CAST(value, NSNumber)) { + MTR_LOG_ERROR("%@ device:internalStateUpdated: handed state with invalid value for \"%@\": %@", self, key, value); + return NO; + } + } + + return YES; +} + - (oneway void)device:(NSNumber *)nodeID internalStateUpdated:(NSDictionary *)dictionary { + if (!MTR_SAFE_CAST(nodeID, NSNumber)) { + MTR_LOG_ERROR("%@ invalid device:internalStateUpdated: nodeID: %@", self, nodeID); + return; + } + + if (!MTR_SAFE_CAST(dictionary, NSDictionary)) { + MTR_LOG_ERROR("%@ invalid device:internalStateUpdated dictionary: %@", self, dictionary); + return; + } + + VerifyOrReturn([self _internalState:dictionary hasValidValuesForKeys:requiredInternalStateKeys valueRequired:YES]); + VerifyOrReturn([self _internalState:dictionary hasValidValuesForKeys:optionalInternalStateKeys valueRequired:NO]); + [self _setInternalState:dictionary]; MTR_LOG("%@ internal state updated", self); } #pragma mark - Remote Commands +// TODO: Figure out how to validate the return values for the various +// MTR_DEVICE_*_XPC macros below. + MTR_DEVICE_SIMPLE_REMOTE_XPC_GETTER(state, MTRDeviceState, MTRDeviceStateUnknown, getStateWithReply) MTR_DEVICE_SIMPLE_REMOTE_XPC_GETTER(deviceCachePrimed, BOOL, NO, getDeviceCachePrimedWithReply) MTR_DEVICE_SIMPLE_REMOTE_XPC_GETTER(estimatedStartTime, NSDate * _Nullable, nil, getEstimatedStartTimeWithReply) @@ -273,7 +354,34 @@ - (void)_invokeCommandWithEndpointID:(NSNumber *)endpointID expectedValueInterval:expectedValueInterval timedInvokeTimeout:timeout serverSideProcessingTimeout:serverSideProcessingTimeout - completion:completion]; + completion:^(NSArray *> * _Nullable values, NSError * _Nullable error) { + if (values == nil && error == nil) { + MTR_LOG_ERROR("%@ got invoke response for (%@, %@, %@) without values or error", self, endpointID, clusterID, commandID); + completion(nil, [MTRError errorForCHIPErrorCode:CHIP_ERROR_INVALID_ARGUMENT]); + return; + } + + if (error != nil && !MTR_SAFE_CAST(error, NSError)) { + MTR_LOG_ERROR("%@ got invoke response for (%@, %@, %@) that has invalid error object: %@", self, endpointID, clusterID, commandID, error); + completion(nil, [MTRError errorForCHIPErrorCode:CHIP_ERROR_INVALID_ARGUMENT]); + return; + } + + if (values != nil && !MTRInvokeResponseIsWellFormed(values)) { + MTR_LOG_ERROR("%@ got invoke response for (%@, %@, %@) that has invalid data: %@", self, clusterID, commandID, values, values); + completion(nil, [MTRError errorForCHIPErrorCode:CHIP_ERROR_INVALID_ARGUMENT]); + return; + } + + if (values != nil && error != nil) { + MTR_LOG_ERROR("%@ got invoke response for (%@, %@, %@) with both values and error: %@, %@", self, endpointID, clusterID, commandID, values, error); + // Just propagate through the error. + completion(nil, error); + return; + } + + completion(values, error); + }]; } @catch (NSException * exception) { MTR_LOG_ERROR("Exception sending XPC message: %@", exception); completion(nil, [NSError errorWithDomain:MTRErrorDomain code:MTRErrorCodeGeneralError userInfo:nil]); diff --git a/src/darwin/Framework/CHIPTests/MTRDeviceTests.m b/src/darwin/Framework/CHIPTests/MTRDeviceTests.m index 3fa4ff45449f89..d5faaec24b63b3 100644 --- a/src/darwin/Framework/CHIPTests/MTRDeviceTests.m +++ b/src/darwin/Framework/CHIPTests/MTRDeviceTests.m @@ -27,6 +27,7 @@ #import "MTRCommandPayloadExtensions_Internal.h" #import "MTRDeviceClusterData.h" #import "MTRDeviceControllerLocalTestStorage.h" +#import "MTRDeviceDataValidation.h" #import "MTRDeviceStorageBehaviorConfiguration.h" #import "MTRDeviceTestDelegate.h" #import "MTRDevice_Internal.h" @@ -1505,7 +1506,14 @@ - (void)test017_TestMTRDeviceBasics [device unitTestInjectEventReport:@[ @{ MTREventPathKey : [MTREventPath eventPathWithEndpointID:@(1) clusterID:@(1) eventID:@(1)], MTREventTimeTypeKey : @(MTREventTimeTypeTimestampDate), - MTREventTimestampDateKey : [NSDate date] + MTREventTimestampDateKey : [NSDate date], + MTREventIsHistoricalKey : @(NO), + MTREventPriorityKey : @(MTREventPriorityInfo), + MTREventNumberKey : @(1), // Doesn't matter, in practice + MTRDataKey : @ { + MTRTypeKey : MTRStructureValueType, + MTRValueKey : @[], + }, } ]]; #endif }; @@ -4139,7 +4147,14 @@ - (void)test037_MTRDeviceMultipleDelegatesGetReports MTREventPathKey : [MTREventPath eventPathWithEndpointID:endpointID clusterID:clusterID eventID:eventID], MTREventTimeTypeKey : @(MTREventTimeTypeTimestampDate), MTREventTimestampDateKey : [NSDate date], - // For unit test no real data is needed, but timestamp is required + MTREventIsHistoricalKey : @(NO), + MTREventPriorityKey : @(MTREventPriorityInfo), + MTREventNumberKey : @(1), // Doesn't matter, in practice + // Empty payload. + MTRDataKey : @ { + MTRTypeKey : MTRStructureValueType, + MTRValueKey : @[], + }, }; } @@ -5187,6 +5202,306 @@ - (void)test041_AttributeDataValueValidation } } +- (void)test042_AttributeReportWellFormedness +{ + __auto_type * testData = @[ + @{ + @"input" : @[], + @"valid" : @(YES), + }, + @{ + @"input" : @[ + @{ + MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:@(0) clusterID:@(6) attributeID:@(0)], + MTRDataKey : @ { + MTRTypeKey : MTRBooleanValueType, + MTRValueKey : @(YES), + }, + }, + ], + @"valid" : @(YES), + }, + @{ + @"input" : @[ + @{ + MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:@(0) clusterID:@(6) attributeID:@(0)], + MTRDataKey : @ { + MTRTypeKey : MTRBooleanValueType, + MTRValueKey : @(YES), + }, + }, + @{ + MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:@(0) clusterID:@(6) attributeID:@(1)], + MTRErrorKey : [NSError errorWithDomain:MTRErrorDomain code:0 userInfo:nil], + }, + ], + @"valid" : @(YES), + }, + @{ + @"input" : @[ + @{ + MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:@(0) clusterID:@(6) attributeID:@(0)], + }, + @{ + MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:@(0) clusterID:@(6) attributeID:@(1)], + MTRErrorKey : [NSError errorWithDomain:MTRErrorDomain code:0 userInfo:nil], + }, + ], + // Missing both error and data + @"valid" : @(NO), + }, + @{ + @"input" : @[ + @{ + MTRAttributePathKey : [MTRAttributePath attributePathWithEndpointID:@(0) clusterID:@(6) attributeID:@(0)], + MTRDataKey : @ { + MTRTypeKey : MTRBooleanValueType, + MTRValueKey : @("abc"), + }, + }, + ], + // Data dictionary is broken. + @"valid" : @(NO), + }, + @{ + @"input" : @ {}, + // Input is not an array. + @"valid" : @(NO), + }, + ]; + + for (NSDictionary * test in testData) { + XCTAssertEqual(MTRAttributeReportIsWellFormed(test[@"input"]), [test[@"valid"] boolValue], + "input: %@", test[@"input"]); + } +} + +- (void)test043_EventReportWellFormedness +{ + __auto_type * testData = @[ + @{ + @"input" : @[ + @{ + MTREventPathKey : [MTREventPath eventPathWithEndpointID:@(0) clusterID:@(6) eventID:@(0)], + MTRErrorKey : [NSError errorWithDomain:MTRErrorDomain code:0 userInfo:nil], + MTREventIsHistoricalKey : @(NO), + }, + ], + @"valid" : @(YES), + }, + @{ + @"input" : @[ + @{ + MTREventPathKey : [MTREventPath eventPathWithEndpointID:@(0) clusterID:@(6) eventID:@(0)], + MTRDataKey : @ { + MTRTypeKey : MTRStructureValueType, + MTRValueKey : @[], // No fields + }, + MTREventNumberKey : @(5), + MTREventPriorityKey : @(MTREventPriorityInfo), + MTREventTimeTypeKey : @(MTREventTimeTypeTimestampDate), + MTREventTimestampDateKey : [NSDate now], + MTREventIsHistoricalKey : @(NO), + }, + ], + @"valid" : @(YES), + }, + @{ + @"input" : @[ + @{ + MTREventPathKey : [MTREventPath eventPathWithEndpointID:@(0) clusterID:@(6) eventID:@(0)], + MTRDataKey : @ { + MTRTypeKey : MTRStructureValueType, + MTRValueKey : @[], // No fields + }, + MTREventNumberKey : @(5), + MTREventPriorityKey : @(MTREventPriorityInfo), + MTREventTimeTypeKey : @(MTREventTimeTypeSystemUpTime), + MTREventSystemUpTimeKey : @(5), + MTREventIsHistoricalKey : @(NO), + }, + ], + @"valid" : @(YES), + }, + @{ + @"input" : @[ + @{ + MTREventPathKey : [MTREventPath eventPathWithEndpointID:@(0) clusterID:@(6) eventID:@(0)], + MTRDataKey : @ { + MTRTypeKey : MTRStructureValueType, + MTRValueKey : @[], // No fields + }, + MTREventNumberKey : @(5), + MTREventPriorityKey : @(MTREventPriorityInfo), + MTREventTimeTypeKey : @(MTREventTimeTypeTimestampDate), + MTREventTimestampDateKey : @(5), + MTREventIsHistoricalKey : @(NO), + }, + ], + // Wrong date type + @"valid" : @(NO), + }, + @{ + @"input" : @[ + @{ + MTREventPathKey : [MTREventPath eventPathWithEndpointID:@(0) clusterID:@(6) eventID:@(0)], + MTRDataKey : @ { + MTRTypeKey : MTRStructureValueType, + MTRValueKey : @[], // No fields + }, + MTREventNumberKey : @("abc"), + MTREventPriorityKey : @(MTREventPriorityInfo), + MTREventTimeTypeKey : @(MTREventTimeTypeSystemUpTime), + MTREventSystemUpTimeKey : @(5), + MTREventIsHistoricalKey : @(NO), + }, + ], + // Wrong type of EventNumber + @"valid" : @(NO), + }, + @{ + @"input" : @[ + @{ + MTREventPathKey : [MTREventPath eventPathWithEndpointID:@(0) clusterID:@(6) eventID:@(0)], + MTRDataKey : @ { + MTRTypeKey : MTRStructureValueType, + MTRValueKey : @[], // No fields + }, + MTREventNumberKey : @(5), + MTREventPriorityKey : @("abc"), + MTREventTimeTypeKey : @(MTREventTimeTypeSystemUpTime), + MTREventSystemUpTimeKey : @(5), + MTREventIsHistoricalKey : @(NO), + }, + ], + // Wrong type of EventPriority + @"valid" : @(NO), + }, + @{ + @"input" : @[ + @{ + MTREventPathKey : [MTREventPath eventPathWithEndpointID:@(0) clusterID:@(6) eventID:@(0)], + MTRDataKey : @ { + MTRTypeKey : MTRStructureValueType, + MTRValueKey : @[], // No fields + }, + MTREventNumberKey : @(5), + MTREventPriorityKey : @(MTREventPriorityInfo), + MTREventTimeTypeKey : @("abc"), + MTREventSystemUpTimeKey : @(5), + MTREventIsHistoricalKey : @(NO), + }, + ], + // Wrong type of EventTimeType + @"valid" : @(NO), + }, + @{ + @"input" : @[ @(5) ], + // Wrong type of data entirely. + @"valid" : @(NO), + }, + @{ + @"input" : @ {}, + // Not even an array. + @"valid" : @(NO), + }, + ]; + + for (NSDictionary * test in testData) { + XCTAssertEqual(MTREventReportIsWellFormed(test[@"input"]), [test[@"valid"] boolValue], + "input: %@", test[@"input"]); + } +} + +- (void)test044_InvokeResponseWellFormedness +{ + __auto_type * testData = @[ + @{ + @"input" : @[ + @{ + MTRCommandPathKey : [MTRCommandPath commandPathWithEndpointID:@(0) clusterID:@(6) commandID:@(0)], + }, + ], + @"valid" : @(YES), + }, + @{ + @"input" : @[ + @{ + MTRCommandPathKey : [MTRCommandPath commandPathWithEndpointID:@(0) clusterID:@(6) commandID:@(0)], + }, + @{ + MTRCommandPathKey : [MTRCommandPath commandPathWithEndpointID:@(0) clusterID:@(6) commandID:@(0)], + }, + ], + // Multiple responses + @"valid" : @(NO), + }, + @{ + @"input" : @[ + @{ + MTRCommandPathKey : [MTRCommandPath commandPathWithEndpointID:@(0) clusterID:@(6) commandID:@(0)], + MTRErrorKey : [NSError errorWithDomain:MTRErrorDomain code:0 userInfo:nil], + }, + ], + @"valid" : @(YES), + }, + @{ + @"input" : @[ + @{ + MTRCommandPathKey : [MTRCommandPath commandPathWithEndpointID:@(0) clusterID:@(6) commandID:@(0)], + MTRDataKey : @ { + MTRTypeKey : MTRStructureValueType, + MTRValueKey : @[], // Empty structure, valid + }, + }, + ], + @"valid" : @(YES), + }, + @{ + @"input" : @[ + @{ + MTRCommandPathKey : [MTRCommandPath commandPathWithEndpointID:@(0) clusterID:@(6) commandID:@(0)], + MTRDataKey : @ { + MTRTypeKey : MTRStructureValueType, + MTRValueKey : @[], // Empty structure, valid + }, + MTRErrorKey : [NSError errorWithDomain:MTRErrorDomain code:0 userInfo:nil], + }, + ], + // Having both data and error not valid. + @"valid" : @(NO), + }, + @{ + @"input" : @[ + @{ + MTRCommandPathKey : [MTRCommandPath commandPathWithEndpointID:@(0) clusterID:@(6) commandID:@(0)], + MTRDataKey : @ { + MTRTypeKey : MTRUnsignedIntegerValueType, + MTRValueKey : @(5), + }, + }, + ], + // Data is not a struct. + @"valid" : @(NO), + }, + @{ + @"input" : @[ + @{ + MTRCommandPathKey : [MTRCommandPath commandPathWithEndpointID:@(0) clusterID:@(6) commandID:@(0)], + MTRDataKey : @(6), + }, + ], + // Data is not a data-value at all.. + @"valid" : @(NO), + }, + ]; + + for (NSDictionary * test in testData) { + XCTAssertEqual(MTRInvokeResponseIsWellFormed(test[@"input"]), [test[@"valid"] boolValue], + "input: %@", test[@"input"]); + } +} + @end @interface MTRDeviceEncoderTests : XCTestCase diff --git a/src/darwin/Framework/CHIPTests/MTRPerControllerStorageTests.m b/src/darwin/Framework/CHIPTests/MTRPerControllerStorageTests.m index 721cb09b994e25..071566381cc69c 100644 --- a/src/darwin/Framework/CHIPTests/MTRPerControllerStorageTests.m +++ b/src/darwin/Framework/CHIPTests/MTRPerControllerStorageTests.m @@ -19,9 +19,9 @@ #import #import +#import "MTRDefines_Internal.h" #import "MTRDeviceClusterData.h" #import "MTRDeviceControllerLocalTestStorage.h" -#import "MTRDeviceDataValueDictionary.h" #import "MTRDeviceStorageBehaviorConfiguration.h" #import "MTRDeviceTestDelegate.h" #import "MTRDevice_Internal.h" diff --git a/src/darwin/Framework/CHIPTests/TestHelpers/MTRTestDeclarations.h b/src/darwin/Framework/CHIPTests/TestHelpers/MTRTestDeclarations.h index b00507d665a9f0..591110b34ea712 100644 --- a/src/darwin/Framework/CHIPTests/TestHelpers/MTRTestDeclarations.h +++ b/src/darwin/Framework/CHIPTests/TestHelpers/MTRTestDeclarations.h @@ -18,8 +18,8 @@ #import #import +#import "MTRDefines_Internal.h" #import "MTRDeviceClusterData.h" -#import "MTRDeviceDataValueDictionary.h" #import "MTRDevice_Internal.h" NS_ASSUME_NONNULL_BEGIN diff --git a/src/darwin/Framework/Matter.xcodeproj/project.pbxproj b/src/darwin/Framework/Matter.xcodeproj/project.pbxproj index a08a406778458e..6a802900d8d30c 100644 --- a/src/darwin/Framework/Matter.xcodeproj/project.pbxproj +++ b/src/darwin/Framework/Matter.xcodeproj/project.pbxproj @@ -134,7 +134,8 @@ 5109E9B72CB8B83D0006884B /* MTRDeviceTypeTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 5109E9B62CB8B83D0006884B /* MTRDeviceTypeTests.m */; }; 5109E9BA2CC1F23E0006884B /* MTRDeviceClusterData.h in Headers */ = {isa = PBXBuildFile; fileRef = 5109E9B82CC1F23E0006884B /* MTRDeviceClusterData.h */; }; 5109E9BB2CC1F23E0006884B /* MTRDeviceClusterData.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5109E9B92CC1F23E0006884B /* MTRDeviceClusterData.mm */; }; - 5109E9BD2CC1F25C0006884B /* MTRDeviceDataValueDictionary.h in Headers */ = {isa = PBXBuildFile; fileRef = 5109E9BC2CC1F25C0006884B /* MTRDeviceDataValueDictionary.h */; }; + 5109E9C02CCAD64F0006884B /* MTRDeviceDataValidation.h in Headers */ = {isa = PBXBuildFile; fileRef = 5109E9BE2CCAD64F0006884B /* MTRDeviceDataValidation.h */; }; + 5109E9C12CCAD64F0006884B /* MTRDeviceDataValidation.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5109E9BF2CCAD64F0006884B /* MTRDeviceDataValidation.mm */; }; 510A07492A685D3900A9241C /* Matter.apinotes in Headers */ = {isa = PBXBuildFile; fileRef = 510A07482A685D3900A9241C /* Matter.apinotes */; settings = {ATTRIBUTES = (Public, ); }; }; 510CECA8297F72970064E0B3 /* MTROperationalCertificateIssuerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 510CECA6297F72470064E0B3 /* MTROperationalCertificateIssuerTests.m */; }; 5117DD3829A931AE00FFA1AA /* MTROperationalBrowser.mm in Sources */ = {isa = PBXBuildFile; fileRef = 5117DD3629A931AD00FFA1AA /* MTROperationalBrowser.mm */; }; @@ -589,7 +590,8 @@ 5109E9B62CB8B83D0006884B /* MTRDeviceTypeTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MTRDeviceTypeTests.m; sourceTree = ""; }; 5109E9B82CC1F23E0006884B /* MTRDeviceClusterData.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MTRDeviceClusterData.h; sourceTree = ""; }; 5109E9B92CC1F23E0006884B /* MTRDeviceClusterData.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MTRDeviceClusterData.mm; sourceTree = ""; }; - 5109E9BC2CC1F25C0006884B /* MTRDeviceDataValueDictionary.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MTRDeviceDataValueDictionary.h; sourceTree = ""; }; + 5109E9BE2CCAD64F0006884B /* MTRDeviceDataValidation.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MTRDeviceDataValidation.h; sourceTree = ""; }; + 5109E9BF2CCAD64F0006884B /* MTRDeviceDataValidation.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = MTRDeviceDataValidation.mm; sourceTree = ""; }; 510A07482A685D3900A9241C /* Matter.apinotes */ = {isa = PBXFileReference; lastKnownFileType = text.apinotes; name = Matter.apinotes; path = CHIP/Matter.apinotes; sourceTree = ""; }; 510CECA6297F72470064E0B3 /* MTROperationalCertificateIssuerTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MTROperationalCertificateIssuerTests.m; sourceTree = ""; }; 5117DD3629A931AD00FFA1AA /* MTROperationalBrowser.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MTROperationalBrowser.mm; sourceTree = ""; }; @@ -1425,7 +1427,8 @@ 51565CB32A7AD78D00469F18 /* MTRDeviceControllerStorageDelegate.h */, 5A6FEC9427B5976200F25F42 /* MTRDeviceControllerXPCConnection.h */, 5A6FEC9527B5983000F25F42 /* MTRDeviceControllerXPCConnection.mm */, - 5109E9BC2CC1F25C0006884B /* MTRDeviceDataValueDictionary.h */, + 5109E9BE2CCAD64F0006884B /* MTRDeviceDataValidation.h */, + 5109E9BF2CCAD64F0006884B /* MTRDeviceDataValidation.mm */, 5A6FEC8B27B5609C00F25F42 /* MTRDeviceOverXPC.h */, 5A6FEC9727B5C6AF00F25F42 /* MTRDeviceOverXPC.mm */, 754784632BFE65B70089C372 /* MTRDeviceStorageBehaviorConfiguration.h */, @@ -1707,7 +1710,6 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - 5109E9BD2CC1F25C0006884B /* MTRDeviceDataValueDictionary.h in Headers */, 51D0B1282B617246006E3511 /* MTRServerEndpoint.h in Headers */, 51565CB62A7B0D6600469F18 /* MTRDeviceControllerParameters.h in Headers */, 51565CB42A7AD78D00469F18 /* MTRDeviceControllerStorageDelegate.h in Headers */, @@ -1767,6 +1769,7 @@ 516415FD2B6ACA8300D5CE11 /* MTRServerAccessControl.h in Headers */, 3CF134AB289D8DF70017A19E /* MTRDeviceAttestationInfo.h in Headers */, B2E0D7B2245B0B5C003C5B48 /* MTRManualSetupPayloadParser.h in Headers */, + 5109E9C02CCAD64F0006884B /* MTRDeviceDataValidation.h in Headers */, 3CF134A7289D8ADA0017A19E /* MTRCSRInfo.h in Headers */, 88E07D612B9A89A4005FD53E /* MTRMetricKeys.h in Headers */, 3D4733B32BE2D1DA003DC19B /* MTRUtilities.h in Headers */, @@ -2157,6 +2160,7 @@ 7596A85528788557004DAE0E /* MTRClusters.mm in Sources */, 88EBF8CF27FABDD500686BC1 /* MTRDeviceAttestationDelegateBridge.mm in Sources */, 5A6FEC9827B5C6AF00F25F42 /* MTRDeviceOverXPC.mm in Sources */, + 5109E9C12CCAD64F0006884B /* MTRDeviceDataValidation.mm in Sources */, 9BDA2A062C5D9AF800A32BDD /* MTRDevice_Concrete.mm in Sources */, 514654492A72F9DF00904E61 /* MTRDemuxingStorage.mm in Sources */, 1E4D655229C30A8700BC3478 /* MTRCommissionableBrowser.mm in Sources */, From f17f9259e10e0e90c320fabf1dad1f3838b0133c Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Fri, 25 Oct 2024 18:07:34 -0400 Subject: [PATCH 124/149] Make datamodel-provider inteface logging optional/configurable (#36249) * make more detailed logging optional in the codegen data model and enable it only on known large platforms * Update src/app/common_flags.gni Co-authored-by: Boris Zbarsky * Restyled by gn --------- Co-authored-by: Andrei Litvin Co-authored-by: Boris Zbarsky Co-authored-by: Restyled.io --- src/app/BUILD.gn | 1 + src/app/WriteHandler.cpp | 9 +++++++-- .../CodegenDataModelProvider.cpp | 8 ++++++-- src/app/common_flags.gni | 7 +++++++ src/app/reporting/Read-DataModel.cpp | 2 ++ 5 files changed, 23 insertions(+), 4 deletions(-) diff --git a/src/app/BUILD.gn b/src/app/BUILD.gn index f3565cf5d9a5e1..13a15f2d7c87be 100644 --- a/src/app/BUILD.gn +++ b/src/app/BUILD.gn @@ -76,6 +76,7 @@ buildconfig_header("app_buildconfig") { "CHIP_DEVICE_CONFIG_DYNAMIC_SERVER=${chip_build_controller_dynamic_server}", "CHIP_CONFIG_ENABLE_BUSY_HANDLING_FOR_OPERATIONAL_SESSION_SETUP=${chip_enable_busy_handling_for_operational_session_setup}", "CHIP_CONFIG_DATA_MODEL_CHECK_DIE_ON_FAILURE=${chip_data_model_check_die_on_failure}", + "CHIP_CONFIG_DATA_MODEL_EXTRA_LOGGING=${chip_data_model_extra_logging}", ] if (chip_use_data_model_interface == "disabled") { diff --git a/src/app/WriteHandler.cpp b/src/app/WriteHandler.cpp index 67a5c7a3ac99d9..e7787bd4dc2cfd 100644 --- a/src/app/WriteHandler.cpp +++ b/src/app/WriteHandler.cpp @@ -108,8 +108,13 @@ void WriteHandler::Close() std::optional WriteHandler::IsListAttributePath(const ConcreteAttributePath & path) { #if CHIP_CONFIG_USE_DATA_MODEL_INTERFACE - VerifyOrReturnValue(mDataModelProvider != nullptr, std::nullopt, - ChipLogError(DataManagement, "Null data model while checking attribute properties.")); + if (mDataModelProvider == nullptr) + { +#if CHIP_CONFIG_DATA_MODEL_EXTRA_LOGGING + ChipLogError(DataManagement, "Null data model while checking attribute properties."); +#endif + return std::nullopt; + } auto info = mDataModelProvider->GetAttributeInfo(path); if (!info.has_value()) diff --git a/src/app/codegen-data-model-provider/CodegenDataModelProvider.cpp b/src/app/codegen-data-model-provider/CodegenDataModelProvider.cpp index 2fb542c768aac0..70253cd1ed9ae5 100644 --- a/src/app/codegen-data-model-provider/CodegenDataModelProvider.cpp +++ b/src/app/codegen-data-model-provider/CodegenDataModelProvider.cpp @@ -140,9 +140,11 @@ std::optional EnumeratorCommandFinder::FindCommandId(Operation operat if (err != CHIP_NO_ERROR) { +#if CHIP_CONFIG_DATA_MODEL_EXTRA_LOGGING // Report the error here since we lose actual error. This generally should NOT be possible as CommandHandlerInterface // usually returns unimplemented or should just work for our use case (our callback never fails) ChipLogError(DataManagement, "Enumerate error: %" CHIP_ERROR_FORMAT, err.Format()); +#endif return kInvalidCommandId; } @@ -155,8 +157,10 @@ std::variant LoadClusterInfo(const ConcreteC DataVersion * versionPtr = emberAfDataVersionStorage(path); if (versionPtr == nullptr) { +#if CHIP_CONFIG_DATA_MODEL_EXTRA_LOGGING ChipLogError(AppServer, "Failed to get data version for %d/" ChipLogFormatMEI, static_cast(path.mEndpointId), ChipLogValueMEI(cluster.clusterId)); +#endif return CHIP_ERROR_NOT_FOUND; } @@ -211,7 +215,7 @@ DataModel::ClusterEntry FirstServerClusterEntry(EndpointId endpointId, const Emb return *entryValue; } -#if CHIP_ERROR_LOGGING +#if CHIP_ERROR_LOGGING && CHIP_CONFIG_DATA_MODEL_EXTRA_LOGGING if (CHIP_ERROR * errValue = std::get_if(&entry)) { ChipLogError(AppServer, "Failed to load cluster entry: %" CHIP_ERROR_FORMAT, errValue->Format()); @@ -571,7 +575,7 @@ std::optional CodegenDataModelProvider::GetClusterInfo(c if (CHIP_ERROR * err = std::get_if(&info)) { -#if CHIP_ERROR_LOGGING +#if CHIP_ERROR_LOGGING && CHIP_CONFIG_DATA_MODEL_EXTRA_LOGGING ChipLogError(AppServer, "Failed to load cluster info: %" CHIP_ERROR_FORMAT, err->Format()); #else (void) err->Format(); diff --git a/src/app/common_flags.gni b/src/app/common_flags.gni index d3e7ce34bf0338..e5d5748153d09c 100644 --- a/src/app/common_flags.gni +++ b/src/app/common_flags.gni @@ -40,4 +40,11 @@ declare_args() { # If/once the chip_use_data_model_interface flag is removed or does not support # a `check` option, this should alwo be removed chip_data_model_check_die_on_failure = false + + # This controls if more logging is supposed to be enabled into the data models. + # This is an optimization for small-flash size devices as extra logging requires + # additional flash for messages & code for formatting. + chip_data_model_extra_logging = + current_os == "linux" || current_os == "ios" || current_os == "mac" || + current_os == "android" } diff --git a/src/app/reporting/Read-DataModel.cpp b/src/app/reporting/Read-DataModel.cpp index 9342961cefdc78..64d027e57bb294 100644 --- a/src/app/reporting/Read-DataModel.cpp +++ b/src/app/reporting/Read-DataModel.cpp @@ -97,7 +97,9 @@ DataModel::ActionReturnStatus RetrieveClusterData(DataModel::Provider * dataMode if (!status.IsOutOfSpaceEncodingResponse()) { DataModel::ActionReturnStatus::StringStorage storage; +#if CHIP_CONFIG_DATA_MODEL_EXTRA_LOGGING ChipLogError(DataManagement, "Failed to read attribute: %s", status.c_str(storage)); +#endif } return status; } From b3223b654cbcc1ad9774e7a3b8b366df68a6a7ba Mon Sep 17 00:00:00 2001 From: Yufeng Wang Date: Fri, 25 Oct 2024 15:09:22 -0700 Subject: [PATCH 125/149] Update the build instructions for Raspberry Pi (#36252) --- examples/fabric-admin/README.md | 6 ++---- examples/fabric-bridge-app/linux/README.md | 6 ++---- examples/fabric-sync/README.md | 6 ++---- 3 files changed, 6 insertions(+), 12 deletions(-) diff --git a/examples/fabric-admin/README.md b/examples/fabric-admin/README.md index c6b4ba7eb3577f..bdfb82d5ac5d8d 100644 --- a/examples/fabric-admin/README.md +++ b/examples/fabric-admin/README.md @@ -23,13 +23,13 @@ For Raspberry Pi 4 example: ### Pull Docker Images ``` -docker pull connectedhomeip/chip-build-vscode:latest +docker pull ghcr.io/project-chip/chip-build-crosscompile:81 ``` ### Run docker ``` -docker run -it -v ~/connectedhomeip:/var/connectedhomeip connectedhomeip/chip-build-vscode:latest /bin/bash +docker run -it -v ~/connectedhomeip:/var/connectedhomeip ghcr.io/project-chip/chip-build-crosscompile:81 /bin/bash ``` ### Build @@ -38,8 +38,6 @@ docker run -it -v ~/connectedhomeip:/var/connectedhomeip connectedhomeip/chip-bu cd /var/connectedhomeip git config --global --add safe.directory /var/connectedhomeip -git config --global --add safe.directory /var/connectedhomeip/third_party/pigweed/repo -git config --global --add safe.directory /var/connectedhomeip/examples/common/QRCode/repo ./scripts/run_in_build_env.sh \ "./scripts/build/build_examples.py \ diff --git a/examples/fabric-bridge-app/linux/README.md b/examples/fabric-bridge-app/linux/README.md index ede6ce26399062..fdb466147e3cf4 100644 --- a/examples/fabric-bridge-app/linux/README.md +++ b/examples/fabric-bridge-app/linux/README.md @@ -100,13 +100,13 @@ defined: Pull Docker Images ``` - docker pull connectedhomeip/chip-build-vscode:latest + docker pull ghcr.io/project-chip/chip-build-crosscompile:81 ``` Run docker ``` - docker run -it -v ~/connectedhomeip:/var/connectedhomeip connectedhomeip/chip-build-vscode:latest /bin/bash + docker run -it -v ~/connectedhomeip:/var/connectedhomeip ghcr.io/project-chip/chip-build-crosscompile:81 /bin/bash ``` Build @@ -115,8 +115,6 @@ defined: cd /var/connectedhomeip git config --global --add safe.directory /var/connectedhomeip - git config --global --add safe.directory /var/connectedhomeip/third_party/pigweed/repo - git config --global --add safe.directory /var/connectedhomeip/examples/common/QRCode/repo ./scripts/run_in_build_env.sh \ "./scripts/build/build_examples.py \ diff --git a/examples/fabric-sync/README.md b/examples/fabric-sync/README.md index 6cbe9da9e9428d..0309218725f02b 100644 --- a/examples/fabric-sync/README.md +++ b/examples/fabric-sync/README.md @@ -92,13 +92,13 @@ defined: Pull Docker Images ``` - docker pull connectedhomeip/chip-build-vscode:latest + docker pull ghcr.io/project-chip/chip-build-crosscompile:81 ``` Run docker ``` - docker run -it -v ~/connectedhomeip:/var/connectedhomeip connectedhomeip/chip-build-vscode:latest /bin/bash + docker run -it -v ~/connectedhomeip:/var/connectedhomeip ghcr.io/project-chip/chip-build-crosscompile:81 /bin/bash ``` Build @@ -107,8 +107,6 @@ defined: cd /var/connectedhomeip git config --global --add safe.directory /var/connectedhomeip - git config --global --add safe.directory /var/connectedhomeip/third_party/pigweed/repo - git config --global --add safe.directory /var/connectedhomeip/examples/common/QRCode/repo ./scripts/run_in_build_env.sh \ "./scripts/build/build_examples.py \ From 377947bbfe219cd4c3abb774f5a12a92f1421262 Mon Sep 17 00:00:00 2001 From: andyg-apple <113489604+andyg-apple@users.noreply.github.com> Date: Sat, 26 Oct 2024 11:15:25 +1300 Subject: [PATCH 126/149] Chime server (#35892) * Added Chime Server * Generated using ./scripts/tools/zap_regen_all.py * Restyled by whitespace * Restyled by clang-format * Addressed review comments, storing attributes in server now * (re)Generated using ./scripts/tools/zap_regen_all.py * playChimeSound -> PlayChimeSound * Changed entries in zcl files * (re)Generate using ./scripts/tools/zap_regen_all.py * Restyled by clang-format * (re)Generated by ./scripts/tools/zap_regen_all.py --------- Co-authored-by: Restyled.io --- .../clusters/chime-server/chime-server.cpp | 279 ++++++++++++++++++ src/app/clusters/chime-server/chime-server.h | 178 +++++++++++ src/app/common/templates/config-data.yaml | 1 + .../zcl/zcl-with-test-extensions.json | 1 + src/app/zap-templates/zcl/zcl.json | 1 + src/app/zap_cluster_list.json | 2 +- .../data_model/controller-clusters.zap | 19 ++ .../zap-generated/attributes/Accessors.cpp | 92 ------ .../zap-generated/attributes/Accessors.h | 12 - .../app-common/zap-generated/callback.h | 6 - 10 files changed, 480 insertions(+), 111 deletions(-) create mode 100644 src/app/clusters/chime-server/chime-server.cpp create mode 100644 src/app/clusters/chime-server/chime-server.h diff --git a/src/app/clusters/chime-server/chime-server.cpp b/src/app/clusters/chime-server/chime-server.cpp new file mode 100644 index 00000000000000..b2b2367f9b826f --- /dev/null +++ b/src/app/clusters/chime-server/chime-server.cpp @@ -0,0 +1,279 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/****************************************************************************' + * @file + * @brief Implementation for the Chime Server Cluster + ***************************************************************************/ + +#include "chime-server.h" + +#include +#include +#include +#include +#include + +using namespace chip; +using namespace chip::app; +using namespace chip::app::Clusters::Chime; +using namespace chip::app::Clusters::Chime::Attributes; +using chip::Protocols::InteractionModel::Status; +using ChimeSoundStructType = Structs::ChimeSoundStruct::Type; + +namespace chip { +namespace app { +namespace Clusters { + +ChimeServer::ChimeServer(EndpointId endpointId, ChimeDelegate & delegate) : + AttributeAccessInterface(MakeOptional(endpointId), Chime::Id), CommandHandlerInterface(MakeOptional(endpointId), Chime::Id), + mDelegate(delegate), mActiveChimeID(0), mEnabled(true) +{ + mDelegate.SetChimeServer(this); +} + +ChimeServer::~ChimeServer() +{ + // null out the ref to us on the delegate + mDelegate.SetChimeServer(nullptr); + + // unregister + CommandHandlerInterfaceRegistry::Instance().UnregisterCommandHandler(this); + AttributeAccessInterfaceRegistry::Instance().Unregister(this); +} + +CHIP_ERROR ChimeServer::Init() +{ + LoadPersistentAttributes(); + + VerifyOrReturnError(AttributeAccessInterfaceRegistry::Instance().Register(this), CHIP_ERROR_INTERNAL); + ReturnErrorOnFailure(CommandHandlerInterfaceRegistry::Instance().RegisterCommandHandler(this)); + return CHIP_NO_ERROR; +} + +void ChimeServer::LoadPersistentAttributes() +{ + // Load Active Chime ID + uint8_t storedActiveChimeID; + CHIP_ERROR err = GetSafeAttributePersistenceProvider()->ReadScalarValue( + ConcreteAttributePath(GetEndpointId(), Chime::Id, ActiveChimeID::Id), storedActiveChimeID); + if (err == CHIP_NO_ERROR) + { + mActiveChimeID = storedActiveChimeID; + } + else + { + // otherwise defaults + ChipLogDetail(Zcl, "Chime: Unable to load the ActiveChimeID attribute from the KVS. Defaulting to %u", mActiveChimeID); + } + + // Load Enabled + bool storedEnabled; + err = GetSafeAttributePersistenceProvider()->ReadScalarValue(ConcreteAttributePath(GetEndpointId(), Chime::Id, Enabled::Id), + storedEnabled); + if (err == CHIP_NO_ERROR) + { + mEnabled = storedEnabled; + } + else + { + // otherwise take the default + ChipLogDetail(Zcl, "Chime: Unable to load the Enabled attribute from the KVS. Defaulting to %u", mEnabled); + } +} + +// AttributeAccessInterface +CHIP_ERROR ChimeServer::Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder) +{ + VerifyOrDie(aPath.mClusterId == Chime::Id); + + switch (aPath.mAttributeId) + { + case ActiveChimeID::Id: + ReturnErrorOnFailure(aEncoder.Encode(mActiveChimeID)); + break; + case Enabled::Id: + ReturnErrorOnFailure(aEncoder.Encode(mEnabled)); + break; + case InstalledChimeSounds::Id: + ChimeServer * cs = this; + CHIP_ERROR err = + aEncoder.EncodeList([cs](const auto & encoder) -> CHIP_ERROR { return cs->EncodeSupportedChimeSounds(encoder); }); + return err; + } + + return CHIP_NO_ERROR; +} + +uint8_t ChimeServer::GetActiveChimeID() const +{ + return mActiveChimeID; +} + +bool ChimeServer::GetEnabled() const +{ + return mEnabled; +} + +// helper method to get the Chime Sounds one by one and encode into a list +CHIP_ERROR ChimeServer::EncodeSupportedChimeSounds(const AttributeValueEncoder::ListEncodeHelper & encoder) +{ + + for (uint8_t i = 0; true; i++) + { + ChimeSoundStructType chimeSound; + + // Get the chime sound + // We pass in a MutableCharSpan to avoid any ownership issues - Delegate needs to use + // CopyCharSpanToMutableCharSpan to copy data in + char buffer[kMaxChimeSoundNameSize]; + MutableCharSpan name(buffer); + auto err = mDelegate.GetChimeSoundByIndex(i, chimeSound.chimeID, name); + + // return if we've run off the end of the Chime Sound List on the delegate + if (err == CHIP_ERROR_PROVIDER_LIST_EXHAUSTED) + { + return CHIP_NO_ERROR; + } + + ReturnErrorOnFailure(err); + + // set the name on the struct + chimeSound.name = name; + + // and now encode the struct + ReturnErrorOnFailure(encoder.Encode(chimeSound)); + } + return CHIP_NO_ERROR; +} + +// helper method to check if the chimeID param is supported by the delegate +bool ChimeServer::IsSupportedChimeID(uint8_t chimeID) +{ + uint8_t supportedChimeID; + for (uint8_t i = 0; mDelegate.GetChimeIDByIndex(i, supportedChimeID) != CHIP_ERROR_PROVIDER_LIST_EXHAUSTED; i++) + { + if (supportedChimeID == chimeID) + { + return true; + } + } + + ChipLogDetail(Zcl, "Cannot find a supported ChimeID with value %u", chimeID); + return false; +} + +CHIP_ERROR ChimeServer::Write(const ConcreteDataAttributePath & aPath, AttributeValueDecoder & aDecoder) +{ + VerifyOrDie(aPath.mClusterId == Chime::Id); + Status status; + + switch (aPath.mAttributeId) + { + case ActiveChimeID::Id: { + uint8_t newValue; + ReturnErrorOnFailure(aDecoder.Decode(newValue)); + status = SetActiveChimeID(newValue); + return StatusIB(status).ToChipError(); + } + case Enabled::Id: { + bool newValue; + ReturnErrorOnFailure(aDecoder.Decode(newValue)); + status = SetEnabled(newValue); + return StatusIB(status).ToChipError(); + } + + default: + // Unknown attribute + return CHIP_IM_GLOBAL_STATUS(UnsupportedAttribute); + } +} + +Status ChimeServer::SetActiveChimeID(uint8_t chimeID) +{ + if (!IsSupportedChimeID(chimeID)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + + bool activeIDChanged = !(mActiveChimeID == chimeID); + if (activeIDChanged) + { + mActiveChimeID = chimeID; + + // Write new value to persistent storage. + auto endpointId = GetEndpointId(); + ConcreteAttributePath path = ConcreteAttributePath(endpointId, Chime::Id, ActiveChimeID::Id); + GetSafeAttributePersistenceProvider()->WriteScalarValue(path, mActiveChimeID); + + // and mark as dirty + MatterReportingAttributeChangeCallback(path); + } + return Protocols::InteractionModel::Status::Success; +} + +Status ChimeServer::SetEnabled(bool Enabled) +{ + bool enableChanged = !(mEnabled == Enabled); + + if (enableChanged) + { + mEnabled = Enabled; + + // Write new value to persistent storage. + auto endpointId = GetEndpointId(); + ConcreteAttributePath path = ConcreteAttributePath(endpointId, Chime::Id, Enabled::Id); + GetSafeAttributePersistenceProvider()->WriteScalarValue(path, mEnabled); + + // and mark as dirty + MatterReportingAttributeChangeCallback(path); + } + + return Protocols::InteractionModel::Status::Success; +} + +void ChimeServer::InvokeCommand(HandlerContext & ctx) +{ + switch (ctx.mRequestPath.mCommandId) + { + case Commands::PlayChimeSound::Id: + CommandHandlerInterface::HandleCommand( + ctx, [this](HandlerContext & ctx, const auto & req) { HandlePlayChimeSound(ctx, req); }); + break; + } +} + +void ChimeServer::HandlePlayChimeSound(HandlerContext & ctx, const Commands::PlayChimeSound::DecodableType & req) +{ + + ChipLogDetail(Zcl, "Chime: PlayChimeSound"); + + // call the delegate to play the chime + Status status = mDelegate.PlayChimeSound(); + ctx.mCommandHandler.AddStatus(ctx.mRequestPath, status); +} + +} // namespace Clusters +} // namespace app +} // namespace chip + +/** @brief Chime Cluster Server Init + * + * Server Init + * + */ +void MatterChimePluginServerInitCallback() {} diff --git a/src/app/clusters/chime-server/chime-server.h b/src/app/clusters/chime-server/chime-server.h new file mode 100644 index 00000000000000..7e98f741987219 --- /dev/null +++ b/src/app/clusters/chime-server/chime-server.h @@ -0,0 +1,178 @@ +/* + * + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +namespace chip { +namespace app { +namespace Clusters { + +class ChimeDelegate; + +class ChimeServer : private AttributeAccessInterface, private CommandHandlerInterface +{ +public: + /** + * Creates a chime server instance. The Init() function needs to be called for this instance to be registered and + * called by the interaction model at the appropriate times. + * @param aEndpointId The endpoint on which this cluster exists. This must match the zap configuration. + * @param aDelegate A reference to the delegate to be used by this server. + * Note: the caller must ensure that the delegate lives throughout the instance's lifetime. + */ + ChimeServer(EndpointId endpointId, ChimeDelegate & delegate); + ~ChimeServer(); + + /** + * Initialise the chime server instance. + * @return Returns an error if the CommandHandler or AttributeHandler registration fails. + */ + CHIP_ERROR Init(); + + // Attribute Setters + /** + * Sets the ActiveChimeID attribute. Note, this also handles writing the new value into non-volatile storage. + * @param chimeSoundID The value to which the ActiveChimeID is to be set. + * @return Returns a ConstraintError if the chimeSoundID value is not valid. Returns Success otherwise. + */ + Protocols::InteractionModel::Status SetActiveChimeID(uint8_t chimeSoundID); + + /** + * Sets the Enabled attribute. Note, this also handles writing the new value into non-volatile storage. + * @param Enabled The value to which the Enabled is to be set. + */ + Protocols::InteractionModel::Status SetEnabled(bool Enabled); + + // Attribute Getters + /** + * @return The Current ActiveChimeID. + */ + uint8_t GetActiveChimeID() const; + + /** + * @return The Enabled attribute.. + */ + bool GetEnabled() const; + + /** + * @return The endpoint ID. + */ + EndpointId GetEndpointId() { return AttributeAccessInterface::GetEndpointId().Value(); } + + // Cluster constants from the spec + static constexpr uint8_t kMaxChimeSoundNameSize = 48; + + // List Change Reporting + /** + * Reports that the contents of the InstalledChimeSounds attribute have changed. + * The device SHALL call this method whenever it changes the list of installed chime sounds. + */ + void ReportInstalledChimeSoundsChange(); + +private: + ChimeDelegate & mDelegate; + + // Attribute local storage + uint8_t mActiveChimeID; + bool mEnabled; + + // AttributeAccessInterface + CHIP_ERROR Read(const ConcreteReadAttributePath & aPath, AttributeValueEncoder & aEncoder) override; + CHIP_ERROR Write(const ConcreteDataAttributePath & aPath, AttributeValueDecoder & aDecoder) override; + + // CommandHandlerInterface + void InvokeCommand(HandlerContext & ctx) override; + void HandlePlayChimeSound(HandlerContext & ctx, const Chime::Commands::PlayChimeSound::DecodableType & req); + + // Helpers + // Loads all the persistent attributes from the KVS. + void LoadPersistentAttributes(); + + // Checks if the chimeID is supported by the delegate + bool IsSupportedChimeID(uint8_t chimeID); + + // Encodes all Installed Chime Sounds + CHIP_ERROR EncodeSupportedChimeSounds(const AttributeValueEncoder::ListEncodeHelper & encoder); +}; + +/** @brief + * Defines methods for implementing application-specific logic for the Chime Cluster. + */ +class ChimeDelegate +{ +public: + ChimeDelegate() = default; + + virtual ~ChimeDelegate() = default; + + /** + * Get the installed chime sounds. + * @param index The index of the chime sound to be returned. It is assumed that chime sounds are indexable from 0 and with no + * gaps. + * @param chimeID a reference to the uint8_t variable that is to contain the ChimeID value. + * @param name A reference to the mutable char span which will be mutated to receive the chime sound name on success. Use + * CopyCharSpanToMutableCharSpan to copy into the MutableCharSpan. + * @return Returns a CHIP_NO_ERROR if there was no error and the chime sound details were returned successfully, + * CHIP_ERROR_NOT_FOUND if the index in beyond the list of available chime sounds. + * + * Note: This is used by the SDK to populate the InstalledChimeSounds attribute. If the contents of this list change, + * the device SHALL call the Instance's ReportInstalledChimeSoundsChange method to report that this attribute has changed. + */ + virtual CHIP_ERROR GetChimeSoundByIndex(uint8_t chimeIndex, uint8_t & chimeID, MutableCharSpan & name) = 0; + + /** + * Get the installed chime sound IDs + * @param index The index of the chime ID to be returned. It is assumed that chime sounds are indexable from 0 and with no + * gaps. + * @param chimeID a reference to the uint8_t variable that is to contain the ChimeID value. + * @return Returns a CHIP_NO_ERROR if there was no error and the ChimeID was returned successfully, + * CHIP_ERROR_NOT_FOUND if the index in beyond the list of available chime sounds. + * + * Note: This is used by the SDK to help populate the InstalledChimeSounds attribute. If the contents of this list change, + * the device SHALL call the Instance's ReportInstalledChimeSoundsChange method to report that this attribute has changed. + */ + virtual CHIP_ERROR GetChimeIDByIndex(uint8_t chimeIndex, uint8_t & chimeID) = 0; + + // Commands + /** + * @brief Delegate should implement a handler to play the currently active chime sound. + * It should report Status::Success if successful and may + * return other Status codes if it fails + */ + virtual Protocols::InteractionModel::Status PlayChimeSound() = 0; + +protected: + friend class ChimeServer; + + ChimeServer * mChimeServer = nullptr; + + // sets the Chime Server pointer + void SetChimeServer(ChimeServer * chimeServer) { mChimeServer = chimeServer; } + ChimeServer * GetChimeServer() const { return mChimeServer; } +}; + +} // namespace Clusters +} // namespace app +} // namespace chip diff --git a/src/app/common/templates/config-data.yaml b/src/app/common/templates/config-data.yaml index 61e7c45582268a..f5259748d9421c 100644 --- a/src/app/common/templates/config-data.yaml +++ b/src/app/common/templates/config-data.yaml @@ -36,6 +36,7 @@ CommandHandlerInterfaceOnlyClusters: - RVC Operational State - Sample MEI - Microwave Oven Control + - Chime - Energy EVSE - Energy EVSE Mode - Device Energy Management diff --git a/src/app/zap-templates/zcl/zcl-with-test-extensions.json b/src/app/zap-templates/zcl/zcl-with-test-extensions.json index 0eba8fc692d6d8..39301cdc30cecc 100644 --- a/src/app/zap-templates/zcl/zcl-with-test-extensions.json +++ b/src/app/zap-templates/zcl/zcl-with-test-extensions.json @@ -196,6 +196,7 @@ "MaxPathsPerInvoke" ], "Bridged Device Basic Information": ["ProductAppearance"], + "Chime": ["ActiveChimeID", "Enabled"], "Descriptor": ["ClusterRevision", "FeatureMap"], "Device Energy Management": [ "ESAType", diff --git a/src/app/zap-templates/zcl/zcl.json b/src/app/zap-templates/zcl/zcl.json index 6907cfea0eb19f..c2de6acabf2951 100644 --- a/src/app/zap-templates/zcl/zcl.json +++ b/src/app/zap-templates/zcl/zcl.json @@ -190,6 +190,7 @@ "MaxPathsPerInvoke" ], "Bridged Device Basic Information": ["ProductAppearance"], + "Chime": ["ActiveChimeID", "Enabled"], "Descriptor": ["ClusterRevision", "FeatureMap"], "Device Energy Management": [ "ESAType", diff --git a/src/app/zap_cluster_list.json b/src/app/zap_cluster_list.json index e38e8809616f45..4de99f1b7aaf3d 100644 --- a/src/app/zap_cluster_list.json +++ b/src/app/zap_cluster_list.json @@ -171,7 +171,7 @@ "concentration-measurement-server" ], "CHANNEL_CLUSTER": ["channel-server"], - "CHIME_CLUSTER": [], + "CHIME_CLUSTER": ["chime-server"], "COLOR_CONTROL_CLUSTER": ["color-control-server"], "COMMISSIONER_CONTROL_CLUSTER": ["commissioner-control-server"], "COMMISSIONING_CLUSTER": [], diff --git a/src/controller/data_model/controller-clusters.zap b/src/controller/data_model/controller-clusters.zap index 1a1f8539267101..8c1eba99077039 100644 --- a/src/controller/data_model/controller-clusters.zap +++ b/src/controller/data_model/controller-clusters.zap @@ -2955,6 +2955,25 @@ } ] }, + { + "name": "Chime", + "code": 1366, + "mfgCode": null, + "define": "CHIME_CLUSTER", + "side": "client", + "enabled": 1, + "apiMaturity": "provisional", + "commands": [ + { + "name": "PlayChimeSound", + "code": 0, + "mfgCode": null, + "source": "client", + "isIncoming": 0, + "isEnabled": 1 + } + ] + }, { "name": "Unit Testing", "code": 4294048773, diff --git a/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp b/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp index c23e0e252bbb99..a1caa8052ae71e 100644 --- a/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp +++ b/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp @@ -38730,98 +38730,6 @@ Protocols::InteractionModel::Status Set(EndpointId endpoint, uint16_t value) namespace Chime { namespace Attributes { -namespace ActiveChimeID { - -Protocols::InteractionModel::Status Get(EndpointId endpoint, uint8_t * value) -{ - using Traits = NumericAttributeTraits; - Traits::StorageType temp; - uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); - Protocols::InteractionModel::Status status = emberAfReadAttribute(endpoint, Clusters::Chime::Id, Id, readable, sizeof(temp)); - VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); - if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - *value = Traits::StorageToWorking(temp); - return status; -} - -Protocols::InteractionModel::Status Set(EndpointId endpoint, uint8_t value, MarkAttributeDirty markDirty) -{ - using Traits = NumericAttributeTraits; - if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - Traits::StorageType storageValue; - Traits::WorkingToStorage(value, storageValue); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(ConcreteAttributePath(endpoint, Clusters::Chime::Id, Id), - EmberAfWriteDataInput(writable, ZCL_INT8U_ATTRIBUTE_TYPE).SetMarkDirty(markDirty)); -} - -Protocols::InteractionModel::Status Set(EndpointId endpoint, uint8_t value) -{ - using Traits = NumericAttributeTraits; - if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - Traits::StorageType storageValue; - Traits::WorkingToStorage(value, storageValue); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::Chime::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); -} - -} // namespace ActiveChimeID - -namespace Enabled { - -Protocols::InteractionModel::Status Get(EndpointId endpoint, bool * value) -{ - using Traits = NumericAttributeTraits; - Traits::StorageType temp; - uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); - Protocols::InteractionModel::Status status = emberAfReadAttribute(endpoint, Clusters::Chime::Id, Id, readable, sizeof(temp)); - VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); - if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - *value = Traits::StorageToWorking(temp); - return status; -} - -Protocols::InteractionModel::Status Set(EndpointId endpoint, bool value, MarkAttributeDirty markDirty) -{ - using Traits = NumericAttributeTraits; - if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - Traits::StorageType storageValue; - Traits::WorkingToStorage(value, storageValue); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(ConcreteAttributePath(endpoint, Clusters::Chime::Id, Id), - EmberAfWriteDataInput(writable, ZCL_BOOLEAN_ATTRIBUTE_TYPE).SetMarkDirty(markDirty)); -} - -Protocols::InteractionModel::Status Set(EndpointId endpoint, bool value) -{ - using Traits = NumericAttributeTraits; - if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) - { - return Protocols::InteractionModel::Status::ConstraintError; - } - Traits::StorageType storageValue; - Traits::WorkingToStorage(value, storageValue); - uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::Chime::Id, Id, writable, ZCL_BOOLEAN_ATTRIBUTE_TYPE); -} - -} // namespace Enabled - namespace FeatureMap { Protocols::InteractionModel::Status Get(EndpointId endpoint, uint32_t * value) diff --git a/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.h b/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.h index 11e2228564e6ab..bb11fdf51607d1 100644 --- a/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.h +++ b/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.h @@ -5861,18 +5861,6 @@ Protocols::InteractionModel::Status Set(EndpointId endpoint, uint16_t value, Mar namespace Chime { namespace Attributes { -namespace ActiveChimeID { -Protocols::InteractionModel::Status Get(EndpointId endpoint, uint8_t * value); // int8u -Protocols::InteractionModel::Status Set(EndpointId endpoint, uint8_t value); -Protocols::InteractionModel::Status Set(EndpointId endpoint, uint8_t value, MarkAttributeDirty markDirty); -} // namespace ActiveChimeID - -namespace Enabled { -Protocols::InteractionModel::Status Get(EndpointId endpoint, bool * value); // boolean -Protocols::InteractionModel::Status Set(EndpointId endpoint, bool value); -Protocols::InteractionModel::Status Set(EndpointId endpoint, bool value, MarkAttributeDirty markDirty); -} // namespace Enabled - namespace FeatureMap { Protocols::InteractionModel::Status Get(EndpointId endpoint, uint32_t * value); // bitmap32 Protocols::InteractionModel::Status Set(EndpointId endpoint, uint32_t value); diff --git a/zzz_generated/app-common/app-common/zap-generated/callback.h b/zzz_generated/app-common/app-common/zap-generated/callback.h index 90be2632818072..430eb0bd3821fd 100644 --- a/zzz_generated/app-common/app-common/zap-generated/callback.h +++ b/zzz_generated/app-common/app-common/zap-generated/callback.h @@ -6930,12 +6930,6 @@ bool emberAfWebRTCTransportRequestorClusterICECandidateCallback( bool emberAfWebRTCTransportRequestorClusterEndCallback( chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, const chip::app::Clusters::WebRTCTransportRequestor::Commands::End::DecodableType & commandData); -/** - * @brief Chime Cluster PlayChimeSound Command callback (from client) - */ -bool emberAfChimeClusterPlayChimeSoundCallback( - chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, - const chip::app::Clusters::Chime::Commands::PlayChimeSound::DecodableType & commandData); /** * @brief Commissioner Control Cluster RequestCommissioningApproval Command callback (from client) */ From 38c3e91dc8ac927f62a2c0b00bf28b68de8d1543 Mon Sep 17 00:00:00 2001 From: sarthak shaha Date: Fri, 25 Oct 2024 19:51:55 -0400 Subject: [PATCH 127/149] [SILABS] added sl_matter_test_event_trigger_config for SLC use case (#36250) * added sl_matter_test_event_trigger_config for SLC use case * Restyled by clang-format * condition fix --------- Co-authored-by: Restyled.io --- .../platform/silabs/provision/ProvisionStorageDefault.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/examples/platform/silabs/provision/ProvisionStorageDefault.cpp b/examples/platform/silabs/provision/ProvisionStorageDefault.cpp index 6a889b5bffeb06..5180e031f07238 100644 --- a/examples/platform/silabs/provision/ProvisionStorageDefault.cpp +++ b/examples/platform/silabs/provision/ProvisionStorageDefault.cpp @@ -29,6 +29,11 @@ #include #include #include +#ifndef NDEBUG +#if defined(SL_MATTER_TEST_EVENT_TRIGGER_ENABLED) && (SL_MATTER_GN_BUILD == 0) +#include +#endif // defined(SL_MATTER_TEST_EVENT_TRIGGER_ENABLED) && (SL_MATTER_GN_BUILD == 0) +#endif // NDEBUG #ifdef OTA_ENCRYPTION_ENABLE #include #endif // OTA_ENCRYPTION_ENABLE From ac43b689b96646dbd07c362ce33983f552fc498b Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Fri, 25 Oct 2024 23:03:35 -0400 Subject: [PATCH 128/149] Try to fix random CI failures by using a random port in TestCommissioningWindowManager. (#36255) --- src/app/tests/TestCommissioningWindowManager.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/app/tests/TestCommissioningWindowManager.cpp b/src/app/tests/TestCommissioningWindowManager.cpp index 5df7a4b6ce861d..297a95e299a30b 100644 --- a/src/app/tests/TestCommissioningWindowManager.cpp +++ b/src/app/tests/TestCommissioningWindowManager.cpp @@ -113,9 +113,8 @@ class TestCommissioningWindowManager : public ::testing::Test static chip::SimpleTestEventTriggerDelegate sSimpleTestEventTriggerDelegate; initParams.testEventTriggerDelegate = &sSimpleTestEventTriggerDelegate; (void) initParams.InitializeStaticResourcesBeforeServerInit(); - // Set a randomized server port(slightly shifted from CHIP_PORT) for testing - initParams.operationalServicePort = - static_cast(initParams.operationalServicePort + chip::Crypto::GetRandU16() % 20); + // Use whatever server port the kernel decides to give us. + initParams.operationalServicePort = 0; ASSERT_EQ(chip::Server::GetInstance().Init(initParams), CHIP_NO_ERROR); From 17a2aad964e699a7c79714a3d747f12cbc3be433 Mon Sep 17 00:00:00 2001 From: Vivien Nicolas Date: Mon, 28 Oct 2024 11:40:35 +0100 Subject: [PATCH 129/149] =?UTF-8?q?[darwin-framework-tool]=20Use=20per=20c?= =?UTF-8?q?ommissioner=20storage=20by=20default=20inste=E2=80=A6=20(#36194?= =?UTF-8?q?)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * [darwin-framework-tool] Make the issuerId of the root certificate constant * [darwin-framework-tool] Use per commissioner storage by default instead of shared storage --- .../darwin-framework-tool/commands/common/CHIPCommandBridge.h | 2 +- .../commands/common/CHIPCommandBridge.mm | 2 +- .../commands/common/CertificateIssuer.mm | 4 +++- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/examples/darwin-framework-tool/commands/common/CHIPCommandBridge.h b/examples/darwin-framework-tool/commands/common/CHIPCommandBridge.h index 3466972f1f6f25..477e1ed8105101 100644 --- a/examples/darwin-framework-tool/commands/common/CHIPCommandBridge.h +++ b/examples/darwin-framework-tool/commands/common/CHIPCommandBridge.h @@ -42,7 +42,7 @@ class CHIPCommandBridge : public Command { "commissioner-name. Interactive mode will only set a single commissioner on the inital command. " "The commissioner node ID will be persisted until a different one is specified."); AddArgument("commissioner-shared-storage", 0, 1, &mCommissionerSharedStorage, - "Use a shared storage instance instead of individual storage for each commissioner. Default is true."); + "Use a shared storage instance instead of individual storage for each commissioner. Default is false."); AddArgument("paa-trust-store-path", &mPaaTrustStorePath, "Path to directory holding PAA certificate information. Can be absolute or relative to the current working " "directory."); diff --git a/examples/darwin-framework-tool/commands/common/CHIPCommandBridge.mm b/examples/darwin-framework-tool/commands/common/CHIPCommandBridge.mm index 85ce8d8935bec0..ee21248594a7a4 100644 --- a/examples/darwin-framework-tool/commands/common/CHIPCommandBridge.mm +++ b/examples/darwin-framework-tool/commands/common/CHIPCommandBridge.mm @@ -139,7 +139,7 @@ productAttestationAuthorityCertificates = nil; } - sUseSharedStorage = mCommissionerSharedStorage.ValueOr(true); + sUseSharedStorage = mCommissionerSharedStorage.ValueOr(false); if (sUseSharedStorage) { return SetUpStackWithSharedStorage(productAttestationAuthorityCertificates); } diff --git a/examples/darwin-framework-tool/commands/common/CertificateIssuer.mm b/examples/darwin-framework-tool/commands/common/CertificateIssuer.mm index bd12878c6addd7..c86a41490b08c5 100644 --- a/examples/darwin-framework-tool/commands/common/CertificateIssuer.mm +++ b/examples/darwin-framework-tool/commands/common/CertificateIssuer.mm @@ -21,6 +21,8 @@ #include +constexpr const uint32_t kIssuerId = 12345678; + @interface CertificateIssuer () - (MTRCertificateDERBytes _Nullable)issueOperationalCertificateForNodeID:(NSNumber *)nodeID fabricID:(NSNumber *)fabricID @@ -67,7 +69,7 @@ - (void)startWithStorage:(id)storage return; } - __auto_type * rootCertificate = [MTRCertificates createRootCertificate:signingKey issuerID:nil fabricID:nil error:error]; + __auto_type * rootCertificate = [MTRCertificates createRootCertificate:signingKey issuerID:@(kIssuerId) fabricID:nil error:error]; if (nil == rootCertificate) { *error = [NSError errorWithDomain:@"Error" code:0 userInfo:@{ @"reason" : @"Error creating root certificate" }]; return; From acf1df3f99a8e6c8e4669fc5e5bff2638383e295 Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Mon, 28 Oct 2024 08:38:52 -0400 Subject: [PATCH 130/149] Update First/Next accepted command iteration in CodegenDataModelProvider to save flash (#36247) * This saves 136 bytes... * More changes to save slightly more flash for code * Restyle * Fix typo * Fix includes --------- Co-authored-by: Andrei Litvin --- .../CodegenDataModelProvider.cpp | 256 +++++++----------- .../CodegenDataModelProvider.h | 65 ++++- 2 files changed, 158 insertions(+), 163 deletions(-) diff --git a/src/app/codegen-data-model-provider/CodegenDataModelProvider.cpp b/src/app/codegen-data-model-provider/CodegenDataModelProvider.cpp index 70253cd1ed9ae5..dd320e5d03780a 100644 --- a/src/app/codegen-data-model-provider/CodegenDataModelProvider.cpp +++ b/src/app/codegen-data-model-provider/CodegenDataModelProvider.cpp @@ -31,6 +31,7 @@ #include #include #include +#include // separated out for code-reuse #include @@ -40,84 +41,32 @@ namespace chip { namespace app { -namespace { +namespace detail { -/// Handles going through callback-based enumeration of generated/accepted commands -/// for CommandHandlerInterface based items. -/// -/// Offers the ability to focus on some operation for finding a given -/// command id: -/// - FindFirst will return the first found element -/// - FindExact finds the element with the given id -/// - FindNext finds the element following the given id -class EnumeratorCommandFinder -{ -public: - using HandlerCallbackFunction = CHIP_ERROR (CommandHandlerInterface::*)(const ConcreteClusterPath &, - CommandHandlerInterface::CommandIdCallback, void *); - - enum class Operation - { - kFindFirst, // Find the first value in the list - kFindExact, // Find the given value - kFindNext // Find the value AFTER this value - }; - - EnumeratorCommandFinder(HandlerCallbackFunction callback) : - mCallback(callback), mOperation(Operation::kFindFirst), mTarget(kInvalidCommandId) - {} - - /// Find the given command ID that matches the given operation/path. - /// - /// If operation is kFindFirst, then path commandID is ignored. Otherwise it is used as a key to - /// kFindExact or kFindNext. - /// - /// Returns: - /// - std::nullopt if no command found using the command handler interface - /// - kInvalidCommandId if the find failed (but command handler interface does provide a list) - /// - valid id if command handler interface usage succeeds - std::optional FindCommandId(Operation operation, const ConcreteCommandPath & path); - - /// Uses FindCommandId to find the given command and loads the command entry data - std::optional FindCommandEntry(Operation operation, const ConcreteCommandPath & path); - -private: - HandlerCallbackFunction mCallback; - Operation mOperation; - CommandId mTarget; - std::optional mFound = std::nullopt; - - Loop HandlerCallback(CommandId id) - { - switch (mOperation) +Loop EnumeratorCommandFinder::HandlerCallback(CommandId id) +{ + switch (mOperation) + { + case Operation::kFindFirst: + mFound = id; + return Loop::Break; + case Operation::kFindExact: + if (mTarget == id) { - case Operation::kFindFirst: - mFound = id; + mFound = id; // found it return Loop::Break; - case Operation::kFindExact: - if (mTarget == id) - { - mFound = id; // found it - return Loop::Break; - } - break; - case Operation::kFindNext: - if (mTarget == id) - { - // Once we found the ID, get the first - mOperation = Operation::kFindFirst; - } - break; } - return Loop::Continue; // keep searching - } - - static Loop HandlerCallbackFn(CommandId id, void * context) - { - auto self = static_cast(context); - return self->HandlerCallback(id); + break; + case Operation::kFindNext: + if (mTarget == id) + { + // Once we found the ID, get the first + mOperation = Operation::kFindFirst; + } + break; } -}; + return Loop::Continue; // keep searching +} std::optional EnumeratorCommandFinder::FindCommandId(Operation operation, const ConcreteCommandPath & path) { @@ -151,6 +100,22 @@ std::optional EnumeratorCommandFinder::FindCommandId(Operation operat return mFound.value_or(kInvalidCommandId); } +} // namespace detail + +using detail::EnumeratorCommandFinder; + +namespace { + +const chip::CommandId * AcceptedCommands(const EmberAfCluster & cluster) +{ + return cluster.acceptedCommandList; +} + +const chip::CommandId * GeneratedCommands(const EmberAfCluster & cluster) +{ + return cluster.generatedCommandList; +} + /// Load the cluster information into the specified destination std::variant LoadClusterInfo(const ConcreteClusterPath & path, const EmberAfCluster & cluster) { @@ -282,20 +247,6 @@ DataModel::CommandEntry CommandEntryFrom(const ConcreteClusterPath & clusterPath return entry; } -std::optional EnumeratorCommandFinder::FindCommandEntry(Operation operation, - const ConcreteCommandPath & path) -{ - - std::optional id = FindCommandId(operation, path); - - if (!id.has_value()) - { - return std::nullopt; - } - - return (*id == kInvalidCommandId) ? DataModel::CommandEntry::kInvalid : CommandEntryFrom(path, *id); -} - // TODO: DeviceTypeEntry content is IDENTICAL to EmberAfDeviceType, so centralizing // to a common type is probably better. Need to figure out dependencies since // this would make ember return datamodel-provider types. @@ -639,6 +590,35 @@ const EmberAfCluster * CodegenDataModelProvider::FindServerCluster(const Concret return cluster; } +CommandId CodegenDataModelProvider::FindCommand(const ConcreteCommandPath & path, detail::EnumeratorCommandFinder & handlerFinder, + detail::EnumeratorCommandFinder::Operation operation, + CodegenDataModelProvider::EmberCommandListIterator & emberIterator, + CommandListGetter commandListGetter) +{ + + std::optional handlerCommandId = handlerFinder.FindCommandId(operation, path); + if (handlerCommandId.has_value()) + { + return *handlerCommandId; + } + + const EmberAfCluster * cluster = FindServerCluster(path); + VerifyOrReturnValue(cluster != nullptr, kInvalidCommandId); + + const CommandId * commandList = commandListGetter(*cluster); + + switch (operation) + { + case EnumeratorCommandFinder::Operation::kFindFirst: + return emberIterator.First(commandList).value_or(kInvalidCommandId); + case EnumeratorCommandFinder::Operation::kFindNext: + return emberIterator.Next(commandList, path.mCommandId).value_or(kInvalidCommandId); + case EnumeratorCommandFinder::Operation::kFindExact: + default: + return emberIterator.Exists(commandList, path.mCommandId) ? path.mCommandId : kInvalidCommandId; + } +} + DataModel::AttributeEntry CodegenDataModelProvider::NextAttribute(const ConcreteAttributePath & before) { const EmberAfCluster * cluster = FindServerCluster(before); @@ -686,106 +666,58 @@ std::optional CodegenDataModelProvider::GetAttributeIn DataModel::CommandEntry CodegenDataModelProvider::FirstAcceptedCommand(const ConcreteClusterPath & path) { - auto handlerInterfaceValue = EnumeratorCommandFinder(&CommandHandlerInterface::EnumerateAcceptedCommands) - .FindCommandEntry(EnumeratorCommandFinder::Operation::kFindFirst, - ConcreteCommandPath(path.mEndpointId, path.mClusterId, kInvalidCommandId)); + EnumeratorCommandFinder handlerFinder(&CommandHandlerInterface::EnumerateAcceptedCommands); - if (handlerInterfaceValue.has_value()) - { - return *handlerInterfaceValue; - } + CommandId commandId = + FindCommand(ConcreteCommandPath(path.mEndpointId, path.mClusterId, kInvalidCommandId), handlerFinder, + detail::EnumeratorCommandFinder::Operation::kFindFirst, mAcceptedCommandsIterator, AcceptedCommands); - const EmberAfCluster * cluster = FindServerCluster(path); - - VerifyOrReturnValue(cluster != nullptr, DataModel::CommandEntry::kInvalid); - - std::optional commandId = mAcceptedCommandsIterator.First(cluster->acceptedCommandList); - VerifyOrReturnValue(commandId.has_value(), DataModel::CommandEntry::kInvalid); - - return CommandEntryFrom(path, *commandId); + VerifyOrReturnValue(commandId != kInvalidCommandId, DataModel::CommandEntry::kInvalid); + return CommandEntryFrom(path, commandId); } DataModel::CommandEntry CodegenDataModelProvider::NextAcceptedCommand(const ConcreteCommandPath & before) { - // TODO: `Next` redirecting to a callback is slow O(n^2). - // see https://github.com/project-chip/connectedhomeip/issues/35790 - auto handlerInterfaceValue = EnumeratorCommandFinder(&CommandHandlerInterface::EnumerateAcceptedCommands) - .FindCommandEntry(EnumeratorCommandFinder::Operation::kFindNext, before); - - if (handlerInterfaceValue.has_value()) - { - return *handlerInterfaceValue; - } - - const EmberAfCluster * cluster = FindServerCluster(before); - VerifyOrReturnValue(cluster != nullptr, DataModel::CommandEntry::kInvalid); + EnumeratorCommandFinder handlerFinder(&CommandHandlerInterface::EnumerateAcceptedCommands); + CommandId commandId = FindCommand(before, handlerFinder, detail::EnumeratorCommandFinder::Operation::kFindNext, + mAcceptedCommandsIterator, AcceptedCommands); - std::optional commandId = mAcceptedCommandsIterator.Next(cluster->acceptedCommandList, before.mCommandId); - VerifyOrReturnValue(commandId.has_value(), DataModel::CommandEntry::kInvalid); - - return CommandEntryFrom(before, *commandId); + VerifyOrReturnValue(commandId != kInvalidCommandId, DataModel::CommandEntry::kInvalid); + return CommandEntryFrom(before, commandId); } std::optional CodegenDataModelProvider::GetAcceptedCommandInfo(const ConcreteCommandPath & path) { - auto handlerInterfaceValue = EnumeratorCommandFinder(&CommandHandlerInterface::EnumerateAcceptedCommands) - .FindCommandEntry(EnumeratorCommandFinder::Operation::kFindExact, path); - if (handlerInterfaceValue.has_value()) - { - return handlerInterfaceValue->IsValid() ? std::make_optional(handlerInterfaceValue->info) : std::nullopt; - } - - const EmberAfCluster * cluster = FindServerCluster(path); + EnumeratorCommandFinder handlerFinder(&CommandHandlerInterface::EnumerateAcceptedCommands); + CommandId commandId = FindCommand(path, handlerFinder, detail::EnumeratorCommandFinder::Operation::kFindExact, + mAcceptedCommandsIterator, AcceptedCommands); - VerifyOrReturnValue(cluster != nullptr, std::nullopt); - VerifyOrReturnValue(mAcceptedCommandsIterator.Exists(cluster->acceptedCommandList, path.mCommandId), std::nullopt); - - return CommandEntryFrom(path, path.mCommandId).info; + VerifyOrReturnValue(commandId != kInvalidCommandId, std::nullopt); + return CommandEntryFrom(path, commandId).info; } ConcreteCommandPath CodegenDataModelProvider::FirstGeneratedCommand(const ConcreteClusterPath & path) { - std::optional commandId = - EnumeratorCommandFinder(&CommandHandlerInterface::EnumerateGeneratedCommands) - .FindCommandId(EnumeratorCommandFinder::Operation::kFindFirst, - ConcreteCommandPath(path.mEndpointId, path.mClusterId, kInvalidCommandId)); - if (commandId.has_value()) - { - return *commandId == kInvalidCommandId ? kInvalidCommandPath - : ConcreteCommandPath(path.mEndpointId, path.mClusterId, *commandId); - } + EnumeratorCommandFinder handlerFinder(&CommandHandlerInterface::EnumerateGeneratedCommands); + CommandId commandId = + FindCommand(ConcreteCommandPath(path.mEndpointId, path.mClusterId, kInvalidCommandId), handlerFinder, + detail::EnumeratorCommandFinder::Operation::kFindFirst, mGeneratedCommandsIterator, GeneratedCommands); - const EmberAfCluster * cluster = FindServerCluster(path); - VerifyOrReturnValue(cluster != nullptr, kInvalidCommandPath); - - commandId = mGeneratedCommandsIterator.First(cluster->generatedCommandList); - VerifyOrReturnValue(commandId.has_value(), kInvalidCommandPath); - return ConcreteCommandPath(path.mEndpointId, path.mClusterId, *commandId); + VerifyOrReturnValue(commandId != kInvalidCommandId, kInvalidCommandPath); + return ConcreteCommandPath(path.mEndpointId, path.mClusterId, commandId); } ConcreteCommandPath CodegenDataModelProvider::NextGeneratedCommand(const ConcreteCommandPath & before) { - // TODO: `Next` redirecting to a callback is slow O(n^2). - // see https://github.com/project-chip/connectedhomeip/issues/35790 - auto nextId = EnumeratorCommandFinder(&CommandHandlerInterface::EnumerateGeneratedCommands) - .FindCommandId(EnumeratorCommandFinder::Operation::kFindNext, before); - - if (nextId.has_value()) - { - return (*nextId == kInvalidCommandId) ? kInvalidCommandPath - : ConcreteCommandPath(before.mEndpointId, before.mClusterId, *nextId); - } - - const EmberAfCluster * cluster = FindServerCluster(before); - - VerifyOrReturnValue(cluster != nullptr, kInvalidCommandPath); + EnumeratorCommandFinder handlerFinder(&CommandHandlerInterface::EnumerateGeneratedCommands); - std::optional commandId = mGeneratedCommandsIterator.Next(cluster->generatedCommandList, before.mCommandId); - VerifyOrReturnValue(commandId.has_value(), kInvalidCommandPath); + CommandId commandId = FindCommand(before, handlerFinder, detail::EnumeratorCommandFinder::Operation::kFindNext, + mGeneratedCommandsIterator, GeneratedCommands); - return ConcreteCommandPath(before.mEndpointId, before.mClusterId, *commandId); + VerifyOrReturnValue(commandId != kInvalidCommandId, kInvalidCommandPath); + return ConcreteCommandPath(before.mEndpointId, before.mClusterId, commandId); } std::optional CodegenDataModelProvider::FirstDeviceType(EndpointId endpoint) diff --git a/src/app/codegen-data-model-provider/CodegenDataModelProvider.h b/src/app/codegen-data-model-provider/CodegenDataModelProvider.h index 085ae67ec392ab..5c87e264fd2aea 100644 --- a/src/app/codegen-data-model-provider/CodegenDataModelProvider.h +++ b/src/app/codegen-data-model-provider/CodegenDataModelProvider.h @@ -16,14 +16,71 @@ */ #pragma once -#include "app/data-model-provider/ActionReturnStatus.h" +#include "app/ConcreteCommandPath.h" #include +#include +#include #include namespace chip { namespace app { +namespace detail { + +/// Handles going through callback-based enumeration of generated/accepted commands +/// for CommandHandlerInterface based items. +/// +/// Offers the ability to focus on some operation for finding a given +/// command id: +/// - FindFirst will return the first found element +/// - FindExact finds the element with the given id +/// - FindNext finds the element following the given id +class EnumeratorCommandFinder +{ +public: + using HandlerCallbackFunction = CHIP_ERROR (CommandHandlerInterface::*)(const ConcreteClusterPath &, + CommandHandlerInterface::CommandIdCallback, void *); + + enum class Operation + { + kFindFirst, // Find the first value in the list + kFindExact, // Find the given value + kFindNext // Find the value AFTER this value + }; + + EnumeratorCommandFinder(HandlerCallbackFunction callback) : + mCallback(callback), mOperation(Operation::kFindFirst), mTarget(kInvalidCommandId) + {} + + /// Find the given command ID that matches the given operation/path. + /// + /// If operation is kFindFirst, then path commandID is ignored. Otherwise it is used as a key to + /// kFindExact or kFindNext. + /// + /// Returns: + /// - std::nullopt if no command found using the command handler interface + /// - kInvalidCommandId if the find failed (but command handler interface does provide a list) + /// - valid id if command handler interface usage succeeds + std::optional FindCommandId(Operation operation, const ConcreteCommandPath & path); + +private: + HandlerCallbackFunction mCallback; + Operation mOperation; + CommandId mTarget; + std::optional mFound = std::nullopt; + + Loop HandlerCallback(CommandId id); + + static Loop HandlerCallbackFn(CommandId id, void * context) + { + auto self = static_cast(context); + return self->HandlerCallback(id); + } +}; + +} // namespace detail + /// An implementation of `InteractionModel::Model` that relies on code-generation /// via zap/ember. /// @@ -152,6 +209,12 @@ class CodegenDataModelProvider : public chip::app::DataModel::Provider /// Find the index of the given endpoint id std::optional TryFindEndpointIndex(chip::EndpointId id) const; + + using CommandListGetter = const chip::CommandId *(const EmberAfCluster &); + + CommandId FindCommand(const ConcreteCommandPath & path, detail::EnumeratorCommandFinder & handlerFinder, + detail::EnumeratorCommandFinder::Operation operation, + CodegenDataModelProvider::EmberCommandListIterator & emberIterator, CommandListGetter commandListGetter); }; } // namespace app From 0b981e720d3df2b76a6002bf750323f3db906853 Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Mon, 28 Oct 2024 08:58:11 -0400 Subject: [PATCH 131/149] Move decodable lists bits as a non-template class to save flash (#36253) Co-authored-by: Andrei Litvin --- src/app/data-model/DecodableList.h | 115 ++++++++++++++++------------- 1 file changed, 64 insertions(+), 51 deletions(-) diff --git a/src/app/data-model/DecodableList.h b/src/app/data-model/DecodableList.h index bff54ca532bbde..b05db43c1522bf 100644 --- a/src/app/data-model/DecodableList.h +++ b/src/app/data-model/DecodableList.h @@ -27,6 +27,68 @@ namespace chip { namespace app { namespace DataModel { +namespace detail { + +/* + * Base class of DecodableList to minimize template usage + */ +class DecodableListBase +{ +public: + DecodableListBase() { ClearReader(); } + + /* + * @brief + * + * This call stores a TLV reader positioned on the list this class is to manage. + * + * Specifically, the passed-in reader should be pointing into the list just after + * having called `OpenContainer` on the list element. + */ + void SetReader(const TLV::TLVReader & reader) { mReader = reader; } + + /* + * @brief + * + * This call clears the TLV reader managed by this class, so it can be reused. + */ + void ClearReader() { mReader.Init(nullptr, 0); } + + /* + * Compute the size of the list. This can fail if the TLV is malformed. If + * this succeeds, that does not guarantee that the individual items can be + * successfully decoded; consumers should check Iterator::GetStatus() when + * actually decoding them. If there is no list then the size is considered + * to be zero. + */ + CHIP_ERROR ComputeSize(size_t * size) const + { + if (mReader.GetContainerType() == TLV::kTLVType_NotSpecified) + { + *size = 0; + return CHIP_NO_ERROR; + } + + return mReader.CountRemainingInContainer(size); + } + + CHIP_ERROR Decode(TLV::TLVReader & reader) + { + VerifyOrReturnError(reader.GetType() == TLV::kTLVType_Array, CHIP_ERROR_SCHEMA_MISMATCH); + TLV::TLVType type; + ReturnErrorOnFailure(reader.EnterContainer(type)); + SetReader(reader); + ReturnErrorOnFailure(reader.ExitContainer(type)); + return CHIP_NO_ERROR; + } + +protected: + TLV::TLVReader mReader; + chip::Optional mFabricIndex; +}; + +} // namespace detail + /* * @brief * @@ -47,30 +109,13 @@ namespace DataModel { * */ template -class DecodableList +class DecodableList : public detail::DecodableListBase { public: - DecodableList() { ClearReader(); } + DecodableList() {} static constexpr bool kIsFabricScoped = DataModel::IsFabricScoped::value; - /* - * @brief - * - * This call stores a TLV reader positioned on the list this class is to manage. - * - * Specifically, the passed-in reader should be pointing into the list just after - * having called `OpenContainer` on the list element. - */ - void SetReader(const TLV::TLVReader & reader) { mReader = reader; } - - /* - * @brief - * - * This call clears the TLV reader managed by this class, so it can be reused. - */ - void ClearReader() { mReader.Init(nullptr, 0); } - template ::value, bool> = true> void SetFabricIndex(FabricIndex fabricIndex) { @@ -189,38 +234,6 @@ class DecodableList }; Iterator begin() const { return Iterator(mReader, mFabricIndex); } - - /* - * Compute the size of the list. This can fail if the TLV is malformed. If - * this succeeds, that does not guarantee that the individual items can be - * successfully decoded; consumers should check Iterator::GetStatus() when - * actually decoding them. If there is no list then the size is considered - * to be zero. - */ - CHIP_ERROR ComputeSize(size_t * size) const - { - if (mReader.GetContainerType() == TLV::kTLVType_NotSpecified) - { - *size = 0; - return CHIP_NO_ERROR; - } - - return mReader.CountRemainingInContainer(size); - } - - CHIP_ERROR Decode(TLV::TLVReader & reader) - { - VerifyOrReturnError(reader.GetType() == TLV::kTLVType_Array, CHIP_ERROR_SCHEMA_MISMATCH); - TLV::TLVType type; - ReturnErrorOnFailure(reader.EnterContainer(type)); - SetReader(reader); - ReturnErrorOnFailure(reader.ExitContainer(type)); - return CHIP_NO_ERROR; - } - -private: - TLV::TLVReader mReader; - chip::Optional mFabricIndex; }; } // namespace DataModel From 77b47801d2f0f6498f2177c49db9c23272475dd5 Mon Sep 17 00:00:00 2001 From: Yufeng Wang Date: Mon, 28 Oct 2024 06:07:14 -0700 Subject: [PATCH 132/149] Redirect the log to log file from console (#36257) --- examples/fabric-sync/main.cpp | 55 +++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/examples/fabric-sync/main.cpp b/examples/fabric-sync/main.cpp index 84c014dfcbf010..66541b32de91f9 100644 --- a/examples/fabric-sync/main.cpp +++ b/examples/fabric-sync/main.cpp @@ -20,14 +20,69 @@ using namespace chip; +namespace { + +constexpr char kFabricSyncLogFilePath[] = "/tmp/fabric_sync.log"; + +// File pointer for the log file +FILE * sLogFile = nullptr; + +void OpenLogFile(const char * filePath) +{ + sLogFile = fopen(filePath, "a"); + if (sLogFile == nullptr) + { + perror("Failed to open log file"); + } +} + +void CloseLogFile() +{ + if (sLogFile != nullptr) + { + fclose(sLogFile); + sLogFile = nullptr; + } +} + +void ENFORCE_FORMAT(3, 0) LoggingCallback(const char * module, uint8_t category, const char * msg, va_list args) +{ + if (sLogFile == nullptr) + { + return; + } + + uint64_t timeMs = System::SystemClock().GetMonotonicMilliseconds64().count(); + uint64_t seconds = timeMs / 1000; + uint64_t milliseconds = timeMs % 1000; + + flockfile(sLogFile); + + fprintf(sLogFile, "[%llu.%06llu] CHIP:%s: ", static_cast(seconds), + static_cast(milliseconds), module); + vfprintf(sLogFile, msg, args); + fprintf(sLogFile, "\n"); + fflush(sLogFile); + + funlockfile(sLogFile); +} + +} // namespace + void ApplicationInit() { ChipLogProgress(NotSpecified, "Fabric-Sync: ApplicationInit()"); + + OpenLogFile(kFabricSyncLogFilePath); + + // Redirect logs to the custom logging callback + Logging::SetLogRedirectCallback(LoggingCallback); } void ApplicationShutdown() { ChipLogDetail(NotSpecified, "Fabric-Sync: ApplicationShutdown()"); + CloseLogFile(); } int main(int argc, char * argv[]) From 21428707a8fee204101725d6a72a78fde90333d3 Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Mon, 28 Oct 2024 09:07:31 -0400 Subject: [PATCH 133/149] Use pointer for subject descriptor in datamodel provider instead of std::optional (#36246) * Use a pointer for the subject descriptor. This seems to save about 88 bytes of flash on a test NRF board. * Restyle * Fix include * Fix include * Also fix PW rpc --------- Co-authored-by: Andrei Litvin --- examples/common/pigweed/rpc_services/Attributes.h | 2 +- src/app/CommandHandlerImpl.cpp | 7 +++++-- src/app/InteractionModelEngine.cpp | 6 ++++-- src/app/WriteHandler.cpp | 2 +- .../CodegenDataModelProvider_Read.cpp | 2 +- .../CodegenDataModelProvider_Write.cpp | 2 +- src/app/data-model-provider/OperationTypes.h | 5 +++-- src/app/data-model-provider/tests/ReadTesting.h | 4 ++-- src/app/data-model-provider/tests/WriteTesting.h | 10 +++++++--- src/app/reporting/Read-DataModel.cpp | 2 +- src/app/tests/test-interaction-model-api.cpp | 10 ++++++++-- src/controller/tests/data_model/DataModelFixtures.cpp | 10 ++++++++-- 12 files changed, 42 insertions(+), 20 deletions(-) diff --git a/examples/common/pigweed/rpc_services/Attributes.h b/examples/common/pigweed/rpc_services/Attributes.h index e4ced64a51d9f2..d34d7e5789c3cd 100644 --- a/examples/common/pigweed/rpc_services/Attributes.h +++ b/examples/common/pigweed/rpc_services/Attributes.h @@ -224,7 +224,7 @@ class Attributes : public pw_rpc::nanopb::Attributes::Service app::DataModel::ReadAttributeRequest request; request.path = path; request.operationFlags.Set(app::DataModel::OperationFlags::kInternal); - request.subjectDescriptor = subjectDescriptor; + request.subjectDescriptor = &subjectDescriptor; std::optional info = provider->GetClusterInfo(path); if (!info.has_value()) diff --git a/src/app/CommandHandlerImpl.cpp b/src/app/CommandHandlerImpl.cpp index 2142af63494348..80373dc32ad755 100644 --- a/src/app/CommandHandlerImpl.cpp +++ b/src/app/CommandHandlerImpl.cpp @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -391,10 +392,11 @@ Status CommandHandlerImpl::ProcessCommandDataIB(CommandDataIB::Parser & aCommand VerifyOrReturnError(err == CHIP_NO_ERROR, Status::InvalidAction); { + Access::SubjectDescriptor subjectDescriptor = GetSubjectDescriptor(); DataModel::InvokeRequest request; request.path = concretePath; - request.subjectDescriptor = GetSubjectDescriptor(); + request.subjectDescriptor = &subjectDescriptor; request.invokeFlags.Set(DataModel::InvokeFlags::kTimed, IsTimedInvoke()); Status preCheckStatus = mpCallback->ValidateCommandCanBeDispatched(request); @@ -513,10 +515,11 @@ Status CommandHandlerImpl::ProcessGroupCommandDataIB(CommandDataIB::Parser & aCo const ConcreteCommandPath concretePath(mapping.endpoint_id, clusterId, commandId); { + Access::SubjectDescriptor subjectDescriptor = GetSubjectDescriptor(); DataModel::InvokeRequest request; request.path = concretePath; - request.subjectDescriptor = GetSubjectDescriptor(); + request.subjectDescriptor = &subjectDescriptor; request.invokeFlags.Set(DataModel::InvokeFlags::kTimed, IsTimedInvoke()); Status preCheckStatus = mpCallback->ValidateCommandCanBeDispatched(request); diff --git a/src/app/InteractionModelEngine.cpp b/src/app/InteractionModelEngine.cpp index d88299c29da412..40ec6e71b3210b 100644 --- a/src/app/InteractionModelEngine.cpp +++ b/src/app/InteractionModelEngine.cpp @@ -1646,10 +1646,12 @@ void InteractionModelEngine::DispatchCommand(CommandHandlerImpl & apCommandObj, { #if CHIP_CONFIG_USE_DATA_MODEL_INTERFACE + Access::SubjectDescriptor subjectDescriptor = apCommandObj.GetSubjectDescriptor(); + DataModel::InvokeRequest request; request.path = aCommandPath; request.invokeFlags.Set(DataModel::InvokeFlags::kTimed, apCommandObj.IsTimedInvoke()); - request.subjectDescriptor = apCommandObj.GetSubjectDescriptor(); + request.subjectDescriptor = &subjectDescriptor; std::optional status = GetDataModelProvider()->Invoke(request, apPayload, &apCommandObj); @@ -1702,7 +1704,7 @@ Protocols::InteractionModel::Status InteractionModelEngine::ValidateCommandCanBe Protocols::InteractionModel::Status InteractionModelEngine::CheckCommandAccess(const DataModel::InvokeRequest & aRequest) { - if (!aRequest.subjectDescriptor.has_value()) + if (aRequest.subjectDescriptor == nullptr) { return Status::UnsupportedAccess; // we require a subject for invoke } diff --git a/src/app/WriteHandler.cpp b/src/app/WriteHandler.cpp index e7787bd4dc2cfd..7a1bbc5d57c668 100644 --- a/src/app/WriteHandler.cpp +++ b/src/app/WriteHandler.cpp @@ -779,7 +779,7 @@ CHIP_ERROR WriteHandler::WriteClusterData(const Access::SubjectDescriptor & aSub DataModel::WriteAttributeRequest request; request.path = aPath; - request.subjectDescriptor = aSubject; + request.subjectDescriptor = &aSubject; request.previousSuccessPath = mLastSuccessfullyWrittenPath; request.writeFlags.Set(DataModel::WriteFlags::kTimed, IsTimedWrite()); diff --git a/src/app/codegen-data-model-provider/CodegenDataModelProvider_Read.cpp b/src/app/codegen-data-model-provider/CodegenDataModelProvider_Read.cpp index ea35356391d63d..aa357ce4dfb5cb 100644 --- a/src/app/codegen-data-model-provider/CodegenDataModelProvider_Read.cpp +++ b/src/app/codegen-data-model-provider/CodegenDataModelProvider_Read.cpp @@ -106,7 +106,7 @@ DataModel::ActionReturnStatus CodegenDataModelProvider::ReadAttribute(const Data // ACL check for non-internal requests if (!request.operationFlags.Has(DataModel::OperationFlags::kInternal)) { - VerifyOrReturnError(request.subjectDescriptor.has_value(), CHIP_ERROR_INVALID_ARGUMENT); + VerifyOrReturnError(request.subjectDescriptor != nullptr, CHIP_ERROR_INVALID_ARGUMENT); Access::RequestPath requestPath{ .cluster = request.path.mClusterId, .endpoint = request.path.mEndpointId, diff --git a/src/app/codegen-data-model-provider/CodegenDataModelProvider_Write.cpp b/src/app/codegen-data-model-provider/CodegenDataModelProvider_Write.cpp index 51807fe98cf47d..de2f8886476707 100644 --- a/src/app/codegen-data-model-provider/CodegenDataModelProvider_Write.cpp +++ b/src/app/codegen-data-model-provider/CodegenDataModelProvider_Write.cpp @@ -159,7 +159,7 @@ DataModel::ActionReturnStatus CodegenDataModelProvider::WriteAttribute(const Dat if (checkAcl) { - VerifyOrReturnError(request.subjectDescriptor.has_value(), Status::UnsupportedAccess); + VerifyOrReturnError(request.subjectDescriptor != nullptr, Status::UnsupportedAccess); Access::RequestPath requestPath{ .cluster = request.path.mClusterId, .endpoint = request.path.mEndpointId, diff --git a/src/app/data-model-provider/OperationTypes.h b/src/app/data-model-provider/OperationTypes.h index 6bfffccc655f00..294bf2616435b4 100644 --- a/src/app/data-model-provider/OperationTypes.h +++ b/src/app/data-model-provider/OperationTypes.h @@ -55,7 +55,7 @@ struct OperationRequest /// - operationFlags.Has(OperationFlags::kInternal) MUST NOT have this set /// /// NOTE: once kInternal flag is removed, this will become non-optional - std::optional subjectDescriptor; + const chip::Access::SubjectDescriptor * subjectDescriptor = nullptr; /// Accessing fabric index is the subjectDescriptor fabric index (if any). /// This is a readability convenience function. @@ -63,7 +63,8 @@ struct OperationRequest /// Returns kUndefinedFabricIndex if no subject descriptor is available FabricIndex GetAccessingFabricIndex() const { - return subjectDescriptor.has_value() ? subjectDescriptor->fabricIndex : kUndefinedFabricIndex; + VerifyOrReturnValue(subjectDescriptor != nullptr, kUndefinedFabricIndex); + return subjectDescriptor->fabricIndex; } }; diff --git a/src/app/data-model-provider/tests/ReadTesting.h b/src/app/data-model-provider/tests/ReadTesting.h index f7cee20c27123b..e34a83377313ab 100644 --- a/src/app/data-model-provider/tests/ReadTesting.h +++ b/src/app/data-model-provider/tests/ReadTesting.h @@ -136,7 +136,7 @@ class ReadOperation ReadOperation(const ConcreteAttributePath & path) { mRequest.path = path; - mRequest.subjectDescriptor = kDenySubjectDescriptor; + mRequest.subjectDescriptor = &kDenySubjectDescriptor; } ReadOperation(EndpointId endpoint, ClusterId cluster, AttributeId attribute) : @@ -146,7 +146,7 @@ class ReadOperation ReadOperation & SetSubjectDescriptor(const chip::Access::SubjectDescriptor & descriptor) { VerifyOrDie(mState == State::kInitializing); - mRequest.subjectDescriptor = descriptor; + mRequest.subjectDescriptor = &descriptor; return *this; } diff --git a/src/app/data-model-provider/tests/WriteTesting.h b/src/app/data-model-provider/tests/WriteTesting.h index d18fb93fdd70cc..7651ffe37940f3 100644 --- a/src/app/data-model-provider/tests/WriteTesting.h +++ b/src/app/data-model-provider/tests/WriteTesting.h @@ -47,7 +47,7 @@ class WriteOperation WriteOperation(const ConcreteDataAttributePath & path) { mRequest.path = path; - mRequest.subjectDescriptor = kDenySubjectDescriptor; + mRequest.subjectDescriptor = &kDenySubjectDescriptor; } WriteOperation(EndpointId endpoint, ClusterId cluster, AttributeId attribute) : @@ -56,7 +56,7 @@ class WriteOperation WriteOperation & SetSubjectDescriptor(const chip::Access::SubjectDescriptor & descriptor) { - mRequest.subjectDescriptor = descriptor; + mRequest.subjectDescriptor = &descriptor; return *this; } @@ -123,7 +123,11 @@ class WriteOperation AttributeValueDecoder DecoderFor(const T & value) { mTLVReader = ReadEncodedValue(value); - return AttributeValueDecoder(mTLVReader, mRequest.subjectDescriptor.value_or(kDenySubjectDescriptor)); + if (mRequest.subjectDescriptor == nullptr) + { + AttributeValueDecoder(mTLVReader, kDenySubjectDescriptor); + } + return AttributeValueDecoder(mTLVReader, *mRequest.subjectDescriptor); } private: diff --git a/src/app/reporting/Read-DataModel.cpp b/src/app/reporting/Read-DataModel.cpp index 64d027e57bb294..584536bdeb9606 100644 --- a/src/app/reporting/Read-DataModel.cpp +++ b/src/app/reporting/Read-DataModel.cpp @@ -47,7 +47,7 @@ DataModel::ActionReturnStatus RetrieveClusterData(DataModel::Provider * dataMode { readRequest.readFlags.Set(DataModel::ReadFlags::kFabricFiltered); } - readRequest.subjectDescriptor = subjectDescriptor; + readRequest.subjectDescriptor = &subjectDescriptor; readRequest.path = path; DataVersion version = 0; diff --git a/src/app/tests/test-interaction-model-api.cpp b/src/app/tests/test-interaction-model-api.cpp index b69c4234273cb9..33097d320bc880 100644 --- a/src/app/tests/test-interaction-model-api.cpp +++ b/src/app/tests/test-interaction-model-api.cpp @@ -13,6 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ +#include "access/SubjectDescriptor.h" #include #include @@ -171,8 +172,13 @@ ActionReturnStatus TestImCustomDataModel::ReadAttribute(const ReadAttributeReque { AttributeEncodeState mutableState(&encoder.GetState()); // provide a state copy to start. - CHIP_ERROR err = ReadSingleClusterData(request.subjectDescriptor.value_or(Access::SubjectDescriptor()), - request.readFlags.Has(ReadFlags::kFabricFiltered), request.path, + Access::SubjectDescriptor subjectDescriptor; + if (request.subjectDescriptor != nullptr) + { + subjectDescriptor = *request.subjectDescriptor; + } + + CHIP_ERROR err = ReadSingleClusterData(subjectDescriptor, request.readFlags.Has(ReadFlags::kFabricFiltered), request.path, TestOnlyAttributeValueEncoderAccessor(encoder).Builder(), &mutableState); // state must survive CHIP_ERRORs as it is used for chunking diff --git a/src/controller/tests/data_model/DataModelFixtures.cpp b/src/controller/tests/data_model/DataModelFixtures.cpp index a5533dc51de57c..f007275c9b3bc2 100644 --- a/src/controller/tests/data_model/DataModelFixtures.cpp +++ b/src/controller/tests/data_model/DataModelFixtures.cpp @@ -18,6 +18,7 @@ #include "DataModelFixtures.h" +#include #include #include #include @@ -522,8 +523,13 @@ ActionReturnStatus CustomDataModel::ReadAttribute(const ReadAttributeRequest & r } #endif // CHIP_CONFIG_USE_EMBER_DATA_MODEL && CHIP_CONFIG_USE_DATA_MODEL_INTERFACE - CHIP_ERROR err = ReadSingleClusterData(request.subjectDescriptor.value_or(Access::SubjectDescriptor()), - request.readFlags.Has(ReadFlags::kFabricFiltered), request.path, + Access::SubjectDescriptor subjectDescriptor; + if (request.subjectDescriptor != nullptr) + { + subjectDescriptor = *request.subjectDescriptor; + } + + CHIP_ERROR err = ReadSingleClusterData(subjectDescriptor, request.readFlags.Has(ReadFlags::kFabricFiltered), request.path, TestOnlyAttributeValueEncoderAccessor(encoder).Builder(), &mutableState); // state must survive CHIP_ERRORs as it is used for chunking From 215cb5ca369d2b9185a79e0dd41791095dd93f19 Mon Sep 17 00:00:00 2001 From: Boris Zbarsky Date: Mon, 28 Oct 2024 10:49:38 -0400 Subject: [PATCH 134/149] Don't try to use the lwip library on Darwin. (#36258) Don't try to build against the library, and don't check out the submodule for the darwin platform. --- .gitmodules | 1 + scripts/checkout_submodules.py | 12 ++++++++++++ src/lwip/lwip.gni | 3 ++- 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index 824bd9954e506c..4eca51b5cf03f9 100644 --- a/.gitmodules +++ b/.gitmodules @@ -332,6 +332,7 @@ [submodule "third_party/lwip/repo"] path = third_party/lwip/repo url = https://github.com/lwip-tcpip/lwip.git + excluded-platforms = darwin [submodule "third_party/abseil-cpp/src"] path = third_party/abseil-cpp/src url = https://github.com/abseil/abseil-cpp.git diff --git a/scripts/checkout_submodules.py b/scripts/checkout_submodules.py index 0290182b5b4bff..4d527148c7d9b0 100755 --- a/scripts/checkout_submodules.py +++ b/scripts/checkout_submodules.py @@ -66,6 +66,18 @@ def load_module_info() -> None: platforms = set(filter(None, platforms)) assert not ( platforms - ALL_PLATFORMS), "Submodule's platform not contained in ALL_PLATFORMS" + + # Check for explicitly excluded platforms + excluded_platforms = module.get('excluded-platforms', '').split(',') + excluded_platforms = set(filter(None, excluded_platforms)) + assert not ( + excluded_platforms - ALL_PLATFORMS), "Submodule excluded on platforms not contained in ALL_PLATFORMS" + + if len(excluded_platforms) != 0: + if len(platforms) == 0: + platforms = ALL_PLATFORMS + platforms = platforms - excluded_platforms + recursive = module.getboolean('recursive', False) name = name.replace('submodule "', '').replace('"', '') yield Module(name=name, path=module['path'], platforms=platforms, recursive=recursive) diff --git a/src/lwip/lwip.gni b/src/lwip/lwip.gni index 89b4808af8fa5a..cbbf0a4f74c901 100644 --- a/src/lwip/lwip.gni +++ b/src/lwip/lwip.gni @@ -14,7 +14,8 @@ declare_args() { # Have the lwIP library available. - chip_with_lwip = current_os != "zephyr" && current_os != "mbed" + chip_with_lwip = current_os != "zephyr" && current_os != "mbed" && + current_os != "mac" && current_os != "ios" # lwIP platform: standalone, freertos. lwip_platform = "" From 928efd718622b5c8c97e91e9e90f259862548148 Mon Sep 17 00:00:00 2001 From: Vivien Nicolas Date: Mon, 28 Oct 2024 16:04:20 +0100 Subject: [PATCH 135/149] [hotfix][darwin-framework-tool] Add missing OTA delegate for per controller storage (#36269) --- .../commands/common/CHIPCommandBridge.mm | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/examples/darwin-framework-tool/commands/common/CHIPCommandBridge.mm b/examples/darwin-framework-tool/commands/common/CHIPCommandBridge.mm index ee21248594a7a4..55df92f8b98a11 100644 --- a/examples/darwin-framework-tool/commands/common/CHIPCommandBridge.mm +++ b/examples/darwin-framework-tool/commands/common/CHIPCommandBridge.mm @@ -185,6 +185,10 @@ intermediateCertificate:nil rootCertificate:certificateIssuer.rootCertificate]; [params setOperationalCertificateIssuer:certificateIssuer queue:controllerStorageQueue]; + + __auto_type * otaDelegateQueue = dispatch_queue_create("com.chip.ota", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); + [params setOTAProviderDelegate:mOTADelegate queue:otaDelegateQueue]; + params.productAttestationAuthorityCertificates = productAttestationAuthorityCertificates; __auto_type * controller = [[MTRDeviceController alloc] initWithParameters:params error:&error]; From e7729d909622bbe4e59910b56e70f10dfbd8c9a0 Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Mon, 28 Oct 2024 13:59:16 -0400 Subject: [PATCH 136/149] Undo googletest in `.gn` and replace it with a build variant (#36268) * Googletest as a variant in build_examples.py * Fix unit tests * A bit more cleanup * Apply some updates from Arkadiusz * Remove extra arg --- .gn | 6 ------ build/chip/chip_test_suite.gni | 5 +++++ scripts/build/build/targets.py | 1 + scripts/build/builders/host.py | 9 ++++++++- scripts/build/testdata/all_targets_linux_x64.txt | 2 +- src/test_driver/tizen/.gn | 1 - 6 files changed, 15 insertions(+), 9 deletions(-) diff --git a/.gn b/.gn index 07b5accb51456c..f844fd20e9b87d 100644 --- a/.gn +++ b/.gn @@ -13,7 +13,6 @@ # limitations under the License. import("//build_overrides/build.gni") -import("//build_overrides/googletest.gni") import("//build_overrides/pigweed.gni") # The location of the build configuration file. @@ -34,11 +33,6 @@ default_args = { # GN target to use for the default Python build venv. pw_build_PYTHON_BUILD_VENV = "//:matter_build_venv" - # Use the GoogleTest backend for unit tests running on host. - pw_unit_test_BACKEND = "$dir_pw_unit_test:googletest" - pw_unit_test_MAIN = "$dir_pigweed/third_party/googletest:gmock_main" - dir_pw_third_party_googletest = "$dir_googletest" - # Required for pw_unit_test pw_sys_io_BACKEND = "$dir_pw_sys_io_stdio" pw_assert_BACKEND = "$dir_pw_assert_log" diff --git a/build/chip/chip_test_suite.gni b/build/chip/chip_test_suite.gni index de6b7c16848eb5..19264b905104ee 100644 --- a/build/chip/chip_test_suite.gni +++ b/build/chip/chip_test_suite.gni @@ -14,6 +14,7 @@ import("//build_overrides/build.gni") import("//build_overrides/chip.gni") +import("//build_overrides/googletest.gni") import("//build_overrides/pigweed.gni") import("${chip_root}/build/chip/tests.gni") @@ -120,6 +121,10 @@ template("chip_test_suite") { # Link to the common lib for this suite so we get its `sources`. public_deps += [ ":${_suite_name}.lib" ] + if (pw_unit_test_BACKEND == "$dir_pw_unit_test:googletest") { + test_main = "$dir_pigweed/third_party/googletest:gmock_main" + } + # Set variables that the platform executable may need. if (test_executable_output_name != "") { output_name = test_executable_output_name + _test_name + diff --git a/scripts/build/build/targets.py b/scripts/build/build/targets.py index 779855f4ed2633..d86c36f328031e 100755 --- a/scripts/build/build/targets.py +++ b/scripts/build/build/targets.py @@ -200,6 +200,7 @@ def BuildHostTarget(): target.AppendModifier('data-model-disabled', data_model_interface="disabled").ExceptIfRe('-data-model-(check|enabled)') target.AppendModifier('data-model-enabled', data_model_interface="enabled").ExceptIfRe('-data-model-(check|disabled)') target.AppendModifier('check-failure-die', chip_data_model_check_die_on_failure=True).OnlyIfRe('-data-model-check') + target.AppendModifier('googletest', use_googletest=True).OnlyIfRe('-tests') return target diff --git a/scripts/build/builders/host.py b/scripts/build/builders/host.py index 3b81f5d94423fa..114f47f971f1df 100644 --- a/scripts/build/builders/host.py +++ b/scripts/build/builders/host.py @@ -336,7 +336,8 @@ def __init__(self, root, runner, app: HostApp, board=HostBoard.NATIVE, chip_casting_simplified: Optional[bool] = None, data_model_interface: Optional[str] = None, chip_data_model_check_die_on_failure: Optional[bool] = None, - disable_shell=False + disable_shell=False, + use_googletest=False, ): super(HostBuilder, self).__init__( root=os.path.join(root, 'examples', app.ExamplePath()), @@ -496,6 +497,12 @@ def __init__(self, root, runner, app: HostApp, board=HostBoard.NATIVE, if self.app == HostApp.TESTS and fuzzing_type == HostFuzzingType.PW_FUZZTEST: self.build_command = 'pw_fuzz_tests' + if self.app == HostApp.TESTS and use_googletest: + self.extra_gn_options.append('import("//build_overrides/pigweed.gni")') + self.extra_gn_options.append('import("//build_overrides/googletest.gni")') + self.extra_gn_options.append('pw_unit_test_BACKEND="$dir_pw_unit_test:googletest"') + self.extra_gn_options.append('dir_pw_third_party_googletest="$dir_googletest"') + def GnBuildArgs(self): if self.board == HostBoard.NATIVE: return self.extra_gn_options diff --git a/scripts/build/testdata/all_targets_linux_x64.txt b/scripts/build/testdata/all_targets_linux_x64.txt index 084b80bea3ab17..58a1fc1021d305 100644 --- a/scripts/build/testdata/all_targets_linux_x64.txt +++ b/scripts/build/testdata/all_targets_linux_x64.txt @@ -9,7 +9,7 @@ efr32-{brd2704b,brd4316a,brd4317a,brd4318a,brd4319a,brd4186a,brd4187a,brd2601b,b esp32-{m5stack,c3devkit,devkitc,qemu}-{all-clusters,all-clusters-minimal,energy-management,ota-provider,ota-requestor,shell,light,lock,bridge,temperature-measurement,ota-requestor,tests}[-rpc][-ipv6only][-tracing][-data-model-disabled][-data-model-enabled] genio-lighting-app linux-fake-tests[-mbedtls][-boringssl][-asan][-tsan][-ubsan][-libfuzzer][-ossfuzz][-pw-fuzztest][-coverage][-dmalloc][-clang] -linux-{x64,arm64}-{rpc-console,all-clusters,all-clusters-minimal,chip-tool,thermostat,java-matter-controller,kotlin-matter-controller,minmdns,light,light-data-model-no-unique-id,lock,shell,ota-provider,ota-requestor,simulated-app1,simulated-app2,python-bindings,tv-app,tv-casting-app,bridge,fabric-admin,fabric-bridge,fabric-sync,tests,chip-cert,address-resolve-tool,contact-sensor,dishwasher,microwave-oven,refrigerator,rvc,air-purifier,lit-icd,air-quality-sensor,network-manager,energy-management,water-leak-detector}[-nodeps][-nlfaultinject][-platform-mdns][-minmdns-verbose][-libnl][-same-event-loop][-no-interactive][-ipv6only][-no-ble][-no-wifi][-no-thread][-no-shell][-mbedtls][-boringssl][-asan][-tsan][-ubsan][-libfuzzer][-ossfuzz][-pw-fuzztest][-coverage][-dmalloc][-clang][-test][-rpc][-with-ui][-evse-test-event][-enable-dnssd-tests][-disable-dnssd-tests][-chip-casting-simplified][-data-model-check][-data-model-disabled][-data-model-enabled][-check-failure-die] +linux-{x64,arm64}-{rpc-console,all-clusters,all-clusters-minimal,chip-tool,thermostat,java-matter-controller,kotlin-matter-controller,minmdns,light,light-data-model-no-unique-id,lock,shell,ota-provider,ota-requestor,simulated-app1,simulated-app2,python-bindings,tv-app,tv-casting-app,bridge,fabric-admin,fabric-bridge,fabric-sync,tests,chip-cert,address-resolve-tool,contact-sensor,dishwasher,microwave-oven,refrigerator,rvc,air-purifier,lit-icd,air-quality-sensor,network-manager,energy-management,water-leak-detector}[-nodeps][-nlfaultinject][-platform-mdns][-minmdns-verbose][-libnl][-same-event-loop][-no-interactive][-ipv6only][-no-ble][-no-wifi][-no-thread][-no-shell][-mbedtls][-boringssl][-asan][-tsan][-ubsan][-libfuzzer][-ossfuzz][-pw-fuzztest][-coverage][-dmalloc][-clang][-test][-rpc][-with-ui][-evse-test-event][-enable-dnssd-tests][-disable-dnssd-tests][-chip-casting-simplified][-data-model-check][-data-model-disabled][-data-model-enabled][-check-failure-die][-googletest] linux-x64-efr32-test-runner[-clang] imx-{chip-tool,lighting-app,thermostat,all-clusters-app,all-clusters-minimal-app,ota-provider-app}[-release] infineon-psoc6-{lock,light,all-clusters,all-clusters-minimal}[-ota][-updateimage][-trustm] diff --git a/src/test_driver/tizen/.gn b/src/test_driver/tizen/.gn index 26cd7015b64f76..c8f8c5181d0627 100644 --- a/src/test_driver/tizen/.gn +++ b/src/test_driver/tizen/.gn @@ -31,7 +31,6 @@ default_args = { pw_log_BACKEND = "$dir_pw_log_basic" pw_unit_test_BACKEND = "$dir_pw_unit_test:googletest" - pw_unit_test_MAIN = "$dir_pigweed/third_party/googletest:gmock_main" dir_pw_third_party_googletest = "$dir_googletest" # TODO: Make sure only unit tests link against this From c50c5914a5d2f8e34d10d089e428531ac8c9ad74 Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Mon, 28 Oct 2024 14:30:11 -0400 Subject: [PATCH 137/149] Post merge cleanup 36229 ember buffer encode (#36266) * Use chip::app::IsSignedAttributeType * Fix up put as well as naming for null value and comment * Fix up nullable tests * Test that you cannot decode a null value for non-nullable double and single * Allow NAN for non-nullable floating points * Add test case for non nullable bool * Restyle * Add a header for efr32 * Update src/app/codegen-data-model-provider/EmberAttributeDataBuffer.cpp Co-authored-by: Boris Zbarsky * Update src/app/codegen-data-model-provider/EmberAttributeDataBuffer.cpp Co-authored-by: Boris Zbarsky * Remove extra comment * Replace switch with if * Comment fix * Another try to make efr32 build of tests happy * Move includes around, to try to work around issues within efr32 compiles... * more updates, this time local efr32 compiles --------- Co-authored-by: Boris Zbarsky --- .../EmberAttributeDataBuffer.cpp | 55 ++++++------------- .../EmberAttributeDataBuffer.h | 2 +- .../tests/TestEmberAttributeDataBuffer.cpp | 45 ++++++++++++++- 3 files changed, 62 insertions(+), 40 deletions(-) diff --git a/src/app/codegen-data-model-provider/EmberAttributeDataBuffer.cpp b/src/app/codegen-data-model-provider/EmberAttributeDataBuffer.cpp index 2c764241ebf3d8..7eb2e9d2b1d2ea 100644 --- a/src/app/codegen-data-model-provider/EmberAttributeDataBuffer.cpp +++ b/src/app/codegen-data-model-provider/EmberAttributeDataBuffer.cpp @@ -384,29 +384,22 @@ CHIP_ERROR EmberAttributeDataBuffer::EncodeInteger(chip::TLV::TLVWriter & writer uint8_t raw_bytes[8]; - bool isSigned = (mAttributeType == ZCL_INT8S_ATTRIBUTE_TYPE) // - || (mAttributeType == ZCL_INT16S_ATTRIBUTE_TYPE) // - || (mAttributeType == ZCL_INT24S_ATTRIBUTE_TYPE) // - || (mAttributeType == ZCL_INT32S_ATTRIBUTE_TYPE) // - || (mAttributeType == ZCL_INT40S_ATTRIBUTE_TYPE) // - || (mAttributeType == ZCL_INT48S_ATTRIBUTE_TYPE) // - || (mAttributeType == ZCL_INT56S_ATTRIBUTE_TYPE) // - || (mAttributeType == ZCL_INT64S_ATTRIBUTE_TYPE); + const bool isSigned = IsSignedAttributeType(mAttributeType); unsigned byteCount; - uint64_t nullValue; + uint64_t nullValueAsU64; if (isSigned) { const SignedDecodeInfo info = GetSignedDecodeInfo(mAttributeType); byteCount = info.byteCount; - nullValue = static_cast(info.minValue); // just a bit cast for easy compare + nullValueAsU64 = static_cast(info.minValue); } else { const UnsignedDecodeInfo info = GetUnsignedDecodeInfo(mAttributeType); byteCount = info.byteCount; - nullValue = info.maxValue; + nullValueAsU64 = info.maxValue; } VerifyOrDie(sizeof(raw_bytes) >= byteCount); @@ -445,36 +438,21 @@ CHIP_ERROR EmberAttributeDataBuffer::EncodeInteger(chip::TLV::TLVWriter & writer value.uint_value = (value.uint_value & ~0xFFULL) | raw_bytes[i]; } - if (mIsNullable && (value.uint_value == nullValue)) + // We place the null value as either int_value or uint_value into a union that is + // bit-formatted as both int64 and uint64. When we define the nullValue, + // it is bitcast into u64 hence this comparison. This is ugly, however this + // code prioritizes code size over readability here. + if (mIsNullable && (value.uint_value == nullValueAsU64)) { - // MaxValue is used for NULL setting return writer.PutNull(tag); } - switch (mAttributeType) + if (isSigned) { - case ZCL_INT8U_ATTRIBUTE_TYPE: // Unsigned 8-bit integer - return writer.Put(tag, static_cast(value.uint_value)); - case ZCL_INT16U_ATTRIBUTE_TYPE: // Unsigned 16-bit integer - return writer.Put(tag, static_cast(value.uint_value)); - case ZCL_INT24U_ATTRIBUTE_TYPE: // Unsigned 24-bit integer - case ZCL_INT32U_ATTRIBUTE_TYPE: // Unsigned 32-bit integer - return writer.Put(tag, static_cast(value.uint_value)); - case ZCL_INT40U_ATTRIBUTE_TYPE: // Unsigned 40-bit integer - case ZCL_INT48U_ATTRIBUTE_TYPE: // Unsigned 48-bit integer - case ZCL_INT56U_ATTRIBUTE_TYPE: // Signed 56-bit integer - case ZCL_INT64U_ATTRIBUTE_TYPE: // Signed 64-bit integer - return writer.Put(tag, static_cast(value.uint_value)); - case ZCL_INT8S_ATTRIBUTE_TYPE: // Signed 8-bit integer - return writer.Put(tag, static_cast(value.int_value)); - case ZCL_INT16S_ATTRIBUTE_TYPE: // Signed 16-bit integer - return writer.Put(tag, static_cast(value.int_value)); - case ZCL_INT24S_ATTRIBUTE_TYPE: // Signed 24-bit integer - case ZCL_INT32S_ATTRIBUTE_TYPE: // Signed 32-bit integer - return writer.Put(tag, static_cast(value.int_value)); - default: - return writer.Put(tag, static_cast(value.int_value)); + return writer.Put(tag, value.int_value); } + + return writer.Put(tag, value.uint_value); } CHIP_ERROR EmberAttributeDataBuffer::Encode(chip::TLV::TLVWriter & writer, TLV::Tag tag) const @@ -497,10 +475,11 @@ CHIP_ERROR EmberAttributeDataBuffer::Encode(chip::TLV::TLVWriter & writer, TLV:: case 1: return writer.PutBoolean(tag, value != 0); case 0xFF: + VerifyOrReturnError(mIsNullable, CHIP_ERROR_INVALID_ARGUMENT); return writer.PutNull(tag); default: // Unknown types - return CHIP_ERROR_INCORRECT_STATE; + return CHIP_ERROR_INVALID_ARGUMENT; } } case ZCL_INT8U_ATTRIBUTE_TYPE: // Unsigned 8-bit integer @@ -531,7 +510,7 @@ CHIP_ERROR EmberAttributeDataBuffer::Encode(chip::TLV::TLVWriter & writer, TLV:: { return endianReader.StatusCode(); } - if (NumericAttributeTraits::IsNullValue(value.value)) + if (mIsNullable && NumericAttributeTraits::IsNullValue(value.value)) { return writer.PutNull(tag); } @@ -548,7 +527,7 @@ CHIP_ERROR EmberAttributeDataBuffer::Encode(chip::TLV::TLVWriter & writer, TLV:: { return endianReader.StatusCode(); } - if (NumericAttributeTraits::IsNullValue(value.value)) + if (mIsNullable && NumericAttributeTraits::IsNullValue(value.value)) { return writer.PutNull(tag); } diff --git a/src/app/codegen-data-model-provider/EmberAttributeDataBuffer.h b/src/app/codegen-data-model-provider/EmberAttributeDataBuffer.h index c3d7acfcafb72b..f4a2de268591d4 100644 --- a/src/app/codegen-data-model-provider/EmberAttributeDataBuffer.h +++ b/src/app/codegen-data-model-provider/EmberAttributeDataBuffer.h @@ -85,7 +85,7 @@ class EmberAttributeDataBuffer /// Takes into account internal mIsNullable. CHIP_ERROR DecodeSignedInteger(chip::TLV::TLVReader & reader, EndianWriter & writer); - /// Encodes the UNSIGNED integer into `writer`. + /// Encodes the given integer into `writer`. /// Takes into account internal mIsNullable. CHIP_ERROR EncodeInteger(chip::TLV::TLVWriter & writer, TLV::Tag tag, EndianReader & reader) const; diff --git a/src/app/codegen-data-model-provider/tests/TestEmberAttributeDataBuffer.cpp b/src/app/codegen-data-model-provider/tests/TestEmberAttributeDataBuffer.cpp index dc83773454d1ff..04e8b94dcce809 100644 --- a/src/app/codegen-data-model-provider/tests/TestEmberAttributeDataBuffer.cpp +++ b/src/app/codegen-data-model-provider/tests/TestEmberAttributeDataBuffer.cpp @@ -16,6 +16,8 @@ */ #include +#include + #include #include @@ -107,6 +109,28 @@ bool IsEqual(const T & a, const T & b) return a == b; } +template <> +bool IsEqual(const float & a, const float & b) +{ + if (std::isnan(a) && std::isnan(b)) + { + return true; + } + + return a == b; +} + +template <> +bool IsEqual(const double & a, const double & b) +{ + if (std::isnan(a) && std::isnan(b)) + { + return true; + } + + return a == b; +} + template <> bool IsEqual(const ByteSpan & a, const ByteSpan & b) { @@ -756,7 +780,7 @@ TEST(TestEmberAttributeBuffer, TestDecodeFailures) { // Bad boolean data EncodeTester tester(CreateFakeMeta(ZCL_BOOLEAN_ATTRIBUTE_TYPE, false /* nullable */)); - EXPECT_EQ(tester.TryDecode(true, { 123 }), CHIP_ERROR_INCORRECT_STATE); + EXPECT_EQ(tester.TryDecode(true, { 123 }), CHIP_ERROR_INVALID_ARGUMENT); } } @@ -1097,6 +1121,13 @@ TEST(TestEmberAttributeBuffer, TestDecodeBool) EXPECT_TRUE(tester.TryDecode>(false, { 0 }).IsSuccess()); EXPECT_TRUE(tester.TryDecode>(DataModel::NullNullable, { 0xFF }).IsSuccess()); } + + { + // Boolean that is NOT nullable + EncodeTester tester(CreateFakeMeta(ZCL_BOOLEAN_ATTRIBUTE_TYPE, false /* nullable */)); + EXPECT_EQ(tester.TryDecode>(DataModel::NullNullable, { 0xFF }), CHIP_ERROR_INVALID_ARGUMENT); + EXPECT_EQ(tester.TryDecode(true, { 0xFF }), CHIP_ERROR_INVALID_ARGUMENT); + } } TEST(TestEmberAttributeBuffer, TestDecodeFloatingPoint) @@ -1120,6 +1151,12 @@ TEST(TestEmberAttributeBuffer, TestDecodeFloatingPoint) EXPECT_TRUE(tester.TryDecode>(DataModel::NullNullable, { 0, 0, 0xC0, 0x7F }).IsSuccess()); } + { + EncodeTester tester(CreateFakeMeta(ZCL_SINGLE_ATTRIBUTE_TYPE, false /* nullable */)); + // non-nullable float + EXPECT_TRUE(tester.TryDecode(std::nanf("0"), { 0, 0, 0xC0, 0x7F }).IsSuccess()); + } + { EncodeTester tester(CreateFakeMeta(ZCL_DOUBLE_ATTRIBUTE_TYPE, false /* nullable */)); EXPECT_TRUE(tester.TryDecode(123.55, { 0x33, 0x33, 0x33, 0x33, 0x33, 0xE3, 0x5E, 0x40 }).IsSuccess()); @@ -1133,4 +1170,10 @@ TEST(TestEmberAttributeBuffer, TestDecodeFloatingPoint) EXPECT_TRUE( tester.TryDecode>(DataModel::NullNullable, { 0, 0, 0, 0, 0, 0, 0xF8, 0x7F }).IsSuccess()); } + + { + EncodeTester tester(CreateFakeMeta(ZCL_DOUBLE_ATTRIBUTE_TYPE, false /* nullable */)); + // non-nullable double + EXPECT_TRUE(tester.TryDecode(std::nan("0"), { 0, 0, 0, 0, 0, 0, 0xF8, 0x7F }).IsSuccess()); + } } From 1e9ef37d299054c2b1a58d20e145e109ed6faa85 Mon Sep 17 00:00:00 2001 From: Vivien Nicolas Date: Mon, 28 Oct 2024 19:32:55 +0100 Subject: [PATCH 138/149] [darwin-framework-tool][interactive] The multiline prompt makes it difficult to modify command with backspace (#36267) --- .../interactive/InteractiveCommands.mm | 20 ++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/examples/darwin-framework-tool/commands/interactive/InteractiveCommands.mm b/examples/darwin-framework-tool/commands/interactive/InteractiveCommands.mm index 2652e2c2364101..cfad15b781e129 100644 --- a/examples/darwin-framework-tool/commands/interactive/InteractiveCommands.mm +++ b/examples/darwin-framework-tool/commands/interactive/InteractiveCommands.mm @@ -27,12 +27,17 @@ #include #include -constexpr char kInteractiveModePrompt[] = "Stop and restart stack: [Ctrl+_] & [Ctrl+^]\n" - "Trigger exit(0): [Ctrl+@]\n" - "Quit Interactive: 'quit()'\n" - ">>> "; +constexpr char kInteractiveModeInstruction[] = "╔══════════════════════════════════════════════════════════════════╗\n" + "║ Interactive Mode ║\n" + "╠══════════════════════════════════════════════════════════════════╣\n" + "║ Stop and restart stack: [Ctrl+_] & [Ctrl+^ ] ║\n" + "║ Trigger exit(0) : [Ctrl+@] ║\n" + "║ Quit Interactive : 'quit()' or `quit` ║\n" + "╚══════════════════════════════════════════════════════════════════╝\n"; +constexpr char kInteractiveModePrompt[] = ">>> "; constexpr char kInteractiveModeHistoryFilePath[] = "/tmp/darwin_framework_tool_history"; constexpr char kInteractiveModeStopCommand[] = "quit()"; +constexpr char kInteractiveModeStopAlternateCommand[] = "quit"; constexpr char kCategoryError[] = "Error"; constexpr char kCategoryProgress[] = "Info"; constexpr char kCategoryDetail[] = "Debug"; @@ -277,6 +282,11 @@ void ENFORCE_FORMAT(3, 0) InteractiveServerLoggingCallback(const char * module, printf("%s\n", mAdditionalPrompt.Value()); ClearLine(); } + + ClearLine(); + printf("%s", kInteractiveModeInstruction); + ClearLine(); + command = readline(kInteractiveModePrompt); // Do not save empty lines @@ -391,7 +401,7 @@ el_status_t ExitFunction() bool InteractiveCommand::ParseCommand(char * command, int * status) { - if (strcmp(command, kInteractiveModeStopCommand) == 0) { + if (strcmp(command, kInteractiveModeStopCommand) == 0 || strcmp(command, kInteractiveModeStopAlternateCommand) == 0) { ExecuteDeferredCleanups(); return NO; } From 2ba440be3cc9dfb4fc8f84a91340b7400ede611e Mon Sep 17 00:00:00 2001 From: Vivien Nicolas Date: Mon, 28 Oct 2024 21:24:28 +0100 Subject: [PATCH 139/149] [darwin-framework-tool] [darwin-framework-tool] Add an optional parameter to the storage view command to only show the entries for a given commissioner (#36244) --- .../commands/common/CHIPCommandBridge.h | 3 +++ .../commands/common/CHIPCommandBridge.mm | 19 ++++++++++++------- .../commands/common/ControllerStorage.h | 1 + .../commands/common/ControllerStorage.mm | 14 ++++++++++++++ .../storage/StorageManagementCommand.h | 10 +++++++++- .../storage/StorageManagementCommand.mm | 19 +++++++++++++++---- 6 files changed, 54 insertions(+), 12 deletions(-) diff --git a/examples/darwin-framework-tool/commands/common/CHIPCommandBridge.h b/examples/darwin-framework-tool/commands/common/CHIPCommandBridge.h index 477e1ed8105101..90f3a6c56415f6 100644 --- a/examples/darwin-framework-tool/commands/common/CHIPCommandBridge.h +++ b/examples/darwin-framework-tool/commands/common/CHIPCommandBridge.h @@ -30,6 +30,7 @@ inline constexpr char kIdentityAlpha[] = "alpha"; inline constexpr char kIdentityBeta[] = "beta"; inline constexpr char kIdentityGamma[] = "gamma"; +inline constexpr char kControllerIdPrefix[] = "8DCADB14-AF1F-45D0-B084-00000000000"; class CHIPCommandBridge : public Command { public: @@ -69,6 +70,8 @@ class CHIPCommandBridge : public Command { static OTAProviderDelegate * mOTADelegate; + static NSNumber * GetCommissionerFabricId(const char * identity); + protected: // Will be called in a setting in which it's safe to touch the CHIP // stack. The rules for Run() are as follows: diff --git a/examples/darwin-framework-tool/commands/common/CHIPCommandBridge.mm b/examples/darwin-framework-tool/commands/common/CHIPCommandBridge.mm index 55df92f8b98a11..b237acaa5b7132 100644 --- a/examples/darwin-framework-tool/commands/common/CHIPCommandBridge.mm +++ b/examples/darwin-framework-tool/commands/common/CHIPCommandBridge.mm @@ -154,10 +154,10 @@ constexpr const char * identities[] = { kIdentityAlpha, kIdentityBeta, kIdentityGamma }; std::string commissionerName = mCommissionerName.HasValue() ? mCommissionerName.Value() : kIdentityAlpha; for (size_t i = 0; i < ArraySize(identities); ++i) { - __auto_type * uuidString = [NSString stringWithFormat:@"%@%@", @"8DCADB14-AF1F-45D0-B084-00000000000", @(i)]; + __auto_type * fabricId = GetCommissionerFabricId(identities[i]); + __auto_type * uuidString = [NSString stringWithFormat:@"%@%@", @(kControllerIdPrefix), fabricId]; __auto_type * controllerId = [[NSUUID alloc] initWithUUIDString:uuidString]; __auto_type * vendorId = @(mCommissionerVendorId.ValueOr(chip::VendorId::TestVendor1)); - __auto_type * fabricId = @(i + 1); __auto_type * nodeId = @(chip::kTestControllerNodeId); if (commissionerName.compare(identities[i]) == 0 && mCommissionerNodeId.HasValue()) { @@ -218,7 +218,7 @@ constexpr const char * identities[] = { kIdentityAlpha, kIdentityBeta, kIdentityGamma }; std::string commissionerName = mCommissionerName.HasValue() ? mCommissionerName.Value() : kIdentityAlpha; for (size_t i = 0; i < ArraySize(identities); ++i) { - __auto_type * fabricId = @(i + 1); + __auto_type * fabricId = GetCommissionerFabricId(identities[i]); __auto_type * params = [[MTRDeviceControllerStartupParams alloc] initWithIPK:certificateIssuer.ipk fabricID:fabricId nocSigner:certificateIssuer.signingKey]; @@ -264,14 +264,19 @@ NSNumber * CHIPCommandBridge::CurrentCommissionerFabricId() { - if (mCurrentIdentity.compare(kIdentityAlpha) == 0) { + return GetCommissionerFabricId(mCurrentIdentity.c_str()); +} + +NSNumber * CHIPCommandBridge::GetCommissionerFabricId(const char * identity) +{ + if (strcmp(identity, kIdentityAlpha) == 0) { return @(1); - } else if (mCurrentIdentity.compare(kIdentityBeta) == 0) { + } else if (strcmp(identity, kIdentityBeta) == 0) { return @(2); - } else if (mCurrentIdentity.compare(kIdentityGamma) == 0) { + } else if (strcmp(identity, kIdentityGamma) == 0) { return @(3); } else { - ChipLogError(chipTool, "Unknown commissioner name: %s. Supported names are [%s, %s, %s]", mCurrentIdentity.c_str(), kIdentityAlpha, + ChipLogError(chipTool, "Unknown commissioner name: %s. Supported names are [%s, %s, %s]", identity, kIdentityAlpha, kIdentityBeta, kIdentityGamma); chipDie(); } diff --git a/examples/darwin-framework-tool/commands/common/ControllerStorage.h b/examples/darwin-framework-tool/commands/common/ControllerStorage.h index f70081fee095a7..76811bcbb7e92e 100644 --- a/examples/darwin-framework-tool/commands/common/ControllerStorage.h +++ b/examples/darwin-framework-tool/commands/common/ControllerStorage.h @@ -44,6 +44,7 @@ extern NSString * const kDarwinFrameworkToolControllerDomain; - (NSData *)valueForKey:(NSString *)key; - (void)storeValue:(NSData *)value forKey:key; +- (void)print; @end NS_ASSUME_NONNULL_END diff --git a/examples/darwin-framework-tool/commands/common/ControllerStorage.mm b/examples/darwin-framework-tool/commands/common/ControllerStorage.mm index 058f00a6b302ae..03685d445a1e84 100644 --- a/examples/darwin-framework-tool/commands/common/ControllerStorage.mm +++ b/examples/darwin-framework-tool/commands/common/ControllerStorage.mm @@ -143,6 +143,20 @@ - (void)storeValue:(NSData *)value forKey:key self.storage[controllerKey] = value; } +- (void)print +{ + NSLog(@"%@ (%@)", kDarwinFrameworkToolControllerDomain, _keyScopingPrefix); + for (NSString * controllerKey in self.storage) { + if (![self _isControllerScopedKey:controllerKey]) { + continue; + } + + __auto_type * key = [self _controllerScopedKeyToKey:controllerKey]; + __auto_type * data = self.storage[controllerKey]; + NSLog(@" * %@: %@", key, data); + } +} + - (NSString *)_keyToControllerScopedKey:(NSString *)key { return [NSString stringWithFormat:@"%@%@", _keyScopingPrefix, key]; diff --git a/examples/darwin-framework-tool/commands/storage/StorageManagementCommand.h b/examples/darwin-framework-tool/commands/storage/StorageManagementCommand.h index 8c3ed69184d742..35e111e92e7125 100644 --- a/examples/darwin-framework-tool/commands/storage/StorageManagementCommand.h +++ b/examples/darwin-framework-tool/commands/storage/StorageManagementCommand.h @@ -33,7 +33,15 @@ class StorageClearAll : public Command class StorageViewAll : public Command { public: - StorageViewAll() : Command("view-all") {} + StorageViewAll() : Command("view") + { + AddArgument("commissioner-name", &mCommissionerName, + "If specified, only the keys associated with the given commissioner will be displayed. Valid options are: " + "‘alpha’, ‘beta’, ‘gamma’."); + } CHIP_ERROR Run() override; + +private: + chip::Optional mCommissionerName; }; diff --git a/examples/darwin-framework-tool/commands/storage/StorageManagementCommand.mm b/examples/darwin-framework-tool/commands/storage/StorageManagementCommand.mm index 007d2821bda5a3..9e6e4b61f88a95 100644 --- a/examples/darwin-framework-tool/commands/storage/StorageManagementCommand.mm +++ b/examples/darwin-framework-tool/commands/storage/StorageManagementCommand.mm @@ -49,11 +49,22 @@ CHIP_ERROR StorageViewAll::Run() { - __auto_type * domains = GetDomains(); - for (NSString * domain in domains) { - __auto_type * storage = [[PreferencesStorage alloc] initWithDomain:domain]; - [storage print]; + if (!mCommissionerName.HasValue()) { + __auto_type * domains = GetDomains(); + for (NSString * domain in domains) { + __auto_type * storage = [[PreferencesStorage alloc] initWithDomain:domain]; + [storage print]; + } + + return CHIP_NO_ERROR; } + const char * commissionerName = mCommissionerName.Value(); + __auto_type * fabricId = CHIPCommandBridge::GetCommissionerFabricId(commissionerName); + __auto_type * uuidString = [NSString stringWithFormat:@"%@%@", @(kControllerIdPrefix), fabricId]; + __auto_type * controllerId = [[NSUUID alloc] initWithUUIDString:uuidString]; + __auto_type * storage = [[ControllerStorage alloc] initWithControllerID:controllerId]; + [storage print]; + return CHIP_NO_ERROR; } From 41305b5218c19b4707585e585b141fd54ffa803e Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Mon, 28 Oct 2024 16:41:46 -0400 Subject: [PATCH 140/149] Support a `name` attribute for XML tags for attributes in zapxml (#36270) * Add support for a name attribute in zapxml * Add unit test --- .../py_matter_idl/matter_idl/test_zapxml.py | 27 +++++++++++++++++++ .../matter_idl/zapxml/handlers/parsing.py | 4 ++- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/scripts/py_matter_idl/matter_idl/test_zapxml.py b/scripts/py_matter_idl/matter_idl/test_zapxml.py index 5ea15e27e8f9c2..2bf4338d20a928 100755 --- a/scripts/py_matter_idl/matter_idl/test_zapxml.py +++ b/scripts/py_matter_idl/matter_idl/test_zapxml.py @@ -360,6 +360,33 @@ def testGlobalStruct(self): ) self.assertEqual(idl, Idl(global_structs=[struct])) + def testNameAttribute(self): + idl = XmlToIdl(''' + + + TestCluster + 20 + + + + + + + ''') + self.assertEqual(idl, + Idl(clusters=[ + Cluster(name='TestCluster', code=20, + attributes=[ + Attribute( + definition=Field( + data_type=DataType(name='int16u', min_value=4), + code=2, + name='SubjectsPerAccessControlEntry', + ), + qualities=AttributeQuality.READABLE, + readacl=AccessPrivilege.VIEW, + writeacl=AccessPrivilege.OPERATE)])])) + def testStruct(self): idl = XmlToIdl(''' diff --git a/scripts/py_matter_idl/matter_idl/zapxml/handlers/parsing.py b/scripts/py_matter_idl/matter_idl/zapxml/handlers/parsing.py index 5244e6574d8de1..30ca8a5956f361 100644 --- a/scripts/py_matter_idl/matter_idl/zapxml/handlers/parsing.py +++ b/scripts/py_matter_idl/matter_idl/zapxml/handlers/parsing.py @@ -81,10 +81,12 @@ def AttrsToAttribute(attrs) -> Attribute: if 'max' in attrs: data_type.max_value = ParseInt(attrs['max'], data_type) + name = attrs['name'] if 'name' in attrs else '' + field = Field( data_type=data_type, code=ParseInt(attrs['code']), - name='', + name=name, is_list=(attrs['type'].lower() == 'array') ) From cdb1920ab5de79694b2f7a249094a9374d16f8d0 Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Mon, 28 Oct 2024 16:54:33 -0400 Subject: [PATCH 141/149] Remove lookup tables from ember attribute data buffer (#36273) --- .../EmberAttributeDataBuffer.cpp | 150 +++++++----------- 1 file changed, 58 insertions(+), 92 deletions(-) diff --git a/src/app/codegen-data-model-provider/EmberAttributeDataBuffer.cpp b/src/app/codegen-data-model-provider/EmberAttributeDataBuffer.cpp index 7eb2e9d2b1d2ea..1296e7190833fd 100644 --- a/src/app/codegen-data-model-provider/EmberAttributeDataBuffer.cpp +++ b/src/app/codegen-data-model-provider/EmberAttributeDataBuffer.cpp @@ -17,6 +17,7 @@ #include #include +#include #include #include #include @@ -51,74 +52,47 @@ constexpr uint32_t MaxLength(EmberAttributeDataBuffer::PascalStringType s) return std::numeric_limits::max() - 1; } -struct UnsignedDecodeInfo +constexpr unsigned GetByteCountOfIntegerType(EmberAfAttributeType type) { - unsigned byteCount; - uint64_t maxValue; - - constexpr UnsignedDecodeInfo(unsigned bytes) : byteCount(bytes), maxValue(NumericLimits::MaxUnsignedValue(bytes)) {} -}; - -constexpr UnsignedDecodeInfo GetUnsignedDecodeInfo(EmberAfAttributeType type) -{ - - switch (type) - { - case ZCL_INT8U_ATTRIBUTE_TYPE: // Unsigned 8-bit integer - return UnsignedDecodeInfo(1); - case ZCL_INT16U_ATTRIBUTE_TYPE: // Unsigned 16-bit integer - return UnsignedDecodeInfo(2); - case ZCL_INT24U_ATTRIBUTE_TYPE: // Unsigned 24-bit integer - return UnsignedDecodeInfo(3); - case ZCL_INT32U_ATTRIBUTE_TYPE: // Unsigned 32-bit integer - return UnsignedDecodeInfo(4); - case ZCL_INT40U_ATTRIBUTE_TYPE: // Unsigned 40-bit integer - return UnsignedDecodeInfo(5); - case ZCL_INT48U_ATTRIBUTE_TYPE: // Unsigned 48-bit integer - return UnsignedDecodeInfo(6); - case ZCL_INT56U_ATTRIBUTE_TYPE: // Unsigned 56-bit integer - return UnsignedDecodeInfo(7); - case ZCL_INT64U_ATTRIBUTE_TYPE: // Unsigned 64-bit integer - return UnsignedDecodeInfo(8); - } - chipDie(); -} - -struct SignedDecodeInfo -{ - unsigned byteCount; - int64_t minValue; - int64_t maxValue; - - constexpr SignedDecodeInfo(unsigned bytes) : - byteCount(bytes), minValue(NumericLimits::MinSignedValue(bytes)), maxValue(NumericLimits::MaxSignedValue(bytes)) - {} -}; - -constexpr SignedDecodeInfo GetSignedDecodeInfo(EmberAfAttributeType type) -{ - - switch (type) - { - case ZCL_INT8S_ATTRIBUTE_TYPE: // Signed 8-bit integer - return SignedDecodeInfo(1); - case ZCL_INT16S_ATTRIBUTE_TYPE: // Signed 16-bit integer - return SignedDecodeInfo(2); - case ZCL_INT24S_ATTRIBUTE_TYPE: // Signed 24-bit integer - return SignedDecodeInfo(3); - case ZCL_INT32S_ATTRIBUTE_TYPE: // Signed 32-bit integer - return SignedDecodeInfo(4); - case ZCL_INT40S_ATTRIBUTE_TYPE: // Signed 40-bit integer - return SignedDecodeInfo(5); - case ZCL_INT48S_ATTRIBUTE_TYPE: // Signed 48-bit integer - return SignedDecodeInfo(6); - case ZCL_INT56S_ATTRIBUTE_TYPE: // Signed 56-bit integer - return SignedDecodeInfo(7); - case ZCL_INT64S_ATTRIBUTE_TYPE: // Signed 64-bit integer - return SignedDecodeInfo(8); - } - chipDie(); + // This TERRIBLE bit fiddling, however it is small in flash + // and we assert statically the actual values we care about + + // ZCL_INT8U_ATTRIBUTE_TYPE = 0x20, // Unsigned 8-bit integer + // ZCL_INT16U_ATTRIBUTE_TYPE = 0x21, // Unsigned 16-bit integer + // ZCL_INT24U_ATTRIBUTE_TYPE = 0x22, // Unsigned 24-bit integer + // ZCL_INT32U_ATTRIBUTE_TYPE = 0x23, // Unsigned 32-bit integer + // ZCL_INT40U_ATTRIBUTE_TYPE = 0x24, // Unsigned 40-bit integer + // ZCL_INT48U_ATTRIBUTE_TYPE = 0x25, // Unsigned 48-bit integer + // ZCL_INT56U_ATTRIBUTE_TYPE = 0x26, // Unsigned 56-bit integer + // ZCL_INT64U_ATTRIBUTE_TYPE = 0x27, // Unsigned 64-bit integer + // + // ZCL_INT8S_ATTRIBUTE_TYPE = 0x28, // Signed 8-bit integer + // ZCL_INT16S_ATTRIBUTE_TYPE = 0x29, // Signed 16-bit integer + // ZCL_INT24S_ATTRIBUTE_TYPE = 0x2A, // Signed 24-bit integer + // ZCL_INT32S_ATTRIBUTE_TYPE = 0x2B, // Signed 32-bit integer + // ZCL_INT40S_ATTRIBUTE_TYPE = 0x2C, // Signed 40-bit integer + // ZCL_INT48S_ATTRIBUTE_TYPE = 0x2D, // Signed 48-bit integer + // ZCL_INT56S_ATTRIBUTE_TYPE = 0x2E, // Signed 56-bit integer + // ZCL_INT64S_ATTRIBUTE_TYPE = 0x2F, // Signed 64-bit integer + + return (static_cast(type) % 8) + 1; } +static_assert(GetByteCountOfIntegerType(ZCL_INT8U_ATTRIBUTE_TYPE) == 1); +static_assert(GetByteCountOfIntegerType(ZCL_INT8S_ATTRIBUTE_TYPE) == 1); +static_assert(GetByteCountOfIntegerType(ZCL_INT16U_ATTRIBUTE_TYPE) == 2); +static_assert(GetByteCountOfIntegerType(ZCL_INT16S_ATTRIBUTE_TYPE) == 2); +static_assert(GetByteCountOfIntegerType(ZCL_INT24U_ATTRIBUTE_TYPE) == 3); +static_assert(GetByteCountOfIntegerType(ZCL_INT24S_ATTRIBUTE_TYPE) == 3); +static_assert(GetByteCountOfIntegerType(ZCL_INT32U_ATTRIBUTE_TYPE) == 4); +static_assert(GetByteCountOfIntegerType(ZCL_INT32S_ATTRIBUTE_TYPE) == 4); +static_assert(GetByteCountOfIntegerType(ZCL_INT40U_ATTRIBUTE_TYPE) == 5); +static_assert(GetByteCountOfIntegerType(ZCL_INT40S_ATTRIBUTE_TYPE) == 5); +static_assert(GetByteCountOfIntegerType(ZCL_INT48U_ATTRIBUTE_TYPE) == 6); +static_assert(GetByteCountOfIntegerType(ZCL_INT48S_ATTRIBUTE_TYPE) == 6); +static_assert(GetByteCountOfIntegerType(ZCL_INT56U_ATTRIBUTE_TYPE) == 7); +static_assert(GetByteCountOfIntegerType(ZCL_INT56S_ATTRIBUTE_TYPE) == 7); +static_assert(GetByteCountOfIntegerType(ZCL_INT64U_ATTRIBUTE_TYPE) == 8); +static_assert(GetByteCountOfIntegerType(ZCL_INT64S_ATTRIBUTE_TYPE) == 8); /// Encodes the string of type stringType pointed to by `reader` into the TLV `writer`. /// Then encoded string will be at tag `tag` and of type `tlvType` @@ -173,7 +147,8 @@ CHIP_ERROR EncodeString(EmberAttributeDataBuffer::PascalStringType stringType, T CHIP_ERROR EmberAttributeDataBuffer::DecodeUnsignedInteger(chip::TLV::TLVReader & reader, EndianWriter & writer) { - UnsignedDecodeInfo info = GetUnsignedDecodeInfo(mAttributeType); + const unsigned byteCount = GetByteCountOfIntegerType(mAttributeType); + const uint64_t maxValue = NumericLimits::MaxUnsignedValue(byteCount); // Any size of integer can be read by TLV getting 64-bit integers uint64_t value; @@ -181,7 +156,7 @@ CHIP_ERROR EmberAttributeDataBuffer::DecodeUnsignedInteger(chip::TLV::TLVReader if (reader.GetType() == TLV::kTLVType_Null) { // we know mIsNullable due to the check at the top of ::Decode - value = NumericLimits::UnsignedMaxValueToNullValue(info.maxValue); + value = NumericLimits::UnsignedMaxValueToNullValue(maxValue); } else { @@ -189,20 +164,22 @@ CHIP_ERROR EmberAttributeDataBuffer::DecodeUnsignedInteger(chip::TLV::TLVReader bool valid = // Value is in [0, max] RANGE - (value <= info.maxValue) + (value <= maxValue) // Nullable values reserve a specific value to mean NULL - && !(mIsNullable && (value == NumericLimits::UnsignedMaxValueToNullValue(info.maxValue))); + && !(mIsNullable && (value == NumericLimits::UnsignedMaxValueToNullValue(maxValue))); VerifyOrReturnError(valid, CHIP_IM_GLOBAL_STATUS(ConstraintError)); } - writer.EndianPut(value, info.byteCount); + writer.EndianPut(value, byteCount); return CHIP_NO_ERROR; } CHIP_ERROR EmberAttributeDataBuffer::DecodeSignedInteger(chip::TLV::TLVReader & reader, EndianWriter & writer) { - SignedDecodeInfo info = GetSignedDecodeInfo(mAttributeType); + const unsigned byteCount = GetByteCountOfIntegerType(mAttributeType); + const int64_t minValue = NumericLimits::MinSignedValue(byteCount); + const int64_t maxValue = NumericLimits::MaxSignedValue(byteCount); // Any size of integer can be read by TLV getting 64-bit integers int64_t value; @@ -210,7 +187,7 @@ CHIP_ERROR EmberAttributeDataBuffer::DecodeSignedInteger(chip::TLV::TLVReader & if (reader.GetType() == TLV::kTLVType_Null) { // we know mIsNullable due to the check at the top of ::Decode - value = NumericLimits::SignedMinValueToNullValue(info.minValue); + value = NumericLimits::SignedMinValueToNullValue(minValue); } else { @@ -218,13 +195,13 @@ CHIP_ERROR EmberAttributeDataBuffer::DecodeSignedInteger(chip::TLV::TLVReader & bool valid = // Value is in [min, max] RANGE - ((value >= info.minValue) && (value <= info.maxValue)) + ((value >= minValue) && (value <= maxValue)) // Nullable values reserve a specific value to mean NULL - && !(mIsNullable && (value == NumericLimits::SignedMinValueToNullValue(info.minValue))); + && !(mIsNullable && (value == NumericLimits::SignedMinValueToNullValue(minValue))); VerifyOrReturnError(valid, CHIP_IM_GLOBAL_STATUS(ConstraintError)); } - writer.EndianPutSigned(value, info.byteCount); + writer.EndianPutSigned(value, byteCount); return CHIP_NO_ERROR; } @@ -384,23 +361,12 @@ CHIP_ERROR EmberAttributeDataBuffer::EncodeInteger(chip::TLV::TLVWriter & writer uint8_t raw_bytes[8]; - const bool isSigned = IsSignedAttributeType(mAttributeType); - - unsigned byteCount; - uint64_t nullValueAsU64; + const bool isSigned = IsSignedAttributeType(mAttributeType); + const unsigned byteCount = GetByteCountOfIntegerType(mAttributeType); - if (isSigned) - { - const SignedDecodeInfo info = GetSignedDecodeInfo(mAttributeType); - byteCount = info.byteCount; - nullValueAsU64 = static_cast(info.minValue); - } - else - { - const UnsignedDecodeInfo info = GetUnsignedDecodeInfo(mAttributeType); - byteCount = info.byteCount; - nullValueAsU64 = info.maxValue; - } + const uint64_t nullValueAsU64 = isSigned + ? static_cast(NumericLimits::SignedMinValueToNullValue(NumericLimits::MinSignedValue(byteCount))) + : NumericLimits::UnsignedMaxValueToNullValue(NumericLimits::MaxUnsignedValue(byteCount)); VerifyOrDie(sizeof(raw_bytes) >= byteCount); if (!reader.ReadBytes(raw_bytes, byteCount).IsSuccess()) From 813c2455b7af50f9f39810040a7e0782b22c05fc Mon Sep 17 00:00:00 2001 From: Ethan Zhou <73028112+ethanzhouyc@users.noreply.github.com> Date: Mon, 28 Oct 2024 17:12:28 -0400 Subject: [PATCH 142/149] update zap version to 10.24 (#36271) --- scripts/setup/zap.json | 4 ++-- scripts/setup/zap.version | 2 +- scripts/tools/zap/zap_execution.py | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/setup/zap.json b/scripts/setup/zap.json index 8b18116caaa5be..8b64288e667f04 100644 --- a/scripts/setup/zap.json +++ b/scripts/setup/zap.json @@ -8,13 +8,13 @@ "mac-amd64", "windows-amd64" ], - "tags": ["version:2@v2024.10.15-nightly.1"] + "tags": ["version:2@v2024.10.24-nightly.1"] }, { "_comment": "Always get the amd64 version on mac until usable arm64 zap build is available", "path": "fuchsia/third_party/zap/mac-amd64", "platforms": ["mac-arm64"], - "tags": ["version:2@v2024.10.15-nightly.1"] + "tags": ["version:2@v2024.10.24-nightly.1"] } ] } diff --git a/scripts/setup/zap.version b/scripts/setup/zap.version index e58d8c5cac5d73..0696cc2123a3ed 100644 --- a/scripts/setup/zap.version +++ b/scripts/setup/zap.version @@ -1 +1 @@ -v2024.10.15-nightly +v2024.10.24-nightly diff --git a/scripts/tools/zap/zap_execution.py b/scripts/tools/zap/zap_execution.py index 9ed0b0f222ab38..72d68a74ffd4c2 100644 --- a/scripts/tools/zap/zap_execution.py +++ b/scripts/tools/zap/zap_execution.py @@ -23,7 +23,7 @@ # Use scripts/tools/zap/version_update.py to manage ZAP versioning as many # files may need updating for versions # -MIN_ZAP_VERSION = '2024.10.15' +MIN_ZAP_VERSION = '2024.10.24' class ZapTool: From bcdddaa9fd53d8b6d71daf6dde6d5276ce4c8d5c Mon Sep 17 00:00:00 2001 From: Junior Martinez <67972863+jmartinez-silabs@users.noreply.github.com> Date: Mon, 28 Oct 2024 17:48:23 -0400 Subject: [PATCH 143/149] =?UTF-8?q?[Silabs]=20Add=20logs=20for=20ble=20con?= =?UTF-8?q?nection=20negotiations=20events.=20add=20a=20step=20to=20increa?= =?UTF-8?q?=E2=80=A6=20(#36254)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Add logs for ble connection negotiations events. add a step to increase the ble connection timeout when it is under a prefer threshold. * Update src/platform/silabs/efr32/BLEManagerImpl.cpp Co-authored-by: Kiel Oleson * Apply suggestions from code review Co-authored-by: Ricardo Casallas <77841255+rcasallas-silabs@users.noreply.github.com> --------- Co-authored-by: Kiel Oleson Co-authored-by: Ricardo Casallas <77841255+rcasallas-silabs@users.noreply.github.com> --- src/platform/silabs/BLEManagerImpl.h | 1 + src/platform/silabs/efr32/BLEManagerImpl.cpp | 28 ++++++++++++++++++-- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/src/platform/silabs/BLEManagerImpl.h b/src/platform/silabs/BLEManagerImpl.h index 9380accce38e55..9ebf113c4f8afa 100644 --- a/src/platform/silabs/BLEManagerImpl.h +++ b/src/platform/silabs/BLEManagerImpl.h @@ -68,6 +68,7 @@ class BLEManagerImpl final : public BLEManager, private BleLayer, private BlePla int32_t SendBLEAdvertisementCommand(void); #else void HandleConnectEvent(volatile sl_bt_msg_t * evt); + void HandleConnectParams(volatile sl_bt_msg_t * evt); void HandleConnectionCloseEvent(volatile sl_bt_msg_t * evt); void HandleWriteEvent(volatile sl_bt_msg_t * evt); void UpdateMtu(volatile sl_bt_msg_t * evt); diff --git a/src/platform/silabs/efr32/BLEManagerImpl.cpp b/src/platform/silabs/efr32/BLEManagerImpl.cpp index ef553bffa152a1..1f8704896f71cb 100644 --- a/src/platform/silabs/efr32/BLEManagerImpl.cpp +++ b/src/platform/silabs/efr32/BLEManagerImpl.cpp @@ -674,6 +674,21 @@ void BLEManagerImpl::HandleConnectEvent(volatile sl_bt_msg_t * evt) PlatformMgr().ScheduleWork(DriveBLEState, 0); } +void BLEManagerImpl::HandleConnectParams(volatile sl_bt_msg_t * evt) +{ + sl_bt_evt_connection_parameters_t * con_param_evt = (sl_bt_evt_connection_parameters_t *) &(evt->data); + + if (con_param_evt->timeout < BLE_CONFIG_TIMEOUT) + { + ChipLogProgress(DeviceLayer, "Request to increase the connection timeout from %d to %d", con_param_evt->timeout, + BLE_CONFIG_TIMEOUT); + sl_bt_connection_set_parameters(con_param_evt->connection, BLE_CONFIG_MIN_INTERVAL, BLE_CONFIG_MAX_INTERVAL, + BLE_CONFIG_LATENCY, BLE_CONFIG_TIMEOUT, BLE_CONFIG_MIN_CE_LENGTH, BLE_CONFIG_MAX_CE_LENGTH); + } + + PlatformMgr().ScheduleWork(DriveBLEState, 0); +} + void BLEManagerImpl::HandleConnectionCloseEvent(volatile sl_bt_msg_t * evt) { sl_bt_evt_connection_closed_t * conn_evt = (sl_bt_evt_connection_closed_t *) &(evt->data); @@ -1061,11 +1076,20 @@ extern "C" void sl_bt_on_event(sl_bt_msg_t * evt) } break; case sl_bt_evt_connection_parameters_id: { - // ChipLogProgress(DeviceLayer, "Connection parameter ID received"); + ChipLogProgress(DeviceLayer, "Connection parameter ID received - i:%d, l:%d, t:%d, sm:%d", + evt->data.evt_connection_parameters.interval, evt->data.evt_connection_parameters.latency, + evt->data.evt_connection_parameters.timeout, evt->data.evt_connection_parameters.security_mode); + chip::DeviceLayer::Internal::BLEMgrImpl().HandleConnectParams(evt); } break; case sl_bt_evt_connection_phy_status_id: { - // ChipLogProgress(DeviceLayer, "PHY update procedure is completed"); + ChipLogProgress(DeviceLayer, "Connection phy status ID received - phy:%d", evt->data.evt_connection_phy_status.phy); + } + break; + case sl_bt_evt_connection_data_length_id: { + ChipLogProgress(DeviceLayer, "Connection data length ID received - txL:%d, txT:%d, rxL:%d, rxL:%d", + evt->data.evt_connection_data_length.tx_data_len, evt->data.evt_connection_data_length.tx_time_us, + evt->data.evt_connection_data_length.rx_data_len, evt->data.evt_connection_data_length.rx_time_us); } break; case sl_bt_evt_connection_closed_id: { From cea1e36e314a760e0e633dcc735de9a1d130cfde Mon Sep 17 00:00:00 2001 From: Vivien Nicolas Date: Tue, 29 Oct 2024 01:49:04 +0100 Subject: [PATCH 144/149] =?UTF-8?q?[darwin-framework-tool]=20Set=20device?= =?UTF-8?q?=20delegate=20when=20using=20MTRDevice=20with=20=E2=80=93use-mt?= =?UTF-8?q?r-device=20(#36263)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- examples/darwin-framework-tool/BUILD.gn | 2 + .../commands/clusters/ReportCommandBridge.h | 4 +- .../commands/common/CHIPCommandBridge.h | 2 + .../commands/common/CHIPCommandBridge.mm | 15 ++++ .../commands/common/DeviceDelegate.h | 23 +++++++ .../commands/common/DeviceDelegate.mm | 69 +++++++++++++++++++ .../Matter.xcodeproj/project.pbxproj | 8 +++ 7 files changed, 120 insertions(+), 3 deletions(-) create mode 100644 examples/darwin-framework-tool/commands/common/DeviceDelegate.h create mode 100644 examples/darwin-framework-tool/commands/common/DeviceDelegate.mm diff --git a/examples/darwin-framework-tool/BUILD.gn b/examples/darwin-framework-tool/BUILD.gn index 0d1e142f1074df..1c492ba10a1241 100644 --- a/examples/darwin-framework-tool/BUILD.gn +++ b/examples/darwin-framework-tool/BUILD.gn @@ -194,6 +194,8 @@ executable("darwin-framework-tool") { "commands/common/CertificateIssuer.mm", "commands/common/ControllerStorage.h", "commands/common/ControllerStorage.mm", + "commands/common/DeviceDelegate.h", + "commands/common/DeviceDelegate.mm", "commands/common/MTRDevice_Externs.h", "commands/common/MTRError.mm", "commands/common/MTRError_Utils.h", diff --git a/examples/darwin-framework-tool/commands/clusters/ReportCommandBridge.h b/examples/darwin-framework-tool/commands/clusters/ReportCommandBridge.h index cd8125e3b12273..ba3428341ec8e8 100644 --- a/examples/darwin-framework-tool/commands/clusters/ReportCommandBridge.h +++ b/examples/darwin-framework-tool/commands/clusters/ReportCommandBridge.h @@ -105,9 +105,7 @@ class ReadAttribute : public ModelCommand { LogNSError("Error reading attribute", error); RemoteDataModelLogger::LogAttributeErrorAsJSON(endpoint, cluster, attribute, error); } else { - for (id item in values) { - NSLog(@"Response Item: %@", [item description]); - } + NSLog(@"cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u: %@", mClusterId, mAttributeId, endpointId, values); RemoteDataModelLogger::LogAttributeAsJSON(endpoint, cluster, attribute, values); } diff --git a/examples/darwin-framework-tool/commands/common/CHIPCommandBridge.h b/examples/darwin-framework-tool/commands/common/CHIPCommandBridge.h index 90f3a6c56415f6..2f53c0dd7bc4db 100644 --- a/examples/darwin-framework-tool/commands/common/CHIPCommandBridge.h +++ b/examples/darwin-framework-tool/commands/common/CHIPCommandBridge.h @@ -52,6 +52,7 @@ class CHIPCommandBridge : public Command { AddArgument("commissioner-vendor-id", 0, UINT16_MAX, &mCommissionerVendorId, "The vendor id to use for darwin-framework-tool. If not provided, chip::VendorId::TestVendor1 (65521, 0xFFF1) will be " "used."); + AddArgument("pretend-thread-enabled", 0, 1, &mPretendThreadEnabled, "When the command is issued using an MTRDevice (via -use-mtr-device), instructs the MTRDevice to treat the target device as a Thread device."); } /////////// Command Interface ///////// @@ -164,4 +165,5 @@ class CHIPCommandBridge : public Command { chip::Optional mPaaTrustStorePath; chip::Optional mCommissionerVendorId; std::string mCurrentIdentity; + chip::Optional mPretendThreadEnabled; }; diff --git a/examples/darwin-framework-tool/commands/common/CHIPCommandBridge.mm b/examples/darwin-framework-tool/commands/common/CHIPCommandBridge.mm index b237acaa5b7132..2eba24c84ad44c 100644 --- a/examples/darwin-framework-tool/commands/common/CHIPCommandBridge.mm +++ b/examples/darwin-framework-tool/commands/common/CHIPCommandBridge.mm @@ -28,12 +28,15 @@ #import "CHIPCommandStorageDelegate.h" #import "CertificateIssuer.h" #import "ControllerStorage.h" +#import "DeviceDelegate.h" #include "MTRError_Utils.h" #include #include static CHIPToolPersistentStorageDelegate * storage = nil; +static DeviceDelegate * sDeviceDelegate = nil; +static dispatch_queue_t sDeviceDelegateDispatchQueue = nil; std::set CHIPCommandBridge::sDeferredCleanups; std::map CHIPCommandBridge::mControllers; dispatch_queue_t CHIPCommandBridge::mOTAProviderCallbackQueue; @@ -302,6 +305,18 @@ __auto_type * device = [MTRDevice deviceWithNodeID:@(nodeId) controller:controller]; VerifyOrReturnValue(nil != device, nil); + // The device delegate is initialized only once, when the first MTRDevice is created. + // As a result, subsequent commands using --use-mtr-device don’t need to specify the + // `--pretend-thread-enabled 1` argument again. Any further attempts to set it to `0` will also be ignored. + if (sDeviceDelegate == nil) { + sDeviceDelegate = [[DeviceDelegate alloc] init]; + sDeviceDelegateDispatchQueue = dispatch_queue_create("com.chip.devicedelegate", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); + if (mPretendThreadEnabled.ValueOr(false)) { + [sDeviceDelegate setPretendThreadEnabled:YES]; + } + } + [device addDelegate:sDeviceDelegate queue:sDeviceDelegateDispatchQueue]; + return device; } diff --git a/examples/darwin-framework-tool/commands/common/DeviceDelegate.h b/examples/darwin-framework-tool/commands/common/DeviceDelegate.h new file mode 100644 index 00000000000000..a3f5cf427f191c --- /dev/null +++ b/examples/darwin-framework-tool/commands/common/DeviceDelegate.h @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#import + +@interface DeviceDelegate : NSObject +- (void)setPretendThreadEnabled:(BOOL)threadEnabled; +@end diff --git a/examples/darwin-framework-tool/commands/common/DeviceDelegate.mm b/examples/darwin-framework-tool/commands/common/DeviceDelegate.mm new file mode 100644 index 00000000000000..ecf8e708e26ff3 --- /dev/null +++ b/examples/darwin-framework-tool/commands/common/DeviceDelegate.mm @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#import "DeviceDelegate.h" + +#include + +NS_ASSUME_NONNULL_BEGIN + +@interface DeviceDelegate () +@property (nonatomic, readwrite) BOOL threadEnabled; +@end + +@implementation DeviceDelegate +- (instancetype)init +{ + if (self = [super init]) { + _threadEnabled = NO; + } + return self; +} + +- (void)device:(MTRDevice *)device stateChanged:(MTRDeviceState)state +{ +} + +- (void)device:(MTRDevice *)device receivedAttributeReport:(NSArray *> *)attributeReport +{ +} + +- (void)device:(MTRDevice *)device receivedEventReport:(NSArray *> *)eventReport +{ +} + +- (void)deviceCachePrimed:(MTRDevice *)device +{ +} + +- (void)deviceConfigurationChanged:(MTRDevice *)device +{ +} + +- (void)setPretendThreadEnabled:(BOOL)threadEnabled +{ + _threadEnabled = threadEnabled; +} + +- (BOOL)unitTestPretendThreadEnabled:(MTRDevice *)device +{ + return _threadEnabled; +} +@end + +NS_ASSUME_NONNULL_END diff --git a/src/darwin/Framework/Matter.xcodeproj/project.pbxproj b/src/darwin/Framework/Matter.xcodeproj/project.pbxproj index 6a802900d8d30c..673f1cacaabc10 100644 --- a/src/darwin/Framework/Matter.xcodeproj/project.pbxproj +++ b/src/darwin/Framework/Matter.xcodeproj/project.pbxproj @@ -336,6 +336,8 @@ B2E0D7B7245B0B5C003C5B48 /* MTRQRCodeSetupPayloadParser.mm in Sources */ = {isa = PBXBuildFile; fileRef = B2E0D7AE245B0B5C003C5B48 /* MTRQRCodeSetupPayloadParser.mm */; }; B2E0D7B8245B0B5C003C5B48 /* MTRSetupPayload.h in Headers */ = {isa = PBXBuildFile; fileRef = B2E0D7AF245B0B5C003C5B48 /* MTRSetupPayload.h */; settings = {ATTRIBUTES = (Public, ); }; }; B2E0D7B9245B0B5C003C5B48 /* MTRSetupPayload.mm in Sources */ = {isa = PBXBuildFile; fileRef = B2E0D7B0245B0B5C003C5B48 /* MTRSetupPayload.mm */; }; + B409D0AE2CCFB89600A7ED5A /* DeviceDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = B409D0AC2CCFB89600A7ED5A /* DeviceDelegate.h */; }; + B409D0AF2CCFB89600A7ED5A /* DeviceDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = B409D0AD2CCFB89600A7ED5A /* DeviceDelegate.mm */; }; B43B39EA2CB859A5006AA284 /* DumpMemoryGraphCommand.mm in Sources */ = {isa = PBXBuildFile; fileRef = B43B39E62CB859A5006AA284 /* DumpMemoryGraphCommand.mm */; }; B43B39EB2CB859A5006AA284 /* LeaksTool.mm in Sources */ = {isa = PBXBuildFile; fileRef = B43B39E82CB859A5006AA284 /* LeaksTool.mm */; }; B43B39EC2CB859A5006AA284 /* DumpMemoryGraphCommand.h in Headers */ = {isa = PBXBuildFile; fileRef = B43B39E52CB859A5006AA284 /* DumpMemoryGraphCommand.h */; }; @@ -800,6 +802,8 @@ B2E0D7AE245B0B5C003C5B48 /* MTRQRCodeSetupPayloadParser.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MTRQRCodeSetupPayloadParser.mm; sourceTree = ""; }; B2E0D7AF245B0B5C003C5B48 /* MTRSetupPayload.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MTRSetupPayload.h; sourceTree = ""; }; B2E0D7B0245B0B5C003C5B48 /* MTRSetupPayload.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = MTRSetupPayload.mm; sourceTree = ""; }; + B409D0AC2CCFB89600A7ED5A /* DeviceDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DeviceDelegate.h; sourceTree = ""; }; + B409D0AD2CCFB89600A7ED5A /* DeviceDelegate.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = DeviceDelegate.mm; sourceTree = ""; }; B43B39E42CB859A5006AA284 /* Commands.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Commands.h; sourceTree = ""; }; B43B39E52CB859A5006AA284 /* DumpMemoryGraphCommand.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DumpMemoryGraphCommand.h; sourceTree = ""; }; B43B39E62CB859A5006AA284 /* DumpMemoryGraphCommand.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = DumpMemoryGraphCommand.mm; sourceTree = ""; }; @@ -1013,6 +1017,8 @@ 037C3D9B2991BD4F00B7EEE2 /* common */ = { isa = PBXGroup; children = ( + B409D0AC2CCFB89600A7ED5A /* DeviceDelegate.h */, + B409D0AD2CCFB89600A7ED5A /* DeviceDelegate.mm */, B43B39EF2CB99090006AA284 /* CertificateIssuer.h */, B43B39F02CB99090006AA284 /* CertificateIssuer.mm */, B43B39F12CB99090006AA284 /* ControllerStorage.h */, @@ -1673,6 +1679,7 @@ B4F773CA2CB54B61008C6B23 /* LeakChecker.h in Headers */, B43B39F82CB99090006AA284 /* CertificateIssuer.h in Headers */, B43B39F92CB99090006AA284 /* PreferencesStorage.h in Headers */, + B409D0AE2CCFB89600A7ED5A /* DeviceDelegate.h in Headers */, B43B39FA2CB99090006AA284 /* ControllerStorage.h in Headers */, 037C3DB82991BD5000B7EEE2 /* ClusterCommandBridge.h in Headers */, 037C3DC82991BD5100B7EEE2 /* CHIPToolKeypair.h in Headers */, @@ -2058,6 +2065,7 @@ 0382FA302992F40C00247BBB /* ComplexArgumentParser.cpp in Sources */, 039145E12993102B00257B3E /* main.mm in Sources */, 037C3DD42991BD5200B7EEE2 /* logging.mm in Sources */, + B409D0AF2CCFB89600A7ED5A /* DeviceDelegate.mm in Sources */, 512431282BA0C8BF000BC136 /* SetMRPParametersCommand.mm in Sources */, 512431292BA0C8BF000BC136 /* ResetMRPParametersCommand.mm in Sources */, 037C3DB32991BD5000B7EEE2 /* OpenCommissioningWindowCommand.mm in Sources */, From 73a1c0b740f81d1c28dff25d60dda3e4fc322f71 Mon Sep 17 00:00:00 2001 From: Vivien Nicolas Date: Tue, 29 Oct 2024 03:20:16 +0100 Subject: [PATCH 145/149] [examples-app] Add options to configure MRP intervals at application launch (#36272) --- examples/platform/linux/Options.cpp | 49 +++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/examples/platform/linux/Options.cpp b/examples/platform/linux/Options.cpp index 6f8afea5bb496b..30732ae7e0a034 100644 --- a/examples/platform/linux/Options.cpp +++ b/examples/platform/linux/Options.cpp @@ -46,6 +46,10 @@ #include #endif +#if CONFIG_BUILD_FOR_HOST_UNIT_TEST +#include +#endif + using namespace chip; using namespace chip::ArgParser; using namespace chip::Platform; @@ -112,6 +116,9 @@ enum kDeviceOption_WiFiSupports5g, #if CONFIG_BUILD_FOR_HOST_UNIT_TEST kDeviceOption_SubscriptionResumptionRetryIntervalSec, + kDeviceOption_IdleRetransmitTimeout, + kDeviceOption_ActiveRetransmitTimeout, + kDeviceOption_ActiveThresholdTime, #endif #if CHIP_WITH_NLFAULTINJECTION kDeviceOption_FaultInjection, @@ -187,6 +194,9 @@ OptionDef sDeviceOptionDefs[] = { #if CONFIG_BUILD_FOR_HOST_UNIT_TEST { "subscription-capacity", kArgumentRequired, kDeviceOption_SubscriptionCapacity }, { "subscription-resumption-retry-interval", kArgumentRequired, kDeviceOption_SubscriptionResumptionRetryIntervalSec }, + { "idle-retransmit-timeout", kArgumentRequired, kDeviceOption_IdleRetransmitTimeout }, + { "active-retransmit-timeout", kArgumentRequired, kDeviceOption_ActiveRetransmitTimeout }, + { "active-threshold-time", kArgumentRequired, kDeviceOption_ActiveThresholdTime }, #endif #if CHIP_WITH_NLFAULTINJECTION { "faults", kArgumentRequired, kDeviceOption_FaultInjection }, @@ -335,6 +345,19 @@ const char * sDeviceOptionHelp = " Max number of subscriptions the device will allow\n" " --subscription-resumption-retry-interval\n" " subscription timeout resumption retry interval in seconds\n" + " --idle-retransmit-timeout \n" + " Sets the MRP idle retry interval (in milliseconds).\n" + " This interval is used by the peer to calculate the retransmission timeout when the current device is considered idle.\n" + "\n" + " --active-retransmit-timeout \n" + " Sets the MRP active retry interval (in milliseconds).\n" + " This interval is used by the peer to calculate the retransmission timeout when the current device is considered " + "active.\n" + "\n" + " --active-threshold-time

=qI-Q zrH;>*Ty4d}t`j?3K}XEuR<-@ts&vts`-sTHKjY~86j+dh==H}glz%-3k(K5whmJD? zzEuT3hDtBB-5@JGgWi0d0}aBd9cjtRY?C0dUura#A~}-RFzF?Sd=%Pm;+UsI1EQO& zI<7)8ky(Ne!g{6Y^JEFPQmSBX39M`Ea3Au*IL(&)6b@k`;hkSr3{|e?wufMBWnyM| zAJ9Y2L?R+1aiYJFLz-D`vUcLt+*sG#
(&u!3OI`uO#`a@!%8Wpfj`L}&_F}RFc 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
nbL1g-BZmi>huza|YOd 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%0AOi zE~cok1;}I704WXNJ_TF$BoNm5&F^!JkzW=!OU(>zH!9J`%TiN^6sZ#j9lAu;)ni`? z6dj!aR-lMuo8QUXu`iatH~Z@)ESjq2P4Lyt1v?_*l zM;BI!j>9sYzjDH;T|?*F)o}cLdS(GBl+JHCrVBVjUn1Qlvw8T6EiAv)2RFY7>PruR zUGV7j^ERJwn#y?`=zHN|MQfF7msd0wDR%vQ877T<{b1jNCnow5y=%;@>AU6>*vx*A z=gjf^d(Ln2LWeyCfXYxQSkCBFi_43!OxZ?#c#iC3h(1rD?B^@m_=23>w9R|3mr+N&gSYq(1QI zP1EUGaSg^l`iEz>ZklZW%sry-vQC}|tFhGoIX;vWrlK6GttaKfwREm_Itbt5opb}phEKt&D(P~wRqk559wOr{3&p-Px2PM zE>6s$)b3wkAEKSBL0-+!-O=;(ZPrN4!Hqr_{|l#Uuc+ep92$2MfNG%qBXx@e%DQIB z;IuYL-b}$w3FzjO;%Xi+r>^YbEhL03LzpLY{9Lu_hw~&3j~vd&;qo)JtJUxR?PL>O z_yMelivODdtkByZx(spxlZEka7NgS`L;ltkY#iGcP_#A^~S$ZxsTlZPnWvM zjXLn6Tsj!s$97nvzanwUCru?v`AEk5*k%cFFu$3J=;SPqdm{I;pn}r*dN6g--vb*` zhq_r{xY?e3Qv4j4yGtcfSRWhv+mT?swHRO^38S%!a2&oFCq45I&gpNq{|XP_<_6@Whjo*}y>+{n->$X|yPJ4#2d<^6u1L_eMoxDD0fbuJ4R%An2s+mLsLIu8 zs8>gYj))b>iI0{88?=8%83sCTZaTaxGPaMmp)Os8DD1JkC$z9H&ejW2-9>jwDz0 z0dIjL13Ykp7X3@sNw(bl8pzxBM&cr-2Tg0{>kW zvn&6(rTuxwnpAaVg>N>V{lAL1Bi=3nb(8R~Yavx8(y-7St{6WD7@uL!6(TuO+TGaJ z^F%QAlYr51uyrtkCustgbbkgl?j|{hii&z}MD1PtSe2M1Z42O}rcT9q&n>VCJ?69W z3^}~$Tk}|_2 z?Oxt0&CVBi=7TY|L|?J(q8P6+HCq46`wifTot!JG>Leh~JU}|9#^9e+gw|nh9`o2{ z24FO`H^y9TRrtL!_We2VXb zsH1ryEWBS^6_d@F zKaj7ThJV%x02sTP^rna}X)qiLbgfW`cY5?6qSwG*bRNCo1s?JrOHjNZ!tvXP=QJM! z$zYCiu9Ag=g@Yxt4mS1+Sh^j9Mj2g>#72UwAC#n+sajpID(xzc%w1;+I8X;1WaD`4r3 z^3I5cwv@UQnMCt>^pg@?Q+uws6NXdU;aMT&J0+?7`^Q3^CDNNi*Bg2Q0Oiuprxe9& z!=B)pKPEMK70@2^V{c#jz(y0uBx9TiTV=~?)bz4RByo}5Rm*h$8w+^mw&0TnHYq5d zTxVwDSGWCmiO@8Q()8w(?E#gvQfD1$b#>nI-SzA}fPN6d!-o*cam>}xj9(nzIXKke z8Li8@noVI=$;C31SOyoWm(b?%#X%hdh~e1!x zRjN-#9aBL39slPW#i1Ye6oJ7`Ab-4={9W1*=;EKNC)+JEl7{A{qEXw)Ft6cVAazh} z;P&{M--mfm;MueLPL0lkcB0xsbM$MC2g{R5}-xQ6Hf zw-%vI{~=L96wCD2H%w%$s|e*8L4v5mC7G7tQuLSQ>X4$)99`$_%dk8?m~;aSEp;b5 z*Hk%KY(H;vVa!uQYV8KQo-G6~(0*{CTjE*Hw)%ChT54eiBj0S{9Lacqwd}zdxaaRM z=g0D7a_Z%-f8-9g`MOwFqDiFt;5AyuzPdr-5<|p=EuoI5=66h1{MFtfhqgJ!z{#zL z(vR75hgyEXAfRj?yrmDfQB}@%<|YYV9bGr1dc$Yr9f?Z24%WZXq_vMtfj&VY-5IdN zL1$723DVi-E!>UO<4lnOJFmbsdc_t8%e-UD$H94e?g_afoFrj>hu#TT4FZ?vKrLsC zwhO*_5nA`p7~~%U@f8}$wM7xqX?CK(eMYO&xR@=j!SHw5L+!@k(}Hsvwys%^OEf=) znCt(L`Xn7wjKAkW6w*COJ_N|R=#euXH{HMG$QtKaMjnhSQgDAb~k+|h9M{@jr%=*zwh8J63T|~O>u3Z*%f_hYbegO6>E@^M_ zfvTf?jLi97M{B2Vb~baeSoS$$}ws6TWM7Mm&oN#igYyNRG8DL|Z8RkhB++-Pnin-@8CHmzGkkIOBzLQI; z2vBlZoom`6X5dqC`pxqh1*m>9%&nBeX-MsAv>d+6h49lycqpHqzI-$`f97%V^Z>PI zh-O!v*8{8r^1ONd&d3v`&jmW=(s}INV=CvkOQdwJ2-KAXF!d9F$zim=3R8z#sU@$vi_-%KAW=S_~M+iEXqXMzjr{ zKqvV1-DwJ%6xk@hvU=q9VYJ7K2_BBVzDk97Y3|+_NwWB$OL?0`hTiagAlHi%#^|u( zLE9FAtxiWk9c=#a+q`7GpV&Vugo=FtrKSqSm1KvUwdjB@wOUL|$aA1e?8I7O8 zmuKXdz%Y9NH7_A{I~QZ}A3QgnXC`CwwUaC`jCQ>se#M<ugwYU#FtUHAUfX=#B~TOvLhBvf%bF~M zzGmlV5|rTFQIFe0H%s|TZAI^IAu1cQxTYR%UFS+EIhe~)FS69{>V)5b7$X*aZ#p-TNBtnexTVPIE~} zJBB?xJ{SUgUNCnw03*}ybE{!@{`zqFP1kvK_dWAbo^dGYd)#4CJ}K?mzN3M=NwyxW zJ)8@>j9Ic;(THc9dxVv#vn)*n-8hONHyl)=(-!Vv7J8a&TvsU4t>nI!Kn=+?WS2uA*cgt9OtBBDhQNOI;tN3KH#?17=J)${F;3 z8Xk!cox8d3q8S>+%Q`#vFroo}hvC_lGXc$%&CI^*_qfdLdQVQ<7aRb#GYgF@c8StV ziIRKpV7)^62ogxviNr@youl+mC9aNo1OwSKvR&_c%J#pdsZuq5%QSRa{b_cW;Jc40 zVSTz%@U^U2qSD^#g&`kK(qUiynuXL|pfqTNvHfK+OADxVrH91&*Xn@7m3u>jz0>ch z3ggcuy>Xv#_I`Zt&rn~-*M_$sQp*`uAjw1vM`}FhdZwyJmD9`2 z(V#E1dbXUz_08a~LeV%ZpGqpY15k^rK&F#8LtZh4s{QSIn-JJb<@_MKfr<8t5G)=oLqAP6SiFz{nLm*sj^r7~hs5_KPca3cSvOguRg?lR_}45GFy;I%yZ@Ug z6RD#YM$9Cb9)3OC6;Z!aLVXG$QU2FQ8@F=1!T}Lo$QEUg$dmXq)qzH`^kDQmy*7+D z39m>?4|N87;eHzj`REu89Y5!L)2W;lw5w?ST@bf6^UKKwzG3yBfN)W);9SA%YQ5J# z>X&))?g9W>FvvKMEo`g=Gp($=qTI_o`KQ55-3;^962ZnhTrD&oO^smhAeJ7 z#Avwmjw}|EQg6P8q_!`$!gOQ9#3i-rIPV`C>(f++sQh_LkU%Y|SqkEa@VRVTD=ypE zB}Tms-jet+`u56Q=_}Or@W=wRf2m}l%ky}iAe1)4FYsgic6#Ep}ad^jYb0OPS71!pD^=~M-(&^r# zpk}u64%$#q&VL2#U}3Q@lRpJDED)L@<3*187#DjOrHf;D+jr9Ojnk3Jy#7+_)!Z!B zw;dIV0xejyX$vzpjQk$TXrn6Zy;H$KVbK+C1|MbH)w7^$>w0^~mde+QZZ)hA52fzY z&lAi|#|mwoamt1a+CvAMP2u4BaIQ)u#?DqhJ+PhPD{4jzH*&~nC2PyVyoIs3y?>e( zeLWL%QlFU)>t*I-LxU`O7$8?_bm?zDf$52^BJD^nuq)xJ%}J5;JZoY*Y=6XL%)7hK zrIXiPJ&se~=yu+!A%6UmP-~OXfUJaZA)3}g@9;1qmN0?Y&R8}q_`J~$=#FjJ(chVN zv#Z~qreyX3n0sf^^8RDkhPP3_vn=NE79I*Z`KkT4@RR6GwjIP&ac}VL8TOQQZ?O?J zx4l* z_U8vV+9jspunpf71k#AT`XmrUrop|qG0T$qt!OVx*Fv^SGnip{DFR%OXO5_TNBPXb zqwQ58`&p`FJng2O#>Y@)!G3i^l$}yun8U~9=`f=aVWhKTxCuXm1^)#us61;W?d@?F zG+W5Vnt2XuCA~yEq%!}9ritE5_HQEW-5SauSAX){Nd>0~(`$b4e@|IPt2>J=PDAdovdHS!C%j8Ww|(BlotH(K&Hd9 zV3SA$Ew7)fI8J?0w{%ZSd_4PsDg!?bdbRnZ(egzE#d^@2U7)DI*Ti;a z%6mJYz{H}$r^}`Fap82%#%jEIZ&O)fDpbZX6*L_5)$HU_SQ3;R_LEku8^hFj8g$9i zB4gqsSFE?m^`jGMQbxeLJ773u@+@>bPw(Q5ahG9U!rcSqwk_?5{^PbD7dXY14)A(0 zhg@ZhXT*002)Ow+BD*!)Avf#gR-IL?!nqVAvi{=N2iAk$G=B`wTN6+XN7yOwHs z3_^xBOeisMufJMA(@(+ksDOGi*Ohw_&*_AzyPYC;HZ3RyyPGIw9*r*a8Bv+Wsy$yn zhAxG+#{Gi1N(}Mw0$w#_D8U;>O={nDX13lGbA;t>02wa9cfX*4UBg6sYn479m>u^~ zWZ`w9D$e=ADNb6!u&$QBC z=Cs6*X#*QgkhF+U&F0_FjK?7>RaMY6GYc2x8`H7PifF3y&nscuVna}9s%)yR|N#?7VAW;N;6tC^a(lEcV z;DJWmAQMf!LUspmUd2s_F;%FGcD?4;#-IPHB4wFV;Ayo#gD^%c`4`$PY;}S2BE8gq zJ7;5ige=Z-^xGT*$O)<8!?MGf$IC&XT5y$-b-tI6!t*@}C}mk=-nvUv&_z_cJ4-I3 zjB3MipD>VEitw(H)ae3`Nvqg-9q%Ql$uz?^3<>G(!j;P}|Dl0|d)+pUjda&ey1Z@v z;l8IB{haQ+yn!X2!f~4EhX#``uB2SKS)X20q!3~_0vyVg|3h;S7v9T#jrihoA|?}Z z93bl`V?WdM-l3TKl})oGn*M$Q{wt9j_yr?_3nOWpx;l@8iHHTQD(Uf}Ani9;Ybx%m zAvB5Mmg|_pbhYFWE0UXI0HbgHDzb&gY`E|35~F4Y)OgYrU#~o}H&p@62LA`w8KW4W zkOoSaqcoEq(13@5OYREBc=u~FM7TG!P-Q4N_=Yhdf;MYqQMW%D@7Kk}&t@Q{U;^@7NvFN8oOrWf6)q*|G95qhUrypQs2Gii%!SBjTTZ|T_QyIi=ye!*({3x37a>#)XLMgg!0teIF3MAFw92Z8r<`CT60f1Pm9s)2wj_g}M=lQNVa8mM@YdowY_<5>@1qp@74Zz5y6 zl*Xd?0Me+fVKMB{#&Q+MNU>~hZ#SmvFLGwIEO#b8e?-0i>@%plHo6#Q3ul~&Wwbud z*%WIKF8;%LLacYR5JrSd^@9V5}y>_8?${O|j^d(MfOGuEEu2u@4p#$s& zde;{Z*{+J3JAJau!PHm-{=Hh=T#|KY#8NFk%}>pCd3SZ3EK^|1x|akbeJa{>=EdXt zmiTqxI%@J|AQggu@iuT7puT;H;R>S3St%h(X!myYNxYV>&yIdu;%HS^9z}L_mDBp5 zZn>_2K=*ITHfc{f7!tq4D)qb#cC-(qb{gB9Y~vNf&(4QM5Co-bcOw7nyd!M=rH-F9 z?qHLz(2OET{Y;G8y?Qf=H-TNrS&)3>H@jZ~wKCKv-T&tS^mr&N{*_BqYsFUZdIf4@ zE&u{`X3u8o{k(LuE})vMiQ8gc5tfCMXgOYsZ~?~+=fX9_V`8F&(u6Ds7`x{yG+*yh zDY0bQ@X##(#jAy-u&BI?QpWXoKBYsUMT#ROC$C?BcpuwD>FN$}1cVd08L8cRtL_9} zKrtOm=yi1%aBL`3*E`Vy#w&a|2ShjG^d{M5qaKfv#JtjNZMX`LK~7J`9Mlre0^pU_ zQ>~$VOh`ieJHJ{YZi~%*+v@^5$4^^6p7<$lm#i6pMBm1lyWq97^fWWy7BX; zmCDiwsUVO#+$Sg>rt!uP@}c}aXkcpk%}`j!N${?8dTE3HMMUINUg|-i1$)rtUT`XT zOBj0yRdwzR|M_ifrC1yv<+CX?a$A1+YP$L0s+BEiS%$iIoX92ee8&}4496Amq&iu- zcW)>yH{IN*73s3vO6Y;f#s=-Di_^oyIZSSp7Rn?Sv@09d#^xh`-A z8)>!-V-H%ph^YO=KjDmd$zgBM%zENm)>(s~CDvY@Rn~K{AH=A63=cHOe?ZBnZgQ83 zPk1SrZz^YhZYXeQ32wcY1o)y?9Ytylr5V~RCUw7?w_vE+=FwAyKd0BttyF>yT)#xA zi1Xs}lKdmwXkw<`UeUh?+&-J|;MFB}s;Rv~<-$mgoV>G+B&sx^A^s0j!Um0JYrVGr zq4kZbJN`7cv`|3r;aun%!<#~n9zjz*li0g0%lSU0ldYp=s69)5WGRKDg)zn(=H^M( zuY5fYeUrAy!)Ivp6>~BJO=kPJ#GDY;nYkSvG=WIvJTD@o;^~Q}b8NXMQAo)>I;)Ls zlrO8$B~bO_KUOi_^h9?(DNV}`j9GkQK#jgl>Fd1i;e zt~?P>s$pD+=;>#Q%Dio9Gwq&kNTdJDBoP{s_%$|=6dp?*vG@jHW;@a^By;~BUqFFx zR6|U2k;Ovu*mC_tf9kx=A{*&6P`9cW?WA)6JLv*|39|^*K-^~j&_G})T3A}RK=*q@ z-M|H2<>P$@Pg`hQaa7(@hZq$uVLZ)!d4|ZQjG#Da?Dr2A5Gc>^@WCdp!_4~+{d8uI}W`*-gAQw`@B?Z!;#2 zB-a08W788TAp&8-S`RWVkiOURcF0KIr*>D&JxTwOOz!dNjA~5rYf0DmWWv>`>WjatV-27xaXj*WVARmsM5P|JA>G1u}u&BL)scuCNA zrtGulcaS$hyTSZjMFY_Ha}m#6XI2c4j(Lg*UX)oUQh!_PjFU8OTkuCgO+`Xp1xS`Ev`43G%n>nFlbCI3>^Qomh zVza@YD6yC;w6ZB{zlsxFuG$AlSk`B@Eqtf#`#V}nU%xse;`GFbJrp0|fTP zcRE`U1N3%MbuUete?N-h8&QOW{{o_Pl1%dXAG*yRQlH-$^f`UAO*xck2u0OnQiT*2 z9h!R)evAD65!=O(I zMHv{p*fZS&blaq=$L6TAoWDCeYkf$6vbY^c+{hCE|DTAb&>9J#+ znHg-kP+zKJ!Y70h6@#ssfcmpgdpDkEeYa=(s`0aw9t zWfFLVjIL2$!)V(FEj>26Rur|Pb!?r)&7WnUvHc;_q;WR186$fc!7npHjDTTp)3gXs zDl+H%7HrI@Bh{wp?xT^w`fL?h}<;pjxx!c1sAXMcfHbN@KJ zbc|+xCRQer_AS1dH|ck{2ov>8uGizN!cFATsPA@(C_?%^E6s8}_rCoP?Kh_Lieub= zXnST0sBhT{-xHc)QJ@}@`6yCuM|Km1+K7!nC9({wjQ<}D_cuoI=Z!g3qJ<(Z@g^ja8A^DLHcnD?OoL6$G?-OR&EiSbdSuSUD@N~ z@y3Z8gi(6ix`yobc(kXki5trj!?Vd@$G9ha+M z61#*xu*?WMCh(W|-~hNmqP~i{t&`Q`@CcH+IX~%A%+i@JN|D>>i6_Mi(YDb3l#(Gm z<_#e~`P2F|rMg>Wc1|J;2j)GjzSS6eZ;4;i=o2n|I?Ky<@goVgbN0MyXgG*F)yecY zBb$s3I?RV4)nRv!ven2Kb8V23;k~QIYu%^GlG${$T@XDNFuQFLz#Vd+YWzUCGdaJ9 zEVF4j4kWCHX_&8@;kic7cR`1Ud*1K4Gq`NiMNiLd7?l$Q4&Q6V1B9=5Ywisiqc1Po z{(($xNBX=tL79$JDGAziS>{FCXj})EUl^$i6bpk|ErAcLJ@?BeZK||0E$RSm(AQTP zg6C_r=vagSSxWwq#C^i*<(8*gR2>Vs)MstAjRdM5yq3a3>YQ34+fjB(%;L0pp;+t^ zyX0gwSu!egTevax(tIo920Q7{f)N=(ghdgs+Og~y5>i}R#nQFhk;Ux#TF>rMci-+k z{oI(8@8rvC%hvjcm16qEM&9$fzxC?6G!Yf7BYNvrX0IyOdnpN0?v#QVM;BQjb5;b; zFM{HY;FaHZsc#5m7L_|PD?n)`-=?LM&HlNdXZ8XGsKwEIQ}HyC^sxOWOp@R z(1@KA?W7Z#oBvr0@*MFDWW8Cb7nxk)v6S=XX5+BBfTM$^1ft&WrWkrA-8^X-wk>c! zlCu@LR~jSzJ(=Ajo-of^P7>f#2acawG=_adQ<_;Aa;`;7>Zfa+#!a(C+p=J9LZJl6C3y zdw;AzFSTCBai3vJyf9{vplXPN(qkP!3|rH8=2}_zmuJS-_0+#V&sNF{DjKObai^69 zs0%uBjngeJJaZ#u)%!vHpv6a1h-l0t&>5hulKV^M$eUqbuh9C#ancEZ1c5iy$GcSb z$eXX(S-E-|7y$pcfE+rU2>ot{X{v~Goe^PMSok@A-@DbcxMg%-OG(w@j-dn*IQ~or z-y9#c!d2N9OSlwCmFBLya0{DI>hXI2Ysh2f)zLT_;R_!92*Jm2I5@41*8MFbp^B@o zKY*)lbKQ6(j{>1QP}16IgO^?W16^FCtRhToDNF%DW{mh-rPU|H)V%EWW}f&Nd=0&%Mgx+^hvqGZ^=kE#!z>(-pjQT&XwQRklr2OAoVkmS2k zT9mw*&Y!wA7stI21z5PI;^oF0Eg$r&W(LrLMG7NGwBW>HGLSGOdmiAA`~Bs=_io)U ztMPS*loxRJ<6t<_AFB7QUTgTivq$0sZ0&MH`&5(=lphxAo|(e5AU8Na(@i5^11Jnz zU+u*?g@ODX3^AjewciX#2M@gMGg~0NJv2$$$=vA?B;pYIXXkdqn6Bk!wD^aFFM=d! zchoeu4|8oRw<6_{K>`tYZEt+tO;glf{bq80!qDfneh9_kU=$HdXr=rF1u^N#_v)VN7{D zV#yZ(KAw$0opm{~L7yZ<;#>PE`V>{o-IurE5YUb^-%dqwfvs=#3G@jFteX7_J)T#8 zt?MJBa{U!VCBaGLv9x6Bsh3|x@(Jo!e$F~yRtkA^tqvkGfZHFGkk_w);G4-6m1Wo^ zZY>viZhbmZVIwE?%UWvdNFBuDC^UZL97_t)wq*FY=H!FYY|lUsYTZ=uVb|`Wnc+)f zL4E;?BJkj}Z0fybUOm$0u5I(}uyVMJc)PkR@4<5AuAy3QP-&)IdV7O45GvLqw% z4DLsIxRv$7v!9A#w6%#B!fP*UxwamoFoq>)SBwbeKR_`M3&_Ti+a_d;%93p)`lPiJ zWW|eTzwT%znTA@8Aay_1|4yH)mQcZmi+1PVSPt^KY_fE+?2j{zNX~Ln#pd#@p=#gn z3KDzcIFk>CYlTf15RrO>?C$>faIcwGXMt+(3g3Qz{{j!J`MZ9rvdw1BsygLHg}x7e z$ja7vqwn#uDQ{sjabCxHV`(yblJH<9G7H-(p2N1rT+Lvv#4ilU&tbhE>=^XYj(+|+ zJ8c|x(-EM^ns^C;_Vq+Uea$E&i&FaWAFXcPRV#y+#@5sGyUm=h#Ho%UNn*rn^pB)+jbMW?F)%ePl(xACkM@GUv$#xi zHhXdt@iU756~`!qUQ zYNEhuixPe3e!L!mr`QJR*pxshYg}WkDPFbcG=Cap?Av@391NFiCVDY!u(WH}0!pL_ zI2@(PY3rk2IKOD1aCY;%NjSgCx_>u-*}?9x{b4(}c&N`Fh}evcAL1hovQlnc7EV<$ zS}HAK&eI_?Q?dEUJ<5zmz4x?cem=hWw^1#AH?Dwj)U1S5i7|mvsTF?h+$C(~rr=M$ zDEiMCM=GpE{vSIhAy<}m?uxA4ko~uy`RHmjj&%!?lYI6eKEjjup**f1$BmVn$$rHS zF_%;S^r}BzP!H8qTlVwmY=tv#$0cLM)c=R(a@3`E0wiH+txoj?owdqN7=76oq+*b{ zAQIWmmmOuc-;RuhN{@84YL&X;{X)hroRVl_ND;N9Je|+c9^gu*TpRkQr|DTj!|eIZ zPv%c7IdMEo)fS0(sVMl~@%#pB<1yw1ZjIABsi~JPU2U+d={#g!8Zox^#x9REnK_vX zJHW9pAatAdE^kB@o`#H6%%3_S@v1yL&th>g9 z>=_qm$_=6^MG*W;iUjgiKB(La=f)j<)DOH)`bpFc@|trN5e1S>^P_fmy3#k&t5nV& zcDNczPXn0c=XbK+S?8_@kl1tn6C@ZFDm>RHE+q2tY2#aiDE2J_Bo~h)eU1ZHGP^b7 zGreqcQrv{DugX?mBwaBgoldFx*n-AKGW!$azDNEXw*L96L&uwZD9^#Ub8Pmq<5TwF zZvH4rh8WwF`uID7_!vUa&~R#DG28$5US1~K?HU(W*j>3d8|@4Kgo z+hru4v-6IHl9l{?dGT7Z3*8G&zBTe^g?V`?Ec$i!b|LMjeBrjGN4bi1)8j5Z@ayw( zs}>KIcQK5b=FwhWIAftfEArWX1vYoB=96Ddz&`$<8b>zju=wOw9DfazEui zzmC`o0X+&C#Q|4UDY7ejBD`C=NPTQFEV*5#B9o)GqkU65=<=t3M>=Taf6N8Z7=CB? zktZ)!v};I7F{auy855=UGp+E!C|Lg!%klpC&SH#Vi4wJNY`Qpma4js}=pbIM`Qj zl6T;$2L(CJL;VqteuuqSs0!s18-`k-Fe^Q53ySGXleg3sIpvenLQw&`(Vd4(24;cIF#O))E>~P=Rj{JT)^y zi6>Fwfy0&ly4_U_-*AT4a7W#y<1YDJ?Y3;fy_=CF=#fQ+ZH1)+6wI49p^kO+wXP!g zI_y{UV;LP^pI%Bg3F@czM5o zcMh6cV;jmSBVC;_T7iU%B+xR6&CJ4p20nFU%k(xM+R?w3Q+C}Z$XIQ|EIItjK1Cg6 zVV4CGT}O-Iqtg}#nYWzjO~JLEEmSU4Ku0C5LrT=@o0K1&zYg7h;foq$iwn3GD*1|K z5D^})trV8`)2y#F(vhG|%hz8B(|9{&;$kE~TTr#pWl2WTS!s}Ge?bgdZwz4LJC76m@C;Z3${y>-~K9#^SB>vn==Zd zrVDKkR`*pI&vwbn5K@MVyxT46W~83v>R`a{Hl=N5TykUdsSh?(Ua~Z|jD!(O3{>-f zc{nGzdp;-?iZyZ1{u;ab`n^y7?EN(@mCeixLdo{v^l`qV6uZLhJNEd>6V452L;RG{$fqU~4RZ#Dt`aGYf@q(JiFzZ1b(m|L*gt1THhM1f6~V_xABYle#l%9e;wisZxiTAeS}41k zImDrr&E#NReotyu>Bt}qw$8u9&_~8JxCZdpd;j8owo}Vidw-56JTXZ%C(&r| zR2=p~HUYqhAk%HlCliM1cX6)2dhv1^sIlL=K0RRhrD;!hNWWn{)io^btdTZ8PLRsH zQt(zU^{1Hvd6Gx&uV;Bi_0e^oGCHZf%fsGc0f39R}R@?nD;7zl?8mSbRNS@i95yxoMbUltt(y9vz)$2mW z{5ruf`5h(@{_-~eg;opa9D;?{(v5zBBad0C1xLqHd5c2zX~auhcQofbnFIpo?ax_P_8<{S=hgAhH=ztsGG zeHT8$+@D?2U|ie#{MpMoWBbFZ3Jb~TFAhp+JV3YUE%A7 zh~w24du`vL6>?~qg;!iPO;5FED)a2W{rU;lR*$sJUJ2I{0lO=zE{es3>>|tGT;sWW zywEu!&_$Z}F{bZ)yjq>zdFTJF!QMTY!3CQf-pSc)2I*_p0oIj|LQBs~K@pp* z@cO+x8lJy-1QKaf?)53S?uM%BB&<_?5dn8oxi;chefCJw2yk7{YIW+q6^@H_5r6RN zkIbYlXJx1RcRNjAeI<3vUjO`S-l*QtxO8bP=2@5)wbey zbXmXu3Z^*YIc5+icWM%aWnNsB#?nJ5YhhP(+0}Rs8^cmJl1*sZTSv_a=_bv{O%#~tiwwO@>WpB z@LUn^BI=l0QNoqUM?3i|x(Y6hZkBiE;Z>3$7CU>;33p3Sr zybCyxqf)Prqc9`BniF1czxxj@xqat~@Kvy8L`G)=yAoI5L|6^shTr&A!{RpA87dRo zqDcvM-$bsiJqek6q<2iZ@7KD^i(VIoOLNhw4CKqc-Q|NR%ok@@ZK_%W!~(Kk@owAa za_D_}cj8kge)eAEZ!hRv)v>CwG+27`qBnrM?c2F~u_1^^P&s0Seuy!n507K#!P|;Y z-f{4*d`X@i9pFx)=Ne;Bp$5s^IvsYbgdc}I9o-< zs*CnHaFK;%b=qrcp6IJx4ccTU;ckYHgvbHo>z-i8+DAhKTlY@&(s9?7 z^F2nrz|H_JIE*jZNOG)^;RiHyoFycD#_Rp>wrA7f4lXrX@$7(C+ya?K{X6nOfjSG1 zDm(P7{sgoN@Fzsp*s8@-#pUIG8`)#C_zPNF{Kt{PLia;iu~FDl1VqbByxpwhoD{>Y zDUMdr(kbr~^>Gi@lccw49wSAMwe(hNxL6{ep@jox`;vV+$=&?BH`=ji_~`FBU)&{t z+1jcmsVdyl%guGZ)N8F7Rk2g_?uV~$_8SH=Qb%CQ!E1-|8LF`AdCowBccRC%uNHZF#ts=me`xAp>!OK_JZixSz{6H#^luN2`F4VAyMf(l%yB-&)K zQDI$Em&m?*AH2OQvMjd~uCP;dQ1uh30wXv`WC>xt=nkwDeE*LF@FFr$Tz-<_=-GO1 z8|&4qJB@BgNnqCgGF-$utx+q#u&koE>*kS&9NA9Lf~-hwJ9(S^v8C(N!Xz(iF3*)R z_4mZJj4F1SDQGuKgCaT(XGD0NV6mN{teFniAY<$ z%zkPV0Jwx28i5$W4+l#KMXU&ee5{C1yS{|noKKDN#EztUdh`^I8K=Bk6~iXTj!9SR zL;x3!;&-rbb)Lap^Jo5iEgRFW)-0q7{xlzkXEQglsAedm-edflbIBVkp*fMf9Kv(w z!~tmdmnq!pu-;bf%sYGf{oqi3P{zXYdhLdpK)1cO{i7}EC`^>Cms`d*Y1H7~)5zIk zYk0s>07VH#1TDR$_+^f5+OB?Y(sH&5ejc$hb}oxoWWegyHm|DwU799W!BQU?k`SVx zUW+Gnt}D^Q@yn$a(4tCK@a?-&cg?#o`wefBU6(^Tn!9Jdm#(JIG5!tCP^Hn)EKOkR zhKdKPVn^6Zb3#p3OM&I63!%UJMd|58=>Vc%>!v3vgV2D?r=l8Uc>AyE6UtNk(xezB z1{=~&c?BYF#HdS8ri9jVtCLm<0gW>cJ*fY?C92nso~_){8GW)X6lAy6)-<(Po>%5^ zNCoD|ol%IJpn`Qqrj+3J;Ot0?jf-_T^fcBS|M?^;X_v=Z@uib?@TG&s@Q-J7LT|$` zDTIO|oPGEby*yug(XFg6SHdn_ZkwiXiiN=A2mBRpoo`GI{pl1yuhQi4BP4?Tu9!S({J98$4k~v-zgZEgwe(yXbLa2#)(Q zJ$OtDAIV7+eO!A)x~3pG?in_D+j2>h;DullBs@UT302(S{nU>VJB&zOygFpKyG>3* z-K9aqa@U74Ckn9yd_R^rCWcq^Tyru^kLK{IOfoOWMYi%HTBu9Hg1h zb!-%qbJ&nes$ErPE!F^PBB}mZIf%^kv>8Z1YjwSNm`mm18POWzv zInV!)j3E^WA>|f$;E08<$|75_D;`$~FEy_~@7J-^IewvQ0|FtPYt4mVfPrdz=i^i2 zkY<5PNPAUj*L*E8_NFvVUkMQI@R{hWFMr6%l2Nj2J#p+u9_t}KeK5DtcNO-tyTSeN z+WkFtDlk?b5ZD`cee2xb94=4Ps#IS0kI?Ts^BY6C1eojzigL!_e3&s@&8!wu8IFxV zBv=$E5~?`*R3C zZDa__8=){2DM|KEZ{M2BP+V|nQ7*VgHwU6I9u^vvM=W$bf3H5GQ8e`{=5s7Q1P488 z(9d|GHE&bpz9$QuUGj|?$Lh)6vC3o|NhfGOytNDX<1T+$J7Nhb9mv3#V5j=W3~;Ch z|7nhMmoS>OCFf$FYID1n+WGf6%&H7I+Lli3N>i0UbFjvHPOE`1&-nJ(Np1c*z%VT9 z#lW_YBqT1VALg0#w~_o*v@0^H{pjyeLwVe5n(4V|noj7;npM;k5&!9;^yvwK!e|I7 za_*01SIi(Oc1zwwZ)dP|M-tTqxg5*Lfa*1|@(U^q78>{;@(6J8TLfj&?vmdM{EQ|t z!Q;Y8GihqCzR7qn{1^2Lw5U}yA31Rh^72KUe_Ew;K2!6fPUHG^=(u z0~Mp6uVLG3YJKRcfg--cZ$J?#J)( z_OPaJtF%tC9CQ>I?DauQe@N`%mx*CYwax({;b%0dBa4b%vtI&Pi6`dbUH8g}hsB?B zswk7%>#@gaq#^MUgeM`&WtC9#@a*A0BT5bS1O-8MD2!EsFSmy3>?NZ>FctYB12g2t zicSUdqTMN9V{>%n=e5~O+&8uXYpDfj9hye$#RTeEE-TVK9_rt0$!QHz%&pXKWfGC# zy5oLKf5v!A{zc{mks`y}F|!>{-U9Nrciyy0yc57?e+T!9G!>cl!#|iWBVUU&l5JVY zxrh5Cc;p`hsjpu+@-Qh5SnM^8MI2$rqRur9T^3vOLlwV68qE|5~pAebMSQMK6A z0;F7nQPBbnkDC(oN983yuJQ5sgWn6V#gFZ{^i|(qbAQ$p3v13eFBS(JbRfK|&*-Wz z(oJ*aS34UWL)XqjO`0PFk#YrNP|>2DCmOMyz7_@6`mZ)3xu335CsI}!-=cd* z@rMUbFZ9tNe?FtY`wKhs#p>rG7@I?EUxLwcF(kZj?r1+}kA|ctyEg!|5UxXp#3q|3 zSH>p7$3M-e`sS%K)L0yS){XWBfD1m@r6PL9PX&L*7&!X-mV3B%UwAtThg9^|f6e{S z^a1~i3fIJ{KPNe8Jgq`Yybk`mTD;1@)pm5IBa~&tsL0gcGz_fN@|PK*bxz{#2Jo!3 z2vXi!G=lv7yKuu5*PkWd`qS;2T+@J<ccNnxGz0;w>vEK4C91bJA|^# z6FzU!;72w1=0b%g8-$dQtS~JSr^^~M0txOc^1>cSLTYpp66asyFdrI2`RGdM7b}71kV~0E_~B!6zR^>N(tl__a2M